sardana-1.2.0/0000755000234100017500000000000012174204361014530 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/0000755000234100017500000000000012174204361015275 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/man/0000755000234100017500000000000012174204361016050 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/man/MacroServer.10000644000234100017500000000301312174204306020356 0ustar cpascualcpascual00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. .TH MACROSERVER "1" "January 2012" "MacroServer 1.0.0" "User Commands" .SH NAME MacroServer \- manual page for MacroServer 1.0.0 .SH SYNOPSIS .B usage: \fIMacroServer instance_name \fR[\fIoptions\fR] .SH OPTIONS .TP \fB\-\-version\fR show program's version number and exit .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-\-log\-level\fR=\fILOG_LEVEL\fR log output level. Possible values are (case sensitive): critical (or 0), error (1), warning (2), info (3) debug (4), trace (5) [default: warning] .TP \fB\-\-log\-file\-level\fR=\fILOG_FILE_LEVEL\fR log file level. Possible values are (case sensitive): critical (or 0), error (1), warning (2), info (3) debug (4), trace (5) [default: debug]. Ignored if \fB\-\-without\-log\-file\fR is True .TP \fB\-\-log\-file\-name\fR=\fILOG_FILE_NAME\fR log file name. When given, MUST be absolute file name. [default: /tmp/tango///log.txt]. Ignored if \fB\-\-without\-log\-file\fR is True .TP \fB\-\-without\-log\-file\fR=\fIWITHOUT_LOG_FILE\fR When set to True disables logging into a file [default: False] .TP \fB\-\-rconsole\-port\fR=\fIRCONSOLE_PORT\fR rconsole port number. [default: 0 meaning rconsole NOT active] .SH "SEE ALSO" The full documentation for .B MacroServer is maintained as a Texinfo manual. If the .B info and .B MacroServer programs are properly installed at your site, the command .IP .B info MacroServer .PP should give you access to the complete manual. sardana-1.2.0/doc/man/Pool.10000644000234100017500000000272312174204306017046 0ustar cpascualcpascual00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. .TH POOL "1" "January 2012" "Pool 1.0.0" "User Commands" .SH NAME Pool \- manual page for Pool 1.0.0 .SH SYNOPSIS .B usage: \fIPool instance_name \fR[\fIoptions\fR] .SH OPTIONS .TP \fB\-\-version\fR show program's version number and exit .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-\-log\-level\fR=\fILOG_LEVEL\fR log output level. Possible values are (case sensitive): critical (or 0), error (1), warning (2), info (3) debug (4), trace (5) [default: warning] .TP \fB\-\-log\-file\-level\fR=\fILOG_FILE_LEVEL\fR log file level. Possible values are (case sensitive): critical (or 0), error (1), warning (2), info (3) debug (4), trace (5) [default: debug]. Ignored if \fB\-\-without\-log\-file\fR is True .TP \fB\-\-log\-file\-name\fR=\fILOG_FILE_NAME\fR log file name. When given, MUST be absolute file name. [default: /tmp/tango///log.txt]. Ignored if \fB\-\-without\-log\-file\fR is True .TP \fB\-\-without\-log\-file\fR=\fIWITHOUT_LOG_FILE\fR When set to True disables logging into a file [default: False] .TP \fB\-\-rconsole\-port\fR=\fIRCONSOLE_PORT\fR rconsole port number. [default: 0 meaning rconsole NOT active] .SH "SEE ALSO" The full documentation for .B Pool is maintained as a Texinfo manual. If the .B info and .B Pool programs are properly installed at your site, the command .IP .B info Pool .PP should give you access to the complete manual. sardana-1.2.0/doc/man/Sardana.10000644000234100017500000000275312174204306017511 0ustar cpascualcpascual00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. .TH SARDANA "1" "January 2012" "Sardana 1.0.0" "User Commands" .SH NAME Sardana \- manual page for Sardana 1.0.0 .SH SYNOPSIS .B usage: \fISardana instance_name \fR[\fIoptions\fR] .SH OPTIONS .TP \fB\-\-version\fR show program's version number and exit .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-\-log\-level\fR=\fILOG_LEVEL\fR log output level. Possible values are (case sensitive): critical (or 0), error (1), warning (2), info (3) debug (4), trace (5) [default: warning] .TP \fB\-\-log\-file\-level\fR=\fILOG_FILE_LEVEL\fR log file level. Possible values are (case sensitive): critical (or 0), error (1), warning (2), info (3) debug (4), trace (5) [default: debug]. Ignored if \fB\-\-without\-log\-file\fR is True .TP \fB\-\-log\-file\-name\fR=\fILOG_FILE_NAME\fR log file name. When given, MUST be absolute file name. [default: /tmp/tango///log.txt]. Ignored if \fB\-\-without\-log\-file\fR is True .TP \fB\-\-without\-log\-file\fR=\fIWITHOUT_LOG_FILE\fR When set to True disables logging into a file [default: False] .TP \fB\-\-rconsole\-port\fR=\fIRCONSOLE_PORT\fR rconsole port number. [default: 0 meaning rconsole NOT active] .SH "SEE ALSO" The full documentation for .B Sardana is maintained as a Texinfo manual. If the .B info and .B Sardana programs are properly installed at your site, the command .IP .B info Sardana .PP should give you access to the complete manual. sardana-1.2.0/doc/sketches/0000755000234100017500000000000012174204361017106 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/sketches/daqboard.png0000644000234100017500000137270612174204306021410 0ustar cpascualcpascual00000000000000PNG  IHDRjssRGBbKGD pHYs  tIME :jltEXtCommentCreated with GIMPW IDATxe    439H)(1)(G (3    ,+ RRT    (%&265  3$,4 IDAT    =     ;;;45:(((:::---     #!$ &&)  = %VXWIKL  ccc @ IDATf(($"zv         θ={  -%0 WWWWSO   pq  ()3Ͼ8= HG   (  666  :::  )R) ]R    5AL   G#   58?HID ppp   HHH \220%"({)=3          ,6 "$ (  "½FHGegh ~~~    (++,.1  /3     .)-/-/ ¿-6  %OPZdfi /q' IDAT##%TTV $$$      ''     ((      0*     =5q{9IL&$     X]fdfg 89+#$f/0+  344=>=3  "       !*(        !"&     - $  2'    `[XVWOƶ>7;()'   qs]@<6/    evjvzv}}}    !#,  -,. "   "         ,$PKM./3    ,!/#     SLV $ ++%,"dXM      rsx lll 3      -(*#!#   ()%     982    QSZ1/'   B &4/3     =2#(/    444888  "" 4&'   /*,*&%H:BDCG ,+3   #  <=;  +'!3-511; 22  &6$,        @u "  *%2".[]_ www=== e΀###%%'  IDAT  # $ "889501!!$(("       41-  1)    +,4002,-%#%(($&%#hhi444 ؀ڀ -..~QPQ  $    222;:;  %   //3"   (*( #       "  A<<  "(>  ,+/=;; /7F 083       789@BC6663***656((( \ !]+%%    ",7  !#"  PQa  $)2#9'%3!0  915/(#! %8D_%8@Q5>       IDAT      !! !     ')*    '"»+**!" ***&/16:< VPRQQQ   !" !  !!?;9-00HJMHJM  25:9;B53, $#&  ??A999 ))(nkn(l#%$TUV!$)))STS   '#"/.+ JJJ "" bcd BCCFGIGHJ)*-IIO?>J$#/         (%$)(&  +.%AD>>=9!  767HHH 376-*)     ##$&)'     ===&&&##"$$$ +++ '''   ))+.-*BA@:44$#! 74.   $#+-0   , 4>Q423 IU?$ &!SRV,,,.00  ),1Ŀ   %  'y IDAT$(*$(!  >.+ 0 UUU}}}777[Y\ LLL >>>()) ߀  3:>DAA  897$&())*317KLNNOR GHI**,..088:!!##%!+-)88999? %#!         ĿĿ 201-+0 $ !#" ONO  '%$     75<  YYY>>>JGJ,-+DEDdcc>655)*0    "#"%*#     AB?ZU[ecj uqx*%3,'9OUZMMU8:>(((?:;++,       2/&,-08:<IJ@"(!"796%  ! -$% Ⱦ     "##     )(&  !   trs lBBC  [X[  ===MMMb  GGD  ?@@  **+hid  ! !58@)$1#"( )+104:  &      $(,  1##   -,A@NHFP  STTcdb  ::;    &(*!   ! ;::BBC&&&@@@/00555466 "$'<<; 112 $$$)'(<:@ ADF*GIT               #  ')#Y[\"") 566=@<  0/1 &#$^^_       !##=:;+)) ???@ IDAT""#==="""=;<699)** "   579  =>>)*) 000+**  #"-    &$"!      *( ,-"$ .2) RRW'(''*,ABDa`]*+*466?BA)*&+)9! 10* ($  (%!    "OLM665}}};<;./-?@?JKIEFDEEE999444=ۙހЀ !.,+ &+/;8;H $#% $     #         0/2 ;=9ROJ  "!(;;8157 31.''(  !$FDC "        ,  KLK  321000  )( ,-4>=A !"# #"#"  +4/  )*4 #0/)          +%'  !$2MKZ"$3.)=;<#$363$'+.-0 99888 "# 745./-DBE # # %#   ',-  7 <:7@?F  XXX zzz#" AAA~~~ŀ "#,   #$)  J%   #=6> :34     D@F      !$NNM )'),BICU"6/!C@= ,), !<<7      %,'fd\ #1#    '#$D>A EEFe"!̀O IDAT    $@AGDKM733# MJF %"%658==B%%(!',(3 ?<<WXS996>@<    #"&     &$!   *$045; Ľ))/   #)-"!,($0**725D./9 #$ 5543;;<:A&$+   #%%!#"  #$'"#&ACF"$)-+)ONP        %!"--- $%* #"#123  MJJK  ++*   YRk)55>!    131$&#RSL        &%      ('   IIJCCA&($UX_ .-4/21  "%&+,.4 HHJ')'   %&% ! *+ .//FFG  ݀ $&% 55:  "2    ,+*   *)+    " $   "# .+&  &$#      !FGG !)&   '*-57:#%*"!#'  IIH   $% &$* * "  <=;::;  333!!-26SQW  $   .+- %%#! !`__#$)+- <9>  864ķ"! (#(' ƿ"CB9TTUĸ½'&$   -/,')- ,-$)*OPI   &&) CCB   '%+ !--/  865GGG +**'%'  '!  %&(**-%$&#"# 896ÿ #%+,,3  '%' 989 Ƚ!"  344+/=!%(GFH))(  <==    433))-      MJJ776  " %#"!$#$$    ĵ    !G<28:5DFF '(#Ŀ   #!'(*-" .19$'  456gif  %%"/>˦ IDAT;AK  $DF? #!"('')(#     464   !334!  )  HLM##$!! QONjjg  !       " #**4( ,()()+ !" **$  ??F -2;-,2&#, $%'. !!# 21? ,7/885¼ 0.. #   4$) 130 %$.@>H 984    ;:9VSU  ,,**)*##%&&'&&( ,*0/+:  #.  /45111 998    ,/-  #)   0--  3//*&*!###$    /81 &_^h,/1   *    )&1=>6 ǿ!&*# AHf)3Q    /)    ""  #$#) #GO_3?F*56%6//ROU !% KJH  *-1;;L  AA&)$A;3/*#3.. 34,&+PJH  443.03<=>̃@AA  =88 ¾,-"%$#777 112HHE995    ')+@@A##+   "#$   *,2 !>=B><  43+ #" !-.+IJJ++, &*+'#&;39**.WXV ! #)(+549#")108[[_ONQ$/,.(#  -%  (+6 ! =<:,+)434bbb   :8:((#'&*"#'"$(')/ HHE --0;5=   %#&*'*"! <<< ::7"  &&'%0OQT "!!&$#"&,),"""<=;        :::4.   +>G<  !""#"  .-, 554 <<<   ./+ !!$   ###"%#"%' 43.*++  :<5""  #'"* R IDAT  ;88MMN ((*ҹW !,"$  221 )  " $"!+*(*+(   /-.&%%736??@FDG'%(  ged       "&  ",    .,)%$&656oob.-+ -/1\ZZ   $%%')&=76   IIW$776%(*'01.  LLM ,'' "!B>?"! ,+0:9@#6:A//*9:6/-,!!  $#$-267440//  "   5:'  ))'&%!   &&'<<=\]]    @AB%&&   ## (,+./.  8:9"º CEE !" GEF>>?$./,+ '%"  843;93D@:$$ +&% 200 ;;<##!$%%((( hhj0+-;:A   " &   ++, #'?>< ./1===,,-  EEE &&% ?@A8574/4 112  +'% !   $)&  =;=! ,('878 ')-##("$(126            ɹ EEH&(+ !$852#" JKP   "91)?><  $$"  TR^#+(0 .+0  2-1%)(998--+ (  ')+  +'.,.## :66 ZYW     ĺ    RVR%'/$        '" ZT70,  /2K  &' ! IBLEFHS[ZGOP +(#˭!',!*##("%%&  PSS       JE= !$) 0,;     ?>81., 896P IDAT    603      CAA     UUR    ##  -.)+"       *,' A?@ 200 =:9  !"!"RPO   2./LKM !    289  21.&&' Z\`'&)C6?,&'OKJC@<  #' ?>> ecd  *.-  '%'GEC..+ 525KIK674MMK%%%        &:"(<    %       .*2 JJC+/',+/HGF!VR[(.6IGF2,-  %%%,,0 ''& %#$ ')(022522776   ""!##$#  !  "#"MJK 025@=A EDD  ..*   '*)))/>?I%55>%$*115021   #½,+,#! /40 '&&)&%$$"      /5DLKI   /01 .//@>B  566,+) $#%778LLN]]_bac,-,##$̀_^^  ! " 05.%%%#!! GFF# $ $#" """560DAB    1.$ !>=2  #  '-/  ! 007TUT CDD:<:  "0 557PSQ 377   RTU025'&*1/1   9770./ 666GHHNOOrrujjkttullmOOP))* 696   #!!'"%'++ /, <==568#!"*76=)+/ ""   "!#  427   !   #"  !,.(*...4#$+),4  !   DFH!$ ,/3$%$  $'0/2<" '.)  7:?24:  ?@; ;;><:601/'%(**+333999ILNSTVijlrsucdfCDF%&(/62!($eAAAXXX TRL !$#'!."%85.,,,134?<=   0,+M IDAT),,  !'# %$)fhf  !*    -UYg    "!   )&! fjw)<>B.0- #,$(*&%   %5  #%,$'0 '&,:=<      ][x!#$ $TUlDCIMOL RRREIK(((###   & ))) !!"b '''26( ɼƿ'   !&&BFAXYW $$%$"%' DEETSZ#!*   )"  )(- .-,"%797#*@4= #(5DA*--017""$-"%1 "#'  '*+A21G;@M +1   9$"+). !/05 "'2     iik 544  #  +(" &'!    $!  <:@ "*,&+0-1;8?    ..0      M     TRO&&#   /-+    573""774         *,-!%)#     13+    +&AB: ?@?  ! ("     ..,΀cbc  " !"'%%(00&&   ,))  335feh $"$LLG   +-2" (&#KIG !   ĺ      ))'  ?C80  9:8 &&(+%-(   ""% 7BG   ¿ ƾǼø            "" HKKK<=A    111D %%$ %'$   '"$--/DE@ $%(?DH414!306 #(  FCCC=AWTG ! -13112'1**,  '(0"%" #":;? ")+(           5 )  IDATCCC,,, /.*  """(+&IKA68=((&   747% '(#   !"&*%*   RI[ &%  LLP=;6      (,0;.357@G   CK%    "&8;H 557   "#444    ($1 $    *  7*. 뀿   01.GGD !! $(%    &&++,1$"("%)%(&+     !"" '!    &0 /467:=$!'      .-.+-0 ZTY*,- "865       ))*Ԁ`_Z$" $" 886$ !!  "$  ",59")*' &$*,,0 #&%-,2<<6 %     ,%    !!,(*2      '       &$/&$&42?FG?<@.#&*)*# WMH     !  )-+ .)&" ! $)     #A@FC?D FEH&#'   !")($'&)445 # !.-5 :=:\XQ!"       "!     ƿ355 ſ#$$$  " %    ""$   QQQ221AAA   ,-+ccc(%(     & 732&&/0.BBB   N,1  _YW "  - !  bmi&%'  -69 '    $( "!%   --)*" e___//5"021?=:    *'&66) #%$M1G58A IDAT450 JJQ0/>""$) !     3=:%%'      $%5#TQ^--/  =9@  (׀C@>  (()BAA-1&%$!      36: .-4 """//* ,/5#    !/4C%,;                 ## !   $)!) ,)*       !.+#  $$#  %)+1!' $)+-3 %*  022 #,       )2<  69F.2< )     "! #"#!!           555556      W$  ===UUU&)-    $$"" $KJI"&    )/8      +5*  3AG# '*, .6#  (-5           " + "$"    ! $ >=A   \903\'eeep NMI&'1      ,(4    551  --+    )15         #%, (12                 ! % ǥ =:6  GGK      "!$ 11(><5RQJ44) -,  LGK%&*%%) #!     8?C#&+%41'84 &'%*1' $             9<0!"  ()'     ž40*     8]z IDAT       (184=A!!&'(       *#  \\U.-/@>B$*5  AA=" 774 $.*        $           *)*    ""!  "$!      331HHH ")  $34/  %!/0-&1TTT¼     $2     "!   *8& abe#    &'/        $ '+,#'$&%*''*   32601.#$&!$+-.      .%  >=>...>>=  # .1* 13/ (,.+0.       )'&  HB<         +&"" ,& ư$$!  !  %"-466)-/     #%!?@<CCA &)' %%*$%&.,-6%&/*)1  dz-,5"  %%    )2   1##     1.) &&'        !! 988+04+-0      Ѐ23.     ((&9:8    #+-0  452//.98>(  .,*    $!  # 44;       "$$        BA?../      즘 IDAT  "!GGG  "((!)&$ )    !#$+$(&(&//0# #* -*-     ¿  379 ''-    %&) ,/( &(&        &')/26 ##""   ("%%&Ѐ!  ! %" ̿(/0    DCMA=D    ! %  0*.#"&    ¼(()     $++%%%$&$       352      %#$ ",00'((    |     Ǿ2052+1   $!%!",( .+&%)  +/*   !  .!./,4       & 0/2           !# "     l  #...@E@()'       !"        $$$!$%    --+   366&%(    -,,FED  //1 "   $$"    '')   "! (.+,02          )-0#$%     A_ IDAT  9:@      ,)* "!002   !    **.!!    $).2138'+,   33-   #?@>./1   ()'      .&%   '!   ))+     !$   ހ;6'EFG 68/JJE  !   !  !&    (**   111        9  ?;631/01-+      #'&!   "$&  543  "               123"&)   $\\[""  &&'*   ##!"#!  $! !      (%&      ..2     #$%e**(΀  "!$!GGJ   !     +&      #'$!$   ڐU IDAT )(-#"        %&'!    82, (!  342//2  !OPQ 3,+          @>:)&'         '&' !         !ր/.-446RTR@?@       "   $"  "%    &    .,.        ! ! #$+,. &%&  !%#  '&!$$(        ܀BBBjgh&+1   %! +0=9(%'    &"- % .31!+)         779 7<=  147@@D139.-7       *(( ;A<")) %&' Y IDAT  UTP/.* &$FGCAA<     4.5             #*-       9  "  " %(((LJL+& #  %'%()("         <7A#&6$$#   302...    $&  *#   tzu   031.,.1/6#!' #         -0,- #2" $ & '!!           &  ;;;SQL     %&' 40/_ZZ%&&    #1$!     !%'"      786'((    ""#;;: ,(( IFE!$!/*1&( '      "  $&%  "((7>>  $$$   "! +,+! !  //-! ##""?:=%(&    !V$ IDAT "``c ! &'$CAB=>= +'+330 ,*+=6B!/        &') $('7;:&,,  !!!   #"& ())  %$"774! )(&@A;  #") !($(.(&0&%-CUU(%0            " "()-     #(&! JJJTSO   4"!  " ".  MHP690;C    ,' A<@<:;>?:    +)* #"(58216===6   UUS (((  !  SOP  $ $"%*)/BCB    ##   #    ##    ! ")! ,# '*)"!   ü    #*'IJK++1  %!# ''MMM{|.->   ((* "#"$  Ƶ-/-bbe          ?IM=>@! A?J' 25<9>; 1 557 #(22         +$$  ]^Yb]XJIP + "+* QQE32+$% IDAT(% ::<%&/⮲ "!'""           =>(26@27R4$-X  PPPhil   $#&  # 0-,272      666%+9   >AH309 ***1.1@@@ $$%%%% ///#"%'*&$'       % '#$///MMM   ""$453NNL'(*    3..>@B*(+        1?::   >=C==?     & !   B>?''' .+,777  !"* !(((       !("$%!HRRR 0..   " 9;5@@5 '%% **- "#       "  /.2335326     000 /21  %%%%%%   &$$        )&"#!)"'e221HHHkii   +,. }~{"+114,+)'*!***            -)&  220, IDAT   ##;>= $$-       )'*=:;  !# 21-   /),( #*#g   ''))-/"     "" ,,+       ...GGHMLL=<=*)*  $%$!#"       "   $/'#WBGI=@)A3:m$ 22.LLL%45.    B 11/ '&. &$'666 %       3)%!&$98; 54://0  &  KMN$    $)$ 362 ()))žCB7  3,(-%%'## &'$ـ!&&'!     " ,''¶55/    )    # (+),   #!!  *       ȸBEF[\`67@#-06!($ &16153 +/     '$*, )#%%R=;SBEYKJA26'!   /2/ <>APRU89>  $$"      *-0DGI157 443    # =B@"!%$ '*( 722 "#MEG& & h[[H?@߀87.{| !!" ::<%%(  ,,)""&') ¹  $&'!%# ()%         "%% ##!&& # /11%(**N=>'"P IDAT  &#/<.(      13A %$# ==<      ! """# "     *,1'(, "#& '*,  999454-,,!%!" %#& " :67)&)  $$ 8*3& 5(! W8850/+   --+ ! *  !"'&     &''!&  689    ./.#%($/03UVY "$ '"# !´(*.!   C=>#  +$(!  QPK ¾   "$$;;>  !'&==>/.2$#*        $)(()' ),.+-/   ,/3 ).ɼ():+./OPR45=     ,&       FQK  --.     /-4@?C?>B104   %#$%#&    !(/-   :/QG/-'"  "&*   C Հ   !!"564$%%" ! 841UTS432/-,  0/+  769ddo !-)&*  BBB  +)%$%%   $&&457;<<CAH///$$#$$!!7-      C:/ @8- $ ! !& :46      sssZ[NMMK!! $"#   VVVEHG RRZ   ('+IJL'& -5, =<<++)ȿ`bbyvrtvr#106"  %<<>/.4 *+/;>C # ,"+    0%       %"  "  & . 7&LJM  "+*- HHH@@E *   261   !% C: IDAT  $/16!",;8A LTUEC@!!! ! %HB  AA= !%) $$"     5-     '($ @1 H7%TVE     ,.- #ZUC;78!%$  ../sss LF9          IKGQTQ<;G23?    ""*  #$/* ?AD 98<"   GED    )'(Ľ>97       .2,  86275.#+--+;?  12I$9'$ $##(')&&*??;777!!wup! %*+&8  !" GMI1  /20 "*JMQ"%    +.4 """$  !"    Yfy! +-,$ C=#%#-+$ "%  $4%1&84@247-*.$!# -/4 FDE]XYJI>    ! )  1-+  278"!%/14;???@A,.*Ⱦ!#(+#%    "!)! #        5 07 GP@,*($%*%! "  &*$   8,<C=EGBI0,2tsyUVO0-.(  LLL]ZS!FEK PNK '&-  !$! Ⱦ !# 209"!)!!$  .)#0/5   :7A01:(,&9! &  *!#$ &('8  !)     ellk AA *#(666=9:!   //-  (&$  $' ǿ   $%#504   $   *& WX IDAT!+ KIU ! A3* TE3FB7)'/2),1; !333 (("<'((!  ȶ "##"$+ QQP 521  --.CRK  ''(  (&%  *)%<:5 ())#%'!!""$'   /830% þŸ."           .$KB7 -&+* " ,-5!%(  $(   '%''%'527    ,,(yxv%$&   !!$   &((   ! " jkl $$" ''' "#"!!""!$"$&    %! "!!$  ')!)11      #  L?67.%%"$)%   '.< 0$(45!"%"$)9=<!87;GEH:8<" $  767*+'   213ffh;29 +,-#!  @CF),+|{{()(   *+,   #&78:#   155 *(.!%%'45:  ! 80 D>1!#(&   &%0-8J &04 "%/4'    0/0EBENKN$#&9$YZP#$$   "$" ().593     JIH  '+0?BI..2226!)**  ! !   "  58= #    " 1"%HC5;9/%!%% !%+."&/*"/0 # )0889QNPKIL.*. QPI" ' &",   !(%   ))(   BBB 8;>AFH!(&(#66>)',-1*%%$335&%&   κ'"#F@B99=?9:*"8. HD< ''$'/0 "$  -66 #", (124 $&! ACCGGGXTY(%&tý IDAT--,ـ 34A           ',*ʹ232$"#"     rw|}srEDC 34?54D$($9AA &26    ;=8@CH 7/914-%*    /  5%\K$0( B7330"%'9.$%1 # ""'#'(%##*54 ( !'LTU  1/6KHL[O]D;E*#,VUNvvv  "     '!%   !    **.    .)><1LK9[ZW! + )(-! "!!#$"$   B=A%"(#    "%B9@4"A:* 2A1 )1$ 2ܾ"&: 0#%(,9;  '-0 >A@ 547LLLPPQ767݀   626_Y\B=B   &'(    %%C@6HH=aTG@<12,(" /02'#1+-%&'   !"$ '    (% '!6&-@9 *-  )$ "!"$%&04#-0,03*-1315JIKRQS314  hha  //2 ,+*9:;$&$   564     20.  +%F>3[SE\UOE>6&      %&(       !$#  %(#ND/$RDC/4 #1"%- " '2I !#(8 +38(*.7:< 244JIMY[\:36݀  llm DCJHIP  +))9@<    D9)F:6`SOTHC&  ##(&%)105%#-    (1%"$   /I>0 >5-'%"(76! &+3 +$0("&8+)25¿!$'%'(,-0IHJZ\\3/5T` IDAT  QR\7:=  '$% )2*   !   #$'HER FC=WG<  $.06..9%  $%  % 6-% A;2 2*2 !,8( # "0- #') 235LKJMMO222ZVKOPQDBC)*,    %$      )31; *!*)4JJR/13 +(.+%    (9355#&' !%           H<6  MGB'.8.3*.5#&2 #'$%Bֻ"(,/""#KLMUUVIGI+,,   '''a !   ')(     ))' !:9:XYXgfgTST   .-63.71+5  566'"   )      "%  $&^\W-.(*:H ')#%*.!%&57$+5&3$&%(>A/-0"704HGGPQRRFDEX!!# vux==2(  =@AWVV]`] )+(BCc   3%$#":9<++.  ¾<3P ! GG?-+)***'*  6%E>,   .3- , !nh\ AKQǾ19< !*1<=?-->')Cи,/.3:;/26:<=<:9ADC"""002(((gaFF?   *+7 <;;^^^oondc`EEE&&%    .+-      ', ! ." ƶ?, ZU?2=" -6!/9!# !+6#*> 7 '++')(455102KJNRRSRCAFX !          !!* % &$%QQQ^\[UUP..,    -*5&%%1019ZW IDAT  !&'*+ ȿ"J;/@8'&./""0$ %.2)7  "-1(+46:+0/&('$#$ RPRHGKDCF" # ##%π;=3445 #('0:72JFC('($$$    )(+65/  #(7    I?8XLB 7?5 '''+ )/*13&/1 &''317@"%' 0/1==>TUWHEHSSO  JFA      (.:$*4  # '[SH"GA?! ++$ #)/$!&"'!%27B0:>38<%!7ѽ "+.# 012(%+@ABTUVHHJ;:<(&*  ؀  " #"$¼  #   :77""ļ &,)-7  " {vc47&   '& )01*39)04#4@ -9&& % *.(%377 TSSSRTLLM'((   HIQ  A>>ȿ  %*)&,0"  6/3D>AA:?/(/ ..%(&'47&+/'-3+-3(/7"(""'&/5#7 ##"&%-1. &&#BCBONPRQT&$' eEEN     "%"GKG   mpDDC      %&,('1#$,ϻ !&$ A   #++-956835 qlhD=5|wq +41 !%%*4446<" )EOA=AA  DCAMMM'"$jheIIFhhd>?8MOFLPBCF;LNA... '''999,,,WXT)    64/.,(jj!     .216:9   859320MBP):;=lnq"FJY01485DWUcKKXGFN 0)9000111Q IDATcca~|    ][Z97: !!!#$$%-037>&*-%&%$-+).* ,:3GECA?>abd $"/ܼғ76>AD=(.!GEE4432/2 fcv"""))' !497&*+ #(DIR()/ƿ 4,,***888Rwwu,."42>LKSǻ26-  !;;=**+ ZZZ  #&*87:.,1  " 442*&&63082.#;<<TVW //-30A  +$>3G  OQA## ///490/5) $' "!(  E J  ;$(9/0444999>_]^ ##%215,,.TTT QRO333HHHOOO   ʻ''),63   /+,967DBC<;; XXX ($%..0103666999000>>>??>)))kkksss   IDAT '%$-+)  +.3  ,,,;89<:;0// ///IGN! *),))) Q>q TTV!   .0/00+$$&  ú$" ?=>]MWq   000--/ FFF&)0   %%%??? (  50'HEC(#%===ttt""!  - 40. #$"///(')211WSH  TTT &$'  444%)% 3*$LC=   ¾75$"#  IDAT***  2'!  ,)( wwwKJK+++MLM  OMS<8ANKV"/><<  aaa434<<<}}}```  544**,%  74/ (ddd=79  !77; >6HKO 2%"KA@ e 666  ++  =80  K IDAT///ooo000TSI#$991"430...:::&&&  " ++)   ...xxxYYY>:I   loo"$$  tu[T\S   bbb!  R IDAT011PPP    QQQ "%,  QQQ  ""   ())MMM!deh )-%%KKK<7399; ' "704!$ HHHDJI IDAT 578&& .&$0$&- ! q46523  4  &Z.:222666  DDD YSU" <>;q333333proJJJR LLL  IDAT``` 3    eZ IDAT     Q=     444KKK((( { IDAT '''===QSS!#   HHH   S>5    NKN???+, $""JJJ'''  999    <<<    z:::  Ѕ IDAT:::!!!  888    3---    IKJ    *% &$/--,   555 >l IDAT555???""" 111+++  AAATy###4===   Fi] IDATEFF   DFE   0-0 \((( ./,111  --- +++sa IDAT@CB+,( #"&)(%%#666 ++)&&& +++;>9*/)+++; IDAT---'''4"""### )))%%%{ --- BwrIDAT*** ;A9  "',(]rXby&IENDB`sardana-1.2.0/doc/sketches/icepaphw.png0000644000234100017500000004573612174204306021432 0ustar cpascualcpascual00000000000000PNG  IHDR`sRGBbKGD pHYs  tIME "=3 IDATxyp]u?}ITJ$K[Nĵ͍7S7$iǞę:ӤvcvcKLI AA[<.ՙьH<=|pI9N |>>CbΠlƐJذaÚ'?f!2VL&N#"f_28N0zl6hD$\.hI(`0{8vQqDQ\.KKK$ N2n4Y?e}uF#dR\Q1zz=,#"$_$4V\."Lb2HRQ:Fq8D"zfEQ p݄B!M~ݻ;88HQM6ϵkטb|>43###\~>vڅ餻ϳe._.\Vַg>RSSCGGfGFFü;twwSWWGWWWs9L&===tuua2~/pe&''IRBIIIѷۑ#Gx8s .\s=PRRBccfkO?.]Gf_rkC=Dee%E?w\Q^-y嗑$X,v?1/^rIxvn" /rt:- D^zK.DeY3dT*+ѣGI$H$nĉ;8Ѩfsd>~aX4]Yd2\~GLOOkr;/(*}}}DQk2p:455D" 2io7hf[ SOH&j}s\UӣC٬[oOߟfÆm /p' p]z{plqc瘚Š[o4/Q[%X˥DO<.1=c4 f<= {u: PB:d=]][nlKK:u;KKzdN67[WcT}FN7!m[aZl I8uDeݙ[zk 3a|F5} 뿎0z~M''f'421?&\@@7ic~^ ѣ&B8x(ŋ76ȦMFΟ`0B9^z;Mٟyx_?9plLO3Ivgf-N3>>*y`@(1O'sIE>aǍdr x忄nxw *fWٴ)Nj/.bɜ8avO_7K|׮ńb 333ڋ.wg3:󤘜\ӟi ocE&&&r?uĵk:~c| , L1.\ϭ2)zȂ,iffҗ\#9>CYS[G5cdƋ/&ٰĖ-&~d&L$?$# z K쬎j ѫJ0d``??l~trXze%[~_fiiW_Q! q~V|KF:"Gs\A#SW's႞?Sss>xc:.]dx2^ŋFB:6ovĉi&8P;1e/XFD7x@ Ns\AsX2"WRzט' /} 55"MM N] 4Ν;ٳga||3l6t)C,&SQT-HHR2Oq** d6%_ R2ロ֑L\aFL͐Nyp\yxw__G,7fVp\IoY.($q:t;vP~Uf׮,2G=W2%?<%%%}xd3 rzqqw}@6[tue9}@E>&]~~q_" t_`,۷gpHuįZ[EC@)9BGGGA^(BOO[s,.xnSe&#oaÆI rp]JhQj466Nii)n  ,I;+_Y .\X'tt,+Q_o[7^/l3q25ejJdb"ƍ&>x JzՉlڔᐱXk_sGҌF#UUU|_jgN$D2Ir/)-Wd2{1,KA5(`VrE; nͮnٸqcA;ᰎ[sTTHmD)>P*++/Hwk9#uuLUċ/ZiiO$>ɓ'}!r^,"I9$Μ1q႑|#^__gf^bߵaC $A=_/91X,~W[P!Ғ}IuݞC?_JXտD"jkkٳ&&rR>\L >b~^bn3[ZC|nYf#ލk@NW. 9x5?RV_~Ed N6ir9zW{^AfhHOS@@GKȕ+nBxU[)#F(8zToxT?UaȈhTJJd>-A\~i@:-F˲{w3SNloL&VYg]e̕+W~z=c۹~:뿾vdYEg?Hr NH$}WPFREHR޽cǎ133# RZZJ(UZN8 ߿aN8AuulUTUUqql67o&LsJ&h4"2x`UCf3TUU֪G$y5=#xQ0LyN5ӘL&JKKՃPPQJ?uuuLNN@CC& jE$2&d5tܹY$mJt@ʲLuu^"FY*++ذa P^^Nyy9x5ZUtH4~d"ƣ˅dRo5~zI_^^Ά X,0;;f[;Ae{nF#>D"A&)jFbڹe ȲL(R߿ޟtޔ(*IXh˹p,醇YZZh4J&Arbl6RTM222B(baah4JEE(CYYͅ4.dOOOޟoGW Z-h˖->eee҂hvbEcǓf>AۺuktVf%\;+ ]{8x 穨rJX\\n#24N`0PZZCדL& 9s;R4~&4Ns3fIZZZ4Yr###\KZTx+~ZH$yZ"`Vq[N[]*r^aywT73H"AP_C= r]Nv344D$9ꨭ%PQQq[\իTVV h(mmm;vld!vӧټy3GeϞ=m+W͙3gؾ};gΜa˖-v~$%%% P[[Q.x$.Gc0d297KII hfAIǙ}mgn.\@OO w^^J6ȑ#|>gϪ޽{Cx 6oތ^5HSS}}}޾};hp8ӧ1x52.\ Ypcccg٫ŒG:={IX, 82;Bsq8+hiia``@d‚jt+**S"IduݝNfdb~~jV+& ѨAژW`/(yg}F#gϞe޽whzQq8z~m5 >wuSp,O55XVPz(qzr˯uiZTD1k{%|PD 2/_V8n,rۦ1͔022t:Y\\dx^CU4 $I"H$EY ØL&dYfbbW^ynƔSҢhݕ|(:`l6 @XR)N>Moo&~_رCRd2c-[eYرc4551<<̖-[Vݍ~rY|ߏcbb2S[l6A>RZܾ}{H)bzͱm۶'3 @2De\~ŋ #n nD"A:M6qqv0,c2FVIӔ9p {/׮]#B\e***'ॗ^gbbx}._l&N#^W]r9B v=޽{r ,cYZZd2Imm @.{?!!xX\\J~AMf3fD"'I cZټysip8N'6LH8\~I8<###k^Xּvӡ!N'NBeXt:M]]:X$\(9sŋ׬_$jjj444FB$FFFgddU>8XXXFctt`0PACOn'477###djjjMiiiIEqB׮]388ֆVq]F:… |/ I:N_n׫ `ͼF>o1G!ew:墧p8L,C$p077$I444H$(sP:F#۶m#CR IDATs*f1;;NS1\OVA~:Qd2vZraO˗lܸQ}VH"jNfDQ, eee J=zh4}Gmm>%c2xwU?((zbLNN0L'O(--+W`2l$%IΟ?皾[Sǎ%H$x7tTTTpufS $IƥÇJwYY`5GL&СC477c4A4 ۷oM`xx |>oZ70(V{{ krqq1L*(knn^… ,J0XVTg- LrqrY2 f\.G0$r5QyWt455q ul6{yKgbbX,N't:6Vh4ѣGٷoMMMo/\@yy9^@ ]4%sEe~lͽK]]݊ϭ3qhhRE~ݚS2LrP/'^zzzpYbnn~ & ^O6d2zW9N^gffr\.,:4dUr|!3::J6errYq8X,u2dEUzNty\eccc#׮][SA,ˌ!DQT`0Huu5~/SSS*FQ(np8\Px288H4Uz)dlvMeee\t á.\l6rt:^:|?+.jp(fy277G"`~~QEQ EiÛ;Ns+3 $IMy+Iӷ5ATooxDYV+ӤR)5k z(&Ǐ7ҥKD"U,$I멭j|:vIOOǏ?!d^*Tnٵk|Gn׋?77GOO勺ݻ jnT*ng͈K/oMOO;w\>WJۋW^^;vW ,--c~+Pg|+7fD"l߾N:ċ/Nۭ)(Uoo/gϞ?h^̜׫S}jkkՊ3V>z(w4SSSe*++KWWW#H$p3L5w-^MyEzzzhPHke`˖-FX_ Iܪ9|޴bEYqJJJԱـ&/Jirr\.G.SRȿ+^"@vkY%GooE+X&<ϊ p8x, 100*WUvy'˻~.]lfpp ށw>;3Xٳcǎv&*\vF.]tnkD"Uy_Hcc#H$GCC}}}+W4?ŋr%dJX} PrǎjZf122Rtqijjj 56t&?55E,կ~U% $6\ZZܹsXV/娩_H$ɓ'q:|ӟFөs |EӧOcxGX,XV~?lVJK.x?NR+J{dO9{ c޽{ٿ?###yu͂ ܼ.|f׋h$ ry5m,,,PSS,z.^H**:Pdffv$eee244Ė-[TVV288)AE__;vP}}}FMn8e0bv3;;2M'OLLidF(̙3nѨfT!eǏ٬M @0K)bR2B!eee (XVl6JfD>77G<j:B)=g~~á~bqqZ$za^T(qEG<2 H. #%UZ AeyXFP(]}ߚ­C,c0MA%9s&''?=gL&EM-Ivd2D"Q/瑁*LA ZT u1 ˲RVlE(/b;Q|HSn%xL&C6`0d\QIw )))<>|p^*؛J֕B\@ ޲K!~}}}^z1b1MPծ.Vzz<0P(^tvvm2Kii),c4<OL&ʰꈷbtldb‰<6 S<ƍaEEi}ͻ(jkkfR2r477{nضm׵|^r˲ @.Rb]y~IԸ_Eƒ$IՋerZj|^WK[` J!B LR*WE룄rR4X 2NBEٷoqMbbky2F"^&!t E˅(EoWUO+JPHAf*^/%g~~>o dY&ToXy!L$b1Ng $I,--ChTC{`P% U8 ?@ۙ_Fu_ ,vĄ&yV!,ֳZUUUH$eYm|)6l[_!5u\,,,0==]X(3/ +--errRTa7^(] :Yn "능i(bSb46R,N X\w^ގLEfjRx޼bŝVt )7N+VmGRo7e6C4N)TŊYvy*> l6K ef[/r'pAZ!z+ DTd2YX,yj͋-qyndl6cXV"j nfE1XVBŊΡ+faۉF!e֡" T2$Ljb~!@![ Ď=ʡCx7.ٻwo^5U0dffF3-[Y(uj}1ӓ+ DvAtd%5=Wlضm[ލԩ8łF[m>h44EAسgO^(7;;>O=499I0 IfJKKԧ>yVxXqƢ'r%%%4YӧO9xΜ9ĕQRRłhW^+d2TTTrމbdzzZSguT#G嘛d2RbC#GUUUjŋy\uuuD:kj /s=y/tF$h4b6/)ĝÔh4Ф Թ;|>_fUv9eZE!\+(E(Y墸: e;‚&"fYɮKܹd2I,ӼpJɮ丕b1[XŽMRTc:NSl\w;(6y;DӑNI&< Yl6PQ7bZ1,,,pܹ, *X585v:LQ- BQRRl&j~*kzU- ys#kp%(9zۍ& h.ܹ׋,TTT^(7Ql… lذL&C.+SXVX,[nE|>444`4Cq].SSSڶRQQBЩTuvvzՋΞ=r܌ kuuuq1|>\. HknnfhhIMMZUzsYF8PRRBII 1Hh,;3TUU1::JGGW^%{n0 lڴ Wmرc,|ǏsA$:t|+$ +Zgg'f'NVYcT P _{ M֧v_W0<hrS[,O2k_ |_1=={nr7ǙCZa~y79pXui-gx"/^d||/,$fioo'P]]}G\HB:Vĭ[299]$ N8ASSp;vhfyٴi333l߾]sѣGe&&&شiSA@jŋ466288Hkk-#.]TSfiE)`6mPDlmm%Hk.M+︭)vܹzIUH^Q5l߾xx 9|>eeeWٴi cxᇹ뮻UC 4}WnЄA!҄嵣466/XWRϯXpNy~?hq)XSSC0̣$!˲JEt255^l .e,0===޼y3CCC+C^ƻ@[u߾}ߍsuupr;׭Ç#"hATPjqqee^/gΜl6я~EJKK'} 566rIv;;wrEߢ;wC{{"R/XXV&&&v裏BYau>1, ~ׯkⅹ\.Ξ=d'J!"/^df3ϟ`0㏫&bE!ɓ'I›7oLݣ -2N3l+YMIe$y7^ryy9O?4/_VДAeO1rsK؍,lKK:oJ:;;M10S+Y6.+9jyZK<\.]ÇU`0VtFn6\T*uǛD!`\G1 dRHGj&6ٳi~;&PYiHMMtvj*ǷҀǣDm[WHGQDc=Z_JMdiɈϧG+:Dyx\H[ =6_HL2 u?~<Źsiz1iրպ~>|8]nտ5LРz\.< 1PJ|+$qS2?nla0 ^ y!v{ 'qt<|z=FM>`PFen5Px)@ⴷwttشɌ,bdaA`XLȖ-w3vMdb",K jjtzuTV E HDq,.;EFF2:v6cꨪ2 ᰈ٬G OJBO}Oᩧld2nAaQlyƹ*kIo7'xt2O.[G:-#2Pr%˶m&~7{ׯȾǓ #2 F,{X~vp+u) <MG"!QVA;ss"${7~^ 6Yyi; f܄Vs%0+D*%O;F%yɓi~72D"2=A+w[FErUUz%slO:YX9t(A}]"nwakjkfqQ\ƍFΜIfy̌@I9pF,&p'?i'v4S]gp0KW_59QW_M8ddzG~wr :()u13#ʼB'#\vDQ&?r F&&rߍ9sυddt:zNy_޵q}oZ~1~ZZ5&,.:N Z d2|w b922RYQ4 eMw D٢gBgϞiJ ##I|qKʗ$`hH,yE6.㷮aܹsE{X`6Mfp_w ͙VIh4`j-9??e?881FbQlooi(JP]nКDSSqte044%`ʿ^^㶶ncffԟ/fwvHlo~!:esQ I-q\p**Fiȯ43Jt~%SkYvL@l6 >x88nﯺ|وgb|>qxx$P(Vj I6771;;[nprd2! yD"ף Dkkkr N8 fH$Sܸq4M"$IB!Ձ8arr]]]S'I`Y޾:%'OQوb;("ͪM2t4TՊt:m8մ6 ׆3*8,˞iB=QPڌsAΔ[Ӹ=z$iMTp}aH|"IP"La`6L&rNzχD"vqrZ+QU$!!0L&\.zR E B|>&iCeY~0 T*΍m8˗/ߏD"eQ(v՞Frr !LuTyCcpS}vmm Ľ{6|.֠jAA|r!@(IENDB`sardana-1.2.0/doc/sketches/multimeter.png0000644000234100017500000221426712174204306022020 0ustar cpascualcpascual00000000000000PNG  IHDR$ sRGBbKGD pHYs  tIME 5'%!LtEXtCommentCreated with GIMPW IDATx#f      g  z  g  Q{3   Q>p    g  =f\      QgG    \      q  IDATRR)       >f3   q(        zg     Q    ): Q      %"  (  # (( ] %F; IDATf   &, ) )      %,]           :S!     Ϻ 9              q\          ,%8#                 ;{|U IDAT             '    #$            Q(          ($ & $D 6        &" '%    A 8           51   q      30  pp )p          D  %>#~ IDAT          !               3(#(\          q          &%  pq)     !   -6!&  "  !$!    %  "<99  (" ; IDATz   132  ( !*    "   ")!$             f                       **         5!b IDAT         "         (Q $$$           =         R           fq\                       =^X$ IDAT         R         fq        z   )   R     #N IDAT                = f   )R   =  ; IDAT\                            =            {  &&&      G (((        """       "%"      -` IDAT                                 z OA IDAT                            (  R   #݀ IDAT                        ()&    ###                      v IDAT                   (         >       f                        3   $.    %   >4;4G    "        - &  IDAT   **        .-       2,&$       -)6.         !4*   '%     ( $!    ((!    +#  73%       &( $    Ul IDAT 2+   #  ,             !        "    (         #m6 IDAT    (   )) g    hs IDAT     &2   # 55-0(%  1   #                      ap IDAT                                             ;!      ,(      &(%       "%>6'    =P# IDAT     &(      4, 3-      ;2'&!   =  *$82&        f  +% @6*,      R  "$<2(5-!       2(93'0(  $ #` IDAT PD8          2*=4)-(         !+ 7.!,$    &  %A9,6+        %   &%,*#$!                  Q=)            4+         B H IDAT                            ('                     (           &)       $    "   )+     //   "//&  "   ),&     #., 9IK"#34,          &&  '% (AA ==)      #'  ,*       μ  !    $  0.7'%))+ CBF    /. &&&[3D IDAT      %"+! $!=>8          !-." +#  JI997         "        '' # #%%%%553&%()$           44   !&     @LG... !$!""+( -&'#        35288      #-+ 52                      !!  * "#.   &"       #"     +/%  *)$!!+,",&        '* 4:,   ף3         )  $#      1*               7^.C /7 IDAT           )    "                             &++/       ! %$453 4* !%3A   GGFK          &&.1>8" """   55??((.                  #          (=A!  !#    ""     3        ") 7;'       2<)9@ 921!             /1749?DB:),         " # $ _fTTVa'*) CF/2 -8991 01+%   #   U IDAT EC:$$% LYL     LPG4#9$+! )     aP% ,..Ľ !"!! 54"    !    $&    $ ),0 0/4 !!!     @:)&+    %  *#     ;8'91&     $()1      #        0A%"       ()  -(#)  /06      "%      )*#          ""!- "       "9F!   10??++    ## !"-,$ !!%-.                   '$*&#    &*#   HHHKE/+;6) )+ /6&   $       #+( #57*(*$" " @EA- '$$#      %  )3) , NJ9  %,(%) '*'+&( 79,   ## #$  -/#   & 720*   ) *+         **'1::    KB\ IDAT       '$  !2)$"        A2,$ #"($!87<         >     )(*  '-    0B?CF7 1-)(       +?*KIWUQEMI<5-      "   $$"      3    GN0( 41#?5     1& 3=xyXSI?A6 B5/           +-:+NF'?8'      &#$ .8&$ H,'          *$HE.;5#      $!VA6 $-A`T,$$   %  2. OM<?;!% N9/ !         !-$F@251   H8:½ )#+%$    o IDAT     . $+ 60!'!   ) 3,  NE(7/        q   / =6#82" /"F20! 6(            )-+ + )!61'$          D* *"F3/ 1/; 89%==.%&-"     # (&40      !?#  2@F   $!$   +8=Ϳ %#! % 91"#      " ;  $   !     $ $+   ,&44      %6C<B3,   ''#(          9,*&   '%1 2,)   %*)"& !$    Uf IDAT ''+   238   !! 848,     2#' +#.$!& ',$)+!   q  54;   &!5 ;;/)       '>" !/#)$ JK &%.  z  #$ "":9=6       /    , !" %             124905 C;A8   /77 00 LH(     *7 %    ',G%%#=@:2       2$̸iouFH=(      24@@0     81."(K:&  z   H=#OG(  !  @72-$##/!# IDAT    <<+=7$  "/   1'  ( -# 3+   #D; " P6            $  ':3)"      +,.#  # z        ( 3+         ! ."#         1)'"                 :5%         =[ IDAT  #  0' #           ) #!#   -&#5-    !" # %$) R  ! '   &      +   .1 "      "#     "  &&$  0(              &$(   !17-GKF=        ' H=D,+©3% M8!  )(&867#     %%%   SS9%!      #ͫ$&4    aY IDAT "#$       (')*    %02!     ' $&%$XVY''   -FHH#5       (   "#TU9   ÿ@I     #4::       >) 40:7(   %% '  R  +'& 1(   \    (   *"    R  &p IDAT               Q                  )      #        _+ IDAT                        (                !#%(      (  *+-.             "   R ##% $        .  &'0$$,      % ,70 0%. #&      %%,#  !%- &          (1+* #                J &ƿ    $#* -    ,,("0-  IDAT$%  62+ &'!/92    p     ,-   GF@&&&  - 0,*,$ !"*+(    !37 G,-        $%    $& "   "#      #!$"307   423 :7!)%             KJ?!!9'   $%/&#$&           10&!    G5'+*          "   &$ ==     Ѫ IDAT0.B  RR         -,&          p>     %            3 35#-         !!      G     B IDAT                     ]    p         *)  $*"                    &    -    g             !2  #=    :;( IDAT    )=J101         %"     &"!!   3      3.&     '29 ! $(       :8'   ,*0           +"&(߽#'  )) @A>      # *&     H?8+,! ,,,!,!       &#!"#        ,$-      "     (" IDAT      <"    *!                !       ,'  1-9                %!    !!!             $&#-#(&     '" "     2-#D@#     " GI;  &(         #  `5% IDAT    44"*            *    "      9/        /&         .(            "7.g   $$$)7$            !6<*$)           #7 G  "         񯳰 IDAT +(!   GJM(#   (+"   !'.       )-8       ,  &!$        7<9            $"       """    %(           %#'$0+' ( %%#           $ ==# )#     (((             )$   $,  #   %$  ))! # C!C IDAT0( '      !2=*$*  98@  008                -      '( <8!"    )          )  $    &($0&  ?@    "/        27 52   %! #          $ '%           $           1$ !!              *5/'$     +-"  ""$ q   hq IDAT "       %% 04D<+                $$      !         '"(@=              3  ]O# 86 )!       &$&!NL5                + ' %       #1"2)*% Q    ==!-/&   !#22('' 687#"&     79+$־:<3       JKFJ0 9;23! )%        $          >@3BH   OR3),  +#         - 66 +'         -.+,0  -/%*.    k IDAT  1,3        '!&'          59   f           * /&           ,/ ,()          .,/  %&         )'GH(    -    %    G)     (6&     ,,!  ::B# $                         &(        %*FH8             "      $$        # f            '                      45,##01!                                          &          $       "$    ER IDAT     11$        ! $     *='$ +. "# '#      .A         %        =  75ľ 6"%%              "                             ,) d"+/20 VR";  013"  %'$  )%&-15       9              '#  !   11)'+     $"#                       'qe5Q    &+    &(        !    #"!"  .,#                              781 ))+465986 #Q    &P0 IDAT   % #           437 %  36?   *,              "  #!#         "     "# /.$              301<          "        ( ()(    !#A>5      !      >?: 13. %%$  !""        Rq  % '+                  #+ DEA  23/HIF          +0                 (*;;=7 /+      o IDAT    $ $'          /0,>@7 ))1IIK!!"HHH#FE;   f ( 63*       #     $    -/       {!'1  *            ( &         =         "        "  #          ?;(  0/ $! %                       =     80'1/)  %      +.1      &   6('""("?  MJA +*"31&     & ,- (#   ' ()&           )   '(/    YR IDAT!     *           %%%  "               "$ "" ))                  G         % IDAT      (         3         # )l IDAT    f  (=` IDAT         f     Rw IDAT   3 $&(           34< GK@%$<@ &9<'   "" !!#+#                      !#-( &!             '4 $"'   20'              //      +TpY IDAT    ('    !    !(&,(       "%              IF&     =          " (                                  )                   f  !    #    3                   %'2$   $#            2 IDAT        !        ,   4  '     #/#          %+-(#  $&%!        '      "         !      %$!    + &!    %+ )    (,  *   /2!)'     $   {À     9)   ' #       )0!&          #         "(  #/"          ,/'           "(   * IDAT                                                 &%                      ,         !                               %&"    *(14.1)'*       ""   $     +&     "                             &' ! (       %'      E IDAT   ++        "))  ')R    %*-&   %!         !,.  '          '39  >  "  #         $ ,6*     !'$    !   **,8.2(     (G    "7"              "!$  "%  #       B("   #( $                  "!%  $    "#(-!    .   '                                )$   z ؀    "!  &      !$     /71          /%    0.          Ap IDAT  +7             '.<(     '6/    '(        "     (=6-    "          3=    %. 0)  "       "(   57"     #83            .7+    #0* (   %/    ) # 41"9=2/ RY0  BC0      12   "  03DB> 560  970  #  *#   DK+$+        #)) >  )         #CA $       10-/< ,+,,) *)$&"!  "%'    =       &!%   ,)  "' )  %.6#    %% ./) 97$ !*')$       JL/    )             '$'         " 065  5JG ':7$)((   >"   #3            :8+4/PM ; IDAT            &%  $W5-+           KI((%      2.!,+  10      !1/#(    CA )),33*ȼGHW  ,+--        $>D45! "%Y^     %& 5=%*222 # ?A!"      $%$ @B97C   %/:5" TO.4+ fg_(--S IDAT5 >C]^8 , @E  (. 64  6=7  "!997 "!   43  J- +    LQ1:   :+8(#,37(0#LK+ GB2!%!    54 %*  &) # 233 &15)99*    EC@,)'     )&"     ,*0     )' SOF$& /.,&%-*(17;<    )   !  !Ž &              !)#4  5*KD1%+('# GNREKCcmK/4 =A0>A9**'         $ܾCC5 :;;  !žGL    6.'& %#     *.!Ω       114;2'0/1<.      z&)7:'D?5 # 4;/99/ --  % (DOP&$-  *0'# ,.3   0/  +%,7 -47  $ Ŀ  )    "=9!D> NM3 48 QS[W"%.'($:44! λKA/̻GM6  &%  !$ 04-/-E?7;804: 32+*20$'   #R /,% $ G>!LE  D8@7   '! ==PKBLF0ʾ&#WQKD?  3)0D9TW;y IDAT@  /4пGH16 2'$     3/&   rhf'(#M   $ % VJ#.% ***)5#! /# E &  KB3 ,)"+'   "MB< @EDJ& -' \&.$/- =D 37 K@ N@ 6*!   0(8*'," '  6*'$   6( + >2$               "               $ #"!*#2.. 7Q"@T              !   " / ,!  *&/ =F9 "- QQ9      "     5M7L                  #               : IDAT                  )".10"###         #!e_&/          !              \                                   #!          '                       550-       6; 1 % '-0/" 3!(n IDAT                 /3          $  #- $              &( &"        1564'                     "        25   ¾ &/<0   CV-& 8 $$              =A& =E # 38  hk*,# D@&&'      + !#+.8       ;=/JP    !  )/%2__5ipD&,FM FM9A   ,-'       ). *,!   ! #          #"/6J',&ſ4=  -5++' 0: #)!C  []%*4  *++B@:#)   ;8  : .$ #,$  "#!        &&   $07+. ;F)[%1)    ]`J&0"  !  "$%+ !   %   0(,( %    +(%#          "% !":88  ((BD"$" +2 & Ž33#141 85ʿ0-2.1UT2Ǽ)(#!" -* ʹ"4  #     1#(&)'   $!#  I1-(  )$'       b: IDAT, xf  JE&-* ;8 51(  XU:6NE&')bX8ϻ C:)*+&.1=< =;'>:ǟ  76 <:+       %!   ## ##      ")#     1,)$ -'     !  +(  *    MG0 !"#    20$ 74"B< &""$-,                        "          ):1I                                            G                    p                       ʵ% IDAT                      p            g                            3"u IDAT4   % p   q p    \  ]  a IDAT   &            "        #  ' [ IDAT \      !   ,  ! *:?   \   "H ] (\ } IDAT%    $    (  &-  !    !    %$,6  3   $'R!4    < IDAT   %(3%  )*:   +' ] (    H     = $&&     !(+5<#(.     GUQ*9%0 fߙ      *7BV> ) IDAT  ,19:H4  (   #,%-   (     # #    (gp  9-<4B QR\ $,5"+ #   6>J{   ( gp   "$,$2  *=)g jXVIDAT      #)1)1 ( ff3   $&# #(.$) f{&&&  .,-&(& "VUU !%" $$$     (((=))(Q  W=GNbIENDB`sardana-1.2.0/doc/sketches/nanopiezo.png0000644000234100017500000036736612174204306021642 0ustar cpascualcpascual00000000000000PNG  IHDRD- 5sRGBbKGD pHYs  tIME ( =ltEXtCommentCreated with GIMPW IDATxw]}9ޗ;7rNs@50^%Q-{ʻqm֖z-yk]j*)FFF4埒}kY-RYby%*U4-1Dְg>kB ~JJJJJ[E15%X\\dqq >_7iZq{ӿH?m^)S])S.)/.Q^\dyy%+ˬh4jZ"kBP(7I8̃XkSOIIIIIEV^fyq?WTDZVQը7t.Z Y~g_O))))))/ϲ"KeVuժfNÅ$kaۿX܇1E_$@K#<++U*ejVDӡhQovtcpRB`Q@P;JJJJJ(odmo TVjDQq !-p߅%g@t4?Sr"7pC񧤤\fH;vqiY\\d~iFskm/T9GoZu]F?y;R祤oq)u6p9ʵ&f c|JZYsc$8ZK?399TSRRRRR.їy~LD\mw0&B)AD8k,gnn)%7Pcزm+DDQ(hZ4[uKx8cM5`qĦK3LMϩT*H)/z!DZOIIIIIyQOB~/[neݚu|Kl6YPh)R!:&}@( 1aQ\^k#TSRRRRR. \w84T9HpIĮ$/pV \.j=HӱAir099(q)A;C ,kAXX#"USRRRRRR$E^xW^9N.ZHC&) gqƱ{VJJJJJJëBsdy?3vARƎ(︧t~4:K2c.qhTG?JJJJJJʛ,@2coYn4-iԚD]ӏԝQ1XgNl6Y^^xџ}K#~c k֬ꫯ`Z)TcE{9gEo%6]&Ϟ'Ͳ}VJJJJJO$~};5@Eqc֯_?Ʉ+@KB""ab̩3 9mێA|/G/o􇊾szT}B>%u'Z>gqR@pB|,cp"[lYF)))))?8zqiWNԜ*#wk-wy'KKK)))))?i$1Qth7[t;]Z蕸ץolɏ=ok4<M6qUWcǎY^EO:'oA)ʼn'_%* R %$bRގvMϿiA%Вl6K>g8~!nTSRRRަ4⭮#FE8?2ZvIբnvt-QEak>u%~!P(cϞ=fJㇿOcCCiapx\.V k-],!J s(-ryFJJJ;`Z{M,KK T*:8Q|Ѥwi4 ;qL[tz V\zZH4AP,ٴm+z+vGBʷܰiz Ga6sט[Zo# L&C.[bdt}|gQ"wIj94" NvI;vM٢u;]::M9N8 I 4\-[pǾf-.4Z6}_䳟, Z*r0G(":X'X3 a 5l>'҈?%%%-.&.wQיq3T**DTM6nnM^{)Nb/k?`(di\=8T d3: Cv{w/wܹOhRW#(;ZKt(`R0}@gÐl.T*>ž{gRRRRRZR6XXXpK,/,E!:[m*qKۦthu;>ĘɯֺKu0"PHj\4H+(޽[Z/}z}??d5ICg)2!B Q"k'Zk2YT}jğ\Q}T7OM{f~fYjF?jw51QG i;n쓔}7/X|knu$(}XgB:0ˬϓ O!c#|~PA'k{+F=uCkM>_ddD(p.HB#Oal|?qBJJJ];S' T*tu8]JG{3]֞*$~1zߓ+J$Xu1A{>)%B сP(p뭷?شyp\%^ն7WH>>CA1_b`G9zJ ]t%O JJJe.Z-9N?‚Nk#A"BzD6fp~:9okߗ]l*0]|ٹK).N^Rd҂|&֭?sn~~7/}K[8 Ð!KHqt;-b&!4J; QZf"~KR7dJJJ;եsM??t}}DX)#9}oc1=^y/W[J)\ceR˷_On_/P5R{_W_-Jzgdl8B8ټ_x0PºI<$i2 Ph K6w^>O& B#}))))oJ fg' BveeRمY&&&9qssWj%`.|k-JB&%P(d2(B z꾸_"=|ؿZ)KthA`)~SY];v[[\qՕr_w_RY\\g1r9/q:-HA&|{/9SRRR@uŭ^ovxou;Z-*s3;~{Sg责~Ts4Zka@H>'_)4ZonJ검WdlpXb+$X H=hk͆lڴ~77{ R_x_!: o&ɛm!6_lBRL1@=D.WHRRRR^H9GޠQ[y5'imh4׫`pq 4Q111s楗_\^Il3qBn,N@&aX8P" u?B`Ɠt 7yL9$|2}? D y MBIpذn mn75DW*>_dt| c R]n׿ \i P!JYranO/300 JJJ(FFnלst+w:Zz37o! _C8>#X Aw 8Ld$Z dd3E2YW^ͯf͚Զ7%%%5$cj+U붼c2zqhtZTuڍ_niɬdu@d|6P/Oo>A&('3}222B.`#TTǧyW"g/pUz?=g~ $l/ L7?oxS"7\WG|^dddħ"288L!6&oHd~W7 FBbyVoGo_Sޔ_ȬBuX\XxfvjJeٛ4;hvlۼNj7]{֨_w?T@j:rI/'~6ell$DBV4c5\PU^A ΗA&|vwFlؼq=.W]}$f)Z|s߳2::J|>lu q!6o+  uC)5 {o)M.4MjʗWh&ci4-%fgXѬ#u@ s\.03PQl" GadP(`p|4\ ^ekX?6ȈoUmv=Z'6ǃ3>!%X?߯]&%Ƨ^3Ҡt⎿vBhw>[nށV!ro[^^擟$>B~8\HaMD!2i!FL&$bz}?bHIIyGF* yת7.q#vNbphVH_<+ǎ15=KV# PAl vl_a/ ^TT*5=-H0Q\GP*X~=A݋^o_?X8aq{%)\p6{IP%t__XQOH Xt1ƠU 3&7) zYrR(RS.C @ dAHq.aBc^DHʫakž ~JJ;KlSgzIupVDiPB⍏l6r5װuLMM0?O,O8Xbڵh!aNg]/4hcߝr\cO\Aբ٨ }w]eq&Ri+Hx_0R!d !FiE)|u1Lwp& ߐ K_P֒x8v/"Al aA+OuE6q+={ÁH-yW(PJ]RRRRYXV78۵*gNvOcy33<i7ۄ: !M/ƆJzr3,/.yAWB.GDh(AkK)1`bE1_}57޸W`zz\6=H]KE7iaHPKsxzz˟obNjsy$ $HS"3BH"4u~Fx>p_fY[kd29~8/"\֛J_Xdg^_frr9J2EŸSRR!EF 7yvb@d9J"B P-9{v{'w;J%r B]p0䊫[nD3OQ./v1qLd,saؘ_$7wnwbiq'OEB]KB)`Nǵ^듩0E .rR~|׾q (!ROD*ZB$k-$V@"q85>}B!k{J_icZ  '83J%Jn ,YZl+9KΊ` >Ϯ;(JXg_{IIIIy[n2u;sمy++eX*/ӬpB044̺uٲi k7c|ڭ_x}yJy5 T%PBvɆ!_k^Jʉǩjt]+)EJId3 BMѾO|įF)pu?~v߼y*oÀ,gq~˷)K؟ X0Љ.Q"6ؾR~Z`rr[7348;Nsn3u++U*ezzٹyMԙS,b80@0 7p#bG=JAt N@uq N# G46ndp`_w^ס$Noa/CC<Esh.^^dtt K"{Ps"&`Ղ޿~w1ggQ*@)/h%))PJ"$81vOpdpp/^ e%T!ԫuo/)?{/pwq'qIDrSO~׌azi %%ri?"fgęfh6!J 9f`h̰TZ)K/rn,/xwr͵ײ~J IDAT8#jYa=b #lZIvٹc'wz+ G")eN>Cihŭ R)ﰗ.W_{ 7Çiw 7I)RYA##CßW~dR9-"—Jeǒ@%FH(RC"aRHRhޣ o$Ԫ+,lwϻZ33ok Od}8kyd&86Xk!$~X5$}1CX(ZGY+GeM?r~ !gN83WUVV*,--rnr,.c`pp165lظs K8R$qܹI <۷nchh뮿䥗^`Xb|sI[D&pǝw266SVT&NAK -5H僸v]ؾ}_xF?vIT;:ZHz ty!n/K=!I6%oҧ}%Jiߏ @ TA;ynn_+ ,ErϻX,# pđ[pqKNn6qZX,w_8ĝ./y@ڽ;SRR nsެf~n'&va~~CE(\|iRDE(Eԙ2Bڠ0P$ ?ϯ_aL^&"mm[8t.A$̀R% Th?HH/'e)| )QʯR'ҁM2q=$ŘU*e:o߹_Kl&Yv}rB. p<WR`L x'?%u%)vL=SRR.pΟwv n g,AUI79 iR}t:L(xM7LZCVi I ذY^.sQ:Vi5H#sE>N۷m6> q7u-L [ZTT(`lrIOL4Z3O 4.ƿ $JVA.)8_%o]|?@&}g#2}~߹së'{qeV^#,̗8'ΏRT,tCC\ϔק}^9}$֭el|k@ZZٙ)83n&)E켹hv8)X!Q$KcQ=GR*o;߰q{'=é004ry~<=֭[}|nbiE+ ?.%Nd[J&$Yq- /@yy ˕2۶lqކUqa[))vd |{OcҞǎj | kJ pZD_IB q _+N\.8 rU7g!Rעt,&r׾;7J_y-""~c k֬}'MΟ?O#2Ql(({MM:8DqL^9lٚ JJeCd~z-o68xbnqJָ^d-^*/ ߌ'Ye+?$9ql+{OHfwKvıeeJ :9$ޮ‰$mt0H6 Dエ?@~ U 7KҸ֨;7߾oï[NW 0<?G^~b!OY8{Z'?l>uWg#ȟNũ'ΰkn_^HjbӚJJ>VŹ?kwer,ǎ3>;ɉS'J36ճɼZHl#}l$ +6 2 R)Μ9Łbqi5kyϻǻ֮]T' CRv/7% x%ƧoP 0:D!cسk7B0ؤd}/eEpÍdB3txsAۦ٬nz,~F_)oa@bFH?~'DgERW~P)X2^*XEʤ lLEHb-mIFQ;- G8u$P(`# Z a 8|]X3? Eq̙3gTعl& ~JJOwCkCLu9*R,G9Zgb6oĦ[Q)sIZI_ACH@Oj%T2,-/O~|ۀ;=6mZP4T>Fzz%.F$~ًʅh \Gr)L֚r™ر~g|f"y 8ki~E Lfc #Ã30)t-3&Yߵ7-\?{%#B8F [Ur@b(,1>ScLLrp6L{ޒ颞0>"')8LAh>9D2i,Bdу&9Sl޲!^wƯ]Eĩ347;SZZZbaafNӜ93AB^ǎݻalܲ|"ꏵI͓-v!| C|OP}mvP(*@jP/^H?.}I'y)ÞpYC6_رcd28&h48q;3>6_EO$HA5a"$wݽQrd0"֨B s/gǾcݼ8p{q䟬fzH,uZ VVͷToIѿл}>Ll֓O:fu6N Op7N'#6I*F:Y"ĩSgcڵ觤d%{ٻcX\s߬K e&QR[Ch4tm۶pjMq`t%—%% x68Pafxk0=s[n{*kZ'+wMC:w{>-;eO]r6ƻ>LLL$w 3T5N:͞ݻk,JZ0 Ð |wgϝ'C?({i%2T3>O>U{RɏYߩo}؟l􇠾˞Mj>wX%D%5ssckv?a Tl{w1P,_C 3!Ԛl.z& Isļ7H68}:ٶ}[:ǟzTKNsKi6,,,bZgժ6mč{oX7 83:wl"7!|d2V?WeN:k"!{QJ"I)H~Z!0J?-;dUr#K1wwu.%BJbZS'+Ya#R8ؐ͆@!dY2 :9qo|Zm{:G^g4*@i2Xg!QR  b<,sP\XCaHO~ocl1cc:z}pϫ%_l_ r-lۺWtc2A՛0T8E.'P7bG'>L&u ,+Nh}C*)))?zjsninaVe~~9*e6KKK,,/E&r qM7wгؾe+Yqss=2'OX16:ab@'E2_W8q8;w?7D>'x t"8lRXHj—2I:~^X*K//~BԽIU8Kgiyg&ټu3Ql64@ `[6nUW]#Z͛q>}%A6d)/BSAA72Ħۿ ٽQ_5#;f ;!L*L6;CcL:_ ֭rL-R:mClظy;6)=qxüK=rB!OxkFc#~֊@JFw: SUl]:.G\^f=d2?%m ,L q5ɉ ON1yn33M Zu{=׭C+E6Cjh6ۜ:un2:$BJb1PklMw^>3bH| YʧUZ*$#V%d|YƼZ ^`&X,1??>9Ϗ20X"c?Ï7z_+%R300ٺy;\ B`cCU}27| _"MPQ 鴻($B޻i?ѡWp9/n/8ѫ[|~_O?4`Iy[d/_w`r6 p((|mchN/=\0)&'3ϐ ct]ɄY)џ(3IĦ}9Ӝ>=;>#wR/v,~yavonwbǹIΝ;OZfZjj5U)ر}C#Ac=fzz(Oq䥗CJؾu+0~ElF(-!*6m݂t`틘28-W%5y>wKsU(HWW z oRFc=ʟgͿ캮oPAIIX))I;tg^t?J<ĎlղlIe˲FR$$s@bQ(*޽?so2ȖwbxCY.L8+0,'5g&I^|v7JVq '>F׌y&tb38[앒b?uү\8wՙ]bsi<,EYQfӦMzvͪU$P&h[ĉ,377Dž XZy]qPG=eZcJ#>nwމYYz(XZbVl4ۑiYBomRObcX ?IUk3&"A@::)c^_a\ /}dttO?4*NeAIڔ4MIS{\|!C$^HCoax pgI|gwqe''~8K|)#wWz$O>6ndddTܵÏL+'v5;w+!0s0_u~~}k8hZRP IDAT+~Ԡk$4Ͱ]68IYOiIhuZ >>O >ۺW~w#(Ƚ#x!Hz2;m+?F'(0J}eɋ$"Y/ #@r5#A؄t8׃`ȲnGGFG~$4;î]O-Țœ,;2'/KYJ4YZX"_y&W%J=|m.\Į믣h^e;(38?HJϗɻ&Ν?z=S%Ez/[ _ 7vV$mE? 6\ ַ05k馛ذa/ckX5:BfI;NbyN)&OOrQonMє]J o|]+c[GÙZ*,2&~qO n7ДuWQtlt lW!(lbzE7z X{Oa| m-t®wc5 iB5i4M+! G$!PA}I xՈhb6(k8P QPxM {wׇw}KHR!9 Z#KFv#  @L'՝RMҚs8t0[^wq M4Ο 3ӿ[Z91>Jb Hڜ1U9/"k46odMuǝlܲ 7u6ݱkm8#z' lVL5|K<쳬ӟ4ckO{h2fݫNj[ !QCu)k-nӧOۿ/\頵], Z~s$-O &AcyHu;qSV!Kxfd>Vv^4FF&ԔеP$׉|b?Ă1pFEVTӦM|?K/ȩ'hڱKK;,P"3WUo -s8իViwe O}0\Gre={Yji|[ՉF B4{Z<jYh'sF+Sd xk[ubn{֊7{÷-gz=Vzy V%EP5q.VZ+c+wu xƀš<(2>I 鴻zsA իyG8r(#KERႧ(8hl5b'/;`rFv!r?8786' ' ']-233s?+t]֬#M : IKdWZE[bJ ˵U+^a%X-ix([Cb,%iuޓO ϓd)0oॗ'{22:Ç8zwC!jݳ,u<鰰~o:of,my=IMۭyF"kI␥%1P!5V t" 2l4 !`_x,\[nAykEV4-6mZ׾W-h4#y!nS悏@aU'!~W'U@q"]^qTh6ɗz{kZ/ZsWo6<#^Lf((-ޕ(mI#$($ Ivz7X0G0=3ͮ]䨫gp_uìM= >~<:qхAEz6CWtQ>g/zSC (V DRAZc9['Wh9;~\wN gp%\q\L*zΝ '{trry&Akիذy3GGk|޵BT VCHv!e!t1*-6zNk-zG+E^̩S=z%fgٶu+=p?ckױ{8r0_˯7ʱG{;<$QIc|5RWQ"X-M2˹_x"~2(脼ٳ7O=,6IqtB֐d.\d({腅 ={[-J On[Vj_:?>~ĉ_={,s,-ĬZVeʈGi%,yc!MKB 1}D{7Z]rS{٫+HVkzyYPsZ6JḴcGxKWp`>= ?Py9y?}O<Zۺt m leh8p_gґqh  F(-3IkM J X$;H L3򢈈$=\g+3?[nFa4*]G@%ëF 5 W{y^lx߾VMzטJܼX+do}իF8x {arrGR$](5ǩA|Y-VE$+|OGkƽwpSTd䋡Y"WhMp̥RDjO4 rW /J$MJSn/D"FBeY2>>g>>Z=5+3~/yK?|EdWкlr C#5BgrRE59㗯 AU|@{IB_AiKYziJ=Ěz!ߨceY~z>>x7|NMěO;lJ1YkE?齏}~%BY=JfӦgp'K/Kϝ9WfPZfҨ7m$k0aaYLn0qͧYBs&LV4T"U)%vxO_/_fiq1֯_Ϛ5kX7۷?Co͙3gI/ tS/ʥ_]XE"SSN2*BZt-ihZT{ Ŋ jgZ^yb,kk7 R1}lEzt;~䚭Y\X`|}<3Wf<&_eB~qѽ={CmP:G$t]9~9qnk "3_!AVJcMkUwhc4Ckie iP(#1 *W'_<@#HmB^5ZGIffp dYFF澂 |8f=z7|5emJ@KEd[5uB_UY <*|Y=:W|}y{tDnݺuzlPyoooW>|'(JGd䮔d*$`.VG 5-eΡrmF38?bc Ë LM]鳜;w9.v;N R*'J zȣ;S8Uh>|6 ĦQXF kȤ{6?Zcn"sg]^.LLj(L],/^q.]  ڝ] 3d-miuM WTyZIHף~|p\z7̆ Tx6pa鰴o&nh5)\5FYG~ګxh &14bVc V'`$]9W+2N*&jcI!WNxNk9?~۶zxАA~]ɚuLM]/ "+3 u;wetZ]G•(4C]?s?bl6t:PE+YΉGq5W)QޓDUHFͻ+gdYN5yT7+]ccYChE2*Sa|`vv#4~(Ibh4Z4-"w@;>h ~nT!IDV妛oE,{ԧ??/]fEyWC_=šC8o?334 >> E$"S1@C8w?O?c9RE銾^cWTkE$ֹ.5M+3QXRlNH]./$6eIɟ |QDAj4Oi3< J9ZcSZ&K/BpwNY~$iC;'xGh4ZW}gZ%&. -P&IB5IӘWQ]W3-Lj{'i-ӱV<鯜P ;'E`4tGx7h$)k׮_ 8A٢in1XVQFSX^Y_ez"hm\<* @&4gΜs> 'xgdj Jy^|a/:Obano]wau;nu4Z-\+[OfW^y__ku^U#ñ!bt"S,(m/3IY&DwMDzy,Iщ(8O^hPy᫊.EnA\q/`]!"f6abb4#Cl̗%Y:p3 c4O|;X,K{^,Z<:L$ji#2G!< v`C)y{ϠX;Dl⭵^!HM]m| '8x-OwhU }iJA6MISӺ,zJk;>Kװ6az1DyR}Ώ ϜztqaQB\Keq-EYȚ RkYXX`vvIՄ-UJKUtVFPuqAfs<'w>^{5FG?q,cor%7ɏoM7~z._HwlsҋwU,ir[o_eFV,0Xj1fX w^32ieNH!wq?o-D]Wa~c("P)15j˦96JXyP+ p8Vck[C AK2]ve|bTh1eR /ɒ5">`:BU+K{爾U$9 IDAT "@tdYʝwy,YZchhG>K}lb1F:`rX/ FfC7"MBHFy3/-q`>΍cktF <"qⅯ?sfb.$ȫ7 x >S'X32pId$T(Ŋs*8;NlҲUb,fvvgyo}ۜ8q=z+;w3=zvŇ>a6'x#aQݶon=w!(HT1M{a;?q/їG&&&&)cܧ0x/5I$IӠ&zF7~7~ʹ)A ڪ(q>ݰV=GK[_apboW)LTȝA$%8!]鴛عm%YyGP'lYgg=_)T 4VUs9P^8/;B/Żj dʽj Vr&J)nqWԚARc}͛7?V-CCԉ=^zE6lٲ?sLOMqqbYv^mweF6S'xIv iF1Y~*$ CCCL^?>{>r0I^P뜏zw}gq*NZi&4MmnDtwRHEYTچט0EꧥpQ"s)ZZW41_=Q^PpJk\Rn7RIUfMs+UCi[d/wbdHVy'V [{ż[yx9s v }i~Y˚ ZC/ߴG&~dBlK20o`fzknlu0PQLn\ą6Y^%"wL'(ҫ/kx?Nǎ9p=ݡ./EMóף_&Hpw;xhC1ڰifύs%nJ#7}ٵkX쾽m[Y~'OBkŭNd[V괙]O%~7풥Y.X0 BuAj+pJgm7Ij":1iԗjDy@裢JHt\ " LJW&V%*@@'Q.xIKK=w\ 4-YϺ"3 A)TUWSx򩧱1/qZ<(%(ByWAVG[v|^4Tp>ZPq+<>u4z"M殻<6 ~_:6l>i&ΏHs9 ^)'͔fh#A?e=ɗ xh{1:j6lS`?8?u{}mbW1{˜>~"<~ѥyZeSM @XRkI J&ϓ9v[\C#mpۜ>}Q:C}9N?N?cM4;WvV c?A@kk.&&&8t ~ť֯OcɒyQaF{އIRWJ]ErZ344Dwo/)v'"eܫV0ZrM۪8dۯ|04:Ym:feB[1q8 (4J5ч冯jlYya>Ւ> zyjy]& M(˒+s1jkw$.^WeY{K\.w<9I&Fe(OհV),*Ph䃑*]Oh6s8C\x_RE)D Ѣje 0P Q,,γdY?(qD+ӗ9L8wģ/]K&(C;N9=  ڬ߸v]kwlJց\9l.>~o6}ceg&: "GjV 7ɋ\t͛62fl0ܪo/2Ņpabщ 瘛[dhh8ǘh]*EK./7ӧ8<3WڬY^}eIZ&/_رc(f6Ї=tbj&USoEKa~  "K&<7K8us\y pW]땬`{O>EKVگrLl'HXT )PJIX6u:n]UΡ%M96N%}qqaA[KubQ^hHQ.u>?^EUYjCC4kW@7BU4߸@$!~~nظoGU1 A:k!467ZBc/b}b-jд@6 IʦMp펝 &M ~|~qI:N$sx\&ťERc0NRE \X7E))\DƠ`z2&Ο=&tZ3:Ff${:d,.-EZcz8Ie6KW&{SC}VPFE6 $4pڣ*{ѤqYE,ZVhUFFiy/>W+%VHRQ\ij_h)ʒ6(ʜ%I,\I? B 6p!yi>༃hENF@3[2BAI_"|&'R'knݡC}ݻyߛ;zF#Ú z}!"y/{f_ĄĦ"Ůc噝cIm/O,&&^=~gnn>ctC8W]>С8~˓X\\x_5t0iJfz 6aM\svW8kȮ\X[&i:bi*z/Cӿ҇^5rP:},K(:<]>pM(KA I JT5W%UЉ&;nQc/ŭ(65/P帲,t/Z#t˒•B&NԖ,juB"x߇IRe^ EyT@qM{2w~~yFGG񖛘2Aދ1J7 H#k<մZM$tģc:<(}e£˒qɟUțM I##kdܸck^Y3?/2qXI A,@΋~$TZVzG9q83Wؼ opަj2tqwN8g7N\fzvW 1zDh9zgy}q)8#G8~'Ӝ?ʼn zy9Dt $ݪUmF[|zW:ZFg= 2aU[٣]^ͯ0\/f_j3W?\l4i6Qʫ润k]}eb I^u qE42L76:u Йh:d"!b+ ܘ#_K91\&hc(9&J25*ԳNM˲$4MkBQk ܉m eQ_YK@ 9~%.AaH(giiM6ʫrܹw gIBш&O@I #^D_!vz* t|Ip! VdSĝİyf_cP~]Y?yf{9HsyQRtH"$]?/a^*ĨFU9 Z҅L\8pn=1y]'?{]SS,pe06$I|pϝ_:Pw~crlܰE%Ξ;rabk36:[O]{L Aǀ*)QVY§xW ;mz}4MZw}, ԶdZWDne\jc@ջb)*~?ĈaIד >D)ZLhb<OPCrᜣNCev/ i"yq h#l܂+]Hd\srݝ'1&gHX9(JXs}RY z̲i&vチqP((9{>84scI4IoީܷT-P(f<DEh23bEیFƍ}Msz[?:'N;4h+҉THiJ{A*SRRE35ygN%77N/gp~SyK&/sp_yG 1Klw4~PJSN֚E O)cs!&.N`[n{e [=!8Jsk)YELSISP*H#`bZ&wB~~ibB`0ys?w^t]џ;_e"~96U*WE*7H P~Uz&>~Xge3(cB•b Z~T/Jy %D4E% ,z]Cou4)V.eA?&$;W*CףS9 Գ("+eɚQ{̬XFO| N3鸳 ^`~QT:kܜ!KB|Rmę/6l-ܤ TqM7_2=gUڝ&ZYh5'M eYn5bEJQ22E՛9s%&8},?ЪaVf.|~38?$/{eS3}ysgN)TщmdJMR5p_$ EP:тJ~JW8c'K,o믿-{!y_Quqwp)Uxs 􋒥~AVrR> hE'?DD+x!^a Ug@84y?Mpn5_(k׎2??G#m|IY:~GדN?~4f|-KGj+K ={g125ckqjWj9?~ Ǐ;wy)%8)ybr}< wgqnBDsڧb5?; H؈dog]e |bOFH`ŊNEشiN>Ç LeBs3qd9.Gܳٳ暫$ J:KG,I*|+8.cV~ IDAT"ZƐ9JR > >߿V8!F>_>n%KS)A+|pV,r+ Xɑ;I9Dpo p4 q[1cdYF{eY@EҰ…޻XFmcWdΡ2gN&A P`PF>:Zbxx۩SXr%v@Ny _Z-aÆ xȠȵ ,CI hl r8c`Is~G[Cs<E 蚷<ϑe['!jc.h λqfj<$;PJCy1_42u7"$,+uqI=A\]SG0;ws"(JuT)Z{1|aagϭvH+V† fP.ѣGڵk8شe "G2 &.+]!o/>i h6x{ރ7a@RAcde[0dX 4/[p}kʂo68}$>OarjF2C 3,z+]!< yƇa5> z>w q}Lx6R"rdH枧*p8`FV @(L+(g*'([]КL3`ldKYjaՊ1\zNъiνѨy{IBlS[ J+%InH`E9c$odިGΓArPY!c$Iz+w]wyD/`f?O]b]D21@eXCTB\i[BZDEiX`bݳx'0;;|.ٱcݿbffMOcai szcccq^[&t'3n{+mڌNKEW4J% :z(yLNL`E77﹕\ ryx9ٔ Vto1cQryp 8s k_ jP{[VgxSkya#X8Hs&O~79FFFE( Ot+yE@3*Iܞ7"6g+k\DX@e v9=B^ %r⥀^C.9 Hlas$|q {Hi,"!)Lnӽz2X#@irH;fߏ= )P')i* 7hus@A+邔(͢d wtMHV`3u#wN~nw kpMoO|S(Wj0&~2F*!H$*%TtF03`@兀s;O k׮;n t-ka~yNe835aO;g&0s,ZK QQ 5HR#I 5`ݺqŮbdJkZ8~84ŦM 8p, 7ވoQX>s&\?IG/^C;i/P6=cKwKq1\qxߎK/ x硭ΝU,][SGvXh 51??{>h4(%dY X,kQnsZ~e N.D$NJǜ7.HN*@sXEK1 pe)5,\O>X4.qõLq(Fx;0FdkeV p AZc~q[lƚ5kikZ#4ju<裮"R QS΀!3"ttmG\Rs+sAx'Jb\uX ߥ޽/wݿj 8%EHZ Z Q$7uZؔX6h|&G'λjժXS~sg\s9t:-(kP)U022jD@Бq),̞GEرc6lnn XZZհ/}Ap&sN\~ <KkɬSHÀ \|_o_ꫯ?RB >%Ϝ!S_C^Cߏ|333Y1 xԗ(D=rѱϛiy?ssD?%+c #C3*=\C:c",, Ӹ0@,%T&Z7`X[pA6d: ar(N^ɲ IX gP|qHd>N Sן=ю  3Zˡs )< `MA|IرyF_FwlR)Ɖ0>>Gx3h[Xjw]0(@H׿{&l61:Y gEn[ aeEAˮI)a  > Y͒=wtN7ɕs$ )8ODY :q\ϝbɇeY $t?krLoQ0Rhkɭ,`a+~ '#%1c\*!9$b\ _F6B"SH 4G#rX!#hR#ma[b&pV RkAiEnpWO?4C11-Yjr)&rN\0G*(EэGg>g=x[ވZIllZCE?ImΌΝCɪthxK5:Q8r}Zv؁-۷sǾ(Μ91l޺ pȄBA.ZW cVSEHg`\7Kp2`b@Y5kր;Օ+Wc֭[QkGŧ>)|_ 4p}a|4㈓{oҁyHm Z Z<裸q!$q+WD>֧1JkD2Bĉxf9r196aqA6.>sid{ͱ 'Mg`1 RndeE&3.ʓLPg-G,"@fh?M3sC )֯l:|^K^_kQ;5>RI j /tv vyE̜GPUqm^g<(v6$a')84 $G9)cii 7_2^:tg&qnySS1>~ ?ԟcj FG $w?Ӕ$$+=qMq;MGd9dυ˭7e12J?3bo:N7(hK@ѱƩ'c̜$-w(ՆZ O%1[K9W|o-3ю/`lb9U gu`l>^̰mf$2U`0 X1hM 3Ȟ <ǙtIj I*JH[ G\Za׮O2#M _/<?RH)ip dA 2 W7e.C-\xDZ05AZ[.? eѭkLLؙSQJ#%rӇpߺ!lٲׯR>;^ V^a .TpcYr$rl.blnO>$/ѣhZXv- q`adlJWSxxb8a8pg=xݕW!rJszp\ȈHlbbbgO~'OBZFkMϪ}Ϻ89L_r r!])E[iS^p:ށOϽx>)8]Da,% wHx2EDN\ =]ȕX^iJ7Fy0]oó1tƿu6< GiM&g7o1iN9 uysZO?4gJpCo "p͂A Xpr<8~_CEIZݻ[.?|TJ=ˢ @9ɚv0#"9>+iil Ԅ (J^:#GN8+eB]5QZBCc > '`ipo% &~uq,$Hs]/3kI||o&T Np.Q.(Wjh6j!M*sBT_*E $}N)%*֬Y;ކoz"BǏ+a-p)ܳpf4.\.122ciahhyAeIUAbv)>|k֭ŖPBvD1}[&%'oUhcghZ˸i-sgzY?zX\\32%@Lyc`IUC[oF+U|[߂0rkqM7n{.^VիW둓_[N N[^gW|'N@9ѡq }!0RʝBk *‰5ZQTxoƓ_FK&#JA:$zwA|`߯⑿(¹ÅHKP/K_"1׆]ޭa\BJ/KܚCsH8Ma*̡pv 'gIHMζ2oJT(1VC;4874Y ׈*Vc5GE}Iˠ`"?NS@1HJ2I1d7;!%_p"9~f#X(4~dW8 ZeA9j:]|1"4ĪY>x1s^(1V\J\15Np{?ѓO`"`tkB$ ؼu vn9ef>s?buǿ?z 0E@RrLLabe#Ip8>gs!I\rgފm۶A)H } 0AR=dclJ(E{g!y u1Έ1@i0!)[jmy8(Zֺ&$4DK 5'{[U C^,10q,LM{$ IDAT`x?rQˀ&]1h2'8vB JteRyp' 8wzgwfȿ V }sN:z߫ T~!D*'|B_͛qCq[mh+2 N ]͂|uh %9:5GkW=TZf `iQe.J*tz`h( ,`<A{sDRBpzr_qƻpŕ(}\+|0:m_z N>V4Mn)K@ҭht]hMQ.AMk2I;v;6l޼VۢRdYTEȨ Z dGhM$Ixz022^\u;q]o;/'jȨ *$rRG//wC#03EliѿVUBJEĥ[YXD2F$"\i` yV4͛rxŢ!n!%$xDҹ*rp }uE/,.WF$N LGOH!f{PJ9~^*Z\8xDš/:'?" Ar$ 1c0NKnC"Ir$bT*_=ކewɯ}kܷgC/ET2@2x<: 7Jp [{]moy3MBYarc`7O6c 1 ILMMaը5o|y{nzmXkQ.q`Xq#UQR'yx9*%(8q^矁8j*u\Br*%4MhC`3ƙQXҜ2aDә e&t͸]Bp_ni^__vXlacW@T6?I 1q@"|:;;[lٸ V&Zax e1F!M{nE^8<-W~Cظe+ !i=8FRo|a6C#0Vh#E_Ox+ְV|O}JC%h/,iV _Xj+~0`ffS'O;|#KKKKp%`Æj*kd!3h9/`qiV yCF ­`ܖi*FϟR ;v@lA!$,gAmTJejT.L9|_Ŷ`tt uHqɥ.NCQ\:65_X'sU)!ϳ@'#F,E]%KNo qpd`Rc-4"I7yjĒfƝ@eogkMCyG&ҡ+,E%дxO SF;(E &ZXCnZ+Ho:`VZ+p\*xX#*){d.~/( I.gT)QYo I"Tk5 Jc 6oތnigyY3϶5:8$FP!eBN,4(r4(7K y tUQ`sI^(ί9~ef,%LTk E]F4vK!#5:.ZmtbV_ +o4`T8<}-8vȅI"yR3q׾78Sx:\~/<;.M7ߌ>0nu/ W_{-]ZeRW5y/}8ۇ$IPV}]xpD n rD<>GdzNP!"4Вҹ B3dqQFV@&wB`L{c!D 0g]0c<p<#*C)NB~.<9hU "XD$Ax:LtXl0yz/<Ξ=ѱa4(z sA9! n[1'xϝɣGcG?233Ej\ga =jm,Ρj#S9nHV`ʕv;Xr^Nq$1 }^ͩ NT*abbqlܲ ׯGu`^9z=s砵Ek:ص #CÈm۱rjG.MZw_wy1xL4!y5*e(E2XUˈ!z9NYGqDZs\/vdM YΒɑ߳cπ!LF?.7F$/| ,H>7,|o](yשhB92pJXo#(o0nxM`zJQlsK-˫/NZk(kLX ^k QL+&{Ch@Y0S$>o-kd0 *oA39־7A[x?gSt ֨tƄ ar(\V68I 7o;P+WE̞j9Ȝ"hzWbƍeBd=gfPy޺\Ҩ.( ׿F墿x9> gQV+ }TA^FR*-Wq!l`\ 8u\uq;$I2@Db+>38y$;3ӘDKa T2qkd)* 6n܈;/e;_!"' 0XZ\Ԕ9NVniݦBBaҀ47]$cp9LLL%:՚CM AFَ YΉ xnŞ1fg}clt_ZЀHoXo\ x'ڇ{ϠTPu-&Te(B}z6XLs8j@"s!3E+oFKg/׆Xk%$]o*$0J<$.9a\>ʧkBC)%z='ֆE9`5{9>D_h} l_u KQLW Fpn^ ^ATJBnCej:;_/cv~.c062 EJ3Ibk0bA W p144XZ.S#]w1 OT8}NS!)E8tGUYC lJ2RqLWxs&\{, 5QDs k2hÃA y؛B %ꅃFd >@ձzo\htAt-cNúի/6~F09e tc'N:5lټju؅}/RTn x[墿a_[6>???jձviXhШ^ ڳn7Vn.aI))JSOdRD[{n,-K/ı#8s nzWHD.<2AͰi}0=2arE(K,(`Kt?#&7i@/3v;L "mr#:B9 vAqغX蠋g<]j}g8?ѝOR04ku};.#H_{3kЇ~?(C#Cضus(!Ba)gE?cTUr_~Hp2 }{G?y #ÐQ!%GR*:`9ҔR4M4(E+D2")KX8D "EuX!U)'q)C;CVCT0&CR k׮Ŗm]Waڵ?[Oi3Sv4igngIvv;qt`SG0< ]h,%[E3I,B`X1kc$wQ*(+_{o_+VX =@Z;#㡇bld }) X&8Erc f}?@q:dmiHV(i V0 ߅S7/h!8^ &E0):冚,Pb𨿷|χ)^ Z k&CQ ӿ8'TC2 R(! Myp㳜TJ@ 1Ng/-aPfCf7pxw7fw@aH29GR)׿-,Cz(I J?כ$e)MXqw 墿Z ^?|F }2:*F)GheN^Z9cךTcp.:\FмQ!SHXr+si3pke*ٹJW.SH?pxS7mt[_=nzP5j^=ZHJ4Mq~=}4Auhw;t:vH4k]Ʃ"#n >YwVi{ymw} IDAT1(תkհAzTb8q _Z$6eRɓ?1]+\-6c ava/N/m&R^yn&^/L*nD]lɱ9w5rOb ~TOW&y T*8n|#o-B+ r &Oa!9,Sk?o t<V8ci#g rܙ {q9MRhoM0r(Q`Wd{C>OLJM?2*Lp/Xk!"&toqL TrKZmzyXݒy'(ɠHK4C lK[8膡5c,ψr2NpX!` >߃}3@} r.C?[`wւI׊9=(Dl(_2JS(>ODF B\cos + SG1ছnƒ_1\PְayP&*2j5*l,XK NlkObgXl`4j/n[I)r*pyW\ǤJS4j&uN9&NƩ'`j ֬;nUH\T)xc<ϱ8{W&''dvvNw}ehPJH(@Ktmu?PŽO4P+%} i&ЪUp4[K+isfƖM[9G/M rSR0A+׈ḱ9rκԿ.9RD}9`&y,$!ΧN*CnA2N#\3! Z( Z{ 1{ ͮtO\13A(S%)dݣȶ*r9NRI(N8/y0)d(eW.NboyQe9J .3vs+k}#*f,Qݧ13}zdYJ.8\PLF*ąߧ/\{+`JP%Vm\|A=)e'奥!~?,Xԑ÷ipxxȷѴslmma8nn1Nauk/޺wxћvx$;/wdS@Nٿ>Zc0MDB۶El=i@k;#%Kxgq.?1W޺wwGE۶nVc楳I n֗Bf>^ @L-m ~.wYk&sg` pw{KVǘ1Ν][x'0 BS 2;]KR1";Bvy =59 ıڋpL&DyͭGQTC ΑA,+th`!c-75$CY}WiAHU! [-{,d h[fLK#D/ډ3c0Xz1MykGH] +Xgi5BD[[^AQTp^'(zc+7~W7[03#kaNp]h778pr5*hr`;p8ļ·Q#|W ,wdgye05u),K!RVg v%++DY*Tnݺ/-om^Oa{{L Ymp4b2mYW$PODݮ>ٹR7)z)4 >"B ĝY8UxX0p09.x'at:{&'Yc<[Hqjs Ƹ1MrPɒNDwc "xQ.%{rhQU۝}0"[S8-ȆߊC%r;-bpΡ0jX3z|kA;Z&(>d r؂8e Bb);'"nY)Hmb*I[@9Dw韜"IaÙ>aus~}I+~hO$ CgE!`P%q䢮H;ߚeJ,KZYsOoe99Ɵwå~/;x _/ʈmegQJ|,"BV4'p%b}!666pzseYb4_@DP ZA@y7=-[:}ܾ};O 670^]@K<#y&Ef'S\~Ծ~T99k`kLŚɀge&fQ.}Qb C ":]IcpCm5 {r`t`&<`#0G8:zĚ^VuxpzvWlv!^-@&bK xItT#*tEXS6b˓d,POڊ'ݒrPp'0KJU_sN&)a88g=GY(M 1 dťPD!}&4zBK ,=+*1iEۡ+0)M|uYX 0{ ֱȪ >FX> J Hq!'zC NN"WW!#~QXpkz&,Érx8p8ֹxcAx~ROostp|䣯ۿͿGF//{L 299oѾ&ܹ%V0k>kP*Ύg}T ҍCD&S&t'Y,<7fتD#2?Nfsʿg?SWvLB;YS |)b7 KaCB^H;xT#d$,$L2Wi-VWWewBd6 a{[S 01f zt" B`2NT@r/w9"** K) Aȱ!pU߆pFH N@b9:Q¼.Nrs rS Qr씪o`֓C@]g;-eXh*^dۢYu$*K@LEȗH_eSƗ/Vd [ _XA=` badP_OM ȢNȡ'9%DmCɹ 骁 oJNDTJh Šh0O>_~:|RO?'u` ]>wO,/ǩ5 Cԍ}u [x0u1ayy(=Jia`2۬F~On›gQ]-m `әa(ư0CJlZb2.O&{e$KWy,M+i?*)qPuv,F @&)MEf4ĕKڍ1, Gs.;mƤJqBba6zȺ0F.>AtchundJ$kD5uKm lQ {ڷ%T s`` DD4j5E@^s au> DF_e^_rYO4>:-ncF1c Bd ?/sTGA#{$#0{$]A"XZP.')޹[қt$l͞{ۣLZ2(4iu$Δ{sF C% hIWB .ͪaʢ|1޴ cE ce*(`+i!xղ2N;h,`K{J E !"+gzH.}zpE){VEjuU?DmoIqm"8Y$;V ! .5/?)#ţ(re)Qn 10o ʤ C< Uv֔.t}UG ^(~ 90rgMSsWHٴ/" ~Hپ'1}"h%ٓ]3@6bOvU5//3 >W ߵ,oEY"hrյUQ B@TJt}sTU-lllH@P"{qvXWXQN&nDK,#ef4)ݾY#q6ȯwx;yL&=<< ɑl&)΢%ک#m/XK龪Y<ؒݗ(yJD RJLjW<}ډYCh[`&\qK1k W.?" `g61nmy.$pʠh$ؠ!KAJ|H_AQv'@]Cn@!e/"@ sA$$ѢsgH1 9>94a6c?j2X䵏< 3!ZCF>c`n$ I̱N]>r޳IpߣW({0%ޥZ]p祿3\poBԉ#" "RcFB42TNqzqxKbՓɨtI.e1)ǀur >k]!sROH#^į7{Z{{{?q}YUr( nߺ+.\S ';15°{ \sa0/@3KD?9a`{CSH5~OOO޼~cpmptt1OQi4#%2BVJp]YlDL*}♽%y{PȈFlzQuJw4@[7 "x>o&#l9; ɭgHpmOQ-]zPߴSVM(-O) VBV>Ok0%ǙL>I|ryH"zտW`d!CѯyB:&S*L|ߊN!=;e g,` ,@BDEı ۷? s^^j{1bQ`!YĖrzgLݲQt8kAЧQOYfD4΀MVOmp'Y& A7"`0`8bP`&eÇ_|% =$>)'wEןhS8<ڗ f1#>-o0,KMn @Q9ܹs;;;(}QiF5oggwlnմs̰~j X^^Ζo=3,--m??ؕnݺ|m+>򛙌0s4S@klu_itǼŸJғxiM{oaRr;8Cy}{.ܚxGh<^[z+888ʶ$KVTd_tduuBJ9QUnFt:̈́c6l(a*>Pd*BDD]鸣E0S>2_rzg#+Dʼn(D@*{h " M 8AC HNR' !y}0sL`p0x!=NÏ;6z_K꽻ƽLzR!']1 ,Xg)$b\0I/&ٖ+tʭ!%}Kꥆtlf3ܿehIԽ(PԭJIc|WOqz&ȏ>}ĠkDU9l0%066P8Y7`w>Nol#aMmq-ʸыéMlnmԩSc^<3vwwF}` ή{~~gK/-1̅7d?(ųV6DeH#֡2y!L|xxď.xQ#^An2(&Id}{zb^.#G/m[}2ƣ%M||wW>"ڃ 0`5%Nbv%(-=7DD_^AFRl%)^?zgZa3v1>v@EE)11P llksgΜ^A:)'wS֖0&vi߶->VWWqYI = ppx7n"zư$"Skp\=2m}=lY amd:/G?3?g>_NWcz)PBӢArYV+|]B` /a r?{1q0(!%غ#D8٩ "LЏMjg YQkW|dAY=/ 8ږf=.H!HDE7q6Z L6$x2UEو.), }2r ${zӅi3u#1Х: @"Mg\r9 ;m/OAߧm X,-  <wA;"@dX*6`A -l|ȫZ#TZ]!Y.iHܔh0!.Ui`@Vu٪G[>P5&= k/.#|De+ܾ <Rb#,1WPZz /}U--f{珬Vh8cd;*UWUy̌;L&X^YéLScLSuu2Ǹx"6776` b*ddYsllg,~]'S=[f>hS~Z3Ms^b .)Ll IDAT7x9b^2'6 z=qοO4a~ILF:U+SON`w;g";=bg-Y#R1w5͐Lvk|kYS#t0^>c6 u$!QR> H^d6DF<ڦɗ  [uo<"B:ԽY;Fl7bdBt-RX@L#ćE@җQ7.ODV=~>eCQ}u&A㏩>O]c6 i7j;ʕȪR@;Iq2B<0$Vv`޾t k gΜٳgB({L~%%!NA+/??>#ݾwoY=|ޠiw8e8(KBMT8\c1;r }sOiy15N\N~_P@u;ǥCUּrz $F٧f76-o`}΢m[`ii?{`k/7IQ&=ge}H z!F>(DdZi\)eBjB%#t8H^H _ WU<ˠSB#q$DX1r% 1$}B:$Eg@T+Fm$iI]x8BL#y!_e9iX9r(S,qc'?IO>&>)'Ec@ǧǚ0 Z 屓Ҷ-ښ8A4p76QQNxvw+6xS7 ~^{x㍷d%0WZ9BOgz?[ {Qa>yOȣ;؅@(6dC'JJbP-FiڏM6&d^B1+S6颖i.uWqC|REf\v+tKKV D{D)t7u)]8$&y,j2+A}҄)ڤ0q=8FlYL@ c:*N"ms' H12^j!0oP8)#r,y܂S,N͘ N[ڼH_ O OEeOV ]ː.[R'"N;`aN 匈[:Gwy1,Ӕ@1EߧiANrc hBİ7䏁Օ1pԩ-ȋ/O~8<xC:ְ( PVgL)77TPD`6uf[[[s Fowlcw>QTKhvpxxW^?c{> wp67‡u=Ged5LN #bvS*!49К&`n!vOQ)U.A-`5%E>gTY#_/hQEŰD4MFl00yex|nVY9ar!2W5%~ޝlBB yrТEY4ⷽp452ϔċbW˅hz] j+ZyM\~ R~/tЧKd,坋A'BmUK_z aM={UUO}Sxcp'E NZڥ9c IWg"!FY9hI=oqtt8= WaVa(`2C^`EQ|G?ß}W_Ew0 Y#߽$a êPqR!pcOdB?}VO:2ݮ5yoz,h'l) Yn `«QUY$ Y%ѹE>zCዿp[xǰ{q]A390EYk1.yucU )QO)& cW1†(O9S дk=)׍YԚ$裌sd ]VB[5Ւ) 6 5E EH^yww,Q%40$E;D? wa">2!Oo_3a1z^86O(%^˩ﭯR޽\tS^FW,Xi)|0X__/accilhӧN?8u %f(ZmCNoO>?7.]MpUUl5vpOy9|݈ڶ,;UF") Rz]zR;-F=dG,Hu`*Ko [̧7^~ꅐI5=;S>u u$42=?7oG.c:h:7| ++X-#xƠ -D{̬I牎XneZдֶ:0k2‘CkY-BC0Q(|emXp7kA, "`("Ƥge:yd*3w.,R@#"c&'K'6 Mm>q!{B<ɅӅ\Y&a,qί30- %ր ´!pD96Ns=חǫzxRhX6bcgwwヒ%cee%j)NvؽR'ը+"/>4n封۹fTlgǰ[Hf!,r^I$|\ CG7Saq!pT(.@PdW^d:}LS?{7nܸG\t:[YA wal.,d'b 'ݪѳb6F;-Dfɂ(JD6!r~_꺖.O '*.uIK$۶0%2" -fP{ (t11 du;ҡqjg?k`&F6VEZQ*cQb /MΜ^1u5BHӇdB܅8؂5blT+|$]B5XFfTPd 0m#]75ll_OO>D?<:6771kj KDa0F5Js u]c} bt̹/h]רIK /bii gΜݻknm™-^A^.$7D 8";{9#u#žXǂ!G3s7Fė/ qzf2s7D#sCDOd<8 ~= ^[ǽ;v:V.K彻,kc a1C{e;MKY; Cuf )Z9:C#6V*L&k<Ʊe)"峿f(GD-ڃ8…K_4`6mqMƃ{2.\s[g0sp\~o.uo`ǚpJtj:&݉J\|j,K[;ZH2p%+yh9f{] .]'/CFaA"M4 C1غ826Rtv@ƣ1G/7&& GSẃ-uI(H,65 X2hh:z-uܻ4D/+$#yFR`\E{k*`82:#| _|6//şG!"XA[ʼ3ce$Q ٲ,1PY'dfYHNX;/]Xk)޿ut2`XǯʕǰT-j㋗/a\v 7nlӧOc8X+x": 2Q=#il:r }aR`U .HV .>Z͉WST.sD>3Va`cM/^ĭ[wpޞ޻x o1* TE!MZl[ªrEy/ɢ1!$^_Y%b+Bc)$GI_~o mx**dQ:J&>f5lJ((s!9flXOHO } @jz~zF-*]&l/Ȳ[I";LדQXb{gK viIDDooeLSOMJRȋK#oOՄ/x饗O<43|W>j)Cܹs[;9BY XF#,F8uBlMF>{u=!`{{on޾X^٧¥ A)jTu_>ڵ7\Z`X.2uT\8N)Eҷ"Jn*ڝr4uũvzID`K Zأؤ [8֡կs™z#sp)hbs6`:n;wd 9UOs 8`MB0G)O$YS0 "lD)E +|..ie/鹿\ehP8H[|ߓ#FP2xI to% Gi#n")HPaVeK~"I3:$N4EgRi F&mH+/]ZS^3g`uuUę,q|SG ;><\=ɛnp"4mq*\tIv޽~©6Mhg .]5ܺs7ohYM-#*h{pht⼤ȓD?HB̅ԇ|7=Q^ýq{QMZw%YBг'3Is(y}Z($+JӂtH^*YÝ)ӥB<]HNR@R"BHy$'-jsKK8{%LO<^)54''E jaPL20<yt^gHxhKAs.]ڦunҡΕka!u'-اOp8`o{ Q.ЭF¢)H'IC=X`~gJe~"Ƕtq.wYy:=Y&GFGXbB;U/G]&Yn9_y@IvBY`yΝ{Z?tC\~^~ Ԡ%lYeCbanX-c 0: J1VG,ؤOSJJg /N/oAZrY $"@}2Y$YR S1$ôV>g_y$hE."屃^\NU7u؈wa/yLwʗ.ϞrFO!;=|nWD"96 o)A}:yy|/D+±+T/x9Cslnn>tmc` WLO)۫ IDAT%Wm2S o0 Gp`ec HjBφ +`xq\h rR\IJǑ `8y0 %d4 ɤ dP)A`M c^R )' ЛIY~:tVlS*޿w3-n`ݥG 7 UQm.lDDrV Qp Sms A:յ!}N(pӋg4jE:3$ga`(VHbKGɴȱIej47w==RCftcӄ$I$h95 )GY[U ?AcwLvs|vR?ވ>,]%67/?Hhbi.'E?1Fjqe @ GBx{yyaeeE)[ĴB}4ML t4,0to:D,2 P4k^tMB!k3Fx뭷AUUfpA?;j.9PbSG SC¨V`(lVGCd2ER BUCj;"wG?#$,k%G~6I 6 Y+]m3Rd K8B6X__x4t2amc]|Md5KR(J2=mTQt gHM?)Ʌd 9){ b2hЂ ?xq}C S˸7' Œ`tɔ@/MZb$EZ\-%t֪E.q+^$1{T*uYsN"^/">ʫ֝c ·j~u'EcCUЍ+R}D$ X/c27"t?a!|`ᣌ#J.xhm.ٳ :n{rn[Ak֠xi<4]c VWVwt+ߋ^d Nd*TN H40G B^iFucrIm L~"r\d9ıc0*i!О7 Dhdwŋ888Vqttnܸ!ѵeլq(rВ`#}L4;I *]+P( K!佾= !3 ы>P8Z2MAK E&iEz%Dm,q;iȐF:(e Q2_* Kp@\n\5$C}G|.?tS)`~;+II :yc{|a|>_US?؅!tK=T*WdN*\X,C>o 'a6S%AjZ3G(WȂMx%:~?>ߏfM"E!MqeuFQ 2qg۶ kH/x%L- a68M%0' _3|h(Eek N>Muo1yFeuj†P6p!x(6g5p{{h|Š-ps4Μ^Ci3{F6:'+kYt}]˜OIDԥa^u~?J1G.hC򩘪خH$Y Y$ƿE3(v7HdtxLk DWÁat)T?O>$>OӅI):y杛z 1V L@JԩSw:u* N`Y#[pmb&]$`$Z,P8󓄵䛽4xE %d? !\K(Y~l  0=Cr'7ʗ>0G)(dh ε PrG\d!ـsN.q^]nIuBa*6-EV K!Y+ALȰZ(Bx"^u|z MI :y3c8OO_-+`6G {|!=)6 FKbwwKKK/{okYvs7WCWuM]j&T7&{ Y|H$H>DbqI [0vBP e*vdXp@"[HQ]5z9{ʇ>VSKH#]z﬽qr#Du>(GЙEʍ0@p*Ѣ]Xڭ;7]+}Eq8R1FΝ;Z-n6n4m\wwb"q"=m=]RuEQt#Ѥh3 uQ!~LfRQ/+ǂmh=t$8( bdQB1Fm#b:8L3`h/^$|1ͷp>B⸐(EQx \w}+W8)Nqo\jNNza).o-BWCC@'v"#EVt`4O k/c~o H ^%o"0G@Qg\&. 'ƘQICݳPu逶_|/}#TUåҵ*O}cKݻ__8\gBk>&"$rBkR;Z8Ei1v}oVr3!@脇w왖9k+0-DA&2 ܄R wޅRU"RF?\,R !F#<-ciE7OD+ Uh.BNv,)BB]߶G>@S\6@%Vh{;w Z6mN)bQ8-eW{f3ܺ}(\-#`}֠@u⣗:&2xIjXmO]|HP$sݳ11{!edl}M"+N#rF.v9xZ9sBFƥ4EPYٯDS!ab.JPq$bp/daB}'dxG?qY*Pn> RC(" {IШ:[M=3-777lm a`125(Qxcx/;X,X5P.! (FoY$4 {ppЉz֫e^HW9,r1)ԻL`.MO¼'i'(ۺ<7=.x|#e˛. B#`ϩm  "ԴnU*!X=Fk8{m?H68>Jb{-4E  ly=AYyJ@.NwcssѺԭ.$ڜMϫ-N:}]y;|/BCV c"9=v_>|nׯ5yX-GoE@#?"Cˮē3%zw}Sz_ f"yz;5?B Z/x/⣗)>6z"{bԿ*˕N677sXkaBsƣu4MS ](Snݺݝ3;Z4|EB Ұ AU!D4u1 )Wm3`\ ,ؓ@PCkyxkQjqQ[bvR),]6%+5`tÈe]BBzͣlc˓pR (3-0#Bkjgٷ.Esr:kj'r K籨'8=5M밶^"I^ܻA]\_׮<8::·zGǧ! bȇź8<:Ck% +9H! dڇ(ӑ{"\UCΨx_Gk4 YD[TJ 'o! Yxh%-"Q|%'| rhH$$ ILJ{Oveׯ_+~ O>$%=ĻjV?Cu|у CC,tw#`mʻ񷒴 "|S9Y=)HcX0Jv-S( %s[d7`i xZ`8{,b>d*4IΪhrthRw"L㐤.} 'b5,*T^O 3Oׯ=AP`scܺwnA6(k8rQTGXhPgzE}!9'Y-26KjaNmfd P2اKwRQF'yO9ƀ Ff-P"}6ăX`p^$/pEO hbC }ҧxq| /@ ߵU_]ߕ>BmZP1ܾb}ĝBn89~Z;դb[GR/D3pvwDE.}⪓|:[a S(cǬL(tq6M# ._o}mٺXxwHyfK8;g$FgѕA)x{9*?/,9)*^(D "HhƓ {J(Ϻ D(*p'Yũkacc{{{(UZkAx2pȪ19mk2`w `2q`U+m[ .^7oAkRS׿CA༰)w6xœ P;tߣoj-T(X vK7\F.%T$t"Lit7 5MhC7;1N 񛿉r~ kkkZ ljZ`2}uD.EbXdG.bscC]ɻ=K2u!,!S; sYcoIvqa!eHKH )"A)( H+Ze Jw <9 oR^}JO8'Q*0>k/=~^S寊񯯯?#>Xk-{tt . AQ(5.Z{zۚ#s1 4}XB{7`1z Š--ƍ7p|| ,Bd(u'Ǔ 9:V)8::ReƖ:``VXBVe;G9[ΕLS Q3=<4@ݠ q6p^-tåT+5h6x#P 188k{,0_,}@Z !%1Cz>&4OE/,}ɍ9A}fR< H_C+ł jTRw$;]$ s@g}ÑЩac"he'LӁӠѶ-\O~xd0U_]X1c.]|&g IDATyk]t:Yw+Ng2GǦPd sl .@vQ:8]T Xm>sc|#7;;M\$wG]ۃ&zFhCy~||=lo[f $: a}]N VIŷocCH;Y 貀;}>s:_5R3R7A5<\PBCSaUcl{UasCy< 5CĊX׵0u \HXt2wcEdMC)[ʍh7-{R}Z |p,ʃS#")(|8ts.)B8eXޕ?#yHf}_:Fah!6?4*IDN737|a[`^}UKTAu*뻦]GP FN(+m}` MPiTIPt];8DbbPaw.H( @F%`(m\tϟoo֭[R ^LXXٹNն-nyW._.Cڳ*jhIx5 ٣MF2$#>ySƼ.%c O9 lp\q! L E1JZ]Rf<"Fb40h%8q1X'A GFs E2Fq4BK(fhYF88:Da*hU!?X[_gKAF`C= |(@wQPןuA(N'! d\dڻ8/<)}F'tODnX ~%'Y6x<ƫ| / mllsSL]K'>C??&|'>`U6bQRln (t3.9 [[[=q¥R Y@(|kK/}ff48 Lt bM@zG⤯y Cw=t$;l'6~uL3ih h9S Ѵmμ>n K\v ZԖ ucƈ!<^qM3F.Ұ p۶-4dJ!Z)Zi,se20{E%^8sCvZ<6- ޠ( ĆCh6w wpW6[J%䉷= x= A 3|VM]X[c}JT 8ۚpI<1> lR:l9ηIa QVkq$xw<Шz5Zt/L|b̳h 1mD$v&.(ã4 $8y.{9R\>D^¼w 4K<}SГbHZkhvպqEx&TK+յ*{=K׾S]0ē}pw d.>h=R1 /ױj4Q)(E}Cǿ%; s8>9ZwT6n:666üO!c,S02GamʦAARQ|-)>z4uRL9ݺ`4M+Z(e`-bڶ" <y~ԶE;gqdt{״N|ϥy$-.R (ds9wmm ш'Qen~~ JZ0-I)Q/2oҡyw6NL (F.Zra6ХZc+X,ABHz޵L&FX,:վѨ9?5b| A cޛ$, 8@]trʢ ILcQGLt UP4 0U [7j{``QA$⹦aO}h$^DTiڴ-CDexGl<"`|Qp.f.BWcqD!yXHJLYen )x{+#s9ݘZ/HB NR90$G8)1³{DKB&Q<Rq|?*@~")A!# '1B~-UdtZwi]dvh4믿W^moo/~Z=4_J'c?c?ϡ װ4kk#myZ +{8 ]tr|W\Ht:t2t>A4X5p0C#Lnk"<x[xcxptȞX@eRO6FUغ17$0pݧ=Ҷ- 11d(J ulTtOߏ6 52ۿ-!o]?_+596R"1"!:DF.G*"`sⷈ4<-Jn")MV| #u9gTRGNp-EA9k@P #:D+``ͻ~>r MZĔ,`'CsG<[P" /^K/^|?w*{K)%g~qrr_ſZ ; qbVEϛ:KHڶҍ8991)¶m= @."a}}]Y4>]Z"nyaA|:1L1* X?۾xd& 诮%Ycgg/׸[>5ιWEKҊ ucZ.y#n `&G#YUUa: EXж)9(XD%;d DbS_W /( f3nN L@0UɹD:xyCK:?O̓[ Yp$Qc`0X*!qy墄]iM'Jľ ?Ȣ='ԁGEP>}vʰS$);(OCڦ ko}*ku}ƛ6ݿ޽{ы9FU  h6yUfɔ5҈zv:AT68=#*I{}pT'''f3h9Q899׿u<֋0/D ;ut>[R#s_5w7>bKB+%z2::"ӑ; &`=Ack,5H>FI %etٳ@eQ(}fG@xXwnqpps{g* .=YBȻbc~0Lru `k} )J?:I=~ `>_:ڶyewh*u%qj} zs/Ƙ<7!xڤ_QrN4,`hMD(N@L,鲭&pG8r]} /%FQqAuY'FN]6BRja^O]5,{>FT1FY0EQ}GyqoTJ| IS= e3U'MJF, @ŹBa)"ȃ!Z`TLƘZǛ;.]~wWUVis®>ܳXY3CLbTi2U.!Y, )(l-N SNk xo9U5pPbQh]Jnn28<>h%ckk mpݼNtKqrr]cP:ୌ#*$#9uvemDU2Q* N0iDѦqe/P,ST^nXāGܥzsY ~\yAv {?"7Mx ipy|S‹/}{~_յw\@W\|EQ4˪H,f׺sg: pzzw Ցr6Re 0,>3w !^}]E`%"o}IT#`:c^=g0+֝{z2\.@@9 0AsR iݐs8ε5Ҡ1R%R.a84̀B@,6Mwc9|kP;sG!|zz}xr3V)xk>X; _TFDtD(Q׵Xb. I7͸T\C.#yz+ 'y6ܝõƈP-tPp{Z%w' 2E.-DhfT\Òb?uI?Frp5  4b:˪%q|:_i7{o%dEQ x^]BS'KioXgAaѠށTe>+>knw8qouZ]svwΠ}eYb:}|c#}^ # R.H"weB6̦8D"ИL&q8ږcg7qfw^;hR8xphSmk(o P5r\>C[LY¹m5 I谬`r0}aKaIg[)2p? F8{oUy 8ؑDĖ`:ha5\xQbb>"}CLԏ]{.2zQDF\8,d2b Pd!#U%C5 PxH ǏiҒGy99H-w8N |/_]cW]诮8ǯӵǮě7ob<d!M 1F<`5(K8O=(xb|E;(;N&8wvEaœO,P`c]sc霝D({{{q_]0ՀPhSLV'yY*ɳo^6=h7"`0(}DYmsϼY۳@ci<$w>J QtDo>k IDAT=,ѹ>']b:;x<6 G/42bG|wLţ-ENSd$@@(D4 r0T 'nBK]TJ̓PCJV)u1!BE5Mk׮o~}]W 诮ruaU=|_bE=q9 O&f3 \JE=01 z5}\~288:;oPZp`<֦TFXof'X!xwwEҰg`CP hU)#v>ek=ToLN;n :lk*"՚A۝fE(W.H\ qeOz QSG Y5Sa%Q!rxN)=QX__GYyfm^PORgLtBxQA- bH@)x*dFTR D##󘥨.Dl4Z <~-}F+S&lvm[looGGя~*;յ*kuAE;B,~;Lpmlo`{{n>fE!>X!.x鶀TlQDe1@]Pxq-/"(A/Mu ݿlIx{xOԕAs`6[䀔 9ٮu \dztFQ ;Qu"܅V`Kb\.cr3W:DD^D؋yxE!nܼ]̝.PE_bcYh(aQH = '9)no9(D(@fY4'7d2T'd+ s.C:E410x㍟8sO[VE~鯮g2|I<>8ƥO`ksG}6S?w]5a4 0@߷.&"3ڋ}9x~m\r{Mc11 0q:q (tzzʢfիhde h1VIv8mݗe #;v᠔ @!?B  /!zyr 6iO.e3hAKQce2PCs6wkkyzk) -} Q\}.#rD\40'_QA3W,lt\Ik -YJw¾Rxj):1O7|ukQFSO;u U_ukuCؿo_U\xyбSG?\뚌%]8ĎNh(v2ŮKc uuCR m- * GΝك(OcT0i "IQ$l 'u3t'<FJti04\B 롻B˲ 8Ǯ\ŧxzxVEu?ի?=::FGW<#`1a6I޶-w|rb^R/:]k䛹k13Lsb.lDkpf&?Y,Νm[# [c^/]3"4)l!ƈgYs0ْy)j|yqm/q{)a> S᭛oxhѠ.? r=_<S* {S۷4w`|q xz&~T:^D=q9kxR?յ*ku]},h AgyZk0UGc7>X.˅Et@ ~F#Aix"}.^x#4)L0 K4?i\0.@I<Ȁ | i߫cwdN "Zc?S'bnEakK_|o8~Y寊,ipy +iMDn>/xꩧ0L|ͼAb}Q:NNN`t,QVFKTcٌ)~|SqsQ ^nh<5ĐpC _4"Zf6d:kUUh_1t::޹sakk1DG*|M 1ò@mw xJokU;tP=5<)Ňʻ1 0s &;/: 5P)HDhɯ"PR߱^ʨM$Ķ_'ly0 y :"GRiFs^IYv=y'CEzk5_]RW?}ר5ȇ7‡F ߻/~ΝիW1pLSVN|)nX n'SJ:(Z L@@6hbWjuy]D9$emڌk=8>KBA㭷 (ރW%8^Nksa1c:00p{{y瞇 2ʗ_s8pwf$F?D4FN|9Lŧ^@FB߃2oi- !',K|M*aUg0 ] Q}*ΩΚJ| dǕmw"I& 0@yS}p8Iz7_JW$"x009=9 ÿA-I?/grng6,M~ [!?y0-0̱>W6%jaxLfSlm7o=u,s1~gmT(`9jp6BB&AUM"<$[^KCnD}; :Èԝ;n >}y:4:u>wH|C"\u~=тI1n[C%?>>*X}H!PR_ŧ>)QUU CB|տV;8899xB+prx:4u5EP: P9K2`>ifkhoQFqVNװnseJsDl1|>2X[!=``EPAY眃%kr'sM"hmd =dmy?e[?lSC~oύ@)ġ,Kܹ{,ָylll,VʫB7u>Ւ>5?4H>~B(ݐ3Tbn@?&w"L_# 59666K/OF[[[Kյ*h'GxƷ;w0sRlmn+_z£/<ܭVo¿o6_]LOp]&IGi$&+mG4ZNqQeJ٣|.ʶ~6ybJheO f}/ιE{g2'Yҍ{-lllsMl>G&%âxS-݆b^g31nDbpKz6w]w2!D98v\nZ Uԡ(8|M $4HݹL_8LketmTkSZ 1~^x:v}[ uht4艈|>w&*v&I=JɵvdZn4jږ 8hA1پ:KkuϬZ2˩7>яէ߿@u|Ō[n+/q8pp-، ZhKYkWS%g﹗QY׮^;7ﱾqw9k7tM\2[/O䩖|(ĀGu+EFM;Ùp(c۩leIfi7Ӹ@S/؝LYYd $١5RN yżZt}AbV{s%G!MEfZntZ{sc8o{[[>Go H9})^Aoy'PŊ /Y͝1ljc9}ںMzi;lҽ7Nhgd*oDۻ>SUlq->i6y/ωS{ǝwSO=D[Y:+"tvƍߺvoܼybeYJ1Pq.455LX8S7!zbc2lk?__WU;3RL^9>6p(_/AIt&u!e/-KuF2:ɼde9RrZ{ܲ(:V0e(9 1鯃ǚ(]vD(d:bvv9t$9ɚHtjb;B*Sbrc"Q%~QW}`-Sԁ}Pi@'[Z~Wp%6?Ȟ[^ĥ~ !iv,x[2tޟ BF֦h%.l[dGU2GS^&$tʱG+O<9U5: rܺ[o찷CԊǎI:u;vlލB ǜoA kQ'7(Wz*_WÏtwi޿w?cs{c'O0f{{NV?t{nMYkGyS7 Efoo뜓Sn:#EÜe@WUBv!VPPͦ4AdYY0LpQEbG2&C5 Lj5Ml!Ș>MR6dcF㥸QJ*ʣ05<ŀt}t}Zp`ݖDFs&AuGyZ ݾ_BVӍdž0Q~2x z@)2X@y's5i%]n{ȋ<%^'àN&xB Y2Krmk{]>ЍvwT21k|'TYulmNchZ`1h\ոhcO;s@Kca-+VO>RDJ.bAf /PAQ/^t>[V:!"9Yy4!-Z{|mi7Bez[IFVj'aFƖ1v!F1dj/1=BfZ1OiE6@('*Qm Z,q{p??o[4&Ml@z֚ S@SG婯?s:ΪK~9W/]ۛɼDqdžݥIpȑLta9DkE|gӸzQn1Fw1[h 'O-6odXte?j `1vp,)s1%AAcE[ q>2W-a6[P9yoɘdE.-.a61Lw.B`>iI&?1FE5~CC !Rj7MCED)倽ɘ{=ρ^qMI=>@kk B1NuFYbC}go}\9OŽ,ۻ;팙fllctƙOs1ָh,;;H$o@ƾw->:I`ڄvv}^ I"cg#< ؃;ZWgMUsP]9zj IDATUUq fN`m0PwkcdOX&%{+R)#˗aa67^c4NX*sskjin*Pڮ-J*!‚Ra[b<6t,rAIv}a3y-6Y1ȋd i<2,jG=DO bLEZT;a˷|H:2)CDpQ nqBރM:ރ &lWPݞ{ϵ(g5J#@_]n}2XumB,%MNi5ϰpg~dJC m#:F\PdvYT !XI{{eDT:bw  \rAkMngN&.z)>Ubǭ@uٺ[(i{1q-=u٣5Iky:q m-9dyV,;?R4}e"<&t۽~Y헉1yR%7]Gk,)2EJB̄>1Ni&=wj*Ģ>8,c2RU~Wd9e$C 6b|6j"6=ZUW脖xHzqe*7a2)Q<,%sqߍ%੎4t#xjxqK3lnĻ(Ed~I Uim7ʢ Ե%mHIuZ\niˇJnDc;>X)`I\T_/~Y Ek|:+7 7ڛMp9& {{{ub'پI~Dv>1ǀwt7|c3 ?8U/v*âd<ߙ8_ԲδM4*cqeYSb^/IX1c5A,K,#ֺ4(GV %ufZàXtk,߼vɔG@-6ZY~..2w`,XVed YJs>G 0c#;;;?~T֍*ˮ/kW,Bv׍>ӎυ/xۓw{xN%fU"6({- pqM.+A)Pm"]DjZ/-?`:(J$&xyk_WG&3}߾ WgO۝ut:e0)O6I~>Lef3y\r3ư|^q0]-I+UD%uĊm/}K}nmntxb$Zkkkݮ1=mbUxE`P}ݾ(MК,,˜Col3A\z Oxލqs^} n2J''ۣae Qv 2·F1oEh:}  l=|N:z$;1YWX*Pؓi 1t\,FBTdZu6 ƂZp?75mw}M&?׿uΞGطXuw#h|?'{X̩Ri笯w.dU5ҥ+9rǎU7CV"/1j-;yoPSOwEa,D,eβskoш`|>dԫu)xl M*L̄}.TcW jtjl6̩ lVvi%K-`Tu"96ImuZYvTMM@ۓی5R(OLA8ed6BX-{6$F!*4UWE@G\h2.V:Hz7lH{{Qse f*F^V欍MQ GFߢ:1ݧPZ}y3ϱWF^$jXTʄ%EhĽիWpBwϧ\*'O2)<$N_:kȳLuKs=ιsx ^qZ=}KYhL&yd9*J1zkrb<wݭ$Z Eّˢ`̌elmmil6c00͘' FiGx/d =I9߭$WUh#iMnѻN;xP&@At "$"FI|XvvwY[[[DG|p dpNF"a}K(Ta04|(t i?moh\%WSwnOC[fyk ^G%G-dXZ eV=Yma DHSt:iM"Yk@Xp1|I>/XhW:+_=ٌtʁz.~uUa ^2Ka3Nw|s)ɄǏ 1,GhM ._t͉'8tǏ Dc1b>pL'k2FZ&F%Gdo:YYHE>(יˬZPF{{{>|,fX4r{{{Mfd;'1w$9ƞ|;'}R/٥1Q8OU5eHthU)54M&3EcDy9ciOTm8ҤD:}/%O1ILD) 5=@DMۍۮ8]KG~S1];"$lW ,;3_dy#L҈ v^[H5iz]|􃂬uȒ]RrGf`>|_Vzw+F@uqvkDdp4"bAHtɢb0pQ+l`'v-u-2( {9WK:}96o]ǿ wy0,JvR2Evs]Wšc#:˹C,{ VY Yμ({`\hGXt6e9dw2fAA^$WsW"'4h~\\/O >TX:}}t3w(7(6(MFf2TyDg"N}/]^݋l%М6U) " jcWRbF1,tb!؍^{V-X,Us4/Rr~电y79X@uLN5. t,˘N;L&ܺytK㡇;?IJ+, >sY1*c}}K9YcWگ'>[<Ò"y AQr4bLش72IƓGF11v>asښYkE{|6FY'6 .8йpݾ1}!tpL$:"09a"Ťhv]m7:G)N F0x`͒{ٮ.w|0& cvZ(M9YJ]RwSu!&N7$M"PUш_O~EV$YYuJ#2U6^~e|mvw6u}7ar P?dV-xe}}K/>Ow~660Miu>@ʠ/AŎIc%Y>;ML.$bA<ʓO|S߉;@uu 33mdcbﲵwyw&7nϏ_Enu !ш~ࡇB/éS8v<~{uF:JYGjsb8է糟,>' aG(RYwq,Ե#+Sצ.LvpЊ|F PZ[R8 PEU:khcyΨOmB4#$kue{4 ()LB*ĤsS>z 8\rlEQPU>4`iBvĶV/G>hcX3Qr#^~V[@m:%ϗ=-&99m74ݮ{/y^u}?`trK9nͅHI;+esK늞Y?Qm+ k-?~m9G}uÑ'9kx뭷x'o|ֹ~5?tRZ,f8CGhFD.H jV42m,c>=͍LxGy7h6[:a׵68x,a6 U5PzFdVÏ.XdȾ0`{qeוK Jh(!1$(^bbiIn|7VXՈ^tz.Yt.(M z Y&`UijxV,\+m :xB*8V ~K AU7js#)NW%冉{bƠYz۷NFgԵdBe0:lzӁ^CÏS1drJa18s < #?}XY W?ioȭwNq`,w;.7o4N>{7x5^=wmڈ,xW'd}}<+ **t>FOB M"֒"t6e1'bkwtYs]7ߎǟYYt^!-`R|/,.vC&oL-G]|DGlx#pio#=5.xLi#?&|ŘIJTn5Qb*Sd r3^|!3遗k!iɄ`"iCEIJ$nRQZ H}Ndg%CNL꺖iǖ2- ;5/ +~toLq#G|\2a3n{sx]>,/*۷6 !~k=Iò,c^W"* \U& i&39Mp-N>ߑ 8ҁzKr>@Wt'ImV|kchRN$=Y3,sJld%YV:tbk1`2Cɒ}nDND!{Z!e=^u"ĵ}-;zrd׷0:vd{hӿ}}c\qM7'|g> F+1JcQmT ,@f<R 9v]ƻ; #{Av]O Q(v6UU@ilᚆU 7}Yf ɬ 2ptTnA𑺩-M)8/3,atZVo^%cTF,ʾ])ChQ1[1fiѺnA\[qh_R笵,Fk]֤Ƥ`miobp mz)kV IDAT#}?OFKrcsG)\ڍk䙅S=r ISB`j>7'|Jmll+@u~*{c:OS2)9Çy7w&㎓h Tgy+W.8Pg]gF RAjDL\\B`og,cC͗A- =#ɭEϞWyg+ᅬ*Tɬ@E%!t!78"EkjG nnMN?Iiu>@Z\R QQ* 51|5"J)6GU.Rv xLSyII7-%kY(9}ݭMbwg$[2@ѳ%}{u诪ڂV|n4J·YML?wekwLfϟ=áTh[F~, N:__ү#G~'Ƙl_Ӹտ1Mgܺ~x̑# .^6ٜބO=<(]{cwy7!{=\q7yqS :*^'|`!o;sQQϱ28͋kS\C8p;cǎRW5Ŝh!PU y^RU fb"M10*41MŁo1 eH 8%<քڮQ[<ZA^dd6Z06uߝRHgFLUrSɟ_M (m+wWYFSrK=tkƓ W._?MAb2!4 Oh) RJ@g91xٔwz{Ν#xG*djoѓud6Ep 5N<#>8ʡ !qiT X4Egcc,/G W}29iXX"LFiF1dM<9RsDpk9ZrW׀PӂYǼ" пRz@ɴ+4a1IQӧ9}4cdy<|_z7uXY9vrs|??fQWlmndox 'NW_C-=ԧ>k*67oQ vwwI<)xG?fs:_xݷUv|OSg("y9EN=%Ws1DWuub0˛Aȩӧy?fks`si nH k3QqO_d|55xh7pNX7 2Oѝ9M15 EQ.$ $>6ĚƅڶW*MT wXdvFc"ɩH1()<}&T&C(+ye{7BEX,vm'.\ vG)H'ҢJA{B^}J خt؎hesoYQf{k<}u11Fyo=r:s?!^zo71Ml0Nd:8z(>[o<9NkW`2í[4Gf{su^5N:|=o3Mɳ lFTfZZ,129s6o՗_E`0`gC1QBRSJW5u z)8'F ID)i^1)þ'h(۽- bShK)!BQIQdy.2æIeڈlF˼uŸFkCYʢ(KYHF% hUv{AChvfM:bw.A^UgY&+(PP gThpțo[[(8vϟcPEAVk7מzZmlbՊ:+_.?&Ss2v锨Ō] s`0#;bs&MSOq%9!z޻p/}q76tZk._D笭3Oi\9/i]-~h^cJ_*<ѣGD%9'O_Uu ]iWgkgQW,fstGClno3N18r.\d}4'«jѰ˗_EvLS{|kҫ&j*6w8x gDx]ww^2Mzaۅo{d֒e9;u ]^z%"r4d6^d6v Uи#Iq^<%w{ҟPZa.4x!Ȣ+_O k?\|'cv=!sn޼`Q3قdy聏o{wٳ\xZ]pwa{g n/];ĉc4011DFZkٌ۠b@%xBpx)tcYT ^u&:9ży%F\d]܆*}#$Z K8,(EgdY5mte;/ۍ<‡v}Ljk\̧~c ?q)/\s[m1 #Ɠ 2ŭ78wyΟ?믿z__3w+/0\qヒy&QE&yQ5ш9lfɳ+W.sa%+r _6!Fx33<ͷ~K>TYԃ }'*W;o͟<nb:\kә.u rx/O07sя^b2c>/fy]NS;@T,U]6qeÁt:egdGMl:$k]J39}TU͢*/Hh:bzkX{l#^to>q=E@ [/AY5錼]"suTjG;@ )'Fy|z^פ>WΘ÷1o?.οMɋSM)lF4k.a6s ~OWo:ṡVguV:9>˗kamFԚR_|fHK|PDԓܘ'^9()"y&֮ j't3=BZk{HbkiB@~}}`0~k٧Q Eцz tЭ1Z֡Ϛ(x=>>tO3-2; i)P"xh% ?B&2fɄPi-m ?|[R9hc$:x夷:+_A_kkW˯׮]'?qΞ9ˡ17 :~kz9;,Y52my-[l@'ՕB']tlBCW*$t5tB)>/1Mc0htey;a= 6 ~Ts9<`6SUUI fy')yѺZW%[[[{G}ysIwA" Γ9ٜ {[;w u])-k)6>[IUhc )MS uSqx8W'Ţ`^̃_.HZNӴU& RX|oe=9,L(O((h)Y]]8\;*@Jqi[a$I<tA׃)v\g/;k:Ϲ;h„@(o', O GZž=k!1ڄ[ȑu`#o}n;$r%/%??烽O,KY__\xc MSGidWH罡LYdyN γ( n^υ WBTlll¢,suKY\8bFQU@1Y5[yǫCzvwvFMIm{\b4u/,9EQcPbM07~b`Q\|#O>&Xh(q_lAu7檬>ϸa}mMCe$yF,ȲeY"kkxilCeNO? qgOsM7쥯TϞgsj#-*!e`4u,eg1ΝJ,gϜc:907f1_u. ѐ/$k]#\ݽ%L KYG`dA01* c$4Mf+4л ^`mC/Ղ,pbmp:f >7* \5|Ѡ.RcD]%n_t"y4=PM!W__!BSkkXcaq7\뢷e-k mݾa/N?5*yNdYWA`s9LHF˾2BGO<&S666y3<}oш˗д ٌkkdyhmJ:her- {eA 9{,u]12vwan 1)( .\EbF : eZZQ~}%Evwa q vצnmH+*õ^[]N޻؝sx><*$ڄF'}@N'@@Zs{}xK%I;N\|!#&*xtc  T L~*So}+yקu$.~YZw) ulOԓooo46vc=Ks+CVG+ &1\x<&IP%Mr囦kww8~+TMEYoǞ`Q,R ;u%$m$gww[oڶe0peHf̦h% )( ꦡmkVFY yꩧ|.YwI1:w}|]}Mm`xӅ=Ƿ IDATK\ا(R mMxg:AH@Ľ}[kwkMe1k[N} Pplos/$$zP]x҇7]XNITh)ø^h-mUqW=;hI"wK_ֲR/"u1}Fa Rv)I҄,I&C4%3`SUnu ˑJ1945W<? EkŽǣ>JUUxuk[fMxYVS`@e)/^<(" N:"i ?TɲY3ҥgJ2Lz/,Kڠ r(;k~ݍY.WJ樳]\m~w͝EA2<޵K3 Ƈ?Fyl@*8ȳa >mǦL;T!HԎ#]mw O:?k*%&IA],X[;C?|c.\fowcYZ_rM8K1_O?䧞W"dK>: 8%YJdh/0Fyߩ T8q-E* Zop1~Q;N~>/\b1ewoZu>}䀺m#n;߲$c;nΓf) ш(m,O OI+_fuu̥KςuŔQG?]|*;7`|:88@)EZz/3SO>+߸bu-Z:ml'J %'4K1ڄ=1m0$g=Y0 r ֵ8$EQ\.iۖo|>KO#a2p+ndccSh 2ma2kAFU8<8@)MQ,M Te^ׂͮRQ@eJCs$Hs{2t:k~a9=XTF';s625o u d BjDL # 2G$&QWZHŜ뮿ȫn/}KKӚևE1wwyΟɟ4{{{>}Oo}{w/kYk[;۰yOWc_ WrCKObҡ3MLd F'dY_c{,c8 c,`@b9ˍ7:UUY\96@/RU<eQP,f<{'N0qx&ئe8Q³X,pxAÄЊvnI %O>DYY]#Ͻi)M(x)|H>hʚSNWބR`ptwPIkхD#tq$fXM7/_om[n.s?sh,5}uBۄ6$e|QƕC Lt$~!p'U]SUдU/tk=u Gϫ۽{y}BNR]r,ZtD/m028nJY*O?wq:.Yֲ_F}`YnWqcc|F]ѥ, eB (rԻT1B/Uv$ ƒ2 I cڸc^f1̇q\ܠR$X,tR`[ _?炑d.gΜb2:t>aJQTTT c SOrm!eX)X'NڶeBm^?1ZDd2o/1Ej~g>WIECAݔLIpxp1}^?3?xv2&/5ԵCIC1FxHYAZ~k[tL˲,X {QǑ{:iߙS}t6ý־)__9'¾p шy+++t5/k5˱a- u[Ǒs^Ǥ&ƇS-d=Z w)qd#YzBsEsg9"?88y$ZW8}Qn}mMXWr 70L&,O%UCUU9؟p)IR'_#`TIKU֘D /Zldx^q,mmu >ޓ!'N(h4:(K[k-ן` D %=\RzZkR}M$uZ8N^ B#:l>V I[`“ h%OR,o|}o=K^G.kYZK دp>6!#c(dfCf C75S.֨|w]b'//%Õ!(&w8w>X,%h[HMd`Rc_w~?>boӧNPEYSy1q6g'dYFU6DSOw<%n&ʲd1/Hg-I!@"gϲ߃v Cn\$޷2='χ G~o7;w;h;8ěi!t:*a/$+\kqAA>;Ҟ$Q!  t(Dp#DŀwѵH )}d+BЍC&L&غZT[y衇;/|YZ˺gv67(X1F ׻G/@Q(Li$z&:lc Y9%״=m2 YK( 5n3f$P lZPU .]{=-o?a>'Ne US3͸xUn;njczys8^<4.?'x!EQ}~HSJZbmXۃl!n\8Mx//|h!L& ~ahe-k /z1}5mS+W.{"H)k5JD0et?Z6J$nljFq~w PJ&ّ1Yu]Ǵ##=eYҺ냾hVIaDN@Y(iZ4_}nNy|_@bxuQ{suy'RPe)KV._̝"31N:h]! V\x:ԊLGSVTU-~䇹o `oVph9y$?OK_ֲ=Xg߶-{۟ܺvwv}2*7xR^J96!JkP1T螔9 8G, m݆ĐiS'fK$1!,IB0-g<WGDUUf $a<CQU%.\KP||` xխMvwwY]YaQ klosYGzh<t"1qG BR <<3|Xבy.ґhI,(l>{ЉF.eO9ȯG?{} N҂(Y~dB 4@I ]\gFtؽO=(q3%w`] jDȼW'VuMӔvm}s˭Z헵%=._;;L&:tnZ]GH$07̵ |D+blj`'Ơe{ʲ=|V%u]rYVs`\cEQq*?`R Z+6}S韒lUaE]1>+GAwGhk"?2T0Q'NM/1)~$"+?L<}le6q|y'엵%7w{[[]2qj}$aPNC1&I82tTJcFHޅt:ꎜmhWMCb'-EJ(ʪs3eâ,,?vГɄo< |+4MEon97 tK&}eTUɓ'ڢ+VWWB2Zspp@M!:#9g1BaP8^u|>BE0GC>[?y̹_:CDG Jѭǹߙ?o}G~GeZk>8<℗} 2toPzfCO0uݚD}}`~ajly{w< <T\!hYZ_5N;Q5ֶyV\#Q*]=VICl)a*$޾劣;6|Vm_Xжbml<|p ES ƨ s|K+n LijKuYU<7x卯Q`[OkEJpkakkn1ٜIdY/,O 3\$φH 5|074E:.~'C|h&1yx^xoh% !^@B !Z0x:FIwXvnz*;BLēR/1q-PҼ-o_8uF&Zֲ%,l]L&̦Z92921!] &n7 ŋnzRb}6An~?N gJ7 mAuGVU UOdV\+'J4 YR!>Krʺ`wwz;_}kRMWMmlnoEBU7Hŕo\U7݄k|0Z1: :!sÔjYo<C3gΐ*Mٔ {>wFl >8]c_EgVV86,JZ<'0"%)cS{V fcν,˂Oѽwx"ߐAW%Z|-{^݁M AY8=|ṃOEyGB ut5m41u1ɳ#'BkZkjyuI0_Woy$o;[_ڼd_|&CȸG}]!a,P(VHRKcl4 eYӶ,:mP%eYHӦa>~**ae0Ux y _s_5Wt3/S5:1\wu|Y=.$AXe!qngR7Y2ZEJp8 ݨ%Ksڦ!ϲaF:O;}`Q=`leG-]Uq|8Bj*h >ARy O粜b<>Ox) HΠ2LX[[aXg,kYKnȷc'l}ro{STeIUwmZxc[Lb.I@~^ "%1xۘ.bTsM ,+fsw1YwS/E?a4kL$ilV]`9 $1u2UǞx[bΛf\},?;bLBٓ!&%.^w[(-QziiI !9Ѩ`F\R0g_O?ſ1\ Iz}[[lA~zauމ6;y7!guuA5c x;x{#k~7e-Ae_ǃ?,`W5uQb LNWl7km0waml1 C/}XֲsI+H`jC]Hq7'!C`IhRlrP*t:1ǘ2W)GJRlukRg3e xz1"tb_UU!]iȴ'W٠'c8S7)UE)P0 86fue%X%䬯 7{^~=\g)[ֲ2% ;[~:9`?TsdYk;ph^*_~ 1 l@IMň+E&I7[tHkڪU{:Jpù<$Ɛ' J`u{G8aAqoM]3iGJȲ!ɜllzȫn}%> vvwˊϓvZ9PL`#р~:GZ2c4 ! z_zZG ;9x㛿Wo_eD+ؓf l+Ѳ{2XfiJ第bӬTӧi'B#MI%g r\)r*/ZP7%iŶ-"훦JptmC[7nQ׸28Akq>7< ʚ$I@H2p "Hw\c ƨ^)|eW{yǙNL曏i!`&7 "q FoL%ԤL&Fg|> 7//${"+ă><HF9}7#ғ-4ɎN… Jvx׻ ]wWXֲpWn^UU}5}Q%UJ%b RȾzݻ%Į' L_6&%I4.wQMݒehe1_ئgw}7qI6h5i4 F4mEy49?HaL -:p" c)Y Ah }8Hs^1N;|wuWʿ_g?_+y9+++3TÓ6!ܹs>}c {x׻nt` Z_ޗї</nmldvHU=MH#x-Jt 0F"$v,@Zg`U }ÝM(NG? Is{bj稪2VEEG6v2:)QYj3 FC$kd춓$5-ѓ }Bjx'l6C"8 .]{!VzZ'&HMHmZR5uaBPw ʶ@bH9JʞilxGl `miba<$ =W^׳>c#֡A)| @uhMRUUIQTUmǕR!,KN &Xe- y`wgݭ/Ng΃Ciy 0q$&^Pt<Q#uuEX\웺daCޔ%U$hx録m\8mxO3X8cR&ZQRh%J#D!~_?Z 0@U,s&E MYR`^Kbi6X*YJaK4 f4|> mKv 4uJQL,/rɪl~Ͼ!꺥q|`Wpd($ UU1X0 W8w NiC>8FQt  V]u_,sN]xg{u|1c4s_Z%Ժ|H-?|ޛHzIBG]<20$&HA4#|ݾRD'<,-MR5mRU%ֺmco*[!m[ޣ¶$d*auL (~eGCq̦<M]4m>D.sN9~7|kw~?/>g| Cp-{@}vRPx-֡UB'c9YoY'"O2dSMdט$/mgY֧1IPGspU"x ƻFe-kY%^%;ۛ]~gZkflll6tg.#nZ6~bt3IbPJ#bVALzͽ8*FxwEmK4ب׺o~'?pN**˲È_ E{]Zi`w!y$:p mUun;rQ2MpkUO{gkyp{Xwuk5:4%G tdk B4--X ؀R/"!tıx]ruk;sX9.WuJ'Y5u=zs4|{HP%@#TI\)[';F󗗗)˒,Ou 8tcBX1[Iw0ư wapivhg>ttUH$Ek*1׮]槟ʙ[8kC 2y'!8Jmmh{d()15]؛OLs=LBZd%c(j )1S^xtc(ƣ, iθ` $C2Z`ЧHvP&#l)ék[g=j覦*._bҮ4UH}'.W~1DvzJ眣z\.\'>g 6 yi,)s}n}4G6Ȅpy.\?DEq8O~훟{ϱdJH] bY6T$inm|)hP'2 KRMx"g9vww3%CmYNr@RWehC;;C OwI3m6qjbzY@\ҋD" O~6C/?{Ν;ܽ{^Ogg!K+,B"XY[g?ۡ(a^*$*Xf)y 23fzh릂|(ʲkŨ躢1g,Ѹ,8kP* 3|PNF'˙mmsA H;ITdyNjWzRx)8uvgdH$VFʛ~o{ѵk$I*E]Q X[]gqaCm~~۷px$#ϲil|a~8{]UZ)c`? s$ sMMn[,1RW!Cx7nC?C{`f!Bilj"v >gp3c9w2'O./--Lˊ7zc~o@)1u]$IµB!p!ڬqE177 >>D"(OOf_裏Z󬭮̠DD"\vV*VWp"Z^o_dnq,s m(N0xYCtYk[U9tL=ۋ,>~^G9*CxNuQõf܄Ѧ YB IDATuF ? w{'@K:R m͋B:P&Z^ҥ翿q_E~ MEr9!?um)@>桦l;H$yEqBu+)\r|2lr<%OsJ9mCnn*CK}o,fH(%шq9.+TME4(?S >C^0bWw7;K#(:E]uN8Tߡr|!~D"s_5uO>wﱻ,|Y[[oc&¹oBm4Mpo ˇ(#vvjCFQWUU=Mpp?n*i2 F9.Nbz$ .8Gf4&O;4MLCh ;Xuh03eN=%t$D"OI$FB'{sgɳ\*.\64 "4Mh%[KڒcRTezp&챳CUiv 5,,eF9Tb#I4ܒOɓ䳗ynϭx> m;ڪubē9g^9ω}H$_8oa$D"O]y@Y!?CGHefګ_S7=VEQPW%`4SիWژ Mj+QYN2E;HURC4H!ƚ6w^e\5a9 496V9{D ǽQ#H$ԋe&߹~EQ,..RW bg{YtU5|zc^9h4, `<S%MP65M*}yNnbT iLn>$ReNL/L@$X:}QA݄x8,Z٭ﯭD"gR'"V+^ocj:"Q|zzk B~[9}fFTup\0Bۦuw~. Tウ~൯5e=Fp4a07K |*ITTYw+p5onkeing8r7ftbD"gVq# GVCkކ3vnS?3 ܹsֲ;QHFe<E믿*(n*IOYf|# qrb#H ΁Mm'z5n=)&K\< ӶUH$Evww .WRb=_\<Σ1 BW$Iv :]d2楔Hpb0À@ 1!MS^8S_U: ~$DyԩSͿ-_5 B9y[>`yqw9S3;߾Ny`0 T`Y$HkM$}(p!9GkPSg=xOӄ('69ufgH$i`066A!ZS5"Q\vR5j&F;i*^Xpo-Bʩ М;wow2*q!{$DNz9"ta.9yx7w!fggY_=p /by>}?ibn%aAoA"H f;B$x]cQB,8y'7E?'D"H'~HIt{+fgg9z(xr&Gk/~pkޓ9[:yC^3AJ!x5H"xXU\Odu~ϱoH)T*~E"H$R)kkmt❷Yy8kqHa8m&OR*$> @ N*2/pc&)Zd" 1dyc9z D"H$qޝCȦ$hg9sdR5nfBBO#$H$Y(GXsrі4I8|Gy(H$V37l ݻu%mOO tnNUU/QJN?i=;$IBk3rĦe xC+*_ܺu,뚻wpVW)%Ög5It<,k|N~H$D5c's01x*˩cp8d0PURl1BB#MS֎/z{}|D"3ڍڡZIENDB`sardana-1.2.0/doc/sketches/sketches.odp0000644000234100017500000556212512174204306021442 0ustar cpascualcpascual00000000000000PKL@3&//mimetypeapplication/vnd.oasis.opendocument.presentationPKL@Configurations2/statusbar/PKL@'Configurations2/accelerator/current.xmlPKPKL@Configurations2/floater/PKL@Configurations2/popupmenu/PKL@Configurations2/progressbar/PKL@Configurations2/toolpanel/PKL@Configurations2/menubar/PKL@Configurations2/toolbar/PKL@Configurations2/images/Bitmaps/PKL@<-Pictures/1000020100000184000000FBD728AE96.pngPNG  IHDRjssRGBbKGD pHYs  tIME :jltEXtCommentCreated with GIMPW IDATxe    439H)(1)(G (3    ,+ RRT    (%&265  3$,4 IDAT    =     ;;;45:(((:::---     #!$ &&)  = %VXWIKL  ccc @ IDATf(($"zv         θ={  -%0 WWWWSO   pq  ()3Ͼ8= HG   (  666  :::  )R) ]R    5AL   G#   58?HID ppp   HHH \220%"({)=3          ,6 "$ (  "½FHGegh ~~~    (++,.1  /3     .)-/-/ ¿-6  %OPZdfi /q' IDAT##%TTV $$$      ''     ((      0*     =5q{9IL&$     X]fdfg 89+#$f/0+  344=>=3  "       !*(        !"&     - $  2'    `[XVWOƶ>7;()'   qs]@<6/    evjvzv}}}    !#,  -,. "   "         ,$PKM./3    ,!/#     SLV $ ++%,"dXM      rsx lll 3      -(*#!#   ()%     982    QSZ1/'   B &4/3     =2#(/    444888  "" 4&'   /*,*&%H:BDCG ,+3   #  <=;  +'!3-511; 22  &6$,        @u "  *%2".[]_ www=== e΀###%%'  IDAT  # $ "889501!!$(("       41-  1)    +,4002,-%#%(($&%#hhi444 ؀ڀ -..~QPQ  $    222;:;  %   //3"   (*( #       "  A<<  "(>  ,+/=;; /7F 083       789@BC6663***656((( \ !]+%%    ",7  !#"  PQa  $)2#9'%3!0  915/(#! %8D_%8@Q5>       IDAT      !! !     ')*    '"»+**!" ***&/16:< VPRQQQ   !" !  !!?;9-00HJMHJM  25:9;B53, $#&  ??A999 ))(nkn(l#%$TUV!$)))STS   '#"/.+ JJJ "" bcd BCCFGIGHJ)*-IIO?>J$#/         (%$)(&  +.%AD>>=9!  767HHH 376-*)     ##$&)'     ===&&&##"$$$ +++ '''   ))+.-*BA@:44$#! 74.   $#+-0   , 4>Q423 IU?$ &!SRV,,,.00  ),1Ŀ   %  'y IDAT$(*$(!  >.+ 0 UUU}}}777[Y\ LLL >>>()) ߀  3:>DAA  897$&())*317KLNNOR GHI**,..088:!!##%!+-)88999? %#!         ĿĿ 201-+0 $ !#" ONO  '%$     75<  YYY>>>JGJ,-+DEDdcc>655)*0    "#"%*#     AB?ZU[ecj uqx*%3,'9OUZMMU8:>(((?:;++,       2/&,-08:<IJ@"(!"796%  ! -$% Ⱦ     "##     )(&  !   trs lBBC  [X[  ===MMMb  GGD  ?@@  **+hid  ! !58@)$1#"( )+104:  &      $(,  1##   -,A@NHFP  STTcdb  ::;    &(*!   ! ;::BBC&&&@@@/00555466 "$'<<; 112 $$$)'(<:@ ADF*GIT               #  ')#Y[\"") 566=@<  0/1 &#$^^_       !##=:;+)) ???@ IDAT""#==="""=;<699)** "   579  =>>)*) 000+**  #"-    &$"!      *( ,-"$ .2) RRW'(''*,ABDa`]*+*466?BA)*&+)9! 10* ($  (%!    "OLM665}}};<;./-?@?JKIEFDEEE999444=ۙހЀ !.,+ &+/;8;H $#% $     #         0/2 ;=9ROJ  "!(;;8157 31.''(  !$FDC "        ,  KLK  321000  )( ,-4>=A !"# #"#"  +4/  )*4 #0/)          +%'  !$2MKZ"$3.)=;<#$363$'+.-0 99888 "# 745./-DBE # # %#   ',-  7 <:7@?F  XXX zzz#" AAA~~~ŀ "#,   #$)  J%   #=6> :34     D@F      !$NNM )'),BICU"6/!C@= ,), !<<7      %,'fd\ #1#    '#$D>A EEFe"!̀O IDAT    $@AGDKM733# MJF %"%658==B%%(!',(3 ?<<WXS996>@<    #"&     &$!   *$045; Ľ))/   #)-"!,($0**725D./9 #$ 5543;;<:A&$+   #%%!#"  #$'"#&ACF"$)-+)ONP        %!"--- $%* #"#123  MJJK  ++*   YRk)55>!    131$&#RSL        &%      ('   IIJCCA&($UX_ .-4/21  "%&+,.4 HHJ')'   %&% ! *+ .//FFG  ݀ $&% 55:  "2    ,+*   *)+    " $   "# .+&  &$#      !FGG !)&   '*-57:#%*"!#'  IIH   $% &$* * "  <=;::;  333!!-26SQW  $   .+- %%#! !`__#$)+- <9>  864ķ"! (#(' ƿ"CB9TTUĸ½'&$   -/,')- ,-$)*OPI   &&) CCB   '%+ !--/  865GGG +**'%'  '!  %&(**-%$&#"# 896ÿ #%+,,3  '%' 989 Ƚ!"  344+/=!%(GFH))(  <==    433))-      MJJ776  " %#"!$#$$    ĵ    !G<28:5DFF '(#Ŀ   #!'(*-" .19$'  456gif  %%"/>˦ IDAT;AK  $DF? #!"('')(#     464   !334!  )  HLM##$!! QONjjg  !       " #**4( ,()()+ !" **$  ??F -2;-,2&#, $%'. !!# 21? ,7/885¼ 0.. #   4$) 130 %$.@>H 984    ;:9VSU  ,,**)*##%&&'&&( ,*0/+:  #.  /45111 998    ,/-  #)   0--  3//*&*!###$    /81 &_^h,/1   *    )&1=>6 ǿ!&*# AHf)3Q    /)    ""  #$#) #GO_3?F*56%6//ROU !% KJH  *-1;;L  AA&)$A;3/*#3.. 34,&+PJH  443.03<=>̃@AA  =88 ¾,-"%$#777 112HHE995    ')+@@A##+   "#$   *,2 !>=B><  43+ #" !-.+IJJ++, &*+'#&;39**.WXV ! #)(+549#")108[[_ONQ$/,.(#  -%  (+6 ! =<:,+)434bbb   :8:((#'&*"#'"$(')/ HHE --0;5=   %#&*'*"! <<< ::7"  &&'%0OQT "!!&$#"&,),"""<=;        :::4.   +>G<  !""#"  .-, 554 <<<   ./+ !!$   ###"%#"%' 43.*++  :<5""  #'"* R IDAT  ;88MMN ((*ҹW !,"$  221 )  " $"!+*(*+(   /-.&%%736??@FDG'%(  ged       "&  ",    .,)%$&656oob.-+ -/1\ZZ   $%%')&=76   IIW$776%(*'01.  LLM ,'' "!B>?"! ,+0:9@#6:A//*9:6/-,!!  $#$-267440//  "   5:'  ))'&%!   &&'<<=\]]    @AB%&&   ## (,+./.  8:9"º CEE !" GEF>>?$./,+ '%"  843;93D@:$$ +&% 200 ;;<##!$%%((( hhj0+-;:A   " &   ++, #'?>< ./1===,,-  EEE &&% ?@A8574/4 112  +'% !   $)&  =;=! ,('878 ')-##("$(126            ɹ EEH&(+ !$852#" JKP   "91)?><  $$"  TR^#+(0 .+0  2-1%)(998--+ (  ')+  +'.,.## :66 ZYW     ĺ    RVR%'/$        '" ZT70,  /2K  &' ! IBLEFHS[ZGOP +(#˭!',!*##("%%&  PSS       JE= !$) 0,;     ?>81., 896P IDAT    603      CAA     UUR    ##  -.)+"       *,' A?@ 200 =:9  !"!"RPO   2./LKM !    289  21.&&' Z\`'&)C6?,&'OKJC@<  #' ?>> ecd  *.-  '%'GEC..+ 525KIK674MMK%%%        &:"(<    %       .*2 JJC+/',+/HGF!VR[(.6IGF2,-  %%%,,0 ''& %#$ ')(022522776   ""!##$#  !  "#"MJK 025@=A EDD  ..*   '*)))/>?I%55>%$*115021   #½,+,#! /40 '&&)&%$$"      /5DLKI   /01 .//@>B  566,+) $#%778LLN]]_bac,-,##$̀_^^  ! " 05.%%%#!! GFF# $ $#" """560DAB    1.$ !>=2  #  '-/  ! 007TUT CDD:<:  "0 557PSQ 377   RTU025'&*1/1   9770./ 666GHHNOOrrujjkttullmOOP))* 696   #!!'"%'++ /, <==568#!"*76=)+/ ""   "!#  427   !   #"  !,.(*...4#$+),4  !   DFH!$ ,/3$%$  $'0/2<" '.)  7:?24:  ?@; ;;><:601/'%(**+333999ILNSTVijlrsucdfCDF%&(/62!($eAAAXXX TRL !$#'!."%85.,,,134?<=   0,+M IDAT),,  !'# %$)fhf  !*    -UYg    "!   )&! fjw)<>B.0- #,$(*&%   %5  #%,$'0 '&,:=<      ][x!#$ $TUlDCIMOL RRREIK(((###   & ))) !!"b '''26( ɼƿ'   !&&BFAXYW $$%$"%' DEETSZ#!*   )"  )(- .-,"%797#*@4= #(5DA*--017""$-"%1 "#'  '*+A21G;@M +1   9$"+). !/05 "'2     iik 544  #  +(" &'!    $!  <:@ "*,&+0-1;8?    ..0      M     TRO&&#   /-+    573""774         *,-!%)#     13+    +&AB: ?@?  ! ("     ..,΀cbc  " !"'%%(00&&   ,))  335feh $"$LLG   +-2" (&#KIG !   ĺ      ))'  ?C80  9:8 &&(+%-(   ""% 7BG   ¿ ƾǼø            "" HKKK<=A    111D %%$ %'$   '"$--/DE@ $%(?DH414!306 #(  FCCC=AWTG ! -13112'1**,  '(0"%" #":;? ")+(           5 )  IDATCCC,,, /.*  """(+&IKA68=((&   747% '(#   !"&*%*   RI[ &%  LLP=;6      (,0;.357@G   CK%    "&8;H 557   "#444    ($1 $    *  7*. 뀿   01.GGD !! $(%    &&++,1$"("%)%(&+     !"" '!    &0 /467:=$!'      .-.+-0 ZTY*,- "865       ))*Ԁ`_Z$" $" 886$ !!  "$  ",59")*' &$*,,0 #&%-,2<<6 %     ,%    !!,(*2      '       &$/&$&42?FG?<@.#&*)*# WMH     !  )-+ .)&" ! $)     #A@FC?D FEH&#'   !")($'&)445 # !.-5 :=:\XQ!"       "!     ƿ355 ſ#$$$  " %    ""$   QQQ221AAA   ,-+ccc(%(     & 732&&/0.BBB   N,1  _YW "  - !  bmi&%'  -69 '    $( "!%   --)*" e___//5"021?=:    *'&66) #%$M1G58A IDAT450 JJQ0/>""$) !     3=:%%'      $%5#TQ^--/  =9@  (׀C@>  (()BAA-1&%$!      36: .-4 """//* ,/5#    !/4C%,;                 ## !   $)!) ,)*       !.+#  $$#  %)+1!' $)+-3 %*  022 #,       )2<  69F.2< )     "! #"#!!           555556      W$  ===UUU&)-    $$"" $KJI"&    )/8      +5*  3AG# '*, .6#  (-5           " + "$"    ! $ >=A   \903\'eeep NMI&'1      ,(4    551  --+    )15         #%, (12                 ! % ǥ =:6  GGK      "!$ 11(><5RQJ44) -,  LGK%&*%%) #!     8?C#&+%41'84 &'%*1' $             9<0!"  ()'     ž40*     8]z IDAT       (184=A!!&'(       *#  \\U.-/@>B$*5  AA=" 774 $.*        $           *)*    ""!  "$!      331HHH ")  $34/  %!/0-&1TTT¼     $2     "!   *8& abe#    &'/        $ '+,#'$&%*''*   32601.#$&!$+-.      .%  >=>...>>=  # .1* 13/ (,.+0.       )'&  HB<         +&"" ,& ư$$!  !  %"-466)-/     #%!?@<CCA &)' %%*$%&.,-6%&/*)1  dz-,5"  %%    )2   1##     1.) &&'        !! 988+04+-0      Ѐ23.     ((&9:8    #+-0  452//.98>(  .,*    $!  # 44;       "$$        BA?../      즘 IDAT  "!GGG  "((!)&$ )    !#$+$(&(&//0# #* -*-     ¿  379 ''-    %&) ,/( &(&        &')/26 ##""   ("%%&Ѐ!  ! %" ̿(/0    DCMA=D    ! %  0*.#"&    ¼(()     $++%%%$&$       352      %#$ ",00'((    |     Ǿ2052+1   $!%!",( .+&%)  +/*   !  .!./,4       & 0/2           !# "     l  #...@E@()'       !"        $$$!$%    --+   366&%(    -,,FED  //1 "   $$"    '')   "! (.+,02          )-0#$%     A_ IDAT  9:@      ,)* "!002   !    **.!!    $).2138'+,   33-   #?@>./1   ()'      .&%   '!   ))+     !$   ހ;6'EFG 68/JJE  !   !  !&    (**   111        9  ?;631/01-+      #'&!   "$&  543  "               123"&)   $\\[""  &&'*   ##!"#!  $! !      (%&      ..2     #$%e**(΀  "!$!GGJ   !     +&      #'$!$   ڐU IDAT )(-#"        %&'!    82, (!  342//2  !OPQ 3,+          @>:)&'         '&' !         !ր/.-446RTR@?@       "   $"  "%    &    .,.        ! ! #$+,. &%&  !%#  '&!$$(        ܀BBBjgh&+1   %! +0=9(%'    &"- % .31!+)         779 7<=  147@@D139.-7       *(( ;A<")) %&' Y IDAT  UTP/.* &$FGCAA<     4.5             #*-       9  "  " %(((LJL+& #  %'%()("         <7A#&6$$#   302...    $&  *#   tzu   031.,.1/6#!' #         -0,- #2" $ & '!!           &  ;;;SQL     %&' 40/_ZZ%&&    #1$!     !%'"      786'((    ""#;;: ,(( IFE!$!/*1&( '      "  $&%  "((7>>  $$$   "! +,+! !  //-! ##""?:=%(&    !V$ IDAT "``c ! &'$CAB=>= +'+330 ,*+=6B!/        &') $('7;:&,,  !!!   #"& ())  %$"774! )(&@A;  #") !($(.(&0&%-CUU(%0            " "()-     #(&! JJJTSO   4"!  " ".  MHP690;C    ,' A<@<:;>?:    +)* #"(58216===6   UUS (((  !  SOP  $ $"%*)/BCB    ##   #    ##    ! ")! ,# '*)"!   ü    #*'IJK++1  %!# ''MMM{|.->   ((* "#"$  Ƶ-/-bbe          ?IM=>@! A?J' 25<9>; 1 557 #(22         +$$  ]^Yb]XJIP + "+* QQE32+$% IDAT(% ::<%&/⮲ "!'""           =>(26@27R4$-X  PPPhil   $#&  # 0-,272      666%+9   >AH309 ***1.1@@@ $$%%%% ///#"%'*&$'       % '#$///MMM   ""$453NNL'(*    3..>@B*(+        1?::   >=C==?     & !   B>?''' .+,777  !"* !(((       !("$%!HRRR 0..   " 9;5@@5 '%% **- "#       "  /.2335326     000 /21  %%%%%%   &$$        )&"#!)"'e221HHHkii   +,. }~{"+114,+)'*!***            -)&  220, IDAT   ##;>= $$-       )'*=:;  !# 21-   /),( #*#g   ''))-/"     "" ,,+       ...GGHMLL=<=*)*  $%$!#"       "   $/'#WBGI=@)A3:m$ 22.LLL%45.    B 11/ '&. &$'666 %       3)%!&$98; 54://0  &  KMN$    $)$ 362 ()))žCB7  3,(-%%'## &'$ـ!&&'!     " ,''¶55/    )    # (+),   #!!  *       ȸBEF[\`67@#-06!($ &16153 +/     '$*, )#%%R=;SBEYKJA26'!   /2/ <>APRU89>  $$"      *-0DGI157 443    # =B@"!%$ '*( 722 "#MEG& & h[[H?@߀87.{| !!" ::<%%(  ,,)""&') ¹  $&'!%# ()%         "%% ##!&& # /11%(**N=>'"P IDAT  &#/<.(      13A %$# ==<      ! """# "     *,1'(, "#& '*,  999454-,,!%!" %#& " :67)&)  $$ 8*3& 5(! W8850/+   --+ ! *  !"'&     &''!&  689    ./.#%($/03UVY "$ '"# !´(*.!   C=>#  +$(!  QPK ¾   "$$;;>  !'&==>/.2$#*        $)(()' ),.+-/   ,/3 ).ɼ():+./OPR45=     ,&       FQK  --.     /-4@?C?>B104   %#$%#&    !(/-   :/QG/-'"  "&*   C Հ   !!"564$%%" ! 841UTS432/-,  0/+  769ddo !-)&*  BBB  +)%$%%   $&&457;<<CAH///$$#$$!!7-      C:/ @8- $ ! !& :46      sssZ[NMMK!! $"#   VVVEHG RRZ   ('+IJL'& -5, =<<++)ȿ`bbyvrtvr#106"  %<<>/.4 *+/;>C # ,"+    0%       %"  "  & . 7&LJM  "+*- HHH@@E *   261   !% C: IDAT  $/16!",;8A LTUEC@!!! ! %HB  AA= !%) $$"     5-     '($ @1 H7%TVE     ,.- #ZUC;78!%$  ../sss LF9          IKGQTQ<;G23?    ""*  #$/* ?AD 98<"   GED    )'(Ľ>97       .2,  86275.#+--+;?  12I$9'$ $##(')&&*??;777!!wup! %*+&8  !" GMI1  /20 "*JMQ"%    +.4 """$  !"    Yfy! +-,$ C=#%#-+$ "%  $4%1&84@247-*.$!# -/4 FDE]XYJI>    ! )  1-+  278"!%/14;???@A,.*Ⱦ!#(+#%    "!)! #        5 07 GP@,*($%*%! "  &*$   8,<C=EGBI0,2tsyUVO0-.(  LLL]ZS!FEK PNK '&-  !$! Ⱦ !# 209"!)!!$  .)#0/5   :7A01:(,&9! &  *!#$ &('8  !)     ellk AA *#(666=9:!   //-  (&$  $' ǿ   $%#504   $   *& WX IDAT!+ KIU ! A3* TE3FB7)'/2),1; !333 (("<'((!  ȶ "##"$+ QQP 521  --.CRK  ''(  (&%  *)%<:5 ())#%'!!""$'   /830% þŸ."           .$KB7 -&+* " ,-5!%(  $(   '%''%'527    ,,(yxv%$&   !!$   &((   ! " jkl $$" ''' "#"!!""!$"$&    %! "!!$  ')!)11      #  L?67.%%"$)%   '.< 0$(45!"%"$)9=<!87;GEH:8<" $  767*+'   213ffh;29 +,-#!  @CF),+|{{()(   *+,   #&78:#   155 *(.!%%'45:  ! 80 D>1!#(&   &%0-8J &04 "%/4'    0/0EBENKN$#&9$YZP#$$   "$" ().593     JIH  '+0?BI..2226!)**  ! !   "  58= #    " 1"%HC5;9/%!%% !%+."&/*"/0 # )0889QNPKIL.*. QPI" ' &",   !(%   ))(   BBB 8;>AFH!(&(#66>)',-1*%%$335&%&   κ'"#F@B99=?9:*"8. HD< ''$'/0 "$  -66 #", (124 $&! ACCGGGXTY(%&tý IDAT--,ـ 34A           ',*ʹ232$"#"     rw|}srEDC 34?54D$($9AA &26    ;=8@CH 7/914-%*    /  5%\K$0( B7330"%'9.$%1 # ""'#'(%##*54 ( !'LTU  1/6KHL[O]D;E*#,VUNvvv  "     '!%   !    **.    .)><1LK9[ZW! + )(-! "!!#$"$   B=A%"(#    "%B9@4"A:* 2A1 )1$ 2ܾ"&: 0#%(,9;  '-0 >A@ 547LLLPPQ767݀   626_Y\B=B   &'(    %%C@6HH=aTG@<12,(" /02'#1+-%&'   !"$ '    (% '!6&-@9 *-  )$ "!"$%&04#-0,03*-1315JIKRQS314  hha  //2 ,+*9:;$&$   564     20.  +%F>3[SE\UOE>6&      %&(       !$#  %(#ND/$RDC/4 #1"%- " '2I !#(8 +38(*.7:< 244JIMY[\:36݀  llm DCJHIP  +))9@<    D9)F:6`SOTHC&  ##(&%)105%#-    (1%"$   /I>0 >5-'%"(76! &+3 +$0("&8+)25¿!$'%'(,-0IHJZ\\3/5T` IDAT  QR\7:=  '$% )2*   !   #$'HER FC=WG<  $.06..9%  $%  % 6-% A;2 2*2 !,8( # "0- #') 235LKJMMO222ZVKOPQDBC)*,    %$      )31; *!*)4JJR/13 +(.+%    (9355#&' !%           H<6  MGB'.8.3*.5#&2 #'$%Bֻ"(,/""#KLMUUVIGI+,,   '''a !   ')(     ))' !:9:XYXgfgTST   .-63.71+5  566'"   )      "%  $&^\W-.(*:H ')#%*.!%&57$+5&3$&%(>A/-0"704HGGPQRRFDEX!!# vux==2(  =@AWVV]`] )+(BCc   3%$#":9<++.  ¾<3P ! GG?-+)***'*  6%E>,   .3- , !nh\ AKQǾ19< !*1<=?-->')Cи,/.3:;/26:<=<:9ADC"""002(((gaFF?   *+7 <;;^^^oondc`EEE&&%    .+-      ', ! ." ƶ?, ZU?2=" -6!/9!# !+6#*> 7 '++')(455102KJNRRSRCAFX !          !!* % &$%QQQ^\[UUP..,    -*5&%%1019ZW IDAT  !&'*+ ȿ"J;/@8'&./""0$ %.2)7  "-1(+46:+0/&('$#$ RPRHGKDCF" # ##%π;=3445 #('0:72JFC('($$$    )(+65/  #(7    I?8XLB 7?5 '''+ )/*13&/1 &''317@"%' 0/1==>TUWHEHSSO  JFA      (.:$*4  # '[SH"GA?! ++$ #)/$!&"'!%27B0:>38<%!7ѽ "+.# 012(%+@ABTUVHHJ;:<(&*  ؀  " #"$¼  #   :77""ļ &,)-7  " {vc47&   '& )01*39)04#4@ -9&& % *.(%377 TSSSRTLLM'((   HIQ  A>>ȿ  %*)&,0"  6/3D>AA:?/(/ ..%(&'47&+/'-3+-3(/7"(""'&/5#7 ##"&%-1. &&#BCBONPRQT&$' eEEN     "%"GKG   mpDDC      %&,('1#$,ϻ !&$ A   #++-956835 qlhD=5|wq +41 !%%*4446<" )EOA=AA  DCAMMM'"$jheIIFhhd>?8MOFLPBCF;LNA... '''999,,,WXT)    64/.,(jj!     .216:9   859320MBP):;=lnq"FJY01485DWUcKKXGFN 0)9000111Q IDATcca~|    ][Z97: !!!#$$%-037>&*-%&%$-+).* ,:3GECA?>abd $"/ܼғ76>AD=(.!GEE4432/2 fcv"""))' !497&*+ #(DIR()/ƿ 4,,***888Rwwu,."42>LKSǻ26-  !;;=**+ ZZZ  #&*87:.,1  " 442*&&63082.#;<<TVW //-30A  +$>3G  OQA## ///490/5) $' "!(  E J  ;$(9/0444999>_]^ ##%215,,.TTT QRO333HHHOOO   ʻ''),63   /+,967DBC<;; XXX ($%..0103666999000>>>??>)))kkksss   IDAT '%$-+)  +.3  ,,,;89<:;0// ///IGN! *),))) Q>q TTV!   .0/00+$$&  ú$" ?=>]MWq   000--/ FFF&)0   %%%??? (  50'HEC(#%===ttt""!  - 40. #$"///(')211WSH  TTT &$'  444%)% 3*$LC=   ¾75$"#  IDAT***  2'!  ,)( wwwKJK+++MLM  OMS<8ANKV"/><<  aaa434<<<}}}```  544**,%  74/ (ddd=79  !77; >6HKO 2%"KA@ e 666  ++  =80  K IDAT///ooo000TSI#$991"430...:::&&&  " ++)   ...xxxYYY>:I   loo"$$  tu[T\S   bbb!  R IDAT011PPP    QQQ "%,  QQQ  ""   ())MMM!deh )-%%KKK<7399; ' "704!$ HHHDJI IDAT 578&& .&$0$&- ! q46523  4  &Z.:222666  DDD YSU" <>;q333333proJJJR LLL  IDAT``` 3    eZ IDAT     Q=     444KKK((( { IDAT '''===QSS!#   HHH   S>5    NKN???+, $""JJJ'''  999    <<<    z:::  Ѕ IDAT:::!!!  888    3---    IKJ    *% &$/--,   555 >l IDAT555???""" 111+++  AAATy###4===   Fi] IDATEFF   DFE   0-0 \((( ./,111  --- +++sa IDAT@CB+,( #"&)(%%#666 ++)&&& +++;>9*/)+++; IDAT---'''4"""### )))%%%{ --- BwrIDAT*** ;A9  "',(]rXby&IENDB`PKL@8\o33-Pictures/100002010000008000000080AA8068AA.pngPNG  IHDR>asRGBbKGD pHYs  tIME 4d IDATx}yTsNUUo(  KĘLLnԘq2ɝ8cƉsu2QA'5Fu۩?̩s#]U|.-? ۷o>0ׯR0Uӧ*//gx={"dťK:s^{$Ȝ{)bٵko``m>}jfD"BE( me& ,d2% ?8oڵǩpQ\qB&,Y~j([A!\A˲ 0d2>(? ! (&il$F|V\MUUU|>f͢.I6,{XVpX,B :%4%<} _} (BDQ!$%AazAxb&2%8+ ?1~_BQǓO>[-Kj8NeYB *2f3L*)EQ_CBe,"N&AƇ7o%8k=z?Dl6q*~8N|>X,fjl6b@e*=TeYWP]!C/<̜9sRXX3D/18nG):;;ѡ~ 2Q ,a8Npe˖kО~,$ BiӦIo6.]z&¸SwY:t+GE*RdY&ZNBGOwHӰX,3gQUUb @CA$b_8rK 0ݍJK/4׿z;rH!DaYh%tf J-)y$I̙31c L<&M$I~0 <B O~EQjͮ]Bfs!:[2dS$Á aݺu2e ;-aEEJ$Ir~z ˖-F׿5n կ~70(D(Ҽp+>9s\bFtuuyZ? v]$h-p=h;z#3 x<غu GP/!\QQ1\ޱcn0??斖ﴷ[,l6b~$]wmF60 Q!2nF\ v}>*T0 ̂ n??ٔGtq X,'{F ŷ#d>M&%@"W\n+WĐ7^R))oݺu /^?8ܼ2aUFuQ Iy\.466;V=#DJT*uߊ+/^wW o>?jnnv,k|z=M4#?z 23fPH$0 F`Y >ڊ)SLٳV8pol6jkkQ[[1s %: ڳgԧ~?SL&²,"5abϗxz*}dZ@\|9n ŒAl )p8L^-fzf4!hѦ'NpwΘ1|n8{xq`)wG?CO>`߾}=>1]OVNrFAG>=]dwy'6lؐa4cBgV\9yL*@ <rh6 v;V"IV* Ef&,'X繍7[ؼy3sϭtcǎ8#AXzH!8 9g%*u[A-[e$a{H<Ƶ^諯5k4Aq۶meYeD"X,ib3[YB(b N˲n`w*++wX`'-[( 駟^,˰wb,F9 h4F-2:Mկ~X,'F1tP(`ƍQIӧOtuu|$IRGH8{,z{{<v{em( 7d2X,nYf~?ǎ(iSh 5~s$gl!п,U&gOID[j]`޽.em"0f34Qa` rI.*QA x ü\UU>bϞ=˩(cYPxf۷VP\\b|eJ0YL&jkka000ӧO~%%%q 7rA$̛\U sV՚G@nǛoφ  fx<B! ٳ8s JKKqcŢR)0 J̛7gFEE*H$=Y!f3JJJPQQӉP(N~_7nDqq9mFޅXZMMMX,^YaZDAK]V3 cT*T*ɯGeҚtZHӈby^UNTQUUzx<,h4h4z2۹xt~?jp7 s.;ڽ:qx p Øp(8d_~) p 9PZ0^/heVUqEГٮ%0N%%%ꪫ I~$IVHI>hhh&z2WÅ> zϵJ-d2 ́zZU{f," ȑ#ؿ?Μ9QOذ/ĽP"G?BCCChC& m ,XV^^1Lnz*Ri6.K룁zBV (X,j  jbҥXj(ZZZpQ9shH<몝{3Z#bhiiԩSQ}rO/0k9|curTDҍ4ijjj< bAPITn vf¼y .DCCL&@i{ٜjŸTp&5F#崏!OXx6."2 ĐT*/]&_1}ELÁiӦaٲeG<Pj@R<6n܈yhdif:Ʉ cl*0T-KM*їع_M^<{.Ui8N\~8Ch)i |G)FHN>bE*} &(]Z[[q_$Y/{fp/YYbQc J!}-.mO٬ Pbt"'n4 /~T*g x>x/8믿O="ڜb@k!x,p XVDQ477>jSJ{4K1FXǎD"8x8PPHRDZdwL2b@"Dww7^*PHX,D XbA4;#npXs\HRX,x<8s !(,,Duu d%zbv;hnnF,Cyy9l6Z[[AAaa!:::(& [+ՊI&a`` HYIWZuFU@___n8s 6O (bXx1^1JUQ"#G?ϖ$!H JN6MmeaQUU>jn%%%UC٣ށdKa$- F?gʘ|>L&phNy?8ED]VmďnSJhH eeep8eY =ǂPY,l65gQEi5f3o va|s @%aħD"qjΜ9' F4zHOhT/v4 nGii)Dp8H$>?hNEh4mmmp:=0J$ԑ`lT Di\hd2DfFcEHi吞Fx<|bjhKKKF4n[=<3gΠHӸaZU{!^$ak/0j(X,v?]v @˷("re &2k8W@xDbLKOT:!L?3А|>8"}ƃd ǃp8 ׫V % 7 6z'NX,t: ىQq^ݫb[$ NvE m؈h4 AP[[۴u]#2k- {/IxF'4e{ \ө^g:F"f8͛7l =QZդ<=wq!3@* +=TnG<-#L&nqU 4b=["@(R3^+Ƣ]P m ZM;]Ŭg3, ˲䦛nCm!DhQDŽrx]wd"huh3s0 DQDWW^xx^tMARz9  EEE&vfHJJ#3!bŋۿ!ɖ yLeYΒ@Vam.uVmmm8|0, jkkՁǞŻ߿VAtuuaɘ>}al hԿivH3APn7?o}ѻ !SNM82cܨ(Y µ̾}с2x^adX @XrrDc䎦GvN'Zq8ꫯ~^7cǎsB}8h +**c=׋*v_{"MiJ*(ۋ[nEk2@iA`M088R4 dΜ9/n߾o !{7t9DTdR);˲D$Q{PAw*b׾ L|,>:g`0hYfy饗n%$}YlذᜆeD{{OWp8rOF:FQ yR)$ ~ s=W''4J ܌Zag~eΝ_ $oߎ7\x$nuڿY, P]сP(c޼y8[L$+UG10˶#Bаwꫯ~zΝ!g}?/!$kǦ7T)H2AQQtb`jq7IڎTl1yz$Ijx6].?oӟ5!$SOaӦM8_kDPYYIO=YoT,=١[YrёaE"b̙j_rewՠh;wkGiU(bF|YI͛׿{3QA)8Ft1IBfϞgΝ !۷[oŅXyI,ԏy'ODkk+~֕B&^XV]V2#"RZ;8Q h7$IX,d޼y^y !m۶7o\ P]]}===8qBMS7S$|><$I裏P[[%Kt@?+;v"cM>2P<ǩS(bڵk3!$SO]?j-IaZTWW6 mmm!M& }OVs/^@ юv>c%M$={555jz} RW?瞭?/˸+/D"N Eg9;1o:n(--lFQQU[a<1_2eJFn,~ohMMM&so%Kz)qV^ PZZ 3gΎ@ ժju )uAqq1kJ-6,I&6 fZٌ_ Ðٳgz}.O^'* &MzO lFQ/PH;g5:bFޑL&ϫHN,Css3i\b>CL,ٳgٵkBH'ߎiػw/DQ| S"z{{ۋwgyy9b hf%@/ߎ{̙3v3F#MwnQٳ{n-[pQ)+V@QF+ gA +psoQDYQVVADQqmbDN l8p*++qWjhG& )d(n à3#dW#?ڑk*玎|>̛7cjĘѨ/AA`ZE\k @Bo>,Z%Ka~|ԩ?' I&72'VǏG__.qr\.R.N'mc8`ϋ-Rϝ;~t!^d^x꠽~^/bzzzAN4M/ӺCutQH$ 3"G_좋hhh%K/^v\e&i:q!PK375A'ՊZȲ`0`02>-93b hhhPXf}݆d29nobk 3r%zQPPkfbLpvB*x.}9' ]ږ .<xSSkdҙJ߱pPE$4YS mߌʬai9uB\:/jkk,Y$pv-C_vb12d+F'G0ӓڊ|@,,c,T9 j׵^+HEQnjjYTTlNMF24Z7'0WH&Z?ӌ"-H|h:u 4Ν;olsݗY,l:Qj9~t(2g K Nwիkl0fժȲLK.eĈ`yЮիW,X*WyXvǿ@˲Υk g:q`׮]j2 3sT*q>`Xriۛ[Xre7^ve"ȿ8Bz3d,.{c-[LN<ʾŋ߻b ["뮮X,eYc\QzL&+.1S?a|򲞞GT*Q T>=wG%^nOjllTxM4555- B ].ټ8=!x}h =D RF 3kPH%8ǫn>vqWx[(1QzZ[M<JKKq%Ng`t:O]Rxi7|Wn[tsh]]]yfYF=zikAиEAA$y\˗/W744$*++o? \.tOhl<9ijGٌ`02z~Z|( `{bʕl2L&moo?#W&sX,8Nu-V@PHTj%H֊+-ZUV- wl4E T50 NQ5I$6m}gd͜9(a޽ Xf]'($7x/>-{f4w( ٳgp8T+,ˊ$IzjałW^yE.))MW^yk׮d\իW'Gf200pO{{{"r (ݴiӽ>,|*iXMMMZѻk׮-{9|cǎ ǎS?>|8?<ȧ>%R^ØnbVk-0l2|q͚5ر㜶t.{}Ϟ=6Һ.OX?&IENDB`PKL@ϣ[[-Pictures/10000000000000200000002000309F1C.pngPNG  IHDR DPLTE3f333f3333f3ffffff3f̙3f3f333f333333333f33333333f33f3ff3f3f3f3333f33̙33333f3333333f3333f3ffffff3f33ff3f3f3f3fff3ffffffffffff3ffff̙fff3fffffff3ffffff3f333f3333f3ffffff3f̙̙3̙f̙̙̙̙3f3f̙333f3̙333f3fff̙fff3f̙̙3f̙3f̙3f333f3333f3ffffff3f̙3f3fOIDATxc'F*U0RU<4IENDB`PKL@ -^=^=-Pictures/100000000000010000000060D74A0B29.pngPNG  IHDR`}; pHYs  =IDATxpTVф(  ;I_tttSSpaaaj,޸q#>>|r^oBBBuu5WVV:Nkkkccc=Obb"xVQQz[__ߚʸx!/4773(-B!́4Ayh`C:.. 0Ν;#t_<.] (Æ GuEsmĈ-ܔ4ȕ按qXDunݺX ]vw[ >֦Be˖!Y!MT@O޽1唏-]`m {Ȑ! X)SrMeddΟ??f5<0< 6V^M !Bpʨ,m`#G*>=233n'K!C\ضMcH7>'Ӑ-\ 1gOĦM))ɓƍs/9*+t1^2q٫߭I;QzFn>f㏣nݺTxITdԌ#FxNm:EdSN9÷֔6 6MgtZo.)woM:9zvVYIi%[Zڜrݸ٩Sի`S[ۃ =|J|9|ذ3р x**KJ|XK/HJIAG|㍘={\>xe17 l `ݺ;"ް}"RR<'6oV/(.Zr֞yqaYkW~o>:V" cw9~EXsWb}e\JQ1oLf&3wZ՟驧ZwwH/Yy{ޫ߻}EW^~ڵuι}yyM7hI9YBu͛#N~lܩ&xN x{S'~/\85LYBg&Or:-j?ᡇ:  @?̀Tĉz΄ իW nU&xгbgN5k*|09gMMXRLGoo~ mO=7VCyy9<\ {wߍ޷ydxFMAW~:~-̇&g}viӦ:Dm΍"qcY > [xǂcoVc~ЈQ">H~mJaXcPҥ Qw"CI$Եk׎;ϛ[Q;yiӦ3gC8%))Ftԩ#GP;=<.sgo~WSeee233sZ@~X"IϞ^FO>qX pz ٖ-[0$O!1I|w„o0:p@^^'??%&&ॗûvuP(ygnmX(O#wOLtiZ"vďO"[Dž7;\`ӧ{W.\x}Q\{#h9Mʰٳ׫[\QgAH편v8hIo&fh<>:;;bT72Zw]vQ c!,hrű{wōTY\\l^I'Nt@R$ᩩfg}b߯;tbX`YX>K5FxxXG/)qS?5gdD,^uLӟ$t)&#U!^я Q?1L\~x'=#&<7уyᇃA.IuuXAo"϶WZꨫ Yl2=qM"B{A\ނGttS[>r$bQdv9-/ec&Qbb"8QeH8K*(9.\ؤ'B^ |07]wBv1r*sPf -{L*x5%3-!9wRK%WH<$X2ڏ:͋ 459`5*fٯG!ui77#=[R`u@P]ݒcgϺ$lC9nj m:5 Odur3CN Đ<(SjfV|g܆^5<5X( P$o^ d|K[CnQ b(1#ZvVl/G8@AAA]]ݰaÎ?N ըKdd$E—؝a_%m;)^[p : ƍP)e/"ʕ+ ܂[/0iҤk׮9NٔQPQQеkWk|kO\M ;y-ҷΝѣGsssll:e7D8/\|qaœ$c}Gk񢢢}(2[0YU)[h{XVVVH׫Gqĉ%K(۷oGȯo~9G[CP}n^{5R5T4eWRRjժ7EOAz-XZ^^·= ŋEYyO'Z3fo@L H'NΆ0 Geew9994uT={+iiiV`={ȑ#Qu2Zq}>lu֬YAݻ쭐cI`xL2K2 K(--Sا*(!"ӧ~<*Hd ZcN}h01%%Ʈ䌜lblzaE<݅^:uu*gEE_`9[kܹp>P@.,,$p\BEzװ%Ǚ3gjD رcA|cO+[?.P>a„G޽"DM<Ѓ;*+&j%n ǂ5];zrAPx 8(ov5< UؤU9 4x΢R-_|׮]wqǻヒ7_V\h?#z|>eʔDz HHcWg;wD{)//O"x(@AH +#1 wٺ}B9"iZW*/# dɣ)2 ri *pFͳ>˄hnh?΋ݻHT覃wЉIISprHD lʼnZ_9d k=tگ鞉cRprX?|u$h%bШ•-#)'x "u<>4*)\/-(ښcXA0P:$pPť U Jړp­[B26`Wbr1@!Q/ONԔȃK# GNҨ$vhq0d'dUh8)^n{ $}֣b`9T`auL*t4~+4@D 0kЊS;GxTfqbEx (WƚI.o7qĮ7*LZW xH{ˉ@j"CU\& õXm @IcTY#k /v!Y>7i"3z6} qE4=ֲɹ[H eU@kyE(ϒIm̀(IipҤ}iiEB16Ɔ~!X|u n2@Qk0,/Hp:x)B]^l:@PR}@ՠAβCAAARR gnB%dD111/_Ƒ᪬ ,*VRR^3nl5P74 ۷ |(r{_633sϞ=NȉXBDYe e74{͛7O>ܹsUUUYYY ~Wݻs˖-۸q̙3<9\fqGrrr;v#dDetV ̛7n|իWBioA3zh؂W6lXqq1!&&p~XP lݔy'NY"yHݻ<.Mou]NEvĨ)ȘajrYEp$ކ9xysywc[oaa)3< s @ҳzn=rss h<۫W/; gϞEYQDtiq$<@LM<q`Fw9:Ȁ!X54raH'r1cw^`D}V @uI ,h;t#z/dҳM'n,?F ߺ+ oqWk+&{7Zچ?Cl#,^4$ R[1%jbkiڲe Pc00  ##cKjH$i&hx ˝?@b Zer)t<͛C!Mjrշs$ Ϡ%KLN>M " F[RI8ؒdIfWI N(u{~|BpSP5[@΀̓U~AСCóPOZ&psE΃x\2FB$ #e\ M h c):0,ym/^YļWr~M(",AP|Bѣ$cx !DN240!FmF(FTHYPcI-Ů]\/D{5D~…CBw$`\V8EHJ>8p #R(&^ #硄4}é382^s7 F3$&]bd+d1G΂h IJ&؂are On>|Gk'NhG+7FYa`< 2tK@-Pf+Fwm|n7Z"EQ}ke NZvm'v#v(}ڝ%YǖD3t0ƒ3&k޶7's$(tU ~S ZAe xDXId>3nX Y/@XLMM%/;sB&C !͞={dCf !V!ӀG#%rT&`;s1% )F q0m^$n3nmd醠GZ(* {!Dn?\^#{򼀹~۶m`#6Rh,'hn۷"&=@[nE'"H iʔ) ۱cܴr0^)ǢP={v);%X4r" fsHe`oa2%͙3g,͛ E^V:Yh$0M 8EEF@ MB]nˈ!HHmf̼ir|E0rBc`.I! nr8 hz 66/wIJ!|uMүaҤI_0~ w^21PmF`!@ Cwe6SGwI׼2*~ΝTA~kP7*"aV{]PS;ͭ'Ȥe ck*ܧ@ .׿d`VԖK~ rb|IG )&DIC4U<@~pB ax:1ۻKIS0xd 1yd M$LBա#BQ.`X |\d y( qE*8p F(d[G!>SI#:O.C"I( .rC-6*3fOtw+UҥKCKFdY^"FeV@NG8ϖT5@SABnJC>"s\ HkOS:${ ,6QEPa`9d [zUk_e&eYA1WYHN(4gU0GfZ5#;Un mЃyFx$wbQh( 㑩a#hVT6!2X 9%0<83:yxe: R˗>|8F0lYALQ-shz!Zc-H=H{jy-[&{¥i쬶K e*otA^3(`H"z!@ xvl!0G;l%)ͭqZȿe~:@z60Ke[x(Y #a,x4Crho7Ia-1(IpY" 53g:a(&Δ)Sl9ɓ'o~hرQFp#FȒM񤥥6gs>U/zS.PK[52[#rRBV6xHxa,AXIr9se< Ge-<4$RTƲ5Cv)d.;K7cLpQE/v7C? CfBCqիW36q0 !wNhz.E}eÌn3hA?Hzfճt#2lkkw(:'HtK? 6`3D/UHPPNBhpA;*+iv rA K@0$LY!{T˕-$WH*(5#ޗh 3$]N Sʄ{d@.5tK: 6 4ݵJH[e.BS ig-Mlի4 Xcu<`Ζ6xbeT+o *n[w['"ς=Qf`2gn(,,<~8:=a5ʁGW(8D F!d(MCɹi]vS)' *8%ri+G aǏIMX,~I(Fф1vXi]hdvBKv xlzH;X-@aK l '/"٣OD#kVHVfff_[7nf͚={=Pb0+L0˲Yٳ>;sL<={.I?nE1O>$9%K%qg3̸`ed.ԩS /ogٽK<8D࿥mF֍M±Phv&-1>%t9}IZFI0`OIzu{2#]t!#v؁Z*㼻w5jiիlOKK?Kj+G^ta6@\R+0 %Qà B $͚5]`{O+5}UK(S7m9 5ַ$_qrrr7e0Q*YƉN6MydÇh*x&evmI܄ϊݻȈD~<1HKr  dHD4( VPX14DOBpBb㡌΂r1f\C O2EޒbNWBCuu5–;l`?>cK8KpmgT2NNN~_ܜۭm z,_hrM_r{ŋKlxPYj -b,N CCX#s[x`/"$J_n 3 {՗|bLA@K& k0k4lʕGeNY0;ltK7A E!^QxYtȝhB!xtFYcDWqFr!KeŁԼmo)i8y[_5xgOgDPyy;vĄ8w匉Q7()i~*t>{-##m\JJ Wo+kk}.u S!hݺjW_:EdQϞ= 4A l/l]E7 ep+oNwfH 00>;7&66k>>!~}mjjڵޑ#]EDF.׮yê}GGd#PNFaCAεkvffll0u\FٝZV|!lƺ^#FDtHIqݸ*/66sfiׯ{pSŜ:Ga]:&N?=z8++a`c ^ذb?>.. [") F0HֵeKر01eb¢xʖ-YԑmZ\>{wǵkY`,Āu/Dnj0t3rHZ@g hNH30;- n-`g Jg_4pN:C~~kwNA٢ƍmN8N[w>STTd l+**Ə"Igkgr/j}Ed}O W^}ہƎ[RRr-99 73ʔ).]Blׯ_ԩSoL >WXGEEg\9r g-b,\0%%'OOFF*7m=l09 455F>1l… GhI|A:11qe3ߒmteee!HOOOJJ2W ?~WfpՇ999rֲAvڵkܹPG[o߾}ڴi(`ib{j8W{Kh`?GJsm&HQ !:?L 0 ΐAh@eٔkCV"M!I.8 `N.#<ᄤM=E$Qݻw{ ١lƗ.c" }V7^J$J2C/p/]`0u} X,bX,V@N3`DcgU1JķzDxN0bX,brBvoˆ(D "2OB{g%RB55*'65X,bX3-F9l!ji)'&@PmSbX,L@A# Np |AC]>iz#t_*5^ R|{Ⱦ,bX,ta`,pyu㇎V-:'c% АQjr7#,!,JL,&&bX,ۆty"*eц &\TP5]b `Y(& 2%4*jՒ,59\,jQhPBx}65X,b<]y$ -9`+;u/?Xa2$߮cIIeӼmiwo<q>5% "?<Pks Ց"hb6šaT5?Yg2}Aj7'5Zw `MwJپ-bX,V@~4q3}BCCS7m5pO`@%[,oqkdWj_tG_ 9eVfC{8jtpGBܝiƇzF#!d _;;j_ۧV! LH'(1GLfnS&wG!2^p<j <@JdbX,_76%X咏sc>!ܚgp_>EZyVs駅2z4۷q]MMRSf MSe>]*";lH Z- s &#'"SHᏘ{cp#CZN%3bX,Ӧ;?q˝!T Gc鿈 #8 AA%$\.L^N2>{ V!C]ROZjeYw,JXYɋHdJt"ߠz8b 65X,bXY&XΰHCݚ";qd`ʀ\R,q؟3z74]IED -gmb{ y ޵P=ᄉdAB9q&ilzl†lLH}JLxaC}#?P@&ʉ#DH$f˺SJ7VR%rFv,ZEAE$g r>ਠ;0bX,_OFt_-~3kj0 \ )7.mR\9Yx^ '61+'*lm(Σ5D|a,5#x;s@S!q2GNX'dni|32G40Kʬ,\P't,JM sQ2a1ۈTF1R5yX,bXH}ħ߬gm?@>uDw؜cyC9@C*)$݅)D|ěͧTD g6{l/Wt@6eHFs93CJIj'K'eY˭dňLZst}F'_DDpLsT ``SbX,_1`"_ Rf PME3\#ŪFRT2-B97)$4H0P#%#EI{MǶyq67 F03<qk4A8Y%{;X&X<KqҙVDVvY)&$' cU\t#n8fSbX,+ mFW|;"MF^@by4ty~iw@_OvC(&lc!{4bCk42pONH%Rj}FNj9K [+\^59ag[]B* S'4˺tRUN%.y}rs]$ Yy#&iB ">JF$/&w39(7G`2 UbX, HC/33Mjz*WVDQB*Nۖ$v.>#m)^pp?m3yu?[K{ 4є'=:1-(A+uZ^NP*)zkِU;GHTD$\T!pHgnr`;^,XN*axxp,'GF L;N9AXcErQ'ߕ-Odkj6.EiD$(" DzHԳ[T< bX,y"HdTB W&B ̱3pQ ToͲz[=w(|./b{ |h_cg^}ywa]b<+RiE6)Ȁ-H:'qjC(Px01=:W)!( TUPù[.:%U9){x;q#G4!W%XQZr.d~K 2%NM4!QG<"y epO zO:*F % 0oSbX,1BF!:_m>p W ti Vxbj&u51qSDG{* 7(^*#N\]Mooqsd]9͊:.|Lky!jB™["%hSD@& ^0V7"C|9I& L(vHpr!Cad,*=4|eVNΐ(9dE%]K>aIr |jpI|wDdj!d`MM,bXy:=lFm'՗r@9~%$p]&^R:ȷ")EB${~6ɹW9\pkPx *:2hjUGjE[Vxf+\qfֲ!J+w9\'aKBsEOjRjpq q0YAE J9'/'"r谾Ἥq2cP %Y!4SBUNs6EV+!|2+N,1x:"("(:D_[=Z>9Je0MM,bXM&%|{+Ϋ)AA W^ы*j'"Gt DeMUAˍq깭X&YѼ!ayC3O1>?G^ G;֡z3Z Є6 ʅIQ{U1'JA:$ FuQJb>ƀe.I2H8 qpVX۬}@k@3L 㚞1~rPfDS DO’. dFDFDjD]mTS8y7}}%qbX,_g@fxU5 DaƐmqYߚq"mClkz9C~a:[rh0:(G |@A} iWa&?KuBiģXZjh9bꀲ'>ІB $XLzaġi1jtlho==G !qp]wMOTH%*\-rV5*ַ(.(4=(0U4kFrQM1ñ<9QH2XqiJI:a#lj"tYH@yAN it9@'oljbX, ȯǙݮCOCS3k7BP }(Vb uH9.5q΋ABCL5}##C:CzC'5x&?D'hW"r+|}|5А -EjS7E芏WX@*^HK DaDQȱcc䤅#oe0;1{]QHrpuc̲)B9q!LPNМR4v]T|& U!1LiF%32KW &3:7ß*4TS\\M_4Nȸsd!̀AL{Ll&gSbX,V@~2aD55Fk(" C<<*A6 4d6r$ oȗ5ÓḬ`_H`x)i&h<8pj?IKFa|Zy$BI@^nu6Q(pcSLEyTֶrƖU{(D6eˆvRɉzU$IԜ}!I G\7L_.W|V$'Jt A9n:sFx%" H ""rF,B^9nJ8L}5 o65X,ba:T] ` fm:" =#*NMʜD| ~^<#{n!/tG=l"LX,b1UWWKf$N4 pHHAzXR F'r{%0Gt\u.-Y.:;7xCʾa 9'B&5bfvK 1{-x%*҈1L166W,20TfӪULҐDGdk=ʺkuV~zBR2!j Qgh:`l>mD:H'튭k?i]c859:S4s$,DIƒ.uԄY/"gΑ yH nӑ>h@2MM,bX9y9v?p]\ƚRn?#)*~ɖOO4ZXN LR u&]2.\vLWC4ad2g8≾dD9AqHBҍFQrϩ:E+7ņ͛ٵkExڙy%Ib0M ץ!Q) qZ!(OGU[w+$ƬL4 G0FEƯ6TI&)l^}ȉ&'x:WX>L)]E"I]jeM'#6TIq$zt VyFFDrr={PNha#d~dcΦ&bX~kDg?㜫Kg?3^^=dN-@"'s%NODQ(r]2.){P7P ߏxrB@>PS. |L BU$\ C:=$.P۶1YTj$JGsyg1:'N C(@BxQuS吮kaݪ, 3^8bSL+qjԲR9IԤkvcc9M5\9NN^<`%.#6)EDLj S+%tʍA/"Z'MM,bvH) -s? Ep7ÉM "!B1t T֝mgV#ԭ݄p1j {OjHOGɴT:['m "? WrBP$P*yLQqs dVӱpxH<|.0" B$C T>9YaIp">ayqm AT 0pь')IQ4չiv9{$Jx!ax2 C2TZ䬧|x& &knuMMrHND&1{n :1"}79jSbX<1 | > ^IMe䮗Ѥ8ug~?ٟȟ:v~õz3֮aY|MWR:*.OrFI>eNm=|' Ù5K6d]Z#2 OT=0!2$\K Nu!ᴜ4}.+ HFeJ"6Ӟr(Mmjk)Z)\<ĕz6}! %iM eD(Z$)S|z2=V8.̌pqpS.qAhSOd:f$x^HQ(syrb|>O>7ER.>u)0FG(' +F訏cfg\bj|Nc:B< Te|HiGD(Bp QPRleFN3)Ȥzز.9-HJ+W2zr?9|03I%XbN /'*o}R"Һ05B^DrJR zw_ũHpdr&bX,V@1s]dz2$J.rg>Jw.={3Fw1r>Nq]nWyt-&E|nSw-{g|g>>SԚK_G>&.{G vKx՞7=~s 8ٱT֭[,HO'=G3IB)ҮrQ.H#46Ƈ/x~(R^J/GD NUP$9}^D‰GU7:j]ñ Ono<ɱrͭ-jRdt|.9u_|Ε4Ԥض.;#0T S%C_u;hq,?x!siX+HLNd'Q5d(Y'i<|Drqs{47H n?X,bPB&ʚHz{Nꂦz?ՃQ/)hpI*.?m,lϿȧ'^R/Rȏ_Ʀ ciIڒM\sv):1dwqE-.zzqŋ \4z:3~2?=qק22$ N3K![㢲.1FQ!#|?#ʞG\E*qKTShDTMHX *S)&&hiȒR$uudjqM8 #WPKo JDDMCmZhokA?b%b|w$[<^'V &K4ū#d#||}uNjrCCZLF+(9ljbX,C##S)6oJkZΝ;X@l9r\[hhxm~Uw^Ӂ({cnm!qN7Q &xb~_p_i׽l.>b1iurR v  QdnϕԵT3/(-9^IZ>[X)vsH)G+؞&izQrT bX,V@~ g\ƳϺշ}kǟ=Cmo8D™}ay_߹u+hPW68/Bssk$qtS=4C|?E{?EmGG^,(8h0}t+v65X, BU eV"Nu;9ct5KƔ I!ӇRSz$J)jVɺVǹ1qb?W ƎM-䇏s;y{hO Qr]̪$3_j8 kil8sw`Gnm/`S{WU;ďn$ϸk^"a[:=I5uY0Б&!QAQ>"L q0@ 檜P^RKe*^*e|BTL1ΌAD qV7g &%Fsq3|xg^3E"Ufk$/oҳ.ZW۟f^gsɹ;~t"{ P?{B$о; vޅ7;ǝ}+_ĩti㣙$ QIe )h#Iah@])x>rZy(d4G].Nz:ˉ BC-m37Iş)Mf`|v;&W~sJ'or+-:nٟ%-"""Edo4+= G#GQݾj73eSbXyǂ܋OZ Ҭ[w *[#+_C_8H;Jbxo}ƻW<>hWg˷1䏜8$kyx`NYǦu+EgtQ?uvO laݦ=L9Ȧ\ts>ahx3[߾Et99-xzp ?׾s~?y n]GMS=k||Y{1vy&_q{.8c21>I}S(MBA1Nc FMOiA.m05 uh#jc%c`qĠczz-;z s$ uBckQ5~J^鲮cSx;^bR(-qV V6Jx钫7!ԉZ9U<[D B%juHxlw9$7G1GE_EbX,V@Nd}54gUU_E/ BEmK3kvn#,r^݌>8f+ug7pIǧ,shΏ]]F2Ug|]G!(e]7]zfݖSNqgFvκMey]S/RLvvf*ўu絙ܻBq.zlK3_x&s}m\WC>ޏ!gx74>^Iͩ;Ol- 6ɵ_u1{F% ~W'usdFq?C,wºUUN/w`u9QD&:}/tjZ]wI?:u[|6la5C/ڿ†6C6X՞=Eʛo⳻_@V#n (X@2 MSmbd8sN>= pkDL|6;GZ#}6A0U915] $R 9 mwL'Fc{( MאXnVN'5/LLD-/3KMiZjjS\)A$!jwJ}IM4Q.vʦ&be$P׾~un~w:Rμ"S<6rvyMyq wkvݫYmɇoW[>JCx7s^]⊫͹A:`͎8zjtuJ+IySt;_˓&Qtbo}o=|kg}2O|ɐvyI?^9gl4> N};kwPtqYAYQz͛5*(ӯlf ad"]ŋB599^iLyCP FH'!ol;ߥU9 a`w\RԤj$'q&wA;w6Tδ7n'Kxd\ W3U$H2*OhĶh0nlk۪~@pI$?lt nj1Bm]-DJI{c<=̖uoyv< ǁ\ߓv]wM6KNgx8V"ݴ{ϧ.Wk:j3yΞjz+ 53q]3!EUĥ]I˝4,''dRBk=l^5+'jr/5=qIWߘa4)Tď#'˕OL3:k&kQԊȚu$Mi-S)=7r#ڑ^"iL'A8eSbX5PTY(Bbͥ/UsFsxt g]κ)SѰu}?324PK93™>Dp~tٴ{ovʿwݼ977E9t\װ E8#B|˖",hlnfn <-2a} IUR G8ԙL<&nuwVQL0qxލ=v ${H2w=s9ׯ =:.ߚIO`% Q<a6=IJj"TXzLXMOAd6=m(Z('5)I m uåfcf$WXaVNhaV$k_x#[uI3Q$JdJ)-~"PwĈMM,b=7٦s|4ԯ㪳N_"ԭ)oEP_|U6 :6k_>M5,&-/aC*PrچϾ>n a߷?O)vִoyW{V˅VN$_9I, t%ZⴭO_u!G(“eMu},X1aR.Ⱥ/+m#"< 6 t&$֤(D! Q D<3N\wpuަ~j* QW%}O<8M<4+7~zƇyȆreC%A/BGYYnހ䴊ֶV:s+۸}+ {gw9xjAInq0KO ,I1:Gq4MJr I{G;!NX#@͔X5@1><ȃI{ E~ҲPD %Nӳ'fFǞXaX.5+ma|,Jʴ6s2VXr.{rv'BumwTNƧ%GG,G%'mh$dnӗe-.?DYA9H9Cd"FB4EB`ٟ5!bRXRՃMXB(ī,ʳXTYǺN_kJ*%M|NA*>Nd5CKhP1m=(rߙM-1pdWQ5זd~>tNt`择;yy쿩ظ0XC:A;A c0!tPC]V&ehBKť 3>Dםq`fzFRRDj<ʮ^vcǣ7d[Y ?y~.eya/ (bPe84i0f'JrɽAW̞X^X5]VF{PRǔؓYaieKy-OQڥD >" ]68Q)NelJrdb`4?,Ld 6 S1MS-58=Bx2˚ kbY2', ]eq}/8`hQaXB(ī^ϩ Mk IDATW}7ϩf2'ɑE#T+knsgG~/3Jq?KrX_z{{ -I̅tP_pjc\VAc:q>.0(VwfsdhPEӾǡ٩SҦPTAh:ZذMdث32e runsc<.iYFR3 d06T!60C%-3<98Np7Np{L9;ظuvF4**BTWql&9ž}GI?W,uccē&N]SyibfȹgJl\#lcfiA&(D !x5\FSګ2+=zyܰ&94dOgX=NEɂNj3(֏N6xv[BTEt ~ޒ&,D]1KGPXB(B۲$X%]UUBbBbƏԭ5!'@N C+HGH7ǑA|:&Zy*EQS"o`Y\z%ps#qڄˊ3myp0%Å1[L(j8ei溺]2"UG5P,*!XT@T6ё$r%Y(#P}a*+.cN;~x {2]Hƈ'R9UQULG'[K4ͯёqPZ S[4OW[`)Xh",(0ENʞ eĽDZ2; Hx3#co}Lx_[h/8޷cEY؇iH t -#%I1Tͫyҹ`#]]#ёaV0Ҕ+.غ7\Yɽy.&g\tS1 Ku{3XV%@stHia&'y᝜7-]N!P4'~ agDݡPQp w%mb3toJekp85#Qsޥ&&$C''%PI1Ofl(6%5?c;类% H1syu7\#yz8o&]sW=/70iO}%d =GM{T|/ Ѵ x x|~ZZHwీEy8(*ciGz{ߣe**i_҃n̰7wQ%וlڰ梅ZSyI,ZB@qi\Bym;i: IrehS$&>r4R r*Zm{qØDs(kҘEqi]m%iH2AR{xM.fۺ&{Vv2:EyIN{beKfkIi+a!0{bXaO͞,DN?=9!p9%Ah(('Sq- F,z-"p0?eiע 4z3h!N_5˚ !Vf&BBJ5=A)ҧ*A s$/(D׾U\-,k3p\c&-v'wu<8ƍ'Z2yCsl2s<ŝ߹O|S8](# ~-\|k:.?)e.j;/}G;ٱwe Vč4iBC~ts뤋46dpDUs8IfhX bftx K8B>Tifv1Zg 麆lpP^姼tχpB)m㚫L11L=88."T?#G'񸊰H0 5b8~ N؃9t+xGٳaa6nJW;0t8KqLT.Ę'4̹uKy-eaamoN^[aBWϱҮ8v J\yt\2I͚߰؞'cӹ.C.%N!d拳&ZK\4e{Brʅyi1Jm}CٗcMQ]R`M QB@Yn?X$i+c$bӼø+䋴Qn,ombmk$oSί~V+X=4}^ P`F_[9[ObNy/,nVGz{>o-u<".زKEh0̅`@H_}bDn_tk.qUS}:ӓrٽ] & E TXKwݿȊ x=uWMcU M,YK!v>MJwu1Z5jĚǞ -W0Iڔf^iBJTaesk;<}RTE=hH\(ī,XMf($34,2f SݽW]KC?-( .dlyщI{%W/eV8kv37jz" Faj)XNYr6h8tMKcԔЂtByIq! or(I)̴\Ǐ|gx v=8u!kӨj׉f)?Ku-zބ+bS;?!j:}%L*q}Aܾw 4,p8T[W-o%lT]w1)jXkna$ħGLyA3rÌOሧx]pؠҿ{/6d֍<g MRҶ:4U`ӤR)n"fTf/B)6{ɢ H4[3yu8 iU"ΝҮKP8d+.HGlPrlȨ V&683`T̞VoJJ cM k) ublmⰐ^k yHQ~#I5)D! *^hK3wF!wn{v8TAgmVNs26-92l186&˸Om1Tb1r*Bq2oe` ؓ9,Vƕ`9ɱ&MYŒ2n!R*:$U}8h0ZRPGG{+m]Xnh4zIK%=^7:Ͳ,8uNQ[4mN-;o#~_G!8%u<<.~|b[ff/fs'yߝw%"^rA):1$z^Tow.Pӹ饢&ױfًښZ&& 0pyݘ$iD"QTD)iĩ}I QTJ}]E&g@q<.ef gY!TQXʽPu|Eut+uY)4ښꩪt⮧'>Ļn݈2t  )X1 ]6Ѵ$^+dV-Sq.bR*]w8@2H}4*)`S=Q܄[+(>ȨRZYH]yDuNgL0"O"4Ӎj(` `e'vytpѥQ4dk }H"ㅾ"Oq8ѡcۗ"-{xx㤪 Wd`ڤ)tl䉻wsqʻ 9:(YW3aO 3;19dv.mʘ-ʰ'ii"S.lb;s+( P]@gI"Òc 89 ^fЕ,X 3eAδk~geQ!|@(" X>˚X42TRıuWXa4.x5)D! GbyhjԦ::[YI%r$5'`c4MLpZxuvI9 @N5+`.G8ure|x[i_A罇DBa>ٿ ֣D>ʧ^z%V&?Cfv[vGd 8H]a*a[߇i^ng's^Wsbٳc/@G!5"/7_jxPTeKҷU4T8ImqB:G.<>7ꔓƖVB}x K~cG%*A}{?[6,{PK*i} Nc RP颼"K{v=$WZCױo+9ҽx<WƺE C2R0\?!LI:9s7e7-my͡PUmth$OÞ؝L'/43ZY݉.2M03icVo.pyΔvUv_ޔ')n!<I`sr")JSrNYשA<1_vIY=5i˱&&R)!qW2=60UTe]}?V} QB̋"- ƆZ`,,GHJ=1``ZAIu@Wdv^O$9O@02'sHɢ.fSlRX$g{Ww‡ нb}SumeE.|{ȝozJz=S%t  D-|ފYD "+1tUHS/ ޾!>(<׾GN*xUKٵk7JfƮZ'F)*g͠9?Yov2i zT4p_9JSX'wsAAgïj$9p2~o0gMyc,::[X.Z:(rKsoF$If҂ 0-P]HdV; "3128Y*E-t&2Z:a~xifAElj{Dj۰DpO?8^-]H>]o$؉өN.Bt<2⺅G* BKW20]̆"K*YN6 T OE1M;BEUz4SZLh %!')Yjw]?RT;jVd]} b%+XH їٰd ^?өc3ac9띣 9#˲2-g*t *ۂtvTy^?=3˜K¶0޴$i"aڠDrDUlsk^g&( PW5NYp"9 gI~<2euM& eA^7 kOδK#^qwcR(u<j 84tu`Pc0v/:3,#dxRJqjAvso99)%)5G $zP%!~%d?ȴꤰOod2a7G7cL=w;w=3<ȃm”8T:{Xk&a%˚)TwqU_?i@4 MpmU"{9kWPVA2m;]\N04. 1Տ!\4/[O}]-e0%Gʧq9WeZfLB-PTKq(SyxxrPZKEKG :\k٥JdM2f8khkai 0;(gI<|;"zXH/ys[ 0r:wczGxm}kv% y7~UU {ռ rMI,POK77C!VѵlO }Өx눎NOXE0s ѽd!fb\gqf޸w|+eAjzVm`˖U\RS]okY WǛ)]a1 QBjAW}F@Z`4ˋég}Ǐ?@Rd*Ep3w⅃IZ նPQD$26wXΓOl54.^6{bYHĜZrm3۹Kbi;˼]0QE^iW99K!p:%h($md*.9qdtF,%Na(%2GqU@x؋&#Z H_3鑧RRIP: QB _`4|>OC] 0tt 0ʫf,h#"zf0 B lJ'a3N 07^#G4VnU;A.Ѷ|9elN8f \TbV^UK>Σ;>}t $I,9.ܼuKrbpt`|]O3#z5_Ѓ_jͷiq/<(ǃ=E$szpks2l7m\0Ar @pvKUQp{hZMUq]%|)&'83PBCG{=QOd(#'>䘗1:\trW0'"T6(*4 tt:2uaPE,\g$%z9X. fe'y1d3/-fD,.yC 4Ufr3ρe{D s"1셔#{0"/aD{b6nxVw (j{A\ 9͹57t]DU J^]. Wf3'{ar7'v|o*ǯ|]FuC凉Or`ؠ~&.8z |xwG350=MytyNse.6ILigiu47J?ּ11sϼp-o,'_(q5lhFELL~ ebeql%&R'zcT*Y݉iJz=12!Ү,8v NAY+U΂lFd2.nEhD68ɸԕτM "90 DĘI )Dt.2S"LSP (/460z2 c quy F%wtRQ݀p#~D2i\`XB@"E , +Ê $j+=ͲgjD8/G/_|%j "HIC-afWw=L_%|V NH8N6룴uyLvI =ƴE1΍l㼦zÌ7LqRn;?ȕXK;Џ?ZfYO'=u1~96^+vDO 8U"5~Vod4*\H/YJie+-q|aRV'HpWޔ`yO~ً3~'XSM!'-1 LtvNVGRz+1o5ğu?WK' v>{bM.2M#׵˴sKLkV/I4!ee'fk]5f< Kr̉KPj5xf:fI 892b?YwxG՞&B"<=J: fCRuݧ8PEF VBϒNzvIe,peK#'^$`n1q*`"Tϓx~̩Bs!tzoFބ4NFwŌq~LN2?<|/_eً0砺s{i@ʫ |Xp>ھ?`uo̴!L& a֭[;qcwhM=ŊP`&@"Btl:;Vc@ɶ;]O_sw۷;ݟ)_˒c|[p"2ͪ [Yl.^؛_ϧA)@RJs&UI˕h8n-\Pm8.:3i %!Mkjhgƣ>P0# 1~`'~l` Gx.d8)ᡡg >'~A%u>* >@TMG`c<٦?Ɂju8i -&T.ʁ=I&0m[dV6vn6HdbȰ]5 N,&3tRp"|DP!^/䔅(Ĝrl/f9`ttvQYӈ)"j QD2da[3GF䭾B!֩bC1̛SG|+֠7]{]7+4X3à_6Vln3 a!&~D{_*!eĴ0^"EɋznZжj-7uznۢZ w)λBV\ZPK;oU*ꦶM[>@bBJn?16|"Uo{֝ a&h.<Ip߲Ej6^Olo/ =7Aṳ!N&-AƇcy{5e˟X^y!O ė^^VBc2Tt;"gi+ͫ$|xZt"]TMEy}=Z*8NTa2rcS^q.-΀Z=uϚ2']ޅi+l߸MK43쉑3e̕v9]yYQڕNnUUfeuM$cӒQ[?4!.MsBʢ۽'`8ښ*[mli7]]T6z7s;#%3sL`3'oQ(8Ey]q 2 Gkm?FhF.̩L@f03X^}?cQl}!c`UIamxH~ؓ>_4)ZFZJ_mc~ΟBзn,V*6]p5V^><2Toシ{fv._l.:h(+PʽZmTT൙ %|?~'~vPny?[+Db.Uԝ5Ru ٱsvL729I,2NLP.%u|MZHb#b]t Ǿ4;eim0;MH$`H&K3 =84p8p=$ǘ1tgu,۝('\COQ6'Qt^;RZĦ 2~U$qTL jh8RҹC;CqgFUSRVξxnC ZxGyU+c ϐtVre?GxDIǎp;XŹ̌ld2ʻ]%3zVo?o cVof Yl-!x T҆81L[HCiP]a(ĹeRU*[n:;P]׈-&jx0?H<6`dmrƙXyʵbF:ls@";F3_@;`rtL Fܗ}ٟa&I=AJ0M UÀ̋.w9r5o(FRffnNx l]Ś)ָ1la54lD2eO ܉72G;yݔ9lR.f|Nn~mm}*n'F7}l즥PYCU27E!QŠnO$sYy&q;?u{=櫈{ SW]DtlM7o|O't~'FZ,Zή.b>s]98nl%l]LƑ~_l !@Q W5Pb<+w{7/RۺVF^)F,[.eSG-^F*m"Ñ4 ɮ;u")x^{V!6q\&Q\^jJqIG%^x<5_Rӏ=NC]=piia1~$;%E<>xYRe^bi9Mmͨ<"O)~!ѝN.z9쉔͐daOr/+#m+]81-'6lpCsWJ^[᳥k( W)%_;|YNsy΁|SʁYQ8u9"@@C[o{ )i(bX:y4ChQ5jhUK=ѝ1 u?~dFhD#x.UWO~mH ؿK8kyaebz*F3?<N9~LU KW5R!s~VDـ bP$ {J"37z);j3 gf6'1d;|b6ר8S>~Yv*ji $,Xm6Y~$wr9uPEŘV!F[U;W^flP>؉.E7u:nG!VO],`IMMG4'4c w] { !?&QrcF|To\۟%M2$Mb]M1(;tMkMꠞ5eRt]DG h5 'i7Ʒ*'$uVO@E#F{cq]F(IiRVRDRKHE%vR0Q[+ƖS#A?DޏW$(AO5"jA~cp[Wқ_!&sʘrL3M({ߧi9̺?ƃ%K2&*K^TΦWsҕopcd&bT{jHb:6{g9<%={  l@a{4jn9s][M((-рQ,"Ҩ `pit5jm/eh yuǠOx'' gEj᪫hؽ-I~2YEeZ!kMXЭ㉳te9tY ̼fv843oe[QUSY<"!#.uݛ޻>{(Hr㌳7MPղhI)>@JXګ,j'SRji&,Y R-'ά~b ,'TMShr"Qy B lqrvaQNx@6WAP6WYeGefIc 2DtT|9^8M`8"*N@K &\I $yB30nV1$${@٫vH6eD6SiWO4d4]&Dv񺆮EDv8]RX@FN@z9@n 0$U(BrjJ2y9_y)%%e<4v5 l5:W,0㐪Wu\ﲚ!Jo-V35- FFD0v IDAT1\ D>U0Z>غNRt&lF?螓-w%Dh;BJ{VǏHO.';p D74 >ebCZChIAq8l% HN˿pPg~l߾Vn bP$Ŏo2۟(eԮ_ؽ.$I!b72?pQ$ƙ=jw%㰻<$p/6kZDI FՑ ;[7e#0@ AHz̆;LgWO݂֗ye\&߽x60|5Qv&ղ?x+6fYq!X~ 0w屋P@ ׸f )r7\990WW2‚xqf]5`ta2U5Dk!m۷loۆQ|_Ş@BN:3NɠQo/no&}+ٵ_tmI G]瞤1!!^M5@s HP2EOjr{֢B("wh王=C0d 1ι| M۶EΞF,]#-8g<˅M_/ߨKL^ՓVc֔QkK*)j N"[SԨz"18騞tH}'Tt T8[Q$S%%gb{Wj7ktf0TX[5xgywH>a(Jx[v*$#A@n"GS!iWdh~`4oЍh'tDK*EF C K ˩DEvJZrٷy;r䧥%rh{E4/5 p1!C{neSWgR߇$\"bٱG0޴D*فd$bǚ,*<z՝\ d@*mISs`݃nP p M?PLP*9 d&63&˥[0[<\p-Ȋ V|ĸ8oYϞ;\+AD~z~1EB5va?lJ.~B 0W7/)ġb]]eYTVXmVl6K]iG`d"KARt5w?G}Ed\^ؖFYB^Oy}C+)Sd#P%)˰ l_Ǧ핔n }7߃zb) zzE5']E"`EjױNtޣ;`XգM%{K[^Fii Y4+ktVǷ0C58RR[C]KOJQk!D5Hf(]9 A2A m%zs#Z%k[? ~>nF ]c&5 Tz(&cyJ IUK5E,~0!?eD|vtA$W%eUwR{՝m'y%lAk;VN: e퟉Wg $ݕ]iħzL^aTd'Rmi2?0b[<^-$wclRCrm?+~s4d}o\ QӐٜv &ш[$ ʆrC^_a ÊǓDr6Uz1mƾ]tʕ_pE Gf\%` )\ )*#E=҇YA[TcQqrY[s\Y-"'DnFR[„B!Ȣz7M8węEzZr&u!+2`Okl>D=FC$1>H{x-j쬜G%Ylޣ;:>~HOJL)+._RJKhOlZظީyfošCi/Gd` RG8n=6ZCzJ>;] BL2lx BQBL^nHU=r:F_4uA3]~D(ҧx "4kwż8Ρh$5gͶlٺkos뭗pW3k|d=BZf ?&oR۰o+Yy#>@P{|\eas,Po;Dq !I.M`:rҚ "RcHE;KJX'0YD;x+2= R^n6e%E+/̜|LD5ĨޫyvoegPb07 1G&$^Ď I8@qdDGuUASѵ0ݯS Lo-By Vw̺kXx, C1N\ z ]AAd26+NtR?? rA# ~ vVk "`3Ɛ6Sv/8)JbG۳~*k'((=PUsxp\T&Ϫe xj~z,~si@U⣅Z7*:hjo9%}ۗ b x"&o| g/-@yw:ma,/`He;E@71de?0i\.lݾ}gSu{p6X&sO0]ͪq>:6j[XoXZ4Զb$YܘL;c}h؍ BN M bf>YĪ;Y3gw0[2Μ"m;JNT4YgJ>kWu8K6aYsV!Ɠ,ۼ17'JpPOUhN@ACdA?wz"J==Ѻ{ic-QbD UPUT#蚆4d% [8d (ܬ6(++#+'33`T5:ϯ};x0 "Ѡp+Huk>:wu(s~8Z&]h{Jrt b }yE;d(X '(h[oѿlt|u$)׭C+28 -Ұs#5`廯Zgٿ`T1dh 7n徳 yvs'_y=0ml'̥@RfL>T7_,yB@&p}6^Eo)aAhd fyGdܺu8˘EYI!(/+#;+fjTktliY-DWwtǫQ+^ңz2wEjʑ^tzT !0i 2yƖ[8mIэC D&{J>Z63o5+jسy!s?Y7\FN `ficvoeϷ_!cvyzQd=uz`ANtA 3Y55IL-.+!Ix0:9t6Vв0.È~q,=0H} ru!sT1$5veDb`'WT3 mQ(HK1(蔱E%BǏw _;oE\~1 ,6|߸썝4zh.lYq6uߴ<.e䏘zd$BLJ\O1$M!7qP#_EF_R~0eמkvQB48 ܕ CtB\v T%g~üx$8،, *Æ̒Z}u9gu2_4o}S~©!*:"w163aMGt~}G#:EϷ|i_$z|IYbM;SeY9H_O:Ⱥ][=r=oJĩ&vU%UERh('9I̙G'lq>e܅'3qh*̎=$eQaK:"KR'IǛvkbԇ`Ma6+>L٤3IreO+ᰐ]XF:8şƝuL=s9vvn@S\8l&Zt5̢_MAA'nqQPadH$@5b@eQ pe|3.${1`$tɔv,I^ⰺ⽲'9 #hYu>]~_ ,p߳! =~qGe>^*wu8J R8zA+9TjTlw -V\F"?@fBKa0(TF FV:u\G ̊?5jP5 B` B,`Tffټ{"bHLꎚ'833~7'7v}?0{Y|Ž|lVZL;y,z5y3xa |֧3=0;3h<'i#;xx@n|nx _ƛ,^v2Ǐ!a<G4k9dq2W7S|CTwUiI|pv5Tw>JmL=SO5P+?a62`EjNݻ!kjޜ&ƴdv5ً%/Fִ)I2uT1F`=7-ztIpaE4_-K^}yk iS͐c*];Lf&3:x'Ǥig1&B%DQԩV\q&Ri`$ J CȊDT$IBD$I" bhɚ|һzao ɔt:Vkḧ51k1Z;I$av&u ~LObwTf[gs$豨'ά} zZG GuX//M{TH[8t8hJvtbpRbKY`eS O3qXELU:4pU`7%B4EsǾ?r91xpnAgjv<:.]x#y8Jq1l^ZofSLZ`uI_ @R'<+FsjMcjPU Q gg}i]x==rl(JLe$^|cֱ?Go܍(!vV5z IA?N:W zȄ EA" e{_ 5~o fKsGp0(2( 5;]@zf:YDv,&EQN.vW IDATsx܀N\R.Q' CӴ^wCeBA?ɄVh" #"V8(L-Kdz`x,Kdʌ󤥥Y,Fp']D- fj|"{"-A`!-hֺ0wz8(>EwNQh^2$d2S ҍIVHI 폧FtªN8 N Eeh:`C8~HUȞ&:HQB~DA |n3u~O߀nF<M_s?rsap0ӿ侔^s?xl5q2LpZp8^h81d\v<n)R[[on :ڛn!,~6FUe DA},_-'G btYBـ)1m Pˬ7_C ۹kOOi1F-ϧ[7r<]>d9d VEgraHjNK.#k@V%}mf{)Gsèܶ7aλlKÒĈ'#tH955_!)xTNZFFIo٤)A$Pگ3&cONC)v.%bni_AwUNLuVD$E"M6--ԠkZقh"$[)(fE90<@`Hs %`0d%  ]IEXQE~)R{"C*3[ߕ:p,Y&봭S/z ޏZ8̲ǐuXH|`IpJdxdRiQirS y6 Q@p at )rG T6 i(QdoHO9$T%Qce, qvYLF't6v$Kyb޻m۾] f+~~ 9~@!<%RȪJ|n' @d'g36oMn0&O.LtkZ$eP. v4WT x<.nRT8}_圁(HKS GIq5%栊,ClUJV$lc]T=E)z<[7l&Ιʤs|Yi,uFf]>-!8ڥo[nKy\98;WQ3و7 X]}~FY?K)|~Qg#nD~{ٳ~ Iwq$E!%˶]545 G~';iÇr@b$R򷑙I'zSBvJ oz3nv^(h T;?a ʲYzև2䬶ꭧRf 5E)vOML&~MIJIǕ ]ٳ+Kj &o+ .cZSFcJJKKzVi9=VI*m"$0:Aֳ `t/q4hK~/er5Up֧ԨBE`S.QMQ($"B6Gt¾# U@_Y`wĮCÅk*vk趴HX>o) "'䨮~d&"r@\zBD!5̓눴iLطf)/R> W1vP7U>f`m=?r?\&`|BO3gp].gcg\@QAkiD4Y$yoG-bds0'?9*U:>xQ̋ve ggx3d;9ތbP cH .1wPy&`XS]~@4`Sغ̺:\E @N_ Ju$|)C ;6$읯s3Ͽ4zx5L  U#xH"%~SOa|3(i)Ƥ߂z4 K|H4UlړLV diܶ˖rZl9*Y٧DD `@ײdZ컍°tmڄOH)"nPhb4`j' nT`X:v "("&K^kۑ%`OKSFNs@ DࢽqH]F,in`ړ^\ FOr:Vz0$+A!`ձFwoW%`4ݞ#G`uǬ^ɡ`֧+߅G:ES& )2VXhETЉBFO;(k}G=1(AmXEE*[bE .*.t]GW:l-DP@:5M"љ$GBE2zB:}-ECvT<+hBI,U[D'&_M~SΟ-g\q=dR*6JX*R8׫&q| le7_} k|H#..8ܽ+>oI?EoRtVbK0g9e*pYETՁA߆h@O핿#b䰑b+r̓7`4wv?zj9 v;v; f7f3v ]DC|*F7|؜^1]xsʙ89 YgY3s>l@#ND/52bxW=$ZSm1;X>[˴QE|¿U¨ 4YIf^P475!,X-XWs_%W"2y !sjwiXk*5Š-~2@%7ўe!j̐e9=..cْcMII{Ve:Mtq^Bfl`E" 2$wx =]4ӻt =[.ҷ{^|ϩQ]Rhc[Ũr$8Y GE"єMlk>.BB]@YdOF \t0usPW' І%n{6ՉSvJ&55z^<&Pjk+%(˯$<(H8~VJ FRSb Ѭظu1KؾQkYŜ{W)?7o-]4 sL#T9/ĕ'qWI,سΫ *o02^fËs폢 _-پu$I%-;,{o, d;tNݱqEqE׵('G/MiYb+2{nF$o)ݜ֒N^̺̞:tQ!|3fT@ɍێ %&h$%voYOslV#MnKظ9Be3yGU!o`|nh=מ]JJh .7f/qedpʔ ./@F6}{FB(v3AwyRz9w|*H$dѴhVQDDtM#Q.BKtX`w #]ŌxjLLәlONNqmn%"0Tz*K{Ā}~)R=NGߩGk>Y^7nw"V1J6 $d')(J3P5uK8-FGE"m]FKp!:+S.*\l(u 1EgxpqPǟ#*Z7qw ϲU>̽wR^ĒX"nm%G8IItؖ?jN Hv LN&Ьj*4;-ϕE0xŚD1 b5ȍC:9#R7L0OoЌvɥ396%&r.~O^ĖOrٷeGT/2CkZ]ynVAjvNws9I<ʤ^5K5bM/8SpB D7 ޴w"R*!*o'>->($3y0>KkSDE-C,=tpX¤8=d$V|w%^JjbL$ӈAQZצ;X"fDn Օ;f:vT5VPΠ~Tށ*$x[W#hO ŝ #K%8YQPaLE'DHD%`icJclDQ̌8$ gJjlsY(` +Nu;aBHR&$>J!]|ݙ 9ewnfY+MѕS`8%2 REaZb[e1)ъQZEHm At]T.T |@_% Ev5Hm.]…^(F.Ⱥޯ]+_<8~>]F?:$Ocs|1BA"!ҷΰ1˙e?Ӯ夤4TUGmY8N~>Xr'& {O>c޸~\Ɋ0Z5c.O |{͌Q}I0}w(Ń/wR6G]S7:N+u|LFF:yokDFNg|Ŋ!XOEN޵|A.;g0Wⓧj"^W>R*=@ @}}5q.L+N< ,Ua_[W,ŖMqI &Epa G!Dg~3t؝'LLՆv[mݗ&gIiqIDG'{X.7Yh80ħlwd \v,'ap,|"i驔{Y+6HE;vv/gqR?e<6:>E^vل$keg%H~Q ^ux2p*Sиc#ށèi&9ŃhV%,FAnQzaIVV5 "*Z$B8iRYQ&N%8 ȌO&)nj,f{%19;Eې@GZ G 82shӴ[#bS36SwVSI$!b(ԭ-Gk6 FzrݤI5tw *E5Ŕf@h rTp=9\ utM81&ŞIQd|"mkT⒇ !*yf0*&&Q fhi "Ew&~sK71x`&.v Y+y4g?5|4|+tLTLs3z.b6֖ 6DJ@׭_Ăߧ?!d4G?9o~K/-D:dRSXh) !W4#Ѫ=p ݆ Mjm2m8[3aL S'Af {_G~ Gxn?.(!ۥ@,ړ@&Z" y$g+?y??:<2L&O4{KB [kβ8,XX\ ,Z@ JKe\5+-}k3sfc>X[Օ-vLfSr8lv| fFAF2q$!I1Ttnt):z nd>dEу^Ql& tj6m,,$BW5t1(uP`v0>d#*1L`;2r}qL2wu1(5dzf*n)n繯wӯ`oe/ڣucF%^}鉀Q*5@\=st6f$a5 HRLcS"Dp!5&$PE튗E1G절Q\Uնkz[ Ѣq ȟFk$M`i>Evr} Â'JʢAiDQMU;]O(G3Id2|vt6cF!-j}HXQʸ?&Fd܋zqnݶ}g2ș:Kє r ~!p3elUZ$S.Ov.=c<2&y|A֯]Ű[^pl:m]ul>񽏉tw?Wb߹癘~ݶGCT$Qo5[gw?0T]r FYWh6M7S]ӸUuiJf>g]x`d$Mo]g~O(8 ܇ic7i2tK:u#do0+[tɩ.LE kD(! RU¶LW&Hd ~AĐ 870-$炈lAyU~.J6){zbfe3ۜ<:pmD%;e~HF; # ۫ I84ًlZҶ6-vLaE#2N )ގ6uv Rm=\ࢡ,*{}Rp!3WXq/ h aUo@ #?ziEGQt^ahS8d2CSm7D׏lV _(Vg >@@A~8 13[K6t]]Rpc4HU ؇*ػ7y6=].-y)QƮZq>XmR2r,躎Xn=kB}lKmsg1frc&7l3;Y?_bQoF,tZ=Id))RN9n'_nCw&Q%lprL+{׆=[>9f>T}]΄ۿbS}alfrwp}/%[>w?Ϙcw^DQ5k |5KNNTU0H4G;Į} ɔ.8{2. 3etߵOP%S`1Μ 'IAmo<,L,SPX ]ic AS}j%k7v;< ~<6-PYYA$gdb$!;$wvWd|01E6DDBU1)B3AV?BѮf-n*`5S~G64 FpQ1 @0XES$ 3 ENF 2 'KpUB.҈|.B2 eQ1^ǤePm^/ C@ !=H#ٲ$G^)sH-9ΫQ=&4 ÷w"VgRlEu߷o0T8c21֘k4 ׇǧ h:. Q%glfOHv$pTW#]~1;g# bug]薛tPDQBLvgJ#E6ش<.}8p NK8| /.ð} \~r˫{m'5/$'X5w3ZildYwì[fW3f2Ϻ^CNr|f a2,d6z6wV`T6yExb ES lCMMsnqռCoFvaHJtD2d̘E @K&*bc3BQ~KhEHOE3nQ;z]޻.t<.J=3Zh'I*ȖPQw|KpǷ>ljhjUMmg눂dw"g0vIa"8Iĭ2iMJ >#Bfшk,Ri6A%GrWE|>_q1{ hV,^Sf!C4#sݬS}h5O'k/}?ɃOcw?8\U<3qť|\&a0 A`Gz***2nZ4̶_滢ZONd ! bjNvbJQnV@em0!(a|HrCУcᅽI.'A[͑LZ|[IXn޹ܨ*?9NsQc_/<)W_IDVv|%ҹch|[ V|: ,6rsm')g4~BpZ'd`̘#goUWҽ @$v%k4dcd>H#4RoNUU>Je$`ŝCfnib3Ph5ҦCG0%SoxW=_9_^F`$OR ȟ@]U/[#g)73=MND (#e$t6tdtcE&G2V'S aCx+Kjf!#ka<^m̼d2W([{\7I`{^{~53^rnyy9 m&-|YAn}2$n"1.All6ty[ {CMIܹ1hNX1i9TǕ=z+=z0TL@N~vxt2&52wfӯ"Hn+kw~x6C &s}y6'_rEף:m{,0*++|TUUQUU$IM#%=NH34 ESc@F8q:H`݉Wvl-mJK%ZUQK:`'&C"/][^yFzm$'Ue1A@ Q;ڰN0.eqE,JbW/6 !!Kк9mD`İN2Vذ-;T"b}/(Je-ڂVowdW$G.RRgdg!%UQ[p5Ɍ4(ͷTEoIDWC-fj NRjQB ce8QпzbCa[6]Nxuj:lٿGehdb?-{xw[㙒Hl`hts/d)@.`]p2ss17q*,]V5dmo'v狷B43gmbwaP;rcpUT̾!f_`_ @\u+W2c -b yfsy,z?B{|̾1&?þ^Aai09g[ԙyG賮+f\.kNeӰ -9Q0Y;=XfM(^t?d{ $.-d?`(Ru%Q۷o0*++ lҺmJaT%ǀц]qW<^ JMy++ӺN6UFKIq4MuꄢoH( I upE}YT0EX:z1\HZAcP%`2 䚡īZ~IM k*6n,QUK9XwE/>w$0юKL]O&ck MAj-~b?C,!C= -t<*{`c8/$Fy37yNSz3^F>xCɩ3?VRmK9 )< t _Vv+$grhADzv'g9= egđlηȺ;tYD,{J_NY+5츝``!@E2׋~@51vb| C}]QQC_cuʕ1հxwY+ϊy*7{Sw;j&R[sʙ#Cݺѫ_V%k Vǜ[c ؄L>|†LOw,r½hNG2Q||4[UD‡r%I77:Hom5$ ͅ$k*G7ǟ̵7[|Qt9؋X#TW{H-g_j~NWQe? bpԌј crr^.*£F5ohNVss%2 _t|[=àYX(QOſ2qTNH&:Fq8c8=U+WrFy- \p(S<8t2 q}w[(Ŏ$U& $edRW󐮽k A.)7S/^O%8Q~~3k.O5K'_&wypޱDw${OACd)gvɆVRoB4o@RױXȓhZ8!:#fW7Sw'sΝL"ѷէRn`2? |d UHdx(T2tUEUDP}8><5 )--QSSCYYvM6D R {ⲸIc ES I)@Qs(HyTVbEkݫ 0{ٯDKoXiL/X- Y2Sdddw^L9C&=Yf1M[.hmp᢮,SRScyҁŁO<3d}bL8BTk1O0M4C] /[D.$"2gJݠ ױjQWL͞UCo*jQ~fbL\9tz)6,DT+6C:H," I"K9I,zd[qo~gJ UT~Ē2`5/ŅsF;s`֗?ScΛRL.?7RX@Ǥ2)Q8*^uUkZ./~)qr^f^y˖Qz L:땎żc9>-f`9wԘx^'#}q 'O\.?PD/&ҳS-2,uO!@er_>+9ͪ~=6HDԿhTl0}Ȼ;ww^|>_=`JJJ hő++ITR4ʐ: k EF3mGW}mCs(?+ jkĂZFI$"HK&Lo%+E"&-y]B 4A-d5@Lsc5-&\ .Z;ZPXC2:%;8-QL:b ׫%3\=Dg8[9G[\- $uP4yU/:Y-??Б$;c4 %!"gIew=hCPȠKMW4-lO>Dl0 Y ;XNOlcʛȨӲxKU ^;l~ KV(IN1u4&%J4$`l(Bry\4 Tff dOi%=6ȱ4hAJQw/}Sƕk| FEzn9nzI,(P.Lk!Ёd]ii_{ҵ<}Rsl )>3eGlٍ9T?{;?_0TEmR쒄͠b%٨A!E!DAj7КJɧʔGt)ֽy K3HQqÉch3Bι-n}@mhpWD!  ljtC:bܯE8n2qhGcf׮]ٳ[Fq\-vD 3WnSIg0/:Zmv:M-jsSA!^$lK{ jolE˝dAb0RY)).D#Y)2XǨضִ͞!~QJcĘP! x"ĎZ"^U.ZZa(\$4t255҉9' &W}N8c,W:b&OycVS<0шTUFyo)Gض WQT:RuwUhTCSuB!`0vnD#10!E]EQTtMS39lQjSCsrvE ǽ-l{u[s: H?< /&,ϸ0~ZOVs99Ub7qC?OJGy{u4n9z&"t6!6Tn'??s/k:]dXR6àAw_8?Ftuovr[c.-X|uLj_!ե؈F"xped"v`'Þ9ė:3|[# &#wc,j9;<~[,vDNj6\v=57H2 9btٙ}Yɀ#3sぽX{jҦ<)%*9]n故٧^`gq1~T oau ফ#?|OƴkE+\ ?Dw.(#*7?)39zFuu5wf#99Ŏ`bMr5G]ll0 Z9ً9w:^ġitIdȸ"8ldabFY(Ă݈ވب,JfG"hTuH=Ap+AyVs A@u.(o Ȫ.3L/mIk7`=`԰gv00vD#wV]ҰAW v 0st8ݿ9wHiԁ1ZXpa6 81Ev;IepIdȸD& t%a%a|ʠHeP\H EE@N]j.õo_. 8R :AGl1mkATaT+nO}f0i*jFTr;\B%UCKcFXQϯb>Xftbb,sk:;H{ye( sVoPC5 `5Phr+"+9uUto%)Y $)}QWQ44<:fCX{4XdH12Pe @^ziًol0 9'I6QD<^w`GQ'ҋc'D$qIQdw# IDAT1)I r0c‰3|:'X=$,ߌѓ#ɒ( !;#WX6F]5 45ds3o1afr͍^GaG**E@@ L;z*n1g6v.WI?D^ JJIg~^|W?ŷ]ONse!BL; J͒\NTf&AK&嘾d?O;=Dz@kx^{6mOxcdS'v-tl@S2yم<NDQl -h0"!}BzeϞ=ر0B$%%՗H.ܙ=I+H?)pPQеWA_X]"M&%l::Rk`X!J"}@S̽r#Oq"٦%B+dL(CDIICD}D;[$څc5[{`ZڿG>þ}ؾ};>0Ձ`b%ՃiXhUAT$Z jkz+->@E;& 9x?wMKHۺ&n,\6HjRl6$,LSaiK-.TņE\D*ވXuP~QAģhU c XP!@Q3$Ȩl-1f("N(*P՘[kE݄4%*$.zc/GR8aJ'J8"{wyUҍ52jY!L?Ą Д\l"ltбuM״-n,B@b ,qK)4%Xĺ% >`}bÕ zO?ODJV=&w{VQŭWgg KJ~YTMʤQj6oF7Q+dQ{=躮#`4FY_umNh!ClCupl(tD9)en~\=S<:]|uwG=53*L}n*B$Aqt+y%Xȼ@Kx?G˦ v:Jh~1Gk._%db W W5.']z/S+ ƨqǰSN9\w$W-1pdن!ZC4{ 9esx\lj+v?=A&Υ^XQw3vDԷ/i$uxY'δ|sp%F]IԶmxݧ!h:hnil\1D m![dJMHj>3L /SsǦxo9U ?U%\a9& {(\Q)gAq:9Ő> Տn%`pT>Aߧ"TRUY0eJ<򑏙T&l_fGA%"MQK/y,C#E,XSaE@QKQM@g*JER\nq"]&3E&3pMoX(ZXZ6:-,oZoo.|q.cO0!%|?ލx%yFQ{ ƨN֮s]q$[s(XElY#w`꬏Tk30^LG+ z:9hO# Q.ǢE?jCS%33)󏻌ӲT-FLpV Z.գ=*t2{\җ8;%r>m]/aalڶ,UYK9bΘ6Ȯo5߮t7]zIGE]ǐݏXƒM" kwwjC#?}Vi ,xgx4!Ng_7 'PY֑2s]=~';̀PFqeDMj];ֳ<{ q A;uPAq_]θ2E+~a}$ewcܨX{wSNy+m]5-gwfJk4:Eӎ%V1옍߿_8h=`|>JJJغu+^CEE>͆@4ڐҲ$rLQ0" YlZ!ߍ@́EC]նbQnM$;!펵u"Ve4t,j+Ex/ *hEas7=b]:"y|US4NC,vֻ,8Q6u L 3+| N9-KsE#UDE[ma֩27㯊R\ tU{,!+׊s_-<3%O%Rtk TbAi#SxtQ<ŖGok{*/D |>&9móoPIJNjZ* *AE6?w%=1 H]K(nk&`62&5Ef . b`uWDb筪%={$"t BRkV~0fd%J\bC6[vtO_p쁛_@;\v<ғ|˜(җ:`n(Z^K'Jx_y1hi5]dN=s"H%OswY'| TED#hl~LBAuG`"oJ) \>6F׌ӘhoFʻvb̛/]=uڽ+˲Tе*v_şCIr`\ک 3< fI+̹lt/ӺbeDowTNhG ^m5P$`4Ww[_՜{ѷ Pg3[wANfZ 4;-Z5U! a[Do0>sMwr੝7I|֭_a¹~W/`ڱײ0mRn$ H͊"*,zc_Տf}N?.eK1(#PUQE_-AEFr\9%Æ)>4:'utv^u.fu͋XJ3 }i乭߰LA~v{`DS&'SP$#OMMM=`uV<*^/Ձ`"ew&9;Cc PT \?`O.j\n[d\ooyԁ췰@99Q43;FY:FYE2\1pERuwnQfcʢT-xӈ d6U6'"QbFzuTmEkZ0y[4:N(V@r d$Kɖ(Ҹh=UVG(*%n:T`&# ^J$M~YPlUJJÔ˪aB2hpDG5D]%Eu 5TU%X0h[=Th`!mE^yG O8L D%n'tRםAV/Tʗ^5\q[-UQAl<&Ħ`9F:S_gAftPQi ?]&meD Xx{Nhv ]c݊RjB-ɮ=Af2CR ߱Z9W_޷SԣݬxM<;@P7$8$V =}+"QrrdX]@U{ 0"kyocqI tv-,{7lu0eY&#;߇LŐ)-:#]Ȼ3'leZTN¨m{)/ Z:Cȏ'&\,$/-cv  G.ItC׻夓&ɘXB/z1>0 '߈/j!#Sf#y׾ɴӮ7gS]!쩤&h[Q g[u8 %$ŋChd`ΠNsc9zֱ dK'DMQ4Xe9 dQ[7#Mhfz[buc[q:\wH,&ZwvӒ4zZ^Hr_RLg.6cX(n{Y#i!H(ѴPgRNEbVD|Y$DC{gWYsnok23B!H UT₮kòb_ˮ],XXEEQ@!B d2Lf2ǹS33v™Ws9y|ʗb qlUd%Q-"+S}IqB=h>H A}t9Z ]Q(H4ʽGk@vh 6j-ʃjimA&{K'Q1WXz"ST8 ~A@P _Y$x _z$e#?o7ɇ aQضB IŖ#64i bl^!uՙB26_S%H\4] vPK麸6Nju\\So@-os@Oz2H;9\)Kp |muخNwvsxԺ/0I(X Pʀ ZwP)\ B!IMy X֗E>=`1|3o{R(Dt!m1}bF]8a!xi,LEEDLPW^7w]\l_4Y?o|_=|.cSY夊:VϞç.5?Ij?Qy^QjD+ -l DGoϒD>Xś`+J/"VHpBs)uA@8ضK6 t'\l2R*GY.R,*BJgYʋ&sl[ޟ}&+>.=|t rMxʱlQ@rM' 5n<{JxE0$.׆EhEyT# ,,ld>}kM1h@Ѓ :>#U` LOp;O&,2='X7<9E+c; @BoXcc,:G'T V dx ^G?ӛ:c9uZi"Pbe˗yY>'_-Rɲ~|iH~\O]ő IdAСKWоL@:8j 駷 24cQ?#ʆ/~|{]_L:#0u>]Q?s7|DGV7Vqw{yWꓮsU_ͼg@~1όW$^^Ab v!-C>{wW *K# ZVN]ce [I,^4r|&Dri3\vt!0F_+(:@tS{m WINE.%8sy|lU4Uaر@0at "i M)t+_`&EA(oe IDAT9XYtiUAm9ؚ²<$;6X3O)4kK%.Q `Ų" v,5Y`t}mtWC4ݫ=v͊3:Ҫ*+&fGO 5i$4G0uc1t24p,\5bplr]PuP RC&(/Ը]R|S>R53(7  -T7~Y,h0NrzЇ(!_('vmGjm_JYI਄@*wU<|QpiHj7cV#y1qPP.]y!qTh>aY4>&-VMU>JO“/xjf,7[mgwqσ ?N^hr>O8]9ӯu\n>{&>^͆ z^\o,]4t1+>/LϏsػn|Whnem|pM#OZAuOox}],]D/ Emλ+kyt]ؼy"_w]o|-ŶtuӑՙtBC įi(=pObԒ%I F+N6x~X,Iݗ% ǧ~޻O. q/ϻ$IV`-)J^*{1DDԀ.ƘKQAc## Q|؈J\,. #\,xI)rXt-viEۈz*Z4uw"ҕ6ϻK\G)qVY/kCdL3cqŁZg8pؽޔ⼓)6u:7xc\q җ?K\] T{@V^..RtXd4~9cWɻhŵT615?i;y+6\YlEEBgEM[-_wl+Bſ>gC$~F9gA E~v&77)vsr})ΘY |!Iuc,ZjuZF $^%ǐB !% R.q͋mY?\O=)#t</p 1hV0DI IG.)4GRB{KQ^iI_ӾǢs.@)wJ`\)H4ϣE0N40 ɟXOі,]R/tq$=Hlxg#5|м$.=y5)Üu¬n⟵L2Ɂmx=\"`0H_@SFutC0JC_"_Cʡ\gENoC^N!П4ݺ,}/ Rw9xf9A𨩰??ⓢ4͠=lJ) tt'_o*B|rDXR[}:5 /1j㈣\N g =#EA3\ ɢ/'` "Y.+Ik"IkmM |W4TIO(" oXpabSŁX!Ɨ;wcQAIڇrQ(ƱM,ӤXȓ˦az0ELqJlC!l{l`/&W(p8G4_K 0^+*9lڼ7}|Nѳxa_='7K$1qs60x;qxUd>cb5t]N.vC6yvw/n*V_8z!/٤Ԇ̈cx z?zNKd-o\γ>wO/G>ϛ/'t ZqםQb)ZGM:\#} h5kyCQT"~6d kFM\upKXǸ4<ɢj9օYTšMO1 |e̛Oo$ʳ5g 1tIj ͶXl.oԕ2,iѴY 6J 4Q5o\t ey!D'FAUm#W^{)}|qA::-/IwϜx9PZ_7}FnKf5rQ#@-xR Lߕe2eX0pp9RT4,wZl9Ph8^KMgZX4&suБv0 e^m)cSŋ&ӥ . PDzqO8nc ُL݆!AM‹ /ϿL#^X;-\Hz8o\ȗ.? d*E(\'[)j"B tvtށ ]V 7ęuW@Sбk'ɵE~zqo`.:8KWɦ; dL[!ׁ[ikOq \`ʝ}0CqJYB $| `!C)LU %F-J8ezLE6"=0@j I:$N, !$>P$J4^F4^dh5a|h4B|.֍O:ݲu9oa=\7(c,8.L@nyEL!*cx,_/|vi=lbwsƅ3ir`w3 D,<Aymz%)}h2`iD"~>1qR\~uū+ba0JLS^)՗_Q<ܝڷ .6t“jG 0_w:J7K`alo'\Fua %h:sӮ\HӺyp97G9+8r} hvRsN'ώCfl|o+Yg?ã:hLo`tu짯3%!|AfˆM(-3OXCc0VF(. K7ĭ\p'eCz[YEEVM]y;[]O<&\QK!e2-sә~ԢFB2F*G5."I޺&n}tloQ(ycPaK )vO 7jeH$ɷS#ϱbEh׭}6~"˾Gó9Lo OwIEDBjm`bTԓ4Txq*c-lcu(?fD ǖٖs5 ц>g8r0|6K#W5Sp^ǥ`u:gn9 +|%~Paׁ" 6R4]DpS4e@KK$RK۴,,i;.p>,Zg${m傍y7Tp~][ލ=wKQ?mRҼ}Q=%ԥPcX1,%C $'l 2XRk0nh)IB~7jDŽ#>DBQB1>c1T(kᖤPv X9TTLB!m;H G+k˜D9X@0G 4]CH`SIz$*pK=|\5t]SKl/~H}R Z<nD˘Wd H;\Jd,M?|{8D|;kYPB!L/+z}<chSc}=}g<ΎLk!Xm|Y= !V"QC`%Zbbxiӹ#ټ]Y̕5vu1JjfS^zM.#gak|=CEMʚ+q|D4 /D=Eϳr{dlR yd*])Mp޻+_mO.M&9G;9TGIln<ak/d 䩍$Ӣ'0mkCbhzTh ^,=vd鞏KmfwnG_޴:H5Dt (NNy/{C1N0XZ0|D+K3,f 1h,++õ:dОu֙+P i?hbP,{ \ C(g_F KǒM\Lu|ԄCIՋP&']ۓe1l/UqrF>unfD\:K&l])l<|ks H+zx`ͪ9-{c̲5egq#)S/i ߝ摭9=B ;>DMdUFBze D:͵:3<9TsNCNETL,ܑ gX[ J238;¦ d,I-IsT1[Q,ȤȤ<Tjt*E.,KQ>(xxYJjDt!JB /ӪcK쌦Si>Or|$DFc$h>::B #H,̡˜kWK ~7mm"qb c&gO;luD8[uJRtr ,9{$w޵7ἳ% !r0ၲ࣯+Qqv~kZΩV4w$K>R7=TG?;wXx+̉Z8j)m| 6^VU[7 ݸz!8B.?T:wy_O!qsh`!'0,=])2>^ܱMo^uL –ٱ0uٷT*G,J!4-T?&!Oѳw3wlG3HMo~=`} q=t73QuyT>ĖsϹg.&|6+ ‘0Iݵhr ;»>.b[6=\-X5LJ/X|y5#"/Hǥ߂Es\S64ﲘ_!(ҟҰXsr%5+ikXB{6CgսG/(.ټ0A͹W0&PS4=E=0E$Q qI4(G=wqӑc s*dAq0;bL.Q SLe7&c^g2IOܫgRI!m,ξB6`7M-04 >DW qq@غH]]Lwkh(}6+(hK; $|\Hv-~0a4{ǯuP6,(JT̬@Fc F QUH%@(-,YRZ}d@ e0qqI,2J%Ko7>@0FYB4  MӑD9TRտ)* I,7^9gŏsn\k@&zhA$$n!@nǎLiȀOx |S1ud_z*g'ΌjcKWإfYxQ3鉞ʦ`=( ]2=CZ۝xÍ+|K5\<Ǡ211D4:`S-[WS3I񎽿єIsn_W\Ptv{ nJ=EAc^Y=& PH} {P r"Ă.A7|e+H394R¥ +a󎷿4I(RFKY]|To7i-,ȀCG IDATO/̊Z*)<ŋS}=<,MвYȴŔzܡ=]Fr:~wߣ4GxC𶍄NOK' 'p;|;F$jYveg/cfpVut?l';`-+ΌQsWɌ!DѢ bDwtb͑{zC\&-Ȯ,{jbwm\掭y2c EtyaO}vt{lm9H(`6 waLI<,-רM ʽXȓ˜bb3sQɢ' 5KT \C )=-5Yw{BB]L;w!S=Oz}~摭 <]쾝$3FtGFY4e 7rvI?ze=@ |^L=>;Mn E6m`c668/YݙRt.u ,@M}C XE|_kٻ{,y,ai&ov1#O'vub%* Bxloː oM1/&Xz԰aiĘ\H5RN9 O$+4]IO׽|/sa-6S?^ko g}>I2>?uVV4,?PHhdb"]2\|2[Gū˻"$ɐ Zgf5=XD-G܋/-M 4 u8h4a\w%0tmX/Kвx {o'uTo0pqd ewnU+2DhbX E}h'@= _0\H\9vvtҗ(ᔀ_K={Zы'S3vN;IC  Fgf,f4VT%IdR(m JD"/d (Z"e<6v?hA`ac#GG=GII?޶,e)nd/4uc, >#?Zmҥ1aIm$ 8fT#)U4UEk)H#L0^ۤ{+O M|]'wl/:ң!f/ ͨ"_kgX8{̏ =i *o/~rN_C׼N訑jjC>L 8,=^,JNw%O\ufL g'S_W[X30o5𙚣//~cW%,z+]smmieH"h7 u˙Ubk*#ƘVY0HʵyPEp*iZ|Z_2# hQ QeXb.;سD1Nj^KZ2g,/gc/pc)Evy5@,Y6H0̲`}[tY^!g9Dv0=ؓ'SÅ^f{mLw!E)P/TKNH5"h\\9\ D|b~2p1Uk,k 6Bg&]!P`*E(3$ |ئ;~'(ձBO ik1.CHGP=JFz@Lw6¶lP^Ga)eko-Ȫ4Fv6pky^rGC,"u1I$8 ,\MU ][r_@G8X"F =IZK2dn!C"G裏 Ȓ /e=)pL R C[2C\?_y_g|~%w!m}9яB1;gx5j+q(˥hڔUG@*xFjLky.r!eHY2M4 -HPTeMLYOk.kۛfxLh<x3QH4fsp~Uw_Š}MP_M'ugoφ k0ipngF>}ۨ{% 1BI(8ZJe3UT_.lt ]ҔL[3 d@j WVص{/uͭ\|y iL4SSSUR.U;w-,?xȁ~lL<̡=H6u%F 2!LܕJ*KQ\FM \&z (E%ò(Ӗ .&_͞=;He:v:sCOaa o4$;v٧i\OxvsмʵP_'%T`Ke-اcל =]FmE0{E!f}hg Fc w =`!7N}O߀ozId8^SFƜq+7:MԷ ww '0lj: JbBjØb#B XS?wJ ?}I6l¼0kRT;)KHkMKj--uy[f;5g|R1PtdYr$Y{Wφ۾?&ra{+._` (5 O2xӥ2 ~ ][ 'vmvu7\j=>"RM13pH~SDKDZ!ر[vl* *_X!IC7 B~,~[P_OMo%OGDLbi⬢a:;0(5#T}qKƋ( LЬ<*iTƇًJʘ$3`LVT >*A\#.ӻG,5nѪ3(<-(aK{i:5}6k)pV㡯!8C2gSc?ϳͬU`tv$`)4cxF/5wˆzIu4q'cxXRz$’xP~C/5G['c7w}"! @L襗~IHrg 1^$ФVb NdrǍ;Lc/]Gk|tur{qZ!>?Y?|7_a罙?Y.i󨔋Y, )DZqmױ1I- bDbbp6_p l`!5t@54M?qDlʲNxc㤪mz`.MDA,(jFK41[c$ĮDƮE@TKަr~{ٙ-yy>O0qr}*r4,DOM [áǛ@<7_Zύ/_@"Vv6h7TYшP qY8' _3E]^#8iPfv)_iw&e"ן2_s$Z#ϕ/[ hI†MРQp=pJNGeIhmiFH./80`<; .쀛߾ /I`Y=!~/‰<%y%qHI\=^]Lx%r/1oR2rw, IPմ>9%6S$fQ)8hNM0RpBb`7F¡vuK|vT~rhiUf ځE2iƔI˴u0B.qqie{CfhĦ:D6\WؕHrvƒ(Sp,ېFS'CrdZt0Ip$9)M9A.{'iDZDʢvO؝(G-VMAIBLD"#:*} @@[>Bn`%MLK FQdpj6[J6(eGʦu WXtY򚥑+z+ZbJfg|uܧrx% ~ r3xwi].fos!@g\cfSgDCKv )c˲,LE'%+еLs/*6;4;SL g`Y5uUoׂd3?y oR:5/jwPr1q@.pMfYˇ{TʐITSaqqNb}$ZC[Xa֌b;79^T&v4<ΞAӺB-kRy1*WٺUؓ)R̬ŶaSoe6q.gɨMPЉ_4^>Ft&]`N0<* =L; /wBѰs1r/xbN<cσ~φu,wʹ l(TO.t-۫ʕGhPe ]X=`*1\[!3{m ۻ}=h)H;;31MX: ɔ)d:$SB CoXD4Pe-bΡtW`ܝM,nغ?րxެ>(2aLa>wp9d\Y'$J4XokG,@z3w޿n\I#zos绛Ȝ0+u FDž%di&B t'^3nL<@-lo@t;_XEqc}Fs2vD_Y8^f\:?y,UhrL>D2܋{roL5>~  3yh2pr L]*$["|8=iͬ䒟 ߐPaȴA0:ܹe[[?݅uֹ}K?Fпxc */=$dI`)طV6W0CKAOů~8sCA6%sX!6M5س\;%-#$MČ"@72n6VկPMjQ}.ޱ:|;Y) z|kw}~h..Y.cy~yWΠ~\tu@@pq0ehҜ@spqH8$AsBs &ʑd4P”lI*)&\'GWlْ"ј68m [FvX(M +?N& ēN\So UHDGW:iA*nb ٴݵ":ň<&o`=XO,Ve[c> rʉi l|1Nj_Nb)78<4lP~8 < 2z` p0p^ f 3 lH14 D|bjHYg{"#)ŗ5UPPsl#I]&QYXL% usk`I|Y>Ouu yC2]_Svl":bS&jv#.䙽A,_afrm_*')sCYYv;k{qIeIqAuT2B'N7{7{?z#τvt@47FYǗs(=C7mX]S ²Ȥ'J]ޤ=#){^^`?i*sc;>|cpޯzޯ|kX/È$GSr<a>7!O.-$px&C\~z",^8R GO7v/%q4>sm['NH4-.%Qt>{GY>| >8w'"/p1<}pc6ya6)/ͼr'WQ8ZVG(7\.nUG'n S>QSZT"VT-5W .}<>%83@ N) ;pOjKg &C8_"Q (8Q8sJoNQ^ImA%G8 {ѵ%%Qӻ HůC]gv2iV?2'/iy<]82<\ԭ#9а03#KG 'W֦-$0y:]t2&s t&QV:f LDEŧ^)@lF{8gShIXXۜuL4i2`DdAɑe A="$.\`% UBaj Q]LTY M14v!dH$L7E$>86Xd23#bT,I0(t  vԙ[f1%IlԜf#̘C6xwM'^-Sݝb ۷Jn4@)ɋ$poj :ľb?fcۀJ*6Ȃ Wt̤6x2MOmY~=%CHҾR |0yH\8{G,b@7@A'dEEd$PFڍpdz7}Zdm'O.&]NEkn$!#z屜}xGMFA^.wk<04PQÇeKIId>C¯ʺS)X}S͸1R&Q&03;]x*Pra4p<;72vp狙Ia%)w0;>`sFgCC'HZlÖZv6 q1sT|Mt{YCJs<51׉`]o|ҐYfuqӁNeYRԁ=tM!h[ArΝ)f).sp|3H:pզxb q ~*h%- 'x(73-nXYF2[S4 3,i2\Ce$ .X>ɰsex*Ey/7݂)2#Ϸ8I1So-j!'%:wĸ <[$R))Gu퉃pJYI(3rKREaP2aBQXmOjY0"˟qm %Qr ONimmt&rG8R%>zZVv9/Y.^.|Иe=.W,r‰ R1?ˀtN- OQ}?kWãϩӉjo]5sZ>Yc.]\!=_??pYS>>Bd(Uo{ t=tLDXF׈D7Y?/H߾-\QI{E]@W>3g&* (쓃G̲-M]aNWXnD(#X,Rʸ#8|dEUpY)nO\k=oUlI)5|.ά`{Φgbvq8 T"d)40394/>9?2<0gfJ|-,\ CnQ>P.y^d$KN3\&;/!.r˲ $( q_(#=d+q~7$8Aϲ ,Pù%8ۅlj\9XVo?(jl"\9PQi x~G ?u{Q]0<>NH_?GL֤dmb{x9~+.[W"u 2=9Orssٱc]uEbZ? ]Kl,Ǯ'B $C[Ȣq WatLSj٫pn$,C1ea H&M-{l Kb >$2eJTHrİB5iF%<\E6 I YXd]%XTGGA2 VnH2(3i&D:U^ۄӄ ֚2N˩ I2^}| }UdC^<~ Χ<~\ yAO(u= .ܾ!٥B @q*}| كF&u6fJK)(( f3d۷a&jZj8zt?XHMu Ts W*`֬xR),IA!?0[A7W ;﹋" F#5coNraId:?LrKjk@>QM܉\z[W׳ﱮpg}ʄanSN8]׻0:a( 0֗ >> ?%y֑% [xT>F>SqفĮdWa Wz&W ,iEV&ϬsdAOG'}\~D{"9,N j]M iVi&5<ŸkV%$| W؋ЫwUVsfΫ/342<>'?;LŪFӓ< Vakddqƞv&cIĿz.d^zC^yd{쒿.k/~u"< K XlN>uܤі l)aPw C+ 6nFHzs|+p>g5L:DgG-?[MG/Tp .mP?7,MU 8T4n7_?5d셯On7tYQeDZ`dLd=Rg n &s8C- 2bXt0 ϯLj/ 2iA҂EA \E' I%kR,|.M< Wj60t Xݚy)F1¢e&ے#F8]f64qmHe$`XLjaYbNY8e 3m)]lD&~K` vgHY&żUД00[tVXvfٱ^М 칫Qۆ2M:ԁm"nK!/M Ȅ aLQJaH!U/P6"3 n-u7󱱉PEA q#NYk%::ImN#/ 7S="S xePEp.z.Kn:ݔq9RW:̪]̽Ժ|e<6\=Wh_TPe9@=΂g__N ֎ IUKG컈=k)Neyy!&Z k70Dzp_ =~B4o-Xû[5.7_"3?};+-<<]Ϛ^Fm#H9dzT"prtT-6-ۍ(9|b)OC$х/ef8B]+:C1 .脍ZF4RAڕW)ON:Q2;v n[FWdt0E3xCGqN$uZ" %မ#4dFklĩ .&Cd$Y%,t֣B;$2M:Q:'K(e!1!; r~ ]ZV咓#fz?GanVƤ6X-AK ֤B-v߄7!3hcL˳(1C@}{`ѝ@{1^Ly[~-aW*so۳o$TeU0 U°vKi!M7Ӥ7[TKCVOO ?UL<U9 2yY̰uBg~_{T%nO~Ba̹SK>z7R1j^:fnz iˤeimS"/9h- [n...ʎ?+9ĀtXET *-D"FhKieFRT@%YF8.\nnsrɤ=! GOJX}RnO`9B~Lڇc9i'#Wp…9>,\Yn•}pӹ(΂wbe G sȲDd_PݶǞ>T9~zvVi5e!/${NCP;N't#u8Z),x̹?tYb̓hI$k%2 M2EӯGi᛼<<K .̚y u22 Ѽu+WPx;GߞBjA1}AE<䪫h̙a~>VVm?JIGEUTM? ݉ 40C(( j _da1,|TtQ*Ymq8SJRD7fxbaPR%1v'{Q-"q 0uS+S)xKhfB >OL,6H>`XB`8"2I/-֒5b殀QkZymutFZ;*`N؁Åg9>\\S򏕌wh-?⎻q<U%jlXo W224m֛ 8#VshqJ^%JӶ:҃屻C>z ?但l.a w=oĎT.v!g_M9`~!v|Zq*vvwѧ3;"=ʈG1 Wy`޼t=)ar[y|6'MYGqN^λW'5(whspf*P>V'eɝ>X޲fBPk`a m[܌[i IDATA$S ܂bX`)%La!Ar}Ҝ0NR1tS؏QC8]Zn>7oaug/ !,Z$bQt=8N<^@`(`8pP5؀"MeeL !,tc[5a=__"u~Sgpyُx>lj}huĶ i LHJi.Zwq8gi =}fq:) Nz:c#wr˳.l^z9T1vz/ = L-ũ9gь+%pه(^՞: Z0C'#vWALy.gvHi%]~58*93NX~;y0MWZCNdQ|#f?Au_TeH0M$!(eTi#\t7!`XUXkN9MFIH\DpT-~VAKZ&Y}X6w.}q`wm30#֬fGPe&iˀ躎۳%RDQteZ$*&U:$0 # !X*f .#He,rU aXȆ1ɸHD<a6fV!'amMJA(t VQ70,AkC Whmΰ@INX^\l LISun{ CSl`Q-A` C[ T'`AcaY4tL]ON&I%SvPz>ÅFL2?'[Ȋ(ȲlU u$qŸ"T~Iz:]1x+A ?TpxuTE"P!>u4 d TӲgҭI+/T IX(ADss3( ;ROOXv W#(G [̐J)hR)nru2>d3N]z=%RMdHg&nt0 1i@',Nb"͍6KPGsc=&bVe*.?@ &%a`P|.Usإe j-KV>:d yzt7ϕ:p.XJg9мg7u|Kpqaj[J(>-5`RH]0nw#/޽GÆE5 ǒ$dI7s{RjiTޒӔé/PRUD{n|;Rc%gž+o6,߫HX۹q)>7\s+yhK3p?u)GeS:4w!D{ !:|xhS_Ps{y:QrCXؕ}BIR>&`^m@ii8N4FF1ev6 ,"+7%!i!10LӠH>'ºmIvZޙAn.:_bcΞQ!~p>hyQPxuIAfY T]7Qz$g44Twj2'pwJ'm29> P RY  ]3z="JL6ED3躎$8nN ,N9<nӍp9h9eY#t`($ɀD$dM<' |\#c}lܸ!tP@gP@ٷ@GUŽ|n=X=c:.<>?@`f)JX9ׇBQvm)OVPX؆{~rNw!]ّ*i ,0g_u @nS 77w&ɴ%+} TrșZDpMb@w?W>FWƼ ٧ N#~q\%%Pȳ;aF2,~lܞ`ȸ>V?Ŵ!ۅ#7V4M@M¼tFO %\9"e᯸}~# Sn`s{x:31KCt~4t~ܷh&g_~+#dMcxEl.~v)_%ko&>n e q'/ ?Ma¹] 6yG_bth!E7:;>F?#r}Eoh}cReԄQ:Һe~~>;Z# 6Pi1\.T K IG-!xmlG5MVANi)wpꍴMJåjq҆m9lyV6P ;fF05rGͳ@7n(Ǎɮ000/ T'`(O -$8ŀ I:m@-N [Wu6,uTXWdDڒ̩ 1b&OV%O"vtG01Ӫњ i*/K$?ɧiav;H%2 z h* /f2o7>N"x4gNŤCOT:IBzQ%PA.%f>-oI JuLg V΋14n{GDq YU/ny ]qGDӆM1.YG̡Pj`]GpSy8UKX ײ7sޣɳ w#mMф3o~ 1N:[!r맸|uRMc\m)[3FKHTwICم&~"AW b@ŷRk)هx} 9X,D+gJT%lp0 T ThB#)De X$$I)I\b$H4 !$E  "DH`9ȼNKs#bL_Ȳ$HM6S!P~1Fnn465ő%CeEFJvL1 ;+-&ٸ7z;Pt%!Gp4%YD#a SRxfpOlH~i ?$OX\r!!3,lw[Y_&& nÍXB0~Ï2\(Q202@{CP^$Pf7{"M* DF:;Ģ!I2LJP^TA 'ǒ#e9!I8Y 4 x9$Y㒺 >X }g+zK3zszSڎDHr:9n 4"4w Ii8}0vprYC(/)a VKwS̾nnA_1*s( MoM?1'ptY%9r.e7Y P[0 P20I&q"MCb@vg9.kBhË,k<Y:`-Z_I2.wV4GW|ɥռ^BnD>޲;'KgDz7`4~2yj+ʬlm`뚗xgpђie#FxI{y7g, X]30K0 0Mtv22.`a0]?%A¥ BK hW$%9Ȗub!BZ7c!rdHeEJЈ'L8.ĉN4i44TTJD i;dZJ+L~Q%@.( :ڑ#xw,Td֥l0a`,k_:)EDl"$ʡ?NYQȬ!+zAq3取! ?!94|b<)BTLAx>O uM=}VltR>_OQ\Ԗ͡6uo)O` 1Qu vXKx6)yM}6M seKx݇٨[ xIN!~OnKm1Q'_ y퍷&O!t W=s;?"/aGވ"YrB!_&O:\ !`~qgs1GP98a@"*& { wUK  B–͵@;*$\Ncfu.tX *)'I1bU HiĈ&L(q#L8 .1H+ aXL"ƄנSfضljC7N`/ CVPNӉahH]**;p[WBCfj J8 .;K}+_r8zr֟j. t"9]H"hd;g]f2ͫ&qK:KGJ. I04r8JL.Ȕ)Sq8v#i"-t Ɖ3Rx`) .{r܆) Txu/Ãj(dJ Tt8J ~?uORc3YRCZi­t2A"' %ODa0XT*Ӆ  /*Z$gJ"(.33CVb8^w=]uTR6Z?L$UIH(E !)*F ^Re~u1ǕfLN'l&Oo"}G! )ఓn?'TW)GxHܷz#+bL.NM[`I6澺5v>I8]Qx6b3s@D;,,i/JO6ECe|}3H\S,FLcoF0Rqda]f,]rH$ Vv'(EE basI)IJNuF  -ҤH%J01b.` TtՙCG'EdRĀ[VM:rok[z,;{s{ Lǟ&q{$j\6\0 R׺X?+YQQN^~TN; A TՁ,LTOҡIʔ -AyRND=H9 M.y!g{%RS@.Áӡ"IT<^FYfpHOEEgKyٔ f<\gٓ=˞zVPLE601It ـBBBv~NMJRS$,; KLUJz4iJRm;Vh}GW:]2 ^?ˁ,+HBx}@2,H2䆛nf֭\Epؔv}N \Jx’V9HŝCӛC3/AX_X4IH?14Ԝn%Q:YyGHsgֱ5ip'O]|fT/B8:yOr[ߡ3/B/^;58vCXK,UNɅD oz^p~h.C"`ȴy)d?Pz (  NKv, *$DWWiTd`&}>c XuDLdVyhz#ip#N@d7qQQ.$-BOƤ,r IDATH TH@$Us{y]݌, @7J!EEEp1c&aNA'.TԆ4 # d SZ@sx_{l<Q(zQǒ/JdX s502T]",`BDH@"_]@=I(Q:jS9˻H$L֭+LK5wdIU_q˟w>LGG'K<ˀ-Ȭ-2@1 #d 8?hǤ0%."+j )*aH1~\;cmD/^=a᣺p]EjId{rձ/uT~0s(. sӞ"BN{[M3jiWn-FK]<'9)v^UrԹrH&m]|U0ky<~FyG3X|.Ufہ0pZe"I=šNY 1 S;ayFx = . //o7ZP;550̀ 6mΔUb-{8kv@JHyۃodOfCy! FNj0 Dhi4]L[x(фޫ8Rp^_&uWR)L5ٳgSSS|uP@6>˞|RK1)FT (n@Z"6mN;t%:S8C@N~e&Ya-2E t&MHiI B@2غxXg#RQS`:z"JRoSKJ|*@e^㎭+'N_x}ikӕ7Yt- Y,Zu/=sOIɗB;P*`~q9;zzz& o, Y%fƜ΍S}_#'(^WVpU,=p\ 'L~:f,:ǀF`0x&_X%X̀ I"K&+j/Kk͕VƢY0?B[ ; L8 ݧ!CH> L,YH` @F1}^O!s)a47먭嘹%2N5!/9ӹ/t#7@HKDII ,`ԩձsN$I"''b |`IG)FZJDU ("9h@!B'tAAt!B>X_> $ch=WIchnWB i2~8&Oi01t -Y_ΖB)+ovt!D̷dzauM3ei5ؒw0t C6?|8׷{:_9اSBM#e&^2Dv(41q򛇎0Ma8eXw\u/FuNo0#qWpO| :"bW0pK=ۖ^~qÇR}lۖ?u9mх=p{ %#pΙ'rCu0>8~\.ʞN 6 :eg-=FAWtXͭb?m5&< Ϻ^JS@%0X LHJlyPPT3C6@OB8/yв 4[X(@KN2%kE Ġa' ) VúВ[j:lsЉƢl0YCrsXяSc@Wy-P9esȬEşY$n[{< BEEgpeI4;;3b { (ىlb_=8Kk9c[ uTu~uIYЃ7% W6k~v3gN YkaҩjnXsdlA;XnJ&Di>@}CWM460m~l3nNgG_ tv 0ٔ$e TׂkP-J%~(t8b UCܙ?{LZPP#:V"uUZ[ε7)#Z9T^Te9pȖ=In"tRxīB쭥ύ<,aԭ㹧`wHK/+odm 8~bJOrы>~.|9Pzx(it88xt1 ]\C#(3Mvhl!ģx:aU,s}>juC?j@x8 !p$pHDԎNM@ѻ@M52*잊b^>gⓗo|;^`\ h=d~]79s<_O!U- ,,n\O~;i*efIb+e 14H'3L#靛%KN2'WaHN Úx>HQGeU5O!p/+= *I'-KM#xUs9R~!RNr(#\.dTbWJ'2% :9tTGɫ9~&; _CyDŽϭA^N&y +9Ί˃L –r"ʪo_m5S&)o|k]^@9据K'CWYq]!߻so/O漣C/"Wo?MYy>/U}_? L#1kd]!iju>x ND@D?'E?{ah ){/I$Z~CwɶmhRTRHha}x+6fUc:O1 ս (eStq`VǷ6 I1,l`2ෟÄC((ȊY,Cˡ*>h 5ë(|GCTRChi3pp904Tr!8 0~:-ەl3 2|mm;o@fL~ Xɴ(ŀgvϮ{xֳi@N楲yB9,xK(,, q㣷sxkPOI#F5,:}!ɛoD,aȲʥXfkTwܷ!CЇ7P@yt EUqz2CEuȖl #$dɂnb\c15^RdDr= vsϞXmv C`d)YXdI{F`bnӱ]n\VphN^H>ӊ|ĩ @Ia-pVW hЪ2,7o͔er5&~=dO)h5 %G]OUcWn@[ L\(B7RǡqEXIkkBo57ݫq!yYtC8+r\5Ͽ·|?[ @{6댨B:2qDA\+ӠO31Dž%839z|Πe?@}$Qʖ0;Xp\Ȳ" !pHgm IcS#+ë Sʰi$֧̘1lqW@}MSPWzoNhS2+dSƉ$a12O-+ ,~Oɩ_@K4PD 'o(``d8P ü0o<$K$~fwF!ge aXDNA$(RVYDcQT 02Akܒ)'5ح}gy|1}uW}̀'1LRaMyfRR/|=O><Qݽn}**+Tp*c1[G"PX;m (ss -!+Z5-.lxkoPvP{bFKI Uze% =k}bjڧ,O "/q KH|L9Dh'ͭ➻Ox¹b_MڭE<|щV1?o& r qJ9)-pw MYcg&VB5dʬEϏP=@C+܌-0'Er/ʶ9ccygC cn|bk:jwF}l)23B}nF ?s"_\v9wA>]eX``YT*͊+Y1j ގć6Mncx,9vl^~yZs~9Vڊ'yǹ\fe,dN^{ow77Jb]r`8-jmdF蚆a(N:v)pI0u2|0&oߺB 80d 8(p+*1X?A| vO$ J0?!QMKgJAE/z(Y"a3  Ē:/pf&~q`5:!8c7d(3{YydgC@Zб]%Ъ4[ش1c?KwngPRXgYk^,:&d ô lv 5"4 ]I%\f1)aX\O_:sھaڅ;b. 5'`>[{+3~v4w,fBɩ`b&93X\gsu?cmW!h?[N:`]f:ΎI}2L"a(i]/JmZ#m,m&.,c⌱<"뀙A1YX;-q!xYn RJBm++ָ0S\ge!^;#N:OC:{tv3VaOƓk~"Jr{d±: G$$‰-v5?Ï>dhJ7iݻoO.cêy{ZrvFHo#i -@7L^&f) 2P70.;x+xZ$$+SItM .g6|̅#OKGj3M4-mՔ"Ji4-mHT=>K.Z߫䱙lä,S! ' =բ`.F jf{T0~0* Rw(HdHBFU4MǴ3Dv r14c ޗ>_f/]ۈ@P !̸L[2c$Q̫[W1*jqFQC }7ųNe{5&w|m%xpyASi͆Uk]p n4{/.|KzQȬcv 6(gmq+Db:]k _Nks[.U ?wjMfNVS(Z?{~v0N.>Ũ=T0r[Osʒ(/+'FYqOX <>N9vIy 0^C%w}7*C/?8;3>ًX,ܾ|2`Әͼ*fdqMH>Yx#2O8~6j$d @?\_2}rx揿bg .V[>ZwF)u+Y-t~X~Ao߲yg.Qɦ-[bi:i>#i㑝G-wg0tNnF{Ŷ~1 +#wݤ&MMfREiQh:a=bXڰI i$7NwU2 :_Z^`sSa&:U7^ cc;iYm./p Tcա``})ldZ˱փvv.BҤ Nb0T2X FTE$P=^\9y8㹢 l7.`&:{"H3z_ucS3 - NJK(pf XVoZq35jdt!IðBmYu0Hƣēڀ!!<6K0^d]t_1RJ#F,>]"lcMs/ⶼy KCJ݈39ۯ>~* 97s<ὁS{=,.|{ V9+MWRQ^cL$lRt>3;QgeDhp_g{c(mk ݍ'ђ ,)ټG}~mXkmqaFHn<5gq1zbKN9\w|FmØygRCbV~Fʎ4k*8=sl'[`)s}Gp7ǕE\e-[cf /Nښ(KWY8u,/< HHm4P"Hl|_=LDaߕ8C^3f~#| si_!q]]UA|v Rx3Av3[oh { Bjʦ&)ZJ'&TZJI=C\G8z\(u/F*|5'Vcu IDATZ.oLoڶcU3?%5:|Vcuʻ\4KD<h#l`LLH1h4fՉ]$SrYar',1^V>@,wHxA%mkׅzfF@'M:# ؉ϰ!&JR4tD ՉCUTr$ǃ/'BVd:s78`boW$q >tݠn[=k[.0j>OI$E (N#㼲MӴS7n,9 ! z*!$\^f"LRR4iX6Ob*g8GZse?fuoq9&F0-'tUgfȲȢDZ^f KY.9Gz3 K`b=\w,AGrJ ﳹ02. K^;y%GEG_G=f:,>/,:f>O8zi }6 W @bn5=E:|UK1 D{px zJGB6"D|s4\*/PTuP7ϭ<3L[oh`&g 17ʇVeC3ISɝ \H %\s/Ul"% 9r $[eS\3]yWu?zΙCу?IF~]BN~ĭvTstH5D;j**w3M|zjaUAW<;|Lc)LK]Ӯ)6>q%i&઩|7غ3~' Ñ"i}MrgJ4XCM~თ_>Y8)W!_Hmen66}&Il1P*zjP4&F %*Ә-iCw%24Sf1j'Can9Fׅm')s3rWz_ mZ$~r>-tMGVY I-Tx|8]l( 2bٓ=Y.3ShVPdͰ$<I/Cj7v]4iimhn`H!OCBKДn6y;mϊi5\RZZ2`'ٱ}Frbݚ+֧8N!!b|Y|Ƌo9{2o2ol~\}?|ߕ/#?dh|&&Uθ* h6hĒjO @VILF0Vi@ _͞mLq+9(REܜY9X|Y'geju͘:Ç -&@ײtd} <*?Ȁ|F2wֱ;J )wȿbvpNl]om9AF7!dݪf:#3{vwF5s#\ Fm(| ~5Cv F%\bnf:f&M0 v5vukYD]Wo@qEn} ; ta%a>Ɉ N"Ux.BY !j^)#0rFD0̯P9j[~i&}.3bW`)䳿ǯ? xqⴎ58q3}E:WPv? ,Gf~uXĎ&tE]*J[L: 4p*y. IJ7zE*fՆUp"^Vm85ZJC뤙ʹ+h. l]{ߥXTUO6ɽ-gpO#Leo^}W\9I4&^# _^;a{_;.h)‚}RF~]eS!w3rC NpXZg`5O[I^gHWC^&&5M]ksC2rqT !u'Dzc~{@vX^{4MAVT8dʦph<le[];۶%e{{ѵf;Wk`fY%$Ͼ.G, kU>3#i6 c-'0,CۿfN'TeCk}'%N"C>;TWsǶhs.DH|{+]yG6VV0wb5fU'0lh:t@R%$SB-NcF'S7g19SNzUWgx2fL)wCR KWBӲNxPxÇ7ֱ3bZ@e '2\JI!P詧oMeIwiZ2FiBΓ 8x%-JO.?éZl$?{gUާ23͌ZlE,W܍ Ő GPB^>!/! Bl1c㎌,[VѴNϹsg4,ͺ;{sY߽w}Ų,j*a:zz(\mfIJV@fZ^8k ## :-zB-SBm$ RKCeN{ Tz~&~kyc ͷQ"晾{Kc\Ώq?ɿ 4kQ~+OA4;~Ia;T~)n\{2_XQ}b@`kz;03Dz)1' !F%__]̌ j3mKL\$!Z4jb_mY1n5B45_2;8&ҒA77"k⪖qnDh_1""xiYtY oQ(*2]Ȟ,l}t_9%BP~'~t^tZ/dR }wa]noz&|L|R|T7 nNkloK8w[7me^L0\'}\[sPOW: q*E2>~"V)Ӕ T@Ap@*SHrluhIHzj֨NQEVBzFNǦ=J$1L)ͼfqq@P,\v\l1W !R"dF \d@FBIO[Nf lTŪK4T\acK˜rb={OP[w: :)\ Y&=7jܿUC)ZQ~S M2 e*T*+0Z9T;Xw5/wsmtFJ2bS煡KZmu:8=d~MRX?.۷K\]0js mG}9 j ![Abp!j#"Ġ5y>BbRR[v,P,3e,t,#!>ˑL ֨)N졧b*b/b x썇jAK4'_Ʋi[}@`^(s?'MƈbN 󚗿:kR?k޴^zP)|jE^秅&%mEui#SuBeeQ;>s<8^ (O+K~yp؎cXm;9li_N6OtJk<v{qх1wliV)b2ZSc-O`ɓF[XH(pygsӗ?E#]|x34-o_*R)ݼooCXlK7\r1t@__Jb]ΝC;er;vSOA 8 `"EH̿wb )ת9 \)ܘ5|'I͓N .(¶m|zA|iɴIB e 2F  X jD(BR רҠAHH5N)i> ɘA6FU@+M9><څҾRt D6B\(٫q2oL[K,@XW :'QA7 e1Tk][">հj31##7 zhoo@yP&BkPKIpWw EaZ )|1{!, UBk߹u)<*u_r=뚙IӨHߓ#@)і]i6ʔ)R@ C PHd2w.q},iCآ3@Q(ĩ @"%0*j/9~eLL`"m*4E&;YhM[}sS1S1Gz !9P'6,r|bofo3˴75B-SE<)P4h ԨQBF"Zb" qiDՃ 6<۫лh]hx |OlMXt\ueƇ$bz{3%,,?lz,#|dvp>kXm[{XV oA4'N~M<|G0RM)a͟3>ÛJ 7FEdH[ ,#z A<pJqXbE?ef ;T 0 q]id=*)%".qHX(@m&hk^O|~Faػ7G ;6Iתxω[Wnεl{ Nm_=˺)9@ IӔ8 MI* (6+ \Pm׿],#:vDP@N@r,{).>buӰ  wS$ȵ9/tsWp'db}8P[8N:Ǵ7(4=o$tb:"QTŦD"ݾykܘ(R&D3NShHI H(lШרWjUj $2ź( I3%v\\? ()Je6;gP(Q(B&bƐ¯zW7w?W}tFe5WO#Y4oŎ,ͽϾH=Rі)%i y 97fBUoڟmSXzQ#¬oɒxeדQIܹ+kj/VI1{Cם ]z)RnOXX 35\)H4[ұ 4ABgC-Dƽ Ę\.!!!uQ&kTeA9Ȋ \>B\1mL1jJDZ^3 6ZԴyAPjBDqZݽQ( EJiDn~ c˧?E;_C!: Q*F ޢ]hrnfptxb*(|!O&Zk8ahhA4T*1}t uP,m<$ZVisWf;s`#i\AĿe?)0/;<0?x7%)Pw U@,&B4=Mwҵ$ZPh/"tB;*JUЋKiBf ܺ:ȋQ8 )o^i4(K$T'y'f9qC=N~}~T(-.1^N0Ձq 1uz,DcFiӒH 9H4d)WHdj|=E"F0͟+TlzR6V)%{+νe+GT3~rя>t6X0~HmBa٣,m6vOk-XS2S1Gytttm6$R-[̞3fG7c \7t5z8'ś'O>yc xq @\ L ` iYyo'}Ȭ:uf]Kpdg`̅h:CUŪsBy=ɭlXpV)$퐪}}'sZ{K-E ܶjeAL|F,n:;;9cqRѹ.DhTlN"&! 0`T$ 5Y&kMI\j|5"3JGHȩPaCDuMS:с@4cySZgIGR${_SOkΟ}KG>L^)p(\Ii6 t}H4].f2;S1Ga /ߖ>F*~W ,ƛU@ p:Vϯ𬽞䞈f=ڶ0d(r\u#̖ܮ2;6<Eݬ<Ɯs+´T 9F͉miɚ T6ݿAh(~ғU3W/o׼_w|\vy ɿ/ڳx^Wk[=^IJlA)m2}/̞5g7[8:&q-A#w>oʥ4۸&lՈ\vo9Q=jrR& cx~v_+s^}ݫ'0KG[}J^~|W?}">/b퓛ٱ'7+q tJ52@6wb0 3b\։+=œ3_[*.>KN|-W_v:l~aj#+ Ӻhs%͕{+W]mHFfIӔ}} |n'qrG3If`KA=/iؗP[MV/)/=n-XyjY5lIgpͫ/aQ|ǒOwzz/|_Sf!-fi2'vyhFF{4]w3$_4^$R PR+$i{ey)i&eG,e/hM1ӂu8nchh![nhaEQjk⦚CA|ÔRbYVTrpq] 4Wwy}8h*b*U8uʰ$OQ-f80!2-*"ŝ6Fd<lN 2~ |/mwAcO5'Mn4ߨiQs*2X)2yo(6FC)Ml6{_>}ݼĵO64.x'ߺVI&@(anNXZK3 z G8H!`͜ZM)I 39zh4AQ$iJ{Db= !Zb @Q2J† T@ E%(.(ҵX_ (u`槸W/rJqz,5'ΝKRʚ 3sv^~dg__nT=~8 ~z Z0'ҐJ%-4Wn{ܘ&lh:*M3~qdDDY[P |}@ʔ9-Xc~E ۿjNC|??+.z/?{\0ij~;x-'9/0sߛw͟ի,^}vg|sgM i& !W i`Ĩ0Mb_(sH7t>6:Mp,\|>'*ֹyڻ071|hR/MXӑk'=k,s"dmem}XZlnh9ҪPcIT^7h2 ڱcG=@KbNDM@ m mV@Z+?G(fGT#g88GAiFU}t{=V@Ⱦ Ս?_{ba6,}cff_"諍݉s?;wH-/Y$^̽=Κ9 X:ae;Y3:hLe?4BfVk~:vO}5( XR\?,}4=RT6ݩylR#JTp>Џf1? EJ) CQkRM+ ^OZ-j}&XD 4vDyuhjn؉+qdւŧ1=Sʯ@ObO&kp`MT>|D2vG8vbŊGDU@ѬAp@{v@ ;9 4(R4Q\AJJ9ZC04:١8xy^*wVsX;,lۢ6ЩFiS *E<S*%Ҙ VCbŽl+ ncöy'qJb=\t+Y1k.8D:짤3 mcZB 8&@^&/(6ieY8q_n ˶"Rli٪*G_fv#xc$ߑ Hїlc`M6'1N%W$JS^{5"ל:d\q&q ;7sq=Y[7`Z[6,sRi}+ V@ÀCǩ{9E3uH#8Dk!A} 0@ <=lq+;϶@h6?WsFC tOt~_;T=>uc@3_KG 뉢4MwqzA6o<)`4m.=]PP jFۘ 9{g %@ moZ1, ie|jVV̝rr$Q@Y#ep۶+ ި1׹yܼaeC02*n-0A X(Qp'y !sslߝᇟcZ ;1Rd2<@`tDgU6!rM 8np1n<93)̿ ok߳u$uϬڕ ̄Ś_ݍ{~-l2E_ ;> wXi:BӏSשtttP(礔jBDmsoSw1/s APC5KVpOƚfSnQ@ ,ifB ii OO\ߢ}V)YsyWd-fމgyZ:(-X ..\\\&d88nnTd:9sQ%9[BڮGBgZ(Җ4Ees$*k(wa{ @$ H2|i?m 1M*ْnevo;CV{3WB!أ礲ŧ$%OS5$O?(9+X9øfO>3ĵo0z*p#7w?^[ƉWO1wCDyT4| W1S5Ia?.jZa֪W,ͫn:xysk؟}Y04>WGsOZ<s#{W"q.ĥ(2wϻV?y-ILj?{)^G XLK+j‘,&lVBvE_Wٰa1 b04=m@eܿrJyL~]اٸU3YO-]LPآkΜJP-]zLTC^p17A"$< m@ӞGvqW>p^{tV=Zgc4M =~f$SI8Ð0l 3w*q<ׅL_1%-ٜѽšĶ-]٬I[+">{NoO8a d [" Z_pӧq)'yնʻX 4Jb>]|Cqz,ξgio}pִ7m!#ٲ}YbT8Z~~?<2TH! ,Gn7r ˾ʷ]މ껃7X,z/XſBJ|y3b{3w!3w{J"cʼBRoHS1٥ucIqkQ1Uw%,k޾gn&§ XMH50U%RR E>oLaZ+_=ShX(fƞ>s(_-䟀7ݙgz 4%,{~t!Ol6s!zgyc=m_'ohu}9[J^)%su]u&igz×"x-Xy˫`S|a(LTٴi1}ߧxΨ V~Xx1o-awu/C 2Xe\%_{t\K[ɋƂ𵏧Z@"?F=һ}~T(m91i qqY- iX>2D2LEQ ¬Ie-PmJH(9"icE m>~3򹙌mgY8˦-a#;x2WC##hq=$Ska-ǸQc}QF"E4o|;_`AIρHa~+ ?Xl9ct3pYi'+0s$D$ʓ[־V@Lm!U!jT+Z4I!|1J5!۶mogÆ \~Xb6O?4=Wfca* S1?fϞwqLRN> ' 7<1@'tuu1|f̘왬$66*C*& H䷱iuQ'q510?eh HDDD kU}r-v2p( Y588X9 ќi< dNҷcߥ\/ez4s^ʆe|O:3w)XYNyiXpmKc2-emTIcEƤQUEZ0[ l3a N>===ZJ=XuǺ{ŒZWɟ #poZ)nʼnXI*PȀ_,`EUti|`ӓ۟?Wj7{1[>: IDATm't@ϕw~;@q|Aq֬Y 7%K|S3gd֭kdǎFݹߖeN:$.]:Ɛ`&4yCЙvrԀDf܇Za"! !H D~ѠA:5jd[sԨѠADRK/*3u9+(J &*hYkC^PyW9 ၇~睃mKcaqA`; aXv$ PNu?2gT,0Q9AV%RvWפnhHA 2OZBD6Ɖ"SD0/;1>p%.Fd{a'q' jt %Q)$)'\."DHY_Ƌ5U le?"\m.mH &ʼ7=oኋ˰ Sz-o|.8ēNJQ =ƈP EoxQ 5QL?ka#Mp QPVhka$1Nk<M$K@ʍO@@df Q7O9Z+<7UBVu()˔%d"vSHfZGu~`MEV8SX~y=>exٳ}fu]y睇Rt>Ә7o۶m+d8JElkG=Mkq*@%5x^7O#hDz֚$1FuZk.|!Qڃ֧rHj6䕚|ֲ`?* ׾sdSTCozKav9f/|{*3yU7͟/n"E$8ML-*IHӘ84-%`)6=r'ɽ 5ڜ no6f:Y#:P^Ʃ筄md,v%iȮ` Kg]xev2[A}f0wPM؋s;TF%&uҠS־SNG6zWXEGG8̙3g x(Y,_o~3|;/>08NTo$IbdJ-|-X`@XOp o;[ma:RR'˗-mT ܦ! `| @cG(K1~}; ǶV@,[}yJ]w=,l!mpyr6g,=muӺr)'[71R ])$װ-;S2JG u&<),z>=f33No˲ĦP\RiI7(!lR9}BtL߄m :&wd,iwWyg-[E޻,wٖ- t qox!&$Z16ƽ[n\eȒv{qff6iUV~ݽ3sL9y~?MQNWVWWsi6u,"DY1%^ i|8˗#% C&JQ"1)qwpJAO k3]4ʒ}fdL!+dzY2Q`K[ژLB\QL]'AW;PG | D48GT⡁ϖ T 4 CUAeM#SӀ;L{w+l./[n3Ǚ:gS6ejbjrIL&Ci-m2WJɎVZ{ڨe <#<Wg+KmHpoON?e%APD)=ވb9-'>j"h1PSSp_c ? 1lVQڴЌ|M 4M0,0XO")*M0Z5,[4tM9f)e~8"I=^;9GQNZ zj.o}S^ZÙ V2( )Qt uw k 乀 fx01+ؤv44tTǑJ{' 9KADFf&z>Z sLR4rZ.3bNZ¡ b CZ1J%L0H@C=F<[2t@`duhIs4aq$JUk&gy|7z#xwm Yn.ם9gMKKtYe\5qhhi22" hHt%T'a|ld* $F>b@nS)ѤnK$掘<2b0"G<<[.+P*Q.nJ()&ea}lL6Gzs8;LpZw,?4ecD[^zi9cmx\Aqoh ,C0ZfN6e)0<|IzvTչj5U+Wxb˙UWaHMӏ xHXNP3cL"рKR/eQN@KZ(REJZIOpB0e l"}qA sc"(9m;ؙ,L''͑6l'er0-41t0cƫ$W *Ga} kaXA\1-(O,PqR@QE>Z&0G>^s.94j*Km:Vr"lךikkmOHUU9~F_wP(/ƫ-K@@.:qM{=?|/g#OA֚-U_\ z/SkpndŬlK['"-a=ob0 ArU1Hٺ]R~N`E~§kNƵq}=>_G?~1X6+g><.h-(~~H4(J~=躆az҉0B>հP=XԇF< ]Fi2gZZZX~=r)%m1m{Z"+=.Є*W%I `(pBQC $*/!,vohÖΊ;*LC_uyz4Lg)˕ea:ֆ&R5NKK*mQ 6nz{ 81CTA Be8 uD"^s/Yh+i$"tHr }e)'rʦl_IL&րd( _}u+0 L( ܂G @mջS,[l }=fpCϲ,lA8ngI mp,i%Zy0⠍-1pH4|) [cRm!xq[އeۇ}?,41@ 6o~ӿ6ߺ:ַ8M002Ep"SMܫK"c6[޾QP8 X)X Y~)2eS?6c m6i+Hm/kŠ$a$*DP"t}WCe Ĥ$Ջ/?~?/-xcζ7L{3#t*fӤrҨx8q HGR)QJ * -tZNc2uәU7\I8$B4?z5̥&qJ~fn"x]G]u zv kgOWs'O_grŒ1$sBMB)gRpƎyQܿ{f| {_gL-a)C"DOlb)lLCCF+B2ز::ȔMپXcc#UUUK!F66>ꓙE cPI"%}GHӼ1EلQ`r0co};o-4cWC%;9PD"Cy_#0 SMT,.n'% ^7U %ab @$EZ%4 ˶qds94HK߅дԑ8Ǡo*" ux4Mu"X:"HDC6 9|d{sfw-'»>yLzJV]' |^~F~8( n {MF\B'nPdku4~D'N DQy.eGF)׽ _E eDkDA uXǼȷCOT߆ 0`"lʦl/N ;MBd2e4Mñ4@,{ٶsL^ًA8ah Bw9,9gDg֒56 yIx̝; &ʑF!'rmy^OWT-Iw10(2UUѵG ôbpf~/"4 C= 躎e;dr9,0Af]Y騞L%DAHX1 Aɋܧ顫^"_~nXo'Mo}-jbG^ j^x1_s\$1mx$Hb@Qw+tOlw@Z<ΰwP1tihi$ht7"ފ{hF4 ^m;s8:3HR_OG6 `&Js-|`u!PLgLGM#}hϳnaWc'7ǩ[+fcْ\7<'ޝ&/gY4_?2h-y}t֧0 (`@n 4AF$EԀ t۠7"SUˌ˙=NCU\,098i|,0jtѓhiW1-,t3jȠhU5h%UƙXKIK1&G!`%7Beܙ)=xG%dNҰT ۶Ǎw"VE8YtJefŗ_LSS~9J{Zg<0TJ!5$9&f*覡aH%hKKZII&`SV\ +t1nqNf!e+S#4Hˤv$R Cض' x('T}S}۶qV\AkLWMO?<Ϯs93f Pk[añCx=f8xX0lPs?"zxy @N@Q^4 y|k- ,g`S\hߣP*Ai d{ik9ڃr6!URhSKfe&g>㙠IP*(8HR +W~GhOeDU7Hj(%D2}gwL)X#Y` Xw|~ xӛ)14 p G93ئZƷﺝb1M"JsoO0&`wfILTN"4)v+)XL)s򽍝ncN0F:P2)9ADF$+*jI0 }|\<#}0diN!A$T1&8Bav~ dHciaqv䡗{A/-sfnő@]Egm7}v}yYgaƸyGkCP Œnd̊9`mZW  +C:3č|-W < < |&^oV Rn h>TקI &u馅 <I6&U3 õ@Νvk>Ǟzڱ 9Kfsdzb 1ľD#̲<\**I!A~)C]i"\1S~'P 9Sj dA8;,*€0㴋8xxG (Tx)9L@un9X*,Ʋ0CcSS\gŅR@G[^96Db((ߵ[lRY/XAt>z# KXd.^c3/r/y->H D!m!%a+[RWSC.!`N ?$è#Ȋ' }o" \ ɂ)1I@,4M~?\^ Ab.SEc2jVcl!Ux"tcWT}Sqt Hcde%#2BPO?NjxL'_&.c抏rE?&ӽ>gŨ胮}t,״wozӛλxmo&u(ǁ~hݑ @D>xix+`Vx1ŎeLŨleh%lJN.SJTzF4z6(TFBAkCC |GZ'>~Z\^XXam[52yFPadT'=BH Qy0 (*sT憛n."j41D_Lj"=+hˏ`2 g"$XںNNȒ$,DW+&qms93) PȃkWs|-bSHwGh6Ϳ;|uEvEG[9iN34i zr~|qۯqȏ "=xdpw .tJ PEKSā {q /s|M7>O7~8lMl3̅_\F[,Qۚߝģ[:x"rH$R7\|7| PσN]M a)Dx81>:"GcYyIE2ErH.yS&dM>[ss3L& 9Gt u\AC^  x$gx㧀LbÁE}@'Q=DOjEh>sTqXHIF<~h#2&v@&2J uȍ d`?u@tEܒ|aȫR)!~z!"‚Dzc0 32!۞FP x%Eko[gp#/rz귵W(ϱ^Mz IW-g ]Cb2}f ϶j?ZʷwK["JB #-u;ŀn>NTap}a(;25)ij]*־aVUGozV[v&;N$ 4] Ǽٳޏ~ n4r5:wTg_2}TU]Jp LٔZZZرcǤ 59m d~vm;!!^ P08TF$<<%Z6 , ڒcҒ&SP . "w| bv\D^HfR=_B=\~v==EoD!:E_ 9 [)i &6U톏sgviKB+T70/ QZ|UQ<[Q AؑAB31Q wDQXD5W/NE~ڞ$,=C25gFX嗡v&dʦl<6c zI$ Fqqimp8d{@"fTG~&cY:E?BH³i6o/`?ɱ'W&M^||;oA>@I$>u 0**ڇOk-_X@9ԦB(LS/{:{dsDaЭ}9ǞpՑ[a LJ&v&J'mz8<8@lc---z뭓L&b- Ev@?Iuu Md2&$Weʔ(foHH(BA|{:烜wlÿ?%ϕW%GxܯwWUPji[.Chԥe؇hʠ'#Y1OEQa@Cچ!3ھ#t0 #ImbWD@kB/S&,]ש{1'YWў(YMDR\Ӵ{-)IŬ_tm`chT>/u& Hc[}^ U|%!w>o|b9d4`CߍfJռfbv`!SsZHFtws=0 0 IEɓWsP*{=sFDsJ'5`䓰dy)5771)^UUEOOBTp lom/ξ>FhOgYuG@=TڈDTbRxC4gw,`~N>F@x9q#sr{'󙏜M|n=ʹeJ p;.9UF,1 4MEr|/eU /sSŽ>428Zۻ2nt[;pW5N #e+Y`tsChy0q=y "%@M @ 4'z򳖏 fz dl 4E箧ql̠ K&#%kOB)A95uR :"d"W]C{c : +}5 @7 "8/E!{er\\*R*( WX\*P.{.axM1 4ck`Y6B7 2:L0CaJRa *H {#Uk2ij@`x xgק&ڔM^[CCuuutttdHEFX`uv"n{a^ko!C 8YHTPcZT |xv 24] bMaHca7]  Х t V>{xgR, P*P.*K*tyRiaZvLu8L'qi3fRa[JoGu4MAʊ`,CQsxVU]*FzA/rl)XrHP }:\y%<WS„S6e{Z'e3Ln[fV5MA;ygj֦O 젍|'ݧ=W-3# SOF#:7ڕ H pZK`%JNE}E! xЂe£BJT@[KckOS"cb:TzKE R55"ϡ:@S FnneBD!e(N0 4:/8ؖN]SZZU!v*UthC[ X|,;}mh3! ?? OoE_cQ&B|B_"D4sEdɒ u- òELRq}KKϫ蘘XX8eq* %2hx饗0.W~ӚO !izc:tV u dRr4oY %a>Ldjzha*YId_;kMȔM̶ٞ{8)qLJ0k 0ǑY*?OPhwAIx\OŅ^>Jص27(G _“5I3oyGC|[;:)X(1KQiX!Xz+(gҪm $,Xɀk:nO9B\Uh$"$@FpVWK狯PkkXG~֮u;:OeKB F(4[Д+nne2VU\g\F#d:Ag"$QG7?/!8C&t<ȏ(l/l(Ӵyxl;g<a_hF;^@cIDL! aЯ\ T&9S2.Ɩ6twCһz5~RD } [qp[9 gkxģܤ?tNv)zs#bO Hb B&3c2EEHpʦl&%4*@'P*y9vjg@&w`z&A!d (PA4zt֏ ^_ wA"wWkqy'c۹M8@8e @g @bM= JYGQe^EUgVӸi]~FdfY"wx#ӎZǚ5G/Wgf/u4]_7F1iNKl!2ol6=,at4]# 6]7|SCSa$^ qn;TS:HDx;]!39s8쳙>} >^" e@2X’ !`;+^ h540? ?6\R&9QX0]am1] R(;=Պ(RtQT9L#Lp24EFyx׶)$ bwhu-h)%#Wz^ቝOw+33W;si7S6eG%Q${2$1ō5ώbnWG$aDEK&"g ]]]EIS>˫OͦW`onQGOyMr։K/b^$/TEA <+(*D[M3KO͌\~"~tW,>2֔w1foZwa9W\tj}u3jk 6nz >fu=KD;{]>JE@9úSNa…lzjO=4] % =z.Vb…!5>j @4 IDATD'D@!&* ,^s aR.mR֊b4 (h,D*"DQJ̠@!J€( YC{.{Rk]DP& MC4la%4ԏC1ƴIÂu(8+k@.>>v_S(˖_F{/EJ]|1v.Va'5eSv0,ajnnTvRiֶH у  J¾XM*eh h=n/}}}: ʪ]H_[/}<K'nrp,YiL\*!J[nynKt+k3gV*+׻Nt@ЄQ+18eDFQCzG6.-}YutOL$ﷃu8$`@c(8 %$^OA]j ,{BFDcw^f(ŽwJG[+"Uecvpe;,'CI!++Mh!NJ*Uʇ+fj[ô5&8kMMm=[VQa=cG,k4l>y^JW Ð0IJ,,edH)yҚ<KJS?u]9)t&577sNV\9- ymcr\_89/ lRPVLHzIT]Vl6;<#\4AHDX3NVp 6x'LE{g36lV4J숷zzzpIyI_K[PyUUKwa RF͠qTJU4Ugf58ūFcƜYxuщ˙U:FBZ)XdlߍK@꺑r%eJɃQR9A,$yK9ceRQT*G42*d Ί>(>h <9=SFfRݗ3"Oa2^pP <<|!DX E\&=_"}-L!#.gc [눢o{fYwΗJJ4T $_ƚYNA)4QDLu]>ŋ3o<{10dΜ9X%\_E]D)}e@m!Lf?SnңO9Buq6ӧ7^ϗ2_9+K֔6m4Yd <l6!i)1 >u7;{{Vg([eDNeBtȽbrqQ]]5U?k{{mQ1]7T8C#c6'iT'CTDmPPMHf=UJ|efwVf&qץ %J) 0t]iռf|PtbUN</e3o.ֆ9 GS6lT*҂m<4662g8ظq#7ofΜ9\pd2 C^~e(s8g>toaqbΜw6R† kOs*P[Y0MxxAb)ךM>I @c T]B?z&v^%c۸m%*~,X`BY/Ca jĀ`,;8 ?wfd*licIPH%;4ƽ[duLU[InjSܙ9==oT}9* rP4Y6(7&fk8m)Жl'2rpy3x$ CI [`{]h D@,&oJjjaU#'3^|&@䵱`pQ.1+u5gTVhgw!i tIDKT{_t [Y3k\ ,FMsȂ>að,4$ ͠E(&8#jMK›Ga/i Diâ |ZQQ9szu]\+W2rH~nɓ_pDolatڍN^x(á̓o'FbQ>C ?Q`PF@##!)i_4dv֭[czp$''s)g^o>S}4p )cȑ*(*>|((1@@T[F'bnPFl@8l)-E51x$+iМnpwh; vwQ#8TA l>0TRM(+Ս'=`[V1oOa~6dh,E;c[EwSj-HNFX{>.wB+ Ǵ^pIٸ_qy/uyL;_IIpdY0X4ԶmlӌUkOmBH_T0 ӹ@CEuyqض :j*B'>Qt/4GKHm3f0cƌwF5V?3vz ,x&]G 8dx!x$ڱUu >Gٴ)4f<9Y`2*HHYWZff&UUU{屧iӦX(6SSSzTƎKee%PKff&mOv2,4 V(PH*S3k;IJ-6BQv6j$*k[:嬮_Cfa&zpRiTar?3+^[dʤ)ݮnߖUۛH _ۘU" d: x@ >K=bBخߜȻ9wz,:{~#m7}ᶙ0]!{eܹ }~ 6)0ȱxJsln&$/hG_atC躁njVj*k;u*-r!6mdMI5\͌utx\XֵXj8Vƶ 4rIIE{H4Lu;bXVj)WNHMM @>ni}xu,ܶAO?  ?!R]c%%  1\&|hZ$qg]k>ؓcj.TBoޥ( iiiZjg;IvvK{wL a]V$Qb[PVt}ef:}K`p#ơƥ~l _uؐ^!e4uǵrzR.S_GVH%!, Ӵ0n @.(0x # B/0))# eB-)X܆Hç<~OOsg8Ə[ɕS"b콑O>_ĪU' ;Y.6|>] iEGh(ؖ%ҙ:i G.kUU<Ӌi(oFwM[jFrJRB,IQ,,sרpԂ(@X&jK'N]1{4 .RB;bWǒkHuyy'xM#pםЯ֚V FX@̜1u*qwv48޻7nUes(:nZ\(ҶYi躾WCmtơ8vT@yvֺwձ6HĥQeXs)vB976NYM(T)Y9b}f=O^^^ ׬c&}6`ٷч &I#Tz>=^I}5h|n1az=Id8m\/b77 ZK" WWDD1Rгw<_: =g#@/4MچH26Yȋv/@#j6)Ƃ_d$ ֖c:*|qBt M CD<*Kj\X@cN3l}4 hўfn;@C`u;=9걻]1 gECi%qяkɿMy[AulـSu2ظci2 ꦝ*Yͪ:(Qlƥpi.-AV;G6oM8!;Ǝ%;#{~o 6ɪsC0$)Zy9Ab0dzWay<BPa ;8Z DoC]vvՎh!HBw9F\>۲*UjJ¥cy*VWn#4Ы jK\J8nsml+ٲx!k B,3 ۄ7RS/<҈l3/H=vn;0~wíL=_Q:jTY)ddfj{\vh.r:~ 4s\@0sM@<MF ".iA3>>$ϼ*7،Qp8TI4#9N&c'6'J67O`L+JonmaYi`[&eR__GUU|g4 L4PloYބ[Xv|#yҭ=7ݎ\<|r KrΗ,sEHdݥq2W*Y,F> ,.Yjಂ].ߗ\3_=#22(? &lj|{%bפ$[ (v$ݙNtwJY`q[#6]4U`FR4E1 [7TX$T.0zQibTFA(`㖍 0d?|?-]yT wP;\&z-!]MN!B36bةӊS,Ǎo/Miui;wS㾫A]>2lAFKEOE0d! !D6F@׍?LOg]q(Ax:`(*:N9fsu"\ gfgm^n7Gdd֭ܲv-K&c]aSPPW0 E)݅@awr3xWK@"9J]cleYmXoceN>@lAԱB~?'Ѵ ꂔs_~ 9%!s813GDP2+sCJSA}<6d}}R-FAPvs~ϞTVƕVq~~>}}z.Rpt: B8QYNHN%v XTACPiU„iEQp4p9`DT뭐BEFQaZB Aȶ}p6x' 9\ei8@UUjhF!tw6 IDATjY^3f\6²C 9"eיi;s/p_ "7,0 ,G~If&p@6ǙsQ|ES)M{4'mk.R;Q9,;jYuY>TY&aΦ \6Q }]pNThqs:'% 6/^/9W7沪rڰSr'l#샘NaDn =z t\™ܵakr.=zPRRW{p8p; }d4; ۢU?T6%#:( gIАdnBF>sa Lx}rqK!Rp߰vn M᧮ۖ<EuY!uE'9JS?eS5,aZd4kFv: Д ramϑ7.!Pm*O-ˢWO}혦X1?K@<Г`=\M#)XU*Jީo0ʫwa' 797xd%edtZkP[RIH#W͛u;Ͱn|o&9ټy^ynP(%[{ټIߣU@ˡ5UF@"D6`(*MRdt (n8S5T-,RdXжU [A8Y28!7LJf""oEKBt(ƙ=^x[g3"KFZɢK+ȴF'Y;9.TAw4;o1!RKF^]|ϖma[z8eXއP4C2 q+H[nHB_uo.{7ۯs}xq:WWSp,RzAh4JrIBi3p UUxI MX3ii2+gO9R5n'kd{G# $-U;vtm!.]T?()]A޽c,uCj[(;lcAr7Çp$5w]UTooFeE~Y+9,iDZp  鄤 =g>I(D7- XFmyE@9UU Բ"ըtu#"cY& z*`T<(s+XY* 6=HԕaG%w.hmͪլX1Hqt1s0osb0ntuu^V̞xkQ099p! `64I4|_W,2BmX>,3$ZM l}'øqU`5U*U^^2NIϔ\0Fd=ٸ!m_6cwsϕ8k)4b(q.o-LO&G=CC`h}zf< &p><K_a@n.L$/(hҶ:kA §i IJjorrrغu^yn;VJ.uw/ѽ< eexZS5t! czǹ?c 0pzH‹3a4k 65Ez :@Ϥ]і]i;%5"/G˙…giq/ :ܞkO ۲K@ӢS UEQP*BiLujᓉVI.%X<ɛ:"6B*"; xXޒղU׹sgQ"&OƩt +Z^|w\x^DI{S[pZn.cSRџ?GM;0SF?Nn<-MFGڱ!&xަpuv;t+Hnu%"MNT/l2:wlnKfdi6yy"!_[ՌKIᐴ=Rz0x 3_GJ'$]|3z,ێjdfr…\YXm⬟~O\EG{Ck6dt?fD]IQj1kR\) ⌡3/o?zt<' RHqYp%-7<)p!ĉ޽Y7r\Vrt nq#ɪʕ8E LA~~jYA ܜ3rsbUd),#C}"hY  Qgd;q`\͏EO)444d˖-!"B6?pR'Jv+1ҹ \Fa d3m4VZAYy9a24B Hnnn>8S9 8hG_Qpks84vƾsl9:_G<2 4ǃ:Z, mL:&ݲ=r*+񍈀7LMlRvwIjs=E'r"($>0ѻOYYX^դi3rrZ:,n= ݟtt64t8wuṷ}dvԩ~}gN<N!t!g6ɽ'˳:&63Ϯ29 O=w#mN;Mzk1$Ջrs3. ĶmnӇϪtJge1-=c,/)gWCpR&jWòe7]|O[~/C Mn͌Wf08{0WLGֶ(%f :&LdxXVWVWtn\f SRȍwV6ܲn=\.-*j/^,`i)췟m읥<`P =M\viESJ$FZZÆ CulFUH:ڥ@b[gĽ- "#n^l,!hu "<!m14"߉ƴ'њ"Z";2/}DlLCevm;2Z|rMll م;]G{اiTcLKR]]|$moT{_.BctbN*nr#Ma9/Om[wvIN3yq:^Y1n"Ay4nߴJ]X_~ 6@j*OrsͭOo'edi޿C{ۧGB^;5fOMꃮfBՆQ-  ̞t'$ = ♲264pXz:r8b;̫ŋ8?Қ&Ӕ[2+2-ޖ-o4̈́N@˖jثw7~o&'2&b)X"z5MK#~m7"@c[hzrk`F>#i r) Šη%&>=F( G:V8Veib$bz4r00L#.]);Msns!; z%GN3w חNߌ5c)O~?sz9d鐗'3΀=Xsز8rKOL}xׯBTBp!~: ~[ݲhȑpmA~r;i}N0/qLf&S;TqA'[:j6P+܁t^ fxR_EB,CJu[>Ι`bAq1vjihoG'N'7}v# 5;v[Tnid.Tnb#b#PrrxcV.] _ JKeUg,- ~}AfJ!ڽ6b풟Sc!K)۶88_8d.ؠAZ>}7mb/OEsQQQH4p۵@vGԝd{ߡ tƲlEݰwit5wѪOJl1ѩ!Id&s5Y YN:|V"]^|'O;uyI޸?Zc<7MRrJ,kWKmg v+G u@z 9`F@`P :J:ZIv YUm IU;ѿMO8g9;뮃+bRRm^kÆ tʪUUFq{/}w7ÒHt"?M(OymF,J %dhc϶mʢ+k~oηKI] νٗ>˃Eu@XoD[бwZ7+Wl=V7ߔ`un<ڶRR(Lq0cmh߳(++_~{ 6Z vzW;󻣪ywr~#BPưR+_A"H= ־f/3"{fG۲ >:OuAgEHD_$۶#q4pi sB V)v5D[c# ݱ oM͌3;",,osR#Jh3\0nO͕F4pu>x$v:`ԡ+m(e KJ$3x-VU%yPr=.V:mچ |{X)EIesyfK&|rD#Xek;wE+t*+r1=+)HII%I leemF'M?UCtvcjHwd=k?Qj _yNH*p۔[Y^.`ӳ䱎)^~YR k tbX˂:/˖-[vj, vPp>vݴIQ?$ i%Nc2G4MlTUvw+U6QPQ{W4XimXŋ/{~CcY"?nC( ?U[ cBX v0HrԯafWp@"ضM ڎփRsbR>fLBGUQ 9Q?ɍ="{}:8T˷.wzoj'ݳφ?$N OG6yY^T=m&χQફ$&77~t7n⊏<"5l`@f1OTWcxxhf|4e^: >zpo9/l68'/w'n{G;i}#&I|"ۣ5ȶˑM>j^Y O9<ڎѶ?z%8U  mOKp^^%DMPЫ͛77& x`KwW=rBvkpJJʨ_CLd`(F}GͯޟDu20EDݧ(ؘƛyظi3wON=LD8j]GtP֛lzZLN>4,#ÕKQVOEEm|hi_r@ v,;kV5^l^ϦUXcgmb=lnVo|''CMTYY&u?rd 00V#)X̲jiaYu6G[ݏN|?/SUNk̙r;ҡ&}%RAZ_x*DI scL1}4,VU[\HE~[s34z=ߤ?~TYZ~ף֪PegK$f F}UxBg j\ W- @NA>c -lwjmO͗SUYv״*Vu,\U;&'cLUEu|Z~sI+Gg4pܣ[F@4;U xGm[avEζ|^9.xxI 8 I))JҢU=u_U[PtTQpfŝ*؆p?@"R̉J@  p9߬qHC}iHJnw aN_e+n4}2Bv,G/X2u*SNjmg<%.isDAQd$dp)ćk8|)9OԂhyMAOM%с(n)l98DJiۼi';5| xz_~嗲GD;\`^r?!+]Uߊ[QKJc~0jDW niNEEՖԕpWw1Fz1Uoh>v6 TgZFS(>Tf'۶f,!d $G*LZP7/%RMi׀XtpͅkI½60TH6⏭#oGB[OpB& IDAT(͉+w =9UfŻ?7 7Wv*MS9~bY11#Q!liGVE!))<|)=HM%5'|="TmC[ H{&s@HdTnz)SIi}`͓BV\|̫-[r89,5 rcTssLcVӠwRMѣe*SU" };݄-ãQgxInYȑlBT9FN%uCʼMb>R;(Re1-MzڭXm-<0\z B1^.eeQ])dFNɪXXɶ%T?>/}}ofQ?Omvy:#մL(1D)/1)-+)mޖU('_j.y$;Stƍk !y ON|R")C>2TYNWW^)%hjkeo~NnYc(v[QNzjjZ7j0KY&kƌq.+ Vs|vN'Fl1B:'euɓ\vsLf&Aaz3lov,y>X}۱,oG8[}I< /[2-|:ڵ6' Um-k6 S,B9oCYe{%pE`hP3ѝiU[NSeeh$ɭ}m 7u\bc?E5Mh?(j6Y}Ŧ|8w6DUܺ- ?1wJ*` ?z9K7hSj~u^xk*r'5_^c;}:'95}%1l)XA x."? |< Z cu"$9kK7ugq7ߡ4?zx{]y?>N;/&})?s0% ^`lQ&'XǶ,,ӒBAQ5Ha"ɦea&z8DCCu:*+*(-+MYb?NT 3D0XG PMl-_EUfvS! U10{ :e)(v|~0axaۖrx楰~w^p9Rr #(Lǐ~Smْ~A z9%7 Byyp)] -B̜jT2_odM՚|8xXPVְyl ۴/䣕ϱn:n75Zӹ+ûS;-'r+!]F5&FV0m+׬d YX ?]GoX_X_G?2,\ĒK>wP޸nOIƂylV pf,{7% EsR3?e{Fᘱg3kNL9r<3:KgN娣d2gk0:|r%eKR [ʖSu%k+:vr`EQpN~,=2`"Z:K_HXI-o/R.6J]f YssPVF$| 6ǃ W޶\wDB_?\Ы,NE!dNm-+w5kZII8I۹hE;UU?q=%Y_Y_{s+؄Vq[y3{C8lDM_σzA% H ccgW]ǶF5R\$bY5[1/0jLjpNN*z^gt)ZJ8zE0ñ[e [ķ-&<OC-Agc DžIȴCùp ,]'CC:Bj]S+|6=fY=< h?BКizdRBXfvz*^o pRO&hT#Lud+] J7&% jT.ӯ,²-,˔YcBLь5CWПA3p@ ULqGϞ=鑗KfFL23LOťvL3ΠZ|_,# & K84 ԅ64?/$=Ų-[8r nߟaxh@Rfa޼ff᳹~36#,C&wC?֝l ȣ7 EOOxbtr'Ew\֢1))v*pm hco^7' ۶9uA 30${pÐ)CQS xO> g@EvK.X=r wc>|~zΞ3;ey~Yuȭdҡv6tHZZYf_:}JDeaYvҺm8mض~(QdM|t8HnBW7/q(---Dx !.!MJJ][z_q)>ok۶i,_VUB᪫\7:ˏO7`0v,)Y=WKQ2_"jDk^})AOC DG |53ƹjjzNa"w[rtn.%َs񄋹~zᅢ|Y\oxV 屝&ן7ioJIkv=]rSR@)% Fy|DH]WkZ 5n2v(ϯz-[8oy}?š_f&MM$k@| k_vbW-'Ȋ*1^6@UU2 Z_؇h14;ȰisܿX6(. _Ow,"REK>k:g;=H +A Gߏp\(`|-E P7:ea)bkA@ Hd$<_e0%p4YֹSz?uDku/s,$\ q AT9_['ԍ'2qe+xO>󟸡](^8?sF0w7~ͫr1VQ&cxp[Gs׷V:ґ{}l@JDؑnݡϛ7ns97"4M>#nvoqF1#9H&gOvC>4K隕͜Jcdz(.vuJ<흈g|xN8jk]Q@冻O]SR`R cL-{[}?p?pYr刖^x|oԐMݒ產p)fνWKRJN+,$Cq۬۰S+"l;=L6,MccӎÊlmʏfSoprrh!X~@<VB-}IKI Q#h2DiU-t _x`45IK@CتFrDCQG%7+5)B ~HKsWO߼8 6V|KpշOapn.boT*5#uP19? zKT'Xq&8-9~ki{C [,55v^^+j qu29_g|گ9{H2-.:l3|?~`F,\oz>> _j@d'v7PO=SOJC,i̛7뮻n?0!Yjyu<6w.ffӧXWFLavNweEK8a͟۝f\{z_{kwE3| ˖ z:~d @M Ӛ O8Y'ϝ:|k? 着a`fU:Vn46~ ߂F{E>ܿ~.xW;A^[h宻\-i769uxCr~gwphS6o,}v#p?nM55ӿqeu">U`\I յIր=52l!vvwwK\\S@7%vLiMX/f2  Z'_Ó! jSbqi*뾼<23T` '^u ?"ėKIQ&z$_/CKx)=,w6,^=¶6O^ʻ'jfβGi-ھ!4x/I7'끍@R&bLkaZ".a9@<ұz5=4> :>ʽBJ'6O: $AwDQ )++#H)ٹs'x^Sl!XūWUQ?|ʁ@`C867ٔxƣ7 rmjwJ7F599pl8)f=[\R[X- 8쨾LM1M|۟ĵFsNw!%6yOGp=~<- ~{XIprde4/ych+y<@pAQ!^};uFoj8[v㍮K/K]𢇩jrgu99ݜ͍SO*EpshСl?@ eY1\ _Ev $!"E= ~Rqj?&Au^?^OЃ/ۇ?ׇ/׋wᐽ%Q=Fw=3r(U!w\pa]!< p]yY&5}D@{]Myb^Ӏ \+بಋSO)лN{n&G'_ܓ_ߗs y@UlܸM6i֭1( cƌAAee%mC--\~{7ͣGse^g2;' ^2UuHG2c+@x)Ëo$p%<.l{y DSŽ[lFna8qKD.(mNW;c9>_O%BuB>yQ qinGIulC'[TqyyUU A1)nunMM?4T n[ǘl'Sz`L.?V p÷P=7@-}RwK&f! ◴KC\ =Oځ˔rdbwLF}&1Sr˩''~jan i^2=d{2x bC 3$''#uB/.&IҠ(>smVZ[)l#J8"IdzO{xL%a%dgB|9!(B]"Q7SaX>ܪ?< bRXoO_OUiq{wqH[wW!sUӝsCEcOBSΜ9>@31g^gb IDAT-[ȑxɂ䦫Liį5hEWi ^kPM^fr4ߛdTZB1+Օ N ܯZsFZԑ*B M(-9jL.ૌsHDdLH<҃ɏÄ]-I>C~a^ɤ=[²̔6eXٺ'<FE*cvU ywɟ yydqqiNǴ;ߒUW1mޭ|NjY@Sz|^G0DZ#|nj袟,zjLs\quSZݠeRf&ݽ?9'MXߙЎ?uo1fL_ K{^a3̐!i+ 撥\v-O9\X/ܺzDZՑO>Gض`rɧ-1x|6h*T͓#~ } W^}ϵ3"ر5%3M7@c#P:r$;V< Gux!{@ HZJ2UUD$~ΡCrErȨC|6|V;$ap8f9Yf1tN9oDAA Pnc;w웎+?+sygP!"\-PEuj|]UQUUU Ek_OokUvTT=r)<ݮVH=7Fܗ䣷[DUŁE@|]s+P[ʝ+p}~)\~M\wk+h'ү^7p~/2) L;BC\#F3ӘyT,]ƟOzϷr3{8Q^TV7'v) -ࢉ1`tUfde1xH.ZĻӧ߀5 wqW(푤:/Zn-:-'y]# Q%R5.&TUK (ϲ+to"DH~Ϟ$ͽ 0ftji)!\wI4'U6c | &\WY8c ߂)G8*6q]ezu(.^>!T:$fd W }Q!p\`JTl|xJ ėʐr>FϟϮLGEeyXQ|=ījQ˚y#0Z^}>ܵ9\?$>x:9&Aw/\%p hkVnz&>n TU~5rd =Ӧz !(+*8a7vy<~=|tf7Gp"xwLw+3B4=g=x5iªGy'WkLonp`FvvoHRY#Ք9bD]1.}m8pW"kwnw3 :rssS@%B*D sJžL|_|ʾ*CU\qRH$p;~)n+DA<=+S[Jc'D W}vGLL#qbKۑvlI7M, `rVu"ut鴯,Ĺۏqٶ׼,ş`X'L2.o@ 0Ki{w Oc $rqhJ'u7I\P?&X6ntQ=L4y GѣIJw7yPiɡ>F@5 =C{ ۑT"&wd6AU~7Fq~J'@HN/$ܒFLs8@cmRn:I:$֩ ; ;q$0oW'"Ȥ'vth1¦(Rw]Ujl񥻮*дRu#ybuyo +x4un_Uc}Sw%i8z0;]&}KI k܀Auunj~LŜ3nvn~#7w D)(p:}ˊMR~=-~[F<^SQUÀԽ#{}aPJ'6.t޸џdK2Z}lg>̒Om'rJx0 /Manu^{MpK!c,M]uu!ɉ}sLyf(TWWշmɚo-iȱ>c|8DNPeBM W1K cb2nӹ{ϑjv\9lKF H-$Iہ tpRq#P'*@S:i- @kj*jQR@X׳HuH'#UBn8QHс̉/_KX'GOi__GcQ@р(+(aW\^dy.^[UG󹢑 \-!t:nlh@]̒<=N^&M"cӄO>q92NWeU8ox+]p&]e$)?-Ox)(f靎[s52+&_Aq0~u޹lqUCawwI{ x>_DB!2nx(l:Zđ(>h} YpHI "-@q cm -S$HdP^an-!ՎINg%2_Ev@r!pdv?iM=n$bq\$ NE5-Y-,~DPeq0MXgǤn-#WU\*YO;/RHgN-NB2y3YQ"͏@9B*NVHivW@{8Q#Eq=,] wį%ۗ9v$ᰛ\|?R$XV/dᶅ圿="# 3;vpNQCb <7lrAono ?)Z%%O- [g?CELBpԫilu/QQH7hדc""y2z;/Gno,H:B^"$EvHf*{;s vR' N/vR'WDzMg@ -' Փ Xw wF; sжn#A>t sv{D;xNӀ.~'鸤YK2KbJR;~\]P\[l Kv[ƈ@ #O9n$ik;qm;@w}^nր׻]yM;)e9e=88;Nx 6Wc%\˖&Kz[ h pZA׭["g0G܉^%x.hi]jРN`>~iFW_ $pt/j~)BAJ\2MT5WQ( Q=hWu`i/ڵ.O$@`\B6 t%%)h$!O.A@mvl“/@;М&In>%L&I:t2@;%avѦ"ucວsu$J9+ c*(LOS;e|HRH["T/>;#XhD OL0Mۏ%:> r ؃ᒎ -7ϼEՋxhC86_qE/i?'F>kv1cxge1ady9b֬^_g0473+'~݃Aש~,w,GٳP|f6W[Ӌ%ן{e ;vpΎ4`6+f;:@tmT'Kȕnnzs6Z VORMfRדlH 릍s$Y>IH MQACD`ŴIN)%); foN'R.R{Z %XH/E;9괛4[| N6d|9ߩc`|7u h@|]wa瓌IMk omz iէ‡WZcu}m.L4#NN.,*)yJ,?9ҧ`szx-l}E_s3lYW:RZZ뎛`Ņ"?a~j,ʲj'29O]lp;x|v]bGTw%:w >aIcF34CKlΛ`P)ӘAUVЈX{z?%G d;h$9<9KV"}_QxCR~n$?H@z}` H:U:@ڨ쨼Q0X_r%R֮ `i0|8S}>Jќӹί{$n sI?!ǵpVAuaa0stV699@S* 总nχ躎K [PQAf'- 3@fdt$!Nv 4uӁΠ^:2&AsGpW*ѐqѳ 𶯁nه7&)Р=xv;i` =Nv`vI[)ӇE/g٧箽^k6z0x&54nw6=A;9I>ܓc@&!iǙO-dk!zt= R ȑDl֯ɲ8?F2TVB4dƜT> nФ٭'^VٯFw9hd i1.‰b~5He"2,2GD]6+B.L}>;Y R)~D-!~BS~m3jHU!&daǾo\~l%R}EEPpDžљ*+ww\^xy1fIHC|0_ ?qpntܟ{84&%$u8vƴ_4;؇$g)..& Q6m1ɕ;!h"Hb7Ur*_ hVdʣmv2177z^uН_sq Xv篶HBbW>x8 F*(d.F4Ff |*:D,A4lƦ 5-QP-U[éRG0vq #VcΡb1*AE(+$G8g ۼ(J rq>}acd?-XksQ2\% Qç2i`8$X3/y0]l`k _5pŰ $korIOx|zLc1`gQY8tH"ɑ)W^*aG%&tǶmr)3dǙ3aTܘzx;_q{xɊރh,477$Я:ƎFk GZcJV$˫"|)\ I7x0mfg ágAu'T<Ælh]c SaJŠJ63x>Dc&u}k^z%G WAM!YAsei3l#+dHɚ&X{Q"'޺ fzUWؘCt8"J.45\zyG($GPWmOM,!f3<,_ӫ,rb|$rXGXvXy#\$N?CAVТ&Cϕ>^z#Lۨ /{XY~QqJWJ?GݦrYL5r/ ]~7r—#(Y*}a+߽( |k5ANأ|A#[۬m0T_A0d~_r/7Kµ=p̉pQGZyZ:UQ;9Ƿ?)Ϭ|39єGsmTVBMk;j:|`dggv@^{Ji!# 98!?BAA6:t < ~QmYnbeü7HbiHȴ~M6/nullR4SU}'JM$NeI=hLKbXi ^5ݼ#BL']W D_;NJE6O0`8׏S:ʧ!zmI48BͤrlPII}C-< ^l<^v@Ħš8 )KDt0P%? [mī86+[=leUsn)GoFuCDp +%}6ɦM"ؚ,}"QǯI֭ 睜ͨVދr,N*WYg0yJw"=| 2Bag!Xi1ar&WKfۼI+`__*C(wkSc9! (dg!a^[) B-lEiyV^0dR>pq} IDATaNyz( (ի[! !ZL1 | _v!lwMt%%+]]&Xҏ]#u R՝.N["pNɥ6ov^zir%eawyas8b=ln5/2j>sp3;iKݿ`髄EӰ,뀼`0Hcc#^T1d{-~kT7{ dmjYX@ lY *4%dIL2"[d6Oşag:j5'ktjmY|lbT8\CڼNe{VSz-o3i5j 4hs@(TY_a$/YWWNp0AmS .#쪷`M\%l%ld8jFP3UN kYa 2yow6!{7ym\|L邀LKK;zꎫl, 5<l0kK@SMtffWɪja~PɆ&ǏhCOTkPUonq%ȘLfDcCu!G icؒb4BEt"$^ݍ,Tpt ]@ 9(Hݟ:ǡQg Ŧ2"QK ٪ DT yMp &Mlbԃ9%Լ!I,H T!S#%'+cbSǑIbMu't؟HZNOH=[,Qj:i)cIVۗO>'km_CNf<:e~/e9) g;&Mpˊ4ΝL z:y@rQej@&Msq!wFxC<gc%>ˌ!3( q3?y'TVskqukYPYe"IZv,{eYhځg!t0 Cߤ尳1BQUT6v|Ŧ66r=68mBMHrdN[֐M/ٰ eS=MN=yɌQ* 4:`i2oIS2@S&kZ'{iإSPP -ޮ[ekFp&~ejŰ\X&z[^j,ee>Tx 'm V8}G^kQgJfTP" ZGQ,!~/s^m&: oV.ieq,?lӬw"S3صUgsQ= &?jjB/>ﶲaLm&|*3Ul7[\wS\ϕh_v 93~p|z"$Pf( D@l,4i!((0"OnAMFU o9|kJtq wXHݤ&#O 5b$2$2q(΃@DŴqt [YUpxA3]N4lyT<_b( jK11uIZ1\0hؠ#ccY#mdx * U:UQ5OrOȽf?7# LB9AXДmMOX"b֕j1nnՎǺDԤv<ђݡ_Hs=IH=NEq谝2ΉÊ]'quMM*42"q|(ZdM<_7+԰;XPX}&3Mxzwlmku)PTY9 4i5 mkXM] mY , aZ ʱ(D[ E4rUB3Nfm6u&R0Oy||?m:\ƢZet ڢK@|*0s%1TMi3B%FTU,[Ƽ*4J=LQ̃AY\M6mykka(lTN(Ket$CDmL6,8H bh?ٰ2BKI T.eD,8ajQ!ðX1*SaQ)o6imC& <_ZD$؆Ek'bX6ư$7daK a[8(L`BfaGz1;t,BY1a=Cp򵨙CR5 @8cْ¢!Qb% E6}̙`P_#Ɵ^K39vٴ輻"]bZim >\fⱙ\~BP)3t^%3jmF \lR5k)gc \HeaWحZsKK~4+4, 5QfLV-ͦH0-h4^0~LwֲBolot(/_kh2-N=n9ylsGw 8nV^u@Sآ/RBtOEvLX㘡ch2 LK] خ_#w-=`9RZ݌HԾ=ϓw^WŽDAY ~\G ڳ _KQ\63$kL >X`v܉455#l KAmnGmіOGclyY>t Pbġ6B}AW7Z vqMCt4F>"؆E8` ?²`6~DhlcgPj0e lp@, I^88-%6%hÐ!~N 6FXhNUh'MM+M1b6k4ˑc}EL,L\-aY!( *ō,\Yc> 3 `&+V`QmZxIژPegȢǣF7`a3c4ZMSC5o3LcpDwríWWqfU&)8(uQIԀExoa=> v~&Xn,>? 7u \QT|#G2ydx jkk1bG@t]wM4AGb [DV!@8kfdP;2HJkv؆Dzywir潵&{!ycKYw"AZ 6 Nce6?gI54h6m4EaX*fpYCa~ASO)MkaFD`:a,9c\+M6nrsI8ad{ɼ GAFBu[_1IPDLɔ1\1DE:CEq$vk5+mUaVᒓr0[ <,M>VfP?64g)ҋb;ئdpyl !n6`F6C輹Zt$l,á^g#5>2zֶ,uo~n`hoMiNMiB9V;mh:Lã cYl.\kR\b$^U!^J ךlX5R7-vH2s-VvN6S-<5i^ӪJUt귶| UI߅&5 &:nV #r$^ r2(̀J ~pKvض=IR9΅sυrMc^ɓ]ߑ%m)<H$1idzLS.Cǒԣ^L᧵EN&!?RX [hh3ٱ48m<ærKL Py+/ Sm*Q0PeOxl^fSŒ-X &ay|+Ä [9F)A,\ϣd K b͆1m"Ph%%Y'+K8C4|1-Z[,qhkxlbX R;LYXJc-:BŏMX4ԷR I~U+ofل 1mԄ4Ѓ Ku>~Ӡf\#a˪- JmRg 0"_ŌXuA6@p:3o[1LI?*&Lmylkv@7,l<%FgMułLu^i?M2G[xvI V{>~ΝҒ,[D^eHu̙XH@5yڿi>@~LIDyvd6ױ#܏ͰmuO;At| Jii)555u @Ob 9aKyU]s{Ӌz$w 1@hL $$_i[#f7eMB $!ll{e˖i+Ǜuƶ,Ysy{T#8V/j۳+׶Osܻ}{yw۾]m;OXgEu<ݼͩ xN7VyK5Щ:;yH2rߌv09~$^i-Y/g@rG~6 ^};uE=L{{+b=3$t#ٕ'ߎQhb|}'7V|*9_hKC>WgMu6*#ܑd?P:]ޑS|e>>/U3y@β E7 gڌ /)))fĝAJI"a+ {ov;7>FHq,ٿ;sMhp 8 (Gϭ4\- @<'PUi&hp" D",Etv&;;qƑE z]3frFKY@&&wn?~_1~2NC$FvOũ|zω+8Wdk:'GZo Pn "q:7V;X;pd$#)>cnYXnV4BFMpx^~?YYYiQRRBuu5`0 N>o<@MM 6l`ǎ|S1/ Y~@Ĺ,{s  E! j!8 F>6J4EQH+pݸ4O 9{94F_4U`6pB)v>T ̹H&%KUm< CARbfd, jg<'rc "X ]בR*N ŨQ|>38:>,?0O=*vۈ np8 . (---t( ٹx]kk#']ץ.vJuxse˖1o<شi۷oG4 5kV/ ))"uѕ @x]ݘTUrBdeeQPPqY!n)7z!y~:?)(({e޼y~s=466ziҼ @Ç HsK {6P2qt'6(qNYKo)n8QQO@:0QtNz4D?PÄU8BXh6q(NN+K tĭ~Yoۇ| Ԏݏ 002ljgFJKKGdr CII @Z[[)**J|455f̘EFL&aňD"a۩D"A[[[z}$!ݘ}>@())Fx*inWӰ][w[/⢅th!0eΖ ֙R5L5U9q:h| r.˷{n֬YñchmmStR̙@}}} 0eOG?QZ&Nmx<\uU랃,RJ,:cΔٍrcJ2,tttyi^@ &UQXX)+ kП8Nill<?na<{yyy#(HbJH>&yv!%8^b ofo{;1k̾^rjeH3N: _v>~CG`hZHo?F̦ N6irh=y%8LkqԬ*U$, &H J*! PHЁ`:2.ASHib!,jXV&ebY TCJٙ%EU1 dæMDqn:彵xh'``({cuT*? @ >6m󗄞*xrKB555?~CYYYYY;:~aLĉHaD8|03f`јּ IDATV6Mt2zEQǤI(+SOrcbqLL].W7.D0$++\***1y^VFv)((`Ν<#tM̚5kXƶ6_LUU;w ? ë&uˡjk Bso U& TG=;ndƌ}8Vۯ'~kBsy)8Jt7+od*RH3ƻ>K_e+X*_W_ _'? < .dժU\r%Ê+Sg+'Naa!UUU0}hq;ln HHH8ё&)ph RQ%;m#zee߻E>Ka-+f[ [[?­'nzVoGusf6mX#i׫'UT_^(I`О'a[C*Ll^ۀ:YNH tt,a%OUHı>49%^xksN|b.Ew_>&*_?D^ģ1|=%UU6DQ#/74P5 =?%%)ؖQw=(LPty~;Tҹ?|n>ε%`$LΈ|uL0M>_HH=AD8NY]ݘR!]Z!`:'D ru;سg>~^z~a{7?vPQE&4DEܰh[ PBEH$z}^=L{OO)i gsrP5!XF(=ˈS/a]ut!& cX톉nJƔQA4nO.B  @# @ea9̀ >#S_Х, gZRDT8מd"5k*i鐮)+DʕiرܘN zj~B?𰋢t"ٶm /2s˗/nD"q^ _qiv.X9998FQ@EEPl̀SCZ f/{@G-Ga%ߺ%3ƀR]x̜G֣_HM`1Kdž/gM_arm8NԐ5I!nS~ )g;ؖ06'!l^G# mb`mI֣?39F`b "aUCS5L,|#mL,),d<],rZ"U^PI*-C5fa $DZfrF X{X$I8FKpE'C!(hqg?qE*2BU1I$TB=;賞 ^a[1X]| =ar$"$T)%Ҳ ;7[`)Nົ TpP4 4A08),aK 됆t{$DTzd;1LjI.xG  SnL==%%%hL qrQWWs&OEJKKϟIJ ;NF?IE{F3w>od\Pħ* niZQg .H(nV[{\z]Oxzs_MMn*6,TGxJ[PN\ nR2q.;M4u'm1\$PZ51x;1`Kܖ dIGWn311 EP(t WYϊ'dɭ@n_K?m~9w&9a7jp .jBQma4i2f(,ˢaJQb!R>Fv~gAW^?7d_ 8tpTUYOnҝ*2c`YY2#> |8HrH3f pCn wdfϞ͛ooͼy󨬬s|q#Gj.9?7g3 SLԌR06m⥗^ 8u$+9w l1cr+xsJAsj^yW]uI8LӜY՘uI A#p4W(}]>0ĉ >V8.̝;srȳB?Ъ(\:%d'DIRy@zUٻw1@ q㩨v1eJue@*N$C#I(Г@QT"=McFqJ Itˆ>9 vdG: @:<>-=߁`]GO ,/ɓ뮻8x ` ё4Muz=܁txqH s˪8fy]7`Q <(8#(999455!;!{x:u*&MJEޞugJuJ'p1cbba!tfut=rc,, B<^/M 65p&|"*"m릢T_w=;ÎŅ˜RbYIݓVz'#rszG| q#:s#eeB!8*:jX!?Zŏn-E[Q=mČ\,OJEYJ/.[όOG)Wʱ@N)nxJf_2+㔕AT^(< &]5~6Gz`L`<{n$| ҵ<ODQ(.6f: _N 1JwuJۓ%D"@$y<() 7 x2unְ exn m|d *i>۷oK/hCg:`MIa YЗ>GOb"FnwC(,PEuՌCm|=t_ | xL?֋;M-2365Fj oFfd.,|xTꕔʻ4tbEϲ=NJ %m~˟c|N~7f|$gd:nr߲w2uLnvW}%QI}v#pʠ+hf_JY ;,̆~.Ρ!+>pmt{oFG{{;-bҤImh@ ӏk4vsCD6̢|K%-PC;URs!Ml{|“GCb*6F`s r\ V%dFnۅp &2xY܋E#A"Q0<ȹ "uWծ@˞BTij< pgSER&!\ϭ.W.XNMf#5H'RD "4m[Y;;!gշXO1&w wr{  Oٿ)*Xv痹cq{׾ů{o?|:+8QŎ̕>*@s!Nt#„J{ gKOC8]li& SGF%>wo6iYD:ѩi8r־C`k0mTlץ.VPPBO\lj$Fj@A9rAiG,NFj KVtn/u]/+*_'S~roɀQw=I?5!\&~)-:B-7YEvTZojE=|+C.kQ#Wc]y=˖{e31)ɎCy>[+`?'kȞ|)sf^'!Huē0SwKt*V"ܗ~)^Zjnl^o`eLҭxsr0+7gdH4$;{GhoHQ­ECDbFըJ&N(}@ --Tv&^ -^X9awYqK7z$Dk1Z&+I)6^&ws9]Qd]E'INnߐ v*i= pπ!4gǙD{RJD̹E{O ϣgvZ#lt |ò,L0MDS8>|= R#;/EOgEqCKZ 7}inV78gSGu:aln+(!ϙ|n\e GULVI Ћ^E1̘M"UJ*h%8&or]18s\\AGC=|挌<0: H$@( ۍrZ%Q-p †lK|sNЁʪXu^=S(/:!)ь yMpFٷr!эnO "'-+Jvٓeʹ^t󞑴UPT6B=LT~r^$|d#< wѩ"Wa~m?k̼js+\5$(,KL"YFBEjwƋ.}^&A0_}Ll',fG?C/gqߦgQi 5ԇm-bԄTL%TN7Zn"1~4S)4:bTy!W__=\=0:8A4as1`U?s\9i8J'q*#-|ssg 3P͕=$ȩlW HG$º)e\E!g tcc;OfnӋu/N  :",K0LD yNIFC$J508H송H8'4atY H΅B|dPQ {%a*f8N/eA>FSN978{PDmo8~ >wgh̨ydcH!0LB- nNj[eZ--[5\CaqNG$0ܡUUx[t x)Taa%W-Ɨ8-"o<}ϴEW&{}/&xq_Qė>L-3e7t ƔswM2ݠ_TS@HD$Dp$N0; M"z-63w_ ٛӖT(^c'#;_5g,Dh@Mh6Z9x~=mKCTof9 {:8cYʼn- a E԰m͍Q\.B(H$-ء?="'<CA Cn*0ӛj̄̀| 5~ q&S{rfw#bw~ COLCPܪJ  Zg^xkΪYdU[{X`S_Ga[/=,P8}7熅E :#%^xnl>ƕvS쥔hy)=v3;kaKK)aw2ݻ>r t/||fc O!ʢڍυ7܋Y 0=̻@=_O,t37j(9|[!@2rx$ۯjz#GJjq<^q K EC+qi;vlAFJZ㏿IŸ_&䖰h>cǒ(nj1]fPx*nk\<6^Ͼ kg_Һ}㣷e;t9"` P.ۢ~ T&vJu&& L* 1 ߁4utBhrFӕAI^^.p2eDTMнv瓩HӔ T 5t#˞g/Bruo+9p(e|\< \U/.S9PU_"(o<(DnV&}Lv3/W4\Nj9ț&)?ų1)90(2}tL 먚ӓJ]'yV jMMC/5x+%H$n 4,y}F;g8,dVzO?1bEA=|KyY6r/ |DxsUv Dg_2\=;B,? o3fFq KӓΦvl>Ȳ;Y6D@ ?|겻 r^\?J5Tz`L9''fIpztEZ-CmԷfetj }s>#G8^@$=R}guM\;E O<#tt-YU.V0cٔ)1rMP7+=g l0T%]5 b` - VRV n$0"--}˃P!^D^!&|^ng\x՘Ƕ~|b?v2HSq9=]3@$phob[7x 5I <#}`IoKkxbwᱧ/܀OH3*P3p^ª 㵗oE*W=_H&w~[+Qӎzaۗ|FXh*™ǐ_6Ǐˡ 4fV-=J 'ᇿ7箿?]d8iҼ%nY:knv7iͿcL&-s0׳crM(BAa!cFt^~\@s9]ϴIe4*`[W/?|1o r3sFN[rrrhooO%lp0* &'lVŠ]b$іfimM.y'T Ư%hk_&+`MLqaiN|eӘQÚWĚZK _,3Jor * (GPr{0$ v҅N\(EQQTO &ǎ9Xu7-ΧfFtH0[ǯ r[y5lޱKn%;ȉ!%=OcC #IJ>L=Ҏp!{^Վ|iQ)ӇQzg ]W=f{P Ж';Xk[7c^c ʦQ7 $P${-˫M-(u 9^6J]-iYz1+ͧca^}f;wW~̜5@YIz6Sؓ;Nr|鳸opo,Kb9QXJZzp8tg4Z?RzVg jeæ]ĜY\r5᷾O~G~2x{䇿{ 1ۉ,[uŴxf ?^aW ZZ@{zfş廏j{pT1#(ԇ$c0+=`(%2M VKӣt,ڷ^wӶiX|Wμ/?utf-|'o:*tR:>>>Lgft`L??2|NJ  SAF%px.}*+ˍͼE/L+ &U|Y9 f"A)N`Ƃl`pV{[ cw,u+?{}6_ww䀸3EVr9辎zK: $L @L̴ P},#ut8+PZ7QgrLj:Ź\<](k8_ XH%ʖA"ᔨD4Xieڙєa$'HE'hnoRt^&Cj?92ѺGR||dǩy.X1eULZXҠy*^ʯWp'Dƨ]Eow3;^[[GC<啼M|ɔӵfW.;_|7\:0i~%cMg(ou %nBuQ>'UR8 Yzg=n/) z ~$j@(0A?{c+<(/>0oGd {Q TTnNT"-”&.ʨY>lΩ1zL-6㟆hQpF,Sw(^?C44MCUU~B EaT$n8@VYYhob7ucj.3.XKgfudÛT0'Lusxaxy0&'Q EBQLOyYY -7RCe%uHJTϥĜM* ?>lJ q*nUE1;ڑDN@atl:)$1 &IK|BOg2W{MEśU=a# t! _?,K)%p\ nRJ2icf?*$p})65(5"2@q$ vDh(vKXdT\UCszQ~;ab[dLO ۩`Zv{>BKhbD>1P@dB(G4C쬋x擷T_&;3r˦Lx,7~j.wp/ma"y9|کLm7_;sץl,+%2ʾ@w،{0L]آzj^wZ%7q4붲?u/)*,<7[ok`˯im`b687vky =Kn'g=峾GگC?z>}#c=N7qcپus@ J9VI w:H*l#&n3V:,3mB7x~loq=TLvU~cɅҁjsK 7[kٶ`kRKNܸ @JDp [ճ /Iv3ݰ&'AI(*g[P>J^|y%k[YzUӪ3WI&QcpKU/j#;5O1ɦk7︅j: .\.܆k;170`,O=HMl:+(yȠ3 BC>3t ɐb\D׺/x~.rݕ>tN;\'nS`ңx|;o>/{+',C?}/N>sg?I;O&t0=-ɶP"mJZ7p_xf6~MrG??ˏW_!jC|wsx67ێniV q ֧[-%`Q n0Zc&&ΐʴζ3ԍ`; y@QɝcAmx߂qߋ)ypWc9$ݛwT.P^U[ءKN7m>'PB`ξ^r!#Ny-Lrŕncv0)nw+!'ˉ!?tWzq)_"6Wǯk4.n@dR܆盶}ѯ_Vz| 䪖m\r o?w7]y)gJQŴr(PQ{qy2BX%B*4ٗ]YI]r\4STR IV!²q!̏@裵B+5n*>^u8Y|P8m1TJ\r9\r9 5BJi4(FqBlL{ 1לNS&/:_{/,aKxW~-=uWN|i.G- |^˒R㎧ /_Yn|X70nu[ @Q'H3t9:`ED% f{/ "u>W^IЋdi>g[F''MM}[og!6 u!f ?:N*~\ZYvn.7X9?#^[S*q9R+&e44N:K:B*J[W?v*i OJPaDqh2ϡţi?6?z^f@/jOMtldNp= H2gu Nfkkbk[OD\iHRJlz%e7Ї#|9Iڼ <3> %FH³7/S14E{'c;RJcsio͢TTQ@縊WmڪT,ݿ~)hWGf`?CTT#:|<㹇X$~rҤxgcsg}L#SZ3ȳw)IZ_fc++B1Zj` `f Yپ"?ZIiJMۤ3)T˄PR)iX~ϗ黎m%c3Ͼ6x?\f+\N2vM?f^_$m_z :x?x}:9}n!O+ |( QIe2-[N1Lab̄tS!3S!bV[Ӫ ]/$ 4m+6lܴp3lo[[JI'%ظ6<.rKG|]|"҄ Ж͕gپ͜Wӽeoל4LTP?N<缳AxήZ2UlK.<g;]S/?;JhT)4!(,[Oq+""cw?ɧnv /B\Dd 7^/5U)LQmD<`gI:mexEJ '&92&P p/?roW\ǫ=( >WUiLU$/r%p뾗Ю5_/|+Mej(+κ9eZ:uX)B-*` x"AѤĴlTTTlG7݃4e5S!GFCBEwK yg ۡ- PH/Wye%qc_NDU"AZ!v0!!BkB!vRJ.Z+8jZ[S">{B]i@:%FMSV@48n䅬D:| _v6u~O nmOJ-*B' @!RH&m)X ?4bv.?9nD)h8UavsGҼO2T *.V"~f{퇤I]#9OEbbܮW(ml'SQ,ںIgq4iJ΄ cŢ>Mۚf6v8wo pL2> [l~J< "qlu,ִQ N V&"BD|[eZ,Úr_^:ӏ'f&+᠖NLB];*]㴫ĻEϻ :LCw㫝!E *l9UJqzOZ qicy ru92\qׁy>QF>c[{~~Ï0a0x3W^t%<_`CWD 1eķ>" IDATn̆.5Wt JT+It6L` IݐXI.PM¯~ΩoV̿~h˼,ߒ&[^n^xk54L:v[[ײOX& <w?-\uPEClk#iAבov52tХ3Il8x lU>S_Q1n'iP[$=0!0 qSYR,N%1X,\?b.1P`t6ttLtaHά?pݮXLDJTԊ 0S&s%b1:fht.͔KjlCaI_ H J&C9{yKpYBmrђyKV+M(\_WJ-J֣jS<4A xflS`Y(Q& Tq* 2ElXV돻+Vܪ; 8uJyf"H]̀Uv#͕P`quTH:ՠTӽj˯/_- _^y_ā{󙿻&_{el[7tLxXEb=/7S:EϦ~v&gu|3| ۺ_}\ b8xK"3b5n[3 ).&(]Ct u6<6zN.d}Z(+\qX+*m!0LIa3q*Tk}XN˲٠*TDPEc3 X̄դB1M_ X\s`"B!Na1XQVQ|S r" -H3,۰P31XXƖCjH Jd3/X;ŷ#yżgFU3)4PXR(#4 e[u*:`Kb B σ9]WP_C!wÈ]+Q,3*N=*>)[$ Q8v-}yuT$A@ ݈JsmS+ B&{N6thP:>yk!ݷC|i#ss,>8xy̟Π/zVv|7_492S\xGGo[M+9c7&5?)΀"E>0KzE2HWJPIq[HiةTEv5)V,,;]KCr(tQ .S !cZ12?1MPWm \- Xq`Q6p'z0f[6&%O>bG{MO(6ԘeB |%ShPhbڵ Iݒ%4P@HJh=ha~0y& lCcʲB8gk cxۈDEBc{^g$MN¹rBWz|DEW/6t GP DUh)rՔVQjDזWmjXoSL{@պ=9~.8={ )<4Kk'$"3OY\zU;o~K'˭q-Ƶ˂2`lY~еwgKȖ -YTx%6cI<0Cg[[ u!4H)e {R*"=|(bEZ40-+I<mةL֊`WZ_ !ň0T؆#m.%b \ nl 2X,P$fԢEo `ڙ4:Rct矹Gv[?H9`hs$os0E;L"W-L FhV|SŏZN< 'Z \ !<>)[iT@BVB!AGN mmj ?V CPBFx 0gTq鶉X3zS H'q^Ð'*ajTyMo}N mVS_f YU6(e/Xm)wrU6&> a5o8oi jPyaB}C02X( l qT0I;3HB (K(RHa4B+숆 Ph@Uq;HCPӴ2lY9 %Kf5W"Ma .C zh( MRN/4E"C8.ZCW?7\\^o w^Ƶ92Jy%iXR`P?}']w>n~+y~HTX |7j#V(ûCse70TLk ƴ \ D X"fj*lLlbb m)MOfC0os=mImB,3pmiqE# ;1r"V-`7N1XیlK&@֩t(K( 8:I _3DQK@#y^zkߏHٸ*>8&dWȨ1j2 yv;⡱S~6Q\KÄQǵkEkLA4Vb$" 8Mtt8% d:Y~cS@zݗ2IZ:RVcj|uss\NǴXw<B aPWTQpZH":ߏS2"I>qZ:Wb;g L$7>c+ZHǣ } x`Auy59~_oRdtW*@#hmsCaʦSNT(ByeHJ)夰4v:KaT rP"P~̼WMbDĥ[[b;m}6hO4ɃbԀE`ИNXTT QҳŸB]Q-&I)QZʪ)E E V,X 4YzԧaE$g+羬HGyzloG p4Ze%K=&0m($; qŧJU* r-A){y?^O2!Z\ V G 8*H ,qs-6LS) f\w~l~-Z+^k<B/wﺇ _ȥ[MLx#aQf?sw ?=ėNސ|7߰6,>Ηn+6 {b#-JO#pa>k+`ŝГ6.)`!-gm܋ps(_ՙewER>M>>ћȮ-y=kS_V+BybEh]e:N*ʐ3J0+fE A(.SeIԴ4ݭ0ء\0 g z[ݷ^U"XRjFX,E/,EÑj}WZ5gMD:^ZDqJPPh>I>'Ko+wy!7]o0nOQѭx x]d BQ76m]:8w&iy+ ~H`*U{>՟X:ex+|[* n1^"aXN*t~Sl'5D6 ?P^Bez!b|.V+ƚEKJq`p/ ڳ I0(X,W1=(/w)LgIBɜk2QJT,F j1癔jѸl@M֠HRT]@_UIj^42sWMSN\T Ӯ*Ye%54X( WQ)ȇYN H;bAZp;簥R Á͝.[i)B?Veڴpab)%cp+PT|}&i)NFttX_~i!R#*.w :ֵ ICr.ϝ>l|AŤW|,V*m+?ϒ6th`ʩvWZn飀4J$Pqpg~6gg+ý6& x<_xF~ĝ!)YA4_<]gQ`+~zIG,.`wAZ*m]7 6wӝL7EV֍$utV9tuuUk_"[N*|׭4ƫe9)T';ƲS48cECEX,(bb>!5-N 1X37EGLtWt| rW\;XMV0”xaZ, qيjQ)k餳6UՂD^̽\,]*%ka*S(ihq4aQ $#yZB \"80ma{((zC.E ?9h90e t*>y2xu)9Oln|>W\fSϸܙW K^@sl\$^m#.~s%wQæ:t0  ~)y}&%?fg5xkG?U#?zT|)W'n%>C,]?m'M7~Nh^7s#dߊ`,6 6dS񹰨 0k7rϬSaqؽw+_B.ڼ^Mڗo9쾦i't!%!hs D H Pv}q@}ջ6lHN!PQD$ W,VmE5:HgttcҕRRE7TnXHb !sӋ! Xtec}pnk"cKV;obQpc8`.egkF(JRբZբFԨuu\wRsE(M܍ > Ud"S%jVB?$R6f%)4 bYwLJn!%@y #N=-SE EEDA ,BdYɎ+X ◮L1Eq"c#Ot h+q5d̔$}ͿۆLa=|@ՔJA9f;bC]3-bԘGԗ9ZṠ|%Dï_ 53!" G0EUh'iMʂ6;1TTCǀ2@:uS >+]I'݄@NFM3Ď=CW\G_xk^f<̓gr\dw>{iY7]fc>c9#C*cϼ4tp=HJl)+S \ˮiKEq嚦˶hh?}c8Ea@{X]ṥJcظ-i۱q;ɶ=0TJbեBi@TrY(*"&BFgcbb Chb Τ]b%MN{Eբm%&nR7ZLjq$xY$^XU- AHܒK9ˌ,MZ*V[\4ㄋfвqL)WkPiHB A r@9*h1 r<}}}::NBr(9H(⡑'ncY`9oI IDATp4u״pV]>udxnǣ.WriU'B8aTMR|\"LCP֮*~gSm9]+]ljm>F/xIڪriD6#?y1+|;<Ɓ|㘁m[Kb^WnȋoU oȒmϐII`e7e7] ن۶RcBadM(t7U=2GJE( vv:C3夰rE(WT ] b\bb)XdMgaS9#V,Z 7ɋlU0SJ>'] *2VRv֒ҳZ |%(Fk1R UtLTd {"pUE5-8p2ҡ~} 4 +MXpd`ϰ;$[$=mt@&\WԞ:aBmE%ZZxkh^16Degh!s>bDF*`@QHiBEaU3B>sd"Wv §BEC%l7o:",):)]kc,/1H"(zSftSl/ ֥O*XKCy3 xn]|>CmlM( o9?[& σ+"XH1!cT%*Cr0L3XE,"T"NjBU쀝݂+w@-N\" pQ1p&r:Tm<7,z&Sn(HZ+DQܽCDD jbPb ^7\84KI(@E$[%${6HvK H$Yh"&&,\)1CG@\ @%SsvF<=^!KXBgitNBXcS||Fs#"ff2\fM,gKy c]- CEDfz! 7qטv !+[y-4萱xQ 923=)ig1 &C3lT@ /@B,aTI);*dMCD +X ='PDcKszm)ܝ c]Xq]q(i.d\k*E dTWTr ĸ- +T ݏk*BB$]vuE*BKXJ |l\LELs/P,:Ŏ.KŞVw6Rt(&XZY7k1ZQ-JsA)i^J!44.kG#5-i\) UX3\2DmYTy7Slhml`gXrƐdcUN$&>^(](-CG02>CJJed}b>%hs ђyb3>ť >=U"?Z 'q@+W- 'G񖫲"3: <;lwo(,Bm#r +|5]O7;X}YMI^:|)ztx@LWF [$#1޾*Bq_H8*.l'8]%HJ͆"XLjl|bD.Q,`1:ᲭvN±`X e&n Jd7.،-Fb`3^q-rI_lm:!&ע(,/A[{Ԥ=2jZ8p4bnZ궁4DRL0)/5d{dװdkSҒ6L|a)kBG<5W{'4 4,n\X3/ MOOPwʲcc10%ghod|[]Ǿi3>O&PIV[P,Fȃ.bH!/l2 gBQn`ry6.N쬹+^Gd&%,,M{ Xl\ X%`Q.-t\ jieb%<`jQk^RzViը1\l&K"W-MLU?(h<φa-eQe 8#Q/v Kv  : NϰB]tgXxt(#GFɎ6;( mm(@Koc/IA5 AִWnl>ᇚ(PD0Rך5h{A #?](G<= k~ A|tg"?⮇ OFzQ7C<YiJclJV`V>mE`>U%Ӿ),+J`ṉ"ebN,2mtc;iL0*Tu[V.Bɫ+`1Uv\ =1Xl7WL2ȴ0OZ,.5峨3qt4S"V-<f`1ZERZKT 3 K( 0e.D_n2M <f62(W#H;'%Q Q& pSpEOLpҳaZӥ"T, 6E$ǁeXZuM-n`tRJ2qp4Lz-Ɨ.h\ajTEW}@k`אdǠdcUIHD&>&"*\SGF1ދ)b^hڐqjT^(@C2?DMNex[;sLq =r' =mi {'&#qu6C |;Ǟav#u'Ӕ'Sn+6 Nx"U/HTF*Nr@WIUVՉY5,ΏZQ8ptV9m{;4D'TQ>NYWy9u~)Xz8ZkOTiE|%] ¸rfRʴ Tĸ]SHBPy;iW X(D,:bE N-I88Q,XR(qa^M(4+dd1TMbh3U2sMY5SgI.W-(D߂%`.VSEX{aIZF5v:ѲOs(3$[%֬vLeEqzor sd H](Y( \h "1wh>=*TЦE<0 d3mm"8!./`<̥g]ϖ JS("ͼ<8ŗ|Mog/%o=8hΰlvx:f:N76? % #,& xhS"Dq]P)IJ l 6'ªuUMSƪLSՊ&h,pMS׫r '8*5g)x _Ðq tc.|Ub&KƲyJ)_{9^bN*B IcҴvj´c-EcBA1_KpXp,M[Jws"#*MiM g,*Ee6)=[Z{&Ӯx5VZ$[ZjDi@=H)Qk[k6s2' .( Gzĸ6rJQ8yS`@ ;%$%]T*n&&^$ET sf0&X^,,"\G!DIwRΒ!Ild^ޥ\]P1~>ZZ0<64uiv.o(,|7󞅀mKBLKXwC@~Wk  )%:Q~ieYyȳ5k%NIij^k %S!ij6-,N^& RǢh*SU 3KƫIS+XUj8٫8'r^^KxcT qxvԏS GWGB~,)tu1dhgj.E߱^I˥yN4/CD&Z'ˑ}#IJgC>5„2>4_O?͚yBlyEy>x)IDVa|ArnlXhaѱAP"bY_MֆcZ`10Y)p]+JґMB'%yVXHӔ5 ELJ5YNXk(x^?PPPmʉ$J̯'u6eftQs]Ё4' #{`"$٬BPq⽨ SӖ8eE$Yd-Ak4m2Հ -Zha!ecU>?ݕJ|l hw+É{:&2|2kC6xrA1Q2aJ97f5G`زž B6i'E 0+ٛܤOJqejh'Sijߖej:8&II֬GS Z`aϘ{_ ql-N/xb SsկAJ@1A3%k^X$k}p2o$r1N3 YTs,6b-\-J(f|뵘zNE%\Z@لP4M ѨS0dќ˶Ƌs`]P 04wEgQ뛺Ywv֔F%}]#TݷMkH2cci8p!#LFyDu:1w'pfyRb=h%BX~>REGuYbEa cwss<~4/yn0$Ǚ!kT+]|v72_?DF`a#>%G1?y8:ײP C^)m:S7ݨx1 ~2'+" F1<'`r`^}IxH@&em)j8||7kMJΥLmiaSZjVfߥpR1G_X+tu~&疁,%k\PG(탊n[|O,0S*i3XTRBe,F{ۨ/s#P$}2b LYlZ(aZe-ѳTCI1Xf-&ӬEex-f- E*5]P5 m$@YɤN'tuĨ[X6FҨl Kom=#m$`/e/X{Q_<;s&^!?3,ZGaLb=d`d.ҬVeɮm *FƩ )uYQe\?|w~ci.-ʷf/W/R 7+ho&,J@mۆsc_{Ξ= +jdlmg,km>d%HmBDܤL-Mo혡 r25w9>(6[c |l/mu e2%- `Fz',pN2N7E\$ҡr Ua!X4F)VF6XzZLU]k4ob;-T6b-LoDG׈MO%Q+&޸Oћlꟓ}^\tj]8.@@d-;sP01&9mYcP2#lQ$ 5ϔPӳ8 {q4]gQss@V(%Qe^88 S!sk`wl9Xp|0b a,E%ב} B<4<l&(j 0 ξ}8GZq(ξ}Qd>>߇z6R[ n5aVeiB H{sh4o? Td[K|P->]%#5x v]ѝtUBRJ݂kĭV)b2ՐDU<4X^FiLX +2(Rhd<^@E+˱zZPq` c1\=H\,RMN IDAT X/)єF5ً4ʅ.`ψ`6Łm5,^FeE.-Q?`ًӓOkˣk󀰂iiacePq8~a^`Uml6n;OgÇ-q(΁m]]DZG! ZcJ%t`y2ic [yঽVѴ05iArEٛJBk2 [[c닗;rs&FE=-̫Gr8S$Z]uE%6!jEi4rZ$9]TfL# SK淋m"#nx@lxtC I q S;\(XZ8(- "CGD:j^L✞T!I4hc)Z)+ތen`$KFб]E*xH fY & #ؔ^nAwpU*fc<]?|5 "V"yFqir64*M{0->*;jŁmVsX0+ ܌/YBDB>=35d&B-{mx/I6ˣ:Ȥ:V=ì0Z8Fkr/zx~H#t}q_vή]ȁd,lloݦ|Tjm1&,uph\P(P.dHŃmSD:F; (AƓ1~'/¾} |2(133Ӣ`mm;Pi|g)Kj##(c:"[兾uP =k/ Jj{*AMV=T=fsur EbkRXk$jXeM #CYYQ` $mIkÊŲ]w34vaovF侧2]e/ ncŝ_5H.Þt~U rG2 dJ-]$F]b#id ;m,Dz( ^^O\e/ {1=\("U5+ir( {~`Pg#UbH@ ۇwEd/̱cxnۆtmhӻMT5jx#<ڶy0I|.)b.̾Lj<8n [y?$+[z/4 q;/# xhLbml=,XM:b- k`-ZgmJT4mY rbSk"UZ5܍Ujbf5 \Ao^0Xv*}ηcWx,F U.EHa#|r;%wxEnx*dX6۳t;6,D^΅.yrkQ=MEǣ,2_SZ(2v{%KĨe/FF,jQQOYB'鞚F!eD_. swEʣ6bE6N9+1zTo/޽d!s%d#s Ύ|`DziucD87nQCR@JvH)q;,k BVq`Xf ۭmkebCf.tغs  @2U&Ey,ojK^وZJ#7l6d=Amk=2hm[^둝$2i ՝ޜj^1yV+O} xz&h[ߒ^╻rߒ! Ch }~w\Dw_Ǖs|:N(.eZFGZHqEihknqGs LِR nM'S'j0f؝X5vOZYԾ= 趱TO%z69*FJ i{ql#9^-kD&ދ;)Tދ70ҷR&u.ƆQqw"s_wݨPhF֚0'N&TD ccijskLPZ)(-.0P&.E*9.o|+__y-C7e}VsTNja+y,9Unz%&f8)֢?-m%^!ljf+AU~A{w˄֜`o c vv 򊇞 rcv{=y讆3Ϸn,w 'G%EJ+Ś]8y|O&r(B=Y9~'98ߺ{ 9TT骦&yt:GhYY Zۺ;F)= 3bž1+9$t^V!X)B-EZ"jf5 XF$5id2'ʣ6b3c2k 9-CӮ CI&ad;rw^!MC1>&lmB2F:7|50X„!0GBHœ4éOcW_ˮc<5Ԃg7Wd2k׉$2 QFJ [e[ŀY@GFb,%o)YxK„3E7rM[I1\ul8M#[\o5J&3jUS 0(W+Dw\qUonyh.V,j^~ua\qfG~ox e)Y0BSGXYXk `dP_ML?G{E1>Q :0ԗb,VbLd >Safy^)C4_˓Ơ@:_ l! B%Ww^06h{Ęd`ۀ ȥJ""! bZ@XAOLXb2a/ff JuE^hF/:Oak9yL9ِNJUa_5?z!DSe! C2̖ }kH(A9KMrUe6uY5.qq2 1g{g$tnF!\X6DTQ]DYE0Q {QC*֓XY{FF`t0ڶґlkETa܉ rG"2]?8Phb>wfi;1ku&o1\B8{בqxK:S!Z"DW8 { 88(l6ŀlm8&cҝI$%'⤌a4~n<4k\{AUF1ȘL_M#<3͟ӗocY 8k?q2uTr%T+1~`EX7Be|:`g'ki{쒚>ŗn.;k]ЫI~abSH-xvXz ɀ.)W5oxu(lSi)MAAH c\yS]l(=Pb> qou@bS ]gfвa:qb14vo4nF)P1uۃY*HE1dYn&,u(A\-.R(f<{?J (l [vdƕ,.u@^C;V",pȈL XI\~铋B]8D ynO{j1.iɒYr&G,gMCY 4K(B4 Da!VmRs)CnɳۉП8=cu_7-qs[Y}]τ?Pmwq3JOē_9QԌWxހ';Fw90$ 2QDA\\'c_x(X/;'nkOfL-OsMs7Уzocj1V-G^%Rz ! '{FlrĨdddҺ"A^!CuKN؋)2MbQAYa:VJ"i: Q&B?o&6m2.;twnࠕ5V7aZ7(g1:-[c 2T*mMiXv(ɓX$Ȇ,UIu])aHbSgf°)j֒gI)®*“\}e%梘DTc p?s|3!1rɧ+|2` &ßuT782D4HZדF%n`dbԚ$^AOAHEDA|9`"jXZދ8^Md/ڰcyskJGnF*6] =kxL;|wb55&+)9z>nz+T_qg|AS&ZYYtj%JtBT)kLڃ/Q_ W6#!fsˑ[!lk&">$MW0.W]q.Wvt_:(r>ͳ{_xd}Kӏ;~\w0i aȩE'4ggXv\o XW Y-& prȉTUTd4}wߎ_ddɿL/dp 8H B* ! E fRi6a\ؐZ< 0 "V<.3RfJ*I~ew3ems\L5χ0+ u9z &7ICД;]^e~k)׹"K!&4Q96 &6g(spo_1ȝ'ji ;IDT>(Si e!84gƀ_[}D"H΋`t@sHwD11&;jƶ$6+q<C$^EVGN5؋3gPStO%Q{\giEcs-r"udGc랕tMTs0h'&p^ግ!6cZ);b0 c%:gT6#ZyyHwssAx<_*E֕g0p6G5tۅ)QRP_*a2y|>Nd`=o6Muߖ}k;oG[5 J9 kq{G, ?x6 F-tӕ]dؐTBmq3&E wlBSz8;=?퐝 /& ϑ?'ɾƍ*vM¯Wuzz_P^(QU~FoY8+D9zd,il\/y8ƞ[P#,L EY ؈Uv{^(lc{4S_ѷ9 /,p>STb&f4gO2>2sl32% 'e 2Ş}=1Ku%>'c5> HjK>߽Ư>c 2υ)cl\mwщ4/lECe{y^A+^Tř)^̠QhZ%EXo]Mȣ$A :n')$c;0%s8۷#{[ZFoZ ] c9a1{rWI}뎍MπTȞ,-!`e%(VRt"Hz<˰劫~T3J׮\2 J0m mm/2r Fj2%߷^~%lSxyffyG{y~"yot3?;ӿ׼ \%#Z1v;8&$ 12R-FY{y!Ueϳ'Ou \i ot6'k۾3Sgxկ!bW[ύ`x ac( 0:AFnLVe8 jNDa@G6V>y*6 lLd,q=Ec0,4i97ZX\uHBI7딗=8µVW亹f[3}Dוyxe//ҽ#ψgP|ZX5:{$b}U'37 *3 AXWz?Y/O^ⲗ_@q<Vp?_= (f˟s>J͸\gA_:;^ϘR| a]r.hON3 /u1qtA5?#BtmPCKe5:qE!aX/5ZbB}zzAc8|2 㙔Z㨄q)tu126zO$ʖ.t2U1gJ! ?5b1%$/x}?fn]x Ϗ=RUĆ2j56(GD` *@"vLP/ye*X`wT{X2>(Jbi=O!\VI, {QTg+ȅb^L,j~uTlx/$Ff19 cPBHz&㝲3htR? T;+ ;$> qA !zðXXqm'9뭦k;K:@lvOdo54C-u>_O?L~ ;rdYr,Rjǿ«w_Z=Q*K@%r\(~![rpގb{fڢY ffJ c`K<|4>N?s _oM_g^bɧ-aix z\#2扛?_?<±77^aE*DZWoo=GW׳sϕHAFϜx7r'}y5pYf@l~~nϽi|y5s>vqthM'MtfpԳ8zÙX}PHY$&Xbz{|q!7'(' )L.j[k0>K"q }Ca*MX (J%E!-)\Qd3F w mrĨ;%}ނ $66A^&#*ud57gRQED¤XhXJ㬞muטpWgQ#; \l0=`V3ԎxYq=Qdwǘ XI-.Jm6%iJ̀ \ł=@IYirDz&Cm35jdxfJBJ֚{ɿ(_[Nz -d=3r>3!h<ϣZ&X0F!RZpC-kÍ_$3iB\_$/Ǯ"?׾7w[wWc4F- yFwA %`n<$!p.2 b_\LuTzv܉RH!Mor#G_vmc˅#b0er>"+5ZCVY#y/1 Z aHIt(z!AQH$㉱- cދrgi\BLY"75E״m%Dn v^XIk뭜oB`84ˍe^9iEq6(`l-2)Pcc{XqrԶmȞD#QkcukگՈk"hZeS skкNց !Z0*D䞍d%p PI"ܱ1ybbV2>>>q7y?0v^׾C\~˛Q'(Sݕ5%dX/qw)t304ΝȨ_)uϓ\|Ռ`b&z3ġO! |AN栛f(rJ\)B܉4ے agi`a*Q<( ˦55Fj B i66n|_/>2I7}$.z۶91|=~ۗ<o!SuqwSf/laVcɇ7N 禨}(|K_|O3z+5Q`b(=Qu`lcwk>[ ?~'|8 @֗`u~ce RNmBeLӃ(ñb@bk}÷28l  QIE&cDo=lɷEB5a\L؋ԙiGK {,뵋u]㴟l'Nd'?9^zRe%7u/uA/b7 !qblb`} `tem6is,R)5dY%B&Z͑R8.z*e*2sr.eT'IK$MXby?R-\|[ҋwg kȝLid2=\yj'7_ʷ\Ogw?O%1ϗɝCswj#ٿ_;; Z굟k#P~l@s~ 8a@$_L|~:$OF o˄\d9ϼBL? ?ŧ/W-g~_|ɟysͱqqitA E$㍰cRq=/ftN?~/w;.~ƂN9 ^pMF%f/v Ycp+([f/# e/jR yz!a/fbjԌh-zJ.[1A&7G5Kq0b@W 'aEED9.dHfOWB^xk8Ӫܘ#I~ i\Z[|Yˆz"2Dc`t*eEXU{bw>^:dA >ƪy$|)ClB;I@g1:a1#]+v!Qz 9ʙ0v8ܖ逑hfZ08[l&DuR9,e}l̷TĶP)! Q0碌PaZ$\!y99xGo;_i=p=7ҟP_Gyw Ώk_ƒݽ58Pw}uWø)㺌z+M#&XV4^NԱp9a' }ߦaL^IA-( :Ntl*6FE\>O܈ds> ЬJ, yxtq˹~"ٷ~Hl7QD1O˨89F5caϥ>`fe@85L5g/a>@(PI~8n-i0 i#~$Etw|LCbNk9/=o0CK3<9P]'~OOZ$"×]E_0h}^ZTW,Q!C&֍0V.kJKdPw݋{$1Hd""mLTd-VkN ZwyB([f1 + X@*6ryN!oW,ݬdLe-˯Qa|FٻYz',sXgՐ=juU\lEe"# s$Qn7B t n>[L-Vy̼ fyuF0·M\fkeLnKx=O[︙q.;!҆+y|u>ͬ@|Fr1H*N-\D :LM38w`K+ aGaH_' *4|cE)28kGsGGy/ߘ˘{7H=_[Jf?\?ѫve6 Xr,4)QBgEhm#:ܼ$R_yǯGH%ЎKxFYcw!r3iܩi369XBT*{R^H e3Gʛb\-m|RkMw詥WibakFE161i4~ej<$<4W|^#w a,A&6Fπ61AAḦ́RaHXtnS 5a[gE[rg8xg^qd_WǖA l2'e2-7M/F:^ ,m.8mC˭-g$s;;M;;q6(" `l_k68`k166-p0"(@( IʛN9;= kyvBS}oS5Zē0hmzH2 E0Zqjt<!LVf!*{cwd$c eK6%E!bףNn0 1!kgM}s`uWQE܌JlF(|`ffP* ֆ!'(N߸œ=X^|[ }l3H;Uu"&wn;aܗp^8ݳ]3gikz:b|^BA2v ` DFQo< XCFR8M%`TcvvBG(S2xV& 5hy6>Kq:W=7KI/%$om@Q Q \z0T!s\uI|n޶vWB~?|{y/=,Rh\;jbΨGkQkǠ>5 5P)VZ*8<vĜ(E"Tr0THR5RG|X&kQ2jRLJBkZ!bgqGcԌf a[746$,n$c'Q#Xc\aT⋥ |EĨkd"C%%a #$T<V[eqWLmA5 Yy|0i8IF_֚5؛7 1k: hk{Qn֊V ՆHq{M1 %S b-F], rp]P:U*~4)<OЃq6k3zdn cUi%Yi? r[Б]lAF^¥ڍh!yaumƗ> m?| q~xF46#9y-W 0'8p`'xjG#Ʌ/~ s-bٔqB]c+Lukn:wk# vq\negF{n߸3rxKZ (X110vwLQӤ$E2)k)BRO;BIr+ț6Z69ePZѓk=IBD!caPR|[y5o2?k"F&G5~R23@氵8(0bFBGG׮jvQW.K;-M>Ŝf4_)FCf\,P̺H<6ISB'C],ZFuQթ JDiE &7MI-˗K!jx9k%:LkLWBa`ggFaϺ˱bҰD>\|_x\v\Yd\?bGߡ}Z!ȶumku(W~/y%/5ZyY::z(t?2]:[;)NO>sJo3RKNDJc-I(XHօٲaGOx!JTL[;c*Ezap̓?yaE\ @+yߩF>hw$F~xh[ˋ_r6gr=۩ؽq6z 90뇡W-Q.?DLMopu݁F] "8ZVk`' xeʄ>>!! D.QMRO]&q-8 Crmg4' V\^ƃ}]sgV_z}uka6~rPq%#"+jRAr+~76恃?1љ a/c*CÄ!e^z%]X)DHۭF T%c:SӕT:HQLDɨi3p&CMpX&iet'\o*\{hʡ1BMMڵ[ڛoG]o% "'ǟg;6W_۷?DX"ձ,XmJk&']H02P(XGQmf]l__Ú\ғpv ?Ya&\P"#5PH7\עD&LHc "C&~$ј\f˄2X2cj; Wu#XmRQ}'O^wԞY~^/ܺ 'c` vg^sW$it /tdvz01M^ .n:p̦ܳޯCu6\ːB  P#$$$$$  ^12rEs@c.\6U;S^qΐs|%[۹/W˿ws=Gq@F9q{bÈĕ QbxӅw}.sglҊάI&3 pMɇ<ԹվO)g,zd uWbXI'ψJ[fV`9WR[­2_f^Vbq[)$%GC( JQ P.s:vM7i*Ce&t "4X5 =ɴc1')²0VZFZsj.L&NR  `a4;M,MZ,A{.狼zw_'61U*L,k)ibvŰ"E-Uxy͘{0M4{g6 yM/:BEB) l )|7%Z% )xIk( xĹhH)]:a2X"XI AXBwO ׋iIn~wr>zQ+evzw׾o3{ {b2߷eDjы1-NJ]~LCXx9vܖ,݇+3>Ҿ 2_F##yN3F[l`vn7/M<-^,TlN@3-ҞS$RٽK_~?Ceng5ޱ 2 |66e\! 1bO>1^?,S' %8^`uСP#"_" Q JD RDPnW4H ?6Yj S~%@fڀQ4uf_Wan#{y3Wy:qY?rsogmBn6O^sa.tSSƪ"LwȥREÈng^$0D nyka]&KLm|9[|3𐆉hr!͡;A C&Apk(Q:`Hqɏ.6 o xP)͋ FII)MJ[` +UꍒۉrCCۋ52a֦MW"6z{1r9eHӤfg33E2[Xʣhj*dݤF6V&k1L 4S4L tCP4S$~OnMEJ#2OW߈_,(}^Vm믾sf/lvL&a{U(=elTjC% HHTEVPrNړVt'L-¯k*(9WcϰM"/z/__U?7|O>߾M/aN&M`x!% LpPTq:O\y>>'覟N*:ҒHl\βxK?>0^tM.!u a: OT w)fЧrk!}rMa<dBDZ)tc$F$5a$ftP*V#WQUh1-ӊV`Dq&>,)u͟Z "I?z2iiRՀIou3 ALFd> V9&NN6_ ḙ:%*Q2u\6n=݉R 7eg.QXSm?N("DmITe }tVKLΌ11iӟ`erBM߮(#ԚPKQ66 B$RQBbHŇF!%Hid\$WIl4 Z#u,ݍY/Uuiƍkb : lj)kR6EmQ.t,Xw/v=ƙΡo0 :4I&G( h5"5*Q{N:u_;~u\qv?p6?庛٫NGo==pƪItJȼZU#ioC ZS)p3,B% PZȵB-3{z!f/jrӲP2DU\r./bg4zia^t%K-OolKc;}cіR;dkPY if*)D4`:N:S0z[ z1` (|fBk˃,)]uC&n>?IQy+䎝T037K~]h}<(D$S%kZ˥Ժf[|;'h=;9sRC+$Eťl)+$sdRef|rH\R.U+G1˴]L6G6W WhNB[6lq[ -CLmԣ OTA-tpJ $%0$*\AU="9Uҩsra$t MI%!U"FAZ 4F64RH"c#MŋaY*64ROAݎXy|LOC}z/zfad='W\0T}?+?z/߿?]{\^ud|T22PĹ j,jos)(kX?~ 2 dEtG7IЅ֚AݴFQYc;t"qT2" CT+ec{R*&@DRƫV|( c. ,q3d9r:o'Wh#fr؎הJ9eN߆_.Ϋ+vR$8O,O)"pOUh"Y-dWA:. ҒnmG_DFЦ T(-f$fwCxZaۘCCX## TM=4ݍ0j 53Hb `> y+EH4bN0DRL4sLHsӁ}Wr9MwZlDi C@FBR}(B͐-oguB;n6WwjuڱؔZ弶Vw"YbE\^5(W*DteL*f|aQywMiAg%;6%xPyN$aS'& A n>ub45js^tԐ 9X?|hJG.~1|X~#=y6Qorι5 a(% ri|['iJʸyBL6' jYkTot{,EοFoQM- NrrX8/S7Vt$ UEaH{x JJyC{SӘ2^U 8 (nPXfdm1,fmq2cm i$"q m/iZGiKa' d|\G'}&gT*X2irwZV htm,0&N59<~} .6nڰsxaDQzJ"& Cl fvRq%P@EFJLNx n2shmĨMHlٸ&Z ^D A]?+䘙Rg \ ΎF0FFOc$ .r]5o{C`V=,rL6G\$Wh#fX)p~N_d)qGp͛/Q|7De`:68km7"=`dTxx2rC8rk6kn 8/,eoaN{mq뙄_z< )%tT*\zv[*WI,)1tJ#F%k>`$#$л ch{f12sޟR: CWGI=Mఒʵ_jjq!M/45N21)*a'ŅR9ɽY(>֠GL ~e!y˵b~MGG;{`>A%;"Rd4&E ɐȷu28\[;lWbf5&!@LWSJB[zVcmCf{j5aO>k-;(-I(MJE5˲|zЊMhH y0>}_5<¾=7 fӲL+x[8K6Wfm'q0-Ӵs 5e QGG7SSL7@6G%L$YY}BUq,O=V3b`15yRa01옸hg2ܸNR#Y*0}$2VQ_-+X$J+}TMQYdBC2X. kcƍX7NRurQu~NӤV ŊVU.1grQuo/][:la-YJNhT?YjַtcD(e˥Zl%/okg :p0LQ%S)Cm4@$5ʖB0@cNXk!-;ZAїz-X{SSB86ZE8RovdHkC*# T!\`iY.E?t ơa*ւH)NWZaZJ%TI(%1-`KHL+gsyl۶K xI~IMbݽ!18$K!(dR}p'Doɩ*nj@ Q~(РD', EDa C1 IDATiցz25kbh 4jB.D6 x `D1ï;IP j.[TJ-p9(#?8p/_s7aD$ER<7C$e3Ϻ~ t0 !.dq$ dx4%t*8drvz q0jv©IFC.#1S+jY'Zk($="JsTs^EXC*_F,H[-IlLTz#>W|`9>/K%^R' 5glNB/χY q'A.n$V۟॰$m,RIPZFNE_-Sf\cAॖdZ1xq3D4Ų(e-:}u]T M^az$c|m>6:V^Â^|%"tE(BGѢNR¶10֯6`['zBCʦ< ]*ayEh Yigym+f{[x tiB؝E)֒i}U~W貺87׿xoH.M ]U7?bPLVtJҌJqD]c0 C|ߣZI(BklL.ONOP 2ryl4䬍biX$0Dk$^1'1=~1"u 38;i6oN&hTHSz궰@O{1}:V5'yثVaB8sKO#MI$a8a3C\S ~y*4 ޖ.^dj2Y J4MWDa"ssĭym uR}>oUh~<Sa & ]H+D"6׭Ӥu010 pxTIJWJ ! hR,whLcj#:8k ,ĵM*(PU~x\Ņ[l|&%uy>ܱn /|ͧ!(DQ Ւ `a("j- yvZ/v=Mi⚔cVBXZ0 ҵ~mzξ9׿?wl{?1zc` ܭOdcS9"3K58=KePviלFk &2K-)^N9]`d<s<9(XX3|u@e+]iZY}+EE΁0Z^OʎRAИlY-rhbrq{z?_<vſ#/}5xznߧ+\k/_{kn~z:1n\2WŮ<\6]v6Ff@GT킮tB?JQ/1/20Hd DLl^ da݃bwPBȚ0:\8;!'17=W.졻ogGWmlK v18'7IE/,QZ?'39Xm [,vE@aDNNɾwX6@XqwZR,R9B c h'oPU-S,9V @z.l#m'i#;B)=H ijrKQ5ZI\Y +w~j4MlCQlE^&(s۽Og>zzms?|@{Ss?ŷjp-w~y`WExPb Yǟ|;*\Ѝ;1 eKf(y >0MB%@f#\Lkd d~ QJcn6G6F{jVwp2Ƞ!N89l rJSL c*Qfh被w6;{rXLIPa?GG7?w hU,¶\+VD@e1 JBr{Y9$RbffQ߇x?Z-2 Z,@ 0M9nҾF&觶$Ā -M5P >7>azZ'^Ȃwzch!l0); > !0MˏL=+d)o#| |'=~?WʚA/?9 cMōOζaYL$Î~ v|d;PY8m~՗3?ۏ}W룜iRn L/q A\B*WdTM d( N6߆f,GsR|1YO~ 3ScLbvj acY6:{\i.\-}.\5?Ynm,"T>S:.uhP2:0{{SS dsX*^]}~9 Tf:2 1 ״ȩE `?D*uhv%\j=8BK %֥tZkJ qfg:{ːeiol0\cnjCLS /$A֍FgOl7STG봈%%p^@IIDDQrpH R+ڑjUab# DFwjf!­XI8>/x? 8ܰs5W^J A8Ķl)_Q.{ )+S?hPPIk?}gg?8>Q'On0Yc9$19=dz70[uw*MÜ~8qA:)}RE[A0m"G1㛜Q__u:7|vVu1p0wtѶj{ QG6; sI6=x_3EcnvDV7oxGx BJd!.|@䗠L.zFyrnc 2?V[w%gZ&Jx"}e;̔W\R؎Ka%OpxדӺq\83X]Uˠ5lrVMގ QxUÔa&u R<0h٭V'FJݗz1=T{F{\nv&yܼc糙+4R8vl7Oڥvj;^1?KjՂX.Ѧ,l.WNXRwJ˥.FB)#`dd [,ڣ胷q]3oz+݋RZvҊٙi)fxlևoH^/9W>>p?a]ÿyoqGhokT)a Z~/Gx[sAh/nؾ(%;9XKj$kBZgUD$%Rz VDA ũGJ>|*0Hnx2ř25FqfJQ]Ϻѭt C6Dz0wɠĴJR'Sį\\#MHjYPh5\ҷmOmڒ͢eNt@5^%`:>|0w+STt?Bm\tٌHRY#@|ƛw﹄|I֘;K{([1N?~E9 #Whv1k@ l'' #FG7w~~rOyFK)@ KZx&\ AJ+vY͎ bXX)Unzu0>9Ch~ϰыvRk` {( ZTO 3j6:0wJ$rj;vk@2 X((d';xzF0K_2Npw֚[vb^/{,5BI^T9PI1[LGOk,Ӿ _atixw. Ubzëϣ#ROl F*-?O'~(}Nv!~ϧ)o7_e7 o|>=yz1Qw+01 4i / XJނ׊QKXax3}grq٩ f'bwqbfCW 7NgO?80N_%#\aǣsb[[F7Eۭ|3Z)5koeʹ\ۥA2ۋBX"J8 5YG -mpE/Iv~ 淮C%@&,L@ց5ӄav&!A-! `EŴ:`I?Ʃ"1!,=%6?_(NYc-:i ~>RØ4qLFz>^JS6Ž6U/806I LH5Ѩ9%eHv #GD}ٛþ}S=/,>횫9th9gx]zk84Q@yha (Q'ϥMa~a"I]X..FiYDڙ4 =;o`MWCg_@gm]d29L\jrBㅈDWf\<|jt<4c'8;[n}妘/4dyL 6f{{`7qqi*/ի6Ҋݽӷ#.g x&& {*s==k@bm6\6,(@X%/8)0svxXf ͺ9\KbS(d]n~Ydlh-s,INVt-S,Ŏ%0 k)q |{I7BqH1&rm(Ë/aH(@2 %if1Te,F3 UfMM lceCV%warMW+dɖe[۸!`BB !$4LB ^B)BI(`"Y]wg3M[fV*:f48 >{w<_j}d# $Rd>ъ2RDet$SJ2l*dغugئN3ܷ%ud,IECe,BWu2Ye2#%tu?0aY #bBxIѪyngj4(98_Q+YWW;b[TO}WwR$Zk ²>z*}7Y@GƜh-,ưT, @Tu> ҩ~xGqTb@[6}4b-b{Di P(@hU8_40^:+/a˖-K 5hաdJKTlmj_m[[,_#DĒ P p}+P T\eD.E4Baw۪jC8 :23Y6Z+կWA=s2u/}3g?} OKw36`GFJ dx  ZW#"6-,#aZ'\œrXby jZz|cvo 27spG52\!<2EOP+Ç; ]JV})z6mY}mK=CF Xqz>Y'Ke-Sr*%]qS ]V拣ր H2_2Aa" I!,aZ+* IDATWP~~^u/7a6m>J՛p_o# Ӣ>P̪2ʪA,2(ŒR d]nUf4+hp>LXJD" 2Bu@p^n c6WǟgWyۣ=ܽ q6W}ӌa`88DGv_=s$}|pHWo0M@Vt<U'fﯫ#ua;-pK8x:B*~Tn|swlArſ4LnP+DwJS,?k,c-hk[6jFԳ^VeX\~ў/ce ʮ^oq?X}J,A@¶39< hmF"Hc8IL;l "na_y~`ǎsmNрo1Ddį(@'B&ߤ"LPrBQ/cfVx0V|Hw+=g35=Y;eUm֘fx(ja{~y{t%:'汻m+!%*Nѹ{|RFƦ[p& ?d3j:܆a",;fM@ѨQc cѰ*R)QJ?H66wfW:)E:Xi:-4VW7\Af_/rna=m KXvh Ź^5r΃ C rǃQz 'svq,c%Jlk K+X0,Kg,KHYJ>% Xԑ#FX誶' d{&NTzy MO"\ץx#>zf;1Lb%S$ FgO>}>~n+^Z@ռB.E>N ]5+m Mk Sn`:_Fa _FUL`[0m0kdOiѲDnq8oW7qwT?@3\Wu׈.0PbRC}3%OTh0—}K6̷{ (iG1mN3 |~CY ݴS6* L۶1 h`_ kĿ X/{D78 %b,K=rJ,UPl}Y+Oiq|S.VA[W$IF7l Kw|;v=s#WIq2i(M't^toTW 'Xjh[j CWAք S&PVfԥLUt씔 h3$:cuf23YT9<Jjh1޲-q=?F逻kt; wERh-'CPiئR ?( H B%~3c+(Սp,0,zFH"33 dۀwZVe;^+{2KY#Y?sw|4HVo!.6'rOEz l4%V㕾ή.oa{KVd*A2UeGFV}N咎<Gȶ䗹n;߹-'v?f%WrOvB_"23kEm.mg ?E^UJ#( KE Y`tIzo~!#oM6 c7?>#cMkU6UNaJ]m31 \ĩQd54(R@n~igg(sHG(]r%}C#ttqiMG! >O~C.Zv}iH5Mj_}vWiAc6¶Е ¶l6ET>/ T/Iqg= [n-C`IJA0( K2=m١$ aE |0Dh^AT};z"Ϟ]p4CC 镘8Dx!!(Nsu73oWj m5v?By0l/oٲ,K9o?"}(>?A2 F=+`^ȶ/K3lmM )L StDM@ΤQ4$JK'77|(!LxgK06Y  L:cccӧ>yVȀ3Xxf U&v%ș08 F..b7ds-L)>DGy+_NOw?ʧeEosӕy;Lebv\cy[f@DIP* GJi,p.TgV$*Bfgn!mM2?7*l#I/c2=_bhRDc+AɃ{8,amu'?'jZrDV X!$Zljaei/84-"!wF8U_danif#$7@([Ͻށ!]Gوu1-Ml=c J)v<T*elFEfvPmwi J ]Fy!_{x`j bp b 6Knvgo}}JgC].y3<-$[>׾Ŕ7]ɟL߃n@a ]5y/ލV)%DǶD*O{e-$2ZyA<TJEtRlD1mT!*;X C*3Eq~gnfr d1Ӹ$COmxSphhK$oZ˒&Ҳ0RI)Qf>Ciq|QokB_]ncEs ZLaP ",7X—ԗ,2[ #iuvl xBq[>Op3ď?́9z.~ދF|پ ,9 wQp#[_kXKH;vqG< A> AEHus o´½tv?,&:z*2Bj}Fغ`%}X[ıtfg QgT/ME} FpD4ϕ*9榙&7?GTDkM*o l2zHg;U&b /hBRv |߭\R-fq,} 4VݮGD(!@Q338g]8Oxk>ǿr j;{> ^s5؉a^7pp_S'InL9/l{ y#:?Cc[ṥʚ^zb##ض~F0w?NQUf_ o$ Gi2{x/KEQq+X4B/#qeJ!|.|,°ٴq _l~cXq?W5,񿓎wh='_4X?z0\Z

;z{Pa{,>I^pI:6utH_IڿBOܭ9xvɑxG^ԁ1+Y}V;suU<(8֣HgJ%r .,))d^^^[[D; ͣ ^{UJMII>jؿ_(ӒKM"N5ŪR#C+|@4Fɽ[^Z^ipoXdHQX,^R"U sJSqNlں5efQ١=r'rTޜ~4muoF缋y$:vjݽisACwmF۷&Pz"+O(;y[ۍivD{?ϱcǂ  !$ dN،W3C"l7]njy`_3yL`J a<+& ty!|EM,cv'CNCY<"`#wTeŬV `sdH,Kyx1ǣ=⽧u&ĮCD)(^xx_Lu<9 wd/B2D5febU'w;/n1ho=,ez0:0.zP4슊s˽rbv]"*f{dávhX\+b Q֥*AgǃǾLK'DÌu-*^Ll%\@z]g"AMaܛ >;7rKEK=GW&-0sz HΗO##| Wa80 zJ>꣣cр_ʲ xx<)9>]]]ВP(4"xܸq)@t&NwKˎEO2Ve48BNct-p0YC:h1̙b1NV_|n} ^/t5k^"!ݛ=ALfBdnzx'^ϘLVg@rǾ"A3B<݁vw嶨ifdo}&SsxxX`:cdLɔ r*(cqATa02!*yP,e'fB"Qo;|grutLL\D䲲Ozj;ZCeֲKKf۵Lxh`LV T7(4|#0"؃Fl?CB66#'NA|k8?޾_t-s'4`aMg-M_w' U~NuvklJ3PX< w`/f2SݜN[tlt8ϯ+ Z=v}9j0̢R嵴`Bа+VTlf< _~\>EᓑJxV+|555 >1ˈ#@-Qɇ?gΜ-[̚52))iՏ<_-9w`c)p9 , s!NW9p̙3wt:(..jmUL0^&X,0gVnOqqqvv61ƨmy}%ΩWiϏHvS;I@UY Mv/"oG0 pi{e+| Iz':q.ߔVaݽ)ꟾ&_G޲|FڈTS?LM}E,DWf ª;ڵ[Y'+oK9$Aؒ]xw4< yn" E@SɄ빎iDCJ;(&FlU44_L02zGg~ rleJCί?!b}.5,rۭޠ tаU-:NL}q5' ŚIǺ]&uwqHȽ`K ɜ[~8|o+Fqa>!c3?A.2; l4xPe>4;0q;>O`8.7[pn`[D_v& !IZ~26$=.ÍHF}A7|\3wۓ.hGΓ$P]K-[n76 ǿoO?D%ꫯ@y}jUT!Fk.t7m{n0-w_7ؓ?p,Yʃ0{!jn w`E5ʤmC5a wSa2 Fiu2]w!m{ u((Ex.n.ދ Ra|fL4Ԡvw%-ɧ RU,JjzLԺi1O&rt~jZB ]6{N#dhsfD",$*q{]a ̦& O|&6xQ:G̮2 B{dziB-xνa9f5գBDkmwB,9nD䚇R-:u:5˙lci[=II8ᬝj|[t >:xnޯڵ`HmPx睆(YlU\n_3@;J z:-}q3dKE׳fLXROà6ݣF>tQfkdj7`Dw_/xF4{Ǎhm٫>Zw#FU5J&*LJbaЕc?!+A0ϸ\n*930ٰӉEG VR ( 84mJ_y[YpS4+#)Sݎdz. 0h+*Gn;;ۄ54 Ў{yJNIٱc!!!vdMG& ([SF%8XgZzرc WO3IOR͠K?Gcnjq8uZܧo|}޳ax.{ ygW>?~ۭ޽'$D,Zl=oW=-]p^dz3a˺-sG|~MKcn{废.sg&gַ5{7l J"#ږp/xλ}bnOONXⵗ~cZvKu+_|wdewkŶU_Z?L[$r}yqq|9EET^ݭylgG?g=ŢD?)k#xa Mmo=ʨQ+,',3^:U?hkk=㚗 C2Yֵ'^k~`sϾ[=];&㤉?_wV.]tǍg٪JN'ܻ{u/D QG~\s>ašuRO|Q!cr|>Hkmo0-Nl4xI&7dz||Ȝ9s$L.5b%`/ӌp 4w\xbVLHHڂvmva_p2y?( !]-?U@ )S>p}5UsU3V(w*7#[Kv BN"N5׎{牗q̦;?tCC7gn#9E؝wdD$"D;{̱_~o6иI(љ؄OT;T bۥ6 gy;?()،ތs#(|X)5ϯ[޺qEL& E8kQa|PYfXdƒ}СG{Sj:#֝uz>Fokoks,cv^p0,2#CO89}W/j" noV(cq£[icUy9w(rwM>9y~}򯝟=C4-y% Eµ9A3w4ԣi6/n~#u?`P߽xLN変LNOkl8t)<#/_J'm &HU]/ǵmQfřևi,[SA\C KVV^Ӹ,M`vU'o<ԓAG?<<:'g4ȃyg>Νy ] ;r̿1ŭضo_ 'Lk]-"2!r]gi(Joo[| Z,@JNoPȈ^o{fڐJPD?j)ܵ{3p:϶6q \A W|>0d D,X"ʊ LíbUiGXdqdTG]P)9$lCkYZo0n߸\ ьJHAשּׁvqaavL-aCV7Ȥ&;NQc Q᰷#yQsh8Oybc^aO׵l$NteDjNߧ٫Eɞ$W ȫpt;Jq=g&#݄k+-|< k6ٹR|2(;09^M;#WD#cy*W%zNEQBzNWw mwȮߏb}F[{ ?~V׺um,Y WF.xx(l3\dV "f;K EKS/l|;IaPxʨ7rDߋ_b!Ӄ6A1+cegԑ6d}yRG|(2lntrQI L^ne_~4vK<\CK9er>)oU;TG;p_hGjB"`,ٓ )|.m;jzst;]–DbL- ܊P,L}㉝I~I],wu+~Սq2522RӹOnt]Vx<)06Co`>&묩/ oo!.w[l4ػw零#dȃ[k, CoDHSf6[E>E?Kot;z,DBa7`U)&%Lj#$ QjD](UHi_6RېX64D{r|NT{̈^,G'Y+qϫR## /p[Zyx$!$].YKک;%8FfZIsuOЗ^WUv4*&X,vޮ |#yb+KOL-"atC7NIqݻy-u.s_,>U/TyCX[3O>$EBkg3R kiLr4F`\^żNzox*ÜJQ\Txjڭf5|ڙ,ѿn!4MMX f ~? 6!,,,$82ڨd4-V2{rZxKw`Eו2u#M}ͭ]+RFIӦ].W[[! 7#~/7Mx}9,{2)QF&0[?V'GNW t&Fp5^ͪ.gU`(27ۢmw3FU:L:6eeIcy< \"U+7O)`8=wT<> sjQJڷtmx@|Od㾉.Ű_4%,`.?L °\$)]YMGGqK~~M1a@=u׎uJks @8Z\mɽAJ7lnfL޻ W*\  M\[]Af1.xgoY:Zg[aQQ״wxW+G4Eea6 ^۝$~%8㎋ϯ2;u}ڵYryJCd?|cyi4KZ b<򘶶)f}*(ѼC@ ʬxySpMVX,OJzudicǾ` H|gxK p]Vqjʝ ֆ;tbGRy1 >(p%Y,<6`0}KocǺk.AqN=o\V~jka4V1^+"|&B;W&of "#g?Fj jhJYAUή#fZ,~V-BW_@5ry:nuG\\nw@sX؂= fc`ոn]߲a:LK⛚7e>˨P^v#tκ:cc74OK!^2Dh4L3뤲s>5:i@4(({Hj=qDhhhee <z;::ϟ_ZZx"""crPL*VWWO4 QWO,~ 2tv ȣbn]jf2'aa#1=ߒ́%N^RىhO>rAqf7>NMa8dʂh4T hZ lF٫02X~Ѩ,֏ Tr sn8δY}R9N7zL(Տ4 |Fc*1Q3 Ŭdc9n 11K1٪Uȧ;NDo:NCdr>p:'OFaF?.`ڴij:;;$4cǍKII),,TSS#ɊࣃbZvx3#)6[s͝/24#pFcx|esfo,hkfₜ/T\ƥ7F:]*yJII< *< vu ū7D1̰ RN{ ;~ETz'OS9gQ%a>^trD9\1㉾D˜)_AmO1kA?(8y \1rc>`Itz%68xlL̝ΥhNb.%F^w~ʻnwx Aؠ@Kb].7NykFMcC!Qjabnfce> .pK=p:0zB-VÇxj% \b;N=0ie2K`nׇ;콆6Hn,pqzӐb22\xpzlMl: vibV>F]37xF#BΝ5kD_}c:;*6H>&O|3Fk '8d3۱僭[y: WI/oJPH #>.d6;NpfLN&iwڅ(Wfǀq8]qo g2w`R(dg!grY`Lq(Ii5}~^ALy%A~ }: d2DNJŁ!zQ(D]_ջJ3F:gLZ볶.QzzoN0˯x.#]TW''|><BnPtz^* ..j6ӂD?y»Ld@3$o|Fh7 =ʉTqmBK-_dNFKLTP4} Y #%^^RK> g[[] {j*!݄o<!Cd2C,4r-NolbFGy 1`!v6zǑ!{D2 FN d\ڤ1롫"W H72?LZ B<ёH<:~#P]d$ޥp0wY:s5:H<>_vSdJFݰaüy7Z-ӧOԾ@& 'p5"ƩSY?pwbmVyaަ9[YZ|kGsw4h+e_}7,fCÎO}$ܲa—_ M'\G9@^vhn;kjx}.z 9˟>~}ՃENO?Yo g2}a˅a!Mp5+3SݭlbhirW6EF]s5rcr$&:g ~`Ahf' ] r͹#Uλ^gAn8_<jҐ ^G^}E'Vhnn?ZgUyyVDpہ(BRo ;N7 ._g4Áwog2%ɋ+m_j W+,d/^v1}r-X`+.?]|(,8t_Yդ^#7---)90*2B$BH,WtI0`[ mCqy g9\'(R@2 a Sv V 2y>jC=EPæD\I~fP @u]1 Bp7<ُHjh # (CǛ8q?PS.tm4 7x-%''/,\o0 DawQ>fz0;M& (ɬ.p=&S~\"n۹'EDlk-(ʈS.zCASنFDHP9qmjn\F̪U{d˵t[,έ=T Q{f5#Qǃ7oX0;].%+PF vDjkGLqPwnE t:l{.0HA_& jă f+D&hthP%ǎaFWx"|C,7x<,bwNM^gEiLfO0 ߸qW_KJm9 jiAotI[9A+̾ ZN(MF=֥8N{?Ausن03lVI}~wX9$p X` U248yiX^yJ`;&FN-)23J|l6kQ0@ihXPRSvuzX$dฃ.5ʜ-MY\D%26(nHWJ"բGN'-KI"Xt#$29Vˎq1Jb޴?tn+ K%,y`H(Ӯ]t 8]+9@6#*) #FA[<%]qZ-ZSR*z򤪶3~?S bEȦfә:;;5:]ƈgRa@|œ&Mc0bM:u3fL`1X{cII (*ebY5m[[kf@f3\QQ1.``8 1ܾ4̟TU4z / /Y ½UQl'DEY7Bѭa ܈7ޤI˪w #~ 醍-tKJؿ“-Z8fsg.,Zj^1tAamмQ<O=NGׇ#S3*g|"t3 , KUAo0?vZ[=|w3ȑCkދU#{ ?ńZ[}N)Ni tu,+C|Ho/vZ s/{+*٦螎NƋ+3ZqK GBZ?}s ~X1cF!̙.fǐ _b}9v沲a% @f;2O>{$S O-^ AS1ybMtLL2 S1VD;w0T*e~;` LVfDbi~O}sK^! H$~ P /# 4̟dRٳݷt4;0n HGG0vxFgrjj))O1GX9n]'tt0^GaRdUE<֜9:ɢaM_oj:b6*! ;rȝ{BoTw>,h:XGD9Ġ^*_ѧSTNtqv;:|Pf]KFI"7"}N[yE!~` 8wvӏ5 U_2NzG YNuvvjcccO8].|rQYYn#ӧԩSG 3mT]U]-cv#G>~ևJbBh<|`!2aL&SqI<[0POi @ISeq ;Ny1[aΦ}q@0a*C0Pp<-- RF3AA fdd 3gZiYZjat h-Bcƌy X+nOKMT*NcG C,))HII) q8VhN@ xSt!999"aBGefǏl0@#GR!.a$t:^QY,H0RU~Fd$*?aǏ {xFtxYYTMMh njDʪ>@I`oN44l@/[.x wpo5baV6 HO8zNJ0#yuRû=ǀ?ܨ"`?xڈi&rr1!~IQa0ݽ˦Yl71-&פcm26n߈Ev7d?qVK۶7 Aa6]cP!OkѠ,)a-,秖Jʏ+lɱcJRS(+HJLiE=Ptok757INJ*--EHagXk1 ҄H.xƒt7o޾}@-.-1s={@>iҤ#@l6PS5ukc@5$''8D @׃js0T9 )F }E t(Rb@%]juޔ) h !۳wP ڕd Tʊd0UR,X*).9sfyY(QSSbiQQQ&Rmټ$84mf^TTDښ sl6nX(ዐ}CC}G{ԩS=CPa'MڷڽtP9@P 诽PTZF>u m@sP SLKha CI > X_Fm1k֬ښPZF  KHHZQݣ0t:&qi6>ZU2J<G4Hr0;wkLN3B[>-wtɳ~Yigb"dĈ`޽{`)Hh4xB>0jX'N_z5H8ז@==k?CHaǍf6:z"_N`'&YZJCnhV+8}]2o%ijfvU;bǘӅ܃|0qݲOhu8+/~G3mhXx\BѶ!!䬳y@С2,p#uz PG/BF@,C֯ArC:v( GP32p~>"-,4>' B!C}QQiiD|hXr@GbܝPR0ܳw_|B ;(Y<2#ɓ"p\ʾ R,&P#R  m7 fAj ^T0 SwbRݷX( 6;$x0T' DPPЁ;(fلB! B$#xKJ:laRb -C~ QYĆb6qp( n&n۽g!(h#G* LY+,0\G<](BFH H !11I}PHF Opn$`$Hq~FN$#aq0mR=L0!c#8@`xޙ RRahӦM`|@7xNJmoomGؠрAi3P:ÃAז3\@`r__ɞ5< gghdAcaӦ9/_"ȮV **؋h `("ᇐ܁ŪD'hzP#a,7`Oh#ոy ƞQlf j>bs8vàC{om#"-ohbwʔ\0f1KI7Qm]NjAEm޼DX![[[ O/cC(5:~Il gۡ,r aPu ܿZCeJ= WDdd|\Vٻw/,  w\p~w,B(&NàJm"ASHoo/J^(U*P04P0=tx@|𮠶3ʛFu\rՇ0}.3+<6xKs38.b_ Coɤ'> 0pP']L0.HW?=騐,W6c+;v .].Ёk #f=`ŋ<LJEHld)wQwӋλ6 "njC1vm-;9#?TlX0u_F&?Z8aUU-QRf i sssAtttN3flmmMyE=H9W__q(Httv6%XT |zPl0ng^5Ia2,~ ZpƑaSaDTG||<g*\ (U Np fVF36͝<#Ql/ TA3FqvF#iرue<ct(+kX!0辥Aa$Fi(GoC֞e/E;k1ړ 8ybf9CCr`#=*/#@mgp~j H V*ԪH݀{?@փ?~I$QH0E6 !ѣ`VJR[P N$.z%PAjfYCCè! "(hڟ@]|[տ[۱c;v Y@ 쏲2J2ZZZJ[B_.HH;{oY{<}%?K㤄痟#y}g{9<?o3P1v0I<CE0 <#lW:qM\T 6 Ɏ=:,"b2щ _N% "gL =(cx23vPsH[hj bqW4n~տD}z!QR (B.$^EBgB- ab# unI̙D݂o%RQqQ8on&Fb/Î`4Jb @IUb7kȞsdkH^P'K!+IJe8T4w{Jǁ2 MCzILɾ4O)5Oy}.M,zb\.?~<e~as "rj0b1ak5@֤3 pWG3310pRHǏKxƇcٳP332!TΝkjhLOOиRS[;"qݦVΝ;, ٳϧ 8ԩS)|p׮]bsN4i@"z; z)fs`577?~S@]8cn>(t8 Λ[AsJ lV-пh, 4 R;x,r1$X*퍈 Z*f"?r䈔KӀWTT]uaoSe<˗Szvt͚5 d@y֯_O)Jaju: DZPh`7apU jcj'O^1u붆X^ҿ/"NJH^=p_, 't Qp!DXEBs"g\wY0P,0LbRBsGRz%_8K%=$%%_!imx}is-b:e Ϸd{6?v53P@;A+KK*+Zs :ch03(W, {Q{eܹPp}c`~AhO䣂3"筷s;<@ ~^^:DTVV(II(?[jkmf5~[m`Z\ۻ}vd0]wSpYl)r˖-.++ JII 0 ԨQYgϞikR{ᦥc0E`|Ӹ`M% G;ACX:|z𜯬\hx1V˜! `;~utvM2"ŋ|J`K(MdHM1t0x0t :qRĚc4f'ZQCzr577͙3O f0vh={F )h {&3pԨQ2gr TJ%:u?#3H&ҖN8W9+2.0jrԠNa@&C,ScdED7ds8D6?@&]RKȁd0~ ܙ Ylo9qwwi>kd7"SYy+V7 R>یNnVH>'50+&BZx􌌕j5m\ܵNL?>x4T~nC%"|Xv-T]LN\Pery϶ i\={?zڵ I$zp4kNt ]ShiifHknjˣcnLʦ;HII0FgImtbS8 @+ηA-&0c/0w8(D]jzҔ /(C'O kӋV(%@\l=[΂@s3LxxBaA_`ܔII' 9G1$)Oͥ?M0J`0$J 2[-QYY0,F.6 Կ! ɂ8`h}X%n= 'Ic`@vlM1F_R; eaQ3^w 1Oyo/fA1 E&0竁-]*d#/^n c ƐI3>bBHlF7Aվ6 8l97׾|j !Gj0890CHKTrMƌqOfAx% ! 5d`|~;nzER6t{ǏՕHf !))ɓ`جV 08X` PiO:ueLRR28㉓'ݻ(Ǐ_bcǎ}Vyy,*pCGZTP\%A;mفx `@mWT74Ё>tȑ{;DΎLH$tuv&r]m-X"Nk bzNsej a`c)tΎv>"4%xf1MX%Dd4r,tn?ƃKKJNZUUy NG^_ f L 'DM jk?gUU,W r(ŰX,^>)j5$Sa!,zL B0Iɐ+'NX|9$|G9s&zCae!-*. 3^}  a!>}fEVKp*&vpgKyy2 KH 8!DIB8&lO"λ}o#5_P@OiS# $$c0 5]\,hd&w`b Eΐnܡrz~XFxFj&1a]*pioG*0>)S@sExi-Nw ڮ/Cs?Oɒ~ z҄rpWzl\8+=覍._f`Tݘ%|;})IjA o&ݑۧ򰬛ǰG7q¼f8:;T#i nt.,a%$7)Ƈq ŧwhii ܼ$i VB?)kJOFHD.XS \H];=o ,$ֿcQ`]Uqрuxv;v XEaRAAXn\RRܹs0"!aeR={|):Hth&9G&X{-&H g_,H'M"VLM[8: 5.6u" )nҗDG=|HK^ dB 2rk"o&A9%`|񓝤ϞCjI`cIKMI~@Vs|ké>BHX4z~$vEҤa?au0a,`QRW3f=n܄Mv3k}FzsL^C aa xgeVaDx-]J7RP0iXk'L9s,PS;h9)1 /u>mڡC[Z0*RFDL<ѣ~ N1` 3#7wpet.߲3[, W\l,fTT$"#)) ܜL3"P9PSĕAB* N=zL,$PgIs5a@Rutv'|w}c8}4C,ZhΝ֭o>Rj>+@önݺU`yO$Ct@eOǚ믗^5z/7v!+"cKjqyH7K}'Mw77Uu#ڹr}˖LBG%gD_D.!8bS7Fsa.o['/P|j*3i:?'ҴE9 qg|(**IxNJ -ßIQ(11A, R\~99վd KKK`Rx***ZZZ.YE‹=r f h\lЯOݼeˀ, CVWoćӧOGϵׯFI#&۶1c*Οj(--+`@a0+HO<ji23g!B ͞5ܹ⮮((k֬ (O,>wnh̔DjJn` '6rh8q"fM&6yd|@uȉs%%LRSSSWW yp ˱} j 幹˖Bj 9`uGOH"#߸~=Ip 7ѣTp]# 07S@ L;?`ρzHsf)..”###$@4iǤp!Z3 Uzy@J=B mjj.$ bssseyP;x!?=,$< P4 ăhʆސѨD7mڄ2ruu56iZZ y_I3.b,Z=.OM!G|zo75M^9NKIlD5ӯ伞XAoh1Ҿ-~-14sp> wQZ&_K"nTn:Pj|L`wR"}YEĥ< őQp8%\‹yHj%Ah˃S.GTtªubNqb@:眕˕-7 xyEQȀH =8:Kpdtc0= $Šq.#QUF#6 i|t 0_0@ͤ*2~k/?_q ÔTKv[Py0#~WL"-&!mbt-  7M|:)OQG2Ў<=1V| ZYYhsiʠqj)0# ̔w3Ӯ15P:Э?>O`HAqF(bng=^H TH?Yp6=ё+N>LTBrre8g*o!Fwh-xz雺A;rE ݅F!4:5\u_ 0Y! ks {ԣO pԨ/3c'J+Q%;H rȦRv1X-DL\]SAX#"v,A!`$ߓo>`1sOώK!|L䐔0E$/T‰ B1zoS/|Q'4iCV/5 !@4W}%ٹf;J(N.[@=J`䓊&| >dt n$ChQuֱ|3C_bH Qq&,44qWw7X<{xqC08axqy|=[h..x VԞ=5Z-ŀAٻGRQq KJKg`Cۅ?32" R u,j2̹bthǔZh:;^Eq 3·OQ9 Ν;&O0GͶsS e&=Q gGGNtO15'N+(K'uQTO`90v{NN⨧VS޽{J%v:4+(Đ`bR1`yT^L4Σnefjmm323) \H)B ^BzC-$gjX8ꅅQR,BvP/1^Z(x7n)`ШP_GS@L]]]lL Lr/rdPu^̞nt &+AJqKKsrr^ڪ*𠦦QYY.3u\$M}}=x(0X==<$"͠)P+*0~HֆF\c\<1M 3¼GS䁦!»hv:У1ڌ\ `d477V8l$q0q[}c [F`<B;TVTF`Hza`-bTG87s-Z]4 -3@Wx?|AfGB :SID*¥%piӧ9|8-=&7'l֬YO5vwȤgcnvtvi5|V$ik,.U/8;w `Z׃\|94qp%H~r/c=}ܹs9s<`|p3gٳg_`AKk+b$.ܱc  !{S[i͇l'O)ɼ0K./hl=njc/ݳ8 IiY%w D`qLs]K|. n?4g~> #[t̞}I?gL|Y0@ֶXH(rzOL0_Aw }9̎T,9.^vK%?:7o}/\x<,#G/^wޅ bs)0kP~ѢERXAǔ!yYH `zxށ2OFt5@ +c(Ġ}0za0/;++pM]]o ]Ώ6Mk[wC+V-{pQ_NB",$v註[B10=-E(L] Je^+]eZȓ[ȍϒ 17= ?cI-d0zyCU˸_"B e#*`ap^]d`'sc$(R5UuIziCa;ܐd_<ë  P\0A{@a:9L}GZWnL=ⶨ/_ë<7H=( AgtfWex!: (3xCЂsDŸ@wʰ>x"#F/Tn.[W &+1+ɻ^ЦxmDfB(ϗ0T»cξr1򜰑yβ;y|t,Z$P@oo9%D@& !<Fo?aGߐA(Y| E|,>or}`_A_=|OF` A~%ϙ{Gw gwFfyHH;]~DݯECK 0To &>~90/O:sLRz̚DNWaz#O'MU$=?M3q@I-1^G"ejbvΜ,?辉|opHq=;3>\mxbPpr,,c|^6gĸ_%0L ukGQJS EBs4jYޭdS3 Ȟ r-޲%H~!Hl[&!{ȫ ɂȺaˈÈX:p̙~:<<\T? =[TT4wΜW_{m…4`oL?^m|ԩW^y3H_# vܸq{aaL%Dj+#5yzw``6ŝs$ҬNӶ\ ifKa*d*o'fM8k#);K.xQH cL} ~8&I$]wB<BRRSGBGΉ.?-5ON=N☦>?mu}eĽ3XzjKϘ{`D,]`&++GO< /9rdQP0VͤI;::?h5pzјӧOӧ;99QQQǏWT]]]'MOSKKKL>W<srr*++bqEEEll\n^dc($bV Ƥ*䞴4&=穟:i6ѠMTࡤcﲹ׽6w(IFp"&%U*%##[ Jx/[1[&=]Dw/&RV@J>Ÿ|ݓٷ(A*DXD}~x@DnzfRKN߀ifd-Jǒ%țBLfZXegp_ѣs"Q*_Y[ SzRG6J@<Ă⧔ռ^V&c}=7e4HFU}֮\瞋Ypݻ+* K>xw&Hvnfz|ݷlam]YطYᇐy &I]:uw߅xqR̙3$jjjhCA0aɓ'3% fAiz(8)))˂YdC$'wĉ!վ=t2inhkOӾ!/{2M;n|l]8gR8P䉏$f*@-BwV׻h-ב{Hz!D ZB[70^%5fݏz^`=ckGSۙ pKv6T20ͥZDǸ&_4}zOzGΞ={lR0ƌɧTg+_sfnl 8wfZ[|CL垫3PH:"=O\yFھ}+ uҠm6@A2LDDMMM: z}|LZ vw/)+bWb^;yCTX?(xWa!f%` o9rXWe%%O,~餦xeHkFF_W#H`b1m,OtT&cҌODlj3[++*X"oP$pe7gnzX!}]y-<y"" QT[}t,GdU4o޲ OTRy#KT$%w㾺0"ya'͚= `iǎ{ǍqFXK==YjUrrS?ɱcfΜ I&Ĥgqqqk׮|no/(==nzfVOJaX|7'Zyɒ%sf{2Xzfff*/vua}re( p;K} ; \lHOHx0}vGI6gJ8C%J%;pm29i`n=W[> |睃1o;gƨ,Wd9<&+ijFw2YcS QV> ?|VI݁wI@J$rr<3Sqo/V:h NX=wWFՁ(Z~/Y\Nt4ტ4K@x0SwK|rm@a0Ob"L\ӌyЛM Js ח._$ KPYLɴ'9wjU)vIZH#ՊnrQ0;#וKT߇;3%؅ިYi > w%0R#MsXYZcFk֨>>{vwq)&O!oqR_`bdVa ^ a% cTOa*aD,d*))[1@oK{նWү4|졹QttnL:M6M0I sSct N_Hϖ(~;8WO:mLkK{՛􃎟3MV֦=TmKJedaXmoyf}OnҶrzn}Ӻm+u4oEv}EO^V^ ㍎wt4$bzSngCEyo_x>g.2܆QV-+ 'AS2lIh$Aٿ0\dZ=A#0~-nSJ$z>8?p ~mWM9f͔&-dߔ]01t2?b'DX=&ILwfhF>9}wKBP~E ͷse!D.ž^<>rgv~ՅN7Q=bWqΞ7`BRikҩB!33ܯ8n0pggV%OR(.;ʗ q$X$==pN4^ERNݻ3ƍFcdTTo`~)r5~UaVaZ,6^;X#di‘Z-ue0v#f@y^VW0kT-ؽBx6M'²l1自e2YZb* asDxA>`[R{C d9wS. \>bu뉈hʤ4*W b^.!E]], H$R*U  u~b`9n!&DV0BdJPBSxX$V zy$b"20`B ĒT(3yåTe A%ka8 \HEp:-$e(W-뭩14Vloo/1e3?Hy<1GuN9gk-~q?!JgxNДכe^+ q3Ҕ(myt9#yik^Ru݆cb<:exNYJ~pI.3"H`%%m2 䮥˜.7;Ǵb0)ax 7Ͳΰ01 ad?1QQvKOȇ:yҤvOI]n.`NL&0%,0͢FvtإBk M!F"&P9_!Wh0x\'P8;x(ۀʘSpx% ӑo!(C! G Ԥ8񅅰2F#Noh'Nnݺ\|0[u4cXэ7xժK0 ŀw9E"^ZkMkW>x<BB൵@ށ[[SggJi:fϹj*a']50 ]~(bn!iU%{yst#Pdٽ ³oNŋw* jo|DۧLD?op S"3K۱|sǛoxy*x)B>P1NIЌ(l vPv{ vqzHf#_a/+MpOMF U6V`Bnb0l M!m^#ؠ+PVۭ]bcΠO_PjzNnfQ)*" s^3-$֡p:r-$e(H!NgAʳgRRi:Ny氰GPihh8qy"8|r%;M䷭88#\fT:<5:)L$N9dC~2ܝ.2IU*Ѧ&7Vi,+e ao}S#w B\x;rjsd:x* z5;t+0Edb;;=,Z?yҪzeY/~EQt }slۑ~W|Eb" YqZCϗv'U,9ȭ+^*V{5AQѳHЪfttD> >1y/Oy7>|0&|1MIII#J$WNaKAoAqf̶jwE !'T H#U*C&oѢ\8+ g|^UݫE샤t0ͺ]/wa(OQaa~T*ӻ`H?f4,N R(Ny=QnW ׭[P(֬YCۼպ\.%|LJO7PգG"Y&y:'R(1C__fTYeF 4_d~<%0@,efd|^Y)Tp>O<56ۓ04lu'O:;D{'lwZFEE 7H8*2B\K. 8Tp4dc+~xPZTfʔï)G ׂ 7Pw1k .Hܵ3 [`Zp(55,+ gz, zLddx@Z;rݍTSf_J6E<x_Ac㮰9+/E,wuŗ:QQ%k|DjFOuu{+C'  9u÷ p)lOf%RWBvgG)'9媪0ҩPd5un .Cbf!Tۅ ^j  <꙱j0}[#х_SS~[QR`8>íNޖ!d-!\w. 1kJ&NN }5xVXbV;Z7wZ 8Z΂ ,V KHҢH_5jeg<˒)&SGpbu44섹U3L\, Dx8GԜؘPUU#Hf3hZ[[R^?wHJ>zcbbgF?ή&өP(2%<5&_dD3N-+FcbM0ZAӃ*e(pb$ƃ0Vbh#bIoL ~,۷EE}a6@˸\nZ- Œ#6nNUB1RLQr/SS36vNߓhsrL0M/ŤR+ijmH ر9yғé0P00΢͟ǃ~&W2fZN+ :Z ĒUqZe5rxg.:*I!"FKZf/""^rTio/vg׾[ i8Q3e(HByce9{LiiIXXX 9gEDD455Amhh0aǗ-[G%&&.^Çz(ًBwOϱGC[7b`,^3g@FF&$>ve_exl/2򉮮^/Jilldܸ-XzBadR\E1:xTfЧuvNI&ǓePYQޥV$'->K$r;/gxąfbp_t<|艞'Ƹ&O3ϼ ƍQ̙3& V{uMlZmJJ`ʢ!"×.]_F KPbd_%a6[)&[$n`no=~5g TQvvƲ.gXܭPr:JI8Ę|YUa^ ۨX hmcLJըPnhe^}bb.k#k;UWzS<%,v[xX!KHa=4?kz0ؘIRSB$lHuZH2؍L{8Y*md,TysMN^v/G$9n6JedDJ5Fj5ɜ`zK6m΄=`k1V[!_|c=iӦ-[4@Kx?,W(---a}2 \Eim SpkCjN]suG&>/ץ47X|J.?D*w z;t:{eBMvGLO.8VBq,ī՟hΕ<vEAΎŒb&3.%ΜI=2F,%5TەJȴ]Ib>rRU7ee2ߵZwJDr&2K㈋h:MoS4c{<&7cUbL!RLVƗ32va02+q0u`zU^0e[z{3T?]fHP*&Yذ:I9ZbcLȃ!q7'&HR*!;sDEteļF^LfXqr=7{^FIŮ8EOԚ7tۇfիaINNHZX7|?~<0n 9,aw5l2]{K#0_ KxmvpB MK̟Tw{]f ;hFE}lo?ץTz}z(qNgz镤l69өRjkkeggWT{}|BQ'$-,MIr]B /kKVTK$nXbsR9қ|m"ez<䊇u26OXWG*YR+q9Fp8i.X}TBq͖j2)`6uҰd! dvW~g,+vqH{#"ޕHV=ٗY{l#_ 3֒JO\TnR,0110ޮ.ud rZӈșZ]%ǻ{nt:Y^̟"㘾anQWW^&C]r~U$wDF|MYocm$yy3|v_r֣gLNʑrfdL*OiV؛_-HnȂ LVNDkLO9>#yFcg4ZƩT)f3uur=go9H~tLNRKy**j3Nv^{%umƦmm\Bnz(}}>Cg5t!OHh4k=Qۿ3eSӪƬ}Zm**tm0em|ߑYӦʾŤ}3WjrK|KB^_Vd̞LJɲfElbQྟ8*lʔ)=#.#oĒR:rHnN 1;'ؒR vd%wwuGDFԇAJ]Y3r"/d1z&ߟI5Qs~g|Bt9sl$øILE8q]af[rg>Qs9E}fJ^#i_\aݪV3%6kXlO$룕lMTB!5{NS*ɾ &UTC(IAR cGGJ)<wXF'X6_"FTZwvD_~ye1Kv,>1a0*^dlVlߡNmiX"I.u(=!:pPsgǍu֑eqeuqt"hj"cctLPblhQr@M퀈a4d%oVԊD~gS?>?/NZ 3~CI/f_Z"gUOlYcTz b~lݻwtwֺ[ަ7Ο?d[[C:ܧv}lN ?OYL7*yxQíGiQkftr˰ę),>#ץ?9*nfUVQm|1:xvd<]\,B_mӄ;D;62NDQ9Llx)r\1\ƀF|{#֏M&.~Y;T3<1(ȉ2Lر }{\糑}'|l7XeIWox a.AVe5ׯ51HL[B/yKŒI>al~S4G&eHmGQY +s3K;%ߗ.f t 5o5/9i(*"M#<4V7{{з5=$IEԟT"-ĂP*JML?MCj02TjBQm$~xg_e$wxdTf{fM6zŜDIxl%a3t*J,A1ڼ{a%z-PNmUdY“s>{Beͅ-_EzyH8{܋˾9/? *YK=5qO)sLm'.N%3Y$GÐh-fZPsBAn K79ؔh/n9]߬8UA7Kݲ_I_zQN1+=+[DC>N7)6K0sCPt߾ó#" # j `3J!SQ)3'ޯpTWN"Mof$cN*=?lp8w@RG6/8.B_o_>b~i$h?x]H9"K2 |lKY*tu/~8}BHՄf#Ysu5Cafrq'! o w1jU>^kk2/,lkIЀ CO Ū7^ڠc52IIˌM- c7eXcM?DPxVM%`Et^SϩQX-fqda?[nA r}$Auh6@=Gr="lnc՜r)$Q2D$XJ5+RT6JmP+/lg4qێThGikQOJDuW/ ۖؼdk-ќxl֬/%L-|lZcCh @LEk'=A^'[Jŗ ( Y5{fL{&nP~4h}Scr8~  Ш4l."j+K(ߦQk.<3A/2 /M\xCH6"Pf6Bj9_%6tyz9ˢMaؙjhRUp(|+u_yK HcIz 汽:F0-Vl<6=tG deÈ.Jnw*oUEB Ez}vW}p:;rWt: h>Ux8L,aMKxye.FR)d]EɕIlBbD[l3`l VPCҾXX =L1ģV=aGm~c --Z8mNUֽ5g;3L#]ɤ+j!xxڲ2 5sՆ|o;-MyƑ!ՄrT&haf3AT*8`Hx3E"SWjڿ2B!a}+;v#.S9M",~E=25YnظB ;%C&T'V?D\@ b@ΐ: ^(`0iDrI"EQܥfO~B!`p/?Mg稪_ cyKor{;g6ɓ>4QiFQ^NSya "*F,ǛW8WcΝ[5Tjqԗ~> ZTqIz=AB>xQBNfea,VZ])v5_[gj4C[[$^_`)c͟4`Idɪ&n1pujhMM+29;KK$6WWgtEN8qR,ʄ=d+W`F=hG=fdvd yB:!p%T6.l?f4Z-~23ʨ&li}xJ%33sLܵK{gK_Mx Z,khOU p%!$;TIu Su@Hd<3B-*"55h*1L2y9G_U9׎mb6ddh8&-=^ߪtw)t&jD8dvhqNjڇ:GԎ)h@c(Dbyvi.Z-:__㏣b M׍}# wAoU䋄y =l'|iNΝM&#Bp~vs5$;BBR><"Q,I 22lXEz]|]};w_Ht|ZCL0*֕ a^̦BC>S6~*rT){=w p4"1PJU|إ=Pl )5:NpxEAHm$b kKn<8Oкu^;R( E۶m >p@llӽPEeeVff>N> w#G{9{wSѣ2n ǫ۟Iĉ07-MKKEDDn 7wРAiɃ:ߞ={L& Vbb+/ڷtB--EWMm u#i)ɮPՆ Vm"wb $`=L?4҃#ˌ%p|rdJ f%%洮y2:ߢbmm!J"kB) $['FU{i۶Zwh~#0j=\[K0=I!O(O %&4-E,s^!1' x!zֳb|(wBE{ p,ɍgmz"绂/T}8Z$}PRw0vFFZÃ9#sZ/X"vVŜu JݽGj`h3G B`2010+?I;JbB>5h#5($ll/ZfułGs 9xpN\04r;t,kke1}g'/4ZC|T>"X* }W@?Yf5$IZLl﬷;g >YQF--A z%"+%CůgfWz{s;}[1#ڬF*rߨTߠG?<mT;1; syع3"22''h8 <ڂ&O BP T`$nNI)[JwKՅݝUwwO) 7ER9u%P֦Lj.zaŊD]c^m}v5y[n a0>˯zckK<) m'N9g߫8O/"_Ϝyv;l_n۴mLtTûϝpГsLJ\Tt6%a/>3[np~~>ǎ퉎:w,y%sz*h.H^^{}|_~\tj==;36c5vB)}K5xt?KyBi R.gܧaNⷠlq9s'}ßK^[_~HL?gN˳% x_s~cPJ;rݸqnbez[|eo&'/]t⷗<xQ-eW;sV c瓳پr-/ů\I"<6gQ"s0QBP+!5D-Hk6dq*ԪiD҆#ei!~HhWo]vN1 7VVRJJ%2#G Bar[W{>lV"nw6Ҷ6 0$v;1q' ]깥V޴?ؼ_}5{М/-2MxZfy QJJz&6^?iba}?,de# /K^J~2ç IqGXeh7yAz?@U(z Q_R|UCnSN?A5I,ow^:xZmyY$) V%7W3 jTU?q^CXhhJDI>QӲFBW{Խ`4f9aMv.4{4 Ւ dj6$9>w1]^ziO@bUW Ym_ۿK2|>a-Ō+kkrҬ^2BJCt"=*Ec cĨ,$"+moʠn'Dy\QG߿3x^#8bNf",i;#,\U b _2U;;zYO]?kgG=l 8gvu򗵭"'WP9~PJ{5 zM*^y5p 6,3@UB2t:-cxSJK˧_]?E7e9̈́/"!*gPdP{:4eܸq;w>lsZdfv=#<Eh\nI+ֈ\Z-KeC['(D7Y1{tULFѶ[PVXk}.R%|u zE.k$Rߍj%,{#HG&TLɄ1DO[?ghnXꘆ1+̫x(׀X5&JG"L>- N!M1%CcZ}_@f.Z.4 o0V (M*{gOčD1UkQ"&ua;|xT}Pe!SڿD,CT1V0G-dh qE6[>]>Ƶܗ=>S+bh(R w,],i#ggRNq`]hc#󫣌oA%UߵF.|pN.F׊" I4r%SMUYA-)ae"jd(#O՟ӼlQ^1|/q6LnHdn,29%rq:y!>JV5Y<`,ӯkr/*_ !ю[(3ng`yyhC"%s7$y+|ֺ=Zl>70%UKآڃ'Ze oipX geӦ*#@liuRk؆Hm4Q;$?w66)ldybS}T&>v~A9bjB0zXH]8v_:#ԩ?SFPCLCٰRzXÆ_ n`4҇ ?ĀH-o.H.ԩSgLݯ߮]ggWVV^AoAaIJBPHRa͹{!w"DTR *U8.GEʮuI+Uy<⍊]>uVLs=BB$T%\^FP3_v\zt:疵b5Nc J /n` 7"_ΏP# u3qx4T~4vHfS,>Y<'!C!5LA{h:!P3`l&fs;1f_ *L3C90cmpPl6s7*oJ/[z* ݄m r]q5>,)Y+v;S8q9 FBI/_Cf۵nDXH S.ؿt Sُ&p3'@{Y2{4nwlݲ%$D.zSs3ϯNMLP 6N7hРިN(I$Zyy[[z:e{{BBKBuE-$2;J̰Fpسl'yxxLw:2 b`&=X1LTloıDRF݉NdZ vlbl߼E/nyf37' (Zv"fYwmh::j6@M !>4WV9b\N&C9ٞ!6_# MMǽ?4<|-$I .(69i9q̯ۜV[ |.(Odē=tCC#@5L6M,rB1L&%؀#{dw" ?Gy|{"(s7bމH$ƣ(1Ws\7 q}|bp^3,Zw*ј]8n#D"T5`(e0^z)q|}=YTd7RKe d)M'4.N8_0ᐶ+bĢX,0E]W7(xhK,kBՕC!!(3yRi_lc^RiwPSC$rLJ ad}weMڂêJUvr̓Kb{FNW%"ηejܹs^^^}R>r/ƍWXX,bopnT&JKKSSSz/H:0)"H;C[> Cl͋uLZ pcN@ t5v͒HmXܽ_#;x |p 2_ ///iP?w:wMd:1:jE3g W\*((jCc#f+&]'\1[<*8 Fa6^7vJMqjF5YC6vpT*TEko`>?t̖IggU7 V49pkCldA6eQ|lg ;P4Ů' }K&KRkt=2vԮ7HY [FP_ˋv%j6x^ܽsC1].漢Ɋ-(X9h+ZKBCJNIcN/$AsRu$!a~ >ѣGO:q<=$%K.\PSSOC@A?}4h>e 4j{W㟜={ֶ̙?JKKP?^2Bk_RZ 8l6i4 ZQ4U:ËIXz!jCtPF3~%e6ݟZ,Bf;'qgxLզv={IQMݴN)jգ')~EE>ybO1ĉꓧHsOrORuu;R_r%)費htt}X,V ͽ+60Id sw)/;CINZ׊ B#:N&BItZ `= BjE0:\2뛾>~68h8z !ego>dr0Hpw`'*kuC\RA+Wju6st wKP?Yۈx777ow<^Yv>h_|Ţ ׮]EYZ&0G&&&M4 @H"~ vCZXPC&&az!!y=ׇgl_V%$4tK Ae1U*UV޳` Xz?gqcBWX@88}&16.pG@@ pؘP_@XH&L|yz :=y1beUUpp07۷h2y9]@;v *`A .]\"\K.E߄ 6~.x$=d+d2Bg4IoW.Ғ{;;'WBqA,N||5{lPD<oDÈڠyKMQcoiwGD$Rb<ѣ`@Asf2=xGdDG%=ARzz)S@3عc29pPAZv4hwz w-  Ags8 u(`ڰaL1|820[dT$yAƯiY]<&80B x :ubcc@"?% 6 ClVM`V\ r^ <=FW|#jyH84;\|7fF""fȑZh40L@~11;XA֑[/^꫋BZRx<\,++2y2 رcAo[bEnn.tmfBf(mЍ W^qZͲEM`pG0[ 3ӫd64qxqA^C._)2r~pRU݁wt ⸡{; W.Dc7y{!93%0`6.b b|qmRQq1]@޷©p矛:e<~824 PJ .-+{!f V0 w "HT\\_Q\0\UΆ555-ohFǟ|g>UCokm5`4v[ <]|?߽{721C{@@?~mmw}y`6˫LNNVTUUU|~짞jS`H@OEg_SRR(KЪȨ(3V{ckܴyZ0~myQX8fU +6Yi%iWn#"fGnMq­͑?l>TZe2{>4*${FzqbȑԴ!QQvTPr{9r^|4̘1KeT8lw---0a{!9s2pѣǰXLH _ho/ m@Ç2ګBՑ 2$矕d>kdٲe7vT"Qd!]xyzVdR:t:Zll <pE"v(I OD/@db}K.H[~ 4G(f 1GCE͠&NlniefA9!9sX,NIN^bpSFa 4BV;csҪh;=#)NfvR'~3df`0գuD7T*۪D)g5 cXrjGF[!szy8f>zX\Gaw) 4h2;˂: fK5bv`t8}@HuXv*j kk}=Xu+08e&t,~%8/vyQ.Ӹ:O?u-vO[[ᇙ>z ӜAl\qT]w\X~ZAv_zGu4vT D"8ݩ@GK!(.ך)¨6 OҜ.qrt46|TIˆ ; J>5#x߿yk}323z0D|ۧH$@s7yP*UAa{ ]S\7wDNAh+_ۮ\='bAXѱ;ؘ۽3]@$ A^{UWWWRRrUgiGr_P*7nKQQuOtI&\&"% zoǎ1W(>?F۱;tz*@PPp "jt΢.2d['O}G=KH.\X,|>)== s͛wG>l6ۮ]"á((G֮Tfff2K. JJIDb\\3g_ Q&)NǛZYkH$gn>i@*<(;gzU7%PoQQWR߬LWWWf'OH$JUwhy A ߳w/hcӦN_"QTTTYYY|||yyyVVΝ;anٲٳwlYmm-^ӪB'_gVwGÔFg@ݡ뾍0 gwYHSJ3hB^<8u8gq}MII?tWP"]ysT€[xR@_kLG}?D-|m u"XẔCR!kSv~ֵ^Bה]9bԋͻuyxv:Ft;v]H]U$>o… T J|nnfNf7mhZPP]h5e{G>bx >.,bF䔀 "omޑtwZe`LߤX3{l(vH4vRT{@pPMMMmmn`iiڰCZV*b2 r7iˋA{{/o# kFR{nmU׹ 0&99*R(R<}G}KtgG}GTTTT|r>/;k{6fxwP`0 n  #; dK]"J;ٟB'<}h m'@D1Lۧ`Xtn[{]wFEsOp>>)7mVe!uH7>o;%oݞMa8=(~p$I}EN6vRz˚1\q5B$W: 8)Epѣ;=BtjTtˑ%a f3qi?((6hˀH)#q]Mb&{NM8A7z ! $sε)f^T\l4Z-:< K@p;u㕖 "`8ydСv豣nTǏ_ooÖS.\SGGGnoIUUL&Cӧ 5D"^w44 ohɮTWA <"+3j?{l-Dpآb~A+UUUSFF4OiAFNLL>;~^cDd$H۵ j>55~@*,*v I=yx|>ʶCcwK@D`1T Ϝf#i8s.?4*N> nj38\755522ҽ P `$H?? 8 ډ<|Z7|}G*EKkylEAa=:^bBKp x衇.瑇MΕ:\O jB1pj@M@`.DRSS+,nkw3 3Xi Z?qq D[Z`#Muag!l$S3σ ۯd|L#N/akkmJ%x lN+ہS7$::|kKU F ͆fd#._`Ek+vg D(;v@3?v e/4*Cݬ؉ *9ŞP B2v= ;{?;TkKjkkm `OpPB,.}_؈9aZAFػ?%3JBPz`AEEYT@ݵʺ*v]Y{A]AqEbCH( $$ғI&afL e {Ͻ{=g/E=2n$'4p=ϝ=KGM$kΙlY'All,?HvCv25>NZp!sK{[$(}3*2u+{bi`=P?1_`iS@coN6 9̂ɓ0ee`^Æ XV!7}td5*) e;`ӰSٗCiA#.)-χB9@z-D`>Zh"hWĩ=z49:u`._9r$9^JOV䀁ȜSi.9tz7|iiZ&hhL@J5"80P8#1/ @$%t))@syyi'S> Stb,g1g F &``W&OBa3f6)) @ǫI`Ç 7Hg>Ǡ nF;}!}(D*,,L$&De= L0C &?>2"rt6D]]ӧ5Z?gTx45$bj$0낂`~۷Oш¼|rZ?{,wIp͝KhiQ6ȓκuh4]kpM] 2Y#{b<4njS^VF@⼁ݻWo0@ħK_:7thxXՈaÇ3{Kuuoii7rVW[3ovVX .~J>l` /\  0 qqqCĞ=wxkDϫcѡa7ys N\B@ R3tzHe0210])^דȊ+9H())Iڭf۷oĉPe&I!Yp=Zc@4"I֠ -X@e@/85}6'bRrWGN 7 &`n`5~7m2'pM$=^Q< <)Iܹs!`r\ 2h`vH#LP~y<_I@`IswBA0JܝwŦ }]iUUUM<&SHp[Byl x㡬f&64!hLyy9y. ڐOͻx"0hTA"XE",,*;wBV@%lfA %"*jʂi6 ^mLhbI]03 j4* 3.U3*6.NP1(1 JLy`XTh0YևW@ u6zSWS¸@,*.kpF[/x~l>  HnNX>c 2ǏMǃ‹h$FJ,G[;/_^d tLp%}h)p~dDv>mxJZzztT0Ϝ1` YBY3gVVU=Nz.:*BǤ99͢N`[O536ijfC86'f dщjkkSjCɦ˙ADB@Th s-qpΠ<*+(l6 ‹jkbIPMwDk1x޽HP_JwgťK`G&:~njn&'(ah-9wP>h lj:ɡ],##s!#HLYYd">r /^fTpHwfFɓR&Lv)L$1555||2e0Գ'F˅F6 Dd^MD4T L$4PFvYt: Ma8D2&<<(}`"Bɀ F$ D9Ot 'F߃ O7!|{_,9Bv5gssǎG׍;ӹgώ=L4i3g$OM&- ̔ҔJtگa͢PrIIHI=pxz:oΜ9,(Ȝ3hиگwahizB&FG466@ 'q'NNt ))̪&ODk_|H`'Rz:JB= ̾#IYd;}"ۛ=s60GD:KOCC@ɛC\6۷c枝ŋvP Xnn-,_Xx10$4/ܹ &s.88*|˩:g@]zذa%%%Gj^HL7p@\q/06ctppv4 B9{6@~|> jaA;5qEdLAKZ4L~^mF04~ ΖpW[#?3dɊ+q4/-((0++)&1BMS cbSqJQZZv8rXx8D(ԣ`  iTXL0F/,8Do$& o/VuY0L\O3;8>d1Ѕ*Ull,Y Cuh94tQO?6JXt|ϓ'NةT7>|j2ɅtG.%.F 7 /HA9C@l8YX<ﰜ"0a+ 'lH=CKaHҎATi+p@ppq4 J=:E!Cb` <,:N$= iH6[G j4G'iJ::БaATjHg΄ON qA}!Dg299%>E`zk?o!O{݆. 5>o$'+xr6jji|(@@'"[5L z(";%oj*%^M /CсֺV_Wo^RVWWAn݂ˡRg AwF۫ x\.. `U *  y:⡺Y[K3NcxYYސV_KKJЩf.PBcq`=ryc#JՁ_C GB `a 2DT]m-HepP+*` U!!vT644 4a`1`@=Z TcCCF{:]d S( @FNOPT)Z 8aC  t`Gvd2e':E:i^3Xiâ Djmn-UWWQ ]Hu11 +?t xDg㝿k>z軛{>%|&L8ug0x(SL~:tP|p[<)Sȩr@KE0 ~Ν;Ǣ=~Ygs9x K`Z 8 :vF D^ 1 bYp!^7* !JwKb͜1رcI MEMMXj2Q]0G##GXagzBadz0=-Ztt6V͡Ç'M׵uЯr&<"4''R! d%b E0A 3KOO=a*-9sfz05Νz؜ٳ!#1 ***ejP1cs"Aa%2N:Au֪P6< IMsH^mv6tfܥ zdY ZHD@tiSzh@nn.f"偶Gf"hSdK7`@0$@:|US :T]#XzG`5|KP322jx*D4>'O˜ !ٓ#5vOTSIq2``5``jkRTRSf 0`ZX,UXP`2Ģ'jE"CKKڿ?Yg f郪cp&hh = y-+$ǎARBs$6%02rrr Xٳ*!iP5:򄞠@mY/Hj`l7 5S>DcHR/JaMyCS,1//j l(z8"6$5â233/Aa,z&i! ܲA tl(O c+f\N"b0Iю/Q e1Hf dXZJ &R*Aajڀz JY( `D2iSZw%2wHdbA'Gmx<}@!% Ͽdku:Ν;XڷO?fkQ9`i7Xz7g̘KvWjY[!hj*@X<>H0 恕+YA6UOHD"њ5k1͇O^P9c&0y34.nhU>|}4λrܱlfڵv: xᇝ0zt842H`uE,_evŋ8u8_q =I{ fL Pu1;bLͥǑhd` [ Ӊzĕ\'Chd&\׉D\&L&[zc_D=׉4e"1Q=zt<`}ŋ !A!>C~~a {bN:+>9{q. tM 9ðmnrl6%df mOWP\Ra_?쳾t]wM{m򒒒KlJR]]mX o㋋ǍGz +J믁-+/WB cƌ>uǃ Q$>#FT\4R?ܴ`X)>>`HllSSB3{6̙3U)YYY\.}Ύ͡--sBQѡC]Rss5k? 4՗d}GINID, b͈͛$Zƍg~ycii6XWVUI$]vA2?8bg|NQul~灃]pO)$pܳg#""TvXwFnn6M t 9r89s椦t@4СԘ`ciitX}ׯͷ}qJJϳJFDDH:L%>uѫ_,C?C7 m,9|gshmm ۶}7puMVqq*#A>ilh|ע"#X-yճ%=7nݺjժh- À>bȐA}oߋ%Xpj:dg?|Tz%eu;'x_yu̘esXmsN٫@0,٢ofCP?IISǎu]`.0ry~~2w?ؑ]ư\RMMF ԑF:s >_XXXYU5!%%''↞?ʀ bIW2;ݺbnjх&Vz4ZX$bRi9,;Zm[.NL&jq{GZ#r;/e #z+言V qQ\Gͮjb`0}E. tY@Hhhus0N,Ti˿޲^M%}5K---V5((@uunYOJC*<~K/oo,:rm`Ϟyb`p=b6ܐH'N40VRSS;?Mnyv^$ka۶&LXr Zqn܌/u=wb d4;11gQQQ9I.ʁ&#Xr:MNUe1c!>lpe*wu8Bet$',FҭewT:|nY,V9œ> %uKkv!@l8Z& >v !䘳(R':- mGht$02hD/ie.I.LWNpqwԩSǍ膆Э9995qɵ|狪z3C駝ܳ +9#Ӡtִ瑹ΰ{&믿u+55o۩SzCۃ:zL1tz*OK& wSssVvvrJ 'ϙ=;#3jѼ0's/+`KjNe2Ps_|iCQ$~CT?H<7Ys9N _֫>-f?_Gk]6as8^8NX$tTF#s. N|;,]tY`괔۫@P 56,4T$A_BcF]χҍ늊HȬ{yyT*4`TXX߳H<@\\\QhUw6p5봴4G)M7輶n>U\\[s)iuVVV:e'QHj(|'K!Lb`ȑ7z6 ٦ٟ|6_>16ȷS[}t!{M}bpS ~žnߨfH$”^?jG*8p`ذaХɄjkK_??A/R"?@BT@9>},555.qocF0T]H:H`hn?am, ؝:t-JNN۟z` #6oG|^_,fs/N2ݣo[-PQQQDDO<  |}}C K|i4Fnޢ]F6N1$Riy7|ߒڤa #ʾk@oS S.42labk?d2buFyl"<ˮ, NU(8JPi,y5#GLA u5M1̓ZKy+-"_χ91 {: hKꒇ*"ʟ xֿX4;& :Ա$DqS~%ĉ7<<| -qp^_~uҤillXKohnk ---i.=e׉dgΜ@H|y͛y4w[#'PQq B[o_TVVh2ziX7n滱!VyM?:Ju%*PEnGF 4t՟61e4=-r&khG=aa__'eQh=xt1 i߆(am[x?}~uê\J~էϊ, R7xo`j 7}߮,3'RgMn4DXWۼK%>N2>./ECIaXƟ>>o5}u,XR&,;+.:qX|xꁽ 0L#?Z[6WZv-vr;W4>s=cMcj[ݸ4QG>[(xgx<Ɇwh({ZG}?/<$HVUKȦ%p11g8,U<(9\|_Ea(Sn >ͽrJB3h6fUTXmɶI!+ȧϣ,O<cuaT2;}w*mMP6l-րV"Ufil,|Oa4V[k"0β7OObLVK|dneg̘6\ eѹT{r͛CC9s&##Îzm6ɧޱG\\v2v;?t> $GTTKJoŋYttuÎbsϊ;f?<3=s t x? ** PT4> ikW۹%%ժVL6vlb_ʯM2%#,W .i]¢V__8 UyHr2 Jj&4SwF1K'ßy xېli 3ŤfaX-lN'm f C| SQsYsT\y$?zxss^5I܌W,8!>s"o»,gDhR' p<Իg1cmPCqaxWd|AK?j8 +Y,%%Pk||d\L{aM ~&%%Ը_ •SĿ.d&٩tyWi"u*b }MfU6*&˗/D/=8fKP(ϛ?& a8v͚ݻw4}'N)yx~h<*2oS J@K*fwePpAԇ`/&%c<\h$ɅVCU- JznOMͭJ'О޻oߊV0REKm>u*8{i@;xf˃A_t^l9ހQ2%x44/" _7јx@ BA?ai]c xOETǹ\HSOhD .ӹ?ch䚚sKgj;4oʐt/ @gBN[wTh5ii~b s--}ۋq'R'M-q9H'Sdžq9V.;drB( PrŔd4*-u^ӹ%ep(ծhZsKN5P1 -|L;Vy. ӹ%&-9[D검 N7>#mp=|n .VP_?t L\\R2oܢ"6;mڴSS 9k~3*)/QZW?0?_0i;=29h_!g|bsrrFЇ^Xt[ر㫯9M}$X&yGvoqM6oGΞ=ۭf8¹szu{vڵ[Ouxn)! &O[j; e3))ڝ%xyRlmRءp8jXnLBԍm@pNdj~-ԙ-Tn`LfK> qJj13ړlWGj5Y"ŔI[n>}Ӄhbw|}l1ZiŁkJ\v%7ĒN9MOvG@@kp%=ŋ$ {)^xr!:D1݂7.^X̚9{}6d&˯mչŋDM0%&Q>+| .N@"yCOvs}qCj^Xx%jjSͽ2}.~dyz]g$}*:r IfI~GC9… NKKKHHt|>?99lG)3tP%%%!!!_k˫q0U>Nv4q+  1t-399xʓ޽{BJ Er~ չf:O7@?yZ-j?*λd^s˖]3[̔4IRr_7N XqЩ7ҽX-QN:4q}n[O"066tV--٦蘷MƗ`tAv۟jj$ {`n8 #9r8/<%xKjE\d1pMΎyyUp8`F,ރ59fkjo{`H7 ->|0өoװRi@@ȑ#aKM2D"ɡ (//5Ýt=Kح/ иҋ :pkSʜXE.O> Vv]zix;o P\.>#G[ ;_aC\FO=>R2u‘ݙ3WEBzrb V72*lHll 8<-ܵ{+VܒVaFna*x._zjx^ժ ߵV UcYڲB&D.ng&Y,V&T?.;`w-oEPn B ߈OfnéX|NDdfyX@s@,KyP : z*aCCĶۊqj|I]MnL. tY@G7'@7f!($>q^!}45xy \1uyBjm6ƑE|Kt2&~/'R,O@*:n0/lٺ ;naIc{ 0=rs{N}!XV9FNMMM3=#H *V8Y=FZcT* ;xy{Xڥ\nnWy* -AR\~:+ CXW_?qif<}:4w%(jZɢ-b;x2YtG[ 8y⪨ myW WP?e`iuz|K|K󫑑hnDܒ+W-|5ӺOd .]N2D0Kn +jow,TK*#[|ƛouD ^,%Iw٧uZ5zBBw76̨᝵_e#U'%b[t|G\3 xycUl>owcI9g<Lj%lUPVc~~!*j!Ji@oQDFc2$  ý HK*Q1G "ۯh4Jǫ>?Qip^?/L.Wl69,N2;ضm[ϺjLrw颅 X,Xw1^vU`]qm#y)813B˖AHKKsz>!}_D!Ãq=+nnr#\&6&QG>BQ:ZҀq>b)sVOF{Ϡ,764ֹds/_;);DA!C=ztMS;w\m~LBUUVE}nmO47m?٤Jų2fr}OFַ\[-A>$.WRy =d2&7vx%b]V h}{+&&5.Gynvm:J \,A8yzذ6.-A&U(^`Ʊ4bq^ז0 >'=ZsI`h#0n)J . l+.+{@V=$~{4dJvS5{]a.~bBXlw=G du 0#a 09jAOOX,&L&JJJyXqq}Ta^|3zh.ϯp;zM6^j"x'N#G.^kl/_P^q{yŵ=Ts_~j@IqVMIIA|k /_2g&ߵjC4mۖ/޳|'> lk~(w{XЈ %K*ٖ$$/;.mENbK eUI{Go${;\/^,=}f}ߛ&??3^p<8l6ڵ7\Y@X"m6;8o//DrAɤRP2СC.D̙ޡaa[lkjf " @Mm;e{Ǟ30G7wӦ9-%վ:.?0c<"gp111 K|!::[$`eE׾7`B e^{af&Z.sR@` ??RIeL^z O>$&}=ӟ 4ow?Mkטբ+/,,b;oAJZUS+Pk^6z׎<& *@2P_|az6:rZ? ? T_ܾ}eTFσˌ֥(<7-'?]նQׯ19Q6TndjsX*@V)~{/2zny&@$V?dK3zG?Z(.tM@~<>E(J>MoYܒCO8כP*TYҾ~ Njk׭JOa^?&N VVROhOߦ=A$ONӹs_STV~ӇB)-m sW/37?ե|I*?В;+˗/h4%K@yyy4YkwMOO% 42228}D"aII ptddڵ0 w2e|S֭JN;u<Y9g7TPPx-{ ==7.y'o7gd9R2GQzBϿ'OrdN@@;.\DGqDB zٮ&0bq: 9VNiڵ4[PM#`ҝqzy` ӧUnPIXy^yO̳VWWd^6[4کy46:UUU*17E999o6mWk +((] :&,P\ߌGBW=+f =5"|~RYDq-J`hoP$T*|Hhڸ <~fߒDH4};6I>"5ghɾ%^ RiRx@?moY, d `GFtX A:onω4f`5AA^SסpoIU-{{g*E Y]-b鶚RQ2d$dm&&ʸ%x\0(׀I@ϯ]}ߥW_.]K@N]~2cu`P/cǠO1t5oRt}!x*(('Jիx* R(>uuQBm]=v93:&fxx]SSSjZZgWT"A W__Or<0** ް&G9̌А{{ qBWT" ! sXnR]c`//9rkCrrxHo[?d g>=đ38@%Ouܯ\1ZZɽrx-{̌df(\zcaaapp0%L(MDnu56&}$a11{E6D@?IDɓgcNɄWXAG*ߊD_ 뚒X{Q*+{0gL6YHuK5/hR*_{%\Σ\]:1Դ'~b043n//xakq2Qe K@i|9E" X^NGn;o"F¨Յ/k^?IWFF_-@7W ;ёk}drφ~+G2Yq>׍w,3@~!z!za|r^6l&L fnI Fl̀띖C&rS$1ojjκOv}~ 8j.;;kb|qЉ9TX̙SE+W=-$lBQWh:v7%^T7 ]QYYL>Yvtt9ɋnJ+WjjkyIGdl .*oFG\I*mי݇㒼i5Nқ΅L,xju2':ɹј_W0gV#xQo!"KkfT6Vm^TkhRםdʀN*.$gJgfQXFrɸ|ZvѱyBw"۝%ĝt2!0@CMINF$˗uYХ #mlllVXrz6+@Gw2 C Hb!_^}= &p=Qpu p_9}7{baA$Y##/u$H;>X+B !.V:t @~ț[ K1,d ~~ͬ +~'^&ͩ"u٤VrgΜq~zYi?ן[|ᛢ%x`FTc$11s˄0g"޾%9 #rԑ%5Ory1a4r>>)x$%qBL>"4=CDY)̓t;אI"ZrKv9/cz%^^n9̴FN,j_ zvpv~&/CZBcĝ8壏=·32|4\P|||GG ˿>CjU|f'cqzWo߾k׮9rw/3~fo7#`un5uOBfFx›-g֭WURvZ6**J.fĕ)m߾ ɓVgؼ({ d#9%`uѣ*+Ö͛}G&++… R,9)6ݷh&-#ÿ{M96RAa8k&ƝY, _`G[ c0( 3^g/,{mC9 莬P(1C2eq:]ԑ۾e.6X|\rWd{k^+x̐3>o)RRj0a4Ȉ8@UQQ zXYA̜E=PX>kNm۶y]?th8ULWp̛y K/|'Nq I\)))< AS=0/..n!k~72 ;ρjĮdzkƍ>x׭[-''h4 VX  P&ZN/WOKB}~ ִ,TVV"4Cu˖68Y׮](/GE8UZZz̙nfSJC*U LRRZH_.VpGGIPP4',:Y,2e.EqO$Rs);JUxq ƼNNξFjC/&&=*,Lߨ9rEN SN|Օ mmmpk_F!ıc232\,ZTpuݴqCes b-SS^|Np>._ b޿{*;O۷*,P;UTTT$˖-hο7bGTSKC[ 0q*ն[#3O=t C?<<66ˋfzd'"@גt *++|W_)mQؼybLNoPo?@TM?أ553l R씜-toJOZCsZfZ8Y,>nIͩ2\,ޛ4f7$^>,,|[|KVk,l;Abtxp;^Iv޽ӟp7<8u伜Yymj Y3Ϗxx ?fh_w۰꫌NQѪ WEDB+>!A̰avݵkڵkHU?\ڽ>VBBB ٢D/PTNaĉ=|IP(A? ߢH$Fީ]YP t^~dpJ_W;۫O`cGmWq"33D&F-%mS0cito8Hď?8wF_o|㹛wShW|pd^>sdXrŒA}J鷿5kKs(kUU`ŀ:`i===p5l*0IݞGHa)'''w嗎M @&Ȁ a ;&Ӎ9{ǧx526H%--:7[([JrwN/922GijjںecW/࠴z*pi6<8n"E~:0no~|2<&K;w^)))^H'-BvSql{\dV-β p!]c_q){>/ 䑩K2sd$ `܅5catiIq[sRnn ?u3JKK^{':Ujď8z踀:ur*o98[gIoxWpmF߾}O~2>qÆno7 29~x>&c&g=~t! j'7΅fy~xɾ5쬬.Ⱦ*.y t#ÿ )U *zF*u2졻.wү 0uwbR"/MiӦ'gvHUeeE+Y3G\ᑔco,+O߾z*22r dae,g"Ȁua$[rEɟӯpfG_v ,D vͤ+-F?Oy{<=iJ, %&͆Bw/dee}K:n5"Mw'Npoi`mhXj'!7tƯظzz¬ d/dߒSIN7Hо%w ٷ䔁oiLtz}K$"n[o0Oڷ5 HeIhf1a J'd29;t;>B.3'ndik|Ν˿-JilR8!!!;o^{ub"ppxI(/ַ{BJJ@]f0#hg,Fo~/..GUJszI ?4E|-t%1L?Cot>^P]-_ʗq7Gܳ\acq)9b^__"#݀l8ެT*Ϟ= mim˻~:"k0CT!q35A<,HauP?Mz<{T*޽{WWeddtuu&''@zff&ӧOK_{`gM&8糱_^%`!<~H$qS%#32:n63A30/`Z\Ju:[ WLh}Kь`&h.[W|nG м&Ec#31zF;GD*>NoNxe3O=pօ;RiiIͬMDeٳ>ORfjcNpOq@2,‚y˖-{ufYiӦM}}))N2#,vl뾝sϋ!`$v!Ѹhi~t[L.ONJjoobK^rLĞdgvŏŗFlb:Jeroog 'D<7B%D슁QF͎2}\j*f7JY0+TEd9d[)+3gzCwKHtsݑfhHrkxQeuV,@3f.1X̎"g~ui- & QᏰZ{̾EdJE'6vEi3WjLJ{k>i+a1333]C'&ZmtTԭcCccZz3Vb1wk3 ߎvX,W^^;埜D[nNfe?>!!#KNSzCw-tX!B 﫯o^^<.2ttt A1Gql4ٳile.yyjerFFr8pu^F™sGF] *HL tQQ!! Ŋ+,FzjW۹dz.P'2!Z=tni)j[!!;+sxx==pڮ燆^x~AaaC}=ݦHZ‘3xnpAȽSaS,f!CNvduujyy0ٗ.]UCȩ6-5x׬Yk $Ю!saԅ] `6OlK! Pqi))mR-[9Z>q$t }A榦ή.ш'?:J.-)Zf/N}CģOׯ]tСFA+{{{\ɤb5=~8 NPsA6hց쁁LZhYچq۪Ud̙3WB.BprrrN>P;݅PM4\LttfffkkkcS`HIMQ'\'@ .S556dzGdDj[]NK{tq-94<v͚CYND$thh( 06ĉkt+:&NgPoosVQQqĄز0SʕHU` 0aQĝ/((%}bbcEBaBb"f||sё Zz5@iY#{P(ƴ v_'<6϶[WW"a֖ `x ^^PlYYFWʭ^ Lׯ/Y&%qWw7` 0(~ݺGֶ+&Ǘ.]ܬP("Ç >s8 C@<:5.7o<484֛oyHOOz_yPD::Qe BW&Ó8r`l@RN`HOKC!!G穭>1t?hPYyQgxQ(&NPȹQ<:2B񩢲RhNTWCxAo_dn-E[gG`t: Пš{x#0 ,,D,4X, {ɒ%._B EdT{z{MPa= ,NTd2 L'b%T_N">XBDBw)DTׯ_WГ'OB ڵ.feX `i^ހ۷  #2L4K! X!AD }n/x,l$t0,5+VO֤h```s+ )H\ޥ3DFF)6,1)IDNK)!>tcQpu@Fdc'&+pDZHEÇSXd2_xWLFcAiH,>Jt}#+9>\rnߪXlҥK QՈi4ZTA&:y@h(k;SёЂ`T?4`@%L#0LLddb@6O1YV1(VJnrXB TJNK?w K8hב&dziG*\@mG(ۑ^P#J^^̽!?``RRSi:xmԉȣ;UfK([NAAsFKB敜^YYUV?0PRD!θRSHF{#8,#3e]ݙdl :-"'^ %`F .] ree-0yXp\At2[2# $Ga` r]i%@!frH e`:a(Q`QQCy.́ 6KINFpCIU(BTS:te˖1J&:A|ٲ`8AA--P2(mU*Mb P!ɵHyy-3(..nfҚ,0 N4ZNJK%L#äNG֮YC.:RC%KVUښ5k(*Eu   lG*!+ۑJ%D'H4 B;+BUӭHh;wBBx tu7`{L^͒z|jjkf77ĉt 1Y d= lANNh! cbb`"ElIOeɒ%!:1x Sc`TJ`--eZ < _ " /^O0A*<jT*UFhBBgPqu ADt4'GKtBa"N:Ct6.Ӹ$ G+33e?0O n$B`nb !$QfGu @0:^OW ñ# u$LGȰ׎D .CcAܝj0BޒSBlig7q% ?w<:tG5欠k!{%qqO@4sqn[h8pSna=vxqQUdZa AKҙ0U<+XAhJ+YFe`-ԓnÈόOfYNht xѣGaf9sltV&~ES  ($ yy!3e --ҥKYvt𠏷7'pIbLJ)|}cǎ"LFTH>| BTиiںׯ'N<v0KB{V^=80pY0`?cDBtpSGGǕ+W $ =, PUUnp ?!@Ff3z% W`ߏۡW,#`){y?wwu9>}ztlϏ<0"я jҥǙ%so]Hp={iP5Xѱ zMu]]`xWz!r688`2! C|G!eėB!'z{(Eɨ{tniVJ$dÜG .#"#3Ɇ$(hiѬyd.>!bi5y T*' (.!Yth M/J @ή.AO}Hz D29phll48O3Q>9(JHzN@lEEETL%&WlEGRZG{jEѳ޾vJKp^$cIPPDGɋ-[PC/,]~޽B+1ppWXX؃< %*+$r IlLݻEb|{H@)n>BА70FM !@ H( d##*` h0 )Crj%+bcc/O-D b %*tM JP)L04p e29T)АP3""J@f:jrjdx8$$t`?5%E@y @1hCB[CC0@kWN@vvq C5nhܹs@;M( j~Fh8۠a4+ɻhA9p)P>;dEڡVGRArFH6 E gv`bT4zz{ҩ+Ar3d4+җ5۹;Uk&:Bw! y4]tw-",>|$22tWw͛ϟ?àj­>|HTd$,~ڸq#!o|Q݁e:EB(SCCE@ ;B3`SuuufƅZ!FAsW\I655  3ׯ۬V*ۆN73׮1 b,MF@W9jv; .CLU\1RZ2iZ Ȩ9Ĥ|}0?B!Uk4FىSSABzl9v}KT US`Ci0z `AIT}EqBNjԤZXgΜA}ǫk9rδu+?^G:ysDTGht0vOu$`<`$ DXH;<^G@\I*ɺCe;6CK+Yɓ!k׮ MT`?=éS ]I\DKJUJNNt)g]B*Y*+`2M,]%B'dHǏGmב+(Pӭ'xB(x,Hʕ9B/]:y@ʬ:zlhp`Itٲ ϟt)3##?355#+Ξ={hAZz Ymi9 f=z QIt󋎉 :ŻTieeG٠|ȀҠcR#Q Lw$ftG*HP&U;zUIڑۑ` rsx A$p wAޥ޻6XDGE>sF뛓 =`л+%8P lZzͻテ~fdl,,dq֢#^71 \ffܶmMhxSHHuUCO;s4 Ν;>|'a;wj`#`Rk555B>\۽kt| 5kkj ~'K֭[557e,YrM7]nhjaA',;F'&&W`^B9YY(gn/_ٳM{iNR!O[C{O@{{z}+y۷082 7E +zАj[ѺK/ö"`t" s=CMh~ԱիWQְi@8ڵk/B'xr(p|RcsQB' l\SSӃ>ERbbVf&8PB{G= w֭N@WPc=B7:Ru5pCNG5#xБjkkЋЬ hG0Ўj:T7JC]wX,֨շsd |zꙅ5xdkj[[[} F M,1(0}R2ib?,}oA5h1բ0L&vzbX"h94v+3#ۘf )X2t. D" 4BA<2fC"'›fO٘? 3nf0Н4[|J.X }ixj0^0qz 3k͙*Eq(f $лv22C@0ۧff1"J3 IБ=4 !!Nh ;9 xZi22ZVV#ɓKUP MF[iG"Odzϛ脫4(Fxd)HOftfBPyDn#-\LCE݆ۑ$^uP j!@`M#Ccd6 ~6\x1++6>0@CW nn9]ڴi6ݎ1r84<<11c(MN`p{MM N<ڛ?VC>`$:J:! 8ӑ G@J:#1J47:c_ߍDt2Ցz{6;iGV+Dݼeˢzx484%!:}4Z=w1lÆ %Xl8RۑGR𫫫?%&%<zelZxk׮P)4͈""ۮmݲLٕi ɒhoٲ.6C/IOoni˃_رck׮=5\<  ",d:@:0/^N @pPPGg'D:|l(UeǏɁЀV;1!q1Yq:"N<¯_N:bLq!0+ /\5(8Ҳ JC؈(*&6m(",lϞEa+} yf ѓ>***P GKY0%Ԕ91KH^^E$ƍt,vW ?AQHtxF;.Y&%%6Nu$ H`233_G]^Q^{H Q@O+Fgf!#kTGjmfYN;Z (H;"4^t$ !㌎Dv;K$h;wC4"ғOHv+{HDwEŋC#Dwm̋'- 3O ̚Ktx IB=Hcpq/4 <pxUQi[yMBj{pvpYOrt;SƙgbgڹWX"p|#3w d|gSE QA$d7;9_q6] fewrmڷTv c KEMcS dצ}-!))t1BN5ေוL̼N>PaZ$U*h|/- uzEn9`V8=͸ᎆfNT 塞1y)x=`C"L"q&# _pd9(ܰW;D5g}pOPLN`;&H(7"L {5}+A_|k8?:N[)ݝ/:]ȿmFTO8NvN{ a` _Ѐ$3yUqTת!WvngU}\?xlG!J>"j_Tfy;3ݬ#ǹ"8\so9f gQ5םvbЈمl'I3%`Rnr+.U"2ޠrcan_8?44ěohHLH`lu-ׄB~~h߾}aaavrz \??ᅬ&NKAHha6H)0u &)*I2&P$m_"8((6ODjo.(yCg1Zb\%9wlxxxzz0{:.99KI55in$D @H&\1>u?77wbb"%%U<q{`rJK+kVRy/&6vyXgx̙v]>vD"9wT*G+--:)adaϟ?C(00hsÍB&o%JHLk׮i p,J4HT(>CbJjjcCrJO=zJӀJ%\wtt׫ʐܫɥa\ҙ3gyhוJ%2ʘ@"$PyC8%&!hiҥ@իbMf36}&;Qx8n}G^^999^yyE}}]TTTpp Ϝzdlܰpddfƚª7x[_TFN 'imw},P/iL-AQ _cG,] FUI ObRRkKKaASU8$8u4KKΞ=Đh=|01~oo%N$Ҏv&& G+&e={`ȱV>9F1?γo[N7-C3۠K>D,\ޞ׿5!!qb|DVvL&ȴB-[6G\͟9s Jvta#""VXh(nLJJJhF!t2ٵks7ٮ"{IXg///I^a>•##U W ,((舎qNb,!&?XGF&#I1TU xxI#xS7n|" 0@=1qUVß*//_HO׾T(`y*ʉӧOdήֶw,qD]tz=GZTJ$,uF׷0Yw3>9%xPD~~k/$Ϲ+0\9 DGy{27w ;q:g_K {)!"͘PwmAmY%H m&W;6N2I>fwJ޲fqewهnN\xe_b;N ;l#q][گAB0RįVwGsmOkdiN65->0`+PEEExez<6 WTTpޞp֩IEI׻ZB|bb"7'vM~(S`ǧO Y_~%;⋞:.#K9c fsc Jhbaܫ:m d1 B*j ‹kR07%Ά[GRI\O7u</vEDo>{6?VUUg~0̌@?.KV]вֶt5B ㈄n޼IJ"`I \t9q|xDRrRRoo= jDcxA@$vSOO7<D*MMMCSSSii{vnvg%"}ɺ AQ /Ϳؿ=tG555N'zuֲ&RAsTR>vh,.)lpbEY,bBfJ˟X"7%\I΢4F(鄛&77gZjox j@Tav]mm>d`33s ټy3^3Wwx} LF|?Yx˽*~o4z+"L~US`001nxܬ5fdeb.uc^,]ɑlKP:ϼ߯TM+|n/bFxZ' P[c!pBxUbjר$^6JeV p8vB!W(  * Maq8-&?e23E bRZdϏoT3Z N6Pv,//"'EQWF3==6ح8J#%.S(,yzc;:###p4`XtB2YLjmnNFMbZmXz{--[nZ (U*Qc$'|ly&?7߹s^XXx zLLP N;gqZB'].\E %l"JBDDqp{fW=qvv?+@2D B_um]]˵ktWUU]|YTٽWOBa\<|nnhܲuDL6= WRZ ^ujee².` b!x Y]]gٽ{7JDccEEE}k =t@MMͣG&࿷~-O=ax_r.8==}F^V <<JP'Nwq֭^z'FǨD }IٔKp`# w# 7nz<0`p]pr)H%R2MM_;gAw}Lj&iiihc5Z[54]o7n[ 9Ǐ5mn QDaR1v:I йp~|h ~HᦸDJo'Fh9Q5xlX d/fNl;U>Sg6ޥH(7/r.]\VZz_/c< XΝtR744<84hZ;66$-[!T_qppAa[kf{|+F,ΉL*ɵ:ݺefzhBd3V͢Ma2q55gA2&nf KxPYLkk[;E"v|qQQ~~o;:;ꤲ287ZimkKNNQTێNÉ?ܺu{Q1bqN<)2h"=|h˗I35=-Rj]jahJJJھ};[qrjjfff S-Ho.'D" |>_GGz%#=19R*R=$BVUYI`߿W3%YFHRBV{޲e*KX,f?n~tIjj8pjjj|&`bD>A vbM- z &BJ O.G|Cd۶m,xCxm TV;e3;OL)GKkIaqNǒ!h8wܞ={Eߟ_PMIOOKqFiYBEӧOƣGq~FnN:vcoCX"iii#ህz-ZE3rD@|L*Ih~yʠQQQq޽@ APA<]]wy~{E,geg35n릔3gZpGM#@bsoioo\X#ļipM:;;wܩA] ɉ 쟝xl6޽{a֖ΎNj}] C MQ Ach. g⍄ˤ1~`2;Z㧃-DT}oooIilD Z8O>NRd2x^uRy/^ @7|c2 Hq$÷gFo4YVp333}(׿ 33ƾ>XNUM=_. ";w>FEL¶T:^_h ƥ'&&L9999ƛo1Gz`oiAC P/]Q(In+.)YVʳH%b'W^wC'4OKJɚWҏYD*jk!yc# ̬eZRx (.&ELEKj 6 (돜RwK/Lhkiy$ڍ<64:YM;=Cs9Q@UAJKg/ry'YGڹH*:vK1"DzQ?{lO".&5"?+0 !{ 2:N>Y?C{ G&qիWBP(N?~57;~`wF]YY..III>>>DJ"DU,R  ^Y+SI d1nsN>NNNZӭ裨`qÇ_??g=pJRGIQES>|_P[2VX[[[UU%;v 0SB%mٲE"$&&&$$ܶm6vX'''gee .#C"HtRhhh߾}q/q7Gٍ1\RRE$@5'{F3Uc>'O)k9aUE9iǎ'Sii>%89ʕY{ΜSGtJvPׄnC־/^]y{{TS={Uz e666)T믿º߿?-_+**wvvƑ~+V< i܎ g͚y戈 6@iiiܴiq"+8By( stZBxevR/Q.U˥ ҂ È8οDQ#SINy<{Dz*Nd nVMNN^fȑ#M&^g...>󝜜F5xrTͶ{1\t00''$XC0az?7߄?~Ϟ= K#p V,G#R)GP~܉ŵ(2&o?v'4*lpUWDyNS88&C<Dg}dMa&$$|ՈKӧ.A5kVtt4ةSd20.J{3f 2agddb(-mo޼922̍GSz!ׯ_/tUZ}MXy߂+WTDŅ%?*/DD' WY^}5؈YbDN^|900uq ؕ}D$=q$&& a)H#[~1[ϲBTpp0Z$ABW`:A=iҪ*C"+>yUuuE")6jktc0[!u @MFBi @ncNfHou1 @".p{Co ױiuuuJJT*0`` jl $BCC###O  @z6|d5۷ϝ;w׮]ǏgK*ᑙj׮];|pww 6 2dݸp.\%@uH#G<==aj4B=lݺJ___Ç@N$vI'N tzSS65kV޽Ϟ=~x{{ hb,5J/@ttK&!v޽Eh\iӦ!CtHLLH$3fp`hb;Y" CBBwѢE..\ ,Ι3ǚ @% f @vD$  @$ n @Π^r~KJJ @XjE¤$͂^|K^üX,#& psl22UDV;h#er#a&{<s`?i)AvˋdžAMXlmbhRֶ÷x Ry'@7G@1:.::%%%yyy84rȜOOϔqY'LܫTjm}{{{k!@kjjؕ8bggUTT!'|ee%ad2g~Y.%DP6VTOﭭU(9Rgq \l͋hP0^ _kZ<ڼ/򔖖 aUjwbY䌏y?(_]677BaȎ;99gϞŕ~~~YYY?NO2 ^4i3_H:`RP9}G.;NA/\/B2Bvgdd,^xŊ Nݿ]]]\\ܖ-[,dSFv޽rJfѣqhuA~G8W}7|^믣짗ׇ~< Zv.o Xw曑=/8y$+ >Cs=9p|WF+$Yɲeᢐp<^=O?=i?CL~w._̿3<ܳ~{ȑoqf:uO>Ov/ k׮0e0.>sM:*epհF( \n3(@- 'sӦMhhӐP'Lnp Æ ٳg|.]}GMLL4{a]S`[۷of>rp+X |m),,hH=Q !V7leѢEѥd=s yO 5mN v8x |ueC%3jb<0̯@XhK.EkaquWh)4`AxafCA̦B3a#&5ϭ|ڜX{r9?i~;ؖ{A`b,_HWvusCQ׳(-D/ijj862owx:Z)37;P@ׯ;v,ѫ2k[(!46wfـ;_l ZcD'rLbAEhUCMF]VHo@GWZN;hcCÀ,х~իWC4C[{B?Po  s+`ܸq+W<[nE/m޼Gy9ʌoٲy~GwA'mp$ʳ{n$?>41cƠ`@\r/KKO  ,q>";xÆ Cͳ#Nm>G̯xy&mބu .Xj&1W\zn/01M'|M` ?!΁#Q#hK6Ldl֎3ⶮ(s6f)bbbz! t^z1*%Tfv*R v Av)0PFlM.^؞k(oꬬ,6 y90elllII 4YtZ\zyyA_ƕ{t]d]8B"OHk>A#1צA0Lluul53\X5xGa}k|Hy ! Y#t hgѕ {p7XalP(Xq07OфbzEHL`Hd0"ܶNQl2uޚп-)l))) 3sLؑHiT ]4,,NP8xҤI0=!U233]$  ikKgBO)%''n@ߟ:e۷oG : >|8>܅0a;|'QNЙ]CG`@XTP ֭[7~x'ѣag2Qof.PX+`"*h4}l=砽IĐJ&=_ڒ%  %JZNbS7 4 0ɜ^>ZkUz!陖^Hyb+GX8cH71?R KY A'>}:Kϙ3-W 9̞dp:|l?>)-XzK ׇa5|,waT"j{aPshTWW˟QݿΟrhnFdnց4!:\f2+zA$*h`enVV@Vϟ?o]+H`p R4,,̊`GzPN+:|ǎmܬ*1s!""1Ei+opDVP@4n@Rs#d+U&`-8&&&88؊y SetG*u8ppܘG̹X :=74$6?JDk'~q0w^m z1]d"ePM󕈅: v1LaLէ-2e;0Ύ,uZL /,_|gD&c rpQpYd&("H\ΐDr -~aÿZW[Fe+uuuXȪwJx{{ݺX"g &IݗÖtSkdjFUFUk4F+-FEmiaaauu&Ln&nW%Ť #am|W^y7w)*/w-:]ԋDVrb$(e[b,cRbef^z_~W\a[^|Ű0PC=okΜ9]~D "@GwRhtCj(+3EE' jzBxN^ t`+,{١CھԪ).) |V&!-!7OPA/-2ÈqJé~>([=<:HݙM{=67-O-//SZZ {٢ BVfUJם!gR~ߓ'݀MMDB_F! hV&0ʥh9X9zǏ&L`ܒSRR|}}L"PH$A_[08ҟDv5jCȯ6#JjM!r9Cyt~M]-(, ph A.j5|4I,+(ʜYPBlھW䐜tg EŸ`!b a`c&Ɏ#ȫřo\-| 6-,,ܹs; =zxyy}GFn59rҔ+!q3!=IFB q!{^e1 tٕ,H+pvD"ei66.jU]|||WS.Y&=ӼRrJI'>ʂ ֭[5<<]Q`$ZYvѯfU&.dǘthvs78&w=#LR[\Z]]i[,$6Gz jNXZ]VV-xsT*(lm!gl?ӛXp'~}{_{ŧ~nkkj.^? !7'6%'U(_mz7oڰz:{l߼Ӯs*I %g K "#Rw*`sjRa3lenb{;oOBD{X6=z Tad'|2vaÆAF74X"Vf`뉱x!<dii󬩩a+̃0*mQ.?q)(E4-‘\?!MN$re8yh—P=86\V[ gp"Vg;$&qW1=]];P{Y6 4a h?zn6Ư޺uY н@Dnc>ȯ2a_ͦ nتMUcjERLbCj rl,)0M;xpR0+5W!M6a9;:zz{gd;;:/y/lST:}Ⲳ)S&NQ ILL߿aY3G2q3b,|O)͘1'N)61Od3go4ZWWϳPƼCs8:8>^c)u{xs6ͯlON-p&tS^^3z PVZ sw:q'+GDϨCNrW*ߢk̝^~LBӸZEtɶ6.pC&V'z9-xϖl> ;Wd"nF\kЛz"QU--٦F4#25{zȿϽD"4( ׫UI۶Լi EqvvCR_&Z d\x}ѵ5QQX(@^ "=HÂ"J2,a(K>CK yBbYbiS !w-Xs+TWG$_ i>}+y>&p3Vv+@eYf…[BB^ZSSʕ{ŋ* kO<ɓ'pwCDFt:HQ$&\ Td@ʾ&-sm"b a3*.+ и`*5ImŦq} *3Tn+5Ql* KlSSC F4R,8$c'KcbbbΜٻgרclmצ]v/l Z0~nTj#hl_N=ҍ շg(ΌIeEő8b} Ag@`Wruţj7n9kL&`i~|AK`ݲeˬY L'P:{1,11]Sglh\1ãG޿?  6sȑ1c0 e@ 2^GU IFLx)9MmȬ"kI[qWզ|W@_5A}JLLKMM>}zPPΝ;!M fVI$uCbR2}{UF'6J&DypzW]^Td q.^).lZB|77b/?Jy|EE6b3߭:tL&۾}kXx}pP04(8xQlm};~ov^En\DTTs2>fP:!*L#i t#h MLZZ΁\[0LMquss<&5Q6j6٣iv\%[jN؊2pq\\\mm-aÆσh~@}wF&W[I !n:vxޗn>^OBӧϞ={@@oq߽4WQĭk#1X 6S":<}PdQ$4FXG6?<}[)ߖ<:A,,\ ;8c>K+/*K$ d!"uHdgɹld!77Fւg^rq^5չg<<< k21q;<=<<< ###?5ز.\Ԩ9z[,m%^_PP ct׮]Рmv=vF!!! XK_u($HM] FDŽQ% I1@xw?z)jĉ}ن ;ƴB7/Avpppww۷/`t7Çw3O(i#BU#$E|%+V`bnVU‚9OXjði=h'5:Aub\lK& Wk$:}]s4dކMߟx[YuVUsWD VJƭ❃3sӗNI>Q],sh4%+H$RFLU*9BBΝ;sSRGLQQ=C\ݛl=3l-qni:1iVS3??ĉǏg?0tߏ472hѫ&MQᣉtlBc{:Eu0xQPQ?̙ K͛ހtw\~~~V, @1Ai Q|&FDM{;:=7Ujt&(jQ @U ?\!6"=O@uj+0=ŎRћ ;*^ʯ`sYR~zE)媢R_HԸQZYuzӹ{)v7z%~[ W!]q!nK)2.JUusibtST?O_ ށS{и>DK6ɶ?.r}Qj4 mO@`PMuչsgbc,2 ۆ=8[yDd 9s2#te!5[xe36e㍮f<==A#Ɵve+t*2^nO ^{&2e GeP>B@S! 9KH !+Swj-ҭ׳fhQ.Uea+M#]V>_p (X}߅z˥2Acӳ+,qNF]HL *ά篘kjk-˯ձ%8/G\9U}=kl-!XаVp۶mH >*-LhFk?̌>psjׅ׬=b{vڲiß^|vӦ ;w`W~ɇV`{aldXx`WЭ8m:/vW.{ =coa" 0yF% ͎?՘xeqnZJo-u@ kRiX\X/hpKq%FbF8V]h E35NщR]+2rjl1I4&Q$1qcF LbщdWN 3q7*i_fIFzuqQokBB悁.^8~͛7~|AkS*+Sr*99F%1(B^p26γ`AUo8ӫ֞JRk4..f>y2եgAFOyy9t1cƘ?:ҙbUCAiPpk]j*fSbE>|𡃶66C  ~_yu+GM)e5y]\tӮȽn^.ʼܽ7||tݐJ c7 le8D.?+JGH8Ӌ1 h罁ah؅aõNp$,ĥ% r:?KOPز& nqqdh+ H_G}}}FFL&2d |AV:܊/\y2Sq],Zd7!a྽{N:5aǏš' #O >2rlQȦ+K,a1O¹lUĆTzO_IJnM} &3ɸt5Jh{I;[ڈ.sr+-b!bQhp悯p_'*!gcg1~G%3Y!W޴%W)2۱rٲelkӯ+K+ld6vC=+Ji-2]?HM6x2r15eZZ6>hhITkjjZ[h8k=?/v8윽*D{.\`PP z9 ?"2 沧s {4p~4((oٳᘈؤ;lrG[A>-J͏ޒ%iWM7:.z4*꣏>bYgd/UˣIȳئx۪jRɲ'KF`u!R*Ejr&WڀE z1L&''Ei>ׄP:\m]o-xU ]]%d#Ց"o)=?B* Y@ꜯl!3RoS6ES.M/8[/9hH,?ζ>pZ,I4YbXȵӗDJB]j؂#AT ]]?pm۶]x199ك *,,lu.KD:(J!to+}fs9E͗zt5=@1L#;Z~z:CWr:ϦngM:@:CAC(*)yzLI%CYz~Q2oԉueCxثFb2%f6c=wDxx7+W8I !NG/J|zޝԩSYzvKٓW0&G:O#N}m( ͷ5]cicΝcZpt 9qjվ$%$5_#`7! 9EІ zMH [_z%^m]:Es+jwij6#ojj݇$>> S _Mpr9%ԗ;T6YvL iN.Ƀzt'$9\ iv0eS32%MGZ}Z/z"5ruаIx=GjUVegf+r7;`Fғ}] %N,k vR=U'z7ߚ<(*-^_Ou`֫]\ lڴ&KA|KӕgZa׭h4?SlllFFFxx8l .̜9ՕG#֯_?~޽s̹txe˖Aqvv?\?s*t^7z^Ǧ?ljv˖ǎׯ/_LLς f\N?|Ώg#G@v6Fӡ5 퉾闟ו8GRA4Z2sH@A9ZNh?P}p\~ɓ'C1l^ gK%R 3rUt\K-3q6CGw[}F+OI>v&iN/Nڳj7D*aG[!??( 6(-66FjLL͛sssܹsXSRօե;vSԇfzjrr2ʕ+CfUVXT#ז]m\$d&!ytr:SBjQ I۞̻P{ASZ ^ȂX.,8m4(Nn;prP_[5(]4.\@M"ãGBL2>--mҤIUVegg:4//I䌖HtX(e˔b ][]^XX >Hy t "9III"^矣rIBCC7lqN.//G ݻ7-4du1 |l"..nѢEPaÆ8q=ʤ)/񏥽9+͍e+.^/{Y%fq$R߯IQy?Ioz<@@}c/bEnhܚ%ho^Hu-tVӴ 9=ǏqV y%+&q%:>U 6EKf\o@#?ul e  eBnԭ5y(Z|+eee];$$WK/ Ӧ) YUM]oU'm |Cۼ+.k:nA<U,{~E^JHޘֶ@*vp4xL <) >|84N=t%+-bEХgJ螙7ځ֝裏e$`_r(;wn&Q`‚akZ"+? k\͛wҥh???K.#@;ܹs ^Aˋ-js/PVTwj)/s.3Y[T bY -2%[Oq3[DVVzќXZb_~ԩS]$}3`0R⣥윭[¾9r$7?CZ 0ot~BMP Fs5P5rwL|ӛ 7gG+E%A88Z̄8BYAW!bQE]ҽń$5e3FFU3v=zABAUoǘ'u;̭;k Cf6 V/⬴kZ{E-9]nn#2pAWn@YP*_\`!nI1 m½MưPtss4iREEEZZڮ]@~~~ccF/dvܮ36mڥK׭[h*<Ӵ:kShԎio0u"5zNNw T1m=#c{۞o .FNop7Z`s\ۆDy@yx\KqJ@c...7_5Cp0FA> 슳"'"r .rO_WP_񕕕qvgFKrʠzSAf46+L7x~er%ގmե EUQqwmB#H<٤63 ](#,pե`>lpgϮ]Mh`QL*{v˟[f*ve&yNp?vkkƷH:=1F)g/ѓh7hl?+(K~/?Wzyn&## o׿~ YgLOOgy.#]: c3:ʥut =gE T>yc"-٦t0Pӕ{xxX%c`Fo߾0cn݊\. YYmo"ʺ!3ff!JgLyZ ^ljP:]Ymze-swa`owL]ۿUZ]a_ԨmԩSPdY?'`I&/C e+W|ꩧrpP 2ԝ(v8 tsQ$!/0h+ nEB pKovDzW}]^r̒@:p␐d:mlzE(m6y ׄ_/m,88ȑ#m6~̿ޞ_EZfm ""  e}fAèQ4Dʑ}@Sc/K^&8 ^0o lll`>hFF{g>o<ޗōٔr\8:8gf=HBLj`-")--;w.*<55:0 _SY CLHH WFScPH>al _{tak cV9zl*Rc/YsoG %nc\<=ǐ!C`۷СC&Lpqq)V;fO.GjmFj<{+r|eXK,A2E%Dt7)Ȯku(];#RӴ l]PRQ׶6 S&bVKk\?0yAȑ#̊4hȃ4f?of|ɷ.=BwOUL tA_ d^#{[ا9vȶFz; ȀG [ MTjުyW@H_VjS_߿off&D޴iӚ"%ҍdc!л-"$TЙUy D1zolA@ tJadinFPcǎ'OR0񮵖)?~"%%%??vXA}L'|[ݡyX s8gWgvMb{B_ܿ?j~˗//..^`ARRիPM !i'ZID}!n.د.MMNI[KZXM s/ة&}j’%={_a%&&8b!Jʦha7zH~\K86U׫Y4J2wo $hu/ɓ'k4ƍsqq":> ɩk>]bŊI&naS:UL~IkҫL꺚ǶM=^GYv-$SYYOôݻ!C̝Z5e4INH* ^DH_ށ<|(kզjV T*!ѻSn4^`nJ)LC:n/H}ϟ?LVZZ{nXPьRs i\VF +.%ǣ+`/wwwH[sÑ F ⧟~Nʦ$.]%'';wBa]&#uFuVN7tP+*"`JVͷRjMt)jLd9+?n*55uȑh~JOn~iӦ9sTJ !\_!KX4ֺiQUyCeffFFFG_Oش[gx<,OLDN16+((EӧOyy9vL~d#nAܩt@mVBbF9&o^ׯ2e \hw}\|rѣ Gg_n݌3 d2<쮗Ohmm0hI7[I]GaFfE;(ſ3W^rV8%`)eϨ`8Ke/! E#E)qJ]&Q7ILJ" Rv0Ml-ÔEE.i.:m^yEr#$& kjMH?s'HTg ґL)̝23gs-2!!|_|G4ilӽ{JJJ~{Ej <?Q s?|0"h bIDkgAoy ܩ@[<+?feutv-?|h=!~ KCP| m t׍-ΫҟJ}n$d,!6. C'IĒaqmhCvu/[/ I::A>>˖-@:UKdԤ7X[Ss$H_ /! jL6&}B:DBm K=062Nng#C:܊K) X` 0؈ҥK ,&[r9s֯_)l-[tMgff&8 D5~xV]]]_[[ƌsXuuuO<񄗗WDDAя?b8w\LL]iƎ -7_<㏧۷i -G0dȐ+WpX曩`0+NG BY$#ϊe6FI χ]txx8h}UKAAA(sUSQfX={,(oYx1.@`x6+_-v('~xQy) MWZ>QQQ wIOOApÇ!}g<ʞv+>>aÆɂ__߀$x[ i} @TGv54( kqK̮q̛%q|̛&L&$M 㾃 MwUR^/N޺ֽ|T:y鿣-7MepSfHuڀbۄ _m~]]T l -+0c)jY:cJ _@8JG*+`;QO).?L&Юi1WrR0/χΜ4'''hc&Lp7^|EKJJN矿EDN;ް\Iqꅴ?t'te&hytM(aQ9dXe8 QXl0*) J nx2g!6=`SSLU裏AEEEC@4,L&۲e ~qMXm!zVOgРAw.\J䋋-ڵkް7o 4h؃_}|koذ_v &m҄nfenNek3Q6Eys*II'B}Bu[bT*esEEEk֬_\dȜ]̣k N6_#t!ginp凮.4,[`S!C4Cn>vXh1='O?>1IIIlPvn݊2lCh0iP)-O`~ Kk՜lg|+pMl}ʕ[nA5C,l`xc(]=|UScFcaTaHҴ=:6ӛ& HX-Į9iEͭԲ2|ժUhl7o_h]xÆ KOOOMM bAFƚ.!9FW:zYx!C@lعs'44ƾ}0 @@: >gĘnJVWW7ٸq#LLүlpև=7!!t/&;X/]~2Y:X8ZۻUƇơkײwܹs) ,tRttt``qL&3<ڣ2BPG i4+4:tlœ&<<<***@b NSSxPuF'mZ0pyΝ;3OϽpzOG3'P)< 9)) Y܆~ `BbVLBIeѾ"­"p^! l\o;ٟۈSL^JETa$̃]6NPS 7Bj%]=n| HsVVѣ \=n/_h=W*bP*aaa...'*++PWBg@8މ6hI\anqplmmׯ_g&Kj*Û| p'7qY7o޼qСCǍC^xW,B"Z`BMM5Dh| R(Ӆf(W#l,kSRR`N2Au dKNTN١ͣtx`@7[{S|?/sR7*jBĦ&t #:t#R+(WM>N͙3gtZIƮp! ,!7A)C=#gyuK7H,5Ȧ;wǎ+,,dK&MPxhu֥K!M2lyyySN4h\.1xɀ`Sl``<6oDDij>]2LGc0eeeuuu <zO?EEE`PX eEwV:KtD=DH0!%@H!ql)dJW0ZZZ_;"֚Wj&&!7WlZTTiӦkb/XpCV>SB\.`wȸt钧iX(46/x!dEX$Dݻe24..&!OH!K C7d3@A 6RP%OJ ׄ.Cln>0y,(<ԁ[XbfoDg.++InvYKCÄMe۷?^hrfNUMNNNO= g*iR.xhׄCla60bqKNm-vNus '4uNN0rئF!{{uֹ3w`*zIIIP!=ݠ0̀GǎKLTjT{_kllnp64snVi Z<s2@M c^([-s-+pʠpӟ<!*TY >rd[=Z%zݻ+++rAٲe4h zS^z)$$$223ﭫꫯs'O6ny) <˅p=,ӥh4,#eY'qpJ1`_4>U5^ý6EC?c#0(4t6'_mĺX,2dC~1^JR*>}б R4\r:;aHe҃wWW)KBGωz١#ƛ]7טP@u3B!`b0\BB7233s4`cڴiP=[# ,UOZ7%ӑ^-XrF:+ˁB!fVUl(ׁ@Qc1 yQQQcƌy!###,XЋumELL L#VT#h<~RԚQ|pA2 ;nP+Wd2YYY"flلNB֪׊0sNp#~,**z뭷> O!G9s&~bxAAA~mpp0~VVV( }vhhIKN*ʶXOѵT*.s]3@AKt"&t'e7ͱ~b壧~?CO{K[ZZmnܸZ' [Xv9k +jmmѣGa@OIIϧO g+5{>gjy$Ѷ!P''k_BNzSOn"3!^H [n* jnJ&{yYfrqqAo  Y|Np0 )99f? ԍ$s_W,ݜܭ8E(c}}QիWq4N)ɓ'wf̯h!{ '$zx-Qz i97e59Vzbμ)k׮1cP`|~C6!O#!YЕu0z\.3Eo0. r|1YD$&*)q{Xsy4_~=m۶{# ?~<..V&ㄤMh ,:sMM d7JnذL# r6ekb G,yd0YP$vGCNe!^#G=^_P'H%zSfgPKԍ;y06PPXXilCl{CF=UoMT2"547Ν;F/LHH՝zj95 " oӰ0KDf&ʇ~ȶ)j+X8€=1'>[Om\Uh?>ouCSU)?QDʘ1h,$m>Eyn*hQrWXlGU*gϞogaP4aLuuu??P6dM }T*ik+Zlc(` gVL^b Sx!/}tA]E+i "A%mxK)jo@5BVFE9onnp؋z,{{ Cʳ4X'N)MqI;m]wa܉C(%l!òWr{W?DS ߲Oo XMkQ=ܰ`ݙ5;q㿘ҵs9URv ,CBx{?6ZvH\sݮ @! [z4453cիW{9=4\،cAAs"""D`ʢ"6ޫs出C|"h2^4ܕ:+wwU?+x˕R纏N4S{-_<77'55uÆ x}SSaF&&&2R3bK["D3FΞ.9FH:ul>B{TZD"),,|+'O:uv sPN<ͺ^VטlR)HsM}^Q}qqqlllff& ?䓻wfL&[z58u֭k׮/YRhUQ'^B7Z1u m.^jx{{WWWXZZ/Xr)j /^Ӡ |C @&SX6=y߳ wȩ,99cV# E;<dbS~I^WƂӧO'Ռ!C߿Mjۦ8y?T5t$X؋`c<³_~޽bX82 %Plmm V)0}~&M2S{Y@Ozɒ%xxȻ9`۷oΜ9`sEGGv|jt6 +LJ )5LCF!!U;%  mUIUդ^F \t/Xzz:D)SnJ"#GO!`NVpss={6+ƭODM|}ǎs΅sG.W\a۪=~f˿3pEI oNLLUO1Av<5%45LԲ ,Ǐ:ugPn耉 T ͯ7l^tN9,,""tx/$ z]\VJhXp+ FVi-K] &GR2@X<}ife^nUNA ZQ&ɇLUUU)ӧOwttd644ف\bF ^Ɨ_~3Ϥڵkɒ%,KzjFL4d2h{[9RRRۛ e{p/ ܼAC, ^ 滙r@6} .( !_;vXl~j>U:}$> ;wڍz1L;)OrQTT>l^BY$׵(աM[pWg .:t}6 FZb߿=\&У+[&UvD65?ZLMDYCn(,kKiӦ,X!:_8LW /[ Ww%`ͳE>z, $߸~_6}&2< œ, eme(l^FVZZ/~fXAO!W7(kGD y҈C5%fy!ׯ_ ~ᇘ&Θ1c80s̾y-rb1T~ցt.gڴi}Y\\l\xro^ӧOc{<R{[jU1{{{S&ISpiބE4t6.h,b؝hy 䈈ǏO>j_?N{)z~/@bSR7 \f6?!r݁P[:\V&<-k''Ovpp}Pu]u&+EiN^hh P|x)((hɒ%wN{PbYV݂7^W(U2Aqzwig#ۙ|uexz^{+WLLL[lKLlϕF)ug`3gT^`cOM/ᧀa>M ޹sƍ vvvB4TgzzT*E$jcc*#L.Py(ni$ 痑qΝG}7o'.nH//o&6p>SXXX<991YF%G&?)p?___aAl&}%? ӟ 3Ν^njed{ 9O\Blid潄;ԑ^;w|衇<GAAd&tJ^H M JcW 2U2Y\W{6 شٳرc}Uq0'fUMpC2m7p겳g͚j3#onnn͍&А۱ySPUjU‹:t/2f Z=kk{=䦆?htRC'WMZ=UDT#}:持 .lٲbŊɓ'1bŋwz?O>/{yyUUUA׈iʠC,r*ᶸ Tl磓&''&l*Wț뛛3T";Uk#QӤje  Gkk뚚X}TmM A`3z"xLdf50d N==a!ᚐSLay~}w7ϳ ǨT {??xږcǎ%=jժv/BTi⴯7@Qs.6$QM<ЍV4Ѵf$EhKXh6ϟJ a>2'6!: LsDH4ue_pʕ!Æ 0f͚e5U{3_:|`͊i1|~H/oNz*dȐ۷5ZEi.~em$VEwu%`i/L*!/r2 ˩N+(LƿC\.gJ~TP@2WglěwSQ[[{ԩ9sJSVFp6,::5IԚZHw_W+ih@Mss|[.1.,jN9Bމtz:99 ws2e#}+FK,!O8[iG~9Afgg]#ٶmEEEŚ5k8eOOOv#_b%ɇ~os8#m ZzO?ͫw^ԓW{̙6l`իWO0 N)))ygPux(P5#TX/B~~>-[[]~}rr2cPw}w„ |>ڷoK:h^ NJws|2Japrttm ,˗/geº&8n@plBy` 2m|!|0_8@:@E___B:GbcEOv?˷x6mnnf*T*d ye065#f$t|.Htɏn0 E&` !CaL1G yȵNRun H7 Ε2e ?5ĩڵK "i&Y[[yP_D`N 8M l2-P\XXȫ_6g+# ~\ 0AϪ boƛW_EUq_z%unsJ܅ϋB<eee87 |vبg^=j.20vC['ⴚW$m;T/m/JtY.C޳`ݸqcܸqhP:hHx!VW޽zõk&N7-ѣx?<.>|\WkllDL܋\:KI""!QM2nL!jҼ<<>"6~a|;5SPu9},!TĆ?. e}Ј4q4C7<΅B2)nS2c]sͰT_VQ7^lYX]VVֳ'2sqrutczo޻`n<S8DS>>>-S3ŋǎ2իp}=tdԁ`2 oƽ֭dLBԆYJ^J;v trѣ;w:tW !Ө?aBذ!9c::$0XJ#%h/1 7 iѰ_κ4Z:mhh+l@f7oP&z w>B66<ΩS`GR\a@E˗/ >///6bdQ'M}v¡HR>(j~->8l(tnKݗ'+MuZADL"oF{:q:HcYVHH]4Y40GI;BMC<={6;/sO@[#s؀F_Ik.SN9dYUU^7jN EDDtH3L3B*wӝaz "111 ¦M0"e ѪFOLӚZҰˋ?!˨~ '9rСCS؂9f̘(t<6mM~~>̙3>~8pYߐ_pSu[YY_ZGu3~7 ) W^kYL4{ψ ߃;QB+]bEFFFRRlMmZbpXjB[ ɞ!ť%l\K A4HBi\${h3Xlq!ڦhaWCD Ay0"l&RzqvjHpNU+@xx7|\BBEOEf/[ %4W>_6<7Sq܇-`ӋTVϜ5,fV $oÆʪ*=I*JK7~L(E&H5J%:KM]ٷ[-1&,JG` U!_yPCPzJaeBt &9?ˑ#G͚넭Gω贚J`if*Z+Iw~ L{wd,qrPkEEEhk֬aJco!Al){{{3s?=1(ƣ|zAF0@fmhj6\W( UUN- ϻ{YMMu@`Э,}YYi\܌ MJ&mTGWy- ]x>8(5-5yQP6~@Y=Uz95fCF~}|Vc`  u^wiiiNsʕu Ƿ@cN %ggg8:F5)ޅ =2<==G2rz9k̷nZx1\I={;vY^!kkk 9uJjkVe!"Fi= ޡ.)G)RV ꦦFBZ]U[^V^P\2AT)(Ke-D[}23RI.h![I '߾Mtuk[o]Jbl+--|8!/O/1jGY:A*ӷVYŋ@JJJtt47-:1f)Yۼys@@p޺ˏ`B\;꽇n]5 ={-=WLQϷCI_zuBŹOTE/J꒣Фannfem-icϦEMMfjT*ggc"oY5`D>477cΩS==/7-Teؒ2M,qckРA5JvC;fFϗ Zi; MsUC1yeoo,-kaalcc7]"XZ;8J6Lhnj..vvMcFKe2u2snf, }֑#l,+.`rrrÙwZuVPP?ƎO?u#k_*d0ͧk]ʼ 3%%Qw"&tQx"Է]---h1)))MMMǏgp_aq=wuuu2ݸQAA;FN񉍍ÃR v:G5\;Coܸ˖1:G3fщf< \|ãOCaT:[ZMzu]]ݖSD Bj,Shv㷾A֬OCc슧޵Bb,li&77I&xmۆ(4)z•gR 0۷GqU+<ݴipT< s6K-5&Z%r7xױ,3i@>/\ܩϝ;O ĉN~O> 3܆σza d| \.7o\pv?aL=A@PPt@1Ooo :} ߱cĉC  iABjK,l6 ar_컂B~k_:HA2},>yxHȐ#GƯ>IXL zjupJݩaxܹ"t֭e8'8 =r:ƍ,N\iV օ4 RuM"*q4!I{M02Dʕ+aXIRp*>9ׁ "##?D*++߄ߞɭR b}XC22=w-FiV4b;;ŗd߹SkH+B^Jˣx&dL'xaݺuxi}3 ;"7-ްQԸT*j ^!i !jaB Plԩ7FƃܬF[Z&ܙ S'3v֝4W|PP ,l,///رc/_0y Lrrr)RT;lLF|hǰMœB 5D;m<)))li?A D}6oqAJټرǭF|ꙓ'Oh>th0):/>s7*|@XO<ŋXېoVg/JψbUm 5<'Tl( gL#4^#!___[O} WNLC% ە j?Ϋ Bx"Z0t((Mhh L )@VƯA%@zG/l$?^:IQu5V/kFj* *ndJP:E e%,o,rpvrմ=@][v 5ݻocxX&GGn{]ΝJ R2 o09s& &@f눠u5Y~~APpX{.뽀[7={tsppʕ+!`K jjj`5hZQQQIQ֭[3}vFW_M: dò@ڵkΜ9菰\Y={PK.Ά8C{ƘFKaZ}R -5HL$4ׯ JOO=;Z/B:w=C<%b'*XL4)oڧU@.\׈'b$:* @}G%lt`@MoDŽ^ŗ|d0؆Ԟ0pA~~~|q4х`邃y[ω\_EbX#;8?tEҩv='~ C k߶ٚti 6Ӗ,Y̚5 =P. fُ7nFtDboLf >9cz pZr^d&q0wrIh0"bö, SCkg>lc͚50Ly#? JιyO'%EU.ή o/o_Nwԩ㾾jTL ĔElm^7?sh:&fT.mgkwBu.]X"؞-}ƿ%Y!DaǤ+r]… 0XG\SSSCCC 5n6wtX`!}=6TWҜ\,-U)IMMAPVTa}㴸~sc[m*-*/ܖJU! {xΎ'RA]+++z F~9D2Bs"#y\{<=m]ye9le+.[;˝yL^HXo)Sڲ|gΜ3g=3 bbbڧFj v yP`;9!!%EyVh%EK +kBT*nJjF׮\4א65VFIRC&//ԴQNJD:b645^Y1 u8NOȨf9 $sQ| {}’\ţje]fS ¤χUdvT"h+,'kl@,WZEtf'&z种uYQrAfHi7FTj4KK+f,xphZ o2fR.gw*i(V(VM-frɪ;r!Dlɤ͍bK h,ILݴiTʾ ҂*L q]]tgN5XTuɓ'3}%^`g B7...0XvWOVPB,TbO[teʣвpӞǬ$kt"&t_!˗/ر(M6rH={Z^^`618 Od>lId^Y7B͵weN]x/@(M—fwCm9[ZǍXT_^Z$W(2I.Ww#fO,3s>RT \TTN5#FKmlnl)m%T'ҩt+ULY4B`$ɿC0*Iw733Qa^Hߨ-ɢ>C̝m^sY0mDFse[fB*߿ʕ;w_bEKKKbb"iӦ iT 2IDDɢdzTOH$!u&$:%vtMB)e^&Ўހ_[St#9E쬎LdQmgo8fQ}}g;>D"qvJ|6\ (//LָFdCF(6s "{mX;V̨2;tҀ{9yl}=x5bbb?rm%,VVVL"*vjl2/;!oVʔl2<.99?Qhoo1˜ /\¢7DEE;˗/gp\N47gN̜ hT 2{U="}K,)((_:> ӄe]\?MMM8ٶqӱfnb7(SUUO{uy|usu kHmZZZCBª-,`i65Ä,~N4 ftͯ:<<<88Ã!V4 |cǢ<_zbyѣq벲2_8D!Ac Bma4 ip:,)zC/^7Ϝ9&M S"CgLJJ&Z9h-Z{wj={zzztttlڏb#}gXkzȘQSkjAAG?´zwF(s.u2eʹsnݺ5o<(+Bgy6Kʞgeff!46ra_$%f>$Ub ȑ#Y/}"Za2qΒRKM #aFQ~">[o hdd$| :l0'd€K rN~ڭ[=jH:g]Ih7,,,\~ɓ'r+?),,LXmCͭT\YMۛOC'sQhgn'N,**ڲe .**JO`6 رcaJS̗5>lL G۵};w;)))fdd<ݰaof'F \4"eY?"!Cg~F@( ]\MI$svvbkB?Fmii8T*NHs,q"N*$wrbڵ |M3f+_۞0Pז::9i6M qE:lSH6E&N&f͚UWWr-%''}}ѼJJJCw<\pwaӧOÇGB5 tձcǢgeeY[niDP:wT =u-;vfDw}dz)|t^/KTTW>Ç󣯾y~m6\QҥK׮]={~)S'?733?ɳB '<->kOQyLLe~+WŸ7|2^zŊډ, Ü9s^uwu+Xûeկ~㔅  V㣑$<0'!˺BY[٬NFDdME8')z@RRR\\Q{l \&aB鶒fPNKn a6tPTh6,|)IDD _G?<2{F8uasWHV-CWN\h.A;իJdċ2}#P  ):$DJ.*k"##!A֬Yq4G@}bbb n FO8R^^?Qϟ~i٨?ɓ':aܸqń 5|b|8pԯ?Oee o@,K6O<(hy13yQ|Pv.RY 5 J}Od1jS|?Y\&q U{,YG~dy!j?w0p;;LeokoQk#M'6DLZƧi^h󟱱}:uqݐbՖ}K<5UW_f+ 퇍WZϹ~s$uU\;$ɚ9sΩS’w^OOO(`SN4A=!Yݻwh kFd25gjUYíJ:m7SGhU),zlS.e20"~ڋØdAH|"rS8UYm"Uj3۔=-pxy ~;+?5/(7ɩi'0}}}&+aޭv*5l'!KbE;G9N]:pU(*ywqٳП`{=:55C*.TiO|N,ʦghC4Qפt)Euu5OԄQ?ʸVaBwɦEEE9`1l j16܂=###''zz^^[mmo5С34AVTŋq!=рw 2ӬZYsc/~/fggDnݚ5kf@_YΤ6+B 9RCn3zg:CPlruv%77Ediii\zΝ)#iBf\%cƌÃW$:::??Ϻ6m ?yTꛪg`ll0''+t7QEx3T*HnE a$3*̰=VϥB0N7](#t؝FP1^֎zk+iU_BϠ#W*WU}E,k6hѻwomhK;Pj|ϟ(^-{G:"34}F%** mJ+XQO?oARE쬬Ξvuu>boNs=g-7Nv7$nɝ'`xmLǎ4ydT,Ao"*ZNslf%'cP 14Y[Y548Ugjbw:Jckc Z#X^qX\֨H f[… Μ9tNÂ.GRJOԩGGO-H$eee,7@~~P(lggt%n- H$b+**p%ʐl~z+==aRbW]IQHCiԲ`8}o?̛>#m?9sAlB69wԩZZ4%j2t.[[C3WEJPBx2H"XTԴDy X+źoTL%''$tK'y8pB%)=}no Al`[bb"v7n555yxxVw_|_xٹýe(sGr%%?1ZcG]wcЈVÄT?dZPɓ'!$f2̌r WI逧]Q|U qR+ܯ{Y:=fS,v;v,w&j]9Kƀܣ{s+i:`6ssi Mu hKKKh~ raPOBQQD9,HIIIΝ nJkk맟~jBS[@P閭;p>.$8T&JS3egxGT x teeepIq0| 2QfA߿m?zC77m)"1Ȁ"kK%_>w'{iZʅ'>(4.D*o$7RITh MulXb3줺ݻNNNWG$A`\411?~<> _ Eӻ.]J#e)rɥ8(75ʞV` mT$SFcR…z4j7aT4 ev? z{,bVK{Ŏo^RhR~HΓ-%]>ȱ13Yjks-m{4޺XPmm'"##ٞcM7n6f̘?8::^, oU,k2\6T/qtT]~GN~Yބ 2-3kǯML%m E'wb`͏^ɩQII*((2dNGWS7e-?%RqqzdmR;V̜4i?OrjjjQQѸq "sWR.})x+tow\E]ٸq#₳s?$`MM1J oЃ0`ʕ+u:O?A ;㸸k.R*9gx[֔`[ =#([XS s_'.!tQF˜HHH`h oso!___]Z|0JlF8\4ٳgp}<==n:m4|o?+516iH1,%%O( `h;M<#PVM[[[Wښ5k6mok9t[Rnb}CäW^uqq^xرc* +++Q8@ `]0#z\|n&Rbrpe|K&M4d;w$rՖ&+#wwm[͔)S`Q_v (ܹ0b.\ЫW/-K~∿iذf~8 ^O}qm+eѣi$Fњq~ƶP0ـ HESEb|d!KA,\@&ǻw1+܇΅oζk׮YXX;wіjPVb+0## ?hlldM3StsKa:u*ENNNQhp)|#X%&#x` m·dv#0 =q0FmK0ccc((z7NR w3TMaa!{۶mVVV*vHLo=,vCWec=:Y;E4}tsΜ9p〔BJ.8x *x:qĴiPApO.=](J5@Э*;7b"lYmxX[GS,X?*42>;|+c@Jh.™fUPfqޱef~Q݀0BU+((@tېʚ JD-\҅ÇOp!H[lA?e{ 6S=čoUnC/LyNC2n`ajxts3PpjkkO>}!CݻEfC|nLJV5n^ދrәAAAJNFRb|eW\cknpp'N̪Ump ~lRzb8&mk"rll8 o'Oo۷ogi.%^_WDʮxΜ9̗E233 ؉vvwĚ3X̵ײe˺ChƧMB=\׶ 滖n$nPy 8M5+oث0vN.Ο?( ʦvt2yܹdY;,(h ?|Y)QSF;w+? gɒ%---pgQ_JiY,VSG9w)oh][||2H˚i9 dHozH`#m=e:/))kmmd jkk h)++S\!TC777kl-Q3w#Gfdd"%99]#Ǐ{.8⥅\9MMM.\={6 xqa5GTUUر%lP(h*i\ϸz77jH_/cHZnd&Y>Q>=n#6D?K 7n3|}V~n=~Ld2TEIL,ouTK+(khTWCCCqqEXÇ/Yd۶mcƌٴiL߬@+yS q1HAG`6QeA#,~l;Ax`oca!hl!O& 6lի qH<۷ollEAQîw܁GXTT4sLnBV/aw={Jfʕb[\X!ak̟% nL- HmKP&&&+-@ o2uyAI'Zݡj@~կ~ 4Ծ}$ jF(,k~_|E)x\GoJ<<U u68SOc *.+DM"T"j ϟ6mիWM)`XYYP>:-׎4J4@CH3bjlcS}KXX:f 0_XmG/^G:>1{ƍΔ  |`SB@ ui@pU JуD">Y |ɓ'!l:ZTTAXM}MnVV0t*YDNO54;s VV|F˗/owވxp8c h+pu%4?l7" {ȑ^{ Vy#ڂ-99OoF`&'$$@| &s,=N9/s߽ܽ.5[@"pruv@Bx8Qׯ_|e: 7E$=ElbTB$lJ)n%7& _ 5MF'T0Qs@ס$8۠[VR(m8ri_ՠ)@jjЕ[$MQ*"zRIڇ9@^z'6 uxEo + |ʔ)x  Z^> jʕp~b66]y[x+l7qh fy0377W0yimm iPiŊPymݺun#4~x87 A}aa!d}l[N!?H~&-OY[Z/jsg%vN nKz{E| RBG}y Oi"!/u\ *>E+ P)ppRɴ_ll,4ȑ#ak2{YhHÇCBYAN`Ϣ4СC7CMz$%3"o&qt5QZ ѣGQk6660Oaۼy3'?i˖-1110d/m_g> <Шx_(O6y3mV x i0dȐ'W^%y򢢢9s樭xذ>s|#5>*5' w*eO6\sj8ӦMSЗOp;i7˟2ApI"xʸYzCڋ϶%xXkߖضH?E J"5(=Q6&Ap9pcƌ!T]\\^4ħA\p (=#4K{hv#$ 8H/]h>-[ n>n ̓_tiUU/'gφs6M9$zHtKMkգ0e~!Q\ (X no4 \#xM6Ԫ,NӐDX*|Zvf+'ЕnW 4\ybRreTK0bVTT@G C(>윘  FB"ݮٵsDbbK8jE-qvv~7__׃7vvAUޒ%Kv}ӦM賽z;vlYYt)'0 X' uLYR-ǃГ/rہѣGg*r K j!:M}:NQIZªg:A0P N7gSTrm\1ظcO @xbtt4솼s }6]oc X;j6 } `"q/e߾}Q\YF{U^;@S%2fR`)}P\^]ҷ%U2SI״IqfFWGU`W0 v'uuu`T7bgFʪJ*On&61oVXt$(i`ybڿ3g)e8_es@-+gŬ'k=Њ+55jH0K1וT=/IۭbQYv9ྵ *.޸pƒ EEE˗/ٰaK/GA24m J H{v?)n)& !ބpZAӰ΋vAYt0YX^['\.B+/nΜ9֭m,to:t( N!zAi#l1%KX'?رcK$7ԄG{(8x~!7sLwy]D7?{3(W׿0P|l؏zÕ2` z c? eN<$9kEE-f5 {?0@ρYc:[NM nֆ.%H6t  Ӑ6i фL1',䶊׻X ^{,VY06!9l*}KWō-- 91h# Ew+#G(yn`2?!)Ki:8$t'J@qCqtS @ la؟pb^vkj.g$ I&q猆Rb6v?[dtUX`YE*ו+Wrr#~!{3{z`d\ԏO.]eV[o֧OJ82;wnUU E~jT.ShY x񂱉 `jb%[;{;{5%Зo\g~Z,?w^"57Kw9;oРAPׯ8Œ >Q$K_~%lOt'*odF^{ 0n" oZ7)ykujL; }8 m3 -7sLŋW޻a'h-ܿ~\>xfϞ.%74cΏ+Eb3Y q p" fѻ(A ,A@ Û\p!|G-31ƳP"6KѻUƊ$py74GE`~2M RҘTü`Kl ˛∈ȻwGfPWn膦#B6\nΫEO0o>V 3v|ۧPˢVYggfi|vQj.t |ԩ_g'||`nk_J:| 8|J,ݵ_*xY4t#+͍2,QNx ψjtyxfg+=vU67p@C&L8sLuu5dwi'`@VӣkE5ws4KăBt}\B$n ȉT gX u# Ǖ+(_T jД.lnMu%=ʠ}O}ah}[XK1o.objbk弱%]'Ň]no秤۷/<<6/,2b'yAAAz N',_E655=xv-I/3G,}̓&ۖ,t)1Qg.XK%CޤvHKbcggcII :,QB2{ĖOsss.W>>>)iZNjIed#TI䲲Rk +;۞e+y+y|'D9 {n'Nq38bOU20զ_7y?+;;P*  X>M!D-?BfНх͋ I%DuZtzV^__M'b@?L21>',,ҥKsiTRŋ,¾ ASKKᑏ)o~-vӣhYYYmܹs=p &/_f9 MGPWWԧOqơ+o>tOWR.}wWpߪ8> qIBaY9.V:(.v7C[z#dڴi\ѣG~ '_eQ!lRd*l$ yyyH$pBlllhh& 9Ta,m߾pзo+WdffO(D'b3 6ٯxč~^ڙ5wD6v?1=11d4fp@Q PT!SXRU$[X]Ri! lj=r {nSzz:c~駖 ++{.^xʕ7n/WZk.1L_@Sex i[AqVyjf#=d?҄qnnn8q"ʇ7SVV g͚]|̙~{+U~mSS}zоm6jVj43XrX9֯.)^lllLj-wDĒț w4YfΜz_|s)SbBaXO&ft[-\[?qDaĈ2.LÉ}NddJ'Rn511N | oϞ=0Yd2FmĞےӶiµ"i\""+u:'{-|x1srr 0 x|6*_ *+'|?c(ʑk׮}W_{5klڴ6 |ޒrT;|Xp 6J1o޼;vYn!7.?/8`Η.GѬ ܰp9*{Uwmϝ;Eǟ#L툰S}#`b /// QT9!+FQV3t(]O$J'66`2G1S˷ wkb><4YR"kPع.*)CCC8ȅojhFܹs'qin2=yѢEpXpmѷo߾.] Is Ȁ_ildM34E{ pU( WXK=N m"w`d NRQ ck 2ܸqc۶mh@/SWYZZ? P6;$E'+挊k6"[ K̹5zY\<$$D-!8T-3=QdWQi&0<$$(Ȗ;Ю#deeݼySmG7ZBJK+%ڴ{r܋xia* )a5s̱xzz۸s"ΧLR-.. TPek׮8gUϘ1{V5>x8֖ c;\m8Bs t `MVU 9%@)Qf&733+ >nġ&SZg׮]cǎuttd?uE+Wv_~mU2?doB{٣D󔤱xhd2Y=%4a#eI&3}™auN` ZL]k245VUhK|]qwp_ԪM6{ܕ&3 7X t$4j"WO`v%q/;qĕ+Wر["Ѷ=\=?ɿ u{ez/P48p .W 'Oo۷ogj󬡈uUQHAo'5+2j(wM qɒ%---fBj)|W?H˺e):]7zRND$[||@ M$8z\ ֵ^@Ie/у"O^ݵC>p֭+WWRy&ɾ}P_*)jkkRSSX?{#_av0Y~v+Wݐ?͛)`NNݻ~m.q{5o]J"rđ"DVb݀3fLJJ 5 6nܸl2Bw8p%;qDrr2NL H\nWEF2d駟p *$11VvTTT~~>[(|Y&jSEeUuU<EQS=[ 233_y啓'Ob YCݹJ:] c޽{Tw-bccqJW=|phh(V6)I'3wڛUV <3` A;,-酦9ly@WC$NdC9!>Ҳ6X)Aq >s 4iT* { D @Ge]ׯ[@JD~x*x(ޭeo .uz. vڥKM믿{x)%؃)&9Cf: oAo]J*AmWyf29z(]y1 %`'[{ fӑ#Gld7:} 1BΝ;7vXHgk+7n܀,Ax^JnB#<<;OKK8}tnPK% 0hMqάM-A\Q&UAN\WeeeЭ*y;E&DUx97p6ZB-]"*θdɒ͛7_pMk? y4AZeַEFTs4SM AWn]n4IsFEzRI& ?tQ6s+סNL%n*Yii)z!###t zʕ+ N_p+rU͋|[aCS8P=ﯯEh@\GoLJJd}||芰a0***pb ֭[-t %v*FуD[>\7BjJq3jFQSPAAAtEFF޽2Uٳg1"pVǛ7omg x#(W>/a^x^LLLTx@}E~D7;kc~f[|Jvѯ5RKmPvHj'򒞥aii+++tCnh/PjժPu JQQў={ ]YYYݐIts~Klע~V+څI&/[_>*8j.dO엉M.A= ir$jSC L78(e B 尗mlln߾ gG߾}a3qCo3) K:axxmkCSgQQQB,p3]sށd7;Sޘ uV2⃩ [[lALHH2Voys/vt|STܖz\6 b2W $, Nfll,$ -x<T`ŋ51OX= $p׮]:͢(N𖊋 i 'p1!¯1&\b`H:33pT,1.5^qX`n}3MLLԴ3P>[׀F~:mΝ:)2~3g[(s\p`72O(OXlAq˻½/O]UŽ -&EN H$ /5Q(=5-]"' =(;&:,ZjGBwwwa9rJMY/4k$:Oijx QFkpaBAE97W&āt:C'Bh?Wܱoq0l\e^&1 ͖;6t+hWCl5#{5;/poveM`mPzHg>EsZ鹃NſSTRoia)Y n3 ffss3Pf7gSTf٥ف+yQ dz}wMˆw  K/ a9pa/|v4{B\kC+(ؚ\XX`xѯXh-f1^rj Vx}xPWua6 ƲN0jh_ 6l*$Ym{>'񞸸8t.h*=3Eto(zJ U+a;rFSSS/ޞ(: %gy~I4MHH ҂—Ș2eو9 Da3!Gj3)%mcp;4C_ʮhBa۷ϝ;vjlCwşׯ_6k &3zF`;k܈i9O i@#U$ĵ'Q?\*Wf*6)2 N:8ċPUXWW=a wʪJ*On&61B oxW a81oO"ٳ,LH///_}Յ OGFFn޼v%@~G6accזٖJ̋)`/j*C\v%ȕFN`Xg{RmϞ=AAA@SM>)KVoMM~~yyܒaee=s1"Տ肦f5R)SYFh*j5 C4ls /(h3k,h+77{9s^YYX]]? q?qD\mnoa+ث[CoO ߜ5sOSllWZ’DZS빨۶m{/_?C 0677 o>c+7[8~k_ TSX_/iݤE֩3I8 ppφ蘚GkE!HIIH$p #""^}w'_זFC a@ ~?njV4g1RV~; |LҙHrŘ2H撹/)~,CM6}\~-""vv}s%J#Љ*d6VI[m19#IQ;$#2V REӼ\qE,G.o&:E˦VzTcƌ8w\BZݻwlY?q}j_ty%['psro߾N" <ү_?,еjpQxAA06ョ B؆ X `f?A)07ptў4Y쳤SmdXE@CO4Ca:5TO4H}ꐩ^gJ79;A`Ԫrbܹ=mIL6LHiVKbFj\y"$ȼx}y2>rӪʍ뿹yW_߻oOUe蘘|[7W~u[oj4HiLKc`_6m"iƿб>>>{(//g}a`>rH(BnL*¥۾}``f;wV\ٶ<2%:ZqE8 >| _hO12|Ghha^t0B[/pihh8x $Ι' ԭWidʗ(>" ,S'zc'hb %]hnd;eČо PU}_~,;ż`|$%6u̐} [pԒRQ-q3b5H8>xTLDz)aVW2s;_q/VVs3ӍľZѸ0ݬŋoݺYDܐdBR4gk+쐇̟?ߙ?q>bC;) !^lP̕*Hx19: 4A IeR3Gb ښF-l7@Rjqh. (!y \4EO͈RfmmFTަ@F&텤#.~-nU('j~^L1B&es8:q~|f"z.A}SwGaۅo2+&.7H,%~DD:Go)Oojs,nz?ھ Iu!_6Yr\BfG`$I"Dg;x5daEEũS,---5+mX8/7=pa4h}NMn}`v`ߠzO>m7߿?##}*<<\mF:~^15ai,VBNDgRBtY􆪪Jȭ=%9<~ԩIˑ#MKp"(lpx` eE9rF}l|Ņ{37]8ahw}bw*Ҝq':D[k$8 ,,<$=¡+ٶB3f^yN Q ^PF_pi_B|aM/K7ƎgΜIll˾Kx,bpO.6[MrX)L#FA<6o޼t҂k\\~JLLԄ Bb:Ky h<8rsKa dqUavW [LGX[7AG 3SS9s;yجYs<<<:;(3,=p: A^iEXZ#ߟkN|6sє(H$gP*/(P X1*))135str,--366rv~K*D НdfQm/HiUkKKb0>ފ ,Qp!6D5l__o `AugNtHZGySRngQls Љ^f8B piӳֳ ԓ f (i0S:mhhrJRRҐ!Ch 55%?]}lØqvC_]ZrYiÇ---,X}i5&5+iF3[F#}iSKb4n"Oi_4>|esMppu(Uw_ظGJWSx+tKeرFǧwƍښss3ݻwZ[%`(8$ ׮Ie**\F$pPM]GDo6 ٵC\C: " ǴM&NU\4y[GN-urr9rdrrWBBBxx8~GK׭(~Fϗ> -L}gq}=MEB"\H@^wBᕞS~)lll,,,B齔gg:*$[i{TB'H/ w驧;PD H(5HB6&7sI6}70v޼y~77}cfSI.9X:N܋TAfSֿK7CB:wƏj!{U*{{mp[n:իWrvvvww3qqq%˓`PO6-99v4HahR(~Wm^B7k} N2wF1ܥB%*UnMQWf5wYTTcjw'dGOgifJ1!ce2īoJJʬYyO^=5B(X`$ԙ=('L5iT<K_giK̙Ǹ hmwVO`oyO)̼y6l@w+VH$˗o۶ JɓyfT v @h6Lj^>jb3R4S9وmĒ:ލ;vN8ѥ-2X8Mn?CXoO| 1X$3˲)X ]G]]WOЫTV)w=Cst$$k.v4&&\K7V*mlll;bCyf'icel|"U9I|{{5l7MKF@!?x80I a&P{]ވkqh?z ݊;T(feez|L&qGGI:dfnf5u¬N߂hڎMKz?H߶L*a%Cyyypw)20kkkv@c(egn֕1..ܣ)AǍ^p!27dI졾h)ANvN]6"(D(Ҙv}qq[ˁCw"--MGz["{ \]]{ wR)%n;JOBҨ:"0d;] uW073vvth66ٕ:F Zc'܋'E*V],9WEEEnZHoc2le6qc'8"$Xjd5x4NjGGG0Fɷ^QYY3C^;zgy{/..͛O>; WZyf3g4fD7`ڵAAAgΜ=z+^~ov-t̼KR\\\nݺ^xƍ(m:@̜&l WEduJ&CKxZ ܲagÇo۶M-PWQN0D)Lzf怐* |pݺG"6 }7 L ϳ%a/{W;裏1ZA A녅͟?A)lau3>f|`S|TΝ; _E! g}B {y4Hܷo?cn_cXv53[bfMDRojA :ɓ+**BCC3HjBj*YK, ׿Dzf͚ӧ6ݸq.Ɵ/B3g 3j(<|P]C :th޽111H{p-2GDDۛ[n*gBSN>Ws7~M6,{l\@x311k.evntNӝfj36>ڎ>rLG&`!on_w~:4/>Wo¡ /~!>_|nݺ-)H^CB,B& LѶȫS&EC=z*<[II ܉`\<4\DžG1 d3`;AG6!!u}C14C1كO83 D~I&`𰼅DM(CH{Xh}۶mUUU666\O<9l0TJF;+< p$;u㹃}]@A=AF#`7p{Lj۷A ;k7PաC@'={,]F,h`+++v9{lO~~~P@t׈a*{3q˭}ؼ}qE/Uh U62 ߖjZim8SLP( v<֧~2$ +TȻs} !CA't!d@`ڵkz3Lcǎ'`kׂj_5R KJ&to>\s߇tEA6urr} }eZ0ѣ!~Ax/ڏ<7| c⽼kt̓xEZ$pwЇ`X!$p<`M=3P;Npxڌ;Iɓu{CCJO|KOn_3ΰ#GT#csK۹b ѫ wO/>gLadXto0Cdaٕ|fTu~ÀC.ø~&zڠӧOBL0:''z?M6 <W^y+{'\|$JO"cZfdd?D8rQƢ ̓ a5 `uPAިN(X+/++4nkH[la/\p! ;B( }Ga5CӦ 7nXx1ZuV4`н`ʇb"wGR)f稔B_0Je-Zӧ^ f͚!yfJS^ @`B8L<uiT|뭷`nC /RKltdUP5`R-3DK,هwA(p0b1r4g̙l-w=!!%&&T$A@S4 U!I46hp<ÇRM9ܕLUV͛@ٹs#G mǍnxAH7@^ٴiӈ#A|?<]Jclcaa&kҬl ׏ h-tsFiПCZ X6~cˍ3WE/4]8M9vеT568uZW_W-GdXcZuP9jZ\4$I1AfŚJazM0:M9v* ___~gfnH8ݒ'}:Q9lK%Fi;q_"Yb+{lJ^5AOؔC'v崴4#T*$رk2WU]WD3+ʺJ>G⿫%oʕ+wܙ KƍhرcmmmSRR222WE|Z2CV,#!7^f B2&II]OS/:|qЃؔC'!쌹ܨjpb wo-d߶,S֪*))VRQ+Ə ZU~~~999Ho˗XB ! &;=6 "$|@B k8sygg炂OOϊ 痖PbqPPPO7M9t?oԩ5F n(xȬ.C ;P;rI+^:00pԨQƍ# FII.HL;5++˫cX`gB 鯷r'Xq J?899ذ^3vꝯWHM{&ҒÕKr+HIj!a)%tna DH!V[h@Z)CѨ jmlSzA=F8ܒȋWA}'O ٳ`7ne;&j ~NT ș^fUFH$! ?P$ёuwv&JKKsrr||:~@KPHZRӐ1aA,EM%D5X ϽI5dM&4zCȐ(ű)e0DčiYϷ߭()*.;ztڴvUN9Q^!Cr(T}Bۈҗ?Y9-R]|P( 8idQ1~ /I`x@W5W1cd! lI?ٳ7oAGDOzm¤IWΜ9t)7'.%Zqq#_h0~ӠA7 \&{ʍK0z?O TI[ =!Vy!+іq0)`iP(^7oF ZWzz:Gř9o>)R!dgg_z5///<<VN <6EONAN8|1n8oo[/XV`Yf:u L"=mmm)~i.aʞ[2$aTLtUq=3lz1t.㸠e\tq ge,-lZXRp1BjHCܜM]nkYfʁ#7oz饌?{8x suqc' Jn_2/'fp.UFÆҺKr{8y 4033ձii4ڿ-%'7CI͸qm?Bd*k Yo&7|$ "zuf]Nڝl}iH]8;Lu3 GK*3np3;tF,ϝ;Rčêb׶TΛ7*\"|pϞ=NNN"m+ \(I)r x ?v6e61zRAw0~yjkU1ȷ)$f< \aNF53\ǨFnqOc!;>hQēS?5mE٘AEGn<ɩqooya1CwrضE.#'O;z;8@ÓWeێKcԟ?5eD.eoCPc۟Օz +3/(.+c Yc?OvY_˫둏4Z͚LWYT!BLȩEk/0^rTy\TI]t \q;|ؚye(&LoZYY;{xxP,GFF=zs߾=,}3;{潉s5P'oJј&dƐJG'd033ќB-^ew 5|?rJQQJ)uS|{duLyi9-[-[zaL@+)jTTԺuR?O4aܪ2@̗4I!$SfKНn߾mXm1<[?__U^Eo|ZkĶ~MBsfH??Mԛ,l;f ,f-D撝F'X:t 7ҕi٩--L@@Zܙ(sdBUf^0TĖu5NWAk6WQ;a6ݲG RRZQBklͻ~ZǵR\MF%SVJ*/ViKnJ2bުD(,K]_UӭAT+ \riieLiliʒ*]i.Q:(.HTMuNέ?x{ysDdǢc]:+qm_p.? $$C8q̜gFS'1(WG ymyJ+͟yAABJ;^Y_)Vdj eR Q\dɒ4-yH$>>>N|X_['Nطo_uu? ޱ}'ؠ@.`HfD..`wB (aTM:ti())).*3Q R*T kWJ;xv;(3in1I#~%tM}nd3G+!NguAڧhʳxrƩq~R- "CooqC!tgy jMt~զҴ^!q\ cgЕvSh'peJ \޺ Ζl 8$tժ;VVѪXϣ%TJ\̳mxrݲx:qHx 2f'+[wj¦&`ɴ]]K[ƻq†عoICi.)-ѕ6ipF\7z|uO :7&.v;7Fɱhk^8tyA2N{ƼXqPH##,LxBp@^~FkgNLKx4ߝцsY+b5$ /C_cސA<ݝZ]s岲R?Eddmm L'؉L

Lhk~577#C!8mz^}} 'l- a(5աc XD?I=aFyQMp\sV*}駹b766ߏ)--;wɓ'> #էO̗_~9ҿ $ ]h޿xD޷֭ --??MN(vץ~~~Cs([8 'W;ϚbMqEe]$HV6DeTr!ADEq *Ax D=PF* =M-B QRm+ɓ’166MM&x$a{ј ϵ7ШWD߾} ˷`=z˖-GԌ 2%%%8E/7!1U,[ppv. y!\) #i~&\#!!gݺu၁)))GbPdApF㬷$LDѦP*oG H8XPPЧOwB]OYyMX4D[BH(װC1]om;ṎFnnn]],qrrJLLٶmĉpч7n܈ ߶ X5!c44`9Ȁm#((h4fddTTTL&ɅNjƯ/[ ʐc_MtߎAŔ)SJJJp7xJ>|8܂ \dl-#S^xAR5X@,s!LbK}ΠS(AH$ؗJr;ذgvٞU+wғCzoUcbs W ?B/vSAxttM$ <=}X$)$ŗ8ZmŶAWy.Ύz _{=gR46ԡi<Wx<̠7H D >'@@4}B3ϩꂂz$@Lwq/pΕG >֢1`p 6_@D88"/;(5:B5[r/V,|Y*nN 8q_'y䑯ꩧN]dI@@N-LZ~hȾrjSXD644[H0jH-k ~xKw3`@źu222555#GN̛7GJ2))iаqƇz4(V}d*srT-zu^U)SrcOe2sss >wdjiii}h4Tr4oř?D9s߿ԩShȤ6* 吤 uXvT'f\6%22VÃZ ]ZZZQQQPP}v1bD^^ޕ+Wx…`JZ km6ص28jz[!=;DW,e4)Y&ɨ%MF#O60<􌊊:|]]]S}>3grss`CCC]\\к2~7|-wߕH$ ,IApwh`z3 RkY@@@l+ڢY,.+p9~>u988YitT|~rrիwdYYY8+?ɓ;xF&K,][3GBPC?neYil+=fdJEEE'NprrH${I/g͚ - `5Dj".Y;;;ۖ(!&Q.Qke,` ,KNzIۂ!+ n ƺu.dPDރ5~i Bj)׫W* v8k-[xyyP1c\\.OIIDHv޽{|6z3\A- 6?_25lGf[ tF2̌iϟ- vRѣ(0"/^hpQl"2[&"9#fE8'8lf7管.8|vlo<ڳ8+DW`qҥzH* s>gφ4h%==\c\SS1nʔ)G*11C x{ZNGDDK|/ZZK0`@hKNXX֧܈Ҩ}jKlig4Tm'A*q=o)K˖t-0j7nܸLc@]cZMs% :`2jm v/),f ]w*#CD"Ox~[ QB{ lqHa~M\.E-NZ:]$H-\.@ok֬qrr5kV=z-p^'U0WəF;p[N D=-MžB/W@ GG'Ct tR[   ~sss[lH$h4O?~O|4/4&"N>(6G* 5l6[("X(ff&  ---555\^?33w $o~уu0!؄Dq Z7 <O"sn'N|ucc,(":ITcu kҊ+a8 t082;/}gӌ-+,7'f/hWԮuP(RSSrMDhnnmDN Z}pƒ(//wuŘD! #\L.پ{yy Դ pwwwttls``& :T^o:-MյD hFEZk`vR(W^CO%RX$qȓ PnP2@L@|?rvRD'KyĀ] ϵԣ0`̓9 0`p79 0`pwfs[  8gx`2&LгgOX6tM6yzz,^xׯ|8,x|||+**@?seeN9s믿AgϞ0{#sǏ 믿|/Zhڵ`/gСC0`YG.,,~tt?J G;wѷQS2Dp f̘K@P(J?}Ӛ~a>}'^x7ިB??G&$$ZsAFNzJهnC{ryU8;;Do9<=<nذil60V9N`²&ˎ;Ca2"""@rhW0hoWyYۍԩSt$@#|뭷w !%>;ٳ.])...((5bKE37bJEuu5|SSBAo7Z$>@X[i"^{W^/٨4*4"6k3 o=*6dhggGc8::R ~z9-O?nmҙ E  @{ @jj*;8]l/^|ꩧpqPP*QQQZpƗLS[VV'NDfB",O(-޲eKmm- QZci`)>|ln'v݂#bAi0 B(jmRBp AI Iff&8_S.\+@Gڠ"B&˭j zCu() n3aԈ{CznoRhK )s?=v\;7< UT~pW@SRu/٣SϞ=<&ł ˂n €Z5Pdd#24=88}p/ hz-E`+WSԋ<ѪF#B7dSB¬}-hu!d el Pl(/B: OĈ}AU8S؂ѯQ@<6lӧ-Zy?hx`f=MjZ5 zOFSE .:ojjNt )--[ޠx{FT* =QZw~zZndJhs. )H, ,Ŭ `Y ay.G=dP0'a`AH)|,t֍ڱ9-\bL6 o=. n`< .PݩTJ 5H%,o[S]]*h=&4 dɐ\ǃf3o&$'O۷n)S>^z {\͛}3f5^) DlWF¨5j2?{ v0 t<@NVsXNlB}٩ϰya+sˬ,xt`9s愄PѣGZǎD^a4YLr& Ù4%j1`zЎ<^ѐ$i2?>OD8gqZ~׷%99CtX77ZJHAjT$,3Eb~+))y7RY9}^?pO>ĦR+H)))8]F8;zIv bmOB- ?atf '_ݺ6d_|1c+e-Y?W_7YgrupsyÊEJ* 0`p`\CU~o˞{ }$ٹ|<}m- 0M03p:텬sj&:$ىk`َq]nd.ήN295nN>;Mw aQQ: bkXE(++jKj($&\Ftw*XBS]KJNS$̟/h_l4nۥJt84?:@ofh)sb|h2pO}#sBҲsǟ~J׏;`I"k>~3$^mƩs$Ν2ׯ7[QO? srTґ#qqܖ=RTjK8i{iAHGs?U𨧢Bm- ˂@ʗ_׮nggrlW\,ϼ?g*;ޕ+ @$a`ռ"7ٝrmEy . c^WV6KZ2 ?XvpiqOTmP:*!]奄ɀFtF[pH$QQQZ6<<ҥK&Mz^uGG5k7""b!V۲%"jիWM$%I#qYYɞ=e/1R\t駟~BN2كRő$UVVs'|o ݻ7DFF"9{#P*MF}EQvvg}&e2C=iӦ"// &@3gTСC=:qA9s;L&?_u"x$A@r5I[ZN-P(wĉ>$;{lϟ?}v{OV_XXs$Yz~-;*β Nwes9-Z?Pݎ;P.0ѣv HOKKXXs:eTِH (444W>}ヒ";vlʕ.\@uXP˭555JKKPS҈;wp 6f䐘[_O]._={6SȒ%K{=VnnnV4uIrq'ԘXl\ j¨#H-al! bV\0hRKXņyIڶm~&%%]xviOK5l60˿ @Jm2dHr<@c, TT0111 {{{A3mCp=S׳-`9$ߺu+b8˩S'B'O[ƏAW(TDZ9O:E-Dg4333Q4^ZgFy;×V$__f <3Og{Oe{Oσ(h 6jn`muֽ/"B'''DB:@{br6Pn`YS"ɕJCM  gը%H>3؁=;whܿOOl ICfd tt<.rrnر3f ,붤,\pƍyyyP*b1DE0W4ĉǞxN7jfe1ܜQ5wquu4hP޽_z%ԝuA< 6oՇtNY5,a2-]\.GK}`܀gvẒv,6!s!Q!4-lk)N888еsmQYSy:-Y&#Ӽ}tFXzn&4˗qs89xAAJ幊iجLJJjsiӬ, lMXVx,juJ~zGe/RX&ced({uJ ?-TѨ1XSX@,6{_TU}Kx8*BN)*RN? Abrօ@~ܑ7`'"rs]Xՙ=d]py.T {H^o` 0)\z+ ZU֜ y'\ >cIX~ePT$LH=+ Nj#~%.uLv}^{Zzi>f';0c=D gfSv|{ O^Qt3r߯[~nܫ3ʣݹO}N*n;QV;)u2Ԟ9Coϰђ# O6|峪WGfhk vvvQcƐ^^EE-FcKht?sGG>ȍXhw/N>]\z.Zt91zN RvAl {>Cbɨ1/m~z>ŸH--1rֆ]kNZr%D=cxV&>XS1j-jwM_-lPx{{k-X,DBr(u:@"`ksBp^V 8䒷7,Q`'i$A BH,;5 vhMUŬju:1BpHkwt!4_"vR??<,#e3SqaBB̌tDoq|d8X,jH򺩍n4"_ǡYf#FO?>ǏO4iH쑺pbww :u G/__ID)f\9ہq 8..li/n׻3=={Fڴ~87:]vkxxx>};p;y?2(j~{ٛt?;>6AvgL{iE2K\,JSÃHW@Xl1ŋ ѫy5ͤI:u:%Ϝ9 ѱYw5?tcǎ3_>|ydQy~Š̘1ӚlK`JOs#G_գǵƭS^u8>>LGD +?`|Xy=0Y<]M>daSGt nǍj08b1ѽOu5dբwK.mذo<@.Ginn_gϞХD5 ^eY"V[١}ڽe/{ϟopbv:ILp҄$P0GLsQ^&0٠ ̸k9?iq{ IuSM3g̵h n=OrDb k*s=ąr!آh+G˶E'80Vb!4C;hA͙;nF#ɖD@7C<Ƕ2`xMр[ũ Qab* ֵ =7sW˅vvBGz/.Ȇ 5uJHR }jW*Dn6Ha%n RA]]Z:8-?^-w!Q&UZ{G2̎,/fZ:] 1`cs{***WCg̈4C[8222@oGW;::`"XbS>}K ]CK$l-.Nm0;rE(AxtɁ FARP`{N*^P[t}<}<yD:U)R ]Hb9ŽhvqA7X4H4 &OZ"+RUhRdκ>1)>$;d=qQRK%D,%&&Jey*>ɉbuz6ۼ6J"H8u:i26>]s 0`@U_C(5 a"L:d,aU].,erU{v7~۶->Fb`j5|  E ښW0dPh B.wۯ?/z^REFE_L0q{{;i555'N;o>h2bɨj|yq.6Gs 0`@kJ,}5,H uQEpۮIu 9}߾mi3\]]zXd^^;RiHHhn^P ,|}Y 8888h"UUVGXdHh2ZG8'޵lypu~ۣŋT*Յ NJvvvvE~~~UU<osxv_۲,3=Y)ϥd2WBgΜ:t۾}P1SL208XUeф Ϳ~BȧСCpUGս{N>9}kWB-MѣVq;|p߾}|kkkΞ="'y4?,!VTTuVGGI&>}Q$JetttSeee;*i@Qk׮E_0&Hr9RB?~ˈVWYYbv---)))2@P9\t ڻ~N ]/!!Aӡ7oٳ'ZΠA 0mMMMDSNh3 輮Zx񢽽=qJ [Wu~&XdA ߬ h` &3MZٯO>()sgS=OwܬY[PlhHH?"-[`maV\ :yEDDX>$// ӆN {U0a111|Azz:GA:O: ^`G}jժ/KJJxn׮]}9իa׬Y;99ʕ+H W yaaaի O?]x14 =qB0/_ Q]]3 $@EPv0>>vزeG@0߱c~/2RAiw~7lԻwoDw2d&ljjBRк AV_}A4 edd 7T<^{ :< 7Ȁ^-Zy;&4v}Ŗ,  `oqivlNp0a2nٳܹ\(,.*jlpؤ۶쬀1p>{&4<^RZB 8MU$7粳¥>Zl6% ` е<<<@HD|}}Ѡoߎd 3 X@BG} f֭[76`a7lۍla'N9X؂aÆAԔ̓1T*+(lܸ*B%Pκu`)`D&O fd>(:gqlK">7nBH {QAG٢T*ՃOR)Btr]\* 4  Eu"vþCEhFtK\Fq07|2/} .T_ -- eB@iE)8]#X( BO+48Uxppz=b+VI{}p"Dp1aЧs=d*P>C-pA.,N!ɓhP)|_Q5p_6Ѫ35YhV_^h,AHCb]kwCe_b~?񜯏C/BNsvy`&X3.^̋RqыY,X$H0sͧd8qF&XA4'MVԄId8q\.G!CK>#d4 bh4ᔟXxu+h n`a:0JЗ`@a&p&4\HOS7o>`2ca]`|I+c" |CB8>feBр0`_ZiVABGq JA-:8@qм:DB{yyd@Q-Pna)Q f?_fgg?è͛7#7*d@> c -Qc 8;jLC-+hz)h|ZF@lhbޯ_?HFzb@T]~@#C Ȟ={bbbкKP6'<8Q ((c¦$G vZ 4~~yф"aPgE@@]#&"7V ">v(xZ]f  PK]]Z&պPAoȟZ2q!j355gnې+3y B\rSC#Ǝ7憗ϵ3ި֎ Ö}D<W,fE"1 x<>3F.hEeHYTayd|wyF p<\`wC@wzS'=Sʦ:%.A2Pz5*;7Y4)SAGy%FjO Rm&8[Z?t$&&"P ƨ7d" FJ@X$Cy@8Tp! jGY̙<c@%}tgƁEZgՉI3% q۾@ ;2XKK[946/sH }a4hjjjfϞM>&S;T|c;~x`mdS°@3mHNbjSӧOv!Cw 7|U˖-ÖzebM@iW:ˎ1ftܹx6bSիs{AA6^vzjԎիk+-ɚ*N$ ƤIw0at6= |hi0U]Pg[wL+}QjjiԖR ?kz'|2Uv50 KӯXT"c'2{ٕw\w(,h|q Ҙ:?u] `C܉_N5kh jZ P[Kq C⬐;nýgG/]ν^@x{FҒ3~ g,@x31<==s]{Bŧc- 3ho0<ǀ f0<ǀ f0<ǀ f0<ǀ fty+*;]Md}o}z=; MޑhV)&8zPncV}D~L`tŠkܹ3fa,Ѵ3Xuxs҅Q-sIh.^L%X4t?}Yurf?,d5lÉv4u8;Qզw4\\)Z `Ø1Mi8GRw?1y76z}zzNo$)[dzw TVW,]Էh}EO7#\6m_F1##CrkXh4@yYK>\8K+p N0reg<&}iiEЖn:0 \yeټWl{ /XB#a|W~MXL7F!7R⹺ڇ_QZ*$fK2 ɠxeʏu􍍍$C˰ziLB<; +b"\*jN J0VY'e|MZD/]Jf7%7w1h๜ xU%%%'88%77&iÎuLP.o5IA/R2_8./%%y<ޠouTp%<\tO̳VV***B!(5e}}=avG$ -v AismEKtMWM&]ޣ%2<=<]\]nEW$Guuu.]",SZ'j hM ءQ ;bLyJ^YK}4ʠR'ImuU\XX[Wpq$dt"hjj >'=og:u u9]XnfҮiOוO=`l7UYiYUue嗛mt9׮]J$.::LRN<}^xg 5)YxVK^ѓ&%Mz¤% JV ,g&e7_}>clNf|0OYSSi<k-7m4e6l֭[AAخf_;v,5'PkOt3J͵JGt]5|enAN#,kVձqÈQ 湎d2GXR^Vj0}La̫2Qn)HIIIOOG0ߕvvvW\!,WA:>Yfm޼yɒ%]GHuA2u'I-afp0e_hsuJ9s:+3#$4z'9:jZ//fEas=Zw̟7SN ?c߾}pօۘS?`񝄝QD*3ꪅȈ YanWUfFS'#"/?gYF";U*ANPb=[=xnG oo߾j:99бiZCQUTpY*EzҠ&LjZo:۲ZpSO/Wfvlzʈc?哖~u=ze-4h4899A?qqq7n ĩvZNqe&ؔ4&`L*7ke[l5]Ç.~%$ٽb=Cv^{'&]8wvy$oeeeAڵ ˗/B].^kAXm\)',]F0F]-q<٪]XBjm[>bdzCm8LvvUèc|Zeu;2'&&/(>\ /G/>3p8֯_N n] ,AsGuܺ]'O2d߆jiqLS]5@z'Ϊ=  l0In;F%:t0 tdvB0&,Zt\ ,K=2/'ClT. P\3)2B=ǃT?#M6bh L`Zoi9OMAl`8AH&3ݓfKe.]f tv¦ T3pv3snoڢ.YՒ,rw ؀ ' I>C `ƀqe*zYIO?3wwV[;_rΙ3wf~3m[6QS[gf_٫V~sǖWd<իTw@[|ȭJbn'Uȼr9^C(1y%3=\Ӵg~epЪZXI/_ّL~^ o`;PŨX`p?yJshh;Z[[{9@;֯_o~4KcGxכxh*UBHe Gaky|ϲ ^w_Ⳗ=d_cS&1_C?-%K{>w޺Eg-wWw96:P17hRy5 =/}0z\}ԼtيŮ];]pa1ă?:\=TشuvvR 6yXҊyU܋nѢE7x??c%:6c k_xq~R,Weo ׃x7g+?~{+`zm;wl_y*zrN NƜA+_=܃%D+kŗ[nExlqWf/~W!Ye{8R+>{ʫq Ҫk^y;w̟@H~^5X7lYڸ絜\Q_9C zu ?>VȑyOzW8.\UλĖ]ulr/?|;c'1ƈhcꪕuC&Ѧ}S^酋 է>%—z{ pt=TbF7N\|%xpdĻ{ +nz6TVs̫H4ru16ZNjlܳm͚5*9;1oЌ%/K_*{7$?aGD^"ҪEƢy U"C.۶S]Us뭷_Uf8\nK}w||_ub>}?wر1b&δaWoK=] R^ߜh'[1t+çWgV;>nUhY]({_?-ҏI,W=XO}쌳*9pnB律(`Cъ| XǮ_: fYVv+>[{{JSm}'_z^PNvɇ׭PF4 #5 N8Lw=ӻ XsKG-W:gi2j)"|h'C7w_3O}d d]οGٛRfM30NױK:I!_^P#%0p)@`=Kcf#A`CtMGya535ɨ3h /PMG F1ϟ&>S̖p82e}^- OJ(jiXt2y t-cE>v :i1L}kq1{ ߥ= p7@?aC "+p!@ҹcƙ.서t7 9yT f 7Op:g5P ݔP(EP(,,eE5O4n'83Jr)s BqPmjf71IRJ B1Q:6|uU,P ]moޖ%-\ax.۲c+.ҹ⵭|$gV:_>D~myѵj&l߻hg+y(xӒo=Pd8il w9S֚wCmPҹGh.m\Z)܆έnO|X8cyc֏}5v/iY4p^~??,PO]Ε/^tM6-Si(fJF&6ewʷ&TN3MxGk*=H:·>Ǯ3 n.M} wm_.-fƗlۓ?>^'w4g彟3%ܗG1)ΥR===sν˞x[nmWR[[lb9sM)[кS=$2M0sp8tқoe?|uaݵk|>nݺٳgoݺjd7wUUӞtRf<ޫtnٽ{QSo~wR ` <}w]핽/@> @<1,W6{=} mbSRr=`[j*lك_1vM7acǎ+W?x㍨m؂~hpעE")Rp|QElI/Kw'> 6^fˮ੗ap{پ+^a<6ƼR!,W@xEѩP(JsX[~(r`M[r#<]wU43]x<^Թ .xH|́5w5Z^aY(PC,nwueWZUtXQ tPЍ{F=O?p.G? ]vcAK@S}.X$Ԕyȅ\NTBomW_}5Pw^twCamjԄuM(t&!%]wͿK, heP*j=MW]A$)AAA /^*)"(xsN<駤ģ7?Wol hK4U_iލ 猱d8+t]Gn^hnA]'ڟ~_K54.TQk]1~iIdeYnA\x}ڵS?WZ-kĪ6>9ݼdNqƠ RY^7[Z_asvw8]rӵ0E:W`ڷ~]m]+ϻ79#D-" h~_"=]֎5KG>>{9o>u[ZZ".t~A1Nzժp(;!55}<'I6[{:(<% !kW:V`{†IB$)i`(RJY*_zz{{͛Гۡ?曍\7}<{Pg4XsojOWXƵh={+]wQcx)ܵk=g[w`(ɤvn3˄TX,^W߈Iݷwwsl:f55x)JH7bJ?0J7tNP(WRSS҂MyP*FD!ax5遁gmg]q H$D y΁{):|`"5űiZ[l^|"| ȡpl6֮QR[װo>Tľ$>m *:P2MӬohj=sdҞ71kD9B3.4Md2(iE+*\Qgq[x6A/Ϸ:XPXeZ@_owmmm,P_ρR8y4|B(gIE ?˦#h,ٹc;^ ̙ѣ<7r&,q~:Ey[rƍ*+1dG-vJ ***..<4:J:IsxuM-խ۷̞H$fi^VVA5Z]_C9rBAӅKgۅH$LiF"aXh8B::<< BTz aEgi]Y/ yȏGz2X<8ճ6̸=.M(Jxb+~P(z:@xHlj4j&@ZCCcyYjoOOuMtqVMmҩ޾BO-ˊwwu@ :nm]}<5Lp(Ɖ.j@mm]__2 #N"#]leaD8sgiA|4Lϳ.]j:N9:o+>=ͨ;k1j ν o~xjjEptn/z#US̫K^pٲem޼y޼y(rغh1ʻ{ GZǹ $~ɁZ0Ιa ]~C37oSXp,`HA*E CӲ.t=ҙL$*dT3u L0N߲T*Ρ,<;0z~ 'R/]U$MYjjyWh` ^$MYB[MY6:ESK^|rt6m8\ꫯ>ѢR+J: DX`r$D" 'S͠no&&fDwq8z?<` @.w7]: Nlٵ }ci=ȼ`>]" Yce`P& 0j5,}dM{ qYY8ę3)jsq\Raj(o)t(oᛣNÏIM-4>dsDmI.5ctnMz#"VDOF)cK2f|\t }qWV2"_~A .[?HXͱ*_K'Gw0s^r~,][x?nywY1~%Oe%䗯/?wh}KTQ~( N*d&W9ż;/ 2V:=gdN:BP(N]Xy않m+ ݎWֽ.hO΍GSmNNٵGq@&f3$Qd"Dd*6ODMݒd-82i]aK}%@LZnйp첫%n?5>-KC'U?EDg:גTB G~z畢 +R8=r5t0}}j5hш Gˎ;J) xy͈ȇF|42ߊ ̨mȻsqg͓@ ũ3tNP(3s BΔ@<.fԺ_QyunF Zst=p"%npLaF9ӡ:wwϟYXckƆ{SRX:Dtn,[q,0ѫ(%й+EH⤸X}*N󏄵(ކbbB5>P(9BPLg) b:s:g޽{#ih[^~pxΝDbR4eI&Ǘ7|bR4ed2ulSee%ը[d ,Jh6005tttTWWSֹ vwwU "w0oa߾}W BPM6e21s: BpTOT( b̘91/P( S6f>m:ћ=cBP('ϩڕ|T( tFBP(39@{g$|P( xR:k o>~(CMxp Vg]Kv_BP(NLtncj `Vи4V( ĔB]{G}p@3oº[`of_-O*S( -ZxPDE߲\~?WAu$:9ꂖ`P}3prBĿA[ U* b|{`\qȥ pօB6<Md-cP3 B@7t쁹Kp_BPL)ֽV\-t)c߃"tn)ΡO?s%4l:_p$gŁcCLfBP( سB\1(QJ2`Fر^Ĥ\x"}!7 +[4U( s=$9׆X5X1V]7/\1 YȊν@TP(S/AW\v 7~n$(~-!Wsn7Ã:W$ |~ϔ) tckp q{@P)@)t./Á͢7WM]`tf0TP(ӆk?gSġQx"2^5*΃yi;NIn^4-JKpwBPL/s?-򣾐ꁭO JraO!+{]'7Ηa`?U( ř[' qeoB>x'&!%9+W|.1gLyL=';_T:P(J r|qQyi4tCtS{sV ~Ծ t8mҥRIe9̋Pw~ P( {) AIl~"eB'S,叠;r뇟|U O,<_ڛP('N_"V*BX!+F>#P>pH~-㞴[ w}'3 bzNJ @L*;A\%~92<@{8Ió?\BB1e!pUg,O'gKUDlC6 i bt8pļ.J5D7zS,5»r$` ȿڛ t(3ؑa9^Tj7o.qY'kj B1AB糷 )'5iD^)ޚG]sS&Sg h%A3Y]C>$Yx[:|B]J8g8Ā;ù@<|OF|$Ca|X1i௣qK0{5j`AL 9ɚk., ĥqy SS7۴.3:GN̏;p?4 F$`Y6uQ>eTckdDY4ЂQ(FA]}HD/ e^CMV[0OE~%`.zr`+XލsYʩ]>?we2t 3w8-R GO֜߱~#/#epWK3pS4 Z+R~7 Y(! >/Xyn:%@Sf&"xr#晁iPv@?wfL'&d2SB4jԭpx;Оִ ;^<ؠ{ܘ$jZqzfC8J`Pj1l,FtZz ^4 :k .c>$7K2i& 4RepTknt҅Lg.ybse nya=v*b @uiĉpI/S:p_يT597<:RDdXn:ѝcr2&)-LJtB}4zhœ\R0B*5nÉ%hcS.ooE `ȥϩO@,KKٱxf .m~69\XTk.XY>^a1b ~=d`ep_ 24Ckw#yG |C`qx ypun*A=,aݘkh<@:Gm7õ$ԭ! h\AHce93g]$bg BMbh0RF,@W_;2.dr'}3k U']yQ+Zjc^. ʒvUVG+ ڿ2CzrUE9GÄ<3`NAY%G#'jɹ)3<1]RօAD,h̷s7'֚z>#x:dgŝ=8S5rXf]uw Ԕi? &'gbun*Oq@8Wa:6K^xW{ϫ;ܿb^7YD*¥7A IdD ,6Z{nPI;wtolt}~g@$ϦpP A4Z'uugldWqRVlq|= uH徎?1(惘%M_O8H}O=XŚ%y?daBGEd໽k#KBy=ul%,hMg86rmET$;61y)` Ž 9oN?pmOIs9O\T&b|v]тU.C>׷)g5.MtCmv֩fP_x5a+8,k!gz)Ncri\O,YB% ]1+kw&;gj !/Dy ȍkAp;I*|NF]g5\r f8W3 ׈'sC#P~ԙ˨ƶC^ |е/b:T54]"=K7+%\:iubyT>Ɯ]XvNUem)d w}D :<~mh.%D;[x!.5 QmY[YqpMYp$d }#8*Y#\:{Î8\eo[͵j3`4+*5#T`jI=~9 IŐnbꪃɬr=;Ϛczc>ؕ'#9?uv][IoVAǰ5e.}& -Cdg9d %Nt t-ؓgX!,"s]e+gqL-h1vU6cE i0?zPw@l'(_|3:N ꄘ$w/7X^kyp,>XmSǢqS1˸uM.ۇ g-'0Wb.W"3 dRu1qCD|QƟi}(+k)4e <>"셋e/EڃX ~˯4$wLz~E 7N JavDɨr$^3+tC^gbQO;baĤg 2j`@!wtw)4N\bZk2"d ?h P!Y =EIDkyi$!A=n,!^. n97CFFo1:: ɖUI5)2tM59*b 0*[1IK/T'r ^E{]Pf1d-J#d` +C1N%2Z700_oLN͒CX6ͧ:QރU*:QD\tH 1f>mgy"O2:fkBAOwE8s(UϠ ^/{g {ZeiP"``ήk[{&Ds%Zy8dBnG]Veb~&ԋ`X1j2='ֶ5Z^Q蕌}V$K˹A32qll/C6K̭*i^KHJ'1\9<[<*Aa3J.[Xl"|-3r|1rjP44[!fK e኉0H[/"-ppq %L( &f Bhfa5K ߋsCa/f~q&%)'ZjB+Wkv(k!p˙,D?O<' r+_ԱB7$,Zpv}z"Nx ~ B4Us`ţ+NƀиJ PW b0q?* fh8յ~'6dՌjF}l # r.&)Η!!( v̘?Z4KId}.m+"R@)XMHlOutP0-] ̠ijR a߸d tzo^4"bAL6rC[yH@ԭGXplLPɣWyEzkAYFIk{Tp Rq;q(qw $;b`ve9T"X'?c EnkH5DtĒ@Bi ί_Qv7>%l#datl t@e(w%ttADBAsS`:7X^5P=9ՈA_,Fu4bD(TtPNtRqq 08ClP ݳ6rS'$ s9#'?GdzUa5(p_lY,TpgCO8 eFB!2-_t2VƧXUZY-LsKo-0g^kYx,2hc WAv JD{:G8ΰ(r Kn7^qüXyXP)ck=a^ YY d$!/f9[Vgs]XC!'W\8?E2\4_3}; tHA@Y^mh^ 02ʨFulfDkȁyTA(>@8OըB/,"HI12 E$?T#g[BL,.Z,:Ie'Ҭ Gt=i˶INKg71:a4ăb0Jfpտ+k[9-  )$D!w;K2 ]9XaU3VV|ĊLq@#jPç6 c.6.#>dӔ:wLS9B,jR##.sCNFSeSk`Âɸ:@;z):ZUfp$ZSCď܌BI bunp 0aLf߆+9YJ5Ϩσ)D!BO'!ָ!t iAoPY;2E+nQDJ"p-(tD%X#bkN(պzRnhQ.W7)l 擕 kxi˼Ys*iH̡_,a*": YĬݖtgӳ{6ݛ_LL Yb \N/^xȦl:ͥm䳹\8%=/]ԕ j&w|*Ɠ?KROK:&zi#7P\56 WZ/:Co CtA0(дSxzמ}C1&D SSyRG'4}=ng ogSha7ES %5m:žBz^bb+M=W3\^o /^b|W;Յ~63Q!u1`R-.:>嗆J's)^RFŲot2| 9q( ]t/Tw^%Mhy4[ڜrb ̦6]/{'6& :cCϴbҩO=[Vp&0u;ƉkSF˧ 4<+43"j.B4%Zd fh}^6gZ6 wV{QY}@ڛ/@E(G|ߤF,phf$”p80zE"4oRJ,c)J 5q{J䃁+\Y0ӢAznR䫡`qѹWet8UĈ7jp5&l/5n_/Lц8?R!R8r, -)Mcr&1o<+l9PVoס퍾m{b$dRH,A_n|F{B0 nmm ,~|V1u='_K2wٜ4p dk}ݘ0@9y37PAyXtz .H(XT.J)< P^ ,bl~}mw'SNa#fG'fF\{R9z*twXk2EK5?!Gfd9Ii2n41Kz_AȴYr3?6, ޚ iR(8Љce9•~<H X.CWM|I}ѰbS] r|_'bjf^fVV뵐 V#U}nb)Cy[c$ZAųMr@縻w{ժWփeLvkX|x\6+zxOe.X<)Rtf 'tG0&߉ vvD$&ۘ5Q(o(S1Bc-NnYDsƻlp-̗ޖ/1dq\(ޢv?齒+&nѫը 6 Ёp.S+`"XEeۮUe~Vqn914 5(11 Pz /ضmfa҆^ksdyPJ?Mli V!z zgЗv.=CZd }BƴUYWoTAEgrAi:1rS+-u4=*CiqeoLTb <4i3*93uNFQW yh b% ِ*ۣ}m[WTۑ U΁ =lEMN.sr5YNjZЮ7c ] 5=,hjA1#Q!`;T`.Fݖ#qs.w'cHDies9)MiNI>Se]DZ.#jl7Vnb'+)6gC7P5C4:r! Pk,wWd2ͯ[huuzPdW[5;h@ x0Boy>1 a M˼{=FU n+37ҾV+&1>)GGPC,9pjȀ:28E84ѡjpS w5М%Wz«Zd"=Z"M|O(}md/.+=Йj4 kzF|ّei":+v^s2?Sc}mTֳƏ\Xե|DL^&T#A\l5C#F|>ݓކB]Ŕ GTm=ee.:dXa4BŒlf-'c+4mv@e}0Lˊ#OS=>Ks[fhּl0.w^M2b8ՠ<ʋ. *|}_ EX\}鞑z s,ڲϢಃ}c7"fҩDS߱gg)dfhK\[[>N>~ 2LBca0򞙶rfSX3m 鯉Ca_"b᥍/se$JyܓfX%f~Pl:| pp_XGem}OCw z/N&lz]Wug\tZʩ&g[v2&4TC` @=lu֏p% Fʘqʅ/_}h$ H}5S>2^b C8dזwhyk{LsG,O$@cVק|,ks^6%k pI$uMJk=`tzxF#0j@p*b` zzTt΢J:_r>,tnr'Xp9{ֻ{wtv5*%kz&Ҵȩ``v< 8H7Xˊ){U F0(n>^2o[(%_ J S ~jfebk K 4-dd ;ES@h엓}#+I-RsZ}|O0ъYj歈Р<0 [v:׀B:疯ySM9")uս?{$ٕ{]YY=  0 IK)(m0Bo "o i!rZK#xӍFwuu̬yq:ܬBcTʬ}G97(P57_Y{E'=>5L:IP/_~K,6@EHӕw`u.)+*I?Sډջ`k5& fn*V}YXԝ57ҶYA֯heԟLHsAm6z?\ia¶\5F2{Dݧ,9|р[*^ 8n>8!Iaz`x&Kg.R;7.'Nیf(Vŕ6MVm ްQYygot<-C,+C8T>B,pdBfT =;JRt@- i= D0"Qr2|ZM5a# ^c͸Ĺ.zT\? Go\ rlC4>~B.3t/ow;r~_zt頵9ӌ\'̀c‚U H3qRc 2r97iYphPVr\5.SNx~ep2bsWc+& lUxsozF"e2(GL341wPώy5h䷜"15KN84P'қh[R<z5r}E4b 5gy[w_3 JlW lL5),ڇR]>*QȓC62Rd Wzb㼔/]r6qȭرf>(g(9e*!9GX5C߽MDP4cq99?n!ZT<,k<хFghS`{;.Q !&%d6EBb@hO33R]۱` p}7!ߩ )`ݳH@ӶVs .(w"h (~/JL;̰yGά{[x:FZe&BJ & d,ܼ55wedjDnҸx%^ң_}m c*+/>Rc!^}uWBp(&^![8+cV3vza.+\ ÍQU܍xyUKc +0``7J<'1 6fX`oƜB3؈v)QIxxaIǰ:h.IiCxW"WHx^^UI撳ׁLՃwQ+;b/Б;[SA7.%eGy0`ø*v5hQbR+(@0 -"[QȖv2#aR 45^ lh3fԒƍ)1:SeJ1} i*WZowUoyϜks$e0g&Mˎh4O$ͯl l͢Gӣ>d=e܊kd.i/=J3AMЉ-eSx.lOn4N1\31ڂt$c̱7)5dV*Wʨ{{ K Va z"+%YZ,t8y:zapmX575;m_fɢ2VZƂ鵚;S!7Nb8VrM)T\:G˵QH{XL]>Ha|x''ڕ}&Ӕ8[& CWt՘n"6!MMA)6'6(46d!s/53,-gXy><5-D4$s4[5/ET-|\go=]i;' Xd|Z*s`>SO.9yZ],a$`#Oc}xZ.M64̋@ sSS;R3c6 ȵ},!!aR \ӤTZ9ӔǤ3LJdjT(I4B0$TP'W[qgOJd-6X rL]b[Ӂ HK l}c,~V S%&J熶La<IS1t*0  ab|ch/-1: ; Fv٪ fwajA<dI׆jlRF, -4$)jJ8IkVJqrY9>0ܺfLCuK?C'dr81ɲRv,7/--4{[ giz~-k~llgiQWUqk񠼼y6+GveT aR}^w51!ȸmRsl%Ds)}*h#Ɂ LD*2Sҭ妁JZfs2=כu5wX5xzߚas,/4զ&(^&]ٱ2kt;5LB=D6B4ĪFc@Ymx:F MZr)rI!hd52ZʚW0-d&yIgJ%05(fmĴ7I Ap 2b{x3^+{feo<85qnN7v|ksZyE~(j骃 V⮎WՆ ;nђm\0ն\#"!.AtӍ'i^V~inh+&~-J2mRq:;A#I4ŘDhJy,jyv4sҎ8ۋfȢgP#(Ly1&l@j^2Ce@È.AR#dOgn)Ty#ѝfKJQI $QDҥuQULYbTťRgϜK/vH:ǣF8Nk^Tzg~X}k\|ve`h?>.gŹ ļP' 6uLqε#nhੀʫ{.>y3 p9yٽ غq(>Mj)֎U"儳h1%@&%/ẚ\jz .98~.4l F<*$&R;H%p޼f4]e]*āUFy`\%>޽ӟ^?E|_\_tfr+ȱ&JωR9{ lѴQmڬgDHՙᇸDO}넢1rQy<AIT.3ǻ'q`5 kpu9SDUƯz,|V t?d|b88tA \Hb7zKj.~+?ikN0LRADd?}Cf+L/Q,b!!+^O^ο(35.QK$eڪg38w>M+p*!`-"”N\9^{x0FΑYKӻƻ[_ټ<ʫJ <~<;Q\[I񫉷V7_-wYgvɕKh2m嵕t0s;P@pZ?qWqa4F~/}Ja W.Jksgf{?p+[n@eHN5{kӽzC{kũ{N׎w0~J&ӎo& ,dRP[i@۪H{ ;|e\ВT0[i(ה h{(\s>O[\Nk(Co6Q@BUe{|p/uӓ@nW-@=Jڼvo;/,7Q. McJwa$q]#^mWJ◾,ݫ+ cm>9l<$+H-! 룿?ϝ@1#OP}Njirҧf%@ UomqVYTxeIJ; PgGZ!ǎ3R5m/7~* XA/:/@9"Z- 5r ci,0w|! *f&P#m)'2ɃB:"Mhqdɉ**Se5$'|c~MFkBmAp! UxIAcS֛ Ҿ+jV|\˧hPR~V?^sH_V&ɛyןۛɩ.zuNg=@C!pL->'fEl Lfo]YKVN@=l6G &Gv{cʊL!oSWX_i V\3G{v}ĂQ݃n_G^j$hRcB#C%NChX4/)2cL\_ݬ*tIS+x6s.3\4@-p]4-Lpd!5.G@ɤ\AbOkBIo{K甦H(eFb腻nSlj@HcҤ^b\>RDX>Åj~6F^ G#'< հs_X/ƍdD<8tZmoZѭ[Y5^zdy*\,^ ~<:ZjhJᬼvҕ_]YyoX׾FvT <a0el>>r^kG%廹Ee(7W~̔gU)| O0=I?ocȈ6RssFT(I:M wfqi(Au06P 9A\}*$h0C~:{ԋ@9O UԀ}`8xxbe7CѤ]ЬS9 K "l쉙OHH,w_7>=eEi3y4SdZvn@6c4\j>2HCܼ$w5iz[wޭ?gd[aT]6M~`I8BsOE8(!lA4mJh/b,,^EC+*jD{VVWjJ^OƐLOpeQ 9M۝<-9ަe[[ѭ۵8M M@7pVo=!̴ITܭuMg­ `z-jz`"Hg/oņN8t7gmR__x?K͵kc6Fx H_lukn\)\Y 1꾲U I8ḢG׎#/x 424ĒWg7Z\#L,Y8+DU!mUzE׈@SNTjL J_U5+kIv_.=xx +qPqx=ལdr=.sȫVbDeL6RљNft5dY|o ׸݃\)=yt_#P+8|W~KBhf\Nӣ=ᖸv11jZ脪+б3G50+5|РFB-Lcם?p\uFK!txi=~yg EՀ)YLEѾ!*ڮ*ִ60 1IW"=d•_yb:e̦ yn[ s:^)R3qX$?P7dAOxxҮ;qӜg㧟qR#i"5Iqba?oRӴvi9B`׋oof'8Qz 98HVŷ[ٺx/|J{P*Eym2x~%\HX#o׿_x. 31 ί}9+߾>.m#q-`{*$zX=[*Xzz'6H߇Wxu r1hHffJ% 9^stҽ- ܚÇPHm`HGfd?&>k jf`~:Ww/=TئUjU)f| u Us@)Bؔc<gGL ǘzi{XM9j~OpLV1ߞ#y=G;жh57)(gfT<J n؉aFQP9"tzvh Ԡh>s:g4gA]Tr]s c QJ?q|#nAl#LRy.} $v7ل1-!8f8s?|?@;UZ=!xݳo8~(Ptǵ+xCOsð<==uڟ m~_i'nlBB"Av"sz!zf8ġ~jl\d|Q#7xk7/mv/ /[ۇNrqeu n:M6j²sBD2/OmmFeCiGR c#̏dDԫj} ~t};xT\hu@R 1tsl1i JkrI:rv!`D-"(HH`(/lN: p;I't*J̕p9 BVpLMO2\`&[Svf߿EG]yNv+걸6e R&Vs*i_6ޟ}rˮ8x;j"$qoXs^XK:4ES{7*#2&©tUӻr$Oms_0/nBԴڪv1_zpϏZN5?:3}n. boYsH+G U2AA*wV9jM*&b1UzZ)'׮Mh֧g# QĈVa`[my abXDip.p6IHs~C,3qOIiяOd"#b&!#oEs&f]]Q0Fӓ$qjMTÚ5gF($zMI\Y_>[yաOz51p&LZ&L*E71tLCT`K[ G]S?HC ȫsy(SWgCl3 x4id̏Ȓ:mq0cf1,G8⇷4;_rZiy\wמƻ T\dHx|?}5vAWexG_/~~/WV߿SmNw^P \B0C?!JD&P-`FƜS`ePdZiPB#h>F_f@Pܙ} ѽ!EO:դ2erվ4jl/7noՓ#t؄20/!Ο?ٓM:y"3m+13;0@t.Org$%'t"{+~~3|3zdj`d-&KD:L.w ܏ 5{JrWLI;f*Lo6 {BbB! ށINieƬd+` Cu")͆LF5Jo-=$A:@]2`ʕcZi_bF.@dcn LRYcDj.3Fr[ p"a->h `SjPfZXO:b*Ф헵Dfd/X1(>20ňʏk8@P:O{ lu1M?!2O<ԙiY #d/C}SVOYb}&cY*,D5{Fp^N! 9sw=O4/*A5VD8oA޽7\=tLhssdڭUq "8P s :>1Rti`G)̈0w~b5'{OwxZzd#W5]9CD?9A?bAD3f2!u(433+ xty2JO<uݥk^/זBUTEjmqaz Wj3-/#LÍB(A3amVTc!jUf[1FBg-5a&9થ Em_]uظ7Lrӽ{cY(C:4&L__5Yn%~tvfGൺ&~ဦqљ$S\ G5&OP bDؔ8`l5 )rp=ZY,PS; Y۹mwοVsЕěVD/R \'lZB st9@<*2t9VUzO%vp2="@{oݪq3Svp~m;c cW~'9yi=wRG`'{jjlMj2eeYQ9P69.IKi'^MHga2YMEG2<[cԅIH]Y1[ƕP$6y@V öÙ|@T B4RGrm7li@p)bPiIbP)HVlnC{FFUɎ9A`Aa>C 5cക;Wa;|QN(bh#ȹL\}kJ@ Gr䱉;T6;Q|P[YG*کK|{W^\@{ xF ֱ)4di`fp0X7"g4ʔ#嚏hOORwkW)ye#q|ew_G<<}d:U3h n:aK |φ_j&e*-XڤVϜqgSXŽp2pOU䪀mhҩ :o[n=@feRJo`o{fD;:p|O((&؅ ΍ "NqWGVV !joZW& h2+ɈUk^v.TYzʛ8{lX .6r$}MÛ>}<$6s!%N giheV;㡏YNx'oz2ܹA{xv;lh;+^ fR77u.29b}؄(ZX! ̴AuMƏ=qE& }f =quR1:?$}#2"iG*`wFCsl!/e6_Z8Gawz>r8=Ĩ\BfTiW'&ɏQ0~&̭7*3ڲNCY|VPl 1$}9gTe@Xa%j8~nchϢAv k5sKRaHWyuKy47@9P2+Bmб"z2h+f4`R_"(^w_\#|~>Uny07䭍/+s׆O dђ\U#g9p)L7/d`LI6/ 3}3(8gʛ+)w%I-G_}[_  Kkht }f(.Z]]'ap|u؆05 7kjvQྤʲ)Is\S\{ylA+|: qW_{RZU|\ۀ].dVrK{[WY'36W7qI=1u2tڀ7VK;@b)dTǣq9a%K;_EݛP~M6w;~'89y7fe?\'+l(T܅˩yrO'I]u52ӸUI@n?HꋣK6fz &c(2BdF n6wAsqnI­2!> %/Kq-w}Ԉ/+N),/Ċyχ%j]5T|_үg?NӦn=tKpャ֕y&!BaNz33a!QXi@c3RGGpFRO6&ALIR52GC+I^<&c=)T4Sj3v8Y, p@S*iB"ySIR ]۞%#[P)h-I0q 3r&isAc).ʴ?4)Vh29&hFTNnG;Qo?|ɮtvu fN6Y9AδEؾO{|~NYt2Bƀ'0D0U?2X g9So󣈲[]확pY}j@F WoRGØ_9J@ 귗/?_/Kr/8/Tc%Szm1`J"ɵg ĩ;'!" HQV4~rzCPFQ ii{vZ(l Ṳٱע/ݙ1 J IA>L/W^̝-V/m~~i~34KP;)@فom q+m `F5.P{=Oz$P&~V\,++aH]}fC_ h)!fjcUOu|R |p|:fڹw&Jjn+o"p~{כ @Jyf?ݝM+V-i[Ě(V~usn4Cۘ l>Sh9SD& s3CzńsȌ{;+bfJvxǯM{#G(EAAqn \m1r,kju#G/m)9F錙i A0F8!N5䛉!)k"dh|E; RnFOpsG[k7[[$l+7s1yc%cU6cZzoT+pz k ZU$B\iM]4/7I Ap0dB0\;2ۓ]e&؟N r%"7n+>]yibO@4 A.2GDu@rk~tA4x1F#ׯ=v4']ս;ka%GGx޹Sit6 l ;ٕ\/ Nwmg:X?JbowL K V3Qϓ9r6J{ !Dnz!t@h֙印?BSqWZ'pZwXyCF!r'[:'GN <[{[5 | 5ވ _|1KT\SŦmR ;1j_Ng.&Hj:ڦq+X~O8esqӿ4Ij}=k s!`ΏlMiJB鶇Te .T92 ad]䅅iF"WޙNY޽m2E8R*̐!lN`ݩ=ʷwlhG9pƍo__Ǔ,ׯ\JuY$ci9\;N}εݽKJT{X"khs3~S q]'[`כw/>y~#GCIh@5.4B)ў#W`93 Lidu֎eM0cJE"Nb*.LfE%e vf~.Ee-?ħ` __'ĪSJ:&2CI&.xjBJrn)cf6H^QsՌ|iuӟ{ڹ_9m.!(,?Ô [x㼨˚Cj߁o<~z4o6qU6̓WX=[n {#_ʷ`ɭ‘'`N":Oi nǴMV^E59TvCų-gj81)Ƃ5Ukem=m5,&8*gm(5=p-a֎`7NPDj>  DK&.B Du(!>X"fJX)RPHu^w7iˡaY #%MM-xA()衦q&)ߤk d:Ѵ=PcoO̹H]=3JӒGAI^\IZU*ͬh "Y;E  bAbЀ0a7 ¾WkK/?we*ҙ#6:\o'Is6P7/G6I7Kjl*]d˻#V4k+Q'WzGn{X4WnF@*SB`qWf1(]S/ M@9L޷DfN~ɤ yK)]?GQVtO逐 Q+Ch`MQRAUgVW{)dkKanռm;JJCugJhD^8~ p(d"#i7Mʫj{}Dz{RuM8͈)7ɬU*"[*) mX#, Nm;g$e *fm#9¶7| Uw%V;kcu`@9oj}U!U٤&Ա+Xɖ=ok'oGXc iU_&b+^6[$q׎z(_^Ok)rL'S3\e%_V?-S^ŭZē}OiKp$+{BcLspXiܛăQ֒[CAPv+̚Y'>`:~pԋ0' 8$J) aKU1Pb{i?a6my#U* [YqK/^$O#{M0 ՔVN)dmcxy'Ϟ>KOgxp޵J&R됛/-haIz a(VӛK`uJ c p@O\C$%z2z^<7yaiֺ~F&Fwa g3sfrw`"}˅8F+iaۤj,ə?F٦hح1 }O+fmٶqк0{ŋ ^㩓*8S~ӡ8+ e9 X8ݽ7^wLX4qLvi̓@~^3 FgTQud8i&Y RK\_PG%O?_j.ѕ;)7è}a.L+7%Df3ʸ V@$DN_{7<`~ǭܢo}o8'9_ ~j$+n1XM|QVk`98N}_ X}ӓq'@n!C+W|;Lb/Z a!dnlo{+{d%XŒ2vbش~ :dU64Ē,lPʌ$ VUi1m fJ*UQ{} Ƃ#@Sw|5M'fh½ôn'nϕc trbf |5_kJU]g?Ny-ŜQ\De2"mUY{C[?s? Pt}ML'V՚G"s\v#z#bhl+aV lNF)Sü#[G6GDܙ]]~-#e 8 y'?}=BHģQSD.Ղ}4!07ii&:& YYZ sz|*.<.#_=U!B[H%բ A ,v]^KoxNC [o휦t‡8X)ۊP`3`ҩTp4Ka N"ə#,ݙ:B}4цO(Th\L9 Zle>Hm^.tn7_c츟bSU2XIo]GIhj])4j3i'arEX"'DRO8g%wt+Xb8x%^2$+mdS8m204"S;֍:m1lR)Iڭ*80Eu'hU{} 9m&se=L8W]|VY \a(ECV*i95uKG~~V#\[=q_i_vfJ~*vlo$N̒^Ά⷟!eY"7n cO'i:v=gڦB>g<<HxuNvm10/II>xt:lDJ&InԶ};+vR hhzb;}W+7]K0RܮFD=]Ƭ4Pdʩ稾3 c\A(Khmk0 kLH~i淔g;biO\I]Aλc QdLdyf&|o/㝦[yҼ_+íav*zz?M SO<(xetn#zjG>{"?%({83 .K"!MGiy }43m"Φ}^{n$K1Sy (1Y$؍uE9cQlFu˺CbN ͊&cxЛt VAzp-{K|3?8ٸ*CzA[0rg=0?vF1I؈ʒޭ[§ epַtDg)VsBn~AM)єҴ %~Э`)[>ÝN|>RՔO/_KωJ#/)iY:Fdӂ1feHؾ.;lw~|78dawt|Ό;,o'?f#ukwLnVǎ>(Gϙ94dAHi+`Ӝ[ Cş[魟oXІBہFvQ`vv:b{ذhk]UhQDh쏑UPj@J*S[1[C3X(b[t^rRNzhJmiF_N"E t&7{kۑ0:!F\hPrR\ĉ݂V;s-|^70A0 г5[-nfI_Zט`2@RIl8ڗ+ /\ȘLQ`wơwt 4\6wCCX,NY>!Bʁ Hw'+j&0ߨ`gt:κN./6-7+Zqq9D dR18VXcSa@8?/pIFkf)RYD+1Ze@~ O|j}vat5ID#?PPꛉwZ1񧎵{xy^8{Z8>hD2 - tNW\gl:*0f1+kv#kd$MVa6_Pb/D|˶w˥mk? qI> 18dQ8M7oΝmd# 4a'i(08冻ynUo*%`ěD :ؔGƓ+ 7lnGU+5~$MB颽(݆,2OIᯇEadDcۭ-˕fz v校6paBaÑ; ޵ÙVC0(N dʱ/c)0FegV!uh#5ZK1^c\K^5[l?-HZ՘ۑ},LV3yzD1tΟ5%ăk2D5(Ίm\Kz[2sL._p%BҐjO1{mpT4…1?F$/ tJv%sO J~*$ygQ`*6uܝ~O1=ٽ=k0ʌJ/g޸s?Y1#7N4OId3 0DyWvU@"`h^`wr+g?s֝2e5(ۮi`o%uR§f'(~*n!\F Y{~%ɪdX9>;צgV=CKʒk{\oQ_D^ #j kYx 7u0.4^IU\fh$ᤄʰ|vpqo]-x鯷!ۭuH]_f&ice>o}E4&Z9m9MtJp$@-ڼo]'3-?wk}Vqr:^9YKwZSǟzyg<6|4 @&-8 lT6ixToH,NJ\9iki@3!q, lu 0wO]ךy݃q#Wdf,P/pG֬yVEשxau6-&WLkl8[m{m]$)bvgl>A^m_6C&]aK$!>~N2a/1EF@xA-V74#v@ U4eJ+V祑f3*SrIrp4!rGIoszD{5VF~m P,eb3I)Bl~qxE 3!TCĀo<= ,E\3kgv^DPcz"(n#i~>8/bY1ZIhjL̟Fe7'۳tX& >Ա'}ܱP<7x*9)^ 8]Xa W0@AṵՕ1sΕWt1pM1CObǫ({r<;ت׿lisN{#H@5 5hp3KMX|P?Nά0|?2;qWs!zA|\Ȯ&-%4d-ewWX[ w! L MߞhW^z~}ʪWU8m_={ = rvb5 #%˂~/>z~!D)59)ۜfrƍ>Km%33͚(1P+XYN9zɻH"U$O%d!)zVG͂ڟ褬Փɍ2%ĶmVB$dF !|G7}$F2nz&TkWy+$QeH23nd:.l!9Li5 - ɨ[{RF|O})SSjڶl:pRmk8 s-b b}w_}Faf:o,Tw/ 6^1߲ilŗ_x-;3өՖ̑5$x0~>xGw;Gkة z"4KT~gowSJgl3*흽UXy7WgHfFI%5̮¸洓;+լ?+g?E1Ǡz<_:ceq|##\ec)"YV6 sʸ8Hw&^ajO$lR Ha,9Twr+N>dkc3E <o$OɚZ3ss`ul3_9/t'1ӇLsV=΂SFJ5$5#alHM;'-]ofI[Aw)`/5EEX(!ˈ!uk?W iWˑ5)!V( ~'PDʤ[9xd2em XǢGÊPV]W?3(j73-QEqIR2*6)<ͺ&WmP\em/|o<}` ,e>{dFXDiDWOmo€4T$ekioXTy N€ kg$_gNZڝ)_x 󌾒i7n8+] "gѡk_!5Meт8WR)W2ewe,/SugSh,ut~GubӦHG>yƦ]%^l8z?ysa+8~u'w$Hg|H6ĂMСuhn1f0NU B?cj.Z\I6íM2ےIyp)& P t$i|>%F®l6ݠM)le[r5Λ :-)>SJ_dޖDCt _kEeg?W^ x<6(n3+ oXܮdJcxAVTEMpqnm0>pG/H]2,3s^9:a}tORێ`l{y:@9!IH+՜#5ӝLjyBŰ}#3 Hwsƙ!6[f^sWɫvбڛŢ:4d"+a$߄91mŠ}#lJGs2m!JZ΄Fu^X~a-f,xm}+H.7g=]`p'-(qS}k/r5A6|{J3*լ rt u4vFŕm?+L LHbZvְRVU?c82E4j@RK3i}k{nbK[ X>۳SG*[M߂noy,^x,*ܑ?".;fPlL} @N5,S';0{_;;# arud*\xE(=ut`T҉E&j&3A<\x1i\o#|WEls5O^^˂h͞TQ/eVC.BZaO nRpj$&r~l~X䨙 UژwubE)n|NM<'̛,i.E8^i%.O"bWPcIҕKHxR3M% pI©'sQ/ˁ[|RTH/s&ݪlydwL41185n !WVmg!ݮ(Ä TҗL;GNr\!e9$&BI{YE䰼J55]E]ˉ_ҴRp{!ƹ2 u`ALSTd~^q0{wgUf?Wٟ εKo4`0[ A:'/{p>KO_rL?#qp"@o ]B[Ӹ=#˂魄ThK}nl1:"Y[E\}t\kߡn\(̐&A0>y;6Dot1JvCX^6UiV>Nj+l<[ms}9z RҌLe^YÃ{XPҸ@[LiORoa|f}eDj LK .ivI0&)J‡UV `W-Y<4Dzsih[|'EuMzKKG-Q&E%6S\G&z-'< Ŋ5knzXDs~'yGs'zh} (C/b"kgKy!]VϮ_ isTwxZVͫ;߯Tّʍ1f[箐I"" w33}o4j:z0%4[f$vvCB1Ea|}tcM1IC W dlY1ԛBފ>)g%=sbU`nf{UK]zTz+?ufp4d s%3unSomy7 C2M`UVH<8ۈ_vw4(9ʙ˅MT0)44Á[&=yM!K@M] fpQK1.mmd+W_vq /淢a< ! jt`=d_?G?r=F73P9DhDwm}Oҕ ?ʙK[8ɤq/YPe #$Kv[=٨vAggt &Q4ʫ6m[VDޤ~ګ y[!!s`ڬ;*@F3)Q~_G~\'%}3T@,)$՛ݢ%y ;V%_Vҝ(ǫU˛)a"w$/I$'k0GeD2[ӨemZ-T?$nj˧Qב$|6qKR/Z=G$8#˂EH\N0?<(2E 2H#DvL38;2yzY|-L"!qNb]-:|IO<>:)!w_,oULʹsZyZ%O/=Ji~H'ܙnngާktT5!j3-/`0F#31qk ˙`07TWMfl/]WY$taq)A)$hiMOTѬWzX鶗a "jXՐQ55Si*Dv~+ZA^fm%Q]dDX_j,cY{VTԪ @qyKOaP*'LK{Ic4%4a ed`@ LEb),!u-?eXuQ8.h1Ј\5y,Eƃs;$-lgc7ekj制Q1]9ߓ\oDžVB&(#DZ\gK>[GWYl&aYi;{l J^YVQ*L_^@5_#̑20HA_7Fh@&T0eS8vFБ>u1`?Hڤۗxprdo`ʹ LayǾeҚwLL6O P#zX+_:;ލtZ#?;2:D׻!Y^q,IQ(׮󲜉ʃ[I_wmIzZ,D5Bcje#~z;=?9g d(!1vD;sFAJc2A!k-TRa!uQagf0!Y2 7"+( %3yܩ6'ȫ/CM ⁀{IPc=Wt9 ,`_lWs>b%|zd=>sJCic6YRJ(vA1 ۍ #_2gc04,hvľ 8HɨQFak>GrspYuJ!c1kzsuv2&ȁ3KLa T|4W$SG,41i[]eq=`&U//̝DF#!i3rM4EA ~D\6SsMD:'J /gꎮ?:lZGGT'fOs^jU(@FJ(S̳ؑvkh imqb"h:G<_Q(;vќ'i)f_Ȕ3霍7.\SV9pJ0Mwc;g*kB&UCjT8X(yR4ҹw!b6૬4uZ SAa0萟hRupB@ oJیFwZD`$QIHj_@OӱRh},R| ToKC$vm?uF(t,D%khaX%Ciu!UhH-:%s.:Vgx ؾ,߽|b9aY ؝))x>zw i`XxpI0riv{E*TjCʯLm.UhZ"e@hu$u =[oϋ,҆)P0 w?x[6„WnbHxO`jH搥Aܽ(a%iBl{a)_<120ߞÑ B cvL6$8 M3o"qmhrYsXY*BwAiݳ j<0ATjݓa0Q6c%*qPEx(zk%a-+$C+CgOdN.(hI|"*G `NR -A@ơy'註{^&9?K6|.f (* k{~-r(?ŒJւy&Џ?{j[ TnM{ +BL`W˕䭰l׫{Gò8KcHPИ`tgz:a{n~WeE&%2[TP8æQh`; c_95b|(1RlB tHä<ڛ ^Wrҏ0VďR=Pk߶!؃3El hqo}5j݇8Zv_r<׿PȏњiklS-JdJ$eȄq*YUB@;#W4`z u)2 qs\ - |D+N~g܅Xи)aKTn%o*F޸qʋoJ s!OmV.T%u1df!tÿΘdžE YiFg*RQTqC]B/.'oǖ,>t|Ϳ[> G7m\~Լ2"F\aM?x'·(; 4;pqvJD sˆqiyN Uj+e q۷=TCh\ŕk8pv\Km5att5pl,d kI+l/m8.FSX<-i=ٟ(b'b Vx*La3`UAӜWM^' 0 :XH*)#]4>F|:H|~r(QJ4AՅEO]B) Cdg\X]!_}>17ʙú(+9'2տ~F3:(v6 i%P&;KjH|yyn`H)r ~f Dipܣo'9go=#HC1/#'^1JT,t[³3aa$v:4GQ9;m]{{Ѐ &cAȁgbz.{9\b".و\!e[;?}B~G77L+ɳo>vѡ%:dwy"ꯝlfؿs˗h7r2$ XW"yx.9@)bCOYcS uva=9A4ܽT()Zܠu+wyJ4U+VV$9$/ם1匛*g4D EJ ::wY*zRJJ)d/H}MIeWf/}?4|ud"8;0U+TO>[ﵼq?t %2@ҽLR~&9qkV|o_(JL#Tcko\}T(Z dbjwO֗'HߟT!!tI1HIj!mgk6LfW^ 4fZ0{ygQ]w㛛Hj8eqbO\`6Usřrׅ2 w沒8>4єHcS1e"̩ǶGl{:-NyonA{f,_hȉY>_լ;,h*ʼn-xKWgWW9G9i+fĹ(,Mͧm0L.}s;Jx$o0YyGkVϥDF85*qr=sМ3B:F"XJoJ EX!d?"B3?rEM'.O:47߾$oYk6 ޗZ _dZ|Νjl}ǦQI92 gܚ)y$S |KŗC}V+sAֻS[w@Hɘy2:ce(~^ ~mݘʄgnʢ}sQ$=KTQ((jzfCaGJģo'RΣaN%n(]ļ%J1@=9ZҞcd xdqODE18~~g7_}gO1JZH5N beڹr(1-7 5/-=Ͽ6^|>hcm*Z{Mu 2ʿ6[k+ 0˱۵pxixׯD^$jU&f’Rmm˪$ɤ<=VA|Ĥr}M)HeI'?~T?}*54"D?*9"Ӷ\<=~mZ-_y/{*#HRC7[k-e PD(>X8{cvq9HgbN MQ>~{~NuT;տvuOKs:nx}FFeA/$wWZ9Z_9踒9 aDl7%m`4Õ % dI#q%&aQ^}|0q~ߊf3%m{*jLˡ OSPDJArcr *6⢳пo])0܀H߸{uIfdޮ0֪#e&a#;-=6UR+yV˔on^f;-eD5b 's{u|&e=Bٛ9Yd%ZZ ɓos^!v]evvK[5aYqkp GX.LdZx\ /*6 R9)a#( p/([ˁ%cR}[1i"ɫA+IxD+kqn51Jp)frhML Z>̪#sf F5?߃@K`{>Y<6;l NP6b> t3f]@U5Qv7lP}#pR"2BNf% Z)/3¼r(]0T+j^YLhs!^4 -ѫ^Iw *gszh a6* =c&( 5Zg^>ڜM0 I{O '`91Xon ɥeSd?g:w_^3+ݧ+';K7^j!`Z>8O:2;҄ h輧=?$?İMSAػB#Gq;*]TʖD<,W$Cujlu)6i- mdHq5gAr3nF`D-rU%jo+ t'Qeh`#xa='AS<>lӑٷgMc=L{a0<4'$ l1!uKb}'[!PK-zԮ&8cP~ @!n Ws./m4Far̙:HAJSWn//2Ե x*@ݧcRdV/auĬh.= *0f$14~?~#9- "EJ_귞ͼ1R+8tZv׺xxyZUd9sFPKUVfC ҒNw)r)$.`r@-1 $>'y@hrySض 6Wo/~JI(SYνW7B]߸+Zǿ;T6`N~3ݿ{t,y|<j|߰{)<˩L X͙$A7hF32srƒC@ e],$49"ܟ]9 pkspd|`&HxG|}o_Y;Ư4@Ii<>[H^o+.a/Y 0꿎&pA# &݁R SXCh໥](H>@Hnxvy Ls? I"0KYجIsss1)" u0MU>oR:Wn(Y43σryh fլTp1 'ٺ}yAz Oܜ4 FT*8- ]qK!Z6pL3iRdRtW8W_[n#xNiPb!t=ڗ!UJeIw?\mu;벌O>v+hs ,5zs/:e zwC$w+A$οyotw*~;ϼ7鯷7~߼^1+;l !Ϝz5o4 >N~ yey6hxzZ;`ȆD-}$a# Bo{o<Ӎ>(=UBҜڐۇN}s7'g|=R NXڽ]iU65 [L#zƕL:Ͻׂ:\scbX^ 棭H,;"\~^EYL0 <7ARxl9eC`٢*??GS%;gC:GZMC4I](YPo{z(4 5ۻDmU5D_r4}ҡŃ\2d"U<сC u_YVx4@_ L#cy7D0gxXhhT(z@W!#uӛk+ȶg: b7qCX0_Bڤ*VpXXՋ5ɯoo|Ow$5 "#ӷ۷7H퐢$~^>gFDm]dkEj&HLE A%sх;|Ĺqv+g3avu7?yV|%S˯-sV פuWp@]sOzEIO=#\ҝy$"_Zб QFqaCy-+X@%k(`P!T`pz_y/?. j#Ql+\;~a5e㈖QN@c&l4rTY#V*Жv~1F7Y+x(܋@ed.jn&9 ګVq*$+[u~jSY~?C.'/\xvk1;{@-;8M;isi̚HI/r1Zh9c⸐ @{d 4tA-uG\SYј5C:?~b ᦤQ& fe QI,'V 5" /_MMup}Zf c'ՂlKfDNd`wo>U 94p{5 V˦ZJ|4NK$w|-)Bg6*:?:[ CݬfI8r l3AAؖs#1HsO! % ㌥y 9w5\ 4CY}L&M"/rEV7_[;KK>ȐD\ts]hyaܗ...ߊpwaksk7s6De?vDw)N<(/E/[{hu9 [۹6VAw$cYnݱ{xu8念w\}Lcsz:/r˅TZhre|";%Bjjr4$B!vyYChL?!$u/"0e)EQ6OxYW߼M?t=Pa,Ntɇ4o ˰B`E 7l ܎u tnYAG"K/\O r aefp6`9W B2Tb۳jhƆ>̺C0}$_oRB8C( O4y`FzEoRQTcX CAr)!VZM.S]5nkzw{rӲ@o.~^ fff|7ֵzĪIQF᝼qͿӗ<~tő{!'^h>*t]nIM;>mIȃ}@!z "(n7./u˽uZʗ_RZaʳ%5B^5]DFQjƈqS3?lC?y+I,0[ c7)˺X[O퐦 KW65f6 {77̭{û7nk,0֌18fF0qGz L1Bk a*ׁs14}̈2ɪ,KR]@Tޱj]~$tWHpFT/oLǻ3MY07 ҔYzl;!q_}sl fF~Ƌs#<s';__{4:K"OR$^}o1O.C b(1H2>ڤqHN7*JxxUWzVSx9 :AHF,Qό ?|gBT+훬l̮~Wj{"2_|&:W_9ݵHO;\P]6(oy9Jۥg˖)WogW0yEX9IJL{cϡhṕ\V `On[|+S=#_u T]-T.eے,GVkԛpqBEpLi:WFm^[bg.X  -s >o Hn/̣n`$$ޡ@N' |Zka<3!jɩ'.ݛcB$ uFLViR;Ʊ\'n^.: O4QQ08i}0ཧ@D>m[0@q>Q.Axvkخis~nl18 fx͞@l_^\Vr]{ͻ7 Wضf+0][Ss=ڴy Xٳb܅'S&㙖[Q`Yit6Ɩ 3ƠRYϋ{ 4:aAe*r9|EdF\i9%լ 䑦-:4i W,-qRge T_4oW*`Xζ߉if%pd~3t|:̄% BR(i>YF69K lUL=ONjhKjx^)19 Rxb)z4|@4xI89Ps4/3#+EKz=M0{8n#=$a@ gna#- %%'&pO]q2Zki`] PVk;WG \\"Ci'^W_z귿̤gv\v, -u_IGJ-,5HDhb@*{ilek1?gs]Ȫ[Vd[a?RYu;9s|\GW~kn4dŠ1J(?˿$(RȌb $s~1<ۨ۩ bc=OᆲՙK*00іA JT֐*8:Pe(v a2,C SnZy63)Y'θ ϥx:yѪH k4Jgb# j\Lk]'@P!(%l*S. 4NqӺX1})s6Lp?,$P4~ Zx6I؃J;Ro X)5_m74I_~5|:bNpgchzn=B8U<<>qFvep+j* l-u<1TaT94*asg=H BE$IkNFZ i+`/rs`~QFET^7o/vVpןq'Qa@ ݵXSbA(4<&unߑZ< :q})ݥjjm`(,qRD6mJs'F[ZFL43  v50݉G J߱VS^yV2Q@tIu4&hb bIlϻ㜕TfXKi󿻺xr%3ssŹpK]}g4'uڝ5Z8 y§FAPؙZɦY^wn"aS]o~?oM{TI~[Rkpטlyvy1R,!BR@N<A5V4MzEyɴĴK1tL*@jqS%Cj_UaZYYzx7=Dh*Z"#w MIDb[_x_{-d|}ߘ ?z&r`Q85I!.ԋ?{&$0Y+ ]X ,h\=ux6U wfbg^IA} `[<5L0# z{F#ILXj4N7w3UBa_/qM2-Cq?Z)@ ΒG - 7I q@ęFAc)1/h[0fv^\cYQ:H^Z^}Æ1I4 X| tAAԔ*ˈWw*Yi0u,U`'!M4破dXȣ޶y6Nӌ)hn$u2_O».҆!BjE97:lmS7Hrt0%!ۀ tP&|7d+YDwO<&tp-YeOr]ygKwOφ@ H"Z,+\XeT*Ry?༤CRrR+)H-E$"%Aw=[~so  ˹_wS"Opʓ¶ԁ0og68g6RRXt95n4Zmޤ' !;v!؁(p,a|{&IJT嶩kX>uU6eSL1O ե֍))[tErƵMxRpZZ:%KzӃE3&\*& 2r5gBWXHg$ 4ց *tpm`㺅`̊[ Z`a2*.J>hK Etf5i~>]ڎ'RGĠ3#xtA͒N*0 E]Bdq^%+.϶ةZo_N_X)3}6?ݎFU"ZBfY >DݘǷz6K%lmNxY"QU-8kIlYL(9*6 *n+G*)xtȹͷw֭Q no.$e]=ShVP9%-1xaD9Fc6|v <؅FyiDKkѸəū}s/޻kESK!?mߗd&_ aEY$ífK^a'csSڊlu hR6sEYs9HG'gNS 7DG>~Pt"ciR{UT⁆&!m-,ff LV8+RFvB4(bl{O(8Cm(ug ֘{L%3D] cQͪp /ӂQʕSaSi V`s,x%/k4XN8l0Й2vky8zw8)p^;ťSyVƌLm rfzջ%(ebOtռ¾>Y~\RAl -!݁Zm9#}澛lHVѧ:8i;g!]¬+Ms}PO<ʞϟ-_^"ٍ|(s̷L劚)Ww`N5$`[ΐ?Yz gx>/'Ssmydg b)(;ijq۶&Ƴ/Tlooнms;91Go [͛O} u4tAÁkN>ۢKmNs B+**I `±{YuXBĠHIF2wM+ІY6^TH1 9'8HL`d[@ܴSPЖX'F*'jrh֭mbfٙb!%CP+^d O­u=<tH3EyHss'ΜZ/6\\2xX6asBG|V^l=JIEo' rm ^Vp6m\< 1, ,4zh;u!C2E(K`olVaVݖLeyX&r@8r9Aޑ~J_o䛇U+)KE6NGO7)zݾ k߿@~7pR~m勲> ^i7ϼ\5i䆎5?D5sx| HEzUmp)1l,h/ʼn!i&a^`q[r_(=H?˅BgzFc"QiN9}%1.Amz&UUzecU&W'dsoonkϻWXin4.!WA)x28sn{]lӵQ3+SSҸIU xf_NOLO((;R_ba1^ބӼ3'??-oYִ.dA 'Eq~a_{~֬׮nЋZ??:| SYpDaQ^!50O\5;TY9,jqJN0~Ӧ"Z,$i?d[FS=Cg!`E KYtUr>On?taiӌ|JާG+% 7a3;N.Eq>ll=/F86sb0F4xlBGm6fVaInKdC%# cz%2pc'1N A W"|k@`!֨j]@&Sa0WYzTߦZ] Η`n+ttUYaY 6Jp*c?slL[\8rFכ;dq-'`ƙuBeCn2wO+ M2KKg(OK%p7$;"Fz<}xx휽c"vaI8T)T߿1w`6x'`_#P+ϳ,Pd.H$d{қuoS!rOڍUl伹eM-o10iJʹϿt"s6ө P63/g^xeW3g4o wV8apї#)#6w3>>i٠T(a5RH6VVIc*{Vx:!2B+}bEt UB*BرIcdH&Ijb!؂PET6s6Uµ"%8ez/pCQl G<1p!SJ /t p("CqJpHMcAFwk8"7!r1/G@!rijgKABrD(VNE-|˷ΆCs͗ ( o9sO0AepnD,aCadEzђL:W.Qv1daxyKש-^\ɉLSWF^zE34d[1u`Zx@iS-ɯN|dVZx0r0IyZep˳?Y;j&p *H39R6'W{2^p?ML ׮_/mѴةh.O_ya1P.QvM8\h𣤟NBAEυMR676KL",zl>Øpf M[B9}+Y^ u3E`=)26S_a`Oh=NJXg)N=ox]`|Wp^Bw B(<$3SO'ϟ&.?a}uὊm9}6e:Ѻp|>~\h3Zcq Bc't',XO s V"scXV4Ki&}ȾɣG~排C}W(Ym_<ꂅ;(ʋ9p$\4@fr78&!єʗdK((r# ug3YZ@p,sb(Vw6|ET7't,=ܺ` Yʿ{z{R\O #j|#oGMpLK]U su fw 8 d߽rtظ,[L5WGh/5.vK=Ұ)u 2׿aa Zk\CBS,JM]SMه\q.n'gL`0^QՔ+0!^DS(X\2Ip"ɆdDgdCg4rKNg:6pZ]bH(a2u?^ #2iM1؍bf7[ ,3Z3|AG\^ud[$Y^gR;bwC]7|X][G3A+Ү#wjZHײ`uZao'v|0Q\q-MdgblBj1! WHl9Z Rz.vՈjkw0#v թqj{2 2OT:끹٢O 0JuS!U1~5*i9l+E??T3{Zxzqv~u݆YbppqҎNuج4Ϭe>V[=;l`In59nDp'+yqiBKZ]i٢]'R<[>|qlTO '$ OYpscf ,#m,l[P\bTKO)?p tx b)gB@aKl!C` ˌJ Do!|8ȼSc\xrԡѡWsqtziI䱈{ {q%ְ)Hrf0ThxABJ7.^ ]T0XT\qwā3m?{ lED ~l /b|,Bø< .ڇPOk&4Vi=!n]P {8,Q*5 7tݾ롂ߐ0"{$x|և3q5qɰ64Ӝ'ZSG.0[ f.qPaHl!\I)n1E" a.Z% IݴJ)TM8zƻ[FeAtؽ!d(¹WmTʶeAՙYhѳum;Ew]pV rwdPx}op1ڕvpgKh탺{;$&``}HF7:'3ҹ(ͮ|'tX/.BkB*Np\~r%x:[HKXdqo[h1_Cvl.՝[ CX`: yW3~xYya`'m|^,[Bve {, ]^1YMQ4V#ub_ U>L!rO :M}&np%OJH}g nnO-F0F`ٰ t Q`/SB&bed6 xb֍6#7Kd`?p,@MMtrzZp|? BO57>wɱTբ&.y+_Z0tLQĴDmw0-5E;qյ12' >{n_ #wU&CG9K|WpyfyfAɇum=]E9pJtDk=vڨM6:WZhnjqܣPXe' .$ɺP,_7Vg =l#20L.Iqv2TY?Q0>l[ldtX<Ƀ57Epc£6Tw xPʥvlΕR̤fy4w-NijUzl& ? .c:K96پcVI!8e(k37O&ߵ3uIS4.˩H /\މcJιU>BtZ ir=xko/i[˿[_^P$t~Gv1f#/W `| ]WSDSZ.hd>\"؇(C92G;HXRbJMs|IvV;#yѹ'C n#gtˏd:l>: \wPfLg& uP }Oe}5(@Lj}^ӄHxiTD9*$PYBU=9bsy'S!Q HX( AYW쇋1yG lF_|[Kr01cV[CV{#`y>G6&J]a(ҎRw=@P 毅qo4jݝ4Ċ!/3/$i `ʐ30ʃ8TbTMc8qAtYԐs>dр&)gXnfr, Mǟiks-&%[aXp ѡ!6X/'6G?UO%"")a4ujˇ*$:LQ ֽhodSqh7Tqc ѪS ,֊&|?ybc]kacJkřfK_u1%m}Bti\Mj)6AQ4[; 7'Y3zma .(á([0N6cg#7[JMBi\Dqncu$uIh FtAwG dekEpE&77ߺ>vxgӢҭP@6{cf1Mx<_}e}6^,k[9\g4B9-[ _9R:Rz7khF azG;EΖ `;)ޚYzO|oNIt@Ő\uTy ck ,-]ӱˢjjU`E/w6Rˆz[s~WvťK?rV;NcGUGqꡮqr3{e$K=x`׌e\DHjYݠz3udHYPe>cuqd|F]/rlPkxH_P`՞SHeD6[9okOJƓ~rV`}'cݲL ;_QhL1:*GE;qeܕfy~'e9=^sA dufG/," SA]*,Fa~8XOÓZ'a%BsD1+|E5DrX5dInYE=z<ڹ|q\,YwALlܝRk' *윥{aỳik xh}ԟq8XxxD}mO(+ Ujԯ ,8;9u(fDq+Li+M;QIJGXo|c8#"">j{rsZ'Xp^2w#sfa{6g+DqPu~kx \Gޯ~57F TV΋{@GEZ!_!0ԡU-<'`3}ΘJ7nHImM""""".>Ko u?I͝ vεTv%.SN)EΤ@t7ݼt{GEDDDD< 82>n{#=$~APb<;F퇡e\DDDDC1jQL.X~P1vn@:'|lD;P{f}aAy|)sGm#额8\M!$rc혻:펛t/|Dv.""""p@H:r짤>s;coɽGs|n<٧\xFϘpEDDDDL KWi~O~v.""""r`#~\DDDDqFsEDDDDgD;q\DDDDqFsEDDDDgD;q\DDDDqFsEDDDDOLfEDDDDOlno[oG;qޓq\vZ{ o1EDDDDD<6l+ι܉^=;""""""RhC+"""""">y>b}.""""8#ڹh"""""38Έv.""""8#ڹh""""">ڰj""""""q`z=MS\syz\v.""""l;Seh"""""ȽEQ>}͛$ڹc]#te\DDDDq… eYH_~cEDDDD\xk׮?#?m xC!d \?IFDDDD|0y.BJׯgY~؅J-,vTIENDB`sardana-1.2.0/doc/source/_static/gui_snapshot08.png0000644000234100017500000035607712174204305023624 0ustar cpascualcpascual00000000000000PNG  IHDR}Z pHYs!!3IDATx|UE'W )!{ R]]ZV](("HCh !R5Mn93s̼3t///"Qi0A666yyy̹BwOx{{!樨խ[7<<<dffZYYjْQHNNΦXIpDaʤimm*;'#5R`A^yC:vj?v,]~Q>t׻v ܹ 4hrdӦM-Z L>}zƍ}׫44,;ց?xh9k֬/RDb5.@XŁpa,Y2}?`Y8"rÆ t.. kQTԫ2w^xC>CB999{pp0U4<aű?t{Itp?g}F cPr= jУ^uk;`$efۄCBvf|azx.u#vѸ5q `ACbAPڵkWSNgԩSK}z*49!{ l vuu5LXΪIznlYN2ȻᆱHRVΚ5n+W_}tK__#kƟг#g٪UR?/ռ\!]1cPg} M5GѣG#yo~oڵ9N|3vXn0BM(Pw C!9N7?+U(u*YzT<<==ٿ!YlG@J;Tp^Ք}#{8[va$qUo+*L׮];|UCCaaiBCCtRx(`JKKo544444,7ar9< =VO5ߟH$$$x˕JB˞-O1Jjr^r˒¼C5ʚhdG4K[3g7ѷoߏ?xƌIƅ$E8HؚhYMWXO>9s&) Vs/2RS$)… FIT"s=z+Svڵk8qBqSO=uQ a*&Ή'ao6+䢲{&LpT.\%99/ƌs؋/&%%Z b9rWI~=zHHH 5.)޽{/[5ɉL/^L(?iӦ*nݺQ'6m‰ٳIoӦʕ+:޲(꟫nʟ$IWCCC*P])m'O%pDCd>^ 5jԵk3gpnC¸Svv6 \~ q@K.e|J.ja Oy(C¦*nVM _z5[]Ucǎ%&Y޹|K;"Jh@56k ?>S<|ШV(ͻxc:/th2_-ѫW/~;vxy WWW??-[GDD F榒U{*U$=jԨ{B0BZ )]V'DfKJջb2ٳg 4 `,{nݺݻ$mذ!<Aqbx0mۦjQõԃ ֤Ą}o߾_HiӦ47DdŊQ=z4|OU7#J]vATV;wƸ7i҄0B(npUx*y@-_"êUN:ec Ǐ74 "[kDH`#y14mn.U]" ]H=33S͚(|Unk&X}*3qKc۵kV+[kw :*>}gzFШ+tIIIAAAzG^ ((,/Z/kׂz:v"ɥ~原nYnciY (8<<>kKտaKFt_zbpUNCC?nVVu``ڀ"]]]! ´4r瘷Dy.Q{r=qsE<@^^ kt ʂ"eddPo8''G-q R޹:On[,q(ɝIjnnny{Apvv&/ݝ{Omzzc9wlԮ=QmD,ŋR^tdKq.ܹsg=)nsŊ<فR~G,'o&j܁Y6|T/nÆ ={,{;vx#~rr%KBCC{СC-J]~+3Þ,}[br9^xۛ|GƢpa%c8uKc._xb 0`*>S/¯Z8qꩧj֬IvƱ$(#5:zh˖-vJ4,5F\|Eqhcǎ}Wtr_~JJJ.S{W_*{C7E=z4Y@i(o):M9[jwߑ<&4i2Yp!Ń2e eϳ.HNҼQ#b(oիt ` ,ƍtxX:u86l`x$NL©Ǡ>cw-ױ2B.H)pԩpsη>p"a`;cJkC >E bjӉIv_q, lk`(Q'$~6m`ܹGB3aVHڵkE<2B`` uBͣqqq)'VPEeA9'OLo1j$.۷o_n]8%(ĉ?w}(B9Y ]jՂbG|rn;K?C}٬Y3|8D(0Ku hH: qڵk[ncDǍix3<8Ֆ< ƩvڠQWc y'T'.[2k؊<%+ 3J﷡4Iqt}={gN 9{^zj6k6or/<)ZҒIhlK}6XXd^.EV5 )^(*.а0L&M4x"@ގt\ .G7`R! *Lmy C*Jq!uxH% 0a5L&@IqҼ+0v!!!o6* D ĉ׮]ÚEi!A|xTll, (ݴi%E"w4G J-Squ;ԫ Jj% =YrP]BeBZƍSʼh ,dB ,K=Cw%mFY:%R/U-aO0%R.)Pc*'ؽ{79R6,,XШQ#r8OgGLx^hfU"(sK-?ѵٷ W^ $ev4]Z = xʸǏz>}{ٺu+*~'5liPS6۴dUgi]e%ְRQٸ{fe=t`2 Sa@ X\A$*>v}!$̝?bR{\LŋazNnw?pLz?~E>\;x`ŀ8o v0\i&I;gc@`=u/Dq 1\kRFx(CDž[_B nUW%aH P&%bЩpO ̟je^z@%va\.ZsiγwAUS+<_~ c8R(XhC*MHVow".K.!"]_ 70B¦yPÇ"$\gަ;s nٸ bS{]sw-I̙3ܝ;dPj,!?9}{Y~ysō9s3.hjwHuϣi37mX;ᔵs"&EV`ޮmߡkhhX 3c0PꄾEfad9 Tm5]vd"ի;C0!7G˜B0S>f:IAKw؄CFiN!X1%anK^8. vˎfz`͛7  MoRkSRRe J"xJ5K/j**UDvؠXE+.h߾}Muōwޝtsk9NL)'mڻe^6::&34 Q'm„ T~ħ%!CR9m<;*RS~R\^7eK*Dj6m'::;yd"_#Gwy_1_g1/m{nwe-j[{7W Cr|=VQ=32{f1Vvp9J^}-(y$T6ye:G@BqTjX,|9|pubPc#$&&R PTTYh ~Z5`l/^#n_w@}Qאlq͕[HprQbU!0M%D:1Sڛ.@ީ?4o pL=?ժj;j{ܷǧ R*f)" 4 }cB߿^]\ݢ^]=쟜RkhhTJgȰ؆wG; NY >>>wJ%}1ޫ}^2|| 5hVVvT=Gŝt!mpuj {f$flL6~^운윝]o7 n"‚| l]bU?VVVe3khh}K@)GW=VV%_kxtuV8R< `̼rEO0аJaFTTTihhhhhhT6h A󮆆yWCCCCCrмa9hа4jhhhhhXw544444,ͻ] A󮆆yWCCCCCrEGGlmmׯ7и%nAgΜqmLLL``/.Xy!7?=ɶ݂wwwH>>!!bQ|x?o?-6qU%1~rddX WR9_nyRi<] w<OBǍ\]v 0 39;,((ؤi󨨣N33N!"]\\ F4k"11TEEs>w^zu۸a=g,.!f͚oݺAÆ/]ػw7 ٸ'ixzyܹ# W\yrS?}Dd oٴVPS.Ղ?qUQp)PHJJرcUBCC`*t~m,3<-͙3gڵ-[,{f4QĐ!C[ʕ {yzZ[ՀZPwKHD8"GGǤĤ/ɭ{f77niRRbaIR;sdР!;wB77BI$nN]+}&ttLtPP0^B`dO+.aַF5CnnnӦMkԨQ98{Ѩc%R#muqm~?7Q.koo9s-cVAtrrnժ5ԽǦ}=\]ݚ5oof]]ܐua["Cԩ[z⌉(-ɯA.1 2ҥKÇ& ɓG0p6I^z ao}:kNN99?S'5I}_EHNNאiiivccclll&Kxz{{ߵ)))W^%PNϿpႧ{E~F'#K/4y?/dG;u"J/G=DݖR&S #Pγo!!15\EsvvAoа-;K#>gի9YA!κV DXh6m .'7;w߿^o~F %%%eggo߾0#GF A:::B׮]KLLWZ5fHa saZ$5kAoeeW_deeYO@ 6lp)*K\bsԫWo~}{ 5U8{[`rKr*?kպX-J,;hD+Z>H1vXlY߾}ӧd)СCYLsSѧA*C#ÇGDD'ND_6i}'xB]K4^z͚5ۿ?\~}"?jdVO>M^@ԁLjZ2Es|ٷ(i;;|OOGGG"sVREgϞYdgeK]֭rϓШW ؼykrrrV\Ed@NǏ sܺuk N81p7bORCI@#Fرc1@#TԪU}a\֑#Gs93f dOFZСH fʀ KOOW]bp4_|ʉ:?;e#'Oۯ_;wB"?Fg\!=zXp!=VɏLrFAOgHHq4~+ @-J }8hWtN:C$?ֹs[1x0upW O8򛙙խ[^K޽']>uҭ[A1w54*ջ8#2:uO>SOmذALJJpy0!3XH]٨Q#uɓ'#5”ydgϞC.H#qL$f`bױc`Sضm^¢Ep=,ϝ;O#mu&PX9z5ärk̚5kȅ{~݋AJG S(ku(;n_FEz ` {{{/Tj܆D8ka5!@MN鏞fRaN'1ɭ[fddxxxJ2ƍḩ"Rb׏d;+++.޽;!Eii`ꊋP|*M"Ĺ"!4iS h3yU] "Q $=c nP7edzz:djVFڢD+I?}4 /\z`#$RD`A3_N=$oNEEG 0'Q#ks0ɢ!!!8|GG%K9ضm[hիAy9UF W .]ܹ3{ɑ(6yQ%}͟?_-{G yRQ~}Zaj#, f9RGyDBWTA8O0|DɌ33R)]Y/5wM/GX54=*мyǫ>k^ &>c*P@0!>BC~}=+jt!JTHR LN,#L/_2hhhhhh<,0e}4444444 tQ JE||Gy"GEEyyy_rc^Ujhݿ_nN8%>|8G%&TPPгg}![Iٳiiieh0`G}+ϛ7 |I6mU544~ԒGU]v* w޶mVu)JN UmIpIE<j?uv\#V> 7M7n%}co]2~  \׭[iR@j'.pBVVԛI*< _~8:<}T9^GV$PXXΚ>u:]v=|>}?N j=44cm… ͗0=qs>~q}cOSSSz)r#0q(@BaV#2ɓ'odQq;@III)))Xƃ"g߿ݺu8гgOc!JڨSNK.x"[^|9o>I߸qf͚K,!¤I222g^L54444 ,ڵkϝ;wh\XcǎP/gkk{ܹH}e 4u> wttɉE@WU̢"*%miӦ4˗I2P045nwīk.33|ن Z0=9|pHY)LXX؉':uBA;m4ggg"իwQGAаU] w_ȑ#焓GGGHV#Ԫ*B Q#8lJڔ-ƽ"??_M@X8qqq*77]oLJJW^jEAffQhHAT\ɐ;Āw]\\,cQ;wvrrb`Jp}N߉襁$.U[zqHHH-#TgϞ&MXrUѥK%>b9L=<<,)99b9L ܊)ϩ_˼d5jܹի/֭[jժe>ɅD.,,l۶ܹsqaܠA֯_-- }ill,ǡL77;ӸH갰0'- !q :駟iXӧO'`kk=zrJ%֍E[vmFF&)!!g]p!}I,ǻǒt a+įbXo!\EK~*F%3ݼy3~9aJ\_yZuBկ_§rZN:_5wڵkW70 ~/[ LU`yyya c[h- yC4o޼l>l0$NөSyXԩp$$ m؊%ܧOdkqqdrqqQvI. 9fBzj%~@eTAia&f7pS\dB1Hrƽ 1c<6R 0GÇ`\KEnίbvRx !aÆmڴ زe 'Ш RKJJݻc0#˗/B^B.} x@^ 888z޾}A?kkX{m׮"b oXAvyÆ Br9\.ϝ; &pvVߖElll) <0n/]O;+((?>O8A7BX@TVBb|qpww ht|v8xG"##12+i>t}.]^;LLܩwxǺB6:ر{T z{{W5k}}={6D:B%,SQvy/ƌI&Щ.G@σ 8 ]m/kƩQFqH *@C]v-8pIƥZ3źqpV|I,n)|\_=3C򛮻)/gJ/^x1Fb" ^x!<<|j;7O/C3 ;c1_)kKQ a;SdݡR4#sݹYpVD=t =v-c{͗Ұ LV~alxuP[㴰Re&NhQ!FPFvF:Tm kɅ* Tq_>/2ރ >W_OR_5*[[ 3gLƺd п ȴ_?(ڿټH/rEhee5uT2dvߋ/hAd̘1Ƒ^z͟?8.xsƽ+ޖy%RSSKQ%vE%54~p-y]a p-￷Lm&gf|*3hH42,׮].\ggWmێ-=fL j9fejkg7-#pp9virLKOO-!z ozEEEiiixp{{{$oꙙWcSj\ת 5Dp^eB]z{;G:eqqbQPؾВ{aY\,MtJ*,` 5*e\zU~vzUzEFFFpp0ݡ rϸp傕+Z,G?S̼.[2bMtXsdxA8|%Ja]c֪mRRŋ-ߧح(8; ,:tp7n0 "⇏[l9|BB/qPa}Q.]o޼ںM6g4hкuH?> 11/xm۶}FլYsǎ$sk׮q>]ٳǔ?@u8x`6jȐ!-ZPQ0h%ĩZԓU]8)D[^8x֭[iƍ+;vm۶5~+Z2}{l*׸O!)͒ Z@("YfMFq$ :kaBTƆY,rl\<]ג6«2NVp  A9.8hT/5k;00߇5k}9w ҷow}wڴidttѣGU/F/P#LHKUaaaȢN:'OZ9sիB3f̙3'>>^lll̝;k׮~UC}=zUjNxhK,ۅZj5r %N<… qqqZ[~9Hܻwo~~>β~zgggҕ\]]ܾ}+VMڦӧp=+"йH㰜}VE!#5{ Km'y˅p"dЁbzZ1̺ؒ% '!&uUB]O:dS6BV9jXp” 8Ct"L;w茉t===բCbDpك!` ɥ`v%W}R P,UjW]Vn,7׫i^t 1DW#L&m71m߾=z9ަMvhh4{C%$$bnjӣG(?ݼzj.|Yq,Xj*HT^B|$WY ?͕b4N !* !NK.l&D8!%-5,{h8ݺuSoAk֬qAg&MBBB...N:J/AAA\G/z- +BP8l0 v$0dE'''Ԁ ɸ{&GycːwcX4_3a42& $Pe׺uk>U]L2ڵkT): sE* u qmb J+p~ tŋH;zzz6inصkW˖-!`c(Xpϊg UΝ;w ;xF/[,GnFȲd3 W^߈o,nF{z݌/|СۗR~ .`?Ij㭘h;u塆 :tpss89%;V%\R)g]o߾G#3-Ds!OKۼys hk֬iӦ|~J'Zz5a„ b,הfu-V;WN+&79F*9l;H?b$ŢܤAe4ؚwAz)hr޼y 4V@aJmp Aw:99a8C݅ r9:kcl222vh"D"Яj'sW^%Z- Txx8dѢerB@zzzΝ>LR$㯿πb=`PAqZEJff&N UKdP3~X<%--,Hw>Q.\Jm⺡}Q>!cv81y.lr1cq[?B{ L ǡITU2n<9Ͱu3zTºBS2ЛȶZ[UeFj ҷPc*v)y#9rVt!y/pf< E*020 0.ol {mР?% $ IQ3gΠA `x Wa0zknJ,YƽcڵʤL'e;i$L0t&-..2 ~JĠbjܢp *^5 h"xG*4H\Oӻ裏KVz'>ZݥKS<}Ahp3z@K.uo{Adxx|)ZpMt\j\0<\29!bh%h [B9BPij-v}m勐iwmM ?y<.i>@eʷ3<<-Ů墦|F @((7;DZSKy=.&pqɍ_?T7V|ֽ{w3g4OMK/^֭>>>111jA cZA5O> 4ԪX%qL ͛|S\@%gTȯ~Ç)\~ ZH%U5: --] \F|&6j^1pPMŬ)A $dD}o߾ kI fe{:<~+3WQT2ZE-bQ ^~ذa/{\-_~8'NxOjh=w\O4ߩ%򰅰VffX2S{aOE}JY7Pf4sJZu֕YvYnRk݌LMA }9GV 33RD֯qMG諭ۻw/еkR3|rJ''6m ˳\z533aäо}{ו+WG ?~x=o2N8QV-GIc A;::b77&ccc{>|8S~65>}"{*?W&^J!???$$c>}֬Yӯ_/,[l5LhѢDi~+C7իג%K6]bܹs'O9?;utر R~zݷoN ?%XB#,;K n!ybVHsvCrr KŢXerP{NV99Z.2aP(!$_vserrV&XQwܙ\pjLIIQ TmܸO=TPPؠA#M4ʤ6j Glԑk׮ M65 E59==\04=i֩Sz&G_$) [ߏ))>)ٷoO<ѹsg5yFC^(k$-?<9wp >[nM tppmֶm;v}:a(8j} I\دrѻ-zK% FDDЪǏ~qq1݄o ^]Ny7NrGS%,rNrR\79\6nBTƚ7-xSz2m-#2tPzj!/o.hck.BDp,SWFcP0'3$$㏛?s j_u֭;bDvv6+u8p :֭\$ b828q ;888**CUq}ИX& GBB6>lذ{RW8%$5++F䢻l*U q5o[OM꩒WTZ1ٺxbK5a6%͛7k$0`=݌1f̘Ie?h|zU +F5z9QP $J%kNSh [ȑM_o3Vzt_"@c %w\IT$R_j%qs[N*!OY,qqqgnRRyݸq6Me'pj Kfh(V.j݌梹D^ĺ5w ?]?s+^bg_^Jީu"dU7r ibb"eUޠ>Jܢ4u3,I4hՂ+9u3Epܩpd Ǣ|Pׯ__nĕ+Wp*vQU۫hҨoU[!Ennnvu3N_Rk! -- 1Mm[,n ’f@1"Fq+75 boyD:nV#""psF:w^.Ϻ_~QΜ93gΜ?OS>o޼1cƨ~Awi'N,uBKUtlCW8+q6ʽ BtXiO99g +5d2(9쿙X97Xd.MBu^SypN[\\nWkP_uw?vEU5ʢw݀V\9ps0ҥK2>tPhhݻΞ=_Ю<==GbŊtRNHH ?~_|-[9?wRH%HPB* ꪫso+VIDz/B%!B y>CK}_ϼys̝9s3vcǎ#G=zT|w=1鈴OӿE&G:㎮lÌ؁#b,>VvF;xJ׍^ z )D݈6(gVr TUF=??]>>t555u Ti+%uF7'O|[johxǏڵ+Xm޼y 6TWW0zjgg眜ݞ={O?488(SOZ* /f#%*sLYDz.vuńͣvJ!f})w2 h Cِ;6f5V*:2GT-ޭUSСCB۰G3S=ljjҳWPJ"Woص[k,J݄ 7oANNNW^?>{zz ͸믿>}4mhhhdd*FkeeݷW^"p/w}G|9|^3%k_/ڑ߇\gGNxl/pږ7O:G_ );l>[ōcID/6kۇ%s֡@^hrHE㾾⎧OtLKrcCeOM» 7x|ٽ;Zd _B(؀֯_/Bk.\ 'vc!maaڴitnn(=fff 4looY*!Z50*҃)J[k\[ÙM_m il[Yծbu#d4Un| [d C%hZ52\vV#bcb=7ot3hc⚒rLU* TkzOE }i^&6S ]UrærA4eHqDhJ#-mpis\-k~¡)=}[]-9ϵm;qWb4xhffƠC0BܧO_:T+?:(iRОtU[TaITmB&r6jFfh uiO~3(\*mg] fLl+ 63tsk/Xl\:۷oŋݑ;Ӧ\F˨ mJ+b$̯*]]>MQU]e^F$fϻmڴ)**у9MyYYaem Z6 !233 $"",> *zKQ&@'[D2)+JFh7Ue3 崼c8 T)ZFZ;)n*W'eMcj+++K#2|LMiX.Q(OE~~8ܽ{:%:u[3 µkJJJ:udl,a'PT%Uo&d٨p \Lr6J +[l]UUU^.6):EnVV֔)eMsCLLL޽<[:w{؟|4I{7FdԿ]5֭[ }m۶MNN1/#G411A&fNdd1c@]vw{1ٳg=<<>Kb 4}6ې!C)7hž2r`Ul:}M׉V~7eٔք5(a‡9 -MglۣsRl =Mȧ^u dvllo'\rlƂ+^fkݽ44RvzrOXu(P:w|!D0J䀉BrZjի N5jO?$6,::tƍSLDWvmРAH߿>tش4L/sNe&[lԫ[h;s/Ӱ37&*!mY1- ٨Ik8 1|)H+toHE~5kq~~>AuѣӧOoJGgΜ)'%%eggWWWo۶ 8O.]0`sawuurhnuw^7 bΜ9clujT>/2TXXVLS#_{(h )Gڵkʼqf)K.LMMʮqSN/'Ba`b;;;Zp9 .6gSw~# "r9Bsf9fRXNg f)ŤO.W3V{,30L敽?C `R,_\2nܸ={`51bĈ_͛=}Q,1O?4 8o߾ٳg?~_wފ}ོ@TOz4c ,mXlmmʰm߾_333[X:u4uT~\tL4ݧOׯ?Rkw>xjûR3+bp)))XI{YdҥK: +2J}Ge.㶈+tyb1zhS lm޼./_| JI1$$)22{Æ stb@:444֭[>\Ir o2{JJ.['͚ng 8ٓ%M0#Cu }hsDug=pB~v =oӦMb>|K?Dk%XtN2CZ+h ٶm[aPCJ*"76:tP<h=zhnnFEEAP JL~dh_ m†cgΜFP7B:p `Do1FqsshR̀~ ֿ}ȩ9~wW_AHyMŋE:N`H|bsO?(h"jW?ixE$hу? HKHFEAh\ Y ExgϞPڂgWzy(gP@'|ISQr (倀5((T\C+* 5"66ڵkb.&&*2Aq!W Qt ?BJO?d8q`zG "DY>rEV- L4CBb 5!8ppmfUL 4 s惖 V_ V  _>S@ jذa!˖-]WppY\!#*EHHH ҥ۷/rШ`>ū5MFۣu .DC0t:n~@9ą^xA|EO֑ױc+ ,@+h}ps(2 @ϯㇸ9ۣFҿ+03͐ShӦMݑAuFBҢJR[}EA2 j,[ƻ`Aꓖ b͏ضS9`򄴺a]2 "mcn\5}tao/CbR:GK_@* @&x饗w0d'œ'OnfKQ{62ВLBe`$;NNsVd}T$I|{ :tNe"0 V 7a4KMgyyy^^^fsLnn9 !d\Er8l,%f8fŞ={:tлw:VX ?^=vҌߗXRRw PĵիWCM{YrA8+9cʨLF֨x!k./RCQvuU9::nذA47UUU۷wssEqNlf3V̊#FDEEyyy8qi#G455E&ܹs&L8t䯿h"]rg}Axnݺϰ0kYYYlllLL TO?^x뭷6mڤg?C06w#l계/X|`P%6,8sd!ʉߌul›ϙW}Nb۹cl"e˧MgL(Q~f aStXAGU}XG<_;uTeիsE:tqٳ(A7o O>׉'#1i$$^?o]b۶mWKJJb"---++ 57kĹs`ͅ?'O zǺ*Vlofr~0ա򢆟~ ,(Vغu={ٳ^~=fNPP"{reo-#Of"wwև,ucc.Rڳ!*OoOunQ͘-aɦ-* ;sϽ["""?.D'>};XP@-//^XX޽{~aCw ׯ_Dž(  + {d:%ȑ#/_ l1n;*~dҥ;$ݻwCbu~7HHλƤ2h="oy\;mênvbͅ2D!5z1 KS ,{1 `мP8hP36 uhsb!kXT.1L#2[7hHh>Shddf&>tر<$P慐ն1X@6 a QX}p F~HHv7o7ۛddd ޅɓeee5$ 1|`G2M ܫSNaСCO>İa꯴8;ZT?Bt$|u܊aee~gLf`*A͐jFc H/b TTWxyz5*)>fBh 9o<_EpQQ_{5СCW777)((H3Q\\ڶm[hF%~~~\h>QyR 6҅[`8"aTUU!&rtISM 3S$8Z7 gΜxpBeWU&8RZFW"Ʉ%čܾRTdKYO~47OIIyS>,\޲5FxWJQ׻7jb&g$LMO ~J| ݆يoAǮY}wBq%-D;NL[/eK3!#77wΝ!<9ѱߌNÝ:uҴ)oBQOX/褜j*r6*fiѢlVs8@mCh ec#mh¬E4I]:@;߾}7 DWG+Wڵk'Lp9#G8;;]v kӞ={F{9;>}zԩG}VVV߿ʕ+/8q\///휴4|=3Ĝ?CF_~eEƿf\fy|8|m=̧ء!I}T{|_|]v1hJQ)Сc߾}ר^zEGG#3((??O6mƍSN1$jOOOƂ{k.(#GܶmСC H~fI$jFӾzsvDH5/sN%ώ^cYn.31M6Dd跘`SlR*qѰ 5SU9993:VP(--:sU>aEVRoNLLχL t455,h*TA6++ D+\=!-vV5fs7yyy3gԳ o2sHVf3qLQupWVw`lުsal.Չ ى-81hv}s5s`,mEC7!?sL߾}RPPгg#G`ѹs2!׋@PΎ?~ƍɓ'[n=zݺu ¾7 ^(xڄB |g7Xa!k*Ǐ߲e Q$nij~ĉPg̘I4hVP,c OŅ^0 F= ]Toذիx֠LzC<;/tcQO|;[b]̻)̵ِ7Y0G. #zc+(sfbg/y80odQl9v)Sg.^xڵ qD8oo;wzxxt>䓻vRrܹ06rPѣ%K*!Ç^رg"xЊ* U3wUKi~9Խ0s7o()}b .ħVIc>1 Wj✙.Œ(<<ѢQ$Y QQ1#Agee%Sxہvknn ^qB X222CڈDGGG;kNxg~m;v ک 4F&&fb̝;w͚5LpgIIIZZEii˗EGG۷kƃX\\P[RSSsu{O\};~G>"A7M7CF˩.mH>il +4,RLt#o%hJؤIRSSձ-,,|||N:5{u͙3 bRzꘘ*oExӧO~[/6GyDϽ13mTC+- -oFd\d&e:,\iz:2>Odkt)-mOWѪ3H2UzՊޡw1XɠӍ7RRsҹsgo`TC ]bj%LN^. #Dŕf%q$//ֶsAXw_X=4sv~mNNN``ѣZ:nΚ5ܼNDtv%gooTA EݻQ{gCkh۶f Z@?<Ǐ:u'\\\tA =ͥm|'{#w[A Q"☘YӼqFSSSkkkFaakO` @#^G !23g$IMM}6mt_~ իWxƌ>C !!|zj333+++CCCQÁ@:53#:m^ֲp*|&{(Y#rc 6'[*W44Qá6!EF,wMylT3SFFFU }M3od/(bs300|ֱcGp |ͽ{: Bnsܹs<|L\{nQ8W 5:@.ob*]2;즪m{F+Mjxk8ɮ-$ҕZ{1}e\cn5V Qs ],]t? ӧO׻/rȌ3/--߿zE)Sb"}!h(nРA}3P?(0uMlMäD$u F“b/PyO0QRDC/HF}g_Pv<9Flnq:;Ğߒ)/Hkĉ!!!X<<<i=-- 8%>VѣGo߾}ɒ%tϋG?~ ϑjR]5ĩ@CȁR Cu(3>1rHu`~ bz SiPڴпghE4"e4Ov'u݊s_hQ}>U/Fo\:uUWٽ{wFFƬY̢-Z!VIrss3ghCǏݱcBg[1d6aԤCwA1o-֨0مˆ^GˡWTT>|xܹv>}:I5Mk-[L2%11Qy'Ν;:l+B5_>Q 5XeQFed/ o}w?*++eQÐ?7^ <_5KMX>@- 8Wbgggiii``УGu˗>ĉ 91^—-(P@Awm}5R-Ѫ$ݜ֋V1'z t~0##CNIIIϟ755_*t]NG; }xaA Z44'"qJtzp%MO̟NqOI$= 7!Q4J}P@ #Lyy9h~***ԇ J Yi\{YYnj0wSiJ4]UU%WZZQ2WNMk9ͯ?:I\J@QErm}7z5YUR@_ҾKKKOOI&7dE?ȧZq[ӧO2e (PTUOꫯԩS;vP ۷GRi]WF&С*_pu%%%} .D7;l2/ зoN]qUAAo9o޼.]fܱx{{w?*@'^`>BMؼy3j߾EEmₛ3qvU3=3_!:@0U@M@wZYY>^x=z8w\^^ѣO>@6+W UHpgNNڵpǡɻW^9ٳgm`kВ8Y 899͝;?޸q#:<<'|QGG3g΀0ȯOm@@]q"##?c__ߛ7o3NB[AAA?qA8tDdܷ޽{߿Ν;lܙ[na &u_Qo߾ ܽ_|7SۿDîwIl+d]vABxɌ8]:}1-,ѣ@#nj }cO?4($9|02..gϞO>G}-Y3>Af͡ $_~`,^{֭677WK᧱c4 %(Y~@`9s@/Y жƦSNݻwo@E43g=z4;;"XӅ}lH$ |ׯ߰aWHu9鷚׮]8qHLcHo۶mlwuyvvv(!M6ի'Oį{=r00Q}PUߣT@~`.ޙl'11:0`{ƍzeff| ן111 NQ}W/S88vI(uM\iA ep5k0tr\8ydQʊ+/_pi*^ТfP^毿k.~EHC d cbRSS1qO `XXX+U?G}=F[ ( Q={<ڷo_uaRA&$ӧo߾s3O{C L޹s'$ *Pja= ay׈Z,--'LP-<͟ аw q ́S5+BN?~_K/Yofֻv z6D,ꫯj_lxTR H*K3fJ]wiY.qD_*@U,}b e í]vCfRWa '|ԋ:QC   <^^^ziZ+uDjToP-<`|71imJBLQ37=)*pwAʕ+rm#6c>#F$&&}C9iee;@FAE߿pp0ouqq9r$_X_Q'x{WXnnW_}a3qqq:sL[[[67UeDoa(/RD7@ F3 رcH;wl=|p.]@HH~Gϰ0/~ǠUϟcڻw]v+::| >x ~1cՆDFFW7oq֣G:&&{wu(PjӦMH_y6+,8eD!D≬vzh(P@z`ԈߨzjŊ (//1.] CC߽vH_aH+.ӧ֭[}||&Ob6@Cq aܹs5QZf? z Ř1 Dz#Q22L (P煑C>ﻹACEB_h5*%%Kikk * dԩӝ;w܆zp TѣGSKI)tֹ_ >{7w\4-6섹j|"'"d.D2uD 0ejYT+Ny|Ib?>ڛ<(_5KLϞ=q:aaa"uvMVUnq{:F(P@FuB*H)(PύyW>lџ )))ƸK*..˫sKsOFylh%(P@:o i׮ݮ]P;wBuuu_UEENXtJoOeà 4Fs$kttO+-,,UAoz)TG͙3gǏG1y7&M-ݻ.?>>Q_|Q_nݺ{GDy TVVFuݻcD]v3g[uFvdz#FٳJ01!&AKhd۷o0`]СClj'kND1>VT/_ љ$k Yd (?^j /nݺEGGggg|bbbRRҧ~گ_?p^\\KIOO`q;w BC/r^@ *5N2ƍA~~~(&5;@cYYYoqGQR] 22 x… C||C~{CŨT2%%e͘˖-;s{nݺz( Z"ݳǪwA}}}Qmrr2z>Oڵk^{M΍{(L=wDAѱcGP"`2S&@.]ٳtlݺdРAE/@, Pg%"4?}ѣ"D3\@UUAghߣ+m\GZto#(Mn/.\TUU Л" 9//Ϟ1c@LA#GD%hp:~^nU;;2kw;vM9|9& jff&QS 2,.CFFdPrJpp0(+5՗C/AD&$$@((2gEEbE# L >,ZܡCOO}hR6W 7= ?rœ%o߾۶m]XꔲkDDkյ@oٳvq?!J"n(h2 AJͻx;Olٲ%&&F"8xxi&F͛X4ݵ;Dm 'Oz*?Cd6lغu@駟\\\7B@UQQQX cJqa= C;z(rf̘O>2sL:P`M9aT]hf:@_"祗^"VF%w?jVԩSY'˗/iڛՈ#@}JY&AF 'JuXݣVpY%.DĠH|j6$gCVLS3πuReŊVVV`8!㑇lggJVUq XNXLadɒ%PiخZ r9r^}o@'M(۲` &}O80|yG-|dߝ)A>)8XܸJ(h ]/D@qDFFlll@{`,>YO4˖-ʰvZJhLlmmݷo_Ǎ"l! tTH j4(=F)&> Ss{PM6999{FF8 VϚG,l,!zH><dhѨ$ Κ5ɤ;ؿXZ#TRajahM"1``HHK?>gd8pR ,oٞ{9oEE5qJkH`DŁqХ6} D. ҟ慔Bܺ 4]'SelnC6DjSMc[Aдi4X4Mj"ѡC)ٯ .\/^{9&&Ƣ9"͛7GmjjzwdZ4$*/b|bvzrOX?탂ơ(33SʠqJڄ0ZqqqibAt [^An.Z;B_P*~wϞ=i˖-ׯ_733:uȌu֨Q9vڌ HoMxzHIǍĩ{fHT!{"m`&$%%577CJIדҵbgfjiz:tkCq=|0^(jr r##k}MWwdHBϛjF䚞y@l׮]񓟟$8wwYfhϜ9?7>ܿP9x{VVVN<922&MtԩiӦAypjqQ4Jƌs#G0kA {l͚5O!UtC̀$~)O(PEtb" &6'ʂ*zۚonn.I `F8n=zI$<3?>R/(vmmGa:,Q:?Š"*Ա{jw,hڶm W]`5j`oʕ+"b>*`zEE.\x^~e///0ȵcǎ?!ج_ uVAlu'''\2pFGG[cߎAtRMHH@W1@ R<5ZcŊ:1f%DyASB$[q>-- iKKKBQTL +++{A նz,PC&UTLS+~Y8N M$Sr$5AS#u @d D : %Tԁ`y,!w~[ 14Ԁ (.@ygh-[:bKMNQ;`DZ &:ҹ˙͝;)4޽{ D~alqk>} ᪴B<޽;gb)LDCB 6l2eO?3HxW4΀twލ֯]oƍ˥0۶m[|;#ۢjH~UX/&ԋJn(eȐ!)1b_cbb6mOA Sȑ#A_}U}wY\۟|CWBID뙮 J%LctѰ0vBf8@t)'{eF2?\ Z13&22 T1&sqvvFb٥7arrrp 2GAQ 7WhX,.Bު_.\عsgUXq0(tù|8mt| rtJ=0'JEJ x=zXjSO=0s̋/ [VVֳgO???軿:B& N2fOD݈ @M%Dt!2w06 @R}Xw7c=^AFUue'ı~SSSDd/ K18$-b׋ߥKu^m`LWP4O _ӧOxxy0W\9m4os:;$@;q?"yc6UDbAt7cٵ>bboݵB̋=y Xo@HfzDx҃{UFR;S2չV*,X^^.=VTT@0%S'rU,y@"mDDĸq֮]+|ݠ )㙜B& z\5LNvÅUR!BeԁZeݍ+L:. 3.to#)EZ=ξ;&}g0p;;;yVς A=GoA)F~ o׮w$^~e͟4q*ނa/6 3~!Юtu Muڄ&~?Mi= K=Ry:Ԭ B⭶&rrrX׆8⁽EW&|XȚkņljƈ$r0B-i9{M&Y[7lm>^f+Aqq4q6lOJLJJ7Gs|pɳtTR%DQ4j JA-ZOsRMեU.jBHtvRQ꜄NHH߿VVVbbb~Vf`"VVVݻҥK觩ixx8>{q$-Z-h}+FPDӀINNN[0d*oI9Ð ȪsU@Cwtq RпOL ]ѭݑ|yPGtM̡9ݨsf<BZJ_җ5H/ړjZ$0ֵM׌kthTYGw1s̯իH|7Νw $@NNN1c8p=ݻw?~xYY8-66644Ts<\\\0d /n#N ;3f$$$,\$\+Bx`O_d H&M{gyXǎ¬>|#Dݻ!B uwww9RbŊT3donݺEiSlM;`+ۉr=q&ZKԇxyM'-|Rzm Q.4o᭣Z$[F*@)/R[7 N{{/S"e… Pp߿_$D-tQQpjnK/@.u9::PPBBxe˖/7n|z%"r\dt {)! ~a(kϞ=w)/Z?Ly֭(9O)8s͛7K-[K0ك !u!6SaL-DtǻLTwXcBNSl3\G[!/DGkp)M &$&&BZ8q'yX6l+ Whi(occӥK\4h(vҤIoF %;w^!*((>EHQKKKdUh7$9U `Xh]:K? )((({Ռ^{ɰ0<) _И՗x Hu`b} >T!HVJ+p#K{{Uc Xf[۾:jR?Xyo7esO~ʄ? Thvf5Ջ(J$Dfԩ Sd\Pg"rHHќnF,&i8wV L1ӧoڴIsgdd@\Ɂ**2ѣGIۣG\@$uuu% \vOۼѝ@렟ɾTrn:jXN?wAXDZܫD8HOIu$s|>$hZXVV& Udޞ4׀Dx GGGqJ|0tQQѝ;wFell )3(((==r۲e@K6 f jwD&gNpnXRф*WKZ /{dMB6jW^*O(7hEu2AƝwjS&dÃaP !uX##.]TN[A'q.,{@hm\Y |w-,:Q-EOǴon)h$ JKK[QMMMEEE ̧ҵHTٟw aFfhž%)VP$$!r[j[USd$<-aaa!^kFiyyUUU'_hxbBqdllܠUV[W^^]sss77JJK]]]pUpY@R`۷ĤEO#lnZ;2@]TQU tn : t THn9` ee9KKKZi(}U@W5*Z}pܜk Oߒڙ8::YYY$mo|bҶmm>Yf ,..tws'ɥԬ ?Ш$66*77/ KyyY似Q#GJsqq.((400trru+ޝ8qmwPѣK.\B ;w7sONЏҵMׇ|d1$p"0 KtP&HuVl5Yɒrdə h0[~p@uNpww(^^^W||lbcc*++r),(6"&6ۧæ NO?{6ֶ_‹ :hSgwS'Ok-yyy^OO;P)cNppp@bw.}򼼼Q$'kyfF]@ee_^^zϣn*((5J;Պ' C,=:0]Y^6rm:F-դV*s4\[t 7E :R*m@وփniWn]utp 1 Jht6 }t)5N[ړ'vƎФ* -T Abz5b'?|<*WSSѱȑhn݈oL"qzҵkA]'%^2p_mdfeXG@ɖWf>4gú鎗iEE 'nV:ʖ{cժU¯)7##0X699y׮]`tccR ,LycǎPzӳ%yY|:'f'6f:AvIh50DêX3ݮf.elؖXN\XV͙AeKrirDm0JLL lJC|pmm}}}%u^o,a0"tJ"bDzVo9%YdiӧΝ;-,,OBrttLHH#2A"⢲թNJJ:eccBCCuVÒ%Kn߾ A(ܡCd+:uo߾D=ݻw4ůX$#uQoܸСC20!4xzzVVVPH)GRC-"S 7ۂyجޕR&МnTHBZKR&He^"wk -0l3++ڵk5++??5Ӏu80fhW\0` E.\@oưa@N N+++.''gȐ! @Pm9燚 $ %\={6O:?66_~9mۆnA@Ϟ=d}]gH*A|On壪D`l1f_\w޼yH1U A|m-[M&ogu#lY;OصL;ћ"e S渿ڔ]>В %Ge=wf DNdy|YA+F\Xhv9K K̙3gF(ׯ_ի`jj b011ѣá1_Ǐ A={ܿ?c-=utr962{-O0>M[н;w`P>(z ~…uFD.CHH_W5!MS9o9^Ly..*Gwޓ'OzyyAv ЉfϠAv؁|Iw{Mz3&3{!=(:woR˔i2fdYʼ{v3?VE!R4w o;Dz43 \kkk-IDOqpe(==ӧoܸOP FFF$33322rYYYXn޼ 6>E@@իWWX4sss5]>ҥK!`M賈!K̸ӘzŦljdhhx"NݻwcZ1o znذSLT:l0^QQ_|E]?~֐š?M>Ws@wYB^ېյm)h0JIIѲY4S01U--ZHٳgʣ+Xf{ #@{n~H ՍhN]JX&:/_G? Λ7oӦMPm!\WrB L)ڒmeuA%Xw+UԽ /Ԥ1`gj.کu'AСCYL9Vjl*\0O"^xQ )2-ܻ_EUeUe8IR*ߵU"E1=GbdffSeXų(?01:KrłIt@N.&$ؗic}c#ud6)--Mu|||A@oƢE ׭[ۯ_?}uuϞ=cƌ)))O{u˗/|+W?^]ٳ0bpĂ6hxׯ/,,]n)F{v.|$6aTVVg#۴yDv8:tHOO\ >1W`kk+|,S,6Zj7F 3uȞM!&)Q7o9֔y+4= ڲ(VݔL(Q 񽲮)G2fceeeEu! JEx/hٲ%sȑ_Alݺ5Ȏ;p̙3]SRggg&ֈ#mۆihSN9]7'''WS)*y˯){pvR?ϳƆ Ə>x#)wLL̑#G@yyy0`z`bkkm~7ngNaX@a8 DMp$,+\ ʸ-3{Fz܃_q. 3plƲaqX-%jEq f}mu>LDuh333L@A$Sn߾ݬY3XQSX$PЪU{nNB'UTT`NýECf88_ Qm)jsٺu+$5k K .**&&&ׯxbϝ;zͨd׮]999FћM4H9ȏ%T(`|ֈ\ΒW*Ts*lrL5^\Na]ڷ@'W=ztSO}Abt =t1 4 > =X$qsss}䠠={tQ9#H}1X$lP+-MO/o%338[-0 #8;;T*&%%ZĘGhQ8.`ƺMR%:R[~}M}%|!6.t Dԋ̒Yܝ-W7^{GvJP4w5(.]xwKs΢]#s,A }IMW:,PlmMZ2^_b!}ttȑ#KKKE Tٲe˅ &L9SNK.a_ H'DDDqfffPà $~ZَŮ09+vLn|<&X$bړ -% Uv|=+o"oNT3 gIInzc|w$Lvd^ʹq`EVU2":K/&$*$ԩSk6!ʰOJWe.Ք] nWCeI5MoT̴ TSud&]V<MXbFf0.e!=ˆBS soQUUߵkWtȠpFэꍍ}x/UFFƥKٹgS2m^/krvvwG|O6TRe rp#7Y/e)N"$׋*<>};3do<$Zے\_3FqLl vVt¼:GJǻ72!ZGRhq MSՎWeooI &?ر NR0 Sp_egLU'N,*_A(Q?x Xa9  \ƍSRR0]6oF0ʱAlm@֭۰a p >MTo/z9z}}}wZŠC&***55uҤIF§b#8e˖0/śaK&J I TBT/)Dٴrvr5, ~ͭ3g̘] \+hܸqx/\n@Ǐnݺ:u̙_#[|s_!Aޠᐐ|Jy|J"] d oo!! N2ۧOZEǻ戈6DOd*y 7߅Hb '[1D%VjyqM.F%XubhGg[gچխƧIY  1G:{ls!CĸBזcuvzɱP],\~80_;ُ7N%:YS/i+V ["i :gyzȊc v圈ZG !H!xUR-kgȇmVM*Vh~ T-!4ќ׊;^O$s:z0/No6m\4339w^tȠk:Yī*))haa=;:\h`$&&K>_Wgv* ?A Y/D/Bq3a(q3tUOիn:dPt䋕,A=|),,z')#-7 %Kj|ݻڎCF5yС='R|q3ʛ)r|,.ݕ/nnwQQA-%Z[[㇪-UzЬY޽{?셩cF^Dī/JJJ dq3.^C1?WtLgq3(K y޵!]ָ=Mzfee)q3&rʕ٘tF Քy#GxUIIIڵUYYy 77zjɒ%yyygNHH@[}⋁:u|>~8oӦ EޥKLw=?իWۿ˖+V-;v,n2.%Y?TqlG37X; %WWנH߿{"'#cǎby_tv~˛G6` 5f%J&ZΛmN=/"'Es5 rv [4ɕfJ܌.HWīRTk֬Ȁ x!K!!!wZh1iҤ>PϞ= oP -1Ian7nlRRt0r-4q6@ t  G7<==A](f#ܖYYY 6inѣn͛9sCи xjy1MxJW ox0Fa N2%%(V ?~zBھWSf#i+^rMjM1G*" Uڵ{]s\("xf*gD^z Tk)XY04HK($(h,XP+%`hnpӸǷϤfVJpf-hF2T04,G( ~b+P)n}j* >R|,}Da\ qYD$˦ |#...7MZ&2*F 0#34N^H3jVUTWx{&&:9r*xu,z5Ao 111'Nِ6Nֆ=fro'%:dɴzɝd\A Е9>M$=0JĂ,lHFR*Jr/I{׋!MuneeKNF 79s&$$Dq3ǮsڍQxM"##o߾kdzy| ~nԄ7yO,= a5UoMݨ4i)))ߗ@˖-5gȊzӊׯCiI%%%iii-Z@!==*>>c_`lK.͛9r_ҥ ħ={UJKKѕ+W5233###7thÙ"GCь_'pEǎíu޼y7]FAg~:>aGv B`bpbLvU$}o4zᆱ?.v8A4jÉޖDw8nkDLWm7c\t=9N8Q6w99NldE9M 3]&R۴iӈ#\7n8h gBر/~7ƍW IS[_DUZ]-ĝ;wE___&6# uD`Ym0p@.zьmΝ0`;wN{' ߿&2C< <>;ww}0͙}fgx; 2`-_FSNW0}tuuցkm Ao~+c|Q,Dy8f~OOp$~[9I^tEjSՒK9ws۰ >RVJ  #jԩ(vժU!!!'NQbŧ݃Z5jTN~=j;vțBt!vA `e;\Ъ8 Z'k-,, sss'O8f̘e˖`91!} 0Dpreuu5z.tȄW4+9iֺFPPмylgwwZabCшq[qAopy? ;`ѭ=Rc\zQL=Bl٬ldqg"V |4srr~9Xmg  лkwl`` '^===A={Ĥ 6۷/l|DY'@+Θ}VĥBbJzh۶-$/%mq W^=tP>B \Ԛ5k sa[t  ibŊ~ۨkX1ųyݬb1I1L`$"t-~"F~g}ټyO>Q͛7o7S9T7STFOab{ڬ3W3^\ k;6rÜp~Վ{hxT!R]#@z@Z<BV ^A{o>{]5)0z/>ΝK@%{0P~s߿_+ҕ!jf`NԜ}Oy [z萹VZ/$D 9s@~ [OLB,$J+UMĪWBhU{V&_-CeM*r 5hiÁQ{{{ϟ?_N)P`L]M|&Q3Y/DE*@ VVVI+0:tㅪ{mjj MIcФ{QJ$.-\)z+>aB&eirpvv>EW.PSd\ɏJQ^ytȅ\dR*I#kB}!E~~TXP߽hWHhb|Myyyiii0M0f(a_ZZjʊl%rȒLƂwopd'y:= mE ^^.%YޠfÍ1)((0(][[[mgt^@FGIr\vGP:kƍAǕtTg=y$lFи̒~~~FHLK ]ގ,t7r@"eA[jٔ-논Kb諒7>&}rrrbccej1оӚTu$ׯ"""ܾ}Z0,,8ޱcڵk,qܪU+pGhE0.lȅhGժhٲ%(Y0WTUեT*DPOM9^󎷷7#j}sN:ݻj& gɒ%x?w}pznJ0D$&Xv|1P&}1&q%ٞu̖nӷ%{@U$Aԟn5b*]CU}߾}yyyqqq0VZ5k֬M6J_IN8NJJ֭:>>PD(--߿Ց#GO:|rVV{Ϝ9޳gf0:u ƯW &=x z~z `z}XJ#=uth z]+Eyy/?ܻw˗KSL=zG;wq`_bW2F6n$.FLiB Se.':EvmFR+(`4"Vr ^vj?}9},~  ;w\h\3 j$FXQQQiii䄆1M02ƍaC=_ܿ5kր?h"n@]؅҅sP9O~0m<0/ڋ/ ]E?,UXjp(\[{]6a((ӧ~;͚5;|5DSi m۶'UxhD"oIaaLʦhۙ݅HPV Q! ÉϽGr]U@*_OnMfffLL h;A+Vݻ7, HA7Yg=zt "y+uumyp삡D%Z{"0o3|p8޴iס_u{066V  TVV6c Y.]Zn]@@fO޽{q SСCn[V^mee=z7._Zw-wߨYՑ'փDäNfrٳ׮]ަM`ooog+~111'N8oǎf͚?Ox㰋=p1y'&fʫmÌ7G^V]$j#܉GuK.;r[D[HAp3D9*"A82[PPgϞYf|/+ɟݻ۶mA׹sg\lsXX$ZʠSN i.%R Yr!CPm0?> -x7##:LLݺuC4̻ Ԯ={RIXZ1pԩϜ9S| rҥm o%@!)R~$e+6^$eR*mQjv^q$|pb,sR9ӭ%5" a,Avvvک@jT1`Yqt =s LTbaa!\eN35CP c>i.PQQQbE^zرCBBvܩkfR3bY͌p_~y-ZغuaF5ollvt*v g̕|ZUGD̻ك܄c?"㢂ݓ/0aB*@I/&ul4|qγE4+  #Fll0MLL m---{b #O@7n܀=ztTTT||#AtK:-TURRれ*C3=x K{ن]j wFDJKKuI/l[𖖿q' «vLq|ܹh5yKH+!LyXM`rkI[L';&ݧoTch4y4wE m G `?L|Ap...U-QFYX<7D\83 =tD_';GPM'.p 4ъZYKL z!*R.ԥXezY=yzzc@?NDݼ y*m_MGH7t5CN7YT1gk`P>}֪c73F0Ftfh.BrBʨJRXQʥ6`wJAUaplڴI14ܹʋn@͠j7=*`2ݑūI>\VZRK7rhMؒm{jKwFru"KtLʔwrUJK Fݼ zKlijpEZ*\Ͽ1cR AE7C6vvꨇԩtAr3ޕBP:/ B)t Y+S'{A^`4_v !^թ˧(UW96u,\uAAA#Fі-[tcǎ2ӦMŋ 6ѣbyc5maǛWUbw$j"[,1(;Q's\I%ǫz70m# }ǭ{?&7UʖUeܷ~;eʔKTݻPׯ_``ٳg! |ML+ׯu떹9_WhѢ!C9r|ƌ/^Q&^ծ]\ҼysTiKk7||x_5 R;==}ѵ5>@[=O8u4y`;99~+~~ӧO~:t(Xy-[8p !!!k֬+q"g1LeW&`Ne_ ux2wm!.wĆ(἟嗸'v[\\{ٳg;;;WxU%%%`%Kܤ?qqqM6Ysuu ֭@Νo޼)x_0ƪUP Q w7GDA{m5v쌸mv~ĉ666`Ç:ܳg&5LFMVGy cyK# 9԰yM9[_mIYJԴeuT0a`ъ %_$Ɂu5>-y-߮$3Ɓԭ\֖QQQ1 FIIIG={ =}4xW)\{̚5 vڅ jQx*ѕ(ڶm}DsO4]##Л-dqC}1L`pL!]v=t/ rΜ9Smfkk`N,X 32j/.5 <+ΐ ܚtjaTMAGXoJTy 5!Q  W_}S[o+"]XC  Yf޼yPhp7ZP'N$ޠ{UUU*MN-|E~ʔ)aaa;v<I³>+ubஊ:dϨ,80d'a:lQ-ʚ#"ƋCC}U@+t%2 WՎc% TA6z{&^ZPU}d #Z/%ye_*++º-((꿨CʈR*Gd.Mx"Zy^ נUWWW*Si[[haķU[ i@=>x*GGCݸad16sTD+#Č䲒LB= ]P/|#B 0`)+^uCCqq3g0ꆹ_GL'A*==}РA#"*,\D(h+mJWejEѽմZ&H(v9}Cdwo˂~y瓒dj1ЦMfPOJ3*++&Mj$8~~~z\`bv%ל#ZIQZjy\DDDknϞ=`hVTTԡC{{˗/;Y=HS@wurÞHQZ:]EZ)b'ڮ\(wcW(utfjJr&/P* KDROz3/p_xlN8Xi^4R!7YTu, xUړKˊ >ߥvdnC@BB+d[[''',CرcgΜ1bDttѣGLW_߰a&cQb/3ad7'~Ñwx{n]|+͍HivLJT&]؞hAo5\uɼhߟ.\.=*hP_k=|<77w֭VVV _|ݻwx Z޽{/>|8ٳg{%/wӧ[h1gΜEڴiCsҥ`AԳnݺ/@A-:c's`lެ֭[|ɓ'о#L Tw}7l0(DEECn, |x$QDo!҈ǡ EqRӃU\nɍ6iҙ>lR)P<cO?q޿{``Ν;_upmNN{ws͟?߾}t͛7s>t钙vvvEEE~UUN@v v#V yYˈpYT Zpڵk0|}}5_)))л[֜y1ƶ+<"!0Á&Kygg2XS RU'8je61D Z6.WЄ*h`HLԍ7F`ez,8s·oȑ#WF% lLaڲUS^^^?^ ,bWᣬ,14Jth[Ć+9X0GX H#FhoPLVf^^^qq!2fu3a% Vo##Ku2 'NS~5RResuzWլ}qsMQ Tv KjR`[n +8//C?/1cFlll~~]+iz=<y$ꩧ 0AL@Xwz!W5^kFU-_|ZG͛.4yKRVY֕Iw!:⊲7ECU^Q uOc+8 tkff W|>mڃpڵ[hB'@0jU~ܹ>hȑ" 4KK#܃-[BNNNLLT7B/ fף桔'|}wLA#PMCHFDNhs%!p *%[Y/Ĝ+',Q/3ߎ 7BM}jMQмDWC)kA@j2c؍%VI?o*'-&ub;rXVg+S܆4Y*# .녔QY)ʝgs+}=_Πt#x.//O7yQ+ N֙w&ACՏ !="777 OiD!҆4|&ȮuB7̍ՅXu8OYEgSk}dG5r ]qq}t!nBv%ԺSD5UWR } ٙ^׭\NA'z䃴ң-)BUz!AdFf'd:,PϿwLM<n!x3Mee{PPn:dHHH(,,c>L[D@+U}0̛77++w^*ܻw+W .\>-fpxHmO%G5(}D^̋y{NU|fx7{I]+YF:TbSoC~:w#KJJnݺ{;veɒ%8>x)S4k֬bΝM!ZuرcȐ!{w=| VرcE@'O>}$7>w@;` +rk׮a|'pM0qffիW<A3`OOO6uTGGG}wqHd;ärhfvK ut( {R~پ|r0ѣG|}%hz///$|ӄcrr2)D0 r}gWZޥ-[.^Ӝ₆͠툈jN—qxl^{&H0+1z {)/XO?Ŷn:%%\iPOt%0$DݥkŸa=mΒa&)]qKonV'%Ilpj GMUeJ J2kdFttt_lل qKKˌ (QWHq =<<1[?~U8nѢHz/Y vNLL[VVv!~rS5*?R=z4^|Mcׄ#O=(0 /? %~+!0֔-HTCڹ>Ț›*vt ~5ȡ*4+BvѬO?ԩS]uyƍ;B(رɓ'!a5{R4;w4hPfffjj{PոqP33n޼a}ÒʖrNW yc.yj>\/z8 ~grF# ^͐B\#y2AlTyH }w@ն{yشo]tAALZQfE޾[);;cWtqqerGx D ]Tzfzz0? @k[FeHhBE1Wr vC}>RYw ܄oP7aw_x_VL5ww3g'C Y96\*QQQH5mI"+VJަ Ů\&v*zTуzm5 hQ*P@A uxvc6111VVVvvv"+HKKu0SsltL Ӭ@@~D֚M =zХ̽qfC6ׅSg=y$A *JzѩS$8}p_^ȳkl߾}UUUgHYYYǎO!HUݘz 8S@cA:$jeeխ[733Pɓ'999Lbbb"xbŐ"z! XW\:99=S< 1o~v`>5˧cZ@-1c,GG$oXrRu| Q{m%(P@tf϶mǎ9أ:;w\[b8M:, @8p(h0ϛ7Bw`h ":6 Z4q/:rT@AS@"1^~!QRqjnnNJR8ѣ ~kffPObbb8okk 9333ܹS`IIhnMu f (hBPyWy_͚5 M /_޽.t<2nFzz > wzH@ 5T)))}Fuu= оeeegSiZx ~hee%@UxJ륥补% [%@uRvqX  6>#:;;ǗRթ ;Mzݦ@O T^^Wcǎzz7l̇WYDD!hT'Hn۶m.\4q2^qk- % &&&A֭6m7|W_m߾͛sMKK}sxmӦ/:s#+Q@ oabb'g ,,,L:h\fV>Oyz (xL\433sss۾}n:dPe"/Z؍ukWPxW UD~Z72(\|y:ra<2^vM:#aAJ  (h ~[]]mggBqqqII!SSGr6xZ[[C)Z+q&^8XTTJPF"T`(,,ąr'y]''tJ?A'dmNؑ8>(P@Quf +JiWVVfcc,o߾8ͅPZZZ#U,&&&.YW^nj֬٫j*P]HHȦM/^,?111[nϟ;wcDhhsWkG (P@ՠBYYY>zhyyydd>}ر7hݺسg .8;;GEE tƍ+W.\H~7lfOECHbر_u5C46l؀?\~49{ݻ:t#s`t Zĉׯ_>|8lӇO|r!CY TTo<ݺu/޼y;w49ɓP]tG^ ҝ={2vuuDljj "K&Mmp &R___X7WiUk׮.^o("[A'>r䈗ג%K>3g 8gݺu8B?~qW^`\ ڙ3g.[lǎ7nN90XKJJt}˖-mڴAm+Vضm*O `}'(P T1ݻ~b.@aCddd`| Zu3Ν;q<==x L4gLm1 !-ZY z>~뭷״¤fޖ-[.r7i֌A.0Ԭqqq EOOϓ'O2߱cG6660AnJJСCʕؠzE coߦ`tDqJuUh(P@_Pٓ6 wf:IJDpb_8JǸsN`` :}^^^"[eyy9GEEA( lЕ+W;v, aƍAAA˗/1 F 8_G&&&갰UVauQ`w <ۏHī*)ih Dń!0Y:#6-$>Tzf\uF'\DAD-ոYϟ?_,--ESk>jT4)PI*~ vCX=pР&ز:)33AL[(A @O6TT[]= ;zWQEe H@ * #N (P@*B(D}P@ dɿ@ (x$U@ tw(P@AUXXkƞ>}Z;j]YYŋ51~֭[8 wvqq7n\xxk}]P@Mnev6vzISRR_oanaogiaUСCIIIǎ~vmܸk׮k׮ !!! ɓ'hA^^^8s޽'N QF]v3&;;ѣK,{nJJʤIΝ;KڰaG^*4ΨT*T< (P@sgӮ-n^Kjѻk)ǵhö /_OTYt0oo`_UFF#?_ǃ@:|Ν;?3̞={ ΃s}ݻロt-==]zzjׯ+++ ݛ7o`zT[3*//$MS@#{~]zt $;w6wk?ܭ7w c7.Gw_ҐACJ*wwG~ GFF0b0 *{߿*$8 +}/]tiV>uTaa!E\ZZZڪϹ4k,+++&&H ڴirQHMMe777NNN!JJJLMM1eKLEbD?Z&$MLoFSKĜk}8`rDΒ4|D(@V7t 5| ' ѿ?ûoVNVĵbSiYo?֥SGEE[ڵk>P&N?s~m˖-qeW\n+.&..5&7l0onݺ\YY9gg?#J S}>}""")1YhvyyUUU%;~vV-[3\G IJJa &DGG'''ܹ`:9ydFFWX!/[lڴisDYYpmV[T#򲜌۷}~NDa֬Yۏ>ڵoAx2e ^'OaiE^T^xgp믿.иqnе)PXU< 2BaC9I^3&SngD5kՐsDeAxr bԨQ(@Bw (NƟX-*+9… Ƶ՜2D{@m۶mwwӰ|}}[oD E:V04ġ3<"ЮDUTUhPwTi]Rf= !Z3  epFs}6HwQ ۟d7.wZ޷W{{z )x dv ovΜ9sΞ39#P(U9466Vwׯ8O<ٳ/^϶0̙3,~hE[DM4W&p]CG-%_{ҥ0X{CIUUUP+W e:u<n ]ֆɾ[$:ZWgprܔ,uRyU_OQ9777WWWCZ] aZXX,^8 ͔?#|abbȑ#ѼcƏqQH(hhjjDjbi#140lPSNݿ?:N0jkkk蠤ak׭[gXaHQ̪je}5ٴtzzNnz ݅K/B=Ο?*P0sT[n?j;v_BǍWPPkgެ\fnذam{ :,}I&vɒ%׮]AXdHHݻwYYyJOOO#n!xPHo_\|߻ ɃD761`xt,k Pbdh``0vXy`ܴhbܻw/??1Y$Dz?ި)+@m}q SI'3Arr:tҥKʁn޼9p*Z}vQQѭ[P;w)-H{9ԉ]| ztU$<12>0gXxŋ!Á0///x[hhhrNII### ,/ݡ c_~СCk׮`0={YA_Q/ٳWiժU[lӟ I?_|qƍ999PHu";".RYnA3!PKhXI*9}"C4:cǏ_|ED|*jjDEu:u ֮ZeZN癚64wp Fy3&.ZV5(7W,'d%Gϝ3ho4KQ;]Ll0xDHꪭ '; K;w MFFƣ@BDepՙW>Xƒ[#o] oOE&7M9!ghm&=-u\XJH#_eQG,lB$D~, `rE=<esG|,ZQZEIIIN|ϟ7nJKM>َ0>^!=aQQѣ&;tSYYlbYM2ꏓdUWiudjG慐5rM9?O [tlI|2.Ɓ"C? w6g%`_Z[v'N 2*qTsǁq#o;6oN*+6hР-Caa2wrr,**tǏfee]vMWW799 rppضmg}-)S ޽{WXdǎlO4 ?͛7N MOOиsڿ_~{nP4m4MMw=! %B>!_M왮!TidqdEH"߅~MdO=NDv&2":~L $ѕr-T,R;YZBPΤpJ(z?t2[3A_2n={X[[AxvB:}Qmݺ2 QSAP 5bĈ*tNԴLOOСC w 8%%)q0&_zrMPӋ/+l 7$'29nٲEKKkɒ%j]J6!w̡&@MB:gNyBʩol!,5R]HȹNAH(!W<Ch%tj~Lzjla\4g@BiBk:N>š666@cǎ-//G 0 0F"DDD"&ȼ'|f> ޾};;;;sLAA<\MM  mNձ8ǘ wذa}B=+---vvv%%%Q(nii).KmmkAA^|{a$fWUb2fΓӥ^$TV3;TvRCj+as= )[ŝɹ y.5Pjj@OS]Hs֢ ?S)TheE !.A'>Ff 9LZ_ާO2^>y>TNZjlffv8{ZYY-[쫯BX]]~˗#[[>ǁVD"..?DΝ;WYYHqJiB1XhQ~~~BBBdddoM2uT6񍓓B׋ah@ٸ0b ,:c;wЀuEfZh!yUz$d" Ύd}L $MCApFʺ# Ԓ׮UL؋Jrgg񱣯ZkP@ YOOh׎3~v|>AOp:G2rI&y;}?*VZ8?TmQ@k.]YQ]Fۗ 3gJAٍ=炊'mjjb $0sqh|n݂xC{BWC)`;m{Eљ,A!3FG)+:߃df.O"#T}lKhw*P;=-Q +pVӖzOˊ7~q ۙڈy\wکM_ ή~[Yf@QJv<ڶ(++[t)+WCCgdnnNla/&g̘z̘14r O˫\Yosa3-8'&: 1QyZDKJT9#CdMU^`Clqj͟3pmBQlϱceL'`ܸqfRRa=lBv9RX `ʟ>X[[;s516X|@>Pm"\2WS/9-2_AVhDWDDȀAD[IsrrrqqQmjmn5!݅KS]ۧԮd;b/Aclnnnwb c_/(]wi4ohIIL,w*g_(x|P5G{xq8ՍD")--ݙz1ct8vW8}tM@͟ȟw01^(\`Teo&xuWjlltpHuu9@Y79Egqq1<4{C E__I$hB wG TTT7߬^T[[ 5u@occݪOHH 155ɱTUUmڴ ˹:d)!rl{-]4///##cʔ)7o^pass32 `#X,ơHBq8 8::v`-[899=z655wyN^QC} \Aǟp8!]xЬaÆA|͟~ jcCZOYtwwфB!~ZZZ/^Tu%-ZM *C9RWWSׯ ջ R}MKKKWWW1.(($5p1(͊+:r5t툈ohd\~YDo fY) UxB9Cg(2.y&B̠FPG*cqg[xБ#G qN4iΝA%%KvQ?>r_2 pQp B h@Ktt4<(+̙3Ǎgh``]E#9`/dvǃ3 G&LIIMw+LaXZC1ה)SQ>CPD 6"Mv2y$FHnTca`tp,]Hk3~)rnn.Gv)m|ss3, QcFZ{=39:7oބSwQJC455 ¶Jђ)g=&є؀pTNt7((,p]]p_N_/zHrl{ӋtHwjkkwo9~v,& =PGEZHO\tHwˤ*ASS3..NiȘegWERRR[YZ ,9EcLI`/QNsν{422B ⭭4##COON/p8ϖ ^^^۪J*rqqeT i%D#C*PѧֽW-]z1 ]uuuqWTT) =p8'҉P頁[oQ:7o:thlllZZڵkQaݿãWzz:[-!LBbBACBA_)"##O8/#7Mp3#ٳV oݺ.,]wwK.y{{Cq/_D1>|8L!axx7A|.PpzL"tΏqEDBlbGH>!}Qt[ZZ ev0`ڗĝ|qB_Cwq{b[]]ݛ'p];;%K$''"J Fiذa '矝Y^SSJ$ S !n+ܳnPB&rw>lfH 7Tu߾}"#Fܻw7?:TQQ1hР.>tBwkjj`Xnjk׮j%Ta,,, E  /--U۹pzWB@~2wBR;w?: &ddd@}||˭j~~~GMOp8JtBw}(,̦bo8p (Uk׮ZA9}琇pVikk>w %;yM3yVXYYmڴ%Kdff'Xf\paĉ՗.]?~|w}FFF,stuuNjoom6X9nܸ{Y2aڲ 9V^^ E1rss}}}>\vpʕ\RGu ]٫&B]P:ѯ7߄B=411BeMÇ/((VTT̚5;FGGCe`͚5]\\̋OIIY|  ƐH{ZZڕ+W^~e~@أիWoݺ5// vssÙu{TBߩSX JP{K 9G4BՇ I=uhLzp8}N.aUP 1a6ĉpN.Nkkkÿ~gpF9sNWC={*='SkG1`vܹˆljU"ׯ_C'2NMG)Jek_4TEp8>K'tɓ'n'LfçCSSܹs0U999a,Z]ccc8f@q555JG޽ yEaΝp-ww /!__GgΜ9==n! )kEK!t@pPhPrhȑ#Uޏ՟={6vDD𸈌D.իW[ޚf1Ø!LϜ s83L'tמl!w𻇇RJ<3E1*jgg'0dc$!9E5?d&Gh_*&yw@Q{ߋCtayaDɺ jaa TUU;vLIwtײh*ww(i)yERDipQ:YieNƹwmp8^s8gH---ކi%j' d}ϺK iYP'(J޽wCԔhlثW[#Dj$18з!(HXBaYݳBUl""0ݠՠYq8pp:DIImov ("thԢrJp*^6W /@/CCC'011n+im![' *c2LwGȑTr8:V˸p3,,L{UU@d㫺&uɝ;wrrr#""p:??#jjj /'Vƒpk+(mwSee%'r>UUE~&N[r8ȑ#'O޳gϤI\KKK.((!tPmB7\.{⒢VYYyiѲjii)xθ#d'!9f Mr]sDDD"##q!PdzizIU|ljtzA-&QYRӧO:t(ܹsԭ^ڄFB`G]`s gghn:Q`gqIтڴi.utt50pqv333Քه 󘎦bw;q8C Et}}}hԩ,f-[ŋs4Pk7+ccV㈖N zaG7d-A# ?+IA J>->dn?KN-Gn#ef-f<6K/ɓ@ppb :cתʑ_R_h>NVT)p†yO+5-kT-J䤒ԕj 1ls /jydrpT 9MPX^^n`Gs%MMM fp8u $Dy^)M,,,: }pB[[;,,<>>>j_p{ piw]r8p8N!mcD"Qϗw?p8Dܣ$77ksLB;vA8 Bs3///NH_<9%D̲1v6rV)MGVJXWGKS bMgR(▖@_cc vp8Noѡw!tɓ'Mۅ+X__1B+***((022bȁ9g,v`G)3tӦM=vH`*N:;;hܑ_zeAA!{"?oiyIOO|d99YFOH*i[ ={z&ϊA]}@(X|}kH WHȴ4K"+[R$r~ISml/s=dpݻv̚=Eڵk+ /^kWW7yRi+p8-qlll~XXBg`o7Mpp͛+aOMMM]۶mUAVuSVkkk׮ -im={&EԂ@ETRR\]]VµkW!p2 +guMuA~ZKKZ+;"6ijBJ%b^[W 𴶶C&55:::W.677CT&\w9ipB̙SVV sΝ;҂gן5kVIIIbb"]Onff6e(ɓY^^[,??n1TZ OS ܽs' 0TׂX" p!KK+P`iiibb)ϊ߫gddb8;W?#csrs P* {]ptd qGbutDǎō;Nrq8lD?ab&Rrp8|QO襼;1[K+Ϝ9S>7=4fТoG ) i҆ѕDŽ([3gaGGyVÆ@(eckijVV#ײ򺺚p+kkߥ~r`!:m :lĈ7 "2ϙ9C: {!l)_Uz2{ J%-[/.K##333/^\XX _PAAae{EDB{T9NϙdD͛6:#@/CBB霜䳂˓⋻v킣͛7! 4k֬"o߾ӧn߾=&&---ư=H077WXDnΝ;jرhыDϣEp NB4|p~QR;9 'OݸqURpP®X3f< _kao|Ȑ!l /6EDD3b 䡓fG!h!FFF666P_GR7774,Yw޲2߯7(U.P+Wމ/**.SL7n{L9}:џB;VYd@@LpJJJee%¬<;twٰlGWW[nA*:g p>]GG?-4TqӦM$Fdϝ;W__ hw]NzY_N[[{ʕ%]t)%Ktuu/^,J.\d ,˃!Zv-剼X@!CL>qp83PȅneٴRp,ȧˇOggEASY|K fvΝp8AHT.p8~P_p8NF(Up8D5| p8=̬p8γp8Nup8ݝ;w꠸ɩZ___M=z4455>z{311a~6;7ki<9]ߣ9٨Ҩ8;;!ba\QS(k(B6򳀩YԔ˗ njckkCٳGM9s:ErroWqFxx8'11)84LSjGSQ)úHUK1M1w3w \*,ݦ=:n#lii2(y6n܈wرrlb //wy]uV6[ŋ}#ߴ}mmmlfWnp R o'%3޾vv7;-C,n%OqܾFu0>StKKK_ I~y0fl8S4gmF4QH$_ ;vlZZ۷CCCMC~244dm'NXÇ?zhCCÜ9sw޽5oݺuuu .ܵkP(Y[[CUvՑw^!!!sZV[7oN<5-=rc;⒟[QQ>q-06$\쳏y݌ԈȨCCBϜ>m1o_.J}0@?'ȇᛄ&M! v}Wn7v7osС{d.%`4N4< B i$.!ArFK8ϜߵEEEO>?桔oםCxzz6,)))77Y^|BqDḸ8z_5 cff=~U,--wQ?*8gFiĈ^^^6l3f͛7_{?<33瞃6 <-!pE܇GK'Ο83cq#?viZg{m[1',/x6BӦCtB/Zԩ-9{?C cyww2s\n3!ЀdN $`B?SB9:B>B"T,Srа5!_Y`h%/.""q:~\4 S~"y?2cYzB6r6'u(!tBK/! ‡i3~S|rT[l?~<wڵAvv"[566(ڂF 1c++++** <<گ<`՜9Gjvww=qo_ 9whG?T__ S'˂aa\lbj* 不a+ <<<q ]Gf޽C*oB@ǎdGN8E,{R܊.c+nC|F|U&x&d!:|IH9!لPCtewt$G9 ;!ZCA}@qMMM^h"xĈ6&9E NkBP)$Aͱ^0g4Hv8BV~gΧ~*_^*#H?o66mD&>ƍC5D;BB_6B$;qDhR]g+W@\]]GnݺH&&&uuu?`HL|=X;{Ԉ#oʺtʛ7WUUJ$3?/E$%d|ﲭL >ЖDْ;ԡF"3M̾ný{j]*e/N!"B oC)!n&䖬ЯiSlG7ao@V&sW_} _?? m_BG3 &~OS }OZOB#r$!ǩׇ$WR=1^y*2¦.CO#UE} |n2>g#OQZZAՌƒF 4/25j <*7)I'qBnhi 4`A'47-^L.Zq, ."l9sC#o#Jdme!]w+TVb:H&}*_5?.&ĕW Iq+U*)9rdKK ~ |e4#f b(1kC;dJzAty}^i15h$L #[]oUS湹gΜQꖬB:HnXO7T&emKЅY<"ޚW  fRM־Z*}JǏ%%=TQH*-ѣh&Z2Tl[, ii[r}^Ue/iTHC}l B.= #U 05ssٳgC>kcA5P\/>:ASEKg*棪<]dt{܍i_!F?&ԑ#N[vаs'[)L3If7$qU----MMM>1:RD ?>11QGG^PJsEa߰aFR_SSSTT]RRg2|A:^v3f[Y[=>+QXf𕞾AKu=ʆ)g__Op8D\QQQ/^|֡\(BP:dff6a„Z##yX۷;mڴ7n燅;w.##қESLT2"H.?;yʴ}~07  p9$$A--v RcTN#9iMt#7N3p8o!pH't" k C6t׳n'N(// LMM7n޽{ᛡUUUcccg"~ѣUwʆCCV̈́{{~Up`ʔi;>0F8++sŲe>>?I>}&XIG>/ұ$d,!c=p*-**gvssc DI"(` .,,, :::BzhC9RMCD*K,,Ξ9哞 vRYsB'E2ggׯ|ldd,@^P:E*t`|pt<p8O ^4H6 JgYnݺ#VݻZiӦB_UZ[%v!vm240koH촵Z;Ѱ,БldR";[čSnep8>E3WWW?1YKER Baw"Ђ1'cIp8SKuW((񉌌8~xń-+)T400pVLdB3iK}}7|[bĈK.EEEb8i%%% .TGiGZZڕWGo`ͬ2Ӽ}|"*/=UlQ|f"Do2QWWgee5gΜuֹ丸0`3gD{쉉߷on!D*8γIu͛qׯ|W<~fff=ҼQ߿{]~~~OL>CqVTTևiE^~PK~75%ҥ!C FFJHE-mMX" q$w(ѣGqٍ޾}?.[ŋ.]ZXX_ƌsڵc^]v> E:x`|B gϞEf($$L' رc˩S:t~hȑ{E4qㆧ'6lwYY"'LݻM_UQQΝ;)))8]4iRەC$I^nlY;w033 p1BTTtHhO7Cn=MWYK낧;!Id <33 {>~Ed@J vD??xb:}n _p˖-˖--HGUaiiV]pqkqwE]poll Eu0\> G@:4## tILMM6"3g0U3җ_~}ۇdJ(qll,@JCCCMMMvkk+ T)(]7kWAvڞ;y'/]Tu!`brw_.^*q7c jָ\+ZNqhhlH4N:x.\-q} Y aM]ݓS=Tz޽4___'''( u2qygee:Kߌ3β1-A}-_; ۨQߺuKGGPSS}!ѣG˵rҩ9O:镖jai5p`DHh3g Z{Tx]\ ~Ȉ H !t! u-]ӻWŊVͦO>D1GyVIPl5-Ep8B؝q5l.jL>R)Ow^sss|>L~~~ԩSa+R< |ΝdooA_ߊ9rdrr2L rN<.m[`]x{v PQ{G--a͐>7w~?fpټ*J'rBG":6:p 5O$31p/R<-d"#X.pCWhllLLLTGi/_ѣG{zzbɰ)Y<3[wV[%YYwK45"#={:f'O +OVSff> Qywάy3E3!F,K.>Y‚|uuu511...>zq㠲Lw&LXnNm AAAOϟ6m=xǏcӞ={V^}޽C"r4$))޾]8N_@UeA퐐 /AO?mhh033G+U ¨P+JOOuFFFePmD1c =l4C 6~llň#p8]VVfeeell։K KF|+,7jԘkׯ3ըUNv}3rt|̻y)Jy`^\d*]'p{WK ʞxyy)ϰMa } ogeeݻwoܸTUUffb1H۬f͚ݻw+NR]]zzzgH;p`DI4u _V遉(>!+,,WܨfffYYY%%%Po߾鮜SN|9sݻ!Zp8>M(655ݸqC=Q0nɷo2WW"[[ljϛ5;Xu.(qee%VZ@V򱰰@!4yg=y:??;jT] wi.zlu͟*"n=||9n?ŰOmmmů, 7--"0a¶m_kccG! ֟~V__ρ8SW>o|w igՠ%ZZZmQx,VD(l  ;/^1c[S(Q<aD$^|ތqƱR_'777|k+l.>p'İoFߟ͛III/ y<}]MM{ll,*˗߾}ȑ#8q"˗/wm0:חkΣz/"444<<^ںu+ld2vBpCuC2sΡ?Xz52jʕ0 _~͛3iҤ:#n常8YvvvQdeeر~ժU07_uyy92sU͑RNl0"jVUHC)LxbD O޽;{lkk_Вݳg*YfakJJ)*LH~ҥ9s+@OOOTVk׮%tfiӦ>|23VsMɓ'_^]] +Oh?"|q_w C&l.$'CYI߀!Cu8ၿO>I AbFh.2]y޽ ZZDFFFh!!|ʏN/e˖!?2Dل bv횫+BQѝ:uj„ ۷oKvqqAWYYH} h:-udrTezLat]waehz{{Ihaaq-۩S%>!fi@dtzzzW|(ôB%---''@ѻ\.2Cz=@C&D@M{}g;8 s rrB9'[QN}{߻ow:G9Ȳ(G" 9 3*=$0#F?}UW\D"K?dUQ>yf;p_y"xڵ,Ⱦ"rNCsrr,jijjjpp08nfF @̇- B>uֹB|kgΜU/ LLL̜'MR_{o_㌻;D~&tRID B6~3SOyЁLkjj0Tp*_ KNNxbRRRmm-I-x7==_z;88oAG.((q`ôGGN*(3A0a=a 4vnXw裏aTBȅOf2R{< & G>R 1hCCCnnnPPО={fϞfyU"i<gJ1b%(O>!7+fSxx8.D`e6Nj=5ޖW\zCP7E<9O 6{vڿǏ߹sgHHGll,ϸqĀ=zh}}=WFFF u'sI??6 |0W(pqqqww? UZhG}TSSMMMOiѡҕw?0TWbCx+dٮpܹs 6gٙQFaFL =B1Ppo߾-S v9O*j_|D]lYeeeJJ Y===Ph`_mmmFЏ ЧϜ9MPa.\Gp6HPwd.آK aܷwvԩOkӧO?v¨Einnfߟ>}Q<#7 ں·cXB L<b)B߽tx̘1ϟߺu+a̙`X= 5wAո#xg1P wnajjzq߿J'h?x0H&&& @2wBwT#144 T}mEE.D۷o߂ fƂXN@IKK ĉ*䄾u.)ivšX|4Du -,*C/ol } ܂{Cs;fii_Ǝ5*..r>77 [ "tĉGutty4ÇÓ\]]NXv)((HOO>x`hh(7b!RPjsNP͛7 ۷Oy6h p9X,mpBUHEwpܸqzUQ~kkk|a|MiIREDh:hnn9hjj:ƒJDekkO2a E+i E09sz|\|?9m63%% Z[[[XX) #G\t){ҒbŊ[nuttJa4ڵw_z>HqQ$P \y'.F5[- ( .{̘1eee lpqWZUQQq`(  fsiAԩSǷPdЊ!!!p?`8h]]]-RtqF}` pDrJvJ D3B8RCD ܁wADEE~uƍ>AQlٲ;*ʝ"Q!sN`L6„i&m`_=gϞ /&&&nڴ "7DNt][ݻׯx"988>7&cW{/qz͚5 uHwA`z/ ='y o|||XX!^| .q555wepsll,_|ǬPMss3,h@R򻒆 C@C'V:~8 6Rl]Mލ:;<֭[m6.KKKK Ѝ10a:~~>4z5 ¾}%%%a` ?:4{M2t9}t<%*Ȭ'^%Ք}OJH x:@87"ro9G*p.yROͽrG :?h% W^W,|rBiQ~- ^xhsP Yаm$Qkkk Fof|Ddь4.;J%"ȭ[~7'ʕ+'n ,>OcD8q"##>z(Zb.=|pIIs=W__ rɓ0ЯԐMܧa€'$e\ I݄PRwSQ--~uHHHV.R)$UrX` e˖1O__!@϶AkAlPpXu/)))aC"ͣxFIQ{J݁%˰YѓoAjiHkjjbx&` Ϛ5 ^zf.88b$DFFp,..F!ȏ!DL:Im$#0U[P+|_(kTt얢U@.NqKM=d={ [CCCαE}@ IѲm*zw:“)/B^d>D9M;::<رcܹ9footGGGH㝝MDY'NB{o9A;/3V`'<1҅PWWG*$kYķH`AH$_Hs&=,"jo0$ODޖTʇq!1x> RLƀ2vܪBPǏ][b()& 5Sz׮]f6aBIp%(_Z.:}=iI8SNAJXZZC >}'NzfhNhӋ/⋍=Х6CB01` fuDQPZ|jee|||rrr`Jy5kրt՗t R: M.8 x]EBd;t)Ginn5kcllIΟ?z`BsΝFB_J3:t'.xbvy1H?">"$Bi/_?>.Twɢ2Z˖-[Ձa@ww7K0EQCtƦn"YMf?r+ͧwoPE{ C*$@P!UŽ=ZUUr+t%c0mll`9H@DdY ҉۶m`?c+W Ԯubs'~4@ 7|o:b[[D"AW;qℽc}}}AH޽… ѧ~W|`V|_{-_4( N .=>##9AFΝп9w/)))--% S-i]8!ń<snouF:Âqpނ-!z/gԲd.\){$,qbKȇ/YR+gӦM$} KBox^kXJ0lZx{(q ]<gҥ ?0={xxx̙3r#s=DΟ]PP@ 6́nmm-[wD ,2(Ґe_Hf0't`r nф!ݳq|;<׮] E$ti(;vALIIAߞ5kDh /oݺ+*//uCrLW>vŭc.!NKAsC[9UR-V^UNAnnFjb-;#wAff& ,LRgggXP0Gmi^ҥKwa%`\"?j8crVfa}V%5 8ǀJOO?0>>7(EASIMhG,H_ܮ_ }i[ouBA6 J'2GGGA7oN4i _]ѐRVC\5ϟ--< 4 ƒUӜDS[Of'߿kd AEP_~eh񍍍k֬0zDN._\CC#** tB[kWXMƍ0"Oɂ }I,}9qD hڸ8%+tz&i@@C%aø;w.|y#RfN-lBSGBi&_ϟӧO~PLa際wͶw܁;m4(H|d0.20C ]UE=>dRw:=&h7 ݤ̀M)z*<BmaS6\4'XWC]Bԧl%d~zhP"f̘mEdт}cbb e*++enذ!88֭[`.Ȗ 10" ]n!KNM $Bn2H.&ĸu9KhG^ω.н賓Ǐ'tAV[ JB5ta5@-bXUy~/E(--Ũ@a +v=vPE<p$[Bh0in&/vy#&i'_*7zdS3:}ŘW<6T)mTꢢ{AyJ~`̘1yyy)))P`:tHyw d;U^ԓ*u޿ Yݭ{AGGFWsPkyCoPyjS` '[%Z7pcb,v.!eMMM}||N>mii8a,(y֬Y666P7n":v55ҟTJ94]M#VYrP_B~H䤢 Xm:P}Jzlin,k- ӻ{1={3y4`mn ݠ( FwQyhE}IRl[~,@slkk\A8Vav޽{} RGdt5(n3Zwwۻ 544ihh:4؎- , 1$.6nܨ`8n0hnnb8mm̑dffAX~wۿIPi``XܥWZZ%@KS NZ[56VM0/M$ϻjUVЁyyF-2:*ǝ;w.^ tT(`8;Ƣ?~^Bə4iR%Y&ǓAMM #d ГJQ9rH%]K%( "`ɒ%C111D֐5:::YYYѕ^}U$H8^>f̘===]>YQQS G+++wޱc*twnMCfϞj߰i~4& ihdlK**'MRQ^Xofn]ggW???XV* ^GHZe.]mz'J0ɓl鲝GtՠSN'#Çq](k׮JW\9?t&jMPuA )'(܌EƙGP|҄mI#lii)ηRMB_)S¢"'@f1kyH~){bA b0VFR&ќ=+ȦŨwljjOGe`h1'OԌ-Z|edhX*r qmTR<qx =___4 a[[: /`;}aFDD@ͅz~F3SRQNBBYYxlWt} d> 8AhC+#Q'$)$E;'M.^|92,!3S)SٳtN"V6DOW& .xPO!crU,AIW/rqfiUXC{-$Ab`_6ldd'F ͛7ϟF^|9hcejj*aFs:U ))~ӟfjiiG =CC㏸_~7o6 Dt-'TGτN Q#: /k!9]]qam-30&w>/5 ¿@9B1x%=N6774V#y~3mmmݡBAuY2D'KDK@r(_1] eooӧOc666fff0gmmmO c޼y=T%Ca9rDߩ 愤(Uԃm)!q= zf7ѱN₮"(77r&%x4TuuUvvv% {&m]%Emm{{{MM͚Z3o0MҋS H7c<""CZiQQ$c=mzm6p bI41v0UQbPV!. e,?θq_ܹF0ȿY7_O :O?:tH(.]YSPP`bbDz"YBOOO---0]]]6sAz J$wP k'O{w.pW!Mttt54Ȓm˖LKOmok1cq}L_|ڵk"XZbW\YUUn1ljjD l]LjtRيApƗ^4l}#eHd+*tXv8"VR~]0W\o4iR||ђ}6PohZ|ÇgΜż?&$$njjw?rY_}՟FR8p͛#0jcbbΝ 1vez\ayߌ9 7j61g22&O7#<|g~ZVf^%vѢE۶mC'3fLNNU$[[)))޻v킆ǭvV/܉l3%}o7oѩkGBszF\%WC\.,$THӧ`oߌR[UQQqL0zh-&5\ؾo_fXZZ8bĈ= _404D}PCw77 --s1~3-Z>*Y~3Q_@CY{n0smbb{nƾ_5F[YY2^5ՂmoJ m3!4[~m"sk&G;;b>Pu cc;;7RzlbqW8 G\)œ9s <hnn CL6˛:u7E" G}e"VS XOHPWO!ܗ@ OMUՁNY*.W8-Gtwo.\T-+ V ( tE--A-rT6 jv̘1H8;;:u .‚+`N{.Bwۊx< OUpOvvv*-?ePax3\Kϓ$Co +--UEPT \˚xر,=wڴi%%%+W077 '+D:ۜKxZFC]<H$Hvf---r,Փ_(ߌ/䧑](Vߟ.0ۭt<<`}?|~~~[[(V, ~Μ9]XG%YBbI aǴS/ӍKhz8-JC) ԍdhf'GCLyCY󫬬liiٶmӯ^MIIILL5jݻ}}}WUU«j(f҅:Jy.u&$2n]XjKpXdHEQrAFҧ`B ~ڵkYYYnsrrbbbߌ-[kG>~k*JfҰn{4;z?s2S u-.<ចjjjfY cccY g̘~^f4u1'Hs*u"qnʴ4lCHy< sF[[{e$ X6$$477߼y3Pv03z伵{nQ9<-(7=oy6P?s?,U1wܹoFyweEߌ@U]PO]]]0aX9i%/F3fhiiy&O˾e8v@M|<O9.ݧ|-#F>=<"xPޕJl}"""-YH"q1 _xM$޽jʔ)۷op5#ɓ')B'Aׯ_PbBG/ZٳÇOcx}}].99=ӳGRn]UcDxyy=N[WHsdu bt>7ހ5eĚ'^ze>sL{{+B Z-++7nwJJٳ|||8B ;V[[G***Ь׮]cǎhd߽{PtwwCܼy3#P ڠBeliiG gg炂'Ntс\"E|T7!!5l $d+ÃǰAV h>;SNe. z^}#'8U__g`+XάѣG:u u`cKbNHQ 3Mep pm۶mٲe޽s̹y&`۷ocY2uNA`bͿjĨ}&* 8SKe\"du˃A^p*K;99)fddGPhcccyʹ÷d`ߜdF 8FFFBwuuJ_[[AA尡a+/\2 /xYI z$ycpH:9o<^d 3(],ȾݴiS2!nv 6Vxx8_ܚIccc___$ yx`1)V8ʩwqq111촵3Yaa@ 8<ꃴo銼<777O!|8::Z,8ppXXXNNNpp`ֻ:thժU;wlйsBB [ożYf׮] s7E[nn_DO6ck37}n _ҩ=]ݡSؚdJB SyfoQTTcػ7ow3aq %---/033(gAJUTV&.kkk3 't\UYy9D@+@1jnnCO1ZMHKK" ,;;;Ѧ ⡮Z&?444$%%"S lncvyEDD߿ K755ݻ$@^# 5&&q(g_oAP!]\\pZp!+xĉ0p-Ő>dF>ra>|xƌ t<4.N:thΜ9C]w*nsH".:_]]ҫ #C.h-h'ran@si(I/KOྂ-c(ȃ{D!_)Sp={6Koܸ%&PNP"XFVZ\$Ǘ^z%&ȮwqѮih*nHTq.{g#FPEm 0Y]\utܡˡŵɆ7jI +;ĬCtJww/ZEihh"oK+녤9HC"d,& 9w䍷 %QKDjbLg2rPe 4S``'G+M'y8a[45`uj[ K +kZDb *wڵ\ P333 9s+ج,t`Gp3 I-))Ap*)BDeXQLpGS)W)EqucƍkkH%Q.rN6=<|~>vf^Se[]p`a M ޮOwhZ۳˒2 DbTN6#3 IAIn]n:%`r_q{@lr;8,>rˤ[`>' U(0΋%: 461ai3c x:ÃHNNf>7T4mm0>>>bwO>Pi644p~g+lL'}ŏۇ"nuUbbHcDŽ|6C5ƀbzǏQǖGAK⦂Y%:::Μ9^^^0gggE"QSSS?677_x8**J! kkk+++{E+ yc4 ߿@ZYEqE֜LT0srr| PiBVWWp50䵔좊1no+Kw{͙Ḿꆖ]ɓҪ^zرcNNN7o޼rݻmoo{ܹs-Xq;w$&&WUUI[nA#}kll,(988r@s\(z|i(3a#577xs˱#c awI:;{jHi0IˉB_q}Ќ_b,ĉG.\E!999kii9s 8^^^)nև' Q&mw#?<<|ҥO<:x𠭭-Xٳ`YfACǘ9s栕ѠSLA6p6TC@P_73z oy,MM l;oSkGMSKIiECK[E]@k8b pu 3g1;;c)22^jV أ# f1477䔖A1|m_[6@O}gdp,;-2("?#z@SCcҩ.ɑ-Mc͍ hWokf1V?]:}3u@;]yAAAra>yȑ2 m]]] ]`b0eAƎݣnj[:9kD:{f (| %;*ǰ?=uɒ%H0*Aq3s(+W0C磣!As=4]XHCcBAPz,]PPPRR[̞=;<<@S[O ͉5hee%kP ZSS O{' ss1?q5] h OoWOjhyh ֢)P"];?> KlȠoV4p{ǟ_^G+S%E)wWMenh@)Ԇ::ZSb:RN)$D%#MlԜNeLI)sBZ,ܤl}9i4y/ӽGHi =6557YLXܷB>o<\hiiAZ$   k\ttty jFףA]I+i5ïҠ=R7hmP vhfCm-ύlm×[TyZɑ 'qjEMCSK)+nln[Tn( U74?w qZdٟ> }ĵdž5cwY>|@/|ͮA%w\/:Ow&Uijϫ~P]]]WWԸߴ|VG|1$B9_rE==[T @'''xs͊jkwkԈU3`{W ݻ999:::~~`i舋G+lll ֒oooq/kky^Z^^nnn=(HKKԌ@>>>EEEEaaa0mSSSG RdN1-CA$;w7B9o(ƍEb񖖖s'N1)V0}?ǽW:n݊~>-ex,л` 9,`_uX3gLJJ]zO? ^i 'z!4a{5JQ,N>}u## 6<:pÇ1{Sk_A<{$$$@. U1&Fcr&e]iPzOH*[;h Q/lrg!вFB5a^iuo)D"ѾѡPWv!ȮȠ% uunez9۵u *jv-M+3Ըot$zfte˖ڋ/O< rϟɺJ.m޼yW\qFpp0K$BBBʶm믿D~`|5˫V剉8ى۷=O;!bM3[EHշl9E̩1dJDrVm&BC^qe[T^0&@ =l.'e{5vEFŠ%n3"|ʪ|DP_לUueQc_K57 tNsѮons5m ꒭mi@o>7{vv6/z;ׇ@~ ?CYfA ]XXעӃ!`#wQi# #D_"k֬Aig {֭[^]Z_SSÌ *>4TIbU!u>%&NFb2w$t5"P,.'tS(ѕi#KwUndJq}=o' Ë/_>}||]!aGN +>1b[C#) 4do lgg;|]XEި͛^z?gsJ ԕ("h<$zk׮͞= &8u… a$ #394~P5 @ ]IȺȰet|D{}gϞYgnn;⒔U(JHqmMP%C;:"j nGЊ&Ii8 /#} I+"B(Hvl! هɓ!4qSŞJvS.6K({B4~ #LLꫯpDwBaQC` jZkᒄ.* 07%*sj҅Qz:+:p`` 3  sC _N}*tIr1([UMIIIŐWxx_AhA1C܁rh۬{D/Vh ȸ*44}j}}k/O -A9ԣl"[p:hfqlK-[XnoU`[[\. uu`Uv%Z]uͭz׆6@P$ 91Kh`@ q56% T7wI$eu܀ }]` yڋ+juK%N_9mER%AAAGl " ]w\\8E8a+ QsQQQVVՁ t`\$2,N:%'Jp̙31`da:P`Y~T`׮]01v=c0q0 LQU67`<$pA+l) +{!S 6m%0 U9fz0\ۡq9=܅K.e+4E} 777!^ >J`c YWn P\k% [JƄ,*]b<1c{! B{yyAhUO4J2ub1Ǭ8϶Ҏ? 9 .T>&Wt&X: TzD3I}![5N^H,4t&zXܫnr [\UG0I۹+nR/nuua7&z(߅5z+^uCj(λ WGPQYw-Z" ˖!SveR9V8F uq`ap!<Pf| 8B|b݃X{eށR9Hh}6S"UsV2ad1߼@C}#DAA%,7;5 n (_\<i]^ɃqsssMM ;7Bqdt {[iG mvɥ omnBLDy6Y=ݙ P6Q׭|Ůtw~ȵ„F(+G )X#%3ŅP!+\c,^M-J K Qp_ͣM5dڏ^S9lUL(3,U :DG'l-.`#.7A%466a]nIVtDp 9u*V;,݀?gUTTGݞÇOqqq흴 .(9K_FpRzm6[lYyyyrrw߽zj3?j{رiӦ]-aŊֻ{:t̙$cwK54=K>ʔn0rH:f05w=wΝ'&&@jF:u/e6{޼yFuz111~,YeO41𞕕/^Q{gڵzFF}u֡555&7??Æ fҭ/K&bꫯL``3g|9 0;v#Gj󎥻G뮗NA٤ORsFmm-sIϟ?=իԩSq_>>>2#bXttkǾ}j ^Ϗˮ/_[{'Xρ]I_jRĮ%wRw+w#=.Dx[Oz'JR7 ‰5kKgϞ5&LbyUUUƍ p:$8^zLMct9Yq(f1bLW)pq7: ,`l9l0駟Rfb.b3.^xFZc>9pŐt-;t[ N9`=<$/MĞs30g}뭷zꩥKÇ:8\6og3TK.vKPEqzҝŶߥOEstG}3i&w~n_=Ua8eZj_ᴃtAtmϘ1_㑶o߾yٳgV4g7'+yM6[]b1cp 4j( lobpBď wCj٬,LМ.:P8#:@\Cvi+तsx7уSط4YpVI4.k*Y`c ^CEtL½t͓C 49s׺8p}||pLj4[ű~c&fg%&b3"l}Yz{N;ґWC2K辳N:T>ܔ;3OpA,pu5IۛGrekyT\H;r:~eA#V?O DSK3aO-ݹ@{p$M0K>^S</"6f JrS7^y2ѭ)PQQy9KpmW _7wB۬&٘_-hc(݃+W9s&Α~ؙGoyǿqa9^5X8C8.k?Ǫ[S_q29dMFF ~{#vf eiM$ZukTYmɉ|ȶs?[?(Vݶ諹햕ltesmM7ǻΛ7d ը|0%,S ,0*nVZ?GTܬ1'|U6GqlTGH)))|p|> WI]k>u\z[RN&sP}TKD7+3KcߥnTq)]Fk/!l}9Qp%:TҞ8wď?ȕ b: VXXh*'4 iJ0t)U{%='8;xvʗgݚn=C$WMhrs4ѽ=G'讳 3o$.ulB\7OsZ ny?zG^1[𙒒b^TWW9r7<<<77:qķ~ެQ|(ٳg#"~Tغu+AgQQQ]]ݤIOD;"cǎ-++;|0'6e{ntfTmܸ@vrqBptڵD$ls7d!>>lr-?i:zjjj,Y2w\w<'OB_e3w[jʼXWGZjMoIROAtvVVV۷oONN޲e˙3g= @$a . @PW .1ٳS:If2:n^3-Ƣ(Iݜ'{@Y@9=vT[y_~yٲeYhO5+: O "=f[Aģ,..6)ktt4\cc#kLtHt׷o_.&&1>AVY? RSS`]fQQQdAA97142{DeiӦ^st:?ĉ?ά+t=5[uin!pp^{ !DJFe}_!Dnٓ0=:;;y˗/0a!r޽R-/9rd֬YvJJJCBB8Bw^t+VJkc6SZn]JJft|.^ c soЬgUikqҥ:{! %$g:Ƶ:uYpR/:sݘhs]9{Dn#yDUUm DY8Vک􌌌vF8 L`:7UVAFMyy9T-]{6~~~P {pNDDD@:C``СC]MLIz*߲_= sWMPx]K/ t\U&IAֈ p|<  E]AAp-_sAvAAn, BG >DwA}\AwCCCsrrH,tY t7rKjjOEjHn ӹsfl% @ A!A} zU >< SQQq .744477_ss9uuuV^xSc)<}Dh[x>bwցކsも.c^"##O<RVV% *..fMii7>쭩f :gҚ:UwT-Q%W QRa^N+6*.?*yG6!Չ_Âb{%"ƶ+lo߾}\޽{c{ǎ  -(**b 6kkkҰvIkTw,:GJ 0X6FU=RQC5LUU~ ۡ6'8Mk@45A+4&ׇ,?cˤIENDB`sardana-1.2.0/doc/source/_static/gui_snapshot09.png0000644000234100017500000034227412174204305023617 0ustar cpascualcpascual00000000000000PNG  IHDR& pHYs!!3nIDATx]|Ek{BҀzQPy߻rλHRIHﯗ-ナK!+8ovofwsju xv;EQZVPP~˲6 u:]C7p/}tzBMgt&:݅bqFПY稾#NQ[[D[rǭɓ'<8n8):Y=.//ǡcv|! :z(РArDJҥKx_JPgϞ >>O=g͚5`2IGIJJ姧{Æ 8ppyNNBF;vlΜ9'!mۆ,+?}^{B_}m ]НցW^ tQnv;v|ڵ8z}/@f|hM6M2 C@(uYI&}FQV;!77Ćth̙3A UHHo߾#F߿@HM~عs'L%(N<\x1@Haaa_~%$ V_`D_a@oא2HhLL z0@NaEp`A]ȂdaEr%P)XA駟N6m׮]0#a^ff&Ҭ\J{y7ѽ(W.dPBo0DddGMOzc +# 18$ICCCwrrr&ND01shќ"w G {$9r$148d0)))GC(@1(~"=zJzhTFFOO<+;;mSv0jN б ),h# JFٳgCr?~0N7: '!b;d,]F yjF7sIj$.[`yHPz&8})}Mo[S]WMȽ@ 888""y좇}Uw7n\ȋ 7jkk 9yOVy 4HbPbcc3dȐ.ֶ k.јER/D:.22ҷ<wچO?Tz:333;;0u@G߿Gk!u6Rl6KPޭ<(/k Ng޽;r<(|ݺu)))eeecƌv; OBɡuuuh4>ŋg̘P(8>󓓓cvlT_.T G} ~)X]]Q^^4p@aPVGK;~I8$nA{Q>~?Qt)s> X~… (,,Sח/^i׼rժUJf G=zQQQH6|tyh*EK,mFP@5P[[r|X@W:t;F\'h#bccwttɓ';-Bw4KII  qWL\t555'Nnm6!MM?(Z\٥P4Mo۶ ʣ /Gyw 2u--- P0>s} ՇHQڛzӹmb:A;p5kր&Oi Àiii 1cƬ[. `p R mt:a ʊXbD$Jv8pUS- v#rܸq0;00ȡK. UkB gUU͛!ڕիWd(aʕӦM;o\?h#KK17i1 &IR8ߔGϗb^K>,,LZ'Rm "fvZ-}~# |͔J5 u7 ȾeKD/. "ni)@@@@@@pKC|m zV\Gইq8 iVn49\%CahjƸ\.Z} ! A )`4/B \. <]xuѲWlN⽮#HBˤ.d2ycCCpH~656#j^mz\u ,/+yQerLL!ԲvBIZܠ8+[,OVw'@ i bH :a܃"# f-X6RY-#8xZ͜8}̥HS*2u^Zboم*Ѵ :a4mT2c3>C@@@p AdOFKg 7,@%ŵ.իlؘ}r'xN| E qz.@ZM V^pCdx&P9H͝bPu^YOZLpեPj堢v{d.^jll<45&ڗEH8]yamYӠVۗ,{=*ZEA3WXeWPӿ<ʣkIJ㨦T 99oٺkSo }^67<5y ͇pC8mh3:=l­ AV&qvRyN(((qx#?NG. eXJ ᡮP hNXZ \=4|[ʭиVp{87˺C\B\R^Pgb7:5{_w&CkQۧT54X 1Nesx<.P%DHFG*Bdm,cRdV8Q ltY )$DU 蟮Z$8zL۪dhe7P g~ qqi[ Wfm=g Z-Cy u.Գ`>y5e15'U`Z/-MQ7FWv.dC*~61;H +hK`ц5W(%Z8ܪXr !gT9eplFZi(k@c@c-65YMvѡ. hpƴ#BkpJ+Tg*TAŦTT H;^{DsBN+ 5-}1+P rΌql.PahaMpGsj9JST+83ι;ny]L@@@piq<~WzņF N90>t$x\ADwPf93}tUmx\8'/4TLھk,y[Uqώ-s !xF)8jMs=G `*C-kjKvN *ZPw%#\-^mRR&Y8CNQZtqrVHgjXyP(!oUT JKaႌ2jnCy+r]#[3㲲 L,t/G.s!vV;ȄPjZ;~E_F@8|儈~x݊3K8-*iVP=H%>jmthHll\rBQlw︝w)J]DnB\ ;L6H!y/ {D_$zQ^2e(M`O3)ҧ|EX4Y]fYƝ2ӍѼIZeQm8-6ʬ AOEE:BBϛek<0ZVM TlB[.Rb*emhlQ9LZu\65΃AH6wj3[_,S(MɴnQ\gιM˔~r}y9_]=W݈굚`cUmve*,l]4iuA+ JKt G06N v. U:!Xc7+,B\8gY-]jp0X׉u4k6uO?!NLe4G-㹣{e89K+Z4 w}fہ8Ṁƶ@Qb}QD \EX~x}2ަS˜d^rRNV1O;X2:X'ୠ)Yݼɱb FR-V 9Xgd1'DػB[tJ#h5jHJڶcE)Zrͱ&ff#r2 sia *k2yA22BEyj66|ۢ4o\ͻrCLNj+5Z)cGxåZbtv.)i5[x9'[*culCmi̒O`w+mzؤ(HS&uXu0'a uʦaz$opxl:&(,ʳ|. ,k\P\E:(9GT#wڶg2A8ӽS [*K,/Wqgw>ZPSfƶ#4Occ9旄u*707.dXgkkLó :UDH`j (OoܕU[[̫ٳGjlHA6c6&D ڤkTV S.Oع31suF}]M8fDv#y9o=\x j fUNXK5;Z.8)gbb[k[+s:ԇ9C{kLziiɳQaVǻJ& J"ܦqz”n&dždԅx2Gk ݋7xvP^^nG{A7bY>8n֬YPVzW9_pݻkjjy+VTVVs=7oK;Gn-''^@hĻ|EsQwm𬿽10'ƨ.3.JEJ9+餘)GzrF.>1g7șuy.Z3r9`P<%W*a1PfF*g6N;QrnZ'S7,[bw:z'8;zh;&0e0l/+8]eAAO[д`dJ3ΨE4WַѨidq8Pȩ+ˌ 6 :T7(x7VD9ZVV+*N`Tqfs)B^CSNspKYTSWAYlfb_mV$v=frfb~ᨨ'N[ƍX,?< >| ,_5\5׭[CՈFLRR/ȭ[xTڻw{*TV9r'~s!P(⪪ fhJx<fӦM裏_C:DGGKfggC+WTT,Z `ǎ hTss3Ξ=[&<k) >gBrBo-s9{rN9 4M0(#%C-?*jRLd<5͛2WFk}yl'?v7[ PQffJy㕻oi1H.(:SxJ`d.F 0j6wLX`b uSܐϻZ\`Grq؈=˱PApHAhcBw=^bqm}Mֈd{DDԩ:?x^N(ZTqre8 -wZyyLnK\ ^)P\~؞z[ #i//yqλ6Ry܂|WiMyMa(9GsMLAc<2Nfy.`~v|]^@=+nٲ|裏2 3xߟ| .|7x JbҤI vÙ~衇@6lZ)SFӧOp?O:EmܸF̣G4IbIɌ3rrzoY\hw[vln2I 9?-Ѳ}8P0Qjix9Jx9x(?CVV7jO MNQ55[5嵖S]Qb8|Mk\-,- V9Z%r+hA.(Fpz Z S6[z ha1]-)r }tESIhɁU"Twʡfrq1G-0 ~,8+j8\) 㐒R%g*\qlpߥ]E8w}N:5o޼+W"G&>0`H\SS# 8p`VVrA1DDDY?t*y! Ǝ #ȋZ~sYտ Ρ$^y耉'B ; ? Ka~k ` at>0y:@@@p=O/.n{yqis:S ErTSWŷ +*(%PT}YoP7`SIy=+`\hZ@~z!м5-er1xC)NkhD8ի'](v 8i =TuOW"K/A.Pk1-~ۨ,5g)ӯNձyxE8C61+7}-~PsoNzpp0 4xꕕ ׯ(:d\d-h4#D*ɓ'/[,&&^>rwdb#G_* :t(XW_]`|0eV;xࠠ 4~ j6lX4@ 11QIB"C1c𷩩_G[ N˄~<^G4g& KSmc N9Su&N*o>=PfuogG YmXo8_$]ML0DR򫢳B~ڶ.L |~me<R s_ ~ꩧ[('0atott4UVLI&'xďC H J* ?yٳgC ''';v /ҨQ!믽ⳳcU怀FY)}~ȇ A@<}N^ا.jzƌ/&;|aɽ|?)8={<#7""BJ6|3gBa@j8+5)J2dȵT7V]4a!,;䭭t:}[zBN^sP(^7_oWP~D  A- "ni)@@@@@@pKH[HD"\/`Yh4&''#\\\l6+ n;;;'Nh xD@@@pʇ̼t ә#N  ۶m8!6nt</m3ٷ|3RUJ dd9NRMp,įerE7j9s3 #c|mk. 0ЈݫWq'ƴtcZ[B3%%%777͙`ٲnk{kN7e49r֮]]]]T(_71E9W&Orwz~Μ]0ro_z>o;,f𑣋 +*OT]]߾1c 2̯g98t̙ D7?G?C{Z%z1ۏ?ZQ n/zhu}{j0o6mç**~B0a{ݳgJSSݻGV?y gaH1TF^}m]ZJfB1s/_:x4l"ɖݻѣ ̘y_^cVV_G}7?Bnϴ+m//?GJjZBB·K~޽iioͲ~Z\1uxHKX9'',UPPpޔyc>Өht@||Byy9Ge=6{W5,dz,_e;dZNծҀ(ǽs{[z~v0dGEG775GDguM-,(z.,<Zur;foj mgXzOGV+Z;SP;b9r]Qq9^c"` FT͜9kѢA)cU@@`Xxx5:&'p6'Zֱx.nF&juhM3.h0LG uuu2޶mwx4*""ҫN"A充Ew5oÆ99ѵ1 t82X,fpzΘ9q@6*I8]Pzh^MAb榦Y}O,s\Jf3aGᗇAƁNgCC2l)kWݻSvr] %z8aUl\<}j0%p{~3 6=̊=ÕUP0ɠKwxɴ5t0\b$2z@Fgq]7h #G8M&8Ohr**N@KÆnᇤƆ^^8Mz4q@^:ݮ];TJzMzoSCFȎOB:tXEy9:V+cdM3CLOQh kqFaÆ CKAmHvvhQ!3.vu^H,ΛNyo[humѸw!DBbhQոY NtN;H 8~].`\ op(3uTѣ-%&MK uҋm[Gm  ¡vYѕgi> "m1 vHNNNKX ̚}W׹д{*uV mn L&#cccOvͪ~-cR#VjW/X.x~O<  3/~|)]Ѩ֮] ON0U+>ǡ0}m@` jB@,%}dPW_Wy`TT4Ew~HRrA 3Um9A7ݻ 8aZ.1w9+W|Qkƌrܸa7E36_շ_/ջϚ5GFDum  M =iJ=v;}ꪪ Jfj6&&fҤ)+V.+X#jQ(/KڪʘX>zH=\kbjPYUYW[Ԕ0}# lصkgIiIVVzFqzPXVfVddCl݌zugKK˩h+T]II)* wH񢋔 IS0;foq~{Io/~ {/vߣbF{D?gj~BM(6NEGkN!R2p S3 #0{:=Rt{oRQ-GO2N/)b "#35@:cdLy3C;۱QT* @zW z8_+SRo3>X?244884yTJӏҥ3թ1R .@N-EBQZvmzX*4h~Ν@Kz@+7~"lߥt"#A@-HW3ϝE({ ;o929{fذT7 EFQO17@ܔ;nmmbDF@]ήPxcw^q9ӷȽB8ux6q8kP92Hkhu0.O_:w\٥ޡ[r%x =EC/zSJz Ck(+Тu|3Aٹyg_(x<˺kk*/ v t<Vt^r<W]mեl}nDQrPH]MuqYt:qKae=sUo x@`6AuFH37!w\$f&qyH|\||IqQVMM U]]hpiu ? qfmD >lH뇀 0 R@^XXl4} cڥ7xp8ݛT*;I@@@@p[RTQSSjJjJA[D^5;{M@R"+-~k:F^_=z@|pp\.::nȑҡ+j*AVrJJ:FJPT'N)#bRBއ}uɓ'cbbv{@@"$ns-8 BtlF}%Wk qA+GAAWd:~wkjP\.MM ~:NsJW^wzHua W8) UaXB|td㢍G~Hɂ+߳gO޽ccc0}iiitt4Th>==i $) ł_TT$=2y )7tT5t… WZoϛ7Q&}֬Y'|_rĉ}D'?~+v. 8/kmu*xk_ȗonrSSS%_~oe~G?-Fj)˹>g٪!,P&J I(gѢEMMMO=Ԯ] c"j׿u\\ܨQp/͛!V^z=zs=_x1o߾}HqxP#2Z֎ա|7B BLny~a;~mnnF!Fz Lv\I@@@ 6FNM̓ w.}Psss0"((\Y-++,$$$:t+%ǏG 6l@iH|ڵ{5k~T|;wKGo~?Y6@^פeRH(Z/w .% @ 01xTznرc}*~544@v:vӒqy.>D"-Kyy9h`_|ʕ+kjjƍ7,=x466BU" =++ ]f )222#)?O֫W;v[Fz'Nq(73@VWWvs.y<7d2Y5 lP>TbڽE={ezwyN|~۷/Rnڴ >l\ ׬Y[l={y|iݫBO~m}t7'AuuuqqqUUU+VhǗ]NwIqCp@<J)#++W_smw?sssåiimx(**3z!G.\0""Gu7x->|xhh(l~j}oj髫kxg7n:7qdG^SSS__Czcc.;˖-V\̜9Rj<޼*rʔc粰0))aoxF3|[NJy0|4 k?iEEEAz)_ӑEW%%%ϵ6#22!??{+*N~=ѫI}yNgrrJIIB=z4G"$2uڌO?{:`~N] ϋKt3o7%2p TUUEDD(Jݎ.Z(jߵ | w9Xϖޔ_u0컞`Es#K}֝;oۺd2,+}y:>T\\0f}3d=ϰJoۜcp:5 %>aYSWT 麺,@uu`Q^^q|o BwLsypRgl6}\UwbcB rWbbb n74L]9`tqo W+GDD~ŧ{.sǎaqq a[v3l6цhi:EDFE"../7a}BBCǍ@hH%>iqiR=!g\дdHHHIIRDuphp`h#RZ0!!|(v;=\ p~!w>җ_[_ZK@pqY#G̝;_ $$'N'Lw͙ˎFA`P~)'Rv.ak~WK/H> CK1!A$qj)=bFR۶m&/\C[믡ϟj*UIɿ6pU[,Hjonn6 8Eb 焴ֻ;88? ^~S5l6׿N4iС( JPRv$OFy@dϥ;Uy BKy@p1q#s=?c׾TWW#KhhhJJ ׏?+_=ܹ'?F>_WcƌٲeC=O,]`&ŋq!?'ĥo|iii>A;vɒ%{~s͝;zgPګJx/p@޻X }PQQ?/4vIKP!8/DvJ U²f "zUSS#kZ .4w?=F8iVYqm `}PU7'{)++S*}ꫯğ8q"22SZZt_RQ!D/[ W׈#O*v9s#G|^\IǕs/>3 C".wygȐ!}QNFFn:?HCO>$0 --mѢEQ/k= =ԙ~J]1G)-nNH.bpCJy(MIpҙ3@=ukPrSTe"XAUx(O*q2 oZ4FEU 7-?Ϥ0LP‰+i޽cƌ.oW];va^u![CCF.i^2p@p\s;hT J>| N!,,kdddϞ=l' ]bbb~K!2k׮o?1Zz5`RRҥK$}pؾ};~Ϸ/ORH4-dspF$vǍrGH1P K:?!0bÝ@ /E׎1D $|uEulAP H/T`E$bbILy)/11gLiFcE((J/Jvn6E4zܹs̜)簀ll k caCIEh¶,cLXk?t>(ʏ!"poC0''{Y7o333GG ryxѲm``Ǯ:<:$Br Ouܠ[;#4 H +sR-egFl 5HgCf)σ7Lt/8/ |Wg@@>;&8?7ŀ _j۳om{ݠJ?QYY= ůYtgha/Dinۡ38:&RPZހ_i A\X :V̒Gѹ,7(3ekfBX6UEr @ >Z|ȑP, KEE%OOkK52qݻwѢE~~~MMINNF}6_tVb{8ydhhTF7݆t~T mq;.QSd-]jM;w쎼|vy5؋7K=:ڌ :ǰ[Di fq MC())rTH44QJj;Gn7+W Ua؄_n۶mƍVVVL 3ѡiȶT6Hԥ67IޑeeM<lv濄 w,t0-p"C<¶&0i@NN(1yH3|t=&ʃ~J 4O}TZZJ  tNmA>I G_ԩ^9x{{ wuua9t2ߔ 5 Е +k `@g@30J-,, R!nܸqu]]]:}?]l K7T,QYukjbXK#kaFX]q/ߝó O(r ݅P4Đ8 P{Q\| @qqD`mGi؀<8.'! ߺu)>BݥL(ufGg[^(#of¿44:h{` m8x0omN̈́3mlA``̈́3m&lA";X=6pe%-&]_/bM0'rpA:^ڵk8`ccgDCņ`8~!SuBZ2)9!yq0)I@+mPhbUJRX \P?6-9BEW_)v퀸"$1}Э,^ 7ǿya%i!-/僜" 0?1c٭6c@ ^~BDݞ\_]]]KK fM\\N,K$رc8z( >555!hCBBh7UXyNHI0iyFUs釬: Rd<ȾG|%уЕ Љh=[ F5hXXXiii@~@\ymI-YyCp>F! ʏ.I\ / ?=Kke*LEi%D`#BY WJn᳋'|D &Ѝ(7C .sQ9<1mYTTE¾sΨQDڀVCt#-lM.]JNjT>%PX_?KSRj`U} i{Eᣇ1Kt9/g Fi?Cgff"Rzz:-ȥ-H_iA_F.((8~;7%nɤUU13v0 Y2PxM !aC2LlϋNY;s`FHi'3fvݒdL.:<1bZ?ZFdd߮222RSS,#Яn ȠP#W]B^{#OOO96Bo@H%$Jj[ 4L4zrx r[TT J.4x \$J#%ȟbwٕ t2dJd C ZVNZ=ID(39<A'''[YY)//:x9VPJXCU(0Ĝ;8hǏeiX,cvճuY뤳}|X 14F2|0!1@~ %%%0$h6x9zSpctNLMMiXaAǫV*r%[ZZр 8A||<:+@ߧ)%%%HR 1eU^^ &{y`o{x ޚpiVMsa8JXK/5j˼*O\U9yhBxOm iii`-\l!<>-@4y9hkkKz -!̄vG߶a bp)dl4af8<(FDL-@vvvLLREy;޻[&O/|;IZIbdA[FlA/_tRZ7,^:$L{{6qㄑƘYy9OOЊ ^LZ^D,h 7P>bTN+4:>A20ۣCٳ>>>O~ fLsM^ywԩS;v(//Ϛ CKfl8c(0jt/^ttuy`ng2^%c[}.+jvȽv$S_7B꿴^^9U$8 itN0*++9h:M<((H[[{]6 qʔ)҃O0e!VH ܧC0A囙4sssYfq3 jԶi[ ӻ. 6<;͘iFHTd6_U[SMsOўliC֭[c6yclǛI8^=K/k/]q hjy/4dexPbrO.***P4I < $%%8!!U!yyUVO>="ĉ;6 "s @Rsr(a=BrŘO t.L))9QJQZ<z0c>qɥ6ӞUhEWf&Wc^3I']~FnX_ԉϜ{]G3v?XƎkllL]Gdq>l} j O/|8Gījjjp'9<-tN2O@PȄW@:ؔ׮]Ky9pgނ(SRRBrrr233k/D^H81ɲIe2eUQM^g Fچ@>qdݾ#w8/q޻wrɳy[*Y;wo޺<:77!5yuًK.5cn`(Y8#` +7qL MLLtuui:{ܠ;߽{R% V,2=à蠠Ag*WOcLsg|Ќ'FER>3xM5M~ V" %I%!Nӝz֙aAAAkzUyyWzY9Dՙv/ LfAiN?q:x4X+Լ#FDDD$''NꥨhggWRR'1Oon100voQ#JU=x(K)dׄX1+kkk$PPT0wFьA?[(ъ544g;4}sʕ;\|y0ckxNK F_F@h"ݫV"909NП96 GVUU8qpJK˿Ml`h>hPfFI>#OT?avq.C'i/&H<dx#lubuRR {"pGڑKUȅ3^;V,rxpQ<X4Ow{bVWW\9eM _ad,ͅ]_! ힻ[voKm/Mi%E. Ѫ$m۶C6/ ]f0 Fb p Ċ.MA^~:.-- 6qVc5z2lhkH1#qz'z>%O555Č?D)#bz($ 4!a#G2*Cm{y7% hu8ObbbN%{Rv"H᭙;qJl=>Z'Z>v4oPEjon_u}Ubն~# ȑ# 044Dfff cƌd=Pxafm2!!^SS M)S&1t3g&O fJvx͓{E#22r|J[Id&n8Mc ͬ A`ÇC1݇hB*++j$8h]8O)))aro5ۿҺDgn@s>r#HC}||i?޾s *ݜ-I>>Ǐ?y$ȁՋC\yM֕[spVֹ3WbEhfdnn.>SRR3o XXX0~Lp]&&&k׮cC|zyMov@ޡ[K%vS- P-©ҷcmT}_jmF9&<:G}Y*m=P=4S^ZZM (B[5 w?n˯^{ÓZȤ#P2}l cjȈ֯LN@+:MwέNs(R W&<;=ф3(8tЂ D_K[  p Z9(**JOO KKKA{𡻻;lBU̘~͍c|OAAA/cƌ #Hk!iKPaaaLNNnODeetQ/_X^V>~„ӾӦϸp)!>~97oܐ?668)1AQI 55+iLMuc!+-UQQ&~MM 4. \'|ڴnjcc#0>pX{ctCOǽm8E79ړ\4l][<G'z%OMOEվkWr5=tC#+(0 Q<cLbO땱2W bbf4A6D8WFff&LI0A(a~Qyy9tYf=qGC+--FiӦpC 3gPoutxz$1)|67@f)))+*(656k(**)**ڻw$764iik)ήo8@QpoiZH!hh~***hAЬ +77jÆÇ_{mH#_a⡷JP7Ǽ}cSb}:lYKC\>Q?tL cǮ޽zwۺmo10xNsûdՅK2dCa>jLJ@H$zڸ)^y =GxYJJJDDpٳY1}Ty}2O;88/?]._\YY֣]Xxk׮^uwwgf/;:ijj015SSWEm)'/'-#{1 ph4Bj(" @;GsÓaxk۬j^~ƭem\ 4MpZ"4_|tX{N{kUcR,@MMM?!!( dV7Mc[Ɗ"7A4==G@Ρ A}}OA[Y ;ϯtȑ +DxLJm|xWL%O5f%{Af!FywϞG@ͼ=C"&N< 6O_KW\ 'x̙3555Qa%t@Յ>>>6-f}UJNB^^^ff~Fjy2(fNs/t76mZ+O7>d7dddF{iii9S ~DHK.¾utrrRE̘1#X5~׽^(*^)|EE,"q::0rrrPU'=} KIIAɹ2gΜ7oC/ZxS-8pwWDF#3f0!}p* }V=#C n߾M! .^8-$$d"x`?ͦMwўm%%%x̬,0| PWn5_o_ewBaGIKAOS$4jaЩ@g'Nb{ܹe˖9rulhhĹCo6wc92§!`ٛepON|c@#dnnE!qoBĀFxyy?fʧ'3+¯sG ʞe Cرc>LHHv횽=hDFF._\DPAM6΋R"FA>HΩ-wިQsyph4{QQQPQQDW|jϭ"\eee9X(|d-/CeX[+jh( ]uyw\*..n儸խe4iAzz.:thG<6޼ys >,w[+t  `ccRׯO:{nc\Z\[~9ۮoozs†##O^#輡uՑC XYYѣ@3fB|e$h{Ѡ"544t}}O ǀ}-|"Hp J%) eB<7-r+]f rrr/rd,ZHtɋ>yΆoĵHNNF8qb`` zD=^Ι3g_"L[1ߞ`'tի;JLP_P)u|^|49IA||sGGGԖ6:в,EEP{{{=JJJQO v)8tAAQ(r 4\llo^ZĴNj? ޝF6n~ϻ (1H؀!CKKKA«Mo3c:5!qb/<.s*Gnn.Xp *A䋐ji9pBƾ 0vz`nw*+/xub߉ @X ([?pzWDd 1IߥK)/e4|"D&&&9>p@Š9 ?44h۸Ҳo~?Ƕcƌq-y^B-^Gƅ3+pn8p ƥ`|0ZoAٲ-01W4`礖~ 4E2 !@.޺?9`&+++ qߊ*nW߮vי]H '2[# j accUJYn<2ͫ7=7t{k}~9)qg222(]db22 ε$0t &ޮ]E-))t422RJJrCOP^^NN5MG"ZD.'ׇ؝;w_XzIVmu^P?Pϵ=t}^kb}fM32,.\?x fL"15VU9:6ח$_}0jx|U5_,=˧t+jrʧ2" ~CZ)^5[>>".Yr^ 69$KtBVVV$o(mmw^rCUU5888&&fժU`Frvv}D¡}OLC w} HRu~1o߾~z~uv2ʧȽnXm~Q"3gԠ\ݹU^v sdʮd !63511 χ=G^Z0QW۹oh+0fPRsC>iZ "*2_z=Ӱ??sW)<3vx ^k7+ZBA4Ly7:mm0''lTVm)ȠRRi:^PA䵵uhqq rVP>~ذa |-BEFFqޣ8@2+hTTTҴtA#%%%"\ݭ[s>|X7ܮ]> ~1{{') x(!/}pa} 2V~ʑ+45k:ݜqoUwߺ+x_m LCWWW/}1.S6"vP7%A ? >ٻ% @oD/99nPL)v3U_GA >ao?q@KII)((9sѣGmmmWlKKKitBtiӦ@ B8FDD$&&A),,ĵ֞-|-*.J4SDGُD-,+P!Ct2#*@U>FII Hg㡜\\˿eҢ$&wor={V^^>..;}V&Sffې0~?f1I}VVx嗛7b򇯷̍cǎI调 H)'[k'?qbEjhhOMC  9keeu bhkg[N)ދ?*®iiAjSFJ )9qW*++ee++ZZEKr)P.F_v @=ëS3Jf&oܸMq8+**ФИʔŤN̙3yd~oOUNupxoS7gF{Ƒm}elޒ:h*T ]lepCv`vŋߝ;M( *F JDM|U*@5gB.^(-= 44g<<|xtt4L| pQtQ؂83xtvvvii vddI o&k4`ŝUz-*8hΞxKV,!>&H%=z (θΛ4y'An}5`O>&- @@S:r@ޙ3ڌӓi}cM?Cф){bCWAH~?,*K|]4cff z;[l ]j4wÇ _s9Db4 >Aܫ \еB&RRRөw >0n~hAee}LL62ZM9464WvynV33\q=DPć џ CF5P|#/nx:.RUZZ uZZE-d+))QSS300y&# @Y/YÊ"?dx_SoCYYywR]r7d=t$o\ąeeeJ~5Ϊ)mnjUY.]BËrtt}6ytt]JT~~~SNӶq߻mnSg&ıMLW ڱ9~:;>1h_~;*޻[AAaɑ#/X0U߷ފڶmϘ5K0n)at1h2 ,WVVC O}CuV؝$u*%%b yƒ¥>?x;vͽP7,4ao3&"B7|P C"+X߯vkέA7y߸qڳ S3sMN&y:33 o +wѷ.ܺ3i~8u)SvܺŒ52Az>rAH/tN a sΞ8t跣v)zD>}j7f۝nB>XCBBi455qkƌ~~~H6a K.I\zAgVS>4w~7<[NSpG,+//ڥP'};2}n^;3{R/5~:) ussCkנa&$$% ~ {lw9x5==5)>P999EE`oooYYY(W^YtQpm'XO:N8ƏP8y{w#hAqڊk߱do^O խGZɷa|ӧOA0Z]"+甝c͞sM6{ 0G[22ё[2CCXllV_˜O] HNNs͒С<6|CC={v+(7660>Ihqq)))9ʍpx>@NNv)8BLrdUn;[spC O<o}w;?Yui `(FDD >… &L 322z^x(l]GM;ud TH;NǧdLIEEqX~> g] A.Q1j/] ih뻻{;w333WW8|CDA7U do[+*S2..?E] ss&żZZZ_i?|YI\ᩑ]\ܒaÆӓh`Z2],@vvvK rYGR [TQQ0cccVVLFGjkEYf&%451n Z"q| G5ʁ 4?+-g-%i@g1*{OBAPs P ܴilP ȞPPPzoNW< fllOmmgzWJ^QQQYY؈CHC~]{ìlvСn,;áƠv)H1 puu <*]ʛ ;7/6l`YYx"tNlmm3r$ ɰ!}||L%|={ՁիWI@0s)]ח[ytL~X;wmJJ (KHMMY:E6i;݉u81"9u|W,7{`vMKO324j[HPR+""@php~8 B׷z޼y A&WmmmffKbccyIG0)}ݧ(b|k֬yׅV&My9 9*~Oi7-[edd(++@(]]]<ࠕ' ~}rb*gŕn?&tBmR|WCTDluAAA`rrw~~~..Pb ʡz6lةStttoA0BKKKp GG{5 w7pA8:;ڻwAghEEEO:B}SWW9nlgK>1iaacZZ Z#Eפ<4-m~JZ>kbwx~,Em?hӚYk * )Ω@RR>/ y,**;wU:Ά3۷oAݿbłܸq<̙30`߼y)(F!Q|윾sgK: a'zǃ59]wnT@`ŋk!-޽ B_CBB!zJ5tP\6rHcc㞿 11Ν;P/ &M.??ѢE{]r%NG/s۬ş/__BYf[Wߚ2Q ą6hΩ- pppx"z" Asw)9lll(҄رcǍ!Ch31S37+CЮ>o RO?s?{3sF.^B]D_||!E&`'N㏗L:wܘ1cxJJJF!?€GEQAA.]ljjZ[[)o{ez .!h>ey^#5qvVQle[ë́&&&hȄ_xJ]@ zJRWeK52Kߐ)(((r d'ɌPOd>BC,wi;R )))RRRA!!!HfSTTb *99hy߿N60, 9[{=z_=)` MO?cƌ^iO{ Q[=S/otN455cccQ[h46""kN%br az#)zlZu5y'Mtv!CIIӣ=ڂ9rҒ\;;; 5Shh(X5s_pŇ-5b3Fthp*op'^o}}=ZÆ ۳_5 j%n&Dӟ8qk8p@ɸ171e.h+?̽3l5|%qh%KLXчa.YD&L` ooo:›psWG[WWW:633Ǜס}7~h^^. $7nFgDK| 7 X9TԌ,1̚E?u@II`bDֲ{:M+K;Xv~} \?n]: l## y+x4yoxҤI.++̜ɋUX]]moo{BIt߃ RrllZyngl***frm ټnJC@j{;Ŵ_ 뾉ܔy&~~[Ɠ"g%%%nW9@+..&.^^NsΜ9+!!!//7""$s?uxa,-t[cg4 *--b|TꓽZxϟ}TīzqR bQQQmQƟn@}q@{Ω@YYxxcRRoo0ѣ饗^۹s'M0ݻ'/)~I'|f[ӶrEEEX,,mURRmz~j,m mS滝w>mTNagdaJDv{ @OХ A$Ќs4*NH.]*((xpx)~s,6Ѓ&AΌF[[ VYɜؕ+`&&8aalv:/fkOs@vEFF4<{oT#>\UWX7tX,/ FiPﴟqqzΩtVVjffʐ!C߯`߹$ xyy]dUPLl5]L?]:ydo>4XYU۷yTȈѣY{*++gg%yaqx8zXi{g-:r<:UD+#tNh;GnnzQ \AXb嗗ҁZ|hoo_UU]XXx?ԩ<=a¤ .33 R77L+5ɓmc6~<ӫCUUUgϸ_wXGxV]A>v<#:\\\$ 9|cѵ De??*@ehhh4hAΡ9@T(==3"Wz׬{ܼy3%%Boq6`yxx9s&'';v찰O.]511'ڽ{Vrr2/VV4455 JI@.+++-)/x!zp~^^RbKNNNJ*555ʼpAŊf~;_ s3 I7ՒI$ ;CE}Ɔ +_6kCYYYZZ?bݤ!d(%ś6fWJErh#m91bă̢gLXWW4]n P@ٳg 2 o>T%=x};;;ka 4v=ÜkjjKЇF|K`aay1JJEְz-(+W Cii) h9$I nE9{ ZYY  ѲiTu׮]GEW>cŊt`ffᇏQ[ٳE\ Ҁ_[~YmN lm] 8iJQQ!^ wusGDzMM-L䦞6^׊ h:1FIM3n3nAd%g.cx٫+HGNDمa?L:`(((yWn_`i& kjj"7niZ9nɡ>\pL>c(n,g-IH7 #jgH VVVSO|4hij(pn} R,VPt!BxY^gͩLBúo]UU%1RZs~0gΜݧ-8J>YЉ3Af6w8p k?ئ23,!RRR ղ4S'ETА m+ZMXY 722! }l RUdf,fl22`1 VSCȴC+i2=--mǎk"^.PP$Ez~n=|_eò6)24}ZzOn hoߤ&,:E=n矉n&DmѶ<͕P2dHAArKK˘j(y=z`„ {}N1\֥xyyy`"A:uuu999EEEh &&&6:nn-I 3gDMV>grKŔ\lw,%ih0s !!2=f...kM\+Y,Q|U-k;H0K h|srEo| & "pw^~#[*`HQqq1 HԤ ,c˾aߤKwŻ0:&h: OΩI[[bb"- #ihh6E߿!!!rnD- ]M 46w 0:_ ?+l)R6of1pL#I+9BK^z҂=פ7abC8[B>{Z ®.*-JPRR u3iCC3kAHGBGXATX{$jјhbkƘ`{ إHޫŶ>Yvgggwfyϔs6Ur_s Oo.,8O@PI?655IuuN7Lxɮt)//KIIXPsu* M^Y~9299sy53@gy'`0;"??,#RQ z&u= ??]8ó&򑐐k706eTa)sj'<@}mc:={+a4X` cR`-bypeggM MK^Ų*$FA(L\]{|wGFFvXǃ*+sÍ9ڵ{d[ '}ddn***YcqA;uPBBt_dQׯ/\pvot|b~| 9rt]]gqPv|n9%_]z'ٹrc}=|UUU=x̙3;Px'TU]8{^1~ T >> W^t .rNrpxzcbbϜ9dɇ!!,x뀎t &DFFZYY2$$&e$ˣGB3#-"))yH™¬(/諨YM>/j ) `A-rrrh4&@Ff>Պ;w{xC|E*I.$* r3bK|^5 ԎNoDikkonmjw$tK覯/tn!V%%% 4gtGXO >|haaM# oFF*T+PZZ*& gc3sYYYZZD,(>(A]|n̤`A!h*H`ffvС/bT PT\$ޫ'hcG4Da}*"YdAW@?^BɼD[fqW]:s> KgɘK/^C}&8԰?[녖dei˾Knz[Nl&$s SVV&///##SPPУGC&{_HaޕtOʘ1cw'?$u׮ݜ]ETtC@@tmPPt'Nq3g>|)!jT_ Z]]9 x$4Ëinz$%'e W._Ԕ}7i*9<0`wth't4^]K6>7hx"-U>}.!΢un6Jέ\^k=JtutNØY6, R멧Y8?ڕE7jkk3)2eE~.]7@ X͛7oJLL~E9J g"55vBYYǃFЩ_^gpXOC24-:`U,C㘘‚B33O%i  " !Ӓ\wq9xp!W=.ۻ,I탕՟45#|8f3Mӕ/w_zcPqFƫe$kt5ectH, FϢ1лmEW{xRQ*r{ȑ#[kJJb@5p0h.M`ii4ΌFrs{2q,segulbT V re̐\|6p@P dmn޼ٔ Z]:'vi+m׹ #Xthhڟ, DE8BIljRJ $kprX[nY^777t\wlm_do'Miji?NڵKIf NlbaAB(li3_opu˖NbRL/ѭMgMVViԩ)))_v-tӧO񔲲2-('\s/ٟzUGV7lwSt1eTwP Ƹ9ɼin "?ͭ@ ihh(++YYYt $K .()CE}TF;wFwt6H9^]]--- ГMLn .,bv*9Ј}BABP8M'3{r`^|¢i=7!7o\"|0PGô7n 4{iPAxjn>v9P EGGᗡӧ l>66],7@񗖔(=wg6H@`BcnΎٮB˙KJJW1R7%W\Ry)Y"h_kђ%SOiOϛvrk<  HIIo=H1l&\/"x YoiaK!Arn$iv@F^>f cٴa޿ޮz%&&&++K4,AV.Q}u$d,cssW&씜_at| U&)c:^UU3*@%bXџsT#=i駄/R&7HZ+_4-RnݲMs{D.-'YTŘV$9m3KS0w~1y}L~XܸqWN,Ahl^(B竼x_3 gDQcctME09c{–ftTmm;6R,Q 6H"14ͤyn;gxEA z1/yϞ=K,bIP]v51## Pk22B}Ϳ_?__HTMY0hj ǁarr2tDߦ @ Nt}ay؛6Hp٭[7^ :۶]RXra| }B-{[uΝ;]ŋ/8BgDQIPbG֌H_TUU%$$<{ vС Ytu*.,UT ڭ[ǏqJq9]?66GOQ lբqv/6HAP芁i8uoYĻ{$̘1cQ Q,b)tUP*ܜA.]T?psf,SD}}thHRppH^^{ff͛7 wȑ#EX``o5ศPQJҌ:\` zY,++iqWWbz;87>>~-ž= b,(!.5(MbP#<`vȱ(cc䊊 =z0ĚN0W+2Re,ƜQmaaa -g@+ !CXZZ. :|UŋO7ƏhR-\6Y4R\XP^^Y__WYQSLBgP3Ewc[)@s"~[ݺu3wWHk{Bhs_Ĉ 7w/_NLϦ p\bffň#|||?~bccҍ X Gt9'YJ+!ee媪*E7!z&... KͺdV#9{yyZ͛gƯftt4~NNVLLݻ7iҤݻ`ԨQ轐ѠwϦ lmmoݺL"""m3K dew /vU[S=p .:qY!28U999EEE{d~čRo ̬씔$g%ŖVEEE:3FBB@rrJQsxslb.٣]ahf'&h.3TÌwbkno\' %%|UT+s+!!annnmmqѣGSWuC4 UJJJPhӮ׎I#)3 @C2kYt2wެ~P~{e4x@ˢ{l0hq=(n=33q F @DVJJJƍ%ԴB|י*WMM p&{S[[O?~#Gkhq.Cͭ3AE)>,: 6, V 'h3,d #>;~p%,hSuG2++ r}ob"* Ie_``ر;v:N"""=579sOM/{ccczfƌUW[gB; n1c^koμt ZJv"+=z \]1pf 3:̥uXtU4Lk_x:=H*55*@b#+TnDxy0q,☇ l;xj'b"ЧI+ڄ]rs⍽O@E ws*'ʀ@ Mj5Ç߹sGEEOx!`!Rt lz˗/)[oo.bE2͎DҚz5;'jP[[~ee%p //… NNN0.\84]k-@AR09ڃs6AHu_UII U:ϻ8 !%eTJKK^q1䠗Amv5teMRO>=}UV08oT4X۷"@cccA=zDM }}}111zlccMMM]]݌ Хj7yo JHg= 﫩´F R,taxu!))IGjjj =6ZP\\Ree%&&$SЊ¶Lbew]p HHNW(:{:&]AhrbEG]@.fB)))漜sliikkk7:`qCd}xݥ( B]5E=6 YCCW鞂th il8(mPbb(k]\r]UHy%[h=1_ptjo{/!? ,@Ё/XuEK`!`{...煾ASWWWy!%+tl,--m䆋 KSSSSϕWo&mk֖F7Kk p,###pSqqq0QMw~?==R3330*zJ-TWk-Lh\-! mn|]]MސE9[nx޽9Ehh)SO<9o< XdFq&̗ꫯVwYF²/d/[*AV;՟aEi@V_kkk099$;wu^{!񲴴> `"EZ`ޱ cq/5 aL[-Yb٧OF9>@oh7dY.Oui8"0000++ɓXXڀH=SG&4#Ue`8v&?s;o휵(ۼb]~sΆ a(++ ⩩ (BQ;-`Cj)' L]q|S_bbbt]8LK^b7c{T yttt9u KжPJJJ!!!ramR. R, @m@tTTTHJJBaPGb`u}Z( ;XwOҞ˿89ޛ4^rr&Cw>|ڵkSLy&`?zP( o>|ԭO?WCڼ ?ie Ò" 3mQ'p0^h _p8ib_???SSӢԔD7`ʢ|m R ʏ.>/"3g,)))T Z2(,,թ]tuvVPWUfcA~3TTTdm=籟ݨЯk׮MՕ ,}G+V=4c>řqf_7|Th;x/x 'O߿Yuo :LVV\ff QSS8AQ}}Ȕ77oY|BA%$$H _)2REW ෴xڴ66'Nfn1z`4&s+9C5^(9ޢQDYNq&z4Lfxo7[fd^"-zDUrg ?`y = Rf={)("DFQHD&ch $ Z6ARCw 9S}YE"77ݻ8@Y~j~dϑ D3`XCCCh5<Cikjj`iii{y3+Γj1ฃB|.3e@GAFav3jkIpuM8i$•ZʨiӦI?xTEy"OGOx[+_FAA8*ͽҽWwa+|b Uwa}mnD$mAA#_,:T(==N 2Іׯ/^vv۳g쀀8pH=A+"5ҙyWQ^^&uvvmӇXYqq`; ))90UFln#y~mYYO֬d`ǚ1>>zW䫭dkxѺa쬭aP6t!?§WS; tAƋ 2 :NqC#C=C=k=k xzWϿhX6<&ԐpNtO233utt*@ZLݫ[7BAA!(o'BD^-3506Z%tԝr@|?tw- <9e=Y .Y]f:v't>c噋oy7|0[_$.]W#R@z_pgNh, :IJJJxx8x:o⦛ uugggxu+ R,EUVPPi߷oߢ"p {ԼCbYZZ*''$G`/ w H/hh ={DcfǦNZfoÚ4g;w`DnDP3]k;hVƟ 9y?qiiUPdI40񫤤C8p z7>8]~m``A1lذf}WWWo,HΑ* ?q+B9HG|_ STD.u)&`zQ/^3(,, ԯH_= Ÿ*ぎIO qqR!1.!ob܎Juc#MT %߫,: hdB4 >HZFǛ7WLm@@mQXհ.mܿڇW鯣WNj{T)nobRʽ8}@(**48ٳ~Y~E). ,K|oN?O[.r[ڟ}Pzfs!?G())ѝRRR=5* &&5&/7,փCt"T 2)i9_VVV^V Rd033SAAt_djձ+>lք Ǘ,qǵd-Q |aY',ǝz} _ TouO׭t^يi>S8tRtڵٳgFfee3qԡh޿leliIK3eeeH]]])MAΠ0qݻwYkSt܌n=;D'uѿB1^7%20HqpppHH8u~~U^M)4:?m躼`@@+KڼG5;+]R%, P1-ZgZ,bş={n8a3uu~ѡMr裢~Zjɸwtn0,3X:@w gdf̊UI%riBgѭaG٧{5)ٳG bz})UI-nǨ"//.&Dz)N&$$8SdeϞ=ÔXt} $>;q$M]o~@ ֨/2 ///?;6qDi===SSǏ'qr޽Cjvv6AC$?:@'&&d`jjjVVVC p96lIPP#G7Q0@---_`ZZRrruuk?\Žc@C#g ahҥAr[rd?p'i`մ%K/q+syy877v^J\йasܑ%BS>X4H1jw`F2FvUUMMH|B=2:zȼ]jjj`e2`np$ gbbQ0O5B;C1J߹sᤷ7 C@ QPR-++ "3g#A@@@uu52X|2rLCkubbbFF:-;tt P t/_? *:&jvkZ8 EѦP]][_ 27 ndp[ iv/?~be-|͔)S@6PWW3gn="$0W3BЅt!.ϊ'Hhy8aB+ BIR??s*AAwo|q]moOpնUm*@ >~#%%((pfRLCꦧ$qF8.]E"%%oߦ>>p@Q8IێA&Peee.ǟtK:s  2BPpy5i$###~ff4 _~ts)4 m9|;wl/L K;b%\H eݯ '-=745c6Lr$- mގp vr4?K',tt|T<?E*t}Ir qo>4$ .DxPUEG%0JaH *@f'dՅM^J Z0oݺE< //$%T@(.'7aÆfy˜䣫 Zy<ӏ7b?"77Uώwe BqRRұhm RB@pp/_y}dDXo ?CǓɠ` 2gbrv۶?$t5%O|pB->Mo4Q;V|a^WiN3m8ĩæ *++޽ħG9lƀ eUϳ>z !t-2d+}ݔ)s]#Ј%%% jtDcH,, R,"lhfX6&Kկ֎ӝ""b֘[7V^:Mu@[Ϟ=;uԎ?XCGmr,YX[[ӹ3j'iaĂD }\[[[^^ʉ+..thijj6HLLl9Sl\z%4#xq>~+Jג ]8w[Ky<%~ܹsf͢g([I - {ë3 3I !dӥ.=]L 1f }C玟K1g:!>-¥x;J;M*Z5[y4zYYY;;;4 8quѢgϞtE\_aQKh< Pm-%%EBA1?d׾' M!d= _(t O^>| E1רco t!ؾ}{333͛t")fn440X-v!±;IU,hE#n!XtMJj>rj%6u3g>XL@c$:t]`` $$k3h ֯k#a ^Rvρqc ƦB k{;HYrr2j=>>|*Zp7nx{{O4)??-c̘1&&&>>Wyg|h^6l`'pP?9PPt gF-CM@ƊwtY&L9s&~̙Ü:u*~!:be2>tUG#v}qڵbHXxziz~K )fآWdKKK: St3!q2{JfK:u;âh=H1v;9;Anyseu%ѣG%`4`FKC`$]ZVpew1vj)< q]Hssׯg|葵uDD>, _'QUU Q]]}y{Xb g˾}&d{KROt!wsn&|; *|۾}{~K!1-Zt鬬,??|777ʺu디Ǐwĉ:HdH7"&<$ SŅ(Ps97qޟ 㳠^̜ع p (Q KaT>Sݽ3|׳Ϟ͘1֭FP! '0H1XB^F&/jmT51p+@N>٢WC^@|@I39~{!ό؄U@X?{ %KW^{edd8RF܅;⠹!D`@$FdxEKa脅Q4gB֧gpݻw[Y M_6 f-!eCt[*@nǏzץ[3VJ?r[EP!9oBwCυO<cii*p_#H(%%4`6Lf=Jh+R *sYCCc׮]!b*СCGϡqW rP\\µ׃ApZ4fV߾}oθBI[[o9T2a ,%SLnih 9uꔋ XHZZ(N"4<.Μ9 Vmذg ˹9  Dg! III+KF]xM(A>5 4<Z)$]WK9\˫g *lymh8@nItq E.XuO=uԎq\WjeeaݻHst)eEt¥:-Hn@ !N@&Bg#ә**;|0lΜ.\HOOFL& @ ;'\yMِ8cv6C/_CV6I@AmݻwE`LtOy|09J5@G#F`RЁ9?҃UV1',X?93Y)zxн{w@E,$Wloh sΝ6? )GG$h6p3,}BHd~?Y~r-_۳n I8ɸq?'$HIVVSHI?q}X4go(&H12,-C &2߅{zl8US祥vH`z~:3~((+DY^ޔn,//Gࡸy  `lZZZte1a XtST t<Fe, 5`{5jŋiߺuk>} A"##'NellqF ъ >|=ǎCJ0w555|:pW[[K}zxxݻŋx.-$D?t3f@ڵ qŊ/%deeM2BH + Ӗ-[ xѣ(ҥK\)i&xS/|r;w/6Tm@-WUU1^Z 6x09%umurGu'[#Ngjjz]4tOOOό 1;;Q;d=}*bfff ъWi )Aaa!JUhjYɤH<58Wfq+ H/>C:T__'Ăύ-++544 E.**022F3hk%K@ X$0Mx:SKsX sC۷)πCBzU+WF [[ۨ(䀓(ѣ!mֲs$ BK{Lo=ޓ'Qߣ_Eilnhz RNN? *''')4锔\B/9rd@Ą\Lk@@7$,'2!Crrr+><<12DG{XˍqK*3EmQ4,9GCЙtUDgۓ BO@Nn:8677 ڵK߾.]5ER,DǃS*+O* ߿DTjuĈ y0iӦcժ_~̢Z&ЀBv3DCe+n޼ Nx}m T,o""(1#oi2wnO  })j`tpy Ϲ644OBe'k;>,-2t =/!!>fJ w޽ɡC=s,:AA(+4=gbccc$//c$#еPt s"nJ9㌅ŕ+W{!>ZTTT J Fi>U#7D6GK{Qݴq)999xиqj8 ˰Z43, | :z1q^RХ {ԥ|bJ&$Hʜ>=ɩ7-@G ѝ ݹ $;h 999,, G84 |?sA޻woժU.]"1:1u ˀ" >O>N;? NUnw:ɯ$KZ.H*Dˆ  $ÆWZ_$ Q?8p ***222bΫ~*ޔ`~Y)=N GIʖsJ׵kWj1dff⮾}wѸ8QX(!VPPh ⯦W6k꽘.l y"sr8iggg$] 4;񑚚J'2냒2_}PHiإ аĘPmr֯_} ?i vv,)wf+,!zt> ^ζ&FWsỻߥz'(K>!bV8 GwLp^ BpoYIH P^N`d>~,e6zƐh낀Asrr?>dȐXW^^*n̙O.]eccs5ӧ#[SSShӔ9s044z1c~_~{„ Hxb\\Xr;p#􌊊B[\\ƍ <ݰaCAAA``ΠA 1b${hh(^ e{# Ț䦦~F2tPKdd$ݭ.];vk0"$ذxָsΧOݿzWfl_K˖Rdm HJJy 4x0D }忿}[֮n;IH1!e+#?z"56N׿?#jjg'^+XOih>hhIǏ:99XZZB#///?ho333сaCp#eРHNbbb`^AtBU0 CGA,(8qMɥbCCBCXYY0x9sq#=gY3Hƒ|eAD>}J&ٳ*PÇtbX&)Mσ8ؖr߾5ujJYSL]C]tࡥ{\&x q+ gAss}JYσjDDďb~"G^|u&%%tfv[T--[ UKwMSUO77RS[ҍpIČf9O*++tS +SUU ꧶s!hQ&Aw D%5@ ńʕ+H& D4:ҥpKqq1ӡ~/T.:3MÇVl?xݺuӧO?uĘ1cqk 2:F+Ba W1h IE6}SSS GBHXgFZl(x;;;0>Df]C222III(1Py𡦦&D455įI<5,, Wi &]]]<iQT;KcY3@?{ ]FNNhW8(**Bc@à>|A: ڤ*N>)U(яeggX1(4H ϟ?4j͛sΝCnr *8:xPP޳fJHHHOO'Y駟1o1 r@[BQ ьgA[iK: T/2I% Xk5}c``<`x;w)4 D>JJJ[nuqqцRU4$+UWh U _д9:SƧ~ݳ%SIx$JF.I wv8/F! sҽWE 2}_uwwGp "j&M..~Dw_w+| =)!,:)=z쬦 @B)Aq^~G~7pux肧'ŋۡaOA >*'{o{U Utv]]uuE,;{Г@HHu'ef7CIOp}޽|-  5O8y$-8Ύ!:֭[hZPD+=;v3g!?hn̫W@ҡAd{BbPB ̄ 1  VQ|cqY=ZƆOPF ]H^5Zr_}~;l2Cbbsb~~SfBӋGcH! ZrLB(u`N2]m{;UVO3ϬXV㥩1łCaB{`M9p@eeE>} 0a vhbbbVV#._T\\ҽ{\(R}p q m \Ԍ 3"߉rs`Ї\ʂM`F 6.T_/zʕ(*غshĂv'I+6hxU9ºul_b5?XUJEיj027'gS^,䐉 & &^@8 0zPI!I@qSEEE4?~_2vs޼5khsGxb555K:)zxlS++kP// 6,ZvvcdȑhׯT2Hq[98*++i8i 77ӓfZjy?B%P ‹VXʾj'En:H_AP&"(An]bu/[(ħR]>?G퉣A+v666 }4\Y)C{ݳgŋG I޽n2v̙܋K@ jhn޽^^^v͛R)X"?p@ Jaaa99998;;G(,5!..̙3c{4qիa "M.]B7 -w = WvyZ ه 2 > }?tP$}T&22(srrs(S$Cl߾_vP nh*W^;t%?֯_N:c@P%A~d\,>1c,\GpȠS׼;2D=/!***h-6l:<Уg҆B]tp;;;)8?!9n ?Ϭz}i) fv1''mŽ >-9eb`߾}QQQZ111V Ebɐtn*|4hжm` ={a͐(\ʂt`䳈2@:@7Og}4 0533GP8N ܁vg*Z2AV EGpB##$ǏoՁFF&coo<\.'΅mkk+FTWypwL`>> A񛘰|VS#DGFөͩSǏDb2it &3fc ָkB 'Nիב#GP\POLxڵ'N@w1@͞={ƍԷSSSaÂ]DQdL9?3gn˜K@Shn*!!>L.J0Œ |Fi2Q+Hdԁ&wL\G(q1CG<==yA>]@AAU tw.0IHK$o/,= sSY:FPB^:t &ZEE=aA>tg11ѯ,--SC ЦxYif޽>>>xkLzvڵkPàq}K,qpp }{@yYŏa0o<T#O>|8}ʼn0m"~=ziJKKi#nݘ@رc;HkL5eёYʧcP"̙3ǎEhISPFmV9LhY}әξsGXlcc_O}gP - oK w{}$4I!r*aM \Z"n,/WRtAH q#,p&PC{[ovY.L4oGiK)ACWA,>89>139œrt4he83",Nvvܽ{ہ/^gn'488xΜ97F]<2Hq@)c=%sp4P~ LEX*x!M5('%Z[;GU*PVG61.Wϧa;iPL,`̡Ax{{Aў֯_ollVƀ?<ٳ[DD-Z ojԩwrr-Ȃ޽{?x 8281##oРA111/]c˖-qe: vCtia$%%A7[n L!mllpuhtЈ &@8q'8T5$ʵkE@)Q, f۷oGiχRG::: rʔ)(b<~x_'@%H2Q1/h;v,d Å"js&P_1=˂VM|tU1:)36iЂܑG]2 = ےgX#Z*@ᴟ033fGk@ Lk{o꯿ ֭[gAyO6Vl޼;wnܸq` Đ5J .%<)@0tp9z] уsssٳ)!BhW!J,)A"uA$# Abn̙$)iuqoꕗݺmHT03he'1HFB % {>(R ąя+#9.0v#Kp'Sm_wK ʼ|4SnP??@(: h M3 As @e@7уPsȔ4|u>䓏>^۴ijD'@UQEEAqP0$p 4o`6?%h߿??(l-5*蜜է=``x;xexŨB@~WT OԩS46g*D&Ah5G*Jae x.EE^xMmD-mBs4Z)YbH!Fw3f'þ tȗaÆA! ĉ0֯_ktëHHH@i#f | ^=8.Q/ٲe  9㢫W7o,J<Ew؁sFd40ʙ;w.DZv-o!2 x\ɩ|Ⱅ&* "R/6Co[0UPPixP'ZAkmۆd\1W(@ sGp  =_1iM\Bѹ}+z_ۣ;tӧA[ቡ%ғ&MeAA}hnOlذ5!!! j^%2GO wZAV&'!8y<4 oQr ?:>  Ц:~Vđ FffG՟ZXHjo4D4 ss c5ZB x~={Ɲ9s&.x]6B@%]x}VoPP|BdPp7={U9r"LД!;;4ٳgT\q!4D{Ugy!EH?>n -.Lё!hѯh_PP 5j ܾ};̋#$:؆Xl~<*e|1cڵ0ժׯ@u@¥4T_{(--BzH^p#L5:_SrW Fyd&({7-|||!`Ȥ\/d )Oc84jL F66658BRc(a)kdo]\W^>ydk#AAA% P8lSLe:~xlL5?tPP 4 rjW!!mB#1@nmm+P-[FD~Tã!Ap!U\" [;&Hԥ݂|,DD_Zw-888h^*<b 䔃MK8h>4).,, in.LddWUbcn 6QKSbtщP[[k`h= <4_@{{,ga EMMZ:%x; R, ׯ->>?A!#q*oP*x7_wnMdHPTTϘ>mC''g>J9888+u|2h"m۶VUUϚ5ȑSN\V)khhͷߟ9} TB)^W n O୷q8P*h?g̤[IT 777888:::44" *j/rs'²jӦͅE| ])+rD"3vLAQ$f<5>P(>8888Tj ))֭[N R\XX8nX5k̟`ǎ) VV#F=ud+BWAqMttt3Skjvrt]':,0J-[ 6G(kRTbbs/| tx!Z6!$t[[[oݺΡ7o޴Yvȑ#{[.4O"c jj_p0{<\Dkh;_APۻ"R˫ɧkF=֤ŋ)Tf  fxTlP& M{q MѕaoosGA3E/$ }^>H1c mbrppp4 MWXC*޺u W^..i=z2.G>H1G $޽.&&&--ku-p֭|ӧSDMA988888 T !!!88Zƍt _"15jԾ}j@WWӋ6_Wf RXhҥKlɒ%۶m?{o)n RJJ8;;///'/•2ة6E[xyyfg3{QQQcǎ***V\I8 -sppppp4(--ƛ9}T@_ҥK[]XGGΝ;bLa6#!!vsppptvh쳳%жs>}P@c(N>9@Aۻ.ڻ  KJJlllsss JKKŲNMM T*UlggWTTdaaQ^^C>qeEz3;g===Lfnn^XX D FFFu2U*..T< _---/2%[[[#3,Jm2^p]QiO?Y  J3Q2FZugy24S4# 4)*ԍx-==}߾枕%U"C``П~w ̄7oK A4F'jO| e(JrJrJm hZP|83 A~FP< ]HFOGfX'3$-J3C !ߣ2#6q#$f[̨6ΌjNux8OX\u^@^G[!B2G3EE:...88㈮ޘ1crVUUm߾ j(H19}a&&!Cݻg7oJC ֭8).((un _ CQ@0`%D'"z ]Qqpppt"hɅ iKa ,,,=#˷e CKL ;۷o_?saa z rT1bcc׺w5@A+*Znᄍyn-UGgV%%%(//gB`P( 6-ZvvY7nܨZuJ|*_ 'NƍpBz#OVՐL_0p˗`Az%KAt?OL+((hҥʌ _xwlٲVc8:54ShvvvLWyϞ=Fɥo AǏ{= 79:4S@rzN`jj*קzҞ^L0<< W  ŵ|Xzɓo؀kD,bcca[WƉS(%K? b|rpI&mݺi6l0ydl\~ՙ3gB=àyWH@$`+;=ܔ)S׿B̓X+4:` _^|EpO>A86oj:ТZp?O"*98Z< M)ЬU8x`Ƞјa6DEE͝;)PëVu@G ?(++KJJ:<ssshn\=Ls'gϞc߿?@K;88̞= WO<񄾾~@@O>m۶7|v],,, yƌ%%%ٳ'nSNSRqԩl,%I&[YY vX#-X G8:2ס }YaKz\Aő닣GTΆ! eՍFg*g6mY/_gd2ʄ 'g(dΜ9Pusn߾@fCCCl*Pz_|Ű0h3B3a nݺZʕ+ rĉ,--[paEE=CvR6bĈ;wV ptX@DXf͔)SNT)'WPHBF_zU^uTwTO?;HR\7ހGӧOzz `K$X2 9B"O[l?!^MoeA`0ܹs{n?VfzWZrp:4St7nTsƍyyΜ9s1 Oݛbs4F9+G{?... Wd.++C6ENfᆱ,ʱv'5j0WXA{ `ÔXl*T*0 /PUU%˗;imSy%o:Zl{rBCC 6l؀LG!chh5AVYY))Cݻ8xb E֮]ۊ2qN>*au8l0JC}4 (c<#FPjnn~O`X:RdT8L jz:!MSauSxt-:$@)8Gf*&LAr B`9`` #G-?#9Iϟ ppppp84S,\^TT}/}Ws:ĬYZ惂H- T &):܎ r+Ä́555u1˗dNNN\ KJJhv)7T*xVWWgee3Uw=={qpppp<6:t(-ULckeH'5Sh Pۻwܹx1ʕEER''GЅ࠵k׾{ ン6yd悂#wނ|ں-bϞ=o^dIRRΝ;[򨪎޽{_}΃M4gc=3\5kQYYYhrh;mgKjfд+**핤Qkz56xeŖMJӮJ.ƞXTT3R"jtD/(2T#Jfaўq@pA::*`K:sT[f*Ov?MXX''':::ݻwĈǾ}M skjjwwAA 8w6u/Zf``nz8lwfd|XW722 o{ihHm갥]-!99<$՛ANrinF]Ee,??ݽtuOzkk"8;;5=-kD =PT6̈́\^Ϣaj4 Н7jGST ^z%,N 2fgg tҨN41\2&&?%{.4^LPbCCcsgȥK@Ν;J~qɓ,E-{P(E%)z2m V' @w.ϖPXXs6..^MjNUWH \<t.PX= )dJKv&\Qh`x%%=j麱E^\^5Ċ  ͯC}z66@p_?ASmlaZ}j3䬳sPPtyy@𼲲N< P<7o~U9KD9;۰vvRHKat tJP::*ML4SlJ;::[ƍh#N>hѢm۶^{fG #ZW:c+؟_bڻF-P]]T`(]۵aa@nnnpppttthh(>E*T`ժ_jkvR2$$YvM>}<<3@ާׅ̗zA5Ӽ$O?ׂAԑcL?E$F#6guxBQ*~~~bbkk[`DDDNNM8͛buÆ o{h,R/>ϲ lUvUc h֯ }UUdL&`=ZbM N888:"4S{rcC/^ҡLpAh5`$Əϙ3gJ9 |fe_.]OH i~\t%<ܴit;>zfz?C={a`cEiE%i%,U_t~6Բ2vjiS;f\ʲ7fYߟ_kP[PTYj*k'N|&&N`bk<.NV G/A(I),Da՝ie_)fX9q`jŲP⬟v $JZUTG7rsbsk՘ښ+լZ_W$D/a:Q55H$(o(˲,'ZZyY\+=_p@\,̬B[_w Mgӊ%U }g¸ҬҪ= J͛Ұu'txl>h/4WȴiU|JW]*VT[b=wRJSZ$dE2W>55|ggT*K$.]rxڎ40LlLd,M&ֺ#Oȷ +/N=% .vBsg6|gyyɡ/]ҳWΘQf*P^^_PP`llܣG3bbbҼvO9k߾cǎ32k6z;2VXSVrK(c%U:t ZX1[%_O_O.;Nt13%>ƾiSJI j,Ij$kxH%Ҋ fͬ}\kqqI\\ܠAmfmmP(Ңg]駟ϟ?#p= `3.jtzrZX~h(1lEB ͎v c[M)' ^LIp'Y.tpFwX=!⥈GkC%bGihc#`y~%%:>>m -,1*T /]T[[[YYy-433[dIzz:yA={TW_fd;;;= ?2"_iisss Zp4 g}Ld61PcB i኉(*vuќ̙ykՆ1(&-drqpt=Y+7|xM@⧟9Npvvwqq)//CM"-uЀ(l@Fty7.u3F3󋏏W*T@nnno&KJ{ wR@ѣG{ :X'8GGGcǎ 2׮]0a֭[4n8uξ}]ԽˣDsɾ}Yu?s_짟؂lxUӦݟ l9T߳gφ󔕕9Z#Gܸqx5 @VZ f,333..NT(Q<1劬/ Α󋊤 HE 0xqӥr]RWTZQ!kVi&X#sq)I2KLGlZ#nj=|Qśv5h=Qk_UUr׺W2QIVՊJ +,,Z"/Z*-n´5TfVyqpޝ=ׯ˗~ nZ9 y{ϟNKK;y򤉉 Qzza|CJi f4:| PW(k@333mM(wzzMLJrW_R~3 QUE/1\ KN+?`ǞYoIMGJYNlZ˪ZM;6@mmmﱩ/Q6M8^"1yxz ֭dZ9Dk{b½w^4 m a1c`>͛?]DDڵk@1W!77!k¾ظ+477o~Ut6ZN%xPHH]-R d CHHz \a'[=pzݣRi‰\<t7h֮jN{lrU&pbyyD"yM(iز툧z bN~P<4Oזc[{ס^dg+ٮ]?aU>" B5Oc'N={ط:t^|Qаxv+.fg~AhBG*<zzF}f۸QCY[7`QመEOMeQ3G7߰ADb0/9?dk[S3xǏ a΅9n;v23Ǝ5(-U(.("=͕}+-/Xk-bwaah,=&kt}y  *fa|ŅupD=BU ԧ|HԽ{9S&eBZmWIoLIڨ! 3wad|mj~ j-Ixnߘ1wZg y鶳c_>83I3D\"/ݸxou#2Rh{$6~qE>Vhhm!ҥ ^SSS_r#8ֵkw"@jy@WAwZ5g. hmw}\ZX6mOPݛ7"l3wX3'~Tu6A g>nj(Bə87`oFsrtd} kE]LL4!f¹(MA/XgʗdH$C \[6UUHL XO(rodq^|ZJP!-MWG5a],5+nphMJ wQWu층UcK2y<1{?0!Җ{043g 霡*Qy᦮\qW/aGf#AS?5袪UPT>6.k&M{eQ.Սݶ҅+ػ7ǷVڏ1p.g+9aバWUW } /!4˻̂>_[ro ]ܜ%2Uh[x]-CsΎuXVt=>**e|]&t|QץܯGWvfLoEfd 66Yӂ's焅wmܯG\q ^uj$np*x|9׿ڻ .S*ܝtvMp=dg?N8sF?>^KnerE_>xp9ژ< <ǫmdTGrfl+cՎ f)V*6|0y2mZ{W_YwN@H_~1HsTmjĩL˞.Ao3&8wn T>tP?u{]'&[7ag + Z+`c# Wki,)Q ZN<үZIk*幹zWT'mZ{VG„XD>fhph*_px~U] Y+7|x֭2Q'r*!}n_9^oT@V3Rwd̴S2}fc:x bس2ӎ:{Npޏvst|cط iq}@DEgg)4ݻƩG$& N`B63\ƚ tU1g"F6m;Ž.**k\3 D<='᫯ ]ӦUP=p*.=/lLcUKCv[oؕj@H#v5ʖ-mڴ ME8tP*eeefn677755A¢ DžmT-M;df ÁA0G[mw4PyDn@T.)R30  `TEitBF7O߷O/gﳿccf{6 {{19B8]pv݀P78*8|BBE^p!77(00PP\~^n.Օ& q7acU!&FP@^L&nzhȲ&j“'IvHa0-lŽ1cc[^MM DeQrGMszi'L v6Qvl${]7sj'.xP-UI5glgijq>TFb! A,t*dp*}vǎKNN:umRRO?#&L8y$TW5M vmK芊jʕw*{ aTJ&L*B?>۹A*~7a,f0`k+8k @2d`ȱ' p_в'aZzwtqUzPiž=h {ׂLpt,Ģw:һ%oi t28݋uGG'N0qÇ訂t޺uܹsv+(]EҢҒ=]Q][C$(7337.G/{5u &nhqqZ^QUmUUQgYGZ卼{9tjeiO)IIgOqq$awNЄ'Wgv4'VVV-57ZvS_b5cII7##C#S )TwV<]d~vn2kVCn=Z\RتVTT@.6y8.~ǧ3gv>b{ɦ$ޤHoH) '>=؟"]E" "wtBz/ffݻM_lޙ;3wwfNYQrrr@@@˖--6By!@BBa"""AD|A=u^xV(͍7JJN- R@Z3e Jʓ^axtm K[3qИXr,?!wJ S4ГO2<`S(e)H1,ٺK\yχtܙUݛ^{M~5?t s46wnؐ +/|3ğ("X\Vd$$ [%KZ -|v(0dTJeZp/?43p" ].Wwt4c1 9֒c@3/9QČ:,xYc|'Nh*F6qTAh4MM:KS;YAp~Ez m߮}}& Vx~m1Ѻ5MȬbhڴ̋]d@8 x^~?D W;({Gk2UTR )>EyZ|DD0xBv 2"4}%}bnP6Wquy)x]vCv=LMopM_m $jȍك::jVyca)O }om x3@dыHᛓN9ĉ9IN@E6d|-1'}v'+ݫT 3UlڔO&6"G9.efz>aO#8A/z}ӱFɻ8vNׯΑ CCZ _Pٞ`?}D~ZpLzS3H<#dﰎ u]P:e>?0}5}l*f.NkVD?3b},2׭c.yp,&qG Kb^ҥڄV@WqR5c9xu"ѳ0ɻ\ 2 (,dJa{n?\{86}D7a|7VDQ[|.uy#eeLIrP莊N,S,ŌxfIof,j\Er2m0r$8zj``10"#Eŋ/2п5 f1ZpۼET-yBH̙Puz7t~X&M 7 d* Cy0wgN|' )8=ol0%{̒({qhģ #bTrۿHd3"{ 9}A=%f?~"|aiӘOɟ;T 3_~M+c**Ȏm3 sëW3}w|&bAjb fo離V3ɭ[m@j*iL_+xYW8G^Q"׋Kȿ|jæ]7!k> XU$ozA($b2{4t^AJRHj4Uuŋ+W z=LdpDD03]b>CXM& c,X$@,Ε%0cưGH XgCpI@vc1L_ ߠ|+R17?!09Ԥ$kPuiӪʀ>|8!;]۶{25'9)%"]|ݭ}a?Y !wO,̷dLT3ba6_Rv{{~Čr@~NyNW=gCnлmVgXU iXU!w?.s&Y̲%&ѫQ@.VCj  <(x%fcI RRg/ZllRֵg3-GIfnO>Xd5x{Lb}h}4,篿6nPW_eJp9~ }T &'6mKT@CDD}nUdx=  ޽M(-G;>ȇ:A[ѤnB@$:DIپmЮ]N_?=q|@Ch:+i (vn$κE FZb"I X(L1.l֌5 4;,N!:71ֿ dK@1n[( ~  FINPZ|HT@ XWD(Bm9ɷM V^ ?v4kl?n}vqfvmv}8̷n(`~j}rjh Q-l!۸&b?k`flu 8a;>0xM+k3gX^TƔOVE9.tQ#у^y=Q7& m0xt}D~`r,/g^}=Pj^<0Awlfj`ƍ4v,<Ț믿2?sp8l햩Su(Ə?clӧ3?2+ˣtD2Bb:"QUm;M`3! ~ϬBaKu N&zzn@G_m`A q44yVT >Z+(5"ѳA_|)gcRJK3XcƚL ._6n>?ƾĿ0ڠ(S L*)!Dl}~F FYla9q{Yob-_ζ"g3P\b)B(,2%t?w"99$+GNFjJt@RADw AbF:z߹3+8~-eIu@6dmS~L*gdPiV~Go9J8|8۟4vDDQTĸOW{ςXi 7d8@\q|<#[N";o ׋ܩ,̾Ge(Pe 7cK).Ssl_`$5ڳ]g$O|߱: Vyl !;8ZaƩ4bcwWGXx},ɦܡC"6}2-?4P3ߠCxfHHm[\Ybt.NP6]~J;9A~>9Ok}qKހzk3w/]:g&PYEGV&J `$͚;qpt(l]wѻ7Dx#x{GZv|/ӁIu7CӶ]l850v,y$U8K8y9}A Z܃d3avc dl>jbI?\}DO>/mdxx13u:t5: -ۙhvDNl;իI_>u߾=ߡO%Kڂ֦Cyl w @_|u1|Xfer/:~zLtfuH;j!ؖCyݶͶKocd( UfC>Ҙt ke^^M7g$ cڂ#+Nޏ=dMҪϙwDv`ߠ=9C unEM#CmQ\EVV`% e־OӿmTUU9}U+[RVZզMNʽs'D8]w)Iъι7D6q#4d aqb?b-|xz3Ƌ,5߰*BxyuHIf3 d[yԩ5LO3:K1~EOqvkT!.g t5_hWsS!;s2N D":̜=y2ʆ͝Nnwa.\ҳlYgǧqd)~C k׬H(**ˋQ(_~ɓ￷kN-DvK0RR#uG&-kXF|m;ImL>!~ [xOyW5ƲxC;zn:5mۯQ{[?NӐ$gDܱB|;ZZVZdv$a㌇Z**B9s&;$޿-I,V,щnˢ3ǍXjR7 8wj*2(jR#"|HZ'I%v (7舥l ;;11EG,SʫWE( LII&#bR=l641S߈s7pY)ėisr\J@a&`vHDz=`5s/0^gi0+`-|1xfxw 3 2dbnݺ.]h" O>2+++˗o@@9PXTXUZfss. ԩ߃sS?}}EBP*#>hT(OwΩ2D}\={Rǯ \}𱠌$IM[ͣ'b9eg˂JvU$p>}a" ~Օ1Hh&KC*C9v?*sm0ƣ \}if٤;??5:EDПl2iSX閡gLJ ARHWSSAiBeQӦu]  eb;6OT4֧h"~-*) =E%7>qS=G鴢pUfJUMiju_h_ 3׮LWjT[_ѣ+v4A_0h]4yK V/lPkE,8)ڵ`"%nQj+hw숼&6WK _}9~<ؤ ./ץX+ ÊdbE@v@qVU *221thͰ|5"ODʭۈp}IiG4hp<уPŇC*NGtjPVv#M{=z5zA_j5NQd^FSzͅHk$a|EJ*͛֬ {Y2Ey |j{=̯~ӦUqqP:l0hZ4hqߩS?<**J8R7A!d' CBljξlN:IOtlg[̇t-8'ª?*&<o' HnkUcy GdƝ }XYIs>_f cCO%Y-:}vHS6{"6x Ht2 zUٱS!{*"vС͹:  v}Ͱ2AkS˗…Ӄz:w^~wA Qj FFR3o0L#Slϒ@v% *޽ 6CJ]CoOcǎ63UD3i<|FEV4GB: \mZ<: in35Sʎ\|G]D|} » l*ك4šhˍj">xeD]tx9;zɛ ͻֽ j,MdI)[5%`{@]+Pw͡ip6~'Dfٱ)tW3`EJ  c=ŸA!S~D(VX˷IkP9dME|ΚU#q|$1P7_%qG$WqaO7i hwJdq ?* 4ڿos L2Ww:1PӨ~4bKsH^;CD,ŶحfOulÙyGކQ9,Nf9#ꩱH(!¦..C2½tDf 7t1ZTIs*3(!T3y*%I\BpGҎ9]/ӊ⑧%E_&ӸsgN:IvW}>97Ol)0dΨv=DTfXbfut|o<V2{%;C24§ qBW5bgLd0a?k;!|Ky,4܁tn1I@vA|^ʍ : vүHg>"Rw3fyCC RRD ,ytM)Wp6ڌ@8@D3{<¹tF2MԐlxb6#%EYƒS?1tb/LdX#2UV:Ll.m,y@i)[$(u׺>0=T^zcc/Y^gVf {ń_N:EZO=.}y#?' DGX h 24Hgrd-{XD=o_ٳgEfUQQ׊ W8<$Shۖen_kyCٖ-'@B]2$JI7.r%ewsrѻg]3PU|#QQbTnμ^yRH5';hf~wSnؼ+(lv}#{c,:HB8VwE_*?b7z7EpOaRmBW@gDgٿRTv! ,U{X` "oP@+H(KЉƫ\j7-CÞ0]k\NyXUr-p&.6ovW] ,Kl8wmU*58fwp6rS=\Nf==v |Ü&M ☣ B]Խ;KSІ[G T>MŅsDj0`5ѿ1K֦_/ 8s_K|Hȶ~ndiT@ 1LH vޡ oয়X~|o'p؍ZwuXZrKK?sN7$jPӦ8B;\⪧ hqt Anhw3M5 t&-3~=NEACeʹs7rw>KRYT \tm}m#t PiB]f4ԋEuf.q=\" ss)AM<0 G)%%%*JSN-kV D>l ڸ^}7>9TlvLؔ>(3fG F2;ْc[Mt7AUktxwEL>_Y;sK'C/-G܊r :R|~'."}ʏC 23>^{#GlܸGѲeUղRp<Em ᇩs; Hx>ȓ:7un^G1{r%j؜`wKK,F5)>p0-T8PdMPv,TQᚻ' ~ؠ14H L <%os\emk nZ0!7]tT!>ht!e' 6 jpbZ "31֬?hnw8ƒѷ95qͽ¬C i❸`];-d Xh;ژ:H+{y "%#7֯I ?,pF!1`oNEn]M}]3x1A6HtueS4;Xz>mZ4+S Szh?0޸qcYYٞ={ڴiӾ}{B"#5'Na< ϝ;ghl;*q_9wDTL'%E2(eAΥ jMQymaaar2s>\sDih/6ܿr npٷ~?nŠC Nj/hfy# )Nl9yᗓl.JQl(KEa9j|FP?YIjMr,ZZZRVVHW+Ri %T|.(|wXNܲAês99(`~Fa4W35,*=]q*ܠ2OG]\]Y҂*sTWFeie]FL@كb0?ɼRlϝK ,\|2E*\( Y|oW+E|G3<;1S2vR`7.;Bvv SsEw=AYMȤU9R)ZEMBm.1j~>L @U,,+QVVT.S [WZt,,S/..QyN68KdS˗b5y0X[!X\mR#\nٲC/.B ,-Z0G%Kr: [ɁD Y+pXhde-f J2IJrZ-,M$c.DGGHA 'GkNģci'PLh 6;~ #C~iHI&b|IIvgC(68dx`QN3ls1xpGטJ` ƒ1 ,"!Q!OI: ÎEl.q9+ߎv b9 ֟"-i$̀<ߦt.4*4:'%$4MJ뙆|F /<cMG23fL111bh*.n?3w59Sc$4Psx~$t]K0$3dZp>L a`iC(xh~} VƖ?bE'Pr7Ŵ6zHUQK3i.Fl9K{ ehX _n%CAٻ9u s/_ n}=J+IA`H4Rൈ^`{j.Vйi|ZqU:y]T?lKZJM[H:]< Ui+ٓKC^v*U*LHpsM:98]C(O8T^zl"@g2S4ȰZR_ E(Ӎ/h0thyF[ pH/s*T`^p^d_emxo^liqgsxX@1H} !5lIߴ"w HYދX6~;}eyy]*'D{Ual:ص:kh#(Rb8o2g*cYJp5Ē%HfҾ}eBBeU:xQѣ+ 3mK'ORI G,\1uﯥ_1wXj xwنJVfΎu(}%Las$75dnK7.YA =֮_e ˘%m?m66B:aCDybW[lLdxj+;4%ZUmbcŲ׍ VޕЍf^灭= :n>Haat U{zh ē 8It LT~^o z0rF0A}:l(h\#l@7(ssƹv(m(%&&N 5QŵȔ}ҽE5\[Cl&Zƀ4w.́! &}> VM/=RR yX2"6EݻHJ1w=bz**D7z|S$c˵;A"& ]+ ;Aj 8mu@Ӆ [eJ _2PA2Yv (CtI3*HG x;x824ah?g٦C RJJBa,176}iJZN+іS'5cS! ʨ?u+b"!گ]yiA[k,QD/n99,G XFjչזx*9V_:Fd҆,z 3әٓOD$AN^cЬYq`)"nц@KKhC2PretJ5YO1bk>ɓ)+Ҝ"Z}۷0XYDQ1nn+QG.-!PH ˶A| #DpVVm7Ʈ],3s:IT3[7͉b(akleqVENPUUuVZ|Y}6v)S~ly,`h׆-:@\qSNs]J:`YYʑ#ԮDL֮Y*PTTP( ɓ'WTT9rm۶U|f̱"'\ݻ"÷yį^R^e+3un ӕ99Ν+mSXἰL x"|Xn]eee.]ZhЧ צM(%W1/_,\333PXTXUZ!34YW]4rO]\+7)( >GF,na:'H<~ /J o!dt"''$Urՠ Bܲ*UC^ ZZfNR_U xm 6%""rx@i@Fܲ\;:ZJM^Վ'*Luv EEaŊԚdlKJ=N{E[ 4wip:R4\Aӕy7Xy9kYYYNNFqRXZ omF!j@YziUi @!b@۷X]MVq"hhҤrVL-F,;wLLLLIIټyӵ.~޽{@HHH)Mnݖ.]1i0ADoeE6T&2Ξ={>Kgm*T*U@Q@eeUdP.@za\R8P;] T'P`^gP2IlԸ?M5STWRS C9.7)ԫGj)Hf?|QYYgYj\![ÅPT )TmԫTjՂ}.Ϫm{_KKKKJlѦA7]'\Fh5ٷoEFB$ݯ ׵T!44? UVx@~mǎӦM0_aƅkC%Fw* j?RаAr^EHr)O%X4 C ݪ'` ) ,wy~f as9if7n\U^l<J.,iP5-88Ȫ+jRWH9k6Z̶6ŮT Bgyrh^oHH~=;ֵCL&L`Pr޽;~r-N.PKIC&˥rg?'E%vم:.t:Jlذم ^x ^-[S8֩EEDD4k֬O>kYYgg~nɓ9ݻwөS'bX|Z#V]tپt@ _t C?-jGȢW',]vMIIG $ֹs0:GXsss1{d_zuڵ<%dq@uh!l 7O8ѡ'bAX1;cʕRxjzo%dÇu&:\ )--p+nD =P!z+z)+++::Zʅ׬Y#ԎAtXyoSLq̓ >cpL('AwnիWcHv\RTTkȝw pztҁ@3229*֭Hx3b^H;v@*;-I#9ڴiOCrK XD  /tk4C׹scRfA@T*-,ZP(!%^M2233Vb`SNrmwb8qx7oi UULiӦAAjJ}BƣRs' j̮ Mo۶-M)P 23`fkG@KCw {Jx44% tK޲eK(K`]XL >|4i?ϟ?IHm #`ٿ? d ? ̙3h~A9{lTrg&HJJ:usXBBF3C]h 3g\p!݉ 6m۶ab-!2*BaAA_n$8(41cƸܗ08z(:hzD +0ܸ??qE~0TJC{,'}^Lm50,P;?eP AS_bŸq>p=9.\Bٷs}c4i>`@Ɠv}aO Xmx| j:j/ 2srr:z^tɓ'!>A`h 5###]Vt7 sѣjq^z1PJ9a޹s?mh&&&:̐h[.]PO>6l :Dŋ vx,38>;w.dvV\ $ĉ!@_K48m4Q;p4! #)ΦFs` 8L )T⪨3z= ^"^bsFеkWifGFƍm K' |!r˫oNdEH@DDĻ{ʕ8bQB4T MxYN`K,z.ۅ8}.ԋ<<)jh qy΂ }vPCXR59Okޓ Ν;![D K(KK+$dm"Хc*.֭['.` ̅ Nk7 C y0☢SN<ްaW_}^BǢ.7!30 P!?𖁃 G0.kՀ7oZD7qӧC/.]$$/(y"p cs=gϞE;1ɥ~ߡ;[Ax/Zg{wunD遆0X^`s 4޽{{t4}{oDsG>XF0R;XO<! 6 舧۵kX0-1'{ byԂWZY$%zÁk 򊦂DDD[{C2\ &&jkXXѣ1;?T QRF zKpO#U>|k+l(U ` ;#*Y|9 hH֭[(EK*:f͚m|B0]A>ХD %щ A@k [. 4hÆ JtD*k׮ &A{BC:*g`^A$KxGpp0;WSN'`С77ҽaÆNv"rY\ " ^."B-,,DIxõ paĈ =堘 4',X}5 o54-y7p5,>8$lBO}RÊdffBCBHb8W+˖->|pr ݺuÊ:xCQQfҥK!nV)O<& WpXч C`b믘`{E?;概*Z(I.3(P!ftY;w=Y Ts΢B21۶m7n4j2/^z! X˫P;>i$l(͘.mT۳gD\O? 0@t?ݎ*J&Mf͚ۊ]{6m*ųbu`xF b ٳ'ȉ>}ϗ/_B<}Q Hé9C6@ߝ6mE,xظ8ٻwo4,X=0} P}B>}:tdGa{!5#e-X!JΘ1C0믿}ACC]P!N+KW0h'`IH0o Q2̙3fg  4%R֭]Z@F!$o>6QQQo.~BVazM9@׬Y.^@͛5k&7|y~)nZx/GRwq^۷˞;wγ;OL*)ų,^ R\.Q>oMaGgcV7,=Xġ `Y{gΜ9XD _Oڮ];}v|-[D vO`~#jժl|E:~-DuԨQk a%ZfjېcBj 0qt/gs['џ .]R1v vB?I͛7  Ъ#xذac X@б/^Dӡt؀bX@I" cw㥀y. ڵk'O NR<{XpF{1CFGee%,ޢL([jGX;GB˜Wu:ͬY-@#qYk׮eW "}D@ ,ϟev(-tLg}VUB`ą oZ˜fAAAK.gUCz~ɒ%Ô~D*0 `0*zo߾"/zRb}۶m8q +,,|]ӝ:us;"A&nmc{̺n>#ca5/OQQӧM*%VU2++رc^XV/Vc'EĪ!VϜ9SPPn-B?~ܭ I{Q+幠cPK? dO]ݻ7VQH;ӧ]͘1#Ã޽;XE*[xh*ގ^[`4Ν{KdC>oCj=2dȐ3-t\_(dD2,0l[st^$[Yu̙Ib}RbnT)QW6jgwONW _~q ԧ>wkN8h& _};| Al( 7"`mi>ϭ^;ۚ7.9;h䜹rJq yÀ#Zsl CH틵h)ʌ؞coXGXZ%%=Fκf/2KڳfG3+!k<{}3GL546݉6u-Yn=a$q@͚i HHO4$k%D֣Ĵ˯ʚ~3Im=5yt4!J+]:S3 q>Bg۰}6WRsqO517,?^O{§inoOIQ (_ES2ŸznF` `E_xvɾwxu7W@>ئ8 VTmaZg.5d ܤ*)ll3O{DlYe[Ͷ2L&t큸‰M1|_Go@??P ŧg 1 ȳ є9˒8Ie?nyKi=0{Wky19TƜy#S$D*xmbb VnR> 3n3fvYk^4@Q yi:IVP 2p4E3`]‹nu,\wdϯ_}%2_2uxJ[Lv)&ʣe C9㢬zKj"U Z C2L)e"A=Pm[3vk-"'+~ւ Z0=yjWpɢj\9GOW-WJpnwБ3{ࡕ%F+Sƨ}8q>ﶏHQtԗֹa ǽlKsyס+XK7.R`nR:}N &hqC. = 'bMH.E9q()e"Go=)`Gq_7)+5%l(X x~o=z~fe+o|g]f o-# 1왂M{Ώ͞)ӎTEŘ@+!UߖtY#=|X [kicf ~kHvScGn[*w0㊬}ߜB2Lj`tc%}[k ÷+]^57 ֭4z+GvyuN D4 X+р`"kBʕ.7Dn="22.@!>!% U2S|M.QwkQ-5AqW`;SLh۾pa2eڂ~u@/kq+ `uMBwmW۾{wk[DA Voq?](Ds@t:?$ D4 X+р`"O*J:%kasgϊц_ H`0̛ۗg3m(r2Qo2ڿKz|?x.[ZjJ*h4Vӣ?zaHDvLw H>YX ?1Io|R5[̿j {JjԨrE-@+v}B3}^:%e$b$kgkm?:ܻ4.٪\_ޯWB) 6h/}}}JOBAx`hl~;L.| Vt3-N_9epRblJШr1N\0A_m8, -O|; @yE~eQ \\'CS Kל>SÇ tܟ,q2v 5h;+I90etqZJN,b܅q@VLꂑwٸ&Wup@$1)TŌ[$:Gù> |K:WVnȫvGr|N5Жi0ZʪJeR'uVR\Q0H{QGXAgi_4@$[:SVh{ovbfVlVo4+X+nXqɮkcvȡӥUlZdn+j8,Rr KQ>^p7y;VnT98]Ieg1\TF| _閕>ah(HĢ,ʆm9(.*3kB.t)C39|x,Ezj^Z .hq[tFV0>t[d"߂u!#FIb+6Zzwevi ~8|h|W^|LH|.AI/BqhʇC*^wO<4Ҭ2'Yɱ|;=s$| VJ:TD^XiU*"J3,à  -a׌iהCqLS˕Y <4{о귛LH{uWIWB؎ϒ(:#w-Mdq)qyŕ|T>힉-U.:Ƿ`Ej-R1in48drE38IcwPϕW zrԈ G֬`e3Zъ%X=]??ʧ] bL|a;HS K_⸧CҾ3AoJX>WR.=RNw4-5%2 z Ln]'nZgbD n.Al(8J̕ .:#t^]I_KPy>3T6-Xi9ZuTi}ੲ2ltfS$eeɊ$=IsUGAtC$&EX۴Iwy®@"`2/澈AR^xg|"5)֣2m: 5gϡg4=S8wfdn}KkL)Cefj NȃTQ1%[ϼfP]30?Sܫ еK㝿'fy}#q@ Q%WgIM)Xy SZa@?IQ]W>-Dkbָ9)jh4i$Z/u~Lc52e]&NMkƧdY (\Ą gtx'ZgG |1mbh޻W3/':^3oO?W=+aH&3mc\|N5(Inn+rҭL.>CK{v!X$Frk@䋮߯1[PSh&(5}3b?ygfZFVTJJ,`S }?=~Cm! " 5**:=-tl㺭 '8ͦZzǾΌ"qiZZ:\䀈B$pQ#rS᤟IWmIW@$W`ZzVF3\Ѽ VS6 3E98;!+U{v ¦?.-ݙ=aHvv_ڋX(z͖keh6A,GA|mp)T*ceLVt833`n>@PZVYTX؈RD+XN] gϞ}wfk[o-;;S v,à-NNo*^Ey8ʚFQ=@ DK_HO{XnYYÆA?/׿_蔆<Ϳp>cٹ0ur[|IEISNtTԙ܉ 2|Z> iu&):\ZVUU\R%% X@&cT&I`5!DMswV#@8*N,Έ՚S CSs(wϞ,fk զ\i>R>xL+J̶Xm%yGAQUr{tMf(h̽wg'J5&&6>%5'x#S` y_$G HZEV8.va jupHiX֩Vq<^z}ԡKa~ĥ{̏2G|>ɮl>@cQ$w(RJ;tMXchO}ޣVzp_z˹lKM) !ojow_}XW 4[m@|*@Rym:-w4M>Wxy=)/O=n Wh4x@^"7Z-j$Vћ[%X RXTwo. PnZx|qrR 7Cs /ЬFۚj)s)eoQ}@M|kӬ $`-Z|{Γ]*@~㐰qT!Z bDW^?}7^% HeR\fעMl6RgN37:q_-_#/[?Kݪ$ԔCTtT*{Â^~ݓ͔|( ø}-lr466#iҕ;Y/5}{_9m_>÷''+_PXE!IjS3"WhWP&>>g*K97lԨs{En>|@;Е`{,Es{ 90YW/n+L*(i];Ьŗ={6{&'^p5S&v/il4wxÇHDbX1w 'ҿO"Q[v}[N{U*eFVɣG^{?n>sb U.RN,YÆ EHQWWWѮZF=w\QQ Mo7rN)ϝzWC׬߳eEjvΈ8zDqii$,>Ag1^ofh( ưt5y+<$xFf?pALA.$8xYޕ1cRQvژ M9ߢ;ZNmǫӧ{JrBEuAd)͚Կȩbgff+8--an+S;/=H ) 2!$UTN9wVu/wGLL҉J}{n)j$ 7tLYsj4*B&"qJ)Jb$VҪ_צfb8:?1R" 70 Y6(g cz"H"( L@ >`+V|w굊zKDi^I4;O@sHN+_70E < \H$<%\qZV& l:Ptr}uZ`H72$A$ ձCxx#;'K!JYXYnYJpCOu2'5 í}~ϫfM6;0l+()*3 KM2V\>y ?wGva>Hw=JB2.p_>njaBH=9u&-t5:|Nj.3ؔ3HERP]Ҭ(SY lH*&i"E`)UN 9qtO\,#Db$Xv:,DZ  $̂՛e_?XY(]U"pU79KK+f;-@4Q$bRf sb-WPF́ 1c3ӻv1H܀ = K|h8a3oz'n=~_|ySf:y]\2˯5/Oe-VGHbf7kفKIBUb򋪍F XneMcJR\Vvqذ7K]wgMj9S-ς {'jSΐS^z¥K?C7r`rؑ=`KeXЉVƗX#ObR"b1\k~59UtPSn]tQ-HmrV#zݰ8j7=guyiٮ'p_88w`jR\} ,E?SJS^5$[5@yYyUUBOHHK=w#'JW%j/l˗_uvL[g)|SZ}g'D-H>tXVLR.lXĬa>r4Yy睆R(i)CޟJ1IŲ(1Aqےeqֈ[؇MMIB׽~5-%vӆVa4\t,,>/*|{r8Ь@9txqq- 1 c9UYN&iKj:Ё5 _|5p@򪣇mݼyOw@K:2U/-/=#fʒ`Pom0bbc'MFT*Z*5m CݶmOZ(sGd~XZpjʘD*qݱPSn]Taҕ^}taqū+9iPj)6Z ߯\f&d<5\.zvڟ-3.F`L؁cE jԲh{fJ98/ Mv|7GuFڲDcMf[~>p}w™{ѹBwe.s.TmˎA1V)Uȝt*xC댶̌WoMl~YδuYM661ՍF 3A}p@[(zW̼[dptda[ }5$&ٵ+8񲅷^+ eY^raY)QP!M|#z]fs4eѢYiݲj#X-nIb1ц5-2n-$5v]?L e+ʫv>hXtV`Uj:V8>lPFEe8k0x챗?lC=+ ՙt(! ӺPUgf';naQx܅wu4+gZW\e%"6=|i8s.*֋ryTTTfFzh4ڬUL꣏t2ݷ*P@"NN7w7>p5X둔ZmƼj4qQ^;uU $򊊊JK+ˋK+*j"^;uhm#9K`xߞɻ%ktW_}; I$OsסQ#8N+o&D}rm0VUUWVypM\'>e+%G kël`jE "&:jvʹ+(D&JR}|C{غj<`d56ǩXZ);{]aˎr8=9^& yD<6Kywނ}|HP]?;GVSPjC7`ߗ~VJOJJ8ollT^+qGiAwwNM>{ʤ'G:ugUvvƌqeuR(.VSYP]c+7 o2ے2RhQ4S[[{\ަ-[&&D߬| Qmi!'(~U ڐX,d05H4qmk+||5JJq\n6m6fo_U%w+@{f:͉\j-/P.;@ktJJ+rsܶp.ƅMo 4}NjM(qD "RԨ!CisyE]|M&\3h)-2:opn]RD i+]~`o*,@)]&`Agӷ#1Ükɤa1;֮[vVCЎVoZ]45Ynzw{]|5rٳk In`GtX,ec.rkJQHҶ[‚lQ)(QSkijjzRH27T)$gfbFF*Ree9=3O.;Y$&]Ik%H:sNUW<mAk4{K4}V J֊/v۲e_J͋@{Б1&]X2Z!Rvt?ub` E:d,L kKSz} M>NW!GN ڛrm_Lظؘh}ln j\Q-hu ^=3m6ہGssbQSjCV-6yW1R|/VKN0Ǭ& ܷ݆@h/`ޛ<ΖƧvNa0Tꪚ.2޷\QX4gZ?!  >H $@X;vC** J J K9RcEOW^.Jvڼ(o?u!~kuS:Wᓛ6mۑ)ՁuufbHe'XҪvMblMw-Vv*pO.@d VA?vo{36MĨOV(o=DGĬzTZ#WDj"e_~ҫ**1~|xYϞ?Џk7} eI, ا6?iVFu] njODm[թRGڮ ŤB!s^aG i'L VR$Y6i$QVb*$IDP( L&8GYL8Q!HanQhh>\}3f3EťOblqQF5Rs0,ͭ26j۶O8BQv@A8*#IB,lvr׿ _l\ߘxTʤ[f+FJ쫧Z~(eEy`uLgvUD23rz/M堭6DS V#9E04=IJ3ԙ'L V:AUָ򟿯[' t>}u[ؾ+#)ip+TxbOюJ֣֗\$F8=\%jz.Л7ɤH{4ONY bTƽ3 @YՃ kyG,ÐC}\H$Ibb\^A`&X1|~-Z{>wLjI4Ordhn&k[wtIV(Jxt-XROcu VGW_iBxwIPc0Y<*3a uvd+*o\)vؖ alsl4D\FsvtrJFQƲka !ݳnݖWNl D1   wg0ɂ?b |n9p7}"+r&Kc6g\؛>c2|z1K_m鵚f*'>pRBQhY.W|Ͳ2q0H8}{VZT`E"c-.63WX3|ףN-@e+\=:=t5g"kbG D* zCsYWkaTL&E~`3NU55ZV \]wTD u|D2?#-bv,FfV[ojV@`CZqS貂dֿ-IHUBW;>櫞z8vv_N Ą"٬TJ6jL,]Y:t1zZ㔝)T{@rTTtXLיs?oЉ99Yͽ_ֻ̘>u(l2 Ɏ>l6'%%!=CQ;^&6"T."5YUV6|):NG<(|icF7v< )VZg7JSOK[;nQZ iП~ٲq־}ϙ3E,uh˖=;wv陭( 4kC}.JxuMG*&6;JE[fuǵ;yꎛE+.x٪9s78b,&\I8;c /<_VBm%Ⱥ|xp@ԛ>csmyZ%"N];z`mpyQ lwK>oSWT||UeUyM r}ԩ/VfXgvsջU.w:UJWN3F&$IQ6_FfW_{?1R/'L>mƹùizڰD~ Pł/S 2=ڛHoAEoƤx.buZ]E:ğr |rz9nݫ R!{Տ_zYOYYYxVF*2 M, ;wPO;E;WiӞ?w3k:o>$ףN%\7w2Ir(TӪ$7]?DG 5kV&Ao]jmʻB<ȢF5Tzk+3-zJLݱs |*!޸ Yi>Jw@[ R)^{}Ξ=i\F,,2I%eS"E!Dzwdvg u*/ԊSHbΜ{g5L8μx%K.."V-=. iu`ޛ|$+|m7 H c>"ƌujjU±u=ێ,BWN08P*xn$@f;Ӥ]Y$F:Hr"j*M5)rJU$PԄˈ{8򤃇"M XjϿ_ İ"QWWǧECT$>=6sV$7U{D͎`Ьm 8)INAIJskS ;K87I[mv$R]PՊb u:W \$q N0"Vz`|_Mع|;wvై+tU"8/"!xu52;o;Z.tS.*ٴwlkj뢴z5RVT%(=)BUn#v2D$ #{t$+X=jIWkN͊THJɢ2W\PPPFL,e"wBW~1|4OM]La(#4̸ H "H7y@iIQoGJsH[$M$A?!󰖔 S:7))따Av`@du7Ū BcV*\eATAqBW'7r|(& I EJ +/r6iW Vg0kTz@^NaiIRRBl&۲!A0(Xfm« V~?O4˸?*CWN=ӢX`'\5ovK%lE;N͛}DRGn.ʇB$Bk+@A{u*&ǰl~яs-KNZ $^.ڜDo9sfhht"BT'O9vpSrx+X& T#XRi{bR|Ʉm֦[¡yz>ڹx`B~6uw:oa.*<:E,Ƌ HOH`tT6cBD\\t:a7~- t:i^᧋VoB]˛۷_?z,.>vu>VAekZp<㦄ӿЁ_,_Kt0 X}a:^bbX#Glw6z̸Vߔ90GݷoݻAt0 X}Cɓj 5%znk`~\r`V+>}lƟAukGfŲm۟v@Ta/^E /Vߨժ1k%e sm} aE_{ʌBA8u7 ͜9~]&LH1gg.>@F$7(=Fԍ55Oݻ{FCCat:h^0,k. ^> V8- 1BԐ:ڙٟ~b]>,B%;"(Jmp~q A0 Z4 c< }U+1dRp{ϵ?o3WBIIw?_׬ 4ٽT@q/bxO'?/KgKLLD"ih4uVLF,J2ğ^y{"1ӣ0p;9=zoc2 b育.:)W6s׮osǡލMDs[^,WÆOB'oQQ8&@1fqޝnj8utUM zn߉bxy-@Ceeò;ގO쳇ޭtJAxAYtG2S⸒4ݡ= ﰳcڦewV:|;REaS8t41/m ʂu,`ޛU bo.[DcykȰfwI;7CZ`\n=WX㝉v˻g[^hJ^UYn%ΓL5'`ţ{|\}(p"K3L> ;}לЕ _}Wcϯ.~h_u}Οϋ5[7mx[_#/_u6Xp3e躂-gbΫ92[t{+r-++PޕpgС%VEx8>?h:}Rs/Y0V^`Η^Da Nb~^e##!ѕk/䣡Cr'f{GjHD76{~٩TWGHjXg~:*[yq/葙s:A[oiT=۲+dyL֗gw|8\xin9JG<g6|v᳘LRg}.H0a'39Vf< -ۻ<55w.]\QF544 [QYv{Ϝyzwz8**j9"N$"L&RTť $WmaiwNZR,uA!e+ϊKv?>k߹Ͻw]9jY3Gf0o1WQ-qY˻Ao1?o݀Ls 7>M3cqe3VXKi'̚9s,`hjF* 0\.GU*xD< tz<2K* 9G}pN㯊p쀿>d]9ij:W0}hKֽLB:A;t;`NcҖ٥;@FSb++f-ƞ>eNӏ+KJKhV*,UUUdrygv{B"aDc1'!cn8N)=xT7viWVTT80 EQeeeQQQ M.o - w7Zc D8"@h5 X1[lBT!*LF54scK4ڨ*ɓYYYf윁AAtx `"yҚ]ga9U`Gg^oՒ-Yr@ ! j {ʟǃH#;W'q/.[Nm||*e=7;N/ V]?m=gh;rxxx4ww~wNȋ5kV/ Sӑ#BI/IH$F%"X3"UHL Ĕ) 58IGEz]W߱s߬FT0  TW=6,-)!XӚ|yIn`U J G:z w]Ud $O9.TRV)qsrj03-` 5E8 W)s\yBkfg7ob_Bل6RLAJQrV1_OPQ#*<yT0 H՚&ha?o+r28@r`4X&~f lh#GrLګvrՅTiS3YSf8Z{?n?9VrBF$7HLp) -dDaR9J>UL>R`&ۥ-XLjrȌ{5<dN:R/ 53Wۉj6iU-ݦ_~'Bl >v^-o"8ZXK@F|w=ڝtFȄDH"H˘PI$W`[7񶡶]F#@"L)n,9zh~[J`B 69lD$Lp'${>#!rNx959.8J‘ؕN 5Q/„#3c&Dv5].g}&˫f/.>u]u5Pg3HHĪNYSHdp;Rd34GB؍ >z+^zFmcTd#n 8ЂMO('pLy+D٦;(]}f`dfғH?u$NKt|KXf't(jg2 IHݵN|b7Nl36T}J˖q}71{>x_a6iN'MAzӝa8}3[̡Y3*pYW,ZJ` 6cN ='<}G>'d?5yN0U%1.s% ( =q9ɲ/w9#Y! KLk߹m,%{>l>9:$OCM=uexIq-AB%-C?4&`A>Ml!Ly+C0:9/l>cT;s[;v'ڹCN3WWU}ʎI4cfENmёT іrД0B0ّ%cZ927xlXMrԟ{WiO 9`T#R%hdPP]}>5{ OgG|=˄l2AG{DDxC&8Vy2.DgvuT;Woerj!q8F<kLNKt|J&5Άw/?j=6A҉D"EY,J$I'Îo~Uפ2\FM|86VQ;){<RSjѝ;J)rd)hi"R I;j iJiLt)|='i{GW˨WN95'rw5tD=ޕ`}F ~1QDd2At~0,.YkP(( 5f~[TtYM){Sk9*.QIH p$I)_y?}$ΓSYb4o۲pIZ7 VF(b!+2vl6,dUUmnn޲iŗ]Q֬eK!7llԜzTgatN~R‰@EQ,͍X&<BkV42Mq\'EQFOVm$YDKaV::mG;Mnrp=OGX(R:} pJBAW㠳hUeyt+qùfɲl1cc2٬x 7?CΨݳ{ײ+Sl&K.h>2>*(92NDV[ɮNw w>rSޞLk{J+RJNI bko50 狻1;Took[1 c|TX,&"v$ p6m^ty[o-zG!E'cM}ZߜQU6zP”j8Yg!¸ټԛK Lhpfb:@V֘e.;䦧#^A 7U ֦9= Q Sj%@ Ӏ]b(Joo/ Ml?!(b S}@ ,` CX fT0Ҙ VIbP2e@ pJs Vf::;ԦRD3NLj0f@ tE]tPPd$IbL:N+aYLES{Nq@ QݑꀑI@ TU];w) bkEEBD:K2֊0M8t=m$-M賟ܬYN@|3չ }iޢ@kVxyoyT; ϝg^yemp`Z`XGLmn cY_broQ1PG 9&'vBc@ L>OO=Tp@kf:;PscZ?B@-^ Bs/xG#ݱ9Scpuuu@z)AE?_7|Bc@ L>SSp$wۿ "X3r@#++<rn.,kUVE|ȀɓpRf@QV ‘0˥{&4&H$G#sS t/~{tݿ"uP*Jr$+!HCNg8h(_rVs]]wK*RTYq Rķ߱Ax6;(Nw팙P>IJf'\I [MrV\`#"W'ή뮽VN*w*E?_ qؗP6!?c R,\*E3"y%g!UpHS''HrLܱy[FEAʋC4l%3/A@XʲFo"\O6nڐMKP]ܲIh9$+vuYfKLsΕgB*C]#1#W p8p×~ej~϶w8j1163[\@xZ,l"aX}g̔WT_o'AۤnTtZ!G}=ԧ?vΛ3<uJd3_˲&.W {{Ϙ_sڬ&·JG}r7jUe+@-=݀R\B%}ٍM) gm{`@(b9СQ(V1%ӯ*g+DZS>]X6X؍Gn7$+}MF CVʃLVEӭNHk_FƮ"}ƾ>_Қ'w;e+VOB кgm׮+ ),֮.Ͼ}+VOX˳0sqg^Gug6:l6)+2Zo/?xf\aK߾,QRC> fh\S8kau("߾r %2çҰP\,Zꊫ,*+Us#5#w*\haE%u, Q*[g3#|ch֓M;* U;X ?Zv3aD옰 }PT|q~d%ƻ;C*ű4#-KΨCͫpp˦}^o}Cîwތ[˞ИH/g|ϾmY+kKB4wECsn{:Aji_{ޜ{;(@`u}QSRfTBk-G_VŇbTօ@(֑9۳[v,wWM^;uͳAvQ{}0TrV7ւv!R'WWUh g9ד0o"˕nm魏`4]&=Y &;SRLJzȌSObQ4Ч"[Oi ieXš}ll3nT^/6+.yM"!4BULz2?wn'ҫ|DU9s`WŸ(W6!Բuګ7ze_=쓳lN猺#w2`HhL3.طK6+C}?,lE=Cl/-:~@ꭝ=<6f6Sc+fE7(~qCi@TRes*Xs2%@"!efݼ~j)ʠqʲ]sUY>71 *]pؤD"X,x+I X_uM)Ceԑ&!lLLfl*L((~%xVo_vWsVvӮ9ee*bl㉯kL;zVGޔv8؎fvy<«CXZ~ ׿͌ j><5&ҬVf9eeFY$ pWw͚owX?t#/^S('ۯ}0t \a޺J/+ǻ,UWfҙѺsozmmChHVa>芡i*>+E 7piɲG4&˕N?,ZRY*PP/x`fݿ[pasη^Yo~yH5HR^d`Yݽ?.J/xnf[8y@VusE  B<2[M@Ȯ]liEЪ&c* ~?Es\,/OPn@PlZ͇۶,\@$,Fpbh`y*vl6,dihnn޲iŗ]Q֬ A)RRQ7sֶJJmSP)p!H?"-zc\Z-E@()>_ua;Y8ud1Ynzg21i${m8>{X AeOhL$ ) v~Y,˚wx}]~߰ۊc_H k!I}v4a.(w:@vINII۰\5j I ׅFl0wBg!E#c,gN4V 8cz agԄ0g ozmm꣆O~E]/8 >*gww3k&dKhL$fh;+:4E3ᡮeK ZxǂU"D22Gsc^Mŏof֜(P;.\Vէ7t'!` C}Y024 F#X WGWӭS:c27Nf8=b#,v$6*&=o-'2~ C$r]?!(GZ)j~MF6EY5 xBMԄ__JFIVB2!X1X iU={8[t:%m> ;&-Z׺+*vxo}d;1vώB#BO8=nN9*&%W&TDGPoo+w._u@צV XL){ 1q d̆O-}N D'IB푝-g>g@ L>Hk4jU3q]*iS"]n>#JY2j[vV?yo%9pzlq}}xZr~>$g>_k?q&1D(>+Moo/ Ml?,b5 Ms(x긞#FdJTRzCٳ{P_i %G5!{~ _GG͛6yy?EBu$bAJy[f(,+,j*ddT$pH|>}^R xBAw HjVeᄑFގ@' /Ǿ}۶oihc5_Q ݍ55EWW߯bq:Am U\t45ɲ|QK`TRrE[ʪ_uw a)V@B)b1}.h/=o)lR>6W`=N 01UBa‚QS Օ95,*P([Xgn~ꙧjtYY6^N{AWLVy<9'9Y?.\kL,]l!X$/H(ju}'!c`07aF?˿~p^|%RC#llWPk[͆.bNhL> h5_0ۛ6JIK^ƷfrݞL}UA5oDbU)ik#,}_fmؑ%`%}X[49EQQo~B`4˰fnž*z }XG>F[F(>_IQqUj4i/< ϗ~qj—l|- EW]]ܗsB4=.K"bRlBAbԆs gp,i)uDYuͨIJZyUL8q Tj h@ -ư*&_D ,)"X ~juhHlSz4XjQYQ65 0dcBѲJ W% ty $d-z駯7Ġ[6{'4&H <(Jz]w-oZ^!Z.n>QEnb ]|zAN*+0c㳟܃>o{mb͞ +0,J>OKӽ߼;aCZB W9~ZKٲM RA4[-E=^jǫM ok>I%ՌqAsOT)@ .XQ tnQ;ᆴ sEF R*:<,*JJ):ELc߲H?ݝp,)79yȣ @ &]!4t*깱-{-isi  CiSE,Ҍ&R%Ů'C{[a')4w@ SY>m q hSGYdh # A ":x2p3j qVWߦ: @ }cr VS %vЇ~up%!ܤ(,l]f9jѻ^< `r 8vj$5fX&Ou˖waxxly_pE_bX:wV]U]SYUqiI"ш,I'qb;eYPpRs Vr,(|jxO,EAVtY-U|t_~Դ1,%hlCةtGw>'2[r!䦿K믽$t:;mo/|V>'ۺy(3?ruUhU MWνrmK'"X * oyCEi9WkW E``:tƁdIOazq?/y3`XnCE"EŰ}r` Πg6S2J֬j;T1O9fTI@0 Z=S}iD[k%dkZ~'*NZvo~֞seWcx( w矽7B!,($(ZLV,`}tXOTZ=@LJrKJMT\Cw_7cIBTi^ҥj2Xa9+1, L63B=ڬHUi. c|9婠J=A.Ȳ|g?M4U?i۶m7m_-5əlxoS?beVyjS*݇\&tn]قnkؿï& Z:"a Pdhՠ>߻ S]te1G{rXp4J ֆg ֳ``M;YJ,>dkaE&lJ L)`Ч楢(9`v%V\WsYs Uű3ϭ9GDTr3/sD"]D5el5"&TUV čPU Ih`@t`=C&*D})gYDw""ua[(í$'|}M_xe_O;*l[")  X(HŚ c +u֑JXXP"~G 6qLChdT3֬@#FH{1t#2EA% .UbqfMkU5)(ULi}x*M#4nL&m& g M¤Bn9{9w|v??kRgoiu,O%F+XoQ5"s6$i>STmG,8uC|净D"閥Ȁh ,8?]~' ʈjII +W@ey/mj hx5yüR{'ԪѶ*SB(D$w0)j&[U6όH;@IEQ,X(^(*4YTf [ o֒o]%@L`% ~tӍ`?SO=řo4+_7~X[Z0Sfۀ(Va ҥTQ\WisYXAF#"MD`Bpk`(nY "}nJ.O}/w߾$:2/B͏~?kο5->ų&I@_`鬙uBbxOYS2#!B@ E@bx٠TRJeLt(XX Q5BEH !! 0 5 ʄD+ِh 'T$`[a!@( + *++ϟ_W\qCe]ݕa2ӏ"; ՖF )ĸC~͇ou"Fz٧wHF"Z{ukf;5wq52nszk*2mڽm"a>O)o;oУ,;YVFP0~#aI-Bw9E,@c .ubjê$ 4HE )dcQ Ž6ـf!R(H5 N\P R)Mʠ+b2˚&>)as V3ƴa c4U<?~([n}b2[(36A8~kk>lx?^Y9ЋU ԱڍoܚCZ;evFvheK`erPiK9t2lҰ O+(#QaE6<$ryϾ` vI)1e%IZP(0*8})|0bH誓ƂK^mּ*bIP4ɫ!1hBLSbAmF+$Z$b:d<=eYJ?pHd[[yܜ yc&NENwj|jkk?}1=X5J7c3ѐL]BuVXyh cكS:+.;p@ZDar=+}eU _ Q|'1jxoa+Vj9thd-~U8vȋ][ I`iz-/y?d|e=6u05룏>zѼd'|k:F@+YeCZêH\~qRN9bRHV,zS\PdYFA$QdCsr@mV;8g8+Ř!KC\xjLHX U"1\%LP5ò\@GZ~b5 oB;t25VxR03zΪ#+0(%#ꫯ73[` 1[64VCB~ P.vâ TS /yWhBH BƪwEl Q R2'QVIm},UBJTH  )/3"U=B SN4(v uuɳhmڋ*UTѿ4Jp pfk˝TbVXceelbijkQQ,**>Lahs6-<Ng|҆ehۛ(JֆI 452!`R7֪HAsT1(F "Y_J`2]E5SIU/GTqXTWY 4qrd/F1` mۇU'R3i/1mќVB*[+s0.K[i L+`Gڎ~]MhV]`5p׬ZʴH*.#\ NHj$+Hm85k)Q̉$N$dimXMXۋ[ GT9F-6zxː`Cp4y晧>~'K<ws\H/[1}곷C ˽EECCXL&,d'o`T0z6envcCw_SR$btף:@j_hC Q.@S JҚB-UhVS$#1Vk:({.shcq؀lUO @TDI>fI+O٬%+B&mTT!iX/2+-í5٠*Vq(mn.BQ}JI P8.p1h+G9,t*J'UaJ V^'紘xCQ;a k9*0:`6_\ {uC[7yOJW b7^~BNDf6 2iߔDID +XtHe=ESX(:A L`ǰWyO}r7n|GNsYyjY^{Evjkb;a\=%-|/]KaZRR:%yQP} jpM7xwWq3,FBjͫXn"]₮2V:i\)+ˆbP`ET "@*⡧4*:e'6O? !$PPef4 Mah(gU~8(B0&@pҿzQ^t鳖/([3iRq(FJC\@ oT}- $ݬ_0qK4 e1QN^6PjgjLmAy-D-d&)QEep(xpf ߙXl;klgz.q@`cduJo*pf~т4;qiұ74wַ-*`v/ԂK\\>s9]]] Xr?PB##(wdDNc< z\LA ̀Śu"wuu)PMx?_o*[yLB1|hY?ؽ(sXoF!Qdq.m,2%LL8rR*l-uqEv̙L r* m0W_v`)JG:;%/0O,z?1?ا?=4뼅kcϬ 5)&n|pOiMˌ39d:9`[WWcήZͿa~2mq =Fꜳ>_6lǂGηx7IYd!OR jVc}7ҫ5&ZA_5֚W%?` w#)QGD/pTmؖ-76R!(:K9[5T9((G]P<@.HgMfpaozOHHaTkŅ2;v1lv93d'3U`m<%H/>fϨ:XCSC--#7g >KVp?6/>KB͠|u n@ ` 'X[둣+G&)<;8l^.ލ 6jJ0- MR io+t`@1ƽ[ޯmofW:OŲ,K խ|kX RFobܸq- (zyJ^ĉ^w;Z,߱c;=UWуXpD*39nC͞p놮kwEUtM#X2jzy9Nyg kCH _ G@х7eL+n "Y J7& e@G&$&``j# 1X1ɰdq'YVĒO:'8 zB%c!$}4];wn=2q ‰.wXr"|X}lyYH'HP1+Xȑ, i>ЭW ⛻oUM2{fض@FK>!Xk?p(۸u3n\Q4"3r[dx\vynGy4Ypw\g&zTd EbK[8hDѵL@3nFd&Sx՛pe\ "2Y u.?̅1=dZ̖bRpg`EK䀢Y٫ubM-L_$ H(a -kB) ("ɀ5 -W "?N̞r2Nm~(N-# +g`u"C`fr#mdjNz}DXdK;d͹jQ;یNL(z̞= bvi)i JҴ}CT {v_O5_W&LAiY}t|JAKJ~kPգȫk~1nuF E"F35 U3zrQElV&s,ǍpTo6v4c4L+$cX8AN]BУf ̰t'=P`JCh-X aXXr<y px+--Ḿ(2W9,MRQ@ -w^?N&l-D Ȕ2DY䀵ZU7t;5e9O5+j;ؖ_g[ܴesDIS|ioqMdW5F_9r.IL+}E:n4e}u('JGGmތ{I&~cSrΝt:-˵sٯFj ?oa/"ņӺA4e.g9PT&Nj|y3-d f{YΫ!ۍU׉d4ī.:H-!3C  'n/xW ćbFBe ÐV+_,Y q80Ɔ8{~u0J<@g-l+TA]PJHtŽ CVTrgϸuY#.9݄k*@85t#299&+;%jE5`M02sOg@X6u?fGxUFF`AT.Ӗ\4M}{/}O|m81%dpr+.7\NaG%m_E_}+/hڏJHCY&@U 1fПyƱSPب7QBe2PC+P8)S*: 8M_EEJq ,$:%N,m((-fkV++ KWE{Wd!ȔznV29db!7 rL/hg3r%+2htqNbrx~.ӢƂ|ۍ+Ѩlޓ>2VQK=g# "9Om9fnnCٚݾcC;9FޅRrcլ%k#XL' )>o4())e3$B~_2p7=2wT:rժU&*~yp#,m{(#6ʺ;5֑=4`0-]}sȃm(MGH՘#  6 ֙ F}hWAU": RXÊ f#ɬ,26!U,C T%N钤Va֭-ͭ(-d%W@]wKS>'{++3>ac/|^||LS &f̘{͵"&*\>1LKk-;+#tk3Vp>-RV 58=P<onnz7Nco*c ]XK<"!'~< M4t#>|x<W+l[aX|ĵ坻xv`WPz V e&^VVRWWtoGVZ b۩gٸ~#Q1>Xޑ+79@Mm}kk3Oƛn<EXkkk_oZNH\8a{Kәf٭`0X\\XC;g#pӦMÒnk^~t'PXVj䗑0:"x !FQTE Q~26AV8daX*2iy%i13Qcх M9vZ̸RB/u$y>>ǡC&\(c@AJ<eY_ln*e"[Ct#3np~je>aaiHL_$hA\M2H1.g¸Q=rB+2L|w8|[Z]#kl _zuO޵3 GXU$IkδpBOWVVuttM'vH1,+0aXT577dYV$oWUUl#m K,0袋֭{˯kޞ O~M5@1 L&3rx_1+f =MfɌҀۚkA& d@Z*S< #UA#$h M!, /"w:0tkcѬoZ]{AICJ}H0F C֌+48ۃom\{GM-nNyJ扐u3,a#~lgfVUWN4G9HTEyMw,xR%|vS툪e p8lX`%[M kd2VW^g],8v$N$sYv?Xxlp7i SHE8;w2Z`(a\&V\A<a @kFYY2U#>! Y(`݉>>e`'XV=Z@h[YY4Î9O-2eXBh2Xk3h%.Fp%k5fcCCsXY]Vبb>^|]S;g٥N~qtY7(Mmko*pdd:yjY@쬵K'52SB O? uW{b($S]}|}2VWR9i򔂂P0"uu9r 23 }XQcO.+pǎzUr,t,ܶr f\*Xeffs9(gzCS\gCtJSS}D]3.\`AQQqnnֲ8 XC?!\3233Pwў{y^|vTTR68ΆE2%!m>5|І"/2!/̴RК #B[7jC񀞈q)xk*& 'PSX1a%֙odF8fCP戟/Y!V "QV ]h`xxHlXn ^4 |^5XgNN+1 %d'mxkXL1xa8ƪTS<۷t4y ?c%Ǝ)ga#BӅ#XOW;y;;xoqժU>WW\UəOpWY^^k6,vn'۹̄)5g۷[3-:e`; |(z5?W>TǞQz*ۛkXi5},/L,qo.dR-8ԩS{ҫnɓi /qh EjkDމ47Re")JȞt'2V<:}H֡Ǫ=aىyQNU͈ BA; fD:%P<eƁÉ+DRq[``@ssXÂFրs+ddE2ɠp$ܮ:x-B#<&M|&9@ @Q㐙1%ivLkzHnhH4n#cfgaj|rӔQ #5n X\| m]|O=Կ_ZwW|zQǾ?FCaa!>_X'dÆif^{ ee)S`:i$Q0iqg,+++mYy芏HhG^~KQE?x]&LD@oVC`Yz5\. 1G5Hqt:WXWW]thІ`9=@)&'@@* ;EL$*7Vy٨H|zq ]\3b<2\d]VltD@Fn`87yyOʍpPG1i2DN:ÓT,u5d8@S^2%F*"b5~oo 1]E|Gaհ sZ{ 8sRraљd{r3/;Mp9Ao;Y|NӮ2q<uso999wyguuO<+O~A/$ xk2 aaayyvdGݵ= 2sƍ?ߟ~z|fb=vjjjw'*EHrSNevp͂g-M~ѿ^|U3(7^+qR硧.|m& ,AJQUk:~ܴ4XH]$Tjۋ%SR۸ [nf#?AhCDTJpzU/, uhHtU`š׀M_ 9tRc-fF:>.  QHE횳|sC Y㠳Xq,,bI&EXzPXKǀBI6$PPY e6e9d ZVt r3vAXnb///+TW^fE&-v3WUlc GIqIokkF]p4.,SAcp[ތ|RX4&2d/Bˉo(KwÉmmXRa~5Շ+OH~`p+3: zvQ'_}{N,**x<ce/k tC.XSwill. Bw5kVffYYVo&u`֎{w;.HHM5~b-D;xh! \ ٟPg⫵Qo`7Z$Si _=$SpK{~fXګ#.XiCu!uM"AP 3 X2V$ND(E3MUGn9 d[͸"PHAyM2c!e2'9rrbsw1zn(Y5(YO!$z]o:3L.L L zDCC}e؁{(rƻbI@ !@IWQ>W d4˖, 7P"w  (O]3?W["3kZ[X8hҤS'vlRsf3?c*~^9L;ȬmXpԖ:Q1"XUUc{0tLۻoO$KW|ڵsϹ7nܸˬA[u(֩+WyJK1s[{Q(X\O;,⛛G!R-(rdl1{=]=5twܹ/L m.[|Xt}݇py}xl 2Fɉ@p($KX ,*&O8g H&?t` HhdYNБib6/2K o+T(#L< qM$1Spd3SS,LlRB ^WʒL 6Gs]`Ua6nA\wU#̚aϾ WgX y_ &V ߝ%ˊLY_xedw!;3˖-8+,^ssǒ;w￝HGU6YN7*4,Ÿg,`5foD 5K09N#XhKdY)6pJJJb^OPIGIUp8q]T5@64bєeD)EYE*kUU C (eBVM2i CfP_9ÚMLgLŊ +krn\U9vX<[Z[ v= ~ztTY61';;5u7w&w}# &px^}+p x_E~܎pRirWMrA<"ē aʔ)%Ł` yAD ?W] DIhʐ3Fa>mLez Wڴ* .\0;;{۶m7onSSRC(K"R_^}}=SҪaD|Vc^ K6e GW\q?ٳR;Tщ7 qU eLs},~ӟnSĒ⩧ٿ{W<;<;'>=OnvV[H64 #qvJ?fsdur%TGTT,p؂g4pP-ϙ g frhC%A8) @AuԡR:kLr7vUq?N wSnŧĽ/j[fzUp^6i'i:6nxb$ LNt[)J'@ӗ+%VrHpY)5)r^T =]>c[Mo|ɵpx޼ymmmox7wɗ._}+. @hpS8nOHi9Bg??wݍ7ވ߱XW`p8BrZNS5Ս*u?oq;EplK|5t&jT0s&N44a$@ 3]f wXC ,Xvݻfϝ70hCa= t薓"ZV?A-DÕ \:3N,ƅ8Dq&TY=(lR%?#zY9dbv0zP@ 9)q#q4<K@ 96jrs3jf1D}ۼ/*AL2Y n|v3"kȚfXFpcuT_gX,y '(sdSMu(Bсdofg\u= /_QUUURReGhԊRSO}hjj=5[b$IÍ޽KکSff;15#4=hkmx > nmީ;b\&Lp[4Ur% X\P(8hC%Z_d",`MĠGBYV" L /x6a<y'RⰔLtEVq'[9DJf$00t!+*2\4J ,w\TS\ZdҪkUOo„&hC/|ñDz< /ޑ"]'G30'Wcc*F` ,TMrz\v/ϯ^߷M. 6^kT1:Ez=V, Qdp'`EsO]>x,dj&Y+L7([gfv޼[g˱ZypzR kyk97(h>"p? kxƒ/CR;D9K >+i/I אC(!Y +$K[%OM+ **Xr2dP!R#"2яL ~QB'xr/G@jET3 >EHD`Ekq"E r^2^:\dR?$9WHu5UρR -,Fa탁KYwD7.=~n #^t^9xq7׿#/~|\q6lhii)((`Y**'ؤ9&4vjQXߥZ:͙Ms=9(y@mS8{l@z=أ@ ut8s` `Vi aCCcvw;syO(b~~^fffAcY:#aip„ #;ϯߺukyN5brӴ=Yc?Dbʰ_%$TEz dX'PpB Nb^XR8Dr$EU$LJq T4H$S6e͒XZ/q< b pX,ST\?7yʴ۷dBnYlg?{ &e[eLַ%ص+Hv.UӠߋ,wt`{|峊Jmr]}ޠ}(`@uZyE۷m9nvغ{N^ srZ[+*wHҫjbp2;%% (u3ֽ;N=S Yi0u#ɚ{ϙ`u( :ct\D8hoGkE mx뭷*^oXZZ ,@ +1`B ND"}|J_fC݃'1Y M+!''6 u %0ծA\SmU #45Z;OV".?Pl`9O02֚NSqd$+. ?e!J/H%(9 l8Z%õ<2E%eWɿ‹nK؝rL +m.B6XJNZ:ƈ`8dԤ 9V Z;Zf:|̜zQzZن !\}nrO?tjRնP8t0W%zuC`荟DQx<-BƂ_\ZHBM$`:5Gd7 NNd_O6T{,+r0! "4d߲r$ķ$F8](.KUMEVP2v÷+d#ȓ]D˶[>È 82Q3#X1[k,$n^R5d@ˌ5 Dr"((hf/d߲U=n/xP9H<ݖ>+] AY[|PTT|g8$"V5ƅSl/^\]]HՌXQ /^9, p|HhzELq9.}eiKq D4q9Lц E%k8sud-l3-[Ot*V-h"=-[5hGZP1(XJ.CpnAnǖڰ}[1/# eL=rf&x?CY.7ش kg^IID7mOY?q\ljj:x@o!.S_pv@h4Po # /EOužWLÊmmmX[cb1VCeYۜ6Ԡ#"06;R5mߤlEVn ~N=S*P,XN#] iF"98˓Z?uYiU }{=eYy͵O=[srNgNNΡC,](mX)S6YfaА:Zm$޾u\vpE߈HV煒Ҳ{o…(Эz>k w)#=Ig=x ̝v 8Bd!T*LcH\ۘ 31PJcA>W%k aiSG(?`ŒnIs5cgAduEF *M={Ο7Ǘ]hiny]lI\,XEǚ ێ+xiw^ЁsUO_;`٫\}_ҥKRcX{ͶwܯŦF4ŏ.ԟ1siC ')m R\@z8T eMwjiPܣ[/Nn>?{?()WnhzG p@I.7tZZClC f$e1ˏn_r*@S[SqŪYbH$rs4 =/kYFvr@#G1GIky{z0jK3顣-S2kXm á)v;B^W.^T7H_І-\CPF cASsOn[9oÜ_2vz;e!So4m-8uiQEhCQ( ߰wԻ'qPPe6|w5u>hX8jH!J) .Ư7߁oC; ՈC̻>s)ohi349F3p!O 2aw6wv7sMsDly>|ui .K跧?( /ƈt۵+Ud97'';')KXMunܦ]< 0 ;yym'bf/\};cMog~khJ("U@VL+hzḢ[o\7h8jHJh6B1#Xcm o8B<)owA!2z̜6{{.9F2HNԹg$'W_M 6-5Gkѝ3uƴҒg3u qkNP(im2"`F' uMꌓc K9&EҢ4hed((wǯBP(T>607]~v H01x6=S gcBP( B9ՌFE'f:y)wޏfDhGcu GJh@U5%y1omKB= BP((X1=*~+3R=uJ---8q_̚sq ?'kkBk.sk3O]6IWx*] BP(Z/+q9w8($h+F]o/Wjv/]tf}uM4֗vz0CL6BP( /F`Uw|;.I߄){nUu* n\^Qbsm/KȢ<'CNBMӸ BP(^Uٽ?iaՇ[0.k9%6l8X Y@;TֽyOR74Nj7]Ù=hlڮ3gjV BP(2jk?@?.aky1Lb{VY.*{uf}}^ZSR:V3Q߇iH; tV!od}M7m/>#P==5%I-k# UaWK~-pzizh[x5V,bӫ'ʱGKm $IЫ#W{?}g?*$WHK9uA@ vY+|Jn۪gimsWICp^qǥNoQ(0J A,)rsޢ&Bwfi s.*X)'J? gδTzj FUC٦:u:k?Evh g8ǫ@[Z;{kvPUrAmEP('X]ՓP\;Q( BP X4u]7to0yWO BP(pB+TUUe9!˲B!:% GBP( e$j`VP8Ah^J˲#]A BP(3*XyUSh$ kjj=tْ0󊇫 BP(g.TO#}^~q7FIlW,C%$4U]-GG BP(c*Xx5]R%쯠0.ɂX߾1ai궧^s^rⲑ=BP(X V`躢(w9١@q\(:YJgLE"*GNpW#ׯ?ߧBP( B+ =_KAp8pp H5DBPĺ#`Ris (YDҚE#]cBP(Ӆ~0H$@ mG"P5%]n;W`^|q^8-',H+3U";7.*Ə)$BP( 2@K(_Z-?;#] ` ;5#K/ "%6wunSS2~FiaєC#]# BPF9˯\l]'5 `!EQ t]A5?A!`,ua0Ι{_NhM(K!#A*BPFziIpǥ34-Өf=e_y4=rOlp$c/ۇ̺a+f r0MSu$$͒cg cἉĵeY˲* I @*X^$ȡsύD"i\AY%Kae^,lohP۽&NэThEM]=5UP4'xgKY4c%ki!1>R5Y'ꆼ'Y1[ϿHY i_AMXP VUWi5{oZx9ĽɍUɔIJ>R CoB#V甩Sء&0Jf"S4WTF50\~.d%6lXu@+< ڡ8{'aqU#]SyXq;8A+e>>R#W ƹg ִ2gfW6n 7龻~}g*[/_o'|ۑ&74S_9^xяΧ7ldMӾ[o#Ǚ\.kfJ']XuPAZx͹cfҮa8bu&[zF\hCǒZ ΟtfTfM /W^pw]֖,O}кxtB6==-G~Bl#1Gmw'~y${gB*+^ZUqwO{8{ aXXcwћ߾6IRgɇKC64Ϳ7p4žw}p.nAZ܀ S?z3vmi1T?N|ji~'69!:I~ oAU= [ gk9/~m>Sq:PJ"Ș3)YI>a+4ϩV<ϙ*Joa}PzB,VB5zUA+yXy2㍢㻨v ;I-́7\~;̂_0eno?55M:m\@yyFé6Ik]1T?EU,XlFLwX[٪^۳LiM=Oqȋʯ$5jp!syCK1Wg>:@C PBlfeSxCOFۺ:Q3_^Z®mQa4RwNڦkm+lXUښĦio/oGUa=X\n~NBmͨ~ Ɵ̞ gZS%;qRڪd̑S_u=F7tUc'8P-2|>F4Դqk1fBAxB q;xޠ!f0" VpZ|*J$8m֊ [\vڅ?glBAxɇX< P`͘dr`|j뷤R)\B5`wur|Оko};md Ȅ#Y2a{Ð+m̘^V7^H&Ui3XjMnknߠl VmC_ZŚ~ȚtjV  `v.۹}G,kޒ7x?5lE-b'Q&kT/sZC}AA I#-5fꁂR\v欁@+ݒ͙y+IwG靤둧^.k_m%}NF  21AkF,tO2GSDהU^:zzmwuS%UURYJT  ' Vn.#`ٶ] }?qIJz7+7\yEA9Y`}ᛇms{` ۖP$"AuŘOY*o_mM◝X_c'AAITBҌRj dz{ Lo֡9=hhE[v3q/uѓ^^[BE  S,XkD4JGٓ:Xlټ~G?Kg\XY ׂ{aM MI+v5AA+1 # bm=PAp& /eF]Ӎ[?5(Xh¹vdIz6%X})6B@ ozYCu[PŲuKX,~YG$•T48uhy%  [ (XВKwjD"qbu(6wu.X(e>̮mdGÂCt\Oq  ̝{7oGVk_Fkwu=/BK~; ǰŁ  0ƂPsK˪縜?=F-<+W]w[q4sS>'Zr6'{h#AA V0h K 2=m G¡`4MnoZmNP˵lEAdbc`}LuBu!k DA9}A!T"q!XPB:@( `=ކ   Aq  LhPzpmvl[,PWAA&(X!R|6kfY۲,(ɨz[  rZj pGՁ@ؖ%>`EQ jVoAAN_P{ST"m[VlV( r+.9e#A\&^`13{ԶoIRRFK&aL.pa]'7'c݆K  ؂ضmfxoPu$6&*a=ZŚ7h4.}eUЗ_f~=GA`%mrwb-pC8@H#ZSΦ~]B_8(v;:cwAAdLAJld;y;#H 냁/ #99~F)ҖWIϛso|5%׿4ޥJAA"4L_3g ďtl[L:C=NS/q }/ݶ傑*  Ȱ`U5#:[NF')N"~Bkvv^_* vOR=  ÂXm7sO\eRM+MvE=:AAv`}ᛇms{` ۖPt$"AuŘOY*o?(RAAFTBҌRj dz{ Lo֡9=hhE[v3q/u  ȉLeZ#Np' t$ɱ/4-y~G17p  R (XaP8k]]] 3Xxq/۸6n/n6塊3W+NBAANЍhqփ^;oydAy=ϾtI!K==M>knKtj2jYAAaAJt𰆖,]W6& C Y,sE)?_gvlK=LFA9@ 1Hxܹ篹瞻|q4g%eyyW"4ٱc]mGA`%`0Ҳj9.>bGQ 1=8ĹOvLszެL/ b21A PJ@@0>sBuN>J\R黩fj}7lgQw?5^цלԥd;Jz(C9O,7R`3~֎ř:.W+0ԕx Uzbgq˗k+Gv'GƯah,QګT`6TjY[uPzUHuGVF nQUQDO[/A!2lZ:< C<[\Z2*w>]FLgQ:U{9%O4eu(Jڏ7W9/oT?z&q0%6d3 2V:)cFѰSj&U~>ϑq,:FpD'9]7bWˇn6U~0T1dAq+CtYFS `L-[kyW3t}.<;c)ԿGcwdzI<(X=8m;-T(ѫcCc+8s{ 5|\eIu풎3Z_< |}BPGPBlfe9XP0Q}FuJC}O.m9ͯϨ~Ⱦo_8P-K1|>F44NjIlدP*Tos*WZOŻԲL%ضukf-W.rΟ3^6N\?kG}lC-Imͪ1 ړzD5*mPe͈-X{[k|G簖dLߎ*J5~jd?J#><j${-GKCqw2n`13{ԶoIRRFK&aL.pa]'7'c݆KNbW gL&r:5@Jl63fWՍm:Ij0Kۍbx u٪_KX3#rDd_Gx(Xc۹\nXuzK??hnj:k֔_wx/`EASP۱3=o^}H$` tHhQJ浰o=|m(Wq%  R+0M3׹Yc͙y+IwÚI:y/Ჶ/۶\0⣣ZEA V%X3b!Ӹl9$'&xXigWOۼ?\*IҒaEA Vn.#`ٶ] }?qIJz7+7 mAKҊ+AA*Le7 -X+Hj%r9nE(172mCsU^QQHEA9Y`bfRgL&/o`ez5MAC3-ݷK|cFAANd* 4M8pp25Pހ=\#I}i/?jiq3AAaAJ X[w@4*m=‹{ƵxFt֏qy- "@M"  rj`%nD yK&% <`}ԦK^ozYCu[SQ" T+ZtW_ۜRH$Nl2%f ,r~ه-0AA4+İ#9s瞿{ ğڗZ]gϋdǒuC~SAA+a斖U+q9m=zdZxWtя\hb˖-74>3g YS6ې?wM8@ m`a0:{b!a[ZGH8 >i߭ 7SBitPA6ֶ! w׷;3f˗m-cc;ޕ?}oOWOcmR VRb3] UuϯЯ6p!k,kFki󦵄 ‚Q 2Yp`_6mZmClk}ٶxIH (X=*r(J$ }eԽzŒK3S]{Ad23gaLesԳxGsS[IcC:LdTېIڎvaM@7嶮cmn]qJڻܵ,g|DAN -LYo[0`=P{u?~[g7?3d$ VǨMGjiGnbU7@Tn^aw~_>}w_ MM(XTN m۱mB ^!d}|h7ngq]  L&luؘx&ۖ1gJ>|㗾;rt߷?t5OkWl (X!R|6kfY۲,(ɨz[7 w,FOB\skaZYt!x ܂/pn* VgZKw?wSgx'Tc8B$2fƖ? j( 5 U[y#l>fOƆ2WA&L/p2=O(zdj͸ [o-DP{ST"m[VlV( r+.9eDDKq 7Uȶut_PIc_P#L>\b`ABl'~/:}M< [+$"c V3LٽOm|T*%PMØ].úNΝotsO>xǺ ŮG{=ٶ}KK7 C<% V_ C xOEӟ>~PMO0joʗ@Ķm3c{{Zxݦ#6Q cԚ(ܾA@p+[5i}@ Ʈ^/~uV|aE|{OV`9?}'PC|b12`\nXuzK??hnj:k֔_wx/Ƃ.ɢGYȉ?RLaEd>=D .~xZn?D+N׊!oG;IEXD"j_0|a$4E絰}o=|>c}+Cd2)ˮ)G߼νhχNVAɄo7iۖ¶d(Nӵ6 )+0M3׹Yc#23V.NPkLq;IG#O}/\tۖ d{=ٻ[|z;#;Ad,0P{6dٹcGM@iv(LhPa]=nWWP?RoA9]@J\oC" )ycL Vci_yEI֮hgncۧv  81  2`ȡP8k]]] 3Xxq/۸6n/n6p  x[D yK&% <`}ԦK^ozY,ɺ:" (XВKwjD"qbu(6wu.X(e>̮m  (X!5 ϙ;5=sox@_7=&$־"/8{^&;\w#wr7]o+d$|򦏝|U@|`%`0Ҳj9.>bGQ Pa4F/X ^XHؖhc8Cϧiwm$oVM@w/ @ PJ@@0>sBu"G>2yAdd` 8j@(W!gmr|#{ۚ"/;Wuz(^F,`=ކ H[4dwoAeRjPLvP!@ɣʓA+2y+>PŚ|UղZ-| R0AܶmǶł 00zdSZ VdR}OɚK*gAbZSYQŖ P\*,Z>n`H٬fm˖s`'Zm@=5K~k#dMy(XPwxXZ㦊?b% 2zpzj pGՁ@ؖ%>`EQ jVo'+ugA`x ` +2yrfxaekMELLP{ST"m[VlV( r+.9e䠺YB%ZA V3LٽOm|T*E)ej`wur|Оko};m]U|Ȱ HFL^Fp( /,J[+A&(Xmfƌ M=]G2iSmc5qQ}OW.[}ik 88lP"{O*MUNEd8vnZ$ p8(^榦#hM9uwQ }؉ ~ 5kyΝڷ^ÊL^E(XؙLz7/zx$ b}0|a$4(%ZX7yӞxBJ)Tٷ%A+2Add`if:9k ~,\ ٜrtwZ{8靤둧^.k_mCu~:q^AU ֌X4n9%şd8 % V6o{OJZ L^E(X뺹\@levy<1Ju\&+yߴ$kW3DVD&/x",X|aܰ^!XC%kID.ǭvP]1Smhnִ#c ޽ #c* V!FkiF)5|d2=V7Pd44Ӣ-M}ؙɗ:E>ݧFzH.<V HwoM@LeZ#Np' t$ɱ/4-y~G179JIU ]@d AA0H h(U {8kƭf["@\YAAF VbF4ڸpn}d2Y 켞C g_Jmloh'gUDZEdʰ9#.%LX;6%Mf;CN&dp㭞 g@k_+::2#H|Iĺ{:RMӨ'LѡTjԲDcs8&h5:LE;ٙ>@.301\Qn-vFki)7b.8T(-D^h/Cfq*hS١8 Lb#hb1H: S))͎\9]Dz4]HN`]Ļ% N\s o3 n.9 Cs8b5zxWg8u2]j1MR>UbFl0Dm_~32i@Jt𰆖,]W6D&>PmK/\pQ"}]?RAR~B@ AAIF\G'Ĉ.W8I1.4G|`YjTHBABT x%XKSq2NK2猬6AB9𴃎A2 ("DQyH?DQ pt健ͤ}R]  ԱpٹtB&m.\"aB D3.푂z1[MoI A A)Fxo`g '¤vAB' fՎ0~K͘!:DK/Mj`0^e;x~AJ .L{V \W#HPB k83wk.z.𾁾nzMYI}=E^qMv,XWoOGvxo|V HM;{w.ШT yT]]*M:4&!Xň怲$fvzkKOU% *E$,YWavoIJB7Z眑-]ou.\%*iT.5y\y*LD#RtʁJI\) ҒBI'\ dE<-*tK,YGcR>-q\5V= <1 += 5i Wo&@kM_)xBǡ&AdRԅ*6P3;mA9Ή*/ԻKTCF&#(Xc0jniYM*6{3\u߹n L}G~Ro+d$\?7Yo+N&n&jsq9r _B\)gn`ƙfL˼#Ls8_KvIX.36dHM[M ,.:#naf5<ǤVJ ?@9v, pkr_V+MVBR[|s!sa09À=+({ԅ.8dTHy,м hmPJM A T ).T_ V1)5=aЄ&tİFQOAOA @+'%7U.Lf*A0 18`(tB¶LFÑp(2|>MӾ[o#w뭷!BwáG7[l'?&uNv`G]Ή)1-lPp`WF15G(PzUHuG!&ʵcHxjk{[ka:Jo[G*}'>s瀏iOV.VSJG2]z{Oz]t5w'̑0 Jwȱc=A2R`5;^󟨦B=Yni0;J|=J5ii9?i[$-hI,@!՛ hKėy6H|!SjҒ#5< cAq3WzgHIk3(;9LEMJr{MMw!xtN_ 3'&;'̾KIȤb搵HW?"K!WNlRQ ra(K( { ] ? l]9R:Gt IԢSNa6R16Eqc*!6utuj/JQƎS]ǚ)Es3G0dB6ݣ;C3f6/?3Wku$i* V9f ˱h/_"9.TAޔv!v76eSM㶣IĈZ*DtCmܱlG KL/(v6-|7ӧ4Rjpp\@&OlU`(՘l*]2Xb[JRpQ 6O3g|KPgkT!7!x5pjR^]rנ.ʃNQ^o2V{R 3d)e<ҶdM- (_>C|WB)~9ry录J{RhPb$2)B*v}h~Ml6~í5gxN9UJ8TKV^S a!ʦ0w*osMx^ 1'IU]&N.#AF59L?3n{;!dyȰ30jCaPFX[Gfw,eE)5CIUR(LL2ª|\EJ#)H3LR ;˛/ɕӠB<~_d[2E 9n+X-)~ 2vj6V*Y-IG+ -S.rx39s9܈!_˲`ҧrsXCb"{?Y^G$(Tp^t0 %Q@j`"?oI ``S"^+.i=Ђu̶#ś k",TZ._YXP/U* mwXX|up{5w2̑Z($wu=G b铈9Pr0lY0I&wa:aHxΙ2d~Nkz 2^RJϨ:V I29u8Y`{5_IRWӑ]%dR|ij*x*s( (oR*P9˂%d9RԬw-&Y_*:Tj)y\ Q2Tr7H2@9*ȠrUxWNe q;;!V9o]5+U ȉxdŠ6Ar+&/G  V@||6kfY۲,(ɨz[7QW-/$ZP +LJڦ+GqOin@ʝ)%XD}hV*'SIɕB1 ləMnMAgL+AA^ 8km> $ڴi3X՝jᠿ1ۻݟM08e>-)e&)U)͉M?8mf/7gv*yeʔT27皔@:7ʯy8FvPYo=J*]25M ø+UBN}YX)hh'>"SBQ,}ue6tQ5"Pd[wPb5:C8,\oP8!Ujd#Cms¬ګ`0 ֕KrE 1@|ZH ďmYbY V46FA7hױ6bMPX>ٕT'C5@&P0 g[ojcY^q 1j5yP oTlcrJlۺbB+]ve/'=|TC=֖&PmцƊ+KP@zZ#oX@,|Cw=w/Zf`V]3L7̼$.qRK*&~ekWvtE۾lRQUtZ9 9T#yYS@͞3e%ot;j7| g'$0C @GdЪyRK՘e&Ski8@&a&IBa6`*=̚%e+#9e39.'7I@GG7}x5V]D:e%ȠVN |G)w J+H@Rr!*QYU/Tyq\juf ԕY&"ܱ42.KѺ2A,WܱL!i*|W*OWSb5N_2`VYVWaA 5cfɁ=mߒJSPa|wur|Оko};mdA͟F B0 \Gw˂XZ' %+ kԂ f(J]qwdҡZ$.7?I xo!ij\Y :eRRpr1磉dbYhlƜ٭sWox3EloU٥s v  l;|Ϙwfhֲ׎xkoXc>+q(-*}PP:5t ?C@b^ʻF!bu©i;2Y4p۲|e;Tq@9_!rU+/b'd'2$@Ws] ItU*'0O`=є^O%uJ_LN0*pU65Lq22:p[ % \ dԘ!Eq!@Rہ7^RY YiWrYUᒕ0`8A1pJ/#HuP[Θ^V7^H&mMT}{,&nȸ}OW.[}ikJ-ԊmJV nD2]Ҡ|MfśqͰh32Yb֟=~  [۶m[l 2!r2ugWӧ\oN2 d,ߴ\,jYs-+HYf*pN83{ӎT_r*7䧎mf柱܎{pk?3Ϛ}[Ot9曮Уg6W;Ku _(4fβݜiױ4 e}٨s U^/5ϟU|ЎPM5>XV{JyzŴd5\N ]+$ vT Xބ8f%Px5Fure/D&ɸYirB\^ǁPOUF'̯ =jQb鈕̈́=UZhl"Âo\.sX,:%nA475ɵDkԯZ NtGy<P(e<8L>yGw>}g7j}L!')*&܏R| b/ue lHc_2# N3Sv!hqvYvj'u7/&>FujA\[B-cQ-$w%:dX\E*@ {s㲼dchCpfsIѣG|B~!2Ld\*:TeUKGĦDW3ppTki)$W&32Q|W]UqUIy͸E"\L ,UILx+qQW ZTGNVB*ϙö₨ TU"2y۵1+2(XؙLz7/zx$ b}0|a$4!絰o=|>c}+xr:b|TTx#qwՐ3T"(/ uȯfR Ҧ_ˬ|f@%[OA 44=`Z(B Ihj;f'H[[7h3aݾ3"DoJp`Rj0=YGdαeܢ2\X-\042ݦhd泖g'z(x&lz*RʽL+J"NHFK++J4WDڐ &sYIL^=0WCUqU\j;0IBh~d!@vUH+~ :dS%0.#ge2K4Ƕ!|*Wl'R yrSX*SC@R/\zh*%+'I3"2/K`^11"4L_3g ď%3V.NPkLJs;IG#O}/\tۖ d/8g]o+d$&L&Tļ좪$uEUe._BX3B]=ygF[4gRCs7@mkoX=CƬy@Ɨ0b^Sz![{yڶ\([xPm6dлƀ3۞i̘0 ]"BT]LEcQ R/0RaK `(vYsmF$Q^T:W7 Fuй ʪ*.*s:TŵS0/A17i yZe8^% @\]C]%,i&6wY(\r?  V%X3b!Ӹl9$Ϻ V6o{OB: .rC.=v\*d!oR̢u/q+߶nn 3ݻtYo?kN;ٿ(A`>)\~]Gf-6.IX—;5p2ONӹ7ej,\$(Z9YP)XBgB8kһx8{1ѐ )}١@QaT*1ϔWr˶yS?aRM+MvE=l. H]Ԡ29Tتi0^f4T*mhC$x.וKuB;U}&ZNjuyq7|o_-5sF[8n۱~_oxvc B9 rT]/u0Wc \ @bsѾwœ͖_MCN`'˙˯0/I|"M3N[KSL(i$##TǛ⯂H9%P󮼹H܋Zue^0νSP bjL݆.8ԝ`*7W`e$UmabE5[%ZɈK&&gbT%m~,+A(ιg'+jwp*ݫL lCYƥ~AjLe7"-X+R+q+BTWi5 S02/{ID]U$K`uVKKKÑ7],9D[КޞўzBcBO wۻȴ#}bG;-:p_h{^gPٴ{Áj},B &N8Mj*}ywEj^^]ù-}\ϾՓ0sfM%ĕ3ݕꓨZY2XaL, %+ , W U]4Q*˯(Y*3Ji)gRIfeU[G\DG 8Pβ^]/)ce-91NMP#aw]wmC[桲*a<72qETPAŒ}@ࢅ$PveZT(aPX)+Xd>C,d2$XެCMszL4Ecg'_MA&<,tɩo9<+QWSh|_ܝ^̤J~=ڨrGQ*Wdm8Mnwfo{ߍvLl~3knFWe=G=^N9縗w_`g-lkk Κ0وLE®ѯV޴&Zٷ힞4 {}w&jOkktR~XLץQQ %ے 7Ks'/Q0Q  8 ծ$)!^V'+! L,I׶C@r*SJd@ YɐZ0DU]V0Y˜Yщd+tfh|)3! 24@#5ud2 85 d`MTZ'S ٓ:Xlټ~G?1u\ٽ{z[ #7}mũH2"@Q/V Z7HȵsEXe17 jjjd˜#9;g5}\w2\HdIPvTr`$zf/Nk >Fyj偰s,n WusA'dfBgX;FݱxֆcF׿̝gin!Lҋ)xO1RT:Ռ-6\*^-\ j^bWd][V P|WֻDgPXR(4`f(F wT*W9_ z憿_؞t+l4q2=BFHYhvyu5\3Mgs67ɝAmZٞ?fH㌨ѓ`-0ɤ+ TVzU*VƫQ.ULKkcBUT ,RX [4uȪV,<&iۥ*27zӶ ;,ZenUL/Y %@\- U9`p`Urj wz/L4;gPٗR.i#jozYD:v]zmp͖/[O|iS©*M@K,B@lq,T[F,IٌilH4p[O01mQxsqYzhi q2$҅H*# /I¶?47pF٭^7c o]N'ȥ2NV.]N_Hac17`.^Z|f^yoΙwkGn?-I=btȹM1sUJ6͛I6IF`Rdq}Z-7)t$!zڼ2Ur7*F״ԙi要dTѨg&?C'\?&ʯ! B =|NU{Zk}}zê]^{Uuջ~6}J)AˡH~Z,WJB^k&a2VAb NZmD[ 9xp@ڐep> I$|D kfgx$iR.U7:Tݦuώɵ#rz7)?J?H"7~&~MobdQE?og>?_T*r@wQJ=K ۥBv+͸SaHh?Mq)g@{M;-_qHNUBH;J:~K5H!|d}葌GR"e]ebOsb([kҶ.q0JRw]Q{m;?xwyGjhc$"o\%`\">KU 寬N"6Ic@Ń}xSU(4;WBJBNDISsbEz0IοDI8G[|KmћD9`Z%8x.j79(jyvI|D@Y]@{vrj8&_I$ l.;jՅ]~m/jhOSַeժQä˺K0sWX&ȰRMRГ5"vB msȊrt¬5r59lfVUuIpxuuUS5VR)ЖZl B,Z(t/ "W1 tn@J2hTΙ9rAQig#Ƭt/BWd +fG/U `,QJdVәg}[veo߾eWG_+>|R_ ƗŶi>C /C -q<`x:R?uͤ xo|شg_J=2k*-Mh[q-O0?tF&61j9ؗ]sMYV(r '^͝gQ~B'pͰS?0 YіI.3tͥzժpfsbdXeJ9VdFOE.rLLQYJ{gjY;y7 T>]mYE.pĦ{ SH ЅmK@e`'L.k'/5\ h fe3ֱ c}6ibNpjl+TJuzO44 C:a$՜XZ.\D12a9y-IVYX8I$qBǚҙMg[(tdsL:㸮='gX5k]߹Ϻ¿zTe$Vm]ЕA 8w߻;NI@[SbS“HDVMRERА1UṞpZ,2=Uǎyla]4'Gߣڶ|bϣuԳ/Ylg[|}x;q $o5x?s__[6hzo<|'WFc{&kƴmC܉nWrYPb%@kqk8A?[X&l7SΚ!8O<Nj~lsdoϦMhvF9kyMb=+kS50b ҆EPxLRXw-n;QT,Y%l }Bq30e ~GJ$QUL;r|Ajnub(Fq(I$ `mGf~K Hk-dbYzuſ;3qsYySIa2$~-(_w;n֍3o +ʛgY){^|ə ?+qԴQ7I(WSz"j (dW#kC?K4l#Mde9Őu4'w;o' 4}ہz w+kya{fH9FP5HQQֹ[əC;_xsvi'-'JDƾAVq^9w-sͬ͸YuA+^ J\TJ˔#\g'beӥR5ryk֦o&y#r͖f&KB4hA `2{GAA&tWPn!hФ~8\o҉j[%|"zi˦pҏ]2[e@hEU{`eo(N(h p#R!]`S *,b ANiW@ܲ NWR+2cF<FQX3%Cb5 |jnaĹ(Ybձ&lD}W8i$,'Q4JrT˂ž%溿`]XO}9&D67`?[o7t - 6`]\!wt*]qy?c|]l,XC'jj]r=f2r^?niߠcM8EuAXGC\tӸRJ 6W݆C+.nrW=Rtjn4QRI ɰ%2)`Z5Yae&3)g̰ŋ)͕>[k{X=g|A`kJ FBa\7k7_uϹptkE8W ֱO3Smc }v>^ۼر8yY>Ǟt\:ŞǏ3I .x.]|h7GToCF;zduSW>s?}4X/]$_ITʧ3ނnYcr׍~0bl8](8tdn^@mD|JFE{ьwMH?20Ϋg'e€3&H1c:Ht:̓ H& B h+>wIPK|Pp$QEڒJs~UCb:h35CjP4@(Haa&psy[v9Hk1.\!J@3.8N.g) @m,2"LԽ&'IB}}Vl A.XLz_ _|eEXylA)?NaVje_x|iۑ<sH≌-v69^(ns6o"+107~xrz?둉Jm 5DQOʄ.76m^]=N_:Uix5h .H+O *8<ˈ\KŵW̪|g 8 CMZh^\΍Bk!4R(9mT&qԘ" O@u, ny84q ٩wɡiRՆpqlcF X/qJs2JANs&2+t[ ̴$Y>Nh`mzdy{!k!XFXEQ^u%qxJMlyP2U͎u@wu4奬zňdE3K=]$*rATԬV >sϾc/5{I,vmgX$'7፟]y߉z[ kPo+j8\?~ k[HѶ(@6|ŝ̼INr*g$9&MRRoѬ)j&pRհO4<0 t[cLw_ڵC/D B+l4B'YdjmUZ*TҸ  jM~uYҺJREmZ9e>Tke9 #eէ`Qק$vj1MĠ8$Mi+@=D.UeYtLlQJ[QDf! !oW+V+i1D'Xo]cv=z}B'/] `}Ʃl*^ ?I<|?za?0ikٵmOoYvE b񏲉;DaDVJQ;МZW\x\ͬܔ+[52^}'a@dHk'):-lޝ2xgu=|٫"AW]v7rflȕqnb,լŽjC@S jG5 ,SEʑv4] ^[ e f˞w{U BJǴ.1P%M ;BOWG'Z'V[.VdB*/G"m13;f`8 X^Rcu$QJ!aԠu\id8!lј!,Q 86Ng9RzO~*ޞ;nA5=-gpcn>Mǥo}gD%̧tOqry|jfht`kv=tjܱkׯfwJ!;${чjTeM뢓E$FbMl*PapfznG b(ULrGlc>sh^`ܛʖ'\`HJڄd .P3*EjQ1IA1"rkvH/E<[ʭ7Om֚Z3=Q+8j B&AoqE!B GҘBBg>H v2PHeoL",Y \:>D3kO(zm+j][9?e8fPTek@ ibUqV$r!=!(7k௲]~fm%J" wjfY }d\2^R76b_g&!>ECr]=$xF}}F3;8;wQahxg{G@p1VjB)&S$?RpYf:szXVJU[DZvfo߼*ʺT,,5RJj$/)]}֡$e((QVT:R҆uHauH{SۢTe%Ɓї;\lPO4|Y k*vySKY#3g̑0`5RY~u}9ouj"A~-V7YI ;HE .H;28T}JbbBd k&\-~!%n@LFc 5SX!j곥 ߝqo53W￞p~3!&DI<`={_sopȴh<}_Lho3/{F@3T75)QuV׽ڏT'TeNZP8 AYќzps9SّOygd@I9}dC85}ċ[ GVFo-F, \!W~%ʥRuҨ,,) HP#ƩY:X3 p=AȀJ 8( \i1 67!FjN#ʏi `+aɑ;c \PXZI>Mt8Y0<|3v\jܶ]m&^umȬVP%i]%,7RP]b!sfxSGEoabOaAT5i_^5S.=sfިnuԸ9HhY6"RD Qh0DOTz6P"bYL c1#Lh D-43Vfk*G&alp=b)Uu,؀I`|b6[H$Y!9Y?txrǾR%&]E$Zԅ6۪Du ,l+8b1T@s*UaHSi])#mlmG\aͼ]C)B m8T)+Je.0Yr؂@T ³6,ּ*ɱ&qx2VR_Dҏ`9~zZj۪5wt+"^ٹU|=?Og?+O0u) S9ݳH"r[6sůPQ.yy3[7w#"Ye8͞>+ e3er~Fz&wqr)<)B#״u!=ʪ}yӕ<Mj [H5 *PDOKć ͿNGڂ(%)TWlH*!רHb#4Meҍj~` wֺ];Z;Dqp@z@0T _fi`ˆ *e jaApj)]v1UE%,a^axEȱaR=)Rx#SϾbyqAEK[?,f=8X)0wS-#4Ȗ+zdF@>ڰB.c/ugֵkAA5$NORU=}r;}E[-5+w!T}uWJ_:_Hf+?w7\/.kLM{:>xYIst"$KůZ2#`J}#;td ܾsF'jt97[վ5k[ڏ`2<3N#yg}mT|4?RERddϩaZ}T4b"wk%@➡lMZ) v@iT eآxژnd3 %kqq @0~Ш4#v0j6$DDF҅b=Rk!SN93HVs t^TVXFQ_ŷL28Heb =?)ca") I3P\`į(N9.]Y7Ҍ>4iIOo3p\iKg5k''-`ܪmCチ"u1^O^|߾ STѡ6޳cr\8sw^n9`}EO[Tz;~tO$$P;qs6okel&T1O:]GJ]>|FT*xSOĩViT }}Lt+h~r5\njryUtS\a:@\lzgL)p>c)Z5Lv;GR?@1`܏Њ!py|JH({5+c~g{+J% %@ V]B Ẻb v q@''-`-qXW^׿_{oB=M=;7׿(2|Loҫ?xx:gOO%zē!nM$0~|2@J?dUطgQGGwwxr#$s.^zvk }e C5͙#DK՟ttoַeժrQG˯LaR 1eT+0'l/ď׊LUN`XO1sb4"cm?'#WWuBw4C:=OtZ1;Cb.UU]n8Sĝ6kuwa'ni+&}] >7ݝ2t$cKe$L."W $WJIbT_ZZfb?ò(n!?4؞݇ђ!dz-sp\;Jf-P~hVrCO~ۛ3!aHO ~ӤT?k=ϕ @m `j"D''-`mV/lV̺sǎyC;dıPr)u٥s'>IUItwll|=Q`؆9̅ڏ9 G6/ާS+;n޾_L}6mWRvA@ eFcm6htDTt;g(Ȧ8mtZ*k}do6+?VT6 eրU/NJ$9P2BGAUx[s \X5[ĢZTBu|>Ո uWEG'Ž3zE0 M:RV:P^R2u_T5PȦ*YUof `BvU>^#:q!FSsMu[f&wEo7A뿰j!{thcp(bGXBóCm86k=QطT@N$I8Y<_qUOLf=6ũ'xN,O/;'Eץݎ=xԑc=~hygA%(jaaۋ#{pU'G6b% ڱgs8/gK]vKb%mB $lZ"lQ@LL* |x; W&:%d j({Rȁc*нhڊ,V7fnl\ŀ/.,dBpF>[M>31&WL*hŵVcH'k$'MeA$Šw@j4%d͗w-[9a3x}%D L"s jGw#ȟ9xqY|k$j54; Jxs|zo[2QW3/GFg7Oa`n`dM(I,,` .$ pX IF=r,^Ȱ.XzטG5ÅGlw>Z/$eOůy{A\+~mYZVt7nF=sA?Vmޥ rus"G)ژZGlF3/Rm4cg$'JàMQ~0jWYQI<[9`K!sUTA V)S`ftFN\y pjcr d0A!]kN& :62]qU).F,x7de%t>ݽfmR.aWmy+2)+eʙy1}a\. Hn TLp`Kߩ׼D*21~{ɻEU &wX++Ow8\@$,P'^1_^&CN'_2)~X`z\'$NOR/Kf=0^^~$Xp%FB968QhQqT{^pkNBa%'@OPR(_w;n֍3oWRy+ -ݑ;P6곓=$?RJ%ddX4B2:P(n˭d=&Y$ϓw< 6: PuTqk,񸐜S@ʀϨc%lG(c̉> H:\%db8N aS@!R`*JօYna努49}~i%VVfᎹtpd]&*͔ %ug:A5v FS QXxQU_aBRq Z%o}dÆ_\ ё }11 -*Ȧw2+*$5אQOSo!4FhԒ~X4x1`Vj~,m/}xls6\KƲ/jM㡅c%L&fM/o<׽}MY5{+K :Zvwe^=_JeP陈@+&B 7֢VA A1Rg>6[ˤ;4275ٕ *nIP@{ 0fZSZŚP+GB,oW݃!cޫRrA>Zj̛l`CʐXI X$(W Vliڥ 6| 0c!NW :M$_{O̺ko8ݓ] q*S|ቇ9*eq,7{};j//=iu$Vds=iO|֛M=]C}…z镑ahہj+#XMTgxn@ T8\™9ݪߔ Ċ@3`T/dtc}]?=<$ͺPhTrTtx}#dn9W'\gdP7x/&iY-zX$5 S7qv 5a)&\Tn$[݌":RFgbPZU24ЊyS20롄+s-1@GTR0X9R4[x-X36nv0#c/iMo'<۸vuOW1\īT̃n,k8lf  .A %hx]ar/\$5: +E:2Zċ*Ŋ^~O~o/U'zgrͥţ'"˱ZۀU4TXụ?m3&t( ХsD~fk 9+8L) ΍!k)gڞ\`( ⦿NID k M _(u*>Y# F`Th8ͩ#[e% j3g$38r{`ٙ,_xS?Lbeǖsn~~;Yf{FFr97B h $!Yj%B1v&2 F wBl:4@6?'Sr}"UzC}*lU^)S,xRj~$ qA~nC9uT,YT'ј ٺJwurr)1M&,B bhF hfj؉AfSf -/-ul < )Xq^Vq$>%#Rl\L? 7Hnz]@ 9{s7v] D\?1k0)P撀oc_qٷluZruY$(/zFwO'1B("I*8id,=8jMCYw3JwSF`=opXoSTҞT~Z7!w RӎjV}h^mHP gE.DI0s4R, 4&(LW3#UN4$Q Vp7itI;͆6on-Hi$j*rZ1qLMs̳֤RIs LC[H.\VR1(R޵לypx,աCa]ٌgo5X[)p5ݸyw`&ڙUW]u]ggVj?X)dNjaV~3p)cu L[5D06בRb1f/3$N+;2>Ϸ&)^EI<0=#$6FGֹBIu5R1YP`Ž_,(ĈA)@ MTX^1TV'JxBHyQS5J5S+g ܣskZnM)hQ`CSgEYJz|vzM*dn&A<.Sgp3z0/JCV M,c;ܜPiSȌX\c,v rD!a:?ESV,B+$$kPfͼV:<9:[{] ڌs\bQ!I`ށs0\p,CSʯh XXm \sᆳK.|9k4 |A: O4%7:OI XAN%>o1kL>k/|H.{I$ n [96T-2ߴv@(q٬ uc%ᮗ u?-}V&lF˸{vv<82Dy*w觙9ES/-88âI uI@H jh9 55ёf+U Qʕ2.;j5 *(4p daaQ5J-$22pHPG $kEq>_`j* J"ZSm+X,@.@I`6uu>Z \H {>@g5L!4sCHGcVf!bJ׬]n?=k{~GZ\ƥi`ybpSh8aM$|W{n~O쌒H"$p p VC<`Sl+:)ݨ沞t P sR$B%#[F $ld1bEteW;J]\6 d$5RYGٔ(q*R8iMeXNt#z3BpmEhPv cAAqYkk}/SR94QK*sGVdE:=Ŕ *V1uxəIŠ$꘥ ďi Zf(,#Y [@g sLCW -_YsEOu:XʖA2Y=2P40SE(:"R@yPA,M3.bsf戡(hf:&qX7?I$DOݠVj`=@{zV_3:һec>1Ll+k-@5w %``|aNWtR8l6֛"ρRӘW\2бz:9v6.I?C2#W\R>^&3'*jOP.렀j͙uN ˘tdް';09qjGnCjTuZg:k sR)OFa7]xʝJ{uWSRVsJ0um7A h5qj^|ˤ̭kkWW@0mMp)IjPӋkKR%46پ7afv]KR"*8hggav *<$*AS.`Kq2*Ld&̂pOpu(`eqI$)-U01APWsgI., i]*p5зa)D pjc"޼0 k iʲ~(v-U 6 @csSӎC`Fč?ʌ(z:RPT.8=SkjoOe.UB0`KZ+qH&*7W9S=|g{7>w_xQr.U/7.FRh\;#5R3C'KSP@Z$u Qe3ZlgDTY$cW3IG /@RrIPXAHi"V9VhGTdU&׾(ZQL#눅k=E X: vDEЀdXI: #NtKt'0N"$%A% F4Y4@PQK{ŠBbˮO9E)+dB'_AЬiu*)2n:A Brmjd&*[)Rt-ءP9)((1ǀHxxhR ?(BXT4o`R:b0qpSHҗXQf#^[$XmnM߼^|[oTI$S/ `Oe"ՍGp3ٖNf7YCYƵt7o&ws\]|9΢Uh20VA\Kh 칠k#I󉙲amF3 zmHPan{Uo8̑\O#n*rYV n6/nޜS#95 PiJMjEQf#c~Ԛ^6MlIdRxͮn{umsz7wkՑ/ F:BTsY` (TTpYJ %'f( Y 0Y.]]`Ɩz~u>V OS,l^[ ]"X"AϐOX*  F,jBYЧX][Sc"PQ;噃 3܉/$XXwZx׽ Co,M/([r#|'i|L"$xb6z) WBmX3 su_D++뙙Ջ,rfuFC#1s_qb+7Să?zAYI~bzuU~}ebbf>R:EtUAn׫%8k%doG{0t|%S{3Tb{DNs3_g,Z;R GqbTG6+*w$?;[_rI;C"[k/**|37䳿W[q /UAT DuwQ(j"JRGPupƔ%`y@!KSt6*^*/UϓδY|,R A2 ռFk+9Z"\R`ajiu+%^0چXf(3]4튠+3WT*+Z dX8I@?'?W餢s7d.tTz~o_7_{Y.]iS:a4BI{߾9yK_808|bGZ5hfCx9e >cUq*U/f38hr޻3Su2(j˿~Ƕn^P_H*F .5Hs=AFJk^jЕ4/f:=J{PlԘh%yEv^ǎCe4u߽j=K82bL3MYכǠJjpu>R͊ ͸sӗS)ryK] esq,8+d?V#e-XP aΨ oЇbBq"-5n`85{Lr$@8Fzc[ rE$jQZU oITkWY Hp4L/\ t+1E=)ZCs c&r^_(PRol5͛v@:X:m&P<] [q-'& ~,V¿îEM^q}k_۶#'B*a1⫮zG˂|f[oo喅{my5 I_wI.bk^FZjZ h⹲K;m7&ԙ4&ir}3?e)r1T#-d:|U%w5wQRjL:Xf ͹\7#In|k?<<>1M)(Ft^Ia'pePP)Mm|/lֻoZ$NA\#2* 5GzNPR'T 7gN!zL(>i.Q{]B򥍄?7Hb;|ՃDUI.DTyh ⲫ[~O)W8Z>P {4v.V8 0 ( {P 4w*vLl~[?~6_y s미Zoxbz/_|EIO5[MˉoUd}Ta9妤Ds='dPE>~SjRuֲe۾?#5`s@$PYG!{Sf{`>I+i[dZ^ y٦r{{ȓǖ--O>a4nڶ}|Hai4 mȱMYSIX^K\ݨQ2) >&S#GOخG!A`~qoݾ+[Z"Ʀec& 0)Pq3S#xE7G5h07ي WjBD MQRF"9ZmyS3~pE@Zpy0З؟୦\o>?;Iʲ={ZsñWo]jpPk"*!3tvёH\2E܌I)LDviBH 2)Tdme/ݵ69qCH\تlֳ1}hT۷\'ywbq\3h-4\htv6 V!mJjd+we(kCfKwvg>2}h߾}]]]b0PA6)Z9hNWi 4#N-Ee21j0%UE,\R MuF|l 8 x"1uEj `iC3lqw{^΃>x]w{mxƍ,J9v45gIOC1HR( Ewe9D"iyooٴ/%c_dEpH?o4[b]>%ۇUe.sФ[m?M1S@*p`\K1iV+.sPǨz&;dXҮmc +eڝ&dRҞ{)ɓY*WjŮ{.=ΦXϸ|{_+} %Ţ ϯoR/d͒6 O,1ͬ }.nb?W‡e1L)iKqdySBf-/vyo ` Yn`ty-yw[uZ k֩2eS񞝃;l)z^=I1[S[amݽD&)vK, dy7 s0^Xwwݗ]vRom%l9.~)6EoT@c$fU8R8DA<N9ؒTZpT+lS!SUԁ| 7ZW;~J߲y@ѨٌwVP plڸޮKB>rb$/lظYo=66n-^8RM% 0Pݔ@ZGa:GCR*R$ T_Fi, B+w^pS Q HCXDQӯ*iV.iҲ$fkZǡ+~ą[QŸ8WF1S`^֎. .d^ [ڪ^XW2VFD&;ֱ֖Uaxfڢ]jםL8)TLdbVVdYW~ndy -Wl`aw-FAeK.6XkKZY|LI'-Wp=/,/.]}mQ/?3ia2JDXD!#A%e =r׵4ĺDb9۽Щ!)P6)]$L'Tr;X$ 'PQ׶oGAp.Υ<9{l?-F' rWP  0>zCMg=|0U0#zԎLMeJ[sick XmoMZ*=B2Ax[L^?_<.GWjĺZ^da=f1Ԧ|Y.'ǖ`,iaW.Y/ۊ [rξ93|V;6 Cp)`* JiL $PT [~+ǁ+PI< 9Gi{z݊S9~u/ν`7Ƛ0CgBʩ4ِoQ-z6sLy"PIUQ,vHV" 6ڂHٙZ'L3D䊙L]S]ZPnlב1?ú[co~{zz->JjKqOeqr-X1:55OzS A8kFT(/Jھ|GV*H?bx'TZX=|XZXD-c/UL<ϑ6dxbnXQ~ P"nSb9.jsRM* .zf?;lԇfGc'7eRDZkOޘ#+h,,_d g\ĺZ-o5E}Պ+OLn^߯MFY*+WtZqb^帖p6g;ef aPx<޷Z>٬ֳex|u:puGF.3TK[6yo'Q?VfMe2 eV[fI 㰤QS+Wk\6)K3˯WzsP0V%7 ew*!%հZa59\vyMPoA$gkwVM!bKGGѩ럷3xfy=?ݾe˾GwlޑZvutd+L)~u*ݡC"aIe΍T}DlKa"0%_7849~3clpܪz_D0 egc热`fp"MINFX+;lߺitb' ٹs=,ׯwѯ\?k\rŖ˻ZV`}\ဳ =©񙅅%+$ I\/~k KưB'*8:vP rQLX(DTerBp6l%3Ըh5{Ro}];/~-̀clTFmi6KynB-BMHh!W\vb]ߺpd?9;3><zJc, @@Db;=1 mE> kUlJCR;mX?!K ظ﷛"t1)d8[ɑ4[ZqМ4x>nMr /?_d >ϓQ Ъi,TXrJ4J  E$wŧNAfxrX<% #JJK̦=56rrZmyǤ,*D8cA;,,ԉO\SzU"VaSt+霕fucgɛQ-q ~@a{ǹyo"}߽O\JW:VEjԸX4;՛-~kTg3+sֱi i6R.%\*HY'vGQߜ'~T1^O}o78@ "6@YI`X(\)B/ &QA"8`K՝-q-k]سg xxv}=/6 Hg"a;H\k19כ`8brcQ;# <J>+yl{֞KÏL,ѹ<'xzfo`@} EPqYsW@%*'S r=BZ葐B)x*Blb0e2hu%!T*aXrP6U8Ua J #<6:o{~VfGj`;RR /Rjfy((#L_m5EG4)Dmeiro $SĒtzd+ YP_Ojo;)BH *5Ev;Pgp[u"de"Ϊ3QD^ e*sF0y84'GN>qB!依[Gz1̀$H 6j/wlxjC_f1@ bL @6cJ(ϹX? DDP!(BHz7*t-N\]^T5ٚ  V&b_Bdqu3TT<;4 D<'Ԗ}  cx 2U+L)2%)bH# fz3u]%, ~;췵+/CďD*Qy/Wy0Ĥu:5>Y՗~^i}\1VP pSQ`0%M?f ѫlYasvmxBa(4͎.w|v3 _t,+G6=MUǞN5!d+`bM'0 y̍10PKe4 jYD)KNŅnN@%1(Ln`+v$;E^pK5ԊJT.!hp7T$qPD91B.c_vLʓg3)׫Y⫱±q~2,4wKZQdBM-\0T§PJNQ'0IzGS9Ͱ>F*>[M æ"Jj>U7 Z(s42QF/e;V[2*[/~A >O;w>C;/'wOl߳3~6[ /j |hֲ}8\ɚR~݆+qdT"$ #uH:SԬTL&R`R f7g`Et]c`ONܜT3q)*M5BZN* jS"{Z~/,Ywo~~WӴzݴM7ѕkvcOsG:cpLbM6 ܯr9i\KK3j\~(t\ƫۿd(!p%Y $m94fk.1J4ESL0,pR,a(D- &2J[m{Ky+V磚S2r^Vmƈ0 Oר鴗ce/|7d/itt'ܐ뭪o]_+R {)23*=:#up⽍)dFϜ0l7AT id_v:c,xY? à́q>q^mevc3xO~J$ %( [ͻ{\=g莝'UP#Pj9OǞ 6Ȼc瑭g$"aTD\(e13KhpF,M5k84ۅh@ _9՜%pi56ngHca_Q5ǧ!*+k:PrzIM+B^Eج"YgLwYXE-bs4;Sx!g2}7i$mY6,eybv9q+jHÇ<+ϾG /y 28B ~U#GeשDWї*Q;Ct3S!eDP ** )L $8pDC=S*B&՛v\%8`eѓdwnoz96gbv7f|䑑-Rj\~B S"3u(J=4R F1GD&PEj_m}'T"KQӸI,m!y#"8W> q1z&B>ttiJޑZPuB:v{Z[MO~rUW-Sz>t.u~?~:ֱsf?B +@8\2G`bB j؛&BP65_(C%LT0 b3 Vsl L Bvcֿz?~ɛ|@ᦛ|~V tw*]-&Tck7zkqdSĕB#D X&TgwoK5e (u F0 ]Q "MpGGY:7]ܽ}"&|5CҸ)(E)K˸JK&.2@G%XX8$5zKk*KF %fX@R) P$) @K۽`q?2Qw]ѝN)8(quׯ7d ;G<ш`NHOjd#8 X^nkHTB&~~Hީ׾EW,< v\U'!BBwΐDFu&\ƗTMXI=l}b")4g1M&Ɖ b Y0v g x1ܭ# ƕ.ԃO뇶ck 꿖nuh@XZOͼC¯qv v%xޖq4Xߎ=O_ϝQt왰7mKV&:Ki`Y%hS rg!V {7j^o\L )^KަEaCOxů5qW^H3ƿhƅ2U1'&5z TĎ݌=;iC14Iu1(k&M 3M Eb L@y.AԆ5 tat7#I'8P޴ izIfcۊi ?@Kٛ6qT o[iSfCaA%ƓWLL2qp52l=z/[e}^Ps5W6͵W\qu:96%SHGQ# 45QV  `U 0e 5r[+8}F`&LMWxc;A`9?ٷ4YCUᤂITUJqdD's[dԿ c6ǡw6W|:=53|[IH-VL".TFVԨa+| efہQ\hw llŏL O_PC\c2S :){V'{mK9j^˳f%pꔇ|n?? 7E?1"Rh& )1C(Ӎ|PlZuem9E*BLH+MmT)!l*=i sS*DhhلGz.dGǷ"QZo b`Oa8Z-%k0]1RveDZ,>7<;O3MȐ׽]>z̏M 5/Z0a_ )XC H 8X9"i=[r>@$I&5Z9P̾lBfIkL1ݬ*%RirHJL4UzHA2ʤC2S|HjR44R/Sv1En"͸SzϴuSoJɩYb&+L>Def&ߕ=5KYm?IJpͤALCeܬ ST\Ak{Ǐ߲eKuG{5jclok&333f'NشiSպ;ſz(J|İyf- nTmvn}zyoy+5=s+?oz{M|5OVF(Ig<"&%,;]cI¶ҿgӨt de6E›ڊ֏RDsoc>rlhY ETMGQ~uR6&2znMᩔҐf#*$2o5|e8`~z}QIRqWf+$T+﹎iS/v]{f2lXmLjy# II':vm!Strr2J} _>T|8g.Bik6S(mO7nZݺgO|,zĠs;sk:ԞՁލ?gyks_׿׿=ztOJJ0p ĄKB)e 2u*df!'3 IQ^Ezש##{zCp&WDCnGsH[;5yAleI;0O*)D4]VԨ+De@mS# ZGq*⸧[)H22dc2vMa#g|? dlr,xblSl6wwכ큞)(aDeMU8b¤)et %z|/ ,~W5L7nLSn=tW/{n|G>d믿~޽SSSA{z6c]y;TEL 8!Lo:JDUfL ;V@ x4 ! $Wul5[ Iza|dgp˖fZ9|oÆҳ oOCWt.Ł %ӰNQgsVik.^x:|2Ɩ}lיoĉS۲cό]rћoKFb醴?7ste0 '`$Qk$3X5*RsYخN溻IOgKG>r;`b!0eRT%&݃Dq&'eQ4m.0#,z+JZ@O4 ΃fuV.)#nJx5#cEL&lI)X8ooj?c?^z^Xr`žږ N~Gk}3퍢hǎwy^iw}{җ\*VJh~=,$P̓Ψ%D</efr#meGp|:jM8lY,|*|8rj:vSpOOF |.@0T2*qM&I S#z^}L3 _B~{hhH#,2]v(Vi"oOzvuu='O|pa[oU??785AEO̡:cpMM]k `Ab߅X(kP@ S~;vؚV 噙0d{f_һhB)p;繭Ȕ4XBK2;Yv:\0jԘLf751RRP]kL&mCNW8 C{{4Q9gז#GN^tjTXLe7h dvM|p5Wf\zV Zςێema7o2(`q hDՈj5QIFk=.ƃ\ ڭvs =y86HM-+UԛkER53'hƚ6dx}i1j`+5G?`jqћ&LYoh=IfӦM^_Qjnub%RR&#(Ɓ 47lV(h՚&fe V +Mm#EXezSR{Z֖R:hZr%b;, Hm[B+BS֎=K>(AWR፶(#LCgFO["wcۋii7l;wgLrq- iY1۱cz^;2ŧlG.~.KD+. 9> "R!*D%ךVjJj*$Ϩ^H2).e]ID'Krng\IS<FHRtot3#nlk1 SA3Ӄ}^WH菤+_C&+c3P6c]vyds!X22sWJa_ 5fT l5?,@΂X&.@["BV 7Vjmsl"w_8UJA>j*ȼ/* li(փhetij4=AGs?ћjeC*\[B?NJl㉓U KuM=3Ă#ŏG83صXrȡQJ1z&lc`w9kkXRfs<:!0η5oھ}zl7 P߹oǞ=ӧ:1-R6Vo8E 3#Z*TR3^PE *R-_NFlGLIΩnt O޶o{2[ Ri 38\Ҟo/XR][6|o2֊JfǪOSclSJG( RQ HEH͋%`e},PB+?i% QŹSpin:1|?'q{6,F_ʧCHЪ'Lje ]ʗؾgE@}cz !=/ <jJy1V @YQqxWX b#T0O+BAEώ-ʔhP6+DZgApH#})e\cO=YY9]qGfՓOGu-; XooLwɕNT4Y6,G;3J<2e88*D1 X&U\7#rdKU42Q?y۱+Gxݥ['~`;[lN;1aib{O~,zT9GvԻ%hbΧʂ D KfIH(PVqڹ! LE EĦL1\` ÿѭrm'aA(|V+"fAOR 69EpSaƅ:70 7а|x|}/Uϻbȩc֣GT:T۵o߾ݰnt* ROOOz8N&jF .QPA*VHh ~Pl=^ d` c8Hjt$ h~c[^뿡剣GOצdp /}k_߻isaG;[B./fI>*eΨm~ٖ{e/*d .ecEv\6oxC߷\)DDY'H(~kr&( Ewdۖ4K(84֚xU6zF aЕۼhǺ7ٗQ"[3T7?},Rv7ڴc3Sb idli1V2 %2j`2T!9_@&DWb:hoAp5XA~F2@2^ D .DT9 Q$_8Q3 \n4o3fPG_/ vn9 EL\(}QXС<'])J==\I'ޛuwvZ{_d[6^fq<̐d320fC 6dpyfd %LB31cKe˲vt|,$.$WWU:uwrٽfR9VZ q1kG{V]58ɛ6 "n&4,A P=86F%7+D8ƀA369Y'K-RS"/DpOnFSfkacN9;54AP^32 s.Y]>tuܧ׏/}q^[UFVL^KUbcJ@b4. jIK}aiӵ:6 !]  >G&Xh5ԆshĩO-7̆T PH3Uf-r \Wx b ]UaЖ(;#7Y|?b o)8m z&1Fݴ]zIC ' v8txr'J/fs5/pl"~|싫Ww|fQ}~VUKo(PR( ."p`PA0*,`\UtWZ 2:HxY`qZL[/FRSdei<16yOVӻWj-&DUj>7JÄ>0gy&WNJ$ GQP~k!5Y.`ֈr_yxH8}׶]R(a%&b܂ NSV%͈aL/A\+8yRwz+ @RsSjtTEwc aߓy&5XTs ۅ۰̳T*$,NMLuVɄ9A.ªLܾ%yʫr/zR!fx:ںk%NeďX`-;`{t~w~ѩ|q]V չVvBu|d#w}szNj*֢^ei -5]L{Nv |9MC{_+OǕC+ֲP9!'aAuL?_mk]!ԗ4rlɃݙeu=W'sB L;)UahU9l,tCjMv104<3j&kQn×z/*[f ̠ũ|E^Jug$X}(2ȐL8X[19=+2vrR>2N|E0'MI0:4mK8o#>aB-,yK[jj=efC#, v0aR= GyV2̷<0^E db&dLlTD=S?Ȟʗ6NTX06^lZM^#SqP)̨q8T@,cADӂw:`6$hu'Io`~.FSt/e00o~ඦa- q@PϕwZr(WoKEKĄ]i@#ͱ?Df U 6+z9Vة/>nbcAT5WroPB劂xǺ:O[W߻ŏ#†y]_ʕ9a ҩr0 jUYm-c඄S>}F (!5hFֳ=S7DGFj7sHqB4DmYioDjN 6! 9|kn}N3h:k_׹|'s+O{ΈhWm9gjnqN &FX_=kϙU$&$-sħ1 G$ M(濲eOgN||}#UF wJ- t)lFg#F0&/΂8d[`OOx| n))Q B~G%,vgTz%_Zqw߂NS P`Z2e}*0Y9s['6fnQ Ax!.˽8NP)uZFKg݅+VmnYN7?[-_CG9֍['F'Ǟ=wgwmo\r~)ನzi]rF2h kEU^^`)GD7acdۦq>4|1|vwUkJVѭk b:(锊Wܰ83Nђ2#j7* t^kMΜ=2K`QQ#i'mi_ Ղ[0ADEO2`W!8 Vo}h[14x핹>iirIEOlqX`WT(NA}J! Yͷ Fp={ƥġ- u(<  =E{6`T*7(W NaiaHPmC<6ǯбVڧB: Ɣ3H;dF. @b\"roVE]:Z׭WKcS'yn?{#*ɭ/߾jpӆ|ǽs׆$I>gVG䟲l s(W.p_ދ^ZR+!Ҿ>[Lai++t`2N]}]O}MxKOu=:>${+* RV׾ֽ{H-4>qԑ?_?+fߓv^^\=Y>:ݜkܖJXj` Va qdUWĥ02Gw82jj5T8/Km=Z93ﵧgۉR%1B eҲT!J6-=8C}#"Bcҥ4pX9"\ R)tup~jȩ'hmXc/4Wʚ"kXi,b%$m$LASSh646\+5O;nup3 ?-R-|Řg s]36?{N&JH9!J֘ZG$?ìߺem'ȝ:>oS8 Za-Qae]\H!/Qm_wY~͍W?ஹp Z=tʫP\怪m_04khX?iMW ӏ=n;V\?il۷mGVU%n+k7ڝVѕϚbBJZ\a4$8rރӟ81ZF^ۼ {~a}  5 L(.SRMBBG0dtLsrKl A月.:;a$eJBXw0*l!pVctUɝ3LԒK4k~[u%7Bk{Qzla׆`x)mQE]^ы֫[;o_d\cj>+^5u֏1$~ USȪ֢^ I itQ {$Iza[Uc@y%}lSbL/d8Wŗؖs,hƵu%˓opNw6v|5cۯ,U2h ªQ0n-$K\͎ώ{o%i'F$^mk4@0ݮ6 TZV("RkT!S)L{X'(.%Ta2@âjAJa^i`B$V`E C^E. [R( *L/@cY U@"AdL=e\  *Iؒt&(*5uZF4֗?“O>_?WNS#gy_}r;Oe&Գ;o6ku=yz^7^k|?괨*B) z9q\w<v7̲ YfK FC73}9:[~zf@,𚳯<z:o3U`/ w*˼8u q~T Zǿa'-tCW xűF;_l;pcp8rLj!nn,&6WFf5֮_7i,n&(*ӏ=;c7~!WfhoThYh|n+aׂJD3ʤ4_lvdVRrurzc.m]xU N7_7} ""9r ɭihbj\gZ넀-TJA%y8Tu4Jlϲ+/;"v^9A)CXT,G3. #F᱇HuHj=9Lz1(<b"9KM lp-'cl"&7.PTQeS xj}Z֘,3ee!609yMoϷzަ<^{[/s)h*!Ko!恿턢.ڢ޶!FPXxmI}3-\bt3mu;$u#p.Â2疜l4un;z'+7o]a%F"99ugT䫶\|^~b۪MǦ~홣m+==P_+MW.|+i׶ݗͶ6ri0nbBo9 aki0yfʁ)ғy)ZL3B B-X* J9'G$ԛE+RVGB١$E9PV;(,@/_-/uY_0^J ry& hjQ!?@ eqkoeqQ{`τb%mإd@-/`{wݵ,RjҮ$h瓻[W6E[~}^z1:J/R3J9j{.^(˯AkVtGM/q  R[k7v v©!ݍ$VKyZ(+><׿x;' ʲVKn|b熅='ҭ'eeܟHFbp䈏[J(̄t*?key V41<ߑ}fLwTDӄrbo{ >G+`z=I3\'~\Ie` a8,*As7E#VG(GBx0 TQC@vL]E^G8hf6^n i? [MU ]Hv^خҼ|jmZ|ݤ<*jO tu̝ɻ&oo߁{xV!~ޢ|>]ן};[;{.a=RE`֢.(p]? -AL~s?Ds[o~٩9j4&$W'ѩ\n'w_o J?M5~t|jwT`a$eꣃ5amɒ2u-#X YȚHK~ ZɆ}ۮ^q6WMy?*:4(9bэj~(V,q#p2#BŞ>{l;8*.4A=j]WkgOa}wU7{< s`vm/yugZ,OAfHkF稨xA0;8VdHj+ag>&dOY*꼵`oG~8X;-+ٛO~mY L>BB~;i/~lv0YҳnZ%UQ/̉^;}/>z$kz+g-=kֿo~W󩓧E;ݚ7ߴfqekop p*Xj%V]w{b끯==r LXpq:8,g=Je,MPιgRZNF,坹a h2c@WSX70adQ.Mفof.aPij}01̬BE` <ωqdPK &{h۽F,tx 1WWrx:bt6F``YgY^zԇ 袀Oڻ4Eky'ㇿ}P.۶/珷VT-Y}׻_=.jy9RbZ <Y}To1++%vJTnC!V̢3Pb- YDzx-AV#PǁfD` 0vTJ)M!!f Zs]MO6N%j^ }yhz.\Xq\zunlZWۛ_&33Վ𽜯{.ݾ\¦ua-Eڂ;>zp}xQ+] Zp觷 <t+,-M^V<|Jj)2qe瓠5s^a:q= *g G]0?:EuZFJ|1kV?s g덄ŋoE-z9_8 ]?9K ]:{Ъ*8Tao\4@p,M3G;VJ)# p7n2дp%VW~+O(}4*-sퟚO_X6a,x,ܻfYd?Z):s)hcEraK/X/B >?y?ge8IxI10{* TCe~!HT]ITTfeڭ7Ʊ-I9૊ cDYwJ@#CT-7 DZ`` U@n"peNe%4;+RZr29L,X):Cdݖr)UXڒ\ 2r'9v\y-t:{1R3,8 $dܘ0Uճny+Eq 1.ZZ:ڽF"/[@GYwAɺ%VP0Eyi;qW([2=dzP]wh~ vZnuq$]]G T-/NRp!jD0U>.ܳ`pJ7SyW~4􄭚&{,G~t폾@f7rBfN ZjmNpw 확”52m$%$#N#@PZ\ݲqSMҤ\-,.G+AX]jrvH=tI-%,ò2)g ],ω mь b/Et 9YF1`\2v Q3 2 K)sVFWcE :K3w#fWS"a4{Y/m-S`}ؼw74IҼ?x =sģ[ܭl]BH=D1WKBf,w4cpAMRlPx"Xv@}5TYm-}\_"(gb gJ8U9-'~K &ա>G_`姼}ib.*nO[ɼ馭DSI̵P )^v`ӋB6hrXڭ`=`3C|)5Ta{xs0ν&p,a %^wtQG-;`?߰q[?=)=|X|t]jfc`hxfծ-㵝ӍM֢.yZKDiDA#GB0q2e~F04aX΢ЪI k8jcH_o(!ҹ_{Uwbh[_sgbE<5Oy`@ '9ƒ!ꂣNÌ޳ J7a-,{>4޴بԀ*HTH#e Mi{NOָo^J i֢.RXM|SIZh`cvq@}><|~+ )ZKM j,rS*7U}J{]2nܣĜ"u\lfs"Q`Cp}j>e U#ðW,A[ڢ`-ȝ7Y=~nk|u7O_=nM393:tl}GkџxVZ&% 7tz TV*6Fv}J,aړu7|n UQ`#(#L3u2TʴvOjbMuo~%SD4mFJ9Zo A'Z9NiV3OyJYb8V;Bh:c3h|2NS nɦ\Z!q9̕&R8s˰I99۽.ļtzb0aܡ$2n=k/bl#fRTAA@Д֢`h.43.X^V+m(xj ϰfҜ\II 9;> %R-p nL@ 1aUv)$E]j7׌V Voq|(cq߼}{7|Coyݶson~}KQEUԥ*QJi$lCT73A8+sX=Y 1%LT@)%GkT;g)6a6)ݻR"\F+qCI0SfiMU2fnGrbZ9dRkI"50O^Bpu;hĭri=Qiuf\Ƭ< };0Y8?mD bgM߀9^vX9x>Iޑ a=34*E},'tBt÷*\SC11Vdy #ƱGڝvNNMʛkC$Je3LOY_C΂^sss9+_@x*e[8d xn9g::&^Ϋ+X+raPkBj1(JPAp)%F'rҥ$%J& Wv|CńQUdT@z!ʱ YǀUN% p THZodh2E1S,?fww0@YzM[U)(qi?J[21hYpNbDzpPEO_x;"Tk4D(I~Y:uŬ |@\!CC8 @" IR;jmy2OYUce}rF~5肠 Yr;/I IlX Bue0 Z<6oQ Ƶc} t4pC9ȁ )wa 1bȮ^k'.雺ˠ^ `}˛;q /νN>ݎ3pzrz~7^{ԱFX?z TO!‡D[ PdVJ\#+VQP,xEy;9:M鐔"B畲A1ؐ4O8Q#YK$=H\Ņ(Z\CCeTsӞO*r "I(⛮65ucRqh;9/;%@ԑl.M7STJ ڄb.4{$ ' PڛB^Ą6-Մ렔[Gئ栥| [P> ՒFD@_̩dYSbT&x+h 0=Wpz&KM9.m\U[7mTi¤3+&"d/8jTuRT&A7 _;< =f5F &n2Ů+um .THo}.8hB/.R {fF-1ikVnq밚G( Jy;ЀLN@ SqPDaΈ$y5ӖڝPBW[ u16I,c.0" mg8z,Wk}z̗Fc~fDR}quhZv;{L'OTm%\l,A+jbbZ2L*J+aZ0E+B7=%%iBQ 9vÜȕ;uqXnpXK9,nBX 3.XXԧ63Tvuk7oWN,;lo^eA8͖Rngos6Bz5g_yέK7t:gZh^^UkQ/Z5.Z>>Ȣ jͤǝ ]P"VX:aF&UJeDur΂u + AT`uxد>w 4r^!˚`jcPw,lt5u(qTHG74$3WvW;p]ֱd0) < FL~vF{8s(Q 9WUI&LYRK̏#l,6jB¨-ʔԘ_v;aPfAEB$p )Ehfa5+D>0E[  m5ZS'?nwNCY0 V"ǜ0'% `.+*<@ a^>=3ID+Vl4Z29ЙI3x㵌;b#6Su|0؇g)MZVRRRa!a Ea5 T$aw׿H3^)w,bXhFAT3S_i,Ua&BGE^0gސ3c#*We}tAqA /@T+8iJ%Τ:S' ܶ `:˱+Ze֞j||h05EmJ|PVAO !3`@IۍPpumx7sfZY'{"w}HL*Zy16ń־rrBv\Fq,`lL Qa8ov{yd~>-{6uiE-Z^hkCYTVȽӮ$('ѺunQGdzR~Q/[(Be/Ϻ=}i*PQDDWqzhhޒ.Z)2 3AxcZ^u/TTFZ2$ʔ1@XMׇ'\@sϮPOscW+)Br[TukGfsYuplB 䨂 Z0-\=9 :9g07.S9 ٪uc+))sкSr&.JN0ϤA,5s fF w<;bOE2 8FD2O2f\4452`Cjh,زqs\=ٗ %Zg Oqu4Z!#]Yv_e\y4p&Y+&@qCWVwmB>BdW[,H9 ø16vUR[ÍmGuNǏ;ejPNj-iRTa ci07,@*r'ڧ#y")@DB!WYǝF-ȀuoFH$4NsƂtIuE]Xm1[w`pS|doO?> nbdd}^맺-Ȼb95e9_}e"ra/vdguiBalﵴJ% ;7]ɎΝYK:2~b5TqB`}:z|2l仛 fKMVk%~Ia7hK.웷*ؒ5YghT]қR]qא^ȃae=ֆY(4PZdX%mʂxm̸lvε< ö]t,[-n9|׿t?5>ڜ^~jetr I: K0 #(~Z_}.{fff.wWPU @2`2EnE~i5FKũ鹹VPccqGhzLO$O~ַi.(,@HwD ˙eY*Ogi:^N+hj,bY;^GGeW G5P`ņumWBўtC3TZV8ݵg~<ɨ0}⯬^A*\2qlĉsmNK!sk9|^*Wo_ypfw /<7r^&VO)֒VX:Z')3j3?oiM$ 8L\I0-MBXF}Ȁ=(4 > GHYEpu/_9rpnWry"BV7GF?䡍L&ڛzx_1PEQ2:ONzzJuVS~Xw~糟OOMo?s9NK(94J3.x+MYXpYijKM?I 0<4;27p6=?|F8QE?vr7GC^ej,g\*h3WjcfѰ{4t\kqae~@MV5rl7FRYߎ:)c3bCz@*0:&(=CkQ=MfPԞN@Itz탏~g灅fVD1 =g$vp xKX/M] aŰZ7V/ݷs?28e?ws-5,, 5,G`)ǧ#j,zc<{bISBЀKIdW HӬdíncfrHF ͔ƇG'ۙ2ss4J#ѷ7'x뭷=?E/z%߶wMc;H<'Y7i|? äRիj]m\:šR-\ Բ"Rj+ʇ}z4:5<:3>4 eydL /BH\2v]61oiԺٝ3o뵱zU`%&Ai=(yiec\XF,lӗBϾ؄Ճ~WKˠ%GꁞTjq益 &p0:uj8xI)h$d-iD8<\o9c_vC7 P ea% z/ > A%{!SKEhx+I+j=HU=,P_`2NϏ ؼvGgkNxxa1xzʢcz@ɦecdS32ӡϪF2M`,mL0pVxOeD7sCT$ޣR-S]8cC+`[Ab,Mr nHMpN:#qA8g2T@ |O~_us)מ{ǣFLJ1^w}F=;wWkzYyr RF2Z4ZUKA2<^v@LJ^TQǰIcS'ZvVxwEYhlSB)N=` jD?2`%_QY8zigq'-ZFa_,3s{*!$(*8 izylTƓeEmeDZ%G+h Ppk 80o&Ppze<b[Y.+'{q/<_߸(ѝNB->w(I{jM3,Ru@ިJUjtڇF␑UcI% =yw(L{B>o8TP[ oU&5R j4w퀆2WXo5ҰK-a1|$G_"Bku]foҗwK/uwa5૯{>X٣T,1Ρd)y\AL@K|5Zba {I;\nn?NTR :ShEԋe-¼%LJ\*+K y 3&ٱJ~iN;TC`;ejca;=-J2pjãcC5do%*75 ^8U% @Z8 8Es6^W}-?iTrCO~:0ufĝ K>ʒ4tOL/dX\\􄵗HC(qdH{xcrg@%n^[^-kc)0 K\28i[_n~ٍ/dX+iƆ q+<16ӌמQ382f;d CYcM4eI-Q{=EyC Z_Y!gbg$D+x8.6hI}`IR!gI ;:}V? c nGτ~4q時Z1E^)64uV5d*{nCJg&i鸟,D -$4GX˨<"epXzP;XG*H2\p#$.6 F<`O |'5e!^mqמfkeye#J臍5x}l%I'=ژ$̇{Iڍ~Aon,el_a5C_|ۖ->vswϿW,_m7G;݆:{\2ZiXx!eC.EF3ΰb <-N[3j(F`CuLF$\B0 Ewy2+wLjI4]aAaZU`.@e-(.3IٸU@9Dq']D]~o\yqEaU)^68߳i3NyZ? +p:&& THνjfH;F;Ar7"-uf& O~5(( ډA:U}*#BF[@TŃvLX7fHh.ɽF)pjewWނ-TqàJ%E!@fyVX Qk/,% qFB7tA>r;5~Jd"IO-^ѨzÄ SӂA$DpKYHҀi1&@9jX`w,Pjʔ Ēt#ighx3l$4|ҋY['4O5,4#r@SșaqHcqYh1^"_JTeZ\Q-&9::l`팭FrPFE-RPT7Nۙ^V̑4j-ffսAj-yJ}Ovf{ Md tFrˮLbt{³(BP m ֥0lJ*{:[r'J_cίL5VdžZ}]7Ӑ޶y m5¤0C ^K\ =zeGf~nw:2nI7]]N}GQ>ܨajPFOkXm4[͓5^ bry׾B?ꢭy`sջs.ٿ7pw32fvWQ\ĝ/ '4GM)LȂG\~pS$jvx0^ujH<UmcB kpKaEm qB A:e@U8wA%j0jEuSs̘LC~9sY4!UV4b5C)ӄwsM\]0!PeƐ#s8U{z?nZ!:G0 KHN@đDEw1(WӃםek<@ 0Hў?V |4$^/'nC"V:qZ\ /{ix35޽hoi􆗜ۋ,MB{jկ{ϓsô}뤽wzr}_}ԍ8WK }.(zp!"ˉUtƛHbw5R[<p{j0٠V={ ,m0 1%* єȰ:ࢤ½^@ *f E:,wC;}4eyQt9Uz6G+;<ϼ:k8/%ufL,:\4)ԫ E@Y@Z=);Y }:XXx~K:G`V UW5VFz9yr'J4K1ȱj;s`];_B X:CevxVE~ȟڕ0nhE^4Z7ԲYIt{<کSJ"Ŗ6e"ZZ}7jѺ$7L}?{o÷[ZEu{oŞόXc1j)|/k-(FtK Y:h x{8'< u{O%QFk=V0M @iWN\֠Ta CZ `nBT׵*}U+|l4I4Z3#203TMz:!A?wǯ,>_s[^3u3 ,ɾx`B_NP(P=&ed.TeqYdyqO.jnDŽ&s(.gҲWGG ڱpN,RctlwT}=. a<ػ^pllxdxQZ%!Yet.2Nv|¯V~^҈f8[e{w,˵jl;?:8!\ Y:v<#{e<=̊q]`7R:X `?OFCy=!$j玽gJKZML7(@_]+uo{oAe3F!״*T$/{'xŹW>Ϳ(tujk.N;`2bkyn7 y&uUuZFO3J2^eXf?">x.hFEhEĊtD{׽XTV= oFI UAr;B 0`UGՁ*/i%?pO!k_K菰 '`c>6?R| \`\y]'w=wvtglb5#0hGPʤ\uQrZn橢ȫmdžC 0H-Z\do%ijtb1iq*8 b]RX+eA],kT.8i[i-"|?N ևJM0 , Se` ^yP}h]FOkXW㶯͏UZc]|Y?cW_-nU7lHSYvGfS5#Mocut@ VޏrcA'|1Ze %B+*~T@hO=QH!J87uM`f,YlM W=jMh4Ai6Cmu)IW%ȳUaȞ`$C*)է穳 ]FmXGf@+?tBȦ/ݼugbڊAnPkGJH*Gn=tgn߂ܯ=GCR%M5[\.M<;G#CZT ,9hqmp|wvkã W6'%٥ޡ%$7?F %Yβ eC6I}JY +=Ԩj}bk  Q+JqXs}{&=׍B|]iE73oܹνo}Jh;N.B=c潧|1[JZ}~E e YTjif^AJTt'P?s(14y 22i]CjCI-U5au]֩ (X?=[=#wI=w|{[usi<߳pxOwFt֏{ᇂo J  nb匥(VP$L_^i4*uUl`,j$ tM{.u 9lW*mgV@}ró yjB' &:pm,*0j=lЎz#c{{_Lnw쁹Jٕve;!†=y ]KeqX[ؾwvrQ˕ p;6+֭kApwc_ Ubr͝B/pBvF!U=HN,z&]M;Ym vcP%*3"U>]~&r>U^tV-<€ 򝎴3* WIo}h8-~|#d{/]rxhYK퉀Is髜}Y.5aFzʓs_oD&B=Tz`?}Μ8{<Οh-<N4*1MPAn+KVq5j<1Ҁ?Pe'}jxh>|'M/UYbb,(k`U,l_^; *qp"V T2LƤ׵G+Lԅ7$VDDy޽RpVqXCj?7 _}/~~<1NKйǛްsCW!>toGL78G% -%O'ӽɟ@(KK؞ QUN|4ED7WN7lZTn> %'tzQ( pj"GqK^Ь<&S7ߞo'q*s4 ߃#>Ud lV^f#(zbZ=uHv"B~G[rDJg~g<ֆiEZ6gsM[ X /P<mٲ{XtBeg k=q(u%[++ LPA8T2a/)Y;hEf aՎۻg;JJ;K~_ }vT P1m$2PK ;fi|N,.5 p^λXCJotW~sCo˸3Woc{>zM*4 7]{-pQ3- 82OuW( { ˩gH/ZB&uk%[@ƮQ7nU|+P D!|ONpi6%U^A>HzA.dyԨjL'0 (zk'R%dՃu"8Rx0Lkzy Y^! ryyk0%R$m{rdd4Ӻ#n}| dfuՊ=@]=B;U9(?>3z䮻 ZoC֭ C׿G{f3E}}{長}'}=2[$^g5,7g=%+# *`^XsnunϳjҎjnXk>w~LfဵLd+PS禛z2,ZP.:+g`p6 rZNfxoG/ip^x JĢuB\ux^ǚV.DF?~+I$MS{MڰJ% ;7]ɎΝYK:2XU< s»xB=V|eU2a9UJ;IbK)$Z5.ZY{'2XpCsNDi)U0{YnG#"u1aEɩJ"|J *LG:_v0 +5ɹ>E>ʷB.U ƵQ0y=LJ.з@@OE6}{oxG·+%)*!./,#N\edUJ&peچ7nLZd: n?j}x*42 XH9-ާZ1ppOpFtMҡVgK"%T9dA --f<5,|ek;.lVYKBuwu9qt/{e =>Zkk6NBFMNU C Z|1XyIr. :0X W~dn:$i[O.Ż~RTȺM֯]yW-3ؼ2EYybb^ĢJvVV}#^0Nk@RԖA*5p~|fis>h[}B1&7ܸ`~ζ{ )Odˈ$oPa!UB.\$מsp+<Ӑ\Nsm+InrxXX+2NoOG\K~-cMXhSf}L=UmЖr,nl g®P)pH2ϋ0W2+hRTqL@#`~|C F'׍L ja 0F{BL-Ke>ۅK^o3ZCs#^ z=,N%Zڵչy{rx& -!c}} g0K3پef1U54 s>Luۅa;C4ǭ<ˣ* . \Bn9r:g9\{Y4iS.-!ˍ9D1d/2BnR۷fRJߕhf,h`_wuxʰ8Ԁ{ 6 `U*j_)pey=nלѫv|I:nr]=e'Ч0PF%=Y## R-:UW壙Ƣ+aZ+HY@QHƊ~$?pNH74&F؂0<O8Tng4=IR6:l5MM֫[PNG%C J՘kQ:NN7ԫ, M!|7~흑Ģ*Q =#70Zއccnxyõagm2Y 7T@/0Cp Jv{}OjQ@QHQ&`ҋm 6ɢ8PʭeqhiWN$g_x"Yqիc􄷟斓%cR52N4q֤Xa̸z7*U܋(_T iF[ZjYȱ4(-jT=/`X&M+rorv~5QR L *#;?W\{>wyX.Wϻ" Hڻ@U'%XF'f^Įgn]?izMRjelX2ҺNjqlxOb'U6XL)wl_]C>R(C|-|7@TȬ2v$> 7L KNz}NtNOwJOu@^!ʝHع` @>/qX~޳i~W\uY98oaSccGwd2~8?;]PO[F}TS@Иx` h `e:Պ@4WhYT@NtM9'mNL#JT͵peh\vťLjh兵R @ SIa{n۟ݻܮ4j[65וKEP@T~B"Y(YơM~ICٖ07T, ,A i7*4[Znw=L{v*jD+dXa趀[rH((5'g)KUpW)B5hsBW@@!HW^{*MPhY@ ϯ\vxFlU*Sm.Ě-}wۯw`oƗ]q4cUdظoiƿ{nkOx3U%Jo2^ E (CUn̕,rM4Bo\fc+B ˕6$8ţ,N<,Km{Ķm,BQf/9P4º1\\8Wty3ggFcZahA`#~5tv,hiC5GqM"\Z@U;DS>^QEu?26 A%q][QĎLp[U԰iPMÍ^hu LcHc^Bsi΢J 3E1Л:+0UŰ^Ƀ2J>mT)j t~s~ɩEjC1WheοAkge 2Nk_unuˆmF0w\giׁ׻bPgOk>U&Y86(:L 0F<ƄQZNP`NO {BwOaet>-FFY[q ڴºQ݅8@#gU Lz2TvΕm=P ȺY{n%S[֏TG+0@E|gáI%&Ud%Ih'x/DHAڪք%_|ŀkӛlxADj2%i܎cxŏkZ}$;QYT] rIV:#j3 `ꕰ.0t(b'st OeC&k~"yVX Qk/.8~Y1`穸Lcn7aXJNX+;R=(_DIȿ\rֽlk+a)_0mQZ Rf;KcQn;܀@#+X? H<ק|Yhዼ2\2>nV+Erh=l dhDDѐvLMnL7yKw&Fc(sK+4KEݎyзѱƂziO^qiѰ(҅IEI*g(`,=U4ܘ-&`QC C 9p2iOTc1}kz5"Ok sp?3E2:^wMyG}o˳6936M{4_ٿh??/2HZ "4t+XPDfaJrJRTyM-ہe 0aJ@Hg؃>ʫ>},2FPL@a#c4i !hQ +` ֤F)" )OI),3V@5@=d33}Kf!όL!b1h#Mߟ۷{d:<ވ|p4Ad5R4U,?S)cmƕ]w}GQFn䚁<A@Ig4VRٶN<= B7 |}:* +!Kբf1۵a܇C0A̳w݅*׵edL%b {A)PH\y'G KT.,q?65QT0|?;.Q>oYXD9kiڏS:ˤɁΡ'΢J/BjAqyҸ]q 4kxRWքt(W~8Y"8P8 uaB0%$S4L,^ 2(en!*XѶ  ShYed+зs”j~8jc2xXC݋9Fox]{I%B{jկ{ϓs['ӓgn|7Xr}XpYSk_qEE0";H efK 56Yژ4"@-X[h fPXnjݲXByRq'94D0hV`Q5W>lP*9Ir'C_i .i ~PP Ш W̵UjX8U!`oԢu#Injg{K*K8ux0ˆ8T|>\A5%fdJJgM @k2Ltaj8H @KЕvJYrf (RqUK137elx-SK ={ڽ.9r\7ųg_UD]+[g{E:*Uf ]eRe)&P'0,Ca w۫ 88ZJ44EO+6 d/dKm@566,,u N73WtѪ5Cܷ#1( oT[=7o2\Oo?!jl32Y7Vu睽%Krp&-Ϸ$N?qZFe0X@zܐzZ5=)ZFQ`թ7h@Y!i ?o^wm ½uuNrbK@LȮ#\w-Ƞf lP:K RF9~|"0*'Z<;"qk V6T}]*0' joil% R%vѼhtK ST+w؎'@cn9nL 3hsXYaY戍p_FK`$J|Ͱ+i%,shxs(4h99҈Sų7?=_oǛK7_KG3_0~}?YgZ8x ='?w~Y;g+|YxGN(x.b뙧{/ Vޓ?38[`tF^e̾J}\ HR%K,D$^O0o]Ҕl)S ~ˏ§׾=(;}גBp"S(v7.{h X,M_5[^mQKvkHu`.j=gOׯrߦib!r$gK/r.hJ GnܕPR~bVsU Dm=B` 9G8VO ؉~p9m{? ~vnG]AȯwqI$(Hۦ AR#D-e15 n  Vp/@&<@]Z5}r\XWz=DJ`& -Sոkco|fY{t1ydYgɼyګdyBcl i` LDL1=1??3˰DG7Lf`Ed-T˭K<˷ɼWURK.:to=yɬy}My{j[OojW始)6_yw^/OuմV߂}mUR2M]8&.L^x7 h>'I$urN+NA. QK4X<'zg׿>x~ӟɻ (#w,f2@q+OȺ:qj]tP|%kj?aC\tLYZ)k c~Ӵg֩>Av\KSO[f̚YWAWͨ˻,Aj%f%n3Ǘo5G,x^Q2CZpJ55^.t }b zͷŖZ3ߺ4ٜaiJǏ?}g?_/Ãw-]_}?S ^uOOꁵC5ΒO<7\>P;Q TYQԿQy6Jh̄J-SgCk{;-:]?rA\O_7x/̹>w(,˯so=MNl"KG2tMNW~L.oϲnx[s~k3ZhRvTFHDxA;v/3 r} 7kVM5mg3;k]KιQ.0yJ<#0Q 8`1өmvͰ.Me<-JC`O1AU!z^m<]oTCW2sU,cdǓcc,w}:|]x{롸1SdyUu6N"xdIݔ8+>U` \`&L3iVO{ӛso8G־볏~7?{O;Tگ;wC=;r6My%%OVah욬lIcY-`Vz].<( 2>}foj^J)6JG/H8Y1<ټyYj)QBvfiZYxW$n3/v&+իXO'WyƯ9oynl>iCKV-t>޼5V?}U c_͟/\?HO~sOCn_`~|M& >V6?o/뫯WGy$hp.Xe#ST9^*9Rĕa &opX(">Qr6J5F>\Y}Ssy<}rsڿwc1?;v 菞{9?? Z=2Hz.~i9vV91bؗ&:f:ߛ`FlvVs]1;x`%fO% MmN(>m zpS¨\VZ۸8a!kcP¬8Q({kx,t oI=[Xvx~x|z=׫ XSO_?p7>ӌNVO 7OO_GW_$Ϋ~tW0*Q B׸|Q 1 iBCB 9 BFpb*!K MٌeB<(ƵAk+YG%cV5'eզi66679s~8?߱(V1=\zni!mvjRԫ;mWbGÉz J0/ίv@Ns+v;˺v7^¨kq1?-;3) e36v:]Τiɛ +Pp#̖dֹPlYՕ&}'?;o+h;.—{<"uCW irj!-v:R}euf?C ѻoS8u-^<VjeJzx 4}v!z)$\o,8I/|(o4>v뮻,~+o85}ێkBIt%\e}" Zӻf(j}Fooy{{.//==8 fU+뫓Czm]] #< eΌYO!1Uuڌ'+嗷&ſM#:(0x.\W鮎JS_6%ĹǹuV7OZBpr@7&nY:!AnӎYy솴ii 1M9b~x8UۻtoooV)7̾}k֞Vz5֙.Ī9RR;X.-a2sI#8+7ա|\,+!I͈>W.>:/pkmvIxSh}Ry//˲??qxOO?b8;[:wVǣLjkE ;p3,aY[+##ƛ~?]?O0{ J2PH("׃K ֮6L9lp_l^^\hIJZb7 Ӊ'rt|A'YZdy/F^+bT[.֏^?6 ־iu~9yk_F emXeZ0Nz?8aBX#dž%1'KRR4 64QUIqR3jqG~fYN0A i륷_ٽ6)e&FAp_}@W_/.lM^ՋQ:떔Thk%4 8_x\0ţ0lj|m/8&,cJ1O<$r^y A9W E^!6f>yeQ৤'|@*\>uha̚z6m[kkE9RsiiBqkrůze@\#IPwBfZM.b ͸1,,+̖6H}G",* R/U) +ƀL Jے`ChWB=t iNK 4Š-;;+٭W< je57|HYx/k9;?.i;Ua EX'%8"c $f+Du~{s{N*WChdR"F8x`gJ2뀉%F!/DI[K4:u]XN oE hJS5j?χ2H) )=`ؽklޣ_t}ݰz`V7uPM;0_ȿa"o 8-SRdJBV@[!e 6n(~ JtMgRgfwD[*zKlVd羊a]^!X:`~5_FS}H;Jk7{-HL 2Оdi[`ʓ@i5ȹRs)5ęUlmdir>&y)uبd"je \3iOR6^7bXݤVZya22g=7TEV.-<"H<^uRNlg>s sq>‹l ޗ%D:4 }W_7nnp@_}:KVs7#-:hޯJOܶH360PY{9@a<C!*R\f*aV@4ڢUFЗ#ȈS%Վ?_nk|"c//Y'\X&_SH%bo)_SqJqd۫E>2JuKeYV}3(xeq;/l)a+E_l}Sa${HE(r,lY'ɣSLt"C4q~d;u.-Ufc\dY7},id_n_ꁵnZ2 y L-ٮX|L{Ys$]S]082־nX=MXz=ai6ىo74L%ϴXO%i Jԭ4Jm7Bn&F2vS,u)HIBWYHǺȼsL #Ih슰qM[P"el95izb'=ryU߽~#,qV>'fGvjTHM] [;A}ݸz`V~;?u^̡%Zj\f]a4ߧF"ڋ AHԐiT/%JzRΛ.GWՎqRz\f|sQ7KS,f.IEJFS`dsɺ gɹ&ua؍L$POKJ+8GvV7Uoam+67wЕ'hn LkcgU]?ӣ68)+,^R=Cx;nY7ALg?~v'ܴ_qգ`h&3I9<浳Zt^CWDЪN Ij_/z`V*~ݻ}D}u|azȃk}]X7‭M6v/_䵣Uy5LHHʂwj:pRi>5H澣]'N,!vVqܡԷ4w+4/+4u/hKr!bti9>Mk. .הiF/14Gt Ĝd UJYƼYLmRbWM'c~VMhXK< ;nԅP[=4 [|!V"BGhpJQ0餔,iv{R|PVVc|u]Y·|gab (C:!׍־ꫯ^N6(HMD;7G=l ȧP!q=EU|L:W }R1{7?'*ͥlۍ<*v#n}cu@D9'q( [U Hv[h@vLDXC{Ŷ$l޶ӕ^tŸ`B :C4&0 n(LNBW1 xkWa-uh)+F<}WrE@:ya#UHkr^ض4%f8:tձ[>ֱ8lnOżbc8{( ϸo؍5D!)[:-dˑPF7m {l@F*}B9vs=I~ OQTKYJ`H+) DԮ%T<5V<6) |;6vs4jI-D ZVvU¤>+֙I4l2 p^zqtuf8궝nwCYbmwgE6e^*X%ޡsU 4/bk.e[pP%_S8ʙݙԏ='/zcmFqd-_bȔ 'QchXQW_}˨rZC8E04NL NxM Æ#aֵ' H.Hq2H(ֳٜ2 T:`UͬliSxreD\X7wv\8 $fI::-Isn# y h6YNx 0ۄXf+3J֔/by)߶؞f NN=1" ZV?V)Rx] Gx ^z`V?VE__[}[ϛ\9N)M-ͶaкosD=S``J˾ W1G5j30RFQ2i 35?fjԀMR,= `b$|%J:Wcd.J%ৰB|whm^KnK|O' ,Zmw=DkЪZb腁"y0^z`V~c(J?>[VxV{<+m__cprK3pꆌoƬQ@QHSv95EiuC( v@+mhiW cU2pMTb_a]'O+틛DRhOZb_@38!̽_;Mh-fK@ZlF7.p93V zs2;Ugo`eh* as wre,S-^'DAž5=|h*@sxhd5Rj8J穋pî8͑UUq{=e8饑krY(WF,_Oq_ꁵnZ>}jho{t>vwo20ugr£m^>rP::@ZvQ..b)xuV2 ʸM X;z(;iִq6 4¶pQޏp4L[\rO_\SV̄%Zõ'njfh=r*(Fp[ds.-\]X<ћmYS*2'R <R6ڦBOm;nΝIWam,gRW_7z`P ox'>ą3SwqC'N>fg곀C\ *aF+itي̧p;/><:v<%IК=%FJܬdɇ>'7VኑSxOmő$?^5E^S'0#u۱G:7TRΥ'(_9M__ lنFJKGTC̚'8F=ֽoo6EQBֹsWvvkҞ}Ӂk#Ql,\x +[y*^`WJ -AC +[i%\P1PjabCf4P;ϰ-䩋 pAK:at[wOb[eщYfҳ#kz`V=z#'ˇ|j LSTwSo)gҌL8T,+|On%&eܹ ?Xm:vz}(U1 @JsLVz;eO.)4F23n=X۩m4O3]7{RymwrsO^o~{ߵ>B^ñ%7c7};OEw>u)a4Mk/=܃'uw-Y fQ]th,_^j"U-aBrm}E[6&|ưzQ!8(锈5\Huan!H% ҭ:  !Ƒ9ϓ!&wNvQl],&'W1o Q $諯U}us^lKg4IY`ߖ6g"Yk˸.5:Q#ʋV3 "󝇟'̱cw^)0I$ߥyS4U$Yjy"[ ȩ>jm#GV콧[;׏|?]YݔFDW)7קom_Y_?g;61/qAxgl=5䩻v;_?u='E:J%7Rg{za=gۚ*W.d#d&hߓ?ǡ~^Z ZʆNi3ȡ!3=䓫w>|fyE'UMâY^0Kˏ^FP?fJ]Zj&uƕr O|։xqk<:yhmu ߙ ڝAdjȣ5y1ګwfcw|w~]³V%͸7k#+{/8$3+cm,!~nρ5)W+Ra.ȤV >dEiUFyud(D ]k&7tEa j#l TНwi1Ea'}B׋V}}u{7 ns=WmvU6ݼjs]j'E7԰.ڮ\ypWmy/ţzU6=p:gψ<ώpqXdi&kiR6gcJssĂ lҰu1T)Gz_̶9ܹc'OdÒK;JqB]aYP2xBdQ_ک\LxO,;.3ΕwݘiSr:V1!(_d\1Wַ.Ov:-`pѵ?qB*etȄ؞ٛ ;\Lsy m᧚I+-v,ä 5\&V(&H aƪ@V2,:6X%(WC:,$\R, Y@+N9[BL1婸'LV+#B1}zT}u-hz^CMw$}>,{ok\|s!X;/Eůlnb޼a>^IRY.GK[cG=]7#<̨k 2:ALg)>!BKg!,p 3VX32s>e.8]WeA+ XSdB6dL0U`/-d6,]iw'Ʒ_9wᣏr`+.J6'gz=GWw$q]}O4h +@܅G-0bb)ywBzX3}3sW,jXF;C#Z805H]:`Sw4}a,j4`9ڵ;xӆvlû* hZ1 S$Ycd%G.;%Z YHLd ALW諯V}mkjLo3ޔQ]/O}V?WU!'& VK h)cQ\)۶m^3ޫ_Y=}Y] :R.>- }<ᜏ.e40*Ml|6lz%YQ|T""8+I!I)$ρEKRJ,<$q %7>ܺ#m< 4;;8OXmuծMCx\V;V;7};&{CgkR$mH*WQwRձ@Lv_?*N4JJh$~&v3PtVu2B l%!̽T9 ̍btLWp'*q\9DdTtx - (aXm,zl ־nA])2RG(5Wb]ӝlGy3sÿu8sѬN`.ixsO=75i 4zֈ8S͗ ϵ̴O[8Lk)5wȝeJ2[d,㭌 5tFGK^ST3M)[˔H]¤tGSљUxw:cʴ-suSfr 63LĜT)B`ynl 4YfĄ{5*Rl%Tp+Sim=D|pJ}3u88׎doΎ\dAOT 8|%xoog@ח[W-ٿCW7^LZpz7a}A}ڲ8wvKgRz𸨬 '~umgZ{K04l&{lV9I%{TJ)Mnk+Pj$l`Xn80 I 3Rq^H~Rgdk6iCɋgi~^/\ E WP ID7呟&>%2NBN@^aۓSL,4161 53er"0#+ޱ/mHIXhgjPƷATE@+ov|Y۴pHMpof>LLRM0 0$;ZQs^^(k ?8P5%LiY1îJu)勣+LI{+ ![I L#K Η"ǀRT q&Ϝgy.Kr1iaӆYPRU,V-s,bꭦD4Xb Оy0Ό bx/TneMǓqJ-O}'2aX1zX]ybOmøm(ΙPWF놀q.:8irIm]⹖vd-WU270o a/3$R`cFFu,Qz@q_; 'Pţmh0ߖ.䁔ܾzꁵS//:\Hp^ ;yOwáa}WE-7-NY޳;WWWVFcYU_[}7Z[Y.<5NKɌ4JE/|TsEwu2߮äE )\UE0,{JOJ K,q*cmyՎH3ez4= 3x!% Ey!@캬H'@QgqCMTq"! /2ְC7?K3]|joVG'Vn?{i˜܀}"F# ƭwŰ h 8E1Y-\iS(7"(a}SZ`Sa5's^ ־iu0ܼÿ̍_Kn};<48 ;sI*"#e{MW`" <ЌwTǭ2cC<$('^"Ry٠v>k<\ P\Z>n2w}Xñ7."`PK'3WSUc o!7#@;ރFY&h)G(ͻqg0ᣣ;߷{e7{| SJz<$/)PiPd/\sh[LY9QQ;UDј=52Yt8E8n >Xxstˏm) .s& r M#ЏU[86ph h qO|QhXhVa+d¶.)8H^׍־^zuY_:tW__EIB)aN9'%R[B|:i5վfjD4QfQ\$rMCD?JŰg'bWJ :FeϽq>v'뫇:r1l )c 2qF<.(8ٚ&YsPuUOv`ui!U8ynrz^mvQm muzR9st-V6҅HnWkdrxx6ZeP`xkqv %꺩(@q񭉢i*E!|KuVuUrDh-,8-h#a0x o~q xEbG0߮H]^p1H亀4b`\OGz`WCid.]ׇTZZLрWdps3̲Uao iY y7BAr1?Fʵ֋iU hM:BաC$P5LiaLEmV-E22ɒ"RDTZ8qJzS1e۾|wPr;|pcČaRgzM> 0c6E>R+Ɔgl==LP:@%/^+ d156pD A Y!_n:kK#iQ l(9c38 xt6$ZtuHa&Եu'Y|"j]]wGEJMv㙏.rzaR_7XU}*/(L2hoq / `61j]`ckt*Nhoj OAK3Mkˠ&2QER5Z=M',㭋o3jP*Κ{Y46 %Zi+EեcG-E2)ILk"Z6n/lh* \wreA[Vђw0(l+Sxj>8}] ֗ÅmkHJ}P2w@- :@MrF\ئm38NCK3`V,ƙ(k.4>i r845Z;Ch8&Zg38$Y$'= b&Up@xC`"<%)#|*0p- t t~\«@ ؘFRo.}ݨz`V*~ݻ}D/U3ZSgK,3ڶNe8!.\ʼn)\6(7@ uc 1aт:eͪ*U Vbrेj QRSS% F륨( m_f*Ө֚o Nb{y 4v=S sY: `5L1I8PqY͵ۤ2`n0eUz?+(R25dq+ģ 6zk_}W_/Ɣ#Z[[@@$ "k$Ju9 M&u1(pPɅ(lUi2[ƈh8)lRo6jM2ʺ3Wr]@PJdEЀ@V;5~ }Ӹs$ @&2lz Jh˱7l+ȥճa$V;=hRXë=$ /DF?j$|[<EiE}vg9SRF6, 1g"/sVPuJ[qF` %E&&ۊif{.<1Sq.xElG+`SZIxB[TzRS@7OIf0)}uꁵnZ=[}}piVUʡR 3;Oi4&˱#kBEM8[qu7֊ڶtRf$%S`gۺmeLKŤ@©zBɿHeѧuG©=rn7.1TfФ궩G%Z4 \fyRr[($@Œ" t%*/b% bzq<ʃUwk_}ݴ_GWȭ>[VgKÕQO'&JaI& %Q:H5kN B6AF,DlV%@:Lޜ’vIaI bZPAAwN"qr "I@9,˲qvwvRJvTJ~_2 hEBQi( c ?ks͢QDֱAATwyvf3#"nHSv r]TLiܔlwÐ!(8ej'fXSг]z؞s{N ԭBN J-yRWRñbW#fJNW(p2̰=LW@=?|CR䪲/ C"\d)e͞ƔAIy#3= ܐЙw=iI&IB۝P9p&] Im C(cRX&eRCITRFNgSe #NB7\qhR1nJYoyJ)iR+_XNCBMG\Ȳ0Tg< 2U/7~XE`Q@3Re!Xa49Uf   U\J)X6O7Qp`~(tZTT)u*(JVqD mC乎ܩAR4*!|)c%Eb%ҺLaj@0h 9梅Y)}/P<5-nBZ#VzHrv֡h˨U|ϱUTT5:$f c3US wJ0o1Lk愞\KГ>W/US,kCjQC);"+ D]CH-PH1 ҮK/䢢؁6VZW,f:Fg6لr>/$tgޑHzT=ZYa] LNH*M"i 顽蚑I!]jW$&QcBbFÜBit Qj-I5ul>ea{o.r äl(&4Ә"_ T[XÞK)nQg DߑV)&Wj C\uzB(SLY@6MUQ\%섕`,HR\ou0Q8fJdǶ3\8֟, [)TW aiVig/%”oQ-||Bцr\ZWtT]'t:J, R>2 I*%lA?@'յ(v|QG)~U;Y71PqDODRәpuyjSbtS@B Sq9|>&*RJRSbjT A <Q}Y Kx6e5iY {7tTG%JhWr܎T$ ҫaW_Hb[4(N k0US)ݘ^Y KIu d`L)A,,¡UrV1*@~kUu+;XB>ذ n_k0`G{$-n 5X|Z,Ry= F#l MzHşC&@6 dth=s?r,% Cʚnp3tҁ2=0jAPh32Eb+\*,B9N^#<*hkNkd2x9!vͱB9C]'1y^pJ7-9OӸ9lXɹM-ݶ!齾W'`&er²SSdBV72mr&v[({XqzJ?+'5mhBi ETG]!YY8JTFsx. LaU"&~Cr}WT#In*̸8 }ATIJ\~Z)482$ԥaNE azVq!BůRGrRR# Ve PV0N)V'īXr+]¼C}MVUBIiQ6Sh@Ä!agٜ<2i*YB Ih_RAv !G﻾Oᕔf񰚨pTMB}|'42iwô\B@tYB<^0Βj:P`KB9߾c s;s9Ƿs©35;c;nBvV|EFmnM|#vѰz%3)*MyZJBFӳY'@1T"U➛Lqe;jOoi&;cQ5X);CBL&*O 5 MTaq&D*դU^8h+SH29R fŠ2 h􏆑|^š:ǙL/8aJB(9iU`㔊 nԊT+!Xe c Щa.M7.QJM<-*B_ y,RDT$O(kUu4KsƣKr!$uڢJ^;JA>/VeR$dcU]|Wc4UwX7J-54rO%N'Q%څ,4 dFPZL5$ u"mv[b6iG =a$RB%y?ɂlg6JT KqW_r'Y <R ,W* !Ѯ-S(_0U][$ ws|׫Q,2WUQ(ߠQm -fbI7'[ VTUZr2#Fg2c(\*\ɚi)v.iUi@URMd%(׀J%ĎX!VޡJjyl@9=/` Kq:3CS]) -FS)"_甥4Xo47Otb10-&C$jY2#QV|Mg b+#HR"dbLC ԵKBeƚtɚ*> EfHrSgj*pfW4c Ƥ -,.sr;x)GT $Vjs2Cs%$PT$"Hքt,\F(ڔa5gJjQQSY<4ZјjWy7Eҟ⯠]iSeXF B67\5))?)^JF|*?@!84†uF TS-%5Yy*b QaE|*KJI##ckT*SЩƹ0/Sew%B57w\)"G~cX MUuVHٜK >)@4**ˎK`E[8ҋ: @BZ.qE2Qm &囒jTf3k{Bf'u yI9zٞ޸C{ΙlLL&L66 :Nai辪 ΥD>URia*F=#* Z-n,c-580xF\ыzKEQPw0!GeM0D~%D#iؾ+뎓'+is]9ܬM ܓMQ fʧUb-DRfd O=>/kX^5*0Iﺪ+RSJT7J&ԜlJX[3L=i۽!I-s'-܉͖oeIxBZ)KQVհxPw Y| p,ezRB )6d~KSs+LR?}&%Wɮz7̈́a>^20tskGRVJ\YKp2G B)xvgmبP, 3}B@$0E/#<2mJTw:9e2ax, ] ae0Gt XxG-%s + k!<j^TIy]r͐$\<,cܩ)zP*t2y!٪J6hfC>SRN.',z.sߧ*4ْ,9a,߱ZUfB)L]Y$d8KV ֥{@We?۔0RFOJU Ug֔5ik{+tv'TcSJ41om@ijgt4RfaU)K%F 'TW/'$WV[" P]$ !z>S)] K%\sy?iF>WYٺ}G&Pjـ'aP2*bI]a-H9g1YekTiai+Tahj`J=G²hw7U}SQV%+FU= F;4Gқ̧gJ8?0(&RxEMOG r ړ`V2)t%gdXYHS-!=(!˚P?ishu9-=aY2!7IϾa;yO[7nSL)03i.rlmʔim-f8y۶ U2PE14^yIc'M!TV(Ąs%+&4 +6MC0tF48r MlF%'&s5 PwFF_9&n5@)oBC W a|6!NM`<   P qk@0hhVz \sM&08Lm¨a˯ V0`/<WQؗf--ԢwKB+@Px D4?,*>q0PY6UԎեd^j XhdQ1EQ!^9%k~/ruU's}!TùP F##2Я ]0b%k%*B0haBFR0Q Ҭ깮*Z"Kt_{,PH1`4 Q"Xߋ,B[*JZ+9D;UZr7X-Re#nP RaVj@_*3Rh*e-^ԓg>;Y F#Orka/Y %RQ5U1Gz9V0``( Pm}.]lİ+Fq+@u"+|NmLo+ȿ 0r?wU|EwI&- ImA@0h@P;ǝpR&žS&LkL;g\Q|F++ǁ&.<),W&$c^ZYm@0hx灸QA'-1S,WdOMʬFVJ/]v`VksPMxi.+\e)ċnH ?xw?j\9s{YbBr>1y7S_x~{Ɂ@¬Ӳ,)He9ʌhq +Yp!62fܩ<LYJLYސ؛pV|g8vN没,tʊ,a2-!+)S-=qb@ W\|178Up@dCS.\ɧC滛PH$Y cq +b<^vylOЍl&&*T ‘U*9Wx ӴL6wlګ;!U5b6"31{~#g4'5%rX)JŪɖew-:lii+Zt4Ѿ#MSߺ5.:_>5 4uEV$1.KjNV=Oyub$@8D 5.b9W8vBbIda¹v~5~eooޔ<0`CEAPHM;S?(_]*RŊV咖r'n^Ãaq0N3/GOjLRLW@V)H^}^yOoKT oIWDRLDUb._ub5\T_۬x,mmMl!Z0Q U| kS eӠ_#wiK PEvoϿG_^]i@ᣧRsg9XKZ*QK%@EnָMLөq격X+6O{\}68 `SR$˪xmcՓUVldnZ&7$ =m$ɜʴR,Z* PT}IYֶKP_` H@.lCd-֬cϵD#i^h*-%}Gq@DEj2YDrbC+тoЬ u塳Mi{z^[@jUckwHҚ)isJ~3_нOon҅r@4KN|MOB~Z[ULn?e¾7Y:$['7?oolj0 ](SUʷcPT-L8^jǛǘo<"v@ Cz}c+zz:h/}|{x귦5gOܒjRemrai31`Ё`qME=ZXZ@-峊=%*ƒ5]_K}Eh#Aċӣ6:ɡE-l]On隬3V*\0yv&@djˮ^ԓg>;Y19bٞzMbSŴ^{{NӳZZ6W X 2D*#=r.Bxך#f۝;6W XĀ kPP`(bXA&@ 3Y, X s޹m`0~Tq G&߾Ke;3Ͷ'VgPKg%%Ο\$9.KU.2 iљYU jޔu0`_ -guVpq' ~_2ӎ?}[:?=Zg?zIyjEo裆"GR eEPJBnش7o}腇^Z}k]O;|+ۇG'ov:ҁ`znjlߋ}WyOgٗ^|1nKss\8%nk\d7Ww>S"9`PykCb٢;.G*<$ח{{+Ĥ|=$Er ]:ϛF3VL'cZsdj\pKU_(_+*oL,™"6/xoQ}׀r >=!_8lE;fm>Bx!{N" L#d{ݵ>#VTc–Ա̙V=sopE >@2K/8}[gyf x fJ7t1[e97!)+_-ٵ%hpK:gQXޒN0qkg??yS'l{mOQh\Zq“^ʮs9V&} 'miȹz﫼__?z_u|'לs'z` d3sSVkqyWDD;s/y~ncwaOoT'nu7ueN9x䧪ܷV;ᙗ>S5Db;3xEp^x+yVGgڗKs7ǥ$g{/oJ@rt}Cz4sRH<,K;+2\^akz/6( K^]&^Rw}M[2e&շ@y{KzyK^oWIdHR[ ^ X~^x屍o66LM}o[Fչb<^vkקjYT~s,؛Ui=-*!^,;t5Hs~o߶[Sv*jCFq?}\̃+O2>߿ܴ͟2O&]8`4 _:??ttnnnxƇ\ap8`4 :wwnG~f: j-qgF X`hjhi_*]mK=LiMoّR̪K\_ 5ReR.j_r+@ ťUMC! +*αA+@臂~-vVQcW:PTp$f-LGb/hXb(`4 б};}F//`y/B|u6sA{^y+c+-ldwMkYx@Ը[ǎϞzk{6cV'滱,+nX~*~[D־bq,쨣C(Ɂx9wE[ guV,UNst#Ϋ[̗_4~6aR8-)AdW+4/+m&ԲeW^"ϜӚleZY?"^MC/W^}q\-wldB<@=<+M{x?v1m$g:` F#`mnnnjlea[8eBR(c=O?evCg6)Fjq[ms?q?, V|HM7{N 2Wdx[ `u`}g2zŮ,+>/İFsg.%E܆F\>Q͖_-nVP'+ʻTYf'\$S2<`@6}k83Wo]BJ_thP'\kkm/oΞ(|߿w$SL6[ IJ`uz5.i;v-/ =`kMĂ_}Ͱ_}9M`}&䣧 0ҁ`c݆-qY@Z6'qV0?MQ +t$w@ +@ +@ +@f͚+,m63g` ;RZ/V0`nlYۄmΠwï|/n[1ӵ՗C +0[yΕ$YQdYN1,>ꨟ603]k_}?@0@z(d*nCl.FV/ckҗC+;Y܆ &qm`26*}i(LsMpVP<O@6=%ZXW'q@\ҵ|/wQd2MzcxܺX` 0-wmKfea^&oabU}q$İ'b㙾֜s׽u/zۜ8mᔃN^9n#PՏѵkr|(ʒ|b1_vGq bVX+ zCNK5W=}Ձ3>iS̔*솞y[s[N~ڱ?(slmA(Zּg.Z6}I\;ӹ/Ϭ8k֗V:@iaxT!c24qbix{j\,bC@v޹ͽaM_}sz.˦HDیY<}U_}s fpgo=V*n+O^۷8)'զz9jjn{-Z8_O|?aYB 9/]*6Jɲe!aMp " XA=ނw2_y=OœWj"Mg-Ͼ}Qyi&IVqD1Mi׺_i}8a%,X׺m\fZr|䯏sUҒ, ԪЬJ)E4ajH,XqVP[][4󺧯UulgyȱV{˃o;r67t2M\$Xq⣸k x緝ywywk[n;nun߶{zG^%jNM*}iɵP yZ ) Ȏ2?kX`~]VgܖZ?陣'$f%Oܺ[깍ϟG=:c3 ? ZUŌhTYdE::6Dq׺a+;6}/wS)Mx8-ϵuΚ17]>Σ/-vPvP ,`m߾]% )̦BJak9Y. ӓ@@ԴPR͖bO3g0_6IR`*}kՃ=M0]#f=rdEqD<Lq׺n Dg"iŝsNx[6n0eω̜'_tf(u%)J_Zr(ظq9svm7Hun ?W}#7Ǟ׼aH_\,bŜB&:kGM6ĄxE-%hW/xan4 6֙M{Oo3DyC=’M=M̶ wޫG+i.VKҗ\;)vRK>c{챇}=vҥg}q:dU;i<N#0K ^&C. C,t0O"ɻ M,_׭ޅRˊcJw];:U{뻺 *.O4ٲz|~͊"-^Lɮrrpݑ$\,bԃXTUv%˳5'\护8Urp'fB_3ƙ]/yoko\wտ-L#+ޏ>f"Ɛs+.,Z>昢UQFIZ_p{qcbVx F⸪6 %%]k\賯߲'>m?ͲԲY'%'oҨ\|B -V/~`N&a &zG}[ҩ46cUUY.WZ/T?@0tz#E7 tnz }irKOժ=i/n{fC k}"/9둇ÏDd׭ڷI0Ԕt4&Z.9W[//cbz[/o͓+Q;-B[+s VlVbzڵ}Μ9m|ߡζm34'ʷj-7X0+^P[*.V8 )\lm;pk+5鸙y(Ih'qأY8>Ү xOpe$_|onMNK+*I~eW_Z~%Dj0-[l޲yٲeӧMokk\g^{ԃ">uw$;fR}<"K=/=s>01iHI])'WAkj_uێկvNjk`FxƩYxXİ Ty'ΛOj9=WU9],Wb1@zND?z߿8㢴'~6O[4iьF2nM='qϙU^v/^esVz(k+I<"0rܳV]tQj[$E^*Ac<ڵJROa3O757~O c^(YV8C8|&ŏO|2ɶ^soo[7sk0s~6|/N [q-GUtK M 3U>ՀqSGKi!ޡ#snQQoM$ȗ rX ?#FDi3X , #}x:z7j0b`,!BW&/ck/L[ۄveq2xwǟ,.nC1ӵ՗C +09oᢋ!m`<2֊}?@0@`ockV0`#V0`q\&w>p̝+ME(}_D\F6d MF cm˜T;;_uťn$R qh:7 rmM#+I.RZE|Ѽ%IENDB`sardana-1.2.0/doc/source/_static/hard.png0000644000234100017500000344106712174204305021664 0ustar cpascualcpascual00000000000000PNG  IHDR4'TasRGB pHYsaa?itIME.n IDATxD{xxxEEEVVVxxxEEExxx###xxxggg333DDD"""VVV""""""UUUUUUwww444fffUUUDDD\333"""wwwEEEgggA IDATUUU333333̫""""""VVV###EEEEEExxx͙######"""333tNu IDATxxxN1 IDATϫi IDATD{o IDATǙ$ IDAT" IDAT5_yS IDATD{߈333&&&333AAAj'A IDAT 333FFF333RRR OOO IDAT޼333DDDUUU"""ޫ""""""333333333DDDUUU333xxx333UUUDDD333ޫDDDwwwDDDމffffff"""fffwww"""xxxwwwwwwwwwZn IDATgggUUU"""xxx333VVV͈wwwxxx333VVVDDDEEEfffVVV"""DDDEEExxxVVVVVVggg333"""ggg###www"""DDDEEE޻333N IDATEEEwwwgggggg͈333"""VVVD{wwwfffUUUwww333www333DDDgggwww###UUU"""www333ggg"""wwwggg"""wwwDDDEEEwwwwww_ IDATxxxDDDUUUDDDfffwwwwww333333www333333wwwxxx###"""xxx333333""""""VVVwwwfff"""ggg444fffVVVUUUDDDUUU.! IDAT444VVVUUUDDD333UUU333ἼY IDAT333xxxDDDDDDEEEEEExxx333ޚggg333M6 IDAT"""ޚ333DDDwwwDDD"""www333D{DDDDDDxxx޼ffffffVVV""""""ggg͚wwwDDDxxx﫫333xxxwwwމgggDDDDDDfff""""""fff""""""VVVwwwxxxwww###wwwVVV###"""fffDDDM Z IDAT333"""UUU"""xxxwwwwwwUUUwwwމwww"""DDDUUUZZZ"""UUUUUUUUUUUUwwwUUU333333"""DDDggg"""DDD333333333xxxxxx333VVVUUUUUU###gggUUUDDDEEEDDD333ffffff333gggggg333DDD######UUUUUU7b IDATxxxͻ444UUUxxx333xxxͻ"""fffމfff333wwwxxxwwwfff͚www"""333xxxEEE333www IDATVVVVVVEEEggg͙333333ggggggUUUfffgggͪ"""VVVwwwwwwfff444444οݦ IDATUUU444EEEfff333DDDxxx###444ggg"""333gggEEEEEEEEE"""D{DDDݙEEE###xxxxxx444EEE͈ffffffUUUUUU333333\UUUUUUffff IDATffffff\DDDwwwUUUUUUUUUDDD""""""""""""DDD+S IDATIs IDATxxx﫫ggg######EEEEEEEEEVVVޚVVV###VVVwwwUUUffffffDDD444aw IDATffffff"""UUUwwwwwwxxxDDDwww"""ffffffUUUDDDfff﫫DDDwwwDDD333wwwDDDDDD444xxxgggEEEggg"""VVVEEEEEEVVVVVVEEEEEEVVV444EEEEEExxxVVV###444VVVVVV444EEEVVV444444444xxxggg444###xxxVVVxxxxxx###gggxxxVVV###444###xxx444444xxxxxxVVVxxxVVV###444###xxx444D{wwwDDDwwwfff333wwwfff333wwwwww"""UUUUUUfff333333"""DDDwwwDDDwww333fffwww333333UUUwww333333UUUwwwwwwDDD IDATwwwDDDwww"""""""""wwwfff""""""www""""""fff""""""ffffffwww333""""""ffffff""""""wwwDDDwwwDDDwww333UUUUUUfffDDDwwwUUUUUUUUUUUUffffff"""UUU333fffwwwDDDEEEDDDwwwDDDDDD"""xxxDDDffffff"""www333ffffffwwwDDDxxxDDDDDD333"""333xxxDDDwwwDDDwwwwwwwwwDDD333fffDDDwwwDDD"""DDDwwwDDDwwwDDD"""""""""""""""DDDͫDDD"""""""""EEE"""UUUUUU"""+S IDAT"""ͼUUUDDDUUUDDD333"""fffUUUDDD333ffffff"""fff"""wwwDDDwwwffffffwwwwwwwwwwww"""fff333"""wwwfff"""333fffwwwUUUfff333fff333wwwDDDwwwDDDfff333DDD333fff333"""333"""333333DDDfffwwwDDD333wwwDDD"""DDD"""333DDDDDDfffwwwDDDwwwDDD333DDD"""wwwDDD333wwwDDDwwwDDDwww"""fffwwwUUUUUUfff"""www"""ffffffDDDDDDffffffDDDDDDfffUUUwwwfffDDD"""fff333UUUfffwwwUUUwww""""""wwwUUU333wwwDDD"""wwwwwwDDD333UUUUUUUUU333UUUUUUUUUwwwDDDxxxͻA[ IDATxxxͻ3_. IDATD{g IDATVVVxxxVVVVVVﻻxxxfff"""gggDDDgggxxxgggxxxxxxު333xxxމfffwwwxxx333xxx"""gggF IDATwwwDDDDDDwwwDDD"""333wwwUUUfffwwwDDDwwwDDDfffffffffUUUDDDDDDwwwDDDwwwDDDwwwDDD"""333DDDDDDwwwfffwwwDDDwwwDDD333"""wwwfffwww"""""""""333wwwwwwDDDwwwDDD333"""fffwww""""""www"""333wwwDDDwۚi IDATwwwDDDDDDwwwDDD"""333wwwDDDfffwwwDDDwwwDDDffffffwwwUUUfffDDDDDDwwwDDDwwwDDDwwwDDD""""""DDDUUUwwwwwwfffwwwDDDwwwDDD333wwwwwwfffwww"""333""""""wwwwwwDDDwwwDDD""""""UUUwww""""""wwwDDDwwwDDDPc IDATwwwDDDDDDwwwUUUDDDwwwDDDUUUwwwDDDwwwDDDwwwUUUwwwDDDfffUUUDDDwwwDDDwwwDDDwwwUUU""""""DDDfffwwwwwwwwwwwwDDDwwwDDDDDDwwwwwwwwwwww333""""""wwwwwwDDDwwwDDD""""""DDDwww333"""@ IDATwwwDDDwwwDDDD{wwwDDDDDDwwwfffDDDDDDUUUwwwDDDwwwDDDwwwUUUwwwDDDwwwUUU333"""wwwDDDwwwDDDfffUUU333"""333fffwwwwwwwwwwwwDDDwwwDDDDDDwwwwwwwwwDDD""""""fffwwwDDDwwwDDD""""""DDDfff5BV IDAT333DDDwwwDDDwwwDDD"""333fffDDDDDDDDDwwwDDDwwwDDDwwwDDDwwwDDDwwwfff333"""wwwDDDwwwDDDffffff333333"""wwwfffwwwwwwwwwDDDwwwDDDDDDwwwwwwwwwDDD333"""UUUwwwDDDwwwDDD"""333giI IDATDDDfffDDDUUUwwwDDDwwwDDD"""333wwwDDD333"""DDDwwwwwwDDDwwwDDDwwwDDDwww333wwwfff""""""wwwDDDwwwDDDffffffDDD""""""wwwfffwwwwwwwwwDDDwwwDDDDDDwwwwwwfffDDD333UUUwwwDDD+c IDATwwwDDDwww333DDDUUUDDDUUUwwwDDDwwwDDD""""""wwwUUU333"""DDDwwwwwwDDDwwwDDDwwwDDDfffwww"""333wwwwww""""""wwwDDDwwwDDDUUUwwwDDD""""""wwwUUUwwwwwwDDDwwwDDDUUUwwwwwwfffDDDDDDDDDwwwDDDܘ IDATwwwDDDwwwDDDDDDDDD"""DDD333DDD"""333333DDD"""DDDDDDDDDUUUDDDwwwDDDDDD"""DDDDDDwwwwww"""DDDDDD"""DDD333fffwwwDDDD{wwwDDD""""""fffwwwwwwwwwfffUUUwwwwwwwwwwww""""""DDDDDDwwwwwwwwwwwwDDDwwwDDDwwwwwwDDDfffwwwwww""""""wwwwwwwwwwww"""333wwwDDDޚUUUDDD"""xxx"""UUUDDD444gggUUUfff͚"""wwwfffDDDDDDDDDDDDgggxxx޻"""xxx"""UUU﫫DDD"""333fff"""DDDwwwDDDUUUfff"""͉fffDDD"""xxx"""͚"""wwwfff""""""fffVVVwwwwwwDDDUUUwww"""www"""DDDfffDDDfffwwwwwwwwwDDDfffDDDwwwUUUwwwwww"""wwwUUUDDDwww"""DDDfffDDDDDDfffDDDDDDwwwDDD" IDATwwwDDDwwwwwwDDD""""""wwwwwwDDDUUUwww""""""wwwwwwDDDfffwwwDDDggg"""wwwͫ""""""xxxwww333wwwޙ333333333DDD333fff"""ޫ"""333\333DDD333"""gggxxx333wwwͫ"""333ͫwww333333wwwވxxxUUU"""xxxDDD""""""www333ޚUUUDDDEEEDDD"""""""""wwwggg"""UUU"""333xxxވxxxUUU"""xxxDDD""""""wwwwwwDDDDDDwwwUUUUUUDDDUUUfffwwwUUUwwwwwwDDDUUUfff"""333wwwwwwUUU""""""fffDDDfffwwwUUUwwwDDDUUUfffwwwDDDwwwDDDfff݈333"""333wwwwww333wwwfffUUUwwwwwwfffwww333UUUDDD333ffffff333333fffUUUwwwwwwDDD333"""333wwwwww333wwwDDDwwwwwwUUUDDD# IDATwww333"""333ffffff""""""fffUUUwwwwwwDDDwwwDDDwwwDDDwww̻UUUDDD""""""ݻwwwDDDfff̻UUUwwwwwwwwwwwwDDDwwwDDD333"""www̪fffwwwwww"""333"""333wwwwwwwwwDDDwwwDDD333UUU333"""DDD333DDDwww333"""333DDDwww333UUUDDDwwwDDDwwwDDDDDDwwwUUU333DDDUUUwwwDDDwwwDDDfffUUUwwwDDD; IDATfffDDD333wwwDDDwwwDDDwwwDDD333"""DDDfffwwwwwwwwwwwwDDDwwwDDD333ݙfffwwwwwwwwwwwwfff"""333""""""ݙffffffwwwDDDwwwDDDwwwwww""""""DDD݈DDDwwwwwwDDDfffwww333wwwffffffwwwwwwwwwwwwwwwwwwwww333wwwwwwUUUfffDDDwwwDDDwwwDDDDDDUUUwwwfffwwwDDDDDDDDDfffwwwDDDUUUwwwfffwwwDDDDDDDDDUUUwww""""Ъ IDAT333xxxDDDfffgggfffDDDxxxxxxDDDwww333xxx͉www333333xxx"""""""""ޚwww444xxxxxxwwwffffffUUUfffxxx"""wwwDDD\DDDfffxxxUUUxxxxxx"""fffwww333wwwUUUDDDwww"""333UUUfff"""wwwDDD"""wwwDDD333DDDfffEEED{wwwDDDDDDUUU"""wwwwwwUUUDDDUUUDDDUUUwwwwwwwww"""DDDDDD""""""UUUwwwwwwUUUwwwDDDwwwDDD333"""333"""333wwwfff"""""""""DDD333"""DDD"""333www333DDDwwwDDD"""DDD"""DDDDDDwww333"""333"""333wwwwwwDDDwwwDDDxxxDDDfffͫ"""EEEEEEEEEEEEޚxxxxxx޼xxx333###EEEEEE"""xxxwwwxxxޫ"""######333fffDDDxxxޚDDDDDD333EEEEEEEEEEEEDDD"""fffwwwDDD^ IDATwwwUUUwwwwww333"""333""""""DDDDDDwwwfffUUU333"""wwwDDD333333UUUUUUfffwwwUUUUUU333333"""333"""www""""""wwwDDDwwwDDDfffwwwUUUUUUUUUffffffDDDUUUDDDwwwffffffwwwfffwww333www333wwwUUU"""wwwwwwwwwwwwUUUUUUwwwffffffwww333fffwwwwwwDDDwwwDDDDDDwwwUUUfff"""333wwwwwwfff"""www333wwwwwwffffff333DDDDDDwww݈333wwwwww333333wwwfffDDD"""fff"""333UUU"""DDDUUUUUUDDD333"""wwwUUUfffUUUDDD333wwwwww333wwwwwwfffUUUUUUwwwDDDwwwDDD"""333DDDfffDDDUUUwwwDDDwwwDDD"""333wwwDDDDDDDDDwwwwwwDDDvA^ IDATwww"""fff͉DDDUUUUUUxxx333333xxxUUU333gggwwwDDDfffDDD"""wwwwwwwwwDDD"""ȍ"""EEE"""DDDxxxfff"""""">>>%%% NNN_ IDAT﫫333 333///fffDDD 333wwwwwwDDD333"""ުfffDDD"""gggxxxDDD"""$ IDATDDDDDDggg333333DDDUUUfff333xxxVVVD{DDDDDD"""gggDDD""""""wwwxxx : IDAT333wwwDDD""""""UUUwwwDDD333wwwDDDDDD333DDD333UUUwwwDDDwww333DDDwww333""" IDAT333DDDgggfff333EEE""""""""""""͉DDD"""zĄ IDATDDD"""fff"""EEEUUUUUUxxx"""""""""DDD﫫www"""xxxwwwUUUDDDDDD"""DDDwwwDDDUUU"""www6l1 IDATDDDDDDDDD"""333EEE333DDD333fffUUUUUU"""D{333333"""gggfff333333333[C IDAT͚fffDDDfffEEExxxwww333fffUUU"""DDDxxxwwwwww"""DDDDDDDDD333DDD޼`yn IDATwwwwww"""333DDDDDD333DDDDDDxxxDDD"""ggg"""333"""UUUfffDDD""""""~% IDATwww333DDDUUU"""gggxxxUUUfff333͚"""www﫫xxxUUU333wwwfff###"""UUUxxx)_ IDAT333333fffwwwfffDDD333444fff"""333͚"""VVVDDD888xxx"""fff333333"""D{333333"""fffDDDވ333UUU""" pt IDAT333xxx333fff333ޫggg"""333xxxgggwww"""333fff﫫DDDDDD333xxxfff:*= IDATwww͚UUUUUUDDDgggwwwfff333fffޫDDDDDD333333xxxKe IDAT"""DDDUUUDDD333DDD333xxx333333333wwwfff333xxx""""""DDDޫͫ"""PPPϰxxxUUU333""""""fffͼUUU333UUU"""wwwDDDͻ111333ffffffވ333"""DDD6 IDATwwwBBBޫ333333333xxxͻ\gggUUUDDDfff"""333wwwDDD݈333"""wwwDDDwwwDDDwwwwwwUUUwwwDDDwww"""DDD###ggg"""www""""""www̻ggg444DDD"""""""""###HHHϪfff"""333ݙEEEEEEgggEEEDDDDDD̙EEEgggVVVxxx"""fff444ggg333000fffwww###EEEwwwfffxxxxxxEEExxxgggfffwww444""""""DDD###ޙDDDUUUxxxgggD{EEEffffff333"""ggg444333UUUDDD"""""",lt IDATwwwxxxfffDDD333xxxͻEEEfffDDD333fffEEEDDD333DDDggg"""333333fff444ggg"""333DDD"""fff333"""EEE"""DDDxxx333gggfffDDD333fffVVVVVVgggVVVEEE###gggVVVxxxEEExxx###qqqLLLQQQZZZ***EEEfff"""EEE"""ggg333DDD"""fff333gggVVV޻"""wwwfff"""xxxwwwfff~~~EEEUUU444333VVVxxxgggVVVEEE###gggVVVxxxxxxgggxxx444xxxxxx777xxxxxx333$$$333DDD"""iiigggPPPEEE333`A IDAT333ggg333wwwVVVﻻwww"""fffggg"""wwwVVV͉DDDVVVDDDVVV333VVV򉉉333UUUމwwwfffUUUDDDfffxxxxxxfffJJJEEExxxggg333"""www333333DDD333UUU333xxxxxxwww333DDD333;;;!!!333EEE333fffggg333"""wwwxxxUUUUUUUUUgggxxxxxxމfffqqq&&&VVV333xxxMMM͚VVVggg333333EEE""""""ggg333mmmޙ͉333333DDD333fffDDDDDDDDDwwwDDD̻̈wwwDDDwwwDDDwwwDDD333DDDppp%%%333333333333...wwwUUUUUUfffwwwwwwwwwwwwDDD̙wwwJ IDATwwwDDD"""wwwwwwDDD333wwwDDD̻̈wwwffffffVVVEEEEEExxxUUUwww333EEE"""333fffggg333DDD333wwwEEEDDDDDD333UUU\UUUxxxVVViiiUUUfff¸UUU333EEEEEE333333ggg333@@@DDDVVV"""333"""UUUDDDUUUggg͈fff﫫gggfffwwwxxx333VVVxxx""""""VVVވ쉉xxxUUUDDDxxx"""000DDDiii333EEEEEE333fff"""ggg333;;;DDDxxxVVVUUUggg"""UUUUUUfffUUU333DDDwwwfffwwwUUUDDDDDD333wwwDDDwwwDDDDDD333EEEEEE333333ͼggg333DDDbbbgggxxx333VVVxxx"""333wwwfff333wwwDDDxxxUUUDDDxxx"""333wwwDDDDDD8 IDATDDDfffxxx"""fff"""UUU"""333333EEEEEE333ggg333www"""DDDwww###"""wwwDDDUUUDDD333DDDDDDxxxUUU"""UUUgggDDDxxxDDDDDD333EEEggg333"""UUUffffffDDDgggxxx444xxx###xxx"""###VVVUUU͈DDDEEEwwwfffޫ###VVVDDDDDDEEEwww333EEEVVVggg333""""""DDDDDDxxxfffUUUgggDDDxxx444xxxxxx"""333333DDDUUUfff||| LLL[[["""xxxfff"""333EEEEEEOOO333ggg333ggg###DDDUUU͈EEEfff"""888ޫUUUVVV###DDDEEEfff"""wwwxxxDDDUUUffffff444wwwwww333333NNN""""""fff333DDD333EEE///wwwDDDDDDggg333DDDEEE???"""͵KKKDDDh IDATD{""""""333xxxͪxxxMMMJJJ333""""""333<<<333ggg333DDDġ'''DDDDDD޼ffffff333333UUUxxx333fffUUU333ggg"""wwwޚ"""333"""333VVV"""DDD333wwwћ"""xxxމgggDDDDDDVVV"""###"""333xxxfffމxxxfff޼UUU"""333EEE)))UUU"""޼DDD```ͶfffUUUVVVfffxxxwwwUUUwww333333333EEEHHHDDDDDDDDD333"""###""""""UUUEEE###333"""333DDDEEE͙///333fffggg"""sF IDAT333"""DDDEEEEEE͙fffDDD޼fffggg333VVVgggxxxxxxgggxxxggg444xxxxxxgggVVVUUUxxx333DDDggg333DDD333EEE͙fff޼DDD333DDDDDDxxx333UUUgggUUU333DDD͈VVVUUUVVVUUUfff"""DDD333333333333UUUUUU888xxxEEE͙fff"""xxxDDDrrrwww333fff"""444333fff"""ffffffffffffDDDUUU333ffffff333333DDD͈EEE͙fffDDD"""333+++fffwww333UUUfffUUUUUUUUUgggͻgggUUUgggUUUޚ333DDDEEEEEE͙ffffff8z8 IDATDDD444fff"""DDDggg"""DDDᚚ"""fffDDD"""UUUDDDggg"""UUUEEE͙fff333"""fff333wwwEEEDDD"""333ggg333DDDUUUDDD޼"""DDDfff333wwwDDDEEE͙fffDDDfffgggUUU000"""www444"""www444ggg"""333UUUUUU""""""DDDxxxEEExxxEEE"""UUU"""UUUggg͙fffxxxfffgggfffKKKgggDDD333$$$VVVwwwEEEggg\\\\DDD"""DDDwwwXXXDDDfffwwwfffwwwDDD"""ݻwwwDDDfffffffffwwwwwwUUUfffwww)))wwwwww333fffwwwfffxxxUUU333qqqfff444wwwwwwwww444fffUUU"""fffgggfffA IDAT333wwwfff""""""www"""DDDggg333gggܫDDDޙͼxxxfffDDD###fff"""www@@@DDDUUUfffffffffwwwfffwwwDDDwwwDDDffffffwwwDDDwwwDDDfffDDD333HHHDDDwww333DDDDDDffffffwwwDDDDDDwwwDDDffffff333333wwwDDDwwwVVVfffxxx444EEEVVVffffffxxxxxxxxx͙"""EEE{{{fff333"""͚fffVVV"""ggg333333wwwDDDݻ333wwwDDDwwwUUUwwwUUU333UUUwwwwwwDDDUUUwwwwwwwwwfffUUUfffwwwwww"""fffDDDDDDffffffwwwXXX888DDDffffffwwwwwwwwwwwwwww"""DDDwwwDDDffffffwwwDDD"""fffwwwDDDfffk IDATwwwDDDwwwUUUDDD"""fffwwwfffDDDwwwDDDffffff{{{wwwwwwDDD333D{wwwfffwwwDDDUUUwwwwwwDDDUUU""""""DDDDDDwww"""www"""wwwDDDDDDwwwwwwDDD333wwwEEE͉EEEUUUޫDDDfffUUUUUUUUUwwwffffffggg444ުUUU###"""444ުwwwfffwww"""DDDfff""""""UUUfff""""""333xxxIIIEEE444"""UUU"""wwwwwwDDDfff333wwwDDD333DDD333"""pppwwwwww"""wwwwwwwwwwwwDDD}}}wwwwwwDDDDDDDDDB IDATfffwwwwwwDDDwww fffwwwDDDDDDDDDDDDDDDDDDDDDwwwfffDDD333UUUfff"""333fff"""DDDDDD333DDDDDDDDDDDDwwwwwwDDDDDD"""wwwDDDfffwwwUUUwwwDDDwww)))wwwDDD""""""wwwwwwYYY...DDDfffUUUfffmmmDDDwwwwwwDDDDDD"""wwwDDDwwwwwwDDD"""wwwwwwDDDwww"""DDDdddwwwDDD333DDDDDDDDDDDD333wwwDDDUUUDDDwwwUUUfff"""DDDDDDDDDDDDDDD333(((fffwwwDDDwww"""333wwwDDDffffff݈UUU""" wwwwwwwwwDDDDDD"""UUUDDDwwwDDD"""www000"""fff"""333wwwDDDwwẅ333333DDDUUU888 wwwDDDDDDfffwwwfff DDDDDDwwwwww"""wwwDDDUUUfffwww"""DDD---wwwwww"""DDDwwwwwwDDD333ݙwwwfffDDD333DDDDDDwwwwwwhuC IDATwwwDDDfffwwwDDDDDDwwwDDD"""UUUfff333wwwfffwww333wwwDDD333wwwDDD333ޚVVVfffDDDޚVVVfff"""xxxfffEEExxxfff"""ͼVVVwwwxxxDDDUUU333333UUU333xxxޚVVV333xxxfff͚EEEwww"""ggg﫫DDDDDDDDDxxxͻxxxͻxxxwwwxxxͻ"""xxxͻxxx""""""! IDAT""""""UUUVVV"""fffDDDEEE333DDDEEExxx﫫333DDDUUU"""333DDD"""UUUT> IDAT333ޫ333"""333UUUޫͫ"""""""""蛛333姧@@@xxxͻ444xxxͻwwwͫ333333"""EEEUUU333UUU"""D{fff333wwwwwwDDD݈DDDDDDwwwDDDwwwDDD???DDDUUUwwwDDDwww"""fffwwwwwwwwwDDDUUUwwwDDDDDDwwwDDDDDD"""wwwDDDwwwwww###fff݈"""fffwww###xxxggg###PPPfff"""UUU###gggxxx333UUU444xxxxxxEEExxxgggwwwEEE 5d IDATVVVEEEwwwݯ"""333ggggggEEEwwwfff333333ggg###333EEEUUUVVVfffDDD333333xxxͻ###ޙDDD333UUU444333DDD444"""UUU333fff444EEEfffDDD"""fff333333ggggggDDD333DDD333fffEEEggg333VVVEEE###gggVVVxxxEEExxx###oooEEEgggggg333gggxxx333DDD"""fff333VVVgggͪ333fff"""xxxwwwfffccc xxxEEEr IDAT333EEEEEExxxggg###gggVVVxxxEEExxx###???///gggxxxDDD???333DDD"""@@@ҚEEE333xxxEEEEEEwwwOOOfff"""xxxwwwfffVVV|||xxxffffffUUUDDDfff333gggwwwEEE333wwwEEE"""DDDͪ333333DDD"""333333ޚؙ333DDD333fff((("""EEE333333EEE"""ޚfffUUUxxx'''DDDfffxxxxxx qqq&&&"""Ӛ333xxxMMM͚VVVgggxxx@@@xxx"""EEEEEE"""www͉333DDD333333""""""#kT IDATwwwDDD̻̈wwwfffDDDwww333wwwDDDDDDwwwDDD333wwwDDDwwwppp%%%333333333@@@333wwwUUUUUUfffwwwwww""""""ު333333EEEDDD333EEEEEE333gggEEE"""xxxwww""":::xxx wwwͻ333""""""gggfff333UUUVVVEEEEEExxxUUUfff"""EEEEEE"""﫫fff333wwwEEEDDDDDD333fff333͈xxxUUUggg"""UUUUUUfffUUUfffEEEEEE333EEE"""UUUVVV"""333"""UUUDDDDDDxxx333VVVxxx"""@@@EEEwwwDDDxxxUUUDDDxxx"""333www333"""EEEEEE333EEE""""""333xxxiiiUUUwwwUUUfffAq. IDATUUU"""333wwwDDDݙ333fffwww333wwwDDD333wwwDDD333wwwwwwwwwwwwwwwfffwwwwwwXXXwwwfffwwwfffwwwwww"""UUU﫫wwwfff"""DDD}}}>>>"""EEEEEE333333EEE"""fffDDDƒ333DDDwwwDDDUUUD{333DDD333fff@@@DDDUUUDDDfffwww333wwwDDDwwwwwwDDD333www"""www...""""""333www333DDDwwwfffDDDwww"""###VVVUUU͈DDDEEE777"""wwwfffޫ###VVVDDDDDDEEEwww"""EEEDDDxxxEEE""""""DDDDDDxxx"""UUUVVVDDDxxxwwwDDDUUUfffDDD"""wwwDDDwwwwwwDDDDDDDDD333wwwDDD"""wwwDDD333DDDDDDUUUUUUfffUUUUUUwwwwwwDDDfffDDD"""UUUwww4 IDATwwwDDDEEEEEEOOOEEE"""fff"""޼ffffff333333\ZZZ)))===EEEDDD"""333EEE///333fffEEE"""fffMMMxxxމgggDDDDDDVVV"""xxxDDDUUUwwwDDD"""̪NJEEExxx"""EEE333xxxEEEVVVfffxxxxxxwwwUUUwwwfff444wwwwww333333DDD333 ###===%%% xxx)))fffgggxxxFFFDDD888RRRiii333EEE###333"""""""""333xxxͪDDDuuu333gggHHHfffggg5ͫ; IDATDDDDDDuuu333"""gggEEEDDDUUU333fffݫ333މDDDggg///fffgggDDDUUUxxx333DDDggg###"""333xxxfffމxxxfff333333333UUUgggfffxxxxxxfffggg"""333VVVUUUfff"""DDD333333333333DDD͉"""着ͫͻVVVgggffffffggg"""DDD"""ͪxxx333DDD"""wwwffffffffffff"""DDDxxx333EEE333މ333"""gggfffDDDfffggg"""333gggͻEEE"""DDD"""xxxwwwxxxDDD###333333"""333gggfff333333fff"""gggxxxgggfff333o IDATfffgggxxxgggwwwDDDVVVDDDUUUxxx"""ffffff""""""DDDwwwxxxgggfffffffffggg333nnnwww""""""333www444͈DDDfff""""""ggg""""""xxxwwwwwwwww͈DDDgggfffDDDfffgggDDD___xxx"""DDDDDDxxxﻻ嚚"""333UUU333"""fff"""XXXxxx"""333""""""UUUwwwUUUgggffffffgggUUUxxxwwwwww"""333333"""xxx"""333333"""UUU333"""ͼfff444"""fff444"""xxxxxxޫDDD"""gggffffffggg""""""333 444gggfff444"""DDDDDDfffUUUXXXDDDUUUUUUDDD"""DDDwwwDDDwwwfffwwwDDDN c IDAT333DDDwwwDDDfffwwwDDDwwwwwwwww@@@ffffffUUUwwwwww wwwwww"""XXXDDDwwwDDDDDDwwwfffwwwDDDDDDwwwDDDfffwwwDDDDDD333www www DDDDDD333"""www"""ͫDDDEEEUUU333xxxxxxxxxDDDIIIgggfffffffffgggwwwEEEggg"""UUUDDDޫDDD333VVVUUU333xxxxxxDDDޙxxxxxxwwwD{wwwDDDfffDDDwwwfffwwwDDDDDDwwwDDDfffwwwDDDfffwwwDDDfffDDDxxxVVVfffVVV333fffwwwgggxxxDDDfff"""EEEgm IDATEEE޻fff333fff"""VVVVVV333VVVggg͙333fff333fff333gggggg333gggxxxwwwffffffDDDxxxfffffffffxxxEEEͪ333UUUEEEVVVfff333333333fffgggEEE͙DDDfffEEEEEEwwwEEEEEEfff}f IDATDDD"""EEExxx444ުwww###xxxVVV"""333333UUU###EEEVVV"""UUUxxxUUUEEEEEE444UUU"""ggg444VVVEEE͙333333݈EEEggg###ggg"""DDD̙EEE###xxx͉444###wwwfffwwwwww###444xxx###EEEDDDffffffUUU333333ffffffxxxxxx"""UUUDDD"""﫫UUUwwwfff: IDATUUUDDDUUUxxxpppwww޻޼UUUDDDUUU{{{EEE333333xxxDDD蛛""""""xxxͻxxx͈"""xxxͻEEEEEE333EEEEEEEEEޙEEEUUUEEEEEEEEE-) IDATEEE޻fffEEEwwwEEEEEEUUUEEE޻333333EEEfffEEE333333EEEfffEEE޻333333EEEEEE333333EEED{EEE޻333333EEEVVVEEE333333EEEEEEEEE޻333333EEEEEE33333H, IDAT3EEEEEE޻333333EEE333EEE333333EEEEEE޻333333EEEEEE333333EEEEEE޻333333EEExxxEEE333333EEEEEE޻333333EEE333EEE333333EEEKKKOe IDATEEE޻333333EEE333EEE333333ޤEEE޻333333EEEDDDEEE333333EEEEEE޻333333EEE"""EEE333333)))EEEEEE޻333UUUEEEEEE333###EEE޻333fffEEEEEE333333333EEE>> """ """k IDATb IDATD{ IDATF IDAT1 IDATBa IDATwww"""H@444xxxwwwDDDUUU"""333UUU444xxx "o IDATwwwDDD333333333DDDxxxwww͚UUUfffUUUxxx"""DDD"""̪VVVxxxEEExxx###xxxfff444wwwwwwDDD333DDDggg333DDDVVV333"""UUU"""UUUfffJ}IDAT""""""333xxxͪwww444fffUUUDDD\333UUUUUUfffݫDDDxxx""""""wwwEEEgggwww"""DDDDDD333UUUwwwfffwwwfffwww"""333xxx"""wwwUUUwwwDDDUUUggg"""DDDUUUn( bIENDB`sardana-1.2.0/doc/source/_static/kwrite_config.png0000644000234100017500000271200612174204305023571 0ustar cpascualcpascual00000000000000PNG  IHDR:sRGBbKGD pHYs  tIME *ԨtEXtCommentCreated with GIMPW IDATx]vM<4K:2K:3?3-   E71H930"Y1 IDAT+UoQH3~o: ,M:J|U)N}x9jy $Z|A@@?/ 8,'TkY0)C =7)C %_gi?ݎ "/ .41*d%28"  DcRL9  һ8F|Qm -PO /  <u'Uo4jrU۩Cp=tV,wK eE8,@gw7gZ #)Qz<gw  ,Z^gR-" !7Zb@6/!ȭĘC[^l9n+   o|y n IDAT:{d: 1;4    ^; !+FywtDyQh4Z=X%(# Wa e>9 鴢0( j@x"0'YL)ݙ #0[se"<P^fEY&'Gop l޲[a4pW>-%(>-%  | Cw^:t{%4?+  5`^cN-! Ÿ&Mwt;( ӳ7\J)y=a (RYdS0( ׶=y(Rm =y(Rm=ckA7+ڤt1Z]dR.$ʧ Iq6 eTy XTJN  3D 7 !68 #._zY@.ڤ~Y(y=a8Rm1Z]dR.$ʧA<٣ 4a^cN-! Ÿ&Mwt;( ӳ "KVfV2+"̟5`^cN-! Ÿ&Mwt;( ӳ8Rm=ckA7+ڤt5`^cN-! Ÿ!Pdud7#զw (VWhS*}T'RP ţ5MET0:վ&$FN:*$tsz  8U5sa Ȯ 9p~P9LlX+;* -WqYvE  'g[ 9,'<;Q=# I|W-?pPCXU'W\ T@OO $C<&M; ,;D3&LZ@$ U '-i|W-?pP*1 4q~P9LlX+;* -WqYv#c|a 0p~P9LlX+;* -WqYv'<;Q=# M~P9LlX!Kzs: )#(+Th59ȇn  $?= 6)#6)#$+ IDAT#     :dPlJ:GoMd5m1!$0QIEc'S /eYgC,!"/ip3$'1>a+bVrC.$'?i >^:$ZU'_Z   PW%FK,R; GD« p3$'1>ac'S/eVrC.$'?i >^: a.aPlJ:GoMd5&G'+5Bk !  (Ujx"3'!3'!   & ꟞]+"6輬z4-"  )  !1 GG- >,Jihh3T|X ִCKO_(AFj*1W8CA    (GG- & ꟞]+"6輬z4-" )!  ( ꟞]+"6輬z4-"  !1 ꟞]+"64"qS  'Koy~TaU    %E4          В^e]f* իN{|yE5l|zF                       1Ick+%!,bT{DHw       m IDAT DkC* 3F@..irP+,Ni`%1fe=  /_Z3ÇYA-"!"-4BSSu<+'Sіg{-oJ *H)ǽ @&ޤ )QB ÇYA-"!"-4BSSu$.irP+,Ni`%,mvS( $% .irP+,Ni`%)QB .irP+,Ni`%:-\MP YhD8XNO_,_Eg   -#-#]v  㪆@T 5eeׅcśTN[[Yv2'kkO\/vv•LY=yyXK ͈ct>qo齨ey) 澺ec  A= EEZY•LY=yyXKZ:5śTN[[›QJTTkYśTN[[A= EEZYśTN[[4aTa+ѦEf!UU &L[1]]Kj-3-$-$   `JsϊrqhJv wsޢi{ϵՑp[}      {dN_+ߤ ę ɌqՑp[} ([PϊrqhJv ˄khϊrqhJv ɌqϊrqhJv ͥuhߟ}gֹUT  !4F# .$ .$ .$ .$  laߵ IDAT       (;5MMߋBA     ,         Cg.`A                 =`y&      9ozr(ȗ              œFcMuOZ                 Rx]{ lbHvjZ<!   C|[ k (^@ub 69;'mbX IDAT      (    )6-)ߎ) IDATo1y IDAT]vBSb IDATIS% IDAT .-- 2225z֖ IDAT===333  %=] IDAT]v- IDAT zyx XXW###//////////..666sss... IDAT ~~}CBB."aaa jji^^^~@@ TTTddcwwxjjkwwvuuvdcc  \\\000 #'8   i}``_HHH00/00/00/00/11000/11000/GGFDDCbbbCCB00///.333222//.//.>>=__^//.//.//.00/?>==<;//...-EEDBBAZZY332776ffeoI IDAT  baa!!  00/00/00/00/gggkklppqnnnmmnvvuxxw   :::FFF@@@TTS DDD>>>kklEEFfffSSS ssrXXY   ^^`DDE &&&   xxx GGF|o IDAT''' ::;;;;JJKKKK {{{ ///<<< ???cccbbc=== JJJTTT[[Z776eef WYZ:=@ 00/00/00/00/oop///###{{{pponno111++*$$$XXWWWV"""$$$333ppq{{{ppoggh[[[aab__`<<<jjiVVU//0k* IDAT ,--xwv ]v""" "" ===eee%%%221 00/ !" WWWNNN<<;223  ||}SSSNNN***??>llk999zzz# IDAT llk...@@A@@A  |f^ ...د=Hn#/U :::wB IDAT )-   %1N ) IIIz --,M IDATVVV 555RRRT% IDAT2O]v΢  T!q6#3"4/0,5! IDAT 4033B AAAkikEEE Eg IDAT,,,D IDAT3( IDAT'&% MNN++, $$% ]vJJJMNN e IDATvvu$$$vvu$$$rrqTUUsrq$%%@@@EEFsrq$%%@@@onmKKK665 !rrqTUU*+,  >?>???gfe_``nmlZ[[gfe_``nml}|{gff KJKKKKyzzKLLyzzKLLJKKLLLllk===llk^^^445OPP222JKKLLL9 IDATHIIIII'&% HGF HGF '&% )('''&******555111111777111wwxIIJVVWXYYSSTVVVGGH^^_CCDCCDCCDCCDCCDCCDwwxIIJVVWCCDCCD{{|xxyEFFEFFDCC@@? TTUHGFDCC@@?{{{rrrvvvHHGpppuvuddeddeddeIIIddevvvHHGdde IDATFFFHHH())zzy99:~())zzy99:~[\\POO===^]]^]]xyxaab~PON===[\\POO===wwwBBBJJJyyyPPPAAAssr322100OOO VVVnnmPPPAAAssr*+++,,__`__` $$$PQQPQQ $$$AABIIJjjk777jjj111III555jjk777jjj111SSSZZZ666EEE=<=&%&CCDCCDCCDbbcGGHFFGffguuvGGHuuvCCDbbc(((666xwxHHIwwxxwxHHIwwxJJK__`CCDCCDCCDuuvGGHuuvCCDYYZGGHCCDYYZGGHutuPPQxwxHHIwwxCCDYYZGGHCCDCCDiijGGHVUVCCDCCDCCDuuvGGHuuvCCDYYZGGHCBBCCCCCDCCDCCDCCDuuvGGHuuv=<=&%&uuvGGHuuvCCDRRSRRSVUVGGHCCDMMNppqxwxHHIwwxCCDCCDCCDuuvGGHuuvCCDYYZGGHqqqDDEwwwqqqDDE bbckkl kkk\[[???IHH CBBsrrwwvYZZggg?>>ggg?>>CBBbaa???IHH}||}||566ggg?>>}||ZYYabb???IHH}||IIIIHH???IHH???IHHpoo}||BBBggg?>>???IHH}||d IDAT221221221221!!!@@@eee AAB!!!@@@BBB CCCKKK<<< ///777BAA:::<<< ,++988 &%&~}}jkk;;;;;;888???BAA:::]]]<<<]]]<<<EDD[ZZ;;;]]]<<<===EDDBAA:::]]]<<<BAA:::BAA:::^^^ ;;;QRR <<<]]]CBB;;;BAA:::]]]<<<221554554 AAA {zz{||&%&  {{{-,,z{{'''++++++ZZZDDDFGGFGG  FGG  CDD 999 AAA   FGG  AABnnm556MMNiiTTS322ZZZAAA{{| '&&zyyz{{222AAAQRR%$$     yzz111FFF```bcc ]^^ 322ZZZAAA   Q=Q< IDAT]v{{{{{{<<<``_<<<``_EEE111QQQWWWbcc566666322%$$999DCC766mnn766mnn899`aa566666;::766mnn??>---566666RRRPPP566666QQQWWW566666<;;766mnn566666AABwww221221wwwAABqqr998}}~qqr998}}~{{zOONNOOXWW@??}||WXXtssGHH}||hggLMMihhvvvMNNTTTdccjjjHIIcddhhhhhhJKKsrrhhhJKKsrrgffJKKyxx888WXXhggLMMihhccc\]])((hhhJKKsrr888WXXvuu^__888WXXhggLMMihhMMMNMM}||WXX888WXXhggLMMihhNOOXWW@??hggLMMihhQRRbbbhhhJKKsrr888WXXhggLMMihh !!!!""%$$?@@CDD ^.u IDAT222CDECDECDE2 IDAT!"" ^K4*  Pb(" |p IDAT xµƳw;  %%"B2; $%& 7 (N:+< ' IDATx6|44S@   $|7\%9_&]v   ̩Ji 110  IDAT?EG 777 ,M %@/////;;;+ &H ;d( - 0ϥ   ###6662Bhl  4 ѻ IDAT]f_=@@ Rv '4   $44I-CC  =Q k+ 77*ee.RR    .D *,-- %&& [ IDAT""1 1 B  ##"::FF55 ,7-P  Att<>'Tx8H   ׏ 7< J9 N! >,--   bc" ll++ v#<     v' IDAT;      - Ԥ ;20    "#]v  "$| !A,,+,,+,,+,,+,,+,,+,,+,,+,,+놾 IDAT ;M    &$5,,+QQP#@FpHFF,o2{ P6#Xf .$1+**VVV110AA@OONbba,,+,,+VVV110AA@,,+,,+eed110eed,,+OON00///.SSRI,l2` 0 =_0 IDAT 3""||{eeennnbbc||{eeennnFFGQQRsssyyyggh}}|!!!r  B!""EEEMMNjjj666EEEMMNIIIAAADDD 556>>> CK  Bd@@E  qqpkkj**+4 %%%m2z $~>>? =K IDATiihOOPiihOOPxxxjjj %$$[B*dBBBGGG333BBCGGG333<<<<<=OON  !!G3!,,,vvweef778IIH$$$sss pppvvweef??>CCBuuussr555}}}uuu !!!"#$۰%% ** GG *+, %n IDAT$$$@AB@AB """&&&QQ  mm/VV !!#   --66LLDD  ]v8oo輼    tZ IDAT(((( 2B IDAT<;:=<;srr*)(210}}|v IDATONNiihjihLKKiijddcPON)))effeff~~&%$$#"~~/.-*)(GFESRQ{|{ccbpqq;;<~~&%$$#"~~~~&%$$#"~~ZYYGFEGFESRQ~ j IDATwvvrssNMM}|{KKK210PONffeqrrmmnwvvrsswvvrssZ[[888FEDPONffeNNOPPQ^^^445```ZYYNNOPPQNNOPPQ===``` qqp0/.LMMVUT qqp0/.o IDAT]vUUVUUVutt999ooo233HHIUUVUUVuttSSS___FEDrssGHHoppA@@SSS___SSS___FEDrssuuvnnollmqpp^]\uutVUU566fee''(PQPABBKJI889uuvnnollmuuvnnollmuutVUU566\L IDAT !!!#$%$$$ABBABB""!&&%{G IDAT))) ..-Qn` IDAT..-..-221qqp..-..-RRRRRRuutRRRRRRCCCK.i@usq oqq..-yyzCCCuut$$$yyz222wwv444 ..-uuv..-uut$$$yyz222..-'''nnoOOO~~},,,wwv444 uut$$$yyz222..-..-yyzCCCuut$$$yyz222Dd IDAT..-..-wwv444 nnoOOOuutqrrvvu333..-..-..-..-nnoOOOxxx..-..-nnoOOO..-..-vvu333..-uuvuut$$$yyz2229/$H~}QSRuutuutxxxTTU~~}rrs"""{{{ ..-uutxxxTTU~~}}}|lll==>OOOJJK~~}rrs"""{{{uutxxxTTU~~}uutuutxxxTTU~~}..-rrs"""{{{}}|lll==>OOO<<<FFG..-..-}}|lll==>OOO}}|lll==>OOO..-FFGuutxxxTTU~~}]v9/#$Hggg CCC555===EEE{{|AAB{{{CCC 555===EEEhhhJJKMMM~wwxFFFFFF{{|AAB{{{555===EEEggg CCC555===EEE{{|AAB{{{MMM~mmneefxxx@@AMMM~iii556{{{MMM~xxx@@ACCC 555===EEEEEG gil)*+rrqmml***110 rrqmml*** 110rrqmml***rrqmml***110Am IDAT   rrqmml*** VWX:;;wwwllkwwwllkkkjOONwwwllkwwwllkkkjOONkkjOONkkjOONwwwllk/ݯ@AC ;=>IKNQPP==<]]\QPPBABFEF212???NNM==<]]\QPPQPP==<]]\FEF212AAA<;<=<<FEF212BBAFEF212<;<=<<QPP4 Qn/{=n:W1 ζҲѮƒ_kmp *))WY[343uuutst565>>>EFE343uuu>?>mmmxyxKLKrqr565tst565343uuu343uuu>>>EFEtst565xyxKLKonoJKJ.-.sss898uuu IDAT>>>EFExyxKLK666KLKonouuuDED xyxKLK>>>EFEsss898uuu343uuu!! fF7'  % (@@u(O$$#BBCBBC<>>eim  ###./."!! &%%      Ȫxxw@UWZ;?A 1!  QQQS TY]./.ywy IDATB3  $;:        E^(((  0 )Fb$   '[Ί IDAT @@?Uif     Gy   +++ " IDAT   457nru  5    }}}887 !u0 IDAT AAAHIJ "     ilo    rrrGDA Q)Wq IDAT ;  |yv222ddd # nnn! YYYGGG 6^ IDAT uuwvvv   **+  ' bba  0//0//0//0//0//0//0//0//0// UGpXdbYKOV   TSSTSSTSS4 IDAT&Dq YZY " 1/A| usq0//dcc@??0//@??4330//dcc@??0//@??4330//0//0//0//ZYY544DDDRQQedd0//0//ZYY544DDD0//0//ggg544ggg0//RQQ433322VVV ,a  "''&%#    ~}QSR0//0//0//0//0//JJJvuuJJJvuu~~~bcclll`aa~~~bcclllFEEPPPvuuvwwfee IDAT0_!#&!!!42/51,  GHHfff```BBBGHHfff```BBBDDDLLLghh555DDDLLLHII@@@BCC 455<== >/ ! EEG gil)*+    tssnmm***>:6 (! qtv KMN:;;lkk677MNNjkkRQQlkk677MNNjkkRQQ nmm^ IDAT    @ACIJM 135IKN@@@XWW@@@XWW{{{nmmBAA:::{{{;;;OOO<<<RSShggCCClcy!!kmp *))WY[mllKLL000mllKLL000>==GHH>==GHHzzzMNN655MNNmmmvwwFGG zzzMNN>==GHHrqq:;;tss566vww! g9( ,M$##BDEBDE>?@eim  #""NOONOO24 IDAT!!! %%%  )#UWZ !TWZ >??111>??111TY]011zzz000zzz000   HGGHGGHGGHGGtZ IDAT )))    iKiKiKiK  Y> IDATK-[5x JOJ {G k!Ik!k!Ik!Ik!{qB {Hb9Ii`@ IDATk!k!k!k!d:*(II% g<d:-H3 M- 4 H+  yU IDAT    E)=$   H+;# , o%o%o%o%c;M^8U IDATzEoEEEEqmAj%& $##b;a;#"" j>[ IDAT%%% %%  YYY !  121121121121121121121121121121121 ONNRRR H IDATI-!K.121TUT==<XXW[ZZ i@K.i@`_^ xyyfeelBlBllmNNN{{zNNMWWV...kkj221xxwoop221121AAB221uvvonm111yxxKKKwvu||}XYYwvu||}XYYonm111ffe;;:edc'((889ssrHHHjii||{_ IDATbbckkl__`999::;::;www--.SSTzz{onmedcnmlppqzz{}}|nmlppqzz{}}|SSTzz{onmNNOedcsrsnmmHHHTTU{||CCCKKKffg44499:YYY:::KLKccd``_AABiijFGGNOOlmm KKKLMMUVVJKKLMMUVVFGGNOO%&&IJIJKK;;;DEE hiioop655LML CDDa`a\[Z///TTUZ[[yA IDATnonMLM '''('(('( ~YXXXXXYXXXXXZYXEDE111A@A999666666:::@?@FGF987NOO889NOO889FGF987EDDJIH<;:rrqqqpwvvsrq{{{OPO656OPOlll:9:767666999lllMNM,-,===IJI232hgf665###hgf665###EEF.-.~edc aaa]^^ '()1Q IDAT6;>"$(334\]\###DEEDEE'''`__ttuHHI !!  %%$ \]\QPO333  232 FED!!! o(_ IDAT%WXX qrrKe IDAT   IDAT  IDAT ,: IDATegf!""zxxCu>* IDAT  xI7x2 IDATI7 xwxwxxxxxw Ix1W"m IDAT9xJ9xIx8Jljk xxw3UU"NQPI#xN; IDATx9x#J :::NON566wI7 ,,, xwxI7 xl{ IDATxxwxI7Ixxx84x3UU" IDATxxI7022wxI7 *+, }}|=== ![ZY777}~%%%xwxwMLLJIIGGHutt[ZY4XE#4 IDATxxxxyy ! wxxGHG677KKKI#xxx::;99:&%$JIHddc%$#yyx/.-*)(667ONMPON>>=9WWVWWVddc%$#yyxIxx4}|{x???{||VUTNMMgfe_``nmlABB'''&&&ABBub IDATx9xyzzKLLJKKLLL4#x^^^445GHGSST--.KJIllkhhieffJKKLLLDDD554MMM00/QQP00/PPO00/QQP00/PPOIxx4'&%# xCCD::;(((HGFUVVWWX'&% xTTSTTSBBB$$$???BBB$$$???9xCCBBCC#x(('HHH***abadcb]]^ x!Xf IDATWWW ___BBBmmm???BBBmmm???xxopqppqEFFDCC@@?GGH>>=LLL ccdcddDCC@@?x000000ZZZ555DDD000000000rrr777OOO***???000ggg555ggg000RRRggg???***???Ix000000RRRZZZ555DDD000;;;bbbx)()BA@A@?'''())zzy99:~[\\POO===FGGJJJwvv__`^]]TUTLMM[\\POO===HHH~~~bbblllJJJlll;;;<<;???666FFFPPP:::I;;;<<;9???666~~~bbblllHHHx )+,#""EGHEGHwFy IDATKKK000444000000EEE|||tttOOO===888DDDBBB JJJ000 DDDGGGЁ|||tttOOO===888DDD000 444000PPP  $$$ x///ccctttPPP333555111:::  I9333555111::: tttPPP @@@)))lllMMM(((zzz&&&111||| I9(((zzz&&&111||| lllMMMxx۝ IDAT>>>KKJEEE222>>>PPPBBB<<<@@@???;;;<<<I9AA@BBB<<<@@@???EEE222AAAxxnnnZZZ666SSSsst>>>GGGzzzMMM>>>GGGrrr777::: ===:::@@@rrrI:::ttt9mmnKKK,,,::: ===:::@@@zzzMMM@@@lllx )+,#""EGHEGHw000I7  $$$ x ո IDATI98JxxI7I784I98x#4u IDAT9xx#xxJ8JIDATg8&%& !xx0.!4;IENDB`sardana-1.2.0/doc/source/_static/limit.png0000644000234100017500000034307212174204305022056 0ustar cpascualcpascual00000000000000PNG  IHDRwgtsRGB pHYsaa?itIMEn IDATxqޚggg﫫ggg444xxxxxxEEExxxޚxxxxxxVVV͚wwwDDDDDDDDDwwẅ333͉www333333wwwggg"""͚xxx444gggxxxEEEEEExxxxxxggggggxxxxxxxxxxxxxxxxxxxxxVVVgggxxxEEExxx###VVVVVVEEEgggxxxxxxVVV###xxxVVVމ###﫫DDDwwwwww""""""UUUDDDfffDDDUUUwww"""fff"""> IDAT"""xxxfffxxxwww333EEEDDD޼fff444"""ffffff"""fffDDD"""fffEEEUUU"""333"""333www333fff"""DDD333gggEEEDDD333"""fff޼fffgggޚwww"""333fff"""UUUggg444fff333VVV"""""""""UUUfffUUUEEEDDD"""EEEDDDggg\DDD"""DDDfff"""UUUDDDUUUUUU\DDDxxx333333"""333333DDDDDDfffwwwfffUUUwwwwww݈fff333DDDffffffUUUDDD333UUUUUUwwwfffffffffwwwwwwfffwww"""BJs IDAT4z IDATEEEqt IDAT﫫ggg﫫gggxxxxxxgggEEExxx͚xxxEEExxxgggVVV͚DDD̈̈www333DDD333ggg333wwwggg333www IDATDDDfffgggwww﫫fff333333xxxޫޫwwwxxxDDD\333ffffff﫫333DDDwww͚"""wwwfff333xxx"""xxx333xxxfffDDDxxx"""͈ͫfffDDD"""wwwwwwwwwDDDfffDDDDDDfffDDDfffwww̪wwwfff"""UUUwww"""wwwDDDUUU333"""wwwUUUUUUwww"""DDDfffwwwUUUfffwwwwwwwwwwww333""""""wwwwww"""DDDfffwww333"""333"""DDDfff333wwwVVVDDDUUUDDDEEE###333UUU""""""""""""""""""333xxxUUUxxxUUUDDDEEEwwwDDD"""DDDfff""""""DDDfff"""333"""333މ"""fffgggxxx"""fffwww޼fff333DDDxxxxxxxxx\MMM++++++瀀͒"""MMMţ <<?Jk{}s3}};CPE H?V5 DPU* djQ S59@QQ(b4 * `E_J|-1H| oDADcDk@PH?> Q|s=h 8!~ǻ}@=>' Bp={|{\>Ǽ'Cpq>>*'ěu? ! (BwKuK! ǂ(A*EIQT5  FkF j4&F$FJ}D%h0*h;Ԇy"h}@Ix'!7:Cp4 1T)`%no^9!~?8K|^ApgV J@`GJ 4D㥠#B  :hr3@B4 R_Ayi{ !yx6xQH$ *h1S8A  Gc_Ѓ#{'$I7Fz L<҄AbnRN ##n FLs `vO<$GlFDh(pɑH M-NI?S2q1~b*LrZyڧ >rtT$\HJ_ ɛ =}@tJ%F'FS%b)uRd( F4YLߞƧ^1 "@puDARkL5D|t*<{SB"*M41/@=OiH *{{O_^xy67,_^*Dnk|̺M45PUcԐ5i*~ o4G 1 2k1"hB4o|<V]2,RG!ŦD0EjxD,{16yz(NKaI$FXC@A=F$["3) FsJ4~C,ysxm Rs:}|,ٛ׌#w.?ǝw /<>mqvsyG_ BheqC 2 xskzU4`UQ +DP& 1 j k\fS)KXH́N1 DIhр11M9AJ&TM)zрQ;/"CuW8_sTFf%ֽ\wPd,RdWm>/2GB_>$0xp1{*QT<(o R]E1}3FsxO@]4F$Ab"s  l` "k(jb P#gbL4@5`4EE1&F3QMC8c'mB#ȝI )j%#u)1E$>5Q<7(E jFT)P'<>s1Z!VQkPSA$Bz}kU UHSnnb3tXSpX<{ ),PՀ Vj⅔QahI%U!YQ2+V0&: HjIDgcՏ0FZ%6z)XyP+KT}LbˤN5څXM4`L@1`Bc5,-jpNLBTl34ăJx4ՏbdQq1'u O m13Q>eZyᐼբ(f̦bLÍ hC>PLBp,xb')d[b< k k@)iZu`Z3T4Scm"[p6ewA4zŪԩ|%~ 默lo1;|5,'Oz;/9i|4w0ׅzژ '<@@S[`废jQSIJp%Dt/5t#ػFt)+vwL'%ռdm}[UЇh9*rxk%#>^vJjDl WS1Kcb΅XyMvM YyB|%&C !ER/5,j 2Mf 9~t~bxbXĆiLLjcί5 C^S(=5mz-ր*mZ <㵷+8[^Ϝ T%k/=C"T1,j6Mվdl} V#;$ xjgc12VHQnP#Xר&d6,!@Et- )Ix"feSU%j_$"kX4N>Fv_[v["̦]2l,&T1x7ju}Ӛj5ľI x I?L{@U8=~ct Z B=:x,:Zyp.ws)l16siT9_C^@&4HVAX++J.  HݛKmchSiFV֪ﻤƺb2hjGhY0i 60oRbHVFLe@3M3/ :eyK{l^ɍzV&A o6ȭqMmF:O,l񸠩o.㙳O7fꐪtl^Upߦebb\w3_#5=FňË}Sg"n K/GB;Kw4@L#kl:ĕtm^uk^(IXFN< 5-(HLVT4,A"NcMwl_b:0MgZsl|ƻ` jBuc&Hb4fo"謩y'G>O=|8a[`:)Upj|Ww.”MjQ\S;!1c]|j MKx $FyGq\CQ1{\`&o3c:RfdbƗ? wo|~CcizjS[m$ҫD֊*_%Am=$`1xFHL*z }oR>yfMkVl9MrYI,UTmX+{'}ggr gc[]z>ۛ,k`BÓ4q Rԅp`>FU<3vvQ)Yg k;U5~?Zb$Gb4Z5#>WO EY1X/13$T;CȬa<n`%"!pqs?WsӤQ'be ;(HfF +UNbڪ)8E=3ՈTބǮ9u}dL&^ڰ%5%oBz1ǎ~KYxZ_(~ cuu hdQ,*5HcR7Bc>/lUs͛S|#w2rOpߍ(KD*/LNes>qGg?r8c^N c*!f=/q"8Gnd2ds8{_şN[[ZEM: ({ZsOqy≧y`D*1 .]O# -Rf\7RsҠ^P04^Jf}n: ĬN0rW̲~Ʉጽ'.7a,x$Fo-`&ܥoi=`&Շ[lLZ.?ϝCzo_YZmzNw =~~j{#;4 V?˧?i}, NMGeAWtLjҠv\/g}ބ da󋑈z^ILC3CTņ}rVxcp>rRhkV=N #dhRE8Ă_LCZ9wlo]kmslBj''ԗm&n;huA$m"f\ާ:_//ؼ|U2 KmG~WPņb!Ν&Ux=_nv#?"X`kcqg^x_ӏ᫂Lf#1hw\D\E^Š0sCM'PEWU%^UY5XQ8aW{O}Oxcƛj/,*[Ŕb:e4*H#.P%~o&5^Kb=D'.ꙮLw rMH9 _t%MYD#%5Qa EJ)F _xq?T3.]|VGfY_[a4m2qU{my *+.F !q|+'ij>Ε-f}rq90y7[D6\ 3>pe~eKWs҅ Lf>s:ڀKWUsL-*,cp[&xhyOXjP% *wy,I!W ,OX[]g&Aa>sC񍇿Ɵ/xIc:\|Ci[\pq>p8lmRX{-^va,ćSyT Kˇńm࡬ܥ-Ξ{?;[LFCBYp6gsVr.v6P'tmVVB|6h[6d X4*9Mw7o~w4 v6go4b2x 'zuGNLHSIJ byAV=O݅^Ik&C"&Ε$f=g$6$VȁiX]D+Os?G*WhXjQ _Ĩ?2P̧Z-nƳO=uןS:ϳg߭韸na>7wc<*ۺl6Pb2e;»~y-UUDzE5焊Wm\xi9!TJ_(0L_،vW. 2M(%#0 ѕ6WO2ۆѤFYF˶p嬖CluRHOY̱YFUαF&;CͿu~Kz'prAn-F7#7cc;ΣjNB)9Yb. !qr-HuiBe'qiQ= "8<߲w566sO {Bc2B, k:dFNbXd\N ń xomۻo?/M c 5n9nQm}=OcL[( 5K\UdZ09ca{g&kaP%y&z=r|YE39UKQ_x 5B*25;ս}.]O~/So[fRzf}N^%4wOqM(p>~PK٘]0f 1GF%QJL|LJ(D潸k*RPXPKo4!91WԴk' |UBcs k[6ǪE* Ѷ9ct2fvS'\;\zv΄tphK1]E+ [w8qÍC?K "N \6cNw=/XqxcES-!yږ8+lo^_yІj$5IcWӑ4QIPbc7\ST"in4 cK_"/ .8r ; k-@PUlkWJeKlɲ(|>ayi%y}AJ$1@e0Y 8rx;~q/)؇Xbpm,_#eFP,vw#xV bM mch^g8pt;m.\|v3*˨K=jDW IDAT(9\ Wq*,|hOOOqe/+J nr|riQV=ƭ} z6^^, `kNǡS]?gpU=UoDk^ 'IV7'8aE\(p?QQfph#}9j-;(-6,t]: o t eLod τC}r>NyQ"d'8szf9NU^qlo_կ_?y{>h{1 7hdODq4<)*j_ g8ŵGk$}ἃZ2idh?Ǽ"t#Qr әg:ffF_;T)9,|4KlllpPvNG]?̨n \O<\X[:K‰XW\㭼?LQJ5<+$A46^X,Mw%O܈,EVd*NMw& fpiJ<ŬX-@#G7V8etd8dq 3XYʩJGl:Wy5ܳYr4n[N7GטLK;9qt[8xcS"E&is$.r GF&$Un7] l%[|PΦ Ġ ج$OXa ]4SfnS]cG8ubɬ`6V;hN;(,s Nny3׽5;=<*JjkSKX(ZŒ)OPvv8@BUpns~Ocs^[l]"rsxxGi :ck.nGG}EkiJ'ܑ)y137_xeټ{O_=K3Nq"Sj-Ek[ iH<5jH!)DPs4CְIhT/0mwBnPpmdd<&3$B.YJ6bUgX0Oa6S|W]UCu(tH@8" l@ ۂ,uHm^vxշcdyr>>Nޏb^ ivY^;dV鯭Qxd4W9fg4#Z0Yij޸=9eQ0ieVrЀc'9~ꕜ{>VW)vF|>F6fS0mq=M2(|\iE BU}`Ki)WP썇ǾIn YYRU ۻ z?t^FN cY[]Av 7(_x3鐛)1M$?wWaU,*0iwrzmtox>J`LƞVnxcn=?Fi|E:>raxݷRo`rrʛo6sWf`vEѾnjVI"aeQ+fZk .|Js8Wʳ!cVNQMc\Xj8!o\v 3}<ۛp߾BʻN^A+,_B>ѩmFB#p vIM:U$X<>qf$^ VLF{ '3rS-fPzBU2/WnK[e:r7›湧*q.p'1l팸էq(畛ZNY!~gKW3[cWE]TH$iF+Q W55D'1YHrrNFs?d*dXSҕm+.+9X[9q:|)N3-k!=?uZI%,z4/-J%ʲ$xǥC=(4#k,EIcR/ Z1z-K]&5IDj xg|-B0eI3Ķ0g`2Μ"C-+*ϋ)o[{#ٯ3O;…˜:Jn[X=|3/{UTXJRf؍o`Eguc#FӂO|^~wR95K_ V8Xg/f%N`Z\]SjiV8i: |K 7--u-8hFQ{;JkkG3@F9Ñ#pGb$,5P0Mn u&R͓!41Zth@mh^\VI:9Χ՞+ZKM:|˛xEŠצ-pEUl 73 K|?-no~GjKSkcoxg䡯#'^3[bsg>-m&h]^zM,S+/M54,|| UlVasZx8dd]:لt:8^ _~/i{Y⨗<imh,йkHjM(V #j"s-[^JNKeȗP1.!xrk鄀 .(v6րfyyyPmoru{㎟'dQ eQ٤sY=t+.++} X/?+Nsپga Y|^2-+6ke&I\yza!{`GmM PdQ,j}04RIpi}ɒ63؜W]9*gl⼉vCTͳ((]E&NhZwE`m-T Q'^z+[BcбC, /ntN1g-67/e\խˌwkֿ2_ͲfC5hH/Bb=|ND) ' t:k1L^Lyk@{ۧ*Rz 9NTspn/g>irkcLBMXaAɁ(IJӥp1נBwF:(aRek8{6-7pNh[8جE1ȧ ҁXl1ѮRq0¸7mÁԶan.nOK6۟o|'>ˬs?oB<^)Hhf 9tXRƪdYe677N\4̘[|V7y ]Z>GZ-E2:;qW|A]v(JihťcITPA3NV[7\А2@(@LR,KI?.+KJ?טFQǼ e*=B(sj/=.UU[hq%-^D&Hk^AI ^ tXY^oqq*yj$x7c8brYd5{mR>+7B(a1 G`Գ<谳Gւ3_f2"H`}u&DiU8J&k*2o>k=Tň,7[Y, vڬ$ϕ.%Q?SzѴ&,DZ:2oҹUz yh~Dl2  _b:jUhىl/0ߧ,iLIXJk*_o팵iz4v%n @Ńm2Zc -eVVV >]FS~K9,e E T3&)_{Üyś^CI8Ji&aKS' Tb$9PiFÁ.Hh湼.Xz߮b԰rܳL6\vU1`=2J禍>w5ƃ?YVOXXP> тˑ6g6O0O1i8ʙ\b/]kϰ?d;|'}( u9Ј^502M`4g2ɱ&)di3Y9a}}$iH9Cmy!y`Lg@< 9Jci#Xo+Cв>"5*$~]ڔ'aˋ HS[W.2L3&*JwZY` j8[d*<I|Ӳ׾٦wSo>m*LZܾyI?,ּJW9]%y,uX9r [=Ƴ6`{5 pzGJ^ KjY`b3a:nWh+g zz>Cl紖VMhXicj6pNUyw0"P45`)V>5q[HQ7K?Iɏ!-$aQ, L3¬`: GU:Wx_PsVaB22ENJTq5c ϾpϾiZ6z%iP1pR S֖MmX[_cgiu[l]X\J;2mOu9EՈT/%@"uy"SBA.^K,Y__v5oo*fuZyyYEjO+Ct ՜U\M2.m >IC$)LJa63S(qs EY*!Th:]\2!2G\dUwQ(t<#g:$-fYfڴxG)clR_5hHM0M(z킕~FUNL!n~w`e:ƞoq9BGUOuq]enPUT!RP@5RyG .шr^v(BBд^@@tA7vWoq",/"Յ@i6ԛN u$oncvT*Kj%!@9sT1XZ[›یܘY5l橳/gwcǺHNv%a?c6!59jiuX]YguZ*rn 7ygR< /μVj=0,[h0f dec0[WZxq */_aC\C`d' Tj&û(;R+2ԣ,0.6'@HR|K F-KĔ>jqЂ@ Oޛ=Kz}gy>}9`eqHq$ʒ•۩JRe.\JRIFTJJe[*(Q)\@AA,0f̙}No,x3 3sy~EƆ۪k !u1~6M2B 6ZJwzt2|[6}.$G#r R,K jklL:ln8I)ݜ$#0α=8Bvc$iݳE8UMS6m(:GnX~q]FmͲ5; ,;bz.(Q+&%X0]ӎyj +rb!pu vM$J$#VwT3 o?غwLm)I}XatLi2(\Ci薴M$fRT>iJ h)9ԣ( A-(qq4xkAY!&?$96kv'~65SD[ik o5sL)0 Ycj4:=`om|Jyxh4Szl[wiYGa2hU\G,.wwYL'Gcs$JDlmϗ3:GѲ'ke;2 wޞw IDAT~mɠ\^Z##\$l\"Q(i -P h]Ζ$Z]Nd7RL-otȓ$g٩>)gF 9{{95ר_is6P6 QvJ8>cI7+=};vZ)A6bv'? 9Fpcg6;HIz݌S'7xEt1^8CJzDi3 D$./4 Gv_iO8tm}T!g~nn1<*vO~mP)^̲ϖE~Zڐ<pk i>L X4&W·Xӑh{B wa"a :"wo_A 0v.Gt5U8{yw8ur rCFE5u(k`f:0Եa}OuUx.a-A s[7.L6,sq$I /۔$ʣ&@p-"]C$$iHcA'N/x,pW_E BUm4l`'S@gfBN%h"2( -Xo^nr?'~ڛHi$Ѥԣ M$?Z V,oxy3gAXpS5*" lR Fu" 8`W'}a,];ZxkW?铼oTL#=eVOjfyKc*T Ι0]44N]KyTmTFTHU'a)zd2boTRSF)ACy40S7:,m\ُ]( -,?fue`9uNB/Oy1Myta x(2ѷO~ f 88إ)+&uCe Δ> @ "lyS%eȒ=˙ O\Kod@v J#ti g? lũYꩪs3zljH x .ˋ9QQȒ qG.?y>ļxs.J[xTPq67ot፫}Whv(BBGΞZmbu–s1Qa%JcE4Bq !ѻQ?%Jmx1O^bR[WOdyx^>*u3lxhȳٹ#MbH֫wuӣUP[1L30 WNj [*hDB㫂$$-Y%*XpKh>a+$'I&ӆnX]\KIhJWch8oUlˌn%kaei.gtݽ}zix޵"Ι Ӧrε\q-ֺh%r^'Gaf:Py6U]rXAo D΅yPdQpQ,qU EUAIJ%2vȳq2׾|/鷾drp2z^]d wT"Zkv0MMQAzyL9* Bx$3o_m4?=vG13rV8}$'p]~ҷQ"k1ԍEXpO_}/|4uE3tNkNp22I54ް?V1޵%x(C?zckhPBQ GSDڱqw38o)iOtjBC F-ƣݣ]J6<}:r}O3[L*%uGS1!SReȣpGDJgNxӤỶ[_A [6 L9n'a PCXk;8j1 k><"M#t}Gis1ؽiyGH?~ eU39bwݭHJCUWL)0p)Jr!`0KR\E$DIx|9ORF ADCq-` Nˠ˺)y\|Q#˅oKvJZ"G`.xQXw*&gxl=>6n<ɲ ktxO,t5Yb,Mȩ:|l<;?dgN.rzRʥ<o6 s.uc~OQl i  yx2 :G']>ۖuh[A[oqޠd<[1Дt_$eHkW*PVJK_z!b"VHQG*G5٥,F80ؙZ,X=v|O]dJqu;wX\?MQx#JHcC7,6*3F'˹s'3G#"%.^*ּ-${HεRV:j,z4 njhjK$4e`#-sC:x$Y##<_[5G1Ś()'0,-.Ik2lAk3S_DeigZՌ&N<Ȼ4wQm4u0b%`#Mb=O < A8Do6o]2>iʲdt8d4R$kJbJYj }Ak:MWH{i,UcjCaah'I4tXAHTJՔa#QFII*#8,!YDm0CrkW EQ1M-wY۠"N𖍍%p(αMS2`;w%˗g<-))?Yw8p15 9ВN S Nx&Eu`@-hmɳŸi &Cs|;HSf yg9}zn'F֢.+4`lXILXui I (VZ9Ak*AZk Pc+.U[RUY-N1qXV!r A݄mtT$R~|o NZ>|)?ݻ C=1ff23{CmƦ*q~>h$5D4m}QKyfzND)VWx8UiH".ng4U5p>S^x']5xFE1j0gX,-uX;Ag?w.oPZԋggȸ.i|ܼYCs8ۍ믁u(-n+뼹pÙ !=gϞbmσwQ B'(fFF(4H1AJM$Sjo)P46ӓt̙9w4KP!dBoݭAChf"!8Ni(,.#b3) >VR}IJdyý0>:x .}7[k ݶ# HcK&% ܝ[N )A:T\}jIL݄#3<"vN^""4C8E-8£ [ E/03' K8 \d Kaqx0 p ocj M1Imwr((y >tPO=qhHGx#eI]VS/%^8:v ֏8Z5KW8 Z^1<ܦ*T$Yj?y݁f0/wܾ] Ζک\(gew4i X&$ǯ[LVNZ]`9LGw&ǎM{Iw?bUrTԨ:JV]na|ZhdMRdX-QL46Teͤ,./C~g/=Q]LIw;]foKid`QjeGQSHAGgGgKg^Hfy؛ٳlzIx/rQ`f2bIt Qn̓}LefV6HiqET,W}oepp^x2Vu45;)L~ɉHcYdgw+wޭ >T(" YiQ';a0c;cSkrȅ){pL+4.řxg=։uN lD,.o+LͰd(QҘ|3KOL9bM{$IwWVH=tJ)vv;Ã=,-(fcϠt8¡UB,StQ"| GC_yLd1IӉ%qLZF qnd:yBE&'/؄>wH?PR:CqQV!-h]iMSXQ5yg&NtiSx-g-!Xߋ {S!'7yﭿ)k kcEUy$ Ӯf}Xt(IM6.$Yo8OI/=x#i`R:Fx,C ++^/Ŋ%4B!}sE:go|u0ܹ>n~`>1ǞG.=i|;O3$$SCR;3u]Ei*lSvh%ZlmIyݸru.`1ؾ!λyYH Σu :l>m >Zi$')."|[c]59 d Iy3ؾ4QpP8vtTes6!r IDATN6YN` E>iP5ýpm,H4x`4 QF N=N4Rkq^bje#Mj{<ˈtNyK2())@%Q`{O@ IUL3yN1[nJ˸u̸J4+,IY>lgYXK[M=Y*)wNcNm!B13\@12HK:dSyMC9v*84Hqn-'OڃC/t.Eӌ)h/hH=Ixh¹ WRLS$k_VfG 9֑ɕw@U]9q'xir -4S| (]ă=L.Hrq?n9 3>Y\ I&xGyfqEjPHOQQ5V1''x2_=I]'y~cmLfPWD:_'D:{g0pu5p.}w.B,ќ:ps|ȧܧjSMECkRe]L_qǹ|[>iO^F8?̸HI\۟;o|tk?J:t1 8Tt$LxV, ˧=kczDv[:"QWW0˟W/54R!zoߺ0Zև{FӚ/Wٮ&"L;roʋHIbϤ 8^"E5eZԀ pzu\O捅y.L _9|Y<{(Y]] *(o_]c;gXpb2)zO> USHJ,T*qHȒcy򭆷:ȖB;ӿ$EB.tΓł*^ڠKc"Y{"E(ʆ=XOv!cz#yq5o螼_GEpD;=}L% kr1yR!1FpxܼH] ~4%o6cig,?9by)^x!T5dq'mos_xpC;4ᕛ?jeIC-iSsd s }[.ݬ/-Kk'wH EyN4 wo>xn{ԃZO1eLE(ɨ+7Ai  N rCoyU[}R)q|[|gX[pmw~LQVܺ!IJ/ӱ(_"FnH?(y翿 \p*7-ۺD g-'ă{8 9 >~ٿG`G0.Hyvo]ewoHYtD%U_&ꭁ;ޠ) Y '\B| {$bi1g{{#n^FG\K4)tȟ|AwĢϽFYLww6ywi>pDo:LBpTCI~0gRpylr.{t\]z[闈z+xΛc~sB¨$vSV4rm'Y 7xܺ<~3* !pSkאMp8pRjVOwqAgynA8fCx{+HwZWs|4oJUs8<+k( 7?XBwp,o qh3 ~uѱ'緗oT;)\z4.9<(n;(-Y~u =SMD^Ϲ0$hX]3W*{leyc?VS;OQ9NV]~-?8OxLUs}ZE~;1z:@K=ӆ{_Km7@YRch sjkX^bDf' {_dqh|K'[ǨkaB@laLWFܘRX.Ω.= zqBƌI=&mxO .-ˤIPKd+us֒??EVXɒ۷1JI|S5BғMsʘ')/~{l)".O~J$$3!yCm8At?L{gRrmse}c=^klHµ@e* (GkІyX\Z ,J{&m&=GUH D(nay`),-;A8+ !J_|uR@&p u8eYHQ(Nqׇι_R Z;9!Q=bDO(Lj:BmAP Edx0bP&0y'5_8Kw8rI+,.$O}9İ· D Bemآ>gNUTRXvD)(w0ᓋms5;yv" AZ<\r 1&"_x C ̓#D il4q^mv_q~Gqo$fC{bO3 9nE DZԝSqvnNUJ:I+y= 7Wb.>e3g&&^hm0JϨ zGJprFM505ZS*|KQj8Bؾ>wo_FR>ᱧW#yk;{zJ` d>HʉP /-[\p޾b SLZs%G 3p,.ʵUn7-CgXQErK'VAںD%Rwd?- mχ6~ sC+ܺ4hT!a'vC3pm>Ġ:$sBd1M칦ɔĚYo Qâ'H$$AWz[f10ek*;-""MbF[! ħVuc;tr;V;`Bb%n\9ΫZ,!r9j>]``e2c3)S 1"n$`IλUc( huYpΘv QmK s Eb{IĘ=ЊtLWlr|9FIc[7.NReww\:#{ sm~x\nB1e }:-ު_Hzۥd͔inA0GێIz?jX̷}vW3]ΦWE#a5iwv2S2mWZ7W, rȊۧO:ܰ/xPQN\ͼʧƒmc`Xsje}e-aEʁ5QyV~oP%Oc8"}Qh]dt6\w7lauaD};HMs`3ܸqO,u9e˛{'9Z9q4\RlkPf ~O<ƕ,Kdwt/I$F+ӛ8"#sꪡ5"|wk- j,lZ R+RKgHV\тUS4yHvb7'E@3i]vfv|\k 9vܼ͍Y~cl1Uh8 ?`1%Gr$ͤM'>}Y>~ :Au80=R%+|+_EIoP1@s:kO>}Њ$ҤVJ(>t 㽯Sklͽ]s\ ZezT /5>)r>U:;^]DZyv+80U +3Q< &K "yڡ ֖MB_DI|!}N\5D&Yk`͢{KhsK~gU6pLX\-<}qZTYaoov? #Q& ߦ,i^ߣNB&²9dB 1آ˭[W/CGN95[w=f_|S>sW0Ό_OZRD!dbc2OWmbQѤg+:D`2 gP?}{(P8.O=#;'(zʼCef=NRU&D 0( ZLf1xNR)ԡ!@*}bdv*]ဃ>^`.WK\Jp_gX^]eqe ,t,t-hQgAcl)7OE.Ukqb?`͸"Ȥc,lm ᙇ=OCv{TtTIh 5_VBSOLMT=8M/z Rᬣr1`E^?2o_Qu2)Or 1;e;=;BvbZCK9S,2r8]צBcCU7ܼv5}*ycY|Eˤ*$$Bi"Qk@p̰,T+S= F'Vih@Ҭ0N)}7Ų(n>Di?тnq>ҳN!z6or+W>1*i5+, Z9wf;OSgțDݺÚs{\)ssLSY= :-yڐwn/Ƽ}P.߮ٽ*߽MGĢ8 Pt_x44?_*e !䶪S?x쩙tCP>kqU$,4֟xmM߷ps')v&C;\_&t'e.sE<||,GzzZmﱾƥٲGPQz!/_Ⱨp( EH 2F3ia9VWAl&Z0ןai Kz7b#iMB@ ;῝{aP¼wH *&"fFeC|YhD3%D"Q([s݋VZh/SJMvY'>[;}bHFʤYA#~B lqR^.O4_C~ʤ6\fNIvf;%[,(B= Glb*lo{%^?wjT#뼴<߻uy>2Mdu}9<mFTA2vrʧ?K<&w[x^>o%6GU'x\m3]`x}NO 619TGΥVɧ]7Gص'@|ZWO]zi{r8[DR&uES1D+ɄJ, 3bg0Ow ][ݜc[plK\r=QcGc`籅`УY`x‟̯Ys۷Q[68>Wv[o񥳆xֈsk\~]  4,v]UvF?~~j2_fԳe`8^qR|p"S??[:Aő,A F=WƵ6+ IDATT /㻭GX[|KSE޿>a\|]o 9˂8S^bS?biwiNJ7_:O.r:+: &ַ ?Xi4&jIC!xoqp"57d,)֏bNQmЬ=U|b̩Y@-/nQ,$BŒ, y{-}j"ߢ<V ql 9/x JztpyoDvNKst%IYH{JV XfvkN]0woq|?IaE5XJ;c?ዯ9yx}l>ghB*xjCaTG;=.03ï<[WH#q|?Gw0΀ިn2N_:7αQNǙR#4!"&$(L8vҺSb5c?j2ahpp  o4Cj2NQ + 03.s7_;zP7d aE˼1E;o|nuS%kԄ<G2.E 6INL?Onk fK%n}ߢ:ؙ]*=I5v+n_])p6JZLdKvʥzʿ>uc9z{gzɴnbv g񏟼Fܿ7P;V -[45njջ|f"]B,u\-Z(ldyaya9bI6Q{y$6KvJMϊrɠaM.pUZax0O<>|?i ( zwX*xgq *%V|w/]Ř4uy%D {IXaU7Yw.#8,-l> ✲7Y6w8]vAwxb-yv9;a%_0`e9GDPc.6y/)cm=-LXYɚ|ְ1G=bTo b`hcSR -i PT =V=ݝ] >}mq :!U9gUušC & USK8Јq tm/"сMf YZ^`PS'zRkS草Zc*9b&I5& bl &0K-8dGL*Qk = j&Hthr%J)Md*QG;DivZ!AkƵ;%6~6 Q&tm6_yfĜpH$PP0?_eo-QbZ"FFY]\buiD=:31@j)AcH$2hL3]M+_Ĩy9a2Qhnc. N I f*35ZbA3ĩ7&49P2Sd_i@y/ 㚦W&L͙eMDgJ]ܵ{,/?̆)!4(7M_O8u)Wtw7vQ[ QCjcm"b xx#ΊDu%K0ɗB$ȐM,Ơ6UF%XzmBEbHN%L 3r8\ǬJdQ5̍&fzt\1cN\ya]̈DIv.ߝ{@vp/;ү~:M6Q&=&Ly6.qĤ\%ZC - fbaܸu`ȜO_dӈ>M` MH i5AhI퍝 5ya b(DEK&*yHVZ\c}12erbJ4/6UESjET 97EQCTvV]%*!&K#,ȉB_o]iĘ"8QPn6WG`MH={86h6Wz2ЯLz7InEH;kƄTF͇33uB3i2dRKTXSIh&eCS1S3)xlRؘ @a ]Mi&Sx"ɮ,A?qVRcm",BmRQ+ `C\*Qr'Ab|Q`ԥJ 3sIJ-fwy 8$ck_QMZB80Fqy 7mKBpNQ)KM|z2a-`XCYPiVkX( 89eRP LDiLL8|$DpjQ Ĕ$MP6nƖ@i U)( (WRw禾bӦEm<( +t-GF^!)}2lR53]R:ɱ)MdxJkV=Ԓv(>`{5yk$$*ƐD |Zki'c!ڔj4eӍ[jE; 7I)&Շ|51Bq.ɴljBLm1UKH6jէC1=Fr="i#I&N} Liertcbf^j$G`t+S!3=2߃K`4cRɋўcf߹%MpbmjJMNY'ɸ~nIENDB`sardana-1.2.0/doc/source/_static/macro_edit.png0000644000234100017500000007720012174204305023043 0ustar cpascualcpascual00000000000000PNG  IHDR/ή`sBITOtEXtSoftwaregnome-screenshot> IDATxw|l~{#HDTP"MTT,KBM rm$܅Bu'MyovvΛRn^@  e "@ 9mD  ֈ@ u 1T\o˶C{~o){fQ{eW#9QAۈ1+RKXu _8<~FU'\Q@xnkk,j^bƗ_|#bëeapQfp>擭?pBvb]eίJl;_FiR`}-)iIs: %75Gٿ5Q' Bؿ1ȚyfYRf⡩>P *Yܡ#nCokcj&1n6Ӻ*dC 9w_u3C??y^  E?j9c5l%<NW-?l+.~Pa\e^ҹ[LQ'VYV&} Xx<`uW JY6C!W-#6[p$sNrQTRt3]"Ƽy clQ Y##i'g(@˲2O?mwo%0 wWdq99dv[}}UKK˼|6lp-pjAM+,[˕sIAY.;|o^iL~m+.p7O/Se'^<8uEee8i0~G mXwr8a+wI;v?ߏC#G˵%=/뛽fW_gM?9bû/{ʃZH|x; BW<{ +KSwǛ@ȺxꮼugNUÚls'3_?}U%1d;.۵ qUTf1k}ջfemlPJٖ߻_ܶiA[+dwiݷ{.C :[SS~uLQ$PZt۱G*q3n!-vr/{˭~qtἛDz% O<7dKY(oc덝;mSxvG_ʷwR,Y0޻p/CM\*Ա33ښO&}Nv|lʟq>*.HعtcͿڿLCgl3b|SV —=Nhp,|)huQ=X c vSv,9A:=?˂F~YQIP2` "9F*>0* PC1PJ5]6S 5PUD٨o/դ_Ooog|Fv0-9{n^)^"und6]RX@m|8K}˯\12)϶sjVzc[2έ~dWYAY`˕J0`*([U,5\eRxj '{HUl8+%K+ՌҘ'TbڧQ HQ< ni->Z5e8s&ASk#(Vzxdw󤫠;m۷ä0=T?- ֐e 25~N {'q?˻Ӕw[M2Rxhk~nv^-Sʹ hڐk0 GBP_)R f%CMw P H F13eaO r?:Cw yQ4g:uJ^Ն%"r6wZ_NF{YiFIց.ȥi+m.ۡ>D+0,WͲٲή]|X٣Ob٬w~;f_t&ۗ~cc݂0c_B1.fvQ֌ 7|}s{{ONnލ;vp݆fJu[cMY]?Ϫw~݆D\axK'+]X4k2@95%ӶTV]$#y>pW{Sd來(`y LjqN)]~R5<elٯO_HQoV1m=mF-|WUIRk^f/HÈ@'k.ļK?s!try>[11 #`Hsg2Z4vR,{PZOJ"@av~LǞΜ;sȥ$ZQ֏Yl3ӭʻQ=G?GÃ;ʂ@ @w.k_G G JW2Jk_),ȫk_v d7P@ j PF@{@ ua:)l"ޞq/b!MBi݉lVQׂjfhNKǂ sqцȜ5C(+blX,j\TȕJFH`A Ph2U5VvvұG%!8=uRRS+tQ[6º~kǟY&pHIMOMO\H!_oo?_ڒ.G=탹I)MM4/ bLL)o{T WLhn\aMPP4EӜƳSlgCtmo&UelVn~fVR)b@oLȒ+r\!qf9;OUעIVN[wd2BpvqdfK˸~vDh&4 |ZFSuEQ! B<:շsK;-L 槎8/~dtm !D"YW޿/kTCo%MM}o޺ժ}''UƪR% BkWAعkg=Y_Buʕ-X.,\|uZmt>;jlYg$nvn1[XlFVnhhhVV\nx/oRɲ,EQ{RT<ϛL̬˝//oJŲ,Mӂ @ӴF1ͷ3sL&LhԸK|EFƷw;<ݲ]5ҥx {6^yojK,?-g\GdrS!wUxG6xBDepx AD@DΜ:]kVژzf0y"[|%N`B-[z&u_ %ͣZj#"qnnn {xd2(C4jϿx/<8$OP(YEjV P(N+(((Gc0E!"{o 3 4SI/gJZ OrUm"0`&X')!q\yζ.]:omSTxX ǧ08޼y!l,HnWӦ̈׬96abu?ikGjRXE4-|B_e2Y r )V0_ImgxGmm.KZ[E)~r~;(Q&AGtrhL܇Eņ 1ƈB,( c11 blxA%(ԗUv0A{&#7My89tdνna?/) SBI!>^ܼsN0˪AcQ%AQ bX,!\V"g.E/KFVv^~jlBbL&ٌ1fYVPt:1Iȫ}a tTG2H1`U[$k:V7x{7}i2~{~6~FU@34'`N)*}$N2 cbRzwE_ ̄ƿw' l۽rt#A4gTc^Ă H-)csEt"͆ {j7k0JT0?s%ʵn7T<{ٛ?}GV~eFe+<G \; 82R[滨eHT-_z)?>¬Y@KRL9xԿKyYS~]׳"8IOL t(1"yflz^L9q99յrrrNMVTurԐQY[TX݃Xlrը}amLtsw7-MK.8JlV5;;GHI)E{ 9Ka`\| r?.?uCO]aQҦpӺeDd!%;z|A@d12kB}cUyU,mTlHl#7}wO޷x?{ƧexEQ f+ߡq@IL/ "V6E\\iZ~? +EY v'/cLO_kfuw=I:*,8y `ri[tk,*Â:騱ELXPtܤ};E{f6F-Y3q~ߚ'%yT% x7 EQVX,999...=0 BIi%_+!ϗifth4J<Ql6#D91Nr+]chS]:ı=T&!z1) SL~4 SW>D.,dHuK|Bf~5#n'zpY_I M<^/rom~z[u(*f욢 ̜Hw緥N];LXgza}ƥ:b}PkuR⍊nLTKH y{G?Ag٩9?&z_/iXظ7+ $CzcE\S. g`K郹n89oJ 9GW DQ.g+^E_W[?5k4ƀB~ܩQuyޟo7`Yh,hZOnz+"ƙG4s/xdӲuc{c_(\. B Ty'N6L!/IuɹoE6<~wW} 68c樶.=횪%(bDp2zcZFF3 FR10f՞5-ܡ/hXrm|J|*\"ޕEsk)&XQ.*ia0r<OӔZkٸ.[Ve%oԙT]]3:e'\K4"ȽjkX:R@|tT1oCzq=3΂t_r~|:}Ʋa)CKk撬A~ݷ}4goNhfs摌pxs)/HTU4ل=^PlN{W=bjQ"  !\bJ?^`Ȱvrʵ_HZy:i>hSA}wAȤY,ќV__KU0f,m~u]-e[oϑ^dpa3)] Eeq8ĿUcs-o#Y̐arrڡJ(@wPxEctQJQ/Fڸ1m2D;t=:1I9<{Je 'K KOY:Mo^8~uӟ_?zꎛz3SnOl6.:چNعUeSALnܼ9[ ?kx*_hwODff_7*`g0bϞ[/M l|С{pUW z @3h@4V)mCr׾O6hXyqP?rxM@@1WP`/ql+.q$9|hgͤcI*{V]PY٬ HJ͓4L Ma-!0[,eǥ߾ +sp`F!84S@tO3}]ddg͢[htq M4MS,Mq*c,,l*RzVR!/_JB%Vul0_o2q'@YE,Q-kxn76E_/׹s-^M55}hSҤۍrWGH~cY_,{ҽTa5(cˑcFygbt׳s U^zsJ2N΅gwFQLؽ)ydfpa mdRA8M5$?P*0%K!9 #bw'T!2X׈OE+r3 3mʹݟ_{0i1[>SoM{WY)R T6 mzw֕ b_ğee!+ֵ=w??|3O^YcF  QOoP(E|mҹOO*3Áh:|`e(Ruve‹&jvvM(㙖m4D Pj04EQ^E⡢g7ðXE^ARs9+E5EwS@D"E( pReFHiXS (ݻV"B;꯰&Mzףe0 6h:PVJr5Ep rvKF&O ׬lBz6WH%̫]OG`Mî~l-hp'R7wyXK=2|3]TeEQES]vܸ_~!0,m(2e†{-+^ >e߷s!\߯q5[B IDATh_K*<X.Vvr_Z`JJȿ~! { QBZUFb;-~?&--p/e$)„o4㚦({sV*հ?(i- z俖@Ld6bgFOr[WBHn-!9(1//w6M`_lhL@2 Vl܂[}mDq׶mM(-pomrɳv4Ȋ{y2>%~J,4ȷL /0 \` |&sy:`ʾIQ9[y+Xސay+ \|N=ιUը<3Yh2l~>~>ti(kdK#Gofz7rS^O q!l39N]Z!%!R.VFbG ܽ rg/z)*L7m֤K-cKoƫk;e FDU 2KЂjaAtֲPz7r{r"~oN/ _@Q)+F M)F̜X=o74dIâ`,O> PH|XJ)#([!A] _ʪIRB]T.W+^ 9ugf5)Omр]OZ^ e5_>)J٤I\FJiKMیyGےsM9a"\r^g ɿzl]+Sidt2a1ܞό /{u:`(+@HIMݶaTtM[:>kPe2_y>1ck =Op VӡOA lʪTr?(b@HT:44yzԋETrr]*=;id,\ClTTvFfݻ0QrsVP䬓Δcǎ\apXzR>Nb "E5B1BH(,"|sWvU]aZYaͅ<~nosrdj=P=**([ :VV"(^x^`,MQ ³shFfMQXZ!SDKu'nqsE_EQ41>qxAQS᭰Q/Ơ2ҋ*FLfE4 V?(p|ʌc^xA@6d*mxr5~~wխ%tXƟ&3tT*y) 744M{Fߛj|j3 ,.  T 8iO_MS4M#(T VUPUJL1(JD! Q8ZzcO]ٶUZ#c|;э֓jAA*FD@1 VY:S0Xfajrl`(yl1[y3%#8pyS:ؽS 3T~>r!*T_YP*=%c]"@oK3r\4e:qZҭ-HQ(Z*^$땦 Ch(3PVxkT~6E9rȘݸш:T:UcSYYlrjZrJj%|}* PL$jF( S=k<@ ^RٔB#Nbnf)7&.>U\2!b2֦5\L|Z>ã׵ǁ.'TB Qc t^{ݳԣ^kp<}[:ǖ @rnbTª=A}wL^ʢ=<((AJjَvm~Y(џ \e[%庖6))1))wm-#(g) .*婳ZE1lg9 0Ƭɖ/Ȓ1R`fʿfexǙ?=:,(aoQ-̆/uk3wo狥oo$<gx@lDxaK؍=]rn-'QQ f)AŽ{[6pP?BM*0q5;ם9~4@am#UEMgݜ;nn:}Ӧ{>PY%"9y9~}N{D7 ˁ4Jb­ւ8Cd1^ Qg,Hl_p[/^ i$7΋6v~|;nGj@:aq,@IK{ߙbZ{@q݃t{Ҭi7Ɓ2Ν~бkq2b6lnr5BE{>sggHvްtoi@,7~;OϵbWƬ떹GK4dY_m^:]0;T`B++nuS' jr``2bh@5Qg ݻ);:@K]Y1Ϲ?MKXj̤[ ! QNu/MaM"FJ0'(B@SXGB|ӢVM.:U-Bց88(($SYd 7v\oKfa-0Mi|P+dmޮ[t)w r+kkTn{ a#3) Wm;tq K<[`hw^qORm05!?U/ʢ!u ]O.'Ke,Pef;R{ @}u޽ZRՋ^?2X*VV?* Fy=WK+zyv5V/_;P8I]wǠJ2wkwSUY芨7V΍9=_L.lٍ̚]];3rP jW/ +oӸͳ>s @;ctK %9LajOZ0ԖjV=҃Ef썶3VZ£S+hV? %Lu&/E)R*mޯ.!Thn'Uٛ-YMM۹ CۦN`]=:N))l3&r:O I|`+z&;ˠ 3Ѭs/W{P'H!1Z;9WB}R@J "i6,pT~ oޘrkTS toH2fp=ֳ]Q p3;D~q -{[o6Wg +؛m-No~7]{3,o‚ql%,ESwmݮwo6;o6,(zIl+cdžxDOYzok1]vaO{ujF7Dd.WBaY)5*sN!_J}E}_F3Zy~[s{&]<#~W_i55Mk5tu뒲M|Kk'eݵy`U4PJoV)YF\L&1wc0F"B%7I $£R,*ZH*7ڴ|A6=k\FeF[`qNmܴϮjX.>ݫ2|ʺaόhe D 6_)Ooj7mBS,PU.]^c A{)pZZ9z]/7mv>td:0I3^) [0 H2-+t]^{KG :h.$mZlհFNBuD@'o#F֕>5 Pva]'͇-sTB[#^>^w+ dO4$~'R.DzI=Yk<0w;ڕXv&F/l-?,vD"[lպW .gČSkQSjf8iObjƖ^GKMkSFfڍY* IDAT;=dQoQEq_ ZqԠ{{ȶ_@q0PQ/7€E^&wԕvKI˹װ`_oGܻy$HpՆvV(1oB{٠!owX`K d@YBh#;oSWnưJC SٺJ}SƥlֳwX->-w~ѿuOPt\5"VĨܓf'|<1cg_^Ө޷Oс^~͟+݁Szv\7.J'WGħ' tݝ3jtЂceHa -CȈ6(լ&iU}\jǛ{$ {MO/ēpiK #$0 [}k /Bk'f?w'=ax -q3Ͼ 766-=lA~?ntyDN]%:wczF7\z_;_?ɥuʯW^|W߯KTn; ۅͳڬNx%_OXtˆ36zf濳~}bOb]t`\.ki9GƏkTB]-7mp;O}IK"lۢomՁl2!NΑ}]LX6s~چF=84W'Ag^x{K`WG{}y 3lqΏO9%GW;="<\{O]igr3#_}{zoAx3ҹLڻ#?Sp7{ ō /v%[lDU2>%k͆-k.i{_Xٍ*_@"#.\c0R)o0`0[07Dsڬ6`ٷmU_Nq1@k4Ɇ{)oW*O3i:08iLn;{nϛ ;Vp>h 0+A1REѝKC=wf\=;5B)'_]:$) jPbCk@ G@F-IGW.m$kvv/Z\t⠩v,$E|4 (ǃi 7N[9EI6_<|k``ś ( "qʞdt*cJ>.,bT ` Nz䈾?S6gJE\N>’ "wcAxk^zNk>K[^]EiMs?+){[^j۠aMƶ7:b.UzXИgkBQ/Mz@Rr'K .>{ovwQ[?%eS7$z'H5^Ă EM,4bHDDZ{6lrfR 'ٹ̙sXBedѝ{D4O*\4u W-e[pB6lZĉw8ێ~iz^]|ʹ:|^N{73v)yX+6FT-t=>QBԅgaTx EF !@ FSLM&5d4jF ^QT1!bE)bn%K |}͇>A@:J0KIųO Abyy͈C3x Rg,ybER|%=!S[ru翦<3,:n9^  9[@L@%;KN@?}ܶj›VmYVaGS?_/[?&Sޙo-]پJS99<S֪M"Xc8.'Y@m|:BviG] [/VP2.l3ϜuU(\GPR@y5Fy \C]HAM AG#9b}ҠɩEeEE'+7j5%Y{ w/DM:FnToQFQi1&jLY^qύ&3S{ yI9J}Sf|LZtXC?I:8D]o a;eLK'oh$tt4upuc^{y!-sNV (qCʇ#A خ/BD)T]?ڻL;g~Yͼ_OkQa2Ѿ~.E85TO;Ȱ sh#1^K@rHVt R{dPRUeA=]Jڍ_3ȤIKt=GfpUㇳF<%P׶|C'0KjN(dFѤkv:qKڟ"D^S4 G4D = rX0B@~)~͜ o:mwxzBIz@Vkn }wO:vvz1sg!vs08ԣi =ކ[͇0XZsQI(d}}jSK&Wլ%BJhdCAJSH+C~rSh h4:x$Loh$pt-~ǽn* ů^`Ht( <,7JR(LPh2hS%p R0!D* 3Rvs۪afp R\D.na#ƾVmgAĂuH L RP"\/Fýg5'YSviyt7Nh89-|MX5O`>Uu쾠PU(*XEkrSڲbH>YŗuiE1#6Vkd*Jܵbs 0~'Dj>N>*xK~[mK%WDUܘ͞s fVwlRq39)Ut=myUMdK`wyjBX5 wӑ ՆnzOۖMK1/Gj6SY;Y5jnw v_tos}5IXq ~#{nu>R~ yL='ptސ-dYwm6/}h٪ri񭔄B'@kK>9Ϥ#~:C{c)/Ɔb_p~͊ 6}0uӦs FMN.**]z_Η]&TmB rUMRŗI;:j_ tmKn/ ;t^-_wPz-LP\|}.Mxn{siIiykO9O䬗h]fȸF[P{ZO@']|Ι MgAD@\#oݨQ팕S>74V=砣7K/kiEf5yi?3ZVn<ؽAAE׵4fݨ,ѕ7ץ˖LHUOnԘ}ˊ=\G s)#]*GX5i=\zCN܂Ϟn~0eg,,quSi@nfQ̧ϧZtyqmk2VnN\;CSQxS VSU<LYlO(g`d`2!AkŃKAiohs`g%fFϜymyQ'b]䴀ETx;j ৤IR@2ץaf'Rq2ޤUQVTo_%O2HCώ^Ojxx+[*Np3Lx{;[M}T.Py4=KjRm?ߑ]+/nx˽|}ĨReK\J?t#i1y`kU7ucѿ]'mf.շvQXxȺ^;Ug5׿p49?}a`DE< OK.Y)z/c۽#N; wrW)Wpm=ǿI[D3ld%=;+Z!nw$s^ԯcՇrWou|Z%@&t>>#)rnS;+\0'i/[j1Zt~;xڼ|?mנŤG Fu~| {yW482lشp|[Sxw:<^<ɸ_#3æz.{؁S;Y<1%+u#xo_08~˔1% bmW2KxD5SD/em$ڄűc/:GpA|_z&~mm 5%d22!D[Rbb.0F`QVl VRۙG;M ˰V3مTEȘ\ H vצ!U[k?KM1@Y' ;<ڳeNmq X j$G`Q5k;5=ިl0x=ݶ6!R1- FAjJSu⛃! ՋyHPr /]9s YB  aFI}҄O_\.^SEA:#j9G oTִzs K0o3;@`I{j|zx 0~QOUX#u߸<AAlnmLGćAlw(etw2!w}# U&@2X--8Q*CA9@voj ѳX#[5/ BA EԲCFetMd AW`["| @(5 RmXrS"5#uZ#A@Je1Ocա5BA 9fS/F H5BeŽ׉,5BA wF,QDb :݃c_큋ipצԙS{  HaN"ayC %{ s /}î=?y;k# HJG)RxWrBv pr7~Ε' R!E`mo#2熽Zs>Miٛٳ6 E(PJ n$9k9l^|Ay(ۺs &ƃ )╉1 qמOek: HRj9 TFe9#!AIgj< H]9 [޳!P4I"(_|BnAa6B %#0)ꏘ?=w3J@ԪwtA: [X~u }ey+5+A_b6I@-m@ HuAM z6sa٠5BA !M FAj %{ڎb>A6WGG̪>2AF,f[`gyO)ܦUvM)U0gʤ!=IDATk4 H1Gf_%@MY;@yW-?9f^?/&}k+ H9 Pb|m;&s2P߷FOmvum68z3 Ravts/P wёu݈sф.^ugA n.2舌훎+Ж\߷y5SAnCͻa8~k1H 꼤Uk[Vn7. S-Aco7bwY|OI}oXsyEA(w3G2ҋk?ZXZxx¯NZEA&ȭ ~`M{pd?p" uJ)B(P0stbWK0F&_bkSABXOf#<A>ͯ+}XA6(Pbs: #- mWAB#,IWA.,Goܳ:@k T+]KF"_5BA@fDxZ#A!#J %xxZ#AZ!֝tSxAk T'RJy3%3u HC;ș%#BEhAZ Z#AZ1j^2b8#F H5ŒCy!-uhAύp Rd =ޔZŝR1!F Hm0Fɠ7 FYA& EEž  Ҿs'_M4QԍAz\ܣ{s?! Z#AAk >hA R޿e2ɘzZ#Azqyd&^>B?A^|Hٓ(2:TAv|7' Z#AfpA9$.~F ȣZ#AAk T%*qn(!hAE垛.UJMn *Muĉ <|f>p B\T*ur12  v:AAk > LW]VR !8ܕnr'JW苲=7nJ! q%ErJWhK5M9nJ4ivrABFd>;wwusw?!2ΕJNA)Ш(_r4jcG$2+1E[%vxlvW)Wu3,qg?NTYzkUfFDE!pu=df$yF^")2l"d{,")15n7 A^S &^Lsr Z+vHBCxzڔRT؁H_aF9Iuf$B@V;R b{Nqx*c"L&z`fߓ$PJ-@;(P =On8.k$*A_؎9fn$-N 36dZ)+&`ޝפXqPJxncn b`; ](^[F[*L#1N9wFs_ǚ{.2sW REj`Wq!v "TWܪK+ ;׮X|EX,BS|-3:KBs)m$&oJmYMCZq[|75K9Er݈e&o/F:)V׍=`g`ĕ Y;:ZbټF96@<-]Y,m;v.9U.XL"B4TVf X\?)DX.R)IXqr]pf;%' dդF`xCIֶ"w$?>9 ޔ?(4$KbX~pM UJesnH]Vknm*ZҼw4BSyyu(Fo<2M9)˖s~܊"s8\%EDe+?mu鶰fy+ȗT')`.IEhNح?*Ù%Yɚ* s}Yj9 "=+d6R|o}k-X5Ptz$J$Z9*SHpZSH&# &޻vOWDlfOd5Tn_C.VrFB騘$^":"5,YNv%3"Q _|+@:+Xp2=RZSA'ιR(@aU D<>4CPJe5uEx`QQr2Dŋ_i/(%ՍSo۪kCR%^{QhɄ>G(uRZTTX3)!֯}O>HMSSA02" jשA(5UzB'2AAA7J:C*\p+)|! p\pEin "! uʅ%Y  U0 ۩ bF H5&.1~U]uf!xij$ڄC'zqZ7o)]h\ܪec@ĬΚ?\}*|vګ.:&SL^\(f}suU?m[o~`QDTL{[m)ŽK'ݺIL'\RVڡ3uڄC',ܼa/ :zYƜ|_N9?5IkunD\6<%!->\pTOπƝMtQ9-|'dR)3UέĹ۰/% Wk!3EถU~("Ltp4A"N^ G-xnsg5G_d􀥧wF3k_TrmǛu{"nMD$GZsOׯ_z }2&,:oˣGMT2!C o=TlN=,837^KOdKEH dg;P a}>OWn魝3qWƗRbGyD\1Q;ٽdO~п>c ӧ bEREo hQS$zڢ[We/fp{^-5K.ٟ}%}lXGI^_xsٹxDžKN@mODvށ!a _q跟i;pN(nF}wI>6mݮ}'S o9?0MIyv,0z#~X=Ovhџn{iYD$GT]߼Ϝ{O{*tυt-KN_7oTB߼`u:qѰ&.1/sUbGo$ddQ]Y 2?т!#>{;t*5wm~5kZkѾ[Wr([='gC. Zk'%cp^eQ\{Ji6B<[ WɪH* aS`=~WmF{Fy%nY:{g9\[,E_`Ttϧ|[AcrlGqOuyj&٠tR<1_6-kl\ج=f.>ɈɳPMʵ)yҬI~ &?xN<;veu|mzFrODpoFMR]?֓?KrZ$E`ʛ&i SnHR wD3>[{nmp |K &GC]\sg.^8Gc*/CdDtS 9 DQa)vaBTjW,=N. }`M*M*] 3qBrwBNвs_o'Goȍnu؆N y5ߙ1ty.ݶ8ǼZ$]_\scǞ ׈nwoTsiҷ?@6^z۶[Ըw&\ر椪*Ʋk=8cOE<:r˛[?1Hsw9?;$_V/˲v(V *C#e ,2pYvpAy 1N|>d݋q rʜ|̞MC¸cY'm<~#ݔ;* hﶕ_z+u̘|Uꗖdao.~ A=Lun򤨽.2\}\R]Bqm=Y}jPa!dMSTn{#qk=+y ⭘@7LC+'D/U~]ٕr0ܹd&{#NkW৕[g&kwɍ"Yaź-ʧc<?x9>R9b(;q۔լKCg[D/zD+Tz.-/%sFn MTm_]:cyÿ*7g1SIФxg^&/|t ^ۏ^0vQv ճ֌k"^*-}p/mzM'_B!n_< H0&o٩[UMMX8vz^uGCo &*xfG.[! S~);qERxηO7q”{dƘ7 Y3_{9/ʼnIQHq81*bBX[L R0A}! CQb4IENDB`sardana-1.2.0/doc/source/_static/macro_fractal.png0000644000234100017500000016510312174204305023532 0ustar cpascualcpascual00000000000000PNG  IHDR)GsBITOtEXtSoftwaregnome-screenshot> IDATxy|\e{33L=]t/"P V, *W,^D{QBQŲ#h MtIds?&&6I&9>gh3sޅ7ՂB!SK t!2Hf@!F ̎BuʿBS(B!SJЄB M!FAjwZQ`֞8! 6)%#Gw_6,ݺqlH%b|y'Xj'$cS C]9o @$0XqZ clͼ\c2Nb z) [y,{;߿ޟ$ ~ jno7lEYk/8!ӟkq+dnkYޑ^zy'p0OG/NH/߹kMz72I>+;9'۞ߺXw(rڞ':@3\!z?!@V:V/V29gFj ls.\_}oW~ĂN ZD`!Pq;[^߳[ҳ"&< hk޶iuڳVes,%k[KDUW7wյ=Κsyz$U=댏wVӽ3k~orxrOoMIqy c޳TX]*5g+&XY6BNB [ms3}]u&"$JBJ@p{oT!YUÂkKHEXTT1f7aِ{;;Z'/^yE֎jk<|}gG_[P[C8D2vsTăPKgN|o$Inryo[q[YUٍ7}qss3'x_O=>c̑_}On٪5J(ڝmWy=ֹ 1҇_Bjb($&|jHZ#'s'E=]]nK*۽z)v-,9RTレ񻌕+WZ,zsOb 22<ΦϷd7Y9aO<[o_H`}9C97`s! !$&uxO&!ILnݶf xpQN+GeAkoH6,{pO|L؜6Ipf0Os-E1PU=km^ɻh%m) Km愵5^y= Yno Fͩڡ@&`LRyTD7*wû`M8l1\)^HVUUEa!Vwi]t\GG4M{>qƻoGv#_9Cᚾ'׺WߔHzOWm7:芪1Y#B7΅΍W7o۳u{{G>qc,$ cBI2J߰q;]TZayk~xê3ϲZu[הrlK瘬!_yVb6NMdY۾'. 7%@Q#ެ^quᄴ /]@{?D0Rb 1Tf:7<;"s5GۛSk4X3BiZe^TU9_D*HUVYϩ,{'0gpcۮ*nQ#SUug_|F%Y),N1d/8hB7$ C|'jTjq #/A9g;;BHrhvs/)rp\Shqfff8}_=k3dr?# 3jbdIVdEUnػk+H׸&F ioW.Y%cmYH(#K1r)˾ 5KD fͱvze]bˊ8c,TUi /Ќh6a0 }[cw5+${z {m{<Qon۵o^{U)Vן^ʢ%K}>bE"ԌO?_!S,xǑzBkֺ|x*c:}?ͽjjjKp(sƊ}k"mũ3x_y[> ucuǾ@?ű;J$ #bHa4k{YϾ7<OSSS ƣ{}g3~i,mYOkw1ے@]-o3W:7 C78u0Zsps![Z5ǾWBfӐ/tG+tמ2|ȖE_J^\pΌf ^"pF\wj}sT\.Z0uI T&$Jkq'AmZ:0rpGˁ6YU?lm=7vw;6 CYŀ~džmVE(}@ե_\)ЅubCNQ0u=!MzC'\znæ%k?*=Y WKct<N뿏륇򓟔 3ԧ>v߻[8\'a=6oZ|i!W^Oa.λ_tC{d'x|o_ \<šs˲tp!as!apι!"s.g/3aBHqNCwo}]#⼊^x CWFx{~ ~pwmSapsnDk:c<_BfGNkAwy^}+pk6<ĺ/fKD6"W_vǁjW/]e/]8P:7`x=7RmVˈB@@M\aL%븶?6I丶O1Fvǖm:ܜb|ywC_s;XՏ/.FGN" VoNas<c߻pιfa]zX#a@U~?tH |M7 oYfYz -"K/q6 t~; ^ Uxk6Io9>}5e~~g$u0f9ҭ`BfP~< -=лd €B).UVTdf\zcj.iNEmGT!D?: `|ޣ =nKZזĥ@pS. }˞|m\mh#hE~ڊM[]G;6j)6{*ޑ褒 `l28 aC~@0sC3h^V]5m+PlI=ۖ[$in6eu>-9OW7BeVJ֟hI-40DChyDL1\㽾7}(fQ{< )RnnOp!qM?8kM{Ju] 0t0 nps5='?!a^i}-zrHhEQ~4_g8#Ǒ-\dkDºu liQ\7ƹfKr"W]us=׶P켂[.]z|Q}֭Y,}o[lpcjFAK#~lw/N":s.0`b_L=`Bf%ђ(z0a:&t@:l端nK!15^^n:fFĒvi  ƘB B0.l+y=N!Ҹu!š\3Ź)ns6@+VtK2kŸ>$KSHj@_h!:!ٯʺt$49+Y, `PU%zˣϾ}|ى lz70 I<"xX0ȸZyP!X$In_NM uu͋3ǟQe!Nz;om0.C)=vGjU s&q&s|ܒSn{]7 ]7놮a@vE I$d FP0x$!&iJGO50 #P/E4)rв֫8aco}Զ&qϝWw>X ɧؼ5]QZaL IDӝUsiTuuu222\$++/ys| ي}Uc!ut-E׮^dl \(/L>_7d:h74t]7 #c?BfɅkNے!n={x;jw[{I)J/8"q4Ʋ"@Y)ssڂM΋5;!zʒm=:ן%m>*Jlrwuuuuu1ƾ/_[xZ[lJʲC!_0HWR@ t[xy{uCE0 G'0W7t]熮Ph!Bf%BzzPtw_[dpu_GB VI22^sB347m7Sdnm;ҽviNb/C߾<|0fUr:!dr)u<.G(еê=зh)ph'!9*_9дssr.^UU54c:{/L˙V 0-nL'^V:oKCW{s;^?7\+;~cm=>t[4Cܬ%[;nO`Zrʿz\peȸkjj̎B9SRR}\XX(Iݻ BT :::t]K%//3)FB,%iiiD=E 8)h[ZZ>Ϙ !/IOO7; <("HMM{n|x8#Ǚ8["X_1;IE'?t%h2`E*D&%`s߿?СCa4!LlHX8NcTtc cNHtk P6E]tm9oʕ4:n* ّ2&PfGB%`sviO<3ոIbP6ͺu֭[gv&;ۀ {RbI:xrMNq I0J$y0I fGBLC $%!PCfAA $' g8pBar41%`ǴKDDCZML-J$8b kxdLJ$I( ,3; B̢ ɱ)A $\d%GLWQ%$ G '>#!$؁ ]g6*ASxr@6; B ّIA LE/!qHlfA&%`2e$`avL/)`͎$` S# (Kȸx4,k0@!]>t l3; H&GT$/!E{&0$VH1; 2$vߛh-Ed,0H(~tMґ!mARZtpHDQ&@aPcN{zh47n D:#!B $P&0ȸ@&`7=?h= )a)@9xZL"(t ّdYt>09dW X=}Q&$ XlvdKɁ A86%(E IDAT\EO_DPiG-2uq[ 5( j%`2n4yz<7tBi0PiB$dH_L^(@aQ ͎d2 4Q#I`L#ɘf@Fec& u@$tl7; /J$N2 '#J>x:XlZ@ 3p%B36 vvZf%7բ JdT49-xgzyTv >1W:;0 Ñb 0Mtt]@/բ%`2$YfA82Hf%@ fc7Eē%`2lnvBl"fGb,  09N0`P@Bu Vu'YYufOI}P c  6 š uST@Ik 9%`r|@Er )ޕ.3~P:ۨl(2MM>! 3U_.{SZModVa(r6"i2\c!P&a}* Cu [L^1g3 (Mg-'P Muaap swe @ǔ$ڀ}@xZL@լ摤(fFR9 Xw2Hm`^]eXRe֦d %vW)h,i(@9y}H^g!%݄$S6V<*cm,tp)=|*M|:G< ni?!:-9Ft_\@[,.M`t@>A `<,f@}2Ch-=Q9H8t؃汄P$@}!zJyԚlxF(NƂsʠ2d؃2>zby>%d%ei4i2u]o(-@0fdlI&Q>e$T$oty.H`Σ*O[Ym;s /= <dEt\s0wN  c k^o-c i9}qӶd?~>ۄrwh 8%8%~ϸ{@e.0f/J3 5PL?:ԁ WV?sܟl:,UH 'tvdf c=)6 g0/PFgdϾ!Cw>|΁FD:C/~5޷p_%eъotxX2ޕ'B cJ2 (M %J*<scs[:F 6,J+llXfMVfNNF2P2 0;YV&Ǚ,NdQ!< t@ێ.EbY8*c3%`Y XT>?C<1$ TJfdPa`PfvSp\Ǹ;MhH P`:un̉ d 07!)SSVnS+H šaVЗ*3V`c:F_6J{ŷ}#)75u ít(z~v=?bcEG 3O*:ߐYA4L1J3 N9`&.`a)9XŸvݻ^bNKrח)s٘c%ߍJ`'3{ E1/Dkѭ/-ptt_H3Y)ʧYTƳoY+rb|ϝx%;vPrSb!8b ]F =uh~bښz4eqJQVжS(Xd%xXpHq,Ҿ*=Ҹ;~X4`>$5-Tl^-{?RE6bHZ7FJ MS(MI[Sl$(O_g ̛)Rcyc{džЙGt^[p Z_HoyP<j'.\b=V/kOGC^›l:.@-c*EHV \zfٓv)N I!mb9GSZr0ygʾ؀f1^V Cj"F1ǠuuGq坡zh`&?r#@ĎXkWyyJkբI(O#Ty$20HgĆ:'d2Zֈ x2?x%>+ ̅eٴ3k>gh9Hs@]M%@׈}܅ָOʄZ4MUsd2Y LP:&@, HjC-CJZHF(LCN I,™X-Dȟ +DE3y0TCO 6ҫƊ1eLY-:S-pO=޽{{zz^|EI꽂477?߹sgzzŵk婧Z~}GGGee^p89vhE28z+CD:7r@P3[쒻rl!:bS6"G]R+!Vd zeiiiOȩ]zݳgOIIիPݻw嬐 N!'>fű]P:df}SZmvغۊpDmEj,SڀK8jG0X(0X>moa' d~L٥/g"%Z\\ǒV%`ŒdNN GAK!q|0i*LQ:ru ՋWny/.՝Y H9թh*:;X+`72Ss ɄP z טKƆ>U9psT2* HJݷn n)@j R_K`m\rwp!-n-ܳsCߑg/ɯk}`[(ڲlьTmXp[˛7ro9  . oi> @D 2cb`g] IG x|7xiii<("HMM?_mI%pYf11 66Y̑&>ǣWfR=Qׂ؇wB/k܏k~1t[^cȶVCZ @1/(GptdX?/M:}@}[/ic=YZZZ::zP//\t 2 ̜(gdg_+CH86Oc{P=WHŨ}/hNcٷ;r;6לEEl^n& p7L8tvZ49}$Iͭ,,,뮸^{w߽{袋n6Q^^~}\r!dLa>$@eT&닱=G<{쎸׽%[C #"=W:o¿8U'6yQ ZSgCzZkeF@qX- *8[u\S UpTlL'7߼;0Ʈ w߽dɒ뮻[222nhiO<3]wsϾH6#p`B'X tᓻ wS=G؈_#p {.{w^Xo慳nn̲5+6ƵWjuQ6ۅP×-B`V`@Tu$,!-cщ4I1TtIʾy+Z 3*eދO[)<M] H{Ńـw .xifȐv[7^} [N7W[=)ZIrG\6ZtT2iu,^Ò0Iru&E ?IQph7 gvі2Jhi&Xp37 q@d ^ toN^յRp2-wfkш-j>:s}>,uL2`+9$?Am1ނsW Ǘ4<6,>]ZxJ[?x+NƦ[Y~Iet7@4j{:#c\/? U鉞(# =&h)Jy@LȾ*CIȾ dg/H'0@Ɛ.9u8DL I2 a$W77wƴ`Jl咑wp X3)ܒT0^`7*>G o\ J?o:f(ű9TUqOYt]>SǷLlC n)` 93m M)qA22w5| sr֨8TI+5xvk/k+f:A|ͤ)2}qsIP&< ,b"'PxgBUTd&tgYP Y R8Xr|u.c"2 +¶u;xdoo/S!.5Ra*H~ʹFTX<lB(Jѝ߼p&X$Q% p&kc_:oЃx@mK8Ƕ߃X~o_@hBoNJa^Z{]@N aw E^MСHL^ P6h'\sP:XcSւ;.#|p͸ڊO45N+|0>!<Uco^rص%AIhZc4J8D#--%2J X:ZZbfGYT}V \b;}p/T^˴nO$^Dd@ 1.3a_~я;  Jh- OX&ɔ _, $d4P,@ vY$KAU:6Yǀ32F<P;L|ݔZZV#w>'7!DP4L`Qh? ЈEi.PBnOևK %`25vQ19K:V\>b @H4 #rǒBۡ]=i bJĢРpOD*o1p jٽ*KMmu<P?kr֋NV$%`2@1; Sd&!J@0W,:Rlή `zwm[I9T9vG+sQPS&K{ DZkC$lu-6"$,P׿i:hsƭh* *jD|.ki4֌G L1)AŤԜ _h~~3A RQ͒,OȌE_ {'_V9\We`G괎E23dfPAws?8 -^0rQ!iV|rg 4Yq),-mXdE.Z5F΂An?.`.fIT`>`u^@wݞױvޕ|@բì|)*KDMF&%`XvbzuvJPYslʳ%V;p@.\˥ܘq­G՟* !;(THAҿ>V̶YXm8ˀ|4 >o^jڔ.7߱!݊ !Zm@fl9#Ga}z"SqjЏρO5a ]zApH>!( n}_h?ԓ˾q046 z1Q! =gkϮ~y>BjѾᗞː:ӀF5SQ&xuI.8ysOQD= MĉSsQQ;,dϋ?>Wa[ 'SЕ֩Lvo=UtYb_^YM7??M?Ůa=/==ub0bao.y[*w]- S>/INl%^&x}jmukl?| +hkr@%`D9bEY:C KxIFc]t|ڻ~oeYQylbgKs+kwU K&>(,5[̡0g.#.e-p@#P[6(??d/h_D:FjdEmyh ߫n;W:p57r/<)W"(}v{y]$:.ZuùK鮧/l9]%ԟ }w)m8io#Ί (Lֈ/J뚻 6qGᄋ+©SFGfwutr[" za|\*ݴ)yļֳ `^.-{L |JcF>C[>Դݡh}E|Qj`;-A{$SQ )4TCV{%GIt'au$MH48Fg"$M9_UJb[bb*as7}^SC/V]DDbw9E- +\7Qҩ5ֶ6䩞Qe>|[ݑmEa׆5\t*zk C̑88$Y ^\wКon $"%hY00EK5QԽ]|&wFJ" ~=ցq dO~ǴҘhqb8Bz/h;.+ndsz:(!Xo鼽u[pQtsB 8"GZ3_R#CսGUscU*Ge*Mۇ"=KoGn/&;b o2͠DYWf~^]}A ԂC9M5NhZ!A QIhow\f qΐmSk7uK /}7IE7ak}i.[Wq9eO+tSz8[8؃TL4^xv_q5p*Ϡ':D8_?̠FG07l(xCb8g_x.ĄC>x[&ʓѩ0ZҸ54֘2H0R$@ J> m:ǭ\fAR}|4D>+ m=ʝ6+ꕿvڳQLRD<G‘|ޡiZ/=qُm&i{0꫈G[,s7BoU",zl_s{^o).K#kwӿ/ T ~8A@8wG}NTZ_a>5 ZaF|?1b.P] aB]>Nߝ["|5Ԋ3pn C`\$Lh^eL};Y>|]ݎKGc^NjTyMvD@K,ݽgI/(&JDy[cN3O& jhq\DaTcҴ3%Н!d]FJ"ڒK:Cp%+ >/P;tz&NI ;gO odXwM !גNm$=7^ί񁫍Ʋ¶x^@o%P/2zXޢXEgF`ۃK|7pc)xO xZk(k"@)xăsY#vX.vԧАF)s#=NNN:CނSżK\1s"Mh)|iwOCP -1PW[uOOE8He~U7j[-G7x0 ɋ>U|{.&f[Nz 5&1N(!Y2! : OG9HZnpMS]:`'oTKv=p\ksz==>tsn@eg_iHK3ԓZNnu wc ps- &c!¼颾"U1t NG$d z0+At E4*޽Ӗ0 w+͠6~=(PTb-2&#߾[麙O_]Yv"Úi)8!t!rw&kxXtB da1Nb st[Ng)Q8Þ=|Dkv,w܎z@?bcܵi<ߗ3D%ei<\Ob#)$X:{d}&k,^P%g\s;mi'8X31\DX(^}E0$L7‰DGU_2}("@P]ߙ;Y){" -#}Ub,Y|݇Gk9;4lT痓Lb)YYK2Bhϙ ;>9rh!h14<+,l`- 8{Cx!HRP Hpa/sd/ovmƦ1+Ww"Im 2(S=e:43CpHrrQDM̳PHyC (Ȇ>U@S. 9qVhT#vT'\L[Džj@UDIR[E<*COcGXq F,,!LZ7d}#ϱr]vBH&F ]CO~ϒ6x[}0'As8,'6i* *=O&yv]Gc@uzf<@-#ilӹq蒥UjKhq2fk<l0s_W4uŧp&@$U n&{m x LѬx=6Z{th;%PuYE9ܫ(;N,)Eೖ<[F'XIŀG =9 F Nȶx HOh;'=I)L_4Y=fO's8 އKdu~աYd[ N+9K:ܱp_S~ma+ pL'%af0mpT^_ `ɩϤ#²5D`@l\T-s;S co`XѷiqG%ϚѥbD]OxwrԶ9KAsݳhau#٪*!ΟyË}PaCiP8qh|Va [9!fZqG%z:2mYa\+S5떾WRvSY0mmxa=֊@\*Yf@zTlw#+c:Ȅ; =p,f4=D"ϖ)^ nW\ߝ> ;y(Qj8 kTZ6R =~|1ܴ,TIb 1 `qig;%̴ȳTˏ00͝3>Dm$56as# m lGL=TZ m'jOkv^8ċsLOJ&1zrܥ5M0o*o`+ߘ0 XBF΁S2;B a~"5T8=9 ii7Mlo*)I?XMD^&ULr?eVypodIriL1P)~$[Q heg9z?ќF2d芭 L{7VUW2Y"UI˒!S{z밄Q DŽ16c C!-y !s{T=N]+d͆t ` :`6Tq9( HJَ&g03- X ay9?_.|bdԃk`<)ӈAs\̇R>J|']eg/&*=YUCbq z 0WOz0 k$23ΰ3#\f l,5guW.nBNqvO֢2,#YÊTQ}nsɟ.3" :GӝoI14>78Fz,kԕӊ6>#Y<< F\ 8IyJb\{l/+v׫yJL4hG(dhPYCccGYbV|rkvvw;'7x#BS Ir_@u~д9 v< LS&g"L@0'y\).q? "L;$8Nl`{!`:`1N Gs$‘~G3v'%4kXS^ 'iM65dá72Ty&;W?ԗE,R䄮'54>(8elljELj7ZG,S]7.y28@h6._:t$vm뿮>ٓ]]O 4m K+0Dc됥khnC0fH`d;Vňϊ;ZlREHۏ6Y8m\%siuǠ bk!!P $bd+UmޘkliN$h 1Lbɐ Cw"pdĜ%`\N-[\; 3dEt4,8o^־7O=#[7{k!zkm%I5E bvRznVqN%~8=tݔZE8>dJ[J:1Q<@x& sR}%OP}az5Fї']tw/ޮեBvhWd rB`ph녮dr#LES"-d(z̢',?{{ ],^4gV;N;$}So$UI5@TCfd 2x KcV?_{X3*6aUMN3jbL1s$?\1I =)ڌO[j`Zϫ*fWB_(ښV7vá$ g36F &̐`׵Is7V*%KQ) ]p8veq;ezVy%[ v}zoIBv=:#g=ˊ{ Vyg毸(b͠aZ>`B(^siw]YoilEh< <qCCìYV^}Wl~qqq7|5kk.6Ofw#'rA M j0H%;2j@ -!Q6f=!N(1~OLIb=zh^̭߮gQW+l>稡q|4JJJnڿ/.;TU{EQ~nݺxt֭{nᆹswNSyvJ‰Go҇$Ϋyucn˪t8Ej!3P PzöPH!p6]}gŅ_i䆟 o_gX)҉ [:CK IDATa-oԀv !A?J^L"%|%=Z7DK` EnZ^ p5:kxδ4A|/}Kz~Νn/,,~W#+\uU~;wק2G3g}|=ߔv2q /.cE{譸ۈ;ozm qʽ K[sW ";TO8(W%T>omhP9}^z]At}s)?M--?AIC]vTC}- ߚ Q3o/R<ߡƔL|/J 獿ncfA4ƅ&(>`CC#%>CτֽO.WW~uuӻǷd.GC*tʈ(I4j_!Lr*uf?|BJ%s}h EG0N^)ue8oL0{#ܣ@K ]@*)4{kutfߗyM})?S p z@0-קx,gO>C>z.8//,WTT3VTTDkjjp^q(l'#U1 FP!:%DI_s>g+RœRU(׏LimhWǜWOhQIӊ;n%@EppЧ h]t6òHBeD]o*kėIu#KGO!N #46> ƃ$єH3cM",l;*-zfpq!·ZpNtN)|9֡Nk&›o)]wQ{.!!x衇z?"1g /yx{gOQ$}&G98l*e5bl ZH/4XεRB̀a6x;z1b܅։rP+ }wd# T~7ftؘ߽V̖Tr>T9eRِZqjLGDqP_p? TUR_d4 Lch< p?kk"<)e8MF0jt:}Ch!AG=<.ڟGr( Pr|wE_)^Ts,B JhP"U?)5̶k[S-2_' v5XA֎J2Mf2Ekj>bjtd&=A@/qxs#$ x"@zch%>0R1T#].Y;F g,.<#ĀXP^صrm"slUh+n#`5[7o̅sF=[62s%xkL5ۨXGa;Y1uV:O Y&әӪTHudLim/ ݠ>c'õ|9p@!nO7F?t!A]]76b˥؈% tF7zEЧs6noXELT,ceoV`X{z|3 M3R v}MAuvҮ#NmL;/}"_v4ohts{yO] Kž>ŋ mZdgƓL#^"k r(1jsIqOꝫف&CTAo{9Yͣ4ȵ.Z|mt@|-=;8HeD},*w|]\ájʆO+.~=>[W0#Roj^xVϟI<]S~[[KQS #u8>RF3Ah|!B)9 @_c٣OװlSYg]~x ' N 2*jZfۇƢ(j dvku3]ktcjwXc ل$SGA[#H9L}I!DAI7Ebƣ#(܉F9!;>ޓ}1'Evإ:KêTMzM}g*[Dܲ3{Ǚm1 M:)>|mD1$:G rHeW9KlSRq'Ee/dQ9C`_JZ@} = )7w{ڐۦrx'O;x;굌=JQh|F3m:ư{ )0rGyDQD}Y|>ҝq] 9}7^Ω M&A2pj3fjߺL &I϶oؿPõ B~314>s1 IH&5wH"#c) nQݒuX2g0j]_]I75ᄾ֎6cLNTRu!^rn@Q7Qiܒ#ޱ??%@pUM_Fp$չf*1 %M0n+ t9`Ļ,;I#πQ9t@C5X'T\^H;="#젾@&&h1x^d>$gkhe] ͳ/V ۤihM,9^#^dzU4i!cX ! |4c/H0`q|G12悮s?o˟|wvH=}h}jYq8_94Ut+lm Y[@7 ~'}!hiX4H2$M1rOwg0‚іsw W_%P^LjO@5쑅jL"ypRR̀L#/%`f `Fnd3Mg2"IaXNbD)G6Doh{dkgQUO*:"Vv*El7dBZ9-ᦓT̥OasM5NMg, 2zDCTx/,6)g({gkbs) yIE 39rgh>khLO쩷cJc& `18Il1ƣQGאd,xxRL:/?POjeOЗFOψo>_fzJZj쟤khUsSEԓ[}_QKlGB8zF?4DbOh+B2Ďex0C$R;˚q^_(?0ooL*|`%C?k|Z5Ӆ@ȟ 7]{e?_m ip4QDb&%ILx`ߔA97.̻zo{/V|c[m@y@6ݭ?w-PW1rjʪRY=yECBd}qTu6 aqh*1sxHKz&OK$Az@DSHoIeYÎ+jҾl:Xpj}-T9LRY+ =G#9|]VCcqyo 6U, c4Q L(7T*!j2>1~HCܧO> ☂g?/1^XvenenڡRޏؤi_oe-]IJ@" {NƌFi,/O I`8+f}ȏ: 2~>OԯMZ$=D!s%=|uevرB44Bi280a!ߣ7yGWd Nꅀb/S#uW>O-|~w]@c=hh&$sٯn- :+! EkhLM1o<iaXH D̦h6jà8Q4*?fE $-yŐ%RڀzFq6t;2/m:, !Ҩs#Jb .LBcpk!/KT[0W2nC8ih&3 #ald 2K]@բs6Ph֢9O!WGI=ށJ2ez':K 9$thn"tlTozQ^IihUYS=#!43Ocrsjd (B[ ĠOYJл^B6ɽN= e[~?{7&(4=#j*2}`&)?XZM!xxQ-yҡe;ZW{^:E-ȥCtUեr}ZΕ4@,ߧN@Ǡ"I^r:)tDi{DS|˾[~K_Ky9|.f9RELdȢr+/Vri輂 K߫?#Rhu;<;gQ2twu}tя{*ϕo.}]0: ʴ~ ywіgxƔkbMRqN44|9 A%+.t.cTu :Ҁ,C\l{ct]Jiǎhp(OzR&? D&7w9prRn*TcNr ݩR⬝ģDHGF풼?x5PC}݇)46R̀5]^gy6,H,'k4ƔTHkfЀ x1tE^7XKG!ګx^\:ޛz+j$!"G뺳>47֐ F},h!8*-_"_+Τ:Q}(?"R]ӫ55ҘbB o֝u}};z!5Uu&FS= 4y_=m` C`_MD#[%ΣR2[FWaH׏E<]IO՛'&s0 z#4~~78TD7`уʅ)tSKY__=.VE1]xa%sCS%?b;e*NNҩxx!ukC{E23Q͂`D[gX} ERܝ U9uxQJN7[q{1>@ܤ~v,*CpZ43=4帴J$S&p#CNrws,1GyLjư㽈*p;[/ &[GZ$]IZU<}XƔv{[Цkʖ` ǐG0qx&YEsX+.ؑǐ'N !@IzK Yt7P59C^8i"F}FϺB=\hŧ:$ld QYDGI\Q`88BXM5NM1J}Y Y>NK>2}lǙ;@``֑+YȂN'y zIGvkIOv=(#WÆ"uax:7T"e о4N MUYw~oƯ}pc(p:k44&&ӞJ[zSg/L`x d)rU#ve=XhxA1D)FDȅ閇Oh+C Bh2fC7Zg?WnʾhvJ֯Kڗ]}lq$YzAKЈrzLDI4COŒF(՚lj Z^h +UEFL6ZPaIJ@C~>psY9d'|O,: x`$3^L;|=khDOݫl!/_( QG B _F/`c,h:,Pcʜ`1dW4_iӛW^fY{lo()S;B0Ë+6.jTuw`V9;GMwN[?..1EiztJ9p1腾SA`bAR?oYj)&RN~) )$H՟aSI_wWBS0( p݄ӡ2=qC;A-ԞqZn /xoh4+U=0Lb7M5BB}>vF VHY>(,l)˶LZ((jġsgi7GFCf|V3(Us=Y]0("!ڜv⃽@}p/<2͟oqU+zox%jgs=giZՌ"XyQ6@6k`qE\Ic<_BPgB$9Ygڔ-Së/$YJY =j9 M }A@i:8yM.]$Z>lR 9 )G>e}-نLw-KUcA)lʇ qf$_3oX`|)O9XjM^@ںB5$è#lًO7^ #A ,(vB3 @0qm TZ2t1žP݇h)>A%BC: d\0Īh62꾱[\rYz)'*ȟ]e6b1`h- /| ^ 搫k}z#XiKhܠO& S/TBAt9# 9ݣ (dsɰ>]0mzT~N .?& 4_S{022vd$~uqI N \LX?|٣ˍk+QsNOo!ȊpWoBhE- S<=" )yt"tk+#J8An@,Rn$碬T0y#/5Nd08Wph0p x'^}վ͛7_}ՙ[o .{ʳ>sNӹ~j=#d/Ib10 *EY M24NjbʂӃ_QvI[Dx )уU9L%&2'$TH_" ,NPkX"tlYCq+krkƪq\ƥmΝ6mCCC;wy+o222㎎sBcu8]+ힴ3f,JaTk_w9<>׽ltۿG.[V^N?W;g2sZƑz+Za$lj=LFh mK_~+VTmfF8tPSip \;8Jl@p,Œ gcC>'en줾Gw%_X }>,GqkH̭by#%.CaEc3E%IEXWX|'W<.Yìd^UMuKwZ?woiG a׮]W\qō7,**ۡxppp:`p,Ƽ9Mm W58A jP5g |X¹5.Z6'Nhj8"dCv㊆"7ru@KlI/tMQ*)cr<ܚ]̝R4NU t,>h^ | s=4cÚ5k}|;qqqwuWhF!R6p0#W鋝=Z>ap-7Հt'>(a"i4 C;xjλ,nX kY:^Ӑ]`aUܼ'Ә<,&Z|츌a\\A[ f977777oJIIywvhnnNMMl6^onn^l:::Ҧ;p~gWAt1K #3j(1f_|O"zLdžh`sJN,1N#oDם"|Z#'%HXO㸉[L<NEFjQeiNWFex}X@wsV<@>߼֘Ji+ӶbRN)TTs-ǀ_w^RRR}}?nݺ»;|?ß}{Vuҥ?7n8c t ,`u(tb1,9nvȟI Ӿ^tLڡF0g8APO7d6tN> wNtl~&cOA: "hpEN]m3D#.(&'aqbt!+[(8WkE 1Yt .G?яo!袋~^xaw}gNQ)4@,,;Ԣ`-STh0 K8@2%Tb_LLǖm(5k_z4:PS%PO:2O 3 |c{]~@$P|dc,BǬ:~aE.) GHhSwi EEQҺ*y qúDTyq|ƼG 1{v{jjiڱcǎ;fs3Eh0 KmN]0c_4(*Zd A7bƷ\DK^RӢCѷԀ.GxHb'u%;]ax\8YVdk6`O ĥM/8xxҐB"N ߀Nrdd YM_}Dx^zo88ņ(V)xp$\RcA\hфuhk8'PlIcWg9Ui |]6TZxk$r31W!S>_(l-H iꐳqĐ<Y:zd x͂M;!<yE?^oanp8j$ eN%+UqO^6#U w0}dHa{l>Ī{Gl"[ΖTC<^?(=X&]KK[Sg@ %7.g?}诋i,$-tl}e0Q \:,vVC+YPVX]l= }'X^;w6 ri=\ K2?g+lߔĵ ERg _P`j ARGɧ?wCcilނ_dC+5g)z{wNI kK7, cfBeE*B$y9zW\a=* pΥsgr[pH3_  ?G}ˮ=tscOrO<=h=Z^3-) DK?밤RX|+ZXxYS;5¼WC+ r%ƫ:aYI_àL v"AiچMQvE⃂ZrDIs y^[HMY`F Ӣa45:]dcp#mڠ`҆eo}T3^|KNr%>.qT-pU]@4)y͓?V}[CAR6cU_5A`%+m|S{>ң ,tyGtq6a|tZyHD kW`.Z^̵-)4SGz<9l,|nRK}Gz¸1j=y*_ocP߶[صT.N.e02}69k]Qvq]}sPՇX>S=ƙ`웼D *N=|> j_wNWB-̩ JdORn) R9< ٸK ǺE \hީCmQoImhܨ?ZZGZߑr{k#sWj@|ZttI8gMpnr65u‰; &K*b,u l訿"wMu?<7pJrטh.%v~~h zp5`aҳ^[ғorWoЏoET/dž{jjJ}z_Lҋqh`kѵ|V-kbI>ŬtcK/1ҽKJ7n{\oK޺NUuIqkq4ŷhezJ;M}6[Zq^ÿQh̎|Hȣs}jeu1Rq{fme+b񇈲%9&J>eL*aȘq zL=L24>%c(YXñ/Y't =*7JH=RVwnL0`?aq̐ޟ67x IDATE ]lcW}šA]JqIS?{N9圑da0+m么!+:^7qi,~w.mBShЃzv@Zh, Rdg=C[b SWm@#PGD0A!GG ax0Bq}'jv)%.ɖ00A^.uhOȶ}an'?>k'W~umuM6{̓LC g Ԃ9Bn&1 .exgv=zλK^Ώ\ 'wCLOH(zچ'W(^P%Qk=uplQ `1X- S -9~iԃIƽ-Hs&wrt+^*泤Yphl%Ga9X'Ew wF0Plg׶[xW$%1yNhx(;)1>e9bWx V'9xG1F*!TovtC$ !EcQ*F$1Yu#ј|J8Z{J6VZ?`IKn5ljXz:=~f^<*PZ, OZc#ʗWoa]˗4R2L>ˤoF=ʳƩ[`Zt;$Ol74nh (-3&? u8nQpfIZx+"7<@3q:pxcAQ|$i RGq &?IV5 \G g= Pn> [ N1YI&*r$[_ҸM#],5׿u5Ol5b5)V zj~=}ehsX3Hs_maS~f) Zli$vh&|Ң+ O!-:YY6-K9h:9@1= ȍH+pU)mu!sI&$<~l<}Dqr[]EwTO=5N x;}weaIpM*'QJs\hDÐ+ q"Y?eim Y$@-ON>XxDgoU1 >) gկs=Z?@0I 9y7xUaoڻ;;wBXN.;:WmCPLNޘhxsAS1 Jf,>:9q\&󙔲A\d<nA9KXX^w (c^NllX߷#[?6ډ4R[IAdU,*8]Dqabc'E@W;N`wRe!8dţ2"'t>;o?kv7q bȒ\h%[L&D:{5AcfA[ްPhzWD5%K;NKoE.ްQgh6^­%ƚ-$c+~`. 0+ h҂G5ZdDHAoM t~vynCo02L*!J xָ4pGt% ט >m}ƼCk~xkr3 vi9^0Ң5(*=(5nTzpYgu~EӅ Դa5}`T%ÂNeԥ 3kVjRA"ɺreB]әiBvOc4@CRE0- RZa$l ٛG}lmn J]G} wz\OEE $NƼG u)#È[$&A:V`S̪$KS3GچkЦqfe7e{WޱHUij&[ \]mȅ)ϙ Z8d1K-:^ 2DdB?TNYnI j@UT\[~niuGQc4/cۀm6yAG|{߿dq׾'niʽh9Z֘J3GN=@4I=]ΤTqzOsթ3ЦO*<D0BDaA k}\}$(Am0M1 Mmw=IV8ݯ+2g#_O }|D'Ml/:Ic$&AkDBP߼i(=+ȿuoUDQ_3sMH:ۿ:0Mt"~UWpHuiʒ 4OR VR›7^{v#' bՖٔBcq!k_FdTCLgu ES6a&mKd8,zr%{s#YĚͬ x&3/b]ee.m`1Н8d\e-vGPGpbxK8f7x҉d9׌iџgђ@ '4ϱSDFѻUl"iB vX5c;©O NI<wR.7ծC't1/ڤd+?m'-@~.p1W7JAm6H dbQ lycV7M#P,)ߑVݷ.ў׶\SqNޢQ_si{qBSYNN3ʠ̠^md>6$ꯗA ?yV>&Z؋ڀbd;o@E Σ;L`@?.Nke]?m̆SFgsa3`Tڎr7]r )K +'oQW&=ٷ៾_K Zs:F aL!Fg6\Ghs~>9%[6V<oooKr8rd2`[bhI͓0䕎}>(bV/l7\n; Oa 0KDuntȩؓ5v~ԞmIZU2koJ|Wbe8 8Xc`!}Ҵ ή38 4)|NH+Nʲ]xᒿ?bo'u$;xqd鐟7-?!KE49:+o^an͸V قwSYΒά[Xѵ#BB= GݐS,mȓ%.wZo9sivK+pqd3zD "sr*gg Pq8dtSHqь}'Z]z* ߊgr_ݓ]ץvLf$'KnƜ⧐Z!.W,JqpQYG,Z>f=e,FHc6CJ"+ߪ(_|)/x/tS+Y_[O.:X*VaT5 Ш"XTR>aVATlG<+R g }gІj,7UmhX$ZB\DȌ6u.] GE7ò wa}lk+ǃ/=/7r3RaXR77=۶R8}x:˖{ 4gzؒㅪlɬds0e"Ez~5/`( .szpOh[?ڋ]V[͋s,Õ7_J dQdHWZ)íl9&3nX0:#hZ8)ǗOPT"dсLI0e3U x&%?a˩z!Gi14 Ȱwۃn%N&Aم p+R!MH?țV:2\$^!Hyc$U5 L>aȋ(e%"+q!Yd@!'5@ҹ|7FwzqYW+k?2GӘגP0$A꼍FR-b_^v4pl5 zj i>,;:M5et=>Lѽ'u㈼W'9uK*\jRL HEa,~;Z!R9qz)cjl6wq[vamǛ}TH:&UyčS 0ӡLkQq]m&P!DfV` &G -kĖðla, OE q"/JΨE@h:AɞbUs2Y߹頡MHM*W_v|Ȟ|bu_ny . _>$LXM0"I@ yShə8h+51_]?7|H$QInHKW($l y$-S?}KZkJ UpHe(* ^m,/3[z?}02!x;{(&ѷ -k/l둜,G@.r'{t[}/<ϻΧU~;@|'=+ ^~kxŻ場z4|6?ڸº||_J 4 %K,8^zժFf HCΠd'O,Qz> " 4@TL'6ёW7? ά@OK \%HfCv_6Cc09 Oo2kZ>F RM_D&J+Zt X(ͺec.,9E4bQůےs$j2->~UED٠;^z2ZjǓz"dvR H6l+xxjo˔EW*F`>2EW,~4Z$(C:oM['U 4 -A|W|ԃQ3r_"%VXhX4J_f3~Qz-!j2akMzS|:Ou5摆$@1ȮVeD@/$chwzhK ClpZsM,N ΃w1tLb#3{FstWTg' S' X%b1cdt+c{`J;aQ8,LN(=ݰ,\7!1l~K@S` AМ:@'e`r6eɉyӥU5\ZR_z1| -(֠ݬ.CFX L߇ 8AynQ|Vb|֣`ӍpjdLؾc-Z/+,E_ ?L/~BS,hU@R ՞ez wKسRNN6 oTNuNXU|:OՔ P̉kzO4N"<}*zcގq4/Z833T,1T蓱 $Mx"Pa"2cLG!ҧP%s4ِ3-]۔U]Ң'<ھ:ԾjIǫAߘxsz (A/hZ<3=QMЯ^ hX#` s=S#dV $4 BE^@ ?E8"AKfů zC.>.4atQӋ^ZӍ[buʶУӨ*'=9`Ղ2vn1[Eq& @rDRq,|VqS^F/VGwۡV.E1̅+^wȧHPDNp( (J{R߄郪GOΜ-*)~XM;&khX3.FI:b:H,*:7F4TC&M A/0EWq* :z!bsܘ-wg*#'Lvl`8Q!؉@C1,)/+\z=hk |NlM'38ܲ/_M;aw'}(BtEt+c_Ciw1ڼ:cnN Hcӛ;gxa78XO.hJ_1|+sYRuObin֔2@R }:6M  IDATֱ+|Csϫci4 Zc9&) Jg$],];{RzBFM(;:=R)8w>~#s_`Of{;00o~sǎ_~{ܳ>~ꫯwxb6}Q{$^ ϔ#ϦQ."J @;NQPKQ2k1ֲeLJ_E uhrvCCO9^~4Dq6/KҸ׿oeee<ѣӛoCm߾{hF`N?pT  ZZ*㤮U$84  H"JV3@P]"cj, 4 :6~o1e߾}mmm;wlׯڹsgEE3\y啷~;qwttt=a7@2HN JGd·z #t#K,6c#ULz]n93ȍv B)ro9*W3Pa'юbzTx$Tv\FEQ|}sckkkSSSmQ⚚BQkkk5s=X,hz8n1%YJ/?ߨؠbl0z/ (ؿo~D \M~Nr9A hN2Z{cjɒ%%%%cEQ}5k,Zjv2pmmmiizٳkk/>ohh MQӆ^G`2jppCTդ`#N:ln0)%)' K;Z|y3?4~0nR:,o;YR` `lhOoZh'LAқfɸr:ua ЧO7 T5O k+`x>*----5k<vڿ V\ /-%Уs L g i1Haşs1X]U]a9=ZOR|dۍg{C U,h!4-?\,&CJ}-;ӋX"٫X˲/dLxl:M}&Cm۶YF8cHF%}Tj dy\Npi33O]Pe] ~ܵASR eWW$~#)s]=?v#ޥ qEI9ҝyg3Cbȧ$NsgN轢|!DyY ~ѣ0+`:~kǤTLV;eNQ4cb ^)Ben*s6%[,$bvW <֞bZ Un F&ZCE,̾|+k, A&IY^(OZ4%9mv9-ݔz%]$ccN.<6뉖 w>nRfG-@&,+V%~{&g/:%25sl UF tIF$`KA~XءfJ\''JY]+v]wo_n81Fз0r`֑y?fy&,a,֙Eh4Og$4Xvf?Z2@twOX˲(jgb dY@a{̀>!^]uNd hkG`[IJ/['ƙ̀Y#hP71&~?4m=3A~:!gf_]rRY &H *F!ɏ }|5u!NV $CUo(26 1i~" 8]B8c :؃ܟuyNA[_ϠӘ(SjJnRwjJh ВAKq:0K!4 5#lZ Fp:^C֢WXH\^AfqC|̔vEԥ՛}g$ X|$JCZ`8CZa'XñaV8#Hx AàO,/o[=pތ *;,=׽>HYP5䘑ToL WDpe ʡusv%Cp8gx8xd}`EHJEY[w~2V6;\4K9u+`K4zRLKYD+YCj V|j$AJwK c^5x „>Y2.Ϗ9qRŢu[4Et \l.]ǒ>'IlVTTC4vnIgucȩ>I1$g ҵD:vu{궆F0_[ S (&tHѮwv߽8s=oN︙=n>Rʋ/]oHSo@KXpYX`a޲qMp,ZtdEpm5K m#p}f \,z"ͯ9pUesiqCK \{ʿݿ|tnO&$(>bWm>2<"I]RKp J 54H13ګ~h }1jǻ_H+] ' \Ӳ ÿf'6y  A4G>Hv%׵r|=鑿x\ߡ$}:Bw oD+6ЭuBpL(cR sd(/r\6(I Ƈ-uϻ}-uNMOOr`Y DoOM++yy5N KXk>3B>v8DxnvBU >G!:)WL S._{ݭ}5;9H8z \O^O:[ ,ht7r9n̻[0~HW5b6p8Va E31b=Ĉa?|Fs  /~3HW<&k@OUD>U1ԏ0Bk՘pd_M X|PJ-Z#`*d@֑ $3]nW[3s9nms$஛e3M@xQpsNå!m9CLj% X:`֑ħfhVJi @k< W$`#a=#~_̸$ WpҍU^>3ĭDa'xW#+2a2[ 7a))AZMةu)4/ +FR*AVb4h 9D\M^c\5U+x˽h8˾~a$dz p֑*(٦ob8L< '*F):%Iq nhh&h 80|E Oi+$FIC%L${!$@z&HnrN1&I*;a42pRTHz\tpwqh tEtyU;+\ axFEI}oOJ'tB+̄ZCM> u@u5>":uAAh]Y.I@m5'sBA )u<@V;tÑ3jYo,$Ca+ %ZG3/pQ*L*B=ܤu$JE"(:TMR(5Qs: `k3l`dӫ! v8Ǘc̀Ő : 1r!fh\-qzV8u bh2aϵA ND+d_p@, 2ä EH?|I0ңqkfh:(aJc% XH MHG77\0C6h8ivY<Ib.A $@֑p DX3JHl,FAjH:185KI>;")8)7HV0&hǙXۃ8q QN~2H f;=jziΰ|^YdX% Xx !FKЀں0eD_#%.I",:Rv3Y 8 Vb!2mE]} @3SGkz^/+Mo̓,u0btz[y`ߋ4m o}7@h'9SHAH댿HS5! 5˂>HU`ZG"NnJ?~ !ƬN5r=f@ L:!bZy" XDE0 bOR} !'gݒ,"΂B C+:1^-4aC0JDu|Ry1 x {Wp^HYd6mzwz\dɺu뀶W^y*77XlY9[nO>dJJ<75;no<=bvMMv8׍,[0DI /70s3fn87Gq53P _@$0[`ﯬO{eggfnΜ9mjjɹ@LB#"Iz]A4%>HB.R IDATsVnkkkKKKsfϞ][~Ҥ!H?AVZ#DXؠ\Z!$ 8 6nܸx⬬Cmٲe剉充k֬y'vڵ 6\^HII)--}7-ZKP !Y`57aIK.=Ns޼yVZtz|ׯ_n]^^3<֜˗;?p۶mk֬.Xta\1 d+T;vht}|fl+˒ JNrcW2 h ,ߠ^ܶm[jjj#3rJؾ 6hO~ ppESeb-b]5$dȗJ Z!$hsG8Ɨ?|@ 4B2sZ0dQ-ae\06b,$G#Kq;0uMB \HdV4 V5999t,!\lQ /G#јuB8%sȐ8B!dnZQQa˟|ɔ#ݻwoݺ۷o-d+UUUƸy?%??n{'M^F7O~{_~e6mzwz\dɺutkgǎwyn۶ѣvALMMMzz_С|P(zZ`A^^18͛7s=?ӷlbm6ҥKx;vTVVr-]_}ٳgϟ?}mɺ#G^ƍW^ze˖Y,݌N7dulr=A݌W7"0(}q…7|̙3WZnN7$G \WW~zrrr*,{&f0'%%4ƤSr-O?ӧ+++4'OlUVvm~;v>;;[7c`_YY4YufϞ][{y@ PRRmHaQRR[ovTmmmicnȊ_ԩS6l۲@Oct=nɒ%*裏YfѢE VUcuaСC6m*((t3:bd8qorʙ3gf7nLLLvzw-ZtR݌N7t4~:5k$''kx(`xW͛gZׯ_ĉ|pҥ[C^b:4KyfU>s;vt…zz>Fw+V6׭[w19o޼e˖-]455N7$ !EXB!$ !,Bh@BIB!$ !,Bh@BIB!$ !,Bh@BIB!$ !,Bh@BIB!$ !,Bh@BIB!$ !,Bh@BIB!$ !,Bh@BIB!$ !,Bh@BIB!)6cB!⎡YBcvthBwBIB!$ !,Bh@BIB!$ !sL@B9/VHB!"$`!bܝ;SI| MCB!O;ݎLul:$!Bz+RB!]ʳB[y ZB)A !avʳBu3RB!4'%h!B"cZ*̵IENDB`sardana-1.2.0/doc/source/_static/macro_input.png0000644000234100017500000003501512174204305023253 0ustar cpascualcpascual00000000000000PNG  IHDR1 sBIT|dtEXtSoftwaregnome-screenshot> IDATxy`?ϙ TPhxzZﳶj֣ZֶPrr+$ȝڝgw}7}f ^8f9cB9~? 47ذ/P(x^|^YYȦfbgM'<`:%\|nSs~h ?nP$ǥQ]WO}o+fr<5|մ# 2FqM2-݅tf9d%}[+y#%Yi^*Zp6X4j쪫 *-cJȡ6Sկ/=}k0&E^7Lg{1W/.;aHnDԗ nMhdacs Ghhn!]dVHI4G EVW웮[yWÛ0.8Ui1Eb:)!"%!݈۾FF7V3'œVHK4"zT`h 1b-2s ֍ToƇLvzZm1,aHT,Z>F+RէB6, ;>!Ci=#D7VUς`zMqs23ZS7 i IS }dHG GddswPޗcc.cwGUD<=+:=j@fzAzvCێ6.m/"Ҵo2b0X&8kN sn tcV_Vx@̴4jZ葝dWo Q'sYx{hRf]s9Saӊpo^ e% e0d=u!d\}>Oa~ڮrӱ͗ۗGs.jZi[*.Hև S)NӫD^܄.i_Zlsn&8їrm'g.̱7?x/ :8G2So粖ӘFDpCʤ.B& ⓕkxL,>=[QjCLuA}S0AJM7$q#{~.7J,4-Hi0OE \JKMe̞ONdx&\k&\o_clX̦` mjy$i`߁JD[>A%%kW⍐A_˝4~Iucq0kUe3-Uķ{{}64 Uk%CZǥgVQ`f6leҭ4d繩n+-ruh4hRmNlI__6kv!®uxG3Z>\nuNRpd ,_nF`**fd$=nuȳ+^Ša׶~B\n9YeEXƈ!NOQfkvЌ4!F䒭%v-$Fv4g_V=d>asX⍞b{#;[DLӯinܬLgض]G7@hnlfYVZrjٰƐ>dP ;ә/֚zu\n$_k5Ǥ ,MܶYgg,s0u:*C]g -U'‰Fvn.%?I쑹uu{).tمM^_oh֣M_Z:{ ;6Ϛ/~=ddeK)xYzIw؊ ]>kh6+3xnwziAʢ> үwG:ӷ@N (4iyB' h$:qš,]ynp{~_4 &3# n`m,*KKK(- 2['@餧6%<>zFݥ,) /D[N7ɶB@eULe第2]g˕6CKK䏏=V(zg4 JIHv\7ns^:K+8 &=PE$w(8u7Vom7. F!,{pH# ǵگ8]6 ~Hmc3ž,ߧT[P(-\x)CP((+)B(+)B(+)B(+)B(+)B(+)B/uUt5Dh 9wEnF0 nP|NQUͼ6HAV3'^2nC BCT5v41ϑ(pB Dg7٦c{pҁ}{<44t*w aw(eD|ZBaVmo`RgS-o]ַG(gAh l  @"[1!DR][O07E?\w ]2S]Đs[ĺ-ؤד[Udz& MX?UJÊ]B?dM$ QY li hF0'4ۋǗ/#퉺2.6L׺! zs#7[xda5NO;;ҥ~wu=˶9dl%d @JiVKwm ]2cL c@Q>5ٺ v\dM⍊CT62nPok68?͡P.p}@9;Zh D̞' gzʹ1Z}JAnL?#J{r!#xwzz{9"ݹ%~01fNE[qdճbEGU.a{} !&'? Π_wmgz[ex?0# _lүgWz>x{] O`zQW%MoNm!>^[ǀliƐ4ף~t@[~kp3SyvF~*!7_NCƭW4SڻEU}+Pt{Q%=IJGꛂ,^=^洶_wcJWk D(ǿ銤O{?Ue(k:-`]¿ЧGUJaIOvLoT$YuWܵ3|k/9{v;WutrF3,bڦ[>iS9ubPI 4AS0ⰢFV೵AH]Kkmk;Ak5hFú?u{~\pom\]ŝ w XxI/ӧ>ilxv쑔Os8 jN x:25ڼΟ~=,Kq+7`c];^6]Y,Xt74Ϸ:j`w:g=1ĖsF28ܕIa Tzgqٻ)^ƃsz37qÿk|~Mi46NQ?>ca:2Mуz[0dܵ>TtN|o+Xl4fv2;~0󠩌8H?6^Ze6p<2ӹOI(982bTo9|(cӣX;80SůU4Y8VPײ81p;&\Z+-s匩FܑMs#jq ;x|;a*#&Ź^>h#01#//'.s,c&LeܑWt[5|u>PF0~|/j@`\rQL7#<Uۚ:ُ ټ ih`сO I"!FW"M5\t!֖P߿`'q?v0"dxٰ.+o8c ፏ78Yυ*NA^_KƍCh#UHOD#AGrŏ#T-90]{Ǚfln}z~;e0-N~9wr߉ExqpsxË\z*胶c un`:=ħ1 Z~\I 9k^3_x% c\0ػ2j?Ϲ~r=a4/*=;n.#n oyb?xkOOs 3~Q~w5 ׌A?r 羘9s䆢zvnDP\&fZ9b8Gi7q5=F` !R0+9x#*:! L.\~|NM&9E"^o1 r/ X3.o1T-cY]:#9#eޛXw 6#EÍY7O* M2 ҿWQG&ʓdŁǧ;ӷW7ŨӇ^1>UA> ̘TJʣ~B{ǰe ev&sD\L[ɢ̓́2}R>w;T)'v,SӁq~>~ }\Ixd -80W~WҀ0^YF8Q}B..t( 'KcUTlԙp _byLs%  E'`1 WGr:{(/ WB6瘞9hc9n6NíIkF'bi6&\'}a:׽0q8׊p^SQ燦{)z*7'Nds"*SܕX貴ɸ%$7c/(55'^}x쨛r9^7\q9S.aqnBwZiԶ./z-b*) ,pvCD^hlNky{,C8W&ؓ(d;{8K[kx]oDͥ/Jw\fνS}PZ~1cs%o۷?;`HҚ̀fdϘǺ^Og;_ i\إ=k;컹v\;-eݣk:}'"1Srϫ:"i y Gf/}S' S*׭ _V5WHmc(*GQ$~7h~c'ӧGhuhu!cܖignj;TG}µ?K_d1j0H7c .[q=g[Cg`) zi u񕦌%X;Bؼ|-uOeStZ  \HĈ{ E6Uxճvi_!aG[BqkMH!;3j+M?g/E?ȶv)D OAIDAT&GÂu5>l=xò16lo=Qk '{\ά}[Ư_Yįu<]8ԩCص aR0t yal-M4FKᐽ=Akj߹S~g.V1KTWH}Ky6_n~}Ȋ3=̄~9`6Vdg$኏lZsCJf%;= E%Rre}x2hnB`Ri^p3 Q6Ek:#%>pK3-g Ewo ">7]N}ˆzCmOO.;gf#& qֹqSWUǔшD"zXL=ިzK So9G_kc:;-0+v_EM#!몕~vP]aLܓAJ.D¥i+%aD_kc "zWvV{ѢHA}.4 !TX=pX +q# џNQ̘p5|?h./PvQQ 4 62s@V+I\\.ͅf]. ih{`"U谀].tB]s n4\1p`x= oF`h> oKC#"A-, )@ӴhﲦrihBZbx5sPtW:=#* \h.nNnΝ5sfbm.mΊ;ؼcu!{4/ YR~ BV5z]抺ZUd$eq4tٟG@hx ;Wf6z$c~'H8D˪%RNϱĨB]"՟/dEv2zn1tIdg5=(㦱wKz",ey i %N۷ホB_V(QV(R%`"QV(R%`"QV(R%`"QV(R%`"QV(R%`"QV(R%`"QV(R%`"QV(R-[uRBP(ҊSBÝߓs4n,>z+7bS!wtv.]ĶOUV[7 lױi~'`Mș谓4~&@0t @h+#e'BhJ E P0J E P0J E P0J E P0J E P0J E P0J E _N$P/0p{hkt]'c*RMsxpvv6 Ɔ6_KC}R1BCAdfe)b]שŪٹFuBףd쵈#ׯ%7/h>j%$y-#=ٸ~-CF%/TpW,Gv&G}ymx0Xq_/qR6AC}ec]tVao1k=PZ;JlXfaa2<]IYHR|> Ǫ선#Z;2I<.]@i~]C͐n'`)eA2Vm[=^MfR8P:R4MkKlt$#0sw x++"@bb2j"l;diu2ۅ%5HE&-[<6xE l6N2VuˊB抭FHMK8#fk^Bby[ȘMۧBI$hcMj 8Z][k>b‚@:,FU#Y̓LJlo-e|xK'2cbcDY;U3ݛ6hV^ EBD+V+r)j<<>:Qv_np' I V:.xvRWܲnmwK}K\;), fa8YǛ?ig^ÝMTMWpWe{AEчqonhHXm{|O'zlD۸z>[r $銊R'U>&m[WVA,J׎"[=& <4.|-[ӏ_<9GgQ9SO;y?1~zb"lzNu1~fَJ")Hg9*!KLRX;>$@mG7w?{3hM_0M6&: Is57-3J`1Cާ{/dJ߹wi@_Lf1y_ͼ'5gph?/BYv9P5S}fNkϽO\v,sj;#l;Aʼnx;"CTN!^i)4/*YlMwGEL7}\[sg:Vr:C͍ xa sk~gBٲUMPvX.!,XKQAt Y'rȤQ86ڲ:ƕ~}C?]4 !Xw> 7<G!~xyK7*.AF[1,rui=Z\Q3$ ;M#ale[_,,G3~ Wj}Oݿȶi~cz [޼>:_m2M,lkfrm3Ҙ;gD[ջ|]6l mǼw``pw@m\:1uҳcYatFpTA\/t7Y9jG T: D;ab+^X9}rFS`˯- i 9ÍN(AFt Պ4b㏥H=A3n}iR  UBb**Pv'[g'XBmfYnrK@d ռa)(G+Nzʭ8ww7^v ugQ#8+juz;<JG~wΉm` n RtbM94 ~݄a55->a,'QC(99浌Ս^0ts2xz1]' 64 )%#naժE% ,((#&I.+V?eNKR^ɺHCOYXMK+uȝ¥gp~'+TEY= ~9={9r.L*߼u9Qdkͅf}Y? kh[hZqc~Ķ ,2i۹q0co?7n\Yr%gϭKAhfB}Ws#r߃r2$aZ\[m``Q㩜?p+rȴb@f _{}=-^' Uѿ:oz^>WrU UvpR!Fctb:1%yϤNùykZ"ٽ:x~w4 Gc׼{_F~+) ZE!X8&.e|2?y8G:RnEO?=vn7#wB7#nGLc̵Ƌ;H;LDB|猟4?-ixc<{{lԗsp0-(}N+LB GY +Jsd]Km$m+-<ya.Gvo+o8BjZWGu'[˴ZڧLwl%?qC"j2Ƃ8}1XM(|c*NXێxhVgنZ!;VD-3c#8+RŞ=Y'|&.v 鈿4M }j:~0aO|pobB@G ýطNckz2kĬL]f],pz3Jvei{ņұLB[ȄֱQ9M^+woNG/3xܱPj>m k4B+Q˲7Wo89gz)>ܮd{5C'S?滢[ H,xs3a?7d_*Qs`ZO|s%{?O\NVvd.0ڗvքFVvU٫}FJIuU9h"G)3GvaU(;_:ײ˥]h?!ɥ_ ܞld9_/X!/(dr<i.2Z6J} .MO:ϷP(\vobHd_IPt{3;oZ:Yy=OB([[y띅WPD9}5xz \voxgG I`IRVb⃏?kDJo!CFIENDB`sardana-1.2.0/doc/source/_static/macro_input_float_title.png0000644000234100017500000003723012174204305025642 0ustar cpascualcpascual00000000000000PNG  IHDR&/s7sBIT|dtEXtSoftwaregnome-screenshot> IDATxw`E?OMBboDgD,p)ݫgRJISvc˳ϓ'$@`w~3 pĘ2vχ(b+t T7׃ N !/ǎ)',"罹jjkEzv׋#%5ٰP! GI*G{lh8#;;k׳!Q0ByU55Bv#c6e7so"i0q77(46ZLXu}4&ؼR| &&oR+Dk]ڕQ'2mԡ{Tͩ4StƪimO`OSɤ0tfr5x벃qLo`~OSUӚd[5E}}iIMT5 )%fTߚ1^ӤlћCa\I~:g]pCd-7W`ljQE]:*yyK$ doB|jf Z 3NCi(a70kq0Mq].RZ eES1z*wF+́<*Uݥ+~D 5۹%ۧЅ|tw{|V@>tzDB7װ<@HO+-Ǹ ֧od^{H'zj56N/LY҇\?|kU̠e 1Sړs Gj?=ubtaor_.]%х٭SオFXʨ>E ];Baذ~]@(b<' ӟIM%L<{D 7N=>EJe[2Յz7n9Rvd.xWHJ%E( 2Jnkx 5*҆tF"MQT{Q LjlF]v6@?r>+UA藜߿y99k”U4Ca*~ d^cկ:q;ރ>8 ݏ>ZA9rek~ztfd&YMwy k46*k4N4ax;BQh1;kYrB\qclrH}M,=I/tkO&QkdyMAoMNJׅ?1t hڹ0<~='9}AfZNݍy-N%e@Kב|.` OwVNF!;EAj 2 `}|.˪)yuz&lL5^R?Xve"=P͒*]O=* 5a-›Cth)Ϛiq)+-mv0v*U|q.wˋl Ӡv;o6H V.O7FR9n{$'%UP ;捏Scќ JuyN"n:B @"q󓝚DNzpEFZ2ғ%nV)^}u/PtQ^\R%}_VvlPVϫc e;w]OJ/?_kOJImC#)M&> EшLQ4.ReqHQ/ zɜ||^#] P˧߈+Yh!i6{g^['8 ^4mL2gr OR EhK744WȒiMr J$3+}v&#ZPȉ{INnOR7t. ̔K@_u hZqEx$rb+o",{Ğo^pcJ+h Dj@-U5$}xݞ"x$S9YitNK$-GzJ" <%$375]6l@7~'V$#iR?q_"qWm6%zp6/_̷$`7oS_,/ܿ`f>iu#{?l1{}fs2Yz ~7<]T)S-Y?c&oM lgs,oDLJq{(BQ|ztͦGl/ُ%@)~2RBlaKu P$Rc5o.2RL{F2]S${!i\לqs>_AIԚ,]Zdu7}ւ$P]ʯ,^K(k~N?!jQisrTFJft>zh&U??=ҧ']:Yt'%hz~c'hɲ8%p VmYf'hj#[jiQUQ5'3- /[X$BrLK!'Mcjq7ֱA4槓D U,PEmXCrHMI$[4y߲u :5Mm뎎7yK-[4Uܞ2#Tu[ gMjZvm=}6WVS^H@&114d2Z|iP '_o8?}~$dC>. W"y]޸?#{).9  >Qq+PHMO'6,lP^?\_B"=:g'BԅIIDDr;,@qHZHSzz*2p=-#p{&11HuwBr ))仼TUu ŅpyeOOlABb" >S(. ;/a~ڰr20.myM# 4/nz.)$7k.M~d۷t kfq-iF7fQ̓ɗPRV&Y%eeFlKFJܾÞd@=Go2ధ)}o Jt~لW/ӓ[ిwΝ(Yt_Te߾_ݍpppE;8t;8t;8t;8t;8t;8t;8t;8t;8t;8t;8t;8t5 kY^dQJiMç\tMu1]XQgd$L$F'zIA Q SU/ְI?^?"FWFfqҨ=4jUJ+|x\u+g3{& +6oc-sֈd}N5qLGmƆ F(B} mcP"WoL)wJ07+rƸf`DŽ$ƒ0G b:ai \) ȃ̗JղAnA߮NeS#e}aɟ/gC¡Cz6IJ¨qV kR%QTi i,Pdv2ar:(m.tU>,EU(MՔWФ!Zj 9Q@slYUٻ+!P;8ĥ͛O/:>Y@XC)f-$PC5ԈoT\\n/_"4GoK߮MF5 щij ʹlb綾$6'+esגBhv[)ىIC{0 ?=eCJIU],]W")3(.zYUR]bfB5={6zu _sPQ4P6Fi/j„= JAzd? :s䇵[uC\Zkn %\2v}I{3MղY-WmU ]RINVemHMk"x$^]Gfs& \TRJʫ薕TWm7Uz9 V5|`3O?)/-4m-J}B_UVG.ye-JW~vPX#J޸JN窨j+UBQ<Tַ:VZ_5 yϯ:f ko[l%tK޹A?!ͽӎ;2yMٔm/Z_EJ`Lp<8ι7Wͱ0޸Cz\Tښ'Oc 9W3S3ed#}ӎ8\1|P%_N<p8Z]qGɰ88avF&Z|U,ɝڛT[ڽdF,Y+zFF%*d8IdM_ʽ iL{'NAbNZ7k?I9([6Q3l.`ɳWrTΙ ug+`tµV|#%=/[Yǂ93S3WZu6uvt^U'{AV>9=Sͤ aѶn%5Ih/Xs>2P-_n8WˊoSVpYHB*>t΢f+|)`Ƒw5Bv+a4_nΈB a[ c.N!5`ztI>wki5  ø^i5\) @[żOz;r:o%7~JdQOx0L*Fw?|VU#쯇1(oKNHl;*= IBPM8'^Ĉdl\.e|r˼*Flc<c9dR!?2$U_klDyw>C/aTj/!yҾDɻ#)}2yl˪/w|]CLی搱͘%|n>qwn欧\#}BSX 'c^`ND~uIrdBՍ/ 6q30溦C;1X&7.f~ÒR/>0~<,v0}W~Kҋz۵]xUaEg/Ի[#Shԟ#F$2gBk1>eQ۸Cy\ag>J@ [h!MtGWl4Z?xd c '$) kIЛBؚ:K&C'P EQuΏTTGX2mu!&Anc&9|k%~B&m|| ﹌h 7*!Bkpu/xta0Z޸.>7g _ge. Ͽ3_aeyIh2uqӌgOq`{&H֪ťZO]F6H~$Ww<DŽٗ3&-NJh2Z?NYZӶ&(v;|h A9SHo.[Ba$q-z$^om#OSs TneU Qa&hϥ{{@({'&.u|<@2Qd(>Fi|CGӥSj9s/R8x0}l2P~FUDǟʝI,zmbZ.t7rJNAOz[|r[qM|o[E$=Ot*pɌwX疓zh2NJ'/Wl vAx3r5OFP@A l}Ct'mC0un ټ8W7yvhh ޞ>>yyTɤsЙ5IW?[FE/==䣆#uyxqV=gҼ m9_ILb/NĖ.qq\=-^|U8SlFv dsԕsEZ/%Yv\9ko^ZH>=GP9$ԕS_p(G䉿>-!(W=ީZAvj)f>o?0Y>:y7s3ЈpyѤ$2n [\@؇d0Y9fȣ[61flv+;<9}E;rIY RO嘬&rX~{^gĭl]/-)t&ϸSo~oN0.q;e|0-~mAڧ[:$0Y9Gߙ UNȤ+9؝P/J5{'n"kFQc| {+ϐ+fR<3LQ7~]u#̬|+SIDATSq'ӵp CvE ;o({6|?Qf.E`E I^ekb~m9n}7jo7'{ZƱ2:.]C+ fg3wl>6R.Te߾}Yj("7GM1^*!Uk6&MI P_[ͰYma+nI' hlZԽ'x㥄}(ޮB!#o~45ې:.>t"(P[z Gwr]Q+vFUNОټ`%_,_˟ d7CDZx@C@- svHR}\`rr)t~kЅ].TBUKR2R\\rP~?ZK6JLJpEѥBm-嘑#蔖(hr)(B=M䊱tp]Ph4UP]USquݲܜPΙ<%e}KoamToBRe0(?Ay蓓{n! /ץŝ[jdfqP tYU2GF髃 ?]bqB5¸oE;)m]h9D^߂3-g]1f Ym3أœeMayXTxn9vp5â1Vsp;8Z#t#t#t#t#t#t#t#t#t#t#t#t#t>jKhJ8BJf~о AqG;kJzVA5/{ToBR75ڃyڝ+շjd;/?؉Ê7E6kYl)#NtRjyA(^NCSl<ş9MV!)On0DjXߊCDEQRZ!6M6i=""ן6f:zt&3^=1<оǒk͡Q]ﺇRn֮]g41>Np8BwphtMoiӦrnA{C3hH~783rܱ|~w,}&/ R)MBcbd%TS\2f lv![o+;=M_L#&9Y@B~wa$ǽ 뮚^ f_b[xu G>>[LP 6v˦20Sک-Y?)%hB[nƷ)iiI PIW41qKZZoUledJr7Բ[m.SQ؊ZI ,E-FSUkP_,G7[֦~&Fj,ihFZm $lf M%USHMCӴRjz_}ezrJtQ.])eSqM;5H [ MS-[vF~W0C=gpc!HS ua%ԟ mSX+Gۙ7w^gol}#jm4օwphӛkRO?CT} NSϸGLގ~3VCɿv!4Z藃SNG1g xq{K{Sy|UL^|uk˵3Qa2jv-ӯ&?O7ƣ_<{^צ9BPםGnbk?sv'noQ9RڝPdvt>>%ʧJ))/+#-#MU[>`/Tv{H6mO;[\AZF&&h؃ 5ڝ /~T՝zlD*@C{;Cjm3s{.4p(E fjS[KCI+ZOj4vT'BzϢ#~Ka6m?~1{oi7_1V#zԛҸ-Mm5eZ¶e[aϗfXJ6%&~[]/pF&Nӂ-ܲ;=E P3;}Ͷ~[+X=5dDgrOq !\7ϞD>e;ު*kߞΈѿ+Q^QӁJy/&@ľfKGDltxnf-+mZqزg=lZʨSNe}vmewRts :yF/"-1E{-o:*1*,fypcYH#/T݌ulYGοY0$nCW\+쟯s3ރQ"g2+3gx.xL1r^5I)1G4}p)%BF{la5إYb,whk]GӗEp+orT8 #|5/]Ι}zof/&y^>n \¼;VHCOqd$U,|~S~P'k=7Kp_̾{^[< 9+P\.^B/x甑mX>"ȝ?S5:?C1[5fKb d=?>{VqɋnH8cux?s;qp.%̆ywq |s&r{x\t3<9u?_ \-˾XHI 82վ=w!,뙜x7dLY/ɛ>;0lf);#ݡ{VBhOb_XQúm'hii/a鬜{ޞRz11]ɴK ⁧%¿h }̃o`m0N(Hy!Ҽ([D`նnayC˛c0̖EDԦ<1-ɿp2V5@Юxփ"'?o T X/ExΈ@#xvvn ˖nzh+LiGoCZn 8i‘:V jRiM5[Rr.ad. B߸wbe9dmoDմH?Xjhoi{YHḡ<uԝؙT!-b }2QT!|rtnJ2qExt bs H-+ē[Ovfk;}te|L2bx)%q'ygIO:4Rj4Us/=p`t/\CTpu.{;_G@Ӭc:+t+ȧWAOzӫg>ݒ"'e^ibcz4vlhMi1 kaK"ai@R+CMC&r1Y^\ZjVָ?*S&r49x8۷ޮ[77==VV$ojs nIcG=nn͚`M6?^ c$\qS?~&?u IR͆e)?ԫ$=ԀDEjjGWBmxnB89;Sg_ɥ42{1i9u\LU8*tO/?d ݙ\:6O#ƭ#İ:V6 aã\f޺lf pp=^|!˦®+W`|>ﻈi*R  @ Hcp+11gxn yorƖuBtCM7vdhrR"r[/0x׹]0gĭsL//;7aM/i_1㑷j u(Ӆ!W̙x:6ZH,|1N?VDhJ MD*;&3y&~<9/3sy v)w]PUdk")3n o硻fSS5i! ȨyQ-(ShFig8j.u1~󯿣d]d!Æv{#;bGӉ.Q]&D*1ZTJD-HGMؼBm,GFߟ7u|1a0\=2 >X>W'ƾf?3o²PE, >xVQШ²5[Tj(Ă~bGԊCŦb.vǣ7!0V"w|7r[QV}%xbm5ڎ,v8"}O"jFIj=iIn3r%ǫ@}9͎E!mƺb/"[IЁ } xCzm+^-9{%`FcoVu#5s=wok"^h%h֑>{̪T-G*fa/25]3zT%SyFu+"2ƶsZ}ft:UUhڅl;}ޢC ~v0C1ԣBd;hE4M*{&Ҵ1bxz=r#=^ّM:[ǣ ] )iѹs]6`GFJIyYi()"=+evViedfe xtX=nzfxQzԴt z4_<XbֻN Tv碵tX+vԲM-.Դ4>ySn༩eQW/ph[\..PpppP`g988o(>(=FxēN888![7so[T}&=5wބ?!,1[7p-w Jљ IDATxw`ڇ{ ! M@@#(^ v`AT*6^[:8=Hƿ1mˆ_~h4;CJtótL<4kB#!6;wBnDtD86rL|>f$a0pRG[gsRIrso9ִh댻4#--se:Z3.u'ql"ީD1Rԍ *>Z36Q$FI-%R.%Bp1W;4 {тW`妻@H;wPKPSYMLD!ߛhR:&aI!cٌp_%͓O0$FK6SKSn^ RIYO#}[ FI30R@Jnu*o9߭9] Bc"뤩RJ {3$Uvg!eV]3g'۵ÿ-&βXf:8zgaĥ`Եzx&: kYI~_:#Bx) uNSyob[uθm CgUwfsc)Ef}[a8$ûƁOHiU SnWyABDSZUCbLTSY. 6JXf~/}齉xtxwͼd߾msq @70M!LD\~Kn-<"2I>pMXSI L3gr2wx*[YQ ;FDFT˲-v^t~$[vRNkR械8ro枇"3&s0cqdg2'KJFZ*iEj7ő#TCN[dθjΠs 's~d9ni'QU\IpKp7Ҿmeݲh6}^6c8:;mm0a8z(j2 o/oQkc_= \&m.XNyTPb+ǜH.qέ26X}ۣ0lpyr'Ə(?WはJ!j","8;l)i圻j)ʣ9.J'iK{cu Y&`-7HB#)ZCi!)10J#4tgO _}?Dώ-12Ą9=y 9sB ťKnjNw]@}]kgfhcl ?Nܤ`PUodڐ;0"(}ݜ+H|H g.a rqYDEF`ЂG>/WSGӾi\ kb55R&/O&an8\ @"1i%FRL$iq"QEkLO\&,DGX ԏܠ0g6&q9Vĥ!vfˎ:k`W#V%:K` &NtDmji47qxהKRp- ;*Y2ct$}GrŹNei0[:@_؇&" O[>$l7 t&*͜@FNx`"g5QJ_udHNc7kۧfbsABb !l"W٣f #6nEό^2l_.;`uj&H#pUNtʬ#Xy||bvV=E.!pQRVAd h:_,$%&OZb,mb#A%-$(ݱleέY^m" seT.yW6M@An:d>3 kݲipx,[nҧ)=Ż.g2sI4 ogٯ@4'=W.cOqR[ ]v2/Oa@)<{3ӴVwWڄtΤ}JS\ .VmŪ*F|L$ J+p\D|k]B1MzB4H#ʢ }3|ݼt#yޑm/ŕ:Qa|y|*Ϭ9]2%G\͊?wm. Iq'E^Oc0t;%Wر:B0[H!=ފc_ Jkvy7BLf ѤlWf{[aGf1ZYƺ]eT &"ma-}l/!iMJ`caoI%%Unݓ%ĄXp}_N?I3KzlZ6w {)A3 6Ldt Z%kʦ]yu9,fKHu* T"Hj3~l%hDSm"5Lhői - L&,Zy loH3Mt%=2Gl4(Q݄2Ői Xh&V}fKDD8 L& *:Lr{B3!LV2RCl ] <"8LDEoY98wEfq_A>Mqp31Mb#1FbCQ4+ V\7/Q148tV0H kllkk`h \NpXx$sp0WP1C7[y;Y{( Ł>e?~"iSbT(n߮Ei@.LSBufeʸFb+ _Gie56,ˣP(u(ڳޣFb E@Bh(R(%V UJP X)V+B*PbP(ZJ E@Bh(R(%V UJP dbHغ͆'WO+f"%Dnm-t7*[T*|c5nqNFB"a%j5AMYeU|j;#:qJp" B8ZSĪn`Ew非9fPUcPi+q]?+bY#3!qظw?S0(3EeSXBm5c)=lv]NjvhBuS"KD42cNgbnz+2$(+!~9O&TtKHiR WdkbI*IyNiY%%IѼbsxLʟPմH?]!n3tn=8H<B`8j*p٫]v f`2["EƢ- o.ٰY^\R4!)#f7^#s;G^5N!RJ@ !0tI|"$#z{f7:iCJIYE^Ē_wn"2 h/Tjy·kvds9:O~+G&VvW/东,vPew{G$ 0Hݍ^52w:BF\T=p|rX%6wK$RBŞ}~Sd}# Ssf~,}Xt Ev|^*!%&g)]16_^o)qi_8FHB<بhCo VQH2IJ`Y! OmCS(G`/w2:$CޮaHoOu o?frװnw9o|G߈ݩuHAt2jRv~ ]qh Y%Mh n߯E]T[C;j.n28KYll/F[[B>{`[(obg}c(=ߤHvѱü; qPV-V[[LZb,A"%QG9&F\#>WEub"muE²RcEF F ?6)㐲3ٹr)KT5c#.2li[GyJS=iGtC=&@[;s͜36ލ;Xm."2XW˷u ϝ ^tiWQYGjTp^vnDZ1&(k˾/╝pqld-蒒/X-dF)i+:hadf}r8#ҕ/saD:u0r%wx {,>lo;ˈ ډ!%B2ȱ.y֯2;mcbʫ\jF}V<`GDRV$&:vѹMD#oW_^˪.NzyYnސMNWz^Za`܌h69<>E@mW{G^#צ O⳻)4J }˲b^O7tk;bi0W}K8`LDd2[W[쿼{z:Nؖ]DSe]?cdn^j3kw-Ek)şϾJW7MÐ!yW݄X՟,us.gc1V`ŇYol:-Q1pFif[8ុ r(Cg z"tk e=3p(`yA^ǹ_'OcNfz+z!}FƜz }1~W;kZ0W9wluA/緷gS(O'@*Zި]o1)ܶ}v9s,Oʏ p7q8oW8? f1.y;l[E=^:1#s5ә>DɪU-ƔqС W@}׮z/ ~^&/4x"/>}rċ @9l`J:vHҍax&GXWA gl#=?UpHhc[TYKIMRM'D`?;Iзw8wIN\֏D/LǏng@Fbs6s"Q:{~X/=aO(ϜADZ67?qƼih%{(l(`틓.(w3w i :p?"̘ [v2\wpEh,tlͩSxC+KGku0WMfv6V'b]RV}=Үdĺ*]1;olly5Y0l6,{0ᒹ,TCT/cr%~+ۧcMHBDbwyo{ѝswnoܳ8ɬ'PLώl]1L;9l*va6k8n O囹.@H +NRx{}2RDw978mvy죵_GRUPyNJY&cMNfZW_,>nśw.,}SB*>HNA LŒ˾-؈6SyĶ.ey8)%[M:!zyeD1pq ΍DsuvǴgC;f3elm[gλu_iecc0ǏFsϿq $RGX|<~}bv d2f_"QM2Q?\p@ jRߵѹFN(wt$) 7t yüxzJep͇xEN`gC bwrsn;<9lr>S`&vXzx˯ҥѻ\΀0aFǥk\Ϙ“"-K#~\̫,`~\э:/5-2c1+XɱMrtj& gm #kvK wb)40ـаU>nFi]z}q۹=;*Nc7E-'n9ϗqAJp|+y#8qB{Ϟ5NRceBaY\nAbQ۲H佢.閎å3 Uw.ˍ 0aIʨ/E_"5Iq񀧹c"b+5oaWژ,&Z$OGulaiľ44ņ@B8Pmw [k@ |U{Њ9>7ſl'49dM|W mDA\A8ih< gjq78l7ɇpqMvΫmNM|WEЯZytՋ(M [0=]?*!&P.?Ƨ1i dv#Ӌz\E}9u8.~{R XXG3Lۓw&"HtDPn0+8_UTgi]q<Lrvo@Xp^ȧ'?jJ+aomIBD,b7sVc{ CMȲ{Y3 ޺5Tw؉3 ldm% XL[ɠrNiazU9t _S>:vIKCj% ,V&]6< z9wD̦{C,/♻yLYbo1jڝ\pl^} TMéjz>.3@msNG/Kmm(F Oœ7p'udN=Fh|N۸!'i5VG!rI?p֜y׸k#ƹ̏{'aJdx:1%O0lO3_1Ǒ=Ci _O!¹oYGU ڐ̥o)mK)Z_>\ "=kOCbcҟ~!oCJ୥|cɔV:=㛾Au_΢λv0iќ1<>'/oo4aqQV0g<wS{Y$)}#O_p nn-aw|;m"< 5!%)x(4tzsFXڗϨ.1\}b Eٺ BH1^V- OlItC⨩j_>5e%\NxX ҽa|_ P(ecxv+Ly;~'{Ȍ=0F{; Ks LN߼YY-1*1-=YP4XI)l.y ,QX43N4*$\ ʊeu!؏3?`+07dD+PGpf6᪩|?W??KPBuM̍P^0ĤS{s|b߭ݍ.l곒:BݎYFLHD4(a2ihBXXABy sؓB= 50$ hʓzs^l;X%)vSn%#)HsZǂk-y5i&O7T tYf,L&4,MO zFJxgp>w'iJ)eI)G'IaXxO  G`i^'߁w) ߁ɘ֎O|.^'ADIҢb>Q ESQB*PbP(ZJ E@Bh(R(%V UJP X)V+B*PbP(ZJ E@Bh(R(%V U"hunR4.e lA3]SbL|?V_D3 šSދM/ :6=r]-X?%V̈́z ЦqZ/0xcP/ `l^~+REJ׾B9WGqaX[v}RA^ -,*@R*Jb>4 JMӐRc-¼xuBx+ٳg_] A*לncObڭ71޻%pJHGJ$؏ԙ/gՐn}<ũĬ~gFN5G>ʵKeٖv%3&U蚈Q8־8+ߎirwj9߾8{' 2ߟ@[%^MA5̼/|>LǏnggJł "-Փ[a}9v*-h h'5H$XVkfl@It>[1p!]q!BTPZN=䵙ypY{F_7ǯx;HoiHwo%#xl{ɧy#خem+?\ }:^t?\3o26 ۶~w7xQrll dP<^5nq0g{Xr{uiT1ɗwM~NJ/-z"gߟ [pʮ˩,GdB3kM0 ݍuMuEӎ8ჲчv{b,Κ0@0~b K3 {0 Z6hc&[7 F;ZplteSgg(=%L%kmؖP2Va$3ǧYQbi=r7_ sLx=+1h6!%Gca{5axTI_ 4f^~7 [⡲$0B cܹ]=BXw&C=%ϢVET볮jw 0S{;ɱh}r]3aFn:VFN l}aKV#l]M~u{&^zY~fݾ^iކvwKΝ]lQ4?ǹH:ڥHix|W~:4V ܆a& ~?13{? V^Oߡ-6x2>\&7=Ǜpm`##q#yt0/d&3::<^pàj_5:sHk8Lv̹%+K%n3ORb&l Է=}o[WHB{`YnY5 yt fJt>g* .cZ2mRDs9i<{%,I(g׆5Ȝgx'R&D!fiLxc7+7a5l+ȹ",)fc⹼{]"JF06s=h`cOJǏK'y:;/;c9/T>_w.:lw^Jٛ?8!> ЂD0 }KKt{|]ٙHNz3MԙYxi2jb?g /oR\XIeEn t fwfrK:8Rx( ?2?aO?,@Q9&Ǩiwry)8S6)љk]; aw]^Oc<I\e)_|Q4Zx>bXU49sCdf~w2n򏖳},}{702vǟNgͯ;>EE t\/m]}pTS{Ĩ.(E&O_pfb<3{~_}E})7>#i85u'q>UC8lYO(23ҹxm[DEF2}df{dzYhxFt C'3ӧDJdǑvwu,y"p_]!# >O>r??}(FUs}fKnjcEᙢ ))gQժ !4, m(\6})R4+&~FJIaA zhL goߓ껁!]Bbg .G ?'ĪL&LRN8M3u_Q5tDb:.GQ@Pbլnzu(G jBh(R(%V UJP X)V+B*PbP(ZJ E@Bh(R(%V UJP X)V+B*PiP/;d4aѴ7Ju\.qtDLX,L.JZ1SYQm[(/;?!}V',])+ukWRBDvbbcZXb.7;m!.>>h_ԫ票zOj/jawNvnB^Xm7 ņukI_?[^jQ%x=0&|{[U_|ϣ  e#kOMz_ᄎYN~ߛ."h;kH݊R4!Q}VNx(᱐/=jpρJA;ګG Bx{o[+] .0wK^cNWv.s0i]Z 7xvV+FP_tvF*_>K_SU?B44_KyV?輺X2!..} 䉜?u.p0! !%#v7y;m <[9ZPkZh9lWZy{ )_)ut(h@]>?2a@߿pUkxr%<>_:dǦ_Q4 O,«j:P@߉a/zU~+ < ᷤ})"ت>˅zGp!Uky똻9aR0mgšr/;? sxXA7F}ej9 O.Z5|VkBE{ GeYj~{v[ƕ A1 _y:&>#{u 6am̀;NmbOQMg2V_wU`I9r{ppxoPb!-Tn|`tD<$@xǂIЈ"$~@Tk>ۑx[}@u|7< w@<BV9IHoQN 3xg9Ksk\ znsV{AY`!T.(g`wj;;Cxd ZO_.O *8>&g;x||2?={ .)6*Y \ŬڬR1w^1_BD~g28>Ê~R&P)qSqU1( \;#u?,pʲ: rp@ ]C=! !pUާV{5No=ie ,>ش<};d^z|{}~d q ݰJ6q|ţsrz2]c^_'ӷ]tqTcuM$亶Wcv[%~zRh[U" Lz_Ο;=k w VϊCKZ|Ȏ59>V?ŅU<= aU_֋:ץ,%yShX 4 IDAT܎&umX-]Uaw߀E644)I)0 B$ _#/| 6EauԎn40 0t'E)uܻM8 " $B)N=wJݡW" U__q  X|GJIY|KT.OKxcCcҠf26l.lՅ잽XS C.\6t08 ÿSt0װqԬL:fucV&;dhR1)qW?Ԫp];}ax . ē::㵎t@gsT~"B þ\:0?8xfd2RO}}y[_}B5൶ݻu^jde,o\c8vږm(B X (X`!(-gԄDT5*kRJ "~P@WӀHE؝뇙-nօ;wus{wG@P7aJ;be٨qTv+?jˆoamȞ2#nF\*bL[A; gn><؊AwbjX,q3ڶs+k?j@k4L/D8r q覎ֵ8irDK4@l$i^Krn Cx"Xio D#a;&`@f=VNJgWc@ZϧڋIn(%>rl, ks' rV&p؝hU;|Qہ[P&v~HGAg]+ח|&AWL˔Tѫt`WcqTU5[T ra4$$ftѹ**͸˶ٗ)AWlMΊ \-j3 *'w{`oۍ \uܵ_9Qy0[A Q,z[̈>Pχ-ܝkc}z rV):p45|Vg˘KRU/1. `]T̓FUv"Z gc+Fe﫫^𨅤a:R o~ ?3sZ[`8BQj".LTky1R4oHITX1x0Ҽ׋ҲH 1>R6^G5^Y0 99()FodFn@od1 O/$IɁ""% gEDJ@Ί :\ 1222p, u Ũoz i,[p7DqUKB΍ ziVcw^"-8 IDATxw`V?+{A!!a -*j[W]U{kNpZ֟:XnTD@2w{;yC% 7w{s<98|h .>[9q28z~^7޽ .PUP8 >,&}qŤ%%QS[CMu 55".\pHHg݆lߟ.`  SSׅ⻵k׮n#"o < UTtq5L쳕W.eu:B@G7a']qGWNjJ>}6Vz"u8|7O kOҵ9)sak |2R짤SY]Ϊ=>CdR6S֧7ݔ}COމsi}'L?-Yrٝ!{7¾SPC3j:DFuΏ_}8ft)t5Aҫ o܀&Bª!=%uxIH$ƭ{ި#ߗ Գ57AV[t[يؿMUɂ=SIU":_{ɲT) kzmU5W0,?V;/X@4r3JIPT>£(BF@Z&p-BlݸR>]z2Rw+{EVuޞH:B=9X+QI' _f:B@y, u۩ra$v!$% fʭI^RJ4]oD,X3S2A79GOj|&/=<+tǭ.w^:|O4d>39rʖ{ 7<}OF9$ytjzx^r g=t7|͂g`geRL[oNL YL)'7+ VQ|_x- ?u ׾w7Ckz1v*?6|EYjNTqUjAբXg& +VǸzn۶nꨬk/ه`1 iT54OM۽I O 'є|r&x7eIyS) 4kf~i]tcbN v-/hd>FoW8qTT ?^-ɫq̤oeIEmEuG~\ب;]~tۄvc8#.af4Ok!\ozo ֕=H-Џ=u%ܟ43"Qy-Ň7aûOP|{ʴtGoa2Ό%~l&$%-5L(C_5n~OAt%  "ټ`$g6.I<~?܊TS v{grY X a#@- >Qߏq8+YT#5QQz=Ùqo~ +YCzq8zl^ʖȆ,ߝ+uE7-$_z͡OveIЊrkOx/}o !>?f7Qʘq_k\85)ۥF~=983oﻇaΨ *uj4FŇs_œKn.d'|f~=+WjU 6q?ǖss# 9 tکY73De&O"|)L վ^zCMbg1)k6p"WװP$BvF*)I{V &޻6mab" U/)SAKJ~.NRe\H/x!o\Ž D44^X\|ךekߟc.^ɖ*c㮓jII"?;쌸g3HKM&iYS);zL7)))4c7ܓ%>x|dҒpxt71EVx[fӂ.iMane$a¼K,[rR%ee4>EQRVfΖ)mL?e+ګ V70򻥑~co%~$Q*_Ǎ[wJ e_ e ܂NO*=NK4B'LwOH(_(^ߒ@:ӑ ts&?؛nm .%*kve_Qvž .Zm[6p7#.\4 .\t`v% .]p EK`.:0\pс؅ .\t`v% .]'{P,Rڸzdx>f{s.\?%ZW3MIcpTƧI{Aԩ TՇPUu5lr`$LԦ$p◅ :/.MAFuzQנS(!EK/ yU(bhVmlgBAgI#-\ h]|Vмf߇ڠΦ0 B! K$jcBAn&Ey|K*IL*hGp?^#K.m*G-uUiW)LB]rhܪQGRݠQY M߮鼲d?l r;1p ^AêTpȈlrs-!MucSMgU<ӤýSRY-˺J2ª*_85M3;?m*.M2:65C %*O[ۿv 7]PNe܀nRCHQ@"PHiRHPC `=Z$*_ @j&ghi]a|\X΅S[o {T[C4/?B I+@$;K"9pd>C ӷg6TՅغ뷱 zHk*Kjݿm`j h~C.:..B6oo.=ƖR:LRSjJ8LٷPBҒJKbha7N8h(?X/'ܒ^#l!3'sct^*iIXΏ=F>+#{&mAs'R WrOL"G?lcj"d/v5vXicѧ[&wOJ6H*HFr*}e\0J {:k#RG7\]xͬZMVlUÚn`.zB_?]oGIYE!o'[6 * Ht&W㋢>UׅXz[,cMY /_ԑ +*ݳywYŞH m&&?+%zq%R9ғ +o[wƄhL\=J~)%U o_[{Gh+fy9 -q׳E,\Sf.#5.:CdC |65i:Mņ wqa#(Bڊwmm5gHexr1toy-BmBLkYLh}5.BGX?NN~c'3bL~tU;n"=50 BHG4 QZ{f_\Au}F]@$TϴQb}{,ot`9;$0),Xŀn΋ >|㜼֣I ~?y37z9GuMYdV4ΫsHכy,TekC藩3;!Y%.c® $'~Su[Z%K^:c3o湥U]n|~ =1VMu_2z Tmϰ/㽝uw^QΨ:0_ptF#⏯VG*_!LeɌ<4.|K*8?8sz:]sCg̏s.9z\4POp.`@2CoRBx5@g?'4(C G@z-sCW|s<_s S))zZrGk.c{fsiJ&<ռ?qnK^͈Hg|U~z{@d%$:IN԰o){.w_?@z47#o< }-?wkO=!HJd \vdj ef0kyO8:7֗v6>׫RUtf` !R0 +i1` qBgPR&}>\YˉR) ʄmB'1Jl;}4]tic"|!Ǟ:)$ }QBdX>OƷcue{g0S2 X~0 KXywl~W;;O|ӆ@ i'0mJ&rE/ǿƓ4! }Rn>6X]FitG"(1†GU{NOh vqJqgqߨ*ztOsʴTTXaM#DG'9<LxH g2nr> ptBk~4JaGkhЫ}60s֯X߽Klngg4] -Pd\.u,'Lfh6i2z 5lR#(/fYË3-"u0IEZ&4dΛNd JLnJgiǁD%6ot"lLBG# j$"(5/ڲ&tXRh5x3bd1Ⱦ-qtg}C~X?wç1o}_|Ɯ߼Q診1,Ⱥ׸gY5,o<~9swM‹FD &70~ؿ[˺{JnOby3:{7㌧W`0Seuۜ6"DTZ1$mO{øy"׿ eU 1nb&p2LjPDŻVF?_/ތGEx#o8=|^ ΀ xy<>=xX/6m8hn5rR<wQ(L>cV;f-[ /BwoKeJ(d'AݎƕBSek<{|K_~!㕯 EMDhs =G}0"ŵ}A mWB"Z=xD|JG*`k\Ki {!R|ܟgs+2$YyzK!=MAqS;{Q<Ƴsѝ$i5Y5ҎI~j)k[Ip<9cuz_fګm_y9[zp֝)ʦURQIDAT`/3F m.g*ӟk!#t8opniM68/'ʆ GhE\_%g7^9,XYnފ|sXQ$u er㼐'}^.(Cpӗq@%=9uU_丁q>{Sta7=9+1O  [1d;rȹ֫yxTk\TluWP6Ŵ\A8'S~?GopDCy~ <EE+VRs t_$aOְj7E11hÚzkި.dTCϲ(aٜ07{bƅ=B`)%Zę/9 %jh( 3y肣':cG$:''$댔" 4TwǢ]h\|T1e 05]M3&[H Ueb} id.\DXZ5 M3vR<;_\W6ҵ7Xuvj`Cog*j5Fؑ4PS)s?"G"QWm뺱E^]Q5̶7fVRrӠiHKI` y;g&3(pd @<,lyPW]!ב,!:N"d X; ^>}w +6*A6AM>)ɘA^/B~G[N"ײ.\tt_Z;~4Ҩ+_+$RWe5PCkڝUB-_ǘ 9v ~;/("PbLE<~0mᙏVPRc/@. ;=:᚝p2ػ8 cJQp.:'v (5txBC㧅S1oW^]܈') P<~{I6. RjPCL-ƒ1:GxP̳ǣ e/.؅&ǃ@ 4,t6еB ! ^!8hXGCnf*ˊǣ*مΊ6O0"GWA#t ճYӆd'?lƊټ}'Ua{d?}3 a}r+дBZףx ^պБ_L,K(:^鱷Gױsѡ22H*oKJ  sh}.%s=3Ô}9]aB*AvAĜ/n0XIIluLe w@,v.:kDxP/;RM3o5gJ`\u]եΝٸn $.THW,KFce7Wj ^umď?|֥NMuEţ-/lͮ|(]Dd绋^ylްn]ר^aEYHR I"@hYc#B&Ǟ(Ú w JHژ1dlTҚ IHM3ұ U|?qkw (-2ݑp&p%a9~ħ+Z 0^y' fmGm'LSEp8&&}$b%pncQ:e"_m e>DTqdje@k]DզĹkab!cNΰz/.~QE2si\q_= GAjDXE;!Q4嘫x iZ(Hb"'cՆ5#+$1iqf`E1N +֪-J~p̾@nDvۊ"p5h*`5*S6Nڢ(҉-L+,7v)bXCҨ|eh|SDm@%pTa95U`F7 S50\ھӮ™f)w9ڎQ-Qm0}[,- k入lsxaV8%>ZV~ǙԶФQK#=V@>Ǚ5!υnۆ-{&fY0 0NIADo:W)(q; Fx*8ݙ͌J3eli\[XT,#@֛P8%wcl+|U;8c  Ň+0Bxry J ޼1eWn␽=ܕR0){ӽPTvTe"2MtZ lY.ƵU+JGaQto(XYgɣ+3St৯d[؃"6vlf$Ү3_ ƎZ}a#>a:vvIv61>"5ڪ4N', Cnf:B 0gu|EuIJmjJ)2V pVnXb$S2΢)]ã+{qs݄ 08t}_Ĭ?}z N?̺{/B7/W?e[ !Np7rڰ4$hU,yn{T~ij\3*m,{w05H.*N ])@NFbT!D(Z!mWVA4L׎e"[FUf9o(~T@nVD+ bfQ8ӍH-;=پjvf{ؚY[~`U?XO#pg;'5MN Bo<MN}=/~btg9o4M.PG&Wd-gxK=<&AAB Ilq潴$9 qC:XWW`k/[␳ g%`k_%%g;O,GO-]3p<*afFӁiKw<"$H.){hRزsKfQ6Y4 ikw vZQ Z36~,fᓎEʔaPy:㧹r=iC ޥ耧z&[*#~O,&LO.YڰƖ$nm@me,yWQGo[.Dedk3{tYcQsϖGQ-v?׺my:V?{?)<*=>8ַNcGi+Bwbvj{QX$rZvBdg"C)# %AW}-\~Kq-^4ªT5tjERJ́=UR $f d`%,05UPw@l$O'hhcYmbSfVOV}w;Btvկ_& hFIOg]WpK!n:0OT hQ+͍4q(y͈m`-T̑2*P)%NH_PcnY4ղ^p HѰ 4 kyft<݊ O6jJ_a35Ji .+|YZ)x?bsSDISҔᏩEfTrL.⌣rI[QfU\.S9k|& wӣ<<]+ yVX celӸ1ŽAu{ݞaÄcN>3lLjf|z56egEfPp&W+&gxїH( RJX[ kqX3 iYޜ<.=I+a5h0t9r6'O#uU8d(΂O?`VjZ5|ʍߖH%a7: MHGg.L΍Qͺ{{$1ܫ8+ysYyt[8󘚩!5Ռ "ipu?fQM4qujUdlK'&/ Fv8tZ۵? &sƋ%FsR"&r2ቧxWJTt-Èxrnz)x;@ 7 RƵ ~(?[Lk9<5^BKasKO烛7fE$I vp:j*[*lETHbNtu%ݬA7f/Y^+vۓ`oF/{-d10b&xDIƼi~7e GN,/jiU5}˘ HJJN:>z2f~圜*L JS '_ᐟ7[aK(^"vWv]/V4e*&[E",;+RRR[{ضe^yS')vuhwuMkke<7-hHuŤ69ڄX?m;XQfBvw04%I)L';9ΊhN*&GwH\4 鈿4M _M[5M ̡ l!́{f)8 dQݞ}w4zi=i*xb Ӛ1f+ٕ-h+E{B!\cG-dlpTKC:E0f~ݢ`: Jxiƿq{{f`WԴv%jisqGlq_zl<̳]: jNا qƶC͂uegmQ  =n !uIDMhJԼil<دqǙ׉ʎltǠ-u"t:+B!=#2uۂ%CJIyY(!KW6ף[*\.\VNNͮ^l\_5/B22S"(V̏?|ϧz7 k.Cs!-=AEݝڀxdݝwg8(]Yx<*x. :\h.~p EK`.:0\pс@k}pᢽ@ (Eti.:5,@`_Ņ -̾vut2N.\ ؓW6E{˵$%… ;ʷpG KP6u|{j{.\o|IN 5͝E{/n".kahIENDB`sardana-1.2.0/doc/source/_static/macro_input_moveable.png0000644000234100017500000004103612174204305025125 0ustar cpascualcpascual00000000000000PNG  IHDR1 sBIT|dtEXtSoftwaregnome-screenshot> IDATxw`E?OKo$Jh);Sv={?l{W{-wEPRHHO;[}$~ty33of =T6a?mnʱczpݱ2p@0 }_d $QS[CMu 55"6^/>d6O],a#N_OM#\=Z=!=o )o? 7@0R(/~Le+g\ϲ݌ǝŀS.#F)#pJJ_oLV,]I&ҭSV`k_ $9KQMAy䘁yTVWSQUj y z F*E,u3%]:^H|?N,Mlv[^~_4)m8{&%/=2SGTs `XvsMxI^P­x;%hpx3fjwy7es!n*SJ8;SQ/3RBXJ}[U U m>5FqDJPD( aUן>(-f_R*t=Bjl-,oϣ:l(ƪimW+N˘2j]dVIMFH4H@LFH)Q5*l {ӷ.6EmOMJliH)4$u~IE $p=cRڗۍwľ>p?8"q_? q<FLEi(bzBMƸq4 ˙5WvTlR[Kxp%,5\9,bKw%<9?=Ĺ4jW<>LLН/a|_џ S9-K^aEd<ʋ'>*uc'ZC@7gxlIzg]p"ze,gZd$ևU#霓d9z7Z֤݋h@XjV#l ckgnҩf* oRY^K<悍Q~?IT5^_T wv@"Oc5T+]5c{D|Gܛ׳4@+>Ael1o~gŪR䶻ahnnx3$ڙKNN2=ÓriT_Hw/. m_wbTVο]6J{ǬFUQc`UnwBaT@(b<{} n䓿OcJ^wN" rMώyxjFNw N5J6snDJx/5 ^])$ŵ!B;H_[HN$>oϰs'ڥ5v* FRV+wWP&;Eo1ͅғϹttQPK+"Q(/.)2JThG qxBe1dQgWMaP<&^.e$0챔UT!3+řO{X+eLp'݋݅]fg2,ГӦT_sǗ$uOWlCQv)@B#sﳲ*җ^dYw1(R86HMF7HVAڔ7iK3L!H0q>ҁp=ey)5.>Grቝu :\@.zOH:teXw21![rI}-vt}dQB/ mVYX>.tLzԩD,}9i9,`o C$֨ 7QxsHI,9ZZN /(qĻ|77Iaj Mzj>-i\+oK4Ǧ2+h}ٺ6Ȧ,Z^||;8_}RJj$'4޷O_Grx!v%d%8cvʫ&l|ZνߔǍ䊗ļdRb[ Dh++7 ⫎g@Lzl\&?i,˥vZH;82)ż|R d?))@lfwxZ̪BZs: kGL椓f2Fw\D ׅ75<^~B tcl~J`3[JWխjwf .V=߳n!6{݊= l)ކ?BjIU5$=-ƳW z @GΞ3>XwY3w!%aP5ԩ~̋gtՁ Pε:W&j-1%?|yk&LpQ\e%q>\nw%-ō[Ѩ4U+DIUܤzͼ9E5zGleҭժ$ŕ".XɖF%SjIH Y|f;kKqq){/-1A3WwegYۻegYw17JOn7yѓY||A ԇtT##5a6l6Ip}$'苣cRk˩Cf4r2pX_T _*@5FőH\ 5Z?R$&'K344Vzf"p yMHWZ PH"%)8T?5*BQp{HM!'K`{)]asaAU߉%)!$D=eXYO@>-;J7uME‰,Z01n}?ªM,Kp(GmX6ׅ%'e MzKW1 "'е};yt k6%HAU 6P^gb8œ[hW5^[\âM~đxkШ+x\u+tH !Vm-%sFl~wU?'t֯,HCE&ߊJ$jko >nYI2.Ǧ2Qq]wpX<1;n߶ KKHaWF^eMjԐT7T;=3ً7?K ~4i)j NymkQ5 MӿwJ7*aMڦJ[xM>fŦ׆84;*OK79huy1eXn6TSZ@UKE6qlIU[޳!:v.sKѫ=+k(B (g)Z(H5G+../_b*ۣRkk]]Xf +eƄ}J-*VWugMQ A !RJKB4UR[QLfdG$RRU`jVlƼ waW3ì-eh|ykkpp8Ph5WU^ZPl.o6fgigj }JAZRiIqmIՒ r<A(DW?Ėa:ܼ I$)ιVpj~fJV?dćvDO m,XMuCDz1&[{Х}*wWBlEOJ|"]ڧR.бNaU&2(,Gj4m/o7jk5E \s {U+\.8nt#^#>MFՓۡ߬:_*/O!LC0~k+"Q"} xh˺f}T:wkBJ![v:YV2j% x>wZɢ7ϋ?p1WY X2:K&\ԴFB_IIi\,[+JI5Ҫ:K+k7pYM&XŬ3diӸ:Z9gλK+?? 77&{,%u$y@6+E YUZdžAUZv*5Vՠ;Fj!E!a}Y_эe|^r /[XISvL7~Єݜ~Tc8l=*㨪ƌycť^ϗs+6ScCFMimUARXZXih~j}* zb%~kc-K `p yGNgssHЍ^?ekre-|@eS qͱ6kvQE~am/ײ|SeUGƠth&4v?L|_6Uy'mrk>ݟ XG4ղv6#m*cae -eG-?!aL8sz:\5{%Jv+ӏ:eٷ*1Ӭ1GquP߽p#'~GƔs+a6ι)Oq r3YHY*<ʙGJ0aLmfT/ve<F3&Y`dddBf.#kj!|$Ʉ1[d+1K0"BYWx^xs?<}bzx,G2{3,Ι(5x`̓I°iA%|u«oOrxy6 O}֡ܗs?r#I9?Y&(xz"̅O?)8 {|޻U^+gCu 1DH0o1sAN<j?w+Zh;0~uMӣvbD$gl7k"c>}I}C~r W/@y=㚍ۡU/cM QDwj,n2s_NE@B_&rݥ ʺ`*Ducd^WCcII CxAOYSQK!ȿ=:4<|2=1߮F+ o]Zo%ܲ( 7p4es=s``"'K&D ab[c |_ ``EP\MoĶHx%z&ATMCo՚2>!3&u4-?_\F7?8ܨJ^jhFV\1 5n CNwQJ #O/?c(SQcmO0sgnÌ_5o!ߚɛ_ F)#poicI(aP6Ō0ډ4Ѥ 1wNy9B*7*xmqݝBq[<9㘜}.$1tD5a]Rkv(wVkOv_gh&Czn-<:l&8Dw O5x{ @!cLNƷG dv?zJc.ŋX'rE1>[5^P~ _TOd{=IUSO ixLއ[{,8U5f R`F^zhA9|F+m66 ČM .wq*۝ƥ{Sq,Hѻ%<ߥo8=I"q8ūT=u")lکc쮜Lf]̉}$+?xrɃ#1)C8tNrd+\~Z'NZ.3}TgJPՃNH|N>9+OIX]#_WC|m!s<˜ūqߜ:s s{<d7ggeq@RzGn-<5|-YwdΧׯ2žt:_Iݍ.ѕW緾oOauv?m[br?R~nE0{Z+a IDAT>[UCbzA]xDI+3eѨ|ѩ]2>50doc].lbc[Z%= حrp؟ٶ3o1vj("溬}V]c!RfhҾMjxjtoe߲.t^4KkQz#X1.cȆu] )(;l6E=nӻCE ="eħ:b6yI)mo}âFMMdy\ToaC:J\6;u\o*KZ!U4MEj{XI um/P(hmR6v5HKEA5Hm:Wk~MscBN,RBBz !cxik"+4J@=;q),W=pEgϺ,+Ҽ|y=Tm+br~gRV}CXJɅG>Gq hsSu֖?:}!x13цh+vje]vp87rpDKʧd#n鮴FSi3){x*.TJ |= pU+z ,U45LQÇ(첢r)(B-Mp7rBEå)bKy=NSZג1WQ"c]:hoEd=wR4h0Ċ.bŘ&4B7PD[ESksb^9PP'o6g8F6#`6#`6#`6#`6#`6#`6#`6#`6#`6#`6#`6#`6#`6>ypG,Y}f6}(;z΂C#|޾B#     s@ XNg̐|r3.% MOe`|rNJPw7?~7kjZ_^F3,rn 4g&!%g.ş]N;w;v<|e,cwRtOU[VNs3lQg\apx?+QqɱC36ke:/'8b&]r3?c| trCr%<0w?ۀcnlڞ V 39nhrF3ky~IeuI>~y3 S+|qr;~`۷r„S-̸Bۘ9n8}0nYY2{Y54,~?y8+yIu! D;qۙۛp,pO'z\WY}4|Z!ӏڛ8\5^"7 %%g iƫsP ꑁ?;^M|حpB0w;O   2/CGP~; ~,z\0B}_v:P)˪ot_JB:5laZ~ ~@NdBFZT`:zvtt3( N<7NMgi`o*{mWPW=i?Q~7T,0n`Z*p6eD8=?=Ƀo̓ہ毪lRܠd3;sKricPWL?u0!gPPN:^.W1-k=s m0Ӧ >_2o%]1"7̾-Cl9yux: >;gG@C͛޷+ Ƿ3938;9y:1oØ64<--\\Fѩ7z_opwY{9m)`[!C[CCCCCCCCCCCpSh,|r7師^痚wphT$'̱oG0_ ģ7I71jo'\g>bZw}GVo)S+/^C&2Ŀbe!78le拮||:~,}͟Ĕ+8uhC1Y9p7v9?4O\;y,, .2Gƍpߩ:RcfElq<$}.'s75Z, Z{K&tѯþM#BVϬo5Ԓb#BJC86bP>9}4Klɽrؤϡ ӣpW8uh;)* cM|![UB7*I8rd"oXFqh9vGmB!¸p7W`Mr.Z8u_iSt@`őo5?d&ˀAҫ*s d:-ڔAvܐp9X +O#|P%q<>3_6uǐ&x絰m6%`D C݆dFA;Kr#9ۻ:<{3Od͌gor 絰m6$EBONNE_|)JL/}{oa坛6 ȕ.j!3cyez FpuW.=W'_es/vwpUZ=NEqxp\-m X/xՆQۓ7/< 3GUB.~IIMe-+Lm6޶{0˘ٚyrC1Iil(oQcp;8c^㓱6. k͝3mv n?"uV ({nlo{338ʆB\oDJmږ`b ގ#}sOrS^e=3bD=J(H[if8St# Sn+g`Vr1쬸Hit#mKJVXs$uQ~RDh4f/]j cU&sQx̿MkňXl1Kiҍ Anck%H*侮1ea2"*;0O(k{'s\iCIK cSUƬ%BPzW'z>pRgXV&Bb(ĺfуK+/o/]z}$:u#?.="r,Y J$s:G?!M̌]v=X]Hwb,fc2-.-"r_p|`_{V}` g4F -u(dCzo͘cYa%mƘf&N3aE$.dcT6M4 s&LF,V"m<&;8L64*w_8}ԫ$Գ9u(@9X.;Hc澛(Ƶ%r}LjMXFYݱH&# 3$M-myu̹K )=xd>K125&f5mcfhKu"6eUQlS1'ߤĚu6\e WٶMmC44WY- b,zu u')5 Ԭe?KrO&''YOgkjF+)t8< ݸo?5Ve ħ9D=wa,o>^FXl)OooXI<F *eų}eav4#!5D >" 4RZ`;o+RE.Dҋ&&^LڷlvHJkn_ 1zQw"5~aj Ϙؾ[X+|ACd̩S"D1p1|$?mvQWtK*/H$zԾtH mzB0SUtO+\ocW̓0*>󪇴]/4:G< k(lAĄ3겒/6k%m-.C@f|i!ci]U:Սd,"s%fiQVT~WF2l&}\-e&6czJ%X0(I?. dNy_8)SPѥ| w?Y4k!~E# 7i4YRKee2 ] 24fP%hF}H4w-!rLKlw3b LK5D5X,KiWM.*E4 Fz Ml2N[^D,uۢuf&mʨH~s4qk[g Pk,\k&\icMI惈l Qiyup9MK@W~dxjزY`3Wܗ$wtvAc28*fȷm4K~n$Fec4it5D-)A~5h.0 H Ȑ=H#RfyRF߲aلiȶ5{)F2Rv-DD*KW.h H"5U/8Mگbc(KԌ~iM"{10Ba μ3 %ô*6$"$H/xh(?hfv,ݾe# Fo4i@IvB-of{g"l[>ky̲L.#auyF`^˲b[nE[VjUfYV4z_h%He6o j!:b6j##b͎gQzY*P.4ȍ{&+¬([B|%tF;ӭOUTR6oJ|qj Ty0<7zܾ^I1 j X3viYPRFKjdZJi;\fa 4Mla1iH#^{[]aAF^"Ƃ6oӷY\:-sgĺJhqGOj6 ζjV2b0: 75ovXzKT5[E&L:2ˀ {,. UYr66k-뾜I_qՔoժPUߑơɈ m6h˟znV67Ecڌ{!ɧ4\|9oS= }ubu$=n"60jk|""t+/mwfҖ0ԟIDg^,c/`1n9)Zb#iM,/.=% vҴ؇9=-2ck;Z7ǧ#nvie'ZP'rl7/D ];fhL)G3ߞv' #Jň^TjkGrh|ΒuL;$z[ IBBNmK3f޲[^{N-:-c&$B#ƕ6n!DZoI@d*&ϱI1؞ @Tm7fnOX+B"ۢ~d^rM,w膍ȼBۋzwe'Ƚѻ!eB7BؼH#-D|MD2zK@")Ŋv_D fzG~εD}BQ2jUʵhdsI)2Qжqɾ`6Fip_f덷ݷl2g7I~) } N,qІqІQ rmm|>j,|9w8ē|:/?~7kjiZ[;Y"apx_i__Ɲ_ Z% C9Ɛ 'qDzst,qę>-To߆N 8t<&H~0ȚuTDIDATxG{n_gc{Vn˹ ٗD(56Mo\͖:$ue |[Uп=g $/ ~|\~)N98wX=x }ޚ_\N/eHo˞u03o,}).KUv0O?RN]a?gۖ}7 `b2w\֤6r& _rV;e +cJ;3˙ue"%_<>|`0:^q3,gw~. e}V~NΉJfa!#I(d ?Vru^n W\ץΜɌ쳴ѓ95VջIENDB`sardana-1.2.0/doc/source/_static/macro_input_select_multiple.png0000644000234100017500000005301712174204305026527 0ustar cpascualcpascual00000000000000PNG  IHDR2usBIT|dtEXtSoftwaregnome-screenshot> IDATxw`ڇSSNz(IHH%4Q(Wϊ`*x *vz뽊]!H$CzN۝SrR!! ̣f=;3*ÉK$I{?7B8\b6a4/H$t' jR^QNyY9Q^D"9ٌlfcwf{K짵 xlꨡ1qث(/&HZ?wm4ALL [vgQT_PNA%cP,q筌鱟1' .ʊt3=˷[mJ B iwX>{_fWe3\Ux/Lvc„Hjifg؂W`Է=/%ee(-k ;j='N6#G<]Ԗ&b&ǘ{~1̟kwQt_HlZP?0&i_DFdS*uAҁʤ AB׮lVKϰB鞥gLeSQUTؓ&EuܔWUtklAXLc@[w!l(t{@eBZ J/ =1+.ĆJ-B&<:dr80*jG+ε E$?7VCvG}M]GzK>|CqQykz* 6*J1PPzStօM/ɋN|]=[wQ&,D9֨BGT&!$d9av؇~=c.k+ĎKf``5l! `J`LN|(mo؍/K*3nӓ 3ݫ>i?m4Aed>o,|M:k5xynsm?L?~> K߾o^_UPO0`z>^~zGmdۏ;nF9ʳޓSk}oIơֿl#'ذmdͿn󔽱iLTNFAt Tc'(pz3WH:ΛD8cP077jpkzj>oglZo~ڴ9uWwz69ZJ*|u,[}{jQRYd:mh:Ʈݰ*! 8+˩Lm>c{cbmW௘Bs类fЕbu1Vh"sv6m1zyDaDXN9Nc 4c2fW\Vc w"JFT6&#bXR&_yg%ަ1̛å6'-W>ϯȠ1tzÍt?s{=- ԓJFJPׁp!2Lړ3kbʴ&CIHA]%\4gnyB4G{E 82gknxKbENq5UM湚뿣rFew;$cZ~ DM^~9uTSww}=7p{5s':d|\1Ea̕gK)_0Arœ)$/KΦ>w%W_DPNқ#4Cر7l7I7YKV^4v}y[Xd~㚡̇OJeajwF_pK"H{e1gfVWs9`Z]?`P1 M]:E(d'j`6cL@IST Пc36pD39 [tطl͉=0}>6fT8')=8bgyjw۲pg/:nӅ`SP|F=]-sx ͚EoeHkQT5*!`WΙLrPKm!{6N [Wx^I YX7&7b`6&ָ1߸hm3mِѳ;'9gp H]U]#$BtoMڋl՟ҏ9$]$o_;Vǖ_@z" H/c;_}||us=8ٚ#nGۘJ7?4w|'wzd #ĺ'ͷϼ̧cmoms/b.Շ;Bཱི_byϑijQ?-Q,Y;`.?!]J5ʤݒ8{Ϯƞ{ي=$?0wbߑYsN_)!ŻY7"XeV"Bp\STV"2,[1m/{iN!pA5 rS]&7]";C ߻G~CxQ4_ux_Ÿqs`*^nkQߚkί^p9Ͼ#ق'f{1e;~gG>:|yUK3ٛ[@q.rbvRj٨=sq3٥^Gߗ]?WbhhmymLT{\G}*ˆ/Ws_DHz'3w2I]cG{_據$.>u77Pv&tʋ]RM\SBT67RlXtuqGU !&]9;AAzTu!{fav#[BR+kn:v6^FfA.^MUU& P⢭8SRC KD(QFŕT8hHXx8 {7bוa=j$(8 #Pb͂mt W8P\Na頨*F0"4>1Bx긨JvMADGa^^Yz53 9F!(8j3BQ iVPDkCO!yFlk&8@|g6 t2K~|MCj &>Hpj6lCJ3qф85e #+az>[s2A'VTBN*5^Ss>a[Mq25skGp3Q 4xL%62>0BC6r)޽4%hi\M4gH` 88FWDX e"k F3R`:8}L-D*|Aj!FP6mG϶֡ 2-Ę-3CQ '/co4sMJ_ӻNMI:e.c"{+T&J}T9hh&MT9l[Nq)]~- i:,Xҕme:ЅW~1BUh~6e bᑯ La_Q5v'R :Bsp)?8:(BDP+i)]8sBWWl v zwg M!*ǚI$ &dGbp4eve S,NGp\no6nOe."CL  i1ǂ4'=;k1G! @sZ&H:8-sREUX.ttoOׅw۳1%_ݟu9ٴ7~bwjozxZۙUt+sƭI$N@*"K$en_~*QP[μr~W|T ~Nev7I]#ָJXxtfZP5]ƽ~K֢i ԫ? ͮ7M]򮰻 ZkoY#(e8)rSʾ#~fXWs$ɖ >IǑ6bS.~oɓ3qcqNXֽ7c1x<`:n}=;<|~~5oVO̙̐H~?ʣ>O1k҆OobY4{pL湮tS70cFLeOs%e-B<pIH>qg1oyLLH||Tb OC9qm%n+gr,nt373Bx`"<DžXmdžg]Y &V;<&*P?&{m!v 1'MKCd?'fa?-`ll%bSnC[ϙ{Pvsix0X43[yds92N5 zq1aq nn:  u{<OGK7L%5އ]ٷquL>yg +or@+4Dl/Rd= */>[sAU]x2G?>ٍ`LTy^mryXA% qEٔ&G˔0!oE\׷{:irU0Un7/ѯ( xK(AQD 4Ǥ5*G?2ƭa`҇vMcaoN#Feq+,sAWi 4/wBZY18 Aa`1Ek2΅ϸ_dvFit9pR  IDATkuVuzAks& oɺkIK( 8]pPBH{ecNզOYQ91qf*e|_:eV^2wK+/=8Wz;1AӒOM/rݬ5'l.^ɜA83hն<STyӝ=HFfto:ҫ9P  >\9%G&n] r#o v.?y0{[]ye `y ]DKܶ@o{R1d&㢌ĎAzvȆN1Z1/{45i5k;\=[\/{j1ާbL^Q:j.zz9{|frK[%;( j'Fy#tx3 ol=VR-1^0_x蛀åq;WZ]Za45u.7Ĕ0I]+yyF!8.Y[9I3zS9M]l,a͏{qZMcZNяK7!UJk#m=eΆlE-wj0Ia{}6zY*Ȅpz` i~$vج&TEiu|c |c5A(q'J[>[Z2@ADH ݶddoPu45uyo!ݘ}\#M&P"qq .c8*J)Δ$W}Г˞C+oŮr*x/7Fh#X3%|/MwJ@hFvUJ$~f} QAw~NB#W@X,6jaCe ulW/䜛gԣK+#T6-;)-d QATQ ft! (^KqC`e(~؜DlLUUG4>' l@ gsJLIjw! W# DP'ݖ-F9?#8&mBo@|7ͫm$y}jLn\M=73v3)80JU#`,f3N 7xN~2RUQƐ֨+IG˴k΢/Oٰl!r"7!E(䰛}"p:8v [5VAں *zlZvY,?VdT+QntkC<2:б$N`q\<9l!SîB"P5<Vxװ)EZ޲VoI'F "kHk`ROC**?OÁ<݅"4t]CZӃ`u;Q]Ieq.եE\N&ifi&'O4'e3wkܚD"|P <#c)vy{*/Me* 4GL}Y%|fa(Lz³ !M0i` QY\"9V9$LQEEU=ayUA*X?`2jj:yM-(vpm庎Y'3ow !(G&LU*CMЈE4OHi NqKk(XCQ fASj xnTWvTp|8=n8` Ǚ  *Հ] *0.D"\)`@CAQ4MA4tUAt JU' 1tn~ظMZMT Cm5ہ1* 8e0bCPU *z,SkDrtsb=:]ESuToAog@h#Iؙs Yl*b_JdG{;.cy)kP Z C.$cV0PU0x̳L/b%=J!j""METcj/LZ`ɱG#$1񽨷楽!sꊘ@1S{3 UH$:m?E Dm%κN0N3^ D"vyOh{DHD"H!H$)d#L"tzI$N2DB&H:=R$IG D"H!H$)d#L"tzI$N2DB&H:=R$IG D"H!H$)d#L"tzI$N2DB&H:=R$IG D"H!H$)d#L"tzI$N2D1G?i{d+HZȘɧns⨪@ѢtEJ=0[_v";㊛ْU r-t]=`8Fh=`!am=Qƍ!V96Iן%)HCwDZٞ=`8RB;}V1)j?LDq)8dPMnBН7WggWyۻ,I;ᾟM -2`Cm!t: :EV|oK[M$>~2K$5"k&MIf>n/Q\-c~jPA^v$)EVRρ6(Mt́bE(@%ʜH(W/ #5xNǿkU8Zp* }|,&N&>/|KxLK-|2wnemQXd9eJ oYVU|ʂ7Kp獜`"̧$b\ϾoX~y*z'~_}_~,'IgrV_+ ~o\6z_/DXӗHfZb哛Ő14rYG\:E&VcKb-.Y<]xl2iL<8X﫲pjp}s+36\E/ʥMos8ӹL,aK$G3-*+?thn@O`*ۮp1,2r c&7P*XWsy*(/(6;]dXȕ'_R<= YPu,)$ Tʜ?fq=05X/"KH o)mS^AQG`P;r/ ߘ?#LTT\;^5,p{!fv^NY83fbjĀSk؜%Xd»w$ Yŕ`YPSǘx)fMՊ͢S_TZ61nŤ :Ԉ D9<|oۧb9dNs ?}dQLgG./Ҫ)QVCWNb1\SLp. ,iI,bcK AJH6sy^}= @%$7'p5LyfTeGE&җHf|s-; &d_TSj LW+T,6+ϣB9,}4xF&2w\d};\KjRd=Ekiܷq.-m %6q C /~c|.F/$AbH4 G E]_ե 2ʶ~#ߠV+/Eǰ$I1?bPoZo4 oIU{/B!BP^^b۬R"t(~h`0b20Mf EQQPP-6-oZ*KZ;ֺ%SP@QlzVB)dpi7Y}t%Iქ#WI8U5zL Txk_o^f>2%Dr言W}Gm)H$:bor" xyw:9ݿqa'>cN_6+ 6O{/^|)}U L"iaZ/r$Dş4N;2nZGŵ1 sK?4$o(3>+w>_=x1F3>4{'7_)#SO%㔹jʧ`ʐqڍ|ug3?)'cԩټϘ~7~ PP=Pq90rżnƎe{S&%ei|k5v]H$Xz"${[! #Csfe#vZ{1yT8Ϭ^~`xCCW|4 7.WKx{&J(׏t!3Fd_jv"aͼs%p aMCs̤E!֕JpHT~3j „SnSr ,YV3 p^1a̞KlCenBT0TV[?>͞ 9vR,É3zزI'!5Tқ[|Ԭ}Ӓ|#9c|;p1=i "E<;52ҭ0Ri)1DL99q s~gRL9텋DPe6Jss$ ToiLÑ!d3E}q %|1n,Ħd.jL}q.>s!L1Xo%}|`{^s nTZyBv'{k@ wqR$z0oj&Ñ2dDR?hQTP=f44ͅihn7Y{0>##JnEFH$&B&HOeOh eR$aiA ϿԤqDҩNJݓ'cIR$!~4EV'VY#]vjH$N%ᵿ򂧉)G$B\E;y\ږÈ)JP#Z"@۞!dz^>Do^ 5?t2Զ [d8kDS<>wӗp>~t#ۻć#byEM!o{:E#2Q=~ g}o<3˦7xgkav HM$>>(Ψy.4 ߟR` -Bb( R/ӏ%^1SNnᇡ6;"~jbmn~4?qw DA%coowC_{z58'dWe |Dzߧ8f#JVviLO1+;?̻pLn)ږHy, p <-c#>V_MsLUqn:0.W,Eæ*6,v0KgDr;<ڸ яzB(nUI#w^3ΑcZQ sa6'7 q=okk)m eMAYR>w֭[ǮLI|V*o'1rV 7X9 c<]"/X 0'Ck0wjBh_dR 0ac=4NqV%2wLU^"n V4D̻2-u;_^yr΅\z|{A^"5<"`~.2ԵD"C]@U~sHkhD{fP㠪_VXͬqtQ3X<cUmF%IJQA!Q11(05\=sw tm2I!H$-bX8X[7mF;UE%k7ӦeB&HZDPH(c'ŨI$N2DB&H:=RZ}= NLg⽿SeH$~:i9q/uw:δC( R`$Ic}SgكW^QDmS ]ά.D"E"2rhF-Ś< sW^̴Q'>>^7ts3 3u۩$t,Lh5wkEhPi:uk> Y("](i]0;Oaң+G"4D2$inv2}\Mfڄ5a fn(=DұXBzl"50y#2߼s\+pTS8e./$l05v56 $>V{2F&ЏQ^kb5f["9:d'M-w-wIS'3tHMCjzҸ1$ 3NuEgpƢ NanH o?ĽI~h0D-ʀIDATO%L^ D?/K3sb;lz>?.dthamJ7 # ב1hB;qث)^Ụy`k,N5_̵iX)SpZK_⏂Q7D(YOo%,9K`Xf3XȘ=|s,Zͨ^MrjG"дXB tn}Ύ3ܸHNJ"k/& k`8g#315{:y7M`sأc Yy $&]L4~XQP TLApj@a%I{ӱ,7CG ;(f?9~}7{pdx8vR,É3`kszovHoU0XBJnӛ_̼8'My&+/hX%z2^]e|<w6f[dcEQBGQ\6cFJ[*6ҪMWRS|?uNؼ3*w e1!o]@Cl򩟺/6C@"'{bd =9884{8"spphpDC#2fGd=9884{8"spphpDC#2fGd觮 OIKM9@Bn q%//P"͚9f\=-~=9y0PW)UalH8E!C[ -& E%wc/`B;\&]|[XګlN 5)K{p$-H"^iEj8V&Uj#;ZhV)öՐPna=G,]ERa{s3ͫǟgYsxJa{հs*NyFLaY\׮RII)2(bscd JPkJDKQ[~Yۿ+pѣOp):/_/g=/2Mn ;;.B go_wGеI\~Ti6xd&3u;HxfΙG/tw*W̘ĹGR#XMo^)08`HLWJIHP/M؝7 ڄE9s2q?rSS^gXM; ʮ{F 7hl|==%H+XJk[ v ?*BXNy7I~}J")lZs0qDG<$GM #W2bJ|*&ܖjJD9f WR޶ڵT Zh5eghRZ CZκMM6[ɭF ]ғ?黟ăH;0Jz_RSEM6.zJж*]),niRԞu1Ջ2tPN(Q*~h$D8."!$QE+L%wm"fJ$:!,5T{4;I RBw:SOtjm/3c:ҬFI\3g6:n06F^T*Mͱ2a.ԉUȧׂu_+6M#aہu2Jgrv$ID6WQ3 u-N:-#zKD%-`0c"Dq =r፷?rt 5ʩ::fMGcpKe /TRT^ooR")|Z1lLx/߱!7(JAjsF9&~a`pьɅ& W$M6SOzH=˖®Q(2PYG᥃'2㞋XtDmbڰv$2!RuPbmܔ-tcd-}s7I47;T7kۏcyl.|?RU>n)㰢Z~‚~:r$:+g+.=Rt4rv))I^.I^=9!Ng)^>죔F??~f*K_Ж|2 m'TU2#[r\ EZu~j O_ Er2jl~5R`r+[{յG{ T:d̴9]i 4vNp',IzFXsKPU[ᴒVt:Ty6@tIiy}[BYߌzFm2j_c|D74S8aб򟯼ƆoIy͛^_D-252Q֐9&܊ nBo$"HfX=Q"2;cd=yRռ-4VYXY!'LtҗfʈWXSmBq^ kϓ_5j͡B6m*>V᧜FmQz\v48D5T[Ǐju.>eF?PֺL;Ff c#dOÌ`޷>P%o̜ձ;.g "To1/PgHv6pDv@*B?!`97Jl4ž.}de͖ΦΚFudC`^{Lo`4M#Wh#$"a1Ju:CSAZz3:_ϿfʺlWEXML҉=-GTgkU;c Z0yJɛ\ﭛ1&UdI: K!LL1*xse)yJ d:Px£MttpoRJ*6mO>g*ֹSuz%m]u~C4P$sQr(k|ĊwnBev@AaQ1K%'Y$IJeՊwxi gF@A9O_֓Y %h[PeK|i IDATxw`E?Oɓ@CU@,vbxz ;=ػg=,w*,TAZBIBMyC$dݝ|73ώ~7qllB<>Gn]9zq78rv{lxBu 6[(,#'NEMm 55tF~ I3ԴT֗j8ZΘ4*%\bwisTdggRv|u6UT(P1_ä[xkYZx9tG^7zJ>ӡt:^I'u8)aql)3RJRո<@7l0쪪FN?/DE^tӝxe.CKثɔ\~s00~iT vMhtKOcCi lyשw vI$8Ѐ,a(R3/c~|| -trmp/#Յ$%R3̨۪jZU @qh\ )䤧6S)iF@zq{[Xut.i| ܵ%%:&)1rm^J-nU8Sl)8#tb@eYW>!"ecYq VK F2l:4z]<=m, KKLjq-`Dۗ}w?7e>@wg_u>XuN)sc/QלɤMȣ˷7=fqY00E,xnY9xb1rᲙԮ~z -ֳ~G2󂙌)Gm_a7ݰq+?Orv/}lh&O 8꫘27Y85~K{^\6_0qHap֩ok9%є%u&2J `L:V {\h aX!ܶnSYK.fSɆ}D*-ƳG?=.LL ]{%cDbOֱx֒x=u1䲓^3}n-PVڊwx9.i88n`)1}rTue \s=A|0mt?2H"QVRm`H7pNS@bn1SgMmSw gVPI ?681ݐ&Lٌ\ؠj;>ٍ3pښ& nP~]Lħ-Ƴ'q9#>ghcJ6I_vnf6׏+>Zĉ?.䓧Ϸ7)3?O+IJO#iÕHSk|&T\4?}o*<3oҫ`S>u6R(BH xo7Pag̺y6i ;BWy1u6Ƒ>$i'%9nN SIs!-0|ŽqE0`b6zll6 ݆Lz7 ҹ'2$+nY=0;Iv^ۤV>W NB? RNgh$4Ȳ^p!MO =%AxOPb+ ޿ qBl:X~ 7iwPv2op+l{_97Ä~=98+fHwN}K[NHl߹xyR.;6Z@cc+_{{ +U]oED|_!@/c8#{y훟bQނM: #K[-E8m*ȓQ珼N߬xwV+? j #;}隒HƋNp/"3-ώvTLK&5^16M7ΏH;*tМ_Rgx(_s.|Ҏ-րrWy*y"~l&x'b_ىήu y#i%lvqGR-̾>c s+ڊ*jڤ1Zgr~UAz%??N _גnkZNM)Q=\~|da F}[m ɌЗR^ޞaƦ3@u4~^qk5&5;vM?,B`'-=:7UQlRHNp35;AvVI=u+Ntdܨ^Qq$ nl^Z^4$]vSSղcGQˎ:/#npٴMMVmG_Kg`"fwHNjZ2 {4͓ж.l5tHK&/6=Vo,O`ї :,qSbP0Xqk -.FZF v I~-,`hv;)N==T4\ cL>z6jbYs-HLJmD2!cM>߿-Y'Iʶ!l8v$/'d)#vlvR]99=ژ'@5fwѫFGaB;L9kn\,^;[ܧFJj)ɉMٳ89LO=K^$, '4Tk&N7NSg 4<]mew&L le|@YVQl:yQtEWlB,^&v}Qucgٙ1ni9P'/]7 ~.x=2>ׅ%ӧ=2-ivfqLQ^i!K i2?ShdfR0i6xJ3U4 ɹQ(m{N~=eVtv~ E+ٶE)J EP1J EP1J EP1J EP1J EP1J EP12)aN_*|\nP^S=rji6F34ALyBOQo5hU=zNMw%3!I" &u>z%Uu|bDm{2 ^p5,ad~'mR1(o#2ఁӮQ-YeW.BJ(m~s/\+ߍSMdvn!H$[%%hSɒ\VfMNgrAT\huS䗻XMgƨm6~\OajR EP2ЫdpFI۠އ.#٩x#6{5)l >o钿ˎZ?+7R1L wjR7CK44XZ?J |zbߣlp1\*/ Ѻ  4179-ՌHV`( +1: Tv 5xuM$ {0lV́đDBr:hJ@ 6k<_6P'En/rPtE:Tf/˯e5}&Ba !0 Ir$ÐIZrRJlV͊ vzl$gtM3t֔2/-5L E\1x˭?M;yr`)L1jʸLٷPB2R\dZ؝g?繏H B nIzl)3'XdR\^a~ cHV LdnCBJlJn<@zwO|l?o'3~84;0Lۏӹؒ!"UyHKLwt^n+гNMkAj߮onnǔ&fk2vxuMRM.7+6UR*<>#n`,;o0>SFlGWPt?XTu>mX\!O(LT]emт~VuQ0pznjNAn&,2F%߽~ݮ2:2ˢW:?/v>0|6$||;yYTT[+@;=i d8 |$J+-9p͈lr3+Oocf^Kh49*?po9ݍkOb`/ϕ9<2ﯪkf}:]u^E(!ɢcϐ{֏!MrRV;Fִj=~4M#`ge#'1te|\rrF=K[ $ R3s~%[9 ;Nayh*Yv[?V좪W``\ﬠ:xz6OTZ_huU$~.jyDQ[,?3^'K3{+$S p:7汑ң'_OOe Oc|pbdc IDg9 ;.'_cIgp38`h~wLrT7a.n6_jjuL3F' [H2x#I"!e`_n;O?(ӹy?9Cp^O';Ɇ7mC}[,`W/UbHJD??i;OsƐ+yK5ov}~z6>V́_CcIZ帒Z k ̽ rR 67?Wn:NMG/Y72t-bPVAw'߬k8e=ɣ]ٗz Gk!ZV} "ѓF3w_%ohv4(?ϣ!A}{;>mW5)#{CO` !R V iU{9>{ur~-&Ӡ|opulv'UuZ3yy*)4Ռlyo5׌b˪(#=#,"L豑/z?$:Y?> io! H<g3y2|S Œ:p&@.sC Jz3&8xR L`b2sl<6^w7`=X|;?%o]Ǚ\ݜke3}FY+aubxb=%bs}EpZ7@>n8dM.ey͙䖼̙: ͒+1pwh8ɨ=˻lj|)zә0wѵWD"ǣS6Y>_z[ N/8=t3eD BpCڞ zSwd =񷻗3W8X2/Jw>D62_>>MrsK?:X2q\[Ѯ^^VՐCe/ Э/ ZR j'8T@6Hh9=.dCe8Yř̜ԯ]Pl\sn>,584'mf+oMi| +4k7#lPvzp^>ǃ&u3^ooXŽsBj ]f 4hn):I7fCL%sd:B}}2F k!"x/9մմH_Wy\žD3 B/x=p)PX񆰊X Dib7}(bHļ4'r|SRBU(7aR(vaT(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(NnR6!' ߛ {o(.%`ME6# ?5,VVՄ2. ll9(:FRJtǃ]]AX]ޫ.΋˲W4 CMTڎ@zf6ͶWdu;X6NٹQtQ:]b %V1xcŇr~˚w_g-DE:s/7m^{jOFO?ONp߿!:>.v34%v덨oo>~=tMàr'c:Ű1OG9Z!`\X_6=;1sqn#xFFѡsQtK2}w7sƤ0dh nm ;@Y߹I'i}\p_4z Et4y=$6)5ǍZ_:5U>lq o,ΟG%P;,O;;'7$[$aC# DQ?_^ǧ˶әE~,nVO>5d z ~z͆XT x { Vi˽$ D9C8uқ7f' 9}./?~W=&ٶ]~s>?cKGH/٤vk.͞ѽb1fXM߅nM ET LpQ_[MrjzajHp%"Mp*LM&vtrg^JDnدvm'i?ֻ{\u2fsc|mv9S/a񄆆n4]ɴ&~tfEe--u9=b+ɉ=ढ:[IQ$nRW|e!ǝt0coXn:3qQO;jYh#&b E;Tlׇߗ^Q+~dAGCI~2鐞fJWⓐ}w!IS#q-ce+}TWm @#7e8gۋ޸9bd.ll!~=trZc7_<$u5uSĔol݊N˄Dukk^O5%ޓ~CF h)_~@I{"˿ UK&k Ems Ϲa6> ,m-x4 iU(1 CJ݊4A#Z4M=hWқۛw7rwv6qFpra} fS(%`"QV(%`"QV(%`"QV(%`"QV(%`"QV(☽Yh)%cR^&fa;꽫 E wHU|:n^Dҟ~$}4S'".tVs#~dm)1 '%WЗž)#xWWWxG X't-s#8*rGo2>Bh&vqׯ/U=x8,mk~m>pfm2:9b5Fn̻W'bԈG=-xoO}ܽSP;?|x)k˪ʤcs,~>xKU@)y9sdzEu|}WiCK9qp2QncZ|"+8ij(Zk΍TgLAw1mB)wq=q HKs+?K⶿$_̻3ss=Pߏqy~).,Rfs6v୹LHeշK(o,"j =(7]b߿a|RUtɹGkWN1L='1mRS˪/w8pb!?'^M&[xi3c}ȭUbˆ@\)'p"^e,<3>XeAVӦ$l]#_t&NɏLLPcRye'Xz曎eM'1G4c=x-U:h.97=>NXd#SzJ/,! Fb8Ƈ3eMĜt4v58RcoP Eל)ugލUiRK$u;iv=bї2"=^mWؗOy)j>5Fw5\<,y%RJ 18z0fp/7gGA6*آ&Hߏ+ Oa"N$YΣ<' s2ǩ/e p+X_ՏOF=yH9[|>˟_ďL;]o8'qu5WK GpT'C.xWࢭcT:yV$Hh焝27RgcT݌Rs3)A+7Ňsagۃ/K gc;?s#Byk΍$u˷c?H^G/y8rB:oHvg^vޟ1cF2~d:*u _Mtpf8y}U]wF">Qc0tt=^ Gg+Wp0tFr?CuȜpԳMƗ9ft^[G=t*#Na)֟bk΍(gz&IQQkid9AN^'ʭC_ީw>s3)%FJ5+qGr!E2}p ܘlx&oWojz'Ei07B SNs/2.w(>6Yջ;orǼmRpzYii7K΍f< ԯ+c9hpJ㿛׿W>諸ady8F z[긹 ]sny 2acO$󛻹yxW,[ ^vd_ /O|_oVSoO'?*0s3U7g?>|T渢Y:Us#X%uՕH)RR[oP/Fc޵<Hؑ_{"%҄yZDIPvDa4dZXy8,v Gv!u˹{E[ԙ'p9=m[w^—?ͭgER ^/?iw„<]G@XIzNRJB#ѡRvGCKk:Rrv.kkp/&)K[y T/z|8GpN~`-uSbHH7&#LgU1knWz_s`R\:ފO鍌1:" ɐG=K?]a Rucġf\p]nI͹ȭkXi=uu?aX,B m@XCv_#O/_7σ?Б7ޡd&gb{9z]0z7f]·&Eؖ2=Q-$m4dػ^wmK0q2TkF„?'-V4 *{d] BSRpz!҃a~41MBOdsߖY`8/%ʖg]}[ܘ"}6-^K?᷈#m헅DlfCMж=HsCEb5mCρfCv`BМϞn ݰ"UzhF2`̬km`0yFv JKa 5Leg(\B)yiQeֿ4ϱp_Fm+GDd.tiF?R" D1OZe V01**P O6g`'H;h mpCb(o|NQ]~f#sWqRup`7l]3X*|ECZ[;V ޻׈}`IبV.J)6$Iw棇y:L3XĽ;"νx6a Hen q43/["+n>FJPݬZӳ~}WX@LAf#>C}BƎP^Ex{ЖDɠ dx^TJ4EyD>γ+0Bi`z>`{=!8y(ɛ3}S?V ,e * 7ڜ]bQtY0~x#g" 6d&^r5|u5vK`zV{EZok::duE x`ue ]V  t[x 1DdLןacOg/s 8.}x[']/ ]zPAC^4 dϥo>̕"qxˈ?ns[O2*n :~wPRm9q|20|4C*flC2-THoXkM'"p3Rhzd p<_i z 4/LDFE7x 3jM?L cEӅ,iZy)|:֊ԚhUQ>bEҐz/"[5]\M'"x>HJ2?P,ͻ}oid=Zow4/pW(%Lipe{">G?RjG-dmeXabk%GZ `[< undѯ}2o%Ԏ!z zp%l:yJ]k.U^@S>fO%lϸH~Xa3:wB7oMLS6hJ4Ұ߿rq5ȨL?{ceG6afl]NHMKg wmael --M4fSV{tQUdSVeer;)O,[sz}!i.tq8eKۻ0 'krm1X`.8v%C%HPC qh$$\.,c0 ;{8<:U`ӶqP;f3CQD[*N.̐B?SD$ãtw`r&1(eZc}BI!? M9׸mzg!np3'f<=zӸ(W`o.*!(+y]^A1ר_ԾG4aYi5QRn B;HBWs(KW^s`7>IENDB`sardana-1.2.0/doc/source/_static/macro_plotting1.png0000644000234100017500000007261112174204305024040 0ustar cpascualcpascual00000000000000PNG  IHDR)GsBITOtEXtSoftwaregnome-screenshot> IDATxy\YAPPESqGM4kYL{̥M[Y^oVW34"DLWEDQD眙y~#yw_Ü9y.;3z r*]@+]@]&bJP稑O~PY t PZ AXIW,{DĈ iGDjNrP*u/v$Jlֶcs5+8N$DQSx3G""8"@8##8qOziX$mwsNuɫņ7{~ɿ<5C䉺+~vv1Idzi-{{5Ms_.H<&㡝mh[kqx$֖]__-;!hR5_*z^qݹ:r#(~#l-$nnʑ1bH'Lb###)]z t-fszgg .nzgvRצwrNݺ)Px21nr]ysb>|c$ݽ}&vvqmǵ/ۂ菋)gA}+ِm`2A#:8MG}֬:Ӯ{K$߅_qqqr*ɭ mʇf]0\$k"w먞^{խccGqc #"G1o7P-w_Z{Cb!hFDedh=;9:3SuS߶K3FFwlhA]5q J$"T^?7οd.wTS *3r {o%]'w<|=J4e 1!'lƙ eNfuj/$%8py"bIcǎ%[8vp7b~(|m"ڴi^cϕۨrpX{Y 7fEY,75A뻏S4͢IAQ$fQ$I(pҘz֔gK&` w52SĞ,I`4qfPm\M}/x>;N]z-qfِo01K<.:la*j? FAbDs\rfKkzcxA CX=MOTpǴo_AYQ.9Jz;ϮruuMNN&/UFb#o[sdO tBD:NR/ZȾeRQg<_|a͚F$bnݙ|#Sy,q;vc$I$$1F1wgcr Oԍm3n'B~וcnn\!YWӶuL[28_F%:nwsum\n%2@F'_1ktZUjZvtubI^ ȋY2GQD1sa%֡mKӚ*8WvANw/[8jv@6;&g{:$Z$㌂'C7w !ݐdV5 qҟx}_$xӨy|5h6˹J #,ȓG2b:p(ZYQK*T_O0$1QDgGI@J4m*ӗW?rb8Cygtj^w ]`|}WzLDMurtDGǯZE(FA("$7 彙| lΈ/%IEA^*%3(BcLbLbϷU&1㋌&}{z{WdZ~=pUo=9~S\*MQbS6>z5`hK%VЪl+YcOOV'+[_)Sghmcnfo&Nt {`w.ɡkSC1&2&HYLs܌I2QL`(dgлKoN67Iϑq+GFFTm r{}Ţ"ڟw3+4y~n=[AId 2Ibj5Uꪆֽ}}sGȳ~QS$f!&$}FsnN"PI6icU9;|]#"9`zEiK 99QpqppwW/^IL$"Ib]-ƿoR}1W >>(z||_^ſ8ZKHE4c5JM{Sv8 1I$I8AXp$50@mB$ $2@|(M=qGW^yx6>vw#QEޟ!FvWqeED1EF&1ƘY_e}=>t,#^}ULFnBA*̹>Nr ڞMc" Geo*SxDzr!#'Ii١#Nd˭.oKx-|ܲ%T|]6aQdҽQQAQEb Ӯj1;Y7τT$d$d&8bTHZ- ng1ɡ(jf*{9}1߱c__95"b:4r0]TO]wwVg"q$ɵO~\zׯQ tӀn7^&;TVzSɾ*UnI~T~ϥ+[z pGVAD+AE9j';<Xk>Ą<$XHI% +ߗ؜Dd0;z^(:18%ZWɉUWE ݐ֍S2=4^W:!K.w d=U_ ~%0o8/~􉔮IOߞE%00իtr*ĺb\fD/i}z7n܈|F;?"{֭ٳg=bC_|ԩSw۷?w޾}^|x oZfٳg7oӧj_yV0Yڍ7 9n)m=~UbW>}cǎlv8p oEǟSSS_~˗/1^͝LjjJ*(::ԁ>}:!!ak\\\N<J۴iӹsf !!!,p%`0^Z:;; /QQQO?9zhgggɴ~z Pzñcvvv޺u+۷ٳg~~>ݹsn)g:tljѳV5 ݺu9 ܹlh4DԼy̫W wuq|I޽j>e[ A1!!!/b\\\=Ug)%|iΥKm֩S'y|gΜEy:ҥKF*>i26 ڶmKD7nСCa"taa͛7}}}˙]$'''ˤ߆ QJJN+Fp«:eʔ~mӦMfn)gt֭Ksss+= 9??߾}.]pM6DtΝ 딳333fΜ)xɮ]Z2-O?tŊB;vxر3fX3JlΝ;}gΜ裏?\>ܦM(55ܹsn-,Y'X>q̙08;qD˖-;sL-+yxx#ܷo28/ʕ+T 5o޼`0X`0h"??_Eۏ(򉃘ݻl6/[lݺufrww/[Ou޹sIn߈hᎎ:wŋu:|QϜ93i$*kZO:::nڴI>,2eʤI&Oܽ{'%%qWbUE >|ٲe{'NbbO?MD7nصk{f_lOZZZ%\pƍa+W`!ݻw?r 9[haGd۷o߾֭[sΝA^׿":uTƍ~嗨^xAt}߾}D԰a⻥}rƍ/eו+W6m*J:tɓ'ΝkYh׮֭[%I _۷ooM@Zm>}o޿Z7nzn׮]ۖ-[1B~S`J,,sL޽-[6hРrǍiӦyɡKDwܱ ;e[p/~?k׮g/_޼ysok֬)>駟=yaw裏,YR2(>>cǎ111QQQ%ez>uVJe[=zӳV[nuBjj޽{׭[קOJ/5kL$I(8 8~+VXtKVz8=((l6榧?rF)Tb(Ö]]~6BCpwYIV%<ɖ;wh4uq{i֬YNNN`6oܸ!OUDvʼOa-NXpatt~Zcbb8PNI/bNNΝ;wol6Q]+}hժUSLc4%I*)ˆ(===%%W^e撞nk}u&aT!#WW;rϑAAA۷yzz&$$8p`ر&L(q@ܠA0ƈvrr"}_!11ǧ2m`Zرc'O&u}DiӦ" kӧ@-:u'SN <Ļ-ZׯwܶmN {uni۶m&M~Ǩ9s^>(ɴ{իWWM93g,ٳg?VpB;UT@` P@wޭ[&%%ڵ ²eۧVX^-sl2rYdݻ_y啑#GnܸqV@Ԙ#|xw9k,iYcǎVcʕ+FDf͚effxjwmR<;wZmƍ(++8m2T{Xh5WsDբ* sիg2",,"Qԁ6ļZDu CDFQZlU{iӦ:.99Yׯ_s\.6j@ST{P)Dk#[5f://ҥKDtҥK. q%$$sDD… cbb6nܸz#G#7iqqwպ!gyPjϟODǽ}閁7x㸕+Wj41c-AF:;8k>Æ quu,gCK'77ͭįd6m/a;Y^Tm61GUg0zM?&FjKjjC.\0z訨(''f͚%''=z׮] ,ر={O>};;;;;;{ѢE[?~|׮]Kȑ2ȌF)g1瀫ԇ ܹJPev1qĀV/秤4m͛7oԩz^z߿/?[nӦMի|xܸq>1c^ڱc?~|Ϟ=/t>|61#`""|  4hPDDDxxw}GD{~&N:cƌ1cݻwND&Pݱc޽{AxRSSA8Nחh4~g7o~dU3g ߼ysF͏7ӹ3&MJ)] @0LׯӧO7l099=z ~t)Pn8?))DTVڬY[oi|ҥWnذa&''^X͂~}}!MjAԢE+3`-ZT 92u}իW͛7-?2z%o'&&~WjĽZju Y0Z҄ TTDc*Ic2#RWPܾ}fslh4Jd㸰0"JOOOIIիW鏸UuapIj5MB_}tPÙU0"A"##_[}0qVZ~̙3]VѠAKcD7ڷo_}||^c\W^ l3|ڴjnرc'O&u}DpcN0.#%h"ڰaCV(''ܹs?جY3Wy2xxhҥ@%hht1ӦU-̞=ȑ#/߱cGpp0mڴIx700СCjaaaoA6o޼?˖-S&L(ؽlSRǎ4oսA#Gxᐍ-X'VTLN4ĉ]t!nݺmܸRO322XC!貵jEJ`o*J~-EFFΜ9Ywgӧȸ@??AOŦ۷/(( "IApqq{-Zׯ57ܶmN { ?C BwuUNԩS^>r1Lw.Z J^իN~3Zm۶M4SRR̙Su͞=Z… pT4dF3lmۦtP!+&".\Vqs])6V:CWsE@ )6#MJH'O*]d S_?BMyoM{ז-J5Pa7641I))DHGhѪiqDҢ-R&iyٟhTfjY)V L 1}$??9$?Ӧ)\4Ua|i;bl{i#G9r4tCqqJ5zDPA;Ҟ=J5&}J5&}40T&O>I/J5 &nnԡu@MU^`0zD@!mճ'9CJ5 Vu@B@E! =Q2j4kF^^tu@́(4T >w.j}ѡCĘu@ *($lZ-c00X l7`nYS vӨv`=a'0X lOX lOAATXq! +! `;C5v&ߎ#7W: G@FGB_ntIuc lAAd0vPvH*ѭ&B@yU"4Ux!Dh(>MEEJ+p WW:uJ:qQh( PJx,Mtu-[䄄[%V>}ӧ-?N>KǏS>qqq˖-3fL6m,Y'|%8g;vc鄮Ni`0VxO=w"jРI][b5^D%uPt811Yf&Mh;qF{.]([sǎMWP@ㅋSSPP0lذj;LD4s&Sm~nnnNNNJRI5iGCW9< JCWP:~DQ:qrmuLUNΝ1 @Wy\1 :P|7жm}{uXa*x8MVi*Q#Z&M*\]͛-~ؔ+)?>=W_h+)jѢ<>j_175oNhR[:{n<F@YYtݾM=1|8hT(#/ڹӦ^Yukz56v͛>}yZGĈƜH՘Υ4AQ^G P.+ɬ-pxAS(2""{ql:sp^AQHkhc~Z3Zt8SQSl,MHIID]cbxL!4bzɇ6MjdZO\ww;{>""f2 ?[L[D凑KqPusr&Ƅ]al$8[?":|9_<^w8 e eض nOV㏢X>jg 4G 7={n]cw@/}^8[qlmD#/8IXGw:q!Vv 6aT63ܹ3$խ[h۷?ʕÜ98tV];J, \U[7_EĜ%%E TS08G׬YgqϨP-Z 1^%CǍXN%JѮFB*b_EvAXkt`6LhDQ^ [3g8WBCpvysmk)`& ??,^w- 33boiY$[и1RSEGz59-Z`d( //?aǎE~>ڵáCZ?^O~>~1\7`g 6mиrg2eP>Nf~իѨD7Fу]<itzѡfǏǣGh'NQǧWu֮Ŋsh V xii=3Q:0Rau*:EGZ>qx@jp-pdM.gԫC5wܾ=[P[J`BCѥ ,- yYǎݻjFN,Rꊽ{E ~nzݭdcR[O> w`^l\WF%/&.:zZmL>^tرczzzrDg)ĩSBZrn3ח<.-B!/u (}"OaCLQerct ,-[ihbbv{-kz>DRWx־}hйE+U &`|)^Ǵipp"38:bR sP$ʳv-Mkzy+ǀ% r+Wb?8~Vaj=\BeKʳgFΝźפ8y7oo1h/cm1c`r`̘:uDGT*XC}(JqzhZta9#:׭QCtb9 8uJtY Ə+c24Quty;{C,`iK/:dc ":GTC~ׯ#8ZXW/4kS7EXAdg#1Qt8r钞~c{7^C&ƍChRt:A\(vvX,-hԈ}z57ލ%˗!8xQBp0FTRaaHHR;) 丹!!Ati;v`3z5>C?ر5 +R#`c E琡njض +"m,Ӵ)NBo3ExE-[V-_/:\ V7c ̛$Qd%5={"$7 4mdl܈~Dxu*t)'=̘PO6m>}0z4 -.oxU,,S6ʖ/!ڵkA(G>>HOE=#9a<vC&/XXrT*B_];FnrW` ; `df"ycdl;;QdX5?!V+Ç!\(:̘޽Ѡ,:O1v,>@t`"ϜAJ tTAϞXTtɈר_ym#:+03CD,ᅨ"ag.:Hij[l܈O>%>9(_^t⢣!p5/&NĮ]H ɓRU'5lKQ St~7˻YXFt حVLN֍r! 8xPt: "7,eʽtixzΡXsfBe˰z(h413Ce}JŋѢ(:P!4'N,]M0pJ C^sKܹ#: }Ρ'O|Bc0Q#QX53QQ@ժs[ÆhD[ 1cJE?C+qOCXiS;gZ+n݊=E0c9nZ- 9JLj$&OFx8ʔEdVw9`]gee=\ZݣG޽{] +95>nD0an;E0.s({LtcJT'Nx_lٲnȐ!۶mۼysꋩmmoT(:a*[oG9 ti,\b,ռ95٭V,9͂ԩСCT\ƍիW/xÇ?e*je,[cV%:! 3x}Q"'sbB6uwҥ7$Jzv5Ii5oiS ҥKLQŧ7{zjNNNkSSSSSSTL|2ΝC׮sR0/ʕSfWGwKҒ%zUtSj$[P\---W~;޽kiiYZ5Ӛ5kHKK3rT=ruş 9 /* + lق۷E0<]hQ\\ЫI,ռ%HN]PT/yQ/2e////// 4h'DG2m݊E0ၕ+1m(f н7gѣ ߈^ca R GW)IIIhnܸQ;*Th4)))FpRR{{g5o޼r+xI5oEv.^D.sŘ16 &)yG0w.,QxW71e qꔒ{;Oړռ NB2苜>/uMLL=vZ^^^z|;ceeUJ*U-[E0[GEQt2ecf *TPe;iiذAt/>Y)ռ%E6-`ݺu;wn2e/_VzO:^z666^^^/NOO_n]E.-1x0am-:ljBKꘙah \qSG]TgX[cNX.yli%0PIi8kހr@Nu;vػw奤 TիW[XX\͚PO+vy$%cG9Ӧ!!nnUX >bg~V`&% Kg~|5.\CT3Offfǎe4 {w4i=OǥKضMt=cF9#8:brȑZ sCGv64qRG?##v޽e˖5L')xXU/(r%*WV܅R]:XÇΡP,2в%G~Ot :խ֭sUv6BBo[Zjx*.=:w#2Rk gzп,u+:wV_@ͤ\*UL K`,.}С=\re,-Ѥ Ou%{g]Ϯ}{"* }(bͷ PͲsbնkg`XT|<(r)ܽ iEf@#i/EF7Me5B^zВ'Ư?6;#CtHNԩ䎿,,[kW"1QbYYf>>__Ʒk7ڶEXeKnCedc#1%t,:4TǪUGQ^Kt4Gh&XʗGÆ8zTt<|KlCp%l_z7#F /OtWt>d ^h X6<<ču+uU __,X :G ըWt 5V&MBFS9L l(&L@T]ܻEﳬ|9LQ\t l|ΞŽ{sñcE֢sHCZaasPU+9$CiE(1hBCQ(&X6VE u+w9BgajRSVcl9$l@kBA *:)aeBbv??͛#<\tW4><=Ѽ31b=v®]XF,'(T)ڼZDشhO11ܟ""AAsH^@ll$Fb0,_jDG11 Lv-غ=zpyEG.Tn*A6ΝsH9֮u4j1b9YF N?Ft4[^SɻFvb"VƬYsD:Jq͛qˌ<&t-Qgn7)Sз/E琏I`a3Exի5 +WR%QLeM\):D lق=Mq&[n'NosȊ6m>?FDw~L8u Z=BL n}Kw7YcD(rS>G~R4dete` Xfjo1|(oQ2\\D琞dsrRYDg`؁W1a4r$Çcc|:kk1L[Ӧ Ntײe z\v ;qJz_/:Pa4Lٳ=_ kQX!2WOd bgzCY-:s""P |}E琳ʕm&Nɓb<|]1h;X~Z?Ke쁣#4C||PƺwAAXp;'HM51p TQ. ,?ouqHLafy0w. sՕG` Z@nƾ3xlJ,K녾wq+hcB9q"""p!Cºuh0x0Z#t Yo]R Yj.:īع vm9CBHZ~[XjFseցItnY[cn4m3 X_ ˸yשcsѫb6mг'RRdx:_wǤIؼYL.IDATdt F+TK*kxxcWLʺA`,/&M=/EcI7{Q1gfU)R_ZY?pAia XEx. M~$Z5L:%`V)WW|-}Ac XڷG\Dx!m#A}Z%Ժ H|jYkcLL|66,WnnÏ?B/ҥɓqOΥBtWVfp8mC>UhOq͛|́, SwV_P-W&MDG)6>cha>RcR[hrr|8|`Pu twyϜKz偛~p1ο˘6m´iss``Is*qpkYNNѾ?Fx8mYva`e娴Z  F,Tnh5nvE&cX3~ 3 `yc|D F͛=l`*VDFX#GD8qgrI1%%oXKiipv=쐞7q *VDvd2,o:woKw>DP i:t;{ 8t}XThKi9={p>ʕCjU k #> 77Qa╁yzbdt還_=d |dz%m 9RV-Ԫ%$~={DxݻسΡDӦ ݺ黬K=t=1t>KDEaNwٶ !TX6Lo&=|P&/XepExƍ_t*SvQtAٲغGD,{*E i5/_StEV 񈍅vt{^^x;wti#aVN5 q#:tJ8twodf^E˖(_qqw>"z!`%"=]t@~>6n+#ym -ZʕWh7v@2GDEcV:uPTx;a2*WF\<=Ѹ1-Fs6Ð!X ˗ iGlߎ}EV/,-E0%X3DdnW^:ׯ#4V}{?ȴ+' 87DHMΝ8wNdպ5~ ꫿Lyj/S՗oy_8?oo;vms7l@Wssm^:woލ L[};/$MG>TҲK`7jjf0i)Sj7"#QX".::H;ɪ;ѣHMEn<'=t|D"B+nz_OF.09V^:D$5, ayv<'ǘnDL ~͘I 'a)n䯀ȵ2f/@v+XK`F:q/'=h'$"=vA+D߽ěVFڵ3 dX9t#R1yZ,] ?4eO~x;#+ش F:9RDD@Z[\g">c\DDJ@*lڗ,/T1XÞUDEaÞHXbrÞ%$ݺq "ېkH4lPTj'&bzANDxl+V:hK3gwoԭk)6}:ڶń XQGWlߎ |X""5k-#O!C;?2` X>^^?z;wA\ E 4kŋv@9PsL a$'hK 9bVѽ;ƍáRRpXXhDD$,X8_ct OO=""2a,&J99ep-_,""l*Gr25/`T|%lmT sslق۷{zalidDD&؄.֭WWYYubt%#"2=\ôt ??tꄃQz/ޭV[h4 _U7o9?,DDT3o߇;d:' ^ kko'%"R2vAR=B^[^ݹ߭V7#" ` .]pq%{ lT*?o*ᣏЪjɳOch\++aAc&R%|j3N yiW'98NJD4,++4mMy]j\++ޜEDg,T,DD1`"""X`&""H`"""X`&""H`"""X`&""Hlpȑ 6ܾ}~'N5!!!/x'9҈KAAA^^^#F0aڵkJ3fiҥsN77'k׮>}iZ 6~T""Gt钣oQbŋ/>2Junݺ͘13nL""Gݻw 0GG;w<2776mٝ8qbŝ:u0`cT pXX޽{yƍŠy֭[Ԯ]n֭,DD$MR)Æ ߿?`ooʕ6m~xʕ ͚5[dɍ7W̯LbeeK鉈(bcccccRRR)666666EnݺW\=~;w^|z `޼yʕ+IZ""ᔑ!:NcV׮]BCCO>=v5j~տcǎΎxbrrrTTԦM>C$9;;Ϙ1cÆ vvv8qbnܸ TR/_޷oFiҤ_˖-E&""zU|| ƓٱctvAZFF޽{˖-+:kG4° LDD$ 0,DDD LDD$ 0,DDD LDD$ 0,dpݳɘszU,dpb2>^ 0V!:i{nd|ύ﹑mݷLEg0T)H?mVR%)^i4kkkJ%: >Vmooof&ױT633=FtP xΝ111鮮ƍ+SDJnݺ 6}t\]]_;`&//oΜ9VVV *?&mkkknn^)hnܸQbELKnnE1*TzjӤ${{{qqLQfN:%:燄,\R^u(֭{|ڵzꉍd:~'ss١dhKKKKOO=MLLtrrԜ:uMt j-t… \|CuSܹ֭s˔)|r777N6-ZTPnݺP [n|Yj\]]kԨ1~Ç>|8!!AVN˽{2338p…ӧNaaa'N jw`gggff& k׮;vddd?Zt"% :{lfffF<===<<ʖ-+:۷oT*VUTaaa5JKK[hѯZr{xxN&22͛vvvZbiFn랪TJ*dQ7LDD$2LDD$),DDD LDD$ 0,DDD `*+ag޺u… o>{3D"±L>LKKk׮]JN<٤InO$e,D ann[oٲejF-:H!J.]T)V{9SCQ8L'OLMMQ۷\ҬY3ѹp,D qk׮iZ}T*///ѡH H LDD$ 0,DDD LDD$ 0,DDD LDD$ 0,DDD LDD$ 0,DDD LDD$ 0e4wDg ""29)33 LDD$ 0,DDD |<_&&""2˿O[OW,DDD|2DfB#)fe/SN6H z_1b"""%{]DDDFd3f&""ОgvAV=`4p&"" ?7IENDB`sardana-1.2.0/doc/source/_static/macro_progress.png0000644000234100017500000015530012174204305023760 0ustar cpascualcpascual00000000000000PNG  IHDR{ssBIT|dtEXtSoftwaregnome-screenshot> IDATxuEo5wqEu***` ݂I(؝*(]qom|}ptwwg}vfgf]|jPy\~~=t_@Sa1er|EQ$OKbsNJ~A>y{ ٌlvs/ POU?Ow|"s h```p"玽.KFGdd$v!Uk($CyNN}Lfbv>@bF;KHNf@Szj呝h jFܠ>8l0,:Mh2[uKEuTM?itNH7ymStYDCڳU{/_e ݆d 18B,m闐Ƽk`]U/F yX͜"S+=&p+'4CE1ԄO3SIjI'kV6"G=kKzG[Q%+;2ځ&G%Xu!g ?.p*û|kUըExʹ6zǬᥑ71s$W*S#jұ~ρzkPW_-VN&!NB\DE ^,rχ$x=:+`qpw!i{vsA~i9"v[=b8-$6lL#i,QS/G`Bxa"d=Zz9" t6Wa1edq!OT;Ž_$s)n `;0̘tq)6#'ү]I吰EE",O@2^E#n0q}j2&^tNdJܐ}V+N[S!iK>]ɦ4g<{"*u _iSJ:fXκao](;9օ_Q4@Q^@Qu4Zk5PԺ{kHt,k+k /US/}5Bno Ǽ^/NBOrN 6]Ddѻ߱5݃#,fMܘٙ>MG5Ua1c"_f -Rӎ]]n&JcնEѶH*U;^m[U/Vu_@A5Uq, (u9C~.-wR<_sC֜Z5PgwǐIt]*zz&j=f@rVI``f5'ҲuW{]H:N8 s'pUգ"nBpcp8ۇ/ws~}8 .2?(_u$a7@v&6Ρﳥ.&>Lq`~gzLB<6m #x59yh%&ot$^z7|bc.źtZfFBtdPA['SIw>JZ'4ڛ~Ee54 )&|?뗱Z(Rmw N96; os`.Įy䋦M'cCHg!E".]X ُ@ **IkyؘkY?Q7EHb9*^Bw }\>u$-Dn3V[_ p:X g+eK˱m.%kh_G^jc1u #*{&btٵ|&_x'\m5՗Y=]{28_H硣Ho~gLݒL~Es }6-r2\;ε 1%T]<??_}D,)&"/cr/٩POрW4Jݑ_z&~E+ېc QY^}廲2"gLL5L\/Y'r(CL|  0ܶJg?xw(w,AAYёp;X-V":hb q4Ċx(pح2ZBI{$N<>얠k:݉$۰ʷDF@#:`%&\UtI$BĆ: 1#u[(WN8,DEFӄ"c9Dͼ߀WŎc[^6@ &3xW9w>v5wʈ'PGdu]%ZOwG=/oH$ EM;qH lo6c%la,C(c7˸oڥteؔOT~VҜVCQ2)ocoz:kZP#._~ZjrLu <^\NPPKLuA*nҶ޼ )n}ilЁwm"GвU첄-$A6u}|λn,v^/{ Xĥ ؜t1.u4Uy_ d 2)=\\z_{Ҳ:se݉JHf3Z>m`pVqdil+V$Hz4Kg]Ch$!#Χ$!'7,^P|q5T)j:!.ctkOH dF(&-o/q-3Y|vǧ7fBT[)@,j2&Q'oUzeIΤg"B$D?Txd{CIVGq4R(ɘP)@QKWZNQBmhtTv[$ұEbv3x\vr6*bMx<ɩ0od^j,W~:٨|ظRr;rE~9#M̈gY4x9L5VO@Py$~KHeXt)޵*'"m&}H~L=?UO㐚β0}|7sFԔ~sF7ɒw+1TO_bex=Zmz~'B-zbRa$oruN(;xՅB5OpĦ NI#+xW)W[IBH^yvބF[9$N`3X.a5槗p^[I8m0g%DpC\_Uo'`WM4Rry1'8B?U<}=W_4Ňz騮::L$!&_v7PGo[.0_ @f^>y\vq:&O[ !O| (d_IW4{I>kvOrpOs)f(r5Os-X- ?1ڳ9X$Y¿&ẃ,5? k8 p~8၏ 7E[L`umygƏ*(΄#/};k>[ej-ҋQf  ̫XZ@mۏy9PG(dݓӢ)mBY1).g$NAGv^5-j)_%1Swi򴹲z5,>1Ͻn,ʄ^T'ߒ̩zf3&IaפlI+擾e9o=Sg`6gt|-{Kcޣ2PSR/pJ*ݟU?ᨗR=)ɉ fUkAU|nˤ4 زHJV&;s<⛰$[q4ŽEY@f lD <ⓧ<P $c 8\N`f>xUUAMVC8<אN8-8"ysȫ#ZBh_-24 זP 7dy(~@EdPvveRWPuDwH"]8:*n[5ػ0J8lDGKfLxDq6"{5TdS!kgDdd8 뼚dVWTEQlb7c؈us蓮+lPlؓMf"5P~S`ƌDfÅog9H\i֮޽9Qk:$cpYe]yשkROT= .dMfI)~PT{FZI GEㄺqhR_5C@6Kd'.Rn)Q) IbyeJ4YxA(t3?Hح6 MtIqh E(D}yE NWm2D$&fQfaq.0M0\$JfjiAБʫ^C9f#C14 LV3VR}-DPXVBjw^.f'>Z<aH3("X-fr®܋H,' b0PT~Wl|3 d ^v{˲ QQ YKPZ %zLo#SɌ 殰Q63ᵈMB,1fM̵-m' ,DXˈUYqkZe- a۱k8Te֚jKl'qUW[*DdLL4 xW ͎ :2ZV d-&&ꍮVGuܲx՝z(SkOP&@zzqWbYɡoJr>v`t^o=@"` %$%WyqiOZlӡ*kwk窊1E0hh-2U9:N&:AߓT]# >/c``p#qRKZ[u4 u$9I?;6Ɠɏ dR6000008b*N1Zͩ 7h````_XJ .EdqRh#zB%^x&E U>i`pTDҨQ(w /?oJ6~ycpglNo_'F05 Cp>Flb"1 rhY|q(L` ]{z&|MiBl;i52^S<\ul9WI]<-V={W}ΧNlav 2mګ!:v-ogtJH3ٿr{Pe*aܽL|GԁtJ=֕N3:N.J6^Z)sg),^0o-.#NXW]cur6꩛9ذ],K5`#C5ZrLE(HP1me9: 3oa{.(lT,Vz:B%BOXםS]A}({<Ö֧͟hDĿ{^~م2nrk:DxD:V.xLFUsˣwt"D)@h՚.k>-c0XĬ4Ð+ol}c_0[%ld&&N3״03NEjIM/w_`J2|6Zx,7xM㒌4ǃ#,>HXxw'[:, }duVWFJgG,=~C|~`b:"[o7vҳ| 7 u/YͲu^/Dx4WS8Uwvf< *ղRPIXOԼtp3ƣϟ+!Y<5fD<\VsT\㮔Ƶ8_sڀǫ9ފz_  د5œ1OF=ރھl``Р:@xn HttE/O/'+۟]~FrEXhSs˳Wg7IKh[];pz̥jX|ɲ}~JsV4Bj̾S8|>S_2H>0yQT,ەCym5=d8B\r> A:U?Sqs3uqR8Jilucy߇CqzL5ђӺxo*i^]8ڵm[a$]uG*V,+?S7f{YG^}| _̐MSCb*7|kA͘"8Wg'> 7}hFC`"n-|gb὏mi\@`{]W:S"?.W}Ƽy c;̟"lhkZSGAwiƴD3W5zճNgTYC$QME8d```>XǃkꪆBeVؤxbb=td)m#d(Uln[$IYJ_hRDzXn} IDAT%|6t{װCOካϡoiזrqC c> TsN"{ f wkېl_/c_ +zTe}V4>F_(A'rD-٧4uCX~^R4"+޽=x;Ç}4\]w^}y4epO%ۄm`DY<5''lA+G3}0Su@*o\UP.3yq ? ;F JNԑΟE+tDadŶpE tY<qwZ'p~+͟fnZ">W=T_Z`qc_K]U3W%/2g4? 7GWGF+Rgp =.H }4Zh5Z8 Z$֍6#.RF&K5X$`)'s8ۗ[,ΉIGC(穋G<yp%$. $t@"G,/.yɯCTIvyjOdn7gM~w?2cuL[7e@t>$F#Nmhc_[]/:Qk%VĪ17]#yOk[e``p,|):veK|:uو^cf/B?趁A%ZG?N- J'gT 9 ET500000oa Tp/; -ە[w;c`````p))]fsc 5P1}?MX3000008Y(k3L' >f#40000Q3Fרk?\wcϯPE^TUW( ڮv,!!n:}7_?fqG%o42ϿW09C"OuvlDVɍ",c@4BCC[͛(<{VPn4~׋DGGͮ]PTIc.ŘFւEc\>z]"#$pf_GvN.=xc. 4ܳqiE;/ :45']B-:2efӯKoj}j 1Q*XUOhDq3_߯bZ[ҽ{wfsq]W)𭭐iQTTDzzz1BLJ8-2撑lظ.'eϓ~(_ĘKF5瞟h. <>X<0߫wAj @qLzc eIb`;q35j 2 fCrP&U>ł - E/.7t~~9#.VܵY7?X>sMq4cNf$ٸ [ndx+mUvxp_?:~'`5Y_#_ǦC̠+*&"v;$:^opWu]X,xj'sσSEuvѪ>ݷO&2"lsp+ ޛ<*9{~h_ɬJے,[co;سw}y>>vv2s*Ȫ,qA}]V:Gyسt掲c}[>a x7ط? lf, ~\233uR!M@ ułRd2S̫eQy{H Ba^v#@bW%(wNtTWXXONҢy>pע%+NYJf,h*fLzp ZnMGWu4ECUuԀqǬ\kG$" i$5 #9.Y86_i _A;v32G qz05r^@{?ϸ_0{ rDωr3F<2oW;|ag~;?ly+ f1ҘD\<"_7S_AfF6M4l6qFKwd6g:#)!{hƔgKp[Q$EC$, P- tt;BW@:?|lM6GSmzCӵK`+Wp_pxzәh%[db d ŎfizvÏ{f07;?~g˺ ?Xbtޛ௴B\3"|+WO|~Lx<}og=np-&KcH^Qسj֯{VS6AG(27n$!!Ў(?,`䩽LcSD觕| OFF. o%Y_kS*^ ܼxjUQ4 (cB$0""#!*#'v ,Mt QUӐDUi#92w^ٜέ+vXj[H]R$&S$ڰy mpS*k}z~g!u-a'36q23 z>SHB<:Aoi}?9[C~ Ŏl,L(x<*>6̼sۣϲSyhH[iV+v,щU8ڮķŒScK C5ͫr0*3Kn~z ryĸ$P^ֹ7s<#ѲqǚKtc<{n 2XkY]~]Ey[strZ^Ts MhFFF۷G4z'W?ư^PT@l蚓Oq5~(p8عs'tM>QÙ\W⩱-0{%fK\NV4]E|[.L+y$MSίW~.~/|ҷb0w66L7/aH@C,5%[gǠ W^ JmCɳw]:y8ڇԎڗLLmЋZ#\<3d=Z-›;ivLؒ '(ٌe'3\Ϡ!=F"l೿wUr?i&gzElش^ݻT[;`e^/aaahVzr @Ӻ!/~[CJ!&]|/\|>`Mx|>֚[pؾcg1_j13\0,na>[.p-~Y>(~ͧgA4]{+chjojM7_j}uY6D#Ԛ"s.ړ4 Q2[8UT':Ov^}07ӯ׭@ IL} Vl#90 vIn%=b+I6lEn|Vk"ߺ]~FiԎeȷ=dlzc.mBZ-Mhi]y4K]׵m>7=OiVV^,YאuXj5wt ECiH[|=e2N"IExxQ2hXws־|-2e_a5/1V5N[$tUBJu_b(=ЧٛO~d֡^c&\1s#OҭK'sm[7_:I&(FF_46l"8ZYK l룡G[ ywxźo(#1ym&Sڅz$(BVZ."m$ $X9p)ƣlD2~FU5U- dCڑ 92\^\RPjejҖds~^ǜԖYǻw ;0ZЦ][ZJd#ٜǯv)/F69С 1##7iMeVxbbtVR/W1k^4wHu5E$粺|yJ Q+z`u~-o{i*QB=]CD&\1)htа% MpݘfBBBX,Z{p^D"R'` bF7nN!)Y%7c@S(((dæGehJ jW"u"@QU형@oFvaB_ez /=¾Cx3 Qkp?*lj߭O6Vl%@wt͗3{v5[ld6sӒ@voZ]Pt`$FιI8. gvV5ad,cM•'ݹ>5H[{+E(V(\F3W52g4cFԥ7,Frwr6]bfItmeR;DnLmSNՉˇ2fKvszo;X{DQ`•iҒ~}z׫S׏lu x<\.BBBTUg,˥˰JNN :$a2(,*ۀJUv܍뤴l`)-tع߽\UUP :VL -7ኡچMDS4jרՆ>M<*L??tf߮',Ԇ?Vrع?iΩ](ƀv'ǒڻFXY+{eA]_̛gzxiCn{F N~0%_̳wrg!X$:2ͤ{a3xfIVxU2X&Gu_khTgq$҉,Ii< I,<؟͎}ܟ7+,c׏:zjp"Cioرs9&)/-9cO VBbR2@b%`t]GU.%IQٶm+{wPVʘ'qix_O#й.Yq6d"0$G+%.%wsYXMtTMCU4 f~wĶ5wsa}NÕva:{YzvfRJG3 62,cop8e.}%Q5p8|x2;n?~(&QJwP_FvmEQ)$] +~AB$dUBLEuyZB|Betx*&z̨4*&=P;#^u @ض/Wn ,U<w{_~YAfa-[FLL tbX0L`%UTTU𷠠}{q^4?.G g[ x'jCtz|*qEëIPTE%(A'H(ԃ0"7g_zO N/vnV&'K+//P N6ymq7e[3n.tr%;[=>~t_KDxǣt-K̗=cY㧘TU垇o 9))7],%B?Y§t Q+*&t]BtbvadZWb 82GXUQ݌cCy\{Bb"~wƒߘ'#ףA ;a8tرcq:x<^o*3e(rrrԮqv9/=˘7pG߰Iѫ{ f52 ޸1~VQ|} рp\6.xcVO tu^;2kG_DVHkHM780XiPsۋAn~[7VcMjwx6̬l&q ]ױ͘Z~ߏ һ?(auHl@χP8r &kqpfv)f7-+45ak,c4 =CJ%ԝȲLxhh,ǯ^G֬Y|u5 Y}zu3ЧW+k$c25Pc[aDbj,˘Mr] 1X_a?%Njd቎ X,f,G-;B4FרZ?d`````pct1F i Thf{0000008fķlW[BDAD6Ɉb2S}.4MS)g<G !$$ryGS#:;@gfR/ɅI ETl(_(JT.4(bEQ@"PBrRk.dx/ꡧLOyH$hلc&uVzwa1 = tMy IDAT'w2i % ,cݷ,jy`痡DU5#Bw)%ݝ[ٲcv/akx5CYb53M"ړekO^)+睵#wobά|O0q`_Ծ;#I;u}U#ߙ9( V\teN OWNd`וzX2DG/JYTJP5M+iq`gJ^G)[:\M"R[@ڷ+Mgy豧Yq3SW`,F6IQc:B AbNޟ'y9.z _v 5B0嶳w+ R`7ll#Ic?r*ы(e,|([uPɋWѕJWw>ySFxBq'g?xiRFidcVaA5Ly쁲Rpm _-xz ]r2vAou;4GyI ʻL$А!d-z 6L6u[lNAm :gct[|f옦V}Y8vbvݳ/۾NMC5} b+] W —#p-†+ST^YFw."h2ܖ.a ]]JM4 -1Jt, R%u,=SӘzx9͵On j^_.''_ gGA'}͉jHH}hÏ=+k5(tޔ eYt,㒤ffM:Sbt:c>޺h.U{gQ]^ZbqDp*F Ch:5 J*θ?;nbנ742q-Mڢݩ D+ў"WU&l“TYVgw{T^~Jeux2 $ VЩ֚NXuҕk zBw>8*eSV9pĺ8,G豼J@F s@WǾp4-<`flB]6'$5EBH$kd$ؒ6KeRW gOzPH|3rtRm-L:hDs]}kz35#6>u/'*"teFF7>7 $m-R D7,_يxUPXQ֜H &+Q[k.yM&OMӽ[RC TǿF jfN ,CH&ILt@Y $mXSG z &-bٴ=?{ :( BE?!^t/-m/C[뺙vX ksE%7}\ (XBBJg +^.VI ?abKPB0Q0E׵7oCXn+1 2Uh{"QԃeВUD"Dh:2Ӌ'dHcT`S}m$S7/j(kԽ15Y'.lnE3,ww>GI/tE/]&q#F)#M" f6KִX$RHiaqi0o}.O>ڧcWDZ޶Trn}J G\LOzjm@& 7.2_k:\#>_F8:Pc7ku;,X3K|j%/W-q0w]Hzs. _TЇ d YryUtDBH$UD#,4$1#6*\e-;%! %RM.шie p?*b}F֤gZJ+W%>/4L&&$Lô0H24dl`Y]"f bYАH "aS*oAFhl^K_'>H;EF͊@9d>sh7t>{'>sf*iivw6p~u]dDcsNYhdyS+D$V~f+w~z߫I&1I O oQhMy{Hg9S1]'H%/3~8k\)no6z3-abX$hHHdzi˴GFYB+.F~`uʣOaWDc#9ۛO 籫܇ڝG`qUWfyNq\f6dDlT3X#";;/ g8_xӅp8yҵG߹wυypLN_\Ν]u RBW_z2|}gWOᩧ ODq#NSgș֏S^oWZDw]V jԌPor$Z b&dXL'NӲ~k׭[dl`S=XnnT7V+~?gV3I +L amtTzv{B-Tw'>v!m?7gN!ҝl54Z>@K6'wt%H.DOW'D=^ fd. G_ļI{fO>W}5-E2ۃiA݄\2$ Y| 'rťr˨uwzPv **"LߓMxBE=,1!Gra_a7컨2|1XXHӪaB=>r*MN60hyf.Ny}#)D{N=ki5197˭xMSn^ʭN$݂sߴ^G0-6Naajγ w:9.&(jQAe `,z,W9N }_&,1-3if1]q/sgL&KȢ L؎L^^zHdeWvyU4Q#eZvoHbF ״f;Z&Af3l~%ws#!X,VJ)K:kN%D5&^D7-/Az+ZDH!FՇH<]=X1L2E8I.:u#OWr~"_Z%yrw:;ܢHk)J}:83yM/<ݎ%|ap9^wo⾻s_KWn N$.Dua' q=_Rg /g c|+|c4" )BR:,4ѷ'"(n͙m²4M,LڎP;}B!%9d).EZ<68IAHEhYZ&B#4MaJ KZ,ֶ J2wJ )abԔżңtu;*=KڈU # JHc)F!3VIz>93t+Gi`0B\Y.%vcʬHL( )W5U'^*Ċx+߻3%NOD{"8Bǁ!RD"\B0J|QO (F}KrZ$nϦa0l0ǎu]XiSHoޭ툆$u1l/O~C}4itp鍌iAmmMT…Pga°N!W͂2|՗McG1=E"bTi HUr Z$f7s5_]t^jA9"͋wFs~`֫.E?Z$٬\N-?!y31\rbTYMT|ERzIl'䌍w/9 !cX8IKn{ӅbE{78nN5"oٚl jdK3ِKW!`V82/%`O?ﻟM/Cl$qjte1AOUrI +ȤcYmOR%zX|?&OXq+ D,#- T@ !c`&v*lR5XQݴ(||,=32ғDu00J S")2X s.32Njyb YԸ#J"bWʧ'dtk"V!IA"_> BDR&iA+w'g11&Z׌qB41%$Zq+{@6\9\BX"+w +*)H.; I}}v`:Ti} *V\{!`%4MýDf3e;q < a=o)X"G!X]aWBIttu8xRJ^`aaZ@kT3#G 3<3[G5Q0VF]RJCÐ>>/8sbEMY\CE4W,zA XנH@=eDF`eҮ(`vx#4*R]^ h1;Twg4u|c1,<:7El!kA\f@ IV˒,t7W$ >1޿j~~X<ΛoySAÐ4X{p^zU36ut@BP;1M̝5=gƘx+ PPO9b!`!|)KI'EwOL! LR[[CUJ='ةB;~P(S__܁BP(vk* bF BP(vk* bF BP(vkz; B؍C",fLYbgh=5xౡ|]s@ Ȼ J6CNߋ7)ʖMm4F(V= O %})BJ%PJ*X~N`gE( ШL7ۿ7PX$qht{UE~Hݹ7кSn+\:EvvPM=F-^]>EEH˫uLَٿZyMr.wDT`QۆCWo2%%rA3?}+ʹ}44D9{|A?Bd2rӫ%L,%^ItǕyWW픅`Q1=~˻oƌ+޺)058)#Ny}Aշo)D;buʻ+&T8Yp@xJQi5bpVl/@s*~\lG̤s ] MYB*g¬HW->,EB c`SN=,"\\Wh1xJY:xb-#d?-͊n|x_A}JZ zwT*(4v-\d5.b%umy/IY; !|Qy/ eY srO,\/S]=C3˟QJD~P6uYw!T%6F];v)JVPlᎋ/ߓO#'w– xIʿ6aAnZݩ+b+SI7F8"ŅQ"kE& +4-4\(!!8 u"!V`!'P($|B^X^Ͼ%V7o=o]¾\opNX We'uήS#s$ 8hncD]bX^ Y1hrq7[/NAÌ`.7,r=A)d@U2Ub6%xz]rV!@P!!pa0c!, :7>)cmMXxʗ?1 W.޴BKCE~r;kz={rJ8eD IDATe[wW) C=s$Q9h`dupW>7^?[:ծĀ?+g|eu"mV4Ro˰늲ӔkxPtVsTGڅ㊧aG|sKVI3#$o!;B 9Eg 8MK`"]D>,8kB`YYM},4[2 혓EM۫ߟƊFu5xO%|})f F%<\($>b& iH(B;tY‘ܨ H-FV~j9SNaWg4ؖnEPےmx9&tc*xQ 7@ @I2D\X̰4d ;Sr+&CO; 4=5k4!ᅻ"J0⌅?*D_p~+՛4E <Q)w7ġXdO/}&_q(k-ϧud1Sf-dއ+fF;^|/fc|0cL>+f>Zƌi0m)}7rӦb^s¯^ М>Vg´sK^ Ni?:B ysދ8c+}Ǯf;^|"fc̕|0ȟÂ{݃}CeCmt~߻=7o9U˖1mbq|գl_#zo,ߓ{ɾs3Y7k365rȪL}S"?E}pܥz>vm/5_cԉua6⚆@ 6RM",`3(8'<ЕD3 ήn'`Y˒әFeaݟuɒ>Y~s~vߝwWyFW 1:FCgO|Q &kᅫo_ ;nڿGe)$59~d}u|oA˳j(_:p| :9t}59^uP`69yƤ|Uy.1AL?;kH*c :k.C(o 8_mX`u>g6#m' _ μhFЯUgp!] o|G2/~2<1o.:zGOE&-½E⹕u /y%8BK* X$ "?S¦%u}o/;PpY;"y BqcH"{yUt:m?~),73yx$C>.a-Ht$2wznyd-Œ0e9[2>{sTx*J -|fd3R]]6׿pYzBn[s'hsTW/fx;'_ƶ%3I{0%l.T .LF*"8.{~r?_?u<  ! ܋u" $7NQFY*OhQWBKS:!F*s?}Y7u5_4- G^H^G" c[MRlW[SXj)R"Ew#VH& g:1- d ===-M$2/H ϱ&c2_nJR;e Aypt+q[rʇqխ1?PY'1'iM\| :0~ 9h(ʰNJ @xx: _hѽ[ +)uEDᯫq"s 9S_Vtov/zgIykO0Qe"S`̥ °#9ʞDyVN/=T.>c.#nKE)D]s }:z;Zs 9vRZZ/-G"kHKHʚXU?oͫrzT=BZvfYHKi`Qͪ3US G AȎ-_By_"ʠ5k]kGc.8pL.[q7S9涳?\GJ'C'!01b\isj4lDe@! M&\cB2.ǀnɼcX `Ou _do;s{4ቕ!kQ:F4eETL'N\N8D^FB _rSܷڷr2rkuz4ӟ1 >)1lh!VU?f34,"A;_4i)C-z1^39wf S?!*/>9!X@HB5IeGfsY*VC.Li'@JQK+&c>2jŖ@Y XQ)wURQ>Ƛoo:y!_>C BzIސ9ˇ(Niᦅ^}NkÄjZyGʂ(\R7fnW?5-dB촏XZ&RNޖBGl ̅eн83cM_+|O.ogon?>hHr_G2lc8lޜ|S8c9rY3U);ǎK-Lf҅_]U#~|B9s~!_8l$X=.uXNjq76>0k"-ۺ7Z/|sOlM_9uֽp>38/JmmS8shm'p Wx xW*[)cƕi^ wV)" lIŤ*! Rb%"t>|I\Hb>ťgn䐱,PaN=i.?\s--Ǣ 5v4o N/?]lExqN/;< ̏}9WOLyUl'䌍w/95 R>O4:/\լlbvIjg.en2΂~ Wr_o[nìE}9sع=`滽$w8Qa IƓoю¿>[KJ X$HˮUMDgW./@+OBDF+_c-^!~Fs}a1\iE0=gg"wX||?e͋kݹP+\y7QRo|ު(1PMC "x?!N.'|9m*{]B5O /<|hYĵ{|#JYڟ%>[!8I?M6EQ~пvY^)B;"zM@AhēU m[NK)Iuw'VC#\w9+. Qw< }=*nSbWYy5ͭVTPK-:y`t`(7\DV"3 Ms: MiY۵{i|t,Rb1 TVZʤ~.8-{%aT$ǫr!1` VY \B>"\y9^c[v?j݅g2>0 p\ˁ"(DtXgk}ls{0ۛ4Qujn\Vld^j%\e5C6E>s[Š4]!زveP( Šc%RJ)׿5H)OU_B5o?y'έlI=%VFhrbs>DPPX$]4 Mu M'[0: {zS5]]W?=mͽtb{~>In\R(;"jۙH84!?#.nՈԳ\|8_BM ===cjCӤvXDa5=/ޤS/9I66~ 4[zk/h&]VQ_edK|/㉣Q\A//\vG\ŏo=s?1zL| KSen|q=|1+’YƶD얭JYP(CDަr M<ϾR:|a}t/fSN>8ͼxƒh}\*ۜ9e G_wC|S=krorטp?fw:=?~u C3Vq~ b5+'ÿ?b f%nhzS7SbO;?FWL n~g8-O1oeݗse[Փފ+3t#{?2YX>=3!t;u[C AP0kA 3yo^/ƽ;i bpkΜ>O_~ȹobd"JD ],5/#u\uFpq'q;iǴ;qx5qL2fdNDb$s:+K_ae*(άattl.ǰa4}01n1[xD?a›tUY5q0wukV]]EOۓi޷Hk籭$/fl2 6yEJ)KmЭP(LKʊ>L֓N΁||}~׻\8ӹ39N>x4RJ&,aqERw2&ծcM+@esf/0\ϖ鈡SGsb͙|r[ޙ7ox_B"̾͟/g2ix-˯.k9p {L6KuUU逾8(agn}λN#V= 9gq7rMǩ藧K b5; G/Z%ϵpڥq!`tm8%|?GvrLU ==ղiQ;+ bRlt9]^&r t-H)Rfe%toP; ) NFJH@!%rDβw9c{/FjPP(8֞%e)r>w bٯXSA J FōT+gEF0E8QB( ғ`G XB(E8QBb YCZXϼ:-0eq X"ĨABd.,L,4M,4 ,1M3] R]$kL+B-œ;BPqG6afe.}w64 F5O"Ny.aזRݹ-;iD% BX$qht0ioJ/ ȟJo3Z׾F B` yKPs٭+φTBP(][3);IHF=>P(A.-[-n("zQBP(=%h kNg66mZ~-Q@jHa!+"me* b#9hJ^x3t=?eYY޸a(!T( ǹi&װ,y93f4]݌3d2s=iZ 4OQ% BȂugZ&< Չ$MFѱ̘͛&O? a8w:Vd(!T( Ů#deSϐL&4͛iʻﮣeC+73i4X~4qs`4 IDATEP(]0My'5MlhE>Z6Ҿ1MM?t40 #4m% B%xmͦMhٰMXhdŋ#4 شicFi:O?bt* b@x!@{gK[+ B"5>)souVr' (x2BIPP(VJKP"%R8qQ(!T( Š-dAX{%!]3KPw qsV % BxTw5u! _-]ݤ$E4=~J B1h'4lbK{+-x)dM 'M<^J B1h4=gh^d{H$eMaYBBP jL#ٕ-7( bF BP(vk* bF BP(vk* bF5P(Ae )ӗ 4x"?% BXI:COW'toJ$hل{%TBP(AIƑM0k>7)ʖMm4\BBP Z,SM8r4^]'w͈w f }[M* b<90.ᅳ[Q؆Ia;lH% B%EP 1̉Kܤe$ʐM+\' B1K/\.ZηZnPD,BBP z$ ŦM`Ԩ4[pe !#F C4* b#im3{1- iҋ/RUUil޲ӧEڄjjTP(73tƏGuôBoӲxy[ǍСCLޙ0* b#aH--tlL$q}Y !0L~d"NtlLKK+C47˄=`BBP 9}:lh}SG"SOۛ'$1z(7un} 0kt* bc 7g&ҲF4F5~cFӾ hBcޜY %i8iQ7( bAc,X8~ֶ6L`lh5*dv7uOY`!eĜ B ]YpBhlhH[{;U$mlhۈ,\-;"QBP(]IݡxBbNkko}6K/"%(5PBP(])A: BJbΒ%{RSSCKXx!-n7jPP(QRot.L zŚBP(vYd^roͽv8;֬:\VaJ BK`o  lIR"ljBBP jBV4ZW}7X@ BP(/B#"EMm]ƂWiK׿y7)Iuw2MBBP Z8#J{;^J!!YSèId)W@t}EP(EtXgizu#XI7id=~!C^ZBP(ʖG N')]P* bF BP(vk* bF B%+t:_sfvVBhid)3ITU( {}e753ojD}ŎFJuo;o9vvq =G;v0ojt=l,`ܤ;( BţvAǰ,)-ֿ"wT nQc O( AœRu ZT3zľgOsm&61( !BJƹuCo uﮈĢn06ojEQ(>T P"+#fjEtUP(5QI-@v=wʩ\Il[ԕP({"L,>M W;+Ml:'?²=4O”q>%_:݄(F}!*u(]b;O=Cotk BP7p[ϭ\4/OoBrCXѫ,~[=ˎ Rā LjC/fUY\Pf9e'܃.ޠsj9mX (GPJNCdRV?{2{d/aY<)K~6}"Ư3t ޽p>mkNᐕ ?y!+>z <3o9itM[8`nȶq_}2utO^g#2Β=Ko~Ɏ5y[yg'es?e+8߼Љveaʭg8kr?rJm5^e܃v?C~'_ɣW_\us9z!7?cnBd=0t,oчGq%o5T_߮lC^G<`_?NZ>:u&>I8^lMw2JA#6 #S{yK>x:ށ/³@bִqqRg1׍U{<%:g' }vG~Gpp=i̬8JC+']7>W>¥:b#:}f70a|qǩXN9-^>Ũ&b8ddh_j3>"fn=2.?[v&s 9滗fr!L/ 5 UߝmFQƇZs +) iaw+^|V5KU2oW#v"I8閜x5_Jsߍ\q3䝉_; `a6_a 9- 1ÈVIp\c r f>A~| a]MV4۷]MŃkPZς?3sWSk 먭DG2uϾŲ05jRC$[.mpj*ImdKG,,T "^SjpXuUkjV u5i#(^[?䂏X=b-\EmsKNq:Yiƙʵ??v+J5"nW+ -As=?z0_aѕpcK~pJ_bY{Zz~K^))WfgSc&CO]\İyzV% +3 ȽhEW~O.gnaC;isn 1o9C k ,HL`Kx:z;6՟pY#q l_e™CmF;gO\G{0Zˑ#QxN v>1`}cyLbH4`mJA C! (z py9yW;QP vcR>pG/)ճo/ƽ g7SgZ5jդV~d+5{,Ͽfe*-JS37˳Yw\_zqV긠A~}VO:v? ~j/#%m_5We^+YCٷw{ZH| 8 'b9wbU43Ja^sz}{t2._+BA]O`roˋ}N4Gݥ$GwbXߡtGkxyT~mfeEP.sI@`zG;ǡˡi\@NzfkrC8ણ8//cL7@ hDRPҁ}{*T?Uˊ:U jHiЩZ5U8eu2xgyNxMU$I4xb ai 5UNdÈ\o,N/LaDI-BfiCƧyixi>V#z$k\/tTMvufP_+E uE޽ /WKF2j'Twm/Kw傓{qr~9@wr߲>{.R bojonz~?G0 ϹI}XFT#/˃#~{5]s]8KLߍJVcڴ +2; {2{feo@G`^H˨[DʲPE(̾{f! ֊xcM~(J5PڎRt`xO8O >*;M!8n+cW3~JJh څNw~5STpN<'?{әSBF(Ywg|ѝ)fIEoNHH8l{"̇x~iWܛkS*\ K9*xfe&{&}yf0yweE3rQ\P/L}h2GƝz-ϝh]~o:pHc<ƹ sܩE}y2%zk1-k@ŗNZǯ别+,3epwt5qx~s;3LLz?яDZWGQ6`GqDHz72\\vak~4x+w7bZC]8C˔fj9> IbyGc;|?0 31_W}ƕ\ǚ3gpǾmsW-c۬[>FlY/,EPǢ-p$6 YLӧe{͎RNAؾ1kT(3{;G4bXvKB#tRm?[I/<"l| i/nǨܗ{XGhI}³FmVDf B^RO idfO&|$E(G!c [R8y.6Ήo,R-8vzB-(q:Hp;q[gCaj?,˼fw=oď1Aae>7xqlT֛]kwh,atܝe ei#NxRAf}74xqlZjH&6+XA!e;aFhF  l+T*bEssl\TUPn5]z Y[]Ϗ w8&}GЁJS>G+O5 q LIiKV-]" B ^zw-|s0]ៈ@ivwEjMTxsǸ +;BJ"暇`aB)_pIpBgqC~c8*ۗÆn~ o^׬6ch*|fDڂ lsng (FTOz?@܈n2)GD]m'*G7w@&s%\473.~s <ҋ<}97'wwSvtxqǓٻGATyPΞxw?4~*>?uZLJӸKMJ_zG\ ]NG:}ɝ%2vC~hz)`ԁ;Sܪl3v*CY»_l!J߳^g=kvks7JqޜMۜA|.kQFVƓhQCp۸><@K&Lڏǔp]sqkw bn,^%t$&5Bdb%}+0'.tp O%g{rԩ00s#R3ݿL0y?w^.<csc8/Հc|߸xse8ZDd3E (lT8)'å}─h^Qɲt*VTAm6jc]yl_A,²-llT"H$%ܟDx|sQ:oqF%%)Մ2a ~;\0|EvVQq763XD lhT*52 P 41Lt }v^ {'rߍq.YƂԒWxm8 ʼnżm%L_E, IDAT;Tߍª MĻQgcOWŗ pEc7Na'{9bژUp~K9e&oԋ䂃=ߦEdD8oSA޸Ю][ Ś{4qBaf alYw .FyƝqYXփ1Zb5_s:Σ{b` #W=v-g].M#wSȐ K8it/p5mWrY?'Qҝ/ac{<{Njð Guᢍƥq AldͩCAtz=ek j %*-zsݴA'V,O7{v"|j$ lU#LkYf%:wÌDD=HûȀ^xhv ׮~;!^]άw_cɬY/L Ϫhuza_ϳݵkJ65\PA[tuS" B^b[)T7قQAء!AvhDABAaFPAءY B^86V*c雉֠ h,a>OPA;&dnR־f$v.#B( V*Imu"wB0 so55U[MHV#B( I%(kLwi o>}kTN()mɪkTA~D6W}wWiT&6m" B^bͺ$ ?S Uh4Ѵ,mIҒ&!A{|</"b20 6vTvN)//Eu y**ʩb Ca(eb-ӢE x-hiȂzA!oQ(jkl9RDLӌ`FL"/aqQoh'AEeYnqr-pqݶ-R䡾" B[.|23b(㊝8h, ˶юeX%%%L?6" B jFi׶ B8H0 I$XmXEiR 1BA!oq->\f],4Ю0 LӤ0l ˲MC,BA!˲"b{ݣaLy;uE( 1hbEEĢQPS[KMM-[nSwYo BA!ѮE"R8C" ^JQR\ e$/Xe@PAcvA|8XPq4-Z}vv%0\[Rf + @YlT*AMm-fZFLM.#!AjMUU5EDi#Q8"" BVj,&La6azPas#B( -0<%S(H$%La6T",GV pHCPA[ݜJ)'=qʝ2hD ƐeAś4G#Nwh1"Ao‹BGѩC,+i^eDL棏>#aؐ!\ CE( /P0v(ZC]"I"$J1M(u$h0#11"A˲( GaF :wUq"Bk(XA86h5e5 ]R $55D" Ca(3a2M yZ1 D"A4%ҹSg"Ѩ+m\ePAo4ޡZkmѵKg $a&h C P,BA!oo5-˶,۶iצ /0FA,Juu ibFLfHCBA!oqƻ SQm`&qi` p =-Ai0ˆD!x arRu MM!A(%oOrv m&j6 ,-hkg QZ,Ĵuؐe(B(  ZPH9ܴ&^SMAQ1i6" BE)k߉Xby3^BCAq1&"B( abFt30qnn4DZIűQ|*\ݰI –Rթ-8()Bزc}FPMAA^q˗вM !h}5e uS RڴQ8vD !tlAl-  ;4"  C#B( d]^|A֬Z a0 ڵeo((iٚ+( 3G¨Zv-on(!b*[i*r4YM;/҆ʑ{sMc{>P^]w_|GN۪i }S[S͒yoQ[Ym[قWqp=}J5pO倴Pʥ!)њzm[pLg9 #/M9ј~,sS[JA-0̭ 7-J[r !Ԏ` 38^*[2˻3"nϪpTFTAO hY#j(m8^C #8R)[;ˋGTVĿ5 "r=WJc; }XV;}rR6nc3LlPU`Ʃ@ 劙Ze>0&WL7}Ȑ//,;3?djKԲP6o!1oAl?˱=1W^Y:|vn%D+ԘNvRax/% W4,˕ڒor lDȊ󛠤ζp{G+7JV 4iHO y:ƜtCnDn]ej$G #$Y_wXϟӢ@$}T ׏RryWVדp h/1eG} `$ܥݐP6AaciR}p7iTޫvBn(o,b(OFg5 qH{fSe*Aڢ^ɶcC XJ5[] O=|AT~QE%3qֻKZ/{/_ E_|ALU{X:9rQasipFCP+vK{t3+hUU 5*7w*ݨ*/!3WA6nQwWR햣!N~6F.ʈt_/J?{?R .]AҌ~OBqxBPD DԄhVx[dy,n جϣe(=?V\AΩ'XdP$h6巼롙AۛvT(`[JifZe3@+W猶Kβ+YF(p Q d8zUC)01}Oʰ2ehX=|[&fh_6-8lQb"fMq?s'Z㋠J?G^r?X+[d0m(g<Z{.'{O9+3 ŋ4Ej,!{IաT}}GcB|* 4':O[whmI3P6/oQz Wz2QD %i„X/gX(E!ң e9$-2d2f5٢Y`L3me )!  MFnV1Z'-BFdTHXRUO˓J:$*,:KCqBU}qaKxy[\ʓz ǯƶfQOYu&0;myN9U?|k>o8N; LWU)r3׳LQ867]XK"y Mѡݛ5 limeYmJSLCRL[V/,?a`Z9i:?coKfkQFM6 Uwee6ȳ9  uË=3 ٝuAtZX;.ìx\N~t, q ]JJY TaU}iseg<&=;[~ձECçh= ?k ;u([zBJ[j;4UO0 _"mC, hedln,Cqt54 HEQG¹l3RPD תuBrN ʿ`y:=X hqYUowP#Ja*]סi^d [-%5kY!w>Wo _re2j]HiCԹǜ'/R #;Пoniɷ~!AS zEgDthɷnn@}[.Kx;,NtynNư iȰ[Y1zIz$BiHi;=;Pb~Y2R8zo4x/%(x+S\,x;9ׅ') 2j+Џϯmnj~Yku5| 8ોxUU) u]9kU?SrgmYutrjϨ+5V_I_ l69P#~r7[m;j%}{RG OV8Q01 |7!ИQzLHKF#uA:$&IK]J5 LC5.<,C9H k(x{;A _wT&fR[3EP Y2Gʳ3}ⲭE@Q6<6(Mr)M/'] ei N.v T~_сiZdZxvۘ\a]L^u 5P(w?UAJ-C} η24۶|,ha3gLh[a a; - ҐsbS/9oi̓?dt]/ҡ+@\ch2mZls3N( %2LÛ,p`zS{hthG"ׯs'iPsGS4%aµ<pBL:ma:D6rfi`t5~׬wrwke[}*WemT8R7'g꽀QUֵDCٸm(qFp2D(bLY%!-JNmON!l.~c,_#n>2ymyj} ufJTy3 ΂n?Eq˒3HrLTxu:?Cbr+׽?nJaSBe`QVM441\цuE$?{CK0|z|s>/G8Ꜯސ`f=M-e >w'CwLՔCW[M7&Ff +G 85~@h"ΆT4O9t}+ O5UhѪ,=C84^x֬X#]XvaiߎCâuvASRhUF~23-]8wQ3& ے Ž C#B( Ј ;4" MƬ}`[$%VᓴAa;Bk0LjH emfE'H/c( lCu--zƦ(IjE5tdMBAaYcΪBn4%k(UE8ĢBYZKޞEQuV,IPr 7' &Z^oXSe )"l~)F&l e,xiJElq 잵&&(Mdw][Yaiti= vNR%O֥p?j/G]XKtfc[5\2~ ¦&b*Ukq=|UtAAlGM}xx߭  l)di C#B( 5 ۶E^AaaY) ө!ʰssM)̈YA,+'yn׻tL7_O$_AAؾ1L3bkBhFwPPApEpQk~ڳ?^~AG(KdQAmAmey9AAA@AaFG [ejVfE$bR\X@`Zl" ֚kЩ=ՑJ֬_ˢE<}.m| M<ϿeytיJˢRjjY[k)lSjk`ż+}Iu]A"^շ?WNEZuSV6aaNWMu|^5ӯ/fPAdYTӞ s(+(#",x%kײf-2)bLolkĝ7_G?zDLZSľ%?s\ٛ=ASuA9|W'Ul+ق8Cmx9ֱ^:*c R m1>$=LLmZ;e+&{ }".hR$poǟ]Gsad9%g8zo/L< _U1ɢ=wc8/1g{ύ_RSnIQ#3oẓR*"(?yl/YZ˪*.a~j!UŊ/bٗ|殚ǢYQЖF &𣗣BhSl톧̺ pPÚj-n攫>&n9|tw;'\VdU_\<${3&C(Ѳ1+i3 8`cGeAv_ĒKXS۱P[U,/e~欙÷+b W-5Xau8JP9Tռ[hYoFa:jESWˇ.P2Xog='2x*"˙}d>'^ßWS~U8p71S|<=yWk{'́gsAlQf`2lDȉoT)%.&\u9Sۇ;};Zz7y0~L#< oXZ0N٢ZYv <,khZj?&2xb2rҜz{T3p2tDv0{fI6wj-}Ro/ٗ}Ng|:p=7GOdinƮ 7eej5eS'nJR5kײbJ]+X~5˩ŪU]q*5N$Z_RWh:-H3_-VUA3lǹ{|%]t1ŷ]j)0h;.ڷYc\9fܲ{+I>xΨd/p֯e8ﳰi\wpZQ!weqN7/SE8_,3N5s>U(gU>/Mѩb·\w@ SpQ Nͪ?qa(cAirn돾vvSNYb {-fو m.xMxuc_݂:÷?[S44[OEAxSNfsY:kp/elGs1kM34w=ӞjI?v{s=k⼫_ɿI]0-W k0"ʭ m4eI{DW}eYXJ r4NR>Yڕ]N>a'20ڧl}ܝ)(F iW  {+bsC ~~V2$3'JO` (Q.=>M#Lߛi2Y뮴̑}DZׄA0]Wo -h4A ^8{G0)5^f?=ؿGǯA},2"˸j/RƵJט*jGri6!!r63'0}5.x2׎_}r%Ziꊏ]Ѳ 7(c.SrK+?ؙ!̼?QɅSa:9fXd`ܮ1aX A\veaG´ DP]+O'=7 @68AichqԱÏVu: ˯5xY~>A%+ny'ƸyY< u8@jKbO= +'[1fbtLUJbWL5%ibydsJߨbj{wEps&BB8B"!!D@`YAY-CEKCPaPQ Ke]-eY+ B 9&1!@XKTuTz//݇(|o.S/g14U2s1{v$nWxDz%'Dϣxo9%;th cb;t9OE#QS2pqKjl8#eO[$zѽTUn*I^ nkyx t, ֤i#B͙jEДN!az].-Rà9)3>esimgE~G J.ljaBǯC`.lJ{PgvK慻VM1=Q8] :tenGXQsLʬdGq:} _}|/RJZz:]"7iM}O u:qd)g?)Svh,z }%):IT;6:3)s' sylAV^(Uʾ#/-2wחc=&(hf Nnk8̱Wz1bhpN|rG:nIG|PH0'nTl|'Iׁ4xu̺5֎W_DftQ*!&: IꙻMVSK%XZ3tdFo.Q3aa*HAذj z^ďM*صA}#{c*| %y'2*ol"8mk ,Oxdrhk.Og4=sYycjg&E/,~0#2'0Ɏ z2)X[%kG%֊E<?;г2S̤s*9k ddŰt՛@dsxKwS1De3yx4|QMbxG}Qo66ߜTrV]N5*l)tIiK4_|g C{?~!=Ϧ=6/I-/Ooo܌%<<a!Ԍ kޤ7&*(BAu!>Vֵ NGDS^Pmb"R[wEIBq).b:y,x5ۃ_JrԔld< Qw_až}5D" Wzrn^a <J1dbgXSdкs&_hj=5!cc+YL|v  .acr̖LsE}4|vW,0(6a!-dڸ-Deɔt.9efd9V<$ECO|x5bV{ť^Fl_:fn`\k$jKKB] >b3* gŧک0E(1Q0Uq9/ rM;q0z]Q4 #>%8b'ϊ<>H~};r?eئMve$IOv~§Pލa/x`Dpȥ*(* 60|\u}osjlœ{+sF]4*,-)˞_?5gy[(L$%J< ;>݄I:@h Ť n `DC) qc٢I..^^iTevUam=Kջ&WKf'OII){ũ**&bl5U@>|['G3co2{HLuˡ4*I$]qYUv}*Hprb۱Yh@ŅJ%*r߸Fy;6[L-^ZF%I+]\, Lg[~*CN8/܍Z9RKzE07Nn(2{a2\: Um4*WI$It0.g4o{ח_s B0[ז]__2obs C+V+gP5.o%I$4M%C 5+*tułhK$z]ߨP2xgf< L$IEgKN@[Ѡ$It K#;K$Iҵl)f<$إ@ O<=Lf3K$I>)v|VPj?J$I{] zq^5IENDB`sardana-1.2.0/doc/source/_static/macroserver_pool_server.png0000644000234100017500000370157412174204305025717 0ustar cpascualcpascual00000000000000PNG  IHDRV* pHYsR.IDATx t) Vنw (SdtA~ J;PSdL=4##"l^YB;( y  Ԁ'L^ @E8 >8 //)  %JHCp-$\eg #-=ooo<&tU -J6轻CEEЅ0dΤx*oU̙P CEuXK/0619t Ҹ zkqvR777XK,P "P  UP$777***ttUU" bfi uuF`4`tt%((`n{YVSFI;s݋"!555.;F^̿M[g  Iʫ;q##888 9GP泅'qqpyY="u%&LwGObUuR nlL! ڴ 8,`Pa1S* ^F&)(CJQ  fF  v II F7(',/ klk  l`Zlol(1:vJSŸ5AI H7((-0w 4icGP,,[R;B?yǨlL **ggg&mP ** CCCC$$v$/zv\hB' Ȁ(vԉn4>qq\" PH7  w~d8v!+dD` s' #SwS GR5atNNUxV\X' NC\.\.\.G`uGe5d3uG&/V+uGV+uG]0sQ/f>a4dY\uOb6""!n{  bZL#q ..cuuuoصщlCzV{YE"-ܕ|X'Gi߅| yc~ȀjQ>ӓSЉqZc@``V!٭P KLis bٽZ@S= *sx tyy||>: *"32x(nn<< !&*>: -+)hk+ 66,,嚉y`qoۑ%%wxDsbHuU  #(fw슩1%%DsY? ziM^B_C!ySf~+9kПbb ^AhП"n6...~dK<-#9*5-4ǬW)iS< J>R!  Bګ')+ ǪMg/ۙ 0]m{ù.8AH/,/1";Vz{" #]m{) # (0!+kK";;;$$$#up*",#"wx*"wxV%f3N`N#G:=kh2N$[ O\N G=k` `f3f3f3[tI^s쾐pppAI^sɾ.=M =p('&A.=M&I!! 1q1ffґ]s@8̇QA m G4{G4??\.e3 e3 tF\\.\f3@TiZyf3f3ZyX GX_y% yw1©_' % G1Wg4a>pGagmŽ)6Cs›e3MYe፹sGsgggzg5 }h6 sghhgg̻ }h7rD[qN`Ul9V2/"MG9 GWhXXMG` G $ N?[$ NU~ 0?Oj$   ɶ\.]_} \.m= ^wn)6CJb|evzF[nJb|Odz]`aB[KYdX Lф*uήfXaBN-rgф*uήfOQ`Q+F$_RJKݭSJK+FpASJKJL|NU&6|6`#S.x.5x@@@6|6h.x.5xL|NG' NUXX:N  ???  c_\n  `gn k>\ Z5wwv^5mCf8 VV\NӇH h /-~C  8|     ] 1  wn^ /Z1ԡ4t     qvc>˿))~%XoX  "  ڣ  "*a>dݵôD2Gap9H(('(Jжy :$HԥV֟ !'.(? Fݤ(('XPVXP ҵTXX^^YʮrT  }XeH '4ħC|lqs `n C< -mOmm2/q=6,(.f(.! ! d{ kM8ĺ=K1ۼWTN  4m Iv LJ`r+6!D5D5Omn3@v@=6,Ƹ,.QVVVVBLXVT OGNܔRZZzNV_ ,7:Hd:HKK B"7%*/_gTI  hx!,  мj. R:33x  aa" ))#~~+3xpyL8 nYU_FSS  pyv qjo&Z)&cu-  SS{{{1y _o%o dtu rO EA +8 6JA)Ћ!/3 Ji t/Q >@ PG)<:s=2k6X9''CC sAxu[+ojro !'톼H5$  !)]3 #DOX#,AB@2EЇ=K7ڋxɨ m7)  _4 Scq$-́6Y>+R[qar  JJJM7&&U<\bsEA-* ,,,,WWWiiiBBB 1CCCCCCCCC~gM[T'** (((cz{+9GseWbbbf3Ne0JN|Іzh^g.Y2bm5zNp N%s+m"Iۘyo4UهSLw]VDN`Ns᐀p}Nؽ|d]VDG>r ˫ aNx囕]VDÏDL~.8Cߋ`E`XZ|@rtnnxe`=qB+ff3g4uub4yk`2̞q+]}O!f4Ur *f(U r&"G"GNU #111  GY>RbiTbbKR  hggEE d9r  nOn qC\\.\f3WWW' N}喏; /fNt)K G G{&N} ʪ LR&|' in\\BG G 6V6V{| fg4e?Pb???}'3>\. ?\. \. ]/>Sh \.\.f4^0P*DJ/O`ہP%`/m ]2q]2#(8 HN0Ёo}`~; G`Iee(8 Hbb%I 0`NUՎ .NUXUXUX4Xi\.\\..\\C\( ( (  RR\.\V\\.yyy+YlL \.\\  `3 i=p@}W e7 zU0}[W)]/T~`2^0Тt}˻4EWtפʜdddf4f40^4EW>dZLwSa`-O&T+# G' O&T+#+Nۡi%f B GN`XU,% NCJ鉶,' G' GXCJ週L`%f@ BN`' ,%G' FxF@,% G' G' ExE׀ )NMؤHn EP8w7P8w7Մ*'i ,UUcR[aL  7)+5=Oez8Ne!)szb[&0` Ϟw@&77   PezKh{a@( ( xT=T=_L Of|Ul?q3BP\.  J%pP\.g4.6f f / Xߑ}aJ      r0π ֏7 `" *[      gNH7'&()+.!q| E       n &( {oE=`D!?:/ ӏ q     }L R-?+pv䦾`D  ;0 ,0:9:Ȳ 3E.S <2"l     g !]YT=q?GOOOB7!%#̏o+q ZNDD8NS𷱪/=C5::՗*rqo50 ;NkM7/sqL\Z/ [`f  yÙРMex-Lά"7Nvp^B horx~OI0::@fko``כ hTQ^B޿"AM8 kH-mMp>%ɷ~7( u [sZflϖ#U0A  "AM8 S*??ztvVkkif&Nw! m-$"y"uQƢj=ߘR_ɲ/NE* ,&FEX w3,t@[`o$0QE`D T ,tP >J_^Y=w-K)r %㳭&BBd|N$܄3$|9½PLϙ@o"СI=HP܌\086?'Tql$'UpKp O+'3$|_jOD4XOQrtqo  Qjn& *y˞4i;82QE4A@@nnGG33h͈P%G":Hފ!V 5.V:6/555@"M6! \/'/6'125YY )/4QyKUKSF6b 2:B"EdI!zAoOz #ض &A.8FDDh~V*{VyK{z;(O!)"(4>Ÿ11+ .3pR=bb A7IJ;HRő#  ``.3= [' c? m2IM J5 K6 V;=AW繊)聁aaa666``` sGnmW) Z.  EEEɨ$7)``xbzLq_:˜c`.!$7XGk!&*$y/l Ks[cuDs#afq!)ini )!$ *%,.FvݸwP(6 _4GPaa!Ǵ._> ekjQnD·2?I @* Q)" w"d: F9.s*2JwԶx ,/ C pIsfAKJKoPv   _ ~ iZwNneCLw 66~U*xTU= ..;;ݡ _lv`~# U˵v|r"%&V>Ł ] / W @ U11U# 񟣭]P>5Kb5K3;B3;Brcc+ *=>☈n~Phz1hlL1 "&> !@ij7u{sN:''iz$.X̓: JhqZ<~=9@  `X1մ p/Ѓc+!/#]8ΑmMNvϜO8lVl:=MN(ls/eQ7{V*t)K*Y'e' ~vBB+''' qyk' +@rf3 f3f3d7 ݯRR \.11hЊ oGh uO(&&qJ"X.~(G]tU*D\s\.9995_ %\q K  r  c),w H UGGGG GU3Q1Q1a(7m֋v^x^xNstP#ao4#aoݏn; b G {\AA\AAD"bI]qq,AAyyy@WnTovyyv//.nn/_ ...ͪy\.yU8BMĵp~*OtlwJtxKwN`Ԥ`)\NUNU}U-q8Cα0dK,\Qg؉U>{Sbm5zqcoR#7Nd+5 t]|yK7xxE"}ihj|OO NW6?``||oY[!f3f3CIPsɆc@|a|}6Zs#-7Tkix;Zwa|1?M1?M6Zb6 Gb ;Zw^1g=*4>i? q]|>UmJJKʹIay@Ztyyyʽ(6C]|3DUtX+RiRppp\.jg4Xl6H#:H(l;D)r?  XTmQ[y@JI  n uBN+ ! VĦr#cyPPj ؄L$,0 4+#dS'O w76OE|OG3y|iV!*$#!Ŝ$U6 MMM o  W4t@mboZL>_!" '=u<5 ը I@6 Ӿ0kGŪdmu M= F4 pL7cpv;be|BdkdK!8=!8:79:7voJEAɿ!V\`ʻ%)'螞9i7 W2|noQ  xBk6{~ %A1ODDCf2ݱֳyUnΊyg%Ǹ 8AM?H7?=h!V[>7   ` -wcw]zrj[uVڹÂѐS)5BJL"NHF5)6 LK&ѯWnWnz`.9{xxó@?0 ruqx.^, :8 O8 pP' _ 3g㦇!\t Dn>6 sQV 0ٞS+HXIg ++&S}SVZ9M`bc^84/|~?Q^~pS)Z^%Y2Z; ̈́ L"'S+ ڽ_Y94 itBE$?7?м0(0Kb"=ui!٥s=KVUkS+  °cH8|p⑥@ DL7nS 3+Y@ fJuL.ek%9!!S+$/}}}~~BE$0D*GK:zM_8Ul%NDktB-{*L >PV>'cF W= 9$/ =oI\X ` + -3)MX2MM оEڈDOX"' $HB ";337L̃ 4}̊)Jkݰ#߽@3ޙ6C652ޛ#6Ee hc_ueL%:WX X!!  ,.4=%xxxx ~~zq",Sԭ)$  4} !4q4W,W ,W#!C3%j[652$$$)) 18?18?ڳ|W( %+7Aû >FLYAQQ55DDcv9BJ*06 CCC&&&444JJJkkkiHJ)5 ڵ"Q,-< )4= ?G}4O NB,281>N'I5 =(-tt ******\\\E; 6QQ!SŇKʬ;qX5#41+##&+^C |ډf^ DD..4%%::$  ttww]C HOYEE "#T#û (En(EVUO',4ճ * (3 dd.m}"Al  ijkQNM10+  PYTTl== gҷI] Q#( 쏉{r  G4Q[R_]^(%%55&&U\T 6s(\]fff,,,TTth 666p`Y hh< % hu ,5 D3r޽CV@ #Zkz!&&L qCOs  |zc^@Auu͛e3eTTT]ؙe *.2ޔyy@]_).3$'']?tA``P`,3TBNekkdffhh#ZZZ6( _lj;; '-3'-3Ⱦ ꎎŗ*KKK$tP))a,VVU dggh9vefSdhpp%J5 '=>> ttttuuud))˕/kqaYYdX UvWW/gg|?|Spp LQ]._S& <^5CO{  k5kvQ ǛgwQ !E> 5Q.h& .  ۑ1ptO(2()uh>+ S`谄(竫,,,WWWCCCiii \^[t HɀU] }@ *3ҋ _= MM MMM nnnCCCiii(((|iL3DD  8% $*tˎB`PrxZ]wm9 /\ҥR槠CDN''(%DMC7** 66 9&a`.  U>;Dl 1=W8q.vҥRmx!($c JA9  G$,NH  ! bb 3)% CiWUH`Ǫ.v )1 [c$@6J. B& Z3n8Ux!'`:JosL 4  q;~J_-Z3U  (' rPesS  6mm*yvXy ! !-M-M$!  5-{  ݑ|Gwtyy샂b҇:%v5UX!3qmdd #%!$'  [iHBܺ^n !"m $ $$  #q3(& J^ePbp"*Ȼ5AILwY~** "%"%E l<#f22CPh /8@ $  >({Ջs?1NamPbp F4ttuu h  f $(Ҟ"#ʟJ[oi (30=G,1- woX!"!" 3& b/1B #8d ϳбm =GO %)(*-,31a.(C<.   jw㹘wY5J^ 2D#z p&+왔]lxphx 5<b/###@ 3 |}*< S8@uap} {xev 9@%/$ [~꾑o2+`  :+ +]n|' P<ddd♙dddaaa$$$PO9%:&-* kk kk ??????'''&&&YB J6hd 4mmmmmm-#j쐐SSSiii$$$U>\Z.|] uuubbbpppy#nk  SS+++ll jh QRQRHH&...UfvG_w׹wJi8J]X]Y4$B!L&N:xxB0%]:_\wN%'9OMeq]:_\w,c:A՝mRAs_qkϗ1awQ1ǯΖ>rA<&W?q 嵜}sF~9/NMĦ_<=B ⎄lR/ZhwQ1ǯX' ꧁d~W?q %ݪX3`t~X +eNUhsti.j.jeotjsl&g A@˞gb gyj䓁lhrO!@lsفR`BNY.j.jYt% A@˞gb {PS&PŁVl%˧#U5b5bN?m% v{EuSx&{ k%ݍ% ˧#U5b5bN?$ VN&rY;glFN=xcuu,'es|ˑP0`@ܤaG{ 5Yɥrq +Lwb$뾝lu2fML: 7.S7$Ð]ľ;h X*EZOiys5Yɥrq +Lwb`11 GGF|FS5oxo GG$\j\7[Bc`QQ=p=p GG`7[ g5fdf3Y- pDW?j kry3X} 序xqq  a3Eulϳ *BTguN(ؘd= dVrh7u_1,;JnVgxh6NkU : SSSK$.0t.W>aC03) r}$* jS>a 1qJ$6:G'Hxn) DbglJ'HVErn lA ] =\W<< H >XӿQnu]%scc\\TT -M癁^wNv2cJNv2c@ׁXhm]3݄thϱ.z'NixDT'Nix@<4Mۺx<ƁN $A`ZqxJn71_en71_ewC%LmpB G`` GG TTc6 RR  wZZP {{{ UYYYYs..{u}}}|||yyyyyy579V|nnsQj=Rh ڶ[/999000Xw0SPLƔն'/7Jh)6E:M`M`j7f3g4fN&Ic XXb/E5X0+٭%@k85"X' NC$ ~I*PfΖ>rA<&:SxV5S*gSXD$ ؁RSONchotjsl&g]^kYcaGakaX' [h8Ŧ;\ncS_'ԶO:bvܤaG{ ƁN$>6Zi ;\mϤq :KxR9AJypFFF`J|J$\j\ GG G1\1\r@ ffg4gg4  kwka=xmc```=JV!-~mAaakqqqn>ʜn&3?Ų*9G ɟqqqqql= ) stEXkIayLavN$}Lsg0N9' ӁUU~3 7ag-"6UdGNPqb.F B]}nQۚw#3TG!]GG77sD77sGGNN5x5׀ >a|LpCۏ6o`(N Uύlq}[/hH2dR{[/hH2dR{ф*]T'aGb@dllNm)M_K ջ!#B uX` 9>'PH7'PH7'nY^[`+PSwnE*****VSPj}[v%Gʄ/Kczy᭙v /4+ʈ9&6 BQ:\T3a4 lX+xӍ7dS(;ގ)3 !!!0' 6|6``` GGG`GG`.x.`~ENN5x5  ! p \ww  lr j<\RRRRRR   V1 5ET_1`3oy‹pppXXWXLYfNh®~i,,+\uuu\pCZoȯtooo[||||||tt*R~hRppppppV,k}k! \w,8Eڮɹ  .;HUm'/ȧt-#?PbSkk &kk˽, eeeCUh$.8}|pZE???s*+6C2@O2@O_1 nE=RfLd},>R0>Lflr>fC,b6 l)6EJfI ???TanPq~c˹Pk@Uj[y 9=@uN'ى[{qE>fi>(1:Pq_1_}_}=Qe=Qe `2_<j9&2>So&/\9n?;OcNh@Xq B?=rK$ͼzXOiE[qTqsssߵ^~&3?}`9ºBXn3DU3DU _1pB2DUDUCXnEYng9 ų:M`^~zǺ İPPPAVk#/< g6a:M`QQQlAVkk;UN,_8-8N9'ɦhFNW(8o< 9ddNNe4hguQ=v pUV;l' XN9' Q=v pUV;l' X`gX 4CrU9N @PJ~ XN>$ 9XsqhK' NbPCl9Xsb_XAU9N @qhK' NbP9' XN#=b9PCl9Xs`_WA E`SUpv1ʦ[[,)-)H܄z܉SUpv1ʦ[\C -)I܄{〩. 6[\'G``GG11sG` GG$|p. 6[\11sYnn` GG` GG$|~Q=v pUV;N9' X"y}Qh U9N @' aN<$XN>$XN>$PCl9`_V@R@/'/SUpv1ʦ[\CW-I܄{䀩[VPACE EHJ  e. 6[\` GGBxGG`GG` GG$| ***bbbbbb7ENq     ˸\.ZͿ234\z9L_ϹL&\ b4 ǫZ,,,jjjY  ̻\uQ$gghPf}]0\ Z2Q\\\\\\\ZVvF3nX3q=K{ QEk m=T.ޒ 9 x}WuyGA;-  _C_Ce  ^8n<ʚ1 /RNRL <<³-oM{ow -?K?N@Ul0?A! 7( 2#͌a Y.6Q*U ' RZ.>Eip>ϴulE$ ԓm%5GH3& 0?AX`s񰔡()NLA  ~ Qn8lC VAL_rF5">5*>ap?١ ]*-m-/PHD8޾$OePl4   ###uoh9u Z>X@-> C9Q[iK ?N "" >5* ݾ.D 4и~nFYrF]VWbox-!&ʳ1(.=^}," #   Y"J\q/ `ϕcSq  ū| !-!!$"K"u+  uuLc34k+:".D 9iw"%( GEOˏDVj55-3B9 |i 6zV.`*+|TNPtH,V0#1:41.4Xf b\H^`]о:a(&gUl  F  )Y& XD%N㳢+U0#RA.ц_>'k.+')u|_`4ܙ(XA0 j 4q  EZD[sDPJ.OL@%_I3)͜|:=RA.DTWh !^~ kLU>    |({) /r~63J@ qL*6S%'Fe1 44L@% R,)A^F⪌Oh()*ZdY7 TPBnnn;e&r+jMP9 6OtmabS9k&ezޗVHRt3 Pt_6],gNە4xQMPUQC 3ON B< ,#<*\# ~HWGK :D I`^-$- ޹#*FQZźA H'T ;=PMe;GFAh/[I) - aa復)Riatp:nx] 4! }  lk/^O%blS dG ؐЭ'3٩ SQO$I wWf 7FAbO,.a\LO37:Pcp Rjl}v/ '''IdF !ï5/ n1xR  }/d>87$#!|Cdf&P%ztY귵IK7P)3.;&AAA \.z8$. Jp\K쭪O*ZE2s:ײ/F@hvLʂI6m> -&c|C~ق]'] H# 9J ^բ$3f#51E.#7IKL-& ߫林o.;( '''߿< 2ƾ 66 D.W  ',"', ^Gw ʦJ @@BB>GO]'. . fUqq}U^f `!甇ãm^d԰ű ) )4IQ)E0l,'[ ޝaa%){/qu]u{f. g{&') l^<^>8AHɆ}V-x}5n`Y kN+ usO~'x}}י~j o m 4'u_ s } rctF $%nu 1;Fy|n8>E9>DD56&6M~ ȫ@KT0:badUT<; >4'deYZ/ vv 33<<$)#+1#%%$$$0"̶,~t:iI|liYG_@<)! )2QI4  O!*)FFF$$$+++dddưd ZSo))(-1ĺ!'$3A(3<, ﷢`V_ ? V[][  !wwwBBBBBBpao#";;8  ¹bgkG+fm! , `_น(\3 ? ^ www##5k d;DL~Q~ǖmw\1\ZY*( (kdjx"JiD  //BB 77**##{{~~~"""q [ҢG ?`"y[&/7+;222~~  eilK 76zz~~~$$$0&[$!/ 2!!(( #$766YYͤpF/Q   MF= Jm .-KKLLL77ˆ'-4_^_ J,0"7~sj2Ls-f@^3\onnlwAAAÌ<J Jz!;dS[ع-M_[Z +[PZ͝)iγ2211 '(2+++s{Ʊu%S -M  67'-2#(  EEEdd6(fGG;@MȰShz0f wa Erj>n=+>>>VVVb85KkXXXUj|<+ |ty~M1&M|gUnm|V?<37ZY$limgZZZ  v{+48Hv$(JU  *(#L LN[f{xvy|$}ʱk "^ˢ4 L@؝sK9)H˯Tbr j} uy VZlGgljh Ybe[=!1'  o.L1?/ '=.$~E=VPGVPG8s(K$.8 qO1hE ysm $睗Ggy{s-!)!c !4.r",4Y n#a     dd !(   '" ⰻqg7T*ztB,&.刺rJI0 0, 4D!Z&{Da3#f()$  (0z\  #\0m^Is ]ݘ1&- wS  39' *3Y:a@a: uZ^ tty0 h) X^ߚ 8#xP%"M,M,t  ʊ "y %#vn7>7Mse U:G*b(!]" {R&Y? L :0G|84+s %L77 W$$${{ ##HO RqGnrl [  ˞W[ʹ(&#E71( ov ̏+f! µAKU"'+Z.. .+[uu=Z~Fz%>H7$ DKU($  +/2iM('  2?I2?I$..ώ޴䳉oΡ~3>GN\h7@E EL%## '( e r0V@!D>`LB&1iPVUyUHUa39?39? ?A *((G5̴sq%󔹴 hHKYd1=BS(  #.yy& э   CQ{t} JV_,15{tw8xBҽp8Vˬ86:ayJ} +)2;C)/"/:B/ `nFwoHHG߮ `daȤ54:TUg~M,"/  $)jvǿBHNnG84('''    @]aaYc0# 홒yްnBt3:C,4<V8   AD2=mkt 6A2J7BKS]UC?5 ! ."%AMX a[T^W5zz{HNN!7+ )  FCIC !!!'''.P: feJD 00 ' z{WWWWWW$$$$$$IIIqqq& 0䈈81"!&#++++++tttnnb`E-" 0.!xx'''kQ ℄|YYYnnnM9@/ ED (1<.<.nnnnnn____F8*  54',;;;L:L:왘222ttt<<<O:L9 '%#/ppppppR; ԣq^~ CCC10!3 ssssss  (' '0'%ý 2 30#3EC!2]bg w@;6(.*...g4-$K%XbwN$X' ٭%@k85"Xb/E5X0+٭%@k85"`Bn8\!׺y=gdK:λy5 D8\!׺y=gdK3YBӣd&Q% }E)WV[JNMĦ_Vn2"t~ ,\w'[JT# qb/fKz3{OGakaf\,]]VDO+jQ!i,yl=!qx?h# 8Kz3{OGaka @7sߣl︃_c9# % ?c_xnN#.x]iQSQn!Bh# ܳ8?c_xxE8 ic5J' N!Ŧ;\nVb}Lh a mM) 8Ŧ;\nVbETl5oc pϼ4K%D"a]?k/4si3'񗒤bgNәQ"̪c{Ҳt$p쏇fqbwyV: r;;}g%&bDCtn:˯qUi$ ̪c{Ҳt$p]`d000 B3S?>i:e X!i=E~74"oϤrk. :W% \Y1 GG` `[[QQ`J|J1\1\=p=p GG <Bc` G1\1\eee1@Uj˰ɲrNjg<5,TTT999...g4  N' %1:Yr (1Ȧsz{~$.8~#)???- Hw؜|yY""1>nTTT630f##p\\555yQ(@TjKe}ó$J ;;}zvjdB:K_.=M.=MnnnrZw (zzznnnUqó~_ ZuW{rD!!!wξ˰| ]mZqcCCCxVhcS+m= &/*05Sp`v"-8 *5GW1q $o 4 E  rbS  jS> ; 3) rbV#: !um~^'$lxK// }Q<& >T 0"WSGVH! ^br ' CLJO)%N# P lk =N `eXsg `&R@pO H P \N9'ɦh7"]]TT 9d7U)~߯p-_ ߯p-_ NHbFN ă?q>9!-UquN }UquN }sˁQ!)ģ= ң= >kY/шjXId|n x̤rv ۚ@ D:^A8q=^A8q=ߋ[`u4^̬ X 4Crr" AVoQX =t AVoQX =t!`kISxv>x EEg ```ug,,ssXgYiL>>``ufaT+  ]HHݚAAA#0**rr333""J u $. &.1'4AqwaG#+3l@{\fnqpnCCC((( [2***ggg UUUUUUw06 )2:HemI   ETL{l]WWW f3fôg4Xb8hGG5N9' N%'9OMeq]:_\w:̝jOhS#X' ӴON1O$)UmͣeO}4oiSΖ>rA<&~I*Pf2=k;Ud-01V]Y:l.]˯J܄]hAK* O#AwU١WO1Y t =\cy   ƁNq‰." tXK?qb/f}˞hUb:1 >#% 5b5bٛ\v ,- 1ݍ˧#U& 'e$ >c+3ۑz=񗒤bgNәQ"̥oX Ԙ`t=jʠf " (&"Zw{;L0!`㶄QUz:b~X*EZy+|Nq +Lw~a'%!@BD1Txk8 GG$\j\J|J``7[vwxD[qwHzXdەpLTTT,,,45IHF(((g4g4*<w  HUb\u>Qc{xyy%-5`{2@O믗\}K_tK_t _z_zѸ CUh*3:AGj°NNN'09b?µcWvȶ ]9!rBVja{5EUAO]^ya4Jd~5ETοp5CR]:000b4>Ul&3 83r ".9hB[x1BR cAqo@%Vt$/<mbb8"555Tmg6aQmI[lM;*ttt֏jE(1s%+>>>ϚbbNDD ,7g6e>>>쥇i{yY!!#22!!hH[pG9 tFg""\\\ȵ[ynnnWWWn`jjj\\\Sozzznnn_eeeWWW>SfO)aR g\1XӿQnu]=mgN\ -MܾhKU6+R @~w !.Ǟ7zUB Xb{NX' 8Fd>鑘t<G S1܅QuYq]S &P}ƁN $A`~C0C06ԂcS|فSTiu{فSTiu{N#?d5QYS'b v|3sss GU# # 0 VvB4 L {vB4 L {GO, ZZ   HxS\n.x{..'! /r}Q!O^cN-{?i ) , ) ,  *ZrZN!] = ] =  , P1òR7:j,1òR7:j,N L)˗"Dn[lmXN9' cccc GGSS`"SyS,SyS`|΀%&oςN(}  ~7 1ۯG3fU{W7tg~/NS9N+Vٍ2&lZ)N+Vٍ2&lZ)P;e]E|kO'b 촒x}Wo Oe|-QK:%KzKA{_uS*| 7qbZ*| 7qbZq5) ^NkY[WoOe|wi   ~'/r}Q!O_cNى@Rd . qA: Nα,#gG$ *ZqXN!%%%~+8E#qpntVHw1-G9 O岙~CCC "(.Xr$/:Ϭxÿ8_=+1nP ]L:Pe{K`u ȸk;<;JVbZt@Re{|}}}|*2:a|2@O鰙#+4Rj8HX8HXZ|K_tK_t_z_zyȨIZjl!F[n+sss[x!r ///@GNj¯TTT/8B(4CvLdsssMT]uN'7Nedµ}`Wuų f7 (4AQm(3(4ǹfĸ(..a|8HWDR``zt$.h`u তb/16FUƴu 6FU%0=/?OSkzzzd8 c5 6Laų%/:p"*|Vt>RgWWW)3kF[y1BRoOrCWu$/< Uri8Oi Ld}KawSng6aQmHZkR@/nnnķ݉a;(1s"(555$/<i8 #/:g6d9555|\jnL؞bbbpLaw=8 n@oHayaHgbbb¯VthhhʻMMMRnozRmuuuhhhxX___AWlR`p>ThȂYegӊXӿQnu]ąlF@$ -MܾhKU6=@~wO*L鰄eooǞ7z˗"Dn[lmN9'X˗"Dn[lmƄg}鑘t<΀%&oςN(}Qu΀%&oςN(}Qu[UN0O ƁN $A`~~7 1فSTiu{N+Vٍ2&lZ)N#?d5Re{#3TG!]sssK: Vt;M`4ld}TjF`z6HZ  AAA ,:H}tluldvvvvvv '5B pppꆆ vvvcbbyyy:;<pDzzz d:J0Ŭ{j^yͨ ]8!Ġ} X555mZoX0qF\XUCCCmmmg|:Od~999d}0?O嶚MMMMMM ")0So$/:Ѳz V0zzc?./sRg41B%xA !. m 5$k;[1 ]quu  K&~7z| ,J)9 Q"G $f+@ x E'H'" !K*{C)A &A;    $J(C%   Z;ҷl [       eV9#'  2L*3 `Pdr~s;ECO1D>Xe7\EFA3-i0 "1?    ZD_A)!C&K) ":* (%%'jq{ %P]N9=3!)!Y?Y?*K*?" }toL3Ilz5(ٿ.'AMGDzP@]Nt~g  Z5 +"!GZJ  G2G2 :"M+-rͷ49K.AMGERCY 7mɓ ۽9a0C+ŚZ;fZA-HC03. rqhzql  qOqOF(K*  ɓ5,V.88A<{څX&Fw_U>?, sip@1"ξLUNU'*  ++~X /N+9e8 6l'PѸb0Gob\] X&lPNXTWF  Ƚ( 3LUVD#&.%:J(>O >J^O"" !ĻLA,(@  6'6'qO>$O+*HHHчŪiM/Hd/Hd. 788Ec]^R`X('_Ue20. Qٯc9ADT9BN$0Ƴ9A9678 %0 T)"&@46 316  J4J4آ +Y⼆{{{uqjimr \i[y HH{iMR`[20. b9՟">npb?Kd,>5- Lf(FZ KUb 'opn$"*++jj^! #    tQtQnU;+ wwwTQLorvK aJ#ʑ 3l#)&N G » \fUt}czwG{i7F&&(0ț!wcDz{znYL(5usq1vO п9lczQ}X zo0Wv1 3®IXarRŴ #,ķzhe K++ u "%   eGeG&micxy{!8P ЛM>"p P>BQuLWȆz, Xub 0Ht89SzmSD@;\u,뫮sM(dAmcXÿO& ΞL:Ƿ B = Kh )     ((X`n --,--,nXܷ~~~ZVP^[Z4K-&y R. CzŸ3+í[2*Ğ֟}Q+ fgv3NQ|F bab  뀄ɬ3R'K)$"9KC@ļL>U ഴ *,B !h&zh,) qR@/ " kI8Q`+fP~8 .Ҧ)|T5(}W9'G@^bIlըƮ:n͘'g~[_ +޴#/}oGX]\ٲ 0&32-TG4   ZO൵&0F#e T> rS6' ҙHOHOPxx(#+"^d";?EL'Na`67 &2G]]-*vUP9  l  )!D &X@ \4^0:FWNM;^n>i&:`z6, sVgf[E.-AxY[biUD Ҁ,:gT6%K4-yY H 9ZF@< LWd ػ,; .0. #B0 D1    XS c |+Q vi4QC.]T +xuY> $# wjb)#(#~[# ѳ)J]SwF>9۸"#-0(&$5&;*>-ʂmӊa5\p` |s,W*{X@ bG2$RKyy,8 $H=zgNR#Ӟ&j5  yW=caJ"t00杣t]C$#c'%<{&`J1\ /M`ggg*-.6=mfTӘJaȶ %'0ۣceg8K( #C0B/  7.c@3!(,&fYO2-7/7^ D :C+o_ ƅEsSu}.hS%eI !.9sl 3'?U+ Q[[VC Ԓ7 <6"<6wqM++_C "hƶ𴟢Slt ݩSD4 -)/F9" I HVP\&7'?/ 89횶 gA/?-#BX!%+7,5/C14g ֛ߑaff»-4: $  8?CkfaHA" J^/W_4 ZA8C989,%\lX0ksA[ܾMn^yxEa +$ VuVu pzx 61 #bb#Q?3SI4"# 9$"p  L7 L%#- dq_~A  Gʼn  5c  ТȎ[[ Vcnl=abJ!F91DBAA=; _p}Y! MR).N6rS60=.^CD;v&V m)i)i* x'a +0   ú+8@+⠐%"2xD'˘a6E?#!$\QIE0:? +-IPQy0HF0`O ;)4F2 FA @=j Bui}":)?.  j<( ٕ/,.5 z0[%Qhѳ 0mp vsv)0 ȾTh%178Z-&$^K`zK2 oT=PLNrnll ئZc7  bD@MMS+,v!\V= wQII1;?BBBe6Hi2  >oD uL 5%%U)  ׍ %/8%*k v &NLW\ oN6]-ᠠ7_Ün $"ܞǛłfE~*/4BO\ Q_@Q#yEg&0*v  P4~d8K ͎o#OR#? ܠo=gY4YM`Yx: 4d!¦*>ZĈy63%5=6iV= v/!6&P uD*bb|x¼5W(*OU_ m_o AB E*B2ÛllÜn33  $$ #"%+  =CH olϬ$2#cqq0I!1Fn2r(8 )]WK-n":$&*>Z]  Ń  ?uHrDzh-`^?,g   ';Bq{ ." 9C9 ˚ ]^#++8B  qq0 '7#"᪫ٮr .ZY2n΢;inbbE)7/ *G3dn hͭ2R{$$BS@R T- ":!(-gT+:::cc?y DŽQ3]=7L#"zGG)((*5*0>>  AAA}Eˆ666gXL% @[9[9d<2 &=<=;:;  nػ A Iv4&2 xur !!!!$$$J}IX $5n5_iq%  B >+ &?00//fUuQo+SzT]bT1[6!+2q}SD3+ڊ 𸸸830#" ooo<< P:DpbbVJ &,ͺ.BO ɿ"%(]>ƛʝ1!*N KlYfSgLF)ff29?aR:ꌒ P *^^^^^^ 33333.!4"48.hch qmi 8^诌  |bD  sᔜ.'-]\]X1Nl tmmtt,.0 %*! 33((rrr9:Aէ۲ii&& 0 !C3?  Ⱦ /!  K Kkkiy * > !%iecMhM2Z]^tY| k`n >?ɴd9#]&Щg4[M*f,f>F  IKʔ::66BBBAAA~Q!!!gr|dI2rS4[=!% /F4A嫮0,* 8* XRWUTnjn S   ; ;"I JF~Ѿ  hz&&&KKK -Dp8pddN`-\P~( ^b]WMF@÷0 ¹$]]+!rmqjj᪘bt؄;;9BDA qoΘ  o FD;;;KKK ܷE"EA D//*x„{={a҂&&&&?LY,,.9FP  @/nu!+!O/*#F6)y~v%9e`#Q!ot&ځ)`ݹcGwt: }yt  giZ#I$IHHZۈnx$$|$|y..==''Bccc+%뺹 "D7ڞqDOL5"otځ)`#Gwt:  ))H$HZI0rx% %? ==__BQ::yyssE֬T+T::LL,,;ccc1118WlZ51{vz vGGSqC&&    .7@!.9Ƌ~?~ff$+ X,XaaQ::CkFU*T ~)5555r++#(瞐{}ƼD#DQvv!} &&&;;;JJff%#!XXY h/G 44߁!!k6kCAI F+spp||(w@ @{}bVc=:DlQvvp[[~!c]lll&P0̼0CM0BQTNO8HU/G 4^֢r-z\IO +,-$$$핓ZXVuuuttt```PppI5lGG66 $$33OOڋ&&!!" Cٖij%%+߿A!A|nwl?b^ceel͚f3fqq[??! ( ']\]" 7AG(Dp~ LI""YUS ֢rz2\O luz lnln pp~ 66$$޽C"Cms" 1*SS%%]]&} A!A۶I%IV?ʼnw;wm>>ee!}}f3fAy=xÆz=z Y]]G40$ spr pXjD5vI5vI5  |l       -4; C"CggM!s1*>22 ~~J%JKykw;wPP..!~y~xz=z00 ?H5 ]B ~*(     W jblhy y M IHْ~(o22yy|ee| * bbk6kwwxxxdZ Y ׺T`Ai `y55 XW!! ׯQ)Q(oJ...;% :PJ(.. ;3 Cg@ K## X> {P uU (.3 nb T> . N&# vW w  -6U    jX8xHdd-rZ r @G ՝(AAhh2277Q)Q^^^>>>(^6=2o`g6PeͼoğQKIN}ช) ...---MMM___ ՏgRmUT _C _C rƣsss 333###QQQ//////111111ñN110"""  ((XX(1970+ &iiiiii (((((( IIIQQQ'¢ 332>?>%%%bI>`%%"a>t5+"H !]=30 "lH! ===''''''s/ `1B߭!Sc"\ޤ9nOHFH=}A?NgzOW''j, '1*¸%. "mmmL>wOt  :S-%n5 9uf" &4}~R)BU Y+g["!Sc̔(<+Ѵe(` ssss 243xF`Y〵5=5(!ss ƭ}* ޾71fe1F@I""444 xEwkKts?" ju~wy0WfxbU8^mR_{(29z^TEAA򓍒paSB1"e112 ]5 $ 8$3kzm앃׋ 55IIRTY+,*. %*  (& 6' oPv 5Fv{-!Q^}9)F&1u|xn"0T72! . {ro    >%&&7,(2)N^8N77<#AC <,e  I04#' ,:Rto=J        Q:lJ R- 'LI$Zoե: 9wW)?e B+J1+ 6   B6YVNWr9- U@ gN FqRtp$)e.F$:$    <'I1(, .C3  V;sO4$  gnR`Z}`k0# Ѷ] 'G.+  33c<   hFI36(  V`df(c"3 dqxEPK  T/a5  Lq ^@gG+!  CJ||))q,,   ,     ?0I@]<_%LbD^@   (( FF]Y ZY{222 L 5e QfA zoC" o Ze)9 cBfm,ШґG#_   nnqq ZYQ6洆ѻm!4&&- ZZ ffpTQ h T}X0%ZBS9Ր  p !!rr^^TUU=Cm q  Ɵ4Yh5U' -ͳgcrMt81 G  A ݋e o]hG)1 ?O uw5q8~UA6/lt\V ;X,jlcc""Q tofR=+7X3Z;?8)H?1 ! qg&6 !"# =)|YqByk" G1"&* !+gB QQ;ii;; @*$&,Ȥgi:>7317=Rb.C o   :AH !23xznر%6SʡϸqP}Y #(utwȿ+3;@LWZ_d$,2:> LL* #%  3&  #$.55K|@0'\{@n  \\pP#"6   rZYY[ZQ >O]¶6I%Ǵ#8dJ1DѵHiWr!& HA[718>&,1 L!( $7[)BY@I@\u<3 ~kf'<7024462-32.  [<'wJeϗ9Eǿ?6G0 (#!"j3 ?KUHe~V JKMj6=D,3:   7= BABK   "@j0XA)B*  d "~¸ﯦ޶AIR 2-  TS51fc&FFF +֨ GGGEEE+++ :+ YX /KKKKKK @1۷444@@@DDD )3%  [Y!gc%$  )222222{{{   Q=⡡GGGDDD,,,&3' , ﻻnl WThe -######ggg %׾pHHH&&&BBB $2&  럞燆:7|EENNNNNN3& ؖٶ1 pnFCro abab444||| 腃., DDyxxt IF ____mm ]Zc`$(   "*PD9FFFv|k=QeHIIxxyEMVɻbKd}Kd}567=6.|`&3?rddd|O$a1///$C"XbAV)ůcV:X' ʊWH`hF Xb'fOtx(ʊWH`hF  o_Չ\εfM.P2Va|ji:X' 赸ge!{kjεfM.P2Va|ji,Cfz8jZ']fzxﷱod/C<]kby ]kXL@ʹ:X' XOab<  1K}Kl`ZQ*]kXL@ʹ$YjY&D%p\l`ZQ*]kXL@ʹ:X' LL4?*qx@ 1K}K >N4V0L* +S@Çy$=B ݃qzy: Hsj5ۂu| `p 憎x:62s~Q ؉9Wrv>(B!fI 4,:"0C&1.9Rx_2GEnj4 憎x:bqf><蠬7O{Y9Rx_2GEnj4 憎x:MmvϨ@!(B!fI 4,:"0C&1..tbòl%' ȴ|7QuS *?=ٻ,?U2%~o~,@Y7&AgM &_rƂԵ>!\x\ӜLQ.ƿMɭc4,@Y7TUrĽ,e΋!s/ƿMɭc4,@Y7!\x\ӜLQ.RSnpG[r-Ձ7 <;aB,)Zd $9$9]>f߆or/L3  =S4΀JbIm3T</L3 ޢ >`$9$9]>f߆or @N5׀,U?/N1Ӓr )-5ͼ־,wE ܃s oav4:@׷.S ֚ :c|7 ;esS 49CմѸ&~Q q=lH]K)u)a_ךr,^ДIUtI 49CմѸ&~Q q=lH]K՛3ff1|7 ;esS .wasܪ:RuP ;Ii=ܑò` HPW:Ѳ`:X'mdW`Oe_u ijfnPn&eSL)0#|nnZWW7 fo){lPl!nPVJ DOzO~k ,}& fo){lPl!nPVJƨX(j[w$0#|nnZWW7 ,--} \1,,, G`XbX G`C{C| W}W G`KtK 8l=i= G`0x=i= G` G` 8l@AAk+9HzZ;$$#i6KCYoTqձvkkkwwwwww=< &}ˢuJ555 gggg4g4r O( )**usqUUUDBANdzQhw=dI]q ֵ~yy #fpphkkZRM?Qb[u[uVeYȹCCC@@-nnnn{ ...iik[3_ssq11RRR SkKav۱ʽ ")nn{A``hhh,04&2=Kavv"*ha )3kno~~FсcA{Rn#+m 1106~~SFm 222 (1{S*as#*ȸ*** 1|T,İs(41BQ#0; )4'3?-./yyy*.fBD[rϋe= z;Pd(1(1F\s &-ڸAAArI`xyM $0= ~yYIJ ng]""qqq˻o b4\\\eQlfwiii\\\BYnFYmrU6G Z Vc  } S( Y !Z`  #]` O C  <3 b^= We?&<3 b^ Ux Z an[ @# gq! o -*  2 -#D+ /q!6L w>~kD+ /q!:S@ M L//h E>4D Z Q  `Q:3p T  D 'i Y  ?,E   l K H)cl K HXb !5'E\,' Y  1 C|Mb nnA N#[` b:* >% p-nSHw  p-nS:X' Tv5hzV>XXSS8('nn'\u#[q rK |J $\ED5Éjd{|J $\ED5Éjd{Ye KB20/84 $E?LAS[Mݴu !g[K  +WҩK%vB4K' Lk'swobvB4K' Lk'swobGv, 0>(ZNZN%  4b 4b)'! /I<֬Ȳh!NL]Mƶ}8ws+) , !G+) , !G *ZE*ZE܄ri^!լNn^K1Gv7_HD3 㾄,k[1Gv7_HD3 㾄,k[Wpo("ҬVp G`&7&7^I"77%#SsS"77%#SsS G`N|N55x5r"+5012xy&&/ zUnCC- }w444Ƹ X}QQǷ⽽G29HVgǸ,9H  0CCC@@ *2mqnnM_33CCC!!!^5kss&&33$$##iknxK!( ppppppVyy %%%hggee<>?h İ&0¶ppppppppp+1N1prg4KU`11120/|Rywt4}}}l`U$/;TpTp'''IU_Xu$/< '/555%#"kkg4666g4$"!Xb1c{bXb:X' Xb'fOtx(ʊWH`hF :X' T}nir:X' 赸ge!{kjεfM.P2Va|ji4MXOab< XOab< LL4?*qx@ 1K}K”g!62s~Q ؉9Wrv>62s~Q ؉9Wrv>MmvϨ@!(B!fI 4,:"0C&1.rƨX &C193&AgM &_rƂԵ>&AgM &_rƂԵ>!\x\ӜLQ.:X' ޢ >`$9$9]>f߆or4:@׷.S ֚ :c4:@׷.S ֚ :c՛3ff1|7 ;esS  ijfnPn&eSL) ijfnPn&eSL)ƨX(j[w$0#|nnZWW7 .14x$.d___ G`KtKKtK G` G` 8lZ\^`7J\c4Ƹi6CZqTpT+oonoonB9"-8r|^A555<<N,;J#.9MLL9+&.ɺh&03CT%2= )4$/<nnn134>s`SSj !!rPjʹ_ eYxYxĵ򦦥RRRtULd} f@8J]\z+;J~MNN!!!GeeVO 555BVk|\{ $1=UUsssG^v؂X."-8{ F]u_v]kYȺAAA &DDo?,;IEXkEXkpO W,hh_R( pv j9 Yw>Rgpn>6IZ[yخr 68((888^7*7E>RgCWj³777e>$,[yRp:::9zRk[6u]tuY<55(1 *3"-8%/8Ȏ4+U>8Xb !5'E\,'蝞g~'ow71J5:X' Tv5hzVrł~WU d~ߨX1P/߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98! VzV30n0n G`&7&7^I % : I3 : I3;q:dbIg0|pnYDo;YuhaJ0zXb:X' WDo;YuhaJ $`{4q˳_P/LW݄tB)w_hb./ o -*  2 o -*  2+VAV)B 蝤AH+ģ)=V6 Ol}䨖Cģ)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n|G i-V{w"az S_i: KxKǒ AkpB i Y  ?,i Y  ?,;LwQ}w- ,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B Xb:X' Xb:X'  b: b:/U==L.  A{?಄ot* At6  @Pzc]N]"A{?಄ot* At6 !4zÒ@9-ta=*Ɗ\ 2mBKC$(ٵƠ !]UT4 88 G` "uu G` P`P 5e P`P G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ$@0Mq98!ƺ-:F)4?Ͼ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW߆tB)w`hIJKj17;t7?H$. '=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4>"/<%.{o|)+,|V0 n]w 341,LؾjC +~itaw  `g`KxKɔ AlpB ԅ_1v+6C}Ã%zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C! 'G4'G2Hd}B {{z{{z`abgFJ`uWo˻5EW㬬W1L`sUo ȶ8J\,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒB9-tb=*YZOj*8F TTTJ>h8K\ 5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?y  =@DY/:::```l;  ^1w+6C kkk99ATf_z/nmknmk]]^gFVpJ_t!* 555Y4&.x$..''sؼs000NN5 ue x&%%TTTTTTmh u***r w^^Ǫ2@O İƽ|||zzz ʳKav ܺ3뿿 @Tf]weɹmC굵MMdY..CCC qrr`2k5CRèo\uuu潽F1N,;J#.9PPO2$~$.8IJ%7DP)%!gUADXk‰gF$xIc '4A'4AMfZ124:JZ-:Fm8I\m33DU:GU___G?7:K[$.8˿wVToBXnBXn;땖gedMbxrH -=L #*?D,sрY3Ng nvcc(((xje (6CʿUUTl  PPPWpRj..zzz!sJ#Rm)6A(((˼lï '2MMMmmmKc|U+%/y Ib{b{N[N¶555xL zAC pA&2?I]qI]qlK~~ _8ݑoNK  j:G^uNh㰌ij9 UqBXnsqB+:Gxেgr_8#.:NhPt===_9'4@BXnI]qĴ999f? cYy===wk|cP<yTn]9s`wx\A *5)18(3"+5$/<'1<޶ſ "1WWU ]mbbH⧊%DwJXHd~ߨX1O_npedUtAZ% ߲-!=a>WU 羍0$AiBSH^nedUtAZ$优ĸ$@2Nq(#jmgx 9oV9oވ~LR3߲-!=a>WU Xb:X' Xb:X' ]mbbH⧊%DwJXHd~ߨX1P/羍0$AiBSH^nedUtAZ%伖Ÿ$@/Mq86 ii G`&7&7^IϾ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' $`{4qYDo;Yuha@a2m ؇:UiaI $`{4q˳aP/MX݄tB$iivϾ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' ^2m ؇:UiaI $`{4q˳_P/LW݄tB(v`iģ)=V6 Ol}䨖C7@I%2(>kYģ)=V6 Ol}䨖9Aȹ'GhO &dy{䩛C(>kY/8W=՚óa='4?#0=#-{r|ģ)=V6 Ol}䨖C7@I%2ȹ'GhO &dy{䩛C(>kY/9X>ՙ´a=&4?#0=#-{n| 341,L   `g` JyLǒ :v|T  341,L  `g` KxKǒ AlpC %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j,;gKΆ+m:x 9uQgP̉_2D" %F4%F2Hd}T %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j'뷎,;gKΆ+m:x 9uQgP̉_1D" %F4%F2Hd}C Xb:X' Xb:X' ,z,̡ňJ !0Q4R}q A{?಄ot* At6  @Pzc]N]P A{?಄ot* At6  8xw{1Q=|.'!4x!Ŕ@9/uR(,z,̡ňJ !0Q4R}q A{?಄ot* At6 -D}})8aC[5Q  @Pzc]N]"8xw{1Q=|.'!4zÒ@9-t`;( Ɗ\ 2mBKC$(ٵƠ !]UT4  5iK5i P`P G` G` 5e" P`P G` G` A~WA~ G` >xT>x 5iK5i P`P"*`*`"J G` G` 5e A~WA~ G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ$@0Mq98!)4?ʽ+6C%/:Ͼ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW߆tB)w`h .7>p???r+/5u~7?H$. '=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4>"/<%.{o|ŽuVmwXk |Ul 341,LؾjC +~itaw  `g`KxKɔ AlpB r8ӓSЉqZc@``V!٭P KLis bٽZ@S= *sx tyy||>: *"32x(nn<< !&*>: -+)hk+ 66,,嚉y`qoۑ%%wxDsbHuU  #(fw슩1%%DsY? ziM^B_C!ySf~+9kПbb ^AhП"n6...~dK<-#9*5-4ǬW)iS< J>R!  Bګ')+ ǪMg/ۙ 0]m{ù.8AH/,/1";Vz{" #]m{) # (0!+kK";;;$$$#up*",#"wx*"wxf3H$xxBNN{`@xQn@NZ}g=}xdJ( 'N`X KCN @س&B ZQiVXy : ###' ML:'up#f3y\.%%w_0w\.K.=/Q(5 M IJ\VmtGVmtSaNU::Ex GZ#$$ \.  ###\.  `2\\.\ t) Vنw (SdtA~ J;PSdL=4##"l^YB;( y  Ԁ'L^ @E8 >8 //)  %JHCp-$\eg #-=ooo<&tU -J6轻CEEЅ0dΤx*oU̙P CEuXK/0619t Ҹ zkqvR777XK,P "P  UP$777***ttUU" bfi uuF`4`tt%((`n{YVSFI;s݋"!555.;F^̿M[g  Iʫ;q##888 9GP泅'qqpyY="u%&LwGObUuR nlL! ڴ 8,`Pa1S* ^F&)(CJQ  fF  v II F7(',/ klk  l`Zlol(1:vJSŸ5AI H7((-0w 4icGP,,[R;B?yǨlL **ggg&mP ** CCCC$$0?OB3#f3jg4NUV9pa@xg3gN @PLO1xv9NXr:4bl3cÐ]=pQ-ӱ11[c=ptf3f3 4]ѣ]]] 4]eCq+]qW,uGC">d  -.vG ^*[UNG*c}SaO3}Z\. rk; e3\.NӇH h -~C  8|     ] 1  wn^ /Z1ԡ4t     qvc>˿))~%XoX  "  ڣ  "*a>dݵôD2Gap9H(('(Jжy :$HԥV֟ !'.(? Fݤ(('XPVXP ҵTXX^^YʮrT  }XeH '4ħC|lqs `n C< -mOmm2/q=6,(.f(.! ! d{ kM8ĺ=K1ۼWTN  4m Iv LJ`r+6!D5D5Omn3@v@=6,Ƹ,.QVVVVBLXVT OGNܔRZZzNV_ ,7:Hd:HKK B"7%*/_gTI  hx!,  мj. R:33x  aa" ))#~~+3xpyL8 nYU_FSS  pyv qjo&Z)&cu-  SS{{{1y _o%o dtu rO EA +8 6JA)Ћ!/3 Ji t/Q >@ PG)<:s=2k6X9''CC sAxu[+ojro !'톼H5$  !)]3 #DOX#,AB@2EЇ=K7ڋxɨ m7)  _4 Scq$-́6Y>+R[qar  JJJM7&&U<\bsEA-* ,,,,WWWiiiBBB 1CCCCCCCCC~gM[T'** (((cz{!g9 H$tK!`1w!L`b'-n`qkN'ޛNr݁O#x A  b(1o9/ߙY<rQ$kNr' YSY%߁PSPeN1rN*N`}5]$&j!u&TaYBxBrQwS_' /u`wc' Y`' #s;\ni6f3 h:  kkkTk^1akkkPg}ķ}]b Iyʞq3DUbNzG  .Z{E"f\'NFG f// G|{$|T|I[O"wNu&|6JKv f: GI"yeyeeq{{qzzzz]|BSf f999 .6f f / Xߑ}aJ      r ֏7 `" *[      gNH7'&()+.!q| E       n &( {oE=`D!?:/ ӏ q     }L R-?+pv䦾`D  ;0 ,0:9:Ȳ 3E.S <2"l     g !]YT=q?GOOOB7!%#̏o+q ZNDD8NS𷱪/=C5::՗*rqo50 ;NkM7/sqL\Z/ [`f  yÙРMex-Lά"7Nvp^B horx~OI0::@fko``כ hTQ^BV޿"AM8 kH-mMp>%ɷ~7( u [sZflϖ#U0A  "AM8 S*??ztvVkkif&Nw! m-$"y"uQƢj=ߘR_ɲ/NE* ,&FEX w3,t@[`o$0QE`D T ,tP >J_^Y=w-K)r %㳭&BBd|N$܄3$|9½PLϙ@o"СI=HP܌\086?'Tql$'UpKp O+'3$|_jOD4XOQrtqo  Qjn& *y˞4i;82QE4A@@nnGG33h͈P%G":Hފ!V 5.V:6/555@"M6! \/'/6'125YY )/4QyKUKSF6b 2:B"EdI!zAoOz #ض &A.8FDDh~V*{VyK{z;(O!)"(4>Ÿ11+ .3pR=bb A7IJ;HRő#  ``.3= [' c? m2IM J5 K6 V;=AW繊)聁aaa666``` sGnmW) Z.  EEEɨ$7)``xbzLq_:˜c`.!$7XGk!&*$y/l Ks[cuDs#afq!)ini )!$ *%,.FvݸwP(6 _4GPaa!Ǵ._> ekjQnD·2?I @* Q)" w"d: F9.s*2JwԶx ,/ C pIsfAKJKoPv   _ ~ iZwNneCLw 66~U*xTU= ..;;ݡ _lv`~# U˵v|r"%&V>Ł ] / W @ U11U# 񟣭]P>5Kb5K3;B3;Brcc+ *=>☈n~Phz1hlL1 "&> !@ij7u{sN:''iz$.X̓: JhqZ<~=9@  `X1մ p/Ѓc+!/#> lC _zkAVk%yQlTk}QlPg}*19i8zU,mg ` t.n<U C-+F!\yv# d/' > fN z:}Z 9N-_f; LN-_f; AN}Z.[^K 1S S vN!mڣ)bd\/ _1%SW/ _1%IZXwޥcS(bd&NcS(q>>`3>Dt>..==dUUU պ.FmYF,,, Xl6H#:H(l;D)r?  XTmQ[y@JI  n uBN+ ! VĦr#cyPPj ؄L$,0 4+#dS'O 76OE|OG3y|iV!*$#!Ŝ$U6 MMM o  W4t@mboZL>_!" '=u<5 ը I@6 Ӿ0kGŪdmu M= F4 pL7cpv;be|BdkdK!8=!8:79:7voJEAɿ!V\`ʻ%)'螞9i7 W2|noQ  xBk6{~ %A1ODDCf2ݱֳyUnΊyg%Ǹ 8AM?H7?=h!V[>7   ` -wcw]zrj[uVڹÂѐS)5BJL"NHF5)6 LK&ѯWnWnz`.9{xxó@?0 ruqx.^, :8 O8 pP' _ 3g㦇!\t Dn>6 szQV 0ٞS+HXIg ++&S}SVZ9M`bc^84/|~?Q^~pS)Z^%Y2Z; ̈́ L"'S+ ڽ_Y94 itBE$?7?м0(0Kb"=ui!٥s=KVUkS+  °cH8|p⑥@ DL7nS 3+Y@ fJuL.ek%9!!S+$/}}}~~BE$0D*GK:zM_8Ul%NDktB-{*L >PV>'cF W= 9$/ =oI\X ` + -3)MX2MM оEڈDOX"' $HB ";337L̃ 4}̊)Jkݰ#߽@3ޙ6C652ޛ#6Ee hc_ueL%:WX X!!  ,.4=%xxxx ~~zq",Sԭ)$  4} !4q4W,W ,W#!C3%j[652$$$)) 18?18?ڳ|W( %+7Aû >FLYAQQ55DDcv9BJ*06 CCC&&&444JJJkkkiHJ)5 ڵ"Q,-< )4= ?G}4O NB,281>N'I5 =(-tt ******\\\E; 6QQ!SŇKʬ;qX5#41+##&+^C |ډf^ DD..4%%::$  ttww]C HOYEE "#T#û (En(EVUO',4ճ * (3 dd.m}"Al  ijkQNM10+  PYTTl== gҷI] Q#( 쏉{r  G4Q[R_]^(%%55&&U\T 6s(\]fff,,,TTth 666p`Y hh< % hu ,5 D3r޽CV@ #Zkz!&&L qCOs  |zc^@Auu͛e3eTTT]ؙe *.2ޔyy@]_).3$'']?tA``P`,3TBNekkdffhh#ZZZ6( _lj;; '-3'-3Ⱦ ꎎŗ*KKK$tP))a,VVU dggh9vefSdhpp%J5 '=>> ttttuuud))˕/kqaYYdX UvWW/gg|?|Spp LQ]._S& <^5CO{  k5kvQ ǛgwQ !E> 5Q.h& .  ۑ1ptO(2()uh>+ S`谄(竫,,,WWWCCCiii \^[t HɀU] }@ *3ҋ _= MM MMM nnnCCCiii(((|iL3DD  8% $*tˎB`PrxZ]wm9 /\ҥR槠CDN''(%DMC7** 66 9&a`.  U>;Dl 1=W8q.vҥRmx!($c JA9  G$,NH  ! bb 3)% CiWUH`Ǫ.v )1 [c$@6J. B& Z3n8Ux!'`:JosL 4  q;~J_-Z3U  (' rPesS  6mm*yvXy ! !-M-M$!  5-{  ݑ|Gwtyy샂b҇:%v5UX!3qmdd #%!$'  [iHBܺ^n !"m $ $$  #q3(& J^ePbp"*Ȼ5AILwY~** "%"%E l<#f22CPh /8@ $  >({Ջs?1NamPbp F4ttuu h  f $(Ҟ"#ʟJ[oi (30=G,1- woX!"!" 3& b/1B #8d ϳбm =GO %)(*-,31a.(C<.   jw㹘wY5J^ 2D#z p&+왔]lxphx 5<b/###@ 3 |}*< S8@uap} {xev 9@%/$ [~꾑o2+`  :+ +]n|' P<ddd♙dddaaa$$$PO9%:&-* kk kk ??????'''&&&YB J6hd 4mmmmmm-#j쐐SSSiii$$$U>\Z.|] uuubbbpppy#nk  SS+++ll jh QRQRHH&:51!AAA?LX!4H:M`Ϭ[:M`\2N}N:N$)UMUTͣe}N9' ӴN18\!׺yigdKVblIlN(M/$ r1}UN WYS6j/;qc/N X OAbjU١W :l:l`v^gM5?N XXColOcEVD]aPڨgN X 2=k=kN # +NyNSPpkU }} 0z<U6[JTF 5qb/fʹ% }ٛuvblj0pd?F G#k4?Eww% F KK_)xxE/N~hೣԥ B]a]?k/4si3 D_bgNәQ"% {y=j˵ [gXbDAi\ׁO+w D7zfqbw̥oXN Lc{Ҳ!6+`~ GG%0Xv0mT``4n4n+!@r@reel`e%OO`` +=q=qo2Y|Y fg4nkiUmH]q|dddn~oy~~ 9ddLawLawi; ffޛegg _A;-  _C_Ce  ^8n<ʚ1 /RNRL <<³-oM{ow -?K?N@Ul0?A! 7( 2#͌a Y.6Q*U ' RZ.>Eip>ϴulE$ ԓm%5GH3& 0?AX`s񰔡()NLA  ~ Qn8lC VAL_rF5">5*>ap?١ ]*-m-/PHD8޾$OePl4   ###uoh9u Z>X@-> C9Q[iK ?N "" >5* ݾ.D 4и~nFYrF]VWbox-!&ʳ1(.=^}," #   Y"J\q/ `ϕcSq  ū| !-!!$"K"u+  uuLc34k+:".D 9iw"%( GEOˏDVj55-3B9 |i 6zV.`*+|TNPtH,V0#1:41.4Xf b\H^`]о:a(&gUl  F  )Y& XD%N㳢+U0#RA.ц_>'k.+')u|_`4ܙ(XA0 j 4q  EZD[sDPJ.OL@%_I3)͜|:=RA.DTWh !^~ kLU>    |({) /r~63J@ qL*6S%'Fe1 44L@% R,)A^F⪌Oh()*ZdY7 TPBnnn;e&r+jMP9 6OtmabS9k&ezޗVHRt3 Pt_6],gNە4xQMPUQC 3ON B< ,#<*\# ~HWGK :D I`^-$- ޹#*FQZźA H'T ;=PMe;GFAh/[I) - aa復)Riatp:nx] 4! }  lk/^O%(׀blS dG ؐЭ'3٩ SQO$I wWf 7FAbO,.a\LO37:Pcp Rjl}v/ '''IdF !ï5/ n1xR  }/d>87$#!|Cdf&P%ztY귵IK7P)3.;&AAA \.z8$. Jp\K쭪O*ZE2s:ײ/F@hvLʂI6m> -&c|C~ق]'] H# 9J ^բ$3f#51E.#7IKL-& ߫林o.;( '''߿< 2ƾ 66 D.W  ',"', ^Gw ʦJ @@BB>GO]'. . fUqq}U^f `!甇ãm^d԰ű ) )4IQ)E0l,'[ ޝaa%){/qu]u{f. g{&') l^<^>8AHɆ}V-x}5n`Y kN+ usO~'x}}י~j o m 4'u_ s } rctF $%nu 1;Fy|n8>E9>DD56&6M~ ȫ@KT0:badUT<; >4'deYZ/ vv 33<<$)#+1#%%$$$0"̶,~t:iI|liYG_@<)! )2QI4  O!*)FFF$$$+++dddưd ZSo))(-1ĺ!'$3A(3<, ﷢`V_ ? V[][  !wwwBBBBBBpao#";;8  ¹bgkG+fm! , `_น(\3 ? ^ www##5k d;DL~Q~ǖmw\1\ZY*( (kdjx"JiD  //BB 77**##{{~~~"""q [ҢG ?`"y[&/7+;222~~  eilK 76zz~~~$$$0&[$!/ 2!!(( #$766YYͤpF/Q   MF= Jm .-KKLLL77ˆ'-4_^_ J,0"7~sj2Ls-f@^3\onnlwAAAÌ<J Jz!;dS[ع-M_[Z +[PZ͝)iγ2211 '(2+++s{Ʊu%S -M  67'-2#(  EEEdd6(fGG;@MȰShz0f wa Erj>n=+>>>VVVb85KkXXXUj|<+ |ty~M1&M|gUnm|V?<37ZY$limgZZZ  v{+48Hv$(JU  *(#L LN[f{xvy|$}ʱk "^ˢ4 L@؝sK9)H˯Tbr j} uy VZlGgljh Ybe[=!1'  o.L1?/ '=.$~E=VPGVPG8s(K$.8 qO1hE ysm $睗Ggy{s-!)!c !4.r",4Y n#a     dd !(   '" ⰻqg7T*ztB,&.刺rJI0 0, 4D!Z&{Da3#f()$  (0z\  #\0m^Is ]ݘ1&- wS  39' *3Y:a@a: uZ^ tty0 h) X^ߚ 8#xP%"M,M,t  ʊ "y %#vn7>7Mse U:G*b(!]" {R&Y? L :0G|84+s %L77 W$$${{ ##HO RqGnrl [  ˞W[ʹ(&#E71( ov ̏+f! µAKU"'+Z.. .+[uu=Z~Fz%>H7$ DKU($  +/2iM('  2?I2?I$..ώ޴䳉oΡ~3>GN\h7@E EL%## '( e r0V@!D>`LB&1iPVUyUHUa39?39? ?A *((G5̴sq%󔹴 hHKYd1=BS(  #.yy& э   CQ{t} JV_,15{tw8xBҽp8Vˬ86:ayJ} +)2;C)/"/:B/ `nFwoHHG߮ S`daȤ54:TUg~M,"/  $)jvǿBHNnG84('''    @]aaYc0# 홒yްnBt3:C,4<V8   AD2=mkt 6A2J7BKS]UC?5 ! ."%AMX a[T^W5zz{HNN!7+ )  FCIC !!!'''.P: feJD 00 ' z{WWWWWW$$$$$$IIIqqq& 0䈈81"!&#++++++tttnnb`E-" 0.!xx'''kQ ℄|YYYnnnM9@/ ED (1<.<.nnnnnn____F8*  54',;;;L:L:왘222ttt<<<O:L9 '%#/ppppppR; ԣq^~ CCC10!3 ssssss  (' '0'%ý 2 30#3EC!2EA< ~K *&#%,,555_0_g4XbwN$X' ٭%@k85"Xb/E5X0+]:_\w`Bn8\!׺y=gdK:λy5 DO$)UmͣeO}3YBӣd&Q% ϗ1awQ1ǯΖ>rA<&¶P#+NyA R/ZhwQ1ǯN85嵜}sF~9/wQ1ǯ"9WqWSV51V]Y:l.]6ތ(Osܪf$r ᏎdꮔV{{8܄]hAK* Ib5_{77- VDxڨgN@{6V)3iv^g3?{8Z`5} =\cy   To7ws>Vn2"t~ ,\w' ć6ee]VD." tXKgKz3{OGakaf\,]]VDO+jQ!i,yl=!qx?h]VD8}˞hUb @7sߣl︃_c90#1 >g?c_xnN#.x]iQSQn!Bh#ܳ85b5bٛ\v 8 ic5J' N +, ,- 1Ŧ;\nVb}Lh a mM) 8˧#U& 'e$ Tl5oc pϼ4K%D"7rmp*0 믔~y>c+3ۑz=̪c{Ҳt$p쏇fqbwyV: r;;}g%&bDCtn:˯qUi$  Ԙ`t=jʠf " }{*** B3S?>i:e X!i=< "xn} k/0kZw{;L0!oϤrk. :W% eÐ]V;r$oWW^e|#T2fML:ƁN$>E~74"+|Nq +Lw~az`wH GG` `[[5oxo GG$\j\1\1\=p=p GG <Bc GG G7[UVW4U3CTؚtOrUqũǰnnn4A;:::g4 N', #+Zt$.8ȨtCFI$.8| ...: MuYck^hC//???tYII"j?:M`Ogó!#&j ]]]d .=M.=MWWW/>Q.=KΉhhhWWW <==gphǴOiAVk ȶ>DJ¼Vrg5[y8J]3DU g6Z0'''[ze})6E(5C6G )ASYr$KeM_CWFm ,]N y r7W]N y  Y 3  ! =Ab  N 0:m&N  =5&N  =t n$ q -  _ #Dc !C>Dc !:U   / Q ~3 > ?   ^   ^ N&<;d/(f9G~'UYx\c-Hcc-X' Cgx}V>\NV w#3TG!]\\\XXX^{ 7DQq  buh[tYrԵ81+ XXX222+,l?EEE&&&lll }}}ZZZZZZ 1B%xA !. m 5$k;[1 ]quu  K&~7z| ,J)9 Q"G $f+@ x E'H'" !K*{C)A &A;    $J(C%   Z;ҷl [       eV9#'  2L*3 `Pdr~s;ECO1D>Xe7\EFA3-i0 "1?    ZD_A)!C&K) ":* (%%'jq{ %P]N9=3!)!Y?Y?*K*?" }toL3Ilz5(ٿ.'AMGDzP@]Nt~g  Z5 +"!GZJ  G2G2 :"M+-ͷ49K.AMGERCY 7mɓ ۽9a0C+ŚZ;fZA-HC03. rqhzql  qOqOF(K*  ɓ5,V.88A<{څX&Fw_U>?, sip@1"ξLUNU'*  ++~X /N+9e8 6l'PѸb0Gob\] X&lPNXTWF  Ƚ( 3LUVD#&.%:J(>O >J^O"" !ĻLA,(@  6'6'qO>$O+*HHHчŪiM/Hd/Hd. 788Ec]^R`X('_Ue20. Qٯc9ADT9BN$0Ƴ9A9678 %0 T)"&@46 316  J4J4آ +Y⼆{{{uqjimr \i[y HH{iMR`[20. b9՟">npb?Kd,>5- Lf(FZ KUb 'opn$"*++jj^! #    tQtQnU;+ wwwTQLorvK aJ#ʑ 3l#)&N G » \fUt}czwG{i7F&&(0ț!wcDz{znYL(5usq1vO п9lczQ}X zo0Wv1 3®IXarRŴ #,ķzhe K++ u "%   eGeG&micxy{!8P ЛM>"p P>BQuLWȆz, Xub 0Ht89SzmSD@;\u,뫮sM(dAmcXÿO& ΞL:Ƿ B = Kh )     ((X`n --,--,nXܷ~~~ZVP^[Z4K-&y R. CzŸ3+í[2*Ğ֟}Q+ fgv3NQ|F bab  뀄ɬ3R'K)$"9KC@ļL>U ഴ *,B !h&zh,) qR@/ " kI8Q`+fP~8 .Ҧ)|T5(}W9'G@^bIlըƮ:n͘'g~[_ +޴#/}oGX]\ٲ 0&32-TG4   ZO൵&0F#e T> rS6' ҙHOHOPxx(#+"^d";?EL'Na`67 &2G]]-*vUP9  l  )!D &X@ \4^0:FWNM;^n>i&:`z6, sVgf[E.-AxY[biUD Ҁ,:gT6%K4-yY H 9ZF@< LWd ػ,; .0. #B0 D1    XS c |+Q vi4QC.]T +xuY> $# wjb)#(#~[# ѳ)J]SwF>9۸"#-0(&$5&;*>-ʂmӊa5\p` |s,W*{X@ bG2$RKyy,8 $H=zgNR#Ӟ&j5  yW=caJ"t00杣t]C$#c'%<{&`J1\ /M`ggg*-.6=mfTӘJaȶ %'0ۣceg8K( #C0B/  7.c@3!(,&fYO2-7/7^ D :C+o_ ƅEsSu}.hS%eI !.9sl 3'?U+ Q[[VC Ԓ7 <6"<6wqM++_C "hƶ𴟢Slt ݩSD4 -)/F9" I HVP\&7'?/ 89횶 gA/?-#BX!%+7,5/C14g ֛ߑaff»-4: $  8?CkfaHA" J^/W_4 ZA8C989,%\lX0ksA[ܾMn^yxEa +$ VuVu pzx 61 #bb#Q?3SI4"# 9$"p  L7 L%#- dq_~A  Gʼn  5c  ТȎ[[ Vcnl=abJ!F91DBAA=; _p}Y! MR).N6rS60=.^CD;v&V m)i)i* x'a +0   ú+8@+⠐%"2xD'˘a6E?#!$\QIE0:? +-IPQy0HF0`O ;)4F2 FA @=j Bui}":)?.  j<( ٕ/,.5 z0[%Qhѳ 0mp vsv)0 ȾTh%178Z-&$^K`zK2 oT=PLNrnll ئZc7  bD@MMS+,v!\V= wQII1;?BBBe6Hi2  >oD uL 5%%U)  ׍ %/8%*k v &NLW\ oN6]-ᠠ7_Ün $"ܞǛłfE~*/4BO\ Q_@Q#yEg&0*v  P4~d8K ͎o#OR#? ܠo=gY4YM`Yx: 4d!¦*>ZĈy63%5=6iV= v/!6&P uD*bb|x¼5W(*OU_ m_o AB E*B2ÛllÜn33  $$ #"%+  =CH olϬ$2#cqq0I!1Fn2r(8 )]WK-n":$&*>Z]  Ń  ?uHrDzh-`^?,g   ';Bq{ ." 9C9 ˚ ]^#++8B  qq0 '7#"᪫ٮr .ZY2n΢;inbbE)7/ *G3dn hͭ2R{$$BS@R T- ":!(-gT+:::cc?y DŽQ3]=7L#"zGG)((*5*0>>  AAA}Eˆ666gXL% @[9[9d<2 &=<=;:;  nػ A Iv4&2 xur !!!!$$$J}IX $5n5_iq%  B >+ &?00//fUuQo+SzT]bT1[6!+2q}SD3+ڊ 𸸸830#" ooo<< P:DpbbVJ &,ͺ.BO ɿ"%(]>ƛʝ1!*N KlYfSgLF)ff29?aR:ꌒ P *^^^^^^ 33333.!4"48.hch qmi 8^诌  |bD  sᔜ.'-]\]X1Nl tmmtt,.0 %*! 33((rrr9:Aէ۲ii&& 0 !C3?  Ⱦ /!  K Kkkiy * > !%iecMhM2Z]^tY| k`n >?ɴd9#]&Щg4[M*f,f>F  IKʔ::66BBBAAA~Q!!!gr|dI2rS4[=!% /F4A嫮0,* 8* XRWUTnjn S   ; ;"I JF~Ѿ  hz&&&KKK -Dp8pddN`-\P~( ^b]WMF@÷0 ¹$]]+!rmqjj᪘bt؄;;9BDA qoΘ  o FD;;;KKK ܷE"EA D//*x„{={a҂&&&&?LY,,.9FP  @/nu!+!O/*#F6)y~v%9e`#Q!ot&ځ)`ݹcGwt: }yt  giZ#I$IHHZۈnx$$|$|y..==''Bccc+%뺹 "D7ڞqDOL5"otځ)`#Gwt:  ))H$HZI0rx% %? ==__BQ::yyssE֬T+T::LL,,;ccc1118WlZ51{vz vGGSqC&&    .7@!.9Ƌ~?~ff$+ X,XaaQ::CkFU*T ~)5555r++#(瞐{}ƼD#DQvv!} &&&;;;JJff%#!XXY h/G 44߁!!k6kCAI F+spp||(w@ @{}bVc=:DlQvvp[[~!c]lll&P0̼0CM0BQTNO8HU/G 4^֢r-z\IO +,-$$$핓ZXVuuuttt```PppI5lGG66 $$33OOڋ&&!!" Cٖij%%+߿A!A|nwl?b^ceel͚f3fqq[??! ( ']\]" 7AG(Dp~ LI""YUS ֢rz2\O luz lnln pp~ 66$$޽C"Cms" 1*SS%%]]&} A!A۶I%IV?ʼnw;wm>>ee!}}f3fAy=xÆz=z Y]]G40$ spr pXjD5vI5vI5  |l       -4; C"CggM!s1*>22 ~~J%JKykw;wPP..!~y~xz=z00 ?H5 ]B ~*(     W jblhy y M IHْ~(o22yy|ee| * bbk6kwwxxxdZ Y ׺T`Ai `y55 XW!! ׯQ)Q(oJ...;% :PJ(.. ;3 Cg@ K## X> {P uU (.3 nb T> . N&# vW w  -6U    jX8xHdd-rZ r @G ՝(AAhh2277Q)Q^^^>>>(^6=2o`g6PeͼoğQKIN}ช) ...---MMM___ ՏgRmUT _C _C ƣsss 333###QQQ//////111111ñN110"""  ((XX(1970+ &iiiiii (((((( IIIQQQ'¢ 332>?>%%%bI>`%%"a>t5+"H !]=30 "lH! ===''''''s/ `1B߭!Sc"\ޤ9nOHFH=}A?NgzOW''j, '1*¸%. "mmmL>wOt  :S-%n5 9uf" &4}~R)BU Y+g["!Sc̔(<+Ѵe(` ssss 243xF`Y〵5=5(!ss ƭ}* ޾71fe1F@I""444 xEwkKts?" ju~wy0WfxbU8^mR_{(29z^TEAA򓍒paSB1"e112 ]5 $ 8$3kzm앃׋ 55IIRTY+,*. %*  (& 6' oPv 5Fv{-!Q^}9)F&1u|xn"0T72! . {ro    >%&&7,(2)N^8N77<#AC <,e  I04#' ,:Rto=J        Q:lJ R- 'LI$Zoե: 9wW)?e B+J1+ 6   B6YVNWr9- U@ gN FqRtp$)e.F$:$    <'I1(, .C3  V;sO4$  gnR`Z}`k0# Ѷ] 'G.+  33c<   hFI36(  V`df(c"3 dqxEPK  T/a5  Lq ^@gG+!  CJ||))q,,   ,     ?0I@]<_%LbD^@   (( FF]Y ZY{222 L 5e QfA zoC" o Ze)9 cBfm,ШґG#_   nnqq ZYQ6洆ѻm!4&&- ZZ ffpTQ h T}X0%ZBS9Ր  p !!rr^^TUU=Cm q  Ɵ4Yh5U' -ͳgcrMt81 G  A ݋e o]hG)1 ?O uw5q8~UA6/lt\V ;X,jlcc""Q tofR=+7X3Z;?8)H?1 ! qg&6 !"# =)|YqByk" G1"&* !+gB QQ;ii;; @*$&,Ȥgi:>7317=Rb.C o   :AH !23xznر%6SʡϸqP}Y #(utwȿ+3;@LWZ_d$,2:> LL* #%  3&  #$.55K|@0'\{@n  \\pP#"6   ZYY[ZQ >O]¶6I%Ǵ#8dJ1DѵHiWr!& HA[718>&,1 L!( $7[)BY@I@\u<3 ~kf'<7024462-32.  [<'wJeϗ9Eǿ?6G0 (#!"j3 ?KUHe~V JKMj6=D,3:   7= BABK   "@j0XA)B*  d "~¸ﯦ޶AIR 2-  TS51fc&FFF +֨ GGGEEE+++ :+ YX /KKKKKK @1۷444@@@DDD )3%  [Y!gc%$  )222222{{{   Q=⡡GGGDDD,,,&3' , ﻻnl WThe -######ggg %׾pHHH&&&BBB $2&  럞燆:7|EENNNNNN3& ؖٶ1 pnFCro abab444||| 腃., DDyxxt IF ____mm ]Zc`$(   "*/00 ###UJ@%{\n^ʸeeecrF^uaaξFFG268pˀ1BR"{{{e?g4***.#zzzzzzXbAV)ůcV:X' ʊWH`hF Xb'fOtx(ʊWH`hF  o_Չ\εfM.P2Va|ji:X' 赸ge!{kjεfM.P2Va|ji,Cfz8jZ']fzxﷱod/C<]kby ]kXL@ʹ:X' XOab<  1K}Kl`ZQ*]kXL@ʹ$YjY&D%p\l`ZQ*]kXL@ʹ:X' LL4?*qx@ 1K}K >N4V0L* +S@Çy$=B ݃qzy: Hsj5ۂu| `p 憎x:62s~Q ؉9Wrv>(B!fI 4,:"0C&1.9Rx_2GEnj4 憎x:bqf><蠬7O{Y9Rx_2GEnj4 憎x:MmvϨ@!(B!fI 4,:"0C&1..tbòl%' ȴ|7QuS *?=ٻ,?U2%~o~,@Y7&AgM &_rƂԵ>!\x\ӜLQ.ƿMɭc4,@Y7TUrĽ,e΋!s/ƿMɭc4,@Y7!\x\ӜLQ.RSnpG[r-Ձ7 <;aB,)Zd $9$9]>f߆or/L3  =S4΀JbIm3T</L3 ޢ >`$9$9]>f߆or @N5׀,U?/N1Ӓr )-5ͼ־,wE ܃s oav4:@׷.S ֚ :c|7 ;esS 49CմѸ&~Q q=lH]K)u)a_ךr,^ДIUtI 49CմѸ&~Q q=lH]K՛3ff1|7 ;esS .wasܪ:RuP ;Ii=ܑò` HPW:Ѳ`:X' mdW`Oe_u ijfnPn&eSL)0#|nnZWW7 fo){lPl!nPVJ DOzO~k ,}& fo){lPl!nPVJƨX(j[w$0#|nnZWW7 )*, h;888 G`XbX G`C{C| W}W G`KtK 8l=i= G`0x=i= G` G` 8l;=>q$/<W-ssthd?TpD[qeF888X70@Qf԰wuuuTTTee@ppp%%%g4g4 Q)&ـ 0/.qqqRRR7:=@Sd_zlRFYl**)zii """jnneee21.%1<^y^yAKE(((rrfhhhh###'+0u@C 88ɞ}}Z**CCC 3CR}鯗Ŷ 66J(OO7;>%drhYxY"*~|| PPkq zhık)1qPPP6RR@k999&1<l@Jc{%/:<oBv#/:Ʋ#;GS/+'58\77I\#/:ŶwUPkAVkAVk𗵻CD荏omkrmc #/<IJI!yM!Qm&1<ñ***U*#=O`.^s IX~ o`ww; @Uo'  P:A[aUo'  PXb:X' Ӫ=Wm\7nnsscc?\\]]TT- TT- - - 9dMӾoHV*|T6߲-!=a>WU ߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98!n-@~g֔囉YDo;YuhaJYDo;Yuha@ $`{4q˳_P/LW݄tB)w_hģ)=V6 Ol}䨖Cģ)=V6 Ol}䨖9A(>kY/9X>ՙ´a=&4?#0=#-{n|Ǟ7` KxKǒ AkpB ۝S Dgl<,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B ƨX )#7,O~f A{?಄ot* At6  A{?಄ot* At6 !4zÒ@9-ta=* G` P`P P`P G` >xT>x%#$%vp % ñ=O`::!v'''˼r!!j:NNU1H\oYs$/< yN55RRRCC%vwXPP:II}eebb*** mIb{=-!88rwwV~~ aaammme娨[1MbvTm ʹ6GX Ӿ(((XXXXXXK=f6GX|iiii<<<XXXn=  k@::9BBNcySlܽtePPP???]3 )2z~XXXXXXX&.5->N'2= )2п^^^||||||.//{dmg4Tn3IENDB`sardana-1.2.0/doc/source/_static/motor.png0000644000234100017500000223417112174204305022101 0ustar cpascualcpascual00000000000000PNG  IHDR: tsRGB pHYsaa?itIME2c IDATxnxxxAh IDAT333E IDATxxx333O IDATސ::: aaaEEEaaa******iii޲333"""""""""""""""333333DDDDDDDDD333333333""""""""""""333333DDDDDDDDD333333333""""""""""""333333333DDDDDDDDD333333""""""""""""""""""333333333𼼼;;;___DDDxxxDDDDDDDDD333333333""""""""""""333333333DDDDDDDDD333333""""""""""""""""""333333333DDDDDD333333""""""""""""""""""333333333DDDDDD333333333"""ע!!!CCCVVV333ͫ"""333""""""DDD"""DDD"""\"""\"""\DDD޼DDD޼DDD333"""333333DDD"""DDD""""""\"""\DDD޼DDD޼DDD333"""333333DDD"""DDD""""""\"""\"""\DDD޼DDD޼DDD޼"""333333DDD"""DDD"""DDD""""""\"""\"""޼\\\www\DDD޼DDD޼DDD333"""333333DDD"""DDD""""""\"""\"""\DDD޼DDD޼DDD"""333333DDD"""DDD"""DDD"""\"""\"""\"""޼DDD޼DDD޼"""333333DDD"""DDD"""DDD""""""\"""\"""\DDD޼DDD޼"""333333"""333""""""ݱUUUͥqqqYYY777[[[DDDEEEͳ ;;;NNNDDD"""n@v, IDATDDDDDDEEEDDDDDDEEE ' IDATVVVxxxVVVwwwggg333444UUU͉gggКxxxgggxxxVVV444###gggxxxVVV###xxxxxxVVVxxxxxxxxxVVVEEE͚VVVwwwDDD333"""UUU333www""" IDATwww333fffUUUwwwwwwUUUwwwgggEEE333DDD"""\͈fffDDD333UUUDDDDDDDDDxxxDDDDDDfffUUUgggDDD333UUU"""ffffffgggfff"""EEE^^^++++++^^^֣++++++333 fff<<>>DDDDDD"""DDDDDD"""fffffffffEEEDDD"""fff"""www"""DDDfffDDDxxx###޻"""ppp...xxxffffffwwwUUUUUUUUUUUUޫ333wwwEEE"""xxx444̈"""^^^EEEEEE333EEExxx"""fff""" 5g IDATggg,,,333gggppp޻ͻͫ333ggg333DDD""""""DDDDDDޙxxxgggDDD333DDDfffͼggg333DDDUUUDDD###444xxxxxx`C IDATDDDDDDggggggDDD333DDDDDDDDDͫEEEUUUfff͔333ggg"""333 DDDDDDͼDDDggg"""wwwfffDDDfff333"""DDD"""̈fff"""ffffff333"""̈ffffffDDDDDDDDDwwwffffffwwwDDDfffDDDwwwfff"""DDDDDDUUUDDD333"""333"""www"""DDDDDDwwwffffffwwwDDDwww"""n444333DDD"""wwwgggEEEUUUDDD"""333333UUUDDD333xxxޚggg###-)o~ IDATxxx444"""xxxxxxfffDDDgggEEE```UUUDDDDDDDDDDDD"""VVVxxxVVVޚޙUUUBBBEEEVVV###444xxxgggﻻEEExxxDDD333DDDxxxDDDDDDވ333xxxHHHUUUވwwwEEE333wwwUUUgggDDDDDD333www͙xxx"""VVVwwwVVVDDD444xxx"""VVVwwwVVV"""<<<XXXfff﫫VVV"""UUUUUUwww333wwwUUUwww"""333wwwDDDDDDDDDwwwfffwwwUUUwwwUUUDDDppp;;;UUUfffxxxUUUwwwfffDDDDDD333UUU"""gggxxxDDD333EEEDDDUUU޼ffffff333ͱךxxx""")))###UUU﫫DDD͙\UUUVVV333DDD\DDDDDDDDDggg333444www/Rb IDATfffwwwUUU"""ffffffUUUwwwDDD"""wwwDDDDDDUUUUUUfffwww"""fffwwwfffwwwwww"""UUUwwwDDDwwwUUUDDDffffff333www333www333333""""""wwwwwwwwwDDDDDDDDDwwwDDDwwwwwwwwwwwwwwwwwwwwwwww333333wwwDDD333wwwDDDwwwDDDDDD333fffDDD333fffUUUDDDDDDxxx""""""EEEUUUUUUUUUEEEVVV"""DDDfff"""UUU333DDDUUUUUUUUU333UUUDDDUUU"""fff333ggggggfffDDD"""333xxxVVVwww333fffUUU""":::iiiUUUUUUwwwwww͉ggg޼͉ggg444VVV444xxxxxx444xxxxxx"""DDD﫫DDD"""\ޫ333͙UUUxxxwwwfff) IDAT333fffUUUDDDgggDDDDDDxxx"""DDDwww""""""iiiǞ&&&GGGfffDDDDDDgggVVV"""444VVVͻDDDDDDUUUffffff333UUU"""xxx333ޫ333333wwwEEEggg﫫ވDDDDDDͫDDD"""fff333ggg""""""DDD333333333ޫfffUUU444333ggg333ͫ333fff333"""gggEEEfff 333UUUwwwwww333333wwwffffffwwwwwwfff"""DDDDDDfff""""""333UUUDDDDDDwwwDDD%%%XXX333DDDwww"""UUUDDDDDDDDDDDDxxxffffff###"""ggg333"""DDDUUU"""fffEEEggg"""333މwwwwww"""޼͈ވ333ވDDD"""DDDwwwUUUwww"""DDD""""""333"""DDDP( IDATwwwDDDDDD333RRR333EEEVVVUUU444DDDxxxVVVxxxDDDVVVVVVfffggggggqqq***%%%www333DDD"""www333DDDDDDDDDwwwDDDDDDDDD̪PPPppp"""ݚ着޼wwwVVVfff333"""333UUUfffgggUUUffffffޚ͉"""333pppfffnUUUfffgggfffDDD"""xxx333fffUUUfffDDDUUUgggVVV333333UUUͻ"""A~m IDAT"""މwwwfff333UUUDDD333DDDfffUUUUUUDDD333333444"""gggEEE333fff"""www""""""VVVwwwEEEgggUUUfff333DDD333wwwEEE333UUUUUUUUUޫcccUUUwwwwwwEEE333"""UUUxxxxxxxxxwwwDDD@@@FFFMMM333EEEEEEgggDDDEEE333ǒ444KKKNNN"""` IDAT"""vvvwwwUUUDDDDDDEEEwwwqqq/// 軻333!!!;;;NNNDDD"""VVVfffDDDeee%%%333"""333gggDDDzzz"""EEEDDDͼ333fff\\333fffxxxUUUwwwD'N IDATxxxxxxDDDDDD444VVV444VVV444xxxxxx333UUUEEE333DDDDDDDDDDDD333UUUͼ333ͼ333xxx3i IDATVVVwww333###EEEDDDDDDUUUDDDn﫫DDDE IDAT444UUU333ggg333fffxxxVVVEEEEEEDDDfffggg333fffxxxwwwDDDgggEEEwwwxxxVVVEEExxxgggU IDATUUUVVV"""EEEUUUfff333VVVggg333fffޙEEEwwwEEExxx< IDATUUUEEEVVVﻻfffVVVEEEDDD333VVVwww"""333333EEExxx444333UUU!" IDATfff"""444xxx###̈fffUUUUUU333ޫDDDfff"""﫫333""""""333UUU"""EEE<fff""""""DDDUUU5T IDATxxxGRdIDATBh̹!CIENDB`sardana-1.2.0/doc/source/_static/pm_pipeline.png0000755000234100017500000014645212174204305023247 0ustar cpascualcpascual00000000000000PNG  IHDRy'OsRGB@} pHYsQztEXtSoftwareMicrosoft Office5q̫IDATxyxe6CYBXY99  ;-HCuD(JȦ3ze\pIHIJ^uqtSe o$I """""""""""avDDDDDDDDDDDD>.s8$IEjjp1!"8 ;<gq W\9j!""""""""ǐL3A\Y_+T ?8^z~<~,b\Eq$IϘ]Q(bCDQLpuPXma7X+gNEq $m3f""""""""P(x+fAVQȨh 셝l+W/+-*\#%I:avDdn\5""i fFDDDDDDD!Qhk } GaͮBPtˆOTwOG(%IlvD"l."""JjٵՉѣ}ԏw)&{xtInv7k9`$RS_|>H7VQ1OfGDDDDDDDD_tXkXQB(N$I]QaCDD~OWؖ;26\^^OQmvmDDDDDDDDDi#B1^&f, /8!IzO ;lIrf34""""""""-N"Ou𠷓`xO~fZmmF AK""""""""" 5BQ'A =.;\;yX!I]Q<~ kTtKfcvMDDDDDDDDD:Eqa"~ٵ*(%_,`(]$I򈼑yX,mvc+ͮ(X#XRx<캈Hf-;8XfEҒlM_kנl$E1I1 ̀(PTaݦQ$i%{.TPHu+Xf]9YM8CǏfWO!кm;c~k3X2$IovDDDDDDDDD2,ۡrY(" \MQ@E\|E 1|ySe|lN[}olb8h!IRuǂfBDhr7px+C%I:@0d M^|U빝lk+V+f)I k&"""""""" %76vJ듣G."aXH$iu"KϧG`Xlֈu2wm1q-( 4Ѱ:h RD>e VkI̮(0䡠>Ǐa\VX>I4j'=U=w >8p?n3 ҁ̾D^mjv DDDDDDDDD!'MJC=w;k^IK$UTT嵟.޼ռd,'wlݮٗP9NE/ ϛu^ˠ(0!"""0!r-{wNY۶CO y( j@# """rDDDd4v$DD޻o?7 "=1"RaC cx`gZy5kp2y#mYyVt JW9 X\9sz ~2Fܨqz#B#o(0xlբfoDDDd<䙊b#GֆOxg۹KuI莆ŋhĹpm\js+ǝ H/\quO|+ȕe\g덬ٱ-|DDDDFaC^;l8F'O7|ޥ3O>Ju[r:&SQ^1gkѣlQ]}ϸ<H+quI5g2Ý`tuNO'Os'H """m.fT'|?j/!3";Dx{4o٪zGAϹ1,;˚鍕$Ip5\qtO7uԢQdd0!r;i<@=z􂞫EEᛯγ>Šξ7*uQ0 OX(zh w'""ͿZy}Us%QaCw<2gAoh3$/:ݛb<]~(ܸo!s@Q(1!rE~kWy<2[֦Chz>Ðfd`BoVf!""`Ő~:6 ،=w)i=;_و‚@uf3E -n""i'/]ZC"Wu|aMj*4\R28͠?\ x͓@ƕ%L|7Q!Ѱ{[RA_GwpO-[>lG7s@!""";S؏C"wm`yxE ׮a 9meeӨ=콷hψB """""""ǐ]-z6pp06Ď 2]{qpv܌ { Dƚ}&aCE{ 4o+ vB CY8qfz_~ܫEE }ޏ_.AƒXvhڼ~A^fg ۗDQ(8S̮UI Xܳ'Z[K:<=mֽR7{Mݰvmw?Mmٽ-O.;7?E=yVW׿;U^{uXtժÞ4zϞ{}2oqOǎ8pW>2tIcoL_윜z/ײukX_@[ϓWg궨d1]+-ߏ"DQ|A#"#QVRbv9q7DQMcD=1xj v1c9R?Z|u3~ݻk H|֥Zkqglׄkwt}dРˏ tc|`Ot-;7ϥnr対zӦ_uFo}7o:8:8.^h:f#vwi#mǕ*(1!ZDQLf-[b̴X:s%y̝eҼٷ2K@[,P@,c{'fcf#cbkrR۶XJz衢}MJzlvvT~oLJL[lRmhݳ͢s{4k?qp{%?`߮]횶hq-(0!DQLX,[Êmۑ&Yn&dn@<@ MI}=yAa삅!u#ѸYs,9=*)1qBQ3toOlD4<8챐2bS(-)洕Q&%=ڎͮ)Xy/@\c͗/Xp_(,ޜ1$ԉ²mY8 ӻԍ.{|SfEDDĐأ*V y Azwh,Т[xu@;N}g,2T|洕Qch1O=h*ex<:y:r\^.hup{V#glٲ욈w>۲кm;K2\ f$úUiܴiq0mFDD2,fBD..}_,QoV;}D!Eo6Wgkq=öҢs{-77&[r3wg!@Fh0k .[wOI_욂4w=j!Dzsrz~%%!#mX4wnz}캈(|U(V<L6\ѻE5#]۷kۡ# !Ȓqp{Oo^t) ?up߾[R?ۤIn6mN{2w 3C<\Wp葸O9Ŋfd$C/ҿT U*,,[^^n-+-Z9sr6hPɜrxC;P)2* 7bƈկ2oq 6u:w(tV\YW;A1&sE6\w3II}ͮ:GH2 NL2bĀu[aCDDVۭ+=  mavmD$+<#a};{=(lѳpJOQ;|JiBgznwwXwihub툋삅ovhԬYߺfoƾf=yΘ}DfSz݁qHzn6JKJ.kzV,|= M] Tƺ)ӎa_B3t0d1`v]={aX8)=ZV[fKDD:ЫW/Hh$ Xͮ(\˨W76uu4MznÀG?DnENI1@篛v9Aᘏk|DEa,݀} O"l[f&Ǧ(LgOEأ@1)͚a협8 7lN]O_èj->Ō:,ɓ&>F'O׺m;χ@YI Μ^')1q`ƶmX<55ر/]ۯ^}UhG4}"y;G!_?~5IPZw>%%¢3Ѷc'K ߺDcǚ/_:Xz8c뙘:hbz}캈٬S{Æ .'`6#cgzmǎfDDD& 8u$N:ǏfH.$$$E OEk톌oTuf_ "So֓O+-) ~+?67c)t.ەBcmYhݶSma,H))ꧥֽy" FM{ڳ]rΈOV6H9Ɩ-{ͮB_۷Gͮ $s?FeĈ/^Z]{2y3*oΙӫʕK!]v-׋~mvNNYSTֶc'VT3}^*!";y-4lo>~knEExnX#"нGfC yy/O >}N޿?x@^N>9rQQWl! Tk>?ٖ[IV[0!@":k1! q$E۳:֏i$'"&͚eʔ¿\;#q8obㆫEE8gc|Ǐ?5í@~fL{>["I,3a zܐP)ɟ5VN9Y nҙѪu뒌mv]ESNUvcƸя;֕su)_?~0! $uEllW/ߘѭmڔL~ kWj"NLX`So0paښ58cvDЀsrrlz.s'^.ZTqb D-[:t洕 I}rF&M*22_Dnv|ԩkEZ}[ XfO)NK+7n|/#GX:c~L evY%0#q8l%Vֽyk""rEdd$,X9sxa+;FZϩZy!wޓPq#c"G^:~[۲eτ(NL,z=]}F!/'GBYi)R$nq#}hr#w:u ۷1ƨ%ܜqq_ӑ*5?;݀`C$I:#b{zJ-m z.ٵSй`EK|xf©O!uFݱfW6bsJ_{mfKV_cܞմ~LCL+ Nm9,}۳HW[n6ʿdMo׺~N} T?g|FzxbwǼd"UݭկСwA<֘EE׻Jk(vz |e#nok۷6{Q|ۓ.{/LK;ԩ}f$ֽ{P9/=?S6Đ4EE8yy_>4`ioUt;vdKˎEFF??8^돣vlcl6cʿ?5WTT'ϥd_]m>裦eX:s:6o^ʛo-@Ay^߱cc<2tsʛ` 5VTC+>ȷfo}w'O6zNl_6VPԭ{3wDnjaXm{G^Qk5{jղe\-\ҒO~II_O2%h߯o& T(FP "ԁM#u(̀Gؕz.9^+AUH_ v5Jӟn}nD$664=3s_$!#O81 4/[v?c"8eWW ̼CEg"2*|fx$7ŊfCDKth,5fW7%ڴ>ƞ=ju@(Q5ZM/S7iţ(g*A\xի>m~1CfbrKƭ[0W1za99 SٱΜZ4]݃]SGՁS+hQ&?vsPu-&^=VYî>uhc|f>Q{mǎcӏ?6uk󡘆 mV}ƍƖ]Ot6:Q]%.gG 1(5\ xjo#<{wK)Qծ;ǐ$5Px$) @svǾ><ڃū̙3TU$hu@# h8h,Vr]A~v( xB w*%CDD#q9M y̗Q?W/٦ޗݥb5*V,ΡB Z±(d!sx\.sԟ:$Q/vgSΡWGD N":_صGo45cZ yB#^/QOP0G= "޵+z5\ah=/Q<0CCrju<2Quh=V=xvuUV`k쿣(fY`CDD]<2ve|hq(w-ZwCDDDi'/:h ?z*+sXVM^2QΥG{G>[HC&=xouory6@;Q;1F'rC"" xv=.c}|aaa&-[f]_ ;/u8±??:hP5 Ç[YuZ^bӮO w@c9rSL y` բՍ֞=ju@(Q5*(rt_ ;8ɜbтxdlsʚ51w;S>Hr_}VMhu(gqk " vզ . xU^e }ԯ iQ8ʎ!uoU ?x4bs2rmDDDaѿ?.]])3f|nvDx 9Czܭ_.TDDDDDBl^Vh-Ϧlʹ5Pua>8z;\xӀjz\ڈKkw[U7ٞ!Q`Zx# ưvQP9 d4h;iԡzy6sPtꨗhS;}sZM:ٵ*eУص;cGd[i}ΐ(9⑱|ΖlS>fp(aNGhs-Q Q pdj#2V#?՝VТM[M~zsHx}yTݮej-m w2{V xk,Gٽ?'KLJ6='qu>׻2&AD7'Da'о]'abz-|Y6cػxh5:h223u_+7@lLDDdw;h|9HPPT^^ܚz5(]S#?^VV9Vc5)2eee(2ͽu++;1e.޽jU/r|o<""FgvQ5!6W#UK]n:kV@{Sώ={[ 5223]?q(kq:5b-ği}A/\Q mZIFky6sAˡU9=zA߿Lݩثnc`ł AO?}%K x-Kgܹuы/xl6AhWTްF'n^M}<4`Jm xw-rs""""#|jǾ}uTթ_XX5Λc_>Fll2^ot-\3<8p`Enc O_èj- rmeA+͆R*Q+//(UoW y4vbcck+юCB _niѢADDqkfBDDDDa~<՝9rng=y;bS.VZZZKGoI5y2Q+9z Z][ Νǐ\x1*++.7;ev?$3:Q(QvZcAuyQF//Ϧ x[GF^MZjzꀧN:Ҫ!WZO%x0]O#kE o&:T㉜-Qj6_S.&[&N8ZMDh, .#BpFȯXʀ'22=cƌϖ-[JQQQPuʽw{TA*+?fCDDDDDd>>Z[ͮj$]/?}V?n۱|r{l(--()//W/1땃9QxA?rŋ㑃łիWx駫>Sׯ/ t-:u x;wյk} 0񈳽j\+שS\|٥QҺ߭xJӚs͚5rǍb+---[G /pV1r'r5^AۻGDlr6lr ~jc'IS Q%IW?7Fowezon5PtsfWFG?L3|NDDDD&Q;VGNsw}zI]@<E f~h.G~2Pj݀Vk;UQcgS[`'O8D :ˡ=9$IEQ¸yz>DD+"Z:Q9rpG^M9nUw( P{G𨺅je'Ky%:P!?Sse7gc|R-DDD8g}{׮:׬bv-DDDDm6[uMEE***PVVVc6X^c{ʐG:qtZ/q^$w(k'22R hS*;wAN:u4gSH+b&oWjeCl4wǹ{,W18FBDDDDDDDDd$}`5B{R+z]K)gS:ZJ-DD䞥+"ٌҸ""""Rs%9v$ cv2ޑ)^s{(vs(_왚(ZW:C$G#HcrmDv:~zhq8 kvk),qȵ7̽ x\df8աׅcVwrmz;qFSkzY5.<^:Q6w*;xR ̄}Tk :%.FDs[q< sB+ˋ4#sH]ˎ.vE/pf ډ|zt8Wwe/!@k~c$wju7:+kS4ZVZ"nVku'zy6kzy6eA\PGݍ<Sg`*yW.Ϧ|\+1<j9sk3l(QGݡSuz4;x2 {0!" (> m$鄇S4\V-[v5pf-nԌ'yҤ>? n̙>>~)wh߾ۆ9s>1!r 92 ڷ]uVYsaժΛ֯GN]C3c'Mrԩ_o(;-3tw}+CC ۺuO0eP xTa]ǝG-ܟV8RkE"(YMګGaS.#,Qnh x'Q}M-("IO&J|yzԉDiI_MW}}-[5|I4Ϸ'O6EEf!/Q֡CYf({6F#n#w"Ĩ+0H Bn!""BT[9nnVǭ:NK_uhͭ~LK<z}!nv5x}劦^u윜zFpE uva߈}olnG63m\ͭhhQP0DZ|k0%WHZB~iCf$yzD7lXۏ{Qmz>;l89-V|HD=1t;v6&(;(9%{9ՀGZ(_Q.cսf FȝCsj- 'C>GNiF0!?aCXFL~ }1ݫ"cS}Oii~# <~L삅o%6lM-ػxh _Ў{C6ߓVڃ1 .Pm;vmY:h̞ݫK/ֽy" G^x!߲k^xv"lM_cvI<e%ؚARbbm]+|dr~ ~F }G\[wxSΗ̮(X;yoRoDdT%Dsq1<njbֲ!ȺYV`ɣFܵk;_~/ԵGgfn]n mBO/f.[EEx֋MH?5y• .g7V .{7wVXx˝4Z{F|Leh\-""v]P/gS1תjFY|~zɵ]G!^`ȣ. sq9vyq}GM7҆ 77>Vɓ&1f_=׶c'{ f$æ HͯԍsVs?AB ܭ?#3VGVcdQI??ܹsE_#3} բH'E:tk;vfCV-[vo-L@Wj)2* 7bƈؽsg L5srѲ[!0LG/ dWhQ<4Q޳U3p&""Puͨ\SAvoXM##ף<|nZh4cBS!h=Λ}ͧқs6Gs8oμD]=D+,,|*)Olpl$57HBHZ13 .MO?qnHYQ|WDΓ-EgueC7=< C^L DFϟ3^o}2~asʨ)F={ZBǎ5_`}u|v.fω?olvުӰcQQXZ&f&͛;EGGz7x?BeFLGkYߒ\<(C eP"??Gnwl5`V+vfQ<*QנZMfbBGa38f6GF~ݹ}1ɕ/$ѕvҒKcbl[|/6_ߥU|@sPI {w%CgOzSNGo; x3F~^OVUG4}Pě:R~Qi$?8nZϹs9B@ YYM.< %2+_}h.]h#C׿P\ZIt^&SS$%4,PٱwoqZu5j#wڳ=uVYsśy'MG5;l9.>>,@XM9S5N (C^=G ius9 xTqYԜS?5#Pp)?HZH1zhSΧ/Wy)} 8~=bv)D;|p))JKJ9.)$Zq؜omϚhu;ܐR۱oksp]vW>'%XC0:Lj))={aֲ>9Z#M'Mꓶ~!k" V99&1iC~U31u,]ྦ-Z\ֽyr?ou,O;|1oISuͮ\Lȣ`3znwC$_.Wgy3<ݹ(X}rΘKfBd홙։!]{22:y:7k4|+Vݕ#&O]XT<}eУ$?,p)qͅю&r4ʹ}=7]N@J]&#q^x!!efDl #?K/ZZAZm۲0#qgQZڡ` zdWFvv67o[nEw'+-񜧏y37:s ~G/gb^4."ZީAFX$G5ǂX /|l_ϟop!7jv z zak] =PlX={ڵ҆ DFE]R@Bxf޹0!r]aaa;{6jֲdvmN6d e(A5[1;V^;?Iw;;oWw4z^Çqaz"qg)/fy^Okz.PyrEսf$IgDQdCa)5%w{[,~=3,0}}mYH=JXjLԏ1?bծ==z6mХ /^ֽ"xZ3p7`q6W\uy筷l~.M0o+116d`F0lڰKz?uߟjy=b4m]覸x,߶3aݪUܦ͕޽{5.@4멧zW ΀rҙӣ >C̮HoMx< u=nWL\tqCW/=޿D^} G5cȟ<<I7kItt׿nJmgAsNWS3xܗqPҒt7ǣkf|tpk;=YpēǼ=¨km݆ y(0E&wQ1 L$]I(Vgi=ߖ/wFphҙѨIL~o!rQtR Le۲`ԧ#__&DD3ګYY&%= .e+x@W03q8~< ]fag% m-]f&<,NLVڃ;]V!N(´C:wdvMDf9ܸaݽcGI~#iXgSΗ֯?dv=DD"'G/y&0KƝ$ s<%vy.66t7{4drr0#q 0pYdSO.**js>"3t´CsM3#q|[3C9ֽyk" V)/xŋu-͜9֘]R@y=m:tnd""SBvhv_͵pt=~E(d3I 43PWܷf&!qfe;qnL ?7jy[?܇2zVK SF?R̞;޽{5&`t͚ɓ&y:QQl%}ol洕UU]9 (< |1/S.ŗu^JDDD.Zaƍoݼӌa6d8Ғ| r§٤Dsa=w|y7]z'+@{H۶=>}COG_BR izbذg5hܬ?%qJdT'OAܞ-[}؆ Kͮ‡C_ߌw%~.Y.wq^ݕ9CDD2u֬o[U=z?3ܞev~cC۳tt4_]wK(QXfmOiʆ ]ĉIX-֒y99ؚK,}ZTqbΞɓLrCۼ}?0xkzu"1:yz1݃0TC4jL}'G ml4jҤbզMcwO 9zS몜Ǖezp(_$Ϻwṯ'}~A}ޮ kݣ t:QQ Ȩ(C x,a'.oOvvL|\9өsKn3u؇_z~NT^Yфp971 l}~D&e/\ϣGZNm6$K4==XqzнCɁXSw0=陙{'1`i11ڳeT?`Fp"u#ܥDDD!nsCE똎^x mھ}IImM_by<`QX3W2fN}9g_6jf}^!uf'QY~8yҤ>Ǐ[:s:f-[avI;י#?\e舂Qk?3a$a뙺R̞;޽{5&"" o y(dx =٣G/gfO""w|g93tȐ ?mCxp{VȨhf$CA^$'ͮ!w~?XS`YB;L)O])~k= ׯ\O?5/g:dώcQC%f^O[}olF-KVgdkv=D8z_4ޏvٳ?\dꌌwTvVy楛ov=F8vd#QQG\~ܹ=nn 2䇉S~ev=DDD2yz]"*%Kij&O}8b=$=d7m}`bcKfg۳woC?\E/uZӱgԼq?:)cϷ\i=W׬͓ߜӦ}}O}z{G>yZ/|gQ O0g[9&NUz{oA-.Z?׼͛7:\j`ZU\\,b$nܸ1bccCkZ"y|􁿖S G,, z\]RߠutVd7GzjͩiQpp}>Zܝ۬n""""w0!"Rq7q't"5Wx8눈‰Kx>n@ :P(`CDA8o"Gˤ)#)\+x1!"""o0!ŀ+轿{9"""rC" :()qV}##?y܈"""2JDDDy\:u _|p?߫W.!!!mڴA6m>v CX_*IR'pXO!g='\qVs 9=O g!} xHr'=777`~+ѣؿmx}{Eʏ6SH<@ZڑmѢ{> XO7={}|nPhuΞ;Z87Cd$W/""""!"""E@yyy?iv1Blݺ֥/NT?ޯpuANN ǦMi&@BBƌ#F0񃜜Y;(fwCބ0FC3*peY@rnDDDD_!"""_;ysss//n(..E6|xʀ':c$$ #G]>1mZ2F/H$I"rss|1(ewv 8gfr-,;=Ǖq\ͷ˗8n( """s-ƥ"""%9TRRSXXN rH#G13+~+mؿx^zA{!EbYӨ X8)OW'W_ gvs67!y "aZ M(&蚈(0xߡ/@.""" >rs_|opG‘#Gk(O>;f-^~xG^rJu]f__~h伢(Z,ֈ˼qf~9oCޝc8Ƿ O@-KOnlK BDDDsaB9{n<,77ƍÝdE 5ʰƠAf&Q!`˖-X,vQ<6T1٧IWG-C+A+oRw|9HxCHtX$Ν;-+W4&Ұi&L 9x9;,Y,^ G+cǚ]^P*..Ƒ#G`Wŷ2d<f&W-EIHazJzuya9ADD8BÌ_ Z<|EDDDzNl_~SN}fEU*w`HH\-!\ ,ZTWиq0n8l۶ *zܴk.@QsAwޛf}Df_-XB'""" ~,^n9*-f=clXtGRmEi#Eb!m@dT٧Hd`ѫsq<ܝ9m_!"""H|Q Qy$IZ"bjzzzs=. ˘*.-`͞= n4hcv=kѶc'5*G4ɷ,VɐG= V\7oU{@zCX*Y.(yy榥3f . +杻Pc-{ӦMov}aC*0vǢEwC=z ֺBU""""""""""2Ӑp(gnwiӐX!褤e оtƍ)))Xr%Dnn.,Y4O$If1$I';_xs붷ǟ0.<2IZ\QQb׮]8pv%?\`$Is|ylI EQSQ^uqff_""""""""""!L<-kW\韕ըjx (imڴ1\M7w(.-[-[lС'Nċ/hvI.9urssqe|q>#b‡;H(/_R۲e"""""""""""y$I#,BIGi ȑ#f_Y`6m瞳C>ov9pBQכU$Ii(<^z>ܜlJ%?ov DDDDDDDDD!C%j,;%bg1DVl'44{6f+Jͮən#I`Q>=cێ1dq/=O1\#!I7Eŷ`}%p6EGK $Iͮ)gXrIv. k (-)Pzlͮ'܉k`@fWƎҀQc%I*4`%IR(iX5wBR5D4%"""""""""2 T X`Ӆ5IN8ƵRF@dTeXDo4JBàA@@ACIQ;q©O!uFK"""""""""""1!Q=۷).6m>8}hxAK[GN-Z={V.˽RRi- $Y6IELJܽ5} FL~쒈 y|j'}wǁq*C嗁~W_ _[ykwVॗ-[9?$`PP)@?dqmι]9GDQ@É}Ւ[٭SXX2lX㥥u=ǎ#*;xƎ 2{ˁ>7Stt幮_EQU3a_'G޽Z <3}w /2##So-Ҁd㎻iSe3ujeȣԿ?ЦM))DX٭y !IQ_oQBfDDDDDDDDDDD07m }x|f4lXiflȳnв%?k?߹se]6d h P01$Iٳϟ=kv9DDDDDDDDDDCj7wǐ`PȨI[M8PY:xeĊx$I'|s#IR(w1 """"" y|8w8}-_Bc),._v~\B]Œmπ<$(_6 < p2LqYc;<3* HHou$@l1P9׭V}w (=}w%IR'k#If{KF믿+??ᰑ#̾.F)8>GX~2?͋5#""Ne=ѣ}̮CZq[=F6qK]_{݁ު ڴ|i)pPe}FKZ+k?Ɉ'N4l1^0"""""""" l y &b֞~-Y9HM z.\fʀE=E]9U@&=WZ ,\3eAϞ#E$IDDQp|t~~fgG\z/y(t01XjF18pش +G;x =%ڴw8`?;W.vPe䓕Z^$ y(h}}Dcv+oQzn` Wu[W2ZiX#O#c79Ðx-*c+>]}{#KHNrsS*itא3@f@~>pD o:O?…M>womr6i9|8zĉ?u_ϝkzK(\3_dFDD㿯^(811Պfα۴o-Z'Tөpbͫ@ x׿h{[>wokW:Zegg6fL^;dıRTd kFDD+!vw7KkdvDDشn=WQQefcvDDDDDDDDxH;;̮$q`W^IN]ݵ͙vR}D#y(t01Voܥ‘zw.yHC5~[tCDDDDDDDDZ>Q0zС[lY|kE/[6kVQMtͮCc10\5k[qP3 3]hB;|MqxoGM;z ;ycΞŹgkj]VZj嗘2KA~QQ|] bb;?vf x}M(-)[+Ν=k`㏫Cc@u ~ ZZnݲ 5Ȑ!?6jTju"""""ŐX60ODDD>/qP3gbrsdslyE|dEyyrGͽ=zE˖~ tmȿХK#e]pg~z姟6~ Zt=дY:ulkw^ݺ:wpDDDDDd<>&"""_xw׮6?Cł "+**j}K}{8!VpsV!9ϸPPۻ;@AP H* #1L-{*Zkk]vBpwPR*i+̌Vih"hADh1I89;'yb ''mi?Og^3ڭ; xa+W_]Aɮk;OΙSRݷl|ꑶV^ZrmӰ"d]eei۶x1[ Ni |w>oyI v-"Ov=qcct,/ӧh3r~lt[Oysǎ??4.;6t ?a!אָ&ֿbt^]QqjK/t~w;v+*:УG=qEmr@ɢt:]{ͩ/#ٸ1s8Jkh[_3/[g:2!g2t!g\VT޷ XSu^*|e>+.swsz<^/?~'%}-@8{ȵ6<>8>wcƨ((,<@((,q|ܸUVe;5p#FN#FyoID/Y1eJңKӤgZώ7(>| NdqѻQڌᥥ14>wugX|yg~p…-\8o~{F]'@yネ3"O.^[nYbe="O븩s…"Ok??SgZ}<~N 9ǂmPqqܘJn!瞘?wYn={IzF CitzG*z?~DWwɺ]"~t:#yy~ڞ3#ozRvQV@ҭ(93^qEumb>W|~ƌ ,|%^(ϒ%0YۻӍTL6-鑀cT\wۿꊊ 7t[goJz6DsSEpVm7%= ttSqٳcHII#M4,Y vu#ǝoO%=td"O+iز?#ygDIO~ln67ΙSUVsOt+*Jz$z>pSg|ʤJi]7z([~;279q7f׉DؓI_4ϯ]ٳo~乂kTUS>~'NKz.DVN|s]{mD׮-;?`AD*1cFWrNGLѲcqt:=?k۳f߻wooq@Aaa~=qԩtz'Kz&DVo_|֘q}-_s뭙03gF,\}}uug>reDyyzZꡇ"^=""o4]ݦM#cxiiңY28N=i/:` :7ߜmE9+2K_̪o\ص+r箻2s>`UWfώ9vRI_4˞~NC$= eC=tӳIȓŽ_<<@r饙U13gFxネu""⮤h:uJz _|Oҳ@G$@:t:3iN,v䓙U=3gF(_Z'}KD~{~ѣljieK?#Y[jkȲ^x!""NIȓ#ջwǼt:?]uUĔ)C2rd&L[ wVlvYNtNoض-""'poDس{w&=%MDDѧΤgHɑt:=?Jt}1ӟk=zdѭf{D|{zhkڵ+b޼}w6n̜+ŝL8=;""K[ִ}۶;B{0XWYС<5KG셐="f͊1##>̏|$[6Қ5UC fKD:3wvcGވݣTW΍Qee1~„Nʸ;bxi yr(NצRkO|"Wv̈́kĞgt:G}{.SRrشeKDuu+WFTVfcG汾}3+>sh"btF>-[_1˦7 /]sM F|˓ :,'T%KbʬY8᪫ދ/kD,Yg`3Ag׮?߰*hf͊/""bA:~S>뮋[X_]m63ϛwv[տ~ yNRt:^|q?>%K2x|k7ܐXDTjĴi+]&=Uv܇g۶bj:ޑL@:mZLY8^qE|kWI1Y_'LgbyNR}68sfĝw&=QfΌX4""nKӋh]݊3+n5ϝ΍I'W^KK:ښ#ǞݻcTYY|mȓt:OTj]w1kV%g֬鴻0@rVq=īuuSO<O-ZCJJ+I';e""V"ONGRt1CϬYtDD!NJz g7Rnx"y_o b܄ Ȃŋ㙧ѫwk+e" HC:j9, Iz y݊bi1uڴXlY1o^D<Q7_cEԢE7>1fܸRRЦcuEE\<b)[QQc-$1͋)/pag'=UmwvmDDvl'N"ONR[>VZ.⤧ʞ%K2g8I䗆-&MVX|y5ǧAj׮u1+(,ᥥ1$}z i55RuusVKUU^{GرT:{7 IR۾=Gi"n5?ճfMD:`ADα7sI[ Xi"""&VWTݰ!Vϝ{ /-ǹC6nٴ:z+VWTğoښ9>rd?bD /-AqVI"OHRGē=E\uUD*6cƍCܿ?>Nw$=@޽WއD=wǺX_] ?559kǐ8w^ZEݻǐ/6&ڻAUCᆔć'LsJJbxiic`8'HƤRsz({#˓0bʈL:^lRPX޷Z??|ODD8wջw <15ȫuuj]]lټսggc6†CCtzmdp6Ğ҈믏6-kͳcGļywK;@pU? OZϭZq@'"bPqqޫ!mY_/UUE{wu #i7&O bxiitݽsyػeȻ+{DŽ|&N䒈|$#Zc%K"~'ؽ;#wC@ְEճqh@ꊊc{xiiF{A("Ytp BMDfg}}n|7 ߃AqԩqrAAjWrIi *FDRoV\,ND_Gw^fKn^ٸ1cɒڈŋ#6m<שSājD8JS@[Ǎ;kV|׮=wGDӂDQ_&'=۷m_8_'@[Ub⥗n듞:*W z.]M'?鱀fY_ߚ93.^ V]w=LБ<̷gy+No}{Q>n\cMP[S7^w]aCLM$O <7lȭ~?C&3gZmx{bܹQPP_W;ꫫ yH'}s~M~dI˖'>5D5ܸ;ao5k#F\@@" ==U+Vy筷?~XL +{ !;Ŗ͛o~{oV|tʔIJ QnjG?шqO}={ GWWsO<8c܋_WKz6DڄOӧ_břVWT^lY/.:5&MڕWbҥKsyӮhDڔcl=fvF}w9j~uٳO3{v <8&MMj;7hNDDN?K~;`h6GϞ{f|ʈXjŊ3Ο?w̞e1$OҤDž6m}uuX,^1t+*:Pzo|⪫*/8.yh]ݳ5"bO_cÞn\*+cmFj]]g/˖8S /-}ooON@^xĺUV8sO]欕˖t∈8W.KKcTYY ))IzlhU552_6~ }pݣʶͤI5@:xODď}tȯyUUZ褧->rd\0zt 7&=>ꊊLԩ߯Yol\OWzoo~@yh7>>}O׏ΙSRzuښU}4xp;thSRKKܡC[QQҗﳺ"WWG *UV6>WPPg鳻w\xE.jz'yh_}uYbř~A/]w믟ԢE }""gCq14}ș۶5nxm""zq ˇ 6z̘:ۯ@&a[Dē ]gԬ_땗_g V.[v ))ѣW1ZluEEcY_];cuE!ҥKѧϞ /9OwWD<tp2e!VXqϺkֿfm~JmMM7[QQcRR^;6m^w< 1av޻{a#GnxĺhD8A+~wG)ym˖M=6o}+ty .^+Cѫw8xp҈T\zNRi=w7&oھ=jkjb+Ė͛u8coϞ=5jG} cI v/{9sJ""~""6=_ްꊊwwjED((,Aݰbkg}}| `=O?}_a׮J/p>w)s>Vӣg=I_#><% h!!mږ-E6lW:OZ]Qxy1s""01tQeeI5n]eeٽipMW_=qO@Qu#Fz#"gϞйnq$<#Zt?ݻvu84>͛m~啈زyseZ4Hrs$M3G3t;uKKRti" 7]s~$aʇ c /(# G{:O|E_⋇x7 #"bv?KDDKR6t?8Խ?ީSۯ_|[w6  &$ *bdk 3t}tJD1 tg}A3g^cjk$ !:L@$g}`{S mB ǂ4x[嵉}FfL@% K}_]hQ`[\E-_Cs@p}'fx}5ϴn2L/J_B v / {%;;rix}52L "- 5 @@' K+"{{&&&7Mú,,44){{<<<GGHHWco'ZZ Z::&/O羰KXdZZ   2Z:( ET^‘*  ((yX<2!M1&w<37zW ##ĺ&zKM#\2Q(88 ]F Tyסis ,pNlLfeT`} "ľzv\NoYdXԉn4>qq\ PH7   !+dD s sG`atNU V\X' NZߦ*Z\.\.\.F~~~*ZuGuGuGuG$)/7uG;uGB"[E/O4I(gSK$!otl- *(7 "rx -9.g,tL#ݜ] %t oQn<3oC9Qǯ<uxZ#E $"*XXX7_ՕdǯwdMuJ]NH$gZ*X 椒ECn$h즳r͵tXݛW \Α"1uqlωSygd   c/!', Lzz$).(2Koo$ $( \/\ 13zPNN䤕j|<<\<'' !,1p,4觾ڢ/''...w>*pO qP 4...nPpZ!"nP"++hN,!}\ ;(k$i?(E3 DVR!  ڠ%559= #4찰@\@;²Sbn&68=A$5`칪[jve]R "`y L[goH lL!QQQ &!:83 &3'f3f3٬X GX_y% yw1©_' % G1W/&}g4fDȼsK$AGM(1oe34?I܎rCnww&g5¸fEqi8  nۧmqm= XuN`UNU` MGN`! !MG`!$ N?[$ & #+ $0;v$ '   \vQkJb|Lzۀ%v|z%\.\.\.\.\.e3e3i8^0e3^0h6(1g6k; \.k; luW(1ða@)_hm ! , Q "*RW\L rF5|T5y{`in&XM-  smhDtVu<  b.3ɼG  NN])C4>=5 (|uwS #K|ES+` *v ,04 H)T. aDjXT\fIQU(>>i_gJ% IJ, XzH d+ _I)3P؍[Z(̼X@",$.,8*. fUqqIQUT8U4^ooUU :iMѠ}FWCrht.:FwwwmN e  K?1;Cchl@6)"pW')O[Bt)4wwwVVV XB<#Ke fn{u; mmm8899lptTISD '' ((D#DŊv;vxwE +x8[:FrԯK C33,(~<v;vEAAAHq/`) UYfՂWҰ" www666SVVVN!)h3Iik<|nitkZb p 2p39B8.VVVVIb*)%  񍍗wyq  E9&p $Nsjbd󘩖ڶrË]w; >ʛ:d/s G@11`bz!%%؊=o||""))AAa꘥ʯ}g@੩&c;  'Zj9 Xn  !yO\h"'+'J< ]x{/ jJ뚪(LsS( ! X+  tP!!gy (|?N4Y$" )19 hH""" 黻IIIC./ 0!B,4<ᰩ PW^^^HHH 2 >=' PWVVVjs!53$/ppppppu#3f' N}喏; /fNg؉U> G G{&N} ʪ LR&|!!!' in\\` G 6V6V{|^^^f-`g4"+5쾐ppp\. =pR$  \.]/ʽ(6C \.\.f4\.L&Ode`C\ƺR ]2#(8 HK' PUL#3N`N)o]*] :](8 HK' r ׉j' Վ .XJXUXUG$# \.\ \..\\C\C( ( ( ( ($( !vv(\.\಄.|\.)Wœ&d(\..|WWW.d*%`3qF̽rQ£| _1b6 +>Pc5a35X|f8 h: wIyPlȚlf4f4\PlHn^x` O&T+#XUO&T+#N"NN* B GN`XU,NCJ鉶 B GN` GN`XCJ週`@ BN`' ,% FxF@ BN``' ExE׀ )N0u:Nn EP8w7P8w7N!VT/)^Xo(Zf: u(1)szb[&0`% :Ϟw@&77"7 % 7CO`{( @( ( ( } 6BOnV(WoMcy a4ɽ M(ʾy\.g4Ml- vFW0pS _d      $_ѐP+ޱPZ\` %L   S6 }D?w!#&!#9NQUҏ H     kw  "$!ֱ&HܒAk     l  VZn  *Ovtg2,A;-x S     tS/: R.>vwqphjir9lI?K-?KFIK8Q>$7 ȉGDAR徳UؙRk!?NFG?mVW5ʶ+=^}$Pl"YG3&̝lF *BPcgiPe:$ڿ_`];$dG `5$x 4 3:5().+'.+|~~~-wf  : d!{!X&{|?4 3:=()a9`%*.,(뮻Ӟ/5 TW`ذ=*ujg=fV0 ̉Hdq! DQBe+$()3 - f  ەM!!6-VoH9 :V7SJp.d򜂊 *}[8}Vbiohhh2^=G`B g\J 07>@u<1ACmkٻ+]']$}V!  )44g#I}}s88C{-, -.Cxy~~} }{K##"LO%D5r~BBMMwbK `I ;C,nET쮡1;CCCCD5KBJTp:˺ !-J// LHTq L$>IJD!V[] ++*~~~>I;$!/\,%XB~~!s} >=KK[׻22#' JJ4A~n ϴv  76VD x;ANjja &-jkط~o>HP,18 ذP(PLR'193@ĤM| d,$܇PDPqUGGuu} _D MxJ:1)DDȐp8pc}HHPO4܍$$gܙ&$UCVI(CbZ/>՚{ A?Pu~p8pnObYc}"5mm$&$666Qvɍֆ;&٢. Ĉzeee͋Us00e7^A ©\F"f%,nUk= >>>>>>rPYR$%i-B nD$p같8! Li?d^BLxyxxjw}D DPc? 2Lg Zcf(/"!y!U&/Q>o{ p53 5(]fij"(/2Zߒ^*/&|Y7·h'jE>L)sήyQ<*9ڗ zmls@"S6  <67Z֛ ry5' LյW  ??!!_F A'' X    "%' }yy x'[~s[KoH!Vs  $($#=GOh\X 7ºcr !?@z Bg{xS$Ϣr(31k.39 +/2~ HH?3@J$.0tӉQWbTf}]KmeL?  '%% ӏGHɩSX?1azF4\O1)/3=!5<^G 0! p? * f3N<**N`Ԥ`)\NUNU}U-q8Cα0dKI,\Qg؉U>ϖ; /fqcoR#7Nd+5 jqbbK7xxE" D54nO NW6?=``in\\|oY[!YyM!f3khdo\7ѥ^xõrbmyBeo *3oqRAO]c^x0=K0=K Be_2,>Rc_2`4zGZm{W3.7@  㷠Yw%4D79;|F]t-AVklmE\sYw/?O8DOh7@Uj  E\s??w3' x}V C2|qV <NRGN_NU N'  7 ^lN 8q3Nr K' O&/7^"֐(" /No`wr;sM(  oNp@ GN`N@NbN` GNb GN+!7N/d7 _1pv1 BwN/Op  6`x```p     +UU6^^ % TTT JJBP]bJ&sK%#C.pI# !   sGMcxWo٫}l8GWX*xR,(0nE(3>|g<e oyKÕ|&5HHH'3>;M`ȼ/?O(V&5H;M`uRh*KKK/?OG^v\. a4pAKwK\. ^0  o9'd]jcN&AEufV555+`gomͽ󨨨Qey ¿7?^O =bUpbUXXXXXCyng4$s_nX3q=k *FWwG5* >Mz>v|U=U]3d&/PHD8AX`s  *###uoh9u ^ \3z !|օV- "" >5* $"D"uGA$  3nw4nwc4k`ak," 9iw"%(   8EOˏDVj5K†B9 |i  z  )qY&_*)XD%f9ʴ{RA.ц_>'k1:41.4Xf ܙ(XY A0 j q E Zz-w>!*L%/ 'Fe1 aIpn,,)^i M* /*ZdY7 TPBnnn;e&l+jMP9 6Ot$vabS9#[z8 ΁ nv5nv5 ) GFAh/[I)t_6]tqnjTPC復)Riatp `D eH  k/^ Ob@tS dG 6y N٩7eOSQOlZc|C ]FAbP%ztY#7IKL-& .;& Rjl}v/ hhh \.m7 pYK) wV{Ҏײ/F@hȢovLʂI6m 7e1>J%$"c|CO.t3 1 w. "!ޣI ^d԰ű.;( '''E05 \7t ҿGzGana{ny\H \u{f. 69C2  PI - ƀFF{{22>>8AH}V-dWH,, Y *{G=5%NR_f]G$Tqlɗ~n 3Z^Ѕ"u VrW *a(ȫgrr A1%c~ n =@:*j$110 }S S )N|;qrKW`O4 B>; H[_a0-%!NR_~^=7:Q~ o1{f{f*9Vk:W66 @KTbadT<;  deY332ee`ee` vv 33<<((P֬z!;(/6dS[ع-M"'E1 fs811 02211-S poomxEEEdd6ffGG,,,[[ } "B    oo"+16z&P ^C\x GFUUUffN52lߔGGOOZZffM6'/#Fiwonz^8"$).Nqq12&&OOrriiMZNNFFӦQ*W $ރ""* 9BJMLI? lVT``` Wdd,qqaa  epNNFE|ZRZFFľ"S=sxt  =6/ 1kkkoo||  ekkpaa||SRBIII %W   S=7Bg!+ kk}}}IIIVVVmNV_:3 S- AF]wSZ5 c$ 0/   YYYó FFF@@@444555vvv%%%|ղ?eOL 5^=4 q W  ZZZBBBBBBiiiVVVװCXXX"'+"&|ty~>,+48Hø WN@f [\\"'+ L;E1?/  NE==HK$.8 qO1hEE2J >7%*.2 _XQN: 璔E1? Z*ztB,r&.刺rJI0' чDA&Z&{DfS.a f(ĺ *3Y:a@   @huZa t{ty0 ) ^_<tE+b xC $!]" {|&f567>8FO R<9ldI 5  [^h՚[)))ʹ(&#E71(F2Eū&0#핒t|ſO]h~[I8 "4M4M==29@29@`c;5  uu Uk=Z~  +6>7F! DK b JD>ov6;>Eϻ!&*  Q%%#f zr0V@!D>ULB&1<?[HUa%1<035FM 9+   '( ADV  CQhJKYd JV_ , "~tw%8xB `daq\s2)/ eIst/:B/ǿ4:B wn훟KKJ  ??? &`edB,+w.mD. ALVc-5=kkS]U0  !  aG!7+ ) nNAMXIIC ]S55"#(''')  lL䈈81"!& z{WWWWWW$$$$$$tttnnnb`E-"   ED (xx'''kQ nnnnnn____F8*  '%#,;;;L:L: CCC(' '3 ssssss  30#22uwy$%Vj7mQ,f3|n`|n`<N&Ic XXb/E5X0+٭%@k85"X' NC$ ~I*Pf~I*Pf:SxV5S*gSXD$ ؁RSONc؁RSONc]^kYcaGakawX' [h8Ŧ;\ncS_'ԶO:bv'ԶO:bvƁN$>6Zi ;\mϤq :KxR̷`J|JJ|J GG G1\1\UUV .M8J]Qft__fg4gg4   AO\#Sj}`9(#+4Qj0=Kb5#-7\8Ǹ6@Iɻf  `3 Ɍ ɽd.@T@TqeQ=RRR Ɨ6FUUa4#2C[u i<|Z!,8BXn_1{i8 a4W11^[[zN!qC$.jUtaQLk: +Ih ,70EXX6FU9L_:K\tD=tB9N&<;d/(݁Q[߅ljX' Nr   6UdGNPqb.F:g\dS g{ɤnG5C0S /]/>فSTiu{XفSTiu{N#?d5QYS'b v|Vm`7^^C'6kѰX*YmXBSL{%XBSL{h( rg*!O] =$- BwN ]ZÁR/j,% ZÁR/j,% xuL)dTcNU )Iy+#XN9' cc"`>GG"SyS,SyS`|׀ >a|LۯG3fU{N Uύlq}[/hH2dR{[/hH2dR{P;e]E|kO'b v}퇨-:F߬!(!#%QK:'  9>'PH7'PH7\5a(k rg*!OhF! u "-8Gʄ/Kczy᭙v /4+ʈ9&6[ʁP@dܗ# xuK+dTcNR]x8K_  9D5z5^~^E~E_ ~<~~E_E~E_~w~w_}   x clvr   鑕  h<b111Ż  R. ::snj҂Pg}_2 ^4 jjjLLp%%}WWW.... T\b^oʺthAAA[XXXlxTcq~tsssSeeeeeeyy6aUlaUUUUUUU8xnxn!\t)6AݮƵ"!/ 3AORh&.˪yT>(CVjPg}õm #hhܶmz "7+6C"+5x˽* gggHWeCZs!(0=K0=Ka4123f<Sm>Rg(4f8J[FLQ^_2y(3,>R]]]:DOjnBxJ&&&f;SozL^a5{ASdǽjsM&ژ K,2xS-j8+9HQm$.tM'uG?TjKe}):L*'%dCuPjCYo5KcqppŶE\s$/$ 9XsqhK' NbPCl9Xsb_XAU9N @PJ~ XN9'XN>$ 9PCl9Xs`_WASUpv1ʦ[[,)-)H܄z܉SUpv1ʦ[[,-)I܄{〩. 6[\'G``GG11s`GG GG$|p. 6[\'AlGG`` GG$|~Q=v pUV1΁XN9' %lmm^xU9N @N=% N<$XN>$XN>xaV0 NiсTX||k8GWSUpv1ʦ[RW w/NO!-*(*(`ab "* $2=t. 6[\G`BBxGG`GG`/`p !'  \.sNhIazLv _1 Y]bj>^}N)/bbb Q5.q888Wnnnnn.lwA%V-L ߑH#.3H(ǖ5D)r? mR .H|6T+xh<b6 |!#+y@JnI5*|  n~ uBN+ !ա7s - v ]jnM1\H6VĦh/+.cyj?6# $,0#dR'O n8>j"NE|Oj諾*#:111 { 4;%I SdZKziAyv!Μ$U6#)L [[W4t@ZL>_~rdS4)c!`D=u= ۮ,_cbv   `C`CxDR-mbom `DT@DV>I@68,Ӿ0kG Ūdmu  Q9Q9phnL7 cpLPsmGpOZBTصdkdK>;0ͼ)#apN-B ݛU͐rUj~  ECBq{y46Aó@Zf+00   `C`CH@ $zǃ?W%TSBo@hס #"t_p˶"6Ԍϧ^j~ssupu2O<+KD?8319?^[`f'*}   hgfQ n``Go'mycVcceLwq_ЙW?g`>rssuu2/& LQX7&A=;   :jElA ʓ *Me 0?DDC|ak^wq_9Ms`>XݽUC?>horC# ȿ +!ûV\` .?%)螞9itnoQ  fxBV7hPl"J!x 7"7NDDC\> #c7VaLH 8AM?H7?dH$ 24<蔣=L  ki YNzD'~چA6((' )ֳUnΊyg7   \` 7r޿>Lp-$܁ZFGiXF5#)=۔"SJZ;3=g$MJB/nO7(=x uo%NE^! WgrSwwcㄮ[j[VېS)5"AM8nu#.26ꭝK&δS(K nz`.9{xxó@?0 ruqx.^X, O8 pP' ~6 %g㦇!h;L>6 Q0 V :1G 260S}S,#х/;`%'9Ksvr ʰ7aj aG H$5 EaF ]B  a v#=K`F lv |zLXc"() B7%Xb/՞~0!ٞS+HXIg ++*,#0}l(.84/?Q^MvoO^Ӌ  Y2En SﺄL{ ee""P!(&ڽ"9Vɲ CE C=)6'b"?:#T@K/0[`oooX0 |vs8| \? [@  `M %* %0"- :kB'rSS }}}}} !C$c@922м,AK:=ui!##D8sVuBck+  °cH}c@ Dj7GS 3̉.fX ek %ZZu$19!ﶙ![N٥lf)GK:܄ <@ϊi1vM_"8($*X ,5, >PV>78%xtRE# J'K)16գ_be[/ Ro|'U_E_   D5D5O,'m,3$|1vUJE/jt?-{ LXOQL\cF W= O  f*3;'2;\Xbba+ y PHOњAx'UMM о DOX"'HB "@S{XK asiQE4JݚX X*gǒ0bsr __` +-311xxxxtua(,@@1X321+' @SXK,:=:=̃ 4}̊)Jkݰ#߽@3ޙ6C652###KX[hc_ueL%:W-}D b%!A! jpu 膒  M5bb95. 4} !4q4W,W ,W#!C3%j[2$$$ u::44""%%'' $/7G"&KW000L! ͦ9Sԭ ENW%:Hd. '/6'/6ߪ|W( %}0A0M"4RQQ55DD3;B'''AAA۶I[kvJ0S(  >F;c[ #$1>JJVضD PK%777&&&444JJJ***ݠJ 6q"  '#qi4O  #p3Id)(-5 ******\\\= ; 5)   D*vʙũqg,9a#GMxJ}=! tt  <;;!xSxjLjʬ;qX541+##$, fɿDD..%%::7  tt8(ERLoM2&& 6T~6TUTN&+H{{ ґuu( bp} de-b_ww%YDh}E`#X#!!Ž ",ճd?a(. "AlXUSijkQNM10+ DF J99r#l#`K{%MZ]rhg6iEkNG'"A}&\]TT^W WWgI 쏉{r   " R h]:Bp%%55&&\eT "-vvF-&333vʦ|au" s  -" u$򳭨#'%+0   fff,,,>:Fth ЖfXpZ33@79ʦ9hh0- <,9D$޽C@ "et!&&L qCOs |z@%x777 KW֏3VTf 趯#N ]{^lOs$%(?Lj%@Axuu͛e3eqqq%%%&] ~7 㸆ZYA ).3   ^@}?}uuuue;e sݍ##Z]HH@888 ul, 03#"#;BGt``Puu`,߾I;Bk##dII@hhM""">;>LL*3Ⱦ#(.ꎎŗ* ''xlO`,+ B!BpdyffhhSR8( U_ ĪuXZE+ATrGBH&&  vvvKKK\))qa+ VVUWp ggvbbSddpp% QH6@mW RNT:uuup11))qY 0qq.3 wwDggpR|pspp&]Z\]\4 #yyyy@NYޣ(˕/k<< YYdX OvqqQ3=ps88V=   ^  * SSk4k󠚜gmOvQ 'rJY=*,#7n{SS  '*gwQ !E>5Q.h& .  ,( )w`谄(]QP*V-'g:)ъ ^< LL 竫,,,WWWCCCiiijGH*3JJJ达EEE666```nnnCCCiiiu#ε䨇$RkJ/!!x:c\*blG( Y2MMMZZZ````x~iHdbYJ##% 8%BBB %&LڴySDPUOc>%S`)0aП***y5 --  )8%-8*tˎB`PrxZ]wm9 5bh$7 TxjX ~vCDNlvC*** H H  0G` ! !-M-M wQ g3C rPesS  mm}zy  Jt,%kX7 .d/ewV`  II<:V\uT$,,lR  qNX5-Z{ ׈|yyGHY:v5UX!3pm  #%!$'  ktH;Y ! Ke )^^ f)D-˵:һs|q  KvHdpB偁~^G9Txat  "%"%/=K8n !"m $Q $$   (5KbF4%& J^ePbpȻ5AI!!=++iOq |~Q0aDII # X' TE ǻ(>1 NamPbpGg5tttt鴦06=>HPq.fd^g22ah9/8@$  k5FI?2%  Qao#, տZcD,k '%*-4;@B@29=-7@  8!"!" f $jҞ"#ʟJ[o SMTNU. ! ]m{,1-jW :.b!oK6í&BUK@7YKk~=  9CJhb,1-> o. #8d ϳBKA? =GO "52-" ><a.C<.     |'>\\.a*35/&0 ^g)k{P\f]lx5.' a.Q;;1 rw㹘Y5J^  2[<.2$# NYc"ƩP\psx 5<K,H-s Pr.$+ gj0"Knh2땎sbq~du톊 > %$2%%%% 'NZ)I\gar  %0$ """ :';0 \m{{{ )E<-D+++[~꾑o2+` :+  -.ֈ;;;♙dddaaaRY W> B> kk kk ??????ƅދ???J7+-*1::: CCC'''&&&YB nj 4mmmmmm-#`?;~$$$uuu===R<"hd **1 ZZZZZZvY 솆SSSiii$$$U>fb .|] SSu```mmm WA\Z **1(((" Y8uuumbbbpppz$ 蠛|y SS+++nk  7777ꆅ GE QRQRll jh z{ XV &(pcVES`-@ 'g#,:M`KYLueOOO lr`js345L&sUg4Xb8hGG5N9' N%'9OMeq]:_\w:̝jOhS#X' ӴON1O$)UmͣeO}4oiSΖ>rA<&Ζ>rA<&2=k;Ud-01V]Y:l.]˯J܄]hAK* ܄]hAK* Y t =\cy   ƁNq‰." tXKg‰." tXKg}˞hUb:1 >g1 >g5b5bٛ\v w,- 1,- 1ݍ˧#U& 'e$ >c+3ۑz=>c+3ۑz=̥oX Ԙ`t=jʠf " Zw{;L0!Zw{;L0!X*EZy+|Nq +Lw~ablwvj7 GG$\j\$\j\``7[>>>·h6qG222g4g4*<  4ANZt?Pb{SWZ#']w1?M천?<8H[pH[p" ZtZtŸhg.#.;H$+RRT$(~cǷ,,,]: ]}ô rJ#,:IvRkŭ_{j+9K.9E^x_1;PeTi~+6C .=K )6AmDh<kBXnPg~D1w1BS]5Yw0?OʼmM}Y3|l< '0Sn#/:qYY7=f]]]Oih6]|Mhn ܟó}&/m0b& G S1܅l' zn0 GG&IS C06ԂcS|w#3TG!]N S HxS\n.x{ 4b 4[)I߻PmJO)-{?i +!G+!GExE܄]iXsg ] =  , PH-UBuk#4H-UBukR$wӬV˗"Dn[lmN9' X"cc GGSS`77sD77sGGNN5x5΀%&oςN(}~7 1pCۏ6o`-W7tg~/NS9N+Vٍ2&lZ)N+Vٍ2&lZ)ф*]T'aGb@dllNl)N_K zh`z-.pa`KzKA{_uS*| 7qbZ*| 7qbXSsQy_>Nƶh`zwi   N[I߻PnGX_g|CWj. qA:Nα,ExDކ]i P?.DXk(3ּ2tVHw1-G9 b& ΀%&oςN(}Qu΀%&oςN(}Qu i GG&I~7 1فSTiu{N+Vٍ2&lZ)N#?d5Re{#3TG!]N#ijf]wwi   N[I߻Pn2,&4/Thm^xٌ=M_. qA:Nα,ExDކ]i  ,76"ATg(1%%%n%.tVHw1-G9 XqF\s''' &&&;ObXXXXXX7I[ ٰ سmnoc6 PPPQ,ddd  XC=ʦ@J?xY YD@XIFC///@BY+owKZhJJJv8DR㣐|***"%g{(1<ϛsyyyyyy ;}}J"1\G=sg41B%xA !. m 5$k;[1 ]quu  K&~7z| ,J)9 Q"G $f+@ x E'H'" !K*{C)A &A;    $J(C%   Z;ҷl [       eV9#'  2L*3 `Pdr~s;ECO1D>Xe7\EFA3-i0 "1?    ZD_A)!C&K) ":* (%%'jq{ %P]N9=3!)!Y?Y?*K*?" }toL3Ilz5(ٿ.'AMGDzP@]Nt~g  Z5 +"!GZJ  G2G2 :"M+-ͷ49K.AMGERCY 7mɓ ۽9a0C+ŚZ;fZA-HC03. rqhzql  qOqOF(K*  ɓ5,V.88A<{څX&Fw_U>?, sip@1"ξLUNU'*  ++~X /N+9e8 6l'PѸb0Gob\] X&lPNXTWF  Ƚ( 3LUVD#&.%:J(>O >J^O"" !ĻLA,(@  6'6'qO>$O+*HHHчŪiM/Hd/Hd. 788Ec]^R`X('_Ue20. Qٯc9ADT9BN$0Ƴ9A9678 %0 T)"&@46 316  J4J4آ +Y⼆{{{uqjimr \i[y HH{iMR`[20. b9՟">npb?Kd,>5- Lf(FZ KUb 'opn$"*++jj^! #    tQtQnU;+ wwwTQLorvK aJ#ʑ 3l#)&N G » \fUt}czwG{i7F&&(0ț!wcDz{znYL(5usq1vO п9lczQ}X zo0Wv1 3®IXarRŴ #,ķzhe K++ u "%   eGeG&micxy{!8P ЛM>"p P>BQuLWȆz, Xub 0Ht89SzmSD@;\u,뫮sM(dAmcXÿO& ΞL:Ƿ B = Kh )     ((X`n --,--,nXܷ~~~ZVP^[Z4K-&y R. CzŸ3+í[2*Ğ֟}Q+ fgv3NQ|F bab  뀄ɬ3R'K)$"9KC@ļL>U ഴ *,B !h&zh,) qR@/ " kI8Q`+fP~8 .Ҧ)|T5(}W9'G@^bIlըƮ:n͘'g~[_ +޴#/}oGX]\ٲ 0&32-TG4   ZO൵&0F#e T> rS6' ҙHOHOPxx(#+"^d";?EL'Na`67 &2G]]-*vUP9  l  )!D &X@ \4^0:FWNM;^n>i&:`z6, sVgf[E.-AxY[biUD Ҁ,:gT6%K4-yY H 9ZF@< LWd ػ,; .0. #B0 D1    XS c |+Q vi4QC.]T +xuY> $# wjb)#(#~[# ѳ)J]SwF>9۸"#-0(&$5&;*>-ʂmӊa5\p` |s,W*{X@ bG2$rRKyy,8 $H=zgNR#Ӟ&j5  yW=caJ"t00杣t]C$#c'%<{&`J1\ /M`ggg*-.6=mfTӘJaȶ %'0ۣceg8K( #C0B/  7.c@3!(,&fYO2-7/7^ D :C+o_ ƅEsSu}.hS%eI !.9sl 3'?U+ Q[[VC Ԓ7 <6"<6wqM++_C "hƶ𴟢Slt ݩSD4 -)/F9" I HVP\&7'?/ 89횶 gA/?-#BX!%+7,5/C14g ֛ߑaff»-4: $  8?CkfaHA" J^/W_4 ZA8C989,%\lX0ksA[ܾMn^yxEa +$ VuVu pzx 61 #bb#Q?3SI4"# 9$"p  L7 L%#- dq_~A  Gʼn  5c  ТȎ[[ Vcnl=abJ!F91DBAA=; _p}Y! MR).N6rS60=.^CD;v&V m)i)i* x'a +0   ú+8@+⠐%"2xD'˘a6E?#!$\QIE0:? +-IPQy0HF0`O ;)4F2 FA @=j Bui}":)?.  j<( ٕ/,.5 z0[%Qhѳ 0mp vsv)0 ȾTh%178Z-&$^K`zK2 oT=PLNrnll ئZc7  bD@MMS+,v!\V= wQII1;?BBBe6Hi2  >oD uL 5%%U)  ׍ %/8%*k v &NLW\ oN6]-ᠠ7_Ün $"ܞǛłfE~*/4BO\ Q_@Q#yEg&0*v  P4~d8K ͎o#OR#? ܠo=gY4YM`Yx: 4d!¦*>ZĈy63%5=6iV= v/!6&P uD*bb|x¼5W(*OU_ m_o AB E*B2ÛllÜn33  $$ #"%+  =CH olϬ$2#cqq0I!1Fn2r(8 )]WK-n":$&*>Z]  Ń  ?uHrDzh-`^?,g   ';Bq{ ." 9C9 ˚ ]^#++8B  qq0 '7#"᪫ٮr .ZY2n΢;inbbE)7/ *G3dn hͭ2R{$$BS@R T- ":!(-gT+:::cc?y DŽQ3]=7L#"zGG)((*5*0>>  AAA}Eˆ666gXL% @[9[9d<2 &=<=;:;  nػ A Iv4&2 xur !!!!$$$J}IX $5n5_iq%  B >+ &?00//fUuQo+SzT]bT1[6!+2q}SD3+ڊ 𸸸830#" ooo<< P:DpbbVJ &,ͺ.BO ɿ"%(]>ƛʝ1!*N KlYfSgLF)ff29?aR:ꌒ P *^^^^^^ 33333.!4"48.hch qmi 8^诌  |bD  sᔜ.'-]\]X1Nl tmmtt,.0 %*! 33((rrr9:Aէ۲ii&& 0 !C3?  Ⱦ /!  K Kkkiy * > !%iecMhM2Z]^tY| k`n >?ɴd9#]&Щg4[M*f,f>F  IKʔ::66BBBAAA~Q!!!gr|dI2rS4[=!% /F4A嫮0,* 8* XRWUTnjn S   ; ;"I JF~Ѿ  hz&&&KKK -Dp8pddN`-\P~( ^b]WMF@÷0 ¹$]]+!rmqjj᪘bt؄;;9BDA qoΘ  o FD;;;KKK ܷE"EA D//*x„{={a҂&&&&?LY,,.9FP  @/nu!+!O/*#F6)y~v%9e`#Q!ot&ځ)`ݹcGwt: }yt  giZ#I$IHHZۈnx$$|$|y..==''Bccc+%뺹 "D7ڞqDOL5"otځ)`#Gwt:  ))rH$HZI0rx% %? ==__BQ::yyssE֬T+T::LL,,;ccc1118WlZ51{vz vGGSqC&&    .7@!.9Ƌ~?~ff$+ X,XaaQ::CkFU*T ~)5555r++#(瞐{}ƼD#DQvv!} &&&;;;JJff%#!XXY h/G 44߁!!k6kCAI F+spp||(w@ @{}bVc=:DlQvvp[[~!c]lll&P0̼0CM0BQTNO8HU/G 4^֢r-z\IO +,-$$$핓ZXVuuuttt```PppI5lGG66 $$33OOڋ&&!!" Cٖij%%+߿A!A|nwl?b^ceel͚f3fqq[??! ( ']\]" 7AG(Dp~ LI""YUS ֢rz2\O luz lnln pp~ 66$$޽C"Cms" 1*SS%%]]&} A!A۶I%IV?ʼnw;wm>>ee!}}f3fAy=xÆz=z Y]]G40$ spr pXjD5vI5vI5  |l       -4; C"CggM!s1*>22 ~~J%JKykw;wPP..!~y~xz=z00 ?H5 ]B ~*(     W jblhy y M IHْ~(o22yy|ee| * bbk6kwwxxxdZ Y ׺T`Ai `y55 XW!! ׯQ)Q(oJ...;% :PJ(.. ;3 Cg@ K## X> {P uU (.3 nb T> . N&# vW w  -6U    jX8xHdd-rZ r @G ՝(AAhh2277Q)Q^^^>>>(^6=2o`g6PeͼoğQKIN}ช) ...---MMM___ ՏgRmUT _C _C ƣsss 333###QQQ//////111111ñN110"""  ((XX(1970+ &iiiiii (((((( IIIQQQ'¢ 332>?>%%%bI>`%%"a>t5+"H !]=30 "lH! ===''''''s/ `1B߭!Sc"\ޤ9nOHFH=}A?NgzOW''j, '1*¸%. "mmmL>wOt  :S-%n5 9uf" &4}~R)BU Y+g["!Sc̔(<+Ѵe(` ssss 243xF`Y〵5=5(!ss ƭ}* ޾71fe1F@I""444 xEwkKts?" ju~wy0WfxbU8^mR_{(29z^TEAA򓍒paSB1"e112 ]5 $ 8$3kzm앃׋ 55IIRTY+,*. %*  (& 6' oPv 5Fv{-!Q^}9)F&1u|xn"0T72! . {ro    >%&&7,(2)N^8N77<#AC <,e  I04#' ,:Rto=J        Q:lJ R- 'LI$Zoե: 9wW)?e B+J1+ 6   B6YVNWr9- U@ gN FqRtp$)e.F$:$    <'I1(, .C3  V;sO4$  gnR`Z}`k0# Ѷ] 'G.+  33c<   hFI36(  V`df(c"3 dqxEPK  T/a5  Lq ^@gG+!  CJ||))q,,   ,r     ?0I@]<_%LbD^@   (( FF]Y ZY{222 L 5e QfA zoC" o Ze)9 cBfm,ШґG#_   nnqq ZYQ6洆ѻm!4&&- ZZ ffpTQ h T}X0%ZBS9Ր  p !!rr^^TUU=Cm q  Ɵ4Yh5U' -ͳgcrMt81 G  A ݋e o]hG)1 ?O uw5q8~UA6/lt\V ;X,jlcc""Q tofR=+7X3Z;?8)H?1 ! qg&6 !"# =)|YqByk" G1"&* !+gB QQ;ii;; @*$&,Ȥgi:>7317=Rb.C o   :AH !23xznر%6SʡϸqP}Y #(utwȿ+3;@LWZ_d$,2:> LL* #%  3&  #$.55K|@0'\{@n  \\pP#"6   ZYY[ZQ >O]¶6I%Ǵ#8dJ1DѵHiWr!& HA[718>&,1 L!( $7[)BY@I@\u<3 ~kf'<7024462-32.  [<'wJeϗ9Eǿ?6G0 (#!"j3 ?KUHe~V JKMj6=D,3:   7= BABK   "@j0XA)B*  d "~¸ﯦ޶AIR 2-  TS51fc&FFF +֨ GGGEEE+++ :+ YX /KKKKKK @1۷444@@@DDD )3%  [Y!gc%$  )222222{{{   Q=⡡GGGDDD,,,&3' , ﻻnl WThe -######ggg %׾pHHH&&&BBB $2&  r럞燆:7|EENNNNNN3& ؖٶ1 pnFCro abab444||| 腃., DDyxxt IF ____mm ]Zc`$(   "*cr 6<@n*34333@6, |um6nnmr]I#/:XuXuͽKLNg4*=!!! g4 Xb1c{bXb:X' Xb'fOtx(ʊWH`hF :X' T}nir:X' 赸ge!{kjεfM.P2Va|ji4MXOab< XOab< LL4?*qx@ 1K}K”g!62s~Q ؉9Wrv>62s~Q ؉9Wrv>MmvϨ@!(B!fI 4,:"0C&1.ƨX &C193&AgM &_rƂԵ>&AgM &_rƂԵ>!\x\ӜLQ.:X' ޢ >`$9$9]>f߆orr4:@׷.S ֚ :c4:@׷.S ֚ :c՛3ff1|7 ;esS  ijfnPn&eSL) ijfnPn&eSL)ƨX(j[w$0#|nnZWW7 bbc3DTdbE111 G`KtKKtK G` G` 8l______12 ~ ˥zzz###667p$/<h;κzzzie?Jd}LV_wS2 ::: g4$C"%rƹ #Y\`zqh Ԙ 28>|{?8/w~l cPjPjkxJJJY_g!+4mhf2>>951pP0?O+9G".:  456eS@ }!+5/?O%0=)2)6DCDErqrIGEMbwhOhx2BR2BR^sqpqj\NOf} ʿkI"w@Wp(1(1BWm'1;ʨTTTNd{cjZy XqXqȹUUUK`uzT.3CS }pXXX555 lM̙8GW8GWeA } ZuVq>;iihmm 'hss`mmyŐᲙɻooo˻ &sssɏGssqmpppp ,,,_}"j`#⌍ponwYvߌf@DZpRn4EWz 777ffe||z..bbb6HZ}\μn #+Ȼ^^^Rf ;OcTh|::bbbNMrrqqqtGMg,8EtF!)Pg}Pg}oMpqqP tGw"-8Qh-:Gj9Zx=Qeo˸ 0##VPX....._78I\"-8$.8111#NhQisK#kZqfF'!!!!%%QINQBݯpV`[1Xb:X' Ӫ=Wm\=maE,g OLog0 - - 9dMӾoHV*|T6(+- /N뿜_ -@~g֔囉 r"!.>Ǟ7`UG 8etǓ5dʑ>Qb۝S Dgl<UG  bXb[alA:X' AX' Y`T͒y?#9,d}/ƨX )#7,O~f ;K}*8  WU d~ߨX1P/߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98!3sU3s G` % : I3 : I3;q:dbIg0|pnYDo;YuhaJ0zXb:X' WDo;YuhaJ $`{4q˳_P/LW݄tB)w_hb./ o -*  o -*  2+VAV)B 蝤AH+ģ)=V6 Ol}䨖Cģ)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n|G i-V{w"az S_i: KxKǒ AkpB i Y  ?, Y  ?,;LwQ}w- ,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B Xb:X' Xb:X'  b: b:/U==L.  A{?಄ot* At6  @Pzc]N]"A{?಄ot* At6 !4zÒ@9-ta=*Ɗ\ 2mBKC$(ٵƠ !]UT4 88 G` "uu G` P`P 5e P`P G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ#?0Nr98!ʺ6FU;3BPϾ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW݄uB)w`hhhhi6FUPU[k3BP7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4?".;#.zo}kA.15vO( 341,LؾjC +~itaw  `g`KxKɓ AlpB Q1c?Pb_1"+5%zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C &F6'G4Hd}B OOO_15CRj DYpNOP^w F]t,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒ@9-tb=*wwwwwwffd y9K^w8I\  5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?ygjmxL ݘlK  [XUA3\wEXkhhhTTT !!&0>>_1EVf[y#/::: ~$/<=::p n@@@yyyyyyNNBqqu555...ht s888Y T??  Sj |``````nh g100LL*˿|e;888lA nH r ..8 NN7ּ윜^0VmLcyɤ___++!(/yrN555(((-==h--ccbݧ3 ddddddT8 p!4F ϵsh]###??7EOW\~x""" /,,v??JJJ||jQQQa  &&&oooRRRRRRFFFFFF>DJ~y&!򐎎ö #]`cypgڑɿ 5:?|60,UNHʿ6FUgxHѓABvy|{zh c~KeKeeyEEE[en (2neX+5`dg:, '/ 877DOY¶tEXkEXkGHsrr479ԂWt )('}mU$,&.;3334.(_z;M];M]}YG6q1?M!333nUo&2?3DT *4$.(2566 ddd30+oO/?N-:I".:  89:YG5q(31BQ$0; )4(5C789{{{q]Tkd(5BnVt %1>%1>Jb|#绻<<<DDALbwnLe~v2BRXmvuv`SGKavɅcAwœNd(1(1DYp $,5ѱJJJFZnȄ`;Iay zzY˽EOdzŶz[gWt ZsZsóRRRMcxuL&*8F  iPPP((( eȸf^#$yxx pRę=M_=M_`> y ]zWr./zyyȷǴ !*5kkk˾㱙ǹuuuózͽ !)gggYw̿qMUqG_wG_wqno\zu#h_~ 呑kkjmTpc<>RgWu2CTo 111;M`vTo OjhbseRRR8J]bȴn #+eedAVlʽlF6GZ >RgWk~x4ZZZqA0@Qa~a~e>hhhrEIaz1?MxuHWoWohClmmn@g1BRuжsEs%1>Wo.9Gk: OjG^vuî\21AR1BR0JdA³..._65HZ%1>)6A:JX666Y/'3?G^v=Rhó111mj{S='pQiuM'c\tkL-r% %#%$.#*ȻvS$XCG;̙5G8Xb:X' Ӫ=Wm\ąl1F9@c+&cyph$  - - 9dMӾoHV*|T6(==뿡 >c-@~g֔囉l CL3鰳|kKeǞ7`Xb:X' Xb:X' ƵlU(:}.۝S Dgl<Ɗ\ 2mBKC$(ٵƠ !]UT4 AX' Ɗ\ 2mBKC$(ٵƠ !]UT4 AX' [`|-0O* ƨX )#7,O~fjmgx 9oV9oވ~LR3߲-!=a>WU ]mbbH⧊%DwJXHd~ߨX1O_npedUtAZ% ߲-!=a>WU 羍0$AiBSH^nedUtAZ$优ĸ$@2Nq(#jmgx 9oV9oވ~LR3߲-!=a>WU Xb:X' Xb:X' ]mbbH⧊%DwJXHd~ߨX1P/羍0$AiBSH^nedUtAZ%伖Ÿ$@/Mq86 E^ G`Ͼ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' $`{4qYDo;YuhaJa2m ؇:UiaI $`{4q˳aP/MX݄tB$iivϾ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' ^2m ؇:UiaI $`{4q˳_P/LW݄tB(v`iģ)=V6 Ol}䨖C7@I%2(>kYģ)=V6 Ol}䨖Cȹ'GhO &dy{䩛C(>kY/8W=՚óa='4?#0=#-{r|ģ)=V6 Ol}䨖C7@I%2ȹ'GhO &dy{䩛C(>kY/9X>ՙ´a=&4?#0=#-{n| 341,L   `g` JyLǒ :v|T  341,L  `g` KxKǒ AlpC %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j,;gKΆ+m:x 9uQgP̉_2D" %F4%F2Hd}T %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j'뷎,;gKΆ+m:x 9uQgP̉_1D" %F4%F2Hd}C Xb:X' Xb:X' ,z,̡ňJ !0Q4R}q A{?಄ot* At6  @Pzc]N]P A{?಄ot* At6  8xw{1Q=|.'!4x!Ŕ@9/uR(,z,̡ňJ !0Q4R}q A{?಄ot* At6 -D}})8aC[5Q  @Pzc]N]"8xw{1Q=|.'!4zÒ@9-t`;( Ɗ\ 2mBKC$(ٵƠ !]UT4  5iK5i P`P G` G` 5e" P`P G` G` A~WA~ G` >xT>x 5iK5i P`P"*`*`"J G` G` 5e A~WA~ G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ#?0Nr98! 1?M˻5ETõ0=KϾ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW܄uB)w`h FOWl1?Mdddj5ETHNSl0K7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4?".;#.zo}$(-}W2mC&),{V0 341,LؾjC +~itaw  `g`KxKȓ AlpB gjm`3%^0c?Pbtvx_2 *3%zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C &F6'G4Id}B 679o F]t\\\\\\_17GVj ­@UjFGIb~ AVk,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒ@9-tb=*rȢ y9L_||||||ffb u5GX ᷚo3DU 5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?y888ꉉwJ _bezM  䊊wJ  wwwZZZ##:K\d^[XE3`{BTgvvvYYY&&/JLS   [Z[      yq FFB %#   KKT  =97650     HF9 !'%%;5= ^ IDATILP    F>4  PNL      61/'%* 735%(,JLR    DDE  94<         &   ILT   951KA> ')+     #%!žILS     ",(%JIF        '"$ ++)    "!# ;><          ȑ j IDATFKR       1000-3053    HC?.37 @|       (%+ STT/.-%(: (         5/0?B?  INU   &!! ###  EBA     &%#DC;!.!(/           =:B         CIR        UPQ           SYkR IDAT      ^[Z +-+             IKR     %#?<=#5  +&/"        333JJT      (*"DGHꫥ            &($'))JLR            PNM!        #   ?ADJKS          HCC  ,.5     !%%"$%  xzHLS o~ IDAT      *,- >=CLMX     ¾         IKB  JLO        @AC9:@ H?N IDAT    븿    =9@#%                # $%-ұ         5+1 HIQ          367             =DB  !%#         ##"    XQ-/3     *.+ !              絵 #/     뭱TUWJKT     *'% |YT IDAT    :86KMQ                 ו  WST8;8@|IKS             捎  #% "$(&-JLR        Ľ      02!NLOKNR            483 IJS              #"- IDAT   +#$KLT󼸺      *#&           #()#  Ǜ   HLO񩫤 %% #              @H^䓕,')  LLS442,,+;:=         搔         JM`!$  ﰷ  .-(     $  Թ    !   ט      $%5-195:CŻ ĵ;=@.    tvw   8/ LNRǿ    (#-  γ  !  (PPc!'741C#%3    l IDAT  **' 짧  343-58JKT        " ! *,6?@O&&4       ݪ467X[[      SVc(    99>     &&$%'(/  KMT   ˞    QRg#       73. ,."#%INQ         W]n 뢝   ,(!  (%#).-7!""IKS         ٘    "!*OUh$&%  ᛡ       n< IDAT*-%87<&&+INS췶      "-+23>N         :41 \_`LLS         隞 )&#!(-2?       庽       !!1-(!564"KMS             &'%)(+()5!     ޽      ==1+$!>BJKMS          4*+#))    􍋆     % IDC ()) LNT  㨯     Ϝ     %''$*3 $''           B@>LIC25;$~ IDAT ½           !" #!3-1 ҹ  '%, 60< QCF    5-5B      LLU          ⩦   !*,+9& ʾ 2,* v YVTVUT%@|KKR          Ǿ  觩    "+(.4        RSRDKF$%+ﰯ          UPW"", 񥩣  /  5AAĻ             %  * =;7#691"1LOU  ؿ        !*'- 򜙛  !!+,6 ,            &#!!#GCA           YXS012LNT                    INZ /04                  48;*((        LOT                    LUe ),2                    ')+ ( KLC         ==>+.0'%'MOU                             TXk ,38                     "%) JIJ          LPOPPW                   QXj IDAT %%0                         # (%!        ?=@ LOT                        +3:8     MME57;                   SKY Ϩ IDAT (%n                .   д\UV  ,+.    Э                       II]                  "*    ! "&*$  *,!   !                          9>F$                             w,t          %&&QSX                        ,&-949J(-;                         NMU KGJ     KNV                  )!$+%Կ                1*'           ),.02-     %*                      (2 "         IDAT             #%+   챰olh   -      (          #*E         &!=(          ''% "      _RZ'    /,+NPV                 %*2          #>FW7=I(                    %%$Z[f ><>   " .06                   ()"   5EM$*1          #     JOUVUQ     QOP¼/44                <=>    -+2"                  ʴ+ IDAT      119  ЪA<8        !""  OQW         SVV715    ),/>     81.        AFQ! /'*      #!%y PRX                 '%$  HE@  IKX         >?8        \]c cba   UXd MPV   FV^       !%&!%'"  1/9".8    C?1   "     ]\m þ  MNI SVe!PTZ    !&, +4>I      $?E]    RME      ;;C;AD ;34 -,4PQW       !)+ *)-;$.        =CX    cdi   +*!    '&1]dl  T IDATfca <@E                 52G"&+"   %,<       %)/cem (0D     nmj       MQV þ  ""fcd  "'  %(5-5A%, '<=EX)4>9AM9BL)04       XYY*.7      ?<5    cgt8;C!)ACA !! RRY        &&@?I $(#$36-4;(,7      !QQR)*0       RPF   &.OT_EHO  :8;.((  @|!23  !       2W )̸        GCJ      ~{}"  !+ NQW      "!  %%       BDJ+.2 )+8)       x#+ "  WVU ,!'JC?" + IDAT        5<<(**              *+"!(    ;=                 "           9DO4G          ɣKIC  ""PUZ   !      967! '         1/0EMR %(1 S[g 2,,,-+  !   STZݥk IDAT       $ & -        ',2$)3&,6"(3;:4  "%#)'$"!ICG                          np|             MGK ХCDG GIDSSZ       #,      WZePUYUQS@@;%*$! ( $       ;EI       '07%       wuu lmk -//            /-<      (3'/;      skmGEG䲶yy}  TV\     2[ IDAT    !) &0       _]]    /01  .'/-0:89%& 02/             8<@ %-        ꜞ!%)     wmc  vwnNQJ44/"              -2@        #          ==6 " RSY         & #,         ' 648   "$½he[                     %*5      CDD     NLG$!UUV                 IDAT      $ 49>       '%&              ƻ/26        |um                                       F=9=4D         !   þ                           $-           $ @|              @89rpi~}por[UQH            $       77)  #.*           ߎa\^x    &; IDAT    .69        Ѭ                     ܭ]dhFRX                                     JKE/4=#<;D        0-67     ! (! HDF Ľ                        %'#<92?>@»+3@                                        fldyxj60:                $                         ٕHKPklt !33  ^ IDAT                 !#               .0/^]UdTSʹalo û                   /*%!   /./&       96*nF^223?IO*)       !$+:=  #    $- '&$ ӆ!'/7              311TR] HFR  "           ;;A           ! (7UV_         *,1)),+27  '#ſ        @BF        !1'&&%$ UV]             69A$*'$        G_ IDAT  16@      58723, YUTVX]½                  "$1        6:7@DG         '(*E?A+.3RU[                +"  !'/         53-JKT          +)1   VW]         ,+!1.&40-@?? +7        +&! #&      4:2@?=4*-              vzxμ                         "                     )0      SJE   !       $                                          *, .-+             Ƚ                              NKL  ,| IDAT                      0.)                                                   .&#           &&#      !                            +&(      ̺       %.<                          #!        >EF(09  s IDAT                  ŷ                           &$               %           $          )(,    '*4                            ﶸ                            .0-    t IDAT    =<4$ FHL#$$              &          % *񩤛                                       ʽ                       *      %"  ʽ        62- (-.            0)- ǿ                32(rlc @|              `vy IDAT                   #/                      /'@<9          ;)9                                  *3'                   ')#  &                        !'<,                             *         M@)m IDAT         ſ                          "%# %!      #    %                     9?F )                    >@8,#" ",+                               !&.                              ("%     #$0                 p IDAT    6+6  $                  ,2. !  #(                  *0'                                       񣮩JKH422                 '%     '                    &//             ʬȹמüƹǽ                               .$ beR12!  "$   18/             ç    /-#        %!&       $       xh_*'%qaY   47;\[a    #            *+&      &#!,02128; IDAT          e^Y65.QTS AAE*26       +)'                             $    @>JAAJV[^    /42    %,3    $        (        <85"(&*/7       ~zv       <=F                -%" DGQ6=K           -$2O ,G       h_^myof[v}        *+            (             !!#   (</   !    혡!x{wuzhfo                   򸸰            ##  $    Xwp IDAT%     ¿)' 430@|                񻳲           $5            zz  " #                       "%    $0                #$܄mjm   $() '                          $          ad_@G6!$VUFgRMߍIHJ      MPP                           #            "%  $           娰GQGsqq         JHX                  !Ƚ  ¿            '#    $,        ꫷#!# WS IDAT    "  HFU                    "!(   #!)+93&9=.<8*J8*(#       24>  '1         𑗞"%戉           5AC                     !%  ¹            63,ZF>-"'    $(9           `ep>4Ektm          &.#                     Ǻ    44225-      #+       &,LMJ      '-5  %+2              $    ཿ .(+緵     .)    547  &           0/2       =AQ %,               '),   ο  )()ǹ           !) $          410  187  ?B IDAT3GU                 $&2)%/                " !                  39N "                  ( 20%ؽ@:6!'      ǽ   @>D   ,&#"     嵸     D>A ½  #                              '+/         $% ɿ                        878   07D                   8;E                 #      $   .0/  AO`           )/      % !         ?;)43   .+/                   +--    Ǿ           0;W IDAT               Ͽ     ;:-IB8.."B@4@5/=60++           399     !! $$(*             !#     ("                2-IA62.!  66'                                   Ƽ    &               Ǿ              DB?        9A?               ,         +0        ɾ   !%%/,  $(              ?>; .         $"'.?@     !-  "      %  #%                  .   "    ˾ )02          *   1 IDAT %        02'@E5           -),*      (        @|  !                  "          /#%'!% % +(PMC              "0&")$            &!"*           "   >C !% 14:ɿ   -&                 (!  "    '((            !&* +     * .++ 2<1 &  =DI                                !)%             Y]Z         bs=@V    1L IDAT         G65#        ! " !             XZ`  $*      9HS\fESk-                     BD:>?@;86 "1,.FF@    **-                      EFR       (       '+49?A452   %"              $R\a *4>'0@               ۯ             &2L             !    $'&##  *$(            ,.6  !#' ((#!%*"$ $%# .) 1/8UX^$7EN #)' &*'"!#!  )(% :BC   *)& $""%)$%)-;   /9O&39                   "#'      !!&                $$            9;G+/ %%"  # !$!"  !$#       !!(      +6;J$#&   ǽ                              ".!,/       *'#  50* ^`h     ɽ%+3 0:= *<)5=         ļ                "!/                      >DN" $  $!"($ $%        ejs!      /7=ʿ   $=G^GLK  Ż !               =ER  (3A  #%+  #         JYf (+&     %$200?EI   !(2#8:B        PPMuz                467" '#.     /      񿿸        &"     OS]  "min@|     ))1                  0(6#$.˹            ȳ         )$2/* %" chr  "]ZX       ++,                   2+.$!/             ƺ                -6HQYsKSc          &.                                        )$1V7B]0>I            +*3                    ƻ    ҿ[D IDAT           ¸ILR    $+  7^~ +-      )08        #                                              =GR   %        !%+               &&()+-                 𺹴             &)+    !" "    $$)             %                        &'    %%                    ˴         &.                        "&  *,2                         %.           .Ⱦ    XH IDAT     *,1    $               1%*/%                          &'                                             !              N.     I$  Ѵ        =&(%    )7?Ǽ         *  <3       $' 26     "                  =+ %  )/&    '*3                         B&     "  *!        ""*        .!O7     ! $*)       /5 $    6 +-                   ! K.%&1).6ǻ   $"        #%      " P8#      ,*')12    -$     )'=!             '        M,  $)>     1D.L[ IDAT             2"[A    J$#C"      "8#'     <4(":        w>'0 *0(¸5;9  L2)      &% %      eI!         B.3#(    #"  9#"$  F52        f     {  h  0 56;  $T6        #   &y kI"     1&  !    &F" 8@2         z  s  '.9Hȼ    kD       wU)    /O&   %   %   2O)            o 3       gB              Y=      W2   *(  !l;                   _A    .+)   j@       ž ̣> IDATA-     iE %   늯  lB                a6      V4      H8  f=     ?!    A*                 G   "          R9  7 @|     #        S5        ?,            $          P82       kA       | +$    I=      <"#!  !N7 :2    $7*  $##P%   H0            *K9 $ FG     F %!  ,1,  )   ,#*T'     ! $$ 4!N+g; @1+ &! I9     8!    [1   NI!    B&  FE  +I&\/  B+  #81%0     mB    X2  !=9     # JH   #S0 i<#   .     l7&  ۲!!bG' 8- IK  H+ IDAT Q-!  8"NPV#$   uA      R?   0   96  i@9   cR  )   ':&4E%'3    /  {    5     I  YJ    6      tGC       WF  7$     :  f8,  '2 $*'%    6&>9&  k<0fO '  #   Y2   *(W?0 ,  )(,%  (]0   zV7 V:    (        H  yP/ (IJ  E.D%   wV8 1    !} I-O  DC      %&  (Y,    %+%}TAC&PMV      ' $!$ J9 g3    QG"  7"o?/       D?#   G- *9M )8&3"3"/&      .     0    M    TD  8"   ?=  P2b8& ! >7"   2      ?    M *0A "    D.   WK$ 3b/  +(* G>"  ?(    ]4   53"pK.   ))), 5R0   2/  9BV          K/    oO7   #   J.J)      P%     8"   {= "#+ !  $'(6>   2" 0D  .** 00#       )*#$% J<    &&%J5 zFd:  #'      '          I+  +*#yW     "%' bF )TV2 %#*   !  ;-         x>)(.  %&'(&$I. f4B  *  g IDAT    " %(.?.,[7H/      8/          O3   $!/     !"fF4!  #    BE     HŽ>?Jú˾;:N      ";).E&9   !%  /8         (+.)K;          8"   (% TOװ      ,S4(*        ,     [5 $    3( #b5         ('%             9"  %!F4)    +0-     (*LƬ   1 ?>R"                                    ?) J.       $)/  4()0C   Z.  5=7                        F03       .!   "7&0    60      j; 7@M $        #          IDAT   W7     .     T9   !      b7   0<2        !  !          _8E       &   2&  &)+     0%   #(8% ! 320{RKTĽ   !       P-C#          5>%  ' Ƹ/4F     T0   *&     * -1# @:: E&        B! i  "j;     ")              mB;AOە%    0?3=ߣkfc  ".)       ! ='U&         )     >/+ $,޹'%    !      #$*"   8 ķRL@A:$$)WYH   *+,&        =\ IDAT  j>V'  .&#               #):          ;#   Ͼ38?    98F AD;"#   -C4    P           ߳               13)06$'7    ,201 AB) #<"        U                  "!(           //6ʿ#     wvp431 @|  3?6        ##Y             3&               "    & #5.26&,    &"    %" 0"2   '+.         L         )(      $ !      -/:#&1     infED;      64    7!,              l?        IDAT        !    *1$ !       <  S=9 ;"*          I+$                      '       $(2+1>&       u  M;*    $8!.       )Q1                ߱  %'8 )          FB    %/I     ~Q                        #MS]о@"        NE.   +[;                         (     U@+   (A62              <F IDAT      }     CKS'.D      NC0   *=+                           ;;&:"    6!/+ 替                      120       % ,+mN+    H(#x   Y        ^    -w    +(5)        Z%* e?.  $F"  o  9!$UR=              <# ;A2          "*  w ;'*XT<   ))IV)  L+ #    U3         'J,  IDAT! '#    //3   Q3$  [3&     %*-"픸  mC              w !c<   008     !      oC #%!    mC$   ,)  퐷 '\/             |N,?"          !(! 0 )Z+--b/(( ,.4  %$sK$   ($  &T+         6 X0              +'5   $R*   >:=--/    &#wQ      &)  e6      wL          #    i=   *&,       "$yU"  R)!    o8    'rC     xo IDAT    ü&  C ?/-+    ##U(    9|  !h3            /sA         # }   o8  1.2)&/     %'SX'   %  #_-        5i?             p3  <42    ޮ8}W  !   k9            !lB                  x<    !(% @| O-%%       g:      y   X&     *   n>   45.561     hG    5 Ǽ    V2             %  U            A}1- IDAT  X2    561   *(( }X    '        !    (         0           xS/  -  S3                          kB                     _>   539       lL6 #              45!н !   &                %   ,((.13         "(  뻼̄g?u     >'   "Ǿ       "       #  && ɸ31&  ;'         %#+#   4!                         C)     //+ rA IDAT eX*w      ľ.                     ! "$            (2&  &,                   %   񲯡                       !#) "     3)    53       À      :82   ,(&       / !!%  !   !    抎qu        ga]55-    zU IDAT!      -1 #03"       88, Ɏ@A:?;6   8--'  ;:.                 "!       7+  &%   99%!      μ))$DB=    '(IB> "%                        S?2  5$'   (.)     ><*  #  ڣ+(#::6   G+,(8<         0 ( 5           +/ F:(   25*} 2R4p    &>@# # $!596    /.,      "",7:9.($   "-         }        *32+   >=)     k@  /)   *)!AD1  !$& 鬯        ( 1700!            u @!z IDAT    aG@94*    ??) 8-$ .2(1x    -0.$㹼  /+*60z      958.!  #* '    # y      >=9-$ !     )%>A0    08) %!E?(1  "+8+) Ŀ  75#1       570## ?     S/$  !        mU;  *BDE +)" A  -@<   ($!!  ,"   )??/.-'#!   340#&  # #   5"   >) $$e<+  ;'   %(    '7.!    &&-/')&  *   $# "4#  '&01&)P 3 %%   " "%   '  " $;,*% 10)]80 C) @|    /M,"  z  O.    P?W5     wmC  O6       mP= 5'3+  9 CG   :CB    # S2"   7CF ED  ?CM!    $# $pA    )FC    3?$6&   L.9*   %b9!  k?/-$   #3#  ցU IDAT      f6   $$N*   t=޷AE4  -&-)7)&NNU   ! f8ٻ*,"  %#7;$ $     %"+.*  A  IG   & tG3(   (      gXB 8!)"  oO? !  x?ſ !  " QU&  "%&wB6'   %'      ~FZD$  ~IFH$         \E3 ' +#   i:?-4        VC,    h5ǼDC#        uH B C $      I8 c4 RP [)43    N!  d1+   W6  ]B4 o< ]M~   MJ   _2  uX;3 CU?7   VH; \' RRӧ    <D0Q/0yXF,n2   jO       G,"2] IDATS-+" V< R/3 Ȼ W? zXA%WùkM >FP  ڈa k?3 πcL2   G/  G- I,   W@  E <*     ʂcq:캯G4IMS"(3#NAV kW'7#j7 #   ('   @2P1  ( LAL+F7-      &&    $$$   (jW&(a%%#URV&(.   A/P>kAX)WC N  D:      [I#p? uI9 \H*i4/!/*   %$   )UB {@C9 "$%MQW+-4#)  A- K<X:l:  /"O?/!l;.VC          J6 .)l6 14&  5a7/ :+C8B+X-RA      ")M?(b5XE      " W4!    ,+   / >$  ((  7& J!$  ..   L4,&":D=^; //"   -db IDAT<)33/"   /  $)  &)!    1/"   +!8 .." 5% 1  "#(,16    *"#      !!     '#)$d)     '$  ,51G.  &$     #!#"  * )     $"!"     )&*"E >CH                                 "!&                        )'#6;;                         '                   ))" ('(                         IDAT      "%" QRW                    RQX           QRV        PQW        @|SRU       8t IDATRRX                 ƺ                           OQV            RRX           RQY          ӚJ IDATRPW    TQV       RQY      PQU   QSW           PSX Ȼܓ IDAT      SOU  ظ           QRT         ST\ м     46<        ^ IDAT         &$%            !&          &%'           !             @" $     b&jIDAT   t\` IENDB`sardana-1.2.0/doc/source/_static/sardana_pool_server.png0000644000234100017500000652757712174204305025014 0ustar cpascualcpascual00000000000000PNG  IHDRCmt pHYs !Y1IDATxRp¬ci{ dt*X#kwAZv "$zv{FI* ] ׄύ1RSlFv!]VWiZDá5GZ2/$K"EYG!ɓ0%+lF ã~~~|kҗ!.o)R<8vnc D JJJ{2'=? ʏU^^hd 5?6hhhNo}} 86ug#w$ LOFdd}}ȒEGGD!!FFFCN\5\UrrV[]SQO$+0ojyDDovvJUuuoʿN\hDDq vm2?F2?y#xY= innˢ$^" ,"rPP ' 9$Y+ Z- \E  L!҇IA^? RD!! ,13 7+#yy ``cBPwy>+6)&%,.07+# ū”iz!-3&'&))4;U4;UL8 $TsTlLhhhCwwwM[x2$ ! ! f3!f3f3f3N6[IsNU480NUX3t #}' 480b1*Wj _xPƁNrz]4RX' P= & g/X(jkR󵆣4f3`KYMX/g4f3&&& &'',9Fn:M`Ƴc5zLnj9`+8FȺ]4}R&zp\.i6h5f 3C">d  -.PkNvG ^*[UGGG*NU2?% ܐ'N`Nx 'dB, [%XRGab{``TP!\^V7ԙ;S~BP" a4T\.i  i΀iae3 e3\.+ Π3` '5\.\..`\.5\.;pP|W1kAc6 c6 uM&}Oh*=PntU{YϪV+hBzO" cR\.(\..H$!qRuO(\.\.\.\.' Ʋ.*_+i3 jLD5)-&A;!!n!t=r!?N־*BP%0>?A;-w;(!?L4BP>@9lҕ&=/H,4%m ޢI3:cÈ o3Oc>#z,{>sTOD}"г>. //43~~~715 2A1OO~~~72'19lOqqQQ ƿ29@ 87T\HOO} # "OT(2:&&ss㥔VguOOYHH} 777pR"\mz٢.EYFFFjN6O7fS:] x؈j(fS:tL 7&wAA!00>/T?;* }ꂞ{Re~ _ W BYwA   # ^ ⢆ ږz39? $%% !~ cdmCM`3{&39?=CI)8W' >DJDJlL)1SYcccfffH5=<0)1Q>0WtCYpf3pf3f3OgWhޣDlm:' ߻+Vg3CTNO:NN ׶Ho=d:OVN!EN:N vTCg4f3! rrrE$$Ź2BR]+\.\.2BR *5c1   *5\.GK.=/Q(5 M IJ\U=X(GG Դ= D GWh:'nC ňY45h/2,q@ GNRi["S&X[M x`*^K ' GG/2,q::\.;b~Z؜ wqpiki󽼹(I4'8$  GDARmU.> p m-%E鶫_`]|#dG 5 D{|? a9`%*.,(-*&.*{뎡/5 TW=*ug=SiV0!c`dt (}[pE8}V̂Şo f r_C^=GXt`B ^07>N ; ?qCkٻ1.uo]o]']pE}V )44D51āIBJMM w MT~~} } 1;CD5s##$$ H7:DL %0Ӛ4?~ D!R_j +KKrrr׻قB,6> ^Dְxϴ ذP(PgLXX.\kb 3,$ܐP(PȐp8pc}!4܍$$gܙ&$dI(CbZu7uF]\i~qnp8p>>Ŝd( Fgjw}c? g Zcf'"!hC(/2Z-x*/Y7hܜ5uqL)[ 9RwsJ 67Z֛ؑ9My'Lڌ"R4 ??!!rR"[s[SS sR!Vs $ 3$ DQ\h\Xxxcr! @pui}]meLd'+' +/2~  II@4AK%/ɊH IL8 񝖄}]O,AKU  `u'Eb/ )C-! L7W<wY{*A9DMih zt'..D|||򈈈/#   5<#++++++///<<< L95<cgA^G  f3f3N`NUNULbLr}i2N}' ' hL^Lr}iNANj=Ls2Հ"hȸf1`'7Nv݊V]d G 2B8 ILLoJt`j"sh1o`' 7'  GDD?' Ķfg4gg4f3Rdp|@b쾐ppp%GjuL$DP]`_1R==@b^1 =p'555BjOasܤ\.FTbEfW}xWolvX|Oi5CCC [1}F\s UyqAf 8HXf4C|;p   Gg4gHG  .Z{E"f\'NFGUUf3G f//  BS' NcNUOK' ~; G`I BS' cYiW=Q1NPd[YWgh}OK' %I˘}ۢN`NUBh(Q1夿#"^uN"sW?}xcc7ijNUs}"udi`NU`NU$:N!m+' x{\AAuc5\;;;\. /` kd>\AAA\.\ _1\+ sFb1kuuw ҉hGb\.\\. !Y|+6CyT'/c9579Y[\\\vL#)4@˿õz["Of|Ul?u/=J\.\.&!a2 ^14FZ4FZa1 LgOe|\y*&8Jϻ:JZ\.  F#xP'zMg@s^0F`|"1C1EZOf|/#|'  G,% a *ZZ׀ )N0u:Nn EP8w7P8w7N!VT/)^Xo(ZPxO`NU~ʑY!=x[jg|ЁS.ҕ^#" BK%2 AXOu.jt>U.~?NX'n7DX:UqnayفN}僗4߉<.ok.=K)szb[&0`% :Ϟw@&77"7 %~^UNU=BNU`NU`NU9FۺtqB`2\ok' Geq0>x~>xҤv `` PnP' T⿜#dNNN]Ul}>@A{( @( ( ( }a%Fuq `2\ f8  =.d pM*RhRj ư~hPȁ7~+ {N!\ j<\ l>.*.P\.\\.\\.\ 'g9 LavXq~Q#q3BP̞bbb6HZsB.26vXq&yݛզu(/7|3BP#/b#MMMoG6HZh6{&/*7DŸlC&f5+Z"vYdh7 M yXdq\.uRhޤwO'dsEsH˻dϿ]kN GR^Np@' XUNp@' U?y@ GN`NUM( N4NU܄ )|U?yF ANl GN`N4NU܄$|  6'`' M(  $|/01 6'l`' $|"&*RZN@% W?W?V0 X)~\.j+5 Z% $ $ $ $0  ko  t\& ʜnı3 ɛd\uM&\3333.evFܚ mW" kޒ4hd("Qa      g  Hr}4F%N2,$  !"      pusp~!#*siҙ>J+/.X?kK"V    T B$-99 _,=N|&@agztv{0F~F     3% XKMG <@tKD.ߴ?Tl񷰤bdk ט 2s    dA n<oorRL<Ea`>a)#*)_hmxN4lbdk, UYQɒ *RW\Lroh%u!:$ v M}`in-nd_'dD  XXXTJ`Df ǯ$ 'Ӟ.;n3{0#A;1oh+ 4Dt( 2wdM=\J@%NNJ]TQYh[P)dzYgK W$w|wG0 .3ɼG  t])C4>=5 氕wS M#|E$ ÷g< 04 HT~GsdZ&鵊D)KP ѶPcp(>>iƄ2,` ZX h ԋ @??>͓ )f!DjXT\fK-85 J% );X% _H-?N [Z@@~N'. b}qqδn1LgZ[}sOIOQg}2x\6)< LZ_=U'o9.02x}52LcsOTTUU==P,9%) :DV5+L/j@q@e @F"""fH ; ?KYd" ?5(KLFptm N !www"""4*OiIz r -:64+c+4elN)O[))"www{{ބ4QQtdX=83E, ++L&{{VO ƨ(2;+( _c{uYY6 &(2lll(/Čr[OSKF^S]_^ŻFPZ (2 /wxO%.9G,C  }}Zgs<<ԧ\/\ZZZZ:: ,B %)JW&00\/\CTD#DŊv;vxwE ZZ::*97x8 [4\ԯKETa33,( "Cv;v&&E((8!x8[޼%*ڢ/  \\᝝''((AAAFqV ) {Y fՂ:);*xW1 ao www666SSSVVV..._E 6)h3Iik<|nitkZ`EzM1&TU˕<20VVVfnWl~F/ w_.pƽ3Uj{p8aF9BbG=_gˬ}% 񍌗wyq\>=c7_ VPGPG.ĺ1 Zʛd/ŕPb11`bo3c ||""))AAu>9P? !(|soh?:AF ǿ0O_ Ÿ2?MݛʅXgh@@ %#U(&6<& !&*!&*Zj9 Xn #44}mO\h"'+!'bS7`QҼQt~~6BKԾSbnBHVtP!!fx'P{/Z1Z1 8jJ S( Sbn* } 2z`yhak(v"&coIF2  !?)+3N4Kp7€[a|)19%oH"&+0 """ 黻"""A G1 @*2:XegBBB0bE ᰩ PWTTT777...0 64! PWVVV<<<hh>='1w%js! &/ppppppu#64$&o<:5!3agl9f^f3f3' N} G GNQ2PKN-N`N`ojQ2PK NN}ـ+8t^V%NqB V`N*݃#}N^w{[r߅jـ+8tZZZ@s  =&ޟ$t[x߆!z!\\{]?+B84:x߆!zF|I=NjgN&eNzNĄ]gPd@Yw9YwWoybccbb$j@3G\3AOq <<<[tI^s\.Vnz<<#-7}\.b5 gAr'7I xTo OdzxQh̿&4Ar(1[usf(0Hc&4AI]syyy$/<`3%`3;Pbt#/<U UU8sPfU,mg ` t.n<U C pBrCakʽ-+F!\H[p f3yv# d/' > f ???N卙K`- G3-"R^L3NЁoߎԩWAQ`ۚ<%f8%)WA܄$|`..%fNV N`p:.oQ2~^aUy+_7r>9! GG& s[[$|O9:^XyQ(4<>9!SS[[,Ÿ.;HZ!:r]lm' Gy3|b.窐 mb§8q1 xNh($$x.;HNpC8׆z9AܙhF/8ؙhF/8؁N!VT/)Ti"wN`RR m,,q=' !hF==!c6GXB'>@'@'ZJi% +N!CGK?LXdK:\m{E fvb ,J9c5`2\ +7;;' GqnOO' G' GOOO k; i: 3&oF ggg ***& ܮ$Rj\. &+xR+RRR9DOoƉhFNNN049!.(u.:}\t_2ϡttqqUmOe|mEd@Seg< 4@LuvTlx`z˽ѲpzKav抉m((Oe|R@Se7LbƘj5u)4?4>I·y+Hd`z5CR5CRF[n&  k7Lb9hdcd~~T(pddd"Cdɉe>?Tiõrmʹ5GX X*\.~&Ž2;Ceeedddn{6Wyj ,7DSbBR`bYu.=K.=Kb5 e>t\.\.16= )6CwYkz;Nby\iͼ˹itvj9ȸkh6ƶi(a3DU3DUh7$. ((6U LJmN zX/T)G[  B : rm:}Z 9 ^6 /5 1k@k"`ہP%] /N`NUg D0nڣ)bdFÝ ".|4 GN-_f; LÍ7+nd4zbd&uoL`*XBZS hg!ONNP/"Nx^U4XG 8o <YNU`w>WUZ,\< _1%SBʱu:cNO&T+ GN`^U2`NU`c5 Gz@rx'5Q!n[tN|坶9`OGUDN7'(pGaMzth`"ye' 0'0ҙUk@іRіR d4$/Ni5InQKu\)&'䪛:GD .(zMۺ&|Ulñ=O`!#QK:PH7PH7T5 g!OۜRV' G˗}/n7D_ÁU3 C_ii`U(=t(ݫJrS.ҁNUT}c" GQlPU.vADfo4sax ~~~}` 5iĘa5/4+[ fABɱu;cNYe15$4u:tf5 yf5 yz@/#|5ii`A~' vL|L' 5 wW --\.!+5j\.5z~_ Q__~1'1AI$.!BK%2BK%2InQ3fj| i2F\ rD Y!=w[jh,XcXфv9 L6&W.C.y\%^0 p( GpG( GA~A~U   ˲e|hsK%n@\̞4bƘj\õ0=K \.Z-X-\.\bbb \r0=KkArJ" ʜn\:IXjש.W\wH[p\.<\Ʒ.Wp{)KmnO!u rI!)Km2@O\.Yr\.;K\ŵUXYqb6 Oh^1'1`3` q`35* >Mz>v|U=U]3d&/PHD8AX`s  *###uoh9u ^ \3z !|օV- "" >5* $"D"uGA$  3nw4nwc4k`ak," 9iw"%(   8EOˏDVj5K†B9 |i  z  )qY&_*)XD%f9ʴ{RA.ц_>'k1:41.4Xf ܙ(XY A0 j q E Zz->!*L%/ 'Fe1 aIpn,,)^i M* /*ZdY7 TPBnnn;e&l+jMP9 6Ot$vabS9#[z8 ΁ nv5nv5 ) GFAh/[I)t_6]tqnjTPC復)Riatp `D eH  k/^ Ob@tS dG 6y N٩7eOSQOlZc|C ]FAbP%ztY#7IKL-& .;& Rjl}v/ hhh \.m7 pYK) wV{Ҏײ/F@hȢovLʂI6m 7e1>J%$"c|CO.t3 1 w. "!ޣI ^d԰ű.;( '''E05 \7t ҿGzGana{ny\H \u{f. 69C2  PI - ƀFF{{22>>8AH}V-dWH,, Y *{G=5%NR_f]G$Tqlɗ~n 3Z^Ѕ"u VrW *a(ȫgrr A1%c~ n =@:*j$110 }S S )N|;qrKW`O4 B>; H[_a0-%!NR_~^=7:Q~ o1{f{f*9Vk:W66 @KTbadT<;  deY332ee`ee` vv 33<<((P֬z!;(/6dS[ع-M"'E1 fs811 02211-S poomxEEEdd6ffGG,,,[[ } "B    oo"+16z&P ^C\x GFUUUffN52lߔGGOOZZffM6'/#Fiwonz^8"$).Nqq12&&OOrriiMZNNFFӦQ*W $ރ""* 9BJMLI? lVT``` Wdd,qqaa  epNNFE|ZRZFFľ"S=sxt  =6/ 1kkkoo||  ekkpaa||SRBIII %W   S=7Bg!+ kk}}}IIIVVVmNV_:3 S- AF]wSZ5 c$ 0/   YYYó FFF@@@444555vvv%%%|ղ?eOL 5^=4 q W  ZZZBBBBBBiiiVVVװCXXX"'+"&|ty~>, +48Hø WN@f [\\"'+ L;E1?/  NE==HK$.8 qO1hEE2J >7%*.2 _XQN: 璔E1? Z*ztB,r&.刺rJI0' чDA&Z&{DfS.a f(ĺ *3Y:a@   @huZa t{ty0 ) ^_<tE+b xC $!]" {|&f567>8FO R<9ldI 5  [^h՚[)))ʹ(&#E71(F2Eū&0#핒t|ſO]h~[I8 "4M4M==29@29@`c;5  uu Uk=Z~  +6>7F! DK b JD>ov6;>Eϻ!&*  Q%%#f zr0V@!D>ULB&1<?[HUa%1<035FM 9+   '( ADV  CQhJKYd JV_ , "~tw%8xB `daq\s2)/ eIst/:B/ǿ4:B wn훟KKJ  ??? &`edB,+w.mD. ALVc-5=kkS]U0  !  aG!7+ ) nNAMXIIC ]S55"#(''')  lL䈈81"!& z{WWWWWW$$$$$$tttnnnb`E-"   ED (xx'''kQ nnnnnn____F8*  '%#,;;;L:L: CCC(' '3 ssssss  30#2lS$2  N1xbXXbV)ׂVDr ɂ.HmjFN9' N'fwׂVDr X' Nb#LOjc<LOjc<:8xx@mD]eU.ظxﷃ_d/N/Q%X?^C<l,S2^C<X' NxmD]eU.X(PjœN\œN\Jfp@BBǤ}Q.(ũLIV`^' LáNOim\<qYeSOim\<BBǤ}Q.|NiX' 5 5 ՗yrP3n9]a9]R~.nzvwS$>f>eO#X&qRP3  %[ӆ) [ӆ)]3P3n9]a9]R~.ntttt025" ^`   GG GG +iiLL00|W`??-z- GG GG?-z-`YLL!!!g4f3ϫF\\ deeyjj1ffffiERRRqdYc6 333<uuьSS]m|]wtN\ -9GXq$,s3(BVhRi˽j,+(p 00Wesc^1ZeYH8kkkI^s)4?zY(((q(+6C5CR5CR_1T.crRo g Wrڳ˹fppp2 />MOi=ɭyĞ!ųdzs袁_j]Qhhh |&ddѾXqqqqpppkw%9+6C ,7s˸BTgBWmo@:M`v.37fԭv˽ *5 *5rRo"-8V.Kn獻5EWuWlk; r#,muR]{ ̽GS^u&3?}V+}ɺlUBUdGU veUL% l hǸ,9HBu$/<G C0CG0Gdddp@g@@@J   ; ] +! GQQ < Y#h< YmIVPI c=:CvvvLLL $S d! m(/AN  ] =] =yc===f3O3  # *  c %4 5 W)D2 5 WDiaS$dNwN9'ɦhcccc XXS8('nn'Xb '9VSltƞS|{Yl 9ddNN:Z[|KفSTiu{w#3TG!]xv>x§\.sAAA՘AAO wݮ@@@ ]]]STU   A ]qA:R*1ڳ   wI܄{_1!***BBB  vG` GG[2` GG` GG// GG$|oA_10>>>++  `2 d8 +29 g9 (? ;3BP b4\   qCXvvv!#&n~.4<ɒt\ 3BPuG h: www17UF h#폏m^1\qqqqqq\5EWXquӿ k1?MtL$zthhhR,,ՖXPP|捶YrYr{M CVh OOO,03`1&|'1LF?"(/~X2Xw~SVVUuqH333IWc$Mcy^1 b4 ZPPvvv^0mlfG)...z`e Rh}o s:_8%,Q`fl?hÕgwwwvvvlC~T(=RfKd} DKQje|OiAWm )"%9;=1"ݓi JYg ?WptQ%-5Ndz7U"+3Rj5`j9,?dF]t (.=K.=K b6 `~g6OiOi6HZ7IZ_1Jb|wR,$,jqI!:JZ4=CzJ 9!iވETS3sP'PXbWoD/Ҽ$T[^Id~OK.ɵ߯p-_sI+XTZIqK.ɵtJ,Sh`r!MGG11s GG11s`oQ=v pUV1΁XN9' 3gρTu鞁^x ;oTVzXWtNL(s=Nd|/2!H"xT"ρTu鞁^xA;q;qNT'09'4q4q_uQNLŁV}ꠁ`~;4q4qY-P|F]h123%)-U9N @N=% N<$XN>$XN>xaV0 NiсTX|N9' X AR7inkKQ9|.⪐#a'뵊IqK8n:   $uNN`wK3(Տ3"cO.⪐#a =`A8q=969 ;D"ꞁw`  SUpv1ʦ[RW w/NO!N^eJ_ď`WozF+VgNEpX#iNEpX#i~3ftJ,Sh,y-{ m AUU` GG DD 8t8m`!uhp+q+{ m G`\GG AvA G`x-a-G4{bSS`!!!#-6   . 6[\G`BBxGG`GG`/`p3gdwǹg ^1^0b5﷒l ˼Wt0BUBUñ܄$, eG'*c_1,?R;N`nEpZx )<箐YG7'uL$iC8K^9L_ a4h7^0~U*k!$a9w}O"mInf8g4fj9i8Vw=QeE_y-:F1BR,>Oݰs+S!Xb '9VSlt#PtPNJ:Z[|Kˈ4L|1KU )Iy+#N9'XU )Iy+#4"^x5ڼL'L׀ >a|Lw#3TG!]a|Lw#3TG!]a|LۯG3fU{N Uύlq}[/hH2dR{[/hH2dR{P;e]E|kO'b v} |W1WoOe|y5CR!#%QK:'  9>'PH7'PH7\5a(k rg*!Oqrr!A| qRǸ,9HGʄ/Kczy᭙v /4+ʈ9&6[ʁP@dܗ# xuL*dTcNm$v\#/9h a{(25z5^~^E~E_ ~<~~E_E~E_~w~w_} oop78:5So   딂%/: lN1 j@h \8Z]_1('&('ڨ_I]qͺԺ666000\==>QQQ.&oKsssmno ooo.FaF!!!]]]]]].lwA%V-L ߑH#.3H(ǖ5D)r? mR .H|6T+xh<b6 |!#+y@JnI5*|  n~ uBN+ !ա7s - v ]jnM1\H6VĦh/+.cyj?6# $,0#dR'O n8>j"NE|Oj諾*#:111 { 4;%I SdZKziAyv!Μ$U6#)L [[W4t@ZL>_~rdS4)c!`D=u= ۮ,_cbv   `C`CxDR-mbom `DT@DV>I@68,Ӿ0kG Ūdmu  Q9Q9phnL7 cpLPsmGpOZBTصdkdK>;0ͼ)#apN-B ݛU͐rUj~  ECBq{y46Aó@Zf+00   `C`CH@ $zǃ?W%TSBo@hס #"t_p˶"6Ԍϧ^j~ssupu2O<+KD?8319?^[`f'*}   hgfQ n``Go'mycVcceLwq_ЙW?g`>rssuu2/& LQX7&A=;   :jElA ʓ *Me 0?DDC|ak^wq_9Ms`>XݽUC?>horC# ȿ +!ûV\` .?%)螞9itnoQ  fxBV7hPl"J!x 7"7NDDC\> #c7VaLH 8AM?H7?dH$ 24<蔣=L  ki YNzD'~چA6((' )ֳUnΊyg7   \` 7r޿>Lp-$܁ZFGiXF5#)=۔"SJZ;3=g$MJB/nO7(=x uo%NE^! WgrSwcㄮ[j[VېS)5"AM8nu#.26ꭝK&δS(K nz`.9{xxó@?0 ruqx.^X, O8 pP' ~6 %g㦇!h;L>6 Q0 V :1G 260S}S,#х/;`%'9Ksvr ʰ7aj aG H$5 EaF ]B  a v#=K`F lv |zLXc"() B7%Xb/՞~0!ٞS+HXIg ++*,#0}l(.84/?Q^MvoO^Ӌ  Y2En SﺄL{ ee""P!(&ڽ"9Vɲ CE C=)6'b"?:#T@K/0[`oooX0 |vs8| \? [@  `M %* %0"- :kB'rSS }}}}} !C$c@922м,AK:=ui!##D8sVuBck+  °cH}c@ Dj7GS 3̉.fX ek %ZZu$19!ﶙ![N٥lf)GK:܄ <@ϊi1vM_"8($*X ,5, >PV>78%xtRE# J'K)16գ_be[/ Ro|'U_E_   D5D5O,'m,3$|1vUJE/jt?-{ LXOQL\cF W= O  f*3;'2;\Xbba+ y PHOњAx'UMM о DOX"'HB "@S{XK asiQE4JݚX X*gǒ0bsr __` +-311xxxxtua(,@@1X321+' @SXK,:=:=̃ 4}̊)Jkݰ#߽@3ޙ6C652###KX[hc_ueL%:W-}D b%!A! jpu 膒  M5bb95. 4} !4q4W,W ,W#!C3%j[2$$$ u::44""%%'' $/7G"&KW000L! ͦ9Sԭ ENW%:Hd. '/6'/6ߪ|W( %}0A0M"4RQQ55DD3;B'''AAA۶I[kvJ0S(  >F;c[ #$1>JJVضD PK%777&&&444JJJ***ݠJ 6q"  '#qi4O  #p3Id)(-5 ******\\\= ; 5)   D*vʙũqg,9a#GMxJ}=! ctt  <;;!xSxjLjʬ;qX541+##$, fɿDD..%%::7  tt8(ERLoM2&& 6T~6TUTN&+H{{ ґuu( bp} de-b_ww%YDh}E`#X#!!Ž ",ճd?a(. "AlXUSijkQNM10+ DF J99r#l#`K{%MZ]rhg6iEkNG'"A}&\]TT^W WWgI 쏉{r   " R h]:Bp%%55&&\eT "-vvF-&333vʦ|au" s  -" u$򳭨#'%+0   fff,,,>:Fth ЖfXpZ33@79ʦ9hh0- <,9D$޽C@ "et!&&L qCOs |z@%x777 KW֏3VTf 趯#N ]{^lOs$%(?Lj%@Axuu͛e3eqqq%%%&] ~7 㸆ZYA ).3   ^@}?}uuuue;e sݍ##Z]HH@888 ul, 03#"#;BGt``Puu`,߾I;Bk##dII@hhM""">;>LL*3Ⱦ#(.ꎎŗ* ''xlO`,+ B!BpdyffhhSR8( U_ ĪuXZE+ATrGBH&&  vvvKKK\))qa+ VVUWp ggvbbSddpp% QH6@mW RNT:uuup11))qY 0qq.3 wwDggpR|pspp&]Z\]\4 #yyyy@NYޣ(˕/k<< YYdX OvqqQ3=ps88V=   ^  * SSk4k󠚜gmOvQ 'rJY=*,#7n{SS  '*gwQ !E>5Q.h& .  ,( )w`谄(]QP*V-'g:)ъ ^< LL 竫,,,WWWCCCiiijGH*3JJJ达EEE666```nnnCCCiiiu#ε䨇$RkJ/!!x:c\*blG( Y2MMMZZZ````x~iHdbYJ##% 8%BBB %&LڴySDPUOc>%S`)0aП***y5 --  )8%d-8*tˎB`PrxZ]wm9 5bh$7 TxjX ~vCDNlvC*** H H  0G` ! !-M-M Q g3C rPesS  mm}zy  Jt,%kX7 .d/ewV`  II<:V\uT$,,lR  qNX5-Z{ ׈|yyGHY:v5UX!3pm  #%!$'  ktH;Y ! Ke )^^ f)D-˵:һs|q  KvHdpB偁~^G9Txat  "%"%/=K8n !"m $Q $$   (5KbF4%& J^ePbpȻ5AI!!=++iOq |~Q0aDII # X' TE ǻ(>1 NamPbpGg5tttt鴦06=>HPq.fd^g22ah9/8@$  k5FI?2%  Qao#, տZcD,k '%*-4;@B@29=-7@  8!"!" f $jҞ"#ʟJ[o SMTNU. ! ]m{,1-jW :.b!oK6í&BUK@7YKk~=  9CJhb,1-> o. #8d ϳBKA? =GO "52-" ><a.C<.     |'>\\.a*35/&0 ^g)k{P\f]lx5.' a.Q;;1 rw㹘Y5J^  2[<.2$# NYc"ƩP\psx 5<K,H-s Pr.$+ gj0"Knh2땎sbq~du톊 > %$2%%%% 'NZ)I\gar  %0$ """ :';0 \m{{{ )E<-D+++[~꾑o2+` :+  -.ֈ;;;♙dddaaaRY W> B> kk kk ??????ƅދ???J7+-*1::: CCC'''&&&YB nj 4mmmmmm-#`?;~$$$uuu===R<"hd **1 ZZZZZZvY 솆SSSiii$$$U>fb .|] SSu```mmm WA\Z **1(((" Y8uuumbbbpppz$ 蠛|y SS+++nk  7777-5>ꆅ GE QRQR  ll jh z{ XV &Q^Nzm`RRR(g4g4Sg4g4XbjN9' N'fwɂ.HmjFׂVDr XXbV)ɂ.HmjF:PnrX' hojθ~N!ffD.Q2Pt}i:贅e"kθ~N!f4MO'v O'v LN"j } 2K}K^C<n:P0.qﷃ_d/N:wY~ﷃ_d/LgRxx@ }Оg~m62Q؈'xv>62Q؈'xv>!(^V3O)JnHaqBP/ 8@\}480$݃zy< xߎ*@wr?}!4Çy=B NDNއy=B NMmj@(^V3O)JnHaqÕhC>8ƁN B=3AM&_rw>AM&_rw>!\\ũULxǤPQ.*yr>:,@;-jxg?׮y|HgF?׮y|!\\ũULj9777:$>f>fN9]a9]߆r{.t[F;nQ<7ZՀ"5gQ Հ"5gQޢ >$>f>fN~K:@;S֚ ::@;S֚ :^*3zvwSP3n @/DD?ӆr!)* 6l7ϓ7N/ N/ ՗r1zvwSiN"Nny7iN"Nny7X(jyR0NNnZrz]RvсNP1NUd&xQ7-qפIi=` HW6 ` Ii=` HW6 ` ' ƁN[ 0NNnZ GGtt``l 8{/GRARCC'`CC Glg4g4g4$C"g4P++3%%۔'mmn~j/77y22ځ:73(-2OQTTVs a{Wo |5섄.7Oe|Oe|yIII}}w j$$Sq.22zf:Pc`zvvvv=Shh7QmCXnDc !CXnJ_sIaz7SS pppjjjMf]]]:U   / Q    JO)JO)$=~3 > ?   ^   ^ Xsg Xsg  =MMMf9G~'UYx\c-Hcc-""8>O)aR g\1XӿQnu]N&<;d/(=mgN\ -MܾhKU6X' Cgx}V+R @~w\NV w#3TG!]鑘t<+!G),  *ZrZN!Yq]S &P}ƁN $A`~XbaځRAX' NZɤnH-UBuk9R7:j,N L)3sss G{}IT ߯p-_ N NLsP'PXbWqK.ɵtJ,Sh`7^^77s"SyS`|dUquN }zXNv29c@ "mq]$W݄{th ''/VA@AUģ= )Olu@A(9X>aP|F]{t&&yQQ~555 icwV KKۺXYD%FhwBb ##hhp ͈$+Q=vLpUV1U= AVoQX =t @ `_lРo71_\A4zw@%Lxʏ66qtt aaFib\ʽ+6C׃>p @ۯG3fU{N Uύlq}[/hH2dR{[/hH2dR{ф*]T'aGbO'b v| GG"ux` PwPe` GG TT555lEE((vvSSzzyijjµ   1nQK:% zE$PH7$PH7$SsQyZZ1|tttffg<>=FDC  [[[555IC>&[/H(555346Cc.;H]0\4[[[###:0Qf{I_u κkA@@bbb]v=QdƬ~tqk ZZZkpv888\.ZtZ b6yy222,*']je`9b~""Zi\qaCCCw&. Y!i11prugiZ1p VVȫMM}bɸ ^:!Ƅ$0:z_~.:HjA;Mawzc\dm]x?PbXXX'.5`{1?M㭔}ij *3Yr$.8ϩwF}}_^^ZsiIQjPj#+ Um^0'5BHn QhQh ff_ux&~~~ (1w,8Cwk`]]]GG (17HZ(1'/c7  WoȹWWWˢx|&&777|pxO',,,h~Xbl牉www2?K8GWgAWWWGCBSkC: fDYoW-Xv0?O췠o>;8zT0k: (1So#/: ֱ[E\r ˻l'0x ~~~www6CPľ;M`|BTh]wzzz!% ̿.=M鷞'/󄄄|||Iazk: UqE]uhg/!*hav蠠%i 5EW5EW^1{ F]tF]t^1# WtWtŶ~a||| k:-:F#)Z\]ͼpUnʽzzz6DR ^1M[h ^1$ ,;J$-|_g{P$q+6C}Tozzz {V0&+1^:~ xLLL`XXXm|]/?ShVr(6b6 PjAVkHLPķ3DU尔zȷrkKtYw˹`(G]uzO">RgH_wZwk]zn?f,;J]zO``vT0>M9L_Ȼ)6E;-ˑmIo.=K6@KJd}̻mYu.]|ʸ6HZUB 'tD=tB9N&<;d/(pXH_wNdzG^tTlk6HZG eSP"UXu"5X' Cgx}VIbyMbxKd~FYmS C0W /ji5j\NV     U^'#  l)j%  S l  JO)N3ˮJȂYegӊXӿQnu]Xsg ] =   Z Xb{NX' g\5dS {*ɤnąlF@$ -MܾhKU6"cc"S1܅l' Vm`7^^=@~w6ԂcS|w#3TG!]N鰄eooǞ7zHxS\n.x{ 4b 4[)I߻PmƄg}鑘t<N9'X-{?i +!G+!GExE܄]i[UN0O ƁN $A`~+]^ok؞v 9! GGSS`77sD77sGGNN5x5΀%&oςN(}9}"xT"UquN } 8q;qNY09' N*l ؆',c? "mq]$W݄{thgUquN }oi|zXNsN1v29^OzO}sˁQ!) *3&.~7 1pCۏ6o`-W7tg~/NS9N+Vٍ2&lZ)N+Vٍ2&lZ)ф*]T'aGb@dllNl)N_K *ģ= 7' &dyv?;(9X>aP|F]{tģ= @I%2>kY)OluB>kY/шjXId|nwxyt-.pa`KzKA{_uS*| 7qbZ*| 7qbXSsQy_>N41.L ` KKۺXYD%FhwBX9 okKP;|:^A8q=,⫓#_;gK1n:]<]ߋ[`u4^̬  _&-9HRo. qA:Nα,ExDކ]i+]^ok؞v ۵J -L{c AVoQX =tUR"N?y5Pzc] x٩wA9jdyP4zw@%Lx/}ǗY!$Eq} AVoQX =t @ `_i{Рo71_\A 8^XWO!`kIS9! K|K PwP*``lGG` 5 W GG TT5ipi PwP` GGe``GGA~qA~`>xv>xyDJJCCC&&&""sss+K` GGiqr~I|` GG` GG.x.`GLN5x59}"xT"8s;sNZٖ}N& 8q;qNY 8q;qNYP*l ؆',˝Q!)/{v FFj OOOz+7 'ria,77' &dyv/шjXId|n{{v EEĔdȶ?Pb 41-K،u~~N `Nx̤rv 嗗d6 J)yyyoo Z!jZZZ鏏lK%zťP3HՏ3"cE,w9ߋ[`u4^̬ L3(ͨvJ MM+,-#6Zx qqqooo ۴J -L{c3NH N,[ry^^ x٩wA9jdyPk!`kIS1 |HEA555 R$h ꋮ+6C  L|L FG`1j1jBG`GG` W`>xv>xkU@ ¯ ~EXkpH"nMiO4ռ l iEз-6"+5g: `2ѿp ̨B?<d6 vz\oH"9NcVnųpTϿrywuʺ6FU ʹ`111 ˻5ET `2ddd:::&&%ʅi?IS`i6FUbl5ET XWV$/9210?=:  SSS&'&zN!60*]0I'нoml+,.Pr)4?_1^7ǩЦA0Of}K_s ʸl>=<bbbZt@RdĪ555\y2@O缞v=<< ooonlh XXXrvz???\.ZvZ b6yylCҐ KKK)%"Z[XT\́]#؍sssSaVyk??? *3H[prQqqqiloj_S*x j ! }bɸ ^; G?6{\F_w 888$0:ʹ_~(3>mD8J]vop|' sssWojKMgKd"+ Vo_1,[ysK!&&&^}u=RfyXŶQm>ShaeiAVkW-Xv0?O췣r32/yS-l< %.Tp#/: ֵe Ohg6D[qE[oKc|j9 UqE]ucedŲŲ!*jVj~" h6k:0=K&.`abǸuZt˽jjj]4999|Q%~^5CRwM$jjj|PPPl```g4ZvrXvñXw-=K7AK+9HuU"Hy\jcN&<;d/(T7yYs^X' Cgx}V  -J\NV bxV% ՂWFY& m妅iz˗"Dn[lmXN9' ˗"Dn[lmi|}ɤn΀%&oςN(}Qu΀%&oςN(}Qu`7^^~7 1فSTiu{N+Vٍ2&lZ)N#?d5Re{#3TG!]Nz5ETõwi   N[I߻Pn z[5ET")1GYbe. qA:Nα,ExDކ]iõ.=K ~_cʻ)6E@/ñtVHw1-G9 Xe7\EFA3-i0 "1?    ZD_A)!C&K) ":* (%%'jq{ %P]N9=3!)!Y?Y?*K*?" }toL3Ilz5(ٿ.'AMGDzP@]Nt~g  Z5 +"!GZJ  G2G2 :"M+-ͷ49K.AMGERCY 7mɓ ۽9a0C+ŚZ;fZA-HC03. rqhzql  qOqOF(K*  ɓ5,V.88A<{څX&Fw_U>?, sip@1"ξLUNU'*  ++~X /N+9e8 6l'PѸb0Gob\] X&lPNXTWF  Ƚ( 3LUVD#&.%:J(>O >J^O"" !ĻLA,(@  6'6'qO>$O+*HHHчŪiM/Hd/Hd. 788Ec]^R`X('_Ue20. Qٯc9ADT9BN$0Ƴ9A9678 %0 T)"&@46 316  J4J4آ +Y⼆{{{uqjimr \i[y HH{iMR`[20. b9՟">npb?Kd,>5- Lf(FZ KUb 'opn$"*++jj^! #    tQtQnU;+ wwwTQLorvK aJ#ʑ 3l#)&N G » \fUt}czwG{i7F&&(0ț!wcDz{znYL(5usq1vO п9lczQ}X zo0Wv1 3®IXarRŴ #,ķzhe K++ u "%   eGeG&micxy{!8P ЛM>"p P>BQuLWȆz, Xub 0Ht89SzmSD@;\u,뫮sM(dAmcXÿO& ΞL:Ƿ B = Kh )     ((X`n --,--,nXܷ~~~ZVP^[Z4K-&y R. CzŸ3+í[2*Ğ֟}Q+ fgv3NQ|F bab  뀄ɬ3R'K)$"9KC@ļL>U ഴ *,B !h&zh,) qR@/ " kI8Q`+fP~8 .Ҧ)|T5(}W9'G@^bIlըƮ:n͘'g~[_ +޴#/}oGX]\ٲ 0&32-TG4   ZO൵&0F#e T> rS6' ҙHOHOPxx(#+"^d";?EL'Na`67 &2G]]-*vUP9  l  )!D &X@ \4^0:FWNM;^n>i&:`z6, sVgf[E.-AxY[biUD Ҁ,:gT6%K4-yY H 9ZF@< LWd ػ,; .0. #B0 D1    XS c |+Q vi4QC.]T +xuY> $# wjb)#(#~[# ѳ)J]SwF>9۸"#-0(&$5&;*>-ʂmӊa5\p` |s,W*{X@ bG2$RKyy,8 $H=zgNR#Ӟ&j5  yW=caJ"t00杣t]C$#c'%<{&`J1\ /M`ggg*-.6=mfTӘJaȶ %'0ۣceg8K( #C0B/  7.c@3!(,&fYO2-7/7^ D :C+o_ ƅEsSu}.hS%eI !.9sl 3'?U+ Q[[VC Ԓ7 <6"<6wqM++_C "hƶ𴟢Slt ݩSD4 -)/F9" I HVP\&7'?/ 89횶 gA/?-#BX!%+7,5/C14g ֛ߑaff»-4: $  8?CkfaHA" J^/W_4 ZA8C989,%\lX0ksA[ܾMn^yxEa +$ VuVu pzx 61 #bb#Q?3SI4"# 9$"p  L7 L%#- dq_~A  Gʼn  5c  ТȎ[[ Vcnl=abJ!F91DBAA=; _p}Y! MR).N6rS60=.^CD;v&V m)i)i* x'a +0   ú+8@+⠐%"2xD'˘a6E?#!$\QIE0:? +-IPQy0HF0`O ;)4F2 FA @=j Bui}":)?.  j<( ٕ/,.5 z0[%Qhѳ 0mp vsv)0 ȾTh%178Z-&$^K`zK2 oT=PLNrnll ئZc7  bD@MMS+,v!\V= wQII1;?BBBe6Hi2  >oD uL 5%%U)  ׍ %/8%*k v &NLW\ oN6]-ᠠ7_Ün $"ܞǛłfE~*/4BO\ Q_@Q#yEg&0*v  P4~d8K ͎o#OR#? ܠo=gY4YM`Yx: 4d!¦*>ZĈy63%5=6iV= v/!6&P uD*bb|x¼5W(*OU_ m_o AB E*B2ÛllÜn33  $$ #"%+  =CH olϬ$2#cqq0I!1Fn2r(8 )]WK-n":$&*>Z]  Ń  ?uHrDzh-`^?,g   ';Bq{ ." 9C9 ˚ ]^#++8B  qq0 '7#"᪫ٮr .ZY2n΢;inbbE)7/ *G3dn hͭ2R{$$BS@R T- ":!(-gT+:::cc?y DŽQ3]=7L#"zGG)((*5*0>>  AAA}Eˆ666gXL% @[9[9d<2 &=<=;:;  nػ A Iv4&2 xur !!!!$$$J}IX $5n5_iq%  B >+ &?00//fUuQo+SzT]bT1[6!+2q}SD3+ڊ 𸸸830#" ooo<< P:DpbbVJ &,ͺ.BO ɿ"%(]>ƛʝ1!*N KlYfSgLF)ff29?aR:ꌒ P *^^^^^^ 33333.!4"48.hch qmi 8^诌  |bD  sᔜ.'-]\]X1Nl tmmtt,.0 %*! 33((rrr9:Aէ۲ii&& 0 !C3?  Ⱦ /!  K Kkkiy * > !%iecMhM2Z]^tY| k`n >?ɴd9#]&Щg4[M*f,f>F  IKʔ::66BBBAAA~Q!!!gr|dI2rS4[=!% /F4A嫮0,* 8* XRWUTnjn S   ; ;"I JF~Ѿ  hz&&&KKK -Dp8pddN`-\P~( ^b]WMF@÷0 ¹$]]+!rmqjj᪘bt؄;;9BDA qoΘ  o FD;;;KKK ܷE"EA D//*x„{={a҂&&&&?LY,,.9FP  @/nu!+!O/*#F6)y~v%9e`#Q!ot&ځ)`ݹcGwt: }yt  giZ#I$IHHZۈnx$$|$|y..==''Bccc+%뺹 "D7ڞqDOL5"otځ)`#Gwt:  ))H$HZI0rx% %? ==__BQ::yyssE֬T+T::LL,,;ccc1118WlZ51{vz vGGSqC&&    .7@!.9Ƌ~?~ff$+ X,XaaQ::CkFU*T ~)5555r++#(瞐{}ƼD#DQvv!} &&&;;;JJff%#!XXY h/G 44߁!!k6kCAI F+spp||(w@ @{}bVc=:DlQvvp[[~!c]lll&P0̼0CM0BQTNO8HU/G 4^֢r-z\IO +,-$$$핓ZXVuuuttt```PppI5lGG66 $$33OOڋ&&!!" Cٖij%%+߿A!A|nwl?b^ceel͚f3fqq[??! ( ']\]" 7AG(Dp~ LI""YUS ֢rz2\O luz lnln pp~ 66$$޽C"Cms" 1*SS%%]]&} A!A۶I%IV?ʼnw;wm>>ee!}}f3fAy=xÆz=z Y]]G40$ spr pXjD5vI5vI5  |l       -4; C"CggM!s1*>22 ~~J%JKykw;wPP..!~y~xz=z00 ?H5 ]B ~*(     W jblhy y M IHْ~(o22yy|ee| * bbk6kwwxxxdZ Y ׺T`Ai `y55 XW!! ׯQ)Q(oJ...;% :PJ(.. ;3 Cg@ K## X> {P uU (.3 nb T> . N&# vW w  -6U    jX8xHdd-rZ r @G ՝(AAhh2277Q)Q^^^>>>(^6=2o`g6PeͼoğQKIN}ช) ...---MMM___ ՏgRmUT _C _C ƣsss 333###QQQ//////111111ñN110"""  ((XX(1970+ &iiiiii (((((( IIIQQQ'¢ 332>?>%%%bI>`%%"a>t5+"H !]=30 "lH! ===''''''s/ `1B߭!Sc"\ޤ9nOHFH=}A?NgzOW''j, '1*¸%. "mmmL>wOt  :S-%n5 9uf" &4}~R)BU Y+g["!Sc̔(<+Ѵe(` ssss !243xF`Y〵5=5(!ss ƭ}* ޾71fe1F@I""444 xEwkKts?" ju~wy0WfxbU8^mR_{(29z^TEAA򓍒paSB1"e112 ]5 $ 8$3kzm앃׋ 55IIRTY+,*. %*  (& 6' oPv 5Fv{-!Q^}9)F&1u|xn"0T72! . {ro    >%&&7,(2)N^8N77<#AC <,e  I04#' ,:Rto=J        Q:lJ R- 'LI$Zoե: 9wW)?e B+J1+ 6   B6YVNWr9- U@ gN FqRtp$)e.F$:$    <'I1(, .C3  V;sO4$  gnR`Z}`k0# Ѷ] 'G.+  33c<   hFI36(  V`df(c"3 dqxEPK  T/a5  Lq ^@gG+!  CJ||))q,,   ,     ?0I@]<_%LbD^@   (( FF]Y ZY{222 L 5e QfA zoC" o Ze)9 cBfm,ШґG#_   nnqq ZYQ6洆ѻm!4&&- ZZ ffpTQ h T}X0%ZBS9Ր  p !!rr^^TUU=Cm q  Ɵ4Yh5U' -ͳgcrMt81 G  A ݋e o]hG)1 ?O uw5q8~UA6/lt\V ;X,jlcc""Q tofR=+7X3Z;?8)H?1 ! qg&6 !"# =)|YqByk" G1"&* !+gB QQ;ii;; @*$&,Ȥgi:>7317=Rb.C o   :AH !23xznر%6SʡϸqP}Y #(utwȿ+3;@LWZ_d$,2:> LL* #%  3&  #$.55K|@0'\{@n  \\pP#"6   ZYY[ZQ >O]¶6I%Ǵ#8dJ1DѵHiWr!& HA[718>&,1 L!( $7[)BY@I@\u<3 ~kf'<7024462-32.  [<'wJeϗ9Eǿ?6G0 (#!"j3 ?KUHe~V JKMj6=D,3:   7= BABK   "@j0XA)B*  d "~¸ﯦ޶AIR 2-  TS51fc&FFF +֨ GGGEEE+++ :+ YX /KKKKKK @1۷444@@@DDD )3%  [Y!gc%$  )222222{{{   Q=⡡GGGDDD,,,&3' , ﻻnl WThe -######ggg %׾pHHH&&&BBB $2&  럞燆:7|EENNNNNN3& ؖٶ1 pnFCro abab! PPP444||| 腃., DD+,.z˰SSZZZyxxt IF ____D@<&| (:M`  mm ]Zc`$zt@Vk&-56555(   @EJÿgy~q8sss"*g4fg4g4Xb#;'Eg6ծȿ ,T;Yb$ 2"9W=kꧤitf-}U5¶1P/+N:j   ˯:܄rARH ܴ~A4K* ܄rARH ܴ~A4K* YZԑtט0} =Ib5ܙ˰_2d9IT*0+   =Ib5ܙ˰_2d9IT*0+  ތ5\Lr'$ܹƖxf+pU 챩bS[: ߇o PXr<֬Nތ5\Lr'$ܹƖxf+pU 쳮]7}IkJ ÐoÅ%p\ތ5\Lr'$ܹƖxf+pU YZԑtט0} =Ib5ܙ˰_2d9IT*0+  PIBo&3?ӨyyyƨXD_kN‰.Q, 4/f)g %% >g ܳ8?5b?5bٟ||:owE ?5b?5bٟ||:owE ︳sc## !!B︳sc$"︳scܳ8?5b?5bٟ||:owE _6:M`]} V-##,- 1,- 1ݎ8rdͶJj& 'eV]mˤE$ ͶJj& 'eV]mˤE$ůic5J' ዕm+ݷůic5J' ዕmůic5J' ዕmݎ8rdͶJj& 'eV]mˤE$ \\\\\\77 #,vuR0 '>fu{+DJTGٯ}"=xm'>fu{+DJTGٯ}"=xmŚUX' ̪ L9JW*1/ $k"  ̪ L9JW*1/ $k" ۼGҩR!!@%7m]xs0VED7ԨzۼGҩR!!@ۼGҩR!!@ŚUX' ̪ L9JW*1/ $k" ///99''''Z`Xܦ{&$=L/! Z`Xܦ{&$=L/! ƨX!,$CE~13"+oҶֺ|Μ -0ZWV$ +oҶֺ|Μ -0ZWV$ %>&^m 3\?qF&Ԓ=X\ *swⳄƒ %E3YzueN %>&^m 3\?qF&Ԓ=X\ %>&^m 3\?qF&Ԓ=X\ ƨX!,$CE~13"+oҶֺ|Μ -0ZWV$  G`$\J|\$\J|\ G` G`71\71\71\71\ F`F[SG`O\OMM F`F[SG` G` F`F[S G`71\71\g4  g4 C"؛ MJJ~ؤQhh$TA7{}}}~~ |88,ƨ0deeQ((11q4OOO[af*6B/=J%.9%-mpqQ!!:ffggfgg**p jVVT(((gt9HYi]}#-7#-7I^s,8Chhh瀀RuF..loosj`cxkMMMxx3Mv$$ nnn6== *+,zxuLKK߀¼JJJ9`3>Y 666//pzznnn^ci֔˼yZ eWvWv˺ HHH]UN[t@Ty0Ty?QbIJ$$$q|z$qV|Vƕw6甔ggg}%ZdeiqVr2AP&3@JJJhhhvkUmeeP^UʼCCCHT_w%/:˽ihi!#5CRi=$/;K_tK_tiFyyz*7Ckkk[26(Pf}5CRqd6 QkF]tǴ  jr|)4`20?MOf{|ɪ獃x# #?QdCUd[u/=J\9%1=F]tяjDJb{Kd}:NbWp777PKGɽ,;J^|Y6VoK_t7Vtɽ000y{i RmXt {o,8E,8ESh@Uk;M`(4AwN!$,84/%-rg &/Ld~&3?Oi7I\lB#Z03CU3CT,=OENV///tng _  t#F]seD9:=?Ui vT$/;q (G\p^;q[o_B#ly|g IayIayxWξt$/<Ld}@;9.;H  h[2OgUGU :G @a1!!")5@e{O# "',tD'/t UG  bUG B q TD E + RjLawݢdpB 2BPevTtG ;K}*8  >>UUUQQQmCSo 4  E9O^j RSvSB @~ o 0*n.! o )SvS}A7n.! o )SvSB IA:!,5Law^}ύgAs4:?"egX/kEq % : I3 : I3 x?𱱱iiijjj===UUUV0Vn 0#! uUAmx~~^8: Kxe $0>>>>>[y­^s IX~ o`ww; @Uo'  P:A[aUo'  P b: b:b:/7nnsscc?\\]]TT- TT-Ȏ4+U>8Xb !5'E\,'88蝞g~'ow71J5:X' Tv5hzVXb:X' Ӫ=Wm\ł~WU ߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98!) j  +WҩK% -@~g֔囉YDo;YuhaJYDo;YuhaJ $`{4q˳_P/LW݄tB)w_h % ģ)=V6 Ol}䨖=Wң)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n|38EҰ7ˮJhƶ}8wsǞ7` KxKǒ AkpB bg Y7RTC٩l a[Q'լNn^KXbPmb.J:X' ۝S Dgl<,:^Ȁ§1p=⫓#_j ^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B  VzV30n0n G`&7&7^IV1R1܅o;:X' ƨX )#7,O~f A{?಄ot* At6  A{?಄ot* At6 !4zÒ@9-ta=*6=:Âc$/|9iɗ|J $\ED5Éjd{|J $\ED5Éjd{Ye KB20/84 $E?LAS[Mݴu !g[K  G` P`P P`P G` >xT>xb0S~kЃ_V_f4vB4K' Lk'swobvB4K' Lk'swobGv, 0>(ZNZN)): HH h   8HxS{:mg,V. 4b 4b)'! /I<֬Ȳh!NL]M113xu5!!{HHvh88yZtXb:X' Xb:X' -V@c Mަ@K- +) , !G+) , !G *ZE*ZE܄ri^! zv88z88LL\\\(((CWi%Ɗ\ 2mBKC$(ٵƠ !]UT4  !i,YΕ P]i;1Gv7_HD3 㾄,k[", -Gv7_HD3 㾄,k[Wpo("ҬVp 1Ȧ__JY99&&&"##XpI^sjmfv 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ$@/Mq98! G` >SS G`"77%#SsS,DD77%#SsS G`N|N55x5ppktEETTTZ^^Z^^`__NkLL=xxefg`3q/=J&Ͻ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:Uia?˳dP/LW݄tB)w_hnnnnnnYY :==77gqq.OO#TA8 @@ճ`5 ~e7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛8;/9X>ՙ´a=&4?#0=#-{n| r:::w222RRRd{{W==zzzZ!!!55sZZZZZZ4EV"/: 341,LؾjC +~itaw  `g`KxKǒ AkpB \£rrrhhhH^rWo%zS@9_gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQ\ ̉_1D" %F4%F2Hd}B  U:!!!i?XXXlllQQQgii`2q/=J̿'4A -z-̡ĈJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4zÒ@9-ta=* vX9ͼ̨bbbYYY`2nn@@@ 5iL5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` >xT>xh_1::: bg;qqqjjjkkkkkkqM^~ Y V)ӕqNEEExxx===V* \:"""ͶzdMkkk   ̥>>>++++++aaaDDD&&%+{ _=((( xfff!  jEǜAA9HPY] i*** a|mI|N"yl |T-ߴ\\\  ---sss6.'H]r&Y2@O ȭ'''JJJJJJ4,%/.)j8GWp 1AQhi@ !!!-+(579c#r`xxx􍍍^0YsI]qlRRRbbc+6Ak DZ|dssssssN;Zs@SexQQQxxx333ȁwUUUvvvgAAA'''rrrPPP[[[%%%x%0:0>L)4? )1pppQVZ /OOq1eeffvvvtT.=L,:H*4ɻ/-,t +50@P$/<'0 #/<ORU ,,-}{yFFFz||LKL "%'geckih=UU` ywtZsjIɻ]{z .=K.=KWtÖ22345Ytc!,7sIb|#,#,8J]L`jqpqPKEZuBTsLs?Qbij)))ut$pU{U{Ɣt1뚚```DA>H\pXqx6Z]w{ 111 %%kD CViuxo 6FU6FUkkkASfĸmLLf `z`z˽kkkyndOe{ eeDOIȼ555MZgs%/:ȹdqqpa[UAUfI]qI]qz3bbb600Dk\855wR,!([6'(mMǘ5CRuK!)1rUQ'1#J^s8GW8GWm !*UmUmoLrrr2vY۵˽ NU\nȏǶ`bcWbm&/`23BQOdx پ|~v" #ASeASc]x.;I ]k|#0>a4 (3?Nez&.o˵1/ξhq%.e`'2/=J7DR333Y`g(1_~%/^<>Qbd5K`<222.=Ka9|Vr } 3CTuTp$1=ƺUTT5-&n '4A̿`35DSkn}XG4GT_r D[qD[qïdAMcyUlQlwO(/.-↬^|ve:_tcG*͆]5j.=M888rC;Oc-:FsZ@}%/:'4A^1$,11("YtΡ=Qe=Qez`3 &dO;y)6A̿^0~$.8"(υ]5 '3>::888vIv"-8G[p0>K!!!%%%ydL  CXn*8FrI!#2/* Pj4EWj@m^LlJ2BQMg '4AqA}%/:mGG^v  LbwMNN]4@Vk"-8%Sbr===ze$,'3?'2 ʽ%1=f (BWla=jb[ƹ p1AQ&/$. ĵ;ObZw%/CXl[7TQMWt õ]m&3? Kd}nNJczNcyNgJczI8'~Ƒ&&4EWs.AC͑ CYpCYph7DZqTo ]jvgccϾg6UqDYp "NhNha9v .#'3? *5_8}S(!&1BRW,Ʊ~ F[nVnwǯyl= UGKHDnx~R'rOk>DK|P$rOk78:'/VnQlb:wUG  b> bQINQBݯpV`[1Xb:X' Ӫ=Wm\wYxnKu\znI{RofA ;K}*8  Ǟ7`޶ſ "1WQb۝S Dgl<9Uf\d~%o^:X' Tv5hzV b: b:g"\ r 1&Xb[alA:X' AX' Y`T͒y?#9,d}/ƨX )#7,O~f nn -J\u#[q rK 88rrAq|I T" ߲-!=a>WU d~ߨX1P/߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98!3sU3s G`rPV +WҩK% ;q:dbIg0|pnYDo;YuhaJ0zXb:X' WDo;YuhaJ $`{4q˳_P/LW݄tB)w_h̑_"eV&% +VAV)B 蝤AH+ģ)=V6 Ol}䨖Cģ)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n|妮xu.qzw#ƶ}8ws i-V{w"az S_i: KxKǒ AkpB B!k}GլNn^K̢ǹ 0O2I[)#˗ȹ /N2J\)#Xb:X' Xb:X' ;LwQ}w- ,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B Xb:X' Xb:X'  ii G`&7&7^I΂CX\ziLy/ )wT;o;:X' CX\ziL|/ )wT;o;:X' /U==L.  A{?಄ot* At6  @Pzc]N]"A{?಄ot* At6 !4zÒ@9-ta=*Ɗ\ 2mBKC$(ٵƠ !]UT4 ׃>p`B 1@@|J $\ED5Éjd{Xb:X' Xb:X' YdP?;- Ж_XhZ)цDKKTFߵ|(zekYe KB20/84 $E?LAS[Mݴu !g[K >cdO- 1@@|J $\ED5Éjd{YdP?;- Ж_XhZ)Ye KB20/84 $FK|J $\ED5Éjd{цDKKTFߵ|(zekYe KB20/84 $E?LAS[Mݴu !g[K  G` "uu G` P`P 5e P`P G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ#?0Nr98!/00vB4K' Lk'swo*|= 77q]m㭉Q$ q9 )V0 ,)^#1l{yq[Gv, 0>(ZNZN/++vB4K' Lk'swob*|= 77q]m㭉Q$ Gv, sB4K' Lk'swoq9 )V0 ,)^#1l{yq[Gv, 0>(ZNZN H[p ¯@SeϾ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW݄uB)w`h 4[ ~'[)'! /I<֬Ȳh!NL]M 4b )'! 4[~'[)'! /I<֬Ȳh!NL]MefgH[pz|~q@Se7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4?".;$.{o}.AqU|}z ʺzw3|NZC +) , !G ,,#8G$ *ZE*ZE܄ri^!.EuUxɋ) ʺzw3|NZC +) , !G+) , !G,,#8G$ *ZE*ZE܄ri^!,```a4 }zvf: 341,LؾjC +~itaw  `g`KxKɓ AlpB ˡȻ 0O2I[)#Xb:X' Xb:X' .sc̎\X%_CRL (-ܽͨ!\UT7 1Gv7_HD3 㾄,k[AQ ڪ̶iW Ď",/Kr-TGF<Π,uQ=Wpo("ҬVp/{eXX%_DRL (-̨ܽ!\UT7 1Gv7_HD3 㾄,k[",1Gv7_HD3 㾄,k[/Kr-TGF<Π,uQ=Wpo("ҬVp+x}(yyy\\\$$4CQi ][YF3YtH[p %zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C 'F6'G4Hd}B ΃CW\zjLy/ )wT;+6|6 2`K2`K"77%#SsS\\ HhH G` G`,DD.x.N]~Yw,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒA9-tb=*׃>p_@ 1@@۾pCO>=- ҙcRk`-\,sUi^ ˗i,yQ9YdP?;- Ж_XhZ)YdP?;- Ж_XhZ)цDKKTFߵ|(zekLAS[Mݴu !g[K  p)) ???:M`ttttttPPP/AP!*4 5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?y/10.;:7p]j㲋W% KzKEA{ZfԌu/$ *|= 77q]m㭉Q$ *|= 77q]m㭉Q$ q9 )V0 ,)^#1l{yq0>(ZNZNs888w222u666||g77ShDDpppppp11+o3BPBVj\vz :;gq.+&   ~'[/I<֬Ȳh!NL]Mhǩjyzzyzz [[ FCCOZZ//.589z[#*^0]xEXk .AqU|}z! ʺzw3|NZC /N1ֱ,,#8G$ *ZE*ZE܄ri^! bAoEmH"RRRrBBBrstyS#*ó.=M õyyyyyyH>ξ2BRű.ueʌZX%_DRL(,޾Ψ!\UT7 5 jXXX+7|72a0_J G` G` ii I=I=|R G` G` G` G`.x.L!*4˻Ϳ&&&pbbbbbb#+40?N(4?'0 LLL!]wlHsE|{j {R*ի¾ da]/w>KK||||||.**y\?6.Law=N`-:F ε BUh"+5=4,95u-:FĢ3DThuLSjMcy¤73/.03vWƮlVfff _1^xCWjqXYZa3x'3>ҿ|aFUUUTUV,8Cn Ͻx^윜ssssssQ: _{8HXx`2B#p&ҏrU݈ăuRRRxxx|_EEE'''pppyyyyyy၁bFFFmMNM5DS*6B%1; ͿŸOOQy%/90?M)4? )1pppQV[ 0>L1?L#-7!ŷϿ788<<<wwwwwwR]hWn|!!8HXFV_ŵqqqPLG!}ŝp#-7#-7K_t#*ߺ>>>|rh5DTjY 1?M1?M`z_uxxyy}m[ovffCCC*'%3BQ |zYGGKD9Pf}WoWoóFFFM-:I*4ɻyyy''&~}(31BQ$0;'2 $0>QRU_z}8I\a_~ ,7 ,7F]t1?LƹpppspnVomNĶWtz .=M.=MXt󐬻+:<=uVpǸ{]$-uBYq#,#,8J]FW`Ĵ|{|;M^²`a uMMMG[mxk ;M];M]onmDWjeBIay ff____<G[pG[pbE0.,zU0!(}W1,wYö?Pb?PbpEe݋˹ "ghhz^ݴʽ PW[xŸʸhiiųg˻_ XuIayIay EEE˺hu"*g`'2<[^a_~ԎhBDZqQl5HZ˼򟟟[[Z/?Ojîg9L_RexHHyyy.=Me>zTo } &$$6GXŲeJc|)6E̾^gffxKRn=M_=M_}҂Y1e3DU!ö555oA1BR3BP|P% (Pi9GU҂Y0/=J77333qCp(6CQh3AQd>BYo (".Zdn999jFD\s J_tIJJZ1:Ma(6C'/LZg888fLd}Zl~JayNezOjOh    ȻvS$XCG;̙5G8Xb:X' Ӫ=Wm\ąl1F9@c+&cyph$  - - 9dMӾoHV*|T6(==뿡 >c-@~g֔囉l CL3鰳|kKeǞ7`Xb:X' Xb:X' ƵlU(:}.۝S Dgl<Ɗ\ 2mBKC$(ٵƠ !]UT4 AX' Ɗ\ 2mBKC$(ٵƠ !]UT4 AX' [`|-0O* ƨX )#7,O~fjmgx 9oV9oވ~LR3߲-!=a>WU ]mbbH⧊%DwJXHd~ߨX1O_npedUtAZ% ߲-!=a>WU 羍0$AiBSH^nedUtAZ$优ĸ$@1Nq)#jmgx 9oV9oވ~LR3߲-!=a>WU Xb:X' Xb:X' ]mbbH⧊%DwJXHd~ߨX1P/羍0$AiBSH^nedUtAZ%伖Ÿ$@/Mq86 E^ G`Ͼ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' $`{4qYDo;YuhaJa2m ؇:UiaI $`{4q˳aP/MX݄tB$iivϾ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' ^2m ؇:UiaI $`{4q˳_P/LW݄tB(v`iģ)=V6 Ol}䨖C7@I%2(>kYģ)=V6 Ol}䨖Cȹ'GhO &dy{䩛C(>kY/8W=՚óa='4?#0=#-{q|ģ)=V6 Ol}䨖C7@I%2ȹ'GhO &dy{䩛C(>kY/9X>ՙ´a=&4?#0=#-{n| 341,L   `g` JyLǒ :v|T  341,L  `g` KxKǒ AlpC %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j,;gKΆ+m:x 9uQgP̉_2D" %F4%F2Hd}T %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j'뷎,;gKΆ+m:x 9uQgP̉_1D" %F4%F2Hd}C Xb:X' Xb:X' ,z,̡ňJ !0Q4R}q A{?಄ot* At6  @Pzc]N]P A{?಄ot* At6  8xw{1Q=|.'!4x!Ŕ@9.uR(,z,̡ňJ !0Q4R}q A{?಄ot* At6 -D}})8aC[5Q  @Pzc]N]"8xw{1Q=|.'!4zÒ@9-t`;( Ɗ\ 2mBKC$(ٵƠ !]UT4  5iK5i P`P G` G` 5e" P`P G` G` A~WA~ G` >xT>x 5iK5i P`P"*`*`"J G` G` 5e A~WA~ G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ#?0Nr98!  °@Rd CWj ų;M]Ͼ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW݄uB)w`hkrxs@RdmnoCWjpsul;M]7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4?".;$.{o}|i?gggb4 h= 341,LؾjC +~itaw  `g`KxKɓ AlpB X0m5CR XXX..8HXf S1b?Pb %zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C 'F6'G4Hd}B VVUVVUlll_tUUlVr(((L5#)y QlPPP^1DVgUp,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒA9-tb=*D3EV#+EEE;ObMM׻1AQ#+ 5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?yRjNdzwwwwww76'q1?M McxSkjjj_1l5ET 543579xZ%|||^0c?Pb]6  ξ2BR ;lmnu (2õ.=K öK;/?OȵUUUUUUbcdh&2=   rvhbbbEJPj + mPPP>>>___f$0; lQQQAZ1 f?111&),mF`7 @@@Z0X+^0c?PbԱvKKKtvx_2"+5xR.jjjX1[vFYmҽx_Fzzz\\\\\\_18HYirMGIJb~?Pb®rX444UUUUUU_1+6Btz___}}}}}}ffb*5A+9F(2>%-ŵoooRS5.J!*4˼%%%kkkkkk|||!+42AO'2='0 ѿʾKKK25Y5s>KK.**xZ.g4LB-PIENDB`sardana-1.2.0/doc/source/_static/sardana_screenshot.png0000644000234100017500000104066212174204305024606 0ustar cpascualcpascual00000000000000PNG  IHDR 4zsRGBbKGD pHYs  tIME  ) IDATxwxW}L4Vmz~1$@˕PTHC  L`mpok{mjjUW}񌺴5IsF3ŹiÏ47jwB刹ZwbX,k<] >7^J$J2C/p/]`0u} X,bX,V@N3`DcgU1JķzDxN0bX,brBvoˆ(D "2OB{g%RB55*'65X,bX3-F9l!ji)'&@PmSbX,L@A# Np |AC]>iz#t_*5^ R|{Ⱦ,bX,ta`,pyu㇎V-:'c% АQjr7#,!,JL,&&bX,ۆty"*eц &\TP5]b `Y(& 2%4*jՒ,59\,jQhPBx}65X,b<]y$ -9`+;u/?Xa2$߮cIIeӼmiwo<q>5% "?<Pks Ց"hb6šaT5?Yg2}Aj7'5Zw `MwJپ-bX,V@~4q3}BCCS7m5pO`@%[,oqkdWj_tG_ 9eVfC{8jtpGBܝiƇzF#!d _;;j_ۧV! LH'(1GLfnS&wG!2^p<j <@JdbX,_76%X咏sc>!ܚgp_>EZyVs駅2z4۷q]MMRSf MSe>]*";lH Z- s &#'"SHᏘ{cp#CZN%3bX,Ӧ;?q˝!T Gc鿈 #8 AA%$\.L^N2>{ V!C]ROZjeYw,JXYɋHdJt"ߠz8b 65X,bXY&XΰHCݚ";qd`ʀ\R,q؟3z74]IED -gmb{ y ޵P=ᄉdAB9q&ilzl†lLH}JLxaC}#?P@&ʉ#DH$f˺SJ7VR%rFv,ZEAE$g r>ਠ;0bX,_OFt_-~3kj0 \ )7.mR\9Yx^ '61+'*lm(Σ5D|a,5#x;s@S!q2GNX'dni|32G40Kʬ,\P't,JM sQ2a1ۈTF1R5yX,bXH}ħ߬gm?@>uDw؜cyC9@C*)$݅)D|ěͧTD g6{l/Wt@6eHFs93CJIj'K'eY˭dňLZst}F'_DDpLsT ``SbX,_1`"_ Rf PME3\#ŪFRT2-B97)$4H0P#%#EI{MǶyq67 F03<qk4A8Y%{;X&X<KqҙVDVvY)&$' cU\t#n8fSbX,+ mFW|;"MF^@by4ty~iw@_OvC(&lc!{4bCk42pONH%Rj}FNj9K [+\^59ag[]B* S'4˺tRUN%.y}rs]$ Yy#&iB ">JF$/&w39(7G`2 UbX, HC/33Mjz*WVDQB*Nۖ$v.>#m)^pp?m3yu?[K{ 4є'=:1-(A+uZ^NP*)zkِU;GHTD$\T!pHgnr`;^,XN*axxp,'GF L;N9AXcErQ'ߕ-Odkj6.EiD$(" DzHԳ[T< bX,y"HdTB W&B ̱3pQ ToͲz[=w(|./b{ |h_cg^}ywa]b<+RiE6)Ȁ-H:'qjC(Px01=:W)!( TUPù[.:%U9){x;q#G4!W%XQZr.d~K 2%NM4!QG<"y epO zO:*F % 0oSbX,1BF!:_m>p W ti Vxbj&u51qSDG{* 7(^*#N\]Mooqsd]9͊:.|Lky!jB™["%hSD@& ^0V7"C|9I& L(vHpr!Cad,*=4|eVNΐ(9dE%]K>aIr |jpI|wDdj!d`MM,bXy:=lFm'՗r@9~%$p]&^R:ȷ")EB${~6ɹW9\pkPx *:2hjUGjE[Vxf+\qfֲ!J+w9\'aKBsEOjRjpq q0YAE J9'/'"r谾Ἥq2cP %Y!4SBUNs6EV+!|2+N,1x:"("(:D_[=Z>9Je0MM,bXM&%|{+Ϋ)AA W^ы*j'"Gt DeMUAˍq깭X&YѼ!ayC3O1>?G^ G;֡z3Z Є6 ʅIQ{U1'JA:$ FuQJb>ƀe.I2H8 qpVX۬}@k@3L 㚞1~rPfDS DO’. dFDFDjD]mTS8y7}}%qbX,_g@fxU5 DaƐmqYߚq"mClkz9C~a:[rh0:(G |@A} iWa&?KuBiģXZjh9bꀲ'>ІB $XLzaġi1jtlho==G !qp]wMOTH%*\-rV5*ַ(.(4=(0U4kFrQM1ñ<9QH2XqiJI:a#lj"tYH@yAN it9@'oljbX, ȯǙݮCOCS3k7BP }(Vb uH9.5q΋ABCL5}##C:CzC'5x&?D'hW"r+|}|5А -EjS7E芏WX@*^HK DaDQȱcc䤅#oe0;1{]QHrpuc̲)B9q!LPNМR4v]T|& U!1LiF%32KW &3:7ß*4TS\\M_4Nȸsd!̀AL{Ll&gSbX,V@~2aD55Fk(" C<<*A6 4d6r$ oȗ5ÓḬ`_H`x)i&h<8pj?IKFa|Zy$BI@^nu6Q(pcSLEyTֶrƖU{(D6eˆvRɉzU$IԜ}!I G\7L_.W|V$'Jt A9n:sFx%" H ""rF,B^9nJ8L}5 o65X,ba:T] ` fm:" =#*NMʜD| ~^<#{n!/tG=l"LX,b1UWWKf$N4 pHHAzXR F'r{%0Gt\u.-Y.:;7xCʾa 9'B&5bfvK 1{-x%*҈1L166W,20TfӪULҐDGdk=ʺkuV~zBR2!j Qgh:`l>mD:H'튭k?i]c859:S4s$,DIƒ.uԄY/"gΑ yH nӑ>h@2MM,bX9y9v?p]\ƚRn?#)*~ɖOO4ZXN LR u&]2.\vLWC4ad2g8≾dD9AqHBҍFQrϩ:E+7ņ͛ٵkExڙy%Ib0M ץ!Q) qZ!(OGU[w+$ƬL4 G0FEƯ6TI&)l^}ȉ&'x:WX>L)]E"I]jeM'#6TIq$zt VyFFDrr={PNha#d~dcΦ&bX~kDg?㜫Kg?3^^=dN-@"'s%NODQ(r]2.){P7P ߏxrB@>PS. |L BU$\ C:=$.P۶1YTj$JGsyg1:'N C(@BxQuS吮kaݪ, 3^8bSL+qjԲR9IԤkvcc9M5\9NN^<`%.#6)EDLj S+%tʍA/"Z'MM,bvH) -s? Ep7ÉM "!B1t T֝mgV#ԭ݄p1j {OjHOGɴT:['m "? WrBP$P*yLQqs dVӱpxH<|.0" B$C T>9YaIp">ayqm AT 0pь')IQ4չiv9{$Jx!ax2 C2TZ䬧|x& &knuMMrHND&1{n :1"}79jSbX<1 | > ^IMe䮗Ѥ8ug~?ٟȟ:v~õz3֮aY|MWR:*.OrFI>eNm=|' Ù5K6d]Z#2 OT=0!2$\K Nu!ᴜ4}.+ HFeJ"6Ӟr(Mmjk)Z)\<ĕz6}! %iM eD(Z$)S|z2=V8.̌pqpS.qAhSOd:f$x^HQ(syrb|>O>7ER.>u)0FG(' +F訏cfg\bj|Nc:B< Te|HiGD(Bp QPRleFN3)Ȥzز.9-HJ+W2zr?9|03I%XbN /'*o}R"Һ05B^DrJR zw_ũHpdr&bX,V@1s]dz2$J.rg>Jw.={3Fw1r>Nq]nWyt-&E|nSw-{g|g>>SԚK_G>&.{G vKx՞7=~s 8ٱT֭[,HO'=G3IB)ҮrQ.H#46Ƈ/x~(R^J/GD NUP$9}^D‰GU7:j]ñ Ono<ɱrͭ-jRdt|.9u_|Ε4Ԥض.;#0T S%C_u;hq,?x!siX+HLNd'Q5d(Y'i<|Drqs{47H n?X,bPB&ʚHz{Nꂦz?ՃQ/)hpI*.?m,lϿȧ'^R/Rȏ_Ʀ ciIڒM\sv):1dwqE-.zzqŋ \4z:3~2?=qק22$ N3K![㢲.1FQ!#|?#ʞG\E*qKTShDTMHX *S)&&hiȒR$uudjqM8 #WPKo JDDMCmZhokA?b%b|w$[<^'V &K4ū#d#||}uNjrCCZLF+(9ljbX,C##S)6oJkZΝ;X@l9r\[hhxm~Uw^Ӂ({cnm!qN7Q &xb~_p_i׽l.>b1iurR v  QdnϕԵT3/(-9^IZ>[X)vsH)G+؞&izQrT bX,V@~ g\ƳϺշ}kǟ=Cmo8D™}ay_߹u+hPW68/Bssk$qtS=4C|?E{?EmGG^,(8h0}t+v65X, BU eV"Nu;9ct5KƔ I!ӇRSz$J)jVɺVǹ1qb?W ƎM-䇏s;y{hO Qr]̪$3_j8 kil8sw`Gnm/`S{WU;ďn$ϸk^"a[:=I5uY0Б&!QAQ>"L q0@ 檜P^RKe*^*e|BTL1ΌAD qV7g &%Fsq3|xg^3E"Ufk$/oҳ.ZW۟f^gsɹ;~t"{ P?{B$о; vޅ7;ǝ}+_ĩti㣙$ QIe )h#Iah@])x>rZy(d4G].Nz:ˉ BC-m37Iş)Mf`|v;&W~sJ'or+-:nٟ%-"""Edo4+= G#GQݾj73eSbXyǂ܋OZ Ҭ[w *[#+_C_8H;Jbxo}ƻW<>hWg˷1䏜8$kyx`NYǦu+EgtQ?uvO laݦ=L9Ȧ\ts>ahx3[߾Et99-xzp ?׾s~?y n]GMS=k||Y{1vy&_q{.8c21>I}S(MBA1Nc FMOiA.m05 uh#jc%c`qĠczz-;z s$ uBckQ5~J^鲮cSx;^bR(-qV V6Jx钫7!ԉZ9U<[D B%juHxlw9$7G1GE_EbX,V@Nd}54gUU_E/ BEmK3kvn#,r^݌>8f+ug7pIǧ,shΏ]]F2Ug|]G!(e]7]zfݖSNqgFvκMey]S/RLvvf*ўu絙ܻBq.zlK3_x&s}m\WC>ޏ!gx74>^Iͩ;Ol- 6ɵ_u1{F% ~W'usdFq?C,wºUUN/w`u9QD&:}/tjZ]wI?:u[|6la5C/ڿ†6C6X՞=Eʛo⳻_@V#n (X@2 MSmbd8sN>= pkDL|6;GZ#}6A0U915] $R 9 mwL'Fc{( MאXnVN'5/LLD-/3KMiZjjS\)A$!jwJ}IM4Q.vʦ&be$P׾~un~w:Rμ"S<6rvyMyq wkvݫYmɇoW[>JCx7s^]⊫͹A:`͎8zjtuJ+IySt;_˓&Qtbo}o=|kg}2O|ɐvyI?^9gl4> N};kwPtqYAYQz͛5*(ӯlf ad"]ŋB599^iLyCP FH'!ol;ߥU9 a`w\RԤj$'q&wA;w6Tδ7n'Kxd\ W3U$H2*OhĶh0nlk۪~@pI$?lt nj1Bm]-DJI{c<=̖uoyv< ǁ\ߓv]wM6KNgx8V"ݴ{ϧ.Wk:j3yΞjz+ 53q]3!EUĥ]I˝4,''dRBk=l^5+'jr/5=qIWߘa4)Tď#'˕OL3:k&kQԊȚu$Mi-S)=7r#ڑ^"iL'A8eSbX5PTY(Bbͥ/UsFsxt g]κ)SѰu}?324PK93™>Dp~tٴ{ovʿwݼ977E9t\װ E8#B|˖",hlnfn <-2a} IUR G8ԙL<&nuwVQL0qxލ=v ${H2w=s9ׯ =:.ߚIO`% Q<a6=IJj"TXzLXMOAd6=m(Z('5)I m uåfcf$WXaVNhaV$k_x#[uI3Q$JdJ)-~"PwĈMM,b=7٦s|4ԯ㪳N_"ԭ)oEP_|U6 :6k_>M5,&-/aC*PrچϾ>n a߷?O)vִoyW{V˅VN$_9I, t%ZⴭO_u!G(“eMu},X1aR.Ⱥ/+m#"< 6 t&$֤(D! Q D<3N\wpuަ~j* QW%}O<8M<4+7~zƇyȆreC%A/BGYYnހ䴊ֶV:s+۸}+ {gw9xjAInq0KO ,I1:Gq4MJr I{G;!NX#@͔X5@1><ȃI{ E~ҲPD %Nӳ'fFǞXaX.5+ma|,Jʴ6s2VXr.{rv'BumwTNƧ%GG,G%'mh$dnӗe-.?DYA9H9Cd"FB4EB`ٟ5!bRXRՃMXB(ī,ʳXTYǺN_kJ*%M|NA*>Nd5CKhP1m=(rߙM-1pdWQ5זd~>tNt`择;yy쿩ظ0XC:A;A c0!tPC]V&ehBKť 3>Dםq`fzFRRDj<ʮ^vcǣ7d[Y ?y~.eya/ (bPe84i0f'JrɽAW̞X^X5]VF{PRǔؓYaieKy-OQڥD >" ]68Q)NelJrdb`4?,Ld 6 S1MS-58=Bx2˚ kbY2', ]eq}/8`hQaXB(ī^ϩ Mk IDATW}7ϩf2'ɑE#T+knsgG~/3Jq?KrX_z{{ -I̅tP_pjc\VAc:q>.0(VwfsdhPEӾǡ٩SҦPTAh:ZذMdث32e runsc<.iYFR3 d06T!60C%-3<98Np7Np{L9;ظuvF4**BTWql&9ž}GI?W,uccē&N]SyibfȹgJl\#lcfiA&(D !x5\FSګ2+=zyܰ&94dOgX=NEɂNj3(֏N6xv[BTEt ~ޒ&,D]1KGPXB(B۲$X%]UUBbBbƏԭ5!'@N C+HGH7ǑA|:&Zy*EQS"o`Y\z%ps#qڄˊ3myp0%Å1[L(j8ei溺]2"UG5P,*!XT@T6ё$r%Y(#P}a*+.cN;~x {2]Hƈ'R9UQULG'[K4ͯёqPZ S[4OW[`)Xh",(0ENʞ eĽDZ2; Hx3#co}Lx_[h/8޷cEY؇iH t -#%I1Tͫyҹ`#]]#ёaV0Ҕ+.غ7\Yɽy.&g\tS1 Ku{3XV%@stHia&'y᝜7-]N!P4'~ agDݡPQp w%mb3toJekp85#Qsޥ&&$C''%PI1Ofl(6%5?c;类% H1syu7\#yz8o&]sW=/70iO}%d =GM{T|/ Ѵ x x|~ZZHwీEy8(*ciGz{ߣe**i_҃n̰7wQ%וlڰ梅ZSyI,ZB@qi\Bym;i: IrehS$&>r4R r*Zm{qØDs(kҘEqi]m%iH2AR{xM.fۺ&{Vv2:EyIN{beKfkIi+a!0{bXaO͞,DN?=9!p9%Ah(('Sq- F,z-"p0?eiע 4z3h!N_5˚ !Vf&BBJ5=A)ҧ*A s$/(D׾U\-,k3p\c&-v'wu<8ƍ'Z2yCsl2s<ŝ߹O|S8](# ~-\|k:.?)e.j;/}G;ٱwe Vč4iBC~ts뤋46dpDUs8IfhX bftx K8B>Tifv1Zg 麆lpP^姼tχpB)m㚫L11L=88."T?#G'񸊰H0 5b8~ N؃9t+xGٳaa6nJW;0t8KqLT.Ę'4̹uKy-eaamoN^[aBWϱҮ8v J\yt\2I͚߰؞'cӹ.C.%N!d拳&ZK\4e{Brʅyi1Jm}CٗcMQ]R`M QB@Yn?X$i+c$bӼø+䋴Qn,ombmk$oSί~V+X=4}^ P`F_[9[ObNy/,nVGz{>o-u<".زKEh0̅`@H_}bDn_tk.qUS}:ӓrٽ] & E TXKwݿȊ x=uWMcU M,YK!v>MJwu1Z5jĚǞ -W0Iڔf^iBJTaesk;<}RTE=hH\(ī,XMf($34,2f SݽW]KC?-( .dlyщI{%W/eV8kv37jz" Faj)XNYr6h8tMKcԔЂtByIq! or(I)̴\Ǐ|gx v=8u!kӨj׉f)?Ku-zބ+bS;?!j:}%L*q}Aܾw 4,p8T[W-o%lT]w1)jXkna$ħGLyA3rÌOሧx]pؠҿ{/6d֍<g MRҶ:4U`ӤR)n"fTf/B)6{ɢ H4[3yu8 iU"ΝҮKP8d+.HGlPrlȨ V&683`T̞VoJJ cM k) ublmⰐ^k yHQ~#I5)D! *^hK3wF!wn{v8TAgmVNs26-92l186&˸Om1Tb1r*Bq2oe` ؓ9,Vƕ`9ɱ&MYŒ2n!R*:$U}8h0ZRPGG{+m]Xnh4zIK%=^7:Ͳ,8uNQ[4mN-;o#~_G!8%u<<.~|b[ff/fs'yߝw%"^rA):1$z^Tow.Pӹ饢&ױfًښZ&& 0pyݘ$iD"QTD)iĩ}I QTJ}]E&g@q<.ef gY!TQXʽPu|Eut+uY)4ښꩪt⮧'>Ļn݈2t  )X1 ]6Ѵ$^+dV-Sq.bR*]w8@2H}4*)`S=Q܄[+(>ȨRZYH]yDuNgL0"O"4Ӎj(` `e'vytpѥQ4dk }H"ㅾ"Oq8ѡcۗ"-{xx㤪 Wd`ڤ)tl䉻wsqʻ 9:(YW3aO 3;19dv.mʘ-ʰ'ii"S.lb;s+( P]@gI"Òc 89 ^fЕ,X 3eAδk~geQ!|@(" X>˚X42TRıuWXa4.x5)D! GbyhjԦ::[YI%r$5'`c4MLpZxuvI9 @N5+`.G8ure|x[i_A罇DBa>ٿ ֣D>ʧ^z%V&?Cfv[vGd 8H]a*a[߇i^ng's^Wsbٳc/@G!5"/7_jxPTeKҷU4T8ImqB:G.<>7ꔓƖVB}x K~cG%*A}{?[6,{PK*i} Nc RP颼"K{v=$WZCױo+9ҽx<WƺE C2R0\?!LI:9s7e7-my͡PUmth$OÞ؝L'/43ZY݉.2M03icVo.pyΔvUv_ޔ')n!<I`sr")JSrNYשA<1_vIY=5i˱&&R)!qW2=60UTe]}?V} QB̋"- ƆZ`,,GHJ=1``ZAIu@Wdv^O$9O@02'sHɢ.fSlRX$g{Ww‡ нb}SumeE.|{ȝozJz=S%t  D-|ފYD "+1tUHS/ ޾!>(<׾GN*xUKٵk7JfƮZ'F)*g͠9?Yov2i zT4p_9JSX'wsAAgïj$9p2~o0gMyc,::[X.Z:(rKsoF$If҂ 0-P]HdV; "3128Y*E-t&2Z:a~xifAElj{Dj۰DpO?8^-]H>]o$؉өN.Bt<2⺅G* BKW20]̆"K*YN6 T OE1M;BEUz4SZLh %!')Yjw]?RT;jVd]} b%+XH їٰd ^?өc3ac9띣 9#˲2-g*t *ۂtvTy^?=3˜K¶0޴$i"aڠDrDUlsk^g&( PW5NYp"9 gI~<2euM& eA^7 kOδK#^qwcR(u<j 84tu`Pc0v/:3,#dxRJqjAvso99)%)5G $zP%!~%d?ȴꤰOod2a7G7cL=w;w=3<ȃm”8T:{Xk&a%˚)TwqU_?i@4 MpmU"{9kWPVA2m;]\N04. 1Տ!\4/[O}]-e0%Gʧq9WeZfLB-PTKq(SyxxrPZKEKG :\k٥JdM2f8khkai 0;(gI<|;"zXH/ys[ 0r:wczGxm}kv% y7~UU {ռ rMI,POK77C!VѵlO }Өx눎NOXE0s ѽd!fb\gqf޸w|+eAjzVm`˖U\RS]okY WǛ)]a1 QBjAW}F@Z`4ˋég}Ǐ?@Rd*Ep3w⅃IZ նPQD$26wXΓOl54.^6{bYHĜZrm3۹Kbi;˼]0QE^iW99K!p:%h($md*.9qdtF,%Na(%2GqU@x؋&#Z H_3鑧RRIP: QB _`4|>OC] 0tt 0ʫf,h#"zf0 B lJ'a3N 07^#G4VnU;A.Ѷ|9elN8f \TbV^UK>Σ;>}t $I,9.ܼuKrbpt`|]O3#z5_Ѓ_jͷiq/<(ǃ=E$szpks2l7m\0Ar @pvKUQp{hZMUq]%|)&'83PBCG{=QOd(#'>䘗1:\trW0'"T6(*4 tt:2uaPE,\g$%z9X. fe'y1d3/-fD,.yC 4Ufr3ρe{D s"1셔#{0"/aD{b6nxVw (j{A\ 9͹57t]DU J^]. Wf3'{ar7'v|o*ǯ|]FuC凉Or`ؠ~&.8z |xwG350=MytyNse.6ILigiu47J?ּ11sϼp-o,'_(q5lhFELL~ ebeql%&R'zcT*Y݉iJz=12!Ү,8v NAY+U΂lFd2.nEhD68ɸԕτM "90 DĘI )Dt.2S"LSP (/460z2 c quy F%wtRQ݀p#~D2i\`XB@"E , +Ê $j+=ͲgjD8/G/_|%j "HIC-afWw=L_%|V NH8N6룴uyLvI =ƴE1΍l㼦zÌ7LqRn;?ȕXK;Џ?ZfYO'=u1~96^+vDO 8U"5~Vod4*\H/YJie+-q|aRV'HpWޔ`yO~ً3~'XSM!'-1 LtvNVGRz+1o5ğu?WK' v>{bM.2M#׵˴sKLkV/I4!ee'fk]5f< Kr̉KPj5xf:fI 892b?YwxG՞&B"<=J: fCRuݧ8PEF VBϒNzvIe,peK#'^$`n1q*`"Tϓx~̩Bs!tzoFބ4NFwŌq~LN2?<|/_eً0砺s{i@ʫ |Xp>ھ?`uo̴!L& a֭[;qcwhM=ŊP`&@"Btl:;Vc@ɶ;]O_sw۷;ݟ)_˒c|[p"2ͪ [Yl.^؛_ϧA)@RJs&UI˕h8n-\Pm8.:3i %!Mkjhgƣ>P0# 1~`'~l` Gx.d8)ᡡg >'~A%u>* >@TMG`c<٦?Ɂju8i -&T.ʁ=I&0m[dV6vn6HdbȰ]5 N,&3tRp"|DP!^/䔅(Ĝrl/f9`ttvQYӈ)"j QD2da[3GF䭾B!֩bC1̛SG|+֠7]{]7+4X3à_6Vln3 a!&~D{_*!eĴ0^"EɋznZжj-7uznۢZ w)λBV\ZPK;oU*ꦶM[>@bBJn?16|"Uo{֝ a&h.<Ip߲Ej6^Olo/ =7Aṳ!N&-AƇcy{5e˟X^y!O ė^^VBc2Tt;"gi+ͫ$|xZt"]TMEy}=Z*8NTa2rcS^q.-΀Z=uϚ2']ޅi+l߸MK43쉑3e̕v9]yYQڕNnUUfeuM$cӒQ[?4!.MsBʢ۽'`8ښ*[mli7]]T6z7s;#%3sL`3'oQ(8Ey]q 2 Gkm?FhF.̩L@f03X^}?cQl}!c`UIamxH~ؓ>_4)ZFZJ_mc~ΟBзn,V*6]p5V^><2Toシ{fv._l.:h(+PʽZmTT൙ %|?~'~vPny?[+Db.Uԝ5Ru ٱsvL729I,2NLP.%u|MZHb#b]t Ǿ4;eim0;MH$`H&K3 =84p8p=$ǘ1tgu,۝('\COQ6'Qt^;RZĦ 2~U$qTL jh8RҹC;CqgFUSRVξxnC ZxGyU+c ϐtVre?GxDIǎp;XŹ̌ld2ʻ]%3zVo?o cVof Yl-!x T҆81L[HCiP]a(ĹeRU*[n:;P]׈-&jx0?H<6`dmrƙXyʵbF:ls@";F3_@;`rtL Fܗ}ٟa&I=AJ0M UÀ̋.w9r5o(FRffnNx l]Ś)ָ1la54lD2eO ܉72G;yݔ9lR.f|Nn~mm}*n'F7}l즥PYCU27E!QŠnO$sYy&q;?u{=櫈{ SW]DtlM7o|O't~'FZ,Zή.b>s]98nl%l]LƑ~_l !@Q W5Pb<+w{7/RۺVF^)F,[.eSG-^F*m"Ñ4 ɮ;u")x^{V!6q\&Q\^jJqIG%^x<5_Rӏ=NC]=piia1~$;%E<>xYRe^bi9Mmͨ<"O)~!ѝN.z9쉔͐daOr/+#m+]81-'6lpCsWJ^[᳥k( W)%_;|YNsy΁|SʁYQ8u9"@@C[o{ )i(bX:y4ChQ5jhUK=ѝ1 u?~dFhD#x.UWO~mH ؿK8kyaebz*F3?<N9~LU KW5R!s~VDـ bP$ {J"37z);j3 gf6'1d;|b6ר8S>~Yv*ji $,Xm6Y~$wr9uPEŘV!F[U;W^flP>؉.E7u:nG!VO],`IMMG4'4c w] { !?&QrcF|To\۟%M2$Mb]M1(;tMkMꠞ5eRt]DG h5 'i7Ʒ*'$uVO@E#F{cq]F(IiRVRDRKHE%vR0Q[+ƖS#A?DޏW$(AO5"jA~cp[Wқ_!&sʘrL3M({ߧi9̺?ƃ%K2&*K^TΦWsҕopcd&bT{jHb:6{g9<%={  l@a{4jn9s][M((-рQ,"Ҩ `pit5jm/eh yuǠOx'' gEj᪫hؽ-I~2YEeZ!kMXЭ㉳te9tY ̼fv843oe[QUSY<"!#.uݛ޻>{(Hr㌳7MPղhI)>@JXګ,j'SRji&,Y R-'ά~b ,'TMShr"Qy B lqrvaQNx@6WAP6WYeGefIc 2DtT|9^8M`8"*N@K &\I $yB30nV1$${@٫vH6eD6SiWO4d4]&Dv񺆮EDv8]RX@FN@z9@n 0$U(BrjJ2y9_y)%%e<4v5 l5:W,0㐪Wu\ﲚ!Jo-V35- FFD0v IDAT1\ D>U0Z>غNRt&lF?螓-w%Dh;BJ{VǏHO.';p D74 >ebCZChIAq8l% HN˿pPg~l߾Vn bP$Ŏo2۟(eԮ_ؽ.$I!b72?pQ$ƙ=jw%㰻<$p/6kZDI FՑ ;[7e#0@ AHz̆;LgWO݂֗ye\&߽x60|5Qv&ղ?x+6fYq!X~ 0w屋P@ ׸f )r7\990WW2‚xqf]5`ta2U5Dk!m۷loۆQ|_Ş@BN:3NɠQo/no&}+ٵ_tmI G]瞤1!!^M5@s HP2EOjr{֢B("wh王=C0d 1ι| M۶EΞF,]#-8g<˅M_/ߨKL^ՓVc֔QkK*)j N"[SԨz"18騞tH}'Tt T8[Q$S%%gb{Wj7ktf0TX[5xgywH>a(Jx[v*$#A@n"GS!iWdh~`4oЍh'tDK*EF C K ˩DEvJZrٷy;r䧥%rh{E4/5 p1!C{neSWgR߇$\"bٱG0޴D*فd$bǚ,*<z՝\ d@*mISs`݃nP p M?PLP*9 d&63&˥[0[<\p-Ȋ V|ĸ8oYϞ;\+AD~z~1EB5va?lJ.~B 0W7/)ġb]]eYTVXmVl6K]iG`d"KARt5w?G}Ed\^ؖFYB^Oy}C+)Sd#P%)˰ l_Ǧ핔n }7߃zb) zzE5']E"`EjױNtޣ;`XգM%{K[^Fii Y4+ktVǷ0C58RR[C]KOJQk!D5Hf(]9 A2A m%zs#Z%k[? ~>nF ]c&5 Tz(&cyJ IUK5E,~0!?eD|vtA$W%eUwR{՝m'y%lAk;VN: e퟉Wg $ݕ]iħzL^aTd'Rmi2?0b[<^-$wclRCrm?+~s4d}o\ QӐٜv &ш[$ ʆrC^_a ÊǓDr6Uz1mƾ]tʕ_pE Gf\%` )\ )*#E=҇YA[TcQqrY[s\Y-"'DnFR[„B!Ȣz7M8węEzZr&u!+2`Okl>D=FC$1>H{x-j쬜G%Ylޣ;:>~HOJL)+._RJKhOlZظީyfošCi/Gd` RG8n=6ZCzJ>;] BL2lx BQBL^nHU=r:F_4uA3]~D(ҧx "4kwż8Ρh$5gͶlٺkos뭗pW3k|d=BZf ?&oR۰o+Yy#>@P{|\eas,Po;Dq !I.M`:rҚ "RcHE;KJX'0YD;x+2= R^n6e%E+/̜|LD5ĨޫyvoegPb07 1G&$^Ď I8@qdDGuUASѵ0ݯS Lo-By Vw̺kXx, C1N\ z ]AAd26+NtR?? rA# ~ vVk "`3Ɛ6Sv/8)JbG۳~*k'((=PUsxp\T&Ϫe xj~z,~si@U⣅Z7*:hjo9%}ۗ b x"&o| g/-@yw:ma,/`He;E@71de?0i\.lݾ}gSu{p6X&sO0]ͪq>:6j[XoXZ4Զb$YܘL;c}h؍ BN M bf>YĪ;Y3gw0[2Μ"m;JNT4YgJ>kWu8K6aYsV!Ɠ,ۼ17'JpPOUhN@ACdA?wz"J==Ѻ{ic-QbD UPUT#蚆4d% [8d (ܬ6(++#+'33`T5:ϯ};x0 "Ѡp+Huk>:wu(s~8Z&]h{Jrt b }yE;d(X '(h[oѿlt|u$)׭C+28 -Ұs#5`廯Zgٿ`T1dh 7n徳 yvs'_y=0ml'̥@RfL>T7_,yB@&p}6^Eo)aAhd fyGdܺu8˘EYI!(/+#;+fjTktliY-DWwtǫQ+^ңz2wEjʑ^tzT !0i 2yƖ[8mIэC D&{J>Z63o5+jسy!s?Y7\FN `ficvoeϷ_!cvyzQd=uz`ANtA 3Y55IL-.+!Ix0:9t6Vв0.È~q,=0H} ru!sT1$5veDb`'WT3 mQ(HK1(蔱E%BǏw _;oE\~1 ,6|߸썝4zh.lYq6uߴ<.e䏘zd$BLJ\O1$M!7qP#_EF_R~0eמkvQB48 ܕ CtB\v T%g~üx$8،, *Æ̒Z}u9gu2_4o}S~©!*:"w163aMGt~}G#:EϷ|i_$z|IYbM;SeY9H_O:Ⱥ][=r=oJĩ&vU%UERh('9I̙G'lq>e܅'3qh*̎=$eQaK:"KR'IǛvkbԇ`Ma6+>L٤3IreO+ᰐ]XF:8şƝuL=s9vvn@S\8l&Zt5̢_MAA'nqQPadH$@5b@eQ pe|3.${1`$tɔv,I^ⰺ⽲'9 #hYu>]~_ ,p߳! =~qGe>^*wu8J R8zA+9TjTlw -V\F"?@fBKa0(TF FV:u\G ̊?5jP5 B` B,`Tffټ{"bHLꎚ'833~7'7v}?0{Y|Ž|lVZL;y,z5y3xa |֧3=0;3h<'i#;xx@n|nx _ƛ,^v2Ǐ!a<G4k9dq2W7S|CTwUiI|pv5Tw>JmL=SO5P+?a62`EjNݻ!kjޜ&ƴdv5ً%/Fִ)I2uT1F`=7-ztIpaE4_-K^}yk iS͐c*];Lf&3:x'Ǥig1&B%DQԩV\q&Ri`$ J CȊDT$IBD$I" bhɚ|һzao ɔt:Vkḧ51k1Z;I$av&u ~LObwTf[gs$豨'ά} zZG GuX//M{TH[8t8hJvtbpRbKY`eS O3qXELU:4pU`7%B4EsǾ?r91xpnAgjv<:.]x#y8Jq1l^ZofSLZ`uI_ @R'<+FsjMcjPU Q gg}i]x==rl(JLe$^|cֱ?Go܍(!vV5z IA?N:W zȄ EA" e{_ 5~o fKsGp0(2( 5;]@zf:YDv,&EQN.vW IDATsx܀N\R.Q' CӴ^wCeBA?ɄVh" #"V8(L-Kdz`x,Kdʌ󤥥Y,Fp']D- fj|"{"-A`!-hֺ0wz8(>EwNQh^2$d2S ҍIVHI 폧FtªN8 N Eeh:`C8~HUȞ&:HQB~DA |n3u~O߀nF<M_s?rsap0ӿ侔^s?xl5q2LpZp8^h81d\v<n)R[[on :ڛn!,~6FUe DA},_-'G btYBـ)1m Pˬ7_C ۹kOOi1F-ϧ[7r<]>d9d VEgraHjNK.#k@V%}mf{)Gsèܶ7aλlKÒĈ'#tH955_!)xTNZFFIo٤)A$Pگ3&cONC)v.%bni_AwUNLuVD$E"M6--ԠkZقh"$[)(fE90<@`Hs %`0d%  ]IEXQE~)R{"C*3[ߕ:p,Y&봭S/z ޏZ8̲ǐuXH|`IpJdxdRiQirS y6 Q@p at )rG T6 i(QdoHO9$T%Qce, qvYLF't6v$Kyb޻m۾] f+~~ 9~@!<%RȪJ|n' @d'g36oMn0&O.LtkZ$eP. v4WT x<.nRT8}_圁(HKS GIq5%栊,ClUJV$lc]T=E)z<[7l&Ιʤs|Yi,uFf]>-!8ڥo[nKy\98;WQ3و7 X]}~FY?K)|~Qg#nD~{ٳ~ Iwq$E!%˶]545 G~';iÇr@b$R򷑙I'zSBvJ oz3nv^(h T;?a ʲYzև2䬶ꭧRf 5E)vOML&~MIJIǕ ]ٳ+Kj &o+ .cZSFcJJKKzVi9=VI*m"$0:Aֳ `t/q4hK~/er5Up֧ԨBE`S.QMQ($"B6Gt¾# U@_Y`wĮCÅk*vk趴HX>o) "'䨮~d&"r@\zBD!5̓눴iLطf)/R> W1vP7U>f`m=?r?\&`|BO3gp].gcg\@QAkiD4Y$yoG-bds0'?9*U:>xQ̋ve ggx3d;9ތbP cH .1wPy&`XS]~@4`Sغ̺:\E @N_ Ju$|)C ;6$읯s3Ͽ4zx5L  U#xH"%~SOa|3(i)Ƥ߂z4 K|H4UlړLV diܶ˖rZl9*Y٧DD `@ײdZ컍°tmڄOH)"nPhb4`j' nT`X:v "("&K^kۑ%`OKSFNs@ DࢽqH]F,in`ړ^\ FOr:Vz0$+A!`ձFwoW%`4ݞ#G`uǬ^ɡ`֧+߅G:ES& )2VXhETЉBFO;(k}G=1(AmXEE*[bE .*.t]GW:l-DP@:5M"љ$GBE2zB:}-ECvT<+hBI,U[D'&_M~SΟ-g\q=dR*6JX*R8׫&q| le7_} k|H#..8ܽ+>oI?EoRtVbK0g9e*pYETՁA߆h@O핿#b䰑b+r̓7`4wv?zj9 v;v; f7f3v ]DC|*F7|؜^1]xsʙ89 YgY3s>l@#ND/52bxW=$ZSm1;X>[˴QE|¿U¨ 4YIf^P475!,X-XWs_%W"2y !sjwiXk*5Š-~2@%7ўe!j̐e9=..cْcMII{Ve:Mtq^Bfl`E" 2$wx =]4ӻt =[.ҷ{^|ϩQ]Rhc[Ũr$8Y GE"єMlk>.BB]@YdOF \t0usPW' І%n{6ՉSvJ&55z^<&Pjk+%(˯$<(H8~VJ FRSb Ѭظu1KؾQkYŜ{W)?7o-]4 sL#T9/ĕ'qWI,سΫ *o02^fËs폢 _-پu$I%-;,{o, d;tNݱqEqE׵('G/MiYb+2{nF$o)ݜ֒N^̺̞:tQ!|3fT@ɍێ %&h$%voYOslV#MnKظ9Be3yGU!o`|nh=מ]JJh .7f/qedpʔ ./@F6}{FB(v3AwyRz9w|*H$dѴhVQDDtM#Q.BKtX`w #]ŌxjLLәlONNqmn%"0Tz*K{Ā}~)R=NGߩGk>Y^7nw"V1J6 $d')(J3P5uK8-FGE"m]FKp!:+S.*\l(u 1EgxpqPǟ#*Z7qw ϲU>̽wR^ĒX"nm%G8IItؖ?jN Hv LN&Ьj*4;-ϕE0xŚD1 b5ȍC:9#R7L0OoЌvɥ396%&r.~O^ĖOrٷeGT/2CkZ]ynVAjvNws9I<ʤ^5K5bM/8SpB D7 ޴w"R*!*o'>->($3y0>KkSDE-C,=tpX¤8=d$V|w%^JjbL$ӈAQZצ;X"fDn Օ;f:vT5VPΠ~Tށ*$x[W#hO ŝ #K%8YQPaLE'DHD%`icJclDQ̌8$ gJjlsY(` +Nu;aBHR&$>J!]|ݙ 9ewnfY+MѕS`8%2 REaZb[e1)ъQZEHm At]T.T |@_% Ev5Hm.]…^(F.Ⱥޯ]+_<8~>]F?:$Ocs|1BA"!ҷΰ1˙e?Ӯ夤4TUGmY8N~>Xr'& {O>c޸~\Ɋ0Z5c.O |{͌Q}I0}w(Ń/wR6G]S7:N+u|LFF:yokDFNg|Ŋ!XOEN޵|A.;g0Wⓧj"^W>R*=@ @}}5q.L+N< ,Ua_[W,ŖMqI &Epa G!Dg~3t؝'LLՆv[mݗ&gIiqIDG'{X.7Yh80ħlwd \v,'ap,|"i驔{Y+6HE;vv/gqR?e<6:>E^vل$keg%H~Q ^ux2p*Sиc#ށèi&9ŃhV%,FAnQzaIVV5 "*Z$B8iRYQ&N%8 ȌO&)nj,f{%19;Eې@GZ G 82shӴ[#bS36SwVSI$!b(ԭ-Gk6 FzrݤI5tw *E5Ŕf@h rTp=9\ utM81&ŞIQd|"mkT⒇ !*yf0*&&Q fhi "Ew&~sK71x`&.v Y+y4g?5|4|+tLTLs3z.b6֖ 6DJ@׭_Ăߧ?!d4G?9o~K/-D:dRSXh) !W4#Ѫ=p ݆ Mjm2m8[3aL S'Af {_G~ Gxn?.(!ۥ@,ړ@&Z" y$g+?y??:<2L&O4{KB [kβ8,XX\ ,Z@ JKe\5+-}k3sfc>X[Օ-vLfSr8lv| fFAF2q$!I1Ttnt):z nd>dEу^Ql& tj6m,,$BW5t1(uP`v0>d#*1L`;2r}qL2wu1(5dzf*n)n繯wӯ`oe/ڣucF%^}鉀Q*5@\=st6f$a5 HRLcS"Dp!5&$PE튗E1G절Q\Uնkz[ Ѣq ȟFk$M`i>Evr} Â'JʢAiDQMU;]O(G3Id2|vt6cF!-j}HXQʸ?&Fd܋zqnݶ}g2ș:Kє r ~!p3elUZ$S.Ov.=c<2&y|A֯]Ű[^pl:m]ul>񽏉tw?Wb߹癘~ݶGCT$Qo5[gw?0T]r FYWh6M7S]ӸUuiJf>g]x`d$Mo]g~O(8 ܇ic7i2tK:u#do0+[tɩ.LE kD(! RU¶LW&Hd ~AĐ 870-$炈lAyU~.J6){zbfe3ۜ<:pmD%;e~HF; # ۫ I84ًlZҶ6-vLaE#2N )ގ6uv Rm=\ࢡ,*{}Rp!3WXq/ h aUo@ #?ziEGQt^ahS8d2CSm7D׏lV _(Vg >@@A~8 13[K6t]]Rpc4HU ؇*ػ7y6=].-y)QƮZq>XmR2r,躎Xn=kB}lKmsg1frc&7l3;Y?_bQoF,tZ=Id))RN9n'_nCw&Q%lprL+{׆=[>9f>T}]΄ۿbS}alfrwp}/%[>w?Ϙcw^DQ5k |5KNNTU0H4G;Į} ɔ.8{2. 3etߵOP%S`1Μ 'IAmo<,L,SPX ]ic AS}j%k7v;< ~<6-PYYA$gdb$!;$wvWd|01E6DDBU1)B3AV?BѮf-n*`5S~G64 FpQ1 @0XES$ 3 ENF 2 'KpUB.҈|.B2 eQ1^ǤePm^/ C@ !=H#ٲ$G^)sH-9ΫQ=&4 ÷w"VgRlEu߷o0T8c21֘k4 ׇǧ h:. Q%glfOHv$pTW#]~1;g# bug]薛tPDQBLvgJ#E6ش<.}8p NK8| /.ð} \~r˫{m'5/$'X5w3ZildYwì[fW3f2Ϻ^CNr|f a2,d6z6wV`T6yExb ES lCMMsnqռCoFvaHJtD2d̘E @K&*bc3BQ~KhEHOE3nQ;z]޻.t<.J=3Zh'I*ȖPQw|KpǷ>ljhjUMmg눂dw"g0vIa"8Iĭ2iMJ >#Bfшk,Ri6A%GrWE|>_q1{ hV,^Sf!C4#sݬS}h5O'k/}?ɃOcw?8\U<3qť|\&a0 A`Gz***2nZ4̶_滢ZONd ! bjNvbJQnV@em0!(a|HrCУcᅽI.'A[͑LZ|[IXn޹ܨ*?9NsQc_/<)W_IDVv|%ҹch|[ V|: ,6rsm')g4~BpZ'd`̘#goUWҽ @$v%k4dcd>H#4RoNUU>Je$`ŝCfnib3Ph5ҦCG0%SoxW=_9_^F`$OR ȟ@]U/[#g)73=MND (#e$t6tdtcE&G2V'S aCx+Kjf!#ka<^m̼d2W([{\7I`{^{~53^rnyy9 m&-|YAn}2$n"1.All6ty[ {CMIܹ1hNX1i9TǕ=z+=z0TL@N~vxt2&52wfӯ"Hn+kw~x6C &s}y6'_rEף:m{,0*++|TUUQUU$IM#%=NH34 ESc@F8q:H`݉Wvl-mJK%ZUQK:`'&C"/][^yFzm$'Ue1A@ Q;ڰN0.eqE,JbW/6 !!Kк9mD`İN2Vذ-;T"b}/(Je-ڂVowdW$G.RRgdg!%UQ[p5Ɍ4(ͷTEoIDWC-fj NRjQB ce8QпzbCa[6]Nxuj:lٿGehdb?-{xw[㙒Hl`hts/d)@.`]p2ss17q*,]V5dmo'v狷B43gmbwaP;rcpUT̾!f_`_ @\u+W2c -b yfsy,z?B{|̾1&?þ^Aai09g[ԙyG賮+f\.kNeӰ -9Q0Y;=XfM(^t?d{ $.-d?`(Ru%Q۷o0*++ lҺmJaT%ǀц]qW<^ JMy++ӺN6UFKIq4MuꄢoH( I upE}YT0EX:z1\HZAcP%`2 䚡īZ~IM k*6n,QUK9XwE/>w$0юKL]O&ck MAj-~b?C,!C= -t<*{`c8/$Fy37yNSz3^F>xCɩ3?VRmK9 )< t _Vv+$grhADzv'g9= egđlηȺ;tYD,{J_NY+5츝``!@E2׋~@51vb| C}]QQC_cuʕ1հxwY+ϊy*7{Sw;j&R[sʙ#Cݺѫ_V%k Vǜ[c ؄L>|†LOw,r½hNG2Q||4[UD‡r%I77:Hom5$ ͅ$k*G7ǟ̵7[|Qt9؋X#TW{H-g_j~NWQe? bpԌј crr^.*£F5ohNVss%2 _t|[=àYX(QOſ2qTNH&:Fq8c8=U+WrFy- \p(S<8t2 q}w[(Ŏ$U& $edRW󐮽k A.)7S/^O%8Q~~3k.O5K'_&wypޱDw${OACd)gvɆVRoB4o@RױXȓhZ8!:#fW7Sw'sΝL"ѷէRn`2? |d UHdx(T2tUEUDP}8><5 )--QSSCYYvM6D R {ⲸIc ES I)@Qs(HyTVbEkݫ 0{ٯDKoXiL/X- Y2Sdddw^L9C&=Yf1M[.hmp᢮,SRScyҁŁO<3d}bL8BTk1O0M4C] /[D.$"2gJݠ ױjQWL͞UCo*jQ~fbL\9tz)6,DT+6C:H," I"K9I,zd[qo~gJ UT~Ē2`5/ŅsF;s`֗?ScΛRL.?7RX@Ǥ2)Q8*^uUkZ./~)qr^f^y˖Qz L:땎żc9>-f`9wԘx^'#}q 'O\.?PD/&ҳS-2,uO!@er_>+9ͪ~=6HDԿhTl0}Ȼ;ww^|>_=`JJJ hő++ITR4ʐ: k EF3mGW}mCs(?+ jkĂZFI$"HK&Lo%+E"&-y]B 4A-d5@Lsc5-&\ .Z;ZPXC2:%;8-QL:b ׫%3\=Dg8[9G[\- $uP4yU/:Y-??Б$;c4 %!"gIew=hCPȠKMW4-lO>Dl0 Y ;XNOlcʛȨӲxKU ^;l~ KV(IN1u4&%J4$`l(Bry\4 Tff dOi%=6ȱ4hAJQw/}Sƕk| FEzn9nzI,(P.Lk!Ёd]ii_{ҵ<}Rsl )>3eGlٍ9T?{;?_0TEmR쒄͠b%٨A!E!DAj7КJɧʔGt)ֽy K3HQqÉch3Bι-n}@mhpWD!  ljtC:bܯE8n2qhGcf׮]ٳ[Fq\-vD 3WnSIg0/:Zmv:M-jsSA!^$lK{ jolE˝dAb0RY)).D#Y)2XǨضִ͞!~QJcĘP! x"ĎZ"^U.ZZa(\$4t255҉9' &W}N8c,W:b&OycVS<0шTUFyo)Gض WQT:RuwUhTCSuB!`0vnD#10!E]EQTtMS39lQjSCsrvE ǽ-l{u[s: H?< /&,ϸ0~ZOVs99Ub7qC?OJGy{u4n9z&"t6!6Tn'??s/k:]dXR6àAw_8?Ftuovr[c.-X|uLj_!ե؈F"xped"v`'Þ9ė:3|[# &#wc,j9;<~[,vDNj6\v=57H2 9btٙ}Yɀ#3sぽX{jҦ<)%*9]n故٧^`gq1~T oau ফ#?|OƴkE+\ ?Dw.(#*7?)39zFuu5wf#99Ŏ`bMr5G]ll0 Z9ً9w:^ġitIdȸ"8ldabFY(Ă݈ވب,JfG"hTuH=Ap+AyVs A@u.(o Ȫ.3L/mIk7`=`԰gv00vD#wV]ҰAW v 0st8ݿ9wHiԁ1ZXpa6 81Ev;IepIdȸD& t%a%a|ʠHeP\H EE@N]j.õo_. 8R :AGl1mkATaT+nO}f0i*jFTr;\B%UCKcFXQϯb>Xftbb,sk:;H{ye( sVoPC5 `5Phr+"+9uUto%)Y $)}QWQ44<:fCX{4XdH12Pe @^ziًol0 9'I6QD<^w`GQ'ҋc'D$qIQdw# IDAT1)I r0c‰3|:'X=$,ߌѓ#ɒ( !;#WX6F]5 45ds3o1afr͍^GaG**E@@ L;z*n1g6v.WI?D^ JJIg~^|W?ŷ]ONse!BL; J͒\NTf&AK&嘾d?O;=Dz@kx^{6mOxcdS'v-tl@S2yم<NDQl -h0"!}BzeϞ=ر0B$%%՗H.ܙ=I+H?)pPQеWA_X]"M&%l::Rk`X!J"}@S̽r#Oq"٦%B+dL(CDIICD}D;[$څc5[{`ZڿG>þ}ؾ};>0Ձ`b%ՃiXhUAT$Z jkz+->@E;& 9x?wMKHۺ&n,\6HjRl6$,LSaiK-.TņE\D*ވXuP~QAģhU c XP!@Q3$Ȩl-1f("N(*P՘[kE݄4%*$.zc/GR8aJ'J8"{wyUҍ52jY!L?Ą Д\l"ltбuM״-n,B@b ,qK)4%Xĺ% >`}bÕ zO?ODJV=&w{VQŭWgg KJ~YTMʤQj6oF7Q+dQ{=躮#`4FY_umNh!ClCupl(tD9)en~\=S<:]|uwG=53*L}n*B$Aqt+y%Xȼ@Kx?G˦ v:Jh~1Gk._%db W W5.']z/S+ ƨqǰSN9\w$W-1pdن!ZC4{ 9esx\lj+v?=A&Υ^XQw3vDԷ/i$uxY'δ|sp%F]IԶmxݧ!h:hnil\1D m![dJMHj>3L /SsǦxo9U ?U%\a9& {(\Q)gAq:9Ő> Տn%`pT>Aߧ"TRUY0eJ<򑏙T&l_fGA%"MQK/y,C#E,XSaE@QKQM@g*JER\nq"]&3E&3pMoX(ZXZ6:-,oZoo.|q.cO0!%|?ލx%yFQ{ ƨN֮s]q$[s(XElY#w`꬏Tk30^LG+ z:9hO# Q.ǢE?jCS%33)󏻌ӲT-FLpV Z.գ=*t2{\җ8;%r>m]/aalڶ,UYK9bΘ6Ȯo5߮t7]zIGE]ǐݏXƒM" kwwjC#?}Vi ,xgx4!Ng_7 'PY֑2s]=~';̀PFqeDMj];ֳ<{ q A;uPAq_]θ2E+~a}$ewcܨX{wSNy+m]5-gwfJk4:Eӎ%V1옍߿_8h=`|>JJJغu+^CEE>͆@4ڐҲ$rLQ0" YlZ!ߍ@́EC]նbQnM$;!펵u"Ve4t,j+Ex/ *hEas7=b]:"y|US4NC,vֻ,8Q6u L 3+| N9-KsE#UDE[ma֩27㯊R\ tU{,!+׊s_-<3%O%Rtk TbAi#SxtQ<ŖGok{*/D |>&9móoPIJNjZ* *AE6?w%=1 H]K(nk&`62&5Ef . b`uWDb筪%={$"t BRkV~0fd%J\bC6[vtO_p쁛_@;\v<ғ|˜(җ:`n(Z^K'Jx_y1hi5]dN=s"H%OswY'| TED#hl~LBAuG`"oJ) \>6F׌ӘhoFʻvb̛/]=uڽ+˲Tе*v_şCIr`\ک 3< fI+̹lt/ӺbeDowTNhG ^m5P$`4Ww[_՜{ѷ Pg3[wANfZ 4;-Z5U! a[Do0>sMwr੝7I|֭_a¹~W/`ڱײ0mRn$ H͊"*,zc_Տf}N?.eK1(#PUQE_-AEFr\9%Æ)>4:'utv^u.fu͋XJ3 }i乭߰LA~v{`DS&'SP$#OMMM=`uV<*^/Ձ`"ew&9;Cc PT \?`O.j\n[d\ooyԁ췰@99Q43;FY:FYE2\1pERuwnQfcʢT-xӈ d6U6'"QbFzuTmEkZ0y[4:N(V@r d$Kɖ(Ҹh=UVG(*%n:T`&# ^J$M~YPlUJJÔ˪aB2hpDG5D]%Eu 5TU%X0h[=Th`!mE^yG O8L D%n'tRםAV/Tʗ^5\q[-UQAl<&Ħ`9F:S_gAftPQi ?]&meD Xx{Nhv ]c݊RjB-ɮ=Af2CR ߱Z9W_޷SԣݬxM<;@P7$8$V =}+"QrrdX]@U{ 0"kyocqI tv-,{7lu0eY&#;߇LŐ)-:#]Ȼ3'leZTN¨m{)/ Z:Cȏ'&\,$/-cv  G.ItC׻夓&ɘXB/z1>0 '߈/j!#Sf#y׾ɴӮ7gS]!쩤&h[Q g[u8 %$ŋChd`ΠNsc9zֱ dK'DMQ4Xe9 dQ[7#Mhfz[buc[q:\wH,&ZwvӒ4zZ^Hr_RLg.6cX(n{Y#i!H(ѴPgRNEbVD|Y$DC{gWYsnok23B!H UT₮kòb_ˮ],XXEEQ@!B d2Lf2ǹS33v™Ws9y|ʗb qlUd%Q-"+S}IqB=h>H A}t9Z ]Q(H4ʽGk@vh 6j-ʃjimA&{K'Q1WXz"ST8 ~A@P _Y$x _z$e#?o7ɇ aQضB IŖ#64i bl^!uՙB26_S%H\4] vPK麸6Nju\\So@-os@Oz2H;9\)Kp |muخNwvsxԺ/0I(X Pʀ ZwP)\ B!IMy X֗E>=`1|3o{R(Dt!m1}bF]8a!xi,LEEDLPW^7w]\l_4Y?o|_=|.cSY夊:VϞç.5?Ij?Qy^QjD+ -l DGoϒD>Xś`+J/"VHpBs)uA@8ضK6 t'\l2R*GY.R,*BJgYʋ&sl[ޟ}&+>.=|t rMxʱlQ@rM' 5n<{JxE0$.׆EhEyT# ,,ld>}kM1h@Ѓ :>#U` LOp;O&,2='X7<9E+c; @BoXcc,:G'T V dx ^G?ӛ:c9uZi"Pbe˗yY>'_-Rɲ~|iH~\O]ő IdAСKWоL@:8j 駷 24cQ?#ʆ/~|{]_L:#0u>]Q?s7|DGV7Vqw{yWꓮsU_ͼg@~1όW$^^Ab v!-C>{wW *K# ZVN]ce [I,^4r|&Dri3\vt!0F_+(:@tS{m WINE.%8sy|lU4Uaر@0at "i M)t+_`&EA(oe IDAT9XYtiUAm9ؚ²<$;6X3O)4kK%.Q `Ų" v,5Y`t}mtWC4ݫ=v͊3:Ҫ*+&fGO 5i$4G0uc1t24p,\5bplr]PuP RC&(/Ը]R|S>R53(7  -T7~Y,h0NrzЇ(!_('vmGjm_JYI਄@*wU<|QpiHj7cV#y1qPP.]y!qTh>aY4>&-VMU>JO“/xjf,7[mgwqσ ?N^hr>O8]9ӯu\n>{&>^͆ z^\o,]4t1+>/LϏsػn|Whnem|pM#OZAuOox}],]D/ Emλ+kyt]ؼy"_w]o|-ŶtuӑՙtBC įi(=pObԒ%I F+N6x~X,Iݗ% ǧ~޻O. q/ϻ$IV`-)J^*{1DDԀ.ƘKQAc## Q|؈J\,. #\,xI)rXt-viEۈz*Z4uw"ҕ6ϻK\G)qVY/kCdL3cqŁZg8pؽޔ⼓)6u:7xc\q җ?K\] T{@V^..RtXd4~9cWɻhŵT615?i;y+6\YlEEBgEM[-_wl+Bſ>gC$~F9gA E~v&77)vsr})ΘY |!Iuc,ZjuZF $^%ǐB !% R.q͋mY?\O=)#t</p 1hV0DI IG.)4GRB{KQ^iI_ӾǢs.@)wJ`\)H4ϣE0N40 ɟXOі,]R/tq$=Hlxg#5|м$.=y5)Üu¬n⟵L2Ɂmx=\"`0H_@SFutC0JC_"_Cʡ\gENoC^N!П4ݺ,}/ Rw9xf9A𨩰??ⓢ4͠=lJ) tt'_o*B|rDXR[}:5 /1j㈣\N g =#EA3\ ɢ/'` "Y.+Ik"IkmM |W4TIO(" oXpabSŁX!Ɨ;wcQAIڇrQ(ƱM,ӤXȓ˦az0ELqJlC!l{l`/&W(p8G4_K 0^+*9lڼ7}|Nѳxa_='7K$1qs60x;qxUd>cb5t]N.vC6yvw/n*V_8z!/٤Ԇ̈cx z?zNKd-o\γ>wO/G>ϛ/'t ZqםQb)ZGM:\#} h5kyCQT"~6d kFM\upKXǸ4<ɢj9օYTšMO1 |e̛Oo$ʳ5g 1tIj ͶXl.oԕ2,iѴY 6J 4Q5o\t ey!D'FAUm#W^{)}|qA::-/IwϜx9PZ_7}FnKf5rQ#@-xR Lߕe2eX0pp9RT4,wZl9Ph8^KMgZX4&suБv0 e^m)cSŋ&ӥ . PDzqO8nc ُL݆!AM‹ /ϿL#^X;-\Hz8o\ȗ.? d*E(\'[)j"B tvtށ ]V 7ęuW@Sбk'ɵE~zqo`.:8KWɦ; dL[!ׁ[ikOq \`ʝ}0CqJYB $| `!C)LU %F-J8ezLE6"=0@j I:$N, !$>P$J4^F4^dh5a|h4B|.֍O:ݲu9oa=\7(c,8.L@nyEL!*cx,_/|vi=lbwsƅ3ir`w3 D,<Aymz%)}h2`iD"~>1qR\~uū+ba0JLS^)՗_Q<ܝڷ .6t“jG 0_w:J7K`alo'\Fua %h:sӮ\HӺyp97G9+8r} hvRsN'ώCfl|o+Yg?ã:hLo`tu짯3%!|AfˆM(-3OXCc0VF(. K7ĭ\p'eCz[YEEVM]y;[]O<&\QK!e2-sә~ԢFB2F*G5."I޺&n}tloQ(ycPaK )vO 7jeH$ɷS#ϱbEh׭}6~"˾Gó9Lo OwIEDBjm`bTԓ4Txq*c-lcu(?fD ǖٖs5 ц>g8r0|6K#W5Sp^ǥ`u:gn9 +|%~Paׁ" 6R4]DpS4e@KK$RK۴,,i;.p>,Zg${m傍y7Tp~][ލ=wKQ?mRҼ}Q=%ԥPcX1,%C $'l 2XRk0nh)IB~7jDŽ#>DBQB1>c1T(kᖤPv X9TTLB!m;H G+k˜D9X@0G 4]CH`SIz$*pK=|\5t]SKl/~H}R Z<nD˘Wd H;\Jd,M?|{8D|;kYPB!L/+z}<chSc}=}g<ΎLk!Xm|Y= !V"QC`%Zbbxiӹ#ټ]Y̕5vu1JjfS^zM.#gak|=CEMʚ+q|D4 /D=Eϳr{dlR yd*])Mp޻+_mO.M&9G;9TGIln<ak/d 䩍$Ӣ'0mkCbhzTh ^,=vd鞏KmfwnG_޴:H5Dt (NNy/{C1N0XZ0|D+K3,f 1h,++õ:dОu֙+P i?hbP,{ \ C(g_F KǒM\Lu|ԄCIՋP&']ۓe1l/UqrF>unfD\:K&l])l<|ks H+zx`ͪ9-{c̲5egq#)S/i ߝ摭9=B ;>DMdUFBze D:͵:3<9TsNCNETL,ܑ gX[ J238;¦ d,I-IsT1[Q,ȤȤ<Tjt*E.,KQ>(xxYJjDt!JB /ӪcK쌦Si>Or|$DFc$h>::B #H,̡˜kWK ~7mm"qb c&gO;luD8[uJRtr ,9{$w޵7ἳ% !r0ၲ࣯+Qqv~kZΩV4w$K>R7=TG?;wXx+̉Z8j)m| 6^VU[7 ݸz!8B.?T:wy_O!qsh`!'0,=])2>^ܱMo^uL –ٱ0uٷT*G,J!4-T?&!Oѳw3wlG3HMo~=`} q=t73QuyT>ĖsϹg.&|6+ ‘0Iݵhr ;»>.b[6=\-X5LJ/X|y5#"/Hǥ߂Es\S64ﲘ_!(ҟҰXsr%5+ikXB{6CgսG/(.ټ0A͹W0&PS4=E=0E$Q qI4(G=wqӑc s*dAq0;bL.Q SLe7&c^g2IOܫgRI!m,ξB6`7M-04 >DW qq@غH]]Lwkh(}6+(hK; $|\Hv-~0a4{ǯuP6,(JT̬@Fc F QUH%@(-,YRZ}d@ e0qqI,2J%Ko7>@0FYB4  MӑD9TRտ)* I,7^9gŏsn\k@&zhA$$n!@nǎLiȀOx |S1ud_z*g'ΌjcKWإfYxQ3鉞ʦ`=( ]2=CZ۝xÍ+|K5\<Ǡ211D4:`S-[WS3I񎽿єIsn_W\Ptv{ nJ=EAc^Y=& PH} {P r"Ă.A7|e+H394R¥ +a󎷿4I(RFKY]|To7i-,ȀCG IDATO/̊Z*)<ŋS}=<,MвYȴŔzܡ=]Fr:~wߣ4GxC𶍄NOK' 'p;|;F$jYveg/cfpVut?l';`-+ΌQsWɌ!DѢ bDwtb͑{zC\&-Ȯ,{jbwm\掭y2c EtyaO}vt{lm9H(`6 waLI<,-רM ʽXȓ˜bb3sQɢ' 5KT \C )=-5Yw{BB]L;w!S=Oz}~摭 <]쾝$3FtGFY4e 7rvI?ze=@ |^L=>;Mn E6m`c668/YݙRt.u ,@M}C XE|_kٻ{,y,ai&ov1#O'vub%* Bxloː oM1/&Xz԰aiĘ\H5RN9 O$+4]IO׽|/sa-6S?^ko g}>I2>?uVV4,?PHhdb"]2\|2[Gū˻"$ɐ Zgf5=XD-G܋/-M 4 u8h4a\w%0tmX/Kвx {o'uTo0pqd ewnU+2DhbX E}h'@= _0\H\9vvtҗ(ᔀ_K={Zы'S3vN;IC  Fgf,f4VT%IdR(m JD"/d (Z"e<6v?hA`ac#GG=GII?޶,e)nd/4uc, >#?Zmҥ1aIm$ 8fT#)U4UEk)H#L0^ۤ{+O M|]'wl/:ң!f/ ͨ"_kgX8{̏ =i *o/~rN_C׼N訑jjC>L 8,=^,JNw%O\ufL g'S_W[X30o5𙚣//~cW%,z+]smmieH"h7 u˙Ubk*#ƘVY0HʵyPEp*iZ|Z_2# hQ QeXb.;سD1Nj^KZ2g,/gc/pc)Evy5@,Y6H0̲`}[tY^!g9Dv0=ؓ'SÅ^f{mLw!E)P/TKNH5"h\\9\ D|b~2p1Uk,k 6Bg&]!P`*E(3$ |ئ;~'(ձBO ik1.CHGP=JFz@Lw6¶lP^Ga)eko-Ȫ4Fv6pky^rGC,"u1I$8 ,\MU ][r_@G8X"F =IZK2dn!C"G裏 Ȓ /e=)pL R C[2C\?_y_g|~%w!m}9яB1;gx5j+q(˥hڔUG@*xFjLky.r!eHY2M4 -HPTeMLYOk.kۛfxLh<x3QH4fsp~Uw_Š}MP_M'ugoφ k0ipngF>}ۨ{% 1BI(8ZJe3UT_.lt ]ҔL[3 d@j WVص{/uͭ\|y iL4SSSUR.U;w-,?xȁ~lL<̡=H6u%F 2!LܕJ*KQ\FM \&z (E%ò(Ӗ .&_͞=;He:v:sCOaa o4$;v٧i\OxvsмʵP_'%T`Ke-اcל =]FmE0{E!f}hg Fc w =`!7N}O߀ozId8^SFƜq+7:MԷ ww '0lj: JbBjØb#B XS?wJ ?}I6l¼0kRT;)KHkMKj--uy[f;5g|R1PtdYr$Y{Wφ۾?&ra{+._` (5 O2xӥ2 ~ ][ 'vmvu7\j=>"RM13pH~SDKDZ!ر[vl* *_X!IC7 B~,~[P_OMo%OGDLbi⬢a:;0(5#T}qKƋ( LЬ<*iTƇًJʘ$3`LVT >*A\#.ӻG,5nѪ3(<-(aK{i:5}6k)pV㡯!8C2gSc?ϳͬU`tv$`)4cxF/5wˆzIu4q'cxXRz$’xP~C/5G['c7w}"! @L襗~IHrg 1^$ФVb NdrǍ;Lc/]Gk|tur{qZ!>?Y?|7_a罙?Y.i󨔋Y, )DZqmױ1I- bDbbp6_p l`!5t@54M?qDlʲNxc㤪mz`.MDA,(jFK41[c$ĮDƮE@TKަr~{ٙ-yy>O0qr}*r4,DOM [áǛ@<7_Zύ/_@"Vv6h7TYшP qY8' _3E]^#8iPfv)_iw&e"ן2_s$Z#ϕ/[ hI†MРQp=pJNGeIhmiFH./80`<; .쀛߾ /I`Y=!~/‰<%y%qHI\=^]Lx%r/1oR2rw, IPմ>9%6S$fQ)8hNM0RpBb`7F¡vuK|vT~rhiUf ځE2iƔI˴u0B.qqie{CfhĦ:D6\WؕHrvƒ(Sp,ېFS'CrdZt0Ip$9)M9A.{'iDZDʢvO؝(G-VMAIBLD"#:*} @@[>Bn`%MLK FQdpj6[J6(eGʦu WXtY򚥑+z+ZbJfg|uܧrx% ~ r3xwi].fos!@g\cfSgDCKv )c˲,LE'%+еLs/*6;4;SL g`Y5uUoׂd3?y oR:5/jwPr1q@.pMfYˇ{TʐITSaqqNb}$ZC[Xa֌b;79^T&v4<ΞAӺB-kRy1*WٺUؓ)R̬ŶaSoe6q.gɨMPЉ_4^>Ft&]`N0<* =L; /wBѰs1r/xbN<cσ~φu,wʹ l(TO.t-۫ʕGhPe ]X=`*1\[!3{m ۻ}=h)H;;31MX: ɔ)d:$SB CoXD4Pe-bΡtW`ܝM,nغ?րxެ>(2aLa>wp9d\Y'$J4XokG,@z3w޿n\I#zos绛Ȝ0+u FDž%di&B t'^3nL<@-lo@t;_XEqc}Fs2vD_Y8^f\:?y,UhrL>D2܋{roL5>~  3yh2pr L]*$["|8=iͬ䒟 ߐPaȴA0:ܹe[[?݅uֹ}K?Fпxc */=$dI`)طV6W0CKAOů~8sCA6%sX!6M5س\;%-#$MČ"@72n6VկPMjQ}.ޱ:|;Y) z|kw}~h..Y.cy~yWΠ~\tu@@pq0ehҜ@spqH8$AsBs &ʑd4P”lI*)&\'GWlْ"ј68m [FvX(M +?N& ēN\So UHDGW:iA*nb ٴݵ":ň<&o`=XO,Ve[c> rʉi l|1Nj_Nb)78<4lP~8 < 2z` p0p^ f 3 lH14 D|bjHYg{"#)ŗ5UPPsl#I]&QYXL% usk`I|Y>Ouu yC2]_Svl":bS&jv#.䙽A,_afrm_*')sCYYv;k{qIeIqAuT2B'N7{7{?z#τvt@47FYǗs(=C7mX]S ²Ȥ'J]ޤ=#){^^`?i*sc;>|cpޯzޯ|kX/È$GSr<a>7!O.-$px&C\~z",^8R GO7v/%q4>sm['NH4-.%Qt>{GY>| >8w'"/p1<}pc6ya6)/ͼr'WQ8ZVG(7\.nUG'n S>QSZT"VT-5W .}<>%83@ N) ;pOjKg &C8_"Q (8Q8sJoNQ^ImA%G8 {ѵ%%Qӻ HůC]gv2iV?2'/iy<]82<\ԭ#9а03#KG 'W֦-$0y:]t2&s t&QV:f LDEŧ^)@lF{8gShIXXۜuL4i2`DdAɑe A="$.\`% UBaj Q]LTY M14v!dH$L7E$>86Xd23#bT,I0(t  vԙ[f1%IlԜf#̘C6xwM'^-Sݝb ۷Jn4@)ɋ$poj :ľb?fcۀJ*6Ȃ Wt̤6x2MOmY~=%CHҾR |0yH\8{G,b@7@A'dEEd$PFڍpdz7}Zdm'O.&]NEkn$!#z屜}xGMFA^.wk<04PQÇeKIId>C¯ʺS)X}S͸1R&Q&03;]x*Pra4p<;72vp狙Ia%)w0;>`sFgCC'HZlÖZv6 q1sT|Mt{YCJs<51׉`]o|ҐYfuqӁNeYRԁ=tM!h[ArΝ)f).sp|3H:pզxb q ~*h%- 'x(73-nXYF2[S4 3,i2\Ce$ .X>ɰsex*Ey/7݂)2#Ϸ8I1So-j!'%:wĸ <[$R))Gu퉃pJYI(3rKREaP2aBQXmOjY0"˟qm %Qr ONimmt&rG8R%>zZVv9/Y.^.|Иe=.W,r‰ R1?ˀtN- OQ}?kWãϩӉjo]5sZ>Yc.]\!=_??pYS>>Bd(Uo{ t=tLDXF׈D7Y?/H߾-\QI{E]@W>3g&* (쓃G̲-M]aNWXnD(#X,Rʸ#8|dEUpY)nO\k=oUlI)5|.ά`{Φgbvq8 T"d)40394/>9?2<0gfJ|-,\ CnQ>P.y^d$KN3\&;/!.r˲ $( q_(#=d+q~7$8Aϲ ,Pù%8ۅlj\9XVo?(jl"\9PQi x~G ?u{Q]0<>NH_?GL֤dmb{x9~+.[W"u 2=9Orssٱc]uEbZ? ]Kl,Ǯ'B $C[Ȣq WatLSj٫pn$,C1ea H&M-{l Kb >$2eJTHrİB5iF%<\E6 I YXd]%XTGGA2 VnH2(3i&D:U^ۄӄ ֚2N˩ I2^}| }UdC^<~ Χ<~\ yAO(u= .ܾ!٥B @q*}| كF&u6fJK)(( f3d۷a&jZj8zt?XHMu Ts W*`֬xR),IA!?0[A7W ;﹋" F#5coNraId:?LrKjk@>QM܉\z[W׳ﱮpg}ʄanSN8]׻0:a( 0֗ >> ?%y֑% [xT>F>SqفĮdWa Wz&W ,iEV&ϬsdAOG'}\~D{"9,N j]M iVi&5<ŸkV%$| W؋ЫwUVsfΫ/342<>'?;LŪFӓ< Vakddqƞv&cIĿz.d^zC^yd{쒿.k/~u"< K XlN>uܤі l)aPw C+ 6nFHzs|+p>g5L:DgG-?[MG/Tp .mP?7,MU 8T4n7_?5d셯On7tYQeDZ`dLd=Rg n &s8C- 2bXt0 ϯLj/ 2iA҂EA \E' I%kR,|.M< Wj60t Xݚy)F1¢e&ے#F8]f64qmHe$`XLjaYbNY8e 3m)]lD&~K` vgHY&żUД00[tVXvfٱ^М 칫Qۆ2M:ԁm"nK!/M Ȅ aLQJaH!U/P6"3 n-u7󱱉PEA q#NYk%::ImN#/ 7S="S xePEp.z.Kn:ݔq9RW:̪]̽Ժ|e<6\=Wh_TPe9@=΂g__N ֎ IUKG컈=k)Neyy!&Z k70Dzp_ =~B4o-Xû[5.7_"3?};+-<<]Ϛ^Fm#H9dzT"prtT-6-ۍ(9|b)OC$х/ef8B]+:C1 .脍ZF4RAڕW)ON:Q2;v n[FWdt0E3xCGqN$uZ" %မ#4dFklĩ .&Cd$Y%,t֣B;$2M:Q:'K(e!1!; r~ ]ZV咓#fz?GanVƤ6X-AK ֤B-v߄7!3hcL˳(1C@}{`ѝ@{1^Ly[~-aW*so۳o$TeU0 U°vKi!M7Ӥ7[TKCVOO ?UL<U9 2yY̰uBg~_{T%nO~Ba̹SK>z7R1j^:fnz iˤeimS"/9h- [n...ʎ?+9ĀtXET *-D"FhKieFRT@%YF8.\nnsrɤ=! GOJX}RnO`9B~Lڇc9i'#Wp…9>,\Yn•}pӹ(΂wbe G sȲDd_PݶǞ>T9~zvVi5e!/${NCP;N't#u8Z),x̹?tYb̓hI$k%2 M2EӯGi᛼<<K .̚y u22 Ѽu+WPx;GߞBjA1}AE<䪫h̙a~>VVm?JIGEUTM? ݉ 40C(( j _da1,|TtQ*Ymq8SJRD7fxbaPR%1v'{Q-"q 0uS+S)xKhfB >OL,6H>`XB`8"2I/-֒5b殀QkZymutFZ;*`N؁Åg9>\\S򏕌wh-?⎻q<U%jlXo W224m֛ 8#VshqJ^%JӶ:҃屻C>z ?但l.a w=oĎT.v!g_M9`~!v|Zq*vvwѧ3;"=ʈG1 Wy`޼t=)ar[y|6'MYGqN^λW'5(whspf*P>V'eɝ>X޲fBPk`a m[܌[i IDATA$S ܂bX`)%La!Ar}Ҝ0NR1tS؏QC8]Zn>7oaug/ !,Z$bQt=8N<^@`(`8pP5؀"MeeL !,tc[5a=__"u~Sgpyُx>lj}huĶ i LHJi.Zwq8gi =}fq:) Nz:c#wr˳.l^z9T1vz/ = L-ũ9gь+%pه(^՞: Z0C'#vWALy.gvHi%]~58*93NX~;y0MWZCNdQ|#f?Au_TeH0M$!(eTi#\t7!`XUXkN9MFIH\DpT-~VAKZ&Y}X6w.}q`wm30#֬fGPe&iˀ躎۳%RDQteZ$*&U:$0 # !X*f .#He,rU aXȆ1ɸHD<a6fV!'amMJA(t VQ70,AkC Whmΰ@INX^\l LISun{ CSl`Q-A` C[ T'`AcaY4tL]ON&I%SvPz>ÅFL2?'[Ȋ(ȲlU u$qŸ"T~Iz:]1x+A ?TpxuTE"P!>u4 d TӲgҭI+/T IX(ADss3( ;ROOXv W#(G [̐J)hR)nru2>d3N]z=%RMdHg&nt0 1i@',Nb"͍6KPGsc=&bVe*.?@ &%a`P|.Usإe j-KV>:d yzt7ϕ:p.XJg9мg7u|Kpqaj[J(>-5`RH]0nw#/޽GÆE5 ǒ$dI7s{RjiTޒӔé/PRUD{n|;Rc%gž+o6,߫HX۹q)>7\s+yhK3p?u)GeS:4w!D{ !:|xhS_Ps{y:QrCXؕ}BIR>&`^m@ii8N4FF1ev6 ,"+7%!i!10LӠH>'ºmIvZޙAn.:_bcΞQ!~p>hyQPxuIAfY T]7Qz$g44Twj2'pwJ'm29> P RY  ]3z="JL6ED3躎$8nN ,N9<nӍp9h9eY#t`($ɀD$dM<' |\#c}lܸ!tP@gP@ٷ@GUŽ|n=X=c:.<>?@`f)JX9ׇBQvm)OVPX؆{~rNw!]ّ*i ,0g_u @nS 77w&ɴ%+} TrșZDpMb@w?W>FWƼ ٧ N#~q\%%Pȳ;aF2,~lܞ`ȸ>V?Ŵ!ۅ#7V4M@M¼tFO %\9"e᯸}~# Sn`s{x:31KCt~4t~ܷh&g_~+#dMcxEl.~v)_%ko&>n e q'/ ?Ma¹] 6yG_bth!E7:;>F?#r}Eoh}cReԄQ:Һe~~>;Z# 6Pi1\.T K IG-!xmlG5MVANi)wpꍴMJåjq҆m9lyV6P ;fF05rGͳ@7n(Ǎɮ000/ T'`(O -$8ŀ I:m@-N [Wu6,uTXWdDڒ̩ 1b&OV%O"vtG01Ӫњ i*/K$?ɧiav;H%2 z h* /f2o7>N"x4gNŤCOT:IBzQ%PA.%f>-oI JuLg V΋14n{GDq YU/ny ]qGDӆM1.YG̡Pj`]GpSy8UKX ײ7sޣɳ w#mMф3o~ 1N:[!r맸|uRMc\m)[3FKHTwICم&~"AW b@ŷRk)هx} 9X,D+gJT%lp0 T ThB#)De X$$I)I\b$H4 !$E  "DH`9ȼNKs#bL_Ȳ$HM6S!P~1Fnn465ő%CeEFJvL1 ;+-&ٸ7z;Pt%!Gp4%YD#a SRxfpOlH~i ?$OX\r!!3,lw[Y_&& nÍXB0~Ï2\(Q202@{CP^$Pf7{"M* DF:;Ģ!I2LJP^TA 'ǒ#e9!I8Y 4 x9$Y㒺 >X }g+zK3zszSڎDHr:9n 4"4w Ii8}0vprYC(/)a VKwS̾nnA_1*s( MoM?1'ptY%9r.e7Y P[0 P20I&q"MCb@vg9.kBhË,k<Y:`-Z_I2.wV4GW|ɥռ^BnD>޲;'KgDz7`4~2yj+ʬlm`뚗xgpђie#FxI{y7g, X]30K0 0Mtv22.`a0]?%A¥ BK hW$%9Ȗub!BZ7c!rdHeEJЈ'L8.ĉN4i44TTJD i;dZJ+L~Q%@.( :ڑ#xw,Td֥l0a`,k_:)EDl"$ʡ?NYQȬ!+zAq3取! ?!94|b<)BTLAx>O uM=}VltR>_OQ\Ԗ͡6uo)O` 1Qu vXKx6)yM}6M seKx݇٨[ xIN!~OnKm1Q'_ y퍷&O!t W=s;?"/aGވ"YrB!_&O:\ !`~qgs1GP98a@"*& { wUK  B–͵@;*$\Ncfu.tX *)'I1bU HiĈ&L(q#L8 .1H+ aXL"ƄנSfضljC7N`/ CVPNӉahH]**;p[WBCfj J8 .;K}+_r8zr֟j. t"9]H"hd;g]f2ͫ&qK:KGJ. I04r8JL.Ȕ)Sq8v#i"-t Ɖ3Rx`) .{r܆) Txu/Ãj(dJ Tt8J ~?uORc3YRCZi­t2A"' %ODa0XT*Ӆ  /*Z$gJ"(.33CVb8^w=]uTR6Z?L$UIH(E !)*F ^Re~u1ǕfLN'l&Oo"}G! )ఓn?'TW)GxHܷz#+bL.NM[`I6澺5v>I8]Qx6b3s@D;,,i/JO6ECe|}3H\S,FLcoF0Rqda]f,]rH$ Vv'(EE basI)IJNuF  -ҤH%J01b.` TtՙCG'EdRĀ[VM:rok[z,;{s{ Lǟ&q{$j\6\0 R׺X?+YQQN^~TN; A TՁ,LTOҡIʔ -AyRND=H9 M.y!g{%RS@.Áӡ"IT<^FYfpHOEEgKyٔ f<\gٓ=˞zVPLE601It ـBBBv~NMJRS$,; KLUJz4iJRm;Vh}GW:]2 ^?ˁ,+HBx}@2,H2䆛nf֭\Epؔv}N \Jx’V9HŝCӛC3/AX_X4IH?14Ԝn%Q:YyGHsgֱ5ip'O]|fT/B8:yOr[ߡ3/B/^;58vCXK,UNɅD oz^p~h.C"`ȴy)d?Pz (  NKv, *$DWWiTd`&}>c XuDLdVyhz#ip#N@d7qQQ.$-BOƤ,r IDATH TH@$Us{y]݌, @7J!EEEp1c&aNA'.TԆ4 # d SZ@sx_{l<Q(zQǒ/JdX s502T]",`BDH@"_]@=I(Q:jS9˻H$L֭+LK5wdIU_q˟w>LGG'K<ˀ-Ȭ-2@1 #d 8?hǤ0%."+j )*aH1~\;cmD/^=a᣺p]EjId{rձ/uT~0s(. sӞ"BN{[M3jiWn-FK]<'9)v^UrԹrH&m]|U0ky<~FyG3X|.Ufہ0pZe"I=šNY 1 S;ayFx = . //o7ZP;550̀ 6mΔUb-{8kv@JHyۃodOfCy! FNj0 Dhi4]L[x(фޫ8Rp^_&uWR)L5ٳgSSS|uP@6>˞|RK1)FT (n@Z"6mN;t%:S8C@N~e&Ya-2E t&MHiI B@2غxXg#RQS`:z"JRoSKJ|*@e^㎭+'N_x}ikӕ7Yt- Y,Zu/=sOIɗB;P*`~q9;zzz& o, Y%fƜ΍S}_#'(^WVpU,=p\ 'L~:f,:ǀF`0x&_X%X̀ I"K&+j/Kk͕VƢY0?B[ ; L8 ݧ!CH> L,YH` @F1}^O!s)a47먭嘹%2N5!/9ӹ/t#7@HKDII ,`ԩձsN$I"''b |`IG)FZJDU ("9h@!B'tAAt!B>X_> $ch=WIchnWB i2~8&Oi01t -Y_ΖB)+ovt!D̷dzauM3ei5ؒw0t C6?|8׷{:_9اSBM#e&^2Dv(41q򛇎0Ma8eXw\u/FuNo0#qWpO| :"bW0pK=ۖ^~qÇR}lۖ?u9mх=p{ %#pΙ'rCu0>8~\.ʞN 6 :eg-=FAWtXͭb?m5&< Ϻ^JS@%0X LHJlyPPT3C6@OB8/yв 4[X(@KN2%kE Ġa' ) VúВ[j:lsЉƢl0YCrsXяSc@Wy-P9esȬEşY$n[{< BEEgpeI4;;3b { (ىlb_=8Kk9c[ uTu~uIYЃ7% W6k~v3gN YkaҩjnXsdlA;XnJ&Di>@}CWM460m~l3nNgG_ tv 0ٔ$e TׂkP-J%~(t8b UCܙ?{LZPP#:V"uUZ[ε7)#Z9T^Te9pȖ=In"tRxīB쭥ύ<,aԭ㹧`wHK/+odm 8~bJOrы>~.|9Pzx(it88xt1 ]\C#(3Mvhl!ģx:aU,s}>juC?j@x8 !p$pHDԎNM@ѻ@M52*잊b^>gⓗo|;^`\ h=d~]79s<_O!U- ,,n\O~;i*efIb+e 14H'3L#靛%KN2'WaHN Úx>HQGeU5O!p/+= *I'-KM#xUs9R~!RNr(#\.dTbWJ'2% :9tTGɫ9~&; _CyDŽϭA^N&y +9Ί˃L –r"ʪo_m5S&)o|k]^@9据K'CWYq]!߻so/O漣C/"Wo?MYy>/U}_? L#1kd]!iju>x ND@D?'E?{ah ){/I$Z~CwɶmhRTRHha}x+6fUc:O1 ս (eStq`VǷ6 I1,l`2ෟÄC((ȊY,Cˡ*>h 5ë(|GCTRChi3pp904Tr!8 0~:-ەl3 2|mm;o@fL~ Xɴ(ŀgvϮ{xֳi@N楲yB9,xK(,, q㣷sxkPOI#F5,:}!ɛoD,aȲʥXfkTwܷ!CЇ7P@yt EUqz2CEuȖl #$dɂnb\c15^RdDr= vsϞXmv C`d)YXdI{F`bnӱ]n\VphN^H>ӊ|ĩ @Ia-pVW hЪ2,7o͔er5&~=dO)h5 %G]OUcWn@[ L\(B7RǡqEXIkkBo57ݫq!yYtC8+r\5Ͽ·|?[ @{6댨B:2qDA\+ӠO31Dž%839z|Πe?@}$Qʖ0;Xp\Ȳ" !pHgm IcS#+ë Sʰi$֧̘1lqW@}MSPWzoNhS2+dSƉ$a12O-+ ,~Oɩ_@K4PD 'o(``d8P ü0o<$K$~fwF!ge aXDNA$(RVYDcQT 02Akܒ)'5ح}gy|1}uW}̀'1LRaMyfRR/|=O><Qݽn}**+Tp*c1[G"PX;m (ss -!+Z5-.lxkoPvP{bFKI Uze% =k}bjڧ,O "/q KH|L9Dh'ͭ➻Ox¹b_MڭE<|щV1?o& r qJ9)-pw MYcg&VB5dʬEϏP=@C+܌-0'Er/ʶ9ccygC cn|bk:jwF}l)23B}nF ?s"_\v9wA>]eX``YT*͊+Y1j ގć6Mncx,9vl^~yZs~9Vڊ'yǹ\fe,dN^{ow77Jb]r`8-jmdF蚆a(N:v)pI0u2|0&oߺB 80d 8(p+*1X?A| vO$ J0?!QMKgJAE/z(Y"a3  Ē:/pf&~q`5:!8c7d(3{YydgC@Zб]%Ъ4[ش1c?KwngPRXgYk^,:&d ô lv 5"4 ]I%\f1)aX\O_:sھaڅ;b. 5'`>[{+3~v4w,fBɩ`b&93X\gsu?cmW!h?[N:`]f:ΎI}2L"a(i]/JmZ#m,m&.,c⌱<"뀙A1YX;-q!xYn RJBm++ָ0S\ge!^;#N:OC:{tv3VaOƓk~"Jr{d±: G$$‰-v5?Ï>dhJ7iݻoO.cêy{ZrvFHo#i -@7L^&f) 2P70.;x+xZ$$+SItM .g6|̅#OKGj3M4-mՔ"Ji4-mHT=>K.Z߫䱙lä,S! ' =բ`.F jf{T0~0* Rw(HdHBFU4MǴ3Dv r14c ޗ>_f/]ۈ@P !̸L[2c$Q̫[W1*jqFQC }7ųNe{5&w|m%xpyASi͆Uk]p n4{/.|KzQȬcv 6(gmq+Db:]k _Nks[.U ?wjMfNVS(Z?{~v0N.>Ũ=T0r[Osʒ(/+'FYqOX <>N9vIy 0^C%w}7*C/?8;3>ًX,ܾ|2`Әͼ*fdqMH>Yx#2O8~6j$d @?\_2}rx揿bg .V[>ZwF)u+Y-t~X~Ao߲yg.Qɦ-[bi:i>#i㑝G-wg0tNnF{Ŷ~1 +#wݤ&MMfREiQh:a=bXڰI i$7NwU2 :_Z^`sSa&:U7^ cc;iYm./p Tcա``})ldZ˱փvv.BҤ Nb0T2X FTE$P=^\9y8㹢 l7.`&:{"H3z_ucS3 - NJK(pf XVoZq35jdt!IðBmYu0Hƣēڀ!!<6K0^d]t_1RJ#F,>]"lcMs/ⶼy KCJ݈39ۯ>~* 97s<ὁS{=,.|{ V9+MWRQ^cL$lRt>3;QgeDhp_g{c(mk ݍ'ђ ,)ټG}~mXkmqaFHn<5gq1zbKN9\w|FmØygRCbV~Fʎ4k*8=sl'[`)s}Gp7ǕE\e-[cf /Nښ(KWY8u,/< HHm4P"Hl|_=LDaߕ8C^3f~#| si_!q]]UA|v Rx3Av3[oh { Bjʦ&)ZJ'&TZJI=C\G8z\(u/F*|5'Vcu IDATZ.oLoڶcU3?%5:|Vcuʻ\4KD<h#l`LLH1h4fՉ]$SrYar',1^V>@,wHxA%mkׅzfF@'M:# ؉ϰ!&JR4tD ՉCUTr$ǃ/'BVd:s78`boW$q >tݠn[=k[.0j>OI$E (N#㼲MӴS7n,9 ! z*!$\^f"LRR4iX6Ob*g8GZse?fuoq9&F0-'tUgfȲȢDZ^f KY.9Gz3 K`b=\w,AGrJ ﳹ02. K^;y%GEG_G=f:,>/,:f>O8zi }6 W @bn5=E:|UK1 D{px zJGB6"D|s4\*/PTuP7ϭ<3L[oh`&g 17ʇVeC3ISɝ \H %\s/Ul"% 9r $[eS\3]yWu?zΙCу?IF~]BN~ĭvTstH5D;j**w3M|zjaUAW<;|Lc)LK]Ӯ)6>q%i&઩|7غ3~' Ñ"i}MrgJ4XCM~თ_>Y8)W!_Hmen66}&Il1P*zjP4&F %*Ә-iCw%24Sf1j'Can9Fׅm')s3rWz_ mZ$~r>-tMGVY I-Tx|8]l( 2bٓ=Y.3ShVPdͰ$<I/Cj7v]4iimhn`H!OCBKДn6y;mϊi5\RZZ2`'ٱ}Frbݚ+֧8N!!b|Y|Ƌo9{2o2ol~\}?|ߕ/#?dh|&&Uθ* h6hĒjO @VILF0Vi@ _͞mLq+9(REܜY9X|Y'geju͘:Ç -&@ײtd} <*?Ȁ|F2wֱ;J )wȿbvpNl]om9AF7!dݪf:#3{vwF5s#\ Fm(| ~5Cv F%\bnf:f&M0 v5vukYD]Wo@qEn} ; ta%a>Ɉ N"Ux.BY !j^)#0rFD0̯P9j[~i&}.3bW`)䳿ǯ? xqⴎ58q3}E:WPv? ,Gf~uXĎ&tE]*J[L: 4p*y. IJ7zE*fՆUp"^Vm85ZJC뤙ʹ+h. l]{ߥXTUO6ɽ-gpO#Leo^}W\9I4&^# _^;a{_;.h)‚}RF~]eS!w3rC NpXZg`5O[I^gHWC^&&5M]ksC2rqT !u'Dzc~{@vX^{4MAVT8dʦph<le[];۶%e{{ѵf;Wk`fY%$Ͼ.G, kU>3#i6 c-'0,CۿfN'TeCk}'%N"C>;TWsǶhs.DH|{+]yG6VV0wb5fU'0lh:t@R%$SB-NcF'S7g19SNzUWgx2fL)wCR KWBӲNxPxÇ7ֱ3bZ@e '2\JI!P詧oMeIwiZ2FiBΓ 8x%-JO.?éZl$?{gUާ23͌ZlE,W܍ Ő GPB^>!/! Bl1c㎌,[VѴNϹsg4,ͺ;{sY߽w}Ų,j*a:zz(\mfIJV@fZ^8k ## :-zB-SBm$ RKCeN{ Tz~&~kyc ͷQ"晾{Kc\Ώq?ɿ 4kQ~+OA4;~Ia;T~)n\{2_XQ}b@`kz;03Dz)1' !F%__]̌ j3mKL\$!Z4jb_mY1n5B45_2;8&ҒA77"k⪖qnDh_1""xiYtY oQ(*2]Ȟ,l}t_9%BP~'~t^tZ/dR }wa]noz&|L|R|T7 nNkloK8w[7me^L0\'}\[sPOW: q*E2>~"V)Ӕ T@Ap@*SHrluhIHzj֨NQEVBzFNǦ=J$1L)ͼfqq@P,\v\l1W !R"dF \d@FBIO[Nf lTŪK4T\acK˜rb={OP[w: :)\ Y&=7jܿUC)ZQ~S M2 e*T*+0Z9T;Xw5/wsmtFJ2bS煡KZmu:8=d~MRX?.۷K\]0js mG}9 j ![Abp!j#"Ġ5y>BbRR[v,P,3e,t,#!>ˑL ֨)N졧b*b/b x썇jAK4'_Ʋi[}@`^(s?'MƈbN 󚗿:kR?k޴^zP)|jE^秅&%mEui#SuBeeQ;>s<8^ (O+K~yp؎cXm;9li_N6OtJk<v{qх1wliV)b2ZSc-O`ɓF[XH(pygsӗ?E#]|x34-o_*R)ݼooCXlK7\r1t@__Jb]ΝC;er;vSOA 8 `"EH̿wb )ת9 \)ܘ5|'I͓N .(¶m|zA|iɴIB e 2F  X jD(BR רҠAHH5N)i> ɘA6FU@+M9><څҾRt D6B\(٫q2oL[K,@XW :'QA7 e1Tk][">հj31##7 zhoo@yP&BkPKIpWw EaZ )|1{!, UBk߹u)<*u_r=뚙IӨHߓ#@)і]i6ʔ)R@ C PHd2w.q},iCآ3@Q(ĩ @"%0*j/9~eLL`"m*4E&;YhM[}sS1S1Gz !9P'6,r|bofo3˴75B-SE<)P4h ԨQBF"Zb" qiDՃ 6<۫лh]hx |OlMXt\ueƇ$bz{3%,,?lz,#|dvp>kXm[{XV oA4'N~M<|G0RM)a͟3>ÛJ 7FEdH[ ,#z A<pJqXbE?ef ;T 0 q]id=*)%".qHX(@m&hk^O|~Faػ7G ;6Iתxω[Wnεl{ Nm_=˺)9@ IӔ8 MI* (6+ \Pm׿],#:vDP@N@r,{).>buӰ  wS$ȵ9/tsWp'db}8P[8N:Ǵ7(4=o$tb:"QTŦD"ݾykܘ(R&D3NShHI H(lШרWjUj $2ź( I3%v\\? ()Je6;gP(Q(B&bƐ¯zW7w?W}tFe5WO#Y4oŎ,ͽϾH=Rі)%i y 97fBUoڟmSXzQ#¬oɒxeדQIܹ+kj/VI1{Cם ]z)RnOXX 35\)H4[ұ 4ABgC-Dƽ Ę\.!!!uQ&kTeA9Ȋ \>B\1mL1jJDZ^3 6ZԴyAPjBDqZݽQ( EJiDn~ c˧?E;_C!: Q*F ޢ]hrnfptxb*(|!O&Zk8ahhA4T*1}t uP,m<$ZVisWf;s`#i\AĿe?)0/;<0?x7%)Pw U@,&B4=Mwҵ$ZPh/"tB;*JUЋKiBf ܺ:ȋQ8 )o^i4(K$T'y'f9qC=N~}~T(-.1^N0Ձq 1uz,DcFiӒH 9H4d)WHdj|=E"F0͟+TlzR6V)%{+νe+GT3~rя>t6X0~HmBa٣,m6vOk-XS2S1Gytttm6$R-[̞3fG7c \7t5z8'ś'O>yc xq @\ L ` iYyo'}Ȭ:uf]Kpdg`̅h:CUŪsBy=ɭlXpV)$퐪}}'sZ{K-E ܶjeAL|F,n:;;9cqRѹ.DhTlN"&! 0`T$ 5Y&kMI\j|5"3JGHȩPaCDuMS:с@4cySZgIGR${_SOkΟ}KG>L^)p(\Ii6 t}H4].f2;S1Ga /ߖ>F*~W ,ƛU@ p:Vϯ𬽞䞈f=ڶ0d(r\u#̖ܮ2;6<Eݬ<Ɯs+´T 9F͉miɚ T6ݿAh(~ғU3W/o׼_w|\vy ɿ/ڳx^Wk[=^IJlA)m2}/̞5g7[8:&q-A#w>oʥ4۸&lՈ\vo9Q=jrR& cx~v_+s^}ݫ'0KG[}J^~|W?}">/b퓛ٱ'7+q tJ52@6wb0 3b\։+=œ3_[*.>KN|-W_v:l~aj#+ Ӻhs%͕{+W]mHFfIӔ}} |n'qrG3If`KA=/iؗP[MV/)/=n-XyjY5lIgpͫ/aQ|ǒOwzz/|_Sf!-fi2'vyhFF{4]w3$_4^$R PR+$i{ey)i&eG,e/hM1ӂu8nchh![nhaEQjk⦚CA|ÔRbYVTrpq] 4Wwy}8h*b*U8uʰ$OQ-f80!2-*"ŝ6Fd<lN 2~ |/mwAcO5'Mn4ߨiQs*2X)2yo(6FC)Ml6{_>}ݼĵO64.x'ߺVI&@(anNXZK3 z G8H!`͜ZM)I 39zh4AQ$iJ{Db= !Zb @Q2J† T@ E%(.(ҵX_ (u`槸W/rJqz,5'ΝKRʚ 3sv^~dg__nT=~8 ~z Z0'ҐJ%-4Wn{ܘ&lh:*M3~qdDDY[P |}@ʔ9-Xc~E ۿjNC|??+.z/?{\0ij~;x-'9/0sߛw͟ի,^}vg|sgM i& !W i`Ĩ0Mb_(sH7t>6:Mp,\|>'*ֹyڻ071|hR/MXӑk'=k,s"dmem}XZlnh9ҪPcIT^7h2 ڱcG=@KbNDM@ m mV@Z+?G(fGT#g88GAiFU}t{=V@Ⱦ Ս?_{ba6,}cff_"諍݉s?;wH-/Y$^̽=Κ9 X:ae;Y3:hLe?4BfVk~:vO}5( XR\?,}4=RT6ݩylR#JTp>Џf1? EJ) CQkRM+ ^OZ-j}&XD 4vDyuhjn؉+qdւŧ1=Sʯ@ObO&kp`MT>|D2vG8vbŊGDU@ѬAp@{v@ ;9 4(R4Q\AJJ9ZC04:١8xy^*wVsX;,lۢ6ЩFiS *E<S*%Ҙ VCbŽl+ ncöy'qJb=\t+Y1k.8D:짤3 mcZB 8&@^&/(6ieY8q_n ˶"Rli٪*G_fv#xc$ߑ Hїlc`M6'1N%W$JS^{5"ל:d\q&q ;7sq=Y[7`Z[6,sRi}+ V@ÀCǩ{9E3uH#8Dk!A} 0@ <=lq+;϶@h6?WsFC tOt~_;T=>uc@3_KG 뉢4MwqzA6o<)`4m.=]PP jFۘ 9{g %@ moZ1, ie|jVV̝rr$Q@Y#ep۶+ ި1׹yܼaeC02*n-0A X(Qp'y !sslߝᇟcZ ;1Rd2<@`tDgU6!rM 8np1n<93)̿ ok߳u$uϬڕ ̄Ś_ݍ{~-l2E_ ;> wXi:BӏSשtttP(礔jBDmsoSw1/s APC5KVpOƚfSnQ@ ,ifB ii OO\ߢ}V)YsyWd-fމgyZ:(-X ..\\\&d88nnTd:9sQ%9[BڮGBgZ(Җ4Ees$*k(wa{ @$ H2|i?m 1M*ْnevo;CV{3WB!أ礲ŧ$%OS5$O?(9+X9øfO>3ĵo0z*p#7w?^[ƉWO1wCDyT4| W1S5Ia?.jZa֪W,ͫn:xysk؟}Y04>WGsOZ<s#{W"q.ĥ(2wϻV?y-ILj?{)^G XLK+j‘,&lVBvE_Wٰa1 b04=m@eܿrJyL~]اٸU3YO-]LPآkΜJP-]zLTC^p17A"$< m@ӞGvqW>p^{tV=Zgc4M =~f$SI8Ð0l 3w*q<ׅL_1%-ٜѽšĶ-]٬I[+">{NoO8a d [" Z_pӧq)'yնʻX 4Jb>]|Cqz,ξgio}pִ7m!#ٲ}YbT8Z~~?<2TH! ,Gn7r ˾ʷ]މ껃7X,z/XſBJ|y3b{3w!3w{J"cʼBRoHS1٥ucIqkQ1Uw%,k޾gn&§ XMH50U%RR E>oLaZ+_=ShX(fƞ>s(_-䟀7ݙgz 4%,{~t!Ol6s!zgyc=m_'ohu}9[J^)%su]u&igz×"x-Xy˫`S|a(LTٴi1}ߧxΨ V~Xx1o-awu/C 2Xe\%_{t\K[ɋƂ𵏧Z@"?F=һ}~T(m91i qqY- iX>2D2LEQ ¬Ie-PmJH(9"icE m>~3򹙌mgY8˦-a#;x2WC##hq=$Ska-ǸQc}QF"E4o|;_`AIρHa~+ ?Xl9ct3pYi'+0s$D$ʓ[־V@Lm!U!jT+Z4I!|1J5!۶mogÆ \~Xb6O?4=Wfca* S1?fϞwqLRN> ' 7<1@'tuu1|f̘왬$66*C*& H䷱iuQ'q510?eh HDDD kU}r-v2p( Y588X9 ќi< dNҷcߥ\/ez4s^ʆe|O:3w)XYNyiXpmKc2-emTIcEƤQUEZ0[ l3a N>===ZJ=XuǺ{ŒZWɟ #poZ)nʼnXI*PȀ_,`EUti|`ӓ۟?Wj7{1[>: IDATm't@ϕw~;@q|Aq֬Y 7%K|S3gd֭kdǎFݹߖeN:$.]:Ɛ`&4yCЙvrԀDf܇Za"! !H D~ѠA:5jd[sԨѠADRK/*3u9+(J &*hYkC^PyW9 ၇~睃mKcaqA`; aXv$ PNu?2gT,0Q9AV%RvWפnhHA 2OZBD6Ɖ"SD0/;1>p%.Fd{a'q' jt %Q)$)'\."DHY_Ƌ5U le?"\m.mH &ʼ7=oኋ˰ Sz-o|.8ēNJQ =ƈP EoxQ 5QL?ka#Mp QPVhka$1Nk<M$K@ʍO@@df Q7O9Z+<7UBVu()˔%d"vSHfZGu~`MEV8SX~y=>exٳ}fu]y睇Rt>Ә7o۶m+d8JElkG=Mkq*@%5x^7O#hDz֚$1FuZk.|!Qڃ֧rHj6䕚|ֲ`?* ׾sdSTCozKav9f/|{*3yU7͟/n"E$8ML-*IHӘ84-%`)6=r'ɽ 5ڜ no6f:Y#:P^Ʃ筄md,v%iȮ` Kg]xev2[A}f0wPM؋s;TF%&uҠS־SNG6zWXEGG8̙3g x(Y,_o~3|;/>08NTo$IbdJ-|-X`@XOp o;[ma:RR'˗-mT ܦ! `| @cG(K1~}; ǶV@,[}yJ]w=,l!mpyr6g,=muӺr)'[71R ])$װ-;S2JG u&<),z>=f33No˲ĦP\RiI7(!lR9}BtL߄m :&wd,iwWyg-[E޻,wٖ- t qox!&$Z16ƽ[n\eȒv{qff6iUV~ݽ3sL9y~?MQNWVWWsi6u,"DY1%^ i|8˗#% C&JQ"1)qwpJAO k3]4ʒ}fdL!+dzY2Q`K[ژLB\QL]'AW;PG | D48GT⡁ϖ T 4 CUAeM#SӀ;L{w+l./[n3Ǚ:gS6ejbjrIL&Ci-m2WJɎVZ{ڨe <#<Wg+KmHpoON?e%APD)=ވb9-'>j"h1PSSp_c ? 1lVQڴЌ|M 4M0,0XO")*M0Z5,[4tM9f)e~8"I=^;9GQNZ zj.o}S^ZÙ V2( )Qt uw k 乀 fx01+ؤv44tTǑJ{' 9KADFf&z>Z sLR4rZ.3bNZ¡ b CZ1J%L0H@C=F<[2t@`duhIs4aq$JUk&gy|7z#xwm Yn.ם9gMKKtYe\5qhhi22" hHt%T'a|ld* $F>b@nS)ѤnK$掘<2b0"G<<[.+P*Q.nJ()&ea}lL6Gzs8;LpZw,?4ecD[^zi9cmx\Aqoh ,C0ZfN6e)0<|IzvTչj5U+Wxb˙UWaHMӏ xHXNP3cL"рKR/eQN@KZ(REJZIOpB0e l"}qA sc"(9m;ؙ,L''͑6l'er0-41t0cƫ$W *Ga} kaXA\1-(O,PqR@QE>Z&0G>^s.94j*Km:Vr"lךikkmOHUU9~F_wP(/ƫ-K@@.:qM{=?|/g#OA֚-U_\ z/SkpndŬlK['"-a=ob0 ArU1Hٺ]R~N`E~§kNƵq}=>_G?~1X6+g><.h-(~~H4(J~=躆az҉0B>հP=XԇF< ]Fi2gZZZX~=r)%m1m{Z"+=.Є*W%I `(pBQC $*/!,vohÖΊ;*LC_uyz4Lg)˕ea:ֆ&R5NKK*mQ 6nz{ 81CTA Be8 uD"^s/Yh+i$"tHr }e)'rʦl_IL&րd( _}u+0 L( ܂G @mջS,[l }=fpCϲ,lA8ngI mp,i%Zy0⠍-1pH4|) [cRm!xq[އeۇ}?,41@ 6o~ӿ6ߺ:ַ8M002Ep"SMܫK"c6[޾QP8 X)X Y~)2eS?6c m6i+Hm/kŠ$a$*DP"t}WCe Ĥ$Ջ/?~?/-xcζ7L{3#t*fӤrҨx8q HGR)QJ * -tZNc2uәU7\I8$B4?z5̥&qJ~fn"x]G]u zv kgOWs'O_grŒ1$sBMB)gRpƎyQܿ{f| {_gL-a)C"DOlb)lLCCF+B2ز::ȔMپXcc#UUUK!F66>ꓙE cPI"%}GHӼ1EلQ`r0co};o-4cWC%;9PD"Cy_#0 SMT,.n'% ^7U %ab @$EZ%4 ˶qds94HK߅дԑ8Ǡo*" ux4Mu"X:"HDC6 9|d{sfw-'»>yLzJV]' |^~F~8( n {MF\B'nPdku4~D'N DQy.eGF)׽ _E eDkDA uXǼȷCOT߆ 0`"lʦl/N ;MBd2e4Mñ4@,{ٶsL^ًA8ah Bw9,9gDg֒56 yIx̝; &ʑF!'rmy^OWT-Iw10(2UUѵG ôbpf~/"4 C= 躎e;dr9,0Af]Y騞L%DAHX1 Aɋܧ顫^"_~nXo'Mo}-jbG^ j^x1_s\$1mx$Hb@Qw+tOlw@Z<ΰwP1tihi$ht7"ފ{hF4 ^m;s8:3HR_OG6 `&Js-|`u!PLgLGM#}hϳnaWc'7ǩ[+fcْ\7<'ޝ&/gY4_?2h-y}t֧0 (`@n 4AF$EԀ t۠7"SUˌ˙=NCU\,098i|,0jtѓhiW1-,t3jȠhU5h%UƙXKIK1&G!`%7Beܙ)=xG%dNҰT ۶Ǎw"VE8YtJefŗ_LSS~9J{Zg<0TJ!5$9&f*覡aH%hKKZII&`SV\ +t1nqNf!e+S#4Hˤv$R Cض' x('T}S}۶qV\AkLWMO?<Ϯs93f Pk[añCx=f8xX0lPs?"zxy @N@Q^4 y|k- ,g`S\hߣP*Ai d{ik9ڃr6!URhSKfe&g>㙠IP*(8HR +W~GhOeDU7Hj(%D2}gwL)X#Y` Xw|~ xӛ)14 p G93ئZƷﺝb1M"JsoO0&`wfILTN"4)v+)XL)s򽍝ncN0F:P2)9ADF$+*jI0 }|\<#}0diN!A$T1&8Bav~ dHciaqv䡗{A/-sfnő@]Egm7}v}yYgaƸyGkCP Œnd̊9`mZW  +C:3č|-W < < |&^oV Rn h>TקI &u馅 <I6&U3 õ@Νvk>Ǟzڱ 9Kfsdzb 1ľD#̲<\**I!A~)C]i"\1S~'P 9Sj dA8;,*€0㴋8xxG (Tx)9L@un9X*,Ʋ0CcSS\gŅR@G[^96Db((ߵ[lRY/XAt>z# KXd.^c3/r/y->H D!m!%a+[RWSC.!`N ?$è#Ȋ' }o" \ ɂ)1I@,4M~?\^ Ab.SEc2jVcl!Ux"tcWT}Sqt Hcde%#2BPO?NjxL'_&.c抏rE?&ӽ>gŨ胮}t,״wozӛλxmo&u(ǁ~hݑ @D>xix+`Vx1ŎeLŨleh%lJN.SJTzF4z6(TFBAkCC |GZ'>~Z\^XXam[52yFPadT'=BH Qy0 (*sT憛n."j41D_Lj"=+hˏ`2 g"$XںNNȒ$,DW+&qms93) PȃkWs|-bSHwGh6Ϳ;|uEvEG[9iN34i zr~|qۯqȏ "=xdpw .tJ PEKSā {q /s|M7>O7~8lMl3̅_\F[,Qۚߝģ[:x"rH$R7\|7| PσN]M a)Dx81>:"GcYyIE2ErH.yS&dM>[ss3L& 9Gt u\AC^  x$gx㧀LbÁE}@'Q=DOjEh>sTqXHIF<~h#2&v@&2J uȍ d`?u@tEܒ|aȫR)!~z!"‚Dzc0 32!۞FP x%Eko[gp#/rz귵W(ϱ^Mz IW-g ]Cb2}f ϶j?ZʷwK["JB #-u;ŀn>NTap}a(;25)ij]*־aVUGozV[v&;N$ 4] Ǽٳޏ~ n4r5:wTg_2}TU]Jp LٔZZZرcǤ 59m d~vm;!!^ P08TF$<<%Z6 , ڒcҒ&SP . "w| bv\D^HfR=_B=\~v==EoD!:E_ 9 [)i &6U톏sgviKB+T70/ QZ|UQ<[Q AؑAB31Q wDQXD5W/NE~ڞ$,=C25gFX嗡v&dʦl<6c zI$ Fqqimp8d{@"fTG~&cY:E?BH³i6o/`?ɱ'W&M^||;oA>@I$>u 0**ڇOk-_X@9ԦB(LS/{:{dsDaЭ}9ǞpՑ[a LJ&v&J'mz8<8@lc---z뭓L&b- Ev@?Iuu Md2&$Weʔ(foHH(BA|{:烜wlÿ?%ϕW%GxܯwWUPji[.Chԥe؇hʠ'#Y1OEQa@Cچ!3ھ#t0 #ImbWD@kB/S&,]ש{1'YWў(YMDR\Ӵ{-)IŬ_tm`chT>/u& Hc[}^ U|%!w>o|b9d4`CߍfJռfbv`!SsZHFtws=0 0 IEɓWsP*{=sFDsJ'5`䓰dy)5771)^UUEOOBTp lom/ξ>FhOgYuG@=TڈDTbRxC4gw,`~N>F@x9q#sr{'󙏜M|n=ʹeJ p;.9UF,1 4MEr|/eU /sSŽ>428Zۻ2nt[;pW5N #e+Y`tsChy0q=y "%@M @ 4'z򳖏 fz dl 4E箧ql̠ K&#%kOB)A95uR :"d"W]C{c : +}5 @7 "8/E!{er\\*R*( WX\*P.{.axM1 4ck`Y6B7 2:L0CaJRa *H {#Uk2ij@`x xgק&ڔM^[CCuuutttdHEFX`uv"n{a^ko!C 8YHTPcZT |xv 24] bMaHca7]  Х t V>{xgR, P*P.*K*tyRiaZvLu8L'qi3fRa[JoGu4MAʊ`,CQsxVU]*FzA/rl)XrHP }:\y%<WS„S6e{Z'e3Ln[fV5MA;ygj֦O 젍|'ݧ=W-3# SOF#:7ڕ H pZK`%JNE}E! xЂe£BJT@[KckOS"cb:TzKE R55"ϡ:@S FnneBD!e(N0 4:/8ؖN]SZZU!v*UthC[ X|,;}mh3! ?? OoE_cQ&B|B_"D4sEdɒ u- òELRq}KKϫ蘘XX8eq* %2hx饗0.W~ӚO !izc:tV u dRr4oY %a>Ldjzha*YId_;kMȔM̶ٞ{8)qLJ0k 0ǑY*?OPhwAIx\OŅ^>Jص27(G _“5I3oyGC|[;:)X(1KQiX!Xz+(gҪm $,Xɀk:nO9B\Uh$"$@FpVWK狯PkkXG~֮u;:OeKB F(4[Д+nne2VU\g\F#d:Ag"$QG7?/!8C&t<ȏ(l/l(Ӵyxl;g<a_hF;^@cIDL! aЯ\ T&9S2.Ɩ6twCһz5~RD } [qp[9 gkxģܤ?tNv)zs#bO Hb B&3c2EEHpʦl&%4*@'P*y9vjg@&w`z&A!d (PA4zt֏ ^_ wA"wWkqy'c۹M8@8e @g @bM= JYGQe^EUgVӸi]~FdfY"wx#ӎZǚ5G/Wgf/u4]_7F1iNKl!2ol6=,at4]# 6]7|SCSa$^ qn;TS:HDx;]!39s8쳙>} >^" e@2X’ !`;+^ h540? ?6\R&9QX0]am1] R(;=Պ(RtQT9L#Lp24EFyx׶)$ bwhu-h)%#Wz^ቝOw+33W;si7S6eG%Q${2$1ō5ώbnWG$aDEK&"g ]]]EIS>˫OͦW`onQGOyMr։K/b^$/TEA <+(*D[M3KO͌\~"~tW,>2֔w1foZwa9W\tj}u3jk 6nz >fu=KD;{]>JE@9úSNa…lzjO=4] % =z.Vb…!5>j @4 IDATD'D@!&* ,^s aR.mR֊b4 (h,D*"DQJ̠@!J€( YC{.{Rk]DP& MC4la%4ԏC1ƴIÂu(8+k@.>>v_S(˖_F{/EJ]|1v.Va'5eSv0,ajnnTvRiֶH у  J¾XM*eh h=n/}}}: ʪ]H_[/}<K'nrp,YiL\*!J[nynKt+k3gV*+׻Nt@ЄQ+18eDFQCzG6.-}YutOL$ﷃu8$`@c(8 %$^OA]j ,{BFDcw^f(ŽwJG[+"Uecvpe;,'CI!++Mh!NJ*Uʇ+fj[ô5&8kMMm=[VQa=cG,k4l>y^JW Ð0IJ,,edH)yҚ<KJS?u]9)t&577sNV\9- ymcr\_89/ lRPVLHzIT]Vl6;<#\4AHDX3NVp 6x'LE{g36lV4J숷zzzpIyI_K[PyUUKwa RF͠qTJU4Ugf58ūFcƜYxuщ˙U:FBZ)XdlߍK@꺑r%eJɃQR9A,$yK9ceRQT*G42*d Ί>(>h <9=SFfRݗ3"Oa2^pP <<|!DX E\&=_"}-L!#.gc [눢o{fYwΗJJ4T $_ƚYNA)4QDLu]>ŋ3o<{10dΜ9X%\_E]D)}e@m!Lf?SnңO9Buq6ӧ7^ϗ2_9+K֔6m4Yd <l6!i)1 >u7;{{Vg([eDNeBtȽbrqQ]]5U?k{{mQ1]7T8C#c6'iT'CTDmPPMHf=UJ|efwVf&qץ %J) 0t]iռf|PtbUN</e3o.ֆ9 GS6lT*҂m<4662g8ظq#7ofΜ9\pd2 C^~e(s8g>toaqbΜw6R† kOs*P[Y0MxxAb)ךM>I @c T]B?z&v^%c۸m%*~,X`BY/Ca jĀ`,;8 ?wfd*licIPH%;4ƽ[duLU[InjSܙ9==oT}9* rP4Y6(7&fk8m)Жl'2rpy3x$ CI [`{]h D@,&oJjjaU#'3^|&@䵱`pQ.1+u5gTVhgw!i tIDKT{_t [Y3k\ ,FMsȂ>að,4$ ͠E(&8#jMK›Ga/i Diâ |ZQQ9szu]\+W2rH~nɓ_pDolatڍN^x(á̓o'FbQ>C ?Q`PF@##!)i_4dv֭[czp$''s)g^o>S}4p )cȑ*(*>|((1@@T[F'bnPFl@8l)-E51x$+iМnpwh; vwQ#8TA l>0TRM(+Ս'=`[V1oOa~6dh,E;c[EwSj-HNFX{>.wB+ Ǵ^pIٸ_qy/uyL;_IIpdY0X4ԶmlӌUkOmBH_T0 ӹ@CEuyqض :j*B'>Qt/4GKHm3f0cƌwF5V?3vz ,x&]G 8dx!x$ڱUu >Gٴ)4f<9Y`2*HHYWZff&UUU{屧iӦX(6SSSzTƎKee%PKff&mOv2,4 V(PH*S3k;IJ-6BQv6j$*k[:嬮_Cfa&zpRiTar?3+^[dʤ)ݮnߖUۛH _ۘU" d: x@ >K=bBخߜȻ9wz,:{~#m7}ᶙ0]!{eܹ }~ 6)0ȱxJsln&$/hG_atC躁njVj*k;u*-r!6mdMI5\͌utx\XֵXj8Vƶ 4rIIE{H4Lu;bXVj)WNHMM @>ni}xu,ܶAO?  ?!R]c%%  1\&|hZ$qg]k>ؓcj.TBoޥ( iiiZjg;IvvK{wL a]V$Qb[PVt}ef:}K`p#ơƥ~l _uؐ^!e4uǵrzR.S_GVH%!, Ӵ0n @.(0x # B/0))# eB-)X܆Hç<~OOsg8Ə[ɕS"b콑O>_ĪU' ;Y.6|>] iEGh(ؖ%ҙ:i G.kUU<Ӌi(oFwM[jFrJRB,IQ,,sרpԂ(@X&jK'N]1{4 .RB;bWǒkHuyy'xM#pםЯ֚V FX@̜1u*qwv48޻7nUes(:nZ\(ҶYi躾WCmtơ8vT@yvֺwձ6HĥQeXs)vB976NYM(T)Y9b}f=O^^^ ׬c&}6`ٷч &I#Tz>=^I}5h|n1az=Id8m\/b77 ZK" WWDD1Rгw<_: =g#@/4MچH26Yȋv/@#j6)Ƃ_d$ ֖c:*|qBt M CD<*Kj\X@cN3l}4 hўfn;@C`u;=9걻]1 gECi%qяkɿMy[AulـSu2ظci2 ꦝ*Yͪ:(Qlƥpi.-AV;G6oM8!;Ǝ%;#{~o 6ɪsC0$)Zy9Ab0dzWay<BPa ;8Z DoC]vvՎh!HBw9F\>۲*UjJ¥cy*VWn#4Ы jK\J8nsml+ٲx!k B,3 ۄ7RS/<҈l3/H=vn;0~wíL=_Q:jTY)ddfj{\vh.r:~ 4s\@0sM@<MF ".iA3>>$ϼ*7،Qp8TI4#9N&c'6'J67O`L+JonmaYi`[&eR__GUU|g4 L4PloYބ[Xv|#yҭ=7ݎ\<|r KrΗ,sEHdݥq2W*Y,F> ,.Yjಂ].ߗ\3_=#22(? &lj|{%bפ$[ (v$ݙNtwJY`q[#6]4U`FR4E1 [7TX$T.0zQibTFA(`㖍 0d?|?-]yT wP;\&z-!]MN!B36bةӊS,Ǎo/Miui;wS㾫A]>2lAFKEOE0d! !D6F@׍?LOg]q(Ax:`(*:N9fsu"\ gfgm^n7Gdd֭ܲv-K&c]aSPPW0 E)݅@awr3xWK@"9J]cleYmXoceN>@lAԱB~?'Ѵ ꂔs_~ 9%!s813GDP2+sCJSA}<6d}}R-FAPvs~ϞTVƕVq~~>}}z.Rpt: B8QYNHN%v XTACPiU„iEQp4p9`DT뭐BEFQaZB Aȶ}p6x' 9\ei8@UUjhF!tw6 IDATjY^3f\6²C 9"eיi;s/p_ "7,0 ,G~If&p@6ǙsQ|ES)M{4'mk.R;Q9,;jYuY>TY&aΦ \6Q }]pNThqs:'% 6/^/9W7沪rڰSr'l#샘NaDn =z t\™ܵakr.=zPRRW{p8p; }d4; ۢU?T6%#:( gIАdnBF>sa Lx}rqK!Rp߰vn M᧮ۖ<EuY!uE'9JS?eS5,aZd4kFv: Д ramϑ7.!Pm*O-ˢWO}혦X1?K@<Г`=\M#)XU*Jީo0ʫwa' 797xd%edtZkP[RIH#W͛u;Ͱn|o&9ټy^ynP(%[{ټIߣU@ˡ5UF@"D6`(*MRdt (n8S5T-,RdXжU [A8Y28!7LJf""oEKBt(ƙ=^x[g3"KFZɢK+ȴF'Y;9.TAw4;o1!RKF^]|ϖma[z8eXއP4C2 q+H[nHB_uo.{7ۯs}xq:WWSp,RzAh4JrIBi3p UUxI MX3ii2+gO9R5n'kd{G# $-U;vtm!.]T?()]A޽c,uCj[(;lcAr7Çp$5w]UTooFeE~Y+9,iDZp  鄤 =g>I(D7- XFmyE@9UU Բ"ըtu#"cY& z*`T<(s+XY* 6=HԕaG%w.hmͪլX1Hqt1s0osb0ntuu^V̞xkQ099p! `64I4|_W,2BmX>,3$ZM l}'øqU`5U*U^^2NIϔ\0Fd=ٸ!m_6cwsϕ8k)4b(q.o-LO&G=CC`h}zf< &p><K_a@n.L$/(hҶ:kA §i IJjorrrغu^yn;VJ.uw/ѽ< eexZS5t! czǹ?c 0pzH‹3a4k 65Ez :@Ϥ]і]i;%5"/G˙…giq/ :ܞkO ۲K@ӢS UEQP*BiLujᓉVI.%X<ɛ:"6B*"; xXޒղU׹sgQ"&OƩt +Z^|w\x^DI{S[pZn.cSRџ?GM;0SF?Nn<-MFGڱ!&xަpuv;t+Hnu%"MNT/l2:wlnKfdi6yy"!_[ՌKIᐴ=Rz0x 3_GJ'$]|3z,ێjdfr…\YXm⬟~O\EG{Ck6dt?fD]IQj1kR\) ⌡3/o?zt<' RHqYp%-7<)p!ĉ޽Y7r\Vrt nq#ɪʕ8E LA~~jYA ܜ3rsbUd),#C}"hY  Qgd;q`\͏EO)444d˖-!"B6?pR'Jv+1ҹ \Fa d3m4VZAYy9a24B Hnnn>8S9 8hG_Qpks84vƾsl9:_G<2 4ǃ:Z, mL:&ݲ=r*+񍈀7LMlRvwIjs=E'r"($>0ѻOYYX^դi3rrZ:,n= ݟtt64t8wuṷ}dvԩ~}gN<N!t!g6ɽ'˳:&63Ϯ29 O=w#mN;Mzk1$Ջrs3. ĶmnӇϪtJge1-=c,/)gWCpR&jWòe7]|O[~/C Mn͌Wf08{0WLGֶ(%f :&LdxXVWVWtn\f SRȍwV6ܲn=\.-*j/^,`i)췟m읥<`P =M\viESJ$FZZÆ CulFUH:ڥ@b[gĽ- "#n^l,!hu "<!m14"߉ƴ'њ"Z";2/}DlLCevm;2Z|rMll م;]G{اiTcLKR]]|$moT{_.BctbN*nr#Ma9/Om[wvIN3yq:^Y1n"Ay4nߴJ]X_~ 6@j*OrsͭOo'edi޿C{ۧGB^;5fOMꃮfBՆQ-  ̞t'$ = ♲264pXz:r8b;̫ŋ8?Қ&Ӕ[2+2-ޖ-o4̈́N@˖jثw7~o&'2&b)X"z5MK#~m7"@c[hzrk`F>#i r) Šη%&>=F( G:V8Veib$bz4r00L#.]);Msns!; z%GN3w חNߌ5c)O~?sz9d鐗'3΀=Xsز8rKOL}xׯBTBp!~: ~[ݲhȑpmA~r;i}N0/qLf&S;TqA'[:j6P+܁t^ fxR_EB,CJu[>Ι`bAq1vjihoG'N'7}v# 5;v[Tnid.Tnb#b#PrrxcV.] _ JKeUg,- ~}AfJ!ڽ6b풟Sc!K)۶88_8d.ؠAZ>}7mb/OEsQQQH4p۵@vGԝd{ߡ tƲlEݰwit5wѪOJl1ѩ!Id&s5Y YN:|V"]^|'O;uyI޸?Zc<7MRrJ,kWKmg v+G u@z 9`F@`P :J:ZIv YUm IU;ѿMO8g9;뮃+bRRm^kÆ tʪUUFq{/}w7ÒHt"?M(OymF,J %dhc϶mʢ+k~oηKI] νٗ>˃Eu@XoD[бwZ7+Wl=V7ߔ`un<ڶRR(Lq0cmh߳(++_~{ 6Z vzW;󻣪ywr~#BPưR+_A"H= ־f/3"{fG۲ >:OuAgEHD_$۶#q4pi sB V)v5D[c# ݱ oM͌3;",,osR#Jh3\0nO͕F4pu>x$v:`ԡ+m(e KJ$3x-VU%yPr=.V:mچ |{X)EIesyfK&|rD#Xek;wE+t*+r1=+)HII%I leemF'M?UCtvcjHwd=k?Qj _yNH*p۔[Y^.`ӳ䱎)^~YR k tbX˂:/˖-[vj, vPp>vݴIQ?$ i%Nc2G4MlTUvw+U6QPQ{W4XimXŋ/{~CcY"?nC( ?U[ cBX v0HrԯafWp@"ضM ڎփRsbR>fLBGUQ 9Q?ɍ="{}:8T˷.wzoj'ݳφ?$N OG6yY^T=m&χQફ$&77~t7n⊏<"5l`@f1OTWcxxhf|4e^: >zpo9/l68'/w'n{G;i}#&I|"ۣ5ȶˑM>j^Y O9<ڎѶ?z%8U  mOKp^^%DMPЫ͛77& x`KwW=rBvkpJJʨ_CLd`(F}GͯޟDu20EDݧ(ؘƛyظi3wON=LD8j]GtP֛lzZLN>4,#ÕKQVOEEm|hi_r@ v,;kV5^l^ϦUXcgmb=lnVo|''CMTYY&u?rd 00V#)X̲jiaYu6G[ݏN|?/SUNk̙r;ҡ&}%RAZ_x*DI scL1}4,VU[\HE~[s34z=ߤ?~TYZ~ף֪PegK$f F}UxBg j\ W- @NA>c -lwjmO͗SUYv״*Vu,\U;&'cLUEu|Z~sI+Gg4pܣ[F@4;U xGm[avEζ|^9.xxI 8 I))JҢU=u_U[PtTQpfŝ*؆p?@"R̉J@  p9߬qHC}iHJnw aN_e+n4}2Bv,G/X2u*SNjmg<%.isDAQd$dp)ćk8|)9OԂhyMAOM%с(n)l98DJiۼi';5| xz_~嗲GD;\`^r?!+]Uߊ[QKJc~0jDW niNEEՖԕpWw1Fz1Uoh>v6 TgZFS(>Tf'۶f,!d $G*LZP7/%RMi׀XtpͅkI½60TH6⏭#oGB[OpB& IDAT(͉+w =9UfŻ?7 7Wv*MS9~bY11#Q!liGVE!))<|)=HM%5'|="TmC[ H{&s@HdTnz)SIi}`͓BV\|̫-[r89,5 rcTssLcVӠwRMѣe*SU" };݄-ãQgxInYȑlBT9FN%uCʼMb>R;(Re1-MzڭXm-<0\z B1^.eeQ])dFNɪXXɶ%T?>/}}ofQ?Omvy:#մL(1D)/1)-+)mޖU('_j.y$;Stƍk !y ON|R")C>2TYNWW^)%hjkeo~NnYc(v[QNzjjZ7j0KY&kƌq.+ Vs|vN'Fl1B:'euɓ\vsLf&Aaz3lov,y>X}۱,oG8[}I< /[2-|:ڵ6' Um-k6 S,B9oCYe{%pE`hP3ѝiU[NSeeh$ɭ}m 7u\bc?E5Mh?(j6Y}Ŧ|8w6DUܺ- ?1wJ*` ?z9K7hSj~u^xk*r'5_^c;}:'95}%1l)XA x."? |< Z cu"$9kK7ugq7ߡ4?zx{]y?>N;/&})?s0% ^`lQ&'XǶ,,ӒBAQ5Ha"ɦea&z8DCCu:*+*(-+MYb?NT 3D0XG PMl-_EUfvS! U10{ :e)(v|~0axaۖrx楰~w^p9Rr #(Lǐ~Smْ~A z9%7 Byyp)] -B̜jT2_odM՚|8xXPVְyl ۴/䣕ϱn:n75Zӹ+ûS;-'r+!]F5&FV0m+׬d YX ?]GoX_X_G?2,\ĒK>wP޸nOIƂylV pf,{7% EsR3?e{Fᘱg3kNL9r<3:KgN娣d2gk0:|r%eKR [ʖSu%k+:vr`EQpN~,=2`"Z:K_HXI-o/R.6J]f YssPVF$| 6ǃ W޶\wDB_?\Ы,NE!dNm-+w5kZII8I۹hE;UU?q=%Y_Y_{s+؄Vq[y3{C8lDM_σzA% H ccgW]ǶF5R\$bY5[1/0jLjpNN*z^gt)ZJ8zE0ñ[e [ķ-&<OC-Agc DžIȴCùp ,]'CC:Bj]S+|6=fY=< h?BКizdRBXfvz*^o pRO&hT#Lud+] J7&% jT.ӯ,²-,˔YcBLь5CWПA3p@ ULqGϞ=鑗KfFL23LOťvL3ΠZ|_,# & K84 ԅ64?/$=Ų-[8r nߟaxh@Rfa޼ff᳹~36#,C&wC?֝l ȣ7 EOOxbtr'Ew\֢1))v*pm hco^7' ۶9uA 30${pÐ)CQS xO> g@EvK.X=r wc>|~zΞ3;ey~Yuȭdҡv6tHZZYf_:}JDeaYvҺm8mض~(QdM|t8HnBW7/q(---Dx !.!MJJ][z_q)>ok۶i,_VUB᪫\7:ˏO7`0v,)Y=WKQ2_"jDk^})AOC DG |53ƹjjzNa"w[rtn.%َs񄋹~zᅢ|Y\oxV 屝&ן7ioJIkv=]rSR@)% Fy|DH]WkZ 5n2v(ϯz-[8oy}?š_f&MM$k@| k_vbW-'Ȋ*1^6@UU2 Z_؇h14;ȰisܿX6(. _Ow,"REK>k:g;=H +A Gߏp\(`|-E P7:ea)bkA@ Hd$<_e0%p4YֹSz?uDku/s,$\ q AT9_['ԍ'2qe+xO>󟸡](^8?sF0w7~ͫr1VQ&cxp[Gs׷V:ґ{}l@JDؑnݡϛ7ns97"4M>#nvoqF1#9H&gOvC>4K隕͜Jcdz(.vuJ<흈g|xN8jk]Q@冻O]SR`R cL-{[}?p?pYr刖^x|oԐMݒ產p)fνWKRJN+,$Cq۬۰S+"l;=L6,MccӎÊlmʏfSoprrh!X~@<VB-}IKI Q#h2DiU-t _x`45IK@CتFrDCQG%7+5)B ~HKsWO߼8 6V|KpշOapn.boT*5#uP19? zKT'Xq&8-9~ki{C [,55v^^+j qu29_g|گ9{H2-.:l3|?~`F,\oz>> _j@d'v7PO=SOJC,i̛7뮻n?0!Yjyu<6w.ffӧXWFLavNweEK8a͟۝f\{z_{kwE3| ˖ z:~d @M Ӛ O8Y'ϝ:|k? 着a`fU:Vn46~ ߂F{E>ܿ~.xW;A^[h宻\-i769uxCr~gwphS6o,}v#p?nM55ӿqeu">U`\I յIր=52l!vvwwK\\S@7%vLiMX/f2  Z'_Ó! jSbqi*뾼<23T` '^u ?"ėKIQ&z$_/CKx)=,w6,^=¶6O^ʻ'jfβGi-ھ!4x/I7'끍@R&bLkaZ".a9@<ұz5=4> :>ʽBJ'6O: $AwDQ )++#H)ٹs'x^Sl!XūWUQ?|ʁ@`C867ٔxƣ7 rmjwJ7F599pl8)f=[\R[X- 8쨾LM1M|۟ĵFsNw!%6yOGp=~<- ~{XIprde4/ych+y<@pAQ!^};uFoj8[v㍮K/K]𢇩jrgu99ݜ͍SO*EpshСl?@ eY1\ _Ev $!"E= ~Rqj?&Au^?^OЃ/ۇ?ׇ/׋wᐽ%Q=Fw=3r(U!w\pa]!< p]yY&5}D@{]Myb^Ӏ \+بಋSO)лN{n&G'_ܓ_ߗs y@UlܸM6i֭1( cƌAAee%mC--\~{7ͣGse^g2;' ^2UuHG2c+@x)Ëo$p%<.l{y DSŽ[lFna8qKD.(mNW;c9>_O%BuB>yQ qinGIulC'[TqyyUU A1)nunMM?4T n[ǘl'Sz`L.?V p÷P=7@-}RwK&f! ◴KC\ =Oځ˔rdbwLF}&1Sr˩''~jan i^2=d{2x bC 3$''#uB/.&IҠ(>smVZ[)l#J8"IdzO{xL%a%dgB|9!(B]"Q7SaX>ܪ?< bRXoO_OUiq{wqH[wW!sUӝsCEcOBSΜ9>@31g^gb IDAT-[ȑxɂ䦫Liį5hEWi ^kPM^fr4ߛdTZB1+Օ N ܯZsFZԑ*B M(-9jL.ૌsHDdLH<҃ɏÄ]-I>C~a^ɤ=[²̔6eXٺ'<FE*cvU ywɟ yydqqiNǴ;ߒUW1mޭ|NjY@Sz|^G0DZ#|nj袟,zjLs\quSZݠeRf&ݽ?9'MXߙЎ?uo1fL_ K{^a3̐!i+ 撥\v-O9\X/ܺzDZՑO>Gض`rɧ-1x|6h*T͓#~ } W^}ϵ3"ر5%3M7@c#P:r$;V< Gux!{@ HZJ2UUD$~ΡCrErȨC|6|V;$ap8f9Yf1tN9oDAA Pnc;w웎+?+sygP!"\-PEuj|]UQUUU Ek_OokUvTT=r)<ݮVH=7Fܗ䣷[DUŁE@|]s+P[ʝ+p}~)\~M\wk+h'ү^7p~/2) L;BC\#F3ӘyT,]ƟOzϷr3{8Q^TV7'v) -ࢉ1`tUfde1xH.ZĻӧ߀5 wqW(푤:/Zn-:-'y]# Q%R5.&TUK (ϲ+to"DH~Ϟ$ͽ 0ftji)!\wI4'U6c | &\WY8c ߂)G8*6q]ezu(.^>!T:$fd W }Q!p\`JTl|xJ ėʐr>FϟϮLGEeyXQ|=ījQ˚y#0Z^}>ܵ9\?$>x:9&Aw/\%p hkVnz&>n TU~5rd =Ӧz !(+*8a7vy<~=|tf7Gp"xwLw+3B4=g=x5iªGy'WkLonp`FvvoHRY#Ք9bD]1.}m8pW"kwnw3 :rssS@%B*D sJžL|_|ʾ*CU\qRH$p;~)n+DA<=+S[Jc'D W}vGLL#qbKۑvlI7M, `rVu"ut鴯,Ĺۏqٶ׼,ş`X'L2.o@ 0Ki{w Oc $rqhJ'u7I\P?&X6ntQ=L4y GѣIJw7yPiɡ>F@5 =C{ ۑT"&wd6AU~7Fq~J'@HN/$ܒFLs8@cmRn:I:$֩ ; ;q$0oW'"Ȥ'vth1¦(Rw]Ujl񥻮*дRu#ybuyo +x4un_Uc}Sw%i8z0;]&}KI k܀Auunj~LŜ3nvn~#7w D)(p:}ˊMR~=-~[F<^SQUÀԽ#{}aPJ'6.t޸џdK2Z}lg>̒Om'rJx0 /Manu^{MpK!c,M]uu!ɉ}sLyf(TWWշmɚo-iȱ>c|8DNPeBM W1K cb2nӹ{ϑjv\9lKF H-$Iہ tpRq#P'*@S:i- @kj*jQR@X׳HuH'#UBn8QHс̉/_KX'GOi__GcQ@р(+(aW\^dy.^[UG󹢑 \-!t:nlh@]̒<=N^&M"cӄO>q92NWeU8ox+]p&]e$)?-Ox)(f靎[s52+&_Aq0~u޹lqUCawwI{ x>_DB!2nx(l:Zđ(>h} YpHI "-@q cm -S$HdP^an-!ՎINg%2_Ev@r!pdv?iM=n$bq\$ NE5-Y-,~DPeq0MXgǤn-#WU\*YO;/RHgN-NB2y3YQ"͏@9B*NVHivW@{8Q#Eq=,] wį%ۗ9v$ᰛ\|?R$XV/dᶅ圿="# 3;vpNQCb <7lrAono ?)Z%%O- [g?CELBpԫilu/QQH7hדc""y2z;/Gno,H:B^"$EvHf*{;s vR' N/vR'WDzMg@ -' Փ Xw wF; sжn#A>t sv{D;xNӀ.~'鸤YK2KbJR;~\]P\[l Kv[ƈ@ #O9n$ik;qm;@w}^nր׻]yM;)e9e=88;Nx 6Wc%\˖&Kz[ h pZA׭["g0G܉^%x.hi]jРN`>~iFW_ $pt/j~)BAJ\2MT5WQ( Q=hWu`i/ڵ.O$@`\B6 t%%)h$!O.A@mvl“/@;М&In>%L&I:t2@;%avѦ"ucວsu$J9+ c*(LOS;e|HRH["T/>;#XhD OL0Mۏ%:> r ؃ᒎ -7ϼEՋxhC86_qE/i?'F>kv1cxge1ady9b֬^_g0473+'~݃Aש~,w,GٳP|f6W[Ӌ%ן{e ;vpΎ4`6+f;:@tmT'Kȕnnzs6Z VORMfRדlH 릍s$Y>IH MQACD`ŴIN)%); foN'R.R{Z %XH/E;9괛4[| N6d|9ߩc`|7u h@|]wa瓌IMk omz iէ‡WZcu}m.L4#NN.,*)yJ,?9ҧ`szx-l}E_s3lYW:RZZ뎛`Ņ"?a~j,ʲj'29O]lp;x|v]bGTw%:w >aIcF34CKlΛ`P)ӘAUVЈX{z?%G d;h$9<9KV"}_QxCR~n$?H@z}` H:U:@ڨ쨼Q0X_r%R֮ `i0|8S}>Jќӹί{$n sI?!ǵpVAuaa0stV699@S* 总nχ躎K [PQAf'- 3@fdt$!Nv 4uӁΠ^:2&AsGpW*ѐqѳ 𶯁nه7&)Р=xv;i` =Nv`vI[)ӇE/g٧箽^k6z0x&54nw6=A;9I>ܓc@&!iǙO-dk!zt= R ȑDl֯ɲ8?F2TVB4dƜT> nФ٭'^VٯFw9hd i1.‰b~5He"2,2GD]6+B.L}>;Y R)~D-!~BS~m3jHU!&daǾo\~l%R}EEPpDžљ*+ww\^xy1fIHC|0_ ?qpntܟ{84&%$u8vƴ_4;؇$g)..& Q6m1ɕ;!h"Hb7Ur*_ hVdʣmv2177z^uН_sq Xv篶HBbW>x8 F*(d.F4Ff |*:D,A4lƦ 5-QP-U[éRG0vq #VcΡb1*AE(+$G8g ۼ(J rq>}acd?-XksQ2\% Qç2i`8$X3/y0]l`k _5pŰ $korIOx|zLc1`gQY8tH"ɑ)W^*aG%&tǶmr)3dǙ3aTܘzx;_q{xɊރh,477$Я:ƎFk GZcJV$˫"|)\ I7x0mfg ágAu'T<Ælh]c SaJŠJ63x>Dc&u}k^z%G WAM!YAsei3l#+dHɚ&X{Q"'޺ fzUWؘCt8"J.45\zyG($GPWmOM,!f3<,_ӫ,rb|$rXGXvXy#\$N?CAVТ&Cϕ>^z#Lۨ /{XY~QqJWJ?GݦrYL5r/ ]~7r—#(Y*}a+߽( |k5ANأ|A#[۬m0T_A0d~_r/7Kµ=p̉pQGZyZ:UQ;9Ƿ?)Ϭ|39єGsmTVBMk;j:|`dggv@^{Ji!# 98!?BAA6:t < ~QmYnbeü7HbiHȴ~M6/nullR4SU}'JM$NeI=hLKbXi ^5ݼ#BL']W D_;NJE6O0`8׏S:ʧ!zmI48BͤrlPII}C-< ^l<^v@Ħš8 )KDt0P%? [mī86+[=leUsn)GoFuCDp +%}6ɦM"ؚ,}"QǯI֭ 睜ͨVދr,N*WYg0yJw"=| 2Bag!Xi1ar&WKfۼI+`__*C(wkSc9! (dg!a^[) B-lEiyV^0dR>pq} IDATaNyz( (ի[! !ZL1 | _v!lwMt%%+]]&Xҏ]#u R՝.N["pNɥ6ov^zir%eawyas8b=ln5/2j>sp3;iKݿ`髄EӰ,뀼`0Hcc#^T1d{-~kT7{ dmjYX@ lY *4%dIL2"[d6Oşag:j5'ktjmY|lbT8\CڼNe{VSz-o3i5j 4hs@(TY_a$/YWWNp0AmS .#쪷`M\%l%ld8jFP3UN kYa 2yow6!{7ym\|L邀LKK;zꎫl, 5<l0kK@SMtffWɪja~PɆ&ǏhCOTkPUonq%ȘLfDcCu!G icؒb4BEt"$^ݍ,Tpt ]@ 9(Hݟ:ǡQg Ŧ2"QK ٪ DT yMp &Mlbԃ9%Լ!I,H T!S#%'+cbSǑIbMu't؟HZNOH=[,Qj:i)cIVۗO>'km_CNf<:e~/e9) g;&Mpˊ4ΝL z:y@rQej@&Msq!wFxC<gc%>ˌ!3( q3?y'TVskqukYPYe"IZv,{eYhځg!t0 Cߤ尳1BQUT6v|Ŧ66r=68mBMHrdN[֐M/ٰ eS=MN=yɌQ* 4:`i2oIS2@S&kZ'{iإSPP -ޮ[ekFp&~ejŰ\X&z[^j,ee>Tx 'm V8}G^kQgJfTP" ZGQ,!~/s^m&: oV.ieq,?lӬw"S3صUgsQ= &?jjB/>ﶲaLm&|*3Ul7[\wS\ϕh_v 93~p|z"$Pf( D@l,4i!((0"OnAMFU o9|kJtq wXHݤ&#O 5b$2$2q(΃@DŴqt [YUpxA3]N4lyT<_b( jK11uIZ1\0hؠ#ccY#mdx * U:UQ5OrOȽf?7# LB9AXДmMOX"b֕j1nnՎǺDԤv<ђݡ_Hs=IH=NEq谝2ΉÊ]'quMM*42"q|(ZdM<_7+԰;XPX}&3Mxzwlmku)PTY9 4i5 mkXM] mY , aZ ʱ(D[ E4rUB3Nfm6u&R0Oy||?m:\ƢZet ڢK@|*0s%1TMi3B%FTU,[Ƽ*4J=LQ̃AY\M6mykka(lTN(Ket$CDmL6,8H bh?ٰ2BKI T.eD,8ajQ!ðX1*SaQ)o6imC& <_ZD$؆Ek'bX6ư$7daK a[8(L`BfaGz1;t,BY1a=Cp򵨙CR5 @8cْ¢!Qb% E6}̙`P_#Ɵ^K39vٴ輻"]bZim >\fⱙ\~BP)3t^%3jmF \lR5k)gc \HeaWحZsKK~4+4, 5QfLV-ͦH0-h4^0~LwֲBolot(/_kh2-N=n9ylsGw 8nV^u@Sآ/RBtOEvLX㘡ch2 LK] خ_#w-=`9RZ݌HԾ=ϓw^WŽDAY ~\G ڳ _KQ\63$kL >X`v܉455#l KAmnGmіOGclyY>t Pbġ6B}AW7Z vqMCt4F>"؆E8` ?²`6~DhlcgPj0e lp@, I^88-%6%hÐ!~N 6FXhNUh'MM+M1b6k4ˑc}EL,L\-aY!( *ō,\Yc> 3 `&+V`QmZxIژPegȢǣF7`a3c4ZMSC5o3LcpDwríWWqfU&)8(uQIԀExoa=> v~&Xn,>? 7u \QT|#G2ydx jkk1bG@t]wM4AGb [DV!@8kfdP;2HJkv؆Dzywir潵&{!ycKYw"AZ 6 Nce6?gI54h6m4EaX*fpYCa~ASO)MkaFD`:a,9c\+M6nrsI8ad{ɼ GAFBu[_1IPDLɔ1\1DE:CEq$vk5+mUaVᒓr0[ <,M>VfP?64g)ҋb;ئdpyl !n6`F6C輹Zt$l,á^g#5>2zֶ,uo~n`hoMiNMiB9V;mh:Lã cYl.\kR\b$^U!^J ךlX5R7-vH2s-VvN6S-<5i^ӪJUt귶| UI߅&5 &:nV #r$^ r2(̀J ~pKvض=IR9΅sυrMc^ɓ]ߑ%m)<H$1idzLS.Cǒԣ^L᧵EN&!?RX [hh3ٱ48m<ærKL Py+/ Sm*Q0PeOxl^fSŒ-X &ay|+Ä [9F)A,\ϣd K b͆1m"Ph%%Y'+K8C4|1-Z[,qhkxlbX R;LYXJc-:BŏMX4ԷR I~U+ofل 1mԄ4Ѓ Ku>~Ӡf\#a˪- JmRg 0"_ŌXuA6@p:3o[1LI?*&Lmylkv@7,l<%FgMułLu^i?M2G[xvI V{>~ΝҒ,[D^eHu̙XH@5yڿi>@~LIDyvd6ױ#܏ͰmuO;At| Jii)555u @Ob 9aKyU]s{Ӌz$w 1@hL $$_i[#f7eMB $!ll{e˖i+Ǜuƶ,Ysy{T#8V/j۳+׶Osܻ}{yw۾]m;OXgEu<ݼͩ xN7VyK5Щ:;yH2rߌv09~$^i-Y/g@rG~6 ^};uE=L{{+b=3$t#ٕ'ߎQhb|}'7V|*9_hKC>WgMu6*#ܑd?P:]ޑS|e>>/U3y@β E7 gڌ /)))fĝAJI"a+ {ov;7>FHq,ٿ;sMhp 8 (Gϭ4\- @<'PUi&hp" D",Etv&;;qƑE z]3frFKY@&&wn?~_1~2NC$FvOũ|zω+8Wdk:'GZo Pn "q:7V;X;pd$#)>cnYXnV4BFMpx^~?YYYiQRRBuu5`0 N>o<@MM 6l`ǎ|S1/ Y~@Ĺ,{s  E! j!8 F>6J4EQH+pݸ4O 9{94F_4U`6pB)v>T ̹H&%KUm< CARbfd, jg<'rc "X ]בR*N ŨQ|>38:>,?0O=*vۈ np8 . (---t( ٹx]kk#']ץ.vJuxse˖1o<شi۷oG4 5kV/ ))"uѕ @x]ݘTUrBdeeQPPqY!n)7z!y~:?)(({e޼y~s=466ziҼ @Ç HsK {6P2qt'6(qNYKo)n8QQO@:0QtNz4D?PÄU8BXh6q(NN+K tĭ~Yoۇ| Ԏݏ 002ljgFJKKGdr CII @Z[[)**J|455f̘EFL&aňD"a۩D"A[[[z}$!ݘ}>@())Fx*inWӰ][w[/⢅th!0eΖ ֙R5L5U9q:h| r.˷{n֬YñchmmStR̙@}}} 0eOG?QZ&Nmx<\uU랃,RJ,:cΔٍrcJ2,tttyi^@ &UQXX)+ kП8Nill<?na<{yyy#(HbJH>&yv!%8^b ofo{;1k̾^rjeH3N: _v>~CG`hZHo?F̦ N6irh=y%8LkqԬ*U$, &H J*! PHЁ`:2.ASHib!,jXV&ebY TCJٙ%EU1 dæMDqn:彵xh'``({cuT*? @ >6m󗄞*xrKB555?~CYYYYY;:~aLĉHaD8|03f`јּ IDATV6Mt2zEQǤI(+SOrcbqLL].W7.D0$++\***1y^VFv)((`Ν<#tM̚5kXƶ6_LUU;w ? ë&uˡjk Bso U& TG=;ndƌ}8Vۯ'~kBsy)8Jt7+od*RH3ƻ>K_e+X*_W_ _'? < .dժU\r%Ê+Sg+'Naa!UUU0}hq;ln HHH8ё&)ph RQ%;m#zee߻E>Ka-+f[ [[?­'nzVoGusf6mX#i׫'UT_^(I`О'a[C*Ll^ۀ:YNH tt,a%OUHı>49%^xksN|b.Ew_>&*_?D^ģ1|=%UU6DQ#/74P5 =?%%)ؖQw=(LPty~;Tҹ?|n>ε%`$LΈ|uL0M>_HH=AD8NY]ݘR!]Z!`:'D ru;سg>~^z~a{7?vPQE&4DEܰh[ PBEH$z}^=L{OO)i gsrP5!XF(=ˈS/a]ut!& cX톉nJƔQA4nO.B  @# @ea9̀ >#S_Х, gZRDT8מd"5k*i鐮)+DʕiرܘN zj~B?𰋢t"ٶm /2s˗/nD"q^ _qiv.X9998FQ@EEPl̀SCZ f/{@G-Ga%ߺ%3ƀR]x̜G֣_HM`1Kdž/gM_arm8NԐ5I!nS~ )g;ؖ06'!l^G# mb`mI֣?39F`b "aUCS5L,|#mL,),d<],rZ"U^PI*-C5fa $DZfrF X{X$I8FKpE'C!(hqg?qE*2BU1I$TB=;賞 ^a[1X]| =ar$"$T)%Ҳ ;7[`)Nົ TpP4 4A08),aK 됆t{$DTzd;1LjI.xG  SnL==%%%hL qrQWWs&OEJKKϟIJ ;NF?IE{F3w>od\Pħ* niZQg .H(nV[{\z]Oxzs_MMn*6,TGxJ[PN\ nR2q.;M4u'm1\$PZ51x;1`Kܖ dIGWn311 EP(t WYϊ'dɭ@n_K?m~9w&9a7jp .jBQma4i2f(,ˢaJQb!R>Fv~gAW^?7d_ 8tpTUYOnҝ*2c`YY2#> |8HrH3f pCn wdfϞ͛ooͼy󨬬s|q#Gj.9?7g3 SLԌR06m⥗^ 8u$+9w l1cr+xsJAsj^yW]uI8LӜY՘uI A#p4W(}]>0ĉ >V8.̝;srȳB?Ъ(\:%d'DIRy@zUٻw1@ q㩨v1eJue@*N$C#I(Г@QT"=McFqJ Itˆ>9 vdG: @:<>-=߁`]GO ,/ɓ뮻8x ` ё4Muz=܁txqH s˪8fy]7`Q <(8#(999455!;!{x:u*&MJEޞugJuJ'p1cbba!tfut=rc,, B<^/M 65p&|"*"m릢T_w=;ÎŅ˜RbYIݓVz'#rszG| q#:s#eeB!8*:jX!?Zŏn-E[Q=mČ\,OJEYJ/.[όOG)Wʱ@N)nxJf_2+㔕AT^(< &]5~6Gz`L`<{n$| ҵ<ODQ(.6f: _N 1JwuJۓ%D"@$y<() 7 x2unְ exn m|d *i>۷oK/hCg:`MIa YЗ>GOb"FnwC(,PEuՌCm|=t_ | xL?֋;M-2365Fj oFfd.,|xTꕔʻ4tbEϲ=NJ %m~˟c|N~7f|$gd:nr߲w2uLnvW}%QI}v#pʠ+hf_JY ;,̆~.Ρ!+>pmt{oFG{{;-bҤImh@ ӏk4vsCD6̢|K%-PC;URs!Ml{|“GCb*6F`s r\ V%dFnۅp &2xY܋E#A"Q0<ȹ "uWծ@˞BTij< pgSER&!\ϭ.W.XNMf#5H'RD "4m[Y;;!gշXO1&w wr{  Oٿ)*Xv痹cq{׾ů{o?|:+8QŎ̕>*@s!Nt#„J{ gKOC8]li& SGF%>wo6iYD:ѩi8r־C`k0mTlץ.VPPBO\lj$Fj@A9rAiG,NFj KVtn/u]/+*_'S~roɀQw=I?5!\&~)-:B-7YEvTZojE=|+C.kQ#Wc]y=˖{e31)ɎCy>[+`?'kȞ|)sf^'!Huē0SwKt*V"ܗ~)^Zjnl^o`eLҭxsr0+7gdH4$;{GhoHQ­ECDbFըJ&N(}@ --Tv&^ -^X9awYqK7z$Dk1Z&+I)6^&ws9]Qd]E'INnߐ v*i= pπ!4gǙD{RJD̹E{O ϣgvZ#lt |ò,L0MDS8>|= R#;/EOgEqCKZ 7}inV78gSGu:aln+(!ϙ|n\e GULVI Ћ^E1̘M"UJ*h%8&or]18s\\AGC=|挌<0: H$@( ۍrZ%Q-p †lK|sNЁʪXu^=S(/:!)ь yMpFٷr!эnO "'-+Jvٓeʹ^t󞑴UPT6B=LT~r^$|d#< wѩ"Wa~m?k̼js+\5$(,KL"YFBEjwƋ.}^&A0_}Ll',fG?C/gqߦgQi 5ԇm-bԄTL%TN7Zn"1~4S)4:bTy!W__=\=0:8A4as1`U?s\9i8J'q*#-|ssg 3P͕=$ȩlW HG$º)e\E!g tcc;OfnӋu/N  :",K0LD yNIFC$J508H송H8'4atY H΅B|dPQ {%a*f8N/eA>FSN978{PDmo8~ >wgh̨ydcH!0LB- nNj[eZ--[5\CaqNG$0ܡUUx[t x)Taa%W-Ɨ8-"o<}ϴEW&{}/&xq_Qė>L-3e7t ƔswM2ݠ_TS@HD$Dp$N0; M"z-63w_ ٛӖT(^c'#;_5g,Dh@Mh6Z9x~=mKCTof9 {:8cYʼn- a E԰m͍Q\.B(H$-ء?="'<CA Cn*0ӛj̄̀| 5~ q&S{rfw#bw~ COLCPܪJ  Zg^xkΪYdU[{X`S_Ga[/=,P8}7熅E :#%^xnl>ƕvS쥔hy)=v3;kaKK)aw2ݻ>r t/||fc O!ʢڍυ7܋Y 0=̻@=_O,t37j(9|[!@2rx$ۯjz#GJjq<^q K EC+qi;vlAFJZ㏿IŸ_&䖰h>cǒ(nj1]fPx*nk\<6^Ͼ kg_Һ}㣷e;t9"` P.ۢ~ T&vJu&& L* 1 ߁4utBhrFӕAI^^.p2eDTMнv瓩HӔ T 5t#˞g/Bruo+9p(e|\< \U/.S9PU_"(o<(DnV&}Lv3/W4\Nj9ț&)?ų1)90(2}tL 먚ӓJ]'yV jMMC/5x+%H$n 4,y}F;g8,dVzO?1bEA=|KyY6r/ |DxsUv Dg_2\=;B,? o3fFq KӓΦvl>Ȳ;Y6D@ ?|겻 r^\?J5Tz`L9''fIpztEZ-CmԷfetj }s>#G8^@$=R}guM\;E O<#tt-YU.V0cٔ)1rMP7+=g l0T%]5 b` - VRV n$0"--}˃P!^D^!&|^ng\x՘Ƕ~|b?v2HSq9=]3@$phob[7x 5I <#}`IoKkxbwᱧ/܀OH3*P3p^ª 㵗oE*W=_H&w~[+Qӎzaۗ|FXh*™ǐ_6Ǐˡ 4fV-=J 'ᇿ7箿?]d8iҼ%nY:knv7iͿcL&-s0׳crM(BAa!cFt^~\@s9]ϴIe4*`[W/?|1o r3sFN[rrrhooO%lp0* &'lVŠ]b$іfimM.y'T Ư%hk_&+`MLqaiN|eӘQÚWĚZK _,3Jor * (GPr{0$ v҅N\(EQQTO &ǎ9Xu7-ΧfFtH0[ǯ r[y5lޱKn%;ȉ!%=OcC #IJ>L=Ҏp!{^Վ|iQ)ӇQzg ]W=f{P Ж';Xk[7c^c ʦQ7 $P${-˫M-(u 9^6J]-iYz1+ͧca^}f;wW~̜5@YIz6Sؓ;Nr|鳸opo,Kb9QXJZzp8tg4Z?RzVg jeæ]ĜY\r5᷾O~G~2x{䇿{ 1ۉ,[uŴxf ?^aW ZZ@{zfş廏j{pT1#(ԇ$c0+=`(%2M VKӣt,ڷ^wӶiX|Wμ/?utf-|'o:*tR:>>>Lgft`L??2|NJ  SAF%px.}*+ˍͼE/L+ &U|Y9 f"A)N`Ƃl`pV{[ cw,u+?{}6_ww䀸3EVr9辎zK: $L @L̴ P},#ut8+PZ7QgrLj:Ź\<](k8_ XH%ʖA"ᔨD4Xieڙєa$'HE'hnoRt^&Cj?92ѺGR||dǩy.X1eULZXҠy*^ʯWp'Dƨ]Eow3;^[[GC<啼M|ɔӵfW.;_|7\:0i~%cMg(ou %nBuQ>'UR8 Yzg=n/) z ~$j@(0A?{c+<(/>0oGd {Q TTnNT"-”&.ʨY>lΩ1zL-6㟆hQpF,Sw(^?C44MCUU~B EaT$n8@VYYhob7ucj.3.XKgfudÛT0'Lusxaxy0&'Q EBQLOyYY -7RCe%uHJTϥĜM* ?>lJ q*nUE1;ڑDN@atl:)$1 &IK|BOg2W{MEśU=a# t! _?,K)%p\ nRJ2icf?*$p})65(5"2@q$ vDh(vKXdT\UCszQ~;ab[dLO ۩`Zv{>BKhbD>1P@dB(G4C쬋x擷T_&;3r˦Lx,7~j.wp/ma"y9|کLm7_;sץl,+%2ʾ@w،{0L]آzj^wZ%7q4붲?u/)*,<7[ok`˯im`b687vky =Kn'g=峾GگC?z>}#c=N7qcپus@ J9VI w:H*l#&n3V:,3mB7x~loq=TLvU~cɅҁjsK 7[kٶ`kRKNܸ @JDp [ճ /Iv3ݰ&'AI(*g[P>J^|y%k[YzUӪ3WI&QcpKU/j#;5O1ɦk7︅j: .\.܆k;170`,O=HMl:+(yȠ3 BC>3t ɐb\D׺/x~.rݕ>tN;\'nS`ңx|;o>/{+',C?}/N>sg?I;O&t0=-ɶP"mJZ7p_xf6~MrG??ˏW_!jC|wsx67ێniV q ֧[-%`Q n0Zc&&ΐʴζ3ԍ`; y@QɝcAmx߂qߋ)ypWc9$ݛwT.P^U[ءKN7m>'PB`ξ^r!#Ny-Lrŕncv0)nw+!'ˉ!?tWzq)_"6Wǯk4.n@dR܆盶}ѯ_Vz| 䪖m\r o?w7]y)gJQŴr(PQ{qy2BX%B*4ٗ]YI]r\4STR IV!²q!̏@裵B+5n*>^u8Y|P8m1TJ\r9\r9 5BJi4(FqBlL{ 1לNS&/:_{/,aKxW~-=uWN|i.G- |^˒R㎧ /_Yn|X70nu[ @Q'H3t9:`ED% f{/ "u>W^IЋdi>g[F''MM}[og!6 u!f ?:N*~\ZYvn.7X9?#^[S*q9R+&e44N:K:B*J[W?v*i OJPaDqh2ϡţi?6?z^f@/jOMtldNp= H2gu Nfkkbk[OD\iHRJlz%e7Ї#|9Iڼ <3> %FH³7/S14E{'c;RJcsio͢TTQ@縊WmڪT,ݿ~)hWGf`?CTT#:|<㹇X$~rҤxgcsg}L#SZ3ȳw)IZ_fc++B1Zj` `f Yپ"?ZIiJMۤ3)T˄PR)iX~ϗ黎m%c3Ͼ6x?\f+\N2vM?f^_$m_z :x?x}:9}n!O+ |( QIe2-[N1Lab̄tS!3S!bV[Ӫ ]/$ 4m+6lܴp3lo[[JI'%ظ6<.rKG|]|"҄ Ж͕gپ͜Wӽeoל4LTP?N<缳AxήZ2UlK.<g;]S/?;JhT)4!(,[Oq+""cw?ɧnv /B\Dd 7^/5U)LQmD<`gI:mexEJ '&92&P p/?roW\ǫ=( >WUiLU$/r%p뾗Ю5_/|+Mej(+κ9eZ:uX)B-*` x"AѤĴlTTTlG7݃4e5S!GFCBEwK yg ۡ- PH/Wye%qc_NDU"AZ!v0!!BkB!vRJ.Z+8jZ[S">{B]i@:%FMSV@48n䅬D:| _v6u~O nmOJ-*B' @!RH&m)X ?4bv.?9nD)h8UavsGҼO2T *.V"~f{퇤I]#9OEbbܮW(ml'SQ,ںIgq4iJ΄ cŢ>Mۚf6v8wo pL2> [l~J< "qlu,ִQ N V&"BD|[eZ,Úr_^:ӏ'f&+᠖NLB];*]㴫ĻEϻ :LCw㫝!E *l9UJqzOZ qicy ru92\qׁy>QF>c[{~~Ï0a0x3W^t%<_`CWD 1eķ>" IDATn̆.5Wt JT+It6L` IݐXI.PM¯~ΩoV̿~h˼,ߒ&[^n^xk54L:v[[ײOX& <w?-\uPEClk#iAבov52tХ3Il8x lU>S_Q1n'iP[$=0!0 qSYR,N%1X,\?b.1P`t6ttLtaHά?pݮXLDJTԊ 0S&s%b1:fht.͔KjlCaI_ H J&C9{yKpYBmrђyKV+M(\_WJ-J֣jS<4A xflS`Y(Q& Tq* 2ElXV돻+Vܪ; 8uJyf"H]̀Uv#͕P`quTH:ՠTӽj˯/_- _^y_ā{󙿻&_{el[7tLxXEb=/7S:EϦ~v&gu|3| ۺ_}\ b8xK"3b5n[3 ).&(]Ct u6<6zN.d}Z(+\qX+*m!0LIa3q*Tk}XN˲٠*TDPEc3 X̄դB1M_ X\s`"B!Na1XQVQ|S r" -H3,۰P31XXƖCjH Jd3/X;ŷ#yżgFU3)4PXR(#4 e[u*:`Kb B σ9]WP_C!wÈ]+Q,3*N=*>)[$ Q8v-}yuT$A@ ݈JsmS+ B&{N6thP:>yk!ݷC|i#ss,>8xy̟Π/zVv|7_492S\xGGo[M+9c7&5?)΀"E>0KzE2HWJPIq[HiةTEv5)V,,;]KCr(tQ .S !cZ12?1MPWm \- Xq`Q6p'z0f[6&%O>bG{MO(6ԘeB |%ShPhbڵ Iݒ%4P@HJh=ha~0y& lCcʲB8gk cxۈDEBc{^g$MN¹rBWz|DEW/6t GP DUh)rՔVQjDזWmjXoSL{@պ=9~.8={ )<4Kk'$"3OY\zU;o~K'˭q-Ƶ˂2`lY~еwgKȖ -YTx%6cI<0Cg[[ u!4H)e {R*"=|(bEZ40-+I<mةL֊`WZ_ !ň0T؆#m.%b \ nl 2X,P$fԢEo `ڙ4:Rct矹Gv[?H9`hs$os0E;L"W-L FhV|SŏZN< 'Z \ !<>)[iT@BVB!AGN mmj ?V CPBFx 0gTq鶉X3zS H'q^Ð'*ajTyMo}N mVS_f YU6(e/Xm)wrU6&> a5o8oi jPyaB}C02X( l qT0I;3HB (K(RHa4B+숆 Ph@Uq;HCPӴ2lY9 %Kf5W"Ma .C zh( MRN/4E"C8.ZCW?7\\^o w^Ƶ92Jy%iXR`P?}']w>n~+y~HTX |7j#V(ûCse70TLk ƴ \ D X"fj*lLlbb m)MOfC0os=mImB,3pmiqE# ;1r"V-`7N1XیlK&@֩t(K( 8:I _3DQK@#y^zkߏHٸ*>8&dWȨ1j2 yv;⡱S~6Q\KÄQǵkEkLA4Vb$" 8Mtt8% d:Y~cS@zݗ2IZ:RVcj|uss\NǴXw<B aPWTQpZH":ߏS2"I>qZ:Wb;g L$7>c+ZHǣ } x`Auy59~_oRdtW*@#hmsCaʦSNT(ByeHJ)夰4v:KaT rP"P~̼WMbDĥ[[b;m}6hO4ɃbԀE`ИNXTT QҳŸB]Q-&I)QZʪ)E E V,X 4YzԧaE$g+羬HGyzloG p4Ze%K=&0m($; qŧJU* r-A){y?^O2!Z\ V G 8*H ,qs-6LS) f\w~l~-Z+^k<B/wﺇ _ȥ[MLx#aQf?sw ?=ėNސ|7߰6,>Ηn+6 {b#-JO#pa>k+`ŝГ6.)`!-gm܋ps(_ՙewER>M>>ћȮ-y=kS_V+BybEh]e:N*ʐ3J0+fE A(.SeIԴ4ݭ0ء\0 g z[ݷ^U"XRjFX,E/,EÑj}WZ5gMD:^ZDqJPPh>I>'Ko+wy!7]o0nOQѭx x]d BQ76m]:8w&iy+ ~H`*U{>՟X:ex+|[* n1^"aXN*t~Sl'5D6 ?P^Bez!b|.V+ƚEKJq`p/ ڳ I0(X,W1=(/w)LgIBɜk2QJT,F j1癔jѸl@M֠HRT]@_UIj^42sWMSN\T Ӯ*Ye%54X( WQ)ȇYN H;bAZp;簥R Á͝.[i)B?Veڴpab)%cp+PT|}&i)NFttX_~i!R#*.w :ֵ ICr.ϝ>l|AŤW|,V*m+?ϒ6th`ʩvWZn飀4J$Pqpg~6gg+ý6& x<_xF~ĝ!)YA4_<]gQ`+~zIG,.`wAZ*m]7 6wӝL7EV֍$utV9tuuUk_"[N*|׭4ƫe9)T';ƲS48cECEX,(bb>!5-N 1X37EGLtWt| rW\;XMV0”xaZ, qيjQ)k餳6UՂD^̽\,]*%ka*S(ihq4aQ $#yZB \"80ma{((zC.E ?9h90e t*>y2xu)9Oln|>W\fSϸܙW K^@sl\$^m#.~s%wQæ:t0  ~)y}&%?fg5xkG?U#?zT|)W'n%>C,]?m'M7~Nh^7s#dߊ`,6 6dS񹰨 0k7rϬSaqؽw+_B.ڼ^Mڗo9쾦i't!%!hs D H Pv}q@}ջ6lHN!PQD$ W,VmE5:HgttcҕRRE7TnXHb !sӋ! Xtec}pnk"cKV;obQpc8`.egkF(JRբZբFԨuu\wRsE(M܍ > Ud"S%jVB?$R6f%)4 bYwLJn!%@y #N=-SE EEDA ,BdYɎ+X ◮L1Eq"c#Ot h+q5d̔$}ͿۆLa=|@ՔJA9f;bC]3-bԘGԗ9ZṠ|%Dï_ 53!" G0EUh'iMʂ6;1TTCǀ2@:uS >+]I'݄@NFM3Ď=CW\G_xk^f<̓gr\dw>{iY7]fc>c9#C*cϼ4tp=HJl)+S \ˮiKEq嚦˶hh?}c8Ea@{X]ṥJcظ-i۱q;ɶ=0TJbեBi@TrY(*"&BFgcbb Chb Τ]b%MN{Eբm%&nR7ZLjq$xY$^XU- AHܒK9ˌ,MZ*V[\4ㄋfвqL)WkPiHB A r@9*h1 r<}}}::NBr(9H(⡑'ncY`9oI IDATp4u״pV]>udxnǣ.WriU'B8aTMR|\"LCP֮*~gSm9]+]ljm>F/xIڪriD6#?y1+|;<Ɓ|㘁m[Kb^WnȋoU oȒmϐII`e7e7] ن۶RcBadM(t7U=2GJE( vv:C3夰rE(WT ] b\bb)XdMgaS9#V,Z 7ɋlU0SJ>'] *2VRv֒ҳZ |%(Fk1R UtLTd {"pUE5-8p2ҡ~} 4 +MXpd`ϰ;$[$=mt@&\WԞ:aBmE%ZZxkh^16Degh!s>bDF*`@QHiBEaU3B>sd"Wv §BEC%l7o:",):)]kc,/1H"(zSftSl/ ֥O*XKCy3 xn]|>CmlM( o9?[& σ+"XH1!cT%*Cr0L3XE,"T"NjBU쀝݂+w@-N\" pQ1p&r:Tm<7,z&Sn(HZ+DQܽCDD jbPb ^7\84KI(@E$[%${6HvK H$Yh"&&,\)1CG@\ @%SsvF<=^!KXBgitNBXcS||Fs#"ff2\fM,gKy c]- CEDfz! 7qטv !+[y-4萱xQ 923=)ig1 &C3lT@ /@B,aTI);*dMCD +X ='PDcKszm)ܝ c]Xq]q(i.d\k*E dTWTr ĸ- +T ݏk*BB$]vuE*BKXJ |l\LELs/P,:Ŏ.KŞVw6Rt(&XZY7k1ZQ-JsA)i^J!44.kG#5-i\) UX3\2DmYTy7Slhml`gXrƐdcUN$&>^(](-CG02>CJJed}b>%hs ђyb3>ť >=U"?Z 'q@+W- 'G񖫲"3: <;lwo(,Bm#r +|5]O7;X}YMI^:|)ztx@LWF [$#1޾*Bq_H8*.l'8]%HJ͆"XLjl|bD.Q,`1:ᲭvN±`X e&n Jd7.،-Fb`3^q-rI_lm:!&ע(,/A[{Ԥ=2jZ8p4bnZ궁4DRL0)/5d{dװdkSҒ6L|a)kBG<5W{'4 4,n\X3/ MOOPwʲcc10%ghod|[]Ǿi3>O&PIV[P,Fȃ.bH!/l2 gBQn`ry6.N쬹+^Gd&%,,M{ Xl\ X%`Q.-t\ jieb%<`jQk^RzViը1\l&K"W-MLU?(h<φa-eQe 8#Q/v Kv  : NϰB]tgXxt(#GFɎ6;( mm(@Koc/IA5 AִWnl>ᇚ(PD0Rך5h{A #?](G<= k~ A|tg"?⮇ OFzQ7C<YiJclJV`V>mE`>U%Ӿ),+J`ṉ"ebN,2mtc;iL0*Tu[V.Bɫ+`1Uv\ =1Xl7WL2ȴ0OZ,.5峨3qt4S"V-<f`1ZERZKT 3 K( 0e.D_n2M <f62(W#H;'%Q Q& pSpEOLpҳaZӥ"T, 6E$ǁeXZuM-n`tRJ2qp4Lz-Ɨ.h\ajTEW}@k`אdǠdcUIHD&>&"*\SGF1ދ)b^hڐqjT^(@C2?DMNex[;sLq =r' =mi {'&#qu6C |;Ǟav#u'Ӕ'Sn+6 Nx"U/HTF*Nr@WIUVՉY5,ΏZQ8ptV9m{;4D'TQ>NYWy9u~)Xz8ZkOTiE|%] ¸rfRʴ Tĸ]SHBPy;iW X(D,:bE N-I88Q,XR(qa^M(4+dd1TMbh3U2sMY5SgI.W-(D߂%`.VSEX{aIZF5v:ѲOs(3$[%֬vLeEqzor sd H](Y( \h "1wh>=*TЦE<0 d3mm"8!./`<̥g]ϖ JS("ͼ<8ŗ|Mog/%o=8hΰlvx:f:N76? % #,& xhS"Dq]P)IJ l 6'ªuUMSƪLSՊ&h,pMS׫r '8*5g)x _Ðq tc.|Ub&KƲyJ)_{9^bN*B IcҴvj´c-EcBA1_KpXp,M[Jws"#*MiM g,*Ee6)=[Z{&Ӯx5VZ$[ZjDi@=H)Qk[k6s2' .( Gzĸ6rJQ8yS`@ ;%$%]T*n&&^$ET sf0&X^,,"\G!DIwRΒ!Ild^ޥ\]P1~>ZZ0<64uiv.o(,|7󞅀mKBLKXwC@~Wk  )%:Q~ieYyȳ5k%NIij^k %S!ij6-,N^& RǢh*SU 3KƫIS+XUj8٫8'r^^KxcT qxvԏS GWGB~,)tu1dhgj.E߱^I˥yN4/CD&Z'ˑ}#IJgC>5„2>4_O?͚yBlyEy>x)IDVa|ArnlXhaѱAP"bY_MֆcZ`10Y)p]+JґMB'%yVXHӔ5 ELJ5YNXk(x^?PPPmʉ$J̯'u6eftQs]Ё4' #{`"$٬BPq⽨ SӖ8eE$Yd-Ak4m2Հ -Zha!ecU>?ݕJ|l hw+É{:&2|2kC6xrA1Q2aJ97f5G`زž B6i'E 0+ٛܤOJqejh'Sijߖej:8&II֬GS Z`aϘ{_ ql-N/xb SsկAJ@1A3%k^X$k}p2o$r1N3 YTs,6b-\-J(f|뵘zNE%\Z@لP4M ѨS0dќ˶Ƌs`]P 04wEgQ뛺Ywv֔F%}]#TݷMkH2cci8p!#LFyDu:1w'pfyRb=h%BX~>REGuYbEa cwss<~4/yn0$Ǚ!kT+]|v72_?DF`a#>%G1?y8:ײP C^)m:S7ݨx1 ~2'+" F1<'`r`^}IxH@&em)j8||7kMJΥLmiaSZjVfߥpR1G_X+tu~&疁,%k\PG(탊n[|O,0S*i3XTRBe,F{ۨ/s#P$}2b LYlZ(aZe-ѳTCI1Xf-&ӬEex-f- E*5]P5 m$@YɤN'tuĨ[X6FҨl Kom=#m$`/e/X{Q_<;s&^!?3,ZGaLb=d`d.ҬVeɮm *FƩ )uYQe\?|w~ci.-ʷf/W/R 7+ho&,J@mۆsc_{Ξ= +jdlmg,km>d%HmBDܤL-Mo혡 r25w9>(6[c |l/mu e2%- `Fz',pN2N7E\$ҡr Ua!X4F)VF6XzZLU]k4ob;-T6b-LoDG׈MO%Q+&޸Oћlꟓ}^\tj]8.@@d-;sP01&9mYcP2#lQ$ 5ϔPӳ8 {q4]gQss@V(%Qe^88 S!sk`wl9Xp|0b a,E%ב} B<4<l&(j 0 ξ}8GZq(ξ}Qd>>߇z6R[ n5aVeiB H{sh4o? Td[K|P->]%#5x v]ѝtUBRJ݂kĭV)b2ՐDU<4X^FiLX +2(Rhd<^@E+˱zZPq` c1\=H\,RMN IDAT X/)єF5ً4ʅ.`ψ`6Łm5,^FeE.-Q?`ًӓOkˣk󀰂iiacePq8~a^`Uml6n;OgÇ-q(΁m]]DZG! ZcJ%t`y2ic [yঽVѴ05iArEٛJBk2 [[c닗;rs&FE=-̫Gr8S$Z]uE%6!jEi4rZ$9]TfL# SK淋m"#nx@lxtC I q S;\(XZ8(- "CGD:j^L✞T!I4hc)Z)+ތen`$KFб]E*xH fY & #ؔ^nAwpU*fc<]?|5 "V"yFqir64*M{0->*;jŁmVsX0+ ܌/YBDB>=35d&B-{mx/I6ˣ:Ȥ:V=ì0Z8Fkr/zx~H#t}q_vή]ȁd,lloݦ|Tjm1&,uph\P(P.dHŃmSD:F; (AƓ1~'/¾} |2(133Ӣ`mm;Pi|g)Kj##(c:"[兾uP =k/ Jj{*AMV=T=fsur EbkRXk$jXeM #CYYQ` $mIkÊŲ]w34vaovF侧2]e/ ncŝ_5H.Þt~U rG2 dJ-]$F]b#id ;m,Dz( ^^O\e/ {1=\("U5+ir( {~`Pg#UbH@ ۇwEd/̱cxnۆtmhӻMT5jx#<ڶy0I|.)b.̾Lj<8n [y?$+[z/4 q;/# xhLbml=,XM:b- k`-ZgmJT4mY rbSk"UZ5܍Ujbf5 \Ao^0Xv*}ηcWx,F U.EHa#|r;%wxEnx*dX6۳t;6,D^΅.yrkQ=MEǣ,2_SZ(2v{%KĨe/FF,jQQOYB'鞚F!eD_. swEʣ6bE6N9+1zTo/޽d!s%d#s Ύ|`DziucD87nQCR@JvH)q;,k BVq`Xf ۭmkebCf.tغs  @2U&Ey,ojK^وZJ#7l6d=Amk=2hm[^둝$2i ՝ޜj^1yV+O} xz&h[ߒ^╻rߒ! Ch }~w\Dw_Ǖs|:N(.eZFGZHqEihknqGs LِR nM'S'j0f؝X5vOZYԾ= 趱TO%z69*FJ i{ql#9^-kD&ދ;)Tދ70ҷR&u.ƆQqw"s_wݨPhF֚0'N&TD ccijskLPZ)(-.0P&.E*9.o|+__y-C7e}VsTNja+y,9Unz%&f8)֢?-m%^!ljf+AU~A{w˄֜`o c vv 򊇞 rcv{=y讆3Ϸn,w 'G%EJ+Ś]8y|O&r(B=Y9~'98ߺ{ 9TT骦&yt:GhYY Zۺ;F)= 3bž1+9$t^V!X)B-EZ"jf5 XF$5id2'ʣ6b3c2k 9-CӮ CI&ad;rw^!MC1>&lmB2F:7|50X„!0GBHœ4éOcW_ˮc<5Ԃg7Wd2k׉$2 QFJ [e[ŀY@GFb,%o)YxK„3E7rM[I1\ul8M#[\o5J&3jUS 0(W+Dw\qUonyh.V,j^~ua\qfG~ox e)Y0BSGXYXk `dP_ML?G{E1>Q :0ԗb,VbLd >Safy^)C4_˓Ơ@:_ l! B%Ww^06h{Ęd`ۀ ȥJ""! bZ@XAOLXb2a/ff JuE^hF/:Oak9yL9ِNJUa_5?z!DSe! C2̖ }kH(A9KMrUe6uY5.qq2 1g{g$tnF!\X6DTQ]DYE0Q {QC*֓XY{FF`t0ڶґlkETa܉ rG"2]?8Phb>wfi;1ku&o1\B8{בqxK:S!Z"DW8 { 88(l6ŀlm8&cҝI$%'⤌a4~n<4k\{AUF1ȘL_M#<3͟ӗocY 8k?q2uTr%T+1~`EX7Be|:`g'ki{쒚>ŗn.;k]ЫI~abSH-xvXz ɀ.)W5oxu(lSi)MAAH c\yS]l(=Pb> qou@bS ]gfвa:qb14vo4nF)P1uۃY*HE1dYn&,u(A\-.R(f<{?J (l [vdƕ,.u@^C;V",pȈL XI\~铋B]8D ynO{j1.iɒYr&G,gMCY 4K(B4 Da!VmRs)CnɳۉП8=cu_7-qs[Y}]τ?Pmwq3JOē_9QԌWxހ';Fw90$ 2QDA\\'c_x(X/;'nkOfL-OsMs7Уzocj1V-G^%Rz ! '{FlrĨdddҺ"A^!CuKN؋)2MbQAYa:VJ"i: Q&B?o&6m2.;twnࠕ5V7aZ7(g1:-[c 2T*mMiXv(ɓX$Ȇ,UIu])aHbSgf°)j֒gI)®*“\}e%梘DTc p?s|3!1rɧ+|2` &ßuT782D4HZדF%n`dbԚ$^AOAHEDA|9`"jXZދ8^Md/ڰcyskJGnF*6] =kxL;|wb55&+)9z>nz+T_qg|AS&ZYYtj%JtBT)kLڃ/Q_ W6#!fsˑ[!lk&">$MW0.W]q.Wvt_:(r>ͳ{_xd}Kӏ;~\w0i aȩE'4ggXv\o XW Y-& prȉTUTd4}wߎ_ddɿL/dp 8H B* ! E fRi6a\ؐZ< 0 "V<.3RfJ*I~ew3ems\L5χ0+ u9z &7ICД;]^e~k)׹"K!&4Q96 &6g(spo_1ȝ'ji ;IDT>(Si e!84gƀ_[}D"H΋`t@sHwD11&;jƶ$6+q<C$^EVGN5؋3gPStO%Q{\giEcs-r"udGc랕tMTs0h'&p^ግ!6cZ);b0 c%:gT6#ZyyHwssAx<_*E֕g0p6G5tۅ)QRP_*a2y|>Nd`=o6Muߖ}k;oG[5 J9 kq{G, ?x6 F-tӕ]dؐTBmq3&E wlBSz8;=?퐝 /& ϑ?'ɾƍ*vM¯Wuzz_P^(QU~FoY8+D9zd,il\/y8ƞ[P#,L EY ؈Uv{^(lc{4S_ѷ9 /,p>STb&f4gO2>2sl32% 'e 2Ş}=1Ku%>'c5> HjK>߽Ư>c 2υ)cl\mwщ4/lECe{y^A+^Tř)^̠QhZ%EXo]Mȣ$A :n')$c;0%s8۷#{[ZFoZ ] c9a1{rWI}뎍MπTȞ,-!`e%(VRt"Hz<˰劫~T3J׮\2 J0m mm/2r Fj2%߷^~%lSxyffyG{y~"yot3?;ӿ׼ \%#Z1v;8&$ 12R-FY{y!Ueϳ'Ou \i ot6'k۾3Sgxկ!bW[ύ`x ac( 0:AFnLVe8 jNDa@G6V>y*6 lLd,q=Ec0,4i97ZX\uHBI7딗=8µVW亹f[3}Dוyxe//ҽ#ψgP|ZX5:{$b}U'37 *3 AXWz?Y/O^ⲗ_@q<Vp?_= (f˟s>J͸\gA_:;^ϘR| a]r.hON3 /u1qtA5?#BtmPCKe5:qE!aX/5ZbB}zzAc8|2 㙔Z㨄q)tu126zO$ʖ.t2U1gJ! ?5b1%$/x}?fn]x Ϗ=RUĆ2j56(GD` *@"vLP/ye*X`wT{X2>(Jbi=O!\VI, {QTg+ȅb^L,j~uTlx/$Ff19 cPBHz&㝲3htR? T;+ ;$> qA !zðXXqm'9뭦k;K:@lvOdo54C-u>_O?L~ ;rdYr,Rjǿ«w_Z=Q*K@%r\(~![rpގb{fڢY ffJ c`K<|4>N?s _oM_g^bɧ-aix z\#2扛?_?<±77^aE*DZWoo=GW׳sϕHAFϜx7r'}y5pYf@l~~nϽi|y5s>vqthM'MtfpԳ8zÙX}PHY$&Xbz{|q!7'(' )L.j[k0>K"q }Ca*MX (J%E!-)\Qd3F w mrĨ;%}ނ $66A^&#*ud57gRQED¤XhXJ㬞muטpWgQ#; \l0=`V3ԎxYq=Qdwǘ XI-.Jm6%iJ̀ \ł=@IYirDz&Cm35jdxfJBJ֚{ɿ(_[Nz -d=3r>3!h<ϣZ&X0F!RZpC-kÍ_$3iB\_$/Ǯ"?׾7w[wWc4F- yFwA %`n<$!p.2 b_\LuTzv܉RH!Mor#G_vmc˅#b0er>"+5ZCVY#y/1 Z aHIt(z!AQH$㉱- cދrgi\BLY"75E״m%Dn v^XIk뭜oB`84ˍe^9iEq6(`l-2)Pcc{XqrԶmȞD#QkcukگՈk"hZeS skкNց !Z0*D䞍d%p PI"ܱ1ybbV2>>>q7y?0v^׾C\~˛Q'(Sݕ5%dX/qw)t304ΝȨ_)uϓ\|Ռ`b&z3ġO! |AN栛f(rJ\)B܉4ے agi`a*Q<( ˦55Fj B i66n|_/>2I7}$.z۶91|=~ۗ<o!SuqwSf/laVcɇ7N 禨}(|K_|O3z+5Q`b(=Qu`lcwk>[ ?~'|8 @֗`u~ce RNmBeLӃ(ñb@bk}÷28l  QIE&cDo=lɷEB5a\L؋ԙiGK {,뵋u]㴟l'Nd'?9^zRe%7u/uA/b7 !qblb`} `tem6is,R)5dY%B&Z͑R8.z*e*2sr.eT'IK$MXby?R-\|[ҋwg kȝLid2=\yj'7_ʷ\Ogw?O%1ϗɝCswj#ٿ_;; Z굟k#P~l@s~ 8a@$_L|~:$OF o˄\d9ϼBL? ?ŧ/W-g~_|ɟysͱqqitA E$㍰cRq=/ftN?~/w;.~ƂN9 ^pMF%f/v Ycp+([f/# e/jR yz!a/fbjԌh-zJ.[1A&7G5Kq0b@W 'aEED9.dHfOWB^xk8Ӫܘ#I~ i\Z[|Yˆz"2Dc`t*eEXU{bw>^:dA >ƪy$|)ClB;I@g1:a1#]+v!Qz 9ʙ0v8ܖ逑hfZ08[l&DuR9,e}l̷TĶP)! Q0碌PaZ$\!y99xGo;_i=p=7ҟP_Gyw Ώk_ƒݽ58Pw}uWø)㺌z+M#&XV4^NԱp9a' }ߦaL^IA-( :Ntl*6FE\>O܈ds> ЬJ, yxtq˹~"ٷ~Hl7QD1O˨89F5caϥ>`fe@85L5g/a>@(PI~8n-i0 i#~$Etw|LCbNk9/=o0CK3<9P]'~OOZ$"×]E_0h}^ZTW,Q!C&֍0V.kJKdPw݋{$1Hd""mLTd-VkN ZwyB([f1 + X@*6ryN!oW,ݬdLe-˯Qa|FٻYz',sXgՐ=juU\lEe"# s$Qn7B t n>[L-Vy̼ fyuF0·M\fkeLnKx=O[︙q.;!҆+y|u>ͬ@|Fr1H*N-\D :LM38w`K+ aGaH_' *4|cE)28kGsGGy/ߘ˘{7H=_[Jf?\?ѫve6 Xr,4)QBgEhm#:ܼ$R_yǯGH%ЎKxFYcw!r3iܩi369XBT*{R^H e3Gʛb\-m|RkMw詥WibakFE161i4~ej<$<4W|^#w a,A&6Fπ61AAḦ́RaHXtnS 5a[gE[rg8xg^qd_WǖA l2'e2-7M/F:^ ,m.8mC˭-g$s;;M;;q6(" `l_k68`k166-p0"(@( IʛN9;= kyvBS}oS5Zē0hmzH2 E0Zqjt<!LVf!*{cwd$c eK6%E!bףNn0 1!kgM}s`uWQE܌JlF(|`ffP* ֆ!'(N߸œ=X^|[ }l3H;Uu"&wn;aܗp^8ݳ]3gikz:b|^BA2v ` DFQo< XCFR8M%`TcvvBG(S2xV& 5hy6>Kq:W=7KI/%$om@Q Q \z0T!s\uI|n޶vWB~?|{y/=,Rh\;jbΨGkQkǠ>5 5P)VZ*8<vĜ(E"Tr0THR5RG|X&kQ2jRLJBkZ!bgqGcԌf a[746$,n$c'Q#Xc\aT⋥ |EĨkd"C%%a #$T<V[eqWLmA5 Yy|0i8IF_֚5؛7 1k: hk{Qn֊V ՆHq{M1 %S b-F], rp]P:U*~4)<OЃq6k3zdn cUi%Yi? r[Б]lAF^¥ڍh!yaumƗ> m?| q~xF46#9y-W 0'8p`'xjG#Ʌ/~ s-bٔqB]c+Lukn:wk# vq\negF{n߸3rxKZ (X110vwLQӤ$E2)k)BRO;BIr+ț6Z69ePZѓk=IBD!caPR|[y5o2?k"F&G5~R23@氵8(0bFBGG׮jvQW.K;-M>Ŝf4_)FCf\,P̺H<6ISB'C],ZFuQթ JDiE &7MI-˗K!jx9k%:LkLWBa`ggFaϺ˱bҰD>\|_x\v\Yd\?bGߡ}Z!ȶumku(W~/y%/5ZyY::z(t?2]:[;)NO>sJo3RKNDJc-I(XHօٲaGOx!JTL[;c*Ezap̓?yaE\ @+yߩF>hw$F~xh[ˋ_r6gr=۩ؽq6z 90뇡W-Q.?DLMopu݁F] "8ZVk`' xeʄ>>!! D.QMRO]&q-8 Crmg4' V\^ƃ}]sgV_z}uka6~rPq%#"+jRAr+~76恃?1љ a/c*CÄ!e^z%]X)DHۭF T%c:SӕT:HQLDɨi3p&CMpX&iet'\o*\{hʡ1BMMڵ[ڛoG]o% "'ǟg;6W_۷?DX"ձ,XmJk&']H02P(XGQmf]l__Ú\ғpv ?Ya&\P"#5PH7\עD&LHc "C&~$ј\f˄2X2cj; Wu#XmRQ}'O^wԞY~^/ܺ 'c` vg^sW$it /tdvz01M^ .n:p̦ܳޯCu6\ːB  P#$$$$$  ^12rEs@c.\6U;S^qΐs|%[۹/W˿ws=Gq@F9q{bÈĕ QbxӅw}.sglҊάI&3 pMɇ<ԹվO)g,zd uWbXI'ψJ[fV`9WR[­2_f^Vbq[)$%GC( JQ P.s:vM7i*Ce&t "4X5 =ɴc1')²0VZFZsj.L&NR  `a4;M,MZ,A{.狼zw_'61U*L,k)ibvŰ"E-Uxy͘{0M4{g6 yM/:BEB) l )|7%Z% )xIk( xĹhH)]:a2X"XI AXBwO ׋iIn~wr>zQ+evzw׾o3{ {b2߷eDjы1-NJ]~LCXx9vܖ,݇+3>Ҿ 2_F##yN3F[l`vn7/M<-^,TlN@3-ҞS$RٽK_~?Ceng5ޱ 2 |66e\! 1bO>1^?,S' %8^`uСP#"_" Q JD RDPnW4H ?6Yj S~%@fڀQ4uf_Wan#{y3Wy:qY?rsogmBn6O^sa.tSSƪ"LwȥREÈng^$0D nyka]&KLm|9[|3𐆉hr!͡;A C&Apk(Q:`Hqɏ.6 o xP)͋ FII)MJ[` +UꍒۉrCCۋ52a֦MW"6z{1r9eHӤfg33E2[Xʣhj*dݤF6V&k1L 4S4L tCP4S$~OnMEJ#2OW߈_,(}^Vm믾sf/lvL&a{U(=elTjC% HHTEVPrNړVt'L-¯k*(9WcϰM"/z/__U?7|O>߾M/aN&M`x!% LpPTq:O\y>>'覟N*:ҒHl\βxK?>0^tM.!u a: OT w)fЧrk!}rMa<dBDZ)tc$F$5a$ftP*V#WQUh1-ӊV`Dq&>,)u͟Z "I?z2iiRՀIou3 ALFd> V9&NN6_ ḙ:%*Q2u\6n=݉R 7eg.QXSm?N("DmITe }tVKLΌ11iӟ`erBM߮(#ԚPKQ66 B$RQBbHŇF!%Hid\$WIl4 Z#u,ݍY/Uuiƍkb : lj)kR6EmQ.t,Xw/v=ƙΡo0 :4I&G( h5"5*Q{N:u_;~u\qv?p6?庛٫NGo==pƪItJȼZU#ioC ZS)p3,B% PZȵB-3{z!f/jrӲP2DU\r./bg4zia^t%K-OolKc;}cіR;dkPY if*)D4`:N:S0z[ z1` (|fBk˃,)]uC&n>?IQy+䎝T037K~]h}<(D$S%kZ˥Ժf[|;'h=;9sRC+$Eťl)+$sdRef|rH\R.U+G1˴]L6G6W WhNB[6lq[ -CLmԣ OTA-tpJ $%0$*\AU="9Uҩsra$t MI%!U"FAZ 4F64RH"c#MŋaY*64ROAݎXy|LOC}z/zfad='W\0T}?+?z/߿?]{\^ud|T22PĹ j,jos)(kX?~ 2 dEtG7IЅ֚AݴFQYc;t"qT2" CT+ec{R*&@DRƫV|( c. ,q3d9r:o'Wh#fr؎הJ9eN߆_.Ϋ+vR$8O,O)"pOUh"Y-dWA:. ҒnmG_DFЦ T(-f$fwCxZaۘCCX## TM=4ݍ0j 53Hb `> y+EH4bN0DRL4sLHsӁ}Wr9MwZlDi C@FBR}(B͐-oguB;n6WwjuڱؔZ弶Vw"YbE\^5(W*DteL*f|aQywMiAg%;6%xPyN$aS'& A n>ub45js^tԐ 9X?|hJG.~1|X~#=y6Qorι5 a(% ri|['iJʸyBL6' jYkTot{,EοFoQM- NrrX8/S7Vt$ UEaH{x JJyC{SӘ2^U 8 (nPXfdm1,fmq2cm i$"q m/iZGiKa' d|\G'}&gT*X2irwZV htm,0&N59<~} .6nڰsxaDQzJ"& Cl fvRq%P@EFJLNx n2shmĨMHlٸ&Z ^D A]?+䘙Rg \ ΎF0FFOc$ .r]5o{C`V=,rL6G\$Wh#fX)p~N_d)qGp͛/Q|7De`:68km7"=`dTxx2rC8rk6kn 8/,eoaN{mq뙄_z< )%tT*\zv[*WI,)1tJ#F%k>`$#$л ch{f12sޟR: CWGI=Mఒʵ_jjq!M/45N21)*a'ŅR9ɽY(>֠GL ~e!y˵b~MGG;{`>A%;"Rd4&E ɐȷu28\[;lWbf5&!@LWSJB[zVcmCf{j5aO>k-;(-I(MJE5˲|zЊMhH y0>}_5<¾=7 fӲL+x[8K6Wfm'q0-Ӵs 5e QGG7SSL7@6G%L$YY}BUq,O=V3b`15yRa01옸hg2ܸNR#Y*0}$2VQ_-+X$J+}TMQYdBC2X. kcƍX7NRurQu~NӤV ŊVU.1grQuo/][:la-YJNhT?YjַtcD(e˥Zl%/okg :p0LQ%S)Cm4@$5ʖB0@cNXk!-;ZAїz-X{SSB86ZE8RovdHkC*# T!\`iY.E?t ơa*ւH)NWZaZJ%TI(%1-`KHL+gsyl۶K xI~IMbݽ!18$K!(dR}p'Doɩ*nj@ Q~(РD', EDa C1 IDATiցz25kbh 4jB.D6 x `D1ï;IP j.[TJ-p9(#?8p/_s7aD$ER<7C$e3Ϻ~ t0 !.dq$ dx4%t*8drvz q0jv©IFC.#1S+jY'Zk($="JsTs^EXC*_F,H[-IlLTz#>W|`9>/K%^R' 5glNB/χY q'A.n$V۟॰$m,RIPZFNE_-Sf\cAॖdZ1xq3D4Ų(e-:}u]T M^az$c|m>6:V^Â^|%"tE(BGѢNR¶10֯6`['zBCʦ< ]*ayEh Yigym+f{[x tiB؝E)֒i}U~W貺87׿xoH.M ]U7?bPLVtJҌJqD]c0 C|ߣZI(BklL.ONOP 2ryl4䬍biX$0Dk$^1'1=~1"u 38;i6oN&hTHSz궰@O{1}:V5'yثVaB8sKO#MI$a8a3C\S ~y*4 ޖ.^dj2Y J4MWDa"ssĭym uR}>oUh~<Sa & ]H+D"6׭Ӥu010 pxTIJWJ ! hR,whLcj#:8k ,ĵM*(PU~x\Ņ[l|&%uy>ܱn /|ͧ!(DQ Ւ `a("j- yvZ/v=Mi⚔cVBXZ0 ҵ~mzξ9׿?wl{?1zc` ܭOdcS9"3K58=KePviלFk &2K-)^N9]`d<s<9(XX3|u@e+]iZY}+EE΁0Z^OʎRAИlY-rhbrq{z?_<vſ#/}5xznߧ+\k/_{kn~z:1n\2WŮ<\6]v6Ff@GT킮tB?JQ/1/20Hd DLl^ da݃bwPBȚ0:\8;!'17=W.졻ogGWmlK v18'7IE/,QZ?'39Xm [,vE@aDNNɾwX6@XqwZR,R9B c h'oPU-S,9V @z.l#m'i#;B)=H ijrKQ5ZI\Y +w~j4MlCQlE^&(s۽Og>zzms?|@{Ss?ŷjp-w~y`WExPb Yǟ|;*\Ѝ;1 eKf(y >0MB%@f#\Lkd d~ QJcn6G6F{jVwp2Ƞ!N89l rJSL c*Qfh被w6;{rXLIPa?GG7?w hU,¶\+VD@e1 JBr{Y9$RbffQ߇x?Z-2 Z,@ 0M9nҾF&觶$Ā -M5P >7>azZ'^Ȃwzch!l0); > !0MˏL=+d)o#| |'=~?WʚA/?9 cMōOζaYL$Î~ v|d;PY8m~՗3?ۏ}W룜iRn L/q A\B*WdTM d( N6߆f,GsR|1YO~ 3ScLbvj acY6:{\i.\-}.\5?Ynm,"T>S:.uhP2:0{{SS dsX*^]}~9 Tf:2 1 ״ȩE `?D*uhv%\j=8BK %֥tZkJ qfg:{ːeiol0\cnjCLS /$A֍FgOl7STG봈%%p^@IIDDQrpH R+ڑjUab# DFwjf!­XI8>/x? 8ܰs5W^J A8Ķl)_Q.{ )+S?hPPIk?}gg?8>Q'On0Yc9$19=dz70[uw*MÜ~8qA:)}RE[A0m"G1㛜Q__u:7|vVu1p0wtѶj{ QG6; sI6=x_3EcnvDV7oxGx BJd!.|@䗠L.zFyrnc 2?V[w%gZ&Jx"}e;̔W\R؎Ka%OpxדӺq\83X]Uˠ5lrVMގ QxUÔa&u R<0h٭V'FJݗz1=T{F{\nv&yܼc糙+4R8vl7Oڥvj;^1?KjՂX.Ѧ,l.WNXRwJ˥.FB)#`dd [,ڣ胷q]3oz+݋RZvҊٙi)fxlևoH^/9W>>p?a]ÿyoqGhokT)a Z~/Gx[sAh/nؾ(%;9XKj$kBZgUD$%Rz VDA ũGJ>|*0Hnx2ř25FqfJQ]Ϻѭt C6Dz0wɠĴJR'Sį\\#MHjYPh5\ҷmOmڒ͢eNt@5^%`:>|0w+STt?Bm\tٌHRY#@|ƛw﹄|I֘;K{([1N?~E9 #Whv1k@ l'' #FG7w~~rOyFK)@ KZx&\ AJ+vY͎ bXX)Unzu0>9Ch~ϰыvRk` {( ZTO 3j6:0wJ$rj;vk@2 X((d';xzF0K_2Npw֚[vb^/{,5BI^T9PI1[LGOk,Ӿ _atixw. Ubzëϣ#ROl F*-?O'~(}Nv!~ϧ)o7_e7 o|>=yz1Qw+01 4i / XJނ׊QKXax3}grq٩ f'bwqbfCW 7NgO?80N_%#\aǣsb[[F7Eۭ|3Z)5koeʹ\ۥA2ۋBX"J8 5YG -mpE/Iv~ 淮C%@&,L@ց5ӄav&!A-! `EŴ:`I?Ʃ"1!,=%6?_(NYc-:i ~>RØ4qLFz>^JS6Ž6U/806I LH5Ѩ9%eHv #GD}ٛþ}S=/,>횫9th9gx]zk84Q@yha (Q'ϥMa~a"I]X..FiYDڙ4 =;o`MWCg_@gm]d29L\jrBㅈDWf\<|jt<4c'8;[n}妘/4dyL 6f{{`7qqi*/ի6Ҋݽӷ#.g x&& {*s==k@bm6\6,(@X%/8)0svxXf ͺ9\KbS(d]n~Ydlh-s,INVt-S,Ŏ%0 k)q |{I7BqH1&rm(Ë/aH(@2 %if1Te,F3 UfMM lceCV%warMW+dɖe[۸!`BB !$4LB ^B)BI(`"Y]wg3M[fV*:f48 >{w<_j}d# $Rd>ъ2RDet$SJ2l*dغugئN3ܷ%ud,IECe,BWu2Ye2#%tu?0aY #bBxIѪyngj4(98_Q+YWW;b[TO}WwR$Zk ²>z*}7Y@GƜh-,ưT, @Tu> ҩ~xGqTb@[6}4b-b{Di P(@hU8_40^:+/a˖-K 5hաdJKTlmj_m[[,_#DĒ P p}+P T\eD.E4Baw۪jC8 :23Y6Z+կWA=s2u/}3g?} OKw36`GFJ dx  ZW#"6-,#aZ'\œrXby jZz|cvo 27spG52\!<2EOP+Ç; ]JV})z6mY}mK=CF Xqz>Y'Ke-Sr*%]qS ]V拣ր H2_2Aa" I!,aZ+* IDATWP~~^u/7a6m>J՛p_o# Ӣ>P̪2ʪA,2(ŒR d]nUf4+hp>LXJD" 2Bu@p^n c6WǟgWyۣ=ܽ q6W}ӌa`88DGv_=s$}|pHWo0M@Vt<U'fﯫ#ua;-pK8x:B*~Tn|swlArſ4LnP+DwJS,?k,c-hk[6jFԳ^VeX\~ў/ce ʮ^oq?X}J,A@¶39< hmF"Hc8IL;l "na_y~`ǎsmNрo1Ddį(@'B&ߤ"LPrBQ/cfVx0V|Hw+=g35=Y;eUm֘fx(ja{~y{t%:'汻m+!%*Nѹ{|RFƦ[p& ?d3j:܆a",;fM@ѨQc cѰ*R)QJ?H66wfW:)E:Xi:-4VW7\Af_/rna=m KXvh Ź^5r΃ C rǃQz 'svq,c%Jlk K+X0,Kg,KHYJ>% Xԑ#FX誶' d{&NTzy MO"\ץx#>zf;1Lb%S$ FgO>}>~n+^Z@ռB.E>N ]5+m Mk Sn`:_Fa _FUL`[0m0kdOiѲDnq8oW7qwT?@3\Wu׈.0PbRC}3%OTh0—}K6̷{ (iG1mN3 |~CY ݴS6* L۶1 h`_ kĿ X/{D78 %b,K=rJ,UPl}Y+Oiq|S.VA[W$IF7l Kw|;v=s#WIq2i(M't^toTW 'Xjh[j CWAք S&PVfԥLUt씔 h3$:cuf23YT9<Jjh1޲-q=?F逻kt; wERh-'CPiئR ?( H B%~3c+(Սp,0,zFH"33 dۀwZVe;^+{2KY#Y?sw|4HVo!.6'rOEz l4%V㕾ή.oa{KVd*A2UeGFV}N咎<Gȶ䗹n;߹-'v?f%WrOvB_"23kEm.mg ?E^UJ#( KE Y`tIzo~!#oM6 c7?>#cMkU6UNaJ]m31 \ĩQd54(R@n~igg(sHG(]r%}C#ttqiMG! >O~C.Zv}iH5Mj_}vWiAc6¶Е ¶l6ET>/ T/Iqg= [n-C`IJA0( K2=m١$ aE |0Dh^AT};z"Ϟ]p4CC 镘8Dx!!(Nsu73oWj m5v?By0l/oٲ,K9o?"}(>?A2 F=+`^ȶ/K3lmM )L StDM@ΤQ4$JK'77|(!LxgK06Y  L:cccӧ>yVȀ3Xxf U&v%ș08 F..b7ds-L)>DGy+_NOw?ʧeEosӕy;Lebv\cy[f@DIP* GJi,p.TgV$*Bfgn!mM2?7*l#I/c2=_bhRDc+AɃ{8,amu'?'jZrDV X!$Zljaei/84-"!wF8U_danif#$7@([Ͻށ!]Gوu1-Ml=c J)v<T*elFEfvPmwi J ]Fy!_{x`j bp b 6Knvgo}}JgC].y3<-$[>׾Ŕ7]ɟL߃n@a ]5y/ލV)%DǶD*O{e-$2ZyA<TJEtRlD1mT!*;X C*3Eq~gnfr d1Ӹ$COmxSphhK$oZ˒&Ҳ0RI)Qf>Ciq|QokB_]ncEs ZLaP ",7X—ԗ,2[ #iuvl xBq[>Op3ď?́9z.~ދF|پ ,9 wQp#[_kXKH;vqG< A> AEHus o´½tv?,&:z*2Bj}Fغ`%}X[ıtfg QgT/ME} FpD4ϕ*9榙&7?GTDkM*o l2zHg;U&b /hBRv |߭\R-fq,} 4VݮGD(!@Q338g]8Oxk>ǿr j;{> ^s5؉a^7pp_S'InL9/l{ y#:?Cc[ṥʚ^zb##ض~F0w?NQUf_ o$ Gi2{x/KEQq+X4B/#qeJ!|.|,°ٴq _l~cXq?W5,񿓎wh='_4X?z0\Z

oN:1=ſfw-r%%;f䒛|Q,YFL34A?l'Km8NwS.MEAhU5V+B026Nnv~lW* 0*XB6%U>$*q+egg&0GT!Hg;dh{UJg$@)Mດ(RUЦc$i6m; +j%n s95]mw":Ĵo[ba׹ c$er)=;x*]97vUtO?S׫p};&L2MԎ,<#NcYV6d e3h$ ,C eͫː^}{]Ǚadh ;P XV{≛IR<,SԩNǩȸ= YvNV/RmI؊\dT:bъ/0vBaKbzx>S{nc%oifaCt ]Dzv;zݓy\tw:_G.zشu {oL=2сhv?= %Rx~=a70{XR(̡Mc;44Uc5ɱ '`YR u P'8#^O~''q okPgK沱#Ot#n5'L]bmgm/!'s7qh }[. &^ǛIF(7ţ&K? '֫߄ =k¡o@POW<.8l9f>cf"yoop'ǒ8iXǼ"2PQ n տ:0q oΆDJ-ufz %h RId!M!'!ME}uUJ=R1aT~1[`nz|yO>w !0L8iヌ8s#e?J0UIT;`bv؝f yDI=4G`?û* ä*zR},KlG(*m瞋p ,.W?%Et8kh=Z +D^);$r^FGGٷo_ YNSL}- u۰YzL'^||&C)4 9!t%;z(P|2ACLұ,i_1, K$d2y2Ex9S1ak=hX6)'ҵve%vEO?O`pJ>ơ=Dj9o ,E}<+|w3[/Cs׷.,Vӝf`Ut$O~J?&=z@2?IiA~rJW0z zc6!g糩+Md:2VWme@!Adb@#]ac|+}O& 睉cTguynk?g|l07=~:C\188zy{#L= JyP^:Cԁȟa5)N `$ ͐+n5Z @3FԂ@Ҡ♤MZ<}T:ja;:H嫍Tue9N2E4@>bJCR,2/:4Ѯ䪕۶ r4,MH$Х51RIjva@i@XJ =H)E/0pʉG `*ӲXi%T+ DF 3mY`Wq"zzO` J!H$(LQֽ:[>+}BgGo&_f7ssIK U$dXx{^RglbwʝȊe9d>V&$^~|<ЙIwmJV6uCF@ ͆+?ȖgdHa+ElJ: GԌШzTfHXeJL(ZyF(jY4BiR!/M|iI 07J՘^Ӳػ&%{+l1ɢ-X8K]n1y t K4ȯډmgXn۶v[->::QEM-Qzڊs0^5 oQt UA$~$O#,+/QXZvV{ʹG*+I*ʲc8ʱ؟ӱ,5&*j o'b< zs8G+N/⠠d?@^ũE,S`G[^n6_y37g{G/ ZVc:, ^)?dnAq_-p?_I7H=Lui 拊+͋^2u| 4.q"ʈ'Fvrޏ rm#3%~)#q(>5J̰4Gs[N6JGH\mf X:VYzH2exNN=8ad]@r( 0 mS$f/i]}c523yۓex Ckqc){ҕDT+>,id6@)!_wPR1Vԥ͚F4+4%l&pl  PulFPHbhNEFrDҩͨ ?e/ZPX%"ωeԚЛ;rqWq~{?Sg_w~㺫g$&ȧ}7o)]p|:=*!3J1?;{9wA)EGW7#cnW\KO d*왈 ے -:Zx+~vV`ڎ쫕h-Y0)FO7rv{&XB"shXIf-iԆ3JP*Cu|_177O\Ʊ,Y0LҨup[sKvP/[Q{rD"*U}IV%Ճ D#wkRu6MA96 ȉh6?VOVr,x)Y C`> ysq|sw3/H~TxHF&D-rvzu*B7s+T`(iNUIv?dSZE[*=!C, <3fU2,%tE G JTV;mdt[Eox?>>~NW_ `cjM$;$U&~qtE=sw6lxsL9s3xK*pqzƍd1,(ZuRCDÒMkr@S+s3:J׏E&Zʣz:T<'(zJbn%5^'0c/_>,t}Kȱ$e07b/K>X]рoR 4d2|Q mlO Ӊ=<4{z*9Pdƅ:h TtiSNGpӵS2v)l 2E G{磼d\z"47 hQgMU"3ψF?É I F pL.6f4jl'N IXd1Ȑ^V=ŗ?{|@׽f8BB }f C[?>DT aHj-p,cYh R) zR:|rEWϧkj1}*$i6eaoUB*TFz$'.U3-z"̞@%XTf>N6౞X8b$6tQ f;W`vHyom4Vl{L&E X(ktÕ^p#epiS0m*vdlF?#>DC? 'ZcRrfTpS14 Lbك&X`CP/_`ӰW=.|1$R5z@MRmC+GXT`@b+7v]xq{/Wx<¥/~/ϟ E% J)g8Cv3qp/ s3()tt10<8_r%=C$S D+M C(EP'ut[bՓJcVWb`Z{"\!XAR؃\xp\mRtn9i;C~{^٣y/i @[56a)vH Dj /6M3LBSbI^j&K X(%Y M  u|iKJImaZZu1a@UkD/-'+J ^ʓ!j1}߯COq&-~)d,`h>Ayl8Gne*1BOWM! 5~BGi-,P/Y*5'6hB@w= ;MDqaI 3*k0WGDAFo 4A/_1pcFca96|z(2=9K|s})܇R]ᒧsw?E+a%NLFZ?ɫN8>Sſwnw?Ӌ}f]ƛ?MD"5HouijZ\c~{s+$SiM(l ARihnwN:J++Dڽ}̀fтX)){z"0sG<!L` MRqѶe_nwr`f*}[~/)xB!-mJ;1 (ϳcl;E |_EYv*Mցah&ݏ;)pLܡL||E>錊 WߚoA`-`,*O4˱UeBS}:$W'X/d4|.O"2iZXꠣP,CsA9Se^:ڠ$4 yaT 2nQx6e 5E}~T'Y 40⃿0$aKPn⎇+Q>o헿ʹ@PEFlXJ+ُ2T%Xq2 v_T߫v;%̷yk_|" Ahh~CCF!m;t34?j- W}ߏ|^uVmv#}5 ^Eieۆa`vt] [\C=w{ijnNߺ*?/?~1y0s;g}?9f<8EpQ_;$4BLQ4(&&&J þ$GΠ7`r@4~tCwwyfgMGf.%?7GEl,A )-LM-72`_' fq'i!;B-~1-PŒ9Jɽ,/ tKץ`>ehdt}ލt˂VL=8SnFߺ^L{HR<§(SzZ}+ka1ڑD>RxFRAdP.ch'i97|^>"^mtgrs _Dzz+Dd>py|49)[PD0u`CKFi#κEFJ%y2@#jw܈ON~t?wDΐ@ s U6?m雙9t_{ż䅿F2Y\H%jq iF՗.()b>},L}|jOw`T&iht$U$([e0L4VvL퀦xZ}죍 6R)Tߋo쯩T 6mN{.?FlޕIXK>g6K|TJJ>-UWmRPA c( DJIgg'܆h4[}7 #edv]]lߑrlQ.dys-# Ox *@( ~" kQ4hJus*mɖ5{U*^>ZJgߐV_ي,H000PJɊT>'[ #;Џ*GL+Бd=1ШJDG#C;4`@#{rm{MyާIxgr!/z6n|W)Ͷ3FC5S~A6i8anzR&L7І\%ٍm;hDtq rܨ~0ޣ1Qr V2@[j+G;HA;킶%O]}X&\FīZmp͍m_W>2ǯyMpe"2c_zHJ|rda8vM 2˳Gl6:n4y !Њ0]A,Kf( Ρέc&eæ3wD ˛draR039~cZ,LPr9wi078QJ;k)VWK`h$`6AD{,'SJة";< K3Uo]ܸ' @R"D$DUήĶw*ڎ^gcߺ:UI[UInnIUk'^I|?foI$$«ntw> n`lRCэFw|-T"jrF[mK7߶}΃l$e< n^7Ge#gZ"<AM/#WB5g0ۆwN۸w XC2L=ə|6apܧtx 4X)C_K IDATrc M 3k>q RI6@D[Yly_}?s'\ tBl?` ~{?z ùq@kW}] 1$BP1ƀ;Bچ5P^YՏ?B-?{ "}fvt+l߁ŽШO@ NŽ$JwW۪8޿F;q⊵) J>h%kmx9/AXj"Uhf =t3O48vh5Y<_ō+/N!β`%?]Xl i!ihA_Y|p=_Hge0,Ӵ<z=З+lG"b=Ƴ٧)aaD QŇ)&LMu.0` K`1Nɩ=`YK(5%X^\Fp?Lǁj5Q4S H+vd b 1ބ2q|;D³h5MO|\[KxM8dRc--^+㽋oE,h^^Zc%,01QeaB3QJu5OTzTo[^\]zN[j+L&+Xr@lw \ERɆ6b984nS̀N8,d4m"/YE1@vƦarXfXR"?ej#5F %58uAetTG]n̒Q^3khw `)@vn  L,g32CaFLk19];qeje!giVl&TUHTZ USÝO>F}AX+MABơ* ·uDe#l'9ꗩ2h+X<`%~#nDю& 偞2ڴ3 4,j#ZXƞE|DC)ϙYUQS^{.`ZECUk:X/f"1l6K+Ir9LLL@Qoe(2t%%zeFݐFE$;pO#{dD%6n^ېeeI %xleG@Hy7-B=adòd94DXkg,l 8di?u%x^aE;N^6 )mka2IZ?AYa03,}˲e'`]3qoҞEKσeWځP?~{wg{yH~?{ fl @Km@+/ޡ?w$ 30x<("r|ll&''4*2suwī4qHE5bP ptS(6Ifվl B|D;Sjqc2ҋI0>@ vN#itN؝ X`)HI< uҵ0_0:aafTaz:zX-ÐD4,hiKR4 l: sy9g FQ8ohӧQ{uvc01O?g_/L6 2tVS,k٬V!^߱K:9@kY0 ,;%th]fk.l1%y,c'Z bX)Wp>~_B2.ѡهK04$ 8F8`l3`|4@ƠָQ 䨚de]gԖQ%Lj"JT]'1 0 X&juu?/ٝ 'pмxQ&Xݐ^~ ?}p< j`i`U {9+ZegtsVLӌe\.bR)E:),rA@>G&:(AF .IMj=Q D;yC,̵ V"t䊒R2y! "_ÀXDS7`Ϋ- yWn_{ 9ŏO]_/8 E0v<>m]pO!iȢ=>e } G=aHh[X5>e_ q16ע{O{Avgg%l&j8(%!JAOЮڪq0Ul6yXlݹX L,mF?Dס> ^!^ -v=Fӂin/KK @jJV搓IIHeYqJWn](ku|iZj䫟~PDA ҏx%hZH샺]J>6&iZu@-wju 7qsKKV>+73/};y|K?W1?>x4 K=D cL"!*ةIrt4kycT \dn۸,F_ZZRR>iex\qt)J<g<]KT<;FDQ 5wī;3%~5 |?g`Y{enBzZnF\7"![ˀ8X!u]f?y ,yO~_ᩄ Zg^[+xs??C])d2v ة[!u2ɆӰ4,_ʲo|+ T;j`AvaFa)#zQu6A?cTײA7 :Z_ƍ???8 r|#|?n[^?>A$ a=e5Fu XXZE/4eq(aeee% [0!dLq I( fQ(/^ #_~wzwa bQPc A}SA|{w?QxE+9|ٯ8{H?M4@^[No}|먲1(1ٟ{%!g瀸9>en;NڌfO4XIm ڃŶ=n{{a7 BV&tvD%ܨ%cUБ "5Tʁ0IĿ@ 677U{mZ7JC6犥W:eg@ܲ,Z*jk4nʸEq1ɠP(xa×_7ͻL\%WUKwJFڎG@ T1F;U/5ǹB@*K4uMG^Bf,_yW X8led8rGK'KO`7sO!yNx+yk;L{|cLgtA ,p r؎GXo_Ր@itN1>IKONv \|2lw$f10:04s6J'#J`bXd04l6Q=}+Da^%Iҏ!?.Xٴo 9C8犥*(T*2 E4eqqQd9S#_ccč7555JL4m%*v(%R C ?A:lb}O>VV*l߾'N#X$j%~L$(:/~kY2=T'~lBu v*g) LѐD &Xp1:] )O<-k EZl+ӳ 3v_hk$OaKTǨǭ~alk.|V@흷aGg?@j=,p׬fl\t[ZR2.IAg'eaׂXqMٶm2GP\²쪑/urImGݔADE4~±-)rVwd# '<,`1<>sx"*1M_8 'BLE2ktj:6ـCfz4nb;"Xr}eE _QKѢ^x6yXi׮a&OC//-{YH`I!4wŬTl+ޢu7Ev2MST*JRIqrʄ1'&E$Ied2ضm*ҭKeyท^._WwfJ>ql6a&=BG%:6qz'Yu q{}ނԼ*{`iu _D;;9ifv lXbK 8×KRr2.RdYPGWf:t)n7ypr%.pG  ŕ;:-N`"䃒@, _ғ0 0QW?Lķ -NGEب] ;v(c1~&ȶŽ-\' Q-FѾ=޵"q@u~+|{vC`__opFZƇ`RK7i-LA9 /.En6JL:%7Ա (c.%y$9Jy$ե+3{+^4Ϛxώ~x|Mx  nA7DZܨcЪ랩Z*zϫESQuao'TA0*p:E!nA CT\QwTa cha?˂.`ADa4p;F֯#.0nC,]?{jX@kZMB8|.///'ytR2,z$Ee9crrrM]<(3OX [*ȍ25bؐmybFNusW,5h}JA0 \.+r;DeO7q%*$`If.%w|[?>{:.]3Po5 [i E$DId00␐$Eh(R1L 9 >+ިn",A (cz?QǦ^#JQ2" f2{g}c8l苋XCy~TN@' c=؏̷_73YzinhXCL NHhz=ۃl=bn NR9Q̉Kzibµ:n.|zb@iB$e#$q,T$2" $=A+Vݏx?B7-? ٱ R*x0%jNF4~EzTbFPys%>e6t1P~&*arUw<8~\@I8#PςQHyc!0 XV[l޶#8+ޣ"ŧ _18F!7 ×KR *c I L&133]J>KQb,nh&TԛVj-\hr g?PoM,W 0 c Mg9L&9eQpOX݊f{OoRb~ $U@^رO\0 Q \X}D/ߠ & Y :tu!΁eY , JeY P>|CP{-#[ر1Wai:`uR=FӹbI>  gYK kh\ZZvrI+Oq'K$;)b< GRRb p7ZHo(jDar j趉w46M[iA7L,d I3in, ZRK>}Sw@gGDUj-~(O{aA6)=Zʾ7; Q 32Ѽv ǎaTOfjSOB0v[¬ކ=J#ihFA:|-n5WR*XR=:$e>M(,K,cbb۷oHZTw0Dib{:-|rzTU `! v'%!1(d9dcRXǁ(TM zzVQ=󰝓35ZIDAT$v[g(Fd$2<D[\<:{O^|׾.w,pͶ+BC6报˴ _,q/˲Zj.)xbeCZ*/ե1qk;eAmX悎t?PU]tE\j4B1q~X($hK\3\Hapڲ)]{~ 3ާa Z -,:Ud| ˲y>RUNBATAa1"b/<w-pW*K˖z\Ӛb0|m%)dUUUU'\G -(˲,K$˲̎#yL&Uy)$A$<g0O6Lr;*V쑯&.TQoXP&ƻ$`\aQs"XZ}3_^yIxvT[ݰYF};F3l w Na,GpUp².`:ʑön`u =4bH &-p[n0j<ڣTbiFV;|.NcfiiurG9?qk|".IĶmېfWRX !HHGT߸;u㞎;:\nzuMlgUDgF^POo ȨZNI;׀~\ Z@C¬3lRz Bpҭjs ABu;0. мv P>x۸wL6}> &SS,p?wpX882WՒr\.{_Ν$QQO,?11L&R&''=]$I.ErKAkYDR7pj•&  +-膅1zLC>zMTd1npE`1Rrq;9@~=8 H'!xIa ywE%|;ݰ d~wj&6a?{2D8SaP/^DTFЪUf >$J% 2Z(V{!lKh@AAAK 7Dјrt).I5@yޛ$d:S^6Iazdyr:)6Q&.~WǍo^EmE1ʏ+,&W~vZknlmZBӣG^h0cLa 0 . 6J9AX؆%a:`HW~2L۸:کSICWBίtZZTwAo%V~뺲2!'.Qqqe_\<g2J/] 2S߱euX3S4Yn#oaje쑯֦䲼mGg!;Id<;b*4 4d`FtV ^v((GVt6ÆI t6P9u CQEX]=,_? FQuw[~fc?bBSPPPl*2I1 CT*Jw$H>"Hl6;P')(X ޱvfM) ^ W ,m}Bf1tQDe-;F>6d'f[m^0MQƐQ ~EzmEGۧڐe=RͶ7JHD=Ƒè;wa-p@왧ί!Q0/MZ(\t^phϒNcVȾ~8l]ϧR)yxWR#_fh#_>ְ3S>9Ba 3䳂mGE#*kɇWa+A_ȆGXn/+R .0m"$3JW]ck [۸t cGQ9rΣU)~+ ,]ugMt\K((((((Cu@_Fj4~CX dA"ɲ,#LzKX"!Lihn.hҵ&|bf`҂iYH9;ѦLב" fAd֭cgS`KkkbyvkD+jVa?haT<t7ˮm\ܬ-?} [@cA ,pVy sR 4M4mfyyurdq/I$&Hԥ y):2Sڿtb[ۙ):pc75T M =Aq;'9GxfK`u!aFݯ c4vqr=l')l.Ǡ׆m!+Q]!t&}aӧP=|չ94?س`L"mk۰o8+nwz9|QpFZVRLU*m2Eۜ? ø]Y$VQ]J:F&mVHQ@$0yU3Qo؎^鸻u5 K-0 A:!Csn_\jt XoG(_eذaAƭ`DAP[~D/hjolw6uϜA[޻0u ħ+!w7tgj`jWsƑ\tޢh(;K_{jZmMqzIKt:|>\.瑔\.|>T*IVR!2Sn-~OG4\DfwS@JppzC>cbwS W\w䊴:^b=pDD!cAvt,yd4 4.]BqT6VLf!<8b_?p3S c6TuaRp6W,wEOq"p(jFUU+,`kSdQ]"Jq # Nw䧸%*~)Bou 諪˶D_oy -%ӼWY8 C@ AQENF'^/0^VQ|tplp\OFyn#GP;} ڭ 8ݏ"ܳHup;tGKw !JL7rGRΒ c TE*OsȻv1t;LBn ף 07lH>Q;mTymuaR9Ȇ8mY4?˂g?.]I&{Y~{j?b};b ×;q\\\.H ,+9Liidَ^(1JlWSkwRԦ'3=7t\DU5X1=J U]R:|?pB$!JaffBttө ҥCWfRWƂ5XIr'b)S5Hb>ʨUX7*9S^vl*zyY(v*Hih7oGwA|i*ݨT/N;MCz _,|F1h4 KKK~J$M$IXX>Ncjjj.]\] !H !bo&B:BY-BE>L|D [a+kdv'Àut/C{jn͏>Ez J9i Gx;W,iIAAAAAA0%(EӴiVVV\s rHN$IRL$q/K K\n?$]`*}7룒9@w6j΢vj'Nq" U;3 a_ /{MMcRjŲ[`[KKGAAAAAAAa9 ;)RJW*BR֤dw~PGDed2]ץl^7 ynm޽ k qB"GAncjǎyAR^q,p}i⍦f5o:;M?PPPPPPPP|r''[#MvFM?Ȼ+~0n;B%fQ;~X.?_ЎnnT8ᐍc.%~)((((((((,Cu(HQTb"IA2~ƞtĉ m'Ovӧ]0ħ@߃.0m \ajw: lXЯ2% :g"9DcشA{OQ^d'>,G?p6Ǐ6?0 l!qڻD/ \ނ-?;MRPPPPPPPPq[Cy . +Nʚ۱,;c%0 $q,j'N>;ŋ00Y{wC0 y0luI4X.QC+,5d c/d %-A K7E# Y B:'܏Zq"ss8[߽ ħD0H"a[-@,po8名劥JRPPPPPPPP |w#ncxWqy\[!nm\zjǏC=sڵO`q,Cx oQ4;T,^Xyh&~~(((((((((RRGuݰaN,Z?(bLjՂUk.GK-zQPPPPPPPPP)` %,$u64 K8u 꼣۸ym+@x~NND-p: \Tf%  jn(JϼٳnYhW>jg7= y0eGNA/) f 7.c1qs@X%!(ڮTmF &Oqp3f[4<8,KpQK&(((((((((((!\\D V~=h wBW>I0M $,wrR^.x,Ga5h}t2vj[Z޲n8{8b64(((((((((((Yv~aXh9dò.j- W,YRXl*zG¹e( bNO;% Ar]z)(((((((((67ӖZ>IENDB`sardana-1.2.0/doc/source/_static/sardana_server.png0000644000234100017500000320271012174204305023733 0ustar cpascualcpascual00000000000000PNG  IHDR?I pHYsl zIDATx ' Ʋ.*_+i3 jLD5)-&A;!!n!t=r!?N־*BP%0>?A;-w;(!?L4BP>@9lҕ&=/H,4%m ޢI3:cÈ o3Oc>#z,{>sTOD}"г>. //43~~~715 2A1OO~~~72'19lOqqQQ ƿ29@ 87T\HOO} # "OT(2:&&ss㥔VguOOYHH} 777pR"\mz٢.YFFFjN6O7fS:] x؈j(fS:tL 7&wAA!00>/T?;* }ꂞ{Re~ _ W BYwA   # ^ ⢆ ږz39? $%% !~ cdmCM`3{&39?=CI)8W' >DJDJlL)1SYcccfffH5=<0)1Q>0]*f3r}i GN.?`K ebLxeX' Հ"`[>$26f3GOm++$t!zg4gf3CCCCC= (((f4((8 >UHyNU~\F;# ߘ%K %2666_/`  a3\\.\]/]/].].\.\.b N8^j #7`tOg\Vj GJX.s\aNV' G,%׀ )N0{⻍n}{ɉdX߁N}--_1`2)Π%w#'7755j((  )07r2``(>}   ɤ \.sEh:\. aƗiih6///$.} 6h -/$.\. \.\.)% NU' )% ڐ'NU2?& NUڐ'Xb9NU'' G`RZN@Z% N?[$ H. P)\.\.\.ZV0 e3 e3U#e3 i; \ԡ1_`2\xFf8 \\.\___\\p¬ci{ dt*X#kwAZv "$zv{FI* ] ׄύ1RSlFv!]VWiZDá5GZ2/$K"EYG!ɓ0%+lF ã~~~|kҗ!.o)R<8vnc D JJJ{2'=? ʏU^^hd 5?6hhhNo}} 86ug#w$ LOFdd}}ȒEGGD!!FFFCN\5\UrrV[]SQO$+0ojyDDovvJUuuoʿN\hDDq vm2?F2?y#xY= innˢ$^" ,"rPP ' 9$Y+ Z- \E  L!҇IA^? RD!! ,13 7+#yy ``cBPwy>+6)&%,.07+# ū”iz!-3&'&))4;U4;UL8 $TsTlLhhhCwwwM[x2$ ! ! Bsg4!wusf3^L GLN:QHf3` Gg4gf3x,Os\.LL,OsrK$\.ܥjZx\.Zxxqx]]ccjbI GI\. jjjtF\.>>>iiiZtK"$,2hz[! FZnD445yXdMMMf4pdgN`#7N)NUNS *Z 3``ƐfUxɉfo{ۢPT)Zw#/<szq :Y@7"7 %O  b< {Xuİ]|N`N?"@' ' N?"@`U?VXb9N4܄ )|U?VW\lN4܄$|& G`' $|!#% Al$|$ N?[$ & #+ "-8x$ '    \zMeNhL}y+6C\.z}dC\.\.Ml- vFW0c%GZ%G<)%` %)n   S6 }D!#&!#9UUUֱ&HZ     l  .> wqpiki󽼹(I4'8$  GDARmU.> p m-%E鶫_`]|#dG 5 D{|? a9`%*.,(-*&.*{뎡/5 TW=*ug=SiV0!c`dt (}[pE8}V̂Şo f r_C^=GXt`B ^07>N ; ?qCkٻ1.uo]o]']pE}V )44D51āIBJMM w MT~~} } 1;CD5s##$$ H7:DL %0Ӛ4?~ D!R_j +KKrrr׻قB,6> ^Dְxϴ ذP(PgLXX.\kb 3,$ܐP(PȐp8pc}!4܍$$gܙ&$dI(CbZu7uF]\i~qnp8p>>Ŝd( Fgjw}c? g Zcf$'"!hC(/2Z-x*/Y7hܜ5uqL)[ 9RwsJ 67Z֛ؑ9My'Lڌ"R4 ??!!rR"[s[SS sR!Vs $ 3$ DQ\h\Xxxcr! @pui}]meLd'+' +/2~  II@4AK%/ɊH IL8 񝖄}]O,AKU  `u'Eb/ )C-! L7W<wY{*A9DMih zt'..D|||򈈈/#   5<#++++++///<<< L95< l; ^G  !f3~{w***P/Kz480S?{[rG G*!r}!/߾B V`N5(?БNo G[N8t}zv}zvfʌK+܁NG!oN-q/n! H1G(NW6 ' N[$ȁN* 8{`C Gf3 8$$b4''j:w(1b;BXnwŤ\.5oBXnw J|X0oaG UUGGYX@@GNUN2M( y@ GWhLMM( 'ƴ##A#AAAn  >  {Mzzz>>>\^0ya5˺hFlYwD^y^0oLl$5Fj8Ywh7Hci8j:qpP%ʹ~lU3BP5GXT5ҠNP/(6FUOIҁYn/Buъvy|N-_f; LNU|\Ȥo (ZkсNGVeˤ %JtNU' ' yee|aLLXgXUXUXZ֦xu**s \.X \zF~&&&~&~&~*ZZsuG"  ^0\ N(SOK333YYY\5\1118GWl{Mm?\.l|rD\L Z,]/IJ;Nb???]/ *5 \.\.f4?f4\.L&Nsy`C\{^NyR1~; GNbX,ԵK' XUہr܇ԨXA1~; GN` GNbX%ہr܇ԩWAZ` :1%b' K'  [[XA1%`b' [[WA ׉j' &Վ .XJXUXUG$# hh \.\ \..\\C\C( ( ( ( ($( !\.\ `2\\.\뽏.q\."Pɣ&]\.\\..qPPP.]vFܚ mW" kޒ4hd("Qa      g  Hr}4F%N2,$  !"      pusp~!#*siҙ>J+/.X?kK"V    T B$-99 _,=N|&@agztv{0F~F     3% XKMG <@tKD.ߴ?Tl񷰤bdk ט 2s    dA n<oorRL<Ea`>a)#*)_hmxN4lbdk, UYQɒ *RW\Lroh%u!:$ v M}`in-nd_'dD  XXXTJ`Df ǯ$ 'Ӟ.;n3{0#A;1oh+ 4Dt( 2wdM=\J@%NNJ]TQYh[P)dzYgK W$w|wG0 .3ɼG  t])C4>=5 氕wS M#|E$ ÷g< 04 HT~GsdZ&鵊D)KP ѶPcp(>>iƄ2,` ZX h ԋ @??>͓ )f!DjXT\fK-85 J% );X% _H-?N [Z@@~N'. b}qqδn1LgZ[}sOIOQg}2x\6)< LZ_=U'o9.02x}52LcsOTTUU==P,9%) :DV5+L/j@q@e @F"""fH ; ?KYd" ?5(KLFptm N !www"""4*OiIz r -:64+c+4elN)O[))"www{{ބ4QQtdX=83E, ++L&{{VO ƨ(2;+( _c{uYY6 &(2lll(/Čr[OSKF^S]_^ŻFPZ (2 /wxO%.9G,C  }}Zgs<<ԧ\/\ZZZZ:: ,B %)JW&00\/\CTD#DŊv;vxwE ZZ::*97x8 [4\ԯKETa33,( "Cv;v&&E((8!x8[޼%*ڢ/  \\᝝''((AAAFqV ) {Y fՂ:);*xW1 ao www666SSSVVV..._E 6)h3Iik<|nitkZ`EM1&TU˕<20VVVfnWl~F/ w_.pƽ3Uj{p8aF9BbG=_gˬ}% 񍌗wyq\>=c7_ VPGPG.ĺ1 Zʛd/ŕPb11`bo3c ||""))AAu>9P? !(|soh?:AF ǿ0O_ Ÿ2?MݛʅXgh@@ %#U(&6<& !&*!&*Zj9 Xn #44}mO\h"'+!'bS7`QҼQt~~6BKԾSbnBHVtP!!fx'P{/Z1Z1 8jJ S( Sbn* } 2z`yhak(v"&coIF2  !?)+3N4Kp7€[a|)19%oH"&+0 """ 黻"""A G1 @*2:XegBBB0bE ᰩ PWTTT777...0 64! PWVVV<<<hh>='1w%js! &/ppppppu#64$&h6:5!3f3Q2PKNUNULbLr}in; ـ+8t*݃#}N剎wr?v0?БNo刈xxHB LWhсNKz}ifx߆ eB84:A\; QnH{]? Ag^wNvŒZ,ϰZUd7=6f1W6 Ą]gƁNxv/C'  8g4gf3 s}zNNM YsK_yUy=L\ô6mN³k %^0jDpq  (p"-8=KYõ  (gkkklllkkkU byc), f ]@kUeHeG GR^L3NЁoߎԩWA8%)WA܄$| GG& s[[$|J%/:=44jH?M\.CW.=M $)4   #)/)33wwwxxx/14!ud6ʜdddbbbCVha|mDOf|Ulf< ddd77bccbba|٫}Ul˼,?R̞bbb ,7@n,?R4bw ,7ðWUZ,\< _1%SBʱu:cNO&T+ GN``"ye' 0'0ҙUk@іRіR d4ŵ;K\$.8!#QK:PH7PH7T5 g!Okkky\\8 5iĘa5/4+[ fAAȲu<cN!!\.H_uCZr\.5z~_ Q__~2'2  M%\.  %%%%zN"Z,\^0l>\\.\糳]m} MMMMMM1wq@ek #'vWƸѩ]wõl@eEXk\.%*/j`2:GUj]w0=K0=K DFFzd8 >Qe¯_2j_2 zd8 Mh\._2yLav{W2.7@wVk4AṢYw -;/25| E\s-AVjlmȶ7J]k#/:Qg|Jb|Yw/?O8DOh7@Uj 7J]SkxxxJb| Y A' x}V sAqVN: V;l9N` G V;l9' U9ZV;N0Ёoߡ9 Gq3Nl#M GbJU9ZV;N0Ёo߷X?9l#M G`ISU-HjySU-IYi.[\C\[[' '1s Gp.[\C\[[' ' ' G~Np@ GN`beN@NbN` GNb GN+!7N/g: `2pv1 BwN/Op q*\ 6`x```p&''~  ###x    !( s>JUf D# uO(&B5\.s¶pK&$s_nX3q=k *FWwG5* >Mz>v|U=U]3d&/PHD8AX`s  *###uoh9u ^ \3z !|օV- "" >5* $"D"uGA$  3nw4nwc4k`ak," 9iw"%(   8EOˏDVj5K†B9 |i  z  )qY&_*)XD%f9ʴ{RA.ц_>'k1:41.4Xf ܙ(XY A0 j q E Zz->!*L%/ 'Fe1 aIpn,,)^i M* /*ZdY7 TPBnnn;e&l+jMP9 6Ot$vabS9#[z8 ΁ nv5nv5 ) GFAh/[I)t_6]tqnjTPC復)Riatp `D eH  k/^ Ob@tS dG 6y N٩7eOSQOlZc|C ]FAbP%ztY#7IKL-& .;& Rjl}v/ hhh \.m7 pYK) wV{Ҏײ/F@hȢovLʂI6m 7e1>J%$"c|CO.t3 1 w. "!ޣI ^d԰ű.;( '''E05 \7t ҿGzGana{ny\H \u{f. 69C2  PI - ƀFF{{22>>8AH}V-dWH,, Y *{G=5%NR_f]G$Tqlɗ~n 3Z^Ѕ"u VrW *a(ȫgrr A1%c~ n =@:*j$110 }S S )N|;qrKW`O4 B>; H[_a0-%!NR_~^=7:Q~ o1{f{f*9Vk:W66 @KTbadT<;  deY332ee`ee` vv 33<<((P֬z!;(/6dS[ع-M"'E1 fs811 02211-S poomxEEEdd6ffGG,,,[[ } "B    oo"+16z&P ^C\x GFUUUffN52lߔGGOOZZffM6'/#Fiwonz^8"$).Nqq12&&OOrriiMZNNFFӦQ*W $ރ""* 9BJMLI? lVT``` Wdd,qqaa  epNNFE|ZRZFFľ"S=sxt  =6/ 1kkkoo||  ekkpaa||SRBIII %W   S=7Bg!+ kk}}}IIIVVVmNV_:3 S- AF]wSZ5 c$ 0/   YYYó FFF@@@444555vvv%%%|ղ?eOL 5^=4 q W  ZZZBBBBBBiiiVVVװCXXX"'+"&|ty~>,+48Hø WN@f [\\"'+ L;E1?/  NE==HK$.8 qO1hEE2J >7%*.2 _XQN: 璔E1? Z*ztB,r&.刺rJI0' чDA&Z&{DfS.a f(ĺ *3Y:a@   @huZa t{ty0 ) ^_<tE+bw xC $!]" {|&f567>8FO R<9ldI 5  [^h՚[)))ʹ(&#E71(F2Eū&0#핒t|ſO]h~[I8 "4M4M==29@29@`c;5  uu Uk=Z~  +6>7F! DK b JD>ov6;>Eϻ!&*  Q%%#f zr0V@!D>ULB&1<?[HUa%1<035FM 9+   '( ADV  CQhJKYd JV_ , "~tw%8xB `daq\s2)/ eIst/:B/ǿ4:B wn훟KKJ  ??? &`edB,+w.mD. ALVc-5=kkS]U0  !  aG!7+ ) nNAMXIIC ]S55"#(''')  lL䈈81"!& z{WWWWWW$$$$$$tttnnnb`E-"   ED (xx'''kQ nnnnnn____F8*  '%#,;;;L:L: CCC(' '3w~raba ssssss  30#2|#HnHna9SH=2ti_ti_ׂVDr XXbV)ׂVDr yzzmUeuڱmD]eU.^C<n:P0.qﷃ_d/N:wY~ﷃ_d/:8xx@mD]eU.[xz^fBBǤ}Q.Oim\< ^H7IV`^' *N'IV`^' Jfp@BBǤ}Q.qUP3n9]a9]R~./[ӆ)&' 7l7ΐ7T&qRP3  T&qRP3 ՗yrP3n9]a9]R~.nLL?-z- GG&{t44W``' GG +iiLLf3SOO OOOR&&?PPC (((_VNb4  ))CQ^lI688?KVppRqq}ʅ_9<<pŻi"-6^0MfyiBAAAMfj: .?Om= U :W1SSK E  rbS $ jS> ;  jS>a 1qJ$ p ]~^'6B!iJ'HH.]J'H 7 - BR  H >0d H >7"]]Xb '9VSlt:Z[|KفSTiu{w#3TG!]+5? }[(((48=_2 (c|wkkj(19xP)pxK555))ZZZ_1xSjkcAt jAMǻ[[[ZZZpH!{O#@VkKd~ $0$).oQtQlAVk'9K VVW -$XN>xaV0 NiсTX|,,T SUpv1ʦ[RW w/NO!**T"$- $-|. 6[\G`BBxGG`GG`/`p11((ަp \G^uQl }LνgTB &. F=3]5?82EEEEy ,J7$%\PSV%&&/24<;;  es(8GWTT^0ui;!)2Un.;Hb6 |U1&?Qb^:!(.8@IȺg }^1`2_2 ع ɽb/AUAUv]G3WWW#-7ȿuq^ؘ1@O@O`3#2CXpg:` &DdvRwmZZZmBsP)6CAWm _1|i8 a3uH}S'g9$.eZz[wk: j:6Vu%2?#9O5CR7J\8HXuU"Hy\jcN&<;d/(^죂^xX' Nr ՂWFY U )Iy+#N9'XU )Iy+#O0}ɤn׀ >a|Lw#3TG!]a|Lw#3TG!]a|LۯG3fU{N Uύlq}[/hH2dR{[/hH2dR{P;e]E|kO'b v}tM%{5CR&.!#%QK:'  9>'PH7'PH7\5a(k rg*!OEFIBf qRyT "-8Gʄ/Kczy᭙v /4+ʈ9&6[ʁP@dܗ# xuK+dTcNy;M`PlVRj|?Uk  ;E5z5^~^E~E_ ~<~~E_E~E_~w~w_} ų W_hu  .Я    h<d(((  R/ ....._1gc^tXp`3 ^5 789222\((( RX]gvƸzpgHHHZUUUmwSdt|t\pp0`Wj`WRRR6vn~vng4.lwA%V-L ߑH#.3H(ǖ5D)r? mR .H|6T+xh<b6 |!#+y@JnI5*|  n~ uBN+ !ա7s - v ]jnM1\H6VĦh/+.cyj?6# $,0#dR'O n8>j"NE|Oj諾*#:111 { 4;%I SdZKziAyv!Μ$U6#)L [[W4t@ZL>_~rdS4)c!`D=u= ۮ,_cbv   `C`CxDR-mbom `DT@DV>I@68,Ӿ0kG Ūdmu  Q9Q9phnL7 cpLPsmGpOZBTصdkdK>;0ͼ)#apN-B ݛU͐rUj~  ECBq{y46Aó@Zf+00   `C`CH@ $zǃ?W%TSBo@hס #"t_p˶"6Ԍϧ^j~ssupu2O<+KD?8319?^[`f'*}   hgfQ n``Go'mycVcceLwq_ЙW?g`>rssuu2/& LQX7&A=;   :jElA ʓ *Me 0?DDC|ak^wq_9Ms`>XݽUC?>horC# ȿ +!ûV\` .?%)螞9itnoQ  fxBV7hPl"J!x 7"7NDDC\> #c7VaLH 8AM?H7?dH$ 24<蔣=L  ki YNzD'~چA6((' )ֳUnΊyg7   \` 7wr޿>Lp-$܁ZFGiXF5#)=۔"SJZ;3=g$MJB/nO7(=x uo%NE^! WgrSwcㄮ[j[VېS)5"AM8nu#.26ꭝK&δS(K nz`.9{xxó@?0 ruqx.^X, O8 pP' ~6 %g㦇!h;L>6 Q0 V :1G 260S}S,#х/;`%'9Ksvr ʰ7aj aG H$5 EaF ]B  a v#=K`F lv |zLXc"() B7%Xb/՞~0!ٞS+HXIg ++*,#0}l(.84/?Q^MvoO^Ӌ  Y2En SﺄL{ ee""P!(&ڽ"9Vɲ CE C=)6'b"?:#T@K/0[`oooX0 |vs8| \? [@  `M %* %0"- :kB'rSS }}}}} !C$c@922м,AK:=ui!##D8sVuBck+  °cH}c@ Dj7GS 3̉.fX ek %ZZu$19!ﶙ![N٥lf)GK:܄ <@ϊi1vM_"8($*X ,5, >PV>78%xtRE# J'K)16գ_be[/ Ro|'U_E_   D5D5O,'m,3$|1vUJE/jt?-{ LXOQL\cF W= O  f*3;'2;\Xbba+ y PHOњAx'UMM о DOX"'HB "@S{XK asiQE4JݚX X*gǒ0bsr __` +-311xxxxtua(,@@1X321+' @SXK,:=:=̃ 4}̊)Jkݰ#߽@3ޙ6C652###KX[hc_ueL%:W-}D b%!A! jpu 膒  M5bb95. 4} !4q4W,W ,W#!C3%j[2$$$ u::44""%%'' $/7G"&KW000L! ͦ9Sԭ ENW%:Hd. '/6'/6ߪ|W( %}0A0M"4RQQ55DD3;B'''AAA۶I[kvJ0S(  >F;c[ #$1>JJVضD PK%777&&&444JJJ***ݠJ 6q"  '#qi4O  #p3Id)(-5 ******\\\= ; 5)   D*vʙũqg,9a#GMxJ}=! tt  <;;!xSxjLjʬ;qX541+##$, fɿDD..%%::7  tt8(ERLoM2&& 6T~6TUTN&+H{{ ґuu( bp} de-b_ww%YDh}E`#X#!!Ž ",ճd?a(. "AlXUSijkQNM10+ DF J99r#l#`K{%MZ]rhg6iEkNG'"A}&\]TT^W WWgI 쏉{r   " R h]:Bp%%55&&\eT "-vvF-&333vʦ|au" s  -" u$򳭨#'%+0   fff,,,>:Fth ЖfXpZ33@79ʦ9hh0- <,9D$޽C@ "et!&&L qCOs |z@%x777 KW֏3VTf 趯#N ]{^lOs$%(?Lj%@Axuu͛e3eqqq%%%&] ~7 㸆ZYA ).3   ^@}?}uuuue;e sݍ##Z]HH@888 ul, 03#"#;BGt``Puu`,߾I;Bk##dII@hhM""">;>LL*3Ⱦ#(.ꎎŗ* ''xlO`,+ B!BpdyffhhSR8( U_ ĪuXZE+ATrGBH&&  vvvKKK\))qa+ VVUWp ggvbbSddpp% QH6@mW RNT:uuup11))qY 0qq.3 wwDggpR|pspp&]Z\]\4 #yyyy@NYޣ(˕/k<< YYdX OvqqQ3=ps88V=   ^  * SSk4k󠚜gmOvQ 'rJY=*,#7n{SS  '*gwQ !E>5Q.h& .  ,( )w`谄(]QP*V-'g:)ъ ^< LL 竫,,,WWWCCCiiijGH*3JJJ达EEE666```nnnCCCiiiu#ε䨇$RkJ/!!x:c\*blG( Y2MMMZZZ````x~iHdbYJ##% 8%BBB %&LڴySDPUOc>%S`)0aП***y5 --  )8%-8*tˎB`PrxZ]wm9 5bh$7 TxjX ~vCDNlvC*** H H  0G` ! !-M-M Q g3C rPesS  mm}zy  Jt,%kX7 .d/ewV`  II<:V\uT$,,lR  qNX5-Z{ ׈|yyGHY:v5UX!3pm  #%!$'  ktH;Y ! Ke )^^ f)D-˵:һs|q  KvHdpB偁~^G9Txat  "%"%/=K8n !"m $Q $$   (5KbF4%& J^ePbpȻ5AI!!=++iOq |~Q0aDII # X' TE ǻ(>1 NamPbpGg5tttt鴦06=>HPq.fd^g22ah9/8@$  k5FI?2%  Qao#, տZcD,k '%*-4;@B@29=-7@  8!"!" f $jҞ"#ʟJ[o SMTNU. ! ]m{,1-jW :.b!oK6í&BUK@7YKk~=  9CJhb,1-> o. #8d ϳBKA? =GO "52-" ><a.C<.     |'>\\.a*35/&0 ^g)k{P\f]lx5.' a.Q;;1 rw㹘Y5J^  2[<.2$# NYc"ƩP\psx 5<K,H-s Pr.$+ gj0"Knh2땎sbq~du톊 > %$2%%%% 'NZ)I\gar  %0$ """ :';0 \m{{{ )E<-D+++[~꾑o2+` :+  -.ֈ;;;♙dddaaaRY W> B> kk kk ??????ƅދ???J7+-*1::: CCC'''&&&YB nj 4mmmmmm-#`?;~$$$uuu===R<"hd **1 ZZZZZZvY 솆SSSiii$$$U>fb .|] SSu```mmm WA\Z **1(((" Y8uuumbbbpppz$ 蠛|y SS+++nk  7777ꆅ GE QRQR'3?G;/ll jh z{~҅es XV &~S'o>(g4ɂ.HmjFN9' N'fwɂ.HmjFi6θ~N!fX' hojθ~N!f>??-HIay˳n }ﷃ_d/N/Q%X?^C<l,S2^C<LN"j }02 (^V3O)JnHaqÇy=B N:wP49$݃zy<f tS_$݃zy<!(^V3O)JnHaq&&&!\\ũUL?׮y|@Y7)*yr>:0  D*yr>:!\\ũULw$>f>fN"5gQ [F;nQ<7Z [F;nQ<7Z$>f>fNzvwSN/ (/DD?ӆr!/DD?ӆr!^*3zvwS0NNnZIi=` HW6 ` P<N) ;сNP1NUd;сNP1NUX(jyR0NNnZlCC'/v/v{/G GG{/`lg4g4g4C118667 !e++.01379  ]vFZm˹7""...^x%4 ?33===fȒpN/:G-/1a1썻%)SNImAr789`1&<[z333ɿQkBYm6qQppptTi8LfG^v?Tih7 tTp XutaC0*3) r}$3) rbV#: 7A# x|01n&  w n& >T 9LnG ffwl  ^b{(i 1P DErn lA ] = |0DP \)[P \%scc\\TT TTN&<;d/(X' Cgx}V\NV w#3TG!]>>555‹)4? '-oPJE!(uuu@@@;=>4PnD[q%/:i?lZnD{Rl`z m9J]W-Yw.=M^zS.j: *4So"-8 ѿ y_ Mgh6[yKe~~Իȶ&/m:IXSD5www!h7EXk6vnOOO\2"+5w{]sO@SeaBOOcccxqqqYwQm0?OUdGLJGiXb '9VSlt  V蝒~QM:Oow;-8 h . h .ł~;vuy?|K% h h.  +WK{ o* o* %8E9}8|iD f,D f,Xb{NX' bN$4I aڼL>b& **S1܅l' zn0 GG&I886ԂcS|w#3TG!]NHxS\n.x{ 4b 4[)I߻Pm-{?i +!G+!GExE܄]i , PH-UBuk#4H-UBukR$wӬV˗"Dn[lmN9' X GGSS`77sD77sGGNN5x5΀%&oςN(}% !~7 1pCۏ6o`-W7tg~/NS9N+Vٍ2&lZ)N+Vٍ2&lZ)ф*]T'aGb@dllNl)N_K ynh-.pa`KzKA{_uS*| 7qbZ*| 7qbXSsQy_>N;Ƶhwi   N[I߻PnT7DNqg~Qh. qA:Nα,ExDކ]icEEl Tk^POf}#/: ȻtVHw1-G9 | 鐐e k!!sh]H^t OOeee^C;SkMf666 KKK>Sh 򲲲ɾ )4?d:7779L, A@>ij,li;',+i<Z[]}sJ"þ&(wJ UUVq/6?͎r13OA89; vvviijAAA ӏ ...\ !$']w1?M첝@<8qgucQHHHjs|/62& ZsZsʿed+ a}iV.HNOP/0')6AsOPQUl  }`ɷ]9F>7ɽpPG_y#_~ʽ pH 3DUwSm© ^ocp_NOOOYs{`7J](3=]w_1:NbSg{cce>OOO)4? )6C)4?lCc5 tmAuG]vWn1ARyXŶWu:M`}|8J]Z0Yw.=M÷fCzT0k: )3Sp"-8ƼkRlg6 G^vH]rLf~h6]zMfuƫͽ&/m2@MfXKjjj%g5#g6F[n+sss˾{t'CCCkFWWW_8+6CuMgsssgAI]sQ>whhh|||Zy{YwKd}3CT>KW0@Pݰs+S!Xb '9VSlt-tNk:Oo nluy?|KnP +WKˈ4L%]b|A#}8|˗"Dn[lmXN9' ˗"Dn[lm4\VAڼL>b& ΀%&oςN(}Qu΀%&oςN(}Qu i GG&I~7 1فSTiu{N+Vٍ2&lZ)N#?d5Re{#3TG!]Nƨ (1̼cwi   N[I߻Pn$ #@PZjwH[p. qA:Nα,ExDކ]i $/<SC3Kaw ,7tVHw1-G9 ٽ ywvp/62uIoF[h: AA_xL`_]### 45R%llkllkyyyPPP~>HT㚈w!!!m~-5>ϕsA71TCtg41B%xA !. m 5$k;[1 ]quu  K&~7z| ,J)9 Q"G $f+@ x E'H'" !K*{C)A &A;    $J(C%   Z;ҷl [       eV9#'  2L*3 `Pdr~s;ECO1D>Xe7\EFA3-i0 "1?    ZD_A)!C&K) ":* (%%'jq{ %P]N9=3!)!Y?Y?*K*?" }toL3Ilz5(ٿ.'AMGDzP@]Nt~g  Z5 +"!GZJ  G2G2 :"M+-ͷ49K.AMGERCY 7mɓ ۽9a0C+ŚZ;fZA-HC03. rqhzql  qOqOF(K*  ɓ5,V.88A<{څX&Fw_U>?, sip@1"ξLUNU'*  ++~X /N+9e8 6l'PѸb0Gob\] X&lPNXTWF  Ƚ( 3LUVD#&.%:J(>O >J^O"" !ĻLA,(@  6'6'qO>$O+*HHHчŪiM/Hd/Hd. 788Ec]^R`X('_Ue20. Qٯc9ADT9BN$0Ƴ9A9678 %0 T)"&@46 316  J4J4آ +Y⼆{{{uqjimr \i[y HH{iMR`[20. b9՟">npb?Kd,>5- Lf(FZ KUb 'opn$"*++jj^! #    tQtQnU;+ wwwTQLorvK aJ#ʑ 3l#)&N G » \fUt}czwG{i7F&&(0ț!wcDz{znYL(5usq1vO п9lczQ}X zo0Wv1 3®IXarRŴ #,ķzhe K++ u "%   eGeG&micxy{!8P ЛM>"p P>BQuLWȆz, Xub 0Ht89SzmSD@;\u,뫮sM(dAmcXÿO& ΞL:Ƿ B = Kh )     ((X`n --,--,nXܷ~~~ZVP^[Z4K-&y R. CzŸ3+í[2*Ğ֟}Q+ fgv3NQ|F bab  뀄ɬ3R'K)$"9KC@ļL>U ഴ *,B !h&zh,) qR@/ " kI8Q`+fP~8 .Ҧ)|T5(}W9'G@^bIlըƮ:n͘'g~[_ +޴#/}oGX]\ٲ 0&32-TG4   ZO൵&0F#e T> rS6' ҙHOHOPxx(#+"^d";?EL'Na`67 &2G]]-*vUP9  l  )!D &X@ \4^0:FWNM;^n>i&:`z6, sVgf[E.-AxY[biUD Ҁ,:gT6%K4-yY H 9ZF@< LWd ػ,; .0. #B0 D1    XS c |+Q vi4QC.]T +xuY> $# wjb)#(#~[# ѳ)J]SwF>9۸"#-0(&$5&;*>-ʂmӊa5\p` |s,W*{X@ bG2$RKyy,8 $H=zgNR#Ӟ&j5  yW=caJ"t00杣t]C$#c'%<{&`J1\ /M`ggg*-.6=mfTӘJaȶ %'0ۣceg8K( #C0B/  7.c@3!(,&fYO2-7/7^ D :C+o_ ƅEsSu}.hS%eI !.9sl 3'?U+ Q[[VC Ԓ7 <6"<6wqM++_C "hƶ𴟢Slt ݩSD4 -)/F9" I HVP\&7'?/ 89횶 gA/?-#BX!%+7,5/C14g ֛ߑaff»-4: $  8?CkfaHA" J^/W_4 ZA8C989,%\lX0ksA[ܾMn^yxEa +$ VuVu pzx 61 #bb#Q?3SI4"# 9$"p  L7 L%#- dq_~A  Gʼn  5c  ТȎ[[ Vcnl=abJ!F91DBAA=; _p}Y! MR).N6rS60=.^CD;v&V m)i)i* x'a +0   ú+8@+⠐%"2xD'˘a6E?#!$\QIE0:? +-IPQy0HF0`O ;)4F2 FA @=j Bui}":)?.  j<( ٕ/,.5 z0[%Qhѳ 0mp vsv)0 ȾTh%178Z-&$^K`zK2 oT=PLNrnll ئZc7  bD@MMS+,v!\V= wQII1;?BBBe6Hi2  >oD uL 5%%U)  ׍ %/8%*k v &NLW\ oN6]-ᠠ7_Ün $"ܞǛłfE~*/4BO\ Q_@Q#yEg&0*v  P4~d8K ͎o#OR#? ܠo=gY4YM`Yx: 4d!¦*>ZĈy63%5=6iV= v/!6&P uD*bb|x¼5W(*OU_ m_o AB E*B2ÛllÜn33  $$ #"%+  =CH olϬ$2#cqq0I!1Fn2r(8 )]WK-n":$&*>Z]  Ń  ?uHrDzh-`^?,g   ';Bq{ ." 9C9 ˚ ]^#++8B  qq0 '7#"᪫ٮr .ZY2n΢;inbbE)7/ *G3dn hͭ2R{$$BS@R T- ":!(-gT+:::cc?y DŽQ3]=7L#"zGG)((*5*0>>  AAA}Eˆ666gXL% @[9[9d<2 &=<=;:;  nػ A Iv4&2 xur !!!!$$$J}IX $5n5_iq%  B >+ &?00//fUuQo+SzT]bT1[6!+2q}SD3+ڊ 𸸸830#" ooo<< P:DpbbVJ &,ͺ.BO ɿ"%(]>ƛʝ1!*N KlYfSgLF)ff29?aR:ꌒ P *^^^^^^ 33333.!4"48.hch qmi 8^诌  |bD  sᔜ.'-]\]X1Nl tmmtt,.0 %*! 33((rrr9:Aէ۲ii&& 0 !C3?  Ⱦ /!  K Kkkiy * > !%iecMhM2Z]^tY| k`n >?ɴd9#]&Щg4[M*f,f>F  IKʔ::66BBBAAA~Q!!!gr|dI2rS4[=!% /F4A嫮0,* 8* XRWUTnjn S   ; ;"I JF~Ѿ  hz&&&KKK -Dp8pddN`-\P~( ^b]WMF@÷0 ¹$]]+!rmqjj᪘bt؄;;9BDA qoΘ  o FD;;;KKK ܷE"EA D//*x„{={a҂&&&&?LY,,.9FP  @/nu!+!O/*#F6)y~v%9e`#Q!ot&ځ)`ݹcGwt: }yt  giZ#rI$IHHZۈnx$$|$|y..==''Bccc+%뺹 "D7ڞqDOL5"otځ)`#Gwt:  ))H$HZI0rx% %? ==__BQ::yyssE֬T+T::LL,,;ccc1118WlZ51{vz vGGSqC&&    .7@!.9Ƌ~?~ff$+ X,XaaQ::CkFU*T ~)5555r++#(瞐{}ƼD#DQvv!} &&&;;;JJff%#!XXY h/G 44߁!!k6kCAI F+spp||(w@ @{}bVc=:DlQvvp[[~!c]lll&P0̼0CM0BQTNO8HU/G 4^֢r-z\IO +,-$$$핓ZXVuuuttt```PppI5lGG66 $$33OOڋ&&!!" Cٖij%%+߿A!A|nwl?b^ceel͚f3fqq[??! ( ']\]" 7AG(Dp~ LI""YUS ֢rz2\O luz lnln pp~ 66$$޽C"Cms" 1*SS%%]]&} A!A۶I%IV?ʼnw;wm>>ee!}}f3fAy=xÆz=z Y]]G40$ spr pXjD5vI5vI5  |l       -4; C"CggM!s1*>22 ~~J%JKykw;wPP..!~y~xz=z00 ?H5 ]B ~*(     W jblhy y M IHْ~(o22yy|ee| * bbk6kwwxxxdZ Y ׺T`Ai `y55 XW!! ׯQ)Q(oJ...;% :PJ(.. ;3 Cg@ K## X> {P uU (.3 nb T> . N&# vW w  -6U    jX8xHdd-rZ r @G ՝(AAhh2277Q)Q^^^>>>(^6=2o`g6PeͼoğQKIN}ช) ...---MMM___ ՏgRmUT _C _C ƣsss 333###QQQ//////111111ñN110"""  ((XX(1970+ &iiiiii (((((( IIIQQQ'¢ 332>?>%%%bI>`%%"a>t5+"H !]=30 "lH! ===''''''s/ `1B߭!Sc"\ޤ9nOHFH=}A?NgzOW''j, '1*¸%. "mmmL>wOt  :S-%n5 9uf" &4}~R)BU Y+g["!Sc̔(<+Ѵe(` ssss 243xF`Y〵5=5(!ss ƭ}* ޾71fe1F@I""444 xEwkKts?" ju~wy0WfxbU8^mR_{(29z^TEAA򓍒paSB1"e112 ]5 $ 8$3kzm앃׋ 55IIRTY+,*. %*  (& 6' oPv 5Fv{-!Q^}9)F&1u|xn"0T72! . {ro    >%&&7,(2)N^8N77<#AC <,e  I04#' ,:Rto=J        Q:lJ R- 'LI$Zoե: 9wW)?e B+J1+ 6   B6YVNWr9- U@ gN FqRtp$)e.F$:$    <'I1(, .C3  V;sO4$  gnR`Z}`k0# Ѷ] 'G.+  33c<   hFI36(  V`df(c"3 dqxEPKr  T/a5  Lq ^@gG+!  CJ||))q,,   ,     ?0I@]<_%LbD^@   (( FF]Y ZY{222 L 5e QfA zoC" o Ze)9 cBfm,ШґG#_   nnqq ZYQ6洆ѻm!4&&- ZZ ffpTQ h T}X0%ZBS9Ր  p !!rr^^TUU=Cm q  Ɵ4Yh5U' -ͳgcrMt81 G  A ݋e o]hG)1 ?O uw5q8~UA6/lt\V ;X,jlcc""Q tofR=+7X3Z;?8)H?1 ! qg&6 !"# =)|YqByk" G1"&* !+gB QQ;ii;; @*$&,Ȥgi:>7317=Rb.C o   :AH !23xznر%6SʡϸqP}Y #(utwȿ+3;@LWZ_d$,2:> LL* #%  3&  #$.55K|@0'\{@n  \\pP#"6   ZYY[ZQ >O]¶6I%Ǵ#8dJ1DѵHiWr!& HA[718>&,1 L!( $7[)BY@I@\u<3 ~kf'<7024462-32.  [<'wJeϗ9Eǿ?6G0 (#!"j3 ?KUHe~V JKMj6=D,3:   7= BABK   "@j0XA)B*  d "~¸ﯦ޶AIR 2-  TS51fc&FFF +֨ GGGEEE+++ :+ YX /KKKKKK @1۷444@@@DDD )3%  [Y!gc%$  )222222{{{   Q=⡡GGGDDD,,,&3' , rﻻnl WThe -######ggg %׾pHHH&&&BBB $2&  럞燆:7|EENNNNNN3& ؖٶ1 pnFCro abab두a[T333444||| 腃., DDBCEJd|Mf;=///yxxt IF ____?CFE]tw3DU3DU68***mm ]Zc`$?CGBXns8J]8J]1###(    g4f3dd"*g4ڴζ"(=*Ca24"Xb:X' Xb"#,!;W,*ڴζ"(=*Ca24":<>Zx6ծȿ ,T;Yb$ 2"9W=kꧤitf-}U5¶1P/+N:j  777j[2 *5p _``` =Ib5ܙ˰_2d9IT*0+  ތ5\Lr'$ܹƖxf+pU 챩bS[: ߇o PXr<֬Nތ5\Lr'$ܹƖxf+pU 쳮]7}IkJ ÐoÅ%p\ތ5\Lr'$ܹƖxf+pU YZԑtט0} =Ib5ܙ˰_2d9IT*0+  ppppppSSS,,,K}KжҚOGoD]^ "tt,\MZfժU' #L( ō3L( $E;xE4n{ "tt,\MZfժU' !I%$SJ`uݵ\ "tt,\MZfժU' 8K}KжҚOGoD]^?5b?5bٟ||:owE ︳sc## !!B︳sc$"︳scܳ8?5b?5bٟ||:owE rͶJj& 'eV]mˤE$ůic5J' ዕm+ݷůic5J' ዕmůic5J' ዕmݎ8rdͶJj& 'eV]mˤE$  ̪ L9JW*1/ $k" ۼGҩR!!@%7m]xs0VED7ԨzۼGҩR!!@ۼGҩR!!@ŚUX' ̪ L9JW*1/ $k" +oҶֺ|Μ -0ZWV$ %>&^m 3\?qF&Ԓ=X\ *swⳄƒ %E3YzueN %>&^m 3\?qF&Ԓ=X\ %>&^m 3\?qF&Ԓ=X\ ƨX!,$CE~13"+oҶֺ|Μ -0ZWV$ 71\71\ F`F[SG`O\OMM F`F[SG` G` F`F[S G`71\71\g4g4cjj,T>5  ```4//88waahh***X^f (3?6ET )2&. ddd'B99|{p3AOmW{ '3>'3>Pg}!'ᶵCCCZee%]]]XOGXq yYIII(((ZeeaaMMMIQYea01jiir[UU>>^^^qxǽ~_&0?O&4@"+6 Ŷ *(&rn wa~{T/p/?O,+578;K\oQɼ  8HX8HX__^oE(3űİ iG kڍhAIayLeRg H`yayZi\ƷCCC'4AsE!)ggiZ1k: SoCYp~Z3'3@CYp@]y̾222bgzaH1$."'.U6G Z Vc  } S( Y !Z`  #]` O C  <3 b^= WeW ><3 b^ Ux Z an[ @# gq! o -*  2 -#D+ /q!6L w>~D+ /q!:S@ M L//h E>4D Z Q  `Q:3p T  D 'i Y  ?,E   l K H)cl K H Y  1 C|Mb nnA N#[` b:* >% p-nSHw  p-nS>XXSS8('nn'Xb:X' Ӫ=Wm\ - - 9dMӾoHV*|T6߲-!=a>WU ߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98!-@~g֔囉YDo;YuhaJYDo;YuhaJ $`{4q˳_P/LW݄tB)w_hrģ)=V6 Ol}䨖=Wң)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n|Ǟ7` KxKǒ AkpB ۝S Dgl<,:^Ȁ§1p=⫓#_j ^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B ƨX )#7,O~f A{?಄ot* At6  A{?಄ot* At6 !4zÒ@9-ta=* G` P`P P`P G` >xT>x b lttb55k Mcyppp AAdddvvvVVWKaubbb--SjHH555RRRb4 ((( II,,@ۭddkkkNNN%&3@OiAAAtss1Q<4 {WW||F5$)vYwddddddⓓ77t???:N_#+wwwTTT???+))h:JZXXXXXX)'&<>@d#* *5 mmmppqyS uts555sssTTTAAA pHay ˜nˇrrrAAA !!ʻrL'QQQwww߽F2;HVfoK555CCC??QbsMj n$$$!!! ***uuu______555%%%r$$$###yyy|||///xxx(((}&1;4AQ&3=&/̽UUUOTX 1>L1>L#/8´ôIJI&&&C@> }Ŝs&1<&1Qf vhCCC:**.:::a?-:FqH iųQhOf~P>RQOAm؍۳˽ cddƴȶ !|||<<ïb!*gb '܁}|z\z֍hBIayLe7J] AAA3CTnJvNh"MLM8J\ŲeH`w 5HZNasDDDssszO"Xum$.8p@&3@EXkEXk~_|| {O# (CWj*6Bo@g0@Pc:K[ c<>Sh (!(DVh;;;Z02CT0@P)7FGQ[222Jc{Md{qWncB !U+m6UGQINQBݯpV`[1Xb:X' Ӫ=Wm\G ;=maE,g OLog0 - - 9dMӾoHV*|T6r$@~ o 0@~ o 0(+- /N뿜_ -@~g֔囉  5^8: K^8: K  78 8 "!.>Ǟ7`JO)JO) 8etǓ5dʑ>Qb۝S Dgl<X~ oX~ oXb[alA:X' AX' Y`T͒y?#9,d}/ƨX )#7,O~fcc?cc?Aq|I T" ߲-!=a>WU d~ߨX1P/߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98!3sU3s G`;q:dbIg0|pnYDo;YuhaJ0zXb:X' WDo;YuhaJ $`{4q˳_P/LW݄tB)w_h+VAV)B 蝤AH+ģ)=V6 Ol}䨖Cģ)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n| i-V{w"az S_i: KxKǒ AkpB ;LwQ}w- ,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B Xb:X' Xb:X' /U==L.  A{?಄ot* At6  @Pzc]N]"A{?಄ot* At6 !4zÒ@9-ta=*Ɗ\ 2mBKC$(ٵƠ !]UT4  G` "uu G` P`P 5e P`P G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ#?0Nr98! ŵ;K\ʺ6FUϾ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW݄uB)w`hwvvk;K\]bgk6FU7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4?".;$.{o}!g;pG 341,LؾjC +~itaw  `g`KxKɓ AlpB  _^F3SkNdz ^0v,8E%zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C &F6'G4Hd}B g7CCC_2-8Cr F]tmlkmlk`abiHTl Jbz,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒA9-tb=*z''eeeeeeooo z;ObԼ|8L]  5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?y\UUA%%DT22z|vH թZL %Fww"/!!MaayyWUR33 QiOe|WWWKKK'zttttttcGGG///_1AO\_̿'4Aʿ 44~ʽ)6CͽjjjjjjRRJjzmDCC###fz r???rzXu kC򷷷WWWWWWbp WLORb6 sM&WVVýDDDi< a= .02p.;HŵpR/..##} dB(((ZR%"2@N*7C$-7 Ȼ³%%%EEECJQb  p'''888AMmM (((mmmAAAAAAHJM4CS+6B%1: ͽȻkkk|z&1;4AQ&3=&/PPPқ /6=~|zC:1amxQg~w!(!(=M_*4>ǰKKK@>;Ȝp)4?)4?Pg}V\`%09iij2N,;I!,8 ô NOO+,.kYG } ,6/>N&2?'0)7EJKMqrryWqv1ARf^~ %1>%1>Iay $+ܰJJJ_]\Qhz^ȷSmz1@1@Pczdffn`SRi ǻmL$v@Xp(1(1BWm(3=ǤXXXASeʽsSSo jNNN555J_snpa SjSj;bbbH]qzT.8J] ||]]555rTʾ\yXu?<``` eDڙ3BPoE v SkQi?;ba`zɽȷ %0|||rюݴʼ ghhʸ #xxx_~õxUZxIb|Ib|v&&&`!*g` 'ބxwv|Yuۋe?DZpRn5HZ :::6GX|]| Ibzb{rvbbb5EWtQĵtKd} !* RQPsD#+McyMcyzZxxxsEr&3?lì wL~$.I^s+7Dl= ^}9L_f r\39M`&3?'=TMSY---b;c-@~g֔囉l CL3鰳|kKeǞ7`Xb:X' Xb:X' ƵlU(:}.۝S Dgl<Ɗ\ 2mBKC$(ٵƠ !]UT4 AX' Ɗ\ 2mBKC$(ٵƠ !]UT4 AX' [`|-0O* ƨX )#7,O~fjmgx 9oV9oވ~LR3߲-!=a>WU ]mbbH⧊%DwJXHd~ߨX1O_npedUtAZ% ߲-!=a>WU 羍0$AiBSH^nedUtAZ$优ĸ$@2Nq(#jmgx 9oV9oވ~LR3߲-!=a>WU Xb:X' Xb:X' ]mbbH⧊%DwJXHd~ߨX1P/羍0$AiBSH^nedUtAZ%伖Ÿ$@/Mq86 E^ G`Ͼ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' $`{4qYDo;YuhaJa2m ؇:UiaI $`{4q˳aP/MX݄tB$iivϾ9vp"xgxYDo;YuhaJ ^fq;ndig|0zXb:X' ^2m ؇:UiaI $`{4q˳_P/LW݄tB(v`iģ)=V6 Ol}䨖C7@I%2(>kYģ)=V6 Ol}䨖Cȹ'GhO &dy{䩛C(>kY/8W=՚óa='4?#0=#-{r|ģ)=V6 Ol}䨖C7@I%2ȹ'GhO &dy{䩛C(>kY/9X>ՙ´a=&4?#0=#-{n| 341,L   `g` JyLǒ :v|T  341,L  `g` KxKǒ AlpC %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j,;gKΆ+m:x 9uQgP̉_2D" %F4%F2Hd}T %zS@9^gKՒMc`O$,:^Ȁ§1p=⫓#_j'뷎,;gKΆ+m:x 9uQgP̉_1D" %F4%F2Hd}C Xb:X' Xb:X' ,z,̡ňJ !0Q4R}q A{?಄ot* At6  @Pzc]N]P A{?಄ot* At6  8xw{1Q=|.'!4x!Ŕ@9/uR(,z,̡ňJ !0Q4R}q A{?಄ot* At6 -D}})8aC[5Q  @Pzc]N]"8xw{1Q=|.'!4zÒ@9-t`;( Ɗ\ 2mBKC$(ٵƠ !]UT4  5iK5i P`P G` G` 5e" P`P G` G` A~WA~ G` >xT>x 5iK5i P`P"*`*`"J G` G` 5e A~WA~ G` >xT>xjmgx 9oV9oވ~LR3ŗ "IM\Gʞİ !?2Ws5/]mbbH⧊%DwJXH]mbbH⧊%DwJXH羍0$AiBSH伖Ÿ#?0Nr98! ˻5ET ȸ8HX˽5CRϾ9vp"xgxɃes;ዕmbdexQ@v጖m7xlm ^fq;ndig| ^fq;ndig|a2m ؇:UiaI˳dP/LW݄uB)w`hPYam5ETrrri8HXTY_l5CR7?H$.'=2ٮɩVm 7@I%27@I%2ȹ'GhO &dy{䩛C/9X>ՙ´a=&4?".;$.{o}.3uN'h=26tM% 341,LؾjC +~itaw  `g`KxKɓ AlpB r{}_2'/ F1XqI^sLJ_1x)4?%zS@9^gKՒMc`O$ ʅx ,;gKΆ+m:x 9uQgP̉_1C &F6'G4Hd}B ABCj Jb|CCC_12?Lm F\sywvywvTUVeB[t Iay,z,̡ňJ !0Q4R}q3Kxp .%GsE+}^ H[V 8xw{1Q=|.'!4yÒ@9-tb=*Ѭ9Ma kkkkkkooo z;Naƭ|9L_  5iK5i G` G`)1j1j9d9$ G` G` G` A~WA~ G` ?yU?y///朜gL  rtvwJ ܜgK dddPPP-:FnYWU83UnLawdddPPP !!"*4v@6!&vʽ)6CƸ555_1DSb\|%1>78 {&3?888f| }viOOOppppppSSGpus999***hv r:::||||||&')lG wO' Yr pZZZZZZmi cvwx_2"+5ȩziZggg€[0>>>l@kF WXY\QhPg}zT|||夤_1Pf|QiĝxUUU&&$*y mJ555XYI )7C3AO'0$,ggg\\\\\\O: t 6K ǮsjbDD@DLU_v""" 67[7qCCCrQQQcZ  '''oooCCCCCCa"[QIENDB`sardana-1.2.0/doc/source/_static/sardana_server_controller.png0000644000234100017500000553767312174204305026223 0ustar cpascualcpascual00000000000000PNG  IHDRd<f'' pHYs !YmIDATx377-ЈwDq@{t} B&)7[D"*E@r[X*G}>g4f3GLP]\. /UƩwk°lll.affffZ_C8CCC;:?CCC..1  ??E ; s7lll!!%   3UlOE Ux}g89; '7=@AAF5UU-NNS ('*TY`  ;:?GHL ,,0  EGKľ   :C,,,//5LKK89=@AE987a]\鶺~}yPPPNLMCCC333}}"""<;9]YXCCCnpt@?=iii nmkmih# !***NMK##!knmBEF220,*+,,,:86KPSBEJPKN+ 1A=0Ԥzwt  G Uy]̥ʪ 6VoYG G 6f3g4\.޲hr[(hwI&UUgwIwI6_*  U<6STP6TP'/_1\zU/\  ҢqrUq.^Uqh6 \.CW>d  -.څ&&{wI GSPvG^*[&xϙK1"g,ӀGe* Gw# ߈j4>pq\!  g G* GfffRRRo{u&݈SEqqPFL:PC.Q???*** GI%# #wI"aOF!ׅF0fX9f.***f3){z,f3 Ȣ|\ h5:$\.\ 7g4f 22l  G{ν-1ee->XT!kPfL aU%AAAf.JJJf(PPP<ݽ#[b2A....d3J(((( e3X YVj9=HT]Wl; =HR]X=fr>I  (*0 HHL;PgIg GIgwIAIrwI^@ GG xxZf// Xb)EqVmtY >gggr* XcR^R^JeqB G}ExEt1.)0wPcwI3XQzIwI W*2zbe1^3 w0 ;Q;f3f h=V}R& +#&*jN1.n%%%R)(,e%%%]]]]]] Gg4g4T~JQ_I Gr5:d` G\ rrrd` yyyggA]AjU(fؚHy9|20wЉ4i6fj7fj8R//g5H@ck,ʱsf)))Ba/CW˳pf***@]|0FZͶkthtgQi`i+++?\y0F\G G L,:::3OiO,:::3MhM,::: Tjjjj]QmPPP:::888;;22PPP77< NMS{mQBth$lbmQBl   ::? ) { <al tlljjj0/3     #(㸷 PPW   .-2 SSY\\\\\\@AF0/2 ü )6 ! =;= =>C   »%4  ,.5  HHHIIImmm?@E "lllCDH½ dbb=>C?@DԷ [[]000)),)),111111iiiđhie[^a     jmlIHHba_>=;333 abb [ZX`de@?=333ABD875+./cfe}HED ##!uuw   %#$>?<   \]Z"!  400v}~ $!"   w{|   )(*WVU㖚sll8@B442PLKSV[`eiP>}P#yNUNU}U-qON>]8y=MQ7{V1nތ(lҌV!X#["Snwkh-+\ qcyY_Wz(M T cV!C ⤔zX\' pNnhyhڡ\)ycyDZl9G('D"O {C86! X{|vFU' ' 'kRR|+B+f3f3'(*IWe[{\.[{VjNh IgwIU1x4 GwI-gi;"N7/q [*SBa Z"kUU>RUa-W< b1(Ug$e* "<[{II;" GIx G|I GyI smzI啴g[gG5&'⧛" 7 ^J1wN.wIwI7 GgLI_* 7 Gg#غ.e|PWte)))nq~~22 qq}}?`9?x``dG_w:M`m= o> rCc@ b<y X1  ~iwwIUwIU"gU ` t.n<U  ^1LQsf f_9   5@E\ioN z|o>o* * *  6:}Z 9]o奪]o}Z.[^K Ϩ)))X1[VBH[VBHvN!mwTj!!!!!!RRRjF}ڣ)bdBis奭isXwޥcS(tQ҉wRfЉ I0&S[S>SNcS(220,1U >];</=xJ}XDiB:OOO/_:{3h{+txR,em!*uN&ff'1rI fʭTDTl_ ,8'똆+tɦ˽iJJJ*Ll̪ĴhLLL%MnͬfGkGĺYYYYHHPPP Oq f7^ZVsssf3tg9ZVQvvvf3yyvi:UPLzzz3vv,6MDDpw G常HHHq> feeeeeer? fbbbbbbr@ f 99`]]]HHHh5fh5fh5fS+++xEfff&&Zfnnrt;:?zzzzQggg  LLRgggTTT,+0TTT &&) ==B  9:?llvR8  d  +9  dMt  A@F8 d1 xud dl Dpll     l JJJ "&, PQVElll}l}tgs   77:FFKy}-RRXRU\!"# 乺 QPVnnn???CDIļ   $%*¼UT[9C   ?@Eý!"#'0><=C!"$ 666UUU?@E½556wtt=>C%)1 DGI ի fdbR"""''+''+!!! !$%+ Q127GIMZYa***015cdhJJJ888nnnyyyqqq,-);:6???(%& UYZDBENMKonp \\\521>:;///qprddd edb\[^'''856 QQS浹#!" TWX{~///njiaef   _bc ...<76JDD  hefBFGIIIOOOhhhUUU `ZZ### 156###%%%$"!   :7630/  kkkkkk<FBA-)++)*  \YXJFE      999QNO!"   ruv     IFEklikpq  GGGWXZrrr?BCebaxwz;=<!!!???ؘokieba;=<]\Z/0.BAC枞$$$QUXtqp =EG\\\첳  %%%HKP6Zi5Yɥrq +Lwb?1\1\F|FSGOvO `[[`` `[[ G7[g4gg4g4kuwz}[u9]FYmFYmuGa^[q888q !I I:wLuyNN}yyy^xhktW]mkQ( IjmkQ( IjKV-  yy 8e#a ,# jkgu$RIG55| GG55|gJ<_YxkJ0Ҷ'VbaIxf;#M<& xk;]؉?k oP*R_eWd~zV!;N=* ^8lj6UdGfF?u?uIW* NNI#  NNwSZTwSWwOuwZx"=* ; jG5C0S  .ᨐ&cC'6 GGg: GG GG GG"p"cg] =$- B GG?cc"*b]Vm+++rI]ql>qmmmyۻu[XXX.dsd   &&n|dddwwDD}5==A94BGLMMpqq>>ֿm%%%롽ۖxLH_wJb{ !*Rg|ZõYw8J]E_xddd$,trwd***h>Rgh5c LeLd} X/ Ysjjjp@ kkkjjjUL% l wNCi I"ikNwN}wSI=* J   n ! ] +! GQQ < Y#h< !XCS }wI'| wJ-I<{HI_IF~q:wI'| wJ-0wc2>|m4wSb $S d! m(/AN !986t<& $ WqHTg:& $þ@/]|:t9'/ # *  c %4 5 W)D2 5 W"u{wI 3|~i =rjwI)h$ (wI_ =rjwI)h$ [Lj SS8('nn'XP,oSSMMgg*MM GGgq GG~U^PJ~ HPJ~ Xs`_WAWWW7:=T ?lj8)I܄{hozls!tbW'ey{J'g, yD P\gQ eт~o58#JK}舌R!!!ïg GGM ''G$|i"l`݉("sU"]zx뉥??|J%xbi0\ߜ~o5cf&*P"S{PJw_܆w/g=Qe=Qeg4<<<A~gSo"d,pާU7ytRcP51&4Pm T~h R777YYYW?Th[y&"& &YwDtwI}JEDBJ4fn7o7Vw}~I -[s[&!pJ>>>h99 66{Q'~)9a 'ccXX:{{ZZU(((kkk`#+/} ;K\11 ]]]\\\\\\457<`Iay333$$ ӻ;K\f8 ||| 33;85ľsGb_]nnn aTG,\/㘘hhhhhh ((jS /2ݵLXs~tEE^1<ÞLDR7Tskg4g4;';߾ܓ OzC +Uuu %$mh.d' &l_ &//NAu\b: ;F *OxuO$' 9sF^^BAAAG GG,ZZG vTNq(1qNHj".:pKBa'5C(d("""̩~777hMMMJ]oNnЮy333eRRRFWgRtյq-,,dYYYAP`W{QiYag4 g=ˆvvvf3zzhhh$r k>ǁ|||3ttddd q mAzzz3k~k-5-hA  ͧ]]]r 6UT %1yЇ̳sYb``````777_|4I]ѺpTdZZZZZZ777^z6LbmO cĿttn "((}r|rRRR777[w9Ph $VݤQov<X```3Mg nnn6ALb\\\\3F~brrr5?Ic^ZZZ3?z])H)غCj)7)uuu4>Hd GGG =QDD?`D   )  68>  Ŀ.6E     "' "' ,.3%%( FFF"#'"#' %%%  QQQyyyꝝ}}}}}}:;@*0=ü# $ lej燇:;@CGM    UUU99?&'))),>@C¿XXX?56;Z[_뼻 MNPXY]WWWAAA]]]lllgggcccXXX|{~132JJJӨ%%#lnk243NNNÿ)&'&&$VYXimn20, ~~~ ˷bbb555<<<a`e "&':97 FDEKNMPST  XWZ 螝|}A@>510ppp  ghhD@?w|653?><666kllAAA634  dch  ?ADfih uvv뚞XXX  ќZ`b  ///DGH/,+jil521 ...*'&bbb  ...oprIII(((hge"""   TLJ*()  볳___/.,B?@777  C?>MJI!"  xy{UUUUUU  ν )&' B?>53/?(((SRP,(* 632  :8620/   %%%&   B?> ijl,,,%%%xtu    wvt000,,,30/hgdhin    ]^`777NLI~(*)VYZOMJffb   :;< .*, .+*   ###%"# 2##"<=;666GGGڳVVVEEE!#" ]bfdgl *-2((* INR_dgVRS49<g4]:_\wN9' N%'9OMeq٭%@k85"O$)UmͣeO}X' ӴON18\!׺y=gdK1V]Y:l.]ӣd&Q% NMĦ_ʠf " ϼ4K%D"% ꡤYT5ɌHೣೣ̥oX̪c{Ҳt$p+|Nq +Lw~a>i:e X!i=<sԤuKB~)4 %gl\^&=xujix|F%gl\^&=xujix|X*EZyoϤrk. :W% ?7[ `[[`\F|FSG GGF|FS`1\1\g4*<DED qqq⓿ ...umgTARRR ]xw[4RRRiTF:,3:Uo? +5?1r wSbwI_* xx:$888Z2ۅh* ؽxxXEE6~cZys#4\J!X<\ =s#4\J!X<\wc DFN;LK0DD""3V" Bsc|tb Bsc|txxdddO{Sdn2{w 4b 4[)wjqqqddd.w?p +"G+"G 0 PN.ZCqs&5N.ZCqs GGYYg;;|J;;|GGߞ"@?wIZ{_d!wT"=* لSJmX#rICqn+TrIHjl /foc!ny>qyeݭp-g |I wIL>RdwS F \]  FFx߇ze|$H|k3:Iς^IseUq~wI ℭwSl UB CJ%2=M+;`k395 84 B G S C0¸8]'şF?bA=t=U^'# G5ՊWFK~-B]oLX !=~ @`wO"wI: S g GGRvRggg"RRlJO)wSb:Xsg ] = g G?"cc+,!wjKǜ'3>ĿeyO̧WSOd8 >>>JC* |||555aaalll  ffTTNNeeehhe--I??ޣ(((Q5XX"JJJJ= 1 t<522G..Vcp21/=(WWyDj4?۩@M\j2G 뎎nnn %h&&& 0?O^^^nnnX((* \2Zx*8F(7D]]]___0&&g9M`h6#,o (0>>>|Ngh6zuyU*71*NbxMdz ?mmdbblc>JU'8I?Pb?PbŲYwj8/>NPk!*̿#- t=Rj)6APjҘ'4A|!>>>~yyy>SgócvY(((]p ~_m00Nf_s|sss@VlOi~~~sssam DE* I=*wS6G )AShtqfS ˰EY N{gKeM_CWFm ,]N y r7W]NM_CqEEzJ' wh0CMS"|f,xj:zJ' h"cgT*I2S%_*  Y 3@ ;D#=Ab  N 0:m&N  =5&N b/݌63QՄ'y>m t~Y"=* ݋*3QՄ'y>wI$T󆉷:t @#q -  _ #Dc !C>Dc :qFM)crr>0 "D,FM)crr>~JF\7:U .I/ Q U  / / ~ > ?   ^   ^  M)btژo>B?SҘ <>B?SҘ < 4_KffO3G~'UYx\c-Hcc-Y XXN&<;d/(TT} GG GG<<G}gGG??gX' Cgx}V\NV فSTiu{فSTiu{N#?d5QYS'b v|:::bbbOOOzB4 L {vB4 L {GO, ZZ!!!&&&???}}}? ..'! /r}Q!O^cNIN# dƲ\{IBi`IjmUʐqB+ *~xbtR}쉷Tct%?yrD்ol-pwMAXv+<]He$IqN :::`7^^"SyS"SyS`|* ?wI&]CIgU7x΍xL` H!t眆w}sCIY{I}`&h ;? ###sssjjj1 ,€0P/Y4.ر'XԇV)vd}է'YU;֨&X >&3? OO; K-3y‰>#31 ɡP`k3tQ0VN0(((?;;ys{긝G踞G빜SwK; 87 .0 ՉKL2!U4e긝F 555777Yĸ:)Ÿ9'ĶJȉQGaJ!){o9yV=sJ4f;ޞj;wN,i09(&lllggg//I)) 'UUw?HHXX 'ccb]x6|||CCCUUD77dYz0@P 999777 ,,,B11!PPeZZEEE89  0@P 999V++ߣ///")/// ̳V,g[dnqygqqq   hhh 111# {yv%/:X1  #2 romNNOW:JZ T/%%%`n_k~U,..[kzKax ̶}l^^^JJJxj\oY6]6,,,N'`q`潽CCCEEEE;@Eix',ƺp7UFcU888TTTNNN?HHH999UdG UdG nnnQQQѮQb|Ii{VfR"8\7wG 'ήIE$ *ػD1cg7؛Q)4~^ n>c`܅2 :(tmF%#$04dbҥw]壛p\e&!4cK-DX" ΫJLXe:Vs_p]:%#; A=-p>:(9 ;">=M:nn G [[777000q[Ğx_ʦdUd(dG [[[vJľpppzzz&.5n{Phhhrss"(.oVaaaiii"(rPPP`7ݛ¼vvvvvvRRR qb8גmmmmmmLIL p!e;ЋbbbbbbEEEo&UdG APPPh8o7|i*φfFCCC::!f(7FօcB:::88$d,>Oۆc@|11199)a0DW뤷t'Q8o $i ڻk(((r<<:TmB\wݿ|f##"o???Ri~EaĩyamSyS%+>NZNDDDPeyHf0 )D'2 nLLLxd]]]@N\X}rHHHt]bbb>KXZÝxBBBoW0Q0ѱ=pqqW.<.ggg;HT] mu/uIſsss~~~)18kvKľooozzz'.5m{Ojjj"7"W^^XXs uuu$*1o;6KƷ`8ߛýzzzzzzWWWr b8ܘ¼vvvvvvRRR qb7ؔ999o{<< }  -+-ppppppOOO rSSR\!2+n͆fGdJJJ;;i$1?цfDfCCC99 h&6EԇdCfQf..H`X`???77"g(8JG GG GG?ַn***s<<8Wq?Xs׺k'''r;;9Vo@Zvټh$$$rff{ aaa.akxk==;Wm@\ywwwsssjNNN|hXXXCRaUymLLLyd\\\BP^V{qIIIw`>a>á3zCCSC]]]AO\W|888rEþuuu-5=jsFttt-4;juIrrr&@&LaNll\%3%~~~+29i³MMM`8⟟[[[p b9᜜ƿ}}}}}}YYYp b8ߛž*4*fppSSzzzzzzzWWWr VVVȉjKfPPP==0k -:ɊiJhMMM>>1k /<ˋjIhϷOEO5|848KKK<<1j!/>>>>Ӵq,,,wW!!!::4[t:TmӴp+++xW!!!;;5[u:SmҴp+++yW}}j99Tpdp995\t9Tnbbbh5PPPkTTTPPPjTTTPPPjMpM+qqq2q]n]TTTf,L,նAl?}H8K8dz&&&A?E #4#\ccggb.... )(+  vMM  448.XXX CBH,,,  ''*AAA    nnn ))/   124   BCG***   򰱩#$(t l||| <=@G  hmr𰰪77;?BB ~EE XXXXLLeee   <=B  lryZZ`///B@F    "# UTY 999UUUBBF½     ""#NNQ***gggEEEddd555>?E !$ )+- # þXW]111񎎎#$)#$)(((  #325JJJJJJ$&*$&* ,,.     --0001&(,&,ý  $,  !!*)):=C #, a_`#%)#%)  )/: JHH24;¼ )/8 ;>D !/      <=Bü  ;=D #*     <=C   <>> <=B  :::57<&&'  @><9:?,19 %$$ ((( 9;@(),  KJKR+++ "QQQ 88=NNS EEE? .03#$&'(+MNR BAD!!FEIE888!!""""HHLmmmCCCvvvrrr666VVV!!!uuubbbfffnnnttthhh? HGEJJJnoq棧*,+OOO~~uusNOT)&%=<:,,,`caWVTW]_0./ JIG歪446 }}{orqoooLOPA>=ssspppTWTOPP**,\_` 111qtwPML312xyy{zz eeekkm]^b|LHG %%% twvsss^_]UUU gcfHGE! |OOM[[[@BCztv(*0?=9OOO???WZY./+CFGcce ghj!!!EHGbefsuxPPP  TTTQNK.,+ghj񑑓jjh  [[[ khi 󡡟JML,-) Ɩ [[[NQR  HHFfff&&&[^]YYZ\\_ORP     twv (''Lj  ኍaac   ><;ux{ zzz666#" jjlvsr+./STV    $$$|||//-   ?<;ddd#" .*, SSS568¾513#"% _^\III$$${zy UOO Yb[㚚LLL766   QNMGCD  <@A  ###TTT\\\   ;98)))***HBBA?;  >>>VWY " 314###%%# yz|T{IHH %%%HFD&$   <:; 666       YYY@AC ;?Brnm  -,* ..0   ORWHHH   4FH11/   JJJPQSnmk9:= uuunqp   OLK222qrt OKL    ู($# kjgvz|     )**:<:ę***###UUUVYZ     a^]   224_`b @?=츷VYZ@@$##DB?WXZ+.+HIK0/-555 ! " ### @=>    (*(,03[YU ??? ##"\ae~OPT%%%$#"NSW]adMQTvro))+#$" DGL..,|AEH @ICg4I{ʊWH`hF Xb:X' Xb'fOtx(ʊWH`hF εfM.P2Va|ji:X' 赸ge!{kjεfM.P2Va|ji 1K}Kﷱod/C<]kXL@ʹ:X'ۚT.qrﷱod/C<[h\Xf,R2ﷱod/C<LL4?*qx@ 1K}K(B!fI 4,:"0C&1.Çy$=B ݃qzy 憎x:ߎ?@oq?:Çy$=B ݃qzy勞Ým tyԐ6Çy$=B ݃qzyMmvϨ@!(B!fI 4,:"0C&1.!\x\ӜLQ.*?=ٻ,@Y7)@[;-jxg*?=ٻ0HgF  D*?=ٻ!\x\ӜLQ.$9$9]>f߆orՁ7 <;aB,)Zd Ձ7 <;aB,)Zd Ձ7 <;aB,)Zdޢ >`$9$9]>f߆or|7 ;esS /N1Ӓr ()* ª/l7ϓ/N1Ӓr /N1Ӓr ՛3ff1|7 ;esS 0#|nnZWW7 ;Ii=ܑò` HPW:Ѳ`:X'&xPMR-q)m;Ii=ܑò` HPW:Ѳ`:X';Ii=ܑò` HPW:Ѳ`:X' ƨX(j[w$0#|nnZWW7  8lC{C|G`/v/vARC{C|G` G`C{C| G` 8lI{ g4 N' ق&}RQP#7EU*8C#,7 ˻̿mmmJS]^x$,$,?Pb(2;ʭOOO|t_u^|jUUU(((?JV^yXq./{zzbtŸ b5```]vavlll```>Qa@Tjo{{)''uPPPڽ>JJ||gQQl !!Sb[i ڼhA:_* A_* SwwfQ555AyI ޔT"ݰ-$>aCYU dzߡS1V3ݰ-$>aCYU ﭖZnemUtAa( 'EE?t:diKg3pnYFv;UukhL1Sb:_* WFv;UukhL 졡$g}8t vz -\CV*G!睝CO-)BX6 Ql}⦖E)BX6 Ql}⦖E(CmY5=v**555 #j1Vxw%aw Sfj:  $$4 ;PzQzs1# ,?bAɋ5s=ᩓ&bj,?bAɋ5s=ᩓ&bj11 1\>?P0 B@ްkt*#C~6  @V}cXNe$B@ްkt*#C~6  Gg %y؉y Gg"RgR 7l"RgR Gg*MFllJKmpݥf:_* Sb:_d_b:_* ƵGmƢIlk;:_* ѴjMl_sc Gdp GdrԳaYdԲaY*TdSD=- ˒_Zp])Uf 'cD7٤2J?Td!24i~5۟W? /m5۟W Jum6xJ &^LG5jm{ /LLS#S" UG Gg*-B 7*7 ƺĿaaa///),K,r_```kkkdddnnnRRR1 1((v׻x222 zv[[ǫ@@@--'껻HHa''L555EEEAAz::p&```&&& ***uuuOOPPPeeeeee @@@PPP  @@@oCCAH<-!377WWWȽ *9G0?O)2#ʽ"%0//IIvNEE8893--P]iF]uj +9H+9HTo4589:SPmjjzxhgr3CT3CTsstOOO###O(((00/:Cژ֯z ###tRRb``U`lԌq'ijUp###wwwXa|eG_xG_x[kX̼>>>y|} dcaqppUP3CTp?-stȓ>g$O&&SP\uܵ\ &Q) ؼ2W. 43i->stȓ>gٽulAH!2/_,Bf1h&Q) U sT8N jT,G8 L Gf.Il !G-/ %( >g $% #% %( >g j!h #%  W  r Y CLJO)Yi @Ned <Ne&=pZvyU?ҁ"SuCD0 /. 1/. 1 "7R* `s IX~ o`ww; @Uo'  P:A[aUo'  P-{1mug!%-T_,+0$'ٻ·fK:. 'Bauw+FOVG֬}"B{m"A 'Bauw+FOVG֬}"B{m$@es%:zPVJ— Fvp:7nnsscc?\\]]TT- TT-ZbZ $@I0)ZhXڦw&%=R3"  ?ZЎ@ &\]ZhXڦw&%=R3" ele 6,hfI:Xb:X' Ӫ=Wm\AoAo&\P\ Gg GgZVZVGg&\P\ Gg GgBBsBB Gg - - 9dMӾoHV*|T6߲-!=a>WU ߲-!=a>WU ^nedUtAZ%伖Ÿ$@/Mq98! 000777444-@~g֔囉YDo;YuhaJYDo;YuhaJ $`{4q˳_P/LW݄tB)w_h򼼼000QQQ]]]ģ)=V6 Ol}䨖Cģ)=V6 Ol}䨖C(>kY/9X>ՙ´a=&4?#0=#-{n|JJJJJJ甔g56I[Lf~ Ǟ7` KxKǒ AkpB ܒFmr9EotI ܳ(G:_t6)Λ &Fp8Wiqu8Wi zzzbnz ȱ{(5CMf ,7۝S Dgl<,:^Ȁ§1p=⫓#_j,:^Ȁ§1p=⫓#_j̉_1D" %F4%F2Hd}B YwSOyS!A Dt ߈j/vfxw:uVlr,5zK xw:uVlr,5zK O!x,֨%XK %>/j  A2j"-8qjD)))777ƨX )#7,O~f A{?಄ot* At6  A{?಄ot* At6 !4zÒ@9-ta=*I,Q!阑bB12/,U`"rq4U. ߈j)':F5T_%יVRre0`Ɖ`ᆐwxsyJ $IΧK$熐wxsyJ $IΧK( ҆x,qXk_!ӗZOpg6砣 OD6䔏ec?5q??3 LA0Չ8qn׊7po$pg4111::: G` P`P P`P G` >xT>x6UUUU繡 5kQq8K;5~տ. ±O^b+0fȽiో[( ۝V_fw͔$_\$ є$_\$ W L|k25y5y鵛Fh 黤8~稝Gf w,,v,***555   ŷ&@X4)5;ŷ1EP)*ϒ>n\ +0)䳨]hԹ+0)䳨]hϰ$;O.¸&;L*ĸ'Kx_ĸ%9J+bbbMMM  Kd}Ӗ(j1Ӗ*i0ӗ  ᰧ%eiԑN7{Ye+ZD+ZD ϔ*k3Ӗ*k1Ӗ'i3'''###BAAy |PPNIby֨'WF ֨'WE ש1߫Vr_̔c+x\<t{b)+Gyf| }p!׫r)rsE+Gyf| }p!׫r)rsE 8OxP~nN 鲴v1|V; ֨'VE ֨'XH QQQMMM??? RR!trr]]]NMKj9 2222 OMu"7<< 2|lol2l2llol2l2l 5[Y[Ybɉb 2222OOObbbPPP-AAp777gggLLL"#5FW^긝FdyyyyyyYYYhhh 66''r00DDK8(/6i]|`lj`###***ttt8++O$$>3 9FFFjjj űD[q!*000 #*qqqhhhhhhJJ-*(a6HZ111!$|ot...,,,///*'%9<>i{##/:#11Ȼ,8Eӳѡ333ddd}sx"""33 wzo<<<QiOe|lB___WWWrrr aBZpwUSUVa4|#-7ǣ}``ְ!!"~ˏ F0...|||_^:'.6jԸ~q000...޽F,CQ_hdJ3{xc ```zppreKKKCCCCBevAYqq^HHH111???+++***555000999mmmmmm###MMM yyyQQQ(((///hhh222```ddd```]]]DDDM :::U(b:ثG U(b:ثG }}}KKK GxJ^TJlQo7|___QQ.kXSv:d6b:ثG pDd/yl'g4g4ue+ȶa|DWp($i&z9Mi{2 ՌGFE:#~J먉: ֒dy$nw)Ӄ?HSy5ʎ7  ?uZQ|8|'<@??>@DD;݄̘M'빭EEEIS#,tr7 *qmպ^s 1ppSp0}h$/̳[ ]7hYu U(b:ثG M2rkvɛ(6#%QSSݶ$5GZlsb=ĺ >>>pppbwbwb\\\\\\ֈ/;H=Xt&/Ź ;;;lllbqZqZUUUUUUۊu-9D>Xr+7Ǫ¶666jjjkUkRJJJJJJዋl +5?>Yr#0> k/G} ۼpoļ$ `Yṵ222eeev^^z^Aqqqqqq3AO>ZvͰ///aaaqddwXuuɷ*L0 5>5y>;>jjjjjjȍ0?M?Zu#$=#  .ɱE!h ϻûHHHvvvd||FFFFFF匌q *5>=Wp&4CԼHHHtttdvv??????늊u *3<;Um*9JڻEEEqqqcqq6PLLee??d + kekngn888z)1:;Rk,?PC[aYu'1:::Ęr#6J\:˳"""RRRvvvkD111򑑃'.5:Qh1FZͶQQQwwwj,,,&,3:Qh1F[һQQQuuuj:NVVbbFFh)fcfuju(((%,29Oe3I` GG G G77DDD555nBnɬµ555ggggZgM}}}}}}"4DT=Yt ʮ333hhh~cZeJ yyyyyy 3CR>Zw ̰³222fff|_^~aEqq%E?vGG||||  HMHvvvvvv5CR=Yu```ɽļJJJwwwfMMMMMM቉~ ,6?>Xr"0>ͼĻHHHxxxf||HHHHHH㋋n -4>=Ys#1?ϾùGGGvvvhyyǪ0R::)) -9-wKEKEEEEEE犊q ,5>>Xr#2Addd```Ѵ,,,^^^pkkvV!',8K_8RjҶ+++\\\llltT"&+7K_9QiԸ+++[[[nnnvT}}?KaaaaLLk&b`b}p}"&+7J\9Sl]]]EEEƽAAApppc~j~jhhhhhhɍ1=J>[v%Ǿ???qqqd}h}hggggggˌ2?K>[w%ȼ>>>ssse{e{ettŵ)K3~DD  CJC}$"$dddddd͌2>J?Zw&]]]Ǯ"""UUUrrrlF777}(07:Ri.AUȰ"""SSStttnG555)/7;Sj-AUʱ!!!TTTtttoG4PHH&uñs*7*}t}TKT333𐐀)17;Qh-BW333FFFƨ÷777jjjkUkR $6FV;VqƩŷ777hhhjWjP!$6FV;VqǩŸ777hhhiWiOvvBFjj^^UUn%\\\t!$6FU;Vr111~~~%%%fTTTTTT:hRRRRRR:jxx̹ +N*AA  >H>}*&*RRRRRR:...'&)555%%%%%%%%%%%%8PRR"rɸz'4'yqy\R\%%%+++=== 87; rr#E?r [[]]]p]!X\Xv NNN  ((+>P55??bbb    p pJJJ     .-2555)))   XXX   ///        ___WWWIII  $&)  ]]]    NNN  ti+t  ,E >6  L 8E 8E >6ttbbb%$' `4  i_"o oRoU?\Zt 4oz 4oz oRoU? WWWWWWYYYggg,,,  -,/ v = 66  i%33j GG { GG {  i%33 a'   z vW  r6 o L1   'an&XX1>]]>>88}.}.v ssssssTTTFFF   78A79   88;OOO===888IJO         67:þ65: !#yyyAAA[[[EEE67:            <<@  ģ///000555===?@F     #%(  þ"  !!215<<<<<<777"$("$( 89?))*D     JIH79Aõ)1?     !! &,7      a``  #       A@@RRR)+07:A   -,----xxx 89=  IIILLL 127<=A $$&$$&  &%'...999LMP?ACFFF558 %%'nnn/01ĕEEETTTeee㮮AAAWWW槧{{{vvvyyyfff퐐oooYYYbbbDDD\\\000XXX###777QQQ,,,111MMM555### HHHNHH =<:CCC&&&pppXZY  RSP ppp('󥢥'*)0 ,mjm TUY**( =<:UUUjjjuyz z}z`]\bef220 756CDFXXX___>A@@>>^^^YYYurq   256+)*#!"yx{000$$$PPN!!!!!#???rrr  0/-FEC 䙕gkl777""" 23 яWWW   fec963َ,,, 220 RTX)&'ݝkkk /-)ɷIJL999ſ $#Aׇ  hefedb;<>!%&&#"IJL)))\\\ 晙jjjlopdghuwz  !$lhgppp¼[\Zhhh yyy lop [[[  JJL-35 %%%ggg¾ ###MMM%$&)(*(((~^]_  QQQZ]^뱫LRT*&!,,, Z]\tttW[Zilk???,/0%"!  111lljUUU|VYXhjmGFI # "NQT$#!  555/,+b_^8;<𵷷[]`NMP       XXXyyyaaa3/1   QPN  QQQ()+ddd222?@=      PPP)*,~~~[[[ (%$B@< ?=>$$$degccceee  JHD0/-$$$)))dddlllCCCdca(%$  \YXHED JJHLMO8<=ijl忿!!!999[[[EEEEEEFDE$$$'*) >:9GDC 000STV\\\  @<=*&(53/ )))  ""  %%%###965-*) ~ <=: 474    ^__  :99 -,(   oqp@AC ('%#"% KGF&)()))! #(&'=<:   8=@ٕ .,/       ,)(#!$ &&&~~z XY[     222\]_(''%ɕ rqt!#" <<~BDE   _dh`ei GKN210  PTX;?B;?B)&'!!STY%"!`ag;;9&$%"!#MPU RRS 58=ƴvIENDB`sardana-1.2.0/doc/source/_static/sardana_server_empty.png0000644000234100017500000017131512174204305025154 0ustar cpascualcpascual00000000000000PNG  IHDRE~sRGBbKGD pHYs  tIME4~tEXtCommentCreated with GIMPW IDATxwxTeL$FBz. M((`Ů,쨠* ""ME^^9;?,9罟ypb`|zǰ^~UD-(ݟ Fkz @N0qAfJ1 g@i6yCr9#{LB0ƪw`_tVO6%F,x t B8BXqTQ[w#D:܏ +AUקfoYRu,7d׾"t= IԚNaw9Buz(.a1_ݽ)bwLQlXZJ\CQ>𹋏Kg=^Of;gCv5tM st w+?ҭk9/oI؏wG`=2AѸN{yI_EŤlk㐗y)UN (HѲ' Ń;psQj.G.z~\1G_I旸cݦALa{/ RݳRs}gDb_ {W-Xv@C먊jE0@U,h`PTXLTUEu,}) ("XVZ\#Ss(JŹDQU;*FR^)hqZz!j5k$TTJ|j_zq(Ieiq Wqqh$NM~\2"[aʤI>N*nc۸͏*KY3 0TZ)Fh(z9)ܳ_m&v]t8#R>tpp7n|铗6,'V N -7).>~t:wŠ4h0iܥ6~㖛odرdeea:ڧ7-[N0DUU6l@ΝqdddҳgOt?'2zU1q|: 蚎qWGZ((RrZfiaak:)6Sid 0n\qA#,`]4Zh2^NO/u*>5&3 |6>A$CҰ)O ǛOšOf`h1 bd#1QKMIn?RRRڭ@+V`g jVC:"OEjVk]UUułlEGT|Nj(Dc:%/+V*aЩS'x7澅aTH$b*tàk8Sr<51MQt"V[oer%)ٌyc1 ]Gf/Lɧ-Mٸx)Ww@r70i4G]}Ω`P "dd`hatAe1D s82 =k5c7_"l0 d}f^( ?9B_M]r s0n4j0EUU > Roq[nbڭ1XLxn|^A\;EQuEQG47~ 7^T74Z6Wgmָ|HCs`0n8vVk k$@0;-Ab>WJ qD"QbVS{CGQTTntyr ̠_k.֛iPvL*Wo~|&5jBzz:s6LA&MuT'v q"={tgPkְt8NN;?K?H8ڵk۷/& vh4әB8J nɢEءjx-~ 'C(ʽYfP|v|Ն &ʠ]جV*+*8S7CuN 08ᄶ(B<OuMٷH4o~D"N'{즬2Iˀ \nܸzح6J~% l6w93ӡCZ-X ˎٱ}G gQUlVH]ӸᔕϸCǎ`x<\];7 hڬݺu1UaTJ/ܶ;wczweO۝瞻FJT{h=Vޅ%.`x*WP)))86n fL}/XܾKL¢/ ``l-zbQb((EY|>?^twzrT=p\k(sB1f#|grq8a'~/|Gѿs2XTksD\8gau޺gNCӴ+ 29;jMigе[w| ?``( |UVzPon7a  UbJ'F( .W&#jjAUVUTUjU0P2`ȏ㩬3ZUUPU+(86TU ˶;HCŠתޭQ*VWA8! aY5T~Xp8L8u ]㣏t=fcE6ۉhZ܂FE9 =5-L7}zᥗMIr>tϦifSɴK!"kWgnGKBIІb1;"1gl33عSJ=zۻ\Ҹ;  ZzݥIQq' :j/))vt:eKAAb{'zjLD"xpGa|"*+*jy%@&^4Ȝt0v,+V5:xQiTTX P4 TUeyФGt:4 A0@EFjrH$iTTU/sKϯp8a (.*B7tZhf{9tyܹ'$aQpMKvv6㡬O>oΝ;jժu8I &~>|>FW4 AVX,.UxaڵȪϗӰ@i=zyfx"vm' ՗Fcdeeayw\{H=BQç 7.&{hZ\Ufۤ@tȼjcb(,,aÆ$iii;nfRRR(,,/fI+`ܸqL:>{~zzwc=Fff&>}zjV\(X z, v]gN&Lpح;K4kژ-f GMЍ/K~$u={bV rQU۶I= g***ѢEZ.N:+вeKv;5"zYno֌,n7wd^RRBii)999h&sdҘqi?!㭦i4oŒv7 G `ĉɿ(EEE<裵5j0uw)))4hЀ!CXvܹww_ 䐓cZ&L>; -˄Bj$~kGf֬Y˜|ĽH>REMePUh/ȰH @cT,ӇW13X~lexDR`E60+H#S*KLT]GM*( :r۱w5&"p}YC2n8 7=ëʪUxyظq#7t-[駟OO> 8I&qgаaCvW\Aaa!K.0d^Lip:19sa|AFO~,"j"J<'55@ ͛9X|9Mӈb|wTTTE<gƍ6m@ y47pW^I~?c v;}ٯmğ6E#RFrUtzI%. )f ]\A14"=*s 45Xߧ@Meg@@rÇϐJ} ȓ@~ȑ: ءSwZNNd:2PXM?Ddri&zN~~>Yf|w$#[j_Mnn.%%%tޝp8(--%S!K#lْ7rѣ+WL߽{wkڶmL6m(..,B;vduY|G?9047oNvv6ׯQF4nܘ͛7x&"5QlTז 8A)-+<%osX&S_;FAXn|wKKլ ".W3½. Sa|K}*G׻A )p?9kF~x}#54ᗍ 3+j?3y$uYۗO?gysr]wq7PÄ 袋xiР&M"==04iӦMc̛7EQ[lۗ,6lW\Ν;_>͚5[n޽Rz)fϞիq\t%9/$tI|嗼K 8EQ_/̘1c5k͚5~0&"$_K5NG|`SY /~e2l=Vn[BtoZpHm?`+`1 K݆pRYI".f )w1`"QXX+Cߌ8E` %( YY\}UoazHUN'v8*խ( h$j%'^59УGׯψ#'  F|wxܸqcONFF `ǎܹ3|p>oHN: yfTUo]vzx\9~£y~̟?zյb?yC/$ 0`  $%%f-wSy睗 7P IDAT}t6mZk}պ8I0 | ƀС6lSN]v<~<8c2f,R5Iuv(6` yx̀ J!IgT¨)P.QTHIր徭XlT)D\ TH D AG1U F5AyIJ!!~+yY,h1vTmڴpѻwLy`fhUR+Ҙ2q^p! ]׉FI]T;wW^^K|l2 _޽{="X$T/"ӥKjʳ>˺u8xᇓtԉ#GֲN9{Z.P322HMM}_M61qĤkСCt|LQ,4}J NKgžlc"͛H,DZ*!i4ŀ̈t¨h$ + FT.r]'W r}b4ѪD@bJ >O0W\9p8̀ D~elٴ|Wm^~M[VXAyYW\1rEaeX,Zcx-|)H7r DXzu2MW_g}͛7STTTc/jg +yW?Qxz.26mĠA0aBm:t$koذN7f#l&cHOOGK bl1aFmI9@\+ vfw!؜"Of"6H<" T*T"Ɍ8 o#,^.YݳᑂpACgj%[3 pl٧?}Ҳek(-ZRfddPѦM""O'S\\ ?fnD~snI&׍O>$9Q=no P\̖-[}5SO%??#ϓ'ON~Nk"m5zjZC#֭uѨH#nG}jO1n<0C$ \z0A卡؀E)mS`(@j;Qr5[rlqkP 4*;RU5* Ϟ/[" x LËI] ԓmAD|IE/ѬYs*+9t UY4޽ M,&PK/{i \s͵1귅oaP-zMqٱcxݻaTU%'''w9t4M#өS'6nH<>3Π~:l6JJJfap:l۶혐yLD$MWՈgYGb ;>6D"j+U z8b|$tZvIn b>d F@8 AROj w4DJdm ɴ=W¢UnH|:vB4eVK\qUBJ0 v{y Y٧ԯ4iڔ},0nZڶmKÆp:L:ɏn8-ZD ` 6A1zhj.4a+IQ$Wm߀-o;kE*`RmG$Ļ NUUG1R1RܐJ;$_/q #;Džgp /69/jB;vGj].W_C $I&sUca 3AqTxn5ɘ19Z^Z|l,?rIշ=l$ޢEK I=^ZeggkhҤ Zbٲe@N8[vk̑0aB.:eX`7DW"Hs'p i@LWdV0_MW p)b~\dj.Iِ"܏.kps۰ldzmjj*]vGG *mx͹ ~XgKIMMeѢEL2Ӯ]#9 {< y 8qb}Yիdž j-pBdP%\ng„ I^PP 5{-Ν;yP%Kc ଳ΢svm\z呞άYt&ï "UNEbE7%HUǴ syL,"-e^!ܪ$fU-N®j4E/Au"3f,΁0:n@x!?" l;?Qbpf Fx^c.g矛ᬥ#QÄCuBD"NV4?\.۶m~ 8ZU/kD7Bҥ SNMZvyу4i0?s˅aDdNy0raXxhڴ)Nrܹwy 2-ZC /gXb/=pz]}v&L`c.RwEzY$E]﫦]I@) w }(Tr4{/vb$͔ř)dT" tT i>3<-Wһ5 WYUa5-ISLofo0b䕄á 6wʰXRjz]u֬_Dkj՚Z.E$~0ؿ?wu_^G}{aÆH5j+Wd޽eW^y%.mRRRBÆ ٳgOۯ_?n7 4@Q݋a w͓O>|tڕ}_3zhxd =2@i9cTA(wJUfH%PALD=\DK[UH0wJ/@rNzB[<8H.݂"=_'/1[ݵ.˞=W>X}N%RG=\VlXuy_ɩa.߅m3L窫a {$ظqcOy]h4F+dv=m۶2eUD^s=IYd )S0&B:q*@-FUUp"> BnH*NGs$:RۥΕC$h-_nJfJU[L[o"5 ?⪼v=mU:ŠM̜4co?\'wŢZ8~yA!h˖}FV((h׏X,FAAHm۶QR\̀uG1Gii b2xK`„?4c'Ա$4IHSD(qC~ fQM&UYqj P5D-S( \(JQC%dYX4cdHR?b1Br{Ŋ7d(;vl#ݝ@Qdi bqʽuTƲ{!//d| `kd.JMHMM3SLB7ağ u:lV^A$Yڝj" EbK"_*lϟ^&/u!33o~eRSSr?}aժUM`ҪUρo⿍ t6o1v1G% T5X KeJFtsl^݃~͎pwGș(hP*$9"B΃4Ŀ ]p34b<ր4{WNl@=>&N9xp8̴iڵk$D6lȠAj,o_֯\s :ub5,ի{/GӴd1ٳgӓ}wF/ 6L~pdU||Ls _AVV3 H/FUY ~IM%s%T^6[5;…ipW" 9Q?.tE)̋swY8lj^\>QƎا_Kjm gʔ\eKT;@ @<.۫EEEzs.y~MϟΚ5koW\1֭OY椧mb^z?kv*qBh4BJJ ݻwgɒ%D6 LOIJLTheǎرVg͚EEEYYYuzꫯ}v.2܉6h')͛'0ToϘ^go ŀn8h^mѮ Fle%8DUs`mؕV!H_ABvLyqYo)pHzȽR R#m[!lR8R;y)K8 \a\w_}ڵc̙qTVVW%)  P^aW}EP(fL\'l~y=Cv:zGO{ƣ*Z2 BV9lk_C˩^ׁv\qb'"\[ *e@+Ӝ$T|T"yVහRO%J`pO4@nnUU탛yeBX[Rڴi[³Zj Z={* _9瞇躎l6xnوb\.^o-cX̬LPTggch4HuU{8ޟ3]J扇ϰ&wWȃpp&Iԛ Z ՛EռyB:" <>NDDORxyBuB'˥Үm^CJpT#$y.G[] ͏H ڢxEazkp"Xil[JJJHMMeyabV} Yr%;,u8yf۷m%%q/U~zL{]y L0Ǖ$:워:.5SM ^,ɼ"$x+"rP\ JE]!Tt"p D]";ZSU&Q]BCZi0XSNo]oͰ2l=paژ޻|7h\We˖̛7>}Э[7yЧO,YB>}N:1nzI赭DB6m:t('|r2jСQVVI'DΝYxq2mȐ!deeѠALL {Gصk/">@D~N<_ #p饗p84h4nsСaÒh 7ܐdmO>|x,##}2h }]hݺ5L>7 .Rzۗ| |7n^x! ,nݞ4iӦMcƌoߞ'|2ySb dU6])))u{h"֬YC  peѣGdG&pi&233IbEF'll -TAB!x V %*\{36#e$BI*'r{$ʂ5 |">_GU>vTaDj[\B~þO妯\K3cBra#3~`ZZ-1~Gf͚UkL4MW޴la IDAThUUڵ[ Wx=TҊ߰FzyP8|׌ϡ3z"'v|7|sLK.m)h_KC1qD`wUzԇ@cAQI R= 1;4UI~VwѤ*OACWnQI`,xmbIȹNU{1Hk.Ȓgʨ*yz4YYYS0P|?yK.[̜1 Zo$B@!"E+MP)*DE.b(~v `A ECH޷μ;I ~G9{\o\k0 \, "X= ~!g !&&];Q~zׇϧWHn^!\=Jn^!u ݷ 2jЃuT63`7kl6t]'<<+hIdd$))Gs$Hu#]P rr"~aV=,= m=X܊?aPjpi" 4[y_"S C(}W~zؿfozOny^H&QOnB:Lݺu),,$,,\/-@D2-N'Wob1SR+G;evY33gaZ4PBрV :c}~t0 6Wbɦ<5q-X*XXuDFFk׮nZ>p&lٲ=n?9f%uШQc0"JCW(+9@O4oXo[@xORULbd <ܗ|kw,6n;ʍ7X:[1 0 wvӲe9 N ?*hEDEՄPNʭ @h֬^zԨQMf+޵kWΝC=@F裏xE2a„ \f`9ӯZjQZ56nȿr(Nv3fxH۶m+kX,e~ז-[0`jpРA֭ eA :ubɒ%_ڵkӡC^uԩԩSѣӦM+SEe^R7o6׭[Mhذ!f}pٳ۷/;w?gܸqtA=+VjÀ(q׬ J=p\0,N@L/hqj$1[[,ԅnͿP/3Wq >~yPM{틈 6>EI\(*T!jjYP>xȑ#$%%q18@z jaT4M{bcO>eϯ{Z sSLnpwPr2rwѣi֬g߾}ԯ_=1رcݛݻwS5 a_GK.hСCѣ}tܹsپ}{ߴi2ߗ\r |+УG3nqXVMĉxw#Fv3|pn7<'N`̘1TT,ZZrҥ IIIY\ 2dɱ=9jٳ'TRFѩS'<}z޽;ׯg˖-ݛ;vPbE_V_@6PD6|_xp[0 k`%Q-6.o~hwR+,on? Sϥ$LH@;Tx+A/GIFח6mʺkOەvJ+Pb} ͰChܸ!V5}Շ/bn?pC/*JW+~L˧F1U b1{*lSncI<;@*@nC_ϝP~G`' OmO@$XzQ@k hau5 II~dTǩ;vd^\+?g8w@JV fw`` luk,%fyKؓp\Trwh;fNRT&'7z:6?m2 AxDݺv!&:i7xoHW%=V:MU tBqy \yof/j_Sv$ެUPhб_))O1kg^?]딄A+tzEv{\JrU__Z@U--uO}B:ߒ=Ȯ {qc/f"V+ލb6i9y@?(..2\j.]y_\Gs)fAD>g?eKjt8ŨhSQak M, AYHoF 8N@?z_w:jT&7s~m@Q@f4i# .Dw Bn@>ZZ~\y${d` J,- k7lמeފ/"jDJcފ/X,n$K-7r]sR!..L3Ln<GBf VX<^7O +/οS7l, ݾt/kLגG@W(~x@[7=+TJu񔤊jP80W X|x~xA@h;p>{@ >%p&.S5hΏAG<}N{J7Q2'v}P7׼%M~ \n';91`h`@vlL#+(MJdd8^?ÇS\\G?⦛nBSi9*# >߿oZǩ9ϧ]vNR(La:~1s.oٔ\3v;GrWFVV *(1hт5kҨQ# Lll,s*Un_YfԪU Fbb";4M8+2j(~a7=Oz%\Bƍ]6ժUu4jԈ:peeՏN:q7ӡCl6Æ )a̬t ʼnTG3߿`pFan.OJUHKKiVu) /:Պoߞ_~.?~pByRSSR ӧO'33Yݳg111L<9sаaCN'IŊyٴiN;3ٳgq 0K. X~=SL?Łe۶m,\ɓ'IOOg׮]$''_vPfΜG~GkQ&ճCmAq?i$jkI 9\Y,.cҥ瓒BVV4lAFF*U2֭zԫW_͛""##ٿ?;w4kff&M4e˖lڴk`͚5fM`fvm8pL"##kaСqu+.J<7r?ֱJDʔ*uous۠ԭW}zt(.."77!IIIԭ[!7'&uQy25_ NXXg7"""X#T.O\~"'9J͚5k&6={s_HfY .t]w1M ՕW՗yCiSQܕ q2Uݧk' !LK̀f!!! Zv@= 3 nNY4i8}8IVBG]|>J(!vbrX S;ocz,YPVM஻rE^^K/CL"8. :::.ͅK\.ܚ AʘdS%]q6knpYN&X, +WZ P( lrb ÑRAS.buΣknؾ]י1CbE͜u/I `14pZKʧ9z( .4- Ǐz8^/>]'4$MXX=,4ӉbfCCCq]hFhH(. Jݎ",,>]Y q8bjv汐n?< 7 CCCOX,gu99lZVS)f{^Áb)Ӟ@Ӵ2޷pbFQqg5+..1(EE9JM V+NvWQTTDMs1h]{YVV旣j 0qntԨQÇ#L$r:qSTThM)*,,6Ėдitg_TXHqQ.=#=CeS1e Ddd$3f̠QF\^xvCaÆbڵ+#GK.eںK7n3g駟fȑl߾ʕ+о}{ F6mhժ)"""o7˴?c NnI&ݛ믿bn 2286mPJ#,,@w}!C0qDz^:&MDll,< ~ 0A>}HOOM6DDDP\\Lj՘3gyҥK2e)NJDD୷"11 pwǥ^JFF:t]v\uU1+VT7E]U4M#==A48Y OX6 tC,@HhZ:,KfsNt]?y9iL[2gfĈ|,X^x$&OÇ<+`ƌhqٲef22Eƌþ}=z!!!v|DGGsS5kV{9V\C=?C=nZ xw0 URXXhj&LEp8&boҧO^//f֬YT^y[op|rmFbb"}nݺ̝; mƜ9sV;>c>cܟ}M4ᮻ".. @f4hyyyT^Ǐsl6v25G}zLP-0 "B0 F4*Tj37aw9T♈C$|iAGDͯ݋0R>0S?kn{o-O@ΰ5F\\\d׎ <8cj%''{맔 ^C&M(,,dƍLhMXlٹI|,Yr/2)wx<RA X0ZJ2*:EŮV(u<234dj֬IhX(qekժUŐ+`/kQ]P‹/ ƏOժUС>(CDx駙4i|ݻ[n-cB.?ٳguֱ|rZnOKRR 6cϞ=bǎ7δ=Z?N:uHHH !!uIDd@qdq=mtt4 kS+!;vv:T^LۑQQ9v][+@лwo+`߾}ѡC2228|06J*DJJ ڵ#$$LH!&&ӞoРA|>-[fԩiii>|*UPreШQ#i۶-jբL\.^{-:tJ׮]M nSbE:DVV۷'225kE-hРM.]W7E`Z efl`qCX,Ng1揱 e}\_nRfmeVqݐImg-vLcEx^((([t:8qPO*Uرc+WA0n8222ܹ3"B.]TRP|fu !!!9rmi޾};ǏJ*dggsA:uUW]Ejj*ݻw/FXX]w9߬Y3, ۷j{nشi&66pzEӦMIKKA}vNi(ƏOի9W\A۶mq:,Zӽ{wѣGe| IDATEcbpwҤI3t]/zDGG}vZjENp:̜9zkFNZ*SPPܹs~tHى 7T2:e23fLG ""[-X@|ܐQ_P;6pegLWРn&jm6Y4Zbl6h&v 1 )s|yn7+X,2aZby~~ npc~/{ۃ[ɕcOȜ9Jn^deIvNt({ƍG&MaذaTP͛ӫW/gРAL&L+¢E7o̙3m۶7o^UVswvZ:{nƏ̙3/1c~!_~%5[oEjj*.9 F|'ݻoA^^j2תV믿γ>k|7Ws=Gvv6?0oW^yYa޽꫼[\> >gy ]h^ɴiݛ]+ix饗p\;1|>ڶm_`VݿtIi5oV5j$W]uv),,ڵk˒%KdȐ!rA;vDEEɾ}d2tP 6Ȕ)SCҬY3y7e̘1{Z-EVVM /,T=zC.R9qL2E5k&}ꫧ-"rUWIΝqRZ5?vINNH1blڴIo.*TqIJJ 8P+m۶\X,ҦMrSO=%7p+"qqq2diԨLKqq-Hqq;vL$%%EDD$--MDDP8 45 CdϞ=""j-n[''III|!0]eϞ=w^u]+;wCrױk.˓}ѣGEu냚]@ _~|scǎ j{ ÐY_Ɗ[(={%;'_iMjQ/.".W]u)7oeʔ)rQ9r<m64Mz-9plRVXa {JIII2sL;wnZx ٿnZ9|8N9x)"nHVvP(./^ɓYh;vȑ#,\?cf͚<-[L]w1 :u0{lnʉ'̶n.] yѣIII,_Ν;h".\Ȋ+p:,\͛7mVz2'gd<'o޿stǜ/"#;zTrW( ]-JCL?h&ҤI9vJ߾}IfN1vEED$11Q-[&""]w;#""2j(u]VZ%m۶˴id˖-7n3gU""ҺukywbA/~0OxPt"#FSJΝeԩqFz@Љr_.:t>}Hnn,]TL"ڵ'SӦMe˖ɼy\Si8?ӪU>ͦKvN+ ]P\LjՊzKjՈb54M#//bƌڵkaРAnݚ 3sӦM 0J*qF&Nb.cܸq;;{|wf<ȦMذaY{>c„ tܙ3fvٳgǏ=uq4jFQQ#Ff͚f63fP\\իyhӦ { :>̟j*, NPƏرc:t(+V@Dg…+tڕ5k֘N=*T ""¼sߢEp\ >]/^̖-[~7 (4 2J:B '%%Eik_E-JCjaH~~L>]233erQȐKN|W{nS+%33S>),,B9NuѣlذArss;02رceْ/˗/M6Inn[N Ð˗? ǎ;wʤILvŊ.V,YbwIzzx㍒"믿ڵk%++t 2rH|r yǤPX'y[/cYO 1;Zi l|>xrPrS2c Yp7 ?4lPׯܹS"""e˖eCCCeΝRV-*ݺuD%ؔ@WEDv-""u=EYPx^z|FAܳgOYzvi۶|r֭[MzڵḱÉ'$))I.RӃ|ǎeM]zH6m by饗tJnL~zٸqXq*;w4#aٻw)X)T }ԨQcǎ2 U{=KKxx\veҷo_Uvm(6M^}UٳgҥKjJz$&&F 6%Е@̘1\MlO'OwgjLZZOw}푢b84PsY۷# u|r9ٵk>^znbNt]رcU(.0[n嫯=Nc= nX,g~*jEn't#2*RrWT222Tp:1_~.]vx<...6_ڵ g0 nP%D E ͚5Gٳg5?|0n\Knn.BFFNCAAyyyfM'N "RHÇ'99Çs!|t]ȑ#rl\뤦r1`b%**#)N ӿs$ۧOf͚ų>ˁҥ C { 0իcZ6lO>ȑ#2 r1vڅ0p@rss1b?ҟ7o)))޽O<9qƍGرcdffm6<#<¨QXd q7ҥK{8x Ǐg<كeԨQ]lƍW&U-[HNNfȑ9E駟b?x<>bͯs{=**Jl6KzI6mLgݻk&[8OM''_}GVsj1cHLL0 ΝKhh(]v+뮣QF,X|Li|嗼KhkFVT*_~ӭ[7RRR۷/=z7n,n7cƌcXVj^x}u놮h 7@jj*7|3 ԭ[{n4hAp8zwM&MYflܸ|4UV0vX4;sm6,X@bb"Ōv8a- V8u>::(/%5Mn_`g6E4t)N-\C_kٰYK<4 ~\:lرc""eJ$ fKOO+W]Nn䐴ʓΣ{*Q9P\씼Ǫ|Oĉ'NZjѣYd cƌa֬YjՊ0;)^o8K˫дU.KlIB "p^0HHH0ם@UfM3Y*U*Wli"f#..]שX"\s f;m޼)Ը̬ώr@? cŊ< ]w9>46o\FX|>233MƍkѣGpB, ;vD4233Yt)~!t:gA4nʤI<^})@Q|jSG00 CYI.{@{Kn7YNt`nW I+u򎨛Gqn7OHh?:dcaҤ̔ /FAnMA2v=;?=UiS(TVjohڼ LJJ ׭0 ,;8|85kR(~qUmY~իs&%EdWI".(ָ ը|tڵkSnS麮L1"TfFӏ[jOu (LNҪԼT~cSeTWH@ vi* B7aԓKT'(NKv2) BP( BP( BP( BP( BP( BP( BP( BPBQQ"R3.--MuB7c*}Gyt𠁟(i4 w{_oz~[Gݫ:Gd=Uku|~^7o.vZA _7_7^%X*]f@%IBq#"W=SzYѺ V2dΜD ) S|vo7v'{zMgDX ,]l_U)vlp{ nX",2˒?+a^w=VRPɬ_cq§iK=EX*´=FJbbvs{ EGsk[~ڴI7Rxc' J/Y{oIV,[:677'^Bq Hx"|m kNy9mpY)K %F,ZL6_ыU "yw4$/ x VDK`ع]◽=Լ"W_qDn];wVPgV^Mǎ[&?~M- gA nԎ]b|1$6cFM~9(((ТD芿999!"r2o?U94|FPP\;wwR% Q]Pqt]ortjdBq\zi.[&cUk@a 6}~.W$ IDAThؔw]i^MhhTLBBV,`__,5NF-j[Hi6==H-ޙ6m:wuTb 777܋Ӆ&/D,GŪw 3 HMMUP,_|n+_!aRŁgwKD1nW|sJԔ#jP\c `]kzwaԭF]:oǎr]w~qA5_&|\VX^ t·3zl̋R@yg~bY~999 ?MP5kBP( BP( BP( BP( BP( BP( m۶*mBP(L֭ۈfQ6mR4BPK7k >[{Hz]ƭqㆫU( V5!0Ku߁piJWP( S a3BP@P( % BP(P( B tBP(ζhc=dihfbѴ/V,6+lAz9EM44MD a%nYX,hvaSP(4.hF~d"k~IFA4 }rBOXaƵDf̨V8eK$5Z]ǕCX@7c uwش'JGG_ډg.E4LW( afJ0DGqfb|32~~$穉^6w!4V0僅7r'^B|&,6嶁K:g/=- ]^xF/c:y1/ź5Wh );OYC>g7!v`cjޚ!Ρ{|ԟm_Jk3@8մ!qh|ȄLBBP(.Kt|c"U*ş;r#. Jދm/$> "D +%":*w=a$9](m)w4,Mhtu^{bOoSD ^6/#4xM} 1x33.: tj'4,_zh uJsLgާ .HؘWώYjDf|bI'R؟;XiE 8᧝1f%~«Fad$>&C?{#x1vz*TamKRzi9l-a{=IH؇ۍQ.f9sJɡ2Do ! HZ=C<P]oP?~/@54ʷWoLlG(fQ(nH#aŗ|ֹ!'ֲlN2b9>4uĢߓD(EW( ?H$֑XߍW3%!µGѾvZfL ^E68ʻ]se.;az3dNNa.O~؈4!oǚdlGl~7_v @>l0LJ`wxi l/=OZ:456 p z}ӎ/}yMd4 xf$? ޼CQNˎaJL qO?'?>mlSw z-5F B'=ެGٳL|^o`2tSJYhG?T|&C°tLOY>ϓ]MJNi8p/B$^?+eԜMKor"L2iL0b7tLoY]CXd&'^1.YJk:݅xmpY!wa$};UV( #tȡ(Ípp s溌#n܎\I@`8C18=`j[+c4[!!/4GqEqQ {HDsⶇ\Q?jʶM=LP( ?@퇮P( tBP(J BP(AW( B'gʸybia)+ EEhp; qͩnؐurkg"LDJ8Ԧl Bzpm9ڋЯ=t@*5W(|%S CpG9\* BP\e؝nP B&PP( tBP(J BP(AW( B]P( % BP(+ BPP( ]U( "Qギ# XJ B8F׾ wp{]k:,2r%:miii BP\4]qq_jvYy(vShQe}BP(.#qqq6  B"|eBP(+ BPP( B BP( % BP(AW( B]P( tBP(J BP~Q(+()(. pB9k 111:$$$HjTN͚5Okv+X۶o|`iBAhҤIH)UVuV&D̏B`Y)RbKдirφYzǎ%y}3b!hQnS~ P64s& ;x4eeqAjW^yڱܿ?o}18¢ ηFʱCOFZ2͚ĉv}i2`۸ $2O!L=ARNmW_B?]2~_}LO$Oۛ̈́ DFF'JρQӽ;w3Q#bL)IM,MLW^aQ|6z4׿,<s桶(^^5*b/V:o> TE^z'{0B0gluLTW2 {1kJ민@'nk~˾￯[H!nOVƘ>۱)LU⊗7_>P*}!>԰fSB Yx%5;{lXn7>R# v`Yb"#FpdϾk|t~m<%*^ee)f'MpF@qY/'3+Q X۹6 g׬9siݲ9?K!߲io6xJ,Gl6[}G߷~IJo޸уMSbr:Yjع ~\#jצŗd'!#Gd1<3rebAJe3Ѽ0v6!px<1'ͤč-ermfܺEoY*T˖1fH<'+ë__(TX\!bq?Ԥ#_; Qq4 ^ ;vxWIOOr #%3Ɠ|ICuRIxTw=ޟE(\{n8 vco.;vcq?G#ߐ؝. ƕCy[l J K~vװкlYwvQo^Oᾊ* KZJ [e@TRĕDDt\ڴu=<ϳgP@<~+%+W=SRO|?9t hiJV"2pagj2wB<ѽ>B|9(@}k{ ],+-aw8)X#" {_²ko/_+oqgX~7r[lR Pvq(a|+WLJLR݆U`iƍ]#5jgzӣy,[[=Yl^o{2TMW~_7jwkx#SOvz {###[|O"Xp?xbkIT{3hV޼e3'PMKKg%A?oMl6匋yg_O>w3p>}/YFB+ėqc<{wYKb+/u-^L針SMyarJU*@UhDn{)40 >h]w㖭`8 !X?}'ό\D7 %>{r-dEyr;>KצpW}ۂy8|X jzić=HiIro#+_R3# @Or_6h>[-SfuZj' ɝGA*JVyګ݇)(͇ũv]U6'~ PV"d-qܕ~Nl2}[v!?-@8o>-Kn2VDteKĴ,/sii*R !9їvs3sqYV'o)z,ϵIK>7+3FhtWGn1Tbo :x_pi)T?2RsO̴d&* N%+Cdt|lP9qd?i)ɔ(Q+{I_!u^%o|~1Q%& iϕNU7wogpm;Mv"=b`X3$KPD|^o'%q8L 6e2qqy2 S*G;F^5q';~:>~z1pVJU-(HcקSebJdQ-tjӚ7iyH /}?&3~ X03f~ZM7(w}7rG1wQ&?ڞ^nϳK[,>/}JV'9:CkcʇSrmU=YH|&3R}q:*BWL?YL`i' fpPvև{I6\ .ʳr)9{jޔ+.)cl_6r-[$Qޮ7>ޏ/ufM>s6N3Olt$aGPެϐ!X<tբ~/gL䇏We"Bd^}u c2bAvi|3)];"2vlB`w8x R͒{ߦ~asPɽ^)=)qBZ>Ǐ[)AWpY66.'"**"#"Qp7uŮ|x]3+VP۪^ZmޞOG|W#܂?_l̢vAh˒! ̝3GE EfǺhPOL\.ʀ~v -- ɞ-sWAg]g~d=iF^OݶNQqnм}V\o]`MS\ΐy/覟k Uś.olݾ̼/"ڸӍ].wK-Ϸj>R"8 W IDAT#)%^”yPFJp^_^utϋV=% " DhZ`"]GNLʄ˙+XghNi>%Fh)p .gFt._R6)\!8@U tkT6՜9daehOFwȳegbiI߁5ь {|RbLc?yb*Vy$ Ґf&bN5Ji(3ڢBL*+>v[)A3%2XkrL|V,a]pQ2:RBP(A ,icJ2!(Up(EN0z6I!\" lX2PYa[VOfTEzFXQW( ⚟Sfx-4#8zl9".%kY,8p\ DRC*ȭ#Y0bON% 6K[xM4-[a'93*Z&BP(A܄"h )y|!"4@v! {p ynycRa⢂+-pDw< BP婪epX&kuN|;hhcO/HB6Q( ſϵ;)N)i?Qt(I{H=B n IqG<ُ r*P( ++>Z<xS $ftCR:*H`ζlH\IfԶ}1f[0.W 3rfDJ 6 \۷*=[Np|hE>|\A 8d#q?.7I5Hˢtvh nXɴ́g>D: V(L FhU8HieIo@0M5l+`"FEF! uF7z6rM_tB lveIUb d. Ǣ8EwP~ZvO!֫{ &IU.wB3w`/Zȱ9Ҕ; F0pl[R6;tdfR TkډfuK^e ^I1N(D;om@8z7tx*Q*̈́4 4p𤂥O"`tVDzMx!9n2RdyҴ@0 |/>i{ædmD%qKҏ%oX*=!v*,qChY)G9kyn_}wV@ZjⰊ/H, gIkYxEP` S)`w[r4aI:an9{)< _!31б}9A{a麃NӧGr_Frn~Z;O:LDKr(CWs.U?1y}J`$~/`tmR5RHK/i+?>n"`D[9Gϡ'ɱt%J׈[؁ĕ8t4#0oA0l1%Zތ:1|>|o4ʭߪ#5EV-RUl SU'T,Ai۶ iP#4 Qsӹ 6Gw!#a8щq.V?Q4uV%aڳ$YW Mß-*;@rZW:a:\iZ͘G* [{;STc9B7znZf R;Q@ +CV B;S.i֥^Nit=}م')[GvZShV~Ǧ,uwta= lZtEGrxRRupƶA UzP 9,ZJy=;Ȼ wbב~G}ϼwz}qH݁a.gg9+fW6_-b, L{s'ĝTGJK]ύ?{ZQpW.L;Ah_F+8\ Aa`%1Y0W |#fv&+[⚖KX"I-%5偷ono:7ȯ߼Ţ/zr{FWkJ.+N&eO^`f`˦.L_?wi ܒu|Dq.jEJ0<8' dp qRy?z4~O~-cX u bŭgl8VDM̌#߸5*Ո+WW&P5 HaҖάūi-iuzόbbƖ- 68)uF ̴l%( {'s ibK\х@|$p xٺsUrAx獘 chӋhg2fw0E(W 6N8)vXtM)d2-p=L߹SDq'شODT$!aP ^2-YI;)Z(a ^Žʒ0ʇR5PD{??3ьӋ l3e0Z=s<ܺic䴣iЄht%k mT{b)K#]?J~o)5J|+Xv ϾE|1 S^S@&Zݔmt&PP;&dPX 4: 8G3u MeS71~}8ܠuګ ցuW._kd<~bB;|n#eIloӷAmgʻo.< .=rz,^Re#]= (+>{jw[ssh w/š4)`OrQ"*schwhG8lǶbRCn-/+q_6ЮIjsWgqjڕDyy U 9:L/=V-}N䕡xŸ^)(*ţ|t{r\CneɐSsiMc쑡=.nxi(<җ.X+U+?Y%Fm<;y&m۱vQ̍#{h\:g\SGXY:uXmZcx@w@d ZoR%MzS O%:Ez9kR.~# _ϔ9sG{5bL,_ypJO^Ͱn0whk}lWJ3o8]>1ԔԈ[*/Ȥ['P @4w7.(VjYTmY : L |ǂs9^Ad3 ?5vq {t}B 3lށs=,Xr-/wMJKZy^X_O%1)a %jsnh݊H=}UމKK"ϙl= Wi9")\V굸,-~_LFx:Խ+H<8LJwrG9(Vũs#)zTMmEbz j,;TN\քUIsR؉Қlے'}^>n !<8@D,Q,#Yf^#$oBKq\y@)ۖ3ogoغa)Du?Br!d*eZTiޞhMˑ-!ՂM(1]9). .ʎWRR½<὘@gGP$# RJ"|KK5 {'wnxb~jQ[z|J`yXӔmqzhuSE MO*యfE4,/wSZ9IrT3$>BT\5L.ك,Thч-; `W_6呄Vkǃ5ڝeBFQ@4HHsr;RYn~"%;xpY`eIZڭVnJpGx~%kxThهwEV?[ߙuSӣrg]V 돧8ۄxB.ať<'<b ϺCݘ~ߕɀs0s|ȞM#ss™g~I+L<\휜Nivƺ!NI]-)4OE9}go+Ȝ>&<8wKv;ϧu?h*_Nݰa`kR%0 )+z \o!iʐWרS(U$dt)=A{Y~J\Hd|>~۲יXygT\Vht\MԪQ ?;7lWS\{^dIl-U{7>=uiI'#~Udd (wd0z"ŵ&eʔ^|u+6.Yp|E#**q:Z 2y)OZlY6mvU Yayٶ%B|ޔ{_Kb"ލ.8w:֬!C(XEW9w3c_~(zT8iZޤV?)d7t#Pe;.jߧ|p ~ !'Ro_g)pFIDZ]qX_ 4RBho7!Ro F%J3}h,84 eeoݚ}^UdfX>ޜrבKj - ݞ',Y+ bm '3]R #^r !l7Tz+GH(],ih* zNQuܳn7Z#GHII?i~?)>G33d;m?p]|'Vpa֯@87TQŒa躖'6~nbcس7qNnY͸]p(]ltfiyPo& xKbaAљߋh9ks,`تU9ovST)5ilٲ,z0{6lH:c Ԩ x23Bʼ+B#rd&| nݺv-%+U[Z'3<[N Buسu KUTθP& bccA ~8hޜ͛iXxY[]ɈU;Uo;ip'T!. <7ԩԩS_2~n S G߂U Qo:zP.:Ǘ=F_(eg7t,gvZnY3ݧ[8a*fe LnwY&-P[m2{O01wD>*z3Xo>@(Pd>h8uDMHi u!WzqL_&ѴKht3}8c*Go#u=]ZdfR0* !Y1Ofb>q0mLT=qUedeR *0)Hʖ.]DЛMKgrvx}LC8QеOhxcbl6>gbPti~T%ۈ 7.mxj֨˕7J)q:|6j4ovđig2 =TR0tc'`h֬Y*Hw}$$$PZ5: |]J )-tMC bm sw0#wEֺuk֬ ТshI }/H6bb vge¬ѯ3qWy>Rr=|{F`H*S IDATKs70~3 uLX1} oJgB-J. v)IjC-W<{L9EXf8;ύJFۅ{Qtq7n|ŞNDdLtHbi*eW~x?y9T~ibi%Ϡޡ+M6Lq28{ T=݊9sfk֮]˯߾Ϝ&V;B歞,YڕBJIRa<^OVZɶ;\b$šU)AW\5QzXX g̱ hs+, d\4 t|5> +JÆ7\8oѬ^y_.-ffA|3M^g/w93V !L~ חCHKf^r=ofwQU[~92鍄NR#*bGAWEP* +DEႢbvUV (J^CzL;gf YϏ@HΜ9v{t̕ӼyhH]MqHIIa 2;dye(ۡ5ɸXV>e[Oո.eҊ=q)DvŰ+`…ik'7,vDkgEȲ¬X4/^BvFJKE[kSO=Ŕ)Scz&}y=nO ۶k\9 CXb>u7-e{Ί }xB]]¬YYEagj1Pn&v*#f= 'ARޞy9V^͢b;h B`E&55N;T~i={V93zh.̟gsӊ8JK;Дgӧ|ݻWzAjӢeKZleCJ :вeKZlɐ˯zV,7f2rCہߋ ŸT҉~[HޤT%`P2)NADAAAAA]AtAAAAA]AtAADAA]Ah]9?:z_Uy"[ PִX a%pѭא ?n&2sl=<|ĹKI G|6>( i?\qwNt[ƱHH" rA2ڶ˿rܮض%BA zb&Ca@?oʄO2:4*$c;3)uc,(. \!ktqׂdqkBNAAJqBW~.!d ]ADA8hY+rj`hn׮]Z"j嘛֐ObRݻwpTN BC)ł kكᎣNfjM2v;_uAAݻQ7{Wߕa(m)#ӄ2x~HSxi >%#UtA8BQ+w?k$F 38Ѽ2.Q-j}`ɒ,'Q[ס^f>lv!.TKsNۇ'VB jOSA6WOx'E]o!O-kwy< tހل~jV=[7Pヘ>P-αco?кk/B^~鈤sBqa.!yw_#7^SO?UÇK}Oq͈fS_к{WڝS`Pośwcp"p8/}ɿ?xB4dpanr㊉ QvksYg1:Qu7#Gzb[PZ(p)6x4=y'|zTF8!CoM.ϧbۺ8i renؖ!?lj={0|Rώ~:rcb'C Iz/ܡ $iwnD?77|dScINJK.q ={Kan''|1,>~r!闍3թd5i>ZQ?Z8;tb[d WW`e%PVZkSE7WOpk>qr!3Wfư,@8,=pr^ZJX)zw ?O\\k/iVX(x̟=sD&U-aB'pLٛ];jKy{h݋[8]BR Z twA["XVM7^OV-9䓏a#h'ExoOX,F6<̍@)~5~4VIdBO&ضa<}?|tҐou3 (eɶucS'/.>Hʝ5+b's}\'mS z3w`7HLLa{x>wHtEI($۳iSn޻|QNa?@Yi~Iמ^t;^dLm6iŷ%P] K@Ӷxv-L|!k0_5noSk@߷0i{_Mkqy"bl]=Ey{ |<2OInVkY/0bu5_VA_l?H1mɴzyh$#,y{c(`u{\w:pHcB4p(71=ɥ/^aN-arٗ\!3Yg=u ħd ՎdU|ዷ .t0"Ɗ+雚*i"~͙|9eYڶpyb4PCڤxôrDUZkpFS{yr)[PRb9*Wjq(z5ޙq;mz,Yc:2UUD ˏP/% 4kM9oӥO8mZv*IKK;2uNO_~W ^)b No|8RSpj^2wL=e<_{ [ŶDʯr99n\4g^g3dާ2ܼO vPDӴEEj|.<;N4Sv,MrLgɷ@jpxYg;) ץ{mǴ̐ ?wZ۸cYWclat_iݚg+|}Ju[aN1-ug mi]׋I`!WZ;^^¶E_Xmm3?bu+"Uz@Z7%V/]7!k߄I&ɼϤ0j UcK}U˪BP}#2'?f#))TPSޠ)ڒIɎST8 1[OUrxS) +._~ezvEQAQ4j\ O:v=N7A.'E7.(MX3JaER` pd|$דKĔ: G`O /bE" ‘AU%M).   " p8O5ĉg G+4Z+\'1 ҊF a2Fžm5Y$ ^~̷:vO3*R0 ͛DO9^G"uk/nW,7aXz;J $Q y^$GMH\V(C,MVAyhFKb%V]۽ = "Tz`(\1Xm`Θԝ "x[Y$J0`T ܦmUqm$eo [A$ІPavd-iPg֚m#woZFGwׅ^ arqwkz':aTNϫ,e0l01>%C "D߲,]q@./[ɉ۶E(zm>_B)acyZKzt7^'6%\Z>t".!Iv,ƻE-2ш)8'!1 cQ`Xm=O,7smtu;^Yn36pzmH@ ԏ~prܹ'Ӽ-?11)\֪p _lƅmhP2RMHt(VCU pyܺ Dxu?fYmGol`rIqҠ÷^ %=31&`;Od$-B^˅,a2m[-Yu0k^P>;wnNqȴ?)t05cY).̇Ax=14yk.wmb )̫MCܹqJ;TƗ[1nI;m"1+'DY6؜KSoFq" X~%{cҸ$;n|ܼh;cдIņۘ";wX¸99ͧv_GLZ{0Mȶ kۀ2e`XL\oUggenj&]7g&hAyz 2ByLݜ 9#;ahoii v¨%0(;r6O<^nm8Hȫ8٬9-z4 H }XBea~YΚ_S^H-׺13L-*_rfN-{rW؈;Ш_-Mь$05L^܂$Ca/b+i]@)g~/։ŰK\7ͫq96=֣gZƊ:!kVķ:vidq޴K2㉍N3f,3ڷ%m)|%-9jM8 ΝJDrjR3SBiMQ}&~5SpbTw1Lkז"Q{5A_e%X(ABwiG96{Wa9-05^^'$+݆=;b#k8qF*'\EcAyo(`̠glҟ`ħKO9s+ Lʦr%+eru+ t2[fbE,K7⎁WQx-x>rJ6 u:tE|, tw ]3I~7`y~<צŬ.geA]`6 ͺ|8^"L`j߳{61:e";tiBc}MMPV[aq3>gnmȔ4>Y-7ݝ frDžzu)YRQ{ Ϧ MͲ{0{M82> ͨݚ$WM=)@ȖS7}F6d#3 6nV Ԏ˻{ޚHUWpp:!X}xy4:;'TL݅;1?(ZO:J9"Ӿw EI/X6niLx9xLY[cj%|ض~,N?$m:sn$N]c #T E«n~)ȬH":ڰFu%Q5p%G6|-+mI4LnʿkA~Y*:0@k#>Ƭa"H27$CMȌwgDfvUc]8݉/5,R9R<kTL}0|66B4;6 S @cag{7bU`] A"ÑI+9MJ>& jxȀknȩxȜ&Ǔݸ /؆@xh҄f}o.&^n?v[j&N3S7[yz%6XN]‚Ռru"nqǷHN,V{{aMI)A":P S\p&Sϰٙ[ʜb T&.ax6 !!DY[OCJR]tjBɶ]l XǢOV:Kf,Ǻ|ؗ}0l,Ba?=¶(+fC0 r۝T|Ap;f+rƒD/;bqf JkيAS'.Os3vuYa$/MHѸ(], {)eö5ܹx)60E`oݹ!7VU h*Bku3ݏIDAT3{es˸?:˦'3# ɷ /64[9;>o~V3qNu>9Fw֕blɤs#ޡ"֌qy2_OF[@؅ K\+gmvrŊ]'L'Ǧ,z_ԣmzmx"ذ7,hIu0 θM &т>4fy3^6r^9.QbQ*/gԗiu r&NtҒmnC4j.ZNzg5F&2i"V4]MɑdV jhH}{HOgP|z=-K9iaQh*sgWDִkiA}[*0ʌSf}:Q`bGeh[(%g(9ck-ێԄpszmMGj +F6&bd4X!u֍яf[5qm (&M#kl0Õ^/թ o"l<U)(քtyOlbD>صC8>\@9U*!KڻPcp|3[UP7TdzIڂu謒;XUdܔO;*Bqt:n~nl6Uk*NlZcYG n c3'6dGf<8Na7Z?[G pdʁΏm[h4=~ WnC^ߏi<׿aúl-qc6V5)̄na Fǎ-[BjfL$`VߑԾ~⃁2N֚sgƳsHrwnt6.FK}P[MbkI ۴!%%:;w7BrR^O (0ʨu_JF{ٯRCA|$$$|[ҵ5Rԯz~!~]ޒ+ Cx,͚i^!M׬Vn."NhׄY4!.)PWym: \߯cYaJINNp4* :@cʟhۮ=oN+,l+Gkk׾Cv[c2P/aC0رc2MO?KvBb:\H3 ļ>JHLLD$aggIXV|5ܝ;*|Y{ }%0U$zA0 7^~V\LIWƽ㫅 1vScϔ1au PJLLLcXt!?W GZkbbb<6ȁ@no,.W PJVOL v .33>/{:tq|@uԩ(eU$Ygħka` l_8% 5lC)<ɢ;?GWK#P-?F-KuYtD*e5x+!A:o/({go6s5e%h+DZZZb|;CPҋ/]ܡooۓ/maI+V.G5""z<8.-A8a(7@/(*Iӵ\2x0nokil?b< }eB??|>__kx4kFQI ӦO7 )d&aĸ8JN>lK&Ltֈ\ 67Gd/zmCMqyW&?rI:(s byq?|ZbL$-- ˉmӡض~%$''c3u l߾2P($-0t:q\ԯ_0VgD)^͝w rϬ/h\Or9›>9O^cSw"Gu`֬ޣ'!25Dzµ èwrRh{!OL\#֦Wח^X #|F3_oD70kudlwώv6m*b^ qrr2ǐ-y|a>I3YJ),+̝Jn]8jD_-S1A1G|Ƶ[WZZ;КXpsˍr3\_z?1 bਇ8 KT.'Px&S{أkL_AN=% mm334JE +Ҍ.gWkms{t:rc]Lu9>_|\\6AHrrP~ѦM6o\ϣdy n Z*p:lvY:?X $W]Pm^?jq5ko`ǎaښW EBB;vCR" ,R/Ͳi,[ ÏjT Bv*tAA8 AAtAADAA8r.*AA?gekᐟM70y#)}AAPJ՗ =~[a͓b (>AAҏKC(rAAtaAWJ7A. "   .    .   " pP~^#w~." 5+PZR:餓i:в9  8|>N,*YIENDB`sardana-1.2.0/doc/source/_static/sardana_server_icepap.png0000644000234100017500000452302512174204305025262 0ustar cpascualcpascual00000000000000PNG  IHDRB# pHYsIDATx 77-ЈwDq@{t B&)7[D"* LN|[X*G}>f3 ŸiH ^1%6H\.k; lC\.mD' [qXCG  G8 G\. zz@tFNx_+Nzxz@[Xn uGt]GG\.\.~~~ 222777AAA444̅eqqqSSSYYY333mmm222ppp666mmm222ir{hqz :::mmm[[[+++QQQQQQ&&&vvvOOO(((HHHTTT&&&vvvOOO}X2&&&gggmmm[[[EEECCC CCC7"]&&&666)))''' )))]= G7w()$&&&]]]###&&&### =CwIU_*yb| GG&&&&&&'''###''' b_CG55 G###vvv&&&,,,׃`ዘtC{}u/9X0&xh6wIu/ MMMyyy???HHHAAASSMMMyyy\.\.///888JJJSSS(((ccchhhg4YYYg4g4 @@@ +++!!!vY<\v>WpsR3YqA\vdddTT )) VVccooSS>>> y@@@77cccS"O= f3pV%33vGG{{44 \\6{{k88999!!!j7ߴeeRRL3j7f ###LL@BBB(((111999BBBɖcEELjjj0cȕbflll.a@@@ BBB(((888%%򴴞MJJsZffGGG"""JJJttt!!!+++===!!!444!!!+++333"""LLL𰰰***gsig@g?ZHrogsgg666444!!!111ggZv}n _fx OkwwwTTT nnn""" @@@s~}nX/ /J.TTTDD __QQ QQ 77<$$$@@@TTTMMM"[[ ]] ︸%%%III!!!ww__@@@ ZZZ???&&&yyy?***VVVfff&&&???yyyMM||||||PKN+ 1A=0Ԥzwt  GUy]̥ʪ 6U oYG G 6 g4\.e3^0e3f4f4hd2hN&:&eiU   gKN?G!5V\>N Kʗ8k9 kkk% %%%%&&444222111222mmm444 mmm222 UUUqqqSSSiiiRRRqqqSSS[dm &&&vvvOOO...sssԯQQQ:::mmm[[[%%%YYY:::mmm[[[6_\.CCCQQQ&&&gggmmm[[[&&&gggmmm[[[b G 9 ^)))QQQ&&&&&&h=Ig) ; ; WJ ###&&&QQQ&&&]]]%%%&&&]]]Ԏ/wI/&v[=8 '''&&&&&&&&&&&&hhh>>d3ss۴hN e43R!!!f! PP<<<Wd=HR]Xm= }P#yc쳿9:d GQ[NXX`N^_c"9Wy"xxEO[P'` G1Wg4'_1{O#*6Bɽ_1(1!h6 j:\2j8sDo?wwwxK㍼ TxxxwwwOU}N,TUDN Gun1GU  ({DQt_i_Qqna   U' wnP ވ&AVN?> !tؔEE') a?<RRT ;D[q"xV`lW&) F e  :PgToevvFt d8 \vutt{{{𕕕  ===NNN ===%%% <<< ===㄄}}  kkk111<<<ooo...  kkk111  fff333  kkk111aaaqqq}} zzzXXXQQQJJJjjjSSS###{{{AAA zzzXXXQQQJJJ444'''gggUUUrrr zzzXXXQQQJJJCq3aʺtUJJJ$$$ JJJ {{{KKKJJJ6FU\.$$$???fff|||jjj QQQddd$$$???fff|||jjjLLL DDD$$$???fff|||jjjm G$W\ _~>.2  ???RRR ???&&&VVV  ???MawI0wkޡRg Gm7Ig)l$M Gx\BBB???xxxBBBUUU BBBabb' '7{.)))EEE$$$)))''')))!!!&&&wpWzI\MEEE333//////---2O^wO_j\M+**333mmmMMM S2^* ;;;MMM 444 (((KKKFFF%%%\.փ%%%###*** 222PPP kkknnnnnnzzztttCCC(((g4g4  ꨨOOO SSSMMM $$$+++***''' // aa GGQQmmBBBBBBXXXb AAQ|||hhꮮk YY &  22VVV uu(((VV### xx((ppJJᄒj7ww((88""qBj8f}}}}}}+++ **+++ gg(((hh_555HH !!!;;;˳p P7***?]z1F\Ͷkf+++@\y/F\555ZZZQQQ666666)))HHH ###!!!,:::__;Ƒ]٪*<<<3Jf*ՀDDDYYYQQQ<<  gsgqd _tC>  gg /g gsQQQ  ///!!!  """VVV&&& 555RRR!!!CCCs  zgA/ |sQQQYYY///LLL!!!&&&;;RR(\\::ff 66 S ccc```/ sRRR  ߗ66 BB3ssAA nn88111kk00㤤>>BB !!!;;;RRR檪aazz! BBBBBB  III111$$$HHHWWWqqq aaSSS~~~qqq---KKKWWWWWW***[[[&&&NNN&&&666&&&졡sss###sss<<< }}} FFFP>}P#yNUNU}U-q8Cα0dKy=MQ7{V1nތ(lҌV!X#["Snwkh-+\ qcoR#7Nd+_Wz(M T cV!C ⤔zX\' K7xxEnhyhڡ\)ycyDZl9G('D"O NW6?{|vFU' ' 'kRR|oY[f3% Z/\9jwxJ)4?BWmvJBWmqE˹Jbz7Sprrr9xO_ l: u PnPewG)8e~\8"""666777000鯯RRR"""UUU"""")0j""" 999""" ;;;""" Qjkkk^^^kkkAAAkkk1?M#3r _]  yr(((" U  J ^I  \\\GGGkkkaaa ___((( wIlE* SU:: T?   (6  eeeGGG%%%uuuppp GGGGGG TE~; GIjwI,ԯQ( wI%wnۇe+ x/// GGG$$$ppp/// ===/// kv5)[wI111'''111'''111 6(g* R)  111111...fff111xxxt((('''000RRR>>>(((AAAHHHHHHn.", wSlRRRRRR}]F]t&/wiv1m)߲zG G>5y&w^a~" $}'v<<AAAkkk@@@XXXbA≷+Q];5\^Vi}V6<$$CCCH)}vvvwIz3l6+ 5%wI ppz111xxx,,,VVVdddAvEgezFFF333 III ###$$$''' ###f;###+++&m@wwwxxxuM&```JJJJJJ|||mmmwwwXXXMMMpppddddddIII XXX :::tttkkkUUU888///kkkGGGSSS...[[[DDD ^^^g4eee (((000 NNN WWW %%%   444vD yF&&&WWW***}}}&&&rrrߪwwweee)))'''KK\\AAAbbh5fh5f%%%>>::55DyyyAAiinn)) UU=== rr '''''FF''ccc0022uM$fOOd(3rIf_,8++hZZ __&&DD DDdddHH!!)) ee!!!$$mmmooo ||cccnn̫hӷ::J``MMM#MoέоgQQQ Oq~~~AAvvvvxxPPJJJttth9XTPwwwf3wwuuO=66[vj;TOKzzz3tt~x 888qqAAA### ===tttr? f22,,VV????~~```r? f\\\\\\ 888 BBB :::  h5fJJJJⴴffh5f DDD )))""" xEfNNf666 """!!!$$$ 111!!!RRaaa)))%%%&&& %%% 000!!! /// !!! LL  """;;;@@@***222 """KKKAAA ***%%% %%%000񡡡bbb  %%%---MMM555!!!HHH222""""""??? 崴WWW WWW!!!;;;{{{ 111"""""""""BBBMMM◗kkk!!!000 DDD  !!!/ mk gg/ 555///;;;``` ,,,ph&svu@&y  E뀷gsggigt oMMM```   !!!!!!888;); g ICZE _fccc 111!!!  XXX(V9,R|rƥϵcvs~n(glZhggg r{gn   &&&///555]]]/ /av;[;N~ y/ / QQQ   hhhs/  ;;;)))(((jjjpppYYYpppBB 11ii00RR __ QQQ___  QQb  rr DD >> ll''#ff55 ddd%%%LLL888ffFFMM~~ BB++<< gg133 >> ]]]!... yyydddRRR ZZZ333~~--*QQ!!! GG 111!!!111 """ wwwxxxKKK*** hh--kk!111%%%rrr!!!JJJNNN666///RRR???000!!!!!!LLL ]]]CCC...mmmuuu,,, !!!---'''jjj666(((GGG!!!FFFGGG333'''DDDRRRXXXMM///Ѩ)))333@@@MMM lllqqqFFF˄&&&???555f3٭%@k85"XXb/E5X0+٭%@k85"S*gS՝mRAs_qkwQ1ǯ{'Vl|Hӣd&Q% NM{<=xB7ӣd&Q% :SxV5S*gSYcaGaka +eNU.j.jlltn-]-]N' QQN& -]-]N' ]^kYcaGakaŦ;\ncS_fVl%X J' "X J' [h8Ŧ;\ncS_;\mϤq :KxRglFN=xcuu,'es|F=sv$QmfSؠi6 XjX_Sؠi6 XjX_ ƁN$>6Zi ;\mϤq :KxR1\1\F|FSGOvO `[[`` `[[ G1\1\g4gg4 !\w0=K鲜;73 ]w]w뼑i&,1nF5FXTo I{Jbx˴jA鉵AWoZppBxQ+g6&'3@-$g5d}E#>>>sEn= .>e8 iz{{8K] ը|X|| h6"R~ĩgF AWm]4{̘ &1<})4?bMf{.=MZ~3{}I.K' ߯p-_ N1߯p-_qK.ɵUB [ tC@U_uQNLzX_uQNL4q4qG C0C0 qթNנ=`A8q==`A8q=  dc GGw` AvA  DD AvA G] =] =yFYmccccm Nj \N\}}}}}},,,v݂gh0mm=]Fy^$s+ٍmn|߆{Z-R3/T-oR. $sebP L///%.6qXdV-.#JpV%:?f% <# q2j2P?$&H"+5%'?hnN,[kV}B;mbwx!`"( "& N O4K' ZCɁ{[5`} 5D{DKK555Q77@{y@{88 EE*wwsCCpZZ   :::טO {m XXXXXXRTV-Op%/: m@<pppAAA\jjj|||fffvvv Y##%  QQQ QQQ !!!*** QQQzzzzzzwwwwwwN }5 444tttBBB444'''777444+<<<XXX...]]] |||111<<<XXX... @@@lllbbb[[[TTT999<<<XXX...ppp___555 ?*** ܎SSSXXXTTT333 VVVOOO (((*** ܎SSSXXXTTT333000$$$WWW???*** ܎SSSXXXTTT333nnn___qqq...###FFF gggAAA :::vvv PPP...###FFF gggAAA555555)))TTT...###FFF gggAAA$-5`z3BP5cFt2`천++*666DDD000 }}} 777&&&SSSRRR666DDD000 }}} &&&$$$+++dddFFFeeeXXX666DDD000 }}} ZtZt忙EEE999!!!%%%$$$EEE999!!!CCCEEE999!!!!(!ZZZ^^^"""  CCCkkk^^^nnneee^^^6G )AS;;;fffaaaqqq666;;;fffaaa;;;fffaaab":n ! ] +0  ,&!5&!KKK;;;FFFmmmzzz)))%%%>>>~~~jjjKKK;;;FFFmmmzzz)))BBB222KKK;;;FFFmmmzzzU )P}.$I=*wSg  dU -  HH!#HH!eee GGG$$$uuuppp ???eee GGG$$$uuuppp444%%%+++&&&777eee GGG$$$uuuppp| @iRs#4\J!X<\wV3kN4_RI=*wc DFN;G$wNTru{΁*eU']Gkwc DFN;LKf~t9'/ #UYx\c-c-GGG$$$xxx GGG$$$xxx::::::$$$ GGG$$$xxx$$-BwxV^[VJ7"* NZN {nT^[>SS'''/// '''888'''Mŀ/|Kl}y᭑| BN.gZC[is&+awM/j-( BW;cW3]4n111666;;``;;|GGgJGG"UUgGG2|2gG$$$)))111$$$)))>>>'''&&&$$$)))lll LLLccc///&&&%%%###jjj!!!V,9/`5wKCgt}@##>)))jjj ,,, g4wI'zI Awa+I*S" tY%dۅ&w_)ۈCjMKV?J`>>(׀ TTTWWWAAA666J J$z30$h n Y^2 U4eF K)zc ffz**333 \\\WWW111111Y},m,S 7]7^v^| `````jjj***>>>'''||| YYYWWW555 :::XXXUUUkkkĎ999jjj yVn``````$$$FFF777RRRRRRTTT%%%~hT1?M^0///PPPhhhddd443443opqmC\ddd,,,LLLoooMMM:::555 ggg k### EEEMMM888000AAAyyy...~~~aaa333UUUooovvvvvvqqqqqq{{{UUUzzz;;;KKKLLL~~~&&&(((EEEFFFhhhuuuttt(((444000iiig4g4ZZZBBB 򭭭???LLL  000qNEf#0>sM=\{(7F   ((( @@@)))hhh^^^...000444&&&,,,Ѱv111eUUUDTeTw׷n***c\\\AP^W{TTTnnn.OOO;;;///#####<<<<<  44MM """rr!!iii 222/// DD..tt ]]]...aa yy  444bbBBBIIIm@~~~3qqcc>33PPBaaap pCwww3h|h[[[p BBBBBB..柟%%0088@((&&&///dd \\JJCCC ..KKK⤤^^^$$򽽽HHH ((///$$DDDQQaaaӻnTd33*ggHHQQQQmmmmWWWWWW888]y7NenP !!!c½OOO999\v9Rj))9>>++~~00咒SSS66<<!!!JJJ8888{{{VVVVQQQ8888{{MM!!!RRR][[[3E|`~gg22ssiirrrr5?Ic_WWW3?z^vvv4=GdJJJ  zz!!!77 +++,,,)))!!! RRRa<𮮮CCCfNN.@@rrssFF6ɎDDDo!*b;FFFfBBBo!, 888""" !!!666  333  Ȥ;;;m99:uu66ffffeeeeʴ ///FFFPcuHhǦ999m,,,IIIPctHh''' 999 ;;; %%%DDD 444 ;;; !!!f;Ћpppf3c~~** vvywwppp"(-ng<ϊqqqf3}}ppp#(-m>>>===HHH %%%%%%--- (((   f??$NNdd-->>-jjjjjjfhjjjjjjf NNN??? HHH!!!///III   !!!ϴEER$$vvvv____Ӵ|| ((,(׀===DDD ((((((""" 㿿!!! /// !!!BBB22M""))- CCC ''' ))) !!!AAA$$$ ))) 444!!!>>> +++ ===<<<!!!&&&&&&YYY 555NNN !!!MMMNNN111GGG555!!!))) 󂂂!!!444lll  MMM [[[BBB999gDpD/ NNN---!!!111%%% HHH666!!!LLL!!!  !!!gD/ DaU8{gHy~ RgE)gHy~nnN¥$8sa hBx! rg!Xy`,m|# {gXy`- OOO(((:::  ---!!!%%%p'fhogY hp  hp里XnNtz[ gtWWgp펐gp ggmgXhogYOOO;;;```!!!444!!!  222&&&HHHLL:?hb DN <t gkDN <khn8 RGK?O I OOO???    YYY444!!!kkksD{~UEBUEB AMz ss/sPPP555     000!!!'''###...!!!RRR]]]ssPPP(((>>>666 eeeJJJ%%% ''55M..447 lll:::___   """:::444 WWWLL <> 55 [[  HH66 888111!!VV !!!999濿%%% !!!ccc+++lll&&& ss..kk ff!!B 111!!!hhhݤPPP000YYYwww999 ..... ###򭭭---,,,!!!QQQ---444UUUTTT>>>wwwfff!!!aabb111 !!!!!!ނ|||$$$111:::hhh)))ؓXXXSSS### 222MMMWWW'''kkkGGG'''&&&eeeẺ&&&<<< XXXRRRNNNmmm777lll???NNNCCC777333xxx(((mmmjjj^^^AAA***---<<ʠf " ϼ4K%D"% ꡤYT5ɌHೣೣ̥oX Ԙ`t=jʠf " +|Nq +Lw~a>i:e X!i=<sԤuKB~)4 %gl\^&=xujix|F%gl\^&=xujix|X*EZy+|Nq +Lw~a7[ `[[`\F|FSG GGF|FS`7[(׀g4g4H$ nT:H]rNcx o$+_z1?M1?M8ER|    ĵk :?BuwP)3F\***˼ƺ trdPkY$S S  - S  5^'^'LwQwV-x,⫓#_ ,⫓#_7SS/L. {Рo71_\APzc] {Рo71_\AJO)JO)`  GG` 5``Xsg Xsg Ȥ&.""|X"-8+5yn;WO$X ⎄ld  ,ҔO/(׀NXSRAg?ˊt{+E]HN?vR]+dl1AkF[)dn[_-w\fCtó.=MA\!u1NQ{E^yHlsoKqm65?bL!,,,.=MA9"3 LL<@Bب&X/{dL #&컑 DѿZ4]dLa @컑 A컑 BB͈AUC!ƠHȳ80ss sbb***FFFTTT !!!*** !!!*** QQQ !!!***UU|{{III222 !!!***III222 ttt BBBIII222 \qvv'''hhh777III222 '''hhh777{{{444'''hhh777ぁ```AAAlll777'''hhh777```AAAlll777]]]QQQ111```AAAlll777444333DDD\\\333666PPP444333BBBPPP eee:\ @@@lllTTT999```AAAlll777 @@@lllTTT999<<<NNN... @@@lllTTT999浵(((666vvv;;;ⱱEEEeee@@@ %%%&&&333  @@@lllTTT999@@@ %%%&&&333 )))꭭VVVKKKUUU(((@@@ %%%&&&333 >>>JJJ::::::NNN(׀&&&333AAAsss$$$WWWsss???@@@ %%%&&&333 &&&333AAAsss$$$WWWsss???aaaTTTKKK ܎TTT&&&333AAAsss$$$WWWsss???===MMM999666555SSS&&&333AAAsss$$$WWWsss???666555SSS...!!!vvv UUU666555SSS)2;PYb&&&\\\]]]666555SSS&&&\\\]]] 777gggvvv&&&\\\]]]@0!>PaSj 4. 4õn $$$VVV&&&\\\]]]$$$VVV&&&000갰SSS$$$VVV:FR$3A0=K0=K &&&+++dddiii$$$VVV &&&+++dddiiiDDD ))) &&&+++dddiiibrHay"+5 000 &&&+++dddiii 000DDD999%%%  000`*++)))  000))) !!! CCC!!!))) KV`$$$))) $$$ ===$$$Z}]zVVVAAA$$$VVVAAAkkkVVVAAA0=KUL% l zzzVVVAAAzzz %%%qqqzzz(  N{gKcy h .Q [ !M_< [ !M_C !!!zzz !!! (((;;; 666 !!!j\  V @ ;D#=A = hh t Q b# e Q bEEE (((,,, !!!EEE (((,,,GGG>>>~~~aaaEEE (((,,, Z@#! o*2 )v+q wkv+qFFF(((EEE (((,,,FFF(((KKKFFF nnnjjjFFF(((ɗ%FnaomwSI=* S .IhhAZ :::]]]FFF(((:::]]]ccc"""FFF :::]]]|%'xxI(wLu5Q >iD f,QlB X;)UlB X;444___;;;:::]]]444___;;;$$$xxx444___;;;7 1wNTru{I+]Չ2't])I&Ad:Tex#4\J!X<\wK;m]EkI&Ad:Te O3G~'** ;5w5:::/// 444___;;;:::/// :::/// -rB8 N{- ,!/ +"G/$iL&###888######111###}xSNz4/G:5ìM7>j-N.ZCqs3wK-/ܗ666###666666 +Q"UUg GG,g;;|GGgyyg...666......>>>bbb...>>>bbb$$$--->>>bbb𝝝...>>>bbb...###...yyy :::UUUcccssssss... lllvvvppp}}}HHHIr %[PUJ$^# dddvJYggggzVHϤ-d ?###uE->>cccKKKnnnhhhHHHrrrDDDeeekkk"""箮jjjKKK```"""HHH???RRR999jjj 777&&&ttt???kkk{{{GGGnnnrrr𿿿勋NNN000&&&DDDg4ޚRRRf3𞞞HHH===(׀BBB;;;觧BBB000쫫>>>777 AAA  󳳳AAA   TTT  '''/// @@@EEE   EEEƠząe   ??? ~Rfffppp &,pY^^^hhh %q    000LLLNNN(((555 a7ՐjjjjjjKFKo#d:ϊ``````DDDo!*777 000))) !!!WWWFFFxxxYYY333 >>> &&NNNuuzz===<<<xx ++gg111///]]BBqqڃa?88888&a/@R߅a>///88*`~2FZ AAH  ((44 ssNNNvvMMMhh )))ggNNN!!!{e!!!l<>000,,,   ///::: +++/// III%%%Ӵp+++xX33&ccmmmmccccnn%%;;5\v9RmѴp+++yW995]t8Tn$$$999###㶶222 666"""  h5PPPj<潉_ k x RqWgg>Fthpgg~g $& D, .aD@u3 .aDOOO---  %%%   {JF܇ 3Ix豜m&B.Dz6 @JF܇ 3ccc??? &&& %%% |Wd ix  :::```  !!!       p~GO8LuT!"!Ed5hwFIAO GGO8LuTwwwOOO&&& !!!     999v ;Smg#}uW{Z{xvgpW{T©hxx~`hvt AIhg*AzM;Smg#}uWWW    ~/OOVkV|gp VkV>W>W~ss.<[<[ /OO OOO111""" HHH """qqq  ===  ###!!! 888  ttt999 ///### PPP !!!    (((+++WWWGGG CCC KKK 111  999퐐  sss$$ BB OO !!!lll222///&&& ,,,>>>YYY jjj DDD !! AA33rrRR MM ttt555   孭aaa&&&!!!&&& mm77aatt %% 111~~~WWW@@@...!!! ```GG 77ff11 JJ ,,....441(( HHH555  !!!***OOO""--AA !!LL ff !!>> 55;;X111!!!vvv~~~555 ###((( ???33SS 9900(( OO ii裏//%%DD999###!!!!!! nnn(׀555iiiZZ  //+II 111MMMJJJ(((&&&OOO ??? #### &&& 111::: ***777%%%JJJBBBcccXXX  ))) &&&111*** ...555 +++nnn)))hhh:::}}}111 !!!!!!$$$ <<<RRRKKK&&&wwwOOOVVV;; TT$$  SSS+++000KKKAAALL---888 !!!<<>>QQQ)))111QQQuuuOOO<<<ZZZ^^^www MM:::IIIMMMIII@@@<<<///vvvzzzvvvvvv\\\bbbPPPeee}}}KKKppp ~~~ssssss???ttt777]]]ZZZ999vvv֓"""333HHHOOO 999uuuXXXXXX*** @@@XXXPPPPPP ``````{g4ʊWH`hF Xb:X' Xb'fOtx(ʊWH`hF εfM.P2Va|ji:X' 赸ge!{kjεfM.P2Va|ji 1K}Kﷱod/C<]kXL@ʹ:X'ۚT.qrﷱod/C<[h\Xf,R2ﷱod/C<LL4?*qx@ 1K}K(B!fI 4,:"0C&1.Çy$=B ݃qzy 憎x:ߎ?@oq?:Çy$=B ݃qzy勞Ým tyԐ6Çy$=B ݃qzyMmvϨ@!(B!fI 4,:"0C&1.!\x\ӜLQ.*?=ٻ,@Y7)@[;-jxg*?=ٻ0HgF  D*?=ٻ!\x\ӜLQ.$9$9]>f߆orՁ7 <;aB,)Zd Ձ7 <;aB,)Zd Ձ7 <;aB,)Zdޢ >`$9$9]>f߆or|7 ;esS /N1Ӓr ()* ª/l7ϓ/N1Ӓr /N1Ӓr ՛3ff1|7 ;esS 0#|nnZWW7 ;Ii=ܑò` HPW:Ѳ`:X'&xPMR-q)m;Ii=ܑò` HPW:Ѳ`:X';Ii=ܑò` HPW:Ѳ`:X' ƨX(j[w$0#|nnZWW7  8lC{C|G`/v/vARC{C|G` G`C{C| G` 8l g4 U+  Ϝ 18?~|z@7.TVYǸ%1;nmg2N&1=(1(5BIKLrqrtdVSk µqQ#+vHa|(1(1D[q(2<ɧUUUG[pyS,>Qf |vYYY555 q ToRl?<bbaڜ|[-8L^[x*8FUo 111[[j]UUUƷlˉa:)6D| :NbSg{|t4RRRu++רEVVzzz*8F}Q%YrYre@hhhCCaeeX~~ l; BWlRn췟 #VVT]5!,6RnqdUqUq)6BPTW5XXIT]666z{Yμnd 1(1yKTqdŸ888,.{N!!*.;H::333b:@Vk!*H]rIJKKd~Ncx  XbPmb.J:X' V1R1܅o;:X' UG6=:Âc$/|9iɗ|J $\ED5Éjd{|J $\ED5Éjd{Ye KB20/84 $FKUG  bb0S~kЃ_V_f4vB4K' Lk'swobvB4K' Lk'swoGv, ;K}*8  SS G`"77%#SsS,DD"77%#SsSG`i Y  ?,i Y  ?,RY_l5CR b: b:15uM&88DŽ_1}$.8|zy|zyNOP`[u G^vꠛd{ U`Ūy7I\ `g`rnfI!t]>ݜgK_]/L3գ+"HtFSDΧ !;-Rp74"^_QZCܝ"MQ[@䬽 #OPW> Ҿ%JF9>A񹳡$N<dddPPP !!%0:sČ6t)TpcbL蜝mfk\{=qQKU`dn=ig|ȒOIQI5\\_IUI5YhR"#.F#*6w `~3+RDG0 :: ~Yu̬2S]3wydedn?_̪1}% 5z #.G( oo܁sKͮmix...9K^")ؖh8"" 2P/Օg;& ؗh8#ؗg6"ɴ 5M dddddd"""[vFYmۧ!ZT Ji;ݒŷeE 豹v.yO9;N|]|xxus)˖-uP=ܧWXۧWTۧ WR#>)u4T`u4T`W\Qsr'њa`sQSUa4tz%/: *5++D|D$[S[S.q=d=*++++883333N|N;e;.`a>ttXb:X' ##+~| ,yyyyyy hMgE_ Z--)**d;  T1111,6?qǸ,9HȻxvvWJJnXXvv,,,@@2#*kpGFFgg 1HH[dd!$W-q nJ򴴴bbbbbbdQQQ|||܀wI~"+5qH FED}}STU\XqI^s˄dATU>+8F4BP(1#ξΝr===|||AAACCCҕ9AAWWWVVV???{{{nnn҅WWWVVVCCC@@@111zzzXXXІTTTAAAUUUlll~~~YYY؊vvv·mmmVVVYYY|||TTTCCC҃jjjWWWyyynnn 222...ۍRyyNE9UGG@@@@@@@@@@@@L--((\h wwwѷCCCѷCCCѷCCCѷCCC""___iiiWWW>>>///ѷCCCiiiWWW>>>///iiiWWW>>>///iiiWWW>>>///6``hhhhh헗999iiiWWW>>>///hhh헗999hhh헗999hhh헗999HHHHHHHHHHHH,,,e%%pppmmm;;;qqq===hhh헗999mmm;;;qqq===mmm;;;qqq===mmm;;;qqq===>>>```qqqMMM:::[[[ף ^@@@--- 222mmm;;;qqq===@@@--- 222@@@--- 222@@@--- 222===nnn<<<]]]MMM999qqqcccwwwPUV ,,,===ˌ NNN777@@@--- 222 ,,,===ˌ NNN777 ,,,===ˌ NNN777 ,,,===ˌ NNN777楥;;;ooo___LLL;;;⣣bbb UUU ///QQQ>>> ,,,===ˌ NNN777UUU ///QQQ>>>UUU ///QQQ>>>UUU ///QQQ>>>JJJ:::pppBBBNNN   --- HHHIII KKK&&&EEEUUU ///QQQ>>>  --- HHHIII KKK&&&EEE  --- HHHIII KKK&&&EEE  --- HHHIII KKK&&&EEE㉆ 8;?}0/,333oooSSSsss  --- HHHIII KKK&&&EEE333oooSSSsss333oooSSSsss333oooSSSssshv#mXyXyRZ5hkm### ,,,###RRR XXX333oooSSSsss### ,,,###RRR XXX### ,,,###RRR XXX### ,,,###RRR XXX>HQ¸z| 444<<<'''444---### ,,,###RRR XXX<<<'''444---<<<'''444---<<<'''444---=0"]wk#*ŵ((($$$ (((???<<<'''444---$$$ (((???$$$ (((???$$$ (((???@2%!(;K\'2=**!&&&/// 444iii$$$ (((???/// 444iii/// 444iii/// 444iiiPF=DXk!(EZn>>?___ttt/// 444iii___ttt___ttt___tttOe|NcyU :G @a1$$$mmmHHHHHHBBB___ttt$$$mmmHHHHHHBBB$$$mmmHHHHHHBBB$$$mmmHHHHHHBBB q TD E )))  +++SSS$$$mmmHHHHHHBBB)))  +++SSS)))  +++SSS)))  +++SSSmCSo 4  E9O^j RWvSB @~ o 0*n.! o )SvS}A7n.! o )SvSB  ######---///)))  +++SSS ######---/// ######---/// ######---///0Vn 0#! uUAmx~~^8: Kxe $0aCYU YmbiHᤊ%"EwP[HdzߡS1U_jpemUtAa( ݰ-$>aCYU 彍0'CiFVHﭖZnemUtAa( `s IX~ o`ww; @Uo'  P:A[aUo'  PFFFEEE|||qqqMMM---$$$cccFFFEEE|||qqqFFFEEE|||qqqFFFEEE|||qqqϸ=yp#xoxYFv;UukhL ^nu?߇jdio|1Sb:_* 졡$g}8tYFv;UukhLa3vՄ:PlhK 졡$g}8t7nnsscc?\\]]TT- TT-((( CCCFFFEEE|||qqq((( CCC((( CCC((( CCC)BX6 Ql}⦖E7CJ%2(CmY)BX6 Ql}⦖Eȴ'LkO(gy{⦛E(CmY--- ((( CCC--- --- ---  382.N    `o`  --- (}Y@9fiKҏMfhQ$,?bAɋ5s=ᩓ&bj,?bAɋ5s=ᩓ&bj,@jK˂-p:x ;uXjP::: ::: ::: ::: 0}0ˡJ !1Q8TtB@ްkt*#C~6  @V}cXNePB@ްkt*#C~6  9鿎t{2QB1( :::     6iQ6i"RgR Gg Gg 7l$"RgR Gg Gg B~^B~ Gg:::///fff :::///fff:::///fff:::///fff---bbb:::///fff---bbb---bbb---bbbώ $$$&*-~~~666---bbb!!!...666666GGGFFFsss666瘘///;;;DDD555bbbbbbea^ꠓ_{ Uh!癐b Qf# BBBSSSXXXSSSUUU666...%%%崛ŵ ---RRRggg`o`dZBuf.氘Nk rwf WWWឞUUU !!! ® />NMf\zI%Z]/R7ԣ+%JtKTDʤ ";2Tp;6"ԣ+%JtKTDٻhBI|\k@`d V`y"ǎam>/@K&Ͻ'LM9?A44y {{{eeeWWW;;;***888h6 H_xE\sE\sŒ7t/쫠cpciQ 眖ifkc=mQK\hg߈j=im'hpciQ 眖ifkcsE5K7}CM"kbmN8t/#1H#Կ-8\tty&&̷|||===PPPUUUwwwMMM<<<Ȫ5Z:|p7zy dmdܾj?[{7zy dmdũ8Z;Ȫ7(ǩ6Y:G+WssCCFFFCCCXXXjjjqqqRRR,,,zzzؖh=$"% 2W2X"% ё#m<$ؗi?& ؖ i<$ȴ 6MyQ]] ++{O++pppeeefffjjjRRRBBB222:::ppp٤$\T =Pk;ڏűgE 籴v1|V;;T]yuxxs*̖1yU>=Pk;ڏűgE 籴v1|V; ٤#[U٤$[S%?)(((hhYhh=۾::HHHVVVMMMdddnnn```vvv\\\kkkCCCƀ..FF [Y[Y 0z>l>FF [Y[Yiωi ....<<eeeeeeJRRN//J=  ԾwWWWWWW@@@OOO333|||XXX :::XXX"""hhhpppKKKSb:_* ,,d555wwwRRR###nnnwwwqqqPPPppp777!!! Ggjjjjjj777___VVVXXXXXX999SSS&&&eee```___999###JJJJJJͯ ***<<|lE jjj...>>>zzzVVVjjjPPPxxxbbb!!!rrr_bd`3!(uM&NMMqqqdddUUUUUUQQQkkkkkkVVV"""KKKmmm###///RRRYYYiii>@Ah8HXɺmO%%$kkkaaaEEEBBB333CCC888999###777YYYVVVhhhhhhttt222qqqQR-/=K/>>DDD wwwwwwћ999uuuJJJ^^^___ggg&&&>> 𙙙,,,AAATTT&&&%%%٫gggdddCCC\\\sssgggggg %%%OOOjjjJJJuuu dddUUU]]]nnn(((EEEEEErrr,,,///___mmmJJJ WWWKKK|||lll888 666www IIIIIIzzzLLLEEE\\\QQQjjj OOO"""111ѷDDDLLLtttppp<<<!!!*** g4g4CCC---㠠!!!000iii(((222  BBB222 ///AAA  ///&&& @@@/// $$$...///(((۽ȿ&&&&/69Qi2DW㿤ż ***$,2:Pg3H]   888...  111 &&&ڽZZZ((( é$$$XXXqqqlH#2DT@Yt ʱ"""RRRuuuh2BS?[u    ///$$$  ccc'''%%%AAA CCC --- %%))PPPHH !!!¦ø 999lllbnWnWPPPPPP݊y -9C>Xs ,8ƪö666hhhhXhOFFFFFF剉n +5>>Xs$2?$$$,,,&&&PPP%%%!!!xxx!!!$$$  333   ... ??33??? OO;;777666 [[``... || uu || \\==BBB%%%OOOuuue܋uKKG||!!!###$)07L`8PfȻžJJJvvve"',6I^:Tk ++        666/// %%%***]]]FF III ::KKEEE nn**  55 UUJJ  44))) && XXX **ɾ^^^**DD ==))!!!+++˯111cccuaay\?ȫ 22SS====ǫuu88.ttJJNnnnnnn1@O>Yuϱ...___pggvWggggggɍ0>J?Zv%555ttPP ^^33++""<<44 HH QQ000$$44qqq  AA BBB!!!"" MM77ط000;;;77 LLGG;;II  $$II((( RR>> 111ּEEEuuubtt|??MMcccc````Orr%%^^arr|>>>>>>슊v )2;=Tn);KڽȿCCCrrrdpp777})18;Sk-?R[[ LL FF AACC::66VV zzBB񮮮HHH```== ..==㞞ppp%%%//  :::##DD MM((((((%%333333 77)))RR  333ڿ'''[[[nnnpLхt))LL77BBBB HHC}}%%%#(6HYXt(3&&& XXdd == vvqqMMMM!!!999 888ϸQQQuuuj풒xBBLLllll \\\\XuuX""\\\ss ***&,3:Qf1F]ѻOOOuuuj&&&%+2:Oc3J`  << 99  ** +++!!!  ... ###  ɭ´444ggg}a[cHŅx ++PP..???? EE=}}++- wwwwww4DS=Yuͱ111eee}``bEtttttt4CQ>Yv     ???!!!/// 333%%%%%% $$$'''ϽļHHHvvvf||99RRRRRRssչ22&nnuXXaFFFFFF剉n -5?>Zs"0?ѾùGGGwwwhwwCCCCCC犊q +4=?Xq#3C***'''000 """(((   111 """ Է+++\\\mlluT䌌t##FFDDtt XXXXbzzb!!WWVvv"'+8J]8Rkո***\\\lllvS!&+8K]9Rl '''eee +++444///""")))***   $$$%%%!!!Ǿ@@@qqqd|g|gϵ //RR6666::::DD:zz114eeeeeeˍ2>K>Yv&Ĩƻ>>>qqqf|e|ebbbbbbϊ2>J?[w&222   &&&  ))) ###444   <<< ,,, ǰ!!!TTTtttnF<<QQ]]]]oo5//"jjq``j555)/7>||UUUUk~~kTTOzz!$6GV:UqǩŸ666iiijWjO!$6FU;Wr 222((( !!!!!!  ...))) !!!iħ33TTAAAA6666??4yy88=RRRRRR:jRRRRRR:'''!!!   &&&!!!???::: 555{BBLLffffll>bb,,hhlddq%%%%%%%%%$$$ &&&!!! *** 444 !!!000Ѓs**MM44RRRRttPPJ}}]]] )))  &&& 333  ///  !!!77SSMMMM2222 444222555  &&& $$$  %%%!!!BBBhhhhMM  ***  111    $$$   %%%:::,,,===;;;///   777555  ---  000  !!!+++ 000))))))   %%% :::333  ,,, :::""" '''!!!!!!555,,, ######!!! ???333Ҷ...<<<  ((( MMMLLL """))) ### 111 :::+++""" %%%BBB222 """BBB UUU:::www >>>   FFF((( &&&&&&!!! ų>>>UUU333͙ 999444+++wwwvvv EEE!!!"""***(((,,,  UUU,,,(((FFF)))!!!... III'''GGG    pj/ ź 3@F7 pj/pj/ ggg  )))!!!  WWW777  BBBEslU}kXtAj/ ggg111 ___ """)))  ... ---  555 [l5ɤ)[l>5[U4 ss# p/RK/ S}F&fZ&5hb1p/RK/ S}FȒ/lS&55CdG) k}. r;Y<׮>[ r H'81 -;CdG) k}. 5[U4 ss# r H'81 -;YYY """444 /// ,,, ///    !!!O>@k@;v^#8}{ x2jX *pz +@@Nir˝8,2jX *pz +1F|S,qx~ |uaK/ +[k>ɓWH* XoG< #Tʲ((+ɓWH* Xo8 {j /OE2  (ue?thH% ut!*&?thH% ut>uaK/ +[k>iii !!! %%%HHH 555 s [[JnJKyK!cc[/ *s&ZZ InI[/ *sn$:y:TT /y s sRRsTT /y ssKyK!cc s~~~??????  555   (((&&&   """ ===555~~~ (((   %%%!!!  BBB(((222ӬYYY!!! NNN s s555OOOEEE    KKK???   eee!!! 333ccc 󮮮))) !!!  >>>%%% ???888000 III ""  ҕccc111111  ###!!!!!!еHHH))) CCC;;;    :::rr == ^^,,==44!!!```wwwxxx ...000 %%%%%%!!!,,,Ԩ xxx  ((( ppp&&  ** !!__  33 **00**&&SS##!===wwwwww 000&&&  ѸIII  $$ CC  cc ""gg ## &&MM11'''   """wwwfffuuu*** ---___    ''.. == !!!OO 00  BB II ""!  $$$$ ---LLL111&&&ggg @@@qqq   ,,,    ..$$++44ll  //444477!! !!,,CC',,,,,,   뼼XXXOOO***WWW ;; CC && $$77 <<++<<7  000111$$$BBB***lllXXX  """$$\\ ^^  &&999999,,,  !!! >>>888---BBBIIIYYY66622 $$ !!!333 @@@GGG### """000MMMOOOgggʱ lll NNdd$$$000 %%%AAA777(((444DDD hhh777,,, --22!!! (((&&& """///___jjj$$$%%%   yy,,,***&&&===  KKKLLLXXX}}}555~~~//++ ///弼HHH((('''  ###000"""CCCSSSfff555fff ????,,,###;;;FFF ... LLL&&&222qqqMMM걱GGG###777%%%  $$$111'''FFF666cccTTT~~~ LLL)))ggguuu???ccc $$$111:::{{{JJJ@@@wwwSSSHHHpppggg(((hhhAAASSS:::DDDNNNkkkkkkkkkXXXFFFaaa QQQ''']]]qqq~~~:::ˏ:::dddRRR ,,,555>>>iiiEEENNNJJJJJJĥ,,,JJJ^^^LLLuuu<<<<<<$$$666HHHBBBߞ +++GGGdddeeeeee eeeeee峳$$$777???===򹹹666RRRWWWhhhhhh '''111666---$$$222@@@AAAUUUUUU<<<<<<    $$$!!!000+++//////```......!!!###:U?/4ޖjIENDB`sardana-1.2.0/doc/source/_static/sardana_server_icepap_np200.png0000644000234100017500001050074712174204305026204 0ustar cpascualcpascual00000000000000PNG  IHDR%<i pHYs*0Dh"IDATxp ǒr`+kqSj)MNUPK.8?N$y ykcMN U2YBHBBH$F%vg4f3b?SX] _1 /?\.QzZ,l; kA#/:\.T"ԭr|#/:h>G*|L1!tcC" * G"p' TiQwI9[qXC # g  G8 #*"\. zz@wQ*tFNx_+Nzxz@͈Azi1\.uG4x4`NN\.\.yyyyyy222777AAA444}}}eqqqSSSYYY333mmm222ppp666mmm222qzqz =KXg\.:::mmm[[[+++QQQQQQ&&&vvvOOO(((HHHTTT&&&vvvOOO~Y4g&&&gggmmm[[[EEECCC CCC7";<]wIU&&&666)))''' )))]= G7wg\>ِ(wIU7C' wIU&&&]]]###&&&### =CwIU_*yb|L G(&&&&&&'''###''' b_CG55L&GwI)_* izic-Q)}}}}}}###&&& 333~Q_u/7XFf)it=)5?Xxh6L/SC7'7XX]/PPP777888///SSA\.PPP\.\.]]]\.]]](((999CCCSSS'''ccchhhg4[0=Qc2YG YYYg4g4g4LF L @@@ YYp +++!!!uW8[t?YspP/WoC^zmK(Sh}GedddTT )) VVccooSS>>> y@@@77cccU$L9) f3sW'3/zZ*/n (GG{{44 \\6{{k88999!!!j7ݴhhPPL3i6f i6gf3 GG###LL@BBB(((111999BBBȕbIIQjjj0cƓ`fmmm-`Ɠ`g;f3nnn,_@@@ BBB(((888%%񴴟RJJrYffgMq"A-f;:?GGG"""JJJZZ4..1ttt!!!+++===!!!  ??E444!!!+++333"""LLL𰰰***grjg@g?ZHrogsggt   ~qk50H!!%  666444!!!111vZ©>Wn _fx Ok }l$] x89; '7=@AAFwwwTTT nnn""" @@@s~>WnX/ /J.<- NNS ('*TY`  ;:?TTTDD __QQ QQ 77<$$$@@@GHL ,,0  TTTMMM"[[ ]] ︸%%%IIIEGKľ   !!!ww__@@@ ZZZ???&&&:C,,,//5LKKyyy89=@AE987yyy666a]\鶺~}yPPPNLM333}}"""<;9]YXnpt@?=333iii nmk333mih# !(((NMK##!knmBEF220,*+,,,:86KPSBEJތ(0|̴weh2,!cHfP77-d*ؽ&L}[B+> [f3g4\.e3\.^0e3f4f4bwI$#kg4e2bd(؉L[ơJcgN&wI( :&ei' U (   ' gK1ʿ)6A_1\N?G!5V\>N K/dA\9 B# ####**}444222111222fff444}mmm222 UUUqqqSSSiiiRRRqqqSSST]f \.&&&vvvOOO...sssԯQQQ:::mmm[[[%%%YYY:::mmm[[[6_\.CCCQQQ&&&gggmmm[[[&&&gggmmm[[[b  WN9 ^wID#E* * )))QQQ&&&&&&h=Ig) ; ; < UDVSb=wI4###&&&QQQ&&&]]]%%%&&&]]]Ԏ/o|= Gg* iiiHHH'''&&&&&&&&&&&&iii;i/55ggZP:r5 >wp`UtC{}??????&&&%%%###...###k:.V&wΛwz ^qiwI@A$5-) L)h6wIuwJ.???777>>>•g4xh6ћg:\a!SwI8Q( CDD HɨXXX 2$2yCCCѯ\.s&&&666XXXf9n\.\.s&&&NNNSSSGGGeee(((___jjj!!!g4f3[:ڥ  000%%%___(((3    HHHqJ.BeHk )))Na|I''']yF000WUWWWHH춶RRllBBB!!! ii xxיOOODD$~e$ۿ%ܩWWWf פ\\\gq+3J++JJ￿!!!kkxx<>>>e3ppݴhN f43Wf e2 ]]]+`]` șPP<<<Xd>I  (*0 HHLTTT&&& %%%!!!}}(( ! ;]8NUNU}U-q8Cα0dK V]Y︃_cNS+b:d G GNqj쳿K+O GmxxEg4g4'_2o5ET_1yN!(4@˿5ET_1$.g5 k:  (1X/zPkrBn?yyy*  GwIDwZx"g1螜a}gPkwJ㎾ ~Qzzzyyy*  GbgbxIOU}N,TUDN Gun1 r\U o-wiщv-whk- J({DQt_i_QqnKu\  -e-g}m3Y' wnP' ^0ވ&AVN?> !tؔEE') bM!VVVXYY "xV`lW&) -!! g RST !Tog||@n _2\|nnnܟ ===NNN ===%%% <<< ==={{{厎ss  kkk111<<<ooo...  kkk111  fff333  kkk111VVV zzzssƘhhh zzzXXXQQQJJJjjjSSS###{{{AAA zzzXXXQQQJJJ444'''gggUUUrrr zzzXXXQQQJJJN| *X˻sTa} :h JJJ$$$ JJJ {{{KKKJJJ5ET\.CUh$$$???fff|||jjj QQQddd$$$???fff|||jjjLLL DDD$$$???fff|||jjjm G$Wd2_~F! 5~; GIjS,ԯQ( SUЉwnۇ@ ???RRR ???&&&VVV  ???Mam7I$Rg Gm7Ig G]1  Gxd25&j* Q(  [[BBB???xxxBBBUUU BBBa7{' '7{]1  Gۮqwt:[A0wJ0zI # vG)))333$$$)))'''))),,,***wpW %wsU\MQwN] iwp,wKewI8ljO^wO_j\g#5+++333<<<444000'''+rW >O^%M[RUM'&&QZZe^* 5<<<ddd]]]S^S >^) g<Z/ 888HHH <<<!dE(.v &&&FFF KKK!!!\.(%a ***!!!111***&&&EEEG PPP jjjnnnqqqzzzoooCCC000g4g4C.)w(_J@Uc1c  ꨨOOO)G  SSS333MMM $$$+++***''' // aa GGQQmmBBBBBB```e𫫫AARjlⲲmrضoU؞ G!7 YY &  22VVV uu(((VV### xx((ppJJᄒj7uu))55 oAk8fyyyyyyk8g"\) :Ȗ?+n+++ **+++ gg(((hh_555HH !!!;;;̵l Q8+++>\y1F\θhf,,,=Zw1G]лd J|>·...;Vr1I`555ZZZQQQ666666)))HHH ###!!!,:::aa>Ó]٩*<<<3He(>>> OQ^cSb|`|||DDDYYYQQQ<<  gsgq>  gg /g gsXRZl tR l luLLL0/3     #(㸷 PPWQQQ  ///!!!  """VVV&&& 555RRR!!!555s  zgA/ |s ^-    .-2 SSYQQQ"""YYY///LLL!!!&&&;;RR(\\::ff 66 S cccLLL/ sJJJJJJ@AF0/2 ü )6 ! =;=RRR  ߗ66 BB3ssAA nn88111kk00㤤>>BB !!!;;; =>C   »%4  gffRRR窪aazz! BBBBBB  III111$$$HHHWWWwww,.5  qqq aaSSS~~~qqq---KKKWWWWWW***[[[&&&WWWwwwFFFGGGppp?@E "///666&&& mmmCDH½ dbbvvv ppp=>C?@DԷ [[]vvv===)),)), CCCkkkkkkAAA}đhie[^a     jmlIHHba_>=;]]] abb [ZX`de@?=]]]ABD875+./cfe}HED##!uuw  %#$>?<   \]Z"!  400v}~ $!"   w{|   )(*WVU㖚sll8@B442PLKSV[`eiNvϜO8l G GǩP>}P#y:llwkh-+\ Y5eoz|:=MQ9x{w|І}U"9W{y}ٛ&e⤔zX\']VDQ_[y{} z(M۱0V0:U_WNy˵>'eG(':U]o}+hڡf~|ʪ nhy@rokRR"*}vX G 6V6V{|f3f3&W+"#%\9]jxGh\.jwxJGhZrv)4?DYpxLJ`vDYpmAͼNh;Yvllm>sO` \AVk$.;Nb  JJJI\ wI`l:/oX4~zwL1+( AVkkF:Nb5GXJc|HECJKKJ9:e_wLDwZxQ8i6MfVWY3yb.樐"pb&co N{gXX"p00cChJGNNUwI R SHlVvun1 UDN`G }y".yx#- kXvb=V6ǥGD   hIreX;)Ysn GQlP UprqG Gxu>u PnPew`G }.> .Za>9J\RoLEv2`FsnZǶdK"n^+GH'᝽cC^Ev!@"""^0%tbG!EHn%5\)N^C;/UXqC\w&epSE##::w g4J`jEE}`^yFYm^0\m ^0}}}```\~~~}}}JJJ-KtttBBBQQQtttBBB:::ڤ666 tttBBBK^^^ |||111666^^^ |||111 hhh777^^^ |||111444444444̝ m!!!파OOO(((OOOWWW000파OOO(((UUU파OOO(((cccuVȹ---냃PPP***ڒ獍333---냃PPP'''QQQ;;;---냃PPP l  ''''''SSS(((... kkkJJJ ''''''SSS&&&ר ''''''SSS5 f:"""666777000鯯RRR"""UUU"""%-5n""" 999""" ;;;""" Me|kkk^^^kkkAAAkkk2@O#3r ^- U   ]=h=Ig G(((" ^{E J^^'P9a]=wI0wkޡ= Gm7Il$M G \\\GGGkkkaaa ___((( wIlE* SU:: Tm f';6 YU.\ eeeGGG%%%uuuppp GGGGGG TEQ(  GIjwI,ԯQ( k;Ie+/b_C_[[* *5| G/// GGG$$$ppp/// ===/// kv5 6)wIU֣###111'''111'''111 6R)  Gg* R)  ~K}wJ0٨t:[A1", I!!!!!!KKKY0111111...fff111vvvtIo SwN<]E,mʂwmiXƗIG>5y&w^a~" $} ((('''000\\\>>>(((DDDFFFFFFn.[ 9wSl@ _#iȧ1R5\^Vi})mmmFFF\\\e=Rf *5wG>-Rf`9G>0TQ%y'v<<AAAFj S*Iq]{6lexS5˙f0l6+ 5%wISmmm777bbb]|AR5wINkdJ 65Il,[tmwV68Ck:1L@\ge:::Hz3l}U|Y:z3l joSTHwI sst:$$$$$$|||$$$KKKnnnAA]]g;At???555|||]]] _1CHHH%%%''' f;111Ql.;JzW.CHHH|||####*nAPtttgggzzzwQ*dddCCCCCC{{{jjjgggRRRBBBbbbbbbbbbbbbJJJRRR 555www\\\ ___|||333(((\\\@@@USSS555[[[KKK ^^^g4f3~2U9'-ˌGAw- 6\eeeΪ!*7)&"'~ڤ=S\ (((000!2RJ0/%$ [G NNN__GNJRRX WWW %%%mmm   444xE!!! zH,,,~L777G mmmWWW***}}}&&&rrrߪwwweee)))'''KK\\AAAbbh5fh5fh5fUd Gߴ_  %%%>>::55DyyyAAiinn)) UU=== rr '''''FF''ccc0022rI fOO`+7rFf["/<oCfؿB3B`8`W|$2A*E < ++hZZ __&&DD DDdddHH!!)) ee!!!$$mmmooo ||cccnn111ͬfּ66EaaOOO OqϯͺhTTTPtѲdzfRvR{WWWRvL ~~~AAvvvvxxPPJJJ111i:VQMyyy3vvwwRA11Xwjs {u.V    77:FFK   &&&///555mmm/ v;[;N~y/ / f]f}vRRXRU\!"# 乺 QPVQQQ   hhhs/ zzz999CDIļ   $%*¼UT[ ;;;)))(((jjjpppYYYpppBB 11ii00RR __ 9> ll''#ff55 TTT:=Cľ   OMM%%%LLL888ffFFMM~~ BB++<< gg133 >> ]]]!... dddTTT:C    hh--kk!111%%%rrr!!!JJJNNN666777?@Eý!"#'0>RRR333000!!!!!!LLL ]]]CCC...mmmjjj<=C!"$ ,,, !!!---'''jjj666(((GGG@@@VVV?@E½556wtt///FFFGGG333'''DDD]]]=>C%)1 DGI ի fdbbbbMM''+''+!!! !$%+ 333͞Q127GIMZYa###015cdh777BBB HHH !!!mmmooo,,,AAA̓ %%%~~~CCCccc333qqqLLL//////+|,-);:6ggg(%& UYZDBENMKaaaonp \\\521>:;888qprddd edb\[^856 QQS浹#!" TWX{~PPPnjiaef   _bc ...<76JDD  hefBFGVVV...|||sss `ZZ### 156PPP ,,,$"!   :7630/  777<FBA-)++)*  \YXJFE      999QNO!"   ruv     IFEklikpq  GGGWXZrrr?BCebaxwz;=<!!!???ؘokieba;=<]\Z/0.BAC枞$$$QUXtqp =EG\\\첳  %%%HKP6Zi ;\mϤq :KxR7[ `[[GGOvOF|FSG GGF|FS G1\1\g4gg4g4"%'^y0=K첝A=8 ZsZs츏fȹf$)0pH 4EVSn K|Qkī]didCg8GW8GWpBkB至:NcSg|n@NPRs666xR+h6{&/'3@( sg5d~C ???sFqN4EV7J\,J#Z~3{}I.K' ߯p-_ N1߯p-_ NHbFN% UB b"P'wN]\a(VVIg9b$Q(wNZ`ς,wN]\#e[ tC@U_uQNLzX_uQNL(sG C0C0|D"x{G#z|1(BfB"w|G"x|G#zlj1u qթNנ=`A8q==`A8q= --//wv7Q-...Iw_* <cd GGw` AvA  DD AvA `] =] =grI^scccc VUTn***s Nj \⎄ldaw}Ski; vvvvvv000r݂gh0mm=]Fy^$s+ٍmn|߆{Z-R3/T-oR. $sl}γ~jW\---#+3qXdV-.#JpV%:?f% <# qycwwwwww|||KKK999.Mt`:+6C%'?hnN,[kV}B;mbwx!`"( "& N O4K' ZCɁ{[pA*V ~}$0; 5D{DKK555Q77 Y22ĕ *'3> >>%~~tCCkjh+B,   @@@И O |h ***VXY%Fh)4? rF>tttEEE\aaa{{{]]]mmm_%%# QQQ QQQ !!!*** QQQrrrrrrnnnnnnRv8444tttBBB444'''777444+___KKK<<<XXX...]]] |||111<<<XXX... @@@lllbbb[[[TTT999<<<XXX...zzzUUU >>>?)/4a{/=J3a۪{̼*** ܎SSSXXXTTT333 VVVOOO (((*** ܎SSSXXXTTT333000$$$WWW???*** ܎SSSXXXTTT333www~~~TTT {{{xxx{%mu\E555...###FFF gggAAA :::vvv PPP...###FFF gggAAA555555)))TTT...###FFF gggAAA)3>>~~~jjjKKK;;;FFFmmmzzz)))BBB222KKK;;;FFFmmmzzzU )P}.$I=*wSg  d! m(/ !N HH!$$-BwxV^[VJ7"* NZN {nT^[eee GGG$$$uuuppp ???eee GGG$$$uuuppp444%%%+++&&&777eee GGG$$$uuuppp| @iRwNTru2wV3kN4_RI=*wc DFN;G$wNTru{wK;m]E!wc DFN;LKf~t9'/ # * x\ 5 W)D2c-Mŀ/|Kl}y᭑| BN.gZC[is&+awM/j-( BW;cW3]4nGGG$$$xxx GGG$$$xxx::::::$$$ GGG$$$xxx$$SBZN VJ7"* NZN {O5](>SS8'nn;;``;;|GGgJGG"UUgGG2|2gG'''/// '''888'''Mŀ/|Kl}y᭑| awM/j-( &+awM/j-( bwK@lܗ% SSS456R~111666;;``"UUGgJGG"UUgGGyyG:~sAzq|I|InK|In9/`5wKC٫[ϾxU$$$)))111$$$)))>>>'''&&&$$$)))nnnLLLbbb111wI&wI*݇'(qQx[~֖sؼc-b-=tY%dۅ&w_)ۈCjbUw:1BRg4&&&777+++###zzz,,,V-wI-kd\1 gt}@,,>J GL IRdjkQ}Iq*jjޓ10.ޓ10*2 U4eF K)zۑok###333<<<zzz000 g4wI'q^"tY%wI wYs[tY%؂-jwI(1 MKV?Kc<<X~Y~[+7P811"m"/1"m"v^|%|%&&&CCC ^^^CCC...J JӼO2 U4el|e2 U4eƟ~> IJ Jc cc%% 99 ::: ggg dddvvv???***Y}vvEvY~Y} \\\\\rrr))) ó=M_ ???:::###qqqfffdddBBB Ȱ=M_i; PPP555VVV WWWfff111^^^xWo\>94]]]]]]*** HHHֿ<<<KKKKKKLLLoZ3BP^0\ 333UUUkkk###pppmmm/....vwxj>\ddd,,,KKKnnn]]]<<<666rrr h ### BBB]]] >>>###!!!999KKKhhhsss111{{{^^^+++\\\VVVppppppmmmmmmvvvKKK+++OOO(UdG MMM ~~~ڌ(((EEEѮQb|Ii{VfR"6 ¿Š"( 򭭭???:nn""" GG [[LLLSSS  000qMBb%3ArK:Xv+;KpH1Lg2DWUdG(   ((( @@@)))hhh^^^...000444&&&000Դs.--dXXXBQaVzغl((( d^^^?M[Y~{e!!!bþeee]]]q rEþuuu3eyeVVVr uJſppp3\r\'5'kdkPPP q)%ٮ8oɄE`2 BBBBBB..柟%%0088@((&&&///dd \\JJCCC ..KKK⤤^^^$$򽽽HHH ((///$$DDDQQgggԿnQ c55)eeKKOOOOjjjj´RRRRRR777[w9PhƉjL ###dJJJ;;;[t:TmɊiJ(((e}b}llll6C6ɻAAA===Yq=Xs >;6K))9>>++~~00咒SSS66<<!!!JJJ8888{{{VVVVQQQ8888{{MM!!!___^ZZZ3A{_bb~//uullvttt4>HdbVVV3:xYxxx2:CedSSS37xW/N/Ҵ>oaa  ***}}}08@gGG GG GGʷJJJ  zz!!!77 +++,,,)))!!! ___a:𬬬EEEfQQ/??ss wwEE5ʌDDDp!*b:HHHfAAAp#.b9ꧧMMMf:::u0aa ++gng>>>p&1 888""" !!!666  333  Ƥ;;;l777uu77ccccdddd˴ ...GGGPbtHiǦ999m***JJJPbsHiǧ~777m]{]$}%&&&JJJParHj''' 999 ;;; %%%DDD 444 ;;; !!!g<ϊqqqf3f{{(("vvvyyppp"(-ng<ϊqqqf3||ppp#',me:ψsssf3zz4VV4EE wZYZnnn#',m777555>>>===HHH %%%%%%--- (((   g??$NNdd**==,jjjjjjfhjjjjjjfg`S`| [[[[DLDhhhhhhf /02 NNN??? HHH!!!///III   !!!зDDO$$vvvv____Դ|| ((-?Z?¨9tff %%%569===DDD ((((((""" 㿿!!! /// !!!BBB11J"")).UU&&&ZZ4  326 CCC ''' ))) !!!AAA$$$ )))   444!!!>>> +++ ===<<<!!!&&&&&&YYY 555NNN !!!ݯttt)),&&*MMMNNN111GGG555!!!))) 󂂂!!!444lll  MMM [[[BBB999gDpD/ ###ttt < > t Kl 8 1 ; K##& ?BI  FFJOOO???    YYY444!!!hhhs~UEBUEBT~AMz ss/s aaRNZ33Nxy]]]AAC  KNZ    LLPPPP555     000!!!'''###...!!!RRRiiissqqq]]]KLQľ      UTZ PPP(((>>>666 eeeJJJ%%% ''55M..447 qqq:> 55 [[  HH66 888111!!VV !!!999濿%%% !!!:D   )  rpowww999 ..... ###򭭭---,,,!!!QQQ---444UUUTTT>>>68>  Ŀ.6E    wwwfff!!!aabb111 !!!!!!ނ|||$$$111:::hhh)))TTT "' "' ,.3%%( XXXSSS### 222MMMWWW'''``````fffZZZ"#'"#' %%%  QQQ==='''&&&nnnbbbbbb:;@*0=ü# $ lej'''666ݛbbb:;@CGM    UUU```WWW숈99?&'))),>@C¿XXXQQQlll999iii56;Z[_뼻 MNP@@@NNNAAA888555+++XY]zzz(((jjjmmm^^^???&&&,,,;;;LLL***ݪVVV...bbbbbb###yyyyyyjjj{{{ttt000###|{~132tttӨ%%#lnk243ÿ)&'&&$VYXimn20, ~~~˷bbb555<<<a`e "&':97 FDEKNMPST  XWZ 螝|}A@>510ppp  ghhD@?w|653?><kllAAA634  dch  ?AD///fih uvv뚞XXX  ќZ`b  NNNzzzDGH/,+jil521 *'&bbb  ...opr...hge"""   TLJ*()  볳zzzmmm/.,B?@777  C?>MJI!"  xy{MMMMMM  ν )&' B?>53/(((SRP,(* 632  :8620/   %%%&   B?> ijl,,,%%%xtu    wvt000,,,30/hgdhin    ]^`777NLI~(*)VYZOMJffb  7Ȁ :;< .*, .+*   ###%"# 2##"<=;666GGGڳVVVEEE!#" ]bfdgl *-2((* INR_dgVRS49<g4٭%@k85"N9' N%'9OMeq]:_\w8\!׺y=gdKX' ӴON1O$)UmͣeO}¶P#+NyA ՝mRAs_qkNMĦ_ʠf " oϤrk. :W% gl\^&=xujix|sԤuKB~)4>i:e X!i=<>i:e X!i=< X*EZy+|Nq +Lw~a1\1\F|FS`\ `[[`` `[[`7[g4 N' hO5EYlNd{õo'/Wp0=K0=K 888 tss8ERy  я AAA Ǹh 񔘁bbb9>CttL%CW 111 QheAbbbɽô ~xV@]]]`}xvWojF[[[GA:+4=`3gǴ !(Rm)6Dz\z *3UrmIRmPk  (7I[&/Y0~R'Yu(6C+9G,,bh0>>E\si7#,n/:Fwl`\\\v22RRwSbi wMA_* wIZLe}h6wz''555WW.\IޔTݭp-g |I wILݭp-gxnQ/ɯ mISl>7 c^^^dUq~wI ℭwSUq~wI $o߉trC3CTNi& ̿%00\CECUB B (Uqe'4A~ z#jaw\弽 8K^5FX(6C  ` ;VK ?bA=t=?bA=t=!\> B]oLX !=~ @`w[i]oLX !=~_ GG%y؁g"RRl"RR GG˺`^y-:FuCafwb< | wa9 mw_:"|ƾx:| ϹM#AN[h:w/?OA\!u1NQ{E^yHlsoKqm6.<#e\}>> ooo(((ú/?OA9"3 LL<@Bب&XGG$%%%$'*  컑 DѿZ4]dLa @컑 A컑 BBߍ]arȳ80rO78$@@@ƼJJJ111UUUдLLLLLLWWWIII]]]WWWMMMlllᄒBBBfffnnnMMMyyyݖ>nn o]]!!!888XYY !!!*** !!!*** QQQ !!!***ZZxЈ000lllIII222 !!!***III222 ttt BBBIII222 Wȍyy:::'''hhh777III222 '''hhh777{{{444'''hhh777勋999```AAAlll777'''hhh777```AAAlll777]]]QQQ111```AAAlll777444333???UUU333===XXX444333===CCC ppp8ww\ @@@lllTTT999```AAAlll777 @@@lllTTT999<<<NNN... @@@lllTTT999ݬ!!!===xxx111 ڧ888ppp%!EZnQh~  N|ƶjMKI@@@ %%%&&&333  @@@lllTTT999@@@ %%%&&&333 )))꭭VVVKKKUUU(((@@@ %%%&&&333 555SSS###000000XXXR^j:JZ:JZt&&&333AAAsss$$$WWWsss???@@@ %%%&&&333 &&&333AAAsss$$$WWWsss???aaaTTTKKK ܎TTT&&&333AAAsss$$$WWWsss???444 %%%WWW/// 1D5CR666555SSS&&&333AAAsss$$$WWWsss???666555SSS...!!!vvv UUU666555SSS )2 )2BKTBKTxinnn&&&\\\]]]666555SSS&&&\\\]]] 777gggvvv&&&\\\]]]6(=O`Qh 4*5Ÿlcs$$$VVV&&&\\\]]]$$$VVV&&&000갰SSS$$$VVV?KX)5.;HC`|Xq &&&+++dddiii$$$VVV &&&+++dddiiiDDD ))) &&&+++dddiiidt>Tj'3>AVi 000 &&&+++dddiii 000DDD999%%%  000^}()*)))  000))) !!! CCC!!!))) LV`$$$))) $$$ ===$$$Y|^yVVVAAA$$$VVVAAAkkkVVVAAA0=KUL% l ɗ%FnaomwSI=* zzzVVVAAAzzz %%%qqqzzz(  N{gKeM_CWFQ]NM_ar7*[ !M_C|%'xxI(wLu !!!zzz !!! (((;;; 666 !!!j\  V @ ;D#=Ab  N h t&N bv< b7 1wNTru{I+]Չ2't])I&Ad:Tex#4\J!X<\wK;m]EkI&Ad:TeEEE (((,,, !!!EEE (((,,,GGG>>>~~~aaaEEE (((,,, Z@#q -  )Dc :qC>v+q-rB8 N{-  ?Q  ^  lB X;. # mA>,!/ +"G/$iL&444___;;;:::]]]444___;;;$$$xxx444___;;;7 1s#4\J!X<\R+]Չ2't])I&Ad:Tex#4\J!X<\΁*eU']GkP&Ad:Te O3G~'UY ;c-Y Hc5}xSNz4/G:5ìM7>j-N.ZCqs3wK-/ܗ:::/// 444___;;;:::/// :::/// - Bsc|t"- +"Gڽ+"G,I777___WWW###888######111###}xSNz4/G:N.ZCqsNvN.ZCqsW;cW3]4n!!!###???666###666666 +Q;;|g GG,g;;|GGg2|2g?lNI~@4ǎ"Lvǎ"Lv %[PU\wwwwwwyQmG^v...666......xN7 I) ]krw{szKkrw{sVzVHϤ-dg0dQlQl_7f>>>bbb...>>>bbb$$$--->>>bbb𠠠ކ{ycp,{X/ I>uamNU=剷s:٩s:٩𿾔0to=YF܊]ICxTkg^, Mu"T2yNNN...>>>bbb...###...www999UUUeeepppppp᫢P&#uyp ) V!g6اVXtm7* 333BBB... 888YYYrrroooIr",zIy J$^# J$A{=ٜpm 'ў@owў@mu/Fs@AY YYY |ETcbbb9/"  ?b $ 맑 6U_ 0-7|' z3msM$ 벒 E빑 F (((,,,888sD)7EkOi ܂{ya0to=YFY(w.لinh0to=YF墭^^ۀ{`$]ba-w7q""ñHO?}OFwHA|c~I2_|c~I2_qr:|I-[sS'i2=0ñ<0wI yI8Q( XXXTTTTTTάTTT>>>>>>gߩU=AG;1##!eݪC)ۆT6u55y &A 0mm 0mmEEbyStttVVV:::Ee㡖/E*h/DL(Emب'X" qqqbbbPPPyyyNNN"""KKK%z302 nO]Yz3U E& d DYLLwwUUUYYY:::(((KKKlll %&qr:|I-[sSOyEw=mjzCqr:|I-[sSiM_$%?4w ##K]]ӎ%%%!!!eee}}}5EEQQEE ee5XX-- 55 ϸ^0b::::::SSS///>>>kkkemtnxbFFF===qqq:::mmm///@@@(((ZYY(((  WWW  >>>:::+++CCC(((ö/=J]1yyyyyyiii...KKKAAA777)))***d9_^]bbcI]s V-ڳMMMppp|||///ccchhh333!!!堠```mmm!!S`nPi ϼ{iFFE###***444欬888UUUzzz```3215N'XkXvvv111}}}}}}KKK TTTTTTpppWWWxxxф,,, 駆f}{{{vvv˰PPPnnnnnnZZZ??? 000&jE&纺FFF+++四UUU555BBB<<IIIĻHHH<<<]]]OOOeeeRRRۉHHHppp!!!ѡ444cccTTTqqq``````YYYwwwvvv+++///!!!vvvgggLLL LLLoooCCCCCC>>>CCC@@@...000NNNkkkkkk;;;---???xxxVVVaaaXXXPPPvvvAAAXXXqqq㶶vvvMMM[[[***777MMMUdG (JJJvvv :::~~~MMM&&&ttt555///ppp===xxx|||jjj𸸸܋NNNjS /2ݵLXs~P@n:dG LDR7Tsk 666&&&DDDg4f@?߭ݻJ/ %>v&D;3X 瑬8\%'*FT, {K1RU ޚRRR /KssRlm;$x eTTemD +U𞞞HHH999u^T`/E!Be#r5:BBB:::\\ %bX:!ۉ5 99ũً!B觧BBB...n*W2Ĝ i<%B9L5DW׳X 쫫>>>222<և_=*# &!e#T\Tb\b:0@,%\J0&*Oxԫk?+>xF AAA^^B,ZZG  󳳳AAA[[[   TTTPPP  '''///fffPPP @@@(((   TTTȤcϬľgӲĻi(UdG    ??? Vbbblll#)r\[[[weee"r bVVVp]]]q sss|||   000LLLNNN(((555 d9ӌeeeeeeGGGn&g=ˆ\\\\\\@@@n",k>ǀRRRRRR??*l)5UdG QiYag4 777 000))) !!!WWWFFFxxxYYY333 >>> &&NNNuuzz===<<<xx ++gg111///]]BBqqۆc@33388(a0BU`<󱱱***77+a~2G\_9%%%880]y7NdnD4i|2Ռ>:xЉ4 AAH  ((44 ssNNNvvMMMhh )))ggNNN!!!èzbm::>wwww99;CCCQfzGeɰu\l IIINatJjζrWicc}%1%MMMK]oMnF*M4^^^##,,AA77$ggrQQQmm :::44FFF LLLWWWRR``//  44vCCCpXWWq <""ggoeee;HT]ơ}>>>jlll9DO_Ȥ999€e:]:ǥ4yqqq6AKb OE1[ ""ii %% ffJJ 11HHH$$|||KKwww###!!! ,, TTT}} ++LLL888((yN»kkk]""p55pjj^uuu%+2n}Rfffppp"'-nW```$=$N_R/xGEGkkk#)qx/Ru[QovF{K B**DD II  ** ~~~ ddd HHH..  sswwd9ؔ[[888zzMMII:ppppppOOO qd9ՐjjjjjjLIL p!f;Ћ+3+jtHH(||zddddddHFHo%Yw/x lؐ&&&mm@@EE 22== ++eee!!!QQQ55!!!iiJJJJ1111!!!ԆdB>>$QQaaYYggggii++ ???77"h'8H؈c@:::88$g);Mۈc@ūZKZ?LWL55577'e+?R GG^^^@@@ ))PP ///$$$@@@  ټh$$$q66-mmxxKKKK==;Xn?[wڿ|f""!r>>>VlA^|{d pppvpp\*4*AAAVj~A` hh 000CCC'''!!!###555TTTpJJJw`ɬIIY--uuBBG]]]AO\W|rHHHt]___AN[W}tGGGrZDdD1|SSbbbAMXW~aaa BBB AAA+++000TTT ...!!!uIrrrrqqH''~tt}}},3:ivJƿppp{{{*17jvKƿnnn%@%KbK2z@?@zzz*06j|||,,, 888000     333EEEb8ߛľkkG//::bbQzzzzzzWWWr c9ޚĽwwwwwwWWWq b7ݘĽ$1$gooAA&zwzvvvvvvSSSs  ***''',,,/// 000 ''' GGGɊjJgII*FFllIIzzSS@@/KKK<<1l.<͋iGiJJJ<<l.>͍jGjмKCK{{{={T\TFFF;;l /?mmm000,,,   ///::: +++/// III%%%$$$Ҵp+++yX55%aallllaaaaoo$$;;5]v8RmѴp+++yV::6]u8Snϳp***{W~~mrrY080::6_v6Rn:::$$$999###㶶222 666"""  h5PPPj<?>|sss:s]b],,, 448 $$$$$$... $$$&&& )))  ^^^^ttttuU((( CBH444555 +++!!!111  <<<Z㫫UUU  ''*;;; """  '''   ,,,!!! ;;; !!!^^^UUU    *** <<< )))&&& AAAGGG""" <<< DDD ))/666 ***''' ???000###666&&&"""@@@III  +++((()))&&&   124MMM 555000333 )))OOOAAA%%%222  ???   BCG'''...)))888  OOO $$$***eee777*** !!!   򰱩#$(lll!!!  """"""[[[!!! ---bbb  TTT$$$ gp gp JJJ <zlomz? tRRRmmmbbb 327555HHH ### ///.fh4u3 RqWgg>潉_ k x RqWgg>FsnNhpgg~g $& D, .aD@u3 .aDw= i3 fG { i3Qlqv  :4xzqv  :=hhh //2OOO---  %%%   <JF܇ 3Ix豜m&" B.Dz6 @JF܇ 3=BR     0g  w u t s r t owbbb///*** 248ccc??? &&& %%% |Wd ix 7!<5 }l      333    JJP:::```  !!!      II;?hbGO8LuT!"!4mn5 RFIAO GGO8LuT tP vV1 5P vT ]KKK?@Bǽ 9=@G  hmr𰰪77;WWW   GaGa/OOVkV|gp VkV }~ss.<[<[ /OO }FF]}.}}}   <=B  lryZZ`OOO111""" HHH """qqq 999%%%B@F    "# UTY  ===  ###!!! 888  ttt999 /// (((MMMBBF½     ""#NNQPPP !!!    (((+++WWWGGG ===___CCCfff888>?E !$ )+- # þXW] KKK 111  999퐐  sss$$ BB OO !!!}}}%%%#$)#$)(((  #325lll999///&&& ,,,>>>YYY jjj DDD !! AA33rrRR MM zzz FFFFFF$&*$&* ,,.     --0001$$$   孭aaa&&&!!!&&& mm77aatt %% 111&(,&,ý  $,  !!*))~~~\\\@@@...!!! ```GG 77ff11 JJ ,,....441(( HHH:=C #, a_`555  !!!***OOO""--AA !!LL ff !!>> 55;;X111!!!lll#%)#%)  )/: JHH~~~555 ###((( ???33SS 9900(( OO ii裏//%%DD999###!!!!!! zzz24;¼ )/8 555bbbZZ  //+II 111MMMJJJ(((&&&;>D !/     OOO ??? #### &&& 111::: ***777%%%JJJBBB˧ <=Bü  cccQQQ  ))) &&&111*** ...555 +++nnn)))VVV;=D #*     :::烃111 !!!!!!$$$ <<<RRRKKK&&&<=C   wwwOOOVVV;; TT$$  SSS+++000KKKAAA<<***YYY9:?,19 %$$ (((XXX222 9;@(),  KJKPPPhhh؀MMKKK "Q 88=NNS EEE111NNNIII.03#$&'(+MNR BADGGG###EEE!!FEIE888!!"888222tttpppHHLzzzbbbgggLLL;;;ccc{{{jjj||||||€IIIttt |||qqqppp>>>uuu555]]]]]]777vvvLLLڒ 555GGGPPP 777rrrWWWWWW&&& CCCYYYOOOOOOfffZZZ ]]]]]]zzzqqqwwwUUUDDD즦LLLIIIұLLL HGEJJJnoq棧*,+111~~uusNOT)&%=<:`caWVTW]_0./ JIG歪446 }}{orqoooLOPA>====TWTOPP**,\_` 111qtwPML312xyy{zz eeekkm]^b|LHG  twvsss^_]UUU gcfHGEᯯ! |OOM[[[@BCztv(*0?=9###???WZY./+CFGcce ghj@@@EHGbefsuxPPP  TTTQNK.,+ghjCCC񑑓jjh  [[[ khi HHH󡡟JML,-) Ɩ [[[NQR  HHFfff&&&[^]YYZ\\_ORP     twv (''Lj  ኍaac   ><;ux{ JJJ666#" jjlvsr+./STV    666GGG//-   ?<;FFF#" .*, SSS568hhh¾513#"% _^\>>>eee{zy UOO Yb[압GGG766   QNMGCD  <@A  !!!RRRbbb   ;98)))***HBBA?;  >>>VWY " 314###%%# yz|IHH %%%HFD&$   <:; 666       YYY@AC ;?Brnm  -,* ..0   ORWHHH   4FH11/   JJJPQSnmk9:= uuunqp   OLK222qrt OKL    ู($# kjgvz|     )**:<:ę***###UUUVYZ     a^]   224_`b @?=츷VYZ@@$##DB?WXZ+.+HIK0/-555 ! " ### @=>    (*(,03[YU ??? ##"\ae~OPT%%%$#"NSW]adMQTvro))+#$" DGL..,|AEH @ICg4ʊWH`hF Xb:X' Xb'fOtx(ʊWH`hF εfM.P2Va|ji:X' 赸ge!{kjεfM.P2Va|ji 1K}Kﷱod/C<]kXL@ʹ:X'ۚT.qrﷱod/C<[h\Xf,R2ﷱod/C<LL4?*qx@ 1K}K(B!fI 4,:"0C&1.Çy$=B ݃qzy 憎x:ߎ?@oq?:Çy$=B ݃qzy勞Ým tyԐ6Çy$=B ݃qzyMmvϨ@!(B!fI 4,:"0C&1.!\x\ӜLQ.*?=ٻ,@Y7)@[;-jxg*?=ٻ0HgF  D*?=ٻ!\x\ӜLQ.$9$9]>f߆orՁ7 <;aB,)Zd Ձ7 <;aB,)Zd Ձ7 <;aB,)Zdޢ >`$9$9]>f߆or|7 ;esS /N1Ӓr ()* ª/l7ϓ/N1Ӓr /N1Ӓr ՛3ff1|7 ;esS 0#|nnZWW7 ;Ii=ܑò` HPW:Ѳ`:X' &xPMR-q)m;Ii=ܑò` HPW:Ѳ`:X';Ii=ܑò` HPW:Ѳ`:X' ƨX(j[w$0#|nnZWW7  8lC{C| G`/v/vARC{C|G` G`C{C| G` 8l  g4Y- қ /6=}{zD;1WZ_³%0:nkk2EEE[grQg~x%%;K\9GS```lYG | ,6/>N&2?'0)7EJLMqqrqaPjo}de333pcVRi ĸpO%yAXp(1(1BWm)4>ƢZZZDS`ɼSjOf}::onmH]qzT.=Pd {|__555gzŸc6 """hhh t QjQi?;_^][uZsttthhhvT+:H/>N'1 E@>@RcAUin}ZxmIʻ[yz )6E)6EPiLI ;M`r~ ( '3> IIH}S' ϱ{ |jjJNNuRwx!,6im[w| 555ccfWWWWSbRue.J:_* ôlxVuRm 4FYM_rx88ZZZz--ե>XXYY|~~V3Y2ۅk;:_* *8FsEMgfWoWod?nnn::Y``] 6A;޿~c(2y:iȗxJ &^LG5jm{ xJ &^LG5jm{UeKG30294 (GKrCo)6EϿ #MMX e3Szk̀_Vgi4rB8Q( "Ns(otxbrB8Q( "Ns(otxI- a90@P)6E®m aRnRn0>LȺFIM6PPIX\555 8O{Sw:vi,V2" "4b "4[)+" hcȵk_ 1.\Bc Mڣ BO. +,!/ "G+,!/ "G#,yKSo:::,. $l0Yɒ Pel;5{Gr7bNF3 ⽄-s[%-5{Gr7bNF3 ⽄-s[{N!!*)4?<<555 Gg >YY Gg";;%&U|U,JJ";;%&U|UGgb:?Tj!* I^sKLMLfMbw  e Qf# oYJ0T XbPmb.J:X' ކk7+8E8WXsn1X/ ߇j! 9T?Y["ܟX Dur?߆k 3(5C9Y] θu_ +jr ,W[ θu_1X/ Mbv"F2V1R1܅o;:X' UG᫢P[Y%D0#ਠafQ+^z k࿙i4L^_)5&@rt&5& 64* 6=:Âc$/|9iɗ|J $\ED5Éjd{|J $\ED5Éjd{Ye KB20/84 $FKUG  bﺻ@JL$BA6=GF߹$LSS G`"77%#SsS,DD"77%#SsS G`i Y  ?,i Y  ?,::U[`k5CR b: b:37tL$88  ƶ:JZϸ Ƌ_1x)6A`hom:JZmyyyutsutsUUVgD[t G^vꠛd{ U`nEg<RRQ|||Ǯy7I\ `g`rnfI!t\<^0w+6CԵ|nEEEۣ`K_]/L3գ+"HtFSDΧ !;-Rp74"^_QZCܝ"MQ[@䬽 #OPW> Ҿ%JF9>A񹳡$N<ihgihg\\]gG\vEYm_]]]III!!!(1xČ6t)TpcbL蜝mfk\{=qQKU`dn=ig|ȒOIQI5\\_IUI5YhR"#.F#*6w `~3+RDG0 OO07CP,8E".: ̿ƿOOO78 zYu̬2S]3wydedn?_̪1}% 5z #.G( ooރrKͮmixOOO*#C#mX***󿪕6GY&.ؖh8"" 2P/Օg;& ؗh8#ؗg6"ɴ 5M WWWsssZZZZZZ[sF[nۧ!ZT Ji;ݒŷeE 豹v.yO9;N|]|xxus)˖-uP=ܧWXۧWTۧ WR#>)u4T`u4T`W\Psq)Θa`s~~~TTT:::VXYb5vu)4?#,++D|D$[S[S.q=d=*++++883333N{L;e;$$/qqqqqq `2D%hXb:X' +~},tttttt.)&ɸ(5BE_ \''@@@,'#McySj X00XYZa3z%/:Ŷ,;JȻ}}]IIfUUzzyyy_`=kpGFFbb8 HHZaa```#&'V+r oL𴴴\\\\\\g~~LLLPPPقvH{&1<sJ!EDC ~||~||ZZ\b?RjOe|τa? VVE *7D4CQ(1&п؊u???...LLL܂ 8AA@@@WWWUUUIIIggg{{{WWWUUUMMMJJJ///PPP[[[|||UUUJJJVVVggg]]]|||~~~gggUUU[[[TTTLLLzzzeeeLLLvvv @@@(((zzzzzz$$$ᕕOrrKI8K>> @@@@@@@@@@@@P))&&Zm rppѷCCCѷCCCѷCCCѷCCC''```rrrFFFiiiWWW>>>///ѷCCCiiiWWW>>>///iiiWWW>>>///iiiWWW>>>///8RiieeeFFFhhh헗999iiiWWW>>>///hhh헗999hhh헗999hhh헗999HHHHHHHHHHHH,,,e%%pppQQQmmm;;;qqq===hhh헗999mmm;;;qqq===mmm;;;qqq===mmm;;;qqq===555UUU$$$ zzzWWW000RRRߣ^xz}XVU||| @@@--- 222mmm;;;qqq===@@@--- 222@@@--- 222@@@--- 222444www 333 SSSWWW///{{{ UUUlllRUVz~t#pT}T}ycEEE ,,,===ˌ NNN777@@@--- 222 ,,,===ˌ NNN777 ,,,===ˌ NNN777 ,,,===ˌ NNN777ݡ 222yyyUUUUUU111 ڞ TTT===Werp5CR5CRGGGgggUUU ///QQQ>>> ,,,===ˌ NNN777UUU ///QQQ>>>UUU ///QQQ>>>UUU ///QQQ>>>SSS000yyy/// XXX '>QaMcyMcyjGxxx  --- HHHIII KKK&&&EEEUUU ///QQQ>>>  --- HHHIII KKK&&&EEE  --- HHHIII KKK&&&EEE  --- HHHIII KKK&&&EEE熃ƿ XXX48<}42/, j8GWt333oooSSSsss  --- HHHIII KKK&&&EEE333oooSSSsss333oooSSSsss333oooSSSsssm{{"mVwVwZ0:fhkHB92?M8GWDYmƷ666### ,,,###RRR XXX333oooSSSsss### ,,,###RRR XXX### ,,,###RRR XXX### ,,,###RRR XXXDOYŹx~ 0//hNkY4<<<'''444---### ,,,###RRR XXX<<<'''444---<<<'''444---<<<'''444---7*Yt&ƶ***'/ (1$$$ (((???<<<'''444---$$$ (((???$$$ (((???$$$ (((???8-!!(:JZ&1;,,!(((/// 444iii$$$ (((???/// 444iii/// 444iii/// 444iiiIB:EXk!(G[o@@A___ttt/// 444iii___ttt___ttt___tttOe|LbxU :G @a1Sb:_* Sb:_* $$$mmmHHHHHHBBB___ttt$$$mmmHHHHHHBBB$$$mmmHHHHHHBBB$$$mmmHHHHHHBBB q TD E †\ 3mGMC%(׵ $`\V4 A_* )))  +++SSS$$$mmmHHHHHHBBB)))  +++SSS)))  +++SSS)))  +++SSSmCSo 4  E9O^j RSvSB @~ o 0*n.! o )SvSB] A7n.! o )SvSB j~mox ;o];o݈~ST3ݰ-$>aCYU YmbiHᤊ%"EwP[HdzߡS1U_jpemUtAa( ݰ-$>aCYU 彍0'CiFVHﭖZnemUtAa(  ######---///)))  +++SSS ######---/// ######---/// ######---///0Vn 0#! uUAmx~~^8: Kxe $0aCYU YmbiHᤊ%"EwP[HdzߡS1U_jpemUtAa( ݰ-$>aCYU 彍0'CiFVHﭖZnemUtAa( `s IX~ o`ww; @Uo'  P:A[aUo'  P(}Y@9fiKҏMfhQ$,?bAɋ5s=ᩓ&bj,?bAɋ5s=ᩓ&bj,@jK˂-p:x ;uXjPFFFEEE|||qqqMMM---$$$cccFFFEEE|||qqqFFFEEE|||qqqFFFEEE|||qqqϸ=yp#xoxYFv;UukhB ^nu?߇jdio|1Sb:_* 졡$g}8tYFv;UukhLa3vՄ:PlhA 졡$g}8t7nnsscc?\\]]TT- TT-0}0ˡJ !1Q8TtB@ްkt*#C~6  @V}cXNePB@ްkt*#C~6  9鿎t{2QB1(((( CCCFFFEEE|||qqq((( CCC((( CCC((( CCC)BX6 Ql}⦖:A7CJ%2(CmY)BX6 Ql}⦖Eȴ'LkO(gy{⦛9;(CmY 6iQ6i"RgR Gg Gg 7l$"RgR Gg Gg B~^B~ Gg--- ((( CCC--- --- ---  382.N    `o`   ...666999 --- (}Y@9fiKҏMfhQ$,?bAɋ5s=ᩓ&bj,?bAɋ5s=ᩓ&bj,@jK˂-p:x ;uX_ ---JJJbbb::: ::: ::: ::: 0}0ˡJ !1Q8TtB@ްkt*#C~6  @V}cXNePB@ްkt*#C~6  9鿎t{2QB1(癐b Qf# AAAAAA𓓓g5 2CSPk :::     6iQ6i"RgR Gg Gg 7l$"RgR Gg Gg B~^B~ Gg{KDqBSW Ǒf,vZAܛQRPO?Ϳa=K) ܛQRPO?Ϳa=K) dZBuf.氘Nk rwfmmmgjm֧lŶ!+5Jc|,;J:::///fff :::///fff:::///fff:::///fffX` Uc@ٙ#OY_C X^ Wa8؟=mPh]ʐq BG"ABu~^xԓ7$̱eO6R7BI[pÁ,WlO6R7BI[pÁ, ԣ+%JtKTDٻhBI|\k@`d V`y"ǎam>/@K&Ͻ'LM9?A!*g{YMMM---bbb:::///fff---bbb---bbb---bbb㾾 $$$&(*ƓOMPMځ.^oQÎ UPVP盒bzi7x7ꯧlx6}# b^4ݘb^4ꫝlpciQ 眖ifkcsE5K7}CM"kbmN8t/#1H#Կ-8 d˹BBB(((%%%mmm666---bbb)))AAA666!!!***666MMM999zzz666雛...<</@K&Ͻ'LM9?A))y##٥"YUأ#ZRإͫZkTѝff^#J \t1Jgo xi۲xbU*Jgo xi۲xbU*Pk;ڏűgE 籴v1|V; ٤#[U٤$[S%?)???ʽ<<<oooeee<<<... h6 F^uG^vBXnŒ7t,OpciQ 眖ifkc=mQK\hg߈j=io|cpciQ 眖ifkc5K7}CM"kbmN8t/#1H#Կ-8[oow е-//謼 TU"07v7vx&~w~-b-b&~w~-b-bFF [Y[Yiωi ....<<ttt???qqqnnn555___XXXfffTTT999Ȫ5V|]7zy dmdܾj?[|p7zy dmdӵ8Z;Ȫ7(ǩ6Y:G+Wnn ==ƞHHH氘NjSb:_* xxxNNNYYY___\\\gggbbb---%%%pppؖh="% 2W2"% ё#m<$ؗi?& ؖ i<$ȴ 6MvNWW++tR//iωi GgTTT|||CCCyyyTTTnnnuuubbbHHH222}}}555ddd٤$\T Pk;ڏűgE 籴v1|V;;T]yuxxs*̖1yU> =Pk;ڏűgE 籴v1|V; ٤#[U٤$[S%?)(((bbSdd>׻~~>>999PPP >>>PPPsssKKKppp___ZZZeeeXXX]]] ;;;yyy..FF [Y[Y 0z>l>FF [Y[Yiωi ....<<______RXXL//M ;  վs $,ZZZOOOFFFHHH(((ddd ===ddd ***iiiPPPSb:_* **b  &}px,,,PPP 000~~~PPPzzzzzz ***|||}}}```TTT@@@ϰ Gg1?Mպ» \\\dddddd 555^^^[[[PPPCCCNNN ...XXX|||TTTnnnAAA(((EXkZtzQþ777JJJJJJѯ +++;;;JJJ,,,TTTTTTddd!!!YYYttt aaa ???;;;\\\QQQ,,,Ȼ,8Eʽ efg`2s-:FԲs111...//////ҸAAAmmm<<<555nnn777XXXLLL###''' ,,,888888(((~~~@EIlnDDD`2J!&l&ʰtbTTT......vvvlll***ؠ666gggRRRPPPKKKQQQ ***jjjwwwDDDXXX "$]9nI򶶶sssssszzWVVVxxxrbuuu  www(((EEEvvvUUU###vvvWWWNNNbbbnpr`3!(oFKKK###bbbmmm TTTTTTFFFeeeeee]]]!!!LLLmmm###(((HHHXXXBDEd=O`iI!! ]]]UUUNNN<<<888>>>???111􍍍555YYYWWW``````|||+++}}}TT5.@DD;݄̘M'뺯Yil```,tr7 *qmպ^s㠠!!!000XXX 1ppSp0}h$/̳[ h[!]7h>>U(b:ثG U(b:ثG ###888HHH(((߾ƾ(((%-49Qg4G\ĺ )))$,28Mc6L`§ĸ***"(.6L`9Pg G   888...  111 &&&ڽZZZ((( Ƭ"""UUUrrrjE"3DT?Yt ζQQQuuuh3CR?ZvԿOOOuuueȌ1@M?Zv!U(b:ثG M2rkvɛ"(AEHݶ$5GZlsb=    ///$$$  ccc'''%%%AAA CCC --- %%))PPPHH !!!ĨŸ888hhhkUkTMMMMMM቉~ ,5@>Ys"/<ǫµ444ggg|bZ~dJAAAAAA狋r +4>=Xq&4C̰222bbbvaaz^A888쌌x *3;;Sl+A#(7I[;Tn <Մ0 /S3uܛ~ُRlmx* 2OwJSD?iRh  ++        666/// %%%***]]]FF III ::KKEEE nn**  55 UUJJ  44))) && XXX **ɾ^^^**DD ==))!!!...γ000```uffy[>ͯ 11SS::::ͯ||77,qq|OOSjjjjjjȌ0?L@[w!ҵ,,,___pjjvVbbbbbbϊ0=J?[w&չ***\\\lllrQss%F=p$`\`yqy \\\\\\Ԋ0;H>[v",$=# ,ðEPE!h 555ttPP ^^33++""<<44 HH QQ000$$44qqq  AA BBB!!!"" MM77ط000;;;77 LLGG;;II  $$II((( RR>> 444ؽȿDDDuuucqq>>OO```` ]]]]Tss##]]_qq| 888썍y )19>>sssdzeze2Q>>??  ?E?{/./,,,'.4:Qg1F\$h_X:!\lj5 [[ LL FF AACC::66VV zzBB񮮮HHH```== ..==㞞ppp%%%//  :::##DD MM((((((%%333333 77)))RR  !!!'''YYYooooKՇt''KK::AAAA GG?}}''("'5GWP%IzkJ3'̴XŌ: !==..OO hh mmQQ || &&&333 rr++## !!''' !!!CCCCCC00%%@@//WW EEEE **KKKƺ ===llles\s\55RREEEE ssж44(nnwVV]XXXXXX؈n.:E>Yu'1æź 999llldoWoWRRRRRRۊu/9D?Yt)5Ũƹ777iiilUlRwwɸ+M-QQffffQQQ{MMMMMMߊ} .9B?Yt+8Sچ徘r#6J\:&&& XXdd == vvqqMMMM!!!999 ѺRRRtttixAALLiiii ZZZZ^ww^!!YYYuu(((%,2;Pg1H^ԿOOOttth%%%%,19Nc4Ka¼KKKwwwi8QOO00 4;4uEDE!!!%)/9Ma5Of G G G Gooo@@@BnBn  << 99  ** +++!!!  ... ### ʮõ333eee|`^~bFɃv++OO00==== DD;}}--0 vvvvvv4BQ=YuͰ222cccy``}_Aqqqqqq4CQ=Zu˯Ĵ222```xdd|]>ss"F?rbbFFl&b]bwqwmmmmmmŽ4BP=Zvnnn     ???!!!/// 333%%%%%% $$$'''ϾGGGxxxgzz99RRQQQQqq100$lls\\eEEEEEE匌q ,5>>Xr#2Aѿ¹GGGtttgvvAAAAAA狋r ,4=?Xp#4EԿºEEEuuufttʴ 0Q66CC  EHEz***>>>>>>늊u ,5==Un%7H(((***'''000 """(((   111 """ Ը***[[[nnnvT苋t""EEFFssWWWWf||fWWTxx"&+7J\9Slֻ)))\\\mmmvT!%*8J\9Tn׼(((ZZZnnnvQ?K__"qϯ*1*sjs_]_!%):K]5Ql &&&SSS666 '''eee +++444///""")))***   $$$%%%!!!Ǽ???rrre{e{eҹ} //RR44448888BB7zz337dddddd͋2=J?Zw&çȼ ???qqqfybybbbbbbbϊ2?J@[x&çȼ >>>nnngx`x`ooĵ)K2~ TT```z`WTWx______ы3>H?[x(mmm222   &&&  ))) ###444   <<< ,,, ʱ!!!TTTtttnF==QQ\\\\nn8..!kko^^k333)178u???///򏏁*06RRRRRR:kRRRRRR:lwwͽ 0P//GGwwwwKJK{%%%PPPPPP9JJJfff'&)'''!!!   &&&!!!???:::555}@@MMeeeell?dd,,ffiffu%%%%%%%%%%%%<MXX%sʧ|.4.ukuXXX%%%  87; $$$ &&&!!! *** 444 !!!000҃s**MM44PPPPxxPPI}}oo'I7y XXYYYwY ZVZzvz===,,,  ((+]]] )))  &&& 333  ///  !!!77SSMMMM2222²}}4QAA88 ?A?{555...:::     444222555  &&& $$$  %%%!!!BBBhhhhMMO?Ogh656777(((     .-2  ***  111    $$$   %%%:::,,,===ZZZ   ;;;///   777555  ---  000  !!!    +++ 000))))))   %%% :::333  ,,, :::""" yyyBBB WWW        '''!!!!!!555,,, ######!!! ???333Ҷ...<<<  ((( 777  $&)  MMMLLL """))) ### 111 :::+++""" %%%BBB222 """BBB UUU::: ቉!!!   www >>>   FFF((( &&&&&&!!! ų>>>UUU333͙ 999444+++wwwkkk  wwwvvv EEE!!!"""***(((,,,  UUU,,,(((FFF)))!!!... III'''GGG    pj/ ź 3@F7 pj/pj/ tt www%$'ggg  )))!!!  WWW777  BBBEslU}kXtAj/ tyt  Y%  r R-  /` _( r" X0 2` X0 2` R-  /`555OOO  -,/ ggg111 ___ """)))  ... ---  555 [l5ɤ)[l>5[U4 ss# p/RK/ S}F&fZ&5hb1p/RK/ S}FȒ/lS&55CdG) k}. r;Y<׮>[ r H'81 -;CdG) k}. 5[U4 ss# r H'81 -; | |8/ )jB? J _$v| e/9 ^e/9 ^)jB? J  %S zi -Y  tz v   %S   2R zv RRR}}}  YYY """444 /// ,,, ///    !!!O>@k@;v^#8}{ x2jX *pz +@@Nir˝8,2jX *pz +1F|S,qx~ |uaK/ +[k>ɓWH* XoG< #Tʲ((+ɓWH* Xo8 {j /OE2  (ue?thH% ut!*&?thH% ut>uaK/ +[k>EARi 3  DO  d d ed d ei 3  DOG  M EG  M EM  J-W:::vvv--0 25< Ż+,+"'/--/!!$iii !!! %%%HHH 777 s [[JnJKyK!cc[/ *s&ZZ InI[/ *sn$:y:TT /y s sRRsTT /y ssKyK!cc s=^V . @ | s!>>%%% ???888000 III ""  ˃...!!!"$("$( 89?))*D     JIHXXXXXXbbb ;; CC && $$77 <<++<<7  000111$$$BBB%%%^^^&&&79Aõ)1?     XXX  ۿ"""$$\\ ^^  &&999999,,,  !!! >>>888---BBBTTT!! &,7      a``YYY}}}///22 $$ !!!333 @@@GGG### """000MMM BBB  #     gggà lll NNdd$$$000 %%%AAA777(((444PPP>>EEE :;@׿'  ZX[ www&&&!!!LLL򗗗ppp13:& &&$??>>>>###ccc^^^\\\  A@@uuuHHH[[[333 )+07:A   -,----CCCnnn RHHH777 89=  IIIdddddd```MMMdddxxx 127<=A $$&$$&  &%'...TTT$$$\\\qqq ~~~888```LMP?ACύ 888aaaXXX~~~)))nnn558 %%'111===eeeKKK𑑑 JJJ/01CCCCCCȥ---FFFaaaJJJttt___888888###777EEEDDD㝝 ***HHHaaabbbbbb...hhh333 bbbbbb鰰%%%666???===444PPPZZZgggggg '''///;;;+++%%%000AAACCCUUUUUU::::::    ######000+++......```EEE111JJJ,,,,,, !!!ҿ !!!YYYRRR [[[DDDUUU888___%%%###xxxJJJsssyyy kkklll\\\얖 111^^^(((NHH =<:mmmXZY  RSP啕 ppp('󥢥'*)0 ,mjm TUY**( =<:000kkkjjjuyz z}z`]\bef220 756CDF666!!!>A@@>>^^^YYYurq   256+)*#!"yx{UUUPPN!!!!!#???rrr  0/-FEC 䙕gkl]]]""" 23 яWWW   fec963َNNN220 RTX)&'ݝkkk /-)ɷIJL///ſ $#Aׇ  hefedb;<>!%&&#"IJLmmm 晙jjjlopdghuwz  !$lhgjjj111¼[\Zhhh yyy lop [[[  JJL-35 333¾ ###MMM%$&)(*(((~^]_  QQQZ]^뱫LRT*&!LLL Z]\tttW[Zilk???,/0%"!  RRRŴlljUUU|VYXhjmGFI # "NQT$#!  666߿/,+b_^8;<𵷷[]`NMP       XXXhhh@@@3/1   QPN  QQQ()+?@=      PPP)*,qqqBBB (%$B@< ?=>$$$degυSSS  JHD0/-$$$ͥ"""[[[uuudca(%$  \YXHED JJHLMO8<=ijl򲲲888XXX???333FDE$$$'*) >:9GDC 000STV\\\  @<=*&(53/ )))  ""  %%%###965-*) ~ <=: 474    ^__  :99 -,(   oqp@AC ('%#"% KGF&)()))! #(&'=<:   8=@ٕ .,/       ,)(#!$ &&&~~z XY[     222\]_(''%ɕ rqt!#" <<\ef Gf3Ad1I۱p%OpwS*l/?lgoXts5oX G 9[[@ ovGf3 ۭ\\\\BbP92,$ hEI9ȸ F `8 sf8 'sf8 If8 rse7 J\\JJJ$ $ fffOqS@-O--v[&yXG_DU*v>/1$4$4T +VfB-OT dPP000000$ $ 8fff y `0y0{ U0y xYQ**[[[Weee_0_0fffTTT '''DDD ???UUU***;;;MMM^^^ ]]]%%%000UUU.y].%+{ p,)0!^Pc )v γ2MjM"G/`k›62MjgM7qruCO OGCl n' *f@>ȢGn?۲H,~  +3L>! OW(y--ffffffgfffHgQ^RUdy $d\ "y(++ppWfff_0_0 [[[iii $$$"""^^^^^^  ___  ZZZ^^^DDD^^^Z     * ])MY|z丹UI;l    B- OzSnkec"]O  F3+)'eチὋR2"7N}?PO   m_f"smhZ+bD a`+ptiEɋ?EO '+++ ިtgښj Ԋ!g~~SO1'@?7ub6Q L^iduyZ84//X~Q)k=b ٓ/'J &=LCCjY}_u`&`YY#T(0O`Y'Kٶ;85wįŊ~_cD\;)VSuj_jD00  ^^+fw-66Q2G\3H]6((FFBO]vv Ǽ(P  twQ  ,   vv K#Kfff27rѕuf{j]u  {Wb@i`X ryja(2o8i9 \oubbsk{j%?gH29# - 8usUz ]\_v Ȳa2r%1PϚe ^^}ǾwW?__``Oҝh L7m"0EFC5((lL870III080f3bK08N'f3Z- ұ8q, G4e' YU`ĸ '2&%&@KB:B:`%&@sȸsBkussku_2gf37\Nu'f3ie2f%%ZZZS3InxACVbϕZOi-Tuf^tl6:nx4#NϙN^||**yN^|q.$`1W;;O`O(Pa[v% F((P~((O(fffg,Im$fNu'Im$gf3HgJfffR rRR R T  Qeee3f͚3ff3f3ZZZqqqSSS SSS  999UUU)));;;MMMUUUbbbbbbVVVUUUTTTDDD Hn]A   uf e      mݣ}Q # <*I@8h     s7EQ&"$'J_ 3 &l   # b (+ 997 qb -q ) ]׃_[u#',ͺ'''/ұpeh3uE;1 (d`[/K3 ^VG''/Ӫcc;5pebJ<gox s~&6sIFo;d;2[bIkc{$D<  ou|zOK4q<  Ӿ ]eJRV[X;) EKMSU:cp4& .jˏ̥ ui{^-3s -:R)A(T_SZY Aofc>%iʏǼ#L+h\Wԍ`Q,13|mhx363 gd'vQɻwK00vRXYsR(-<^$ysv[J666E# H7Ei7Ehhtz_;iR}444AATTtt&?|levF3 Xj[BBZZnS11>I򖷙55F(*Nj؄ׄk!sGKV^^~'')~:F,! //{^balA (8fÅ]] 0 cBISSSJWLoo55**󄐗+*23IgL ]?  gg0./GG22 cР`0`NN+++IW}2B;~~~~ Ū;V}$+c`0`   &tTeF/Jq$ Ii3S6"9΍+iSSSHHH2%ZU ~x~wnܘXXXizdu1)_  t@a6* 3"i4/ vר2JuBA  -@G̿Á-ȷ  IӪe  `n[ ENW  ŢB98  J # rpuaZ~swwMYc $MUHVI r_MǼ6AJ6=Dd`SC8*t]r}|xxyy!)*+ Ci%ʩV_"ķ>KV) %%%-Fȩ$0W3'@*&=Ȃ"@MX+&&&88dD%0W&GGQev wV 0P:") hhh***RRR 1")\bh ‡sU3;_/>>>>>>z\녅 ia ( 3;b1&f30&f3' T&pYU+54c`YU`҄2-|2qU`|25@ Rnk 2í VQ  `  D"V+SRGG `''N2N `:     f3e2`0O)e70 "I8 <ͺn3}f8 z_ȸuuBIm?j<61)7dst/ qaޓ<I % JwvBGq9.80 L@srE0 ;0 sxgD!P{yW+-\L t! "IO =ⶂvh{yW+-\0 뿁jO0 Dm?j<7[h뿁jO0 q I8wpc5 aޓ<>ve8wpc5 /  L/ q/ / 9.80d\.ݲ7We7 +IYVIII f3/ ;Y+@+qq``AU_zųjDSWȘ9%C93ip 9wv7/EFdak}WȘ9%C9qh{jDSƸƸ 9`rh  ;W(E[[vXƸƸ 9`Ruzr8B2 ;coȺ8B2mipfH5O~^^cwO(fH5A`к.N qhq#rmFx{$‘J;U0 `++ @־L4UOlup&$>?-lI``\B uu\ll %%ddd*fffgf3~ V+k;X MMD HLLQR RRyRR \[R/R y* f}y>x pt%tی, PP\ffffff0`Р3f_0_0^^^^^^vvvZZZhhhEEE---:::  ^^^UUU^^^RRRrrrUUUBBBBBBoooBBB"n{:~X5r=p:el/ J ]B R6/!נ  !Q    tCV/ˬ0B JXP9D'0}K>)>>բ L      >'Nc6GnE(ݻ珠pP uz²?BRջ-'=dXJ)+'LIKʛ ~       _ [[[,*(y{}xs|zXPL(.c]EO;(øĜ,YǸ a$>xsh||z YN0NHE{ &r@y%*. O;0*!꘸i]}5e&!&+15/11  rdDNHE  zb,lll[v'NH#_ wfՆ}DN[+6>U`>U`ĵ1:K 4R9 (MaS"pmTݔ?tTt xџF:d*xf]?^[}&(7  _B  L; ulLmP /,0iۡ(&bRWhv`)tto xspw|!4G,G70r70B_Rx},VR$jRl^/?$g ~X Q: ɶjeG)Oq <=GL%Boan{{@@55X;AFѝY*c>ڶf~A,;3Rdydy*۵/ * Ġ<`uhFR y0 ll BB>>..%.7ŻwAeEEZk[%!(~tj666<(g<(*%K.B<`uqQ CG z++TNB'/6 %yVxoo!!G ;%-4M$333C }a++mi?bI !& I(q-=Τ#%.. >!hh+& =) !! q 4~~;:+J%JJI%I!LA00C1 u!9"w4X)n0O&fV԰VQbs  ;:kkAAAYYYRRR}SQ!  "mnD3F;;;NNNNNN+++ǧVV8 .q77;;*Vx\  148ԫ%f[JFFF0̲ek1E~wD(2: Z]7a@ !bb,Uo,'0:cM0V8 d%  e"fG!,FS !%|-RyL+ *2nP sW%$0:h \&h ݙ lwĀ ؼr !J1X+ 8"  fyjQϑpt{ pQ0Q0 cۖ  +[17깸 rt1˵,8E7M\  *mJ%   >#il#.! "(1.5Kb7M\ COX  =n1  j d%8ycjq  )3ȸ޺s,Ox 8 Cځ<(Oryf᪇li3nqFȸ{J%Clrs8 C0  "Fo8 T$ ]VfFfY m~]f=@Tn8 xfAi.# !rZ >ȸ @}K [HᩀLj5a)yH%AlpI?s LLmWaqKϓVV L8 C0 8 C0 `rs>ȸfDVCfDXlm*o! 8 D >ȸʖa0Xy8 Cށ8MM=#8 ޺s,Ox ۫rY9-ʖa0Xy L8  )__8 Ys8 C0 f;K5i8 Z$ vQs8 C0  "Fo8 T$f;.Tf;K5i8 Z$ * }GCfAi}8 E j0 rZ >ȸ#Y8Y/% @}K [ ٨pY9-#Y8Y/%s LLsp?s?sssI?'XX?s?s'55 RRR]K9տŨf3, f"@@""WW((wwfffApyOqR3>G7rIZ3ApyǮYg'uoIXZ")bWApxC2IN5rIZ3Bp$MyQfBPfBPvNYiy%g%:{;YgwPfBPfBPvNrΧ( vNX!a|v,pL X!a|l mCQvy-%6S$xvpJZ3!nJ&^j)y-%6S$ _g{Sc{S(U`4 &t{i(({Sc{S(ApyO `o}_HTb|$i2(*gV e.. hg6n._R(wQ}envN `z.2y2.{=oYDS/{;9|#}#8vрxVU*tjAR5@H8oy SXO $lyOlhp((((gIWgI .{.QQ.. XXXې*)))f==*uuk T~*bʮʮ!3 6R6R( ^/ɮ7R;;;<6' rqߠ+ vHFQ(2  b*      W-$&8>wnBZԿX$3ګi_Gܦ 2ROL @-ޖu @     S9?-5q)bZ,AA0"(GF[(V )ƮCM3 -NN __UJ     X5u@?-5?;;:k+w#Fq[v}G\\;F_@utdh/HL  )֒ |)Y9_)^v P/C +giegqY*6T|aL  џRIGssh yUyUhfc`zo c|՞3%$; ؼ(ESE-ȽBjCC?_oaR E* 8G>A$468 "/n"/sshP%".&9=HF?:՘D gcC0  2Ig>2Vf /^ ҙ   =(  yE2Cfu=- -01-$޽"g+oN mN hP2g*p&K t|傠3]~S[a 흜WX =(3ߪ#V9]Rns{\( e{=JVJă"F0[A LK ac 8Ϋ 36AB{__JU`?IR HB$KfJ>"U 791ń |Q QV8roY=Cd 4Wt4W.4==xxxxfffXeqw(j%Yao? kL],$,$KdR?SSS|E׆0&&CC''==| X c;Hf9x0i=P26D"9""R\``...twwv~L%!5ƹ\\$$MM!!ڽ39>+04%%%xsmk)2!$DYYzz* *.;WR 2,(((! AA&&''..=- z Um; %K**+(0# FF!++  O\gHUa22-L!#>ޢ;f6.$f瓂rAGO%^^^>>JVaV&& pO+=Uw}22-# B}g ÿt~^[lq>8>>WrVXRW TT$$!!&&!!D=7ï;iaOw<Ե  dddfHP3laҷW:Oѯg\\FTa 66?L !(F,EKR9Df19@$'$)-ddNSSA. |CBChhFNU KH  ? z (M^iڰ&?|z >ALGN=<%#''YY&&&#EFd ٻ8i.&P MMY=4 >>::[[SII""oo[nn$8]}}##**'1XooI>>::Q==WEl:^^ll@Tv\. GSY֧**!ggIPT윛TPDDI ֞o7oa^^gdwJM\ާ**[֥**UUU' +ԁjy"SYG'22yoG, efDc޽C"CJ>1 27oHH  !]֣**66%ܡS$_**-" iKhвoy9ggC"CJ>.8.nIhhHHȐo7o**66S$___III  2!nnnn`  aSp8p!!!U - L(?A%R f  ݊  bb #.( X> ;>_t\G2  뛛ggg~~~͌FbG6p=|D$ۗj? ܙ]]])))zzz7T/Gm~nnh@G>RY  c> EEE$$$2?qN?\h!*||| wOgRNV[ ꢟ^a !'+¸#,ƥcI&6!̴uow9  ]]}f%':8;'6 @/ Hp}czp =F%Áa=G+__CGGlB=OZ;U}Z@%':&&&#06.9EV_  \;'-_U% '!I+R#D+++ɿ'2=h#T& }zpDw +<' 'V<4,%D {'''ɿ #*.hX6N3# m" :@蟧lN &# FLZ1f?O!f,xO r~dm\c^LXZyzxyH?.kԍ^% !# Ζ (T_[+ %% ((AhA gH$,$L /%X ؔ hzV YYrm;9*81g_w}]{bIp dA%1wcorv9+ U8!ƾ158!%*  4ܐrakk QQыBCh?nsgQfm !U9"Αk, /6>D6>D/Gqz`!& ܘlvぬJ]#Zkv\N !!  v`zmf`PelM]k!&*!&*MC="=^e"34/Ԉ1@ sJG   9FP||e%Qcwż#).dd 3 #eie| "*^o~+4*4<f>""# #\ nȷ+G@<8W&=JUbsG5@!@ȷ&A}ï_3  "$ !: ̹'6ĿB? 77 NZ 簦`o|#%)򕖩"S`67&/* )*)(((A4/&2>S\lz/-<5'nig$$$))) 8& 3;>:!)xxx(((XXX]]];;; ^B ih | 3;0OOO))))))qqqtttttt,76#++++++pppkN ⪣ 76!)/=@1@1OOOǓXXXoR  .,!X_V+G6G6SSS666qT  '%$1S*+++N;N;TTTQQQ쏎KE (3O(%%%+)$ }~L&nisp'3&&X,)"*f3Ć nڥXN1̌<,w ܥXFzqnsj0]N._I`P5sx\sj0]N._I`D:* vܿ*z&[R&7mGA3Lm=:Ud@ .e &[R&7m'  ק9rqnK#kexGA3//H{YK#kexGA3>$AMzAK#斗^`I Ѐ0c 斗^`I mx}rjl eS /{R e8I%Y=Xq\\#⠊e@Cb$ߵt#⠊e@'& ܞ`S' Dl'4n^IuwDl'4n^ W+D"q^'\Nb :- o}o@%O%O' G''\Nb$bZ$rc,:n.`(}(,:n.`S*?" O(9' D"Bf3.-^2^O@"&&&&&&fDȸfDVg9 j0 ™k ErUP8fDXlm*o! |I /yȃ6CߊmZk{ZI  FfnFrgZXP& |G۵8 v4.(!RpvIziOa>* -:' (NYaHQ%ome$#69ز: ***$}EТp<%'rmpȂ3I}jZѠzpO yweWj0 ;~Bs@:hhDszHtB>v#="yt9a8!!QQJJL LLsTSg! $\~\8 'l sfDȸfDȸp8 j0  LL28 >ȸ8 Cځ<(OryffDVg9 j0 ؑkUNK8fD`}ebPfDVg9 j0 ™k ErUP8pR$Evr~ؑkUNK8sgED a͐wQ1}:fLgEǷgHQidP%b6nqު* LgEǷ.pY0}Y#gEJH.޼, gHQidP%b6:6/ {haemPJ0#hcxae FfnFrgZXjJ'~QH*MmPJ0#hcxa.# !\>6iOa><8\>* P$YaHQ%ome."7L* P$ **DhL.ɪ[, *$}EТp<AF%L@/<{+ DhL.ɪ[, fDVg9 >ȸ yweWj0 V"jQ2T|d ;~Bs@:hhDBߗpRl"DttFV"jQ2T|d  Ls LL!QQ 4t LL LLJJLi 4t D",6> O"  `A 7 +7@>>>g,+)IW7Zb) Z&)AA7;ߧpBX$]xh| ߧpF923RvsZJ]gp)# FjsaE2Rv#``-*|nZ0_^m@6l :%wXbc筝-%6xWnZ0_^m@Z:GZ:G &t{i(( -r-({Sc{S((( &t{i`AyOAg+tUn._RApyǮYg'ApxC2IN5HTb|$U4tL`Bw{˰vQIbOw'OSakM@' Afn 6]x#D=fCV>K;U.;@q|*ZOab{[lGAP{i}RoHvN Cj(L  la _5o F5S} xf}w/NU>lhUq]S.blKɿ;QIl* JRhH zdpy- SX -xDXR5@FRwk `((gIWgI((hp]j LL88833 ttcccww±7 ddd>OOII*$<<<***VVV-`0 Ũpd2.̲6R 6Rй#5$6tƩ^/ V+^/Lq&d2( >>""000==:VVNN """W½111EEE111DDD޼DDD޽CCCBBBH͚3f_0_0﫫YYY TTTXXX TTTXXXSSSWWWeeeCCCHHHNNNcccfff***EEE///>>>HHH;;;444???:::MMMBBBBBB)))PPPBBB|||444QQQ'''PPP|||BBB444QQQ'''PPPBBB|||BBB444 BBBQQQBBB:::BBBuuuOOOBBB}}}000444444,W0o< _ wA z  #vA1܎. oBO%ct j;R,0$ @EhL@ kn<"s@  +4 OAc#&4)%  $jD⦊F   x@4zTlt%WW<6zY^D~bcd?< ).)(%  48;b*4,% f8X1$ӑ|]3T<2r-+Ҟ`.*OxнBW1+٨F)&$   %g lp:!tA$5:Ej:ᤆ[~Q(5dž+mf6603.  $3    oNoNxD9CML<=8<=ɓ59,;f aI"&4:,GR9Jvjst    fHfHS/_4WvW=L#P \Qf ga`$1.Yv>"""   _C_Cr ;W\\\VRM~}| 2 ubzdYMdY  ϒ .qf(-@;4$RM@5uvx'hr~ֻ/K~OLgĠta?s!F}!4[Ne`aiB>Ws3AcYwC6^n$0-$  Ađ*2< )LED P9 !ì{Mowviʗs6 Y59k /e2. zw_ s`;7-#-o-= YR;0$C5'(+1"')92"   E껻&''&1>?:79kL7   ti_$4 I7 3'wbT35K_b駷ˣy֣  G' ɔP:c:&Ǭ\QC,-0$(*{mT񳳳 7Q(aH3G'&p;+  j"*6 e_$>MPxl_# m3ppZF 7jU 55t~G' 4.)x@l }lPlP뭭&/Q"JI 5&U= 6'  n.X E1 NONT]$ kNyXc`q]}Z~*  %GyrFĀG~o`# .14̱yLc=3)߈[Aƶ,>Yu魆 &"'8<6=@A$#aJ2S_;FO %uUT- 2#@- M8 K[ 6#WLqf&U~ { FZݸ3p b '9@ b!컐 h *#m;hLdXȷSQ1ۇFG>A;>N+$ + {u xO# ~.$c^ KKKV1  &% VK T< N7 ;M\$3f):k.*wj]lTR$@6i 9CJ#(- spk D<& ٵǢD=SĘ(׍^HW1 |9?2/zb>(W{Oz#B6 ǻHX췢Ls xOZJCCANQ444α !+; rS@ , OA  i,# GGa b … 0L {黳_qGVcg" "/!w[ÏjtD qnk "ױ<=TW951h2 Y*4S&8+ $%-53%#Vآ-G ޯv+QŪBSI2썒tnib`ScaTm^F @@ z:tX944**M ô%=$]?#A :^LYnnq2b5DDN<<vv ~~dUx zTMM% ZY$$$vouvu0"   OOY OO;yv֫U*UDD44<!  C^x"(**TT& dU\j z&Q_TMM[!!cԃ濿\C  A7w5%4(RxAaʯ`?ac7%%$).4^֢T A++"핓 XXVeeeeee``` K@? ?U*U44Ä=||!!vCx"(**TT& ݻ*j\_Ǐq9q [[SS(((Y] Y$ ' 0+#5(Bb&&f ֢r\렡UQM lnln666fpp =|ivcc.+ jN,,)EE^^]]4Z& q9q>>> !%%%%I{T1n}~I}        !!ŋٟuZ.JJ=+))rrJJAAA _h# !!Tu!JJ<zKK=G  /c2% ' K6 +- " l3 b= !hSFg/u8#/wf90r %&7o#^      R# !![36 C  9`0d4;er5KAXՈHC y999}}}444:::===|YG޹+07ԙD**+BLU?>< 777777}}} +++666### UUUUUUEEEծ3?nq uslƥCd++#"hs&ϲ{Y~lmlzs2B@>!!"W1!''''''OOOzZ?r'T#_T(QQQwnOh{.dE "?x|  #$?7Jv{e.#:.D6R >-$ *6B6"*ҷ4gtƽOPS@.╰K* zζ HdhUC| aa1$!¼C?;!*1Ƿ wZ& -< ;2v{_J*Ύ]&H]CUJǔxb{`t#z "*8FHFHOPS%-5&9*mބ,۔h4L5MmmlpU>V?..$ dci .Y{V:!VSOU5&& P9gWI#AC'2, jhZn2r2r){ f5_ %-kF2!L,}lTp       6 ''#*3$G0 KN)7ZĮGna{T~=м@B ?" S6X:  &! w   dH N>DR ],MA!'̶MiV*AY5Fqg7)$**B, 111  >)[= # N8e Ʉ XS> *), #'E(˾  N3D."!aQ8 ǯTC3K$  w ˙ޕvF; 3    V$YDW rOyT  o07T)[:3 $-zL F5}1?l= / [Q4,fF]A II;9v  0%%%---    qN ,i{ j  E  bb{|98ΊQN˜'W ;+ Whˢ7,gJmr8 |  /p6S` QQ YZ??:9o mK?#;A7znøWco8*+J l[rV9V980PF>2AB 6k,   ]c؈=2TjBϩy\P 삂YYX uULgJKAM?Zxz^̠l-%-7  ~{x72GX2 hov.~w '   &+#(,'-2%WU% u ""vf gk\N8!8lq'06 ſ!$',1!'=;k5&.8) e6# #1>Hsv)Ba’C3 }H (V[b #/ U>) 'W MYb! B Jr<+30  )/. , א-\( 4j֎#9ImXXIIXw."-/! Zl{:DK',1A!SVY#TU_jfvm7%>*vvun% g^~nP )p(  =--%uS;D%B ɸ7HdȿƿBLT%+2#=8팭fF  #nQ@)9% _6fI?;_Mf#'¸pGR[P')29+4;ic"RbK/ #  )^B kJ.8@/9AFdx CڑTTTEEE...+&!6(/pStSRa    utro"* HHHH'/SSU‰LLLZZZ###445 #7#8$hg zw ( BBBBBB###չZZZRRR5&7(  ]\ur&#++++++rrrM;M;///XXXEEE8) 7(   PM|y FD%&M' LLLLLLVB VB:::BBBQQQ* L9$ _]~z C@$**4 L&CCCCCC ( ( ⟟QQQ???>>>+ y[ nk| @=#773 K& + + 脄#DD J% yx$!||||H$ ts%$2206B! f2^k,+$ͤ\]M!c9' ƪ6;("H"H :iGa\ s?Oߙ@Y& (F9_= :iGa\ r:s9ؠ-YCmx* :iGa\ 㫹 &M=i4# ĉ 9+VE=s?Oߙb%癙n45ĉ 9+VE=s?Oߙ@Y& 1J߬k %8!0A&8K%$MD{MD唙jmI x]ByOR\^MD{MD唙jmI UYM蜜vq MD{MD唙jmI ï|&LyGE^]XeN x]BS]яe3yGE^]XeN x]B!ViVٛ@cf]ի: 5780( /Uի:-/.ի:>U֫h +aFm|-4N% 578DIEH\>ugE4N% 578G$ nRVY@!93e%b]h$%*2̤e%b]he%b]h&+]+]ײַoj $+,+NS5-uiRKۙHQ +,+NS5 X,E"&?Ӣ "=/Sql @Sݳ18dFfaSL`^Y[6#Ċm#D:c`$ @Sݳ18dFfaSL`^Y[ @Sݳ18dFfaSL`^Y% ڝ .XD$/ ˎm/U@et*JRq z*/ ˎm/U@et*[-A $ -bJ-bJ$dSd\~\%G =Z=5K$dSd\~\%G G`G$dSd\~\&eSe5x[5x G`G 5y5x[5x G`G ^/<* `020*<G#z ?  I% MMM BBBDV>j0 DV–E >j0 DV2wo DV:Yw]n,wzPt>j0 f5z`N% LsEW>j/  Lsc|qz_vƫĠL|h'q0)kl,݉*/aj-/ֽx9ѭþ2X~^Ck#qǷ)Sf;{UzȻ)Q{\ <}U{織m8) t(BGhO4. 琢Jb  / *UD|j 9ISͤخ~0nă 7DFαׯ3bă~ Gm" 7QxMxX>j0 ?`]}U4v$rlӊ-vyy~>yYz!҅ $y؁(dmzj0 Ŏ>j0 DV>j0 a*TrF  Ls>SgR DV>j0 DV:Yw]n,DV–E >j0 ۛup ]oj? DV=a9s>j0 DV–E >j0 DV2wo ⨩|k>j0 ۛup ]oj?  LsEWƫĠL|h'q LsEW>j/ :~ I}L FItآTß n, LsEW>j/  Lsc|qz_v<}\n+:~ I}L FItآT2X~^Ck#qƳVtΡS. !J+ѭþƳ$M+ƳVtΡS.   Dj/  t(BGhO4. 琢JbDj/ /  9JW#˟T*UD|j :Ma,ʔԴkl!, 9JW#˟TDV–E >j0 7QxMxX>j0 gЎ6w_v;_>j0 ?`]}U4v$r\ɔ<{mH>j0 gЎ6w_v;_>j0  Ls Ls Ls @ 1zrz Ls Ls#szsQg ]_]_ 1zrz K% V+===b9+<<< NNNʹͳ'$7Ba!0I6P 8T& zNt'5O$6¤ŧFj#!  W+=` %8% b12L4M$7$7ͳBa!3==//\\QQ++ 2XXE쪩*>>,,,/A y`OD y`OA FZ:0A [ y`OԵH!.8A FZ:0AL 0jOI A FZ:0Zpfm(ܮ$1i>)_uG ʷ7M`3l(ܮ$1i>)sM~T΢$Ji;&(ܮ$1i>)"Dnn +-(@&&;ț){^LG P1fQDț)Q2*7:;&ț)'8b8ˀ3_M!T "uCI" ;5T "uCI" ;T "uCI" ;z * *"PH.G!Gd\sw3zW_2d\sd\sA,bQG!cDݘtt VKF<2FoG$090!cDݘtt VKF<!cDݘtt VKF<( <~<56(+M+MPG <~<56(( <~<56A y`OA y`O(Ad0aMVd5<[C!A [ y`OAL 0jOI d5<[C!W9vFF ę(/Xo(ɞ(U^+_uG sM~T΢$Ji;&ę(/Xo(ɞ(U^+Z!9bGѨ+L{^LG Q2*7:;&Ѩ+L&KU.9Ş)kVX #u]O5#u]O S5*El4JYCi= {7]W,{7]W,7O3z*G 3iLF -Bm"X y`O-Bm"X y`O_JĔ y`O( FMrM ?w?((( ?w?6}6 ** RR &&&rr $$$***``888...yy⡡$GGG &kk ;;;******Pv( t# Jp%δ̳m#5Bb z2L2LBc!$6¤ƪLr&!  [-Ce!"2! a1|6Q0H.T!  zzډ6>>@@??8FFXXmmVVVJJJ*I%\ \ z3b% \ \ \ &Su jD\g \\ \| jDQ\\| )}h| \ )}h?m lmk_ o9 lmk_ 2  k\ =>  => &&Lv i#UhFhm i#UhFmx mx Y.T ::FF 8 FF+ z ""C,,::SSJSS99XXCCC77R쾾CCC VVV"""BBB"""CCC"""CCC###BBB===)f3f3ﴴ MMM ]]]ﳳ LLL^^^ MMM^^^ MMM^^^EEETTT111III """===OOO 娨000111)))+++&&&///???------;;;!!! UUU555BBBVjBBB666&&&666222666iii [[[000xxx)))bbb...000444iii[[[)))xxx000bbb...)))444www000iii000000uuu(((bbb...(((444www&&&BBBiiiBBB000 P IENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_0D.png0000644000234100017500000206371212174204305026160 0ustar cpascualcpascual00000000000000PNG  IHDR}^ pHYs/g|IDATx+~f31Z9;&5թZ! My79JI/1OÀ/1O11[BulslYc%;3;3lo$d%% 5G f3 T*qnJ0jNDS'ԀZk>FG477\6` `)/fV!I)TMSHICQRO  !!Ɛ-! e7 eeeeQ Ǿjt<OCo PٔN  ܘ''SPK3:[+O^լU  t<of^~2c8LA#JJJf8 L;[+{jR R u   ;GQ'$-4 d; E9{ikUR\*jR   ||ǎr9r=H=|DʋŻ/9B f3T*61 if\*fPG XXX:4*#||Wq;))w ?g9+g9 q~s!xm" 0 f3`ĒyT ։XC?MQ  eeNN+ Y8WO z2錋Ź2>I0 Ƽ"f\. KKС% &M _g4@KTS*TTTzuO AQ˟!% 2 , *5/aO0P(A+'5%' O.Oyi2&# )9٫TS-8_3F6 !J@ '{f3M}ݷ}э9.!nэ9wXl}%U_~[ wwr% ~fuG++}{j}{f3f3%x [ & LL6_b5IQH   #

=| M eL+OOuF %x  L|P]5ʃ$!mѢHhq: C~WJ2f3 eT@.fQQuy`yd fgRRU! DŽ`a_kkw`5AL L>6}sAwleTpq`Ou`OVRRffff383( $ʾ"RQ!o$;t Uړ0 UU{lOOx`O~  j`0^``a gı "* +3eefeeO-' #ukUZG7_;  22tt%-e7  -/  T/b ccc GAUR*  % J\ $ 0EBb؞(/U@P 1 !IJ *'uuG#!!1%|s ڹ캹ߊlK6>T/kf™ 'J^f3ٚ@&^V@\R[QR'"V@գfCh# GQ=O G'f[yG+].]>(f3  > 't 6p,o.1*   p] `VH^̻''( hw  \< 2E=IGI(&("# 740 VHY5-5-ahe|J`e !n1L' ?WFBIEFBBGGIDEB-+(=71 w}  Nfl ףE aڝYLE#+e8ywfQQeeLLQڱ ^ t\ u^@ cDA޳kI9 N Г1zz&5M||oo*ɒj|yw2; \,`yHofofOOǁ cDcM9444S^F @ qkpaf3f:@fBCҷXִ&\ KgT~; \,~\\A\AmOO,Rtb  Wj.Xc͢ 4445+{yvvuEuƻ%2=*&_7IUb 96 ,Q)ſHeIf~Ty(&qLayf`O, W0bg <,iᨇ P PPPYYWWV?}}//[~:'4?;IL?if300fDV>ȸn;Wsiȸ0 Hl$ä=\洡L_y(qLu{yOЮhzOORЮh fff?%  *  WWr// kk06:=ٵQ f8 Q}_6g9I'sE s-=\L_(^4bܲtm `<.Sټ`<`yw Oukd|fxW w)R0RxPyOPyO)R0R ,CjZZRZRRTRfff f3   ! sH?W+;&! $$$BBB)28 E(_Esi! < ~.  \. ۭ7\ fQQF8833 PJ"2 ,3 h0gJ e7 7\Q]     =2.!mM 222hg 0:@;tذҐ(؞*bH3aAH1w? 6U #H3 * -2 ӹUFAs"TOUM! # ,$V F ^wpkp"- j ~b oY   %iSJ ?t_f3;WWpq"++\b_[hzWW N$݃N!}羢gN!}B& ;YW XU"ūybzYWB-\ 1bB( Ӟ}hV췵m- &_hV B% Y %  -b}b|`\ZG' |{' Y8{' <*0 NO6;  N?@%΂B :8Ui@k  +4  Mʍ A:4c b   v *Y('' E>@*$ ԛTv*ղ .CeEq>ԇ OAG !!"FIG'-+%(+s# 񫠡e  xy   =?=''WYX W7n4/"RVSj"j[XN*$]]]1e7 ""    Z[_ tO#Ԓ=0!|gku$<HHHddeeQ /.- ô v!AeL@%~[44mC:i~_RZg$d=z+" ZHw ^ T!AjK Ax`fQQfff묀 mLNvO?Jc_rR~Uyy++1ԜU7  ;aE[;%A6 h   `WZ=?1 B/ re ҧm-   1{ 5jw(5jwA ƽi0-2 ]W121.{kix>f3fDV>ȸf8 >q\W@x` \,tc`D[7ow-{dow-ӀRR cG/ + &$ aaJJ`B( tca^&@ L[ 7A8 W >Y:@TURRR  Wk۪z!y& #( Inno      ?>2v@8e_Q23Ms͗]3O(|$|~|$|~kfReWbb! xj *O111KY]1(07aG кBMV  98f336f3ZRs4gfʽ6C EVfgf3b%VWIIImɟ   =ZGWWJJUWS[[[  ii f30 "yYmv'RAAA8gHE9HGG 򶶶JJJڐ .5u7!  WWJJ&**awC򉽉D!,3f8 f: K8 tf3yfʽ6C L^=a yNAyP=AA *vVAyO.8fgf3g俿5}/Y00  &F  .T 5%, >ȸf8 f'f Pg84ꧦ0*5up^qڙ'k 'G P#oV (`6C L^<XA(@<Cff3 \\ AAAך  $53 ggg;;;]  lH ~: P5$\_`E(BhyOBw~R8ƐQ7 R9ҫZM (@<?%<[-[-DlR\\ R\fff<*ZZZ! |X  @&Y8$6 úBOZȸ."  Lȸ/ 0/ Ŵs/R17"$嵹. н$c]. нx`2QxȈi,.AlA%SS%SS[\ ZZZ73     %\K @kAtJ  7n[{@5 =7@ sOR1=PZ=(x`(x`(i(x`` R` R Ra3  [%fM{١h /,F&gx"%{&oꉫؑ 6  (  :,OV8_T@P+}z7ȆhhkkeeG88eefQQ  ' ' '<..C# :ڇ~#(+nPM$  ER^  cOOfQQa +.`<d?-2dHرPQs!gf ,04NN TTT+1  #kV$JiDAIw^B"!)//b8=QvvBBB  WYcc A- 5bddQ  2ıXQ  lL!)EEfffMMMliU ' 0I]A!*  뾷LS!)v%,  *td-bP(*t֌B*tq'&~ڂ;a[+؞*bH}9z@7bH . 752LSNNN gؙTbddO !gؙTb@gؙTbqf`7ҔkAP(Ux  3;GBN8 '.   29O99.k GO  GA#   *yׁ?    r~ƻ݋z" .' 'S *, {u5Ym$}(}Jwr}& *?b }pD_$ h4S7T G +_͗ ^2"+kQ   %WFUyIv!f3ef^ lOaYU`PE`40Uy`_kiP ^y60l 4V8d _ki<0砾`DZ@ ._CPC瞼bD`DZ@ ._Cs)`JY 5>4/.\JY>0^bb  A89EZ=j  A89&[@-Yx`6}4 9)G' G''xbT5 G'[T5 G'<* T*    N64 & #     G@l^$JtPd R;  W  "$   APɩR 3 R)>#'O{b|ҵ !O      ~JN+p+2.! :6cɱ9gIGJ950xwu$X5i{V< rhvԩ VVVZGG\II,,؃؆333 [ / 3 ] 873S.S.{ 4TYʠ{ss fkq(䑒a3q|(f2 C4&RP0 ƼTX@ p@NZAx`ϼ15(1aO(1aOAx`333ݙ9':'  ޲dIGB2^MEs fls LpoR5 QS*iW= hN)5L&L Rb'1  1Fۧ6|6=n56|6=uZ`I(\S$ApyO9z;k   % vB[0 00$ƁjPQQa~hI;791RF+R+^;QhWP0S{* 4trI|Vcf3=L)3 Mo~~}|7A(VX*~~p-}-A(VX*f .  &     ]7eC   '99 #@:*G""aE bП'(`C E}˕8 2@8 \!5StfGŴܯsAŴ9 :88 DE :88 D0f>fg^͚ر(OL8(OAx`.: >M&l"Q*  ӀQ* .}\\\fff󧧧NNN<* ZZZ .!   "J5 -BXJ{ccc R RffDJO}yg.kE[os4E Fs^z|k3{Uk닊Y*  /6ӲE)55KN0qO0BLT A{l=}v >@w^ιM"x6'f@yfֳ*Ûlh 68退~(({~ww y|sKBRlB\sKB|c!\ ffffff K     0.=  ":bnw@tBwfE#փ KabcC C]nSgzEP\G) LLRaj M'jÇ·L LLrss0sde(zimoݳL[ߙ+8t=u[]C(DEP wxpa@[ڛ5 1S!c8!  &$ #    ;z  Ƶy0Q+H= ɟ<!e u 0l)IKf ^t%QyAds (Omo#MC 6!t` fKwSmx`]>nQknQOx`(O(:R8Ildw*BB BB B>!U8 3R   %( :wȩEVI < h 4  jUg~zbt@LLx` A33ee( <00"('/&3,7? 8÷ ?;   %̓n:]`:  X 47[iq pp}}{r f=zuu"4?IFE??>=GQ"%'c &$&. ccDCTT^ "&6N=4)) уj Ƴ ! %\> h:lʶBLZ"#*/    98iH()+&''% d   ܳ96   49:  2  ###3  +Fn $) ,6> D9  ]DR) PPP KK   '?3.*A8 8 ," M6 I2PCO%uQ+Yft.:C.8@DP l0=NNNP666000}  R#ڌJ6!8&9'l{$Q_l =<!) $qEqqq jJVVV 2 %E)  ;pBClL*0&ffffffHHHBBBXXX|g (bO A:A:%أ4N $$p'ˡ#8  {+--,%>=#-4!!!x%7Oa~g^K3 Iܜ(bpb, P^K3 IU(b;<^K3 IܜC"I NٗA)(b;Ĥ-#% 8TJ*+0 !/,     CJ G GVVOV GO\\*nn[ߠVC76y668,."Ouk1ѽ^H5;1м?*IUƤJ㩜. ZQ{EQ ϐ  0%  >LaB 69* K'A@[T$ڮ +kdDhppq7  YbC-Z"b/b ~ikS ٦*蓁 aF  ?8  -yPJ Rw_Z.|!b0 06bk;9)⼆c`M!G' ƪJ3"H"FFbl^ i]Q|J 糒pkb enU*FFbl^㪍lq%Uqh30peoC<c5h30peoJXBGh)%D{D )w t}\QMrM_kiLM`k*D{D |xx7\qN@Bs<]я3gw2\qN@Bixv]ԣhXl78+(B /U۟oS:-ԣhXlU__sNBN 5I \1NBN 5j,=Iy]f$+2̤8OdobQUIy]f&e,+Z-uHvv,+Z?жA,Ulx/_ū`^~[APH SRN=yaS @x/_ū`^~ڛt /eoTm1U*J̍nxx/m1U*JJSS~'=}=$d|dl%`SS~&e|e[`y[`f30 '$.66    5/o   -!1!  I- Ki  1  &y, z Az~Eق(Qy !")  #B{] t(  mn 15     ]cVՄI W{   g ٤ !  ;;; \K~G!I+  [     f    GEC  "" $$#WXRAED!'% ުt]# r +"Q     k  #&'+  --- )))  kxmoP|I!mdRHs֬$-x P      e ' "BB? \\@?:tČcW>2s      i  DDD&&&000 """  ӽLrR( c<@?:0 Sq{  x      gooomhc$).N' >>>**** *:=*:=i3.  39dWP#-vS[Q]'&$M̚,~هc9 !!! %%%??? P-O@Ypq0&b>5*?3$󏴝35k˕ηz7,"RKHKHč 41-K# MĬ>/TTT((==RR\\P  ### Bo. A2 0˕!`:79!M;1nehFWYLD@%+wwwN=tU>k )((+--ᝥL   !v%9mJDsþǷ%9I#D7*>7*յ [~?tEx t2$ nɘ]W C4KCLW'2:W'2:IyOͺ#(*   +3318F 0""wζvRp000̀]@Z MxCNZ[lO!eˮ  ooXUUZgs B(\2;-\2;-C4J6K`G8PH.`G8PH.ӝt5  6  F |2[2vf>AՐhkd!Va&df/+il(!ؕ]77zzddfO*4Oʌ: )I%N'X\t^_lnX\t^_ln#a`͸;̞]ysW=3̞]ysW=3. x6# ;     (i0z0AƸ:Hd8%::GG;;,,]OA J"%gS_)msA66GUa(Z- 8 j0 8 $E{(Ocmcmo|P"!{zh~gF3Kh~gF3K\\-|JI;H$   = I   :HdMBLm5X?KVq? '`OPnnooEOXȿ! ]4!E#siR. j0 f8yO [_W $9  # # jf}4~<.V*>" dQ77%& EJ z((??? LI,'- &&+V3Ǽ%,1!ypxwv00 ss ȡ #Ǿ10(2uuu0"+;ALJx{] $l_jljZXd駌9AH#).   f366U+UTdd LL(Psg2rVl ]fd|ŷ+6 jd2mEC HHH  rV   %g`(?,1(:aI(ufa9A{O%. xY  BBet +0P(00M& r,7 :q:T[=wҐoE³^vgf3g~C qV,ccc ]}f   Ȳ3j_ "I$I"Hš>833<<5 1113 ##<<ҳ $BNX+0 f3 \." :H3bnq1$3osֳf ayO` ` `+gH  bbb hB=  AR'号pL  <>33<<5 ڵK&Kn333f]""gb~JQU8 3Y,\.Ov'+5O6D 0; We 4A ̿Zpa ((Ee2gbbb Z-   Ye  4Z ~ ''RRV&&ڴL&LA&AK&KnvvcccwTSkvRJ 48 j0 ˌ{P9 C0 gEǷ 0c1 \s 2> fayd`{{5A;5_^x"A ` {F{5tT  `Ocf ħf3 fff>a   -9 <<<~/0''V&& 2A1A  Ʀ""ZM!+ 6( /" + j0 nv,Bc!*4 "+Pe~b?Ps0 Ϡh6\ sJ`?Ps0 Ϡh6wh|nBBSf3 WWW$/x^H     33 kHg^ס11  ::ZEly7 L7 P ,oq(gEVfx V+ |M $ krgnG2 ;)nK6 fDVd;sfDVd;DhV|wSoAyO`Ygx`AyO6X h& '46o)h& '46 3? &9ZR R R ZZZXXX! - - ʻ-33NNG))n Z8%r( .3!2hd~UW&0 -ԗ:/65$pGrh65$pG~Cd_X #  x`#lf¿رwP2}aIX0 +IX0 +  S9t+ ZRRZZZffff3XXXTWͫ%  8 NNmmmՓœh?e*3ԕ%=59B M +n9  yG4_sg׶%Oh XUCE>A]ܙ4ygy yy. XSpTE\4y_QkaCHSxelĬ@ Nylbdmza  `lbdmza ` `cbtf `r \\\ Rl| Rl ZZZXXX  -        777...{{{C" $>,Fh>l4xqD0ܛ9ץe\*/.9PhSLŐ<{+ =V Jjh؆lk) )5Qqhe!$ 9$_OMʙM9$_Oli..DF2`r5EjnLc{((((퀀퀀 ((RR R RRYYY$(B  w=  gx9UO`3 `f 'sh`>2 2"0s1GyLL LLM LLMMFzTa2koq躹nLe Re !%H0   EE9$)4"u|KcXPX rm+b4i_ƼsrmX?9nޏW9#f#zQth׶e\NKD!@P!-(ͦuF0]`h˶eSOD&   * <4  'ZE "% 5( "u~Ԍ\B)PXĹ5AMZ 5-]$)757!% M. '!(3A& LLx` "#mKذxn((4P?ADcA~+(ONq$|yOx`(Ox`lieD^RPb Rpi pi FR # F    %  # '4? M}` 5,Eй/X52?q XX22hh (";?LO 8.  L!')쩿m!.  L ho52;2S-<*(OCNN  ', ILY  ~  72 <@EO7  H' LKX ek-5 d>d>VVץ)[[謬  ʅ #le$E"W   ~ !$9B] Xۘ~L9xSov8#  Kt(ppWW e_ )[[Q@@ QQRBB   '3 & . #As #    gnu Wu %#  W]*nJ "8SUU ( $&0if @:&0F88 cOO  N@ F!.4$ + JX/"   5  m'ObnMMt   $@]YcYGLR[0#$ *05# ( &7ӀR`kjj 1/ĻC;&O/OAM & %(.  LuY;FRԾ.26""y --" 4455T#>ۡ uv  8=*2: {bG{|˃򻻻fff     MP%*8/   cRK-"5$ "*cccCCCBBB+++  K $>;:dX  < X^B@G"*''''''YYY(((&&&^EA:(bO (bO ޴  D'  ))+BU8ĽAO1ϩ'J+Vg"87'@G999UAuuu[D G؞(b  17iͧ, AB`ͬ4Q_ 6R @-Io 31'0bKLLL888* H6f*UO(bA:(bI(b(C9z(b(? a՞@+ DX*5  \i G!V_  -2 2sV /O Gڡz&_E %B Gڡz&_&h0pM Gڡz&_E Q1CxSzBzp&h0pMgyٗ $34   .[@* a' 4N>6  <駡MQ 8?ccUQB'L{ȃ8}E{ȃ8}E{ȃ8}q|Ht;Ls+!k  # ^&&"!  ^p+  !ø;3 KL'!:9 !Y_A" 9 3B " 9" 9?\t0 8wO.Bl7l: 9n9n: 4.GB#IJ _k=@+ah  /"_e1XXXXOX G\\G! *  36gd&[    txyޣ. gƖaʓ$؁d   AB/GT/~|h  T-J0"H y_%eWC  ~9@48#џ]_+ t|    .6& &0g~$xh}! bp.U@#/,       Ю0$+߅k-\\#|\X!,),' '''$PM+*aX-  :'qi:{1zn繴( "E5)p'Q Q0=8@)ma {2J:  %<     .E@ 'wE|  K> 8U  [nLݓH 'S7#mԿ   .x/,R/,06Ŏ =,Nq;<&c9' ̴jr |Xz}~Qf.7I u _i-1) ,e,v[sx*֨$9v[eOM[i\t0r9-٦ sM.jCs64, TvT޿\Nz,&= :7mdI' !n5̽912mVo&= :7mdI' #@0 +.edU &= :7mdI'  ׷ 2?RqRϽ8: /kY|唈!n5$4{mo=0ﲰ HYϽ8: /kY|唈!n5  $A$A.Ow줞ri #ЂJ{MN: ЂJ{MN: ЂJ{MN:.|.ۍVl ce STh&};㖈d/ ce o܏Y|:<4 Ѩ _!2#߼&& 5Cbyuu&֥%2#߼&& 2#߼&& xU2RP7 G0Dl'tco|/(ڰ}S^^ 0Dl'tco|/(ڰ}S^^ 9q"@z^@z'@*%O%O G`G :r:2o[o'@*%O%O G`G G`G'@*%O%O$::QrQ,o.,c, G`G(}(,o.,c, G`G8'  ) T*    3'#     ݡ'l&f       %/"+ ׎ۙ$Tj     %    1  cSE9  ><| Fo(z T.tXOWL%    "\7  z 'Tdz/*6oE 7"f8.ݎ %=("        81 լx+T x5% J"} c8W0  # 032  HHHNLJHGEʞ 6bJ"o"3&A#   }>NRȾ   zôc(e7?#ߴ"*& #')"!RQQCDC LOJ#'* ˺36b0 b0bgx85.]]jHOVBCE $[4g, ^6a5 $0 $  ###""$ !    Oiyb2Ձ/ $%M _؎C "%ǯ(0:;YF"wS{Vqm_6Q,     $!! ###MJM!" LLN  ﭢhrsNZdNq+V@(&'%kmW 캻&(+" ,'pu}   #~ pUS1j;   #%  222  ')*  hrs7!fa{2 S N=-  .+&MK4*<;"  ( y ڤ/X҂555 2[y B!    *+) + """ / i`D)pi$ >! ⼨;;%!!薾 JJJC&     " [Po6$7Cm={, {C"6J5G>_HDWuO@*("vcOqkURA.WgSp{Jܽe ;fvu~>$$?7ܙ  3_F lF3   cg d&X~ A #!_<@p( A y`OfQQ%aaa cۓ      Xrܗ|B ]KvfٜKڸWRe&g1 \YW\YW#2rK19JJQQackRA-Wn^^K: B  '97+,  䞞3Z& oZ@ T< ! m A=~DI,;=OHiG]pW? q`Oۮ(hA,(A  *a      %2"PW #1RKNOU(+78[F$LA/sb )Aq  H3jK (  {ǝ1):"3@_^Y tоz '/56>EbgmE+oN 33CL{*gXaf33CL{*gXafOKY  ra6B#     :k2 wS0Ł'DN"_y_bJk61 @ܑrt\qxZ80$Cw)b " 0&  " D-r 9> M% - aFK7kbP D8}Whh9GS9GS_ $𞘒  P " \:@km]fkyA6R"5LjI6v]fkyA6R"5LjI6A -eQWA y`O $  #捛.y<        -0  8< #5-v0zV*q2L80w[[[&t}-> !! _T& ~; Ro@ Ew,CP$=:S y1벥@GN(.5#  q`O y`Oۮ%XqN;(A!! kL 1 ,<5d[".)/aGMY'# (8Ǥ9\x $6qQ)?=,?=,=0@S%CEBD7 q+z7F¸\G , R`$CE=mw- ֶJJJ}wp _nz  C$U$2EM{*gSag6U$2EM{*gSag6S.?&!{=cC5{=cC5  'xY    3( % (89\x 0-%RAH{03 NR_lN'*, H[Q:ɗyq~杞'w0ۘ?l9652P9 $;ȫ|b7 &q  gTC8ZozDV>i#۶~=}\ y`Oh& '476h& '476\ \ {-% 8(%,';A %16  /$##>LLX[Bֽ*H3 gc3 &:%%% (((!!!@M%4Au%3"=M[(2 :+ zY&JY$) ,/Vui6",910/ MU = v.9X(E@oE0DV>j 1e]T1՜*IBo?) 63i,8gxif{nT IU0 %)IU0 %)   ' lfx6 $  6 (JP( Qp  &u+Wn/lr *Q#<; qa(  ^^^000@@@+BZ邃Y!) L%h#%ز畓 @VCQ] QY >ɫYAc{d-׃*)؁jzh5V͸okmTȥ0r)1ً:Yxa8S@ֱT( ݄5"/K>E A.$Y6;i% lbd䜝CG 58 _X(    %7ZZZKKK2t}r*** )5((l Џҫ>?;>Qb %+%I ! =)OlO G4Hoooo .4;  8?D5$(' 噍Vq6b<ɾ"h͢V. %9U79^:4+ ,VΦS,& ͟87Ze>)e2 q`OpLk#(jj%SSx)~!kzvlB{ #67- F'|XAf@ Gv#(C?Fj_ f C]c |D8& 48[a&VZH    (>do88tttKKK[[[xip+h+!5GG##v  eMA#÷80*6( "IHH  4 4O{{;CL-Xqxsi"J,- %I%5-e|r4VC 8CEѵ8`7  0823:Ԫ1Y ܟ9wn Bc!EWmZ( QG6.G3W..kL8se44   1*"  xA  )Wx[E1 %+(.   88mmW>{jy}h{ !"TCTmW>ITέ6_B!   0"cni] %%--%O% ͟pW[HVc''02r̪V>j0  (}pƙ` 2Q>Yj7.5*Ә?ux)GQ?,–E #:/LAи˲$ &/ N"*H\&q`vq%)45"FW;W+AdT x\NNNFFF   ?@ $oO !    )#-i9 I6 B<  =bz--- W,W,Z^0.] / 4?I3BS~gY$^],v !% 4()#22(9  +e[PΚ5L7#$ɵif3ٝP\$J] Ƌ ,)f98[ A y`OA y`O+ŨŨ,A@hh  㝝GGG  x} -s<     +GTC#   0566ļ^D]""ZZ*_֡k55V'NO(O==(:9::} @yyWWW 9_ 2K%.88_/=TSUɮӽ%@Q  #oxXGfXG(x(?,?,= WdGBC,ל\SHA y`O(A(A䝝FFF ) t    /@" RZ '&      6,6;;C""^^rmnZ'֡k@@iϹ1G55>ȑvvoOÁ*ZZ}̢@o|xD@K ͪ  ){w{pi58<|n s+mH8&mYVDV>j0 DV>j0 9U9U$6Bc!ĵ CTfk1ŷ I[ W5bK M5쥽8'8C.(A wWط Y@N,AP y`OA x]1͒Ҩ^@K. 쥽8'8C.(мz3!1I;D A x]1͒Ҩ^@K. &bLP 2J4O䞞FFF  #% 嘔!  ф7G}Ƕ52    2A$$$^^{Y'- @@3i1G g6mS1uZ K14to7DsLLL6( aFXN@5M0N1OOyJJcXkĻ LYe6DV>j/ ݝS D^`N հa0 LsDVS|)%e~*4 *4 *4 6C !)BSq9 ̠#!Uc i)Ȱr[vk#Ф/.TV[CDVr[vk#DVr[vk#(E@oE0 "ayfh]r%?g2Ŀ.K8ibo&ZP/AZr+T+jh]r%?g2Ŀ.K8炰kkDGAZr+T+;J;J)>*?(N(\ \ XXX LLL  ĻBPBN\-&  0H ;=   (M\K&Kv, WWWW= Rc21RE* ;! cL2|N tB Qf_3&,Q,} OȊ(p               –E >j0 2\`D+LL( q[wp"7T54.V^b咄Txv#1dX1dW졈LMwZt%U^a咄Txv#U^a咄Txv#׃*)ׁiyh5WApq`O[yC4Eݨʽ{p8pq`OApq`Of&jJ F!u_S FbZ} \ \ \ZZZ򴴴>>>0"񽽽 LLL AI%'  bZrƶ     ;;   :SW!!ܴLLL000 :;8;"I$l1:f]Ea)Q9m:X>fXX >j/ (|~)Q]Gf3/4, +TΧT, */$ # ߗ> &Y2$#awJ4c?3:խ0W 4R_k8c⯘Is#̼2Rvl& 8CEѵ8a8 P y`O NPqIV3X`sEg`pOg?ŝAT%`L SY20kJ6 4 4SY20c"SY20kJ6l UScwѤ!0[-]Zz]ĎϷJ ,(fCD? 5c/룽 80QD/*lo9úЬ( y`O 5c/룽 80QD/*kf|Gսj1 y`Okf|Gսj1 y`O*YzƼO4"+cJ>AM t'hFii{ \ k/Sk4 t'hFl$bHfk/Sk4 ZZZYYY    4 C&  %- (  (9Ro$$$$$$ᤓ%zO 6PPP*?`qzsn(ZZRR6">f< –E >j0 w2's׸f5x!>U*$邍T #ADK83ȑǎp: (E=dE ?c!qS ,LHjl&` (}př_ 2Q>Yi6-9]#pZ>j0  q`O/n GmW$x2%19%H  k)̾C{E:T k)"k)-M 82F2F^I\^I((OAWOA(^I\^I$+G+G$+G+G&?&?(2k? z` z&&s2k?}\ z&&s  ,/%&        z#$,,þ !  'cnw4,]:sQn  "Yˁp]\nݾA%NKN2@777³|{nU0̄q[pKXcwtsB4(½ ""#0$  Ls66*IIEtQ9xc9x Ms Ls8DD9V Ls LsMs Ls 2=t=t -;w;w=edSaT<>5N.PgD5/bRnp.\1 3e    !}U n.( "( 4 {m$ !%!3̹xy  #B]#K+&/8 qIF/?3&o]J]JsYt*AA!B4%DHD2 P y`Ow Qn!%mEKfU.,|Ia:!Nl\$e@Dr mS©- ,$5DK@BNj?柶 0 *g97[#[[a y`Opb-{ Vtt&WO Vtt&W"_ "_ kb_8    g7 4^   N_B?% $   0:I   r5...Ir #*V8]=<kC1* H f  2     $ Ls( TTrTBLo&A-A%>%>x((x(TCYTCHx+(x((x(Ox((x(dJ\dJ 9o9{)[ H@A\ H@A\^ ^ 9/d Ҋ    1Kd> !*  /5tY      7.e"_:...#)H/hE >  N?eg@{1 % *"AlӅ**(x(44DDdd XX dd::::33   XG)+2U  (~X $0/#   Q5a@  8   N=n  k~>6#ސY%ԃ.. **##ﰰ  bQ  bP+i.#MO     LG? @H%   4Xb/)s   J6T  Ff*& kW>  // ~|!MOH __0''6**WW-$$9--˗ jtlg ) "@'aB5("   '@' hw, :;5 Y`Y DXIS   D> V_E  ٨ Xj KKvx ty@DJNebD;3 ջgԴ 4i| cc  bNNbNN sgKNLKO10!  H/  ' C)-F#( )4 a $  )))N^K  AQCM ۈKT 6%n,,  D;3 2)&??9 ְvzyN[g<40<40**  FHbސ)   Ћ xw! QA"77  E1B"h/$ !  6:Dac]]ZcD+    nn55L " #,3!!N46#DjF*J/.25ż 996 '  h]7 #   %(0+ " 0HO8 !ƽW_a   "! m2 aSf  鿱-4;5>F&2< dfSMMg@""#    '...  Ӓ0C- %'.++! "*+%  LO,++"\%#,   o9w O--.  s %  hH꼭kBF!#&!r "pgVPP   5' _2  GGG AAAA>>#)* B@:&       |;  Ϳ JĒc).H*F)ŸhGh"'ZfL j:8»(/5/6<4@I ?<?a԰sHCWw' +#  ȿ6( _F <ߘjjll(( ٺ      : כTb_ $8oJUo e, 4I@Ņ=We&vR_i 5AJbháh""" -""""""h!hh!h**44+++;;; 88{~^A ̧r3f"(- y@JR *y `qci BIC5) &+ $$Z(((      Ζ3& ;WZjx,Fcw21 "G44PlllFFFB1 &&&&&&         ſ )6/-     D@4D@4Q9 >= ( 1 ______ ###ڑ///qqq222AAA(b:ثO A(b:ثO A(b:ثO  ܿ  8'9U" 1 +6/ѾCN 8/ 'B6 6:/G`A   )($#!)-&&& &&& WWWaaa=, A0  GA(b $^9 :j+֦N7O2  ҺAE+м Jd ᯯOb 'AǯL]={.~ȠVr =;3 ______aI aIό+++uuu???>. P< Ⳝ".8Kfc_V2 'CXrgB!A(b9G:ثO mhAyK 'CXrgB!A(b7;8`xL 'CXrgB!WCl@c%ߴ}}!,=dvs?A(b9G:ثOA(b7;8`xLߴ}}!,=dvs?  '(*66"'') 8J=8$2  2$̸*@L *(42-111rU㭭fffVVV###V2XZKκF Ɂ,fy3# Ո9[^nw.pA"L9m+]Z*ņzɁ,fy3# Ո9[^nw.˙sc׾oǗMEɍ< Ɂ,fy3# Ո9[^nw.x7PEޛW!i8K_ƀ<]{Z{*ݷd"pA"˙sc׾oǗMEɍ< i8K_ƀ<]{Z{*ݷd"  )@7O"5/4 0!, Q  $ǵ$ EE5#<=& !Ie  '*EF3Td$   1 ?=~y)(  2pppppp =̹mAmYB ucu .8kE۵3ygEN9nucu .8~f;30ucu .ؕ ϗc:ֹd" 8kE8~f;30ϗc:ֹd" Hr$ "3'½poO2;A  #% 懐ig`{a`97 "ER,JJA    *(xt DA  .`b#Zfa&Ĉ?]q{`BF]=ZrKjD%K)͉]=ZrKjD]=ZrKjD:ЂPDSܚJ 1fD NP- м  1fD NP- м ;ˏD\%   %:>1  #1cZ 6B   *-" ZZ9ܮ1&$E>  __;  #-o77XW f`87  2 :|򟥓_+MK^}sZ5 :!p}|}c=ql$jiഡ΁h>q :!p}|}c=q :!p}|}c=q)9VeQۭ_!Mƃ93w,3Hfkt= Mƃ93w,3Hfkt= )8|y@ y:ثO   J1 ++17 :   32      k^   (/0Ny0NyCCyV GH{{~VCCyVGGCCyV G;?x?x G GG?x?xLsLs  $V_69@.qpx⎟GC&uo@K.26,ZP5&np 0).     +3p|lXl*Pm^@© ĆK9@B>92 晥m:nw%52עj"鸿4&     ~t%DZ JG {# m`|n   [KI3/~3mO& `8`?1        ) #  '81 2+-pVh0 С%*&Aır! \bNr7de;D@6kkG[c<VO+(@c(0!>- M!zt) 3+cj  Hxvgn G2>R˓BTY#pkKSC"3PN2  , " 8 :'8  {cQќ~& n# x   . oPK.+]Q %%@~C #$*1 <         &?[9     17@A .]3t 9C^, Uۣώ ! "-%]%]ֱ ;`4(70.aª,C`%5Y #JyJy  &)#7J]?--<<nKIENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_countertimer.png0000644000234100017500000226203412174204305030433 0ustar cpascualcpascual00000000000000PNG  IHDRZ+/ pHYsW cIDATx>f31Z9;&5թZ! My79JI/1OÀ/1O11[BulslYc%;3;3lo$d%% 5G f3 T*S'ԀNKRssq+@` `)/fV!I =:= c`WNtLmx "("*.'aoLH@a 0-cV2  !!Ɛ-! e7 eeeeQcb읉m)Ӻȩc`|nz~-g،t<OCo PٔN  ܘ''SPK3:[+O~YS{ضc}̲672+5C~t<of^~2c8LA#JJJ8;[+{jvRTVo2Cd-~fnļ^cV'+9٨BKB//';\UŤ;GQ'$-4 f8?2t_ !Y6jvbRRR7 ¹`iɶe?] hf|ֵrt{'566*||ǎr9r=H=|DʋŻ/9B f3T*if2 8ۺ6fPG XXX_`uarz~ %7$, 2#eZGepZ`j d\qҿ||Wq;))w ?g9+g9 q~s!xm" 0 f3A `%FfybIeybfRRRRwd_51m[lv ĒyT ։XC?MQ  eeNN6=>E!&,a, [et6N6P'wt)z2錋Ź2>I0 Ƽ"f\. KK=;0NT-WKOڳ*W_g4@KTS*TTTzuO AQ񑓒x &MU& *5/aO0P(A+pomO }mtm{xmrnf3M}ݷ}э9.!nэ9wXl}%U_~[ wwr% ~fuG++}{j}{f3f3L6_b5&&(;9-e[YV65 (j"1 ه0).yxHRo#!-0%PU`2ڶ_cl6@J['6BY4ge7 eeeetItzIS|~ CLSo]Ge&"v~QQQ000[YYhQ[-S S7yufQQytuuttPQo]Yq ݆ f#_bi*(5 e[FJ@Ը?rYeVgS f3J%f:yx{j8wR he^HKZDNbwqV$Ƽ  )27X` zQ:RN\$0Q 8 uxaoR3T"ztZRRRQUnor圛)9;ixw(304?9ɤOڋuu  AA f3 f3sgf& U8f`OOfff ,".6ͣ 㴺8|s8;NYdv $6:OOuF %x  L|P]5ʃ$!mѢHhq: C~WJ2f3yXF\XFwo.fQQuy`yd fgRR28NԜ3?ٷ[]c #Zn78;6}s@ Ax`u`OVRRffff3ɳ&1ؚYa   Kb`aK8=F&-.QbYc@:ʾ"RQ!o$;t Uړ0 UUx`x`OXXl..1]a^ NO4|)3;yeZ^g;3( syLq:^``a gı "* +3eefeeOtr03HпLn{ή}G<8(>-: hT7_;  22tt%-e7  @!'A8PU[gs:\ 鳸`c"6BXb ccc GAUR4-@ºKFyl8Cc8C_g$ 0EBb؞(/U~  *'uuGC$??z|f3ٚ@&^V@\R[QR'"V@գfCh# GQ=O G'f[yG+].]>(f3 6QQD VH^̻''( hw HL>,,,B=@G@:4:>+2ã$  2602!%hU4KYsSI? *y VHY5-5-ahe|J`e !n1L' ?WFɝssx18<ֲ#(B?Ho   nǼQ]v㮩2(&1'*MMKw}  Nfl ףE aڝYLE#+e8ywfQQeeLLQ8=78=7==G14G̵ jeJ"B@0 MLJvUfch3D JVt]dw $?RLW(;7WWUcDA޳kI9 N Г1zz&5M||oo*ɒj|yw2; \,`yHofofOļ_^bFϺc`ZMIW*F@;8+[RD 7'/ 1Dc4Cc!D~$*夣sxt ٠v:L>4445+{yvvuEuƻ%2=*&_7IUb 96 ,Q)sT{%=tnZOAx`x`W ayf`O, n*RRw w]]SFHaFMQ@G\>),A?Jsk)( =Qb򆠻mcZfq58@ 򶾹$7;PPPYYWWV?}}//[~:'4?;IL?if300fDV>ȸn;Wsiȸ0 Hl$ä=\洡L_%uZx`OOx`W u{yOЮhzOORЮhHGG9fffEEGOQh*AyͥXQANDY! #+hvų"#*!!`dw5;5熐,?CWWr// kk06:=ٵQ f8 Q}_6g9I'sE s-=\L_Ax`APe-BnC!' d|fxW w)R0RxPyOPyO)R0R ,CjZZRZRRTRfff f3EEihhr%'vU^Rniu0)- goqW_hk`TIJJ,6XQxe+;&! $$$BBB)28 E(_Esi! < ~.  \. ۭ7\ fQQF8833 LKj'&(~}~xfaG id"7EfVSB$nSXȖqMVW OX#OXaJh0gJ e7 7\Q,(<jef%!79J@}}{hp+3=,7BTmo{momM 222hg 0:@;tذҐ(؞*bH3aAH1w? 6Ufde 1J@As"TOpnoeNPOýBBBBBB܈xxX]Wf3;WWpq"++\b_[hzWW N$݃N!}羢gN!}B& ;YW XU"ūybzYWB-\ 1bB( Ӟ}hV췵m- &_hV B% Y %  -b}b|`\ZG' |{' Y8{' <*06<7=Z[_4c b   v   mpuv*ղ .CeEq>645  ~|]_v ''%0)*FM> O (% " ?AK+!%(+s# 񫠡e  xy snr C?3he\E ++. wlSej0?;6'خWoet325ξ}FIhOG, W7n4/"RVSj"j[XN*$]]]1e7 ""  ¼OKL:4Dě_ 򝘂gih$2KH7#2ޅ!w'"1ƼVDR=W ":?P4=G$%-615EC/zpb[oEZn =LK\1 AZJ$+5meZY^{/  52KYmo" `WZ=?1 B/ re ҧm-   1{ 5jw(5jwAPTuMF4IRcO[aZ\o`ew{w`"'DfbgQvw[cm{87&bS6|~idY\SCfvǂBAOblmFFD')(z~ ]W121.{kix>f3n;Ws+j0 x` \,tc`D[7ow-{dow-ӀS\ ACUgij񃒭x|622.0=|qAN]eD:C%s~͋ t;22JǬiaaJJ`B( tca^&@ `J0 Tb zRt RSt)TV6103$ ?AEV`v ɺzпXE],(û08:ʻ^ctG=$zwr #*0nno      ?>2# 9Z'(A/:Ī'u|.t}(|$|~|$|~kfMJ 0307111KY]1(07aG кBMV  98f336f3/ gf6aYdDx6t}ʽ6C EVfgf3kt  IIIZ]?&'$84D-Bb_N~v,CE 2 +Ex-0/HKd&037;C)gj~|ŴS_[B<WWJJUWS[[[  ii f30 \(9Vi &cQ> 0 lRPRAAA8gH  򶶶JJJposBGX菏ORVm `^ (+D+A-0"  \ixhvx ?QUWWJJ&**awC򉽉D!,3f8 f: K8 tf3_g8c(pvfʽ6C L^=a yNAyP=AA *vVAyO.8fgf3g俿AAA"tsv?$llnIL8A>< '|apxLNe[em %]ev# 厠r`\  &F  .T 5%, >ȸf8 f'f Pg84ꧦ0*5up^qڙ'k 'G PAx`6C L^<XA(@<Cff3 \\ AAA;63BKi`f^}uqEWOӸ -/?FJ Ŭ1.BX㢠Y[b YTW" ggg;;;]  lH ~: P5$\_`E(Bh׫9\ :Y!mLG<?%<[-[-DlR\\ R\fff<*ZZZ442-.Aҽ188ݻ$ϩSUh   ܷ{y"=oz~609 $@&Y8$6 úBOZȸ."  Lȸ/ 0/ Ŵs"-'{i,wbhO.AlA%SS%SS[\ ZZZ5:4NJgFEL=X]IJOľ9NFFLLjt /6;FPTR;IJ @3-]=W5*2\K @kAtJ  7n[{@5 =7@ sx`(x(O` R` R R23.*'*8߰>MVznTW\؍*0~JJJ HQDͷKSbñŐ>ITieef"9>.# 6DgnfM{١h /,F&gx"%{&oꉫؑ 6 EOjuymwa/23Y_s (,%76MB٬yyOV8_T@P+}z7ȆhhkkeeG88eefQQ h[;UUUr115/5C̽VYwtplID>#=>;>>H'h>"8 (A>3 NGOX"8C# :ڇ~#(+nPM$  ER^  cOOfQQWZo!'=IY{g\^[as|wuе-3:L_e U9% (f^qرPQs!gf ,04NN TTT *(!3rps겶zzz0,D9=P ~rWƹctsǿ }v~ JiDAIw^B"!)//b8=QvvBBBȳnx~ m%/@Ijb[H\iY}| WYcc A- 5bddQ214z{xSWV4-+-2=IYe V]M;lL!)EEfffMMMliU}x|~???BFX%-:뾷LS!)v%,  *td-bP(*t֌B*tq'&~ڂ;a[+؞*bH}9z@}}aaad752LSNNN gؙTbddO !gؙTb@gؙTbqf`7ҔkAP(Ux ;WU29O99.k GOywxz^^222$! xsyCHB~|EEEEEE}~|f3ef^ lOaYU`PE`40Uy`_kiP ^y60l 4V8d _ki<0砾`DZ@ ._CPC瞼bD`DZ@ ._Cs)`JY 5>4/.\JY>0^bb  A89EZ=j  A89&[@-Yx`6}4 9)G' G''xbT5 G'[T5 G'<* T*tPd R;  so~ <:E >#'O{b|ҵ !O      ~JN+   +*&MF@w  Ԭ# 3  <% ckhCNX] -Pn 䱈4B=F`u :x     qC\3?>FkgdX\_  JIW%$nq\Yd TS]')zmz 1' ģ:#6I⧢G>A/"Ȼ./ ؤxX;0K?@IDJ҂ ?OxF`u  "VPF 󑧷uϰqk +r      b= m<S+I$ nimPVVJFG+++0/9ث@AG 6 ''~"$>=@VZZ24)R^r >1(̷PU`[]` '"{pKP\KStbj!/̵VNYgnhsm84%$$$ at}C,$OPVD" &,eE,$:V+:=   "*=\xS0^6 ee__}(})652NNN+++U[MQhklaLPXDFp>Q$$<0,d`o'(;gm`03>\_pbpûz6cɱ9gIGJ950xwu$X5i{V< rhvԩ VVVZGG\II,,؃؆333hlkab~ JIEEE`ftWc{jt ͟VZsѶ%     S[v1:7 @M*ƣei+4?"6.SWaܕȼ%(+ xͮ!GN8& ciLtCCQziol{v/;4  ޲dIGB2^MEs fls LpoR5 QS*iW= hN)5L&L Rb'1  1Fۧ6|6=n56|6=uZ`I(\S$ApyOxxxMVoUM[z guǸ1-"fl 56G3 ,>? +.   N疖f`i)9%4,<vTZb0/'"(莙ҽˇ#!Cf)D[SFLFjflOQQvB[0 00$ƁjPQQa~hI;791RF+R+^?T 57H`e&Vgqkqxkn $9=% ]TD6 \R jjhNMd'/;%!!20)  {SlqMFWIJJ ),=  2z267y@ol8 KWpSgQ   ne`56t3*!$)!ѹ27=;U?t ```ca9 푕뉋4BA31* %%ZZjj *)b15StGD#`Ax`zU3{*zU3{*|FQyO\He_FR \R f\=hsR Rolf\=hs9;K7:E̽0/<Ŀ$&( FGJ* exÔy#$(ZQQE=J!+";4RR$&5|q]dQ)`K eͮ |      @әbWLFEMJKƽ] O +#ª7JVJq zzzccȫHU`bBƼ~xsTlw7!ہzx "+d2 R) Fs^z|k3{U·f3=L)3 3_f ,3;T(OA~|C6(F\-)?+6 ɼ7D ((oxoxlu % 3e {F ~\qs58qs ŵIGN)/0Ѽ]^_xcab  ze^cfhbfz  2#!⤢"cr# )1+2v/9D"," 9    WX\ "Vco s}½ h!rzȱ#v{gGRddNH,7A 00 NI H/$+16& z/ L&`0 T* Y,'jÇ·s"gôôd%%alDÿC<6 O7 #\-8ŷPd3M4sy7vJlz VRu%R\u%NNNIIICB@%(16FM".PR[  #ůGN ,>4hm1#  & .( 3K;in   /1" 01,yCPY STL  '*nnNnnI-gJчyy~uOz &ŋ+16ځ)]bf #TJU+f3AVVVqRz)d}lDC=A; \,~`(Ovg1(Oxl|oApyOApyOApyOdd XX3 3 㚚JJJ IF#$2íMNR) y+,3(.UZ' ⥊nm ܼ 7 HMM  gpX^e KRd1C5nnI##ƅ@-(IJy$$$iMhKE5z%4' 1# 0# FG fDǷu8 w㮌F'gEǷ8 C0 `0ff.: ³>Mo~~}|7A(VX*~~p-}-A(VX*f . åg>U&&*sw~)>W465(+%xum(\c^! EIHϩfo߷0ciu   .@D6H@x|99 #@:*G""aE bП'(`C E}˕8 2@8 \!5StfGŴܯsAŴ9 :88 DE :88 D0f>fg^͚Ax`.: >M&l"Q*  ӀQ* .}\\\fff󧧧NNN<* ZZZac` %'F:MHŸ177 . ?SR  hkb O6@Nhe|yXJ{ccc R RffDJO}yg.kE[os4E Fs^z|k3{Uk닊Y*  /6ӲE)55KN0qOAx`Ao7*v]vlh 68؄%|退~(({~ww y|sKBRlB\sKB|c!\ ffffff;Ch24AŸhkj jjtŴ$>ZXV&)'#"[_z) +97=GQ"%'c &$&. ccDCTT^ߢ_`] CH]-*;nnnsqoனcx fa^!/bWPŹUYbީ.7Mgy 2 edlcs j8SL/&.  JYR޹WS(=+64 7!.46Ȥ vp*Hh:lʶBLZ"#*/    98iH()+&''% ^_WXYR媥RYn;GGƾ$:8MUb"'R£)-'WLS| AHFD2{(IQ^<>K . Rr-mS'!' 33@693 Cy2KQ]###3  +Fn $) ,6> D9  ]DR) PPP KKkkkޮ % $('}~Ȗwmnj zw ?[ksl^`nе1^Uż>OY~x"vtz *v@GY," M6 I2PCO%uQ+Yft.:C.8@DP l0=NNNP666000CC;32 􉁆usos697ddbGHH\au[ji}gYf{zsza`^qpY465>Sp R#ڌJ6!8&9'l{$Q_l =<!) $qEqqq jJVVVlov􍌑jmlZ`s jsKؼ.0I9:LpBClL*0&ffffffHHHBBBXXX|g (bO A:A:BB@((( y169@B@t%:I|g_>=#-4!!!x%7Oa~g^K3 Iܜ(bpb, P^K3 IU(b;<^K3 IܜC"I NٗA)(b;GNf(3037]# r +"Q     k  ccWccWc_`*(&þ /K5ֽʋBHN ##  ,+ ) )  #V HaPK+F@%A8;  B!&  kxmoP|I!mdRHs֬$-x P      e  n ιNPUfk]_v 79O &)(%  fs_A2p  248B PH){$(444\\@?:tČcW>2s      i IEF    B<<  ~t:9E57=!  (=  '*8 %#+  "ݦ -5>)8`DLZVLoTDCoz_nxèN,Vmh8D6$**557oooӽLrR( c<@?:0 Sq{  x      gooomhc$).N' """@>? $&'@?EJIQӨqs{#(.ý013 /024=J&    MMA[]j dc,*5 MMM  +1@25*?3$󏴝35k˕ηz7,"RKHKHč 41-K# MĬ>/TTT((==RR\\P?B?$&#հ - ms#*)!& 7Cf-5J  ,gpwvyɿtx~Ⱥ(38F "jt}fhgBo. A2 0˕!`:79!M;1nehFWYLD@%+wwwN=tU>k )((+--ᝥLHJGHJG@@@bb~οu|B 3:@=0=@7)' ) #  SN7EPFa[[@7DNOFL_n/96*.88㖔}ݦĽ&FNY㥬$(ԞzHG_...v%9mJDsþǷ%9I#D<%RB?  wĀ<8  t*( 4˶#W(BPx^`E e ך# V t"ЎȨWl +4C4J|1WabljabljKJO-$%,BE7*>7*յ [~?tEx t2$ nɘ]W C4KCLW'2:W'2:IyOͺ#(qrmwxu")K46Dª⏇RVf93<53#s]cq𚧠xm$gf  ћ!D6@h9?)($ÿ1,. 8.3;ʷ23@EHW(0,.5ľ?MV3318F 0""wζvRp000̀]@Z MxCNZ[lO!eˮ  ooXUUZgs B(\2;-\2;-C4J6K`G8PH.`G8PH.@@@7< %ꍏ54C`]p rsxq{(/ȯ<Ei᠖ۑ! oz Ү ώ $(tfff`_dF |2[2vf>AՐhkd!Va&df/+il(!ؕ]77zzddfO*4Oʌ: )I%N'X\t^_lnX\t^_ln#a`͸;̞]ysW=3̞]ysW=3  )(2twp nof@AH97C ½1I;   38FRUN()#ثMRP˟)%2!$'/2/qRZi0z0AƸ:Hd8%::GG;;,,]OA J"%gS_)msA66GUa(Z- ˌ{PVlDV>ȸ(Ocmcmo|P"!{zh~gF3Kh~gF3Kv)R \jkf_ak*PMS䠢Z^w$ wYZv)#-+XXi *+Cö. ϻd0ICyDQd0?L ZXs,,,NK6104_cdqlW ӳʱ[DYdsr YEP:HdMBLm5X?KVq? '`OPnnooEOXȿ! ]4!E#nv, fDǷyOR \ ijelll $nmg!2UQI/**zw} UWl#$8CThଧgpFyxF}    92 $$$4=:RP4梚iY\W# s;*4#^]GG//@@~J(& '-.1fbTy h `0|M $ w?!]rUW:Epw?!]rUW:Ep*q\R\fr;\\ wRR\iwREHT#WRL/93#}YZ^ 9:J  GDB1& .7Qŗy&..`!    )&/  Y^wycay>Jb!djv !" dcm*,77 jj&&г蘀eWW`T2 ϞB.ЛSS2 2HG,!\D+MoOر(O 5cE7Q4 5cE7Q4U9+ `Z}Y m9 R Sbk \c`f|SbkVXz!%*hhh}|2:?4E5RM;:743>Ԥ/08ɺw| 'aj|GHZ     lu~mNruyZYWɽpE333!!-QJR((??? LI,'- &&+V3Ǽ%,1!ypxwv00 ss ȡ #6  -zsbW_  ''? XG`,!."  "  s}Vbw>ENREGV    '!ĽAAFeuqvp)+lQ`I$I"Hš>833<<5 1113 ##<<ҳ $BNX+0 f3 \." :H!N!)fU=\t^_lnjX*Q<#m`BNjj0);WEֳf ayO` ` `+gHDD??G bbb£37X31:Ͼadk PWWcck0'>'! @KLÿ@C=˷BFa*(J46: & )+$125a`h#*  mu!=B  oKW <>33<<5 ڵK&Kn333f]""gb~JQU8 3Y,\.Ov'+5O6D 0; %>x>cmu{x`s}dJ\dJx` 4A ̿Zpa ((Ee2gbbb#45OOO+69,> )#!C*3 %"! ꂁ`ww'-+(  ~|Y]k  V^k61-9* ~ ''RRV&&ڴL&LA&AK&KnvvcccwTSkvRJ 48 j0 ˌ{P9 C0 gEǷ 0c1 \s 2> fayd`{{5A;5_^x"A ` {F{5tT  `Ocf ħf3 fff66`1/=\]Z|rs!=@ % (4! EQS Ч7yen߹:Q=-09İdak?AX   dlfcVj<<<~/0''V&& 2A1A  Ʀ""ZM!+ 6( /" + j0 nv,Bc!*4 "+Pe~b?Ps0 Ϡh6\ sJ`?Ps0 Ϡh6wh|nBBSf3 WWWeee &VUZ2B@KLNŖ}GXY2D(+ 2ǹ ˻i_i27> '?A,33 kHg^ס11  ::ZEly7 L7 P ,oq(gEVfx V+ |M $ krgnG2 ;)nK6 fDVd;sfDVd;DhV|wSoyOر(O6X h& '46o)h& '46 3? &9ZR R R ZZZXXXȵ%2V'GABɺ>NP//2$"   qs`ow)mXE 6:G7:A !" ))) fzƘ33NNG))n Z8%r( .3!2hd~UW&0 -ԗ:/65$pGrh65$pG~Cd_X # (ر(O(OwP2}aIX0 +IX0 +  S9t+ ZRRZZZffff3XXX333 ' $&3XXWʜ48& gbd~ 'Ig  WbԸMKZǴ11G   %11!"hlqahm &/+_]^ڻZOSaaxNNmmmՓœh?e*3ԕ%=59B M +n9  yر(OSO!.X'SxelĬ@ADS$ !A Nylbdmza  `lbdmza ` `cbtf `r \\\ Rl| Rl ZZZXXX//-GLl 騞@EG6NT B``-5A/2; ?8+   #(ſ,;> ',BǴlz|ĸzvvX`l 477# AADç  ˽,1[9;777...{{{C" $>,Fh>l4xqD0ܛ9ץe\*/.9PhSLŐ<{+ =V Z"+).'2`r5EjnL7!Ac{((((퀀퀀 ((RR R RRYYY;:= $HPTIED+"DC5;      )!"+LJVw$*< Zi% Y]]ȶ77G ʻefo?:6 (-28&W:DQ>D gx9UO`3 `f 'sh`>2 2"0s1GyLL LLM LLMMFznL e Re775##FFHnps-A5@ƴ"7# 20'MNC0AC CCCddbǻƶ+-0[\[Tu~Ԍ\B)PXĹ5AMZ 5-]$)757!% M. '!(3A& LL(O(O(OOx`Oliex`^RPb Rpi pi FR NNN)))HJ)WV\ +zHJN̳)52F/%  xZ GHXNKNyvtmwֵ`qy (QIawnXbl*?K礡,@ 3#,ⳳ Ӊb3 B '4? M}` 5,Eй/X52?q XX22hh '*/ 8BC]cqVht\Zd˺2HQ"  ,;>>AAxmy񷳬333RTS9I?AAA~ *HJ&34N5!NW7 +.? L!')쩿m!.  L ho52;2S-<*CNN!!!޾Y[%- < Ů얘RSqgd-grPQr**9jb^{_amadr   ÿ ɼORZ$[Z 4c8!%$'     )#f?-6-4 #+.O7  H' LKX ek-5 d>d>VVץ)[[謬  LMc  SXZ%&(44E*05'/6BҼ! |MXj1;Ctty !LKHTLRǾNEX3@Y ѿ1;@ %# <+  LO<7,:JLLJB] Xۘ~L9xSov8#  Kt(ppWW e_ )[[Q@@ QQRBB.-3 %%$*  01+6C3opX\S +'(-)*')8𲴾'-. gnu Wu %#  W]*nJ "8SUU ( $&0if @:&0F88 cOO((&  ><+'%.𯬽 !/10.¿"$+5 dzGΣ@KQWbx¼GMP "(&G?N Y9')'    % m'ObnMMt   $@]YcYGLR[0#$ *05# ( &7ӀR`kjj JJJFDM# 󯶦νbap%!) + (X 1-RS+ʹ0,~>;DCP )'?A1.'jLK5 +' य़ZZf%(.  LuY;FRԾ.26""y --" 4455T#>?@: 2696@AiS  *=0侲lps !GYn'=e~WF"F1$  ckt Ah/ƣ>;M- #*0Ź:16hhs]ݞeȷlZ|](/5+4CNXA.-4 |z ﻎryӗ0xXheDꒉ*18 S%򶶶HHH@66 _^Yʸ wŪvi  5?81¹i{-:7F>OʳF9;/ tjS *.  㹽 c`cROXtE83 dj]]kvnNQ--\\\552ZZ豱}~|n{&31ԓ|I@= Ļ !+ϼ yy{~# :AE5 !uU~qû)19&#$W  ...YYE EcccEDCzhE>@ í XXN@G7EEEgcq P@=<^>=*2: {bG{|˃򻻻fff('.---  % "&ļexy8G@Ǹyyy~RQ_Q  cRK-"5$ "*cccCCCBBB+++ !), %*2?%2C jaG0////X^B@G"*''''''YYY(((&&&^EA:(bO (bO 922ˇ'"0&/87'@G999UAuuu[D G؞(b888  ehd{`W31'0bKLLL888* H6f*UO(bA:(bI(b(C9z(b(? a՞@LHIütpdXXX -2 2sV /O Gڡz&_E %B Gڡz&_&h0pM Gڡz&_E Q1CxSzBzp&h0pMgyٗTRS pu # 駡MQ 8?ccUQB'L{ȃ8}E{ȃ8}E{ȃ8}q|Ht;Ls+!k ihffƢ|vG+A:9 !Y_A" 9 3B " 9" 9?\t0 8wO.Bl7l: 9n9n:## Ǣyss"_e1XXXXOX G\\Gwuv  &sx*֨$9v[eOM[i\t0r9-٦ sM.jCs64, TvT޿\Nz,&= :7mdI' !n5̽912mVo&= :7mdI' #@0 +.edU &= :7mdI'  ׷ 2?RqRϽ8: /kY|唈!n5$4{mo=0ﲰ HYϽ8: /kY|唈!n5  $A$A.Ow줞ri #ЂJ{MN: ЂJ{MN: ЂJ{MN:.|.ۍVl ce STh&};㖈d/ ce ܏Y|:<4 Ѩ _!2#߼&& 5Cbyuu&֥%2#߼&& 2#߼&& xU2RP7 G0Dl'tco|/(ڰ}S^^ 0Dl'tco|/(ڰ}S^^ 9q"@z^@z'@*%O%O G`G :r:2o[o'@*%O%O G`G G`G'@*%O%O$::QrQ,o.,c, G`G(}(,o.,c, G`G8' T* #% PUO(z T.  \\\_555ilqdz/*6oE 7"f8.    LNH𵱰777w~896GHL ccc x5% J"} c8W0      ʴLPS޽ʥ:F\#, #G8OdddJ"o"3&A#   }>NRȾ   zôc(e7?# $?;:252ߓ  734QUX\\\;;C &===    P6A '%~dY]'! _n=ƹ hQI@,380 b0bgx85.]]jHOVBCE $[4g, ^6a5AB2AB2    φп%#&" A9A ffv ׵"9?V SUL546  ubzru;:H , ,() =J yLPIB ܨ H5˸  ϳrfDPh~0.1 555Oiyb2Ձ/ $%M _؎C "%ǯ(0:;YF"wS{Vqm_6Q,  RRRokj }|z#%!!.՛Y`r  IPXGEQ :;V xSZf* 0%! &*' 'ص&/6pjlк  Tgx#WVw;FV;41s bRhev~YMS"=<2,VQR ﭢhrsNZdNq+V@(&'%kmW 캻&(+" ,'pu}   #~ pUS1j;  ˘-**;;;꭭JLKwwwiiiust('. ~}'& %%& ~GK;FGT`be _ej**,  ސSVc?Bc   0<   10(*"#wfR?@SҲQAQQX\BDMcfv MLYɜB?DS\en|~\VV%@ y} [[Yhrs7!fa{2 S N=-  .+&MK4*<;"  ( y ڤ/X҂555 2[y B!fkePLMwww(,-&'! jli.*NNN"r[fiG?Dmmk| 376220]]]쭫 71?,+;)  *5: /0+*:Ipp CFHԯqst# žHLOD@>$#)Q**4670DIPZds KK[ ;DS񯬛  ($0 ihx!$!$!ZZZ8b'+)HU\YR齛'" ^ZV4"~es1QP'&*l5:;#$B=5 ,32,32|v  坻v_!%+Hb}p_Գ-Jd¤w U%0/-,,,** ;; GGQQ嫫jj9NSMNSM###)))fff覧 MP^qcbt p{°",/FHY]^A '*7-/G 8![cp.$/5M (  %($)  SNQu{€ $(pbfo ᮭ@GPNW^:>! ⼨;;%!!薾 JJJ999ä   xy|    ?6R:5Gx7OMɼ-)!   ' eb]ñGL^   SQ]ձEJO )$ 0&&ȋ72+sy榥MPk\RPee`nqzOSd126?þDFa! ")1-*., !mrU]O{{ƺ  cZQ%(+ 6$7Cm={, {C"6J5G>_HDWuO@*("vcOqkURA.WgSp{Jܽe ;fvu~>$$?7ܙ  3_F lF3   cg d&X~ A #!_<@p( A y`OfQQ%aaaEE= ""__i}~v}].:Bpk  t6*WIE:Yjn :$ *ILD mi!%u~yyw37`),=".Ay  ($. 0,.ÿT[.nhf^`a *2A տlsHJ픍 &' [`L) mvc z WX u~ppXV^it   t{ $;;B764   %2"PW #1RKNOU(+78[F$LA/sb )Aq  H3jK (  {ǝ1):"3@_^Y tоz '/56>EbgmE+oN 33CL{*gXaf33CL{*gXafxw|$!."(&3鋋OKH";C><;AH7PRc  .*)]da3:{FI> :BO11+\ZBokrqg]ײ  5*0  ;;;999 :k2 wS0Ł'DN"_y_bJk61 @ܑrt\qxZ80$Cw)b " 0&  " D-r 9> M% - aFK7kbP D8}Whh9GS9GS_ $𞘒  P " \:@km]fkyA6R"5LjI6v]fkyA6R"5LjI6A -eQWA y`O2=A-,3yyy{wEDJ/Щd]gv%'*69K/2,BCJ7nrq;=B-&*]V[QTSſ)3 !! _T& ~; Ro@ Ew,CP$=:S y1벥@GN(.5#  q`O y`Oۮ%XqN;(A Ŀ;?EKHF nsy󭱫  $,0 2E^!70:-#bJ1ؗ12, &!dq]418!IJ@D[#a^n饗€Ǿ0-*|vv059ens%8 &).ʹ' #~~:<]#/(%7 $$$BBB **(,<5d[".)/aGMY'# (8Ǥ9\x $6qQ)?=,?=,=0@S%CEBD7 q+z7F¸\G , R`$CE=mw- ֶJJJ}wp _nz  C$U$2EM{*gSag6U$2EM{*gSag6S.?&!{=cC5{=cC5   %&&2VWR58a&, WY"!'%08<+*(-/2%&. $4NO,--6:9+<4%Oԕ?8:  ng_ 0 973,$1;L  5+"8! RYp  )-0  ru1BV lt027,(6$   &*+$gbA쎏y{mkR|}} ZZVݦ@@B   **( (89\x 0-%RAH{03 NR_lN'*, H[Q:ɗyq~杞'w0ۘ?l9652P9 $;ȫ|b7 &q  gTC8Zj/  y`Oh& '476h& '476 \ \ \ ! #!.`^ZXXVSx{  !+.+Œ~WW_46*'+* sjc33639A#!<,2D+00'‰Ǖ&,, <<4E93  2" 6PŐz{~ &wXf_@9$xy  u.(% ̵H54.y$e?Cq& lbd䜝220WSW "̊$%/34ypO "$˵eBfYblZZZKKK2t}r*** )5((l Џҫ>?;>Qb %+%I ! =)OlO G4Hoooo .4;  8?D5$(' 0fF]< A>Apq`O(jj%SS{lB{$t \ ~!kz \ed~!kzuusmm/ cdeMLQ  50:𬧡069IHMQ^`HY[-+,  7/>귯QU\%-+  `d sw5EU;3& =4FK8KH %39 $    î&RMO.H>?OaND" " ,41Q_XFgqcW0C88tttKKK[[[xip+h+!5GG##v  eMA#÷80*6( "IHH  4 4O{{;CL-Xqxsi"J,- %I%5-4R_k8c⯘Is# Bc!EWyXXi8 E>A33CL{*gXafApq`OApi8ZAFu*$ ێ\H V0I5#)o=\fA !2G~,,FGA44 7se se]\aUQR &4]adv43 AJ4=$81;?8B%$"Ҵ?8J.23򱭫 =??   4K74L5jm⧦ C?T.6>%,*9/2   #   OIS0 ZR] *ûڹ |$%* ,/+ jP5++nK_88mmW>{jy}h{ !"TCTmW>ITέ6_B!   0"cni] %%--%O% ͟pW[HVc''023ȑǎp: (E=dEи˲$ &/ JS 0*;  ?>& SanJc  # '* . VC?!(!$ ՝JFe$  LIX#+%  N]H]W[rjs81)mxv  ƬɰũÍgj8(2333AWKK22  T`, (/6  Sj  -  A$JJ#! -49P'e FE--`0 T*,59xc9x Ls{>N"*e^26n - "FW;W+A*m xmsK Pb  \\ NNNFFFvvt  %&( UUUIK@3(!*%ZTTP r'!!#˲ֽ,0=.&9!6>EW  !![QI   53,&"*YS;?BJ04=  ADX̶!   >2.~+,0>>O'   NJK9838@H"%.ꬵ &)oQKKxXc--- W,W,Z^0.] / 4?I3BS~gY$^],v !% 4()#22(9  + PYj!~D3Dݩʾx w`OU$2EM{*gSag6!.IM9I u> >6^8`2Cu+& ՜n^SHJ] Ƌ ,)f98[ A y`OA y`O+ŨŨ,A@ 1c XXhh hh 㝝GGG AAX 00ݒ"*"Ƚ4OZ+*fAXư67<"$$$FMR%40WGC2!  𶢪{~y uvvDOF+*H "ū  JVJ ,.%,(VZ]d    95?&+--/0W "֜ù/#f66ļ^D]""ZZ*_֡k55V'NO(O==(:9::} @yyWWW 9_ 2K%.88_/=TSUɮӽ%@Q  ADc+w+wS DzD@5R5;IpE6O6OOx((x(mz (l(R8(x( WdGBC,ל\SHA y`O(A(A䝝FFF 38PþWZYBBThmx 2A,!FHLLNKɻ-<9ULT#@)$+>8ACI 6/ !7D->MFEd $ ,' ")JL ( !lkr FHU HJW$(*, 6JTg[vM[6,6;;C""^^rmnZ'֡k@@iϹ1G55>ȑvvoOÁ*ZZ}̢@o|xD@K ͪ  ){w{pi58<|n s+mH8&mYVDV>j0 DV>j0 9U9U$6Bc!ĵ CTfk1ŷ I[ W5bK M5쥽8'8C.(A wWط Y@N,AP y`OA x]1͒Ҩ^@K. 쥽8'8C.(мz3!1I;D A x]1͒Ҩ^@K. &bLP 2J4O䞞FFF:<1% zzz# q.8QXJCjihMOT2"*--.0G\PMBHD.* ,/3)+$   ?AN   CIT²EDN縹y~{DCS ! "CLO 壔 kQP$$$^^{Y'- @@3i1G g6mS1uZ K14to7DsLLL6( aFXN@5M0N1OOyJJcXkĻ LYe6DV>j/ ݝS D^`N հa0 LsDVS|)%e~*4 *4 *4 6C !)BSq9 ̠#!Uc i)Ȱr[vk#Ф/.TV[CDVr[vk#DVr[vk#(E@oE0 "ayfh]r%?g2Ŀ.K8ibo&ZP/AZr+T+jh]r%?g2Ŀ.K8炰kkDGAZr+T+;J;J)>*?(N(\ \ XXX LLLfff2./$9 xYfo DDB146'&*'!74?C     34/@-4F .>D C],®JMJ % W]e  | lwnc>FM\K&Kv, WWWW= Rc21RE* ;! cL2|N tB Qf_3&,Q,} OȊ(p               –E >j0 2\`D+LL( q[wp"7T54.V^b咄Txv#1dX1dW졈LMwZt%U^a咄Txv#U^a咄Txv#׃*)ׁiyh5WApq`OApq`Of&jJ F!u_S FbZ} \ \ \ZZZ򴴴>>>0"񽽽 LLL<<:216MMMD:*2)+4&(3 |'!!¿), 󱘔++++5>"  #,7E7BjjrX`o CIWux}yj ;=<&(06;A ,2$  _Zd㩞vZj?,0!!ܴLLL000 :;8;"I$l1:f]Ea)Q9m:X>fXX >j/ (|~)Q]Gf3/4, +TΧT, */$ # ߗ> ŦTAP5DRk^ʝ fHBa!,֚f[RGw?sULg i:@;47.: w?sULg i:@;4Sn&G*)Sn&G*)N'T_EFr)$ ԝn^SHHfH5[\X;\\ \X=5[ -d\X=ZZZ󳳳  LLL[Z_TPO'!ýDDN8;Ben 76F !%"/ M 70554&Y2$#awJ4c?3:խ0W 4R_k8c⯘Is#̼2Rvl& 8CEѵ8a8 (A VSd9*mt=)TBl UScwѤ!0[-}JP]x]Zz]ĎϷJ ,(fCD? 5c/룽 80QD/*lo9úЬ( y`O 5c/룽 80QD/*kf|Gսj1 y`Okf|Gսj1 y`O*YzƼO4"+cJ>AM t'hFii{ \ k/Sk4 t'hFl$bHfk/Sk4 ZZZYYY  ^cblih% (%( DEO)/1RN4    㘨""$twpHBB4.2 VRg.)- 0%" 5;;DFFգW]\-34?B=_`[$       =*0[?M$$$$$$ᤓ%zO 6PPP*?`qzsn(ZZRR6">f< –E >j0 w2's׸f5x!>U*$邍T #ADK83ȑǎp: (E=dE ?c!qS ,LHjl&` (}př_ 2Q>Yi6-9]#pZ>j0  -M5 82F2F^I\^I((OAWOA(^I\^I$+G+G$+G+G&?&?(2k? z` z&&s2k?}\ z&&s ;:? LWX >@Z #lpXXXuvqMNU܍ ҪROZW]]NPJ%#'  $+ LaZNGVJJI}\_j! D(<Y`_ܤ158 ( (((%%%388   "$"$#   40>!"  H;?!3&-cnw4,]:sQn  "Yˁp]\nݾA%NKN2@777³|{nU0̄q[pKXcwtsB4(½ ""#0$  Ls66*IIEtQ9xc9x Ms Ls8DD9V Ls LsMs Ls 2=t=t -;w;wp.\1 3e  bbb8?Z", ڳ>C;焌&$G?JlhjBMT #!,+-"     ~{tK?Igccͨ-349̹xy  #B]#K+&/8 qIF/?3&o]J]JsYt*AA!B4%DHD2 A y`OBNj?柶 0 *g97[pb-{ Vtt&WO Vtt&W"_ "_ kb_8  edi:;:!"%&6'''|{~PN[𚝖]l}*%$Iɋw{}$$&(-1򧢮  EIW V`g`q20/GF? :8E  0998>C )!- *$"*(2GNS)*"  5,ȿrksOKT.40)1G+ H)  N-+ (   r5...Ir #*V8]=<kC1* H f  2     $ Ls(x(((x((x((x(dJ\dJ(x({)[ H@A\ H@A\^ ^ 9/d 9:59:7=9 '%$Y[\ a°DE" OSV¹Z]j  WQA ,.<**7 yxLVq%%%,+/!#&98<*.3.,'**'&.5$ &  gdQWsEI1UPT>AP=LY$%QQ' / j|d!r !  -"_:...#)H/hE >  N?eg@{1 % *"AlӅ**44DDdd XX dd::::33 672 57Z&'3   ^[eDA@knlVRQ47; &12"UST  >=;TVb %' $/5A6%ߟ6?AFT*+. 664HFFB@@  8EG*'/E;H! "UbwIiz  ǾO9 Samy21fZV  mgsQ5a@  8   N=n  k~>6#ސY%ԃ.. **##ﰰ @B<.+.--8 x|}xnn  $$FJQ^di  0*B   !{ﮧ98<# ;EO$R^g 148)))RRR;  // ~|!MOH __0''6**WW-$$9--?@;aabAAN !>??*+' җ )"JJ\SSS 8=D3 !;>Oũ025쾾 CAO +*'38851  '&.񫣟NLH@.+"&.3(* ')-"""KE/_XhD> V_E  ٨ Xj KKvx ty@DJNebD;3 ջgԴ 4i| cc  bNNbNN12-  -*ì?DZfgpź  ҈}~CF/e:b  vrq$$'58>Żhe_!"%Ľ_dhJJIĻ48C ڹ8=B\\b~rq +./ $$"354$)-LNNuQA DBKq*&*   ! 85$    57 FHEX)0ۈKT 6%n,,  D;3 2)&??9 ְvzyN[g<40<40**  FHbސ)   %$,idN (##!0  eaqQQOqpo012ty  I#!lmh䳲ABH73@ 34!."&_z~RKR8A>״/*"\vS "8,(A3z:CB    svB;; +5ػ.A6&/ & ##ϴ A@C"+3.5PP\ nn55L " #,3!!N46#DjF*J/.25ż 996 ' # LLUDJV og\ ̽hΖ  NGDoleFHN[[],;:`]OK3%    $$,]Zq(/?GI-λܵ07*& ,1 A,!!-.0Tch618"! m2 aSf  鿱-4;5>F&2< dfSMMg@""#    '...   # {v[  pi^w)+(JNk36: SLR++.##bk  ,e`= &)% #8+ʯ["%,ZVC ! &$H2'ûzh\ӻX*)9*71? #6%  0 658ggl  9w O--.  s %  hH꼭kBF!#&!r "pgVPP   5' _2  GGG AAAA>>((2##%vt?#%1 .    ٖw""QNJ!" t $"/ccq:;@" Ӂ;@O7=E Կھ+! aB[!!;!<`?  5;;;3,1knu! &]W|;  Ϳ JĒc).H*F)ŸhGh"'ZfL j:8»(/5/6<4@I ?<?a԰sHCWw' +#  ȿ6( _F <ߘjjll(( kjq*'ooq(bEHIB  jgSۿAIY26O#".05PR" ?8;+nprmgo' %   ߹ JJJUT\ כTb_ $8oJUo e, 4I@Ņ=We&vR_i 5AJbháh""" -""""""h!hh!h**44+++;;;=>8`aZ  ((& :::us`=ENGHM::<ڻ 175 *42bж"-"&_[Z% roehf1Ǿ@>IINZϟ謯NNQbai88{~^A ̧r3f"(- y@JR *y `qci BIC5) &+ $$Z((( rsm#!,QON 񾾾¼³ƫ ((( +2B( '`YVaNT:;=352()! 7:2|z{Ζ3& ;WZjx,Fcw21 "G44PlllFFFB1 &&&&&&ORAFI9 TTV!&$$^`Z8;<  $" Ψeff\_D@4D@4Q9 >= ( 1 ______ ###ڑ///qqq222AAA(b:ثO A(b:ثO A(b:ثO EEG13:  ߧY]Y0.1᫭ VC=XV[ )($#!)-&&& &&& WWWaaa=, A0  GA(b549~zbbb*** 蝛`da %pۼ ؚzdZ=;3 ______aI aIό+++uuu???>. P< Ⳝ".8Kfc_V2 'CXrgB!A(b9G:ثO mhAyK 'CXrgB!A(b7;8`xL 'CXrgB!WCl@c%ߴ}}!,=dvs?A(b9G:ثOA(b7;8`xLߴ}}!,=dvs?EEE1-.8:5WV3HLPsmsD;% {cZ *(42-111rU㭭fffVVV###V2XZKκF Ɂ,fy3# Ո9[^nw.pA"L9m+]Z*ņzɁ,fy3# Ո9[^nw.˙sc׾oǗMEɍ< Ɂ,fy3# Ո9[^nw.x7PEޛW!i8K_ƀ<]{Z{*ݷd"pA"˙sc׾oǗMEɍ< i8K_ƀ<]{Z{*ݷd"YYYYYYυ񸳵  tZ;92 ?=~y)(  2pppppp =̹mAmYB ucu .8kE۵3ygEN9nucu .8~f;30ucu .ؕ ϗc:ֹd" 8kE8~f;30ϗc:ֹd" 021GFCȶ  7.*(xt DA  .`b#Zfa&Ĉ?]q{`BF]=ZrKjD%K)͉]=ZrKjD]=ZrKjD:ЂPDSܚJ 1fD NP- м  1fD NP- м ;ˏD\% VXW ߺKLEAA;8D<rUcNL_77XW f`87  2 :|򟥓_+MK^}sZ5 :!p}|}c=ql$jiഡ΁h>q :!p}|}c=q :!p}|}c=q)9VeQۭ_!Mƃ93w,3Hfkt= Mƃ93w,3Hfkt= )8|y@ y:ثO www 󫱌(/0Ny0NyCCyV GH{{~VCCyVGGCCyV G;?x?x G GG?x?xLsLs  ATZ    #60} " JJJ+()JJJ|||{yz  HJG   , 1NUNuuu䎌%%%ppp 01.loh|ytys{z;@:ic]]]777999()#kc :::((&nnl<< IENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_motor.png0000644000234100017500000256356712174204305027072 0ustar cpascualcpascual00000000000000PNG  IHDRh%T pHYs| )IDATx$~f31Z9;&5թZ! My79JI/1OÀ/1O11[BulslYc%;3;3lo$d%% 5G f3 T*S'Ԁ` `)/fV!I  !!Ɛ-! e7 eeeeQt<OCo PٔN  ܘ''SPKb;%`[[[ffft<of^~2c8LA#JJJ-@{jb GGG;GQ'$-4 fZ޸ȸ0 (<Ӏj`  jjj33>~~ x||ǎr9r=H=|DʋŻ/9B f3T*ng9iffPG  XXX ~~&&&ZZZ||Wq;))w ȸ) f3{jP{jfybIeybfRRRR)))999jmm&&:EN nj8bd dbiRUffff3000&&&!!!===innLJܖ@@@ hhhX x݇>ĒyT ։XC?MQ  eeNNYYY QQ z2錋Ź2>I0 Ƽ"f\. KKAAA555뾾(((44&&C&&&_g4@KTS*TTTzuO AQ;;;WWW...&&& *5/aOP(+A+;;;777XXXqqq$$$BBB444 VVV&&& JJJf3SSSIII777'''f3M}ݷ}э9.!nэ9wXl}%U_~[ wwr% ~fuG++}{j}{f3f3L6_b5V65 (j"1 ه6@J['6BY4ge7 eeeetIt[YYhQ[-S SAfQQytuuttTTTeeee[FJ@Ը?rYeVgS f3J%-Ӏj5tK LLL$0Q '%Ӏzt^^^SS '((aa22Q77Oڋuu  AA f3 f3n6 B_aJP%gf& `8f`OOH;; ++ ..22OOuF %x  Ln@BGFf3 .fQQuy`yd fgRR444'''DŽ`a_kkw`5AL `u`OVRRffff3+++<<(f3 6VH^̻''( hw VHY5-5-ahe|J`e !n1L' ?WFw}  Nfl ףE aڝYLE#+efQQeeLLQcDA޳kI9 N Г1zz&5M||oo*ɒj|( 15jw(5jw(A`~\~of`TTT%%%000cDcM9444S^F @ qkpaf3 1OKd)|OKd)~T~\˝yt;ɴ\AbRb>   4445+{yvvuEuƻ%2=*&_7IUb 96 ,Q)׋e>ȸf8 f8 >ȸy8 ǀqT(|$|~|$|~kfayf` 5c4 4 1bb0XXX 55{{ cc""!&& $$$PPPYYWWV?}}//[~:'4?;IL?if300(yf8HJ /csǍx9 ,ȀHl$ä=\洡L_t1{LofyNof_n`u{yOЮhzOORЮh  ,,  &&((( ~WWr// kk06:=ٵQ LȸJ cx90 =\L_ /\A4O\An`d|fxW w)R0RxPyOPyO)R0R ,CjZZRZRRTRfff f3AAA ???111"""+;&! $$$BBB)28 E(_Esi! < ~.  \. ۭ7\ fQQF8833 UUU'''EE11ޝ## !!332*** JJJFFFBBBh0gJ e7 7\Q+++ ##:!!!BB ##D##'&&&&&&***mM 222hg 0:@;tذP(؞*bH3aAH1w6U###??hhh222 s"T555444222bbbiii555 nnnOOOEEE!!!111???fff!!!444!!! 111>>>888***```jjj:::=== JJJ>>>$$$󇇇 JJJf3***'''"""FFF\\\<<<'''BBB&&&&&&&&&&&&f3;WWpq"++\b_[hzWW N$݃N!}羢gN!}B& ;YW XU"ūybzYWB-\ 1bB( Ӟ}hV췵m- &_hV B% Y %  -b}b|`\ZG' |{' Y8{' <*064c b   v v*ղ .CeEq>%(+s# 񫠡e  xy  W7n4/"RVSj"j[XN*$]]]1e7 ""  tO#Ԓ=0!|gku$<HHHddeeQv!AeL@%~[44mC:i~_RZg$d=z+" ZHw ^ T!fQQfffmLNvO?Jc_rR~Uyy++1ԜU7 ytyOaE[;%QQQ`WZ=?1 B/ re ҧm-   1{ y`yHofof-H.5jw((yX^^^ ]W121.{kix>f3~tj9j8`D[<7Yow-ӀRRFFFaaJJ`B( tca^&@ z`4$?4$?mOO,s߾y~*RRRRMMM;;;nno      ?>2f8gA(8 s`O,(y_|$|~*abbRbbcccaa !!! bbkk+++lltt || cc!!! ;;;111KY]1(07aG кBMV  98f336f33^~5z/f8 f8׍8 >ȸgfʽ6C EVfgf3RVWVWIII ##^^44+++  !!!WWJJUWS[[[  ii f30 M :~՚8 8 sA(tRAAA8gHGHG 򶶶JJJ<<:::||77-  '''WWJJ&**awC򉽉D!,3DFă~?qf3FBOP5jw(5jw(A3+Ud fʽ6C L^=a yNAyP=AA *vVAyO.8fgf3g俿 999...---  !!!!!!  &F  .T 5%, ȸ L^$y>sh! ow-Ӏ@ow-ӀUd6C L^<XA(@<Cff3 \\ AAA ]]]<<<  !!! ###  ---R{ ggg;;;]  >7<?%<[-[-DlR\\ R\fff<*ZZZ """ AAA!!!!!!@&Y8$6 úBOZ((|$|~p|$|~.AlA%SS%SS[\ ZZZ III(((<<<:::!!! RRR\K @kAtJ  7n[{@5 =7@ ` R` R R $$$ ...fM{١h /,F&gx"%{&oꉫؑ 6 TTT ---!!! ZZZ:::|||OV8_T@P+}z7ȆhhkkeeG88eefQQ''' *** C# :ڇ~#(+nPM$  ER^  cOOfQQUUU^^^kk((tt //99 رPQs!gf ,04NN TTTಲppp111$$bb//0ZZZjj++JiDAIw^B"!)//b8=QvvBBBUUUKKK77>TT wwcc,((( &&&HHHnnnBBBWYcc A- 5bddQ cccGGGXXX&&&lL!)EEfffMMMliUCCC++*&&&DDD뾷LS!)v%,  *td-bP((b *tq'&~d9zC؞*bH}9z@\\\752LSNNN gؙTbddO !߆Rbȃ@gؙTbqf`7xSVP(Ux 88829OO9 GOppp]]]ppp888hhh***///???@@@...xxx[[[::: 111ooorrrVVV:::ZZZOOOppp[[[000JJJppphhh$$$888jjjPPP222ZZZ GGG$$$qqq}}}eee444&&&___---YYYzzzzzz!!!\\\iiiVVV222f3&&&333(((mmmPPPLLL(((pppsssvvv&&&bbbqqqqqq  !!!!!!'''f3ef^ lOaYU`PE`40Uy`_kiP ^y60l 4V8d _ki<0砾`DZ@ ._CPC瞼bD`DZ@ ._Cs)`JY 5>4/.\JY>0^bb  A89EZ=j  A89&[@-Yx`6}4 9)G' G''xbT5 G'[T5 G'<*D{ T*tPd R;  >#'O{b|ҵ !O      ~JN+CNX] -Pn 䱈4B=F`u :x     qC\3DJ҂ ?OxF`u  "VPF 󑧷uϰqk +r      b= m<S+I$  at}C,$OPVD" &,eE,$:V+:=   "*=\xS0^6 ee__}(})873"NQ ĵy{4W ù=T)>6cɱ9gIGJ950xwu$X5i{V< rhvԩ VVVZGG\II,,؃؆333873S.S.{ 4TYʠ{ss fkq(䑒a3q|(f2 C4&RP0 ƼTX@ p@NZ333'''DDD ޲dIGB2^MEs fls LpoR5 QS*iW= hN)5L&L Rb'1 `I(\S$ApyO`I(\S$`@@@vB[0 00$ƁjPQQa~hI;791RF+R+^ȸzU3{*zU3{*|FQyOtE7Ot:zU3{*(U `e_Fe_F\=hs???  333BBB{{{㹹ddd""$$$ nnee zzzccȫHU`bBƼ~xsTlw7!ہzx "+d2 R)>ZJ9's8 C0 f3=L)3 ((oxoxlu+6 ɼ7D ((^I\^Iox$+G+G % oR {F {Fqs---hh--RRKKK ~~  RR// SSS ggUUU vv""" ,,?? 00 vv:::ddNH,7A 00 NI H/$+16& z/ L&`0 T* Y,jm! f8g<*݉ }bg#w88 ]"gôôd%ŷPd3M4J VRJNNNIIIXX ~~~BBBB###^^^666((ee999@@%%!!!nnNnnI-gJчyy~uOz &ŋ+16ځ)]bf #TJU+f3 GHl) * Q]<}^w8jAVVVqRz)d}+Eg;`ApyOxl|oApyOApyOApyOddXXdd 㚚JJJ 666---     !!! nnI##ƅ@-(IJy$$$iMhKE5z%4' 1# 0# FG  Bw(g9 3x) fMsE >ȸhw8`0fuٕrQ\lU)~\lU)~A ^l%+Df.: ³>Mo~~}|7A(VX*~~p-}-A(VX*f . 999  """ ###!!!99 #@:*G""aE bП'(`C LL LLQQ @ s_b}}$?,8}$?,8o{H#.: >M&l"Q*  ӀQ* .}\\\fff󧧧NNN<* ZZZ???<<< """***   XJ{ccc R RffDJOzU3{*|o3PyOzU3{*退~(({~ww y|sKBRlB\sKB|c!\ ffffff555  &&&111 111 III  888...D{nw@tBwfE#փ KabcC C]nSgzEP\G)((((oxqwoxc8!mmm*** 111FFF&&&&&&!!!555 555!!!&&& 000 !!!;;;:::gggƵy0Q+H= ɟ<!e u 0l)IKf ^t%QyAd *BB BB nnn '''$$$  ,,,NNN < h 4  jUg~zbt@LL A33ee( <00yyy  !!!  :::X 47[iq pp}}{r f=zuu"4?IFE??>=GQ"%'c &$&. ccDCTT^555KKK"""...  '''%%%<<<bbb !!!@@ h:lʶBLZ"#*/    98iH()+&''% ccc$$$ !!!EE 44@@ 111 ''c   ??-?? ^^^###3  +Fn $) ,6> D9  ]DR) PPP KKwwwxxx... <<=#-4!!!x%7Oa~g^K3 Iܜ(bpb, Pۼ&_E(b;<^K3 IܜCs5B A)(b;>>qqqUUU///SSSkkkTTT===666222ƴ666VVV\\\'''wwwbbb'''111::::::ooo---''':::yyyTTT000zzz444kkkgggkkkkkk###&&&'''+++SSSDDDaaa!!!HHHhhhhhh&&& BBB +++RRRooo'''wwwbbb999111$$$!!! hhh111HHH MMM0 +++ΟRRR;;;yyyCCCD{6888  )))&&&CCCpppPPPVVVcccwwwwww111IIIĮ (((OOOnnn ///'''555 ###<<<<<<!!! ###''':::NNNyyy+++###+++&&&06bk;9)⼆c`M!G' ƪJ3"H"FFbl^ i]Q|J 糒pkb enU*FFbl^㪍lq%Uqh30peoC<c5h30peoJXBGh)%D{D )w t}\QMrM_kiLM`k*D{D |xx7\qN@Bs<]я3gw2\qN@Bixv]ԣhXl78+(B /U۟oS:-ԣhXlU__sNBN 5I \1NBN 5j,=Iy]f$+2̤8OdobQUIy]f&e,+Z-uHvv,+Z?жA,Ulx/_ū`^~[APH SRN=yaS @x/_ū`^~ڛt /eoTm1U*J̍nxx/m1U*JJSS~'=}=$d|dl%`SS~&e|e[`y[`f3D{06~E(  mՄI W{   g \K~G!I+  [     f ]# r +"Q     k  kxmoP|I!mdRHs֬$-x P      e \\@?:tČcW>2s      i ӽLrR( c<@?:0 Sq{  x      gooomhc$).N'*:=*:=i3.  39dWP#-vS[Q]'&$M̚,~هc9 P-O@Ypq0&b>5*?3$󏴝35k˕ηz7,"RKHKHč 41-K# MĬ>/TTT((==RR\\PBo. A2 0˕!`:79!M;1nehFWYLD@%+wwwN=tU>k )((+--ᝥLv%9mJDsþǷ%9I#D7*>7*յ [~?tEx t2$ nɘ]W yOͺ#(yOͺ#A CCC3318F 0""wζvRp000̀]@Z MxCNZ[lO!eˮ  ooXUUZgs B(C4J6K`G8PH.`G8PH.C4J6K6jf(`G8PH.  릦OOOF |2[2vf>AՐhkd!Va&df/+il(!ؕ]77zzddfO*4Oʌ: )I%N'͸;̞]ysW=3̞]ysW=3͸;\lU)~̞]ysW=3 @@@i0z0AƸ:Hd8%::GG;;,,]OA J"%gS_)msA66GUa(Z- P"!{zh~gF3Kh~gF3KP"!{}$?,h~gF3K\b  @@@:HdMBLm5X?KVq? '`OPnnooEOXȿ! ]4!E#yOyOPR  @@@#^]GG//@@~J(& '-.1fbTy h `0w?!]rUW:Epw?!]rUW:Ep*U4?!]rUW:EpSnOO,?jq\\ qR GGG!!!,77 jj&&г蘀eWW`T2 ϞB.ЛSS2 2HG,8 $ޅjZj0 5cE7Q4 5cE7Q4U9+ `zk4{~ 5cE7Q4kf|yO#gZ}Y R Z}Yk :::   555 hhh 333###$$$***TTT 222SS [[ PPP!!!((??? LI,'- &&+V3Ǽ%,1!ypxwv00 ss ȡ #>> ##RRR {{HHH ]]??? VVSS OOO((LLL@.t&)'/CC\\""!'K #ᖣ ?ƨa_o 8_t8_%G#U+Oa{T'u( ( c{+6 $5%%%//AA <<22EEEuuuWWW33111@@@$$***TT!!OOO++!(2uuu0"+;ALJx{] $l_jljZXd駌9AH#).   f366U+.uQ=Z GJy8fDVg9 j0 ^~5zeN%fDj0 rVlfd|ŷ+6 jd2YHHH""PP <<EEE..AA \\\``444||RRRRKK))I(ufa9A{O%. xY  BBet +0P(00M& 2Ƽ}d݉(/agynjxLgEǷ~g<*_NQ+r,7 :³^vgf3ql qccc## @@ ff}}55 ///+++""" &&&I$I"Hš>833<<5 1113 ##<<ҳ $BNX+0 f3 \.\Frw™ Q\<}^w9) * !+" :HA 5tKyOֳf ayO` ` `+gH bbb444***   *** """BBB!!!<>33<<5 ڵK&Kn333f]""gb~JQU8 3Y,\. ?Ov'+5O6D 0; "Kɱ ` 4A ̿Zpa ((Ee2gbbb,,, ;;; ###///###:::  777 BBB ~ ''RRV&&ڴL&LA&AK&KnvvcccwTSkvRJ 4DFGcă~ G 7" 0c1 \s M)5`G8PH.A ``G8PH.]*:RNi.2> fayd`{{5A;5_^x"A ` {F{5tT  `Ocf ħf3 555 '''(((   ///:::(((%%%!!!<<<~/0''V&& 2A1A  Ʀ""ZM!+ 6( /" + $y8f8m77g9 j0 wQy; 3xBc!*4 #IbH=̞]ysW=3`̞]ysW=3D(vt.L"+Pe~b?Ps0 Ϡh6\ sJ`?Ps0 Ϡh6wh|nBBSf3 WWW     ***&&&33 kHg^ס11  ::ZEly7 L7 ss QP LL Ҩlj}–h~gF3Kh~gF3KS8TL6X h& '46o)h& '46 3? &9ZR R R ZZZXXX666+++  ,,, ''' """+++:::33NNG))n ـAwP2}aIX0 +IX0 +  S9t+ ZRRZZZffff3XXX  000 """ +++NNmmmՓœh?e*3ԕw?!]rUW:Ep!w?!]rUW:Ep Nylbdmza  `lbdmza ` `cbtf `r \\\ Rl| Rl ZZZXXX   )))  ---&&&777...{{{C" $>, 5cE7Q4?'( ` 5cE7Q4c{((((퀀퀀 ((RR R RRYYY """999...   ---JJJ:::......PPP!!!fffooouuu gx9UO`3 `f '^I\^IOAWA^I\^I((e ReQQQ999''' <<<񲲲III888𩩩KKK 888  (((MMM OOOD{4"u|KcXPX rm+b4i_ƼsrmX?9n  ===;;; 333EEEFFFLLL ,,, YYYYYYXXX u~Ԍ\B)PXĹ5AMZ 5-]$)757!% M. '!(3A&^RPb Rpi pi FR mmm 555###CCC  BBB!!!///MMMXXX '4? M}` 5,Eй/X52?q XX22hh  !!! !!!,,,JJJ ::: L!')쩿m!.  L ho52;2S-<*CNN}}}jjj+++  CCCIII!!!O7  H' LKX ek-5 d>d>VVץ)[[謬  555???   """ 瞞VVV+++B] Xۘ~L9xSov8#  Kt(ppWW e_ )[[Q@@ QQRBBMMM """  ... 666!!!bbb???PPPgnu Wu %#  W]*nJ "8SUU ( $&0if @:&0F88 cOOcccFFF<<< '''EEE..."""55AA###gggUUU)))m'ObnMMt   $@]YcYGLR[0#$ *05# ( &7ӀR`kjj MMMXXX $$$WWWHHHFFF }}??--00**""XX 66!!!pppWWW???%(.  LuY;FRԾ.26""y --" 4455T#>ccc """%%%  gggQQ HHVrr))RR ""%% bb7 GG''!!!JJJ,,,]ݞeȷlZ|](/5+4CNX=*2: {bG{|˃򻻻fff77 222 000 JJJ&&&+++AAA$$$  cRK-"5$ "*cccCCCBBB+++jjjGGG""" JJJX^B@G"*''''''YYY(((&&&^EA:(bO (bO IIIHHH&&&FFF+++87'@G999UAuuu[D G؞(b}}}xxxuuu31'0bKLLL888* H6f*UO(bA:A*tq'A(b(C? a՞@(b(? a՞@OOOIIIbbbddd -2 2sV /O Gڡz&_E %B ^K3֕q&h0pM Gڡz&_E Q1Cgyٗzp&h0pMgyٗ222!!!駡MQ 8?ccUQB'L{ȃ8} Ag/T(E{ȃ8}q|Ht;Lsk!k EEE666PPP===DDDD{:9 !Y_A" 9 3B T(" 9?\t0.Bl7l:.Bl7l: 9n9n:ZZZ111OOOIII"_e1XXX G GrrrUUU444$$$444 888yyyzzz888YYYttt ***+++eee222bbb&&&EEE((($$$SSSyyy&&&ddd:::bbb333bbb...ggggggJJJ,,,qqq  (((KKK𫫫'''FFFfffXXXXXX%%% XXX %%%...555333eeeeee jjj!!!111,,,[[[ 999&&&222*** ```qqq<<<888mmm222 )))bbb:::>>>333"""000 /// 慅xxx}}}TTT333  ... ZZZ{{{[[[...111666(((222vvv`````` iiihhh===???eeeEEEEEE"""''' mmmԻ+++***333333333]]]%%%jjj'''mmmYYYTTTCCChhh &&&cccUUU```''' '''&&&ڕbbb QQQ###Ϡ  !!!''' &&&JJJ>>>555ٸ݊"uGGG333mmm&&& Ğ888$$$ gggvvv<<<```FFF<<<999```+++'''666444000+++/// 999%%%"""###WWW######06Ŏ =,Nq;<&c9' ̴jr |Xz}~Qf:{.7I u _i-1) ,e,v[sx*֨$9v[eOM[i\t0r9-٦ sM.jCs64, TvT޿\Nz,&= :7mdI' !n5̽912mVo&= :7mdI' #@0 +.edU &= :7mdI'  ׷ 2?RqRϽ8: /kY|唈!n5$4{mo=0ﲰ HYϽ8: /kY|唈!n5  $A$A.Ow줞ri #ЂJ{MN: ЂJ{MN: ЂJ{MN:.|.ۍVl ce STh&};㖈d/ ce ܏Y|:<4 Ѩ _!2#߼&& 5Cbyuu&֥%2#߼&& 2#߼&& xU2RP7 G0Dl'tco|/(ڰ}S^^ 0Dl'tco|/(ڰ}S^^ 9q"@z^@z'@*%O%O G`G :r:2o[o'@*%O%O G`G G`G'@*%O%O$::QrQ,o.,c, G`G(}(,o.,c, G`G8':{ T*(z T.dz/*6oE 7"f8. x5% J"} c8W0 J"o"3&A#   }>NRȾ   zôc(e7?#0 b0bgx85.]]jHOVBCE $[4g, ^6a5Oiyb2Ձ/ $%M _؎C "%ǯ(0:;YF"wS{Vqm_6Q, :{ﭢhrsNZdNq+V@(&'%kmW 캻&(+" ,'pu}   #~ pUS1j;  hrs7!fa{2 S N=-  .+&MK4*<;"  ( y ڤ/X҂555 2[y B!/ i`D)pi$ >! ⼨;;%!!薾 JJJ6$7Cm={, {C"6J5G>_HDWuO@*("vcOqkURA.WgSp{Jܽe ;fvu~>$$?7ܙ  3_F lF3   cg d&X~ fQQ%aaaXrܗ|B ]KvfٜKڸWRe&g1 \YW\YW#2rK19JJQQackRA-Wn^^K: B  '97+,  䞞3Z& oZ@ T< ! m A=~DI,;=OHiG]pW?DDD   %2"PW #1RKNOU(+78[F$LA/sb )Aq  H3jK (  {ǝ1):"3@_^Y tоz '/56>EbgmE+oN Ν!!!*** :k2 wS0Ł'DN"_y_bJk61 @ܑrt\qxZ80$Cw)b " 0&  " D-r 9> M% - aFK7kbP D8}Whh9GS9GS_ $𞘒  A -eQWA y`OA -eQWA y`OCCC -0  8< #5-v0zV*q2L80w[[[&t}-> !! _T& ~; Ro@ Ew,CP$=:S y1벥@GN(.5#  y`Oۮ%XqN;(A y`Oۮ%XqN;(A褤000:{,<5d[".)/aGMY'# (8Ǥ9\x $6qQ)?=,?=,=0@S%CEBD7 q+z7F¸\G , R`$CE=mw- ֶJJJ}wp _nz  C${=cC5{=cC5{=cC5{=cC5AAA (89\x 0-%RAH{03 NR_lN'*, H[Q:ɗyq~杞'w0ۘ?l9652P9 $;ȫ|b7 &q  gTC8Zlbd䜝?;>Qb %+%I ! =)OlO G4Hoooo .4;  8?D5$(' DVi}_&6>j0 DV>j0 (jj%SS(jj%SS^\{lB{ \ {lB{III KKK,,,솆FFF===999777 888333 &&&$$$ )) RR@@ @@@ 555333 NNMM000tt``))--- !!!"""88tttKKK[[[xip+h+!5GG##v  eMA#÷80*6( "IHH  4 4O{{;CL-Xqxsi"J,- %I%5-4GF㹗^DB䗚Gt Bc!EWEG44 44 eXXX==oo--GG  KK """lll yy$$!!! vv ##666##kkiii>>JJJ&&CCC 3388mmW>{jy}h{ !"TCTmW>ITέ6_B!   0"cni] %%--%O% ͟pW[HVc''02 "k:H1`|y]uk5ާ,*@;c{7" DV–E >j0 ާ,*@;c{7" DV>j(誶 'C;dG<#и˲$ &/ j/ ߊY=[#̞nZ-QI ִX KOqqu+ؼī1) {>N"*"FW;W+Ax Pb xNNNFFF QQQ ??$$$pppgg!!!2222SS %%%JJJ--- W,W,Z^0.] / 4?I3BS~gY$^],v !% 4()#22(9 6d=*{=Z6 ظv4d7 )LIK?]xpv/yظv 4d7 )LIK>]yqv0zdؗO8eZ8e  +J] Ƌ ,)f98[ A y`OA y`O+ŨŨ,A@ XX 㝝GGG SS    """  ///!!!:{66ļ^D]""ZZ*_֡k55V'NO(O==(:9::} @yyWWW 9_ 2K%.88_/-{*M]B_zH +0' (N,0' )N6?>=TSUɮӽ%@Q Azil) y`OA y`O WdGBC,ל\SHA y`O(A(A䝝FFF  !!!   +++  6,6;;C""^^rmnZ'֡k@@iϹ1G55>ȑvvoOÁ*ZZ}̢@o|xD@K ͪ  ){w{pi58<|n s+mH8&mYVSpS!#48ز:!#59ز:9U9U$6Bc!ĵ CTs)hd3'84fk1ŷ I[ W5bK M5쥽8'8C.(A wWط Y@N,AP y`OA x]1͒Ҩ^@K. 쥽8'8C.(мz3!1I;D A x]1͒Ҩ^@K. &bLP 2J4O䞞FFF  111/// """;;; 000,,, !!!!!!$$$^^{Y'- @@3i1G g6mS1uZ K14to7DsLLL6( aFXN@5M0N1OOyJJcXkĻ LYe6)I}Zq>[bS$̞m+Or *0$Ģo\#)I}Zqw>\bS#̞m+OrS|)%e~;EKԗm*t!U{=cC5AP y`O{=cC5AP y`O*4 *4 *4 6C !)BSq9 ̠#!Uc i)Ȱ>>:::<<<)))  &&&666 !!!lY- v++||  uZ K1476,   aFCRk;l5Fdf   "ywܦx +)Va{7#  B!W{>j0 "yvۧx +)V`{8$   (D%B$CnR 𔝚?Pr0 ϡ!6 f6(A y`O𔝚?Pr0 ϡ!6 f6uVR"ayfh]r%?g2Ŀ.K8ibo&ZP/AZr+T+jh]r%?g2Ŀ.K8炰kkDGAZr+T+;J;J)>*?(N(\ \ XXX LLL...???  666  """M\K&Kv, WWWW= Rc21RE* ;! cL2|N tB Qf_3&,Q,} OȊ(p                Ls Ls$\V\!QpQ %\V\ Ls!3Opƙ85h& '476h& '476K)f&jJ F!u_S FbZ} \ \ \ZZZ򴴴>>>0"񽽽 LLL'''  $$$   333,,,  !!ܴLLL000 :;8;"I$l1:f]Ea)Q9m:X>fXX qIU0 %)IU0 %)DRk^ʝ fHBa!,֚f[RGw?sULg i:@;47.: w?sULg i:@;4Sn&G*)Sn&G*)N'T_EFr)$ ԝn^SHHfH5[\X;\\ \X=5[ -d\X=ZZZ󳳳  LLL  --- 111   000  777 !!!ܽ<<&Y2$#lbd䜝AM t'hFii{ \ k/Sk4 t'hFl$bHfk/Sk4 ZZZYYY &&&,,,  ### '''  ,,,   ### &&&444 BBB$$$$$$ᤓ%zO 6PPP*?`qzsn(ZZRR6">f< ((j.AlAj( 82F2F^I\^I((OAWOA(^I\^I$+G+G$+G+G&?&?(2k? z` z&&s2k?}\ z&&s NNN )))"""   ***,,,BBB ///EEE  /// ***FFFWWW(((cnw4,]:sQn  "Yˁp]\nݾA%NKN2@777³|{nU0̄q[pKXcwtsB4(½ ""#0$  3e  ccc!!!888 :::... %%%000 999   $$$ CCC!!!CCC???Ĕ"""KKKmmm###BrgB'J F>̹xy  #B]#K+&/8 qIF/?3&o]J]JsYt*AA!B4%DHD2 pb-{ Vtt&WO Vtt&W"_ "_ kb_8  ccc??? 111  ]]]\\\--- ***  !!!<<<<<<yyyꙙ nnnqqq:{   r5...Ir #*V8]=<kC1* H f  2     ${)[ H@A\ H@A\^ ^ 9/d vvv &&&    RRRRRRTTT555ݿ󖖖FFF"_:...#)H/hE >  N?eg@{1 % *"AlӅ**44DDdd XX dd::::33 vvvggg999       '''  nnnwwwQ5a@  8   N=n  k~>6#ސY%ԃ.. **##ﰰ hhh !!! %%%###!!!,,,\\\wwwaaa000Ԉttt/)s   J6T  Ff*& kW>  // ~|!MOH __0''6**WW-$$9--hhh!!! """>>>  555'''  444KKKFFF000\\\eee D> V_E  ٨ Xj KKvx ty@DJNebD;3 ջgԴ 4i| cc  bNNbNNYYY      888"""___000ddd ***???***### ۈKT 6%n,,  D;3 2)&??9 ְvzyN[g<40<40**  FHbސ)   [[["""... $$$ۭ\\\###:::666 een  66__6$$___``` nn55L " #,3!!N46#DjF*J/.25ż 996 ' MMM999 999666 ^^^ 5"" CC !!  // vv77.?? %% #!!!...lllsss"""FFF"! m2 aSf  鿱-4;5>F&2< dfSMMg@""#    '...  iii$$$*** lll//22$ %% BB  33 ""uuLL << !!+++qqqޖ纺OOO 9w O--.  s %  hH꼭kBF!#&!r "pgVPP   5' _2  GGG AAAA>>jjj  迿lll~~ ""NN HH  ))CCCC&&&"" "" AAA=== !!!!!!222Ա|;  Ϳ JĒc).H*F)ŸhGh"'ZfL j:8»(/5/6<4@I ?<?a԰sHCWw' +#  ȿ6( _F <ߘjjll(( }}}JJJ 00##RR2200 EEB!!!666!!!VVV JJJWWW>>>***֦///???:{ כTb_ $8oJUo e, 4I@Ņ=We&vR_i 5AJbháh""" -""""""h!hh!h**44+++;;;555}}}"""!!!!!!pp//,,, """ OOO  JJJ999...===ç/// 88{~^A ̧r3f"(- y@JR *y `qci BIC5) &+ $$Z((( 555ccc::: %%% ???!!!;;;@@@ ///JJJ888ݛΖ3& ;WZjx,Fcw21 "G44PlllFFFB1 &&&&&&MMM곳GGGG멩GGG󛛛]]] '''///WWW@@@111uuu]]]D@4D@4Q9 >= ( 1 ______ ###ڑ///qqq222AAA(b:ثO A(b:ثO A(b:ثO ccc###)))...***333///777 ((( )($#!)-&&& &&& WWWaaa=, A0  GA(bccccccCCCMMM=;3 ______aI aIό+++uuu???>. P< Ⳝ".8Kfc_V2 'CXrgB!A(b9G:ثO mhAyK 'CXrgB!A(b7;8`xL 'CXrgB!WCl@c%ߴ}}!,=dvs?A(b9G:ثOA(b7;8`xLߴ}}!,=dvs?zzz ݏ *(42-111rU㭭fffVVV###V2XZKκF Ɂ,fy3# Ո9[^nw.pA"L9m+]Z*ņzɁ,fy3# Ո9[^nw.˙sc׾oǗMEɍ< Ɂ,fy3# Ո9[^nw.x7PEޛW!i8K_ƀ<]{Z{*ݷd"pA"˙sc׾oǗMEɍ< i8K_ƀ<]{Z{*ݷd"%%%444콽 JJJ ?=~y)(  2pppppp =̹mAmYB ucu .8kE۵3ygEN9nucu .8~f;30ucu .ؕ ϗc:ֹd" 8kE8~f;30ϗc:ֹd" fffBBBOOO{{{MMM*(xt DA  .`b#Zfa&Ĉ?]q{`BF]=ZrKjD%K)͉]=ZrKjD]=ZrKjD:ЂPDSܚJ 1fD NP- м  1fD NP- м ;ˏD\% >>>mmm###ddd111$$$77XW f`87  2 :|򟥓_+MK^}sZ5 :!p}|}c=ql$jiഡ΁h>q :!p}|}c=q :!p}|}c=q)9VeQۭ_!Mƃ93w,3Hfkt= Mƃ93w,3Hfkt= )8|y@ y:ثO  ---VVVmmm\\\TTT]]]222<<<:{(/0Ny0NyCCyV GH{{~VCCyV GGCCyV G;?x?x G GG?x?xLsLsӭ444&&&QQQFFFhhhyyyTTT555RRR ZZZ '''VVVYYYВ QQQ;;;III{{{zzzCCC}}}III &&&(((WWW JJJPPP>>>@@@bbbMMMMMM  됐ppp444111FFFUUU]]]]]]DDDŵ^^^ '''YYY%%%)))???EEE<<<<<<yyyBBBvvvXXX''' qqqqqqBBB """'''---RRR^^^,,,SSS mmmlllqqqbbb...***mmm\\\TTT######~~~XXX### 444BBB󻻻444&&&bbb򀀀(((rrrKKK444ZZZ '''VVVYYYВ QQQ;;;鍍:::222:{+++/// &&&(((WWW JJJPPP>>>OOOsss888///  됐ppp444ѳ """AAA```KKKKKK555%%%  222"""777III333///|||bbb""" 111ᆆhhh %%%""")))&&&555555)))!!![[[ \\\---}}}...iii ```ooo>>>444 444BBB888aaazzz>>>oooqqq~~~<<444/// ⃃xxx222 MMM+++///$$$ 888yyynnnnnn///666PPPȱ===^^^KKKAAA:{%%%  (((TTT $$$;;;NNN888888""" iiinnn   $$$!!!,,,,,,!!! ''' ---&&&222,,,***AAA 000&&&+++GGG XXXIII~~~111 9999  WWW^l IENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_motor_read_position_flow.png0000644000234100017500000645755012174204305033036 0ustar cpascualcpascual00000000000000PNG  IHDROU*P pHYsR_IDATxhSSSfff %%%FFF ̦$ =܌$ UU""VVQQYYuuuBBJJss|| (993Y܌˒ 5:-e7 000YY111!!!!!rzmS6@g 7owiA~`1X>///!!!%%%#10#%mm-}nj|WV[ 1OK)ɀ˝[S1X>\\\OOOEEE%%%hhhc[bhg Sq*Z(|$~ 5c4 ''' GG ""---zpwq8$Ҙ Lפ݅hzhЮg0RyXa`jRRRb!nXXBBB"c}dжnX_mYUPd]N\h)\)RRRRbbbbJJJƛ%Gb{]LoHVbjOjDjDDlllEEEpO lbbbvvv++ 0fQ~~~ddd222***vvvfff''':::DDDZZZ&&&'''<<<AAA'''999LLL<<<&&&ג)))999H+JnS?eee%%%lU-~R{դn$x?ygggPP-}׫UjRn7~]q4 T/T :G e= N(a ׫``@'U'Jz<+ G i2J7QǗeA( Ϸf"U؞ Gl~_@[[[******U)U׫ƺ:simG (; < ______b(>W:k"J2iΗG GG Η  ***PPPcccyyyqqqAAAwwwOOOwww> Ƌ(|/U011ˆ 6XԖH`G/2G(7͘, CefM, ک-_Ą*  ,! ͘RyKya :j2ӡ7n5L˴,RԮN&;:˴ԮN3w::ˊeIGlΕ6;0%3ϨbbIؠF<<<sssUUUmmm222?ye7# #r̙.*=UU""YY6 PPPuu㼼+ee <<{ "*1'D0$Ų]ZWvvaggeeLL!!!q||J%]ow~UIbRLb0""")/5UXO!)\k˝[Syt\bfb0"""((( jjjvveeori&^ϣ[]GAAA s@@ s~ 5c ^^^???NNN ^ ‹!xyP}n@^xAt pyOZZRR(((ԽIIILL&&&@dqf^r`n?[-U@ORRR _bb`^HHH`O``!!!(((===e7 7WooRQ,,,###!!!(((>>>fffDDDYYY w((([[[zzz<<< ...ڥ@@@<<<'''v+v+J)LӖЀɶ״0yS,UD*YAɟ+Q( G/_ԡM SԫII? GA7a GԡMLLL%%%ƺ:5U٫wnmB G GG Q.|=]"k_+^o{{o{"" GR2gEb(U妠O-`c\fe'UɟQ5DA>q G\Ge QQѯwwwc)>W (|/U>84ˆ 6XX;H888SSSTTTɀ=R؞ G7888rrrgggoooDDD ;;;-\mY-W(; X< $$$. @7( LS1ҡ .I-tJ'V0u3ǻZ&_ |6(!y3 ƲZZYAA0&03FVCuȋ,R} 1I8uȋiiizzz) ȋԮNNȋSalyyyyyy8 OCCC !4qee|||DOY::: @@@@@@RRR]]]>u   777(((rrr!!!,# wAmqA/,.  "*ükv҈  L LK8&KRK8&Ks bIbId |%<`f%<AJ `AiVVRRVVRRUR&&&)GGGPPP'''PPPFcs9ă`IObId o%Ā`f%Ā`}%%%MMM ':K(0/7MMM+yy$$......EEEDDD888bbb /7TTTe7 7\Qrrr<<<jjj ###999999[[[222 ـ&&&&lllkkkBBBQQQYYYuuuMMM'''hhh{{{tttttt...{{{%%%NNN y*]557w+8G&K}(Jٿy*h7FF8Ȉ 'ٿқa!^ ].EuD聁w (JٿHHH{{{bbb GG O(`Ȉ3.eE =x)'ٿq"FFFG [+MճU(##?-eT C##U)U:q`q&G ճ##ӛ CG ##׫LLL(((qY_4kK6lJ.(ثU)M ª#:dGG ؜00bj1<⾓pgGUD!jlªG<BmBY)%Ej׫ ;"""ں7<ɷ5:؅*&8 /ٴ3W0MҹG U)U׫A9q|: T//dE/MMG ׫qN(`ooo`[[[xxxU)U׫õ}IE0g*IV!/F ѺG(Y@M)וIW&&0tV ׫K$=K$aЙ'o3 gg FFF3 >>>TTTSSSCIV!/F ?mΓ G G1jϖ;G fGΓ G G3 :ooo3 < ooo  (((222;;;!!!UUU%%%%%%___𜜜!!!;;;XXXCCC===tttttt<<<<<<;;;E0g*IV!/FѺ*;[(Y@M)וIW&!/FϮ0tV ЙƮ'o3 gg 3 G,b! %;Djxo47r66Fa%;DAB{,G cyg| :8{pn0XԿ,AZG P-RӨXf8> G GjjjYY[YE 5e ^?.l3I͹?% 5> ^&`bjr,JZP0<<< 5e ^.͹.5e e fH)$8> A"ӂ-~c/Tz,Bbbb///|3M ___111-~SS555 3MSSSOOO BBB VVV:Md&p ϶ ք555 000\\\7B>$z =EEgg6UUUܞRR +++bbcc(((|| %%<<< SS YY ]]\D~O,> (%T>ԁk#"*5j׳e7 xxJJ.55 Q$$$gg鞞"̈́3Cww7tt]]&&+ӫ>o9 --,N Gwl~#.55NNN 333   AMb}(-ƦT*ˎszFeI\r{ ytyO#!h_RREEE---000--- Mm)"W*$ݷD>dd   y`yHofofyO¥-H.-H.yXRRRR((( 111...:::)"aG.9B$^;u MM~tj9j8P"!h_7Y7YabbRbb%%%222???EEE888  444_E ##lR^j"f8 f8Hȸ z`4$?4$?mOO,yOs߾y:s߾y:*RVWVWVVV...!!!///111ܸ 8?qq111PQ")/>r[df8 j/r[d_O`O,Oy_y_*GHG ###11 τH$HpqǍs9sCCCBT>EhhLg@\0 f8\# WWW  qqHH 66! EE!!!|||ݣ6o6tQ vS f8Hȇ 7x0fCȇ 7x* {%߀AayOOyO \\ ((( 77CCMMM""",,,WWW2') zl OM?ȸȸ{fC0 ͜nW=a=hCAyO2gP{|yO zyXЮhDlR\\ R\ {{{즦 KKK000bbb 2'ֳ ߓ OVtclg 4iLwa<@<Cb4CjDO耀bI#QR[\ fffYYY M D[:6Odd> i`X%<?<ywPyOw'Py` R` R R@@@///ʆ ջ/ ¦0 ((.AlAc{OjO((jO MMM111:::WWWӺb;/ٲaq ""###'''ZZZ111WWW JJJ+D\.!FBBAeeevvv%%% MMfI mmmAAAvvv888춶dddzzzc5 2222ffffQ aaa555))) TP0 cccaaaooo444 0&&&'''EEERRRAAAccc&&& aaaFFFooo444 &&&'''EEERRR%%%!!!&&&!!!qqqIIIBBBuuuwABEI%Dv '???&&&XXX.nB (Ji:Z;;;Q#&7" p%W*׬O?yi!iW`0f"w99^ɉ5'''2 2К>`d3|v)50(888G G(Oر`aa8'ٻe^E0fК>7=z34a6]*3^ zx;4R,G +5f;Ȳ 3ر`>AǿqEБ 6o3z\d:5H@yA @ydj 3 3: k̸fG U GA(Oر`ÿqر`---U)UʗNIV!/FѺ*;[ƮS;*ڢqa(҄ CGG(bѡqa;#Дr&JrbtV ---ս5k4M̳M2iZ>t;Q G؞G ^NʑZlt;Q; ---׫̳ΗZ G G GYZGG}3Gl 6111U5ưSylB2RR(Oر`333:ƫOJSO.-4Q `+2M*& &CbR؞ر`>AǿqjG uf\e0Lв LTG׫G G E\EдG T(Oر`ÿqر`,,,999O/`YC=gqI{׫'kK6l 4ar[S'j1<⾓p{FGG D!jѠ::Uu4V[<Wł>uk\O^ G :'@ثZxx :F{ǗeG nz7L^   Gc(kK6l]gl2DμG G j1<%Uu4V[ޕה< G :'@ثZkG G {{ 4 ; 4qqq(((```III((( $$$---777???aaaaaaCCCCCCGGG000GGGddd ssssss잞!!!===ZZZ???CCCCCC:::vvvvvvU)U׫'kK6lJ.(/NMq:2p%RR$(<ɈeM\v?\SuS"z387x-Sv?OqqqA0'#rJIuF%h;NjIu: >uL GU)U׫ v~_v_)ҽ (ɰ s(No9NǿGR.[ҥѫɰ캍[DyCCC999G |S?c1No#{f&|S?Ա܎ABBBxxxZZZ7 ?ɋ7χD < ?ɋ7&rG .WҩMG [[[[[[XPJҮG MG M.RҮK-_ӡZZZZ!_2Oޠ"`6)&)Oޠ I}ZZZδ`6 ))d`V0! ھ k; ߀ 111v  MW % @7/    ,# ] ___..J $$VV ``AA ii :: 111|| tt777kk__  x~g (*-(*Aޕq\=>,}]mh    P T.} r R. ##\\PSSS{{:: ee22!!!!!"" ff""111111{҅V. t 4ؽ)D !. $"ʺ.S󠬹O)S } ]ZWWW'''ݸHmmvva 999 GG!$$ FFF  !!!V. )Di^sPTns|C0tX LMČ: DtE'7' HV???!!!!!! ;;;  {H)#@INH^snflsSO/:tB$(E3\\22OO򤙏n/`I(\S$ApyOApyOͺD`R \))))))###   ###BBBF ]WWה)RBHBB  r\lU)~\lU)~̞ rTWFq3̞ rTWFq3e_Fe_F\=hsoooFFF ,,,--- &&&***!!! 555000((((((LLL,,,--UIS)s),~ VVyy {}$?,8}$?,8C4K4Kyh~gF3Kh~gF3KoR {F {Fqsxxx ))) !!!### !!! !!!AAA--5@Fd.:EKK?ffefDcl\ h@,!Ƿ8 C0 zU3{*zU3{*|FQyOtE7Ot:tE7Ot:(U `J VRJ555JJJ !!!&&&"""!!!:::...WWW)))% __+ d}WWWڦs)}T PPO1F4wGh8L3rh8L3r8  V S* ((oxoxlu^I\^I^I\^I$+G+GddXXdd ccc ---000###77  勋 --eeﹹ )) % kk+#$ p.7=X{K*^y[ 9*K8&z# *K8&z# Q+ vvvhhh;;;}}$$ $$!!! OO6 88%##',,,"" \\\eee嘘r/ / zKT'+ 3+54 .:EH(6S!vrԅVj0 6S!v2c$`ApyO ~cApyO`ApyO}\\\ZZZ GGGGGGvv zz  $$$FFF,,,GGGOOOGGG!!!aS"Y·3>EKxڦm gC"! LL LL )|"| )|s..sW~~~~A(VX*Q̧t~~`Or1 sJ~~I{nBA(VX*|sKBRlB\sKB|c!\QQQ!!!WW0KKKLLLGGGrrr,,,"""- K8G(roh kphJ!7h7Q*_2X}ap*    :nQ*c8!;;;pppPPP@@@?GHj: 3=F    Ĩ%9MtV㬣oKZg((((~{~ N}~(({((~hwcdc*BB BB +++333IIIEEE ^ ch{ ԉn+4   +)%$  $)@U fwLZg(((hhhXXX444999ݷAAA Z\{I0E ,27wyh!  ***&&&DDDBBBSSSQQQ͋DDD!!!jjj}}}[[[lL!) ...oRe7 LLLϻ \00oo  O99--CC '''CCClllooo$$$<<_YrЯ0fК$eBfvfv<𚍊좰8طgpƂ/.^ҢD555QQQ/// BBBƦ7Z觻 Y?EλM9uNjU'JٶM4kY:Y ZFj[QLig\ GG GG ħ:Y Z3QدU)U׫ho$nZԦfvfv%/Ƃ/ܶDPPP :8je:FηtR=#G R9),˫(n}SaD`v=WY,: C.b6U:(n}Sa$LLL &"OOÌLU:1bb7ZZ1bb׫׫B%BLLLLU)U׫GG GG GG 22 U)U׫82oΑ(((---UIg"fAN5lLeU(5J˲AjAi2Z3v. jAi0P<5 b: j?ζ X: b;X şÊ3v. ų3;  6]x)X-B韅5@G1lPxlxx•V'@ŠQ.yG\% xlxx•P@( [8Jܮi)ZExgXv?'@xX;xᰡ/k^׫8Qq@Q}Q^dd :d8^ɗbL} GG-\ GGɗG GG<!y!?7?׫ Ab͗looo׫"""333U)U׫7<{GG ߖj5 GG ~9<BǂGG U)U׫e>$eB3òCel2EλM9uD2@jl2EλM9uWA@XG $ooo׫ GGÌGuÌ#PPGdž3mmB%Booo[[[***VVV***xxxU)U׫ڿpCj&U)Uת̬ZŃ7G:MĞa=[Һ22 GG 82oΑR+\Ig"fAIg"fAN5ltkA˰(o³n.1I4mwIg"fAj?ζ X6犯&bVÊ3v. ų3; &AjAgO]x):׫j2]x)X-BzlvtS;O7Ŝc>L$ ]x) [8Jܮi)ZExgX{X>;xVʼn'@ŠQ.yᰡ/k^׫ GG8Qq@׫?8Qq@Q}QǖGұӽ׫׫8Qq<!y!Gʼn GG AbL}"kFFF>>>___vvvfff???wwwvvv______@@@___!!!GCTL$ ]x) [8K-B{X>;xVʼn'@ŠQ.yᰡ/k^fff׫?8Qq@Q}Q^ddұӽ׫׫8Qq<eQ}Qʼn GG AbL}"kggggggfff111$$$U)U׫.WҩMGG F@[!_9RҮI8uȋn5L˴X֫|,_ԮM.RҮI8uȋ&;J-_ӡb|غaN*OޠR˴^6 xHud͔TFOޠR?}rrr)δd"`e^6x͹). 5d"`e> V j28...8=v(M3j͌=|.M0dk7pǘe6tʌ5lޕDk =|.M0dxUӃ&}+BBBxxx...ZZZvާj|IF ]?RУ`UKņ:pt<2M#k ]?RБ@?yXsh}xxxtl϶͛`]<ņ ?Z =Rѵ͛`yh䠨s@tqnWH, VBD\3! Lڙp%R1 ! LڙnWH, L._<7ov?mmmζcb\Suz۠;DżnʧX :^ ܓDmݪfu8 X1Z6jt'>S@@@XXXھˆi<51jvԴ`[Om #R>,`,Jx}p'V7  c.FӒ'|ϨaBa@E{wv̡m)ZMR ξ98Ζ:ШP=QB===```JJJnnnnnn???F e;m ~u|ɰ )CſuNҺNVSI===aaaHHHppppppwwwvvv@@@BBBrd SSaY<< 7 hN>=WYggim!/- eb^"%)'www,ЦeF aI % ***222\\\,,,;;; )))((( ?vɔRpWCphqxv8sK?>aaa8ceG ]m8= s4+++$$$ (((///))):::ɔR@H%W +UVOXD# y/"fBIQB-AzDx#̺wS nO0=J w%%%333 """777###!!!|JY/5yk#%mܕqy+][Ppfd7_ P VmfN55ye_A#!c_" ` _>O;%AyO\b999 /// ''' > ) iG,I$qy$B w7(o6ޏ_'iK-O!2AB llr÷{ =iyOͺ#( `I\S$APR  ===  )))***'''+++///) ^>Wc[n$d,_+"[[[q %Mx7(H9CM iK-!?98 r'C4J6K`G8PH.`G8PH.oOS$6jf(6jf(?jq\\ qR111'''555!!!''' )))888aaaDDD???!!!222iiijjj !8oKWbk|YF C k͸;̞]ysW=3̞]ysW=3G*\\lU)~\lU)~#gZ}Y R Z}Yk  )))>>>AAA:::SSS333 RRR111 |||nr55~ĄfW𢙱Kuž(Jn!+2/ñP"!{zh~gF3Kh~gF3K _?[<$}$?,8}$?,8jnj11z!||| !!! 666CCC###\\\\\\EEE555oƅiR Q^i ajX5^yO `555(((  &&&  !!!mmmUUUddpU=I);jgdp߶T,<>|9 26< 8 ff@@j0 w?!]rUW:Epw?!]rUW:Ep*U4U4SnOO,YcccNNN    &&&ggggggFFF___ **'? y8/Qg}̞&,0FwhfDǷ 5cE7Q4 5cE7Q4U9+ `zk4{~zk4{~kf|yOql qMMM888  ((( :::HHH  ˓m6m&&11100|y}77IIݦ_] *MyO ȏQ+WmqX8 g9 >ȸȏQ+WmqXfDPuv2{XG(^I\^I^I\^I$+G+G((oxoxlu NNN+++!!!  66:::  |||777|||ػ``ee55m6m--q܏$$frf"E|w[vG뿆:%&&<# 6($iCݚO !9vPsgEǷDݚO !9vPҎL~޼FbbbbbbMMM&&&??RR(44AA88@@#BBBΙ...ee5.(EcIx, V@.x  VA[iU qigOU qigOkP999444"""  MMZ22``%  .. rr VV   vvv___&&&fk SH- b'Q97=* h0eRF'n{('vvvQQQ 222!!>> 66$....444RR 555,,,***%%%nnn)))0000 mmmZ{id2<k;YAHd8y_O7^y#m Hd8y_O7^y#mAo İyO` ``AyO `ZR R R  jj__!..DD111 III 666BBB&&&999BScBBBV`m).3 RaOvC!)UrP.jcLE>ǷRaOvC!)UrPs)4l|oA(ZRRRRR (((CCC%%%...JJJooo***]]]```Bř4NL,/%))+5 ŖqssA Aϓ̼wxvss9r9r0ee9r9r LL;EKm!7{5A `{5 ` o{5 vA `AXP.hyO{5R *vV `r \\\ Rl| Rl ,,,KKDD999---###***---000;gD 芾= 999)+!&*2 $/*#V#@KRQQIG= ؛wwwOOO666<<<8iIkKpAKW3" &&&񵵵== '''iiilllddd|||gggsSJar[`HHG# #:::%%%(((𦦦^^^mmmvvvOOOS: -'.{{{```)))俿,,,.#==;44  999%%%"""DDD}}}vvvvvv齽 ߇(HH&&&&&&cH +Ҍ XXXmmƓ&<<<Iuudd\\\xxx{{{ ///EEEKKK\\\\\\(((|||<9/(JJJJJJtW"""' :4.:%.tt:mmDDD"""C  ^^^111OOOWWWkj%2 FFFYYYYYY===...000!&&&WWW111""":::mmmRRRIII蟟sss\\\\\\\\\???&&&RRRyyyCCC]]]\\\]]]\\\]]]\\\@@@<<<"""򒒒444pppXXXUUU///|||lllooo***@@@ddd|||||| ^^^111 %%%YYYYYY===!!!hhhWWWWWW111""":::mmmRRROOOXXX&&&RRR]]]ݍ555 uuuQQQyyy777VVVZZZ&&&kkk%%%!!!WWWNNNXXXMMM555 &&&>>>++++++\\\\\\\\\IIIgggCCC(((X=ܪ?`p,ttt:::888Fkpt幛$|ʰ|KYҽHK1333JJJ߭n]ZgJ at-xHK+++zzzZZZn0l5Q4PaD(Ps 0\ϡWL0?Fqqqqqq###ttthhhb|1{$?kTd*ݢ*By.- bbbbbbkkkwww5``LHBj*LDeZz^B߫UxTTTTTTzzzddd,TTuiZ'b[@tΌpOwkzKAAA_3 uuu[[[LuLuGxAjxߘEߪd U3 aaaMMM崦[K918i6d|pGwkzK nnn>>>333RRRU)U׫U)U׫ۓBiCm%&q Z{սh}ZZF \wߘEGk꺳BfwI|||GG ׫U)U׫׫UQmP0m+CVCV +97Wɯ|dP̢JGK yMyI+YYYmqJ8R6$BαFB>ËxDCYDxKOUݣl9̲Gu@ U)U׫U)U׫YDxKF#Iȹs;IIddH&սh}z6d| +,L .M ȿ_dU<+,(M0@{ 0Z ?;!p60^mK7(#ǵcO=\|bG +G(bmK7(#ǵ%tmum^^^ L[EKV4``!Q^~~LG GG GGQmQn______^^^ ?`?'s(bG %mm______^^^GG U)U׫U)U׫U)U׫n18GG ~&<  Gvvv^^^ T]'oa*eG9ɲ ⾓D],[YݱCj[{>P󹚱ĄwaO"M:7$Ƴ BC_ d=U:UG U:M:7$Ƴb+R*@fkL?) 4q̒Fn51(bBC_ d= 3~mjϖ;}}}!K(6RʮZBmmriskG@2D4U)UU)U׫U)UE@2D#ߍύI4m@̓^N8 N5l˔v𛾚v G؞jByȤ;}}}fNz<@9mb <) *==* )<Ԛӿ"Lj>$ Y-@'NM9fӿ"Lj>h@_Fxm TCugތFlJuJuSZuJhJċzQY"x B ylMaaA8=j>- x B y~n /^i!4Яw;wʼnlMaa91Bk>8\ GG 5}Sy!Gǖ V``6UЮ,׫~׫V``6U׫ ,DieQ}Qʼn GG Զ4q93(R(;;;SSSwww(bWd7U3U)U׫(b:UG ۓBiCm%SSSwwwG w7,:׫E7uɋ`_/ GU)UUQmP0mwwwU$0&s4:p0BαFBԶ7J6$BαFBs[voьI9hzB뵁pVeSIddH&b(T7V4:cpѰ^jcp.;-%yze/ S|S;!& !;&G \5.[0I͜\5qd3 yx   L .MM0@{ 0Z(M0@{ 0Zi=~dV=,'$ Z~EE~Z1BG ?C!l5%tmumJJJ;;; GG׫4``׫ 8(4``yy x))x13mmQmQn<<<;;;%mm<<<;;;OOOOOOuuu&&&&&&uuuVVV333VVV333VVV333^*********999GCi?<GCTsreG9ɲ fkL?{736rʑGU:BC_ d= 3~mjϖ;fGxThlK(6Rʡb(XǍK,6RʮZBmmS=(V.S^V,6RʮZ^N8 N5lb;X şU)UjByȤ;  6z<bG ɀ=Mz<@9mb "//@( z<ZY-@'vYwӿ"Lj>h@_Fxm7Cܱh@_Fxm TCugU@GQJph@_Fxm /^i!4Я5?lMaaA8=j>8\  GG׫ 5}SG m }Sy!F^ddw+wuGG GG5}S ,DieQ}Q7?׫Ю,...ddd 4<eeeeeeddd999eeeeee333...///&&&///&&&---aaaaaaaaa\\\\\\???]]]]\\\]]]\\\]]]\\\@@@iii!!!U)Uת̬ZŃ7U)U׫+<8 U)U׫U)U׫n1882oΑ4U dg3eG9ɲ ⾓D],[YV?6%"ߣi!fd K(6RʮZBmmS=(VĆPjxsygAr.^y>sreG9ɲ f⾓D],[Yo636rʑGU:BC_ d= 3~mjϖ;b(XǍK,6RʮZBmmri.S^V,6RʮZ^N8BmmGb;X şU)UjByȤ;G ɀ=Mz<@9mb <) *=//@( z<Z9mb vYwӿ"Lj>7Cܱh@_Fxm TCugތFlJuJuSZoGQJph@_Fxm /^i! TCugU5?lMaaA8=j>8\ GG m }Sy!Gǖ+xw+wuGG GG5}S ,Di!y!?7?׫Ю,...DDD 4<DDD...yyyzzzyyyGG UOU)U׫---J0`۵?罎IcU[Ɲw^~<^! LG+k_І]*a罎IcU[騷 ^l <ģJ3k;3kr5Ic,R9AǿqF֝X ➶kr)پ A D,aob5I)"Q' H/ UPط3Haobuy Ҷ.G]O beWZ]̮K8rQȎ:8!VL67 Z]̮*Ω?HWWW溫^jg~R3$1PҶغX]lƽh} 05!I6x剺3$1PҶXAWWWeMw/(F ]]/гͶU)U׫GG ^^^f׫Ge GG]]]]]]lll******m&_ᶽݐH=0-Yu=U؀C^$g߱X|*&rVQ9Aǿs0-Yu=UHDzG,Aψ***lll999Ѧ,vnA "wIc #770꼞:XQ3>xA "w4W6 :Ԙ1ZmԜ3{X>]

KVVV9^Bʓt؁`>%RT J,<^Bʓ:.#:O'VVV"_5_=>Qzfgѵ ?Z >Qzz+ 5VVVVD7U)U׫UOU)U׫aJ0`۵?罎IcU[Ɲw^~<^]*a+k_І]*a罎IcU[騷 ^l <ģAAAYYYJ3k;3kr5IcF֝X 9AǿqF֝X ➶kr)پ A AAAYYYD,aob5I)"Q' ط3H UPط3Haobuy Ҷ.G]AAAO beWZ]̮K8rQȎ7VL67 Z]̮*Ω?HVVV溫^jg~R3$1PҶغX]lƽI6x, 05!I6x剺3$1PҶXAVVVeMw/(F]] ]]/гͶڛm#e444e~˘5h{!Ofqp1ab==9j vIfỹrrr:{ƅ1ʾ{ާEmpؾ-1fϞ밴AtoooooorrrÑ6BM8Bj% 5ooooooqp1ab=Q]9C=nL }YX ɚ73Z yNx Й<1fϞ밴dVZ \'A`F_"%͟<<<```KKK777\\\ ͜ʆE﷦%nÛǴ_H-~SN"{i`sU[A/$ٿȚ***NNNqqqpppppp\\\\\\???]]]\\\%H}YXensbEcƽͱDgخU7e===```JJJ888]]]\\\]]]\\\@@@ΑT+4'A`F_%?TK $/:$/gƚ+++OOOoooqqqqqq$k>>///EEEYYYYYYCCCCCC!!!~\\\\\\\\\III +++Ϟ"""000CCC 쨨000 AAA_| l///bƙ# ] W ,,, >g clT7?J  ~   {GP+===%%%///DDD"""lll DDDDDD:::JJ UU  $$$ ppBBBj}q!#7/e:mS !bxY     d;h9hhNNvv22>>''",,,((( zzJJJ  RR """ KK  ??QQ aaa  ''' ƻH޻m%߾!-0C(?clWN 4;Aw[jP       :%Q <11JJ88>>SS++7& &=`` gg --11  !!! ))AAA******ww LLL^^^^rrr----000!!! &ȯÁq ! %/i%|g|g~~~#-f jp\j3MKI֝YYY д'GG%%%ٚΰװ```   """%%%!!!<=Wyxw\ho+ gC8晙AT'[+G98G98hnn ~~~->Rp`MqV` 555000%%% """$$$ ((( !!!!!!  """V"zqN[ ^?84׵ʹ6̼ i[a#CF#l+Z ̶Q=&,9675  *~~~%Is'mI4` yuk_ " "B ƒ2$ vﹹ III ... !!!,,, !!!   ...!!!  yеٷh Y9)KfKf>^^>^e(4J{411/rxy3+(:fTwh1# 239U 2u  r`E HT%`% & G)FFFHHH CCC     bHNT%di1g0Kg0K U)D  #!Һ?EvwjkndD'@)z4ZM F}\I5 g 4 Ƚ9LkN5dثWak *A -eQWA y`OA -eQWA y`O\s \   )))   ... ---BBBXA!]>}'>]EKQ{ɶvv ͓t ``a.3 y`Oۮ%XqN;(A y`Oۮ%XqN;(A85"""!!!--- ''' ///!!!   %%%BBB!!!nn4# ¿K>J ]_) dABDIih}4X  {l5;@ G /4{=cC5{=cC5{=cC5{=cC5]qsz \\ z \l MMM  444***  mmm :::ۺIII $$$  ...!!!:::CCCFFF!!!333;;;((( gHOdA%!!2(! B-sӺ6Ÿ',2  P -eL;𔝚?Pr0 ϡ!6 f6𔝚?Pr0 ϡ!6 f6P -eL;𔝚?Pr0 ϡ!6 f6𔝚?Pr0 ϡ!6 f6^\{lB{ \ {lB{vvvxxx   '''DDD ))) PPP;;;  000;;;ppp@@@iiiCCCIIIIII6~ B#@"&YoL9g,8@") "@KG* OO%%t:k:""<+?%+0  y`Oh& '476h& '476 y`Oh& '476h& '476EG44 44 ehhh  +++>>>   ...  JJJJJJス \\\ ]C ##&&Xc@ ̹.16#YA8#վVZHHw w\ ||/"8?D IU0 %)IU0 %)  IU0 %)IU0 %)  B Bhhh...&&&***  }}}}}}|||999ǾYYY$$coIgqwkG G +R""+5=ʽ2%0.EX/i[Π|l$)-4:""  DV IP$}~^>j/ DV>j0 lbd䜝j/ Ͱe?%ux! DV;[|>j/ jjj """--- HHH)))  GG CC ## ttt}}}FFFHHH```55$K%K Yےݺ1A\uP]CHU,,+  !%W[LZk"}Ji2f=&}qJJyfg LsDV>j/ f=&}qJJyfgŭ¥Ɲ kkkYYY ###  666''=  22^^ """dd dddddd|||>>>999JJJ244ؑ~(oyy* F#FP$гk.q  E1OC;kyQ!5>;;j0 Ad@%i#rxg"c9;ɱ A y`OWdGBC,ל\SHA y`O(A(AbZ} \ \ \555{{{ ***!!  \\\000[[[+++***+++ A6R™}yE(?[\ (`2;F;UO<+3Lf*pdb{" Ls Ls 5RReКe 5RR LsM m0^VeOPJﭰ쥽8'8C.(AP y`O쥽8'8C.(A x]1͒Ҩ^@K. W5bK M5쥽8'8C.(A wWط Y@N,AP y`OA x]1͒Ҩ^@K. 쥽8'8C.(мz3!1I;D A x]1͒Ҩ^@K. HfH5[\X;\\ \X=5[ -d\X=555MMM!!!!!!''   TTT!!!LLL===bbbppp! Ϡѐb"#зY/> <L[\ -`2Ż$-7nh |@  #IkH$]̠#!Uc i)Ȱـ>Ff&jJ F!u_S F 3e  aaa(((555LLLUHT6x ʠvZKu{NuFE;iǡϠp M9!+  CC%%ppw?sULg i:@;47.: w?sULg i:@;4DRk^ʝ fHBa!,֚f[RGw?sULg i:@;47.: w?sULg i:@;4Sn&G*)Sn&G*)N'T_EFr)$ ԝn^SHpb-{ Vtt&WO Vtt&W"_ "_ kb_8  qqqZZZddd˝j^8/ g[,, "+(girkH ߾A{)[ H@A\ H@A\^ ^ 9/d $$$QQQCCC ӷs}v"3=GFNT5)K4KiD'D'$*56IXd((^I\^IOAWOA^I\^I( 82F2F^I\^I((OAWOA(^I\^I$+G+G$+G+G&?&?(DDdd XX dd::::33   vvv"""hhh"""...NޝUtw =JVmThh\*P*4R`m  YX6"ثUUU  YYY=== TTTsssMMMCCCs!͸[y{@Ox]`=*<~k}\%I Zaf4,cmE 0WWW"""###RRR<<< >>>nnn``````999fffdEmYYtǢ][4(-2 \chm&&_ْ>!   ===222999SSSLLL!!!AAAcccMMMMMMhhhSSS;;;fff, O9NL"Sbox~01`Y _n0$)0ggg'>>>>( (^^.."")))888SSSHHHHHHCCC䨨>>>  _BB; ) GGGpppYYYkN&+!T*... zzﷷ...AA22 3v%vKKhh@@@ """***000888111111___茌@@@ RN (ghI8I8ddd硡222iM6) 4#4#;;FIIII???  ss㻻---999++J??? OOO凇     ((((((fff***??? 98  .!!!>/>/' ******......bbb......%%%''':::  ###WWW111???kkkEEE IG"*/===WWW )))+++ggg uuuGGG666???)))LLL CCCCXXX))),,,UUUEEEؠDDDllleeeeee999888;;;:::$$$(((222ZZZpppĻ999TTTMMMmmmggg 999'''CCC@@@)))...CCC<<<<<<gggʓ111zzz凇%%%%%%ttt!!!   ###&&&WWW111lll!!!))),,,jjj uuuGGG666~~~jjjxxx|||&&&aaa444))),,,UUUEEE'''\\\tttPPP&&&aaa:::$$$(((222ZZZppp:::XXXPPPKKK<<<999'''CCC!!! ...CCCKKKPPPPPPBBB^^^!!!    """((((((XXX  |||aaa!!!BBB&&&aaa444111fff&&&aaa<<< !!!&&&WWW...  ---???UUU#)))>>>OOO111ЅS['226!д:i| "B_xvKFFFFFFȲ%%%999MMM???͚_x*m{a>U,oݔJC~-ʒq{-Jd}i;w@up&888888ۮ !!!555IIIJJJė$t)Ѯ-^G-( '2dY ؊GA|,ⱄs 'Je|x1_"%%%wwwwww鞞 111DDDRRRZyE >\Ko='*5 OMSa'Ͼ!^CK͂ޖE="jjjjjj---BBBSSS /p/@@+<3=[<#S8Ц&f BjC ZZZZZZ***<<>> &L[&XX y)05 JJJ]]]]]]rrrrrr㰘.zYK翣·3)*.6R~i- i=9^mmmmmm򣣣///BBBRRR~~~mmm˚r^QŹӬfy9XtʣƘOeko0yʚ= ᯞ@8 Aas%ę= ڡ|3]]]]]]***>>>RRR***ttt@@@111$o# -V{V{:idڸu/Hu}; ֕o-0*ΡL/ ߮F4 &_FOHf>wFkbc3ڷrq+:્fh:OOOOOO³&&&<<t2 ~Be<  +- &JlJl*kbWbп BZEᯞ@8 {pgb&Iz>>>>>ұ||||||888888ᵈv 6TmGρkʫG •|3NsV& U(b(:ثG U6E{0#7RsxN" ѣ| 0Hj\. ŝ &1E[mn\<U(b:dU(b(:ثG U(b:dѣ| 0Hj\. U6WPǎ%Aan@wmf2 3~dHRwÖ;  0A 0 80'֕o-0*ΡL/  ⭎.it!Y2T}Ͼt3%...~~~999 NQr€k8ODNog?S@ZU6dʫG Ńl>K1dݔGU|ȏj?F+l#jB{$  GU6 GU6dʫG GU6ݔGU|ȏj?F+l#S^MIq: ѥ^{O^;;  .*kbWbп BZE0ŹӬfy9XtʣT)hѠ T!!!!!!!!!!!!!!!!!!!nnn>+ *?) *=#$@(   0A 0 -V{V{$p8ȗay 8DLd~V1װm}6 9h`waA*ǵ-ӝ:X% uJh|T.ձn9 9x DOkyQ,ԯl y9 lZQ[N-ӝ:X%  9x DOkyQ,ԯl y9 /[8瀲Zi!ᰡ8/ )))+=6 BBD4^b 5} &8Q&8Q-~ :G 5^^VV6`` AA,L}L GG-~ GGVV6`` GG GG <,?Y63 Y+: EEEUUUNNN޶*>]yB ; 4EEEUUUNNNU6dʫG U6dʫG U6dʫG ۓGM^`U6dʫG SFDm%,,,ϼr(((\\\rrr GGU6dʫG GGjUQ` GG`GTj+BLLL(((UUUUUU---U1w&#,`yfD' Ұ(|-yC^ApF!۰kArh*`[E3%⽏g~tKjEm{Q+ Ҭk:dU)bJ|T.կoE\D s|R+խkyOPSB[7 ˷Y@ U6dʫG U6dʫG \D s|R+խkyFX*bOxrP2կfM۞I$rh*`[E3%⽏g~tMэTddSfO+r/ U6dʫG ߚPSB[7 ˷Y@ $dHBs=q&(((UUUUUU---Le;b;llcg 3^PR̾5 .tSzuY:e L? /Z7aOL}::ǁ|Y7c OJG/9e[74/*'""'4Z ǁ|Y7c OJ;Q 6M 3^6MG [! .tSMF  /tz8Dȷ/9e[74/*'""'4Z  !;&8$\\hAA‰f;h3XY/+X,#{{ԍH.كǛ>  +X,6L hAA‰f;hΈU~ǒ]Uy2 7{{ԍH.كǛ> 5\̤to"4I^oo]= >u@*"0BfuI+ dݱW= 6SjF$ $0S9 6Pr·& #mϡ}Lx /Gh0ɭ #4H`˜5 U(b(:ثG ?dD!p:ثG U(b(:ثG #mϡ}Lx /Gh0%b},?tdm$ >u@*"0BfuI+ kI7 :~G4zKU(b(:פ.׭!zHUUUSSSu-}% GG4``HyHy]S #PP\g !Q^1bb7Z~7Z~ GLL G1bb GG GGBHLT `HyHy]SKK 7 G7Z~7Z~pqs  E99UUUSSSU(b:ثG%mmppp999UUUSSS!!! G"""UUUUUU333U6dʫG ʭubj&U6dʫG ׾}~47 U6dʫG f:j*ƚ? U6dʫG U6dʫG o>t2 ~Be< """"""UUUUUU333 &AiQD]A U6`nߕ#Kt_. •|3NsV&  4U~Ow7< •|3NsV& ⿜"1Hj~X) ݲy 4QiGߣ@YH~;i!wmf2 3~dHRwÖ; wwwUUU333ʫsd: ʝ!lMDNog?S@Zb(XʙODNog?S@Z BmBmPAmx:LTwj8Ćl6kN\@ ѥ^{O^;;   &Ajj 6fN҂= Z:ʫG ɁJKbR҂= @jGnpN2 <)  *="ޢ۶9}޼k" 9h`waA*ǵ 7j?Z.m9h`waA*ǵ. ж5 8FQlyO+ Ҭj:† `NM^A %Bؘ.g: %Bؘ.g: /[8瀲Zi!ᰡ8/ 999 GG GG 5} &8Q&8QGG ?ν5} &8Q&8Q@e0Q}Q}FF8dd BB``"ii"ii <,?Y63 Y+: <<<SSSUUU999 ; 4䑑SSSUUU999䑑MMMnnn...MMMUUUGGGMMMUUUGGG---\\\???\\\\\\֫vvvvvv֫֫***ͫ333333ͫ333333͵333333RU(b.Ebyy`7U(b,B[pwfBU6dʫG t)>Z}r>ۓGM^`U6dʫG SFDm%:ʫG wC@{,:ʫG ߖI=5 vD"vߗK<6 jUQ` GG`GTj+BU1w&#,`yfD' ҰC~iApF!۰kAŤ7%yC^ApF!۰kArh*`[E3%⽏g~tMjEm{Q+ Ҭk:dԦ\pO]P67U*bOxrP2կfMyC^ApF!۰kA۞I$rh*`[E3%⽏g~tMэTddSfO+r/ U6dʫG ߚPSB[7 ˷Y@ $dHBs=q&b(.Dax:Le;b}l=cg 3^PR̾5Ѱa:ylcg 3^PR̾5 .tSMF|zuY:e L? 6M 3^6MGylcg 3^PR̾5 [! .tSMF /tz8Dȷ/9e[74/*'""'4Z  !;&:ʫG 8$\\.[Kd@Pe8$\\hAA‰f;h3X ,Z=Xf 㳤@, 8$\\6L hAA‰f;hΈU~ǒ]Uy2 7{{ԍH.كǛ> 5S)))888))))))\̤to"4I^oo]=E@^=u\̤to"4I^oo]= >u@*"0BfuI+ dݱW= 6SjF$ 7ĢaB(u@*"0BfuI+ hI7 :~G4zKU(b(:ثG ʭ #4H`˜5 ۛu-}%222BBBUUUQQQ GG GG4`` GG 84``HyHy]S #PP\gBxBx GG GG4``BHLT `HyHy]SK 7 G7Z~7Z~SMQBeeeBBBUUUQQQ%mm``eeeBBBUUUQQQ+++>>>>>>///UUUUUU&&&///UUUUUU&&&LLL---UUU𱱱______𱱱______U(b,B[pwfBU6dʫG T2m5άRU(b:ثG U(b:ثG ۓGM^`SFDm%:ʫG ߖI=5 ӓ`_J/ GU6 GU6jUQ``GTj+B  Ť7%yC^ApF!۰kArh*`[E3%⽏g~tMjEm{Q+ Ҭk:d뵁xV96AmS۞I$$dHBs=q&Ѱa:llcg 3^PR̾5 .tSMF|zuY:e L?ґWEF~WdK0[! !;&.[Kd@P8$\\hAA‰f;h3X괁 y**ix @nT    6L 5E@aҤto"4I^oo]= >u@*"0BfuI+ dݱW= 6SjF$ ѐZEE~ZbL1 ?jJ!l:ثG ?jJ!l:ثG %b},?tdm$ۛu-}%gggUUUSSS GG 84``HyHy]S #PP\g1)x3mm3mmBHLT `SMQBppp999UUUSSS%mm``ppp999UUUSSSTTT...999UUUTTT999UUUTTT---'''   ... RRR```BBB  888[[[ZZZ       mmm[[[]]]111!!!IIIKKKGGGJJJWWW hhh]]]JJJ]]]]]]rrr... rrr枞hhh 㞞 !!!!!!}}}  !!!!!!ٻ''''''lll񾾾 ޫQQQQQQޫ444ǫ;;;;;;ǫ;;;;;;555!!!U(b,B[pwfBU6dʫG t)>Z}r>ۓGM^`U6dʫG SFDm%""":ʫG ߖI=5 vD"vߗK<6 jUQ` GG`GTj+BŤ7%yC^ApF!۰kArh*`[E3%⽏g~tKjEm{Q+ Ҭk:dԦ\pO]P67U*bOxrP2կfMyC^ApF!۰kA۞I$rh*`[E3%⽏g~tMэTddSfO+r/ U6dʫG ߚPSB[7 ˷Y@ $dHBs=q&Ѱa:ylcg 3^PR̾5 .tSzuY:e L? 6M 3^6MGylcg 3^PR̾5 [! .tSMF  /tz8Dȷ/9e[74/*'""'4Z  !;&.[Kd@Pe8$\\hAA‰f;h3X ,Z=Xf 㳤@, 8$\\6L hAA‰f;hΈU~ǒ]Uy2 7{{ԍH.كǛ> 5E@^=u\̤to"4I^oo]= >u@*"0BfuI+ dݱW= 6SjF$ 7ĢaB(u@*"0BfuI+ kI7 :~G4zKU(b(:ثG ʭ #4H`˜5 ۛu-}%...AAAUUURRR GG 84``HyHy]S #PP\gBxBx GG GG4``BHLT `HyHy]SKK 7 G7Z~7Z~SMQBgggAAAUUURRR%mm``gggAAAUUURRR111UUUUUU$$$111UUUUUU$$$U6dʫG U6dʫG UUU$$$\\\???\\\\\\ GGj>1e GGyyyvvvvvvm4U 3eqQ;1# 躅`{MڡhVTyX@+իh>ɀPvZtO1ʷ>X|Aqs&컎)r|Aqs&ڡhVTyX@+իh>և@E4]}{bC+ŗjg0ƈ3 Ѧov(OvnKCBr . 7bwG>> ܲ5  &7N&7N3꼞3q:3xBr . 7bwG>> 4ǮY"=L;Ѧ3ԘH1mk, ԜE3 1ֿGƇ2 л&l( 渢8z6 л&l( ˙k, ԜE3 پ$XAỾ>#䬬ѥhq1}Q)϶z\f+ ^Bq|#S*¨} qz( cs;e^I4#!IM%ֵJ, ֵJ, 0^Bq|#S*¨} qz( :o徸:'䬬Ѥ"ɲ`=__> 6QzQz]] 6QzQz*y h䬬УVzU6dʫG WC^MU6dʫG ... ;ζNLZ}+ž&@bm?罓1Mn~Y, ơ%5IdvsX3]0a LΫ< p5R.h_dž1 ]0a LΫ< 罓1Mn~Y, NEiVӔ !@bs?BBBBBB绦[2nSuMHo•: QLPrMEw5n?6cFX;K* 7zBrq&FX;K* QLPrMEw)پ>{KxMGt5ơA BBBBBB绨D[!,ەa2c$ 5FuY)w -24@XnlP' طH/ӣ U"طH/ەa2c$ ju3 Ҷ&X. BBBBBB 溧 gcb! 'ޠZ]`%:nnNS~6 :cТVp:c 'ޠZ]`%'u Ω!W9ͫZZZ溫MnqB~2> :ͶU6dʫG U6dʫG :::e GGj>1e GG«m4U 3eqQ;1# 躅`{MڡhVTyX@+իh>ɀPvZtO1ʷ>X|Aqs&컎)r|Aqs&ڡhVTyX@+իh>և@E4]}{bC+ŗjg0ƈ3 AAAAAA«Ѧov(OvnKCBr . 7bwG>> ܲ5  &7N&7N3꼞3q:3xBr . 7bwG>> 4ǮY"=L;AAAAAA)))888Ѧ3ԘH1mk, ԜE3 1ֿGƇ2 л&l( 渢8z6 л&l( ˙k, ԜE3 پ$XAỾ>#))) )))ܫѥhq1}Q)϶z\f+ ^Bq|#S*¨} qz( cs;e^I4#!IM%ֵJ, ֵJ, 0^Bq|#S*¨} qz( :o徸:'ܫѤ"ɲ`=__> 6QzQz]] 6QzQz*y hܫУVzܓI^苾1$.˵0Tty[. 䵵aڛs|L؊Fc/ĵu1ٙ[P=YXG0ȡ(? hL?[n8Tn\<\ Soooooo䭭!OfY taS"!  =Sa=u@xwG[FTMM: Fkٹs O[ oooooo䭭ï 6KXXG+趄ɨP-CCߘJNQH4 線<{HV  oooooo#) ܻ1SkjM' ٙ[P=YXG0ȡ(?bJNZq>ZJJwu .194 ώW];M  '''GGGPPPъXSFfLf[1 L.ޛZ[ !U[ ! +>H+ '''111999,,,WWWWWW@%:I76Ȩ!0׻!;JErs B"ee (((000:::***WWWWWW%rn$)H_)H (((000:::***WWWWWW ! (((111:::(((XXXXXXOOO (((111:::(((XXXXXX (((222888(((ZZZ NNN   ]]]JJJ]]]]]]rrrrrr ^,â,IENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_motor_read_state_flow.png0000644000234100017500000671234312174204305032304 0ustar cpascualcpascual00000000000000PNG  IHDRl2 pHYsE:SI7  Ԋ LK8K8&{jP{jW_-Ӏ{X- ZRe555nnn@@@666+++s nj8ӀtӀnnnDDD  '/7OOO+SS۾DDDYYYSSSggg/7]]]e7 .,,,,Q[[[zzz  ...ڥAAA!!!\\\DDD'''hhhYYY...{{{mmmeee...y*b7[sur7ppB-yxxxE-3uG JLftWƺ:F HHHHXjҍ`.[wīƮǣx9]z6F%1Eϖ;a.YYm) )<  Ci0Hu GD'V FM6Uן  Gм) G׫222 ߗG!i0Cнm_= ~H(x,#g*`R7ZG GHe>mU)U׫/f͵d˓ItR=x)tItL999^^^PPPssssss\\\tttttt GD'V ʲ0#5$d= ;)  d=aaaaaaƒ:n[Klll:nKkkkkkkUP墰2e/!!!^e/F8v7o㿓Am~~~ȊPPmhhhhhhbbbbbbT&&&;;;}I/,. 0-$4ߐc5888TTTAAA>>>p}X ճ /, 0- wݙt ]ZW׮888 +++u- N+M+^w/nN~pmJh6 BB[[[ bbEbbn=I¶~@ @ llMBdddEEE ]]] ¶~@H~@' `7WEvR BBB(((```rrr]]] @`>& # Ս VzA$@ܿ@r'@ٿvbRREEELLL&&&666NNN///ͣ!If؅`zaaa222???:Kh 0DD$$ڼDDDBBB333???TTTe7 7\Q'''<<<'''999LLL[[[222&&&lllmmmDDD)))'''%%%鹔TcF&K}hC{,'B&=]ã  {,ؽkãlllB9xLj>b(N/ζlll222ðkr}w^Ad ɥ a'W#!aЪ;K$=KG GYYp28999O/`.ʲP0 999Ѡ U)U׫G H߸h!eB併ä|"6V ݮ$lKU)ͫקR)UwTR $ě׫e>e>aa׫k"/8em|G_DA8EG >xxnB (((LLLnnn >>>>>>bbbSSS(((CCCbbbP0'G !.=U#('( { 4 4Wk+W>}P2x!]2g4 .WҩM /5/F[QF OOOjjjjjj ___ JJJ ?ySA?93 #r$u*```uu44!!!))bbRRLLL00nntt,,,q||O,"$*+˝*3I -ݲ]ZWOO000uua|| 999 :: :AA ,q||10AJ<)()S"q(ۮ%RAA퀀`  999 KKK(((>>> """"""BBB#10=$ss)/5[r2lof}nhzLS [%R~p 퀀lhʓlhh6l BB RRR"""NNN vc[bggn &^fq[69 8 s59 8 r(wlhh66h6h B B RRR333 !!!MMM.||LL   ,,, p/K`.qATcs_ ‹ L K~s6~st1{LofyNof_n`BSx5jwibo|~5jw(`A~A3+Ud qRR(RRRRRURVVV000N//000 L"c!d,<nX_q^IlN\h /\A4O\An`BQjgRG2BOKd)@bo`wp|~OKd)~T֧owJeSUdnRRGwuu*RRRƛ%醺k꙳Lb`^M/...@@@LoHVb``A#O5&|$|~`p`|$|~kf*YeSHGGHG9 ǔ<<<zzzCCCpOwVb l=FFFvvv+\\\f00𪪪RQ\\\222999999[[[......eeeeee!!!===...vvv******fffffffff&&&lllkkkBBBQQQ)))ssszzz888...'''ǎ{{{<<<qqqqqq...999999<<>>888&&&'''UUUH+ђ(7v+{{{nS?lU½6`yyy^rxƵo& xx??!rrrALoHB@_!189KlᴀX`&6Rڽk(b>.$^X7:!/F|(b'j1<ǵL|ܒʲd< 4LLL $n ; 4 H<LDłmI̳w]xf+U׫9ił Gm)^OlأiVCJ2iΗHUnz׫Ǘe^@'@ثΗ Gm)G Old Gm)z=G U)U׫ ;; #l 222U3DzeM9u⬕K4,OG M9uWYXBدl2EλL>/$3F^rh\R,ZԦeNj4G Nj\\λLG {7էzI(6U׫M9u/@DŽG Y,RԮMF׫NjG ԮM000GGGggg EEEEEEG Old Gm)߽('Gb(8 @'@ث'GG W׫JYdJY888&E_Yn%R"ؠizHkkktCe&І%r* 71 JgRC[&7R.[ҥi_Ry (G2(@X(vlllkkkee}}}7ҥ]GGGGn5L˴9AǿqW&B9|DŽ˴ǿqW&DŽ@;r[Y]dEZHl'Nv{9!6CDl#'AAAOOO AAAQQQw߅>HI***______OOOCCC 𰰰TTT:Md&p ϶ ք 7B>$z ___,,盛-- SS ==AAA EEE <<$$$ CC% yyD~O,> (%T>ԁk#"*5j׳e7 ""]]NN111AAQ""ee~~?\\D``jj3#yy+ӫ>o9 --,N Gwl~#11&&&+++$$$  333 AMb}(-ƦT*ˎszFeI\r{GGG+++   $$$Mm)"W*$ݷD>dd  `vNOO;(RTR"""  )"aG.9B$^;u MMr~} }P@1`@1`^ssssR+++ +++...,,,_E ##lR^j"f8 f8Hȸ `YyO RWWW$$$+++  !!!rrrչܸ 8?qq111PQ")/>r[df8 j/r[d_O`~ ~ nO0 a0 a***|||hhhH$HpqǍs9sCCCBT>EhhKg@\0 f8\# ttt555ﭭdd'飣UU 88001$$$ݣ6o6tQ vS f8Hȇ 7x0fCȇ 7x* (tyOS\\ :::!!!dd]]6$$$$$$lll 2') zl OM?ȸȸ{fC/ FBOP5jw(5jw(A3+Ud ofel_yO!)ofyX϶g U=_n`bzRb t>JJJ :::!!!sss)))III&&&lllNNN 2'ֳ ߓ OVtclg 4iLh! ow-Ӏ@ow-ӀUdq9jb3O#6j80U=n`MJ 0&0cccHHHD&&& M D[:6Odd> i`X>7vi{x4$? OA#4$?*mOO,gLFkt  t  ```AAArrrʆ ջ/ ¦0 ((|$|~p|$|~GO(A#(*O,}jO     Ӻb;/ٲaq ""###ooo444333+D\.!FBBAeeevvv%%%P+xx'''EEERRRAAAbbbdddzzze7 IllYYYfffw&wII aaa===pppppp***WWWTP0 \\\aaaccc......ooo444Ъ0&&&'''EEERRRAAA+++zzz!!! aaa333ooo333nnn&&&'''EEERRRVVVZZZ!!!lll***ddd&&&!!! OOOwABEI%Dv '111.nB (Ji:ZQ#&7" p+++i!8%~?LO/MѳY<<<k֦ב?ϙ^2˻YC(PPP -(ثtV ť&؞(beG5  !/FϮ0U>.$^d=$$$m)J'UZlt;QWn ;Z6011:xyxd= GG٫ 6GW׫JYdJY{ 4jjj 4kkkkkkMMMU)U׫õc :!/F|(beG5M3mΓ GD߼i!ߖD!j=a|WF3n؞ GY-Wĕޏk^NO^׫H͒WG GM;^:L^tttVVVWWWR%%%sss7<{U)U׫ G $ Gl2Eλgw~>/$3bl2Eλ 77 U)U׫M9uG D,O44 G3GXĸ $η,ʹ~#7 CU,!!tR=N "6V1(b: 5 LQqqqqvvv GL׫HïH%KKKNNNOOONNNeeedddddd15U׫}|YU)U׫ G$1+ wW{l2EλY$D /ᑋ#戫,٣1>G EU$C jjjLG13mG$kkkkkkjjj555 &&&...888333DDDZZZvvv ///HHHddd)))kkk!!!===XXXAAACCCCCC vvvvvvsssaaaaaaAAA@@@h :!/F|(beG5ˑrn&6RʲD߼i!kK6l]z{:l1jϖ;h ؞ GY-Wm .^m)^NUu4VأF8N1Ȥ;P gWG xGGM;^@'@ثz< )))V>/NN/!.3\ }W63: ĒPb-2Kʟ.P:  S(a싃Xahذ'Q2  9X:,!*;^n_Q]-UӰZZZ 2!ؚ=Ӱeee[[[[[[9| 1J(@eeeAAAZZZ6 :d0OЮ< rd͔Dqqqvvvuuu6 :б͹r&777Cn}VV~/777_Q N1 N%AAANNNQًA'u( 1.*y4 yyyRRR'u@@@PPPjjjjjj>>>yyy OOOVVVSSSkkkkkkUUUFFFPRRR444000  NNNMqͼV  d> k;  &&&///v  MW % @7/    ,# ] WWW### """!!! ߾bbbHHH--- EE oo  \\---  x~g (*-(*Aޕq\=>,}]mh    P T.} rF# oomm3__퀀$EEgg rr  aaccc 00III/// UU}}{҅V. t 4ؽ)D !. $"ʺ.S󠬹O)S } ޳\YVss Imm``սՊa111~~"""gg== ###:: ::[[''!!!III(((!!!V. )Di^sPTns|C0tX LMČ: DtE'7' HV000??????FFF !!!!!! !!!!!!>>>{H)#@INH^snflsSO/:tB$(E3\\22OO򤙏n/r~WAyOA -sS `Rs \BBBHHHFFF  777  ...BBBF ]WWה)RBHBB  r `ۭWvN{=hC{=hCAyOS;{5{5(ZRRZ\:::((( &&& ''';;;aaa!!!  bbb--UIS)s),~ VVyy%Svۆb \\\PPP ***LL!!!!&&888!!!+++EEE aS"Y·3>EKxڦm gC"! LL LL )|"} )|suٕrQ\lU)~\lU)~A ^l%+DVn~uM5F\lU)~Eq^M`/%-?M.TJ\lU)~ޱjL[KA ^l%+D\He_FR \=h-e_Ff\=hsTTTXXXtt333111!!!DDD&&&---EEE - K8G(roh kphJ_b}}$?,8}$?,8o{H#f&_uJ}$?,rd]T/S8TL}$?,8kϬo{^y{o{H#3e {F ~\qsb {Fqs,,,SSSddd?GHj: 3=F    Ĩ%9MtV㬣oKZgzU3{*|o3PyOzU3{*DTyV5(:XFzU3{*|o3PyOzU3{*(U `|FQyx!V]X sy7vJ VRJ tR tRu%'''""",,,$$$ ^ ch{ ԉn+4   +)%$  $)@U fwLZg((((oxqwox coox((qw((ox$+G+Glu&?w?dd XX dd::3 ggg www333000QQQttt Z\{I0E ,27wyh! ((("""&&&SSSKKKIIIjjjrrriii lL!) ...oR) ܱ톆 f00}}Q__ ddd''' +++GGGdddddd @H88wZ$$8[zz??IIII^<DDD yyygggwww333333iiiXXXXXX  @HNNN"""&&&SSSKKKIIItttnnn;;;  ddd''' '''IIIkkkPPPPPP111DDD yyygggwww333****** yyy}}}ssssssNNN"""&&&SSSKKKIIIddd---;;;  III @@@(((]]]]]]111DDD eee}}}iii KKKKKKNNN;;; 111 UUUU.%`qthMiiiGGG!K4).'NA0!0[ХDл$92aBo J_  xxx666AAAɊ4֠]D:\z8+3IͷbD=_(((wwwd̮?L7-39~꽄x*-Rm `-?>~-***lllHHH111GG GG GG 22 ~&<  SS x*h$n `O D#l*@@@g Dj5X(Z6RʮZf->N5l˔Ig"fAj?ζ 32iΗ @.///wc‘|{OS[F5ZG\% &=jЮ`G\%K-BG\%]x) [88\eee '0&)FtG 5}S-\Ю,-\eQ}Q-\8Qq<Ж;sssQQQ U)U׫U)U׫GG n18U)U׫~&< "Kxx###222R+\K(Z6RʮZ XS4eÊ3v. X:K(Z6RʮZ4N5l˔䪟&bVf-> 32iΗgOS[F59Jܮi)ZExgXSr5@'@ŠQ.y- Jܮi)ZExgXG\%S[F5Z /^i!K-B{X>;xVʼn &=jЮ`8\ GG 5}Sy!F^dd AbL}~!y!-\ 5}S i eQ}Qʼn׫Ю,Ж;jjjrrr111999U)U׫ڿpCj&֒K:4>XGG GG f-lӚ?GG U)U׫n1882oΑvvv999R+\K(Z6RʩC@z)߮N5l˔K(Z6RʮM8f? 4ų3; wwwvvv999&AjAgOS[F5U!uRMyʋ=G\%K-BG\%S[F5Ⱦd0dМA %Gn;B /^i!ᰡ/k^uuu׫ GG 5}S(ʋ-\eQ}Q-\ 5}SМA"n"i i "ktttVVV VVVU5°7[iu>ۓBiGG O([:׫7<|OWUNYn!шO=Uݣl9̲Gu@ U)U׫Y0;sТMGG xYn!шO7ع%sv\'FX"9zgńYn!шOAڞ;Y0;sТMI5p:IʷsL2>{q`9Aǿq|j bVS//r!3(e=д}M ۉ//,\f 㳤,g\ :e=$)ʈ//e=д}MhQPgf+׫ GG\ ,t>ճд CU \ f g׫׫&cC.д 2z:: GGӛN(rKKK%m`a]]]iiiddddddiiiddddddѨUu@b(b:UG (Oر`Cm%T U)U׫r[voьI9U)U׫xYn!шOATTSGU)UA>ؿ;x&g7 4 =%G ۉ//CcSc.S   8 g7ճ >Z IGճ\ҧKKѯ AQ q(Oر`Kc3jjjر`mkkkkkk555 555 *** 777 888}}} ,,,,,,RRR $$$...000,,,@@@ ###,,,444(((((((((000 ###***666&&&******ttt 222@@@rrr/GujB0GGG GG E-MĞa=[Һn18U)U׫~&< vvv R.',T{w N5l˔K(Z6Rʡo³n湼<5 bV(Z6RʮZ4N5l˔䪟&bVf-> 32iΗwwwvvvf؝]8iG\%K-BG\%S[F5 .O7Ŝc>v( S[F5Z /^i!K-B{X>;xVʼn &=jЮ`8\ G֪Gx-\eQ}Q-\ 5}SұӽG GG5}S i eQ}Qʼn׫Ю,Ж;aaa888)))UO.WҩM)))n5L˴N:P WB |ޙZ{4 ڍs0)))˴^6 bmd0Oб11rWud͔]g&s0nnn^6 :e б͹žj28Ge[[[{3I< lԯI[uèYer0&QD GGG%%%g1b5Z 2M#PG=R}m}ݏT ?{QGGG}}}%%%fg =R!!.x.VBD\3+_Іit@dp%R1 tUC蜜ʧ 0WMȯcIlK-20͵Z/xO`%@^vvvee !SS(aaAmm؀ /f1-x ttttttWWW{r{:hTP\䘯:2&Hg\`/NѲL&hڏ>@A@  $>XehBEK9C=2&~Hg &q•׽ ї(((KKKooo+AMϕ+T;D:=8 ʩL =*Ϙ_ZO(((KKKqqq///### BB͘(((LLLppp111JJJ˙(((MMMqqq333///555555$$$EEEϤRRR 򟟟ZZZ ---000 AAAF Mw   r  @@@eD! Wg     H1 L  v,izTX<1ӕ麺487"g     p AAA---BBBfffyyyDDD...<<<BBGG __ SSBBBzT{t[u]& )&e#"ݙg     mBB )) Jaaa 88JJJ BB,, kk >>..쯯rrr//00066**6D\--쟳`H";FIK    tuuu#UpV+mmhhUUO@%% !!!,,%%%***CCMMMrrrss0.7DOG < J@S% FIKeb^nh*DDD1rlifpU8∈xxUUUUUUQQ((++  __%%000    4> 7 hN>=WYggim!/- eb^"%)'www,ЦeF aI %ccc\\\䠠``` !!!?vɔRpWCphqxv8sK?>aaa8ceG ]m8= s4555 """ ,,, 666...((("""ɔR@H%W +UVOXD# y/"fBIQB-AzDx#̺wS nO0=J wVVV   !!!  !!!|JY/5yk#%mܕqy+][Ppfd7_ P VmfN55ye_,,,  $$$ !!! > ) iG,I$qy$B w7(o6ޏ_'iK-O!2AB llr÷{ =iA -sS `r~WAyO\RR  )))  555999) ^>Wc[n$d,_+"[[[q %Mx7(H9CM iK-!?98 r'yOS;( `ۮWvNA5!!!??? %%% 888!!! !8oKWbk|YF C k{5{5{=hC{=hC`r \\ r Rl MMM $$$ 444444;;;:::VVV$$$---...!!!ttt"""***nr55~ĄfW𢙱Kuž(Jn!+2/ñP -;?Ps0 Ϡh6?Ps0 Ϡh6r~CC^R R R''' ''' ;;;!!! NNN{{{oƅiR Q^i ajX5^yOh& '46h& '46 `77E eQQQ+++    NNN===ddpU=I);jgdp߶T,<>|9 26< 8 ff@@j0 IX0 +IX0 + ))   &&&  JJJ **'? y8/Qg}̞&,0FwhfDȸlbdmzalbdmza `w< w< R-oyORPb RRRR...   bbbgggEEE  ˓m6m&&11100|y}77IIݦ_] *MyO ȏQ+WmqX8 f8 >ȸȏQ+WmqXfDPuv2{XG(퀀((jj%SS XX  !!!777 ***@@@ػ``ee55m6m--q܏$$frf"E|w[vG뿆:%&&<# 6($iCݙO !:vPsgEǷDݙO !:vPҎL߻Gnnn(((---LLL???++,uuDD EE?''99 NNNee5.(EcIx, V@.x  WA[iU qigPU qigPkP888 (((  LLLuuDD =##<<KK__##"ss穩"""fk SH- b'Q97=* h0eRF'n{('|||  FF 88+ 66jj1II !nnn)))0000 mmmZ{id2<k;YAHd8y_O7^y#m Hd8y_O7^y#mA 5tKyOW Wac AyO `v)R R 555!!!PP ee 88 !!!BBB ### 333***MMMBScBBBV`m).3 RaOvC!*VrP.jcLE>ȸRaOvC!*VrP"Kɱ `WiknccS`A(R RR{{{""  jjj///---LLLƒř4NL,/%))+5 ŖqssA Aϓ̼wxvss9r9q0ed9r9q LLM)5`G8PH.A ``G8PH.]*:RNi.Wx c`G8PH.KGbSk,A `Apx}ón` `G8PH.KjlD ]*:RNi.q\fr;\\ RqwR555!!!!!!::*** 666///666999111NNNppp;gD 芾= 999)+!&*2 $/*#V#@KRQQIG=YYY'''YYY===sssppp<<<8iIkKpAKW3" &&&񵵵==WWW111""":::mmmRRRQQQXXXqqq sSJar[`HHG  &&&RRR444S: -'.{{{```)))俿,,,.# BB " "GG""" ;;;lllkkkkkkJJJ ߇(HH&&&&&&cH H$..ZOO}}<<<O ::RRlllooo777"""444___AAAAAAXXX<9/(JJJJJJtW"""' c?NNN00LLL~~DDD"""QGGG ^^^!!!!!!!!!111 kj%2 XXX......FFFaaa%%%YYYYYY===%%%CCCMMM!WWWWWW111""":::mmmRRR===QQQXXX&&&RRRaaaՊ555 """~~~777JJJNNNlllooo777999YYYUUU &&& ^^^%%%!!!??????ccc%%%YYYYYY===}}}WWWWWW111""":::mmmRRR(((ჃXXX&&&RRR>>>˓555 }}})))"""dddvvv&&&kkk]]]>>>,,,,,,hhh%%%WWWNNNXXXMMM555 &&&>>>++++++666...|||TTTX=ܪ?`p,'''vvvbbbFkpt幛$|ʰ|KYҽHK1hhhhhhoooqqq߭n]ZgJ at-xHKZZZZZZeeen0l5Q4PaD(Ps 0\ϡWL0?FJJJJJJvvv```b|1{$?kTd*ݢ*By.- 888qqq WWW5``LHBj*LDeZz^B(((kkkQQQ,TTuiZ'b ^^^HHHLuLuR1*Kqsҳd iii@@@,,,Wx@L䍽+;gvvv999>>>-vqQOҢ`_/;л$92aBoZb6|i- 000MMM999қa>9DTZFM`^77""Aa ЙfZj{K||||||***xxx]]]{{{.e+97Wɯ|ЇgH$FeEoݔFnnnnnn"""rrr@@@U)U׫U)U׫U)U׫n1882oΑ1ƈlU (dѮ榞7, l______%%%AAAW?5(#׫‘>ZMW&UG tV$;[]G ⾓D],[YUG eG9ɲ fd xx ЕM.3' >֫ݤ 666lllnnnK;)V`MofU)U׫^ U)U׫BmmU)U׫K,6RʮZ^N8O^; .3'k+ZMW&kL?) ݱCj[{>PBC_ d0(b:kL?~'G ‘>ZMW&wm~⾓D],[Yo636rʄ(btV$;[d xxxhlVMof N5ltrijBy؞GG  N5lU)U׫`Mof<BmmGb;X ş؞^ O^; xxx 6҂Uf-@'<) *=ӿ"Lj>Y-@'҂U 9mb vYw =iʒ 92:fxڹ4Я 8DlJuJuSZlMaaA8=j>G\%4Я-  92:fxڹ[8 TCugU5?󿌾ss"ᰡ/k^׫8Qq@Q}QǖЮ,-\eQ}Q~8Qq<}3 !y!?7? GG AbL}Y+k@@@ ;3ϒ@@@@@@rrrrrrqqqrrrGCi?</GujB0G U)U׫U)U׫+<8 U)U׫GG 22 ~&< vvvqqq A U)U?Hӽđ>ZMLi wUG ⾓D],[YUG ‘>ZMW&ߣi!wm~ 3~mjϖ;wwwvvv fGxThlVMof,uT{j=U)U׫BmmU)U׫`Mofچ{qr[voьI96$BαFB̦7#Iȹs;IK&BαFBqr[voьI9c{H/ U)U׫Uݣl9̲Gu@ dH&b(T7V4:cp/9[^e[QL.;-%yF cp ^cp5 .;-%yF /x ˍBoaNVcK !;&G \5{{?-eӛ qd\5=@Z\56qdU~7UԌt> .MM0@{ 0ZʦO_v#¾ ?;!p6i=~+G M0@{ 0Z7]B0-̽M0@{ 0Zb},$ >i=~h4 3h͋(bpO=\m͏___qqqvvvvvvvvv GG׫4``7ZZyyL4`` GG GG4``B7Oر`yy ͘KG~AL``````___ر`X.``````___***+++***++++++pppddddddZZZZZZZZZ[DA^:RgRUG (b:ۓBiO([z=U:xGG GG R GU)UUQm`eBG8fG.DvxY0;sТM6$BαFBxzId$ԃBq??ťZ!Ɉ: tS<Mcp5W}EF0;!&yyI#;[pp: hA'W \5ꬁiSiT  L 5^?2&-÷ ?;!p6嫖l*3V+ ?;!p6M0@{ 0ZTzT ?C!l5BG %tm-}bnnn:``H4``dž3mmQmSM@@@%m`@@@JJJuuuuuu------\\\%%% !!!111lll !!![[[!!!!!! \\\\\\"""###!!!!!!***###ccc LLLxxx,,,  '''111333WWW """...222***AAAAAAgggdddWWW  '''111555******@@@ ###+++444(((EEEEEE """'''222333,,,,,,\\\vvv uuuWWWFFFFFFWWWnnnnnnrrrrrrrrr֒K:4>XU)U׫U)U׫׍LQrr(22 GG 82oΑvvvnUUG ⾓D],[YUG ‘>ZMW&jxsygA*@‘>ZMW&wm~⾓D],[Yo636rʄ(btV$;[d wwwvvv˥W>))îU)U׫BmmU)U׫`MofߍύI4m@w`Mof<BmmGb;X ş؞^ O^; F3n͒9mb ҂U// ҂U 9mb vYw =iʒURBBU-  TCugU-  92:fxڹoGQJpS\ 92:fxڹ[8 TCugU5?󿌾ss"ᰡ/k^(ʋ~!y!~8Qq+xw+wu׫׫8Qq<}3 !y!?7? GG AbL}Y+k...III ;3ϒIIIIII~~~~~~.WҩMUOƝw^~<^p%Rh,SP^S$ +k_ІtUCIc7ܴ ,& 1L,]Sԣ9AǿqJ(CA9|DŽ 5I)"Q' ӣ2?0R H UP QK8rQȎ6lmAlVL6sr&XXXغX]lƽll!0͵Z?\3t7 05!/1jA%@^ XXX(F(aa͇X AmmXXXGej28iii?jVw3lrVQwu`IɍN!w*)d@XSx.iii  No꼞:XQj/kv3cHV֜FZxuuu1ɘ1ԿIrχ_XG>yyY##8c6ɄEզ..._U/!I T nw 8}VDvֺ'dj'VVV]<ņgrJr =R շ8Nj8VVV.WҩMUOƝw^~<^p%Rh,SP^S$ +k_ІϠ=P{,gzHZZZIc7ܴ ,& 1L,]Sԣ9AǿqޙZ`ڍH0FFFZZZ 5I)"Q' ӣ2?0R H UPU肖sFFFK8rQȎ6lmAlVL6'qqqvvvWWWغX]lƽll!0͵Z?\3t7 05!偿J6) ~d@vvvvvvWWW(F(aa͇X WWW UUU@;v,gIDs/ttttttvvv؀ /zt=cPP\9:2&S0dܿA;stttttt¦Zx:v@f? F8v=2&|@@@nttta9F>Z+"H M78l{I6  (zoj\ї'''KKKppp*:OdWD7ile ks/pȌ7K:::\\\TTT+uu<. /^:Ka21x ͯL:=8 T\\ϙ(((KKKqqqhhhhhhc//JHʲ =츷%2.# :Ѷ:+FA:::^^^RRR>HIϘ(((LLLpppjjjjjj:::___PPPHHH͘(((MMMqqqkkkkkk;;;ZZZ:::___OOO222ggg]]])))NNNooommmmmmѠ///"""***CCC褤((( AAA_| l&&&bƙ# ] W /// >g clT7?J  ~   {GP+  111NNNٽKKK(((QQQ ﵵfff j}q!#7/e:mS !bxY     d;h9999!!!++G)) %%%&&&>>%%%``!!!yy IILL &&dd '''222 AAKKMMM }};;; !!!&&&ƻH޻m%߾!-0C(?clWN 4;Aw[jP       :%Q + ,,;;%%؄لCCz'z//333kkYY FF  --UU>>>bb jjj>>>!!!$$$  &&&'''))KK&ȯÁq ! %/i%|g|g~~~#-f jp\j30555쌌HH2225DD%%%88XXN7N,,, 6666  ))777 <=Wyxw\ho+ gC8晙AT'[+G98G98hnn ~~~->Rp`MqV`  *** '''%%%,,,   ))),,,&&&))) !!! V"zqN[ ^?84׵ʹ6̼ i[a#CF#l+Z ̶Q=&,9675  *~~~%Is'mI4` yuk_ " "B ƒ2$ v444999뼼>>>!!!  ///FFF///:::  yеٷh Y9)KfKf>^^>^e(4J{411/rxy3+(:fTwh1# 239U 2u  r`E HT%`% & G) 000  ###!!!bHNT%di1g0Kg0K U)D  #!Һ?EvwjkndD'@)z4ZM F}\I5 g 4 Ƚ9LkN5dثWak *A !>-:|6%"A y`OA !>-:|6%"A y`O\i ((()))!!!000   '''  XA!]>}'>]EKQ{ɶvv ͓t ``a.3 y`O{#-\S$(A y`O{#-\S$(AP\  ,,,'''!!!###   666 ))) &&&nn4# ¿K>J ]_) dABDIih}4X  {l5;@ G /4C4JA(9L$K쥽8'8C.(쥽8'8C.(C4JA(9L$K쥽8'8C.(쥽8'8C.(jAn5[\\ 5[\X=111&&&'''  111!!!''' $$$___!!!///---333;;;((( gHOdA%!!2(! B-sӺ6Ÿ',2  z*8;̠#!Uc i)Ȱ?[7%#h]r%?g2Ŀ.K8h]r%?g2Ŀ.K8P !>?[7%#h]r%?g2Ŀ.K8h]r%?g2Ŀ.K8jn2k?2k?z&&s||| !!!  666!!!CCC  '''000 bbbbbb}}}}}}SSS]C ##&&Xc@ ̹.16#YA8#վVZHHw w\ ||/"8?D  y`O y`O555{{{  !!!kkkkkk===Ԯ```$$coIgqwkG G +R""+5=ʽ2%0.EX/i[Π|l$)-4:""  DV JP$}~^>j0 DV>j0 w?sULg i:@;4w?sULg i:@;4Sn&G*)w?sULg i:@;4w?sULg i:@;4Sn&G*)Vtt&WO Vtt&W555ccc꼼  444:::JJJ|||AAA]]$G""z݆##222n)T-:EXbC5no~ݲSz܆qx˔bS- lps 3E@Ḇ>bŅ=lÔ 5c/룽 80QD/* 5c/룽 80QD/*kf|Gսj1 y`O 5c/룽 80QD/* 5c/룽 80QD/*kf|Gսj1 y`OH@A\ H@A\MMM곳888   %%% ///!!!EEEeee TTTEEEFFFˣ5}܃$%K##Y%mۓ{{222JCv5l Y] #k\gQ^m@a<ÔͰe?%vy DV–E >j0 Ͱe?%vy DV;\}>j0 (^I\^I^I\^I$+G+G(^I\^I^I\^I$+G+G ddXXdd ccc111 KKK ..++< bbbbbbXXX###{{{QQQ55$K%K Yےݺ1A\uP]CHU,,+  !%W[LZk"}Ji2f=&}qJKzeg LsEW>j/ f=&}qJKzegŬjƜbbb)))... 000DDD  %%@@O**cc ##4422 BBBHHH444BBB JJJ244ؑ~(oyy* F#FP$гk.q  E1OC;kyQ!5?;=d"g 5?;=d"g 2UtM vvv 444  !!! MMZ!!!++&DD   %%++&&uu MM "" !!!!!EEE(o* 꿰ޜN= 0UU',!2Kě!G  ',!2Kě!G vvvhhhccc(((~~  ;;  ''.. ..44466  ''$ ,,, %%%!!!ggg|||QQQ(((999tttcF LPӶD2#6Skhpd ~Ngr6%Q&Ad@%i#syg j0 Ad@%i#sygAzil) y`OA y`O롶c y`OA y`OA y`OA y`O \ \ \ hhh $$$UUU###xx00jjbb --111񽽽   <<<  000BBBQQQA6R™}yE(?[\ (`2;F;UO<+3Lf*pdb{" Ls Ls 5RReКe 5RR Lss)hd3'84$l|n(A(Az \ \ZZZ!!!)))))) 000444<<<MMMIII+++***! Ϡѐb"#зY/> <L[\ -`2Ż$-7nh |@  ;EKԗm*t!U{=cC5AP y`O{=cC5AP y`Oꈰ d`^o{=cC5A{5 _^n"AP y`OAP y`O{=cC5R *jUT AP y`Oz \H.\\ \lz  \l \\\999KKKK!!!BBB000 $$$ ###***---QQQ0" B+(R?$  w cC)#-5g t3+z(B<7"*:rG'# t5H4  (D%B$CnR 𔝚?Pr0 ϡ!6 f6(A y`O𔝚?Pr0 ϡ!6 f6uVRC𔝚?Pr0 ϡ!6 f6o'ơioJ7(A y`OuVR𔝚?Pr0 ϡ!6 f6\wh|2UkB-uVR{lB{$t \ vlB{~!kzQQQ 111***... ;' a%/-,$Ǐ _gks{hYI?&]s}I5 !3Opƙ85h& '476h& '476K)6X h& '476o)"K)h& '476-K)44 7e44 seMMM---UHT6x ʠvZKu{NuFE;iǡϠp M9!+  CC%%ppqIU0 %)IU0 %)wP2Λ.j]lIU0 %)IU0 %)    SPUm+ m|}B B  #s;bbb<<<222j^8/ g[,, "+(girkH ߾!   === ))),,,UUUEEE먨(((KKKllliii111???!!!, O9NL"Sbox~01`Y _n0$)0ggg ""+ +,,,:::$$$(((222ZZZppp߽ 444IIIKKKmmmmmm???ɫ|||  _BB; ) GGGpppYYYkN&+! O'))ee ddHJJ""rr999'''CCC@@@ ###---DDD///dddddd___JJJ RN (ghI8I8ddd硡222iM6)  `6 FFF|| NNNQQQQ߻---999;İޱ '' PPPzzzaaa ***<<<<<<[[[TTTggg 98  .!!!>/>/' 44444:::::((((PU,oݔJC~-ʒq{-Jd}i;w@up&``````,,,>>>SSS&&&ė$t)Ѯ-^G-( '2dY ؊GA|,ⱄs 'Je|x1_"PPPPPP(((:::OOO888ZyE >\Ko='*5 OMSa'Ͼ!^CK͂ޖE="AAAAAAѯ###888KKKDDD /p/@@+<3=[<#S8Ц&f BjC//////ᬬ 333HHHNNN /xx***%=03 ?zOGf݀kK*ʜuqO9ssssss즦 ///DDDRRR &L[&XX y)05  a  hAA‰f;h 8$\\6L 5IIIIIIdBV<"8WpI(\̤to"4I^oo]= ?dD!p:ثG ʭ #4H`˜5 ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG \̤to"4I^oo]=%b},?tdm$ۛu-}%LLL HHHUUULLL IIIIII888888ʕK3Φ|o`; 4``LL7Z~7Z~LLHyHy]SLL4``BHLT `SMQB HHHUUULLL U6dʫG ۓGM^`U6dʫG SFDm% ??  hAA‰f;h 8$\\6L hAA‰f;hΈU~ǒ]Uy2 7{{ԍH.كǛ> 5WWW\̤to"4I^oo]= >u@*"0BfuI+ dݱW= 6SjF$ ʭ #4H`˜5 ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG \̤to"4I^oo]=%b},?tdm$ >u@*"0BfuI+ kI7 :~G4zk+b(:ثG ʭ #4H`˜5 ۛu-}%OOOUUURRR GG4``HyHy]S #PP\g7Z~7Z~LLHyHy]SLL4``BHLT `HyHy]SKK 77Z~7Z~SMQBkkk===UUURRRU(b:ثG %mm``kkk===UUURRRSSSHUUU888U(b.Ebyy`7ѫ)8J^iiW9T2m5άRU(b:ثG U(b:ثG ۓGM^`SFDm%SSSTTTUUU888:ʫG wC@{,zBvX꼎.x8 U6dʫG U6dʫG ӓ`_J/ GU6 GU6jUQ``GTj+BTTTUUU888U1w&#,`yfD' Ұ(|-yC^ApF!۰k?!G8detvbN=+ Dvxrh*`[E3%⽏g~tMyC^ApF!۰kA뵁xV96AmS۞I$$dHBs=q&b(.Dax:Le;b;llcg 3^PR̾?ŵ/:  .tSMF ylcg 3^PR̾5ґWEF~WdK0[! !;&:ʫG 8$\\ȇ_tI#;[U:7  hAA‰f;h 8$\\ꬁ y**ix @nT    6L 5\̤to"4I^oo]<1^?_C )>Wof  ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG \̤to"4I^oo]5됍ZEE~ZbL1 ?jJ!l:ثG ?jJ!l:ثG %b},?tdm$ۛu-}%... TTTUUU555 GG GG4``:`:`LLHyHy]SLL4``)x3mm3mmBHLT `SMQB TTTUUU555%mm`` TTT]]] KKKUUUJJJ  KKKUUUJJJ JJJ ܫTTTܫܫɫ888888ɫ888888ɫ888888U6dʫG ʭubj&U6dʫG U6dʫG ׍LVCc7ɜstBr(o>t2 U6dʫG ~Be<  &AiQD]A U6`nߕ#Kt_. •|3NsV& ŝ &1E[mn\<U(b(:ثG ⿜"1Hj~X) U(b(:ثG •|3NsV& ؒjCx)FyFiKu'U6WPǎ%Aan@•|3NsV& wmf2 ⿜"1Hj~X) rK{FqI|GU(b:dŝ &1E[mn\< 3~dHRwÖ; ʫsd: ʝ!lMDNog?S@ZjB{$  GU6dʫG  BmBmPAmx: GU6dʫG ODNog?S@ZY,'S^MIqwYDNog?S@Zѥ^{ BmBmPAmx: GCf>X9B}S GU6jB{$ O^;;  &Ajj 6fN҂= Z =ӿͷɿ]>]GnpN2 ҂= Z/L/$@(  ҂= Z ]GnpN2 NvYXscN =ӿͷɿ]> 9h`waA*ǵlZQ[N-ӝ:X% . ж5-ӝ:X%  9h`waA*ǵ(oGIWUb7ɞtqJ' 9h`waA*ǵ /[8瀲Zi!. ж5yM}l }E;?lZQ[NˢA  GG GG 5} &8Q&8QAA,L}L-~!ee0Q}Q}-~ 5} &8Q&8Q+xDww GG GG5} &8Q&8Q <,?Y63 !ee0Q}Q}? 8 GG AA,L}Lj!ւEEEUUUOOO ; 4..EEEUUUOOO999***UUUXXX(((...***UUUUUU+++***UUUUUU+++---999999999JJJJJJdddddddddddd\\\֒TY/zhE( Ѽ$֫G U6dʫG U6dʫG f:j*ƚ? U6dʫG U6dʫG o>t2 ~Be< ????????????ΓiW ;Uw;UwU(b(:ثG ⿜"1Hj~X) U(b(:ثG •|3NsV& ߣ@YH~;i!wmf2 3~dHRwÖ; !!!!!!@@@@@@@@@@@@ ;˥ĞyW7M]qyf= GU6dʫG  BmBmPAmx: GU6dʫG ODNog?S@ZĆl6kN\@ ѥ^{O^;; """"""Z}r>ۓGM^`U6dʫG SFDm%zBvX꼎.x8 U6dʫG U6dʫG vD"vߗK<6 jUQ` GG`GTj+B!G8detvbN=+ Dvxrh*`[E3%⽏g~tMyC^ApF!۰kAԦ\pO]P4bOxrP2կfMyC^ApF!۰kA۞I$rh*`[E3%⽏g~tMэTddSfO+r/ U6dʫG ߚPSB[7 ˷Y@ $dHBs=q&?ŵ/:  .tSMF ylcg 3^PR̾5 6M 3^6MGylcg 3^PR̾5 [! .tSMF  /tz8Dȷ/9e[74/*'""'4Z  !;&ȇ_tI#;[U:7  hAA‰f;h 8$\\,Z=Xf 㳤@, 8$\\6L hAA‰f;hΈU~ǒ]Uy2 7{{ԍH.كǛ> 5 1^?_C )>Wof  ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG \̤to"4I^oo]= 7ĢaB(u@*"0BfuI+ kI7 :~G4zk+b(:ثG ʭ #4H`˜5 ۛu-}%sssUUUPPP:`:`LLHyHy]SLL4``BxBx GG GG4``BHLT `HyHy]SKK 77Z~7Z~SMQBbbbDDDUUUPPP%mm``bbbDDDUUUPPPUUU)))...,,,UUUUUU))),,,UUUUUU)))j>1ej>1e---ɀPvZtO1ʷ>X컎)rm,QO?1&! orAx*컎)riP~1\db\K(͝tq8x. ܲ5  &7N&7N꼞3q:MkP䐚s9꼞3q:r;aFDu>kD 1ֿGƇ2 渢8z6 ߖK\兺Qy[8w C#渢8z6 ɔ EQQ趶bbbcs;e^I4#!IM% ŬH"Ȭ)*  8u[Y]eC'Ͽ{j'譭bbb]]  0ll!iH!0ͲZ/oJ\ &3DXehZ> ҫ(FeFe (aa!SS (aaAmAmҫj>1ej>1e...***===ɀPvZtO1ʷ>X컎)rm,QO?1&! orAx*컎)riP~1\db\K(͝tq8x. FFFFFFܲ5  &7N&7N꼞3q:MkP䐚s9꼞3q:r;aFDu>kD FFFFFF1ֿGƇ2 渢8z6 ߖK\兺Qy[8w C#渢8z6 ɔ EQQFFFFFFB cs;e^I4#!IM% ŬH"Ȭ)*  8u[Y]eC'Ͽ{j'ବ]] ĘH 2Ԫ O7ۨpVu)$F-jKJ%;7 >܂ &&&///888333MMMMMM999999999JJJJJJ =Ue=ҔXc$F-jKJ%;7 >ͬӸ 7GIUYNN &&&///888333MMMMMM.::jNN-Lf-L &&&000888111OOOOOO':K': &&&000888111OOOOOOɃ %%%000888111PPPPPP888 '''///999111PPPPPP888 '''///999111PPPPPP999///RRRRRRZZZNNN``` ::::::<<<######TTT????????????!!!!!!@@@@@@@@@@@@""""""}!!!!!!!!!!!!??????|wqqqqqqqqqqqqIIIIIIPY9-8IENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_motor_write_position_flow.png0000644000234100017500001012343512174204305033240 0ustar cpascualcpascual00000000000000PNG  IHDRe$ pHYs'`z IDATxhWWW ___U+='u ,# 45m @5"*üa3a԰e7 Qlll!!!###@@@Az 8TEt000$$$@@@S)Y/)E:SI7  Ԋ LK8K8&{jP{jW_-Ӏ{X- ZReEEEWWW---s nj8ӀtӀEEE===  '/7OOO0NN۾DDDYYYIIIuuu/7]]]e7 .1111Q[[[zzz ...ڥAAA!!!\\\DDD'''hhhYYY...{{{nViiikkk,,,IeP.Cҽ㗗|9>.n̡kkkҽvJ-kkk~~~ͷbbw50| G GK? GG۔%l[+MlxA' G U!A6 uU G%l GG4J1aGGG aG G U)Uу(G 9A ؾӝ׫((ǿq#5P $.̳p![˰cU)U׫SG.Cb,C˙]a6w\8GҽԽGMMM^AU(b/J(UثBWšz?ҦJ|| G G^^^ثBzBz GU(ݵ##G  G -##G z?53#n|( ׫hH0^ТMɟ+Q( NS&HТM7a i`[&؞l?λWՅ{6Ug DG+{GG׫SSS֒K*nٺ'FyMbЫnUS4 GGdS4¹>G Ԍ ,t GRGő't& >G ,t GZ G νl&]Wֳx1ܕk/W..1$k/H^3lxZ^͔::}}}~~~111P0p&&ux G ~~~ YYYYYY1 1U=\Jý̄lB"y GgyaNNNG GaoooNNNnnnpÐj=U 6k<@j=HHH777ZZZ\\\qqq\\\\\\qqqsssHHH%%%MMMMMMbbbbbbcccZZZT  &&&}I/,. 0-$4ߐc5888=== !!! !!!p}X ճ /, 0- wݙt ]ZW׮888 - N+M+^w/nN~pmJh6 BB bbEbbn=I¶~@ @ llMB!!!*** 999쓓]]] ¶~@H~@' `7WEvR ***;;;fffmmm]]] @`>& # Ս VzA$@ܿ@r'@ٿvbRR000 ???>>>ͣ!If؅`zddd222FFF:Kh 0DD$$ڼDDDAAA777FFFTTTe7 7\Q'''<<<'''999LLL[[[222&&&lllmmmDDD)))'''%%%Յ+{ޖDS]˛3}":- +{4k_̓-3 $ $/X0sss/⛑sssH8g(8@ʫ׫x>fȿqG UeoYg Gu 3LLLq Dq6; QU)U׫ѯ C;U*[G Y4r4 [G UU׫JJU)Xա G׮ G"""U(Jo < GUثb(Uޫt0Uct)ض G׫H!!!  bu"=1P̦H1!n) ,)će$OU(JضtG tddCz ׫hhh////// =6RʮZ#l8m̓ =ʮZ##̓r`[ /gRnƛtcG|d8 GUjRn&:ee/ :׫ť.[<$ĕ G0D #;[#G0D mmmllllllJڶj&ū.UG )sj&ȯ!''$K#Gbn(Oر` G8Qq*# G+-GGر`:dI***::G I+++ZSa @Sddd @ccc<<<'''555|||i0Du GH7D0#5$м) ս$G !/gG-~UXxUn. 7+ ~$G ]S&&&'''ęu>>???---$$$ #10=$ss)/5[r2lof}nhzLS [%R~p 퀀lhʓlhh6l BB UUU --- ;;;$$$"""vc[bggn &^fq[69 8 s59 8 r(wlhh66h6h B B UUU$$$000uuLL ..__   p/K`.qATcs_ ‹ L K~s6~st1{LofyNof_n`BSx5jwibo|~5jw(`A~A3+Ud qRR(RRRRRUR(((111 '''XX"HHHAAA"c!d,<nX_q^IlN\h /\A4O\An`BQjgRG2BOKd)@bo`wp|~OKd)~T֧owJeSUdnRRGwAAAnnS~~~KKKƛ%醺k꙳Lb`^M/...@@@LoHVb``A#O5&|$|~`p`|$|~kf*YeSHGGHG9 ǔ<<<BBBpOwVb l=FFFvvv1\\\f00𪪪RQ\\\222999999[[[000,,,jjjjjj+++>>>555vvv******fffffffff&&&lllkkkBBBQQQ'''uuu~~~???555'''ǎ{{{<<<ssssss...999999<<>>888&&&'''RRRf2bb}wǒg4np+lm#>Q(Jٿ㡈~~M++[FZŸTdo ٿқa!^ SI|MMMWgru爈 .eV϶_DoMxsq"???ޗf:   --^- 44 uY/{\,E2D{o½T;  GU)U׫ G*JLW㻪ا+0U3/UJ D{o+@_9Aǿq-lo_TO@B G׫ Gֶyjx :xykLLLA`tJ(B G  6U׫0+ G9M*Jȉ7 G׫= G  G G׫K. GdzU +KBG U)U׫>* >Aƿ J/V[۪LWªBG ׫BE$ƿyG `y"e7G k3LʹU)UdiB˭k3Lʹ,XԵkʹ׫Gʹ GԵGU(L_  Gh'P1ʹ > G = GU)U׫ GGhf:UA """ش > G = G׫ GUUϚL׫A  PPPbbbӽFЇ GN+` GU6dmbbbXM|:Aƿ=WثC| ثU(L_  >}jRA9|DŽ-CДa GGMƿUUثPPشDŽ444 333 GG :⾉eU5[ cxЮ`  U)U׫ As]s׫ On׫G  ׫O(`&FgI|AF?-eӛJ5d'UؤU(##?-e&ZI׫ӛd׫##ӛDDD7<{z:EƻG <9~ǂG U)U׫{ G0ʧt(5H˸;G*( :d G_$C G>G TTT G`3mG}}}MMMLLLHڸ` GIަ#?#>iǮG N5lM G G[-RӮ G5 ;RʮZm&&g"ǮG ˔ GӮ G: ʮZ   GUo}/F5pː G}ː8'G ž///>A{ $ĉ{...AAAXXX{ 3 wSDDDbbbWWWWWWjjjDDDdddG Ol ׫ GAAv Gb(<G @'@ث Gv GG z*4 G !K4 ;G GwW{ G: M2h鹕K4D F G ;G G``U:G: ΘD 222'''&&&/GzZwU)U׫ G  <82oΑ 6U׫-JW `Gn;wm<ϦcHHH֪{{ !GG׫~`n;<"kIII JJJJJJ999㡡 $$$???XXX:::888||||||WWWVVVVVViiiϯ\\\ AAA:Md&p ϶ ք7B>$z fff^^kk== KK///$$%!!!jj$$rrr ddD~O,> (%T>ԁk#"*5j׳e7 $$![[NN11166Q88 zz/,,%))Ж0T * +ӫ>o9 --,N Gwl~#11  ******!!!!!!AMb}(-ƦT*ˎszFeI\r{___Mm)"W*$ݷD>dd  `vNOO;(RTRTTT777&&&!!!)"aG.9B$^;u MMr~} }P@1`@1`^ssssRMMM''' +++TTT!!!:::AAA---_E ##lR^j"f8 f8Hȸ `YyO R###+++  ###jjjۻܸ 8?qq111PQ")/>r[df8 j/r[d_O`~ ~ nO0 a0 aUUU!!!888 ,,,jjjZZZH$HpqǍs9sCCCBT>EhhKg@\0 f8\# (((((( ﹹGG 111 ,,,ݣ6o6tQ vS f8Hȇ 7x0fCȇ 7x* (tyOS\\VVV999""" GG!ee00...(((2') zl OM?ȸȸ{fC/ FBOP5jw(5jw(A3+Ud ofel_yO!)ofyX϶g U=_n`bzRb t>333 ooJJJ000,,,@@@ 2'ֳ ߓ OVtclg 4iLh! ow-Ӏ@ow-ӀUdq9jb3O#6j80U=n`MJ 0&0III @@@SSSHHH M D[:6Odd> i`X>7vi{x4$? OA#4$?*mOO,gLFkt  t  gggAAAzzzʆ ջ/ ¦0 ((|$|~p|$|~GO(A#(*O,}jO     Ӻb;/ٲaq ""###ooo444///+D\.!FBBAeeevvv%%%T~(~؂'''EEERRRAAAUUUdddzzze7 IooYYYfff)SS aaa>>> ssssss###MMMTP0 \\\aaaccc......ooo444ا0&&&'''EEERRRAAA)))!!! aaa333ooo333hhh&&&'''EEERRRYYY```!!!ddd***dddR&&&!!!"""SSS]XV{ 444()]K {,H#O%Sڿ0AQ7QŐ*M50f"w93 ÎiV{_***Qɯ|ڐU&qHК>`d3|ζ!V{V_:::&qaa7Qɯ|q/RѮO7=uNNN  ɯ|VJ7-6oAN9JAO \,J{{{: PfDzD dž\fiHvvvG G ؍A(sO(`ԫ˟oɦirHUK6b*U׫ J/V[۪LWª'  M(> >`W7WovNotuBB  r&B B(? ճB( quӝG G ( GU&(@  77'x؞6/X_B$٫dȜ8qG )G hhhpD'r6Wj,kKK,Gc=) )hhhVVKϵвU hhh*U֫[nM LW] GݕFea#F֫[; G:|Ƅ8K!#t]2oM_^Fud@B9CCC GGuu(ӧKeee GddddddddddddeH6iD0I1!eH6Z йK G K U)U׫USR/XNE Ghf:UV©G G > G|uguSV~<<<B,7< dG5SȯWU:%6΃ugiACSqqqvvv555G MG׫E}HҞ444NNNMMMmmm}}}RLLL|||888bbb###$ؕ(bV9&ڌnil&G [U7_\GxF-sCkc,BԾU+U)U׫D-R/{dA[tGbO. G}͹-` ::G ^ɥE Zђ/T:`˭Ծ:kj7f|FtG G - -׫G GU UӨѮSS*U֫[׫׫= UϚДS*\555֫[\555 >>>444HHH\\\```\\\G U)U׫U)U׫ Gv. K(_6J5uUxvo՚jxecȫôS[ &G\%1lPxxx 3 ,-xxx*bGG\%d8dJ׫~ GɗhhhۓB%mU)U׫UdG ;  woH/ L2R, zx;4R,>Aǿq>㔖.Sf`7e=в d:5H@yAcL2G GU߫_!дQ̸fr\\\%m_!U)U׫Di1 GU)U׫~9< G0CнmB0m]]]\\\+9NDzeM9uNj{>D,Oe0mm:ǫtR=N2&Uc"6V#{+?9zDŽU|SLmS}nM ׫G eïHG Ldžоmn U)UB&AirQsd GG  r(RXrGR\xF'R-\랙i_&AjgOPMyʄK-5dV0Q}gOG\%9.S[ &׫G  @?(Y?(eG \%wD&G 5GG GG (C۽m%A>qr[v@Xʷs @ 27g3 G:1eL΀s&D3B ;4:gBT"g!:> M|mqZIzG > @+r@G >G GѯQ5 m@> Bc3+++rG m%zzzqqqvvvvvvU)U׫UU)U׫G 5[˥Q@ :&˥Q }}}׫׫G *b @L[r (w~~~}b3ȳY@v[x1 w}}}}}}---3YԴ}}}_ C***`q1 Fhl19B VVV1 H(Aa!B -GGGVVV> uAuOOO BBBaaa|||333DDDddd:!/FÔqY_`(*b@Aln&6Rʲzzz///F3n؞ GY-l .^m)CCC͒WG uGeC GU)U׫B0mhowW{G gw~W G XjJγgw~m戫;~ˎr޴~\6Ȁ~w>G |} `J(7KȮ~S}nMBy]:ū\#P\g3mGɵn666000000\\\]]]\\\6U׫+<+U)U׫ G~2  .'$X2 ; -JxX  B %/  G~yEy  i"  $$$---777===??????,,,,,,墢 """@@@UUU>>> 000NNNhhhyyyyyyQQQPPPPPPPPP  qqqvvvaaavvvKKKKKKRRR ---000MqͼV  d> k;   @@@v  MW % @7/    ,# ] AAA---CCCfffyyyEEE...<<<BBGG __ SS BBB  x~g (*-(*Aޕq\=>,}]mh    P T.} rI$ lloo4ZZ͠)33 JFFFttLL!)))tt BBJJEEE KK333 <<<MM!!!GGff``{҅V. t 4ؽ)D !. $"ʺ.S󠬹O)S } ݱ[ZXrr Lll[[ӼӇa zz..__%%((( !!!V. )Di^sPTns|C0tX LMČ: DtE'7' HV000VVV  !!!   !!!;;;{H)#@INH^snflsSO/:tB$(E3\\22OO򤙏n/r~WAyOA -sS `Rs \,,,555))) 555F ]WWה)RBHBB  r `ۭWvN{=hC{=hCAyOS;{5{5(ZRRZ\MMM777 VVV ---  ddd--UIS)s),~ VVyy%Svۆb \\\555xxx 'aa ##  jjj///KKK@@@oooaS"Y·3>EKxڦm gC"! LL LL )|"} )|suٕrQ\lU)~\lU)~A ^l%+DVn~uM5F\lU)~Eq^M`/%-?M.TJ\lU)~ޱjL[KA ^l%+D\He_FR \=h-e_Ff\=hs555KKK 33$$,,,///HHH999111NNN - K8G(roh kphJ_b}}$?,8}$?,8o{H#f&_uJ}$?,rd]T/S8TL}$?,8kϬo{^y{o{H#3e {F ~\qsb {FqsbbbEEE555qqq?GHj: 3=F    Ĩ%9MtV㬣oKZgzU3{*|o3PyOzU3{*DTyV5(:XFzU3{*|o3PyOzU3{*(U `|FQyx!V]X sy7vJ VRJ tR tRu%''')))111111 ^ ch{ ԉn+4   +)%$  $)@U fwLZg((((oxqwox coox((qw((ox$+G+Glu&?w?dd XX dd::3 ggg www333--- &&&FFF||| Z\{I0E ,27wyh!  ((("""&&&SSSKKKIIIjjjsss```666lL!) ...oR- ݱ f00QZZ ddd''' +++GGGcccnnn򠠠  @H88wZ%%9\{{BBLLLL_=DDD yyygggwww333555ccc`````` @HNNN"""&&&SSSKKKIIIwwwqqq;;;  ddd''' )))JJJjjjUUUUUU111DDD yyygggwww333,,,,,, vvv||||||NNN"""&&&SSSKKKIIImmm111;;;  III BBB&&&gggggg111DDD eee}}}iii MMMMMMNNN;;; 111 WWWR Sa3O̞X=ܪ?`p,2Jζ^ jjjHHH #+D(ElܒCn t禌^w@Xy+;뷔vvv999>>>0#$nnZm;nAp]P^C NU0U-ۜЯ0fКIͷb/Rѧ#x8hH4)*AAA &ըDYix^˪5J7-+[ѮxƗi,v 777U)U׫U)U׫/RѮXeBж^ -:if鯊 y;1efnWA&h'E EUO2g[;o C.b6嫿^DpmrrrBqq &[[3mm+aa&UUvvvGG UPUSwwwvvvU)SdI8VlQ C.b6d(bȓ6%Vit)iQS4  Tk7RxB\>;CWJ~4 >q&;׫ GGK]\&>q&GG W~U)U׫GG GG *U֫[As(Uik?tOК<H'aVGte[B; *JƗ7W ]*^ˠX3`دW.K5U)U׫*JƗ7W ]*^ˠX3`ت5\Vl|:GƿM(0B 8I& =f7p'No ].x -u6Jn No ].x -u[e:%sVVV<<< % 3&GGga(4uG׫3 GGճ GG(4uG׫ӝJV]]]׫MMM MMMxxx333""",,,%%% GG U)U׫At(U)U׫U)U׫U)U׫،rH9m% T=~>0 E;O`,g;K1eϗJFia3 a@Hx4 P2fΚU 0w/%w5 7@ɴ69m%(t._Hҡ8XжiG\%B-[LJUyGT;# -   "z7*zȬTTP)7QTk7~"y3U9B́q"z7 SP8Xжi} ?lKжi-\pGG~UG G׫GյwmK]\&TѳuB׫&h3Xi(b:::BBյwm%lKжiU G666+++&&&333)))jjjmmmmmmtV$;[eG9ɲ (b:U)M, ѡqLzT^.BC_ d=U:UG(bG ѡqLzT^.U)R*@Zlt!u*$W؞GG M2i[G_.<8xyxd=U)UU)U׫G؞G_.U)U@׫ 6nz6nz GG ΗY Z<JYdJYd׫׫ GG ͈3h͋(b.D`v=WY5I1ͪV=,'#(bB"6V E6 b5R9),˫(n}SaD`v=WY67Yjоmyy ͘K7ZZ HU:1bb7ZZɦ(((U5°[DA^:RgRUG (b:ۓBiCm%DDD:׫7<|OWUNYn!шOTC?xG.GG Y0;sТMOWbU)U׫CbCRҫ GU)Uڞ;;x&|j bVS//ȄyG.F5pː e=д}Mj bS:RT  ׫ GG\yyIː CU д GGճTT AQ ѯ&cC.Kc3SSS nn}}}rrrrrr}}}vvv]]]wwwvvvooollllllU)U׫O/`Ѡ T]'o#>ZMW&i0Dм(b:kL?)  T]'bk:嫋AAu@A.^y>sreG9ɲ Ѡ=&rAFJмF3n͒؞GG Z6U'L(Uث=a.GG  .^^6$W׫ GH :͒ GGWث GH GGvuG GGG\\\e>$GG U)U׫B0lhowW|F 46GG /G[aNVcK4ŧ9Y GG wW|F EZ Y=MγM2h͊ /G[aNVcK4mD $~;~};!k:bG'K4aM̄ ;6~k]|=OU:~>G |y^S:ˤK7(#̵bG'K4aS}mM+++***^;Tbb]hh^;THT'bbo+++333ZZZU)U׫U)U?Hӽb+U׫GCAD[Gƶll5\}}}͆@/#l/VֶIG[ :yLj24edҶ\c7 ]: ͝=Q~,f|J}}}׫׫ %/хמ6|?P.Sc֝4}]{1×er7 ||||||~~~jjj---wcƑ|>oZ2Jn}>F7 }}}}}}$N*fff̺гAxx 3Z.HQes -XVOͶ]:Bƾi/)Li9m______WWWxIȑX[Xk[Z,Y׻5***[[[ѢC@0r&SSPPP 000UUUkkkHHH___ 111VVViiiMMMMMMPPP000VVViiiOOOOOO֒K:4>XGG GG ׍LQrr(uuu111VVVjjjPPPPPP*iC@z)߮N5l˔UbVťsyy-\r]y<5 bV(Z6RʮZ]]]RRRRRRU!2RMyʋ=G\%K-B 6G\%6Q9@( S[F5Z'''(ʋ-\eQ}Q׫-\+xw+wuGG GG5}SCCC***(Oر`GG GG GG (b:Cm%A>ؿr[voьI9K5p:IʷsUݣl9̲Gu@ 27iu>bTr[voьI9U)U>ËxDCYDxKOUݣl9̲Gu@ ;x&4 =%hQPg!r!3(: M4 =%G M 9lbzSlr!3(q(Oر` >Z IG2z:: GG ,t>@+m@BG GG >Z IGѯQ5@mνl ,t>Kc3NNNر`r GGmooo666666666VVVppppppŘ7h UG ⾓D],[YU)U?H)G ߖ 06i!U)U׫GG j18ߖDj  ;h gU)U׫W G llU)U׫D<%i<O^; rrrrrr g8׫ǗeUG׫׫׫ GG{}3 :L^HHHvvvIII...wwwvvv;;;]]]!!!VVV 999FFF ggg """%%%+++333!!!333333``` !!!&&&---111777777888888\\\{{{{{{aaahhhbbbbbbbbbgggggg```\\\!ހ EEE444000CCC쩩 NNNTTTF Mw   r&&&///eD! Wg     H1 L ---???v,izTX<1ӕ麺487"g     p XXX### """!!! ߾bbbIII--- EE###oo((( \\zT{t[u]& )&e#"ݙg     m999hh66ee  33 ee  ]]"""KK ///'''6D\--쟳`H";FIK    tuuu#UpU*nnee^^O7`` gg rrAAAEEEwwLLL^^ ----!!!yy .7DOG < J@S% FIKeb^nh*DDD1rlifpT8މ"ww^^##VPPPPP;;##33::::[[ ''333$$$ ߀ 4> 7 hN>=WYggim!/- eb^"%)'www,ЦeF aI %ccc"\\\ޠ```,,###  $$$(((!!!?vɔRpWCphqxv8sK?>aaa8ceG ]m8= s4555666   !!! III (((ɔR@H%W +UVOXD# y/"fBIQB-AzDx#̺wS nO0=J wSSS???+++"""$$$ !!! ...|JY/5yk#%mܕqy+][Ppfd7_ P VmfN55ye_ﹹGGGHHHCCC      > ) iG,I$qy$B w7(o6ޏ_'iK-O!2AB llr÷{ =iA -sS `r~WAyO\RR  777  BBB) ^>Wc[n$d,_+"[[[q %Mx7(H9CM iK-!?98 r'yOS;( `ۮWvNA5"""BBB ---;;;,,,    !8oKWbk|YF C k{5{5{=hC{=hC`r \\ r Rl :::!!!&&&  111aaaNNN,,,  aaa&&&,,,nr55~ĄfW𢙱Kuž(Jn!+2/ñP -;?Ps0 Ϡh6?Ps0 Ϡh6r~CC^R R RvvvQQQ ???PPP333777 PPP GGGoƅiR Q^i ajX5^yOh& '46h& '46 `77E e >>>'''  !!!\\\CCCddpU=I);jgdp߶T,<>|9 26< 8 ff@@j0 IX0 +IX0 + ))  RRR555((( XXXXXX  **'? y8/Qg}̞&,0FwhfDȸlbdmzalbdmza `w< w< R-oyORPb R !!! ,,,UUUyyy<<<  ˓m6m&&11100|y}77IIݦ_] *MyO ȏQ+WmqX8 f8 >ȸȏQ+WmqXfDPuv2{XG(퀀((jj%SS XXRRR222 &&& ((( ػ``ee55m6m--q܏$$frf"E|w[vG뿆:%&&<# 6($iCݙO !:vPsgEǷDݙO !:vPҎL߻G 222!!;; ##99 YYYee5.(EcIx, V@.x  WA[iU qigPU qigPkPnnnQQQ  666--77||''%%55^^ 'dd ֓;;;fk SH- b'Q97=* h0eRF'n{('--- ﴴ SSV~~kk ,,  ''%ss8''000nnn)))0000 mmmZ{id2<k;YAHd8y_O7^y#m Hd8y_O7^y#mA 5tKyOW Wac AyO `v)R R ||| ;;AA&aa%%%BBBFF!!!+++666TTT ===llleeeBScBBBV`m).3 RaOvC!*VrP.jcLE>ȸRaOvC!*VrP"Kɱ `WiknccS`A(R RR555  ***yy !!!!!'''888[[[+++///Ϡř4NL,/%))+5 ŖqssA Aϓ̼wxvss9r9q0ed9r9q LLM)5`G8PH.A ``G8PH.]*:RNi.Wx c`G8PH.KGbSk,A `Apx}ón` `G8PH.KjlD ]*:RNi.q\fr;\\ RqwRMMM222''''' kkk!!!...---EEEccc;gD 芾= 999)+!&*2 $/*#V#@KRQQIG=YYY'''YYY===yyyxxxIII8iIkKpAKW3" &&&񵵵==WWW111""":::mmmRRRQQQ\\\wwwsSJar[`HHG&&&RRR777򻻻S: -'.{{{```)))俿,,,.# DD ++NN""" <<>KKlllooo777$$$222aaaCCCCCCiii<9/(JJJJJJtW"""' c?NNN22LLLDDD"""  QGGG ^^^!!!!!!!!!---kj%2 XXX......FFFaaa%%%YYYYYY===&&&IIIBBB!WWWWWW111""":::mmmRRR???ggg XXX&&&RRR^^^"""eee555 """~~~999AAA___lllooo777;;;ZZZRRR&&& ^^^'''???\\\%%%YYYYYY===vvvWWWWWW111""":::mmmRRR%%%ފXXX&&&RRR;;;ϖ555 {{{,,,###eeettt&&&kkk]]]$$$;;;......hhh%%%WWWNNNXXXMMM555 &&&>>>++++++l_"//////PPP Fs2%`qthMi8 (((www```F*fxJHa)wKz2ʉ5kkkkkk!!!nnnpppՑ̭0X7_'j3(?LO\\\\\\~~~hhh}}}lVLU& bP`-@i̛S:&OЈB%Iɯnv+i9KKKKKKxxx```Uk_.y*hb A;Lc[Ф9=^ %0?[vDΏi7\O1PҽpGwkzK<<<O?yooo XXXkࢡ^_E5y|'4 .?aA0!̼ic-ȗwߘE U)U׫U)U׫ݕFLh:uYfP+~S WИ9_"`*JƗ7W e\VldH& + &JJ`:tRmyΜ+/< 1B @| k@14 ahtefnW k@ 7E$u{ wgT[wfhRmy !;&vB-c}V؏;  .U%/V(ż۔&?  %/VW+U (U %B-cӝ.M(b:UG B+oP@iymuH! ?;!p6B,U3u6%V5⿗F\Fm(bG ?;!p6d(bu6%V5Ht)qZ;QYoP@ um GU)UU)U׫ȑ&UU Aii G׫ GGHt)anMMȑ)1Q6/Yě~kĵ"ente[B;GG U)U׫ykz[;_Ү[aVG ׫ GG999n kxO5d zpؕ''((;[~vE  \KhKt 4  "/ U1!BBB 'PW(Qm/BadG5̲ ;O-0% ?C!l5N+3% +gR:* 8ɼ BBBBqq +aa3mmL rrrrrrrrrvvvGG ؍A oAs(wwwvvvU)U׫ GGWgsg/sk,cE@IFLh:uGG *JƗ7W ]*^ˠX3`د[_SUik?tFLh:u֕E2Rϩ3_> R^0L:)"AM k@= ǁwf]Sx -u[ 1B @| k@14 ahtefnW  %/VU % 0SU.U%/V(ż۔&? 뿢0USlllu6%V5+(:;QY@UB,U3u6%V5⿗F\FmVVlll GGG׫GLGMMGG׫ AiiҞlll׫ZZZZZZZZZGG U)U׫濏B_QG gZ& ҞkI/濏B_QT&/0hПkkk|]q nuK2iZv<J:xj|]q=+SմjjjjjjB274 ! ƈB27ܕp& 9:YGśe~: 9DlBl:YGśe'.o]/>ѨeG׫ǕѨe׫GG U)U׫U)U׫؍A oU*U׫GG ׫Wgs[US WИ9_"`U\ْv9MXHȉ66/Yě~kݕFLh:uYfP+~MDff4U)U׫U)U׫ݕFLh:uYfP+~¬I2Rϩ3_> _S|Swg` 6O*Μ+/<~on k k@ 7E$u{b> k@ 7E$u{14 ahtefnW U (V؏; \K%/V*)V %/V>ż۔&? 0SU+VwwwqZ iymuH! 'PW(u6%V5p9&1muO)(bG ?;!p6d(bu6%V5⿗F\Fm@U֌tqqqvvvvvvwww)an׫&UUBqq׫ GGG׫ GGAii*vIvvvwww GG磣eeeeee]]]===oooAAAzzzaaaRRRRRRccc555WWWWWWhhh///:::xxx333>>>LLL(((333U)U׫GG @@@c/@GG GG GG @/cѝ5Ah$IĹ^G ܱ@nBU(H2xE(b:U$3a3QW8-9р'/::ƀҞkI/|9+4/lsQ`G(bV:0`èz󹑠8-9YJ5Ah$IĹ |kLU)U׫$OOP2fBΚ&؞GG `QFgwvzwvF-s߽<J:xƈ\@@EPw G؞ = 8m 9CǽnFUwJL@]A ҸCθP" 3}Xzw| 붽L! ƈ 3N+4,43ҸpXun- ҨG\%vbhOe;LN 9DlBl.xsX{kfu3V sKwGR %Gn;u`F:jzvbhsVpWunxWt"o~&h3X׫-\׫GG׫$@֟''#llǕ;Xc> GGp"n"x e$m$@"oZMW&UG 󹚱ĄwaO"M:7$Ƴ tV$;[(b(b:U:M:7$Ƴ ^y>srjBy`MofU)U׫skG@2Dΰ/^ G؞ G؞GG U)UE@2Dί%S^: ӿ"}҂U =* )< liʒ%@( lMaaA8=j _2:fxڹ- uJhJċzQY"x B y󿌾ss"G\%x B yЮ,8Qq~ V``6bL} GG-\׫V``6G GGggg GG(Oر`GG GG GG (b:Cm%j GG GG GU)UP0mqY0;sТMI5p:IʷsGG Uݣl9̲Gu@ 27iu>bTGG r[voьI9>ËxDCYDxKOUݣl9̲Gu@ dH& tS<Mt46ˍBoaNVcK u .;-%yF  tcihRˍBoaNVcK !;&6hA'WΈǒz2 Ԍt> Y5Zqd Zi=~ ?;!p6zZ~EE~Z1BG ?C!l5b},$-}bWWW GG׫4``Lyy׫x))x13mmB7Oر`SMXXXXXX WWWر``XXXXXX WWW,,,***---===(((---rrrrrr(((---vvv<<<wwwvvvffffffdddccccccXXXXXXGCi?</GujB0G U)U׫U)U׫E-MĞa=[Һ A U)U?HӹrI9ɲ i wUG ⾓D],[YU)U?H)GCB|/R*@‘>ZMW&fGxThlK(6RʮZ,uT{j=U)U׫Bmm: hlU)U׫,(,ߍύI4m@w`Mof  6z<Z{qhzBU)U׫Y0;sТMUFGOE+5iſv@;՝L2>{q$ԃBq;!& tS< x /9[^e[QL|ze/ tS<M /e:a4k:Y| {/9[^e[QLL hA'WU~7U7{{?-eӛ3hA'W /Y=Z#{{?-eӛ5%tml*3V+ h4 3h͋(b.֦O_v#¾I1dV=,'$ (b喴l*3V+ ?C!l5 $S9),īdn\SAɦO_v#¾-}bQmH ͘K7ZZ 1 H 1bb7ZZSM,,,n`aPPP===PPP rrrvvvvvvPPP <<<GG  T]'oTGG U)U׫kO|i7p5_kZ5s_&滫FE G)V'VVVJJJ1)[1Ed/ ;{[y+Ii|h7 VVVJJJ GG GGO~O~ZZ߰.phK0feZ |:|㚞ˑK3j͖qR@VVVxpDuPv1TCG(DÏ@;ŀ'''VVVLx\ ,V0:+U(((VVVRS0K(K-@Ɇ&;usr&(((XXXVN3B'< ?F({xC! /1j!A'Cb((((((ZZZ 7g >X Ammx0!mxKKK/OѱU~~~$bB;2M CUStyX7+\PVPv,d?O2`ar2:06`і@ ev~~~~~~쿟;TO1zn 6`TɇCӡ{{{\T9+%㱀~a :yJZMW&$$$888돏 DDDhhhPPPPPP ;,uT{j=U)U׫Bmm:!aU)U׫,(,ߍύI4m@w`Mof(((梢222WWWhhh{qhzBU)U׫Y0;sТMUFGOE+5iſv@;՝L2>{q$ԃBq;!& tS< x /9[^e[QL|ze/ tS<M /e:a4k:Y| {/9[^e[QLL hA'WU~7U7{{?-eӛ3hA'W /Y=Z#{{?-eӛ5%tml*3V+ h4 3h͋(b.֦O_v#¾I1dV=,'$ (b喴l*3V+ ?C!l5 $S9),īdn\SAɦO_v#¾-}b===\\\QmH ͘K7ZZ 1 H 1bb7ZZSM\\\%m&_(b`\\\ Gtttttt###||||||>>>===XXX===ggg===֒K:4>XGG GG f-lӚ?GG U)U׫n18~&< nU(b:kL?)  T]'bk:@??f 3~mjϖ;˥W>))î G؞GG  N5l˔!a.GG luvf ^N8Ȥ;F3n͒Y-@'fNޢ}9zAk"URBBUG\%4ЯG\%†0dkA %Gn;B /^i!8\rrrrrr(ʋ-\eQ}Q GG-\BМA"n"i ,Dibbbvvv 4<bbbwwwvvv,,,ooo===ooooooiiiOOO<<< !!!PPP---/// !!!fff!!!!!!\\\!!!!!!yyylll333555<<< !!!&&&+++444!!!KKKKKKAAAooo ###)))...:::555555ccc """$$$---111!!!OOOEEEۮ%%%(((000888888888񥥥RRRRRRuuu555```````````` [[[hhhqqqvvvvvv\\\[[[ZZZ\\\[[[\\\UUU``````ggg`````````III"""***CCC褤((( AAA_| l&&&bƙ# ] W /// >g clT7?J  ~   {GP+  111NNNٽKKK(((QQQ ﵵfff j}q!#7/e:mS !bxY     d;h9999!!!++G)) %%%&&&>>%%%``!!!yy IILL &&dd '''222 AAKKMMM }};;; !!!&&&ƻH޻m%߾!-0C(?clWN 4;Aw[jP       :%Q ,,,:: $$ԆنCC}(}) )333kkYY FF  --UU>>>bb jjj>>>!!!$$$  &&&'''))KK&ȯÁq ! %/i%|g|g~~~#-f jp\j3/555苋GG2229CC%%%==PPŊI8I,,, 6666  ))777 <=Wyxw\ho+ gC8晙AT'[+G98G98hnn ~~~->Rp`MqV`  *** '''%%%,,,   ))),,,&&&))) !!! V"zqN[ ^?84׵ʹ6̼ i[a#CF#l+Z ̶Q=&,9675  *~~~%Is'mI4` yuk_ " "B ƒ2$ v444999뼼>>>!!!  ///FFF///:::  yеٷh Y9)KfKf>^^>^e(4J{411/rxy3+(:fTwh1# 239U 2u  r`E HT%`% & G) 000  ###!!!bHNT%di1g0Kg0K U)D  #!Һ?EvwjkndD'@)z4ZM F}\I5 g 4 Ƚ9LkN5dثWak *A !>-:|6%"A y`OA !>-:|6%"A y`O\i ((()))!!!000   '''  XA!]>}'>]EKQ{ɶvv ͓t ``a.3 y`O{#-\S$(A y`O{#-\S$(AP\  ,,,'''!!!###   666 ))) &&&nn4# ¿K>J ]_) dABDIih}4X  {l5;@ G /4C4JA(9L$K쥽8'8C.(쥽8'8C.(C4JA(9L$K쥽8'8C.(쥽8'8C.(jAn5[\\ 5[\X=111&&&'''  111!!!''' $$$___!!!///---333;;;((( gHOdA%!!2(! B-sӺ6Ÿ',2  z*8;̠#!Uc i)Ȱ?[7%#h]r%?g2Ŀ.K8h]r%?g2Ŀ.K8P !>?[7%#h]r%?g2Ŀ.K8h]r%?g2Ŀ.K8jn2k?2k?z&&s||| !!!  666!!!CCC  '''000 sssssszzzXXX]C ##&&Xc@ ̹.16#YA8#վVZHHw w\ ||/"8?D  y`O y`O555{{{  !!!ssssss:::ڧXXX$$coIgqwkG G +R""+5=ʽ2%0.EX/i[Π|l$)-4:""  DV JP$}~^>j0 DV>j0 w?sULg i:@;4w?sULg i:@;4Sn&G*)w?sULg i:@;4w?sULg i:@;4Sn&G*)Vtt&WO Vtt&W555ccc꼼  444:::OOO,,,ppp:::]]$G""z݆##222n)T-:EXbC5no~ݲSz܆qx˔bS- lps 3E@Ḇ>bŅ=lÔ 5c/룽 80QD/* 5c/룽 80QD/*kf|Gսj1 y`O 5c/룽 80QD/* 5c/룽 80QD/*kf|Gսj1 y`OH@A\ H@A\MMM곳888   %%% ///!!!JJJnnnccc???>>>ˣ5}܃$%K##Y%mۓ{{222JCv5l Y] #k\gQ^m@a<ÔͰe?%vy DV–E >j0 Ͱe?%vy DV;\}>j0 (^I\^I^I\^I$+G+G(^I\^I^I\^I$+G+G ddXXdd ccc111 KKK ..++< kkkkkkEEE hhhLLL55$K%K Yےݺ1A\uP]CHU,,+  !%W[LZk"}Ji2f=&}qJKzeg LsEW>j/ f=&}qJKzegŬjƜbbb)))... 000DDD  %%@@O**cc ##4422 BBBSSS(((SSSJJJ244ؑ~(oyy* F#FP$гk.q  E1OC;kyQ!5?;=d"g 5?;=d"g 2UtM vvv 444  !!! MMZ!!!++&DD   %%++&&uu MM "" !!!!!PPP(((rrr(o* 꿰ޜN= 0UU',!2Kě!G  ',!2Kě!G vvvhhhccc(((~~  ;;  ''.. ..44466  ''$ ,,, %%%!!!%%% SSSQQQ(((999tttcF LPӶD2#6Skhpd ~Ngr6%Q&Ad@%i#syg j0 Ad@%i#sygAzil) y`OA y`O롶c y`OA y`OA y`OA y`O \ \ \ hhh $$$UUU###xx00jjbb --111񽽽   <<<  000BBB III A6R™}yE(?[\ (`2;F;UO<+3Lf*pdb{" Ls Ls 5RReКe 5RR Lss)hd3'84$l|n(A(Az \ \ZZZ!!!)))))) 000444<<<]]]:::$$$! Ϡѐb"#зY/> <L[\ -`2Ż$-7nh |@  ;EKԗm*t!U{=cC5AP y`O{=cC5AP y`Oꈰ d`^o{=cC5A{5 _^n"AP y`OAP y`O{=cC5R *jUT AP y`Oz \H.\\ \lz  \l \\\999KKKK!!!BBB000 $$$ ###***---LLL0" B+(R?$  w cC)#-5g t3+z(B<7"*:rG'# t5H4  (D%B$CnR 𔝚?Pr0 ϡ!6 f6(A y`O𔝚?Pr0 ϡ!6 f6uVRC𔝚?Pr0 ϡ!6 f6o'ơioJ7(A y`OuVR𔝚?Pr0 ϡ!6 f6\wh|2UkB-uVR{lB{$t \ vlB{~!kzQQQ 111***... ;' a%/-,$Ǐ _gks{hYI?&]s}I5 !3Opƙ85h& '476h& '476K)6X h& '476o)"K)h& '476-K)44 7e44 seMMM222 UHT6x ʠvZKu{NuFE;iǡϠp M9!+  CC%%ppqIU0 %)IU0 %)wP2Λ.j]lIU0 %)IU0 %)    SPUm+ m|}B B  #s;iiiFFFDDDj^8/ g[,, "+(girkH ߾>>"""NޝUtw =JVmThh\*P*4R`m  YX6"<<<SSSWWW111{{{<<<888###s!͸[y{@Ox]`=*<~k}\%I Zaf4,cmE 0)))[[[``` uuuGGG666㋋ DDDyyy'''dEmYYtǢ][4(-2 \chm&&_ْ>!   === ))),,,UUUEEE駧 )))KKKlllvvv***KKK, O9NL"Sbox~01`Y _n0$)0ggg 77 !!,,,:::$$$(((222ZZZppp۾ """555IIIJJJpppppp999ѵppp  _BB; ) GGGpppYYYkN&+! L&-- iiJHH((mm999'''CCC@@@ ###...BBB...%%%gggXXXRRR RN (ghI8I8ddd硡222iM6) a6 FFF}} NNNWWߺ---999<í߳ '' PPPzzzaaa ***??????___^^^\\\ 98  .!!!>/>/' 444449::::((((S=SS=S   ###&&&WWW&&&111666111 IG"*/!!!))),,,jjj uuuGGG666cccggguuu*** CCCC&&&aaa444))),,,UUUEEE<< UTn΅S['226!д:~7 ű./R a,oݔJC~-̀2P7, (Jf}n@EEEEEEͯ%%%888JJJDDD+: /p/?;//6NszZ%Ѯ-^G-( '㰘.zYK<'wFkbc3ڷrq+:  333333i=a̳^ݯ !!!444HHHKKK +CV+CV 80' >\Ko='*5 ۧ/~J {pgb&Iz翣·3)*.6R~i- ~9---???UUU˚r^Q0ŹӬfy9XtʣƘOeko0yʚ= ᯞ@8 Aas%ę= ڡ|3 WWWWWW)))===PPP111$o# -V{V{:idڸu/Hu}4h-0*ΡL/ ߮F4 &_FOHf>٥yn &E_ttK߫fh:FFFFFFώaeFɱ%%%888NNN??? +- &JlJlkbWbп BZEᯞ@8 ^CJؐߘI6f{Ð 77$[2Ѷxz53 ԈGXjs777777ۮ !!!555IIIJJJ>>>``` 0A 0 80'֕o-0*ΡL/ ̢%f Ș!Y2T}Ͼt3%U\rO߫fh:%%%wwwwww鞞 000EEERRRXXX .*kbWbп BZE@iOEd܁mL,ʝw{:)`)hѠ T!͌iKΑ,5%e4ܼsu9x-٥yn &E_ttKjjjjjjZZZZZZXXX 0A 0&kkSp8ȗaySȗb $Gx=hK^CJؐߘI6f{Ú@ 꽈ht3JXeniL& And©ZZZZ```+=6 BB&'>&코㭏0k̢%f ט{Wq?4K- :SM< !!!!!!"""!!!!!!!!! 2mg RaJ崚L[f} Aav`@iOEd܁mL,ʝw{:= -~̯C`-iiiiiiU6dʫG U6dʫG U6dʫG U6dʫG eA)t(~Be< III!eeݫG6( xRx&kkSҜnc+Yb[RHbJ\ew\Y{,ӝN- III᳋} +@Ys|kF Ҡxv (Jqa/U(b(:ثG U5 ?ҸêźMG Ga44%E3' ?ҸêźMGE3'4   44%E3' ?ҸêźMG#bbpd$^_JQiNWUF'pm 9FLlyO'ѹG> -ӝ:X% u`i3њkj9 9vbOah1ϗhb9 pd$^_JQiNWUF'pm-ӝ:X%  9vbOah1ϗhb9 .mrFxZXu`i3њkj9 9vbOah1ϗhb9 pd$^_JQiNWU=!nvᰡ8/ U6dʫG U6dʫG U6dʫG  ??=ooKK<\<\-~ :xB >uu$mm@xx ??=oo GG-~ GG$mm@xx GG GGTGCX[ :xB >uu$mm@xx ??ѷj#j888UUUJ'^+: 濕5Vw|S& ܲz!9[vB濕5Vw|S& U6dʫG U6dʫG ܲz!9[vBU(b(:ثG Ҡxv (Jqa/U(b:ثG(sr=888UUUTTTIIINOkq $OORGjš= NOkq $OORGjš= GU6dʫG ߗNgbNHz3 ,,,Hrrrwww~~~B2RI.lC( B2RI.lC(  GaLLL???UUURRR 9'DH[뎂\7ϰ*~;  Ҩo}0 %Bؘ.g: 9'DH[뎂\7ϰ*~; ,O(Ӆ(t;ƚux)g %Bؘ.g: Ҩo}0-ӝ:X%  9FLlyO'ѹG> ???UUURRR>&>e>&pp/XX"ii>&>e>\\Dww"ii&pp/XX-~KK<\<\U6dʫG U6dʫG eA)t(،GWxHU1z1/bn2ђB] 㵅o6Y~zJU(b(:ثG U(b:d㵅o6Y~zJU6O9 *PzY& lv|r(U5ًF_싾ȁ wAFբu' GU6dʫG GU6ًF_싾ȁ wAFբu' nuNLr×; Щ!\8mwCGԢn%ًF_싾ȁ wAFբu'kL/%@]!JA     E3'E3'4   44%E3' ?ҸêźMG  9vbOah1ϗhb9 -ӝ:X%  9vbOah1ϗhb9 .mrFxZXu`i3њkj9 9vbOah1ϗhb9 pd$^_JQiNWUF'pmxr- GGGGGG$mm@xx-~ GG$mm@xx GG GGTGCX[ :xB >uu$mm@xx ??=ooWG>>>>>ddddddddddddmdddU6dʫG U6dʫG uElX\7ˬ0;q^f:ō^ng[dOo|cH#a 7 uElX\7ˬ0; pNzfd( zpn\(BkB 7xEFu{-6[~vsRs|Ezpn\(BkBe,# 4a 4ZK1! }; 4ZK :ʫGޝW2D9u. aGfG3Vv}V(  gڬS:(C]u}lG! aGfG3Vv}V( "cNk<9<BqBq GG GG &UUBqBq GGKKlU6dʫG U6dʫG U6dʫG U6dʫG eA)t(،GWxHU5 9'DH[뎂\7ϰ*~; 9vbOah1ϗhb9 9{kNbf/͕gu6-ӝ:X%  9vbOah1ϗhb9 pd$^_JQiNWUF'pm.mrFxZXxr-̫ :xB >uu GGKK<\<\>&>e>$mm@xx GG GGccBzz GG-~ GG$mm@xx GG GG??=ooTGCX[WG yx!՜dfZ[U(b'am<ϝ9= U-r|F`!՜dfZ[U)b.li2ИioU`ݕKMAi2ΗhlMj"ڑJXVV/ϽI> R^`K014 ca@82--4Ay_xO [ 6NHvH (L:I&N="M!yǬ wBB*6'$% 5|@uZVu5 ~vsRs|E 1DŽ}v@Cy>xO [ 1wB@v|QHU< lj wBBwG^= 14 ca@82--4Ay_ >۔H0ǝ?  hKGt;X %U  ]w###ErL{rE1! };  0W+ߚQU*U hKGt;X  U (%U %>۔H0ǝ? 뿢+f0 '?Yv? ?dD!p:ثG >vX,s%>]uH# ?dD!p:ثG (u[6Y5V|N5YWEnl gڬS:(C]u}lG! HAV,t)%p_9Y'KgNU(b(:تvX,s%>]uH# ?jJ!l:ثG qBa8\G(u[6Y5V|N'?Yv? ֌VIX??????AiAi???LL +aaK[ GGLL GGGGGGMM *yy &UUHHE}E}moG+aaK[3mm )apnMMAiAi*v???!!!!!!@@@@@@@@@zzz GG@@@""""""ggg|||999fffKKK(((ʌrrr@@@쨨qqq ᐐ999ppppppY!!!!!!!!!AAA!!!??????NNNNNNJJJJJJU6dʫG U6dʫG U6dʫG GGU6dʫG GGߚPSB[7 ˷Y@ yC^ApF!۰kAU)bJ|T.կoE\D s|R+խkySߚPSB[7 ˷Y@ U6dʫG U6dʫG \D s|R+խkySU*bOxrP2կfM/9e[74/*'""'4Z ylcg 3^PR̾5 /Z7aOL}::ǁ|Y7c OJH< /9e[74/*'""'4Z ǁ|Y7c OJH< 6M 3^6MG 7{{ԍH.كǛ> 8$\\ Y/+X,7{{ԍH.كǛ>  +X,ʭ #4H`˜5 \̤to"4I^oo]= ?dD!p:ثG $0S9 6Pr·& #mϡ}Lx /Gh0ʭ #4H`˜5 U(b(:ثG ?dD!p:ثGU(b(:ثG #mϡ}Lx /Gh07Z~7Z~4``LL !Q^1bb7Z~7Z~ GLLG1bb GG GG)))U(b:ثG 999 Go>t2 U6dʫG U6dʫG U6dʫG U6dʫG ~Be< wmf2 ⿜"1Hj~X) rK{FqI|GU(b:dŝ &1E[mn\<ݲy 4QiGU(b:d⿜"1Hj~X) U6E{0#7RsxN" ѣ| 0Hj\. ŝ &1E[mn\< 3~dHRwÖ; ѥ^{ BmBmPAmx: GCf>X9B}S GU6jB{$ LTwj8 GU6 BmBmPAmx: Ńl>K1dݔGU|ȏj?F+l#jB{$ O^;; ]GnpN2 NvYXscN =ӿͷɿ]><)  *="]GnpN2 "=* )<d?) *=# =ӿͷɿ]> /[8瀲Zi!. ж5yM}l }E;?lZQ[NU(b:ثG 8FQlyO+ Ҭj:. ж5 %Bؘ.g:uJh|T.ձn9 9x DOkyQ,ԯl y9 lZQ[Nt2 ~Be< 888888999AAAUUURRRnnn &AiQD]A U6`nߕ#Kt_. •|3NsV& ΓiW ;Uw;UwU(b(:ثG ⿜"1Hj~X) U6`nߕ#KtRb*b(:ثG ߣ@YH~;i!wmf2 3~dHRwÖ; AAAUUURRRʫsd: ʝ!lMDNog?S@Z˥ĞyW7M]qyf= GU6dʫG  BmBmPAmx: ʝ!l.U6dʫG Ćl6kN\@ ѥ^{O^;;  &Ajj 6fN҂= Z Z}r>:ʫG wC@{,zBvX꼎.x8 U6dʫG U6dʫG vD"vߗK<6 U1w&#,`yfD' ҰC~iApF!۰kA!G8detvbN=+ Dvxrh*`[E3%⽏g~tMU1w&#,`yfD' Ұ(|:Ԧ\pO]P67U*bOxrP2կfMyC^ApF!۰kAb(.Dax:Le;b}l=cg 3^PR̾5 ?ŵ/:  .tSMF Le;b; 6M 3^6MGylcg 3^PR̾5 :ʫG 8$\\ȇ_tI#;[U:7  hAA‰f;h  ,Z=Xf 㳤@, 8$\\\̤to"4I^oo]= 1^?_C )>Wof  ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG 7ĢaB(t2 U6dʫG U6dʫG U6dʫG U6dʫG ~Be< wmf2 ⿜"1Hj~X) rK{FqI|GU(b:dŝ &1E[mn\<ݲy 4QiGU(b:d⿜"1Hj~X) U6E{0#7RsxN" ѣ| 0Hj\. ŝ &1E[mn\< 3~dHRwÖ; ѥ^{ BmBmPAmxGCf>X9B}S GU6jB{$ LTwj8 GU6 BmBmPAmx: Ńl>K1dݔGU|ȏj?F+l#jB{$ O^;; ]GnpN2 NvYXscN =ӿͷɿ]><)  *="]GnpN2 "=* )<d?) *=# =ӿͷɿ]> /[8瀲Zi!. ж5yM}l }E;?lZQ[NU(b:ثG 8FQlyO+ Ҭj:. ж5 %Bؘ.g:uJh|T.ձn9 9x DOkyQ,ԯl y9 lZQ[Nᰡ8/ ===+++UUUUUU*** <,?Y63 !ee0Q}Q}? 8 GG AA,L}L⩎&mF FF8dd GG!ee0Q}Q}"ii :G 5^^VV6`` AA,L}LY+: Հ+++UUUUUU*** ;dd 4Հ+++UUUUUU*** GGHHHUUUMMM ]]]HHHUUUMMM PPPUUUMMM 666U(b:ثG  GU6dʫG U1w[qM-Ұ(|:U6dʫG U6dʫDhG~W|]>$ Ÿ~{7y.  Co%;b;ԇV-n$.M|1NVν2 (`777 9tR}\WfB&и6+weqSFZyiL2"³bA 999999999;JdÁ/999٫xxx777 GG GG 5 &>aa HH'6'6JeJJJJJJ/c=CZ٫ǜ!aӂA\ 5pjL3 ԵWXe.cӃDn u'gP5`hc]J'˚qo9w- Ü)d.4 5Z5wAJn(zn:fB@r|FjB }}}}}}ثxxx쿝/j=ڿ/x2 ۳D辨_& ʗ"AWW(((}}}}}}ث뭭MMM麟5t8:rʳZ7Ѹl 8u[Y]cA$"~k'(((}}}}}};;;[[+z 3 %;]] .xx - ->AxxIH>i>i©UUU333<<<!!!)))333===//////\\\\\\!!!***444===////// SSSSSS???!!!***444===111111???KKKKKK??????!!!!!!@@@!!!+++444<<<111111@@@@@@@@@""""""!!!+++444<<<111111\\\ѫ)8J^iiW9t)>Z}r>󯯯^^^"""+++444===333333zBvX꼎.x8 U6dʫG U6dʫG vD"vߗK<6 폏JJJ"""+++444===333333!G8detvbN=+ Dvxrh*`[E3%⽏g~tMU1w&#,`yfD' Ұ(|: Ԧ\pO]P67U*bOxrP2կfMyC^ApF!۰kA勋ZZZ###)))444===555555?ŵ/:  .tSMF Le;b; 6M 3^6MGylcg 3^PR̾5 ݇\\\[[[###+++444===555555ȇ_tI#;[U:7  hAA‰f;h  ,Z=Xf 㳤@, 8$\\jjj 1^?_C )>Wof  ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG 7ĢaB(t2 U6dʫG U6dʫG U6dʫG U6dʫG ~Be< ??????wmf2 ⿜"1Hj~X) rK{FqI|GU(b:dŝ &1E[mn\<ݲy 4QiGU(b:d⿜"1Hj~X) U6E{0#7RsxN" ѣ| 0Hj\. ŝ &1E[mn\< 3~dHRwÖ; ѥ^{ BmBmPAmxGCf>X9B}S GU6jB{$ LTwj8 GU6 BmBmPAmx: Ńl>K1dݔGU|ȏj?F+l#jB{$ O^;; ]GnpN2 NvYXscN =ӿͷɿ]><)  *="]GnpN2 "=* )<d?) *=# =ӿͷɿ]> /[8瀲Zi!. ж5yM}l }E;?lZQ[NU(b:ثG 8FQlyO+ Ҭj:. ж5 %Bؘ.g:uJh|T.ձn9 9x DOkyQ,ԯl y9 lZQ[Nᰡ8/ ͐UUUGGG <,?Y63 !ee0Q}Q}? 8 GG AA,L}L⩎&mF FF8dd GG!ee0Q}Q}"ii :G 5^^VV6`` AA,L}LY+: NNNUUUGGG ;dd 4򤤤NNNUUUGGG,,,򤤤TTTUUU555=== TTTUUU555))) TTTUUU555<<<!!!ګګ~~~ccccccū======ūIIIIIIIIIIII======888888ѫ)8J^iiW9T2m5άRU(b:ثG U(b:ثG ۓGM^`SFDm%zBvX꼎.x8 U6dʫG U6dʫG ӓ`_J/ GU6 GU6jUQ``GTj+B!G8detvbN=+ Dvxrh*`[E3%⽏g~tMU1w&#,`yfD' Ұ(|:뵁xV96AmS۞I$$dHBs=q&?ŵ/:  .tSMF Le;b;ґWEF~WdK0[! !;&ȇ_tI#;[U:7  hAA‰f;h 괁 y**ix @nT    6L 5 1^?_C )>Wof  ?dD!p:ثG >u@*"0BfuI+ ?dD!p:ثG ѐZEE~ZbL1 ?jJ!l:ثG ?jJ!l:ثG %b},?tdm$ۛu-}%===PPPUUUCCC:`:`LLHyHy]S GGLL1)x3mm3mmBHLT `SMQBPPPUUUCCC%mm``PPPUUUCCCTTTUUU999TTTUUU999oooUUU999***   ===[[[]]]111...      ꏏGGG```NNN!!!(((  '''[[[___!!!+++KKKLLL:::LLLJJJEEE RRRggg ... QQQ %%%%%%񧧧mmmQQQ &&&&&&񣣣 (((  ******llllll຺ ffffffº JJJJJJOOOXXXXXXbbbbbbbbbbbb]]]ﱱZZZﱱQQQ[[[[[[ """ﱱZZZ``````ﱱ``````999999999999JJJJJJ%IIIbOBBIENDB`sardana-1.2.0/doc/source/_static/sardana_server_internal_pseudomotor.png0000644000234100017500000561003112174204305030270 0ustar cpascualcpascual00000000000000PNG  IHDROHp pHYsP?IDATx_f3 [+tp1@g\1BAJU_~CׁS0 BBJ~) \of306e7  bb__QfKpj0 A{"` eeQPPP 777000j" L# Kj5 XXX/ nntXXX^^ zzdd***KT }ffHHH zz*000"""TTf8 XI#f3rrffg!!! $$$$cr]owUIbRLb0ffff3fff___ ===!!!@@@(((F)\k\bfb0'''%%%$$$[- eeF~ GGGBBB 11BBBe7 ddyXA@pyOZZRRcccmmmۭP11NNN 00JBBB!A{"`@?[-ORRRIII::&??????TTT$[ЎW6,".*uAAA t@@ rj5}}}***{1>}{RKfFS+ wg4A 2tf)=J8qy{qkŕ$gՃ m8 [-Df555---873+ Pɹ8H0D#*$)7{f=!f Q[-DX X ...%%%===vBB8H:GCF,rw 855X ö㴴 $$$___/,.ccrS|y-- ReefQF%7L%LDDD$$$yyfuf3e7 eeReeffQyyeO  f3&&&7awcZffE#ʿܗLĵ1;Ff3f3f3'''N!oxςb1458f3f3e7 eef IIN [  e  *#Q& 111EiLf8 GRg9Ij$_ :DVs_rrao9١VV?O???pP-4**IIddd!!!?grȸ: Lt 9Ȣgf3pfmmmJT׹G-!ܹG  -4qOcV O1= 3? mmmaGGG  qx f8f3Ȣ `c V 2X,rTc 3? [!h44T28T28c  2y\j}$_Rk\RMM]]] 4{~]}oxGYv92R ]]]e7 <<4JJ*ox e7 fQQ&"Au-fgR 2\`???f8 LfDVA /wQ&(ကӀp&iwgXo>j/ &gMwQ"rT*  KKK ` Lt``gf!6r6fHHH >>> f3}mT 'r@%Lf>>>fCY i:o+kP8 K, g$RR}3  Fl;(}X X 6d8 syNW[RR׶)J999eefeefQQOddG:0Q>>>###e7 fQQ_(((333>>>^ci [srg?.lk7ͬd4o222333 ==.ɔ3TTf3N^jn P_M < zpBU_v=<j}~f306e7 eeeeQ6fQQZZZccc/ EEj5tK HHHN"Eppp/ )))BBBgg..֋9񩩩WWWf8 I9gfamKO),=8H ))));;;gg.. 񾾾BBBE8q8 f3mK ( (f.fQQ ///;;;  O::7owi1X>ffff3///222"""NNN$$$ 1OK)1X>uuu)))!!!zzze7 ee(|$~ 555>>>$$$YYY!hhe7 eeyX@pyR>ÿjRRRbGGGYYY++RHHWV[O[-RRRbWWW...---!H)ۋ[j5tKjDjDWWWa".eA祷ydV%u%4"y Ltfa363^+b4ydg#+3A f8 ( ]/ӮyoO(f111777A+ Y(zJ:$ / '-8 yo( """MMM777[0 lL YO, ,==) 8$$$ooonnn$  #||fQQ# Dkkk///nnI.9Ce7 eeeef*Q000Ic f3VVVskwݗ `9f3f3######fvM} e7 eefeeQS[}>:LfQQfff$afvӋ#.ig/...NNN?ҭϏwc2q>2hGjve8{zw ???yyy\\\\@~qBHHH L1 0rBd8(I08SIbn 333߇OZs2!  (PdZXX; gAiq) @_ _y y`Lc@CS(b;<O2c( 227LWl}$@R\rrrSG0{3}ox{~* V 555e7 0JJ(ox*Rz) 444e7 eeA~p<Rf R` &????0 AVwl&/ f8 6 K«; ÆBJoDTj;aK  ### Ld<@{eAe gfar_k CCCkkk %}t)f3 y`nyXAyPbfkkk uނkaȌYmDF"X@1JRR}bu'ux~1(ryOOO6O6 '''&&&5eeeebLLQ44fffffe7 5fQQX000000[ڥF?&44ԷH:@ G@=%:::000R&&.{FFG Gf3QR( Bq.' `QR' ڍٟ|0}nyB' 'y&t..Sf3f3 dde7 eeeeggYY]ǻ[āERWmqXf8 ȏQWmqX@XG(A7ɀ~~`fQQ PPP OOO 8t'bpW''bpW6gXɀ˝yt;yt;4   !!!0 0 . Lr0< 6% 5c4 c4 %3-fg777]]]**ii))777... {?Fy{%nw9 f8^/{Y,+6 Ԫsvz󿥧-H.-H.!. 00)55 !!!LK}ioD pY,+6 %V}]AH.|h]AH.#6%;JaE[;%Aff3b ffff3NNN  󿿿AAA*** $$$&&&'''\jqOOy_!y_(-{d-ӀA  NNNQQQ!!!  777 JJJ...222III\.7\ee9---(ӀӀ   RRR&&&### """$$$CCC?LX f66 AAARRRRSSS666256\c'#P+m'|n %of8 yf8  *|*|耀HHvW./Q)MMM111LLL v791h[63C9w~uY3OO(0&&KKiOOU )s &&&ڡ ^^^PPPPPP񴴴 oNRCK>,#UJQ ځ) e7 7Zee9---eef6Q:l-@jN~ 1G YBaF& f3\\\fQQ'''111@A% (o(R RffEKP)kl &&&"""&&&yY6eBQB%H& 5*-=r?lǸC&J}ef3f3Y,f!YYiiDT= @J#2#-b )f=֜<%qJ-&Ż$! %,e7 ee__G #VKON ,6>kK%40-###')+]D& & K9 Kv ?0 g}OfQQfff<<<"""LL8mMoO>_2>G!)iAI<<<aLO^FbjMw\Lrl֪~.w\`2gh+t5)eǃއm20[:fN^4eg9Iȸg}t{ll>/OG =<0!)fff LfnA0!Asm2s[:ȸgfaOl>e[g n*/'hhh0f8 cS%2tз¾If92ؘf3hw}mtU`P-6SJyX(vZvLyPAf5UR؞ GBs&qG G hhhf9 6uMH>MH_h}zVmLoB/+OF"1 *|fA &K -1 *(8{A\RqR5WZ:X4O}x~O1OUdlO`lsyO`l{-{d-ӀR\ R R R RRJtS Ge7 ee*""<(ӀӀ2F  O( f88oAAA)fQQ fZ 444e7 fQQyX(AA   AvRY RT <<< K9 xH>tpzvo: f8HȸA/prLP^!jb vg8 f8 jIPszgf8H햺A~x%TAl{ww   ,,,MMMsNf8Hf8 jLYgPx9f8 yghf3Sgx($T̿ fs 邂000MMM L Lsȸgh(ت(WO4A %---''''''rrrNNNRRRtvzEFg8 P M l9 0P V@` @` UM ``!5yXV XyyTa 2b%kkkooGU W(T2828O2ˀyTOc 2bހwxs OO{_OvOOY&&& ZZfQQQ//fff))}$&&&&&&e7 eeZ eefQ???UGO ???4 )oXed,gP(.؞GP(UX ed,gO ) UA؞GP(Ц/?_ @ݝxxDO GO O  f3fFJF\a^^jeqa3/s}dzx6#rL\bl^Owg*[֣eo}.[֣eoJxJ+"ūybw2(MʠYU4J"ūyl^R]5R]Nzp_Ё4/=y% _$1{q\N$y$1{q\SG=fu`|[*y[*f306''OO;*('cceeN  *('fQQƦ:ZZ Q8 sf8 #!h_:fffZZZddd&h8 8 >ȸh8 f8HƊyO¥-H.-H.yXTTTJ K fKof8HǷK fKoىP"!h_7Y7Y@@@8 Hc8#drHc8#dr'yOs߾y:s߾y:*GGGssvPRvPȸOy_y_*aaa GG }} bb!!! aa CC!!!yy gg || NN###  ZZgff~f ppmm##BBbb OOOZZqϤznxAf%62fff::HH}}4AAA##  &&&g8.1\\> u|S$7$7?~A `~|~ff^u g 000 000::: (((!!!l3Y{p3f8j`jtK|~ff )KKKfffccc@@@,,, )))+++;;;^*CCfK[EـAv?:@;v?:@; ytyORRMMMf3;;;  !!!@@@;6/5 E  G 4 ~ 5c4 ` y`yHofofRRRR!!!  WWW:::---JJJ!!!KKK~tj9j8abbRbbrrr222HHH%%%333HHH)))!!! z`4$?4$?mOO,RVWVWjjj ###)))e7 VVVeefQQ`O,GHGKKKKKK   """ \\\F88cccXXXggg}}ll  `OyOyO \\888 KKK興;;==eed!!**$$!@% cc{yOЮhzRЮhDlR\\ R\vvvSSS %%%{{ddxx!1111  \\\)))EEEݗ% fQQbO#QRbIRO#QR[\ BBBll+++FFF***...&&&HHHtttf8 f8Hȸ#!h_xW wPyOwPyOPy3Q` R` R R WWWFFF,,,ajTkr>r[df8 j/r[d_OyO¥-H.-H.yX`OOjMlMO JJJ!!!jA=jp  UN+hKg@\/ g9\# P"!h_7Y7Yxxx5/! ʃ=F`u 3s v f8HɈ 7x0fCɈ 7x* yOs߾y:s߾y:*_vf ,03 6F`6"#$-?;( u+:5glKm<ȸȸ{eB/ gfOy_y_*8f &03-,Ś_Wt 剔 20"*"|=.8_wfXXX S.WìtϠ:60xwu35!ۓkD df8 $vGM8 )=)=A`ff///???$$$ =TYOYTL'."qWRIF̺T!³AO[ }ڪtm՚M}Hu%jH3P@{v{F{5+++111 }~qLC8RF+fls;l5sk5 b*1 57:q^`LO Djh)aR$K`K}[((( ###EEE}~էPQQa~lRF+^Q: Q~yik R)l{INFkEՎ hgK" hMj`qAwdzzdz 9+`WQHHv>>> eee[[[jjj{lQ: 'tpm21l +r=t]9]` LLQ30(((񚚚oooNNNaaa럱J!}wX1777%%jj *)WWf>== ###OOc%%%TTT777AAAFFFzzz%%Ⱦb`-7?sTQU:!ۄ߄"+C"://8^KK<<YYAAXXCRC*, ###WWWAAAddGH  &2Ѹ\"; ZZZccfQQ86666CT#+fX@XXX'''``````n-+JJO&z/^cgTQ ******F88OOOnn(# ---ӵ(J"$$$iL䚵5eJOFG(>+++99#:*G:bП_B`C f3%%%NJ{f3 F#&&&%%%nwCDPx I]{ac].f3^v---Ƶݩ3H= xg׀Th!I ^%veY-''!))55''BB1:::< /o>Q~b@VJ>\\ ee..ޜQaggw   zuu+2:¹058c &$& fQQᡡ__Q):%$l &.3  :9()+169 ###,=JV   D9 (((f8HǷ& f8Hȸf82yTg0 8 sA{vc1A???," I2$Y=AN\i DP# JJJpM1u\CUr51#N # K9 (Jf8bYn :X IgW+ Kh{aI7 S֬sR۪okKqPQ_l =<  $$$$>]wX1̺r>[U@!қ.fCˆne+<=E"7YON555Pdˁ׈9)xpBkK&fffAGS ȸ.-*,)ȸǷ/ Wml22x($Tyd} {24.th'# #5xaaa#!!!!!!K^3f4"UCJ Nt'g !Ah{~`vU+OA*&A@Qf===moo 2 "CJg/ #h"f3|wӁyPyX(AvY v 6|u+yXvZvK žt`@Qfd0a(9/uuuA/mDf@Z|+\gq  c2.X6ZZ|msa(@XyT4b>9˶T!tttnA !S;='<y yC*OzkrK"S$OR RR Y5" 4K: rmFUmF,-E-E{wk`OO`lO[A$%?[A$%?`RyrrR|O T(%?(%?8 0???W+zUogzUogeuOFRRRRR\Ryyy999e7 7\eefQQ`ogogluf3hh """ކjjjF ==]]]\.bb瀀OOOUjURRRyyy_N<} }7X*}p-X*R}R GGG???Q*-Q*1;!1+!f8 'f8Hȸf8 0 J;O退~ `O_ O~ nnyOiRiRR~k> nj{ߨg#yy* L8 shF4p]j:X/JPsnfDVg8 ܻPP:,AQt{ll>DDUUU%xA g9IhFrgdr L'sB fB^V#PyOG& &$sOK)222 Jf8 rg9 >8f8 qCN `PVf8 g9 lOkkFK)"e~TTT333ȸbȸ0 #rښrLL_f&&& eee999Hl$g `vU+OAJ\,6 fxxxf8w\7fQ}f3 c0yPyX(AvY ^ 6|u+yXvZvKyO,6 fT G#Tr\7~G ;jڮLAy"0|X6Ze|msa(@Xr,aaa5P yq5i.y`f<Ѭ&iGHX*0S;='<y wIrjC*Ozk 6fRRx 6((( /ñ1`mFUmF,-E-E{wkrj`OO`l(OOOY_gXRJL[OO''' \AWmL;) ! hȱ"""&&&f`` MMwaKD!>>[-:NNfeeRAAYBss--99fff...e7 7\6**6**:::: %%%===((( ===000AGO !!!!!! ???̿&ucM؞ik'N匸ucM`G`񡍻@zE#M *VP>"/4Aucjkƙ0ucjrչhE#8*|"O^%R9RO;\\)^f3bk;9)⼆c`M!G' BZ0ϰBGh`%l ._C V5ͣ3G_kiQ(_`kfl _MVw./qNP ^sw]v)/w./qNP ^lAghq8>489 \JY->4V T qN 5v~{ qN 5?qy4 9)G'T2 B''x``4 9)T$`KE?K/`f3f3 )3eeaa ccN_O?ePPddllޕMBB-##ەޕ 999QQQ ^^^8 2d0 fDȸApyOͺD`-##999 CCCUto%iDyNnvPCyNnvPfDfG{ywXO̞ rTWFq3̞ rTWFq3 ﭭ@@@M9iU pigOU pigO.jOC4K4Kyh~gF3Kh~gF3K  @@@[ǍOi*Vn Ljck9 >ȸ[ǍOi*VntE7Ot:tE7Ot:(U `:::   555 hhh 333###$$$***TTT FFFSS [[ 777ss9s9s0ee9s9s LLŨտf3Yo ^I\^I^I\^I$+G+G!$-  //AAA22///UU!!! $$ HH''' ``GGG 99FFFSS)) 44sg \U%. A?Xfff...888NN[[ EEEvv @@@bb }}///RR+RR"""KK ))GGGi]șwzWkrsWMh\ǚ f3nRz)VkAyĕ2yO`---''',,, ///###((( *** !!! X "~]Μd5k^ySvޚR Jrt5f3fpr9=̞ rTWFq3̞ rTWFq3%-?M.TLf#+6 f ///...  ///''':::  ***&&&HH42;l emיe3  R(Ah~gF3Kh~gF3KS8TL#+6 fff洴ffff3NNN666  000   (((:::m]:bL"A2g9 BX!fAHj9 e5;-h9 u|StE7Ot:(? `tE7Ot:`I(\S$ApyOR \ffffff /// 999...000  :::PPP!!!?yYY>__^I\^IOAWA^I\^I((\lU)~\lU)~e_Fe_F\=hsMMMNNN%%%;;;䳳EEE<<<888 &&&AAAxxx  {}$?,8}$?,8oR {F {FqsNNN ;;;(((--- !!!    oooooo)))SSS\. ݲee硡'zU3{*zU3{*|FQyOJ VRJPPP222   999!!!(((888d;8Y__N((oxoxluddXXdd PPPFFF;;;EEE ...%%%&&& 55AA !!!PPP   QQ  rr))RRP00 %% 887 ss!!!!!! F#eexl|oApyOApyOApyO}\\\PPP;;;;;!!!ii$$ $$EE !WWW  &&&*** ㋋`M:ePPo~~}|7A(VX*~~p-}-A(VX*|sKBRlB\sKB|c!\QQQBBB!!! dd**--- 111 JJJlll***///DDD&l"Q*  ӀQ*c8!jjjGGG"""!!!TT૫###JJJVVV&&&+++򫫫+++***fDclŀ\g@,!ȸ8 C0 ApyOͺD`退~(({~ww y*BB BB HHHHHH&&&FFF&&&UUUMMM4&MI       kAb51F3 wGi9M3~qh8M3~q8  V S) ̞ rTWFq3̞ rTWFq3:::AAAչv.^¾"# <~      ]9q>9*J7&z# *J7&z# Q* C4K4Kyh~gF3Kh~gF3KUUUJJJVH^%(+sj] 竳g  o      K0I6S!wrԄVj0 6S!wȫҼf3[r tE7Ot:tE7Ot:(U `>M( ???6@Jܴ{en  !! Nekj"j[ԛ+$]]]C * KW LL LL )|"} )|srg ZR^I\^I^I\^I$+G+G( ???tO#MqL,.4[YYRZaU.&!+5T |gjQ!65uc( Fc f3pKp% Yof%DT&&& GGGvJxۨ~[4mC:*?eRZa\<$,6A H= u7(eIJeE2<ο#YW&8 U* Qn;>5{'g~f8 f3fA3) oVu|yO`%DT$$$111 XXXt9B3o*?gtzU?gB B$!a>vR uK ڃ++UUGGGf8֘rp) >LLYY&.4%+0 1Ң= 2fwsPXa &”[#??XgݝE ~*<Ǻ&Iw sيhl1a1$$lhl1a1((Ū1EUmVLWNf|NftLL=cO-&&&mmm333 444<<@@a]>KW  VG tca]>l>lYYcc:5II}}ܯXs|5LOY--- '''&&&JJJPPP>>>ˇyyy444jdV 9'19@ $)  ($ ]5 - =5ee fQQQppfffg2OOO+MR\`QbL,OOO+ xxx888888zzzyyy111 2:@ƻ$1<aG !2:A  98> ߵeeզ' 3333-"dLL55⸸`b`2 555___cvWWr9ruuhVS%2=;zBn/g[[[3366(,> "" :[+ZZ[fQQ5 L_fff'''aaa\\\PPPSS||WWOOJZuuV?}} &**@]]p_qCUht *1f3S) fTi(((444 \\\WW kV?}}//&[  ;.'.T% 5[z%, `0999 nnn k vvv###OOO;;;(] kk06: """VVVܻIJ⠟^^BBBBBB5I77#5oo.f3f3f3L& "######&&&\K=OtJ$$$7 7|`aWW | |l#  ) %99f3  ^u%. (2 444f_ȿiAESS h# J.M`14{ ` ؑa3ccf99,,NN??=  I '2:&vNI Sc##+d Ylr!{ 77XX::..vv_QDfQQǾ11B44BBvvJBTyR/#')iLH 5Mtwl$ n)  ER^    BϪVEEBB++^^^5sd PyO???̭Ji7FcQD(V K5"[it!)·/;Fd>ǷԤzeg7>ȸf=0g3fDȸ8 C/gHTGhL Z>N=&gHSm-fDVD j/gHSm-fDj0 yOwQ1hh7 n?2IN6(A555XXX,,,SSS4vW4 w 7& KYd1=H 4acc|zz###lP,\\hʋEĸ9cC0KKlST^;h38 )9 RS^;gR`8 C0 BS^;gR`9'+]\3:d,64$LSNNNNNNs"n+5 ;,)=d}xxxƞ:WEϛg=n⸨0sԩV%'(\vq!4M< A>9992΋_JXۍ>`$ĔYC||zi]?*mja1f3c{ApyOwQ`6PbyOApyORfԊ#TȉMCYwXaƀ+%0G *lg`9RGGGGtt0\g Yui9#Ӥ⽄y ZzUD8 {i&  f3c{P:,?wQF(-9r;6Q|g`ApyҚIx$Hx$۬e FU2Hx$۬l>Hx$۬l>AAj?iNõk3 Q:G,~K))3~> CCC6(xg( Gteg8R,tTH% yO]>M8. {H.,j_HI 2pK)~lKe G&|mLi ,fBSxAG&|mLi ,f/N:G&|mLi ,f8 _>O;%AyOZB2m-`sjZxx8F3aX}]Ix> Kq& bm8&tF%B ;h; e>>DoDs4FpFr(FpFrr4FpFr `~\6jf(6jf(A\R \%R 醈OemWWWy66 _>O~\w-{8w-{8RZSR\RUUR?]\URURR7w GG `U4U4TmNO,RJJ m444\.000ee䢢  ((????kfk"b1  444444^^F3hf3555yyy...RR `ApyOAyOAyO*fQQJ\ t]/v)R R 444"""ކR$fQQ{=hC vyOAXP.hyʟ=hCAAR *vVAXP.hyOJ\]/R8q\fr;\ RqRRwR `M:ۆbf8X-{iu>"t]&)2WGĆm2*2WGĆm2fDb5rY8?(  h}ߣe5Qsc yT$$$===--->Ƿ;]RȨ\ JJ6{ ^zSr@0 j uWX85{ ^|Upl15{ ^|Upl12dU>(!wI-w8By?1IyTzBPyO %f~`666 nnnYYYTTT LL':0 9LLt0 7nJ 7 LL)=d| rylO`lOmvbo (((bbb n$- B4BS  d}%%%^^^PPP(((Ȋ~r T_*r( a1f3d}`+{>`6PbyOApyOF(-9r;6Q|g`ApyҚIx$x}( FU2Hx$۬l>Hx$۬l> '''f:3Ev8 R' 7W J"f=Vi#Kdjag8  `]>M8. {H.,j_HI 2pK)~lKe JBSxAG&|mLi ,f/N:G&|mLi ,f }RR+R\)R\000h9 [& !r5)K{(TNή9+ u: 2h5 ((%B ;h; e>>DoDs66((FpFrr4FpFr((QPWzOY 9TOQ8RRR>s+++00033 AB1  ż( mNO2cqLLv/%%%"""ccSBBF$$ww cfQ.]Z8%78DRuVE]Z8%78ڥ[@!93dobQU%Iy]fdobQU+]+]^b.+}T5=j:++}T5&NXBu;SRN=yaS6æm-?$ @x/_ū`^~[SRN=yaS% p2TEN5jj}{Rq&EN5jj}{ -brb$d|dl% ZSS~' G'$d|dlSS5x{x G' 5Y5x{x G'T* *0   5500\.66//3322*{'{d9ʽC66VV%%||ߥHQQQ++ ڷ&II%%ooM6**&"hhcc..."QQߙ...'''DDDfDVy!K >ȸ _>O;%AyO QQQ ܀\8 C0 `I\S$A@@@1mI]/z|~ن[C!wfDVD j0 ؆[C!w8 CۇF oOS$6jf(6jf(...000X)ύYwi@2M3~@ L8 C0 i@2M3~@TV@) G*\\lU)~\lU)~  AAA5yykYz*J7&y# *J7&y# '+&  _?[<$}$?,8}$?,8 LLL ww*  `MMM :::2ֶ3 !/fC2ֶ3 U4U4SnOO,  """  ͅ[?!QV>>uu TT 111***)));;;---666***(((FFF,, b?Ps0 Ϡh6\ sJ`?Ps0 Ϡh6wh|nBRR R RR%%% ===  zzz***GGG"""555vvvNNN6**6X h& '46o)h& '46 e ReQQQee777 &&&ttt,,,GGG444eeewP2}aIX0 +IX0 +  S9t+    UUU ...%%%+++6662228 ff@@j0  _>O;%AyO Nylbdmza  `lbdmza ` `cbtf `^RPb Rpi pi FR !!!(((JJJJJJ///KKK醆zzz~EhfDȸ `I\S$Ac{((((퀀퀀 (( XX22hhIIIzzz(  mLyO ȏQ+WmqX8 f8 >ȸȏQ+WmqXfDPuv2{XG(oOS$6jf(6jf(hhhFFFՄI W{   g 6(%iCޚN!:vPsfDǷCޚN!:vPҎM߼GG*\\lU)~\lU)~hhh\K~G!I+  [     f WAZiU ojhPU ojhPjN _?[<$}$?,8}$?,8;;;]# r +"Q     k ' ` kxmoP|I!mdRHs֬$-x P      eHd8y_O8^y#m Hd8y_O8^y#m  U4U4SnOO,fay\\@?:tČcW>2s      i RaOuC!*VsQ.jcLE>ȸRaOuC!*VsQjT}*  Pczk4{~zk4{~kf|yOe} ӽLrR( c<@?:0 Sq{  x      gooomhc$).ss9s8r0ed9s8r LLd}((oxoxlu f*:=*:=i3.  39dWP#-vS[Q]'&$M̚,~هPc  VkpppAAAP-O@Ypq0&b>5*?3$󏴝35k˕ηz7,"RKHKHč 41-K# MĬ>/Hl$l$- (H_w^v \\\Bo. A2 0˕!`:79!M;1nehFWYLD@%+wwwN=tU>k c1>\ RgK^³d| """\\\...v%9mJDsþǷ%9I#DM$$$@@@! ZZ89H #rXJֻN. hhh LJA- B* F1 Ap Ihkٓk.i]^sW).汖K" XnЅc$'8111###wĀ<8  t*( 4˶#W(BPx^`E e ך# V t"ЎȨWl +4{C D{x{䭔Mv>~D YldDCחG3W{=hCyO{=hCAXP.hyO""" 000;;;  4 TZs]L +*8 -7ὓobFˀq|\A e~Kկ!R̀aVaX"ΜdC.ޚ8 JqG2^DBs4C(ApyOCu(R%%%333!!!@@@б0ONZާ@ RBl >7*>7*յ [~?tEx t2$ nɘ]W  vvWۜB!3O77K)&&&  WWWBBB\\\3318F 0""wζvRp000̀]@Z MxCNZ[lO!eˮ  ooXUUZgs B(;;4pEa m R$ r))HS9 8SjdE???>>>ggg222DDDF |2[2vf>AՐhkd!Va&df/+il(!ؕ]77zzddfO*4Oʌ: )L&7.g D OǦ汖cAw< :/`yOw<  9vHHXs2!gYHNvHHQ9 DDDVVVSSS111###i0z0AƸ:Hd8%::GG;;,,]OA J"%gS_)msA66GUa(CumM:b^L EA2s> BX!g9 e5PъM))^aL((((j.AlAjw "fw>%vsr]LWSH|8 ZZZQQQ___QQQYYYlll:HdMBLm5X?KVq? '`OPnnooEOXȿ! ]4?yYX>_J ZVGv}:ט>veH -yLLO8 ZZZ'''VVVZZZΟ;;;EEE#^]GG//@@~J(& '-.1fbTy h EE3]]c~_ZvVw}YPKi****&&&222YYYPPPٛ ,77 jj&&г蘀eWW`T2 ϞB.ЛSS2 2HG\\__ 'RRާVmt bOT%bO' pppttt\\\((??? LI,'- &&+V3Ǽ%,1!ypxwv00 ss ȡ #>>9w6'dd'''VVVxxx{{{(2uuu0"+;ALJx{] $l_jljZXd駌9AH#).  O( 222QQ /&&(]] 4))2((Xͦ,,,:::dddI(ufa9A{O%. xY  BBet +0bC%)))*** TT XEEZGGȻ9ayZZZ555 ###I$I"Hš>833<<5 1113 ##<<ҳ $BNX+0XXX cOO]t 444BBB<>33<<5 ڵK&Kn333f]""gb~JQU8 32 0Tif+++AAA&&&*** ~ ''RRV&&ڴL&LA&AK&KnvvcccwTSkvRJ 4X,999333<<<~/0''V&& 2A1A  Ʀ""ZM!+ 6( /" + c1///DDD33 kHg^ס11  ::ZEly7 L7 H$+++QQQ33NNG))n -9+++###ZZZNNmmmՓœh?e*3ԕ[-@ &ZZZ777...{{{C" $>,F#`0$$$ gx9UO`3 `f ' d2H$Z-  \. 4"u|KcXPX rm+b4i_ƼsrmX?9nf3-9" u~Ԍ\B)PXĹ5AMZ 5-]$)757!% M. '!(3A&V+D"c{b{ '4? M}` 5,Eй/X52?q(4L!;;贆نu%uRR L!')쩿m!.  L ho52;2S-<*6GGccSSIO7  H' LKX ek-5 d>d>0ⶸJHHccH B] Xۘ~L9xSov8#  Kt(ppWW e_ LLL) bb Pgnu Wu %#  W]*nJ "8SUU ( $&0if @:&0) `LLyy^m'ObnMMt   $@]YcYGLR[0#$ *05# ( &7ӀR`kjj ޔ%(.  LuY;FRԾ.26""y --" 4455T#MMM]ݞeȷlZ|](/5+4CNXȸfDȸ^fPA `???@@@ӗ0xXheDꒉ*18 j/ jdnK5%$V `#222!!!tE83 dj]]kvnNQ--} g:j0 lQ8 C0 fDȸJ gHSm-0stТHsLfK Z8 g9 >ȸK Z8 .g:>ȸ"0)n?2IN61hh7 wwwVVVllljjj $$$ :AE5 !uU~qû)19&#$W  ...E #Ex_*>V",8E[g9 p9 gS5d7_rfw kEq9 sgEǷq9 *>̺lzvf"FaoK# 666 P@=<^>=*2: {bG{|˃򻻻j/ /ͳͺorf9 $)"  %B $$MS) `lofN@3m74B222ǰPPP߭, 6,FQda2cjQ 6-"   6-" - c   wwwVVV^^^TnC^[***X^B@G"*''''''YYY(((&&&^E @ bLk R#f@s)M{m ,T'n{rG }X/F'mYHq@&Ml1 \7x2d\>zC>ȸ\7xybZv]  /(!  `fHZYYYEIb(N-jUmq$=yWw+Jtq7!6}}}}87'@G999UAuuu[DsBnBm i wL@s_A{Azs LK66l6k6s¤,A K^(( &tVk,,,RRR0U:xdG(o&َ4S/0X.r؞(}31'0bKLLL888* H6q -8 9G)_20 ;GH`|аi` 4rZ -2 2sVv^uܤ]0z +w( 駡MQ 8?=)Wmnnn$OPM%"Dej}K*C]ضB(oƥS 999:9 !Y_"4b.1mTihApyOA"~^D ``fbzHZ!!!nnnmGGwiii"_e1đ[臐Btk嚸ċjXl-8 Pizu f3}Eh# 1= )3 `+>Y-f*5 *5 AU4ڇ`|f)";#s+R5v8+ ۀ2 666PPP^ iutL:h_dRXí1ob#VoW,Wl"ɽ8 `o *vVApyO`].^ /tQPI=wJ(^ /tQA `^ /tQyO%j; ;|,s,sV Q΃555AAA njHL$OD+XD-U lzJ C)3Y o y-xxQ8lxXxQ`xQ('F%  jjj)/G o;@ $b:$ *łz(q `pqߝid%TT%$$($( ,3J+ߙ` Sa Fn ?Qg9 )U,. G‚$d ,Bf8 .W]KKuAFcK[hf!˿PaHV/T GJ8J8J8A#!c_" `ɛb%)R|: >a5r!1'd*9+<Eֿ@333kkk03zmzQ:SM/$3uLzRnD1@Hfy*kXu_(-K@wd0yw wd0yw ; ! `wd0yw yOͺ#(R\Rs \兰(0 F̄ *VV|||gLiE(('k'cjow( !w}J2 ry(( ryZE[ZE ry((C4J6K`G8PH.`G8PH. R8jD ( !eee__͸;̞]ysW=3̞]ysW=3TR \[?Z]ZRRZ\-V|V|P"!{zh~gF3Kh~gF3K\hF~!z{mA{lB{u\{lB{\{lB{tttyO zz4s3544 G4444%w?!]rUW:Epw?!]rUW:Ep*l#M;!@BBB,,,xxxsss  ߵEE 5cE7Q4 5cE7Q4U9+ ``xĦ*? RnUmsKZ>ZZ RZ,,,555\8>>> FFG88^I\^I^I\^I$+G+GIn%+1cp www$$$\\\ WWYFF <[ ^^^WWW cOO 222:::++ [rFi# 0www$$$___ \\ayO` ` ` bzRfĦ(; 7v\\ G$fQQa ((`xd`{{5A;5_^x"A ` {F{5tT  `HIHLbRRR\~k>Lb7t\~k>"""666b?Ps0 Ϡh6\ sJ`?Ps0 Ϡh6wh|nBeFi}\eFf>%%%???6666X h& '46o)h& '46  {F zcqsb {FYfqswP2}aIX0 +IX0 +  S9t+ 3e  竫hA ` Nylbdmza  `lbdmza ` `cbtf `pUA:Vtt^ Vtt^  kb8 $Gyux8 C0 8 'e_ >ȸ `+>c{((((퀀퀀 ((|7CH\JGV\H\JGt^t^9xruWWWj-h#he_efDȸ"vK ^ /tQdd XX dd::3  V~c_qC .W5)_<o)8 C0 fDȸ~XNGI&NszgSh!h☳˃]Mq!8 f8 >ȸ˃]Mq!8 Ch-ReU1 lzX\x$۬i*xQ(333E MGNNɩv5i;WesKhIHY+|C)2Wz5m2Ka\r|hF?X-{F sgEǷhF?X-{F [Cm֛1 `E"$(WWWBBBj/ Wpd_ogi,3@/ mw^ ggWl2x3A0 ku) 3A0 ku) :wt35RmLh 3fJ8&>>>ggg222 ,srڄmZey50 Ш<ݿ+4Fp?1JFwd0yw Q6, `d},7  DDDVVVSSS111:::8 f(X9g9 jQvHtYRv'6h9 IgHl'8h9 Z ;Rg9 >ȸ8h9 ZȬ 0$ EW((lO`lO ry+/J/J;IZZZQQQ___QQQ}}}ssBBCCudcIs LLba basu-8 9GHZZZ'''VVVZZZΟ;;;JJJCCC}}}r^u***&&&222YYYPPPe~$- BR pppIII#5/m YoAh{~ApyOA"~^D ``fXn2? >>>_*r( Ȋ~r Tf3}?_ $ %. /; yO~wQY-f~'''VVVKKKۃ!D7vpv8 lW,QerKɽ8 `o *vVApyO`].vK PI=wJ(^ /tQA `^ /tQALBt `dddh[ f9Bg!f uAJP#˘|{f0 鿃(`xk`? 6P:,?T2J C)3Y o y-xX\x$۬l>8lxXxQ`xQ(L555 ###hIInKuT{g8 7(EӅs5ymstԤ/_-uSxQ:SM/$3uLzRnD1@Hfy*kXu_(-K@4Fp?1JFwd0yw ; ! `wd0yw 6}RRܡYvQ|999Tg/L NEԜ)^h8 $+ @ Mg9 e 'k'cjow( !w}J2lO`lO(( ryZE[ZE ryڤou,ӛgz7///\ǚ\32UU )4+).;F>+aЃ?r ΌZxW+++bQҺ˜zh3v>͜\' 0$  #1+++###GGw&wۊKKnwAjjS\cב>57i:تyzp;orKluU!4ImVd^MLML!~_vaY 1`c'$$$^^ OO `LLO!889:(ee3(( \\5 VDDK PPP  ޴?BBAVV>9@@99$B44O GGTTT E( 333 ZHHpdpii ***%%%******//////444 111???"""(((((((bO A:A: 000 &&&&&&A +++ EHOK)͵]=ZfCƄrV>:| eJfD ٭ 1N݈Asl; |HIT=MdF :y>|=lЍ(37hq3_2rq :y>|='VMهlP93'1De>˦0Lf;ȴ;E O 0NNƆ~V CyVOƆxx G GO?      N'Ŏ =,Nq;<&c9' ̴jr |Xz}~Qf.7I u _i-1) ,e,v[sx*֨$9v[eOM[i\t0r9-٦ sM.jCs64, TvT޿\Nz,&= :7mdI' !n5̽912mVo&= :7mdI' #@0 +.edU &= :7mdI'  ׷ 2?RqRϽ8: /kY|唈!n5$4{mo=0ﲰ HYϽ8: /kY|唈!n5  $A$A.Ow줞ri #ЂJ{MN: ЂJ{MN: ЂJ{MN:.|.ۍVl ce STh&};㖈d/ ce ܏Y|:<4 Ѩ _!2#߼&& 5Cbyuu&֥%2#߼&& 2#߼&& xU2RP7 G0Dl'tco|/(ڰ}S^^ 0Dl'tco|/(ڰ}S^^ 9q"@z^@z'@*%O%O G`G :r:2o[o'@*%O%O G`G G`G'@*%O%O$::QrQ,o.,c, G`G(}(,o.,c, G`GN(Z-    ,11##-- ΍܍[[q#q i/3 0055EE JJܐܐBB7ι@4)Э'':.. TT22==I\\\ .$$22922++ MFMңYGG??wwXXX DDDRAA񬬬^^^Ν!!!***DV JP$}~^>j0 DV>j0 A -eQWA y`OCCC3E@Ḇ>bŅ=lÔ y`Oۮ%XqN;(A褤000 #k\gQ^m@a<ÔͰe?%vy DV–D >j0 Ͱe?%vy DV;\}>j0 {=cC5{=cC5AAALZk"}Ji2f=&}rKKzeg LsEW>j/ f=&}rKKzegŬjƜP -eL;𔝚?Pr0 ϡ!6 f6𔝚?Pr0 ϡ!6 f6򲲲 ///jOC;kyQ"5?;=d"f 5?;=d"f 2UtM  y`Oh& '476h& '476 깹@@@0UU',!2Kě!G  ',!2Kě!G IU0 %)IU0 %)  444 ===Ad@%i#syh j0 Ad@%i#syhlbd䜝>JJJ&&CCC 33AR%FX%:I+5 `xĦKo% J66&&44%%22ܴAAA... %%$$:::HHHHHH[[''']]3322rr }} ʹ϶Ȭ BS ˾ŶŶ,7 :HFj$fff///777 QQQ ??$$$pppgg!!!2222SS %%%JJJƩDUƶ &DC *;*N...888 SS    """  ///!!!ڸ\0!JP#\vm2fFǢPC%OK =\=\Ns)hd3'84/8 $, @P +ZBN Ba!ƶǝ---  111/// """;;; 000,,, !!!!!!so/W Ο*bSwPv$ a(ny;n 3g5 *@*@K^;EKԗm*t!U{=cC5AP y`O{=cC5AP y`ON%3? 3@ VkXn ĦHm$!  >>>:::<<<)))  &&&666 !!!w DO6࠹WK6Q:^=AA﬎K^9a8  (D%B$CnR 𔝚?Pr0 ϡ!6 f6(A y`O𔝚?Pr0 ϡ!6 f6uVR,7 ,7 fL^>>ooo???P -eL;𔝚?Pr0 ϡ!6 f6𔝚?Pr0 ϡ!6 f6^\{lB{ \ {lB{ccc??? 111  ]]]\\\--- ***  !!!;;;FFF!!!MMM y`Oh& '476h& '476EG44 44 evvv &&&    ??????YYYccc  IU0 %)IU0 %)  B Bvvvggg999       ''' }}}}}} =XX %lbd䜝>>  555'''  444KKKzzz54354aNNYYY      888"""___000ddd ***!!!|||[[["""... $$$ۭ\\\###:::666 een  66__6$$&&&111...MMM999 999666 ^^^ 5"" CC !!  // vv77.?? %% #!!!ggg(((Ƌ ,)f98[ A y`OA y`O(N(\ \ iii$$$*** lll//22$ %% BB  33 ""uuLL << !!+++|||nnn|||ddd%%%(, 00,,WdGBC,ל\SHA y`O(A(AbZ} \ \ \jjj  迿lll~~ ""NN HH  ))CCCC&&&"" "" AAA=== !!! ooo%="((==W5bK M5쥽8'8C.(A wWط Y@N,AP y`OA x]1͒Ҩ^@K. 쥽8'8C.(мz3!1I;D A x]1͒Ҩ^@K. HfH5[\X;\\ \X=5[ -d\X=}}}JJJ 00##RR2200 EEB!!!666!!!VVV JJJWWW諫PPPK:*د'':..q9 ̠#!Uc i)Ȱj0 DV>j0 A -eQWA y`O]Zz]ĎϷJ ,(fCD? 5c/룽 80QD/*lo9úЬ( y`O 5c/룽 80QD/*kf|Gսj1 y`Okf|Gսj1 y`O*YzƼO4"+cJ>A{)[ H@A\ H@A\^ ^ 9/d ccccccCCCMMMaaazzzȆ(z T.3E@Ḇ>bŅ=lÔ y`Oۮ%XqN;(A 82F2F^I\^I((OAWOA(^I\^I$+G+G$+G+G&?&?(DDdd XX dd::::33 XXX[[[111zzz+++dz/*6oE 7"f8. #k\gQ^m@a<ÔͰe?%vy DV–D >j0 Ͱe?%vy DV;\}>j0 {=cC5{=cC5OOO x5% J"} c8W0LZk"}Ji2f=&}rKKzeg LsEW>j/ f=&}rKKzegŬjƜP -eL;𔝚?Pr0 ϡ!6 f6𔝚?Pr0 ϡ!6 f6>>>FFF !!!J"o"3&A#   }>NRȾ   zôc(e7?#OC;kyQ"5?;=d"f 5?;=d"f 2UtM  y`Oh& '476h& '476777>>>$$$%%%0 b0bgx85.]]jHOVBCE $[4g, ^6a50UU',!2Kě!G  ',!2Kě!G IU0 %)IU0 %)  >N%I[888***Oiyb2Ձ/ $%M _؎C "%ǯ(0:;YF"wS{Vqm_6Q,Ad@%i#syh j0 Ad@%i#syhNu' !)7Elbd䜝_HDWuO@*("vcOqkURA.WgSp{Jܽe ;fvu~>$$?7ܙ  3_F lF3   cg d&X~ ڸ\0!JP#\vm2fFTtr)a-D-DHZ"c9;ɱ A y`O///  LLLnnnzzz...Xrܗ|B ]KvfٜKڸWRe&g1 \YW\YW#2rK19JJQQackRA-Wn^^K: B  '97+,  䞞3Z& oZ@ T< ! m A=~DI,;=OHiG]pW?&HHPuu'p= 5集PpΆq;* Ѡ(^N M m0^VeOPJﭰ쥽8'8C.(AP y`O쥽8'8C.(A x]1͒Ҩ^@K. rrrEEE   %2"PW #1RKNOU(+78[F$LA/sb )Aq  H3jK (  {ǝ1):"3@_^Y tоz '/56>EbgmE+oN so/W Ο*bSwPv$ 橹1,hylx\&#IkH$]̠#!Uc i)Ȱ M% - aFK7kbP D8}Whh9GS9GS_ $𞘒  w DO6࠹WK6Q:^=汖 $3a集PpyP+  YN?T~j/h]r%?g2Ŀ.K8h]r%?g2Ŀ.K8AZr+T+   222xxxUUU~~~zzzkkk -0  8< #5-v0zV*q2L80w[[[&t}-> !! _T& ~; Ro@ Ew,CP$=:S y1벥@GN(.5#  Ciȝ(\{l5ਘSm ˉK2}dJ!ν I.6>ـ>F ???CCC888UUUvvv,<5d[".)/aGMY'# (8Ǥ9\x $6qQ)?=,?=,=0@S%CEBD7 q+z7F¸\G , R`$CE=mw- ֶJJJ}wp _nz  C$ .9o9o瘆Rs㩆`, &;G&诨o[4JN2Ύ 7)쬜n-Tqw?sULg i:@;47.: w?sULg i:@;4vS.9 vS+bV!vS.9 TTT[[[ ???///nnn (89\x 0-%RAH{03 NR_lN'*, H[Q:ɗyq~杞'w0ۘ?l9652P9 $;ȫ|b7 &q  gTC8Z>>444---ddduuuvvvH0-%RAH~lnG Q~#x20%j[=B652LX[Y9Vk8yy )/5)/5ó'/5YW[  O+ 7) lrI3k""((FF ))66(-2'$  1#DDBB88u((^I\^IOAWOA^I\^I( ٤uu-|8 yWҁSH-|8 888aaazzz>>>>>>\\\vvv%%% (((!!!@M%4Au%3"=M[(2 :+ zY&JY$) ,/Vui6",910/ MU&&44==AAƿ!)(15* 缍vNd/ 8yW-|8 ***/// ⃃xxx222MMMjjj%%%^^^000@@@+BZ邃Y!) L%h#%ز畓 @VCQ] QY?? =++11XX^^ʰ2t}=Π3asN& $$$ SSS333lllZZZKKK2t}r*** )5((l Џҫ>?;>Qb %+%I ! =)OlO G4Hoooo .4;  8?D5$('JJO??Eوڈyyoo((NNN΋z5A<3($5E6?0=4Ԟ\6 ٮ#Jl>!ڳ$G& 666PPP```OOOKKK88tttKKK[[[xip+h+!5GG##v  eMA#÷80*6( "IHH  4 4O{{;CL-Xqxsi"J,- % ee L<<x&xx&x}}cc&&PPP+dm %3\yvI4N1¢l+x6ҡݶl bL!`$e+x6 :::  (((TTT---EEEWWW88mmW>{jy}h{ !"TCTmW>ITέ6_B!   0"cni] %%--%O% ͟pW[HVc& PP %#9988! F77>˺Ӻ ))11 GGG  5J 5J_?e?e6=^|=^ iii666///SSSFFFFFF000WWW333AWKK22  T`, (/6  Sj  -  A$JJ#! -49P'e FE`6  AAAbbF886++6++$ ","" 666666 !!!,,,!!! ''' ---\\\zzz--- W,W,Z^0.] / 4?I3BS~gY$^],v !% 4()#444444bNN)!!)!!²..9 6D))))))&&&222,,,***AAAkkkmmm66ļ^D]""ZZ*_֡k55V'NO(O==(:9::} @yyWWW 9_ 2K%.% CT'Ti 6,6;;C""^^rmnZ'֡k@@iϹ1G55>ȑvvoOÁ*ZZ}̢@o|xD@K ͪ  ){w{pi58<|n s+mH8&mYVA 000&&&+++///$$$^^{Y'- @@3i1G g6mS1uZ K14to7DsLLL6( aFXN@5M0N1OOyJJcXkĻ LYe6<'GGG XXXIII~~~<<<lY- v++||  uZ K1476,   aFCRk;l5Fdf    E" 111 KKKzzzM\K&Kv, WWWW= Rc21RE* ;! cL2|N tB Qf_3&,Q,} OȊ(p               14,,,///!!ܴLLL000 :;8;"I$l1:f]Ea)Q9m:X>fXX 999///ܽ<<&Y2$# W,E"  WWW$$$$$$ᤓ%zO 6PPP*?`qzsn(ZZRR6">f< 00+ 640$$$cnw4,]:sQn  "Yˁp]\nݾA%NKN2@777³|{nU0̄q[pKXcwtsB4(½ ""#0$  N'$  C" Ƹ4A 1= BrgB'J F>̹xy  #B]#K+&/8 qIF/?3&o]J]JsYt*AA!B4%DHD2 ""D""  N?eg@{1 % *"AlӅ B! --**888㥀׀ {'{f!f Q5a@  8   N=n  k~>6#ސY%ԃO&II""CCIIhhhh@$ $/)s   J6T  Ff*& kW>  // ~|!MOH 0"///ĪP@@!!5AAaa%%11LD> V_E  ٨ Xj KKvx ty@DJNebD;3 ջgԴ 4i| cc  ///I::9߼77)!!AA&/./ۈKT 6%n,,  D;3 2)&??9 ְvzyN[g<40<40**  FHbސ)   ?2((ߗyy||::: nn55L " #,3!!N46#DjF*J/.25ż 996 2((::: "! m2 aSf  鿱-4;5>F&2< dfSMMg@""#    DV "2WFbk/ DV>j0 DV'ea(>j0 ???"""2229w O--.  s %  hH꼭kBF!#&!r "pgVPP   5'>j/ ۸kW-_Xf7 {DV>j0 Ahc~A y`OwwwVVV---|;  Ϳ JĒc).H*F)ŸhGh"'ZfL j:8»(/5/6<4@I ?<?a԰sHCWw' +#  ȿ6(  .\VV}^忘 "3R;Q_1(۪| #4]Prq)DV>j0 DV>j0 º$+HnT^~)7dRld!:ShQόhv~)7dRld!DV–D >j0 ~)7dRld!DV>j 1e]T1 y`O0@rQ>(Åyyy$$$ כTb_ $8oJUo e, 4I@Ņ=We&vR_i 5AJbháh""" -–E +M%ğOF!\ft@ͭƊv , I}ZZ|g)Œ[KRv;5RY5%ئ`h4QX7&ڧ}qq[Ām2K>H`rL3QX7&ڧ}qq[Ām2 LsEW>j/ 4QX7&ڧ}qq[Ām2Ϋ[C ^S{_ʧ0' ُ"` /jPK ` /jPK VVVUUU222!!!PPP,,,88{~^A ̧r3f"(- y@JR *y `qci BIC5) &+ >j/ :W}~Ѥ_ cf, ǰ妦ij:+ʸ3^; 3mh Mj˺3^; 1kg Mjᯐc( 2Mr;ux% ʺ3^; 1kg Mjᯐc( ˺3^; 1kg Mjᯐc( :J @Bw@P +>T9P쇞X\p$۬#Li>(쇞X\p$۬#Li>(wwwVVVsss KKKΖ3& ;WZjx,Fcw21 "G44PlllFFFB1  ,sksڅ_Zr( 5\=/ Ш:۽:ݿ+ @:ݿ+:ݿ+ y`OD"$(D"$(̊yyyXXXbbbZ5lFMZ5lFM D@4D@4Q9 >= ( 1 ______ ###ڑ///qqq222AADV!\q! (L xDO>j0 9QvH{YRv'IYUpFh'I[SqZlt(I[SqZlt ;KRԪǜH >j0 (I[SqZltt3dTDZx 3:8t3dTDZx 3:8Ks)C'%Ⱥ 0; @PVVVUUU222TTTRRR5XG! 5XG! ݔD>:ثG  )($#!)-&&& &&& WWWaaa=, A0  Ls Ls(BBCCuKddIbb Ls LsIbb #rښrIbb Ls$ ̿0= 4Fp=䗺m 3#JF58 4Fp=䗺m 3#JF58 tjzIѼm³,˩ y`O3@ PcwwwVVVqqq```III f?i7pa7Ҧ{d;[h>e2sd6˞o`,vo(xBX7oe9Ϧ}fA[111=;3 ______aI aIό+++uuu???>. P< T~*?O!)( lO`l lO`l+/J/J# Wl???vvv """}}}ڑRi"vo%:jD?vV3v(=ooҀCX&}Īh!=kH9~vS.~-ttt *(42-111rU㭭fffVVV###˰ѺCT 2VJJJ!!! %ooɺnFN  cc``` ?=~y)(  2ppppppAQ$% 0 Vkuuu***^^^ 2gXϝQd嶟We1 ݞe`MSkM2sNh`!ΑNr&΀JaFrS"""*(xt DA  . \.=L$- A+.t?8NA y`OAKf5񗚏j y`O5TBB3@ 3? ĶPdvvv777lll 0lɞoB0 %->ZҲ5#b*o5 +AvhExk׮O; !*=WdD  BY_yf+Nė= ZZZ77XW f`87  2T*ŨT~* %. =L y`OڐQOb1v.#޺zA y`OJ\ɻ'0 ?O͝}&4;Lfo5QY4ҰQͧ .Eaux`:O/m MB$Ceo<@@@444uuu7ff G G8ff )TTPP|||(/겨mX0RЮ3S ޻^,)lPtwJ)Pw>(<(<¡GX "0T1ʒԹ/!+b41P ɻ 3!1I;D A y`OA y`OG.9< 䘻 3#3E57 Cvf*"CE 䘻 3#3E57 AP y`O䘻 3#3E57 A wVÉϺQAP57E )2 )2 k6\3ͮx; ؎MR}ȣ ޕE=U0dŁ/ tLJW4W/GʝG???lll`{stz蚆Qq6cG "EElzfɜQl^Kd޴l>. Dg"K^P_L>`7;PJ!+՞^THˠ(/O` ᙵE5bK ͻ4+WRZv̺5 *Th[v8ζ!:fF 0LgʟZ21x̺5 *Th[v8ζ!:fF (A y`O̺5 *Th[v8ζ!:fF s5[1G@ 666gggŪ*U|iG, Q"dhۗ QVT&ز(R  y`O[D﬽Ŭ:4]RH}kkDGeTc  8f7fUc 7f7@TB~I>U^6fUc 7f7@TBfUc 7f7@TB `_i| !mL!l5U!tǥ&H9HHH555sss### ־'iMӦk!_bȳ/uW? XQ@ۡ3עf[q]Q5[jAn5[\\ 5[\X= -uu ;ff GGkG;a`P -eL;𔝚?Pr0 ϡ!6 f6𔝚?Pr0 ϡ!6 f69 kE l$bHf t&m t'hF/##0 t'hF \ t'hFk/Sk4 """PPP...... y`Oh& '476h& '476\VJ4'KO}\ 2k2k?jn2k?2k?z&&s𸸸 IU0 %)IU0 %)   ffu EEE@@@0  lbd䜝>>YY ) (jj%SS:I{ Hm%" m'*9/d l(?^D:=dH@A\H@A\ H@A\ccc`222$$$.... L== A` #5 ``33?? ldd ddXXdd 555yyy222<<<333ZZZ******bNN3߽Mt'444www$$$% 3=\(;YYYBBƋ ,)f98[ A y`OA y`OZp`x ĦFj#' 555yyy222"""333  88+""WdGBC,ל\SHA y`O(A(A Pcŷ W+ \ \ \ 444www$$$&&&@@@yyyJ& 4WFFW5bK M5쥽8'8C.(A wWط Y@N,AP y`OA x]1͒Ҩ^@K. 쥽8'8C.(мz3!1I;D A x]1͒Ҩ^@K. =L0Gz \ \KKK OF> q9 ̠#!Uc i)ȰA*m x Pb xpi pi  WWWDV-NL& DV>j0 DVAf4K]>j0 DV>j0  "0T1䘻 3#3E57 䘻 3#3E57  82F2F^I\^I((OAWOA(^I\^I$+G+G$+G+G&?&?(  XX 22hh 222KKK>j/ ⏃W|kn&% )5%ɪ.s+v$V٪P_L>̺5 *Th[v8ζ!:fF ̺5 *Th[v8ζ!:fF pppڵ <ߙB>j0 ھq=Qg3DV>j0 DV>j0 ZTGh [SZm-0sUkqD\Ʊ HMe[SZm-DV–E >j0 [SZm-DV9Ug>j0 y`OfUc 7f7@TBfUc 7f7@TB 222 ^^^–E  "1wim/ θ$9,D-/#a0HR%䒄Uyf~~ضfT6b7`{ٷgS5c7`|rf%v kZ@hrDD!ٷgS5c7`|rf%v LsEW>j/ ٷgS5c7`|rf%vˑ* - b   - b  CCC888PPP >j/ /SRʙr9U^$("  &B$)"  %B (暂$)"  %B$)"  %B:MS)ybZٖ /b=(ybZٖ /b=(!O(ff y`O!$- TTT[[[ gggj;Y4:7>a/ ѧq׿U ?Sf-є#`Vjg/+#˭Ż+0$à} va#Ϡ 6GS!ˢ͢eb6'צ}u 5FQ˥͢da7(٩}qQp"  5FQ˥͢da7(٩}qQp" ˽P4  6FQ˥͢da7(٩}qQp"   ,6 ( &t &t*XƹHZ3? 3@ AAA111 ```ooo>>>444bbb @Y}˷*GR?<%\ɚ[庈b (5Sj0 mט_~~7)7xme! Nu'ɻ@P (ŷ$- @P888aaazzz>>>vvv~~~F Ls %KB%KBm GiG QwQr@JJr6A{A Ls Ls6A{A )6l6l6A{A LsϷ̳CT ʽ(.>***/// ⃃xxx222===>M'6C 4@ %DU$$$ UUU}}} Y-9H*4 A+.t?8NA y`OAKf5񗚏j y`OCSCSHZ%,6 :I666PPPbbbT*ƩNu'$ (@O y`OڐQOb1v.#޺zA y`O4@ 4@ `7;PJ!+՞^THˠ(/O` ᙵE5bK ͻ4+WRZv̺5 *Th[v8ζ!:fF 0LgʟZ21x̺5 *Th[v8ζ!:fF (A y`O̺5 *Th[v8ζ!:fF s5U^6fUc 7f7@TBfUc 7f7@TB `_i| !mL!&&&222,,,***AAAUz{*jKgߜ{S, *NNۂ%(pA*NNۂ%(pAɳ cbʼξǍ}s|ūv~>v ؕd( A6;<7~ikff y`OK&}}*5=%ybY֕-6ybZٖ /b=(ybZٖ /b=( }4YY y`OybZٖ /b=( 6}\ӛ5>SlZªv$eI000&&&+++ Ű.^;ɗdr{_곆Kn" 곆Kn" ݉'S`/-,8UK]^M Ҹ2fO ǽ ((m\vm+Z+KC 'uSJ &t(( &t:IqI &t(ȵ !.;CHE8# 4v4 3Qs_ܻJM濞#/D\fS/GGG XXXIII~~~.S+u]| 5"1pqk(ͺ&@R.ͺ&@R.UGBb %"za@A(b:ثO A(b JޙFD>za@ /DFO_][O'  G۽֕eE %z¸p} y+B G۽֕eE&~ùq :0pFM G۽֕eE Q1C(Źs xSzgy\ΗB %z¸p&~ùq :0pFMxSzgy\ΗB ccظ}[f3چJA{g58}!چJA{g58}$ چJA{g58}"q|&t;Lôt"+ɷk!$ +ɷk  A(b")" T( 3~9q߀B " T( " T( ?\rX"qu=<赾0 .?wl7l:ثO .?wl7l:ثO 9m(n9n:ثO  GXX GVVXXGGXX GVV\\ G GG\\*nn       %**uݡƈIENDB`sardana-1.2.0/doc/source/_static/sardana_server_np200.png0000644000234100017500000433421112174204305024655 0ustar cpascualcpascual00000000000000PNG  IHDR<F pHYs3+u);IDATxXg4p ȉ9>qkqSj)M' N}.8?N$y)7kq`cMNE@rBHBBH=|=%v' g4f338;G\pq\.]vT"ԭr|G*|L1!tcC"* G"pTiQwI9 # g "\.\.fff\.7";<]wIU7wg\>ِ(wIU7C' wIU(|||ކnP# "I?W$mz {kzgf|x 0mvv a!SwI8988|vy?\  g4@mVG"%'7Ug4g4/.yU<ɮjRf4G\Ѹ}bHc7MbN3Rz\P@K~bUdTk8fk8gf3͚gfggg3fʗdg@If3hhh2efgIj_E3fyyy;:?Ryyy..1  ??Et   ~qk50H!!%   }l$] x89; '7=@AAF<-NNS ('*TY`  ;:?GHL ,,0  EGKľ   :C,,,//5LKK55589=@AE987555a]\鶺~}yPPPNLMzzz333}}"""<;9]YXzzznpt@?=iii nmkmih# !***NMK##!knmBEF220,*+,,,:86KPSBEJތ(  G'\I' +f3g4\.xwI$#kd(؉L[ơJcgwI( U (  _1\\.\\.b  WN9 ^wID#E* * ) ; ; < UDVSb=wI4 Gg* aaa^^^Vkc,oJh@J_u/???&7JH{zΡjr^9/IHH5A!AAA(((j\(((\.\g4f L8lA Gν-1eeG >XX%pT!kU,:::f5%AAAgwf3.[c4:5555b2 B6[Uj7>I  (*0 HHL;>>(%&~쭩_[Z,+)lki$" mmm  Ŀ  b^\ qnm,01  =;=ADI~}nruimpg4ON>]8' ΑmMNvϜO8l V]Y︃_c) BNX' G GN2/EQ ) B' G G'  'eg4g4_114.nnn*  GwIDwZx"g1螜a}gooonnn*  GbgbxIU o-wiщv-whk- J  -e-g}m3 Kavv999  RRR ZZZ#JxCCCC m G$Wd2_~F! 5~; GIjS,ԯQ( SUЉwnۇxd25&j* Q(  [[g2'e@4K~ǎy %wsU\Mm< JhWXg4wIQҴI9rDwIJ%M[RUM MLL@??h) ㉵I.L55) \.06;oT9.jOOO(1gOOOlll Gg4T~JNNN孹B:d`G G***Vmmma\ rrrdU:ƫ(fؚHҐ|20wЉ4i6fi6g=3H(.TȮxf'''Dd/BUʱsvv$激t)))Ba/CWG G I,:::3RkR,:::KWjbcvW:::;;$77<000 NMS   w  i}l  wl   ::?XRZl tR l luttt0/3     #(㸷 PPW ^- ttt   .-2 SSYvvv@AF0/2 ü )6 ! =;= =>C   »%4  ,.5  IIIVVV___?@E "BBB CDH½ dbb徾=>C?@DԷ [[]YYY)),)),֧$$$D______đhie[^a     jmlIHHba_>=; abb [ZX`de@?=ABD875+./cfe}HED##!uuw  %#$>?<   \]Z"!  400v}~ $!"   w{|   )(*WVU㖚sll8@B442PLKSV[`eiNvϜO8lN`N`ÕU S1ON>]8:llwkh-+\OI۩_%hތ(lҌV!Q9x{w|І}U=kN1Y}ٛ&e⤔zX\ 6 cV!۱0V0:UpNNy˵>'eG( ycyDZl9f~|ÏDR{C86! @rokRRDsvUX`=qB+f3f3457\.VgxNk?II333I\ wI`l:/oX4~zwL1+( 344J9:e_wLDwZxQ8`aa_3yb.樐"pb&co gXX"p00cChJwI R SHlG }y".yx#- kX   hIreX UprG۶.m_2xm666  *++@44***myy&$$$ 70}W0 7 #3r ^- U   ]=h=Ig G" ^{E J^^'P9a]=wI0wkޡ= Gm7Il$M G:: Tm f';6 YU.e+/b_C_[[* *5| Gͦ///xSIǎyK~[ 9wSl!!!!!!TTT۞}^xwWR-\嗇‹割7rx+IwLZ 5>ȃe%y'v%x^Viyp‹ٜa Ej6@`I,FhIl,[tmwV6333JJJFFF+ 5"jnn{}OF~I(Г{zq|I joSTHwI 333 LL5wI( 0mq0bA  K++]UUpppeee s@ Gg4fg5f(,z02Ռ>+t|W3ep&xR,ej\jsupipm!*'똆+tǢ}Ŀ!jEEE 4Jhɦ˽i:]:xqqqq88ǷJJJ*Ll"-d5da]nnnf3tf7^ZVsssf3#KARc񶶶t GG Gzzzq> fjjjjjjq> f *Weeeeeeg4fh5fSPPPxEef9-9^'%'f[~[(({oWo&&&;:?UZ11ggg  LLRZX(((,+0((( &&) ==B   9:?ll{'^ol Ho  A@Flx/ lx:ZlLW* C6a     u emlxoRH * -\000 "&, PQVl {7>s {u.V '''   77:FFK f]f}vRRXRU\!"# 乺 QPVcccDDDCDIļ   $%*¼UT[9C   ?@Eý!"#'0><=C!"$ 000UUU?@E½556wtt =>C%)1 DGI ի fdbDDD''+''+!!! !$%+ Q127GIMZYa999015cdh ((()))...555,-);:6(%& UYZDBENMKonp \\\521>:;bbbqprddd edb\[^bbb856 QQS浹#!" TWX{~njiaef   _bc ...<76JDD  hefBFG<<a{xӽ#'+ՂWoWo}O!Ҁ-58;999ѽKDDDeWWWI[d:J#UB b"P'wN]\a(VVIg9b$Q(wNZ`ς,wN]\#eG C0C0|D"x{G#z|1(BfB"w|G"x|G#zlj1u--//wv7Q-...Iw_* <] =] =gcccc-./...l@ 2DVRnȥW111\.YY||!!!XXXDD]!!pMMhj((? w.=!!3::: C ((( O %-Zt$.8}٬ͧvT`lq *3y{\/[qfbbbb`^]cccbbb6G )ASU )P}.$I=*wSb":n ! ] +! G, < !#!| @iRs#4\J!X<\wV3kN4_RI=*wc DFN;G$wNTru{΁*eU']Gkwc DFN;LKg  d! m(/ !N HH!$$-BwxV^[VJ7"* NZN {nT^[f~t9'/ # * x\ 5 W)D2c-Mŀ/|Kl}y᭑| BN.gZC[is&+awM/j-( BW;cW3]4n>SS8'nn;;``;;|GGgJGG"UUgGG2|2gG]]]:@EX wI" I\ ]k|m8w~3zKk|m8w~3VwI-kd\1 gt}@///~݉(uY%yEjB wI'I@剷Vgw͉8ą͉8wI؂-jwI(1 MKV?Jb|Jb|g4\\\%>/6U_qkLb}vɈxJ}vɈkxNz3msM~> IJ Jc PPPI THH| 6q  ,m,Y~Y} ]]]]]] QQ '''JJJ::: TTTc5000\bf`3>>>\<<<...222UdG (jS /2ݵLXs~P@n:LDR7Tskg4;';߾ܓ eBSSU+Uuu %$mhw%&l_ &//NAu\b:ov B ;F *OxuO$' 9sF^^Bmmm,ZZGߗxZTz (vTNq(1(UdG EEEǢ}>>>!iEGGGL`tLk̩~777hMMMJ]oNnQiYag4 e;Ћpppf3nnn%*qg=ˆvvvf3zz<9< ;9;hhh$r 6U#$%D%1yЇȮv]chhhhhh999a1EX̳sYbaa<<^j^``````777_|4I] Uu{Z䒽}ݤQov<Vccc3RkRjjj9DP_X```3Mg$>$N_*z+ nnn6ALb GGbQDD߄`=:::eKKKn%`>>!j888CCCPeyHfǢ===lHkH-JJQaQ333EEEPewHfe;Ѝnnnf3sss"(.ne;Ћpppf3$4$_MDDv#sss"'-ncmmmmmmfet\t BB vZOZmmmmmmf /025U5̭;r [[[[DXD569ZZqqR  326  NNN###)),&&*qqq< > t Kl 8 1 ; K+++##& ?BI  FFJ aaRNZ33Nxy###444AAC  KNZ    LLPWWW"""???KLQľ      UTZ DDDJJJ:D   )  68>  Ŀ.6E     "' "' ,.3%%( hhh333"#'"#' %%%  QQQPPP777yyy:;@*0=ü# $ lej999:;@CGM    UUU99?&'))),>@C¿XXX56;Z[_뼻 MNPXY]yyy!!!444444;cccnnn|{~132&&&Ө%%#lnk243𮮮ÿ)&'&&$VYXimn20, ~~~+++˷bbb555<<<a`e "&':97 FDEKNMPST  XWZ 螝|}A@>510ppp  ghhD@?w|653?><dddkllAAA634  dch  ?AD fih uvv뚞XXX  ќZ`b  DGH/,+jil521 MMM*'&bbb  ...oprgggAAAhge"""   TLJ*()  볳"""PPP/.,B?@777  C?>MJI!"  xy{\\\\\\  ν )&' B?>53/(((SRP,(* 632  :8620/   %%%&   B?> ijl,,,%%%xtu    wvt000,,,30/hgdhin    ]^`777NLI~(*)VYZOMJffb   :;< .*, .+*   ###%"# 2##"<=;666GGGڳVVVEEE!#" ]bfdgl *-2((* INR_dgVRS49<*٭%@k85"XXb/E5X0+٭%@k85"8\!׺y=gdK:λy5 D8\!׺y=gdK¶P#+NyA ՝mRAs_qkwQ1ǯ{'Vl|H՝mRAs_qkNM{<=xB7ӣd&Q% "9WqWSV5¶P#+NyA Ib5_{77- YFMb$ r1y}U{8߇c φax"YFMb$ r1y}U]'HBŐr93(Osܪf$r Z`5}Ib5_{77- Kz3{OGaka MZU]VDō3 Eu}{ MZU!"Sn&t~ ,\w' 8Kz3{OGaka?c_xxEb:#0Bb:"︃_c9ܳ8?c_xxEŦ;\nVb ዄm+ݷዄmic5J' N8Ŧ;\nVbE̪c{Ҳt$pೣ7m]s0/ ̔ೣϼ4K%D"˯qUi$ ̪c{Ҳt$poϤrk. :W% gl\^&=xujix|F*aci-$QzU%gl\^&=xujix|>i:e X!i=< ƁN$>E~74"oϤrk. :W% 1\1\F|FSGOvOF|FS`` `[[ G1\1\g4 Z-cba ___is|VdVzk???QUXk^R( '0+05Yr`w$.8%,5[~s mbii bbwSbi wMA_* wIZ IޔTݭp-g |I wILݭp-gxnQ/ɯrrrdUq~wI ℭwSUq~wI $o߉tvp\CECUB B (#jaw\弽 lf ;VK ?bA=t=?bA=t=\> B]oLX !=~ @`w[i]oLX !=~ GG%y؁g"RRl"RR GGuCafwb< | wa9 mw_:"|ƾx:| ϹM#AƓ'M'"d 1PMzbu|dO.+]x.+rU"1H7_-6UdGȨ9&YȈCȨ59~&L[#l$ o$]縣Zƙj' n$o$$S S pj0醶 z 5^'^' Tx}`7SS氘NwSb:JO)JO)iv GXsg Xsg ""&.#.rxt`G#+3j=}^dntrq<ÀCCC&&&"" [1***ggg WWWWWWxxxFFFqkwqtkll))pOOkkk ww 00 򨨨"ZZ~**s lg@@XXXXXXbbcce evv߷'JJRww xx111xx33Ϝbbb򱱱KKKxxZrr\\\kkkKKK RU,,vpjUmG[oMz~}|||!! ߡeI^sI^s  쇇yyy|wq yyyUngwI]pK[mĀ;UL% l ɗ%FnaomwSI=* (  N{gKeM_CWFQ]NM_ar7*[ !M_C|%'xxI(wLuj\  V @ ;D#=Ab  N h t&N bv< b7 1wNTru{I+]Չ2't])I&Ad:Tex#4\J!X<\wK;m]EkI&Ad:Te Z@#q -  )Dc :qC>v+q-rB8 N{-  ?Q  ^  lB X;. # mA>,!/ +"G/$iL& O3G~'UY ;c-Y Hc5}xSNz4/G:5ìM7>j-N.ZCqs3wK-/ܗXX(' +Q"UUg GG,g;;|GGgyyg===fffEEE!!!???ppp ۮq (SruCHA1uCHA1",zIy J$^# xVϿk,;J:텂zdq|J$|XI3K$|XI39/"  f{N! fIF|UTf|߇{o_K~s~ Bl'l'SXAxh6^^ۀ{`$]ba-w***uqinਠa* ^z[s?֖˂d|2pٜ2sA^$y5ݪC)ۆT6JJJ@BGn߹$L_06 6 ̬="DL(Emب'X뽽C C빐 D빑 D2 Q}I!q4,/ ޕI9./ ޕI9 *U4e E& d DCCCmoð;0ñ;/%Uw=wz(N$1m9xQP'/m9xQP'ؙg5N>biM_$%?4w SSǐ+n1jR1j@H\\ g ee5XXEEExxxCCC Ϥ.fYYY&&&%&&300ϲ::!!{{ )MM::CWjůGug888rCWj~pug___}|{ ppp333UUU___}}}S1  U3ooomuuarF]qz}}}}}}ppppppNssCCCpppxxxccc\\\(UdG }}} GGѮQb|Ii{VfR") >8\7wG 'ήIE$ *ػ___9@& 1cg7؛Q)4~^n>c`܅2 :(tmF%#$04dbҥw]xxxԚ&!4cK-DX" ΫJLXe:Vs_p]:%#; 5p>:(9 ;">=M:nnG GG [[FFFXXXhX|q[UdG(333pDĿwww+3;lvJľpppzzz&.5n GG^7㡡}}}}}}YYYr `7ݛ¼vvvvvvRRR q(Ah8o7|i*ȆiK dMMM<<1g%2?φfFCCC::!f(7F뤷t'P8o $i յq---tW;;7Wp?Xqڻk(((rBgB=K=³<<:TmB\w0 )D'2 hPPP~kXXXBQaVznLLLxd(F(ܽFgHd#-#]]]@N\X} +/oCwww,5=kuIſsss'3'ajjKK~~~)18kdk;6KƷ^7㡡½[[[q `8ߛýؿH>Hz-yC?CzzzzzzWWWr ''&G2+nȇiK dOOO>>1j"/<͆fGd|b|DD$xoxJJJ;;i$1?GG GG GGյq.--uW!!!;;5Wr>Vpַn***sUyU%yyy7yXfX<<8Wq?XsGGGhPPP~kVVVDTcTwjNNN|h1Q1б=pxN4C4˻XXXCRaUy ,oCwww}}}-6>jrEþuuu!7!W^^aaj'-5=j^7㡡½]]]q `8⟟686o{EE ! ![[[p ȇiK dRRRRRR>>-k ,8ȉjKfePe&""8QJQPPP==0k -:յq.--uW###993Ytzlomz? t'''### 327w= i3 fG { i3Qlqv  :4xzqv  :=QQQ___PPP //2=BR     0g  w u t s r t owggg 248}l      ttt    JJP tP vV1 5P vT ]```?@Bǽ 9=@G  hmr𰰪77;}FF]}.RRR   <=B  lryZZ`&&&###B@F    "# UTY SSS^^^BBF½     ""#NNQ888sss###GGGddd...>?E !$ )+- # þXW]CCC󎎎#$)#$)(((  #325MMMMMM$&*$&* ,,.     --0001&(,&,ý  $,  !!*)):=C #, a_`#%)#%)  )/: JHH-24;¼ )/8 ;>D !/      <=Bü  ;=D #*     <=C   <<9:?,19 %$$ ((( 9;@(),  KJK "Q؞ 88=NNS EEE+++.03#$&'(+MNR BAD!!FEIE888!!"NNNHHL$$$DDD]]]ơdddEEE쩩ZZZ |||ccc OOOHGEJJJnoq棧*,+~~uusNOT)&%=<:\\\`caWVTW]_0./ JIG^^^歪446 }}{orqoooLOPA>=TWTOPP**,\_` 111qtwPML312xyy{zz eeekkm]^b|LHG YYY twvsss^_]UUU gcfHGE! |OOM[[[@BCztv(*0?=9zzz???WZY./+CFGcce ghj EHGbefsuxPPP  TTTQNK.,+ghj񑑓jjh  [[[ khi ...󡡟JML,-) Ɩ [[[NQR  222HHFfff&&&[^]YYZ\\_ORP     +++twv (''Lj  ኍaac   ><;ux{ 666#" jjlvsr+./STV    mmm//-   ?<;#" .*, SSS568iiittt¾513#"% _^\[[[444Ɨ{zy UOO Yb[ږUUUUUU766   QNMGCD  <@A  $$$ZZZRRR   ;98)))***HBBA?;  >>>VWY " 314###%%# yz|IHH %%%HFD&$   <:; 666       YYY@AC ;?Brnm  -,* ..0   ORWHHH   4FH11/   JJJPQSnmk9:= uuunqp   OLK222qrt OKL    ู($# kjgvz|     )**:<:ę***###UUUVYZ     a^]   224_`b @?=츷VYZ@@$##DB?WXZ+.+HIK0/-555 ! " ### @=>    (*(,03[YU ??? ##"\ae~OPT%%%$#"NSW]adMQTvro))+#$" DGL..,|AEH @IC*=ʊWH`hF Xb:X' Xb'fOtx(ʊWH`hF εfM.P2Va|ji:X' 赸ge!{kjεfM.P2Va|ji 1K}Kﷱod/C<]kXL@ʹ:X'ۚT.qrﷱod/C<[h\Xf,R2ﷱod/C<LL4?*qx@ 1K}K(B!fI 4,:"0C&1.Çy$=B ݃qzy 憎x:ߎ?@oq?:Çy$=B ݃qzy勞Ým tyԐ6Çy$=B ݃qzyMmvϨ@!(B!fI 4,:"0C&1.!\x\ӜLQ.*?=ٻ,@Y7)@[;-jxg*?=ٻ0HgF  D*?=ٻ!\x\ӜLQ.$9$9]>f߆orՁ7 <;aB,)Zd Ձ7 <;aB,)Zd Ձ7 <;aB,)Zdޢ >`$9$9]>f߆or|7 ;esS /N1Ӓr ()* ª/l7ϓ/N1Ӓr /N1Ӓr ՛3ff1|7 ;esS 0#|nnZWW7 ;Ii=ܑò` HPW:Ѳ`:X'&xPMR-q)m;Ii=ܑò` HPW:Ѳ`:X' ;Ii=ܑò` HPW:Ѳ`:X' ƨX(j[w$0#|nnZWW7  8lC{C|G`/v/vARC{C| G` G`C{C| G` 8lg4`0+{vs!+43@N)5A(0õttt@?< ɘd"+5"+5I^s#*޺>>>'2> |zYGGxtof\""qqqytp d6\\\feeUogxiii\\\G[nI[kr dllmpp?..]uuuuu 111SbRue.J:_* ˺:GG@kkx334WWWV3Y2ۅk;:_* '?bblkk6A;޿~c(2y:iȗxJ &^LG5jm{ xJ &^LG5jm{UeKG30294 (GK je3Szk̀_Vgi4rB8Q( "Ns(otxbrB8Q( "Ns(otxI- 5**5n444 8O{Sw:vi,V2" "4b "4[)+" 2.\Bc Mڣ BO. +,!/ "G+,!/ "G1/ $l0Yɒ Pel;5{Gr7bNF3 ⽄-s[%-5{Gr7bNF3 ⽄-s[ Gg >YY Gg";;%&U|U,JJ";;%&U|UGgce Qf# oYJ0T ކk7+8E8WXsn1X/ ߇j! 9T?Y["ܟX Dur?߆k 3(5C9Y] θu_ +jr ,W[ θu_1X/ Mbv"F2UG᫢P[Y%D0#ਠafQ+^z k࿙i4L^_)5&@rt&5& 64* UG  bﺻ@JL$BA6=GF߹$L(2¶tttpppppp♙-1N1q|||UUUDDDXXXYYY5 444uz... pJJ@@@+** <%%..:  tEE~~RRR(((5AAV !!33x }}``` eeelllnPPPCCCCCC @@@PPP@@@OO|3O<4 qllX*p33qAeeeͻ8FFgiihhAAA''' _JJsqKKELL/// }xxvvv...{{{PPP33b )*+ljh```XX Y;=>ATe^xrROf|!!!A=:/aCYU YmbiHᤊ%"EwP[HdzߡS1U_jpemUtAa( ݰ-$>aCYU 彍0'CiFVHﭖZnemUtAa( 0Vn 0#! uUAmx~~^8: Kxe $0`s IX~ o`ww; @Uo'  P:A[aUo'  P(}Y@9fiKҏMfhQ$,?bAɋ5s=ᩓ&bj,?bAɋ5s=ᩓ&bj,@jK˂-p:x ;uXjP7nnsscc?\\]]TT- TT-0}0ˡJ !1Q8TtB@ްkt*#C~6  @V}cXNePB@ްkt*#C~6  9鿎t{2QB1( 6iQ6i"RgR Gg Gg 7l$"RgR Gg Gg B~^B~ Gg """000:::111777SSSWWW癐b Qf# RRRRRR۟g5>TiE\r{KDqBSW Ǒf,vZAܛQRPO?Ϳa=K) ܛQRPO?Ϳa=K) dZBuf.氘Nk rwf%%%\q+ ,:IQm#X` Uc@ٙ#OY_C X^ Wa8؟=mPh]ʐq BG"ABu~^xԓ7$̱eO6R7BI[pÁ,WlO6R7BI[pÁ, ԣ+%JtKTDٻhBI|\k@`d V`y"ǎam>/@K&Ͻ'LM9?A0?O0?Oք[1:::!!!ƓOMPMځ.^oQÎ UPVP盒bzi7x7ꯧlx6}# b^4ݘb^4ꫝlpciQ 眖ifkcsE5K7}CM"kbmN8t/#1H#Կ-8!*|g4ƽCCCRRR Ȩ9# &+ȩC~" ԣp 7@uɆ8¿)8@!@3ό)8@!FGh7zy dmdũ8Z;Ȫ7(ǩ6Y:G+CCC___SSS וh=$ ؖ g:$ו 2#縣ZrkOLr~d  뫮naa: 뫮naX "% ё#m<$ؗi?& ؖ i<$ȴ 6MFFFnnn٥"YUأ#ZRإͫZkTѝff^#J \t1Jgo xi۲xbU*Jgo xi۲xbU*Pk;ڏűgE 籴v1|V; ٤#[U٤$[S%?) 777r``-//謼 TU"07v7vx&~w~-b-b&~w~-b-bFF [Y[Yiωi ....<<333...555@@5tt+:::氘NjSb:_* ___555>>><<1➞iωi Gg,,, ..5ww:!!!,,,^^)##R++@7  !! (1󮮮CCCAAA::z/00rzt///RRR/// Rhկrrr]4kkkPPPώF19FTheKKK###yyyCCC??&JZiTr Ӭ ***eee(((???UUUUUUOOObbb FFF>>>BBBOOO___!!!$$$VVV%%%jjj>>>ttt...~~~U(b:ثG U(b:ثG ,,,NNN777 GxJ^TJlQo7| mmmQ.kXSv:d6b:ثG pDd/yl'g4ue+ȶa|DWp($i&z9Mi{2 ՌGFE:౜`ZZmmm 먉: ֒dy$nw)Ӄ?HSy5ʎ7  ?uZQ|8|'<@??>@DD;݄̘M'빭(xZZZ_,tr7 *qmպ^s 1ppSp0}h$/̳[000[]7h>Xs%2?ѻ''' )2<>>pppbwbwb\\\\\\ֈ/;H=Xt&/ k/G} ۼpo g|`Yu$=#  (QE!h ȻĽJJJvvvdOOOOOO቉~ +5?>Yr#0>ϻûHHHvvvd||:PZZ ZZXXXrX"]\]~s~ FFFFFF匌q *5>=Wp&4C%15>I|W!\lj5 ҵ...___nhhtW"',6K_:RjԹ+++\\\lllrRvv&G;x==  @F@}*)* &+6H[Yt!.:ɽļJJJwwwf6PKKm11$0$sksf^fMMMMMM቉~ ,6?>Xr"0>jjj>>>9ƀҶ...___ohhuW!!!"(-7L`8PgѴ,,,^^^pkkvVuu!CEmSSgggxgTUTz!',8K_8RjtttݾƼBBBrrrc~k~kkkkkkkȍ/>L@[v#ƽAAApppc~j~jԼ||ϻ ,P..778B8z848hhhhhhɍ1=J>[v%fff&&&Ʈ###TTTtttkG888|)18:Qi.ATǮ"""UUUrrrlF:NUUk99 . ojol`l777}(07:Ri.AU---Ǫö666jjjkUkR $4EV=Wqƨ÷777jjjkUkRqq%E?vPPooooNSN{ $6FV;Vqjjj$$$fUUUUUU:fǬ0R9922 3>3{>8>TTTTTT;!!!QQQ'&)555%%%%%%}}?Kaah??+igiufu%%%hhh 87; ssô)K3}NNxxxxIPI~   ((+4PGG// /;/}@:@ hhh    aEaieeA;A     .-2ֲ   111---   ppp        oooyyy  $&)  !!!444   ̽yyy  ttCCC|||555%$'ǀ8tyt  Y%  r R-  /` _( r" X0 2` X0 2` R-  /`444  -,/  | |8/ )jB? J _$v| e/9 ^e/9 ^)jB? J  %S zi -Y  tz v   %S   2R zv ;;;888  ] VN3 < RpX '     RpJwMG o #t gbJwMG<tZ: gbmmm;;;jjj   56:V };; +`   g-  94 A-Z 94 A EC 4Z "  ##&++.M}v@   3 o    3  TTTTTT{{{/// %%'%*/  鵵GGKEARi 3  DO  d d ed d ei 3  DOG  M EG  M EM  J-WwwwwwwnnnHHH--0 25< Ż+,+"'/--/!!$=^V . @ | s!D     JIH79Aõ)1?     !! &,7      a``  #     RRR***  A@@333)+07:A   -,----RYYY 89=  III(((  127<=A $$&$$&  &%'...999LMP?AC###,,,558 %%'BBB /01yyy;;;HHH&&&___eeessshhhCCCyyyWWWjjjggg틋oooRRRUUUHHHTTTSSS\\\\\\롡 |||NHH =<:...VVV111XZY  RSPxxx񨨨 ppp('󥢥'*)0 ,mjm TUY**( =<:슊jjjuyz z}z`]\bef220 756CDF&&&>A@@>>^^^YYYurq   256+)*#!"yx{___pppPPN!!!!!#???rrr  0/-FEC 䙕gkl:::""" 23 яWWW   fec963َNNN220 RTX)&'ݝkkk /-)ɷIJLuuuſ $#Aׇ  hefedb;<>!%&&#"IJLSSS111 晙jjjlopdghuwz  !$lhg???¼[\Zhhh yyy lop [[[  JJL-35 FFFeee¾ ###MMM%$&)(*(((~^]_  QQQZ]^뱫LRT*&!""" Z]\tttW[Zilk???,/0%"!  $$$lljUUU|VYXhjmGFI # "NQT$#!  CCC /,+b_^8;<𵷷[]`NMP       XXXVVV3/1   QPN  QQQ()+RRRJJJ?@=      PPP)*,ooo (%$B@< ?=>$$$deguuu  JHD0/-$$$333lll\\\XXXdca(%$  \YXHED JJHLMO8<=ijl###BBB[[[PPPPPPFDE$$$'*) >:9GDC 000STV******  @<=*&(53/ )))  ""  %%%###965-*) ~ <=: 474    ^__  :99 -,(   oqp@AC ('%#"% KGF&)()))! #(&'=<:   8=@ٕ .,/       ,)(#!$ &&&~~z XY[     222\]_(''%ɕ rqt!#" <<&R4PTL w`\Z t@}&"d "D@l%#%$d$h8 FU]p%`#=zLSlhOy"|1@g7tҶ?[L<5y80S %wkZɉe#""&w;YTa*ȖS'V6 >fa̦>!$&PICL!$-# 9 [ţQ-Me I騛WM |ǽfF;KRQj<ɄsA#⎺>}4nS||_l>>$ 6JLverTdl*))a5-.yd)|-?fH$ )1i,dh ?? ߀2Sj\TYY)?rl& -= +>PZ_߰k'Y\7PC =bRx?_dwUn! `yͱҪ,.'Tyw{6 MBo4O=U.w;DD618z4S=&0=)d!2Dm6AÒ?M>-IyZNa$_<9iAG>yR\oI\j~dt2LqtiFdvʦylS|51}\׉rN÷n[uSΓz)CF Pfk 3~Р)v9OS} ڵzzb׉l8r+;yxኂk]G<̲6=; M$0;vo`;;awLb Yx?}Nq6Lʶ6=_9%S[pXќ:ujl"fˣ.]+bbt&&d,M¶A8r%m8ZPYP+a_~`}wppײ P۴)ri! [\@ЩIcO۷/dR12,yc>Jyk}%RZɓ's f&v:z4д4&Ɣ))f#p9Z ­_ۺ{P|ƲϡS &vwiFO2%77Ԭ->7˵~:|Go.YG82U:C6s2 <~cS`D[1P7 oO8s<?13,GX_/@E[6~GK[oriӻrCi|q˳xT|3;_ f-Ҝ^"~FM8loT33BW"^nSTTģ3!R a2t!* {ce†'Fwh-/d-T7} ^+f̧ F{iϡ|*)_*fUZN-y. xޠRVBV)>B [cfe_ة&. rN=i~1}m/a/y l d#G'N6hnJP(l/њ%є 8_OdץwB!I<^vD7q6);]5Z%W*.얆Ro:펾danկ%ֱK掠˂3?PWeʄܚ܀GM(]hk_Mϥ=婊vBXB[>MK A۬~JT* 1eeH(ɑ4Lbc[/2{{:aЯFM _Gf; Qpy'IkJvc{4- Cam9+ ~\+6 +Lj,^a Iy*]ɠ@aX84I1&Fd߰)jT#6u[ܭ8zMƇJ?(=aRZ}J}`"%]~Dշ&N6Z/٤/1B:B0_ 5諊2֔IlV_ZZ>7T[~Gw.e 7*lr%m<}o5Դb4ť8LSkLSZZw6J5Ǥ:1(j N#bnk㥩VCy*)i(Ag)5T3 #>ԙQBTIos˨Ev$ Ap(8^粒N(ʹԦbSnˈ[F͘zs6ԋe59'/VUU{ H$C߳gz֍]PȟW-G_ӻ;69tڕyRgh27Fo=1۽AnmE}MT;o>pzNK;~sB$Slr1 /%|fϤ <)(C0L`Xow/2xqmN|S9r/_U_d"k?G&`MNܥYSf'l:vV7TLRB7vٳg@7z >b.5dthBgN._8t"kG|7$hq%SFۏ_})"sMbFL&ct: b x FCGh h2Z bRc'R(^Zr||=g@p:{ͷ|ߠ{ v̭m-MD1Y])_rbeq-[7:;q%t p(L&KJJ7~0X-)))CWt\}Z5Jtme $cX:pVOOOOs=o<ŶL&$3^vM0ofj@苎vڭiny؋{!&C2^pgİ0DeU6uӎ^-TW!5KMG[_D8!Hn&Yf g%LMM "T t){ɿЏCA6%E"EQ3tT=:Nyn}Oesk55**Kt̔iӦo%%%?PVθp@lZcPrJh6.D9/eI>:P)ׇuI0`R2S ÅOfJ9sJ?6P$4uф8Crn8жqI^ݐftgJ=ms^p"έcfbUa9hOS{.o6ṋ[c,9tE&Ԁ +`+[~ً3USTٹ0\8ΠD6͌'''Vя N%7t 35:^p<{GzT۷.N4\:==)*44400JmA^RGyfb/{iP+\⹭fDonhCٽLԢ)oSL[l mGWWWL*NUwg#A)kޫ&R5+_42T &P{A{iz0>HBL{Kl<$ = a)6~)tj$P 5DMZ=ɇб'}uaFVq~SR􊢋∶\]c~{"l6Un} Hd& اp<'-+Lg~LKKk.F߯ݎ|Mqג(9 Q[pղkV.%=㜋Ġ0%''7?|mv'SLRGItgrn FRHt#L_,H@aԡuhɨӕf17 ĉ$V׼ĸSݾēO J,Y12{B?tgwDMZ"yrXڤo4ޗ>re.lgj?Y"f\9`̿q|} g {KŦƸ3MH V[&w@mBЖ(Ǻh2ocyo301a4<ƖW~;}ߚZfYH nY~A Qկ,b>d113/xdGO1?֝rE_WR"JWgN*(Oa5 &aH_c_;._v#q~~>AFuE^@$dx.I85lY)gk`sn`Nc)ΚK$@:W9`Hb#g?Zz֯ i}˱V/HS~BFlbts{n|45 ?/ogjJ8}3#C ߿STJg}eP:F"?ܤE#""t:]iMgzNnusiOȳ{EcJ2`ʁh$0ukS+Kh$c'߁F5Kk /V3Ĉ%ϻZH$L Ѷz\pz0jfB:`ZpqN~t[2HqTk9s00/dskPYXspEuqYC/n7q8{г҆]QSMϻLƾnVy7Z~ Ɋ^Y`{z' 53 #-0 {r<3BdC\s6,L37 Ф+*.,jE XNH+J[5G0a$dI}MϮzգk?)?`!TȵT掃9FI|ŲBkd~XAZE./L&-Qk4$Я=|+++= L*Z8h!ϺF$z*wP3nIu=wL$`eZzg/;zzbR&XD1_?{/3ۣ9W4|Li*BG[ޝzO*I{ W+/W(@Y}a|uo Z~5~u[|5t܍'=V L~n!Re8T, )Ն:Mh4٢wy#'lbIWHbԝ1ޘÝ` J2j(i'CË{3V_DA>4 &PSfr&dR#ZT00R*PF BQח zwdu3(I%dzF2k=^GbICY9iIj ;l 0HO?x"=@ZHqnRvq 4  E@BPRPI !On>?9coF]vnLvSQQBE`*^ZT_#(*n@s;.**~f3k|D&AHЄ:ߋ?K]?v~Arn-YK8gv?S+=T^9dݏ'8aٮS}l/b;3cz)}OOhXu-3ja>TKI wc4rfEJL"$Nib鳮%%%L&SV>4@VDIRB޾'id 3NauZL8#e'CCCj5&*2^%-v^;Kd@\u|S JbkMZQSik\V9H*IT@@d+ dF%oOXT0W@LQS2< ԧxnUR!NL Tڻp1czQ.K:66$ɖ&2"G4(nhPaV $mmAuQm2QKg4<6GUr?'ymƭqȼ%7 ]{\~w%i4ށc ۆ˒X0kcC7$I;^XeQi'X=ޝ8{fѵUGTfq8ͭZBlX,Wx67{Y42O^ҙ9_P…36 y#=k K;ZϽK»\um5ss>:ҏ7&Y0 MBPG&zT*T j ڒ$$˿}*$(A;ϣ,d@U2 Vc2E歬 ;"5:o@hۯ5KNzvS &6wѪ0 MoyͶ7X}GCklY|3rJt! 4=dA5'пJgk\LQQ&-LLg/t?/DiUS{i \B ` JQ2 "Ŕ@F DH@c&m42c&+*~TpAAAvn0E &FS 3fBc4t`c瀐*I'1b29q6SQLbIPPJɂIK}\ӃIk rCX[0,r^r \q>hl0Q")31j &OVSis,M?npZ߷l&SjEg%vh "}eHOqX=]Ffzg;h`~k-($=F{I4$0pd'ͤZX\|ꢿߵ?Q~Ĭ0Mc)&&fڴiNy#?c֭jsеRsV/gp!3 BrHS||)S L~4jOHo+0^%btd2*uI64}!nb:?}(K Z AtCϢC M )fBJJJSoK.tq?#'dFR=)#AjZ&q7 >7I@Z|b_98$1ݢ@hл5嶪3}'3|IEEEF}+p8lΒ)mynȶkp߬]S|EL/vm1 R{$YSc8Px~~N# ɏ_Xg iCe&QB>O >qf;Xp[_~e٢F*7nسiA>2&Rr!7W6Ipt}Lwc09?iks7C%$L˔xc+Wڤ$aʖ-87!SACoe2,l.ILC~:u6i\Z܏駟`f\geC04aB$BL3QužM͇Dϧƫ=wyw>`tby٘ 3SYG L6V@Ot&Jxx$.R|jԇ|?!2僄 3t42XIllh4yCXo\s/.̒u@ d>>Ht:ƚj3A:+ h@3 UZc<|}qg(]:Fe+0@Z@ 3!G%[sPfj>%fB >Ly'j~{OSծ*goI . ';x h&pdú5d4Ҡe+꠱B]d'Yh&v&84ՑSXƄE/YvtS!05;*8ǵ[N'ONLLlJ$FT դZ ˼vZ#]RGZ+wBC,nInNM$7. 2ÞN:s[,D&FRM͑եuY8xb/I8C@g|Ɖ!YדJPI=!_O$pՓ :ۗvK#mfSַ~ ,46w 8_1Cs8ÇjwܶmۛI@}o0cvn.÷7q pMH%I5CQ+yG^A5#$aO܍Z'yjlcgؽ[H?K n=H %n'x%a59*R A?FE8MPir0Uj&0 IEg|#!I{x7]UjіZ6G֙DzǵxZB0eZB4_\UDoFiA@Pbez՘۵#RcNښ&7493Z*ym|;n{È6h TA:8r^*j4ػDq7cڧq\PP/V$N&Ypm9Qi3b/YŔXnx]L

/Gמ*$' brжj9R $Ֆ-Fm-++#5fT*dpQfFusm醾B&ZbqąD"iFQQQ/  Md#jI3r0}ޞy rl(fiҺfC&tb@jתj}IB*jk1/ z\.@`:={ز[cU~=WV[#1-s!&_bXzRl?gU/zZ4y< $ <ƾŀ33<=y΍$KUUUo~GR`hAU"[9')APc;!fܕ}W^0XyOO@#?|/l_#QHr1.FÞvO۞ ?)k8$FFbIVsUpHɫo$Mxo/˟gt%1lr8%%㘓OBR\saDv\a~w@bxge/UOJ|}EC׽8 5$t|SUwĂJ!V|9K)5ݚl3P 4㣳O\vGBm-%[gق Oo|ȏ>Id-mI+|{9s2RN+&O5a#a؎ bpbp+IXuv1sv j}Yk*CY9Rwvsh񐔖u^$dh4#WF.SZ]Zׅ]jm$L8zG1t@,w+ ۪/&5WUIPI"] Ʀi^H R+lX4M"φdcƐ~8f\7<й݊c'vmi|kr;"}ӻᮼGGG7S$1H\.-Z0(VegJʬmq0b :)߷ݷ',=(漥}mHi(Tfh<yoϡfrE":=|Y$x,THrJu67F| 3|Uf:ѨW30IKr؊$+FIRd62iT&"˖g2 )?Gث%2$_9I%gwpkH깴''z=:#ݥTt:qd4zzSmST+ikLR\M ϻʕM$f?q#%Z1*מ](I@&PDa9}5?e@fИ:ƨ6MZP<}UtFЎk3HyJŨ=۬ S Hf[W&= Ԣ䋹nqbOe>E&H# JBR!$$%G7;Lh% n喖Re04ȕf] ȼU žpi>@bh{$g!BO#="L|RixW9Ͷ-IF*'r:1ur4"Kx"7II1>pmrzf}aWe.~M=wv~Z:{C̔OTɠ |-u#V".쐧pLCMqS"JBk=7ڑ]y{o9Bn٥nLt+>=c%;4$m/lw$L<) 5QyTp9ȋ+C= Hɥ;Axϥe{k?xyb7_{tF͑ui0nnMsFC"IRQ7%aJ?n$7ĦHa~f''΀? ̀gjp?z==a~V*TfYA#P4mZc70º7%TY$(QRN7R^?M$yHI_k3JaPM!AWfvAi֗;ߛYn8>-``_#ҟ`^,ܟ_Y?wpoyz&jwBۑ6h ;y\8tHhUe(,F&ya&3 )0pcee ۗe]ߏ.0K2fHb٥ւs˭/w]{P8$pGQ_t\ >6mڴ$FGʳES3HݮYfB_@0C^Yh`fVp_)wՍǼI) 1Gy*9j  ¨$M  RFR0x Ip@N ugmImy>""lԦh4(9 SSi6i6bpGŨD~5:wvh wxs0J}[yy9h&ՌRBbBN5:XWZqR`gPR%! Hd04*x%1p)s  Ib9iii-I>ى{nDP-BjU5#'LJIffdjŻuA=i*.71,r9?]?7QQ[p *UFlfsv$nɄ$%jxk3݄AԈjKǁN[TUvD[u٨B( k+FTwYeւ$ ?`VUT7h X{sdйs疊$$BҤw{ 8<%èhQJʴ2eI<*A%%%Hfm0_>?vGW֊Ҫ|}?.i>x3UZ5#$Sn!)} j9iA M~:U/Aoj0bҼlޱW`Խ;}# :{Fu% r'~Eyۧ Hr+}`:%/I2KgM4:1Np[P @|sꯓtng3Ԕr"LVG$Q(mřJ f߬4m w~4_d $p~e 1mѪ{@}>̰IǸbhܙ<3{y IҹGϥb0jUZmV9_SsƤaf/ "ň,GnoEHVS>۹Iזdu w?V =hPܡ IRh&fQZ%LƸ|dAeWBCM);56[zLZ)n> n.(Y0lznKt<piԗ\&MB[`wߗ5׶F9{'%/myHV\&XG)IpmsBB¿Iͪ><~<}>i4^9K9gz?̀9"UynI3X3wg7$(Sh6 BBBl ~7-?w^+ d &pLxUQ( "/Eh .=D"0ܪZ$z)8޽ Y{750[i&b)gG[cxNN VSSg7Mֻ 4țU?Tcǎͪ_<1c3,ؿvEbiDʈ|w'{CH/}Z8-ɼ_nEj%w(>0w㦿{_Qf&J)ڥgH0#=}oZM#SF6"%(}0XER;)HA^x-wswڱql$6%)m;vI ɷ9}sy >)HE)SXq2C`+;ɪ2KtZ$Mz'iu +mݾK/tBzĉ|iI2 $v#`4+{+P]lʼnt:+}b[%m\^puEWNnpo/ ~z.; ]1JKKInPOӷ9sS{K ߮/9VOTzދQņ-"M0:@ۆNycœ=f{fZs#J#W^}L3Є]F~WQ?TNNNDҖ+[uߴ1dne#[gO1mlƓrssz常&@Ҹq:[$ed^߿@8?djy-CG,q{52lP2+b~$76(2LI.rK.N m7pAl R2e0s쟒džY*}z'! Ϧ1, _ܬ,.WWV.7Usx$ ~=U3*a8ħn\¢˞,_zax0v8`Xnn0պ%$:8-[VcT@һJάw튯S1^@@DBd2i+ t?k 0Q x}bq!$5ޖJG~9s|=x+VX\̌=__r%b0A IR[[uYWWCx .LhnHJHH֭ ɭwm86/VO3҆ 6w2a!fM\*ѻsf(}@isn{,+kY߾l̫Z[bfXSg+jӦ?ϿTKJvڐ˩}@'/( .³>ٝWG$3i3kmIv=\erSѝz:PIȢdf:m4nIBHKvL%'CB44 n QXd"8ST-IE٧i p;7$mL%{e1$R !B!%[{:$m 0**J$W Lw,,8+bcc#&+7W象 3Yۤwމay;H#Z׬Ys.=C XHP({XwqR=/lƌǎcPWX}@N JfB^x^ `;fj.H /@G/[qg _E|Q{>g#=ك0+3>0pBf -xC7"f1 `Z@@o/$N,c u[o=XЖr UH駟&cuc5m 0Um^@ If #2k6iOu :|7UA0zqF ,]hXiƗ(aG Ĝe[Q@81`,]6(U|HpkjcмX֑Xi*om'>>_*Ih66V0Lf2 {YUO6kYU3;HAa @@@T ߎ;$#5~1$M cıR[|`"h({2QB"0qCㆮZ~%aEHȮtb@2RiGl&gHQ$~`+[$|S';.r?>?ЊZ"1m}ϧF}x3ЂHN^Qf\C4 bFSt dAeau >ƶ1[  ?X(\*\׌!"@,>631n{JcԳ[Jpz̯(%+g(Oe Wt p1/ +{ȫKJJ+S %Ʀ t:T`@o z^hZv0!/t6 ]ʘ3M*geuz1A1d,tI]Xq 22iR`l!6Cĸи!fBG5`> ,//6KY4|<<]ӒU ׺ bշMz8Rsy69dg$x "fTѕ-6 4ܜ',ހz80@= H/JҫzŊ;h.H%UkS.gzN|`A\4TYI @%ԖoSN ;wd<+#(+E@Aumȳ+>#C12&/">ky^~o'dRS'p}[}ݟ+AJMAX?٨p8{-oܲȼe8δ5ok;|qWyz^0fKv#n58M Xd5S\ZSLNn5-ZΟp7B^ NVٛ1% 2D_?-,RkѮ߽}+/W:?ػ|:U=~x͒^b[j963s3pa#`xC)!m.ؚcwx藇Yl6xGw)ÓG-=Lz"dfǔ! zp_R 2eQ2*qJ}TF!J1ubaD\ 4PFxd#PXd8k'|=.gk om` Pzr੻>+s Eft fg?J5ĞU\Ss+ʌ8dݧJP%9%KYʓB`!+Cne56r_5_|᤹ TX)f/b Mas<7|vY)O%_̿3o[)-JO!sg-lRǔ )S4u@4ڳXif3jA['b((JY!-Ս %1Wk:li<;[ r}ԊV"î<_ժ]^ jp."x&,:(fJF1u @ǂoXkh4:uYmx:#X9}S;KA C ݐRoDD$Jt$P J(|<+CU\L. V@udUon9 nG.v(ρ77[S3*-b+PS9D0V> vSwE4GKc^0pÒ7w75; z38_4jN6\Y[ȳRjr6CĞ>i&,sQLI,JeGnл5mC6_WX͍qӅSwG9a+S|{!㮾 8PRk !( O}d ?>s+fb`fd% ,XFRa7o<+9K(k ߿+JʆOGit_GLB;Qea23~Rė3 ;^)G1]׹%mX>r_\~Oކ-=tRw*SO^_? tn0ُ}ށ+ZMֺ*@id'O_e `V'%ϭ ֱlW$`hDh:;1Wy1K:IRC9(8f5qXo)-ns 76~˔l'Cc}4?K:qY3+Yqpmn[PldT;X s"---!!O{ =Jxn_NjRÙ*ԯ7V=lUUU?6Jkɭ#9Op<+2J2K`ٖd(Dm(//J+|(CC{7Ig:M FP*s8smœo/oӫ0W{?Vpm.1*unl]QW-X~ɐ#<;EQS(+hd ֒- VyVjʨVC-%Qr5G;Jhw!JJ"V}}jRV}3B>wnx-uj'$_Yߢ6Vҏ*d0mU΢Q)T$ʓ1:IϝO+մ\-8Wu?#.E`:3+P gjdT=f`my V QL Kխʜ鶸PœcbfS*2<+%nVd\SQ/q%9nk%*WA{{]l3;z_BBvL“^sBc^բӺ f)f|}`r¸#ĢC%OltH22TpSgՑF݋mkhfo& lf& XYiyG_)tCo9!ǚ=5yO'>_r|.g*_ )Bwǀ z$#;J>'I@U]&]$~\z4mZIRRDzڢִ&Hphd%K8ty{Ɍ iZ . +$Y+csrc^L}r% ,dN%_x;߹ȫ^xi uc玵,7,Yuӯɶf)c~30C^][D&Ft3ܤIz >P\$"TqIީG_}ekή n-lLFTd\rA4*WnaVZ[DDd |q^\+ݻڒ7U/R$Goxx JeMVKO340%\1}ŶOzqoq,N&)S^khNv<)An޻I޾ip}ߺsC1^Hz w|]r}H{aoyZVSQ)w->|lEۋĦ $qZK%&&Q ڊBbtoJFpoVYzB'O˧Æ:cXG5=.k yǵ?րe7SJYY ;R67.HI~}i_iMIE?7cюuokP {o䆔$P5,MV;/n.i&c!+ EQSd8..bɈbֈuy^6ۺmxӇ:_ž f6f9Yz=b 槣%>.m >mVֹuGA8K'z`Q(qsc (m`ΐd6tr+^_%f#?_)[#ZEScǎPD*((YS$&_"CYɥXpUTbP?uz]w_J?rlqx ؘ//8${%sپH\ g'/C'UO:\{fov-(=k,$U/L v]u{v"ǕZu$ſ@k.gC 4@E[QR`)('}6J {!e~r!+l+ yu]g3D? k|觛| bވy·vrkUY_״I Xxf㎥@Ĺro̓ş? wI&3EKhѴ\vU٨qs;aMk3GzFOhЭ~89uTXKn g%Y34cX 4|άWԡ+;;^?_7M T|UM`x8rù{z}_NwPJCRl_KIW'3 ) ba~-~D7~:L PV***D"QN8Ԗ6TIJ4B-Ѩ;wP@P-yZ JN +Ͱ$M~Ʋ;dV6VpCϥ=V'lY'M-ROnZPYff&J-U3EA.H;3Ks͔e冓 Ű= wV:ty8@HcA^e:{6I kg!zCU%ꞓdXY<+zY-}K 21Y_پgvN/ڛ_Tܔn{,=FI$IR`[7HD=}DuѷaѠ ȵ˾1>DJT!UҸj}γ]8 ȯ@M %[>qr7 SJD `+ HFPpy1Ui4m ]llX#qRZ{ Gz25^ N8UMԓ_yp.j?X'MK֝}^ί:3zeIx-x&."}T 6*{J!K5i$v+5s߄hFnjjjBBBaaFYP gCR"sg] FMyE(іӋeNܞ|@ڸ9_ {t\JR1NGS.1U)+QrTQ7<˳Zbvt'Hy4ocϤCJ+?[)>B3_=% 5i&ΈTF{_ +^%Z.h b5p%sr<䥥ᡘ6s$L-R YtGi@ //'KtHy'gU\[)}]{;y4yYk^q9O.tu;]XMhюF)JO +]~|frΈfJ!%[j^'uҟXzřD== n!AՒr1؉l-}*'+Eh.U[jK)YR1]>LI=]4śޅrmz||w(RЛ}a ? $u79C>(.uHI:+iX(/%{1$RauyU!1l_HCPں\Pq #[jnWНIϒ(mfIR^AVFT*Zl3ϓJ e5g%Ch)a+]eVhzɐ@U,aqȁ}<>^n[lvJ6=5u/mtH3枯2VHW nVyrڰMۛt!+uHI<RJy/H#+DUUe,d%v{^\K#\TГicYq>bAI@(DO*PzK"4G"&&gVK"@ TQ ix틗d*P}'RLbC VU  AK#&h1&Bքm' Mم:⇹; $*h mE>zi+ECF2!bw 7na Δ7LmMӁ}JxfpnRLMvu]< O葠T8"홰F [2j npg (4[{֞aunt}{:4xwGhZxЉnf,fjFƬ͘32LYԌ1;2ޖ HT:%޿7yKHHo5rßOG!>Ү赫@!%A 3 آ ۞= _Kc!+ ̡LR)c},Cd*=kb6F]Pl6D #c5qX(P /9f`i%ٿP7? }rH򩱟ק qpa^x|Ekםw~/v3w-vͩ=ﭰ*ic}?_9`ƥ>zϓht06aJRrNX$es$<5௨jP͇|T;1ɯM^5k靇luo-lb 7ƥhÊKۏYo=;$G磹鉽yx틋oVE[.Ty1ѬG,N=yhR.{%~ yc)ۼ6K$J|k͢m$$X)9V2)ȥUy`<) +MqW ij|-V %qy硾HDR +QT~NYXHY<3!ԕ9{hZv 2b؟qoc4jRKxazw{Vl}L坁o\{,V] &x6\ڽϟ0'|ym!б` vh.ַȡRuXkd;#7Y )OZ|?8NQjZPo-q\2]V%S^(0V){?7YBJjʕQ&6 SY.i PCP{O=l^XJl>8 #jgE`'`yG. mA~wЁ#zb@)ݏ0%BbkpRRvz;ڰ'ܠR@{|-uD*^ JM˓656ZJZ[N!1'f7&\}Fk1†؝ŲH-U=#0,m1bX;@j5JASHkeUF܆lV`hI-AxL&Y- <w߅73ν!?& =Zun2MAJ{.MZ' B!o˳B?sMP瘹5Tw g:@f奃S&PsdqBu*02 ^pλz̿ӓfRs` Y)xܼ?+TKrgǴ8>Xg6D-9݄O'*]U&%hֺJ*(@Dbbz gV29^qGܘtx>xO!?$p`yo!59 Z3^^XiRR>] > x>r;ƁC|zR=(!CtN5Vb,e]ox [YIb_bڕ<'ɟp`g]fu6~xSŕ=Jwh(Yz6mahzuz^* G+ܘ~#_m6@:=n-]Im|wS ݳZA)J[a ҐnK`(Ɖ(R43?'mBBѢEDXDB"$RR.WDDDFiR;I'Tpi掜bOڸ#T@u륭"lvg-y[6vY*98D`6/jM%qZIMJj)q vo mV2TVVK.rN-Qa%ǔ-IHًpC+pÆ iiiJl7dz59q戞bcTYn) ]u/7yLFˆMx%=k9GS sc:mƗ;{߫ @!r"⿑N"koGn ֎Xݏ?BJ  fً}EVH3.: vK^{СC=vYҀ'OWG􄁨)[L-לxzɅ/ *$HeTBeOJ1N)$Iߺ V5kkBsm!c'ڿX,aYrIR/>)wKOHYFBA Xag@h:opW/qɃMp%)$jǾCﯟKJ0`@b% 8 ;wg!'/ j̵9# x)UQ j]ۗv@=i/_NII9w\z_!ij妇;XƽwkP_S)=߳t}gn]} . 4HԞo,Oq Kб+h{7 '?~k ;kI~?Y l%c`Vd*gQK%B J 1V 9'̭߭Ι֍:a^x uHM۵kK/]848J16?PP*//ǁfʓ;Y>Y+1~;ݤ7^/p#w}`$7gߒ]ܹkjmPRRdTmB\%IG5ϥ#7Rł]C双dR9b SC=i#u^ýg$V~hyܹp!=}򼔔6l#DJeE )Eqhp#/-k]u$edd@JYuDtq2_-oza3zsϔKA.:::??Y>e}ܘXi>[xiюd%qqys7z+wp̍B1jϺu(:ͮ*^ʇt)i42'\DW]ma%'Nt;~8lgϞmXJ~NO '94HI_) q\)҉رɯs3˸ˆ#˻v}(=yrhMYY@TӡO 4{J5ͺ?k\+ r5n6xz>2GnxoNqJ@U9v}X]EJ7n|fݫz߾}`Pc ]?]2/gdd$$$x4hBD&0"D0Ӑ\0yUAH#i Jܵ Ǭ[nr#׀gVb9 AVcb >THZ&c$ E-H p3 bp/b1l6~VaSgYj$}SsW^y`>eYޯ}tn"_r ._{AuaZؠ+󥞱f!g s,"&Cg=Q:B܏AD]m&T)^DeA `_Q #l 6+]p!--=}t׮]=jٲe'Ov֥1K 8-y䱎@!238ϯW/?cƌ&S<wD**"-]Phdp/J A@#LXO>Giٹtb_~7pVY9 ʱ\OɺiO wN J #{([uT۶_XWXd /'߰-W={6t̙&I}iX6رsSY;KIPrw#؏Ӈ ]P}cI(]OQ<@n:lxk P3ڡ/.bG`rim^qrZ|aƌ2V9KC>'8ZId B5Y 7e7h\-սRou)yEvl"K7,0ﰆ]Ph&l|de/QY krRS\A ,lpG;<+ <hLwTkD78H'Ip#=\D"pZ I(\pMSdù_Iӂeg"G'QPu SC@'܎KЈL&3#%*BT)a)2\a/l"kK Yb_?'xַ=-qs'V?!I%|ysɗjBAY^%n/ rVkeeewAc"$5ӤGO; !q ka̭&p0I_׀pt`m"!lflϪs&o]k[/l_ HzG > W;*y;[vG .`BJ`n1fnGE]"pYrsKpV$ ٓ%P7ڃʮƊ̐50HQ/$3O.` *pL9؁UU75aH0pPZ%x²_cc+YQeBx4Kj/Kj\ cUH6BȳS,رcp]4?kS0U%|C@Kɥ1,!Gdv8$M sskJdta{Zl fq00Ih7'~.)}S(p%=4L<~xFADYs,Cq>݈?=|wY>q>Za OI$c(IIl-w~Ð`JD8R;bX! Pd j?KI0qD|N{[BJ2eޯ\If7kbOI|kE_2v LJZj|$) }tuO^m|{Lp/Jj}_4T)I,%V ^l7ŵ.'~};b2bbˇ}gOU^P+P]uH.0i7D4Id%\{=__T#aTTRV;%i-0Lqv1'~3 .ރ?=M\,{9҂KA&ry'joO7/s%2-t%hh P|)r{Y.g[yfxPoZzNJM葰w^($#H߯(ќy/P΢FwC Vv?xO!-*fbxh5-(APgƗ-uHFvh?Kyd#쵠I<c>{,7 Up?qv| o&29ѯ֏Zh{w}7)eRa2p/v;RxJ %4)gwl9>7ᦄPjsYck9;*ֽUUXtЗVVPkþ} ) H:>QR(.q į.}IwN7Ԃ"ć{{{i% $TiU7uTݑx Xov6#Du-) %fM JGҚʄ@!LIRL)oPc ৅ij&9+04l)0ѣAH"GfĮ\WTjR$”$W(Km%X6Ҹern }] #Uw39az׎8Jp90#$Z8H8iNx3rޜ5X>+ O2&*{8F$ p[hS^?>ɷ^n)⏤bE^uWLi`raoVW.Z7TUvZAPأOv{Kp'7OI P)cI߷~* vԒ*T.Tٗzܹ֭zڮFKmJRcI Io*3_Ji"/VE,m_BT xpn$) A'5RU %m4A$ ^@_˿y1nDYH(#Ü7_Vz8O MXYkt㏓:WaE a_+qՐ٘NuyUoʹ|GSf붲WiH| %I`@27Y,kwqW߯;n($k j&#cRo4Rs2%/O:tG-(B+"^ u{4;aQ͚9jwzn5 Yi֬yW>Ԓ'[mS~pӇ% Fj2ݜ\¹Mt q;nl L8|Shp$SRK(K(J %.#nO_(LA ʟq _͹c1}SR!AZ2p_y6yH%-JU7}5mzRR+׏]rJSyw(`J@8 ׅ쀹 -|SucQ'ٸo|jN'BSr&"M D"hOI>M[qxjLf(oܝHPLK ޠ%_exM~uY DoyĂ-~ܗs:{3?XF}܀Ng~sKUNk\eZno.K|jְ߆ puGGGc7ns Uύ l{)+1T&1g *DX?r/G|+K>7:=NqSfv{`@CZ=bQɼ*G%ecv.'Ɋ ^Jv`@<ʊ0m<%M5γ? =L֬n̒}1sܗ/DO:-\` PΆ]ekOp輭;PQ07eƜYqnEZ?V{zz $ԧ GšccޯUƢ*!)RT#6%IeJcIxL}12f;] "%_ڼ2JN[vDD$L% J!Juhۛ1%$ 6; pkGflđ2d6\~E- VN,4XֻHXДiTS DEF8KIƯF4W4~'.a_()|( ;orP 2RXP ַ).Ä0\RXv/ %D=$I<Ϝy)r&IoJE^ A Jez^oMR%9-Q6,o [oZIiH<% 4n3(;M%㼳O۵wă0M $u%.: (Ry˗HrCc)γb刡RP8ŴuU$_iOAV:TnN@ )OUNou=eDDJ^nyJjWY U_y*q BahقC񬤒*^V吒ڷ^( P2y.TZJù]Be8skõ@ƺˆxЩmyk;hq__"j2u0%ag<% "՚?d,LhެC⁶bXGJP2ж{U%! B4LibW\&_ቦV|!=n[ ۦ¸]4 J 6:48IYј="Xjy!` P(H\wn6$[J#v: 3t(ׁ3鵐2-L %٥))@"rZfdfwo{4)F/C^gzZSR3;DJl4* ks5hPJjorYm@$Z1dB#y~'&m[=%=z9wa`!p*ܖqs_\f7YUP;rguUW)H$ʅ(|U/sTPW cZy5.qy.Z|b<kI"?ȂLRH %lw|8rOr6:-4P%XI<%5‹$nuh?-kX> _w1%ݿ&~ d>1LjaXgdhȧi[p ~؅Sʲ I/p yoRMQs6͏w-e1WsHŀ O)uk]{fD[!% l|4gW oa巍dac+eh-**JVr<#n>$G!22ѾVzk:gom0Sl7> n3g}8Y{kiM>?YF%B)mGx<ֆam]W<ǜ9g%.%gmM(n +J#8i=T6q@V2BP$_=6{|~ԔbJ2͠M,@qtk(׃\@N.ϛBm; m OOwͿ fo`Rwj!k>]_-MXT~?6Qk^Y.־c߿p"zd X3sM݃[?zaѼB=f$0/ 3{?fOtb$tK*3bz4y>^VO AH+$(27[,@J!ݵhiV][Z;B}8tPw/k~E xq ߳y̛`ӛ?7ٮq_>sOE>U0!B&eFo໩}T˕%țP{a Xy|rv%.͒_1!;tqUѶS텽ga253:޹~cW_/韼q):l!=cA44S%R %!/nc4vfL*wmY-]rw!@(Gw$r(({ KhI $Azw͎eٖd5gٌWՖ߾fU~)5ugm-`Xmlcw0)>0_*u-7nzG]yTch[$igZ{{)G$Ew{ٶ44g=6B~dT'M.B6FCQ$%H2ۑPmGz蘇Wr)}*m "t]UzF=U{@R^I22Ox8񚚺GVȡgOMVh7᪥F 9w%_=2.2n~?} LlkDIH'Umj֚fds3\o(_pt!8=7)Q|+og=*."F2^ˤ OF/ڸ#;we$җy_T x xDYL8{㆗[oG1%q8mϣSWNDHm!IUTHjn?a~wk4*RHRYKڹpu??ܶ&Zrl~HmmSx4q1ˬE ;hǍ@֡ 7/WVvRUFI)#kŸi߹`OQ Z";:omSxu$ϷooSe96..*G;x0Djn;"$(b }ʰ$>%?hRotrܻqĤvWѰωn9vkavєw~gaHJ8wRR$7 C. I3$!KLj)0fqhoCNȈ=uXVQuAl/ O9S%$G+*pWݢPPVW^.*==rs%_eiф\nW6$r\,ӛ<-u[{ME6h;W6+{`{"I9}u5e"l/w)bOv솩ֱպz£ɅyYxt<$I>ytJkℜ@$p$-*bR_6=pH9YҚK WWզG]w5aEҸ bpL&@Rb9$1Iih`޻<vGLI\c7FILYdirS6Tތv6!_g7m] Yn$7ER|21lhE4'Dn6{9I]3v />'t)XRs#vܬV+()Gd5FR :mRIe)NW-ݵOAC-h Af<1-@ld%j)ZIIc-vUy*eH0Xj0X|Ŏ Q K ɭu$lBA"'\DRd ^I ]PA^KۍWV~e; n`0F ^nSŭ=KV?QQԫm`7/4,ԸZgBGwP,B&tj( ZQ3$Et@-MكC*Kê %W$ Pk5FPavevhYR#0K提 \bЖY+ ~$)HU=a!si8d |^iAEmLv$Ug|@ޞQ!3C/D^ieSc%/6W_qZBΝJi %L:l:#92*q)uh9'V Ɇa2af| Ȉwcmˍ㇔it%䋳l9I/صgu)S7g9f5sX|=n4†Zt@163~A8J>ZTRO+RXRx7ix c߸[mVAE8"2\0,#!s?eGrL\oZqm>T!ٹ]Iv{SSSI['c!WלP LGZh)o@5Fl,ݒ$aVOn?rL'^F4:8p5(prgXY32 ֗u8Ӌ H\6M<8V;J'd%8Tb_Kr dj"I%ȟ*/ c6T+s$xcD6AsGa9o9567v[{^B">mIqo$z"Xdfxg0%7+SJ"$uFC 8 {TaU! [v R1vd6 -8(4ږnn3IbAg\l A$In6Բ#o@Jn ˴MޚiM;HR錾dx[L Ԏ(x YIT}O\ɣm񆾚)-#HM$b5,GRqbm7}E+b1*nv\QmTݦ1p) &)`t=oIbS};%b߲E%Mls;>v߂Gm6AQ$%(#?0ˑĶ9=X;cT,"jOu |O}-HmڭHe#͑$L1& I>@Ke1`25߽f7[S:)O|ۋSnj3,iw5z39$?V''e6 ) L$z 2< H p`Z?"mLf$QJ bm{Agc_$J]V?xZҿca$98Ѵ`7e3d#jb0Y ێݶϽ'#ǼnQcoP^jD Neô,u?+MmqnĀqڿ*[6): ?v<1n}젮_~_h4e_eR.48q`/6=Uղkw*U6`!9w7moO{TWgm7[DǵT mN6?cmrIyVs,Vd80me+w Y3u`17~ʧL(Hh֣OSo:uKo72V\G<6_hզV\0>u?_<[ZgdD@ M;Ƭ+Ht{ōs_[yȂnjvۋP{>˦ >#]%ddLII [ }oӋс+<6Ԣݖ%$9X$$X%$Y]i[E˜qzg oxU﮹#sw Wl%GTwgzwKw&318/^:_u+_>\ʛp_p/6> lwc.V)?6FX~PX#ءId@ڤLVREm)(B#C2OϮAp6j5*^/;n7QmI8zCrRaٞӻqȂMׅ/'Ƞd%MUv}I]nRomGdw`¯8@ _o] WNmE!7uݹIfCPM vy+5cwՌ'|EK'اiܶZuuuF"X@#5mYG6ܑڢ1oD DҪf]'w u֌;_\~P7EpOi^[y#EnK>妧v5N/ '||+o#ܙlYW7հĉWASc]ts?bYUm[F{]hVY"Hjm&V䕑he` ~1H4jzkhGƲl8u{6sm G=? 3_ܲ#ovU}gLa%U6o+3n?T-AIaѪ[NrFe\uu=<WKnsS~N܁P[ `Rˣ@qft԰DL<Ԅf")ׁ0Ǖ?PiY/4]ZLLdx+pk`ݽQ=W~Gwu_Yz$#t JT,Ƽ4nAztHIiʪ #MXl! ++Qz}hHrzi 05ӏ$Ѹ!,it5i2 2a% & Dn62,1>0kUe܇24N#}0)Ҋ$NW4<=Ɯ$(@CoQ*>#)jYuxb`NV$KvxoFu^LHs9铜iG"ψ#jc$R۴})kb#:[q ))"mIZ >!ue'wm nXY~ BGϋ ^t,aT:<NJ|ܿEmt%|x$znX0v4BgM;rpdP9wl$ qD~$ĶYxe^DE /:~Wx{0ZJ@WG'D2yPI[pшS,"")Z=AW-zLW2S>8fφ8Z/y!wU2 MR6~^KOxeX=:a4hY(9bH5huUBώ8kFad Iߑi-%phơݑyz L(GĀ"my߲ e3// ǹw%6Pn7L ƶs I&FRI$F9Hl[nqJ+%UG#xፏy+>0+v#GIɑSm6I&b>lz{8k9[1V^[EW ȘqK &hBSbIgqKf{d3O 8yY65uH]0 ")ƈ%&Ǎ硖֑zb"iK{mPYRBy*YJA?8 b9F,/b⊶r6.qR")[ iŶk6F,>_Ͻ/k|-bЍC<ϙT 7W!9qWp5 ažvI \;RYTbO3ک-_;M 붦7qHJ/J['; H$15 =$B@S}A_D daF9HOAn &K+L>ʐm&+sz^ֻr_-Fp8  )m{}DLʬ 8a:]`WKA`=~O҆.@e4 _z^nFVZxK@/O#Ac;GOV[{^$Hʌp Igԅb=;UL}~ U|uOp[$Ԃ,Y1N@ V eSWU!t ZѤD`saOܛ77mF >4\ӔōNp=>o52kN1c =x|"tjmYUk۬A |Ć!)-RGee8 )'7^[ݺ& O5%md I'Ԣjim4`+e,ԒVِu66B6]GFuHf(R磎6X(ᇄgÿY s hռ)bC-j}z_A(n($ @!IWӏ#o f>G&U">F$Ip(R([Ϊtnm[#eYx L%% )ş8h$5$7uZv1)R.^Kkƺ+Ⱥږu'6yO -JA;n֡ ~v kٴZg<=@$җō4Y뀰P] éne96..*G;ܧaAywfEfMW$y7 I qV$U_"zv aԌ3Q--wN#j%%Y,XA5,n'6 d%6ϭ w\=&{Z_6M HO_hcGaHOBbpII5LtF_[$A(ݶIt(ƒ$}2Pls,7lƍ0h͟bXIRX^ & [pb󧠋#OqN!I## @O,n)GV pqmh5Sr/ۣH(lӜ/nG/=`1P~ϗntSpM}}~z=keЃ~M O ҩ~A_y}umk8+!H0+ <}r/۾"\{ӓG7$tXFl2;z8=T"ڥOnU*ußYG=T ^%7/Ӛm_}Pxx>?sɇW<|hi ;{芥?}?lx/x{~|SDZ sۅoܼT$ݵ/{YQGhu`%}fn8<P?4m~eĶs IdDM"Rx%Hl[&xY{&V߲8ad_ v}Ʈ!m9}jhy)8}򹘬~ ߒ$WϯY ǚu;rBwA?8#DK; ![)7SHʳ܄ؐS$05 ˷ [u8VM{hX̒`Xx#FX63"k?*ݴ>8bo]agq#Z$ @ܑtⵁEOIR$%_:!zbD{OJƘ,<0RחEO! $K %,iuR<9˝cqLAUJj5#R$DBHJXDŽ"7Fm @}J8%zn-Obբ019DmKX㖅N]wE$*[6B($ONxH+)[1YRH KjKJZO[FEglz$9p$QHt~\ A(2*ϥ{RT>u$Zt pV.洙tjpa6IV")ӎMIl;nNR$eMԬ38JŚxȱQ=i2$( H%cPh$PnITs#ngوF&POێnC)FaX 0@p,6"j `Yl8!@%%Q $idMXO8 ")e֏zyhhe4R+u5IZ e@y t/b`@`(`@iF`@J!Ҧ઴Jp,a_ǧ ,bmI'"8rI~0)?DMdor Ijo!iN 5VYKI>"fɎG}5[V7=p ;QfSČk ByvxК8a*NjAje*- PSikX'"eސɱXIHJz =! ι[g_ 悐 x~&?{"Y aa@F!;Hx53LJksMxuiet1h4fɲ,ER e0I$c;6?0i#Va'Jݭi'R>WϛbL n"q(IL!).@-TA 0'4.LI8 Hʆ$sIi>]IKTpRA%r vQHD|%G~wY = xZrjlD`(v1wZnA$//8[dlmi~ДϾjkVlS`(I5>UjnQpER+ )ĒeqyHͅXG^F4KBV5A1")U"ctܒVnjFsQQQ$ʳ1"@d</mF-l|l9 אd11"ʖd'tn[l*R;wj&")",b@k@Qb{( AA GBo0|:&JBnP/JMp_N]DzSet"ɶ6}bMrգu;DZJ œd @RzxRQ% $ײI$C"{k G go=U֪tͶIwo3~8In]}1>E-aReLpIY'!_O 6amn&n.(0ƶcTP񬆞z(HM C s@Lo:Ty[w3ՍmԧjMb`) &)rjt 5@^eKYyic:a tε0*=p-8K]V}}V=(!Wɠz7N?OgQmw@}3SĄ7nEr-FAYۦHJD)ƿ_<%z*µp [ݧI?sʥI$$miX:6v⬯$H"nER:O !B{ZVȄXY(jNk]{O,8%N'7lYKsIJ##ϻo'WM.ܚsYӾW{r㌭~O)xeo~?NdeDZgfwPh7 N^aFI .P_ߟ3HR~i}DR6+՟:9}5Cݲ*OѠNB\vL}ђm::,Zwy^V+")MLr~"Kc|F1ѽ;bɳkϽzfl5k s~x4RnlZ@& r$o;dIXY*OT𲹩mpw׻w=~Ƃ"D 8L T*DҠ|[?m$Sp}#!FDrwq]s%,OLSPg~C}hמ}\k`-q e&)ҧC޽;p:3mZ)P__%}7'9vƞD%|Gz盚f9;`"iԨQ$A/_c8 6a#x̒%vP-C8lr2e!i_i$dnY$!y l:ᮛ|]qq1OwR):?w''oh[M%I")3:#3{7|X PVR6~x;緜Ca@;Py=TIY"Hz{MHʨ,l\m(' ERPGLFFĠ\AĜ]IUGNzhmx"A>''l|#EUL7RaAF:93>sKN} bO":z6Ҭ;sIo6sG'WgR$QŤ}/RxH7m'QQ9Ӯ=?Krp,C$_V=ƯnPF4*`6-Wd/,՚R GRN"*:s%.$䙨<JDB B0|0b3!hd1[,VW(3ǔk(_\JMIyS9)wۥ? C fh3Y<׊Fs<͏d툃hQYnɫVG>ъ$r痳ҫp?,|'骮!k+ 7׺ C @'x`R p: i;X'&FbXv6:{Z4Z1*NUu:l6[{>hzk>ERNi}_9<[Cw& XO lZ}]v¢H7u6%P[_4T%DC 3,NȎyzqwѴ 3Z\xXЈL;"dD8 FO;< *)bSǹ£i:|[Kdd=q !toM&ӵ^ C@bSaY^ NDg~Mh!'4!QCB0B_nv]\x]B}UyR!R>뢶7N0!m%H ~`?rH :Fa8ӛJ쳒, gjZ%mgU=o׀\눏զ_ƌC^AKD2cHK _s9\жK fc;x,q.sش$$^7ߖS ^?#,';vڵkv!CneA"Ci%yEJpgk,񍑰qz,#uI?GG9Եak׮˗iӦ797[D]n.<74zӯ_]K%lܩ/lػ彻/ peg~E8Ҡ64gټN@A~PIIV;8hy{UVf-6”)SXŤ%H>nܲU 9.Xqh5VzRq0 KpV9NI*ڨ6ƾ2 l5, , }JK[%5] &_5w?@ҰaB@z4x~ԩYr< vHv jZkkky$6vD8Iq—y3N-G y^d;Fu!++ x3g$:Av;jj"F<6d$&2uwm/UVVcGR1d\ܛ$ՁcIiO„]A/|hizbIN۔&F@H:^z%thʣĤ2m+fqTveߧ97uNY幝!7ۖj"tA@RCvCѠ?!NGMMM,l\Z4e)3ɢB lo>{>~[t)-h ˃Ay^hvbDqC' &VMMeF%%% "-RZ=} 9X⦛,6W-%j=3oƱsࡥֆ%̭߃UmY'3.um4xm4yd4$D?!_n٬ږbܤRր;@&D,7>p_m2OV?{>yr~|=T"mmm9///% H/ Npg[ rIꙛ^*wQu2rWDOH[6'778&}``uEGhԓZ?X`JEEرcRoBDJW^rńCO,XOf։tu-zB{)bl><ؚ$5^rCF8!Yb"3$>$n+7o]?K1nt] 8c/<{&SAAAuu{3BOKan^f M O>g̙ OzSyfܤUւCKw ]vzcqTSwVk6|S>xXt]ᆕ/ڟ'5M9r$IDe~ le"9THIJgP~x?b@5F@l[ρ>ۧ^tϨjj PZAB̿u}BihZ5kDeYDmOwr~7`H"-j؎Du(1&Mj nIB%'pDт&Sw=Kgx#۫o3Sp H`#//ڙ̆kt(*$>U]r*%N^l( ~ԙHIgu֋/ݞ~:4nۖ7vlݯ.+O~fլ]Kwe'@q027!/|`ֿJΘo0TSSZZJAvcC>EI>#CTEEeee{졸QFHqJHIug׺^:`OW[Э|e9sΊ P.JhK K^|1l2^Nj`"B~~z%B_n 4"6S&jFG)ꢋ.ʕ+IѴך0aBM$Osow顇Wsg\+X9__{ &w;:bXn%K{U7Ff&5>,aÆUWW$ex-`fhT"&Ҍ3R-IIݶ~3;=TgF֭gq 01TXqdF*^wcޫÁG&Ғt)˕pU=Vѣ{X_Tg+Iє)S2>`0R*/O}'=ѳ^W]\^PC^;HS 1zKdԝ+,Il6@R=ҩl+1ճVtFu:<@n)n1ZI0;$z_GA֕IQ{ui /--%P6&ZqJjFwD0EOQ]IlA(Ib2#j" T۸ȳ>;s?ϟ~*%Mf͂u/:,SُsRXV"-X3`wL:i Kaaa,8PSw!';5QQ};]?`0;O4fo˒~p 6_VW4s**.GrKHtZdM11k TV bh VIhJ[ XA>bm9Du:<QeY80QvX_Sl=7t8QWL{\'pBF9ƣ!i#~!3`'X+\AAZT*JT/= V~s/VA"B `ʒdK,]HX2^2ljNbF|wJ uȌ3A9|bӄ$Go&O4\g0"0LXSΗXB·0'T\X ʊ\!"Sr~)M>y #Ӻu~mx+h4٘V~~ڻ&+++ɛ [n]UVʑhѢ?u.nsƮ{L WG |?𮢢b߾}b\La,GTǙ͞0GMa G|?"'4"fESSSZXv5lذpS \2Y[lN\TcJ+K(2Jm|qoRu ==%ympK+wJ$!H=,xDk)ܮ%^r}C+rԩ+Vx绚BgjΝQ90uQw9u JEnȊ>E:ʚ6vpCL6t%CČ<)^^6x#0?xׅwyU>pytmۀxIi$}wwi^[ Bڦh`L||>0N5c[ЇPcgwĀR$׹I.Wh fNSO%j|}y܏ `&;|0`zakakM^TGr)!^G0sV&C=kj|h\{|񭨣D p¨|CD\s p mx~-|O;EՍ7onG+*,,\`\̮o r6*K0,h39T)nb)̊ pl 6N"|>k.Wj;{Nv)Z \"'i^D< EN2pXHnui"H{a=?#xZfMW;k{k%N)+**K r&-oCd+vyY 6vR; 6V7+t#b4ԥ"D@+>)b?Vqr}i%'EiIγ2,l@1"F#2W$A t0'R~=u\|b"lna7ŻDxyUx3,fpP}A~ /yWl76()ɯ^2X^TA$8&ud0)+xI?U^iMͿ7G4j}6ոыOca/H~hXҶ+jU%G`.B2'I>~ewu@/btjqI::Zubm`! o]:Q5 Ľ=WPWk_p<95(.kiN&RWִ);"mF~@JI%@ sM^@"pG< QQM>hDy-h+%"NFSՎ e8Q:W}$K|T}^^J,*C4i ԁpG wQ%fkM:**lwP'gzƬF) eZ^?Yqr EDvR$0Nx6Wk5O6=MC)!#bk$n>]GTT;C֑hMFHM1,4 rbʔ|$vw5Hj:Aqȣ;=W /廔rwKb<| X7ޑwH:S8w=rO\6g̃QGʳ(8GcC5JU:i1p(!ʝ(;}߼3`ʠuy?as{O K)Gy| {#=tj&[ӡGd"HyGS70MUhStGjKAJh97;@#8ySSӓZ[].%Y봷^xGo|6a=\ ghB0v$ZvLS2ԅ@at҆gc /ro"Ah!ȟYnf]yPO>ȣ d#N^Y9}Ʈ}|6R.2>!|o`LoX|fM?;L( 4FYW9ܺP+Cѓ$-.. <)|RGrf#v0z1#OJ̮6SJuIIWd0O N{-'w٭_X1D\-ue%`OXe|H$?9u?_\VzG~c6ZGksG}8\:(2Yβ6#Yb0.]}cݒ+"mBbᗅW@mXas*Ћ Şwe\p*"/GBQ{KGHYXq2,=>=@R_=3ܳe% Ý>H-9^ƖsM .Suw E͵fxbI 87-8\v;77|e*gU~1X=dy""LѓHꧠIGU#yF;;=:`-kjP,_:9H ؂u'qJ=|LAY G# .%ƣ|ӡ:'iC^c(0Rr?gUD#"bU&kTA{eRT\UhT3J G}{pbYuuxF)+DAgg'w(UEmA *~ƬzD/chވ,|`ˮ)vġHYZbdu[!ʁܨ(2-J ؛AR]A |SQQQQQ )zѳAEEEEEUVVw .`ذaYxxNJ#1XPQQQQ @W[0# #;IiŴ?ׇaƑsBEEEE55XrAA^A*N*e$xUTTTTTTuWZvl2ONw:`tΪcnvn+wϮ'>EF9db!Ϡ1jjto?DR;B\C,t$=Q`SMS)k4ѨZ[[#,'j' \,&,qv/=uq) ĩ9U?hꠙ<;WOMُۭ}?>c{C;˲y#&60Lݶw}W 8c;fqcoCm3=Әo:_gИ4ǟ4NZZ]ӧ,#. Pqgu1~sk~:*RIl6ֆ^6ІIN&-/յmbv}on҈ N;cZbIklY ,gM2cr]k74mRQsޝR__sX\bnk_8X^S8Rl7}iS덹oL*#lӼuۖnKGE~)wi}2|Ơu6~L҈3O?{!K_.l|#FZӟc#y.MGp6`odG]su̸_?>Yy16e;]n̔Y&BOQS$vRaR;)ʷ!-iv}فe_x0X =#WyXak~|N vèߍ:޸}ڭKZڸwYwa!Y[xW #v=q]|[g g^8s̡Y˯ {[x{~kw:zߏ>&4ߋGuլ9`Í-[,O8g=~0kY슶6C?Q'z"_\6_h L]YmW$q:yő0趏"}76G־cYYrEwmc)ÓkHx< VF lCC]!0ʗ\Y/TNŽtK`L%/oJ>[ 2YL>l!Qi\>yKO(~׈,,SO5k?;BYkv7~xiĒ~TWYJ-0GVco8a8Q_oُ3,?O`'K_bSQQms{!fP,j'Q!^kz]roy+S?~o1fQsomG^]q]ബY*#ɦ22aj  <V\K?㺣u0wklzU0ЪCVQ`լ9ڲ}Z!0S."O}A8_ Fu;C <4޸ .e߳tϑ~NO 2Gٜ^l '_:yw]~U7`ꀓ8 k?dϐ}ފczF1 JxIVk pRO+HWn:I^7ro| (CWml/xl:!(46lZi;#>qI -7?z8ܵ`ڕ޿T8O*׫o]P!9g DQDsՕԽr+'pEXHs*V,Ӓ](?T[ο}[֗zk~=zϔ5" (mq`=p ~k v]0(.0 %{=*?I(rpL!De`Iqw-fȀ%* Ȕ?=nz'զDtðęl{q,?Q^֮:Wu2 l|;,IKNt*ۭRӍpRd`IZ &$Td(N,C!GN AOLS )?3JP{I1).' ( `b,'Eb7$hFDsF*7xf!v]˶l:Zv{ C7I}]6s vrRäN,ãAeN8.*pQ a u.$iYSfby{n !CLߝ޸TN$\~|%[?hBPy8gZ4"kBō)ZBF 4Ԅ]l~pQlړbJeחkIME7nGUHi5*}߼d"'PGrY"L&fs]](Pk4 'ET:2킯cI)ʗbַ(ۀw1֔=I)aj-t:]cs,&ԓR錞Fܛ@DDDDDC.ɞK)mBRH (x-qn4i1F~ 3:SDC5Xn61G(ʜD6hڑ[[Dm t6vҰicߢN4tQ&!'%ۘ$VVGl6WUB60)}Gd0vk#[RP`$5FE;C}:ɋoAs/p437*s[ӑj~ tdD7(#%i0i&3'Ai9TBtT _=)F8d/Ԥ#}ġ$mI8ҋor CDDD>B'z% :@tS 鈢(kK882:r ҈jha[uip{6ј,/S/f&sFh8O~K~To,ZFd:t7n~(B; ݫJ7zްIϙ]PYυwDQ<Fwq;R?=)Z5M,[~s/Y//Oͷ[c<_f km%Kv;Sn?fonPpW _"r/~F i׿Vw89:" w=_ M°Rn/v7TguruEr~KLyR~G8;IzR&C7d}KIGMf{I9v;"<.)éBER9g/U~|:rS;?bWGW!ݬVbM! ;uxEhٌgcu^ xģ2:JĬvү72g(]U(I1}{WUVm8sa lEaqmPof>/hU`_rE]%qgPüs]ݾ5I#I8)Ƥ5.z  iY5p-5x{UHF 6֔_k%{'Dͦ{R-(˘< wPx(bHW>sG($+(Gh~E@JSSQxQILͼk~St+Uir>'޹eH /RX‰ƌx.V3FU8.O"h4T*\_*4˲&pqd5u=iud۽g}S]Y?a#_wp.ir_pTy>;O˙I~ߛ }[>x'Z ]=pղNXEfxo_=v' ¬.qI{[ԾG@KhHg)8xT/`QRF_/t J]kN絍)/%5>.X7t#K4s76 ]cwkk| +Wes-3Ӱa9s\ϋu7=Nf?o̧5^i͟_ \Wݺo™S}ϭXs /x?/Փ[oxp:Kco)̗}8Bk=9_K(GjC҇^6ݨsb?}+\r}؜{_æ7+Z.V|Kv;<þu7 j A߼g e?ϯVҝ_k>m[Z}C 8nE@篼e>l8P0=3Q@ijgp+AjrT9EO}\s8}$c?QƤT/+S>puNQNvoqJִA`|TaZ?=ՠ*6&g] ]v <"߰r#KwSG[ v DŽ>YZNޮT^p xeplsٷo3;Oy؛B1ܕMж|p悌?fۿ}(wm%]6) Y4~_ld ٓV;,:@%sQbPy3^^X4S>tLܐ '|CotkY rE z5J~ SEZQ?\eϜI9wEU>8P5o_Ne%ť 6Tֆg2j G8(;IhFBM[uG;vgQ[fZdzv3份pTon,q3O X%*3fb냱OLw_JيcX[Sa͗e7%s^ŊAKTyx?Dd1On3YϦZ+!,KUUaIDqFD.!"Jʖx3>qO+I$U3Զ̼WDE8y5PtU#ʶI`tb'zI iI%x+>R#Wy!@iX4TrvQD0HF 8%'z5a6(K8S7Π ^$"""" ׶lidi/P2q ,-m@L'5y<yj3(j^'Dz{1 Q ƍ eфcQ&5:*>NROaWgP DD. ټsN0i^|RlP9֐F䮈J"rqhNQ|=Ӎ8%5&NyĠ^H;RiDDDDD&Orh$(* *kF~eդNuqN7'VMb!cM6AVL&% 70fpQg7I> Q]s5z+#'9gF6ѧ{Q]2**۲H75Ӊ6pR(ҕ8Hr ZRǨ9}ۚ<ɠjsN7Z]|M"h')sӍpR˔K*}Q5H`Q4 {e0JVnzy5T Fcei)}ӭB ǙL&Jp8'%@sWCw5FMG"Z"LҰIb#C!_eZn[OZR&ѾWMbX,աXJM,{͔)Dc?#" )͢I9  ՝ȊCqES4Ùsh2iQ/֠VC"rVVeQ$$I=tkxSdNRTbd: 8Nc}r!Ɛns6gaØ1)If#[R0OFwK_M:sho=kBgp6]T҈@}5QTN܄z^fSqe d'DD3 I@nhhl@@/u]$F " D"uְ 7cԶv70IJUFKΣM娬q m\6`F~8p/b0 `TW xR"+N".M3*-v ۥ2ƚN""R:)Knll 9q׷8C MQ]?#_$$iJ? Ik7 zњpzm5wz{{rگl˦#F v;эIRQ3zdN xE!جl$98N""{et9pRJH xҹFk'!di? xUQ4m8C,Fg_%̈́9L1o:>coMݿ6p=7z!wg6dȨ R07ZYK4+ FtH-'%@:y9:Ibnф( I0 8Wr,'*= 9[L{ FO==7y=͡"ro(JᎳHf }ͯK)K;6IG%TQ~\d2UV`VObRא!obuhARD}Vpf $=cAEu]7zžt1I_8d'BO:{4͍vi#Zz1`֕&Be[6Q?^F8)%d$xIl*ID}Vi!l]|! qq)sR/)!׽. v3ZGle%RxV4*14-?4]Yr<Ni: 47o._[>__?#Y;&Fy}~x&9\ugG>ϱ/UJiwcy6 o_'Erw;gtγs=hWvenEo#fuĺo_ofNꁪ[_V`p# ݹ_)8[̠7xxUَ˞ZnwOY4]p:{8# n[0dcPnےm^ZeX0ų^ܽtwkؘa<ǜ5&m`1ptpK+V[@?_|d#pE\/ sg]5 F:o`5o|̛w l:SNI!yfi(ɒ@Pfh)zhCUpwDCI9-7tK_uo_v[r$ת@fx(.|Kq ξe^8ci&C',w lY'Crܷ&5 =21 dw{i}$!LDm ?dm%B8(q5x%N|.ӊH1TL{R.RBXO+翢`71soO˟^+h~w` SPЪlgه7MZ'%а~rړś}ҢIP% {BSjj>x.)OuvA?6A J~ml6vݡ0ZsrnIFWJBm˲fYR)$bO"JtScUh[9I|G l*_M {mOL}|wyL$M4Oϟ|Mlj}Y͂:]wyg.%I- oS']e@NQJQ3 2sFȝMomq-Fo1\>5p|rߞq<ַNkڠvw>|0=q4&s0mXje5q8} #8*Cg;da5'iPUS\e$X,ա ȁo e."1ޘMOz_y[{?.㟷;>&4>}tdա{v>fow<}E>{ C_Λ95FʗV~xJf8JzmmYu?1l@#kx^@NW} p6wVk'ͻi~Ğ1$mP!pmᐓܱX\yҘa<3Ɯ1( pYp`0-JK!٭o3:k};qѷXyr.1j'~0͎Lѿ_lj8ޢe廪k{o*IFÓk67|x2L=kC,Y[bxb.6eR'%RFCBM"Aa<4!$Fҗ.Zf-7U5l-?)㼔|x?Ӯ|JAm[ɶ/S5vD˞_6 286:w|cC/ߨ;N9>s!aɖO,]|JrOgW;~w-Uw_tYmܬ9gLd}llovŋ+dPǯx+߸_y$[C1฀hW|xÀޟ>tE,V (̼Ϳy>\&_z߾Gп@ο+Cݻ^mV#߸xj8¿]UPdbv)6zv) CW55ϟ<`ٝ|vγ/%*p5 TTwGuʊkzqOwZ&ʽ*W6{<}[o}$ٕ~{fNa;ZCau`~o0xŻU\/įZtFj{Mi|"dX?`լ8w0xi-1iF(d<_Jw(Z{)Nk{ne􉺙Y<<MmϾPyxwGG΀='aX!=gOvWo8Uk˚Bmj]?*[ ps9Z4g`IhNlOP)Au8ω UsNN{:NBnRL'1N"J(쾭t0:kaݷMcJv&LZfK+m:׸=;KdIc^>k/omh&jewX>`RFNcPqYzIYٶ_n:~Sycv[ò@-o]ΛSNPO^F3k@ί-]csg7kg:z 'jjܨ#n, )^_V/9o]lc3qkܴU}+M#b4*i%oZ]$=_H0}IRHjQ$$Mtޕ/ g'J'mcol dݷ51%30:ރSr.=loﭩj f=RrN*T튎"?n|G3=Yd1~n;`_gOq8T/FeMN(3 <`6W=z'#U7 <pރ`Q]2xx!rvZ~) tR./U=v I/JpWT5(F4N"iu[9I"w<$(y{ ȓ )1 vUj3{; fjZ&Ϣv pf }sLKɽ+q7hZkkC!O5N}uN8)eޏ&Xcf_CD*)tJtzbB t֩vV=6oKg{`\&F(ܴt7GZjMEi"oG:cՠnLG wjZI$I)$)< O]F 'gV:}J};r.o*=0U],ILN ƥ+۾mhtF{܁By[v^T (* FnRKfCBM2iHN"}M}ldp='5v|~-m$D>;^AȪ iYt^r۝G;$}V7FJzFc0$$jNXI_$T(hZKVӌo3*1#5hx,A K1k)h!i-LV y- &uY"vJцvyM8Ut8d h4VTTDN"JҬ{IӉ >L%80Q& - DE6` PL'4טK`Cr99rCf:@@H$&u(%Mc3񴸑ja3ҁH`7Wp%uQA\{sTH{R9 SLʪ–\O0Up(b DD7Sho`"al)&;$8$O_lZAHS([tv蕆ŧ=B"j8++ll5b T#"&Dn#15,'"S sPgHE*\`H:>5מ* dXb#Nz; Haqn=(?=iynNM%#MZ(㲌Ii*SKd8.yD,T3 if b8hOP (nRzQ E!( 5 , ?mۊҵV7ZB~\ɖ a6i[׸pzgMW\enWگȁo%Nk bODe}bג՘^y;1*,-$WfK'~JPt$^d) Ed W0<3l݋wΪ"v)Σ +)́:h𸓻70jf[,s9pHE4#j*.6DL,ID$'&s TG8)'M ͍J}MQC?OaΒ (y`@D nd7 Bnk[Z64vV"'ڨ) n{?zgK OD#z{pNJAN uѕBxؓ"uVV3tRƜ˛HjvR DWP5r4)K3HvIcwi/ӍpRjlLXIښA8)J1噢8IeHS ?Q* j^S`]e]#DV FD8d5xjxhhI2PKD+ Ty7T1<-+-~g9(irŅZCҐSA/2aPBM$=&h2 S(! (-"EQ7&NJ15b*.xV}<<}n S Z=~Lw(OvƌD#?> In"Hl !Ɨ-l[86Ѷ012 ږ_*­V5cN;LŠ }ڊTF< i|9[]S1p^o9N"&ړD jpZÃ[it$XiPrW"D{:2RFlȮy8dkTDNT%y xƒpE=VZBEiP Zg D}>b;uݞ'y%658I>[I9| 42(W&"JG˯֢H}4iRCl!*\#nmw {p0O (]pQJ5Ȝ$OC -((8ݩfTzx5l&y/##3Ihx:^@ V/tGIԂX]fj,r'̦M]"%U<'oH {p,{kL<豊ZVuƢϣjo″_TV+;b ثh^;ݥMNؔhU dM,vɇ#'U8p`Ѩ܁>#jT؍H8-ETpD&Jݺj:P*6bVk31 INd sl uPFcJ䣹AsR$hU+<j Us8X5'y~wEqlȻx#N獟oSNzŘ[X$31 8w۟ovy5jujK$ vy*V:Va ?xh@~3 .57[owW6:ְX>3 .ᆢ϶{Ù4k|VQլ_;X M8W[/{^!ک#5|5dfK͋pa؜,Eg CiLԨ?<)/h8YN?[.l)$e KnRNS".tfQ_1?#ʘTv(n1Lеj胵|k;gBW{پWcj߀T[G6 gddb%DC׃eiN-| '4=79I_e0HIa)71%pnJ :ם1ow>j ̿pC28>l< 8yE9o(J 8fM{.=7I/7*Xӡ0(}RAIr-_5%1I+&˶&vyrM 3WвB6Ӣsa`ʝ>ڍn*mz-wID=LF+'HP/BGnF\q8+ת1W!n'N-mM:P i/*ȜVT`պ2mz Ԝ7Z (f9&wVS!Iq|vsj-|WOd!ʟ'9\D3e5g~Ӝ577n,[<ۘY4{Ck ;C1'MfbUb*\46 CRiZzc_ww h'EWN7I( sCMj;od2eNk$JEYGF{p3:6O,'yAL*ZﵫOǤgB`y=n~:Ω#Wn5_Gχwxkg xDS"^.v!uEڒ~9xױe|wɶLJe͘3V IuG>^Tw}'vg1(!RvG_몙34t?dRTC9N(cVIH9yXQН%/Mý_]6GdI6PU8d2ꦦ&ID"ޠKIQ >VS},s-*5>HnuFx &쑴Jyj7Q?8uE Wِ|P,k,)@DžwKN`պvauz#,Hi:C>6=TBTh9 nW(d~pWZ{pK,n{AD"RU'lbپERNQ}.vݢJMzVӂO#u1'M K5&_*!70Q qK% ŜtI| 3 i+I{*;Ȝ$#B8'e4$4dc7o/TzڐV4F151?p}Ճ(e%Ŝ,b|FT*϶h]Ŝ̗g F7P{Q/x|ꞹ8kTlE|ID=Ȑ]DLSuN< Qd8 uoO&oRNRIjcNVW1#uKGFsIOSw۪AVhQ#k2o656K*XRW]RENBJ8gf5^A᤾P{6 yt)}5!Il ` vܽDDɕH!ApE %rHX ހRDւ oJ+q\E&@<5n -@ʦqq&‰<_@(`Tj`7ISrp} +AͰY \)!nD)/ 2a08:& 0 kd€51J Mh# Q8/PLX-b js 驘-^dw%nQS~i(r"DBP-;>+4x Z7H݀DMrTazx60hɆJ`I!0 $` if \S0ڰ], A  Eb N̐~p1'K&܎h e;M5m˛nkZN^pQHV,' $64sI$PޢBhon$&p>NS1T<֍0$ CaH![2dlAGdq0 6@H% %3t4`QDKVa5nEfT"XWCDIR#BוBU.ٜCxqR8%O-هl;p(߂ػZ+ʘd4++CnVUK8i >'Lf9Nіڵ$M2M,6c`)0*b CjXք!13# 0UC،b`*xHyH# @-Y}cC1 a"B 9E05Ǭ9w7kT郓TClhe-䣁ftXn<ū2[r}tWEqR$M$IjReNMJ+ S` t$ZOD{pslo `EÃF<x![GҢ#2B;Co$ 6h bԀ0cMC`H.FЗ#%фlݡ^EB4f C@5Ь&T ہhJ-bոQP0 ȼAx5 a<,4<mƧ(U8Ёn\u!<-2]t#J5UNBA/s3s@oir|>Hܺ9G nL GHߋ9wĠiEl 4& b9 CdB, -(JƵDRI * 1I1%0ZYw1aDW lc$ 9608IMN O6ރѐH71/6`0:քߔ;#v{'&M]ٛ @+~M՛9iFZ1 &nkxjTbC0ur)(h;0$hAB! Rb0"$zCt3%0 K" ƅB 0qb `d A7 ehs98W2cCؾF8)Ee4&2$bu '\tuzsȃ yHhGyʱ["g,.L `NJmh6N FA'rKhH2oP{ ""RaQyT6HIXkJ+ΦE<1 ',o 55!Ԁz+wYFb! 莡AWJf60XILCMv"ާF5a*WJ@n%`)_W,HEQD& dhi5aM3u&md*pdsm+W*Uܫl˦#fr$I)4s"IlF&:z1'ƲNzBC4g 4HJbX"+`ޅ%x@? ;q4fh QYZpN( / ^^ hL(zD#w lxiGyfNǭx&U.(N#F_ّnRWNz'Y{)'ʃ0*ozRTE,g/woų]r^`CPA &wͼddl}3 3ofggߴ~{ S -<˺EC VN4Y#p~%$5T2":4@p!@RmbBbۃAY8!ьgф 7pX"$} C;F[ w[Yd]0)&CRoCኜdXzcAFlzsԕh1Iwh=HH{ydp p c|7 DsGv\6@p E3HN4H$ĺ@_ |Z&rV kh|#/qː"H9 ]Eu۔\*GMM *X,oREWIIUt$CJՓ7;JZ:R"pC$ Bn>$Z_6sK! pR*%ҋd> ejAas+_$')  Bx zS፹#/m["%RNzIC~Ԯ/!1w0B59}i[MI*1&SD|.҂D%$N.D1)G\hn!-*sKs܂8&{ 6`9 :"l'@J'3|8D{vFRd: XVIX(Ūܴ5[{>9)sxM "i=*S&9c}gA2(4D1@@Ԃ-s9ibnAln: ̊=I\ {62xغb.&>@jzu?R$d:2 k'6&aNJ]YlFf'YbieUܣ}F[r:cna9BrsyVE> 48^S+.iw]s ١܂|CJ8W/FWCmⓦ㢽ҲK,VÄݽ#S:b3 fd2\m = sRʙTy@:3wj+o~b}ײˤ/u_as Vf5\J-{[D{Ҕ"0X`U["EvlUI"$UUUp$+I)ImHMd '5Z|>:9Bh6 [)GVaHqʞ${->q$4?(cYOV!K}M@rj*Ŧ#tÜPݺj YO $dMFpz37qiXXI/I^j9Ir(aG `Awxou{ HESƀnRZvqIH= ccB-ݎ6f01C,rCHoz z߆P&g )P>Ӱ2F6\`f2f?r%8F)}C xRttn $Juu]`0L&|RaNJccRd<@#ƙ7+JnSb{5˹i޸mgV/ֆ=02E~?<eW qLAx F戃Ƃ `k/jsd:ROI@zI AweF't2oV SX܆J1ԙ |\C )~<jXɝm+Z0'q ~^ރ{t'K>)rćC]Lb_{KPE8@YD ^U.R/|K l[&Nœ2&9jYk?;<i!-dHOmISnIRCK%$3o8툫//~y;*1zIP72v~~UϩW9v}~Ҩه]tެ#gW 3/']]CNwȕ?~zau9 ARm< y) gSL9VW<1+ Z2*XiXzjUp#>0'Lbu֒,OwN"h9N=RI:*I9)ZI<qoaz5΅'ܙk/~;󟫶|ZvNKr3w]t]g?\R80]}9/߁EtpΘq-}{E^tsCELbr՝|'ឋĨDCrb7j(ߔb]l՘ -bctDQ4Px R6^&AņKʐ$)5H$-zm\8_9B"YS# nX ߰0' :? ҮBOG>_![PR9xBLĐyj-Eo6*%hihG`WBn9ׯdh\rV -Up\STYtSpvGMh?(f۵otj5nۓ1*qJ$hQónL]Vn鈦`'aNJ8wa+H!o.K Wm:1ʁ=9&m SN7\GL ue[E8$q{u8$k59;y1HNVqRP cg_'v]ـ&hID Ɔj ) {vaNJ#٭*{R28I)'9u:t=+I>t9Cekᄡp48uE*$, $1$n[zgñ=ӵn*oTE2Un4t:e{0lDœtFNz cQ8)j#4MJ.D$XX*  '2'hC1jb@6JSJ4&Phl'p֫kv2LG&IɜnL:Շ8)xN<+",D;ΙfdbdJp`mrs$ߤ''aae,'%IIPz+f?X75gfqbum䈊xא,ܔޝl*諾=)6'k#ӑ`Є+aaNJ7NjgOJFIhe}|S8N;C~tnX$ (A  DI !zW Y#%IR캇"XdjYJ")J>V RfBSŸxO~…A_7¤y·Wf);0'vuWI0XNJLsS!dt ZzT4AQIbX"Y\2QB$O! Dt`$6bBZJ/,HiVg82, H4K%4HhSAJȑdetr2y#Hқ "@z0XqQg IxH_9Aid"z/c8#)lFiaSHI}WUcLl;IdcNb IIO󀔷294d@nCX@1~oۺ, 1ʑSφ4%gMҽB Ȁ7"#Btqdt !Bc>K\1mCƑlۧ>^| a+-rx! +):Ԥ]}QXH&*jRYDģd. 5=]p}ӟv7Om2i:IX%*@Tk0]8)N|y+TNjrR>vZ&!5"]M)1BZl@'2QTA!$Ǚ!CUIGGࠃ"=ű rs\ l lVX5"5I2`M8hlݑh -Ջ>Qk"6BJF +cxb>G֊(0Ɯ9)d4[b%$N$I96YڎhX|H6H2fs_2ҳUllCrdFcD, '>>PHp#Ƒr؇XwXـ\P NFɶ/i cJOJ̚2[zOdq8Jnv;%IiII'ƬpRjr:w$ܡVz2LGfYɜn^9u|R2RM4,'9UI*R'(o>+\I,vaNJ{exKJ%=xсŤ͝%ےPn8Vb2Սrf^oX CKK $I#xN-pbΤ'٧Co..<ıCYBP<,<$pNrI%mC-h:)XXXX}DBVMOZl6^9)AD))I Lb8Oaxo H <,/ /<'&A8˲hP8[A$A%XXXX WGFH0'e&$1+pKL$%0,|7u{pX$IY oH^D$:h!I(V{L8 +wl_Pܺ! Aܘ2FFE#w9I+C(I$c uf%:v{5@N(&0 `ҳ-s+}3'V*Qt H,9 + cp_+^v! N|_bjCpKb;k7-42Y֪*7 Q7.U5+ʗ feuhMWRpz{6|;ֺKW:ԟ'AAn8޺}mtZ sR(ׁIj;U_}mC7y< u';nih/mwmu>r-GF^5yρ:4MQiZo;0'efsmsR{|_VfW WV|-Y?_SU/ZAh w {>&Řh_{~wQH 뷇B!5qmm-*1J sRF1B>GhӸf܂luGyymd[~Hif]*z"Xw>ӝwbNJAm8u? 1;iR;ݭL#0,I%ɂ8 'h=m%؞G ҏu}p#77]鷨JllbȦ6.+@zz7HuWjH1/aNœ2Jjҧ9j#ʛyM6VibVYOR$ sRJ)VkSbn<¡H6aݮ&Ip9)dzngZ _朆b|`iJ[114.%.ݍ+rmu*[QΡE2wdQ ,n?Gw#TMFIfrlLœRӗC]{O 6`NŠC4YGp\϶=B,^nݦ ֕*ӑT[aNL η(/>C_-}+0|`%EO`TӍQۍF|SGI`M3z^Ε"P;V^oiiCNX2A'O޳g/--5`ƛl )%p(h뱨CJ_5?a`@k m`[/pd#AƎ 2Y,u7,I#$>le㸕+Wi (F.?ȿЬCmmgAAJD/R:YSgVč-;k,|SY~˵5uD5n{cc椾"J4,+aC/*_W}JeO{hC}6*}>S_3sg.nK^ִmuD1'aN:Ⱦ޻u])y7:s+QnnϜ93ewvǺ`c?sL|S\"ϲgq359 t͵%~=$ VIcdsIOꬭvl59 7~Ӯ6>4!\3X={4% -D1gjPaR$\9zD};خJf2X{gYpՒ;fnXvC{| W$,$UoKF区kq`e4~7tKYyB+?r[ݶu\ :r3q]aNJnMSՂ٪/椴1yԝZ#N+ sV?zp`e4N7 vl2WKjTΨ7xZS+ sVuWZS'acVkwnMIٓo_⣥'t:0zN7 86M&Uo4Vf4Yi!o_bC[-K۝Eg'6$,d깵ߡ.Y0mn򃕈7A6] FdH''j>xm|JB:WՁ:4[ <$$"K&>}zqqqo;ӭ|/?=df=F߁vb'Ofl׷̬c? gsWYݵE4N=Ki 2Ls%T4bNJ-;\gb*%$ߖTn `x.H< 6k :zv¡a]w]VVM56mLO0 kUq@ ag|iFi# QSSSPP9 ,2fmzKWT(CI]!. G+Zݼ?\Kֈ`P|^~Yzm{s=r+ I$j\$4}44s-oƻ,+8;cR0'ar͹=w澃({叁iR|nGŬA`;XUY#xiz͚5 #'vh9rd/sЬOZ y kYmUSYlӊ[Q}agat~=cKqAa:X_]zُ-U'(NXy^u&M*3sLI/oN\ݑ g~wW*JPٜ3jb1 g6z (?Lt&=^9gzr?2֏N0 1~. $Y֢FmOb %vٴcHg9θ;/c8^8r^6& =dW\,i?×z[2$C!.%I_ :uڵkѡG VYDH8\]yB}}YKKK"eM^vQ?[*vR$C 8Mͽn˞*v;~I*͘M=媕o?=+fEC޼{m} FH1'%Ssٶuyf۶z5~puCΩSg~Jy]}=# uw/$aNJ t衇ȃ3/j=GV;+ n$I~Kh#a MH-s!$y?tES/~jըbǝKo}:Mβ]=;r>'S(>$[Y !0J'?ud2nб-Kl:ЮVӺl ÷45^n4ݛ<0{o#kB6$m ~ogs%p y{_{o[&Fp P^^ޯ_?TyiIb׻mYi! sRu$Lm M4Y n+hF =Uz'p ̨ɶ>Ӆ\-OԂ#ܶ끫kRb?tg'nsE"ӄtܙkhVe82s~)n7F nhhN1'%%8i/n\Gq^|`%>6$5QiIzP'tҶ[=qljmR%}43ޟ?J?v9)Y,\ XR[tamq9ɔs^Xm@orgǎ8s;,<6`oO$tјC)}`?yCHRkgñB?|?Pff +r:`pԨQIzI};z5䤡'wgWe~s/ѰO~ۅ7BN:kZ(vCv9[oڳ9tsG\ 3zu?^p~}x߸_]_zV!]4xS \~AiJE,nuTϸ3]S^>P4wmm#ߺPwmw}7|)f՗EE& $| $Iwo}Y'<ȶ뾱=rA6BʐѬÏ[oLru~uS]]we7RQ5lw=Ww>;;t'Ԕ'\Ҳ n۶{f/wklWcVH,Kڲz=8 ʂ%Im{]LH/"0߰C/&TWW_VSSlUֺi. K#55$aN= 8[.۴wf]|E?̙E]`D_yN?~Ԙֿkۼo_5YXSXR* L=p9 85l62 Qy))_*RB-t k|ʳqK(=:&qGKkk̙hWښ`aaNJ͞={-c~m?M=7a+)fq\ GVDtEE+P葼7"m}9'ϫO$W.$)_T{7-w:[Gn< 2Y&{⦍^J ݨɱUUE&OJV}M귅#< TTx<tg Z++jaǓd\Iӧ00~JJ#ӡtH5YC"؃&kfLnJ%AQzbYM~i"zpdR^xᅿŸ~if{S:Rx߰2FӦմ( ^XXhXTvdtcn+!NIk4CaM1$C0^@X6q1 (!^>at:J($y> ƶH'uFQρHH{zw.2U0'aEWx߰2CSNiχݮDpI7UְmӍ$g$hՙ[y灂;@+D|ҴJCuPICJ$,<I I&}sp#6-^믏,W!q86-??[,ԹRrl@8!w9c ة-$EN?+!Eu1V n\ejJ!*A5"}{g64]%qTf.j: ‚V NnCGNH1"*F,RAzF`@NZ~-$a ­u;o޼? .t݅p娸lٲ9sD_tR4;z-[߫tWךD_aaa%WNrɺv6t'P1jœ`t^؇NMMԦ&&S@j'YԈ2CRXJmR$2p +8 ^*._*O>3Έ h,Vvv6{ c]n׹KL[y7!O"Lono #`ddxB(8V~=Y&>n:=f̘W>XKo67NT]E I +-gλZh=p˧Qwwq$$o%D>PM{Ry5~i9o2GABDQ[De ~L'UUU%1]Zꫯ.--,K V:AgXJ#QX>mYZt/'Qc%P$J?gl|8x,{RM; ^0 tB(#U H S"{S/4&/ZptE2T`F@{1`4ItZݫ+"""AS /#>!Avo&ƔF## qښG~y`cB>20w6.O+CVBGڸ!ASC)'%S{5+rkU')bRr^\I'OFi*++,Yk=Iڠׇd6.l ^ƑLJԅ( QW҃BC"1.Ts[]@:++ҲzL]}@~"67~.o,.kg ^[ҩ9GY6:2;*|~_W.\d!'R0ÕM&b[@AkIJ󫫗o.i AHd#EEE<ƍ!o39s,5aZ8azq٤$T? շٰza#v. SYD)ą6qy*JyMk멵8#88M%"6)BUAQV Ѝ1#Sw`nɊ&3-^Ө5lق4[nUw:93'L,I"rEèՓREwx7XRglt#gcKa" ZbWⶱa8AQiH#5={ݯm#mBXD?|\;Lj'`!a=hkS.f4fYivS\l O^.eOv,X4;Nq'NDIJ0 DX)o`y\Nz i:0-aae2u,CJ!W-VU) =9o!q d‘A9# ZR Nk($F#(*>) pV*gXsλ/Յ.+*=JLH q4mŒH`,z0$PS뢵Uahnє"m ^ _֦>_6vD\> My,rq%q:IQ}V7'RRF!usMuU.,i\!#[ ѱ:8I ߏ! +ÄދJbZ=gk_Ԃ#Vmԇ0͐C\jQTW7"I#ؔ}ڨL: sNECOfrA{]džQp< h  {`e#YRB5CQ$TgI:VVRYQ'<jjdKU}?e>]JׯuѹCQAQ Ziw`yjK?"w7Gn'Y ?Z+Πw eqiR~ ?G5?u9+ @ lf0?8!ʮRG_8!➨)uh?ASpZAHzgS3dLJ_0MOEgik ¥\^oݿ'׏hLce bJ%%Ӡ:9ГB QBJ̲F`ړYKYt dl<ꒅ;/l>_E3c3HVYJ"mN~Kqwy+W|JV8!AYYKohf 4[ $ĦN[bN"ڏtӏ)Ni,GN.u[J~B\B="22cJENBgBF1ECu$[BQI]]o/ FNt'jnEu뒎ZXUд@})?{FYSPldTv%K/p2NIIJ|Ps@73)N ŀRQ2DC(>f z봂?Fؖ}k p_l=ʩTO1RL{1.)j{$Y}~.%GHc|T;:F4椨 G"=jzwI+J=|*J52%~Gs{:Rݩag^!= ʹtpb(ӒK4HEGi".uwKӂ]R?pK.I _4ΑH{ ie)i)Voqſ+ç&RG1pȀ'8|I4|xUw_mlFۗעzi>z7*r;()_A^PA D'eJ~u ҀK~!IfiފtlEkVǷt,drVg+7"J6_)'˃ B~WVjC /[w->( V-D3\uب-DDL>]['ȥQׇ5A^3Ei݌څ@|ImQ cCa(͚F[jfҴZx0'aaU@8JSϩ#iXHfZBEr>Zo7x$ & =qqNS1b CV+Q|o'C hR*2Sš%j'u5hR3G{0'aauTŊd\ JOjA;$r)-y}_24Ȳ"+YS-`cVg~ ZtYPeHbՂ2/++G&Pna9K 4R\Z6Վ-M&l sVU\RsUd@X

N~7 $|D&!")1.Jtf~ IbaQX.RVw$?vb4M4EѬ#'.Ey'(% \MK;l6R.!E.e l6766FHl1L4E%!J$dIVe2bZJ<<<\$Qv{ &[9 ?02hdOrʌ1" a] tie ydu;Ohk֬FS[[y]wLF.L&_dDĴ47q_UeXxR&l,7YfwVI9Cas5Joַƞ"r3qNR mV޴hႳgU@:qqp XqմԈI\< $vrf~CB6Z3?י_XFSވH7yfBtV=zkLZcqjQ}If,Z`kd][vhA&d,?52@tԁ==7*ڮk޳}Of圞bǏ|،X[Itˏ[M 8wb*mXDZĢoḙS_p T.. F Wj.U+:\n ! cv΋$2|$"m}펒nazbجM,}dH/%'&^V Fƶ,oij>u|HŋYq11ii%vք˙Y! ]tD@sf: hi27eB1zĬΚs:N0P2*οlX Eюꕫ-li*VKZs]( hIȒDo}U1e}[vN|j"CO\Μ4ӯ [$9pl˒iaSWf5{;dͲn.ce)w|_kh-ʊzmDIH6Bnnkn'hsk]WlLVbJ .%}""@"Hm,4iBb#HJ;! jД5+#%%!FZ,F J`W[ ei #[*+B6\.Dk/I&.}*e$M$5vҟ8~Х6'$<"0DQaquϜ44^u;+hq\:WT\^g\f+7#C3&OT+vXQBKkR f&n^\\.*^\أ>1%*\4w!9B}V.Bф"ӧ_9;-j@$x rZTܲgZB5+;N-!K[u枖&P@tw岼٭ma^S[ޮU1 !3=V1D Qg ҲrDk# )TrX)k7bҗ.UhǤ c&eLj%~f[L˵L S uu`ZUYC Qj:!!&Y{˚ gtu5e=8*Bw|f'lNWUv=6=\JߪEKcU^]1eeOO_US+E%w ;c ,4zb````<pg B6{RsG;$QU80~r h6ܵo L`Z{ =>t:07ݼ#=5144]1JB޼EtA2 B;8 z/8W3R[{lΣ(5(p pf.~SWӡ];hgWN߾LPߕK{y-o#gifJ)HWc/Jnߊnٱ $pG^rp AeٵUƣ/ f54A5]Ik0@sf@ E"[zJ!5m]]}.4@a]<\1}aqszZ st6Sp+[_`````<20vǥ.)]wq'͜1;oڜ] @܏ 4qmtpKM1'9gǜ Q3×&hW֍PL.uр\06{Yo~T\\I~V_\=RrR HezivE{ = t0YA%|2csq?Cpx4{wo5v9~H$Kwl%ք,_rn^1nt8Oo^Vo}X,>\bbRHH7 W^< 縖(n^wʔ #<_ilx^TvqM𤗏,%0ȡy˭nJ&Nֺ]Mi玄kzJz\!\4]untM $!|kkko޼R@3~Y&222defu};v};vXXxXccc]}^oaxMJpNWWWyf7Bd;::Ǝ={ 0 H?=}diiPR(v_V* ܵkO Q2/ ?{k g}P햝=ѣK,9|3naSnٲexɠz[~s./!'C_7n3ađ#Gbr|jj=BQQQ===P~0/k }4&V9K!N8m-2HG?&q/@˜Z!>:[Osve: {k õ$YfNUCqkY\Q"B U M39Umr R~g,p{I,?II gQa MN0ûT*;o~8 ޺ukŊgF7okWcbbΝ=+( q㋋o)򪪪`k6T.W457WTҔJ_ .--5HQ^^ @R&H(\| yf~b@tLqxbم "##Uo@@ 53\*5Hۃ;"\O>ƠƒGn*?R𣐞Y<'ƼPk9y &>}:1qDhHH~TZ RSS,)SJ _Zz{%@ f Kg4eʔ-92ԩS3/ pǏzѣG`Xsnݼ Sk֬?3gF͍O RC: qq'NX,˗/Yr^t /̈́N"^%''T2iD3˟v:L"Q,XOrܸ\Y ݌ ^L΁^c I\jwKvBb?8=`R8/%.ϊ{^\_ϋ_Z0n#r9ZV[ҫNhKD9糦Ⅲ\fmtpSQ^c`< i̓M$FԪRLRadsj!{ؑ%z%Row J5.9>./Y9iԹ*B h'A BB_n5 ϧ|BwY{' q*⚦[^2gC;%:,xd*\{Bs$i]WC)'9zP./LO|`< -?J.`@;lPu/W ǦWI/޻vNP^m) FpqgJ9wI:ݴ 8W6g )I#IpwMorp!pNQ6ޜJt/p۶:YLϵa`gY~!ÐP4apc;N<֛ ɿѹt18 ѫjqlAQfwݛIKM1}{%NeK1h޴*T^x`(?W* e 8ރ9@Iޯ LݹKqoဧM!NQbX  Pvf6|+ ݴ¾h8XrnΎ̅[8r˱ĥ7gM$a u[J\k1si:Ϛ:] Cs*wsNMQHot_/y, |{2L.YV?<@ Fb}C OY)S-`m32(pSBE$x{-/{:y S)!(ΘRp!-VqN@UאJம.r2Q]]L&lkk _R҂Rj0  /7loo@KCjAAAMMMq  "m=E/Oe2tnEۣ#gΜ9sfbRҩ'aڵ -;w[^ _t͛!s{ ݸqlɒ%?xzZ^BRa͸XK2FٳgO:5aĨȃB֭_T .deeٻ7<, lqq#G>y6m_^zPq````` u,Uc+/[ޛ31BKN/$"H?ӹs_|q;^۷O8qÆ?/Xڵ_}xBll, ׬Y˥FVWW-\d^JJg.\PPP>av p)n.ZMd?Ե[zcI@Ο?ĉǏ &{677+Jnll|\ /||ݺugϞZ/p̛7ɓI10000VÑjQQ?O`qqqG+--Y%6bX{tu/555/^|饗kjjE"`j;a D &;kkkCBBS~M0pf|%\wwO[[%K֭۾o Xw,Zm`loڵu&",w 6evJKk n x6mZ/Z7o|z9-{/k<)SB 2#LSS=Cw^ F@z𛈈p Dl!H33Ο g\r>ñ$a<`#1  MLL¬CL38FPj4a۶m1"[+..T||E3 uT%6#<Ǘ> (W`` \1s,H51gjժ՝*ֽY t\\w ƒsM鑤X,('A rC#7nN<;ˁ3R.}uw_z<Q{v{>~.bNЮ{Fn v4$*5Hcy˖-@Fr峞ٹ}u^ X_d c!#n0ͅP@W4IyX0`74+JxF!Dlw00000[B!ea`EVDL& ~~~---Z?k0Ypjll 2gR--Ͳ!4ͫo^?//S%@2-[v葪jMXؔɓu: eQcsJ֜-[vi&LXTO.33#?v|gv74N5iNWJr #CBkxl :mP$VxryTTv [җu* `4#5[,@nAdjAPPg i$-aMf^b 'O1bDMMMFFQ6mw/rcsؔ 1f"ƍ׿o;wj֭ݱcǍElXǼTgg'K/AlV|yy?ظ8x'O裏__կ~ q{EБDXWW_݅XD*MN3MmFxiEE_|Ԕ6mڴhd`'76okR:8>~8d1ec)p cs€7BA$&&٬ֶVgF~A䘭wt7dgg E@@`xwA ^^׿ TUUYɓDGGszJPDFF|NCPhY~e˖g:MQ0h4=Xau 999w1c>S<`曀̊Db\?Y!K]v;Iw&JܵkyE OQHnf f6mڼ~zhUx1jj:TUUm6QâWVVm۶-$$LII9zD"NJbmkk'nࠠ;v\|?jXܰf$b}&iu&N(ڥK% ^ӝZLFӔ?3EGZNJJ|':M&#J$W^bcc>iӦ~˖-rO]|'0F j7.8quѸaѣGߥ\୒J}9"E|! UlL~B!wkNFn3)|i̜,!::/|on߾ vP>}TSSy+%$$ !S+**N_ | >_;v솿E@ ^ګ `y-A0ꚚH E.\8=\@gS 9YEțôiM$W?X/ D.e LMDbZ-_~e̘1GNX AۣVMuv6 r n6 19%PhͦSFGG)J dfm?5jѣG'O\QQq A\0{{vv6u((( % YҹGʂT౴N*@HL^7.?/F}30nYu0rrr<IJ9sV{U~~ї Ka|̖l7(4N ??ӗth4сC4+͝ݽLfӨQPf>C٩{Xc.Yd˖-7`zyff:q8:(uҤIw޵Q28p… 3gΰ۩ӧOgdd asff`4]t[Z[WX?D:+HNN^4!؀ۉ'!y=p a Ӧ#wXf͚VzC /}wW>t[W,l6t,ϔHCBkkjaDTT*Ef\\ G)_xa?#` ȑl~gwݺ\_\Ϲ8Sd2)p `[[#"H׎er&4"hxÀww:aùsg7k/~˺2U^^_v---{}=5{m J1B(Fc'4XFxkmSL upHHDdD"aL:- cbc$).jB!3g60a~Í7i40q [bƌxBb(jجV ho<2.F#m{ilnĜ9s[Z~fΜcN_bネW^92g?Y?ikv;[s28-MN#XVc^+D=p™w0O 8kܙ]1{CAu .Xo'Ow~*ܺukƍիbckqhMs% e~W?.'^\Z~Mz׃A ~ D}v MQśϻo"t ((W_t/Z4o޼~JzxOM6m…Ϊ)D_ƈpH~~w ٖu1|4is>>5?tP@@Z0a^Cpkԭ`<7-zD;4L5J*c.j}@ƃh+Pֆb`` @'6y04C/!bڹ狊?xw½{Ϟ~׳2}IٝatuuTXmVj`)˜4GS{/n{pRxNBA2N 8A"V$g1+ 2B\.SQdMwBTap8;Id2zzD"t5b/4v[Wg'K@_6O>jo|)z}ss6m,~Zǭ"5mm#G%2ftnV55zDVbn (U{{=t V@K>_t>xCI^[#q/A1s%z kz000 ;k_qJ_bj5MA3sc?$=V~P%@tTmmm0*c_@qq0 CGGٜ7x#;;<}OT(s-}2lْ"߿r :H BJň(l?Dwٳv͚py^ף N8133+%Ͳ;HިG~1$$t $o+#l dsDO9Ш:"-**%|2ti) Qv`&X.~c IϞ=m6PՊnݺifMXX\lepHBﯪ>yX,Zx_|YVV{zj,aL\^XXd6fΜӦX7.wd^vGHdVl]&@kk+>chl<{@.))¡V5M]]]mm `L ;88ѣ[QQӁJ+W=͛0*NHH0ݮ YPB f6W9W^ ]UUՎ;?sP?(22җ4x]~L*MOO555Nm*K]r&w؆Ƣ73FrŇR}3fvS׫=~59VI *( ޒӧOϞ=ޏk׮%''hv~]:^(ddd H} w7mc```xQ}>]Ya`T0Id-K333ǍyɌ ա ihh>999v'N X BKKKMy5={[P^yU0#K\ti/~Gie}~+yFfGxeO|X&yǏ4sa)` ΍Fax1ٽa筷#y9_phB.D|Ye%^iEqs8&hSVҀOf,+v@W_%%lٲe͚7n\;v<3~3nݚǯ=x#F\P)+**}_Œ .(;E t-001ˊ0+k$ؗiԪ*: }4uciYf7&Z?G—00tuu E1>U}/ 7 1٫WF yw^z;vH~ԨQ' ?~)-Jqrq;udYKӐ%K7!!ޕriIIX36=}5k;q#G {d_y74Mq{qAr''']ԩ6 PAAR!!!m͹`%0i$Af_YY qqq/_&A^Bܾ}XLfpٳgA~_z ڵwn/0DdC 1cƜ>}~.\R9P?Ymxϕ3 v=JzEZw7- S)):&4T"vLM W*g_1lLH~ t}`1VɋAGq= }yD$]f9&6?|aL?m%)$YTFpCRZ+d2 VSZ HIWWwu=<2Ƈk#~fK3/gbA m/B\ !]*$"!q8ɨ f _[:;;WcƌdII P@'XTT4e_\~:;e-rHo4zѤ=#XKm yh&zYOϚTG=nwi?D𨂂̢N~pPu}z'D"O ,裎{Ceee_4)FJVbܬ 1(=Hz B;e D4 24|HUa1>DL"+#G# R]]0Ԯ@/6kرcܹ Ց#00rQ_̡]/ Nͬ;FJַg?9MS jA;yÇGFD|ו ?ڗ?aТ q(Nz26h#DȦ6^9U.<0'vWehqs;ޡW}ջTc}Aa/'o\(^@I@*`r5XKۭun{F$5Rݑ~Z/!4W0DP춷J~qRwJ&Z'&"F6O!2:UTJ1 ΂q׭[WR\g7⒒Ǘ. Phygg[9s?$!|afiX,q";j Z8>~@ mOoذ׮]S={L .L^e)e8 o׍Gcy~xD&=ց(p_+V4Cا7|cҤs u-_kc}>VÑXG[[lL U|rnn.b55W bnjs۷oGDDL0(11Iu^P(vtDL5$}iiirrrjjիW-fD*:ڊBfggC\m6`&X* vZzFFIqqUUPV:u =ٳXT&{Ο;hf*7?~5kd^J^jU֚n'v[Oe3?nB2j|jtX.Z5J#]7RF@em[wZeBU-^::]13kEl)Y3g̙3a~⥪*ɤfJO&M/H/Z0WzEvJ5 k *Y#헽O议;v,^ȑ#B"!m٢;v؂gqc kW_|Ţ 8! z{OeUUDxݺU|̙+Wv'OXp  pu`7F}Y3gQTN\x;F$$&&%UVTb.JB֮]SS[~ZW[Zc4WX{ ی@֟(vs .-e XiD 28!T/ & A4M@BBdM@GluN#cBE$9Vl-QRa@8+ib"`2!:H 53`@h;Oj|za={CBBGP'hfVv@"`48q<>>!111>. L.~~~/24zMM f(t_9ĈFѣ\EEȀtPPT&jt˗/UU]HTdŹ7o ۟}oKD _*a D S⤣8NIT"`~"T60ZZ7+i4E>~cYa63X$MN@J LJ{>1 ~ANk4k֬ ˞~@Z(m4"::P;`x55ׯ_1_OTVUEFF={]767?nܸsMT'ܴiS'[ŅEE!:,***saHرc˗/i֢Jl\\kSYxCRr2<ׂ3Yk`t&*'ЅSOm۾22={4ꕫ?:?~֬YΝkmm2 8(Q(k Ο9L:u޼P:um9}Ljjŋ ŋWF233ڎ|FX[n:=1000Uс# CXX} (%Cx8z\ϟjt{5>m?*/_/stH4j͙f:Ё=,2As_  ֭[@#8pСq,3ÇN>3UUUC#&YYY9b 9B|'؉ L&C;>P0P* ` H$,`pȭZ9=vvwArG*%:'BPBFGE[j_pMA@<`oc ]9*$l#AV/]xHHIJr111?8mmmRBT{駗GEEN˻?{OTpǒp0vuu kk+JDR)> zb@j@@hH'l0 ܐl.A - `@v pqx#M}/QN6w+6Yp#:(F.>qqLSZZ*@TD9gӡ@GBPIGAc``` J%|Fܵ!N?R`[Yn! ܅[hKR~[F.! JR_WE聻tz0fHHf3qQ^^G$TrMp =jN~ D/ E+@r $DL(kl+AI̅Q>UD{I"V[@nۖ7tĈGJmwy/00k,n97 "\pPPePs 0 YYcƌ~,i_vwwC[̞=vIsV\r׮]Qtx6Oӟ~ixXȼ*&ݾlٲK/665AK/.+--)))~=>.͛.]>9Ua 5>Pww~h#v꫿µ?3RȞ0ӫqwL.YrS[g\]p@5`Ο?% B!rXt˗KJ2a~;v _ZlYe|LJT8|m۶#Gidu_|xg;;\]""#cbb;xkuK/.,,)S֊2f92ZF#Hď0߂^b___IIIvv7Go$qw`f6@ĸv\6U[[[XX0:LPggg^(" 2r#+c[A(H_S*~SN/%/^|qmǏ>8Ørd`mqY(Jpq <) rիV-~w8dVrb$g`rGGЈysQz!^_FhinőКGIo٠*LFJ▯\bjEp K/DTNB:8z}Fv6X5׿\\ɓ'wڊKss3.Q.!ݷo>o޸q_r2APi<+ŏvtt Ϟ= ~؈T__Zi9AFAAAa~l_% Ζ>>/G:պuke3Z߀Xz5 0fj'U|/#d WsXTTsNPhgΘ~諯$RitTԉA,9zKpE8yL"//_vfee%zZRrPoX"IHH@.]"Zˣ##0pzPɬ*3zB? LA't",, ?8""?9е;vlذw J{Gy<#==,, 9o>> ݻwY|ĉ`OƻcԬ\rBNtÓNJh(Ύ)\r ĹV_'h[ dtNNL\f?{1|#QT:63lʪjB'2A`Aj rg8o޼k׮Ƣ`~.\@*,, G@x򗿠6P\ CK1 *0͉ϟYGVr. H{{;LhІMMM#Ey.m4 rpxg`3|7?M$ھ=-=m%㻣 [qFb"xA1rP7ZF5Џ^Xi3إw6=j*4W<裿݋ @tt ZqgPPPPI,HNH]0Ҿ+dB2a`遭 ~O"7n#@~>wߣ6n0bݸq:⩧%8%i\]]XԊK>h-Sx^^nnVD[|L2h7Y6I ldtb$<<<55 m"$$4**:44̙3~i||BppW;3<<<RRRw|вR;#ύMNNA%?-**Zv]DxDUeΝeggXF߼y :ϑ#A%CnjF-[KKJ"100pBstc@BMbɓAAAdx ZCB-Y8CsHx+//)eKooN~zE\Xss~.~Bc,T}!q'ӱ@ LJm\4^z$|p;>7oތϧ5ĥH,Hs/^?~Gusit |nذĉ ,Xt)' cynH9זۡ]L.41DB!f9M L縀&(w={~:t諬,3%%]++gWwz[O\1|UcڍLČMa_.yLjGmh~!f>,˾a:Kx aẂbPUUj @pDN*l|No~sȑÇ;88 =o^X *?17GM!.Z9eb] u gIi$nIxwa|Y {>{#jMgo;KzrJoooDD3)a9c a(]'СC~k֬@%%_MIIO<+?ٺeuRcµȐyD2Vq':~c=7Kr'Y(PPPPPH0Kd@z\;ظUT߿ ϿR([[k/_G&A&>a\+,,SO=C$ 9k?3`Tb޻Lô3̙3*J$$$wNNII!r92G۷$jcX,++ɺ_&~ N>O 'J$OO۹5Vk^}Ԕ߈ի11߄gڰ1GZV(]]滢jNe 9o޼+W@d;v,//k41.hP/_&aBCCJ zq@~mmmCC… 8`#ϭΟ{L$=-młzꩪO>O~qwcx[lo?>3db|ZGlPSs!ipy:H>baeB2N^Dpp059@ڣ~pTFBRD^^&k"HˡIC#E99ck\>̙/_Ydؕ2 "JJ.\|ŊK.˖-v|FX蕲!zn)._pt)>n_w\OܹԔ1zEs9$B֖i]@-t:%0hxL}M-0l#.@w SPP%5h2)noqgGx+5- σF'Oz+66*8(~̙HX6X|ȑuС͛7@CWUU566'*z#N`sdѪE"S蚬?qLL ZZ=3v>{lAAz<@:@lG<ĉx\cCQPPPL+ l\$n|VVVMM êۜ==kQ@55P6D> \OӛFX"GϘإ(ӣT WBE% #ݻwaNN㸓c999'OR(8Esws񩪮 CM>>kW\bVP's``'쫯11 + bNc5  ;! PUdž[nZ;hE{&Ҷfu---0s'aPʺU>NJ5r蓶6JrRVQo/p^N\C$%%UWUq³g[Z+**\`[ΰܩs4Gϗdַ}Vdn۶/K@@@PPP\\ c1/18MD$99b oJ]p_)C'D"L\&i H^ߵ# Io/MlԳ! KƼ%h-Z UL]m'O/%@S[^^6++Ң"#?A`n:FðY|ǎEEE>s&)9ZZ0 ` $)ZhAtt44 hghNR+! Q ;fk]0'Anzv 91. jkkGyx*Zs0ehb{#5<7l0wDޮ^EF2́Lց2wOG:33s͚?4"<<''>KII~)HbqʕZlHOU(vڕ'pal\\P`dB;;v? ҢV}aq ?+Y;/ƍ̬q+aqB[ᓱyB{ZsxPyrC|-O疟$ *>j_F,?$sbov ?҆× 'tr܉&IcL͛7UB"%#Dj|ܾ}0[qA%dD"QwWׄob0OOЈ2(ymaj&aI3x3a:öKmbq]wKo}71C3+#c<ѣE %11!=-c8@c{T"pˆt䟂adj8knaƉaΰ  0Fϒ S0Y 0biax0b pwG"f+V)`rw&:l$㭞f/& ^Lll_(`#K#ߜ*vvdlj1L;1-"n]`ݪcO!<==wWswbą9` d.ݦv‹e  e$0L+D92L/1- büĎpIJ_.v$v9qixUl`lXUU*Z*d ڵ o577,Z.h]0'00Z^q8Y{0eoD;:QX|2`U6].ۊ $098tww7EquM&b6`8AScO?ظcǎ q>>ɨ jYٿbooowuuUUWGFDH$Cᆆ]ϊkהJ%2cbbf.z;??I8bX[ƝFIŖ cvA6vɳ]ro38QUUlٲO>$)1ڵ{UTTlݺU"z{{|*(())Yj_~g555>|8%%>6.nݯpV . Ca~>h$-̼B$ l322&aՖ 0p##y%$$m-,\x1 ʛL`OnciLMMM2ǏҝQPPP <% >a!v)$Hl$-e%ƍ:RWWwR ㎅Z]hmm˻pBjj*T(>d~aJm6 'O*JgΜihl7jjp~s~~~z}}}׮]ػw͛m[: .]kЋIL(ðGFjXu[#d2P={?3ؿCCC >x@}?쳁`(W_-]4,, \aU"##ϟ? /JjPb:I ƍh>XgH3HxbX[aW V+X>3ljs`=eN6 ^跿m˯d7mDyyyKK'XCKAAq|֔X,t_d]ryx` c/ ASPmDDDII` ci L!-ZFz1 (((.F٘fܯjbOrfXT eؒɔgsVZRr1(7w޽Hzzzb@]]]OCY?pܷzK?fcccjjNkjjZz'JJKz}JrFѳ.:tf_&왣򲲲Zo)))$2; FR%vZU,s2Ȣ 2w@1kK[fh2?ɋ'tmkmlhXrC&|ޕSNBR" 4<<⩧|JŵkL^\\\pP\qС+V2ZtW* x$&KXꞝ_tO;?|xÚ.IRk׮ 'Je}}=:YQQ!ɺ]\\/\S f n݋iH42K0H΋ho[[Szҥ={vC_;??Zy9>>(yG.a !y]~a`}{jnnēO/s'SK 4E e΋/8bg?I<^;W^^/z((((:d2YeUUO"W^|ᕟㅄ$Z$Dtbb"AfL`fy#)IJJ\jqC>77-u ){ԾF!P(v'acH$b74G [(-Z0l]]pOMs΄pʎZ% )Sƈ0X}_=888444--\VׯX,33UFp똶`[l((((@&wuu'}/P0ݭJ0r[OC=CuuuK, .ohii^j༔UU`a. PPP4`999A͑dv ^&NSSWWW9f0d2YCCCoO4dggA>w*)((<hqI,wxUP#k! zzz{zz'\\\Ƚwo4Ȅy˓03phw!#Rv2HAq=qV~Ii}b-}|ilYL.2_?_JzѣG,X000C*حX[FSRRrKέex2rbV<?!&X{lrtt mYǷH~x:O>9~xrrRtuu}G>^xA.|< :Çzׯ;w.>>>55 HAST*8_|^^*[ØhBNS 06=mWX7=U?divOƒU>:H{{e& eu=O LPHbpnx;{1nEVb?~}y>d؃YxHpY 2韦̳$=Zv_i4ތc#c1?VT~\yǐ f8y\6qaeqMqg5'wvt,]m؈RlǓJVOt3$el~OOO/O%K664W*wrr lmkYYSrܧ~ Qr-[>}b~ڵ`xp[+W??v$d(N!.{!74ͽ z7HA1+p k?9s :BKK Zyy9o=lRO z*z+NBá˗/o޼w8O_}UgggyH⟦tGϝ;Ѐ }9$$} ;m -03 _Xq3ʦ"dxW#L1TjDQkD"h}0c#}vNlT"orv ֢b4D˰lc޽$ zfWWWQq1ziVf9`zzUe%!hpzFFFMMMnn/A.999HCM!wQ()))`'xDD`Zzm;AŽ(JBud٣w@[@J'HÒAB%]*\f az z <.<ƷrGG.B 9&S(͕x.EviULu:\>s Ah-s a^]铩idЂ䤤ƦFwwe˖:O"Dlѣ+vj ' ۩B}J ?MDxm۴Zc/';m~uffdڵ+1)"**͍PGopCyZ33;ќZF6atqK"ֶ6L/Tww,~ۣ+=;8+)z 2T* rGGDjA͹ĢԴHfjRf͚5!@7lPTPBNyyyB>4ދ@/bbce2kAAA3=--221`bLW2J{$x|k&Q`:SVijVn_O -x|>f*^'J%`h4&c N8;utt( S''IZNQ< FޠN_FV )۠FK1P 8%} eS cpaϏ`qPȥ9Ɛf%KBB>s-O ->(EH\5 Vz'w\ 4q\\dΝ;.\ў=]]]H>|M.V^ ?@  ˵ZmNNNRR<@ARn Í}c֘Bvݪ\# nݙ}k7J\ ..>邂ꪪĤE99{-GGy vƍoƙ3g.]:/!7YbEll,Jz{@c]x7;S5}o/6P1'rRo0ehw5\ʪs΁F4r OOOp{ǯ/Y7nXlP$<}tZj뼄_|Rw=Szw2n2 ;Ywbx-+GxG"  IS(h覩 He2Y7k&Ald1|@zlH2߯jF2\ld^oK1m'ɭu s(nrG&%vF8 j:!! Y^RRxn]]]YRpz{{SI;jq&ł q[uCCX,{4Gin}wl܃LF# #G"øMFnnn--- OW(gφRDGG+ P\urrP*x;wZ[[tJs:t:<<ҥK3/fԄ^zuٲeBf.xD3aL(ðS}?[ &FN+=„ F:PX=NhRSSA@8ՠV^Oۡ=䓠0E"fгu/w$T*W[jll›555;`\ Dz@=h2b*Pe [GDܶmG}|rدPggukrfn[VP!;.L,-8K`$rGSV+J,sAR ]%&&y׺P@M+ lZPaW#H55mmmuMͥeess:hg/XP^^~Ȕ .(JRy[|ӷ& \Y %K5OO<ikk+! ++A HYx"Z٩ZRr9᫯oCsE&0l_MP10_[[_@yƍŋw@%]|+,,D灩tߦMܙv-`j۾<%\bl( <NB$Z?|BUh4녙<Ld12D*xjγt[wг 1uww~:zgg'9ڒX,98OhvaչvgM ٲGrȧUa)X\#CeNpX:b=Z)A\lO{ljjjssʕ+Q&WYYY\\\$ 499Z-$$ 11qL{o;!"_nƪUfn4@-=zDʕ+`l]]] п||| gV G8#25--mojl@:u*44 ;LǣsݻG?l_0pOF7A///GNccҥK)z{{j "?Fmx(9' پ;yJ1rn(Q(*g'C߷il_tAV\ aC?R"@|ۿկuzrZ- nG*.Y$#//X֧3n 韒A2 I/_0 7s*oOD<==.;;ŋAAA%v?z%(.Y g?cݖ cV Oh3gs=P`W^d4shrP&ɷt:"" &R***~A Q %Btvv+ # d48555pp"Ӽ_G"k{Q^ʺe#,!6cz PaqhR&M^ 2Olق6cQ$'#m(! Ѿ]ܶlތ֯w)WGGR)Y[[ | qݸq#7:- 9Ѯ,-\92667mKDQqc}ɔCS,qk1116N$S$zmrr2#E&,{:0W)&O_l>2{iٓYVW^^fO?h^,_ZZ9T8.'sNLL$_IL$ WWWTbXa@zn>aKdJ˲$AFiH^p#[AGA4Ș1s3b$s$irr$]􌋋'mV9V"߼|z`{'!ArLqpAPH`-'{T "C u7ni,'#dQCC>7ʂCdo9"' ǞQa@Q &0l7sKI?M^sgIk"Rn*P(p×O<'uu9b$x q!~/bcc&QNlg wftvx|]xאIaBV4'`Ú(GLTTVbZUVVyf/CXCɼ50(ðStX|NX#Heϟ0 py  IH1먫oKȀ+))\L/jD_x=WgW+ qA#:::-Z!r/^8|̈́Dc,N"ppp@zJU0p=(q莯shN`􄁅QH H/w$aAQӃ4` 5HqOggg\F~TXX&#[9XӋ?8 "x fN8mkr=T~ߍ¥'Dq'Ľxctj2|tI(JT*I|I~V0\UjѶ p縠Yq~G(dNC577g`/5|MFchhɓ'!P? x 4MSpW?;ڹ}e ;d K@"at¤Yh(e˖92eDh񂂂>;AG(,<'%xM;cŰϳe/ tx#CYcT*q ׮]#!|Ͳep}Ŋ/_NLL$dpVN؏YxH0#589R c4ڡ?(I,CH$a{q[ <]'-\0;;Q+asZ*G~cÚī ;8]h!Goj|*B ՞ i5*%}r3KWr%9G=B rJU qFDDj8 [n4?4UsIcحxsvՂ1rr-id=XΎAd+9wF3ݍCaQݢ9՞A;yk#9C^M0y!ˠF\Zʁ¼o} d˾AA"pM'%n9PA" ߗ`?GBБRa 4QQQx0@DZ[[UQ[\E6O+p׮]_3 ;IaY(,\J ryXh-VY- dPYH*?H$R}+Emq}}}ŹCƩ|Add pǥKˮ^5 V\`xj1iډ` } 9Z$}}+PC_ +wU}|8;,^,a7/-z?v![bA n{\@a8da7{[{ݠ]x{zXjmi\fڇ V&&^Ww脆t&sa4u^ghooFqqIUU7m_BAiSSukܷ `I\g#_ݧ ծ[.556Q cv!dgf7x@Ϧ08.~ާo=3!Oaaa|Iss@(QQQ==0;`Y1$4,-+Ie)J5kYςd+:LOϹ uAA1PՖ3ZVȂ@rt:ݭJp5Xng'θ:a"Zz.W~Pz>BT$N2LY0LCD"<<( ԙ:Uu)nۆ:Zs5(LDyeN괫*c1 P~ɧ,˖Uc$CNND`$-s8::rĒڤRق?aFY 0ml"f"MaŽT*7m5_IIINNNqi ...,V^ "R[[Kqw}+W/I6 J&$$:QԉFmmmk֬괫}%c1 vT$H$/r}]pur 6F=χ€f0N;}G#2'OR?E!WWW|28~8Aee%nϿzjFFĉYPP: 59uԕ+W@bP'ԨJ)B?QVV:===j1 vI( &cB~ oy@,f͝:M0fB8Sfvbp]VA_ur郞"qM#JM&t??pWT&$$&6YmY'A&AQgcce^^^DfsYd?q a18˼aNƒ0-mres uvF&PRR0胜~Ѩ==<`ڕ V)Xo%ĝ[GId .!C3&rh&W'̰3G k'390Ev/&/.7AUvg-w ;"{9H.6DFFJ2ۗ@1viFʮ埌U_\\;“t rvv[$ӯVkuuF__UVA!IHJJ"+4M_|QQYq=J)Hx{y-[lǎUcb_|ŋb5$8#TJ E 4K^L&~TYDGzՋovTXXQZZwҥGGG*0(((lABdXSd7B݉0z 0SIDJ($4Q&,;OFLn4T* i ..PSx@V Pȱ ˋٻL*]Qx̠_n4 tR1,((((6VlUi9R /m d>bڵ+EET\أbb-|jZh$,I^2-CSzz%mqHn?pС; L|Z0uJJJnFꪭMLLV)h򵵵f޼yrF|Njpnu/\,ᄌ:ydTT4 v`gg'la|A1#2*@ ഝu=w(K)yc'(D+nFF d JaeeeNjooǨ^O৭[p  1b m۶i4Ȭ]z ny찰Fe|2@VYU:c,gpCDcc1f@~?""Q;ye.1D܌4ʊ YYYKIIINN6ͯ/.Y >>>Gݸqc^^Xŋϟ?D?F2?/2552M&!I*3** <)00ȑ#6mB Xʕ+!bj M1xhUM 3.s76 fR*UnչW???Ƞxg`n{tAt\jjuj]F$;Nhx.}#-ZK\1#)A AhoowC1#!̙3PL7o yN p㏣ځdnٲTHݻI_UpωL}XfΤD=T{GFZL,TVԹsGA7<+#W^Fs̙7o]˩S^:->>++{ ?R2 05Fe4,]uo1BA%$$DD6mڄB̒RބLR^^^>>>Je !%tUpO1!WO^ps}Ћ4cP'\o0ҟQ{1t6⡌]vm_*/".Ҙt6DEs4O@PRSR9'%%(jkoD;qC4o43NfE;IieV c25hzA0%#zD,xCWX#rÄ'HOb9t!V|$gn0I" ?0ж&Pt;PRg#ֈ!-`Xϩh:i"& IHe&a_w;+׿? gǀ'9z??~|]m۶P} / _?nuE[Xc'䥉3Bxoʘ AvS@GgϞ~˖zd2^t1hrptn.jO:UZV}].n{i,Xرchsf6mon߾?v-3FA;&dEaL Qj{c"N2cZ)aTߨ֮{<ه:"@o0fE$&LH X.W*r*6BQG'oOL)hlii9s6-= C}g0-3gO8i4Ͻ?=>>p׮{oTu֍6*i`a/CVR0ֈlbn0kllİd6)]k[ۡWYgw@n73G/yw664?C7_eeeyyzvm:+W|u57Θ>}Z|wƌ.KFm{pZfuįt4L b%Y2gƋW% @4JOc ͏j$F(91T ŵ(͈m#ZBGG:Uq}t ;tc9qٔS ;lAO|wϵwt rܹ> ׋B0flKRQ C--<73czV^Fb췌1vaX?z⭭oƓ?4; e˦O7u ۥ'2Ξ=[^Q|2̢p9> qиy Ѣiy>d &]3`"Ut2Pp/!ə '&Ij(sH Cj e+** ^x000]"u[|9~#O^x1t]뒃K.-E>˿)[o\>s/8(СCYYڂmB_CCN* 3/>ߞ7O-&@A!llºR.!F"p}V8d-[P7np %KdLnKzܥv̙߹y3  w?|'ovooeenojjˋCjuK,9ի###}||P.\ vf_הta\蒌1c(I"@31u}%CƮ_I&6_f ^ƍӧsТ킑!\w$K)N=5­krNR {׮]{o"מ}7W `O? <x{E)--O?%K[ʕ+6P':Ʈ0+Xx :U0%j+bl@7[Bn'-d]ڹ36Ƀ(0a?"_P* _ QNOO'$@je@ \(\n .EccHεO>{X8zhq]T[LRTǀ 9&aJJJ'ꤻٗa{5s3pX" ޼yhQL[رD4rPRh7R&ѾaQRbғO>ɄXhQX=cOHꞞ4w_Ee+00O <=/l/0* ipQz[Ã]V0m  .BcT2#(:9/p !$@UUUBofK>>>tbbKHO JOП5v cbbHv z p}KVSRR T!,, c`}@nuhh#þ\I5&fdB "tsǠk1%$'%J')ˆ #$8?U7ޠ0͛Ph3n'cI]~[,]xz>zu@ς0]X: 'ۂ> _ ɲ`iӳnJ=dNcs5$ӸC8f.V_GL*'O&B@viBqHI43CJ$CD!٘BG˱$Y$!tr[S9/v r%hQZT GXjIj}"hqDgo'ʼnO_Rn==Jگ#E/KGq[ܝ;:zDʔ`PMOY91|<]ˉ Udf:振` J^wpN q8 #Ӄ҉F5Č\ d}@#"j@ *!7ORB R!UsJb?zp)ݗz=-h][%lcAiSwKѿqej gIVLpH@SS#PccBLEj_o§`oFg~!-:BF? vg`7`2#K֮^JA5@̰ U6w{0:7 yyy+V@KͭƦ\N gI0ƸD&@^xsDFFvgl߾=::l gѢE k֬~:.G(**jhh@l,"dFDD+ܱcdh$,N q256^ŭ1rY?+]ͽ=$}K^^^࿟|x{e]?Fmvq8Zti7>.>}||=z)aª;-g}y!P^OYv o {R<ڲe JsժU~)Z(¬Y@5Z-9 55ĉԚmduuuk׮W@@ ̭["ի?d (;wDʙ3g?~,ր@&Afmmu Mӭ*k\q1*9 C]BLNJBxP3SSQe{9B1;#?rp٬pÚUICa4+U 1:D tTDT!WҦ2/-;N8 Lju.9KaСCL8F 7,,%n=Q#G`P?}tvv6|0p?? $8NKNNF38|0ϟ(AL͛G << 3''2* a GL>db&KFNȢGI]P1*Z흔$$\3 h2#P  !AF8; /y<\.EX'70w;5 ;ЁMA|%ߐk$=cqggrag\%+L˄&2%2BR $ܰPȞ=H-\e='f޺[&q,VR;bQi7'6Iz1iEakllEW<>}Y.G F$0!:R{FRz-rNQU2zz29~@;v|Aд011"銋 bzh{W;;>OӤ9ЅD"0#n2e/ 9 tc*Po=5A ☜3)S"^Tp`FD4L*K' X6ǘ 刖痕3gΠSSS{!~?nLԌލ-` _&D c ԿsJ1huЉQ):ԜR nAvhMRi+u@] c's/4a%nA;.iqqq` aƜaxʁ,SS__AGOˊ␏&;Pw` "4,ܠs gCDEEx?AtE& d.A_vm8Aڂ#\c`2ܶP/b9T2[AC8~8]XXwA*M@FFxb֭#!cAλ aV{v fm)~b39D )t`uRLMMuk¡n[x(eU`VIsLL &$eh4\̙3_<. *TcZs\jnb07-e2 &ƑH\E755! >LLR R*r^ޓi%^CUpdDTYU*O/ÇTWƮXvHw5kJJKϝ;!g9r$..Pt9sPXܸq_c@@:CCQJϣyip0: NG^}&hL*~rc`Jld_HBf$}JG:%@szx;Ф=\ Q.^}kIIɓO~W g?|?zCr_mmm=Xhh:jO M_xu֥ 61FQˌaKI/06Ɔ6qL%R2 6lK/-ZpUywSRR*++)MaaeΟ?A#֮][TT?S^?~MFSS<_Ӷ}ԯI%(LiHbD f`MM _găxFpaaa/^dˆBJ(z7,jv Y8=Y{p|vs#P& R5) QK/!?RF ws#G~~~ٳ3>iKCŠKJKJȯNޓO҅ٵ랧-_>!酉أ}`lJM1AVýžh6PΟ;.YxQQ~~FݱlvVvUeU\l 2Tϟ?7mZTrs};أ2:!:1YϢOyOCz,|9))766v޽g^d`FItMeߎ魷Ze7^#F0RM輍qc}ۛh%Y'㧬' /zFJ@<W%}9DL P^Rxd>)jWUw*# n gI0& !D`A#Yw maZQQ>++k߾}))رdɒ󣣣9&bŊ/?ML2ATDA>dbe\t vVHqXr%B[) _zLJg-ȑÇh}&={fJ|&88w>#)˗~k,5Qz<訨.Ɨc&Hc+K2LXKfE B@&TvN=Z|||Lt .s+ YY7:jիW}ݻwWZ W]Uqǚ5C)SFp6Bhłt9 w+ғ^:j3FsH1^ FAzKib.+ :L(;ӯB5|NZ0Z(?aetgΜ!%P|;Q:0c'eX8|'jjjPLQ&lقxL$U6r 0VKB63a? <=~1|j*&=E{~'<+X"c } ;Ջ7v0Xl(z|AN鰒mTKTĴ;s}\p1>4$$T."ٛ [s=0驈G{! z! uB[K9FQƤim%Q+%C!R/LI0&Tj1t(x2h|M0 @&ͭBٸq#2!!!Z1>|ĉ ,ADv@fx$t(&ᐄ]& >߁ StȜ7oT&f ?Oinx]ÐPe+ -x #7o? ú1X? |M *eQQ jbqℎW9 Lr`NI0h̓ s9z [ZZj4@ Yà(@F `^<y ^APþ;Gn1aA{X `Μ9d>1111QQQt % ;wx ( Kn)sH#$O#/W`Y]/}䑇1I}󚞂ojB>=&j01憐 &V/Az"~DⅬ 8 `D@ BAAAnkvB1x2175x8e$C{{K pp"""FY&\IeLqݢe`.m@8%tttR-%0 RBYWW0Gs%#\0&b{KͲȺ(dY^}3sb\=@2[\A!Es&܁ tqer{ĵ:x5a3AwIJǬ{qbێ897qp?Pc1%71$4na~,zG3o1"?v:AsqBqF5:f̄T%#ʤ@Js)v%vl!["h4܌\E޸qcڴi^pNGg~%@ꠑ3.m7XCecm PAM*&Lgi'@L(d@ 0pҹ!JOhZ̭1n D|J`pªU=-1҅HP444\͛n1cƌ3ncr i9:pToq["AdEECP*k'hko @*))41MYD`BK~nIWaqgJ ! w`=new`F'`'E4UywG1#Gx 3IMM $1ouY=|9#y gsT Nap= nh<4/Jciii|x…_S1+*|yҥ{]l>l K]8 :1$bȑHV@KĢa^u%TP øj{+9[Vޣ>9,LЎP}}WޥǿF#f^/***.>G׺ ]Xm]]YYٴifed.7p> pMO \!~C:#HЎhUt_"aSJcؑq1 9[{.\T(ov"\+~4 Ѩ uT5k֠ↅeϜ9cHVSSngQSd]1AyIBDu"4e'^/.%FQG}p 1 w^B!^MU*'-_QQQ{v{į ~p9888*++/]Ԅyڊ+QVWWMOOooo?yd]]]```ff˗ m-Gk\\\EEd 1<}4įiiimmmN,((()) %')))ӦM|P^JGA~ru&́.4Mmmdv=VNi L)u}!ŋ!͛ f}輼< 6R05k\~c`-**jhh@l8q2#""D;v7EO2j @A_3fךּ` 7 }sKWNc0}޾eRjժO?'>>~֬YZ=6[.4`Nm6Nduuuk׮WiP(uV$[z'|B2!@Pv܉3g<~8dg"d֮[2AnJJJj{0i4&1Q߄poXֈ#G`P?}tvv6|0ӧedd=z~:TPP0o<HА`&LQ&H dj40̠ R.ɘ=dO?W3GTu@1cHoXCY1cis koo9s&.!2LVyDȜ6mB&D9ĽH&~%iii2IfBBd}$=lهVFL$ĭ-}-98888D` %u%-D c+)҅ R&x-eF0(PQɋ!bBVU0v C?pppppL4K̓ҽYuaؤ "2 G!k׮E1fge?~\o099w\+2&[pNrJ~~===sNΜ7 >~eLRK[fRRmձйmcN44-eeׯ)))ijjǀE+ 1Đ9TPPH dE{ZWWى˥~ܮqM[bkVa\|ۮ]gMHL1}Wp9s~_gff߰~ܹsDQ~E BCss@HZz}|ʊo'|͌Y#r{1_b,HثeǮ3b0vcCj[PT=(*\pAӁ8x<hCxI9gB=3BrU]\\LVO>ҥKgϞ}!|OۼqzG^x]. z*xŋ?P٬jϞ=wIБ`rVKp!S"7S ;,-:~ķrg6'Nֆ^/*߰ w9}|<<{%C<̵kפa^g짌}Q1kf쟌U1C2cگXN㲁Btަj/(شq_|qڵyyyoΜٳAA2 AU~[BሎDq ǎJpkB`aa!gS /$h.bO)HUSbR%C$$"L$͜9H0CG0Di͇!aDz _ǎ99iHV\l_3g6FVG >^^ޝlGAF#מzG:„#N1g ?b;-AZ fL#ЋNf삋9gѠT(ZZZQדPE{{W Z\}}"++{z+V h<3.\TSWW]UUI8880.6sUfk *NuҥL~o۶ {hcܹz=`}P۷Q~]`೪ TC4I mܒaJJflok{8~bYYK|iVW_~uw^.LIN^zj@??A ;"""oΜ9sٵLq_?.^^dn'"u#TH3cà_=$Wj)`ZQxqGG 9`-[GZyꚚ0;֬~嗿c@÷n?ѝ=sppL`EL]v9WTd0&nVDJqbWzI_^HR"&**ᦃ?0q40Ð۩SEeů}˗0?.rE񌍍[8!!3g?D铊B\ ={>u?E?{}}}Tʭ[U6'alcX9c`KRq0&6\ҟqav]˛3{V端~PTTazk#E_EERrssu:݉'

& XKO5A4+Y^ OH% I 0-Z{RFhhcBmTȔ772dQWo! M~͔mq&q Qvo\]7ifdg FV.\Ǎ' {W\q%\}:1NW}^'ưG6lFLUThM^~g*IʥB׬ &~i$ˊ~C=w5c!VA5\'j`01RӦMM crJqȒ7 c3$.7D1P-DG,s{S>M^ƲSNfνXxA_G&ˆaC0`VH`^aUo|kťV|8eyȐ!GV[h# =!&UWdra.37Sj}YI8KSD rt8rgX9)"HS O뛋1lO|3d _$xl]V∋̄^Rp ㄔC$v̲z=ƛ3gEr]"lckر*-&brkH1#c9'Bl4dJ9ل@SE 2ƍ#\?hj&x {mTvq!KA'DxHE9T]Lڬe<չZߌt$M%̱RUGS$:?cƌzI2$01k֬+4rƏ?y0=.\P0Ć ?XzkM -r)ImCABVӦM]@h9jԨ &DYOLx{:F.v !"2|3g<ӯ΄&"11a sb13>d"Q>鬁m.[LI(A<Ũj8$^G! cϔzG80i@|ZtiAVjUb5fc:"8EBe"^0mmڴ;U"IL{Ii$YiT=܊IT#G~O]U; Z6x.$YFT9ⱏY}|=fd  F 1oeÇ C¼De]rcxgyWǧVLem /]^B 4*{X<}\!Hr" g :mפm>]f$#ݺuCYMٺ}[{t2m%K&Ke=PJZYlN1 ň=PqKx}8G=TIBe{H~đVP0'TlmP,Zy>ŶR| χ!/ R ډj*_~eld H'::_۴i#GiK'k4p(y1F4hAl- %BiRFcC)8b~7.LE NLWizhĈ#rq)BT1^)B8C]vΔo*Gvu5Ech )IX2 8EN!H!d 7r"|ɒ%슣xpZl$F.q*BS yG9#z:BoNO>M na'׌ɓ':Tذǧ0YXĨnX[j/^sHӦMN@f))2U"PϞ= (RaI%+u>{%;9s^AnA01hO11&UD.7ŌDpi8$M^_3$ůidx\Q#\1zLRc#7#14]>,[aJZ@$AȇI-=lЂSZ딐#0)@hZZ"ĎEI`,w a3mڴ:@e'ƽ!01$^Ĭ[*9rH+xbR0a'D#2ܘ @Vc=uI@*n &NXdW +47s%1?qMYDx|޹ցB RyVd|=|-sUrTZp62sH6 E ]a5hUNP"NtkMmv}cWqkG=(@%f„ Y|{[حI 0ݻwUY3swO>h N(7n:1-MCU/S,Bɡ,qTѻQK8s9ϟO ȭHNDȁ"eRQ1  sIvuIZAgvb_+,jjHn\A<7cT60TD&+ErE|<lƨIPÒ'70]C!^g%ݭXOQ1Ql]bhK S4ZFF͂ Jc`ʔ)UUEUUUvVSTre?xbt…L;Ҍ.z]Ͻ|;Vk}3Cc؅DX M[5лpZ5vr^sn("&~LxH,ycN.ʀ ?=z}Lvѿ@}ѢE1T,,G@V*x#S/xZxƆ`E"I&)E4*;PT XEеkW̙31L*ol+HguP %3f 'R'5Pe\,G <,]KJ']vsc|b"ܳ=#c|cj}I(Ο??WFbDHɭ' eiD` ; ĮsFm| -V12P& vk[V֬mSIofLS\qǾkz+ԱXzd$mGϞ=P J #c7Oߺuk q~޽^,.H*f4 Q"!fdۆ .l! +y7u}Lsà oKXv2Mķ' / pɍvULAJbW;C1 ]E[nd 0; Ԟ:I:3gR!^cL>h}$nu8Ix "0:{ϛ7/FFJ45KcƁQzae.l<@rqf@^&Mmx8q"чL[yY`,) a(Y’oIw Ks$FLle1Hg͚vڅs_r{(X"m۶U6̕ oy"^$Tx(#Iʛk,28\UBLV">J%3"a`iYʨXժDV{ >!ŔgrW"gBKI(fz14ư߽saJDŽ3߱ rq:*&ٳgs,TBҵkXp>Yv߸`H=[ًc"Ē&NzA5c:D; lX .^$:ozN.:wRQl(>M6^ZYA0;\[}-gtPnҪ/*+ Gj>^}U *Z z{WxEiR,n(Wz6R Yjn5ھ}{|bIl/=IE~T4j\63tб{[5LI" AHYI 0ؘmKR"xڴxZ3m6sLqd.\F"ŋeܴiӠDFRf8p`EN^UhT27S$!O8b:}OSLeQD|VLI a%$a$$i(ֶZ[[WkvWmjQ@6! $a 'yߜ<0“sss`t-ʸFn/Mp[[la ɤ'/B>}(<;wﱂU&OpE+BBf̳-r܅=dffJpUuVt<;;[EJ%_!UF p̟J5QNs-[лF)M ӂ|H+6n(w ĺQbTWK~S(A@Y(&Gy/Bq,L?3bE!@`QСCӕ CJB `9tĪ :5j\>.&&CZī5ԀgFDD@,22zU#UqB9_p}S*s]kbO W8; fb˥K*_TAe&!`Fq 穖N6 `nʟ` `?pbL{̠k {(I]}nj#ecfբPF1_~ $&КO(Ija*Օ^bG999(A ͧ€W!-eWlʹ߿Ƥ * R,YL%2t 7ZYl%][:b9($\8رchzWZt)I>J"/#(رc1x!A`] ;wtfiC z[)F7NϞ=9Y/IRzllŖz%<@o-I(ES2dv'P t z1@ e i({0`b **ç\&5RIGii)(۽{w B48p!f9 Z3~pr'TFAe(ݡr`hRd-@ʃZ FzLJS QNp´AkJ V8ZӥXעML+8((@̈ bZhiY1? Ue޽{\ r*C8FyH`,k`()BAȱ% SV;'|Ҿ=gyb :YX\vђhBq F@ Urh"}k#LCwY`B+s Da k&{ ƾ i4]ExxBI_'A9?(c5;§ȁk٧Rqyv/)m) B}RT>9A-W zzYad(X$-=i( cʂIz%;ݛ2b`3oܸq+0%b1ԗ eZSL`d2ڌn޼yard8.J*rPİE.,V#0,YݡԆxѬN4FޯBܠӹk$-ui\|R ;e~!#*8Jˎǣ݊4 !j z}3LÑ"uS4N&u@\,ځ%_r ɟư|~)&i7XJ&%%)@WٰSA)CƼ©R-+(l[(PM\<#---44TUSQ^CͲKH NA5ۊ _Z'u#G<-XJse@!C` *a@Prm~ Ç_~yq㋒B D[59J1(@8A C'KU S-?ѣ>sK lez1h g7o $C)9@ĉVGݻw?r֌0ڻwo-t~Aտnp6 jU.R}NSE niy,'8֢ahA|N%DӧI48ʆ^E*(_24zjqU~ ݐ0ѽW47r_g}3daax.5etVq&͛945u;~. m8JxcǏ+Sarg=i 3 ~2G1ZϠ-zi&JH(|20fC(Mx0)VI# ^l(*0nS&@Y(qF̥ Mrss1Vj](|)111@b,ʧ*O'Pb c&b%%5vFay 8wzuE1PPM95\wN2ӿկT~ 2wO?ٷs0+cݨߵ 8H$/_>|p`F"|,` 婪=h( N QZ @`*p_1)j*JEa\IaIɮz i!Z@%qZ>@C ҅ 5MuBlI0X$8+ұX3` @8j!Ç5d+Pkb!;wV\NebzA%F*TNljk׮ s0*7k׮)a]К(?k֬>40"Pr(-05~bf)FZZ\Mp\+YO_p>\vw;vvݽT-ÍX' aQZk xSE*dȀ(hѣG>H` TV#˭@֭[|駀(Y@0 FS/9\@\OWEJԅЯbZ (((e#0 xp^E%W0eӫ,~)rQ8/QUZ}sΣgEٯ_NҺUf\#Gp>2f5A݊l"C;wU?L K!m:w6N&!IeҀ)S@~޽0 O }e^sIHH{͹2G!Zre||srGXB1U`b-VG0 y$V`( i:*ً᠃K0%<#lXj*x;]&ä6<bNpT!cB\h<55U~`JJ EގVa=&6[:b^Q}08@^&6l}!Q(@w{h C4~z wtJKsٖ? =rR`] ,@m0(!S c2@Yz5}F-[KWw_$B?1pE2ڵk'l'N.#FpRɡ=e9CRR_<.+I}ǽRyqm[j)J;յ[%Z'-QKFpҵ2'݁4E4aȴ)?J )'Q^XKDAƍ.inڴ Z¼E@|-!t(t6VLO.G.EȀ.ӸBhS 1p@hU`r/MJJRLLMəal洆J, _W1H#W E1:Rcz)E1g&6h +ĽW% BJԷwaFzuHlTOjsQ?O'R`('8 h!`,GP *^)z@Y>4ҔZIhJ+$]НZR(!P_rss偨DZL;*j1M9 (ѥ>Wj,0{>܂Ni322PX+'٩]d'x<%ـ9#(P?$lذ@bbH@\ {+ BYz6Xk 8$M,_8ǰ X%MθњpsԨQ[nMLLd86C)}Fj-8xpmp4W^^DǷqޟ̞6p7**% !!!ʝzmVeW0@LV*СC_pN1*H@ٳ' A)EֲenJx ̹ h`*$%y)ڷ}P9! R8ԇ fp$Y]DM&ͩ vzzWQLJ¸ Т @}6ȢEI9s\li&%4y`Hy,DJXBAљIt 2shC(b&0)t h/B۷lO W0>U \Xxa&NjR Mik^gS&aŊJZI5N&ۀ ~{6m$fZ >r(3-:*4Sg}̴<ŋS9 屭ܞr*̥U(xpmᨒth^+хC\E =&:A=qJ >,&{ ?#664vSUJtpUҚ8~9/ZH1.iU)S tRxXFF2r3+AX\b:%t|r5#EOV.TR-֠a[Uy J/C'曚 DBLȃ+Б0+ekmq0sD? XfE٭@)>4` vzSȕTQl˯1;e2K{iIXʖ։(>7DSUlP :+.^Z*Bu3^`(XLʟq)?)6в[FZD+-a]vAП@``%@5e˖#G.Y"dЂ ~H!fqQRE!5| j[x}zjR\QЗBX~ڵA#ZbgR)+u)::Zɺubgŋ;oo(T-;Nh@ @ _RLu.\7k֬S#Щea:a3:j0.v*M,gԨQ؊RZ2 Y_ylNy(ޣ$%%iUة G_LJג ,¤P=+BI櫯ʙeDz=cccPm cLL4,-;;b >+3*g{2|CJl'/EDp#pmڔ]eys jJm*]N0XkVh cyܘgA>6f ޘ_Ӱc@7(Zcoqu0Kc^11Ř)2f1#ܫ-K\)oLBSF 9rXf4XBfBRqc1vjLI }PDZ2HѾ$֚08JZAEi@Lӻ@sԁJMH{p 5D@ME`` 8 &G8 Lҝ0Q@1( QF9 Y5cVDꈈ؉m7@Ŵޒ͇ҙb O  ȇ}R RŸp4M ҤXhE_JUMwEC!AzVOZT* *v14ק1 .acaǎF9qY0i߾;vۯY3 g΄qy/*nڵAۻOdP /K[`A2b%͘Ci9$r,O<;pZĿ/+.*(ȑ#q.p?3Za=< @y*1G9b;_3oYɸ77o裏/a DhڴivbkHdŪ~͛5N&hJJPi ,Z qYk%xzϯ$Ԡ#xc=g+< I0Oq M@Q.>>Qy)&e%ͥA:`,G3 \NiV/*ǐ.PF+;qC,h 4ӠV@0q(, w q cAdQ e_؍kXN*b* 9JNAPfQXa+g3NhhVh-(Xr%\J$BJP~"天)8|_ޔ(]`ޚgmR^JV8)//;/[9bF Mu7㓙{7~ûΞM72/eN-׮Yଈ\N~49~~o AU#Fpi}駿~_{엿Ӗp!5H&aƸVBXoe!טƌ6NX↯rC=CO=yȾFfuZNڷ ؍8M;pMzn'o/>gH |cn P(qbOEoaF H8io,lyL l[DŽ;W٣˕wXvu9St_@d CtW*epP&߿?XlL0g~ fިH%mG(=zNd]v O L ez ˏ ]'$$(=Jjm;Ae%5vv*LxnK hJ9nZq&K]q4a:!mڴ ###?p@-|l]ЙQs P,NLaLLd+B_˵B2gl(FyR@>εXYN"gu ł B;Ka˩A2Jli8>+WLNNV/!|kر"LaQMBڴ?ocykVumG<_n('UgYY^Jww4-v5߻oώy݈2И笍YcL1݌,a/c5xYYH5/XĘw Ֆ %3?$i[2GU+EaYKye*NdO/K;r4 (}mfewZK\4TDỈH=QZP~l9Rl,j@]ΕMtڵu= ++o$66鋖`'JU2R@khVlGP/B;k:>w\,O& %ZKXOQ4k zW@R(A ,Y3B/2h2S(Ɉ^2n!~pBw(><͛7W^zѢUU*Nz6ɣ^}-O2ISݺߒEޕ2=zFxxzqhտo9jKݻfefPvLSWfۭLE(_c[l6IL>]f̘QQ׿1sLmL[z-OHkg1X7NGsc>|][ԩS%=i$oK+=p/{g;^<п̷?Z4R$L@>kBvv6hTΕ ӀAK@E*Oy񫠇 ȞLt! =mQ@?pVX5ҡJA]ɤ+5{0 eP` zk%r&aY {ZwJDIpѢE.$AaÆ͞=;**X9*bd1^(\~=)&%j0Ňp@CuFA)5M hj֬YP+za:$DsJb= vSNk1Lθ|9Q]hH;R ҫf#}*6g{rtt4/KOddHAg&O@kT̓?^ASNwIڬ.uī"WxvOJn4~>!W oy%*2ڦVUjjvEԶՑֶTHq ,\[[' `'vaȑ %X L5MpHk*o)f&*/p [ \AHOKL5d,Z2޽QW  hFA>`!f /### Ρ 党(!L =h)))3KD8̕{j*EWAC>%r ɸPrڵX*匈gb0-+ՈwLA۷'$$([Ŕ x)Gٳn: ˍ{* VJb !ځzr4*D ̥m0&p+}\EZ_:)U0pKbKh8p2x`pl0*oٲw O8@ x)Z]'&&WWk"g@ xC0O"Hf܂shFnݚ hQ;iC( 2sSX^85uz@P\ }9R|tPd40|}yQS̈PLa9%zCܧz5З+1J}ש82[l{9˗5ib=lL]PÇF< DRkvx{W'b-WsVIl-J8hS|H8I0H*w^rj %V /i ),OV T8J/`$(zJPIIItʟ@k Ja4TD }Q0e,pH 0XG=u#֪\0rژ1cRRR`zd,Ha(… iDY?pp/|x-{aZ+ƉFIԠAtFzz:D6(9p@4tnRIh+;4 0Jr03li0 &}Oi NwאFH||}'r㤢U )H`6 p E+kjq $`\(@IPvMLLp%p6%LVQb`FY'9 4JN`$h!O ʠ'iӦM JҩV۷QP GQљhM;JŽ&(z;(]8j04(3.v ;3FLMMN8Pb?(Y)(mZv,RF>j hDQKKK)]ك %g%%rS8/(**d3H1\^VoDoKrѰ5\iF^tULGQ gpG*^RR}F`>hqS tdЅB^ РbU7DtGTWvyǘ={ B/(aQ[?)eD0cG[۪uz7 A^kUws C MaJ^jKMӣf2A =0[k\Ap=#GT'y`_JBzbպ:3]v4\~y߾}dFP/44WJ` ]E\rJJkW (EdJe=2ĝJ9@Cz_repp00MK; 2DE=EXa < pT#z@SG:5СCs"@qJRFǏj* SSeW(78epxqja Nj)-b*+BB-藨 BBzסxyy7kV_@NV f5V wUhHEϚ8sGŐAi1P5Bl!LL~f06:$$\T*m~.X2W;+kȔyfF-رc-/Y 6l@=pFBB²e@DaHd49q… ]17-+"UY튮ccc)v SSpɁ 0FYSkʎp׏bhB :R8?-EP)I$(.wJ\դ4`K6FFsG MSY©Da-zPzQ&!Z EF[:bP[c-Z݊|%\;rsw}MCBScC!i@}LYI5VĖ,IO a[C%̹BFjj 3T@M HY=*bb^)#m@D 00]nq 7s$B z9Q >yM@GT28Ӡ)m"{QfJTCПfff2 z8pIKE4V0:D1}^4phƍzKASz56%h2dhArkAhS`^,Ex惓ȟũFtq>ƮD}?۷/ DV4Jl2tZBkիW/)[cz$a:;9wSS 4̤+Q)J1)̶+efM#|c)7N& *@8}t4\$@(4M@EMq&$$@JD2lٲe{VlR2nX C)/HN0Sih Ӽ8AP&B}K1TR 3 `6xL;w`3xϕAZlGMПJs̠5+hMJJOٳg(vСC  H )z+Juy5ʟ.]qیKQ7N8~zu嚊A8~,ϟ #G)Gh2޴4=11/ ~L)PvB8YaÆavѾ+坄5)2fjו],2H1mLc3Ϙ^+"* d+ 2SijcL{@++akqM}Y  o lَҒom5+Z7s r(0)FP*<<\;ox <`@P,$8wpK1\y''22"Ԣ;hZ3xELBPfȓcѢE4S@;ji-WMF P hr_r l[`6AJ&ʇSPُ4eb ɸ&Z)PRJʈqT+6隣uq:0)Fxa4y„^PBowЖy,BI ДX^V^PWTN酳L;XRޒܹۤys/6!m!C >=Hupwl]xϘp #i_$N_t'Ɇj4 n؋Z__̲ tڃY4f4U+Ye-<4cįj\ȝX܆g}8bHX)A Y D']B~ӻwo0)Y) ^C * `6.4eF ~yРҗiy >jhm-)6y9I ]J*M P &$$*s~(8':e?&ؓm:Bsb -gƁ!g }P6M͗x]JŚ3gFw W^+/;zE’\o*-uE}L4c#b٢^5MI~5栕ʜ%=ȳfһ/… 'xoO>_|Az?4E$]"Rj1o}5xGfΜ1bɒ%s /b];pо{J<9~13鷆uy`{y5N&`$Ƚ,3f̪UZ |i)9w\HShYRJBAk֬Qt0MA7N>GAg҂RP~ մ0).ZHS?-p(h"M 0|t򰣼Rzb2@ 5Nw.`"N@DD ,b%b%'- }fV(?0'I<34T iVgi3b4PZh~W댣CrJN:'CP+N326`̾JJKv{W?7*i2SGM#+娅Av9֟Jʴdԩ\6}ٴiz! ~+&,QI%bap< ׀ڮLDh @ K=)#w택A5~Q761zT]"UG(^->rZ%觤f3g;Q,5ELxxCP(իe'##*1zt M)ĔU\u=z֗bjq0bJtt4QFiJ[ &1-C2`3rpVrJ0W~-FtE#e6t(,jĉv 6h&Mw aa-[jW{MvA>u };-PNR*똲t/Zx]1Tܓ_ex&XGEN\tt49; ޿E@߾};~Q^aH(b)b2@z_/),,]֧~M^sDᆛ=fl`@a7ggO[[zImy\ѤJJ2amLT[>q^7J׽pXOJ?Z[W_>| L6k˅D޾m;Ϭ v0ugWXFL+'~c= ,"lT s!oX_\ecmT 뚿J 5^3sm)վb%{aTOe eULmrhh.e( _*訯 R,pWu\Zܚy??&ѭG^VӖ(*\{owҒ⚼:Zp4o&6[*ˋ7G˝NOTNb{yа!AM6Ry6h_T^Txz޽[C;}W>}d##+#v@Loo/9r:6oRВ^-TѤ d]0|pޔYeEqou+uz;jO[liҮ] n]!H~b -?>py3?:4g%ֈl~$lŖ iڴԩSݭ-`$?Cj$I,//8S^Xvm-'Z \Hl[lȄ֒IIņM׷:ؼy 7ߜo>r٢KjiYY١Cڵkqa}ew^ZZפI6{m۶-C:tԺukV)-N6m%YRXXHԩ>6S:wܼysvD0Łrs[[l[`ݵd"6)0֯k1 saIzVk&-(Η_~3TIƍZ}oW.3k֬~/K׮]'|%o:vqFJ~;?쳵2v ٷo_VV\쪠&TTTd*e6[l %#!r bOr,:S|+m'l-86 v;qĉzkfffTT+[o5|C&$$?~?%K$`l#Gւ rrrƌcǎLhj֭s1 瞃Cu^zĵk-;C97 @mԩS'@:ݻnZ~=sӧy睌nȐ!3f̨[lŖ︀qqYOB!\~«WٳM:u?ڬtċ۪UBD6mݿ?@>o+Q\\sI ` $(* `Cz衰[nŦb-T7ԒI==;ש]|LA~9A5wƍL>]USB8z.]Ph :`!l7i҄k׮;vB#L`޼ys laIn tN_1ȣ9Zf | P}>ĸam[l4xuKp}אǥXS"a.'N.)nݺiӦ8qbΜ9 X>1f„ ldeeƎ;y'xoꩧ}$gϾk@3f̠)Shd.`))) ,x7ow}3u zCBBV\ԯ_#FNfo~3k,6n;-b-եLB/!m+]/ҤI޽{kkxxK,)(…@wp (̠Ihp_hÇw~19s&.nwc|A׶osy饗.ܝ%00^;QGFb-40=K @_-!K@c-viOym[lədgΜqy\>sH]Cf@ÇVab-b-_.ؒYK&1˥%5[lŖz"׵U^Cr,|򆱼\H^FQJKKs}ٹ@m[L>{Lꪫ{BCCO:a3 [l[l6{l&a-b-Rm&a-b-R.5-bK}rg۳6eB}lqٚMːc6w⁁+WklŖM~זi|6?zLIQ˖-w|o}V͖sȇޟ{>:X|OBQ7upwf˅Y###Z[lŖ(_;tKϮ]:myuv>*S7Q/E.++{7Zmw@fѲum[v<򄧇Dž;RPPкu닭DȕXU>@X{z&~9J_í[GGGŀ_~_aF?z{7 f̘³>_ -?UvcfA^N<}Y)y&sN맴k[WuѲeKybӧO_IIIlr-}RСCO>AƏ?y9@>]_)mRnjӔ8ʜe|8Ln=\U8_]t۳gϚŖKgIb-UGsaa/K9>󬬬QFEFF>WY2ɓ'gggo޼yذaCVll;C]ܻwoǎ'L@IVZx1|kMII~??S뮣L\\Db7nܹs7lĴG֬(9]𪈥ce(w8UtĉWڦI8#_`ݻk'?I?Op׭[{رczfͰ:~ 2>GBcǮXbΝSN]tݻ(Wg#F^z#(ОM= K|+"S0 BgNW\O?toJlSx;/IlڸQV+\xUT-sq&\/[l 4uܡ-Z488q"D088?onm˖-M4ݙ r?_W(3M/ 3?u-!!!,,l̙oVi+/c^{}{~!Dd{a@ש<^% Y&t8|6L¹ ıO{w?تwQQQ`j{G/z:0 Sv뭷~'W_}/I) 3 $oaG|X˒3EENz(7ަ8Tp'KL)#rp)#WBfja[j-EE4UGiTE;pL[꧀债dxbAnnnff&6mW~CDi:$ک{UVz=pӧ <ڵ ƛ6mi& Я Sތ X0(tUWze8$8}UT={rzzz-_]_йd0Ϟ=Rc)M|i|ݺuuiղDQ=--kh+Ѣy!s7r'|£KFlگ7GDXɓ<ٸ뮻*\(O7<)E2.S%8Տ7.??Xv$!-kbh<gPҙ3g@q^Ԗ:Q#&9]9r'Wf¸g͚5a\v;v2bJ4SN<>ZM[^Vg"yf.5=h(Qf~?Ҿ}{6F=w\8Dvvv;K.l;*w3fW-Gfܿ'N`=P3<\2ӧOWӟ2nXp;An ?1Ӄz{2er-P c@M7tNoi :Do/l׬M'N=ᆔ%]w6C` M,9m4>B"SQsMyWArovX>p ƺxԾ: bv >UϥroW33?gn>.=-ZU3xi@1to߾-"A-Z:vx'kO]^Lbbb\o&-[6i$v2\DFFB`T|K^^YllWm&1 <蔧 WEDmŖ"d%Cm۶L3KZm._}Z(*ZR%S>?~?&XppPM7iucN\ة&M0bkU>}欅u+5~2ϻĵزiu}vQ]?K\/>Mːgw~1p+9|囙-F Y<sÆ ١C[ꍸ-WLwݐQS&AdEtQp&rqaU< o})ٽ{7uBƌCXea-:t|GkGqYIӮVUGPn-.xN;p̃n皲Χ6xɣZÃɪ[4>ɚc,8Yn/s'DEE۶m>~Μ9p?<11ڵ[\ҴIn]];a~i6i6m.ڷ}x&M{Gxyz?stM۶j)hݺ>,o^m޳gϳ>:m4 w&Q߯9L;! K@A@Q9ATwWWW?ԯ^~;C^߿{/~C #***eP*ĺv 9rdff&N q 'Ч89 eW 흜lXC\k~mo6R@[!mlBӪjWFjW)))G} &ңIP(nH1#8"g@ѣ@n`Lf㉉oCh,ƅA5Zd*JN1&/jVRoR$4M^ӡL&STTT||sҽ{sBo>2Vm!u5-~6 h 'BLԏ/)-qUN ]k AOss\Z~آjP u){IӛzIAs\=z[AAQQY٘PTbA%??_hPm"f4@^pj ;tpdhLI۷cy#Eڵ4AKvČp! " aAh117y%WxL29 ;vvk^)'Kį@  )-/--+ф  MM\U  žȈbRAA4Jݭs]HIA #1Ԑ  gOX,D^_TT@yyyUUUtttIm9ЂFw娨(B/>DZ81eeeHST憇T*7&&),,lz8RnVt:qolBP>aaanA H{"M)2,;;@R(F@"3;l;Y.;d `7j׮b"$$!w~[-M[U Z!p0b4EhrXVxmVk2GHh4?؄` tШ lGc Ǣ@dC"W,eGi(D"d% mvKs9")H ZjVp3:Dnuà͆;׆G<:S cɃc8A?Vcq\MD"nπڅ Bb u`0lRAAgKJcCBt\]?sP+C@tIAA\뤧3MRܹܹsON9ߣg`igպuv,aSh4ajkkJBOj5OpJq /B: %O;KK0E$.d'~5%CpHܡ&.J^"ҧK@JULU^e,[{{MުݻԷTAEEyn=u__!"zsg jg_|188'3gn@@xWWBr8NÉˣpb^h4[ F '/ڵk@EEfQYY( qJDp:$"%.$DZVDAAA PQ(R⑑&!8E ȹ.Pd3J{q g_"q(3qQ8i H[(^NPȹ]DJB u(xl@NKE 850Q"F"23FDD8d`R &2YD HH % J!(fU1TMbB˸O?4$$91cFJJءqko^fn^K'kDZMC 4Ԡ8@ (/MjMxsT$P$|>s۷oӧ/^ W~ܹHg ܺu ?\MIJNLQ58=N)>BDq0kpP(wd7U .5#BtJJJ18D:b7Izgnn. yÕ}!"qfb.-qcp9ׅF$RF#3''9lpC @5R"q@ 6/$pSD:4EE ap2 /Q""%GM*^Qjo`86R/]} B$s({%PD:HCpJ&lUL*UL**f_U 9 u׽H6nx}Q]kX{-2ih[} 4dҽQk/ZkVFJ;- J%&U|4&UM*ԤJU 'ٳg!l2NIX̖={r.]4f,7mT/eIO<N{h!x1! !.a BI| C9bJDJG$.A$.O(w8qƯ8 ED  D&G&q"NVd~ gKWb@Eڗ}R H;}:H\&Qb}}s()%36T&"@Cf_*f&V1b@BX;R>wcǎp1RkwzڝZ{tkϤdR񶘵#qO[{C J ̡6(}P5(Ki%p JM+w駟d}Kg͚վ}%Kˈt9[`tpJ</r/!c)T"b8C|ZH|y-J\ ߛ'tD:}&X҆C% H 4/o%H6TM7,gҩI$''l߾_~ݺu[bŷ=jJ+v5(tAIT1QCIટx _g1Ubˆ޽;׿BRm7nWH:D)8^H[F+qґ"[&TqdׂmK%zERs94,1Wz_)W F  u㷰 >2""CJJ|\|Fƹ M ͉(("%AA/b>=wk$ pYfRAAZ2a )  \% uTjRAAmUqVj"bnp^h4үZƯ*(M//3ĤL  <D~~5kF'f̘] /K.nJ`?jΙ3'%%ѣ &gff#GJAC4ٳgJѣGvӧO#>--SN?Ǐb΃.ZԩSevi1$ 5ذab+**Hii)R:tG  7y|XӦM[n}'&֭.((HLL7nܔ)SVZչs޽{WUUA|$$$`, b\YY)<|X)r۷xwqGff#GHIADkRvG_|%aX222JKKşsZfXyT.]b@x֬Yv/^CzX ҁ5&&&>>^$ . L4 |9Aq.wa4[k,QYYY  bD ???** 7xCH1bĈ~ 7fggC7kNVYY[o!0|)Mn )-[M0kjjH[ˁ  Wtҙ3gv*TTV(~Xi@DaMDG{~~~f͂tC'{1*9rHDCXbe8*11w BS w * \.^d*bSXXoUpb' ubSJh?AA&$$$2"2,AAFPL$ p}RUjHAK(_OJ  Q)i-P  \V' E8AAD#  uHIA"'N$%AA+Hx'$ h6V?2J"==d2y"[AA02,%%a +R^QW/ț$vޝ$$ ױX,>|ÒݍSYUYYUU뚭$fs||8AA>jͅhQZc2iAA&888***8AAF!W 0dݦ/IIA {  d2Y>IIA"*JAKd2RAA\  $<$jjjh:m(ϵjZz}s]!"`5qD |Weee{Aur{al4hPhhhSv:~RIصkצ\YY oI4FqH|ߡw.]JJJܹS&A23ϫ~C/6QI\p!555**y$9?P,kk:u51޽{;ĵH~~S⍆}fffzBI=q/iUqusQ*!999MLnNW ':Wv4Whn(??%233nbٱ{ѪZrd2#\RR"=P(f`{~j0ˊrF+^rlbЮU[8M&'eYyYAQLKnfTǏ/V"i,V`m=I&ϝlF<h4\gW>?hf2*N- f>bꔛ?|m^MVkQQ{GGXqM%qfݑ}ԛ?[v𐡰U.h$Jʋ_xYÐɃwsfk>%#xw&$l^70乺 JVcYn]vsKg. 9`@ogh6UT=sOUUv)=3511ӠA]]ğz~:uP(?9/[rFvfqERV~K,q㵴0:WkLLLb`mp˗/WHa00{C:݅U;=Yf>8mv%xltY3g$ppa ѐyb1gr|䐑k]ۢJ9r$?7!CrrrxTߑZ/~뭷ϟ_#M?o<\5L^n=b>w\~`2M5]?|by" <) Dž8"zz;w-l5V;SO=իW/}wO<ĀPWsss,YT*_y$,sٲeNZlqiI&4M/0 I I=z4""B'Ѽ k*:3KwZ3f mڴi?]nݥKp:b)>++k֭ ,p}n޼y 1]A@tAdlcb4?b1~u9cxSJx8]y6 5U)0sL.\oD;O>ƍpƏ/>=-0qN,=9SsgYEEEpᩩ7|ڵk.'LbŊYf{ィofII?__߿ioc `Y "C^hu\>dlZZڞ={{94o腠M{;k-*ƩS@K.`aa!Eꫯ>ǎȀA%ܶm[rr9sAZ G,\}Ν;JJªd\ e?R^^O͚{(:rȦM^|ŏ?u0Qogͳ-9y\I$WàA`r;v쀷x;#^ڭ;[Ϟ=;eʔ;n߾ܹsv={3<0zk]ty⨲+ϣ-ԩlŧ2%c1{lBgl#c27C>}zذa,j~L.W (T4(&Lǎ;i$h osOfff yfTt7nOVVV||S6z{yK裏OPA(Ji+:K,Af9s&4\PbxpB|3fG(we!|YVg_t2!rD%WUU[K?2- A޽? Y ֬YڣGC>8qk=twQjzqx#Oj{naV b8*c5 #ȡ{1og尵:@(++9 |^zA!~gG׿ Zjرcz-xɓ'Az-ZT?}Toe*\!gYt!2,8(-p-Ԑ8_uQ6Me2Uя?  {e! 0j(]=ap#GğpH=18{bgiӦqƹ1 Ƥ]%`,kv3𶸸riit233!ᢢ" 'zM_e-4-)-8qw}72N,5z0$pdzgF@{W+VH?cCnXsSRɔLc2M*;wxM-ynzС/Z;4~B׋uO̓hx6^ ~iP$\`A}:kW_S+3>m`dj:*"R^%2i{.EVK/{YYY{<_!((hՌ{j8F:uݻ>h f{ hsеGE:z@:tKXW"c1`IAaY+@/a…۷oG㦛n٣>aWA_wժU\iϽ 㴷1">>^V*}_mLkمkL5Nhh!"FsRcǎ=\Pu<~}׸a}g޳DY,uq3޲O~]@͏5 4WWW+ꈈvZ$|#|^-7 %f3x ou` P:)Z>y;k-SieqZ[B|msT =4H+e򄘨wMV۹&NUoMwn+ȗYdx =uwy-/g-i' б̬.Vaa'v/dLL'k6iJBRDwHd2J_ }I2ᣨTJrF q$|XJ,>Bhu|nN8Ȅ.fu+֌sRrssBkjjf3;M%!!# &b51 dFP? Yqa11- &EAٳsZI&$Q*JF_C+-+-*.VW&9'bll¼`R;hq ׁM^)+-ki%x9[Ζw f۲O hq+**päguuX<HċՐQ 6t F Eʺ`KUrr/$ƍoߎOMM3g16OK,k9[댳6,gKR{-al2~N${c'fd?-+++?PN:%CB5L.S}GEǘL|6|IDwqaW:u͛4hرca&L IJJ:{lmmXERVJ͵em+{rzQr~X6ж p jtyLl?AYje tfVs{v %qlٲ?\t:ԱcGNiFӥK8h4KӦMC-BZf $8o+w9e2c{CZZ7|[={6+V;v>@… Sv=z膶Ƽv9ee%pߞ};SXܔ)SPuq]hoRRR<(:((nxpgX1B]n&j3[<<&Zp/"$[ ̙'o ';`OE/ݪ28@+-o/MH\\ n022M69sǏ֮].Nu˖-̘1#Ha1DƏ?vcn|n#_1ם|)Ō_ cc,ܫecri|Ρ/[b y91aUUJܣoVSR$`03g_:t(j&sҥ:|װbQIP1PPGO/ysߠc"bMB7-0`֭[ӡĂ _d :_Wt|f1t9؝+1\tF4.%QRR]( Vq[$Ϛ5 m۶5WImYy&9 KAdffp p'O/a/̽馛֭['& 2oj?OJ?6ARynذ{MMMDžt ZgBIb9.&.3n| \- {6z~롧0 %8ɩ<ʸ}wO=ܹsѣ<# kѢEhÁVTT-E=FEf =-j(+h6yGIPpC"?Ã[d0dƟnBU б\vo=z1&nl+䬙?iʕb]h>Re˖DI[p+!_}Uy 8^;key£KZdk%=:X K ֯_ qKu̙3+ {皚8who-{A2v?NԽ)Pq!хڽ{7,72A GEr : !헃S7߄ǟ0xĉ:1)/v wڵpM6]x}gȘ%ZnUVyXUdpkҐcuw2aie#a1fyXYYiq8wbWWiX}>}H }*));v &-f̘!'^X(uSN8{Y4WW.//w^Y4v@4qM#Ag|ֺ%NtWnG> G Sa+#-돃Z-!rB h 6TMLx ojaƅ njөS'胣GFDD@%_Pp SSSQܨ侤$q ;۵X6۷oG[v:o޼wk0/膎=y/ҙ3g֭[ww\ҡ$$4F'w{bDmȐ!PݺuCC9Gvg9ua2 ]wx v؁? o[چ+`J֨P(Fs L ozrDX9r͒ꂒt@ק Ͼdvvv|&1r~5KV] ?@ !'|;í]%BX2!P^VRYQ&O,̟?_N8 #6lEi?J |t|vFh^U8=3`0HV*}Y)\rsBBjB)). u:RPJB/ 1bPGrܘ۶@nڍ] !׸i17xѿx ¿BJQzd X[:f;Ӝz!o3cm>\.׶ʠ~|}-[&wNڨ~VEF6- !grUs| ۹Wu7ڪAڃڜȩYrJRFMcǎ{)F 1éS~Ftq &V!0w6J>F&+霎 X,%%Y-000H7Ԑ p6 UiUqaf=Vhmd,]Ӈ7@]`|l|6$ kkլ-KFf%S}Fӯ_?[,s;55:NRygAcb5#4^ӧŲRmZݿ yEM~Y36:Sf*S^Jx2oOkJ$???,,LL"@{iAuudrx\SUU#00a1د[Uoa ˗njC%9:th]:wq#il1b wA9ӞSa|^o4q TEEêrZ_7H{&IVٯƉNVV_ߪV`ϟ֭z"~8::FuwB5;s]w[t}[nu={z~1IdVOmb,n֩ZC @ϟ/&5j}r&oYƤ<+q‡W3ZyoǶ9~C$hUJ/(|VD!,Ptׯ_7B -Zȍm e1`|5C|;ȕD1K;q _8cblb/&>>sfѢ5z685gzzŒ0]JBX s#6:;Jb۶mGq!gݷoXg.Y+wDysf Խw9rB[RRqF!CJKKw܉&鱸c4E8q7 LvUx".Gޱc W1gCÆa[oUz=O'jww]XX!]v*++߭Z RRS{{ ފ$>&y|jmiUqhhtUw1|T'ڿ?[6/w X]] Ljt뇾7AxNF~ `юK_ã8 PѓC}ѣqB5FQŇK.ٍbŊ˗Еk2r[5򬆱o߬,㏨ 8tРAlXx'|?~'|>p@ZRqχ>x ӧOjiM/Y"P B|{HrfSW=0Ɨ2]+5N۞^ɨ+@K+nC[K]CW_=KӜY[O&W%K,Bmݺ) g2eJPP_|iiiMph~._,fhۦOu aS_'v*BW\Hu6p?{/%f6bĈ;㩧z~iz5k!3f K/a>,d] SMJJ:sLbb"x%-.}P(kP=5 刕|:& 6hpƍi&&1hթF?!??^|X_ܮ];H lY\CLL .%ۏA:ԪQ.Յuֺ y`T҇RkqKnMKRT4N02ѣb:bOi4Bcǎ z뭨n1>m:>С?c?$_'g1C\YD0n~3D;A @VfQz0"ck2wyg ~atDqѓ@ĉ:ŋOVba eiOՔɘOvÆ Ǐ())IMMBdBBɓ'tx:ilzz:4ݻVU]JEGo|Ѝpn' R`ctpҹMO&qsE8a^( ]:t]@FOV`imruT.1c f6*M7ݔ& P4iҾ} 4uT%pa'AMZY+m FSϟ( |f-n;+~G+ȝO.ۭ[MZ^^.z,0W^yK.b]Ν΀.<$8wdײeˤ?E KPm*07CVge]drpBnwro>9l&g9ӦMWZO7sLt}~hm;W'Gw޼y߷gb{/G{'Š?'-8G7t1VpB-#޵ZE{٦6髯>ϟm&,XЬS%g?RYv իb8Yf'{L$'wNJJۘ$.& N[b~SI@ЅΝ:uZb~uHON6Q:Rh`Q9{i#^{S#G%r?qP<@B)Κ5KǍ'>rL0&44{ S .oo [.GnARM?J Gj/^؅S{:} F)xztpSQQQq$8ҥMJ^[T bm1b#Z9rR bu("{Y*H|KE`~eee(S|VٛBSWY֗gSê7]x:W$;;<0]`A~n)Țg12=߾qmG+WZg!%9r42qPIqQttCZ?ffbQI-|!a;Ž<7N0 vF gW7hРCDaaa /(6+JJJ-ڪNMdFR6=B_gȐ!ǏoӖ7w0hh}QYYg'uUwCwv.׹t)k؈_piSJ Ț΅ ׯs5fx^wΝY j6iY^5`{q(??zz;_5blSJhbMsϮxɓm#~BCMFcn^3o5jOhX,wJ?{fӳ+JiioA;yakOLKu%%%ݣZɓ-j_|qqqmJIT˪ϨzM2k11׆999>vbaNbF.?PT^>6)#`(٭g|0@u oe+TM\Qoi!654SM}ݻmcmR-yy>$[/1w4IJ,IJh4ݻ799tcϞ|Ƨ_|_خ]||yK6qѬ;RJrony ӭ[+,~mk~x"XW w`{^k1{,/p֢$&N~V 39sh̘1~ܹs#g{N7y3]V7{_&.O $Cr\f S^Z@IJ@b /"&22R]td2!,&sjHI/ca =/=8hʕmA+V4ofСG}i*EQiqeUdW-2S2`pA qtc/77СC#xv0\(|DɸqR>~J80_/W4s+++h4D9w͝N( \ 鄪sgdd@{=[d}UVAgL6 OnSe'TX};رcAv[tt\ ԨQMgϞmHIdlpqշ[!" :rH\Ά &Mm۶AAz\{aa!KMu~;Wk5jVMQfK:+-Mt'.ux4PsK0s=|Aǎ-_xˋCz5kL>] z kBffƶŶMM0Kii'0KS+//um6BZTgTo&88zenfn}H7cU6jr \0_ ׺ sLP1к}7nn>?O#̞=a*농xFƹnx:111p⒃43p ,ك213`T(ljSVk2u]QRfꪪ];rKeee֭Fjc\~}C;WtAAA2k׮E Ϙ1ZPP=aPn' =5ǂ$ C~歷zW]8!,ĩɹyօJKoUn@tQg߿tR]ս{>|cǎyyy2|*'<˟]v;wsn&ܝg?~|ĉgddбH/^?m t#"p902yرc_~%,X;K~ nq}ux,a6Ϝ>5)Uڀk/գnد;y~1L9200pʔ)[n5kVA!2&~بm;0Mr\f2J$fsBxR^Rt];moypҟqO&:w#qN:Ul422RZVW;::Z*% n֋_Ј߆$h:g1\]a#Fznf*衜V$ e)x(kƟՈ?=p&~H_NC/xK,ֱٌcǎRMFXBt{9ƻpg^׬{쏏ߋ/!l2=:RQQQғ.}Ġ`i .5a܄{vmٻ-(Dk4 Bh*ˇ ΕIbZu}٬;gtӄ,YZ,^Ohk(:~z˖O :-=6 @[~Fe4&} {P)˗/ԃwgM=z⽆ ˗> 8 BZ;<,u蜙}>po 0lL,TL~-3l2)&ll&tڠgο'щFH*Zm&IB TAgmپ5W_ 4znL43V`P§*O$/c˼' <~s3S)А6$,6Q3rU~Gj:44t]zs-4j?ǥ/*T*ccƌ\YYRS;l91K=t2vo炸* ]lh-lSJ"PC΅}NqsȈC;Ww9??8CBCC>Z}8QUU>77+"qݳK pѽK\GJ"222==CS !F^x111DEE"yb7$**RLn6"2 ѕ7s999q-bX"!Ox_I zL\9ol:t(((,5EC* ٳ' \]4-H#o7ZC {LLsAr *8  ZRAA4JRAA)  _rrr||<)  \AACJ  !%AA4[Ir^P(<  ZZSSJ@V={LOOwdAABڷoV7oib>ʪf+XNs" -VĵqAA4պyw/琒  dg]ڰkLJ  f"""HIAl eXXXDd)  \j6f+(OdqVV߽{wy% IFFFAaWV׭[7\JUxDtLl\s_PԻO3S-~JA^)$м:ͫ_ӏ}/αh25I1ADD.G*bf 99nu4+&_[AJPēpF`RRb4~?uW_EMq'\wݰ+k-S5  ҥo7l9=jkk5}?lr[70Lnj7u۶Ǐi?naMnpAD2MKۙ[VYS8yࠠO>['M?#t7ۧ7naU*UlLTLL o7liRQXMͽ\^^6}68qŋ,\ w~W&Nb2H  $VWPT\Rk08p`~? kQa.|bZǏ3͍6ɛݼ* H`Wn\-:9qq_w99nٜ!2*Y׮[!!~ؒ׾}{) mbmK 2ss.۷s箉IIAA80!1%bKh;m!5鼚յq+Y0|T6æMIAm>Jo7ƌ݆ y^{w=%Z۞0:ƍ;v~45'6OPpO&d2YTTY#9bk'e ߥkW_  &+7G HHLhgppȘ17tHmxISo|~a{wфT<I bm^jڋC4Md۵K`&Y9ǥqVs^zAAI5Vh0ZҢ۾NAGAg5xyuyuf+s駼dڼAњVʬh^T*UKNNovܙܣ hNoOA됒  uHIA:$ pRAA4>ʪjRAA4/::.,<AAWa*Ųa9sHIA h4Jgnڴ8  AVGԭ-a2:w+"~$222RRRZ0AA^$bf,ʆ7J"&&-A  Z1LkjTJZp|iAzF2"<:毽V5jV7Y/K^CAa @TK`NQU%9i[7^ΈVO1$&ћ\4fFjB*@^U鹤FyV/F8Zc =zuE`юXQK%ѹ0Ƅ'S Z N@g!DqW. H]u^'GQGF|hm%,DEV^Eɨghwի)ڨ)#iU ލ E :]S)e4\ >ѥ#B1JߦuWC`C&0Oh32SM.QTrQo=FT M(^4&C+iT襩"mdPWS4A"3k<@JK$Ԍ)52*V\.UU opnO./ z+*t:Z1)lha x 3D񄘔bnfQP‘}B&q{0tKFhTYLn&D(̤YalC@'^UByQ4ĚX":IKkE~SN$5<0fHBW(#-+ 0b#~ʨ@ŞwK+12P de"XB.cܼXuY1"S(&m"-1Q"2h`FAj6q Ąi"BZdY*1ڛ03T(HPό9l ْð-7"zB|e(K92^0Ju1g6- X`! _[48***Z=33cZ6#OόXru$B V၁$/PyOӊUtUlMRZu~ nsiS ͐Ь O+NF&r5©)x*ay7GѠV0:63WLa!G̾z -E)+G5gL`co{휓ދE)N^*%JCސ4rU2IixfE֨!͙Kyb 6ɂX6+W 5a2@$!g/"51Y!KIpe"()9*hrn%fPl'[bcP fHdj07=÷7yLDGhvF *o9bQ3mb7pmJ bCbMP#ԅM* lfTg$fDnܼ gEiiԽ eI  e]EZgd2ǘኒqA:lPאJ6EPokwMmdžJ+JyxhVtJF4[IG,ЫֆCP Nc8ٚ^zJl~8iZ*JFg--&QAD U\a. .M4kmd3ETUw\$15/-Y&+CSsqMp"(r[F&4z1Xe1Gd"gCDiÆEm_vmXEO}XViP;b.eCY0%O͘Gs-?6 W@eF H>qL2)HȜ7FVaM/h!lk!fsluLXhJfpS }}YWz o> xH/őڢf5MV5x>Zh1h3#!pcv>mVC EO'fxo1`&b[°(>+p-lp8n 7YO᭛%b($>BH$:37LC6w_K}A줔J(8uۡwx̵_DcgO,%my)SXI:'yBl<ɷ~Ҥ+^zdžjW ݝk$ֺ}@4IH%i|XLJsbq9& F]Q3IK}i o.'LRnodž<4bXH_ΈeX1f%"se5*LgH[ h]Ѣ cV@DPdk-"60ri2 Y3pBj֌H6Ν\ҙ̎[&QBTb ֖ &,AvF٘inb Vx&jü-uE,XlM''X! d#X5x@tbUV"}XJ6ti.)Uv*M-\`WS?KijbòWU%s<dmlAe"*\YdlM!]d,͔JZ7 ?JBff/sdv ǧƽ9~mo">7?@qQh|rBT F/tI&q.}7-o[5ٞD@a'W׵ҺD!B\ 33Uzy vz뭷?VE)?XïL{VSqڿ -h׏gSi9+8_ɦOUsEjdc2o1 w${%,pβMF鉹M (r!pYQ3,[y֢:v1B3dCLf䧓f#$'o-P\ٰÊ-(f7ץQQz0–"Lb"fqEDK [15 nlWCƎ's"c J jø$"VW/r'.4``MA`-"43,ԳinGZ[]n3vfE2:{o`{Xm1sdaTF K1w6JIg,/;03w\٫lOĒ,ښ"a`cc"ugĦ#iۙtgOW /nX 3.$[LB]t$Ͻ3jدMTV\琝NJJzMRN~rXr\qyK/yWXq:,{RD 'jHb@EW&@Tm8)LH)'V:]M#.%`rV3T<|2}z# t¢/2Q3u7! x^nNSCEPW>CP@巆+|SB8hxdm Yv0KĂ|h|[K4)Sp #t/bXA̖#h$6rSıd6VH|U5jfe0DƦbNur=Ơ1Cg6{& (0LJX}Y֋4 5wu' im7T.`IwB)f ф0AdlMA]c@,unp0"2r51b +a>I,S#fIa9B4H07(-Uy bDfPA.B026. CD2J"E;XB!4wuRi mϫ˜kX =^ВMխ=;*6T+Œrb ''L-.TQqkGh󹈞El>*b]\djb9˷ nXvfFLyd8NL#ÑgJFNjl2ewnDoOem#{SI&d8 W;D9sV1?:Y`9B8Z=FB,m!8lbBCrm5Y@:c!합FbJ,2A,h9ƒ4lѺamj Q Nb0<Ebga5Y˱cE G*Fړ1Wk5FV<[7$7XH`\wDtӹ~D7=A{!>`c\9.yz nżư*eKH.ɹy,;$ESNBuJ}x \e_8|hJ &R* ID۔*[E:֭P 8bH 05 Z:umƙG;1~Rfu3])EgL=!A1uy1[bn[NPKZ^Yxmy@tJR5cb.^Ɔ j>)ْG#x"29VEIk:|HŠ9E,TBɦ$&جĵġ6]+ {҉ښٍE&1xiR&qGx @,Zgv,1uEBU.C1bVωMO0ub6f.F ɡ3 +TcfykRK_5f"}ʞhBTa!9.{ :hQ;VInp Ly'B|288 >ALR{.^†eOD*K¨PV.*PF{ >Aڬ%3rdLΧ LF˅Jށه$jA/exԙOy#` `kjN^  +dEoF Nw@FB_SyuU͔`a|$Pa5[Lm(C垤+&af ´?Z& 2+⽇d+.aK Cf?&\M o,(|ʄ:5$<SrTigAr:Z`ZcL)Db{Z`YY޵tYѕ EӃ!"SLpn7+OYgZzH o3'WYXh"D ;36{V5.W @oRlZnWrM1[jnC=FzEd5}뫧"_#/q9 uU镚\'ձh\[̿X+`+0Xmq{J:h-DU_գ^dVS:sL5WBdiQ4uTodt,N詊mZɳ,d! Y‡y>Ʃq:ҐLє'Wƶtr3୩,ts cW]۰M׉N?޶rN9eYõ}5Լ[@t2M`)szǗ^gѧN]i;]7Դ_rJy͕pq3?ݲRsxhjnƻW4{Y~>3*CRO百檜.ݹrAƚ?2$>ضmϫQ.`חPi}%a,{+xh罇~q%ajαןQ‰"guc'IǙ*+t?JHߡ'zr;TU&rgIQZZ[̞O<)w`*+^z) eh$ƦJː|#}xT?_PQ>5^76}硍m,xJxC#Cjt?6ty`n 7)?р3%e]޷=ʂc#2 wdê$YB,PwI`m߶^ ZMZ}2h Zm- ~O+]NSIP2"$7.W>N[I,Wܮ>_).%CK^]~-x97Nyige7yzn"ϻ}ںlq>d~j[V[%07[%;m]vZX7_"_D$_kVd\Z֡i'yvv5. fv,dJ`v]YD|~S3"g ' ,i:2>V@A!-e\,~>CPG뱡Ps%[V7V^`_Cת9Lty\ֲˡ/(tl=xOA.B,|<zAnEUVzLW|Xgyr796=C,dcDR!fj*snZW9 j撹[ fgg}>\e" YB;©3 =|N[)կZXXz@Hi'+QbzpYt?zbr'B:BN=n9 Y,Lk綫j*D"@~* ݺukeeE*H6ͪ`# $! j@OoF0my<'2B?2Wrd! YB&ٝŊE)%YP jr5(l7;XjBw|eF&sgF], m+kWA=L͇cNY:rj$IyN3 5<enn. &xSg49UKsCqx.9W=66f0 x(QCY333SLhK]pqzz鍥D+ h5G&>wקem*k.$:s TjnF"}yX_?TTHmy iE'g‘xnT(7;#00TZIvrb&`` T0V@8fAPڎ< 8g">2 -L53|n@2KxE~Z4+W|82S< Ku<+/Qd! Y&Ǽ$I-@  c-`IOXf<@[fjǍzc1>C.O{bC}k*eH/KXv=Lb_gmCx#Hyn5&àA^əџ%COMM=(  .7N?ӟh9I%4dBe:vT!M588Lfn7ҥKħj߾}6mAhw} <+@;{ͷfFY.$8NE- {TxL,XtC{'zEjgKx38T6O_bPilb} ^_~`W`A/]EC{AsbB4nQ$xHGO_ϯ8pcY(]R;ҢHN Խm"'/FrKN FsgܶZ$ '''730g`0SR1K%f "QgQlt<O_J5gv xRRT}~h~I}|TΦss|ɓfSLlұx̹+p0$pbҼ*1XK@qmoMZx}XhYX86@{mE!~H Z \" ͻ恵[tF->*𤩫@U'W!BWDU9C̮|99Ӿ@WڦulvvLQe+**xP?TxSC@B0Gvٓ+/)P1oБa@q@7EGe,0_\8"k~l(x6:CKfё[K hxT@7WUUA]P8)@^\mƗ.\T \S'l4:pXF @h_|YY@h8*v} c!gXYB(޶ĽUzFyWhb nP?8Ň_-P"q"bwN]hL9W$vSvwm{6>_8ߠPAhCDpu37-O33ILVJ%$)B|Y Ay$ TB <64H^j WT3+Д'@@ քkˎ{d~a-Zxb"9HυնzEH9h@e}[璵{\V /K-}E}ssmŰΟ|1uu…SN@goڴ\̪(Bϩ5K+ N.k < jkcm4=;_p:hed_0ttʣ8m%.Jy1@~NYB"kc~ETe4v ^kcKG{OO>[[H.|vɊ9GQβtB|>GAщs "΂5-/Ԗ/H3QPm]XXd0Πn{{{-/--  ZDל z($|~MYϾ/L( Ɛo&ge+*WPN("77ghhnq'  }D*Rt]z`*]G_lܲ oOG+v<[.9z<ϏӖ|+W>sm_=ޱʄF,dcnIגF½ 2kDDxɚO/-I%Uwlc\rOwDƚ<ו}}V%"%M:CeuR;]qY8UF\V§ZĠVIMEY:k:q+,ZWQ?it*mJd:m&>LӅ9.[Y[RlѠwAP3;; 9+xNd^^tA߃67Qwp<]0O Yt\4"݇* =A4ə溩)3TŋnHScQRSq {g:: `*ھmf{wl?o9rϾ 讑hg9v&K%}lFi!Vo;wUz%xիBၮe 5:%^~{'q'V6Ti+ >&Jme\nt9Q@| CM oAB "8h*mEMyѿnƾOBBrƊq%,`;7>yWD|IME}=(噜P/x ض}8IÊp&O_cY>&>/+Si%./wD d%d jzq}M%Bmu'ނ  准֭[5+M 4D(&ЗJC`oax3v\4m:dʧ`3? f3M_B!:)CLa~~~ggI% I q Br|\8ͭ ɤ4J0b'ġZZZΞ_vo%:&?us}Kʰġ8GHTTA4dTIM36==hh >x]ZdttԖt9XV8s ||`lfݶ-?iۺ kZvV֊|5IkӞ__n7j]|x#5 FR4ry<P-)\MsIce! Yu!JrA_L m~4>ڥK=J~i5uȹ)PT:;vee>.7ҁݍe˖>}||FKB/_DZqRZƂ) ٺjiPݧ\ ;V/~PUU&<8r@{Y!]/fQBXgf;̩ qjj XW9I-TmsmZMNV[xѓ^}JKJ-|PȜe ꬩ]Zc Ott?U5]֣pذ}% l^-2xc[觍k"P̙׏Ĥ;ϭַVP/9>!XlE'wL?itt6Jp*7ދ{Z=N)8ppM+>B,ϯX| ,B{P>=97ʏ˽YBn oS/s,stG2T||oQomqvJ,c> _>kSWm&{si9u;ObsJ2:;>rKsC陻oҥKo;v8uTH'k~a=2 YG$&ϽyԚ[.\x:9TWNŤ`A@zWMWҀܲr;?*P74j|mˌqwѴIт`ayͱSwo+yxυف1[}O}ipw狚GǪsq^me5Fp#GZJ\pϸ*guv8LԙW:~3<-_5,؅VV*O|5+C>Jdܹ>WZو^\q[y#Ó =VVNVo)hPǥP̂GEk0*i}wOۧ0{dӊs޹S_)~d! YABM;>veA+"?q$O[jHM/hU(6srv6{lvZ݂e|R;)vܠAP.Զm˲D*atd"דTȭ(EUMU{SgMM_fk?Ri{ONxzz|7&F'sKJg[*4'_+ͭEϓ2<5)Jїuc΍ M;s=r)YBl,d&6PӦoש&jYr}oA+>QrwIQqUUp8] %I'R*w\=HCVaol><^9@$@cP9w}_] abJ=Jd֞|W$zos4u?7AEF<';KxՠF.H$n9 >3V 0l)P-MY.6xX5l~jŖ&G yۨj)R##LfcO6?ɋўj CgQX['/6Ŀ-M}ʿ[yzc}Wwܾ}=ŗg6sRt$|xxxEEE`W^}Tt&vx%őH4J,9H‘x*Xl\o/B!۫L,\@qr ӕ(!oN'ڻwoxy1oS[7ULnȽ7g 6N܍ySɱT3[&g )v^p U@82N:Ar *,&AḘuRIQ@Q\E%² f;OY|Ī٪.UZ{_}鹳;￸/ꋯm΃/'9Wq{:KHgVTHR)ھmSmk GӕA0qR㻍et6涑2BEDKcc\@RG9d-aRONMnR\b}~"H$d2 tC|T ~.b|) S@X Z:}hՈ~πIjP:!O+ަ-8/Z5p-] xKdmHrc4\Q'?lA grRZ6|ؠmNk?ol(rETuZ{T~H$d5/.6Nc*pDn3qxdm9(fu+TJS9czUhK݂Um'mY&О)$<ʀM5_ՍPGns".% ½H!4mLW}m]8z]^*ˮ(|;8V7]:ׯuzA]'N3o#'ʖrdvR[ouH~ݬ> LD>j,,d! 97 m"UTTH#ȕʩVpZrT\&;?CS`>\O"~iEY=Pw6?8~9|ڃ__eGtusW^s׿(l^ͽUӸB[u#|8oqvQZ-n2\xg׿zNkE"Nbۑ.4dUwaЭΝ;qy2ܳ?'[{Vo86կ<֏Uu'*ں^}GH212~Wo盻n!~gEU&z6HnhѺ&w~d~Is~|c\Yz@}~==7ē ko^<ݮ <߻1wEEI Q},=mݭeeeWmqQ\}⽚r{ܲ><+j`ٹm|O+f-;M/D&k o-b[y=EY~47?/ &.zƒ|*me62>0z|JV:9yS{:.TݻWlKv>QQ޽ !-[$ȩc+nf:<]%4 7nx -F_GjSe?x~cU"O?#n;_ߵĥ檆S!"9{wm)WcX0`']^@5brrZ􁎹ёmU՘vŋ:|ZQ[ӡǷj#4HS.,^'ѡq/gtleYBCR"K9޻sq+,ITb2!{lo(o./;/ƭc^PNlz#G-ZشGF?ᩎg{wd``~Y"G}Ƞ/x&N7yP.<77jժ^t,YznO@):Z_OԮM$}{yeUcgڶ:Oc s=yO]:jبbcs [o |s#N9rއh5QA,s>R!u9Tv-_rll _Nq4>5mwww}}}QQ~vvnVm[in+l(u_-7 U  Vh:^/ok+߽;11=[mcEuWΉ{5qIQo{g2sX~3g{oݳ[3^9nsħ?(,Φ?=?X͑puN[LC9%jϿCCC---7 'wtՊ3G=JyPwWS>2;[\g{g }w߱Yc:?ӷު+k*F;OHՏv\N1zsANMMhKRm-.r /{t ?!2ʣG@s%;}M+f͝ۦ}.+Ngg>:B@yOPXXcs727\H}'ߏ#x{ѿkJɛc @ܙ"W~apT411S״^M1h`q<~o-YjS,1 i1̖" %KI),ӨSӴBǧS3f[[9:{ӎ]ãdˈQNm?ׇmƦk Ep,ZCS8r&@'ZOO# poFȀa*&ţb 1L߸`y'$$h'6q_SJ!ዛLA+9#,1!anG:-\QE«Qz#SShuZ]ʖq8 )ōat 9a:֠k+H6 ;sGGpcu<v;n nTx3## kwWKܪV(E#RApOSmL4YɌ%3vֵlibXJfý^c9e![Y|7+?Vm54DڲIV n˦vl6\D)|$[ƈ),EV2  㓁7aScf ń^LJ &K Rtj9(؄AW&LZuWk/_,@I[TnZ@5yT!6n/ٴDtJrzlLp#<1;}lnxOt24 d_ +LT,.cc§MoHb'9C7%c9BD)/s̹cŋO.┷fr;ѹ͜Sۆnu &Oy)ʴM >ǎ39/|oP[[k"""ƀXZTRy~|l .<k@kuuuM&h#E^g~& \Da`[!Z3X->ӛJ&3ZݻI6M?qSA`v o߷ Մʹ3&1.닏RKDqa~Ʒ}/Όoa6w, ܹs@yQ0>/y!9xKٙFiY8>}299-79%x_@TTT~H~mu=csk]+y J'&#BI^LL =y}I)z?uw{_>&:&t]5ul]u jMO:w1`Hq9{ϖ-[f^(|VH11 KͅT` *3 Ф$D$hx#7&(--:;;ꞡ9xI3f6+**ZZZ233׭[Gq"9E 8O{ap;% njjJKK̝r*|Ͽ846-ֈfG LѡT9]G.Ykk<{.8sMFCуC %y8G>8zzzhg z"n9}uQ&{NzBa!؅ ?ӓ _>[7EjuC/Hk/&eоr?afRO&;Hu/#M$ ZNb!k9?{,+Wѳ.-;f'֜H)Y0iRBmѪdgZVLGJJvGFFp /..Kwz Ν;7,, H2Cg3gTUU%&&n޼GܓE#gR|t:8o6ne hXp=Ϟ= m`֬Y!#:t|=NKz"?v;tW~V㱋#zuy`VЁ7Bs!(7=0&sQ u4[^}y0x''پ .ZE}ˎwsFkWn޼uʼ_ܜ +5s]no$*?s5]œȡS.7ٓ!˼yqĢ5=^5eΏmEN lCzM 1FGc:/E3i aK(XIl׷z;ٝ[nln s=VST:2*[I[pB3ş?ؖOڷ6eG !7yY)܌Ai b(h!#M?͍u, |BoNyx ;;;mn ގ?SSS) 'oijvmmm)//8~n=4j%dT\ʌS6ZCt֊ W⊲~q4-M+3233;::222 Ha,Ós\&ETdp׏/۴-SsaL4 (ٹ鹕M;:v}-5kpoRs87#Rgv#MZ]ʹrm!M{_RXHfc wy[takUxHN#7[_k D+N;I]܁pm#|$h% r I{ esQůH11srrx L،R(;o~p<۞n61а~˖-Ck)̛3/sX_YV=i[r /r?~@;:`ǁh;UۿJ:cܙHz"{UAQЬkWg±#q3O~˗/CL,Y<*o:ѣ+ّ֬B*BK̴V+Nyt07'C2r&nAqi!  2|!ih5^?<7lя߂us#G=Wc Cns4+Xnw6 bhVRR sWƼ|8eYdCM!0=oBX)ŻO賴t zjf>!Ag_9$Fi%I2׹iT%Lmc%+J-|BB뜩-%5٬y7.DD'=FEbinn޼y쒠oRxS4q)JTHYTdRvޒ5-Zԧp_vzJfX#"Üe6KɋOt+czВܘF]!V)LD8M`rX%$3~v6OBn xa~[rC(ϙ30<DyRf"gsB|I~LA LII!]7p?ᄀIJB'aك[OҒaMܸOYj-}qK̹s{Ο /E.@P^A_vQ;nNjևX(CbsFX{=va׶U'04fC1FQvt쒼ݮUnW[pmya͒0H>.N$%ySa s7 ^vBhSzxL|7$uT|S~ȍk)L؛0 E0=m󳶡tfP9Kٌo{Ʒ Sg?f@s !0VxO~LOM𓶶6p+CuF]]nhQQQP+++O'U6;~TdYjphth՚󝥋/ '|yU[0jnm((J7Ƹj"Fۇ)1\69CѶW -fwG8,h8%v=t7;__xtat9 Yk Jyz)IA}uݱA!u!9cߚ[}AJTf.yRڭ>tvzhًE]ń)dU&dD8c`oذP7C~LmW ><Ӄ3qqqı`c{KDۄtwuu]zfddXrZy#ۂn!4ܡJ=͌o^8mOoT9566~˗/fS=j˚|YNK &Qĝi=#@ɠO6t疟ꉿT6saFW{zklJkWPa#ZCLR؛{g/7nQ2ϟv`7_ Rb=u)WN2<&Uxe.8`dݶw9. j[rBՄC2쭷 }y_z8;oB)Dٔra*|& ~kfhB"j _&eL&sÖߙ? *9̅7>11qɒ%ՁWFLA34CwRz?>HD]LDlwvlyҡ!)IlHаsʕ6cbbΜ9i {)x;[Qeׅ Hapj UsIJpz=N7Dt¨{|󲥱_HtX0Nn¥ɻ4gAAb>sD^.B^gilЩ1_2,)5{H-04ã Rx.Mvap[U!:Mqf˗_xEmݺU!U*J<&sJ%ytPUU%~&I4 e8UAr[Iְ})Rkv.,rB1($WWW,((Xx1w$|o~D& lL~)zݒ:ě䱾!Q PmZvI,&_&&;l0 ̈́@k`l=OEƘ^/"@m ^<۞WwY-3oƷͦԷMA݂l;%a n]<]F9D[nt,ĸ_;?O-'$$?TJD.ڈ|t* 3-{k¤)Z#>N>^ KkoTrd &)ʥ V23Ň2sMt-8gmqZvIiYtd1>_|yX&fx1G`,DCfM)r@J;Y WS,؂XBӅ.;-_ٳt1ޗNTl{Eci5c#Cοǭi Z{Jۆ5,9fˣǐk &(-A͂N5y,O)**8RSߍt3Ƀ%\П<%%eƷ=M ~יmOobEcŸ:ujɒ%zП&=Dc&o"ca!nZ'i/]X={Sǎۿƍ CTWW/X೾MݕR" QcB/edd6 -]wpP~S EV{T*|x޾^`JAM;hߞIˎK0ʫ}׭K mM h8ߜio3.Ѳ.}bC[c&~$69-ߦ%G_nv5Fsٔ=ZCҊ!|uilT~yX:^)+ =u}KVSH _yV6J ݐ(K~ '))l /S)'~נW O_y[gkﴨ?ϘͤZZj~/fLWFFFsK˗!h N4$NK:uJv/>=7_vk/!E ϒ)}Mۦ *~KDVPM5%:`!0Ow!Ά!a6!z\Dlϟ"Gn903m?-Gw3{mo}1 ^z5ڂ ڢ0~m,qM&-`4p.twW-GF*++z!A`햖BnygTWWaNd;3DO!:Z 5[%[IHJ$u26#,`y\!ԦC`ZݜBFNtσI(Gfp&GԒe$ R^~~B*2}#J@[ʀ n̾|/S>2 1Vsp sK?ShC /&"փ402'?i,-=að5d2@`j"iiiW^mkkKJJ7İaO#lѡKJ = jom.5*ca;oY.-5iWc33s F'u)|c,Kٔ9!?/2%ME(DWR\QK,(Pr{CLWl-l|/V5>fW_Q{zzh7aKF+1B[Q H-4۸~ƷMLXُi๩ 6KȌ:̓ YuV把 &-,U [_q[aH]6ĕjX,K<}i=uI}_>qcŒ%`T4?fgh V|Ǡ˓z`9Crs Wlk#zo*{jZFU5E>> Qn^Qr,K̐mj z`hZ޲G c B e'NiUR/F24b 0??ٳ|GѯkghI]ЙЦ뛛)g0Mt8)5$7j` a&x4@pPp I&f*))e,o,mkZb WD8ZXNaom ZG>s!""h4r\ifާ7~C+WAe.}q!BUw#3E] qQ&Y5ɪSW>3A#)CT&GWBM~v`.[ [?{7{bNi~₌ f`]]u_RiVTPlGF Z^$Bma!Ҡ~&bGLjfO`6-z+rJ,msfWiUl6Ts[N @C_h!jjj4'&k;2@J*oz` b -S A=yǝ?V~VQƙSa PHKKR4r sE9'q? hҠm際?|≚ ňDFFBP3&l9b3 $ ܴt.qBQZjyʰe*Suġy%"'s9L6*2-'5)kWYaY VKЂyTh,q [t3~zȊ;w&>}Y&#G-1,)QezV%*? '.|x54:+"퟿c45y9b uS|ȎM/ȻsEYǣ-33U%%%]zUR <2hdl톭"iG⫔1Gc~ެ&d$7 E^xLƞ4ap٫BtBq;=^VsJXBg$E}Uzni)xg_UҨv8QpqONlW2br<]_҆Ϯ9Zrf]c\q3'g CjQZ`#;[^6ϱMror2?zJ{}Hk9ȥZ7#23it*C" MDgyN_YM_HL|]9}7JY7-$6_khCc7X7ϝb0ȭm@(SL 0BHц BB?%B6HAD~7pcT0Z[[10)QGʏngr|0ƚώ[n_=ooQfj!vvh(01~@.Xn)pS5R~Uamԯn-͇.ğW \>6?7,(%]ut S\ڕ+Fr eܔcEgYیGgӭNuW=` |[BL2 Vx#7^(t[2GhAO\yjTT{Yې/0e&{otx}vww&8EBMcǸ1䇦?a1vn}/H Xț/a~E@ˀ)d2 ,X𮨨0?mVRR()i.TL_ővA' -Y{Nq"O+REmCQZWDl5Z؎1 CblܸpsV齾`$mxwXX]{a4!#W*uAQq#tJt[ k!$H z?XvWU2uRo9p:T0Eixiz5_Ue&[F`LZC 3d7Eʒ6ik,KJхFڌ-N8QΞ߬ :}9xc Sb*t 9KMk}G$RIzFF jBJ{y- u)eNXx=U} .YgU31< jT}1E1XԱvsZݻwc^w?x/c&qE{l6[Yv[0<"| ZXPP_W7, lLϔ^2(Њ:-#Yz%ۤ}yS.u؆zquwV[Ny'']GX튨Q9* tƻGF l2UH1$n裦ݻ%Qˑ^+)\׫kJ 8\5wvˆ###F|O@؆xɓKIIᑭ F ;dTf1SpKC/NNIf_CmzglkLJ=$IQ Z#]Z<AʔЗA:W@򎁧Rx"@[Gj$O-Тd3F`+؅5|Ayyyt㕊Mjxf #ԡ}g[[*pdq 0r]Ri17q:{{V!">iY ]E $A2 0vM`l(ct"4}R0)= dʮ]ȍ~HOOd6m# 94j~<5UPE\@`ONh-0/^n&ʟj(3hh(J7cFʏ"|9u:͵kqqF߯ż]BHxgNCc\~JĂb̝mNWDt#aC9;xKhp+zz`p4k8葕f]YYqukϚ5SJj(AKi1\iq:jRq*lBwB:$qW*2:QݶC_\0fA˥kѶ꧟_3UhQO^wO~L9dFn918rV ,hl3_ dܹׯ޷R3ȥK0erDb֐JvMLL)*-sI$_'֒@{K!9Zx:v>(rY,{h ;(X5Uxi1 4sxcIyaԶ9Ɋy!l}Zj\l0N:E_߾giIrHgXܨ=,ͫsGO=즉3=('9Õ'OHFP.^^Ir,a=0y~aX L@ʷqCiE !&1'(xDoo/.#[؄dʓs$e~Wc0yOB5?J()ttF+mgՌ%țq۾J{sVs!2|8òeN>%ln'tM=RO$G1IBOfS%+x'pˏkצ>P!hm)B53富ڡ˕[6̮ܯzJPC2(ui" Bgv]y6D Arʕ~YM6הƘͧx#.Ww;,67|4-ÝEc߇~8K~I$࿞gvIgZZmi ŋo6lp R`DXϴMk'h6XHeN`Z:u Y{ ~f3tR( |s/=Ej"Y1&Qq .]Rnqʉ677;W%{xcvǧ̐BOP]ރ,O𨯯?}4FqӦMBSR2<~ mټ^'ߦBYP`3g<333?d7]vd:8˸{:iL!Ν;7yzG8ğ(Ӄ]kجë{*a[2{=+xaT ( uTbtw }6 HK1}Mp+W&j 但 ~a=0񪪪JKʝl7䩛?%o oQWSSc4%ϛ7:;;DJ+43g(*Jc˔I1 1Tn(QhYYY~i- D<TիMVYy1PÕ+:Tu5MA"*P&S)RIi`b [W=K0gap&ay].ѫV Ŏkdy^3P,ІB܁I< $gϞMqmmmP`/^:Hxq؋@6mȁ\&9`gOCY/m 9Kei%6-W,|*Vj_~*`0K8]}Xs SS6?gQњ}37^'!1l ̐ bZZZBw!z*0 W)Uk.7PdLXBo{{{Ip:eb*fb ef&Q1AYG=22Bf]nPKx-N6,^^|ſ˿l IШoӧ|(!h䗿}{gϞ]p!:qdի)((Oy㽙,2'^싗ݔEٌS `S=883o/י^^8&~1JKA$#^WW.{;v nl8[Rx¸1,ZG\:cxdtpӟng`~+UϽ_<~#׳Zz3&2vv{2:..Hﶎ<hˌmv$Ƴq_7~(46%%}ɔ-zĦcȠIN K1 iϠ[' Z~jPe00 ܢxs=Ir9=C!wӣI$GzztNwbs#|b@;@%T6fᔶZN:zJ9srr`yB34U} _Il~/VCǐ>K/ߏ@_hQBB|҄|!KnU0[ *`〤΀XMMMF WB~5'yה:NCC݅wDtSp>866/1{+˓JbIP<H̙:?~1s΢e;z~7?xïױ}˚=7Qڶ(n=ʅglsiw0"r]bϾL>ss?ܶm9\HM>R^YN5哐\ RYkwsrrqPvq=8Efy`;&jA*׋ìDӂrk|ڈLvHy}1sVD ]^N:>~:srZK_lY{{).f1|۴U2!S</%qWB}ϟ-٦ׯ///Wk~˯v BCHCq!ZztEHETRSH\7\n뷡b.](+! 5h?qϟu\?mRJ"!oiЈ4_`Ky8ĝwC:l(չր2Ŵn,?EαՕ iMhFF6G]pC_={vɒ%S>R~e%ˤ$0ckpܹsy'%,,r?w`„ֶG*J6o<(OP񎘨d݇enfJQW̑9?nhhf&^u㨥WY^eӎՋO|nw!MɃBRs{UW\ a6LgB ?p9BeuyչSy|IwO&t"Ş}Py3'zZUBw7\'ZC%3YMfkqɬI5?g 3ʕ+EEE߉-y48~ֶXZ!X (6m2c!Bgg'*++i|H0fE'SU4 )j Ƕ_L%U:> yFlnK>1kWv? .b^7,ARZSEQf٠x}ab"0gL#,VBl2Vc.AfTUUQ/O10]g$u%4wP<:T* ZESΌJ@90|0i[WWWaab?69槴{.]X}xhBRuC<]m<w}:|/h ӎkV̹Qg*FM5G/' >~ +uGZlipʑŤȉ(?5j65U«]a&> 2˔r_žoo6<%:Fr0U1XT"rg`0uH8RW;ei#踪]KywjMOݍ+<ёma5O{ }cKx'_3< 0A.6رP 0r K28f͚M6q&@|WǔVLm.W655pfdHsf3E]FZlP+Y҇/c.*ʍ9i팒oW:m.EM ;=yv oWlϝ6['{I75cH%잝W_hjjj9r|y})W~5$^L|#5ӧOOjajb,?C@OD \.q %#'' mdǜp|ۛm~{w8R'%:x܄H%*!IپHҥk' ܸON P60knmu:RZ^8Y>o}+к#WkAAAjFJBm8:1,qeW>}%=&=;&[>3z[>9t(=$E^xzy=r&[ȇ*[ƚK\FjZx>4%:;qBl\aБ-˃Rq9Kȣ&;Xرc.]%))3ظS^^&;з"A|:~ğk =Nq:vvy5;cqx| L+j9Q5r0o0LQ(f6 ,$<;pB?ӏr>Ϳ]n#-/Kg2;/8w=)Vn߄Ԙgȝt*1 8RWW^j\cJ9sfʕHХ%|eha7 CBBȻs'Rmt* EMdmIV`{B)..KFAH"A|ˆ@bdJ4 D8-_۾}/CK7¢ aAo6tFqƨBaך$01Bt'<-)))۷m_3$~kln[dD`?uuu%%%ٟk-]3K+=QtEDdQ,63ϲ^惱iPz`RV4'\Hi|͌|)|X|R;9 Yh?- _jn0t@wt ̖j6yU;JR8{3 0!+> - 8f6}fCƁq7nGތQ{5^my` xzo{_y_8, t扠b[!ĒgPIE0^T7?r=:QPu8`S ~)L>N9nf3/"߱IFX,WC/8''o'7 9?`Âm~}e\?<5!.,P<#m`cDr\dw{;(L8c]#|I[U^2iҏE ύ&eJJOgj)'3gΠl[gs#ztHW2ᡐv`L۽$DtAbVP[O0,lP|ZC95ϟ?OI!8a,޿vK.A!3j ;&&4xKzBd=:3hFJ;::,okk[zHh :ȑ#_}֧g&?ukwx:zu:ת6(mDȊp"ך4/' 'V{̏Oꁋ)y_|l .]dv{{;pvq%911BRRmopr-&/~MM FM+SnեBbh(_YշL>:=ޟHy =H1 zwaa1hy^ q}}=mn0=̫+|oנoLZYA=6g|0a:PtڦabˌcQ .MvTB+v:11VP}|ՙھf5˲%ݸbmH@:R?#HB  8-۪VuW[e̓ƣUuQ'ξy<[sMK_CE uթ Ǔ"gC\OJЪuW$?_XelI+pQ5'1h nG"Vf),Ufq]a[cbj45~KO}v$oúXt=@t'۶iRc=dʥ[++h- elL(`Wc" 9smʌcvK&'`Vdnk_v(vC$&՟NYt@w*OLIX+3'z:=7tpC[v<`ի`Aŋg435"q.B;y3 0-NN;@Ua 6("NÎ}^ AU^^;%%yXY׾/"4u:X%MLԄ^S^ɨǓ.v8}wy "L<IJ;v̎B~"<$d2^8Ncc#[O5͗w|q]U+2y$o^;QFm0t"XBhhVn34 mp:mopey1gC;1 mbdw-~ԝڭaat@-l qw = xt… pm00fjE8T6"e@"ogTLDyfq!a` h]ZZ #?{j`rEa|WiPɥW\$=R9"eVGmG 璞_#[c7m]6wPC~>%}V1k\/u!4G_| KM~&8=,D KMPHTjy"?Uuy|RijHRHо); mmmEm@ RW-?`ndhI:&WciPnbE7;ȠPЗ=Ϻh \SSľ ĐZ OHHEXFoh0@6Tl$d g (Ò~:%KL\`l1mTD|n-(zn+ms+H~o@6)`jQuOFvU(E>N*շ^O4{TsKEBlB?zRs1){_f `,|X;ZVuf7Lt"m Vۏ7tE7glD~9uf~pqܬ_nR?|~#rt7-Fe=J8ՓgjÑGaΟ?n3Ț}.`rr23Ӎ3273HP0b 4Ηh tLKx1%nTک{#`PD89r,D>#מ}0]m 烂4W< Wb۾=lIe`h6J>AM)Ch=9 f,_'^}}?xi G?_ ^s㏾Co>;Uy{«E9JȒ-yx?~7O xa,ij9vҙaAfKmLZϿv\'b8nnnbOa3i~IIZSxB"&R{ˑ p,$>#_( ۇ mZ^m2_WW:B)?,)O[Lv fttt=e92Yg5մpDb8{Zq(e[7ZqqoΒ̕ȶ`g, kjjpp=WÆhܰ(WkٓIhng]xq\\\o_ůza湹z^|xPO s7]`[JbҢ#~DD)5azA jB[kbM<PJ y ! ]BBB/]UUh@f#F!1,C?ĞJ ƺa 5[[[gܪU~.;]ZP03.g <ҡKչ wo^?Ԡݍ9 W`jWեs5kGo0s.[Olp˱KUqJu\ >Qv XA"`̠_Nͽg##эh+>c& ƍI>OQQ,osKE)p:j/'FXӱ~~/q?xlſb+',tÿ󇡾͆}B5`];)¼> {l#Z'UbZ1VqT[{ N>MKK~oWxQc^3[VYÚ#MnSqӪm[SV8ݎ؜e˽pg'obVM'+}ޓtv"sJMMs m|9#]GTV4%Lvrt0e۞3%BjԶ= HLL,xAF~h-cڝїGK{Ty|ga|ҋ߼_[߻>yc^oex~VRMfMO䘅WT_,B(t Lc`80*vzJ%ɠ]ġk88b &x4 yP +**;/Njp9_D,LzwFG]RJ_6!1wƍ~/Fe- XlۓĶy63555i{PNdEmh F _"O+f';[:w}!qp4Mgl×An`@UN] HN:rJ.:9B izAub/iR:Kd)lf?#j ük h%9-۲ 7,>dLS0.X '~{/0vsC| PR-HҪ@z}ѿ/{x|#Ca6=VR'nXz( UuplX fP"8 YO=U}Rr.(ONZqLl66=j,6*vB?t݄* ⩧Z|9t_~78s xubfZJD6 cfv0*xJ]wB!6-xzw\.j_s8@:u!v푀5kɕKy?ubhUآOї.\zԕXǾs`|,v _^_8Fv|06g<+C+18].>#f;\9#sS݌J=bHTbD[BŎp8.Tm =b 6bW)jXQAӐzLiӦEy!v|BǴB7B4نQ2IqؚUlP8e۾l7FkXu  )kmG^[TJ|/0?;??7y>* cTɉf5/7S\KQۚrSHQ].rd+6 gr;o9[?w{ůw 6lh^?O_=ZRzj4ZU\_,e,1ylv.C.Ђ7rZ] <ٴTJ sW/Uڼ>S"N^Z"hܸ9nLxk׮l6|$ĪH`&>ioo/))>/W!r2@cA8]ct̔ `UW a; \iv2 dן &MQչG-uTKf)ns Ϳ=̩e}##??IDv!3%T6Nq1qЕ{)¨l۴͘F9gΜ m`7 B|9McǁlEPW` D 8ꋟ¨ hXԶmtCPw-]tŀQSr9",1صIxn{#FlCڀCn~ꌔ2/КǾmCPܦXWVV m``o'H[>;B7#kλ;v]W0|cogkh0S n^K2g{7S!@fp}.3|,`3dMe(wXz ܖ-[{9L<>iVhjjχ_;::EN ]"6/;lƶ !!;Hg BkORկW+{PG6W_pӾc}< f@׳iӦ-YdݣT??3Vͅ V2ɣv4|3nW~ SThXyh¤]?]]]¡˗/2[߂,_r`Ƿn vKK ,3יִЗbޝ OT^J=$ ^J"xr)$b|N.&7nw::-NW ٶl٢ɠo jOw566NxV퇿 t]b*gv?C]>-...>>x4-&)N_{zz֭[o߾"ayտj?2 ]0="ÀQؿ՟0J266me;KO*`؋lsT*&=IY 69smx ^bL _ JrF?mj<:Ei揇nNz%j(d ]XwNNIq8ʏHJ5S+̚ZZ[˗fdUVmޘ3il@Aˁ677C* vlrr2ƹpKEE&+\0FN "E/r_eSj5$%%Lr64mb)pUV^~i_ki+W_xu5b S"h:)))4%ÍyWol|7~ӟ*b~ݗr/sm&}`Ǿ4o7[w؀^Yn!ۘ@϶ 40Ayyy~WNƛ%ǥ˅!zZmѩT|ݺ4m2*;[5,_s*,''?2r9kFNUqE'i OzǫY}krm4J=G6n5^lF_^j!7\gl^bB!rɕ:wmວgk0Zav85uzI1ę Ʈ omEMDRIQ ~ ]lJ5tG6N-w#ܔmvBMM PS@@ؐƀ/((`aOxk_ ƒL3ʀAVQQSbwjg*/ñ?!::>kж $ }Q٘law;OG].]E<~4- @Á90P9 3 S } h6em.w Ol|hVFqͿ=eyT*ś>Tmtti7?isy x'm(`jBBB! Z h;4vvC{/))_l;])t-+n*r?s&b241)R:~*!3wd]^QF6ۧgE 4ٻ jQKS85*;x2vA}DE=5fU6vUvbFd^l9 ;r5G6&zFUl'Ëu܋}IvxL0#Pb:RlX"G8Tb~N"Yq—X*r7}Ց/(s]hɡ.`4cɱԔx͜n.UkWjcTmUs<%B.#&>mP LtAC?۱{XvBC a Z-vtt4774J(-l[vz!.tm,g>>t<mœۯj$¤`;n )qZ=3-.FNGk~?Y3UDEkX#|EY!'E*/4 x cwe[%R>`Vٞw9qڏ7{kH?vtZI$Bb>;!,< VAB$⁌r0AŚ`qZLS\.&7PȨ(,F׈fnxx]]]Fh3@ >aaafa`/|2i1<A;sK0d'3ajݔLL?>Tx-ڽN/$D*.ATRD2LY6gTH,'$OFE-ie<_I:i?yͷvmR5! 9D.%}xBv{NxRyalFZyM%hE՝7 >3񒤽 K񚺐HrgVd(.]I$WRXR!PIĵ]l#37Vc|`KᘘcgNIs7w~ҹdTOK{`x2\(ɔG"W|;/*<&$`fvdQ7.;[}t]X.޻RtNIg廷SX @s/Z8*x/hSRbl^S8-޸COD y;mznN55[q 1G Ӆޯ?!5eĪN[+%Y1-\AL_\KJBèDFYҲ2pSrMٶe4Q݆_Էٶ.ʷ d\ot!$Al5kx F+t)3'Nlٲ 1u4|L4*LkjjHn :}6vb# ox MB6S}0:A6XfΝ;7xG?ٽ&;==B,R'"D~e+7x Ć؝m{`jBSŤL(M$$ xS)UT,/hsU]=gN~n7}Y'.̣A*u-p yxQB) P| G*9)Urxf굏'QȁQ0 ^~Jᷗϔ7[]|?g=398H8CZ3@K@/1|Qr2@=@$766ٳP̙3kK.:jZnG TTTr»T5g"}S!T hTDt @zX a۶= aPj=(ٮ+Dòv>SGzl^]g6|4ي3.$dLm|g#|h[DzҖ,Y2=0xG$Rmс'mrZ `4 t讗4W_ݽqAa>0>ټW@|rRR.6s~mCDžf\=0/ X#꘩M#CCC`/qZFݣĶ0 Y|ch?qw}1mlEgg'0vPg֬Y/^U$ˡB\\VԳu3'JɸFKI{MgHoOKK_YIȇP຺:X*b:$%%E&p#xٶ[""4)ׯFeL@v_=Ry7`B&DOSd$C]ɮ]a";uU3 y|V{3#)sHڌ%4`Rg8eC&}hzl'].]XYϜ>kNj.W.ϣ败Ni,ivp!jV<KnZII\}l[y0n@+V?Z2i݅[mN$+O/!%>^~bâ3ݸM?IN:zOƨ B@h6"77d P}U$ ~=q0fZ/Va7rLB ,-[`J8HWTT0c8]*8UyV5tZNnmk9ۀȷWu=Ȝn;!p-Z>8m-^ |t5 sD3gLTt|#oQ'[W/S -tyZ#ZYҞ+Sv!qnY6Z}QOFj'/qV l4_ ES|6ÇfO7- LƦO]~OݗyntlUIuy2.KvL2azJ5gA͡c&h\P6Ǜ(j:v$P0.@@"dJrrrQQDZRRԔI ,6Qp}cK{D*{D::|FEEѠ t: iӦټ]#ΫXnuFfUُ}kU"eJCh[mݞvO{a`MJc/tfdr[cVV5K[{;͛7ؿ?4/_ްa.nv II1) ;ʄ(A{B&hцG՜=sD5\_{GiڞYCܿF'teB.H"4=A*RTA $ҝY0 N 8hjØa272No56Q u(P_h1F5|; ڬmGټ(cgrvI*uXXX}}}ss33& [U'L:dU*мp( ucc#n65dAGװ諆5X90km0k䁆]uR oZxCRSS)C.ir^aơU8Ch=qCtWj)@{|{k[H>#r_4\TuK=yls/])\VGrѩ-[<ܦM;kRԟlީ5g$yW_'3z9G\^oKϸlXȨBΒЧeY}3^x;R!W$SWU$fW^c?H ϙg/z٧`&&x3kctd@}87x0βD񋎅5xP|Jzkѩ=q:7 bF=wf7e0T4!vTd'" *9A pny 5k ("{ԱaIEdԹɑ>-Z.S.̪sW< Qܼ"ON$GD$C;` >-"n\9V%QElxwfថ2WWU jb޼yx0CH p\ξ^i`_hUg7[h8 &[NNN>z(u%sd (zRRҕ+7L'f2ZJ‚HKz ۀaz {DtĨapo>1.Z3P_D0ujF;: \N'VQb_4i8$Ĉ `mmmUUUnn.n@l@FP0 !v$PiI<d1X9>.l#ppɉ6YL[[`)%כDdXx[o׊{vt8fױu =BOv'υ\AN^y7n#4/˫7K̛摊lOrҝ_-$Dժ㰙]LnGedm`ch8 gN+2fm{/5B,X<0x86u}^"VaxxmZp9;&NW_2Vڬ3f)ҥ렫u_(Rf΍Bu&3psGpQnm4m I]fPuFs/"-}5/5.lƮ 1..} ' dbU "/^fbiRFz]톮 u_#Uk|."=mT3XM6WP%d;6?}ArP 8U<$3^Qp5<!4FGo\DB G%eXS\]խQ ^yMAx˅+ٳ _?%ک¸F'Ij2eyb$rÂ% \K mbfN عg6+6NUg41SCtmIἊøgޱc3f03gNaaer^?~ ^ni^ᩣg~_y*];{r ~g}yx?O\gn-qBl!l6FMETFO\u}${};|5*Nyrey꽧C9Y 4ާ2I}xk\.żQOr\.NQKw_;oBY5}oA+@ /xz-&FÚel㳳Y5=`t9И V.!lw9g9o'F"y_Y;#h?q"Y&b;TƆ)zϘI\KTI[)OZz nF Ŭ*76-l3\|.6oQ򡱱x.c+^| a+-9u)Nq> Y7k'gr7w@7Θ把Ld?1O1/8qyx]O{>W K{QC/~k3?/}֒9o"?vloFH(w,>?ڬ*V$''S6>ۍ'#sی_#u*v7I5 Y:Zwq0My!2"KPG?9B>S }S cVO^?dcZ9`1SӖ&;>1٠+ +̕ W53,TR*/T E]Sq9BIpvBxL?vNHTA\q#tnL9j)mJzJ[ Y3;lX`<>>$awpyԡJ9lYW=4-\Yr| Mdo<)t$Dn4D"~bB:"ȥHN>uX,./tuu8~DxUGxEk4֎FwDZɶ'^9`k/&cO/MUUX1}Eh<}cPu).xzrL]%h0]hpGGNccڹsnݺ @rss… ?AG@HO!]㯿mXڂGXp?Rf?ڏq s p7z Rs4Dh7BUE}zHPtjm fhfa11q27,  uS_PnVRxkr)3_HΜ3jkrwSr0Jď r3>$𵎐6atX_.+QWx}-|;Z6:7/0$*;Nit4s1o^,.$=kRqxʧϕ\SgdTTvp] NX<;f$_TpHE>VѺ'=T""x̘7OS$]'/J%C@#lr Ug4 òMlomҘ1A'DzNtti.^&,yݻwxMuO~rᄋU7-};?؟?0 H(]I)%%%Ѱht38+PpuX<̡`2Eh-v@Bs 'acp8&]ݽҮy^QC| FޫT萡޻pI*pͭP )\ MMmE4j$$$ <5D"aE#כ)---ɖ\.WPPЊ+.]8gvbn?ɓ'[+.U16'2~d'Gؿ,<ʾ \W+D^f#,, 7#jhoocډ;mۘ~hbr-DSzϒr2N9ag0FCg| %`. ;##c< 8zTjsBJvGi.'Hl^Qh$`g4#hf*`1&ƾ7@JQ74v`O>",]P/yy[|yx шT*BCF·蓗oCxFR [t1;>')]f|SQYqR[Td ]3a&!tZ~9RRds+s+64 h|.9Dk4R7UD(G.Tl 40a'%%8q>D&Ҡj˿[%{{ w56cnjQ'N!O(G5"<{AY7( DǿUJq@i/^=f y">Μ%F+ZTHTQnO+-x:fr8^S=.PS6;/ϠPZ6454aϑEQ.TrBbVm١1%t*ciSɃ)U_^nرɷ߯KLN IM EѡgpE,7Кsk7jW)];mMz6nMYt!F$%x(`0LinL\!yF}o.J =jcTDn"L5d22(B>SjsV" H*P }Ma!7}št$S?S6u[fN0ж8£Sd8^uNܦ &z1f24*Cʒ`w>F7 d%Є /11R{L՜dIG䉱5==&gOTxZw0Xl=t2Y:Vo\yba\yE}bH55uQ *aߠ pO?WJY6+1+.l*MZɁZpko^+y8_Ђ J˖$/>9"dAeMPc*ƈ3Zxܼ`UuhlW:9NchYr1!8rC===5,Pp+i3|$\ɚSù(jqpCnwvoUChE >,vP׽IptvZ75b^  >=Plͻt}o)Dv;(2eIˆfe!ԗ2sxF!X@lE@pcfN'hz8d:}eogFr Jg4"Ԋދ+~Meh:A/~:Pʱ<=ꫯ*JʰSh4imku.D]]]SVx!i!0&ADH&bef۞ydKju0 N,ڷ0*UC8ft\yLN|_Vz#;=uz{"URmr%eUMle݅e*v#9ӝ,jkKp8xg #qS޽UrSe[F+S@t iZ=Gҥs2CBC>n CqÚHYU0: mDzW&Ri  ?۞y߾}oH999oa0(({޽]߳opA;h+[}|7~Ά؍K9ticT B (Ç#S_2 "`ܒ̀۷oGqz HC{)1GQzU@` =|"@|)+hT 0NrV248Z4 j"TFz9eK ]W(LmΡEײ_Rה]qzIa-zgBi7Olw+h$>ucsYru}^w92A766œqd 4:)JVm:1nDދ~MeJ{6j%%%W^MKK{ʺD"&⸻#{)ɭ;},Br.Dt- SDExW봰_7ln{4o0M<|2h{DjJ j?NOã'q=8aPDLi",C a4Q!!-RqW+@ F_l 6<*0#d 6D DkHDj(#&@/tSz\|uvt:ťrL(Q^_$ȱ)ѵ+{J (<<+ 09cahCބ_93DhK!"Q|!عf=.Muݜ{"9[NjWFcXdr&\.e2ُcWWW2~TTT\xN8:̛7~* 64ql3 MGMV&9@09NzJ >w21to۲QN>\sll,񾾾?augKw&Q>᝼rد|wh]UWX %6#8Tʢ/8#/-dFHfȮ-戇uoq`q厽v %ڱD{:PGQ5È oJP l(aiii)E~+m۶:l3&& chʕ+x/ȖjjZ|07ubiL.V5Lz'?qqq!ȑ#𔝝]tt4rL&www`ȃC Ih{peth#m"5|nV8MyPk>"o[ p޽Vk0&avttSgzz:Q0b#ADOqztӰ4ۓ0Ja°I5O6]{OK?y'#b'/{ǐ@#].s,3>sZjN:QpE:Lt3f}> NhfCR십j <<<55u 74ql#lr:c6I¶-0e0WYXW^Ngz`NC&#|Zaobk^ w#|iJpx2xVV^]<kZt/PŹC"aPRhcn[N+M򌛲NX,C wmyK`\BJ]fp K8bXNE}- _MO<Ġ-+E߆z/v`"|&FF(揞1hN=+tذt˖----h ?/ @4?Y< ifŧL&ۼysdd$n1AxcǎGE׮VlڵkOn{DdkW+&oib#CX,I '*35:C5ud2$u Lx9։QZu>|{EDzG*tzFKߖl`c(t_'/bX4Àž}wld61 м}XO!f͔h(** =ŝ4۞mlXc رc,+? ;$$>QXȶ 0X.g0(|hh(`"2|Ԝ,6`GaHN6==}#@V;R dD\Zp2jkkr"pmΝ;#m=(賨([ ^P GeffB Z IbYh䪪*'KPM??ŋB)І={qvv^iʕ+W+V,\8djz 궧S=[*qo@:rSf2u"dDt;lh{vp簘0ufD92d-3._;LMjqKo&'j{ZnVD>ylw&Kb`y7(f]Tߤs }v{nΜ`粂R8dnhۆeK|a|E` F;fG0^:(c(ai@|loo !)݋F9AW926"f\V+ tͿ 7ٵkѣGPK:990{{{šT ;99d/ЛnBU~޼y1 m8@ SOPhhQLb6&l%ol$0Ol|ʰӉ#t('xo, X>C nIx@O‘@Mg'HBrJ,0qѠ())ꫯ`ݱe'T5E7;ʄLJiX$4cZiWyEZUg]9w*o1bts?EUƝUGi( H Ϋ|EFsR{d[E5iBS<@ 4ǔJ%sºO% E,DX&9%D"!Fȍ2B];;mE1ɓ'z ۷/YW__ x&8YIKV("ޅ1 z?ʟ:3xpNii)4 l޼vhVL&Mv zжwQ&sPMSr&{tr ' )ײ1aJ:F1F2t AzSrn[+q7.^ذ)ɠB.d2Sitk?i :,.(.{69G,7_~[#GK08=מ 8<}n|" [ŭ:s:9"zFCiE .У0oVƄz(%Yf.x\#_4DFO`  0@14 & 1D D vܽ5RE^GO ^QQQ?~ㄶ&NmzD`Ur[GdF ws{#g׀BzbU_k6ߝZ=At51ҳzO,d̀ 9? ⅘{7ssr{6> ?"<ɫʍw/ߋ]2_ޯI W-5OÿkVNSYihS/$//;mpi|#]qy7D14&3ѰhWvKO;zyj#,c}S;_ HXC4 ¹q=nV&EDD* &!@K0*?-})v & >d<}m(9ڀe={؞xbCCÛo 8رcw0hnne y@> J8 j8M(!fYY62n $'''$$誯Mas=̩'T {j5#1Ok+V&΁AB VO y+bʃ 9Nݽm[b 7;'ΎqiM# Lxɜif}!˫ݰwpPEeH˫:$-t kqj`[}XgڽC\9'NCLlF>cbbJKKg7E9-jΒ<ڱ腕wV! T6ګ9k1` L8=AZE4MBe-= G=2Daq9B! ( JD=c*|||A,b1<`iU pEl97'qwW0ƕᯏ>6,72Aݶ>Q&1 b躺 3jXjEqz>ϵ:?p +- W`4rlJk^xt|V_|q5[a2ڵkW~~ ׮]`?~@ذMΠ@a9 Y Ӷ5j5^L  4[neggQW||s=:==dmC5j4( 2#6b\ E#)zҫ ܤ'֨) X0|<1o<ґZQ^|оe)iV$6A|V}^csG_Yi~nM~eo$`7NnN[ƋN%={w}x6G,9!6T`H%M0錑>J)QE Wh?K͍bqH&#6 SqxwBBBmCݻw,ZYbō7KJJ`DMq5!q^ d1 >)鶶6l'ނB@ Bv l+n zmrX Lzx9ZլΎ44 yҀ߄ aʾ|*1Y5.*Eb1D+7?2elJ ,Wth"mmt+LPVDlՊVOn۶y晸>,??D׮]A $]`|!#Yyyy "&q߶7hDj.X!Gdу´BQ^Z ڱc7LӦ۞hp홶\ؒVdRBE%D8PIBVu F$c75J#FKaxWouwkȿRP%q!,巶/{="QJ?Qj(ͯ+uM5>Mye&92+ge H :8HO<3|̳&&4fx4"9TF4n*YEܹs1, ]^^^__/  -Twww N #.:6|ڜ8pO#8t :Bhe"g ftBruv>-98؋D\z/2w u.S%4w2 Bp4;v&NYqq^^n$6t([WfG}3e"0JvҨqة u<F˻kC"f3Y n٤l֪UR$ꝋfO_Qg{IrA0յ~3 1T.Es4GO ג kG3  I H$N|RD\ST}]㍭ؿuVgwG6o{uWTP4Wnq fRJ?Dm%f/{Sexn]zuJJիW3221 {3#*).ƉlÒ| *#8N&d>>2ls4G#H4p9Û rj`8O{0 m:t|ag3WΠi6z΍4dd{7u4+o}_}&Ō%w.GEVj¬~5^}6NS#匊;iIWgMVgZu۶ad uɒ%999g̸3l/*r| 4TTb9ņь9m3"i mf/1r6趓fo6zvޔ l,5+yTzue1׭981Ns٢V|aH|ٲe+..sN}}+&BRl$L#IRElÖ́mX\:u4$gL$7ZyloFRJen4|ٜ,XRŃ_/0]8me~*|Nc!޷q%RgGyv"׻ };|%ݻQN)yh,ʑ8uvvfddX+mi 6Rk=HPX߰>} |ophȽN/_6z zurdWﺺ:OwwiNJU[[.X)=G3SF$G1,L݅1h" s^Uhmr}f#ڥCWUG$F]q^%O+ϸ^t᪌,ګvL6OeϾt,M,l#^էWѸ >7`5u(Ƥmxǿd]4۞-jImvIVCv@PP($>A#j!׭['Hhj{1-]tct⻫ϮKAD3 hȜy\34h/'UU&͋*+k.TYAR|N 1\TWTI"aLdj͡5 aPgBpMV!ht>~Es٢Vta!<>'pݭ=== CJRE"I\E|'Nx$8`[SL9UDHe 3R]rtDJ;a \4ut/EzF_d$?}: $k zP"a\PorׅǩM }.sVqf*a$moN!B>Ӥ/{7hKk?{1dyJ(nU HF[KR/aMCu-~hbxwGu7Gs')t?0d +@V|$xr͑ QoX8<[o8aTNi:Ebb&jCCVVn_DxGzfa s*Dc2Ae %G@hT n6wK?A9I4 *m;tj;2˻r"Z~6ٟekpvPBjOEڨ2ndyDU֕J 3/8Ƽ1߉~כQV%9qP9YMT] l bwF`VRVk y4X'Fg*eHNdx|ZI7tzttsh2tA5iqa0jtAg>eC> .ɩ[$pr+>D^Vݛݾ(Jbh667Ԟvc_ϢBR(t y0# .I;fPqZ/i8B+Z?i"C}GdK;,\gnN=~bXEh.b' غ'DZ8HYvT92;.s%OTMdt,*eYC1 Yt|@-fU Ph>˲d-/겫y2yt|+LW뻿==\ vۚo_.]&D91wu-<(`3li<&:q"vt7wj\GTïkO8lw<GuQW?_ͱ87;s\ܺTb_"q㪆NW\99Bf@ksŻ?pss@luu5GkVd?`clcyؐF!p%wuu%0姬x2gSPȍ aQn$,/ci20n^ɑ^Xk $RNUYPfX3S)v:Չvt:͓FXS-6f3 EzQ׫x&dh2\Ջ{P26\ߙ7o(EV/iw7pRIg}dk d[99@: D[@G5.+@b8d2LX,3 ӈ2yo s\du@)@̦zH (E~L['|ѡ s!&LuFELe'RaBDؤ\-Lf cb}28h`3Q6-ئ.kU%yR՚B&Mh+cB}߁=RVr{F.DsfhW->EٲyiW0A'S)&+64GV+pV(bI>x6=eۆhD̈́X)̨j m~&T z 6n\5UC#W͢{ۭҁb.|"@t gWUU::::88 aH&$C4*(J@. gC 1! dCimm؆@3Nzll,=4ihhr7eV?$.$c{jւM;YY0nYKѦcT:Cvf^ҧj\7czJ†b,X'3 S82.ݷ`V%]UӔp^@sn""rIMϞ_|)8eγ],0ÁOY鶉0*O*L kI#/( k1fBu̶&sj؃Ff"gBF)r T 0͍ՀP hzUxW>o(vII `63`vdddHH- ggggNC.eDu[@ ^|3n{LLׁ6 >?0" 8'O0'Nq?$mShf8 4 VM<,ler1 0ɾ֊.%d'᳛q,~e||n?8UiYZGL(,jjQx$[./]"29BnW@kcRA& ]YYrR;*@> H M  qi;9{U2y(N r'o8wwtqSpw՗sG\<=o]~8xX;`t fal 1lW̶S ܙ4fSo5%lJo/ ׯ~B%99B,Xp{(0' d2r9HWlJK&M袢"fHB@3k 777}}}V_A|2 ,֏Mf772ʑ zƵo 3"V=<܌s1]M K3^t-rr@' J`v! $E(vq_puߔȁA^#d^J\CMp݌J Tug$TwG+ {wI-LA m"Nh[10>9ND҈]5];#BC)da6h4:%>lI~*M @2dE~nÆ&dWiG WfQ}Wf@VWf'TjUgUͪP2?!]CP5V Eb1`6J D"bqx<%M:G#!et_kD :hU7 |s|. l K*7:14@{QԿ mC?_r6j?Uƛ XKqUGoi F%0)6+wyp7WY_SW' 2qdיuΣül$,|ݺ Bv|Cɚ|)a /OcXXF3BucG#Wy Y_l YԔS^^<8NNN!ŖG_P#a !‚zVTzyyEFF:@1~l(TW4xHRɠ\ HPL&3j&SLC[{;YVVbߵFFEf1@2e,lWooNII~~~mm-fF+ha@ơji  ~)K}[[)j5].'Fy~e0PO ahIV,Saڢss xvٶ[tr8,!ʏDBɡ:`=R'qxl*GBrxN'zgRy5ݹQϿTs3১\x*SudK3lNJo?bv LR#J>x]_ㆍIF]L}f/M}nUgxV9!:c|SȮG4`7u⾳+vw3O"򹣦E+9josnmkU;~ٍtgĺ[Zn$Ez;vLaz8wmCF3KvSuNNwѿyu7a×ã&tG&wt+?M[Dx.Aɔw隚.koo K-Zs[ڊNwDtt+r 1F̙3 렕b㢡!˗/ 3AJ6 ͛7ϟ?iB@A()SSS/^a'O,..^ Arc/7rJ1GC}/\)EEoMKKKLLc 5E=LRO5=l2±J:z3TdXXJ ʒ#wvvfȠ y!JNFO˗gddb( OT`` 諻pb ~#Azl^Ǹ(eȍ7)繉0C'IMk&D#p YK >(gOMD j(G^CL'BcQIxmPpŠAvx%z"^"V X9Hu)<I3M$ &=R{t?S4#4AxH(v{3?t=w:Gecv_2< \fWfR 9Bsd"D6)TE/imm~)*'حh~\\&;;UWWPRDZ@?"ѳGJ#p_x ټU&HWО#""p1G^#DGUSRRH9sM#EM_|M/ቸGIt<Pʓ]VAz`DA!DCp(:<)%8f2; seN $.F!9ݢE26xtV>HB@kb v8i2%Iiv9 ;]q[K4bC3>̯9RL-Ӫ$oJ"^-tz5` и^dٞv[__5 log&ք??ɍ:f|x˖-^U{n_Q`DaxG[o7]V#or5V/0R#1R{B@p5RԌ|/Y'{`0"m``@ KD  ;ۉػ/2w`YxObS^9?] =pj®w+O%gx?)!$3cыM-$H ckWo\;8y<.QO?;~пߗn5qҸm2tg[>|2ݣ;rke\8|PF{~xB*Bȕ^p u˧L&7|}TYY=ꫯBu^B5ݪU ]pO? <܊!$ $u8CLjjU+hCdؽ'("33;I֜IDgt?Qؠu}Pdg}ϟt1p7X0_7Rfssx`ʕwϝ;Dex5U'FqTZO.]LZDЁ9 +6C0RP1R=2R1j:+\'Gݏ8pM!0l |bb"P=ub<.@W?~|ǎP,#gt\`0LM8/[ !kg[%ɩ ^h|mΎp8!)!0]VYy{ΏgsevnfӴ"=rqϊ'zR5CYg?04;E{yIB m2gw;6GW^rnf ā^x3Mv>s{M`bvU\\7hUv;+k"<}Yž=%~i vW45˖jU&ljrߢN ⽧Nν|36:+;G4j܁lłG_L2`Γt~rFM`>YzX,'f,U l\:0 ^$)X0Fs>(I>.&)bwh\[q\}Jgl}[[i2ɨh t E؝x=\쵌ϑ⑴hQ@`!M&M4 G Mhq[裏{1 fUl}u`dMz9R$`?Ec L~nEnRns[dda %!0jP1E!^"YH ,(J]ksd1)QZiFz| 儔$,wG>!IL  ].f,DRh5=T⦢etoNU˥*}he:h S>ziImw|NC||ޖO+sJM!K1u[3clwC" 0vo(RZ3)6(FgtA› b %Msmv Ș#6:*&?V_ȔJKb]9yPhHW2^S Oo]wS)|M׶q{"P#j:)Ԥ^ORX"r钜`͗ŢkptĆQYy?'{{{c0>@5~Qi@Hn wuOf/A,zDj+Wr@9Ե:n1zd>u NETL^ v|\ K>(8s``a!!b2i#!===h/;lnn&;?sΡXr :E-*..ްaM`|U2{{zaŊ<SOyPt#Ύ/^ f? C0$8 5J.\0%5e-X6>Q B`l( IqM+Yb!9BUJ&d.sg=O?ȝ\OvKuŜU' W~ d"D79@Wa|dlׯƳi VIRc Ƥ01'.8Ǹ\T/"]նY?lऩ3vlJW{<7&F_3O}O &'':kpϠ/=uLԬ[R*:yQ><6:aU2{;VW9<6hOR[L1'J>}Y{ftK{~Fࠚ +;%h \^.ZadDZL`a$4ʕ+hdn<0򊾂rL%h` ܃JQ1شh g%D%L&Ӕ̔4bU8! ~AΠpԙ *GV9U5 D}xfo_`{!u/4 o P/"Y3x0`d!LDJ jJM`$7oA27q\vm]{]NMnQ'.kom~?Fw)}J޸ \PZ#h٩OT|t#T%iYD!M4J"v@,#(ʬt% j2ʷ%'g /{Ud|,sB7BƁT$7酌m>lRNJ aSJ"?%D|j1U*S*Ka8Z, re$bJ苄̷螞n@BHH ] wM&Tbpi$`Ԅѫ[:&XBD5G i>Tfm *ObYG$6N.p#1{u`ģ&$(7y={1YߺiU cXon>U451l55c.Of-%bD`zGȠ '[*4+~ݗ$$ K|.DX~Uoľ?fPאϸ*zd n秝̗ y)2vtϱ#ʍ:&:fS\hd-lxxx\5a$tMѸ2rZxM/d]aaa *-բ( B`p+Hq$J 9&nYe}l}ݽW?>k::eb^SQ@r7߭pby獣}- COzdf-:pIQ{lv% DIaêo~wx+3hx%( \LٳgKxiqVknn䪁@ao 7;f"ݨcpL^O, ZY md׃Sx b[[[5+a._\PP@ ymϝ/$JO<~&%Eߐ"S^k!/&2@w7cH⻤*˕Aa?atIMO|Rnh@h^4U5nD{]ݘ?hVƇ.k;~2s ՘RcumB\)l{K3֤2#*o?q)9\㣐񐺞}4ۛ7o.--eB? wIdaawNE_e|&%JgcOzv{\AuiyYǫZ\96Z\H˟^T޽zhRRz :zh4jڃAϟǛ܂X`dr!QI4MNfwgfgO-qX8pEdΣ+pBF $N&ޠ&CZ?1.&MK3 $ r=B2'T.̸cd9ZKqDHMFFF *I:7xvWIv.In8}|SgkWlX5z,q{ĺ) K5:X+WX6M)9Qfy06aAwUxCyurZCK$aưzWW# 7mimݟ$ ;;ę<:\bj24DŤ|:#KMMfsbb2$N >w]аTb$;dd$,pȡ3gNfffq´'b7Ο?+tğ7 S]]Hd^<K6 e +>_ 7<<YљLyT8fP}0`J>1"GT mH : >(t5QQQ555 :CHq?y~$$ w Y~/Aa]T$@wOwHW0>*'XqKC!L1egwgs+NNdRPx (P>:lfjD$NA48@lE5b,Ƽـ|qmR fvզeW0,_#HnU-@Ot.M[$R7S•$WVgu m$4%*ˆm4_wjMHR=sBХ 1ܿL˗[glʓ B ={tUv oCJ>Vxul=rҖ-+Pߔ9,gԩGf-*\?2nK 2{..SC S0a` `8ܹo;AAA`w*g&1r!# Don^x8CZZ?YYYeee;wܺuC9l={lڴ)11h& Gyd֤|"ġ-] [EQ[srƢJ(3p<"##… o;i 5Aӓqh>ɟ}}#HEGGL%b 9UWH2VHU#*˂L@n.Fk xgg'n:0ƿ(a]xϦƒ!˷|f{c]* ?KMg΄d?.˥̧̘YS$9cylyr!˗hzWm%OP: Pejժ M<Ȅ7 Y 6ǽHr=40MȤ9b.f_6:}ƽU[hFP5Ka!>dW[D4xpp0?;]j(/^xoB>b/`4|b#ɼILdg_ %Y%-"p Y<w䑓&w]()))$'G D~zxT\8;"?? +:!|21`$ FHNN櫿bsssz z6 _<RXX[owu@w.Ub}g`_EWCH{ bPr"M )\^,MMOX!0eN7#}צmXTbLd, _ $`wWmټ-xQ'#OBuRQQݘtĔ7LI}ӕ>V=U7]b$-,=9$T]qy,q. =/~/8݅> sn|\$fTmʞUg5I&kMW( D斬qyOLSgohC4DNDQX.p/q0Wv4""[7Gw|-jORR24ln+d)Z$ݧ_]]a4^ ;ln575\:uz(-9mք#4Lm!!!\{#As۶mN8ښg[RRBidTjիWw}wށFNŢz(sÆ P߹dbВg7n:>ߥ@xg U /**_y- ǠB;2W]j*CDHAHA nq?YL& f86ten!:^xktV䩑KL6. :'M&*2 #Ml===hpr4`V L.O)9]7WCV+%|eJx(!5h𴎑ڦeF Թsp2tjxjnH2֑gXu}׻_찮O2He][O-4qUH-9 %L_6BCƍ"16VS](ݵݚ Yto,db^o7Go `c08!!ٳ%@'|_(+CCCf9V }vB^SNݻ9 T+0喖GHcaaa?U:6s='|RZZZUU}B95u J%R֮]ϡpŊɮ]DTj<L؃cǎe˖ߓIc\z^/?O Nu ~_E@Z\;x9 atΝ;fvD@PTL&p第,|{\}b]C"ΐ?d:R@kHӍYCcamvNPׄ+` TsѫL\j׆$XO]ftǦ t+F?R A5%} L,]968dĞ(̙@U}I-5jhnI+_00l%{J 'wR/ ] $ڏbͽ=~]g}%~~n} 4O,` [0IO 4)))N^5PsrrhcwC~QK.5553RA$--mƍk֬AϼBCRQQQQw><4+"(r]wgACIIIfC/!AyzUEѥӍԪU(<<8 E!I-q :;!%?堣Ϫ8e"$0#&jL{=VzL_[AbZr0Fxw!fj;Ll1{ɋvW@V$5S#HP$WomVhigCs{>OQ\a%q^gܥŦM]+|{\mn?WjRlT;p|lT@K٦÷(*Xu4X#\:b\s~*?.W]vrvwk_ظ5w?0^mn))GI6!V U.2V Ju;E696FlQDH.q:¤"Ŕ- 5rz1\/Yp#DIrhbp6 u8sh~1L!9TknpD"~jY2eREL* )}&pEV-K.]'ԷQ.ɉ= *N%~7:G/tK|R󚇫&~eݚyD@Ej")U7>AFkm)i۳m{VtQ(+sXDIK4<Bs%Ovcc#k?;g1j`IQIO~~>d3K$6I\ .9!)-$d# z{dd|]x4gk dq{P&  K>S J (,3*?`M*/@*d"Z\{XUH&u˶ضer9˩)Jňgڠ'ﵷm\$U2cd(by{ԒN2i5+r[)OI2R[!>2*xm&zPR( -ixm6JC`…OMdo`XWrR좐j'rGɜkБ7ž@wdFܡtPNͦb#H52fnk(~s ҋ.fO)drJ)QѴTJ|.u=8b,Vma_6=(KeɭWPF% /rJ?/,i7O Tq1/a?t_@Q{eiUãR_{r6b61VPpp0'D_zLȁȈL&'d }meMd+1͞'| |#)dFYul^aev@ ЭԂ MoW/2)s D`J/1v;*T 2zln5*fG]i'N?UTFA~w5$B)f8=Nlu[r@*WXɔ.L!r zhUI@nPBܴqXʮd穞6'Ď(BѹOL?鰻RD,:X1=˅`ѳLS$9ͺ31Ǹ=g;s|eJ-40B: '6l~` ʻ}zƗQ,2ˀMM$?0{tt`09 D'f\-]uuE&~e| %IK<(""e&Ox8~K}cL!a K *8( ;}hZ(rlԪ$9d(x jD=am7/D 2)$ QRT.UM;,1HL0!6-H r%ӛM`u©RqWfeypSD#RCtuyɪiDB[@Z.Zm#??B1~WkxaR3վOzz@զXM=b}0Y" P>dU`v^ |,cXV”9ض)v^C13ٶ=iGO]77j۾dK:iٵF&ضIWbjAgҒ4FKɲ 5[3R|ĉ?ض1j^I!@\HX\o(hd2jD8ZsFxjMV0/f-kusks|ot`بΫ5أuNcπ0:VƻGin_.f8Wߝ$>]\>NJJ +k|;F+KA m}5x'-~1I$] а<&n`̋î6c*_lնM ۿ͙K`Kp64 r Wupk=%X$=#o캼4.?k %<ju쟼vkٶn!/ŋNL*xŒFOE؊ȘJCPfԂ"ٴry5>N+`4bX;J)`mEbfKya5$CÂnI(>W)>s t nNbvvvČ︓Je^_>qDZڒ_l_+0&l˂~]> P*UlTDDC^^^ yfͻCwOw4 q$`:eɝ|bW]ո*1ZsW(ՕlW_Á=R! ̎f1 =wՀ&ɏ=<88lYw *pZN{{w}qh9f~44`~~[R9slne8߶RRp_} "vu}%g欧&E =1ɕֵqpZ] 4[֯KnN-lL"3dAf<^1>><44f/FGG dmmbf߁qڂ_O(F9X'Ѿ;;yUj8<\9)Q?PmY d'VOnTF3Y"'8O@]')z*Юµ>&sGwIg1kGLi =C0m7m.6Ɋ='O߲ewfMן'k⣢b\.F'!|U|oo 0D6[!N: a1c۾c۞ױAHM@^fC;4O!afB/.O++eYYЧCB8-2"oG]%?&dд:~@ƛ`Z-1Qŋ {H" yJ$$O!JVvz,$45+Tj^`!~ "fKJCC蔩`%h٬]{ 6TVV{|N{\M,=.-dfMjr`@;n )K\XIVy8tZ!)Ge2ؘ;>p`_^^Ό#AA%Kin~. !dQ2;E3d=t bŁ$J{⊑ (<(X@%#<\mw`D]ʉh<w$/|ղuR`¡@G\,Oܺ;< [Ҽ@>qAz@MZZgxxN~!/#*䅋cZ-f1iuԁDS Ţ;s-Ʒp=z9///LVlk݋ ?K #G]Lvˎ}T ش2W<ӈt?& }V_8#)3))j{wϾx_qpP:,C ɷ=aB.[[Rr3ƙqq Sj$tQktt4gddB/+;? yVh5*p_W@F1"p$ :{Րbضg>v] c;:2R[[s=c MsC錍S94gBul###L޴zEN{pDl'/UZ4uuuI 6xږ0bnV󾶐J$1޶6W@:ض^PU)rm5Ut:bMmt(zoҘY~W~40Kc]qoexGkəwϝ;KD!2ӯ\fL`m</?BgUi׎qx[b>64hsL]1%]-|Ą퍏8w?/(iC;aiBŎ YKX@xhp~ *z4Qv:F'?hdte~~kQ Ub4;0r DpZZb1- R!SK0Vwv͕>Pt"W`Fcr诒aD:^ 9.s)w_7+fČKhd0@ݠIܝ="=e~RkuP+P|EQ&3e2{L~*_v9hӘLN''6niƟ>U!!!- .H0(f&TtX.Wf^HFeYIa{ϖuTF:=NGg$.o¢: fQ ǶD`*W`zϘ^yi&lz ( H1,%y g@lۓǴy0JdrkFi4""[O:vl#' K%HCԨ~8d_?Q(`LS&CA !T/x قLg5!mfX*Ch@3R#Fnq}!X$e2v dnl:fi^el?,sIx5\TƇ2^| d-[ds >w"$'iB6t6mٳmb=!&zS<9M$y3ax f7g5 g۞dT𖤩 4m ȥ.#WvJm(E-jstI|GBTK7 ~r)_.4b;hhߠGtH_? x0$ R^?X&"~ rNmv݀m %RN'31,vGkIj&)A.dFmہnWC3]Yv='ў?*WYY v*yNV R+mAvi&MbQMK St{w ] HW 4DP6!8*BD$ q1q y<&X -j6kZ DRR`++UV`,#Y)=`6P`<^0dj=3E^G@D+A!Ax AK Su1W8"Ct~pNuQVVƆX,mƓi1Wı7M ˊHܸh8cGm׍-7S'(j 19P(`Z!$m2l⡴ !v{`mO`A$ ,j -@!А 700MmFh!ba@19I<(.f4 -ENݝ! ]HН%Y 9h?=*5O)r4JS*7?$`ڑd܌v-pFݻ!Pf(?EѰ:ا4{X`y3 H}tzRVb`gs۷>̼|Nk#'ZrXJJy`͆ꪊ,GKsl{<~ TD;K1 U+((ЌT[oeoK}2]8t+_|*5uJFWYy-O*"%t˦8u ͛7 %##' /)%$lPEӈ@A> ŏ٘5Pztml𦰴M3llevCJswNX[drH$eUj`XxŸM-u%E*+G+)4+MM,eM#!o5(Bdc-lwU!SB$c.bRzcyI$!Fd֨(]:dڛr-N)ZQ:X+[4XwtwZnt6*瞐x]`ֳkfSЄB!1mAď>N}޳!Jh)rC%v8܋71+|eКME7+vS(M΍,RSS;g<plgϘ=&lB!ଠi#C #hga0æ$>Xn4!f: ;x?|۠N#9{̚ :]Dmِ#jwlpImv q7b2tg(pa-+$*eTYB 󛐖UmDя*|[?TfrSA% w9 Jz{{wg֠ض,xT\R)7;4dٶ'-;yyyS%#+!c5X1bW`+%%%H9m f4dtRGr 2{\GtyP*p{jE#- Ngp$ٶC!m_11bĸE!xDnE"wuJSl0y ֫Z͛7cCCs6I8#F+-?0'aJ2M<֕TBz IJ!Coxvfp01,\.k󖖖ne1`3ho}߳*.B\yVI-?jӴ;J-7,~+{Z #@FE$fAIR7oݜ+ >H8vܙ=888u~Yz}ucjX_hF^ ]JbE]߭V$:_2LѴlC! Ckǟu>͒%Fn `cF z@ Z=?_>simZn$D$c `Jv˪S5 Jq_ojk jxNU??b[/=9H,|͹{cfvݠ= acz@juILZhNS*N*bIc˳>A WlO&>ms9c{jm;hX@nn/RuDN\pJʓ#gZXzЅ_rBMpbn6כm+6,n]Xektgk/hc۱p`Q *C`TWW200NOO[`H\}~|yЧ_BO=ݣ?tC Cz5C;הbhyV[ӊ@4UM,Kċv\q=9?!^ތabKqo :䧘J$ Զk%gmi^eS`yED=>¶%>m兰hn Ô+tq /7nw.}ģ%.8w,bXS؄=Mlcڀiw~@d΀Z=r x- ]h0z ^/TJ,d4e.Yqyb{qƚmeɉw;H3u5uX|a󺄞A*=ܫq=zyaSL%ᡂlgJT.YdFqm S"E]p98_;ɜ[4$08}ܔmKL9=LeUOեx^WhsV#l K`|A;:: Ŋ+ ؒgk9ݱ}Z+be+Rܜi`ʯe[Gd/BvFn!=/i _0fBm 3kǒ'D8 o۷zKL/LD^ v1v |{O<܋<]<3 pޒ$A@q^NE΢VA@:ST p>$ *Ǒ%ty#0$O4#2w[[bYre^^# B_{nʑ-ONAd@ba4RP,i^v77 8pI˛J2Z զwA s/{Ƚ=KZlO i38=5bF{j B(5Ϝ.[Enbb0< VuzcYhci4o' bAVP$p#mQp6ҮcZbebJz A9k?L2.!rl_߻iDn%Ck:M/KӸLrx^ N+w*DO=HcPF(!PBQEb(! :MM] jxo޾jpﻯv~&g1'aƄv6xx'k^}76nXWWy?~1kg}7'W7sVlxz(]Rؽtɢ+tEcZ߁vo~|u]&੾CDz(FID%F`U*J5v+\8w[IÉL ubo6ؿKiIs~KqJs ʃh\y,|7afp6e4X%8f_rbMm$xiQ P?pI#;t3`΁C $$c.D/1ycGx=5K   ::FR~ʇ'Z–Sgɾkmu <^(NI%%N}7x塀rB[᪴k.`6`V]Yyǎ?|}g[ZZ+/|$*O|p5ߕX]IMǫیA^ U]]R*o5^#S``JKvQZ+Ͳ4=.S/h27`.5b:x2SɘKcx#M MmAP)CP .Ao6Tf؞k@xi3Ռ+;4HD0ܚ#£lH8-dz.A͞Xh)ӧ$ee]ؒ,읷>]XS-Xqp,ݖ\.z@.ԝ/1ˠPz=&h'Fw>_X3zL8 ?YaI ڧ/[,+ =6h]iB)TBx.]K76S`Ke|'Sh_rrRVN;&V$X[#jrW?"7d=ky݋"`,h/4+<-iKABNCP-gHI΁C8 i]EYE|Y;ۀa$M܉づRK^d]axǓO|6b"rM:eg_Yx™oBD4&9a FT]̄p, D/e: 2sX(Crدr+SJǺʕ2_&K61lbj{$'MWI{%}3"pF6=JYĽ'JSoA?B>檫*gmMz5*h]\X *J!"ӌS $'ȉC@N[چiHpkFP2>9RD#x2멹)G"!3sJ'#y{V(V{tC٩{7Shę|Zz_`jh09iSܕ4g8o,2m6ZȤ7`!'14aLm?)X cj!G 4qSq'CS3̋2/RJJ4vq0nlHtzuxr?6|%-`?GTAL5CժjDd4MDAsLI!_ QćDT`rlqhi+zLQ͝t]ik-%+UG>>F!X"„⅖V,6 ؤ(H4Ց#OLc]UŶ8:јQTTtũ ܡ t {HBVUNJC |^[QR"`{V}}v @6 |5Q LjQUcUfG\n]tnHvyѺܖLf*8ni#jT=h,\UjӚ䅖s5` &`,鏺a׿^!~ox6J~EYx7[{Z^_ (\ZVz5/{h[sju_5^hSYw.|L=dçDi~8S3BO_inRɋ{ fELF\iY08p Oijݽa&xuZ!pd$C>x▯bc?Ml&5?%bqBţxfrsl]UF %}%f(9d-{72'ckfwU_y(;ayxRMز\K3*垖{#C$|REw(;;;n B{RsmUG$}9}-/_w-ٳI<Cه;BW--%՞6&ZiX5+API[F ъ/:"}ru:5ghh}x(:X=͞.9sL Bϟ?xWTk֬IMM_rhr^[@vSXjذr'=q f=\jذ>3ؘ$TDxb%n _D" 5#T^|/}u[A0)CXA gq4H(xlaK OpYQ^ K*6:#Q+X,S1as<7`4hzMPP&o%}m'_gI~?ٳge RdU]'ַb^Pm&U i3XܾA'$P8"kOτ`t:N;|j${{{Y>^SSs5p0--mv@ǀ-gn>8G{{0ǚ⁄x)gv_ܼyxZAWxbo#ek *i0xv0uoW]:wZWQS3HZ xh鿦"FTy.T,JKrE[=AtUaY3nGWydž* ӏ>0l{< ۶6i孷bV4LT _6Fȑ#`e?-8 S)z0!K, ')?{ca0Xkpxz΢GvKZ .y kUHe^ ja$4~! |x*0:."M7.>wT 8}`{.)v5KcP&Fcbsǖgee%(} gH8c8i%L6mZ[HƂAX@oB3o0)̐^;*iE Aм?S3IaO> ϧnrэ ;'rSUJF-Äm鮬3O6, ʌ<ӟr_|SȤ"!? z=fu]4_H "|0oՊGoݲt*o}|H xO]t)  DmۦR湡0TVixb}>_ԬʠkX#pUT(_ٞ~T=䀲H$b_X@;C~dP7rx*Q_ހGdz>"(4M*s2 :*V7K`013B| =oprP WfBAW]ZTbt:b(GםyOcn7] r1D#~ %pDž|/q " ;FB40i5GT #> S &XnԊ=Dg6ͯ?ymC.ehC% ZtSNm۩K(֩yQxȲ5-466*E!" z˼ ~Z-/6>лOzo ED{`C<&N 0:,ty1mS /Sz #,)z{^'(LFbina$I ަ\nX&E᱃0~?S h) b`<&~m|0l&k/ 3!٠O+> H.>Sc?(anM3lB^?P(Pq¥$5-5ˢ m&=Pu |bL"1i~tVTTՁ2//^@ `* jFRj4*c ݎeM3쨆bGnL&0=ܛY,b놣$IF`e</Ÿܿ?d:ܕC\oڳ?0R\Yht\' Uʊd6TFk}9wŶ۽^s#~l Ŭٶgʶ xv~~~S}SA(xW%z>8:v x58> T m/"g۞unܸ,kkkM n5^1I@ x0A~#oQ;vmm(8ڶGD0{ Db4GQWWʍׁLUYY?]Tk\̀.]%ۤǦ?Xկ~u =rСm۶ԘL&{2"X?r1& ʗTtwu |[ ,jWoF~8eMå/ζ8o]{OBy2ͦm]w+Vo'/{ .'uբ@+2biMt&n\>E™\I+)++TyQ&SlT{#ܶw#ns3PSW?wBR*Xˁ >V.[=48B1+r홲m;r asf6 Cq( Q8o|ac0m*h |t>Tw%ؾuX6ބDXBQa߹-ׯ^NP&pӗfK{_gJ}|m|T\}>H$"wϜW[:llǏs8)@=2" F4̴zʕ+7GQ$+;PSq*3|ŜYfm/"gێJܶMDm ,̤@uBҕP,}!T$FK^v( N_mozO ]/0a T`]5玑0/)Q2̛5*@T_ToN O8'I =PTv_i```Dv a {T_bbRc8phnÌȤ=ۖW+_1ED Q@i@ɶ@mu㻅0T{>RwZVW/+DpΊW,g# /i]c_-t%Q2A$\E^3Qw-b6-?-;;Wnm"I4$BˉK u7_.TZ><[=WA0tˤˁS4'ə寥`<*J.O|xrħq`pmxW0X,aDUb/?)˟UaYR};—iR”*5 Lt yzHJcl7T-x|螯@ ĆϏ8p` ^^4;R=ہp" Cս7-0>K]I&IqtRAYaѨ6cu mr:EpILJ, 4m.nygеѭja*_cx( Ы!G`໓BYIɏnV};nkαm/"gl>tLo!RV#Wm+; Hwwn6`dmM%"labhтL+:7фr,/4f?d t.ƄK .ɓLs#*~iSpbVlSm{LpN__5Rc=IUۣk:ϵ 7ohp3$ʐ^jF1y6I:>V}I>&ێ1` ***JII˽nerYk28pXȠy_f[qŎ"Léޡۍ@8! GCY6%Hj1{3l쵄tݲ6$PAn4氩&"T^[b z]w+]0X'y( TU$3Dpz&bRzv>]ugΚǞ;2W!ͱ5MU/Ր.ݴhu˱#\]w'V_=u[9kŋW(OE~˚uѻk+i[HhI\9uhU2SVl)dz9paakwwe[óYJ?vyMPm{&ks!p/zI/|L`ڃV+E=;;;8T*U*<chNNdz 5;i}k5UT譳V%|շmN!-㉆[,<˴rކ'۞]ӌK%*3XV%$De"ҨKHI<|C.14y?K^[TsM&Dۼm/"gl>۶;(4-;`r [ߤg` 8BcHsBWW=`xt1l`+A'%*gҮ1֬.-r[QG@}+2< |nٮh|{O )͏>>\J> yLNwl Ŭٶ㭧8 Errʘ90zǨ!ӟ7=nW<7FGbS$=l/74p9ƹ}?X+`+֎(z5p3& >A#A =Fބܸ\o8pСT)/C nqFj9NVkJ9Ӏx_1&J؛x<$nPNOOJqqqk\2;8)? vM ֞m?D.@=7p"?*ݴ8aPiu! 5Z= 0 qAs|7fۋsz#@B'9ݧSuj}į~H[ҊNv(rn9;w*޽'^inI]}FO(q?=fJN1iTr?~//osdQg㎳9CPoo/pɛ&p]ntzDE2 ;.Arv'BVˆHn ̟<|xcE?zGKcA2$5"M^#s~6 vn8: O "w^ʭmS*QWPb|y_-''xN;cw%,&Ui3R `/d :>8YZ4;O !7IQbDq$iyU 8 6 | O\|KqOކ۩J۶/%ZՙjšPVt4_ݶsǮ)y^sO7ezE(rbSĜMLf-ĺ FH*9SvC|aX^WZֈOq7rE8I >Hf%rIH$XTZܟzaktc lAsn(d2?>|>^v-!X}"ECT(\k5-+tɉƒǎ|Iɚ5ϼUwcpklg/7oߵgO68, 0+xV(H;?a9-8%Ҳ<Ɣv/󘓍Wc"sP5v "{:Qڟ^=˗Y+WX"ߐ>^K]~kCvNPd+!d6ٖiLgwd2 gjbܹ; |JAdx >p8 |bApe0Bz겲2 p1z|_Pm5R_z9Øq =bfArR ́8p`buP̞6=44X5Vǩyl(8pcP<qjDm݁|d2A|׵fog6k*ذzQzl_Ucm+RLؼ7?r¯|q̾gĸA p PѠ,-0Ik|^ɗ>˳/ D~Y;/{k߮,+R'G?tv~hZSw!Kwe[772Xr Q69ظ)n[ 9/3J&~mlp nޫG?>'p(:<?לTf8hhMFg ./xWboǺJ7x/߼ejj 8pddjP*# ,~|[m;$E_BqRY-.iMAК_汅%klXEYY~Y 8pXl` rRiVVlfmk4H4,WDKFƫoL*M?ZxyA#2 hp`$hǴ0x(n-H]U3L"##' { V Kb8pDt`Sc`0zn7aAtvv;55pq. 8p0ͭI:$fr$|qƒ%K_{[n5vJ-S.\r-18I'-3&~[1Et|%Bs,kP(Z>vl6WW.)~_{r%@??fS}!)a.}ɒ}mU(:EۖݧxD-8pఠAa{p랞 v݀[,={I6 ;bǭM:-#&n'uݷ>F,\ -oVA*.Q'8p0}0>eclEQ&NfA~n);RD3ܣ)>8 hW'K7lk!0T߱0yъ9?q8pក!LTSFe973/^b7`. +Wipם{4F! K!n,88')VvR[Uڊ+ĕe1.B׾@!aH3=={#""soI,3^Oç5|ץ-p6d}q+V`u]cj4d C  w8!z}שּׁ,;ZZZ ԶN'? ޑ5[u4`H nM7/I.sKE@55PޤmSe6A VJkZiz7~^@   &HJq\ ju $+,j"@ ?IpD7$o[|l\d^q!kPp2@ hlI"mp6$iu曹˭+r ?vAUZ{dlՎm}l1N~q{ [KҥƑFR8VQ=gYG E0!lvSJq\OOp:M…&{ݯǨ1]ճ-W IަȊEw&s+?:ͺD3:1z3K뛇XmneU.G IEDq0L\M 5k?j5… 3VEEIs,.dr%AӤJOEo6.@qPmLK6٣a!%qqh24@ -2<3,ñ,t1L-R.2Ù_3f+@|؀xl2L@ q~o޼ruD CEEPOAWf^A-Cg}ܵ'G[tA;탙9IxLccכrMZtc0*yF[9@ a|<6wE]˗GcgNym9#Q_Q8A8tU>gC?W\@ y `0eYN$ZN޽{&I)ZN<[Wz.Zzэ g?Zcb@m@ smF300C>;m6[llt p2.8zMxuGYHbxkǫ>>p,(?u7VgpEWmMHO6L:zYs'YlK,V|}BÃY sWB@(l F3z9XVpB$i=9xѳWla;jdkKFO;ꚇ*-[kf`/mݺ}(>2%?NX!ZW/.{>|hΤWE 1x8ъ8I kh"#dB8qJ;r_-Š"Fc1%6yy -r` %# G6۶`l(@P.7~QTZKMoM.o0@ P.$˲ཫrY,$JDwX8βRC ;N<3שx ^T4wN\aIj~'HAΝ;z}>NdƍfyR=o0L혀I  7B JE:zNb Oxch0x֖f+E4I$-y@:uѣeeeuuuK.izΝ9,߲< ޵vobA%I1= 7ٴxz:8fپ E`{o,ڼpZ`g`92&g=k6$z>EBpq{aM߯LY@ Az>q$Ek'9e|xXkjYMÎahM9ӽ[PYC8F}v[ P|OpƁ*Kitt/4N3"" (jo;rӈL/ +3U_y961fGÁwƚ/g`c{m׾nyKV9u%F|CM'~>cY+JΝޱaƪK#>}g___zzO  u>KrܿIۧ~t>9kQŸqZ/f9-7W8i8a<]|^~0 0_,gC\Vbx8nw77=^Ol}mO F̑@WJT~u~͍\mfaK`Jixz p҉KنN!g,Jj(T׾huZ 'sם с>̼ W:~UuflA3=fsy|Mywl}ƦGAa }l6AIlNJJWVA) wL`}`c1M[/nBԄ8á%ru?֘|jr'jCb ܺ>cٴԅ;r~Jq>*āw6Xc5p̷o~φڊuuuW^j[*Z2 x!s˱ v{tGWWW{{{MMtP8&jؖlzQbض!k7߿ikP]Qxu1t]ksz5.u٥6]1M,|JTm6e*1-Tbm3|JYk1|[Dt|A3Jm)9KV/YW#kO?k02sJekr9tzFn?4 _;wR2{5F5]oުwp\AؓA۳__jQvOODD>>>PZڧ'q4Ώ`[L۝U٘8 m&% 쩽{׿$V {nɛl|c?oN{5sQ{N{UGU\O75^8gd-?拤-] syǺs1*b*OؼfPVobp WĮ s?qShN 9Πю'XS?^{KKK Ƥb{oHYXCϞ<2%dX3h%vmM } +O֔r_w{u ´&,`iU% v4p e}Y")8ĤZK ܐ}Ϙ3/)֩%E U|ҷbICCӊfk˪W:~$a Ucpl֒JϢ kn#q/G RTɆ5w/~:TwGr3-ݦ%px!>-٬LO1pT^IKaKKJ[3P1h3=9<;;s@UUVV> V21*|. ԽKAh]Vnr_{ͻ2_qJ3ƍ\^S tyYY҉6F<*TkA$<OHxgqvQQz@MqEܴCe5bp-/+ ) D䗅EZmO!I@k)Ɗ Řbð`3'YC=ٯ ߷[-P7=0SSYWAUXZKE5|_DٳgK_<_?? $rj{ B"Hn9t K?X;vNπ?;dN344<=1~!xlc#Q) xC'LLL>?Vu:hs)t:]tz&HaDZg,޼SgN70ch$!adVxXvaJ&D卧$ŏQ^T(Z). H4}'@,bo<%)1n|~e@ '11Q3FٰsAR٢iu'z0}q +۔8 h\@ //p@a+<&#@ Å; 1wg@ >/b vs!67@N|?wi60\|TL pq qt8w,EMNܗ#SICH_SIǔm&~oujCV"UFMكCå"S&E%,=S/Bojr3'`aŨ[8iϔ2 ;5)8RjNJs5`h\=W6Gμ2q2_{  Z%(rEi!YfnPLN8y9b"EeX֦nפ'TѨj>˜t.C$Ҳ~NKpQAC7!a\ig`V1Q)/EiVjY:^H'TNs?T ]/Zj0+ܐXiof/T7OoH349G\NL 8bO)$/MgYs0$qYmEeOնA)~ .*++RD6jTI@#Xp*UcA1E DI)؟ߠ$I6 Ik&\.pԤ?{q.% )N,f8dJJJ$:IENDB`sardana-1.2.0/doc/source/_static/snapshot07.png0000644000234100017500000032753512174204305022754 0ustar cpascualcpascual00000000000000PNG  IHDRK pHYs!!%IDATx}`Nٙ5J UQ^^on^x-+" D 'Jzd{CBDЀLΜ9uss9!B 𧹩_("D{J8yM "5-+"Dr9׭^߫ 6 8!B MӇH.x}T ?v$.BrUQYeEA&caA߯Y3yL#"cZ-0tU7 aiRb2 P\LvDEJDm5~v2y^^~a^OqAzTv8>tZZZ돡W$Rav 3Txn8OoWVƇEZGv˃wT˰(U7"BVl*Յ&Q(eu> &}'wp i0(JXdgp!=nwMM/!) E!YC656J B׷Q~9880j4Y 3]c'.Io,@1D|ȼ$aZ7mX`g mqpJ)ݼUi-he(u+-16oD,CL# sC#%~*͍eiwelYC@E~Z d2}>P(h|֮~O^~WӦNOy>L;vSi &7:khۧe`H"щu_}"*9ozKg?w-}h߁=(QŋQ'ڻ'MQa =[/S(=t(zK)!C#v-} đ_ <r9 8ؙF 1y p/ZUGtH $M{ׄ ?PA~ !A Ll I$&uucZQ:1⼳.*M-۷'z"G7nD~[OK$pV+U2Z ֕s|~ G52FR^j[os[\qN/G'z$I1g"<)S{0@'ĂK tGq8Bai86U`0^v6f;sOhIAcܸcc{©6jHƘb>>#8 ko[KC6ڳåcwy`p_pTp9݈Olv?y:;;+pe˶yőӧOK.m\2+-zٽsgK.NǏعoNk`hH$~y5E@j.F[p̘|{3_Oy<倢(HҸ w 1gijvH1b\UUU!B.qރcOFffsS`RL1]ȨظF ;v(CIe']Qqvq ~_WED!Beɧ#Ky+`yGQ q\Ƞ! q)xCAAR=ÉD!+\@;;#AʺH0 na Cy~ +I"DqYv!B:γ3%ZNR)GE3"DqCw<#Dtvjs~)&uDZMM54uCj4Zo٫ގ pZD@N?ٰ=_o8RcS =TVՆFnp99e{ 5q=1+PWѪp9錈0\aI":3w_A|IQ@^?u{v}.?76[SP0Fn CGV8v`[ؙ8KK!BD...oJâ#n%gk1Xse][fRaU+9]ԟrDmV'ވ7~ \" \$q)FS$Q^3,$$&]12E1H7\]1H;#bz'}5%n/"I#dMu?_NnmFqcuu!CHNIz{wz⩧Nw855L]dI߰Ma}^A%6-fO.=ZSRt vok\F0ě:qz$Y~P.':t2ÏW|TAgl8U]ӷ3e;t`ZpƂæMG?S RBϜrD@8i*kA&]em !-zۿFĞ,-+)>?t_});'oŗ5#=qúKHLfh*<"h߾ACګ_}h˘a8!T(e>3evşL;}ֳ0쩆P7狓tgD!#;j޵lؼOF/x)Ě-/؈JL땐8H"s>/wSSS]mcO>/CƎP Dzb649|ƅkDlqeD#_sΛ626)9%44_x? ?p3g͚soѾ=773p ksJy9}"DYp1 GG^p"BVk޽ NS#&NXDtV~0bsv~$,? ?j`8->?2"8!;EUZo=S~&;%bXf{hB>!ZV^Ƚnqn^fde.9a2@{$fRi Ȩ()å"n.3I`frFU\t`Q,=0lPt ?Cw!92mziG01(8w}rKrypLJ ,. 0-E1[8(E24"oH*.04M 2gg :Kp$gKy |^R}n".ŏ;ƅMg[[Tˤm>XqhY܈nvXN{MKiJ*u9l;%"Z7gdpXtu|E5JnHr;R6D*Ȩ˻2$确F7nC*y(O>'S\,B˲c3w\ 0Uȱdq{4;+k2od"D?y̮.?X{) peuWtڥ!Bį\ØW)֪UUW,B݈kDWȔJehxy>D\nuq\ccq\TD5k"𖕔H b`p754/~2'FOp ̯xPD«r^Udu}"1`TUս"NϱŁ sG[;϶4ܹλݻRCBP'rժ$By?bg̹(*ĸ J(z 5Zd u=RjZڥ^x:N_eӫwظW^zqٽ71 {?8jrpO5hǎLYs{׼oCBV|zifE_SQoN;[H1, ohYnF5̸WGv9QJe׮ENwK$zslOINISFB}gg $D{i|3;#a9yJi4lߺmC S(kVR(s{_ q\;m}s>@l\ܘ1c׮]CH _av'~HO= _~B$m۲eAoKzS8YVVS],~kĤ;'N=Wq7pjk Bjlj4姤O p~Jأ6=5hDdVwެES`!zC%8N/Q|ka}S:<8g6-YTTWn_ E #&JD( &KxfAKW_~?[Kk 0Ï՗^6cuwXX_?dǏ(r2"2*7/s!X c ӵY$/Rv*RSt\ڒH( @P Q:Q65.>~6U.WrA7OZ?"2rָ / wV=!FadZc7S#"omFƆ@xRb0 ;\Rv; z%Oc떽U =8^QY;lh!c'>r zPM(f|8ձjDƧwCf(Bp'MՕƚȈp ?3GεkNɱ ϳ"©#;[ fSA"n.5^bu ͖v[+1JH|5-3ؑKsh dub  +u5aB{L=z$cM(9x0%5"WKO\&#'MR__7xp C= b~Rrrw<S'ϖݷlǟ|TB(e `gk r7n-AP)ű;88S }F-S_!s ?q]Ixv2B0BUUU,BN`$'Q00bI(͹voU\rM=vGj/ ]v;RYfڨˆRVU[[jjo@b[,- 䶵YB#y{B aaa¥a:ↆO: D ?,"",yF-c~AXB@vjp/z)ݦ) .(\N47@ rW28as^)C|ƹbcu؍L:n ßsɂkMgsZ*. "~XR 5   83pteRHuvQ R_q9vxYKeYh|m0U>W He.w^uM ^=!!@$T d7[mLeqq :| 9˱.n>` :yBG:Ҙ},VOs|y -aa_pR)rʞ_~jqpBO6|m4FCN:79Rܔ`P4޾֭)pvEԛ:'hbښ/C:-4f.#_-;Xa$ ku:dP݇ѣ~2)D`>oc6yfS`gQQ PoWZ>Ty^Y]뛔?JuGǥPqv81O7v"'׍?MCt"kIrRZK@8 ľ=[9iz7w>.lah=i Pk"~1Вk[}\7B/-IJJ9.DySo84ڌ6RPK*y]M6\sk]NJpIw{st;}O(d%.]x' @8zd4bIizRD[--a4=^LEOpxRSSv<+%~aBy >kR7~JݝSKV4u֗ߴEʑ4O͏'}mG5Uy6 WЎJY#^6Ez깛_{+a h_ 7"Dtp$7ֶB'kꚬWzuڽ/""FdgvS z%޻ˊC_K 8&jh̨*2zpw啖U[adTLJjvF+uD/qPUYCHIZ27[l74E?fu]PURؙ1^w]Wәu]k*fimaa/=&4=߷XK^)}d}?]DS umT"7g-|X-;\9qßn͔/nc2irU~ojS"|$*MEE)8XPНldgCV.MaT2Tչaa{*@1q5y*-JU˫>cR+ƒr~g94E;3)6k)!۶?~X|\0 ܹүos,M3*,,Df֜ ٠V_q& 4еsӵc㝬]!``AB…e⢆ U\|<)) (#j[KOT8NR=pB\Tyw!WM[˩NEV|p$OR4GXˇHzzH]kmseRdYcTUH*F"ru41udyT5",2szzH؁vNvl ǬĄ8˲,I BJL=_9+dӸ/=}gK P>*)LPʥ$EUġ#aF[;CHWZ\;Q;:@ܪA59<;cMS|gG`ӹC= ZwuӖۖ>m&P""]L7)z:[gN~}{&ph~/Y02,LʽIwҪIFNonqT5Ma(.x<h 3ֱdxXggWV Ij,KQhQ_i ^aT2㝐j{Ð/T;pz!_mDa1/^8G;N}W Z pj쳖.s2D$]K Tg}lWa# Voк~m i !RT@wuWX3$ kjjZͤnj!+.6vfY{|6Z8 k4Z 8"=+"Tramu[lZ7~EݭbmLk<" 2) ;fj'ӱ!4Gs_ޭtwS|Mչr{NomU$2lH]9e# CAAjD;C )-'q Ekz";q_>N}G#w߰67;/,dy.(t2]]j g.O"S_^p(XuW C $S6vLdqR N4J-'$,6g\ybqFJ0I!6E^P IDmun&P.%C T|wh)%!n4bj8j|E ܔ-ρ<4WtA@Ve~a~:ᗴ,c0ڲLk^X_X܍T`O K*P^]s&,Hʿ!BZ9)a虳{}>`H |O֐T"*\. .E$1N20=) ڻ|r`s w$)po|Hp$1]p?A` JOٝͭ--m۷(MJq6O~NʕfΘ@V1|-[f}ᑰ*zlo3t]/zXak w$p=w$BkcgLtZ"#.+n6Ӭ`#c/)8B"OOLMƀN_bb z]O )yƍ1ZlPNf IJk*SRbM]w27_;.O7,_P/ʐ"DܜN]AEI(?=#u]b@1m|'qÍoOy29s>ݏ7P8؞Fs;5QQJ2 Kqw0MugQsDEܳ5T5*O /Y#/L$^k}OкīOS[ oӋe."A~0|=(A7{BmmCsz{dr%VS*E!Z8Ʉ ҧϦ &OP(.McI%E^ ~琯xs<{L2+RՓiu}f^ Jx"{}˳ÐE6?~Ʉ)}ރpW 5Efq-.:wǣ)70R̡by=tNwϷr>QbP,R~V /3m-.FaTj}4(41۷mDK<R (bMo>W{2-%@oaMs|G`P4G9X~"@GOl=G#t2cv%\ZbbbX_>y@I߉"u. ceZA5!Ϙ`g{SRO\B!JRt$mX "~ d߀6$0V{#v9"; طp.HPG0fAym񲓇KK =z,ʰѠ?|߳vnQ|uQ\l(c}$JR5wƭr.˕W+OXvf.HON޻iְC鋽Er~m-ɥţTwPUZLFNiDK?M9zQ*~Aٝs%ByD5ѝLQ3v5Ňd4\䣇[OL4{Yd+ٍKNP,__M3|ŋu{9jL7V#--SnS557<~42dsٴ1"$,>:*,vNIq;W[7 Ϋm\q> t:c Ɓ 2x]1XT{f*0`qy$89D E5 T@@@8yjַ 4ގ j0^ n(q҇c/y_BFhJx u4:Lq36AUq=fh/t/!(iL(-m5j%K;\֊%SZW[U.7'K]!#FMTH0u p۬֏>|h43yʲoq'X,-}dي{jNnll۷o{O}ݠ!l;-h)ӦmXnQ7?5@pǸU)eLefhƜiD$i:0,Ȩ ,o}ANMoF6=D}Y$n;dǏFEFi5Z|oêkΆ5It^_ݻveefIIRJnSO:A0> bjJJ*I~^V IyH U+22yE[ e7?AC.fsN0AƂ55eH@=U(+IQ[AgW#XT];Y4TX .'Gfqh{JYH[ܝ[{ BA$ 4h֭|QA3fC€Rk~ 99y[[dd)p]O*G^9o #+;3+h__Nb. lU[[rzv<` 9 /{L:sf8>睒[ @RޖT0C3Z[ oez2xu 'ҳ(,B-5%&IRz\.;\i74>i3g ,\BU)f"Dt/n;奕$eZnj]qwX5E9"~AX(/Mf8TvDdf父D bg Àa)z?'#E;čI\N)2"<6&]RMWH"D޸AтT㸞zXٙs4忥E465>$HpH8jP`嗱V(MG|)[s.WSScdwlp|6\<}3v i[Lvsl[[gimkkkKNJExuPÐRqWt&&&q ؙGDˊLr[o,xN_rߩ^gjLnxY %5IwD"A(X`ؕXDXu2mt!8'yel}.L%MZd2BJ  n?' ~畑ͫ xO2R: w3.aB_R6x@4MАo)x}"H(Akq,I j,xRB*ɯ>qIqsv;oUV*HczcO7~vx\P/mlh쓏^}E^s?^}Ompk禾o5d:8Oo5)_O{+ i^i_(ƠtwPKWu&bԨf[HDdTMoEO>У33p JCf_BS٭G~E_<kp Z,a( G#s=#a"',ヵ+ !O?n2M&^EղdRg@\ Zt,?5'*Cxat6m9zĈQ11L{@ @ZND(בp ݞsg32 N%$8:55M*>bӏ-?ujȰf:P2H9.H+g͞ۑ>͜@hX \Z֛$I&'8Ҕ;wl?``G\{SO G&p?ε۶:Y 3'z 7So7Puj3旈[ ;W;~ёN*l}ࠁ%k\umC7:?/'*&N G/4=|@MLc<neɹ_G)O%DӞ޽g0>& ?)w$&K۳:Y"# X3F;}EYO ^yi>Ĥ;ypIqhhc/\PN1k}r rr׭.9-mP?x ;o\&=3;TYiV,[v!wx!׍p/{^4x"t+ۑ=ÏΝ1U&EE8^x}ZPϾ\ɇ9[-|11 Ӑa#J=wAqJm*nmiٷo/a{xGEEpWFovdY9N2mm55#GYtJ 0yY yyKYb0 0>{N O C3|e)tdQ^~jU;n<1ܼ7 i>G#o];Oo9eFwVzLx^v y5f!3ކ9O?g1y w+['5#'J}<$QQY[أ456Y·_[Wg-?_r9?`Ta*'[}hY80GrƒY>-8 rL$NN*Qե9fȲY B.\JB}=:n.en!ySw2E8s23J%AHye ~@|]ڴ36zűLsScc@ '^>}%vȼ:UVIΚsV{՗Spd!ŀ &8ν>srr EdT(ᄚ3 UOSC%BRWrr8 w=# !аzBkvڮQ; 'RD*Ce.v4w2ʐgB y63=I }BoCpZߍfh:'8{^Ǐ ]-򋦆d2x! er T{AAH?դHxC%w88V-_#W_|T @VVsTSSC]uutl` 0Bz~F-]|RR"$%,@5e$ equ0Ȁ$3PP 4;;IHHqFppǀlm| W>B.ZTHJ2{EV70HΈ跠#I05_@ەPZZo!C8)o9=giccye^}@JXmꪔԴJ6JrRtE&@=fxyK;{rB/zw Fi:q JRp3㪒==}[]WW$Wk!N}?.|gMK 8BH(wM U҇;qd |2 Sj/<aa@!!'M=N/PT3gq][t0n܄*Vb@d@%2R6qdǫR*̽B i&t< hf288zҤ)8RiޅFcPNN^^~~H0oՏӯ\AAAxx3PȚN/d͛vNUj98/{C *cB!֨AzA摑Q KNNUUc Wj^(&<,;p@yR^HO =^UuP*(ISXȈHjaz;V='LfZJ1("#;J2):E~@vVq'G>&?Bʅ`^ q@ޅ}5*L>< Ĉ QUA4w^'. Z7j{qhD4Q,ZZۯ]'Jv0把NCCct'Ƅ L PhhπBN^6Ϙ9R$Ǩ U,KPLΫ!; ֑V87.*B ,H$:&FpL" D(ε:Ne*.lv ?ePL "yv`|:&ᎇґx0qB#"3 (@SS;'R-OK.G^56h6drF{tZөܚ e}C[Zgfq٪ cD"MNEV7jnLJDFFTUU3ZXa!JUuM]}}=011樯Yے`t<>s)P| b)0-No5李J/ ͫHǮ9].Lc9#)EPbelvV|[*a\.JXqLi:Z,0rO7h=SsVǣj!J}MBESE+צRظZ7;0:n*c۪%TbNGY).N0ovUc~awl>uS::(Pʘ` ͐t^}Z`E+#GUN7%.Q#W^/e`?`8gGuطk,OϘ5wȰzq2-?luxyAI* !}91)a %zu^xuÇ#"" Jq/|b|^JHP)+; ah I9t.ߗ YxߞݑQ1M͞saO* 'sǏ;~--A㕮tLH6,V`GZ,+5ڨqj7ٓ~g8g$6祖~88L  S65#e!!?ˉ̈uFѨ `ou^^IŽ1h Iy)A3N",rX,TW޵Vlnn"/`_ :>z}tL{ sgr{^m.:%vtZn-Ν0 ! j𪗕L>SVN E܀ŋ>)ѳv$9h;u Fminr{vlbن KKu,CB”*Ţ? 4wv߯j5? ѳ޽{٬EDF3/_5S~ACi wM\ZE-]wa7oP_?j̘?x?,_r͜6im##6m\B}~~x!6mxܼܼzOа(#`h8) f<)]}UlLk#G&ݲ ӟ3ix7/@\>n8LϒvƛޖKL B$ȸ!XqѹI3CN aʎ%&B:I`g[ÄX^9P*NP*@XNw_qNO˹y9YV'*:f ԩ99W}DrZ,[R+5<ӧˁRzs܊YY9p_8kp Fѹs޼W\C+WUUQSU?_={ܼaSPO>es!M 0d l0u/ۖmsn~=b{;t[嶯*?*:;+mkFieO8f)rʼNJ{{*zՠj:w#cyq|%썃b{;f@H+H5:g֝`"9#bWKmcpwbJ(4+)浱6 Cj J_eFdR kcUCGR{:+o|ދS\d(6 )1&Mv}[_6oK&! ݸWYzyO?wFpeٖA?aޝ;w[9ھ (Xy͵2,0R]N'TTk,$<{=Fb֙f[(QC0٪(8y GU#3@އW3wTݣuMsOgYӎS}~ϲh4p^0??'b1byDf̜mT UF*!4{wܳ{甩vjt9gϙ+<&Ѥ,kIB֡~ܸFXnZU=zLcccEe%|˚5w?2 3m 9 GRj1[ک?߱bBc4ؾe9LN39]/\77y22$qPcXX}1GlMTw&: eqf-}9, %vqV`;qgN2Lip?s?G]n:!8ߐYy0U26hzi`Em4te05E(K A܂ P hs`􉯉S ;f ܾv!| =f3KQ/+٬8p ͔!'``k Fx{gL:cCz3O:v5pी5A퇿}p_n?~{O 'nϗS1oN)⡹U[o(x8ǝ|3||#YESew%M=Q/Ͼگޥ{.$le#uQq6bjYC@G=0 :;< aqx86 D\' IA+i`]Y>>8o'K -KQp̧ %bR~ ӬֳSQ$:C諹xggPuj"Ԍ ryۻS{^u+Eز\Lhw7^x<v/?y\6C182J雇Ac7JʒLR$v:j̎@orܪ?Fͽޓ,{iy6)گ0mԸغ7[]pr튡zq.kzpWx/8Ahi9d`gdIKAΟNXAv;'8AQw>E hk  ;c84#Edݑ.w-y6dF0aAL4Yb;s"/ÔfYlɺt]Qm"gd-ta< Ъ1GÂ~ZC? 0i&8.7@xhnS#*+&^~yƯcLE[~D,jٰ3}(rmɳg72_w tuu.KMzK͙;jvO?,khF+v / !5bYVʌLg~%믿( ?Y"K}I6vNSUUN#M[ruf +z<---Ax«uDLxϚNEWU5%ʐQB9otf?+;ˠ$! AHpwC0 *1Ք ZL*, ' [h&j,ͤODnPI5@ao$Pwر3wU6./)3$Q :,dCR9kOX՗F,͵MB3=ݏskcH݃z3@նp qPIl%l *""8^ήvIH)cŘL/ͥQLAQ}h=(UZco^y-]lOuiprm8[Qi(cyxUy]y OSAiW6 e ']6m7lH2FYƾE1CAQ -M6i:5K>W.af 2_G`sw0N'qH^h8fX(xtpˉ?M}h/OŞڿ^ܘ|CӫlW7u Eq%68)*E~ߏGp>8_cOt?īG ,?ϬO˩=jřO_f.0pj۪7rDfl8wM$ĺ&I'{s5!t:5kt`Q@a`/WVZKpD\nh q<2ɽ7 DTK~#̥\B21>E/%ɜP0 _?8ݎ?e$FP`a4{61U`ʃͮĆ)}NGEܺ;Mƣ^i`d2 ^dHp2چpT9,vO}c iJr|ira҇cP Ǭᔜ~/P3<ei%%BLJ_mZZ 0+m@6u-K"pl.ehVsP~ZF +v촣2S5N^zeUMwr!!ˊCA. xg**e_}溺pw 3Ŋ&殣r)'ZLg8}BX<,r"e TI(p2gÝR,M_oY4E-?gb+om@9H2/Nx|!D[ B-hsԱRx'BBBy)D rU[B^Xc ;Pc 9PcEX|8ʑζl;YmU]GnuGGf`ÆMMMjAUٳgG+Z?]{_nժ**+]#pSO>9f挙=t7x[o{+~CwSB͟n|n _soݙ|RR s>[ t*@1LPrYî_[Ω48T2TʾHNm;vgwg²zypta܍pnspKE_a[y;TkZ@5<+& ;zהhL 1'f83>.tH;Q ];!< 11ܾ*ѣdeEP:pBwf512* nF1̻9J<2@xq-S;lqygp(&Z $*s 8h$s`*DscN| @D}+oXA'g]VVvh=16^_>mF<+1mO;ȑ{vc߱TԌi]R]9O{E&r;І ;\d[ud3YYuÄHi[ p24 hzu7I1LǫlM{{|*0\%Z!bUh]((='3<2X2vj׷2UC?pɏi;W[k :cjՄwI`=)ϑTq5 {J22 ;P)W&-l|(| GnYvl߸c\_,MQJ 1ʞZ  "^ Rõ7'?íIŔ4m4K  O(@Jhot:b|^o<߾z8g\S zkUWݱt*+Wܼys$iii:Ut>2wq55O=._ y& n\tA4yԦ%Cӝ9DZQeiQGTAd@58P x)_ꀑ<љ70#9Jl6\w錂!JpONtL6U Hf`s}oy)]T/ϜUxmU*b8VQVQ'TwLFLhB?Vi/}ȫeMxq5 &wߣ\)ڀӧYDqΗҼsqI~/cȌ(FOG돜tz2d0T4t:CxV HeEA3f|Qq ޥ${_[^^-!(I[Pp2h@%4i3̦ G}e+5ch-9)aFy([L%S]@|#+q.CjECulEEEq٬tHvn4'/=[AYDF@s@3v%gL%3T8gU!3%]0̄,mL RKtA")ٴRmKfL5͠qjonwFɌ1u'mLyySkW]q񒥃5[ A*X,/#A1l]}Ŗb0}Wy!JJ1kHIhګiaĈdhqgzl1Ŷi%e@ zeًg[u]*2;kZ*YF~]T\c >͖hǜ3fPן>qNAKOǞg,>꿋9.JEN"#%f~|L Fj.JMr'Kb$1/k35)Zbgone!0=qY]u_`+@ޗT㴒]d7r_<'x>1xaU=(pK}~^tZ:؝Y%I9B1ʑ:5ߊg  _q)ͫF#F%̺|:r?zo%Ӎ rՎ@79nf7[H.ѣk' f 8L}a]CCI5Mn4 苲p\gg5x~d-E $g F9%T`.T(Mlggg?kpY?c` شi˩. ygdf+JK=lH\}#[;J%H%3=,޿{Cw~**i'1?D?/gޥEi߻g隚ӦO>{?ȻowL(uI.XHQt{[˺O>M'3h; 4=3f lUs+j*OcHD{5lϝeOEi9niƄΘct! RpeMð`g 6Q#ȓ 7ζ Jļo8@kK̀|-7\koL<"֋^xba QjQ(6tӊkoسke>K 6H([:ͻ=.c<hoEM6l@oh#p=9rQrنI8F3;넫b=ǹ}JZ6M-1<6R$nFef+YVR46~sigGbx2~ɧ Ƴ8>8ߙ_ >ùYu-*҆u‰ \ bmN*" o 󑌲h8oɧFޞ_m^&GSˎ`IUXxG^YgOeyKs*l U#edbZ:Md$L0T ˻Fag;Η3 |4h>|e- jD ,[I( /j B.:ݞR4K!upL*k7r\lG'1\uЌ1e~qxycgMM:Jʋ+*l29-ID'g2v rK"& qhF.5ZAt.K )apF#0c ׼;tfU+ΛK/mڴֶ֋PCbPiTYO"t: b(+g"gMƖ༚x yl_MahA~`ZZ+=wܱ}{G7/>N)٬ɨ4&5 n.x9Y Wq&<">(8}Rwjh0ZH3K#t67}u+p/+mGxAy"޹x2D-Q(Dj%E1qFL&RhXpG6'Ź5Ic˝(ǻ< դIA0.㮣HvmaPk RA-W%QJ7E  +tSȣ`9NEHi#hȃ6#n",j.fJ6AQՌ `/PC-!IvDH -'ۭRT276#e$%'e uV˂ibJ>7.}Y? EOz b[TBqgme&9 |j2[@j0R=<6xΣӫ"E0[eُ>C" Bis((&JCn ,Ty wbMJ ](J:FZUpDQ>)% nѴdEL.1RjΡm!Z 7o᫩VDv#^` t͔?*N;-!89/;ڢɮ:)L"qjb lD-ec=e |S?(ݮ{sJe+!]:Y){!l|my3B~ˬW>{bqD؈6lVwչ Ub\n'vG@Ufnt1 .q nN>8[4w'5At Jlinr 8AY >^Sq~7;Fv>nO= 9ojd2$Itvv r*@x5R&JU6VFN掶an7a$$Cp,Z3KN9QD#H`#L^;S(Z rSA~}}SnbB.ww{4 bW79ݾ"p%.C:Ay,?vGfHÅ&2cav7%kU9mߊT ՝.p]ۜU2 B=p诺si<ˢ?F~wn)м)}#1*R㾟 8:7/(vp }(^Jw`qF!]*^Bl4[ƌ(I62X툗R!oh$^d1E7[-]ctQ fVlA~g̚5idUs?m ]dFBy3fUs+p*JKi6 9 QP395S"*Nta5p" ҍMwdTck%L$6o⛷H--JLPe~;.eDPv|=q,;d;O{WNx RsD|agf8gMxn[R'YeJ+TDQ8%Tba%A3Ti%it})G*˪xBr9JUL j̊kQ)J$%'(Ѫ78<]]#qFN壉P`oqlKCprz llqB4&`ZDǟWm4[^\؟}O`bmm) ˫F;衇ȿo.]V|Iq y}~eE $$08>LZEX;N/婐-bt.fUl8֖ƨ^*2]ۅǰ ?nbFfŃcǎőO]ʝq cIwa'U,#(Jcv!y׫Mt Zo2FG0IyTVP&i+ۚǰ1y@e :/J#Ӥ:*eP&0s>ŮYi5Fta1 l`rUUmACCQI% ;Pה58JP$1|7&c&"EneRv;{ݻLk$_6$mIwvlVl6sY,(bd_HEk8NS͜c⒨" F|!a ʊkg;dJȿM B{W;ؘtv_ g IQô軦Jw;'R,?xK]^VZ "ѨqzWW훶o'߿Xth9|eKASt4hHȦ=lo5;{٠!IaQ5H:jJc8e 8iU Ps;\2瓞<ѼOM gӘ>WB Pтbg?+jXY"@n[ʪ,JXI(5PД;Zp4q)Ͷ`Bf'hmd>H\۴QP儊 5{w2mF^~55i>f̘I]:~_}s]y\NINh]h-^~' qvY,&BGaUѨ=rntM9Pv8f`]t(DtQ6)k$X gv˩f$i βJKUL2kEth)pL:ܩHˠ FIQ !U4I$1otD6bxsż7"q$(I^J!UI*Db*͇<%rwg}%%WL* [t= \p[5I!y)@[mۺyӊDGo;9w;;H<Iо%Ze-ev+j&y,k(**r\$B F ,X8:t`tu5Zl^Œb GH0dV+Y+ƍl㦪Q}tU(|d̚O3Xs[1!0%KL3qs?Pe,ƒ)^rUP*f[TX"M3(pF01NKrZ80 n}'|'J:9%A޹- 'n-­*ťoʖegFTrDETA(XWa-'cx_qՏS^QWx_zЕn? >u%;Ǟ]}={v_}ͪ`kƍ /5{)@Hm'[nѢb`{ )//i (ޝۻkMC ٻwWAQṬ lZ me[讚Fqt}{v%hqap:loMvǚq[QYUZVg룑p0eXb/l1M޸aæUTTAr O-Sce-l]~Aݻ'O 2c_y%YUC' ym>O$8yyr:n}F@Fխ&7%?tE6VPo5L /֎>}:qmXC:*x3|FW}ˤ3nߜ,A_#9w'(JY"\ ?\eqJjB6AUR4͇ (>ŭ݅ӌ*ZU3] ) b FP8E0U1Ձ3[Y%K/[sG^XS}. N,@FgVϤ)XiVĴ[gqf6BeX17=b;-;5 ///3.Bѣ<m Av8y3g!5w_Ch`Y*U4+AnV ,VT‚W=gXs=_۝$IWTx<6B.fU[rɼUn{ߞ=?xGDt` HXJ'ǒW sAeˢ-UQu].1(x#(2auPr{OԯzIiwe&ph{Pr)h"qЦMF,S'Xd6hE5F#a+IK|8YU&ns2(kiw?֍wMoKZڛ9zaXnjH#ql ,p+ NRf30vAa!KKˊN\cޥ1c'@9j[3~oP>f(7~jTUߏ}p:O?7bhP3O! c1 @[ub'd_Gkc2촘.Ke([`EjmmK@.Cc "O^x*G{d·l0l@i,NPaI A Ncha 6%p7H;1.^F n2`9B,6[%.= mDw4.;#w&#IQ@ٌ8)|^a7OA_pbz>K={.^˰(Zz6]wM:2Q6<8fa67ȳ"dK$e3Y>5%]6Ȇ9A/hZGPʰ=RJčc* -4٨.M͓P(fN1*M9aod1qxibEwڬ"&GN {Z<ֽʙѼsj4C{/wwwud2cN/DI9'^}?':cfСVM9ϲ R}G`RQ3-#Ɂi7(yD:Ha= ·~ (HP$@FβW;a@*۔g"Bee%DiVNٻ/@Gkc9"GS9+F{o<5gAUXmSrpH嘉 .Xc4|$05mZd3I២msxQՇ?(RO E$E9FUyE%uNltvt*M8# ιr4WUQݞu s,Mt>aRՉ\<]d$m/(t5mκ Ϧ#I5ŤWepW=k/>t fdX2ٜ 5wA-o}pueS:A>m)`q g!J 3ʦm`gb`Glj#d?%ųBO[Ghhª)W(lq f{.wyu67[Bl΂eWXY(ɁTa86|C]uDDZNLMEEh$R4[1gӹ宺?oeI'۵kפIt#t%A+ kD$E4k0#zFpa(ٹ;,ck)S REYK-vvuJTVWHD"S-{}} x㍋/nll/-Zx`\sM}},d2lڴi&o2`.eYʉ`K(gfZ &cKol` . :(ToY6oܿi,Ղ3G?wq<+Vx'ʴ]]]7n"~Dz,EQp_3fW*`#%!ِ%Nrʉ@6xwazuCmJECicN 41Ɂ}WXս7Ti *|M6sI]h+di3.h1oo<;INerj~NSbW]0{O^ [V8Hܙe0k#9%%v3; I9ᥐ '8{;VRl<(?)]bg]/^m?ĈZP'dL;A:* ݮgn gdgbU͢|*yKM-%[6$uz1O+k G{D}ݭ6l ?ŋ{= nР~nm{./Q*onvf'C.[1Cq@PHH1o-9dcrBXmݔ;*E92)4򴒱淓ou-uCa`U.W=x{79n Kn)4&ݾ5 $|cLy(d bMz3IA凷ȧs[b&7 KݐA{{rWrG:~>IPT"qrAA{mP8Ly5)|D(J,as)xDչFevBsHpP$\'9 ;`Txju=}tiɗ'&!}Y:f2YTmd-e snf8=3zS.](.Z{s{r0Evkؾ>s]c#ncwqg;y%/WHHH(B/JP 뮟[l+,4!PJ ̛?w&B"3ܹsf{=: xڞ%p{~$,UIžok-7Wf5&ُxynC>:MtcZSxCNEr꧀|Smϵڠ~5?qqz<rH(Ѡ6qMK ?t?u}tw4$PE9fv,=x#c|~4\TClо0HU0'?:h08,p~ƫ⡄ uTx,$ Dn/'<A2\kCC2ܚB |MDYj;C$Fs}~~a΅ 4W@P%j Sf[oQ}o^{2z7C/jcV;ɅݻDdCP=4ߙ@\&F$kfݦf>~Qh+,z JNܯݰ} F5~C^UQ@phU8B65l 'r(*K3Oq?qKCǶȿㅶ.̤H 6@ ޽T, O2U]ItSʇd[> EAzwAp<0|k5@H8`cWHO<5H;xq&}*d$S%ll$`Lzk9Yjʑj!]Q푳e,CΒ Pr_mQz\Dד P"GC4eNAT_!{,↗;|Ƚ]tWFF"yRh'2ͳ\սEm~8t:YYKoyF`@/ԍ%ߝ\ 1n{T,zH_  :T"6yƝy*S9:Q71S8Unm/,\}@͒}$rdQԮ;mʉp*G;w_fA!7_6ivwq#Ԩki]ygv7E6IC _T¥[+膲z8t]g Wv景eet#Hk(\&\3Ez? -{|n-ྈ<\ACǤ7.ttY9K ;~&@φ;P/t.?qg{sm/Uwt,y"VC<|MvHzxn^5pthI-9b1A_lf[ _i 3WEq:8okk).*nijq=<ȊL,@KΌ_v0EGERhM=̜C.e6*k(Pp TZR17 FKdRngi :yG䋁ڊcu.'NqC+ %.U(!ZS2 :2*Ϙe8kkokaVxD[ѴngΫ+67.\g>I^_εM2L^X~/h$QpvO!jO+P/NOnШhg8?˝/c±O+*1BJy |v=by#q~CQdYS啍cgfh3OX$Nx'k}²j9aTwJi zen}T>';Ax:>99%hl z@AdゔFO*1^wPGCE3JW=\?aave޵Kq Yƣ^I1ve.\A9ٙTs|2lAhxio="Z7j5;0WUTZ6NiX0 j)^TwhdS0^WBk 5񚡱z\_wէZ[3͐mHjp2zlunr9mQ~m Lͫ^$U$gE~GP0q7^@J;irk:~05qxݩ+_6`2n>x+'G|.uO+oIxR pn/"(FmP)㗃ep) (:Nږ3־w!$A'C}aanj6PEQNfHx|]qQUTz*mؼm^fkN6~U$e5b:/;XmtFXڏq޹F'`[bcMۂ#NO6X'b^/NQz-yӓF?-b¬;z>Ms~qbǎj;:I0_4-\TB<1,`(Vi-uAVEA>@HG-Me7o_/ C6RU>c! yv$B1`ԋ Hu$hr7b&%=-orw฽HVSꅯ3GM7~mRmRw`GcKc؞Ma^~@ԴIW^ʹ{EMpj\p(/^}̿%[ WG&Thm !v8 DQjP{e"Fy[?~VEqI, ggGsx"!aꢭ>A0W'(Vnj j5a`E4;6#1Cl;igEcp#H{ԉt*+ڃAiHܾ}|[GHiXo[=bҥ V`b| |Դlh>̶D7qVPR'~%kJJYڋw)RCHep14]Eim8 (aR!r ; v;Z[u:d(A#=u)8z>Zц16-4gFU+A]O?Lתb#fDBq,:t%cU#*yLcx\sv:}~s?4,C4pa™NeBBm!^@gb)rѝo>}TVy .Uh~ο,]T]CQ]d ~vhuT$ӄ=tU>@A!=J4{G)Zǻ\Nt$w;3֖V':0 üv'~5?ѓC8v}5f95NtYTts˷t:ð֢ʪ (;'尺EPD?rߟ|?|O39w.~ЂQ.vޝw{۝N_~-ͧNV U}_3M<|耚466_rQJ?/MNNbw66 "{l-#jGtfҲ$VWq?|۪ d v9=Š9tr:QXSt߰fٌnGaa3gΙaW/XEF@iqQA"bTDGEEM%4Z]^~o6&GX+Z49B5~hbe4Ӫ]A,xۻ^ٹ;Дcb9Z'$&dM [ӱeyrrl$'&&%oۺewrr655h49'q ~> ;TTZjq9n5ftqZ8d5i͚,gw\#]H4Ě,&WFҙ13JBChT  \ ;3#"ƒ, M^Kkx~ f3`GGdMG;lm`η,$Q >D ΃^`Ɩ b4D9x 0 /c<Rh >F/x3_US@_^`0kB|L)$I7Z  "s4tì0t}@˦FEPAϺj*P@9 ViZv0T.crSLi91~P3JUhy? m$#`o ( Tz>9)Xy991<v"H?Z~bDGGwݶmFdnhh];U*W~<(bs_.'}.g3$5zt}}}Q?~io;̨—3gnݼy܄ g$-/rZ[[-ke zFqyٷgwjZu͂~kĜsEH?S*SONI=W *˲KK/2GtӮ=wɉs?vYj/\3L~EWBȢccNzhPK{[XhQUe}W]} %\`4_02wtq7{oYz{DdDScӭKnxTUV~G"͚=g-E;v\9kvNn.޾q׿.xwLLt|br*lԮ KJ**N8~|IÆfuUec|/ח?'bbb{UUN޴,XѢ8k(rvm]>}#=~ѱGou)r8͵DXjSSR^ԴWwA{ϧ][neoGDD\}킓yjO,ovYZtb[^ƛ|ӥYZRD3o&q')>Ɉ&@>\{׮M7H I')i7q9cL|/>[ <²hkk%kVNNIx<'*VZ1xf)%ySRR4C #G6|W­gihB='Y~W~;n&*O퉡àlߺrNl2ӮO?xrЬgΞ//>#11ϙ{խ7-?=ٯtUWCk0 'K]];wLr9&O*f r4xJp,^rKho{)޷wI[/c@Ӧ];9VuDS_ UWhyq&B4dfګ#,h~䃞@3&EDR?ghjj|SOO@v|1޽w}7(S=z8Pgeok׷iÆ;Lfg4m%Ct إX577_HKq}(m[7^}eر:3 Z@β#G8٧ !CÇ.^r3|Z), |xnENILJoڌ+d1:FOwnmirOҋОYlA.sW^ hKvwϸWzj um@q(?22Ժ]&ƛoywu< [ pm[ OVkiigt%CWYQDЎ~՗u{v* VDkZC ބ ]>x=`Cג;=}d2M"PQ\a GZ|9λnGU4؉OH=w?t޴p؁ὼC ve/Js˒緛6Js̅9y_aB "IQ3 a ?^aȑy]P{ur)ꟕ uvvqn޴qi (hłB'hp 0](_ y>*_(eaMKQGV;T쑈 SC||֌`YNMM9==Cs^:K;vtRп/ 2=WPo0F`bO魷^zo;ph<켷vd}{O?v!AgXYYQR7&!w`ԇLu~7tX9ZfP]j y뼫pE.4Q]yX6(}+ݻ :hLNN퉋¹ ߈n\*q7h347~<4"\~R|x#oim}7oZzZ#TX;М&tEcAcccSd pEP32dk Y47]Vvu*_\BTbvGGBj!C{CGG S"""Z7y=H3ne4'O .*Ze2 lm5`3lPI.7v܄ݧf۞_'LgPUY Gwuz|B"^[S/tvomII˗kNQ%͂v;'!1jv@&*+5zWQ1c@DKt<=⿟Dn|]-_2մ׸C:g__t858=;W_t1CW_ }zcGNǎ9~}`/#Qj uuP~}Π5CG~h dRud 3!Yn= v 磿#@[wHB|w,{a̻+{-(noJ@i]k 6>Ǿ/w~__7L6 }h n@/>R0j)2SR4jtKƛQݸ~񍰕Fޠ vF.'y؏:~]f=]UY vfChմ>6ZM:¦N&Amn )I^A_-܆Ic ]O_J+ ;6{FZ .ZBL1a uÏUwYߙim&[ݛϜśu@At}opIQ3:5jaX:4(̢K NKjwMW_Tyk|rPYca;+P්^`SΆ)s(yz=4Iz^i?0;$6'u^h}@'`ڹ (HvNJOL8s2VC]D(HQw!bDx̠uJFX2"{_u U sހ \|eC Fކ(H8?Ō >0Mٕ#}SI=a+%*˵' \` ;kuY;o 8i>?rڬ"LTs\" -dHa-uPg\T n7('Yo ju*LӪ,ekN2͠IӴ:jtv5/3+O"(9lE E z^갘gΪp{`O7NĊ-&- 힢tR 7+dv3MUu 6q`BҟO70ΘDZӆhDE}+?ykh!EA9' 9+t$;p"8~bicF\AT!Dn !t DAPkj5jh;ϙvGtDt؀ Y .]p@QU+"/Ѩ]5U=j^Ad6 Uw*8Y]]{F5OyQ$d+uV:l>Gq qL D"(zZw&#_Z]Y> Oa4cB32'J5^fC~ҨmG*;MLQxAz}*~_o}ȱ)(%AbPp) z:4 ,z-'J^c2DOP4ڞn*.8B@yqO% &\"I^?Q笮qhk:⏜c{{Bh:k8 J9A*F0RŻ{^$vw"Ƌ<\X;{]T 2" ruXbHEsʿY-[Sع93`@v\K -¯B/p8~z@g6YY ii&Og ؕ([<{>^`g[xQM757$/~שCU1icʏ92^I`WÎ!Fo )P}*vgNiknlhokY$wxoP[RYfu:eqi{{U 閼oGSagN7hȐ7tAq[\|3;A,6TDew).Ҫս-ȥ? :<<"⧳*Pʣ(211i֜.jfFtzg7xPOgUp!pb(P*쌡)k$^Zѝ$߀OwLޖcQW`'$=څɉA5YؕrWюC?jc @A7_6Y3jA6ƫ/=[FQN`ʤAi#bh^0Դ>k͎5?/o_򿱱񻋋*+Nj;olwڹ㝷_q-#FhkeHz[_Pag?t9 Iks`p *i5 kpljϾҩՐg3ED"",VA@+E;Ry`@-+۴IMKH4jX`g{GǚWͿzASS%`?jr )|{[kiIi}m-|W*&)ԓMSx^IPLLJ9֠p\ip+YwOl @kxUs-K@#pEw9N:cjtzAhe /g^6-.>O>*=u5^wwqbR2F*}}s vfe-g·&<2N%]N{_mvA!᳟=~ছo=Z^6l֖fhX ODDD^˩F(*x.}HG\ڄDعbkom]Se[q8%!)Z<4f܄6B8LLF9,\`T3E3P@vD1fAqSkL/9jcgNh)cװuT\`X-f_xAhmolbzpe;m?)_)g~g˩ha'=#,'$v],&s+Y1; ޖB_^`SΆ)sxc#(?( kkv/wp xOL B[ pmMTp9)!8u55,57μHz-aX W#7>؋mjGF:ah;^ۂ\*U5LqFQЇ* ^Ouށtd#8߉dZ.3Z9jUi$5CnlE##8+dġ]uu'qj0l(` ) j!my?I J8:Y1Q"f׉Aya4Q"R }&P)XDB L&!_MJS \.Q(""pxWii"D Jpd(MD^t&CQ"$Yd!DpO,)u-:WB3)KJI )AcCCNM`ksI P331tʏ;]Rɨ@^|̢~8>'D}, T)܏0Ŧwy J!IרUf(ADsE^IQTQhYfwyDO " tB}\Z*!G\p.H(BE(_bg} 'bO#BGPnAn D6ג@a@>$1ԐLO$' QU5lRqu@BR YV@>8&~Ha TYst{@8ImEHJ6({Fƒyy ;CEDN41`4NgiŸ>wPUQqZQ8J3~8q>1)15V3 677ǣPUUU&~#Q s.蟙xR'QeB ˫qLA]HMzG5%ZTLI%HlFkr0F%B'3PVUWAbdY "d}<K6z#q, b"a AD*E qI H&eG d S@̌K xBbg5@ N424*IafɄjR@hfeo_wÒ􌌺p8h2]exO5tRWc1`XQ,HOnڔ$Ue^kA%4:$7L@XPDIJF , E,YoQ)C"x@(Sz$dퟗ-&[> PS=WKs&.b j٨uWX>fxؿ|ڌÆCǝٹ NRL:53#E656vȐ!(j*\NٳfAZGGǸqv.)555&֖֜ܜxzIQѵu.Xp! ԩi\e꽥_ϛqwLTJ[S)(D(). FT::֪7یMvd,/2 7*KL&y[HodF6qZ/(e9]FòU1pdVF/!ƐWdBbOMʖV@b!5X@C}l%-$2ʕ" (F!}( )/KtZE棒A8xL<?MD* r ;or(@AEe}cc #Cz=lǎXh`G~cG5'FFcIk*ZMYg͚'!&\o?;tgawlq@ j5MHVd%pJ`U&Xެs' v"Co*( iLJ%VXU/@"%L)\i-Ny|u nw<%0ڋA2_ŸݤH u! DS4g#+4 C҆%WR 'GjcУ F9E.N"AIrQ2aR-Jd@ 4M,, ΉPag&?thڢjA{ҸQķ?c CSTLsa{ќ\\ܫvLhAPV?rJ!ByGwNڙ3gdM\GgiQ#GuGNvݏ:z&гT'yIFӓEZ4CI8!/2 ќ Сy͊e \hU:A(A&y?}=jZa9; (yG+ QD8XAL 5 ·>xQ[pZ4Q:N mf]!mV,h$ܖ`,f05B9?ٰ}$mqfwŋQa"ichǴ;&59=o;j@;2LȆ"$. h4؞%3OJ.h[H@윈SIfi<;1*C5 9cANHLˌ) zB\;x;ݺ=Z9g7440ۀ~G͉H!IN+\۫'4}&ܽkgoKq)A 0[:xc5N/ki׶45(a}ֈ$ȨZ\4X~^硓IvQiDnsThşLj呪~*9ojBss ք( ciP"&GEs"Z_DH44&]A!M $pDAfߡOɛQ(!H4z7$(EX6zbvm4"0;yQqr(UmwU;x<̴TŻTMͶv]Q';]`gٵD=# A8_~eV?6UE.\r5\}G#ubkPp(؝OU+ J^ȶLimt>)}o$(HA{8ZRDoY[2lXlaqPm<lKJN[z4Mr: QEI<+%كrČp:V#48 3L [pfcX.XK,0!͜(Xͼ TIz$3)M!AJ3Yp4U(ihKif3Fʞ#RNL{` ]ƥ(9B7%4II)B~J#'AhtpBv;ϥ,<&9}_ܔٯWZ;$|Sp@=pm]݇~O??[rd)..3}1cb\AJJ9syĤ|?_tuͷ:lh+>3vV)޽z566޳{-fH{Awņ7K+t YcHJZ*GfEGY!ORCHJ3)\M%-XgimT2M{SSƨ26;\"4gͤPiH!0^gæ_\x+DHG#mKQN  wl@B:)`:HȤ;ѭHI  ya%vTR%O#dC3=ј UPCͨyC3 Ѳ#zĩ_|ڛsԤNwXNjT‘Æm? &${}_^8rw۷?0  ? ?_{UsСs7 e.[L~qرF/@ϦL .]yuQvxwٲ Gz;lLKK;|D=q%0==OY9D`H0:>K 8$CHۺ'7WF en5MaS:Z\'i 3f!(qaÎFW6衐_7%G` R8đ /*Iȓ "O֖JPthEg0RҠ)ti]uH1HH8)yKtgyR9 .x~;Wxy4$LֵVGtowt d4J^xBBNU3)):`ςei_~„InS$G!On((:*HA.ާ&=Ge@~b087L QtBbbsAk zU+Y .**NdggA׫R }Y;?E;XrЂo}߾}W]u՚ի` U˗gfd0,kvvEGE$f&YOj 'wxh35-"##dE $DJ1-~ FT(+0h<(Vmc ò'is@(.?cF\+EUiETnXs\O ^NH5!I4WhGRW ^/G<)Df[H-@uB䖢;Ci"?AQR 8bmAT*1,'%A٥Uqi\ZeA8>s.!!fՍX{89+]rꜦ'hrDu^o&ۻ〱 6`H9Uwwﭑ1ƻXĢ]s=v_1jz c1yeκC l|ȡC>/$$sܕW\^ƙ]] \Fr sE1繝kkl!8[޺{*g%K2.:u;~ff^W_skN[,ש!T.[:n$-]7R\%M+ڮ֠ ( f]47_q4|?t"brB|Xrj"(>uVǹHوT Y7[BI!? @8$P^ ,A&MThDq$PcE/6P H29Lv9Y+d<a$*aae3[1}.,$R4Hr%X%-ın3;{X2](f}4dA8: Ĩ8f x5yF#!)Q1$YQ! m0Zp,!z^6RKճlAHh&8:ӿqʅ$Iz" CS#=ù\]3>ulaznX}o||t޽Vԡnޞ˲Ei a9qu7ܸ˖+}fbQr0 偞 Of;fn9u suR/ˮF$ ]3tAj)[6 &5087d:a^m#zn!FiǪenR,TW\ULɈ!wfFNM#2),`Bht gLykۛ & QtnCL()% a2܌Y^v&t7t3'Rp뚉!O .WG@RB@ӴHp<Wʯm?58P5 /_2@綠t8xy?y,,KGǹwc^CR&0=T ά["|x{k˴1g);==\6jdČplTl?釀KPH/sĒt"6$$<"",>,i<(mV¦Ly8T0}.3dxK-ӬRʾP\. V<)(XC,RDdJ&vH7f^Lؽ6a@E&aBbbZw2=\Xuy[<.3IK<diL-rB5Xjy.+*ϟ9u+m''Ƽ5 ĕѸ3@wbllǎ75s?w--l~9]w߻>е/=mwIkO~v+V꫗_ywQUSP`k[,\ avԉX*?v$CIX+HCKKۿ(xE)/|aYƬJS社ERidhe_Aw}y|n8zZ2YCǷ,-{Mt:R}u8jgY!˪\.d~?Kg 9)x RR\(31jpTmRcUy?8+ƨ#akd@0U#>4QZ7]X)g'lShM)Eo&E\[x&&Nd+c>kJIj2Lpic3 Ca55,CU| 95xOt(/=}f{}0ةWL$͜ҋ݊;ۺo$TXV^ 'ko,?ںߛ_t)x9yXVVVl9/ 'L)ؿ,GF߿~ᡡrzNo3w>D_2a%e;yBo>VPo_o f9=oUU_i0 p3n?l0|!gu/lX12Muw2p(dv jҤ&0`?QpEA $a`ܓUDҨd)=0)҂0Wi )fIV"se) } 16z>(%LJN %ȊcH,?in0 `_V[= &aM qx@D.g? OHuCΑ&Hŝ/F8T?1ymߍVDW[GE,QHK-l%&=d\rI\ d"qU~񳟆#ޞSpx>7S @Eƚjs< 0eI*)VgtQb%hdsšwny; 5! NӤٟ~`Z1$I1M[q~"4PV"d0bdQ̷2)Fb(?l&k[ >#| t=5r`ǎ(C!v"W%%\͔> bU@l *"jZBAdr͍Է 1DKd6tS37h uT[&vp2 $i(|d&8 ¸@N2Ab~w:ga=,V.cU $(\p&xφ [ UUAtݻ1Yb 0UÚJ`M7]{QURUvtlͱbg߼89geي޼,raGmU`%|6zGGA[]:Z"GGv=YgvӂΖCKd6˻N H<ϰRyd UEe ]uB OX)2,E,\HJa%,XlT20+eAV!?Z"2$r7|JrT0"$;13vSCPp=@4Eg9eֈَ=TH_jl˩ 7qp f&FtE}AUUd?p|r[nYN4 m!`Gu]SI:T8xqV<Mߞ1aciċjkm]4MsqA MiaA6uKl,&ta ,B"6 ˀD K+iz Z2@(Nf 71;IhA85";߶ذ,biR VmT.- æYڲpm4J(ڍ[ThYI fwvT*Quͺy i,a;#e™Gne'N˲v_@M1_@gYC^q$%p,vMs®7fڌaY0ϯNs!i IhoS4Q彾ȸ jqi$ME9̐M-lY)qI5v4g$f蒜Բ G_*" d8NC6tsg)ZQ:+QQ7Vx]ιitD)BmD:>AUW#\Cmq#BO00VbS x% ]LXie#\[bbl2M-,;n~3c0ljdg% miZyȇ_z-^.\}(Z9/XŊ4%K^dǵcٔ=H4Hi8:1tvX 趐83N@Mh=B$ n4Ǜ.& (+M Zondocq *FB~+]KvFe G0xT>y/\OE4Jz.w0 b2H|r=qMetx?-49OͿr i)K*ys4KxBi8h/RߴPl4!W-R#̂vna! T(N'DeKe*Lu}&dDnh2Aڶidu)H$E|qBm782pBdXуe4 ]6x~l{WeENPgEp|o'N]=2Y.Ru\ahy.xIĪE4eb0[AByB`IHE1{GLsЗɤ];vTVU:yr%xg%K'EQᦛ_wGg'<\%W6>>GF%λ=w{͖ 7W\gB z9>15B7 hIt&Oe -+(iC5X 7Ѿ)a_KŐd! ct|dxGyBh$ TE7WM&*6ĪZ+I%+Txn8mnEkXJ%34 W$ebe² I!HVxGE.WdD*"IuԉEͨbq֔Uh-`1a) grYJwΊ*=[63O Le80sjpϒ}>˿.\zN>Ɔy9:w?wo/={6\{>8?!^x@0P[Ww+V*El )OlEU O`[(.t+.L}%upkLDNK%FuWuu:r8͟V4Ypᣏ>a$U AC j!nðll&821B'Ψ<&&+ARۣ;;4' w[{'r!>k~SSd.wGFӹc^u#f´pHtfzjԩRad..oeká*ƥ'2eלe&âԕrfaXoJSnA%i}C}^6F|[GggudîH"Py:`ϨBt9`E*J4M̙7v+0 ֮]~5Ra9* BֶG?= 7/61>] CÀKdžSMm+KzrY6SpbǴ0}e3?1x-mx[fK{\ ^x7x˹eYfY:ܱ}f+ߦ 4&bc5K#DaP2X:pT5KL`puu`0(ŐrY,&fj& kG`|-O:3~z")UU+9;0!X\N<ǘm۶|>_UU#N&Ә^F5G $m8N6ըCfϖ">]H3t|͞Maʧ~VtG ,jAkQḿ W0|-o:߿6M MQ-8M!|N}ŕ˦*hƮjT2o?rJ%K/{1{֫=lO}K?#Ҷ0CU>Wgw RskC۷\~E[(>=v@ggمJO;vp[W*il90 -}]^aV$,0~tM_߿~/~뮮ow474NOnԍ9زjWn9r? ~!Q<_s[6o>v_tЁ'Dg~jӧN_~>rO> vhALJgFLX*KVKRs͝M>wQt/ZC+:-Zy櫯C?:+QL-qjqͲ(T S&T14e[lHx.IC*1fx$b2͛VK#HqDDι- Bmu8F1x/wQtŝQz6R]et=l0 綼@ce׹?g4{В GK-s΃* z  v>|$^u@mMDR6~k^K8^mrճ^;9?s4 ogiX57=? lcSԱgn]؈ن_g>|ͭm_㉇F,VYQY9<<Gg ޞO `lՊؾ]1N 9._q˷\W^޻w 7eηxܳ?tNG> ?o7qwz>`iy~0 Gq*Gq UM~YQrkjdpdUGŲmRCKe, Fь,I$Bfh]-=J.;,,r,Ool75Y0XVe\0`E=z44M{tYHf(#XXSJ6a67=~Jub p#X 2 O}XYsq26p+̘9NY(g1))Yd<~iЗ ;SU\蘻H`>s|A )J!b[ V^|`[Wp]v̬Epϛn_u|njxd9[_<2k^C([1"&mC ? M9[z =zRg{OBT0˟@қlX]]c$_zQD&N,> LBBKܙ!g?KWA/<7ތm7sI`0Εb9rt0JQ7XH;Yȍ<='Sgo];,y:F E3yz 4㸢B"aKRW|8ے(!llXtVp !.`~믿L}>ri, PTMph1U,ЉB &:D%+DFm 3pILt N1F6T1,Y/[2ռ461IK01\.߅/^&tđx"Iع;2]*j$.%=Jo@xz5yr x>/X=䮪@MCcipȍw,O;_2r]Kl:Lumg0A$COz-Z?/̆g45Ƨw}ϣުU}]ހ?|9aWkmH}];wZgO ^8]3=?s;rkDQ5{ ~쪭{n62 (wdjht^mW.8 /+k䖬l/r<ݬb Il-kMͯ:t$<79鬬]w5x~ o9j|Cy˞._qv`y/[ 诿eϮYΊt2Kaޫ[/&f{(x\U ~d2$a Ā_c9,u(x>ڀlV2'خ%ai 'e-(L4IX ޭU4K,onƶjr`|^q`OCFYlN` g-Ӑ Lt4 -Y6Y-cc#68v7Vͬ.`H\*kxn əT[jf=n.#h}u"Ke%K9dӄv\WPY/S'.Ntdhxd%v &v'?d1#Q$Ps"$ZV3!aaŐŠgrx!'zpW/˙FᤔTC}\*( <%I:%XY WL-4֕m5kK_bcdr,wջ0ÀTlqa7&3mj,+F+p=L%9A />ZՖ R(@ uEҫi*  (ǠHJ&IE$]JnۥR Bm|iU/eysn{#2rX^pQ3.t#d ~_{QAyqM:ƙRiѺQJ{pMEqh po[U]YR ȉq`lyb8aE:SOЙazcq%&$cXQln#'\W5[GI˖&2$8 >4,`lSΣ2nyyHWUPQc:^3/ eil,%G/H(XR*+ R9)F`N!N0>gKY. ^y%蒻_|X ]B >9)W?a0$m R鸩p`h8k⚦& &d&7WKLJVtأMцO} `kYq#Iv ~_i5]v7_qӋ`0H GQx<\x&)%=(KRvk?`@yqH;rhtϬ|xΙcf\*B+C4Iݢlt@N#K:6~ǒ%i,IӔ)F0cAIdrzڛFeR00T2y޴D 4t7[020U0S F($*tow& 9v !YcapA+SU5 my9 p \xcތm<O* kgzMñ]kL ҋ)cNgM%0mGgv_)vw(d =7ICr? %"d)"} v 2SG1,#hi OgaDs4/xE`C}oٸpXE`a]w_08 ~oO4K$/Xs˛68qoO~?˙e/Y|g"G eXoaL+.[qklσA G>sAKb^~q#kaFN8~ӭ7_~e0ʋT& '_IϿzzilqsbp#4C1,έ&cqAqЉ= "iV: ͔RYj0ʶ"CX'\U)T 8ι\i< ~ g^ISՋ]nj:NP6qC!SsCICͧv5hq1'j] 6<$f@5kmT.X [@sR) }vQ96;x`WY^]d?߿#nS'>xw*fzE[`fmrbsdxCO;g-ic f`0FP:WV :#FbyCM#*^c uma6isőqqFctVsMuePE0d3}G4:uaPSU0qAi:j9H8&M7VSi b34/S`tp؄:a "P8q|Wx< .DsdSӌ3}&[lz$ mtOlmFeEUGa(\Pę$^\wi,p(qr-Nl%AS+wm9>s\>x<>Kã mݲ2xN.\Lӽ,n`̭)*0 }6 &04-{PW {Tf)6PSW;T]gXnd8Lkܤ,AQ̴p̊Qmnj  NAot]H&uؖ Y_'AE@fp.hxb76U4'`Z bg.k:dz"N^?c<'=Wa%YN4M+#KlxϽ閾={r8Uf҂kWMO.͜5?{RݱXI~W^ӟ<zkO{~08;_-~@tiYBά޽{3gΦMNx>c?>WN`Y0a/l.Ml{46„/e|e1۰(탨eYrϠ29UT*&J( 7?10#U{k Q4r'H}A6YiA04\Yos-(;T'65%miLpuM XcBd6VR0(sO=yWΤi!߿ձh絵y+Q, ' JցoeEV`-H 5=Agð2&FD}B cW!HS) VV1E$T>7o;=:[} 7rnO~oY.9;[pO|IP=g7pþ}*':،3Hd/yCѸj.ZNOc8XLbYO,jeL>\{MaBIwu>p?PG*C#rshB 1AJU 6p_-F,*綶x6N8Kx0he@Ff41 :n-׷fϛ SakS /߻ C q8M,k8 AT:;B_ %slE1 )a(4Ma  Po;KrX4,ilf yq\#Ptm( 8f踎e0F 36cu1EV4z ^`1eZL:O,ܠ݆PB |sX*$FbH7_0M")6a K^jp4~[q!MV/<qj Xs0l*mۺYb9mSx\=,"ܒ0pHj[lM&fgܐ.ӞʒIP7 /k3 Aӱv6VxȄ]2l t6nS ¦C"I&fh4IPPpj$` ġd, : ,wx2Zw.5G*)ʊ%]~zuYmՓ7Fcc쁍Ehh//X,H涎Tk'\ı3aZ'qhnL:ln%Ox} 4ǕJ%B##y3=g.t+.e:ׅnD'l!s٩ofETdwc Iᖢ"&Ur$_}f#R_򭻲ff8ϭ) K1Mް'HjkX֞r^hN3ii.A6bP# tj;(#+Lm#ؘb!"9L$VE}Q$Uai "4Ӗp  >}\*4eP(ykjT9` !fK%咊źޞżltxΛЭ@4toc8E`MX1iS=œ1HQS<|-3jY$_^3[ڜ7I 5fbZVʊe3 #Y |G1]Zsl U3)a:`P*CִB^IǷ-k$9Q˦Mu19 i /O î,(c*P>25G{7 5T:߼ tHږԘ_o>Tc)99T:gg羘:lf;LnS^h3UFa*1Ͱ@]\p]z:Ld9S7d@ޣi=|1[ ڶs굌?>x]seYTSe{?2${!), AaaIQO3O6,ÜAzŠ7 KQ$*@((GF T;qnm"fL%l~g{76Mq,p ;8AR$0[W ]VH8@a |RK6 F`&LttC8 :܅ 6((2]{z a7hRTjb9'4ZO c!%(t.j̀Oy:lF,f6he9Y(R*d fv uϒDD6.L}Z`;[<'LWD  ttqP Оf!9*4@%T5}jO bh: ~8A)Kv!{DŴU/[B}p @)K$VP h/wٲ`.BȊZIiO@>OH NW9 & ($Tݠ(4Ub(TCT0rnNET(`z ]vЙ& _9re$Uɂ߇:o^'oni}q ]n~Ek`~k֖-//\-,;%<9WVV׏<_W?]kRԸ6DRPbf"xfٺ@JeXV$ґ-_)a;'{o&U WZՒe#ccc0ƀ1f{2 2Ow2yBI`f1IX<0ƶVkZj^]]9?߹%ُa&Ӳ՟ۥ۷nݺU|wGyG᝙$Lo vnoyj6Mh{ނL}6\0URT^ᯮЋ{N,d;[HLj7_n'^qEY2 mP'20cIn:DO8edhc&zE5$}bz+TlǏ5;Jr?| 7W=o3 ۭbt mxk-.Tņb9L`M]{֭ݲgo?6ۨ,K n?ơ5+p3@o~ti8Nt;F׷mkh}<O&J]ZUNYTZݧ8/[D" -G4&봺rE2$;T/̆v!^8B Z]z,N%:[b q̳M?˿tn7 #YLu/#멩I=4:.20 oxcNz\p4DC!&F. zD!hI#T<ӰȪ 7͟,E|z9kFf &0-h4fK( %&۵zؘb 8j81̄ڐ8šcܴK6!B[n%KhI纨C=w,Y/pBCwFJ ͆;<t'2QQVuHb+q*?~;G{޻5ϚoG}{zyg,b$bBr&Sq^jJUQ::䨁xէ'kSj͹~9ό ve6hg"hYR8h='fj<9sc R:m,pb.Q%2p9h͖@^#f"ӥ4A: Q^R'EFOT4հ8P8  A0y$.X{pu"P S.2_~ykKu\Kz[ c ~G&[ض{B_BF/x1'Q# ԼqAVYKpo׊Z ~û_)Dwٲg& jDgQm Q,PFB2$BAL"㾉<c uGB;gdets3غND "%+ӪNj@ PwĞ p(ZVw$eދdq{'+mxJ`O碘a&Xo}tJMj :?_*lԛFZ%T*a>B_BZp$P "c`咂t0Ak%Rcy7YH637lpY11v{Q 0BX&P4#hi%Rlp b >AP a/P (U@%&7#QWr݉Z1ىG'g+RN|nI)`s+FH:^ɢ)C{~L_ΚkN6׾&T4qóԑǎ>9ڿ/56k6L&AX8>vdrw99{FG^Co֣)C` $b 8)KF $S4dεԎ~;fS,9AŜ6bąh/t=/bSsZ Lێo7①'I* gHBAJ \0u0ZQuӂԳ$XW&LT4mA)L0UsePzð3RݠCȩgƓG=\=Gm8Ald|!~ ~!`~9qCmڱqGݽ}ECH!;:gs%K=rsfG@p!tGw3zprAhWj{,WBmϥԑ!,B% BE*,!Y=c8\Fx)5iTkQmlT$ 9ˊ 3ΙB:p*b._SvP#,VL2H! c"&&Q DU- b]" VΫ/g 2R.fh*K=IHmY0Fb!"T&CEdB:n΋dȹ#ut%)er(îr;nF\9-*޾ٙƘ0[K0 9@j#:L#om[w3,:auR*u$i5 Ru -ԆɌᡅ y { V!7v;^43NPc*JQM(ɵ#P`%6wryRs&:z!/ҺEjf/cbYf (–q؎( 4VX%JfJd,w/SXS.R՗27qb;YQ?hx\%b1q|r H;i2Kc!jP+=ACbc =8e<ҕ C$YקNg?{fu8}3e[NRaz6:0 ! s2n6Msr@ukoypxDT_mf}4W:D? ݙ {7::Z(N5;;;11Q,.DC`̍eƥjtW#w͚7hzeerYmdrު(hQ mPt;gFBۮL&ۨ g w<3̚5k_U^/ x("IEX"hnL0& {YX26Cٔm#hl/B喿 4`WJG` -!-\.[CfP4Q~|n5BC,a mWUdO6-PRsWnLՍ?=%JH DLJMK n#ʙa* Y5iAifjGIR;P.+XdqЙQ|+~^׍<.ZO>߸c` ]~e@OUGm" BlYǥeӆEs/bYZt,-՞?U8 5gM]{PBၠc#6y\ZK0(jZi5%m{~KkIҐ^񚽕J(p읃}nZ5v0e(Ԍ'c=D!nG=ExFƨ8vd΃(hA0Xa ^phZc&`f8N\x>?YJb>{V5j Z;kƛNswA([c}`氷~k^wuk۶mccc^xgteSa5ƸhƎ;NNb SރikYc\˷"BZ1tb37-+L5cSU3Q\νNBir7KFuG?:vإ^1"EbSL=5ǧ9;H:E3mW!ܻiu~*ܜa%egx&fχRdFtՒQ.D5ӓNT4(AB'DԴ{l x  bF6yn4:FGy]7l??Qfmi" {!dp嗧|;U),<}{ߝwYgff/UZLdb>( $]W?%B别I@"VKPŲ:ήv֯C~5j=QEE/ʵɣo(ھ}{oo]6?xty,H6cMˬVu\9ka@ۚF.vѣc|?vXɦ[wV\ r1GY4`fI͌.eIF ]8Tf1Ta71Q:n"2-Hg~N8ŭ-/6Mlo0r^re}Z5zz_'2 #lz O=*2Z« %2&ϑ(F[L glR*=e\(#{'MSZsiP=SZXgt+fҀ\⧱bL 'Ņh-"bƖDQb5"DOB#:3Sx]Z6!&saZiI$s\S΄5!;[[+Jp~XZU+FX]!4d qyLp##]9cףVWmC0WZ;fB T-_ői;~Q&vu~>uǔm۩܌ dBI,U,d« THS5n%࣪).* `y\ ,/UD3fH.hg-G!>" |)ˠA/.3M}`%5 Br`q &FK hhRڵ۵ϿHlT˘z2pf,2uBJ>oAnfG|N]йٮWǟsv~bG3~4oUD2}GRtjJcrw3v`ܥn{zWꚘ8yWlCKFLMıc M˚1MG~񳞞3ZXXfhhVƚjAN`1 [cΓzD1*y$do*F=֕Xv& ow㮇wbaU?\ɈǖC`Pll\0"3xa"4>K٪0%h c^+SS_oY;2 7W(8vT*8kY6eT=a@d"D}Gd9vPH|KE 3HQwy'̸Ul֕1{ m֫쎉9[6Gf{~s1Qa7~i0S];aES%穡V/`kВ3e\>W: |'็uY㲞cP- gb0E)V4q6Cmbb" а:e(ZfILF2{Ӓau4ܻ?bnXkkfͷlfp鈫]7%(tk)ʴð6Y=^Ҧ \@jHB&2I45Kvh[NX,w˥|ڶMN.`t, $?Rt*i :w z8zﲣ0Z#^^ *H2kmjCg陞j6 LMPu%(aٵI۵ju;½^vzlo__{io>ob!ѻ\)Ґ 5h LYj%+!gehv**MF٬+$q$h> ǰ3IVD8NC؞w~ż?'zAtڷO}.{㍽}Rys;{ W^B C li="5 Z]M4e&h*Yi`,W=;8><4I4i-d3 ^99=v}L}9ozӛ?/ =%$A,*\NRGA*e}]fV|b2E9h=+uJgv,)` rКj|"ϡ]!iu/tV!\v(€:2{tOhc+ѷ]nE)>Jk<ֵ́ŔBW/hT=]Y1#M ms8 KP>-H/Zз4Sq٦<uBXAh4IQ+wsy?oyoZ~ʳVؿO':򝷀CK|l~!=ޮ_7+fgg#o||s.Fk_Zu{뭷>Jw~ _PiJݥ:MB:pn]Ҍ38wuHڧ&_ڳmقs .>6~:'GojvcSj:pZB,rI1:,s6mJ;91Z\z~5w r׿z \<84_# #fK;}CR055w+32jTKz,)uLŇl(9X"X}*_:d`oo96=`;9%6v$/*h6rKVq >4CUO<["V=$tjme^Qpoۋd)LYoP,*#Li@^̽aX*=(ij,h-;wǩLDqlq@')%꛴vݺ^v׎2=;oBxwΦe]|Ȓ ^484qӦKFv#Vvo|o_9X LY ߾4 }X|ƍ>d֮]l6/RݻٳuV)bf㩈[GLDR{TsDđtaJpr#mUc9&t^,{]cX4L!T_yї?~t)6\uŋ.^MA>Sȩ1Y(p7=k*ȠypE!!|a)L PuEGڭ^vV؆!Pm![}3:U|?1ny)'qBs752d:/wzǩD˟>>ܓϸ`wU˷/|]1wT\sKjj\޴Y宮cGWu&ů[ޮJ% V >08:+^Jw}gWVauzń\LW}Gy[vݭyͷz%K^׾59vKD.G{mK TTE! aQEPvDH" "AXnSCeò ,j[̴i,XF떮Z߉+7g_s}vM{jJh O{@cٞRT@xmFZE.nGI?{(Jm!aRD JǺMҢB 1%vlFSڢP)퀌N$37[?cT><~|GsIn}G8ohk^ԩofbHq:>jzWz;49b]TVwwٶsX>p78DSbd`CrcAt$ 0S m_qb9i*|"'n:A%+{ʹ@28l2"õ휙eĔR+yY&T*mǁеwAF"v 3cڛ׭[rWd!\ ]f E P4jĠ)n8X/ ^HX{4!D(lQ&C{`G8ozhCdkR'ghYwﴎSʝ$Zkye.B}v?go&'΋ۮ ( 8M34є+6 E\$"pۺe֍3AMELf Yׯ=o= CAzA:y3Ͷz)T. }uIz)ZQ4%1\2zCb!Vٜl"%pu>ŝIͧrY+k=LVn&uӤdG(cJPDpɝNu~h)zԻXKbf~j\ml<ŶHp>IAh|e./2s Cy'٨3?ޖiwhb!} Ib z b.'I)Vte<|0Dre vzhZ\"ȄvN{ J̺C;A(ٲf0#0)v +7jś'`4U)etuHP?dC# ai7sF<!1ם$ xJA p* .יOi3#N:RU[՗=?xd]^/u=veb|ZY:_Y2f>sg0zz{1ꮹ镫֨7wݹ|~xRvff`hx蘚2 u:GWRgT ;Hr|\B@(w{XPpyP _4uWh{,9Xf1Ldn$ZcjPJ։ʍS%)+"P&(agbY &hGVGh :k) 5j@XuJ9Ӣ #V#.9fuq2IAhV$XHt[z^~Y<^UxqW5)FإEk:,(+dQ[GAصc,vwo:Oq穉n>Ȓ^5>zyAn+s3+V.O*2R# I2ScS/VFE gK_-7~5̑A)SKg& g$#|P+y9t_i`̡~m! YE$ԅ5t҆H8 0.^X;c U=-GG4&$aIfmAEZ z,ǡ`MqS u^i5: [.x/cP^Qt?r3tZ?\xçG7=)\LOMC>3TPL{^6YXh6 ?d(b_ /I,ySg]weI#i80ȷVk}?dRUj>ђA;_3ڑ~m˩GcbPLw#tNnGvѺHM(pڵ]yDr3;uYB$601HKӀ9܌¨yŽΓѕ"_5ha:bje6.X?Pm9wl"e#B[tÛF/iu-5mٽcuG+r\h!dʳf.<%ukZv|TatWw;wJ%7,H ۳{՚u걽x$k_Wqw. D (d%6Jښ}[+F(R(vO^C^56i[4Lk]9|M_EJj'>!Obv3AX|M&t3'*=(VkD܊^Q3L`Jb&r]>U[F0 ?9㔡sϴB˒$/k-ƍ<ϝ hBtr5ox;6||0ڳ;8Wm =H+caCj #Y;HBmd#Bb@$1s9R.% 5/ϭ>2tͱ۶m{^gϞVյlD!2-HER]XKIN0Jjc覿=<'Khzz(QQ-aa2HŞR{q xZCkSs(2 qyq٠{HdUwp)LV*ǏS"7΄HS׮]W]'rM7T*nl6h.Yl|Z:6e&1(fn ?퓅u$]L DӬ|"qbB'Шncfɀ!'6LF똶ms1Awuo)[1ly՘WxӝifF.۵k-r+h~ް|[o\.Mo8p} 4qL2єoNDate9P!/dAc pU%n)Y#ZEMM1BnZ;UuH"$<Q A 9=P^= XDX+ {uqb?ltN3a[V!!ZNX TY߉lZip*)[`+uJZq 5ՌHk<ϫu0 EP>#l#$v"x?H*Wà=]Q̆ˌZQUw,{ZN ǥ!UCDD8UňBd;j &i=%gdeԮ$4":?|?g5[u~ivaĉ$Rp.2YDPی=]PY\h)}mC2K #0jDT(kuTY!`MDC[} }ݗ\#`8NjUu2"Ba‰1 UOh8-3ª7xR4,10hKh::]o6HJig;y.,̞Me8j$Z4Et~ZG۾~hU2y-}&EhYS Z,h(ME-=80 ]J%C9ERMɀL HDDv3K2]dD@x % Mi5Jg/`p<:QKGz^yMRL#9m9m]be\˰fmCn7hckn97ך;2! jN622g¨3cg11)o*jHF yFS+$p`*Zf}߽: 5_?7q`7r`kK^?k_>`G&| o{xvfyW |K׼;?![lꪫ0|omESTL#AŦ2F2ӆ$3Cq8%[0ܢvvƦǎp?sl]RE"]tղb( dނ|%,SEMd0J>Dt+u?kOk _q]DZt$fls"G]Dp]'rĴ(h#PIC!c)ds5&PLt%P@z'TfZ_ۅK.|hhwo{ǻo_}._bWmMz֝_C:{ }\*W4#G_Zn׽_> ^pMV|gܦMLO}YrK_?ɏƏ}o_˞V\p?g=YjgRԧ>o~R]zwܱo>ӲO /| F{|G曇?Oe/[nO㘛8,6[tbf Y$Z5b,yBB5X.uìh޽#.\-SMOʐGj;< |ڭJ/-}b/ߘK,kz0\W96l!b?78QlYr!AӶC3qF,ùD~Ԇr;omj@pUC (o < 5StMU]0@GF%hdο](<4<WMănG>]'o/V?W]U*{?/>Ǐs\tE~ۿ&@ݵz]A|Ё{ˮ RT<44~3Q;\s5ݟo&QjҥK_Wkd2ǎZ[Osu®O]&Iuўd#)e Ar>@цt2Y¡1 l;2h 1BD_E@GI?PA,LW u_mƉ`rQd DKvut߾c 'Pz1g]m^\#L&H|ņENTQC˅h[+BJHIm{LP;1F,p]ĵɢ^ *dο]\u+z`@+U_ˮ>i cZ]US-GE-㺴dR4v8E,ݱŝ5^wR@EeH4+V`|^/7}V}޽{kvǎ*^WbN=)gږE<=+VX2??cI"G;927[?.`HιȵA]{ד I'g&u̱X׽V5X*3'/Uމ5M<0icz>X&PQ"{~gm?S8=+ 1 qnMZ!7L-/Kk̦,!!u$PYB]X( C ]Biv[(⦈E ahQj[ r1񤱈ο]l_o{Q:t7359o^~yuo>/7wL&w_?U/P_˯RnE׽Trz|6S*_z {oZf5{tMA"GQмdɒ ֭[c7966xg}~~V}nfu[wV.S'QCh5rQH 4bxFIQ?zY6quL6# jEI֔97R_ PL0IvIL˗Ҷhh fyBSTY7vSaXN"b@9Pƾ.p ]0?߲{ҋ6k h"Is%͉$Ci7tSv*E,IFT=';Dp5 סPK  Mu0~(OIfTj'EtCdnmt/&8{9t mۛtf3M#ͭY(~~+|~B3:ΟN!ϿVHwo>y Onygg'w_ůk,l0ffcq5m߹y 3{z.m@VXa!"cbV:&K5/Uі 2y#G>V9Mrd,[G3$|84b}obӶ`?5q^F)o8r|az Kq`2e֙cf+B@"Ōjöu\#*@l!5FwQ?Lo @QX@EA]^-{-W]+keUD6D@)JO !!OS{&Ĩ AL_33sw&}S#K1Q$h0g&q 4a6PQd T+YŢZXQA!Jh&^[TiTBw4A:QP hFϩH͞2bD$KFrz6;fI@wH溆#'˞m&(NaPL>р\%*Y8Z,qx1(Uj"` >rN&)g@QWk@ d~ GUDs -K2N>@#Cjkn͂.n/2zX"W}@s!*v^ztV&<,3"Sq ŀ "B>VaF! FM$UEF@$!<%I?_HvYL'2#*pDA7ň7pLXO4="-o9'[h+hA`TM4-(k Ӧ&UE-2 meR ,˳4SU% s\Sr4j* D@Hz#G&J 䄍 Q'?Bű Vrz0KgrcYVŧz~޼y%%%ӧO&cGe(3JDdHUEgH3&;a(1"s8$eb᳔dG5OXIIQ e5DK<z =(&CXL6fJ'> S\NfhhxDz),wpȴb(Ej@4b/%UDhZTPZdbXhf[ "[I%ZyP"(=yIH\6ZRC9܃CG?W?u߰lVےy\T. iӦѣG1}ee~͛@w(VМ&0q4Y4+XE$09~UZcNE xZ\3yO[l!8шҬFī zn䲡JPő6Q:`֒.3ar6y" i;qR0oi0"q*s`*? `oFz"ZUAIHZnp!xbX 'QH4X9;X{{vr>p|/g̴ZmɩEC`ٵ: JzQÇ… չPQe\9* e8^VE)aوV(4h!,a49=>9R.(<53ɠáYOy)3u4|~d#q}y\I!(NdME(&Gq$`@+}iiE(tV5}XD1@?6F7PIՁ!4F-^msv:,&Nܶ|ŏn0a0FWjO>_|Vs77NUVI3`zʙxb`I&T %#i9t9 TVa)KJN#a4j i! Ć?6t.1 &4dDFEDe_eF&BeYe48"Jz ncbߨ,Kq JQcb.kzpdYh@ @*`q*'Mjhޣxh: L&˱os8xtu^^s>Ѱ#D>t;\1F'OdY6^q=sOJ/B&k*FJѪR6qXf>87MjB$ g0'5+ǰ(F4CAQM)MH蠠*mOS,He@%bUe%El61Bw&#dz(r*Fy(F)1Y4 = M_ qՓ桺U`+#7mJT5Y,I4p h g^ D!$^: o~;~Ki+^ۃ.'''O:TBO0hVvŌJͩ$ U KrP9Q"LfJ(YQ:!My!5B3%I"Tk 4#3yf kF GOwPe0x4[p+YRm2adTݧP6hI-7 }1 ork mRg2r}O4Y`״5E]^Et_hDӉb Fc[PW~.t1} Oz7t#]9j2^NuU59#- ϳ`2f6[CqC.wA:},qjgX]àUzt hk>:CCQ4ACq2GG8 u3eYweŻhZ&`: n nEw^>4l3 -={ IeZs.WK|A{N‘l[W2m%|w---UUC:myǬV^΂so$:';?twON7֭[WWW7gΜ~rݻZMMM?뮯=k3T͡_]y5< ._x6#3sʴ7onj0pPFFлv~R?| zcëu~v/PM{ECƍ8CK_~?~}UTVl߶{njl^?[Uuʇ~_R䙋 <*xsGd0`֭[e^ LL_:1hFFfnn !NgϞ-U~ߴmu]6m:p6n8΀xmë99/[_+޼GVɊ\4dsk΅~rdž//];w^FY.dl_pŕɩ)@`>xo7ݲu<_^|ᅟn;nG8`s;X]qˊ~VAX0x].WZZC >r!%7ܸWC =x`'zΉA}]-\̯ Xj}b/.xv>Nseee ,ظqȑgBFc$"x[<ꔩӬV+|?V|{ÆP%;'z6` nN ְH$bQMT8o|c9 ohLv'QQYQ֤+nMMM5s֚YtN|(o]Ss Ɔ;;k?t5N `4=fca93AoM>_f2_{5Xmjl RiڡCNzO>yrǎcǎ_N:'`?d ; >\rѣGG ċ/ LBxxhK`v!CK8tXbW\y57`Pu:qIIbw~1񚒕Wt)B-Ѩ4f,}䦫I2GЕѩӉA/$Vpja쟖"uwm`/(Jȋ$UcEm~UZ]#se0}{a뵔T4z4|$(_sޑFy:]_o_+¡وn ѻ~gvN]? gF9 _g}K/efe-ۑCKnXҺ-_qK}C h?Dd<|F~ZRD?aۡwU%V049b3jxb}H65VCӴ+IWX""Ij`U?{ܯT2LKr+wFjS|Y J+23K-VM IUS  lJ螯^t׭FE>?P_S,L˳A|vz-ןzK~_ż 7ި(lZzMYS'_z+zgeEƥ6JQ#E#g]3a-}T[[uݿ^4LW]y/IҊ+^&O}s2;xa˾;5T?=87fRFZMSBD|~M}&X8ED 5,ݻehEπ&HQ'݄DnXfxUaaѵ'n"ѩYr#&dQ8i 5UU\к1xG\4 6s僤$dVWU)KSw~bSRܧj;K Eaɗ]6X˦LbNoXxÇw|oTWWM4>1jh޲eKyyu]˲{++*.q}} BWI7i孳׶oU^(5N9 ʘ:4?4Ƽd|v]vX8WoGlw9t6Y[A<|xuWsQUP&_:%f;)ӦTo9qu/q͊r |)"WTdfe¸y-7ojՙM! DxgPAA,]w]~5NL3gΝۯJ3qDE#st=>Gl o ^U46/om|pu7yt`u` ˰O'[O~3fS c9x1UJr'x|^'Ummi;qr@~MލF\(0!F9ƍo ˗+/;_O_yUv8qԡ`p+\N:(sG=шZT<77®f͚u+J?=c?yHRwV6#glLi`cGL 3sn()R[ӷ_v=PT6(>N+6ɫi:!Hp-).,l͝[0VNgfm sm:=Ӷzt< qpnsTnnlRtzt2}ŋ"_睽aOwѥ^vb8c0V?o;  IQ U[/h&Q=ٓϹMQcZIvW}cBidMj0aۦXM<#t2j~@7 o9iEo}Q>p_?xO Ȳ,)(^/=Ӫt $IVtefan+_;Xl{+txi:o|ᮣFP0uo61+fp]|ƲwwuрmcQUU[0xp~iv/o^8iϽ7OOGC.)?'5)v}Dd09V!TM#5?0fP{qI痿Dz {79jk5ؖmϱ ,ZaÝ.gVVfkݭ?UUpw:\8X1 Q$"HFEQ$UѴǏcdqu;w~;@~@ e}Scy;-9jtKKc=*ʴӷo߾on|c䨑?WO=ܳg?sA]6壏>4+n ڹ͛6 ^ZZE_h70tXo(:w-"Q`TVV~:_5 FU`&: 0nƳ;Kx{UJjkZbipvjʙsf 0Nrs<ԧok7ab<*3 a8ɝl|^ԳsH}$CϚ|-`;7464׿w~lg8-?OYzNgUՉW_]L|^ ɶyIչ&ΰ,ov@Pb0q%%Ϲ^ aOKK=ςQl4@Ԏ=TkX砻-8s.`XF6lĉ'_> DyқMFlϭ$7$MApI$\{P0اOX;wl;Nr_xkwػYYY,Z$` fK<ܝ`u(`5QF̈DPQ;EU%Q!6/F(2LGj} ɨN[jy <3}boPUf&طh[HMK+`X X!> 7rEEQ6LmLIN&Nsz'.7K%Nj[m{75%t{y}:vmչeDTٱ% YUTYTRbXd՚X`upNvI+*7*݁ Dv~?VsΩ==ޭ c0ZТ%pl&|nrĐx.:c0LO3D:wP(ifY:hb2eJ, DЦM$QYI'ޟٱr >aĮ>PչC֛M1/eYZt娪;C!VgLgȳ̔ɓXT{Թ.lٻ:S7չWb'E9ƈ"KF;0]g~>w+J 6lF^ [Ha4/ܢ=\ :wEQE1 z[zv6E82z'z9wdYS4c 08DQhk"չ9(rH $}<33Rq<|tWDžU4euuybE]8tҳe͚5˖-#tu0]FpV7b(󢒿$z: Sz9QDf٥+| ( r*,vnG6kQC$u&)r!=='_nwTMU@\P+AgX 5Zm4#GDE}Tvlƍ'NUWЫl߱cʼys_y h۶646͚9Mvc۹7\JJB< ZeK弔ţm$M""_Zyvz ^^7ŵ/n84`;>ʅ7Mvvv(JOK+O^.M3gnx5I5l;c M?II zaݞ}'[lա̛;W} PCOG'yFZ/gxcC}r7n{@NEtzzT>]^ tq6ؖ!lqU_}l5'V\Td乭aܧ:wfX=ـ4B-mtY.oPjNd4EpÒ0̄SF>pBN'())۷a@ﯪ:Fa7c)W04,z ͝} AtP!ㄼ'9D )ޱcxYBX1bD zsrsjN%\Ppyy\;6`+Xˁ@ BϏR?Kuupykj`;=(9ONPB޽h0g!C9ٝ.1.sG3xh2CoOpnJgr`3fLw9cǎm/,(<^qh6-blpf;yhÇχ3ޚ;gt34v"KSUΈHBYhnIjWq `m;xFcLǬ/oljl68s9Zf28:qd &5 Ͱ}ee%0Ο)rri))^:)y0%G-X0 mp8p5UUU#r<6I(,xN ڦ:oc_W)%zMNN7glTikxۮbi),Y7*`$3#**%3"ǃǼ[&M;")0uE\.gl!77^6=-!F@ m$;c]-BAWqe%5~Wi/)ɭsܱI z(, SAa`tmzUJhR4)r9=N647~0u.d4LJ&H}C yEe/PGxctۙDQ|'%Hh456ֻ}}9굟 :|g7l4pٓ "Œ,fag2 }+++2R)M/edĻ-V33f ~~֌i]_dt! ͵5F[>= g饯oܐdyO`0 78i]"E`u>+%7I)EMAO&PD$H%`:C3݊VsPXTE{6 ,RPg> E`0 Vg `u`0Vg `u`0Vg `u0 ]xhY`VAZZbw+0LwrdTX E^_$G 4E%3$g5(0^  3;:@3 \AB,Ff6I2f1Lj^DMX.*v\H7cg~:ml)}LwChe: rۨ+Y/ux1H׏dgw#,08)9H. dʲ 8da{ K1{$RE**Wa:=RAiqzd" vb 601oR,%Uh'͘T&5'Jhv ࢏6! l9wh~nӨ"46=cU_9?`S}E$MsGer,,6lC%vxy^ aj9 ˴)p갘 2n1#hhOY&n})8BF@x¦LXs=>j_!IA¿wv٥[ 8|G| ߇% ˾tܐF_ϐ6qkNBee?BS#7(>aK"7\,wú\4V m6r9I&FGG/ M<]]]EtD_d +/b(JH|a/(p<J|D5d2@gˆ (wp2.q ϋńIe $a5V3!,@0R@K}k,Љ,l$`q(zD"q:wޱB,GDDUUV^| JZVB UaT*y6nc#Gぶ1 %BzyW|ʱFFFF#IJn۷jj299  رZKJJcbb @4]Cؒ` % >wCٕ*`l@-\H8C6!ϟ?y aϠ`0߱?%r {̏c<0 +?1xÿ4<1_qBܧԗbrX#jG@Xy0ͅS.,,x/x%NdrrK\VqP\@qqqmmm@[ PO^FX,~))!JklVM* |!J\j.C,ar ٖj_`}tn^6` l&7`v0 P$_f& >.'}v^,**d8 gΜNbdrr"##]:YPLR"0-3 kz3224Z]\\v8*FDh:o/VP1;;+0|T*$"#Dx|&v04T/BK -MT3W?mvPDE_8XMgV+,7_p'й@}?N"pPx!3P,??F} Ғe*gZZ/]0=|*j^k3BiTrO] ptv8Ctp\@pB ,ByC^/|% Al! +e(3NHe/JP&S)oy 6t: qK EJJrC. cwKa {`)_ar E"HINN(ҥKJ$bzA@~zˡo9jˊWhANbn\J#D2;;(UffF}IQҲAzaCv<`.*R \"{<[nm߾/匌,..u>1)I"ta'RSSnb),,lmmMȠޡɤ$Je2͹\. ?88TQ#Kh>c=HL&d9 c'hVcA\S3 P`(..ɧAcށ3<< sNnn.(=Anh\A܎ѱSpɓ a766n۶fAkP o  ͛1wX,;v|GW]] 5tuu EG4+IRRも8 MG(I1 NYq<p=*<@x{3Ad9GM}& vPA@OZ~?T!lj/}KA7`d56pکe_w0;::@innh4%@?~>%||[[X`g =P5BwTV( vvv6++ -99ynn(r:r]BBX @@`y =EQ Xu^Tn"R-x 9ާ{'+qnܽ J .55޽{ ^ăˁ111=B$ hh O/2\= ك 444駦A@@@@@1 zi|;X,NIIkIUJUYY@6%;wϚkUjutt`IsǓ |?ԊG$I>s@|ywwO0%\8-:rfY^(B.VKNv2 Cee'%%qs18 B8-Hu\P0-TPAZd޳gT})IBgAsBKv3@|B3Ϝ0 c]ZjsB; {)42q^H"OA(/[& CkPlj ݇R"a=98طo&A~t ւmkBw \ˇ ł 9GR x*+ QQ*n:VÆشXeV ܞ4n(GcưNenF P][~-8(T,8)q-Oe19.>. eii.:BxC8ؑ"lއ`x0 g)og}%\ė(†Be?7 s /P (Yp7Sf}Ndu'8\.^;6 ޛJjrX-{~XM<]M2B*K'"A^#>#3#| |&6HDH$bh"*aߣ%!^Xу.Qҗ-[ie "|qįb GpcJZX _^ r1IJEiܹ;vJ:B@,2}t^T8p`ޮ銋B:6(fvm,а.:ZJr 966ՕβDy۷ob%C@k?phh(##3.N_XXXWWwࡎ{III Å8/**tQQɉX=? qx&0ntZfttTՎLsV =%%,'effu||LAY5Q8q ) }ffvǎ ܒkWessUpGylu(JB /&uI4==cf6JJ7oinn.%%(!#D"okkMRA7P5ЍU*P4Z(G@@@pFEE={VH R)EbK_ 0ΜJ`iyP-,,?Dx2W|wpaH4$V]G?33s-@@@@@@@XFUWOEŮhU<4M;a@*%}ʗeu:xkv{bbFF}p\33Rzil 2Fϛ[ET/3zn_\t.(lv<1k2)^LΞ:iOx^JcT|= < '''LC544`>U$bT*#\^IN'%Ķ!ϖuRl+j[S#f#Y =sgrHhʃIuvmvߎ88+ ۬oDwH{JuIؗ//~SE `@̇[Bj˷?/**zͅgnmkݳ{7ð }l-4UDEF`S:MX!{MކDIb Xn$ɽzbV3O;f.nRL&MD6LssSEEvŋ:l ؅@ PHZYmKD䔗0- F].OUo!6+24zt\* a{нy W]7CBR~r$)%D~iC-V;SFJ=2k+HTnC{.ti,K`DS&0 N`{JY^xuNǤ{[[%'O8ĺhZJ}lh#ǂ|Oaw~YZR222DLMO8l'JJ _~u;;z{=4CXldĩ_`q@^R~+H)(x+477ǃ^#/P}`=ܞQT:3csVA]_=(L&3p]u'kCu㬯u̝YRIe~=W㮊k uG](K[1L'1A8*}zc--7 WBjA>h k4L{c+J b텔$n8ТV; Ӫʦh]Ӛ7?Q z‚:&>ח禊px<8)J,T:I3}Bg8eFFa<`' 耤9baRh:47ÍoxMf3p9RL&_w`{(ϔapʘXDBu~$"~.b97{፭mlLI]v+'"r~yG6!,QznjgEFxQu$۶Q۶-u[_zhrLbb"Ƈה۔JEJj꺋ǫ s̋w}^sCg&{k_S>dquzp029p%uZPX(I}@iݡZ6:N6K{wXmwxEj2X hGVGNqټv NQSTUUwJ:0ITJhvw@W(Ku~m-سgOJ27 X]] ,ۏ?-c#dOKr^R 4W(5 1*tU xxaÝ 2hC.1ò4굠x|nwjrWnf'ϻB`8A{?S,4 y`ñOC`):q3^D^ZJy\1]xk^\a ^@vw. -"(99)oG/ xRr<~!֨~WW]].L$n/_VG@@@@X ,lsĜ8pr*W7-ĸ^䶼"}}L_66f{O-/+.՚2 2.ZzOCGQx5s #Q0 )uB˶VJqK)0$%Et\7~ƍj=X^Ϟ|.C8=z`)MKS׍?0 Ykj趶$W0ˏ?F C||77… #m6ۼǝ[/Q8xWof߾};w i(6ylffqWmݻ ؅?أ٪owUpgw*oy ZI.vvek9:M_uZ >Ľǯ;8w;"gNNN@mv= /XS%Ej\BEu/PgAcB a'5f)mozy@J+_jM%<%U>~zzxAf hUؘ-%l+@QȰw^P4W V,fI &a#a#l`ANgrU`{>%<.e#ÿmG~SSS~;xuR꺏m6ϯ -oiiillDk6"Z+9/k2<7A5d::A-! c&VOtKݿgfe=skZ/]K Z_О4 ȝ"ȮS8uK eXZ(I&Z_}[VZ56>`ؘs&ۉDo|'Ox嫯o&*bo(lPeY^%+:֗܅4Fb%,KnjiiٹkiFj8t:~^qqj}HRӥ$LOO$%'+ nɩGӌaztTT6c)ybccyGqOFFG<SSSܶo'&ί@qB_Ӱ;@E%7#8ˍP 2=$&,%š``l(SI91#99,KiIO3ȳ21nĄں:8ceph]l/(|ABBO>TR۷z% ǎw;wV/?ћqqq8^.nxh= /zz},zxp8wGX/ܔzpWwoRHdx29}1|DiibjnJMtGGYQĴaؘ;w*raafBV߻r: YQד$j ?7ÿ'߿?ݻ_yA獛7vWWLёݧ׿~W=q9\2>J|btյ>66P*ʒ.*a`/N嗶'?9uԭ['teJ"|q`&,ݒn8lL4I[3s퓰2w鋶чzEx\hledx>s︲r>vEf~yLLL,,(Rv9_2ǟ {yS%{}s7dA 077b|ƻwsrr$5,˸nLکi 6Fa5HW6jNIII:rA-JUQsՒl /@Gt1&&nuAA # d]]]UUU$''B#CPWW w=5-MXw o߾YKwb/螴;(fXNTJ<`L>44tС۷ocN00\vSxVrKm*lQbvU~ՆfiwԍU$+9<{XA)"e6 L`ٰM>[ETA(,9UsׯgffܵSOHջ۷/l0dDVKK |ݻ+ d۶v;::Beeccmmm"*M f (Z7ะ966 hEEEwޕJp[[[΃Jמ={~ӟj4pfg/\ ]P@ MMPJ}<ƎeK|9 Zl}}=:@0~RM=|P ȝVAڭ 'D:;5rnZF46»pW1j9%p.9xhS`o!ȉ}L4uc_?||s <^/^XZZ t{u|oj$H2K ,=ģAud //O!**..,o)0RAせ-er9֜*-A-hjB2)ha3`6%:5<3Щڛ7YxG})$scvcKȉm@` %%a%1tUjq7JV ~c-qWѷq &LLN?_W^ wO/_{ߒ84ȵpb"'qfZ=/׾;޾}~2oر[c_Oɸ}c~]} +ЎW^U bV;`t"h6v߲,8||@Av \K'fRVIk:KhZc~ ue_z14KJWGFFRxkbrpȇma3_l\)̚ sh:qHz;In t, =i2:eK[@Ma]ttddd܌ GGGpJ};E"Kvmu˾STbpƂ,JSSSC2tvs%i6uzv=].9Pޔ<*;߇S5]ve/5fPq"jvS(\;. P'v^MZ$IJ7xO?СC]z춢⾾]6uu۽Ƿ[ZMt8F+#C{ΊaXU'Iщɢ-HhօI8s;ava="V\.zeQl8{\}{4$ 3:6w}߸?4<ҿo54ؿ?( ?F#ONIX_AࡨѾ>xCJɩ &EQ/D+j>[L "^"s<7$$TnX Yakk+ړf`'c973aMWR̊N9N*%i̓B@xT%ZqKyO:{mkkojj<*`^r07kkvJ\wɋ zꩿIOKI@;el0yoϞ eRRҺ ̎v!PSnxt}ȧ 1LƲᒒ:˷geE(g}ACbtLL A^R5b1. UIvEF'&v6ܦbID;8>d:"~BV"7,o`_T ]صk'go˿{qn@+mzzzcb ?V.9W_~g׮]rh4~vN|+_ [1 ǫT?599}W$ndJɍ<ش ?hVVŹ\^utzkFEq{ pE}CK!'U`?0º,r/1jep,m'ʦ"=.n+}k ٘%7D@l̤V>~ϞΞŸιC Q5 v)Io_+0E"sgKƹ Rr6O? ze>.&.oJoq$VUmpLJ0ݕp:9t;&$Iўz-X;FtM5N8dn~]bVdaJڹ%v}H<W,r +b8i)V P/Mb&-!J7fGGRSS%P={]I^Q./{Ēu8_2|^/#=|8~쾾9Lۿ?pT^^dUUbm&$͖)?j vL볈DSO};sg[oSɉccVkOqQqm]}fsj+`jj&Vv;7T;g1 )ƶDd{H!㋹vA\Mvb$_AUMd}:Jٍ]2 fhw\&F[wtlFCr3YY AwH*^sݩS񥥱{g2|cGͱ׹X-P 8LM\p]W.^":9{XdMMMΝNGno-"EQ+"eo?8ӹNOLt޻dշIہ//;p t^"0b(tO z_3 W *΃(~G.~!uvuy|Bz`$ßZL' [Pzs8)b]VJDaf\@`'3Ul|=ζ6YT]ZJmd" G#8ܹ{ i˵ΫMMHPk22=#9YS]47窭Vm))K9ƸMG\>RU85޽"Gݻg$Ib߾ @]Uj4+W(! 767O}kѣi}o335##o~+JM@O?ֿ>1a"KJ_|;"0 IInCٜܺZP^# }v6걅`oÆ9o_=;q|TYlj5fԩ$futn7g||W2Ғ_q'Hɒ%˼7wUA%ghFBKy',&pJůV^MGpŐ+zKYYzI(lټLuSΜ)ضm :5  ܮMR  ":ܒ^OojUav_e-p, Î#(L}ܭwG~:lr[O=e}:?(Vϫwt)7:mK{8^TTܜ^__#k v׭[)W\fv{LL )Ta xi>-2?3gάpݻ ;777W8u8/~.ˏ=&ܸ~}d:rL&po=*vyLn^(b))n7e\~g7G7o>p!1)iΝ?a E84#Jh0%%%+`jLOO\*䲔dx̉O>w!L8Uv="{ AÇkoބ怜XAX,QQQPr|lDjkk۷o_CC2p0|} HTdήxv\^O\ z @ț7opYHH˩Tnqy;eîk~oSubaw 0n~SܥmP32FVC@؊ 7 x/AO=%nJJLS7O\NNʰ`3N'vڐҲR ᡡPȁ1.~*#edd rF{U4,\%'' ܹs4gbړ$ކc>8hin% cbf)PĀl>m۶) 1tX,5"&9%8hυggÕn ¢h-_ĉ:]K 2[ۯBٲ&35n&>Q&,^]xnOu];g#lakV6!wN-ͣ_S1*8%Yasa%j2U$|P|,\s걤m N (&*姟~N[ 6U;~tl%*MMjbgŜq.%9e; Zjz>~]M111cc9 Cߟ|={F*WYVuhpp}}a\|z]~򊛯A@SRS`v \rb8x;$)"4kWڵJ955cGP{Zu힙Q(͝?dw^SSU]؄s#Ϟ=wy[ujʞ3:tV}:vd(ty!~SSHazh`Y{#$X=Ի].Y DDDjZf8wx痿<|Pggg(ǃ!>QTT\__ bhI}嚋 #L򒆆ǓF<l`r%&==N,X,#G_tkxcgt㗏 >]w93gS~|xsm>Ax;7s=t9>==-d%OCw+<~4DDD$odz²iδ3t:A^}he99p D?"wJ-@V+C]RTU gegm!s x庱>^8u8w"طKfرc  )O?v] n47W\RؔQ^$;;[h---G ]]]ee ŋ?. WHiii额y U<'::&ȯTZW[{͚0nuzopw8죣+1$$C@@J`WB0鿶+/$%3 qk!N9ч|o{u ;|p{Gŝ6kaaэ\ZV/f&j 9|oFn3M߿ua[S"tvޫ?tЭ[%CC%%.^,++3u߿J+**\ūCP4ᵥL;v U.p: eee *Bzaf577_fWe/y710O̙3@>ζZw @P <}˗vMMNC\+++ۗ I2));B U ^7=5Z!}ltjs1@7.z˝5DQD@@@"cI+==LՄľ~O09R{\!9|ȥK3CaaAccSZ @jJJii62l2R"yM&S>48R@`hte,bݻwnY{S&:u귿-@ @LlPjjjLLJOG0GB1N)Kn".Jq㼽V>z_3 *:]_$Ѝjj8qׂ'ps~qqׯ׼ؐ'x*Az< s[S l*N}.WGD {Ϟ7ndd *Us;dtQ`aGEE= N"ɫmZ6::ZTq]]]&\^n]Bg)`ICBЀ6֦P(+++kkk4\dkS11`VUU7560:6 vs&=#cll 4Wz!I 7СCB:0_ZZ Ug !A>%%o>ÆE.4366 S]]-}"~^B޹\.\=-gu757 B@@b"+]F[9~޽)lz9jpY߱`Kj#srrZK?3{3nrnŗ^/&\((^O>C;[@/xF}=ezŰ߂ m|x 9rpJOD8M8z,_¤@vvazջݮq&1~n7LO,v"En׊J" |I{ Mv쥗^^WF^C o?lC_%t1HR`1[J$ qh, /ThE44" l(l9NwwFS8ވ˲A1<Zv݈ekpS@-T|.KDz,z\nͶ$7==}mpgcδɘ G"HfQ,i%ˡ>ue?~eonm}UzkTlK$+Qs $@s}h H +ְsΜ}O8jZBQII̖{kpk8rdV(N;m;RIeeeiij دg?[Z <|\O#^:3 7rl?\m *o۴qw 󿓒~Y322`ݺ%Æ#;ۖ}EÑ?88(&d ʡ̌+y>%AO,#\.Bdܷx}zzzAL{"FGe?#ĢKTgnWg?ct's 05& 0pM u655٬6q?$!!`0h?v2ysJO,##Qs8=nEhhhhkkKKK5LC /J /r,.n#9T5_=plEE-((+).غmksslf3@222jkkӣvlӳL^@O,+NXII:=i5>9544Ӎ˽;~س,f(FSzz/ fzm"$ONGN5x8-U ޮ ߺu+#A, H㉠G*曇nnn&'`Abw"""qvʕ+`k&t:-kM~2Sӆ@)b͎wP{`1 !4b .^hw8㫫b1KҲ2l5iT*Z:{FLLTM0JS& @H F(Bl6ȹlV*6 b@O=NABOAh| B{wК4AXH㉐%//h =A4YD"H$ A4  B4^*t @YC@0@[A<2(k k'!r.vv І\jeO" }vl["wnnnnii\h[XP`eJܬ|6 "`m+̌MWz*yҧ"Ae0EVGurB@P J/aat+kcǦjk !XR_eb`0LHCC .R;1qFԙćZ4-.2rNjyx i`brrVQp~kΊʨM7z@ 8^(Jv}n蚔䮬ڶm E1W+l6\S*A!HO42 ԩC 8/TX,tg{-[ddd<xiL&S[[[Jrri[o ~|95.3 ;c#XL ;c*sŎ]D)FawdZvzڰuVh곧KRYscǏ!2]zfM wtt"urقJNNQ(r~rr211QTYfg_RbKͺ+y{jjQ>lUS3>1C jlfg dON S6; SQQ6$0,.H(}<)::&<<G!^x7'"ڵkO>-WBI H%W_} n(N녊)+959-=#j!0-:;b.Bpqurd2BPs W&&$L۶mpϢfNS*jh~%ۏh|J S-)=KqM d_WX@ +6lV+`N7<<81LOlڸIR=zdxxDRGEFܾukϞ噙a@NvNBbbXX5͎%Ž}}cqqq2YXBB{榺-y̾3`>7 "xXD l0>~dzcl>ǎl%ILLb3C֬YԹ"6H nb1s]A\33#B+A֚SSm6PK,/ Qn 3@i S!9c '3%C x:HedG{\.W__ottFk!'Zvddı1phM V8I\6ova[?pSg*]v{D!|AhիW!fiUjnOSRFGF 8?w\aa[n  d5c2'&&N'baAAj;99[v#_Ɔۭpv__g+G("nQD"]2DȀ kP ALxV֮ˇE"RdF?f۶R:0П߿vڧJ0mv%%%K$z\wC9NSq9]d2E"™,f-2D3Bg~}fSe{ CW^_y%\1s uy|l8\w>;7|'#zqݺBVwtwvvYu# ;G,/.wll̊f/:11G/ Xɐ nAw||D\ZOAh4* yBb"v55 "YD'''vCT*'o2RPll,Djzdd$>>^" Q^HO\Wnw{P:niApjܿjOMM)sgϞx9]h0(U*e۔JDDDlkii޻wEj4jƍϞ=9==V%BԢǟJb6Soy 'P&^]rLV\Rގ[Tڮ]nG[ gggE7223!&|򉀛tӦ.\ 'IC|h|@,geeaCeegzCzZNfjr:ZmLLLZj7Be>>UJ|Ӊ0.L.W SrDp!\= .Ų phM Cg(Ymh4x`xh _VxxxeeŮݻ[u:mBBbUUՎ;"c+oۇv{tLREV \/3A,/Dm+e}JHLط8G|B߿ɳ8 7gRR>SRR|q"p:]NfM'J0.I yrǏp VhPh|>az`XRWZr`Ll{￟A0h={ԇ|۶?-ƣQvgAA x\7l9FhM V8+!5iXA+7Tcc&yR(/x b#]clnqC?NI>bMX&˅BKcppn'''Rf_  %ZڱݐmՄ;??^6-Uכ-桡aTjZu:JT58?yf}pMx\|\RRr{[J>z옇i+ /(X;#V66`0Lq+A,`CMNHL4LOj^& qvBTT!';kf|n^Դ.2.bTrA, |OOp !h͛&CMLL贺w"glٺh4,Wk4m,Wc@ 3AS^$Nd !h|ܼt:`f>ȰP$,Z[f۾cvݺJ{͚5F>3  c۷4AA4>  Bx bE@D@k1Z? BZ i  BOIC 4YhM "QM$AWSwyPxF%gv5*/!#b0'[#a2O q  f{M*ի5vC WVL*0O]zv$/4[-ӻהRw^':DڤgvN@2XHҥfs\V?;'%66V-8$"?>gNKpڣё)< j5u 𜑉Ɋ~P;:d2wrr@E"HDO… =>dյw^pZunwG++$P\)7A,)qWd,'`jX56U(eeeCC8ʕ+`46D<hßԴ!&xJjT%XLevFDhJ3b[vXu rDs=~y,8ǟn -~ǞpL5~=aױ9Ңꊹg"77/RT*޳?3`w8ju (^s2 zV/,eS&mb  =o D7`a߱[(δVvv=s_g7PK  u L.VnV03ǟes.(xʚs?u2UR)*錉?rHKss^^ނ daI))D5nL:CuTf3).~(1uy º}BN$Bl6*^%⑙3/K >2~_|j= y]Bjf͚/462hi!"Q[lYՋqrŮőz{8dhh1X,{*)|Z^y۽}6]" 3P+\k.O(/ S3˯lݺU,~rʪ⢢0φ>|q57w3)O00pz՞ݻγ3[$W(jnr:6qz꒒@$"h&MРŕ "$qh*1?xFՕ_r:?@8&jvvu;I~rj*F-DDGl-Iϔ~InKz:pM@0$MfsԴjyO~Rlmb9j:v(`v4ݼy;ζ+||(ofW|lꩦ[&33C*:Xx܄KS<ԅcM%BP >rD$BJ=o]*--ݴix׮]3lrg*!_vr͛7"\T*Rc"=~'jaן|Ofщc'p&!T>A|RYi.ʃfnWq =5Yܬ[vK%LS(Cv?6~w*=N;f3G-Hz77lJ!W?j9 펙GF>s^x×9GcjsMf\eXq?90g&FuP(<.6uO)peĮB8B#2\/Xg_88<3#f&Nkތ,~Y *7ϼ{H/ZE3GN{-F¶Yq}ؓ`O&edo1dp/'/n6\_Lԃ1[z``d} Z골?a@te{Q`2Y%!^6C#Jg/XcGO=7k`bf9gsF۴y|1v?F**?doԳQЌBHĒǫ&$^^a+SbK1>-3Tj48ŢEv?->xA'=xxz_"z_=*"G{t5>F,ʰxh> F@{ҧxW[LRϻ=],/٬^\GP*wTW#"<WmhZ'=AAxT&nwgF^WWg4 rsMnn{wz;v 7n\"""hAAKBfDNNJꊉA`z}NNж[oVW۹é$A|xD555(++@. vQQ/_qZ+  ]p:z[ƛ  3)Ƕ6Tw ~cǎJ6 ɓ'c+AA>% b1N' 1g]6]$ߟ~a~䰅f@FF-p` N7<<*hhhXf * n@ɄlfZU*jM*UWWLH$VjjjZz[gw V8Α̶x ,OJJEzzzv;rI__4J 9-05 eElvr׿u2"sxx-{wwow^<b}G[6ŧߵk? tZʉ pŋp3߼y_WW>w ZVV4feeBB/G6 FGG_~e\|**r+eA)ܸqc˗/(rgaMMݻ3 dpX񠢢_{Db14bV?^UU:s _m bɈijo}q?o+xDъUB rCW\AyiT}?P_D!kz{{0)6>P%ǂ%"Opy  Q0 !!ĨkkkPKp8t">x $2J <vz nphzuu52Qrdd$ha'|cǎan1~;1 pa wlmm.12 Vc⼘AxR?OE--mbbbjj Gn7BիW{шwvv"ZsOzFKׇH }ڵkYpf4aLvv?m v6mboO`vݺu(/ԇTdw[,LS"zSaGP^ق}ժU5ssAgߟm.,,lkk^&сR@r0[V6GQQjݨE#==ݻ6 ;޽ƷwOLJoW޽{!hyx hF^T{{{$ߥ0K.!!ohg}Ο?!&7\b͛7&$$\~B""2_WWzs֭_=Bծ.Đ[א[|ts : I308݃BS탅*&99Yӡ"##kƍ f/aTKlC_%z ~E cG;pkH(7./Bt'&&CEE!`'{6ucF 9<065*Q=(T^޽{ӦMnA˟YG Gcǎ|hЮ?>|-Z U8޽{qhBsA 6^Rr@P{ԁBh**uG*<\GǏ$x<6PX6Ħi=={0l?Bq;6a0W  Bx"8 Qrœ_ǛHber}<;{ԩ}pX_v 8Hv)g67:l왷,"Ѥ|L +;d| v˼|_ "`)(W C "4x@t:.ŲlBQ6@S`8ioogwRXX܌hEO@)ܼyE`'776ܹs'==l6OMM}#K(\P Ө'|PW^EUd ~ձ 2++޽{8&(d_Z{.LBgb16AZN?v0j)O"@r֭!6ڵkY IXQokCVyo[VV^ l6'D횯_ 744/5m%ҍξvhDr̙s9rD=%~&d~ww7~D"~իWCW***D"4!!񨄗/_NHH@(/؉C)))WUi<4ٳx'O57D.!cZ63ύ7FFF/ذ $l 1 8k4@:xXj<8A8p qBi~hy}jbč7vvv_=njAܰ^aK2 Yy-""uC&@)B0{>`ӦMoۈ%HDׯpK7oYڋ⃪h=\|Ν`k7A9z`n{߾}wUUU"c'nLMM nGZ(, =j ? FFFd? ì!4A j0sl )3#@DS^fЧ_~5j:###Pa(J42/}o=[sssZbG}sN'F$^<,, !2 8q ƣ"|, /4~ڵ׮]'Qo{qxXj|DDDkk+m4ZdO~Ch͛WV ^ CGlٲZ@ŌG5_=Dtw\:D(q8v.FD~e CPVԖ7x=ՃM&EP6m櫇dnذV!CP7tt:8OXY]x[@ȐB T !G߿&%%`EEo(7C%e  |tTi| 9 PLt4'2F{T^zu׾懕ZBmzvH+[.--EX= bh5 2?g$E&&($ZUPPpQXsj/2N~-ĕس$#FGpc|"Uf(sk|X͇cu ɱ鱱l-`8#Qd?@H}֭ĶJB?Qp9~_(*vVW""2Ƒ=_V.8k"|ްpo,| uP6|2ʈ> u=K}_ՆeV(?Ӈ@ JŒ[P X9Pz Mf5rݽ{tZք7o5t:cId6aLJJ&,{l֢F~@fE)`/g]lCmmmZZZTTTuuM戈hD#\~{>_}EEyyyl__*d~~>+#^ cu|DMMMNN 6gppMPh`3~&MMM@< 6lv "P|Ȑ.oԻWގVIVO;wL&hЦ4 &:H-;H?k<CT*tVVVhii Ɵ={v˖-.\8v였{rDx xTdݺu׮]O> p@G/^k裓'O"]\2114fgddO|5~[o/ek<*͛Q7n|Pp02[Z$ ҥKGC-PǏz*9ڄί7^]v!:ξse$%%UUUō"\rtww#Ѥi ٽ{bAQԁ:ݎZ0'/ B [[ :wvvƑ0 rAΠ8u&%%vzр %Aa\.| .*̀9^7ΨB@xd>BvxZpAP.(,|R^^݈ - Fcu fs^{ ++ !8p`޽lv#Zj6GƤ a0"fX f!N@ 2ͻ6 o}[Ç.BQ~|euջ6,8C fO;o|2_1#Q$QC berQGR/h+YX M>ҁ8`60̍'Hw*d&nD+'XP4 lQ-cyIAOAɬ;]۷T)))т~YYYì_펋i/T[[ =\իWjt0Յ?$a˨ Ԅ۷o+ 8^C%%%֭aUQ%pZqqw{0!-[q}6{tt#// oݺ_U*l۾};۩뛛Xzl p8KINNF氹~X ԥ_@rW߆F?믿mnG!`50Оz_ tvv>Mhhqpk hϟߺuKXz'$oC,Q---h rTb݅ Ӫv]c\"u8[+orss{{{\vؖzԩ|+>x_=#s+ 7~ɞ={Q|>x$_(>ӧyݻwК5k._ o4 V I"lܸܹsІKRl_T*!FVL?g8-]]]kXz6` +\J(=źp#fW#DoooG~"uޅW"z׋h w}$QfGq?X6g>o||r,Ks##<#G?mBKp8\/q|zw b-ۆ'?mb@۶mc_qA|~_g;ٸ ~'N`Wݿ  _җ/Kֻ[\W |2:/, 3  Bx Mv\f9--ˬO{ddXvv$߯Gz}fffuuuFF?|HTնܻw۫W PSSSXXȞ>l5֭[ 0`nCCCxxxXXXSSSAAAggD"ILLDmܸѻ6]tIccϞ=l?_n]mmmzz:4='' 07npy555Յ ӣT*`Fz璁$e˖"`[[/..6Lbc`wm b3mm"mh>קRФQC6wfuv[N?G-xUUbA#xi?~\uMYz56/+WiUP0| lج,kЈJx]ԇ;w2?.۷o J`WPWv@vݸq0rmxE^?OSN1eVn2&(<o="'ȬDTTVBtܹ P@p ņ PzOßT xhՎ;jC!!l75APG_=q<BWaaa?Ǿ}`**%^QWBl䷷ñ|Bka'r G}7s߯/Jq׸e=g|EFrSRRnbmm-D>!հ) ^p~p _a'bqM'N,zu|k}Ypuh9=?Yz?_~le3օA/,}e/^ ~pCubg"| |/~l2l޼ 6 3а 8A m`& # Є4  BYw 7nܰZMޭu*322_n޼Tx,ٳgxyyCؘ_’ӧO+͛7/:`s·Rl˗/۷Ioذ]_R) YuoooNJſ뛘@><6Sz]]$э6İ Ofփ!K%\Ş "%R__~z6K+|`` ??GFFfggc$d,l޸q# uvv(6qk'=% B)7l7$2]7G}4d ЛK.`8Ңp>;ރ ݻwCGq v]_CAJ;qL&{҂kJ9aX63˿ ^X~=jll wh4  t *¶n  |ѣG^t:4>==>]Cw+++ RRRA{p/}KX؀-ÕA((p?ӽ{<|ř۶mCriiie؀\CqLv;NC8}Bd!rX9DA,'ljk'jD,xqB T krHcSNjCnPR($CPk BoJ`9 @ L;dDH׮]+..~뭷X.\f;w48";.Nb{ժU񄬀޽{8{AfV07ؚ{Xhg+[UU "i9si!G-a?A W\LSAIf}`: |>w_$k=qA>灞_5?S@)bc$8B&.p+l:KN0*<4'CUTTS|^0$%Ϩ ^E_W{_@@A ϝ7Y k0 XADh2&7_`XfͩSSnNOLL6_֭[}j͛7<_=#))ݻ} zfݺuxCCUj­[P :oΦmllX,EEE}޽{_>0wAeϑ l@I[GGGa%>Y/ʦçիWR){]_СCͰ*//0 6ݾ}&&&Á룒L&lo755iZ˖ V sշh4o8055ꊊbA|jҺpBYY5ܹsfuq? ={?Ǎ1hƶmۘƿpPXG?ַGw b  چz|s>!uK/6_?_UU_xX:,jiia#?a΄#|H5%4 V PYUFh TXX|VccczhX[Ojh(pD %.]BW|r ~˖-Ӱ$##8D^dE0U XȜ8}3p=H h'vw}[d2wşo r%|2ס8sLSSS\\\eeeRR޽{7"`S  8;== }T*l?Z7nJOJKK;::jccctxYY_h' :;y;H9oXz6nyyhdkkkaRwwSUXjZ[[qMD!i2NA8Pr!~CS=t2n 9B\XX?WTڡpd24ʍ+4!5|hhH`-A7o 7X"bxp#FZv#!#Ba?Wn||<[$&&[~ADs?_t=y_ ~nr_:6Zu6|k?9*AͲsG , pO[$t%C@Ax]f6M&SfffOOTll,h4]ӍFcee%v=1Դ99~MHŋ=ܣu}X| zO>}qJ >wf[,~b4c___nn.[q```͚5j_͛:z(իȱškײ>2ۏɿYcpe˙3g gHWW`_4'!Q\p3Qܰ_Ν;oܸP٬%֭[EEE---H؋ bYq}*VVV{Ð:\رcz~ -~ Q(~glD żv;."HOoƾ}،l(6o>22kHCיj"Q#4`].]p;p 6la޽0V^?*WZu8 R˗/\F 0I .k< 7N< ?َO#s6 O/˷~[ӱ8]__qr`-o 3gD Aq!7&h4)))ׯyx _A 8=#FgX;v#Ά"t|U*nz$!lUU҅ٳ ?]k₰::{n7`2x*\ \õ?~AAVAdUA cԘLLiOәδI3mL۴ɴI6&&.qň(((l"r {!?=_f.}sys{y<*Hv́I}!r;v T @x(6R* XL4HH=K2l 01jwss> LNNT*btØ 7///4@F:Bh"ȁ1 H111D$ȑ#- ~l5Ѕ~gCuu-ڼoݺraŊr`^ٶmj1r8L|ӟr]iWaAmY§&BYcx\g*3 /iàrU|||hB"@ҘhIxh{J рX3 *EvIIID0P30x^?44trew3.;/5+-AaBH;vppprPxq7o^UUU{{oWWxȻXY%,1Wu_]}YO Tcj|ܹuuu ۾}wތ ahueV3.]lkkMKO\xڵk$rW:::\_Hxܹ 6h ***<==Ip[ ͛7S:tM%3.#@; >^lmm0 ֭[{ncZď}Ϟ=3gΌ0kjjOl裏>Zlٳg6'۶mw _=<<… 4Lq999MMMp-RK?C,!C2GG~T\t~;R'YfS(7&&T:nqTTԕ+W.] 擺BĦA*}}};C~?3d8s B`t bBo(!ir\\ -X)WPPPP0y<GB07e˖ӧO,2>d C0Wkڵի$eEЫWg~ Fʚ1D\]]_[H ?GG^YY @{N]!R&l3 ϟ??gX+WRSpjG4+++I/R577/^Xd) 3X<==+V'CMդ),,QSkϟoNl^^^O<cZL^x^d>/ji֭[7ow1nC8 /p`5\ koq4ǻ$gqAS5M{ )0"""-XA*((((< x]o|wx4WA1&SPPPPx1m?883<.?F<^'£Q=3!_rgs֡!(W rطoSKMMx+uS`)ݼy3M1)4wt9m]_% _SS¬_Hݘ>ȖrV(L{^R:HRGnn3G@g#Jr"IcǎC~%0:deeEGGs8q">>Ke_ -ZR(T8RBT>>>p70@ _},H;::>cǎ{[W S|JKK_xⶶ6ի2o<,m5AAA۹s?O{K.1:͚5 6m UUUGZAE|r~Æ aOȠ-"""?22͛فe˖;sW|H܌~h!NdCZEu@ŻvrwwYf ЂT?P(5 .M1)`{ 2 bf-_iŋ9cva0TOϡ?3X6 ^^^(=%%nC/JHHP?Cff4NNE@sbsG dSxr|XX8L/9ri:S(< d |^{59޾}{hhq$],Q [aV0%O/>X0̱(#0gff l54^ fi|eg0%런t@ECmc FaB$J 'I3ҖA$DP"!ԋL^bPܽc !QT'Ag@`60(Eih,F& P8IJ$%%$mb|jF(j޽)U&=47 d{Z{h\E7r:XށǃE[#]WWGo ^zz:EC(ZCh/mKG`oKv ݾV]1g]⥏w-î׋ɦ;Rwf^o,$x? Di 瞻7M-L i&)Dׂ7*\`5`admrR;0/&dΨLEAA!ƴ5ƒ@+(((((<3gt@+|} **J744>}$!Q%~___ڵkܹsEEE]]]555aaajvxxСC"??_{aTYYYRR_ܹɓ4'g͚%/2̎B2;;;sss9Fy9s&22m:nog107o$gn#Gh'h2TA?ꫯVZ$---D_߲ePPPc4\]]_|Ekq?qp3RRR?n@&`0`/..^hQyy4r<䑙I[`TTqeG+`;vlp-4O'Hbbb `89? 9X_(>pBuBٳg'11q׮]{t^(##966!ud'//Z(ݻ)}̙zBV`r OOOhk׮њ=: ?rՇ3h2e~ƀnWO22R423ULU[[ rww6?)ت;nxw!FINNqE)A̘1ȐܹsvDm3瞃[[[_p|$@-Ȁ6?+((LF9ΎJ Q\{*?nnnnS0t,= x;9-[f|F6/мʥ=Efh@s㗗rR[f _j"-ڂQRB NZby׍7i"CAAᑂSPPPPPx88^AAAAA(wvupPUU{%$$ ůEZǻkݖr//,YrI77ڵk/_. S]__9ZbmذA300l$ r劷=ɢ\zsMM }RW.]GEBOOO{1UWW#/(**B/a(f)..wttVwf߿8{xx*v"իWѣ$ꔂ#QwuueH}饗ϟ {)V1ѣ2 1|#87Cp…5k|w4 aw'&&:99Ç]V6_?zzz0JJJH 1? Drxҥ4g,$k1d ~ӦM J}Tuy\b[: $G&r d@W3>50FB~۶mcx^+ OmaED;]9V}d!`2ͅ^%hZkAG NAAAAAxޞc/..޲e;#Oį>66_߰.\ёfRL@]}qWWWTV()) \=*{NΜ9Et[ۑ޲k׮3fܸq󽽽(0##~GYδx۷O\rss9YZZWz,z#J?͛7mllӏ;⒜_O^y啬m۶Yȯٳ'((Ay-_|źu(://ۙzԿRPPvruWxrP>SB PVB`tpp`h)&T D(VR W\YjՑ#G"##}||,u<į~ҥ3gμv}}}}vvv\ٹsgvvv||޽{pɒ%PZYYYbb%- z%Ġr4,ĩ !!o…ԗ~%Qj:ioo?qr[ίt΍7VWWzRafΙ3gͲ|ӳOB(((1aaLxSN2qOh4p<)gQd ȠSGˌ͍2O=8{ 6hdZ%æp*̚ H8::y%P(I阘4PLLf$cmm]TTm۶_ӳ~_+ >DmΩ;::r\\\^^KffT rJiiippihh8tг>;2999^^^/:#ofǎtb}ů1jkk@KKBN:M~|Z(Ν@5HMM'}SSسgSO=URRݽyf ZbjwppWiLy7}{_ӟ~[B CJWW'o344</޼r|C}'PY&((cԸxbzzzkk+CoW_B 0kee%C$?2`,񫷷7sOOJJ5kLsNXև03#""8$$$l؀%K敄raPرctȾ>N?~RH4{x͛oQNʔIq\l2d۲e j[ SF@"sJK)(((7 ;\ C˒|j~ȧ|Mfop|yy?ӌ\rssc`uuu40)ܰaYXYYҥK1-t\#k%&caff󑑑O>!`c!}D!].AqCNϧ`2|EZnk9 F_l ILLŋ-::Z6:AH %q!͐*70)(]g#7īά0 /1ԷhgG9AeNuj]K)_49O=?|ƍS,%@ 茚&%%EgO4_n3R%p*XbhN4ځX$ジˋp {B>,##C7GAAKg3?s0m`/{~3 'KKJ|}}>|o>}ں/bee5k֬f̍a??;wWc={ȑ#O=F۩ƍ;6c y":Ÿ|rEEE``… u S)CMM͙3g--- @̯ lmm#444Լ_D]4o?:: ###ݻ|rdfACSSӾ}~ ͛7ei￟0G}P|||H# fGuu_B뽼J^^ஹpႣ#sB뭷޲ qqK,k@aԩSX7ok@@?5kHM6ٳ[GEEsSs---*,))quu]R 0Ċ+?#~l _lX0 n6--~RTTrJ,B_7COX- ɡ+3 WOWڐpAAAāhB.CM__֭[=p߸qN{0,8#997%dPPP0 4gj78`C(|M UE˜ GaxBwycňXigg\zu VMMMȀq92-~6lh2ڸr Y6f_=̾gfA]]$ ^mȀXNw;cZA:R,0GDDPH||<b r=Gqׯ_OII  kaЏWPѢugF0#ks=S󫷶h1oa`m)kiZ|ڵu4߼[ ⵮_n@7uxK&pvI77/0w%"|bI֗얐A&ڵk-2d94`c64r/O}QPPw456?e,+((((((L=.\P_nZg>66SsFAAAAAфQ4 = ho3|tkǢpZ[oeM[y \%GH.z^%Tۮ ⒅ط[GC[%3|%ݫ6Q&FQPPx@XYUF긑?I;6ۯƬK4.HKEhu?ǎknOؔFh1_Mk4```1mϰ1V2/6f/&(cNr}[q{e{u&MCzろ{%36~`䎺9d$G&)MIʛI{^50fY. gNc8 b<ķدtw+㔺ۿ[Y.V:ݭѺۊ|jppPg&\|~߂qF???EOͽ<`u} b<ķWGG3ni,nlmmknN?V]\\&7SA9`L vruu0(oo3䫁nX]"@@OO#Zk] SβCu㣘l"Y]"˝ꢠp߸EQr9soyffv$$*gPE3H4P6v?)(4~lwwޘ770KMMJ ْ^^RZjcJ|,O_OCV#H6===ccMr>s欋seUeFF3{24S`Bdpwwӄ4R]oX6S,#lhh8>sOpPHUQǧsθ,\r+(((((9YrUUu„Ąk̙_P:o˓M7nCc#|GFFB%2p^xc,X`xmmcmRo|Y7霪*>--$Og~X\\\wFhH˗\]ݺ}{z{zgfee;`Ɔ.~_=sQuKKֶmmA!3ܼ,X ZSS;fPό:2"JXX(kgoMOif.ú'f:nmcp͐`,//prrrtcxzz ٓkljP߀nnnLGϻ0ZZ:>88@bcbO'Sv{{kj;͘`=0' :**' 5988ZMAAAAAa3jy𥍍MDļY\㓗pa|\%=ݸQ4 ihh$duD6tw͕pd˧Zd[[[;?..ő@]]W^oh?>9@! MM䙘%QQ^zy|aa!'|< .ΏElOO/lL)344n}üO\d1KX:͍;'Tml?,099:La;7[ECMddؼeL2%e˒`5팤IIIr"{H|#r5iUDHCr߉m|tsE)M?_h|QѺ(9^x$}Ԙ`!hdCA+AAAAAA2{9svNo}!;njgkkgmmԤ3Ϝ9~GӼ+C  '+(((((^ IDATq IDAT+/ IDAT ~ IDATp IDAT     ,>9/*,)"     |M IDAT  *,)@9-VK*>;2575    njc           464      L6 IDAT ~                                     ~̜ IDAT (%#     (%$                   U IDAT                    ? IDAT                 IDAT ~               5 IDAT                    IDAT        S! IDAT       Fb IDAT  ~    IDAT             J IDAT          IDAT      ^<% IDAT   ~        -"m IDAT         Wo IDAT        ^ IDAT    R?L IDAT ~             %l" IDAT         ˖ IDAT                     %  21.   !#"      ""v IDAT$"   %          "                  !!   ''   %$#  tH IDAT         .$  -"    + , ..     !"        (( !$   9 ~                           /1    !%&%$              /-     '&# -  +    &        .-     Q& IDAT *%     )$#&  $/'                                                            !!!    5<  !                 ڂ IDAT                       ;>  $)    #                                     $ $                                   " $        [ IDAT                                                                            !))*              #(         %6,$94- 7 IDAT                        ޿3)=70)&# ~                    4+40+                       60*   ȯ- IDAT+              ND91/+ !                    GPKC               A>8 IDAT              00*           <<7           FD>UN$ IDAT                 ""         TK3     80( ) : IDAT   ~            IDAT        &%#          |N IDAT          oV IDAT           IDAT     ~  <}5h IDAT       R IDAT              c IDAT                IDAT     ~        sW IDAT    Qc IDAT!? IDATA(B IDAT ~                            QR IDAT                                                                                                                                                 !                            IDAT                                         "                                                              &       !%   %   *     %  '("  CR IDAT               $      $       $      $0)          #         %! (%     &!         '%            (  ,  d IDAT     $"      <>+(   /%#  $ 11'%  &$      ~  #((      %  -&)    #&//%    -# $20'$     8*( 0,*$         *$    1( & ,'+#  # .+     3* 9*~ IDAT     )*       '     !    $#   '         )+'    #! - .  ##2*    #-560# &.  '"     (0,       =2     0(  ! !    IDAT  .%   5! %  ,(%     "  0#   93   :2'    !    $4"   &.$   '&  %(  )     # ,)     (   &) )   *!f /u IDAT  *)%    7$1  -,      #,'!*$     .44+JD '  !  .  ('    ,&      '*$  $   *  %' $!      "  i IDAT.(!'   (      # %( /$  %'<    6$   ~ '+  )!   )(E3    2.  A  $)  0               C, IDAT                                              #      d IDAT                                                        IDAT                   #                                                                       q- IDAT                              #          *      '      )           ~                                          &                                  + IDAT                                                                                   { IDAT                                                                                         {H IDAT                                         *(    " '$   $         ɏ IDAT       $    $        #   0!  !  !   ~      %$      $              " Ii IDAT    /) $!  $*1      $#!  &42    ($!  ,'   -   '$   94  *1+(   !-&'!           | IDAT %6?#!  ! 0+(# $  ,+$! 4/   !     #    '%0/ 4*:1    73#"   3/$  !       65&$&)" &%$31  &"1,  #!      K IDAT  (&/- %% 0*!    4/$  *$.* "  (    !+  #(% ;B76  # &B> :4 '#8363   - !:8,'  ( !4    "    -"*750,   % 2+ =4//+(    >9'"    "    +.  ηz IDAT&+65   # /'6.  0/.+ # -(2+ "  )      $%41%"   0' 3+$  313.    !3.4.   #    ~  / !! %7787'##  <=;1   1-:6  ! $#A;/(   (  3%1%    b='%$$# 5                %@;8 *&"G:0            LC<=} IDATKC=               7-$E?; M@8             ?/&F>7 ~=73             7- E<2/,(pE{ IDAT A:4뭼                  ]QF(&%<70                 4*[PD&$" 51,            w{f IDAT7)$@91+)( B>9                   8.'C<7)(&?;7                   D<5JFC!\TJ3/(             ٍ IDAT " :=582/"! (#                    ("!-' %#  .+ (#                    ,&!20* .,).,)             4Q IDAT *&/+&#!2/*                 */* 5-' /(  5)   &"  ,## *  8/%   ~   2-% & @=5  4/%! @80  @;1  7.#"   *'&A<2pQ IDAT          &#                    %                      &sl IDAT           (                                  J+S IDAT                             #                     '!         m IDAT $                         $ $  ~             00 IDAT                                                  /N IDAT                                !           d IDAT@92      "              $'2"%/"'.                     #%+%            IDAT               ,'"                    ~               / IDAT        >6/!                                        %%& %         :"+ IDAT                                                        #&$         ~p IDAT              3!D;0 '                      !(B-8."     #             1 9+)#   !     0+ IDAT  ("       A6-            #   /#<3*     !   (     $     :2  &$     )#       '#,(  84.]VK?<6 "        #        '#   ~ >5,    +'!   "! ?7-95/    IDAT #   '#              +(#  !  $(   #'3&*4#-!      &$"     -5?     #aҤ! IDAT     '! %                     &  1-*@5+  !           "     /$ ""  !        )$ 0+(0,)#!Lx IDAT     !   .+% $$$WQK -+/    $&    /*&ULD('$ LD?!        !    465  A=7     ($     ('$&#   J@8752     &! $ 4/  CCC)(*=          ֚& IDAT$70*952   *)&     $-(!    +)$  ""         "    ' )'$        +(#   #! LGA &      1* 20,+IA?  !WQG(%"    )'$   *'$/,*   *&!  +#   # K+)&   433VVU ~63.   #    $ IDAT.!=/#0+$   2,*         E@;   $! ?5))&"   -("    %"    **+63.     & F:+.)$!  "!,#    840  &$!  "  #!!    75699:,,,;83     + G=273//,%    '$  6.       "        <<>OOP0/1!!!B?:    : bW IDAT    F>,>7/" %8!& .!                /- !  -,, 799\^a+))/,(  &0 "E:@*%)%)    <4&5.)%    F:6!*% (&$     :4-><8  $"$!-("*)%&% ++*)()###   +,-LKK'%% 2/*       ! 81$=7/      C:0"! $    3+52+ '$"   '     )($ (%!    -.-(((    !!!%$$,++654HFD><< ...30,   2; IDAT    (>8+:72!   5+2.*      9.'@:1    #  .    # !     577 NNO%$$CAABAB%$$777JJJ... /-)*!    ?3 EA67,&1&"JC;      ZI87/(  D6+)$ ( %" <->6, (#    >@B::;.-- ***+++&#!H@  0,#   ?2)<6.   ?6$=5,     H;/5.'')&    ,&#   ($## @7)0+"     146999(((4Q IDAT +)%  ) 7-#:4. 3*  )$6/%    8,>6.+%         %%!,   +"     #  111 &&& -+(   G<22-).*% H?1#!      =1$A:0=83 4)          &'&" ?=6          &&&qrn  )(%`W  .%aTJ %  !;1$85/   QF::4+&%#           -(#  CB5IF>**&##!*)% (                        ~ X7 IDAT0/1  <-'D9/+'!    4(?:20' C1/6/'83.!&  +%     ($" &**& (&"m\L                         ))'""" B@C>=>555  &=1"92)#   1%80' %!   4(B91@:4          ,)%                          #" ! --.KKK665*)(#;5)84.#%  <2'(%" 7'"A;0 G@9       " 1.+       ).,                  IIN''( IDAT--/][YCBD LIB*)&7۴   YMI(%" '!MI;:6.MH   *"  #    '5,30+W$!    &'( %**           ;:=+*+""!  .,*IFDDBC )'!##    ;.)&#! ! <;,51) 1,'XM    /%      EG472),(&X      ;68               )((566 ---CBC@@@   2,& -"=70    1&"?;5=81      3(#;6. -*'                   zҷ IDAT" )((%&%==<<<</01($"  &&93*%# 2*!B;2%$!FA8        %:/$>:2  0-)    ../###           #%%@@?,-,*" B9.51, DH5B:1 E@9  $    2/K@5.+'^UL     231       6:< %   SF5$ G>->6. +'$gXJ +6#     96(B7-2.*                      # IDAT    "/$2,&   /,G=362-       "2'<5-+)'               !!E=1 "@;3'%!B>6     ;3%93- ,+)!                  ,& &2-')'#1,&!#" ?<5  "    ^QC%# WPG       !  ~ IDAT .      >6- "!$#cZI " - ND81.*        .-*  0/*    5(70%$" '&#        324        :73  $?1 :4+ .,+          ?{D IDAT 767 #+&     "           73/  _O>+'" #""#""   $ $ ")'    )2"          + 4"B7*0,&                  ! '   #!  >0!7,#%#      C IDAT                           0,G=2   #       #)       1          50%TMF00 !           "               9.".,)  04$+ IDAT     .    =+ $          $              \̀ IDAT ~     (                     $    IDAT              ) +             $ &    %!#   +$(% +"  60 $#F IDAT  1%1)   3'2. ,#"  3%  6(        $L<-&  .#     ,"   $  %       ##XW8"-*ľ    Lչ~ IDAT            #    !  .$)6  !E>9 "$      "#  $ '($#  ,#                 %  1'% !   >++$   .''"         ";,   -$,  60  "   +$ 7+& :+ '%!   +'    %.,! #          %.4"  *$KE+!%!##2, (%(JC    (% (PF2 !! )  '(%B<.=, ,&! ';.KB# /+  1')!0&% 7+ 4/(8-/&  7-$ -&$5, #!-&    [S IDAT         ~  ;4*,(3/ 3+)&%$76)  *&"?6%F8!   ' SME+# !  .)' 5.'=4(&$ #!     -!3 " PI?A:*(!  2-%2-#70?:',* ?8   º #WC M%(D@7#&34            ! !%  % #   +' +",  &     !"-.  '##      !                   # *" (    -%      )  &*  4/!   #    "  *"# '  43&          IDAT      +$  % ' >2*1*4& /&    ;1%(!   '?4&      $ '  *' 9.$%$                  %+  % <85:3@>7>8!    2.)<5" 50*:8+  C2  ("#9, &  `Y0%SE         &  + $    .. "   &        $  !0/ B*#/"        ) #     k IDAT $ 81   1- /&!'" -)% +*.',) )%++  * "  ,(1($$    2%   ! %!30"    ,$(& $ ! "$!  $'#" 15 "   +"    -0)  ' N@++% :5   #)$ '!/$ &"8!0'           *)$$) 83)+'8381,+#219; 00*!!+(    63'A@(F,,     31><    62%,36" < ..*+         ]7 IDAT      %    &("   "   #!                                                                 ,> IDAT ~                        IDAT                           " IDATd9 IDAT# IDAT ~ZW IDAT6 IDAThq IDAT_3#v IDAT ~iO? IDAT] IDATٲC IDAT#L IDAT ~ IDATo IDAT> IDAT?W IDAT`6 IDATg IDAT*,8IDATvnCDoIENDB`sardana-1.2.0/doc/source/_static/snapshot10.png0000644000234100017500000061606512174204305022745 0ustar cpascualcpascual00000000000000PNG  IHDReq pHYs  IDATx`Ƿ\J((؟a}b{==;vEEA R,^{rio6WKr߇{ͬeY "Qgw D4n~8]g~`奪rЮM[?o:2LGq{% H~Jc`ڙ/_,CSh@d[¢EG5J#u۵C!H24U䭷ߙ3-t\_(dD2,0l[st^$[Yu̙Ib}RbnT)QW6jgwONW _~q ԧ>wkN8h& _};| Al( 7"`mi>ϭ^;ۚ7.9;h䜹rJq yÀ#Zsl CH틵h)ʌ؞coXGXZ%%=Fκf/2KڳfG3+!k<{}3GL546݉6u-Yn=a$q@͚i HHO4$k%D֣Ĵ˯ʚ~3Im=5yt4!J+]:S3 q>Bg۰}6WRsqO517,?^O{§inoOIQ (_ES2ŸznF` `E_xvɾwxu7W@>ئ8 VTmaZg.5d ܤ*)ll3O{DlYe[Ͷ2L&t큸‰M1|_Go@??P ŧg 1 ȳ є9˒8Ie?nyKi=0{Wky19TƜy#S$D*xmbb VnR> 3n3fvYk^4@Q yi:IVP 2p4E3`]‹nu,\wdϯ_}%2_2uxJ[Lv)&ʣe C9㢬zKj"U Z C2L)e"A=Pm[3vk-"'+~ւ Z0=yjWpɢj\9GOW-WJpnwБ3{ࡕ%F+Sƨ}8q>ﶏHQtԗֹa ǽlKsyס+XK7.R`nR:}N &hqC. = 'bMH.E9q()e"Go=)`Gq_7)+5%l(X x~o=z~fe+o|g]f o-# 1왂M{Ώ͞)ӎTEŘ@+!UߖtY#=|X [kicf ~kHvScGn[*w0㊬}ߜB2Lj`tc%}[k ÷+]^57 ֭4z+GvyuN D4 X+р`"kBʕ.7Dn="22.@!>!% U2S|M.QwkQ-5AqW`;SLh۾pa2eڂ~u@/kq+ `uMBwmW۾{wk[DA Voq?](Ds@t:?$ D4 X+р`"O*J:%kasgϊц_ H`0̛ۗg3m(r2Qo2ڿKz|?x.[ZjJ*h4Vӣ?zaHDvLw H>YX ?1Io|R5[̿j {JjԨrE-@+v}B3}^:%e$b$kgkm?:ܻ4.٪\_ޯWB) 6h/}}}JOBAx`hl~;L.| Vt3-N_9epRblJШr1N\0A_m8, -O|; @yE~eQ \\'CS Kל>SÇ tܟ,q2v 5h;+I90etqZJN,b܅q@VLꂑwٸ&Wup@$1)TŌ[$:Gù> |K:WVnȫvGr|N5Жi0ZʪJeR'uVR\Q0H{QGXAgi_4@$[:SVh{ovbfVlVo4+X+nXqɮkcvȡӥUlZdn+j8,Rr KQ>^p7y;VnT98]Ieg1\TF| _閕>ah(HĢ,ʆm9(.*3kB.t)C39|x,Ezj^Z .hq[tFV0>t[d"߂u!#FIb+6Zzwevi ~8|h|W^|LH|.AI/BqhʇC*^wO<4Ҭ2'Yɱ|;=s$| VJ:TD^XiU*"J3,à  -a׌iהCqLS˕Y <4{о귛LH{uWIWB؎ϒ(:#w-Mdq)qyŕ|T>힉-U.:Ƿ`Ej-R1in48drE38IcwPϕW zrԈ G֬`e3Zъ%X=]??ʧ] bL|a;HS K_⸧CҾ3AoJX>WR.=RNw4-5%2 z Ln]'nZgbD n.Al(8J̕ .:#t^]I_KPy>3T6-Xi9ZuTi}ੲ2ltfS$eeɊ$=IsUGAtC$&EX۴Iwy®@"`2/澈AR^xg|"5)֣2m: 5gϡg4=S8wfdn}KkL)Cefj NȃTQ1%[ϼfP]30?Sܫ еK㝿'fy}#q@ Q%WgIM)Xy SZa@?IQ]W>-Dkbָ9)jh4i$Z/u~Lc52e]&NMkƧdY (\Ą gtx'ZgG |1mbh޻W3/':^3oO?W=+aH&3mc\|N5(Inn+rҭL.>CK{v!X$Frk@䋮߯1[PSh&(5}3b?ygfZFVTJJ,`S }?=~Cm! " 5**:=-tl㺭 '8ͦZzǾΌ"qiZZ:\䀈B$pQ#rS᤟IWmIW@$W`ZzVF3\Ѽ VS6 3E98;!+U{v ¦?.-ݙ=aHvv_ڋX(z͖keh6A,GA|mp)T*ceLVt833`n>@PZVYTX؈RD+XN] gϞ}wfk[o-;;S v,à-NNo*^Ey8ʚFQ=@ DK_HO{XnYYÆA?/׿_蔆<Ϳp>cٹ0ur[|IEISNtTԙ܉ 2|Z> iu&):\ZVUU\R%% X@&cT&I`5!DMswV#@8*N,Έ՚S CSs(wϞ,fk զ\i>R>xL+J̶Xm%yGAQUr{tMf(h̽wg'J5&&6>%5'x#S` y_$G HZEV8.va jupHiX֩Vq<^z}ԡKa~ĥ{̏2G|>ɮl>@cQ$w(RJ;tMXchO}ޣVzp_z˹lKM) !ojow_}XW 4[m@|*@Rym:-w4M>Wxy=)/O=n Wh4x@^"7Z-j$Vћ[%X RXTwo. PnZx|qrR 7Cs /ЬFۚj)s)eoQ}@M|kӬ $`-Z|{Γ]*@~㐰qT!Z bDW^?}7^% HeR\fעMl6RgN37:q_-_#/[?Kݪ$ԔCTtT*{Â^~ݓ͔|( ø}-lr466#iҕ;Y/5}{_9m_>÷''+_PXE!IjS3"WhWP&>>g*K97lԨs{En>|@;Е`{,Es{ 90YW/n+L*(i];Ьŗ={6{&'^p5S&v/il4wxÇHDbX1w 'ҿO"Q[v}[N{U*eFVɣG^{?n>sb U.RN,YÆ EHQWWWѮZF=w\QQ Mo7rN)ϝzWC׬߳eEjvΈ8zDqii$,>Ag1^ofh( ưt5y+<$xFf?pALA.$8xYޕ1cRQvژ M9ߢ;ZNmǫӧ{JrBEuAd)͚Կȩbgff+8--an+S;/=H ) 2!$UTN9wVu/wGLL҉J}{n)j$ 7tLYsj4*B&"qJ)Jb$VҪ_צfb8:?1R" 70 Y6(g cz"H"( L@ >`+V|w굊zKDi^I4;O@sHN+_70E < \H$<%\qZV& l:Ptr}uZ`H72$A$ ձCxx#;'K!JYXYnYJpCOu2'5 í}~ϫfM6;0l+()*3 KM2V\>y ?wGva>Hw=JB2.p_>njaBH=9u&-t5:|Nj.3ؔ3HERP]Ҭ(SY lH*&i"E`)UN 9qtO\,#Db$Xv:,DZ  $̂՛e_?XY(]U"pU79KK+f;-@4Q$bRf sb-WPF́ 1c3ӻv1H܀ = K|h8a3oz'n=~_|ySf:y]\2˯5/Oe-VGHbf7kفKIBUb򋪍F XneMcJR\Vvqذ7K]wgMj9S-ς {'jSΐS^z¥K?C7r`rؑ=`KeXЉVƗX#ObR"b1\k~59UtPSn]tQ-HmrV#zݰ8j7=guyiٮ'p_88w`jR\} ,E?SJS^5$[5@yYyUUBOHHK=w#'JW%j/l˗_uvL[g)|SZ}g'D-H>tXVLR.lXĬa>r4Yy睆R(i)CޟJ1IŲ(1Aqےeqֈ[؇MMIB׽~5-%vӆVa4\t,,>/*|{r8Ь@9txqq- 1 c9UYN&iKj:Ё5 _|5p@򪣇mݼyOw@K:2U/-/=#fʒ`Pom0bbc'MFT*Z*5m CݶmOZ(sGd~XZpjʘD*qݱPSn]Taҕ^}taqū+9iPj)6Z ߯\f&d<5\.zvڟ-3.F`L؁cE jԲh{fJ98/ Mv|7GuFڲDcMf[~>p}w™{ѹBwe.s.TmˎA1V)Uȝt*xC댶̌WoMl~YδuYM661ՍF 3A}p@[(zW̼[dptda[ }5$&ٵ+8񲅷^+ eY^raY)QP!M|#z]fs4eѢYiݲj#X-nIb1ц5-2n-$5v]?L e+ʫv>hXtV`Uj:V8>lPFEe8k0x챗?lC=+ ՙt(! ӺPUgf';naQx܅wu4+gZW\e%"6=|i8s.*֋ryTTTfFzh4ڬUL꣏t2ݷ*P@"NN7w7>p5X둔ZmƼj4qQ^;uU $򊊊JK+ˋK+*j"^;uhm#9K`xߞɻ%ktW_}; I$OsסQ#8N+o&D}rm0VUUWVypM\'>e+%G kël`jE "&:jvʹ+(D&JR}|C{غj<`d56ǩXZ);{]aˎr8=9^& yD<6Kywނ}|HP]?;GVSPjC7`ߗ~VJOJJ8ollT^+qGiAwwNM>{ʤ'G:ugUvvƌqeuR(.VSYP]c+7 o2ے2RhQ4S[[{\ަ-[&&D߬| Qmi!'(~U ڐX,d05H4qmk+||5JJq\n6m6fo_U%w+@{f:͉\j-/P.;@ktJJ+rsܶp.ƅMo 4}NjM(qD "RԨ!CisyE]|M&\3h)-2:opn]RD i+]~`o*,@)]&`Agӷ#1Ükɤa1;֮[vVCЎVoZ]45Ynzw{]|5rٳk In`GtX,ec.rkJQHҶ[‚lQ)(QSkijjzRH27T)$gfbFF*Ree9=3O.;Y$&]Ik%H:sNUW<mAk4{K4}V J֊/v۲e_J͋@{Б1&]X2Z!Rvt?ub` E:d,L kKSz} M>NW!GN ڛrm_Lظؘh}ln j\Q-hu ^=3m6ہGssbQSjCV-6yW1R|/VKN0Ǭ& ܷ݆@h/`ޛ<ΖƧvNa0Tꪚ.2޷\QX4gZ?!  >H $@X;vC** J J K9RcEOW^.Jvڼ(o?u!~kuS:Wᓛ6mۑ)ՁuufbHe'XҪvMblMw-Vv*pO.@d VA?vo{36MĨOV(o=DGĬzTZ#WDj"e_~ҫ**1~|xYϞ?Џk7} eI, ا6?iVFu] njODm[թRGڮ ŤB!s^aG i'L VR$Y6i$QVb*$IDP( L&8GYL8Q!HanQhh>\}3f3EťOblqQF5Rs0,ͭ26j۶O8BQv@A8*#IB,lvr׿ _l\ߘxTʤ[f+FJ쫧Z~(eEy`uLgvUD23rz/M堭6DS V#9E04=IJ3ԙ'L V:AUָ򟿯[' t>}u[ؾ+#)ip+TxbOюJ֣֗\$F8=\%jz.Л7ɤH{4ONY bTƽ3 @YՃ kyG,ÐC}\H$Ibb\^A`&X1|~-Z{>wLjI4Ordhn&k[wtIV(Jxt-XROcu VGW_iBxwIPc0Y<*3a uvd+*o\)vؖ alsl4D\FsvtrJFQƲka !ݳnݖWNl D1   wg0ɂ?b |n9p7}"+r&Kc6g\؛>c2|z1K_m鵚f*'>pRBQhY.W|Ͳ2q0H8}{VZT`E"c-.63WX3|ףN-@e+\=:=t5g"kbG D* zCsYWkaTL&E~`3NU55ZV \]wTD u|D2?#-bv,FfV[ojV@`CZqS貂dֿ-IHUBW;>櫞z8vv_N Ą"٬TJ6jL,]Y:t1zZ㔝)T{@rTTtXLיs?oЉ99Yͽ_ֻ̘>u(l2 Ɏ>l6'%%!=CQ;^&6"T."5YUV6|):NG<(|icF7v< )VZg7JSOK[;nQZ iП~ٲq־}ϙ3E,uh˖=;wv陭( 4kC}.JxuMG*&6;JE[fuǵ;yꎛE+.x٪9s78b,&\I8;c /<_VBm%Ⱥ|xp@ԛ>csmyZ%"N];z`mpyQ lwK>oSWT||UeUyM r}ԩ/VfXgvsջU.w:UJWN3F&$IQ6_FfW_{?1R/'L>mƹùizڰD~ Pł/S 2=ڛHoAEoƤx.buZ]E:ğr |rz9nݫ R!{Տ_zYOYYYxVF*2 M, ;wPO;E;WiӞ?w3k:o>$ףN%\7w2Ir(TӪ$7]?DG 5kV&Ao]jmʻB<ȢF5Tzk+3-zJLݱs |*!޸ Yi>Jw@[ R)^{}Ξ=i\F,,2I%eS"E!Dzwdvg u*/ԊSHbΜ{g5L8μx%K.."V-=. iu`ޛ|$+|m7 H c>"ƌujjU±u=ێ,BWN08P*xn$@f;Ӥ]Y$F:Hr"j*M5)rJU$PԄˈ{8򤃇"M XjϿ_ İ"QWWǧECT$>=6sV$7U{D͎`Ьm 8)INAIJskS ;K87I[mv$R]PՊb u:W \$q N0"Vz`|_Mع|;wvై+tU"8/"!xu52;o;Z.tS.*ٴwlkj뢴z5RVT%(=)BUn#v2D$ #{t$+X=jIWkN͊THJɢ2W\PPPFL,e"wBW~1|4OM]La(#4̸ H "H7y@iIQoGJsH[$M$A?!󰖔 S:7))따Av`@du7Ū BcV*\eATAqBW'7r|(& I EJ +/r6iW Vg0kTz@^NaiIRRBl&۲!A0(Xfm« V~?O4˸?*CWN=ӢX`'\5ovK%lE;N͛}DRGn.ʇB$Bk+@A{u*&ǰl~яs-KNZ $^.ڜDo9sfhht"BT'O9vpSrx+X& T#XRi{bR|Ʉm֦[¡yz>ڹx`B~6uw:oa.*<:E,Ƌ HOH`tT6cBD\\t:a7~- t:i^᧋VoB]˛۷_?z,.>vu>VAekZp<㦄ӿЁ_,_Kt0 X}a:^bbX#Glw6z̸Vߔ90GݷoݻAt0 X}Cɓj 5%znk`~\r`V+>}lƟAukGfŲm۟v@Ta/^E /Vߨժ1k%e sm} aE_{ʌBA8u7 ͜9~]&LH1gg.>@F$7(=Fԍ55Oݻ{FCCat:h^0,k. ^> V8- 1BԐ:ڙٟ~b]>,B%;"(Jmp~q A0 Z4 c< }U+1dRp{ϵ?o3WBIIw?_׬ 4ٽT@q/bxO'?/KgKLLD"ih4uVLF,J2ğ^y{"1ӣ0p;9=zoc2 b育.:)W6s׮osǡލMDs[^,WÆOB'oQQ8&@1fqޝnj8utUM zn߉bxy-@Ceeò;ގO쳇ޭtJAxAYtG2S⸒4ݡ= ﰳcڦewV:|;REaS8t41/m ʂu,`ޛU bo.[DcykȰfwI;7CZ`\n=WX㝉v˻g[^hJ^UYn%ΓL5'`ţ{|\}(p"K3L> ;}לЕ _}Wcϯ.~h_u}Οϋ5[7mx[_#/_u6Xp3e躂-gbΫ92[t{+r-++PޕpgС%VEx8>?h:}Rs/Y0V^`Η^Da Nb~^e##!ѕk/䣡Cr'f{GjHD76{~٩TWGHjXg~:*[yq/葙s:A[oiT=۲+dyL֗gw|8\xin9JG<g6|v᳘LRg}.H0a'39Vf< -ۻ<55w.]\QF544 [QYv{Ϝyzwz8**j9"N$"L&RTť $WmaiwNZR,uA!e+ϊKv?>k߹Ͻw]9jY3Gf0o1WQ-qY˻Ao1?o݀Ls 7>M3cqe3VXKi'̚9s,`hjF* 0\.GU*xD< tz<2K* 9G}pN㯊p쀿>d]9ij:W0}hKֽLB:A;t;`NcҖ٥;@FSb++f-ƞ>eNӏ+KJKhV*,UUUdrygv{B"aDc1'!cn8N)=xT7viWVTT80 EQeeeQQQ M.o - w7Zc D8"@h5 X1[lBT!*LF54scK4ڨ*ɓYYYf윁AAtx `"yҚ]ga9U`Gg^oՒ-Yr@ ! j {ʟǃH#;W'q/.[Nm||*e=7;N/ V]?m=gh;rxxx4ww~wNȋ5kV/ Sӑ#BI/IH$F%"X3"UHL Ĕ) 58IGEz]W߱s߬FT0  TW=6,-)!XӚ|yIn`U J G:z w]Ud $O9.TRV)qsrj03-` 5E8 W)s\yBkfg7ob_Bل6RLAJQrV1_OPQ#*<yT0 H՚&ha?o+r28@r`4X&~f lh#GrLګvrՅTiS3YSf8Z{?n?9VrBF$7HLp) -dDaR9J>UL>R`&ۥ-XLjrȌ{5<dN:R/ 53Wۉj6iU-ݦ_~'Bl >v^-o"8ZXK@F|w=ڝtFȄDH"H˘PI$W`[7񶡶]F#@"L)n,9zh~[J`B 69lD$Lp'${>#!rNx959.8J‘ؕN 5Q/„#3c&Dv5].g}&˫f/.>u]u5Pg3HHĪNYSHdp;Rd34GB؍ >z+^zFmcTd#n 8ЂMO('pLy+D٦;(]}f`dfғH?u$NKt|KXf't(jg2 IHݵN|b7Nl36T}J˖q}71{>x_a6iN'MAzӝa8}3[̡Y3*pYW,ZJ` 6cN ='<}G>'d?5yN0U%1.s% ( =q9ɲ/w9#Y! KLk߹m,%{>l>9:$OCM=uexIq-AB%-C?4&`A>Ml!Ly+C0:9/l>cT;s[;v'ڹCN3WWU}ʎI4cfENmёT іrД0B0ّ%cZ927xlXMrԟ{WiO 9`T#R%hdPP]}>5{ OgG|=˄l2AG{DDxC&8Vy2.DgvuT;Woerj!q8F<kLNKt|J&5Άw/?j=6A҉D"EY,J$I'Îo~Uפ2\FM|86VQ;){<RSjѝ;J)rd)hi"R I;j iJiLt)|='i{GW˨WN95'rw5tD=ޕ`}F ~1QDd2At~0,.YkP(( 5f~[TtYM){Sk9*.QIH p$I)_y?}$ΓSYb4o۲pIZ7 VF(b!+2vl6,dUUmnn޲iŗ]Q֬eK!7llԜzTgatN~R‰@EQ,͍X&<BkV42Mq\'EQFOVm$YDKaV::mG;Mnrp=OGX(R:} pJBAW㠳hUeyt+qùfɲl1cc2٬x 7?CΨݳ{ײ+Sl&K.h>2>*(92NDV[ɮNw w>rSޞLk{J+RJNI bko50 狻1;Took[1 c|TX,&"v$ p6m^ty[o-zG!E'cM}ZߜQU6zP”j8Yg!¸ټԛK Lhpfb:@V֘e.;䦧#^A 7U ֦9= Q Sj%@ Ӏ]b(Joo/ Ml?!(b S}@ ,` CX fT0Ҙ VIbP2e@ pJs Vf::;ԦRD3NLj0f@ tE]tPPd$IbL:N+aYLES{Nq@ QݑꀑI@ TU];w) bkEEBD:K2֊0M8t=m$-M賟ܬYN@|3չ }iޢ@kVxyoyT; ϝg^yemp`Z`XGLmn cY_broQ1PG 9&'vBc@ L>OO=Tp@kf:;PscZ?B@-^ Bs/xG#ݱ9Scpuuu@z)AE?_7|Bc@ L>SSp$wۿ "X3r@#++<rn.,kUVE|ȀɓpRf@QV ‘0˥{&4&H$G#sS t/~{tݿ"uP*Jr$+!HCNg8h(_rVs]]wK*RTYq Rķ߱Ax6;(Nw팙P>IJf'\I [MrV\`#"W'ή뮽VN*w*E?_ qؗP6!?c R,\*E3"y%g!UpHS''HrLܱy[FEAʋC4l%3/A@XʲFo"\O6nڐMKP]ܲIh9$+vuYfKLsΕgB*C]#1#W p8p×~ej~϶w8j1163[\@xZ,l"aX}g̔WT_o'AۤnTtZ!G}=ԧ?vΛ3<uJd3_˲&.W {{Ϙ_sڬ&·JG}r7jUe+@-=݀R\B%}ٍM) gm{`@(b9СQ(V1%ӯ*g+DZS>]X6X؍Gn7$+}MF CVʃLVEӭNHk_FƮ"}ƾ>_Қ'w;e+VOB кgm׮+ ),֮.Ͼ}+VOX˳0sqg^Gug6:l6)+2Zo/?xf\aK߾,QRC> fh\S8kau("߾r %2çҰP\,Zꊫ,*+Us#5#w*\haE%u, Q*[g3#|ch֓M;* U;X ?Zv3aD옰 }PT|q~d%ƻ;C*ű4#-KΨCͫpp˦}^o}Cîwތ[˞ИH/g|ϾmY+kKB4wECsn{:Aji_{ޜ{;(@`u}QSRfTBk-G_VŇbTօ@(֑9۳[v,wWM^;uͳAvQ{}0TrV7ւv!R'WWUh g9ד0o"˕nm魏`4]&=Y &;SRLJzȌSObQ4Ч"[Oi ieXš}ll3nT^/6+.yM"!4BULz2?wn'ҫ|DU9s`WŸ(W6!Բuګ7ze_=쓳lN猺#w2`HhL3.طK6+C}?,lE=Cl/-:~@ꭝ=<6f6Sc+fE7(~qCi@TRes*Xs2%@"!efݼ~j)ʠqʲ]sUY>71 *]pؤD"X,x+I X_uM)Ceԑ&!lLLfl*L((~%xVo_vWsVvӮ9ee*bl㉯kL;zVGޔv8؎fvy<«CXZ~ ׿͌ j><5&ҬVf9eeFY$ pWw͚owX?t#/^S('ۯ}0t \a޺J/+ǻ,UWfҙѺsozmmChHVa>芡i*>+E 7piɲG4&˕N?,ZRY*PP/x`fݿ[pasη^Yo~yH5HR^d`Yݽ?.J/xnf[8y@VusE  B<2[M@Ȯ]liEЪ&c* ~?Es\,/OPn@PlZ͇۶,\@$,Fpbh`y*vl6,dihnn޲iŗ]Q֬ A)RRQ7sֶJJmSP)p!H?"-zc\Z-E@()>_ua;Y8ud1Ynzg21i${m8>{X AeOhL$ ) v~Y,˚wx}]~߰ۊc_H k!I}v4a.(w:@vINII۰\5j I ׅFl0wBg!E#c,gN4V 8cz agԄ0g ozmm꣆O~E]/8 >*gww3k&dKhL$fh;+:4E3ᡮeK ZxǂU"D22Gsc^Mŏof֜(P;.\Vէ7t'!` C}Y024 F#X WGWӭS:c27Nf8=b#,v$6*&=o-'2~ C$r]?!(GZ)j~MF6EY5 xBMԄ__JFIVB2!X1X iU={8[t:%m> ;&-Z׺+*vxo}d;1vώB#BO8=nN9*&%W&TDGPoo+w._u@צV XL){ 1q d̆O-}N D'IB푝-g>g@ L>Hk4jU3q]*iS"]n>#JY2j[vV?yo%9pzlq}}xZr~>$g>_k?q&1D(>+Moo/ Ml?,b5 Ms(x긞#FdJTRzCٳ{P_i %G5!{~ _GG͛6yy?EBu$bAJy[f(,+,j*ddT$pH|>}^R xBAw HjVeᄑFގ@' /Ǿ}۶oihc5_Q ݍ55EWW߯bq:Am U\t45ɲ|QK`TRrE[ʪ_uw a)V@B)b1}.h/=o)lR>6W`=N 01UBa‚QS Օ95,*P([Xgn~ꙧjtYY6^N{AWLVy<9'9Y?.\kL,]l!X$/H(ju}'!c`07aF?˿~p^|%RC#llWPk[͆.bNhL> h5_0ۛ6JIK^ƷfrݞL}UA5oDbU)ik#,}_fmؑ%`%}X[49EQQo~B`4˰fnž*z }XG>F[F(>_IQqUj4i/< ϗ~qj—l|- EW]]ܗsB4=.K"bRlBAbԆs gp,i)uDYuͨIJZyUL8q Tj h@ -ư*&_D ,)"X ~juhHlSz4XjQYQ65 0dcBѲJ W% ty $d-z駯7Ġ[6{'4&H <(Jz]w-oZ^!Z.n>QEnb ]|zAN*+0c㳟܃>o{mb͞ +0,J>OKӽ߼;aCZB W9~ZKٲM RA4[-E=^jǫM ok>I%ՌqAsOT)@ .XQ tnQ;ᆴ sEF R*:<,*JJ):ELc߲H?ݝp,)79yȣ @ &]!4t*깱-{-isi  CiSE,Ҍ&R%Ů'C{[a')4w@ SY>m q hSGYdh # A ":x2p3j qVWߦ: @ }cr VS %vЇ~up%!ܤ(,l]f9jѻ^< `r 8vj$5fX&Ou˖waxxly_pE_bX:wV]U]SYUqiI"ш,I'qb;eYPpRs Vr,(|jxO,EAVtY-U|t_~Դ1,%hlCةtGw>'2[r!䦿K믽$t:;mo/|V>'ۺy(3?ruUhU MWνrmK'"X * oyCEi9WkW E``:tƁdIOazq?/y3`XnCE"EŰ}r` Πg6S2J֬j;T1O9fTI@0 Z=S}iD[k%dkZ~'*NZvo~֞seWcx( w矽7B!,($(ZLV,`}tXOTZ=@LJrKJMT\Cw_7cIBTi^ҥj2Xa9+1, L63B=ڬHUi. c|9婠J=A.Ȳ|g?M4U?i۶m7m_-5əlxoS?beVyjS*݇\&tn]قnkؿï& Z:"a Pdhՠ>߻ S]te1G{rXp4J ֆg ֳ``M;YJ,>dkaE&lJ L)`Ч楢(9`v%V\WsYs Uű3ϭ9GDTr3/sD"]D5el5"&TUV čPU Ih`@t`=C&*D})gYDw""ua[(í$'|}M_xe_O;*l[")  X(HŚ c +u֑JXXP"~G 6qLChdT3֬@#FH{1t#2EA% .UbqfMkU5)(ULi}x*M#4nL&m& g M¤Bn9{9w|v??kRgoiu,O%F+XoQ5"s6$i>STmG,8uC|净D"閥Ȁh ,8?]~' ʈjII +W@ey/mj hx5yüR{'ԪѶ*SB(D$w0)j&[U6όH;@IEQ,X(^(*4YTf [ o֒o]%@L`% ~tӍ`?SO=řo4+_7~X[Z0Sfۀ(Va ҥTQ\WisYXAF#"MD`Bpk`(nY "}nJ.O}/w߾$:2/B͏~?kο5->ų&I@_`鬙uBbxOYS2#!B@ E@bx٠TRJeLt(XX Q5BEH !! 0 5 ʄD+ِh 'T$`[a!@( + *++ϟ_W\qCe]ݕa2ӏ"; ՖF )ĸC~͇ou"Fz٧wHF"Z{ukf;5wq52nszk*2mڽm"a>O)o;oУ,;YVFP0~#aI-Bw9E,@c .ubjê$ 4HE )dcQ Ž6ـf!R(H5 N\P R)Mʠ+b2˚&>)as V3ƴa c4U<?~([n}b2[(36A8~kk>lx?^Y9ЋU ԱڍoܚCZ;evFvheK`erPiK9t2lҰ O+(#QaE6<$ryϾ` vI)1e%IZP(0*8})|0bH誓ƂK^mּ*bIP4ɫ!1hBLSbAmF+$Z$b:d<=eYJ?pHd[[yܜ yc&NENwj|jkk?}1=X5J7c3ѐL]BuVXyh cكS:+.;p@ZDar=+}eU _ Q|'1jxoa+Vj9thd-~U8vȋ][ I`iz-/y?d|e=6u05룏>zѼd'|k:F@+YeCZêH\~qRN9bRHV,zS\PdYFA$QdCsr@mV;8g8+Ř!KC\xjLHX U"1\%LP5ò\@GZ~b5 oB;t25VxR03zΪ#+0(%#ꫯ73[` 1[64VCB~ P.vâ TS /yWhBH BƪwEl Q R2'QVIm},UBJTH  )/3"U=B SN4(v uuɳhmڋ*UTѿ4Jp pfk˝TbVXceelbijkQQ,**>Lahs6-<Ng|҆ehۛ(JֆI 452!`R7֪HAsT1(F "Y_J`2]E5SIU/GTqXTWY 4qrd/F1` mۇU'R3i/1mќVB*[+s0.K[i L+`Gڎ~]MhV]`5p׬ZʴH*.#\ NHj$+Hm85k)Q̉$N$dimXMXۋ[ GT9F-6zxː`Cp4y晧>~'K<ws\H/[1}곷C ˽EECCXL&,d'o`T0z6envcCw_SR$btף:@j_hC Q.@S JҚB-UhVS$#1Vk:({.shcq؀lUO @TDI>fI+O٬%+B&mTT!iX/2+-í5٠*Vq(mn.BQ}JI P8.p1h+G9,t*J'UaJ V^'紘xCQ;a k9*0:`6_\ {uC[7yOJW b7^~BNDf6 2iߔDID +XtHe=ESX(:A L`ǰWyO}r7n|GNsYyjY^{Evjkb;a\=%-|/]KaZRR:%yQP} jpM7xwWq3,FBjͫXn"]₮2V:i\)+ˆbP`ET "@*⡧4*:e'6O? !$PPef4 Mah(gU~8(B0&@pҿzQ^t鳖/([3iRq(FJC\@ oT}- $ݬ_0qK4 e1QN^6PjgjLmAy-D-d&)QEep(xpf ߙXl;klgz.q@`cduJo*pf~т4;qiұ74wַ-*`v/ԂK\\>s9]]] Xr?PB##(wdDNc< z\LA ̀Śu"wuu)PMx?_o*[yLB1|hY?ؽ(sXoF!Qdq.m,2%LL8rR*l-uqEv̙L r* m0W_v`)JG:;%/0O,z?1?ا?=4뼅kcϬ 5)&n|pOiMˌ39d:9`[WWcήZͿa~2mq =Fꜳ>_6lǂGηx7IYd!OR jVc}7ҫ5&ZA_5֚W%?` w#)QGD/pTmؖ-76R!(:K9[5T9((G]P<@.HgMfpaozOHHaTkŅ2;v1lv93d'3U`m<%H/>fϨ:XCSC--#7g >KVp?6/>KB͠|u n@ ` 'X[둣+G&)<;8l^.ލ 6jJ0- MR io+t`@1ƽ[ޯmofW:OŲ,K խ|kX RFobܸq- (zyJ^ĉ^w;Z,߱c;=UWуXpD*39nC͞p놮kwEUtM#X2jzy9Nyg kCH _ G@х7eL+n "Y J7& e@G&$&``j# 1X1ɰdq'YVĒO:'8 zB%c!$}4];wn=2q ‰.wXr"|X}lyYH'HP1+Xȑ, i>ЭW ⛻oUM2{fض@FK>!Xk?p(۸u3n\Q4"3r[dx\vynGy4Ypw\g&zTd EbK[8hDѵL@3nFd&Sx՛pe\ "2Y u.?̅1=dZ̖bRpg`EK䀢Y٫ubM-L_$ H(a -kB) ("ɀ5 -W "?N̞r2Nm~(N-# +g`u"C`fr#mdjNz}DXdK;d͹jQ;یNL(z̞= bvi)i JҴ}CT {v_O5_W&LAiY}t|JAKJ~kPգȫk~1nuF E"F35 U3zrQElV&s,ǍpTo6v4c4L+$cX8AN]BУf ̰t'=P`JCh-X aXXr<y px+--Ḿ(2W9,MRQ@ -w^?N&l-D Ȕ2DY䀵ZU7t;5e9O5+j;ؖ_g[ܴesDIS|ioqMdW5F_9r.IL+}E:n4e}u('JGGmތ{I&~cSrΝt:-˵sٯFj ?oa/"ņӺA4e.g9PT&Nj|y3-d f{YΫ!ۍU׉d4ī.:H-!3C  'n/xW ćbFBe ÐV+_,Y q80Ɔ8{~u0J<@g-l+TA]PJHtŽ CVTrgϸuY#.9݄k*@85t#299&+;%jE5`M02sOg@X6u?fGxUFF`AT.Ӗ\4M}{/}O|m81%dpr+.7\NaG%m_E_}+/hڏJHCY&@U 1fПyƱSPب7QBe2PC+P8)S*: 8M_EEJq ,$:%N,m((-fkV++ KWE{Wd!ȔznV29db!7 rL/hg3r%+2htqNbrx~.ӢƂ|ۍ+Ѩlޓ>2VQK=g# "9Om9fnnCٚݾcC;9FޅRrcլ%k#XL' )>o4())e3$B~_2p7=2wT:rժU&*~yp#,m{(#6ʺ;5֑=4`0-]}sȃm(MGH՘#  6 ֙ F}hWAU": RXÊ f#ɬ,26!U,C T%N钤Va֭-ͭ(-d%W@]wKS>'{++3>ac/|^||LS &f̘{͵"&*\>1LKk-;+#tk3Vp>-RV 58=P<onnz7Nco*c ]XK<"!'~< M4t#>|x<W+l[aX|ĵ坻xv`WPz V e&^VVRWWtoGVZ b۩gٸ~#Q1>Xޑ+79@Mm}kk3Oƛn<EXkkk_oZNH\8a{Kәf٭`0X\\XC;g#pӦMÒnk^~t'PXVj䗑0:"x !FQTE Q~26AV8daX*2iy%i13Qcх M9vZ̸RB/u$y>>ǡC&\(c@AJ<eY_ln*e"[Ct#3np~je>aaiHL_$hA\M2H1.g¸Q=rB+2L|w8|[Z]#kl _zuO޵3 GXU$IkδpBOWVVuttM'vH1,+0aXT577dYV$oWUUl#m K,0袋֭{˯kޞ O~M5@1 L&3rx_1+f =MfɌҀۚkA& d@Z*S< #UA#$h M!, /"w:0tkcѬoZ]{AICJ}H0F C֌+48ۃom\{GM-nNyJ扐u3,a#~lgfVUWN4G9HTEyMw,xR%|vS툪e p8lX`%[M kd2VW^g],8v$N$sYv?Xxlp7i SHE8;w2Z`(a\&V\A<a @kFYY2U#>! Y(`݉>>e`'XV=Z@h[YY4Î9O-2eXBh2Xk3h%.Fp%k5fcCCsXY]Vبb>^|]S;g٥N~qtY7(Mmko*pdd:yjY@쬵K'52SB O? uW{b($S]}|}2VWR9i򔂂P0"uu9r 23 }XQcO.+pǎzUr,t,ܶr f\*Xeffs9(gzCS\gCtJSS}D]3.\`AQQqnnֲ8 XC?!\3233Pwў{y^|vTTR68ΆE2%!m>5|І"/2!/̴RК #B[7jC񀞈q)xk*& 'PSX1a%֙odF8fCP戟/Y!V "QV ]h`xxHlXn ^4 |^5XgNN+1 %d'mxkXL1xa8ƪTS<۷t4y ?c%Ǝ)ga#BӅ#XOW;y;;xoqժU>WW\UəOpWY^^k6,vn'۹̄)5g۷[3-:e`; |(z5?W>TǞQz*ۛkXi5},/L,qo.dR-8ԩS{ҫnɓi /qh EjkDމ47Re")JȞt'2V<:}H֡Ǫ=aىyQNU͈ BA; fD:%P<eƁÉ+DRq[``@ssXÂFրs+ddE2ɠp$ܮ:x-B#<&M|&9@ @Q㐙1%ivLkzHnhH4n#cfgaj|rӔQ #5n X\| m]|O=Կ_ZwW|zQǾ?FCaa!>_X'dÆif^{ ee)S`:i$Q0iqg,+++mYy芏HhG^~KQE?x]&LD@oVC`Yz5\. 1G5Hqt:WXWW]thІ`9=@)&'@@* ;EL$*7Vy٨H|zq ]\3b<2\d]VltD@Fn`87yyOʍpPG1i2DN:ÓT,u5d8@S^2%F*"b5~oo 1]E|Gaհ sZ{ 8sRraљd{r3/;Mp9Ao;Y|NӮ2q<uso999wyguuO<+O~A/$ xk2 aaayyvdGݵ= 2sƍ?ߟ~z|fb=vjjjw'*EHrSNevp͂g-M~ѿ^|U3(7^+qR硧.|m& ,AJQUk:~ܴ4XH]$Tjۋ%SR۸ [nf#?AhCDTJpzU/, uhHtU`š׀M_ 9tRc-fF:>.  QHE횳|sC Y㠳Xq,,bI&EXzPXKǀBI6$PPY e6e9d ZVt r3vAXnb///+TW^fE&-v3WUlc GIqIokkF]p4.,SAcp[ތ|RX4&2d/Bˉo(KwÉmmXRa~5Շ+OH~`p+3: zvQ'_}{N,**x<ce/k tC.XSwill. Bw5kVffYYVo&u`֎{w;.HHM5~b-D;xh! \ ٟPg⫵Qo`7Z$Si _=$SpK{~fXګ#.XiCu!uM"AP 3 X2V$ND(E3MUGn9 d[͸"PHAyM2c!e2'9rrbsw1zn(Y5(YO!$z]o:3L.L L zDCC}e؁{(rƻbI@ !@IWQ>W d4˖, 7P"w  (O]3?W["3kZ[X8hҤS'vlRsf3?c*~^9L;ȬmXpԖ:Q1"XUUc{0tLۻoO$KW|ڵsϹ7nܸˬA[u(֩+WyJK1s[{Q(X\O;,⛛G!R-(rdl1{=]=5twܹ/L m.[|Xt}݇py}xl 2Fɉ@p($KX ,*&O8g H&?t` HhdYNБib6/2K o+T(#L< qM$1Spd3SS,LlRB ^WʒL 6Gs]`Ua6nA\wU#̚aϾ WgX y_ &V ߝ%ˊLY_xedw!;3˖-8+,^ssǒ;w￝HGU6YN7*4,Ÿg,`5foD 5K09N#XhKdY)6pJJJb^OPIGIUp8q]T5@64bєeD)EYE*kUU C (eBVM2i CfP_9ÚMLgLŊ +krn\U9vX<[Z[ v= ~ztTY61';;5u7w&w}# &px^}+p x_E~܎pRirWMrA<"ē aʔ)%Ł` yAD ?W] DIhʐ3Fa>mLez Wڴ* .\0;;{۶m7onSSRC(K"R_^}}=SҪaD|Vc^ K6e GW\q?ٳR;Tщ7 qU eLs},~ӟnSĒ⩧ٿ{W<;<;'>=OnvV[H64 #qvJ?fsdur%TGTT,p؂g4pP-ϙ g frhC%A8) @AuԡR:kLr7vUq?N wSnŧĽ/j[fzUp^6i'i:6nxb$ LNt[)J'@ӗ+%VrHpY)5)r^T =]>c[Mo|ɵpx޼ymmmox7wɗ._}+. @hpS8nOHi9Bg??wݍ7ވ߱XW`p8BrZNS5Ս*u?oq;EplK|5t&jT0s&N44a$@ 3]f wXC ,Xvݻfϝ70hCa= t薓"ZV?A-DÕ \:3N,ƅ8Dq&TY=(lR%?#zY9dbv0zP@ 9)q#q4<K@ 96jrs3jf1D}ۼ/*AL2Y n|v3"kȚfXFpcuT_gX,y '(sdSMu(Bсdofg\u= /_QUUURReGhԊRSO}hjj=5[b$IÍ޽KکSff;15#4=hkmx > nmީ;b\&Lp[4Ur% X\P(8hC%Z_d",`MĠGBYV" L /x6a<y'RⰔLtEVq'[9DJf$00t!+*2\4J ,w\TS\ZdҪkUOo„&hC/|ñDz< /ޑ"]'G30'Wcc*F` ,TMrz\v/ϯ^߷M. 6^kT1:Ez=V, Qdp'`EsO]>x,dj&Y+L7([gfv޼[g˱ZypzR kyk97(h>"p? kxƒ/CR;D9K >+i/I אC(!Y +$K[%OM+ **Xr2dP!R#"2яL ~QB'xr/G@jET3 >EHD`Ekq"E r^2^:\dR?$9WHu5UρR -,Fa탁KYwD7.=~n #^t^9xq7׿#/~|\q6lhii)((`Y**'ؤ9&4vjQXߥZ:͙Ms=9(y@mS8{l@z=أ@ ut8s` `Vi aCCcvw;syO(b~~^fffAcY:#aip„ #;ϯߺukyN5brӴ=Yc?Dbʰ_%$TEz dX'PpB Nb^XR8Dr$EU$LJq T4H$S6e͒XZ/q< b pX,ST\?7yʴ۷dBnYlg?{ &e[eLַ%ص+Hv.UӠߋ,wt`{|峊Jmr]}ޠ}(`@uZyE۷m9nvغ{N^ srZ[+*wHҫjbp2;%% (u3ֽ;N=S Yi0u#ɚ{ϙ`u( :ct\D8hoGkE mx뭷*^oXZZ ,@ +1`B ND"}|J_fC݃'1Y M+!''6 u %0ծA\SmU #45Z;OV".?Pl`9O02֚NSqd$+. ?e!J/H%(9 l8Z%õ<2E%eWɿ‹nK؝rL +m.B6XJNZ:ƈ`8dԤ 9V Z;Zf:|̜zQzZن !\}nrO?tjRնP8t0W%zuC`荟DQx<-BƂ_\ZHBM$`:5Gd7 NNd_O6T{,+r0! "4d߲r$ķ$F8](.KUMEVP2v÷+d#ȓ]D˶[>È 82Q3#X1[k,$n^R5d@ˌ5 Dr"((hf/d߲U=n/xP9H<ݖ>+] AY[|PTT|g8$"V5ƅSl/^\]]HՌXQ /^9, p|HhzELq9.}eiKq D4q9Lц E%k8sud-l3-[Ot*V-h"=-[5hGZP1(XJ.CpnAnǖڰ}[1/# eL=rf&x?CY.7ش kg^IID7mOY?q\ljj:x@o!.S_pv@h4Po # /EOužWLÊmmmX[cb1VCeYۜ6Ԡ#"06;R5mߤlEVn ~N=S*P,XN#] iF"98˓Z?uYiU }{=eYy͵O=[srNgNNΡC,](mX)S6YfaА:Zm$޾u\vpE߈HV煒Ҳ{o…(Эz>k w)#=Ig=x ̝v 8Bd!T*LcH\ۘ 31PJcA>W%k aiSG(?`ŒnIs5cgAduEF *M={Ο7Ǘ]hiny]lI\,XEǚ ێ+xiw^ЁsUO_;`٫\}_ҥKRcX{ͶwܯŦF4ŏ.ԟ1siC ')m R\@z8T eMwjiPܣ[/Nn>?{?()WnhzG p@I.7tZZClC f$e1ˏn_r*@S[SqŪYbH$rs4 =/kYFvr@#G1GIky{z0jK3顣-S2kXm á)v;B^W.^T7H_І-\CPF cASsOn[9oÜ_2vz;e!So4m-8uiQEhCQ( ߰wԻ'qPPe6|w5u>hX8jH!J) .Ư7߁oC; ՈC̻>s)ohi349F3p!O 2aw6wv7sMsDly>|ui .K跧?( /ƈt۵+Ud97'';')KXMunܦ]< 0 ;yym'bf/\};cMog~khJ("U@VL+hzḢ[o\7h8jHJh6B1#Xcm o8B<)owA!2z̜6{{.9F2HNԹg$'W_M 6-5Gkѝ3uƴҒg3u qkNP(im2"`F' uMꌓc K9&EҢ4hed((wǯBP(T>607]~v H01x6=S gcBP( B9ՌFE'f:y)wޏfDhGcu GJh@U5%y1omKB= BP((X1=*~+3R=uJ---8q_̚sq ?'kkBk.sk3O]6IWx*] BP(Z/+q9w8($h+F]o/Wjv/]tf}uM4֗vz0CL6BP( /F`Uw|;.I߄){nUu* n\^Qbsm/KȢ<'CNBMӸ BP(^Uٽ?iaՇ[0.k9%6l8X Y@;TֽyOR74Nj7]Ù=hlڮ3gjV BP(2jk?@?.aky1Lb{VY.*{uf}}^ZSR:V3Q߇iH; tV!od}M7m/>#P==5%I-k# UaWK~-pzizh[x5V,bӫ'ʱGKm $IЫ#W{?}g?*$WHK9uA@ vY+|Jn۪gimsWICp^qǥNoQ(0J A,)rsޢ&Bwfi s.*X)'J? gδTzj FUC٦:u:k?Evh g8ǫ@[Z;{kvPUrAmEP('X]ՓP\;Q( BP X4u]7to0yWO BP(pB+TUUe9!˲B!:% GBP( e$j`VP8Ah^J˲#]A BP(3*XyUSh$ kjj=tْ0󊇫 BP(g.TO#}^~q7FIlW,C%$4U]-GG BP(c*Xx5]R%쯠0.ɂX߾1ai궧^s^rⲑ=BP(X V`躢(w9١@q\(:YJgLE"*GNpW#ׯ?ߧBP( B+ =_KAp8pp H5DBPĺ#`Ris (YDҚE#]cBP(Ӆ~0H$@ mG"P5%]n;W`^|q^8-',H+3U";7.*Ə)$BP( 2@K(_Z-?;#] ` ;5#K/ "%6wunSS2~FiaєC#]# BPF9˯\l]'5 `!EQ t]A5?A!`,ua0Ι{_NhM(K!#A*BPFziIpǥ34-Өf=e_y4=rOlp$c/ۇ̺a+f r0MSu$$͒cg cἉĵeY˲* I @*X^$ȡsύD"i\AY%Kae^,lohP۽&NэThEM]=5UP4'xgKY4c%ki!1>R5Y'ꆼ'Y1[ϿHY i_AMXP VUWi5{oZx9ĽɍUɔIJ>R CoB#V甩Sء&0Jf"S4WTF50\~.d%6lXu@+< ڡ8{'aqU#]SyXq;8A+e>>R#W ƹg ִ2gfW6n 7龻~}g*[/_o'|ۑ&74S_9^xяΧ7ldMӾ[o#Ǚ\.kfJ']XuPAZx͹cfҮa8bu&[zF\hCǒZ ΟtfTfM /W^pw]֖,O}кxtB6==-G~Bl#1Gmw'~y${gB*+^ZUqwO{8{ aXXcwћ߾6IRgɇKC64Ϳ7p4žw}p.nAZ܀ S?z3vmi1T?N|ji~'69!:I~ oAU= [ gk9/~m>Sq:PJ"Ș3)YI>a+4ϩV<ϙ*Joa}PzB,VB5zUA+yXy2㍢㻨v ;I-́7\~;̂_0eno?55M:m\@yyFé6Ik]1T?EU,XlFLwX[٪^۳LiM=Oqȋʯ$5jp!syCK1Wg>:@C PBlfeSxCOFۺ:Q3_^Z®mQa4RwNڦkm+lXUښĦio/oGUa=X\n~NBmͨ~ Ɵ̞ gZS%;qRڪd̑S_u=F7tUc'8P-2|>F4Դqk1fBAxB q;xޠ!f0" VpZ|*J$8m֊ [\vڅ?glBAxɇX< P`͘dr`|j뷤R)\B5`wur|Оko};md Ȅ#Y2a{Ð+m̘^V7^H&Ui3XjMnknߠl VmC_ZŚ~ȚtjV  `v.۹}G,kޒ7x?5lE-b'Q&kT/sZC}AA I#-5fꁂR\v欁@+ݒ͙y+IwG靤둧^.k_m%}NF  21AkF,tO2GSDהU^:zzmwuS%UURYJT  ' Vn.#`ٶ] }?qIJz7+7\yEA9Y`}ᛇms{` ۖP$"AuŘOY*o_mM◝X_c'AAITBҌRj dz{ Lo֡9=hhE[v3q/uѓ^^[BE  S,XkD4JGٓ:Xlټ~G?Kg\XY ׂ{aM MI+v5AA+1 # bm=PAp& /eF]Ӎ[?5(Xh¹vdIz6%X})6B@ ozYCu[PŲuKX,~YG$•T48uhy%  [ (XВKwjD"qbu(6wu.X(e>̮mdGÂCt\Oq  ̝{7oGVk_Fkwu=/BK~; ǰŁ  0ƂPsK˪縜?=F-<+W]w[q4sS>'Zr6'{h#AA V0h K 2=m G¡`4MnoZmNP˵lEAdbc`}LuBu!k DA9}A!T"q!XPB:@( `=ކ   Aq  LhPzpmvl[,PWAA&(X!R|6kfY۲,(ɨz[  rZj pGՁ@ؖ%>`EQ jVoAAN_P{ST"m[VlV( r+.9e#A\&^`13{ԶoIRRFK&aL.pa]'7'c݆K  ؂ضmfxoPu$6&*a=ZŚ7h4.}eUЗ_f~=GA`%mrwb-pC8@H#ZSΦ~]B_8(v;:cwAAdLAJld;y;#H 냁/ #99~F)ҖWIϛso|5%׿4ޥJAA"4L_3g ďtl[L:C=NS/q }/ݶ傑*  Ȱ`U5#:[NF')N"~Bkvv^_* vOR=  ÂXm7sO\eRM+MvE=:AAv`}ᛇms{` ۖPt$"AuŘOY*o?(RAAFTBҌRj dz{ Lo֡9=hhE[v3q/u  ȉLeZ#Np' t$ɱ/4-y~G17p  R (XaP8k]]] 3Xxq/۸6n/n6塊3W+NBAANЍhqփ^;oydAy=ϾtI!K==M>knKtj2jYAAaAJt𰆖,]W6& C Y,sE)?_gvlK=LFA9@ 1Hxܹ篹瞻|q4g%eyyW"4ٱc]mGA`%`0Ҳj9.>bGQ 1=8ĹOvLszެL/ b21A PJ@@0>sBuN>J\R黩fj}7lgQw?5^цלԥd;Jz(C9O,7R`3~֎ř:.W+0ԕx Uzbgq˗k+Gv'GƯah,QګT`6TjY[uPzUHuGVF nQUQDO[/A!2lZ:< C<[\Z2*w>]FLgQ:U{9%O4eu(Jڏ7W9/oT?z&q0%6d3 2V:)cFѰSj&U~>ϑq,:FpD'9]7bWˇn6U~0T1dAq+CtYFS `L-[kyW3t}.<;c)ԿGcwdzI<(X=8m;-T(ѫcCc+8s{ 5|\eIu풎3Z_< |}BPGPBlfe9XP0Q}FuJC}O.m9ͯϨ~Ⱦo_8P-K1|>F44NjIlدP*Tos*WZOŻԲL%ضukf-W.rΟ3^6N\?kG}lC-Imͪ1 ړzD5*mPe͈-X{[k|G簖dLߎ*J5~jd?J#><j${-GKCqw2n`13{ԶoIRRFK&aL.pa]'7'c݆KNbW gL&r:5@Jl63fWՍm:Ij0Kۍbx u٪_KX3#rDd_Gx(Xc۹\nXuzK??hnj:k֔_wx/`EASP۱3=o^}H$` tHhQJ浰o=|m(Wq%  R+0M3׹Yc͙y+IwÚI:y/Ჶ/۶\0⣣ZEA V%X3b!Ӹl9$'&xXigWOۼ?\*IҒaEA Vn.#`ٶ] }?qIJz7+7 mAKҊ+AA*Le7 -X+Hj%r9nE(172mCsU^QQHEA9Y`bfRgL&/o`ez5MAC3-ݷK|cFAANd* 4M8pp25Pހ=\#I}i/?jiq3AAaAJ X[w@4*m=‹{ƵxFt֏qy- "@M"  rj`%nD yK&% <`}ԦK^ozYCu[SQ" T+ZtW_ۜRH$Nl2%f ,r~ه-0AA4+İ#9s瞿{ ğڗZ]gϋdǒuC~SAA+a斖U+q9m=zdZxWtя\hb˖-74>3g YS6ې?wM8@ m`a0:{b!a[ZGH8 >i߭ 7SBitPA6ֶ! w׷;3f˗m-cc;ޕ?}oOWOcmR VRb3] UuϯЯ6p!k,kFki󦵄 ‚Q 2Yp`_6mZmClk}ٶxIH (X=*r(J$ }eԽzŒK3S]{Ad23gaLesԳxGsS[IcC:LdTېIڎvaM@7嶮cmn]qJڻܵ,g|DAN -LYo[0`=P{u?~[g7?3d$ VǨMGjiGnbU7@Tn^aw~_>}w_ MM(XTN m۱mB ^!d}|h7ngq]  L&luؘx&ۖ1gJ>|㗾;rt߷?t5OkWl (X!R|6kfY۲,(ɨz[7 w,FOB\skaZYt!x ܂/pn* VgZKw?wSgx'Tc8B$2fƖ? j( 5 U[y#l>fOƆ2WA&L/p2=O(zdj͸ [o-DP{ST"m[VlV( r+.9eDDKq 7Uȶut_PIc_P#L>\b`ABl'~/:}M< [+$"c V3LٽOm|T*%PMØ].úNΝotsO>xǺ ŮG{=ٶ}KK7 C<% V_ C xOEӟ>~PMO0joʗ@Ķm3c{{Zxݦ#6Q cԚ(ܾA@p+[5i}@ Ʈ^/~uV|aE|{OV`9?}'PC|b12`\nXuzK??hnj:k֔_wx/Ƃ.ɢGYȉ?RLaEd>=D .~xZn?D+N׊!oG;IEXD"j_0|a$4E絰}o=|>c}+Cd2)ˮ)G߼νhχNVAɄo7iۖ¶d(Nӵ6 )+0M3׹Yc#23V.NPkLq;IG#O}/\tۖ d{=ٻ[|z;#;Ad,0P{6dٹcGM@iv(LhPa]=nWWP?RoA9]@J\oC" )ycL Vci_yEI֮hgncۧv  81  2`ȡP8k]]] 3Xxq/۸6n/n6p  x[D yK&% <`}ԦK^ozY,ɺ:" (XВKwjD"qbu(6wu.X(e>̮m  (X!5 ϙ;5=sox@_7=&$־"/8{^&;\w#wr7]o+d$|򦏝|U@|`%`0Ҳj9.>bGQ Pa4F/X ^XHؖhc8Cϧiwm$oVM@w/ @ PJ@@0>sBu"G>2yAdd` 8j@(W!gmr|#{ۚ"/;Wuz(^F,`=ކ H[4dwoAeRjPLvP!@ɣʓA+2y+>PŚ|UղZ-| R0AܶmǶł 00zdSZ VdR}OɚK*gAbZSYQŖ P\*,Z>n`H٬fm˖s`'Zm@=5K~k#dMy(XPwxXZ㦊?b% 2zpzj pGՁ@ؖ%>`EQ jVo'+ugA`x ` +2yrfxaekMELLP{ST"m[VlV( r+.9e䠺YB%ZA V3LٽOm|T*E)ej`wur|Оko};m]U|Ȱ HFL^Fp( /,J[+A&(Xmfƌ M=]G2iSmc5qQ}OW.[}ik 88lP"{O*MUNEd8vnZ$ p8(^榦#hM9uwQ }؉ ~ 5kyΝڷ^ÊL^E(XؙLz7/zx$ b}0|a$4(%ZX7yӞxBJ)Tٷ%A+2Add`if:9k ~,\ ٜrtwZ{8靤둧^.k_mCu~:q^AU ֌X4n9%şd8 % V6o{OJZ L^E(X뺹\@levy<1Ju\&+yߴ$kW3DVD&/x",X|aܰ^!XC%kID.ǭvP]1Smhnִ#c ޽ #c* V!FkiF)5|d2=V7Pd44Ӣ-M}ؙɗ:E>ݧFzH.<V HwoM@LeZ#Np' t$ɱ/4-y~G179JIU ]@d AA0H h(U {8kƭf["@\YAAF VbF4ڸpn}d2Y 켞C g_Jmloh'gUDZEdʰ9#.%LX;6%Mf;CN&dp㭞 g@k_+::2#H|Iĺ{:RMӨ'LѡTjԲDcs8&h5:LE;ٙ>@.301\Qn-vFki)7b.8T(-D^h/Cfq*hS١8 Lb#hb1H: S))͎\9]Dz4]HN`]Ļ% N\s o3 n.9 Cs8b5zxWg8u2]j1MR>UbFl0Dm_~32i@Jt𰆖,]W6D&>PmK/\pQ"}]?RAR~B@ AAIF\G'Ĉ.W8I1.4G|`YjTHBABT x%XKSq2NK2猬6AB9𴃎A2 ("DQyH?DQ pt健ͤ}R]  ԱpٹtB&m.\"aB D3.푂z1[MoI A A)Fxo`g '¤vAB' fՎ0~K͘!:DK/Mj`0^e;x~AJ .L{V \W#HPB k83wk.z.𾁾nzMYI}=E^qMv,XWoOGvxo|V HM;{w.ШT yT]]*M:4&!Xň怲$fvzkKOU% *E$,YWavoIJB7Z眑-]ou.\%*iT.5y\y*LD#RtʁJI\) ҒBI'\ dE<-*tK,YGcR>-q\5V= <1 += 5i Wo&@kM_)xBǡ&AdRԅ*6P3;mA9Ή*/ԻKTCF&#(Xc0jniYM*6{3\u߹n L}G~Ro+d$\?7Yo+N&n&jsq9r _B\)gn`ƙfL˼#Ls8_KvIX.36dHM[M ,.:#naf5<ǤVJ ?@9v, pkr_V+MVBR[|s!sa09À=+({ԅ.8dTHy,м hmPJM A T ).T_ V1)5=aЄ&tİFQOAOA @+'%7U.Lf*A0 18`(tB¶LFÑp(2|>MӾ[o#w뭷!BwáG7[l'?&uNv`G]Ή)1-lPp`WF15G(PzUHuG!&ʵcHxjk{[ka:Jo[G*}'>s瀏iOV.VSJG2]z{Oz]t5w'̑0 Jwȱc=A2R`5;^󟨦B=Yni0;J|=J5ii9?i[$-hI,@!՛ hKėy6H|!SjҒ#5< cAq3WzgHIk3(;9LEMJr{MMw!xtN_ 3'&;'̾KIȤb搵HW?"K!WNlRQ ra(K( { ] ? l]9R:Gt IԢSNa6R16Eqc*!6utuj/JQƎS]ǚ)Es3G0dB6ݣ;C3f6/?3Wku$i* V9f ˱h/_"9.TAޔv!v76eSM㶣IĈZ*DtCmܱlG KL/(v6-|7ӧ4Rjpp\@&OlU`(՘l*]2Xb[JRpQ 6O3g|KPgkT!7!x5pjR^]rנ.ʃNQ^o2V{R 3d)e<ҶdM- (_>C|WB)~9ry录J{RhPb$2)B*v}h~Ml6~í5gxN9UJ8TKV^S a!ʦ0w*osMx^ 1'IU]&N.#AF59L?3n{;!dyȰ30jCaPFX[Gfw,eE)5CIUR(LL2ª|\EJ#)H3LR ;˛/ɕӠB<~_d[2E 9n+X-)~ 2vj6V*Y-IG+ -S.rx39s9܈!_˲`ҧrsXCb"{?Y^G$(Tp^t0 %Q@j`"?oI ``S"^+.i=Ђu̶#ś k",TZ._YXP/U* mwXX|up{5w2̑Z($wu=G b铈9Pr0lY0I&wa:aHxΙ2d~Nkz 2^RJϨ:V I29u8Y`{5_IRWӑ]%dR|ij*x*s( (oR*P9˂%d9RԬw-&Y_*:Tj)y\ Q2Tr7H2@9*ȠrUxWNe q;;!V9o]5+U ȉxdŠ6Ar+&/G  V@||6kfY۲,(ɨz[7QW-/$ZP +LJڦ+GqOin@ʝ)%XD}hV*'SIɕB1 ləMnMAgL+AA^ 8km> $ڴi3X՝jᠿ1ۻݟM08e>-)e&)U)͉M?8mf/7gv*yeʔT27皔@:7ʯy8FvPYo=J*]25M ø+UBN}YX)hh'>"SBQ,}ue6tQ5"Pd[wPb5:C8,\oP8!Ujd#Cms¬ګ`0 ֕KrE 1@|ZH ďmYbY V46FA7hױ6bMPX>ٕT'C5@&P0 g[ojcY^q 1j5yP oTlcrJlۺbB+]ve/'=|TC=֖&PmцƊ+KP@zZ#oX@,|Cw=w/Zf`V]3L7̼$.qRK*&~ekWvtE۾lRQUtZ9 9T#yYS@͞3e%ot;j7| g'$0C @GdЪyRK՘e&Ski8@&a&IBa6`*=̚%e+#9e39.'7I@GG7}x5V]D:e%ȠVN |G)w J+H@Rr!*QYU/Tyq\juf ԕY&"ܱ42.KѺ2A,WܱL!i*|W*OWSb5N_2`VYVWaA 5cfɁ=mߒJSPa|wur|Оko};mdA͟F B0 \Gw˂XZ' %+ kԂ f(J]qwdҡZ$.7?I xo!ij\Y :eRRpr1磉dbYhlƜ٭sWox3EloU٥s v  l;|Ϙwfhֲ׎xkoXc>+q(-*}PP:5t ?C@b^ʻF!bu©i;2Y4p۲|e;Tq@9_!rU+/b'd'2$@Ws] ItU*'0O`=є^O%uJ_LN0*pU65Lq22:p[ % \ dԘ!Eq!@Rہ7^RY YiWrYUᒕ0`8A1pJ/#HuP[Θ^V7^H&mMT}{,&nȸ}OW.[}ikJ-ԊmJV nD2]Ҡ|MfśqͰh32Yb֟=~  [۶m[l 2!r2ugWӧ\oN2 d,ߴ\,jYs-+HYf*pN83{ӎT_r*7䧎mf柱܎{pk?3Ϛ}[Ot9曮Уg6W;Ku _(4fβݜiױ4 e}٨s U^/5ϟU|ЎPM5>XV{JyzŴd5\N ]+$ vT Xބ8f%Px5Fure/D&ɸYirB\^ǁPOUF'̯ =jQb鈕̈́=UZhl"Âo\.sX,:%nA475ɵDkԯZ NtGy<P(e<8L>yGw>}g7j}L!')*&܏R| b/ue lHc_2# N3Sv!hqvYvj'u7/&>FujA\[B-cQ-$w%:dX\E*@ {s㲼dchCpfsIѣG|B~!2Ld\*:TeUKGĦDW3ppTki)$W&32Q|W]UqUIy͸E"\L ,UILx+qQW ZTGNVB*ϙö₨ TU"2y۵1+2(XؙLz7/zx$ b}0|a$4!絰o=|>c}+xr:b|TTx#qwՐ3T"(/ uȯfR Ҧ_ˬ|f@%[OA 44=`Z(B Ihj;f'H[[7h3aݾ3"DoJp`Rj0=YGdαeܢ2\X-\042ݦhd泖g'z(x&lz*RʽL+J"NHFK++J4WDڐ &sYIL^=0WCUqU\j;0IBh~d!@vUH+~ :dS%0.#ge2K4Ƕ!|*Wl'R yrSX*SC@R/\zh*%+'I3"2/K`^11"4L_3g ď%3V.NPkLJs;IG#O}/\tۖ d/8g]o+d$&L&Tļ좪$uEUe._BX3B]=ygF[4gRCs7@mkoX=CƬy@Ɨ0b^Sz![{yڶ\([xPm6dлƀ3۞i̘0 ]"BT]LEcQ R/0RaK `(vYsmF$Q^T:W7 Fuй ʪ*.*s:TŵS0/A17i yZe8^% @\]C]%,i&6wY(\r?  V%X3b!Ӹl9$Ϻ V6o{OB: .rC.=v\*d!oR̢u/q+߶nn 3ݻtYo?kN;ٿ(A`>)\~]Gf-6.IX—;5p2ONӹ7ej,\$(Z9YP)XBgB8kһx8{1ѐ )}١@QaT*1ϔWr˶yS?aRM+MvE=l. H]Ԡ29Tتi0^f4T*mhC$x.וKuB;U}&ZNjuyq7|o_-5sF[8n۱~_oxvc B9 rT]/u0Wc \ @bsѾwœ͖_MCN`'˙˯0/I|"M3N[KSL(i$##TǛ⯂H9%P󮼹H܋Zue^0νSP bjL݆.8ԝ`*7W`e$UmabE5[%ZɈK&&gbT%m~,+A(ιg'+jwp*ݫL lCYƥ~AjLe7"-X+R+q+BTWi5 S02/{ID]U$K`uVKKKÑ7],9D[КޞўzBcBO wۻȴ#}bG;-:p_h{^gPٴ{Áj},B &N8Mj*}ywEj^^]ù-}\ϾՓ0sfM%ĕ3ݕꓨZY2XaL, %+ , W U]4Q*˯(Y*3Ji)gRIfeU[G\DG 8Pβ^]/)ce-91NMP#aw]wmC[桲*a<72qETPAŒ}@ࢅ$PveZT(aPX)+Xd>C,d2$XެCMszL4Ecg'_MA&<,tɩo9<+QWSh|_ܝ^̤J~=ڨrGQ*Wdm8Mnwfo{ߍvLl~3knFWe=G=^N9縗w_`g-lkk Κ0وLE®ѯV޴&Zٷ힞4 {}w&jOkktR~XLץQQ %ے 7Ks'/Q0Q  8 ծ$)!^V'+! L,I׶C@r*SJd@ YɐZ0DU]V0Y˜Yщd+tfh|)3! 24@#5ud2 85 d`MTZ'S ٓ:Xlټ~G?1u\ٽ{z[ #7}mũH2"@Q/V Z7HȵsEXe17 jjjd˜#9;g5}\w2\HdIPvTr`$zf/Nk >Fyj偰s,n WusA'dfBgX;FݱxֆcF׿̝gin!Lҋ)xO1RT:Ռ-6\*^-\ j^bWd][V P|WֻDgPXR(4`f(F wT*W9_ z憿_؞t+l4q2=BFHYhvyu5\3Mgs67ɝAmZٞ?fH㌨ѓ`-0ɤ+ TVzU*VƫQ.ULKkcBUT ,RX [4uȪV,<&iۥ*27zӶ ;,ZenUL/Y %@\- U9`p`Urj wz/L4;gPٗR.i#jozYD:v]zmp͖/[O|iS©*M@K,B@lq,T[F,IٌilH4p[O01mQxsqYzhi q2$҅H*# /I¶?47pF٭^7c o]N'ȥ2NV.]N_Hac17`.^Z|f^yoΙwkGn?-I=btȹM1sUJ6͛I6IF`Rdq}Z-7)t$!zڼ2Ur7*F״ԙi要dTѨg&?C'\?&ʯ! B =|NU{Zk}}zê]^{Uuջ~6}J)AˡH~Z,WJB^k&a2VAb NZmD[ 9xp@ڐep> I$|D kfgx$iR.U7:Tݦuώɵ#rz7)?J?H"7~&~MobdQE?og>?_T*r@wQJ=K ۥBv+͸SaHh?Mq)g@{M;-_qHNUBH;J:~K5H!|d}葌GR"e]ebOsb([kҶ.q0JRw]Q{m;?xwyGjhc$"o\%`\">KU 寬N"6Ic@Ń}xSU(4;WBJBNDISsbEz0IοDI8G[|KmћD9`Z%8x.j79(jyvI|D@Y]@{vrj8&_I$ l.;jՅ]~m/jhOSַeժQä˺K0sWX&ȰRMRГ5"vB msȊrt¬5r59lfVUuIpxuuUS5VR)ЖZl B,Z(t/ "W1 tn@J2hTΙ9rAQig#Ƭt/BWd +fG/U `,QJdVәg}[veo߾eWG_+>|R_ ƗŶi>C /C -q<`x:R?uͤ xo|شg_J=2k*-Mh[q-O0?tF&61j9ؗ]sMYV(r '^͝gQ~B'pͰS?0 YіI.3tͥzժpfsbdXeJ9VdFOE.rLLQYJ{gjY;y7 T>]mYE.pĦ{ SH ЅmK@e`'L.k'/5\ h fe3ֱ c}6ibNpjl+TJuzO44 C:a$՜XZ.\D12a9y-IVYX8I$qBǚҙMg[(tdsL:㸮='gX5k]߹Ϻ¿zTe$Vm]ЕA 8w߻;NI@[SbS“HDVMRERА1UṞpZ,2=Uǎyla]4'Gߣڶ|bϣuԳ/Ylg[|}x;q $o5x?s__[6hzo<|'WFc{&kƴmC܉nWrYPb%@kqk8A?[X&l7SΚ!8O<Nj~lsdoϦMhvF9kyMb=+kS50b ҆EPxLRXw-n;QT,Y%l }Bq30e ~GJ$QUL;r|Ajnub(Fq(I$ `mGf~K Hk-dbYzuſ;3qsYySIa2$~-(_w;n֍3o +ʛgY){^|ə ?+qԴQ7I(WSz"j (dW#kC?K4l#Mde9Őu4'w;o' 4}ہz w+kya{fH9FP5HQQֹ[əC;_xsvi'-'JDƾAVq^9w-sͬ͸YuA+^ J\TJ˔#\g'beӥR5ryk֦o&y#r͖f&KB4hA `2{GAA&tWPn!hФ~8\o҉j[%|"zi˦pҏ]2[e@hEU{`eo(N(h p#R!]`S *,b ANiW@ܲ NWR+2cF<FQX3%Cb5 |jnaĹ(Ybձ&lD}W8i$,'Q4JrT˂ž%溿`]XO}9&D67`?[o7t - 6`]\!wt*]qy?c|]l,XC'jj]r=f2r^?niߠcM8EuAXGC\tӸRJ 6W݆C+.nrW=Rtjn4QRI ɰ%2)`Z5Yae&3)g̰ŋ)͕>[k{X=g|A`kJ FBa\7k7_uϹptkE8W ֱO3Smc }v>^ۼر8yY>Ǟt\:ŞǏ3I .x.]|h7GToCF;zduSW>s?}4X/]$_ITʧ3ނnYcr׍~0bl8](8tdn^@mD|JFE{ьwMH?20Ϋg'e€3&H1c:Ht:̓ H& B h+>wIPK|Pp$QEڒJs~UCb:h35CjP4@(Haa&psy[v9Hk1.\!J@3.8N.g) @m,2"LԽ&'IB}}Vl A.XLz_ _|eEXylA)?NaVje_x|iۑ<sH≌-v69^(ns6o"+107~xrz?둉Jm 5DQOʄ.76m^]=N_:Uix5h .H+O *8<ˈ\KŵW̪|g 8 CMZh^\΍Bk!4R(9mT&qԘ" O@u, ny84q ٩wɡiRՆpqlcF X/qJs2JANs&2+t[ ̴$Y>Nh`mzdy{!k!XFXEQ^u%qxJMlyP2U͎u@wu4奬zňdE3K=]$*rATԬV >sϾc/5{I,vmgX$'7፟]y߉z[ kPo+j8\?~ k[HѶ(@6|ŝ̼INr*g$9&MRRoѬ)j&pRհO4<0 t[cLw_ڵC/D B+l4B'YdjmUZ*TҸ  jM~uYҺJREmZ9e>Tke9 #eէ`Qק$vj1MĠ8$Mi+@=D.UeYtLlQJ[QDf! !oW+V+i1D'Xo]cv=z}B'/] `}Ʃl*^ ?I<|?za?0ikٵmOoYvE b񏲉;DaDVJQ;МZW\x\ͬܔ+[52^}'a@dHk'):-lޝ2xgu=|٫"AW]v7rflȕqnb,լŽjC@S jG5 ,SEʑv4] ^[ e f˞w{U BJǴ.1P%M ;BOWG'Z'V[.VdB*/G"m13;f`8 X^Rcu$QJ!aԠu\id8!lј!,Q 86Ng9RzO~*ޞ;nA5=-gpcn>Mǥo}gD%̧tOqry|jfht`kv=tjܱkׯfwJ!;${чjTeM뢓E$FbMl*PapfznG b(ULrGlc>sh^`ܛʖ'\`HJڄd .P3*EjQ1IA1"rkvH/E<[ʭ7Om֚Z3=Q+8j B&AoqE!B GҘBBg>H v2PHeoL",Y \:>D3kO(zm+j][9?e8fPTek@ ibUqV$r!=!(7k௲]~fm%J" wjfY }d\2^R76b_g&!>ECr]=$xF}}F3;8;wQahxg{G@p1VjB)&S$?RpYf:szXVJU[DZvfo߼*ʺT,,5RJj$/)]}֡$e((QVT:R҆uHauH{SۢTe%Ɓї;\lPO4|Y k*vySKY#3g̑0`5RY~u}9ouj"A~-V7YI ;HE .H;28T}JbbBd k&\-~!%n@LFc 5SX!j곥 ߝqo53W￞p~3!&DI<`={_sopȴh<}_Lho3/{F@3T75)QuV׽ڏT'TeNZP8 AYќzps9SّOygd@I9}dC85}ċ[ GVFo-F, \!W~%ʥRuҨ,,) HP#ƩY:X3 p=AȀJ 8( \i1 67!FjN#ʏi `+aɑ;c \PXZI>Mt8Y0<|3v\jܶ]m&^umȬVP%i]%,7RP]b!sfxSGEoabOaAT5i_^5S.=sfިnuԸ9HhY6"RD Qh0DOTz6P"bYL c1#Lh D-43Vfk*G&alp=b)Uu,؀I`|b6[H$Y!9Y?txrǾR%&]E$Zԅ6۪Du ,l+8b1T@s*UaHSi])#mlmG\aͼ]C)B m8T)+Je.0Yr؂@T ³6,ּ*ɱ&qx2VR_Dҏ`9~zZj۪5wt+"^ٹU|=?Og?+O0u) S9ݳH"r[6sůPQ.yy3[7w#"Ye8͞>+ e3er~Fz&wqr)<)B#״u!=ʪ}yӕ<Mj [H5 *PDOKć ͿNGڂ(%)TWlH*!רHb#4Meҍj~` wֺ];Z;Dqp@z@0T _fi`ˆ *e jaApj)]v1UE%,a^axEȱaR=)Rx#SϾbyqAEK[?,f=8X)0wS-#4Ȗ+zdF@>ڰB.c/ugֵkAA5$NORU=}r;}E[-5+w!T}uWJ_:_Hf+?w7\/.kLM{:>xYIst"$KůZ2#`J}#;td ܾsF'jt97[վ5k[ڏ`2<3N#yg}mT|4?RERddϩaZ}T4b"wk%@➡lMZ) v@iT eآxژnd3 %kqq @0~Ш4#v0j6$DDF҅b=Rk!SN93HVs t^TVXFQ_ŷL28Heb =?)ca") I3P\`į(N9.]Y7Ҍ>4iIOo3p\iKg5k''-`ܪmCチ"u1^O^|߾ STѡ6޳cr\8sw^n9`}EO[Tz;~tO$$P;qs6okel&T1O:]GJ]>|FT*xSOĩViT }}Lt+h~r5\njryUtS\a:@\lzgL)p>c)Z5Lv;GR?@1`܏Њ!py|JH({5+c~g{+J% %@ V]B Ẻb v q@''-`-qXW^׿_{oB=M=;7׿(2|Loҫ?xx:gOO%zē!nM$0~|2@J?dUطgQGGwwxr#$s.^zvk }e C5͙#DK՟ttoַeժrQG˯LaR 1eT+0'l/ď׊LUN`XO1sb4"cm?'#WWuBw4C:=OtZ1;Cb.UU]n8Sĝ6kuwa'ni+&}] >7ݝ2t$cKe$L."W $WJIbT_ZZfb?ò(n!?4؞݇ђ!dz-sp\;Jf-P~hVrCO~ۛ3!aHO ~ӤT?k=ϕ @m `j"D''-`mV/lV̺sǎyC;dıPr)u٥s'>IUItwll|=Q`؆9̅ڏ9 G6/ާS+;n޾_L}6mWRvA@ eFcm6htDTt;g(Ȧ8mtZ*k}do6+?VT6 eրU/NJ$9P2BGAUx[s \X5[ĢZTBu|>Ո uWEG'Ž3zE0 M:RV:P^R2u_T5PȦ*YUof `BvU>^#:q!FSsMu[f&wEo7A뿰j!{thcp(bGXBóCm86k=QطT@N$I8Y<_qUOLf=6ũ'xN,O/;'Eץݎ=xԑc=~hygA%(jaaۋ#{pU'G6b% ڱgs8/gK]vKb%mB $lZ"lQ@LL* |x; W&:%d j({Rȁc*нhڊ,V7fnl\ŀ/.,dBpF>[M>31&WL*hŵVcH'k$'MeA$Šw@j4%d͗w-[9a3x}%D L"s jGw#ȟ9xqY|k$j54; Jxs|zo[2QW3/GFg7Oa`n`dM(I,,` .$ pX IF=r,^Ȱ.XzטG5ÅGlw>Z/$eOůy{A\+~mYZVt7nF=sA?Vmޥ rus"G)ژZGlF3/Rm4cg$'JàMQ~0jWYQI<[9`K!sUTA V)S`ftFN\y pjcr d0A!]kN& :62]qU).F,x7de%t>ݽfmR.aWmy+2)+eʙy1}a\. Hn TLp`Kߩ׼D*21~{ɻEU &wX++Ow8\@$,P'^1_^&CN'_2)~X`z\'$NOR/Kf=0^^~$Xp%FB968QhQqT{^pkNBa%'@OPR(_w;n֍3oWRy+ -ݑ;P6곓=$?RJ%ddX4B2:P(n˭d=&Y$ϓw< 6: PuTqk,񸐜S@ʀϨc%lG(c̉> H:\%db8N aS@!R`*JօYna努49}~i%VVfᎹtpd]&*͔ %ug:A5v FS QXxQU_aBRq Z%o}dÆ_\ ё }11 -*Ȧw2+*$5אQOSo!4FhԒ~X4x1`Vj~,m/}xls6\KƲ/jM㡅c%L&fM/o<׽}MY5{+K :Zvwe^=_JeP陈@+&B 7֢VA A1Rg>6[ˤ;4275ٕ *nIP@{ 0fZSZŚP+GB,oW݃!cޫRrA>Zj̛l`CʐXI X$(W Vliڥ 6| 0c!NW :M$_{O̺ko8ݓ] q*S|ቇ9*eq,7{};j//=iu$Vds=iO|֛M=]C}…z镑ahہj+#XMTgxn@ T8\™9ݪߔ Ċ@3`T/dtc}]?=<$ͺPhTrTtx}#dn9W'\gdP7x/&iY-zX$5 S7qv 5a)&\Tn$[݌":RFgbPZU24ЊyS20롄+s-1@GTR0X9R4[x-X36nv0#c/iMo'<۸vuOW1\īT̃n,k8lf  .A %hx]ar/\$5: +E:2Zċ*Ŋ^~O~o/U'zgrͥţ'"˱ZۀU4TXụ?m3&t( ХsD~fk 9+8L) ΍!k)gڞ\`( ⦿NID k M _(u*>Y# F`Th8ͩ#[e% j3g$38r{`ٙ,_xS?Lbeǖsn~~;Yf{FFr97B h $!Yj%B1v&2 F wBl:4@6?'Sr}"UzC}*lU^)S,xRj~$ qA~nC9uT,YT'ј ٺJwurr)1M&,B bhF hfj؉AfSf -/-ul < )Xq^Vq$>%#Rl\L? 7Hnz]@ 9{s7v] D\?1k0)P撀oc_qٷluZruY$(/zFwO'1B("I*8id,=8jMCYw3JwSF`=opXoSTҞT~Z7!w RӎjV}h^mHP gE.DI0s4R, 4&(LW3#UN4$Q Vp7itI;͆6on-Hi$j*rZ1qLMs̳֤RIs LC[H.\VR1(R޵לypx,աCa]ٌgo5X[)p5ݸyw`&ڙUW]u]ggVj?X)dNjaV~3p)cu L[5D06בRb1f/3$N+;2>Ϸ&)^EI<0=#$6FGֹBIu5R1YP`Ž_,(ĈA)@ MTX^1TV'JxBHyQS5J5S+g ܣskZnM)hQ`CSgEYJz|vzM*dn&A<.Sgp3z0/JCV M,c;ܜPiSȌX\c,v rD!a:?ESV,B+$$kPfͼV:<9:[{] ڌs\bQ!I`ށs0\p,CSʯh XXm \sᆳK.|9k4 |A: O4%7:OI XAN%>o1kL>k/|H.{I$ n [96T-2ߴv@(q٬ uc%ᮗ u?-}V&lF˸{vv<82Dy*w觙9ES/-88âI uI@H jh9 55ёf+U Qʕ2.;j5 *(4p daaQ5J-$22pHPG $kEq>_`j* J"ZSm+X,@.@I`6uu>Z \H {>@g5L!4sCHGcVf!bJ׬]n?=k{~GZ\ƥi`ybpSh8aM$|W{n~O쌒H"$p p VC<`Sl+:)ݨ沞t P sR$B%#[F $ld1bEteW;J]\6 d$5RYGٔ(q*R8iMeXNt#z3BpmEhPv cAAqYkk}/SR94QK*sGVdE:=Ŕ *V1uxəIŠ$꘥ ďi Zf(,#Y [@g sLCW -_YsEOu:XʖA2Y=2P40SE(:"R@yPA,M3.bsf戡(hf:&qX7?I$DOݠVj`=@{zV_3:һec>1Ll+k-@5w %``|aNWtR8l6֛"ρRӘW\2бz:9v6.I?C2#W\R>^&3'*jOP.렀j͙uN ˘tdް';09qjGnCjTuZg:k sR)OFa7]xʝJ{uWSRVsJ0um7A h5qj^|ˤ̭kkWW@0mMp)IjPӋkKR%46پ7afv]KR"*8hggav *<$*AS.`Kq2*Ld&̂pOpu(`eqI$)-U01APWsgI., i]*p5зa)D pjc"޼0 k iʲ~(v-U 6 @csSӎC`Fč?ʌ(z:RPT.8=SkjoOe.UB0`KZ+qH&*7W9S=|g{7>w_xQr.U/7.FRh\;#5R3C'KSP@Z$u Qe3ZlgDTY$cW3IG /@RrIPXAHi"V9VhGTdU&׾(ZQL#눅k=E X: vDEЀdXI: #NtKt'0N"$%A% F4Y4@PQK{ŠBbˮO9E)+dB'_AЬiu*)2n:A Brmjd&*[)Rt-ءP9)((1ǀHxxhR ?(BXT4o`R:b0qpSHҗXQf#^[$XmnM߼^|[oTI$S/ `Oe"ՍGp3ٖNf7YCYƵt7o&ws\]|9΢Uh20VA\Kh 칠k#I󉙲amF3 zmHPan{Uo8̑\O#n*rYV n6/nޜS#95 PiJMjEQf#c~Ԛ^6MlIdRxͮn{umsz7wkՑ/ F:BTsY` (TTpYJ %'f( Y 0Y.]]`Ɩz~u>V OS,l^[ ]"X"AϐOX*  F,jBYЧX][Sc"PQ;噃 3܉/$XXwZx׽ Co,M/([r#|'i|L"$xb6z) WBmX3 su_D++뙙Ջ,rfuFC#1s_qb+7Să?zAYI~bzuU~}ebbf>R:EtUAn׫%8k%doG{0t|%S{3Tb{DNs3_g,Z;R GqbTG6+*w$?;[_rI;C"[k/**|37䳿W[q /UAT DuwQ(j"JRGPupƔ%`y@!KSt6*^*/UϓδY|,R A2 ռFk+9Z"\R`ajiu+%^0چXf(3]4튠+3WT*+Z dX8I@?'?W餢s7d.tTz~o_7_{Y.]iS:a4BI{߾9yK_808|bGZ5hfCx9e >cUq*U/f38hr޻3Su2(j˿~Ƕn^P_H*F .5Hs=AFJk^jЕ4/f:=J{PlԘh%yEv^ǎCe4u߽j=K82bL3MYכǠJjpu>R͊ ͸sӗS)ryK] esq,8+d?V#e-XP aΨ oЇbBq"-5n`85{Lr$@8Fzc[ rE$jQZU oITkWY Hp4L/\ t+1E=)ZCs c&r^_(PRol5͛v@:X:m&P<] [q-'& ~,V¿îEM^q}k_۶#'B*a1⫮zG˂|f[oo喅{my5 I_wI.bk^FZjZ h⹲K;m7&ԙ4&ir}3?e)r1T#-d:|U%w5wQRjL:Xf ͹\7#In|k?<<>1M)(Ft^Ia'pePP)Mm|/lֻoZ$NA\#2* 5GzNPR'T 7gN!zL(>i.Q{]B򥍄?7Hb;|ՃDUI.DTyh ⲫ[~O)W8Z>P {4v.V8 0 ( {P 4w*vLl~[?~6_y s미Zoxbz/_|EIO5[MˉoUd}Ta9妤Ds='dPE>~SjRuֲe۾?#5`s@$PYG!{Sf{`>I+i[dZ^ y٦r{{ȓǖ--O>a4nڶ}|Hai4 mȱMYSIX^K\ݨQ2) >&S#GOخG!A`~qoݾ+[Z"Ʀec& 0)Pq3S#xE7G5h07ي WjBD MQRF"9ZmyS3~pE@Zpy0З؟୦\o>?;Iʲ={ZsñWo]jpPk"*!3tvёH\2E܌I)LDviBH 2)Tdme/ݵ69qCH\تlֳ1}hT۷\'ywbq\3h-4\htv6 V!mJjd+we(kCfKwvg>2}h߾}]]]b0PA6)Z9hNWi 4#N-Ee21j0%UE,\R MuF|l 8 x"1uEj `iC3lqw{^΃>x]w{mxƍ,J9v45gIOC1HR( Ewe9D"iyooٴ/%c_dEpH?o4[b]>%ۇUe.sФ[m?M1S@*p`\K1iV+.sPǨz&;dXҮmc +eڝ&dRҞ{)ɓY*WjŮ{.=ΦXϸ|{_+} %Ţ ϯoR/d͒6 O,1ͬ }.nb?W‡e1L)iKqdySBf-/vyo ` Yn`ty-yw[uZ k֩2eS񞝃;l)z^=I1[S[amݽD&)vK, dy7 s0^Xwwݗ]vRom%l9.~)6EoT@c$fU8R8DA<N9ؒTZpT+lS!SUԁ| 7ZW;~J߲y@ѨٌwVP plڸޮKB>rb$/lظYo=66n-^8RM% 0Pݔ@ZGa:GCR*R$ T_Fi, B+w^pS Q HCXDQӯ*iV.iҲ$fkZǡ+~ą[QŸ8WF1S`^֎. .d^ [ڪ^XW2VFD&;ֱ֖Uaxfڢ]jםL8)TLdbVVdYW~ndy -Wl`aw-FAeK.6XkKZY|LI'-Wp=/,/.]}mQ/?3ia2JDXD!#A%e =r׵4ĺDb9۽Щ!)P6)]$L'Tr;X$ 'PQ׶oGAp.Υ<9{l?-F' rWP  0>zCMg=|0U0#zԎLMeJ[sick XmoMZ*=B2Ax[L^?_<.GWjĺZ^da=f1Ԧ|Y.'ǖ`,iaW.Y/ۊ [rξ93|V;6 Cp)`* JiL $PT [~+ǁ+PI< 9Gi{z݊S9~u/ν`7Ƛ0CgBʩ4ِoQ-z6sLy"PIUQ,vHV" 6ڂHٙZ'L3D䊙L]S]ZPnlב1?ú[co~{zz->JjKqOeqr-X1:55OzS A8kFT(/Jھ|GV*H?bx'TZX=|XZXD-c/UL<ϑ6dxbnXQ~ P"nSb9.jsRM* .zf?;lԇfGc'7eRDZkOޘ#+h,,_d g\ĺZ-o5E}Պ+OLn^߯MFY*+WtZqb^帖p6g;ef aPx<޷Z>٬ֳex|u:puGF.3TK[6yo'Q?VfMe2 eV[fI 㰤QS+Wk\6)K3˯WzsP0V%7 ew*!%հZa59\vyMPoA$gkwVM!bKGGѩ럷3xfy=?ݾe˾GwlޑZvutd+L)~u*ݡC"aIe΍T}DlKa"0%_7849~3clpܪz_D0 egc热`fp"MINFX+;lߺitb' ٹs=,ׯwѯ\?k\rŖ˻ZV`}\ဳ =©񙅅%+$ I\/~k KưB'*8:vP rQLX(DTerBp6l%3Ըh5{Ro}];/~-̀clTFmi6KynB-BMHh!W\vb]ߺpd?9;3><zJc, @@Db;=1 mE> kUlJCR;mX?!K ظ﷛"t1)d8[ɑ4[ZqМ4x>nMr /?_d >ϓQ Ъi,TXrJ4J  E$wŧNAfxrX<% #JJK̦=56rrZmyǤ,*D8cA;,,ԉO\SzU"VaSt+霕fucgɛQ-q ~@a{ǹyo"}߽O\JW:VEjԸX4;՛-~kTg3+sֱi i6R.%\*HY'vGQߜ'~T1^O}o78@ "6@YI`X(\)B/ &QA"8`K՝-q-k]سg xxv}=/6 Hg"a;H\k19כ`8brcQ;# <J>+yl{֞KÏL,ѹ<'xzfo`@} EPqYsW@%*'S r=BZ葐B)x*Blb0e2hu%!T*aXrP6U8Ua J #<6:o{~VfGj`;RR /Rjfy((#L_m5EG4)Dmeiro $SĒtzd+ YP_Ojo;)BH *5Ev;Pgp[u"de"Ϊ3QD^ e*sF0y84'GN>qB!依[Gz1̀$H 6j/wlxjC_f1@ bL @6cJ(ϹX? DDP!(BHz7*t-N\]^T5ٚ  V&b_Bdqu3TT<;4 D<'Ԗ}  cx 2U+L)2%)bH# fz3u]%, ~;췵+/CďD*Qy/Wy0Ĥu:5>Y՗~^i}\1VP pSQ`0%M?f ѫlYasvmxBa(4͎.w|v3 _t,+G6=MUǞN5!d+`bM'0 y̍10PKe4 jYD)KNŅnN@%1(Ln`+v$;E^pK5ԊJT.!hp7T$qPD91B.c_vLʓg3)׫Y⫱±q~2,4wKZQdBM-\0T§PJNQ'0IzGS9Ͱ>F*>[M æ"Jj>U7 Z(s42QF/e;V[2*[/~A >O;w>C;/'wOl߳3~6[ /j |hֲ}8\ɚR~݆+qdT"$ #uH:SԬTL&R`R f7g`Et]c`ONܜT3q)*M5BZN* jS"{Z~/,Ywo~~WӴzݴM7ѕkvcOsG:cpLbM6 ܯr9i\KK3j\~(t\ƫۿd(!p%Y $m94fk.1J4ESL0,pR,a(D- &2J[m{Ky+V磚S2r^Vmƈ0 Oר鴗ce/|7d/itt'ܐ뭪o]_+R {)23*=:#up⽍)dFϜ0l7AT id_v:c,xY? à́q>q^mevc3xO~J$ %( [ͻ{\=g莝'UP#Pj9OǞ 6Ȼc瑭g$"aTD\(e13KhpF,M5k84ۅh@ _9՜%pi56ngHca_Q5ǧ!*+k:PrzIM+B^Eج"YgLwYXE-bs4;Sx!g2}7i$mY6,eybv9q+jHÇ<+ϾG /y 28B ~U#GeשDWї*Q;Ct3S!eDP ** )L $8pDC=S*B&՛v\%8`eѓdwnoz96gbv7f|䑑-Rj\~B S"3u(J=4R F1GD&PEj_m}'T"KQӸI,m!y#"8W> q1z&B>ttiJޑZPuB:v{Z[MO~rUW-Sz>t.u~?~:ֱsf?B +@8\2G`bB j؛&BP65_(C%LT0 b3 Vsl L Bvcֿz?~ɛ|@ᦛ|~V tw*]-&Tck7zkqdSĕB#D X&TgwoK5e (u F0 ]Q "MpGGY:7]ܽ}"&|5CҸ)(E)K˸JK&.2@G%XX8$5zKk*KF %fX@R) P$) @K۽`q?2Qw]ѝN)8(quׯ7d ;G<ш`NHOjd#8 X^nkHTB&~~Hީ׾EW,< v\U'!BBwΐDFu&\ƗTMXI=l}b")4g1M&Ɖ b Y0v g x1ܭ# ƕ.ԃO뇶ck 꿖nuh@XZOͼC¯qv v%xޖq4Xߎ=O_ϝQt왰7mKV&:Ki`Y%hS rg!V {7j^o\L )^KަEaCOxů5qW^H3ƿhƅ2U1'&5z TĎ݌=;iC14Iu1(k&M 3M Eb L@y.AԆ5 tat7#I'8P޴ izIfcۊi ?@Kٛ6qT o[iSfCaA%ƓWLL2qp52l=z/[e}^Ps5W6͵W\qu:96%SHGQ# 45QV  `U 0e 5r[+8}F`&LMWxc;A`9?ٷ4YCUᤂITUJqdD's[dԿ c6ǡw6W|:=53|[IH-VL".TFVԨa+| efہQ\hw llŏL O_PC\c2S :){V'{mK9j^˳f%pꔇ|n?? 7E?1"Rh& )1C(Ӎ|PlZuem9E*BLH+MmT)!l*=i sS*DhhلGz.dGǷ"QZo b`Oa8Z-%k0]1RveDZ,>7<;O3MȐ׽]>z̏M 5/Z0a_ )XC H 8X9"i=[r>@$I&5Z9P̾lBfIkL1ݬ*%RirHJL4UzHA2ʤC2S|HjR44R/Sv1En"͸SzϴuSoJɩYb&+L>Def&ߕ=5KYm?IJpͤALCeܬ ST\Ak{Ǐ߲eKuG{5jclok&333f'NشiSպ;ſz(J|İyf- nTmvn}zyoy+5=s+?oz{M|5OVF(Ig<"&%,;]cI¶ҿgӨt de6E›ڊ֏RDsoc>rlhY ETMGQ~uR6&2znMᩔҐf#*$2o5|e8`~z}QIRqWf+$T+﹎iS/v]{f2lXmLjy# II':vm!Strr2J} _>T|8g.Bik6S(mO7nZݺgO|,zĠs;sk:ԞՁލ?gyks_׿׿=ztOJJ0p ĄKB)e 2u*df!'3 IQ^Ezש##{zCp&WDCnGsH[;5yAleI;0O*)D4]VԨ+De@mS# ZGq*⸧[)H22dc2vMa#g|? dlr,xblSl6wwכ큞)(aDeMU8b¤)et %z|/ ,~W5L7nLSn=tW/{n|G>d믿~޽SSSA{z6c]y;TEL 8!Lo:JDUfL ;V@ x4 ! $Wul5[ Iza|dgp˖fZ9|oÆҳ oOCWt.Ł %ӰNQgsVik.^x:|2Ɩ}lיoĉS۲cό]rћoKFb醴?7ste0 '`$Qk$3X5*RsYخN溻IOgKG>r;`b!0eRT%&݃Dq&'eQ4m.0#,z+JZ@O4 ΃fuV.)#nJx5#cEL&lI)X8ooj?c?^z^Xr`žږ N~Gk}3퍢hǎwy^iw}{җ\*VJh~=,$P̓Ψ%D</efr#meGp|:jM8lY,|*|8rj:vSpOOF |.@0T2*qM&I S#z^}L3 _B~{hhH#,2]v(Vi"oOzvuu='O|pa[oU??785AEO̡:cpMM]k `Ab߅X(kP@ S~;vؚV 噙0d{f_һhB)p;繭Ȕ4XBK2;Yv:\0jԘLf751RRP]kL&mCNW8 C{{4Q9gז#GN^tjTXLe7h dvM|p5Wf\zV Zςێema7o2(`q hDՈj5QIFk=.ƃ\ ڭvs =y86HM-+UԛkER53'hƚ6dx}i1j`+5G?`jqћ&LYoh=IfӦM^_Qjnub%RR&#(Ɓ 47lV(h՚&fe V +Mm#EXezSR{Z֖R:hZr%b;, Hm[B+BS֎=K>(AWR፶(#LCgFO["wcۋii7l;wgLrq- iY1۱cz^;2ŧlG.~.KD+. 9> "R!*D%ךVjJj*$Ϩ^H2).e]ID'Krng\IS<FHRtot3#nlk1 SA3Ӄ}^WH菤+_C&+c3P6c]vyds!X22sWJa_ 5fT l5?,@΂X&.@["BV 7Vjmsl"w_8UJA>j*ȼ/* li(փhetij4=AGs?ћjeC*\[B?NJl㉓U KuM=3Ă#ŏG83صXrȡQJ1z&lc`w9kkXRfs<:!0η5oھ}zl7 P߹oǞ=ӧ:1-R6Vo8E 3#Z*TR3^PE *R-_NFlGLIΩnt O޶o{2[ Ri 38\Ҟo/XR][6|o2֊JfǪOSclSJG( RQ HEH͋%`e},PB+?i% QŹSpin:1|?'q{6,F_ʧCHЪ'Lje ]ʗؾgE@}cz !=/ <jJy1V @YQqxWX b#T0O+BAEώ-ʔhP6+DZgApH#})e\cO=YY9]qGfՓOGu-; XooLwɕNT4Y6,G;3J<2e88*D1 X&U\7#rdKU42Q?y۱+Gxݥ['~`;[lN;1aib{O~,zT9GvԻ%hbΧʂ D KfIH(PVqڹ! LE EĦL1\` ÿѭrm'aA(|V+"fAOR 69EpSaƅ:70 7а|x|}/Uϻbȩc֣GT:T۵o߾ݰnt* ROOOz8N&jF .QPA*VHh ~Pl=^ d` c8Hjt$ h~c[^뿡剣GOצdp /}k_߻isaG;[B./fI>*eΨm~ٖ{e/*d .ecEv\6oxC߷\)DDY'H(~kr&( Ewdۖ4K(84֚xU6zF aЕۼhǺ7ٗQ"[3T7?},Rv7ڴc3Sb idli1V2 %2j`2T!9_@&DWb:hoAp5XA~F2@2^ D .DT9 Q$_8Q3 \n4o3fPG_/ vn9 EL\(}QXС<'])J==\I'ޛuwvZ{_d[6^fq<̐d320fC 6dpyfd %LB31cKe˲vt|,$.$WWU:uwrٽfR9VZ q1kG{V]58ɛ6 "n&4,A P=86F%7+D8ƀA369Y'K-RS"/DpOnFSfkacN9;54AP^32 s.Y]>tuܧ׏/}q^[UFVL^KUbcJ@b4. jIK}aiӵ:6 !]  >G&Xh5ԆshĩO-7̆T PH3Uf-r \Wx b ]UaЖ(;#7Y|?b o)8m z&1Fݴ]zIC ' v8txr'J/fs5/pl"~|싫Ww|fQ}~VUKo(PR( ."p`PA0*,`\UtWZ 2:HxY`qZL[/FRSdei<16yOVӻWj-&DUj>7JÄ>0gy&WNJ$ GQP~k!5Y.`ֈr_yxH8}׶]R(a%&b܂ NSV%͈aL/A\+8yRwz+ @RsSjtTEwc aߓy&5XTs ۅ۰̳T*$,NMLuVɄ9A.ªLܾ%yʫr/zR!fx:ںk%NeďX`-;`{t~w~ѩ|q]V չVvBu|d#w}szNj*֢^ei -5]L{Nv |9MC{_+OǕC+ֲP9!'aAuL?_mk]!ԗ4rlɃݙeu=W'sB L;)UahU9l,tCjMv104<3j&kQn×z/*[f ̠ũ|E^Jug$X}(2ȐL8X[19=+2vrR>2N|E0'MI0:4mK8o#>aB-,yK[jj=efC#, v0aR= GyV2̷<0^E db&dLlTD=S?Ȟʗ6NTX06^lZM^#SqP)̨q8T@,cADӂw:`6$hu'Io`~.FSt/e00o~ඦa- q@PϕwZr(WoKEKĄ]i@#ͱ?Df U 6+z9Vة/>nbcAT5WroPB劂xǺ:O[W߻ŏ#†y]_ʕ9a ҩr0 jUYm-c඄S>}F (!5hFֳ=S7DGFj7sHqB4DmYioDjN 6! 9|kn}N3h:k_׹|'s+O{ΈhWm9gjnqN &FX_=kϙU$&$-sħ1 G$ M(濲eOgN||}#UF wJ- t)lFg#F0&/΂8d[`OOx| n))Q B~G%,vgTz%_Zqw߂NS P`Z2e}*0Y9s['6fnQ Ax!.˽8NP)uZFKg݅+VmnYN7?[-_CG9֍['F'Ǟ=wgwmo\r~)ನzi]rF2h kEU^^`)GD7acdۦq>4|1|vwUkJVѭk b:(锊Wܰ83Nђ2#j7* t^kMΜ=2K`QQ#i'mi_ Ղ[0ADEO2`W!8 Vo}h[14x핹>iirIEOlqX`WT(NA}J! Yͷ Fp={ƥġ- u(<  =E{6`T*7(W NaiaHPmC<6ǯбVڧB: Ɣ3H;dF. @b\"roVE]:Z׭WKcS'yn?{#*ɭ/߾jpӆ|ǽs׆$I>gVG䟲l s(W.p_ދ^ZR+!Ҿ>[Lai++t`2N]}]O}MxKOu=:>${+* RV׾ֽ{H-4>qԑ?_?+fߓv^^\=Y>:ݜkܖJXj` Va qdUWĥ02Gw82jj5T8/Km=Z93ﵧgۉR%1B eҲT!J6-=8C}#"Bcҥ4pX9"\ R)tup~jȩ'hmXc/4Wʚ"kXi,b%$m$LASSh646\+5O;nup3 ?-R-|Řg s]36?{N&JH9!J֘ZG$?ìߺem'ȝ:>oS8 Za-Qae]\H!/Qm_wY~͍W?ஹp Z=tʫP\怪m_04khX?iMW ӏ=n;V\?il۷mGVU%n+k7ڝVѕϚbBJZ\a4$8rރӟ81ZF^ۼ {~a}  5 L(.SRMBBG0dtLsrKl A月.:;a$eJBXw0*l!pVctUɝ3LԒK4k~[u%7Bk{Qzla׆`x)mQE]^ы֫[;o_d\cj>+^5u֏1$~ USȪ֢^ I itQ {$Iza[Uc@y%}lSbL/d8Wŗؖs,hƵu%˓opNw6v|5cۯ,U2h ªQ0n-$K\͎ώ{o%i'F$^mk4@0ݮ6 TZV("RkT!S)L{X'(.%Ta2@âjAJa^i`B$V`E C^E. [R( *L/@cY U@"AdL=e\  *Iؒt&(*5uZF4֗?“O>_?WNS#gy_}r;Oe&Գ;o6ku=yz^7^k|?괨*B) z9q\w<v7̲ YfK FC73}9:[~zf@,𚳯<z:o3U`/ w*˼8u q~T Zǿa'-tCW xűF;_l;pcp8rLj!nn,&6WFf5֮_7i,n&(*ӏ=;c7~!WfhoThYh|n+aׂJD3ʤ4_lvdVRrurzc.m]xU N7_7} ""9r ɭihbj\gZ넀-TJA%y8Tu4Jlϲ+/;"v^9A)CXT,G3. #F᱇HuHj=9Lz1(<b"9KM lp-'cl"&7.PTQeS xj}Z֘,3ee!609yMoϷzަ<^{[/s)h*!Ko!恿턢.ڢ޶!FPXxmI}3-\bt3mu;$u#p.Â2疜l4un;z'+7o]a%F"99ugT䫶\|^~b۪MǦ~홣m+==P_+MW.|+i׶ݗͶ6ri0nbBo9 aki0yfʁ)ғy)ZL3B B-X* J9'G$ԛE+RVGB١$E9PV;(,@/_-/uY_0^J ry& hjQ!?@ eqkoeqQ{`τb%mإd@-/`{wݵ,RjҮ$h瓻[W6E[~}^z1:J/R3J9j{.^(˯AkVtGM/q  R[k7v v©!ݍ$VKyZ(+><׿x;' ʲVKn|b熅='ҭ'eeܟHFbp䈏[J(̄t*?key V41<ߑ}fLwTDӄrbo{ >G+`z=I3\'~\Ie` a8,*As7E#VG(GBx0 TQC@vL]E^G8hf6^n i? [MU ]Hv^خҼ|jmZ|ݤ<*jO tu̝ɻ&oo߁{xV!~ޢ|>]ן};[;{.a=RE`֢.(p]? -AL~s?Ds[o~٩9j4&$W'ѩ\n'w_o J?M5~t|jwT`a$eꣃ5amɒ2u-#X YȚHK~ ZɆ}ۮ^q6WMy?*:4(9bэj~(V,q#p2#BŞ>{l;8*.4A=j]WkgOa}wU7{< s`vm/yugZ,OAfHkF稨xA0;8VdHj+ag>&dOY*꼵`oG~8X;-+ٛO~mY L>BB~;i/~lv0YҳnZ%UQ/̉^;}/>z$kz+g-=kֿo~W󩓧E;ݚ7ߴfqekop p*Xj%V]w{b끯==r LXpq:8,g=Je,MPιgRZNF,坹a h2c@WSX70adQ.Mفof.aPij}01̬BE` <ωqdPK &{h۽F,tx 1WWrx:bt6F``YgY^zԇ 袀Oڻ4Eky'ㇿ}P.۶/珷VT-Y}׻_=.jy9RbZ <Y}To1++%vJTnC!V̢3Pb- YDzx-AV#PǁfD` 0vTJ)M!!f Zs]MO6N%j^ }yhz.\Xq\zunlZWۛ_&33Վ𽜯{.ݾ\¦ua-Eڂ;>zp}xQ+] Zp觷 <t+,-M^V<|Jj)2qe瓠5s^a:q= *g G]0?:EuZFJ|1kV?s g덄ŋoE-z9_8 ]?9K ]:{Ъ*8Tao\4@p,M3G;VJ)# p7n2дp%VW~+O(}4*-sퟚO_X6a,x,ܻfYd?Z):s)hcEraK/X/B >?y?ge8IxI10{* TCe~!HT]ITTfeڭ7Ʊ-I9૊ cDYwJ@#CT-7 DZ`` U@n"peNe%4;+RZr29L,X):Cdݖr)UXڒ\ 2r'9v\y-t:{1R3,8 $dܘ0Uճny+Eq 1.ZZ:ڽF"/[@GYwAɺ%VP0Eyi;qW([2=dzP]wh~ vZnuq$]]G T-/NRp!jD0U>.ܳ`pJ7SyW~4􄭚&{,G~t폾@f7rBfN ZjmNpw 확”52m$%$#N#@PZ\ݲqSMҤ\-,.G+AX]jrvH=tI-%,ò2)g ],ω mь b/Et 9YF1`\2v Q3 2 K)sVFWcE :K3w#fWS"a4{Y/m-S`}ؼw74IҼ?x =sģ[ܭl]BH=D1WKBf,w4cpAMRlPx"Xv@}5TYm-}\_"(gb gJ8U9-'~K &ա>G_`姼}ib.*nO[ɼ馭DSI̵P )^v`ӋB6hrXڭ`=`3C|)5Ta{xs0ν&p,a %^wtQG-;`?߰q[?=)=|X|t]jfc`hxfծ-㵝ӍM֢.yZKDiDA#GB0q2e~F04aX΢ЪI k8jcH_o(!ҹ_{Uwbh[_sgbE<5Oy`@ '9ƒ!ꂣNÌ޳ J7a-,{>4޴بԀ*HTH#e Mi{NOָo^J i֢.RXM|SIZh`cvq@}><|~+ )ZKM j,rS*7U}J{]2nܣĜ"u\lfs"Q`Cp}j>e U#ðW,A[ڢ`-ȝ7Y=~nk|u7O_=nM393:tl}GkџxVZ&% 7tz TV*6Fv}J,aړu7|n UQ`#(#L3u2TʴvOjbMuo~%SD4mFJ9Zo A'Z9NiV3OyJYb8V;Bh:c3h|2NS nɦ\Z!q9̕&R8s˰I99۽.ļtzb0aܡ$2n=k/bl#fRTAA@Д֢`h.43.X^V+m(xj ϰfҜ\II 9;> %R-p nL@ 1aUv)$E]j7׌V Voq|(cq߼}{7|Coyݶson~}KQEUԥ*QJi$lCT73A8+sX=Y 1%LT@)%GkT;g)6a6)ݻR"\F+qCI0SfiMU2fnGrbZ9dRkI"50O^Bpu;hĭri=Qiuf\Ƭ< };0Y8?mD bgM߀9^vX9x>Iޑ a=34*E},'tBt÷*\SC11Vdy #ƱGڝvNNMʛkC$Je3LOY_C΂^sss9+_@x*e[8d xn9g::&^Ϋ+X+raPkBj1(JPAp)%F'rҥ$%J& Wv|CńQUdT@z!ʱ YǀUN% p THZodh2E1S,?fww0@YzM[U)(qi?J[21hYpNbDzpPEO_x;"Tk4D(I~Y:uŬ |@\!CC8 @" IR;jmy2OYUce}rF~5肠 Yr;/I IlX Bue0 Z<6oQ Ƶc} t4pC9ȁ )wa 1bȮ^k'.雺ˠ^ `}˛;q /νN>ݎ3pzrz~7^{ԱFX?z TO!‡D[ PdVJ\#+VQP,xEy;9:M鐔"B畲A1ؐ4O8Q#YK$=H\Ņ(Z\CCeTsӞO*r "I(⛮65ucRqh;9/;%@ԑl.M7STJ ڄb.4{$ ' PڛB^Ą6-Մ렔[Gئ栥| [P> ՒFD@_̩dYSbT&x+h 0=Wpz&KM9.m\U[7mTi¤3+&"d/8jTuRT&A7 _;< =f5F &n2Ů+um .THo}.8hB/.R {fF-1ikVnq밚G( Jy;ЀLN@ SqPDaΈ$y5ӖڝPBW[ u16I,c.0" mg8z,Wk}z̗Fc~fDR}quhZv;{L'OTm%\l,A+jbbZ2L*J+aZ0E+B7=%%iBQ 9vÜȕ;uqXnpXK9,nBX 3.XXԧ63Tvuk7oWN,;lo^eA8͖Rngos6Bz5g_yέK7t:gZh^^UkQ/Z5.Z>>Ȣ jͤǝ ]P"VX:aF&UJeDur΂u + AT`uxد>w 4r^!˚`jcPw,lt5u(qTHG74$3WvW;p]ֱd0) < FL~vF{8s(Q 9WUI&LYRK̏#l,6jB¨-ʔԘ_v;aPfAEB$p )Ehfa5+D>0E[  m5ZS'?nwNCY0 V"ǜ0'% `.+*<@ a^>=3ID+Vl4Z29ЙI3x㵌;b#6Su|0؇g)MZVRRRa!a Ea5 T$aw׿H3^)w,bXhFAT3S_i,Ua&BGE^0gސ3c#*We}tAqA /@T+8iJ%Τ:S' ܶ `:˱+Ze֞j||h05EmJ|PVAO !3`@IۍPpumx7sfZY'{"w}HL*Zy16ń־rrBv\Fq,`lL Qa8ov{yd~>-{6uiE-Z^hkCYTVȽӮ$('ѺunQGdzR~Q/[(Be/Ϻ=}i*PQDDWqzhhޒ.Z)2 3AxcZ^u/TTFZ2$ʔ1@XMׇ'\@sϮPOscW+)Br[TukGfsYuplB 䨂 Z0-\=9 :9g07.S9 ٪uc+))sкSr&.JN0ϤA,5s fF w<;bOE2 8FD2O2f\4452`Cjh,زqs\=ٗ %Zg Oqu4Z!#]Yv_e\y4p&Y+&@qCWVwmB>BdW[,H9 ø16vUR[ÍmGuNǏ;ejPNj-iRTa ci07,@*r'ڧ#y")@DB!WYǝF-ȀuoFH$4NsƂtIuE]Xm1[w`pS|doO?> nbdd}^맺-Ȼb95e9_}e"ra/vdguiBalﵴJ% ;7]ɎΝYK:2~b5TqB`}:z|2l仛 fKMVk%~Ia7hK.웷*ؒ5YghT]қR]qא^ȃae=ֆY(4PZdX%mʂxm̸lvε< ö]t,[-n9|׿t?5>ڜ^~jetr I: K0 #(~Z_}.{fff.wWPU @2`2EnE~i5FKũ鹹VPccqGhzLO$O~ַi.(,@HwD ˙eY*Ogi:^N+hj,bY;^GGeW G5P`ņumWBўtC3TZV8ݵg~<ɨ0}⯬^A*\2qlĉsmNK!sk9|^*Wo_ypfw /<7r^&VO)֒VX:Z')3j3?oiM$ 8L\I0-MBXF}Ȁ=(4 > GHYEpu/_9rpnWry"BV7GF?䡍L&ڛzx_1PEQ2:ONzzJuVS~Xw~糟OOMo?s9NK(94J3.x+MYXpYijKM?I 0<4;27p6=?|F8QE?vr7GC^ej,g\*h3WjcfѰ{4t\kqae~@MV5rl7FRYߎ:)c3bCz@*0:&(=CkQ=MfPԞN@Itz탏~g灅fVD1 =g$vp xKX/M] aŰZ7V/ݷs?28e?ws-5,, 5,G`)ǧ#j,zc<{bISBЀKIdW HӬdíncfrHF ͔ƇG'ۙ2ss4J#ѷ7'x뭷=?E/z%߶wMc;H<'Y7i|? äRիj]m\:šR-\ Բ"Rj+ʇ}z4:5<:3>4 eydL /BH\2v]61oiԺٝ3o뵱zU`%&Ai=(yiec\XF,lӗBϾ؄Ճ~WKˠ%GꁞTjq益 &p0:uj8xI)h$d-iD8<\o9c_vC7 P ea% z/ > A%{!SKEhx+I+j=HU=,P_`2NϏ ؼvGgkNxxa1xzʢcz@ɦecdS32ӡϪF2M`,mL0pVxOeD7sCT$ޣR-S]8cC+`[Ab,Mr nHMpN:#qA8g2T@ |O~_us)מ{ǣFLJ1^w}F=;wWkzYyr RF2Z4ZUKA2<^v@LJ^TQǰIcS'ZvVxwEYhlSB)N=` jD?2`%_QY8zigq'-ZFa_,3s{*!$(*8 izylTƓeEmeDZ%G+h Ppk 80o&Ppze<b[Y.+'{q/<_߸(ѝNB->w(I{jM3,Ru@ިJUjtڇF␑UcI% =yw(L{B>o8TP[ oU&5R j4w퀆2WXo5ҰK-a1|$G_"Bku]foҗwK/uwa5૯{>X٣T,1Ρd)y\AL@K|5Zba {I;\nn?NTR :ShEԋe-¼%LJ\*+K y 3&ٱJ~iN;TC`;ejca;=-J2pjãcC5do%*75 ^8U% @Z8 8Es6^W}-?iTrCO~:0ufĝ K>ʒ4tOL/dX\\􄵗HC(qdH{xcrg@%n^[^-kc)0 K\28i[_n~ٍ/dX+iƆ q+<16ӌמQ382f;d CYcM4eI-Q{=EyC Z_Y!gbg$D+x8.6hI}`IR!gI ;:}V? c nGτ~4q時Z1E^)64uV5d*{nCJg&i鸟,D -$4GX˨<"epXzP;XG*H2\p#$.6 F<`O |'5e!^mqמfkeye#J臍5x}l%I'=ژ$̇{Iڍ~Aon,el_a5C_|ۖ->vswϿW,_m7G;݆:{\2ZiXx!eC.EF3ΰb <-N[3j(F`CuLF$\B0 Ewy2+wLjI4]aAaZU`.@e-(.3IٸU@9Dq']D]~o\yqEaU)^68߳i3NyZ? +p:&& THνjfH;F;Ar7"-uf& O~5(( ډA:U}*#BF[@TŃvLX7fHh.ɽF)pjewWނ-TqàJ%E!@fyVX Qk/,% qFB7tA>r;5~Jd"IO-^ѨzÄ SӂA$DpKYHҀi1&@9jX`w,Pjʔ Ēt#ighx3l$4|ҋY['4O5,4#r@SșaqHcqYh1^"_JTeZ\Q-&9::l`팭FrPFE-RPT7Nۙ^V̑4j-ffսAj-yJ}Ovf{ Md tFrˮLbt{³(BP m ֥0lJ*{:[r'J_cίL5VdžZ}]7Ӑ޶y m5¤0C ^K\ =zeGf~nw:2nI7]]N}GQ>ܨajPFOkXm4[͓5^ bry׾B?ꢭy`sջs.ٿ7pw32fvWQ\ĝ/ '4GM)LȂG\~pS$jvx0^ujH<UmcB kpKaEm qB A:e@U8wA%j0jEuSs̘LC~9sY4!UV4b5C)ӄwsM\]0!PeƐ#s8U{z?nZ!:G0 KHN@đDEw1(WӃםek<@ 0Hў?V |4$^/'nC"V:qZ\ /{ix35޽hoi􆗜ۋ,MB{jկ{ϓsô}뤽wzr}_}ԍ8WK }.(zp!"ˉUtƛHbw5R[<p{j0٠V={ ,m0 1%* єȰ:ࢤ½^@ *f E:,wC;}4eyQt9Uz6G+;<ϼ:k8/%ufL,:\4)ԫ E@Y@Z=);Y }:XXx~K:G`V UW5VFz9yr'J4K1ȱj;s`];_B X:CevxVE~ȟڕ0nhE^4Z7ԲYIt{<کSJ"Ŗ6e"ZZ}7jѺ$7L}?{o÷[ZEu{oŞόXc1j)|/k-(FtK Y:h x{8'< u{O%QFk=V0M @iWN\֠Ta CZ `nBT׵*}U+|l4I4Z3#203TMz:!A?wǯ,>_s[^3u3 ,ɾx`B_NP(P=&ed.TeqYdyqO.jnDŽ&s(.gҲWGG ڱpN,RctlwT}=. a<ػ^pllxdxQZ%!Yet.2Nv|¯V~^҈f8[e{w,˵jl;?:8!\ Y:v<#{e<=̊q]`7R:X `?OFCy=!$j玽gJKZML7(@_]+uo{oAe3F!״*T$/{'xŹW>Ϳ(tujk.N;`2bkyn7 y&uUuZFO3J2^eXf?">x.hFEhEĊtD{׽XTV= oFI UAr;B 0`UGՁ*/i%?pO!k_K菰 '`c>6?R| \`\y]'w=wvtglb5#0hGPʤ\uQrZn橢ȫmdžC 0H-Z\do%ijtb1iq*8 b]RX+eA],kT.8i[i-"|?N ևJM0 , Se` ^yP}h]FOkXW㶯͏UZc]|Y?cW_-nU7lHSYvGfS5#Mocut@ VޏrcA'|1Ze %B+*~T@hO=QH!J87uM`f,YlM W=jMh4Ai6Cmu)IW%ȳUaȞ`$C*)է穳 ]FmXGf@+?tBȦ/ݼugbڊAnPkGJH*Gn=tgn߂ܯ=GCR%M5[\.M<;G#CZT ,9hqmp|wvkã W6'%٥ޡ%$7?F %Yβ eC6I}JY +=Ԩj}bk  Q+JqXs}{&=׍B|]iE73oܹνo}Jh;N.B=c潧|1[JZ}~E e YTjif^AJTt'P?s(14y 22i]CjCI-U5au]֩ (X?=[=#wI=w|{[usi<߳pxOwFt֏{ᇂo J  nb匥(VP$L_^i4*uUl`,j$ tM{.u 9lW*mgV@}ró yjB' &:pm,*0j=lЎz#c{{_Lnw쁹Jٕve;!†=y ]KeqX[ؾwvrQ˕ p;6+֭kApwc_ Ubr͝B/pBvF!U=HN,z&]M;Ym vcP%*3"U>]~&r>U^tV-<€ 򝎴3* WIo}h8-~|#d{/]rxhYK퉀Is髜}Y.5aFzʓs_oD&B=Tz`?}Μ8{<Οh-<N4*1MPAn+KVq5j<1Ҁ?Pe'}jxh>|'M/UYbb,(k`U,l_^; *qp"V T2LƤ׵G+Lԅ7$VDDy޽RpVqXCj?7 _}/~~<1NKйǛްsCW!>toGL78G% -%O'ӽɟ@(KK؞ QUN|4ED7WN7lZTn> %'tzQ( pj"GqK^Ь<&S7ߞo'q*s4 ߃#>Ud lV^f#(zbZ=uHv"B~G[rDJg~g<ֆiEZ6gsM[ X /P<mٲ{XtBeg k=q(u%[++ LPA8T2a/)Y;hEf aՎۻg;JJ;K~_ }vT P1m$2PK ;fi|N,.5 p^λXCJotW~sCo˸3Woc{>zM*4 7]{-pQ3- 82OuW( { ˩gH/ZB&uk%[@ƮQ7nU|+P D!|ONpi6%U^A>HzA.dyԨjL'0 (zk'R%dՃu"8Rx0Lkzy Y^! ryyk0%R$m{rdd4Ӻ#n}| dfuՊ=@]=B;U9(?>3z䮻 ZoC֭ C׿G{f3E}}{長}'}=2[$^g5,7g=%+# *`^XsnunϳjҎjnXk>w~LfဵLd+PS禛z2,ZP.:+g`p6 rZNfxoG/ip^x JĢuB\ux^ǚV.DF?~+I$MS{MڰJ% ;7]ɎΝYK:2XU< s»xB=V|eU2a9UJ;IbK)$Z5.ZY{'2XpCsNDi)U0{YnG#"u1aEɩJ"|J *LG:_v0 +5ɹ>E>ʷB.U ƵQ0y=LJ.з@@OE6}{oxG·+%)*!./,#N\edUJ&peچ7nLZd: n?j}x*42 XH9-ާZ1ppOpFtMҡVgK"%T9dA --f<5,|ek;.lVYKBuwu9qt/{e =>Zkk6NBFMNU C Z|1XyIr. :0X W~dn:$i[O.Ż~RTȺM֯]yW-3ؼ2EYybb^ĢJvVV}#^0Nk@RԖA*5p~|fis>h[}B1&7ܸ`~ζ{ )Odˈ$oPa!UB.\$מsp+<Ӑ\Nsm+InrxXX+2NoOG\K~-cMXhSf}L=UmЖr,nl g®P)pH2ϋ0W2+hRTqL@#`~|C F'׍L ja 0F{BL-Ke>ۅK^o3ZCs#^ z=,N%Zڵչy{rx& -!c}} g0K3پef1U54 s>Luۅa;C4ǭ<ˣ* . \Bn9r:g9\{Y4iS.-!ˍ9D1d/2BnR۷fRJߕhf,h`_wuxʰ8Ԁ{ 6 `U*j_)pey=nלѫv|I:nr]=e'Ч0PF%=Y## R-:UW壙Ƣ+aZ+HY@QHƊ~$?pNH74&F؂0<O8Tng4=IR6:l5MM֫[PNG%C J՘kQ:NN7ԫ, M!|7~흑Ģ*Q =#70Zއccnxyõagm2Y 7T@/0Cp Jv{}OjQ@QHQ&`ҋm 6ɢ8PʭeqhiWN$g_x"Yqիc􄷟斓%cR52N4q֤Xa̸z7*U܋(_T iF[ZjYȱ4(-jT=/`X&M+rorv~5QR L *#;?W\{>wyX.Wϻ" Hڻ@U'%XF'f^Įgn]?izMRjelX2ҺNjqlxOb'U6XL)wl_]C>R(C|-|7@TȬ2v$> 7L KNz}NtNOwJOu@^!ʝHع` @>/qX~޳i~W\uY98oaSccGwd2~8?;]PO[F}TS@Иx` h `e:Պ@4WhYT@NtM9'mNL#JT͵peh\vťLjh兵R @ SIa{n۟ݻܮ4j[65וKEP@T~B"Y(YơM~ICٖ07T, ,A i7*4[Znw=L{v*jD+dXa趀[rH((5'g)KUpW)B5hsBW@@!HW^{*MPhY@ ϯ\vxFlU*Sm.Ě-}wۯw`oƗ]q4cUdظoiƿ{nkOx3U%Jo2^ E (CUn̕,rM4Bo\fc+B ˕6$8ţ,N<,Km{Ķm,BQf/9P4º1\\8Wty3ggFcZahA`#~5tv,hiC5GqM"\Z@U;DS>^QEu?26 A%q][QĎLp[U԰iPMÍ^hu LcHc^Bsi΢J 3E1Л:+0UŰ^Ƀ2J>mT)j t~s~ɩEjC1WheοAkge 2Nk_unuˆmF0w\giׁ׻bPgOk>U&Y86(:L 0F<ƄQZNP`NO {BwOaet>-FFY[q ڴºQ݅8@#gU Lz2TvΕm=P ȺY{n%S[֏TG+0@E|gáI%&Ud%Ih'x/DHAڪք%_|ŀkӛlxADj2%i܎cxŏkZ}$;QYT] rIV:#j3 `ꕰ.0t(b'st OeC&k~"yVX Qk/.8~Y1`穸Lcn7aXJNX+;R=(_DIȿ\rֽlk+a)_0mQZ Rf;KcQn;܀@#+X? H<ק|Yhዼ2\2>nV+Erh=l dhDDѐvLMnL7yKw&Fc(sK+4KEݎyзѱƂziO^qiѰ(҅IEI*g(`,=U4ܘ-&`QC C 9p2iOTc1}kz5"Ok sp?3E2:^wMyG}o˳6936M{4_ٿh??/2HZ "4t+XPDfaJrJRTyM-ہe 0aJ@Hg؃>ʫ>},2FPL@a#c4i !hQ +` ֤F)" )OI),3V@5@=d33}Kf!όL!b1h#Mߟ۷{d:<ވ|p4Ad5R4U,?S)cmƕ]w}GQFn䚁<A@Ig4VRٶN<= B7 |}:* +!Kբf1۵a܇C0A̳w݅*׵edL%b {A)PH\y'G KT.,q?65QT0|?;.Q>oYXD9kiڏS:ˤɁΡ'΢J/BjAqyҸ]q 4kxRWքt(W~8Y"8P8 uaB0%$S4L,^ 2(en!*XѶ  ShYed+зs”j~8jc2xXC݋9Fox]{I%B{jկ{ϓs['ӓgn|7Xr}XpYSk_qEE0";H efK 56Yژ4"@-X[h fPXnjݲXByRq'94D0hV`Q5W>lP*9Ir'C_i .i ~PP Ш W̵UjX8U!`oԢu#Injg{K*K8ux0ˆ8T|>\A5%fdJJgM @k2Ltaj8H @KЕvJYrf (RqUK137elx-SK ={ڽ.9r\7ųg_UD]+[g{E:*Uf ]eRe)&P'0,Ca w۫ 88ZJ44EO+6 d/dKm@566,,u N73WtѪ5Cܷ#1( oT[=7o2\Oo?!jl32Y7Vu睽%Krp&-Ϸ$N?qZFe0X@zܐzZ5=)ZFQ`թ7h@Y!i ?o^wm ½uuNrbK@LȮ#\w-Ƞf lP:K RF9~|"0*'Z<;"qk V6T}]*0' joil% R%vѼhtK ST+w؎'@cn9nL 3hsXYaY戍p_FK`$J|Ͱ+i%,shxs(4h99҈Sų7?=_oǛK7_KG3_0~}?YgZ8x ='?w~Y;g+|YxGN(x.b뙧{/ Vޓ?38[`tF^e̾J}\ HR%K,D$^O0o]Ҕl)S ~ˏ§׾=(;}גBp"S(v7.{h X,M_5[^mQKvkHu`.j=gOׯrߦib!r$gK/r.hJ GnܕPR~bVsU Dm=B` 9G8VO ؉~p9m{? ~vnG]AȯwqI$(Hۦ AR#D-e15 n  Vp/@&<@]Z5}r\XWz=DJ`& -Sոkco|fY{t1ydYgɼyګdyBcl i` LDL1=1??3˰DG7Lf`Ed-T˭K<˷ɼWURK.:to=yɬy}My{j[OojW始)6_yw^/OuմV߂}mUR2M]8&.L^x7 h>'I$urN+NA. QK4X<'zg׿>x~ӟɻ (#w,f2@q+OȺ:qj]tP|%kj?aC\tLYZ)k c~Ӵg֩>Av\KSO[f̚YWAWͨ˻,Aj%f%n3Ǘo5G,x^Q2CZpJ55^.t }b zͷŖZ3ߺ4ٜaiJǏ?}g?_/Ãw-]_}?S ^uOOꁵC5ΒO<7\>P;Q TYQԿQy6Jh̄J-SgCk{;-:]?rA\O_7x/̹>w(,˯so=MNl"KG2tMNW~L.oϲnx[s~k3ZhRvTFHDxA;v/3 r} 7kVM5mg3;k]KιQ.0yJ<#0Q 8`1өmvͰ.Me<-JC`O1AU!z^m<]oTCW2sU,cdǓcc,w}:|]x{롸1SdyUu6N"xdIݔ8+>U` \`&L3iVO{ӛso8G־볏~7?{O;Tگ;wC=;r6My%%OVah욬lIcY-`Vz].<( 2>}foj^J)6JG/H8Y1<ټyYj)QBvfiZYxW$n3/v&+իXO'WyƯ9oynl>iCKV-t>޼5V?}U c_͟/\?HO~sOCn_`~|M& >V6?o/뫯WGy$hp.Xe#ST9^*9Rĕa &opX(">Qr6J5F>\Y}Ssy<}rsڿwc1?;v 菞{9?? Z=2Hz.~i9vV91bؗ&:f:ߛ`FlvVs]1;x`%fO% MmN(>m zpS¨\VZ۸8a!kcP¬8Q({kx,t oI=[Xvx~x|z=׫ XSO_?p7>ӌNVO 7OO_GW_$Ϋ~tW0*Q B׸|Q 1 iBCB 9 BFpb*!K MٌeB<(ƵAk+YG%cV5'eզi66679s~8?߱(V1=\zni!mvjRԫ;mWbGÉz J0/ίv@Ns+v;˺v7^¨kq1?-;3) e36v:]Τiɛ +Pp#̖dֹPlYՕ&}'?;o+h;.—{<"uCW irj!-v:R}euf?C ѻoS8u-^<VjeJzx 4}v!z)$\o,8I/|(o4>v뮻,~+o85}ێkBIt%\e}" Zӻf(j}Fooy{{.//==8 fU+뫓Czm]] #< eΌYO!1Uuڌ'+嗷&ſM#:(0x.\W鮎JS_6%ĹǹuV7OZBpr@7&nY:!AnӎYy솴ii 1M9b~x8UۻtoooV)7̾}k֞Vz5֙.Ī9RR;X.-a2sI#8+7ա|\,+!I͈>W.>:/pkmvIxSh}Ry//˲??qxOO?b8;[:wVǣLjkE ;p3,aY[+##ƛ~?]?O0{ J2PH("׃K ֮6L9lp_l^^\hIJZb7 Ӊ'rt|A'YZdy/F^+bT[.֏^?6 ־iu~9yk_F emXeZ0Nz?8aBX#dž%1'KRR4 64QUIqR3jqG~fYN0A i륷_ٽ6)e&FAp_}@W_/.lM^ՋQ:떔Thk%4 8_x\0ţ0lj|m/8&,cJ1O<$r^y A9W E^!6f>yeQ৤'|@*\>uha̚z6m[kkE9RsiiBqkrůze@\#IPwBfZM.b ͸1,,+̖6H}G",* R/U) +ƀL Jے`ChWB=t iNK 4Š-;;+٭W< je57|HYx/k9;?.i;Ua EX'%8"c $f+Du~{s{N*WChdR"F8x`gJ2뀉%F!/DI[K4:u]XN oE hJS5j?χ2H) )=`ؽklޣ_t}ݰz`V7uPM;0_ȿa"o 8-SRdJBV@[!e 6n(~ JtMgRgfwD[*zKlVd羊a]^!X:`~5_FS}H;Jk7{-HL 2Оdi[`ʓ@i5ȹRs)5ęUlmdir>&y)uبd"je \3iOR6^7bXݤVZya22g=7TEV.-<"H<^uRNlg>s sq>‹l ޗ%D:4 }W_7nnp@_}:KVs7#-:hޯJOܶH360PY{9@a<C!*R\f*aV@4ڢUFЗ#ȈS%Վ?_nk|"c//Y'\X&_SH%bo)_SqJqd۫E>2JuKeYV}3(xeq;/l)a+E_l}Sa${HE(r,lY'ɣSLt"C4q~d;u.-Ufc\dY7},id_n_ꁵnZ2 y L-ٮX|L{Ys$]S]082־nX=MXz=ai6ىo74L%ϴXO%i Jԭ4Jm7Bn&F2vS,u)HIBWYHǺȼsL #Ih슰qM[P"el95izb'=ryU߽~#,qV>'fGvjTHM] [;A}ݸz`V~;?u^̡%Zj\f]a4ߧF"ڋ AHԐiT/%JzRΛ.GWՎqRz\f|sQ7KS,f.IEJFS`dsɺ gɹ&ua؍L$POKJ+8GvV7Uoam+67wЕ'hn LkcgU]?ӣ68)+,^R=Cx;nY7ALg?~v'ܴ_qգ`h&3I9<浳Zt^CWDЪN Ij_/z`V*~ݻ}D}u|azȃk}]X7‭M6v/_䵣Uy5LHHʂwj:pRi>5H澣]'N,!vVqܡԷ4w+4/+4u/hKr!bti9>Mk. .הiF/14Gt Ĝd UJYƼYLmRbWM'c~VMhXK< ;nԅP[=4 [|!V"BGhpJQ0餔,iv{R|PVVc|u]Y·|gab (C:!׍־ꫯ^N6(HMD;7G=l ȧP!q=EU|L:W }R1{7?'*ͥlۍ<*v#n}cu@D9'q( [U Hv[h@vLDXC{Ŷ$l޶ӕ^tŸ`B :C4&0 n(LNBW1 xkWa-uh)+F<}WrE@:ya#UHkr^ض4%f8:tձ[>ֱ8lnOżbc8{( ϸo؍5D!)[:-dˑPF7m {l@F*}B9vs=I~ OQTKYJ`H+) DԮ%T<5V<6) |;6vs4jI-D ZVvU¤>+֙I4l2 p^zqtuf8궝nwCYbmwgE6e^*X%ޡsU 4/bk.e[pP%_S8ʙݙԏ='/zcmFqd-_bȔ 'QchXQW_}˨rZC8E04NL NxM Æ#aֵ' H.Hq2H(ֳٜ2 T:`UͬliSxreD\X7wv\8 $fI::-Isn# y h6YNx 0ۄXf+3J֔/by)߶؞f NN=1" ZV?V)Rx] Gx ^z`V?VE__[}[ϛ\9N)M-ͶaкosD=S``J˾ W1G5j30RFQ2i 35?fjԀMR,= `b$|%J:Wcd.J%ৰB|whm^KnK|O' ,Zmw=DkЪZb腁"y0^z`V~c(J?>[VxV{<+m__cprK3pꆌoƬQ@QHSv95EiuC( v@+mhiW cU2pMTb_a]'O+틛DRhOZb_@38!̽_;Mh-fK@ZlF7.p93V zs2;Ugo`eh* as wre,S-^'DAž5=|h*@sxhd5Rj8J穋pî8͑UUq{=e8饑krY(WF,_Oq_ꁵnZ>}jho{t>vwo20ugr£m^>rP::@ZvQ..b)xuV2 ʸM X;z(;iִq6 4¶pQޏp4L[\rO_\SV̄%Zõ'njfh=r*(Fp[ds.-\]X<ћmYS*2'R <R6ڦBOm;nΝIWam,gRW_7z`P ox'>ą3SwqC'N>fg곀C\ *aF+itي̧p;/><:v<%IК=%FJܬdɇ>'7VኑSxOmő$?^5E^S'0#u۱G:7TRΥ'(_9M__ lنFJKGTC̚'8F=ֽoo6EQBֹsWvvkҞ}Ӂk#Ql,\x +[y*^`WJ -AC +[i%\P1PjabCf4P;ϰ-䩋 pAK:at[wOb[eщYfҳ#kz`V=z#'ˇ|j LSTwSo)gҌL8T,+|On%&eܹ ?Xm:vz}(U1 @JsLVz;eO.)4F23n=X۩m4O3]7{RymwrsO^o~{ߵ>B^ñ%7c7};OEw>u)a4Mk/=܃'uw-Y fQ]th,_^j"U-aBrm}E[6&|ưzQ!8(锈5\Huan!H% ҭ:  !Ƒ9ϓ!&wNvQl],&'W1o Q $諯U}us^lKg4IY`ߖ6g"Yk˸.5:Q#ʋV3 "󝇟'̱cw^)0I$ߥyS4U$Yjy"[ ȩ>jm#GV콧[;׏|?]YݔFDW)7קom_Y_?g;61/qAxgl=5䩻v;_?u='E:J%7Rg{za=gۚ*W.d#d&hߓ?ǡ~^Z ZʆNi3ȡ!3=䓫w>|fyE'UMâY^0Kˏ^FP?fJ]Zj&uƕr O|։xqk<:yhmu ߙ ڝAdjȣ5y1ګwfcw|w~]³V%͸7k#+{/8$3+cm,!~nρ5)W+Ra.ȤV >dEiUFyud(D ]k&7tEa j#l TНwi1Ea'}B׋V}}u{7 ns=WmvU6ݼjs]j'E7԰.ڮ\ypWmy/ţzU6=p:gψ<ώpqXdi&kiR6gcJssĂ lҰu1T)Gz_̶9ܹc'OdÒK;JqB]aYP2xBdQ_ک\LxO,;.3ΕwݘiSr:V1!(_d\1Wַ.Ov:-`pѵ?qB*etȄ؞ٛ ;\Lsy m᧚I+-v,ä 5\&V(&H aƪ@V2,:6X%(WC:,$\R, Y@+N9[BL1婸'LV+#B1}zT}u-hz^CMw$}>,{ok\|s!X;/Eůlnb޼a>^IRY.GK[cG=]7#<̨k 2:ALg)>!BKg!,p 3VX32s>e.8]WeA+ XSdB6dL0U`/-d6,]iw'Ʒ_9wᣏr`+.J6'gz=GWw$q]}O4h +@܅G-0bb)ywBzX3}3sW,jXF;C#Z805H]:`Sw4}a,j4`9ڵ;xӆvlû* hZ1 S$Ycd%G.;%Z YHLd ALW諯V}mkjLo3ޔQ]/O}V?WU!'& VK h)cQ\)۶m^3ޫ_Y=}Y] :R.>- }<ᜏ.e40*Ml|6lz%YQ|T""8+I!I)$ρEKRJ,<$q %7>ܺ#m< 4;;8OXmuծMCx\V;V;7};&{CgkR$mH*WQwRձ@Lv_?*N4JJh$~&v3PtVu2B l%!̽T9 ̍btLWp'*q\9DdTtx - (aXm,zl ־nA])2RG(5Wb]ӝlGy3sÿu8sѬN`.ixsO=75i 4zֈ8S͗ ϵ̴O[8Lk)5wȝeJ2[d,㭌 5tFGK^ST3M)[˔H]¤tGSљUxw:cʴ-suSfr 63LĜT)B`ynl 4YfĄ{5*Rl%Tp+Sim=D|pJ}3u88׎doΎ\dAOT 8|%xoog@ח[W-ٿCW7^LZpz7a}A}ڲ8wvKgRz𸨬 '~umgZ{K04l&{lV9I%{TJ)Mnk+Pj$l`Xn80 I 3Rq^H~Rgdk6iCɋgi~^/\ E WP ID7呟&>%2NBN@^aۓSL,4161 53er"0#+ޱ/mHIXhgjPƷATE@+ov|Y۴pHMpof>LLRM0 0$;ZQs^^(k ?8P5%LiY1îJu)勣+LI{+ ![I L#K Η"ǀRT q&Ϝgy.Kr1iaӆYPRU,V-s,bꭦD4Xb Оy0Ό bx/TneMǓqJ-O}'2aX1zX]ybOmøm(ΙPWF놀q.:8irIm]⹖vd-WU270o a/3$R`cFFu,Qz@q_; 'Pţmh0ߖ.䁔ܾzꁵS//:\Hp^ ;yOwáa}WE-7-NY޳;WWWVFcYU_[}7Z[Y.<5NKɌ4JE/|TsEwu2߮äE )\UE0,{JOJ K,q*cmyՎH3ez4= 3x!% Ey!@캬H'@QgqCMTq"! /2ְC7?K3]|joVG'Vn?{i˜܀}"F# ƭwŰ h 8E1Y-\iS(7"(a}SZ`Sa5's^ ־iu0ܼÿ̍_Kn};<48 ;sI*"#e{MW`" <ЌwTǭ2cC<$('^"Ry٠v>k<\ P\Z>n2w}Xñ7."`PK'3WSUc o!7#@;ރFY&h)G(ͻqg0ᣣ;߷{e7{| SJz<$/)PiPd/\sh[LY9QQ;UDј=52Yt8E8n >Xxstˏm) .s& r M#ЏU[86ph h qO|QhXhVa+d¶.)8H^׍־^zuY_:tW__EIB)aN9'%R[B|:i5վfjD4QfQ\$rMCD?JŰg'bWJ :FeϽq>v'뫇:r1l )c 2qF<.(8ٚ&YsPuUOv`ui!U8ynrz^mvQm muzR9st-V6҅HnWkdrxx6ZeP`xkqv %꺩(@q񭉢i*E!|KuVuUrDh-,8-h#a0x o~q xEbG0߮H]^p1H亀4b`\OGz`WCid.]ׇTZZLрWdps3̲Uao iY y7BAr1?Fʵ֋iU hM:BաC$P5LiaLEmV-E22ɒ"RDTZ8qJzS1e۾|wPr;|pcČaRgzM> 0c6E>R+Ɔgl==LP:@%/^+ d156pD A Y!_n:kK#iQ l(9c38 xt6$ZtuHa&Եu'Y|"j]]wGEJMv㙏.rzaR_7XU}*/(L2hoq / `61j]`ckt*Nhoj OAK3Mkˠ&2QER5Z=M',㭋o3jP*Κ{Y46 %Zi+EեcG-E2)ILk"Z6n/lh* \wreA[Vђw0(l+Sxj>8}] ֗ÅmkHJ}P2w@- :@MrF\ئm38NCK3`V,ƙ(k.4>i r845Z;Ch8&Zg38$Y$'= b&Up@xC`"<%)#|*0p- t t~\«@ ؘFRo.}ݨz`V*~ݻ}D/U3ZSgK,3ڶNe8!.\ʼn)\6(7@ uc 1aт:eͪ*U Vbrेj QRSS% F륨( m_f*Ө֚o Nb{y 4v=S sY: `5L1I8PqY͵ۤ2`n0eUz?+(R25dq+ģ 6zk_}W_/Ɣ#Z[[@@$ "k$Ju9 M&u1(pPɅ(lUi2[ƈh8)lRo6jM2ʺ3Wr]@PJdEЀ@V;5~ }Ӹs$ @&2lz Jh˱7l+ȥճa$V;=hRXë=$ /DF?j$|[<EiE}vg9SRF6, 1g"/sVPuJ[qF` %E&&ۊif{.<1Sq.xElG+`SZIxB[TzRS@7OIf0)}uꁵnZ=[}}piVUʡR 3;Oi4&˱#kBEM8[qu7֊ڶtRf$%S`gۺmeLKŤ@©zBɿHeѧuG©=rn7.1TfФ궩G%Z4 \fyRr[($@Œ" t%*/b% bzq<ʃUwk_}ݴ_GWȭ>[VgKÕQO'&JaI& %Q:H5kN B6AF,DlV%@:Lޜ’vIaI bZPAAwN"qr "I@9,˲qvwvRJvTJ~_2 hEBQi( c ?ks͢QDֱAATwyvf3#"nHSv r]TLiܔlwÐ!(8ej'fXSг]z؞s{N ԭBN J-yRWRñbW#fJNW(p2̰=LW@=?|CR䪲/ C"\d)e͞ƔAIy#3= ܐЙw=iI&IB۝P9p&] Im C(cRX&eRCITRFNgSe #NB7\qhR1nJYoyJ)iR+_XNCBMG\Ȳ0Tg< 2U/7~XE`Q@3Re!Xa49Uf   U\J)X6O7Qp`~(tZTT)u*(JVqD mC乎ܩAR4*!|)c%Eb%ҺLaj@0h 9梅Y)}/P<5-nBZ#VzHrv֡h˨U|ϱUTT5:$f c3US wJ0o1Lk愞\KГ>W/US,kCjQC);"+ D]CH-PH1 ҮK/䢢؁6VZW,f:Fg6لr>/$tgޑHzT=ZYa] LNH*M"i 顽蚑I!]jW$&QcBbFÜBit Qj-I5ul>ea{o.r äl(&4Ә"_ T[XÞK)nQg DߑV)&Wj C\uzB(SLY@6MUQ\%섕`,HR\ou0Q8fJdǶ3\8֟, [)TW aiVig/%”oQ-||Bцr\ZWtT]'t:J, R>2 I*%lA?@'յ(v|QG)~U;Y71PqDODRәpuyjSbtS@B Sq9|>&*RJRSbjT A <Q}Y Kx6e5iY {7tTG%JhWr܎T$ ҫaW_Hb[4(N k0US)ݘ^Y KIu d`L)A,,¡UrV1*@~kUu+;XB>ذ n_k0`G{$-n 5X|Z,Ry= F#l MzHşC&@6 dth=s?r,% Cʚnp3tҁ2=0jAPh32Eb+\*,B9N^#<*hkNkd2x9!vͱB9C]'1y^pJ7-9OӸ9lXɹM-ݶ!齾W'`&er²SSdBV72mr&v[({XqzJ?+'5mhBi ETG]!YY8JTFsx. LaU"&~Cr}WT#In*̸8 }ATIJ\~Z)482$ԥaNE azVq!BůRGrRR# Ve PV0N)V'īXr+]¼C}MVUBIiQ6Sh@Ä!agٜ<2i*YB Ih_RAv !G﻾Oᕔf񰚨pTMB}|'42iwô\B@tYB<^0Βj:P`KB9߾c s;s9Ƿs©35;c;nBvV|EFmnM|#vѰz%3)*MyZJBFӳY'@1T"U➛Lqe;jOoi&;cQ5X);CBL&*O 5 MTaq&D*դU^8h+SH29R fŠ2 h􏆑|^š:ǙL/8aJB(9iU`㔊 nԊT+!Xe c Щa.M7.QJM<-*B_ y,RDT$O(kUu4KsƣKr!$uڢJ^;JA>/VeR$dcU]|Wc4UwX7J-54rO%N'Q%څ,4 dFPZL5$ u"mv[b6iG =a$RB%y?ɂlg6JT KqW_r'Y <R ,W* !Ѯ-S(_0U][$ ws|׫Q,2WUQ(ߠQm -fbI7'[ VTUZr2#Fg2c(\*\ɚi)v.iUi@URMd%(׀J%ĎX!VޡJjyl@9=/` Kq:3CS]) -FS)"_甥4Xo47Otb10-&C$jY2#QV|Mg b+#HR"dbLC ԵKBeƚtɚ*> EfHrSgj*pfW4c Ƥ -,.sr;x)GT $Vjs2Cs%$PT$"Hքt,\F(ڔa5gJjQQSY<4ZјjWy7Eҟ⯠]iSeXF B67\5))?)^JF|*?@!84†uF TS-%5Yy*b QaE|*KJI##ckT*SЩƹ0/Sew%B57w\)"G~cX MUuVHٜK >)@4**ˎK`E[8ҋ: @BZ.qE2Qm &囒jTf3k{Bf'u yI9zٞ޸C{ΙlLL&L66 :Nai辪 ΥD>URia*F=#* Z-n,c-580xF\ыzKEQPw0!GeM0D~%D#iؾ+뎓'+is]9ܬM ܓMQ fʧUb-DRfd O=>/kX^5*0Iﺪ+RSJT7J&ԜlJX[3L=i۽!I-s'-܉͖oeIxBZ)KQVհxPw Y| p,ezRB )6d~KSs+LR?}&%Wɮz7̈́a>^20tskGRVJ\YKp2G B)xvgmبP, 3}B@$0E/#<2mJTw:9e2ax, ] ae0Gt XxG-%s + k!<j^TIy]r͐$\<,cܩ)zP*t2y!٪J6hfC>SRN.',z.sߧ*4ْ,9a,߱ZUfB)L]Y$d8KV ֥{@We?۔0RFOJU Ug֔5ik{+tv'TcSJ41om@ijgt4RfaU)K%F 'TW/'$WV[" P]$ !z>S)] K%\sy?iF>WYٺ}G&Pjـ'aP2*bI]a-H9g1YekTiai+Tahj`J=G²hw7U}SQV%+FU= F;4Gқ̧gJ8?0(&RxEMOG r ړ`V2)t%gdXYHS-!=(!˚P?ishu9-=aY2!7IϾa;yO[7nSL)03i.rlmʔim-f8y۶ U2PE14^yIc'M!TV(Ąs%+&4 +6MC0tF48r MlF%'&s5 PwFF_9&n5@)oBC W a|6!NM`<   P qk@0hhVz \sM&08Lm¨a˯ V0`/<WQؗf--ԢwKB+@Px D4?,*>q0PY6UԎեd^j XhdQ1EQ!^9%k~/ruU's}!TùP F##2Я ]0b%k%*B0haBFR0Q Ҭ깮*Z"Kt_{,PH1`4 Q"Xߋ,B[*JZ+9D;UZr7X-Re#nP RaVj@_*3Rh*e-^ԓg>;Y F#Orka/Y %RQ5U1Gz9V0``( Pm}.]lİ+Fq+@u"+|NmLo+ȿ 0r?wU|EwI&- ImA@0h@P;ǝpR&žS&LkL;g\Q|F++ǁ&.<),W&$c^ZYm@0hx灸QA'-1S,WdOMʬFVJ/]v`VksPMxi.+\e)ċnH ?xw?j\9s{YbBr>1y7S_x~{Ɂ@¬Ӳ,)He9ʌhq +Yp!62fܩ<LYJLYސ؛pV|g8vN没,tʊ,a2-!+)S-=qb@ W\|178Up@dCS.\ɧC滛PH$Y cq +b<^vylOЍl&&*T ‘U*9Wx ӴL6wlګ;!U5b6"31{~#g4'5%rX)JŪɖew-:lii+Zt4Ѿ#MSߺ5.:_>5 4uEV$1.KjNV=Oyub$@8D 5.b9W8vBbIda¹v~5~eooޔ<0`CEAPHM;S?(_]*RŊV咖r'n^Ãaq0N3/GOjLRLW@V)H^}^yOoKT oIWDRLDUb._ub5\T_۬x,mmMl!Z0Q U| kS eӠ_#wiK PEvoϿG_^]i@ᣧRsg9XKZ*QK%@EnָMLөq격X+6O{\}68 `SR$˪xmcՓUVldnZ&7$ =m$ɜʴR,Z* PT}IYֶKP_` H@.lCd-֬cϵD#i^h*-%}Gq@DEj2YDrbC+тoЬ u塳Mi{z^[@jUckwHҚ)isJ~3_нOon҅r@4KN|MOB~Z[ULn?e¾7Y:$['7?oolj0 ](SUʷcPT-L8^jǛǘo<"v@ Cz}c+zz:h/}|{x귦5gOܒjRemrai31`Ё`qME=ZXZ@-峊=%*ƒ5]_K}Eh#Aċӣ6:ɡE-l]On隬3V*\0yv&@djˮ^ԓg>;Y19bٞzMbSŴ^{{NӳZZ6W X 2D*#=r.Bxך#f۝;6W XĀ kPP`(bXA&@ 3Y, X s޹m`0~Tq G&߾Ke;3Ͷ'VgPKg%%Ο\$9.KU.2 iљYU jޔu0`_ -guVpq' ~_2ӎ?}[:?=Zg?zIyjEo裆"GR eEPJBnش7o}腇^Z}k]O;|+ۇG'ov:ҁ`znjlߋ}WyOgٗ^|1nKss\8%nk\d7Ww>S"9`PykCb٢;.G*<$ח{{+Ĥ|=$Er ]:ϛF3VL'cZsdj\pKU_(_+*oL,™"6/xoQ}׀r >=!_8lE;fm>Bx!{N" L#d{ݵ>#VTc–Ա̙V=sopE >@2K/8}[gyf x fJ7t1[e97!)+_-ٵ%hpK:gQXޒN0qkg??yS'l{mOQh\Zq“^ʮs9V&} 'miȹz﫼__?z_u|'לs'z` d3sSVkqyWDD;s/y~ncwaOoT'nu7ueN9x䧪ܷV;ᙗ>S5Db;3xEp^x+yVGgڗKs7ǥ$g{/oJ@rt}Cz4sRH<,K;+2\^akz/6( K^]&^Rw}M[2e&շ@y{KzyK^oWIdHR[ ^ X~^x屍o66LM}o[Fչb<^vkקjYT~s,؛Ui=-*!^,;t5Hs~o߶[Sv*jCFq?}\̃+O2>߿ܴ͟2O&]8`4 _:??ttnnnxƇ\ap8`4 :wwnG~f: j-qgF X`hjhi_*]mK=LiMoّR̪K\_ 5ReR.j_r+@ ťUMC! +*αA+@臂~-vVQcW:PTp$f-LGb/hXb(`4 б};}F//`y/B|u6sA{^y+c+-ldwMkYx@Ը[ǎϞzk{6cV'滱,+nX~*~[D־bq,쨣C(Ɂx9wE[ guV,UNst#Ϋ[̗_4~6aR8-)AdW+4/+m&ԲeW^"ϜӚleZY?"^MC/W^}q\-wldB<@=<+M{x?v1m$g:` F#`mnnnjlea[8eBR(c=O?evCg6)Fjq[ms?q?, V|HM7{N 2Wdx[ `u`}g2zŮ,+>/İFsg.%E܆F\>Q͖_-nVP'+ʻTYf'\$S2<`@6}k83Wo]BJ_thP'\kkm/oΞ(|߿w$SL6[ IJ`uz5.i;v-/ =`kMĂ_}Ͱ_}9M`}&䣧 0ҁ`c݆-qY@Z6'qV0?MQ +t$w@ +@ +@ +@f͚+,m63g` ;RZ/V0`nlYۄmΠwï|/n[1ӵ՗C +0[yΕ$YQdYN1,>ꨟ603]k_}?@0@z(d*nCl.FV/ckҗC+;Y܆ &qm`26*}i(LsMpVP<O@6=%ZXW'q@\ҵ|/wQd2MzcxܺX` 0-wmKfea^&oabU}q$İ'b㙾֜s׽u/zۜ8mᔃN^9n#PՏѵkr|(ʒ|b1_vGq bVX+ zCNK5W=}Ձ3>iS̔*솞y[s[N~ڱ?(slmA(Zּg.Z6}I\;ӹ/Ϭ8k֗V:@iaxT!c24qbix{j\,bC@v޹ͽaM_}sz.˦HDیY<}U_}s fpgo=V*n+O^۷8)'զz9jjn{-Z8_O|?aYB 9/]*6Jɲe!aMp " XA=ނw2_y=OœWj"Mg-Ͼ}Qyi&IVqD1Mi׺_i}8a%,X׺m\fZr|䯏sUҒ, ԪЬJ)E4ajH,XqVP[][4󺧯UulgyȱV{˃o;r67t2M\$Xq⣸k x緝ywywk[n;nun߶{zG^%jNM*}iɵP yZ ) Ȏ2?kX`~]VgܖZ?陣'$f%Oܺ[깍ϟG=:c3 ? ZUŌhTYdE::6Dq׺a+;6}/wS)Mx8-ϵuΚ17]>Σ/-vPvP ,`m߾]% )̦BJak9Y. ӓ@@ԴPR͖bO3g0_6IR`*}kՃ=M0]#f=rdEqD<Lq׺n Dg"iŝsNx[6n0eω̜'_tf(u%)J_Zr(ظq9svm7Hun ?W}#7Ǟ׼aH_\,bŜB&:kGM6ĄxE-%hW/xan4 6֙M{Oo3DyC=’M=M̶ wޫG+i.VKҗ\;)vRK>c{챇}=vҥg}q:dU;i<N#0K ^&C. C,t0O"ɻ M,_׭ޅRˊcJw];:U{뻺 *.O4ٲz|~͊"-^Lɮrrpݑ$\,bԃXTUv%˳5'\护8Urp'fB_3ƙ]/yoko\wտ-L#+ޏ>f"Ɛs+.,Z>昢UQFIZ_p{qcbVx F⸪6 %%]k\賯߲'>m?ͲԲY'%'oҨ\|B -V/~`N&a &zG}[ҩ46cUUY.WZ/T?@0tz#E7 tnz }irKOժ=i/n{fC k}"/9둇ÏDd׭ڷI0Ԕt4&Z.9W[//cbz[/o͓+Q;-B[+s VlVbzڵ}Μ9m|ߡζm34'ʷj-7X0+^P[*.V8 )\lm;pk+5鸙y(Ih'qأY8>Ү xOpe$_|onMNK+*I~eW_Z~%Dj0-[l޲yٲeӧMokk\g^{ԃ">uw$;fR}<"K=/=s>01iHI])'WAkj_uێկvNjk`FxƩYxXİ Ty'ΛOj9=WU9],Wb1@zND?z߿8㢴'~6O[4iьF2nM='qϙU^v/^esVz(k+I<"0rܳV]tQj[$E^*Ac<ڵJROa3O757~O c^(YV8C8|&ŏO|2ɶ^soo[7sk0s~6|/N [q-GUtK M 3U>ՀqSGKi!ޡ#snQQoM$ȗ rX ?#FDi3X , #}x:z7j0b`,!BW&/ck/L[ۄveq2xwǟ,.nC1ӵ՗C +09oᢋ!m`<2֊}?@0@`ockV0`#V0`q\&w>p̝+ME(}_D\F6d MF cm˜T;;_uťn$R qh:7 rmM#+I.RZE|Ѽ%IENDB`sardana-1.2.0/doc/source/_static/spock_snapshot01.png0000644000234100017500000025321312174204305024134 0ustar cpascualcpascual00000000000000PNG  IHDR ])sBIT|dtEXtSoftwaregnome-screenshot> IDATxw|SUO&MӑЂ>xp "PDž""G H!PFAfY-tЕiZhE |߾΋7{B!B!B!B!B!B!AuG !B!JrK>c(\%I툘vYF!BԎt2vd\/B!B/3{~ݿ4" H/c(6B,ͧdGtA9't{IS^)̻&2Ļz2?QtrjB"rԦi}u#UE/n>w_q{iF@Wׇ> έ;Izj<)kԫT|>\\=+\?AW J '쵘i?kQcS-5&?]mreOcLXBJJֶC\|5{4Zml~MÙ)t[މ?aZf7.ލ/\ÏNդ5I\Ap:+L <\У L#%/B.oA͏6q!'y݅mfWt:XWFTE#ݳ3F#wKzr9L ??!9wZ0'2@n9* !p%'֤k~j !7֭Gwy̤ 2NYWYCjG0[ 4䜕y֛*Lÿ_+Lnl6"^ǜr .MMɈ$ɞO=c1Oǔ{HhΤ4M_ϩvr-q8l`𫅥ui/NE!>H|NϑB"^G]7cZ╵WO;&,#N)# _#B_st|G Bb3il`G)E5Ln#uΌ8@rv>_z?F{p¦P*}3Wnz,و(^w~$܊x 6}ievTYyzHB(x#>7ԏ{g9c[jb|, Y$f i.kߎGI'>a9;J 1_[\k2pzN$*JتW?Ks`p44.gٌ3t~5|׭%VHhSĐyai$m&M-/7O)oOIiEFP?ZR-$S?!ŞLԡF/{a~ 1ѣu l]L!?r8Ech̓M37JYu}5_㳰${fah G m5#;epT!Fh\qYh5W>kQ =1ȑ,'> 9uǛSwTʅOc+~]*Pr s<&EQZ8XuȻn~(o[5j穫J)RQ?[~QbQM^XlP~\EVTƔo}˼~J?o^#~9AZ~IqR˪WUA_/W(#'CI$IruRux4걡cCUS_|úQgk*`  50O= u|7.7N*ꧤ[遅O ̑wZ5Cʼ'*"#я(,TO "Wub_9'ތqfz 0fAկWhf0Wq0H?wJm|SISߤ~-C翨2Rei!q{T',yt~:!pbv͜#N6ѤU!m<<7?KZVL&+;?{qɂԯ`ЎǦJS38ڿԯ~lIuoztCğ' oYOi(,EsߐW`}z U{<0;~s&&2]lƫo6<3WmͰ7'VNƅF!Œw5'mJ)yc',͵0zwj)k Us>\ٕR*F.Zz -S56[T_OSU5i؞)zPXՇG7]nvFW*?w1^QT׫EUe E zC-uA)JTg^hǤj<YQ{Ԃ SԎXS ج95 ?Ew*$\dd5Sjے)WU~ ˿g!uٞ+ܔNk*9oOIXj9h\R"U9jX4>-|^RWGt-y%I$ɉS~s䋚Α'3$XM.87:U+A+Չ]TS+u^neT$I$݌t3yAHmS H=4%6}.#W8!!y@ #, &]?™ݦnyyNLwT?B!D,#B!BBl]zJ4]t;d $e\'6Z#B!@^!B'$B!NHy!B!B!B8! B!pB !B$B! I /B!@^!B'$B!NHy!B!B!B8! B!pB !B$B! I /B!@^!B'$B!N 1wFDX !Z)'wzˊ5PJT!+/6R`w.ϝ^Lw.3P?5Bܦ ]hXkovlDGfx_To߯]B `ĻR+iA0 #%;t$4U#zo:`%)MmX]zúw\(L$xB!n7ϑ7'p&! Rc8~;k)]={nM <ުUi8&2"-wuVpJ~ 9Oʘt7fd nhYI:,{|?N^q@c7>A`w)<5^(|= ~4o5^cyqwG G̡/~K !eČhN&.4XwC>.4f1ץ;P0a{߯ץwf5q@T U3٘Jyd jY;W/Ê.Uiפ:glB$op.ROKO4?Syϵ@ͫ-/vcb{5zSI󟧁Iî01u 72[NC˞`մ_F5ӊ#G죞yvƶRi ?K{e,3 A?5EJIkY3F`H#f3>x-5QmGXFZʻbxOl+qV]4p[0g\V\[XR~Qls6/X5M)bκ"yGGԿ#Dy IDAT-QB!^mKؚOOSxH4nZvͅ4) =J7%'kyZ9$b 24{-NJiٜ@ۀj?#tJ*nlVO&oKIhݞ|ep3 :V ƹs<3w'|ʖ%cgrRgjKK ~49cfL)GX>m6 y@/)H̴%;Њa9t[%){QߒF{3s| WSR'QxG$p[<;ˎ`+JJ~ ʼnd鉜?hfN{HN##='wZo`Dʩ9s4) Nt[ߑ-[_!(BovU=Ѓ΄W ׹GY32I\ƐR !r/OR3k_%2Kqo ^[/7xS zWcznnldu};ْbgc/?5ߴ\{ U&a7(YE%ٿwhGRy7*kEqr~Wq T:Vwaε0SNۊV"^ ona镺gOkM[v$:Nɹl\MHC Wlnx$sRzG˺oY!?~Rw=Կ) {@z2lħYnpŜӮZu|]Mu\-UiҠN*Цq *bLm0GGr(ʍV]Y6E$*HȾS)4oݓ&>^L4oڃ9_/f(zEF"b Jx,`|ʄ_@ћ`չ̺7]^7CGspv7v[ޚ/~͏ҵJOyaz4b"NR#|0@kt~h&3 ^rsDg %%[VMpKheT53sMqwDk'`˥iկϹVnBQ eۉJӏͼAzN3=<Ի7:QXqtVl}O?D_ʪ'I ǖ"^ ]"_3Er~f ~ 4nڒc 9f+cM)>O!<[/ [PGy-osCX7GC-y\bŚYw4Ir#=Sd[2i`_ l2:a+<s'#^}Z! JzY?cX!h+-l R_Ey.aGp6zH\TKR[gPpUq8ȊUKO='c>ˆAj B!J F:Z|j!5zKku8{[-ekK1+BRt"oNwNB;LB! I /B!@^!B'$B!NHy!B!B!B8! B!pB !B$B! I /B!@^!B'$B!NHy!B!B!B8! B!pB !B$B! I /B!@^!B't BbBwFT.T}xG*j7iߛO&+mɥ3P\0};w.S}FM޾4#ΏB! *WJƯ_;[}\6~gYA|~a}V}&23˗y_>|Vtx4|?lB>lCfhn_|O\p/އv72K{n\ Z7OSƒ<[ӭ2\]FۗQB ?cndNA^?&P/ wSbl=9CRLܖ?LW XLTl?zMFỮDn~ۧү&j?1QFƳ/T\0u:tؘӎ ˵ܾ2x?O<͞k0hE:,vпceN<2o*[l_ Nf (tԖkU,Ͻ5HlW~_+J>FMh\ݘۃҹ7QO/[]QJY3q쫀i&,SqJ)TT[o/ksxk RJE}ƨ:MeӴB|ϫ=+T ϫe.*Ԙ˴ H:ajK//տ֜W[9VIך h۾}]jq/+oҮUMai_穚>|ήJW;P5_B=h:?}}_F ?ENzp|jQ󇆶pؾ5ՉDJTV:fB?螳?Nՙ$NI[,UQg(m]T>@W  Q΄w@ CxVq8I6^my{ܫL< Lkm(tt[ȃUܱTFBHΛ{ϸ;{2 +;ʱ&\#RZٌ ~eH;JfwBS_ˈl2K gѧb/z*vMYaw\?Pxu˅=zX0aF5fx~;c˼QGq͗ש~ZO{;NP50,7UN8E-8޾koT"Q*|Zx8_NP>G+btFOU`5믫ʏ)=J_yZw/LB_Y }h#n~9ɬ Fަ&51kR׾5Sn.&]⼺!/K?oWD07U|Y55C/{4Sjժ묾9^h=?u|ZIy yJJMT:tԾƜՎU+ {fc{7Itepѹ ~"6k/*5 tm[GK_<9<5p.TD{ȣDW;{D/S#.:FgZWjIywcelXW94Z">Ldd\Z˜<;nwF{%77t<_: 彃2GOCQ$S=Mti^ۗ۹}3Iqlxol[J4I%}|SobWXK;f,A41c0TxiLu=_L++/z/wir,sሣM?'6DCv=Mmfi>~x҂!q"NUmzlا;R삥jFϞL3Kd`h&3 ^rㅸ|.Ll1 i\>M񥔳XJ\-,<|"~}5M%*5 $_ a~'V뇑5}]&)=W?ߞDd๔wzic(U>GRx6Տ#e]>ǨE)븐YһU;SMS=a37bmoysA.eDY}IvZ}DήE~ #3XRRbX>UhC q+:(Gp<62cx[5SOS-kWjTQt]jU(Kʻ/QSkB!(K2F!BQ( B!pB !B$B! I /B!@^!B'$B!NHy!B!B!B8! B!pB !B$B! I /B!@^!B'$B!NHy!B!B!B8! B!pB !B AĄd-枭A(R Jqk*i(KB!+`t1̎"DHB!5NLј!3W\RrF4GKj+e)۝ԯBqǒ@YTcVߘ#w w@wF_gygP!B%(H>)mZs"QT"VJ'_ Ak8aS(;Echy %1ko sM4gH O GHJK#q-ͨ>#M~>혰<8P*&;WN5[N%d_7cZuCfux3=؂4PDq10kH#<4w[:(o<ϲ^9Dm pq}ؕt|V~k!Iذ"J%Rl 7B!D)~:&?ڎqn|,4_셿@Ois|>#쎷3#ut:ti,^zSMQϢ{n*tjGL"y!)5HSj(@J7DmNtPܯ&7,7Tv]y ^~=*Wu䧚{N\:ogmFB~ ʿ[THfH#js\R^^^?I$I$IuRux5K0t?  p:ڞ*5 Xk4#Y3z|Ixd:FgZoyZqt4G X 'U`ʧBM5KtGv `vR'Gm ]lgJ}_bGGyc/?CrQY>n|2gc]}x^~ JK{ S0rBYovM?'6DC%ui?[:|S?uL9kOb1WuJLyȢOÖ a,B o)~D$Yno9b@Z$W+&6za2&5!\-w:*|:z)|*sW9b }5:;>'Ҿ}n7~\~!B8Iox,]kY1$-}^K>K 1!ͭgsŖxw>?عrx{PpW'[WO׆v~%րv<6UZϱd ߤPo#igߚQ3_oB}|:?剶0 93=I\o %3˰ޡ ^߿%ս )$g:oPSc~ƷiX0l!Fm{1̓]j;ZHU%yĥB ͑~j*RGQ7Tsʷ*ʒ5Hą9WJ)BU-t>)΢;I}b2)mիQS};WVV3ՑU'_c*NQIZ)>^-*nj *M)T:[B{9ҭ?5E[e֩tM5zGu,;**:~$I$I͜#He "x>].ߒiҐ}ZJjB!5K׬M} d&?%D9ҹ5`YBB!(y8Ć蕴>~Ca R!JE~^dQnmsݔ5HĄ k-Ռ҆)G @=qѡU5SEJ;>2gW!EzEWT<=OϳԳ(zbE[HBzdBL}^!yg><;;UvB>~PYjfBT 7~B*vugg_zEZa͉u1zkBƪyPMFSC\hC{Z4RrT}x*&Ȫ,QۘƅCoӋO#]FWOk~<ӥ?Z@5쭽j8e>f7k0h$}_a*HêmWYE_ZuuG_|?˽Z#UH~dܥTwAA~4Inek1}%) UԘTJQoo"Gc|Oȧq?.TGYt^Y@[ 1)AԼ=lUxXm=Dy#*y-GS#jlTmA0֪ߙoQIG?RcQV>G=s ;P9{MGvn[wmꙏSG Վ/Pu~A]^~_=Cz|0{Z8L?w2vMIӋO#yOӥ5S>NS՟NYB@nRSŗHS䋝C6Y-/ܦb=5jy*u-墳)յm_cǟ⢶<a~d`zӢ_3U|߰jyjZMf5+/ԤXC}6tG>5>M9|N\`6{OՑ8-U8yy^r0rG .G #o2C{̀-BSY{@b^30j-9Ho)՝'nZ ͇KڏS`ҩ_>={_C\.^!)<2k6n͂alryO#ݜN<Ӿ|lzQ$^Hv]ŀ=0a l(0~Y2j$lOA\}aɧ|_ ;r->C4Z?z9vVS9qm:<4D*'NRʟ~X|)i@ޙKrq$]mUFd1rU8i5+7xV+>֌i'>Y'?<[c2@Z#ʷmlvU2},?b^$%FslB nvo5_LoOG?fM;uŻp[k&uۅe!v"=KdhW_Kkl^g=۟&/˅`xz@f\t!}Yq[m&ftHt9)̥mkZBF33.+_( L`;xE/ԩJd#ZFnF:Ens닏1+dԞWO?t<,y.@|Պ?si.vt[|ŷ+rÉa< kC/tizZճzjߧ{mmFͪK$}IaQ*UJ)(qS pUj3ܛS"f<ŧ_C}Vu BϑeNR@A5"T>(lZYC)զN/i-A]3WkU=Up((5oG {sUIsT M4?aruBin)݃f~֟M%\1Gz̡Rʝ^w_URnZ"G=-PuZ.U)*RG|L@tk|cR,QJ)L[޼&6ğӢz֛}zןN7@>??ٿbM{%{S`oO]zc6޿nV+W?C˽ES)rԖgxO_yy٧0>|<|r|mt_T~{+wb%DӒӔNwe65x([[j"Ux#g BB.[|Jcϖu 4}*`+>E~%Mp[k&5ݦBFeε$!% o 6_2S8u&7R?vѫMsB!|x'!?H攷BV@W,B!D+$y!B!Z! !B @^!BVHB!BB2B!B! B!hd /B!D+$y!B!Z! !B @^!BVHB!BB2B!B! B!hd /B!D+$y!B!Z! !B ܁\_0.H:I֏\ϚY8}i3cx3}n=mGsGe#p೜}(lG\ג⯥tK/hX6D]&}&lӰ4whT잷K8ֳ{56wi?DۓeXѩ=mćq&}j=/wYkݤm{%j68"Ϲ} E[KƖHu&R_$.8ř z_G9C PCdoz#sl 9eN3X/imiCY [ڇ3#?ql/~i;9[>8hAg~D' r)>VE^`AM/$8g1s|V_y.I(y!'9JzҾtG.'-g<ݓÙzX<7E悇h_KQAآl?>>3a a k?ѵ$3Kh.ؿ?Wqd_ 8X0EC3c@Htb7ˆ}?8ٳaM!7{؈8e ?:Mt˯(1Tgwn}6ʤ*%8pC/-`pڗ#1uü' _O7"IG =Pq . ئR+gg.x9G+{,.9؎0c~ "Gr-^37`?(=Dpd!\'Ff"Gu'71&,1?d"ёW&26,$e1WO@H<|5?sʯ8b;3ľ+PK۴5#nC,򷯭Co;/#D3M.a&bMꍟA/9b KhD^$qesٱbNB Oβ~Ď(>?U;-}?'Qp[|_oӆ(Z p}ǡҧy~Oic"z->#So8}r["8?.E5^ǦיOΥtUыS_m;z'c=\;Jzߢ3а&Ҧ])_,#!8s6k_0ۡIE?WA6,&aYHY-m '?Wk~Rcޣa|X$훥r/ZPPlqzb=JN>ע͆t9[3)c=߹214k(mϣݐ;~U՟։PڏGb靈iwΡ5|` m|޿VH/1?Ā>l=RuBN}GuJ"axJJať!G2&rY>G!{md٨_SۿS27+ܖ0"-}ކxRJ%2?DnC.)hq$ w7@lBr/lߖKF^tK3m#ޕa|^sΧ٣i?r aidzCԺ뛰DGW{N# (l)ܒ㮌j"v;P&1@yĝ`u{2 &R2 LK޶kҋO(N GI[q?w UJ.&xӫx!ՠBtO/Ck?޹2Pܟ'mmP  >JvfI+_tʿԿdIsx- ?.*a|-T.2Jqd.h3v!`9=f7O<w!eA?YGzKo0OhpL<\Z (kh_,F$Ə*G& "X~S((-&?3Bq8O^ř G#`+9F$mzɟx,ׄ$`:_C!W_gdd}Յ6aہC8e8W4V_N|:q( 2*'iƯp+=6(5XnۄɤqҎԫ?Ӌ謯DZK'(+Dd\? He:;ա04 UtKh{?8HƯk/zoG6->wX0tU%PHͫ<_CvlU]T.X`G +Km_hXZce5<7K[_κVw?f܅6^J@ X CPYD 9WNyԐVLt!(XNkjdܝ ZY'.B_f [*Oa}{:3c %xJQ߶^$0L&3xͦ۹puG#LXB;fg!}zZZ[h с}{ᾛst&u["͢e-}68Up]V}g[Bmin۵cË֊e7?> =YA6(=LNp*t>=?ӟCڮ.Ğs?qpH_Kڏ_{H^Nßf(9D)י;V5/:_;_;:/.1}_A8z $N6# )37Njq?']F U'm<@0'ZA]o=C7>}Ʊ \O„WHנ0ϻuĝhp/9;-; I!cՏ^ F:ԩ?Ӊ]_™;e6 G3qAI/_?<ŷk6Co5sxS~w_R[_* d &Wdg+9d.9e@2߾6t*]L;v 2 ϛJtZRrj\*TCj;~6v+^P->UIɿs/+h_ZXb"r}$^n~Q>Js5Eմ4B!uytx``eL35a鼩Q޶q٫VF26bbkn2m|ʹ5lb0V+]L(H8ȳUit 8]*T&޺2kSe݊"sǼ$wmGe._n{ř}{ >;^50E0䮏ؐB)z1p KB!CVw9X<89+]㚨tzݬW7;_Ln3wAhAn6[|žY4:n!6ڿ/oNp_eV<{}L΂ Xb/ ^z!AM]Ԏ)/ޑ[pLb}KpE \5 ?]/ㅴ+X>z6X⪁~9?ue3W}ȒyJ"!!5uA.i1^͝s׏B=)PN(MW.sK8ՄV~FV.8#>3'V[NaX3ͰIV[HEaF)f?N \df T7{>tcn"OMb79˝9%. "4[ʤ+uCpܸnf-aBͯǜ("}\ſDIG)8+s)NEpebHV*,?k4ʨ~dbMKp7v"(Q(n|6=c~P괓c O3ଐNӏ/|Nɿ7:Mfyq*?NCb6o^R`?|’?Օ5n=N%K߿KG!hux]MI!~u7s2Y | ,䧑A K-#HAPm4ktd&$KQTV4*4^|p0UnO#įH[:_;#' yhb<~qQߎX&ދ? h}r'Kl?m X'{{OĠX{:*{K t0w}°qQ<00z;3{| MGф+*Lȿ0:6qid%8b"y{֗MLw-u$ЙQd]'6M%MN?KG!hu+eF\|p+D ,PEF _urM&ͩrpBκnn̴ l1&^m"<J򡋜F?k{+~]ךk$7~us]n-™ s)jL!hc؋N˹릧Y#qּ:{:M{ \8°A}ȊpC>x6ܫoG/-%wr^\PQ oo{_g"ʊ⍗n$xI:^=}sC΅?PU60D}6Fu jMI<ƣ #@-Ysl8V>p 3R](O2ܺqC;Wq,3QN1g'} ~z^f_/Ʈ! phF N,s(~`5&\z~tڬ V6ɞba7mLیN7y4fdŃs,cnghz %<48? /RקaL)+θ?bDt~P'CRxdl>ݾ7uږn=\ :8s8}r4ی_p'ĥG^r02m/i|= ylNM#_Ka2(||X`([8D#y('NRʟ~?N]LNiQf(7=0EPM_Dw6sz7v!MQ&S(SenZ/ԙ*~l!~V+}PX2;Mؒ>-q]1G>[EQ| ?<ɕcsc?_;W&8CGw`z{*="1kؙ-e^5shMIz ٓyIlm}bGYQp쓮ָprc;o=oAbiŏŒݲኳhkg*}oL8Ȥ'@#b$WBk͜^]?B!Dk3)-U$NSLv:v )Ts8 a&XzR"'O&#N̑LhXoNSͮ΂L +h&Mn.ddd-#7#"7 ù\NxY&w]6P+ \nx-`ևs~pV#奧 uӃm̧n'yl>~{2sjOrY-br}Iⷴ~#_ ]l|Uܬɑ}aeP8Pf׳N(3e [lxEpnޅ'~u뽛Wmp_ְ4vmݛ.a4ݶ^IVT=k/_N*;YsbPLrxYS Pg.dr<=9p/o[x|:6IUſ7~,*Xǻ+_aQ+؏aهmԍ|3^`Ɂhk\Yv4ėհ,1N/Ooe^å^Gy'.OR02{7w[?FB!|S<+КҲ6BnYR}YW!B4UKҭy>g:O>j?ہyZrcxL+B!Nk-s ҙiт՘rq*~!B ظ73q?d2Ֆs'0 -s /gEkZ>}G!Ƶa6A=4 |ۍ1l\N0G~B!-QVqDbb6[0-V,+&֚V>4`3) !BRhծ+NҴSޣiZԚ0+__΢ٳZK`oN3>)LOB!h2g@3Zc93}V?2ɥ]"!BJ@S y:Ul3֘ 4:zCl_. ⩖KIKg-hAFN-^B!8#rXbe?&ֹUMftLwe$H ,hj&L&۴3!Bg5v .Gʼ,p]\[9)x#e&b'?ќkY9 jEfa;SXyԯ;]$݃#x/p5 7L":ѹ =ٵ| $י8;^S쇵]5Y܋diN[Hat *0oS (%},~>zurqrH>|w)~ho S_ӯz[_ ->BX+>WC8N{BǔO3^~o_!g$q>30/?y{t(_Zo>N.R>'3](n/<{>xTY3Rr(>\aDSA2g¯}sA7}M&2jl_哛LI͟_uu;8y=y3 ͤ~g`;4̔KC~mV~֦dU(y;# ?m ۯ^BqfQ'ൊ9Nc`ߏQiȅki%dLv9 A'~m Ū"@` &() bK(rpߐOWԟMjJ\\}UK7j`t@bw{qZKC~MAWO?k#,_ZW_B!8chx|͓񚦝xM@b&I` #&eO8~g3r$ɬ:6+ʁ;ٷ]F%+/5|@LhDO(J |'N'``TJuZdkg9) $ %qĮ#%-<}CKktݝOAoホM|'^~:B!ę||Y1<]ͱW1nB{8S d 1\qSl$2>s.09:m$ ŏ7~Lٶ6JDhp"2*%s,KсB{M (`gztnvbpnf6vQYDtrfkqL͆P^u+B! |8#_~gxͭD ܇o'/ȯ*Eь|r #>t3,%I {zHi;}g2huc1m'\R|o{~r||fʪ8^%v,:Z*m,۷wΘyzʀ^_ I:=&tj7%+Ix)FYT_UL^Bb߇OO|Z Ť|z+0ǽά,c-[|- QKB!ęF)U1͆zO{f yB!UKҭy,xTydŨ[4 rspUucL:lYIӧvSTg;PҰӾB!'9q93> e /B!D#Sډ9Us}<-c\:[zoaSMUMwO}|Uۨ-}4ZܧC6ImQfWqƳvW>yH-g{9r!g~L5uꋡ@^ Iwp 6;ٺ]6mMof#. cr.~-{qW7NWUdEK Ҏd2oǃFUhP⳥OK/||ƮٿLT1Gz>{{4&О=nF;FMGL m_ oz/KwK+8q)Nw块~bK:kL-(OsI8Ա|? vf/ҋt@mIu!~iWcc <įipnN~jSô˚^&.;K&VDZ]HKʘ3i$ Qd.&,k(=,1hW'&}La!'x>mUY !Y~wsTw3O{y0)4ro;W''+7w7үiu&NW0o!G=Ɣ+a|h9xIkWcL竍!N{BǔO3^~o떿^UQ~k<ݮ? ~tJ~a1ĸkU~kQk־}g8`n۝2,mi דW15SP% wOK_^h|oéTK#:_#Կ{__ {d $06@ɖAhePm 9aw&犧Wr=f[7 8ĺ?!5mlUK*( >#%CÈUh;8y=yP*UV/kK!ϞGO9cjf,f8_4៽<Ñ:(=l_7 nW|A7}M&2r*F:ѥ*MK8iy7zQv|G%DjMGOց hӛFyQb; 죤1f_=~GԢj&_Zohv ,BhƩx1]δew>C.߄)wK)dWW`+!dI:k[(֓ po8Zz1{Sp(]Ughb^ ?,c;o`W>y^Gi~H$" E5~g3r$ɬ:6+X5f IjIWߦװv&a\4e(Sn&v?q_gB#qQ % ]Lq PI'R؞wSыi_ki?о}pn&kI0<`'`:NNbb8z}C4rmڟka:Ǿ{kMPdӏE W!RoCx 2L0"/'xdم{^,NJLО6# IDATN렴EɴW ~$Ic?ROH a*>Dꮝ%x]mk3HD .:rSl$2QYDDT&pl e_{I/Wj/D5~,"+;-'A_]4}BVFľnɣmkY2*#ѷr_4vPqah{*PFj P xOIYe BWlBԍBxMC<$ԋ!o+?QJjk亜O|漟QeƜ@Nv|Oj3,%I {zH =ց#̽`Ӯ|*zleCRx aMIJ>CJ(&|o{~r||fNEь|r #nb߇OO|Z ]Ť|z+0ǽά,c-[|-FO%FKof?LqSÇP*alߞlFJs,:擲m?ldR)X<^%v,:Zr4rP% WWT2~ah{,TK#?kk{)m?nwqSĎE3R9"+[!Z5yъG_0kgB7s~nA73ݪ <}<}`2Y@0U5ܜs \.ej?ہ-J!љې8iq2gtB!h.UWe /+Bf qIӍ`3Z#B!DhG@^!B&P ޷}--,-@K駹liG 2rjķB!Dx݇{] 1},fi,L:+=m{7!zfg "8ęDŽ OB!>*G|瑭+ݺۀä=Lɤ{u@@_2O"Yp~>@ G8e6ŇrSl|tLӡg]HKʘ3i$ AW;O-O+n$Ưb_wIGs_>k2nD)Ffa;S$vLՕ/ݷ6y|EIfr Fȭ^%, *x FXtwW`|yrhW AD]_ /#E/)!}{(z@&x6>ٓ3D [A"i9tU+JyoktW#wIAGEJ; 3cٿ' _s쭬3 dE=1ŭ!5+sl`jA.ulw%o)wfLMhd'wđd )=M;fqIK_Z);~&:03%S>I;9ּaQȨar|(b*B-|j4SUR~OAA `V@q`x-MԊPef@GȶưTL7v>PWq)ïO?ދ%as&ـ~fXE֖Ѽۼ [ʰۇe,ie'6$#+bv;Cy4k=g\;b>;>ԔOsDk儳 "uW}OAA}I򚓋^KNӵ[GB|1xڢm 8][1@Y2dtYPN5F(z  2?+SM†Y;  n@kE_pvH ) ^H$  \ܵ3v46զAAAH /  Dih_T84) U@]ZTrWF:>}S~եAAjyƻzA'P6t٫sAA@qxu@|Zf qе3Fr*v/գ ,w8R@e_4[TܫCH`' p P+* M9 e遼.mKnoɁχ2wq,6(OqWc HQQ0`0(Ӿ  byGhisqr,H?I/I D]HtH88gKV#@ ^W76BM2-fo'`dh6ߪ!^GnMi3 zlv͟˹ɲEdư:Ž0RߞIi4ᕐE&u1Z8>mzbJ±G/3B|1R,~}\_l6>w?- +Y'ײ{l'yz?ǟ{h6fK֞PV1lgoYCH]>AAv+Pk;bkT(A]p@s5уQ3? 39\nH!R\enIXMLk&֢ƙ)ۇ/# GO׫9_dgu1kJ^u7` $Ӫl!踎}`5IcH2QZIS!jI!a^cQx_ოɡ])@u}1G& 7i团9n`dOfψ5z>/okQ3WVo+cNѭ_ӻ~%SAjWf? >o2?"-dSdF*]̅Vv|/dyl# TbԬTm9mԱߕ@꾥|:E 05Y3-矜G݂ph67&>2 us'.=|Zжkd @̔N&yOXFE‹tkhF hy#OZ6N嚧~կ_[S WzeR~OAA'O)cҸ"Vg):мn4ƥ2sYX%~&ӓ:0tҳJL`6Ж~Sѯxa ?~>dXQk9\wkR'P0lşS".f &ȿ/خGv4mӃ&5!}!̶[ruop";j񹣈]z % PWNWQJ]>AA2`/.57ظƁ՟Vٷ(?6S+&BMߗ}=No"ÆS]2߄k>ԕXӸקb9l?M @"kh_mC-eCDzK42bRH1da<F{d3I.1Î jJD粒sPw"rky_:>܍ڧ  : ω.}ot֑ _ ^ho{b)/撓i!c Yvo: ۻh2S;@C (G͹}#BGS˕8椂GN€ͱ*čQx]7jۅ[ >M4oqr⿟ʮie?]}-~/rkP9+~QթFg 7s?{3P8a_Wk𨳣O/i_Ñ;_6>"oKoCxd'>x~~]u[UR\1ر|yb˧#.ܧ1u4}'rh};iw?G`Gn>=p}2o1~zG-Ft:hi=(ÄW9Qvtm;࿳7ӣΕr8{;{;п9W>w 5XțӢ 8CɱX $[$qKg !4;^nn *u7{Lb*@ ^W76BM2-fo'19ܓEöx7X] 4>O&uJɵ^IO䝈d;=Y1ߪ!^}Sc =]"yg,r.gIp#nXQ}J`gGNs}l_YY2ycg9n>t$y/BӸx^?@FwpXR_ڈ1v,]GZfKqCDM+8?Nil{=w~TtDP/ =}S>Tg8s;rǻ3hyIMYKNQF M^K_+1Ń)^[ɰ$~?r<'OL}\WzGUgZӾg Q]K;ÙsDHDb fjEOc= MOu}]8fnIXMLk&cq5KHZE=GFLQ7Mm|0'gaJ=s?Z83Yce[GO׫9_dgu1kJ^u7@/,=>"SFxSE?ӏjqq9n]0w|'{ק~ms$eޞLäHp@5hh,fn癙O4k]my;_@Y0nq)jS7Fji5pÿ\X,, ]ѿxts_Yzn;՘w*XdLTz S_$@2\G˿ʐg3c 6nkc˼o9M=CNf9IA汍\h؃S dSdF*_̎,ՌxGh% l6'h֐ʹ q6JSW`jA.ulە@꾥|:E 05Y3-矜GnWFexpK zrBχ7ܡ&gcng/5هG~a|0P_"Lx}1boc$C 3@}= w{ZmYqhlCp@n`;| [ҏsd꿮w{l2 W\ѿxts_Y8zUq}wΖrW)Z*^ie ),a!ͻ o F3h\*3$R# yv&ӓ:0J42  `ɺg7|8Q5 HQ.=^ `o6/ $$3NJ"r]<{_-*ؾ05ǝxGi 7G{ضl+9V2~ř;_np''lI*\wF=EKYrL{پz7Y9VWtk|3L?rə@~)땯*&ԃPEPq(Վ&r)?Ox45N/?u/?t7wlܝM-qⅮE8x-MԊP4.^PB!D0o@GȶưTL7.jF>;>ԔOsDk*4.e{{ă9l?M \AnQ4[ll0]^+hRWmr}WPްcs?OJӖC*jF,6r~)N èbB٦ܟNjiN'Cp;Zr:۹~Y5"NxȎ}85;M;v#DtN>^^f;nV~znTjl IDAT n|mTe矓z8{靟f-jbE+\Sz۝~_kb &E{<HI?ȎFt:AfZipَ6dZCm\-_n5!O@~A5,PBCMvҿ`@[n+&>u 4rrh.М7"}4*r}=u_A O!{z÷{#ׄ;:ʘl;@1XʜO@ە;oEþQݵsL* Gyf4-v4~H>hs֣wD]NZ)؁6\߻-suGaq~iW>W-h%eԿYshW*unl1(Sm/$ A]׮>^%cX|Gp/r|? 6_3gY9)*پ7'|YZ9)vo^''KΦvDn`->Mۼhɇŏ1?YzϰC~-|U99qM~վyrM>l&} +٧׳iT. w7cP{`ozNE]_3In OnF^8]9:o/r݃2pf29_-heKt6򀿾*tʯG6nA~oFh@R}ֹ3Iʰ\I|:s xޝ&H2Yģb+2m1?{Sk'jʽ{]%.pXE~z[aԍdwϲ|Yz=ugqN%A4!dG7'i;r~ vQh:jFQ|GpE t7vw>i'N98{[;ΗB7s   lKΛEvm11iZ4R(bǪ,("!1>][1@Y2d_e  P(:״  AA('{ʁ  p5q&Y  +yC=Zkp4i!7iGAz <S,ٞJ@4>3.a)TʶfAKϯS]` *:X`?yvjJF(Oi?WۡrB2n&Ne=ϼg{Rh75ϫI*HW^MmxB.+C%ʬ=*2O~̴:"P+Y*VoU]M|~G!_Ty}y nL-/.ǨU֪F/Tg:?na߫RRJߏW]kܮKR}󿪻Jѷ(S綨1ˎ#Ǫuǫf5/Z ՆU GM4e:5aMT{{IVүR"VO?gV+7QJeKMzI)V|AanM^f(T:ӋP6HUJ$_7Z-50MwE2kI']%*/ڧ qsURa5}jo?++bնjMlzWjՂ/3Բo~7MMJJ86U N7h 4jF<@&9GG`s/+PQgӄvhUEG-$$/'೧sejpD亇d ;άu|Tp/oI泹&>{v*Xv?Q~Y뻓}XxDOgȁܾeϬu|0' j~ jW%ܴ6'w{16xO1\ U@_>$?ڳ">6p*Qj{rrdV`<_{y,;cbx~|Va)}h6|K>^8^Z?8UҧOnqZ< L4gF ⤭`Xx;# S8wٽl+舔RXs8t"?ͭ#b9g?ޯ?e4.8U~)< ſ5H n؉a3Cx~Dy#e(^$7?eQw,v>CɈ9_st͑ ʃ+{1s#!) )K8{5TWQuONb5Iӈ(#h1]it_`c1yINзneK*3h\U: p4aȇ~Cf=KQ 94Ry[v| m#\G"B<ȧrMs 2ݧ'M 5yM mm`GQRήf{L "'3CiתSfbU)5ۘn8%uFDMsx/Fjem}$KZf6m(..Z ]r"J;ϑky8Xtjf助m~Tǂ,zkδͻ&m1i} .CzTI;k78q(< q&ܮ5Zl#+z;̒M[|)Mf J? s߬So?J0|jwbOzH ڭ9zуna/1 .~^^mG _t"Lyn粎ۙ(^|~:7͑߉᯼@ Zo} ^8)&=GiaQG%L{3CM5h}o[+Pݣ_}'Y4}'lU)vf9FP^l֋\!OPɹ*]}v5)ʬ{R'K2wx_ԡZSⳆZꮯlBoT/دҔRJ]R,|]9*s O9w5:?/IHzSdPIǷԽT,.en _5=6~isՇTA,)O^<$I:]k,_XZ6vZ+/Պ3Բ*k )@   LYiilk̬V,V VJB)b}pc}, e; AAF/lg.zT^7_}+7R?E, 'Z-6L2[ nBHx߳p%U6( UʧCFAAS8+   \5 Ur AA*0^yAAApꊙ3[kw oS΂Rz\jToUGs/{pwW}͇^vlEܔdp?CHWĩlglOj h5I?l%!(+ZCghr>_ n??駫N#ywsu@?S:?Ĭ:J$~o`r(_* 4ЊG욆UJx#fs~|9(@@ q|5F}Ͻ@߂#Y}V6ܭ޼ro2b_|}e$Y`$t7aЗq ۏ¾۾`#x>m&dݿik")&>#rAˉd ]I~w a ɗX^(p&M%xۓWc5nYhPWNA ^nyB5>V$U}cԪ TLp%(׵_k KTtT-jLcպU3smuw\Zxiݭ 'g*>7HGo]]~k~I^\߁|O/ڧ qsURa5}jo?+m+cնjO_5_?P˾\:o>epXmA@o3h;"۔^xTA+)sAozз^D_p~o0QqF--b?:P0K4ADe)ȶ}6k:Vnߋ}X*5G_fEB\ۯ~Ij]yi(ׇm& z kfN~F9'Fi(WMM&`~qJ{!,-ӎ ӟX22W}q Ͻn_8ےÅO ♵.W^6y]4/~ jDz/wh15~Cۇ q}gK_W_N"ߍw#%r-\:ϼ;~s:W'b=sX3K#d村ٝ F0|sRȴzJ^D_p~/mV><>A" :'hH&qs]1ϐm>z%ţpDz $._i#;{;UGb]{ wJ;M|k6H? M07oXc qT9p~-3m.e`~LZקL3u4nnzeH#oؒFn~.i zn?t\ Yd2T+?o?Uj$pe=~BJ)TYbWc?v5ճC>j6FM߯.lZοEM%5 Ru۩U׫g(RF/W}Eժ2M*qD`mkݣԁT~R_UřzˡŮ:nzۨW\R{?y@un *~'u{TU@|T],_XU~R~FiZ`Zjw[I ?3WH*&oW65Nu 1x^{g}![F}zUz;_U̍I;*ڹMȬ|I< WƪUjݢXy{@   LYiM3`0SAF%U|k>VBB)b}pc}, e; ȮsAA*m+J!   TA$AAGk*8H/   \TSl$AAwW AA&hvU AAMhL{w *PJ*b=PCO?CݞsRPz:qV޾ݭ}|CHWĩl5r3ٞ2vt գ3 |wn??Em_~ˬSqދΙ<[s"ntr@_Ԡ?Ώ'1*GQCXn4Y}TAHY_$'FgB_ GU..ЯZowg_'PA_Rw<&o? n9Dpq5khhZt38Y?=BWO53i?%eկ#SqV޼ro2b_|}e$Y`$իVLXeԖ  j۪X'~7jO_?~?]-7MMJJ86U N7h 4jw܇oSz?-PEl^iAߪs[?=:>LҴO4)4o@k~erҾr~*3`Fx%Z[~*bX$mu x楡\3 /To.WdIb#ĜEr|1aKFYP啍OϾN~V4>8nu~NTUUpf>㨥KON"ߍw#%r-\:ϼ;~s:oB J5 9 0Bn9`7'L~n'hH&qs]1ϐf)~1E^.12b<]Ӹ~4& 7oѼ'yO%U#0Ry[v| ۭHF+Km|pDW\ًs!E`+ө{:SDw )<5B:Eyr-G<[U@swg?EmLu~|憷^˾Rkê1TIԏ_Lۼimbض֧`u Oeߚk78q(4GQ?~m}$KZf6_)~\+_h–\є%C ~~~Lv~E۴ɶlng/^b@T]ێfD"?}̸:0،)Y1!Uil m m߉<_~S?1g ?γC4/5bE?s(]?6L IDATE~rۙ(^|~:7͑߉᯼@t< ; o@ٵ&8FR%.?3WH*&oWUNfT~|K:  : >.M}B_UT tحB˪_ }5?49Cb2CjT^sjRNuU;bGtMwhךm+U?U?uQ~FYZL|~v7 9.  BlKΛEvm11h4hm2LF%P`ZZ,[Q 'NsCܵ d)Y@LAAf+ $AASͮ*"   \5\  P@^AA܀m*W%k4ۮh#   \- 7t  ՠx+_}y͏&wNp>_"~~,~= ,(?uWjWwWr/揳BY]G4Z e[IH}.*>|8 {gwqbO_S:?Ĭ*@!13y30 U)uʯg["@2O*9l?$=BWO53i?%Vrt3~l?Ǘ" YWCa͚Vc /ʆӱ_z^u>}Mi^|L`ɺ׸EfSMI}F9z'webO_S+&,Ð32y0fo3A!YhpR&Z>^_ڽP9GO*6t]vxh>MoĿߐygO]RϚɅ_j!{7l0ᛓB\(DswWvS Ä)7e]?x}$K"+?GWḉ,P /^:zE2b\]"ls#^̜_s z}ռ-x/5; ec xTqN/[-C:`Ö4rsIKp+5opPi\K_sоVߢc8N?A\7]@Y@vZ?+/]QO~^_y=WO&E+Ac*Re,f]ݮ/Փ^𯯨ZRfI7\ V U\w/u4Q칤~ PyU@N/ֵnW3~\=;j꣌^f^j– 8NMi?Q>P k?g3yZI=];yuBuB'zZ7W[Z+b[G _ԁcYy+srD?C\#٪Rʚ]}dWUAFIWV jQ@nʲ_dw}cmu߫IDqk;;TbwfsϪ T1 O5~N}XmI9VxJU5?_jfW}*-߶2Vů+_&vS}o qAAA`C\ZDu&v,ڴk_T0hK(ebbcZ瑐p{-}` ,HyAAAp7cNN[^+2m^yAAAJh "   ;Cn^#   \ _Vo'@^AA   bJjTK /  n_U Py͇^v^sfqSCPaB!g.yYcX ^oVVo+֯,[<!+fmT3{'hʤnLU|pn|8G;'?8_Ps{t.0L8p~;⟧qJkgjПWǓUpnV"_CPQ.+I{˽Ɉ}~MBv3gɂ4򴃕];H}i4x/zPq~ܬih5l[?_\wqQU3rUW3I zG9feYߟoGMˎh0#~SDuNxQ2ta0yz^>k(oK@0 [V=S1Ź?7}CR'*wt?QjZme_ eQcivO)x%%_FǤPQ4 R8?VIŽ5xKbێ lS(MGJJSZ;Zb(xEHyOM99ӯc$gR`fV?[Vj"Q9tt޿E'trPVjelû7Pڎx6i5/CyHFx^oL΃0alKOP?tE>Romdčc)8ܜkk GgMCzRg̊-Exxך΃йmOD.B=|{v;q_ov8DNgu8[s4ֿ9GK,&댎>{,L Ocp(EeMlô$gf|'SP6$K\Z gG] E\bTB#22&XuQ T}"cEW !#sOExg/(jH|\O<FN*:vkk-&+cմ8xe"?T9{-U]7 IȹrՆjܾb;pZohd Zqt|}(;X7N_JhL?Y9nV]Tƒqi(7:;pcdl5~;8sL 3&R7#Xl8[J\?L Qz%x"+FEM5J.ce|䇿mllQA+ gy'|52KT:~FMfh쥿]Ώfƿ4"6b@@x0._%@ߌ`B3oDc%~;/?Xcuv@ qJ " U>"x0%T~6h[.J['#P[{Y;ùv"=v. >Nau/F*-_nc|^/Ө~D9 Fi1l)_?uyv=]j W]pLC_ \T4bݹˎc/0hZ+gq?=K+7|%Xf*ľPnpDsǺqh y<q|`d\Wa/ZW硘b.68 }s=rG#d||WԄI7dc|Vm=?z2.Hao|_пGx~; ײ-?RZ\5FΤuP b }ΏOf~2zfz"ȨϥMLF?(J#""3O3Ņ^h,/xPŔ|:Uו}m5UVyP7u/ӉиB"an5T_c_R۪YɦrG&֬5%ƿ;E"qB RQ?3}jMw:IK$oúڧּ֘@ 0 0 X +5C* L@EYF RD{ ?ƳPL>Wtݥ5 0 0 P7Ip"0 0 0Naa`z]j V\' 0 0 DaaaZNaa%L?ڞs"0 0 0-Tc 'uOEm ~2 |or@D):ͣ:l[]ͯV?EۏNviXzoxV/EA./á㷚6V_?=' &3]. O!uiEy)ll_L?̝T#Ѷ\W#DtT3t]yi1ܿJL+Ĭ~rt)3X?:I@Yz;3V0A= %Wj~65/o~t^ Z.'ND+tڨ`̟ѽ*5|ힳǛ9CP#M߀HR$V^!X|/ߴKٌ¥ jGbia46ġJL&a\%$z3—L'QW(JBw~{GRo}ičc)8Z>VgROQz^]Zp"mI?~1_F:-o_wAp6% ԜkA쭿~fe:#;C)S½;{::J@[տ hN䕁.H?ۯNâ~2-|1PſP `(+F-.= 'Oz,}J5|za(WH<~1쮿b⑾=VMK@~ Uy! k#Nbڟą"M_,^go`o&Ms6 ո}%I/wY0΅J6Cǡ ƴKeimg,*7ˁX2q1NW6Vu,eX?ې~ OIr5(I<~1쨿G%g*G woxgbx(D7!~ӯ1VĄ0PF+ Wo PfeV/H`&⺉[!ƺKvaP* ~8|%|L/v {0*de&b~-`EVU7a-ǏY,ۉAtǛ]Pj"1X| #E{ͮ&śZ=cRIy+M}ƟJ-J.S+HX%oVEiDDd͘~+(hR_RUy(*C~&?_<(O-\4oxsyZg =Ր\F[?8 V_lN7Wį9ԽhtWGRʔߏ C=U"gnll-h ov=v`nHBGnD:{\Oolͮ0':!"k̇H'F""2siӻa-@R"zg oGg_G>J'kj]Wױ#.~-m[=4h5r&KJ5׾G~ 㷦|k_ZOo.uQH#UUP]D?ZHQAj6L]W6=0 0 0JMDp%% $42 2 ATh4``` .#jkT6|e uVf@뮑gaaV ' 0 0 h6<0 0 ôB8gaa@Y.p"0 0 0-g8gaa!Y ̥3 0 0h}^꺉WҨX\+d>&\7PStcuG]ӰUǵ46rQxvSH]:xď]^Úo5ggfb7/J5 p1GڲiXzox48OEm$t٤k[ڿOb~ʺ-A+02DI:Fy u请arv`ab@xh<4&mfO@.Vcn0L xBz-%,3e0ܔ $ 9A X>~ YaoAR÷[9 w@ي{Oeu}cj.yG<>M8=V$VӘc1?:NѦaVz̶ߊ[0z}*f|B8uF hB0e . JHf~{Gp{BE(H!6H쩟+ԯ ~1G'{6,C[Mh_~B@w+SџRR.M3kbo']ϦNgP7$JM<_< eI('m7'ST~7H7Rt`Z6K_< (+5"! J׾"1[g,E~|jHicI?GJMнF8Cya X?ې~2;„|.?UigQX,0{`"s IDATcE|z"w2TK}t"mAr<6r%6|S|Us 쭿g'-y8MA֚auG-)hAg0"f@X82bɵQW@hB>B5кȳgRѯ~- 7/damIL󗸠ri݆;Ҡ[Ly ּ7 ^76"o͝?{3 nņ%3xwEߌ |C waQ_y~>&7rˇqMHM?c%~;/?XcmdhcBF`QDJ/>+/xcO뿱4E| z`䠶6-)مCDOo8ډ_XVY aI#4~ͮӚݫ(KM G _ #/A1JDL*/oV%ASibJ~ɝJ(s3c-9vz?z um!u q+rxW{P [h8=.m_i4OͧvMOAAPͥzZ"CݝWx5c&ƯJ";x=GX7F~ y<"P>!4Z,B'{$ov\#uY$td>D:7QK #od3k"Dϒ_Rș.*nBkߣp?#Vɦ VXzo"N+#v3d~4íttX oyִƿ̃ze\_;>q=?ւ֒kJfgaaY B -@Ey9F#j`0`[K55|*F2@:+3\3 0 0LK!n(DaaaZ!3 0 0L+yaaidI)5>Naa‰<0 0 ôB8gaay=b(S4|7<=V ۄjN`cx[Bս>$Y?3]^Úo5ggY(O$nR>u;?KOTݧ"6 :l }M0~ oq}U#Ѷ\U\EζQUo SKT^qؗ7t?:/{BrG?C'>ø Hсx hLJcK;wKa{Kh%-@Lmt{ YaoAR÷[9 w} dq|K 9%=Tpa,^opџRR._f~{G6d~L eO  e~R{u9sXa_ eφ>B@GLߟG~sZ)|Tuq@зƿg$gR`f 76[Vj"Q9o(N:~PG9i)P Nm$ؽwҷI_R9T\GY`4 @OAxPymOD.B=|{;q_ob5buE>Ro2ƱwnnN5ن-~7"?{>}M/bPtV \at0u9j<T<FdTaDGFObxjN7[s~oY.Pʔp4Ξ[f< lj5I9frO5W!䥆B兀p<\c2B\?G>=|hzx)3e ;V{>{V czzM#Vyj(c'۴4/oH"]đ𣿠G53wBeW 0Bpecxj @Ѱ""tX 9?`b|tRo$"">6F2 (<zu&\7PStcuG]ӰUhTn&OSv@ - Zty1kԶY>}d  t([[R>up|W1mՊ:*"gG訲E5aVׄOl|{51#WL+`JCg(qDø Hсx hLJcK;WGޣ^x~1K1ʻ1$ 6?iƬ-Yb9 :#Vosx =`!(}]|oD$g`ΉRÜKٌ¥ jGbia46ġsy[ӯ Ol| "cE2 ^o&Q[Z2XZ5OљbQh_LBE(Hx%nOjkJ7Oo _3D]$:,CmWCY}ie_4g$gR`=ټ(Z֝#_66'XVj"Q9o(N:~PG9i:IOS辭H)}z:m-}e5/CyHFx^o{f/C]c|54ϭ+}to##nKA~!P[m8Z?{1[-'0"?{>}f'9_>)q6诀gT<FdTa,[3:bx;2%;<á5}v7߄iפE⳪рy O1ჽzNÌ~2-|1PſP `(+F-<,ن[: SШ *`D>vqpӍOX{ 66] #}E{|ׯ6T,8iѢf}! 9WnPWrQL}gҿ1 [?>96_yTtC4PcUc5f3f|@i,+yprk2m8Z?O{gɣ0a=Ty ּ7w.^y9;᫑Xrb}(;X7bkUbu|U ]#߅75ҿ1d"+b_/gyC]ecWq"_\/v {0*de%MX XjEv-!sx JQ]S҂c8S=5!b;{φ "iks d\fWS]4qciָ~rI%4*?h*m\Lɯt bYW]fWׄmf*}/uRBEfKݮIF }3Sy2 9S~i5~@VCrNoD7(X LSgn_=H)S?˪3TzzT5E+ /_3w3:7:)kɛ]aIAvZ!y)Kk41d>D:7QK #obo f~{>S=oAbST]}m5듐OJm߬vdD-uIRP(OѼ㣁ΣhG*"qB R;_{[F ǧ-=ccs5~8߽ɦD[P6=0 0 0JMDp%%Wh( %AL2A2  F wa0`0ťKW55|*F2@:+3\3 0 0L+yaaip"0 0 0-` <0 0 ô$fxjzbω<0 0 ôB8gaaV' 0 0 qD^1mՊWHW\EζQZ|0Mȹn6K&`~^QH!ע ϒ_+Ms46rQxWUx ^Gp1Gm*Ӱ)۱EA./á㷚ڶU_?='L\F7'KH|R&mWjwbyo5#" z .e3 bdw/jxv؜<XFT?9:ۀZ$ͬT|= ȝ䱃~t&G!Jϒgj.y@I:Fy7F-C`>.>pSj7`"3oD)M8=VVlF=c0U-l;D>OX[Q_"a,^op󌤽L^,@R61vE<ڗ{~BE(H!6Hvԯ]ZR?Q-t-o to~_(ۏz2vyR0{ߠō$ok͌Q*}b7-+5 (~~7}`'?ݔs(NNRVjeD;mkۤ/)~*.ȣD0' ~<(]|Y.Pʔp4Ξ[%~ƮGJMнBF8C͉X?~at0uݩc(\[`,E~|j]!S LX8Qz^E+_/YΖ7p5ԧmj|)4ֿD_|f5sf|'ao&Ms6 ո}%I/wJ1H uw &q#TʊQn <됱~6!)Tx).QШ *`D>vqp'Ȇ*ܼ'1_O<FN*:vkk-&+cմ}ݘ>z}MLY>$2~"֋@4gOC aW1 vW@ߐG#7.*Oc8] ۴[ ?2Y?~X:CUIw1yB&@X:WZm|;#@V |_C6ӂQA+ gy'|52KTw6}5'sҿ?EƯH2>3L=kC<&dǰq{j BP'+crg~|+{k 'xcO뿱̚pFAY+Jw_~y}"Tvjݞ`v_>v {0*de0E>VYkB|-S{keT_>3"н+;_w]սhtWGRʔߏ C=UQ&cRIy+M}ƟJ-J.S+H%oVEiDDd͘~kh}Ӛݫ(KM G _ #/i5~@VCrNoD7(XI(K=|I-WWΫTs Z@E oWD_?n6o21}ƯH|fY57=NJ~SwFJ۹loͮ0k$;Ej.w- ck &̇H'F""2siӻa$5YJDLqAvZ!yOuY_3i]/TR7׾G~:~4ítJǾ0U֓M;zXGL_kbbZlRL Pm{aaa,KJ@P(J 2Y FFC j 50 0ޭˈ~>g#_@y|PkaaEF>7Naa‰<0 0 ô$z' 0 0 DaaaZ!3 0 0@տlݕyaait"/ ClRI "T ;;ց~2 |or@D):ң تWҨoh OE1 IDATm{ݯG- Zty1kԵY>}d[Q^T?SuGrpn":쥠mؤ&3]. ֶR>V߀ƷX&9=dGa'WNeaT{Fssq@(O6 eGCだ1 h3+_}R50A= %Wj8Z?+VӘc1?|_QԆAw `Q?+ 30{;hUj{ =ga7_ ,R6#p)FvZgXZ)q\V`!(}]|oD$g`Ήߴ.s[:MMS28`28DTiN#'q%$z[]ϦJ[82AݔQ&[g=^Dɣ}IQ1)T=hMaG(fW?hR%o _3D]L3_,CmWL?K"<](Zb?Gmkyhb~6D*.ȣso؁]t]t;'S:w e$)mz:m-}%/CyHFx^'Ky:kZ>V~>]웸7 tskX[#nM8Z?/c#Wb'1e|{,L Ocp(ei2;„|.?EƷ+0{`"3w]0 n"_@]>᝽"s nuG] E\bTBZFلCX{ :o0L!@ 2<1Dp/ew5jZMA[6go&Ms6 ո}%I/waw8ҿ~ 7/damIL`F*< |a|1?<8{wbތcl k*quL<~0?^+D'b#rܬr<%t% onU7PγeM8Z?[Wc%X2I>w1yB&@/;/h z,FFbə&o)1a: >*Ԯ UtM ҿ>|;#@&RX&;Dc 5Vn@~UFRܻO&N`[Gfu?gwJsΎNX8|%|L~</|ßN`lZ[!ƺ3%0{(vXx.2A]}2^: EuIU[(ӆ yM.(EuM5J aOh"7VⷼC;HhnX~7!T>a\9Ǻ4U(~/㓺''T_JS'RKҶŔJ;;~ɛyEQYovu~Mof*}/uRBEfK fe.N?tsHb2?u/{6Uу2%:CPOU+yZg =Ր\F[?8 V5c~o0-_[F|:}m}\nb~66gY7(fD:{M7 <_Pj""tb'4]l6'g'I\ny$k0kB &:YLɧSF/ cEՓM+[\?SwEt?RQ}UяRT۪3i]/TR<Í_(}{FǷ+B:n7RODkD-JfgaaYBPA&d *`4a4`0`0XSK55|*F2@:+3\ҥ3 0 0LCyaaq8 ' 0 0 .?77DaaaNp"0 0 0Naa]BCumyaaq8vzT v"4{=4y-ۄjN`cx?ڪXa~bh, Mg\ޭݦR>T s`Zty1kǫ{ŢQpv4|7"15eLyȬ͈.\ݽV}$FcsJzcw:aݲ">_iƬ-{K-bcBsE ֮fj)x%5yڏIi@Ra}m2{Os[K}Ȏ#Hw=&P3{(ۏz2v4kgS2j- xF^}& fgEtj1#ߣ~EַO?SIկͬ:>_?[Vj"Q9tt7}`'?i:MKC)tdOe$)mz:m-}ϡla?q$0; > M(G0BZU:S66_Z`Cn^ڈ/q$ |*;{A)WE/梟On1H_% <}0aK_R ޯcGyػ6 =>4ů“@LG`F0\7 IȹrՆjܾb;p4j 3]Ad,~ ߻2p<)'c5 1X8`ǵ3Wvӽ0f|@i,+ypg1jX_iRѯ~- ݇Êu +,1ΖWB$" WANjd$(џǓ!\1*jQr!+c#?5mBk ;oM;Dc 5Vn`+1a: >*Ԯ U ָ)c0L0}cWi `ˈ;pLm=fGߤcGM+@D1@OH^>N5 &x|چ3VⷼC;ZxV{jkoSw>|~t8W^>v {0*de%M!8֩&b-*?C]e 6}oBvA)kQZp  DHH0 r+,=v=0rP[|nPU҄'d5?b8 Wmx&5}q Z<R ASz@l;.9Q#_%k֎{qsKZy>{V czz?ޏCP㡈ۈof&:y sJ]AsWl[_j ^bڊ5¶/___r1s^&JMϓUq7>/ѣv?̝kYU<^ؗ  sYabSeG!$c_$ţ(J=/g'I\ny$VX_Q#O9Z?K~AK]#gҺ_c }~ ʸ\],L'v|Bz>eldD9AG>J'kjJǾ0U-"N+#v3duQH#uUяRT xPŔ|:ջo_NaQD }_{n]gøwq~/U8;i!~!z dL,~mn' ӗQc@Fp?} p)oYj{zC@ ^#]<\:RP\hDcb=8c)n|9[S{uqtR iR (a;,ذ*rRQ~ E9"ҥ$!!}wG6I&OC6;d|3({#x |sv 6{\I h]4qmaG`Z o-R/`Y*-"mڷTe@|ˇv q_AnL}ފe9?嗨E[mFӥt+eow(reҭ{;jM_=7/#/bOT¾vréFVM7Pz!ufuLg`[%yg=6dL_ OT}9v\OÍVTL \U"K5LO!35d'P3qj`.zmc nu*Q19n>Ʈ )#})=}Lz7]HdPf/N!Ì}῿Gcg\М6S;b-;.Q^>b[kI'Q hC#_о|۵KGygӾGOP^Y#m"oA3FeSM=<~>%cV, I8{ٻ'ˮAxb%ډ5}s㿟Ay1=jR~})RJ@˺cBfs-#oeg%δw'=Y)eNV>9Fmyɡq1|h;vQulNřg%d7TI%8+R~ }te+cR~Jd/w^v~?}wA>$:'~@ Or >h9j`O\aWߓGWj<%!D%cǁ|` )^/>Nw~JN۵]GVy47F _yǯ?G 6ˆ4eW(#zM8e eE |;:N3|TV'}%4m `Pv_yxD ĵ#:-j#m{~]9QPΜdN|'_\̼Qv>"OEQWкE=\xٹ՟̒e[)8SV|dyv:{.z'~~e 0c0x[rœl y¿go~ -Q=Њ~.I?YOdA$xw>Krԉ(zɴ3F8P35Ф@-Ø+gO\]LdĢ&-[/۫Lz2D{lC _@oNjtҊw ߤT~YzeA^DVd]mS߰ aMcmC>I=SW0w4;5*||8~lqI$䐓W"8 ?vOX<[dHq֦~Z)𜋩[vgj:ԭ{`Mw1c9Ϝ7{0Ȗ WYV{⊎J~~3 :{F4}gղK/׌ vxw;eM,S8Ǹលit<5f$`.kX3#_K̢i؝E?иOuwD%"Sp[Ӷ[Wo_qx)?'^VGJEʷ>QpVJb\0_щ_egq[1ԿYX7g[0 ց`?Z~RhV$,;XœQDFD] o|3l%ԫrb6S<ś2wN .z.? UJ מGxSI|j u+7s`܊Ao`Q{׭f5"&ud>{bҽ-8咉KG@W)Oŗ)?(1hIn1dp`K lK|y( j4^M8eSq^^XN_ ވϿӺu 2u?Nzش sD'P(wxyMOx>emoK. 1}nJy6/g>kwU!t0obؘL}q7 ,40bѤCq%ޤ=x<^_ha` (Ct$@6y^ Ƕ|m>GI[*? '?yzo#DYM52gd.{z'=QDY%/#G>}w3)_eŷ{4>NgQ+|6Lv6y:=GPwb/[o@i0/TW,5ʭOo?kvG` ߆][̹u4_O\z=?tʫ{އe_e?𤒖p@ߨ|6 1D.pa `mBhPË1ib? ./ivk_D_~9M;\F6}4s g1r'4SP ~;kH}_; IDAT!v/W+"0?:%1\2 ,OM\̽jzIΉgB$ D0ё3&Q١,Ս'jeX×w_=nMYo6ٹ@T4,+bʏNUO^ xP"iF^V>"GɓO_qC, vkj\Zᐑ+)Vp0;pRRL-1uJ[T^߱FjfzrgƷWbT,hb"X$U'>AK\~cܾ5SW_(?r锘Hb\M+hfO i~_~o܃8v!9;7VG+_ג&}a=i:F,/Aρ,Eߝo[k i_y.Py?3F m]O~u5!pSᔣ4XVPtaʼv{{$Epœynzh+4ԋ׆S/Fx哗!PTe[%{vtߝp"5ci-lޒӚt`jU|f>lsHJPӐF;u@NTyBlT8$V)ȵy`Y57U./ޟc%~UY@[JLD-z@O_MhM-q0+}_Yd}Yqprz;]Lnpptnos|?0{Kz%.ߑJz <8PA3ڐjWn8 \UFDu㜛o甖uqdAp>م3FNla]2r9OPD!WOfzmJ0_rK]oNyFsI^*7̽Y3^.Zo<<ʏQmy>aEe= R36\5-%Nȱ)v{yOj:'PZ%e\ J߶uguli!?OJJٕ3/Buu痹_):>7 ٵI s]rU46S>2|1Y},p龃;`*$L޾_eq{z yx37GX4[r#Ϸ+?PUxՊ2VurFQ^yUͽEpeYd Ɩ>ꚏx r/m߿>m/wp ]͊eآ..[ᇯUJ vǏ튒ҩ]s~J=|6?"ec +Z4`g%Y4z^6KfLWeaR/%g,yuDԾ%~%k1W7˗qurҾ3MD$t=oh.募`}c!8;l9Y˯-G_`>eMN,am8^BO'Ӻ̙m۷ aNqX,a^׃fǎ] j6ZF9@/eru\91pyh柈A|d'zLK:_HmlS0f S:u|У]cWޔȋȉKRG65 yyjFx1|FfK*^j EDG&=횈H,_(oQx1(w_eU"""""&i4j@^DDDD+$ȋ5ȋTQy\ȋTb ~nyy*Sbȼ)Qy"""""U(^/Ec?얱="ȋT;@^DDDD^ȯ]ȋT)6@^DDDDXUxcS EDDDD9l֑9Fi7Z| EDDDD1Y EDDDDʇ EDDDDZQ)WA EDDDDCi:UDDDD/u+p‹rkZxYz=9հUE|Wv5~c/SQ CU" 剈*v o!m-<$ yW~VyY}yrh+ڢH'no!y ^p$:h5Ia@j/7-[ԦZtEs4g/?CA/""""G1ʭ]l/Kv7“,:;is5^,`J=_ht[uη/4eQ0ZY~yCpu|.n~ZF7K% 8-ÿ=d{L ́ڝYhzms2/""""njP?옼|  y _h>AU80ΐ79&'~'Ah7/>`AÞղ y|Ek^k/ [ΑO3P}?O&9?-`mߍ}n;dbQ1l%=7G>հSYąۗorPʖD؂mz>V:wet^OoeG ݃ᜒӲp6EDDD* E[>rBxmz\l%/ϰs= !0Ho2Az/@M~Y{C)]^# u9|%/ߐvТՅ̑ottCv'oiO&^%}(2'TG7ycn>z5jG81a#5Kt?Vu+jMn/={#x7{ pjwlX~JΑwCz_v>poXz\tF ׈_gJ0l|Սcv<^ғ1 z0p |P3/uA>G[1#x`*O+ء_^CcsWh/~( )To՘kϺ':RK H 4WCU Yg1Q=Gyv}Me~pea%\ķe]o{ C]DD2_7Leؼ[Dƿfѿ?k:Vxr5Ν?!Fw}3.hW愓-Yӝ;/hWFDD/2}1X/78v'h~nEXTM:\5Co[l-%XX#<.f4"V.;&ghWɿqI:^>|, r4 ZѸX7&#PTv skt3vtDE7`Syh^ R6ׂ'"""+S_]ԏ>΃A}o=_gȏȍ#y|y3kxvb}vdQEyuϤE{9>IE 4yOL{s¶þqcoEn؋?xdFW <mOxx<-μfMܸ Nc{nK.ӄP4]\OڑD Io*ϤkHgDž #<2g^:9YPߎ9s96ˮ~?OJIY utIdXN tڗ#S%Ion~t+!*g ?muPǀOe,"""rԔ{AƑŝƺ78 Ϋ7> P"(:>ݞӠ]]s)_ {򏥙UpV!Wl9/;_fֈTӺ̙m۷ DzYxx^/^;v1ҫٰjپw;Ղtr a?PhW,㎷ j1hCDDDdXL^HY2ԚG"""rB0Esf܄O& EDDDD1RMa]P#/"""""U'ȋT (ȋT4W/ݶ5 EDDDD EDDDDUR /""""RdM)"Cuq͟(""""")4(jViKTv"""""U7o֏7;YR^H)%rȼyfv_(JՔ\Aު;fO4 N9xly μs8oPpo%Wޘ[S)'cLyqwmC&)d<|:TDDDXg *xW}FlΌk6Ʒgd^4q#Ԡa0j4Ĉw"+Jqݜnw@h? 9 8!O eK'%*|; mr)tƾÏsku.(]k!惛nEX~v_gpY${brOOjKf{Wh' ~tDx6ym/ >VX, O̘WAADDDu eQ(J8G>]lj"Lv!)̹~J{kw{~MCՔkM̯[9Ms7}:`{ ?=/~jqق__j!ynMnE[t{>cgWnιvl9M~9dO<ì eIDATSpjsa3h]E4>r{Sg~w̳ϲs3v,aiilC`%p!#>r&.]Ķs@!*Q bYN&2CQȉ *5%Uyu0i{vMD; SfHzD\kϠq/=v7-ܰ+? 5DnjX_6+~}݀q|7iz}DDD䯡dn4Gͩ5~Sl%>IV/2Թ?4϶UP-^[Gxnm. 䓆c%|O>[q_Og-?/Z;k5}<_ټ<*ZG/I.2nhkO vcZis€SDDDDDN(Muә3ڶoQr[V̌`z=x0;v1ҫٰjپw;ȭ5"""""A7?㏏ BUb/cj'MW>ρT2uߥ~SH ^NycD,@^DDDD] *P~+{mW"""""&tR /""""R|_o[:}`; mkdU] ou 3 kg+&g sVw=5t {1Y5(";6dy{XSb#ci6bǻ#ͷlU]ă3eIؾ둾dy- Nq/_||l#:OODDD0 '⇚i x\͘O2:Lsef6. `d%>/m0)o2-%Urxfp_xtc43үf f >6?O6 gO5_Ϛbjͤ񏘔y 0 8  4@X}IՒ> 1wY^Re[dUoWpRw+L'y/}aZ)rl>OODDDU!@MbDy =c'GHdD&߮fl~5SkzS&ܫndO*'#mb&Z헽OScM#7+ya7(jpBja5ڵK%mͷ_[sh\JOWtQG$5[t璿SAS.DDDa -jtr6hWSwMĮisSm[~v VTJCKVfI~ $Zo6˾,=|Tͬfo/gLɮ"@p/q$L7+{1x0$8/l_u&Պ6-o|ѤZޓ|;.ӧ~JJJJJJJX@ÀRr,7NgΌwh۾ ˲||Y]"""""ǥE3-_,'yT\x<,4c ,dh|q,{/wL7>~!6fV$Mκ`OA o*x ~"""r0G~5pea%\ķ%34=ÚK<Qm`˯Pt'85(K2|_%k lHTX$u{hf;ih??9^ŗ!^6~YVf{ͧjcfMH|s[~v UL67uJiɪsY 38/~JJJJJJJHZ6|lhf0_Θh1LIٱ,7À@3 UݗQ-psa%u\5II6QU\~v 'u´+Il+硎p'o.ǦDDDR뗼.wDClI>ٕRr`:0^<^/c.^z5V-QÁ ۗnZBDDDD~3elaOHu U]ȋT f0P /""""R,=4@^DDDDz]@^DDDD ,ģ4G^DDDDaqȋT5_nX,"""""UQZV(9)bow+5 EDDDDԟ჈ȋT1So@^DDDD w6@^DDDD^oj|pO*ezȋT)bWx|@@^DDDD\j9vZK EDDDDZi3h& ns9^}1j""""P4䌚4"/""""r҈|UrkZxYz=9հ3 2 +^>T k@>G6"w{5CL,U爵χ/]P,bf5CFjr [/0Ia$/龩TO=4WBNn_/{EDDDg? - pourG' Y IDATxw@ptrH( "Ec5j=(5R41b%7c^PP۝{enOw;vfwݑgAA~s6vj@)`A! <#X"jR֩WTki,(K@F @)m[fYJ) \da AAg KeRYZVT 2Q\ [P$X`X Aݴ W,AyXϿvqQC)K)Â=F#st`e)QXJ@FEgnpJ˽gYnAAgIլQyyShZ );IX 2R RW cEXMR}(-b-4  Ӆ)BOOE ,`gVwr:>ŢBA`U7SK (8?hc.  ,QKF]tIuJXt"å <Ȫ6yV{箉T}mRRVeYN YrrԨYe*,-  H%A/",˔iǽ;w*1@Bd5WK  RTN(yk ʲ  UjBTE XT,AAX  ,AAJ  H% AAA  RɠBAdP`! T2(AA*X  ,AAJ  H%cǞqc(  ȳBrNXXnQg ba @l#1(P ^A O}-nj5ysﵚ&"2p%yXrcKȶ; ډV$c+ ړUD(ʣ «窰clN帟*tYʌUS"]M]?o=UJBbROTNH^1!i%a "բ"Y,}d+% +U^*-Աb.ߨCZ9{Dm<*g~+'[ia}(53˪ #D2;o= ے!%'1))mmz,NH®rIO5 bM0w>D;0!P.o- 9D򤡹3}gcsjm}ÿiRᵍ}8iHxuE.S&JN#+LCEn|˽gRރVnfxFU(ݳhTƅ$JR6Tuͪj.T7iPZQ}/%=7ZIb '| m۾hݟ~?/պC Ñ?3KKGI} \"GFLw `L ?]aZP&#"BE'WMahg~WZ l_Nov-'"$:"M;ʹ B4kl$ݧUAޮv&2Fa1O5]{KW~˹%+4k'p1˩ѷIu.eE'fT?a@Z?qڰxNK:ַ߆%Jf",c3o}Ù5 D(5fm$^Lf"qaMpj*\M @  {ߍ^iXNp ! -/w R)VYƒg:m.wVSUp%O.fEŒ-|xf;AIk4>D_Gڙ8-Jd aҒ;/"5}c;ꯔox+o W]L֦]_4/D7U67$pcXR:"yW$U;u|#ʓO!!5,AJxEB1|{{Z[L̺SkEg$>YDhz͗m3<_#W]-w h}<Ĥ$sSIe@hpmԫ!ڻNy&Ong;#Q-eAE zmΑO:4^N 7&53 r3>mfm5d菳͉}4:,L&Y&% Pv*Ofx1^49l~Ŏ>ΡGgu y(:X~ɿ} |sǂ;79s^<-CFL2 tߥd1`oَ~I7L{Kך)Ĩ) PDR8 E9/%'>869V{i̴Q.e9N% ,*b^U NfQ?J)DFV.8xF»79k~__qjW90 ޛ:aƂ^vn  >IPVHFih>ÕU5KE/dx+ e2$1Qb3/yo'VSVjN\r n- I.J26NrYF 5L ni6 !,}_L<)^f}g>_kc @ɉUiߎY#t}K~cf.[3<\I0vnt][&'61q wΒkmh?Ks`/5M ׬we@dr}v1Wnϰfm_?b74zwwYBW7KqGetap]pp_pxDyhrt_pxHBrٲ umWO\VsUc%'3 }>iM3許pA'C| ){k8_GHFRZw;tリ k˻e؎)#7=s׹bJ%>٭Y|@X藇} <ۡi|Pd>v7ҕ_@ސ ߨQV_2~݁Ϧ4:n{:QM$7vGĤ&ɉM=79%݊΂.!)s)fv-[DkRzPs5;5O ״ksv+fͽxwJbEdN]c~2 љϬnp?SCD:yY(Y.6$)ߟmDk=͘f l=S1u)^_K;?ͪ&rH ]fwy-"ݤlz[ʧ<aY^*2AbߒY|<{0ʹ$mO3N }á n2@OU#jvPvvŠ^+^~gpz%^TP{Ca=e^47R-+&w=ၺû:nJo q~}]֭!]5_|+sؚ)3=V duo;Bj&P/WS3=ȪVOsm|dw2j(;~܇\9W𲩓ߐ,P \ʎʜ}\U4` o5}BI*!D,H0!?P y9 Jt"@MǦ?mۧZClu9e,q[ޞcج}dwoְj@eFNZ_wמЛ|sOyYӎ$# #ϬwϏrxx^9p[v\QUWRqV L N;mt=y}5*s4*m^2ⷫM{.i μ$f SJ^v atdnZ̍ckt>ÌƤ͋rxx'w=()9|[tMzx̩Ce/ExK+"}뻹זiۻLs+ g0:DYppVᕣ?ï7 (=bm.ȊS"/|miDv[9&)$rmkg4oK</zBdoy5U\"+MvTD6 -miˤ&>"E$R~GL f -"RۆZR(G&URX`(a,)ISt;kEjajK XKjK6ߌtLr aSG6tf~'9Yiq6̅"PRTjkJ nAG:Дi+on[8(InV,<磦e,).+)f єi(SVZVRPp o5 e; ]KhYsQ uY 0 `5RL׸V`;8uzQjAMĆ_6r(Ӱ}426hl}~&Q읛y$1ʙ@$hhoX3 rn݆Qj*@.y3_D}"aR"вٙ%bF]QK .fC-2LiiQQTT7?pӍ)ۮioʦP|.@ե%4\;d42V.c)PF-+h -sM؎.LﵤsYKAY;(:ЖKJh1i?bIÌ+$.žF7qG<5~}{cZPF !~0DZIWө і2Ûm$ k\9:* "$6ƒQzh@5kvlQzEINGn7k( C6o?>":N @)?ZZ.+),4^SP%%EۺZXw5#@iՔh;LWԔ&G'5=[]̂RZGW\$sſx 2[RLF{MJcz %mbv(@(%D]pb䍶b;B iLv[+ $Qь2KI]JkSy"mR<#c6p񎈌4RAeG9meM7_^qi>>Rxÿ'nЭR1nl @;;+@S&j>RJ(jRJ5\vm9nLe)i̿/i; l6juiM\>n̲X-KA4W R/syةSJ)K/{֯N k 86vr^ ,߅%nusn'Ph$98_yt0aqy-Bn/{Fˀ2e抉_F X_m\ykbF<$\β,(VKY,H eu1 oMVp-(PQ`&T85@ %ġv|jkfmi}/ȕ `4 uX{YOrWTA2l6sՄJ )8qU ukPӄ\^WiyN^rJD\&aXa&~ePJ` ]%PdΔJD8a*q &jK P0|*Tϫ/HZLNe̎Wtг+ĆrtVP +Ǭ;6%vX+jNITEJ ,MKm2!F?S(ð@/u:9Tso5D) @~?_s`0%1`T o;=,&׏/W[A)uuO_ :uBuuf{p/9T{n)9ꤑN Qy˵V5KOyF-`wXJY*Sz:BѽBe-%1maJn&J}g7~N[w?AHEɅs:]-Sz8Bѽ"Y1PE_ɭ)Q`%T렻RU;mt=P~j}싛oK1nK8Ұgoi]ܡ,Jiuz^'u7VNg?Gj(N?R=]jf Zvmw]k^S;he2Ll݀N)h9]hZSA^~ҋ:}2T(Ws %s##Bļ#6SĨI$㵥 `>(eu*[gMg, {)ߌ_ob֒sJ'lbmOP %B DFA2ɲ٦1 is Bc!7l=pRT9Jj0WwLJ%oh,ɹ0[(7&7q$ܫJYrZ~9:7r*B!p3xL_UuG0Cy+r_ f)s8!˲ ˲ e(=7kz?ލ2TQ+.aWl3P`)e- E00V m  )>ygedy]-.˲,K =9PF_֋x/GjݷzŻɣx6~$ܳJY|Z~PnD#džIy޿YYtsGn>m];P :|ߘVZ +(;͆Y^,x$USɠTkAݺFLQa97A0:y*0=J?g̦_{-l ~Ct BIlZmWT@eLJ>W4֏ت>#vn[Dbr%zRۼ:qBCW~eg-~+~ὝeЖ#^7[L uVph<ٽ!aڝڒWFאH1aCWlvZoBȦֽzR,¥y,ՌѣvDBj2nR8qlÖMYϞRVs}9 {Ж֮.;y wU7ՄCPeM˙zC,cY -'{VN|GT'ext)w~veZ__C[</ڳf|cVut0VN|WX'eDt.!2s ^t'Kj%ә̋bn]BNY-%nʵV5ٱFs-a-(-Ō y?طuλ~L֥Z.ꦛ;,罹"˱ s 7)KSWo\wdI[|Wq.TGi|*sUMvlwvܹ';4ՑsG۱oѦ\p,cˇs @)P\?rD.n#? 9E;XpFL9Jt|k櫩xu^JOXw6V<ؤg rQjêiÎr(S$TXqdۖt d_>c9o?o)!$Xťj`q(}Ծyz 2e#4?꾆[QĖ$Z0b5lY0(iWJ"È`K~%eU]з)@nļl}*XLkmÄ#&^iƂi.-}uޔu'D؃ה ^l@WwdMBDW--Ú3]M$^~BϠJ_<p̰͜ؤ97-,a6{~rGmZru9h,7l_ s6,XXJo%,|gxV>8i` r[|23UUSc>۴AyS{XVUВ2a]Z,8 M:֝,lyG%jDt fkޮ֬]խ&/޵1kWrA^z-I AކoUo!BꟓdZoJ- 1gyX&{JZB (aE0D9]-M*qbPlBWRaF{z_4-ÿq5+yⓊ3x1OՀe)5D=Wpѷ!@ R_G*]/2XL,Se`(՞pXDh͌kiߺ?:57,9_ad $3PQ󟢒jBDOmtI2e+I V+]T -)r*MH[`H2;(=.YD֎[KVAlXR-,0YfIW~٪}2FC@9dž]}20g>\1Y>4B#}e^3`z 2+:1Z3` Z1\cV-g{J-3<7ST-}zR`܂5]Mxah"iPp#W)-SCeBRMl̴e3?2mQ'89"W&1mXm'{KǦ&QUtd1RWx9۶+W AGcl>bIba+C½Vb!wS#>ZH7#\0MJ= az'2Yy/&S+^%&]Enbg.m 1Nf sBq*7?XT~pϗ+i9tʤ u+HzjUmTy$m8O*)ªZD|P_>3;ؼR99G2)JhXH/6 b͗^ˬw&"RA-%^1ƮW~MyJ6iAMK,e,2jU)(+\-֟9*b [J#Of㑬TVK yz4,24҇Xef8xXr8kȗRowн[֊VUE%l6RΜepW@2_96 ;nTu9AAlX m{Tu9AA njc(   ,AAJX̽_zoIy|ho>dxA "rڰ0O HRzꃶQ-g[ {kŬ\ RTkf͚fYYY1x`vl4ao~|%BlS}1i~ PhĈ۷ooӦR)$Xlq^wȚݽ S v y:}w㼦n -̮VU{?R! Hz} .45->}|A*J4xG6srJi?E%T*-%f}5[JJiBr>_)[(m]/gFIz"kځ:dUܴ59 m K<~:DAΥ޽nݺOYYYff;LRj.6qw+s=?GvYz;w}d5XvMW#OY<|joxaFC&-_;ټB~Y0[Բ)aݧLQv9\$>UH5yJyyPFhubr O %'zY9t>y&L' H_4 R%TT`qA nիW{eRܒMw%ЈIyԃk'Fܢ^[?9'7 ּM%hyKbXxDw6F -}Jux*}YԻ 8z-kgFԽIH,wl̄>ֻ M85qcVXA䅢>EUXXV RSS͓9RgR_Y/Lj \:hXp?U݈k2Aw=oӊZC: ڭ=ͫ\?ZˇVl{+Tz:eϱ }U*Jt(0DAJX^^^}yVyf>}WС;JNFT1`L8Qf%g#RW~y]Ֆ(0jF²4ĐѰǾfT6HU<D7ha0j7G[%% rܼ\l..]T {*vj/Uɕ/jUA| %0PJPy,K*ϝe}B 9  UH1J۷O<|<(Ez;]Oxu@<ķ~q}}B%kuuE-u_-f6ry}T˻txclڨp}.Px[G. 9e]ɋӿ;Aѣ3zh;',[7v)SWfN}Eis!u~NGք G~Z JO`7 \RJ-ƣ ׬Z|cl`GmB6}1lr^\ԯ9}Ek0N5#O RUg,hgFFFVFAAR0u'i*  (?  A  RɠBAdP`! T2(AA*X  s*k<|@@A7Ogaf͚fYYY^rr7N7 s-dvl4ao~PqJS}~'D{+ <15bĈ۷iFC=R[W"fewo9Ȕ`qiB8N1'ߺ+ S{~… !.\ݻHMNGC|:~mW4PT>ቝl=m8?ORTmy_N TTv0Uj.:dUStP(6:::::^h-%yW̽! o{M^~OL#O!l <OR`qA nիW{e[:3Ϧ-}e;NhּM%hyKkGFjplr z*#I9l/w֑=tA= м"TnwAq9#[©?{iT?  ȣfee¬Td?6UT*_ӹzvɇyC^V֖SFO~~?Wul)Rݚ3.߼U|8`ꋚʨ*RDLY2AA'ӧÇ}}}o޼٧OaՒϧ:wɜx.?5@-??t>p_ߦuAkF=vG ӇThOr R.#zjjjnnn^^^nnh *ϝe}B JrjNPxbBVŨWc`J ZgJA'έھ}{~W' f ?ϱ(J^D ݥ$D)^&p&;nb\ ܾx%6dj'?;\߻.޴6'J~K)AAB:=zϞ=GN7/jNmQS͈;X/M{KG^\*x;֟G^8fۥegHtr}>2n:xGAy$H3SWNr={62R*Pм4v{z;A*{~ܺ4OcVW8Ĺ<}18ؠ?  "7tRE;Zρ<Ϡ?  ʋ*w{O{ IDAT RaI?4Ml',g X`{_ VT*Uҋ>i Kh-AxJ O4f$⦝(8?ORT7=T F1^8"gdbr5{Gf6ᭉ2%T*-[p'.R)i;7 RT;2uDEcFs}ę?zQ+c?͔]9{kEܾs7ޙ63wiS{,!R2V l<'?f2xn{ p+9֣zϡs7;6ab?Y@,ߖDgW>HvȤ勣y/7]/MOƵյH%Fgu^;Hw15@ݪj7fޮ骽q)OmuOn^"R{qͰ{=G}%_ٝA5"37 rRx~n۱;~yZ\Wb|;#Ưmޜ1{@ s/{vpd;vO;`ufM][}v8zPxDl5o2F -e|`$ZUӼcÊ1mRB[[AڸKo?b_BbՉer(Zlϙem+g].y&wඕAK6M_h(_8MELJFt] J%xJCSSJL꘺˓ Pqoyqp{ur{a[@-ɹU ung&j~Z(i] b d 90jFc⌆VK>kɜx஭Q r}0]$qDk_ԂO7f%%毜=yx}뢑J Gw^|dOjrIoy"skBbo~ة1k;80PM su?n3!,A]a}ޯߝ7*:sgYP] rjNPxP4d kevٕwmm Zrn6duپh[5 >C캔HK` inW> Qu{#Ϋ۱G4<-&nl(zG3;_:nC_ r_:9oZK%kuuŰ~tH<(Ez;]Oxub~=S_ %э"=Vnc6D ǭ1G% ?]՞Ue x2b^6r}¥ob07sԯ9}Ek0N5#OԷKVi={˜5X5nש3Ox c^w ł( ^v`:b퇷&,^8RPzA Osu3n8Չ{ea - 34ed^6*3a9S[(4m;= =  6$)~qC'> |Q ZxbOgOLhrֿ?΃y&L' H_aFC&-_;ټB~Y\njWow`bw/=nƵյ0#aW,o'S?s`ﭘzgY;Y1JBxbDڭZݭvk&횮G>xԘVJєڋkM9Ý/\F2sO-'|Z>u%wDL~]/팴S8ƶys1/C! <ϿyLiko}tَS35o2F -e|`i;nM8P;H߬űVpdD5զG]CJQBb̯[ 9OsD_~`T!;Wrs<(BN.;F$ֺeO,kwW @4%znۦĻhĥt"·KN 0wK[8xpBTzq󄅗cƭj]eGSy礯8m_u-B5@)ϿRgwqKvw=o؞wU[eӺv_!5$^)B,3> k:l֒]?Upu()MM?gW6tPj S5{^ppqߵe6}Ø8]֫3wZP`KrnC`~V#7PNިyy0Z-|Z~̩ SQ325S@mJp#a( @ `5,wq5_v]nVn۴ܖLJYeFČ!MRTBd/ƌ!K (BRFEE۽V1yyνutP$j+;B`(/gyVO $L XIE289^?eOl๓%QDVjv7c\./|ƭ}unr.+#Ņ"PPeB .jEzDO( ]z٭+V2PQ\_~s;>AV?@.礉r/!F_ j"*|&g/b>n>Gq99Q_+A5OG;UAP3VWŏԌu2B t\=c,WUf0BxJ8N!Ӽ@Z2^T:krgl}Q^Od/[ _{\\b$#FvWS&7>Q6)ȹw Yħ@AU|8؄!KT 5O)y[d|z.y63^1]$PUf3q [+yWw! @|Jk7 )I+u a6Ƅ,)dԭ\=eR2}Ɵes~l'D$ ?1z)| !m좩A@l_kǂy`[K@Sm:(buyҪアlhdһtx%:P̆RLM?AEtr۷U}/%7a8|z%BhϮZ+P@Lk9 PRyk)gܙX!z31mZ 3XDXSSH(LM=5YhB!X`ׅV|r?ߖD!PV[I|kw] zg9] |xm !BaB!ΰB!jgX`uaB/KLCO!ɰjD\2rBzy3LGF}&#}g5d iK]-t lgDvEmhvtDMޕ2y}CEX`5RsW|)! 6d UvJ3gD'Q/K~Q\ta:AAh 6sM"A+kof;&.M|$Ozp?:äid5jFբ}Gπ?$5 0vOeBL^tRX[ ]d]~ m4K_M7 3c٤ݖ2|(-CBo}4 }Ѵr1sNI[mdiA߂ʖ =<=fӚؚlw X|M ~t0ֳ9:ĕŕ䛣t 2^ }=0 7'][?4K"Ai\:AG ^4"ɪ- t55l'd\쨝Nx)s]'^%d,}a:5sj,w vYBȊiT`[wO]˄QBؖU$uiM`VM2lYݿp%,4؊)xK12Q&}!4\W}:BV$}Xuyp;'Jd#qR@a Ґ,ou44A=Ƞ087w[ ͌u{+ ]~MoG9= QfD <\HujQ[4fڸN&!eOo$ p,3>X3BgFYv#8*Ԛ)*߇{@NSZ#ųu F@q/ؤ5c?fJT>\׸MBȱ+E.HnnN~>@[ }=CKۛ1F\3_N;1k4I-yQvrZЙ6lgHth M^~r:{LzO?B}_`Y#w/U}rK2 斵Ea N,ɯI^kf6 ~u\Yn&δҚS۲{N>G,6 ! DH;oY @VeR(d?IՈ(?+*xI?r`ńba$4 Ոj#:٤m'⽼! "zwh A81 H=ǣ "g8k'XިWzGϘ˼4UfLPhn:krgl}Q^Od:+XwF+!2͋ %SEEwPwVv+Q_yAK,К}"uPRBcvNjfѠm&Rs1:ىO߁k ֯AUC6j0՟R"(zBX2ϟVZ9~g@LHZew͗#7L'|5M.Sچ.e…ad,>{a1! bJ4Y%u+W=yjvPD'Q/6$T5 ]]4;H+vX3LuKy hj|)Jk(=:4;tFZ2qN:P̆RLM? Ar<|;7= Yv}kMT -Uޚo15Gw&̎-lqtk9>~>*'Ye>,²OAdj"Bod]sUie}V{Z"j=?zAf<ʕ+]+ԙȊ'Xjڬ2D_ #?dAAx\|1,d9˼'휥,2b4=ڢ}C9.WZͦ,# 4 4>ix!P[,8y򤚚T+|>?''رc=MZoUD?Cք#Vʽv 7i):5sj,w vYBȊiT`[9 %W{mVގrb 3e.~|:(R+eVL[ Zso]]we.Fٳ a[VMs5s0[5Iʰ{WpYlW&FZu!<>aĪK5 ۴wrunxp dsu9!ZS IDmmW)S 4x9p;SX&RoT{Y~o:Q9mLo IDATQ0g>,أu2Fp͔3q9)$斂(;K9 mK G0I]mzs;}cʀ_k\wx6ZVOMGO3*@P G;a[dF 8U#÷%>Fv2eèQfoyEk}A!+Krss+**jjj***rssZ[IRIW H)eP^X!;Fxw:A1ls(Ϋ ι.*Lgv6@g}łܲ]GIG/?-x7SxM>3MX1xjںAWcd+/o=G!7AM:5!!A]]իWSNmnc4)I D$ @$b"v~TiUE,AAq~k289^?eOl๓)t+jZYQթ$AT#PH~Rp~Vz$)xSBH9eTI*^2!:V²6L_DRLV쉘yO-GJzN-rbKN֡j9IK$ V´*Z; 7fWQ^2%7JjKC'uw^kϺzǂEos7 ̄kH#z ߉uiӦeԁ+ݣĝe^v*s zYӰԀИ12Yu񂜋qAϐ%N|Th.߮,٩o lcɝEyejc<-=[`gTY#h+k>|*Qa3J?ŐL;5"ph%evL*?B zv-:s̢EsK2ϟVZ9~g@LHZew +vX3LuKy ԋa׽H ף_\tWxҤY&fhfsͅS2}Ɵes[2{Q ǰD49U-[g ZݥFΜ[>v|`\{v;ZJM<)bYdPIoXˆHw."(yi-Gܾz7szew# jqirx5#y,[l6;d?B}7fc{z)A7B{Ÿih),-.:m<#{\8ui4||iࣂE}^b~D{ vڗO]&J;eתs,EnyK:'ח{~hWPi3W V}xljzBӐkeem4añ'T.  <.mU[ϕ37@Tu( 8\J`'bZ;Opc|ҵC T(d1x̐Er4LY3dUA:r$u2$z\G>H'7z8;OZeDq<CvvNzOm6sNI[m ?=fQs GL=k¨̶居oڅGxB`}<j l1ߪIU-ZTm-g4>fDP K 'V]D_087w[ ͌u{+ ]~MoG91k SFi2R=7,s#թEoSC<2}7 b%FL 6nF#zi !eO wO]˄QBؖU$uiMdEօ<ĥJ͜|ma*G:uAw!ZVkr' 6ЭejS14j  :6vaGc~X@GbC)';Nm9)tV .moJJFp͔3q9)Ĭ$eMFosKA~Fe7rN"`}XرGlMh2V4]QHtI9={oL0kϦW[|2O/> \:k zAbd nOT>^);XRr7B5]}F/YTǬ:+Hz r؆7Wx@/5szӑƾvON;DPwfߥK?/W%6=k*JT?~ZFS3RaGݰg]qse!Ԝi]\#;gxZ274gsJuF\(C2ֈβ֕JTW^ fv$!԰ԀИ12YR6HAŸgȒg'>} 4t\=c,WUf0B #;PI'T2Ռ&PyԏX'X"M~|Zj$͒FuCX`})ꀑCtrxKffhjS8aѲ3gV]93X#מ<ǠCӕ( ߆붳rI=Ů ~n#/M̷Țԋa׽H ףnS*V2pYK˺.Unu[K֛to3|J3^&vɤ`뾖!"B%/3W/xvNoB!31mZv",JϩB)LM=5YB-X`Q Gh<\??y!B] !ݯuu/B!-+BvB!P; !BaB!ΰ|⊗ɗ˛y~0:(qx<,O_jKU9ӹÿ_h#z,>_uΙ7^)j/.M3Lc:Jqirx5#yNB s B`k ZYwlۑ!sGh>w#?Yg8V+'Ńh\ YݘC]3 O3%Y/,B}.,څ 3zgWPq2 +>:c׽j~HaYnHwQSǢ6x /o&2vȏ'ʬBccwf_5}ý  cS׀ q&/?aa`t&_gIKC (N'nq++7GAv?e|ZJ ^i4[ۓE!o|%0yp\ ^[]x >!ԩF[c2cTE uafVM2lYa;ER_Q8t1$(k_H/AӥQ|;-yKfƺ^.զ'؏@i2R=7,s#թEoSC<2}7 b%FL 6nF#zi M?)0i|Zu!<>aĪKH5KB 4x^fARfN>60y[g: ^{ðj Yvct1FR_觬chU;|/KAV^"*S"e:E8wW7%%lycfʙ8wbN|8h2|[ 6,(06,vj sVŽ=ZgkD]bG鲽]8 j_QEGbC)';Nm9)Ixz`Y_k #WOx-w+~yHم)V!нO1mєj=(T֗d;A 'n>ɯI^k#}.d3w" &K-ԗ~X_6Jl{&dUyݢqrv|2">ȫqR5*r>L`<*bQ앂(kun!ރ H jʉB T̄w%uDV䗃"VN&,ʋYޡO "|D1$N\${^%Ư-p D nͤ6j+_[%W~Bj6.+#7oQeP4W8Aڮ_Avzӯw *,ZBgiJn'\ Ei(x-mKidA΄igq?ȓEU4[0!AW\$Pe|$%WG jEzD漧Ö5nӑwxy:rm="脹.N˺?ݷR 4m*T ,~frm{`kNOP3> e9c§yMb3+9c鳹F'wF啩4giR_į]ut]zWw+IЯ ߿%h>:HBa1;bd'p5erOY?Mf"9㮃!K(*Ѐ:q{YN_enVT/ FzZvnm-;PI'T2;^+Cijң3ruF\(C2ֈβjڜDOK~Q?Z[b!Wcc%ϓ4:k񪙒6K :I^fZ&2A?Wk}b=J@+ dXV^Q|$%f;fi;E?|'jHuo-ù®ه^GTxnjbX,p'-W>_nU\z'<$'ȊA^Աp[rQeA16F,cpf;y4oXRQ@~'[YC~|7 !Z&7I$w"9[X:.uI$IRX;\ֳXu:ZI75'd :cBV'J^fZ<|;C!lqtk9B!X!B ,BvB!P; !BaB!ΰB!jgX`}>q  v!Ȍ~Lº>? |w;e| ^EW7 e"ENi.rIJ>Xp K^u c5lS5 CvvNF'w|stAaSƧ$yPAp O=OY\ѭGε居oڅGxtG_#z1Z!}n;R+K.`VM2lYa;ER_Q8t1$(#,z[,k !g&{#~wRn|%9o('f PfD <\HujQ[ڤUxNen>.KY8lKmlg}3>ާ1DžH1H%P K 'V]D_ @I]ZH2 *R7sYqR<qڮsPge7IWh$J~:ZWl)*r?%BP{ xq+vd.먈_;CKۛ1F\3_N;1k'q>N4I-yQvrZIn;f9+aa5m.0HtÍ>@[vXdٍmD,6pTpߖ8PۚĊ{. 12pr'G/]h, )!Vjr6hJ NedUyݢq"$YN{9lC艛O+irR<Hic 'YzfH;FR ֗ͫvIQ⪛o𙤟9$UʹhUϞٜtrvxt\^z'eu[)|j6CX^\yX*?~ZFS3RaEx_ oP=kL'B]2q1Ӽ˦Z\#;gxZ3ߴ`/.:d.63^1]$PUftcz[ _{\\b$#FvWS9 IDAT&7čm&Rs1:ىO߁ WzGϘ˼4UfLPhԬ%SzaFWԤGf\#V P)d9e+Դ93̣~\xB8qJ'itU3%) %Mm ~Du̴;Le~ұ{ꕀ$gWbt$I Knv42w~ND$Y~WՐź.ޣ^@Txnj];jz]>\PST\,~Vr-#ɻHlf"+{QmɡGږE#XSWh0+}8W#Id5kȏ?FT1Df9IN#ʹ:~ ܻxAFæ=Yݵ-E昫An3+V:ٶ#9C4 5}GR:jGD]90N >zchrK_%< .KY8lKmlg=^F-5@RB| J Nǘ A^ZGhK֥xІ^Z/ $. y$yJ98T g{m)uꀃ8xmW9B%dٍ{.IVUg,[EzrO@h,P?#A\]ޔ<>F1)gsR߉Y;qHmn)؏HFpTw۩5ST$Y ;hiv^F܊:*V"0oCo`P; ,ƶ ?"J8qF8oK}ImMbӋ=Z^zk[UϣD.4cE5yLo4ZJӧ2ȟ~;/u#EI}$/ r/m=qI~%MNR^3 5)m`wa$TLi5yg]jyUb߳6!XuޏӖ>3muhqA^IWW4aU busmDx_3w !VEbPUN %3]nI_.堨X[Jȩۍ~dyٰ^wrw26aQ^D}bK'&|$q"c,1~uh儰GU$H i_}pch&Q]"g.Qv*M$FMH@yay*VW&!vӛ~!Wa:LVr;wJ(JCEqni,x]J K v&̆KQ@,3qDV?@.礉r/!F_ j"*|&g/b>IU3-Zճ'b6=q,kӑnsU @'uw^ֽYWユXͧh3ԌUŕ?RiMHu}%۾@2g|wUsDŽO/jfWrƎgsO6/+Sii:4~ӂ+_tL}SZC<.jvRv+Q_yAK,К}"uPRBcvNjfD r.]=C4?;;PPUuJou`Fܬ2^ dva޹MWLb>I-2utOQ45QWU:f.~!v|kDgف 5mN ?W--+NܱI{ExLI CIS%)B$/3NG}v>btlz% I~ٕchX,]+t>I’aM̝$),aY,kf?J]?bX,5=WN.[*|\vOx$I6N\3׽cУrqm˂clY,B)+ASvhe5d.Zчs?j$y 2YN$),9BұtߗmO"I’Q,ǪYOQp9a'SNGZ>Q2Zn_9B!P7w&f[18_B!ΰB!jgX`!B3,B!X!B ,BvB!P;+^&_NH/o"<-~.A:n{_TO~6!|թ;gxG4yH3-)~ ==ϔ FDduzqх9Aa0t5djH~吹#M4BM;n49d󑼮x8q_e=sƱj4^?%/fGRȢ bXwB `.<"֏IX7⫫'oYHaYnHwQSǢ6x /o&Nlnx: 46vaU7ܫa3[$MΓn&Q|+OӁɝ',$CAi#*I:C{lmO"c9ptkù*s>PWҧqX+qQTo$*Ö޿S$eCC@bji2l-ųNp]( MFaĪKH5KB 4x^fARfN>60B] e7IWh$J~:ZWl)*r?%B2zIBciH) .moJJFp͔3q9)Ĭ8qd$6mGYQ`hm$Yv#8*Ԛ)*߇{ִf/#nŎLe{k+Dw70GYvc[dF 8U#÷%>Զ&Kg}A/H \=ܭ*Cu>#to5yLo4ZJS(FN5`:c$YN{9lC艛O+irR<Hic 'YzfH;FR ֗ͫv Y~hl~]&Ai0 mG+jmM ܧSJX{`Cu!,Z$BmT9Q($.D 5^;X*q'}hޝ8uJ;B`(/gyVO $L XIE289^?eOl๓%DH;oYҪLjfEϸ/ݢmsUjZHMѦee$\4,[]_!ԥzGq̴hn'~tPBFQ*+GdiRZ,?uO3ḹ2]/Y,ycֹ &='M,r`IP͍WL$Pe|2v1jEzD̞̑xۼOtd-^k6W&脹.=NK>P YWユXͧQf 1Wh(QAXiMHe>PW]2q1Ӽ˦Z\#;gxZ3ߴ`/.:d.FSӑoW͔04Y2$VBX5D 숑Ք*D r.]=C4?;;PPUuJou`Fܬ2^ dvjy63^1]$PUft>EWԤGf\#V P)d9e+Դ93̣~\xB8qJ'i݇Jyi-w::E#\ c;+IϮ3DbZyEIh:ev5'd `zQy36bXjz]>\PST\,~Vr-#ɻHlf"+{QmɡGږE#XSW(jb]JG׽X ;c$Ilf ވJ>GB!TGkVct{vRP?B!#E% U !P[art-o]-̔ꘘ1= vz67.9ʣ9۸팯t(964 ,B%]۴>}-&& +_BLF=FҀe5v(2\ssFƑ5ileҗ]ƮuAS/Z w_0m{LIO/$ ZLσôpͺcεqǎy4_ޒUK?ˍ,;mU1xp;O%H)ҎS %DL ǡ3Z5w0c&^9;>@JDz_9Dͻ{@H0I;Ln_/EZL}}zQɉ'n+`w|n-)??\ 7b>߷󗦱+'<+.z=jsx~*Gd(Y5ﳢWur!>Kj~Xg+3ΝEXQ!fO{>&Fuݿ0zDmס> Cb LR"?|I3={猽g%kٽYU1o+L}x 7oi|9KvQETH*$ӪN%g6q9Xq_J,wҫl$w Iͪm"" SZ$&"t,&>}[e@~[n=##^ ~+M@$Vf  `=gOP# Di杻l=tB@[-_ْaؼ[z(^H03o6X$) eNxe͵^\T*Rɳq7ƃ+Vy|~s- f=/sȪq$DD,XJ@(ѹI.<+xS"IBIq}ۺ%2[) ^>}FH\ =O{=a.0l }܋DO2ڮlyɭ'\r㕠.5ݵRĹϞ=I*"dR"XR 0 [tiS>QLt}b9M#yvv/zO1Y ]wM'KB)I$j  g7?",_mrpZpb. *~IZ𨨙1Vn׺z=w](:ۡӜ_֟HXflɘ_~A]㉊31xu ji4AMF!M9yOe]I|Kc#b37ңgH23y gh^QLN}R@Ua!`af_,_N‰/ Y&t)XB HQDFF"1̍03O+ʧ}a΢,֑JǴv^;"iB[uR&A;D&ۀDFZa5kua f^tJ+w"2荔HZ"u׳nvX2,g?~#ojzT\AǗNI~-!f8 $yujȍ' ǒNֽ),a/ }%ANHJk|;sVi;Jc~pG#}_ӳrļv7QhroV\Q}&mv+-JWW_4b?z"""H/4/2esg޹B)1MY<}w/ 8gαz}퇀%rir߭dtY˞u҈DYriH}rJ,>簶s:|2;RgrlC2Va䐑m&֮vwͦ9f ZvHxsGFZpIa7ExR6Bg4Lj^AnK)8ة]}ՁKD?,{()13ͳ.ٝI*(υ:w{y;h}4%z-m5@HoSsDD$uI~?kB(Eq.4uv8?K[QQƑ{mA={3KnbI>~#wՁ˷3xBNiε]z1aآ_CM}WF򭷞 ܋?N}D9.9 j#=1.JzE=fv/yp|T.C߮}*]Swv+/,ʤ+wYvv!øW}M{\jE1dY00mX%-~2of!_+"̚&2xWhFD6O~qGYlDo_VѳURhF}G FT  @ڈ_EGD*VS]+444++kę~V')Ox MVDD 4NQR(` /oܿK+g>o;l{x#h]7::6meM>4꯿pߤͰs':2ܹz?attsxp(=ڸ;|ېCi""o0s.ia|SR>ZGs3bJ@6|~Ko w r vv9(dH?|M6݂=?ѭV??Mڅw=iM#&,|~ӹrN 7dUvNuky{,ܘysCL ,@UttS .]tA-]+ӜB~\ݔpqgج1ONp'_LpǦ6 ^kMŰY!ØT&lrlY),DD%7rmNi?i zijGĴl7|։Ƣ6}n׶1$oDx<{f/3|um[#G*{wrGgC~`R;ǧ×~qlxBVLw gkW1"rih#`(߭RxڙAFTG*izt*rLMMW>`kyϯcA;[HsaնTG j"ooXqܴl2iӘAo7\D{O~}܉ZOۑ_3ۺuҜGS/>_Զ#[t2[4_suig|ԉ6^%~_vqeݾDD_ɭc%]SAB>ٵs3?!q\|T)²AjjjBBBPPP%_icTw;Cۉэ|>oa#KI/94xO}5u b]>W[;gc{mS06_XSNZ+rw' PdzVV#L(1k۵5ƴ8fyJDlN[{.({URR[nu%::ZU9L$"̯b2ǥla&\vOoB)D,!Q#G5sg-@^9$[AlA=~t6>70D* ȮlGOK*(WOⲩ$_PU5=t4`]zǧ4Z)E’{mԬGƋ‡qlt1:u$VĮ{Eĵn~}ⓒ2IԵ-=]|۝f%4Jm$L=2YD>xCVlb6g]FKf nc(p=G0`ܝ{Ԫ1GvoȒs32{j[7U}fJLvU P%] X&MR|+A^[DzFK9 =~r}kDd ,Z?TvdŜ^cb"+o%"s?Vw'l~#5h迢"VgZfґb"y:>eNH\(l|x37dݼK6#"b4웉Mmי^}=d~mi~kWcc"b~Q=yg5k:ܺYu9,@鉱vTF{%otl8]7ZrS9U pjȂU/7n_:xgGG9hj@&L|E1mbX*bXP}W-'a  t$?s|Flߵdb1: $X;>훴?bU(fQg8 Uf?$N=}v ;}{C>o Yb"iI깰qݛ7]Xۿ]c[]vfCu@ IE9i/S^&#?wsCSGhemˊ%[d5#y׌Yg,ĸy sIs?cJ [qe|C.W׶1d_~˭?VTb}5  Z@>DG>мc,6PįiB.|WI0 ɽuŽϷsn֮荱Ų6"L1Ŏ7lyD,QNi؁] ^g⑾Zv6neec>oӸo%|!ط+`X$0skӮ}_x_ԥ); 9){N(a=Ε[RZf@F|>vԷ>ެ Se4jڮX]7}h@Q- Ґa),%{ ?BS-л35x}-'\h^ꦼ܄;fɽ|r$;u>fF6f\[=6dž+dt7p}.pzD%7Ϥ9?3RO)7²l7|։Ƣ6}n׶1$oDx:gƖz/4oQBnm̪cxE wuq]3^Sqg(&l͂Zns1lV0CZ6H|$xGϭfn-͘]Cl941"b,)J>.1RrY+fͪфSw'Wƨ}ߊwQ%{m+l 87kj&bXԧc<ֱ?4iٖ/GvۜG]Z0;_1um\\%~_vqeݾ&j쩝߷4 ?/"2qǝȫE_J-5+}إcWm ngȺ%Zv3Ĭm׆z?ukcZ3]@´L{Taڹzy66= +̻q,-(U׫;֥ik5>s_ۉэJo奤j,aYRj+rN*+4xO}5u`:W5Cq\?5A<x+ o5ޥ?'%=9؜3G/WM +#Xe19L$q)I ,|}˷,'3~iYz R)$BE+sH,b oA 62]|=AD6ͬ A$p=K]>mI6rԦ,fL6g ?fi/Lw<3櫅N]$;8: e w8燾"b 46~~{mԬ8.Ù}brIn깴ת-Ӫ()ꑴA][ӥ@Xpd>ظdc}[Zp&}&;',CsȱkQGLnEW$\U,TamIDҼ˂<Ӊw>QV<#uDDLfܹOjϗ0@iGr^ZUSmȼQ N~GL6;M{pT;;Q. f,9_;KHN־x&¨aZR^5gimhGҌ {&ZjE~i"?|8ЪX"ykqxvQ9}SRzzeru6(I|LLU!Vx'l΢f4x}Yܶ~<\;@̸L""&s}~Ǯkws7. pަ@yQglIYv-IsqПg X:g s֬{݊E,R˄֭txfvN&21˅K-6lkPX v~=晍l$C#+OLUCfKþ ߔv7XvIAV;=/&2j \{6iU 3뙽""=3VgS~bq!W+l|&*8 ,Yv)qj@;0c+/q©!Mf-k^,@:0E:Lb @T  @Z;f$c7|obVwV;9󻶟L,ƣ@j*Y;bY|(*ފXF6QFujMZw`߿YU=%s]d:ܛ.p;}{C>o Yb"iI깰qݛ7棰*-zr&l>[61Gh|֫!h뉠Em 夽;Oyw=OA}-+lIԴ+#_3g6|Nw3 X$ͽ6PN)3lű \]ƈIAc6b.bЁ#ia|SRE^IXcs;yM;UZNy~وm|>mȡ4Q1 (dH?|>ߵ{v-ۼ!ߨeo#~^"rCo Wz̭Mz~=|}QB[6LXnS.o C hԶ]U4(U+I:=ϸuӇ ݲi- ¢^ܿg:^.$"*jɋWLأ[Z=(L>.1RrY?f1"rihcDİl7|։Ƣ6}n׶1$;u>fF6f\[=6Tx\rIs$"]$i fͪфSw'Wƨ}ߊwQ%{mQPb禽s]-D3 틃Z,ֳk;f͍uB jeIN~> j]%NnMߟ}܉ZOۑ_n=:{VtQ1AW]:viΣ6w8zp'#6ѿ}sgN+z<`PuƟ}{C%OGųrfo{7l*iJE]*HEsU7K7ngM>c#FTg֚3v3g<8}SXӀ#/"8z X5t54xO}5HnAaڹzy66= 5DZtW_ҫX2DۉэJo奤bPiQ)egMq\?5A<x+ o5E$E/2 1`X@^&m#/4~E<Fݓzy[PJD`I?|w\xqMlܙC5lňaD\ZI"HH,A?.}pek3hOV|=AD6ͬRFg䷅ L6gmSEP:[xϘ>K\#Ce&* e?EL#ǮG 2^܀_*Jz$m6~fPז_t#kY*űj.|'qy< -zgt>zY 5'5z>#-T:amIDҼ˂<Ӊ>tnmS+z|NH{=NUja=ڠ$%22emy;18=Ƕϗ&¨aZR-r˿w!Ś}rf >|$/HKi28n*4{{DpuhUz,"]f Wx'l΢f4x}Yܶ~<\;@̸L""&s}^=͟3mk$r͊w2H +Xy||W.4웉Mmי^}'DΘnͤ#D3t2}3-{=͸Ed1c [;%"[l`٤B::z3 H,c+FnW:ث.rbit9}FN[N"f3{;⇭EDzf/Y=7ϦₕCz|W*LTh3_^wa^O,6AHOĵ 6PDOl58cfFP[XݮejV$ŧ旻1sp5&/7n_:xgGG9 5s #mhM@30+~P1,CP1 D~[8v/š&_tw\QM@t `I9w1>CysíB^<}Z2[TlkMl-!H?kb<t#F->USIDATed#* OujMZw`߿YU9VS[kJdɶtM}$ށ|6~×_IKRυ̞Ϸm̽1y"&n/ܚ> 2 'j<('y}d<}wn}| 割eŒ-W2te䑼kF3ib\<}1%|8вus!k [ۂU،Q(HW>ؿ X`e;ǂ2_-G"rCo W fnmڵ:e!g2Dü\|~æG]}xm-0~̀V|>ߩo7 3Tօ0`H_FSVtzq 8eaZ1L;E];$Ϟ×u`':]H nZjY?^aF>͘]Cl94Wb ,x69f c:DjoǪi%;zn|6pkvmhi,zzik~mG} %E Dž0`w;fVJn# 6Y54pD#[qn6t d ye b.DܴbE+47jh˱g \;5q|{J_-{iΕURV]0:[Ծ:* gznz ٘NDբ~ݎD|D2KJsӲɤ]'?Oc.-)34Yuc4?n ;zd?vbh-X<;22}rcVAΛDDD$J $-?3U#>wj;@jio0slD痍ݑ݆J8SeiBzzzNNN 4tÇ tRE(L>.1RrYb ,x69f c:DjSmfjc&eW{eՒO.kgggjjo>(7-Lu4fP_JsږA XDvXޢDD&nztnΫU@@%K <{,333((H7 s*4mL1G73g o' DOQzZj - 5NVIIIRRRzzAMfiiYeSIG)%.ܶq^~9yxjSX(&[B]9^V☼:T2G %bJ&# YDzhYaZ|{qqq\\իW}||.]*#]nCsʌ}/ȱkQGLnEWD‡ql>6M\qx66Kc'šKDhYaZsAM:Uvzck˪Uso]V)1DD$L=2YD>xCVlbZt=.`4#^ -)Vj9"P'V|;`ʴ18ϣ&8ׂ+88xҤIUD8l=sŮY׉:dŜ^cb"+o%"Cy\t)b&ǰLߙ:˖eѯYb| ʐвP鉱vT@Xݮe,̈́bX*bX*bX*bX*УrGzU?*> @݊̈́bX*b@Z4d[@>Ugƽ~ؿy.q=ќGvsk0qbGU_5Gˡ_7oa0+>[L\>I}#m4r0ިIߘ[<4e>*[n^}s˾TGIJ$(bn{?ptSd;J,Q]cJHɐA$)~S000V6EU.x} BIJ$ "FU8O'J,N=W>]RLĹc LXUU?Z\m%)?e={:|QlJ]ɝiiު+V~{?t\V T*Gрeaid{OS~!4dJX4sr X6&rʮeU"Q)B`X&lXP]j0U%@tgXYtvXiE9ʮU @a3a@aJtUuC0fX jC4XJé/`ai&*Uv5,-J`Ja!Q2X5S~KZzqݧ6I=ty=m*&MTP FzbrvfQIJW9e*YtՆG DruP#UVA#F #*#X˜gr6ȡ89K&Yo7ҁqk_U.x|sP: T Qe?1*tZH鋉Yv42d2 [Ęq@kaTEɀũ>۩}gFUHW=*#$* J,e˞/۴rAfݦ֕ڪƨ@=^hefxx᪬ !QAr$TMT"ot&XLTj*YtJ-UvQ-h/LXPcB@P ,DPt nP,Z @j$*4fP ܖʮI0F]0E$T!Qh Xqg>ᛧpUT+DP[}F*I;k>o>CuJHTHOUmA:[>V̌+[kˑ zd9U%$Q7J@C9Wwޯ@u1be$Uǒ#XBߠ\C]F 9²k_U.x|sP: T;'Jp1*)I X:6QZARA8x:|eGl{~[5w@mP6`1M}BOY~Ũ_y/o|Z TZʯ4v a[ .HTP uBZu V%kb|&LFQ_*&|&$*d"I7Q=!`m@S Q@5 j+,Pܖ ,u,,#J#`]"@퀛d!( T B`@%t n `rHTꧾԦPD XeWBP- ShLh+ Sh,,a*m8y3~94MO520L>/`s"EH< S$Y\asB Q>`_]Y)s<BO X7׷n` O%1]ɏiW'9rX%޽oEVgmtvu)'Prdc$R2` Sxi *_We ^~>-\?T4Xw'P%;rKuqvܯz};rlRfr X,P5{,:@(@0@J˰ÚMD #XHTbXpT+,P9 P/`] a ,LBm)?(X}* !Q@MC1*"X@{!`$TMT"o&a j%u,,e)8LʮU K` t Z` tC%!Qȃra @9XTKw!QT,}U0 XeER PLHTK!Qh&e[6~MF'McRi͠"D X-ڞ/o0ף{3U[9*-dbԫo?WkQs*jϿKf9*@HO3]|ê 3=M*NVC (Ϩ9rXvޯrFFDIU |(ڱ+z͐㵯*|Zev8FU{ZղN~UR(wvL\~Ɇa^u'%Mme D 6dnZPD XҼODiOv976檧i4 S@% X ;"*T <*G. Sr>a*| XU0L*UvM [HTPj!jV ƨfi}h XHT `a#U^ 4:2BUvR"Wzbu#7$*j̚@yw*| X @T  @TL} *VS_*b"P1,S>`I ,'V]|.TaK{e 8|hȶJ+ X⬫{9b"`ƙǏ<,RmKF֭X&M fZJeIߘ ""&τ'{')ùەP: T ~U*IF8).%˨1% d )f[W+U%|ZeN@?*)I"sSڍb""qØlC;VUoJ,3{.'m˖z6Wm40M;[5o ]3WVN=j*#)5+}T b5+n*P~ %zyu_y Yw(w1aWWE?$ʲz.6nY!;&;skZYEoC j!"é&eM,9|5*9xGOY[w-]ztysg]=}d7'6<~aQ")͗7r\.bt@#Heae^U>&1xM_:%/0-ᵈ>bKF֭X&M W6-/'o$5]Sf|ݼF\Uc .,  ==dܩ @ JXiiު+V~{?t65|LR'gyæV뎏KWP.,4qQړ]ŀM'){1a'Vc}tFL&X*bX*bX*bX*bX*JƟvIENDB`sardana-1.2.0/doc/source/_static/trend_a2scanc.png0000644000234100017500000007745212174204305023454 0ustar cpascualcpascual00000000000000PNG  IHDR ~UsBIT|d pHYs+ IDATxwT-3;[J](n 1jb7 DAM,1 h (шJ;eپlm<{93w|s%Fctm!ܖn@<OМ"4Hy"DТaAKvЫ{^SUǿ@E‚t&x *vjj$֪Y‚W  @"/pkxLiNwU#Յx]U@şBxۍn? *$M`~iʐ)޷˾A}]G ߮mXdAASu  `1$~:2ƾνᖄC)FqnL55}x/ (4ݒp,GÂf ]׀,93K5T#4 (xUI@P`0ߜaYPS` 5QPИ)*0%P, < 뺆 ea*4\(=Ps ,0}.,دQ j( 3uLu 79Ծk nMFpe\i_H`QT#i*KPP!Av1s7t]tL׉YrpL2 8fLqJ4EP0\Ò 0MGc2Î2Ì 33L0~ 4T5\'f~p|Y3]۲:Z&<0\È9nĈL5bq  ӊšX AAU kPP`7pC򆱊A. lYclkiزm1 ˖ SSA̍ڎ?h1-;6,ǔc"I (8'(RUSOIАN{w}k |>-6m4,eZ1ٖi϶,Ӕe>YO*'s4јc'q]ðLO" $vIRB5HrkqE c+bٖk[NS>-3M۶度iڶ횶؍9N4ѨsXض-#i;i"~ G]7qSRptllX 5(a!A*nEP2M1]7VH߶N\}~m3-6mr]OD1#DX$⚑1p5X(,nonp])BdA'4ŗFfd14 p-rL,oi@oۆ~Yk<1Vu7ZpU(3MӉ  Gږn1\%NJq-v c@Pv4A"/$bACb!3\'ftZ>6 mgۦ~;`v@V 0}4, @pܘDX(rpȌYVԶ, I15 ǜaq\qY:2R %bHlAc/8%k⺆d*fDz2}e9>m~o|m@J$d3 A_ ,-}v86BhrјS4 "ŅFiQwvp¦,E#Ni]q-38S @G7$jؿQ[x5\1:f(t-嚎im]ӰL_rmf ) S)vR0oc.nŇF"l6b7՗biaY#p\%ǜh4j pbu74"Yҟv_) ;ǿE eRX̒IQۉmgv1)~d$|IR} R;SR_? NrFn@>ٶ-3CeNˏE #9nQ8;P(*hQĈD#Q1YVLvL$sm:ws 8%Ɇ\ 83ceki}i d_r0 <9K#9S 㺮\וa2 PjU"+*$)qSt%c|9N4)9H0+\Ês}F g]t]HqFSF]8΁ikp]אgcڮk5M4M6mMoL  ypp8hæڰi6nޢܼ* 6+8uza㨸Xy:IAEWy*..SjUuL]`@rM6mvMӔk뚮 w_?Z{`Ai?FIC{B#ξJ\5d ׵ 2Mð-amۦ/9tV+}~IҖ͛eY BڼuڵoE"o~ 2 ;vhJOKU5e u;#׉` ,,۶caZϴ rXdiB < /)b-Rؾ]6oڤܜٳGZJkeYz`P۷nu@c P U\\H8bauI={Uhh뚲奺#X:$Ѧ͛nWAA BaǶJ+I~*SZ|wlbڹk>hT\Tp(p8| H!i箝\Z/u畿-OhT}W;vUjGyTսEq.*,s݉1.lPN]8yb$n >-۶+'g;8yXg^~:v,SqQaFakQyj߮]c4@m|;|@_-c"I*ZwWS-s",fV!Kնm[UXXPOUTX-7uVclݡ}:+/Wյ;n>CMytBb=̿ 3nS݉# ,"LU#uBAfB#,7PPG8 ^缯>/EVǧȂ[whrr6hC!`]:-TClOfW-IO f /wwOzբG1{5pouSyIlї߶ץ-:7 9|>Sen/QU#` |vgt ^'TnN?ɉ4顇TXX?鏵_Uw4i$M=>e:s%վt֋/G?r}7ڴi^9K]:wRnV/fIILIÏP(WS;vhΝqH듓H4*WR8Tp$\gQ^A~}}㺊DMuөik]X.m(^/#r͋:]5}iV'eV\o^v׺*l}ʻy}z^պZA›ꠛҲzZܫZGON׎ =ڢxV|0CQwvw׉L)Cwv:oFgpXr]~~=OCݚSZ5q}#$bhis㽞Y^nž{RMeUw^"mOW7XXDaP#׎;WW3/aɒNw];S]?W^(V)^{QaQijz`:=zc?N}Bov޳'K~ F7|ÇCvڽ{gz`$Axm2k |ڸuneHmޠN碘f+(uܴZz"eV4MCPHP tb#w}W1W^L5_E8xIJٵR+Ru#Х?I~ՇcO@1A֮m%_I_بO^wqr*4zT_ŶlqYSRIݡZ 7G/9Ûc5M {.vp:*';[ya)S_:Dv-Taϫu/tCSd+<9e%ϿxK]? | oՒ}u=U-Wߨ~ŨDrie Nks^ MQW Hn4"WFoNܐ6X@ uc d tnek_ЋטEu(f:@U8Ҵ/gWT7Q5󥗔H8\Uźlڪ)?iߪz_jpݒ=|[~y16=`T] è]ȕ== ־R[eQ}ھvճ:8ݔ+Ҷm[K3JSӅ&}$m۾U1'Zi?|r۶))9I> k?fkkÂέ$p׉wc!E6}2rYFPnYoV{O@%W{}F=7}:0C{wkO֮:chZf6nX>}3u ^ӛo/:R3f?Ӧ~C+ګYr{U˺;/:}`.ܭ%oOyNW$7_̸Gw^[B;?q}x]w re_/WW{e:߷wv,׿Zlyu[H85+ךߕ믭_J+uow.YLk()֋yY3TwtH}*XFi;^.'IjLS:i% $_-)9EC<8:G=LLZ_y޲OS}e>7C_Q`M [gn|:4%p3:ty?tof*ku\J 3#tqmtݕ7A\űn7ڍ! M{RUOo ꬡzY54oT`ȃt~=:vك%#u%v]:jctPDը>M2]8w"^Qۺ;/cO>FݠG?lGRwzaJo{SqN?B]pm0ە մg?UQ7hx$bX/6 Rhndg>Ԏ*IWe^dA׻1r|)kM +u^SQ߁qeg6ܷNE-9$No;>Y>'9MߴI$H򧦦I)v;u !]No+nڨX54u}q*v3%O?|F)i~ɧv.]sG[m7|v: sb2MK~_߯˗+?@Gyzt,UիgeZ@^qp|FTE{rdOk3kC=uߌpOe*[9>f)cwܥlCnP9;6kЁmW%٩ܣ:eF w[,Ǫp|m#Q492ڵBU0|Avlب!;-zX_?}S5kqu+3z])@[.u=lܴE9aRo[ vTN2U-+wCUiҫ:- wkۦ**jk㦩{Fg9ٛw/oͩ>:RݻuoNiiMRwc۲muKL~mfQNvVhovvxoVV8/''Z\w#pqQ GH, V,bFb3EQfL9vLr$T=8~_s O6oԆ9@^&IѨfϘU[k-Μ={#lݦkV+77W}U׮]*)m۴zZOOWԣ{7|z$çޣSu9*NU )W^+!''#5J $4v);ܶm 9)g U{iWNT~;oGRITr˭=v=v`m[;uRvԫW/+ʶm%%%) g2jd^Tw6-"Mٿj݉!AE`>I5zV4eʫu'V h&DB CkعP%Ktx-[ZD-݄V)TTMI1A.pDK7䡑^q14k4B IDATk\8g,#3S޲GJeUMY-sէ߰I{5Z}M}Do_"hs_RYSiF @cJYI`B8tB=zh&49s(#y͙ ,]tQ͜\ynnXi?b*-۽Xf饗VPq:@UegoTԯ4伷`JUY쐮}?t}e 22sSN}EO%4P[Y/ҨQ$IW\OfR,v7iJ6@olE5ubyTO-jĉuݷW+k⃋ʕoܘ'1cի!AePHSs=G WT$)77WcǎI'SO=E~vgeXh\ݢ^=S.ILWh ?YÇm:ޚ={Diټj=dq}I]461νqalЙgԇn.W>c :CznO?_K/Մ $IӦOS^=Gs{gzj,T-#3[uzlUTԩ_Uَ~S}{,Teg,О=ÆЛoS46kЦcKHBZZmڱc~^)//t$~HRe@mէߐ`CZZ,ګ-tɥӸq?]w֭To>}5yK喏u_jk_$0%ŧ-M:Y'׸q4Kϰ3zꤓ?\Sw1c?}-I'uգ8N 'Cq_jڴ h̙ӟzHd*0mWWVѱ[͝7Ώiz|8gӲ,S7l$)je׷>U_xզe߇K%Bގ=WsVk^{VTC|[+pmFsܣgr[6otL,CYeyZOW@a=ǥzayIs9DWt+_*voKz*:uJϮx^ɐi㕖&I5lX/NZZ9"hY|y" = Λ(pμ'YF^u.k$sݿ~ærۉy}m ^iGs~V%gcK7}?T}U>>/h=<tAێ(H233{}kHyyܗUWC{^WŲ~!A߾}[osϕ$zi9II'_~YeY==5uK0u x}(LHy7ǎY'>lYg;S+]r?~ "˲4h`M8ƲhZNM@[W|5mIte5<uGjʋHRΝ3Թ S]0@BFϓ!&F 4@BHWU8@q}e4ğCBH/ڴj;ʀN$PrqǶtZ=R(uJ ,[6@`:7 Xh] X#F ! Z‚͂U[.x DH&GGm.0M8u Ė!A]D8^Tgqo޴[$CZ>.8mv$ %DM6[Ǩj_l޴ہC!A[lY@B0b ̖n@ ̌;jJ) uʩ5zoHkĻW@c úqںuk<5H$2r) W]}Olk  P#4'‚##MiAzu‰'_C5{ZՓ_:#uưZbEx訣WRVVVi1ctءֹ}\<0【Uj9+W'|?='=Z+}=1q{s4!9B_B[/E 5b=åZ6qg$H5] E8DQjeﷶ˲Dkdd-(%%Eg}~1z啗 sQ48gٶ;Ow^[ƍSRRF)=V:gB4$jÂ%+z(ձcGImY:ב{@ݺu+;;;~u0`q-&suW&@w U5J6 hkp8,|Ϟ=ܹԥK?_[ƚutr7րuU,`ka5l+79gBlIІ58WЖu睺׿>}25y_˕wM )}ZY?% ̝7_CuJ h ]`uk]:g]e7֍7u;j2B6hWo}  4'IB[RЀ!#K,6ŷ|^!pP+OUn{M-Ԓאy}փb*{  Zs(EHPM5zՅeˁC!A/Ntr P" ,uXUGk3ꡐ5[PjaU!@+@h|U-vX>ݡ5dHGÆ ҥ{-ZHeOք ԩSj@ӫiA}[Wy2$XfzRճWO=CrWO?^9Scnj -Sj[̖n@}YFvxܲ .RrrRR5xIL lX *$ڵkuG=zÆޣgvNrpH|ۄWyv$~[?ui?ܧBIR^^Jͩ T%'uuaґGM7u֮]Vcw4ƒc?nvg?mFTfr8=>uѨ{}=z$Iy 0 vue 0m;o~ӔpμeYog{ISVoY}>mdMY˾՗K64sս {U^wu瞝!͋7q޼ڌڭaPNSQ=f9OϦi{+{NB=nI˯hܸNzaɐ9sJ۶{8Qp8,/IF#JKM,KVێx!OۋcR{eUzLQw77$=$WW_;=vѢ=K@K/)=th"QyfV}DbrG+eddhݥeyyScY}neTb]S^Nb{c ׃ Æz+mK.H~{o^5j*XO7d/I+))O9E>:Et%;g eY4poMm!|ㆍ*aHhĉu͹$o߾SO-ܹ~eb\fh*kQ(d3JOwgI2%KII%ǎ!O'ؽa NP:5Oku?_K.a:cPMڵk-M nZMҾ!׷o%L{mJM9 fɭ úqںuk_Ѩ+FiѢZpu;K [XZ7U .N;XgP(douq=B͘{MzT]p~a3]u?a|34rJ u˸qGԢğo@HP(wh /4\|-^бԱԜt ye8l-])t=vOޛmiӦkA8p}w>cpIP͞=V7?H1lXQ9^z?:ctu`ƱcCmkDJOOoP^5 Zʒ%Km*8蠘Ҏ*ˮq ˟?7}VZO>X>X>.}}'3f^:&MzH#GSkwK-^ŋ_C?zH4tٺrԨ uXF $(VqekUZC[nQJJ>lWc+/+%9眣h4 }8gٶ;Ow^[ƍSRRF)=V:k#++Ks|'hu&:Cŵn% ЊuQd[%*Թݻ,֭[iٍ3m"?Q|R4#'E Ҋa4.];a{QΝ.]46nܨGWftA KX8!+wgk3˕W8os>A'hرc۷Auy# @u睺׿>}25y_˕wM )}AnΝ;u)ۿ~M@[Vc]vU:tw78Z78΂/QO7H=нe$A 8|@!C# V2DΝS{\ue[h|n$hF ֆx #e&Zt2xnm+I4)B:(Dh@s ڢk_n] mI‡ Uh I м~$h{ʆͅ$ *i0$ (n!hq' 0J@@!$thUz-ZTn@! @rr8?$p#74SM}E,ՏO+.]b-.6ʫڹQG5qnuTZD♫p# ku!-\^ߨ=\zcpGz5*O7; bBhzO֨+ JIq+sti K$OfD]FOsHD H2F@XΧ^۝;nfkj<!*h>@UN؂S+W5^:Ljͥ{/,\@?nPq ]f>Ֆ[ܶJf~aHdHO֫lU0hڴtzlFHP .,Mh@eQ1IvB!C@I0JOwYW_OذF^LxhXZN߾u`zA^}#q!B,&-Q@:"B By'E'\CW ;}F.8[DDHdL1p啹Z$Ieh ͙唖]Ѵѱ%ǮYwif#&s+ etPLfnmifcI>$uR6hMIj(ua$A-Z h>$pk>,\6-zJn>$--\`o!ChȐ!;%Iկo 38ek6x2$0a wyGK}$_P^=4{lѽ^z@S$wB-=쳺?UjJRSRGkjEJNJR09Y^|u+.Z b,^_oh<&Aaaf7[C $mذQ{(-ةVZ]cm! p"E"=6e$)??OIII~X@[2-n͚j τLz!9Sꡇ֋/(u& IDATe C9ܮԬAyO˞L߰)Z岪\}\i{%ۍW_mZ}ikSzߐtQaܟU=&Λ])|bmP&M晐*ioԬY$Iii h4Y`A/Dz)ze͝7QAyO"޽\\I*MZvt?G׎JF @cJ kEat322{wiY~~222j,`qBP 5 }4gb49b$׫ba׫_ު['몮9& IP9&& $0] ];lPk,N @%c$*qm 12?Q,DH@L=PR$` @!؇Lv .nPc!`?@@FHPk&4Ua@`@! 3.o⊑ԉ]MC jöZFcqBX I@/Nh I@ 8aшɶhѾUgjX 6A\Kǽj־E߅" 51p̱F@qiCTюS B*]f6`PZuܑU^Zo;34Dm͚9=fq*^pYtMbas8Z2B(==|]Q"C{^7|xII/Y M>];w?=أJ:c˗1U,PI>FXGF',Ծ/Q7D_E{կI/}u/x~|Ϗя|1Q 0YܚN^ckG 0YlToOwQ"C{E^wz$^W\vZ[Z$I}Y◾81FI6tP ~j1ŁcD? д69IzqΟ7tYgkG[w~Yujac٩n\ggVZ믿^䜓yCǍ1Cەr.qUߧAP䉶fM%wDw?VnJ뱱g->ݎ12ԁuWI4mtye2IRjkkX)k֬BjQ[XuhQC-ܻcO\p7 ۮW O]]4rFu8!Nx7=VIEÈ87z 6lh@<\>߸}>yI~ojݼt{-]pхڣ.TGGΝ+I…F<@n Yu%8M[z7oy6ZaO8`60 +bܩK/KGE{B?H 1A_HNHh%'|qlEps/P! Vv^0 C % 0D0L(^pqS5CHaW(eٲΡiaAxzMf*A)!&FN3Wm JL&iD c6H / (\sT@CkwQ7"1֫PiBXrgsK0!ӵ(!Avaۄ& [fjF(@.XHS  Z ٬ٺp{Qi}Z|gϮx &%gя u3 ~W%Ą7|?+?9ʫÎu]`ZYkuwЏ>rG*v@(VA@9+3P/ }O/תU.SKK$鬳ԗ@R`(Po% \two&͝7oh{v=#86(T |L)y @%6$8J) ILvxl,Z4<ظ =?ɣԀQ. [-&X $KbCrs VZ5l]߸t,F  Ј;^?ć#S)0(-GKYilL.@>BJ:\? &j2hLtQ ay&`$U8~ɒPфGn@|ٟ|P!AI A!V &?B S8v,ɦp$4/ # L/@CIH, W$pb0`IKơ]P-' \z}H'V]*48cz*I…Ln;w.a#:@tn-5kaKΝ:q} b[f2(w;KoW׊߬}g'/uVZ+k^ۀ08!cکUVk$}ssK?~?E'񗜑0zƲqcF C{zv]˨FӦj0ɰ8!iNoh$5gv:4}|f!L*ţneE0vtP>m$`1獼@GGZh-74vbr!$IL.!Hf̰匚7>7җ_/\XUYr Q7JbB✶nMku Rwq7mj-_S-3'W3sUXrmBq@@${t׏fcUc-yەƛmnܽAc"$bBP߮O-c;@tԑN;=jiiє)St֙g'YX0٧CCIsڞޮ!hdL/@~M\K---Cۙ&uuG.^$H9yޮƘaŖp¸84Q7UfK?g|\zh肍/n*W#+Xci{wyt/mcUߎ=V߫{L-.BCӦMW>W&$eojʊ+"KH0#Q BT5+|Oԥ۵H{ݢ o|qӰz/nd9_ڐv󽊿gDL uths%IݽZϢ>X:X=b@  )|a-^e(B:RtKyχtěY%ѯ4Bux)jOUW]wbv%;IPMdfT}?JPznĭB% $({ܱ%wwweh;Ԥ#&HSecƌ,n}s-BR% $sNk1fhұRpBՏUߧA-=唅Wԯl6TX#+Xci{wyt/mcUߎ=V߫ L-.g;QԜڱ#5f 7m ~NIf)Yj[Ӷ9MLj͙ה-ܒikkKLmL1#3yY3fC;:;u‰o$ZrXCp°}4߽d28ۗA.X?T{~{|P;ҡa%2؁?;@9 G::7ݽZϢMC}Բf/6qYJ-@{y8o 9Y\z C̘a57 }hVM$ثsQGꁟ٬χtě$վsںuwux_@i.$8]~wko ?Gwh< /IDATrFb:7f!3ݠi[K޶1H>|9yG+7u@ jjLs\ ! I7ݠF"TE DH$@!$aA9 9E'<j<,yYPfDL$FL JG$źgD eQ7b$u $%'uȪ+nP!A ` 'Ƒ0,yYPfC͒HL7?ۀ#$$`<@BP@!@HC\6yYPfC͒%u0 $\HꂐH"$ b$ C򗿌SO=_퍺)m۶isaM(mٲEJ@o^%>$CLt .t͵gѥds+_њ5ki:Cn*oZZsOmܦ[oUg͊i(Zo|v?ԩm:t(D4a-_ECjmn3t 7h=D4TgsZ!$=7&^Z#s>9~)SDwܡ=]M2EzǺ.i(wܡzJw.߮b}+_Sηnz}]jkkӷ]u[n*3Hs`A̜ruꩧ'-_zAկtUWaYVw}?֡jvA^U+AĭC)w*)JO|BwcluP$^6I^t٬ou A׿5CrQ7` bNUt7z5> ή.?$myT'{th֭W>$[lt߽ .uC쿿֯[?l߇>[=,}ӗ`մi5{aO>dmӦZ3H9@x?Ss'M1j2sR^*弔kJ>]wڹs_Ulx۷wjk6M>]W]wN:dM:u6z^yUOGydfgjmmvG;vŋ#j!$ hB}!@8 Ol_fl__l|>/aΆu64A:k&2)9iA =;ԓO=U)o?E?ϕd4u4u( ZqMK.Dj=3:sw޹ڴy"V\}k>hڴ6wyCǖ.]^~+DZnI><]O .ԬtyjO6\Nwrjh׎;9_~\t G $Jm9s $1Ko}[|F3gЏ[O=Y6bPZ]zkk莎iR oЉ'U;v+:֭ U*5V^-9a:o?E%Æn۶MY^e2mީK.]p Yf|Ru5AHiӦO?^qnA)Stkumc>1]ϨC7oֲet1Qkj֦ /Pٹ]O=.]L>[FZ>k#gѲet96Q"Ϯ[0tɥOE^Ehjg)W\.7+bVtzo?^q| z ߾ fSZ}쳵|DG?3N?#RiYk./qH ͜9Kv7[xIENMutlՏ[sAF[3>KtICus$5^,a HJIf)Yj[Ӷ9MLj͙ה-ܒikkKLmL1#3yY3f?ԵcL*yFU^xy: Zf݂hj68!,Ym۶ۇk֪W'|RDB%J[ x%S= Cxsai3f殾흝;lOwl>ۗA.X?T{~{|P;ҡa%Ov2 ": c=FW~ʒSY*s:K hkvdmz` "vG&ިYP)U37j<,z"$0 _rؾn]wnO",y_Ob 5KjL @u<)˓XOyts)/r^5SINMiJSLKg2斖T˔)֦);b!\VK^uk>񏫫[ ܜ=yO١` ,СZf5Kr5;SYLU:o};駝QfTMVZoS7 IUsK'\/fa/r6a> 0g: CYc5ah}X74|qHHPCSN֭[_~yE͒%O55j|5KjLmy HgLH!$y-\HzaÆoaKo2fC͒g5[h8Zb,yY2n 4 <0Զmۆ;z*xz't׿|>^2t.L/<| Q$mͲ,5 ^gC͒%xn.`\!H݄a뮿^~3fimzm˖7>[w}mj~nrãfSM9jΒ%5Km׿M |GVevd2:m{z`Y3\%Q5fu<,yY2Q7qFH0No_Wܼm7+fΘ}zI=vm-5KEYPfD]:( 6oެa}zPO>BCՔ)StUW~JR[Ԕ%5Kj<,yY2Q7q|.̜۫9SM&wz;ޡ>W_}U֯wmp[t3m뷣YPfC͒%uXBn@H0===XK,'/Do;DtuS1%5Kj<,yY2Q7A%$$o;A1>sߜ'~*5Kj<,yYPdn⌐`6$i=Х˖mڰ[lQooxhJfC͒%5KjL @CWwZ~^RJ_%I׶h:sɰLPfC͒%5K& 7~E #)%{dmjmML62aɶ6g^SK7dZZ[LSsK-2-3mƌ晳fΘ OP2h//wީ7zx͛7~TSLy督O;-D1j<,yYPfDsaig]};:;r;;;:];vٞ|wws|/k\6~r yvCJ տ>V_q_94c#-_\7xo ,eLԭnl,yYPfC͒(ōoMtg"M3N?]xz Ʉa(I5Kj<,yYPdn9IF߷ICѡN:YW~ʊo]v^x:PfC͒%5K&o+I~/Obb=9e\)ϥTy)הNy&2^:J7M*Ne2/ɤ[ZR-S[Z[ZZ{7֦ͿyMMsIV~w?]uU:>cռyVfC͒%5KjL H N7? l |e 0Ά&sXgMZV8<' Η=0$"!>$ $W5qs͚=[s!X7֖PfC͒%5K&`$ZMz qC {HaF͟7O߼o7{D%5Kj<,yY2Q7#q*N7;$úV[Vs1e~zumvG͒%5Kj<,8kJBqow!h-X7fC͒%5KjL Hy^P값Bvσ 򯭡69x^͡)T%Vk\}\WGpn`ԁ33ʸG/qgxBټB& ̇1N3a < &=ȂE<'Ycb3M.glk&il`J;ys6 ۫T,a~>z{{ޮ7s 6u55gM{13w=&vM7-(բ=и-Nf'u;:Yg䤼Ϧ/4&Sht\N\xsa暚Zj^jX~6rþ>rl C &NFϪ8yN&i kHPA 56*HD rl|kX& kBY5 "5v,mH]A99zg>ϙ͙x^:z3=r^hl}.LŅ.4 ]m. l66^l{.\lh 1ycVƸF lnPh0 p醦)4{Vy/4 e<}_ϥ r XkC7MiNgJ^ uaA\ޅ䃼 rqahBw^|Hr@>RaA`w&JARX.(ok$Aj:"L&FD "$ ᨇWQǩPOEyx" p ;IENDB`sardana-1.2.0/doc/source/_static/trend_ascanVSascanc.png0000644000234100017500000011564712174204305024650 0ustar cpascualcpascual00000000000000PNG  IHDRsBIT|d pHYs+ IDATxw|[l9q6#(S@SVeU(Fh[VP(P:mmA)@X-0 Iر({=?H,ԯ3G!P* ԇLKCS/JiN#lXfɒi VCTȶM}diRKt5P{&0[4J@` ReȲOpz.u0I},fP֤mIYMaۃ$cc,eLEo%0 XZXV}臘ɶ5 ԹpQK}*u"PjT&x12yKƒ Y&DrB%:ϲ,SmٞjO]k+RVJ]I6ƳM~m#MȳedLp{%;)fō,+f{e;p%Tx:Tnv g|6^1^1!yAV0`ϫ;ee,cٶx³,ۋqϊٞe'RKYWmٞTR됩QVJRN 8!/@1&`qd<;`2ƱW 42LJ}KR𬄓ىO,IuTR[(Xr{rVfOm,ZJI>Prp Aڞmr]۳-Ǖ,!p ϡ2ɀSJ&=qqlyV(aXX',//dHÌQ:IWTi^0R@)p)\5InulXql[mcB%J `R)ϳl+LyN c,˱`ҵYJ$=X,hmm vu7{*I;&a %ϳ&O&U?-r:ns=[/t+mucmۮuzXlcyɔg%NRqud2elI $S0)Ń2'LAmjYKJRj}R7S`;:!Rc䄂c` 0u@s۱]uclz*<%)+%T"aDIvKRM=tHVZrmݺU/-V(Z*wƦ>sZvMx< Mw_ >Bx\uuuJcS,װ#4eT\m||o-֥j3m' %NY*uEjj%U]]X\UrI>[ZpA\K/~_ҩ6S6nڨ[HubOjkeYG6nP*5S;OϘo/uz?ۮIvmMMf9QwFc:탎RҫkʸP[hͺ*/_JvfeU)'P]mM&q! :\UU:dHo=4m[8n>霛4wkϾI)]_*t 9yw:^]&u[?d=KwׁGn}5ֵ=܍tM??+WuO}ؒt׃ g^Sv/ x{moݲEG赶~>bfμiO>X?v[TUhs}/UTUQ2KiɇwVٖm]y5ˮiEynݪwEuUcj]u&dce*.]ƒ%K1U\K[ԕL??=ڇ蓅zj uw˽9JkuV?p^V5ݼVjKܒ?wV9JE[Z쏯[V55-kkf;0W{/0O'xxnk3 /XN{~h+s*GuOQ.cRj͝_R_9&JmZ3&I*N{f*RUejvXtRɶqIR~@JR- uRJeݲPD?#Vk/zJ[)ܤp&ZU~zzS $S ZÃ/-qiDމEZq˺.PҴM:1Eg*}sB95o f)rtGc~xf>J_M i:ݳ(y|iV*P`wM1e*/_e=Cn;C?gn|_:请ޥ˪ԼV|͋ӭwh‘k/ѣ=.ݎןP[ttفQ]MP{3Noޓ*zjmmB\kZX{A}dKnIRh??Y@ /ҭjjj_x2)'o{_{uz뭺?.?^RӵӨzͳUV9h(ߖ39?nPP {dmN7lƍ5>[m3LHOw8sェlq]!Q"ˇ @5*Ty>}I-Ku旝BuQ9RxtywƓհ6:.7M]jT[TsN.]ߺFNJ5eʶ$5uU#}U"V NUݺ M8;*zY}M,I_E3&)f=ՄcIThV=ͼmumnz^lL9:yeKJ&L2!#/&nzmno?k*4)"G黷+eGХwjܡ3tɣsZc1=8!Ϸ\՜GUUex[fZ~:U'\4I^=3=n[?뙧?@?J斤ο|Y39{*ԠZYVRo֗.Q~~Nv.tdjnM:Np]iJyO*ִKyZnp}r]gs;оh[FɆǤbJ6mȪP,6׷_{Og_6KiݾK׿8r/Wӆ5t,+H˒C+(זjʪL%TSVIV@Aٲy5rgZzʫ6)֦$+m)Dk$Kj6,ѿ_Ǟm ʱjU~VPU_W"PJy+IcO[۪Z>/ξlJnZQVkil MC݆Ԩ_꺧vu\U_SLW/ӲRmNdV ?yo+ۢkVYλhClnԥtm`w}|YV(It'|RO?f?닚=Qƛzs*GuT^}/TɫzjD .sM8NA;DFhXU~|e#qT8x>\\'DP6iSUGhLPdzoGtCkU5&fN뗼YZy~F}W-gj"d;alY\OYUl۪-6w g/[-}tY~Qӵ=jNzGJWd|$r_JeSSeaW?[E&ʶmKϤarm٪EϒXSm:aÆ  +y*ҰaCtr-;swz9~z=T'w|OgθJOФvjgZ?NڽT^5C_;PuuWj6l 뫿Ό?+uUy .ԑ7^I\}&深SiQ9k?뼽j}I$g>Hhb̧zTgS }{)I?[u/-kyv!8%gI'Do :vxYؒgk7k|"ݶIr=I5GjӺȯO7NR/=xkBݹ`^s.>jR+?׊[cj%@'?ufEmX{ߩtmեϯq'|ZzbU:㬳vOGog7\w$yS^(z'L9/?t@vCy<+ 4+}vӶyqkԸqv٬u֫:2ϗ Hye*Vڄ ȼ{ﳷxg=t5lKl[YY|ۖ-d]uU$bu:/Kz]ǝTNv,kݔœR}ghoF])סҺ+⥫P=7*,IJ&;D j®a}[5z`"КTD8iveb 兴~:jha&LcF+tssf4x2ߞֻ˕TH;yN`,ҕ񉓊4fK~ |'??~QqBa*;7-w]Wc|VGB @ cF kƍ._^8ӠA4H첋 *# IDATk*oT?_NA+K*߼A[+b t^_lG0t7HbdViʔ4e~ju]1BC ѸqTWWd2)up8rLJuiuח~m; T|ցRo,K@@!C!Cz}E>8JeJ2̩To..|?%r7N:Yk׬tJ$.!'jk0=otrSSc+Sw镶00$Nsmse%%׷jɒ%,KvnB]w{]9Uj.-Oi7t̡iG|5e`LLᵇL_\Nw˿-IڴVF]6&Tꎭ[W^oMYe޲֦LR뙿.[ʛ.!LЩ~O>O'S>e?Pfv*u}^c"O7m϶G.篽_[S{?nKg}ddI}r$e{yCR?Fy5cF~xMg*)N<4:g[gib$pH$F?   %Iq-K^HB\w4eʗNtghѢE:t^9:Gm ?2KݗMs1<ƍ  %I&jA`LC&KuQc庖Nv=r%F/ZӦQ;y@D3]BH}_ T> ~Pn7~߹.m[Hdb]cǍkqyUĿ:__n r-HjnU-NK.T^6˷~Эu @pzt1cK/|S'p: ˝jR\s9M>]Ixu\e&Mr]pan GNzuoK{qz뭺k;Ɵ=X-X@\r~Xh"͛7Oy'I:_V_=n.0`FK Xgo[C*it5VA8iӦ)Lv_{5]~r]SsbB!eƙe)z*zMQdJe СC%IHp(ۺU`;sSݨ|Sɏkސ˓bgٴٓ޲J$r˷mۦÇJ#F dT9*J饗^駟b}ߧD"瞛iӦJ5P*qcC]wE/[,y:oK.mto[|J%Lzt-Cs=G{NψGzJ%-%P8e}[O=FHғ ;TpEk$Z,WNCL!pDE.%BEi'loiOoPVȿľ/Fo_JRzP m=z>%1C#T@ekCr}-C%@V2d P D%t/*,bun , X3taL4dP Ph\9.v˞?/-TʯVX01P %yry>Ld=B%DK Ȥ 0Qw/o}3]E"u߂Y.Z> … [\o5@Wh]Q-VQdJe6#뇿O.O s|*WIXtyf HYB%dB%1P )-\a(}J.a@ Ԁ T ?+%YP NG@;p?3N=j*V깙.&j͏5ҋFK*Pj'2JtR0l LUT[[O%=#'?dɹr)Zx:(uQzͳ)I:miiٶ2 +'?nN2:묳$I#G;:]/|D"r yAߊFK%gمBJT.t 9$Zw d7G3ffh7tOTJ{3_Ϸ@#TB0Dt3e@1h)RYC-J"&V h z/\C]@"TB%kcs)!0 71:59W%kn3|*!+>(2J@D9&6(T2>;/\gZvyľ/*Jv >gDYݢRrTR@3>' > =tr2*-KRHd"O_B^{ﵸ|~g?=`m]x^ҝav ]uk.d'mْ~] ,Ju r_@)LDo\8{%޻+֛4n\R*Wc Wh•:Z]qŨ/Y'C%Ux3O3fT*6*(t9Z8$f'C:*BFӪ;y_@@$C%[/d=h}6,%4n\ȑ)}Y0ORr?` 9aoP /BE~{@` &J '& l@\qEYKCJJ P _@ 3omJf*LVRJuL ?T2.ât[{+&EZ]E=$@vCrR$2z:^IX^]E~2Q7`ςƀ(2a|[._"JZc1&F_+N}LZVfYG# W(JNju;DX {4I-g&}1p&TB`G%d%t4B%ox@j>@n!TBF16r00q_X襄L(Lߏt 'Mjqtٲ UP|+_t P}D@8[n!DB&*wyeB&˘S L>Di〹 1 2$Z,W3C l K%tr=@d'&@@|{Jř.\k B%d"𧬟di=B(yL z* 1?ڔ䈬 k͏5M#E6"詄LhA00*!㘬7^ۆe9JD }C"$RzoM:;ئ͛_ZdY:uWkذaЍ7ި/u5uTF}ɺ*y\O3~z~<=:+n$=Hp"I{ッSN:Yyy Ú>}>1Y7K΅J{キ^xޒ+Vj1M>\%2ƴ I̩YW_}?Զpi{Zm蹪x`+`]P~$fwGn;3ü^׵Wv枝;{|ߟBuFPf[YgBUeCqs*&Mp1MvZ#;'iP<ToDvMz޺e{_z70*kl_wh6{m/ _1֮Y=(/>Tj7/-Z4velQ6v=kl?b )8REkeP%KSBeq7ǓOx+^m<-nq_Xq.T;8k_xpqWDD??~?WUW*n~[o)Ҡ F?{wh X* ,_x?f3">Nsm J(;|Hf*㛿.DHRo%0Cfz4,+zYaȸsvvNz~MJ@j~Mi?K7*YJL3ޝt @N?TR,%*u" 9Giub(.*3b@vh 4BB% )bG p| Y7@nȮ,!+g+y,aʬ; /&;Lܗ教P@J}h ڒ.H񁒠(d&@yV.Dt{"\-PY;I7PoByK^t ̥ɶ.͠T׌HT#~BB`v&;vNNuˢt, S rX8&P*# >0S 25kM\H 'IҤr -#VZg+bX@egR9ѲXsh 0=Hhr93 JI@*@R+F[&\ iӳ<&#T jX숡N MFI}dU(N&S*s=MC%{]rE@Jfm&B%8&@Jf)A}u4& #T"3PD\{IbXDy4;:iԖt3|XY*؞t@J?< zﻯД2*p,M" FY YJI4PkREke@H@4G~z%suH4Gvۤ < RHnHe0s l}bRf@LvĹ/M+R90%»@dAC%hRtLQ|be%ML)Y슡N hj7Eݻ.hBtTXWMȔ JpIw YmI&0 KT+ce(2&&T9Hh $E)0zWꍶhMh^ ȬK.( #I5WN*9A2(3hYI@ L%HYJ^dW+^UG'o|`!z~Fe Ə<FiԝvgqF%!f)0[tS Xf0y8FF">/-.}J?\o}˞x3ED[޼;>rR$yW*Շ.xpwr>H[,*yN΀r $eޖXpdxIo}Wwy}\zIw䷥+If]{~q . Q'/Ldr9&N*"ZZ&_62qmEF_ZW&ۄJ@fW0',McCJ?~$ 1 СBwȤmo/ѣqq:V0`4@7a0iݽ[n椣c ڷ%֭ɺo/_>KY!2<caM P\ӟn\@!ⴍOEap](ė<~콍/* AL[޼'8%]qKbE4Gݏ<^8%]}c UN~ uLt_[ܤɡy|@@ODqM% -V/~)CU1AԇJs)P oJ0¤S޾eQz$X1!FS &Q,v(zm fDV[Xf*yNZ:cHF;u iGJrm`` [fſ˿Ĺ(G 7'tR|߈o9N…7#r MfUvU ێ\(y(=mh|( SHSGcu-C<~\o?3y4?}[5]~+i|n{||.ci;nBuIPi޼yq饗%K"" {nDD,]z\ F{{{DD %KW6m[N[dK:_)ݺe{uQ(&\9ov&MUGo遝4[(Ti7"z;]U=F-۫cV\fEbG\rE&VcuBkz?FwcDU |Jrmٲc#ap̟??""֮YO5mbɷ$@u*Ukmq]|[ߊvs寈__?cpp0ĩ/<6En`:]1IPJ|;oWώx0߉;/xg>;nxFKK˔ r宧oLmŊOmYdAOKRf*@5JIdP$twNch:NٰT&*KN+F[&]dP\"Pj#w`&&@ڙU*;b(.&I7Vf*4,}Tw,Ri .߻cGBLJVay 0) oH$!I@8Y@sg YI7B%ٌ@t44LUNaB%rr ±AD.ycԎP E4-bI$,}ꩳe$uI7vBٶuB&tqRhz{f)@*[f%JYJd5Xt @J.`JYJ@ M,*,z-Z.#T)xs,%-L ͋hJ -omd"HmjIn +JFg+&WMHPDhf)@ =':]1IMCnrE @,OecRb#bXo QS ^X%X6B%8 ifHЬJd@mњ`5\J4wG7>P*J`ShGJ@71R9gD'Z@}ۼC?o&TM7']@Ԫ@ HR?Ŏ(;D߰a|O C4G۶nza[ݗz^kmYvI@2YJhJ{Rw J4 'b'/z.@>hL4֤ JUC1}ޤKhZ} ͥ{why dP qb41h6B%]hRoEke5$TJNlAF[;ȧJrP%2MK@f/4+:ޝt "T/{h6}4M;P{W [Ii Lg1p@eT$T:*Axfؕt @J45 y@m#\NʄJTC1,Pj IWPSmIL4o0;v$T D@UF{zQB$`o^۷6ffȫ >x[zr9ZZhBat&3Lݺe{?|Qqu>n]Y6R4>)߱KSGcu-CsuǭQ߱M龝?;0]~)gGkY_٘ث|n{||.#b~;nBuIP\ чz(/9%l[:K,m2۶nBuƌ*u8ӣP(JY*}Nۤ[fuLݦֈ#Iu-*;~RZڷuUV(lu>`j5*=_^(*vcxOSg}}i`gߵkvvbɷ`5Xt uP#Hlۺu+Ȭ__?cpp0ĩ/<6f@u.twN]4;/xg>;nxFKK˔@,%+-{ wRSi>ZbE|ӟvmNij%`&jL3L9LGYJ%/bW pe@\12I7[f*4b#Ŏ YJWꍶh䆙J0 ͺɢ ')"zqODFOvfBJ=$2nld T*']@Fήbwgz^{m޽ۢhkشi,̡i(.q 4S & 6醴kO5km_{cIK_^##H&2J]7Kx,`Rq\=pH,^<o{яN3wݵ09BA%l+&]@DDJz+1Ώr0VoFGF('A$J޽-pᑵnG'$j_ph (Yaôۏn].GfR(DLAY3험DB% (0^v#10PI)%=@{t~y9IXd:uG늇"Jό{7lUifA1f)d8gq@K Z7>ItSŽ;v}ET?3|F6mޜt A}hA#t.y{+N~r㴍O>K7lQPFm:Ა)J~SI%nP +W_x`J&Fe$T=@ub(&oOOKh=2,%13:.h THb,%Fy T 4H& JI0P DfIfB%+F[&]0tDBf)@i 4@Jf)R{o$UB%/`"L, @R>2\H Gr%Ts@ uwN0S E,}hNdP fȋ=7x@ Ro%@Rl8ȮIpB%Kn X kJP/c y @V%]@mڼ9hRI?  mۺuM4o gd\t %T,*Aأ'"V TҬzr2\߰a{wHP !BJ>MI !IHrY; Rޝt @d$ I}Gf)0# ̂{ԊYJ7*Aأ:]I0gB%) 4P :]1IԐ&@*4H1(to J0K^1[}ޤK @J^1!d_7ڢ5jNPgfyԖty6>P2 c4Ju"P`.P &"P` +J0 ^1bC4=1#zaODJ@ jdI\6 Ft4;Rlۺue!dсRu=/?3k36=W/7FCg+JI$|T5}o,*, pYf/g@OlJ@(zH;M*B%@@%]EaK JY슡N o0?'ښ)/dP Ta ݱ#hBB%)TмH܅J'{'P8=Kƾ}P;-61EDD\# MfUsU ے.|o{[(`]Y6R4>By/~9qӴo#bz+ԛ}[gg޴4^Z/aro/V-m\\\t ;NСCq5{ޘ7o^DD,]z\ F{{{DD %KW6m[NN/=Y.L-3OBt)uIJŵϩx4õkV4mk-#ΚϏ;'iڷBz#So-۫QMٌ?j뒋/jʥܵ{]:ZF?c 9rS+>%\+V~5Į]c*֮)>}`|TإY7PS$~ ?+Xvm7(`|߉S_xjm0^Sg+"ZUh<7q۶n;/>ug---S^W]hiirм4ZBoim+VOSUoXH /9\0{?$gק`o7MHԇJE}|jś$P jTꏶhM Ȼ}ބ+'$4P &Z-##9*e9"y @uPku&B%R1 4P %sI7@eB%)twN*a=&T:b/gB%Ro%4@c \-0WťP <zФ`zmI6oNhzf)lHPFm:ᲐR?/lt} @3}0j .߻cGBLJ@fy1 HJ@晥xB% ,{a4L `Vmٟ*AES{Ů_AoTt ,vP G@ i> Ȅ 'T);! qt{"\WO=@m Xu&HXuRoEk+'̌J@CL$]zc22aeQz`F4I0S f&JrĐ\BW4T}da Th E^t#Tbt0 MfN\-4(;b(.&"TLYJPSZu 9,v%]@zz']@& y_gEtT-nI@J {@tmњt)4Jtڶu hVf)@+7`μh>B%hљO>9َq{U2y. Fd]wI6L;&\.#ZM3)"ZZ*ڵ-nݲ$ͪNE9S,vxѡQ%??ptP!;n%m{VUļy`0 t@:z5fc@Mx,͹~.\._KcU i'%]DPiҥ`GDСXd߶u7YҳΘ[Lpq֙GмM0*[ݗ=W/OzT63k׬i=gk_~?^-bKS٩7}{UV(l3{NP(T|R>Y'SK|[]&صkO5<8Pwݻ. W*5ƍ/}188wtYP3z+PKBwyq]w>;^wqmǛ/0`|(VX. Tr˒?*Wh'HZB%h"fP+B%huPkB%&TrR?*f@}ɘ@-I@- P K/R9̲~R*W,vP ']&T&b"TjmI6oN 46+ J5m L]g+JI@YM jA@ՄJ@nSJ:]1IQsԟFЄJJЌo0?'Znp54 dܽ;v$]507 Sh,+)4P T_7ڢ5:]I@ P B% "bep̄P 1 yI'+MԯKYC* 3W **YTy'T&Ƭ*d 5̄P ȌϞh&B%`Ji q̦H^[S*6P~Æ ݱ#Jh&B% \05!I VKALJxtR*.H\fKP H^ZBCLITJ@]rE!H ȋM7']EbGWꍶhM$R@T#۶npYs^N. bW p7* u8P Hѥo^w}•00#REkt.*#^t 5SrH/0c}h֤ JTMJg+b82@J*n2H_n],vP 1 J@ڌ"lF}!TaO0+y4LJ%hKZ?>yuOs=B~}_,]4mmmqEq 'L \bG,{ȦTzUW9rKzc󈈸ի7tSzW###Snff6io{osSNjN[]~REDD\#9ZP<ݶlڼznݲaz[w[%Ⱥ(=mh|( Tk}zbz+ԛ}[gg޴C]Ʈ,vM~뮏[cfcjcu^Tlu6s-O_.5bEK?##Goo:}um-[/h_pAaK,i[xIo_be˗/<~~o(Nwm:C#hݿ+V_9ܸF{{ӷ7}={no.:ވ8|_0Onn|jmI[G[K:c¶4;MjPoe^hC"چ&^7mhR?^+ḕv>*~Æ?{c~!~|O._:9q<{ݻ5'|ˇĈؿXBamXmݺe{uQ(9SYY5Bz]d\diF7i4;*^U Y8(3C qq~ Jĕ@v]v¶__?cpp0ĩ/<6ȋuGcUhr >яƽo|cc_w^u]ώם}v~ /)@qǁ-10Po~kiOE T+ߎvM7MmŊOmopO\~IOr˿x8*TB:\Mkmxe$$$#Iy+W_x 29d1SF?dK Af*P534t0m[&]LI ٴys|o˖hmmM̦͛=IG?b$㏤.`,jB%&TjB%&TjB%&TjmIm֤KI{$#II1HS3S ZCr4\ԇJP Ȥ{,y䑤ˠ {$#II1HkKH|3?ߌŋ^F']9w{_o a$㏤{$idd$>7?Jd_{m?|C|_x;>XҥsGCw3ygIFj9I7Hu|s=T T"SzM>K,w+^Ļccxk^w٥ ߻u7z曍=s7ǟ\'T T"SNz'\x}bpp0ȣx'"bGuUi#1]}nMc G}WKĢB,irwCczb߾}dɒi}>cu5zj iffϞ';<>u{Ѓlٲxngg|#e( ?,=4p80<8002thpxpp0F#C#pKy0R) * DPrārDG}#ͥLI k}(暈Xqѯ]W\qyٳ{m7@#Ү]=1{;~أfFӾ7uwb]8w>瞱###ɞOK/7⸥{4H\}5vQه?+W_W?@D=+㗞K}`oxc򕯊wGO<?٣122T@X0ضcأj y3hB!=yO]W7<Śkc}qWozGM|ફxX"ZZZŧ_ݱlٲcx ^tR:_u)3W;~} ^`600W]?3t ͛%/yɔc^jO2ձ|mx /6hH̟om{Wu ;KK, v60n$@cLC:Ɔ!qBS$f$alA2&8~c`Ď, }=ղzX!*U!/}:ܑ<.Xo 6l+p,Xs;w_.JƸӧ_;lذwڊbf:~l?cN,Z\z饕:UƠSL%K޺ ?ku˖K.p iF~زIDATe #JzPfZ֦|6ƋT"X\d}YK㈊Owo>&Onuƍ7J Ɖ=#lb3͸zKDp>Җ[Nmmx;<y;*pcP*WPD<ǡCm3 uu&U//\5C41P*h(#v|oN;:pPSS3N; Xf &LXUrT;{.Zo}(XW_ux%MU wv߼nA^{ >㦛n-[objRR @kzA֭[9LBe//oןvhoY;_rpE!?_*јʕ*9{ f6MM;g.q^]v28uBlټ[^}Qz1C*_^ݲePbpPL$p'a۶>}T,Us{pw9gD#;p`?{GTd,><|/p͵?ƲezmPrJ3/Pf/^QI>U0k, >baRDGUVݻ4Bf׾{5]{ݻ%:c{穮?KЬР=XڔoqƼXx1J}+?'SI%:?Y[oh767'R MO\ ?lx\Wq+[iFg0˖-1TJ׾I,#gx1Y$Iw 1ld3Qh05h5:kDcbcl$B!PK$wy4)yljD+V`Νݷ]~ebݷ" D#qۙ=*%K#e"[o.#bx%*Tڳ]0u*6>͟#Jas-rJ\q0kY5UeMsQ 'ݻujϻb)C~Bj{x&̙;̖c 3?8SV,^|֮YV+,W|=W_~YGKd(ٻ񦛘=*w7??k.n JEuAb.ڷ`5GQ1{1g*QY5Nc,d>f:wygߚt҉pWb̙-Ug$\2{TG$ \t'q'rp7m4揊&yueAGTL}֭9sz͘chT#3X*QY5MIiӦV)TdUPdRC*QE_D'L;٣ػn70w<J,舽a„ }n/|sAFb D#Q%1T)U@;Rl1G4*RM 1O %hVhjmʷoc^,nM%⾊ŕHƓx]]74MM'[C<{,ؿ>{gqW.%陽[J*Ja?vhOhG2jk u6vtt(ȆL mLTd":2Jh r3lez8j̝3/`=g3UGQ%1DT O>5g.\1bg. <٣Ra?f*=ߚƆ /K/o~ʕ+oWpT۰avlߎ>,GeQ%?{UVݻ+8JVys*iqc ?؈:?p?vlߎ%K੧~̝w~ΘQQR5꙽K2{T'?Ic?*?既3T e/o;pWpTk0McCF}dѣ=;w{߅_}ף#r Ѳ_ xHwv2{TT=8Gcƽ0~FFݣTgkY*B/]t.wygW'M? \| |xRq %{1{TL/2xqaz{׭[sɓg U#g-|϶TQtfcX*B&yb3OI%q53{T:&@QE_͟QY{׭FrR.6?FZ(Ϸe4RɲT&NDK$i}sKT URSSGϟ0TV='L;+{w0{T+,6Mw}KJϚ:Z Ri+|ss3Q)UGQ)=*?4>KJK%onxM̙=M͙S8Q%1T)URXbZÉ'_˨.)* J5P Zrt5h1ej+g#g=T\SYW"0hA"tLRX#Yd#" d:ԡuAd-u:mm(+,#S׏=jґbI)\Zr6<)_:DV v ,rV'Hke3SxR3ΈF86Y VZ;5tD "ڊ.-뱟 cV/\8XI(PqJ3F{F<:֚(X"yNIXD]Duhu3q:2aicgD++3KT7W5"%t,UR KX(#'pb\'"Ngu((9%%"""""""✵VDDXaP HrhcOm%,}Az9Si}zw8QAIĕmH„CieEEƹN) <ǙJDDDDDDDT8qb9MEb&E*c$(߈܉R/l*Lu[lNf !h8'!38OxX*QJrRhu:krKlPFKiϨl`i4׈T:lVf B~ tK6;gc_YNJ%' eY CkRW$Ȳ76eBi #*Riwg`IKEM6@wKhqN"oMWelcome to Sardana documentation!

>>.ŗ~FGReffT\`<Ο??gD"%$$bс7 MJ~~~nn ƺXW6˶ csVD[ϫWbNNNƠHO rL' I_:9;㡡$ovjj*(BYYYtt=srr._\YYI(22211ҥKׯ_/--?>9gojj%IIItNuÆ ]mPdv G1&2D=2ZofUrppp|}}1xc ^p^ZǨᒳ˯~jMꂖ 4&$$iӦ g͚H< jx;""X^j|DiqEnx?HЯp~$.9u/@S-計S\dt#0sL|.Z/W@ ٷ={6 ]H!иb癒UUU f0Àǽޛq#fi}".@ig?8\r*\!{*2UTcATbmb4Fіxra˞u@i4~;n9Ơ8'.TjM35&Irj˫IIIihllokCϧ665!\^V6{rҥ/>bxj4g /L y|\2fB?vsssQ--3g͛7|UлnvMJjᄏt+W Bm^aO*cc2AL&74&08pGb7##wj=FD6->~55btO&*:$###))9>>>:W_ڳ{7z!2&KKKJINΜ7lWcc#zW,_N'9888&f}hK87!dvMq>v+D=.I PחD117d`u~w"OHm,Nʮ[ v>x`Xt|7 (s׷a3 wjV=zܫ+7rppp 0B+hogTj@]m82$0fSz>Bnlku㴱htapppppp&9(۸#08888888\08888888\0Rgcq|`3M&kRXU:;mjowmZk&aÑaxxhVk1f r=yQ(N\T:mcR)i4Z]5i/_._vi}tEےR|<<0`M_I l6Y1؃Ty8P`Raw48vXHhhGGǾ}h d=Օo޼ ~_=#999 7nX^|ŝ;v->>|fVzz]}kמя@yBCCwwp=:gVo^1;юٹsII^'OtĔ8՝82 s\eʢ/S"E gY֒Y/žݻJK|ŋ]/*:y$Ҁ|tvvnٺwʕ+T*U```TTԷ{Kd ZK_c$6o5-\; XM|Ϟ155Zܳn>\cr ׫֖VPx}G^7 {1upp"^VVK/a~&%&^zGMHLV:888*9';BUkRL_?}?u5~xޕvSf^ cr.((h467774T*OOĄeߎ4N cǏwttٳ_###R ZIGh4Hvܹ}5&X~[!wuuppp)d2Ri6r20mRt4ZPd:{01@mm%KnhL|)X,gΤ޵Ut8T]qio5xlعa6.ޮH SgRl$꽼d鳦.'1; ..i</è!8sFu(333322pT*nZZy'I.1?!@t-xw䱱#}#44hH CBB] J//G{BV vX̗МCCf 5p&Sי3#uLb0*}sSO?:ZWfP J??N7O9󝝝~(!sny0ajb, ^` Λǿl]&B]ڡ%gD.wSj07FGٺHM3c|6b0FCMzM&Stth<$4]JOx?o6Mw˔kת^{p* W+#"bw\9KHXc/)-eBR-((!b)JT02h4办b/ 0I`$%s {yy%j ]@zFs/G>Q9Icג1|!yxPb`@ '5vj4(GD f_hH%}Z 72 @bOOO)@F>e` Jh_dsfwf֨TNB/4YT)͈7ᶞa0{7nZ-?OŦT" # SmaM9r6eFBj :t"z(GS 00PZw1J\P$BC,b"R?H:ȴZ ?K[NOhhSHHybNKʅcKqaKK q'vHjȭ D((L}S >ַKy87?{5m_|q]lt6樟gr޽j7n| .$ :]0J37osbyjQDK'%@`Oz mVZՠ1 !J:>`[o&LKM D_Ԧ0@BCCsC3H;Z7;F*rOh$* F*v"2ba،8~lZo(}-/`y9;KAuBʕޥ%a}}qfϿ\vmw6ԬYѣ蝧O:'%W_ݱf͜s}"whǔV.}0ģBţI] Ҥ6Sh%C"X[*PxDp(f hehTX#O8`bŊ\̝;744~˻SڴGR <)R^j۵K!2ESΔ$克os@1⒓S={6'''=-W?~ttڵk}9sFFD,t6Ļdax[lȚ\kvRȫ3ihhpXRdJeXD`apovyؐPd˗{5ԛg$'xMHӧ;oݧ4d=1 [zj]r5<<>j}}_V駟EFFԀW$KdzҥT?pʕv t@ l,^*QcڴiF̙?0nl,lX7[{`NiDD(MW##KGxEC|_ei4Ξ3/2RMŮ{=SO>,Y,~GO?8e\VZmjhk_=SUU^Сf|iuȑŋyxx]ň{ƍֳ)䬬,ߤM79{ 8wY3L"Ճy&Ag98&<=-Ms9fwDGx@K1Ɩ9_g6}rZ2(HiQ>ef₽V'˘3@ƝN (ޕs8\!s̮4aǎ[ƍxG.)ӧOϝ3 zdd`hnixUˏ>!$8XVnڴ zkΝ "}cC.g3}b08:Wh.jL J__1FEwi_@8Kcbaj̏N 82 c׮\DVZZu!l UHFb/] rTSSσ=ܸq{-痽t?^=!1TTT'O/4ig᧼988?yHI?jlmU:'};=sAo&g?<rs1vFYȡB. 8$XHH}߸WTW/Q˵Iu~ F. [G\'Xس@\*Es4 fZٹv=T00tBIǠڵk ӧ#A 'ǐjBEEEpHiTԘ#G$Ed {yy͟?? `^ca+)4-۶,3̲}G<>]e>?3f7SXhTo4T0t|1#_T:M19sɱ_.ؾKXyJJJ[[[l… 2)9oܰ[R(<$!Cu61y`_Z+4XQnxKcڔ m%kY.oT+m-~qV2 ddFcum6;{5sL lܸQ` $$$s_ @hH9?3sO1lHM\`1so{Aj\Kڽ`0ڔ*Z eJ՜g7(fOkkRYmd[P&>l$I H#I0yinhx](ʰl{Za-VsͲ|iS/Cckk_? .wjԲex& $`^ =4ba&vY=dGn'9!okd݂leEti[T^,(9>*T>M~ w:V~`Ǧ&=#hfl&NA,|}}[ZZf_֗[Vhljq&z|ZV`wIU;`J/l2>NngɆǀin d-qe ;::ic12/oOva4T)Yrt#`bP'c"Ccҽx$IwIn ].ysppppp rnPPYx?TD$6)ĄCP*-V+-uuuY,Zޮ5VޮTZ[[1Z-vFW.hM\&tE&yyy455y Fqq2v [`n"!d[R8k9JjM&ʈ,[xsppp@gkx#U`/#'|V[Stظ7|;6+;vRXվ}˗-C2D>00ocbb<<][W=!51|[-]q f86/hQK@[[[PPPLpxa00Zx2==׾Z>}:(gtttAAHLLLLWWG}jժ?h\q1F33-=Hdd謅 }G2Mܙi4FEEQQ\PoVW_ :AۆG\ 1h$vbN882ֲ x|b eR{2&ÔCis;ѽe(=$?|}}I's%z1 &#Wփ<0җt`fs3GFEt/)j?}~Z $ CCCz=c~1Be72BKbX's0IPE{!-m=F]KoY-zÐh&Ʊ{GR{‚Tz&(Yzpwg l32v7Sɲv.i=_F-Q:Yw%bi.'i}8mopbiB'OE\{ٺ%v\7/Zf4H{lw4ϸiQ6Iz1a9\MۅuzGqpp?{[cGΥt"}o^S%Yf5h4M4tdڛBm I N:K"8p_pJ*r0v[+ȁfA?9:ep\dÌ@B1nvjs dG0{qٽ{/PCD%Fj:6`;K$Nq/lp;66`SL4MSGnSA:t:Iynvvvvvo;e}eA( }e 2@(J  IJq# >\$bʥ) E h4FyIEr[;f`^;B뗖"㭣;)bry 0L~ի;ڬT{A+*ڰp>X1bA+6|fׯ_LرfBVr|Ŋ_~Ռb'!Y}}WxpMCbɶmbܹsߢR9XmFP(v޽|rٳDr+P(*jȯz׷ t*ɕƸ#QS[+)BXӖ,LyyyxDt9 Ffņ|~Dx8Ĵ93g֭[VR\wވȨׯ .U+WYreSs̑nii k׬%  F:\Zn7^C><<&s96 邂 tkLQ\ZT& Mf 4Z-}]~߻56]B \]YPp}FVu :6k$&^Fg C:$U:%i57Eݞ⺽`nΥnuw6Pԝv &`Pv9 \z*S kg|q-zku|n8km?ty[ ~Y__prP? t;߽{)Hjw:lc[FDLi"Rmߎ̹joc95;p>n'wm~r8ܾ ԙipuz[AZEv2)8۪\bƖ,x\wjJ2000""::>1QRRQ\n]]]llsիW!D"vTg2\peR^r'OϯopXlݝz2ͨ<:^t |gwP:R=~xw =-#M G¥t|۶m?ѣGG裏yvN{󭷦M:c g}RSϟ?_u֯mq1cdffzXdX'O'[$tG(!(ټ&czZ:bijjzʕ'#P8zļ#GT@fRzֶ O7wj5SN%~$ZyדO E}A00oljbDmc\VS2[,> T꺕p5:\߻d19~S[]O:7wh4bX  uMb2X߯_uuAw,xR>p[_023~eLh5P(`^/r ADZV-qȐ !,VH,h555 nQvׅnz[hѸ9l ;RF_7v&>{;vgݷЀ $wH!fX^B|Mu΅F.DFE}{geeyUeŚuCCúe<&::8$f?n3gJP*9pMWVVe~[Vȳ٪"##'O<"e2ak\\CrrrJJJ񑘘yH]  =E\q߀?zR"٬60Œ~ƃ.YקoJ0W__{wMMMTTq3S[Wh4]fٻ>g[ya| 5=T(/Bj t ܽ$ QXpdʴq 0h7ͣF xC Zp!\)^Ϧky:|G+gZR.#otҤ Je 6W,wKaj19c&dlnV{wŖ[,-[ZXxfy„[0pB~B1 ~NH !o3 D 鷏ab' *+Y4.k{kn' [l3^.;}-s~& .h\fsG˗S A侱mŝ3gۣKINv sAjjjg755:ŽC^73E:>4JV$՚-.>djbbɓ]|yDJo9KwnjR8x33At8Kc`OL&7 2A!vBg^g(ess[ni4ZD=u0ڒs^{i*+Ʀ?MU--F!q=2# $&Dv;ohBS Hl0Upyaa6TVh}|}^P >,m:S4M[k cbbBCC3O?bP(|GhBzZ2 \*?SIՓ yYF8f*$lfF5f.%ė 8 9Ail6-ΐ (0("o2@^xN0X3gIx\+DlLz;XH;wO$U]:%R! ŢQh?OM:S3` S:N ybq_bC`A2{={444u)ĮXBЂ7Q͸$7 sd%V 1J ziC ~鼏Ҋؘ SlTJwt@h FcL.D^0ms=[;gЉ;plw*f 6\EEE Ct:L*3gNm]ݭiӦA7|pBtt 6x۷;W^ 9#Zmyyc?yf???ȧgޣ4OIJNe <_x2 Sflh:.1=7]b~ Dfvh ӡVpmHݶiٿz57|sCEEE]refff\()-4uuuF4+;lT C$=657CbX }sR]]kc`+.)Rxvʃ| E斾.`ڰȈf5558cz=t\c\fY.D]( c _>W zaErf޽[є;GQ!N:kjkaSeeDg̀ 7o- 7Chh0έmO\lT_£ SlܬtdQuA=uT+y7n\|yqP!<.׮]5kd^>1 f 5 O./̍>23s޼y&44‘-j杨%K2NS OF}d|qA !C̘1@*Jx^x1""biiiV(0`ju_3f uax˗`}ð2 ==_.^!J{⦆|s^m߾;{o 9s455AoM†G.=Z__rLbl֭Ç<7z˽ca}\2A=@<#lx:^~=|&&&5kg?cn χ+sԨQ/{е`| De^X\^ہλ A_p87C#{RƎ5JAP[~'ldӀϳAI  \n^^iЫE<) o0j2  =Lg CӅu|+$ 2Lazx[ '8ĝ(gw*! Wzh|+>PBJz B FMm0װÔ^7MvkBECCP;w&&66%9QVA3gΌ1Q hK⬬,Xr M)*:qID999.^TTcFfnEA6۪qץt7Gkߡm/ ca)8~|qlۦ˓VWW c߾} ӦM{w͛ظkٳ'55QVHq>$V裏6nڄA0?jjsM}}D}c=3lxrĴR";3L:f-]ļ׿NpС HܬR OLP(@DFFhA$: Q(BauM AA;v^8>BK0BF020bBԄ|M(B ʺqm6Drh YБ#[nMLL1ccjh! #"@,Z믿xVho˖-p5L8qA2>Jf̝A K/_uB >@lܸ B|r\r!Cs%cƌ0a3+ɴvTOuhs᡽k. „~X.Pt0E.K6N2Nihhi_`4,dPZ-TF&fߏ)ť"H3QbhcFFu|[ugrmbRYdžF ί?| g]6&3S AA ĜpRcSS?ǃTHvmƏRxdW?g?~æW^ybvO|W[NN6n!~7ߜ0~|SscǮ]c|hrWZ۵kwbb™3g̙}w-/ 3qr:CA&܄.a&Zm7Ͽ3h dA_HvC,.hBp H$P%%wkׂ tU_d\0cTáS^.U9sڬM7 w޼yHNNq&`Dngh,,2ꅐ e#Dh;3?2;5dgLib8V;J3A'?K75r<t)S>0a¾}' P[[z!֭ s't0 @]P/Ot$x}!3f$h-dNW1 _M>^׿ bD"Y : %!nܸtϯX⭷R(СC( jn`[JEػ$ H O?cٰm6ۨQ@yVzO~b2 ]w׬|>d*/~ӟD3fpN$FO $Dҁre" ^X BA&ս8WQ3RXXxu6>!!!'']|ҤsA;`0 'zn>Q+^{w HT&ZAQ? t>KB[gҡ63V6S z8ZwLb K: d,AWrH/cg(tmqر_~9,,+5k㥗6n ˿#GBA˷UcP]U0:EѴN@6[yy1cBCxqTF1 Z}P,_~ǃAA:K[`E "55o6Ϗ5c&S  JGAmU$}z)  ZbT"aQRtQr {tEŋƏ@mm͛|>MQ=X_ A,3a[p8_`u5I|U ׿9FZta}Ξ$ H  \NHbXyp[{qnw&@ACz8]( 8+?ͶFmfL\N6ɦv젱7f7Jނk{IAd2mٲuݺqP}UVO?l"hf YY]yXhXSR:t00(׏nob2ZmH_Ay@OxpMzl6LJ7v,Dffd#33'O  ٷo?ȎP_%% IOO]ޠ ,//;g/MFc~~KJJJGegm N hpAVK_AO'WH1@%r'>}СÄY l2Fကzbu*`֢s-]^ OU[[ }䑃 ڽh4eeҤIC틚hKg `0P譫A~ UwSK (( QcNf?&OfX۸Z yDDT*5̷*+jk!,juBBxD㕞WW/H.pFl}]AO_xJu7nQSSIQgRxj޵;77…._,c3v^0Gh@uzPpIM{ʹ<1r7-ŜE;aWKgp+vІ;P]]khyTu)<`;vnB55uAM&qlP(X`~}Cuk؁,DrGffBFEEtZ0y䲲  ؜H ~YW\ 6^&n-Mץᤳ]_L*-)9/׭[@>r|СcǍ9Ȯڷo߄ bWXRZ}k֬1G-))IJJ7n\}}٢Y3g}ѣG<߷d?~|||'OhhP(zh{be`;f%}|}]Vk Fc`T&<%MӮ!@tt30۷FN:%3353D+QQ ٯ IQP N9 랙6گpĴji*/JJs -ʝ0/,9s7"%eɒ%@ ̙3Fѐ0cƌ}wر+Vqq˖-;pmےnu9?^\ |GSN^Bh¾.Eo1⒋/R ŒҢ3a A7gT*KKlv[\l,{LÄ $aEEB>@*B|Dt!$Rjii^y\ o"kq`0جVV h;o3\~[\\ ibSRRnܼRaÆ546¾'Mg SLٷ!C`߫׮eGGGCx)@A\qKa[K223x[SL"4L*lʔ)|mݺ;w;6P\۲e˪UΨy}%d!S;HQ"BVa9|PRM]QQ, z}:EcgluA1Urs̙iձnB0(0ٳ-JcG v0u}||?ٶd6s8sO" nap8t^^.oܜ1;v(?fCK8p!\}hJ]cǎ䴙a )!abb̸T! 1cQcv~oljLfsd8pĄxu~3|ذtDr@7TTTEawILL/y󦯯OhhݻSSSO|ݰC2YC}}Jr򹢢+55 ,##"cfΜ3DA4]* fזz ˗, [Lev!-**ifƍmW! [S"ab(F!D㝭;\z$aPppǎQ0 | Qz8feΜ=[tGHmhlt 3>o3q8 10fq؜g r:Ue611džO>3n8 b#O ӦMgw9t-^5grW.z%!~̟N*lbP=.b8t`wܸ;RMnM  Hҩ i{`<^[Kx䮑 YaWUBA>3}@4i_?2џgIAx ȠSAQv0z_; pae( H;,ˡCrrƞ:u277鄄xW_$Nz铘$sInIvàA`6...11a]~'*:..ٳ)^ |Xm՞%ҡq6IۧDAr.{ה@m6[3gNOmhh WZQ\0\ZVV|W_Lg=NW+=7ПgҮzA^ù{uzd\KkF#|ryf^/J}|| l6C6566Ap8V: "^8DAoUU(B!ɪ qa_G *]-h֙ίiiWR]]5{eSwP]0a7oaIƎ'"%.\ 3gN/-)7o$xG%'߲uի[ZZ\uZL._dɟѣGíܺ|…ŰXUYYY}~CXR'N(gz cEA\ G}[]UKK.ֵUU$00tCIIIddի|||$_TTqUUU/277*wQQ7lH2vE''}Fc}}7_pʕީA?1-rz1O;~Djڝ+wgIǍg޷?Hp"P3@P( JKK5ܹs[ZZ>Æ5448kח;d##(ZPRxꩧ,fP  ;Pax#4MsAX-wr9cHdp&Ά7mbbb֮]KfOGO< ظa~%|>sEA&0ʳP4n AsPax)h48Ep- ҿ@ὠ@A/PY)Mⵍآ51ϸ8 c<0< w}8d "-  fID- F/fsuMj/vD,  Hahu*¨4|&G4R6b1q|m H_anܸSQQm32 _̘Z4\nkݡ{gUРP(Z3Y Ţ.^D@m`bDtxx8{@UUU ((6H z jntk_&"^*|ÇBCMV]SS[SO߸!H,\?pٳr@3vl?P(pqgL͝;tPH׿mãKϝ;?=P x_t9  4u&<\\$0,8~<%9={׮YC+Ƀf7?+~8++0ء5w F#B:u **777//b.^}v__߰o'''CCNq:n#/byfn/:w[o&&&~w~irJʭ[t:a|ҢE._o>V;|084heK*((a67nh'_4ibyy9#(g2I7%K|MeKK0Ad@Q&s~yI3'^tҲ6mTT$-[B tWaXQq'<ȣ_\fivN8~^ ֽ{>Jr۶m€>%%WUVn++y\T-- _F'M?1::xa!hgHjnn\p֬YAWT|cݱcbsy(8kׯïᤥ7Lvk A.CxUzRkNΘ˖maqIɄϟgNJJKĞ~~nM_׿l2fdx) 2|@ buTk6y<$ufX,61Mᮞ;wq H!$8W._ {l&8oBn\&S(pÓ  qͱcZm.!x*zj.j[U]ҢV=WPs? NԗfYm/] UnA85-AncJ(;@":6*WCc_]] #išIYW :T.' }+/ODPHrѲS)ʯ޽fm|~ݺƂ:3mAhH 7Xb$G|{A ]m"W:mٲ5&&66&#"¡ϙgmٲp8s' (%ǻUUλL6Z}m޼"&:~J\K%"0hVHN#"\wWxp֋/J{kʕGI~C-ZjZ%w+'sa@>f*)) 1cƌ(al(+ZZ˖- 1 ji<&J˿~ Y:>!RPPЂo޼9s̨U @:ƣ5~9l`U/€^=$^%W&C0VСC{96_$~' v$vvvDl #Ftvʃ|b_pl6{q̀k׮3SBpDj*MeeT HWBQ\u%1z 3#C_JKsX {챣G?wʺuȑ=}zy6[82bd*<~2|zA* oE\aݵ,ET~?k/wȑj.tFK^>7\6jԨꚚpP--*T* F# aHou_| zoV@DшE" p 1bl~?W_}60(ˏ~â_|:cŝgGQx'Ab箝S&O~_ >S 7,aA10)-- |ܹ'OJe2Qs3k8aÆ7իWnٲ0@hþ q%PO /@gou yTH:3Im.Z͡eK:t /-ZT[Wg44qqq͉xxr9| λBS!k,((ӄ0~A9[nί˖.[̝]2m~II… 74tgߪ<bwr0av*J8<޹ _v:N3 z!Ad03~(W趹ny%M6 Ψ0;vܔ Ljbh}B,^vͷqCu iQax)&=!S7{oڸ0$3#oJAzWaT j \gc5}z@ xU7d7NOA!>S'@A~D* ddvft:VۼẵMmz,O_Wc, 200TjX"BDbTUUF#?-! 0All0/N}ة;/(l&qN H?{ h4쬬c+~Z/J^nZcsrzwrsJrʡCBLee[oe0Ν{A-Y$==0  6](94͒9sl6GQ*_50?nܸ_|100tBزe 0:f=iP"n`lkׯϞơ;7""W=++ڵk|1._^^#P8uښH )}oX=M&ϟ;723ԩS \q/^|R@ tN[ӐW^  >yԩSЁax<^ss3 \n2JWK\nK J W'uĈ_}h/] i& P. 2@%&&ŁbPk4BpQee͛m6[dD 5͵uuCDRTTԫ' #g4WyQ@#ϟ?_ZRk5: &ny!`4Y/bBfHz$MMM~ k p@@0ii̓4ׯ] a>u*22 ͝ E /аK2j4|@(`\/BAi砧~1__ϝvAh4=PY RIM$~Fr,ЄO6_)S:t(((h[n=p@NNNDDtnnn RdN@` H pR\R2wΜÇ? [nOWT|ǐ81 rj& 6.nǎ˾*2 2P3sFT#!~…;t̕D +lD! Iߘ8qbRR򃃃j5 ?Fchh(@ձ#mtɝ0A*K )))A,+ ٰٜa WJi&D"7lV}ͷ/^޷ SG'u1{ bm#co14gӱm;6 \CCcUYIIij^d26N] |cìz lb)d/vG6ӟ;! l#VB9k?͛x%͙3'91,ݝv]Яq7m xѷߊϘ֑uk~%K+[Z RTC `yAHa tjBx{j {i65( Lf ;o3)ɂTj@odd*wB+ M$)` `?HI cv6kk٢;w67ϞRy0fiddb%6]C  ~_Ǎ.X\tL& ޵:wFFK:i#  AQJDοv P%>>ϜOMMkhP)ɓ @=+8,tI$ғ'4ӧO/8~drXTJcsr e4!  * o68fVK7L/222;VUURVZ*$%%̘1[xqcc].\fff2 {{dUTTHbXW_-_ " A4mdH@4xa.‹/NM8x`yy9ijnVT4#JJJK! ɬ  B.4A!!!UUU[n9~OAjDb8X%n;6??b^zں պt鲺7;qbڵgn4CB}ѷy'/7w`[AAl&űA;z4##qqqRĮa)2=-MW Æ xlXZwh brsXȅ F:\]'44t(~ݺCGÆ}hjȑ#^|޽{y<޺kA4mٺRN<:#6.W@^^޷~{ȑ5kpPa   Ki䂅˵Y>23 D3f8)SC_7m 'ŚrDA * ofMf>O9ݫFMy11V[^ ٬e`;_cGכLKEo2°RV Ս,õs9vw'^ <Ԍ~Y9hSC)5ME4|6:=b¸.QwOӷ4ֳl6gv)&6UK]ࠀ.Gl<ηYIQ !jh :pɉ C8|+z/%KǑ1z{=4v6x՝7mo6l\\R{ϳFA/tЈ~7CCC> SO6x_r7˃*{n>?_~t__߷zgV6v6vM4nQٮ-\ݷ%=3"Xv;|G! #tOaX,ϧZZݼy+v=gN>MӇV z^*"4Z.((`#+**"##ZmYYٌ3Ri}}CY`ڴ&" ޙ5cAegEQQ ț+*ƌ/8. 5F99~{wfN4\Ѣ ɄTguueǣ13PD v/] +WܵkP(>}AsA|YY?c9#0:E>>4Z(GAz xo'( L@m(B3AANH$%j$ʎ۠8@APw'8  Y \6[Ey9t}[A3@zzlXmaAπ ux<ެY3pIIqA 0AyPa  @AA  Hσ AA  =O* #m&p]}ZT!C{gy]i:}!}lBb@Đ@N ti6mLgH'46 %@Hp&@)8 9|76d[ֵ$ٲ- c%l> s}v<1<;;;:q`hŒ: EZ~rwhh:4]ݽ| Ceۍ:AIۜ`'h+Dݧ<7{UsisAǔcY-fWBJRA6jݤI+'Irpp@\L ZZZJD7l(++=:WHe2p GbbbqKdRSu͘uZ~r巻ȹAT0fURƷ-QQxl* #Fwc<9ETUh_׭[m?M(JA<.{=xܹ'O=W,xDH$Zh( A3A0$MCC9|UL%?QQQ+WLeJCc_A:6 OHHJAAӋC( FVV3,+yهA 0,gfPL|qZ2JPT*g 3rcdn-A?+ #Zӱ$fԘCsAA* !+ԛO  b@A$A  Aja6A 0lنL& AA* $@ZA$@A@A@A@A@Ax* |v(  O!m6@ GeuAGx* Tby1,fG}r74# A$Z^LA*bx޽.}5A (&A=0A=^0' ة+8yಅBQ뻂9 S<˲(1BưZ,`=:V5"2R!W9i!%b  >SFLCqq C~J\H$~JbaTfP(FcX,S HH0,$Afmqrϡ(===??Qwuw777xwF蔣˜"pm6;Ax޻woP4^W.^x$;:@ /BXgz( ={~+hsca ^!y޼yr-+;?TVVH@eg.zSgΜuBjZZCCC?xKKMmii1 9:݉'jkk Mb!Č  :قؘ7 )2:thŊ\rNw/]; I"2]ey&6矿|rJJJѣFPTW߸qcҥMh4};2cXv`p ! 0/^p_檮><<`0{ n޼t5(gffŋizBT_愷17l( AAq8p@HQǏzիIII5)͇Kf wB H0MaN۾};4`ޞ={232Sq_~ydݺuy ܹԩSQQQШ@k5 NL,8gΜ]VVVqbiZ. aSSSO:6pG[.k֬Ϛj  Xx@xӦ̓K,egg~o޶mt=z{-xvyrr7:::bPngAQc袢wD"/WB .\sssII| }񔤸ce.GAA˱suN\'Ąp/>jLe#|ruoO?38Z-ӽ*2G>loV Ac[9 n0m ۥK$LfUpju\&G̦w-)iinАD"VECX0 -qk2R)LӴlulܐYFb1̲KX|f3\ZNǰ|]Z3/ڵk8hx8F!HZ[[)0,L>q`Zdi#Ct yS?޹s'ԩSz>==C765y9a9^zuLL /^nF7p`&Y%h,))ٵkW1G\*V҂k r;?ݻws[YV^!;wg`T F8g{6-**WV! 2u( קT*ڠP(E"QMMMrr@@655AGeفh{###[Z[{{z@}A1JN744@SVCX)""`HHHxbXֺza:]xxxSSJi0h쏏ωBLneryUƮY&;vx'_#+6mt R>z+=D#*2ϯ{[8o uֵ?|(H{:?onrȑ D|E{|uhfF\8܋/x1P_>psϭ]棏>z뭷@Lb(˗~V').nTnظ!>.$έ[ݯG< 79]p!"'L geeqBfpNz&HkkkZ- X\+Cb4ܹsʖ-[&1Q 2LZi,J$|JnnP(-&_"<F.T*TT4'7ntܶm/çEZḏzܹ99_p9@ǃFk{v/븭MEX,枞_޽{< .\ඇǬаi&kmPP55bݻs[a՝9sF" ={ߠ9BFL0a L&MMMs^aH$"jkk-_η9d2>}zsυK+ CKksmn6P(̜;Pt-[ZJ%1޻+yv$4>N\ geBp(Pz7PTttjZVFlD8q#˺jw?}J:/i}{m|Y}K =pts}Rܷ؄FuXvr~Ŵ"L+ǵڀ%ƌcJx8SD;U<<  _b'/J LJȐmcAdR'{;A1n        >$IT DӋ AA!R@* AA|ȋgdddtSAA|UWW@AdHG{azjA* AAf=E HϔD  wU^^`8<"[ K%sAA 2W-UTJy*'EEW*YV 6AAY NC0s'=Gw[Xv][6AAqsͭ2kPIENDB`sardana-1.2.0/doc/source/_static/snapshot02.png0000644000234100017500000026636012174204305022745 0ustar cpascualcpascual00000000000000PNG  IHDR× pHYs!!/^lIDATx}|ǝ׻z !z1L15>kI.䜸;BދDH TP}nϾʾ"!Q ٙߔݝ~Ӱw^P0EQp0 ޾v1VC+G YGI`_ At됒`~c`}#fXB}=x17[A>_ yϼT#-Acx<2Al6EiⳑDOOD|UУ37K)Uq'o(!;߽{W$=>G묞F_j4;22 7(ߴOc/? t9(APH$r1 bDYX,F>d$lFD!'(㘫Hj•Tm9Rs߽5߫A} qQ*9<ʻ"f4| 2DjyG ]B>O}Iן^3ĕ3783BWsmK(ynY$*-Tg j`s @ w A\lN~B:&&l29|p. Pw~:LIDi[[;D[Q1LoZ n\8$D;R%mvjJ2= crNxP_s@lG^†X處]gz'W}s8T/*PNԫ/w }exƏ {o<}VC9wRiLAi@0l~xxWWwDD#7]Ѿ-3nțXHI`)C^/bg{uC\=kz-mϡ3q"Żq{_:C*9ؔ*+6ϡanN~r ptto[R/]b8y-K/Xv4l7P(:::f]w[6?5_ m]$F|tGFFao5ד%}k62Ftqg\n瞣8ƝFpWTx4g;SZ8я^Gy=.c̬!]S$ "+mJ 14t1'(ڣV1/ **Rי&Rwہ:޻N?d0ЇA"(:vի/\DQoLk[xć@܌nO8m\{ 07ݞIgv6NxŽ0?>ޒAឞNlap_kGt_\:'܋fwy_9V|r몿lxAd kd WhG-|h/WAAgvpd{S]z8A s?f2|uttމIIP[Z[h` %'..026k춶6c(ޞJh Wzsqa} :W\ XlIIIQW@uJ!p{ A5l|)[&O.}Y Üiz̮]tGO.ptLWH^O_R2\!** ۷o8fWn\@WaxzC(추p`K&"2 $rUGP|~~+l*JLM Ë-f3ABxS9<:Dy|=!1zR^ž!6#A7vyB^򴓳艇8'_HQBpQUUxhh hcbbLf3a<>D#F'b]FEED0 ^fA3_.٤~j90n2KtoУE`IS ا`]PM3 [ڐvg >P}K- 0_TC"0G?vgYAdY35}>hq?@`lf>ᙻOSyn1(}c`~ZYZew !%g;UlBյ:Fk I8@4_6 BL EPɛP; `Ql/ PM՟u+5dʾC.9mۯ[!y?;=9@Ѐ9;pvޒe80|ǺsWѐpXZzNĺ^]1+poSwKYlix^;jlDz{4^:UFx!Eu[n4g\f1ü!>]}tX x #37>8o‡HmXX Pc` >NV$e>QCZe}>:,>ܗro–\x(f0q6oNPAl{_,raL@Rhp<}rϚw,EV龟 wO_hp3ۇjt T$Y`*0BuT]2DlC lNrβƞIVxz8KL9*:٠%U ]ط~Ko˰$]"OgA?w$Nn͖SH]dxJ8Ow弢,vBaӷ_p kzDŽfmtL sny4x~2vESʾf9.FxrT-˷[xoN5v^ž䥎3{,Vt*$?@"d9"gE}/}lJg["@vqVK+DS%4|ڭF'II! ¸>r7KaArct o^"Pڭx!_ BcTWgs`W Q C>-t !Hjf* LSruSx8maNykp0I+ICYqFJ;>{XjDbl~ς(Wt] {E818~-m?; ۾FVp}po!1 B]؇X{{Js )6,=mkiK~}E|f-@Zdb@Q2`B?Q:C8x++gH!f"Uy @ЋoVA~\)ĤaP Tu"r(&>\P7 F~nCy'"i!ph$BHf,h,.́S8".#{VCO":M<;-$|O)-B0jefq ދ[ГspAs9kL& 4c8t`"2/*B!dl6 Bץ{{h=sW~ϙ)]1&sͽz*I_AIdd2b1찰0FkH3}'Ci 8mCf -GH,I $#8pNvA3L\Jv[5[V&ʨju5!t6vlLDdl[' w־FoD9Hgێm]]]GmV! @˓fA^t FRdz(jB1tY?t`mChq[`{$ꃄG 9e6fs}As:MkW&\.Af6:eXŘaiAwe K„bk/ҙ,"0K1%_R`($''o̵ٜڠ)~2cGg6mjk6]ӊDF MNd ܥЫ[=t^5D¶;!Ϊ,]/hI (Hz=wuM[@u0h>IBPh˕ 7R ӈJt0Hj48Nsĩ+ÇC+&Oh=Tmr񸊼ĞƋ;_hLtFj/M'Ii?Rw;44CzlI8D28sDs{WʈXݺ{OUMе:p6|OM]G$w_6)/DL(%ջwHU{5\!4hOtJo&w]Fࣳ$Y $0Mv9dHĐxMMpnVCՏn6d<#F477MfQM;9(}w՞ڮJ+]ajܻ"}p[ -1'Pwo[#rEAvjyKbW-ڎ߯Gc˞]GZ\Qsr(es:=Fţi-?{'"#+9M9džy{W CIxCG8n671SʢW}e ]/3Rlذ u}pYM*Mhu듢oY|q熘Ѫ޸;xyWco߰c&!v['2s N7_MQWҖw(113$ ߃D z=PG(zvh DItX]]qqG5<11Q pgAD'?l92|,,ior 5ns`A\kӷEe)]Ǧ-_xK*I-铞i<g#sw}KxԋkZ]KkBҶXBAJuþc{SS]g0 gԥ=_ >v>2PM=f!b"gڼe_n`3Mwu9~cP4q!ṕ~$}X*He K$t,P$dVM ]֧F(02JF`̤qף3Ñ>?MvN1y:w\'i{H%rl!ܧ3n%oe-7U$$ECqzm '@qZ]%'DpX\]{~S"ܟڶP5p8d2pBCĨ:Zg$*srnTIْ_>Қ}Fqf}T(߾kvnGGφ,Ǵ ?2ڶ?̛lsʏn8G~# ތK,*_=~5g|>4KQS*ohEbН[7ڴ&")n8wIe"~re.s Xx>I+,Knٰ9r1oLVpaLM~,P m]׬6 EPGG?|?aă,\SX"qY7b`z܈Ḳpm &&fD헰z'ER$GnGߣ1ϩ߬cEcMgW_6Cvq͇%e$K3^\jgMrX|cYA5M{{T*OC׃W˽76̚l埾N?t&&% y|hDltg{ؙltUtJSf671mc6 a E^_ ^(K߱Hx2gWvƢNbAm#@|XPrAŢt7tfq&g%դ^0tr񖁸?B'\ZPe^VlO#֬Yo37dA c M,=Wú<%2}" se9)<lqN_PeC0a<"<( S#oJrE[&@llߞ=fK?x~i/_'?o88<ܤl<>u][b3 tDaę&))*$ ct x/%ͲFQ\\{ @؀fA }B&(Ea64<rжбpX) i {bN<AfmSzAƸs^b{\8p>m9E zLNQdhT64wp W 8d2(>@n]eO"{gC|n[;#&-@ƍ͵v3!d4y8",.-8@ٞE.qZ8pxk6}(h0J|>9twwP(e~赮^f / qE"Vc7:"+8p# w~LAfsSCdYr~n` Pr 8pa>qf~ȁ8̱(VU03# $;v:p#v {3 #'vgHsq5zN){#Yuc^^B/E{SP &1ɨP$g<rС$a_fIҎvAhf:RYx0,k۾GVzbzA."ۊgO;w3*M(2e=JXxFil_dlis; &e7^Qeq |~`MdAEn:{&ʗWMbj8wB=&T2p^%"uͧECi!IT"n}C2L}BA'l2(Z ݫ0'ۗ׍&CH,+Iڣ`ľ?sH,Y-D @i<~p4D K7zNmfe +s-E=pRTQ$Pdt}s-fl; qXH._YH齷S?[]U)r~DFrY~4 ϏҞztF"0niK?,}fMђ1*ƆMG_Y0n'{r 0:7MoX8,XX )ѣ555G=ܱiJniQ*iin >J9̮x^nBXpuk٪g~,V+ >LXW**Vy΋}b| _?&;*#qpm76qBy 1IOkmoCƗu՟9ZӘ5blaZax|Z0V'WUUUTT0;ǎS]]=qkc!W+[7Ȍ MdҰa8r|}\䵮V_\x7?;-7JA7ko,ԷD 7/jaB,!-w5Ij' zh >XF؀b]먼 f^.6q 4@O{ҾH/nAqD1j҄+_1SB .uI;/yR_ƍxbGRdͫL!IDħJb5䚽B68 כ8}c`? rۧj xm=< _.;LdƳK<ČMrų! IcnvF VsUڈV櫛kٸwd7N?s񖴠(:>%)>fOoF2|Ģ} "he~)SZ݆@KK/{vy90Ǣ/ nè$VQC@  ?')GE]7& ~/1*s@P`'Pe>Kǎ:⊟|@X$~ow&RfiӘm zt2[lZQ"|[taD&2K'_;?5K"Ǫ3)lř2nh/aJ'?6 $q^Ԣyq9$9민DP0_Ox-99T>Eh8_uPn߶맑t[oEنg'e&.aeS2ayH(p;lmxk*7 8d$.8 sp݄v54:b5[ ^PfC΋I}esYQ|ݎqӧe0∔I~wr,9]z^Ǜ<-k`G>h@qT=-ı &M-λ7od{c|xd{n'[|9+x̢*6|E>K%n(mMon[]JUKuɆ"x-؏ fT>O{]V OK{2Gۺ-ӗ`?_4͋i9ɇC@̯B!?B..OwS w/HU*/U |f/rJaw:I2Kc7Y؁ToPѳ|8<3Mɓ`h)%9lߪL.3dEa5S&޹*8'Q#w3rRP.06}%zH"/; omwFfOYe3"T+˻[MS'H۵uU1qJRNw|r'N9g 5z|n{X89<90Ä|ßy_٬QQdj cO4Fe4o,mK4oJhw5|uUU 5,sLږkmz'iӖoVte HErlg~@țD`xg&LM?S8_,Qv$#)@ޡ1U %췈;ܬ>_=1C`{ʠ l.`6x'11QUn#Я? 7Euwc,D/yJF,}˳^~W-|ʶ Ԥ-2ȁ sR_֤fFy)M?u iԛ/N\7?o(ڿ]EVٚes~_Pd:ÚGw 93xE[FLRF'J')0p6V._t#S4_-~Kq2ǧ8DVZhz0~afipk_&ȇlVa%OpۊNt]ubf֒kq'=vO^? &D{JXJ:xjkZ6w|pݮe8o׿TonICwkƻI=ZʎXFPXGyI(wAnl݆3FeXbX]ĦmFϚPg l<0X>_cC/x 0${BԢש/wzͰc;O ) ,V ],;  319 C iۏ_hl ysLtc7iűQ*0?v]szl$J*RI;;;t_.#"|u\:yGDbwcT. 8UX0HS ꌻ0`7]7򕢒8hO՘幉x!¬??>hiM|y{h[nا 1kwV>77Bn˔q" ,i|hۺ"囉GgYTFU抾r觟 *yF>7tH7;=_n,Qێ~r{w ɥm9F9 Tn-HQ%.0t.󄠃9>W^B p!B(<<Ğ&*ȹSha݁Ysaﶣ&)*:q([JKl6GDQ$iT&okmmhw4)qYuHg:.u'|S<ަ?yްB Ù.yΩO-w~J%\ڥS̨(r&pysL̨6АHM umW(|OPB@Ql 1.ẌECN6[DD$bvQ,0p{]n):<<> [cwR}vX﮴0. kfkHx` wɛ6zWWzȚ538Xy8QTj ٯ]fi^}>7cj| LﶵK Xqڿ%O0nDsmZZ1qB;zhte?Zy< zz#€j:tff:Ie$I0.L1b w9 E>z-Ӧ3Ә taI3LSfᑽƹ 'AvwǏIJe m#>U9 +y1[3 (9TĨpA">Oo2;}[&9!`rtj|mSLȍR pKۭ̐g=Yqp ]Ա ;/Bфrʨ7 ,Mu9啭{iNoVV>;k72kXƝ;Ye;!m=#qΓ_}nB'|IUUUNN·~8~\壠p(ӀqGǭ]76a'yč3f?)>4"LWt㼞 iPJPEwFY6a*M*A}z7qzAs{$2bLf xT7N( H)a80(;K:{Qn$"]u͗%oYU \ x I^ >2^~8i>;l=;.VD۹=uâ$z3/^?1,,,111;;XfϸNCĠ w |JQWt.͜o3xRвSŝ&5ҸD4.1M)3Ήp%;n 2334M[[H<1a[汅?q8 4uLRdOr;w6\ J֥utpںGaff|r,p7AL3; FXn4[ i Y0՘PifYB `D$v|WtQ18Ay "_>wiSG *JPh0Ac8c\ S4y$fFچl Qы~%uX1*'NjF,ǿU0۷O[MVn[mNn[SQU)eY "h)\p177hI/7;H_ D};TX̩VӧΟz~-O9DzVli:#Ipfs_Fi~c Prh־'_rACݗ5_J%\kBA-w5g6˗D;Esx l6ɔw`೦ۀ}v'& 0`t_aFMľV o7uuwpaX)CB&.N WY6JDa 0͛g}<țn 1 <ރ@΁=7^}GV>A_47'%&(Ptf?!CjgD 8yw0~">ߣ&pu8 }6y$) )|e Ǵ5넩[n߿8n޼/,a/^{iUm :ݍ \` KXaַ7Y1vwGC-;5v8MpgNT* OrDTZRz\pܗb?!x8c&IP6йCDAގV'99yٲeqZny/ ,#ڝet' V7bM)憞g5_os4NڶL="cf-.IU/mg\<~X\bց+ <>l%t'mc 7 "^P݊eBlL-Z8-!r`]! ݺn8:9R<:o^EdHV^s31C/M$ܫpttS$k?o1ա0DP#vc/X19"A$ui1lMuGQE9%J&Nm$trnŌ;^ip7_.^&鹼qOBZ~ꛯ> Rpvޕ7|y*2h 2ޚ_5 ⊖L/We/]b,! m>\~׉- KFfų EQ O(xa?[l#o|B]g[On?pJ&ԓ_66ox/.N>{H[^tNQT q8$3۶W/^03wa(aly~-]]isB) M&XӶ},? h9W>О5rl,FX,WFg`6KZj٬VOƊnYBbᎫ-0P Segg}6~šc 猝џew(Oy۲eI[L&9J iYحU/Xs=Mf+[U\ڙ}ݴحхgi0W `yُ/zn) Jĸ/y00Z`Դٷ֙nPC"{vi}c;Z/8z^x`Oڤ'p]wUdmkug7;eQJl'%;YO*QIf|T͜]D#9Bmõ6eizDZ9S8 `11ehloo'HhZV VOxkU?j{߾+_ f3 PWޭ-FNcCvԝ;٣䱺PwXZv uW6խ;rnÔHN @g ( 0&ML;~<1ˤPŰ?mطaIj_l:9?EQؖA9nBWcxǥNX, Bxd !+ P]jZݧ캇Yߡ!GNo>Q19JYSW uk\IXv:5;'M+hB#1@$A8}NUX],j a~IEź1Ӧv]96QkQ4 EMm(U$@K ݓ1H(L ^XbB"O}芊YYCJH"ڦIqNcYy0D焵`s^BaɿhhJƌti]z ̏)Tw0 }]lzj{?Й`^T٤ebGAaߡ5$J~6$(߫!%k7BA4a381|( fF#\tL 1rZb`%Pd*VL%N|BaK %ŅJ=CEJ/;WwHdN*_JPHeJ1kll|@nhhɥT*͎.$:Ar#J$ԤI{8WݯGk>2w5}pG(H?$vu &nx=pw#F {7w`Ǖ?[; {Hޫ%ٲT\dKe%rK..NX.cEduVfYI$F A cZyf޼pϚS9aXU}81(;˔Ri0YLv2'PV 9K5*d<P- RFIPSM;+$W홉\>q~B?״nBWYňƈ7[Dp[T5PzP<~>:47 gbcaojjtu8#  9 Z-ur hIHfCZk[f`TJvu-̟umOƺFU-ߺf[l]+AfnV~=x V^yq6_{MbWgى4t+d`[*Z-([0(f蛝3`ZݓV|<gݜu9.}h}S{x YGej`7 8 -3&5o3@q3(0(ּaWiDx1Pj(_nr(vAj›kfA^o-i!RX6h$܉gJrMV\-Q϶+ګn},.t~v Х,]qп`!ࡃ05jzV^~DjNNxl25 u.U.^/gHl:]:3qҬI_9iJS_yFH͟Q~Ġ6V=}֐&{ A\%6c@ *KxgwA5 ~}J9^2#B& '|>\P@a n\f1 ,~2FӖD3꧟vU!d|LsZݭR*E }cz P O[ρwL!R&?2|Iɓ6&OY{}|R9:D ~r ?ʳG]BQ>D| |"CVt'^CGQ$RSĹt S*r\䷬'7.8|G/ZO >l͢ݻrVV!Bf'+{9Q}8)+qgw>#;g)ٖ8ľ/U _OWhB^fŶeCg|KsV-\}$8=EF $&&z<j0DaP&vvvS_E| \v9!YW\.ק\7s 8vzʫ)o/)zߖ©KS+ܬ r%G,Z6(*!`_zZ jE&p0(.^dכj&T'-8_TDMbQLPtX:X#|@ynL&. qqqfء565 ?moMXLMa$v w3%M<Ņu[1y')RZ[lix/[t1)3&e"R ͵Vfں"] 1\;sDcóU8eՆV0uG(〿=71¡)' DG(Gcc㰅SpC(\"e~;It~ azp5j`^#o 8T+n$1;*"==ܽ1X ڵkrrrXlEg:r~OiIЭynդΦ Z5 q@1 r ȭ V1 FaJnc>S 7PC1?tԆFqzZh0R{ pŁB1,t&$dX3T̄DjϮOH+7KϹ-W*/JN/hkO{ozo{խM9K\(zM&a-Q.f¨wކ@4o+U aHo;m[RJ~=8qF>۫jS-WeY7Ek]{k;D4ߢE<,sp~Y2cZ,!C 5̹:ko>Fa l.0J5u.;AF[jQe.Ci4j*-0?R2L†KU2(7gp޴mTtn)ۿ}$ƿBʓ7NB* =)*{p$${TS=ax) : 49߁0CTLICU8@A|>J&bGamW7*i 4fR3o7P`޾<۱x Z0 XG3>{moAfXeM\u߽ opߩٴ95kQF i(~Abu2Pj(I SaC;C7 }Xɏ ]yyȁ6# 0!*Wi?vjЕ'Z5@p)p_ !d %QR+vRf;'[z7!ZHjjՠQV:R1TjX9+fSEhqp8=4g @@K_B!wDqZ9a[vjA ֐d\N]Hܡ7J477Rյkl*(3Xl{za\[]]]UU BaFr0W8SA4Nr(4(mwQ Z @[;$Э%$"/FQ 1 ~U!*m?ݻ4NY%xaA4aKK0 H Jn_s Ixo^yicXQyC3b#Sarڵe˖uvcbb 248@ fvqV{1X )xe}ޑ$!1{.kkڤiKxvg3V<{IKɞ-},ѣǞyf/7Pxhu8dAnSSsccSJ0eC! ' ah{{N-,7=T㕤ZYёmmg}Y[[u .-?8[RRJCc_HxQ rן.޸1}^ }aԿF.3v߸Mx׶6ˠ+4v a{F}x} +>VN?@Hn3)!:e ͛V|a=^OJJJDѭ A FS1NVUӔ9mul"r4Ęb`au%dRAr\'˲o>Wڒ+.;:o]zNBtZq3q=~aO>{sy\Y?RҞZȦ8vfŎk8ttY™_/ㄦß.͸hEKPG*PÁsW7wĵNiQ!c[_y,ð 0gn =1'ͩǡ8 e.Ud-s;ULҵ3Sq[}K۴ӧj][,ՏlZ~ܹHE.&7/G6G21dW1$Z 5,;8Aqv{m0Q8]B-1IyNTecp-"7kt{'NGM-"%Rޒp]wRH6I شU~[9$_;y˜_8mCݪZ$mEKՒ$ۙ>IQkBQlii1l Y1 ~?ތ;ñ#w7RWB}=@!wu10fVv;,UD8U*$(0Z&bgeiJ坝 C<2??:N ͚)o{L ^t >Z8SpO=_2m}+࠮hsEUې}beIKXj_1?MUU! jG? FvF[xKSX~MɗWz$A9u킵s'8g.0s^-L(L:)7rL#6"ԓŐ@*|>\DLIry lJ"0B0B$#F˰?`RsssCCOJJm>{a0ٳf(++%ׯ_m5b2;/cc aHB8w !7-7{\Ӥr9f(k[='/*!'5+)U՘{&Oݑ7i>O6 E V}u♋ qszvS{٥wu1+LP]5>[g1q#iL/%PIBe=-$)1R9|T5\& :pL5obHD@b6r+e$i464\bYYizz4M#G_Gᵵ#?-YGp4^ޙ@AУqޏ~pPC3HBbRKF7NFQwQ(`'ӯMr8crw yv/屺xl(P)\_mk[8o6n籒Mm֦*@=!\L<ۭ#UAp Vc3 Ka e4aNliFbTcٌݫ28PÁbJ*>./uLU9TmGm<vRk-+4;k׮UWW؄Wl=-tljnWw-\K֫;Sk Ry \o.:;Ʒ&-\8RJ\^e]|5JWt/Q*"` d~ۖb֦e;{{ri9Lyᱹ\=XWxsԶLߴʼnhT(UM &6&VF\.7'IJĢ9ǵ:bj}>a oT4`dl,$$yaaX Ƙ81D'|7~_ %3E233RSkPK PiCp G~/][{XC!(_zt1u#.gbr?uy4/p]$ZAg@XX_[Ȁ.|`{A 0t[H'ݷ-B F j8srNj-jb1`(UkdrR:р4a37*|8_'{' (.R55߳?|^Fb1 FjHll? k-fl6 ?nطfiPhB:W=*+?LK\ؒ4_V~.w|~crI1t*B?|Gy¾hl} љr7O3O6|Y $5drFSSSc$ǠqlvhZGn9cKsjՉ/K^eU{|,*7l|,`-sfZp{0]K.]z eN:yϻN! P/_:TȘd0L59´a줺c8f0& Vi^#(V!T6vRflbPh71l#pM*z#zT$|2 /Vǜ*! w֟9Q ׍`o=U !G8 Nɦg+m=nl;m7l'𚿽 _)֦v~uW_{^뭖Iw?+R1y?gٛ:;gR`dw395r^^y .(T ! 94]f~'@D' G^ ֐ [E=U+1< $V~i?jJȈ`CO>.W+^x! 4yAbY3׭Q(c:1a*x$.I:f}5&/~b$g-2gP:֨C5Ϥ2Τ-x!)'gbz3B*6g0Wy<ϸ*ffWWef8y PW'0 Y`߅aTJ ^h¬e/]099n7V;C"|kިZ46džX;COJPKh\gF*4 pZAXL-<&E?%tF"q78:QDIIiaaA#!URGN{ @jk`2!ҙ3!ǁoo_"nn9M0힁o'''\im7ZK&R-A?P(=γ[!KkkKAiiir8tпۿ8)zHe#!$n=tbjv~6ܡBtO3`mnn`LKK-\tp:bXGI t ~@ 罺ܣ7ؒ *ڱwk2 ae F,Ƀ/ửՆVZmQQ1zdOZ-[wzWex ju4=Dj\!t7ܔ).Gg78{ro󖐐q1V=@[[[ qq@_R$)|0qNC󴶶a2F}$wpOL !@wGQf\HD/ݞyw5of4P:톣+**2h:FjR77?d\=TQQ+}qڽ[8˹vŰ=E5z_ t9iCJHP~$)"9:K|GK,z1;bc]%L\)-pkCvڒIˢ{e0R$I|7aStB'!kZ)24..d2 w3gË/Ʈ]}&my7v^=^~9m`gV1T|NEr1*4ۛ瑛760t<ǣyC-Wb"3]WLuU,ah?sUO|S995!$‰0?Ίk<ԹwOn8z}ҭƑ]V(i:T6-yaاv *vNx`SILUo*lTsԔ4"+FwxLH=oǾ}~ݻN]/eWn6ٗ21ko}2>S9z{loWvdk62ќg^@>;H͙`cykO:gF֙&Od}^՛>-gNBjOȣ̪?r`Jт46#6q#('O9a}'_EyMY2%+ KDǓNM JD)E.ya4p]+~xԲ?ێwC{X31J-L팵b*S &mJmTOtO<}TLp49m@_/CAt_޻UhϹݜ3u}7q롔JeNNNtC1^ |>Vi:00UHE1(TN7X\:}D)1k(8~Ue6sL1u[& r-w{'/*#NnKa !fz`{QI1".immzJIG=p /)2;; j55#cvZ+tGKTp x'Xrv#G*oo,dnmʝ.#0Ιg*ǤOD^-KGf]p 3S{b4՜$9'vw2am 2xkG4nfc=}"m備7T+ 9C@DC\&W0,k2F"v+ ;N/nz w[3KU ]#!Bj4|3U8-(:l ifϚ=[ߒ8hP ?ީSD йsO22rff&/ ډɌdjAJj⤤>-+$@5󠢺ysOǛ/{m6OKx OEdť+ԙkzmWoN/31: hc9ˡץb4t8 P>f\_l^ysj?t+W+kJ|~Z~իU 'tﯶ#.yU*b[_k@x/]J#=ǗQ`?Jo=5Bhҏikk#HrZV*vS%P*{;l0t(NXaZ~^U\'OX oZ}!~Un*G*:u+e PŒ5W5Y¿~:V6KIځxjW(n8pHM b y)ZviN_#7Sr 7q-#rq^Ԧ9' u]VF'\!2o}KƘufE>>蓐P~ZX 4cc7u*`_~9``7lsa׳ڇ[\nGW^Cp:@[ph 4 x(j8Z8}YWSʱ'[Fu ,:'㞞6m\#G%fXeB j/Zq-<.E,nP.{WMS]KYs~՘?orFbƽ+}UC޼)@U׫")y^UϩT*T1&|XUZӖ <8;*Ļ#QFBb|P^^7p'x7ߚ>\V4-yC1vO FfqJ=屽ڏ3>l٢C>@lX0TTQT b3))]/:~ML!hQkt]5'3qieQ. pb0:/h㉅̋ v0 k0jտ+VBmvzi[bV\K;P7#.)fY'5~q3}el_'oB7gf{;*.MX/ξ?4o]{&~';YrDf6h Oۖ<@׌~rHϸN>XN+1oi-.~ƪuf31OφSb4P?x01I9}BUeqƼENѱjҨ7겴xF3;ZuW3ӻd쮏˚99Ko^*)^bѷ6Sej2c {F;vBK:^ T3<»ɮKxÃƦfj}xZ˗d28t=ʫf7o rWo0LqQQl^/˶ (,k+GXfדh!`.(nB! ;b܆ A!8l;Ld7SID.#Lx1O<"Sy(xTQny,שKoiŭ[o^WՈlcO;8ݽ)/rE`Лz]:w Plo~X?r{>0pA.U*1gih2lT%?%oip`PA0lxcsJWuC@"ee*o@c})BqP0 W\cL {a1% ]1Sj>?U+RG YrŘD(jkkZlP7gaH^Y*a$%$@LS]a0 jΊs.X}V,..vP-CVG6d2U?K%F-!!!!GTF( anBw~VTTZb!yHj.~$\ K n; ID5~vw7F2r~!^zM6 UT n,+ 8:]k%[BBBbJ cʼܑ.̻\ؑ:;Z}7XN>>Gd4@O>pƍGXApY^_Ay`w:DO wؘRRVF^hs:Q6GM|FƘE7DPx{KK4'E4SB-!,`DN90L e|L6aeZw$qqq^7r&'eIj o ":EH ~ڦhJen`;::LAbk2 c0办OXu:ptV`X-P~G[T Qɓu7?ۏ=BEE'|ڵ & 5fכCK;' ƚJYG7-rҵI ^{d;c|@ 14]Rr}D/= 4qO1M6Jƚ5eeei5!{h ?T?:5z6\Ppct*;{vgX*d8kޙEӦNz/,4#t٫>. lċ 7/ggbjv1jwUF-9Kq@CFw=Uť*/l7[<8y(ci^ @ RYYkn0r 74]Db;+K*6RBދ?Jj5u| %d f}3,7H//\` %q|O`Wqu!ab̒w^MΦ->h~V;}@hz"U> 9`N) L78nܼIt||jT)! %$"ž}׿ 5kּK7ntHqb'^B`lN]6_0Ul}l VeksT]kogtgc(q^6`&qW!P\r5)!IB3bzD@E䛄ʹiӠSWWbT8J^EHQCіfFFFo8pm$9Ebz?HbBRy8)?>.q}^_}ɾTB"b 0:FFPhGH_yH,1 "(9B0EH qr9MSViPdA9-p_/ CQyHu#IqGGDvѡ(555\=*YjoLH݊GTqD߽~U7r\-\ӑg|Cw'E0eގn De[FQt[ޡNolü6-G`!V`,X|YkM(-{Y3vit}.D2 j4M_ gZ((Au D3y2mr4E#LI$0"Cx-@ɲ:1j*|=(ST? f2[04_BFH o ` ^J?Εo Sa{ۿMFFC$»AppF! M37/2 [ C11 K% JrZr=9aIk+' &N/bf%@NdVubYD:"td͜M*(V:Q+syUj$5~Qj⤵шՇє0hMgS. :81'$x@׶Sŋ1ޭArT TZLl!5),E2mBh!@i R.Fa*I> nJ]$h FF#n࠾aX:⸸X|A IF 7кG96  $e/)HtDts'oo }j 3#^ո1=9EMC"nX|3 nNN,ò4qojܴnhmw M1fXiA)B%yfgͳ q54cby;9[9)1xе@V0Ty)AxPڄ/ȑy05'GyYD,ʑqXEs#7i$%ע7]7lܲY'UTf(KJ% \gMѶZOv *_ wOQj0FHN-Ԕ8cwʬV^m ,޳ Cb2C ^N" Aill [dLL-j+"16&/5_1q}[Q{.&pdCO 99 ǽ0̓Jp³׿jc͚W3u%+[i-±AIĴ R > ,nj,{\.ToPuP@q@],&qpjR2&Fv2kg`/ Z<NEPbTnϗ7@X43>oҾի&r$aQ `Riw,Uվiih @ @I#f3{w{=ݝhfd2Ixa{oJEfVUWw5mڡ UGFFFFay8G0<"]a=~9 D.%)8G07c)zK`q>4 ~^ 1Zh!TV*6ΊY s`}-ݱ"l}R8F=q|_NxFR @gzѮ˿ѝkVmݵ-M/5{MΎ=C& <01P @C#8_-n={jsz\mAU=[z`܂Ox`xCK~v/ivmYbKDm龝/ptv>KKvT1ܦ$H,x$O7$7 HMrfbah[<UVzgS-_6UVzg/b+5B_NOc׸7FoOBV,*}"wW>ܟWr}jR]hپ!K8]{@lj{6."{i[qr_6\ν WZOu_ch-G.JIoM:~1p[ݏog44|#Bdvv6~9E8TnF^=fϞ=s]"0=^y=x-;qK,xÎRV% $Mߌx$!,o.y⛆APXTndmw0FKyT? %/SyuɜN1uŭ]0+R\TTZȌ;xw^sNIiq⧗W{ݒ}E|']ĹU߆D}};ɚowҔAњ)@oC4#G5~]6ĂCRu)怋*N =*@|&#)&1<شz=VKܢh49)c;>p8IfTJhARz7cy~Z[{9td߮e-k{ [ *J&%+^~E2GR#m֪muѿ%[;<3B@(8)؈X,DO \{۾wwםO(\e_zuxf7]}H:k?_"?"I`>,BʈU%0iw{_Iy_4GSSIqxפO%ON|~?8mQ=}aGxYH!nZg} B3HXRiUO vL 7-Gf@af8s޶ds]T*Ffobn;Y5@L'(lB%PTC| Bm^r8eOa`G*bѵEf%NCJE){*I$a :EY6jvuu577UUUi eqܦ_~)!&#xUZ9jb[k࿙ blnK^ ]]4]ًs˪1߰.Ԥ&.G͔|g!ژQY]ut5sʋl^oiRw_fj5!t ;|얥o^LEo?+-OX6s7]/R;}/}R,Rw>rEЦax-6#j*|_zGWCkx)Vs_-/<أ#_lrx]֒]_~ǔ…=zs|Jќ@*:YϝэUVh.|?kʜ蠇{OtyG7U[ZD] |ϹѐSy^ @EXʱSP m9EeU@<{ɶ'2WSb.ӫt0 tJMNx9yμ7ߨwOyUwo}BN&\x>cy)]|w2J:vॊ{U.՗X\+7_lmoA28N.x C`wamTּڭ*BCQ3Um3b0Qm\5n~%BmXȈG7n{q8ZzƖqQI>+jt;6 xTĆh@=;~-7'Aq灼](*.7mi$?{{@?~\Z*lZ*v FVaʨ0ӕ&[IqGG;TbM[zbьz퇞y.޾{@bE=ܢ}8*xzNazq^,Ӣ˜ʄk1kvuğ*x٬kV@c˔R '@({]0 ̌8H3qii0j؞v8oFFFz ic1F ex#f]?*! lWR:;333I3= vwO7M7ƮbNĉy *TzA@ jskk4Q@[,9)XyW-FYmD qnѶF{fr@x@jLdsJgw<)pZ␖{L2+|-"~B%rotDl.-a5gf*eIR\^=ym#3"3}|3}qyG-DȍFiV3A c6gF׉FʶXr0kxQv7/6s@ nThvشrBp&?kc]W￙U\ z\xv[ vxvu26[{woRV t44w;3 ˋn$ wqq:O=VB宯8 |YSii9h^_|[P.]QLqQk4}HYF^ȟ<1q{ 2Kt\ҹ($Pkigߌ;鉷kL5ԝ.ηgYo}#*{!lpc>擀?.C/av˾n̒c_z!+Tg"=*[RrqA]>O7j+ xGQbID& <쁻zh tO=]i2 { G[.v5ñCO?/_l簘/ r)h' gĊjkZg^O[|~ϊ0s?ޮSG ì,8a2Og?9Ȟ4q_ڟ{h tܓ;4~Ռ;s_`VWn20BQ6J{E#F,pZZJZ/4B8X8g=Fis]kfFb{ĘQݧbmgWm3"~s y~k.]~O Gxgt E8ڗal'i?E;s\RΪ2 ٰhB)3LtTS([tDH)byD&?V2qda#P TvΣC9Ue"T u741KYr-YdFb  :՗ǯsxZ&xu?cÀ6'p-F˹/oj1#oW14$i\ //Iy9 6c YlO팓?L3/Lmi;Y֚ka.:s!U=&-oH}^K@C-Dz] u e)^֠٭n哳oW_ r+Ѽfz}jg?Xb.*Vw=mWȦ'Ws,?6d\z_m{gelY=\Hs{ݺaSBLl kZmVKIN)gAč(;쾞AɃcAcy(Eą5?fTyۜ!cE֘hSFyZ>uOao<0 :n7NΏcGx]ѮX6sd;hn0\t +LQT8Ye$0ɉ 1ț e~K5e\M?vS\:xG@{C(4Aw4r:W>9lvM`ph`pj&l%PVKFF&),tw0&7 u΋[-<1-A,P-k0_[fC@_!֚`d0H9d>?aF`O#N ::AO (IK|!^IxdvFW|yGR7 ?y*KLf~y1)o2BJ8pE77'̗d1 t.F,].`10_yQ|G}E뙮m0u Oo7#|3zB MbAxH9ϙng2ݡ|#m=j )F޿]=c2),P<ΐ{$N< [S)\vk{Ma24g.)aXndPv;GRSJOMT z=v~qbb:\UCC^/1C*57Z2%eSٴiS 3D鋷杦]QQj v22'NqfKnֶH$BdyyOf(JA '2_uA`?}Qkc"ĻIK7A9J]ϜWMjb @=@%X*|$2iiijvBONxi&ޖW@RU/2)hs;&m9rОohv<S-r38aY$D y[b#, ~OV  ~9fz=ۭ-v|o#t̓kn5/9+=?=~Ȧء6-m' %ib"ނ* ;^v}/mn0ܳ/uZyce.ߟ߿ǰX* 59sX5;ؒ3\Ǩ94udV ˖ 马/%m%__ݺ"7[}? FGj4pۤxpl'ȗ[sJ[cSk~Z:KnٵBϿ>r`,^sۮ~nʥd ;Jˢ 9 82@ R4 PIJ.|~eM&\1>b"#x' gHWs l•~Q#&|t:,oIjtcqG E1b!{pZk[^tI2D鉷5;OCsԞ?Y4݃Wz<&/gb[&w36 ͗6!9\3f7'?*~-xyU?8Fh1x\'g\F"o udA`8"ިq³?Oh|m8-P3JoCݝ<ڻ?[ YpgWe+A:Zܬ⪬鬢ʬ"lRp8 G8ayue0Ԁw9L8氻[@\'q ]|՚<7.GV8pܝJʎE0<ݓ;7eq|[o?@g8q3^CaY'N ",KUBaM&*YFRkEotVlдz|内fdAQdsKbMvҢ2˖z}>VQh/KA `vVV1mGgIӯCf7:3+Ay6Ǥoh#_>AE0٤eb=wAA)U=in$$&Sɋ5hص84fR?Y0qiao h|a}]O),1Prݱ]jՊ@[mv8/݅,;CY* JIVԃa3+:N-HFoXlυ鋊'6|}|E_T M_ `hPw(@8WTBA'"U F ōku:EϽy/6ݛ0Z[λ\ӲVCSG@ f&AfA/*Jdħ̺C^鋪+#=zJ<$1(fy;''_OԶxY%tO=``2 { @yěsEhNZO&|v? F iP0f{׫Ol*466VW.]l|r=kmR5zT7qT= ;)UA@ 345 z}uuuVά^= RQw<2paI);Y:-߷;U}r# F q=]=5paps8ېV<裯uw[[4ߗ,pֻVy|E,yG}]oAX'=>0ܳ Iee=獍Mt=A@ c6̵P h"cv+TT8~==@w rx#Č?>y5wKKY`Ԃ@ R94*8kqMoLoe݃\;H".).mH&\9r6@kkO~(Xq!oH1hޠ9چd} --^gw#R oH1O \Yp2.օoݻfTԂ@ R'_͗@vguuﶶ>pǽ\)7@*`!7ېܷwΩ_dY>oH6$??+++{zs~.g`@@ xzzz`gQ3̒H$e;gl5{ڵuSֶ6;g`PxQR 峽F7@`"/fkZVس9&6;.QE ­ndx#8e`Ohv/,T)+-%IrrW?أP*F#Yܷ]/H"+b0'ﶶ߿x)"% F ycv+s?'s /H}SUCjއvN%7A_‚ .13[4s^WYYy4Kԟ')ָ X ~wJGGFD0 ?(8RQG)nJ?';d¼2sU_0x775|k[M eHv\ւM>.5[A+H7Hf񦨉ebRJ .CBu~M>4k 2{=&&q݋T0܁ FARoj])K-bFF%.y,qHˤ 9s zx.Q^Fa$t/azd $ա`_` 4*phkox䑇EG4*JG4;aVcԤn77~?,rY<2$q`oKπv; 8CQKl* PEQPr qZsdOa`yB2  .5 {i9I<] ,g8aPLsy1&6&p[rNl/bB\#&/G_;&7q!skcŤl'| C55 Hɜ}=E %8GMQ'z ݫX5H.,=cBCƭRykqC!0ʏ w$z_ݐPh4\1YsVєп(^UĄ ~aS{b`&;J3}ߒO]rEC8W6iZ5ٖ^CjY:jfY9(WT/^\v f2U 7NX35򸌙u*)i Jgo9ZRS۸/߸iUx+4h&TIZZ. e>k QOqwlM:۪5?Q/qG<u˭fS#h9H*Q*Vv+#ؘ3Q4#:?bNml!K8:F]4e(h;t^/g`TqFYVh WLheH6xYD0h@(8~t})#;3:'9ddRژ7ڃc'>>"LBd$n7<{Mvܻ7hZWf|t߻g~9[XLU7ҥ:koT?FSB O|{[/<2 ksƪřy%\Kۇ޶<̲]|Cl%BF?ZhIs9Xq40ZLcfR+MhBl$4AF 5lmcUZe0Pb"wqP1Aco#>i-H~Ow-wGl-تNqyZwf"A=IR1y*W{MjLj["z \^^iٹ9y d[o^SXu HRVoծ,,P5єx6`·b=ZT W䏥?XyLSn`D1J?;X]uӒ sm;kA;U?`ݾ4iY;( /ϗH&?@2z |ܜN8w|1j = ba&Jhf'bbI1*.mtڽ*q v ty\^1s8'N'~#&y$ޓ4n‚8N2xHS9 -‚~f'{wwG#R8MӪvi'٥tnPfN`Lmi"`VVVjvd2%w 2jf;&!lYV.)5cqc-5ɍ(XP(_e2e9>rŇA vnʐtLm豾.|ظ5bG,>q,9I?oq`I9d5$ ' ;R:ךFi kt8ID?h?SΏ$F, qN<)u&(-iJV||L#5K$H+3'1hfdҍl2K^ock={TI?y>=A|@q~0Zv]|y"Ԗt7d~/F{Zk?u]!9oC1@&@t<NGʉ)f"H\8}=vш'LF)wlY찄j^Jܹ!P ӪwI u9p30Ii`ĞDM<Ofjr,6m-1ҬJ b^>Q4E~-:c: UxҦ9  dc$ߥ/cR20IW֬ۏn-DNDT+BIkl(r'N6جac?:3nܭ~Mh`2Iټ`q<;;' lR$I=ͦMyyy,*(՞UX HȑY#TV +&Hp|ix,_&@=@|Z:pypW%<U5_5c(Awz8hxcVI!Q<>#5Mw1]ǔEqaYe.1"Mqe[4~VSt!$ R}ϲ[_^οwׄëM-m>B2of ΆpQ-}t}~иyQjbbGs$*1&@K 33SѰSc d/3= ģQg펒hά_`n2{+i+BnT*s`0S5 o嚤;&ݞ ҤYlP' ҾH8/`(o!h4x? z*]9e2 { @E=Uˋ$6^}YлlCৄ{xS*hc)s4x/2h3 Bxݾ.`37XoP1]@8nrvw Z#%c4._0J= rdD㸓[oy"v҂ɤNcm(xub"pn:/h7좚MA,*By4Ä~P1LDom@Fc)]U0gƌ &1<{Fb}yѳy2y&L[w KJ3hCݒ0kq;"{Qu.MU>RQ{5a(#1o4&!1skGQ_t887'&eUr0# Bc{CzBiJl,YIfDi)ջpaN'k^\ fqVY$ƨt;$u=m,6uMd|3.p))1 -@ +pzdff*#RET;;kZexxH٥9R9l%/)я,+mjӚ:Kd(Шթ$$"SyOg ?+)+/OKzfV1MNO 8nlp/41R[q"kX,>:z뭛ა & jؠ볲c:655iڜ!\ 4TҊ尵ȼEa[[|6XttêP萶|,,vuuŠ8vKܺ'𗖖)=>,zv{c.b`tVTT*vJ9۰ad-bDjo0=la=F 'pu`8^W¤Щ %4zAirsr0@lcwءlgee94PFB($OiZ6 0Si8t20A8G663j5 >*2񓞞^\\Cs"--T9qd2EaC\o0T)0s%RQTi UUUrUxŋCVŻa6Xd-]X.U =-[jV˗/s놆FǽrJ就rZJ9lnn鰥epp` y<6/z{{ㇰٙ/kNU Vnh/AJ18Z9p,-):!I0`iq 3ˊV#Y6դլb]FMŸ(u;i1FY:8]A ^)I41(y&wcQVmBQxJOc^QPd/ԄMFݸА$~hQ`%=t Z"AO5&ݸV0lT{ s k@|H=|! e4 x*Fmb)C]N6(0a`s`lOj!,²8`IeX ^'ylhuY[lV֕)W6m$V( U e\(J ~7-cE:U9v|9[dgǓeggmXP*6!RȈ[}2z-F{ټeru5ウ#u݌qrzQw.`>~/gڷ`ź%B|zzco}u01TW)<:V~6 d֊Ow :va R3' 9RY˄  7-y0~Xǫ<I'-ڛ[ֲ\=@3!i%+ 0l2J60NP bM_ 6pL2aT2~J[*gq N(Zd2"ޢ[H,Fw5.nݹĦz?9%~p[{Gxw.jA7[v)cZtZa$=M 1beLf(%6ܶ"aV}̦WMH.LVx) |W6teN- $e&m+ol}NK.hm+\qwl;:zܴs:Cn#ývtwg-ƯZ≮byҾ4w׋5EDW/QLhMvܷi* ٳ۷osnǷv͖4QU[0o]g\K !/n4NK2U>}ddȵ5 @2^v{83uz Tl.%O` vn(=yRYE^oPp+2 :Oi;1#pX9^ ~E9\'\A[>T夹ajf#cN $y7#jje9B'4P u-+lQ[ٲ"tH-/!NDb8+p^̬ 5aq0' HN0W(\qFY*4ꗥ5ic7 /Nxi "ɩ$+)-!h*[2gff11MzW 5>c }CEx}aZ1 K2K:KlI7"1`xxݜ(6֛KTWu{;- uaHLp0vIKFVl=&CdaRi|"y7خ!eiW?~J@4O\^n3D{]Ziw2Y{::s Z.lMӫr*4C=-zwH,(S%x(q{'|2yB\VVVqqÇ}ѱgȰ*)|EegB[Xp,̌N 9B,jhZ1E>G aB~ è.1-;O]`ؚvC9᫬]za "[WVx#7a1BO~AMUBO/dv Y1Qo,BEjȹs . {ZdQ" ,s@R8؝UptRJQuc'&D*O":0YwHEK ,p KyXlx:1-K38u #d9r|yD8qD-`, 1s4T t!ɩ$c2MM!njOL 7'&n#RHbSe;1KU+ӴFVu]gZ/_imj,]Q07KN5k^/ƂޓWjx~"Ib$4tj,eTZB*&-`͚7}ӹxszӚ`W5r^]4(ub iZ.|sj:Wl˴5:CPW-iqIt2 ǚN(1=H/,鳗hOKz*JŒV= ztwK+U~źӟ׭y-">΍ᘒ'ఽj+ N> u 3bgYMŪlz%Pz# "+ >+YSD ElHH{ BHϖsd[6upevv̝{=snLJ?lfזv[lY][l۳s`Ͷn ' 8hAX}C}}ܪ{v-KfIQO|Z?UDM>;&_\yBo~W߻7ӧ}ٗk}CYY[M#AUZC>'S/HƔ3L5ԮZ/`̧ͪ㚄&&Ы}هSϜYӲvv}oY][VljׯW@&&ݺuMKKg5j|-VȾ]'Jx3޾~Vۇ·Xf ieDo5uP%2Rqͼe,c[?Wh& i/yMy}ĦмЦ+Ct{)Z:TU] 䇘kڞjGsc9w$]DѦClX_$)ʨPnޱSۓkS=eS3(Rj43 J]h.V3ȸ~!;'"SKןせ:[n7hXӺNf.ۼ9sfnQyn޼%;L㞸'._oY-y5"\)?zE$u!+X,/]LpM- y[r6,OץmwoVi%ּf&OTmčWˢ[E NeiЀFĉ"[r5v}mI]cI n5׺ m{O\hk(N}`gL/T`"V &UA G7T f!mbͣZ `|Z]'(2ZԈOXظ OdZ}}Ȧ"dhYYukճKIYMR.4hx];.:to`L;ii~aA⃭ O?__[ dXqb8zaӼj֩gV_YOELᓑ#+FR^ġ :̞3ccǬX&[nu,.}[9-='Ţc\/MOs\ڽxlYCTBKSE; ISܨCc״eTʩSgS4tm^+|(y{y}bO=['2ٳ11eEyZjOJvgBa:Qf .AA9> ;ytddn-pEpuJQJJJVvkwFC[v{]@VNFXOJ&WtO<۽K%*? ^2U::R "1s_˒tzcsc\5g[9Qed8{Q &tJK:kcc;Gդ㰞1?]עI=[㭜?{;9^JMB~nfgg]LKM"o>oB6Z/6LF̍sP- jZe>|H֍,^uD˩*@u/dԴ}{L298vxÆ ܱإP󙙙U~R1J ٤wi6ߓ9Q}T҅$5rmY[v*Ŝ{?^ի.&yŷmuqxQʅ$ A+{xЃ8d qq1ΣFD9B}CRFF++1p_a'ȷV .cm  _^٭\%mAA1ƒ4sg+_EoDZ9a9%D)MU0j֬QZhDV{p4Y'kKHT]BJGf.pHT>mN([;aCs\zI#|Fj ׼UNpU wtV놸XS=&Y%'nÈ`_g*/Bh8ѾíSfp~YN]΁WЯ= u[5KtwMxSSx+ܺm/>PҐZgK }TL"H[ŋ IR5CCCJ!@=@jIHx`LjPq]{骛Nm۴ml޽/(J@ ^%f  ]zģwGE5n"Q 74i~ ^vBv펜&mbzQHu7UA ~`Ţ6ߵ vY6J uMM>b@ Q@Ũ __#%Rw2}ozz#''ϟ4nlA]1MFg;m˽ ++kEPTYv8~o)"}|33322nupͷ3FH"&W,lޭzIA;Fy xQ2t⸊Y ],OߥɐpKo̒wj{Ŭd[Gy>[DJtr_`/kn./el+ //o: o)55U+=-`f{ZZj%mLFCg \*B]KQZ(.oΫx0> )Lh67]wqIsd凫 ۟k _d[4wr٬hnȮU@Ǻ3yb X.!O{.[rl!(g4Mj֬YS)lL G)jÂ!/ 'mm"[z1t.Gg;n=b'bqv]!*U8ARȃ,4;0ҠۘY7ܿd6!!J6g[?%Аl)!!!!!QŠvnչuv2888#-ͧ u]wnplޱfѶCauj: L9֧ww5jn!DEal>|# L`fbٻqKC |N> rtvӤӀ=ǠD$tjp_(A9#ZXn6m5+w_ԉzP%;umcNֿo4ؑwX?͞ѨMFTz{doLL_G7ziGo㛙!7_ժwDŽUs64obe,e rxxow߾}/^WW13gz饗iCCx.^,=x'wD瘍_@?/$ֹy,&'/n gΜ9|𨨨{ҥ &l۶mРAL‼-ٛW?a4קgwWn R=ϯfXì}XEDwک~d5Cܴ/8o 9I][JHMV=ȸr)?"UdsFI&/xaG^AwJӳ'hص֭ ;_uQFvW䜊iam7^ߦo'_BBBBB`6/^HP9IjKtj]7}{Dyy׎MnRMD!(@fj]OBBBBBJb `X$g.+#Qָ|钿`@sQCBa2 MW wbN~̽R0u۶m;{MkNksܳz(uW(rL_jwzzzjjjڅt,)lv.ץY%$$$$$*8133NJ0b ўJ[BBBBB-Lŋ4O&}M7V#)-!!!!!۴mk6FɃC$yKHHHHH:6d8<233z:!GN]yle-Q0'OԟfR?=R?:x:!DZZ`x衇q)))/_.guzp2şw^^ )6l{:Jrr2zNH1W咷m% _~'6h`׮]ׯ_߹sgO4ѷonө(&.^wߕ}ݘr{\Xx1TQZ5O'0lذMz:E'<*}֭Id-N:-YtZ$< b;өGJJPi?wl]vUm(h.[BB\z:ħ$vj|b4T_*+35###qfmZAY?$yKT89s_V6n̘1۷/ٳZf5-MYTYVټY(ݺY<$#QHKK[xqpppϞ=fee߿wILL裏Tdgg`z5kpG|T<ӟ~) 6Df_~7n>}]wUۉ322]vֶm۸\^ɔ姟{Un]2EreKOoVC4O(o[j0bn׮uZ\ҡChqNJ.]P999{[jչs;vU۽vZ*ư>Nmc̥ w,qz$$a7fh4B>:BqLmO>+˗//u0]at ?c0JS_n]]ٺ{W^QwWd$VR?zp[lf{$~!ٖ-[Ң;w _Q-yW+o&?W_3F_-[ּyk+0CCC̔C~7EN%uԚTd BSU *Ȗ!3O=ۜzEDD_*_DիWtB gϞq_{5g sj+`\Vq}Pxv89s7\,FI}(&r֬Yy:Ǝ$dQT=++K8DÇs|I9"doV ?3tGңGE5!%\If4%0PQS;ek֬ݳ`k^-+BBֈ_1X6Yqƽr5j#5B":ĉıEpے8Dz bÆ Z`E/^Y>`Lo+Slj 2|WU`yUKz |R 0\_ׄb+j-3( k5wc]wɰ}.~.P|RtJl=%?׏GȨV [Ν;qh8ks|jؽTB7 }O88&L;w.ewõ-Z/MXB 6TTcG^-\O M,T`fϞMpCqcQjxynz֭oy߾}IU3!+KYH:IE_pԮ]ۻ;==mH?׮|yglL5sOw Z'`oWtkx_'ώ;r&22fW/!Zc] 2ľ!G}T=h\ۍL5=]ѣG<7Y]p+zt)ʐ7N6&7$$DhV/?,Qy+1 8B v@??WW@V1+%OA%VlI|IahFcfcb DaP0%_`͚5Th@"$njQ#+.yXkaay $*dk[LŰ2iLkE?bFB8Oe5id(yҥze˖<2rH{E )jM[T6.ZM6;'y>8ptR.9$_R_}ի:|'ӧ$&_ݻ8ǏKKK NO IN NED@b8CFp[nn&1][>{N;?Vԙbhj@PܜνXan{08LjBH]~V@p@hO=ԩS1tk׮nQ2dW޽k :L%p KEǁbJa9`%pQ,޳yf>vҥiӦTp<Kq/^|qJ,XPux[0KȠcɅbEkԨšd4CJcvM%O?tĈ8: >5\%]oܸ~D01eWr+w-V )>#Z/<u P; վPrYVVMc^hOɆp&?[}]dn!mH'Qڮ]ˢ빀WA{ XgmkxG}3Qc6!hJ*h:k`/Xyƌ8 BƊOD 'QFzy'/9xfx9$#$ƥK;jzN~z=д3gvԉ~X~*#"g7ܶ(5,),\}#=\o?jmT4c=FGIVwSEBsC]!tU"駟E*arq͡-Zh'5͛s <}4M'QjYw>裚oڴo]|96^g NR{KG"W%~N2W=y$D||A||4,%K R)QF < .-EIM1O6L޽;b +`5;wbmfϞ wi /гg_|QK0:o޼_u֭_В$M0 ~qW]u DA Ɇ]&y+bGrk5ĉ'RHk qu ^z0xxbI*w8g|'tn߾k׮6&`q)X(I]zqxbB>#HʅG .F( }Gj=q:@0:˦Ob M6TM`k䓏<6 oiN2ܹSÆ yܒ%pU{Cy='xĉG PڵC8!K2(hAyǩ'o؍tjRa5^uK$bq0Rh t'Vx "Ux5EmubRBz\\$j5<@=$1D8I<ցKOs%!Kwqlxv[o+ {p1;f^Y }N wQ pLd F _+BVօ>;v7ߌl2hPXp 0w\8cǎ96n ·OrCZS*[ N[1}QX$!Pk-X>}? SlZ[`ҹyӦݻ!lVM4UQ`nD~mII :2kmpW^j LFyA*2./*HP1sM ]jVꫯ&p[LLC\UשSZ䰢N%_q7t+Vf0c=:|mL%ԂAC(>4u~6Co.\IEZa5SĘDhwmiPEu5 EѣZH|a1XokE!,%DdDC#xq4% QvS­1v$UI;OQ(wk綝{nyi7ݻpq[EWbsꦨv`ѢE8Dt'Γl!BD$VEQSˆH\[*S<`BX{{܋V`ĸ\l5 ^z%.GnGMc^{h GtRvyV/j:G 2=mQU6~{b`kf,5z8 /<On _1-[@W\ͿQZJDH$4〠 :3J%Emܸ_|%$$$&O"}eJ+%Q%!?IuM:L'x~'I)e1F,B*sO`Uǎ ͛j\ڡMFĀMY5:Oȡ4W?= &*}'S<]?ɢMhbf&bjD^J`ÇCaaa; nOZp҉ɽ$u8F{}@[F-,wD݉7B8Ûid;/Ev'B'"T%8YaBN /VP*l]Q#CMq;?q1ڀI*9-MIHR+j?%&.@D>O(]X'3Jk5gç0 ,p?ʯ /S$9jz2fpl9#zpIy7qu1j%{nދ={68~lq p`3mrD%K?'1EFg~Su)X;yS.H#RGFxXHC]Wx)n TQaM>]-@lEbME$Kxu8C"sD]ڴ 3WL xb0PfLpUŀIOMZQVXcIŇ^nхqig^|E Xr|zцDL-|e&dab3 +j#X +ISunPU"o~ "\XQQԔ>h' [JKحs޽b  L]Fޘ3|* 0 pb8XWB`Z"Vv( \i~f( S Ӆ}w?v/|EB lp9ˋ!zGbRp66񫯾4?~-[t)( \׊@AQQ*r1vÐzm__//̙됐`N:\& "o{H4*jhObZ01XND=sLEm-_(w uiFEO/_7z_K ᗓ%t ok ٥ӧ) , IRRR =~D*J(+sQA+Z߯7C:uD꛾1_~%q)9Dw^h?Lj6X]:V.E?}g qL wYP)5A!T$&{4͚5sv ԋo̵wUI f L&oǦj(vJ49c$O^0.VEؼy3n-IWȩAa"q1jdǎLtwk5E/CEI1c.J՞;w.%~zjm)ʝ:uیx~h!'ZWI _I:b1jLD:u$xD|gsĬDEEvx-1w8`һwW,Q֬Qܘ`ź緯_iӦvcn9&֬.{i&gY56j -b ,) &~f4Hתp}#,A-ZX u~mGt(MFxTxKЕriq?__7P i!F4|T lܸ]C,&fxj[EAwA J=GCn%撉^|N>ݦ MTְ8T!~-7o!yiTfh[-6la[n8 9:@Eo65\p%~ Yč ed~VƾC˜rM?\DKJ NHD?&Mz饗W2d]ZQ^=3~-C@|]w0 6L&%KX,XСC|4h$j &zYUi=֭{qhΝLh„ ڪzpT#uKqZ|ifAX`⫗g(r7Wn]׃Ŭ[DzM6$A.\5 ƍ60qDغCHyMs"bq؉Z4#!!w Mof1ț駕_ [nJ'waO[ :gw z sSpѣG &rOx06!#ŧj"@ Vzl1Vͫ >6AG?3j!=%pR)g.Z¥`%QԡCVjVԹg&nAÇcۇBuNDXNb@M'c[h}vBY/*O:bV̙T{Ϟ=OH%y ǏgFN9r_ůb}ţsu%F0T%E{NawsW19 eB="0 _]X.-FiV> ޝ?`fPzʈ___1"SuٲeDba=ǜA*[l5``em/cܘtɣy睄6$ŵ/bj(\C|E!}rM7)y:FFFO>zZ}GyCmhN-d#V-ݺukƍ}m g  L.#:ucp+QZs/ѨөJ@?#G+d'AIXwWuSO=%E#ɓ'z o'U?*@> h[,III ?#p@IΠMǀ"1Pϡ*5Ŧ#, 1r-((HLvx pjGyu-ZH(ӧg̘o~m۶פhTun֭%RZ5m`lK?:x/wJr-RPiӦ/p̟b8z{6N* _}Ar\R* }ڵbE? ૯p#J(& ]zBcJUZDFp Et׮]Ν+j4%Y,BuY2xA<={O72~e+;J4iqٲed֋>pF,`J6mhVhRy!|oFN:th2kKb` 2ł(MOMM%$$Cl.;PQnSƎU컀׬Q>,]uq#R<|=ɴQ*~bh=~X֗^>LO]i|ЬY3}|^kܸhխSNҥKW\*֭[lx|)QP;x5k<d~vLIpEJ2M[%ou9#Q(4h@<}3fRT/Hoڴiܸq|[%.X'0:qĄ nbauj9}~;a3m8:Z8v9L1ba(0Uz)Ф͞=[d>&,Ⱥ]dƍy>|8t4\6K.ƁOa]<ի[l?^@CV܈XTM%x6 ל<''Q[oU,pʈVfMm[l nL"ټy[ϢE W}v}KZOُXP]!]pR:ul߾=<<|Μ9b'434yda>oT~(|_*7F:lnO>e }[x0ĒG}#5a1%F !!A駟.޶mN2EH2bS|ޭg̘c|>|l$cɴ!ChvϞ=W^ݲeKځp`ڌͬ(}nݺ5Ѻ0:X̟s=8\+Δŧ:hS\(:K;3~ 6hkJޤpvLl21EQ{qL=𼨸Dз7 ֭{ 5E^]vܹ2&MҖܹ"Q( 4011I&_}qݗ.]*627oޘ1c^|GqE6Lrjժqϟ9sg^}U#Gxuū 0}jCVymzf~TN:9HXQM:f5|p$+-Fhs]7Z̕f0_\qN>B)8F/ \ .f.xڕ#j@ WTm߾}45nq%畂kR@b6X| Z%{ '$"þbpm n%1]rJD[MU{DA3[np2__~UE&ߣ86(*0%yS(}ƅ,uvIUc6gAl7 DH4-~駒%b}Ybb"ưW^}Ϝ9SHb @(h׮ݪUZjuȑI&~mZO>9~!CDFF؄ìܹsؐ Zj</YٱcFСC}ݻ3Á6jܣ 3Q\Fފ zp˻wȨ"}q6%KP%ɁիWCaaaJI D[lY&Ff+f;vk!6{! H8a|+y.Ejj*n[k4y{Lh}뭷ƍV!~衇`zgw s 4l0XQ2e?U/[Llcsʕ+_~enmС6K V>kBCCɐƍڵKryXe_> $oJiӦp'L$0wI@QӧO'T3k8{%%W̴}6>dzn:ق8C;~$zh3|۶m|Άµ_OvÆ cbb#vbA@>I9PofΜ9gΜ,Xp뭷*ܐΝ;.0\D(-Q!pbC7bj\~BRL$( ?:vإK/^ӂoъn=/_~av*aI>|;--mݺu_DӧOxĉ G7nVɴ8999Bݻ?Ӫ\K/i_ǎ+::4sLE]8X+$yW&׋-:vǗIc=W ~Nrz%byw؁A`_ޕPQr&iz7H%tnM`…]wns.Έl+iӆ],Λ7~NZ yvoybɒ%=111bbq׮]b5Zt)$ 8v=Jƹs> 6@fZj*ʸı 1kCBBސ~/b{kNipPd&LxKY/2rțo?ߚ6mJ&[Kg7g`{%|_o>*w]j"/szΆCHΘ4lЅت܊ڽ5b6۷oTbccz,B:8VO%(((44TA@Ecƌٻw/.cNN@%'c雒k.<SN;W&5gТ{5F4ErS ij8#QS;y$Q6gΜÇWxiiiRԥ%9X!67o>vXVVV.]U(OV/;[n]pT/^kV?v0=k2vZɕ Aڙm۶uܹF7KiP|=mH o|}}}ڞ={~'[ u86{ԫؖYCX,=F;v\d۷oo3wÆ 3f Xf͐] "ЬY3.mWϸ`OKM9iP p%yKTbZJ8|^p-⡮]Ƿh.%4?Q5kn5\yS+mwTE7h.իsoRRRhhhQ#PL&cr\B]TVz{}QQ_U ^ZF'D9o~8޻woCH.гbѣ8㌹S233۶mUR>QQT "mmB^p^zxjUTWt![R"""bӦMNE%_1Hpݺuɓm.#X2,… 1LӦM{g|xf' Sӧعsٳ;[ ~c~'A;vLLLb  ++h4bLszz_]tIKK鍻ݼ ݻw)$Æ +ӍmN3nBjk/V('hϳbFlŁ0R|{ウf`x$8D|fdd||^\sM|wy+B66i8;w:X+qy"dS\7yG?m snݺ7.|}7M6:u i˖--M6d1XU^xQ#hu [nAΝ;|G}T 6̍z}Q{`!fTB~ͣ!oj{NMv6;QNMO>|U]<[KVn}q^{;wA0=z(L6 믿üW p7|Ȼ t^E .vf+ nPp333yk,2 QN.{䕘NAO=Y{CNBzQ&W-DQa B9)qh9 %6Ď*K7gΏZܷo?|_Jp$cƏ_v*OPx{B6htUFQ2\2|TSС.6޵kW2Odg(AJ]#,6kLۯ_?q###] ߥK~aY`T`ĉ9l'[dM,Ԭ a( N /@͛7'WHwϞ=7oO8qͻ-[v 7Y͚5ݻw/zJ+ 0S{_믿qӦMq<"=zm۶Ŝyzi\?3{l,ɬYIT_'9]}ɨ\:sd=N玤J\Y%%m{ |k0^PLNNv 𴯗08K.]4J&!!!!!&Ķe'l(Klll%]. {}EWug@% *uE}KJ7pAܬwג]=HC}nt-k܇tUA - IQQ@A %?6]KKT / 5AbɽH}_EKV1J^'&od韡T^(`O^tɴyO||]t9J^ Xl.6- w}6k,rlY/P0:3a}OShղ[[N Trq.ߎQsW0I5ԛ%d|#{ެ3,N$`6`(pb&:;;왳e:l6_LP7n=Lᘼ/_xQ#j0vDdDB&dWj'_s5/NzQW3nI֟)S6\K6X$;X*Y=KtV'JV$"k%lײmd2ed+^4nH,▞~ixP!8 Ϛ5[́K V"g\V %B2T y؈$nJ֟)SWfV^GWW]d\dVf%/"TÙL'2uFޙ+JAq*Yœ~)^xXqe5)p>ׯ?{L m;##㣏>?~\XX5[M - y+y#WE)PfJ1K֫x  tI80CN%s*Iƹ˜JE,(0] W ޫS"-+ddy(#ds`B5|h~~wu}F [zs=zt``Aұ7T,6&#(PHfModKAZ^xJyeגm^H`ݔXKE y[Ӭeh6DJq(ܐle)dp:T1ɥxvFL{Yv튏?"b]!c9%o۹S5jlܸw^>>dϚft_hJTgDmjK4- Y|8oؒUJAɊ^fĢIhFŋ-YwKJMPgOfE8Թdݐ&مI6Y8\619h!"d(?CJ^Hǒ-%Nsn 717U a^1*s8?k J "[45q,YWOU=>IjPyŕ90! "gH(%j[wr]er|X{ڬU^i"B*@DCy~afV{R {=}ݯ_ [7-*@Z2Ńpaqξ^Qq  %|[gk"/sΩT*zѨ/~v ߓϼ].gJrRfFfeXbh0 ?W vyK1pB*4GZ6C_w*-[^2OB H(?L2 8\*'@iS_CDx|h W3#@ϠbB <v8t# <ZQÎU0#|M!Az~K_ֺ 8~u$<_ZGӑȠJ*6 J? h?#6""~ǫJGl|7MJuف8?ha@ [/ oz(u>%J]pj7$ }2soA\.\f\Pd6&i&;&[ϛ)(M&ykvE~/{7nCS~$t z==l~ p%N|:&:t@iwv0PqH!3>׊t!)J,Az'Htj: "HxWa?a(Mspp{r؝ƃUbHWk8<]AI?ո܈|Dlz mCF=&s׌t ΀!զC" C e׼pĢjg;X 5W|Q#d:`#I`wIkT?SxHk&,zk Aʉ,2rד8k 1B/~nE8mNŎsS%aMܤW.g-C}3'<sf2"PGD/5)^rG!x #ބ;5޳s?Ҧ yȑ^E`7{7U=P f JAhx6NQQ/3Ev:iiss/3 `гl܃;6_",,̻n2nqqqCt rC"hs S旯L&!d8׳8 L&zG6Hb*5<EQo^>c@Mz7y1)d//&/|8D,q\ c,p|+QxK*??Ct:ltɧ/"ዌm S ~e"7Oa)5pju,ٸ4dc\9.\N;CgDn]p9"9n,j)[Ho"+lIM7 yϛj3W?ݞaqj:zTa`z UD^z8Q̤(ْRS [4*<%-Uː'Z&x+#PV9Bی߿|S0yƾeLJ.Py*qS+ 8Ϟ`#$R[+0DG]K'NZAajI2Qz4q30I&5ֽ 6xמEERyr<kX5$ɨq"ٱE.s~Hǂf,T{t|Hf+6`daAqr*L<{}P!<⌃9ۓ*(__$t׫4K}WՀ)Mi=J2["!"=zv_n\-9IQ d͡|0 OG1nFQѼu@ 5+3ybrax't݉"Mlt:mu ;%jSZRn1eeP;nw/<:R7 Ȗ`sB#F4)u[ =oܚtP[润A2&k.~x8^b=~5˷&2ƊXSXf0Vl֐5}~p@DG_=d@GZ׿RoJCѥuՙ1]_c`tJb`AǓʚd>ORQ>}ݦ cZb:V>qY|z}k=4vd٫W: w/*Ǧ56̓.=Jg|qk ֶdLEtzZ;ycˮ]tÞ9%(Qj`T+X5#̆-+¬o}wNIQr*0|ݫwza۱gDC&4Z'W[ _kZvl:ޤ&>,𤉍5\|RB2^N$m3:?r1l'99lj&ķ &S rcE#yeέ-oro{,|4*&Xqں:,i"vm+vו_?D{$:햒dJ3 7'c'Y|ajvq qUG)j'T%+Cy)BSc<6iW'lʷު%n5:Y/ͣ><@5# 6q~": n<=G#2N>v=~1ޤ-iO;-}z?ղ/Kb9~摫<CaS|7Am [ Y7 mx|i%&=PpNaln}-F5ٞe:j/s0Ga crlx$<;ugH\W8u<~_e:̩.rᶱ:[Ce~ w<ӟK(Y?yrlSco{ƞ-O:;161'Rl=b<6z!,}#VN l\T$&22eVvN2V+hasagjNw')2+'g-ŧ?%;2\ќ|TԄ/d@D[wͨB޶0ymOwka;dٰqrIkUZDc lز8l]ggun҉zfb8^joz]҃'Bfͥd&N,5m‹~0V7ס71p AY;K=Jӣ9qg{OO;Aɺb3 (0̙Y/=m7uqufF]\opj[ЯXܖap ňQ>26#`H9ANpz畒iT$ 0q|]DS>1]W'l[:Ѥ]% n clPKM=3.VYv+ɑT L> 'w1m:by G?dC%-؝njTf#D*Cwo3bӔb}׬V],Q0fE BFv ߻(T({zB0[͓p,yÂ\$:6o f"1^c֧<MENlrbֹyanNcL`nU^<}fISVUb[ UVY }ywtU^,!sKt$| N T2)3g6mfH [j'?3>3Mztiu-wex*\*G:a$PRu)DzޮEK^ġ9jYM$EBԒD;œK#S\G[w9FnMeD"_`^)iɎ((d S{?2uw8SM,:~Cj`ly[`8i:z :7[@vpN()tgEFW`Q͙mc c&lk ҷRuFY\NdVI֤k 9bKUHQ~=@6Iݒ>-u1v_(M-T1 Mx(O 6G` k WLL'>%4x #2GpÁ{ޯXqgPA ɫUKQhn)_E,D*Dz^>$(9!9s2exwA烶iMYu~N/@jF ƽyg w\:$n?>02^P^@c;xC`4/j L[xAQ47 tf_)'iV!WzA'el:cfں[&сK"Nlbffc[ZZ,5ϗ(Jmt0Һ(3;gH5z QCU8\qM ojJF.Yb[OԹTBOx mL |_[U,kttL,---TI0 S|Kv7kb:NG^rm{Z3Y6iX|j1Ҕރ)WT[_=IKrHS(,ٖAY ʮhj[PIBWݭGX&$&:]y{}[☙VDGok|bdH%.|`Cr6J\|]ZZf/_D:88rd2b Ba 0Ps%(-Ơ%A d'Ohpx5W?vk DWgE4>b^O;"DOES*6ڀ Oa-8Jh^rn|k!rzZj1-I<޺{@lDL8sx= 6P b(x a|uF,V*j]/dffSGBjf (lo  5#:olɎ:RMGzm5( xo9t'=hz.a*G7p Z\2T׋'.~\ÙZP|;úm=3S8#/znBuӞ;Os++ S;r ǃޙ\ mO.bH2mфïKQ>;ޥx#<>աc:b2᐀8?)O|ơk'NbϮ\3m⅛Mo:$YlH֍ ,**qszKwsɧӃK2(:v&'<3zvIENDB`sardana-1.2.0/doc/source/_static/snapshot03.png0000644000234100017500000017041512174204305022741 0ustar cpascualcpascual00000000000000PNG  IHDRpe_ pHYs!!>IDATxu|To'$!$(Ŋmqw+.A z %Ǿ̝9sfyswآ:EW$$$$$$$U'@onfζ=^53jDw),,?U **Qokm63UOg;9٧EDF#buC" A: sxǨ7?&mN}0 L:]TTRu,H_i '@BSD&Sw hbYQ!*KJּl?GDE+Nqq!6V:(s33'{+x3]TDxK۷zmw50w:{*VO~_%$0ϘR=8sJ>yYD8 +ˈWa/rU4 pz&UAsWq}oڃ<}qes!ĥ`՘@ "cmb|:[] orV"Cx. 6ic,t)o_8/srI_LQ9,4,u|'Uo 6fv11ca!1~SpIwϺ% *h}L_pkޡ~WWz&4KFȈXYDFHf!k@T)$$$Laay}ccBWuIzގÇ?ypԾWsjŽe)K Z씦zod/3 {3Sؤv /^m\vG.nԨsoYԁ#Zo9湛nLԿpN/Kbo}W_ra.0$eIwTW-#O;kض-uu_uCjY-%KH#b"?U1:""*6>48(>0C9K{WVrI<94d>z%;]p]ltTdDD`>}V:g萰X b@w⃘P_kd6KnqO03H:"2&48 6c눏ebRqё! {g>.uLJ QzKKK,㝝bc,luC$$&b_76R;v3O%~~[UsOX|Wl,}jߨPp}軔͛IڠRSn]>Xƙ{Jnssy=1.斱>޾.O2= Gį!|ì>_}%.:,Fۯ|w ߾tTp۝[u:T_333n]bgiu'C }OY/^vk%7km>-˔33Zg^ flScEB6Ѿ%2L]T]ӛoސHdЦS?/I(iԃ RLQsI(Ѯ.> >WkquB -9&hZ8GsuP s6`~>' dROo6kʶd!JHH|1f66N >>vMnX:XEڤg ~Fx`26*<Ď lRV);U tхIJbDx] 2;#"}j8%b*mg5yTE6'}dg;8~˾m?gߍ%! J||L:뽗,--\*.dΜ˗%i%M4_šSL:uj^㓐eʔ#Oҥsvv tYfgÝh~ypOsُO˕+WP9s{}ҥgϊ]]ŋMKfȐaʔ)ZTUZh&22r;wΞ=׫W΅P… ϝ;gaaq1͛7lp,XgϞ((B = JvD=z8pC EگRmϞ=I]VN~&Lh׮NlΜ9ǎΆ n߾X\|ǿn?sss+k}\+W>{֬Ic3ssKe/^EH[xq˖-޽֭[u!_&5k `ppԩSQG0 $K.}_~tFc 97c):4_reXXXƍVqM두Hy+j:]u9H+ % W\k׮=NժUm*6`\3|,V;o<O>Q7hf͚KF^WTjժ-B"oٲ+a.rF߿ OuS^!Ǜ9s U:uwΞ=ZvBSS> ʶm5j{xx_>{E}-\.%(PiӰ0QF"7m4$$/Z`L^^^FI) o*SwQFtfhH,  " _R(m &8G=E3BTA4 V!xܫV 9rdܸq B{.UT4ₔWT" *8::=0fP uԯ^BXpAs!}W֨ؔӧEkN6!G**DTV-sЧB,9r$ ߿ej<_T) c6פJyz*MVӧdɒC%Kd/NABBBB$ųx>J `;$8#_p޶m]vAzq\Ν; <]HիÈ;w$vZrƍ7m daَ;¸޿ e._b߾} ٯ_?*g{РAHsZ|%RhYCy&j Qj>F,Xd0va˗m%hYՉCS1*đrʕ,Y޳gYfE^O? #GaÆё &G 'Nć>>>q:u8%`3f"hģԆK]L"%"E=zt@@1Wől߿ʕ+ 6ϟ?}l={~a!D]v-!!!6ܸqvn:m m˖-3]tؾ9ـݱcOT(*>X:u*S‚9 Ȇ  .0:|ׯeg ci2h`ʋ*#H|>o Ο?7?'TZ= i0ܽwannnmcca?3%Կψa dgɓ%$$$$HpWWaÆ)*ϛ7S=z;wv]vi,˒%K 6}1ʟ~iW\${%ZjE[.}F AiҤرib=_EܡCJm*TСòeːm۶GmذA3k֬C ,{6m±w]re.]f̘aeeիWƶo߾PBݻwtH*HGEEM4I|K4Yf|8sΠ PԇOiӢۗ1cƖ-[jlZtC/SN$vvv0zL[2dh޼۔)S~gv>|ի׊+tɒ%i ̙Ө6 U)RN"x͈#={-[_~k˅؆ ܹ3:99yxx;vYfexw/_̔)P9M>3y !:RZ5wwwE;gq L2W\7n x0KɄ څ 8*%?zsݜ(>ǐ+@Hg*ހq1]=88]J֩SG 8EeڵkC\ku:>oի6,ABBBBAiћ Tv\+XL^zџ,6<?ش#?Uox*JtРAcs* ˓mh0ᮢ ^1WvV/p/d`b?o^Ɇ=ULF02Xbׯ__̺w óO5k4}یķOeH@tPT+ڵkWyxx$$$$$q$PEwQjg_mv=<<"""n))"f?eƍ3f̸er̙|5kV.u9!C*Ux,.'S0.ӧOa fHk>-Z`Ax"h.W\X.;wn7n\:u;uT,u~ SϞ={d6ݻwo׮]ҥg͚|M6qjٽzjӦy֭a}=sYd(;|jN;`cc-FJ,4!.Jcg_AUOLToT8vO>kV\͛9rLͲeˊrh 8Iy#_d͛7ѵ ,[YY @tV$a"Z% ¾c'EW\1ѣG.*i&T8LXE *r{}҅!7nlvSN4O VeTLAեKV[:ZjZ{1{GM_2$(U"i4s8B<`8qx K@Pp6mm3V_,ظqPBAfY'OŧN(^if.DBPpnnnquhsa-bqP˽{вXήm.I h3gwbҤI֭[_=3...uݽ{7%;IzĪqFrww'uD԰aC46_,)S&gΜiKBBBBGCfFo!Kᑷ* h? PҞ< naaU@'.G Rl4sAg|U$[4~>+AF z. 5Ӝc>BS[+c>AڮB m7,,L)͛m * жnEA#2:5%$$$)|_NsrrR>a#G@[u2ԹhWb%Fj| Wj*HpmڴiO8ЯRJ,YrΜ9ڑuBڟj׮M!~ȑ#СCw.V-!!!!AתUω'$rutt\nݓ'O<~x\Μ9gϞիW?{޽[par6m#GI=˗LM6(B|힞͛7oܸ>nT3gK.Qcǎ ̘1cΝTRYfS^tرcؼ`큰-2$E666fڭX"D%K-ZCX;nܸٳg@;wų%$$$$Y$P8$'֦T vqqӧܩS']relF~rǎ,moo?`/6lXxqhv߿װ~ʕgΜ)iBp*(LNa3f<,I&jɓҥKh oo:tuֻv"/Yx󛃃mw o ~y/w٨dɒM6{Ţ;-ݦLW^{ӧOa4ip9r<(((44 aSQwG[7Qk!׽ R̙3YMc c(ieeECtϒ% ڝW\իWA_B*D%J`gn D@hh$2C[nmժUHH(~ رcp!Bb͚5kB!#Ck׮͛k׮H^NEѻO0քb^Ӧ֡ݻӧa6mڼʍJƍk׮N?~<ٳ߾}nܸ1ݺuGgϞ5LIMcU\Fd))\BBBB__R=B]hYKf׬YY 5Z,OST8kh_;v|opEќ $ӧOvpϷ.!!!!!o_l⊊ o 8p@ ^dq ,z^|8Ur圜y#}aÆK~ӫWFgޠcǎVt._|)RԩSwְaCHsl>/RH>|RJ===֭&M9KVѦM`?M6uuu} f[[[FR-t^hшz{{ׯ_ݦϚ5k58qVZ^`a||͛70UT$1Tv?{LQү^G)*I]rڵk3f̑#G޼y_~w޻w&K qNŊ O߿s uT=qDm777(F` k`ŋ?zhС0ѣa]v?BY&Զm3gpҟ9s2$hٲg;OrCW*2eܤIhJHHHH G"g̘@W.\7ntaEJөȔ)\6mZHZ% 3fLԩѸWEH(|ԩSӤI#qZmICP'ԯ_ "Uϟ99r.76&&]+.#!9!Ǘ-[ֽ{ʕ+](۷Ôyv l$RJ'NHp%K&$5r5kFW^A 4ȟ??rvSEAg;wTԟcϙ3gGm 򩊮}w4E,1lCp/Y#N&XCh ~nǎF׮]}ѵm%iaV(.4Ma'2_~E{VOő* k0ܝ1cTaX8 m۶ڮ򷄄ğ7?G~Q9bu^_OgNIHHHHH$i(\BBBBBCH H.!!!!!$!)\BBBBB"IBRDp $ II ;w#Fϛ7UѢEL2i&3?*^ix̬u֍7~m޽ W (Yd^ǎk? ͛ŋD.Z}7&O8P;RR% 1zjժ5mڴo߾j*^_7OC4iF#qvWwѪU={ׯ#ҥkӦͧҦMˀ>QBBBB(Q>5kVHHHddd'O,Vݽ{ھ}Ν;1ݻ3gvqqyeѢEOLV/<]E M/\ ;::bub3Ǐ&P‰' k&-}c{6fzD gdx]vg#CaK ʐ!C?.dT{Æ 04SyZ#2':|r3+(jժ9sjNHHdɒ\rl!:a 4xv s F!H7+ : ?hÇ"E ^LQ=GPBp9~?{̴#.+=3Vvm&.X`9 %oY38hnnnBQI\kkkٜBa DY8hd=݌j±`zar =zjR200i $0,`kr(kҤIv*WNC Aq-݁Vu&w L Ǘ/_dqzD(E8J'X޽rӧOEߛvA2d@)$#K3(?`}z!g ( *kΗ/d%jķ*"d]^!,D9OB0Dxm۶},w%(ױcB }9,˜93(y!E5j-(&ZmڴAmQ—,YAŊ+L;Bۅ˅7رc/&|o (4%pQyp 8ܹ#۷o20(F" & +3f?QjqHJu6: ߽{mܸ^?uzKx 777u8~1R!T,!>!-rle˗/S`ʔ)0:myzz¬t.]p8nT9ުU+:5kޠ ""𧶺+J}WdE2A|Lʗ)SkxuݺuLW&֭[9NI=zػw/"X"#R..?s~N>-IRp  B;qqjDmuϟ?/61T! PaXHmC?_'1]̨~qrΒ ~O3m4óThڵk-[ٳKf~U`* m8n8`ڶ§*6:{^ U~XF֓hnG~U!ϩ0޼yӈ_`lٲK,:t(DnT0Mc?FPޣG,ԩSOθIbL}={dPĻrӦMK3f$<{͛?~ҥK'ǎ[psCs̹r MrfϞm4ĥԩQH/^I&+W4] FBBB"t2m۶...Pט1cڵkWF 777m֬Y#G"E.]JD&—cǎ*W\@NP-[nڴCmڴ!1F(5k BBƄuHq…p!o.9r56 ҥK߿?~Ѡk׮]LfիWo߾br.rJ(!3I;M\AXnA ]QSdAWz#j)+VlԨQ˗/o֬h9B9F06{| uMn K`Ċ,Tr9J~gΜ$Í]Ȝ9iS`_\CFreؔj!~*˓%K1Ee)=KUHqbݻ  ӦMZj1UH2 ,Ȁ̟?I kIzZj/_>3y֯_Ltp%$$$:>RB AM"n6nu7wڅ9s&*S, *%GիgP3A7m?~B94sرUVQ޽{hs΅!A+V 7jԨf͚ AN>=ߔ+UԿׯ_mdʔ . !F'BdL@}H>8Y5nСC!GapZ!Ae˖}۱c\+W.# lӀ4%|Ǐϙ3$eǫŶ:(0.Yłi'(@&#qF͓4DFFB0Dp* E>|3(U|ya).ѵʕVj֟˗/L-[`'8dɒbŵgtӧP#@؉n1jd5,V ފ ;8p@Qs#!}AbrٳgRkEO̙ Զo L ɵbTSj߂c!)yHLL n!?Y0d+WwH=-L?-zDɹ}Z<}Ep]t G¨5kpSDgb.2F)Y$ԂB[.z !%[|!:̴ų5+5j : DG_*7.|EtPeD!F [ҧOObsqɓ'-a.'܂xbڱcB*8AyڢަwK&_|c5R% LN:թSO 0 j $ II%$$$$$$$KHHHHH$IH H.!!!!!$!)\BBBBB"I"˕+gccs[ZZ&N *hTwpŋM׋CXbժU╻vrppWޖ-[ċt:gi!!!ŋr^mu)RԬYsǎ[N.xǏI2e*]4%OQF'N{}ƍigϞŶΝ;gϞ}޼y/F²ejvt>W`eefΜ9,,l_?4it=<::z;  w񆕐[@pa+,W\pcǸ+UĮN.>lٲQ^JĻ5qY[[S 4F@ܤ0B,}A`=tXTn ]e0&&fÆ DLBΝ;ӑ.] 8A{,ϟرcעXǎ߾}wϙ3}>| ;w1$.\T ٺuCݾ};}5jԵkn߾=z=z4oޜiӦ <}koܸQ~}WWWS M6$Ε+WM=zt rWV H&R ёdɒ9s˗g*nbT'ҭ[LߠG='bӵkז)S&gΜ S.'M O1%ߪ\2 K*gZ3gT1:\Ey㌑x+ 5(]_,S?$kqW…߿/^J*ծ]; &00jslɋ/fdDئe˖1b!vqDnZf,[$$$5$ -tR///<dɒ%]v>| !>yAt+;/aA"/3uI&]- AƏ1cƅ 7I8 L_mff%plN2ZkR"‚{1b=ڷo A[-R7R(L<aݺuG,$"7 D$k֬Aa*Yڵ! b#b$X7p$4ѷ+ Va.Y~|8S[SD,$Ȣbu1"ڡ"%IӧADm5 &p L`, E| \)F)S۶m"ܹ͍V;EyH1}!Y|9<Q8&%bVI,m;(ebui:JA8ċ~ ? ҹstHp x:ٹs'Ea30(Y{+>sgڋ꜅2=zTlYr ²bKbH(P;\&Mc1Wrho#a꒨1$/^Qqwh4BbX{\lBBiv.!!" h&tni'Vކ BA! ΑhDaz%H!.чq]X"ڦK)^8Sj4 \4 6.]іV(K .Gի=B"CXRP!4]CdAF$բ$lݪU+Dd'`%:s >1cҌFݻSaG2p>aS$O0cQt ^S\9!l+6aԩSaS3v؁[5ܹsFԹe˖FPzZ(]v+WZ!N:XBu.]"ZT9۱cG' aq!@|mۖ^)iÇ{zzb 3bzs#@h2bJo6F,c8=JLCBZL2Hn:,k˗gb*v,~ȟ??ndu4A.K14iB@*j*fg)Fre˖/ew͚5O9VBB_Aez q? H0%%G +RX(.$r߾} B)B_؈ł]trb٤ ZE$Ma vI5k aT6?:Nc WEC8N[c\X~w0a9劺OL)0`bX„ 8tl\(]N(E 70y`Qfo“`֭*nɖ%Fst-6fLU/DV295 SNf M'i#@ 6uMhV.a \,s~z=X:TUmڴiu7niτap-QNA s֗/_NӰ81^=1Fd"ܾ}Z_(@L%F]Dd3g늙Š!eʔEy U" ŋ侉zUBB_ƒThG]QcIMbD(|oJa* v7>|P.Al mplXIhG4Ts*mwٯ5-w5rN}jU`2P𭑓ф15T!3|0N64̴-!02L|ah"U5C&RQF^2ŷF˙°ajS .52FBBW_8D, .!!!!!!AEBBBBB"IBRDp $ II%$$$$$$$KHHHHH$IH HHp+E!C>[[Cb,VJ-m|nƹ׽#NH,} }\C*\B-bk/ޢE //9s#nnn t۷ϟ?ق <<<(\^/^7N]RBBBBB⿁ dy8c +U+v}-[xߎq2?ZAP-xѡĖiij6RPV\LqM4_[5jPF z/e˖?ڵkbmSP@.]NZ,߷m۶| ݻ{|]IHHHHH =EE~ۭ.}.-6dJ>]a]H%*HL(c UשS'o޼_§M>}cǎK.Gy7a{߾}111hnDC}A,Yœ_ Ŀ mZYA/2Dģj7.@l\fvйu畸-uZx݈(ncN[zeee?~KKK=***,,,44ZK>r4i2@ffCR^(R^D*tVǩX%20>c f(bR04{qVR\dsa:[@3ݝ~ƚ8$$ٳg/_Ι3GxxL k$͛Z0aܹs 6=z֭[_DRSDDΝz_޷o8-[;w݌3֪U+<<||ʕr;v0V|%Kv?dGʔ)K*uٳOٳ{ɓ˟>}Z]dΜvځ[lGlmm 4駟3eʄzƍ9UlpqqP¡Cė͛7Oׯ_+ IHHE$Pe˖ӦMK'ܬX]`3h'N6lA'J۳gD˒%KI lll)OCϟJ)S#TxabGժU`F *hrm 6 *DC_½ M:t7o=|pٲe-&M4h l u۶mKZ3C xΜ9hSʖ-K 6o'zB=x޽{< Wji۷ ^:p͛5 g9C@EDӦM7m,|8uԔ)SSIF 2uTF4mڴǏɓ'ܜlٵaÆD+'+"iy=(P(01"fq%c/0mp 8QQQ$N…_zb1+Dݹs'sAU\=\x5:|5kbgBG( C3oa; aUn`D)|@XLxGq:a*ʰ2p>ӯhѢ̬xx q>ӸN>[HIH)O\r+9vZ3"!!"¹i "=zTtiyOYLd$p?k}ݧ*冇3{8a8ND gǏ;v,eC#!lܹhM;sZ$g#B`۷ڵ#d+WD5n; :H5 -X M"DF\gYJ+o#yϞ=;wL K,DU:p xMpݺuAyʕ8 cԨQ#Fۗ !?">NdE$Oxi9s˧O!֭[[݆1X$2*Hp0 1cXE`WRe̘1/^FqΜ98E\NCR.E&TDd 0a2Cr9n6(核^[Lwu-sG Dk#k=z4n8y9Rq[V/^0?c$$$6$]xXX)t-xJ5(E1!"֐J8 sp b&'Qu(^Q \[Q##UCdɒB:I݄[Da 3݉8{,f]]]ѩJd(QhГ'Ok$f17oD|c A*]t!:ST/_B'`9 ԣ=u%w Ț ԩ s@$PL̜!%I!gŽuԹ{.嘺pBScpS+sFSH?E P!,+|$܃p`D?H09HcTk߼y)!~BRJ9rC(P@cB3A`_;~~~D6mڐdhPN jnҤ  !z: "Ź&q9~8R30 H M tk"RThvKqbgjU0(^ر#E 0Jn݈ݻwa  %TD5"$%l, 8pQF1DraUf۶m3;viԌLrLN\Q-0y|FSa' LNr&E Q׮]-Ԍ$֭c*Rw'Ӄ&Dw+y|cUaUf 7ˆM6͞=( j~J2 ҥ*0p3MzA2eڵ+72S`t>e0R$+؏y.\سg#nE>?S] |.!#sGAф @ d :T~T5sdڵ*Bĸe`PjSTսC. ;!~ b36@$$j+܃KϾ#FHbT.J*բE m B檝;wgB)jȦ$3v~x6 ` '.;_*2!-THdcbۨ*X<?dQjoݺ?˙L3cjO&\$?+ZG\2ჽdma9gY #^EgmkC߿>]cx"]B[G1ɴv Kxww,8)R,@SP,$@ݳηl'ܙ;wY=̽Q!2'VEgUǛCQ=PFj}bfep Mπ8\& 27.JUig'dZjE\}>|0#@E֭[U?!ȩ*!r^\" +TaJy9%SmI8_T#{@5M UyXz.2zi\#nQ'UBA|A>p^?)op }?AMZ[5*k}ݢ%o  BAp (AD$  J%$AQ*! ' RIip w#={v_: H%rRi`^۷N j$*EڂO ;^(S1|YC}R!H WFߗ * 7'TGKK+..yРAledddppp۶mܘgΜwD"1bӧ *)J$ <0޾}{Сٳgkp'N888L\GGdGZ[[wֶ{-bHQ^aRZKP tMɡ :*=r 7H~"0%LXF6(Vr墣l24Ʉ{.> ?`B b XfOȶm\]]5jջwo6Q $ݻ0`XN;v\lx\d 0l;w-[W^ET0C qrr G~0vإKiFDpy/H fΜD&AͿC[$m,7q4zel)2qK \[("k|<Y$zFFF999L;%I]):+JܼǏpttۓǁ+%gϸ1q|1"N8c4pep61 ͇O©ۣ6=N)SީP#Z\0cƌQ]3y俎F!˗/pիc_w6Z^~=ǿϟCe &b ѣ كjef̙|Q:l}@Ag)M/eeeM>wS`ֶ|lj ǃ ||SA㫓={:t&!;;;555''g5jC#6mvfٳg9O%Vڅ fbf V\ oI8֭[LAǏ y;wG;w5kFeffֶmۘn``E"QPPPŊ 17SWWRJR'Ԡƃ^z5@naau*TiGkkk^fMLfhh=vG/^HKK>www%)Skii!rNnn.I8A|u?-~,P(Zly9(_@@@F~~~-ZؔD"Ynٳg5kV^L<O?7 -X7nܧO4Xn]BϞ=ᕷmaիt_~?ڼysffy~)S θ8OOOׯ?v؃zxx߿ӧS'Ao嫓p5`a[SajQ ׯ_ŮKx_8f~=waXYY!?8~8WxKBW)ő#G`GabbRVӧ#m:;;ïFwX"tQA?k 6_yj |RLJJ:W{ >|#9bc IP(`E 0NT*r^}̙ڄ"GFgqN  ': ܹǍ֌9׮]ò%KBBBP wƌ:u9s$ի7na4h`_vmPwooo,s W'nժ_ӧO.]jժUJ͛7~~~п͛>}z֬YNn˫bŊ&&&sܹ3>>{...ݺuˇ?Rh9[nDDDffgϞ=zhӽ{w~Gikk|˭[ر#͛ 6}ccc֔9000Xtill l' W'j@+W / pB >y䴴4T_7xf͚h6MlfiišP(rssv{n:t`hh`‚f ;h|XX؎;PT{<}-dKA|gaa qpA Xƍ1oڴ=JPk>Z[[^Cܓq0ʨ!CuҞ mƁp8~^Q8\5?),[lJJ\.ǁ8D=''܄eʔ&QQQlb4.a#V  9_oٲ[n00Pcǎrm۶'O8Nׯ_AAAڵSSS,U/A ncccggCSSS77۷oce fTZ599=n``P^=== B߿F@svvQFhhhPPRhذabb{*H7ns֭LuԹyN3JA_ Eڵ+$upHf͚5!L!NNNlJ>}<{ӧ l\ )B^nܸ޿>|x#GD$-ںu)Sv܉0V\yȑ={V\yǎjM6 _~4iP08ɓq8T*566db畖VFA/+U4vXVlٲ%,P?~\\|pmK[n-.^8jԨWZt6oYfVVV]`ѬO AA|$%<**ԩSKlP(|l3g^ڨQ#ssO: w {*^Tb#˵l_vm##ӧ#GA… /_۷'8 p4K87o؄0p+ef͚CX}'O__GZǏccc8Wn]8oSSݻCb4ig, oڴ)?ٳg ?]Z55deر˖-3g[CA_'$ӧ'uA¡_s͘1 ,((8z(1//oÆ %͛7;88z*## A&%%M:N:+V@ؐCO>͏B:͂ |ʫRSS/_=e[[[>U;y hX7W7pI Ummm/"˟uTh(n޼9((H=2&ɠ]vnܸqڴi 48vΝ;!K,paE"r&-Z@0_C &w;[.XM t ?w\^.\УGp BC˔){ d5_'556/sϢ@eב#G^xaoo(B\%{ `矟={v!P6ldM6jՊbŊ=3Åo֬Y3nܸӧ W ؋SA aaa˗/6lΝ;; !ۏ?Cz=z`ZvÛ6mth611 ߟ]|iii3f̐J G߾}MBCC{O??Ν;'NFX̙3!o߾6m6,Nu֛7on׮ݳg,,,,84Mӝ&AA 6^zǎ:uDžm۶-daǐF@!lP(JhNj͛7Æ C:u`9//EFFv֭xfffvvvGt_tݻw{7߷oǏ1bܸq%~AÛB8?~ɓ'?x u߷o_5j$v۶m-2dȘ1crrrT|ʕ]vMII~C< bK󤤤.]GX,fߥCˑ4lذdO  >nnn?@ ܹs'd Q@ [vxe(zr`wޝd;**Ν;۷=z… v|ҤI[ne-`:///9|6*?zpp0vG88NA_$޷[nl0ӧr(()DQ-z8q+8p\c/eggd26vX===2ܯF ?ÇϜ9YSjNJ8p ڙ8q"KAAh&% R wwwoӦ͌3U5~xѣGzz˗ן8qb``+W>yŐH$7_`llg􅅅>>>+Wl2dȐN:;{ʔ)fҥ<0a966v׮]Âjk~mLL̒%K/_޼ys4nmm¯:r;AA|q4^f͙3gZYY TbkkˊӦM6lHH3g~WƓH&5jDPtH5 AzP1ISdd-[BCCɱpByGG/uRACHx:u nprrrؔ5'n@zO^R8rL&۽{7kpzz:8ܗl{2e7nx /7c0ajru6*իK:^ (>䥲% AAܺuk}}[nݿdihhXrefKN:egg =lnnޭ[7mmy[(vɓ'Q EӦMkժy9K:AA-$_~ټysxxD"J͛7x"z lԨjZ[[_p!##E(\r իWZj``---}vu{xOF$AnxyyYYY_~Æ sAF?O4iٷoy=:33Su-Z u/_*nj"Z)OCkg|jj!~_CվO`2,77Wi*_!$$ kpt@GEEVav%'AA|<$VV[׉),@w8WWW@a% \Kbqqq(46b+AA|=hp+++V=nbcѢEgΜqppX`7j֬y .̚5 R a~֭[ZR H/.ygϞmӦرc Œ%K>|XN5k}.^#''֭[&''_v .W^$AWKY;v쨧wϟ?ذap۷o Q:PkLO?#@e$`mmm65Dj8Tww|,Å ΐ  %R ͅaMŊq㡋ʕ6MguÇ̠'SRR-Zbn`!611;000;;;$$DWW7..=ݼy{bsK.3g }w元~$ EC/^ئMeRRҞ={LҪU+(  l<,Cܹ"R۷oPF -dQ  8$AQ*! ' R I8AAJH TBNAp (ADHFFFZZi wKNEB@'x(RZUeU$+YH-H*Z) PALH~(?aeʔi߾۷oO8꺺јv-//~vtto 9RRS 4pڼg}ǙQֶe˖ZZZ@j[E"\rBo`[ӦM###/_3WPPqA_En.*AyySxEE5.Mlk*Vt 'ŪC̊WVоȴ֫Ȳ*B0?S,qО:uܻwOOOB AAAՓH$))):::+W~ԷbŊjFEEݿȑL™`}0>|MLL-RB_;y(%::f͚...ƱMT"#း;w.Jׯ fffB݅Ba߾};V\…ڵu$ͼy-Zot:aժUժU5k̙3OXA" -bH++vI m^) &$zxyvR#0+lk R j$ شm9eʔI&M> A:uf 2...'' C ?$ї/_2ê/݇gHOO=z4H#yǎ͛7oܸ1q۶m\JvGX}vر#}ZJ0yQF9r )ݻw/߿i $f8 o޼HCcSN}t?z*bC~cҥ8€ JptÝ_4y _k9HְK2Z"Y~V ljGܒW-6q&( s֨G5Ol w477tBڡʑ,##(Bn,4¹lڴfii }6bNʕc5O>`tnݺ_:{,dW^p`5k:P\i:(4wvvFZG h 8ZO?!7n@;aʡ^AAATd~(-ZJH5?c)ʕ+hAGvlٲQFw܁Ն~<.744[W\8lԩ3/hgϞ`ӦM8>}xxxؚ댳F*SF;ʪu666pը08;wwt YfÆ -{nA$}zʕ={v%(ŋSRRR)l.Л+V@ O۷?#S&ԩSPY4Eq^O|}YOO=fffs;wBTСׯ\lٲ9sԫWo.\QP9sfNNZ[zuHHȉ'ڶm"ACRBxсnܸ>{ҷA 0jXXݻMMM,Y$*aϝ;wjժ9" Yûo׮]!ϭ84ir޲e F5ᆏӒJO>]v)Sh'55۷ܹsU#!L,X1̙3& Rg``.pfeea+첛[@@6谡WajվAwvv϶pjp899EFF+WGLV,v῟DT88DPPPaa 8{ Eh000 T@"A^" J/HxHHիW믿?… p]t^Κ5 {ݼyh6&Cmp-fϦŋP-[,*dC_/\!C+ } /^%رc{nٲ%C!҃ B2j(#G7mڄ W\wބ Zn ϞǡQ| "?pS} (!ŝ;wk{8b [Q g} T[|lݺ/Ʈ^/Bt35Rm ~8H ϟ' T񱓍eSz^mADi%MղeK8ofUֿ,8qݻb ݻ秶H$5j]rr͛{Yn܍7&$$4mڴK.+W8p z̄  +SN5sΝ5kVaaٳG=a͛7׬YCLZjU6mӻv< Dcǎ?âE̙₅C.^8##E6'9o (/ayFd2T9==YM]]]cbb /_TRlllNNĉ!nnn:::իW)JjժM$A-<77/EFF2  $AQ*! ' R I8AAJH TBNAp (AD$  J%E^QGgH(J:S 0YA 9HdYQ(/d N\;F >$,=:''O  J/r,#-]K$R]_$!yyc$euvȔ".)__:i ;MzuF;Lb`-5MQ_  bA+tl###w9sW^M4dPVCBSSS-[?)m۶6h kkk}}Y֨QL|=GG1c`evM$egg/]aÆ#FX3ӋKA}C*u)8JBT(9|B"5N E:¬DeJzd@+RHN Dgԕ2AJRV!,H2 7W^!C߾uС7onڴF:::+W6l6 BB«T_7nxG_/OJJZHOAD"H,JH7+pc(S.ߐ'v21ٙ!7ׇ |eT[[Qs"׆Bm#AvVVB[qJ"z_Vn\!)Կ=T*!:X/( zlll5X&&&osssUrssk֬lGچ /8ٳaЂT*@*p٧Oo^"yTW&cE di L.z*d \Y$崵ɕJP8366E& [q. R(˷CREEX! mkB˳lA5KSQxA"-N48Tm۶P3f,^"]zu~O8$?f}Ĩ6իoT_(zr ذnݺvwޅY9=~899s\ ; gղB'"," ݧrJ߷ora pLukwTe_|q \' vZ~m͛ Eqeffv9zj1-- *qŷoBcA~ @A?$AWcc@.#ΎN7 E\/%%@SmIS}}{`j*HɎ}\AQ(j۝}bcoee323!"A ]]@0'fvDH[K+^&;&ldd&g)'ӓe|gH_hd(sX(TOvv`nPR,S(#nƺZZ2٩ ̜MD;Ors;;I$Zkjj##'P$kb#j ss/geJ;*ZZ;SRd2{M[nnn\e  J" [P\̌S} Hd!4la//zڼ mmg}ZPB9u feͲm7^Twq:ҲwlO33qq$ Ռ&zZZG2r(7҅zzz##q$ mb<9ּ˽eʜȈ)(=3^]O[xp TS$qr94D,CDyf]Ϧ277H6%&:zEE@+tuYZNV[, *>"<1yö$파茎 ^Ff|6&(/&)p\^7(t3rHrr ֹ*xAA$rFƱ5yBBL8'gDr %mATZ^[nh7L5[3h=Zp#+^N,kkx)#aNΦkᰗӫ5.$>FTZZ b;H$MLp_gn~_r$S RAKKȠw)' E)cbDhgECqGFBpp-nYc# `ЋRYHNޓ"PiًkY56̼)Xh7)__z:۸(BLa!2/tV˗p>wc RI))SS5~OA?Hg j9[U.yߚ"sݤԟE>4??O.Dr?~? ({RFfffQQQAAA?$dI7Ao$|ԩ2ѣGUVCs9 bq^^D"),,LLLѩ_w}7stc/mll d XF4(AAR/ /\b׮]˖-;wӧ333͛e˖Ν;XVZ5zavv7|cii fv][[;++ !71b?>T P?WXzΝƍ;z]Ξ=kooڵڵk:tť|0߿&M@!-Zؼy3~͚5 G[nA?>N 7Q޲eˌϟ@Ǐ{zz |7LT!5j۷o~*U=zHII톢Å#?hӦʕ+?>T P^n]H+T  y&&<<]M>xm޹sٳg'Oٳ'|vhh [666c  M*ThԨє)SX1CMp3~SNsαH  MdjLAħ wW\ jРAϜ9sƍ4*n߾ŋ;vڛ:u}bbbv4 ~,-[422:qƭ={LOOt 槟~ڴiS7zzz 4iv) mll8#T--ݻwWXqaaa+:j(ޝNСCΝ;C~/^j'Or9:--4q^C7o|_bwyٵkÇs#G,W{2e  B s)." x \_4t2;v1Np+dvv#G򼼼7 3H$'M68qd ,ѣGݺuSSS {Ru&MtΝ;g^BDQ=P#GN_ TдiSt<>>… s -ᅅPkp[ w,ށnP9s 1Cenĸ9- Í lh~ 7ShZss)S@![lup_{-t5qMjՐ(7#BVX!ǝUV3"njzhCCٳg[XX? nyoF*@ep,HzPjU)-'''*juVpP; m۶8Sl|v-j~F^ @kB qi_xzC@—/_4zMXFB`ggAW@qн\ &ؽOkPu4d\nt$  DWCV!*(M~~> Cݱ/vM!'!iǙ&߸q#z4®ܵippYRCZ %2eB5q,*\A|T?! E*`=kǂ#O⃊k֬GpϪc"ѣGסT]8::$ z> Xg42)*p'O8Ǐ#0~w>ck"l|Ҏ_+ ݋  (>H_h俸AQ%cǎP&p)77MxPqOr4d 2c+ )]_{7z$CkhA=(b%lPUWv1A-jy gSfMCL;wA6;}C awR(/3,T~5vG"G #C3p1b4 B5h  nX!.A+W6#pvtfykpRd``0i$ FCЙU-`/D"R [bEbCE?{ 9^)\V$aȺAٱ*PE8,;;e|<~<DoͿ7H#sn)s+Hj:ٳH}'6dY|'Hu)"$9`{'z V3ph|82'e>Hep:'}n ~@ZpOd_h /$;`5srrp[Ôiwׯ_;AAAQ#QƁcA$ a/`yqh0dP+YP`+q"""4'rHYPB 8S"qF~8!(p0jPqtyhhշ#G`L -}|| 9Hn`9 3"3l`y`[`_$CݻwڄEl}\ wibzI;r={'"G0(~~~P&H5RT{cGI 3gԺ<2 &>|8vʕ۷o;v,NfXmմW}G u )n3R . `l<IՠiӦAYq֬Z WDžjiD˖- Nq[j kN'`t/V⃁ON꯿\!}n a_lH8k[ְ j 9㯿W_ 2pC=/Ο?_u+n˗/W]-ANmW5d$EܝIjj@PjsX(>@\#_#Ɔ TLV$Be>>䭹3{85~aCRXdA^&L 'p`}!ϳ``G_n.ꡑA#/7!IBaW"[R=]!B#[‰GOOŅ/fdd/~tttT#;ES D0w\4Eϡ >5$u࢘-u~=, /z p (AD$  J%$AQ*! ' R I8AAJJ@ ,qLMMuuucccIeHTZ5Tq+7"L&-0?ccrʥi|C$''mlii) ِ#eFEE:[XX 6 /fpuu'}S8/2AWN Hݻ{xbr~Ͷr:::l|\Bf٠WjUTY|9xY͂c~~>ͩBr͙Hc ^^^aaaΝcXk| EdBe#[ƎB#55k^߿wwء0r,TD"*>KIIAO<~:L\pLQA[[Yk 1o޼QF }q,6 ;"gm]72o\Qy#R[ŋ(5kxĉ+W;v-[__{[[[ҍ7N:uСˇl޼YMkԨѮ];ܠmڴBܷo"322Μ9sIu֬Y\jոq4ieX"o߾L23gDXXhB*и bhI>}p7hРQFZ AƍܹӬY)+l+ZÎv0ٳaÆISSܽ{wlE!ZlnA{eggG.֯_qU?Ϟ=;vأGdn;vĹRϞ= f_m۶-&&f |2$uzSeiڴ#28sȑR4E8/$^hZ|||pUV'::+hmmw%OOO|QDrVVBuirrpAJp664m۶'N8z(.s8ϜԄAbז-[LwC0Ԍ=n:u@ &@upr[VBlrss;w.4cFl1$ l-ZI8r _":`dd7bH_v D}Rmnݺ*C{<ix Fl~752{"?Ժuk5 G@t#҈k,6wI .5Cqkq>H)VX)w(P\KqwB $)q .oI>Ji?Ҟ4șc3rhČtڶm?䐰fJXB+V [Lit/ˋ`֬Y4< 4gϞ4EA,>g Ǎwŋ7o|׏:91N'RRRR$A!nQ @aÆ1kNuFK 63!!!͚5sMB\rق{͜9Ç\1maH"<0|*T 7 ZW%v@^esN >aմiSP.]xm۶pxzj2-[FHsΝuuXMx"$:j(a 99р9r֭+%%%o{@ PN/1WҼVg oHk"-?Vg %0ML|rJuj~D"uULL5Dla4#<Π4JW,_\mQy tBe΂:fLLQSeFGjz0ot3U_k1qMauQr g4ԿML'ᖒtʔʔʔʔʔʔʔzUVݻw>[T…Ή5>|>|xԩORիWE533˓'._\dܹs\xֶRJ:ߟʕ+;::?>""f͚} p¾}z"1Zjj*ŋsyzzO$%%={6::ZlN^"%%%%%qg✜ek/_ޥK֭[CŋkZ+++۶m[X~ԩ>}s ]j=z\~3f3fÇ?ޛ7ogƍ[llٲ!C_͡y4L3gܳgOdd$1@8g֬Y^Z*%%%%% >ʑ#ɓoǎK.i"k9ׅ Gʟ??ց/[,AB43rhWWWjݻwg˖m˖-k׮5аaO>///z)K,4o1zQxq6ݻGwݻCK& %ӌ3o~+Fpp0U0aBXXmԿSTVtL>Aܱc uvZX1pٳg7h`ܹpvpҁ֭o޼Y}HmjDgϞ-RY6mj׮ /q{Yzur`KDYlͫP=x}ɰhѢi"ёvqPz ׬YSTf͚]~״iӅ r948Ņ*ϴ:..nѢEix9 4 I:yΜ9zH֭[7o޼ )gpCMFBh*MzEX?MΝk۶-4="O++?zN7/^m?{9NQ=c 92~ƍ{{{O>XF<"N/2$,(߾};߿رcoֺufɒe˖-K.ZZdݻw{ 5(#zxx,͢UU 8i4@D ^߿{bi۷'Lfpԩ{Ňd~ʕ={ 'hZcͧL"Tri^=&.%%%' ?|0miEi)Okk'O|hт4}LJ&''mB^80*T`aaq֭Cљݻwuww' )Rަi~9äK7n,%0j۶ rB)_~Ŋٳgɒ%i{~7oNYÎeR7~%ԩBYw=x;tߩ̍px0{leӦM\.]*x *Wǃ h>0;h駟LT+Vpw  'M[>~g7KΝ;رc/<==ڷo_7}.]GS}vy91KDD% L`UP .ȟziΛ7%$$70({@?g1bu`!* h!ijԨqرUVqltt4'HB |3|;yd)S;2k,'|h'$u lі9s^~ΝKWlrDEh ٳg̠~RRRR27!C*Wܿ. 7h߀zM֣Glٲ5 QT*ظT\_z7 Ŀ+hu4h<&0=Kg<~Jet*)2eq =c왊PaÆ(7n4ݻk׮-[]ҥK)Q>}ĻxիWwttdKHH=&F5J^f1c`/_N *5 ?~؉'9>SP8999SBCiz6|yԫMJeGN^OnfBt| -eZ"\JJWF8iݺz!(R &`5k .s5'%ڵæ/XԈ!(6 0|Pg履~y%7f;qhꦎpQ>sC?́;ŋV0RޫWCYdiZpt]Qz6zh` 9 q";Ҳeˀ:EoߞA|w'>17 j:… Xs:@.S = >aaW?xCX 6 E1hcʕTbСt#aa !۷bŊsMs7oޤJ!'qt` vACEȜZLO#1>>i+%%%+ɓ׮]+,YdҥUΕ*UJ|tڵR`As]HPJfyn^^H!V`ήD;wWkt.s훜+J1bp )d )h@#.|ƍ7rw~aѢETElə3g(r˕+G@@c9B992L8ԹF/KIII}h_rr`L? 7|Rp޹s'؞6mluƄq@\!7}9O˖-_y;]CSM6QS17o'[n6Śs8uCȑ#M-[Yf2iT'^PHݻ78?z:Iݺu DR^=}4EFXذ0j(FǸ߿ 4ɓ_K hŊUd_cݐI~0%K)Abp&ܹslJCl[XU?ݻq*=p8D :WvRRRR27dccS`A+|b(]\(FP9Q^9___aUKWjՋ/rrL'4=d\, 4_kjuuGTTS bP<IYڵk˔)iDzy:d.]Nk`izI@`eeE D۩S/_R3gKDfWg*T8{%Jw^©_~&@J,;:5*:>PP s :YvyC.]ICJ# <?h#ǁE`ݥB3f_N 5Z|&8bM|bP\ifu֭d{~Aayzc<== ;v;n8XJ*EL^&©S.\ (ȤVo߾n1\4JOi*cq Ӈ,~Ҽo;5*q?!p9s&l2[[ۮ]CƏ;F"!6l 5w3f͚KI"J#ܙ5k5A>*IݛZS3|*GU3VJJJQG8dU0+*R4i0*." z9ӧGkzcE w0>MsoΐqaX ={_ Pd"L pt!iEtu4oz4gpB9/ϟWW9 54a"^1ܢ՘8RRRR2=z1C7,$>*U|w((60-?_5G[q+++O.;7/w@p,rK76~%~Zb?_bŊ*UjݺuimРA9~Ҍekk;mڴŋc1===?S3gNXXQ,YL8qEvpHٳK,Y^=11LrttܲeKFDe':eÇg0pR͚5 *k׮AAAeֲ?/;w.IIIIi2;K(_:u 0w߯SN=_5k)^8{Չz Ο}zΜ9BN>c޼yw5 ~S"-hѢe˖pB1ޞ(~ܹ3>=r&W\FڴiSHm߾}Ϟ=*URΓ'$44hW)))TF8l.\1>>> o&+ o޼yժU'OKL;ֶmҥKO( 5 ˹Xs6ДlMQS6%`zV)SF'_84+j9|sss" 1˧~Z~ݻwB!V7p͛73MJ9=vss(or gΜC?9%ǭbg9Rgj.ai#nvh?Pre˖x1PDΝFyxQvmµ8XZbESseŪe׮] ,oݺ{Ν#Ңs8e1~r5jСC&<uf6!"h})))?̍pCMYz-qmj!ܔz^Nnl !!!=* 3_hi}I8E3E7a^"Q4`/i({#ƘB=6 ,P?2j8PO}7oxedniTRG-[@!UV\īTuOzO?;>k֬[BO0K`>| {ÆVX1W\Uիȑ>} Kp+WLo߾R&0@>ZѻwoA̙3۵kw *7AzK5 iM!ĨaERU,Q}EsahJ?dɒÆ nT`ԨQ|͌3ɏ?9^z <ɓbvjHEsvΝ;VMiӦ+VpCCC .>> sN큨rIR~T.X+߿.Çǎcq8@nv@gϞg,K)DEϟ?f@2Q 0t#%>q?{NsrzժU{Ĝl֜SM8z1nذP"Έa?XMMB:Q1P˖-HIII}8' ֭ѣG\U.,/Fm ] DoFbñq`}M///l6Z"Nf|9|dnuڵ+ Kvb21lugϦGݱcǴi޽{#""@N |Ryh:gݳ%jC0u#K.D6#G$7u\tF!:=_rsjݢH]=̙33Uk6uu"uU+>zΝ;3-$>p@RΝ;Gqmڴ1 W&Lb HϫjժE52$=VX CjhG{!"ŋ_|RuIMYłN|?;EjÇMNCY݊IJOL 'zI5OJJJ*S+s#O 6l؀.{^b4J$ sRRRRfpgsvv6ϒ~Tdvr݄;hu-,.y>vvW[VZmC''s6N;a37ci(11!z嶲*`eu266$6j4R_!qNUԿVb{|qqbcYYKLt63s47k4:ݓŹrxn@RҌ,Y5_Eml*pGlIJMaabaAnzӤ$Cxתz{:r%>dL"Ej9:淴lL0QadPPN7n%&>OJ򏏿p@M/^P/SRZZ:"s*Vn]<%$Śupdo8""I={uM܆<{em=([C^uvs!2r⯿# ,_\)RRRRRR^#L5qrU^.ig2<áI#RRNt͒Eݒ]hhAkRvvIoBB^eVCe+M..;^64XB,-|8F!pcbYY䳱m\]z3NyM2H<2kqq_y3HxJJw;RRRRRRU~իٲ qw? ^`m'?^A$)l+ mmo&$RSRR U iiizXZff*ps74.ak[QR阘ZP773qq,9yJʓS11Q))S==م}'԰jK]NyxZZ[XXkP?@ar9.K3'֗Oݯ^KgrL)))))D ?|XIRƴӧyEG/BI Ph憆^rpmeS=-,+n/RL^aMW/++@:@36^'h[ daSb]GJ"%'ǦF7!8Ϟ崲n cdPPV/acS&462S4-F'^'Gᵥ>xFzNw^FCSRx4HOϔ"sjSSw|˗FaaHPFR{0`c"s73''&eeM>b{VANMH[_)))))SwptCZ| OIY,_[ʜЇviԨQnv) ҥKTT@f+gΜÆ 5j;Rrիϝ;*>|ĉ5c*UE3f̒.%%%%7= cǎ}5kV#f"E˗?^~ʕ+۶mۿ,,~c>CϻvŮ]/^ի{ZS:u*V8gΜ7ډ:tpvv9 ^l͑#5}EsȐ!pnԩ#GlbW^t Dcǎ}u:݃ʔ)cp@p۷O4֖k׽DÇ^:_|-[Y&=&Pŋk.ZӧH˗= tB ݺu-vvvK>wyuuuxV.ʕ+ē---=a4oiɟ9s߹sGR4d|X%[V2?~lmdd$ΛQFEf4o UW5J$QvP}yH7o^ZJOccc5 AC֬YXbb)[kԖ`mHJJJJ*3"6mt/ȝ;'O\\\X~qu֭A߱cdž "q`}]x1[mÆ G`mhy͛b +X\ruYE8'r4k~N%v HM)S}U>>> ]vsma Z-ƽUVU={={3F UoooGJJJJ*"ԩ7{y0&=<裖-[IIIbly)))Y-,'&~-JKԼ|K8xh_&6CB5Լ NMQL;c$ss+Z[[:uJmYzJ B QQQZXbǿ:<ݻ'g +Q~zDDDx{{G~t!1k@@Fdɒ,ܺu+!!~p''7oy8ʖ-[Μ9oܸVHjBRSSmmmK.M]vM $g(]`A^O'uݰ0T3BYT5s *Yx1,X@iW7ۙGM?lgՔdyk%6w շӇ ZhyjK(,gtI_5q qkt;E ŋbx5Xߘ1V( ^|iff& {{{6Bsέ]@22eʺuܹ5jԴiӳg߿G^~Ν;m6qͬɓTŅ:S^1 666'OӧOxx9bvR"h  jN;v$Eeh89P^<ϨC26l[ƍf͚M:˖-K  PGY7|rʝ9sF>>_})o֭ Ϙ1W^˗`m2oҤ %Mqҡ=i}P$i۶m۸q#P%K?J³^:8#G+YsO?VZj?rNgްaC&Q5f2ĉp2TF/BoRV^M-ZhժUF][hQ E-Z@@q;w4LLi; JӾJ+P%JIII{m]]?vrZ1V{#Ą)f9+i͌SYJ|*s4u&Ť&kONLkk._ 'pFrbF@^ByB (P>|vZ{n-[|@ECn(G^5=yyyb #L.\ÃhfɒOs^ n4w>r 8Zq4oc9H&&СK+Wa͸Őt8pZU:t .z4D0ӈ08c zz}Hc &Ng@XYY&,,8q L{ܸqi߾= (Pw܁X@Xs6DXZCѡ:`Oɒ%qbZ3G=~8::… ۷wY 'O "4z*cYHf DŔ@w̙MV-P µ3zB"1 A'OD>>>(Q,XXbcn߾-&xś!}N F4*Go?}4,,.iJ7-38WWWYfA]:upZɓ'Y1cgt6tTi۶mVf\)e[6+%%%eaaE{M;kg`nt>..2%R IIIVxrSzfD͹)MSfNkumվ!x?Q<{ {S"ufӨ|=ztǎJHHqj@رcIpa9i{-SL)))d\Ӽ8H_ kuAMԿ:9@*@;j( ===jȐ!jZJTٳۼy(cTciuqI[80AXʼnEܺu+05jԠ11oԮ].U (w͛7TɳI&=brRjBg6"*FK)ÇѥMXPC(P P#GЍ`9UgΜ(DLC)˔)OJJJJ'V2Rꔿz~x|xotI wCoB7wIaMߥOΥ+"umE )R_"zjz-/*իWV1l2u {Q;EW^300QdX4Q*3\Ӎe<ϊԽP0=pݴizZf͚zRB}I]޽{38\VϨDWtڷoіL_xFstAuswӷ𤤤rqu7~M~4E,l.uI[[u-r[9kee-.%%%%% 2;\eϮIIIIIIe 9:)TL#1Cp)))))Zz>9)D-+ظ~ڃHIIIIII^~c;8\LIENDB`sardana-1.2.0/doc/source/_static/snapshot04.png0000644000234100017500000025256412174204305022750 0ustar cpascualcpascual00000000000000PNG  IHDR n pHYs!!U&IDATx%mW^ob|. n \(C) R &:\c\q7ξ}{_{vuz̏cFf}ձxuC q"$( <$.(pcN^\!%"0 DžZMqIM&!$Iz<;1@@`P$a'D R"}N @ 1L!e12Ņnw )*X]#IBA޽ۏ?n2xrRR}0;s̹seqqQQK/nCbIG8pXERQW#R v;ětRյ9cFbLUgo{9)8g~z r>usٳ^S>8-|mmi}\~=82$0 (WBNBUŕ 3ֵXpabrrJR]hIY)l[Y>W\ p1H53%i8c'uw`>߆Rpq߀dš2Ti%/`IIޫwq:]jhk蒵") mmyILNZjj.I[kԉI! &<*vH*FOSۍmU*Fm;&!=1J˪Zϻ}T*aƔC_?nfF{*IKĈ Rs;Q#IK1Am] W~ ݵ'\`v{٩ͬI.|8֯Vx&+T)3GқZ2uG?zȶ){g+W &S~p,Wn%},\mjVuftz)K{GNbGm}㢾O+߼>”)*emOA7@ zW&ɎqR,J Rԋ3gfS#) dTgZP+$0Z (ؾg޾} ݷQã4*\nYkDf(-oW8=Jnb\v8JoVnjr1rrb闾 U>Ko>#AGqIOu9(y93%f2fZ8wޔ#^0rˆlG[xA5wa*p 7@ .@v\6j8:E+-IxKm'T)8[w]BafayW^8vx>N 'WTvct9s, ۱aCշ>)m=6x݉7y,~CL%p+/15W5ؚdF? 'B53rkߋK1d5<'%)/272o߈$u48(B~ 0>B "JV$FOBgwjU+솄_T(k wė2(=E\]4 \OjQޖODXG{MrxGCx~gs`6t:᭓)D8ʗ rT7/pNQ|=W#9)>yfpB7"1_ ֧\c90QD$ O>lllH$9rdkkkZZZCCI7ENoV?ȣ>4iRmmѣu=zwƍ:tX/(駟:u~;{YpX,Gp8|c=iRǏ6mt}z~Ws;v8 Du{c<=Ɠ['|?Y*=xRQ I0]nE<^QKO|y/±yAk N/۾b=Ń@ Nw\VTnKII۱cɓ'B>R48xjDuZ&8P rY{Rd'ҫWz7xG*++-{lL8СC=_|W$ νw]QQ) k\.Nru=Bȃ> r ֭?@Vt:+++8ݑH6mǎ'O2={6ї_~aX  ϼ6P>삔g^^\ˣ 7n=z4ɱcGRA>|wHp;C&JiqnXvV?9;WUh95lڌiB<:TN!"/B/p_dgx0|ȗs3t(W%0Fذ=Xon [c1,}@\wRx.Ws朜7xCnV\ 9M8b1\vTf1[b1= &TWWۻw԰c WpV2INNpV-YE"rq_Y9tuvr95w ZS\8+j!. ?lU'Dy^@XG6++855-??Ri۷/( fZZ*8۷o,, CӌBC"9rΞbʔH /ȶB/<77# iii?|Ȑlɓuo۶|~p%'[^C L .T޽[.O:5BN]YfA޹םXs38;Ȯ?+hI̯*x>7'pvH oP(?ϏPCA!xam}|$C>0sgQ"QnKwZ#kw4k,_J(̜y+leff'/Jvl lPq15j/b$ ;v ?… m^ɂnL֡g77,t:YY{cccN!22e{wm3}62/^ )n_BNW<]dFo@p=.cw;7fyuEs;0kU مdP_`׼ј_a_y$P@:\jg P~NL#qgވ1c ni%ǿ[)*_iO;>='*H:.0^/wQI#w3JmWjY픦72+ʗFиUD]ji(ph7rC QU$tqzG&߿} 0C)!OxI0GyTеQJ x߽V}&OGwd(+W)eji6SAV}^翮k Wk iɀ3#(~$o8^03{ {B{݈}!J᯳+eх8??'s1q<\cHa7M> эr e6G n0=3m'_p{C7 c+,'`| :0~?+?1nj3wܐ`8@DH/FbGPp̂/r$2=Ppp_0]/x lϋ%"2\.Hts5&D%=+:T7 2@"R"kCr#mִbh47φmju4Ȁ@袢I#zLo8kjQw{5f#5R e`+?;F& ^ nwkkktt4;LlzR>-~͙ARB,U*U= .p o.i)ʮ^ZQJĝGE\KCV#q]C7GGTIƲDNK}9s$QQŴӧɓ' D  VZkZm O Ah&+оH={p4%p`X,EѨ ›hk')7v{K, FͫHNz:|1iFMш\.[ZZbNlj' *b(=`wzrtkhhls={6!!c߾B,[@ f9=밧]1O؉f?j>s 4{޳gOSSHQAAD'O/KNNvmmS eIII||<Ç=zb(bұc*]vK_{;W+J̄l$$$2NGi4p j'l5{6(Ie˃:N$-3fQXR (D"oc0bbbnFo9 f 5MNvwG)Rt!$PdmO͉s]V`iPr8a֏;fڵśb z:xPsSqߺukbb"Ot`N݉\NmF!;z%7ȓK2;pƌ̶m۪ /_>#GD"lll 1Sne ϼ <66d2^,w~8曏>{n!C5Pz η}ݺuwuתU@}.\`v! ,!)P+-55t%''C|0r˭X !&M NI%p[[ͮ\,&Jp8 ې[<8|Iyɨ=.: QP6s.\--dJ\\9Dt8ʠ7 \slv3XTN[A֯I&xb0_24h}9}t0o^bŢE"n\Y3]m9>c|_^k`(vUJJJNNgk֬2?w{{{;܂ٳgoڴ 58޽{w@ D`y$B%CHOKlao|2.h٘|qqqӧOnƍ4T$ @kjj A~z3P)S%b4322A۷Af N~!(J߾}\ZŦFW4X$bڪ.v0r聢fpksskPAp8kJϕTUWWճob.m=X-0k 3 p a:n8p(mRɮo(t2rrdmmJܠO%(R0@p|־&w nߖ-[ Zff&X`U@Ȇ @ z̛m p 58Xp,gДq}I aiii Ԃ)@!2hf_zuuuٳ/_`08;~xH<4!1 'vXYY-P4p (9sfG0rLçHG&sc:$t:T3@׬n!MT(7(ԶvO0!-@ B*F7Dtt4y! xI  /l *5?ITNw6= ͮ`yذacJa!jRTr .qlΚ5ì|-I}wu_|yϽffdlzYPbHu!U$67M82͌oG5**d2eZ‰w歠VOXaO7&Tܢ^) t 8ѓ6x|0w0fc e(0tҊ<+$BVjL[KܼD` +/޼;v 2Jp++j!pՠ--rjţ>yyJ_e@ ĥo5PӐ7H'xW9ȊGj~Hrr2ƸtޱQ 67B=LR.] Ҟ*E;̆f-'෰D}ٱc,pQ=d$+ m%:* dxp9:dhΐ[o5b]κIIY-q- Xp+ܗC T*#vF> <+,(4@\G0Mxvf>=++y@ l9Ņ~@\uƼ+y < ȽR@}6 wNWxgm{J f "fh6Ei4r[E7"$H>{_(&]8@Om2iꐋ*F. &AEдzC.W>-Ծۑ#G~7Vpoʕ<^[d_ #G^~e_'ce2x/R,\p 3R;}q X PNg29 Eb.-{p[̙?pӦM;w|.@  ZΘv.))Q&$(l?~"++k„ ׿N81k֬>p@ rM_}꧟} < /3'O 11q=!'ACt @ؿU*[|zR*NC(|dff֭[oZ'$&߷RX,{߿X, jj n 7u.۵"ĕ@&.(hnnׯԚSORn|t9E|%%Vl^斖1G;=pTTTtt48vW-a(&&V,kZᴴ4vr9sر/5j]D"q߾}!bsϽwe 8BmZD }6ͦ A~NedfZ*)I#77/999??oŊG 7}m 繹2j8iiW6;6 EE232NG3!`@ %**W^淜jղtZMX@3pႩS&_|c?w|fҥ/o}vʔ̪m,Չ㏸6w9NM%yH HJJ.} @ !p\K A-'EQB =-M(9NvUTߋ/.hY_^NWjN9ƟN]$%P az9p%r { JS"?أ?pW_}CFHrɓ'G@ ߏ>/x;vLޑ:׮]-III- H+nJJtJe_7e7uwFՇW?vC;QJo8 BD'5f'$&zHH7in$|%(Z8!(C_q"\nHQDb1}=82NJU* 32LB0rt"onzj?%Jڑ8TGvw\U;1(lT /T+k,Դ]tc̵k.yy1c,C }ǎ_֯?~{O~~~ k?7(ާ ERr_U9~,qa*bk@H#no0mڥ\H=B:v lYjAB*N6Ȝ_B0v}C(c111=?XWO1Ƥ"eR_" ?U֒:+i&-ъ[ErsxITQv:?dΥRɜٳLK/b#>/#g7i&MDle.& :v͛N#KKKRj4o]*ŒSN677ϛ7?ӧhx%asYYBh4L׷4*c%ŗd4%$&PމErR6mmZT]m znLD;e\ft{p1ppEʓ C#8f+~ /Yr߽W* Fƍz/bF 73x`Ar1eыk*jpdh0LOOp O߾}N>]TT4m4^ u:]={1bq"_<g=iҤ wKIIy%!P !5s c 1g"3TL_$&$$جYYbhqz<ivC]#Lb. #0\S8&tĸq㦳gwǼϳ]={|f=y'$ ՉO;7?,9h<5^±aD(g6mޜ+GVUVUeff;/>zd޶mT; LNMx;;f76p?`8q"V CF03F vii)Dt{ZZ[bFv?qGR7MN#T'/ 6TRp9 MF珖 O.~<33A,_a5߭5jdd7[,owAd8ccѺv wġ恛BM74gIII@[[pQi:<$ژ UUE@t\d܏&HZ-mԶ6'sA !$D rl;3eٶjGSn m"4nίfrUOot[oQ#GSO>\CEHy;NZp8<juP n7_LNp`4P9+@0$|w Ab!.&@ ݸc׷qHKHHx0|4YoꫯګEEE$u/[LP<J2wDol+]QV1BQFpU0ӗv G5C@])V|ӈh^.> zOQdhܼjժw7Mqqq F|}zEݘ&tEvyQ`;[u!pQonTB[L4=bB0@\S(^x!&&?o~+'Wn/J ~KkӧZ%KfzKW\k|sq x{&$I+0t:B!Brl/P&}^Bn#ĵB/6l_|y͛|hccb,EOgfRP "!I\΅F\.4j yP2>W lJNJZ,@m&QNT w5Bn-.i{腕XjuMMF @\E@4nj3rȦsϵ BKh4z=p1uT"ƍep v{$1@v-{,),DA'R0l 0IcX0}av ÉS:INSNhm&$>1c\I 9Ԫlxe;bw(1B{hpE|YGer)_Q\Ļ[9Ԑl h9ёJyIx׿M3 ӧO?sRE9r0疞;wm۶j4Q1;33D:|#sgWy9 ò0,J0f3!݋ak0GZ7_(o"E4sF2㭚DZ/#Vidi@Uf!i*R ΕlF3^&b{+xb|h }n߾'xرcwq.\nwux_4a1 F0,0LϘyIVaSlZ.nto͟Q 6_, Z¹C51k^"ĕA$ ~u\q ) FhзwEA-[YUUu\|*_xᄑO8 B@Z[ZΝ;Վ9Rx`Ą쬬H_SȼaNzdy>bL?3ot9]mîww`3Czf.Y&"`DX\! Ǒ7@ n`M=pǗrW"yv=GPԚ!„ooz{ 7P*#FŽ v٫Wm[U*uq \~ԩaÆc\:!!~*jР={L4͛++*g̸K9@aÍC `bf1 zS!c6rHKKFl U*UU$=-"p锯?M,L^^A;? %qq񗶊?^T$&`=0a\Vj/zڵXۥ7 `dBwH~zT?=*(Üsqcso0p@vge"O^oj9\ohsZ$f%g Ux![5hh4f~f&{ Xh`|߾}gφH~ҥK=Z__?d^_WW, CٳgfsLLhjyyy'O5jԪU?v!2`Ǐ;K$kEDr:NR) ֮];|YXKJ&''C&-픔#G*@ 0e5.I"TBAMU3NR}V\rv ܞ;wnџ}?ҳB@ ?[&$&la&p%ByW;s>"7hew/y4vl eyEBVFlL)bb;{J,GGEKH$SNEGG ¬)Y QSNlbc.**:r޽{!jZdeeAVWWo۶ c+-//kacbb{dAH$`4@~Ն\6$k ***!@ n`U(5"$%9I(u<$ؕ p`. LAb׺EzɆAJJ\.c]OLLOjr$$$!F`4R140XӡǞD"S33gLL lϟONNd<## ĉ੃nʪlٰO?Ӌ/63>}$Ip֭[ mf0+P!DgP̳L R! l=o8ElX K$RiBbXtHb6BatRH+J҇!`K.Zp! M>}خ}!oPeLvDb! ,OH;@8ήdrWXSO.?SX,?O+VT 0)>, $]RiFF $t3d87<}ڴ-[ӟ ٳr,7ŗ_8%l;񼯙gnV(@ 5Vǣ@,|N<'~/kaa߼N-_-_kfg&g6" b$ *]}eIf~1f0÷*JȽ6 L#EEE{^ B !I}3hZi@|vitw4q"+V\:=ux[Q̂cPB|2(R*իW/r ]J@7_~ vK/C~ Κ5k߾}oW!o>裏q?~7p.\Xh]Fu.|yZ@ n0B;1빅BwU1;wZv)S/I :ti,SHD K<׷OгA˟~7H|BF/7n:t1b_տw %%%8y$Tgθf8x@n^^EEs[}?~iSWXQ_W_ +&LW@ 5y %:$ϘͦDF^ *3+{ KBF;r觟}moR$ݑ=oB_Z:^__{գG5jڴi/"h䀁~E]re\\}_;gO:rN<1p@F۷WRF}{;d?vugff3|Y9$X,Vkz$9ss=7ߌ p|/xb}:M0x2( C.߀::O<&&b8~?;ߏ= \&Z,VJ*7f3qƍϿ4))wU0/gΝ{{]mm^~>f>oꫯY7Ϙq@  ^Tz2|(MԊ+qj@j۷lٻb| w]Xv8hg8,6E,J$ fĈ9rHH˯~'fk͙iFPtyt9.!$p9e˔JeFf&=X|3 g~FF~ݚ5x%QQKǤSߟoM# ;{2x;K?ᅥK UP[ǣѨE+xӽEYYY$Ff۲B1 E?'N&D|2RS,X~0a%sWomc'&&>ClSJJKA6l8_Pp2@ 'xkEq5nKυjrrP!CyHnΝ<>;gΞwĜ(k\,WIݡ|>XVP3\.'wq\ `/ΘvBe`:NPߟ2tI Sryg. 0s RDRXA_y+Vt/yn } hpҥt+4\ `[+s33vr(K;d6@I(S*\&kni+2bbbBqY=u!cڹ@ g E¤de- t1K~gV}7C@bcbyWo2$r76Fyy6.)55U?۪djnn5xy(&:NT&"prnMk-`8vEZFTt0@ XhACq{$hYY9xBw;:h'M}e*p lO?l„ ~:4x`DRXXϟ/8w}~UUv=]c26 1_ ^{ ta7#$?Pd[[+ `I8ETbg3kf:xT1C=[t6s氡C#D{^W>}Сo!u~DZB13bݻw_._'9'<ݾkV ;ab?0Ò01l!D]10+@y;2Pn3m z^OVya71#VT,Ԓdٳ!b* k*:u 1fPygL6}eܹҡCGuwllNK%%%ΝmmNNjDVڭiLT1LazF[0LaJ c߁[a d6iCE-dfZn7隚 Mx c0$@ .vIкZ dZ%A9nOCC4Zkk@"̢ѩxYry#D \Ғ8-ǏIe999 vV e:%L/|Ù`t v a=o3y ?F7Iz@pF@z٘(`Vgu-XPG //ffo3i$V/!zvD"Fc0Vkll,*rJ}IلdYqwA:x`l䈑/}9|oaaSuf;ߕQ$F;@tVJepq]42ׂ $q@+_Z{ӹgǹƻ`ܔqKsz$F,4Ō ='p\*2uVŠ^B Y8 T gGbb7ۿ6С\n7og,8AfHvKJJJxb8t=/-{gZ]J>b Tt*ee CJ%H@ .W77/+d `Ji8A؆W:50DFzϟ~tnp t(*WMp``vo~zxx[ZZDQ'T񔔔BvոwHȑ?_o~˭N8 ~뭷yː!IAk5x_c(QO@Fxwv^i-[ޟ6m/V~A_{GG)yy7߼L^{me˗ŋ߿ĉC8ݜn὿K4A3˲P l,֔DqAehzDAD,cqk諑#/?ן>VSSs̙y;QUUQ^a0nsܯ~5k^ĉ)SןCSN54ԯ_~ȓCAU@J]ē(I^{8JzV4LT.D3fŊv}ݺuyyy`yùk׭عs'999yGA˗Ϙ1c޽{ ۷mxYCx9d[w3M}qg>p@vv}9ܸv5)"rM^T%YATfeNWg%}5%"u d3g|.Xгxׂ sҤIz_}:2L34H~hѢE_̽GU8&gb}=Ñ" =K蚚nw(8q"3@]KEFԦM A'$(|-e9ܟtIk@s }ϟ<6E3g|ފ㓽8G~͈7T+LfKNv\M(K"SI}}Pفc`,sA,o @AMfSVffٸ2<EP(1Z( 5ト!;+`4LA3u_hsAk bX.4^-%%`JܒQԾzIfF`aHLg2UJ53z5 p7 g \4. 4KE0;i;$~uRY뗏qI&]>{UWzU_ ̥$-v}c=X[[{k$T쎈!6 C, Rm6%( xEPsHQ6SQJJK򗻺|ɂ۷Xv[niw'L U ڵn]nDaW=:}-~gaaw~;''`0L0k׮\4 >6$j9*#x5C~SgΜ__*++/lٲiԩ6?|{S̝7/6$孿ueof 7qvoh0ijs2rs~AAP1ϟ/--$DUTeO(ԗMpiXF>c}Ihy1e̙? /~̙= /<>q&۱cG/՝: K*}Tfw߽:W'yz+ ;闾žhBmb4~^z;|P6a„ӧOC)###x؝.իkkOCqJKJW\yAy;yDcHqC=oӦMYYY~Cf"|G?{d)%!$A`ҽa#}P~feeB5_!T;{.E~C!k8exU 2L{[;‚(̮}.]{?׿1|YRZjv_OT((0Cq#EAohZ-?+ot8أk֬Άl]ffƆ%KG>o޼L mPظ۷O:5 roeffvtt8Q5v{~~>Z%Jɓd_- r999jS*++aCH4L~dސ>}t7-^L3zUUUAA<`` n3g=znO4 fss(//ח>{> J_QQQSSɁGfU< ה)S:(v_{m>2`+A$1Vs׮s;`{Cxw}(/?? STgzKJJ6m's=W1~9sl2mڴӵk֬yJW"!!Egh髅f՜:=7h.uzz5>^\\;o/ZOz} yi_?wE4A-#Wx+/߼W_yvZWZ}(ySb,'odzo'( JԼô=]u믿^g}C=3B  ܉:9s)S:.]3 }KQ*u[o,mdqt8OT W^zUwg'CGf{no߱ $Tw;Jx f?v<+;n޽{N v}TT\9 wvvv^^u)/8t?]P/ L<9v\9g"⌰5EMxɓz!E(˂7}?dO?񪪅 A׺|={X ;̟E%F ,3r 4M!~۶w߽yΝ;'v/0mvY3̯ڔz()o⸳gfUΚ9s%%;o{}ܹ Gϥ"WP}ImV+d./ĉ&L8T1#>Ļ}ԩf׿yhm~AHde4XԠ`OaLpiXNVW߾q#eK|E9QұTŋAib,Zl۳a@0v<>Mv} <2YRR2} e;b;QZn nX^^~AQ5E l|IUVqg}1Ak^=}4 #wy P{^˵u)ڰabw9sN8q9fNcݺuV r5mڴS5f;s AڵhUw买0//dvQm{vO:ʿ8QPʠ3i$WW#]b%Ʀ=zTY[n석e-Ϛu9>ᆅCtYPPmbFIzwYYԄ b&Mڊd26F/_EˇP(h6|0=v9 vuuzZ}t#DA NMKDQ4؜l؈UnA&C H*❮Ȓe;$Adoa(ݧq`1W@Aґx,=sԐ@q\YAIS roY뻺q>(G|.V/)$SYEEQ+`_qAd%^l65mm@ (="33ÁK+1Ngzp)d iKN_cXFAhd# H  i7 ( fx# H  i7 ( fx# Hџx˲̲,Ǚ{22kPkE:e<(A*Ii|t:LS0mm4nA&I; 9NdyR""F8n  =XފM)d-C4qtZ!e\SL6S8 &=vVi\ rR~p/'&oIYm}EaWdG) 6 ,imh#mRz9E.G :K(șL\& E ^I]N$Kb;::o322b=PxAm(/ AI1oEkpܹS':tvuwa= yy1#98a9҆I3ȴBtNNT MiJ.Z j$; A7MӪPPCʙ͛78SFMœ P_#<tR4s``].g4榒bnniCqA*y+J*t2$őv[]]]ss>!<>tdA|^sVKt?vd2tbUuʙ~27 %xSTx詷DBR}R EfIu͵;BgvqqqQ2ax0ӓUbhQ  |m1wq聆P f֫G jb6:J FOب+  6W%4R jeZ;Wz[l 2VZbOHA., Ad2} 7 X%FA/( f $hOr$]4F; pџxKdXM&St` jנ"ďdl:As$P(d6[Bln|aـ $o}ʑc38;&ۓ Vݣwzx8XAd 3|ךk#D4%d d!lF˲iǗI̲ YU 7 lI6M$ϲ,6 &1CD8h %! lvP^Y=E۬.dY]jjb8ζV8 |NN,'SS4񸱵Adl3x+i?hߞ9sfqqqcc;nИ?p>xMbŊW^}+gUZu\d5ǓzbwM` `4 oXs'&QD,oIƷHn69#7 Xfp={tnjj~755K_ܰaCmmmssw|Npwgy&vZ߄4GW &=̄I_}{eC# kimi:7'O=Pڏ Ir[,=;w}iӦݻ?nlj=s=tƕs׮`poڼ[liřLy&-\0=zg/E yr["'O^B֩)l9~oLK`\ "ԐL)1GA,_ \)W-KҮ];srrZw=nܸw{<6;3335lOBlokM=>Blj/D;4~ :/Ⱥ ZJNvnl(OףhjfeJb1+~mAk;VyN'2ӧM<^efdZ,̌nξ?_OUqFh9K/++/[bŰ]БE%B:AZq‹ NHeD[ &dV$|>oq&gV jdebx=) P&(7͚[m% 7ZۇD6vۿȗF~ ؋;MVqpӟX>=:hLȯ Y^BVRE^ԝAG~SD@J{M+ 5vBiigy- -MB?'.@{ I0{'GOC;AOB"$TL;GMyLW8 ?ӳNB ^J?IJK wIZ-)I /vLAt- $J>Ij%HaoWrA xGB,VkIqqԆ^k@ v#(}2W_}u֭?OA=uuu`~ ouuj}M r.63,k`ih% /n5Nd8 h*~ů~F΀]Zh-O_S =z*OV%*e3NBf#XPl3Ғ`Mːb J g&ijFIB .ÅCтMBeUՂ.\{j+,b Zthp 4̈́;D$(%,N=q~o~ ,HwaOQc+x"}3رǿ+7xD1d2B++p֍&? ƕT MT4jEPLC}2)I huEU*U:6!NB3#)͍,捄' pdO%NBH$ 51$n4Wsk?(m†'s+Ӕ5$W9%bdž/IBm Jp-3KZ| *tз-]{c=vi>V⍤1Wp)*++0a|t@~YiZ۫,i OoiV<[D#4RT1Ҍާp1jp]tpI#$d,= :, MX';W}P-W$" [qIe+\t|"IDU&|ڈ^IEÛI"z{73<1Z9$s/RS[GJA#ȕO< uDxEw:{lI=:q:C욏md k09l6ãi5 Pذ0,=xASA0Vk2Äu-6&iI( %r)Jj檍LhætSªNJj'zt|Z?$z]VIHZԦpsMBIeh-GEv IpxEh~/D d/C+ܞ$"/\ˉJA޾'DKAh,JłdkffOxYd3g<+W|GF;W7ҋ;w,/+۾mۤIAT>oxkä4 v2]S0&̰qOJZ{r5QR{sծH*k*BPw}ڤJ10z Q'aVs%J U; pj{'1MBRa|fI#rὓýzXGKҝ#i-K=۫.( 4+=Bc7\8\S8 7AQz I"RjZky4 I\Uh ˖ '!ZdBV+InаfM#cx14Ǣ'xbQ`ltS?~72YA }Pnnג%K7ë?<t˹gpa#u۳r>RnQH$k$.? E}9IDNPzM"u=I$ppDۧM'Һ$w3$pM?E/^rt*$0t8֭~- 7Ԕ322ԊA*_S&`wW'M +gHbCAw-VYnHfzFoZBء 2&GE6' (Z PE:yWL][d2iDMb`!=ЀU=knʐ2НU۪C 2zTH~U$}gE\=EllqJptt>d*08… h;wN]>6m).*:rH^nK/TVViӧ;կ|Eoͮ5^Ym+WH5! !_sfB~KB%iZ^MÄ65)'|`4Wz9= 2ؿmLe ]Y  EŰtRt5u u9]t%aRbhٶ}Ǵ_w,9sֱc=SDI:\?^s ڍɔSk L?Ei d"!'C:B}CaN6V@Q؝z%Z6'!`Tb* ;AaO W>Rl6y,Yr5*xB$ZgͶR]AE@lFݯf-L#V^EBlKY!ڹfzHůyH] QaVOT2xāhGL`8ה(w' I7K!Hs.5UzDQU 6 T0g)e*BNm쬏v}4uҒƦY%UUU'OnhZ91C222pʘS-/w]S7J+a:){/$Ӛn5{ [k Yfs`ۼbU[T_ȼz,fcm]o=tA0ee,U7uQVc=<)霙BJpYj+4*]J$w@ 霉E7m>ey5 -p7>oq#K"O5$ːr' ы !D$Q{SA\Eͱ=Pl8d0o|C߀Ku=z,,kWc=G v2@AB>Pno$/i,$dR8xu%"T"! JHZ $A ?d j`QVdX(E j1jgZL^ Ed AtCuRo3-AQq]9F9Ξ:d7%Bo߮ts8K,1LWR>o~t6_VuWV>f qDi_C T~ow%Md+Of^=oʟYYBR&L7t\[ӳ,$buUט_`SحLХsY"o}.p)=SyĿsU7q$HA)KE, ND0$XYr/rKP4 Ȓ&5vIünq,KOO`Q /+7LPp}j64?h//r$mW D=@}%JQjK_SO-Fθa$.4t &@{F9U]!YYٙYQlTSc#(fi*Օ2Iܨ|679eN!S),XZZ)jK?|7Pfi'(we ou>T[^ݥ~=~]!Q]$Viq3 %.^c7Muz DHdYo* nw9zǕ-n?%tQqy=[X;Rs ŞUMFWh1/nsjM+]HZ1rAADxWw›fb?utkaGa#UdH7,&Df1[N8(0. ³ MMMgjdgeєsnNnKk˞={- &{Iqb3p%v޺)mƑ;=C{XwIssR&]~i/tߡK ]^5rP=un}vst|BB8o;$KZM&_!Q ի>z!|_A4G/3'7etVFl*wmYɘ(tNgs97gxin.uTC?ʰLAaa~~~?vEl(̽WH2 c uJɄJ=xkfP^A`LZOBt'lhz`Yhڪ)f);rAdHa(y{ugKvP xĉb$$Que%pMƔp 22m̖}SlaܜY<N}dP-u|" (//!}iy;;I' A$'Hhbo$; 2VIAdt: ȃ  adYfYfmKJVg#A YJK@g2XVl]TT-2c{%|4|ND#e]AD_~Iڒ~+*kO$SZABo;€ls R$ Hj ?9#WT\LJN07>ȿՑPBBC@a"9AE%IBF,2Q! @Q<{l1ow*VׇsfsǦ,1+!mq:v1sZY \=31Vwt!J-E HZ"oZ5 8SaaQ)#2@||=*W+0":sY!|(vwJe X,Ֆl$l6vW>Pk뉠آDkPH׶֛)VA; ^J*.YR}* g>$Qvǎ[hG-^ K;V^^"$o~oۜ d+_X?8|wm'(B ,N&Bn!`ƻ2m.*j,I]𭨰8~Xc?+NA$칳EEELRcGJ@Ƭ)1{{f;w'`ϴiSO3w.PUKcD[ZZ?7n4Ŵ氦od !4k}V dn!mT;@?nwWDg:hMQ:fsT3K!曢0CAB]4+}-Ief--8SO A7Μ1}] ,˫ohZֹ֖soi &S4ܜGHSckˢ ~+4w';B`Txe!Fơ6T:cE vYmB?Jvuw!ͦH7ID#\ }Q:EUŴ__7iҋ/ȰLvVիV7n\ÅF¶Cu/?Yh<ӦMƩS644=Os/lVV&g~Z-wޫL9]Zm3B:KGȳ'ppM)l6Dzl[~0 .@sFSHª]~2mxA xyܸ>$:N; "J6(۷_U[n`0VڵSLo'6xkKZ9TL]˄xg5QTt<}ъGiFu>Z͎a6hy1F{E6'!YouNPDrtWF1o(kTGG{Nv`(Zl(I ʆ>/$JU%unңx#\ $Ra+z= bԞ>'bGGG~~>hhmmuw]Pn31ɓ'srr&֖Ғ] Ç$`ڙ$uK~lod$,CvFL>pW\\v0yyy6 C ?ҥ)v]5M*If1,[TXdL$\pAK"defmvx22Z[RzU14MȌ<6=@qYDKBZګ[$iјܸbh%PBI;"Kʒ$B|[{[wW b!dM%Av[?^AF\>g0X.6d{[hy# 9,|0B!`0qԱ-`kڂA(!!t,644TfuX_ 7 ȕ +PXPxF]fb).,J%Au;u2 oA+@t,8jsh;!՝  H/ *"0P(DiREQA$JtIPaXjK%A1 2AF (~`l]tXpȑ‘`bP0P+ v/ ښtIЂ|K->zx#a8\k-?m0 vIP$EJAQ$EA$5AFA4Q'5 !A%F K; A}QA)>⌣߽ě㸐j%^.IGgL`4 ( e ޴^Ͳ, h@M&!nE]V\!1 9%QF1 }L2X[]v *~۶mbŊ˗/Z; 6Qc PR+!4p2Ƕ|^oYyYuMMccm݆O):K=9æahʜҖHjpRiSVȑE756 `;[7d2vDE2/ފV5{"˫3|90cS}:W*p`qdקK _.iLlŲ}v3v}xɢ /Քj6Jn~AfqB&w_sAe&dnmh4&m>c"HJ0ew~+ΛwG?ㅋ⃊ꃘ:7($I4E{,"\7,蓑㺻:fD>P}"2PDC9 r֝c I z!Y|lY&A:XQ;wn 4i]w=ܭܒOHYK=t$Qc=6yʔ'UUU?/yjwk6l4r*tG1k-QLL\K,rWgWFFƈCB[+JeeWW_y̙3`UTT,Wf曳f 1}zvVVmmm/nۧL۶mU6 ~Wxz^lO? e BPpF tY>O2A1E(5w&M2]w[oݱc'{쩩i[|I׽\KA?dm+Z _f󺺺[om„ ʠ$¾}\+W?~_χboi,Yz9 >7B sA$Hl"eƍ`033׃ϲ=!L h,VkgWWչDQji[Se #wҥ!1/AUD`9UƜi5Fo J /zٵbUp8@_AhviN(myN0ag(„QMveAQFM_3h6aƋ7(7].אޑtƩ0Ů:\aQW EyO\iS@dlG!* {Ў #P Ip(4X,b;zhAAA~~g~GK.Z,qTf$x?7]aө$Yq)8V%z+|b6)L` ,%6[O&?A*-0Ĺw!3S5K̮]ܴiB~?'|FBJ#'rE>p+Os\·rYY=wYɑ#SDeEjO``iwҳYP< \ M34T$$ k߻s춶6P喖6i$W__o6g͚UUU9t݇?>l맇Bcǎ<ٜ9s%ب1LK랇D'O̲ٳg #G٧L`R[[;~xo|C .1 ~?]uƒ%|}zl6{k'DO6z?(g2۷7·;v,}N,Jg'3}P\VvEΨoiZ$(T #o%Z @vlb$v\ᣏ3ؖ,I8v̰`s+O:Gfv PW+j XtOW5H!E؀ coXQd#TY3nhVt7,pȯhA=D匌ݯb夹Q ;Q雑ʍ6TSQȨBܟpUt/4MVcq{7ҥKAhAbA-Z׮[UnbKb9sfkkɓ'oƦ&8$lʄ(`[|yvN}l2YeH*++o04A}NQ) t]~}Z/\`"|EzPwdR'NNNOӦ7 gᇦxC33Ţ"Bi+vdAM C_(F޴#~  5"sy=B(Ʊ~n>yfPtk.ǓF<`U @~ Ο?Ls΁wӧOUTTϪzgRhP\ qDڂ 3u!`DXgYO1#0Ƅd'P"(7]ݻm`_v=<,韞 ~mV-ư8*I@wKSY{5i/G✵ـsB9WR5zaѽ J](DČ~454!$}*wMlj'Y1m+ B+N8^+**СCmt_Dl`֭l`LKK/^q^{_|:C3D9ko ;7 w|Ʌ S |f6e|]M$Ls!{sby4UJM*jX-I`ls}ŸW_ߘ ϻ4?:3ˍ n); qfQa>C=GrçN>x@MM>3Y__?22;r#pxPbc&uz.W PLJ-nGR'Ol, 𠨸8##4wmIJJMIկ?3B911QQQa6)fI ` Fg֭[q? ]v?*.*zLoѿs+/8O46Cbywtt?p:U^qEb1(;8~ӆ۷fthhX@@p:~뭒bDV ڇ}{?0pڵή.Ųѷi `Fw+/7FK̄"J޹sǻѣГZci V{xd<5?j:$$ H<Rr岟VCB˭۷pw&8yyyc&ܹk1s3>[,>twCqz˥k.+V5-d// foh4%BP(Spj$V'wF1K*L3ۃo`nYAr|AGMc1|#N};"?9o3k@/5Ɯ/x"{gט_^) 9' Xf-fF\/;S0Q0NEP3B g.ͤDq?++9] ^=zirzXgXVYOsḳ375HP  P)>s@cD2V :}p1/[)>uwFXyeNZb3<:h@$l.(+wS& @^bX3ǁRvĸJ^đL*h42C#**Rzfcp,d2FZ`+M`;9u&`4Er̍?$itB=et4|b;$vOL^XR^_Q?Wڃ]OLN\,2fx_7|3''gΜ?Vb0|G4{'''oܼ9?)?~pɖB9EޓĄ* Z`0X,fWOlٲ^MMfVVCCCXhhOo}$dRiCc#km۶!PTo޺/J[''N6.׮];7odҠظʫ.k[IIssskkkff*K`cyD"d2>?я'&ObB~]s=v{RrZJĄDT*N5ګWV=hh`# ޻Z^*E||`3l#{vy߼yS*d_xQ(~ZZZX"l6yPPСw}X]]dw8V^7(U!E*zxxx||8:*=|AțQ46LNIp\YYI}YHHRRRpppzz}TTX EJJ"#e~<38hԩԔή.V:{6#=#;+JH}\lmm}l  M@.//GCc|~嗹72|2`x%D د&!aj0ܟ9())~>J6+yl0.}b 6t B@@@ 5qͅB8nE"LH% >:v08-HV1Y>#oxdq=tqV [ݬEBaddFgn|A;y .q~.bvHR~{ u,ᦇᐈ%P[ |,',>ɛq ˌOq;-*XLQwॼ]8)fEv]:gz ,?jrsݮf޿o/ X YeZS,?bbѦ!cDz'Erx<+9NFp 6@l6"0i\""x9g*%`)j~H0S;9sOf嘕2g~ktj: /5d`^ũtx5΋Õ۫P*^ʏ+w^_m@LTH_WkJWzYY.>syjޙv<ݠf֜𚪗iS&N=<:M#=+3dQԜ/LawW7Tڳ~)\M'ȥʫ 'م5] ̥yd\;=T(9=|7~^dY-3.M,W*s|izѪ!o5:bnSNg^ZΉF@1y7{I0 λ`6Wi2TRE]D^nW/'֎ pxM f?=ݞ3{ڋ^EȤƚ9JjP";fN\5";6i,et^S  -?OO/^ܵk%xD5fFT( Ąbs5̜H,_)~K>oRo | zt}<>>vgi9z||m(NSTTj_+H|t(XP&^ַ􊊊WF2H a.^2޷nObcbǏbLL̜j .jzEIS{B>޻vt6YoA t*??cʲ2`'''JelPqttllLr})q?64<|<9y|0ON'*bhxr:eR隰ٹ4AO.Eju}}#9);i---AAA:)))h={Q 8::|Ξ  -~ȑ߿D,޿ᨪegzx775೸ޒdIh4JLIIIvvB5a+@N>V/B-..ZrlT=ЎOxA!!aHף#?ʕ{@,.EޙN̙3/]3:}pU+W5roW?faJQ(j;ꡨ+KQ1y7Hl6YI2k m^; fD*uӣ, aU@&/^ƨlk:٬+}D``w.huhtGF@PH:O?nxhHPFP~nNZat8*tرկ(}:6>!!''~m?P8!okjj)ƅX$x?ݷ~O YH!Kj'0f1] zЙV߸QYYt<\kk+k?;]tY2ٚ+EMQoS_PEP5z~A5JQiK%5gI wݣQs}KKK\lm(N\lȑ#^x 'ܹ.;+48(())P€_eւkP?J9bNLw6 $X̬)j0K(EOEg-Pqz'P(̒P(繙?/W[$T*gi:Aa؝m}-eޥ $pi6u uJV޵)Zÿb 鳎L1,X́59d@2.|F;¤gB  p&r.x`0ʮ? `A4FD`$d^ 099iقu:aaan+/oVzjYYkjj:;;>0;BBBtу[~~~JrtP۷o/NLL@\{aLͿ#ׯ)9D"B8h0K2cdd@I`]52oܒݲRO0*#/nH$ZWY^0u`,/jR@C%Qٳ}}.pnۆĸl.+^Yye|||}.\SO=IitttWUjf֭$0 ""=.##ڵ*%SSR>ظ8$j+%₂B}Ԩ5dnw8vIOOZg ~?XVTʤ{ 3+cӧONh4Z644=JK{{{G^aadn޼i Twl+e}݈~PZ||WLA464@kywbcb"#?쳘ȍ#?u iȤRPsK/srsWuu5Aq޽`v?8p 238[nw6P~k~Bttt@``RRFG;:_D6N8U(Ldd5~~H~ ~m܂@I&MѰ>Ŕu]o?`pݧ]jq<:wK 9XLdpĤ h ޶-,<,:x̣!頠`>S^ "@T*@')%%'degaA2;wtBCC_.DPLqEWxII(h.:) fkTTLNI)*.7'O۷59v$'=+!DT&?#"arr Ŗ _rbڽd|e/CD7 0<eCË޻o dǟ|iТP*#G('D b니˃Z^ vl0Dao/` yQAP>PĄıw'$@i|&JFh}Eh oߺ}VAà"FX,{g <<|9 Qoo_TT#oCi.QQI3\5q;tC]\G_NEh:u c+?VQΎRAAU(*tmnY]?|?h0 @igϞЗhr@:1 4ٌNCHzmin@P#DHHHeB =,o'sOSgKņȠFu5ԫ;`ܖ--c#ͣ ii\jNWc\EEiZiz%R)d"00a!sPٮNÐh7n{ABШհkD4~Pb%B}E+Z!LLLc%TPNu@0[‹l `8]( iu{wuwu߫jjFDǠh$^D||E@$Vfַ^/4~?P~rf3,X|O~wSոk>rcEUQVvz) EE.Z, zݾump(ƼznnObU)1J\)SO ;IkقB. 3, X2@rr2Ccw:>p w6%?0+۷oϳWhW*an*ȂҧĆ"oĀ QA$*:z2GU$=8hHMM8૾ ڷm|~ߤEO2ý_l`\ 5GR oW[?/++Ћ/c*^^ֱ8u`C` ?}Je_o}{_---MMM@?(g?C*??ٍ1~FQ(]23 h9Eݥb:ީ?ܫ3Cn7z^$c9o~t|E,u,RbEyygs z` 2[*?~~]]Mm]rRr=P~ؘ <}k׮>̯kT{W^ye*80JQzwy=w?.Q;밦{͓C)fh~lnv`~"wa1S_^M%{hmiikk}vk[1"r(([.!hE R{1**vfj7ST E>EыP S,ǚޅRES*U]NR::;R1Xb=Y {0ve"MMϠּ\6088?S‚| ۰aߜăb ?R?i  yl4_`|^lLEM.YެO)Bj_M×&z{{uZ-gGGGm6@(鉊3"}H46%b>XZ__f}U͊Ei"Ѵqi].aʤ;w"#"E"zZs]Zo tG`MWH&^Q(V='ʳDbі-qfr" JY1[=$$D㧱f)WDPUxbz ;-T*D̪& جXԷ96j r=#جWXB5#.@(T*]{L._&з,ayhz7Q]y 6+|7}<Ou&Gゐ7f7;ݸXfZ קj3-KDDĜ(ƷM[[{\\P:mj<v:a2RV%k6ksιN}fV\.gpp0ne2Z#`6T*ҹRYv6@Tsxx877*EGGW^8e" Z2$$f!k%-HPl>7 8^|嗉II3Đjk!ɚL(F0ؘ J044/J #X, b^x!55 vuu/ 4QZ"}Gި{ScT&C4DF mŋQ*mmm(n! 7.](KbZ[[AO6k]ti[IIsu5wPȦ}B#vʕ+x,h6[sF$ܜ Ay@Q 60P}}=N$,VKիAAn0^oE돉 :;hwޖ-qW++). ڛ/ԋr>uɓ'ⶌ 8x[Z*FMUܹd<9ښާPHcĻ\.L CfT6v IXG `zԠ"hC;PTQTݮ`)ee`P}h( !)}TzQB F@6`gegZf)Bg ]A(E.~~HUvl6+2U>,EJv8P/l6;uw@P-,4 {NN088233PZ)yy[$A,FR@0ȁ4>ɛR>qѡhFN2D.`Nl88,ave TĴ9[Å333@rJʜGy1@RRϞjioR:pg`䤤$v֟_l]&WG. B6ȿ92B@@9N 3b1/ᎍWe>ɛvR5YZOnmʝiPyKG];z`b '-kwɺON)$ȧIw9+Jn&vJWv};-ٻ`_0`"\5vVD"!M@@@>[ń]YT[`nR% =)njf||L*zhx~"No0 4zpPsC,6';!!xޮjZܹWݫ#55uN2b{msP7nrŗ.]ܶz`Xƨ***Z2(eeX LNL'gv)cm6JeZ\tf:z8cJbpߧGXgdx8>!|SW[tBaCCܞ̬:ݦP(333n\#&&FCGGSRR:;;F#* ===bpfMJBb۷eryllLHH(llllkk¤m~H(ξy8^SSRf 6U@nP,$7{{ TG#*O`b7om݊l6ۭ[2YNn.B\F b``*BQ;۷_8~ΝކHVV#w vGJj*ޙ/,))IKKdVTD7%?ԾV4c$,PudsrTmmfONN º Byy[!d4f2wt fdddcCŠ 4EbcZGM&4 }%H[>B{HJJׯYYYhraaaqqq+isItĠkׯ''Hh08d`*޿Ws/%%ŋm%%kTǁ_'(Sz܀\KQ3IQ`w KCQ#$Y6 @3A=B8ݵ{7Ώ@K#* Q07A-*eOy9lk^PbR!575> cf}ч\FxHZZ:1::??j4%?oٲ`kUU`X*ܺu+W :2<A'Ruڵ "׮_óSרY'_|Lq0o /_޻woEٗ^:85 EB4@?:&b4;w\(3g?rD hA6-.)^S[ jَ;"#"A)4]04YBɀ>!'OB c)'-sJ ֩S|/ 7K\x1**JTرWd7`P)){AQ{ x2xltT۳9?s9@hh0PGT*ͶRVxmT9JP(<E"B~LHK#ۨ*MɋZf(X{"P/x!x$yϚ_),*O?&`1K|ێ߉Rч HO@Vf`T 1[[9o\Kb#dxWD/>ʤ.kXD21S+X_d3Zg[t·fZ!c l8aG9/-:/D`NҌD\h/ӎ`BT)?mfd)FE<\|E"H| |Y)~boR< ֗ߨh/-`\z~Ou͖CLto'o%1 ^GA=/ބa~969zscn317%ѠB》 1.JtނvoiiIq} ۍ-5[naUi 'nC5ǢkӢQj\(b!TQS]])\EHTjUS(=+AumTJ,'onYuuuqq1Ŭ]~EVj8{ÇYZ~ ĒLvh… yaasO@֖-sҲ].S<7/h'+j|Ɂqt:/_:mGʋpܨVk`}ub>|@0h [slF.,f3]D"_׃]Ι8{WP_/D e2z6bhthhX@@@dddMM HZz:shܷ?냅;fee3ٽ^'..NRJ$ҝ;wrYNNLŅ+.))-,,BELWVB`h X,1Me\uz{{oݺxilSȰb\rnW( smz+ 2s6tԴ46|VUeBx翝8 o=77uh4ϟGڵk7l>y$?Jxn9 Rl5uk~ff&Ύv_|vZ[9v:hm(%EEEsxBiiYCCOH@ 4jUY ΝC풓o޸Ba7U^2JW=x >!ǫG[|EHh@tt4D(-5mll?LT)[:BT‹;%HeR;UxuD T*U{z*ltH(2;P@)ii.A01VpjXXXEERN :Vt荍 :]308XR\>0(40jt{=WySĿV(޽&wtCn2DB޵zہܹ[[SJAi el< j///OVp0ҥ‚qS[[ طoW_~)I!zه=P[S*$BwAֻvz-N'f7<߾}'pxrR21E!/_XPXO`z߶LknAA~'   SS Y"2LP_^^ӧ@Pz@{y#e\,au: xA!lok[F"Hv=**Ձvr 0k~Ejj*"C$уsYDEEt"E6}{O~6l42Y=z ZeiLi'y=TeLeܼ9?>G\ܷޫ4[ڌfnH+Ō7pudSf!}?O7+-[P;9vㅅ|!fҰxG?b|Ghh(A[k+rGz7kW)fփ)pgdl5-``^Aj`kNjT1`1 Xam,wQ h?kKGOS7UI`M8yl`7H@@@Y>y<4y<$|Npt}-: ɤPeBia-]$J{\>P˵wM B+dcCjh!6&6)9yGN2%Bի۷o_#V5>>~N 4/?_ZV*ʸ d_%gaO>@b^V%KJ>Jqgee/'_lw8-Lf͆^}E@K;y'^^郌O1/dY岀nll tW_s:ׯssڂUچ֖g[`"&!o`xxXwtjujdg N]}JWWbݵkɜ\WVJ7a4ܹo~GGng֭%?wnpp07/ORutvbptuUW2ZVS*`gacǬt> :-Gu?q'33* ?p8ݽ+߿DJJJ{{T Qp/ v۶)wZWW7GoVFFT"lljBA?###v e>rhZZڍ7XʇFŖ__``oVbb?{;Ƒ***FG V&44>(ѳ> uѣ~c  [7Q0X(XC+ͻc@x<{`ՆZ 7oLE*&$$:/ϜYB2*!O?$))"c6SŁ[nIpڻ@#[[[vn߾}ڵԔҲO>8;+;=# haQQ&bw1C;6 qFuil,77r|ZZxxx 3g@`r2*p "E5(戶lEQPPxm߱㣏>d0u1CAt\4[(y:A-%taz=z;w$&&].9CLcFO755ccd)2ASQ.kvEX.'$@cHHHszǑ7(!5- #l7s0%R)}΋ۍj (W++?W_:r1?RSą%%&٧NZ"YTS.vag ,  AՌF0Xx瞻 BtUUWԃh8UUP,\N'6A%.n}gϞE1k94ob|Π`f(/99J@G{ZPXHa^CSScYi)9wj2b/.)A޽{u,`?%o 44/]d29:RA- ǘF777orrg2sP9'-3zKt:=Zs=w:XZVWⱋ. s䍶bT(? :GhôBCSSS;;:112QhTP>h6Wֻ Z;^zMMMaa!۷Zx-9T )N H=䄙`Ձ`B41>']vwwu)UJA`%~~ݻ s:차GϫH=99{AK0˗a:vaGDFݽ{vE` `$EEGsIVTMHLT~Ai= F jTF4P Rt@DFGa@<`Z=ud =֤F RY#Q d ҃Qȟ€ǭ6$rpNnnvNxR`VYQtuv(DIOL@@MmV뮝 @ ?߯ d(݆la;rT٢UЅ S_:oٲ7,55wo/d|ᡰp~}=G gEG-4d080񢑃"Qɶmׯ_7 @Eu;w *ɵ<juUA7 ;#3qFNNւQ j_ WQQi.h8qquCo_W[{: !kKA=TCz Bz߹W^yOJpÆ`}ϲdv<l=gL*zdn/g ts{rǻR>4:;i5j4~0Y'-֝$2`Å (>Cv0Ja(L)),p0p `ig<Ƽx7I1k@ES2u<{S5Hj>7 (ͬ)aY2ь=c ßf1 'WP`kֽ+qtyf~j"鹂q_GE͍NQU)9 !kG'K@ɰMMM|=J$UU$RIlL_}'f}RPWWuփ-Kޗ/_~7O<.OSv2^_Ldcj4z-.|Ч1b[l14:W fþ }$$ˋd;N";|'=I>$Ĺ>'ĶlI6)ɤJ$ +3fw7 @ gz詮tW=e9-<~8ws;v1ҳo .@W$'MߏfGJ6z꾾>$$F_&#[T^ȍگ~k΁v{< Dr9; (;nssVv6pHsSSFf&"555۷z |(zP3XqEAVBilQy BD{B3ubkCgNr ٫c9Sl2vX8 FAznTsq4>==uC8'`ա7 A&&&p/m[[kM.tz}~~>'ެMglQGvPbg4`4 L|BwSejjj]Bq¶c}7/\( fgQ- )Vfq8 Lʞ ]^z>3xη#<\5;kdDGGuFcQpŦ&Z[Z,VkVfff* Bw^?َeqqqܐZ&٬033sឞnDnllJep)Px.^x7>㪪+/GDFTTTg{P!{Q bA2W^9}{;stAa!CeݑbhhhiiixwwwݹS? SRM+#NOMp'P )&:,{}k| 455IC]zJ|dq>2kao|˿/s R CaVq9 q#Zn8xWv|AzzB!Z|%#fP:.\>>>^RRjف ׎C&3y&DjZj6TWجVST\#4][kNs88044Ċ1Z5N<~tT*CQ-F l/,%GGS\|ZkW : vm%NPST5GZ'Lrr2$@g&&&fŋM&ӊSVA7 pϿmvמxʗ/_Z-踡~]$62}|oOR664aDFD?;˘QQQ JE ذb~dV߹s'i.Sձ B@&Ja?AnݺWא B} ^&rrr]޹ obEw#"PͅS~F v%RiBbb63 ù!W(btl jvۆvipàyy+XV!˿yoq$hEe%38R 15.^pĉGͰ1c3(*"KpjvZ+O>0F༐O( "%99.X)xU}C . 7!!1##3n*..>{N evvxd$\ J!1595R!qjj `twccϞ=ΝE= d0$@ NzHL-+2yL ݩ+((hcaEEGcf#G`~IĢ`\$|B)aEX -BRy- &K m%k㖷ОeePЕ'iRDȻRuvv"[45.Gvv*{g TLX j1> w:6 ͅ^E &^1|G2ͅ΀qӯgAbPLX ɆTVV#&&}1: T {9C0cU%-zk.{[Tƽ(_l7. Ls]SB/օncÇIR,1(\ń9frҌ3vwU= pRQqs; l9 Ӟwʩ[Ie/p2%jӹ0;k++xJ$zmH.G'7{)-EjZڊgV &`N*-HL4.x-RB. ‡MܢG* }YY(b#Z Ejuڭ6@ ʡRK,t3صqۂ($ann.xRs=b'm@ fs;q>{ԟ@/>KIv)6TyT'ɒaluVk[[kUUÓ577WVV?1<O__X6zLLL?Ŏgc q;łl!+{v?<a[1:22GGCE"Qbb";GY* l8!1ѽ l7OMMy!@v:!--mhhhaa)klxK111ȭ/ A~lVF0 blppjgR-333*\H\֡A6ݖ‚T ͅ) q \;gw\ZP"06.jq5)̒-r(V*{LxEDF|2-8L(ɄjT\\"DfǏG/ >;wNј&uwDDC0~0nCh\$'B *999"x(Lnn.ԋu'66nbA'͓2h4thiiZ,yy?x Jѯl*Դ4TçBa4@sv띙_p:~m:HYX ΂"ȰL&W*W"`87L8ذkn7Pׯeg紷GđQhs6R0#*r?\pg6h9drNX;++NgWWOwwͮ]SbƱ0gP٬wnWVv!,*->,ܽfH<ȟ=/D "ބ(17isv6%^?&&{ED[;B 0b&{ttb L"τäBOnlkND2#ytD+Eգ$(0T$dO0 86M,S<S [RZzY S̄3ӝǍF%%%W\.-!EbP =]VVVh 4R̍1}KfaT)‰̔q-%G+؀Sc(Zl Y]t"I tWARR#JL& \ b}Mh&`pNd(U(03y8oyut0͛! "ބQTTD}pBvNM\c P 3i+9@}@pGCG0tjjZٻo?TʤhGGG#tc9(J>==u Z\\ y "KJJծ]+(?:V a=qF'LGJeؑG,V+t 1pGh:[A(w{v]ºƱ1a>ʰVڬ;pqFő-\`nMpKCkQ TW >j\_Tgr/12uS;-.<X0 bdT/.`S A%$-h ;W蠂,x 4 vNb$xWHvp-p،2 ˌ :+)VPdC;p]_,L0\d/V"TNścE"Qp;B\y@x!!Ow !xv{.@ l/6KE ?ߐBH$=?O)H.+jO X@ y(Ǻ /xAr8Y%xQkXcc3Wr#7+, ,Ȫ$𬳉}F@O؎+]B%O,hQ_aY XF g0`ǃrs' bbdQ""Wѡwkkjz鱱vJ$B;@ $koxu_׸~;TW E("Ǐ(G?r:Gİlooկ~%|g)))oDT, ig:'L]aTGqnW($bI~~nr^*}ډ'M 0ko##6?Wb555(#E޽/?Yy?}h S+wBX):ļZaw<166j;eEedԺIxKNI)QN%%q0&**nd26WTӣ]]]mfVcaWHˬd%{C#rUBr@X7koH_8ϣxַkNOR9[N5UReSu?П;/P|ܺu'?Wz8ܯگk7s?_ x"˜3iSĬz.^Xptm6Prnzzzn^￟d0@I4\jjkoH%lttà̜ihhի_}^ᨘqAo4+++QT@ PkoUN377oH:?H fӟ=<7wݐWnȰ|+馦I*ULX\Q #jHNI**.(ݱ#2^٥KwQW_WPPdvf&:&j혛hPbh6N٬ҁ\{P888 ]N'N? :I =Ul>-#RKw7S=ʓb3?篐6B 8 :ԠO# tS٬5JlPXTT* “6ML677d򡡡ٙyǼ煳2; O=""B,X,$˃)u}Nш//?M$.ߪy&\mA|~n{hxP(쌋Un[(jc~>42.KRi CUUU*p<<_~ۙ!͒PSLpY,]ƣ WOi6JM&y³f/|.9hU?N&d,7@ <lx~e3r~!K "Cě?/((ufqq 2t:g)):v_|С::YYYW\9~87q||\H%G7irƍzh0LOOݞٙBq Lj?ܼ]~޽'8g WzO>X*yLoGPNuxxT*D"1D"\X8p {@x!Mx$''CM2||x!т w .\8_RRRXXL224@8<>?.66*:[TWܸQ عs'tq~qq8ăyyy;w1b߿dYUxSS/`RRrZZ P}\i/,*Жޱc$,]vݾ}{ffķbUUW'CRYY*dnDkjj~|>JNě@xn!MxR$778t86s݁"|Z,]#qqTTTpNPUU;ggg!R :tLl,ggff]pA,UTV5#Ia4mpSSgh3dReddx###vV %8BCjbI4$11(ŋ` >_*>txhhH"our “7i'mn<<33sy&pǗڵv>^R[!C|Iaa!`B144Է "77gHMMՇ s47J咇:F{ɴw>J%^"Դv PZ6 uF>8A]a4._^>yܹseeew9u fK666&JQTgطo?rSy<^Dq\+ʯ:嘛a w.,LMNb'unE^8+l;b$yffCMTF{ġ:йUFhq#rFmFA)B5j5|D ǎ_DFDdgg[M>- =uzxwtx|K&J]%#(?/RGUII Msss( \( [Ѓx,t.###"""\zچJ2xj B-z@X?ko߇^?iPt .xjy٩iA#k?o{{#G9<?яӃή?ATVzὰ$p'{s1бT^ &+ z`[ņUAss\Rl ;w\_P"=\pp+*8vտ°^> 1;ێ :9%hZEWVxenn&ERr2^964`{F- &C :ko85 \zmjjnW'&$ܩ߼n_õgYӧ f7EVf_pU^} PS >m+O};9)x&FL#iVḤtf7w}.HNg_NF}}=6v322n ɡ2;+J333m6ȈJJOOQ8$qqHDTTT]htt,66p"raH䘟xFXl(gΜYUsmVk@0p-gltok)*11MMMclll||te1FᐉDBth JԴ4OT\)r/˽NCn޼q1\IOO4R ]|/ = u/,Qe2v2#R C}vرcf&̝۷[V'' ClCqj v;.(jҗC4<~ޞ]vT ؈i0X%$&Tk4n=My&%%aN:c/7@(x?J>>Rõ7j7N6w3v{Ta8jxxxvvAyAF(-No/^VA(w^^B&4~f9KNhDD@jj*B|m$[GTsձsjjl4 8 ~!HpALllݝ؀)0<45[<;dxas-8{dZeR)Gc5LQLXq(!@QcbAKO ozzg45}yHbc0lT KsNvÇVyPr77r ={v\nde0$lqvcK|xGU(0pF d2kN儵"UVVb?J yB=Ovv6r0*qA!%;hhpʶB?a3\~t%(&Ls:叅m 6p!V  E-RrpzM^1$jŅ hO0JCl]qU2 ^LUֲ+D/#``$`@#( v} zH! ^0W a+"6Xq̦>lzO U;o@ &l:i -oVbgg/grD"Fx<텅V9hǷڟOMM9سl>~nܹs/:pUϿs6FY:m} j2E"!&ٳD*TW|#"mAARU5W\~Sz[Z(hdJ_ŋAMMݻwKLlVqF)جnDԨ߳gO\L&}H4+*+)d圱68;k?)??mpۃCC0<*<z2_|i}82, M=6vbˣqTjZy+O <>D O-áC١Ç]nב`e,E{B+)))yJ"\IgݷJl600?ŁPX8<<HKO0CkcccFF6̼} K/чjtL/NGyY=>FPXVCB8?O{KhZGk677_|/JX*QϜ9y$_\)_p:>z4 'NA :E&ý]ěm^mܰf nkoGS=ߏ&irҌvW rOPH$f$&>nt9І(|krts5*Ql`Vn5 y=2,;'wiXfS_(ڵ۳33%%PסQQ N|bo9/(((X,kWvvu Q9hd9>nĹB488emokKII QL|7jE"1idd>TӾ˗.]T*Fc<<9 N^ўN 2޽2/**Bn޼ bcbf-ogΡ 2--ŋĉl석tѷv.y/\*fC@(Jyy |y[ڎ@؎k.ݻ{E _~}{Ġ>kj>G}TVV{};?]ٳЏ ǰz0GXastCv7 "QR<3Bj?R&[L^~>\gl#"233BHSSSb{8 'lv[DкP,jú$2,j:Z,+5Hw82%%h4'%''(3 W )U(cRGF_Y&C {zaJe\\\WWq3=ca@SRSQ5jo߂322 Krc'Aqҁ_4 C]8¢"45(v&zyrrooOG{Mi7Yx\nG͓!JP|7tK6>RϟGo>cccg +ȉFemnļ@`EAڲ;wǍ&LI3Z":: Ӑr…fs(HBw33#n(.]E;BaH,qܽ#i.B=99933[Lbf744jEȄ v033S''KJJ35p- ~>bJsSfB64ꂳёURZhq,SO~5G"[5=[=.ʆj},[u9""koRyqdIZe3X, qZZ $$$:u ̷-W^y`(**/ڊ:7,\=39]NH Wda!yo@ Abqjjhd5J'T#38֪j&rckY|˰GT.{u' QarJ˗"3ӞPToUnƜ?"NoQ5e65,x!,eRkx^16&fcN -G¶0o6{{z9v\*,,lpp`xiW3س9y  ظ2ɛ@ c{yexza}NJ%1 Kg}`vyo->̳YJQ>﹋YT>RaYǿMʜ@ r@ mo@ D @f&aAě@ mo@ D @f&aAě@ mRޞv\D%b}1[ jŢ$vaxD">ViD"~5I ]}Mzy@ 8d@  "@ l3Vo/y+<_ho.5f˛}M l?XH3ExȨhX.GXXle@{9n'B! 7z?O*NMN,D>}L}8 ٖH6r8?{=H,x<H$x\Q @ !7$6f999;t!-ߐr?c}~=yPO³BT󥤦_+>!+WXp v{7n#G>*<;,F . ʊ?$&:geeM_OO_ **$'V~@ <V. ljl??9MK.LtuxRϟ? 9_-|'55,]$bq>ԩS~)X$d}}}### bٵ{ `E;/K* `T#zg.B.t^gnvJhCaJeEyk~'CnÁKw~VTT\3J R_O~cǎ^:|ƍZ^ZZwƆ Xrz+\-ʪBK/`3]r%<\o߾hsssFclldڽ{7yA +>6Uwoe~ؓ~%{뭷$WeyWVV2"&_NNNv\z{d)))+7iv@xov6Y v/8UyWWh4$ EȹW_]~, r]06@x,obccV(Y'mqqqk/3숋 μ\p.3.>`1$دB&yѱ0%M V遊o왔aaQQQB!j}}>c A :6s@ <3$hDD^3o|>&F9~\@Xӧ~0ڧ“ov\IZ 0A0ER~g;|ᐈd\3  rXG1T2ROXru/[r6Fo OB}7} 0-xZ#pf o"s ^I={``Owy+.b!qw`Tliig'l~0s{֒Բnh)7< =ue-Wucs }Yu-"/u\Jx5OJOk@J-6L&x{<}kĶ>h;W s ط;%-P˓' >\W`3^5.h8#RK/,։kG4Ypx+yY  BnQ^F,\A +T<8nqq~߹JB(<[)Koe}⭾[փQuBG-soЯ6x/XS[ BhXZڞnr "p|ks#狄Xt=@( m_h!1<ᡰ+C>3 q>$KBOwK҇W&jT"lRRRdrycCǨ :p$%%A3zzzr‚bF/Bz9? ڬQQ(NÉ D>.mi)vd2=ʁHՅj $>F=qF333+"ܞ!Ʈ.SSF2,!!>F3:D|ڇ1Ͱ*@t:-nr0aY&e7@BKKK?ӌ \}}'Μ9| zj~^9rŋ'^|O9ֶ/|$=2oh'-=;ηU 7<2p8T\|Ξ}wR3337y?ڵkW޺uooFFFaATQQQCC@.WLNMuvIq14 j|?0qaA=?""h4f~G{v`yٙǓ(< wKK+LNNpbEyE||Aikn7$v׎nܸTVT$Dӧ9|VA9a"ҖDd$--C򒻳׿{]]+W>/..÷.] ̙_{ L|\X,ms{ܨ&ӡa\X$r@XPFPNNNMu5GWYv #:GH;t[VMijp|>t 㙅I:;~2i„[8#tΝ|\!G/)86=n4656%bPo>v7C~~>4>#=sԴ訨ׯWWWg&'6᷿-LKK=}~Wwlܼ<z޽{W)yzzzIIqDDdmm-raF446efcs cdd#CG5EiQg ƌ0XկXjB` b89%^3GG\ΊL&Zm0=bN%';kdx& qS}C}uN ;vho 7gPk~`&&{c Uon8v,h흛YqxWFWwwo_paQ!h2W_xbtdTZ,oa''.WkkkgWΟ5iE('&&O~+HL0;_|Eoo_WWלc.-5Y`lC" aBl(7׾vh[ol^x.IKr_=:}kb\%%%P_z bNŰyP$TLLU;еW!&CŰpY #GfSI uݸGx X ̓pArncp455)²23au ƒ̽kԩS0FFFvڅ9r+TY䙙7**+B}& zd2k&ܬPJyl8l a$ BփrxHfu.//W*8r,--IMMEhmmW/kcc55ɠHϛ]ՠtNl`wy 3Hh^詹p Fvv6όBGOVV-fSkLfX<׊p)уgs'(=7qM6 XHc.. 5\݋w+l `+ x]vB؍ .̤GJ͸%h eS*tUy?>nQ–'i>p~GIWōMF|b $k@ )Ȁ5@ x M vB$&a{>ggo@ PnsqD @]xf׵+&aK(ҥK;wvN!M օS7nTT߾v7@ [i97oYUuuL&l]b7"a!?;x`۷{>o3^}4@ l5R G{}}cwx}v @ <u exIENDB`sardana-1.2.0/doc/source/_static/snapshot05.png0000644000234100017500000036413512174204305022747 0ustar cpascualcpascual00000000000000PNG  IHDRD pHYs!!/^IDATx|TBHB {EDA޽6.6_^X@TA zfw+5eIBy>sΜy3g_Yj)(((((((T^o0F㞘䨘:u}]]\tmf6Zh=Z4k6p-Z3tĉMkמ8rb17isVʅIHHXvCfshhh~ڶm{1Rp^dAgBy770LNNN5 B9su.)((UlC_"wwwR 87ڷ~-7}w>P5+Ȉ?IS'Klû~-0NzNz{u֗ 䠠@HRPPO0wNMMʴlrՓ&MЎQIųc__nݺLj׸qcrުXy׮]k֬:thN˱c~ᇈÇW&%%q?ȑ#͚5C"ӧ'۵kӧ iӦ[6.aڤIR?'O4hP5WPGO57KCT$k,]tjwDyHy{yJk6|]SSBϰ:uK7cp/o㢯ByVkXgm 4@tkxN*MJ$7N)gZƒM; zcqFۦ)%-6z?O˯sYn-~:'/.5jC?~\{k𐡿>k!_|裏~Gp?~ ?# :{ҤIqqq[l{~>CBB`8p&v!C QhbĈ1{A޹sʕ+ Iݻj* 6c \B- 8^ԉqs]v%v tMͣ5gu `WsOZl駟N:!Ȉ&_PP?111+VğiӦٳgwA'9믿"L8?ȑ#hZǎcǎaÆ瑑X;v,n`p„ ĥ=?CxE!)x?T=?힓6hP_o0'9e0 C|F.?-)HR1- k88nސSᖘ jNAwZ4;뮻dHlW)Pk֬Yo\sСDM!F#ˇ~m ooMEpo~W!B(sԩB2… `{1:fęe˖{߾}<oW^y ?}t֭7oNu988xɒ%צMoedd-o)SM*ԩCI WD^o"\\\P'=z "{i6qDJ^\$ 2%!!K/_>55KxK0$qHar!/NhV^ra4-pyll,9rdرH r͛׭[5[nKMe?0 N_N.I y%5oO8AbvyٰaoXT|~lٲ}-\pܸq{[{Hgm]|ӝ,kamهiЬM?G L'=֬>ɘeh<]۞JF(\q֯_OZ ݛc(!KO?ܮ?K:u'B| A8s=Wq֭[yRwI|yD͑<<2;aqI5\ tN7lސEI ?Uo4 Ia:kUgp* l0R[7\+~~~kONNgu6޵W:[Z;B{!_-$Xb_T2,/M`h `A(mb7K+w^{aQ.v f4-.{7H3D_i^K;vjxG,hGL.U4NdҝY>DZPDb@F@FE !2,hAAULp0"d((\T5]lEvFS_LQ(,,NBMSI_jg0$^^jOH9RpEB&J*%P{WqHHH۷o_PPbŊx;o?!gnl֬YΝkP\\ܼyvաC-Zyտ7))ߏ #vرc7n2eJu ?ζQ˖-۴iS񒂂?啄9s5p# ٳgʕm۶>|^\]][nM=z>|w)))K,Ǐ駟Fڸ֭[7dvPmx'{d"%0 VT"l p#L0gѢEG4iRƍ#G|>חXU6IuȬǏ/]QFcƌKc=8P^=;رc3g&5k֏?Xvm||HKK{G>S$irm&cCOlЪן B| &`kg+V 8pϞ=͛ԩ8m[,m!:#$d@WWW9$˖-+iӦg`ɒ%::! )lP)((((Q#F͕Mxh2dŋEIt=&&&995йs+W9~ꩧiVVUsXtiZZZ5Wϟ߫W/???GruΝ|u r M=zt7p5%۷oOoSNtCUBxx>ܬY ޜ͇^x kuִiӈESLh{NNNg}0iҤurܸqh&Mτ #FcH `&dpww-[;v_~8#]RPPPPP*Q r, բ`vUvs6AH ؛r95XfoȱcvVS!9mIP4uQPPPPP*V:WmRp)BBTZZz}PPPPPPP k6͓HMM(((((((\aSIh'((((((((T*jBmPj ՄR R zpPJBAAAAAAPc $j$j5RAAAAAA\Bm$fDFF 8p>>>ݺuf֭yyyC IJJڻwoxh9ۮ]뻂•$N̞=;33sZn-Jb޼yÇoذy7>uYf%?N4iڴiO~w(E]cԩz2 EEEǎ{y䑎;^+((\\L 'p=QPPtaݻw3l6@ZtqLL P޽{[,Nr^0]ڍ7x; Rn_{/~z.h իﯔUѣGwqѢE_>駟^pa֭OH 6u]|ȑ#wIx9sdeeua̙ #˖-ܹ/]V@n]оԎ\tU.Η}W{L&,̢>g- 2޷ݠIѴP;{Ν;ׯ_?jԨ-ZY v2yٲ.NNƿh[ܴi^c It:u( 위6m"499E]48/+?f;&%%}Wڵk gaJO ޳g=zƳ|7]??ӧOwڵe˖2.xj7FFF7.,,C^kN@Æ i,,-[Lq^^޿/B裏^]4LIdeeQVby{_‚#>xd@A ݽFA:KݸNDx5l>$wbҽ3[SS:Y`#6\7=t|wԭ[^iͱ11;Sh3M͝JZJMŧv6Kxnۓ)Xt/o|Ѱ0ݳOn۷ 򷵊eYoI5~)y-˖|Yy@~'R>#Gsƌ' G|r4bE3sN:u S7tMBhѢ-{mڴiҥifС/rAAe&22266MlٲP zv}HRwwӧ8IWsǎ($?pxxd͔5 )ׯEaaڵ"dQ؏>ƍ=;!`Νk$lbm*uН5(.~8OM/61񴓓_Vhkʫx f Rٔ,:4I0hbݻ7699vaÆ'N$< 4I;0hРI&]t+Tp~C"L6m۶)g4!A(8$$[o ;w{]w^TŐ!C>î]ҟOlg}ɻロBG+5XOBGfD֩{͏CzϘPI&YVA!͚5Cu&s)z-kݟd)u[ׯߐp"##}֫W+{Io~wzik+f5Jf R%rDZ СCZ֭[DEEю޽X#JRi?FGGk?[n3yxuxow|=ꖶiãAIz]9?}͍ۻ37f i=;OŐUCnK Gzӈ[|駟㓹sJL^ 8u,7Z djrIɓ'ō?\= _mW7Fp84h@S{Th?inj8pкuӭE*mǏ/h4#;qDvĉys=M6% Ν; O%%%˗/WJAƍ!|0<}heCi3;;88Ǵ>_}Uzz:v͚5ro o6-]w=r:uʪGyd"ketz "Q3O0Xqx0X^l+܏jD >3Z*7ds%siqM/^($Ƞ71Rd-#xS_*BHs܆S'OѸk$`tt [_R/Q۲eKbYl:XJrڙڴi_~ -ZȱÎAӜ:u*G[b}ĕ+W|}:thEy 7p{РA{F~ʀ5,#dTXʒ<(2eFE FԩShhhūp)Q99>ufKX́}ySCEȾ;_c3 JюK/DyXzŋv `Gy0H?W1hx͛Ӊ|ΝKܘ"9i/EIl{={ݻaÆ߻5hЀ_~ӧO߿Y EW@0!!lj~i$hDuցLIȆt? :vs6$&&;$'; ڱp0뫯RtPj-ֻ)(H9QǷ˘̥N.!W%rRaffSIIu%V"b6KM9y&UƎIPTТEȸ=zЄ!]t.___1m<Ԉ)TvOO7٤wzW~Ne) :vn:ש|ݠ]D*swxxSo͜+V8qԩSHi9.]f*#=Nmm/AA6jv uzo:fcUH!DF\.^{S"Pf74`7AHdggknĉy?{IT`vϞ=5Sd @q-[[4oJ2)ʢ_=S`EEk4U6oKRΘ4**jo!!!i7ڕרqGU%a[M%ǣmtttgV2SvDX?b1#h\a N+ݺuh,Y܄.]} 3#F@˗/6mZ2ŚTh@TgJR~]R'(,X%4nA\\\ϯyhm۶!PH"PUrLxL@h#k]۲Cnzsٲe_YPV"]BJv ~ 4VMM;nxXÆ֭s*|S}FOtuB_qͫǏJAp+vW6aT>$}aQJBAA* u.]6lX3%+@~~~妢ߟT!1(5-D|ʾ}=<|}+-_]-`Q'%Ag']A?g2ޭUrsK_Eg~m]?+hyܼ_#޴̼ IZ;xEGu] }bbAtt:ع3ٶ_S;tPTT~UP@C,@ǎCUvh AtR*RqWU[{w֭شoOlБ۷rLmUKJ[oEFFVMCCsvw[odпgUQ2W''C!99gڲe_*^Yd LU7;p!앛hyҼ7l:oyСu9;;ׯ_^{YoPZɧ^7w߁p9rru#e w4kcƌiٲŋH=3323{I׳gt#U^ܣGpb_a(7p)iO>]^=5fVC&vHvKʹsqDxI}zEF:u*$$nnN;^/ZP[d-TB4C~B8~8pҥK#""5*'<5… /tM6={fZJ"))\RPPĀqO?4''| 7(..3ml]#SNJOOo߾=+Vwu… P''Nm&Pٺu^-}rPM7|qqIvvg/˳"' Ƽy󤇹gϞ6md/rDDȑ#e&J2T$>RBpg,$!rg$.T  ys˫W+xt_{aa!:7&&ɣ&MݻnݺtBCCԩc0 @ϧAݔ7|215>>ynĎ;h+X/Q)F8qB ɻdߩ8|ѣGoD%R7l&9Tc??TiР/X -"c---M_7mڔڎ-Z8~85q[d_L!!t;3#dlΝ&p)00&I,TL&CN<#T׮]q$KVg 9## ,EL&H@,b0BnPz @x44dȔa"d;aِ FǎcṷYf^n$vg FrI ( 0b ɚ5k&Oܮ];̲ef̘޽{u}@'pTGu9SH&SsJ \ £:E|I.a6"Rh0%qu׮]P;u?5vUHe[c:mn4>}k S S9) <9rO$L0ـM2>|k:)2ZXB` ^'<& l9,GAIt֑҅v\< ؈S1 kY0fD. 'q|&pG&NA4Cw@)BR"!0IQ#Zsb!In,?J |CrO'ΐyrnC<9C:uGMh r9F?^AO?Dj}l~}k`}A=} 7PPy!ݙw"#lK+\<\J` Aj/aA>4T sUV k.mذC0=ptbs4${d.Z'Y&w.Û6m"<˻NV¾ eCD '8z×9$@ZW0Tx? FeRo8@`"=2sHY&;JrFܱcGَkek:9A2Cx.ɲTD*p2`ah&"KNC`y5s "߿?~C@ ` jzrAݿ_}%sβD˗/}vD6Uk|Ta*ZK_풝~]Ÿ:eTMti<Gq@Unt͚5$> #ĦLf`\mܸQެÈҥ $D,Ba_bG@l&}!H.؄1B~"B!I)@Qta\҈} A^zH,2ev^Z|#Hۼysc's C-BDH",Ira^4Wg&LY-B4 B8C]dRHTTN>]ٹs'NlA?܅{Î;QƊ(( !}} U&? ,7{Հ"'MDnSt9֭[Ϟ=ə?|mݺo7nŴ>'uKjʄ  [oA*0A} [}+R.ĉe6z+V8[u̙z=JL\I:Æ g4VFsݐKOC~r@T>Ԕ~!N$$6%VVNRGG!Lc@]%| ɄNb ޽;<?#pdd$ %ӥA[2@8āe,\%"<$!N,:T7<'=$0@aSy$9I.bvDQ/SPč"tHb?-20@\ DaLBzQF9 27xL01B&;0y]2:"cd>EE!Aܐ9}.q)$aK,3hW2pLDdۇd6oC>x)Jv+h/O8_)TxǐCmG/~믿o˙zW5u]G%hO&4\T!}\8&F ԧ<=|pu* K.H7FDD4 ;?ɬ(BxЪ\a2Y>u S>y8`8j#LLGj.[f)‘6l:uJzB$ T'Jb*Ɔ R@`J OHH%pI޹`M ygdd#i!?(߀p;ĉ3;wY @,'[HL]̱ D)HHMG׮]85$WFX(ID5.v}eR2 C{` ƈ[hLF >|#/_UAWCLBrL+&r$0"ߵ2d޽䳌 We #44%DzYq_Qa_}cǎ%g{=MI}O%QHqqT Wsn6L? t6X5s̡*=T"I @#}/!Ɓ֭C&O.~?m^-+Wlh1Ԩ_+HZl8Bڂ9Zqi{em@zAsZbb@N4j䎬@O4<<ke|;B0M*WaY!vC{H֭[Xf?Os LbPM"Kiief|ֈ} \B(d֭[tBrͣ?d% Fp"qWr"3e1agG,< N|*OQ!d#n9 +FpYXBw-Dg$V ?~<1%aĉW4իTӧ[H"&4<4tM*,2bӦMTL: :<6*y^h4\݈6.^l0dOj B̙/p=|8ݺu動j߾5.ηcGCDDvII/tQ6Nгgize[Թ~TE.=8nG|ͤuu* nruؑ 4gP.=TY *@NSLZ$Rm w>B9aSxT^ȔFx i;{AN*ɂ4u!rmĂbظqc=`M~0D[oDz_Y9dBӵkWNRWWЏ_9/( FFFSI0YArLXO|X!3!K&U$8r|:|ppqA:;?SaUJ)#4XdIhժ,*kP#?eE>PmpAML Q!v*Sa)g$9(D ޽-O?t͚5,ȍ{ftn%9ڴi._мw}T- [ g p:rݩ ҍx9Sg*bD\ét 2޾}{(3-{쁮8@#dAR^zk׮%<4F\9II*- s/Q~k. c!:}[AVo1c >`SȒ mU~ʤEhb.cGGEE9Ib#1.q7< ~ʮX , YqK{bmذaan<5r q3!3lK#p9NU3D̡g.t j&\ޫFN M7:bqYDʽ:["h K/_^o7.{_]g{1TUi*&W /ȠElѣKgtZsoDd4Z3!EյHheZ~k4iߖACFQ}Py[!Q# C.b/>}J׬q6^&ԊSI(X0P p7|##pBrjȆ"._r{PP|&B?A?n޼9a4~2<.Z 3H BꄤIŤB4l׮p@YjժU4aSB2Qd|5 |U:$ tFRez^TYaDN ¦'do#GdNItt1%O$`\js;\"8\we?j(ػwED6 "nǁ)rgx?\ի0n:|CKmFȄ/%@2###4MYŜ֭[=%TS5Hq- (rfܹJĉeiӦ}wrK<Y徒z |rL}1V''rr-ZTuo\aRzUnJO.K"O/l/ܹEl4>?u^LK-IƖg-tzM׻k c*^zWdƸ8m :F#eid&N;udJҰ"ڹ Bǝvڰa%fQ7<<\&@;(7 $ٺB6:|pn 5Nt._i˷UWXd!QyXH,/d3 ˚<$dL²}9t|F!K\#Ap#gII 2V+ҳ[/G#V{Q\%Q(h쒈O˼Y SzIe(e.cP̔ر#n#&S,J$VExċ% Pl1d~d* Eخ]>A]a1p*<- V۷o'<'aD ciJWN" 02C#YxMCA']2!'-7)f7ZB6[6*d̊leLD<D'sY eYg%svލP.[/+4LpqN~\|:7HMu#K9c6CCi1*Ɇ,}f2 -[Z&N4Z.u~={vJbAԱ֫g=~߀}m[8m%xA{ySIh2| tX",'l'g3B| y\K\,hq7FEEaR@u-̻D\⇢*?HFLA ^YG7Z̆,3Fcbbh!N( lAQ'!^'uBx.lpR֡)֭CLCٵD6mawYAqFFFB̔$rcŊ]tɒ$_~؏'_ZJ҅'I>yNVZ*ʶX&9E;dV!nx8e2drܐǰ3Dij=2TٓnZFbo_I;gd ߬rzj6<RE).m @ ᯾,H 9G&]P֜3hJGmHjiT79:_*ch_Xr)-[FO@g$Aզ%lE믧r͞=8|pJ/,JI?+W`LÊ|u]Z93S f.9mlɓz}YbYePSpg\Q۔)ňOOuי1t9  ɏ,_8m;ץ[7sDyĈW^T6&!3ΝdT)  ODKFFg[M r-l =yAb@Aq# ơdy-l:y0(2/{鬓:fIi1! $&h уDT d,@DWN2f*G>KHo%{a("M6*Ȳ] fU5efl*On۶M[=3!OOBplxf"Ud.|\6s< ]9+k:>wA`G6/u CUW7l#IQ(Ud|Ȑ!:[GF/$YEg[Oq(rP)x;;O$$$zl^"Edŋ5!eZk׎&8;xmn5=}PP#֭:O=U ~{YeKF[  xxXǎ-?oc}m!Dd_,ZΩTySFoI%ӪZS]C3t %Q8(*G9*u,@B Ik(n&{}s;]\swzVZӰ":vծ9gyg$+uè ^m:aB?ۯeQ Mz?3#PO܌c&x_'o[j+30PdƀlD&Ksa&OhڵUVTtbEїMY@67 RIR 1;dHB& !` JF)tdBuB Գ1 eBs%[@4NdKJ7( ܃jb"( Sm wϟ#JD?%''FȊ8UZR%Z !a \&"0_= eɃhE=fdʕ+?,PX[7B\7ޠoKW&MmCtՙh i`L0*4i"S az$[2hD R <N-Mb߾.]xκLj$#ŋy*Wŋs8P,1޶P5j>}&eKWef`d~f3dybT?C_];%O-*>xS FϜcNvȞ7u >۱fٰ^_,ҹ\ϟ./ËfϾ/::Q#3Yog~39sjp_|U|>cΜiiy >Тg+ץ9iiQ*Iyɥ+UɡST2d۝+ 3jN͋ý{=`FWMiNrMtJHP60)-@/YvS%f/8'jժ15k]R:Āi;we™umDf^^ !*G[+ 7D"jM6:(_Vr HKR:F;"1A,#H.#ݻwG *TH'3IVl˖-\0lذ@e!Eu6RAj#'%%Q@ʥ- @:pA}&FhՖ\;uVjT5u&4Oܫq< d`*11ŤMeÃb &u6oBƧ}xDFmJSb Bf12dHt-#D,:wHa]o0ŋ~ɒqaT^c+O5>nD'8PkןL;<sBa#|p׮ Cիn?ܼ?9ٖ#/'*Uʒu{*Sƍ#Fh}ȟ?ynD]JG捋˙7n|;v~EJxyNR}6g#Gw^=% b/T.nLp #'\/0 %A'*!Ұu@Ae#A*;~/X? W: y%A\Mus۶ms;ؓh \'>ȵ&Lʵj"#Qtt?k!6qx*Lt}))Q)>Yl*!*e]iHSRD: d,ϥTX˾}xQ_ݮ a .ܳg[Gir97B6we[%c uv40f͚0o߾}׬q|  7g̘AWbW;wn'N(?wyg׮](sL! ڱwЈJS\f'3g,(Dt=B `~sVقAsњbFoZq͚4Ƃ-XUK9.Zd+X0ئ/@ /uk߇:˖VBd;xLÆ]޷φIL!7 qϚǫ&̞czD#WTTDjri'ۓI0.[9\ױ0Б+tZ^=J- Ԯ]UV= tPf@З܇/<`\Q3'IdIg1dZx1OGyY%qB+#\BDٙd $޴8MS>BUܼy,yQA4 * `$s"H #';p4ddF$`^_(#B!>>*q(YåFTÁtXxZ|t$5kXB4v}`\K PgeQRJ@]47V>"|<M˕+'&J)oRZS n)pІe/A'eYFTnNQK)t@.:9IZ-ؔW֫Sĩ( B+R.\صkW]JM@v;HSNiaÆp)>;ƍk֬IidYkТ ꃌf6X\v4&w_G]>ܩ. Dh,ґm{C21tj'Y.}/8ʕ+F c n_騥cu~˞h#oQflviѢ>vçW_tٸԩ%78@ _}5YWŋj DDD0-xaJ{\\m[:|2%"*܁kd.S&Kھ7Y˳FpMJjW^qUnȆ 6ĬYq5kkB={lGX@ₓ&1Z&NtԮ3h'[vGO>i!c+1gG̓'lmҤp{2 JaLa:M"  Su]0{jEK {HK@VKr@AI` 2 ydB3Ea0((&`۶mtRyd=4BQx3LyQϡPp!>-[kุe˖AthDxD$޽{)#1FSj>lJN5CkC<~U8()dBv~jCZ@T@8:TB˗I_\`?gz.]=/~nJ tGcǬ;z?)"uӢbfa_2ͥ-rҗ1]c} %fx}ׯ֯?|ؒ+W8?uʲ|Bg9eʚCߦM6m|ŊM%K|͌Ϝ|'&-H<}2d[~26m5jz'$ȑɓ η'D@(+ -@-޲evejCVunDDCG?(  ڵkeIG yW0GZkGFݑ2Gˡ$/FQ/ID,͡@֑ (ڕI 6bիW#&\( 蜧(@ %hѢHi%8#Td.r5N}""}XAqQj|:С&rO4!!þ3d߂ijPUV%AU"SD9Fux E?N7jhƍtu_Ws˶p19nØa_^5R:ug7|ſuHM%y淟, ?Fk,55k,^qפIz-Zd`{ᆩ?UJg{SqoY^Ko;k{7퉋3DL뵽i NLHWOO4l{]w*;:0gN^A۶ѝ;6vB:HmmzA3?,U*aT/P [AZZy;v̘R?z^=?2#U2Hcc{h.̙hcRE믻2 ` ]1[jRl=tjd bɓVJ͛WVsa$H2T@y$,3 %Z8(u :Rud6N> a/S0h|rcd NK]*_bb"E`FV R"$\Q@T'Orj[e>} ӰJr,:ZB 4"}J(Й[k+.ͽ{njoݺu P0UZݐŪȈEM_W!2&:2{lD}+CZ-I(0Xx≛}D2e  9m4fFkƘ#G2Ձ9ϝ}قo͓'Cх,Y_}~I.t?n8w.f߾]W6oi{뭴֯& ۶e6:X6no2ܚ+6%d\0ȟ?@^>wO\O?u:Ʒߦ$'N)-#CgZDCȤ$xtsgv@&,;e0ܞLe:l2D8dB-؀0TdIPrڱ=@&7ty]f)B6B[6([ne^^d faN 5)oi?l(Mp ';h"j:O* v,lrRC9I _I Ԟ'C䓂<,9>X2vZ~[ՈWKi;J HN䓝4Y6 򁢃ȠDxy#BDQD^cE'0P)Z" jE1 U*#Qg1|j w3PCRE;wR94KpӦMekaÆ1 -aZaLue&C""SL}dy=W ŋ]zƏw&u;9aooZnX`߾㏍_4qbeN0 6Yc;u=ŋc:'s .] E+g|AKJJL& TШ\#F`^x!pp4ub<|QWȓ'l3etMӼpe˕70䣏>}~Y&M FxoO&!+ Uh!: 2OPAP&`۴iJ9ZБs, 4ʟ ʂ7KN"̤rC8ke#Ak%̡}NM`\rH͕D&wx- BdRDLg6#ҒD5#_ശb, '> \DGeS4˨]6K+-Jurs6sw'w*M_S)kX" 6@hGБBQWjOBvk֬1;,匫Dba\3jyEM/YJMԣǕNMN>vl,&ʞWȉe qwo^ CGAgŊ'Nz ޝ?yF#&/:O̝|ONc/PuϜ9-kT)%rx?-G29O/3祆 }+8/& L"5՛|5Z5ʺ`AS}D5/]ZYӧ:4iظ;h+۷t_%| ; O?ojԨ 2^~re…9Ȗ-6>'#ݺ9*fnԬ&v"E,LڤI`:ۛoM\9d e*ۓI̲%+28D Qei鵠?C'(i03 `mڴI/Px*oh!߲^NJn 3ƛXϞ=;2hS k wÀ.eAuِőeXLaB'!QD@u:B=5ݛۇNF2tDFOʐ Hʰ e'$$P$Z+AZPiРBF$ׯOyI'ā>^fMD(ȟv#/ϝ;iӦÝ 68'R-T,CT :&DChVm=YOkdLӲ$'JPY+g%zZv-MLdh܋yT;݆Nŵv2. i-~ #G,X.3a Ǒ#y=:s2qb1+iSs?`G+WϷLJ$nznYo'00Lt)0aAUa@!v q .ãZjOl" 2)_ЅIYп'(P͚5{G @7h+VtQf/^,&x+S=ouOWF*@5wʕY˼|իm{A#"7oeQO?uڼyL~_w;lk"#}h9slf3h {ȷcC!SL:NBeY`~Z+{w:U ׼`Fws!q[il|lo4o8n3x kR'-t]e-\Dt23~Ϡqp-:: .oq,8~4&"2=Gs um.Z<Dz Ď NG.3+b%ﱕ(?{tYItnfvHl僂Wm #U]`$dA:t  ˗/[Zv&P~J*!")hm6&VTqN3;/ʤ4:Uˢ%2)iqAg@xd ܢhObrNvPT|D @4fXԐ ^QH<_hUH$XZ5"묬,DɐuHFE[k֬ц @#*Ɉ2qFNRO@;=1g۶ma`B/Oz#5P4= NPRz') ! g\MQR. X:5'^͛7s̻[RW0]}ڬcД:g0 goX?%op!*"c*W:Wb1;m\Ҳ;=ᇎWGE@MwDE*Y?Е5k`׮}])~rğ={*j¯zg-(ʆ n^Ne>L2XiJ;}TO| [7 gN YC=zHMo_z][6thϢ_}Lv=pg"gg(:vj2ߴiSYD*tzvڑLc!L|"ERH(7 W'B_ˍ(#$ƨRnjCf$u . :-APԉoi%))T!E_ A&Ѥ[m$eI;v@YtTV=Ė2Pj:yR2W*dAB&? oRWQhn5ڴiC}ڜOl*):à1LtFa]SMII +=}j}uTllc:]_zqe0C]͖շɫs^|w9`舤7:,_Wu.P'siFbb@dϯ][My[IR<҂Bya]#dɚꢘ<줉$`6y& AE@~hkMe?X)*_IB?#W#Hsr{xL3*s^zAzMPG}D:dzުU+-|Ο@ʟߜ" om;}&In]ߴizY%:;K|)3fMl'ryw"; Kڵ $c0Oǎ(A&Xa{Uז-&z&NM 1W^y>sF̱L< mb5q<3ǏۆV 53>x ǎY 6~#|XT?bDijϦɶ0xI\[Z5hC?=fQ˜9N;jܸ@Jf-Zb~[XѢg[FG.Yݻ{Lq<|zٲe|~ꢇYnu5d ^l2֬3@&Ov=|] voyevm>wɒIۓI0kV%lذ!*խ[W&aԄ$bĂd6mڐɩVflUI{c>e `FTt휷*Trp(+V@ܬU>r HF?F~G#'uKeZ۶ƌI%zX'cX3asܔ@ܶzS'ڵ6m|c8k ϝtk;4忨_`̥ǏP=\ {c1A-[ꌷTp4h.ej԰atBe[[nO&|21r.] {_`q`l6igP`֓{-PD(@C"11K  DPx _1(@A[n#IJYX1hLY5jSaB2D̵k$a"tUժUC^ ri/˺dHdeZ-Oƚ5kE2utհ I%^D:u/԰ΞhÆ ` OP:]bA j"zH:SF hDε r]"iMK1SICZA.IA69% ّ!u ;+-kR؄_JI&Q{;wKpM[t)Ceʝ1o' @8vSkĿ\-Zxm+-[lsT]Ŝy쌋 8W_M-|D-S_P_( קOO=ڹwjUSc~/4=S55w.Q`/Ti<&%tt7mA}4bPo:/>lX!~^w7 _5@2gxǞ|I#dy i#Onݘϟ Ia8gΜڊd˗%J/]Z E_r]x%@/kwĉwq.u<&ŨM11-Ιۭ'~vP̥1W6K}m?>}]CG9;l-&&;L39o3'[Ϟa{ݱ^#jjW.?KŊggȶwt.ϙSI!/V9V﷾JlWJJ9qg4x%[bbL y}ߥKg;k+)̲N_:2/@2 &ܞLC̅& hV4P ʂkYK A2<42ϰ~z*D): TaBV0tzƌ + ZI\N"(knݺ׀vu]Pd7Bޜ a+_( 3;I "#ʕ%^$k<35T  v!Lʕu:B(tA-C@x^zOd`\Ijy;Rn(gˈbhv}0:Y*ꖪ-x ,? ٬]kDD =q9kRߠ[(^{W\h7mZJII6tܹc pѿT^hj O?]ǼVkzo4Ǜ/rݰfMOGTԏ?{Dqx] +W~G y#, cs޼y̓ʌ9 6Lp᭸ 1Aj4u?-Ra#^ tѹ ;vdM'qq&mŊ#>+pXw^I#.eR92^kxZtf+.ヒDxO>Y6weˎssυ_,7z}{\ސ?@uq}۫Ul^r+f)TÆXJ]> 7o_=;ʕsedPWJ[V H5AUns{2 ntwf7ТM6@:" E;,*2  L`̙3Ae0ʾ2 r!%q#;|Q͙ID L"xtcsL],yEҁ($%%iEeWj x9Ő /(P(VLJ+E T#eI\1jXBAV׭['ϥ7n,C+V䘘e4Ohd o#4%.2HQB?i$mD:dʋe.0 '<' {)SBnJrh*_h(>}kz~r Ӳ4|B#3\o ILb,hygv[Z@{UȗϾnڡ ֗i_}Hxԩ.֞3gJΜӝ]4#Ұ~Doķ`N`*߰!vre_nѣ]+V\͘8߉9K*ݴi`z4];OL`[ھU9 6kV/F0!k?hm,wK/zLqBnjґ#U*HhDݻwkc&&'8׈ RE"GRkJAHt䐌>&5j* s%V(lsھJuh '=K.Zġ@'T70BKkO?TF2WSM_E8:LRLٳO^ͩ;`gW,Rlzg3ϦVf˚Ւ#2yrJg6l(s;Q౭[unĈC>{ϚUR%o\ܮiӪ<{v@ Rͅ 86F*Ln.\H7EΝxbGctSL8d>C8}mۖ=zYw?=`3ϸnjqz<@r S=$LI%SO ;6_?O.Νs|sS+$Xx ^L;1kq+˖~?6ޤI@;v4?@ fM_Μcn=XdѢ]… |5k` >4kc&[mӧ;Ǜ7nukw\ֺu+V3G82?=fVͲykWw|ۓI#04ho#PMHtlNбjժ)p.)IɈv,cѢE:4J*v)cp?^yҲr ~C20‡RD.r'B<*ARDFOH$BI߬Y3܎ePAB` rr0:ϩ&F(yX /ק +o#k !ڠ #ƒCQLUN-UJL4x͉4 >:aٷe7Zg7o~pw>j(#4uѷ€9x4B6m닉)vUGo0oQp~fҍ.Caڙ3-[ް>cFa&֭3f5u2.y&ON]۝/%8z4OVK,ݻGwݹ3櫯*rEJYSR˖٫W?>lXMiK޼Gș={] jZ-_n ΝOM#\Gys Z-#Gpԋ/>xp5k{RS-]z_~_o"S\W뉍S?99:w6.,H~ ʕG)+FzzC5Ol:?bD=%~Į]{J,kK30ma j4F*֦-V|_@ϖ +x⋨ ĩXI2&Ov@*flmo~%"km-[pr06UxhRh7(~$&5OCsϹAzT_*Uʟ_6pA%{v\Ŋ =Z_in$Ξ;f&جY Tfŋg}SK6 >T?dLɟ?fMԩNtMLH}%K[ ({뭷.] 0Bf+o 07$.+7Qu %ŋ[ÇÍJ~a di3{v!gEku 8ƣH JɆbglq"ʒŸnnB/A lŊ |t mp: s3 4Qc3Co_w֬A  ?˛$XDN&d ~ʕG\~ -ur RsJ9Nxj U7L&H3:Lr( F_J8 V sMd2շ30+':t#L.+)s%[O Lj5Bj*䗐ZZ)H;U}YPMnTygfTuHH!MRBg/@fO:A梨uEAZ OCFmS-Pe9=QTQiR Sf4@<-6ڵM6?2KBqd18r+/O+CpG:'w'Pdyq#diSzrg댁67L/4i_\+s>7lꏫ8z8}P=ÿ˅"n{_~8~(iE~}:zEZ;s۷g2-?uT.|IoNH@CލaTs `и+W,_}essFwLftɺtW/矛r=޾7) 2ujʯڶNdSPkWsOvKԍ ~y&ѣ|8'VWO]W BM~I:u^%аwj&g e+ܹ;L;z,q@Amsba7 ? 'lv NNN'd7mnjE rkҥeG]H=x j=q(W=ʖ-l2( "$ V>fcB>'$$,_d(Z:f 8e9)-h(UP*:AYn 2MYF ΄ f(W:~0'H*BZbj'r_H3@n1l'eyG$}O ?)&BNFC]En)֪x6xޢyD䁅wesɒ%K{ѦwqJiIax]a-[ȗ@%CȨ:*:4i!I[t֍gp r0$7Mm8p`dȍD5:Y5^rϗqoK_|gqY ز6yυ܇-X^yprW5OO,9h0Y͘'N_NVl9F?>u-1,ZM͏Bu> >s|Ӧ9_nlrpk$5^5-]26`ۛ%x.yg?w_a/Cc[@U8q"cMz;tH ?{5dޤR%JGo:uef,\ܶZi :S >1vM&fLLm۫u-[f裴gBή9ec`ƍW^>Oj%Çl(!!YGHZ?xg2 ԩ>&C~f$G࣏"ʗ,h1¡C #w3+R7ibZ̤-0I S!scۓI02i`P1Зb|_`dPUlE mtT3A!\M!%!; 6`2afvڤ&"N:L4)Hm!(5dBAdZ>IF8.^III5KH^FRGHŠ2,WATjbRWWnڴ)鐠LJȞՆ  sCٷGGܹ'| />áSNpɓ'çwN[O2_~F U+[~]<>ޟ;7;|def&}饈-[l<-yer;*` @s f|0+g6g2jT{XvN@u~4llqh(}ƌժd3w:''<%mڜ1x3/^-[O/^HrK_wy^y%FqoPFȞ=&'+NR. ĸ˗GsU;؀;O/hʖ<Ѽecَqm}0wn>]<3gׇ`0pҕrjԨ~$@#ʗhQ~ :g@WрA2]& Cۯ_>!!A*,'˖-.w6ɋDƘwx L}ѵGAK5eE*|ʽvxP(X&6'Rܭ\20!t1xIgAق B\yQeF8+WD< @<2Bחm.m0d&qHDV8)2D@n^un1 Ko"lAcƴx& [nv|;?j.^{fVtӁ׼iu;77ҒΝ˻ϟW|dá{^xC+Vӹ~jվn;wF2~zϧ֧3g.{[|apqѿ5k1c6{+GOWZBY/x<hWUU{Z{u59.]W1baݖ!}om_TUړK>mǛf׿6JK.d8mڴھ@ =Dw3`Ye BƏo~k+ňRj}KW\ZׁŞ{j&V^%[l!r8G%Aak[͆KG瘱&9kVsUbDڦzkBÔ$j^6Zq2 $ WEE2'3y-u77/^7.jr7r2*eO-BW atcO3{9w6D&(=@ٳgCf"NqvfliFk|zA}qHeNh1˨T3&*EW ʈC)rO{b&Y2k;/^I|dgb7D5a;.CXɰa{Mw[x__[?|~~_S>)qGoo{ѷosy,߾}{>>rHl '?ߐ5 'WG (ڶ}_I!XtWLv MSֻe_ g;]h~"'a @tL*nr;T1sܐհգ Qd Bc>3irp`$0 'bRr&&Pݺu1L & g`5@;޽{Sy! ?xfe_~Y<)`C(%Enh$ qpHV*S 8R} s*QU~UEZ3PҒ?bQ*),f$o h,9Yx38$Di T5/\hܹM-D].ԕv?яҽ o~'(s΍lQ'ѧϺ3cFǸq;uZG}& ]un[#FY0+Zuo<#W-8cҥM^|.dUWfMnqykO>쓟\{ik6lh駯s@}W{ko5f {Ar>5ӧ7?߭>˖G駯s\dɟb_?m,yfR7?F*/WSF܁ᮻҗ"3Զ];\x|j%-[nq[u6mn|soz!>ꓟ\}5t}n]jM0[/ov2?0% P]x4 3bH`"8Ō"h4EGc=qklyf_@Lle|^&E3L%1tҜ9#DGԺuklrds=~ѢEl+% ^D"~3eD` B@Z{LiCU?SXu>x j24%KVPQl x"T qDV.aQAqaF(n'?I}Q Au&QRi|gcS˲]%ȬUx,*LWM rY}1RǪ E~\P5jzS?sk~](W7<[UY>otSg9hbW(|&; F}nu5ASv7A!Z %Kun+Wz6|զ45j٣@/x1h[=؈W Rmu 1l,XEq!*@G'3& )+H#:D'u;M6 Qr`I^b~laπ, %r Rp:VǚL3G0J_;ubŊFB bǯQ \QV@&(͍>}1b[4;~w/L Xds+\'Q8 ʅbO8`G-VH$,uu6 CſkiW/EqE #1Yb'jUU+W.[ռoʛtR_$>X{ZV^"sΚ{mMYkOs v&lxj;睷6vV} M Fj7ݴ۪U,5巪k>#/[f:`3jb $abM_$HS!s=zIbvmUGm=}=j Fso;jv yпje .7 S>BǎcE*;1si&= 7o;7`WzCxI tbxLUgKXkڵklKȅ|7ݜ9s26admZk6D?n9jQY\jlC!" q&Dcc{VD~_mʼnWO( Ee-$WC!Ռ'v)€J8C垍tGA%Xxėiv [#F۷ܹssQ?~!Cb4[DX8|qQ?"$S9,ӅT"HS$/u V_7n~nڹw&!f^v[aOϞ߯ޢeܸqX|$I]$A0??s&Mj\|yΈ߽2TkxW۴Y E-[nvvp/tnlghP+kmGsI?:B+:\`k} <K)uy&SzFcK Sȑ#zF{01ݧOh,im۶P. ٰ4>腩AB:{uƌ2)QFaLHg}vzt61ȈhF.񣡰D苫"`̳JU)E*Tob]4f=5!)dN8+u{)ʌK|!{̉ >9*-XvrOwPUv͛j@yT9T vԩ{vntCk馛.MA-x=P*k|+_fROO|ٛo6onÓO;m5Vo|̿eYfMzyRygc]?lVXdhqZVZjUӗ^jҶM|__n-.=l>}gg\]t"_#m1>a2IM¬(f?SJ+V4[Y>n:|kxka+BÔ$. >'mA  X ZVQ#$@c\P #}YI ˞-Quؙ6rNaҦNp(PrD'1/sqbZ%aFV|:sstZDon"gv_`!܍}8{< ,P(_&w7I$?gϞT' +n⌜X("pBܹsb+VFt2eJEQ*,4c*FAE TਾkTBqO.WJ'|H!BVe~( .GN m Tk.w>+5it#c-Y|РuEm$h=>gD?ooֶw5!F yP?^mfxݐ!k tbFwrF"$z8*>|@Q0cF!̀WFʚx/U/^=oQF9rۧ(F?n1cb~co;˗K.g95JUѾ#,"( i#Բ}R>  }&t뻏oWȭ9ѣO궵`(,_JfUUKkTIfWrh_О>0mv@lv?&F$e*cuCmȭ0 U;ʾՈ]b:Pm4(-yos͖FT;>@8 hi!:aC ='``> Z*gFWZ *ǬBLXfCZbT[☴Дpܸq( "x CL8׬rG1 Kۭm֚FfP/BBC WrQN%,Oqm0K\&Zj@(=h2gs„)FP9  UBYL86SO=w'A.dcK1bٳg+g၈` Բ"&K''T0p 'evLuYw0757}iڴiz>s ~BUU\ߔ=8[[,zKV"}9ޱejA!G}LX"XqPRZ$Q{] Dw)1[!7Ϙ7(hfED Oʮb ƪsԣtiC<裹9&9^QXre4. Fx*Zg I$1f5&=-owTZh1a„믿>>ZKEtG#Ir8Gᔤ= R>l5yφF˃0t^5 6jqqGۖ-7\z3VF}cY(^e/ $oc,U_yyѣ/~1&jmObCǎCaJI2&}z…H>~3)>!kD#ޝy1Ζ7MN>yMO|p3׼B={|1:thypYv@VE(8 hߍ] S !t N{1)%eq {ԩSf\=('ft 4j?(3<.j`q 8A 1`.51ʊ-UVW$xRR|L\_]:tiXR8GYFVK%Kq(Kl[v4V+FK\Wh}]o+ pran12;ưS)IRR(Mp >8X%'O<D(wHej6Se7dK"x0u. ؀qcg#ݧXvq xCE(Oh裉 <|R> Y LdxlNą:yܹ|n kD" X7?Q_Y|cN*{R-X Ra F䡬Tq NЛnݺ͞=;V~<]tE3/>9TKIN<8ӦM՛ >i޽{kUh}YCoaٿ;(r>HQw>`d>>3rHusВ]{bȹ[0TڥOa DaÆ崫`4Ms3d\Lh5b0BÔ$is0&fL|9/P(BV0y;S)\ Wx8,=I8SL`T룓G?0y67@XoTBuIT}"!mpWdL` 'E&ثVo2O$qǰj0&;q*pI"D({݊ҥK;T TFp싨7#lBG<"jxhiPcA\E!$(c*#-.z!r-&C &CTTRD13rV]|B7~ܸq&M*U:w,k̑;gy"Lv7oeI"NXN:ڇ&yea w4W\QQ#\QPw{W֖$+%e%a SMD 1??~<@MzN4r7ap0KgDfUh2~eQbн2_&jmREdnQXΖF.p;6*D3>K@F8ԀoYfaC_X$S#w~nfLDxz~;f̘bO( DԩӔ)SHf̨>E2:w.*N,pR0s'ѸKl A9c$Q S*VIϒ;D3,Q|mڴoZ/hccMZ"S9:I-2{z:ŋEwлʺA[PV=zSCj9sPƨ'&1{W IlU L_e+hTxeFTܧrʼy Dɶ*tSlhZ*.Y+; `jޯ 1',. 5N DνPc!CUDsRigh rmϥ }gBA d-#ދ&L(i6+Wګ82Pܙb) MƓgkWZj~(b@{=RFq0;.B O=Ik9u7cl'-rfzUZ.ȔcI=>D`3].xRU_C.nJЩS' R?RqX},ITړH:uUlB{[h\qح eT5ŽLmK-Sf ZN8F59qQvh |3]r VSRz4RuH0_㌻{D^zh' Fu4QlkN{D:Q>&s=!Z XSQ(Gmx.sA%2[)L\rA)5EwxzG;4>y9-VWS|Bl!k \lg||VYT&8AuPRT,J/nR8c\;Ru>a MYUrEeR]{4ƻ*jR-TZjyA[o-#F7;] S~;͂׳gO`ǒY]UU5j(!baF"lnhhB=@EE3)jK ATB0-ET2!(|sRÇb[|ٮU{]<Xr1xՍ\@@tDZʆT| pK(QX% kVI"[_;fF\fnaXhfI|ō䑁BTK3eTGOWS$-XY;V߈W =8_-6խeGTgqFٷn]pptsxO ;O>9>{߻wlmjjXKj[F0vLƾ#ZZ[ݲF0`;#3m[P]dkC2#۰MXQfLj-?)IX h ~A/Q~;wn6LYBy|q=XsO~0gehiة$&0qC\ik3t@y}[vSN5Yx#\>U ,X wVsm90 zzJA&c=W#V7 EĤ(OD${!1qxV@Ϝ!Y9̙3%mnEv.B30:Kqϟ/f# QC&Ǎ\Ş0z1 "` |'X_(ƒDO-rã%K(y{ͷ=(W,nU.BTСfҟOªqcqfSJ[6Er.+jVF؞;["Y??$rҘ4AE_&'h)t bC ."WìYM|=s54x5@E@IK̐]rTDcOF>uXiaytQ pK8C"Q|<I!&٭Y% >})%X1rt\HpB6! Ym,^8 Lsj/!`ƭ~r {{L5nXZ(EvUUU1XBYM4)f0ܣG̘1E13*)#Oj=и1,wbLDqh&K^w&(+ prIl6/5\OZ}Wx5!Cxu7tI'!oFi;ݻw{_}Qs=\K82}'qqu}iuK'92JMķrï|]rg}ve|%6mD9_u?r$*IԩSaK/N3g}Z~06dPKFʹppr M޸.;{'>Q*;ƎO}*ȵǢvן~ͶMQlӦM3-seב\կ~u S{/boT:SMh^7ӧ nV77; RZI?[nǩҥKqE6b< 793>hjk,CTc,ֳ&>҄.`vjloMFscC~A/28ʲ7^[Z`2rޑBFTa¤3|p"K\.ٶO>f"y%KٞeMy 6rH!_s U'(>ADLM$ c";uO<$jUD$5 JbЍـ!d;ăW(G$J;x,Ik*6Im ;$ϱhc1EtB՞寚F'F1<`L>EFw1D]es&f5⋐ʯ50I\#~Lt֠_V~u7j|-?lUu= x.W{M/V7gyu0Pl9Y.?@l%3a CorO4Y rfޣ^{{UÔ$TPǎs3yKx! (]|m T|pVj6$ ZgL\|}hcX ap܋[$_#| dp.] nD#[@q*Q˘ȂO1, 8!b ԃs1r%Muh"ďR~njE?>o޼\NB []{%eeKL-|0)v$4cƌ=z<@rKFKn'd$k,oVj vTY0`X`lS6JHc׸Uޗ}M2E+U6D͡ttu S0,MՔ5ktp {<ʨM@riVYg7:E3M>vMB<|Hea!W*6j/ι@Pܵ3-A1OZVʙVQogm eU4L!7JšdbP #y{o5bxjw^k֭iD D߼3ɞ W]}eT&pi(pŽ ^Qr L"g;$pEY74kt բswŊXWP|ҤIn裏-,3f %o~":,C*sAr ˳'wڵ(HU aKÈN:ŊWN:r>2~xG;-p"XPp¤۝>gR~<{ "ߜ7G u("x VEM)y&Z\;|KIes噘QC$FeOzYރrջCch9ꌆ)IK 9@;۷/$q_34 Z`:/RjB *v,S!{˛A͙3ǔ jGVI ;wF9d `Ր!CD3֐,z!R܉@q. ԕ"ƌ1Ϲi/ !Cql恥[rA-ecTHi'c*J?:AE3C)`"W,)$xPyo]bO41bלܖ@VK-k%=G}٤ѻwo2ĉ 1'> %2 zYIz2y9ѱNjZy=|-BufY3TiƔm۶o-ZYB.]15lhZ+S˖3`R:ʼRo*(x2V:vx1͌3HcΤL&I'0֊ ]x4 x4_|#gW\u0`:}e4l02f(-Z6LID z0Ø]d\P4tt1m05-} f8Xh7є'*jLGW+D=!AuŒO}1o☣iwٹDS;nj}ӳQ ]v;vb+ =}ћIL&o4~'&[!U5"{cqj%NNrVe|baK~L".Lv5IXN?P)3I QlOlCL6 0.[-InyK@"nj ;Dm_~ I',wd F;yD2ՍÀkSu'.gU CÔ$ (@@#.3Q* mqLx+f:m!$qKNSiʘ/m| +UBnѹ7Q4cLđ[NA( W=(u|9.#|]w݅:bՓoX~lԦ⛑O,'ƌ'peip ynCYx˞SZmr-cN?TdM1%DFa8qDrvLXi\G#zC=pP9rԍcToc0 6ʘc zQb߉`PX b[aٲe JmD(2106T@Oؒ䦎G4a@0S՝v~liϹ%WGr??13vXm CvA'H)R,ϛe2\aJ*TD}/+ Tٯ*Y9s B_FJ#Rs sPK^ʌwJɵTxԩSC}BI8>L=Idɒ' G.A;NMx fIJ=Vtϛ7/Q͹V3Ʋszn)b0JB&߾}$ʒˆ$PZ'9`FAk%GV#!%hAmڴCY$xOmJ}M kxV3#Gy4hLu:ܗ9^]*}:C 4FǏ?OgYʘem)fe."ĨѣJIB'$@+gzڰatX:\yf*@{bX}yņ=tUi2=| _PI d 'P/B(60`Mr"gyfGa9Dak sM4Ւäo&#mL X!fsTh'(i&"€(S}> 6ZԹXM[@9~~$t)u1-T4}Da"vu 8ѣLH5$ kFӢh#kbZ@ ọi7͝;7no#g`>"#cfI5{=(lLq#8G5r,M'/q* 1 ٜ0h:>S7Q"+!~d!N綅ZBQ3KbS3f&[ SJ"!J7}htxPlH;lBCZR׬=W "5~E(㕟־+>E([)3mԈ+"Wܨ OVBE""N".BVMm ԨKP{hj?.-B?RͦgbXChPi5l-(cekhD]ǣ4ض%D@ %!%>{h̞=;> i3}t/-X!hQQ RpeD| -[&e˖N+U 0cg!.hKLA'CΤ2J(f֑ƍ4}O9~XԴCP(#Xup;SNimzyB'S?F{؋ɓ'+^V!͆9Aolc~I?4CQTdƑʛy-x=I5˲p̹OܸkD2Y6$z, 'r_L,d'SueK(wz;ya]]o14PڷѪZ6л1319#;$ FE TAl$sq& z~>llղ|0 c@VUUYgG'Uv"Od bssC$ʅػT\K/:=%j5:&zgW ze$i Wx"-׉ØU/#z "g4qg#di=9RٳMeƆO\@Mj)Sy1Ƨh#uD6o2sTBf#$4$Q ڣݩcvtBb -DsM[b޿x6b 54Mx0Ƿ+dY}s3[na'/abh5tx}EJE}Oy;] cR;wnYż3ݤaEF,,tXeɮ~+E͛x{M*n r܂ !P$x(ҫW/@l5f̙3s_4(w &3D|!!U\xDeP$8;}OhQС)e Vŗ,fnjӻw˗ڰ!@,^X0Skx:AW9ޔ+ڵko,媪!1'B%PrQ 8zƪac 1“+z\1%ͼR,ރ)/Aꛑ.V ?O.;O?O 6jԨ u޼yFᢋ.3g 0 _r>$a0|ڮvnV$bȑ#'M4p@3v R]xX3isI~q[cEyܣk/7LIb֬YP/KV` JiQ+,YҧOݥK#,XQC"WD jr!+7R&V#M@Q UFNKّ

Sardana is the control program initially developed at ALBA. Our mission statement:

Produce a modular, high performance, robust, and generic user environment for control applications in large and small installations. Make Sardana the generic user environment distributed in the TANGO project and the standard basis of collaborations in control.

An Overview guide will help you getting started with the basic sardana concepts. The FAQ will answer many of your questions.

For sampling, see the Screenshots and Examples chapters.

A PDF version can be downloaded from here.

For convenience here are the links to other versions:
Development   Latest stable  

{% endblock %} sardana-1.2.0/doc/source/_templates/indexsidebar.html0000644000234100017500000000062512174204306024263 0ustar cpascualcpascual00000000000000

Download

Current version: {{ version }}

Get sardana from the PyPi, or install it with:

easy_install -U sardana

PDF

A PDF version here.

Development

Latest development version docs are also available.

sardana-1.2.0/doc/source/_templates/layout.html0000644000234100017500000000103712174204306023135 0ustar cpascualcpascual00000000000000{% extends "sphinxdoc/layout.html" %} {% block rootrellink %}
  • home
  • FAQ
  • examples
  • screenshots
  • documentation »
  • {% endblock %} {% block relbar1 %} {{ super() }} {% endblock %} {% block sidebar2 %} {{ super() }} {% endblock %} sardana-1.2.0/doc/source/devel/0000755000234100017500000000000012174204361017674 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/0000755000234100017500000000000012174204361020445 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/0000755000234100017500000000000012174204361022056 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/macroserver/0000755000234100017500000000000012174204361024406 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/macroserver/macros.rst0000644000234100017500000003643112174204300026424 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.macros .. _macroserver-standard-macro-catalog: :mod:`~sardana.macroserver.macros` ================================== .. class:: scan.a2scan two-motor scan. a2scan scans two motors, as specified by motor1 and motor2. Each motor moves the same number of intervals with starting and ending positions given by start_pos1 and final_pos1, start_pos2 and final_pos2, respectively. The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.a2scanc two-motor continuous scan .. class:: scan.a3scan three-motor scan . a3scan scans three motors, as specified by motor1, motor2 and motor3. Each motor moves the same number of intervals with starting and ending positions given by start_pos1 and final_pos1, start_pos2 and final_pos2, start_pos3 and final_pos3, respectively. The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.a3scanc three-motor continuous scan .. class:: scan.a4scan four-motor scan . a4scan scans four motors, as specified by motor1, motor2, motor3 and motor4. Each motor moves the same number of intervals with starting and ending positions given by start_posN and final_posN (for N=1,2,3,4). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.a4scanc four-motor continuous scan .. class:: scan.amultiscan Multiple motor scan. amultiscan scans N motors, as specified by motor1, motor2,...,motorN. Each motor moves the same number of intervals with starting and ending positions given by start_posN and final_posN (for N=1,2,...). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.ascan Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.ascanc Do an absolute continuous scan of the specified motor. ascanc scans one motor, as specified by motor. .. class:: scan.ascanh Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: demo.clear_sar_demo Undoes changes done with sar_demo .. class:: expert.commit_ctrllib Puts the contents of the given data in a file inside the pool .. class:: standard.ct Count for the specified time on the active measurement group .. class:: scan.d2scan two-motor scan relative to the starting position. d2scan scans two motors, as specified by motor1 and motor2. Each motor moves the same number of intervals. If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.d2scanc continuous two-motor scan relative to the starting positions .. class:: scan.d3scan three-motor scan . d3scan scans three motors, as specified by motor1, motor2 and motor3. Each motor moves the same number of intervals. If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2,3) The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.d3scanc continuous three-motor scan .. class:: scan.d4scan four-motor scan relative to the starting positions a4scan scans four motors, as specified by motor1, motor2, motor3 and motor4. Each motor moves the same number of intervals. If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2,3,4). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. Upon termination, the motors are returned to their starting positions. .. class:: scan.d4scanc continuous four-motor scan relative to the starting positions .. class:: expert.defctrl Creates a new controller 'role_prop' is a sequence of roles and/or properties. - A role is defined as = (only applicable to pseudo controllers) - A property is defined as If both roles and properties are supplied, all roles must come before properties. All controller properties that don't have default values must be given. Example of creating a motor controller (with a host and port properties): [1]: defctrl SuperMotorController myctrl host homer.springfield.com port 5000 Example of creating a Slit pseudo motor (sl2t and sl2b motor roles, Gap and Offset pseudo motor roles): [1]: defctrl Slit myslit sl2t=mot01 sl2b=mot02 Gap=gap01 Offset=offset01 .. class:: expert.defelem Creates an element on a controller with an axis .. class:: expert.defm Creates a new motor in the active pool .. class:: expert.defmeas Create a new measurement group. First channel in channel_list MUST be an internal sardana channel. At least one channel MUST be a Counter/Timer (by default, the first Counter/Timer in the list will become the master). .. class:: scan.dmultiscan Multiple motor scan relative to the starting positions. dmultiscan scans N motors, as specified by motor1, motor2,...,motorN. Each motor moves the same number of intervals If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2,...) The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.dscan motor scan relative to the starting position. dscan scans one motor, as specified by motor. If motor motor is at a position X before the scan begins, it will be scanned from X+start_pos to X+final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. .. class:: scan.dscanc continuous motor scan relative to the starting position. .. class:: env.dumpenv Dumps the complete environment .. class:: expert.edctrl Returns the contents of the library file which contains the given controller code. .. class:: expert.edctrllib Returns the contents of the given library file .. class:: scan.fscan N-dimensional scan along user defined paths. The motion path for each motor is defined through the evaluation of a user-supplied function that is evaluated as a function of the independent variables. -independent variables are supplied through the indepvar string. The syntax for indepvar is "x=expresion1,y=expresion2,..." -If no indep vars need to be defined, write "!" or "*" or "None" -motion path for motor is generated by evaluating the corresponding function 'func' -Count time is given by integ_time. If integ_time is a scalar, then the same integ_time is used for all points. If it evaluates as an array (with same length as the paths), fscan will assign a different integration time to each acquisition point. -If integ_time is positive, it specifies seconds and if negative, specifies monitor counts. IMPORTANT Notes: -no spaces are allowed in the indepvar string. -all funcs must evaluate to the same number of points EXAMPLE: fscan x=[1,3,5,7,9],y=arange(5) motor1 x**2 motor2 sqrt(y*x-3) 0.1 .. class:: communication.get Reads and outputs the data from the communication channel .. class:: env.load_env Read environment variables from config_env.xml file .. class:: lists.ls0d Lists all 0D experiment channels .. class:: lists.ls1d Lists all 1D experiment channels .. class:: lists.ls2d Lists all 2D experiment channels .. class:: lists.lsa Lists all existing objects .. class:: lists.lscom Lists all communication channels .. class:: lists.lsct Lists all Counter/Timers .. class:: lists.lsctrl Lists all existing controllers .. class:: lists.lsctrllib Lists all existing controller classes .. class:: lists.lsdef List all macro definitions .. class:: env.lsenv Lists the environment .. class:: lists.lsexp Lists all experiment channels .. class:: lists.lsi Lists all existing instruments .. class:: lists.lsior Lists all IORegisters .. class:: lists.lsm Lists all motors .. class:: lists.lsmac Lists existing macros .. class:: lists.lsmaclib Lists existing macro libraries. .. class:: lists.lsmeas List existing measurement groups .. class:: lists.lspc Lists all pseudo counters .. class:: lists.lspm Lists all existing motors .. class:: env.lsvo Lists the view options .. class:: mca.mca_start Starts an mca .. class:: mca.mca_stop Stops an mca .. class:: scan.mesh 2d grid scan . The mesh scan traces out a grid using motor1 and motor2. The first motor scans from m1_start_pos to m1_final_pos using the specified number of intervals. The second motor similarly scans from m2_start_pos to m2_final_pos. Each point is counted for for integ_time seconds (or monitor counts, if integ_time is negative). The scan of motor1 is done at each point scanned by motor2. That is, the first motor scan is nested within the second motor scan. .. class:: scan.meshc 2d grid scan. scans continuous .. class:: standard.mstate Prints the state of a motor .. class:: standard.mv Move motor(s) to the specified position(s) .. class:: standard.mvr Move motor(s) relative to the current position(s) .. class:: expert.prdef Returns the the macro code for the given macro name. .. class:: communication.put Sends a string to the communication channel .. class:: standard.pwa Show all motor positions in a pretty table .. class:: standard.pwm Show the position of the specified motors in a pretty table .. class:: ioregister.read_ioreg Reads an output register .. class:: expert.rellib Reloads the given python library code from the macro server filesystem. .. warning:: use with extreme care! Accidentally reloading a system module or an installed python module may lead to unpredictable behavior .. note:: if python module is used by any macro, don't forget to reload the corresponding macros afterward so the changes take effect. .. class:: expert.relmac Reloads the given macro code from the macro server filesystem. Attention: All macros inside the same file will also be reloaded. .. class:: expert.relmaclib Reloads the given macro library code from the macro server filesystem. .. class:: standard.report Logs a new record into the message report system (if active) .. class:: demo.sar_demo Sets up a demo environment. It creates many elements for testing .. class:: expert.sar_info Prints details about the given sardana object .. class:: scan.scanhist Shows scan history information. Give optional parameter scan number to display details about a specific scan .. class:: expert.send2ctrl Sends the given data directly to the controller .. class:: env.senv Sets the given environment variable to the given value .. class:: sequence.sequence This macro executes a sequence of macros. As a parameter it receives a string which is a xml structure. These macros which allow hooks can nest another sequence (xml structure). In such a case, this macro is executed recursively. .. class:: standard.set_lim Sets the software limits on the specified motor hello .. class:: standard.set_lm Sets the dial limits on the specified motor .. class:: standard.set_pos Sets the position of the motor to the specified value .. class:: standard.set_user_pos Sets the USER position of the motor to the specified value (by changing OFFSET and keeping DIAL) .. class:: standard.settimer Defines the timer channel for the active measurement group .. class:: env.setvo Sets the given view option to the given value .. class:: standard.uct Count on the active measurement group and update .. class:: expert.udefctrl Deletes an existing controller .. class:: expert.udefelem Deletes an existing element .. class:: expert.udefmeas Deletes an existing measurement group .. class:: standard.umv Move motor(s) to the specified position(s) and update .. class:: standard.umvr Move motor(s) relative to the current position(s) and update .. class:: env.usenv Unsets the given environment variable .. class:: env.usetvo Resets the value of the given view option .. class:: standard.wa Show all motor positions .. class:: standard.wm Show the position of the specified motors. .. class:: ioregister.write_ioreg Writes a value to an input register .. class:: standard.wu Show all user motor positions .. class:: standard.wum Show the user position of the specified motors. sardana-1.2.0/doc/source/devel/api/sardana/macroserver/macroserver.rst0000644000234100017500000000063612174204300027466 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.macroserver :mod:`~sardana.macroserver.macroserver` ======================================= .. automodule:: sardana.macroserver.macroserver .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MacroServer` MacroServer ------------ .. inheritance-diagram:: MacroServer :parts: 1 .. autoclass:: MacroServer :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msbase.rst0000644000234100017500000000104712174204300026405 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msbase :mod:`~sardana.macroserver.msbase` ======================================= .. automodule:: sardana.macroserver.msbase .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MSBaseObject` * :class:`MSObject` MSBaseObject ------------ .. inheritance-diagram:: MSBaseObject :parts: 1 .. autoclass:: MSBaseObject :show-inheritance: MSObject ------------ .. inheritance-diagram:: MSObject :parts: 1 .. autoclass:: MSObject :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/mscontainer.rst0000644000234100017500000000063612174204300027460 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.mscontainer :mod:`~sardana.macroserver.mscontainer` ======================================= .. automodule:: sardana.macroserver.mscontainer .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MSContainer` MacroServer ------------ .. inheritance-diagram:: MSContainer :parts: 1 .. autoclass:: MSContainer :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msdoor.rst0000644000234100017500000000057312174204300026441 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msdoor :mod:`~sardana.macroserver.msdoor` ======================================= .. automodule:: sardana.macroserver.msdoor .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MSDoor` MSDoor ------------ .. inheritance-diagram:: MSDoor :parts: 1 .. autoclass:: MSDoor :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msenvmanager.rst0000644000234100017500000000070712174204300027620 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msenvmanager :mod:`~sardana.macroserver.msenvmanager` ========================================= .. automodule:: sardana.macroserver.msenvmanager .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`EnvironmentManager` EnvironmentManager -------------------- .. inheritance-diagram:: EnvironmentManager :parts: 1 .. autoclass:: EnvironmentManager :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msexception.rst0000644000234100017500000000061312174204300027467 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msexception :mod:`~sardana.macroserver.msexception` ========================================= .. automodule:: sardana.macroserver.msexception .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MacroServerException` MacroServerException -------------------- .. autoclass:: MacroServerException :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msmacromanager.rst0000644000234100017500000000076712174204300030137 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msmacromanager :mod:`~sardana.macroserver.msmacromanager` =========================================== .. automodule:: sardana.macroserver.msmacromanager .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MacroManager` * :class:`MacroExecutor` MacroManager -------------------- .. autoclass:: MacroManager :show-inheritance: MacroExecutor -------------------- .. autoclass:: MacroExecutor :show-inheritance:sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msmanager.rst0000644000234100017500000000067212174204300027110 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msmanager :mod:`~sardana.macroserver.msmanager` ======================================= .. automodule:: sardana.macroserver.msmanager .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MacroServerManager` MacroServerManager ------------------ .. inheritance-diagram:: MacroServerManager :parts: 1 .. autoclass:: MacroServerManager :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msmetamacro.rst0000644000234100017500000000136112174204300027442 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msmetamacro :mod:`~sardana.macroserver.msmetamacro` =========================================== .. automodule:: sardana.macroserver.msmetamacro .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`MacroLibrary` * :class:`MacroClass` * :class:`MacroFunction` MacroLibrary -------------------- .. autoclass:: MacroLibrary :show-inheritance: :members: Parameterizable -------------------- .. autoclass:: Parameterizable :show-inheritance: :members: MacroClass -------------------- .. autoclass:: MacroClass :show-inheritance: :members: MacroFunction -------------------- .. autoclass:: MacroFunction :show-inheritance: :members: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/msparameter.rst0000644000234100017500000000054312174204300027453 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.msparameter :mod:`~sardana.macroserver.msparameter` =========================================== .. automodule:: sardana.macroserver.msparameter .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`ParamType` ParamType ----------- .. autoclass:: ParamType :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/macroserver/mstypemanager.rst0000644000234100017500000000057012174204300030007 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.mstypemanager :mod:`~sardana.macroserver.mstypemanager` =========================================== .. automodule:: sardana.macroserver.mstypemanager .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`TypeManager` TypeManager -------------------- .. autoclass:: TypeManager :show-inheritance: sardana-1.2.0/doc/source/devel/api/sardana/pool/0000755000234100017500000000000012174204361023027 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/pool/controller.rst0000644000234100017500000000731312174204301025742 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller :mod:`~sardana.pool.controller` =============================== .. automodule:: sardana.pool.controller .. rubric:: Constants .. autodata:: Type .. autodata:: Access .. autodata:: Description .. autodata:: DefaultValue .. autodata:: FGet .. autodata:: FSet .. autodata:: Memorize .. autodata:: Memorized .. autodata:: MemorizedNoInit .. autodata:: NotMemorized .. autodata:: MaxDimSize .. rubric:: Interfaces .. hlist:: :columns: 3 * :class:`Readable` * :class:`Startable` * :class:`Stopable` * :class:`Loadable` .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Controller` * :class:`PseudoController` * :class:`MotorController` * :class:`PseudoMotorController` * :class:`CounterTimerController` * :class:`ZeroDController` * :class:`OneDController` * :class:`TwoDController` * :class:`PseudoCounterController` * :class:`IORegisterController` Readable interface ------------------ .. inheritance-diagram:: Readable :parts: 1 .. autoclass:: Readable :show-inheritance: :members: :undoc-members: Startable interface ------------------- .. inheritance-diagram:: Startable :parts: 1 .. autoclass:: Startable :show-inheritance: :members: :undoc-members: Stopable interface ------------------- .. inheritance-diagram:: Stopable :parts: 1 .. autoclass:: Stopable :show-inheritance: :members: :undoc-members: Loadable interface ------------------- .. inheritance-diagram:: Loadable :parts: 1 .. autoclass:: Loadable :show-inheritance: :members: :undoc-members: Abstract Controller -------------------- .. inheritance-diagram:: Controller :parts: 1 .. autoclass:: Controller :private-members: __init__ :show-inheritance: :members: :undoc-members: Abstract Pseudo Controller ----------------------------- .. inheritance-diagram:: PseudoController :parts: 1 .. autoclass:: PseudoController :show-inheritance: :members: :undoc-members: Motor Controller API --------------------- .. inheritance-diagram:: MotorController :parts: 1 .. autoclass:: MotorController :show-inheritance: :members: :undoc-members: Pseudo Motor Controller API ----------------------------- .. inheritance-diagram:: PseudoMotorController :parts: 1 .. autoclass:: PseudoMotorController :show-inheritance: :members: :undoc-members: Counter Timer Controller API ---------------------------- .. inheritance-diagram:: CounterTimerController :parts: 1 .. autoclass:: CounterTimerController :show-inheritance: :members: :undoc-members: 0D Controller API ---------------------------- .. inheritance-diagram:: ZeroDController :parts: 1 .. autoclass:: ZeroDController :show-inheritance: :members: :undoc-members: 1D Controller API ---------------------------- .. inheritance-diagram:: OneDController :parts: 1 .. autoclass:: OneDController :show-inheritance: :members: :undoc-members: 2D Controller API ---------------------------- .. inheritance-diagram:: TwoDController :parts: 1 .. autoclass:: TwoDController :show-inheritance: :members: :undoc-members: Pseudo Counter Controller API ----------------------------- .. inheritance-diagram:: PseudoCounterController :parts: 1 .. autoclass:: PseudoCounterController :show-inheritance: :members: :undoc-members: IO Register Controller API ---------------------------- .. inheritance-diagram:: IORegisterController :parts: 1 .. autoclass:: IORegisterController :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/pool.rst0000644000234100017500000000064012174204301024524 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.pool :mod:`~sardana.pool.pool` ========================= .. automodule:: sardana.pool.pool .. rubric:: Functions .. hlist:: :columns: 3 * :func:`get_thread_pool` .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Pool` Pool ----- .. inheritance-diagram:: Pool :parts: 1 .. autoclass:: Pool :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolacquisition.rst0000644000234100017500000000067612174204301027006 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolacquisition :mod:`~sardana.pool.poolacquisition` ====================================== .. automodule:: sardana.pool.poolacquisition .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolCTAcquisition` PoolCTAcquisition ------------------- .. inheritance-diagram:: PoolCTAcquisition :parts: 1 .. autoclass:: PoolCTAcquisition :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolaction.rst0000644000234100017500000000221012174204301025715 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolaction :mod:`~sardana.pool.poolaction` ====================================== .. automodule:: sardana.pool.poolaction .. rubric:: Functions .. hlist:: :columns: 3 * :func:`get_thread_pool` .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolAction` * :class:`OperationInfo` * :class:`PoolActionItem` * :class:`ActionContext` .. autofunction:: get_thread_pool PoolAction ------------------- .. inheritance-diagram:: PoolAction :parts: 1 .. autoclass:: PoolAction :show-inheritance: :members: :undoc-members: OperationInfo ------------------- .. inheritance-diagram:: OperationInfo :parts: 1 .. autoclass:: OperationInfo :show-inheritance: :members: :undoc-members: PoolActionItem ------------------- .. inheritance-diagram:: PoolActionItem :parts: 1 .. autoclass:: PoolActionItem :show-inheritance: :members: :undoc-members: ActionContext ------------------- .. inheritance-diagram:: ActionContext :parts: 1 .. autoclass:: ActionContext :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolbasechannel.rst0000644000234100017500000000066512174204301026717 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolbasechannel :mod:`~sardana.pool.poolbasechannel` ====================================== .. automodule:: sardana.pool.poolbasechannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolBaseChannel` PoolBaseChannel ------------------- .. inheritance-diagram:: PoolBaseChannel :parts: 1 .. autoclass:: PoolBaseChannel :show-inheritance: :members: :undoc-members:sardana-1.2.0/doc/source/devel/api/sardana/pool/poolbaseobject.rst0000644000234100017500000000065712174204301026556 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolbaseobject :mod:`~sardana.pool.poolbaseobject` ====================================== .. automodule:: sardana.pool.poolbaseobject .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolBaseObject` PoolBaseObject ------------------- .. inheritance-diagram:: PoolBaseObject :parts: 1 .. autoclass:: PoolBaseObject :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolcontainer.rst0000644000234100017500000000065012174204301026430 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolcontainer :mod:`~sardana.pool.poolcontainer` ====================================== .. automodule:: sardana.pool.poolcontainer .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolContainer` PoolContainer ------------------- .. inheritance-diagram:: PoolContainer :parts: 1 .. autoclass:: PoolContainer :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolcontroller.rst0000644000234100017500000000172112174204301026631 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolcontroller :mod:`~sardana.pool.poolcontroller` ====================================== .. automodule:: sardana.pool.poolcontroller .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolController` * :class:`PoolPseudoMotorController` * :class:`PoolPseudoCounterController` PoolController ------------------- .. inheritance-diagram:: PoolController :parts: 1 .. autoclass:: PoolController :show-inheritance: :members: :undoc-members: PoolPseudoMotorController -------------------------- .. inheritance-diagram:: PoolPseudoMotorController :parts: 1 .. autoclass:: PoolPseudoMotorController :show-inheritance: :members: :undoc-members: PoolPseudoCounterController ---------------------------- .. inheritance-diagram:: PoolPseudoCounterController :parts: 1 .. autoclass:: PoolPseudoCounterController :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolcontrollermanager.rst0000644000234100017500000000072412174204301030166 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolcontrollermanager :mod:`~sardana.pool.poolcontrollermanager` ========================================== .. automodule:: sardana.pool.poolcontrollermanager .. rubric:: Classes .. hlist:: :columns: 3 * :class:`ControllerManager` ControllerManager ------------------- .. inheritance-diagram:: ControllerManager :parts: 1 .. autoclass:: ControllerManager :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolcountertimer.rst0000644000234100017500000000070112174204301027163 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolcountertimer :mod:`~sardana.pool.poolcountertimer` ========================================== .. automodule:: sardana.pool.poolcountertimer .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolCounterTimer` PoolCounterTimer ------------------- .. inheritance-diagram:: PoolCounterTimer :parts: 1 .. autoclass:: PoolCounterTimer :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/pooldefs.rst0000644000234100017500000000033212174204301025364 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.pooldefs :mod:`~sardana.pool.pooldefs` ============================= .. automodule:: sardana.pool.pooldefs .. rubric:: Constants .. autodata:: sardana.pool.pooldefs.ControllerAPI sardana-1.2.0/doc/source/devel/api/sardana/pool/poolelement.rst0000644000234100017500000000117212174204301026077 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolelement :mod:`~sardana.pool.poolelement` ====================================== .. automodule:: sardana.pool.poolelement .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolBaseElement` * :class:`PoolElement` PoolBaseElement ------------------- .. inheritance-diagram:: PoolBaseElement :parts: 1 .. autoclass:: PoolBaseElement :show-inheritance: :members: :undoc-members: PoolElement -------------------------- .. inheritance-diagram:: PoolElement :parts: 1 .. autoclass:: PoolElement :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolexception.rst0000644000234100017500000000162512174204301026447 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolexception :mod:`~sardana.pool.poolexception` ======================================= .. automodule:: sardana.pool.poolexception .. rubric:: Classes .. hlist:: :columns: 3 * :exc:`PoolException` * :exc:`UnknownController` * :exc:`UnknownControllerLibrary` PoolException --------------- .. inheritance-diagram:: PoolException :parts: 1 .. autoexception:: PoolException :inherited-members: :members: :undoc-members: UnknownController -------------------- .. inheritance-diagram:: UnknownController :parts: 1 .. autoexception:: UnknownController :inherited-members: :members: :undoc-members: UnknownControllerLibrary ------------------------- .. inheritance-diagram:: UnknownControllerLibrary :parts: 1 .. autoexception:: UnknownControllerLibrary :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolexternal.rst0000644000234100017500000000145012174204301026267 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolexternal :mod:`~sardana.pool.poolexternal` ====================================== .. automodule:: sardana.pool.poolexternal .. rubric:: Functions .. hlist:: :columns: 3 * :func:`PoolExternalObject` .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolBaseExternalObject` * :class:`PoolTangoObject` .. autofunction:: PoolExternalObject PoolBaseExternalObject ----------------------- .. inheritance-diagram:: PoolBaseExternalObject :parts: 1 .. autoclass:: PoolBaseExternalObject :show-inheritance: :members: :undoc-members: PoolTangoObject -------------------------- .. inheritance-diagram:: PoolTangoObject :parts: 1 .. autoclass:: PoolTangoObject :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolgroupelement.rst0000644000234100017500000000122512174204301027153 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolgroupelement :mod:`~sardana.pool.poolgroupelement` ====================================== .. automodule:: sardana.pool.poolgroupelement .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolBaseGroup` * :class:`PoolGroupElement` PoolBaseGroup ------------------- .. inheritance-diagram:: PoolBaseGroup :parts: 1 .. autoclass:: PoolBaseGroup :show-inheritance: :members: :undoc-members: PoolGroupElement -------------------------- .. inheritance-diagram:: PoolGroupElement :parts: 1 .. autoclass:: PoolGroupElement :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolinstrument.rst0000644000234100017500000000066112174204301026660 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolinstrument :mod:`~sardana.pool.poolinstrument` ====================================== .. automodule:: sardana.pool.poolinstrument .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolInstrument` PoolInstrument ------------------- .. inheritance-diagram:: PoolInstrument :parts: 1 .. autoclass:: PoolInstrument :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolioregister.rst0000644000234100017500000000066312174204301026626 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolioregister :mod:`~sardana.pool.poolioregister` ========================================== .. automodule:: sardana.pool.poolioregister .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolIORegister` PoolIORegister ------------------- .. inheritance-diagram:: PoolIORegister :parts: 1 .. autoclass:: PoolIORegister :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolmeasurementgroup.rst0000644000234100017500000000072312174204301030051 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmeasurementgroup :mod:`~sardana.pool.poolmeasurementgroup` ========================================= .. automodule:: sardana.pool.poolmeasurementgroup .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolMeasurementGroup` PoolInstrument -------------- .. inheritance-diagram:: PoolMeasurementGroup :parts: 1 .. autoclass:: PoolMeasurementGroup :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolmetacontroller.rst0000644000234100017500000000224712174204301027504 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmetacontroller :mod:`~sardana.pool.poolmetacontroller` ======================================= .. automodule:: sardana.pool.poolmetacontroller .. rubric:: Classes .. hlist:: :columns: 3 * :class:`DataInfo` * :class:`TypeData` * :class:`ControllerLibrary` * :class:`ControllerClass` DataInfo ------------------- .. inheritance-diagram:: DataInfo :parts: 1 .. autoclass:: DataInfo :show-inheritance: :members: :undoc-members: TypeData ------------------- .. inheritance-diagram:: TypeData :parts: 1 .. autoclass:: TypeData :show-inheritance: :members: :undoc-members: ControllerLib ------------------- .. inheritance-diagram:: ControllerLibrary :parts: 1 .. autoclass:: ControllerLibrary :show-inheritance: :members: :undoc-members: ControllerClass ------------------- .. inheritance-diagram:: ControllerClass :parts: 1 .. autoclass:: ControllerClass :show-inheritance: :members: :undoc-members: .. rubric:: Constants .. autodata:: CONTROLLER_TEMPLATE .. autodata:: CTRL_TYPE_MAP .. autodata:: TYPE_MAP .. autodata:: TYPE_MAP_OBJ sardana-1.2.0/doc/source/devel/api/sardana/pool/poolmonitor.rst0000644000234100017500000000063712174204301026142 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmonitor :mod:`~sardana.pool.poolmonitor` ========================================= .. automodule:: sardana.pool.poolmonitor .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolMonitor` PoolMonitor ------------------- .. inheritance-diagram:: PoolMonitor :parts: 1 .. autoclass:: PoolMonitor :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolmotion.rst0000644000234100017500000000127412174204301025756 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmotion :mod:`~sardana.pool.poolmotion` ========================================= .. automodule:: sardana.pool.poolmotion .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolMotionItem` * :class:`PoolMotion` PoolMotionItem ------------------- .. inheritance-diagram:: PoolMotionItem :parts: 1 .. autoclass:: PoolMotionItem :show-inheritance: :members: :undoc-members: PoolMotion ------------------- .. inheritance-diagram:: PoolMotion :parts: 1 .. autoclass:: PoolMotion :show-inheritance: :members: :undoc-members: .. rubric:: Enumerations .. autodata:: sardana.pool.poolmotion.MotionStatesardana-1.2.0/doc/source/devel/api/sardana/pool/poolmotor.rst0000644000234100017500000000062112174204301025604 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmotor :mod:`~sardana.pool.poolmotor` ========================================= .. automodule:: sardana.pool.poolmotor .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolMotor` PoolMotor ------------------- .. inheritance-diagram:: PoolMotor :parts: 1 .. autoclass:: PoolMotor :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolmotorgroup.rst0000644000234100017500000000066412174204301026670 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmotorgroup :mod:`~sardana.pool.poolmotorgroup` ========================================= .. automodule:: sardana.pool.poolmotorgroup .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolMotorGroup` PoolMotorGroup ------------------- .. inheritance-diagram:: PoolMotorGroup :parts: 1 .. autoclass:: PoolMotorGroup :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolmoveable.rst0000644000234100017500000000064612174204301026245 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmoveable :mod:`~sardana.pool.poolmoveable` ========================================= .. automodule:: sardana.pool.poolmoveable .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolMoveable` PoolMoveable ------------------- .. inheritance-diagram:: PoolMoveable :parts: 1 .. autoclass:: PoolMoveable :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolobject.rst0000644000234100017500000000062312174204301025714 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolobject :mod:`~sardana.pool.poolobject` ====================================== .. automodule:: sardana.pool.poolobject .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolObject` PoolObject ------------------- .. inheritance-diagram:: PoolObject :parts: 1 .. autoclass:: PoolObject :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolonedexpchannel.rst0000644000234100017500000000071012174204301027436 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolonedexpchannel :mod:`~sardana.pool.poolonedexpchannel` ========================================= .. automodule:: sardana.pool.poolonedexpchannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Pool1DExpChannel` Pool1DExpChannel ------------------- .. inheritance-diagram:: Pool1DExpChannel :parts: 1 .. autoclass:: Pool1DExpChannel :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolpseudocounter.rst0000644000234100017500000000071112174204301027343 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolpseudocounter :mod:`~sardana.pool.poolpseudocounter` ========================================= .. automodule:: sardana.pool.poolpseudocounter .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolPseudoCounter` PoolPseudoCounter ------------------- .. inheritance-diagram:: PoolPseudoCounter :parts: 1 .. autoclass:: PoolPseudoCounter :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolpseudomotor.rst0000644000234100017500000000066512174204301027034 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolpseudomotor :mod:`~sardana.pool.poolpseudomotor` ====================================== .. automodule:: sardana.pool.poolpseudomotor .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolPseudoMotor` PoolPseudoMotor ---------------- .. inheritance-diagram:: PoolPseudoMotor :parts: 1 .. autoclass:: PoolPseudoMotor :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/pooltwodexpchannel.rst0000644000234100017500000000070712174204301027474 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.pooltwodexpchannel :mod:`~sardana.pool.pooltwodexpchannel` ========================================= .. automodule:: sardana.pool.pooltwodexpchannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Pool2DExpChannel` Pool2DExpChannel ------------------- .. inheritance-diagram:: Pool2DExpChannel :parts: 1 .. autoclass:: Pool2DExpChannel :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/pool/poolutil.rst0000644000234100017500000000025512174204301025424 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolutil :mod:`~sardana.pool.poolutil` ========================================= .. automodule:: sardana.pool.poolutil .. rubric:: Classessardana-1.2.0/doc/source/devel/api/sardana/pool/poolzerodexpchannel.rst0000644000234100017500000000071112174204301027635 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolzerodexpchannel :mod:`~sardana.pool.poolzerodexpchannel` ========================================= .. automodule:: sardana.pool.poolzerodexpchannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Pool0DExpChannel` Pool0DExpChannel ------------------- .. inheritance-diagram:: Pool0DExpChannel :parts: 1 .. autoclass:: Pool0DExpChannel :show-inheritance: :members: :undoc-members:sardana-1.2.0/doc/source/devel/api/sardana/tango/0000755000234100017500000000000012174204361023166 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/tango/core/0000755000234100017500000000000012174204361024116 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/tango/core/SardanaDevice.rst0000644000234100017500000000124412174204300027333 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.core.SardanaDevice :mod:`~sardana.tango.core.SardanaDevice` ============================================== .. automodule:: sardana.tango.core.SardanaDevice .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaDevice` * :class:`SardanaDeviceClass` SardanaDevice -------------- .. inheritance-diagram:: SardanaDevice :parts: 1 .. autoclass:: SardanaDevice :show-inheritance: :members: :undoc-members: SardanaDeviceClass ------------------- .. inheritance-diagram:: SardanaDeviceClass :parts: 1 .. autoclass:: SardanaDeviceClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/0000755000234100017500000000000012174204361024137 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/CTExpChannel.rst0000644000234100017500000000122112174204300027132 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.CTExpChannel :mod:`~sardana.tango.pool.CTExpChannel` ========================================= .. automodule:: sardana.tango.pool.CTExpChannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`CTExpChannel` * :class:`CTExpChannelClass` CTExpChannel ------------- .. inheritance-diagram:: CTExpChannel :parts: 1 .. autoclass:: CTExpChannel :show-inheritance: :members: :undoc-members: CTExpChannelClass ------------------ .. inheritance-diagram:: CTExpChannelClass :parts: 1 .. autoclass:: CTExpChannelClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/Controller.rst0000644000234100017500000000116112174204300027004 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.Controller :mod:`~sardana.tango.pool.Controller` ===================================== .. automodule:: sardana.tango.pool.Controller .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Controller` * :class:`ControllerClass` Controller ---------- .. inheritance-diagram:: Controller :parts: 1 .. autoclass:: Controller :show-inheritance: :members: :undoc-members: ControllerClass --------------- .. inheritance-diagram:: ControllerClass :parts: 1 .. autoclass:: ControllerClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/IORegister.rst0000644000234100017500000000117512174204300026702 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.IORegister :mod:`~sardana.tango.pool.IORegister` ========================================= .. automodule:: sardana.tango.pool.IORegister .. rubric:: Classes .. hlist:: :columns: 3 * :class:`IORegister` * :class:`IORegisterClass` IORegister -------------- .. inheritance-diagram:: IORegister :parts: 1 .. autoclass:: IORegister :show-inheritance: :members: :undoc-members: IORegisterClass ------------------- .. inheritance-diagram:: IORegisterClass :parts: 1 .. autoclass:: IORegisterClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/Motor.rst0000644000234100017500000000106712174204300025766 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.Motor :mod:`~sardana.tango.pool.Motor` ========================================= .. automodule:: sardana.tango.pool.Motor .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Motor` * :class:`MotorClass` Motor ------- .. inheritance-diagram:: Motor :parts: 1 .. autoclass:: Motor :show-inheritance: :members: :undoc-members: MotorClass ----------- .. inheritance-diagram:: MotorClass :parts: 1 .. autoclass:: MotorClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/OneDExpChannel.rst0000644000234100017500000000126212174204300027456 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.OneDExpChannel :mod:`~sardana.tango.pool.OneDExpChannel` =========================================== .. automodule:: sardana.tango.pool.OneDExpChannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`OneDExpChannel` * :class:`OneDExpChannelClass` OneDExpChannel ------------------ .. inheritance-diagram:: OneDExpChannel :parts: 1 .. autoclass:: OneDExpChannel :show-inheritance: :members: :undoc-members: OneDExpChannelClass ---------------------- .. inheritance-diagram:: OneDExpChannelClass :parts: 1 .. autoclass:: OneDExpChannelClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/Pool.rst0000644000234100017500000000103012174204300025565 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.Pool :mod:`~sardana.tango.pool.Pool` ========================================= .. automodule:: sardana.tango.pool.Pool .. rubric:: Classes .. hlist:: :columns: 3 * :class:`Pool` * :class:`PoolClass` Pool ------- .. inheritance-diagram:: Pool :parts: 1 .. autoclass:: Pool :show-inheritance: :members: :undoc-members: PoolClass ----------- .. inheritance-diagram:: PoolClass :parts: 1 .. autoclass:: PoolClass :show-inheritance: :members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/PoolDevice.rst0000644000234100017500000000304212174204300026712 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.PoolDevice :mod:`~sardana.tango.pool.PoolDevice` ============================================== .. automodule:: sardana.tango.pool.PoolDevice .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PoolDevice` * :class:`PoolDeviceClass` * :class:`PoolElementDevice` * :class:`PoolElementDeviceClass` * :class:`PoolGroupDevice` * :class:`PoolGroupDeviceClass` PoolDevice -------------- .. inheritance-diagram:: PoolDevice :parts: 1 .. autoclass:: PoolDevice :show-inheritance: :members: :undoc-members: PoolDeviceClass ------------------- .. inheritance-diagram:: PoolDeviceClass :parts: 1 .. autoclass:: PoolDeviceClass :show-inheritance: :members: :undoc-members: PoolElementDevice ------------------ .. inheritance-diagram:: PoolElementDevice :parts: 1 .. autoclass:: PoolElementDevice :show-inheritance: :members: :undoc-members: PoolElementDeviceClass ------------------------- .. inheritance-diagram:: PoolElementDeviceClass :parts: 1 .. autoclass:: PoolElementDeviceClass :show-inheritance: :members: :undoc-members: PoolGroupDevice ----------------- .. inheritance-diagram:: PoolGroupDevice :parts: 1 .. autoclass:: PoolGroupDevice :show-inheritance: :members: :undoc-members: PoolGroupDeviceClass --------------------- .. inheritance-diagram:: PoolGroupDeviceClass :parts: 1 .. autoclass:: PoolGroupDeviceClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/PseudoCounter.rst0000644000234100017500000000123512174204300027462 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.PseudoCounter :mod:`~sardana.tango.pool.PseudoCounter` ========================================= .. automodule:: sardana.tango.pool.PseudoCounter .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PseudoCounter` * :class:`PseudoCounterClass` PseudoCounter ------------- .. inheritance-diagram:: PseudoCounter :parts: 1 .. autoclass:: PseudoCounter :show-inheritance: :members: :undoc-members: PseudoCounterClass ------------------- .. inheritance-diagram:: PseudoCounterClass :parts: 1 .. autoclass:: PseudoCounterClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/PseudoMotor.rst0000644000234100017500000000120312174204300027136 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.PseudoMotor :mod:`~sardana.tango.pool.PseudoMotor` ========================================= .. automodule:: sardana.tango.pool.PseudoMotor .. rubric:: Classes .. hlist:: :columns: 3 * :class:`PseudoMotor` * :class:`PseudoMotorClass` PseudoMotor ------------ .. inheritance-diagram:: PseudoMotor :parts: 1 .. autoclass:: PseudoMotor :show-inheritance: :members: :undoc-members: PseudoMotorClass ---------------- .. inheritance-diagram:: PseudoMotorClass :parts: 1 .. autoclass:: PseudoMotorClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/TwoDExpChannel.rst0000644000234100017500000000126212174204300027506 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.TwoDExpChannel :mod:`~sardana.tango.pool.TwoDExpChannel` =========================================== .. automodule:: sardana.tango.pool.TwoDExpChannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`TwoDExpChannel` * :class:`TwoDExpChannelClass` TwoDExpChannel ------------------ .. inheritance-diagram:: TwoDExpChannel :parts: 1 .. autoclass:: TwoDExpChannel :show-inheritance: :members: :undoc-members: TwoDExpChannelClass ---------------------- .. inheritance-diagram:: TwoDExpChannelClass :parts: 1 .. autoclass:: TwoDExpChannelClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/pool/ZeroDExpChannel.rst0000644000234100017500000000127512174204300027660 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool.ZeroDExpChannel :mod:`~sardana.tango.pool.ZeroDExpChannel` =========================================== .. automodule:: sardana.tango.pool.ZeroDExpChannel .. rubric:: Classes .. hlist:: :columns: 3 * :class:`ZeroDExpChannel` * :class:`ZeroDExpChannelClass` ZeroDExpChannel ------------------ .. inheritance-diagram:: ZeroDExpChannel :parts: 1 .. autoclass:: ZeroDExpChannel :show-inheritance: :members: :undoc-members: ZeroDExpChannelClass ---------------------- .. inheritance-diagram:: ZeroDExpChannelClass :parts: 1 .. autoclass:: ZeroDExpChannelClass :show-inheritance: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango/core.rst0000644000234100017500000000034412174204300024642 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.core :mod:`~sardana.tango.core` ============================ .. automodule:: sardana.tango.core .. rubric:: Modules .. toctree:: :maxdepth: 1 SardanaDevice sardana-1.2.0/doc/source/devel/api/sardana/tango/pool.rst0000644000234100017500000000111412174204300024657 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango.pool :mod:`~sardana.tango.pool` ========================== .. automodule:: sardana.tango.pool .. rubric:: Modules .. toctree:: :maxdepth: 1 Pool PoolDevice Controller Motor I/O register Counter/Timer 0D experiment channel 1D experiment channel 2D experiment channel PseudoMotor PseudoCounter sardana-1.2.0/doc/source/devel/api/sardana/macroserver.rst0000644000234100017500000000124112174204301025130 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver :mod:`~sardana.macroserver` ============================ .. automodule:: sardana.macroserver .. rubric:: Modules .. toctree:: :maxdepth: 1 macros macroserver msbase mscontainer msdoor msenvmanager msexception msmacromanager msmanager msmetamacro msparameter mstypemanager sardana-1.2.0/doc/source/devel/api/sardana/pool.rst0000644000234100017500000000340212174204301023552 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool :mod:`~sardana.pool` ==================== .. automodule:: sardana.pool .. rubric:: Modules .. toctree:: :maxdepth: 1 controller pool poolacquisition poolaction poolbasechannel poolbaseobject poolcontainer poolcontroller poolcontrollermanager poolcountertimer pooldefs poolelement poolexception poolexternal poolgroupelement poolinstrument poolioregister poolmeasurementgroup poolmetacontroller poolmonitor poolmotion poolmotor poolmotorgroup poolmoveable poolobject poolonedexpchannel poolpseudocounter poolpseudomotor pooltwodexpchannel poolutil poolzerodexpchannel .. rubric:: Classes .. hlist:: :columns: 3 * :data:`~sardana.pool.controller.Controller` * :data:`~sardana.pool.controller.MotorController` * :data:`~sardana.pool.controller.CounterTimerController` * :data:`~sardana.pool.controller.PseudoMotorController` .. rubric:: Constants .. hlist:: :columns: 3 * :data:`~sardana.pool.pooldefs.ControllerAPI` sardana-1.2.0/doc/source/devel/api/sardana/sardana.rst0000644000234100017500000000110112174204301024204 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana :mod:`sardana` ============== .. automodule:: sardana .. rubric:: Packages .. toctree:: :maxdepth: 1 pool macroserver tango .. rubric:: Modules .. toctree:: :maxdepth: 1 sardanadefs sardanabase sardanacontainer sardanaevent sardanamodulemanager sardanameta sardanamanager sardanaattribute sardanavalue sardana-1.2.0/doc/source/devel/api/sardana/sardanaattribute.rst0000644000234100017500000000230312174204301026135 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanaattribute :mod:`~sardana.pool.sardanaattribute` ===================================== .. automodule:: sardana.sardanaattribute .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaAttribute` * :class:`SardanaSoftwareAttribute` * :class:`ScalarNumberAttribute` * :class:`SardanaAttributeConfiguration` SardanaAttribute ---------------- .. inheritance-diagram:: SardanaAttribute :parts: 1 .. autoclass:: SardanaAttribute :inherited-members: :members: :undoc-members: SardanaSoftwareAttribute ------------------------ .. inheritance-diagram:: SardanaSoftwareAttribute :parts: 1 .. autoclass:: SardanaSoftwareAttribute :inherited-members: :members: :undoc-members: ScalarNumberAttribute --------------------- .. inheritance-diagram:: ScalarNumberAttribute :parts: 1 .. autoclass:: ScalarNumberAttribute :inherited-members: :members: :undoc-members: SardanaAttributeConfiguration ----------------------------- .. inheritance-diagram:: SardanaAttributeConfiguration :parts: 1 .. autoclass:: SardanaAttributeConfiguration :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/sardanabase.rst0000644000234100017500000000117712174204301025054 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanabase :mod:`~sardana.pool.sardanabase` ===================================== .. automodule:: sardana.sardanabase .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaBaseObject` * :class:`SardanaObjectID` SardanaBaseObject ------------------ .. inheritance-diagram:: SardanaBaseObject :parts: 1 .. autoclass:: SardanaBaseObject :inherited-members: :members: :undoc-members: SardanaObjectID ------------------ .. inheritance-diagram:: SardanaObjectID :parts: 1 .. autoclass:: SardanaObjectID :inherited-members: :members: :undoc-members:sardana-1.2.0/doc/source/devel/api/sardana/sardanacontainer.rst0000644000234100017500000000066612174204301026126 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanacontainer :mod:`~sardana.pool.sardanacontainer` ===================================== .. automodule:: sardana.sardanacontainer .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaContainer` SardanaContainer ---------------- .. inheritance-diagram:: SardanaContainer :parts: 1 .. autoclass:: SardanaContainer :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/sardanadefs.rst0000644000234100017500000000267312174204301025065 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanadefs :mod:`~sardana.sardanadefs` ============================= .. automodule:: sardana.sardanadefs .. rubric:: Constants .. autodata:: sardana.sardanadefs.EpsilonError .. autodata:: sardana.sardanadefs.InvalidId .. autodata:: sardana.sardanadefs.InvalidAxis .. autodata:: sardana.sardanadefs.TYPE_ELEMENTS .. autodata:: sardana.sardanadefs.TYPE_GROUP_ELEMENTS .. autodata:: sardana.sardanadefs.TYPE_MOVEABLE_ELEMENTS .. autodata:: sardana.sardanadefs.TYPE_PHYSICAL_ELEMENTS .. autodata:: sardana.sardanadefs.TYPE_ACQUIRABLE_ELEMENTS .. autodata:: sardana.sardanadefs.TYPE_PSEUDO_ELEMENTS .. autodata:: sardana.sardanadefs.SardanaServer .. rubric:: Enumerations .. autodata:: sardana.sardanadefs.ServerRunMode .. autodata:: sardana.sardanadefs.State .. autodata:: sardana.sardanadefs.DataType .. autodata:: sardana.sardanadefs.DataFormat .. autodata:: sardana.sardanadefs.DataAccess .. autodata:: sardana.sardanadefs.ElementType .. autodata:: sardana.sardanadefs.Interface .. autodata:: sardana.sardanadefs.Interfaces .. autodata:: sardana.sardanadefs.InterfacesExpanded .. autodata:: sardana.sardanadefs.INTERFACES .. autodata:: sardana.sardanadefs.INTERFACES_EXPANDED .. rubric:: Functions .. autofunction:: sardana.sardanadefs.from_dtype_str .. autofunction:: sardana.sardanadefs.from_access_str .. autofunction:: sardana.sardanadefs.to_dtype_dformat .. autofunction:: sardana.sardanadefs.to_daccess sardana-1.2.0/doc/source/devel/api/sardana/sardanaevent.rst0000644000234100017500000000145712174204301025264 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanaevent :mod:`~sardana.pool.sardanaevent` ==================================== .. automodule:: sardana.sardanaevent .. rubric:: Classes .. hlist:: :columns: 3 * :class:`EventGenerator` * :class:`EventReceiver` * :class:`EventType` EventGenerator --------------- .. inheritance-diagram:: EventGenerator :parts: 1 .. autoclass:: EventGenerator :inherited-members: :members: :undoc-members: EventReceiver --------------- .. inheritance-diagram:: EventReceiver :parts: 1 .. autoclass:: EventReceiver :inherited-members: :members: :undoc-members: EventType --------------- .. inheritance-diagram:: EventType :parts: 1 .. autoclass:: EventType :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/sardanamanager.rst0000644000234100017500000000070312174204301025546 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanamanager :mod:`~sardana.pool.sardanamanager` ===================================== .. automodule:: sardana.sardanamanager .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaElementManager` SardanaElementManager ---------------------- .. inheritance-diagram:: SardanaElementManager :parts: 1 .. autoclass:: SardanaElementManager :inherited-members: :members: :undoc-members:sardana-1.2.0/doc/source/devel/api/sardana/sardanameta.rst0000644000234100017500000000114312174204301025061 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanameta :mod:`~sardana.pool.sardanameta` ==================================== .. automodule:: sardana.sardanameta .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaLibrary` * :class:`SardanaClass` SardanaLibrary --------------- .. inheritance-diagram:: SardanaLibrary :parts: 1 .. autoclass:: SardanaLibrary :inherited-members: :members: :undoc-members: SardanaClass ------------- .. inheritance-diagram:: SardanaClass :parts: 1 .. autoclass:: SardanaClass :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/sardanamodulemanager.rst0000644000234100017500000000066512174204301026763 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanamodulemanager :mod:`~sardana.pool.sardanamodulemanager` ========================================== .. automodule:: sardana.sardanamodulemanager .. rubric:: Classes .. hlist:: :columns: 3 * :class:`ModuleManager` ModuleManager --------------- .. inheritance-diagram:: ModuleManager :parts: 1 .. autoclass:: ModuleManager :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/sardanavalue.rst0000644000234100017500000000061412174204301025251 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.sardanavalue :mod:`~sardana.pool.sardanavalue` ================================= .. automodule:: sardana.sardanavalue .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaValue` SardanaValue ------------ .. inheritance-diagram:: SardanaValue :parts: 1 .. autoclass:: SardanaValue :inherited-members: :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/sardana/tango.rst0000644000234100017500000000033112174204301023707 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.tango :mod:`~sardana.tango` ============================ .. automodule:: sardana.tango .. rubric:: Modules .. toctree:: :maxdepth: 1 core pool sardana-1.2.0/doc/source/devel/api/api_0D.rst0000644000234100017500000000104512174204301022265 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolzerodexpchannel .. _sardana-0d-api: ============================= 0D channel API reference ============================= .. todo:: document 0D channel API reference .. seealso:: :ref:`sardana-0d-overview` the 0D experiment channel overview :class:`~sardana.tango.pool.ZeroDExpChannel.ZeroDExpChannel` the 0D experiment channel tango device :term:`API` .. :class:`~sardana.pool.poolzerodexpchannel.Pool0DExpChannel` .. the 0D experiment channel class :term:`API` sardana-1.2.0/doc/source/devel/api/api_1D.rst0000644000234100017500000000104112174204301022262 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolonedexpchannel .. _sardana-1d-api: ============================= 1D channel API reference ============================= .. todo:: document 1D channel API reference .. seealso:: :ref:`sardana-1d-overview` the 1D experiment channel overview :class:`~sardana.tango.pool.OneDExpChannel.OneDExpChannel` the 1D experiment channel tango device :term:`API` .. :class:`~sardana.pool.poolonedexpchannel.Pool1DExpChannel` .. the 1D experiment channel class :term:`API` sardana-1.2.0/doc/source/devel/api/api_2D.rst0000644000234100017500000000104112174204301022263 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.pooltwodexpchannel .. _sardana-2d-api: ============================= 2D channel API reference ============================= .. todo:: document 2D channel API reference .. seealso:: :ref:`sardana-2d-overview` the 2D experiment channel overview :class:`~sardana.tango.pool.TwoDExpChannel.TwoDExpChannel` the 2D experiment channel tango device :term:`API` .. :class:`~sardana.pool.pooltwodexpchannel.Pool2DExpChannel` .. the 2D experiment channel class :term:`API` sardana-1.2.0/doc/source/devel/api/api_IOR.rst0000644000234100017500000000077212174204301022461 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolioregister .. _sardana-ior-api: ============================= I/O register API reference ============================= .. todo:: document I/O register API reference .. seealso:: :ref:`sardana-ior-overview` the I/O register overview :class:`~sardana.tango.pool.IORegister.IORegister` the I/O register tango device :term:`API` .. :class:`~sardana.pool.poolioregister.PoolIORegister` .. the I/O register class :term:`API` sardana-1.2.0/doc/source/devel/api/api_controller.rst0000644000234100017500000000764012174204301024214 0ustar cpascualcpascual00000000000000 .. currentmodule:: sardana.pool.controller .. _sardana-controller-api: ======================== Controller API reference ======================== * :class:`Controller` - Base API for all controller types * :class:`MotorController` - Motor controller API * :class:`CounterTimerController` - Counter/Timer controller API * :class:`ZeroDController` - 0D controller API * :class:`PseudoMotorController` - PseudoMotor controller API * :class:`PseudoCounterController` - PseudoCounter controller API * :class:`IORegisterController` - IORegister controller API .. _sardana-controller-data-type: Data Type definition ---------------------- When writing a new controller you may need to specify extra attributes (per controller or/and per axis) as well as extra properties. This chapter describes how to describe the data type for each of this additional members. Controller data type definition has the following equivalences. This means you can use any of the given possibilities to describe a field data type. The possibilities are ordered by preference (example: usage of :obj:`int` is preferred to "int" or "PyTango.DevLong"): - for 0D data types: - **integer**: :obj:`int` | :data:`DataType.Integer ` | "int" | "integer" | "long" | :obj:`long` | [ "PyTango." ] "DevLong" - **double**: :obj:`float` | :data:`DataType.Double ` | "double" | "float" | [ "PyTango." ] "DevDouble" - **string**: :obj:`str` | :data:`DataType.String ` | "str" | "string" | [ "PyTango." ] "DevString" - **boolean**: :obj:`bool` | :data:`DataType.Boolean ` | "bool" | "boolean" | [ "PyTango." ] "DevBoolean" - for 1D data types: - **integer**: (:obj:`int`,) | (:data:`DataType.Integer `,) | ("int",) | ("integer",) | (:obj:`long`,) | ("long",) | [ "PyTango." ] "DevVarLongArray" | ([ "PyTango." ] "DevLong",) - **double**: (:obj:`float`,) | (:data:`DataType.Double `,) | ("double",) | ("float",) | [ "PyTango." ] "DevVarDoubleArray" | ([ "PyTango." ] "DevDouble",) - **string**: (:obj:`str`,) | (:data:`DataType.String `,) | ("str",) | ("string",) | [ "PyTango." ] "DevVarStringArray" | ([ "PyTango." ] "DevString",) - **boolean**: (:obj:`bool`,) | (:data:`DataType.Boolean `,) | ("bool",) | ("boolean",) | [ "PyTango." ] "DevVarBooleanArray" | ([ "PyTango." ] "DevBoolean",) .. deprecated:: 1.0 [ "PyTango." ] "Dev" types are considered deprecated. .. note:: when string, types are case insensitive. This means "long" is the same as "LONG" Here is an example on how to define extra attributes per axis: 1. EncoderSource: a scalar r/w string 2. ReflectionMatrix: a 2D readable float with customized getter method :: from sardana import State, DataAccess from sardana.pool.controller import MotorController, \ Type, Description, DefaultValue, Access, FGet, FSet class MyMotorCtrl(MotorController): axis_attributes = \ { 'EncoderSource' : { Type : str, Description : 'motor encoder source', }, 'ReflectionMatrix' : { Type : ( (float,), ), Access : DataAccess.ReadOnly, FGet : 'getReflectionMatrix', }, } def getAxisExtraPar(self, axis, name): name = name.lower() if name == 'encodersource': return self._encodersource[axis] def setAxisPar(self, axis, name, value): name = name.lower() if name == 'encodersource': self._encodersource[axis] = value def getReflectionMatrix(self, axis): return ( (1.0, 0.0), (0.0, 1.0) ) sardana-1.2.0/doc/source/devel/api/api_countertimer.rst0000644000234100017500000000103312174204301024537 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolcountertimer .. _sardana-countertimer-api: ============================= Counter/Timer API reference ============================= .. todo:: document Counter/Timer API reference .. seealso:: :ref:`sardana-countertimer-overview` the counter/timer overview :class:`~sardana.tango.pool.CTExpChannel.CTExpChannel` the counter/timer tango device :term:`API` .. :class:`~sardana.pool.poolcountertimer.PoolCounterTimer` .. the counter/timer class :term:`API` sardana-1.2.0/doc/source/devel/api/api_macro.rst0000644000234100017500000000074212174204301023126 0ustar cpascualcpascual00000000000000 .. currentmodule:: sardana.macroserver.macro .. _sardana-macro-api: =================== Macro API reference =================== Macro class ----------- .. autoclass:: Macro :members: :undoc-members: iMacro class ------------ .. autoclass:: iMacro :members: :undoc-members: macro decorator --------------- .. autoclass:: macro :members: :undoc-members: imacro decorator ---------------- .. autoclass:: imacro :members: :undoc-members: sardana-1.2.0/doc/source/devel/api/api_motor.rst0000644000234100017500000001540212174204301023164 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolmotor .. _sardana-motor-api: =================== Motor API reference =================== The motor is one of the most used elements in sardana. A motor represents anything that can be *changed* (and can potentially take some time to do it). This chapter explains the generic motor :term:`API` in the context of sardana. In sardana there are, in fact, two Motor :term:`API`\s. To better explain why, let's consider the case were sardana server is running as a Sardana Tango device server: .. image:: /_static/sardana_server_internal_motor.png :width: 680 :align: center Every motor in sardana is represented in the sardana kernel as a :class:`PoolMotor`. The :class:`PoolMotor` :term:`API` is not directly accessible from outside the sardana server. This is a low level :term:`API` that is only accessbile to someone writting a server extension to sardana. At the time of writting, the only available sardana server extension is Tango. The second motor interface consists on the one provided by the server extension, which is in this case the one provided by the Tango motor device interface: :class:`~sardana.tango.pool.Motor.Motor`. The Tango motor interface tries to mimic the as closely as possible the :class:`PoolMotor` :term:`API`. .. seealso:: :ref:`sardana-motor-overview` the motor overview :class:`~sardana.tango.pool.Motor.Motor` the motor tango device :term:`API` .. :class:`~sardana.pool.poolmotor.PoolMotor` .. the motor class :term:`API` A motor will have, at least, a ``state``, and a ``position``. The state indicates at any time if the motor is stopped, in alarm or moving. The position, indicates the current :term:`user position`. Unless a motor controller is specifically programmed not to, it's motors will also have: **limit switches** the three limit switches (home, upper and lower). Each switch is represented by a boolean value: False means inactive while True means active. low level :attr:`PoolMotor` API. high level Tango Motor API: limit_switches tango attribute **acceleration** motor acceleration (usually acceleration time in seconds, but it's up to the motor controller class to decide) :attr:`~PoolMotor.acceleration` **deceleration** motor deceleration (usually deceleration time in seconds, but it's up to the motor controller class to decide) :attr:`~PoolMotor.deceleration` **velocity** top velocity :attr:`~PoolMotor.velocity` **base rate** initial velocity :attr:`~PoolMotor.base_rate` **dial position** the :term:`dial position` :attr:`~PoolMotor.dial_position` **offset** the offset to be applied in the motor position computation [default: 0.0] :attr:`~PoolMotor.offset` **sign** the sign to be applied in the motor position computation [default: 1, possible values are (1, -1)] :attr:`~PoolMotor.sign` **Steps per unit** This is the number of motor steps per :term:`user position` [default: 1.0] :attr:`~PoolMotor.step_per_unit` **backlash** If this is defined to be something different than 0, the motor will always stop the motion coming from the same mechanical direction. This means that it could be possible to ask the motor to go a little bit after the desired position and then to return to the desired position. The value is the number of steps the motor will pass the desired position if it arrives from the "wrong" direction. This is a signed value. If the sign is positive, this means that the authorized direction to stop the motion is the increasing motor position direction. If the sign is negative, this means that the authorized direction to stop the motion is the decreasing motor position direction. :attr:`~PoolMotor.backlash` **instability_time** This property defines the time in milliseconds that the software managing a motor movement will wait between it detects the end of the motion and the last motor position reading. It is typically used for motors that move mechanics which have an instability time after each motion. :attr:`~PoolMotor.instability_time` The available operations are: start move absolute (:term:`user position`\) starts to move the motor to the given absolute user position :meth:`~PoolMotor.start_move` stop stops the motor in an orderly fashion abort stops the motor motion as fast as possible (possibly without deceleration time and loss of position) Motor state ----------- On a sardana tango server, the motor state can be obtained by reading the state attribute or by executing the state command. The diagram shows the internal sequence of calls. .. image:: /_static/sardana_server_internal_motor_read_state_flow.png :width: 680 :align: center Motor position -------------- The motor's current :term:`user position` can be obtained by reading the position attribute. The diagram shows the internal sequence of calls. .. image:: /_static/sardana_server_internal_motor_read_position_flow.png :width: 680 :align: center Motion ------ The most useful thing to do with a motor is, of course, to move it. To move a motor to another absolute :term:`user position` you have to write the value into the position attribute. .. image:: /_static/sardana_server_internal_motor_write_position_flow.png :width: 680 :align: center Before allowing a movement, some pre-conditions are automatically checked by tango (not represented in the diagram): - motor is in a proper state; - requested position is within the allowed motor boundaries (if defined) Then, the :term:`dial position` is calculated taking into account the *offset*, *signal* as well as a possible *backlash*. Afterward, and because the motor may be part of a pseudo motor system, other pre-conditions are checked: - is the final :term:`dial position` (including backlash) within the motor boundaries (if defined) - will the resulting motion end in an allowed position for all the pseudo motors that depend on this motor After all pre-conditions are checked, the motor will deploy a motion *job* into the sardana kernel engine which will trigger a series of calls to the underlying motor controller. The motor awaits for the :meth:`~sardana.pool.controller.Startable.PreStartOne` to signal that the motion will be possible to return successfully from the move request. The next diagram shows the state machine of a motor. .. graphviz:: motion.dot :alt: Basic motion diagram :caption: Basic motion diagram. The black state transitions are the ones which can be triggered by a *user*. For simplicity, only the most relevant states involved in a motor motion are shown. Error states are omited sardana-1.2.0/doc/source/devel/api/api_pseudocounter.rst0000644000234100017500000000104712174204301024723 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolpseudocounter .. _sardana-pseudocounter-api: ============================= Pseudo counter API reference ============================= .. todo:: document pseudo-counter API reference .. seealso:: :ref:`sardana-pseudocounter-overview` the pseudo-counter overview :class:`~sardana.tango.pool.PseudoCounter.PseudoCounter` the pseudo-counter tango device :term:`API` .. :class:`~sardana.pool.poolpseudocounter.PoolPseudoCounter` .. the pseudo-counter class :term:`API` sardana-1.2.0/doc/source/devel/api/api_pseudomotor.rst0000644000234100017500000000101712174204301024401 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.poolpseudomotor .. _sardana-pseudomotor-api: ============================= Pseudo motor API reference ============================= .. todo:: document pseudo-motor API reference .. seealso:: :ref:`sardana-pseudomotor-overview` the pseudo-motor overview :class:`~sardana.tango.pool.PseudoMotor.PseudoMotor` the pseudo-motor tango device :term:`API` .. :class:`~sardana.pool.poolpseudomotor.PoolPseudoMotor` .. the pseudo-motor class :term:`API` sardana-1.2.0/doc/source/devel/api/api_sardana.rst0000644000234100017500000000104712174204301023435 0ustar cpascualcpascual00000000000000 Sardana API =========== .. rubric:: APIs .. toctree:: :maxdepth: 1 Macro API Controller API Motor API I/O register Counter/timer API 0D experiment channel API 1D experiment channel API 2D experiment channel API Pseudo motor API Pseudo counter API Pool tango API Macro server tango API Library sardana-1.2.0/doc/source/devel/api/motion.dot0000644000234100017500000000331012174204301022451 0ustar cpascualcpascual00000000000000digraph "Motion" { fontsize="-" "On" [ fixedsize="false" regular="false" ]; "Moving" [ fixedsize="false" regular="false" ]; "On" -> "Moving" [ constraint="true" decorate="false" label="start" labelfloat="false" ]; "Moving" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_backlash" [ fixedsize="false" label="Moving\n(backlash)" regular="false" ]; "Moving" -> "Moving_backlash" [ constraint="true" decorate="false" fontcolor="green" label="finished" labelfloat="false" ]; "Moving_Instability_time" [ fixedsize="false" label="Moving\n(Instability time)" regular="false" ]; "Moving" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "Moving_backlash" -> "Moving_Instability_time" [ constraint="true" decorate="false" fontcolor="green" label="finished" labelfloat="false" ]; "Moving_backlash" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "Moving_backlash" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_backlash" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_Instability_time" -> "On" [ constraint="true" decorate="false" fontcolor="green" label="finished" labelfloat="false" ]; "Moving_Instability_time" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_Instability_time" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "On" -> "On" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "On" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; } sardana-1.2.0/doc/source/devel/api/motion_complete.dot0000644000234100017500000000463112174204301024350 0ustar cpascualcpascual00000000000000digraph "Motion" { fontsize="-" "On" [ fixedsize="false" regular="false" ]; "Moving" [ fixedsize="false" regular="false" ]; "On" -> "Moving" [ constraint="true" decorate="false" label="start" labelfloat="false" ]; "Moving" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_backlash" [ fixedsize="false" label="Moving\n(backlash)" regular="false" ]; "Moving" -> "Moving_backlash" [ constraint="true" decorate="false" fontcolor="green" label="finished" labelfloat="false" ]; "Moving_Instability_time" [ fixedsize="false" label="Moving\n(Instability time)" regular="false" ]; "Moving" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "Moving_backlash" -> "Moving_Instability_time" [ constraint="true" decorate="false" fontcolor="green" label="finished" labelfloat="false" ]; "Moving_backlash" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "Moving_backlash" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_backlash" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_Instability_time" -> "On" [ constraint="true" decorate="false" fontcolor="green" label="finished" labelfloat="false" ]; "Moving_Instability_time" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Moving_Instability_time" -> "Moving_Instability_time" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "On" -> "On" [ constraint="true" decorate="false" label="stop" labelfloat="false" ]; "On" -> "On" [ constraint="true" decorate="false" label="abort" labelfloat="false" ]; "Alarm" [ fixedsize="false" regular="false" ]; "Fault" [ fixedsize="false" regular="false" ]; "Moving" -> "Alarm" [ constraint="true" decorate="false" label="*" labelfloat="false" ]; "Moving" -> "Fault" [ constraint="true" decorate="false" label="*" labelfloat="false" ]; "Moving_backlash" -> "Alarm" [ constraint="true" decorate="false" label="*" labelfloat="false" ]; "Moving_backlash" -> "Fault" [ constraint="true" decorate="false" label="*" labelfloat="false" ]; "Alarm" -> "On" [ constraint="true" decorate="false" label="*" labelfloat="false" ]; "Fault" -> "On" [ constraint="true" decorate="false" labelfloat="false" ]; "Alarm" -> "Moving" [ constraint="true" decorate="false" label="start" labelfloat="false" ]; } sardana-1.2.0/doc/source/devel/api/tango_device_pool.rst0000644000234100017500000057056312174204301024671 0ustar cpascualcpascual00000000000000 ========================================== Device Pool Tango_ :term:`API` ========================================== .. todo:: Device Pool chapter is out of date. Need to update it and distribute chapters logically around the sardana documentation Introduction ============ This paper describes what could be the implementation of the Sardana device pool. This work is based on Jorg's paper called "Reordered SPEC_". It is **not at all** a final version of this device pool. It is rather a first approach to define this pool more precisely and to help defining its features and the way it could be implemented. Overall pool design =================== The pool could be seen as a kind of intelligent Tango_ device container to control the experiment hardware. In a first approach, it requires that the hardware to be controlled is connected to the control computer or to external crate(s) connected to the control computer using bus coupler. It has two basic features which are: 1. Hardware access using dynamically created/deleted Tango_ devices according to the experiment needs 2. Management of some very common and well defined action regularly done on a beam line (scanning, motor position archiving....) To achieve these two goals and to provide the user with a way to control its behavior, it is implemented as a Tango_ class with commands and attributes like any other Tango_ class. Hardware access --------------- Core hardware access ^^^^^^^^^^^^^^^^^^^^ Most of the times, it is possible to define a list of very common devices found in most of the experiments, a list of communication link used between the experiment hardware and the control computer(s) and some of the most commonly used protocol used on these communication links. Devices commonly used to drive an experiment are: - Motor - Group of motor - Pseudo motor - Counter/Timer - Multi Channel Analyzer - CCD cameras - And some other that I don't know Communication link used to drive experiment devices are: - Serial line - GPIB - Socket - And some other that I don't know (USB????) Protocol used on the communication links are: - Modbus - Ans some other that I don't know Each of the controlled hardware (one motor, one pseudo-motor, one serial line device,...) will be driven by independent Tango_ classes. The pool device server will embed all these Tango_ classes together (statically linked). The pool Tango_ device is the "container interface" and allows the user to create/delete classical Tango_ devices which are instances of these embedded classes. This is summarized in the following drawing. .. image:: /_static/hard.png Therefore, the three main actions to control a new equipment using the pool will be (assuming the equipment is connected to the control computer via a serial line): 1. Create the serial line Tango_ device with one of the Pool device command assigning it a name like "MyNewEquipment". 2. Connect to this newly created Tango_ device using its assigned name 3. Send order or write/read data to/from the new equipment using for instance the WriteRead command of the serial line Tango_ device When the experiment does not need this new equipment any more, the user can delete the serial line Tango_ device with another pool device command. Note that most of the time, creating Tango_ device means defining some device configuration parameters (Property in Tango_ language). The Tango_ wizard will be used to retrieve which properties have to be defined and will allow the user to set them on the fly. This means that all the Tango_ classes embedded within the Pool must have their wizard initialized. Extending pool features ^^^^^^^^^^^^^^^^^^^^^^^ From time to time, it could be useful to extend the list of Tango_ classes known by the device pool in case a new kind of equipment (not using the core hardware access) is added to the experiment. Starting with Tango_ 5.5 (and the associated Pogo), each Tango_ class has a method which allow the class to be dynamically loaded into a running process. This feature will be used to extend the pool feature. It has to be checked that it is possible for Tango_ Python class. .. image:: /_static/dyn.png To achieve this feature, the pool Tango_ device will have commands to - Load a Tango_ class. This command will dynamically add two other commands and one attribute to the pool device Tango_ interface. These commands and the attribute are: - Command: Create a device of the newly loaded class - Command: Delete a device of the newly loaded class - Attribute: Get the list of Tango_ devices instances of the newly created class - Unload a Tango_ class - Reload a Tango_ class Global actions -------------- The following common actions regularly done on a beam line experiment will be done by the pool device server: - Evaluating user constraint(s) before moving motor(s) - Scanning - Saving experiment data - Experiment management - Archiving motor positions Sardana core hardware access ============================ The Sardana Motor management ---------------------------- The user motor interface ^^^^^^^^^^^^^^^^^^^^^^^^ The motor interface is a first approach of what could be a complete motor interface. It is statically linked with the Pool device server and supports several attributes and commands. It is implemented in C++ and used a set of the so-called "controller" methods. The motor interface is always the same whatever the hardware is. This is the rule of the "controller" to access the hardware using the communication link supported by the motor controller hardware (network link, serial line...). .. image:: /_static/motor.png The controller code has a well-defined interface and can be written using Python or C++. In both cases, it will be dynamically loaded into the pool device server process. The states """""""""" The motor interface knows five states which are ON, MOVING, ALARM, FAULT and UNKNOWN. A motor device is in MOVING state when it is moving! It is in ALARM state when it has reached one of the limit switches and is in FAULT if its controller software is not available (impossible to load it) or if a fault is reported from the hardware controller. The motor is in the UNKNOWN state if an exception occurs during the communication between the pool and the hardware controller. When the motor is in ALARM state, its status will indicate which limit switches is active. The commands """""""""""" The motor interface supports 3 commands on top of the Tango_ classical Init, State and Status commands. These commands are summarized in the following table: ============ ================ ================ Command name Input data type Output data type ============ ================ ================ Abort void void SetPosition Tango::DevDouble void SaveConfig void void ============ ================ ================ - **Abort** : It aborts a running motion. This command does not have input or output argument. - **SetPosition** : Loads a position into controller. It has one input argument which is the new position value (a double). It is allowed only in the ON or ALARM states. The unit used for the command input value is the physical unit: millimeters or milli-radians. It is always an absolute position. - **SaveConfig** : Write some of the motor parameters in database. Today, it writes the motor acceleration, deceleration, base_rate and velocity into database as motor device properties. It is allowed only in the ON or ALARM states The classical Tango_ Init command destroys the motor and re-create it. The attributes """""""""""""" The motor interface supports several attributes which are summarized in the following table: ============== ================= =========== ======== ========= ========== Name Data type Data format Writable Memorized Ope/Expert ============== ================= =========== ======== ========= ========== Position Tango::DevDouble Scalar R/W No * Ope DialPosition Tango::DevDouble Scalar R No Exp Offset Tango::DevDouble Scalar R/W Yes Exp Acceleration Tango::DevDouble Scalar R/W No Exp Base_rate Tango::DevDouble Scalar R/W No Exp Deceleration Tango::DevDouble Scalar R/W No Exp Velocity Tango::DevDouble Scalar R/W No Exp Limit_Switches Tango::DevBoolean Spectrum R No Exp SimulationMode Tango::DevBoolean Scalar R No Exp Step_per_unit Tango::DevDouble Scalar R/W Yes Exp Backlash Tango::DevLong Scalar R/W Yes Exp ============== ================= =========== ======== ========= ========== - **Position** : This is read-write scalar double attribute. With the classical Tango min and max_value attribute properties, it is easy to define authorized limit for this attribute. See the definition of the DialPosition and Offset attributes to get a precise definition of the meaning of this attribute. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. It is also not possible to write this attribute when the motor is already MOVING. **The unit used for this attribute is the physical unit: millimeters or milli-radian. It is always an** **absolute** **position.** The value of this attribute is memorized in the Tango_ database but not by the default Tango_ system memorization. See chapter XXX: Unknown inset LatexCommand \ref{sub:Archiving-motor-position}: for details about motor position archiving. - **DialPosition** : This attribute is the motor dial position. The following formula links together the Position, DialPosition, Sign and Offset attributes: :: Position = Sign * DialPosition + Offset This allows to have the motor position centered around any position defined by the Offset attribute (classically the X ray beam position). It is a read only attribute. To set the motor position, the user has to use the Position attribute. It is not allowed to read this attribute when the motor is in FAULT or UNKNOWN mode. The unit used for this attribute is the physical unit: millimeters or milli-radian. It is also always an **absolute** position. - **Offset** : The offset to be applied in the motor position computation. By default set to 0. It is a memorized attribute. It is not allowed to read or write this attribute when the motor is in FAULT, MOVING or UNKNOWN mode. - **Acceleration** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Deceleration** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Base_rate** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Velocity** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Limit_Switches** : Three limit switches are managed by this attribute. Each of the switch are represented by a boolean value: False means inactive while True means active. It is a read only attribute. It is not possible to read this attribute when the motor is in UNKNOWN mode. It is a spectrum attribute with 3 values which are: - Data[0] : The Home switch value - Data[1] : The Upper switch value - Data[2] : The Lower switch value - **SimulationMode** : This is a read only scalar boolean attribute. When set, all motion requests are not forwarded to the software controller and then to the hardware. When set, the motor position is simulated and is immediately set to the value written by the user. To set this attribute, the user has to used the pool device Tango_ interface. The value of the position, acceleration, deceleration, base_rate, velocity and offset attributes are memorized at the moment this attribute is set. When this mode is turned off, if the value of any of the previously memorized attributes has changed, it is reapplied to the memorized value. It is not allowed to read this attribute when the motor is in FAULT or UNKNOWN states. - **Step_per_unit** : This is the number of motor step per millimeter or per degree. It is a memorized attribute. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN mode. It is also not allowed to write this attribute when the motor is MOVING. The default value is 1. - **Backlash** : If this attribute is defined to something different than 0, the motor will always stop the motion coming from the same mechanical direction. This means that it could be possible to ask the motor to go a little bit after the desired position and then to return to the desired position. The attribute value is the number of steps the motor will pass the desired position if it arrives from the "wrong" direction. This is a signed value. If the sign is positive, this means that the authorized direction to stop the motion is the increasing motor position direction. If the sign is negative, this means that the authorized direction to stop the motion is the decreasing motor position direction. It is a memorized attribute. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN mode. It is also not allowed to write this attribute when the motor is MOVING. Some hardware motor controllers are able to manage this backlash feature. If it is not the case, the motor interface will implement this behavior. All the motor devices will have the already described attributes but some hardware motor controller supports other features which are not covered by this list of pre-defined attributes. Using Tango_ dynamic attribute creation, a motor device may have extra attributes used to get/set the motor hardware controller specific features. The main characteristics of these extra attributes are : - Name defined by the motor controller software (See next chapter) - Data type is BOOLEAN, LONG, DOUBLE or STRING defined by the motor controller software (See next chapter) - The data format is always Scalar - The write type is READ or READ_WRITE defined by the motor controller software (See next chapter). If the write type is READ_WRITE, the attribute is memorized by the Tango_ layer The motor properties """""""""""""""""""" Each motor device has a set of properties. Five of these properties are automatically managed by the pool software and must not be changed by the user. These properties are named Motor_id, _Acceleration, _Velocity, _Base_rate and _Deceleration. The user properties are: ====================== ============= Property name Default value ====================== ============= Sleep_before_last_read 0 ====================== ============= This property defines the time in milli-second that the software managing a motor movement will wait between it detects the end of the motion and the last motor position reading. Getting motor state and limit switches using event """""""""""""""""""""""""""""""""""""""""""""""""" The simplest way to know if a motor is moving is to survey its state. If the motor is moving, its state will be MOVING. When the motion is over, its state will be back to ON (or ALARM if a limit switch has been reached). The pool motor interface allows client interested by motor state or motor limit switches value to use the Tango_ event system subscribing to motor state change event. As soon as a motor starts a motion, its state is changed to MOVING and an event is sent. As soon as the motion is over, the motor state is updated ans another event is sent. In the same way, as soon as a change in the limit switches value is detected, a change event is sent to client(s) which have subscribed to change event on the Limit_Switches attribute. Reading the motor position attribute """""""""""""""""""""""""""""""""""" For each motor, the key attribute is its position. Special care has been taken on this attribute management. When the motor is not moving, reading the Position attribute will generate calls to the controller and therefore hardware access. When the motor is moving, its position is automatically read every 100 milli-seconds and stored in the Tango polling buffer. This means that a client reading motor Position attribute while the motor is moving will get the position from the Tango_ polling buffer and will not generate extra controller calls. It is also possible to get a motor position using the Tango_ event system. When the motor is moving, an event is sent to the registered clients when the change event criterion is true. By default, this change event criterion is set to be a difference in position of 5. It is tunable on a motor basis using the classical motor Position attribute abs_change property or at the pool device basis using its DefaultMotPos_AbsChange property. Anyway, not more than 10 events could be sent by second. Once the motion is over, the motor position is made unavailable from the Tango_ polling buffer and is read a last time after a tunable waiting time (Sleep_bef_last_read property). A forced change event with this value is sent to clients using events. The Motor Controller ^^^^^^^^^^^^^^^^^^^^ XXX: Unknown inset LatexCommand \label{sub:The-Motor-Controller}: Each controller code is built as a shared library or as a Python module which is dynamically loaded by the pool device the first time one controller using the shared library (or the module) is created. Each controller is uniquely defined by its name following the syntax:: ./ At controller creation time, the pool checks the controller unicity on its control system (defined by the TANGO_HOST). It is possible to write controller using either C++ or Python language. Even if a Tango device server is a multi-threaded process, every access to the same controller will be serialized by a monitor managed by the Motor interface. This monitor is attached to the controller class and not to the controller instance to handle cases where several instances of the same controller class is used. For Python controller, this monitor will also take care of taking/releasing the Python Global Interpreter Lock (GIL) before any call to the Python controller is executed. The basic """"""""" For motor controller, a pre-defined set of methods has to be implemented in the class implementing the controller interface. These methods can be splitted in 6 different types which are: 1. Methods to create/remove motor 2. Methods to move motor(s) 3. Methods to read motor(s) position 4. Methods to get motor(s) state 5. Methods to configure a motor 6. Remaining methods. These methods, their rules and their execution sequencing is detailed in the following sub-chapters. The motor controller software layer is also used to inform the upper level of the features supported by the underlying hardware. This is called the controller **features** . It is detailed in a following sub-chapter. Some controller may need some configuration data. This will be supported using Tango properties. This is detailed in a dedicated sub-chapter. Specifying the motor controller features """""""""""""""""""""""""""""""""""""""" A controller feature is something that motor hardware controller is able to do or require on top of what has been qualified as the basic rules. Even if these features are common, not all the controllers implement them. Each of these common features are referenced by a pre- defined string. The controller code writer defined (from a pre-defined list) which of these features his hardware controller implements/requires. This list (a Python list or an array of C strings) has a well-defined name used by the upper layer software to retrieve it. The possible strings in this list are (case independent): - **CanDoBacklash** : The hardware controller manages the motor backlash if the user defines one - **WantRounding** : The hardware controller wants an integer number of step - **encoder** : The hardware knows how to deal with encoder - **home** : The hardware is able to manage home switch - **home_acceleration** : It is possible to set the acceleration for motor homing - **home_method** _ **xxx** : The hardware knows the home method called xxx - **home_method_yyy** : The hardware knows the home method called yyy The name of this list is simply: **ctrl_features** . If this list is not defined, this means that the hardware does not support/require any of the additional features. The Tango_ motor class will retrieve this list from the controller before the first motor belonging to this controller is created. As an example, we suppose that we have a pool with two classes of motor controller called Ctrl_A and Ctrl_B. The controllers features list are (in Python) :: Controller A : ctrl_features = ['CanDoBacklash','encoder'] ControllerB : ctrl_features = ['WantRounding','home','home_method_xxx'] All motors devices belonging to the controller A will have the Encoder and Backlash features. For these motors, the backlash will be done by the motor controller hardware. All the motors belonging to the controller B will have the rounding, home and home_method features. For these motors, the backlash will be done by the motor interface code. Specifying the motor controller extra attributes """""""""""""""""""""""""""""""""""""""""""""""" XXX: Unknown inset LatexCommand \label{par:Specifying-the-motor}: Some of the hardware motor controller will have features not defined in the features list or not accessible with a pre-defined feature. To provide an interface to these specific hardware features, the controller code can define extra attributes. Another list called : **ctrl_extra_attributes** is used to define them. This list (Python dictionary or an array of classical C strings) is used to define the name, data and read-write type of the Tango_ attribute which will be created to deal with these extra features. The attribute created for these controller extra features are all: - Boolean, Long, Double or String - Scalar - Read or Read/Write (and memorized if Read/Write). For Python classes (Python controller class), it is possible to define these extra attributes informations using a Python dictionary called **ctrl_extra** _ **attributes** . The extra attribute name is the dictionary element key. The dictionary element value is another dictionary with two members which are the extra attribute data type and the extra attribute read/write type. For instance, for our IcePap controller, this dictionary to defined one extra attribute called "SuperExtra" of data type Double which is also R/W will be:: ctrl_extra_attributes = { "SuperExtra" : { "Type" : "DevDouble", "R/W Type", "READ_WRITE" } } For C++ controller class, the extra attributes are defined within an array of **Controller::ExtraAttrInfo** structures. The name of this array has to be _ctrl_extra_attributes. Each Controller::ExtraAttrInfo structure has three elements which are all pointers to classical C string (const char \*). These elements are: 1. The extra attribute name 2. The extra attribute data type 3. The extra attribute R/W type A NULL pointer defined the last extra attribute. The following is an example of extra attribute definition for a controller class called "DummyController":: Controller::ExtraAttrInfo DummyController_ctrl_extra_attributes[] = { { "SuperExtra", "DevDouble", "Read_Write" }, NULL }; The string describing the extra attribute data type may have the following value (case independent): - DevBoolean, DevLong, DevDouble or DevString (in Python, a preceding "PyTango." is allowed) The string describing the extra attribute R/W type may have the following value (case independent) - Read or Read_Write (in Python, a preceding "PyTango." is allowed) Methods to create/remove motor from controller """""""""""""""""""""""""""""""""""""""""""""" Two methods are called when creating or removing motor from a controller. These methods are called **AddDevice** and **DeleteDevice** . The AddDevice method is called when a new motor belonging to the controller is created within the pool. The DeleteDevice method is called when a motor belonging to the controller is removed from the pool. Methods to move motor(s) """""""""""""""""""""""" Four methods are used when a request to move motor(s) is executed. These methods are called **PreStartAll** , **PreStartOne** , **StartOne** and **StartAll** . The algorithm used to move one or several motors is the following:: /FOR/ Each controller(s) implied in the motion - Call PreStartAll() /END FOR/ /FOR/ Each motor(s) implied in the motion - ret = PreStartOne(motor to move, new position) - /IF/ ret is true - Call StartOne(motor to move, new position) - /END IF/ /END FOR/ /FOR/ Each controller(s) implied in the motion - Call StartAll() /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ ================================= ======================================= ================================= PresStartAll() PreStartOne() StartOne() StartAll() ==================== ================================ ================================= ======================================= ================================= Default action Does nothing Return true Does nothing Does nothing Externally called by Writing the Position attribute Writing the Position attribute Writing the Position attribute Writing the Position attribute Internally called Once for each implied controller For each implied motor For each implied motor Once for each implied controller Typical rule Init internal data for motion Check if motor motion is possible Set new motor position in internal data Send order to physical controller ==================== ================================ ================================= ======================================= ================================= This algorithm covers the sophisticated case where a physical controller is able to move several motors at the same time. For some simpler controller, it is possible to implement only the StartOne() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Methods to read motor(s) position """"""""""""""""""""""""""""""""" Four methods are used when a request to read motor(s) position is received. These methods are called PreReadAll, PreReadOne, ReadAll and ReadOne. The algorithm used to read position of one or several motors is the following:: /FOR/ Each controller(s) implied in the reading - Call PreReadAll() /END FOR/ /FOR/ Each motor(s) implied in the reading - PreReadOne(motor to read) /END FOR/ /FOR/ Each controller(s) implied in the reading - Call ReadAll() /END FOR/ /FOR/ Each motor(s) implied in the reading - Call ReadOne(motor to read) /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ =================================== ================================= ================================================================= PreReadAll() PreReadOne() ReadAll() ReadOne() ==================== ================================ =================================== ================================= ================================================================= Default action Does nothing Does nothing Does nothing Print message on the screen and returns NaN. Mandatory for Python Externally called by Reading the Position attribute Reading the Position attribute Reading the Position attribute Reading the Position attribute Internally called Once for each implied controller For each implied motor For each implied controller Once for each implied motor Typical rule Init internal data for reading Memorize which motor has to be read Send order to physical controller Return motor position from internal data ==================== ================================ =================================== ================================= ================================================================= This algorithm covers the sophisticated case where a physical controller is able to read several motors positions at the same time. For some simpler controller, it is possible to implement only the ReadOne() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Methods to get motor(s) state """"""""""""""""""""""""""""" XXX: Unknown inset LatexCommand \label{par:Methods-to-get-state}: Four methods are used when a request to get motor(s) state is received. These methods are called PreStateAll, PreStateOne, StateAll and StateOne. The algorithm used to get state of one or several motors is the following : :: /FOR/ Each controller(s) implied in the state getting - Call PreStateAll() /END FOR/ /FOR/ Each motor(s) implied in the state getting - PreStateOne(motor to get state) /END FOR/ /FOR/ Each controller(s) implied in the state getting - Call StateAll() /END FOR/ /FOR/ Each motor(s) implied in the getting state - Call StateOne(motor to get state) /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ =================================== ================================= ===================================== PreStateAll() PreStateOne() StateAll() StateOne() ==================== ================================ =================================== ================================= ===================================== Default action Does nothing Does nothing Does nothing Mandatory for Python Externally called by Reading the motor state Reading the motor state Reading the motor state Reading the motor state Internally called Once for each implied controller For each implied motor For each implied controller Once for each implied motor Typical rule Init internal data for reading Memorize which motor has to be read Send order to physical controller Return motor state from internal data ==================== ================================ =================================== ================================= ===================================== This algorithm covers the sophisticated case where a physical controller is able to read several motors state at the same time. For some simpler controller, it is possible to implement only the StateOne() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Methods to configure a motor """""""""""""""""""""""""""" The rule of these methods is to - Get or Set motor parameter(s) with methods called GetPar() or SetPar() - Get or Set motor extra feature(s) parameter with methods called GetExtraAttributePar() or SetExtraAttributePar() The following table summarizes the usage of these methods: ========= ============================================================================================== ============================================================================================================ ================================================= ===================================================== GetPar() SetPar() GetExtraAttributePar() SetExtraAttributePar() ========= ============================================================================================== ============================================================================================================ ================================================= ===================================================== Called by Reading the Velocity, Acceleration, Base_rate, Deceleration and eventually Backlash attributes Writing the Velocity, Acceleration, Base_rate, Deceleration, Step_per_unit and eventually Backlash attribute Reading any of the extra attributes Writing any of the extra attributes Rule Get parameter from physical controller Set parameter in physical controller Get extra attribute value from the physical layer Set additional attribute value in physical controller ========= ============================================================================================== ============================================================================================================ ================================================= ===================================================== Please, note that the default implementation of the GetPar() prints a message on the screen and returns a NaN double value. The GetExtraAttributePar() default implementation also prints a message on the screen and returns a string set to "Pool_met_not_implemented". The remaining methods """"""""""""""""""""" The rule of the remaining methods are to - Load a new motor position in a controller with a method called DefinePosition() - Abort a running motion with a method called AbortOne() - Send a raw string to the controller with a method called SendToCtrl() The following table summarizes the usage of these methods: ========= ======================================= ======================= ========================================================================= DefinePosition() AbortOne() SendToCtrl() ========= ======================================= ======================= ========================================================================= Called by The motor SetPosition command The motor Abort command The Pool SendToController command Rule Load a new motor position in controller Abort a running motion Send the input string to the controller and returns the controller answer ========= ======================================= ======================= ========================================================================= Controller properties """"""""""""""""""""" XXX: Unknown inset LatexCommand \label{par:Controller-properties}: Each controller may have a set of **properties** to configure itself. Properties are defined at the controller class level but can be re-defined at the instance level. It is also possible to define a property default value. These default values are stored within the controller class code. If a default value is not adapted to specific object instance, it is possible to define a new property value which will be stored in the Tango_ database. Tango_ database allows storing data which are not Tango_ device property. This storage could be seen simply as a couple name/value. Naming convention for this kind of storage could be defined as: controller_class->prop: value or controller_class/instance->prop: value The calls necessary to retrieve/insert/update these values from/to the database already exist in the Tango_ core. The algorithm used to retrieve a property value is the following:: - Property value = Not defined /IF/ Property has a default value - Property value = default value /ENDIF/ /IF/ Property has a value defined in db at class level - Property value = class db value /ENDIF/ /IF/ Property has a value defined in db at instance level - Property value = instance db value /ENDIF/ /IF/ Property still not defined - Error /ENDIF/ As an example, the following array summarizes the result of this algorithm. The example is for an IcePap controller and the property is the port number (called port_number): ============== ====== ====== ====== ====== ====== case 1 case 2 case 3 case 4 case 5 ============== ====== ====== ====== ====== ====== default value 5000 5000 5000 5000 class in DB 5150 5150 inst. in DB 5200 5250 Property value 5000 5200 5150 5250 Error ============== ====== ====== ====== ====== ====== - Case 1: The IcePap controller class defines one property called port_number and assigns it a default value of 5000 - Case 2 : An IcePap controller is created with an instance name "My_IcePap". The property IcePap/My_IcePap->port_number has been set to 5200 in db - Case 3: The hard coded value of 5000 for port number does not fulfill the need. A property called IcePap->port_number set to 5150 is defined in db. - Case 4: We have one instance of IcePap called "My_IcePap" for which we have defined a property "IcePap/My_IcePap" set to 5250. - Case 5: The IcePap controller has not defined a default value for the property. In order to provide the user with a friendly interface, all the properties defined for a controller class have to have informations hard-coded into the controller class code. We need at least three informations and sometimes four for each property. They are: 1. The property name (Mandatory) 2. The property description (Mandatory) 3. The property data type (Mandatory) 4. The property default value (Optional) With these informations, a graphical user interface is able to build at controller creation time a panel with the list of all the needed properties, their descriptions and eventually their default value. The user then have the possibility to re-define property value if the default one is not valid for his usage. This is the rule of the graphical panel to store the new value into the Tango_ database. The supported data type for controller property are: ================== ==================================== Property data type String to use in property definition ================== ==================================== Boolean DevBoolean Long DevLong Double DevDouble String DevString Boolean array DevVarBooleanArray Long array DevVarLongArray Double array DevVarDoubleArray String array DevVarStringArray ================== ==================================== For Python classes (Python controller class), it is possible to define these properties informations using a Python dictionary called **class_prop** . The property name is the dictionary element key. The dictionary element value is another dictionary with two or three members which are the property data type, the property description and an optional default value. If the data type is an array, the default value has to be defined in a Python list or tuple. For instance, for our IcePap port number property, this dictionary will be :: class_prop = { "port_number" : { "Type" : "DevLong", "Description", "Port on which the IcePap software server is listening", "DefaultValue" : 5000 } } For C++ controller class, the properties are defined within an array of **Controller::PropInfo** structures. The name of this array has to be _class_prop. Each Controller::PropInfo structure has four elements which are all pointers to classical C string (const char \*). These elements are: 1. The property name 2. The property description 3. The property data type 4. The property default value (NULL if not used) A NULL pointer defined the last property. The following is an example of property definition for a controller class called "DummyController":: Controller::PropInfo DummyController_class_prop[] = {{"The prop","The first CPP property","DevLong","12"}, {"Another_Prop","The second CPP property","DevString",NULL}, {"Third_Prop","The third CPP property","DevVarLongArray","11,22,33"}, NULL}; The value of these properties is passed to the controller at controller instance creation time using a constructor parameter. In Python, this parameter is a dictionnary and the base class of the controller class will create one object attribute for each property. In our Python example, the controller will have an attribute called "port_number" with its value set to 5000. In C++, the controller contructor receives a vector of **Controller::Properties** structure. Each Controller::Properties structure has two elements which are: 1. The property name as a C++ string 2. The property value in a **PropData** structure. This PropData structure has four elements which are 1. A C++ vector of C++ bool type 2. A C++ vector of C++ long type 3. A C++ vector of C++ double type 4. A C++ vector of C++ string. Only the vector corresponding to the property data type has a size different than 0. If the property is an array, the vector has as many elements as the property has. The MaxDevice property """""""""""""""""""""" Each controller has to have a property defining the maximum number of device it supports. This is a mandatory requirement. Therefore, in Python this property is simply defined by setting the value of a controller data member called **MaxDevice** which will be taken as the default value for the controller. In C++, you have to define a global variable called _MaxDevice. The management of the number of devices created using a controller (limited by this property) will be completely done by the pool software. The information related to this property is automatically added as first element in the information passed to the controller at creation time. The following is an example of the definition of this MaxDevice property in C++ for a controller class called "DummyController" :: long DummyController_MaxDevice = 16; C++ controller """""""""""""" For C++, the controller code is implemented as a set of classes: A base class called **Controller** and a class called **MotorController** which inherits from Controller. Finally, the user has to write its controller class which inherits from MotorController. XXX: Unknown layout Subparagraph: The Controller class XXX: XXX: Unknown inset LatexCommand \label{sub:The-Cpp-Controller-class}: This class defined two pure virtual methods, seven virtual methods and some data types. The methods defined in this class are: 1. void **Controller::AddDevice** (long axe_number) Pure virtual 2. void **Controller::DeleteDevice** (long axe_number) Pure virtual 3. void **Controller::PreStateAll** () The default implementation does nothing 4. void **Controller::PreStateOne** (long idx_number) The default implementation does nothing. The parameter is the device index in the controller 5. void **Controller::StateAll** () The default implementation does nothing 6. void **Controller::StateOne** (long idx_number,CtrlState \*ptr) Read a device state. The CtrlState data type is a structure with two elements which are: - A long dedicated to return device state (format ??) - A string used in case the motor is in FAULT and the controller is able to return a string describing the fault. 7. string **Controller::SendToCtrl** (string in_string) Send the input string to the controller without interpreting it and returns the controller answer 8. Controller::CtrlData **Controller::GetExtraAttributePar** (long idx_number,string &extra_attribute_name) Get device extra attribute value. The name of the extra attribute is passed as the second argument of the method. The default definition of this method prints a message on the screen and returns a string set to "Pool_meth_not_implemented". The CtrlData data type is a structure with the following elements 1. A data type enumeration called data_type describing which of the following element is valid (BOOLEAN, LONG, DOUBLE or STRING) 2. A boolean data called bo_data for boolean transfer 3. A long data called lo_data for long transfer 4. A double data called db_data for double transfer 5. A C++ string data called str_data for string transfer 9. void **Controller::SetExtraAttributePar** (long idx_number, string &extra_attribute_name, Controller::CtrlData &extra_attribute_value) Set device extra attribute value. It also has one data member which is the controller instance name with one method to return it 1. string & **Controller::get_name** (): Returns the controller instance name XXX: Unknown layout Subparagraph: The MotorController class This class defined twelve virtual methods with default implementation. The virtual methods declared in this class are: 1. void **MotorController::PreStartAll** () The default implementation does nothing. 2. bool **MotorController::PreStartOne** (long axe_number, double wanted_position) The default implementation returns True. 3. void **MotorController::StartOne** (long axe_number, double wanted_position) The default implementation does nothing. 4. void **MotorController::StartAll** () Start the motion. The default implementation does nothing. 5. void **MotorController::PreReadAll** () The default implementation does nothing. 6. void **MotorController::PreReadOne** (long axe_number) The default implementation does nothing. 7. void **MotorController::ReadAll** () The default implementation does nothing. 8. double **MotorController::ReadOne** (long axe_number) Read a position. The default implementation does nothing. 9. void **MotorController::AbortOne** (long axe_number) Abort a motion. The default implementation does nothing. 10. void **MotorController::DefinePosition** (long axe_number, double new_position) Load a new position. The default implementation does nothing. 11. Controller::CtrlData **MotorController::GetPar** (long axe_number, string &par_name) Get motor parameter value. The CtrlData data type is a structure with the following elements 1. A data type enumeration called data_type describing which of the following element is valid (BOOLEAN, LONG, DOUBLE or STRING) 2. A boolean data called bo_data for boolean transfer 3. A long data called lo_data for long transfer 4. A double data called db_data for double transfer 5. A C++ string data called str_data for string transfer A motor controller has to handle four or five different possible values for the "par_name" parameter which are: - Acceleration - Deceleration - Velocity - Base_rate - Backlash which has to be handled only for controller which has the backlash feature The default definition of this method prints a message on the screen and returns a NaN double value. 12. void **MotorController::SetPar** (long axe_number, string &par_name, Controller::CtrlData &par_value) Set motor parameter value. The default implementation does nothing. A motor controller has to handle five or six different value for the "par_name" parameter which are: - Acceleration - Deceleration - Velocity - Base_rate - Step_per_unit - Backlash which has to be handled only for controller which has the backlash feature The description of the CtrlData type is given in the documentation of the GetPar() method. The default definition of this method does nothing This class has only one constructor which is 1. **MotorController::MotorController** (const char \*) Constructor of the MotorController class with the controller name as instance name Please, note that this class defines a structure called MotorState which inherits from the Controller::CtrlState and which has a data member: 1. A long describing the motor limit switches state (bit 0 for the Home switch, bit 1 for Upper Limit switch and bit 2 for the Lower Limit switch) This structure is used in the StateOne() method. XXX: Unknown layout Subparagraph: The user controller class XXX: XXX: Unknown inset LatexCommand \label{par:The-user-controller}: The user has to implement the remaining pure virtual methods (AddDevice and DeleteDevice) and has to re-define virtual methods if the default implementation does not cover his needs. The controller code has to define two global variables which are: 1. **Motor_Ctrl_class_name** (for Motor controller). This is an array of classical C strings terminated by a NULL pointer. Each array element is the name of a Motor controller class defined in this file. 2. **_MaxDevice** . This variable is a long defining the maximum number of device that the controller hardware can support. On top of that, a controller code has to define a C function (defined as "extern C") which is called by the pool to create instance(s) of the controller class. This function has the following definition:: Controller * **_create_** (const char \*ctrl_instance_name,vector &props) For instance, for a controller class called DummyController, the name of this function has to be: _create_DummyController(). The parameters passed to this function are: 1. The forth parameter given to the pool during the CreateController command (the instance name). 2. A reference to a C++ vector with controller properties as defined in XXX: Unknown inset LatexCommand \ref{par:Controller-properties}: The rule of this C function is to create one instance of the user controller class passing it the arguments it has received. The following is an example of these definitions :: // // Methods of the DummyController controller // .... const char *Motor_Ctrl_class_name[] = {"DummyController",NULL}; long DummyController_MaxDevice = 16; extern "C" { Controller *_create_DummyController(const char *inst,vector &prop) { return new DummyController(inst,prop); } } On top of these mandatory definitions, you can define a controller documentation string, controller properties, controller features and controller extra features. The documentation string is the first element of the array returned by the Pool device GetControllerInfo command as detailed in XXX: Unknown inset LatexCommand \ref{ite:GetControllerInfo:}: . It has to be defined as a classical C string (const char \*) with a name like _doc. The following is an example of a controller C++ code defining all these elements. :: // // Methods of the DummyController controller // .... const char *Motor_Ctrl_class_name[] = {"DummyController",NULL}; const char *DummyController_doc = "This is the C++ controller for the DummyController class"; long DummyController_MaxDevice = 16; char *DummyController_ctrl_extra_features_list[] = {{"Extra_1","DevLong","Read_Write"}, {"Super_2","DevString","Read"}, NULL}; char *DummyController_ctrl_features[] = {"WantRounding","CanDoBacklash",NULL}; Controller::PropInfo DummyController_class_prop[] = {{"The prop","The first CPP property","DevLong","12"}, {"Another_Prop","The second CPP property","DevString",NULL}, {"Third_Prop","The third CPP property","DevVarLongArray","11,22,33"}, NULL}; extern "C" { Controller *_create_DummyController(const char *inst,vector &prop) { return new DummyController(inst,prop); } } Python controller """"""""""""""""" The principle is exactly the same than the one used for C++ controller but we don't have pure virtual methods with a compiler checking if they are defined at compile time. Therefore, it is the pool software which checks that the following methods are defined within the controller class when the controller module is loaded (imported): - AddDevice - DeleteDevice - StartOne or StartAll method - ReadOne method - StateOne method With Python controller, there is no need for function to create controller class instance. With the help of the Python C API, the pool device is able to create the needed instances. Note that the StateOne() method does not have the same signature for Python controller. 1. tuple **Stat** e **One** (self,axe_number) Get a motor state. The method has to return a tuple with two or three elements which are: 1. The motor state (as defined by Tango) 2. The limit switch state (integer with bit 0 for Home switch, bit 1 for Upper switch and bit 2 for Lower switch) 3. A string describing the motor fault if the controller has this feature. A Python controller class has to inherit from a class called **MotorController** . This does not add any feature but allow the pool software to realize that this class is a motor controller. Python controller examples """""""""""""""""""""""""" XXX: Unknown layout Subparagraph: A minimum controller code The following is an example of the minimum code structure needed to write a Python controller : :: 1 import socket 2 import PyTango 3 import MotorController 4 5 class MinController(MotorController.MotorController): 6 7 # 8 # Some controller definitions 9 # 10 11 MaxDevice = 1 12 13 # 14 # Controller methods 15 # 16 17 def __init__(self,inst,props): 18 MotorController.MotorController.__init__(self,inst,props) 19 self.inst_name = inst 20 self.socket_connected = False 21 self.host = "the_host" 22 self.port = 1111 23 24 # 25 # Connect to the icepap 26 # 27 28 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 29 self.sock.connect(self.host, self.port) 30 self.socket_connected = True 31 32 print "PYTHON -> Connected to", self.host, " on port", self.port 33 34 35 def AddDevice(self,axis): 36 print "PYTHON -> MinController/",self.inst_name,": In AddDevice method for axis",axis 37 38 def DeleteDevice(self,axis): 39 print "PYTHON -> MinController/",self.inst_name,": In DeleteDevice method for axis",axis 40 41 def StateOne(self,axis): 42 print "PYTHON -> MinController/",self.inst_name,": In StateOne method for axis",axis 43 tup = (PyTango.DevState.ON,0) 44 return tup 45 46 def ReadOne(self,axis): 47 print "PYTHON -> MinController/",self.inst_name,": In ReadOne method for axis",axis 48 self.sock.send("Read motor position") 49 pos = self.sock.recv(1024) 50 return pos 51 52 def StartOne(self,axis,pos): 53 print "PYTHON -> MinController/",self.inst_name,": In StartOne method for axis",axis," with pos",pos 54 self.sock.send("Send motor to position pos") Line 11: Definition of the mandatory MaxDevice property set to 1 in this minimum code Line 17-32: The IcePapController constructor code Line 35-36: The AddDevice method Line 38-39: The DeleteDevice method Line 41-44: The StateOne method Line 46-50: The ReadOne method reading motor position from the hardware controller Line 52-54: The StartOne method writing motor position at position pos XXX: Unknown layout Subparagraph: A full features controller code The following is an example of the code structure needed to write a full features Python controller : :: 1 import socket 2 import PyTango 3 import MotorController 4 5 class IcePapController(MotorController.MotorController) 6 "This is an example of a Python motor controller class" 7 # 8 # Some controller definitions 9 # 10 11 MaxDevice = 128 12 ctrl_features = ['CanDoBacklash'] 13 ctrl_extra_attributes = {'IceAttribute':{'Type':'DevLong','R/W Type':'READ_WRITE'}} 14 class_prop = {'host':{'Type':'DevString','Description':"The IcePap controller 15 host name",'DefaultValue':"IcePapHost"}, 16 'port':{'Type':'DevLong','Description':"The port on which the 17 IcePap software is listenning",'DefaultValue':5000}} 18 19 # 20 # Controller methods 21 # 22 23 def __init__(self,inst,props): 24 MotorController.MotorController.__init__(self,inst,props) 25 self.inst_name = inst 26 self.socket_connected = False 27 28 # 29 # Connect to the icepap 30 # 31 32 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 33 self.sock.connect(self.host, self.port) 34 self.socket_connected = True 35 36 print "PYTHON -> Connected to", self.host, " on port", self.port 37 38 39 def AddDevice(self,axis): 40 print "PYTHON -> IcePapController/",self.inst_name,": In AddDevice method for axis",axis 41 42 def DeleteDevice(self,axis): 43 print "PYTHON -> IcePapController/",self.inst_name,": In DeleteDevice method for axis",axis 44 45 def PreReadAll(self): 46 print "PYTHON -> IcePapController/",self.inst_name,": In PreReadAll method" 47 self.read_pos = [] 48 self.motor_to_read = [] 49 50 def PreReadOne(self,axis): 51 print "PYTHON -> IcePapController/",self.inst_name,": In PreReadOne method for axis",axis 52 self.motor_to_read.append(axis) 53 54 def ReadAll(self): 55 print "PYTHON -> IcePapController/",self.inst_name,": In ReadAll method" 56 self.sock.send("Read motors in the motor_to_read list") 57 self.read_pos = self.sock.recv(1024) 58 59 def ReadOne(self,axis): 60 print "PYTHON -> IcePapController/",self.inst_name,": In ReadOne method for axis",axis 61 return read_pos[axis] 62 63 def PreStartAll(self): 64 print "PYTHON -> IcePapController/",self.inst_name,": In PreStartAll method" 65 self.write_pos = [] 66 self.motor_to_write = [] 67 68 def PreStartOne(self,axis,pos): 69 print "PYTHON -> IcePapController/",self.inst_name,": In PreStartOne method for axis",axis," with pos",pos 70 return True 71 72 def StartOne(self,axis,pos): 73 print "PYTHON -> IcePapController/",self.inst_name,": In StartOne method for axis",axis," with pos",pos 74 self.write_pos.append(pos) 75 self.motor_to_write(axis) 76 77 def StartAll(self): 78 print "PYTHON -> IcePapController/",self.inst_name,": In StartAll method" 79 self.sock.send("Write motors in the motor_to_write list at position in the write_pos list" 80 81 def PreStateAll(self): 82 print "PYTHON -> IcePapController/",self.inst_name,": In PreStateAll method" 83 self.read_state = [] 84 self.motor_to_get_state = [] 85 86 def PreStateOne(self,axis): 87 print "PYTHON -> IcePapController/",self.inst_name,": In PreStateOne method for axis",axis 88 self.motor_to_get_state.append(axis) 89 90 def StateAll(self): 91 print "PYTHON -> IcePapController/",self.inst_name,": In StateAll method" 92 self.sock.send("Read motors state for motor(s) in the motor_to_get_state list") 93 self.read_state = self.sock.recv(1024) 94 95 def StateOne(self,axis): 96 print "PYTHON -> IcePapController/",self.inst_name,": In StateOne method for axis",axis 97 one_state = [read_state[axis]] 98 return one_state 99 100 def SetPar(self,axis,name,value): 101 if name == 'Acceleration' 102 print "Setting acceleration to",value 103 elif name == 'Deceleration' 104 print "Setting deceleartion to",value 105 elif name == 'Velocity' 106 print "Setting velocity to",value 107 elif name == 'Base_rate' 108 print "Setting base_rate to",value 109 elif name == 'Step_per_unit' 110 print "Setting step_per_unit to",value 111 elif name == 'Backlash' 112 print "Setting backlash to",value 113 114 def GetPar(self,axis,name): 115 ret_val = 0.0 116 if name == 'Acceleration' 117 print "Getting acceleration" 118 ret_val = 12.34 119 elif name == 'Deceleration' 120 print "Getting deceleration" 121 ret_val = 13.34 122 elif name == 'Velocity' 123 print "Getting velocity" 124 ret_val = 14.34 125 elif name == 'Base_rate' 126 print "Getting base_rate" 127 ret_val = 15.34 128 elif name == 'Backlash' 129 print "Getting backlash" 130 ret_val = 123 131 return ret_val 132 133 def SetExtraAttributePar(self,axis,name,value): 134 if name == 'IceAttribute' 135 print "Setting IceAttribute to",value 136 137 def GetExtraAttributePar(self,axis,name): 138 ret_val = 0.0 139 if name == 'IceAttribute' 140 print "Getting IceAttribute" 141 ret_val = 12.34 142 return ret_val 143 144 def AbortOne(self,axis): 145 print "PYTHON -> IcePapController/",self.inst_name,": Aborting motion for axis:",axis 146 147 def DefinePosition(self,axis,value): 148 print "PYTHON -> IcePapController/",self.inst_name,": Defining position for axis:",axis 149 150 def __del__(self): 151 print "PYTHON -> IcePapController/",self.inst_name,": Aarrrrrg, I am dying" 152 153 def SendToCtrl(self,in_str) 154 print "Python -> MinController/",self.inst_name,": In SendToCtrl method" 155 self.sock.send("The input string") 156 out_str = self.sock.recv(1024) 157 return out_str Line 6 : Definition of the Python DocString which will also be used for the first returned value of the Pool device GetControllerInfo command. See chapter XXX: Unknown inset LatexCommand \ref{ite:GetControllerInfo:}: to get all details about this command. Line 11: Definition of the mandatory MaxDevice property set to 128 Line 12: Definition of the pre-defined feature supported by this controller. In this example, only the backlash Line 13: Definition of one controller extra feature called IceFeature Line 14-17: Definition of 2 properties called host and port Line 23-36: The IcePapController constructor code. Note that the object attribute host and port automatically created by the property management are used on line 32 Line 39-40: The AddDevice method Line 42-43: The DeleteDevice method Line 45-48: The PreReadAll method which clears the 2 list read_pos and motor_to_read Line 50-52: The PreReadOne method. It stores which method has to be read in the motor_to_read list Line 54-57: The ReadAll method. It send the request to read motor positions to the controller and stores the result in the internal read_pos list Line 59-61: The ReadOne method returning motor position from the internal read_pos list Line 63-66: The PreStartAll method which clears 2 internal list called write_pos and motor_to_write Line 68-70: The PreStartOne method Line 72-75: The StartOne method which appends in the write_pos and motor_to_write list the new motor position and the motor number which has to be moved Line 77-79: The StartAll method sending the request to the controller Line 81-84: The PreStateAll method which clears 2 internal list called read_state and motor_to_get_state Line 86-88: The PreStateOne method Line 90-93: The StateAll method sending the request to the controller Line 95-98: The StateOne method returning motor state from the internal read_state list Line 100-112: The SetPar method managing the acceleration, deceleration, velocity, base_rate and backlash attributes (because defined in line 11) Line 114-131: The GetPar method managing the same 5 parameters plus the step_per_unit Line 133-135: The SetExtraAttributePar method for the controller extra feature defined at line 12 Line 137-142: The GetExtraAttributePar method for controller extra feature Line 144-145: The AbortOne method Line 147-148: The DefinePosition method Line 153-157: The SendToCtrl method Defining available controller features """""""""""""""""""""""""""""""""""""" Four data types and two read_write modes are available for the attribute associated with controller features. The possible data type are: - BOOLEAN - LONG - DOUBLE - STRING The read_write modes are: - READ - READ_WRITE All the attributes created to deal with controller features and defined as READ_WRITE will be memorized attributes. This means that the attribute will be written with the memorized value just after the device creation by the Tango_ layer. The definition of a controller features means defining three elements which are the feature name, the feature data type and the feature read_write mode. It uses a C++ structure called MotorFeature with three elements which are a C string (const char \*) for the feature name and two enumeration for the feature data type and feature read_write mode. All the available features are defined as an array of these structures in a file called **MotorFeatures.h** Controller access when creating a motor """"""""""""""""""""""""""""""""""""""" When you create a motor (a new one or at Pool startup time), the calls executed on the controller depend if a command "SaveConfig" has already been executed for this motor. If the motor is new and the command SaveConfig has never been executed for this motor, the following controller methods are called: 1. The AddDevice() method 2. The SetPar() method for the Step_per_unit parameter 3. The GetPar() method for the Velocity parameter 4. The GetPar() method for the Acceleration parameter 5. The GetPar() method for the Deceleration parameter 6. The GetPar() method for the Base_rate parameter If the motor is not new and if a SaveConfig command has been executed on this motor, during Pool startup sequence, the motor will be created and the following controller methods will be called: 1. The AddDevice() method 2. The SetPar() method for the Step_per_unit parameter 3. The SetPar() method for the Velocity parameter 4. The SetPar() method for the Acceleration parameter 5. The SetPar() method for the Deceleration parameter 6. The SetPar() method for the Base_rate parameter 7. The SetExtraAttributePar() method for each of the memorized motor extra attributes The pool motor group interface ------------------------------ The motor group interface allows the user to move several motor(s) at the same time. It supports several attributes and commands. It is implemented in C++ and is mainly a set of controller methods call or individual motor call. The motor group interface is statically linked with the Pool device server. When creating a group, the user can define as group member three kinds of elements which are : 1. A simple motor 2. Another already created group 3. A pseudo-motor Nevertheless, it is not possible to have several times the same physical motor within a group. Therefore, each group has a logical structure (the one defined by the user when the group is created) and a physical structure (the list of physical motors really used in the group). The states ^^^^^^^^^^ The motor group interface knows four states which are ON, MOVING, ALARM and FAULT. A motor group device is in MOVING state when one of the group element is in MOVING state. It is in ALARM state when one of the motor is in ALARM state (The underlying motor has reached one of the limit switches). A motor group device is in FAULT state as long as any one of the underlying motor is in FAULT state. The commands ^^^^^^^^^^^^ The motor interface supports 1 command on top of the Tango_ Init, State and Status command. This command is summarized in the following table: ============ =============== ================ Command name Input data type Output data type ============ =============== ================ Abort void void ============ =============== ================ - **Abort** : It aborts a running motion. This command does not have input or output argument. It aborts the motion of the motor(s) member of the group which are still moving while the command is received. The attributes ^^^^^^^^^^^^^^ The motor group supports the following attributes: ======== ============================== =========== ======== Name Data type Data format Writable ======== ============================== =========== ======== Position Tango::DevVarDoubleStringArray Spectrum R/W ======== ============================== =========== ======== - P **osition** : This is a read/write spectrum of double attribute. Each spectrum element is the position of one motor. The order of this array is the order used when the motor group has been created. The size of this spectrum has to be the size corresponding to the motor number when the group is created. For instance, for a group created with 2 motors, another group of 3 motors and one pseudo-motor, the size of this spectrum when written has to be 6 ( 2 + 3 + 1) The properties ^^^^^^^^^^^^^^ Each motor group has 6 properties. Five of them are automatically managed by the pool software and must not be changed by the user. These properties are called Motor_group_id, Pool_device, Motor_list, User_group_elt and Pos_spectrum_dim_x. The last property called Sleep_bef_last_read is a user property.This user property is: ====================== ============= Property name Default value ====================== ============= Sleep_before_last_read 0 ====================== ============= It defines the time in milli-second that the software managing a motor group motion will wait between it detects the end of the motion of the last group element and the last group motors position reading. Getting motor group state using event ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The simplest way to know if a motor group is moving is to survey its state. If the group is moving, its state will be MOVING. When the motion is over, its state will be back to ON. The pool motor interface allows client interested by group state to use the Tango_ event system subscribing to motor group state change event. As soon as a group starts a motion, its state is changed to MOVING and an event is sent. As soon as the motion is over, the group state is updated ans another event is sent. Events will also be sent to each motor element of the group when they start moving and when they stop. These events could be sent before before the group state change event is sent in case of group motion with different motor motion for each group member. Reading the group position attribute ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For each motor group, the key attribute is its position. Special care has been taken on this attribute management. When the motor group is not moving (None of the motor are moving), reading the Position attribute will generate calls to the controller(s) and therefore hardware access. When the motor group is moving (At least one of its motor is moving), its position is automatically read every 100 milli- seconds and stored in the Tango_ polling buffer. This means that a client reading motor group Position attribute while the group is moving will get the position from the Tango_ polling buffer and will not generate extra controller calls. It is also possible to get a group position using the Tango_ event system. When the group is moving, an event is sent to the registered clients when the change event criterion is true. By default, this change event criterion is set to be a difference in position of 5. It is tunable on a group basis using the classical group Position attribute "abs_change" property or at the pool device basis using its DefaultMotGrpPos_AbsChange property. Anyway, not more than 10 events could be sent by second. Once the motion is over (None of the motors within the group are moving), the group position is made unavailable from the Tango_ polling buffer and is read a last time after a tunable waiting time (Sleep_bef_last_read property). A forced change event with this value is sent to clients using events. The ghost motor group ^^^^^^^^^^^^^^^^^^^^^ In order to allow pool client software to be entirely event based, some kind of polling has to be done on each motor to inform them on state change which are not related to motor motion. To achieve this goal, one internally managed motor group is created. Each pool motor is a member of this group. The Tango_ polling thread polls the state command of this group (Polling period tunable with the pool Ghostgroup_PollingPeriod property). The code of this group state command detects change in every motor state and send a state change event on the corresponding motor. This motor group is not available to client and is even not defined in the Tango_ database. This is why it is called the ghost group. The pool pseudo motor interface ------------------------------- The pseudo motor interface acts like an abstraction layer for a motor or a set of motors allowing the user to control the experiment by means of an interface which is more meaningful to him(her). Each pseudo motor is represented by a C++ written tango device whose interface allows for the control of a single position (scalar value). In order to translate the motor positions into pseudo positions and vice versa, calculations have to be performed. The device pool provides a python API class that can be overwritten to provide new calculations. The states ^^^^^^^^^^ The pseudo motor interface knows four states which are ON, MOVING, ALARM and FAULT. A pseudo motor device is in MOVING state when at least one motor is in MOVING state. It is in ALARM state when one of the motor is in ALARM state (The underlying motor has reached one of the limit switches. A pseudo motor device is in FAULT state as long as any one of the underlying motor is in FAULT state). The commands ^^^^^^^^^^^^ The pseudo motor interface supports 1 command on top of the Tango Init, State and Status commands. This command is summarized in the following table: ============ =============== ================ Command name Input data type Output data type ============ =============== ================ Abort void void ============ =============== ================ - **Abort** : It aborts a running movement. This command does not have input or output argument. It aborts the movement of the motor(s) member of the pseudo motor which are still moving while the command is received. The attributes ^^^^^^^^^^^^^^ The pseudo motor supports the following attributes: ======== ================ =========== ======== Name Data type Data format Writable ======== ================ =========== ======== Position Tango::DevDouble Scalar R/W ======== ================ =========== ======== - **Position** : This is read-write scalar double attribute. With the classical Tango min and max_value, it is easy to define authorized limit for this attribute. It is not allowed to read or write this attribute when the pseudo motor is in FAULT or UNKNOWN state. It is also not possible to write this attribute when the motor is already MOVING. The PseudoMotor system class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This chapter describes how to write a valid python pseudo motor system class. Prerequisites """"""""""""" Before writing the first python pseudo motor class for your device pool two checks must be performed: 1. The device pool **PoolPath** property must exist and must point to the directory which will contain your python pseudo motor module. The syntax of this PseudoPath property is the same used in the PATH or PYTHONPATH environment variables. Please see XXX: Unknown inset LatexCommand \ref{sub:PoolPath}: for more information on setting this property 2. A PseudoMotor.py file is part of the device pool distribution and is located in /py_pseudo. This directory must be in the PYTHONPATH environment variable or it must be part of the **PoolPath** device pool property metioned above Rules """"" A correct pseudo motor system class must obey the following rules: 1. the python class PseudoMotor of the PseudoMotor module must be imported into the current namespace by using one of the python import statements: :: from PseudoMotor import * import PseudoMotor or from PseudoMotor import PseudoMotor or 2. the pseudo motor system class being written must be a subclass of the PseudoMotor class (see example below) 3. the class variable **motor_roles** must be set to be a tuple of text descriptions containing each motor role description. It is crucial that all necessary motors contain a textual description even if it is an empty one. This is because the number of elements in this tuple will determine the number of required motors for this pseudo motor class. The order in which the roles are defined is also important as it will determine the index of the motors in the pseudo motor system. 4. the class variable **pseudo_motor_roles** must be set if the pseudo motor class being written represents more than one pseudo motor. The order in which the roles are defined will determine the index of the pseudo motors in the pseudo motor system. If the pseudo motor class represents only one pseudo motor then this operation is optional. If omitted the value will of pseudo_motor_roles will be set to: 5. if the pseudo motor class needs some special parameters then the class variable parameters must be set to be a dictionary of : { : } values where: - is a string representing the name of the parameter - is one of the following mandatory properties: 'Description', 'Type'. The 'Default Value' property is optional. - is the corresponding value of the property. The 'Description' can contain any text value. The 'Type' must be one of available Tango_ property data types and 'Default Value' must be a string containning a valid value for the corresponding 'Type' value. 6. the pseudo motor class must implement a **calc_pseudo** method with the following signature: :: number = calc_pseudo(index, physical_pos, params = None) The method will receive as argument the index of the pseudo motor for which the pseudo position calculation is requested. This number refers to the index in the pseudo_motor_roles class variable. The physical_pos is a tuple containing the motor positions. The params argument is optional and will contain a dictionary of : . The method body should contain a code to translate the given motor positions into pseudo motor positions. The method will return a number representing the calculated pseudo motor position. 7. the pseudo motor class must implement a **calc_physical** method with the following signature: :: number = calc_physical(index, pseudo_pos, params = None) The method will receive as argument the index of the motor for which the physical position calculation is requested. This number refers to the index in the motor_roles class variable. The pseudo_pos is a tuple containing the pseudo motor positions. The params argument is optional and will contain a dictionary of : . The method body should contain a code to translate the given pseudo motor positions into motor positions. The method will return a number representing the calculated motor position. 8. Optional implementation of **calc_all_pseudo** method with the following signature: :: ()/[]/number = calc_all_pseudo(physical_pos,params = None) The method will receive as argument a physical_pos which is a tuple of motor positions. The params argument is optional and will contain a dictionary of : . The method will return a tuple or a list of calculated pseudo motor positions. If the pseudo motor class represents a single pseudo motor then the return value could be a single number. 9. Optional implementation of **calc_all_physical** method with the following signature: :: ()/[]/number = calc_all_physical(pseudo_pos, params = None) The method will receive as argument a pseudo_pos which is a tuple of pseudo motor positions. The params argument is optional and will contain a dictionary of : . The method will return a tuple or a list of calculated motor positions. If the pseudo motor class requires a single motor then the return value could be a single number. **Note:** The default implementation **calc_all_physical** and **calc_all_pseudo** methods will call calc_physical and calc_pseudo for each motor and physical motor respectively. Overwriting the default implementation should only be done if a gain in performance can be obtained. Example ^^^^^^^ One of the most basic examples is the control of a slit. The slit has two blades with one motor each. Usually the user doesn't want to control the experiment by directly handling these two motor positions since their have little meaning from the experiments perspective. .. image:: /_static/gap_offset.png Instead, it would be more useful for the user to control the experiment by means of changing the gap and offset values. Pseudo motors gap and offset will provide the necessary interface for controlling the experiments gap and offset values respectively. The calculations that need to be performed are: .. math:: :nowrap: \[ \left\{ \begin{array}{l} gap=sl2t+sl2b\\ offset=\frac{sl2t-sl2b}{2}\end{array}\right.\] .. math:: :nowrap: \[ \left\{ \begin{array}{l} sl2t=-offset+\frac{gap}{2}\\ sl2b=offset+\frac{gap}{2}\end{array}\right.\] The corresponding python code would be: :: 01 class Slit(PseudoMotor): 02 """A Slit system for controlling gap and offset pseudo motors.""" 04 05 pseudo_motor_roles = ("Gap", "Offset") 06 motor_roles = ("Motor on blade 1", "Motor on blade 2") 07 08 def calc_physical(self,index,pseudo_pos,params = None): 09 half_gap = pseudo_pos[0]/2.0 10 if index == 0: 11 return -pseudo_pos[1] + half_gap 12 else 13 return pseudo_pos[1] + half_gap 14 15 def calc_pseudo(self,index,physical_pos,params = None): 16 if index == 0: 17 return physical_pos[1] + physical_pos[0] 18 else: 19 return (physical_pos[1] - physical_pos[0])/2.0 read gap position diagram """"""""""""""""""""""""" The following diagram shows the sequence of operations performed when the position is requested from the gap pseudo motor: .. image:: /_static/gap_read.png write gap position diagram """""""""""""""""""""""""" The following diagram shows the sequence of operations performed when a new position is written to the gap pseudo motor: .. image:: /_static/gap_write.png The Counter/Timer interface --------------------------- The Counter/Timer user interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Counter/Timer interface is statically linked with the Pool device server and supports several attributes and commands. It is implemented in C++ and used a set of the so-called "controller" methods. The Counter/Timer interface is always the same whatever the hardware is. This is the rule of the "controller" to access the hardware using the communication link supported by the hardware (network link, Serial line...). The controller code has a well-defined interface and can be written using Python or C++. In both cases, it will be dynamically loaded into the pool device server process. The states """""""""" The Counter/Timer interface knows four states which are `ON`, *MOVING*, **FAULT** and UNKNOWN. A Counter/Timer device is in MOVING state when it is counting! It is in FAULT if its controller software is not available (impossible to load it), if a fault is reported from the hardware controller or if the controller software returns an unforeseen state. The device is in the UNKNOWN state if an exception occurs during the communication between the pool and the hardware controller. The commands """""""""""" The Counter/Timer interface supports 2 commands on top of the Tango classical Init, State and Status commands. These commands are summarized in the following table: ============ =============== ================ Command name Input data type Output data type ============ =============== ================ Start void void Stop void void ============ =============== ================ - **Start** : When the device is used as a counter, this commands allows the counter to start counting. When it is used as a timer, this command starts the timer. This command changes the device state from ON to MOVING. It is not allowed to execute this command if the device is already in the MOVING state. - **Stop** : When the device is used as a counter, this commands stops the counter. When it is used as a timer, this command stops the timer. This commands changes the device state from MOVING to ON. It is a no action command if this command is received and the device is not in the MOVING state. The attributes """""""""""""" The Counter/Timer interface supports several attributes which are summarized in the following table: ============== ================= =========== ======== ========= ========== Name Data type Data format Writable Memorized Ope/Expert ============== ================= =========== ======== ========= ========== Value Tango::DevDouble Scalar R/W No Ope SimulationMode Tango::DevBoolean Scalar R No Ope ============== ================= =========== ======== ========= ========== - **Value** : This is read-write scalar double attribute. Writing the value is used to clear (or to preset) a counter or to set a timer time. For counter, reading the value allows the user to get the count number. For timer, the read value is the elapsed time since the timer has been started. After the acquisition, the value stays unchanged until a new count/time is started. For timer, the unit of this attribute is the second. - **SimulationMode** : This is a read only scalar boolean attribute. When set, all the counting/timing requests are not forwarded to the software controller and then to the hardware. When set, the device Value is always 0. To set this attribute, the user has to used the pool device Tango interface. It is not allowed to read this attribute when the device is in FAULT or UNKNOWN states. The properties """""""""""""" Each Counter/Timer device has one property which is automatically managed by the pool software and must not be changed by the user. This property is named Channel_id. The Counter/Timer controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The CounterTimer controller follows the same principles already explained for the Motor controller in chapter XXX: Unknown inset LatexCommand \ref{sub:The-Motor-Controller}: The basic """"""""" For Counter/Timer, the pre-defined set of methods which has to be implemented can be splitted in 7 different types which are: 1. Methods to create/remove counter/timer experiment channel 2. Methods to get channel(s) state 3. Methods to read channel(s) 4. Methods to load channel(s) 5. Methods to start channel(s) 6. Methods to configure a channel 7. Remaining method The CounterTimer controller features """""""""""""""""""""""""""""""""""" Not defined yet The CounterTimer controller extra attributes """""""""""""""""""""""""""""""""""""""""""" The definition is the same than the one defined for Motor controller and explained in chapter XXX: Unknown inset LatexCommand \ref{par:Specifying-the-motor}: Methods to create/remove Counter Timer Channel """""""""""""""""""""""""""""""""""""""""""""" Two methods are called when creating or removing counter/timer channel from a controller. These methods are called **AddDevice** and **DeleteDevice** . The AddDevice method is called when a new channel belonging to the controller is created within the pool. The DeleteDevice method is called when a channel belonging to the controller is removed from the pool. Method(s) to get Counter Timer Channel state. """"""""""""""""""""""""""""""""""""""""""""" These methods follow the same definition than the one defined for Motor controller which are detailed in chapter XXX: Unknown inset LatexCommand \ref{par:Methods-to-get-state}: . Method(s) to read Counter Timer Experiment Channel """""""""""""""""""""""""""""""""""""""""""""""""" Four methods are used when a request to read channel(s) value is received. These methods are called PreReadAll, PreReadOne, ReadAll and ReadOne. The algorithm used to read value of one or several channels is the following : :: /FOR/ Each controller(s) implied in the reading - Call PreReadAll() /END FOR/ /FOR/ Each channel(s) implied in the reading - PreReadOne(channel to read) /END FOR/ /FOR/ Each controller(s) implied in the reading - Call ReadAll() /END FOR/ /FOR/ Each channel(s) implied in the reading - Call ReadOne(channel to read) /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ ===================================== ================================= ================================================================= PreReadAll() PreReadOne() ReadAll() ReadOne() ==================== ================================ ===================================== ================================= ================================================================= Default action Does nothing Does nothing Does nothing Print message on the screen and returns NaN. Mandatory for Python Externally called by Reading the Value attribute Reading the Value attribute Reading the Value attribute Reading the Value attribute Internally called Once for each implied controller For each implied channel For each implied controller Once for each implied channel Typical rule Init internal data for reading Memorize which channel has to be read Send order to physical controller Return channel value from internal data ==================== ================================ ===================================== ================================= ================================================================= This algorithm covers the sophisticated case where a physical controller is able to read several channels positions at the same time. For some simpler controller, it is possible to implement only the ReadOne() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Method(s) to load Counter Timer Experiment Channel """""""""""""""""""""""""""""""""""""""""""""""""" Four methods are used when a request to load channel(s) value is received. These methods are called PreLoadAll, PreLoadOne, LoadAll and LoadOne. The algorithm used to load value in one or several channels is the following:: /FOR/ Each controller(s) implied in the loading - Call PreLoadAll() /END FOR/ /FOR/ Each channel(s) implied in the loading - ret = PreLoadOne(channel to load,new channel value) - /IF/ ret is true - Call LoadOne(channel to load, new channel value) - /END IF/ /END FOR/ /FOR/ Each controller(s) implied in the loading - Call LoadAll() /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ ============================= ====================================== ================================= PreLoadAll() PreLoadOne() LoadOne() LoadAll() ==================== ================================ ============================= ====================================== ================================= Default action Does nothing Returns true Does nothing Does nothing Externally called by Writing the Value attribute Writing the Value attribute Writing the Value attribute Writing the Value attribute Internally called Once for each implied controller For each implied channel For each implied channel Once for each implied controller Typical rule Init internal data for loading Check if counting is possible Set new channel value in internal data Send order to physical controller ==================== ================================ ============================= ====================================== ================================= This algorithm covers the sophisticated case where a physical controller is able to write several channels positions at the same time. For some simpler controller, it is possible to implement only the LoadOne() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Method(s) to start Counter Timer Experiment Channel """"""""""""""""""""""""""""""""""""""""""""""""""" Four methods are used when a request to start channel(s) is received. These methods are called PreStartAllCT, PreStartOneCT, StartAllCT and StartOneCT. The algorithm used to start one or several channels is the following:: /FOR/ Each controller(s) implied in the starting - Call PreStartAllCT() /END FOR/ /FOR/ Each channel(s) implied in the starting - ret = PreStartOneCT(channel to start) - /IF/ ret is true - Call StartOneCT(channel to start) - /END IF/ /END FOR/ /FOR/ Each controller(s) implied in the starting - Call StartAllCT() /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ ============================= ====================================== ================================= PreStartAllCT() PreStartOneCT() StartOneCT() StartAllCT() ==================== ================================ ============================= ====================================== ================================= Default action Does nothing Returns true Does nothing Does nothing Externally called by The Start command The Start command The Start command The Start command Internally called Once for each implied controller For each implied channel For each implied channel Once for each implied controller Typical rule Init internal data for starting Check if starting is possible Set new channel value in internal data Send order to physical controller ==================== ================================ ============================= ====================================== ================================= This algorithm covers the sophisticated case where a physical controller is able to write several channels positions at the same time. For some simpler controller, it is possible to implement only the StartOneCT() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Methods to configure Counter Timer Experiment Channel """"""""""""""""""""""""""""""""""""""""""""""""""""" The rule of these methods is to - Get or Set channel extra attribute(s) parameter with methods called GetExtraAttributePar() or SetExtraAttributePar() The following table summarizes the usage of these methods: ========= ================================================= ===================================================== GetExtraAttributePar() SetExtraAttributePar() ========= ================================================= ===================================================== Called by Reading any of the extra attributes Writing any of the extra attributes Rule Get extra attribute value from the physical layer Set additional attribute value in physical controller ========= ================================================= ===================================================== The GetExtraAttributePar() default implementation returns a string set to "Pool_meth_not_implemented". Remaining methods """"""""""""""""" The rule of the remaining methods is to - Send a raw string to the controller with a method called SendToCtrl() - Abort a counting counter/timer with a method called AbortOne() The following table summarizes the usage of this method: ========= ========================================================================= ============================= SendToCtrl() AbortOne() ========= ========================================================================= ============================= Called by The Pool SendToController command The Stop CounterTimer command Rule Send the input string to the controller and returns the controller answer Abort a running count ========= ========================================================================= ============================= The Counter Timer controller properties (including the MaxDevice """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" property) The definition is the same than the one defined for Motor controller and explained in chapter XXX: Unknown inset LatexCommand \ref{par:Controller-properties}: C++ controller """""""""""""" For C++, the controller code is implemented as a set of classes: A base class called **Controller** and a class called **CoTiController** which inherits from Controller. Finally, the user has to write its controller class which inherits from CoTiController. The Controller class has already been detailed in XXX: Unknown inset LatexCommand \ref{sub:The-Cpp-Controller-class}: . XXX: Unknown layout Subparagraph: The CoTiController class The CoTiController class defines thirteen virtual methods which are: 1. void **CoTiController::PreReadAll** () The default implementation does nothing 2. void **CoTiController::PreReadOne** (long idx_to_read) The default implementation does nothing 3. void **CoTiController::ReadAll** () The default implementation does nothing 4. double **CoTiController::ReadOne** (long idx_to_read) The default implementation prints a message on the screen and return a NaN value 5. void **CoTiController::PreLoadAll** () The default implementation does nothing 6. bool **CoTiController::PreLoadOne** (long idx_to_load,double new_value) The default implementation returns true 7. void **CoTiController::LoadOne** (long idx_to_load,double new_value) The default implementation does nothing 8. void **CoTiController::LoadAll** () The default implementation does nothing 9. void **CoTiController::PreStartAllCT** () The default implementation does nothing 10. bool **CoTiController::PreStartOneCT** (long idx_to_start) The default implementation returns true 11. void **CoTiController::StartOneCT** (long idx_to_start) The default implementation does nothing 12. void **CoTiController::StartAllCT** () The default implementation does nothing 13. void **CoTiController::AbortOne** (long idx_to_abort) The default implementation does nothing This class has one constructor which is 1. **CoTiController::CoTiController** (const char \*) Constructor of the CoTiController class with the controller instance name as parameter XXX: Unknown layout Subparagraph: The user controller class The user has to implement the remaining pure virtual methods (AddDevice and DeleteDevice) and has to re-define virtual methods if the default implementation does not cover his needs. The controller code has to define two global variables which are: 1. **CounterTimer_Ctrl_class_name** : This is an array of classical C strings terminated by a NULL pointer. Each array element is the name of a Counter Timer Channel controller defined in the file. 2. **_MaxDevice** : Idem motor controller definition On top of that, a controller code has to define a C function to create the controller object. This is similar to the Motor controller definition which is documented in XXX: Unknown inset LatexCommand \ref{par:The-user-controller}: Python controller """"""""""""""""" The principle is exactly the same than the one used for C++ controller but we don't have pure virtual methods with a compiler checking if they are defined at compile time. Therefore, it is the pool software which checks that the following methods are defined within the controller class when the controller module is loaded (imported): - AddDevice - DeleteDevice - ReadOne method - StateOne method - StartOneCT or StartAllCT method - LoadOne or LoadAll method With Python controller, there is no need for function to create controller class instance. With the help of the Python C API, the pool device is able to create the needed instances. Note that the StateOne() method does not have the same signature for Python controller. 1. tuple **Stat** e **One** (self,idx_number) Get a channel state. The method has to return a tuple with one or two elements which are: 1. The channel state (as defined by Tango) 2. A string describing the motor fault if the controller has this feature. A Python controller class has to inherit from a class called **CounterTimerController** . This does not add any feature but allows the pool software to realize that this class is a Counter Timer Channel controller. The Unix Timer -------------- A timer using the Unix getitimer() and setitimer() system calls is provided. It is a Counter/Timer C++ controller following the definition of the previous chapter. Therefore, the device created using this controller will have the Tango_ interface as the one previously described. The Unix Timer controller shared library is called **UxTimer.so** and the Controlller class is called **UnixTimer** . This controller is foresee to have only one device (MaxDevice = 1) The ZeroDExpChannel interface ----------------------------- The ZeroDExpChannel is used to access any kind of device which returns a scalar value and which are not counter or timer. Very often (but not always), this is a commercial measurement equipment connected to a GPIB bus. In order to have a precise as possible measurement, an acquisition loop is implemented for these ZeroDExpChannel device. This acquisition loop will simply read the data from the hardware as fast as it can (only "sleeping" 20 mS between each reading) and a computation is done on the resulting data set to return only one value. Three types of computation are foreseen. The user selects which one he needs with an attribute. The time during which this acquisition loop will get data is also defined by an attribute The ZeroDExpChannel user interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ZeroDExpChannel interface is statically linked with the Pool device server and supports several attributes and commands. It is implemented in C++ and used a set of the so-called "controller" methods. The ZeroDExpChannel interface is always the same whatever the hardware is. This is the rule of the "controller" to access the hardware using the communication link supported by the hardware (network link, GPIB...). The controller code has a well-defined interface and can be written using Python or C++. In both cases, it will be dynamically loaded into the pool device server process. The states """""""""" The ZeroDExpChannel interface knows five states which are ON, MOVING, ALARM, FAULT and UNKNOWN. A ZeroDExpChannel device is in MOVING state when it is acquiring data! It is in ALARM state when at least one error has occured during the last acquisition. It is in FAULT if its controller software is not available (impossible to load it), if a fault is reported from the hardware controller or if the controller software returns an unforeseen state. The device is in the UNKNOWN state if an exception occurs during the communication between the pool and the hardware controller. The commands """""""""""" The ZeroDExpChannel interface supports 2 commands on top of the Tango classical Init, State and Status commands. These commands are summarized in the following table: ============ =============== ================ Command name Input data type Output data type ============ =============== ================ Start void void Stop void void ============ =============== ================ - **Start** : Start the acquisition for the time defined by the attribute CumulatedTime. If the CumulatedTime attribute value is 0, the acquisition will not automatically stop until a Stop command is received. This command changes the device state from ON to MOVING. It is not allowed to execute this command if the device is already in the MOVING state. - **Stop** : Stop the acquisition. This commands changes the device state from MOVING to ON. It is a no action command if this command is received and the device is not in the MOVING state. The attributes """""""""""""" The ZeroDExpChannel interface supports several attributes which are summarized in the following table: ===================== ================= =========== ======== ========= ========== Name Data type Data format Writable Memorized Ope/Expert ===================== ================= =========== ======== ========= ========== Value Tango::DevDouble Scalar R No Ope CumulatedValue Tango::DevDouble Scalar R No Ope CumulationTime Tango::DevDouble Scalar R/W Yes Ope CumulationType Tango::DevLong Scalar R/W Yes Ope CumulatedPointsNumber Tango::DevLong Scalar R No Ope CumulatedPointsError Tango::DevLong Scalar R No Ope SimulationMode Tango::DevBoolean Scalar R No Ope ===================== ================= =========== ======== ========= ========== - **Value** : This is read scalar double attribute. This is the live value reads from the hardware through the controller - **CumulatedValue** : This is a read scalar double attribute. This is the result of the data acquisition after the computation defined by the CumulationType attribute has been applied. This value is 0 until an acquisition has been started. After an acquisition, the attribute value stays unchanged until the next acquisition is started. If during the acquisition some error(s) has been received while reading the data, the attribute quality factor will be set to ALARM - **CumulationTime** : This is a read-write scalar double and memorized attribute. This is the acquisition time in seconds. The acquisition will automatically stops after this CumulationTime. Very often, reading the hardware device to get one data is time-consuming and it is not possible to read the hardware a integer number of times within this CumulationTime. A device property called StopIfNoTime (see XXX: Unknown inset LatexCommand \ref{ite:StopIfNoTime:-A-boolean}: ) allows the user to tune the acquisition loop. - **CumulationType** : This a read-write scalar long and memorized attribute. Defines the computation type done of the values gathered during the acquisition. Three type of computation are supported: 1. Sum: The CumulatedValue attribute is the sum of all the data read during the acquisition. This is the default type. 2. Average: The CumulatedValue attribute is the average of all the data read during the acquisition 3. Integral: The CumulatedValue attribute is a type of the integral of all the data read during the acquisition - **CumulatedPointsNumber** : This is a read scalar long attribute. This is the number of data correctly read during the acquisition. The attribute value is 0 until an acquisition has been started and stay unchanged between the end of the acquisition and the start of the next one. - **CumulatedPointsError** : This is a read scalar long attribute. This is the number of times it was not possible to read the data from the hardware due to error(s). The property ContinueOnError allows the user to define what to do in case of error. The attribute value is 0 until an acquisition has been started and stay unchanged between the end of the acquisition and the start of the next one. - **SimulationMode** : This is a read only scalar boolean attribute. When set, all the acquisition requests are not forwarded to the software controller and then to the hardware. When set, the device Value, CumulatedValue, CumulatedPointsNumber and CumulatedPointsError are always 0. To set this attribute, the user has to used the pool device Tango_ interface. The value of the CumulationTime and CumulationType attributes are memorized at the moment this attribute is set. When this mode is turned off, if the value of any of the previously memorized attributes has changed, it is reapplied to the memorized value. It is not allowed to read this attribute when the device is in FAULT or UNKNOWN states. The properties """""""""""""" Each ZeroDExpChannel device has a set of properties. One of these properties is automatically managed by the pool software and must not be changed by the user. This property is named Channel_id. The user properties are: =============== ============= Property name Default value =============== ============= StopIfNoTime true ContinueOnError true =============== ============= - XXX: Unknown inset LatexCommand \label{ite:StopIfNoTime:-A-boolean}: **StopIfNoTime** : A boolean property. If this property is set to true, the acquisition loop will check before acquiring a new data that it has enough time to do this. To achieve this, the acquisition loop measures the time needed by the previous data read and checks that the actual time plus the acquisition time is still less than the CumulationTime. If not, the acquisition stops. When this property is set to false, the acquisition stops when the acquisition time is greater or equal than the CumulationTime - **ContinueOnError** : A boolean property. If this property is set to true (the default), the acquisition loop continues reading the data even after an error has been received when trying to read data. If it is false, the acquisition stops as soon as an error is detected when trying to read data from the hardware. Getting ZeroDExpChannel state using event """"""""""""""""""""""""""""""""""""""""" The simplest way to know if a Zero D Experiment Channel is acquiring data is to survey its state. If the device is acquiring data, its state will be MOVING. When the acquisition is over, its state will be back to ON. The pool ZeroDExpChannel interface allows client interested by Experiment Channel state value to use the Tango_ event system subscribing to channel state change event. As soon as a channel starts an acquisition, its state is changed to MOVING and an event is sent. As soon as the acquisition is over (for one reason or another), the channel state is updated and another event is sent. XXX: Unknown inset LatexCommand \label{par:Reading-the-ZeroDExpChannel}: """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Reading the ZeroDExpChannel CumulatedValue attribute During an acquisition, events with CumulatedValue attribute are sent from the device server to the interested clients. The acquisition loop will periodically read this event and fire an event. The first and the last events fired during the acquisition loop do not check the change event criteria. The other during the acquisition loop check the change event criteria The ZeroDExpChannel Controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ZeroDExpChannel controller follows the same principles already explained for the Motor controller in chapter XXX: Unknown inset LatexCommand \ref{sub:The-Motor-Controller}: The basic """"""""" For Zero Dimension Experiment Channel, the pre-defined set of methods which has to be implemented can be splitted in 5 different types which are: 1. Methods to create/remove zero dimension experiment channel 2. Methods to get channel(s) state 3. Methods to read channel(s) 4. Methods to configure a channel 5. Remaining method The ZeroDExpChannel controller features """"""""""""""""""""""""""""""""""""""" Not defined yet The ZeroDExpChannel controller extra attributes """"""""""""""""""""""""""""""""""""""""""""""" The definition is the same than the one defined for Motor controller and explained in chapter XXX: Unknown inset LatexCommand \ref{par:Specifying-the-motor}: Methods to create/remove Zero D Experiment Channel """""""""""""""""""""""""""""""""""""""""""""""""" Two methods are called when creating or removing experiment channel from a controller. These methods are called **AddDevice** and **DeleteDevice** . The AddDevice method is called when a new channel belonging to the controller is created within the pool. The DeleteDevice method is called when a channel belonging to the controller is removed from the pool. Method(s) to get Zero D Experiment Channel state. """"""""""""""""""""""""""""""""""""""""""""""""" These methods follow the same definition than the one defined for Motor controller which are detailed in chapter XXX: Unknown inset LatexCommand \ref{par:Methods-to-get-state}: . Method(s) to read Zero D Experiment Channel """"""""""""""""""""""""""""""""""""""""""" Four methods are used when a request to read channel(s) value is received. These methods are called PreReadAll, PreReadOne, ReadAll and ReadOne. The algorithm used to read value of one or several channels is the following:: /FOR/ Each controller(s) implied in the reading - Call PreReadAll() /END FOR/ /FOR/ Each channel(s) implied in the reading - PreReadOne(channel to read) /END FOR/ /FOR/ Each controller(s) implied in the reading - Call ReadAll() /END FOR/ /FOR/ Each channel(s) implied in the reading - Call ReadOne(channel to read) /END FOR/ The following array summarizes the rule of each of these methods: ==================== ================================ ===================================== ================================= ================================================================= PreReadAll() PreReadOne() ReadAll() ReadOne() ==================== ================================ ===================================== ================================= ================================================================= Default action Does nothing Does nothing Does nothing Print message on the screen and returns NaN. Mandatory for Python Externally called by Reading the Value attribute Reading the Value attribute Reading the Value attribute Reading the Value attribute Internally called Once for each implied controller For each implied channel For each implied controller Once for each implied channel Typical rule Init internal data for reading Memorize which channel has to be read Send order to physical controller Return channel value from internal data ==================== ================================ ===================================== ================================= ================================================================= This algorithm covers the sophisticated case where a physical controller is able to read several channels positions at the same time. For some simpler controller, it is possible to implement only the ReadOne() method. The default implementation of the three remaining methods is defined in a way that the algorithm works even in such a case. Methods to configure Zero D Experiment Channel """""""""""""""""""""""""""""""""""""""""""""" The rule of these methods is to - Get or Set channel extra attribute(s) parameter with methods called GetExtraAttributePar() or SetExtraAttributePar() The following table summarizes the usage of these methods: ========= ================================================= ===================================================== GetExtraAttributePar() SetExtraAttributePar() ========= ================================================= ===================================================== Called by Reading any of the extra attributes Writing any of the extra attributes Rule Get extra attribute value from the physical layer Set additional attribute value in physical controller ========= ================================================= ===================================================== The GetExtraAttributePar() default implementation returns a string set to "Pool_meth_not_implemented". Remaining method """""""""""""""" The rule of the remaining method is to - Send a raw string to the controller with a method called SendToCtrl() The following table summarizes the usage of this method: ========= ========================================================================= SendToCtrl() ========= ========================================================================= Called by The Pool SendToController command Rule Send the input string to the controller and returns the controller answer ========= ========================================================================= The ZeroDExpChannel controller properties (including the MaxDevice property) """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" The definition is the same than the one defined for Motor controller and explained in chapter XXX: Unknown inset LatexCommand \ref{par:Controller-properties}: C++ controller """""""""""""" For C++, the controller code is implemented as a set of classes: A base class called **Controller** and a class called **ZeroDController** which inherits from Controller. Finally, the user has to write its controller class which inherits from ZeroDController. The Controller class has already been detailed in XXX: Unknown inset LatexCommand \ref{sub:The-Cpp-Controller-class}: . XXX: Unknown layout Subparagraph: The ZeroDController class The ZeroDController class defines four virtual methods which are: 1. void **ZeroDController::PreReadAll** () The default implementation does nothing 2. void **ZeroDController::PreReadOne** (long idx_to_read) The default implementation does nothing 3. void **ZeroDController::ReadAll** () The default implementation does nothing 4. double **ZeroDController::ReadOne** (long idx_to_read) The default implementation prints a message on the screen and return a NaN value This class has one constructor which is 1. **ZeroDController::ZeroDController** (const char \*) Constructor of the ZeroDController class with the controller instance name as parameter XXX: Unknown layout Subparagraph: The user controller class The user has to implement the remaining pure virtual methods (AddDevice and DeleteDevice) and has to re-define virtual methods if the default implementation does not cover his needs. The controller code has to define two global variables which are: 1. **ZeroDExpChannel_Ctrl_class_name** : This is an array of classical C strings terminated by a NULL pointer. Each array element is the name of a ZeroDExpChannel controller defined in the file. 2. **_MaxDevice** : Idem motor controller definition On top of that, a controller code has to define a C function to create the controller object. This is similar to the Motor controller definition which is documented in XXX: Unknown inset LatexCommand \ref{par:The-user-controller}: Python controller """"""""""""""""" The principle is exactly the same than the one used for C++ controller but we don't have pure virtual methods with a compiler checking if they are defined at compile time. Therefore, it is the pool software which checks that the following methods are defined within the controller class when the controller module is loaded (imported): - AddDevice - DeleteDevice - ReadOne method - StateOne method With Python controller, there is no need for function to create controller class instance. With the help of the Python C API, the pool device is able to create the needed instances. Note that the StateOne() method does not have the same signature for Python controller. 1. tuple **Stat** e **One** (self,idx_number) Get a channel state. The method has to return a tuple with one or two elements which are: 1. The channel state (as defined by Tango) 2. A string describing the motor fault if the controller has this feature. A Python controller class has to inherit from a class called **ZeroDController** . This does not add any feature but allows the pool software to realize that this class is a Zero D Experiment Channel controller. The OneDExpChannel interface ---------------------------- To be filled in The TwoDExpChannel interface ---------------------------- To be filled in The Measurement Group interface ------------------------------- The measurement group interface allows the user to access several data acquisition channels at the same time. It is implemented as a C++ Tango_ device that is statically linked with the Pool device server. It supports several attributes and commands. The measurement group is the key interface to be used when getting data. The Pool can have several measurement groups but only one will be 'in use' at a time. When creating a measurement group, the user can define four kinds of channels which are: 1. Counter/Timer 2. ZeroDExpChannel 3. OneDExpChannel 4. TwoDExpChannel In order to properly use the measurement group, one of the channels has to be defined as the timer or the monitor. It is not possible to have several times the same channel in a measurement group. It is also not possible to create two measurement groups with exactly the same channels. The States ^^^^^^^^^^ The measurement group interface knows five states which are ON, MOVING, ALARM, FAULT. A group is in MOVING state when it is acquiring data (which means that the timer/monitor channel is in MOVING state). A STANDBY state means that the group is not the current active group of the Pool it belongs to. An ON state means that the group is ready to be used. ALARM means that no timer or monitor are defined for the group. If at least one of the channels reported a FAULT by the controller(s) of that(those) channel(s), the group will be in FAULT state. The commands ^^^^^^^^^^^^ The measurement group interface supports three commands on top of the Tango_ Init, State and Status commands. These commands are summarized in the following table: ================ =============== ================ Command name Input data type Output data type ================ =============== ================ Start void void Abort void void AddExpChannel String void RemoveExpChannel String void ================ =============== ================ - **Start** : When the device is in timer mode (Integration_time attribute > 0), it will start counting on all channels at the same time until the timer channel reaches a value of the Integration_time attribute. When the device in in monitor mode (Integration_count attribute > 0), it will start counting on all channels at the same time until de monitor channel reaches the value of the Integration_count attribute. For more details on setting the acquisition mode see XXX: Unknown inset LatexCommand \ref{Measurement Group: The attributes}: . This command will change the device state to MOVING. It will not be allowed to execute this command if the device is already in MOVING state. This command does not have any input or output arguments. The state will change from MOVING to ON only when the last channel reports that its acquisition has finished. - **Abort** : It aborts the running data acquisition. It will stop each channel member of the measurement group. This command does not have any input or output arguments. - **AddExpChannel** : adds a new experiment channel to the measurement group. The given string argument must be a valid experiment channel in the pool and must not be one of the channels of the measurement group. An event will be sent on the corresponding attribute representing the list of channels in the measurement group. For example, if the given channel is a Counter/Timer channel, then an event will be sent for the attribute "Counters "(See below for a list of attributes in the measurement group). - **RemoveExpChannel** : removes the given channel from the measurement group. The given string argument must be a valid experiment channel in the measurement group. If the channel to be deleted is the current Timer/Monitor then the value for the corresponding attribute will be set to "Not Initialized "and an event will be sent. An event will be sent on the corresponding attribute representing the list of channels in the measurement group. XXX: Unknown inset LatexCommand \label{Measurement Group: The attributes}: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The attributes A measurement group will support 8+n (n being the number of channels) attributes summarized in the following table: ========================================= ================ ===================== ======== ========= ========== Name Data type Data format Writable Memorized Ope/Expert ========================================= ================ ===================== ======== ========= ========== Integration_time Tango::DevDouble Scalar R/W Yes Ope Integration_count Tango::DevLong Scalar R/W Yes Ope Timer Tango::DevString Scalar R/W Yes Ope Monitor Tango::DevString Scalar R/W Yes Ope Counters Tango::DevString Spectrum R No Ope ZeroDExpChannels Tango::DevString Spectrum R No Ope OneDExpChannels Tango::DevString Spectrum R No Ope TwoDExpChannels Tango::DevString Spectrum R No Ope _Value Tango::DevDouble Scalar/Spectrum/Image R No Ope ========================================= ================ ===================== ======== ========= ========== - **Integration_time** : The group timer integration time. Setting this value to >0 will set the measurement group acquisition mode to timer. It will force Integration_count attribute to 0 (zero). It will also exclude the current Timer channel from the list of Counters. Units are in seconds. - **Integration_count** : The group monitor count value. Setting this value to >0 will set the measurement group acquisition mode change to monitor. It will force Integration_time attribute to 0 (zero). - **Timer** : The name of the channel used as a Timer. A "Not Initialized "value means no timer is defined - **Monitor** : The name of the channel used as a Monitor. A "Not Initialized "value means no timer is defined - **Counter** : The list of counter names in the group - **ZeroDExpChannels** : The list of 0D Experiment channel names in the group - **OneDExpChannels** : The list of 1D Experiment channel names in the group - **TwoDExpChannels** : The list of 2D Experiment channel names in the group - **_Value** : (with :math:`0\leq i0.0 0 Monitor 0.0 >0 Undef 0.0 0 ======= ================ ================= 'Undef' means no valid values are defined in Integration_time and in Integration_count. You will not be able to execute the Start command in this mode. Getting measurement group state using event ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The simplest way to know if a measurement group is acquiring data is to survey its state. If a measurement group is acquiring data its state will be MOVING. When the data acquisition is over, its state will change back to ON. The data acquisition is over when the measurement group detects that all channels finished acquisition (their state changed from MOVING to ON).The pool group interface allows clients interested in group state to use the Tango_ event system subscribing to measurement group state change event. As soon as a group starts acquiring data, its state is changed to MOVING and an event is sent. A new event will be sent when the data acquisition ends. Events will also be sent to each channel of the group when they start acquiring data and when they stop. Reading the measurement group channel values ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For each measurement group there is a set of key dynamic attributes representing the value of each channel in the group. They are named _Value. Special care has been taken on the management of these attributes with distinct behavior depending on the type of channel the attribute represents (Counter/Timer, 0D, 1D or 2D channel). Counter/Timer channel values ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A Counter/Timer Value is represented by a scalar read-only double attribute. When the measurement group is not taking data, reading the counter/timer value will generate calls to the controller and therefore hardware access. When the group is taking data (master channel is moving), the value of a counter/timer is read every 100 miliseconds and stored in the Tango_ polling buffer. This means that a client reading the value of the channel while the group is moving will get the value from the Tango_ polling buffer and will not generate exra controller calls. It is also possible to get the value using the Tango event system. When the group is moving, an event is sent to the registered clients when the change event criteria is true. This is applicable for each Counter/Timer channel in the group. By default, this change event criterion is set to be an absolute difference in the value of 5.0. It is tunable by attribute using the classical "abs_change "property or the pool device basis using its defaultCtGrpVal_AbsChange property. Anyway, not more than 10 events could be sent by second. Once the data acquisition is over, the value is made unavailable from the Tango_ polling buffer and is read a last time. A forced change event is sent to clients using events. Zero D channel values ^^^^^^^^^^^^^^^^^^^^^ A ZeroDExpChannel CumulatedValue is represented by a scalar read-only double attribute. Usually a ZeroDChannel represents the value of a single device (ex.: multimeter). Therefore, has hardware access cannot be optimized for a group of devices, reading the value on the measurement group device attribute has exactly the same behavior as reading it directly on the CumulatedValue attribute of the ZeroDChannel device (see XXX: Unknown inset LatexCommand \ref{par:Reading-the-ZeroDExpChannel}: ). One D channel values ^^^^^^^^^^^^^^^^^^^^ To be filled in Two D channel values ^^^^^^^^^^^^^^^^^^^^ To be filled in Performance ^^^^^^^^^^^ Measurement group devices can often contain many channels. Client applications often request channel values for the set (or subset) of channels in a group. Read requests for these channel values through the _Value attributes of a measurement group should be done by clients in groups as often as possible. This can be achieved by using the client Tango_ API call read_attributes on a DeviceProxy object. This will ensure maximum performance by minimizing hardware access since the measurement group can order channel value requests per controller thus avoiding unecessary calls to the hardware. Measurement group configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Timer/Monitor ^^^^^^^^^^^^^ Measurement group operation mode can be checked/set through the Integration_time and Integration_count (see XXX: Unknown inset LatexCommand \ref{measurement group:Checking-operation-modes}: ). Setting the Integration_time to >0.0 will make the data acquisition (initiated by the invoking the Start command) finish when the channel defined in the Timer attribute reaches the value of Integration_time. Setting the Integration_count to >0 will make the data acquisition (initiated by the invoking the Start command) finish when the channel defined in the Monitor attribute reaches the value of Integration_count. In either case, the measurement group will NOT assume that the master channel(timer/monitor) is able to stop all the other channels in the group, so it will force a Stop on these channels as soon as it detects that the master has finished. This is the case of the UnixTimer channel which itself has no knowledge of the channels involved and therefore is not able to stop them directly. Integration_time, Integration_count, timer and monitor are memorized attributes. This means that the configuration values of these attributes are stored in the database. The next time the Pool starts the values are restored. This is done in order to reduce Pool configuration at startup to the minimum. The ghost measurement group ^^^^^^^^^^^^^^^^^^^^^^^^^^^ In order to allow pool client software to be entirely event based, some kind of polling has to be done on each channel to inform them on state change which are not related to data acquisition. To achieve this goal, one internally managed measurement group is created. Each pool channel (counter/timer, 0D, 1D or 2D experiment channel) is a member of this group. The Tango_ polling thread polls the state command of this group (Polling period tunable with the pool Ghostgroup_PollingPeriod property). The code of this group state command detects change in every channel state and send a state change event on the corresponding channel. This measurment group is not available to client and is even not defined in the Tango_ database. This is why it is called the ghost measurement group. The pool serial line, GPIB, socket interfaces --------------------------------------------- To be filled in The pool Modbus interface ------------------------- To be filled in Extending pool features ======================= To be filled in Common task handled by the pool =============================== Constraint ---------- Two types of constraint are identified. 1. Simple constraint: This type of constraint is valid only for motor motion. It limits motor motion. This in not the limit switches which are a hardware protection. It's a software limit. This type of constraint is managed by the min_value and max_value property of the motor Position Tango_ attribute. Tango_ core will refused to write the attribute (Position) if outside the limits set by these min_value and max_value attribute properties. These values are set on motor Position attribute in physical unit. **Warning** : The backlash has to be taken into account in the management of this limit. In order to finish the motion always coming from the same direction, sometimes the motor has to go a little bit after the wanted position and then returns to the desired position. The limit value has to take the backlash value into account. If the motor backlash attribute is modified, it will also change the Position limit value. .. image:: /_static/limit.png 2. User constraint: This kind of constraint is given to the user to allow him to write constraint macros which will be executed to allow or disallow an action to be done on one object. In the pool case, the object is a writable attribute and the action is writing the attribute. Therefore, the following algorithm is used when writing an attribute with constraint: :: /IF/ Simple constraint set /IF/ New value outside limits - Throw an exception /ENDIF/ /ENDIF/ /IF/ Some user constraint associated to this attribute /FOR/ All the user constraint - Evaluate the constraint /IF/ The constraint evaluates to False - Throw an exception /ENDIF/ /ENDFOR/ /ENDIF/ - Write the attribute The first part of this algorithm is part of the Tango_ core. The second part will be coded in the Pool Tango_ classes and in a first phase will be available only for the Position attribute of the Motor class. User constraint implementation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When the user creates a constraint, he has to provide to the pool the following information: 1. The name of the object to which the constraint belongs. It is the name of the writable Tango_ attribute (actually only a motor position attribute. A user constraint will be written using the Python language. It has to be a Python class with a constructor and a "Evaluate" method. This class has to inherit from a class called PoolConstraint. This will allow the pool software to dynamically discover that this class is a pool constraint. The class may define the depending attributes/devices. A depending attribute/device is an object used to evaluate if the constraint is true or false. The depending attributes have to be defined in a list called **depending_attr_list** . Each element in this list is a dictionnary with up to 2 elements which are the description of the depending attribute and eventually a default value. The depending devices have to be defined in a list called **depending_dev_list** which follow the same syntax than the depending_attr_list. A constraint may also have properties as defined in XXX: Unknown inset LatexCommand \ref{par:Controller-properties}: . The constructor will receive three input arguments which are: 1. A list with the depending attribute name 2. A list with the depending device name 3. A dictionnary (name:value) with the properties definition One rule of the constructor is to build the connection with these Tango_ objects and to keep them in the instance. The Evaluate method will evaluate the constraint and will return true or false. It receives as input argument a list with the result of a read_attribute call executed on all the depending attributes. Five pool device commands and two attribute allow the management of these constraints. The commands are **CreateConstraint** , **DeleteConstraint** , **EvaluateContraint, GetConstraintClassInfo** and **GetConstraint** . The attributes are called **ConstraintList** and **ConstraintClassList** . They are all detailed in chapters XXX: Unknown inset LatexCommand \ref{sub:Device-pool-commands}: and XXX: Unknown inset LatexCommand \ref{sub:Device-pool-attributes}: . The following is an example of a user constraint :: 1 import PyTango 2 3 class MyConstraint(PoolConstraint): 4 5 depending_attr_list = [{'DefaultValue':"first_mot/position", 6 'Description':"X position"}, 7 {'DefaultValue':"second_mot/position", 8 'Description':"Z position"}, 9 {'DefaultValue':"first_mot/velocity", 10 'Description':"X position speed"}] 11 11 depending_dev_list = [{'DefaultValue':"first_dev", 12 'Description':"Air pressure device"}] 13 14 inst_prop = {'MyProp':{'Type':PyTango.DevLong,'Description':'The psi constant', 15 'DefaultValue',1234}} 16 17 def __init__(self,attr_list,dev_list,prop_dict) 18 self.air_device = PyTango.DeviceProxy(dev_list[0]) 19 self.const = prop_dict["MyProp"] 20 21 def Evaluate(self,att_value): 22 if att_value[0].value > (xxx * self.const) 23 return False 24 elif att_value[1].value > yyy 25 return False 26 elif att_value[2].value > zzz 27 return False 28 elif self.air_device.state() == PyTango.FAULT 29 return False 30 return True Line 3 : The class inherits from the PoolConstraint class Line 5-10: Definition of the depending attributes Line 11-12: Definition of the depending devices Line 14-15: Definition of a constraint property Line 17-19: The constructor Line 21-30: The Evaluate method Archiving motor position ------------------------ XXX: Unknown inset LatexCommand \label{sub:Archiving-motor-position}: It is not possible to archive motor position using the Tango_ memorized attribute feature because Tango_ writes the attribute value into the database just after it has been set by the user. In case of motors which need some time to go to the desired value and which from time to time do not go exactly to the desired value (for always possible to have position which is a integer number of motor steps), it is more suited to store the motor position at the end of the motion. To achieve this, the pool has a command (called **ArchieveMotorPosition** ) which will store new motor positions into the database. This command will be polled by the classical Tango_ polling thread in order to execute it regularly. The algorithm used by this command is the following: :: - Read motors position for all motors which are not actually moving - /FOR/ all motors - /IF/ The new position just read is different than the old one - Mark the motor as storable - /ENDIF/ - /ENDFOR/ - Store in DB position of all storable motors - Memorize motors position In order to minimize the number of calls done on the Tango_ database, we need to add to the Tango_ database software the ability to store x properties of one attribute of y devices into the database in one call (or may be simply the same property of one attribute of several device). Scanning -------- To be filled in Experiment management --------------------- To be filled in The pool device Tango_ interface ================================= The pool is implemented as a C++ Tango_ device server and therefore supports a set of commands/attributes. It has several attributes to get object (motor, pseudo-motor, controller) list. These lists are managed as attributes in order to have events on them when a new object (motor, controller...) is created/deleted. Device pool commands -------------------- XXX: Unknown inset LatexCommand \label{sub:Device-pool-commands}: On top of the three classical Tango_ commands (State, Status and Init), the pool device supports the commands summarized in the following table: ================== ====================== ============================ ======================== Device type Name Input data type Output data type ================== ====================== ============================ ======================== CreateController Tango::DevVarStringArray void related InitController Tango::DevString void commands ReloadControllerCode Tango::DevString void SendToController Tango::DevVarStringArray Tango::DevString Motor CreateMotor Tango::DevVarLongStringArray void related commands DeleteMotor Tango::DevString void Motor group CreateMotorGroup Tango::DevVarStringArray void related commands DeleteMotorGroup Tango::DevString void GetPseudoMotorInfo Tango::DevVarStringArray Tango::DevVarStringArray Pseudo motor CreatePseudoMotor Tango::DevVarStringArray void related commands DeletePseudoMotor Tango::DevString void ReloadPseudoMotorCode Tango::DevString void GetConstraintClassInfo Tango::DevString Tango::DevVarStringArray CreateConstraint Tango::DevVarStringArray void User Constraint DeleteConstraint Tango::DevString void related EvaluateConstraint Tango::DevString Tango::DevBoolean commands GetConstraint Tango::DevString Tango::DevVarLongArray ReloadConstraintCode Tango::DevString void Experiment Channel CreateExpChannel Tango::DevVarStringArray void related commands DeleteExpChannel Tango::DevString void Measurement group CreateMeasurementGroup Tango::DevVarStringArray void related commands DeleteMeasurementGroup Tango::DevString void Dyn loaded Tango LoadTangoClass class related UnloadTangoClass commands ReloadTangoClass Dyn. created CreateXXX commands DeleteXXX Miscellaneous ArchiveMotorPosition void void ================== ====================== ============================ ======================== - **CreateController** : This command creates a controller object. It has four arguments (all strings) which are: 1. The controller device type: Actually three types are supported as device type. They are: - "Motor" (case independent) for motor device - "CounterTimer" (case independent) for counter timer device - "ZeroDExpChannel" (case independent) for zero dimension experiment channel device 2. Controller code file name: For C++ controller, this is the name of the controller shared library file. For Python controller, this is the name of the controller module. This parameter is only a file name, not a path. The path is automatically taken from the pool device **PooPath** property. It is not necessary to change your LD_LIBRARY_PATH or PYTHONPATH environment variable. Everything is taken from the PoolPath property. 3. Controller class name: This is the name of the class implementing the controller. This class has to be implemented within the controller shared library or Python module passed as previous argument 4. Instance name: It is a string which allows the device pool to deal with several instance of the same controller class. The pool checks that this name is uniq within a control system. The list of created controllers is kept in one of the pool device property and at next startup time, all controllers will be automatically re-created. If you have several pool device within a control system (the same TANGO_HOST), it is not possible to have two times the same controller defines on different pool device. Even if the full controller name is ./, each created controller has an associated name which is: which has to be used when the controller name is requested. This name is case independent. - **DeleteController** : This command has only one input argument which is the controller name (as defined previously). It is not possible to delete a controller with attached device(s). You first have to delete controller's device(s). - **InitController** : This command is used to (re)-initialize a controller if the controller initialization done at pool startup time has failed. At startup time, the device pool creates controller devices even if the controller initialization has failed. All controller devices are set to the FAULT state. This command will try to re-create the controller object and if successful, send an "Init" command to every controller devices. Its input argument is the controller name. - **GetControllerInfo** : This command has three or four input parameters which are: XXX: Unknown inset LatexCommand \label{ite:GetControllerInfo:}: 1. The controller device type 2. The controller code file name: For C++ controller, this is the name of the controller shared library file. For Python controller, this is the name of the controller module. This parameter is only a file name, not a path. The path is automatically taken from the pool device **PooPath** property. 3. The controller class name: This is the name of the class implementing the controller. This class has to be implemented within the controller shared library or Python module passed as previous argument 4. The controller instance name: This parameter is optional. If you do not specify it, the command will return information concerning controller properties as defined at the class level. If you defined it, the command will return information concerning controller properties for this specific controller instance. It returns to the caller all the informations related to controller properties as defined in the controller code and/or in the Tango database. The following format is used to return these informations: 1. The string describing the controller (or an empty string if not defined) 2. Number of controller properties 3. For each property: 1. The property name 2. The property data type 3. The property description 4. The property default value (Empty string if not defined) - **ReloadControllerCode** : The controller code is contains in a shared library dynamically loaded or in a Python module. The aim of this command is to unlink the pool to the shared library and to reload it (or Reload the Python module). The command argument is a string which is the controller file name as defined for the CreateController command. For motor controller, it is not possible to do this command if one of the motor attached to controller(s) using the code within the file is actually moving. All motor(s) attached to every controller(s) using this file is switched to FAULT state during this command execution. Once the code is reloaded, an "Init" command is sent to every controller devices. - **SendToController** : Send data to a controller. The first element of the input argument array is the controller name. The second one is the string to be sent to the controller. This command returns the controller answer or an empty string is the controller does not have answer. - **CreateMotor** : This command creates a new motor. It has three arguments which are: 1. The motor name (a string). This is a Tango_ device alias. It is not allowed to have '/' character within this name. It is a case independent name. 2. The motor controller name (a string) 3. The axe number within the controller The motor is created as a Tango_ device and automatically registered in the database. At next startup time, all motors will be automatically re-created. A Tango_ name is assigned to every motor. This name is a Tango_ device name (3 fields) and follow the syntax: motor/controller_instance_name/axe_number in lower case letters. - **DeleteMotor** : This command has only one argument which is the motor name as given in the first argument of the CreateMotor command. The device is automatically unregistered from the Tango_ database and is not accessible any more even for client already connected to it. - **CreateMotorGroup** : This command creates a new motor group. It has N arguments which are: 1. The motor group name (a string). This is a Tango_ device alias. It is not allowed to have '/' character within this name. It is a case independent name. 2. The list of motor element of the group (motor name or another group name or pseudo-motor name) The motor group is created as a Tango_ device and automatically registered in the database. At next startup time, all motor groups will be automatically re-created. A Tango_ name is assigned to every motor group. This name is a Tango_ device name (3 fields) and follow the syntax: mg/ds_instance_name/motor_group_name in lower case letters. - **DeleteMotorGroup** : This command has only one argument which is the motor group name as given in the first argument of the CreateMotorGroup command. The device is automatically unregistered from the Tango_ database and is not accessible any more even for client already connected to it. This command is not allowed if another motor group is using the motor group to be deleted. - **GetPseudoMotorInfo** : XXX: Unknown inset LatexCommand \label{sub:GetPseudoMotorClassInfo}: : This command has one input argument (a string): **.** The command returns a list of strings representing the pseudo motor system information with the following meaning: pseudo_info[0] - textual description of the pseudo motor class. pseudo_info[1] - (=M) the number of motors required by this pseudo motor class. pseudo_info[2] - (=N) the number of pseudo motors that the pseudo motor system aggregates. pseudo_info[3] - the number of parameters required by the pseudo motor system. pseudo_info[4..N+4] - the textual description of the roles of the N motors. pseudo_info[N+5..N+M+5] - the textual description of the roles of the M pseudo motors. pseudo_info[N+M+6..N+M+P+6] - the textual description of the P parameters. **example** : :: GetPseudoMotorInfo('PseudoLib.Slit') could have as a return: :: ["A Slit system for controlling gap and offset pseudo motors.", "2", "2", "0", "Motor on blade 1", "Motor on blade 2", "Gap", "Offset"] - **CreatePseudoMotor** :This command has a variable number of input arguments (all strings): 1. the python file which contains the pseudo motor python code. 2. the class name representing the pseudo motor system. 3. the N pseudo motor names. These will be the pseudo motor alias for the corresponding pseudo motor tango devices. 4. the M motor names. These names are the existing tango motor alias. N and M must conform to the class name information. See XXX: Unknown inset LatexCommand \ref{sub:GetPseudoMotorClassInfo}: to find how to get class information. For each given pseudo motor name a Tango_ pseudo motor device is created and automatically registered in the database. At next startup time, all pseudo motors will be automatically re- created. A Tango_ name is assigned to every pseudo motor. This name is a Tango_ device name (3 fields) and follow the syntax: pm/python_module_name.class_name/pseudo_motor_name For each Tango_ pseudo motor device the device pool will also create a corresponding alias named pseudo_motor_name. If a motor group Tango_ device with the given motor names doesn't exist then the device pool will also create a motor group with the following name: mg/tango_device_server_instance_name/_pm_ This motor group is built for internal Pool usage. It is not intended that the pseudo motor is accessed directly through this motor group. However, if needed elsewhere, it can be accessed as the usual motor group without any special restrictions. **example:** CreatePseudoMotor('PseudoLib.py','Slit','gap01','offset01','blade01',' blade02') - **DeletePseudoMotor** : This command has only one argument which is the pseudo motor identifier. The device is automatically unregistered from the Tango database and is not accessible any more even for client already connected to it. This command is not allowed if a motor group is using the pseudo motor to be deleted. - **ReloadPseudoMotorCode** :The calculation code is contains in a dynamically loaded Python module. The aim of this command is to reload the Python module. The command argument is a string which is the python module as defined for the CreatePseudoMotor and GetPseudoMotorInfo commands. It is not possible to do this command if one of the motor attached to pseudo motor system(s) using code within the file is actually moving. All pseudo motor(s) using this file are switched to FAULT state during this command execution. - **CreateExpChannel** : This command creates a new experiment channel. It has three arguments which are: 1. The experiment channel name (a string). This is a Tango_ device alias. It is not allowed to have '/' character within this name. It is a case independent name. 2. The experiment channel controller name (a string) 3. The index number within the controller The experiment channel is created as a Tango_ device and automatically registered in the database. At next startup time, all created experiment channels will be automatically re-created. A Tango_ name is assigned to every experiment channel. This name is a Tango_ device name (3 fields) and follow the syntax: expchan/controller_instance_name/index_number in lower case letters. The precise type of the experiment channel (Counter/Timer, ZeroD, OneD...) is retrieved by the pool device from the controller given as command second parameter. - **DeleteExpChannel** : This command has only one argument which is the experiment channel name as given in the first argument of the CreateExpChannel command. The device is automatically unregistered from the Tango_ database and is not accessible any more even for client already connected to it. - **GetConstraintClassInfo** : This command has one input parameter (a string) which is the constraint class name. It returns to the caller all the information related to constraint dependencies and to constraint properties as defined in the constraint code. The following format is used to return properties: - Depending attributes number - Depending attribute name - Depending attribute description - Depending devices number - Depending device name - Depending device description - Class property number - Class property name - Class property description - Class property default value (Set to "NotDef" if not defined) - Instance property number - Instance property name - Instance property description - Instance property default value (Set to "NotDef" if not defined) - **CreateMeasurementGroup** : This command creates a new measurement group. It has N arguments which are: 1. The measurement group name (a string). This is a Tango_ device alias. It is not allowed to have '/' character within this name. It is a case independent name. 2. The list of channel elements of the group (Counter/Timer, 0D, 1D or 2D experiment channel) The measurement group is created as a Tango_ device and automatically registered in the database. At next startup time, all measurement groups will be automatically re-created. A Tango_ name is assigned to every measurement group. This name is a Tango_ device name (3 fields) and follow the syntax: mntgrp/ds_instance_name/measurement_group_name in lower case letters. - **DeleteMeasurementGroup** : This command has only one argument which is the measurement group name as given in the first argument of the CreateMeasurementGroup command. The device is automatically unregistered from the Tango database and is not accessible any more even for client already connected to it. - **AddConstraint** : This command creates a user constraint object. It has several arguments (all strings) which are: 1. Constraint code file name: The name of the constraint module. This parameter is only a file name, not a path. The path is automatically taken from the pool PooPath property. 2. Constraint class name: This is the name of the class implementing the controller. This class has to be implemented within the controller shared library or Python module passed as previous argument 3. Instance name: It is a string which allows the device pool to deal with several instance of the same controller class. 4. The object to which the constraint belongs. It has to be a writable attribute name (actually only a motor position) 5. The list of depending objects. (Variable length list which may be empty) The list of created constraints is kept in one of the pool device property and at next startup time, all constraints will be automatically re-created. It is possible to create several constraint on the same object. They will be executed in the order of their creation. Each created constraint has a associated name which is: / - **DeleteConstraint** : This command has only one argument which is the constraint name as define previously. - **EvaluateConstraint** : This command has only one argument which is the constraint name. It runs the "evaluate" method of the constraint and sends the return value to the caller - **GetConstraint** : The input parameter of this command is the name of a Tango_ object. Actually, it has to be the name of one of the motor Position attribute. The command returns the list of Constraint ID attached to this object. - **ReloadConstraintCode** : The constraint code is contains in a Python module. The aim of this command is to reload the Python module. The command argument is a string which is the constraint file name as defined for theAddConstraint command. All object(s) using this constraint are switched to FAULT state during this command execution. - **LoadTangoClass** : - **UnloadTangoClass** : - **ReloadTangoClass** : - **CreateXXX** : - **DeleteXXX:** - **ArchiveMotorPosition** : Send new motor(s) position to the database. This command will be polled with a default polling period of 10 seconds. The classical Tango_ **Init** command destroys all constructed controller(s) and re-create them reloading their code. Then, it sends an "Init" command to every controlled objects (motor, pseudo-motor and motor group) belonging to the pool device. Motor(s) are switched to FAULT state when controller are destroyed. The pool device knows only two states which are ON and ALARM. The pool device is in ALARM state if one of its controller failed during its initialization phase. It is in ON state when all controllers are correctly constructed. In case the pool device in in ALARM state, its status indicates which controller is faulty. Device pool attributes ---------------------- XXX: Unknown inset LatexCommand \label{sub:Device-pool-attributes}: The device pool supports the following attributes: ==================== ================= =========== ======== Name Data type Data format Writable ==================== ================= =========== ======== ControllerList Tango::DevString Spectrum R ControllerClassList Tango::DevString Spectrum R MotorList Tango::DevString Spectrum R MotorGroupList Tango::DevString Spectrum R PseudoMotorList Tango::DevString Spectrum R PseudoMotorClassList Tango::DevString Spectrum R ExpChannelList Tango::DevString Spectrum R MeasurementGroupList Tango::DevString Spectrum R ConstraintList Tango::DevString Spectrum R ConstraintClassList Tango::DevString Spectrum R SimulationMode Tango::DevBoolean Scalar R/W XXXList Tango::DevString Spectrum R ==================== ================= =========== ======== - **ControllerList** : This is a read only spectrum string attribute. Each spectrum element is the name of one controller following the syntax: - . - Ctrl () - **ControllerClassList** : This is a read only spectrum string attribute. Each spectrum element is the name of one of the available controller class that the user can create. To build this list, the pool device server is using a property called **PoolPath** which defines the path where all files containing controller code should be (Python and C++ controllers). The syntax used for this PoolPath property is similar to the syntax used for Unix PATH environment variable (list of absolute path separated by the ":" character). Each returned string has the following syntax: Type: - Class: - File: - **MotorList** : This is a read only spectrum string attribute. Each spectrum element is the name of one motor known by this pool. The syntax is: () - **MotorGroupList** : This is a read only spectrum string attribute. Each spectrum element is the name of one motor group known by this pool. The syntax is: () Motor list: () The last information is displayed only if the physical group structure differs from the logical one (pseudo-motor or other group used as group member) - **PseudoMotorList** :This is a read only spectrum string attribute. Each spectrum element is the name of one motor known by this pool. The syntax is: () Motor List: 1,...,M - **ExpChannelList** : This is a read only spectrum string attribute. Each spectrum element is the name of one experiment channel known by this pool. The syntax is: () The string describing the experiment channel type may be: - Counter/Timer Experiment Channel - Zero D Experiment Channel - **MeasurementGroupList** : This is a read only spectrum string attribute. Each spectrum element is the name of one measurement group known by the pool. The syntax is: () Experiment Channel list: - **PseudoMotorClassList** :This is a read only spectrum string attribute. Each spectrum element is the name of a valid Pseudo python system class. The syntax is: . . The python files to be found depend on the current value of the pool path. See XXX: Unknown inset LatexCommand \ref{sub:PoolPath}: - **ConstraintClassList** : This is a read only spectrum string attribute. Each spectrum element is the name of one of the available constraint class that the user can create. To build this list, the pool device server is using a property called **PoolPath** which defines the path where all files containing constraint code should be. The syntax used for this property is similar to the syntax used for Unix PATH environment variable (list of absolute path separated by the ":" character). To find constraint classes, the pool will look into all Python files (those with a .py suffix) for classes definition which inherit from a base class called **PoolConstraint** . - **ConstraintList** : This is a read only spectrum string attribute. each spectrum element is one of the constraint actually registered in the pool. The syntax of each string is: - - - **SimulationMode** : This is a read-write scalar boolean attribute. If set to true, all the pool device(s) are switched to Simulation mode. This means that all commands received by pool device(s) will not be forwarded to the associated controllers. - **XXXList** : Device pool property -------------------- The pool device supports the following property: ============================ ================== ============= Property name Property data type Default value ============================ ================== ============= PoolPath String DefaultMotPos_AbsChange Double 5 DefaultMotGrpPos_AbsChange Double 5 DefaultCtVal_AbsChange Double 5 DefaultZeroDVal_AbsChange Double 5 DefaultCtGrpVal_AbsChange Double 5 DefaultZeroDGrpVal_AbsChange Double 5 GhostGroup_PollingPeriod String 5000 MotThreadLoop_SleepTime Long 10 NbStatePerRead Long 10 ZeroDNbReadPerEvent Long 5 ============================ ================== ============= - **PoolPath** : XXX: Unknown inset LatexCommand \label{sub:PoolPath}: The path (same syntax than the Unix PATH environment variable) where the pool software is able to locate Controller software, Pseudo-motor software or Constraint software for both Python or C++ languages - **DefaultMotPos_AbsChange** : The default value used to trigger change event when the position attribute is changing (the associated motor is moving). This property has a hard-coded default value set to 5 - **DefaultMotGrpPos_AbsChange** : The default value used to trigger change event when the group device position attribute is changing. This property has a hard-coded default value set to 5 - **DefaultCtVal_AbsChange** : The default value used to trigger change event when the counter/timer attribute is changing (the counter is counting or the timer is timing). This property has a hard-coded default value set to 5 - **DefaultZeroDVal_AbsChange** : The default value used to trigger change event when the Zero Dimension Experiment Channel is acquiring data. This property has a hard-coded default value set to 5 - **DefaultCtGrpVal_AbsChange** : The default value used to trigger change event when the counter/timer attribute(s) of a measurement group is(are) changing (the counter is counting or the timer is timing). This property has a hard-coded default value set to 5 - **DefaultZeroDGrpVal_AbsChange** : The default value used to trigger change event when the Zero Dimension Experiment Channel(s) of a measurement group is(are) acquiring data. This property has a hard-coded default value set to 5 - **GhostGroup_PollingPeriod** : The ghost motor/measurement group polling period in mS. This property has a default value of 5000 (5 sec) - **MotThreadLoop_SleepTime** : The time (in mS) during which the motion thread will sleep between two consecutive motor state request. The default value is 10 - **NbStatePerRead** : The number of motor state request between each position attribute reading done by the motion thread. The default value is 10. This means that during a motion, the motor position is read by the thread every 100 mS (10 * 10) - **ZeroDNbReadPerEvent** : The number of times the Zero D Experiment Channel value is read by the acquisition thread between firing a change event. The event will be effectively fired to the interested clients according to the CumulatedValue attribute "Absolute Change" property value. - **Controller** : An internally managed property which allow the pool device to remember which controller has been created. Creating device =============== This chapter gives details on what has to be done to create device using the device pool in order to check the work to be done by a Sardana configuration tool. Creating motor -------------- The following is the action list which has to be done when you want to create a new motor: 1. Display the list of all the controller the pool already has. 2. Select one of this controller 3. If the user selects a new controller 1. Read the attribute ControllerClassList to get the list of Controller installed in your system 2. Select one of the controller class 3. With the GetControllerInfo command, get the list of controller properties 4. Give a controller instance name 5. Display and eventually change the controller properties (if any) 6. Create the controller object using the CreateController pool command 4. Give a motor name and a motor axis number in the selected controller 5. Create the motor with the CreateMotor pool command 6. Read the attribute list of the newly created motor 7. Display and eventually change the motor attributes related to motor features and eventually to extra-features Creating motor group -------------------- The following is the action list which has to be done when creating a motor group 1. Give a name to the motor group 2. Display the list of all registered motors (attribute MotorList), all registered motor groups (attribute MotorGroupList), all registered pseudo motors (attribute PseudoMotorList) and select those which have to be member of the group. 3. Create the group (command CreateMotorGroup) Creating a pseudo motor system ------------------------------ The following is the action list which has to be done when you want to create a new pseudo motor: 1. Display the list of all available pseudo motor system classes and select one of them 1. if there is no proper pseudo system class write one in Python 2. update the PoolPath Pool property if necessary 2. Get the selected pseudo motor system class information 3. Give names to the pseudo motors involved in the selected pseudo motor system 4. Create the motor(s) which are involved (if they have are not created yet: See XXX: Unknown inset LatexCommand \ref{sub:Creating-motor}: ) and assign the coresponding roles 5. Create the pseudo motor system (command CreatePseudoMotor) Creating a user constraint -------------------------- The following is the action list which has to be done when you want to create a new user constraint: 1. Display the list of all the constraint the pool already has. 2. Select one of this constraint 3. If the user selects a new constraint 1. Read the attribute ConstraintClassList to get the list of Constraint installed in your system 2. Select one of the constraint class 3. With the GetConstraintClassInfo command, get the list of constraint dependencies and properties 4. Give a constraint instance name 5. If it is the first constraint of this class 1. Display and eventually change the constraint class properties (if any) 4. Display and eventually change the constraint depending attribute (if any) 5. Display and eventually change the constraint depending device (if any) 6. Display and eventually change the constraint instance properties (if any) 7. Create the constraint object using the CreateConstraint pool command Some words on internal implementation ===================================== This chapter gives some details on some part of the pool implementation in order to clarify reader ideas Moving motor ------------ Moving a motor means writing its Position attribute. In Tango, it is already splitted in two actions which are: 1. Call a Motor class method called "is_allowed" 2. Call a Motor class method called "write_Position" The second method will be executed only if the first one returns true. The move order is sent to the motor (via the controller) in the code of the second method. The is_allowed method ^^^^^^^^^^^^^^^^^^^^^ The code implemented in this method follow the algorithm: :: - /IF/ There are any Pseudo Motor using the motor - /FOR/ All these Pseudo Motors - /IF/ They have some limits defined - Compute new Pseudo Motor position if motor moved to the desired value - /IF/ The computed value is outside the authorized window - Return False - /ENDIF/ - /ENDIF/ - /ENDFOR/ - /ENDIF/ - /IF/ There are some user constraint attached to the motor - /FOR/ Each user constraint - /IF/ The constraint has some depending attribute(s) - Read these attributes - /ENDIF/ - /IF/ If the execution of the contraint "Evaluate" method returns False - Return False - /ENDIF/ - /ENDFOR/ - /ENDIF/ - Return True The write_Position method ^^^^^^^^^^^^^^^^^^^^^^^^^ The code implemented in this method follows the algorithm: :: - Compute the dial position from the user position - /IF/ A backlash is defined for this motor and the controller does not manage it - Update motor desired position according to motion direction and backlash value - /ENDIF/ - Start a thread sending it which motor has to move to which position - Wait for thread acknowledge - Return to caller The motion thread will execute the following algorithm: :: - /FOR/ Each controller(s) implied in the motion - Lock the controller object - Call PreStartAll() - /ENDFOR/ - /FOR/ Each motor(s) implied in the motion - ret = PreStartOne(motor to move, new position) - /IF/ ret is true - Call StartOne(motor to move, new position) - /ELSE/ - Inform write_Position that an error occurs - Send acknowledge to write_Position method - /ENDIF/ - /ENDFOR/ - /FOR/ Each motor(s) implied in the motion - Set motor state to MOVING and send a Tango_ event to the requesting client - /ENDFOR/ - /FOR/ Each controller(s) implied in the motion - Call StartAll() - Unlock the controller object - /ENDFOR/ - Send acknowledge to the write_Position method - /WHILE/ One of the motor state is MOVING (From controller) - Sleep for 10 mS - /IF/ One of the motor implied in the motion is not moving any more - /IF/ This motor has backlash and the motion is in the "wrong" direction - Ask for a backlash motion in the other direction (Easy to write, not as easy to do...) - /ENDIF/ - Send a Tango_ event on the state attribute to the requesting client - Leave the loop - /ENDIF/ - /IF/ it is time to read the motor position - Read the motor position - Send a change event on the Position attribute to the requested client if the change event criterion is true - /ENDIF/ - /ENDWHILE/ - Sleep for the time defined by the motor (group) Sleep_bef_last_read property - Read the motor position - Send a forced change event on the Position attribute to the requesting client with the value set to the one just read Data acquisition ---------------- Data aquisition is triggered by invoking a Start command on the measurement group. The code implemented implements the following algorithm. :: /IF/ in timer mode - Write CumulationTime on all 0D channels with Integration_time value /ELIF/ in monitor mode - Write CumulationTime on all 0D channels with 0(zero) value /ENDIF/ /FOR/ Each 0D channel implied in the data aquisition - Load configuration /END FOR/ - Start a CounterTimer thread with channels involved, master channel and the proper value to be set on it - Wait for CounterTimer thread acknowledge /FOR/ Each 0D channel implied in the data aquisition - Send Start command /END FOR/ - Return to caller The Counter/Timer thread will execute the following algorithm: :: - Calculate the list of controllers involved and determine which controller has the master channel /FOR/ Each channel(s) implied in the data aquisition - Lock the channel object /END FOR/ /FOR/ Each controller(s) implied in the data acquisition - Lock the controller object /END FOR/ /FOR/ Each channel(s) implied in the data acquisition - Load configuration /END FOR/ - Load the master channel - timer(monitor) - with the integration time(count) /FOR/ Each controller(s) implied in the data acquisition - Call PreStartAllCT() /END FOR/ /FOR/ Each channel(s), except for the master channel, implied in the data acquisition, - Call PreStartOneCT(channel) - Call StartOneCT(channel) /END FOR/ /FOR/ Each controller(s) implied in the data aquisition - Call StartAllCT() /END FOR/ - Call PreStartAllCT() on the controller which contains the master channel - Call PreStartOneCT(master channel) - Call StartOneCT(master channel) - Call StartAllCT() on the controller which contains the master channel /FOR/ Each controller(s) implied in the data aquisition - Unlock the controller object /END FOR/ /FOR/ Each channel(s) implied in the data aquisition - Unlock the channel object /END FOR/ - Send acknowledge to the Start method /WHILE/ master channel state is MOVING (From controller) - Sleep for 10 * sleepTime mS /IF/ If master channel is not moving any more - Stop all channels - Send a Tango event on the state attribute to the requesting client - Leave the loop /ENDIF/ /IF/ it is time to read the channel values - Read the channel values - Send a change event on each value attribute to the requested client if the change event criterion is true /ENDIF/ /ENDWHILE/ - Read the channel values - Send a forced change event on each value attribute to the requesting client with the value set to the one just read .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.scipy.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/api/tango_macroserver.rst0000644000234100017500000000223312174204301024711 0ustar cpascualcpascual00000000000000 ============== Macro Server ============== .. todo:: document this chapter Introduction ============ This paper describes the macro server Tango_ :term:`API`. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.scipy.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/examples/0000755000234100017500000000000012174204361021512 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/examples/ControllerTemplate.py0000644000234100017500000002100012174204301025666 0ustar cpascualcpascual00000000000000#!/usr/bin/env python import sys """ ControllerTemplate.py: Create a basic controller's template. Its parameters are the file name plus .py, the class inherited if it had (optional) and "yes" if you want to use the obsolete convention. The necessary "defs" are marked as #TODO python ControllerTemplate.py ExampleClass.py InheritedClass NoCT """ __author__ = "Carlos Falcon - cfalcon@cells.es" class ControllerTemplate(): def __init__(self,f, e=""): self.filename = f self.end = e self.ind = 'ind' # pass def addHead(self): f=open(self.filename,"w") f.write('##############################################################################\n'+\ '##\n'+\ '## This file is part of Sardana\n'+\ '##\n'+\ '## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html\n'+\ '##\n'+\ '## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain\n'+\ '##\n'+\ '## Sardana is free software: you can redistribute it and/or modify\n'+\ '## it under the terms of the GNU Lesser General Public License as published by\n'+\ '## the Free Software Foundation, either version 3 of the License, or\n'+\ '## (at your option) any later version.\n'+\ '##\n'+\ '## Sardana is distributed in the hope that it will be useful,\n'+\ '## but WITHOUT ANY WARRANTY; without even the implied warranty of\n'+\ '## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n'+\ '## GNU Lesser General Public License for more details.\n'+\ '##\n'+\ '## You should have received a copy of the GNU Lesser General Public License\n'+\ '## along with Sardana. If not, see .\n'+\ '##\\n'+\ '##############################################################################\n\n')\ def addIncludes(self,inherit,others=None): f = open(self.filename,"a") text = "from sardana import State\n" if inherit!="": text = text+"from sardana.pool.controller import "+inherit+"\n" if inherit.find("Motor")>=0: self.ind = 'axis' if others is not None: text = text+others text = text+"#ADD others includes\n\n" f.write(text) #f.close() def createBasicClass(self): f = open(self.filename,"a") text = "#TODO - Delete it if you don't need\n" text = text +'class BasicClass():\n'+\ '\tpass\n\n' f.write(text) def createMainClass(self,inherit): f = open(self.filename,"a") text = "class "+self.filename[0:len(self.filename)-3]+"("+inherit+"):\n"+\ '\t"""Description""" #TODO\n'+\ '\tgender = "Simulation"\n'+\ '\tmodel = "Basic"\n'+\ '\torganization = "CELLS - ALBA"\n'+\ '\timage = "IMAGE.png"\n'+\ '\tlogo = "ALBA_logo.png"\n\n'+\ '\t#TODO - Delete it if you don\'t need\n'+\ '\tctrl_properties= { \'AAA\' : { \'Type\' : \'DevString\', \'Description\' : \'AAA\' } }\n'+\ '\taxis_attributes = { \'AAA\' : { \'type\' : str, \'Description\' : \'AAA\' }}\n\n'+\ '\tMaxDevice = 1024 #TODO Standar value\n\n' fun = '# --------------------------------------------------------------------------\n'+\ '# Init()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef __init__(self, inst, props, *args, **kwargs):\n' if inherit!="": fun = fun + '\t\t' + inherit + '.__init__(self, inst, props, *args, **kwargs)\n' fun = fun + '\t\t#TODO\n' text = text + fun fun = '# --------------------------------------------------------------------------\n'+\ '# AddDevice/DelDevice()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef AddDevice(self,'+self.ind+'):\n' fun = fun + '\t\t#TODO\n' fun = fun + '\tdef DeleteDevice(self, '+self.ind+'):\n' fun = fun + '\t\t#TODO\n' text = text + fun fun = '# --------------------------------------------------------------------------\n'+\ '# State()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef PreStateOne'+self.end+'(self, '+self.ind+'):\n'+'\t\tpass\n' fun = fun + '\tdef StateOne(self, '+self.ind+'):\n' fun = fun + '\t\tstate = State.On\n' fun = fun + '\t\tstatus = "Undefined"\n' if inherit.find("Motor")>=0: fun = fun + '\t\tswitchstate = 0"\n' fun = fun + '\t\t#TODO\n' fun = fun + '\t\treturn state, status, switchstate"\n' else: fun = fun + '\t\t#TODO\n' fun = fun + '\t\treturn state, status\n' fun = fun + '\tdef PreStateAll'+self.end+'(self):\n' fun = fun + '\t\tpass\n' fun = fun + '\tdef StateAll'+self.end+'(self):\n' fun = fun + '\t\tpass\n' text = text + fun fun = '# --------------------------------------------------------------------------\n'+\ '# Read()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef PreReadOne'+self.end+'(self, '+self.ind+'):\n'+'\t\tpass\n' fun = fun + '\tdef ReadOne(self, '+self.ind+'):\n' fun = fun + '\t\t#TODO\n' fun = fun + '\tdef PreReadAll'+self.end+'(self):\n' fun = fun + '\t\tpass\n' fun = fun + '\tdef ReadAll'+self.end+'(self):\n' fun = fun + '\t\tpass\n' text = text + fun fun = '# --------------------------------------------------------------------------\n'+\ '# Start/Stop()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef PreStartOne'+self.end if inherit.find("Motor")>=0: fun = fun + '(self, '+self.ind+', pos):\n' else: fun = fun + '(self, '+self.ind+'):\n' fun = fun + '\t\tpass\n' fun = fun + '\tdef StartOne'+self.end+'(self, '+self.ind+', pos):\n' fun = fun + '\t\t#TODO\n' fun = fun + '\tdef AbortOne(self, '+self.ind+'):\n' fun = fun + '\t\t#TODO\n' fun = fun + '\tdef StopOne(self, '+self.ind+'):\n' fun = fun + '\t\tself.AbortOne('+self.ind+')\n' fun = fun + '\tdef PreStartAll'+self.end+'(self):\n' fun = fun + '\t\tpass\n' fun = fun + '\tdef StartAll'+self.end+'(self):\n' fun = fun + '\t\tpass\n' fun = fun + '\tdef AbortAll(self):\n' fun = fun + '\t\tpass\n' text = text + fun fun = '# --------------------------------------------------------------------------\n'+\ '# SetAxisPar/GetAxisPar()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef SetAxisPar(self, '+self.ind+', name, value):\n' fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' fun = fun + '\tdef GetAxisPar(self, '+self.ind+', name):\n' fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' text = text + fun fun = '# --------------------------------------------------------------------------\n'+\ '# SetAxisExtraPar/GetAxisExtraPar()\n'+\ '# --------------------------------------------------------------------------\n'+\ '\tdef SetAxisExtraPar(self, '+self.ind+', name, value):\n' fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' fun = fun + '\tdef GetAxisExtraPar(self, '+self.ind+', name):\n' fun = fun + '\t\t#TODO - Delete it if you don\'t need - \n' text = text + fun f.write(text) def main(): #Add MACRO_PATH filename = "" end = "" inherit = "" if(len(sys.argv) > 1): print "Creating " + sys.argv[1] filename = sys.argv[1] if(len(sys.argv) > 2): inherit = sys.argv[2] if(len(sys.argv) > 3): end = "CT" s= ControllerTemplate(filename,end) s.addHead() s.addIncludes(inherit) s.createBasicClass() s.createMainClass(inherit) else: print "Please introduce filename" if __name__ == "__main__": main() sardana-1.2.0/doc/source/devel/examples/controller_examples.rst0000644000234100017500000000046212174204301026321 0ustar cpascualcpascual00000000000000.. _sardana-devel-controller-examples: ========================= Controller examples ========================= This code let you create a basic template of a controller. (:download:`Source code `) .. literalinclude:: ControllerTemplate.py :language: python :linenos: sardana-1.2.0/doc/source/devel/examples/examples.rst0000644000234100017500000000026112174204301024053 0ustar cpascualcpascual00000000000000 .. _sardana-devel-examples: ========= Examples ========= .. toctree:: :maxdepth: 2 Macro examples Controller examples sardana-1.2.0/doc/source/devel/examples/macro_call_examples.rst0000644000234100017500000000051512174204301026231 0ustar cpascualcpascual00000000000000.. _sardana-devel-macro-call-examples: ========================= Macro call examples ========================= This chapter consists of a series of examples demonstrating how to call macros from inside a macro .. literalinclude:: ../../../../src/sardana/macroserver/macros/examples/submacros.py :language: python :linenos: sardana-1.2.0/doc/source/devel/examples/macro_examples.rst0000644000234100017500000000046212174204301025237 0ustar cpascualcpascual00000000000000 .. _sardana-devel-macro-examples: ============== Macro examples ============== .. toctree:: :maxdepth: 2 Specifying macro parameters Calling sub-macros Plotting Asking user input sardana-1.2.0/doc/source/devel/examples/macro_input_examples.rst0000644000234100017500000000077612174204301026466 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.macro .. _sardana-devel-macro-input-examples: ==================== Macro input examples ==================== This chapter consists of a series of examples demonstrating how to ask for user input inside macros. A tutorial on macro input parameter can be found :ref:`here `. The :term:`API` documentation: :meth:`~Macro.input` .. literalinclude:: ../../../../src/sardana/macroserver/macros/examples/user_input.py :language: python :linenos: sardana-1.2.0/doc/source/devel/examples/macro_parameter_examples.rst0000644000234100017500000000054412174204301027300 0ustar cpascualcpascual00000000000000 .. _sardana-devel-macro-parameter-examples: ========================= Macro parameter examples ========================= This chapter consists of a series of examples demonstrating how to declare macros which receive parameter(s). .. literalinclude:: ../../../../src/sardana/macroserver/macros/examples/parameters.py :language: python :linenos: sardana-1.2.0/doc/source/devel/examples/macro_plotting_examples.rst0000644000234100017500000000067212174204301027162 0ustar cpascualcpascual00000000000000 .. _sardana-devel-macro-plotting-examples: ========================= Macro plotting examples ========================= This chapter consists of a series of examples demonstrating how to plot graphics from inside a macro. The complete set of :mod:`~matplotlib.pyplot` examples can be found :ref:`here ` .. literalinclude:: ../../../../src/sardana/macroserver/macros/examples/plotting.py :language: python :linenos: sardana-1.2.0/doc/source/devel/howto_controllers/0000755000234100017500000000000012174204361023462 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/howto_controllers/howto_0dcontroller.rst0000644000234100017500000000243112174204277030051 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-0dcontroller-howto-basics: ============================ How to write a 0D controller ============================ The basics ---------- .. todo:: document 0D controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_1dcontroller.rst0000644000234100017500000000243112174204277030052 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-1dcontroller-howto-basics: ============================ How to write a 1D controller ============================ The basics ---------- .. todo:: document 1D controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_2dcontroller.rst0000644000234100017500000000243112174204277030053 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-2dcontroller-howto-basics: ============================ How to write a 2D controller ============================ The basics ---------- .. todo:: document 2D controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_controller.rst0000644000234100017500000005231512174204277027633 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-controller-howto-whatis: ==================== What is a controller ==================== A controller in sardana is a piece of software capable of *translating* between the sardana :term:`API` and a specific hardware :term:`API`. Sardana expects a controller to obey a specific :term:`API` in order to be able to properly configure and operate with it. The hardware :term:`API` used by the controller could be anything, from a pure serial line to shared memory or a remote server written in Tango_, Taco_ or even EPICS_. Controllers can only be written in Python_ (in future also C++ will be possible). A controller **must** be a :term:`class` inheriting from one of the existing controller types: .. hlist:: :columns: 3 - :class:`MotorController` - :class:`CounterTimerController` - :class:`ZeroDController` - :class:`OneDController` - :class:`TwoDController` - :class:`IORegisterController` - :class:`PseudoMotorController` - :class:`PseudoCounterController` A controller is designed to incorporate a set of generic individual elements. Each element has a corresponding *axis*. For example, in a motor controller the elements will be motors, but in a counter/timer controller the elements will be experimental channels. Some controller classes are designed to target a specific type of hardware. Other classes of controllers, the *pseudo* classes, are designed to provide a high level view over a set of underlying lower level controller elements. We will focus first on writing low level hardware controllers since they share some of the :term:`API` and after on the *pseudo* controllers. .. _sardana-controller-howto-basics: Controller - The basics ----------------------- The first thing to do is to import the necessary symbols from sardana library. As you will see, most symbols can be imported through the :mod:`sardana.pool.controller` module: .. code-block:: python import springfieldlib from sardana.pool.controller import MotorController class SpringfieldMotorController(MotorController): """A motor controller intended from demonstration purposes only""" pass The common :term:`API` to all low level controllers includes the set of methods to: #. construct the controller #. add/delete a controller element [#f1]_ #. obtain the state of controller element(s) [#f2]_ #. define, set and get extra axis attributes #. define, set and get extra controller attributes #. define, set and get extra controller properties In the following chapters the examples will be based on a motor controller scenario. The examples use a :mod:`springfieldlib` module which emulates a motor hardware access library. The :mod:`springfieldlib` can be downloaded from :download:`here `. The Springfield motor controller can be downloaded from :download:`here `. .. _sardana-controller-howto-constructor: Constructor ~~~~~~~~~~~ The constructor consists of the :meth:`~sardana.pool.controller.Controller.__init__` method. This method is called when you create a new controller of that type and every time the sardana server is started. It will also be called if the controller code has changed on the file and the new code is reloaded into sardana. It is **NOT** mandatory to override the :meth:`~sardana.pool.controller.Controller.__init__` from :class:`~sardana.pool.controller.MotorController` . Do it only if you need to add some initialization code. If you do it, it is **very important** to follow the two rules: #. use the method signature: ``__init__(self, inst, props, *args, **kwargs)`` #. always call the super class constructor The example shows how to implement a constructor for a motor controller: .. code-block:: python :emphasize-lines: 3 class SpringfieldMotorController(MotorController): def __init__(self, inst, props, *args, **kwargs): super(SpringfieldMotorController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.springfield = springfieldlib.SpringfieldMotorHW() # do some initialization self._motors = {} .. _sardana-controller-howto-add-delete: Add/Delete axis ~~~~~~~~~~~~~~~ Each individual element in a controller is called *axis*. An axis is represented by a number. A controller can support one or more axes. Axis numbers don't need to be sequencial. For example, at one time you may have created for your motor controller instance only axis 2 and 5. Two methods are called when creating or removing an element from a controller. These methods are :meth:`~sardana.pool.controller.Controller.AddDevice` and :meth:`~sardana.pool.controller.Controller.DeleteDevice`. The :meth:`~sardana.pool.controller.Controller.AddDevice` method is called when a new axis belonging to the controller is created in sardana. The :meth:`~sardana.pool.controller.Controller.DeleteDevice` method is called when an axis belonging to the controller is removed from sardana. The example shows an example how to implement these methods on a motor controller: .. code-block:: python :emphasize-lines: 3, 6 class SpringfieldMotorController(MotorController): def AddDevice(self, axis): self._motors[axis] = True def DeleteDevice(self, axis): del self._motor[axis] .. _sardana-controller-howto-axis-state: Get axis state ~~~~~~~~~~~~~~ To get the state of an axis, sardana calls the :meth:`~sardana.pool.controller.Controller.StateOne` method. This method receives an axis as parameter and should return either: - state (:obj:`~sardana.sardanadefs.State`) or - a sequence of two elements: - state (:obj:`~sardana.sardanadefs.State`) - status (:obj:`str`) (For motor controller see :ref:`get motor state ` ): The state should be a member of :obj:`~sardana.sardanadefs.State` (For backward compatibility reasons, it is also supported to return one of :class:`PyTango.DevState`). The status could be any string. If you return a :obj:`~sardana.sardanadefs.State` object, sardana will compose a status string with: is in Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Controller.StateOne` : .. code-block:: python :emphasize-lines: 11 from sardana import State class SpringfieldMotorController(MotorController): StateMap = { 1 : State.On, 2 : State.Moving, 3 : State.Fault, } def StateOne(self, axis): springfield = self.springfield state = self.StateMap[ springfield.getState(axis) ] status = springfield.getStatus(axis) return state, status .. _sardana-controller-howto-axis-attributes: Extra axis attributes ~~~~~~~~~~~~~~~~~~~~~ Each axis is associated a set of standard attributes. These attributes depend on the type of controller (example, a motor will have velocity, acceleration but a counter won't). Additionally, you can specify an additional set of extra attributes on each axis. Lets suppose that a Springfield motor controller can do close loop on hardware. We could define an extra motor attribute on each axis that (de)actives close loop on demand. The first thing to do is to specify which are the extra attributes. This is done through the :attr:`~sardana.pool.controller.Controller.axis_attributes`. This is basically a dictionary were the keys are attribute names and the value is a dictionary describing the folowing properties for each attribute: ===================== ========= ============================================ ======================================================= =============================================== config. parameter Mandatory Key Default value Example ===================== ========= ============================================ ======================================================= =============================================== data type & format Yes :obj:`~sardana.pool.controller.Type` --- :obj:`int` data access No :obj:`~sardana.pool.controller.Access` :obj:`~sardana.pool.controller.Access.ReadWrite` :obj:`~sardana.pool.controller.Access.ReadOnly` description No :obj:`~sardana.pool.controller.Description` "" (empty string) "the motor encoder source" default value No :obj:`~sardana.pool.controller.DefaultValue` --- 12345 getter method name No :obj:`~sardana.pool.controller.FGet` "get" + "getEncoderSource" setter method name No :obj:`~sardana.pool.controller.FSet` "set" + "setEncoderSource" memorize value No :obj:`~sardana.pool.controller.Memorize` :obj:`~sardana.pool.controller.Memorized` :obj:`~sardana.pool.controller.NotMemorized` max dimension size No :obj:`~sardana.pool.controller.MaxDimSize` Scalar: ``()``; 1D: ``(2048,)``; 2D: ``(2048, 2048)`` ``(2048,)`` ===================== ========= ============================================ ======================================================= =============================================== Here is an example of how to specify the scalar, boolean, read-write *CloseLoop* extra attribute in a Springfield motor controller: .. code-block:: python :emphasize-lines: 6, 14, 17 from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet class SpringfieldMotorController(MotorController): axis_attributes = { "CloseLoop" : { Type : bool, Description : "(de)activates the motor close loop algorithm", DefaultValue : False, }, } def getCloseLoop(self, axis): return self.springfield.isCloseLoopActive(axis) def setCloseLoop(self, axis, value): self.springfield.setCloseLoop(axis, value) When sardana needs to read the close loop value, it will first check if the controller has the method specified by the :obj:`~sardana.pool.controller.FGet` keyword (we didn't specify it in :attr:`~sardana.pool.controller.Controller.axis_attributes` so it defaults to *getCloseLoop*). It will then call this controller method which should return a value compatible with the attribute data type. As an alternative, to avoid filling the controller code with pairs of get/set methods, you can choose not to write the getCloseLoop and setCloseLoop methods. This will trigger sardana to call the :meth:`~sardana.pool.controller.Controller.GetAxisExtraPar` /:meth:`~sardana.pool.controller.Controller.SetAxisExtraPar` pair of methods. The disadvantage is you will end up with a forest of :keyword:`if` ... :keyword:`elif` ... :keyword:`else` statements. Here is the alternative implementation: .. code-block:: python :emphasize-lines: 6, 14, 18 from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet class SpringfieldMotorController(MotorController): axis_attributes = { "CloseLoop" : { Type : bool, Description : "(de)activates the motor close loop algorithm", DefaultValue : False, }, } def GetAxisExtraPar(self, axis, parameter): if parameter == 'CloseLoop': return self.springfield.isCloseLoopActive(axis) def SetAxisExtraPar(self, axis, parameter, value): if parameter == 'CloseLoop': self.springfield.setCloseLoop(axis, value) Sardana gives you the choice: we leave it up to you to decide which is the better option for your specific case. .. _sardana-controller-howto-controller-attributes: Extra controller attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Besides extra attributes per axis, you can also define extra attributes at the controller level. In order to do that you have to specify the extra controller attribute(s) within the :attr:`~sardana.pool.controller.Controller.ctrl_attributes` member. The syntax for this dictionary is the same as the one used for :attr:`~sardana.pool.controller.Controller.axis_attributes`. Here is an example on how to specify a read-only float matrix attribute called *ReflectionMatrix* at the controller level: .. code-block:: python class SpringfieldMotorController(MotorController): ctrl_attributes = { "ReflectionMatrix" : { Type : ( (float,), ), Description : "The reflection matrix", Access : DataAccess.ReadOnly, }, } def getReflectionMatrix(self): return ( (1.0, 0.0), (0.0, 1.0) ) Or, similar to what you can do with axis attributes: .. code-block:: python class SpringfieldMotorController(MotorController): ctrl_attributes = \ { "ReflectionMatrix" : { Type : ( (float,), ), Description : "The reflection matrix", Access : DataAccess.ReadOnly, }, } def GetCtrlPar(self, name): if name == "ReflectionMatrix": return ( (1.0, 0.0), (0.0, 1.0) ) .. _sardana-controller-howto-controller-properties: Extra controller properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~ A more static form of attributes can be defined at the controller level. These *properties* are loaded into the controller at the time of object construction. They are accessible to your controller at any time but it is not possible for a user from outside to modify them. The way to define :attr:`~sardana.pool.controller.Controller.ctrl_properties` is very similar to the way you define extra axis attributes or extra controller attributes. Here is an example on how to specify a host and port properties: .. code-block:: python class SpringfieldMotorController(MotorController): ctrl_properties = \ { "host" : { Type : str, Description : "host name" }, "port" : { Type : int, Description : "port number", DefaultValue: springfieldlib.SpringfieldMotorHW.DefaultPort }, } def __init__(self, inst, props, *args, **kwargs): super(SpringfieldMotorController, self).__init__(inst, props, *args, **kwargs) host = self.host port = self.port # initialize hardware communication self.springfield = springfieldlib.SpringfieldMotorHW(host=host, port=port) # do some initialization self._motors = {} As you can see from lines 15 and 16, to access your controller properties simply use ``self.``. Sardana assures that every property has a value. In our case, when a SpringfieldMotorController is created, if port property is not specified by the user (example: using the ``defctrl`` macro in spock), sardana assignes the default value ``springfieldlib.SpringfieldMotorHW.DefaultPort``. On the other hand, since host has no default value, if it is not specified by the user, sardana will complain and fail to create and instance of SpringfieldMotorController. .. _sardana-controller-howto-error-handling: Error handling ~~~~~~~~~~~~~~ When you write a controller it is important to properly handle errors (example: motor power overload, hit a limit switch, lost of communication with the hardware). These are the two basic sardana rules you should have in mind: #. The exceptions which are not handled by the controller are handled by sardana, usually by re-raising the exception (when sardana runs as a Tango_ DS a translation is done from the Python_ exception to a Tango_ exception). The :meth:`~sardana.pool.controller.Controller.StateOne` method is handled a little differently: the state is set to ``Fault`` and the status will contain the exception information. #. When the methods which are supposed to return a value (like :meth:`~sardana.pool.controller.Controller.GetAxisPar`) don't return a value compatible with the expected data type (including :obj:`None`) a :exc:`TypeError` exception is thrown. In every method you should carefully choose how to do handle the possible exceptions/errors. Usually, catch and handle is the best technique since it is the code of your controller which knows exactly the workings of the hardware. You can discriminate errors and decide a proper handle for each. Essencially, this technique consists of: #. catching the error (if an exception: with :keyword:`try` ... :keyword:`except` clause, if an expected return of a function: with a :keyword:`if` ... :keyword:`elif` ... :keyword:`else` statement, etc) #. raise a proper exception (could be the same exception that has been catched) or, if in :meth:`~sardana.pool.controller.Controller.StateOne`, return the apropriate error state (``Fault``, ``Alarm``) and a descriptive status. Here is an example: if the documentation of the underlying library says that: `reading the motor closeloop raises CommunicationFailed if it is not possible to communicate with the Springfield hardware` `reading the motor state raises MotorPowerOverload if the motors has a power overload or a MotorTempTooHigh when the motor temperature is too high` then you should handle the exception in the controller and return a proper state information:: def getCloseLoop(self, axis): # Here the "proper exception" to raise in case of error is actually the # one that is raised from the springfield library so handling the # exception is transparent. Nice! return self.springfield.isCloseLoopActive(axis) def StateOne(self, axis): springfield = self.springfield try: state = self.StateMap[ springfield.getState(axis) ] status = springfield.getStatus(axis) except springfieldlib.MotorPowerOverload: state = State.Fault status = "Motor has a power overload" except springfieldlib.MotorTempTooHigh: temp = springfield.getTemperature(axis) state = State.Alarm status = "Motor temperature is too high (%f degrees)" % temp limit_switches = MotorController.NoLimitSwitch hw_limit_switches = springfield.getLimits(axis) if hw_limit_switches[0]: limit_switches |= MotorController.HomeLimitSwitch if hw_limit_switches[1]: limit_switches |= MotorController.UpperLimitSwitch if hw_limit_switches[2]: limit_switches |= MotorController.LowerLimitSwitch return state, status, limit_switches Hiding the exception is usually a **BAD** technique since it prevents the user from finding what was the cause of the problem. You should only use it in extreme cases (example: if there is a bug in sardana which crashes the server if you try to properly raise an exception, then you can **temporarely** use this technique until the bug is solved). Example:: def getCloseLoop(self, axis): # BAD error handling technique try: return self.springfield.isCloseLoopActive(axis) except: pass .. rubric:: Footnotes .. [#f1] Pseudo controllers don't need to manage their individual axis. Therefore, for pseudos you will not implement these methods .. [#f2] For pseudo controllers, sardana will calculate the state of each pseudo axis based on the state of the elements that serve as input to the pseudo controller. Therefore, for pseudos you will not implement these methods .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_countertimercontroller.rst0000644000234100017500000000674512174204277032302 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-countertimercontroller-howto-basics: ======================================= How to write a counter/timer controller ======================================= The basics ---------- An example of a hypothetical *Springfield* counter/timer controller will be build incrementally from scratch to aid in the explanation. By now you should have read the general controller basics chapter. You should be able to create a CounterTimerController with: - a proper constructor, - add and delete axis methods - get axis state .. code-block:: python import springfieldlib from sardana.pool.controller import CounterTimerController class SpringfieldCounterTimerController(CounterTimerController): def __init__(self, inst, props, *args, **kwargs): super(SpringfieldCounterTimerController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.springfield = springfieldlib.SpringfieldCounterHW() # do some initialization self._counters = {} def AddDevice(self, axis): self._counters[axis] = True def DeleteDevice(self, axis): del self._counters[axis] StateMap = { 1 : State.On, 2 : State.Moving, 3 : State.Fault, } def StateOne(self, axis): springfield = self.springfield state = self.StateMap[ springfield.getState(axis) ] status = springfield.getStatus(axis) return state, status The examples use a :mod:`springfieldlib` module which emulates a counter/timer hardware access library. The :mod:`springfieldlib` can be downloaded from :download:`here `. The Springfield counter/timer controller can be downloaded from :download:`here `. The following code describes a minimal *Springfield* base counter/timer controller which is able to return both the state and value of an individual counter as well as to start an acquisition: .. literalinclude:: sf_ct_ctrl.py :pyobject: SpringfieldBaseCounterTimerController This code is shown only to demonstrate the minimal controller :term:`API`. The advanced counter/timer controller chapters describe how to account for more complex behaviour like reducing the number of hardware accesses. .. todo:: finish counter/timer controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_ioregistercontroller.rst0000644000234100017500000000251212174204277031722 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-ioregistercontroller-howto-basics: ======================================= How to write an I/O register controller ======================================= The basics ---------- .. todo:: document IORegister controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_motorcontroller.rst0000644000234100017500000006243012174204277030713 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-motorcontroller-howto-basics: =============================== How to write a motor controller =============================== The basics ---------- An example of a hypothetical *Springfield* motor controller will be build incrementally from scratch to aid in the explanation. By now you should have read the general controller basics chapter. You should now have a MotorController with a proper constructor, add and delete axis methods: .. code-block:: python import springfieldlib from sardana.pool.controller import MotorController class SpringfieldMotorController(MotorController): def __init__(self, inst, props, *args, **kwargs): super(SpringfieldMotorController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.springfield = springfieldlib.SpringfieldMotorHW() # do some initialization self._motors = {} def AddDevice(self, axis): self._motors[axis] = True def DeleteDevice(self, axis): del self._motor[axis] The *get axis state* method has some details that will be explained below. The examples use a :mod:`springfieldlib` module which emulates a motor hardware access library. The :mod:`springfieldlib` can be downloaded from :download:`here `. The Springfield motor controller can be downloaded from :download:`here `. The following code describes a minimal *Springfield* base motor controller which is able to return both the state and position of a motor as well as move a motor to the desired position: .. literalinclude:: sf_motor_ctrl.py :pyobject: SpringfieldBaseMotorController This code is shown only to demonstrate the minimal controller :term:`API`. The advanced motor controller chapters describe how to account for more complex behaviour like reducing the number of hardware accesses or synchronize motion of multiple motors. .. _sardana-motorcontroller-howto-axis-state: Get motor state ~~~~~~~~~~~~~~~ To get the state of a motor, sardana calls the :meth:`~sardana.pool.controller.Controller.StateOne` method. This method receives an axis as parameter and should return a sequence of three values: To get the state of a motor, sardana calls the :meth:`~sardana.pool.controller.Controller.StateOne` method. This method receives an axis as parameter and should return either: - state (:obj:`~sardana.sardanadefs.State`) or - a sequence of two elements: - state (:obj:`~sardana.sardanadefs.State`) - status (:obj:`str`) *or* limit switches (:obj:`int`) - a sequence of three elements: - state (:obj:`~sardana.sardanadefs.State`) - status (:obj:`str`) - limit switches (:obj:`int`) The state should be a member of :obj:`~sardana.sardanadefs.State` (For backward compatibility reasons, it is also supported to return one of :class:`PyTango.DevState`). The status could be any string. The limit switches is a integer with bits representing the three possible limits: home, upper and lower. Sardana provides three constants which can be *or*\ed together to provide the desired limit switch: .. hlist:: :columns: 4 - :attr:`~MotorController.NoLimitSwitch` - :attr:`~MotorController.HomeLimitSwitch` - :attr:`~MotorController.UpperLimitSwitch` - :attr:`~MotorController.LowerLimitSwitch` To say both home and lower limit switches are active (rare!) you can do:: limit_switches = MotorController.HomeLimitSwitch | MotorController.LowerLimitSwitch If you don't return a status, sardana will compose a status string with: is in If you don't return limit switches, sardana will assume all limit switches are off. Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Controller.StateOne`: .. code-block:: python :emphasize-lines: 11 from sardana import State class SpringfieldMotorController(MotorController): StateMap = { 1 : State.On, 2 : State.Moving, 3 : State.Fault, } def StateOne(self, axis): springfield = self.springfield state = self.StateMap[ springfield.getState(axis) ] status = springfield.getStatus(axis) limit_switches = MotorController.NoLimitSwitch hw_limit_switches = springfield.getLimits(axis) if hw_limit_switches[0]: limit_switches |= MotorController.HomeLimitSwitch if hw_limit_switches[1]: limit_switches |= MotorController.UpperLimitSwitch if hw_limit_switches[2]: limit_switches |= MotorController.LowerLimitSwitch return state, status, limit_switches .. _sardana-motorcontroller-howto-value: Get motor position ~~~~~~~~~~~~~~~~~~ To get the motor position, sardana calls the :meth:`~sardana.pool.controller.Readable.ReadOne` method. This method receives an axis as parameter and should return a valid position. Sardana interprets the returned position as a :term:`dial position`. Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Readable.ReadOne`: .. code-block:: python :emphasize-lines: 3 class SpringfieldMotorController(MotorController): def ReadOne(self, axis): position = self.springfield.getPosition(axis) return position .. _sardana-motorcontroller-howto-move: Move a motor ~~~~~~~~~~~~ When an order comes for sardana to move a motor, sardana will call the :meth:`~sardana.pool.controller.Startable.StartOne` method. This method receives an axis and a position. The controller code should trigger the hardware motion. The given position is always the :term:`dial position`. Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Startable.StartOne`: .. code-block:: python :emphasize-lines: 3 class SpringfieldMotorController(MotorController): def StartOne(self, axis, position): self.springfield.move(axis, position) As soon as :meth:`~sardana.pool.controller.Startable.StartOne` is invoked, sardana expects the motor to be moving. It enters a high frequency motion loop which asks for the motor state through calls to :meth:`~sardana.pool.controller.Controller.StateOne`. It will keep the loop running as long as the controller responds with ``State.Moving``. If :meth:`~sardana.pool.controller.Controller.StateOne` raises an exception or returns something other than ``State.Moving``, sardana will assume the motor is stopped and exit the motion loop. For a motion to work properly, it is therefore, **very important** that :meth:`~sardana.pool.controller.Controller.StateOne` responds correctly. .. _sardana-motorcontroller-howto-stop: Stop a motor ~~~~~~~~~~~~ It is possible to stop a motor when it is moving. When sardana is ordered to stop a motor motion, it invokes the :meth:`~sardana.pool.controller.Stopable.StopOne` method. This method receives an axis parameter. The controller should make sure the desired motor is *gracefully* stopped, if possible, respecting the configured motion parameters (like deceleration and base_rate). Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Stopable.StopOne`: .. code-block:: python :emphasize-lines: 3 class SpringfieldMotorController(MotorController): def StopOne(self, axis): self.springfield.stop(axis) .. _sardana-motorcontroller-howto-abort: Abort a motor ~~~~~~~~~~~~~ In a danger situation (motor moving a table about to hit a wall), it is desirable to abort a motion *as fast as possible*. When sardana is ordered to abort a motor motion, it invokes the :meth:`~sardana.pool.controller.Stopable.AbortOne` method. This method receives an axis parameter. The controller should make sure the desired motor is stopped as fast as it can be done, possibly losing track of position. Here is an example of the possible implementation of :meth:`~sardana.pool.controller.Stopable.AbortOne`: .. code-block:: python :emphasize-lines: 3 class SpringfieldMotorController(MotorController): def AbortOne(self, axis): self.springfield.abort(axis) .. note:: The default implementation of :meth:`~sardana.pool.controller.Stopable.StopOne` calls :meth:`~sardana.pool.controller.Stopable.AbortOne` so, if your controller cannot distinguish stopping from aborting, it is sufficient to implement :meth:`~sardana.pool.controller.Stopable.AbortOne`. .. _sardana-motorcontroller-howto-standard-axis-attributes: Standard axis attributes ~~~~~~~~~~~~~~~~~~~~~~~~ By default, sardana expects every axis to have a set of attributes: - acceleration - deceleration - velocity - base rate - steps per unit To set and retrieve the value of these attributes, sardana invokes pair of methods: :meth:`~sardana.pool.controller.Controller.GetAxisPar` /:meth:`~sardana.pool.controller.Controller.SetAxisPar` Here is an example of the possible implementation: .. code-block:: python :emphasize-lines: 3, 18 class SpringfieldMotorController(MotorController): def GetAxisPar(self, axis, name): springfield = self.springfield name = name.lower() if name == "acceleration": v = springfield.getAccelerationTime(axis) elif name == "deceleration": v = springfield.getDecelerationTime(axis) elif name == "base_rate": v = springfield.getMinVelocity(axis) elif name == "velocity": v = springfield.getMaxVelocity(axis) elif name == "step_per_unit": v = springfield.getStepPerUnit(axis) return v def SetAxisPar(self, axis, name, value): springfield = self.springfield name = name.lower() if name == "acceleration": springfield.setAccelerationTime(axis, value) elif name == "deceleration": springfield.setDecelerationTime(axis, value) elif name == "base_rate": springfield.setMinVelocity(axis, value) elif name == "velocity": springfield.setMaxVelocity(axis, value) elif name == "step_per_unit": springfield.setStepPerUnit(axis, value) .. seealso:: :ref:`sardana-motorcontroller-what-to-do` What to do when your hardware motor controller doesn't support steps per unit .. _sardana-motorcontroller-define-position: Define a position ~~~~~~~~~~~~~~~~~ Sometimes it is useful to reset the current position to a certain value. Imagine you are writting a controller for a hardware controller which handles stepper motors. When the hardware is asked for a motor position it will probably answer some value from an internal register which is incremented/decremented each time the motor goes up/down a step. Probably this value as physical meaning so the usual procedure is to move the motor to a known position (home switch, for example) and once there, set a meaningful position to the current position. Some motor controllers support reseting the internal register to the desired value. If your motor controller can do this the implementation is as easy as writting the :meth:`~sardana.pool.controller.MotorController.DefinePosition` and call the proper code of your hardware library to do it: .. code-block:: python class SpringfieldMotorController(MotorController): def DefinePosition(self, axis, position): self.springfield.setCurrentPosition(axis, position) .. seealso:: :ref:`sardana-motorcontroller-what-to-do` What to do when your hardware motor controller doesn't support defining the position .. _sardana-motorcontroller-what-to-do: What to do when... ~~~~~~~~~~~~~~~~~~ This chapter describes common difficult situations you may face when writting a motor controller in sardana, and possible solutions to solve them. *my controller doesn't support steps per unit* Many (probably, most) hardware motor controllers don't support steps per unit at the hardware level. This means that your sardana controller should be able to emulate steps per unit at the software level. This can be easily done, but it requires you to make some changes in your code. We will assume now that the Springfield motor controller doesn't support steps per unit feature. The first that needs to be done is to modify the :meth:`~sardana.pool.controller.Controller.AddDevice` method so it is able to to store the resulting conversion factor between the hardware read position and the position the should be returned (the *step_per_unit*). The :meth:`~sardana.pool.controller.Readable.ReadOne` also needs to be rewritten to make the proper calculation. Finally :meth:`~sardana.pool.controller.Controller.GetAxisPar` / :meth:`~sardana.pool.controller.Controller.SetAxisPar` methods need to be rewritten to properly get/set the step per unit value: .. code-block:: python class SpringfieldMotorController(MotorController): def AddDevice(self, axis): self._motor[axis] = dict(step_per_unit=1.0) def ReadOne(self, axis): step_per_unit = self._motor[axis]["step_per_unit"] position = self.springfield.getPosition(axis) return position / step_per_unit def GetAxisPar(self, axis, name): springfield = self.springfield name = name.lower() if name == "acceleration": v = springfield.getAccelerationTime(axis) elif name == "deceleration": v = springfield.getDecelerationTime(axis) elif name == "base_rate": v = springfield.getMinVelocity(axis) elif name == "velocity": v = springfield.getMaxVelocity(axis) elif name == "step_per_unit": v = self._motor[axis]["step_per_unit"] return v def SetAxisPar(self, axis, name, value): springfield = self.springfield name = name.lower() if name == "acceleration": springfield.setAccelerationTime(axis, value) elif name == "deceleration": springfield.setDecelerationTime(axis, value) elif name == "base_rate": springfield.setMinVelocity(axis, value) elif name == "velocity": springfield.setMaxVelocity(axis, value) elif name == "step_per_unit": self._motor[axis]["step_per_unit"] = value *my controller doesn't support defining the position* Some controllers may not be able to reset the position to a different value. In these cases, your controller code should be able to emulate such a feature. This can be easily done, but it requires you to make some changes in your code. We will now assume that the Springfield motor controller doesn't support steps per unit feature. The first thing that needs to be done is to modify the :meth:`~sardana.pool.controller.Controller.AddDevice` method so it is able to store the resulting offset between the hardware read position and the position the should be returned (the *define_position_offset*). The :meth:`~sardana.pool.controller.Readable.ReadOne` also needs to be rewritten to take the *define_position_offset* into account. Finally :meth:`~sardana.pool.controller.MotorController.DefinePosition` needs to be written to update the *define_position_offset* to the desired value: .. code-block:: python class SpringfieldMotorController(MotorController): def AddDevice(self, axis): self._motor[axis] = dict(define_position_offset=0.0) def ReadOne(self, axis): dp_offset = self._motor[axis]["define_position_offset"] position = self.springfield.getPosition(axis) return position + dp_offset def DefinePosition(self, axis, position): current_position = self.springfield.getPosition(axis) self._motor[axis]["define_position_offset"] = position - current_position Advanced topics --------------- .. _sardana-motorcontroller-howto-timestamp-position: Timestamp a motor position ~~~~~~~~~~~~~~~~~~~~~~~~~~ When you read the position of a motor from the hardware sometimes it is necessary to associate a timestamp with that position so you can track the position of a motor in time. If sardana is executed as a Tango device server, reading the position attribute from the motor device triggers the execution of your controller's :meth:`~sardana.pool.controller.Readable.ReadOne` method. Tango responds with the value your controller returns from the call to :meth:`~sardana.pool.controller.Readable.ReadOne` and automatically assigns a timestamp. However this timestamp has a certain delay since the time the value was actually read from hardware and the time Tango generates the timestamp. To avoid this, sardana supports returning in :meth:`~sardana.pool.controller.Readable.ReadOne` an object that contains both the value and the timestamp instead of the usual :class:`numbers.Number`. The object must be an instance of :class:`~sardana.sardanavalue.SardanaValue`. Here is an example of associating a timestamp in :meth:`~sardana.pool.controller.Readable.ReadOne`: .. code-block:: python import time from sardana.pool.controller import SardanaValue class SpringfieldMotorController(MotorController): def ReadOne(self, axis): return SardanaValue(value=self.springfield.getPosition(axis), timestamp=time.time()) If your controller communicates with a Tango device, Sardana also supports returning a :class:`~PyTango.DeviceAttribute` object. Sardana will use this object's value and timestamp. Example: .. code-block:: python class TangoMotorController(MotorController): def ReadOne(self, axis): return self.device.read_attribute("position") .. _sardana-motorcontroller-howto-mutiple-motion: Multiple motion synchronization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This chapter describes an extended :term:`API` that allows you to better synchronize motions involing more than one motor, as well as optimize hardware communication (in case the hardware interface also supports this). Often it is the case that the experiment/procedure the user runs requires to move more than one motor at the same time. Imagine that the user requires motor at axis 1 to be moved to 100mm and motor axis 2 to be moved to -20mm. Your controller will receive two consecutive calls to :meth:`~sardana.pool.controller.Startable.StartOne`: .. code-block:: python StartOne(1, 100) StartOne(2, -20) and each StartOne will probably connect to the hardware (through serial line, socket, Tango_ or EPICS_) and ask the motor to be moved. This will do the job but, there will be a slight desynchronization between the two motors because hardware call of motor 1 will be done before hardware call to motor 2. Sardana provides an extended *start motion* which gives you the possibility to improve the syncronization (and probably reduce communications) but your hardware controller must somehow support this feature as well. The complete start motion :term:`API` consists of four methods: - :meth:`~sardana.pool.controller.Startable.PreStartAll` - :meth:`~sardana.pool.controller.Startable.PreStartOne` - :meth:`~sardana.pool.controller.Startable.StartOne` - :meth:`~sardana.pool.controller.Startable.StartAll` Except for :meth:`~sardana.pool.controller.Startable.StartOne`, the implemenation of all other start methods is optional and their default implementation does nothing (:meth:`~sardana.pool.controller.Startable.PreStartOne` actually returns ``True``). So, actually, the complete algorithm for motor motion in sardana is:: /FOR/ Each controller(s) implied in the motion - Call PreStartAll() /END FOR/ /FOR/ Each motor(s) implied in the motion - ret = PreStartOne(motor to move, new position) - /IF/ ret is not true /RAISE/ Cannot start. Motor PreStartOne returns False - /END IF/ - Call StartOne(motor to move, new position) /END FOR/ /FOR/ Each controller(s) implied in the motion - Call StartAll() /END FOR/ So, for the example above where we move two motors, the complete sequence of calls to the controller is: .. code-block:: python PreStartAll() if not PreStartOne(1, 100): raise Exception("Cannot start. Motor(1) PreStartOne returns False") if not PreStartOne(2, -20): raise Exception("Cannot start. Motor(2) PreStartOne returns False") StartOne(1, 100) StartOne(2, -20) StartAll() Sardana assures that the above sequence is never interrupted by other calls, like a call from a different user to get motor state. Suppose the springfield library tells us in the documentation that: ... to move multiple motors at the same time use:: moveMultiple(seq>) Example:: moveMultiple([[1, 100], [2, -20]]) We can modify our motor controller to take profit of this hardware feature: .. code-block:: python class SpringfieldMotorController(MotorController): def PreStartAll(self): # clear the local motion information dictionary self._moveable_info = [] def StartOne(self, axis, position): # store information about this axis motion motion_info = axis, position self._moveable_info.append(motion_info) def StartAll(self): self.springfield.moveMultiple(self._moveable_info) A similar principle applies when sardana asks for the state and position of multiple axis. The two sets of methods are, in these cases: .. hlist:: :columns: 2 - :meth:`~sardana.pool.controller.Controller.PreStateAll` - :meth:`~sardana.pool.controller.Controller.PreStateOne` - :meth:`~sardana.pool.controller.Controller.StateAll` - :meth:`~sardana.pool.controller.Controller.StateOne` - :meth:`~sardana.pool.controller.Readable.PreReadAll` - :meth:`~sardana.pool.controller.Readable.PreReadOne` - :meth:`~sardana.pool.controller.Readable.ReadAll` - :meth:`~sardana.pool.controller.Readable.ReadOne` The main differences between these sets of methods and the ones from start motion is that :meth:`~sardana.pool.controller.Controller.StateOne` / :meth:`~sardana.pool.controller.Readable.ReadOne` methods are called **AFTER** the corresponding :meth:`~sardana.pool.controller.Controller.StateAll` / :meth:`~sardana.pool.controller.Readable.ReadAll` counterparts and they are expeced to return the state/position of the requested axis. The internal sardana algorithm to read position is:: /FOR/ Each controller(s) implied in the reading - Call PreReadAll() /END FOR/ /FOR/ Each motor(s) implied in the reading - PreReadOne(motor to read) /END FOR/ /FOR/ Each controller(s) implied in the reading - Call ReadAll() /END FOR/ /FOR/ Each motor(s) implied in the reading - Call ReadOne(motor to read) /END FOR/ Here is an example assuming the springfield library tells us in the documentation that: ... to read the position of multiple motors at the same time use:: getMultiplePosition(seq) -> dict Example:: positions = getMultiplePosition([1, 2]) The new improved code could look like this:: class SpringfieldMotorController(MotorController): def PreRealAll(self): # clear the local position information dictionary self._position_info = [] def PreReadOne(self, axis): self._position_info.append(axis) def ReadAll(self): self._positions = self.springfield.getMultiplePosition(self._position_info) def ReadOne(self, axis): return self._positions[axis] .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_pseudocountercontroller.rst0000644000234100017500000000252412174204277032450 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-pseudocountercontroller-howto-basics: ======================================== How to write a pseudo counter controller ======================================== The basics ---------- .. todo:: document pseudo counter controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/howto_pseudomotorcontroller.rst0000644000234100017500000000251212174204277032126 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-pseudomotorcontroller-howto-basics: ====================================== How to write a pseudo motor controller ====================================== The basics ---------- .. todo:: document pseudo motor controller howto .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _Taco: http://www.esrf.eu/Infrastructure/Computing/TACO/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_controllers/index.rst0000644000234100017500000000147712174204277025342 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-controller-howto: =================== Writing controllers =================== This chapter provides the necessary information to write controllers in sardana. An overview of the pool controller concept can be found :ref:`here `. The complete controller :term:`API` can be found :ref:`here `. First, the common interface to all controller types is explained. After, a detailed chapter will focus on each specific controller type: .. toctree:: :maxdepth: 1 howto_controller howto_motorcontroller howto_countertimercontroller howto_0dcontroller howto_1dcontroller howto_2dcontroller howto_ioregistercontroller howto_pseudomotorcontroller howto_pseudocountercontroller sardana-1.2.0/doc/source/devel/howto_controllers/sf_ct_ctrl.py0000644000234100017500000001014112174204277026161 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This file contains the code for an hypothetical Springfield counter/timer controller used in documentation""" import time import springfieldlib from sardana import State from sardana.pool.controller import CounterTimerController class SpringfieldBaseCounterTimerController(CounterTimerController): """The most basic controller intended from demonstration purposes only. This is the absolute minimum you have to implement to set a proper counter controller able to get a counter value, get a counter state and do an acquisition. This example is so basic that it is not even directly described in the documentation""" def __init__(self, inst, props, *args, **kwargs): """Constructor""" super(SpringfieldBaseCounterTimerController, self).__init__(inst, props, *args, **kwargs) self.springfield = springfieldlib.SpringfieldCounterHW() def ReadOne(self, axis): """Get the specified counter value""" return self.springfield.getValue(axis) def StateOne(self, axis): """Get the specified counter state""" springfield = self.springfield state = springfield.getState(axis) if state == 1: return State.On, "Counter is stopped" elif state == 2: return State.Moving, "Counter is acquiring" elif state == 3: return State.Fault, "Counter has an error" def StartAll(self): self.springfield.start_count() def StartOne(self, axis, value=None): """acquire the specified counter""" self.springfield.activate_channel(axis) def LoadOne(self, axis, value): self.springfield.set_master(axis, value) def StopOne(self, axis): """Stop the specified counter""" self.springfield.stop(axis) from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet class SpringfieldCounterTimerController(CounterTimerController): def __init__(self, inst, props, *args, **kwargs): super(SpringfieldCounterTimerController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.springfield = springfieldlib.SpringfieldCounterHW() # do some initialization self._counters = {} def AddDevice(self, axis): self._counters[axis] = True def DeleteDevice(self, axis): del self._counters[axis] StateMap = { 1 : State.On, 2 : State.Moving, 3 : State.Fault, } def StateOne(self, axis): springfield = self.springfield state = self.StateMap[ springfield.getState(axis) ] status = springfield.getStatus(axis) return state, status def ReadOne(self, axis): value = self.springfield.getValue(axis) return value def StartOne(self, axis, position): self.springfield.move(axis, position) def StopOne(self, axis): self.springfield.stop(axis) def AbortOne(self, axis): self.springfield.abort(axis) sardana-1.2.0/doc/source/devel/howto_controllers/sf_motor_ctrl.py0000644000234100017500000001151012174204277026714 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This file contains the code for an hypothetical Springfield motor controller used in documentation""" import springfieldlib from sardana import State from sardana.pool.controller import MotorController class SpringfieldBaseMotorController(MotorController): """The most basic controller intended from demonstration purposes only. This is the absolute minimum you have to implement to set a proper motor controller able to get a motor position, get a motor state and move a motor. This example is so basic that it is not even directly described in the documentation""" MaxDevice = 128 def __init__(self, inst, props, *args, **kwargs): """Constructor""" super(SpringfieldBaseMotorController, self).__init__(inst, props, *args, **kwargs) self.springfield = springfieldlib.SpringfieldMotorHW() def ReadOne(self, axis): """Get the specified motor position""" return self.springfield.getPosition(axis) def StateOne(self, axis): """Get the specified motor state""" springfield = self.springfield state = springfield.getState(axis) if state == 1: return State.On, "Motor is stopped" elif state == 2: return State.Moving, "Motor is moving" elif state == 3: return State.Fault, "Motor has an error" def StartOne(self, axis, position): """Move the specified motor to the specified position""" self.springfield.move(axis, position) def StopOne(self, axis): """Stop the specified motor""" self.springfield.stop(axis) from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet class SpringfieldMotorController(MotorController): axis_attributes = { "CloseLoop" : { Type : bool, Description : "(de)activates the motor close loop algorithm", DefaultValue : False, }, } def getCloseLoop(self, axis): return self.springfield.isCloseLoopActive(axis) def setCloseLoop(self, axis, value): self.springfield.setCloseLoop(axis, value) def __init__(self, inst, props, *args, **kwargs): super(SpringfieldMotorController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.springfield = springfieldlib.SpringfieldMotorHW() # do some initialization self._motors = {} def AddDevice(self, axis): self._motors[axis] = True def DeleteDevice(self, axis): del self._motors[axis] StateMap = { 1 : State.On, 2 : State.Moving, 3 : State.Fault, } def StateOne(self, axis): springfield = self.springfield state = self.StateMap[ springfield.getState(axis) ] status = springfield.getStatus(axis) limit_switches = MotorController.NoLimitSwitch hw_limit_switches = springfield.getLimits(axis) if hw_limit_switches[0]: limit_switches |= MotorController.HomeLimitSwitch if hw_limit_switches[1]: limit_switches |= MotorController.UpperLimitSwitch if hw_limit_switches[2]: limit_switches |= MotorController.LowerLimitSwitch return state, status, limit_switches def ReadOne(self, axis): position = self.springfield.getPosition(axis) return position def StartOne(self, axis, position): self.springfield.move(axis, position) def StopOne(self, axis): self.springfield.stop(axis) def AbortOne(self, axis): self.springfield.abort(axis) def DefinePosition(self, axis, position): self.springfield.setCurrentPosition(axis, position) sardana-1.2.0/doc/source/devel/howto_controllers/springfieldlib.py0000644000234100017500000005260012174204277027042 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This file contains the code for an hypothetical Springfield motor hardware access library. It is intended to be used in the sardana documentation as an aid to writing a sardana motor controller library. If you intend to use this code please put it in a directory accessible to Python or in the same directory as sf_motor_ctrl.py""" __all__ = ["SpringfieldMotorHW", "SpringfieldCounterHW"] import time from math import pow, sqrt class BaseMotion(object): def __init__(self): self.min_vel = -1 self.max_vel = -1 self.accel_time = -1 self.decel_time = -1 self.accel = -1 self.decel = -1 self.init_pos = -1 self.final_pos = -1 self.curr_pos = -1 class Motion(BaseMotion): def __init__(self): BaseMotion.__init__(self) self.close_loop = False self.dsplmnt_reach_max_vel = -1 self.dsplmnt_reach_min_vel = -1 self.dsplmnt = -1 self.curr_instant = -1 self.start_instant = -1 self.positive_dsplmnt = True self.small_motion = False # position where maximum velocity will be reached self.curr_max_vel_pos = -1 # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = -1 # necessary diplacement to reach minimum velocity self.curr_dsplmnt_reach_min_vel = -1 # maximum velocity possible self.curr_max_vel = -1 # time at maximum velocity self.curr_at_max_vel_dsplmnt = -1 # time to reach maximum velocity self.curr_max_vel_time = -1 # time to reach minimum velocity self.curr_min_vel_time = -1 # time at maximum velocity self.curr_at_max_vel_time = -1 # instant when maximum velocity should be reached self.curr_max_vel_instant = -1 # instant when should start decelerating self.curr_min_vel_instant = -1 # time the motion will take self.duration = -1 # instant the motion will end self.final_instant = -1 # steps per unit self.step_per_unit = 1 self.inMotion = False self.lower_ls = float('-inf') self.upper_ls = float('+inf') self.power = True self.enabled = True self.__recalculate_acc_constants() def isCloseLoopActive(self): return self.close_loop def setCloseLoop(self, v): self.close_loop = v def setMinVelocity(self,vi): """ Sets the minimum velocity in ms^-1. A.k.a. base rate""" vi = float(vi) if vi < 0: raise "Minimum velocity must be >= 0" self.min_vel = vi if self.max_vel < self.min_vel: self.max_vel = self.min_vel # force recalculation of accelerations if self.accel_time >= 0: self.setAccelerationTime(self.accel_time) if self.decel_time >= 0: self.setDecelerationTime(self.decel_time) def getMinVelocity(self): return self.min_vel def setMaxVelocity(self,vf): """ Sets the maximum velocity in ms^-1.""" vf = float(vf) if vf <= 0: raise "Maximum velocity must be > 0" self.max_vel = vf if self.min_vel > self.max_vel: self.min_vel = self.max_vel # force recalculation of accelerations if self.accel_time >= 0: self.setAccelerationTime(self.accel_time) if self.decel_time >= 0: self.setDecelerationTime(self.decel_time) def getMaxVelocity(self): return self.max_vel def setAccelerationTime(self,at): """Sets the time to go from minimum velocity to maximum velocity in seconds""" at = float(at) if at <= 0: raise "Acceleration time must be > 0" self.accel_time = at self.accel = (self.max_vel - self.min_vel) / at self.__recalculate_acc_constants() def getAccelerationTime(self): return self.accel_time def setDecelerationTime(self,dt): """Sets the time to go from maximum velocity to minimum velocity in seconds""" dt = float(dt) if dt <= 0: raise "Deceleration time must be > 0" self.decel_time = dt self.decel = (self.min_vel - self.max_vel) / dt self.__recalculate_acc_constants() def getDecelerationTime(self): return self.decel_time def setAcceleration(self,a): """Sets the acceleration in ms^-2""" a = float(a) if a < 0: raise "Acceleration must be >= 0" self.accel = float(a) if a > 0: self.accel_time = (self.max_vel - self.min_vel) / a else: self.accel_time = float('INF') self.__recalculate_acc_constants() def setDeceleration(self,d): """Sets the deceleration in ms^-2""" d = float(d) if d > 0: raise "Deceleration must be <= 0" self.decel = d if d < 0: self.decel_time = (self.min_vel - self.max_vel) / d else: self.decel_time = float('INF') self.__recalculate_acc_constants() def getStepPerUnit(self): return self.step_per_unit def setStepPerUnit(self, spu): self.step_per_unit = spu def __recalculate_acc_constants(self): """precomputations assuming maximum speed can be reached in a motion""" self.dsplmnt_reach_max_vel = 0.5 * self.accel * pow(self.accel_time,2) self.dsplmnt_reach_max_vel += self.min_vel * self.accel_time self.dsplmnt_reach_min_vel = 0.5 * self.decel * pow(self.decel_time,2) self.dsplmnt_reach_min_vel += self.max_vel * self.decel_time def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): """starts a new motion""" if not self.power: raise Exception("Motor is powered off") initial_pos = initial_user_pos * self.step_per_unit final_pos = final_user_pos * self.step_per_unit if self.inMotion: raise Exception("Already in motion") if initial_pos == final_pos: return self.init_pos = initial_pos self.final_pos = final_pos self.curr_pos = initial_pos self.dsplmnt = abs(final_pos - initial_pos) start_instant = start_instant or time.time() self.curr_instant = start_instant self.start_instant = start_instant self.positive_dsplmnt = final_pos >= initial_pos displmnt_not_cnst = self.dsplmnt_reach_max_vel + self.dsplmnt_reach_min_vel self.small_motion = self.dsplmnt < displmnt_not_cnst if self.positive_dsplmnt: self.curr_accel = self.accel self.curr_decel = self.decel else: self.curr_accel = -self.accel self.curr_decel = -self.decel if not self.small_motion: # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = self.dsplmnt_reach_max_vel # necessary diplacement to reach minimum velocity self.curr_dsplmnt_reach_min_vel = self.dsplmnt_reach_min_vel if self.positive_dsplmnt: self.curr_max_vel = self.max_vel self.curr_min_vel = self.min_vel # position where maximum velocity will be reached self.curr_max_vel_pos = self.init_pos + self.curr_dsplmnt_reach_max_vel else: self.curr_max_vel = -self.max_vel self.curr_min_vel = -self.min_vel # position where maximum velocity will be reached self.curr_max_vel_pos = self.init_pos - self.curr_dsplmnt_reach_max_vel # displacement at maximum velocity self.curr_at_max_vel_dsplmnt = self.dsplmnt - (self.curr_dsplmnt_reach_max_vel + self.curr_dsplmnt_reach_min_vel) else: # Small movement # position where maximum velocity will be reached self.curr_max_vel_pos = self.init_pos * self.curr_accel - self.final_pos * self.curr_decel self.curr_max_vel_pos /= self.curr_accel - self.curr_decel # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = abs(self.curr_max_vel_pos - self.init_pos) # necessary diplacement to reach minimum velocity self.curr_dsplmnt_reach_min_vel = abs(self.final_pos - self.curr_max_vel_pos) # maximum velocity possible cnst = 2 * self.curr_accel * self.curr_decel * self.dsplmnt / (self.curr_decel - self.curr_accel) max_vel_2 = pow(self.min_vel, 2) + cnst self.curr_max_vel = sqrt(abs(max_vel_2)) if self.positive_dsplmnt: self.curr_min_vel = self.min_vel else: self.curr_max_vel = -self.curr_max_vel self.curr_min_vel = -self.min_vel # displacement at maximum velocity self.curr_at_max_vel_dsplmnt = 0.0 # time to reach maximum velocity self.curr_max_vel_time = abs((self.curr_max_vel - self.curr_min_vel) / self.curr_accel) # time to reach minimum velocity self.curr_min_vel_time = abs((self.curr_min_vel - self.curr_max_vel) / self.curr_decel) # time at maximum velocity self.curr_at_max_vel_time = abs(self.curr_at_max_vel_dsplmnt / self.curr_max_vel) # instant when maximum velocity should be reached self.curr_max_vel_instant = self.start_instant + self.curr_max_vel_time # instant when should start decelerating self.curr_min_vel_instant = self.curr_max_vel_instant + self.curr_at_max_vel_time # time the motion will take self.duration = self.curr_max_vel_time + self.curr_at_max_vel_time + self.curr_min_vel_time # instant the motion will end self.final_instant = self.start_instant + self.duration # uncomment following line if need output concerning the movement that # has just started # self.info() # ASSERTIONS if self.positive_dsplmnt: assert(self.curr_max_vel_pos >= self.init_pos) assert(self.curr_max_vel_pos <= self.final_pos) else: assert(self.curr_max_vel_pos <= self.init_pos) assert(self.curr_max_vel_pos >= self.final_pos) assert(self.curr_dsplmnt_reach_max_vel >= 0.0) assert(self.curr_dsplmnt_reach_min_vel >= 0.0) assert(self.final_instant >= self.start_instant) assert(self.curr_max_vel <= self.max_vel) assert(self.start_instant <= self.curr_max_vel_instant) assert(self.final_instant >= self.curr_min_vel_instant) assert(self.curr_max_vel_time > 0.0) assert(self.curr_min_vel_time > 0.0) assert(self.duration > 0.0) if self.small_motion: assert(self.curr_max_vel_instant == self.curr_min_vel_instant) assert(self.curr_at_max_vel_time == 0.0) else: assert(self.curr_max_vel_instant <= self.curr_min_vel_instant) assert(self.curr_at_max_vel_time >= 0.0) self.inMotion = True def abortMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() if not self.inMotion: return self.curr_pos self.curr_pos = self.getCurrentPosition(curr_instant) self.inMotion = False return self.curr_pos def isInMotion(self,curr_instant=None): curr_instant = curr_instant or time.time() #we call getCurrentPosition because inside it updates the inMotion flag self.getCurrentPosition(curr_instant) return self.inMotion def setCurrentPosition(self, curr_pos): self.curr_pos = curr_pos self.init_pos = curr_pos def getCurrentPosition(self, curr_instant=None): curr_instant = curr_instant or time.time() self.curr_instant = curr_instant pos = None if self.inMotion: # if motion should be ended... if self.curr_instant >= self.final_instant: self.inMotion = False pos = self.final_pos else: pos = self.init_pos if curr_instant > self.curr_min_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel pos += self.curr_at_max_vel_dsplmnt else: pos -= self.curr_dsplmnt_reach_max_vel pos -= self.curr_at_max_vel_dsplmnt dt = curr_instant - self.curr_min_vel_instant pos += self.curr_max_vel * dt + 0.5 * self.curr_decel * pow(dt,2) elif curr_instant > self.curr_max_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel else: pos -= self.curr_dsplmnt_reach_max_vel dt = curr_instant - self.curr_max_vel_instant pos += self.curr_max_vel * dt else: dt = curr_instant - self.start_instant pos += self.curr_min_vel * dt + 0.5 * self.curr_accel * pow(dt,2) else: pos = self.curr_pos if pos <= self.lower_ls: pos = self.lower_ls self.inMotion = False elif pos >= self.upper_ls: pos = self.upper_ls self.inMotion = False self.curr_pos = pos return pos def setCurrentUserPosition(self, user_pos): self.setCurrentPosition(user_pos*self.step_per_unit) def getCurrentUserPosition(self, curr_instant=None): return self.getCurrentPosition(curr_instant=curr_instant) / self.step_per_unit def hitLowerLimit(self): user_pos = self.curr_pos / self.step_per_unit return user_pos <= self.lower_ls def hitUpperLimit(self): user_pos = self.curr_pos / self.step_per_unit return user_pos >= self.upper_ls def getLowerLimitSwitch(self): return self.lower_ls def setLowerLimitSwitch(self, user_lower_ls): self.lower_ls = user_lower_ls def getUpperLimitSwitch(self): return self.upper_ls def setUpperLimitSwitch(self, user_upper_ls): self.upper_ls = user_upper_ls def turnOn(self): self.power = True def turnOff(self): self.power = False def isTurnedOn(self): return self.power def hasPower(self): return self.power def setPower(self, power): self.power = power def info(self): print "Small movement =",self.small_motion print "length =",self.dsplmnt print "position where maximum velocity will be reached =",self.curr_max_vel_pos print "necessary displacement to reach maximum velocity =",self.curr_dsplmnt_reach_max_vel print "necessary displacement to stop from maximum velocity =",self.curr_dsplmnt_reach_min_vel print "maximum velocity possible =",self.curr_max_vel print "time at top velocity =",self.curr_at_max_vel_time print "displacement at top velocity =",self.curr_at_max_vel_dsplmnt print "time to reach maximum velocity =",self.curr_max_vel_time print "time to reach minimum velocity =",self.curr_min_vel_time print "time the motion will take =",self.duration print "instant when maximum velocity should be reached =",self.curr_max_vel_instant print "instant when should start decelerating =",self.curr_min_vel_instant print "instant the motion will end",self.final_instant print "" print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =",self.dsplmnt_reach_max_vel print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =",self.dsplmnt_reach_min_vel class SpringfieldMotorHW(object): DefaultHost = "localhost" DefaultPort = 10123 def __init__(self, host=DefaultHost, port=DefaultPort): self.host = host self.port = port self._motions = {} def getMotion(self, axis): motion = self._motions.get(axis) if motion is None: self._motions[axis] = motion = Motion() return motion def getState(self, axis): motion = self.getMotion(axis) motion.getCurrentUserPosition() if motion.isInMotion(): return 2 if motion.hitLowerLimit(): return 3 if motion.hitUpperLimit(): return 3 if not motion.hasPower(): return 4 return 1 def getStatus(self, axis): motion = self.getMotion(axis) motion.getCurrentUserPosition() status = "Motor HW is ON" if motion.isInMotion(): status = "Motor HW is MOVING" if motion.hitLowerLimit(): status = "Motor HW is in ALARM. Hit hardware lower limit switch" if motion.hitUpperLimit(): status = "Motor HW is in ALARM. Hit hardware upper limit switch" if not motion.hasPower(): status = "Motor is powered off" return status def getLimits(self, axis): motion = self.getMotion(axis) m.getCurrentUserPosition() switchstate = 3*[False,] if m.hitLowerLimit(): switchstate[2] = True if m.hitUpperLimit(): switchstate[1] = True return switchstate def getPosition(self, axis): motion = self.getMotion(axis) return motion.getCurrentUserPosition() def getAccelerationTime(self, axis): return self.getMotion(axis).getAccelerationTime() def getDecelerationTime(self, axis): return self.getMotion(axis).getDecelerationTime() def getMinVelocity(self, axis): return self.getMotion(axis).getMinVelocity() def getMaxVelocity(self, axis): return self.getMotion(axis).getMaxVelocity() def getStepPerUnit(self, axis): return self.getMotion(axis).getStepPerUnit() def setAccelerationTime(self, axis, v): self.getMotion(axis).setAccelerationTime(v) def setDecelerationTime(self, axis, v): self.getMotion(axis).setDecelerationTime(v) def setMinVelocity(self, axis, v): self.getMotion(axis).setMinVelocity(v) def setMaxVelocity(self, axis, v): self.getMotion(axis).setMaxVelocity(v) def setStepPerUnit(self, axis, v): self.getMotion(axis).setStepPerUnit(v) def isCloseLoopActive(self, axis): return self.getMotion(axis).isCloseLoopActive() def setCloseLoop(self, axis, v): self.getMotion(axis).setCloseLoop(v) def setCurrentPosition(self, axis, position): motion = self.getMotion(axis) motion.offset = position - motion.getCurrentUserPosition() motion.setCurrentUserPosition(position) def move(self, axis, position): t = time.time() motion = self.getMotion(axis) motion.startMotion(motion.getCurrentUserPosition(t), position, t) def stop(self, axis): motion = self.getMotion(axis) motion.abortMotion() def abort(self, axis): motion = self.getMotion(axis) motion.abortMotion() class Channel: def __init__(self,idx): self.idx = idx # 1 based index self.value = 0.0 self.is_counting = False self.active = True class SpringfieldCounterHW(object): DefaultHost = "localhost" DefaultPort = 10124 def __init__(self, host=DefaultHost, port=DefaultPort): self.host = host self.port = port self._channels = {} def getChannel(self, axis): channel = self._channels.get(axis) if channel is None: self._channels[axis] = channel = Channel(axis) return channel def getState(self, axis): channel = self.getChannel(axis) channel.getCurrentUserValue() if channel.isAcquiring(): return 2 if not channel.hasPower(): return 3 return 1 def getStatus(self, axis): channel = self.getChannel(axis) channel.getCurrentUserValue() status = "Counter HW is ON" if channel.isAcquiring(): status = "Counter HW is ACQUIRING" if not channel.hasPower(): status = "Counter is powered OFF" return status def getValue(self, axis): motion = self.getMotion(axis) return motion.getCurrentUserPosition() sardana-1.2.0/doc/source/devel/howto_macros/0000755000234100017500000000000012174204361022400 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/howto_macros/index.rst0000644000234100017500000000037712174204277024256 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.macroserver.macro .. _sardana-macro-howto: ================ Writting macros ================ .. toctree:: :maxdepth: 2 General macro development Scan macro development sardana-1.2.0/doc/source/devel/howto_macros/macros_general.rst0000644000234100017500000012754212174204277026134 0ustar cpascualcpascual00000000000000.. highlight:: python :linenothreshold: 5 .. currentmodule:: sardana.macroserver.macro .. _sardana-macros-howto: =============== Writting macros =============== This chapter provides the necessary information to write macros in sardana. The complete macro :term:`API` can be found :ref:`here `. What is a macro --------------- A macro in sardana describes a specific procedure that can be executed at any time. Macros run inside the *sardana sandbox*. This simply means that each time you run a macro, the system makes sure the necessary environment for it to run safely is ready. Macros can only be written in Python_. A macro can be a :term:`function` or a :term:`class`. In order for a :term:`function` to be recognized as a macro, it **must** be properly *labeled* as a macro (this is done with a special :class:`macro` *decorator*. Details are explaind below). In the same way, for a :term:`class` to be recognized as a macro, it must inherit from a :class:`Macro` super-class. Macros are case sensitive. This means that *helloworld* is a different macro than *HelloWorld*. The choice between writing a macro :term:`function` or a macro :term:`class` depends not only on the type of procedure you want to write, but also (and probably, most importantly) on the type of programming you are most confortable with. If you are a scientist, and you have a programming background on a functional language (like fortran, matlab, SPEC_), then you might prefer to write macro functions. Computer scientists (young ones, specially), on the other hand, often have a background on object oriented languages (Java, C++, C#) and feel more confortable writting macro classes. Classes tend to scale better with the size of a program or library. By writting a macro class you can benefit from all advantages of object-oriented programming. This means that, in theory: - it would reduce the amount of code you need to write - reduce the complexity of your code y by dividing it into small, reasonably independent and re-usable components, that talk to each other using only well-defined interfaces - Improvement of productivity by using easily adaptable pre-defined software components In practice, however, and specially if you don't come from a programming background, writting classes requires a different way of thinking. It will also require you to extend your knowledge in terms of syntax of a programming language. Furthermore, most tasks you will probably need to execute as macros, often don't fit the class paradigm that object-oriented languages offer. If you are writting a sequencial procedure to run an experiment then you are probably better of writting a python function which does the job plain and simple. One reason to write a macro as a class is if, for example, you want to extend the behaviour of the :class:`~sardana.macroserver.macros.standard.mv` macro. In this case, probably you would want to *extend* the existing macro by writting your own macro class which *inherits* from the original macro and this way benefit from most of the functionallity already existing in the original macro. What should and should not be a macro ------------------------------------- The idea of a macro is simply a piece of Python_ code that can be executed from control system interface (:term:`GUI`\/:term:`CLI`). Therefore, anything that you don't need to be executed by the interface should **NOT** be a macro. When you have a big library of functions and classes, the approach to expose them to sardana should be to first carefully decide which procedures should be invoked by a :term:`GUI`\/:term:`CLI` (namely the name of the procedure, which parameters it should receive and if it returns any value). Then write the macro(s) which invoke the code of the original library. Avoid the temptation to convert the functions/classes of the original library into macros because: - This will most certainly break your code (any code that calls a function or class that has been converted to a macro will fail) - It will excessively polute the macro list (imagine a :term:`GUI` with a combo box to select which macro to execute. If you have hundreds of macros it will take forever to find the one to execute even if they are in alphabetical order) How to start writting a macro ----------------------------- Since macros are essencially Python_ code, they reside inside a Python_ file. In sardana, we call a Python_ file which contains macros a *macro library*. At the time of writting, the easiest way to create a new macro is from spock (we are currently working on a macro editor :term:`GUI`). Preparing your text editor ~~~~~~~~~~~~~~~~~~~~~~~~~~ Before launching spock it is important to decide which text editor you will use to write your macros. Unless configured otherwise, spock will use the editor specified by the system environment variable :envvar:`EDITOR`. If this variable is not set, it will default to vi under Linux/Unix and to notepad under Windows. The following line explains how to set the :envvar:`EDITOR` environment variable to gedit under linux using bash shell:: $ export EDITOR=gedit If you choose *gedit* it is important to properly configure it to write Python_ code: Go to :menuselection:`Edit --> Preferences --> Editor` and select: - *Tab width* : 4 - *Insert spaces instead of tabs* .. image:: ../../_static/gedit_config.png If you choose *kwrite* it is important to properly configure it to write Python_ code: Go to :menuselection:`Settings --> Configure editor...` and choose *Editing*: - In *General* tab: - *Tab width* : 4 - *Insert spaces instead of tabulators* - In *Indentation* tab: - *Default indentation mode* : Python - *Indentation width* : 4 .. image:: ../../_static/kwrite_config.png Now you are ready to start writting your macro! Type *spock* on the command line. Once you are in spock, you can use the :class:`~sardana.macroserver.macros.expert.edmac` to create/edit macros. Let's say you want to create a new macro called *hello_world* in a new macro library called *salute*. Just type in: .. sourcecode:: spock LAB-01-D01 [1]: edmac hello_world salute Opening salute.hello_world... Editing... This will bring your favorite editor to life with a macro function template code for the macro *hello_world*. .. image:: ../../_static/macro_edit.png The next chapter will explain how to fill this template with useful code. After you finish editing the macro, save the file, exit the editor and go back to spock. You'll be asked if you want the new code to be load on the server. Just answer 'y'. .. sourcecode:: spock LAB-01-D01 [1]: edmac hello_world salute Openning salute.hello_world... Editing... Do you want to apply the new code on the server? [y] y .. _macro_function_writting: Writing a macro function ------------------------ As mentioned before, macros are just simple Python_ functions which have been *labeled* as macros. In Python_, these labels are called *decorators*. Here is the macro function version of *Hello, World!*:: from sardana.macroserver.macro import macro @macro() def hello_world(self): """This is a hello world macro""" self.output("Hello, World!") **line 1** imports the *macro* symbol from the sardana macro package. :mod:`sardana.macroserver.macro` is the package which contains most symbols you will require from sardana to write your macros. **line 3** this line *decorates* de following function as a macro. It is **crucial** to use this decorator in order for your :term:`function` to be recognized by sardana as a valid macro. **line 4** this line contains the hello_world :term:`function` definition. Every macro needs **at least** one parameter. The first parameter is the macro execution context. It is usually called ``self`` but you can name it anything. This parameter gives you access to the entire context where the macro is being run. Through it, you'll be able to do all sorts of things, from sending text to the output to ask for motors or even execute other macros. **line 5** Documentation for this macro. You should **always** document your macro! **line 6** this line will print *Hello, World!* on your screen. .. note:: If you already know a little about Python_ your are probably wondering why not use ``print "Hello, World!"``? Remember that your macro will be executed by a Sardana server which may be running in a different computer than the computer you are working on. Executing a *normal print* would just print the text in the server. Therefore you need to explicitly say you want the text on the computer you are working and not the server. The way to do it is using :meth:`~sardana.macroserver.macro.Macro.output` instead of print. If you prefer, you can use the context version of Python_ :func:`print` function (it is a bit more powerful than :meth:`~sardana.macroserver.macro.Macro.output`\, and has a slightly different syntax) :: # mandatory first line in your code if you use Python < 3.0 from __future__ import print_function from sardana.macroserver.macro import macro @macro() def hello_world(self): """This is an hello world macro""" self.print("Hello, World!") The following footnote describes how to discover your Python_ version [#f2]_. Remeber that a macro is, for all purposes, a normal Python_ :term:`function`. This means you **CAN** inside a macro write **ANY** valid Python_ code. This includes :keyword:`for` and :keyword:`while` loops, :keyword:`if` ... :keyword:`elif` ... :keyword:`else` conditional execution, etc... :: import numpy.fft @macro() def fft_my_wave(self): wave_device = self.getDevice("sys/tg_test/1") wave = wave_device.wave wave_fft = numpy.fft.fft(wave) Adding parameters to your macro ------------------------------- Standard Python_ allows you to specify parameters to a function by placing comma separated parameter names between the ``()`` in the function definition. The macro :term:`API`, in adition, enforces you to specify some extra parameter information. At first, this may look like a useless complication, but you will apreciate clear benefits soon enough. Here are some of them: - error prevention: a macro will not be allowed to run if the given parameter if of a wrong type - :term:`CLI`\s like Spock will be able to offer autocomplete facilities (press and list of allowed parameters show up) - :term:`GUI`\s can display list of allowed parameter values in combo boxes which gives increased usability and prevents errors - Documentation can be generated automatically So, here is an example on how to define a macro that needs one parameter:: @macro([["moveable", Type.Moveable, None, "moveable to get position"]]) def where_moveable(self, moveable): """This macro prints the current moveable position""" self.output("%s is now at %s", moveable.getName(), moveable.getPosition()) Here is another example on how to define a macro that needs two parameters: - Moveable (motor, pseudo motor) - Float (motor absolute position to go to) :: from sardana.macroserver.macro import macro, Type @macro([ ["moveable", Type.Moveable, None, "moveable to move"], ["position", Type.Float, None, "absolute position"] ]) def move(self, moveable, position): """This macro moves a moveable to the specified position""" moveable.move(position) self.output("%s is now at %s", moveable.getName(), moveable.getPosition()) The parameter information is a :obj:`list` of :obj:`list`\s. Each :obj:`list` being a composed of four elements: - parameter name - parameter type - parameter default value (None means no default value) - parameter description Here is a list of the most common allowed parameter types: - ``Integer``: an integer number - ``Float``: a real number - ``Boolean``: a boolean True or False - ``String``: a string - ``Moveable``: a moveable element (motor, pseudo-motor) - ``Motor``: a pure motor - ``ExpChannel``: an experimental channel (counter/timer, 0D, pseudo-counter, ...) - ``Controller``: a controller - ``ControllerClass``: an existing controller class plugin - ``MacroCode``: a macro - ``MeasurementGroup``: a measurement group - ``Any``: anything, really The complete list of types distributed with sardana is made up by these five simple types: ``Integer``, ``Float``, ``Boolean``, ``String``, ``Any``, plus all available sardana interfaces (:obj:`~sardana.sardanadefs.Interface`) .. _sardana-macro-context: Macro context ------------- One of the most powerfull features of macros is that the entire context of sardana is at your disposal. Simply put, it means you have access to all sardana elements by means of the first parameter on your macro (you can give this parameter any name but usually, by convention it is called ``self``). ``self`` provides access to an extensive catalog of functions you can use in your macro to do all kinds of things. The complete catalog of functions can be found :ref:`here `. Let's say you want to write a macro that explicitly moves a known *theta* motor to a certain position. You could write a macro which receives the motor as parameter but that would be a little silly since you already know beforehand which motor you will move. Instead, a better solution would be to *ask* sardana for a motor named "theta" and use it directly. Here is how you can acomplish that:: @macro([["position", Type.Float, None, "absolute position"]]) def move_theta(self, position): """This macro moves theta to the specified position""" th = self.getMotor("th") th.move(position) self.output("Motor ended at %s", moveable.getPosition()) .. _sardana-macro-calling: Calling other macros from inside your macro ------------------------------------------- One of the functions of the macro decorator is to pass the *knowledge* of all existing macros to your macro. This way, without any special imports, your macro will *know* about all other macros on the system even if they have been written in other files. Lets recreate the two previous macros (*where_moveable* and *move*) to execute two of the macros that exist in the standard macro catalog (:class:`~sardana.macroserver.macros.standard.wm` and :class:`~sardana.macroserver.macros.standard.mv`) Here is the new version of *where_moveable* :: @macro([["moveable", Type.Moveable, None, "moveable to get position"]]) def where_moveable(self, moveable): """This macro prints the current moveable position""" self.wm(moveable) ... and the new version of *move* :: @macro([ ["moveable", Type.Moveable, None, "moveable to move"], ["position", Type.Float, None, "absolute position"] ]) def move(self, moveable, position): """This macro moves a moveable to the specified position""" self.mv(moveable, position) self.output("%s is now at %s", moveable.getName(), moveable.getPosition()) .. _sardana-macro-environment: Accessing environment --------------------- The sardana server provides a global space to store variables, called *environment*. The *environment* is a :term:`dictionary` storing a value for each variable. This *environment* is stored persistently so if the sardana server is restarted the environment is properly restored. Variables are case sensitive. The value of an existing environment variable can be accessed using :meth:`~Macro.getEnv`. Setting the value of an environment variable is done with :meth:`~Macro.setEnv`. For example, we know the ascan macro increments a ``ScanID`` environment variable each time it is executed. The following example executes a scan and outputs the new ``ScanID`` value: .. code-block:: python :emphasize-lines: 7 @macro([["moveable", Type.Moveable, None, "moveable to get position"]]) def fixed_ascan(self, moveable): """This does an ascan starting at 0 ending at 100, in 10 intervals with integration time of 0.1s""" self.ascan(moveable, 0, 100, 10, 0.1) scan_id = self.getEnv('ScanID') self.output("ScanID is now %d", scan_id) .. _sardana-macro-logging: Logging ------- The Macro :term:`API` includes a set of methods that allow you to write log messages with different levels: .. hlist:: :columns: 4 * :meth:`~Macro.debug` * :meth:`~Macro.info` * :meth:`~Macro.warning` * :meth:`~Macro.error` * :meth:`~Macro.critical` * :meth:`~Macro.log` * :meth:`~Macro.output` As you've seen, the special :meth:`~Macro.output` function has the same effect as a print statement (with slightly different arguments). Log messages may have several destinations depending on how your sardana server is configured. At least, one destination of each log message is the client(s) (spock, GUI, other) which are connected to the server. Spock, for example, handles the log messages by printing to the console with different colours. By default, spock prints all log messages with level bigger than :meth:`~Macro.debug` (You can change this behaviour by typing ``debug on`` in spock). Another typical destination for log messages is a log file. Here is an example on how to write a logging information message:: @macro() def lets_log(self): self.info("Starting to execute %s", self.getName()) self.output("Hello, World!") self.info("Finished to executing %s", self.getName()) .. KEEP COMMENTED WHILE CHAPTER IS NOT WRITTEN .. .. seealso:: .. :ref:`log configuration ` .. The sardana log configuration. .. .. _sardana-macro-reporting: Reports ------- Once the report facility has been properly configured, report messages can be sent to the previously configured report file. There are several differences between :ref:`reporting ` and :ref:`logging `. The first difference is that log messages may or may not be recorded, depending on the configured filters on the target (example: log file). A report will always be recorded. Another difference is that report messages are not sent to the clients. The idea of a report is to silently record in a file that something as happened. A third difference is that unlike logs, reports have no message level associated to them (actually since internally the log library is used to report messages, every report record as the predefined level *INFO* but this is just an implementation detail). A report message can be emited at any time in the macro using the :meth:`~Macro.report` method: .. code-block:: python :emphasize-lines: 3 @macro() def lets_report(self): self.report("this is an official report of macro '%s'", self.getName()) This would generate the following report message in the report file: INFO 2012-07-18 09:39:34,943: this is an official report of macro 'lets_report' .. KEEP COMMENTED WHILE CHAPTER IS NOT WRITTEN .. .. seealso:: .. :ref:`Report configuration ` .. The sardana report configuration. .. _sardana-advanced-macro-calling: Advanced macro calls -------------------- As previously explained (see :ref:`calling macros `), you can use the Macro :term:`API` to call other macros from inside your own macro: .. code-block:: python :emphasize-lines: 5 @macro([["moveable", Type.Moveable, None, "moveable to get position"]]) def fixed_ascan(self, moveable): """This does an ascan starting at 0 ending at 100, in 10 intervals with integration time of 0.1s""" self.ascan(moveable, 0, 100, 10, 0.1) An explicit call to :meth:`~Macro.execMacro` would have the same effect: .. code-block:: python :emphasize-lines: 5 @macro([["moveable", Type.Moveable, None, "moveable to get position"]]) def fixed_ascan(self, moveable): """This does an ascan starting at 0 ending at 100, in 10 intervals with integration time of 0.1s""" self.execMacro('ascan', moveable, '0', '100', '10', '0.2') The advantage of using :meth:`~Macro.execMacro` is that it supports passing parameters with different *flavors*: * parameters as strings:: self.execMacro('ascan', motor.getName(), '0', '100', '10', '0.2') * parameters as space separated string:: self.execMacro('ascan %s 0 100 10 0.2' % motor.getName()) * parameters as concrete types:: self.execMacro(['ascan', motor, 0, 100, 10, 0.2]) Sometimes it is desirable to access data generated by the macro we just called. For these cases, the Macro :term:`API` provides a pair of low level methods :meth:`~Macro.createMacro` and :meth:`~Macro.runMacro` together with :meth:`~Macro.data`. Let's say that you need access to the data generated by an ascan. First you call :meth:`~Macro.createMacro` with the same parameter you would give to :meth:`~Macro.execMacro`. This will return a macro object. Afterward you call :meth:`~Macro.runMacro` giving as parameter the macro object returned by :meth:`~Macro.createMacro`. In the end, you can access the data generated by the macro using :meth:`~Macro.data`: .. code-block:: python :emphasize-lines: 6,7,8 @macro([["moveable", Type.Moveable, None, "moveable to get position"]]) def fixed_ascan(self, moveable): """This does an ascan starting at 0 ending at 100, in 10 intervals with integration time of 0.1s""" my_scan = self.createMacro('ascan', moveable, '0', '100', '10', '0.2') self.runMacro(my_scan) print len(my_scan.data) A set of macro call examples can be found :ref:`here `. .. _sardana-macro-class-writting: Writting a macro class ---------------------- This chapter describes an advanced alternative to writting macros as Python_ classes. If words like *inheritance*, *polimorphism* sound like a lawyer's horror movie then you probably should only read this if someone expert in sardana already told you that the task you intend to do cannot be accomplished by writting macro functions. The simplest macro class that you can write **MUST** obey the following rules: * Inherit from :class:`Macro` * Implement the :meth:`~Macro.run` method The :meth:`~Macro.run` method is the place where you write the code of your macro. So, without further delay, here is the *Hello, World!* example:: from sardana.macroserver.macro import Macro class HelloWorld(Macro): """Hello, World! macro""" def run(self): print "Hello, World!" .. _sardana-macro-add-parameters: Let's say you want to pass an integer parameter to your macro. All you have to do is declare the parameter by using the :attr:`~Macro.param_def` Macro member:: from sardana.macroserver.macro import Macro, Type class twice(Macro): """Macro twice. Prints the double of the given value""" param_def = [ [ "value", Type.Float, None, "value to be doubled" ] ] def run(self, value): self.output(2*value) .. note:: As soon as you add a :attr:`~Macro.param_def` you also need to modify the :meth:`~Macro.run` method to support the new paramter(s). A set of macro parameter examples can be found :ref:`here `. .. _sardana-macro-preparing: Preparing your macro for execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Additionaly to the :meth:`~Macro.run` method, you may write a :meth:`~Macro.prepare` method where you may put code to prepare the macro for execution (for example, checking pre-conditions for running the macro). By default, the prepare method is an empty method. Here is an example on how to prepare HelloWorld to run only after year 1989: .. code-block:: python :emphasize-lines: 7 import datetime from sardana.macroserver.macro import Macro class HelloWorld(Macro): """Hello, World! macro""" def prepare(self): if datetime.datetime.now() < datetime.datetime(1990,01,01): raise Exception("HelloWorld can only run after year 1989") def run(self): print "Hello, World!" .. _sardana-macro-plotting: Plotting -------- Remember that your macro will be executed by a Sardana server which may be running in a different computer than the computer you are working on. Executing a normal plot (from :mod:`matplotlib` or :mod:`guiqwt`) would just try to show a plot in the server machine. The macro :term:`API` provides a way to plot graphics from inside your macro whenver the client that runs the macro *understands* the plot request (don't worry, spock does understand!) The plotting :term:`API` is the same used by :mod:`~matplotlib.pyplot`. The :term:`API` is accessible through the macro context (``self``). Here is an example:: import math from numpy import linspace from scipy.integrate import quad from scipy.special import j0 from sardana.macroserver.macro import macro def j0i(x): """Integral form of J_0(x)""" def integrand(phi): return math.cos(x * math.sin(phi)) return (1.0/math.pi) * quad(integrand, 0, math.pi)[0] @macro() def J0_plot(self): """Sample J0 at linspace(0, 20, 200)""" x = linspace(0, 20, 200) y = j0(x) x1 = x[::10] y1 = map(j0i, x1) self.pyplot.plot(x, y, label=r'$J_0(x)$') # self.pyplot.plot(x1, y1, 'ro', label=r'$J_0^{integ}(x)$') self.pyplot.title(r'Verify $J_0(x)=\frac{1}{\pi}\int_0^{\pi}\cos(x \sin\phi)\,d\phi$') self.pyplot.xlabel('$x$') self.pyplot.legend() Running this macro from spock will result in something like: .. image:: ../../_static/macro_plotting1.png Just for fun, the following macro computes a fractal and plots it as an image:: import numpy @macro([["interactions", Type.Integer, None, ""], ["density", Type.Integer, None, ""]]) def mandelbrot(self, interactions, density): x_min, x_max = -2, 1 y_min, y_max = -1.5, 1.5 x, y = numpy.meshgrid(numpy.linspace(x_min, x_max, density), numpy.linspace(y_min, y_max, density)) c = x + 1j * y z = c.copy() fractal = numpy.zeros(z.shape, dtype=numpy.uint8) + 255 finteractions = float(interactions) for n in range(interactions): z *= z z += c mask = (fractal == 255) & (abs(z) > 10) fractal[mask] = 254 * n / finteractions self.pyplot.imshow(fractal) And the resulting image (interactions=20, density=512): .. figure:: ../../_static/macro_fractal.png A set of macro plotting examples can be found :ref:`here `. Known plotting limitations ~~~~~~~~~~~~~~~~~~~~~~~~~~ When you plot from inside a macro with ``self.pyplot.plot``, the sardana server will "ask" spock to execute the desired function with the given parameters. This means that the result of plotting (a sequence of :class:`~matplotlib.line.Line2D`) is not available in the sardana server (since the actual line is in spock). The result of any function call in ``self.pyplot`` will always be None! This means that the following code which works in a normal IPython_ console will **NOT** work inside a macro: .. sourcecode:: spock LAB-01-D01 [1]: line = plot(range(10))[0] LAB-01-D01 [2]: line.set_linewidth(5) Also consider that each time you plot the complete data to be plotted is sent from the server to the client... so please avoid plotting arrays of 10,000,000 points! .. _sardana-macro-input: Asking for user input --------------------- It is possible to ask for user input inside a macro. .. hint:: Asking for input in the middle of long macros will cause the macro to stop and wait for user input. If you write a long macro that might be executed *in the middle of the night* please take the appropriate steps to make sure you don't arrive in the morning and you are faced with a message box waiting for you to answer a question that could be avoided with a proper *default value*. To make sure your macro can run in *unattended* mode make sure that: - it implements the interactive *interface* - every :meth:`~Macro.input` gives a *default_value* :term:`keyword argument ` (read on to see how to meet these requirements) In pure Python_, to ask for user input you can use the :func:`raw_input` (Python 2) / :func:`input` (Python 3) :: >>> answer = raw_input('--> ') --> Monty Python's Flying Circus >>> answer "Monty Python's Flying Circus" The Macro :term:`API` provides a much more powerful version of :meth:`~Macro.input` since it can accept a wide variaty of options. Similar to what happens with :ref:`sardana-macro-plotting`, when input is requested from inside a macro, the question will be sent to the client (example: spock) which ordered the macro to be executed. At this time the macro is stopped waiting for the client to answer. The client must "ask" the user for a proper value and the answer is sent back to the server which then resumes the macro execution. Asking for user input is straightforward: .. code-block:: python :emphasize-lines: 5 @macro() def ask_name(self): """Macro function version to ask for user name""" answer = self.input("What's your name?") self.output("So, your name is '%s'", answer) Executing this macro will make spock popup an Input Dialog Box like this one: .. image:: ../../_static/macro_input.png When you type your name and press :guilabel:`&OK` the macro finishes printing the output: .. sourcecode:: spock LAB-01-D01 [1]: ask_name Non interactive macro 'ask_name' is asking for input (please set this macro interactive to True) So, your name is 'Homer Simpson' The macro prints a warning message saying that the macro was not declared as *interactive*. All macros that request user input **should** be declared as interactive. This is because the sardana server can run a macro in *unattended* mode. When an interactive macro is run in *unattended* mode, all :meth:`~Macro.input` instructions that have a default value will return automatically the default value without asking the user for input. To declare a macro as interactive set the ``interactive`` :term:`keyword argument ` in the macro decorator to ``True`` (default value for ``interactive`` is ``False``), like this: .. code-block:: python :emphasize-lines: 1 @macro(interactive=True) def ask_name(self): """Macro function version to ask for user name""" answer = self.input("What's your name?") self.output("So, your name is '%s'", answer) To declare a macro class as interactive set the ``interactive`` member to ``True`` (default value for ``interactive`` is ``False``), like this: .. code-block:: python :emphasize-lines: 4 class ask_name(Macro): """Macro class version to ask for user name""" interactive = True def run(self): answer = self.input("What's your name?") self.output("So, your name is '%s'", answer) a helper :class:`~imacro` decorator and a :class:`iMacro` class exist which can be used instead of the :class:`macro` decorator and :class:`Macro` class to transparently declare your macro as interactive: .. code-block:: python :emphasize-lines: 1,5,14 from sardana.macroserver.macro import imacro, iMacro # interactive macro function version @imacro() def ask_name(self): """Macro function version to ask for user name""" answer = self.input("What's your name?") self.output("So, your name is '%s'", answer) # interactive macro class version class ask_name(iMacro): """Macro class version to ask for user name""" def run(self): answer = self.input("What's your name?") self.output("So, your name is '%s'", answer) The following sub-chapters explain the different options available for macro user input. Specifying input data type ~~~~~~~~~~~~~~~~~~~~~~~~~~ The default return type of :class:`~Macro.input` is :obj:`str` which mimics the pure Python_ input function. However, often you want to restrict the user input to a specific data type like ``Integer``, ``Float`` or even complex object like ``Moveable`` or to a list of possible options. The macro :class:`~Macro.input` :term:`API` provides an easy way to do this by specifying the concrete data type in the :term:`keyword argument ` *data_type*. The following examples shows how to ask for an ``Integer``, a ``Moveable``, and single/multiple selection from a list of options:: from sardana.macroserver.macro import imacro, Type @imacro() def ask_number_of_points(self): """asks user for the number of points""" nb_points = self.input("How many points?", data_type=Type.Integer) self.output("You selected %d points", nb_points) @imacro() def ask_for_moveable(self): """asks user for a motor""" moveable = self.input("Which moveable?", data_type=Type.Moveable) self.output("You selected %s which is at %f", moveable, moveable.getPosition()) @imacro() def ask_for_car_brand(self): """asks user for a car brand""" car_brands = "Mazda", "Citroen", "Renault" car_brand = self.input("Which car brand?", data_type=car_brands) self.output("You selected %s", car_brand) @imacro() def ask_for_multiple_car_brands(self): """asks user for several car brands""" car_brands = "Mazda", "Citroen", "Renault", "Ferrari", "Porche", "Skoda" car_brands = self.input("Which car brand(s)?", data_type=car_brands, allow_multiple=True) self.output("You selected %s", ", ".join(car_brands)) ... and these are the corresponding dialogs that will popup in spock: |input_integer| |input_moveable| |input_select_radio| |input_select_multiple| Providing a default value ~~~~~~~~~~~~~~~~~~~~~~~~~ Providing a default value is **very important** since it will allow your macro to run in *unattended* mode. When given, the *default_value* :term:`keyword argument ` value type must be compatible with the *data_type* :term:`keyword argument `. Providing a default value is easy. The following examples repeat the previous data type examples giving compatible default values:: from sardana.macroserver.macro import imacro, Type @imacro() def ask_number_of_points(self): """asks user for the number of points""" nb_points = self.input("How many points?", data_type=Type.Integer, default_value=100) self.output("You selected %d points", nb_points) @imacro() def ask_for_moveable(self): """asks user for a motor""" moveable = self.input("Which moveable?", data_type=Type.Moveable, default_value="gap01") self.output("You selected %s which is at %f", moveable, moveable.getPosition()) @imacro() def ask_for_car_brand(self): """asks user for a car brand""" car_brands = "Mazda", "Citroen", "Renault" car_brand = self.input("Which car brand?", data_type=car_brands, default_value=car_brands[1]) self.output("You selected %s", car_brand) @imacro() def ask_for_multiple_car_brands(self): """asks user for several car brands. Default is every other car brand in the list""" car_brands = "Mazda", "Citroen", "Renault", "Ferrari", "Porche", "Skoda" car_brands = self.input("Which car brand(s)?", data_type=car_brands, allow_multiple=True, default_value=car_brands[::2]) self.output("You selected %s", ", ".join(car_brands)) Giving a title ~~~~~~~~~~~~~~ By default, the Dialog window title will contain the name of the macro which triggered user input. You can override the default behaviour with the :term:`keyword argument ` *title*:: @imacro() def ask_peak(self): """asks use for peak current of points with a custom title""" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection") self.output("You selected a peak of %f A", peak) ... and this is the corresponding dialog: |input_float_title| Specifying label and unit ~~~~~~~~~~~~~~~~~~~~~~~~~ The *key* and *unit* :term:`keyword arguments ` can be used to provide additional label and unit information respectively and prevent user mistakes:: @imacro() def ask_peak_v2(self): """asks use for peak current of points with a custom title, default value, label and units""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4) self.output("You selected a %s of %f %s", label, peak, unit) ... and this is the corresponding dialog: |input_float_title_label_unit| Limiting ranges, setting decimal places and step size ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When numeric input is requested, it might be useful to prevent user input outside a certain range. This can be achieved with the *minimum* and *maximum* :term:`keyword arguments `:: @imacro() def ask_peak_v3(self): """asks use for peak current of points with a custom title, default value, label, units and ranges""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0) self.output("You selected a %s of %f %s", label, peak, unit) An additional *step* :term:`keyword argument ` may help increase usability by setting the step size in a input spin box:: @imacro() def ask_peak_v4(self): """asks use for peak current of points with a custom title, default value, label, units, ranges and step size""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0, step=5) self.output("You selected a %s of %f %s", label, peak, unit) When asking for a decimal number, it might be useful to use the *decimals* :term:`keyword argument ` to indicate how many decimal places to show in a input spin box:: @imacro() def ask_peak_v5(self): """asks use for peak current of points with a custom title, default value, label, units, ranges, step size and decimal places""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0, step=5, decimals=2) self.output("You selected a %s of %f %s", label, peak, unit) A set of macro input examples can be found :ref:`here `. Showing progress in long macros ------------------------------- Some of the macros you write may take a long time to execute. It could be useful to provide frequent feedback on the current progress of your macro to prevent users from thinking the system is blocked. The way to do this is by :keyword:`yield`\ing a new progress number in the ode everytime you want to send a progress. The following code shows an example: .. code-block:: python :emphasize-lines: 9 import time @macro([["duration", Type.Integer, 1, "time to sleep (s)"]]) def nap(self, duration): fduration = float(duration) for i in range(duration): time.sleep(1) yield (i+1) / fduration * 100 The important code here is line 9. Everytime the macro execution reaches this line of code, basically it tells sardana to send a progress with the desired value. By default, the value is interpreted has a percentage and should have the range between 0.0 and 100.0. Actually, even if your macro doesn't explicitly send macro progress reports, sardana always generates a 0.0 progress at the beginning of the macro and a last 100.0 progress at the end so for example, in a :term:`GUI`, the progress bar showing the macro progress will always reach the end (unless an error occurs) no matter how you program the progress. |macro_progress| It is possible to generate a progress that doesn't fit the 0 - 100.0 range. The above macro has been modified to send a progress with a customized range: .. code-block:: python :emphasize-lines: 6, 11, 12 import time @macro([["duration", Type.Integer, 1, "time to sleep (s)"]]) def nap(self, duration): status = { 'range' : [0, duration] } fduration = float(duration) for i in range(duration): time.sleep(1) status['step'] = i+1 yield status You may notice that this way, the range can be changed dynamically. A progress bar in a :term:`GUI` is programmed to adjust not only the current progress value but also the ranges so it is safe to change them if necessary. .. rubric:: Footnotes .. [#f1] To find the absolute path for sardana's source code type on the command line ``python -c "import sys, sardana; sys.stdout.write(str(sardana.__path__))"`` .. [#f2] To check which version of Python_ you are using type on the command line ``python -c "import sys; sys.stdout.write(sys.version)"`` .. |input_integer| image:: ../../_static/macro_input_integer.png :align: middle .. |input_moveable| image:: ../../_static/macro_input_moveable.png :align: middle .. |input_select_radio| image:: ../../_static/macro_input_select_radio.png :align: middle .. |input_select_multiple| image:: ../../_static/macro_input_select_multiple.png :align: middle .. |input_float_title| image:: ../../_static/macro_input_float_title.png :align: middle .. |input_float_title_label_unit| image:: ../../_static/macro_input_float_title_label_unit.png :align: middle .. |macro_progress| image:: ../../_static/macro_progress.png :align: middle .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/howto_macros/scan_framework.rst0000644000234100017500000002542412174204277026150 0ustar cpascualcpascual00000000000000 .. currentmodule:: sardana.macroserver.macro .. _sardana-macros-scanframework: ============== Scan Framework ============== In general terms, we call *scan* to a macro that moves one or more motors and acquires data along the path of the motor(s). See the :ref:`introduction to the concept of scan in Sardana `. While a scan macro could be written from scratch, Sardana provides a higher- level API (the *scan framework*) that greatly simplifies the development of scan macros by taking care of the details about synchronization of motors and of acquisitions. The scan framework is implemented in the :mod:`~sardana.macroserver.scan` module, which provides the :class:`~sardana.macroserver.scan.GScan` base class and its specialized derived classes :class:`~sardana.macroserver.scan.SScan` and :class:`~sardana.macroserver.scan.CScan` for step and continuous scans, respectively. Creating a scan macro consists in writing a generic macro (see :ref:`the generic macro writing instructions `) in which an instance of :class:`~sardana.macroserver.scan.GScan` is created (typically in the :meth:`~Macro.prepare` method) which is then invoked in the :meth:`~Macro.run` method. Central to the scan framework is the :meth:`~sardana.macroserver.macro.scan.gscan.GScan.generator` function, which must be passed to the GScan constructor. This generator is a function that allows to construct the path of the scan (see :class:`~sardana.macroserver.scan.GScan` for detailed information on the generator). A basic example on writing a step scan -------------------------------------- Step scans are built using an instance of the :class:`~sardana.macroserver.scan.SScan` class, which requires a step generator that defines the path for the motion. Since in a step scan the data is acquired at each step, the generator controls both the motion and the acquisition. Note that in general, the generator does not need to generate a determinate (or even finite) number of steps. Also note that it is possible to write generators that vary their current step based on the acquired values (e.g., changing step sizes as a function of some counter reading). The :class:`~sardana.macroserver.macros.examples.ascan_demo` macro illustrates the most basic features of a step scan:: class ascan_demo(Macro): """ This is a basic reimplementation of the ascan` macro for demonstration purposes of the Generic Scan framework. The "real" implementation of :class:`sardana.macroserver.macros.ascan` derives from :class:`sardana.macroserver.macros.aNscan` and provides some extra features. """ hints = { 'scan' : 'ascan_demo'} #this is used to indicate other codes that the macro is a scan env = ('ActiveMntGrp',) #this hints that the macro requires the ActiveMntGrp environment variable to be set param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): #parse the user parameters self.start = numpy.array([start_pos], dtype='d') self.final = numpy.array([final_pos], dtype='d') self.integ_time = integ_time self.nr_points = nr_interv+1 self.interv_size = ( self.final - self.start) / nr_interv self.name='ascan_demo' env = opts.get('env',{}) #the "env" dictionary may be passed as an option #create an instance of GScan (in this case, of its child, SScan self._gScan=SScan(self, generator=self._generator, moveables=[motor], env=env) def _generator(self): step = {} step["integ_time"] = self.integ_time #integ_time is the same for all steps for point_no in xrange(self.nr_points): step["positions"] = self.start + point_no * self.interv_size #note that this is a numpy array step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): #just go through the steps yield step @property def data(self): return self._gScan.data #the GScan provides scan data The :class:`~sardana.macroserver.macros.examples.ascan_demo` shows only basic features of the scan framework, but it already shows that writing a step scan macro is mostly just a matter of writing a generator function. It also shows that the :meth:`scan.gscan.GScan.data` method can be used to provide the needed return value of :meth:`~Macro.data` A basic example on writing a continuous scans --------------------------------------------- Continuous scans are built using an instance of the :class:`~sardana.macroserver.scan.CScan` class. Since in the continuous scans the acquisition and motion are decoupled, CScan requires two independent generators: * a *waypoint generator*: which defines the path for the motion in a very similar way as the step generator does for a continuous scan. The steps generated by this generator are also called "waypoints". * a *period generator* which controls the data acquisition steps. Essentially, :class:`~sardana.macroserver.scan.CScan` implements the continuous scan as an acquisition loop (controlled by the period generator) nested within a motion loop (controlled by the waypoint generator). Note that each loop is run on an independent thread, and only limited communication occurs between the two (basically the acquisition starts at the beginning of each movement and ends when a waypoint is reached). The :class:`~sardana.macroserver.macros.examples.ascanc_demo` macro illustrates the most basic features of a continuous scan:: :: class ascanc_demo(Macro): """ This is a basic reimplementation of the ascanc` macro for demonstration purposes of the Generic Scan framework. The "real" implementation of :class:`sardana.macroserver.macros.ascanc` derives from :class:`sardana.macroserver.macros.aNscan` and provides some extra features. """ hints = { 'scan' : 'ascanc_demo'} #this is used to indicate other codes that the macro is a scan env = ('ActiveMntGrp',) #this hints that the macro requires the ActiveMntGrp environment variable to be set param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, integ_time, **opts): self.name='ascanc_demo' #parse the user parameters self.start = numpy.array([start_pos], dtype='d') self.final = numpy.array([final_pos], dtype='d') self.integ_time = integ_time env = opts.get('env',{}) #the "env" dictionary may be passed as an option #create an instance of GScan (in this case, of its child, CScan self._gScan = CScan(self, waypointGenerator=self._waypoint_generator, periodGenerator=self._period_generator, moveables=[motor], env=env) def _waypoint_generator(self): #a very simple waypoint generator! only start and stop points! yield {"positions":self.start, "waypoint_id": 0} yield {"positions":self.final, "waypoint_id": 1} def _period_generator(self): step = {} step["integ_time"] = self.integ_time point_no = 0 while(True): #infinite generator. The acquisition loop is started/stopped at begin and end of each waypoint point_no += 1 step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): yield step .. seealso:: for another example of a continuous scan implementation (with more elaborated waypoint generator), see the code of :class:`~sardana.macroserver.macros.scan.meshc` Hooks support in scans ---------------------- In general, the Hooks API provided by the :class:`~sardana.macroserver.macro.Hookable` base class allows a macro to run other code (the hook callable) at certain points of its execution. The hooks use a "hints" mechanism to pass the receiving macro some extra information on how/when they should be executed. The hints are strings, and its content is not fixed by the API, being up to each macro to identify, use and/or ignore them. You can find some examples of the use of hooks in the :mod:`~sardana.macroserver.macros.examples.hooks` module. In the case of the scan macros, the hooks can be either registered directly via the Hooks API or passed as key:values of the "step" dictionary returned by the scan :meth:`~sardana.macroserver.macro.scan.gscan.GScan.generator` (see :class:`~sardana.macroserver.macro.scan.gscan.GScan` for more details). The hints for a given hook are used by the scan framework to select the moment of the scan execution that the given hook is run. The following is a list of hint strings that scan macros support (other hints are ignored): - 'pre-scan-hooks' : before starting the scan. - 'pre-move-hooks' : for steps: before starting to move. - 'post-move-hooks': for steps: after finishing the move. - 'pre-acq-hooks' : for steps: before starting to acquire. - 'post-acq-hooks' : for steps: after finishing acquisition but before recording the step. - 'post-step-hooks' : for steps: after finishing recording the step. - 'post-scan-hooks' : after finishing the scan See the code of :class:`~sardana.macroserver.macros.examples.hooks.hooked_scan` for a macro that demonstrates the use of the hook points of a scan. Other examples of the :mod:`~sardana.macroserver.macros.examples.hooks` module can be illustrative. Also, note that the Taurus MacroExecutor widget allows the user to dynamically add hooks to existing macros before execution. More examples ------------- Other macros in the :mod:`~sardana.macroserver.macros.examples` module illustrate more features of the scan framework. See also the code of the standard scan macros in the :mod:`~sardana.macroserver.macros.scan` module. Finally, the documentation and code of :class:`~sardana.macroserver.scan.GScan`, :class:`~sardana.macroserver.scan.SScan` and :class:`~sardana.macroserver.scan.CScan` may be helpful. sardana-1.2.0/doc/source/devel/overview/0000755000234100017500000000000012174204361021542 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/devel/overview/index.rst0000644000234100017500000000102312174204300023370 0ustar cpascualcpascual00000000000000.. _sardana-devel-overview: ======== Overview ======== .. toctree:: :maxdepth: 2 Global overview Macro Server Pool Controller Motor Pseudo motor IO register Counter/timer 0D experiment channel 1D experiment channel 2D experiment channel Pseudo counter sardana-1.2.0/doc/source/devel/overview/overview.rst0000644000234100017500000001132612174204300024136 0ustar cpascualcpascual00000000000000.. _sardana-devel-global-overview: ================ Global overview ================ This chapter gives an overview of the sardana architecture and describes each of the different components in some detail. If you find this document to be to technical please consider reading the :ref:`sardana-overview` guide first. The following chapters assume a that you have a minimum knowledge of the Tango_ system and basic computer science. Architecture ------------- Sardana consists of a software library which contains sardana kernel engine, a server and a client library which allow sardana to run as a :term:`client-server ` based distributed control system. The communication protocols between servers and clients are :term:`plug-ins ` in sardana. At this time, the only implemented protocol is Tango_. In earlier versions, sardana was tightly connected to Tango_. This documentation, is therefore centered in the Tango_ server implementation. When other comunication protocols become available, the documentation will be revised. Client applications (both :term:`GUI` and :term:`CLI`) can connect to the sardana server through the high level sardana client :term:`API` or through the low level pure Tango_ channels. Client applications can be build with the purpose of *operating* an existing sardana server or of *configuring* it. Sardana server (:term:`SDS`) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The sardana server consists of a sardana tango device server (:term:`SDS`) running a sardana kernel engine. This server runs as an :term:`OS` :term:`daemon`. Once configured, this server acts as a container of device objects which can be accessed by the outside world as *tango device objects*. Typically, a sardana server will consist of: - a low level **Pool** object which manages all the server objects related to motion control and data acquisition (controllers, motors, counters, experiment channels, etc). - a **Macro Server** object which manages the execution of macros (procedures) and client connection points (called doors). - a set of low level objects (controllers, motors, counters, experiment channels, etc) controlled by the Pool object - a set of **Door** objects managed by the macro server. A Door is the preferred access point from a client application to the to the sardana server .. figure:: /_static/sardana_server.png :width: 400 :align: center A diagram representing a sardana server with its objects A sardana server may contain only a Pool object or a Macro Server object or both. It may **NOT** contain more than one Pool object or more than one Macro Server object. If necessary, your sardana system may be splitted into two (or more) sardana servers. A common configuration is to have a sardana server with a Pool (in this case we call the server a *Device Pool* server) and a second server with a Macro Server (this server is called *MacroServer* server). The following figures show some of the possible alternative configurations .. figure:: /_static/pool_server.png :width: 256 :align: center 1 - Sardana configured to be a single Pool DS (no MacroServer present) .. figure:: /_static/macroserver_server.png :width: 256 :align: center 2 - Sardana configured to be a single MacroServer DS (no Pool present) .. figure:: /_static/macroserver_pool_server.png :width: 256 :align: center 3 - Sardana configured with a MacroServer DS connecting to an underlying Pool DS .. figure:: /_static/sardana_pool_server.png :width: 512 :align: center 4 - Sardana configured with a Sardna DS connecting to another underlying Pool DS The following chapters describe each of the Sardana objects in more detail. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/overview/overview_0D.rst0000644000234100017500000000062012174204300024454 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-0d-overview: ======================= 0D channel overview ======================= .. todo:: document 0D experiment channel overview .. seealso:: :ref:`sardana-0d-api` the 0D experiment channel :term:`API` :class:`~sardana.tango.pool.ZeroDExpChannel.ZeroDExpChannel` the 0D experiment channel tango device :term:`API` sardana-1.2.0/doc/source/devel/overview/overview_1D.rst0000644000234100017500000000061612174204300024462 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-1d-overview: ======================= 1D channel overview ======================= .. todo:: document 1D experiment channel overview .. seealso:: :ref:`sardana-1d-api` the 1D experiment channel :term:`API` :class:`~sardana.tango.pool.OneDExpChannel.OneDExpChannel` the 1D experiment channel tango device :term:`API` sardana-1.2.0/doc/source/devel/overview/overview_2D.rst0000644000234100017500000000061612174204300024463 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-2d-overview: ======================= 2D channel overview ======================= .. todo:: document 2D experiment channel overview .. seealso:: :ref:`sardana-2d-api` the 2D experiment channel :term:`API` :class:`~sardana.tango.pool.TwoDExpChannel.TwoDExpChannel` the 2D experiment channel tango device :term:`API` sardana-1.2.0/doc/source/devel/overview/overview_IOR.rst0000644000234100017500000000055712174204300024653 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-ior-overview: ======================= I/O register overview ======================= .. todo:: document I/O register overview .. seealso:: :ref:`sardana-ior-api` the I/O register :term:`API` :class:`~sardana.tango.pool.IORegister.IORegister` the I/O register tango device :term:`API` sardana-1.2.0/doc/source/devel/overview/overview_controller.rst0000644000234100017500000002151212174204300026377 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-controller-overview: =================== Controller overview =================== Each different hardware object is directly controlled by a software object called *controller*. This object is responsible for mapping the communication between a set of hardware objects (example motors) and the underlying hardware (example: a motor controller crate). The *controller* object is also exposed as a Tango_ device. Usually a controller is capable of handling several hardware objects. For example, a motor controller crate is capable of controlling several motors (generally called *axis* [#]_). The controller objects can be created/deleted/renamed dynamically in a running pool. A specific type of controller needs to be created to handle each specific type of hardware. Therefore, to each type of hardware controller there must be associated a specific controller software component. You can write a specific controller software component (:term:`plug-in`) that is able to communicate with the specific hardware. You can this way extend the initial pool capabilities to talk to all kinds of different hardware. .. figure:: /_static/sardana_server_np200.png :width: 500 :align: center A diagram representing a sardana server with a controller class *NSC200Controller*, an instance of that controller *np200ctrl_1* "connected" to a real hardware and a single motor *npm_1*. A sardana controller is responsible for it's sardana element(s). Example: an Icepap hardware motor controller can *control* up to 128 individual motor axis. In the same way, the coresponding software motor controller *IcepapController* will *own* the individual motor axises. .. figure:: /_static/sardana_server_icepap.png :width: 500 :align: center A diagram representing a sardana server with a controller class *IcepapController*, an instance of that controller *icectrl_1* "connected" to a real hardware and motors *icem_[1..5]*. These are the different types of controllers recognized by sardana: :class:`MotorController` You should use/write a :class:`MotorController` sardana :term:`plug-in` if the the device you want to control has a *moveable* interface. The :class:`MotorController` actually fullfils a *changeable* interface. This means that, for example, a power supply that has a current which you want to *ramp* could also be implemented as a :class:`MotorController`. Example: the Newport NSC200 motor controller :class:`CounterTimerController` This controller type is designed to control a device capable of counting scalar values (and, optionaly have a timer). Example: The National Instruments 6602 8-Channel Counter/Timer :class:`ZeroDController` This controller type is designed to control a device capable of supplying scalar values. The :term:`API` provides a way to obtain a value over a certain acquisition time through different algorithms (average, maximum, integration). Example: an electrometer :class:`OneDController` This controller type is designed to control a device capable of supplying 1D values. It has a very similar :term:`API` to :class:`CounterTimerController` Example: an :term:`MCA` :class:`TwoDController` This controller type is designed to control a device capable of supplying 2D values. It has a very similar :term:`API` to :class:`CounterTimerController` Example: a :term:`CCD` :class:`PseudoMotorController` A controller designed to export *virtual motors* that represent a new view over the actual physical motors. Example: A slit pseudo motor controller provides *gap* and *offset* virtual motors over the physical blades :class:`PseudoCounterController` A controller designed to export *virtual counters* that represent a new view over the actual physical counters/0Ds. :class:`IORegisterController` A controller designed to control hardware registers. Controller plug-ins can be written in Python_ (and in the future in C++). Each controller code is basically a Python_ class that needs to obey a specific :term:`API`. Here is an a extract of the pertinent part of a Python_ motor controller code that is able to talk to a Newport motor controller:: from sardana.pool.controller import MotorController, \ Type, Description, DefaultValue class NSC200Controller(MotorController): """This class is the Tango Sardana motor controller for the Newport NewStep handheld motion controller NSC200. This controller communicates through a Device Pool serial communication channel.""" ctrl_properties = \ { 'SerialCh' : { Type : str, Description : 'Communication channel name for the serial line' }, 'SwitchBox': { Type : bool, Description : 'Using SwitchBox', DefaultValue : False}, 'ControllerNumber' : { Type : int, Description : 'Controller number', DefaultValue : 1 } } def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) self.serial = None self.serial_state_event_id = -1 if self.SwitchBox: self.MaxDevice = 8 def AddDevice(self, axis): if axis > 1 and not self.SwitchBox: raise Exception("Without using a Switchbox only axis 1 is allowed") if self.SwitchBox: self._setCommand("MX", axis) def DeleteDevice(self, axis): pass _STATE_MAP = { NSC200.MOTOR_OFF : State.Off, NSC200.MOTOR_ON : State.On, NSC200.MOTOR_MOVING : State.Moving } def StateOne(self, axis): if self.SwitchBox: self._setCommand("MX", axis) status = int(self._queryCommand("TS")) status = self._STATE_MAP.get(status, State.Unknown) register = int(self._queryCommand("PH")) lower = int(NSC200.getLimitNegative(register)) upper = int(NSC200.getLimitPositive(register)) switchstate = 0 if lower == 1 and upper == 1: switchstate = 6 elif lower == 1: switchstate = 4 elif upper == 1: switchstate = 2 return status, "OK", switchstate def ReadOne(self, axis): try: if self.SwitchBox: self._setCommand("MX", axis) return float(self._queryCommand("TP")) except: raise Exception("Error reading position, axis not available") def PreStartOne(self, axis, pos): return True def StartOne(self, axis, pos): if self.SwitchBox: self._setCommand("MX", axis) status = int(self._queryCommand("TS")) if status == NSC200.MOTOR_OFF: self._setCommand("MO","") self._setCommand("PA", pos) self._log.debug("[DONE] sending position") def StartAll(self): pass def AbortOne(self, axis): if self.SwitchBox: self._setCommand("MX", axis) self._setCommand("ST", "") .. seealso:: :ref:`sardana-controller-howto` How to write controller :term:`plug-in`\s in sardana :ref:`sardana-controller-api` the controller :term:`API` :class:`~sardana.tango.pool.Controller.Controller` the controller tango device :term:`API` .. rubric:: Footnotes .. [#] The term *axis* will be used from here on to refer to the ID of a specific hardware object (like a motor) with respect to its *controller*. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/overview/overview_countertimer.rst0000644000234100017500000000061112174204300026731 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-countertimer-overview: ======================= Counter/timer overview ======================= .. todo:: document counter/timer overview .. seealso:: :ref:`sardana-countertimer-api` the counter/timer :term:`API` :class:`~sardana.tango.pool.CTExpChannel.CTExpChannel` the counter/timer tango device :term:`API` sardana-1.2.0/doc/source/devel/overview/overview_macroserver.rst0000644000234100017500000000654512174204300026555 0ustar cpascualcpascual00000000000000.. _sardana-macroserver-overview: ===================== Macro Server overview ===================== The Macro Server object is the sardana server object which manages all high level sardana objects related to macro execution, namely doors, macro libraries and macros themselves. The main purpose of the Macro Server is to run *macros*. Macros are just pieces of Python_ code (functions or classes) which reside in a macro library (Python_ file). Macros can be written by anyone with knowledge of Python_. The Macro Server is exposed on the sardana server as a Tango_ device. Through configuration, the Macro Server can be told to connect to a Pool device. This is the most common configuration. You can, however, tell the Macro Server to connect to more than one Pool device or to no Pool devices at all. When connected to a Pool device(s), the Macro Server uses the Pool device introspection :term:`API` to discover which elements are available. The existing macros will be able to access these elements (through parameters passed to the macro or using the macro :term:`API`) and act on them. In order to be able to run macros, you must first connect to the Macro Server entry point object called *Door*. A single Macro Server can have many active Doors at the same time but a Door can only run one macro at a time. Each Door is exposed on the sardana server as a Tango_ device. You are not in any way restricted to the standard macros provided by the sardana system. You can write as many macros as you need. Writting your own macros is easy. The macro equivalent of Python_\'s *Hello, World!* example:: from sardana.macroserver.macro import macro @macro() def hello_world(self): self.output("Hello, World!") Here is a simple example of a macro to move any moveable element to a certain value:: from sardana.macroserver.macro import macro, Type @macro([ ["moveable", Type.Moveable, None, "moveable to move"], ["position", Type.Float, None, "absolute position"] ]) def my_move(self, moveable, position): """This macro moves a moveable to the specified position""" moveable.move(position) self.output("%s is now at %s", moveable, moveable.getPosition()) Information on how to write your own sardana macros can be found :ref:`here `. The complete macro :term:`API` can be found :ref:`here `. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/overview/overview_motor.rst0000644000234100017500000000407612174204300025362 0ustar cpascualcpascual00000000000000.. _sardana-motor-overview: .. currentmodule:: sardana.pool ================== Motor overview ================== The motor is one of the most used elements in sardana. A motor represents anything that can be *changed* (and can potentially take some time to do it), so, not only physical motors (like a stepper motors) fit into this category but also, for example, a power supply for which the electrical current can be modified. As it happens with the motor controller hardware and its physical motor(s), a sardana motor is always associated with it's sardana motor controller. .. figure:: /_static/sardana_server_icepap_np200.png :width: 680 :align: center A diagram representing a sardana server with a several motor controllers and their respective motors. The *motor* object is also exposed as a Tango_ device. .. seealso:: :ref:`sardana-motor-api` the motor :term:`API` :class:`~sardana.tango.pool.Motor.Motor` the motor tango device :term:`API` .. :class:`~sardana.pool.poolmotor.PoolMotor` .. the motor class :term:`API` .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/overview/overview_pool.rst0000644000234100017500000000533112174204300025166 0ustar cpascualcpascual00000000000000 .. _sardana-pool-overview: ============== Pool overview ============== The Pool object is the sardana server object which manages all other hardware level sardana objects related with motion control and data acquisition. This object is exposed to the world as a Tango_ device. It's :term:`API` consists of a series of methods (Tango_ commands) and members (Tango_ attributes) which allow external applications to create/remove/rename and monitor the different hardware level sardana objects. The Pool could be seen as a kind of intelligent device container to control the experiment hardware. It has two basic features which are: 1. Hardware access using dynamically created/deleted devices according to the experiment needs 2. Management of some very common and well defined actions regularly done on a laboratory/factory (motion control, data acquisition, etc.) Hardware access --------------- Core hardware access ~~~~~~~~~~~~~~~~~~~~ Most of the times, it is possible to define a list of very common objects found in most of the experiments. Objects commonly used to drive an experiment usually fit in one of the following categories: - *Moveables* - Motor - Pseudo motor - Group of moveables - IORegister (a.k.a. discrete motor) - *Experimental channels* - Counter/Timer - 0D (Multimeter like) - 1D (:term:`MCA` like) - 2D (:term:`CCD` like) - Pseudo Counter - *Communication channels* Each different controlled hardware object will also be exposed as an independent Tango_ class. The sardana device server will embed all these Tango_ classes together. The pool Tango_ device is the "container interface" and allows the user to create/delete classical Tango_ devices which are instances of these embedded classes. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/devel/overview/overview_pseudocounter.rst0000644000234100017500000000062112174204300027111 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-pseudocounter-overview: ======================= Pseudo counter overview ======================= .. todo:: document pseudo counter overview .. seealso:: :ref:`sardana-pseudocounter-api` the pseudo counter :term:`API` :class:`~sardana.tango.pool.PseudoCounter.PseudoCounter` the pseudo counter tango device :term:`API` sardana-1.2.0/doc/source/devel/overview/overview_pseudomotor.rst0000644000234100017500000000060112174204300026570 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool .. _sardana-pseudomotor-overview: ======================= Pseudo motor overview ======================= .. todo:: document pseudo motor overview .. seealso:: :ref:`sardana-pseudomotor-api` the pseudo motor :term:`API` :class:`~sardana.tango.pool.PseudoMotor.PseudoMotor` the pseudo motor tango device :term:`API` sardana-1.2.0/doc/source/devel/guide_coding.rst0000644000234100017500000001102512174204301023037 0ustar cpascualcpascual00000000000000.. _sardana-coding-guide: ============================== Sardana development guidelines ============================== Overview --------- This document describes sardana from the perspective of developers. Most importantly, it gives information for people who want to contribute to the development of sardana. So if you want to help out, read on! How to contribute to sardana ---------------------------- Sardana development is managed with the `Sardana sourceforge project `_. Until release 1.2, a svn repository has been used to host the source code. From then on, the version control will be moved to a git repository. How to checkout sardana from SVN -------------------------------- .. warning:: These instructions will become obsolete as soon as Sardana 1.2 is released because the code development will be moved from SVN to Git. Updated instructions for using Git will be posted ASAP. **For read-only**:: svn co https://svn.code.sf.net/p/sardana/code/trunk Sardana **To being able to commit**:: svn co https://@svn.code.sf.net/p/sardana/code/trunk Sardana .. note:: You must have a sourceforge user account and have SVN write access to the tango-cs project. You can ask write access to any of the tango-cs project administrators. Documentation ------------- All standalone documentation should be written in plain text (``.rst``) files using reStructuredText_ for markup and formatting. All such documentation should be placed in directory :file:`docs/source` of the sardana source tree. The documentation in this location will serve as the main source for sardana documentation and all existing documentation should be converted to this format. Coding conventions ------------------ * In general, we try to follow the standard Python style conventions as described in `Style Guide for Python Code `_ * Code **must** be python 2.6 compatible * Use 4 spaces for indentation * In the same file, different classes should be separated by 2 lines * use ``lowercase`` for module names. If possible prefix module names with the word ``sardana`` (like :file:`sardanautil.py`) to avoid import mistakes. * use ``CamelCase`` for class names * python module first line should be:: #!/usr/bin/env python * python module should contain license information (see template below) * avoid poluting namespace by making private definitions private (``__`` prefix) or/and implementing ``__all__`` (see template below) * whenever a python module can be executed from the command line, it should contain a ``main`` function and a call to it in a ``if __name__ == "__main__"`` like statement (see template below) * document all code using Sphinx_ extension to reStructuredText_ The following code can serve as a template for writting new python modules to sardana:: #!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """A :mod:`sardana` module written for template purposes only""" __all__ = ["SardanaDemo"] __docformat__ = "restructuredtext" class SardanaDemo(object): """This class is written for template purposes only""" def main(): print "SardanaDemo" if __name__ == "__main__": main() .. _Tango: http://www.tango-controls.org/ .. _tango_cs: https://sourceforge.net/projects/tango-cs/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Sphinx: http://sphinx.pocoo.org/ sardana-1.2.0/doc/source/devel/guide_migration.rst0000644000234100017500000001732212174204301023573 0ustar cpascualcpascual00000000000000.. currentmodule:: sardana.pool.controller .. _sardana-migration-guide: =================================== Sardana migration guide =================================== This chapter describes how to migrate different sardana components between the different API versions. How to migrate your macro code =================================== API v0 -> v1 ------------- This chapter describes the necessary steps to fully migrate your macros from *API v0* ( sardana 0.x ) to *API v1* ( sardana 1.x ) Mandatory changes """"""""""""""""" The following are the 2 necessary changes to make your macros work in sardana *API v1*: 1. from:: from macro import Macro, Type, Table, List to:: from sardana.macroserver.macro import Macro, Type, Table, List 2. Parameter type ``Type.Motor`` should be changed ``Type.Moveable``. In **v0** the `Motor` meant any motor (including physical motor, pseudo motor). In **v1**, for consistency, `Motor` means only physical motor and `Moveable` means all moveable elements (including physical motor, pseudo motor). New features in API v1 """"""""""""""""""""""" This chapter is a summary of all new features in *API v1*. 1. Macros can now be functions(see :ref:`sardana-macros-howto`). How to migrate your controller code =================================== API v0 -> v1 ------------- This chapter describes the necessary steps to fully migrate your controller from *API v0* ( sardana 0.x ) to *API v1* ( sardana 1.x ) Mandatory changes """"""""""""""""" The following are the 2 necessary changes to make your controller work in sardana *API v1*: 1. from:: import pool from pool import /PoolUtil to:: from sardana import pool from sardana.pool import PoolUtil from sardana.pool.controller import 2. change contructor from:: def __init__(self, inst, props): code to:: def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) code (and don't forget to call the super class constructor also with args and kwargs). The following change is not mandatory but is necessary in order for your controller to be recognized by the pool to be a *API v1* controller: 3. _log member changed from :class:`logging.Logger` to :class:`taurus.core.util.Logger`. This means that you need to change code from:: self._log.setLevel(logging.INFO) to:: self._log.setLogLevel(logging.INFO) or:: self._log.setLogLevel(taurus.Info) since taurus.Info == logging.INFO. Optional changes """""""""""""""" The following changes are not necessary to make your controller work. The *API v1* supports the *API v0* on these matters. 1. **class members**: #. from: :attr:`~Controller.class_prop` to: :attr:`~Controller.ctrl_properties` #. from: :attr:`~Controller.ctrl_extra_attributes` to: :attr:`~Controller.axis_attributes` #. new feature in *API v1*: :attr:`~Controller.ctrl_attributes` 3. **data types**: #. :meth:`~Controller.StateOne` **return type**: Previously :meth:`~Controller.StateOne` had to return a member of :class:`PyTango.DevState`. Now it **can** instead return a member of :class:`~sardana.sardanadefs.State`. This eliminates the need to import :mod:`PyTango`. #. In *API v0* class member (like :attr:`~Controller.ctrl_extra_attributes`) value for key *type* had to be a string (like 'PyTango.DevString' or 'PyTango.DevDouble'). Now they can be a python type (like str or float). Please check :ref:`sardana-controller-data-type` for more information. 4. **generic controller method names**: #. from: :meth:`~Controller.GetPar` to: :meth:`~Controller.GetAxisPar` #. from: :meth:`~Controller.SetPar` to: :meth:`~Controller.SetAxisPar` #. from: :meth:`~Controller.GetExtraAttributePar` to: :meth:`~Controller.GetAxisExtraPar` #. from: :meth:`~Controller.SetExtraAttributePar` to: :meth:`~Controller.SetAxisExtraPar` #. new feature in *API v1*: :meth:`~Controller.GetCtrlPar`, :meth:`~Controller.SetCtrlPar` #. new feature in *API v1*: :meth:`~Stopable.AbortAll` (has default implementation which calls :meth:`~Stopable.AbortOne` for each axis) 5. **pseudo motor controller method names**: #. from: :meth:`~PseudoMotorController.calc_pseudo` to: :meth:`~PseudoMotorController.CalcPseudo` #. from: :meth:`~PseudoMotorController.calc_physical` to: :meth:`~PseudoMotorController.CalcPhysical` #. from: :meth:`~PseudoMotorController.calc_all_pseudo` to: :meth:`~PseudoMotorController.CalcAllPseudo` #. from: :meth:`~PseudoMotorController.calc_all_physical` to: :meth:`~PseudoMotorController.CalcAllPhysical` #. new feature in *API v1*: :meth:`~PseudoMotorController.GetMotor` #. new feature in *API v1*: :meth:`~PseudoMotorController.GetPseudoMotor` New features in API v1 """"""""""""""""""""""" This chapter is a summary of all new features in *API v1*. *New controller features:* 1. All Controllers now have a :attr:`~Controller.ctrl_attributes` class member to define extra controller attributes (and new methods: :meth:`~Controller.GetCtrlPar`, :meth:`~Controller.SetCtrlPar`) 2. For :attr:`~Controller.ctrl_properties`, :attr:`~Controller.axis_attributes` and :attr:`~Controller.ctrl_extra_attributes`: - new (more pythonic) syntax. Old syntax is still supported: - can replace data type strings for python type ('PyTango.DevDouble' -> float) - Default behavior. Example: before data access needed to be described explicitly. Now it is read-write by default. - support for 2D - new keys 'fget' and 'fset' override default method calls 3. no need to import :mod:`PyTango` (:meth:`~Controller.StateOne` can return sardana.State.On instead of PyTango.DevState.ON) 4. PseudoMotorController has new :meth:`~PseudoMotorController.GetMotor` and :meth:`~PseudoMotorController.GetPseudoMotor` 5. new :meth:`~Stopable.AbortAll` (with default implementation which calls :meth:`~Stopable.AbortOne` for each axis) 6. new :meth:`~Stopable.StopOne` (with default implementation which calls :meth:`~Stopable.AbortOne`) 7. new :meth:`~Stopable.StopAll` (with default implementation which calls :meth:`~Stopable.StoptOne` for each axis) 8. new :meth:`~Controller.GetAxisAttributes` allows features like: 1. per axis customized dynamic attributes 2. Basic interface (example: motor without velocity or acceleration) 3. Discrete motor (declare position has an integer instead of a float). No need for IORegisters anymore 9. New :class:`~MotorController` constants: - :class:`~MotorController.HomeLimitSwitch`; - :class:`~MotorController.UpperLimitSwitch`; - :class:`~MotorController.LowerLimitSwitch` *New acquisition features:* 1. Measurement group has a new *Configuration* attribute which contains the full description of the experiment in JSON format *New Tango API features:* 1. Controllers are now Tango devices 2. Pool has a default PoolPath (points to /poolcontrollers) 3. Create* commands can receive JSON object or an old style list of parameters 4. new CreateElement command (can replace CreateMotor, CreateExpChannel, etc) 5. Pool Abort command: aborts all elements (non pseudo elements) 6. Pool Stop command: stops all elements (non pseudo elements) 7. Controller Abort command: aborts all controller elements 8. Controller Stop command: stops all controller elements 9. Controllers have a LogLevel attribute which allows remote python logging management *Others:* 1. Pool device is a python device :-) 2. many command line parameters help logging, debugging sardana-1.2.0/doc/source/devel/index.rst0000644000234100017500000000053312174204301021530 0ustar cpascualcpascual00000000000000.. _sardana-developers-guide-index: ================= Developer's Guide ================= .. toctree:: :maxdepth: 2 Overview howto_macros/index howto_controllers/index API Migration guide Examples Development guidelines sardana-1.2.0/doc/source/sphinxext/0000755000234100017500000000000012174204361020627 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/sphinxext/ipython_console_highlighting.py0000644000234100017500000001215312174204305027142 0ustar cpascualcpascual00000000000000################################################################################ ## ## This file is part of PyTango, a python binding for Tango ## ## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## PyTango is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## PyTango is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with PyTango. If not, see . ## ################################################################################ """reST directive for syntax-highlighting ipython interactive sessions. XXX - See what improvements can be made based on the new (as of Sept 2009) 'pycon' lexer for the python console. At the very least it will give better highlighted tracebacks. """ #----------------------------------------------------------------------------- # Needed modules # Standard library import re # Third party from pygments.lexer import Lexer, do_insertions from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Comment, Generic from sphinx import highlighting #----------------------------------------------------------------------------- # Global constants line_re = re.compile('.*?\n') #----------------------------------------------------------------------------- # Code begins - classes and functions class IPythonConsoleLexer(Lexer): """ For IPython console output or doctests, such as: .. sourcecode:: ipython In [1]: a = 'foo' In [2]: a Out[2]: 'foo' In [3]: print a foo In [4]: 1 / 0 Notes: - Tracebacks are not currently supported. - It assumes the default IPython prompts, not customized ones. """ name = 'IPython console session' aliases = ['ipython'] mimetypes = ['text/x-ipython-console'] input_prompt = re.compile("(In \[(?P[0-9]+)\]: )|( \.\.\.+:)") output_prompt = re.compile("(Out\[(?P[0-9]+)\]: )|( \.\.\.+:)") continue_prompt = re.compile(" \.\.\.+:") tb_start = re.compile("\-+") def get_tokens_unprocessed(self, text): pylexer = PythonLexer(**self.options) tblexer = PythonTracebackLexer(**self.options) curcode = '' insertions = [] for match in line_re.finditer(text): line = match.group() input_prompt = self.input_prompt.match(line) continue_prompt = self.continue_prompt.match(line.rstrip()) output_prompt = self.output_prompt.match(line) if line.startswith("#"): insertions.append((len(curcode), [(0, Comment, line)])) elif input_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, input_prompt.group())])) curcode += line[input_prompt.end():] elif continue_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, continue_prompt.group())])) curcode += line[continue_prompt.end():] elif output_prompt is not None: # Use the 'error' token for output. We should probably make # our own token, but error is typicaly in a bright color like # red, so it works fine for our output prompts. insertions.append((len(curcode), [(0, Generic.Error, output_prompt.group())])) curcode += line[output_prompt.end():] else: if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item def setup(app): """Setup as a sphinx extension.""" # This is only a lexer, so adding it below to pygments appears sufficient. # But if somebody knows that the right API usage should be to do that via # sphinx, by all means fix it here. At least having this setup.py # suppresses the sphinx warning we'd get without it. pass #----------------------------------------------------------------------------- # Register the extension as a valid pygments lexer highlighting.lexers['ipython'] = IPythonConsoleLexer()sardana-1.2.0/doc/source/sphinxext/sardanaextension.py0000644000234100017500000001436212174204305024553 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """helper methods for sardana sphinx documentation""" __expr = ('or',) def process_type(t, obj_type='class'): t = t.strip() if not t: return '' if t in __expr: return t if t.count(' or '): i = t.index(' or ') return ' '.join(map(process_type, (t[:i],'or', t[i+4:]))) if not t.count('<') or not t.count('>'): return ':%s:`%s`' % (obj_type, t) #process a container template start, stop = t.index('<'), t.index('>') main_type = t[:start] main_type = process_type(main_type) types = t[start+1:stop].split(',') types = ', '.join(map(process_type, types)) return "%s <%s>" % (main_type, types) def process_param(line): new_lines = [] try: prefix, param, desc = line.split(':', 2) p, param_name = param.split() desc = desc.strip() if desc[0] == '(' : pos = desc.find(')') if pos != -1: elem_type = desc[1:pos] klass = process_type(elem_type) desc = desc[pos+1:] new_lines.append('%s:type %s: %s' % (prefix, param_name, klass)) new_lines.append('%s:param %s: %s' % (prefix, param_name, desc)) except Exception, e: print "Sardana sphinx extension: Not able to process param: '%s'" % line print " Reason:",str(e) new_lines.append(line) return new_lines def process_return(line): new_lines = [] try: prefix, param, desc = line.split(':', 2) desc = desc.strip() if desc[0] == '(' : pos = desc.find(')') if pos != -1: elem_type = desc[1:pos] klass = process_type(elem_type) desc = desc[pos+1:] new_lines.append('%s:rtype: %s' % (prefix, klass)) new_lines.append('%s:return: %s' % (prefix, desc)) except Exception, e: print "Sardana sphinx extension: Not able to process 'return': '%s'" % line print " Reason:",str(e) new_lines.append(line) return new_lines def process_raise(line): new_lines = [] try: prefix, param, desc = line.split(':', 2) desc = desc.strip() klass = '' if desc[0] == '(' : pos = desc.find(')') if pos != -1: elem_type = desc[1:pos] klass = "(" + process_type(elem_type, obj_type='exc') + ")" desc = desc[pos+1:] new_lines.append('%s:raise: %s %s' % (prefix, klass, desc)) except Exception, e: print "Sardana sphinx extension: Not able to process 'raise': '%s'" % line print " Reason:", str(e) new_lines.append(line) return new_lines def _is_return(line): ret = line.startswith(':return') ret |= line.startswith(':returns') return ret def _is_param(line): ret = line.startswith(':param') ret |= line.startswith(':parameter') ret |= line.startswith(':arg') ret |= line.startswith(':argument') ret |= line.startswith(':key') ret |= line.startswith(':keyword') return ret def _is_raise(line): ret = line.startswith(':raise') ret |= line.startswith(':except') return ret def process_docstring(app, what, name, obj, options, lines): ret = [] for nb, line in enumerate(lines): line_strip = line.strip() if _is_param(line_strip): ret.extend(process_param(line)) elif _is_return(line_strip): ret.extend(process_return(line)) elif _is_raise(line_strip): ret.extend(process_raise(line)) else: ret.append(line) del lines[:] lines.extend(ret) import inspect from sphinx.util.inspect import getargspec def _format_method_args(obj): if inspect.isbuiltin(obj) or \ inspect.ismethoddescriptor(obj): # can never get arguments of a C function or method return None argspec = getargspec(obj) if argspec[0] and argspec[0][0] in ('cls', 'self'): del argspec[0][0] return inspect.formatargspec(*argspec) def _format_function_args(obj): if inspect.isbuiltin(obj) or \ inspect.ismethoddescriptor(obj): # cannot introspect arguments of a C function or method return None try: argspec = getargspec(obj) except TypeError: # if a class should be documented as function (yay duck # typing) we try to use the constructor signature as function # signature without the first argument. try: argspec = getargspec(obj.__new__) except TypeError: argspec = getargspec(obj.__init__) if argspec[0]: del argspec[0][0] args = inspect.formatargspec(*argspec) # escape backslashes for reST args = args.replace('\\', '\\\\') return args def process_signature(app, what, name, obj, options, signature, return_annotation): if hasattr(obj, "__wrapped__"): if what == "method": from taurus.core.util.wrap import wrapped obj = wrapped(obj) signature = _format_method_args(obj) return signature, return_annotation def setup(app): #app.connect('autodoc-process-docstring', process_docstring) app.connect('autodoc-process-signature', process_signature) sardana-1.2.0/doc/source/sphinxext/spock_console_highlighting.py0000644000234100017500000001240512174204305026567 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """reST directive for syntax-highlighting spock interactive sessions. """ #----------------------------------------------------------------------------- # Needed modules # Standard library import re import copy # Third party from pygments.lexer import Lexer, do_insertions from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Token, Comment, Generic from pygments.style import Style import pygments.styles from sphinx import highlighting #----------------------------------------------------------------------------- # Global constants line_re = re.compile('.*?\n') DftStyle = pygments.styles.get_style_by_name("default") class SpockStyle(DftStyle): styles = copy.copy(DftStyle.styles) styles[Generic.Prompt] = 'bold #00AA00' class SpockConsoleLexer(Lexer): """ For spock console output or doctests, such as: .. sourcecode:: spock LAB-01 [1]: a = 'foo' LAB-01 [2]: a Result [2]: 'foo' LAB-01 [3]: print a foo LAB-01 [4]: 1 / 0 Notes: - Tracebacks are not currently supported. - It assumes the default spock prompts, not customized ones. """ name = 'Spock console session' aliases = ['spock'] mimetypes = ['text/x-spock-console'] input_prompt = re.compile("([a-zA-Z0-9_\-]+ \[(?P[0-9]+)\]: )|( \.\.\.+:)") output_prompt = re.compile("(\s*Result \[(?P[0-9]+)\]: )|( \.\.\.+:)") continue_prompt = re.compile(" \.\.\.+:") tb_start = re.compile("\-+") def get_tokens_unprocessed(self, text): pylexer = PythonLexer(**self.options) tblexer = PythonTracebackLexer(**self.options) curcode = '' insertions = [] for match in line_re.finditer(text): line = match.group() input_prompt = self.input_prompt.match(line) continue_prompt = self.continue_prompt.match(line.rstrip()) output_prompt = self.output_prompt.match(line) if line.startswith("#"): insertions.append((len(curcode), [(0, Comment, line)])) elif line.startswith(""): insertions.append((len(curcode), [(0, Generic.Error, line[9:])])) elif input_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, input_prompt.group())])) curcode += line[input_prompt.end():] elif continue_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, continue_prompt.group())])) curcode += line[continue_prompt.end():] elif output_prompt is not None: # Use the 'error' token for output. We should probably make # our own token, but error is typicaly in a bright color like # red, so it works fine for our output prompts. insertions.append((len(curcode), [(0, Generic.Error, output_prompt.group())])) curcode += line[output_prompt.end():] else: if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item def setup(app): """Setup as a sphinx extension.""" # This is only a lexer, so adding it below to pygments appears sufficient. # But if somebody knows that the right API usage should be to do that via # sphinx, by all means fix it here. At least having this setup.py # suppresses the sphinx warning we'd get without it. pass #----------------------------------------------------------------------------- # Register the extension as a valid pygments lexer highlighting.lexers['spock'] = SpockConsoleLexer() sardana-1.2.0/doc/source/users/0000755000234100017500000000000012174204361017736 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/users/getting_started/0000755000234100017500000000000012174204361023125 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/users/getting_started/index.rst0000644000234100017500000000056112174204301024762 0ustar cpascualcpascual00000000000000 .. _sardana-getting-started: =============== Getting started =============== The next chapters describe the necessary steps to get started with sardana, from installation to having a running system on your machine. .. toctree:: :maxdepth: 1 Obtaining and installing Running the server Running the client sardana-1.2.0/doc/source/users/getting_started/installing.rst0000644000234100017500000001055512174204301026023 0ustar cpascualcpascual00000000000000 .. _sardana-installing: ========== Installing ========== #. Install sardana: #. From easy_install [1]_ :: easy_install -U sardana #. From source code: #. Download the sardana source code: #. from latest stable version of `sardana `_ (|version|) #. from `SVN snapshot `_ #. Extract the downloaded tar.gz into a temporary directory #. type [2]_ :: python setup.py build python setup.py install #. test the installation:: python -c "import sardana; print sardana.Release.version" You can also work from SVN trunk checkout (please look :ref:`here ` for instructions). Windows installation shortcut ----------------------------- This chapter provides a quick shortcut to all windows packages which are necessary to run sardana on your windows machine #. Install all dependencies: #. from `Python(x,y)`_ (by far the easiest choise) #. Download and install a python 2.6/2.7 compatible version of python(x,y) from `here `_ #. from scratch: #. Download and install `PyQwt`_ < 6.0 from `PyQwt downdoad page `_ #. Download and install compatible python from link in the same `PyQwt`_ page #. Download and install compatible `numpy`_ from link in the same `PyQwt`_ page. #. Download and install compatible `PyQt`_ from link in the same `PyQwt`_ page. #. Download and install latest `PyTango`_ from `PyTango downdoad page `_ #. Download and install latest `taurus`_ from `Taurus downdoad page `_ #. Finally download and install latest sardana from `Sardana downdoad page `_ .. _sardana-working-from-svn: Working from SVN ---------------- .. warning:: These instructions will become obsolete as soon as Sardana 1.2 is released because the code development will be moved from SVN to Git. Updated instructions for using Git will be posted ASAP. You can checkout sardana from SVN from the following location:: svn co http://svn.code.sf.net/p/sardana/code/trunk Sardana You can directly execute sardana binaries (Pool, MacroServer, Sardana or spock from the command line):: homer@pc001:~/workspace$ cd Sardana homer@pc001:~/workspace/Sardana$ scripts/Sardana .. rubric:: Footnotes .. [1] This command requires super user previledges on linux systems. If your user has them you can usually prefix the command with *sudo*: ``sudo easy_install -U sardana``. Alternatively, if you don't have administrator previledges, you can install locally in your user directory with: ``easy_install --user sardana`` In this case the executables are located at /.local/bin. Make sure the PATH is pointing there or you execute from there. .. [2] *setup.py install* requires user previledges on linux systems. If your user has them you can usually prefix the command with *sudo*: ``sudo python setup.py install``. Alternatively, if you don't have administrator previledges, you can install locally in your user directory with: ``python setup.py install --user`` In this case the executables are located at /.local/bin. Make sure the PATH is pointing there or you execute from there. .. _numpy: http://numpy.scipy.org/ .. _PLY: http://www.dabeaz.com/ply/ .. _Python(x,y): http://code.google.com/p/pythonxy/ .. _Python: http://www.python.org/ .. _SardanaPypi: http://pypi.python.org/pypi/sardana/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _taurus: http://packages.python.org/taurus/ .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _ESRF: http://www.esrf.eu/ sardana-1.2.0/doc/source/users/getting_started/running_cli.rst0000644000234100017500000001015512174204301026162 0ustar cpascualcpascual00000000000000.. _sardana-getting-started-running-cli: Running the client ---------------------------- After the server has been started, you can start one or more client applications (:term:`CLI`\s and/or :term:`GUI`\s) that connect to the server. Each client connects to a specific *door* on the server. A single sardana can be configured with many *doors* allowing multiple clients to be connected at the same time. When the sardana server was first executed, part of the registration process created one *door* for you so now you just have to start the client application from the command line:: homer@pc001:~$ spock Spock is an `IPython`_ based :term:`CLI`. When you start spock without arguments it will assume a default profile called *spockdoor*. The first time spock is executed, it will inform you that profile *spockdoor* doesn't exist and it will offer to create one. Just answer 'y'. After, it will ask you to which *door* should the default *spockdoor* profile connect to. Select the door name corresponding to your sardana server (*Door_lab-01_1*) and press return. By now you should get an output like this:: homer@pc001:~$ spock Profile 'spockdoor' does not exist. Do you want to create one now ([y]/n)? y Available Door devices from sardanamachine:10000 : Door_lab-01_1 (a.k.a. Door/lab-01/1) Door name from the list? Door_lab-01_1 Storing ipython_config.py in /home/homer/.config/ipython/profile_spockdoor... [DONE] Spock 1.0.0 -- An interactive laboratory application. help -> Spock's help system. object? -> Details about 'object'. ?object also works, ?? prints more. IPython profile: spockdoor Connected to Door_lab-01_1 Door_lab-01_1 [1]: That's it! You now have a running sardana client. Still not impressed, I see! The next chapter describes how to start adding new elements to your sardana environment. Populating your sardana with items ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ One of sardana's goals is to allow you to execute *procedures* (what we call in sardana *macros*, hence from here on we will use the term *macro*). A *macro* is basically a piece of code. You can write macros using the `Python`_ language to do all sorts of things. The sky is the limit here! Sardana comes with a :ref:`catalog of macros` that help users in a laboratory to run their experiments. Most of these *macros* involve interaction with sardana elements like motors and experimental channels. Therefore, the first step in a new sardana demo is to populate your system with some elements. Fortunately, sardana comes with a *macro* called *sar_demo* that does just that. To execute this *macro* just type on the command line :class:`~sardana.macroserver.macros.demo.sar_demo`. You should get an output like this: .. sourcecode:: spock Door_lab-01_1 [1]: sar_demo Creating controllers motctrl01, ctctrl01... [DONE] Creating motors mot01, mot02, mot03, mot04... [DONE] Creating measurement group mntgrp01... [DONE] You should now have in your sardana system a set of simulated motors and counters with which you can play. .. hint:: for clearing sardana from the elements created by the demo, execute :class:`~sardana.macroserver.macros.demo.clear_sar_demo` The next chapter (:ref:`spock `) will give you a complete overview of spock's interface. .. _numpy: http://numpy.scipy.org/ .. _PLY: http://www.dabeaz.com/ply/ .. _Python(x,y): http://code.google.com/p/pythonxy/ .. _Python: http://www.python.org/ .. _SardanaPypi: http://pypi.python.org/pypi/sardana/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _taurus: http://packages.python.org/taurus/ .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _ESRF: http://www.esrf.eu/ sardana-1.2.0/doc/source/users/getting_started/running_server.rst0000644000234100017500000001150212174204301026716 0ustar cpascualcpascual00000000000000.. _sardana-getting-started-running-server: Running Sardana as a tango server --------------------------------- .. note:: if you have Tango <= 7.2.6 without all patches applied, Sardana server will not work due to a known bug. Please follow the instructions from :ref:`sardana-getting-started-running-servers-separately` instead. Sardana is based on a client-server architecture. On the server part, sardana can be setup with many different configurations. Advanced details on sardana server configuration can be found here ****. This chapter describes how to run sardana server with it's simplest configuration. The only decision you have to make is which name you will give to your system. From here on *lab-01* will be used as the system name. Please replace this name with your own system name whenever apropriate. The sardana server is called (guess what) *Sardana*. To start the server just type in the command line:: homer@pc001:~$ Sardana lab-01 The first time the server is executed, it will inform you that server *lab-01* is not registered and it will offer to register it. Just answer 'y'. This will register a new instance of Sardana called *lab-01* and the server will be started. You should get an output like this:: homer@pc001:~$ Sardana lab-01 lab-01 does not exist. Do you wish create a new one (Y/n) ? y DServer/Sardana/Lab-01 has no event channel defined in the database - creating it That't it! You now have a running sardana server. Not very impressive, is it? The :ref:`sardana-getting-started-running-cli` chapter describes how to start up a :term:`CLI` application called *spock* which connects to the sardana server you have just started through an object of type *Door* called *Door_lab-01_1*. You can therefore skip the next chapter and go directly to :ref:`sardana-getting-started-running-cli`. .. _sardana-getting-started-running-servers-separately: Running Pool and MacroServer tango servers separately ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: You should only read this chapter if you have Tango <= 7.2.6 without all patches applied. If you do, please follow in instructions from :ref:`sardana-getting-started-running-server` instead. It is possible to separate sardana server into two different servers (in the first sardana versions, this was actually the only way start the sardana system). These servers are called *Pool* and *MacroServer*. The *Pool* server takes care of hardware communication and *MacroServer* executes procedures (macros) using a connection to Pool(s) server(s). To start the Pool server just type in the command line:: homer@pc001:~$ Pool lab-01 The first time the server is executed, it will inform you that server *lab-01* is not registered and it will offer to register it. Just answer 'y'. This will register a new instance of Pool called *lab-01* and the server will be started. You should get an output like this:: homer@pc001:~$ Pool lab-01 lab-01 does not exist. Do you wish create a new one (Y/n) ? y DServer/Pool/Lab-01 has no event channel defined in the database - creating it Next, start the MacroServer server in the command line:: homer@pc001:~$ MacroServer lab-01 The first time the server is executed, it will inform you that server *lab-01* is not registered and it will offer to register it. Just answer 'y'. Next, it will ask you to which Pool(s) you want your MacroServer to communicate with. Select the previously created Pool from the list, press :kbd:`Return` once and :kbd:`Return` again to finish with Pool selection. This will register a new instance of MacroServer called *lab-01* and the server will be started. You should get an output like this:: homer@pc001:~$ MacroServer lab-01 lab-01 does not exist. Do you wish create a new one (Y/n) ? Pool_lab-01_1 (a.k.a. Pool/lab-01/1) (running) Please select pool to connect to (return to finish): Pool_lab-01_1 Please select pool to connect to (return to finish): DServer/MacroServer/lab-01 has no event channel defined in the database - creating it .. _numpy: http://numpy.scipy.org/ .. _PLY: http://www.dabeaz.com/ply/ .. _Python(x,y): http://code.google.com/p/pythonxy/ .. _Python: http://www.python.org/ .. _SardanaPypi: http://pypi.python.org/pypi/sardana/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _taurus: http://packages.python.org/taurus/ .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _ESRF: http://www.esrf.eu/ sardana-1.2.0/doc/source/users/faq.rst0000644000234100017500000002020312174204302021227 0ustar cpascualcpascual00000000000000 .. _sardana-faq: .. todo:: The FAQ is work-in-progress. Many answers need polishing and mostly links need to be added === FAQ === What is the Sardana SCADA_ and how do I get an overview over the different components? --------------------------------------------------------------------------------------- An overview over the different Sardana components is shown in the following figure: .. image:: /_static/sardana_sketch.png :align: center :width: 500 The basic Sardana SCADA_ philosophy can be found :ref:`here `. How do I install Sardana? ------------------------- The Sardana SCADA_ system consists of different components which have to be installed: * Tango_: The control system middleware and tools * PyTango_: The Python_ language binding for Tango_ * Taurus_: The GUI toolkit which is part of Sardana SCADA_ * The Sardana device pool, macro server and tools The complete sardana installation instructions can be found :ref:`here `. How to work with Taurus_ :term:`GUI`? ------------------------------------- A user documentation for the Taurus_ :term:`GUI` application can be found `here `__. How to produce your own Taurus_ :term:`GUI` panel? -------------------------------------------------- The basic philosophy of Taurus_ :term:`GUI` is to provide automatic :term:`GUI` s which are automatically replaced by more and more specific :term:`GUI` s if these are found. Refer to the `user documentation on TaurusGUI `_ for more details on how to work with panels How to call procedures? ----------------------- The central idea of the Sardana SCADA_ system is to execute procedures centrally. The execution can be started from either: * *spock* offers a command line interface with commands very similar to SPEC_. It is documented :ref:`here `. * Procedures can also be executed with from a :term:`GUI`. Taurus provides `generic widgets for macro execution `__. * Procedures can also be executed in specific :term:`GUI` s and specific Taurus_ widgets. The :term:`API` to execute macros from python code is documented here ****. How to write procedures? ------------------------ User written procedures are central to the Sardana SCADA_ system. Documentation how to write macros can be found :ref:`here `. Macro writers might also find the following documentation interesting: * Documentation on how to debug macros can be found here **** * In addition of the strength of the python language macro writers can interface with common elements (motors, counters) , call other macros and use many utilities provided. The macro :term:`API` can be found :ref:`here `. * Documentation how to document your macros can be found :ref:`here ` How to write scan procedures? ----------------------------- A very common type of procedure is the *scan* where some quantity is varied while recording some other quantities. See the documentation on the :ref:`Sardana Scan API ` How to adapt SARDANA to your own hardware? ------------------------------------------ Sardana is meant to be interfaced to all types of different hardware with all types of control systems. For every new hardware item the specific behavior has to be programmed by writing a controller code. The documentation how to write Sardana controllers and pseudo controllers can be found :ref:`here `. This documentation also includes the :term:`API` which can be used to interface to the specific hardware item. How to add your own file format? -------------------------------- Documentation how to add your own file format can be found here ****. How to use the standard macros? ------------------------------- The list of all standard macros and their usage can be found here ****. How to add conditions in macros? -------------------------------- Executing macros and moving elements can be subject to external conditions (for example an interlock). New types of software interlocks can be easily added to the system and are documented here ****. How to write your own Taurus application? ----------------------------------------- You have basically two possibilities to write your own Taurus_ application Start from get General TaurusGUI and create a configuration file. This approach is documented here ****. Start to write your own Qt application in python starting from the Taurus_ main window. This approach is documented here ****. Which are the standard Taurus graphical GUI components? ------------------------------------------------------- A list of all standard Taurus GUI components together with screen shots and example code can be found here **** How to write your own Taurus widget? ------------------------------------ A tutorial of how to write your own Taurus widget can be found :ref:`here `. How to work with the graphical GUI editor? ------------------------------------------ Taurus_ uses the QtDesigner/QtCreator as a graphical editor. Documentation about `QtDesigner/QtCreator `_. The Taurus_ specific parts :ref:`here `. What are the minimum software requirements for sardana? ------------------------------------------------------- Sardana is developed under GNU/Linux, but should run also on Windows and OS-X. The dependencies for installing Sardana can be found here ****. How to configure the system? ---------------------------- Adding and configuring hardware items on an installation is described here ****. How to write your own Taurus schema? ------------------------------------ Taurus is not dependent on Tango. Other control systems or just python modules can be interfaced to it by writing a schema. This approach is documented here **** and a tutorial can be found here **** What are the interfaces to the macro server and the pool? --------------------------------------------------------- The low level interfaces to the Sardana Device Pool and the Macro server can be found here ****. What are the data file formats used in the system and how can I read them? -------------------------------------------------------------------------- It is easily possible to add your own file format but the standard file formats are documented here: * The SPEC_ file format is documented here **** and here is a list of tools to read it **** * The EDF file format is documented here **** and here is a list of tools to read it **** * The NEXUS file format is documented here **** and here is a list of tools to read it **** What is the file format of the configuration files? --------------------------------------------------- The configuration files for the Taurus_ GUI are defined here ****. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _SCADA: http://en.wikipedia.org/wiki/SCADA .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/users/index.rst0000644000234100017500000000046312174204302021575 0ustar cpascualcpascual00000000000000.. _sardana-users-guide-index: ============ User's Guide ============ .. toctree:: :maxdepth: 2 Overview Getting started Spock Scans Standard macro catalog Screenshots FAQ sardana-1.2.0/doc/source/users/overview.rst0000644000234100017500000002621212174204302022334 0ustar cpascualcpascual00000000000000.. _sardana-overview: ======== Overview ======== Sardana is the control program initially developed at ALBA_. Our mission statement: `Produce a modular, high performance, robust, and generic user environment for control applications in large and small installations. Make Sardana the generic user environment distributed in the Tango project and the standard basis of collaborations in control.` Up to now, control applications in large installations have been notoriously difficult to share. Inspired by the success of the Tango_ collaboration, ALBA_ decided to start the creation of a generic tool to enlarge the scope of the Tango_ project to include a standard client program - or better a standard generic user environment. From the beginning our aim has been to involve others in this process. At this moment in time the user environment consists of a highly configurable standard graphical user interface, a standard command line interface understanding SPEC_ commands, and a standard way to compose new applications either by programming or with a graphical tool. It further consists of a standard macro executer, standard set of macros, a standard range of common hardware types (like motors, counters, cameras and so on) and a configuration editor to set all this up. The origin of the Sardana name comes from a Catalan dance to honor the region where the ALBA_ synchrotron is build. The toolkit to build Sardana has been C++, Python_, Qt_ and Tango_. If you like the tools you will love Sardana. What do we "sell" to our users ============================== Let’s start our excursion into the Sardana world by a word of caution. We will talk a lot about technical possibilities and implementation details. Our users will judge us on the ease of use of the final GUI, its robustness and the features it offers. There are millions of ways to arrive at this end result. Our claim is however that by doing it the *Sardana way* and developing the application out of *lego* components in a collaborative environment we will arrive at higher quality software with much higher efficiency. The following screen shot of an early prototype of a specific beamline application should serve as a reminder of this final goal. .. image:: /_static/snapshot01.png :align: center :width: 500 Inside this application we have many features common to other beamline control applications or w some accelerator applications. The following screen shot shows such a standard application which has been done without programming - just by configuring the application. This illustrates one of the design guidelines in Sardana: Always provide a generic interface which can be specialized for an application. .. image:: /_static/snapshot02.png :align: center :width: 500 Starting a procedure ==================== At the heart of the Sardana system are standard reusable procedures. From past experiences, the importance of standard procedures has been realized and has influenced most of the major design decisions. To illustrate this point, please let me walk you through different ways how to start such a procedure without going into too many details. You might want to think of a *scan* as an example. One way of starting a procedure is with a command line interface. Users familiar with SPEC_ will immediately recognize this way. In effect, inside Sardana most of the standard SPEC_ commands (including many diffractometer geometries thanks to Frédéric Picca from the SOLEIL_ synchrotron) are provided as standard procedures and can be invoked in the same way. .. image:: /_static/snapshot03.png :align: center :width: 500 Every procedure can also be started from a GUI. This does not need any programming or configuration from the user of the system. When a new procedure is created, it is automatically visible inside the GUI and command line tools. .. image:: /_static/snapshot04.png :align: center :width: 500 This GUI interface will mainly be used for procedures which are rarely used and where a specialized interface has not yet been developed. An example of how to use the same procedure in order to carry out energy spread and emittance measurements is presented in the following picture. .. image:: /_static/snapshot05.png :align: center :width: 500 The standard Qt_ designer can be used to create new graphical elements (widgets) and connect them to the system for even greater flexibility. The following screen shot shows the standard qt designer with some fancy widgets developed in house. .. image:: /_static/snapshot06.png :align: center :width: 500 Taurus as a toolkit for applications ==================================== The GUI toolkit for Sardana is called Taurus_. The graphical user interfaces in this paper have been created with this toolkit. It can be used in conjunction or independent from the rest of the system. It can be used to create custom panels inside the generic GUI or to create stand alone applications. Again, this approach of *take what you need* has been implemented to foster the widest range of collaborations. Almost all applications in the ALBA_ machine control system have been created with this toolkit. Creating the applications out of standard components has been proven to be extremely powerful. In the :ref:`sardana-screenshots-guis` chapter you can see some of the graphical user interfaces used. Configure – don’t program ========================= The Sardana system comes with a configuration editor to allow non-experts to add and configure components. The editor adapts dynamically to the hardware controllers present. New hardware controller can be easily written and integrated into the system without restarting it. .. image:: /_static/snapshot07.png :align: center :width: 500 This configuration editor is currently being rewritten to be more wizard based and provide better guidance for the end user. How to write your own procedure =============================== Another example I would like to look into is how to write your own procedure. The simplest possible way is to use an editor to assemble commands and execute them. This batch files type of procedures are useful to automatically run procedures over night and for similar simple applications. The following screen shots show the procedure executer with this feature enabled. .. image:: /_static/snapshot08.png :align: center :width: 500 To go further I would like to explain some internal details. All procedures are executed in a central place (called the macro server). There can be more than one macro server per system but for the following I assume the common case of a unique macro server. This macro server holds all the general procedures centrally. It provides a controlled environment for these procedures. They can be edited, run, debugged under its supervision. This allows for example to automatically roll back changes made in case of problems, log access and grant permissions. The procedures executed in the macro server provided by the current Sardana system are Python_ classes. A class is a way to group the different methods which concerns this procedure. As an example, in some procedures it could be possible to do very specific things in case the user orders an emergency abort of the procedure. The following example shows the procedure to move a motor. As you can see in the example, the procedure must be documented and the input parameters described. From this information, the graphical user interface is constructed. It is also possible now to start the procedure from the command line interface and use the tab key to automatically complete the input. The actual action is actually carried out in the run method. The motor movement is started and the procedure waits until it arrives at its destiny. The Python_ classes should stay small and very simple. All complicated code can be put into modules and tested separately from the system. How to adapt it to your own hardware ==================================== As the system has been thought from the beginning to be used at different institutes, no assumptions of the hardware used could be made. There exists therefore a mechanism to adapt the Sardana system to your own hardware. This adaptor also has another very important role to play. This is best explained with the motor as example. We consider more or less everything which can be changed in the system a motor. The term which should have better been used to describe this thing should have been therefore *movable*. A motor can be a temperature of a temperature controller which can be changed, a motor from an insertion device which needs a highly complicated protocol to be moved, or just about anything. Sometimes we also consider calculated value like H,K,L, the height of a table, and the gap of a slit to be a motor. All these different *motors* can be scanned with the same generic procedures without having to worry about on which elements it is working on. You can add one of these pseudo motors with the configuration editor. It is easily possible to add new types of pseudo motors. This has only to be done once and the Sardana system already provides a large variety of these types. .. image:: /_static/snapshot09.png :align: center :width: 500 Please find in the following an example for adding a completely new type in the case of a *slit*. The actual information how to create a motor of type *slit* is kept in the two methods calc_physical and calc_pseudo which can be used to do the transformation between the different coordinate systems. Or to say it in the language of Sardana between the pseudo motors gap and offset and the real motors left blade and right blade. .. image:: /_static/snapshot10.png :align: center :width: 500 Once again the information in the beginning allows the graphical user interface to be created automatically once it is loaded into the system. Symbolic Sketch =============== I would like to end this summary with a symbolic sketch of the different subsystems in Sardana. .. image:: /_static/sardana_sketch.png :align: center :width: 500 The user will normally not be concerned with these implementation details. It is presented here to allow appreciating the modularity of the system. .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _`PyTango installation steps`: http://packages.python.org/PyTango/start.html#getting-started .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/users/scan.rst0000644000234100017500000001472312174204302021416 0ustar cpascualcpascual00000000000000 .. currentmodule:: sardana.macroserver.macros.scan .. _sardana-users-scan: ===== Scans ===== Perhaps the most used type of macro is the scan macros. In general terms, we call *scan* to a macro that moves one or more :ref:`motors ` and acquires data along the path of the motor(s). .. note:: Sardana provides a :ref:`Scan Framework ` for developing scan macros so that the scan macros behave in a consistent way. Unless otherwise specified, the following discussion applies to scan macros based on such framework. The various scan macros mostly differ in how many motors are moved and the definition of their paths. Typically, the selection of which data is going to be acquired depends on the active *measurement group* and is *not* fixed by the macro itself (although there is no limitation in this sense). Depending on whether the motors are stopped before acquiring the data or not, we can classify the scan macros in *step* scans or *continuous* scans, respectively. .. figure:: /_static/trend_ascanVSascanc.png :width: 100% :figwidth: 80% :align: center Trend plot showing a step scan (:class:`ascan` *m_cp1_1 0 1000 8 .5*) followed by a continuous scan (:class:`ascanc` *m_cp1_1 0 1000 .5*). The line corresponds to the motor position and the blue shaded areas correspond to the intervals in which the data acquisition took place. Step scans ---------- In a step scan, the motors are moved to given points, and once they reach each point they stop. Then, one or more channels are acquired for a certain amount of time, and only when the data acquisition is finished, the motors proceed to the next point. In this way, the position associated to a data readout is well known and does not change during the acquisition time. Some examples of step scan macros are: :class:`ascan`, :class:`a2scan`, ... :class:`dscan`, :class:`d2scan`, ... :class:`mesh`. Continuous scans ---------------- In a continuous scan, the motors are not stopped for acquisition, which therefore takes place while the motors are moving. The most common reason for using this type of scan is optimizing the acquisition time by not having to wait for motors to accelerate and decelerate between acquisitions. .. note:: The synchronization of movement and acquisition can be done via hardware or via software. Currently Sardana only provides an interface for software-synchronized continuous scans. An API abstracting the specificities of hardware-synchronized systems is being implemented too but it is not yet available for production. The (software-synchronized) continuous scans introduce some constraints and issues that should be considered. #. If a continuous scan involves moving more than one motor simultaneously (as it is done, e.g. in :class:`~sardana.macroserver.macros.scan.a2scan`), then the movements of the motors should be synchronized so that they all start their path at the same time and finish it at the same time. #. If motors do not maintain a constant velocity along the path of their movement, the trajectories followed when using more than one motor may not be linear. #. While in step scans it is possible to scan two pseudo-motors that access the same physical motors (e.g. the *gap* and *offset* of a slit, being both pseudo-motors accessing the same physical motors attached to each blade of the slit), in a continuous scan the motions cannot be decoupled in a synchronized way. #. In order to optimize the acquisition time, Sardana attempts to perform as many acquisitions as allowed during the scan time. Due to the uncertainty in the delay times involved, it is not possible to know beforehand how many acquisitions will be completed. In other words, the number of acquired points along a continuous scan is not fixed (but it is guaranteed to be as large as possible). #. Backslash correction is incompatible with continuous scans, so you should keep in mind that continuous scans should only be done in the backslash-free direction of the motor (typically, by convention the positive one for a physical motor). In order to address the first two issues, the :ref:`scan framework ` attempts the following: * If the motors support changing their velocity, Sardana will adjust the velocities of the motors so that they all start and finish the required path simultaneously. For motors that specify a range of allowed velocities, this range will be used (for motors that do not specify a maximum allowed velocity, the current "top velocity" will be assumed to be the maximum) * For motors that can maintain a constant velocity after an acceleration phase (this is the case for most physical motors), Sardana will transparently extend the user-given path both at the beginning and the end in order to allow for the motors to move at constant velocity along all the user defined path (i.e., the motors are allowed time and room to accelerate before reaching the start of the path and to decelerate after the end of the nominal path selected by the user) These two actions can be seen in the following plot of the positions of the two motors involved in a :class:`~sardana.macroserver.macros.scan.a2scanc`. .. figure:: /_static/trend_a2scanc.png :width: 100% :figwidth: 80% :align: center Trend plot showing a two-motor continuous scan (:class:`a2scanc` *m_cp1_1 100 200 m_cp1_2 0 500 .1*). The lines correspond to the motor positions and the blue shaded areas correspond to the intervals in which the data acquisition took place. Both motors are capable of same velocity and acceleration, but since the required scan path for m_cp1_1 is shorter than that for m_cp1_2, its top velocity has been adjusted (gentler slope for m_cp1_1) so that both motors go through the user-requested start and stop positions simultaneously. The same figure also shows how the paths for both motors have been automatically (and transparently, for the user) extended to guarantee that the user defined path is followed at constant velocity and that the data acquisition takes place also while the motors are running at constant velocity. Some examples of continuous scan macros are: :class:`ascanc`, :class:`a2scanc`, ... :class:`dscanc`, :class:`d2scanc`, ... :class:`meshc`. .. seealso:: For more information about the implementation details of the scan macros in Sardana, see :ref:`scan framework ` sardana-1.2.0/doc/source/users/screenshots.rst0000644000234100017500000000633012174204301023024 0ustar cpascualcpascual00000000000000 .. highlight:: python :linenothreshold: 4 .. _sardana-screenshots: ============ Screenshots ============ Here you will find a host of example figures. Sardana oriented graphical user interfaces ------------------------------------------ .. figure:: /_static/snapshot01.png :alt: TaurusGUI at work :width: 600 TaurusGUI at work. .. figure:: /_static/snapshot02.png :alt: TaurusGUI with synoptic and macro widget :width: 600 TaurusGUI with synoptic and macro widget .. figure:: /_static/snapshot03.png :alt: Spock console :width: 600 Spock console .. figure:: /_static/snapshot04.png :alt: TaurusGUI with synoptic and macro panel :width: 600 TaurusGUI with synoptic and macro panel .. _sardana-screenshots-guis: Graphical user interface screen shots ------------------------------------- .. figure:: /_static/gui_snapshot01.png :alt: ALBA_'s Storage ring GUI :width: 600 ALBA_'s Storage ring GUI .. figure:: /_static/gui_snapshot02.png :width: 600 :alt: ALBA_'s LINAC to booster beam charge monitor GUI ALBA_'s LINAC to booster beam charge monitor GUI .. figure:: /_static/gui_snapshot03.png :width: 600 :alt: ALBA_'s beam position monitor GUI ALBA_'s beam position monitor GUI .. figure:: /_static/gui_snapshot04.png :width: 600 :alt: ALBA_'s Radio frequency plant GUI ALBA_'s Radio frequency plant GUI .. figure:: /_static/gui_snapshot05.png :width: 600 :alt: ALBA_'s tune excitation panel ALBA_'s tune excitation panel .. figure:: /_static/gui_snapshot06.png :width: 600 :alt: ALBA_'s fluorescent screen main panel ALBA_'s fluorescent screen main panel .. figure:: /_static/gui_snapshot07.png :width: 600 :alt: ALBA_'s front end GUI ALBA_'s front end GUI .. figure:: /_static/gui_snapshot08.png :width: 600 :alt: ALBA_'s digital low level radio frequency GUI ALBA_'s digital low level radio frequency GUI .. figure:: /_static/gui_snapshot09.png :width: 600 :alt: ALBA_'s vaccum GUI ALBA_'s vaccum GUI .. figure:: /_static/gui_snapshot10.png :width: 600 :alt: Sardana configuration GUI Sardana configuration GUI .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/users/spock.rst0000644000234100017500000004116512174204301021610 0ustar cpascualcpascual00000000000000 .. _sardana-spock: ===== Spock ===== *Spock* is the prefered :term:`CLI` for sardana. It is based on IPython_. Spock automatically loads other IPython_ extensions like the ones for PyTango_ and *pylab*. It as been extended in sardana to provide a customized interface for executing macros and automatic access to sardana elements. Spock tries to mimic SPEC_'s command line interface. Most SPEC_ commands are available from spock console. .. figure:: /_static/spock_snapshot01.png :height: 600 :align: center Spock :term:`CLI` in action Starting spock from the command line ------------------------------------ To start spock just type in the command line:: marge@machine02:~$ spock This will start spock with a "default profile" for the user your are logged with. There may be many sardana servers running on your system so the first time you start spock, it will ask you to which sardana system you want to connect to by asking to which of the existing doors you want to use:: marge@machine02:~$ spock Profile 'spockdoor' does not exist. Do you want to create one now ([y]/n)? Available Door devices from homer:10000 : On Sardana LAB-01: LAB-01-D01 (running) LAB-01-D02 (running) On Sardana LAB-02: LAB-02-D01 Please select a Door from the list? LAB-01-D01 Storing ipy_profile_spockdoor.py in /home/marge/.ipython... [DONE] .. note:: If only one Door exists in the entire system, spock will automatically connect to that door thus avoiding the previous questions. Afterward, spock :term:`CLI` will start normally: .. sourcecode:: spock Spock 7.2.1 -- An interactive sardana client. help -> Spock's help system. object? -> Details about 'object'. ?object also works, ?? prints more. Spock's sardana extension 1.0 loaded with profile: spockdoor (linked to door 'LAB-01-D01') LAB-01-D01 [1]: Starting spock with a custom profile ------------------------------------ spock allows each user to start a spock session with different configurations (known in spock as *profiles*). All you have to do is start spock with:: spock -p Example:: marge@machine02:~$ spock -p D1 The first time a certain profile is used you will be asked to which door you want to connect to (see previous chapter). Spock IPython_ Primer --------------------- As mentioned before, spock console is based on IPython_. Everything you can do in IPython is available in spock. The IPython_ documentation provides excelent tutorials, tips & tricks, cookbooks, videos, presentations and reference guide. For comodity we summarize some of the most interesting IPython_ chapters here: .. hlist:: :columns: 2 * `IPython web page `_ * :ref:`tutorial` * :ref:`tips` * :ref:`command_line_options` Executing macros ---------------- Executing sardana macros in spock is the most useful feature of spock. It is very simple to execute a macro: just type the macro name followed by a space separated list of parameters (if the macro has any parameters). For example, one of the most used macros is the :class:`~sardana.macroserver.macros.standard.wa` (stands for "where all") that shows all current motor positions. To execute it just type: .. sourcecode:: spock LAB-01-D01 [1]: wa Current Positions (user, dial) Energy Gap Offset 100.0000 43.0000 100.0000 100.0000 43.0000 100.0000 (:term:`user` for :term:`user position` (number above); :term:`dial` for :term:`dial position` (number below).) A similar macro exists that only shows the desired motor positions (:class:`~sardana.macroserver.macros.standard.wm`): .. sourcecode:: spock LAB-01-D01 [1]: wm gap offset Gap Offset User High 500.0 100.0 Current 100.0 43.0 Low 5.0 -100.0 Dial High 500.0 100.0 Current 100.0 43.0 Low 5.0 -100.0 To get the list of all existing macros use :class:`~sardana.macroserver.macros.expert.lsmac`: .. sourcecode:: spock LAB-01-D01 [1]: lsdef Name Module Brief Description ------------------- ------------- ------------------------------------------------------------ a2scan scans two-motor scan. a2scan scans two motors, as specifi[...] a2scan scans three-motor scan . a3scan scans three motors, as sp[...] ascan scans Do an absolute scan of the specified motor. ascan s[...] defmeas expert Create a new measurement group fscan scans N-dimensional scan along user defined paths. The mo[...] lsa lists Lists all existing objects lsm lists Lists all motors lsmac expert Lists all macros. mv standard Move motor(s) to the specified position(s) mvr standard Move motor(s) relative to the current position(s) wa standard Show all motor position. wm standard Show the position of the specified motors. <...> Miscellaneous ~~~~~~~~~~~~~ - :class:`~sardana.macroserver.macros.lists.lsm` shows the list of motors. - :class:`~sardana.macroserver.macros.lists.lsct` shows the list of counters. - :class:`~sardana.macroserver.macros.lists.lsmeas` shows the list of measurement groups - :class:`~sardana.macroserver.macros.lists.lsctrl` shows the list of controllers - :class:`~sardana.macroserver.macros.expert.sar_info` *object* displays detailed information about an element Stopping macros --------------- Some macros may take a long time to execute. To stop a macro in the middle of its execution type :kbd:`Control+c`. Macros that move motors or acquire data from sensors will automatically stop all motion and/or all acquisition. Exiting spock ------------- To exit spock type :kbd:`Control+d` or :samp:`exit()` inside a spock console. Getting help ------------ spock not only knows all the macros the sardana server can run but it also information about each macro parameters, result and documentation. Therefore it can give you precise help on each macro. To get help about a certain macro just type the macro name directly followed by a question mark('?'): .. sourcecode:: spock LAB-01-D01 [1]: ascan? Syntax: ascan Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. Parameters: motor : (Motor) Motor to move start_pos : (Float) Scan start position final_pos : (Float) Scan final position nr_interv : (Integer) Number of scan intervals integ_time : (Float) Integration time Moving motors ------------- A single motor may be moved using the :class:`~sardana.macroserver.macros.standard.mv` *motor* *position* macro. Example: .. sourcecode:: spock LAB-01-D01 [1]: mv gap 50 will move the *gap* motor to 50. The prompt only comes back after the motion as finished. Alternatively, you can have the motor position displayed on the screen as it is moving by using the :class:`~sardana.macroserver.macros.standard.umv` macro instead. To stop the motor(s) before they have finished moving, type :kbd:`Control+c`. You can use the :class:`~sardana.macroserver.macros.standard.mvr` *motor* *relative_position* macro to move a motor relative to its current position: .. sourcecode:: spock LAB-01-D01 [1]: mvr gap 2 will move *gap* by two user units. Counting -------- You can count using the :class:`~sardana.macroserver.macros.standard.ct` *value* macro. Without arguments, this macro counts for one second using the active measurement group set by the environment variable *ActiveMntGrp*. .. sourcecode:: spock Door_lab-01_1 [1]: ct 1.6 Wed Jul 11 11:47:55 2012 ct01 = 1.6 ct02 = 3.2 ct03 = 4.8 ct04 = 6.4 To see the list of available measurement groups type :class:`~sardana.macroserver.macros.lists.lsmeas`. The active measuremnt group is marked with an asterisk (*): .. sourcecode:: spock Door_lab-01_1 [1]: lsmeas Active Name Timer Experim. channels -------- ---------- ------- ----------------------------------------------------------- * mntgrp01 ct01 ct01, ct02, ct03, ct04 mntgrp21 ct04 ct04, pcII0, pcII02 mntgrp24 ct04 ct04, pcII0 to switch active measurement groups type :class:`~sardana.macroserver.macros.env.senv` **ActiveMntGrp** *mg_name*. You can also create, modify and select measurement groups using the :class:`~sardana.spock.magic.expconf` command Scanning -------- Sardana provides a catalog of different standard scan macros. Absolute-position motor scans such as :class:`~sardana.macroserver.macros.scan.ascan`, :class:`~sardana.macroserver.macros.scan.a2scan` and :class:`~sardana.macroserver.macros.scan.a3scan` move one, two or three motors at a time. Relative-position motor scans are :class:`~sardana.macroserver.macros.scan.dscan`, :class:`~sardana.macroserver.macros.scan.d2scan` and :class:`~sardana.macroserver.macros.scan.d3scan`. The relative-position scans all return the motors to their starting positions after the last point. Two motors can be scanned over a grid of points using the :class:`~sardana.macroserver.macros.scan.mesh` scan. *Continuous* versions exist of many of the standard scan macros (e.g. :class:`~sardana.macroserver.macros.scan.ascanc`, :class:`~sardana.macroserver.macros.scan.d3scanc`, :class:`~sardana.macroserver.macros.scan.meshc`,...). The continuous scans differ from their standard counterparts (also known as *step* scans) in that the data acquisition is done without stopping the motors. Continuous scans are generally faster but less precise than step scans, and some details must be considered (see :ref:`sardana-users-scan`). As it happens with :class:`~sardana.macroserver.macros.standard.ct`, the scan macros will also use the active measurement group to decide which experiment channels will be involved in the operation. Here is the output of performing an :class:`~sardana.macroserver.macros.scan.ascan` of the gap in a slit: .. sourcecode:: spock LAB-01-D01 [1]: ascan gap 0.9 1.1 20 1 ScanDir is not defined. This operation will not be stored persistently. Use "senv ScanDir " to enable it Scan #4 started at Wed Jul 11 12:56:47 2012. It will take at least 0:00:21 #Pt No gap ct01 ct02 ct03 0 0.9 1 4604 8939 1 0.91 1 5822 8820 2 0.92 1 7254 9544 3 0.93 1 9254 8789 4 0.94 1 11265 8804 5 0.95 1 13583 8909 6 0.96 1 15938 8821 7 0.97 1 18076 9110 8 0.98 1 19638 8839 9 0.99 1 20825 8950 10 1 1 21135 8917 11 1.01 1 20765 9013 12 1.02 1 19687 9135 13 1.03 1 18034 8836 14 1.04 1 15876 8901 15 1.05 1 13576 8933 16 1.06 1 11328 9022 17 1.07 1 9244 9205 18 1.08 1 7348 8957 19 1.09 1 5738 8801 20 1.1 1 4575 8975 Scan #4 ended at Wed Jul 11 12:57:18 2012, taking 0:00:31.656980 (dead time was 33.7%) Scan storage ~~~~~~~~~~~~ As you can see, by default, the scan is not recorded into any file. To store your scans in a file, you must set the environment variables **ScanDir** and **ScanFile**: .. sourcecode:: spock LAB-01-D01 [1]: senv ScanDir /tmp ScanDir = /tmp LAB-01-D01 [2]: senv ScanFile scans.h5 ScanFile = scans.h5 Sardana will activate a proper recorder to store the scans persistently (currently, *.h5* will store in `NeXus`_ format. All other extensions are interpreted as `SPEC`_ format). You can also store in multiples files by assigning the **ScanFile** with a list of files: .. sourcecode:: spock LAB-01-D01 [2]: senv ScanFile "['scans.h5', 'scans.dat']" ScanFile = ['scans.h5', 'scans.dat'] Viewing scan data ~~~~~~~~~~~~~~~~~ Sardana provides a scan data viewer for scans which were stored in a `NeXus`_ file. Without arguments, :class:`~sardana.macroserver.macros.scan.showscan` will show you the result of the last scan in a :term:`GUI`: .. figure:: /_static/spock_snapshot02.png :height: 600 Scan data viewer in action :class:`~sardana.macroserver.macros.scan.showscan` *scan_number* will display data for the given scan number. The history of scans is available through the :class:`~sardana.macroserver.macros.scan.scanhist` macro: .. sourcecode:: spock LAB-01-D01 [1]: scanhist # Title Start time End time Stored --- ------------------------------- --------------------- --------------------- ------------- 1 dscan mot01 20.0 30.0 10 0.1 2012-07-03 10:35:30 2012-07-03 10:35:30 Not stored! 3 dscan mot01 20.0 30.0 10 0.1 2012-07-03 10:36:38 2012-07-03 10:36:43 Not stored! 4 ascan gap01 10.0 100.0 20 1.0 12:56:47 12:57:18 Not stored! 5 ascan gap01 1.0 10.0 20 0.1 13:19:05 13:19:13 scans.h5 Using spock as a Python_ console -------------------------------- You can write any Python_ code inside a spock console since spock uses IPython_ as a command line interpreter. For example, the following will work inside a spock console: .. sourcecode:: spock LAB-01-D01 [1]: def f(): ...: print("Hello, World!") ...: ...: LAB-01-D01 [2]: f() Hello, World! Using spock as a Tango_ console ------------------------------- As metioned in the beggining of this chapter, the sardana spock automatically activates the PyTango_ 's ipython console extension. Therefore all Tango_ features are automatically available on the sardana spock console. For example, creating a :class:`~PyTango.DeviceProxy` will work inside the sardana spock console: .. sourcecode:: spock LAB-01-D01 [1]: tgtest = PyTango.DeviceProxy("sys/tg_test/1") LAB-01-D01 [2]: print( tgtest.state() ) RUNNING .. rubric:: Footnotes .. [#] The PyTango_ ipython documentation can be found :ref:`here ` .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _`PyTango installation steps`: http://packages.python.org/PyTango/start.html#getting-started .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ .. _NeXus: http://www.nexusformat.org/ sardana-1.2.0/doc/source/users/standard_macro_catalog.rst0000644000234100017500000001163212174204301025140 0ustar cpascualcpascual00000000000000 .. _sardana-standard-macro-catalog: ====================== Standard macro catalog ====================== motion related macros --------------------- .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.standard.wa` * :class:`~sardana.macroserver.macros.standard.wm` * :class:`~sardana.macroserver.macros.standard.pwa` * :class:`~sardana.macroserver.macros.standard.pwm` * :class:`~sardana.macroserver.macros.standard.set_lim` * :class:`~sardana.macroserver.macros.standard.set_lm` * :class:`~sardana.macroserver.macros.standard.set_pos` * :class:`~sardana.macroserver.macros.standard.mv` * :class:`~sardana.macroserver.macros.standard.umv` * :class:`~sardana.macroserver.macros.standard.mvr` * :class:`~sardana.macroserver.macros.standard.umvr` * :class:`~sardana.macroserver.macros.lists.lsm` * :class:`~sardana.macroserver.macros.lists.lspm` counting macros --------------- .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.standard.ct` * :class:`~sardana.macroserver.macros.standard.uct` * :class:`~sardana.macroserver.macros.standard.settimer` * :class:`~sardana.macroserver.macros.lists.lsexp` * :class:`~sardana.macroserver.macros.lists.lsmeas` * :class:`~sardana.macroserver.macros.lists.lsct` * :class:`~sardana.macroserver.macros.lists.ls0d` * :class:`~sardana.macroserver.macros.lists.ls1d` * :class:`~sardana.macroserver.macros.lists.ls2d` * :class:`~sardana.macroserver.macros.lists.lspc` environment related macros -------------------------- .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.env.lsenv` * :class:`~sardana.macroserver.macros.env.senv` * :class:`~sardana.macroserver.macros.env.usenv` * :class:`~sardana.macroserver.macros.env.dumpenv` list related macros ------------------- .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.env.lsenv` * :class:`~sardana.macroserver.macros.lists.lsa` * :class:`~sardana.macroserver.macros.lists.lsm` * :class:`~sardana.macroserver.macros.lists.lspm` * :class:`~sardana.macroserver.macros.lists.lsexp` * :class:`~sardana.macroserver.macros.lists.lsior` * :class:`~sardana.macroserver.macros.lists.lsmeas` * :class:`~sardana.macroserver.macros.lists.lsct` * :class:`~sardana.macroserver.macros.lists.ls0d` * :class:`~sardana.macroserver.macros.lists.ls1d` * :class:`~sardana.macroserver.macros.lists.ls2d` * :class:`~sardana.macroserver.macros.lists.lspc` * :class:`~sardana.macroserver.macros.lists.lsctrl` * :class:`~sardana.macroserver.macros.lists.lsi` * :class:`~sardana.macroserver.macros.lists.lsctrllib` * :class:`~sardana.macroserver.macros.lists.lsa` * :class:`~sardana.macroserver.macros.lists.lsmac` * :class:`~sardana.macroserver.macros.lists.lsmaclib` measurement configuration macros -------------------------------- .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.expert.defmeas` * :class:`~sardana.macroserver.macros.expert.udefmeas` advanced element manipulation macros ------------------------------------ .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.expert.defelem` * :class:`~sardana.macroserver.macros.expert.udefelem` * :class:`~sardana.macroserver.macros.expert.defctrl` * :class:`~sardana.macroserver.macros.expert.udefctrl` * :class:`~sardana.macroserver.macros.expert.prdef` reload code macros ------------------ .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.expert.relmac` * :class:`~sardana.macroserver.macros.expert.relmaclib` * :class:`~sardana.macroserver.macros.expert.rellib` scan macros ----------- .. hlist:: :columns: 5 * :class:`~sardana.macroserver.macros.scan.ascan` * :class:`~sardana.macroserver.macros.scan.a2scan` * :class:`~sardana.macroserver.macros.scan.a3scan` * :class:`~sardana.macroserver.macros.scan.a4scan` * :class:`~sardana.macroserver.macros.scan.amultiscan` * :class:`~sardana.macroserver.macros.scan.dscan` * :class:`~sardana.macroserver.macros.scan.d2scan` * :class:`~sardana.macroserver.macros.scan.d3scan` * :class:`~sardana.macroserver.macros.scan.d4scan` * :class:`~sardana.macroserver.macros.scan.dmultiscan` * :class:`~sardana.macroserver.macros.scan.mesh` * :class:`~sardana.macroserver.macros.scan.fscan` * :class:`~sardana.macroserver.macros.scan.scanhist` * :class:`~sardana.macroserver.macros.scan.ascanc` * :class:`~sardana.macroserver.macros.scan.a2scanc` * :class:`~sardana.macroserver.macros.scan.a3scanc` * :class:`~sardana.macroserver.macros.scan.a4scanc` * :class:`~sardana.macroserver.macros.scan.dscanc` * :class:`~sardana.macroserver.macros.scan.d2scanc` * :class:`~sardana.macroserver.macros.scan.d3scanc` * :class:`~sardana.macroserver.macros.scan.d4scanc` * :class:`~sardana.macroserver.macros.scan.meshc` sardana-1.2.0/doc/source/conf.py0000644000234100017500000002450512174204306020101 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import sys import os import os.path as osp def set_src(): sar_dir = osp.join(osp.dirname(osp.abspath(__file__)), osp.pardir, osp.pardir, 'src') sys.path.insert(0, osp.abspath(sar_dir)) # try to use code from src distribution set_src() import sardana as_pdf_extension = True try: import rst2pdf.pdfbuilder except ImportError: as_pdf_extension = False def fix_sardana_for_doc(): def type_getattr(self, name): if name not in self._pending_type_names: self._pending_type_names[name] = name return self._pending_type_names[name] import sardana.macroserver.msparameter sardana.macroserver.msparameter.TypeNames.__getattr__ = type_getattr fix_sardana_for_doc() # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.append(os.path.abspath('sphinxext')) # -- General configuration ----------------------------------------------------- #autosummary_generate = True # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.pngmath', 'sphinx.ext.autosummary', 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.graphviz', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode', 'sardanaextension', 'ipython_console_highlighting', 'spock_console_highlighting', ] if as_pdf_extension: extensions.append('rst2pdf.pdfbuilder') # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'contents' # General information about the project. project = u'sardana' copyright = u'2012, ALBA - CELLS, Creative Commons Attribution-Share Alike 3.0' copyright = u"""Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License""" #Ideally we would like to put the following html code for copyright... but how? '''Creative Commons License
    Taurus Documentation by CELLS - ALBA is licensed under a Creative Commons Attribution-Share Alike 3.0 Spain License.''' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '.'.join(sardana.Release.version.split('.')[:2]) # The full version, including alpha/beta/rc tags. release = sardana.Release.version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = False # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' pygments_style = 'spock_console_highlighting.SpockStyle' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'default' #html_theme = 'sphinxdoc' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. html_theme_path = [] #html_theme_path = ['themes'] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = "logo.png" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. html_sidebars = {'index': ['indexsidebar.html']} # Additional templates that should be rendered to pages, maps page names to # template names. html_additional_pages = { 'index' : 'index.html' } # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'sardanadoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). latex_paper_size = 'a4' # The font size ('10pt', '11pt' or '12pt'). latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('contents', 'sardana.tex', u'Sardana Documentation', u'Sardana team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. latex_logo = '_static/sardana_screenshot.png' latex_elements = { 'fontpkg': '\\usepackage{palatino}', } latex_show_urls = 'footnote' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True todo_include_todos = True autodoc_member_order = "bysource" # -- Options for Graphviz ----------------------------------------------------- inheritance_node_attrs = dict(shape='box', fontcolor='black', height=0.4, color='brown', style='rounded') inheritance_graph_attrs = dict(rankdir="UD", ratio='compress') graphviz_output_format = 'png' # 'svg' #inheritance_graph_attrs = dict(rankdir="LR", size='"6.0, 8.0"', # fontsize=14, ratio='compress') # -- Options for reference to other documentation ------------------------------ intersphinx_mapping = { 'http://docs.python.org/dev': None, 'http://docs.scipy.org/doc/scipy/reference' : None, 'http://docs.scipy.org/doc/numpy' : None, 'http://ipython.org/ipython-doc/stable/' : None, 'http://www.tango-controls.org/static/PyTango/latest/doc/html' : None, 'http://www.tango-controls.org/static/taurus/latest/doc/html' : None, 'http://pyqt.sourceforge.net/Docs/PyQt4/' : None, 'http://matplotlib.sourceforge.net/' : None, 'http://packages.python.org/guiqwt/' : None, } sardana-1.2.0/doc/source/contents.rst0000644000234100017500000000040512174204306021162 0ustar cpascualcpascual00000000000000 .. currentmodule:: sardana .. _contents: ======== Contents ======== .. toctree:: :maxdepth: 2 users/index devel/index Glossary To do History of changes * :ref:`genindex` * :ref:`modindex` * :ref:`search` sardana-1.2.0/doc/source/glossary.rst0000644000234100017500000005325212174204306021200 0ustar cpascualcpascual00000000000000 .. _sardana-glossary: =========== Glossary =========== .. glossary:: :sorted: ``>>>`` The default Python prompt of the interactive shell. Often seen for code examples which can be executed interactively in the interpreter. ``...`` The default Python prompt of the interactive shell when entering code for an indented code block or within a pair of matching left and right delimiters (parentheses, square brackets or curly braces). argument A value passed to a function or method, assigned to a named local variable in the function body. A function or method may have both positional arguments and keyword arguments in its definition. Positional and keyword arguments may be variable-length: ``*`` accepts or passes (if in the function definition or call) several positional arguments in a list, while ``**`` does the same for keyword arguments in a dictionary. Any expression may be used within the argument list, and the evaluated value is passed to the local variable. attribute A value associated with an object which is referenced by name using dotted expressions. For example, if an object *o* has an attribute *a* it would be referenced as *o.a*. dictionary An associative array, where arbitrary keys are mapped to values. The keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods. Called a hash in Perl. class A template for creating user-defined objects. Class definitions normally contain method definitions which operate on instances of the class. expression A piece of syntax which can be evaluated to some value. In other words, an expression is an accumulation of expression elements like literals, names, attribute access, operators or function calls which all return a value. In contrast to many other languages, not all language constructs are expressions. There are also :term:`statement`\s which cannot be used as expressions, such as :func:`print` or :keyword:`if`. Assignments are also statements, not expressions. function A series of statements which returns some value to a caller. It can also be passed zero or more arguments which may be used in the execution of the body. See also :term:`argument` and :term:`method`. generator A function which returns an iterator. It looks like a normal function except that it contains :keyword:`yield` statements for producing a series a values usable in a for-loop or that can be retrieved one at a time with the :func:`next` function. Each :keyword:`yield` temporarily suspends processing, remembering the location execution state (including local variables and pending try-statements). When the generator resumes, it picks-up where it left-off (in contrast to functions which start fresh on every invocation). .. index:: single: generator expression generator expression An expression that returns an iterator. It looks like a normal expression followed by a :keyword:`for` expression defining a loop variable, range, and an optional :keyword:`if` expression. The combined expression generates values for an enclosing function:: >>> sum(i*i for i in range(10)) # sum of squares 0, 1, 4, ... 81 285 interactive Python has an interactive interpreter which means you can enter statements and expressions at the interpreter prompt, immediately execute them and see their results. Just launch ``python`` with no arguments (possibly by selecting it from your computer's main menu). It is a very powerful way to test out new ideas or inspect modules and packages (remember ``help(x)``). interpreted Python is an interpreted language, as opposed to a compiled one, though the distinction can be blurry because of the presence of the bytecode compiler. This means that source files can be run directly without explicitly creating an executable which is then run. Interpreted languages typically have a shorter development/debug cycle than compiled ones, though their programs generally also run more slowly. See also :term:`interactive`. iterable An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as :class:`list`, :class:`str`, and :class:`tuple`) and some non-sequence types like :class:`dict` and :class:`file` and objects of any classes you define with an :meth:`__iter__` or :meth:`__getitem__` method. Iterables can be used in a :keyword:`for` loop and in many other places where a sequence is needed (:func:`zip`, :func:`map`, ...). When an iterable object is passed as an argument to the built-in function :func:`iter`, it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call :func:`iter` or deal with iterator objects yourself. The ``for`` statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also :term:`iterator`, :term:`sequence`, and :term:`generator`. iterator An object representing a stream of data. Repeated calls to the iterator's :meth:`next` method return successive items in the stream. When no more data are available a :exc:`StopIteration` exception is raised instead. At this point, the iterator object is exhausted and any further calls to its :meth:`next` method just raise :exc:`StopIteration` again. Iterators are required to have an :meth:`__iter__` method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a :class:`list`) produces a fresh new iterator each time you pass it to the :func:`iter` function or use it in a :keyword:`for` loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container. More information can be found in :ref:`typeiter`. key function A key function or collation function is a callable that returns a value used for sorting or ordering. For example, :func:`locale.strxfrm` is used to produce a sort key that is aware of locale specific sort conventions. A number of tools in Python accept key functions to control how elements are ordered or grouped. They include :func:`min`, :func:`max`, :func:`sorted`, :meth:`list.sort`, :func:`heapq.nsmallest`, :func:`heapq.nlargest`, and :func:`itertools.groupby`. There are several ways to create a key function. For example. the :meth:`str.lower` method can serve as a key function for case insensitive sorts. Alternatively, an ad-hoc key function can be built from a :keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also, the :mod:`operator` module provides three key function constructors: :func:`~operator.attrgetter`, :func:`~operator.itemgetter`, and :func:`~operator.methodcaller`. See the :ref:`Sorting HOW TO ` for examples of how to create and use key functions. keyword argument Arguments which are preceded with a ``variable_name=`` in the call. The variable name designates the local name in the function to which the value is assigned. ``**`` is used to accept or pass a dictionary of keyword arguments. See :term:`argument`. lambda An anonymous inline function consisting of a single :term:`expression` which is evaluated when the function is called. The syntax to create a lambda function is ``lambda [arguments]: expression`` list A built-in Python :term:`sequence`. Despite its name it is more akin to an array in other languages than to a linked list since access to elements are O(1). list comprehension A compact way to process all or part of the elements in a sequence and return a list with the results. ``result = ["0x%02x" % x for x in range(256) if x % 2 == 0]`` generates a list of strings containing even hex numbers (0x..) in the range from 0 to 255. The :keyword:`if` clause is optional. If omitted, all elements in ``range(256)`` are processed. method A function which is defined inside a class body. If called as an attribute of an instance of that class, the method will get the instance object as its first :term:`argument` (which is usually called ``self``). See :term:`function` and :term:`nested scope`. namespace The place where a variable is stored. Namespaces are implemented as dictionaries. There are the local, global and built-in namespaces as well as nested namespaces in objects (in methods). Namespaces support modularity by preventing naming conflicts. For instance, the functions :func:`__builtin__.open` and :func:`os.open` are distinguished by their namespaces. Namespaces also aid readability and maintainability by making it clear which module implements a function. For instance, writing :func:`random.seed` or :func:`itertools.izip` makes it clear that those functions are implemented by the :mod:`random` and :mod:`itertools` modules, respectively. nested scope The ability to refer to a variable in an enclosing definition. For instance, a function defined inside another function can refer to variables in the outer function. Note that nested scopes work only for reference and not for assignment which will always write to the innermost scope. In contrast, local variables both read and write in the innermost scope. Likewise, global variables read and write to the global namespace. new-style class Any class which inherits from :class:`object`. This includes all built-in types like :class:`list` and :class:`dict`. Only new-style classes can use Python's newer, versatile features like :attr:`__slots__`, descriptors, properties, and :meth:`__getattribute__`. object Any data with state (attributes or value) and defined behavior (methods). Also the ultimate base class of any :term:`new-style class`. positional argument The arguments assigned to local names inside a function or method, determined by the order in which they were given in the call. ``*`` is used to either accept multiple positional arguments (when in the definition), or pass several arguments as a list to a function. See :term:`argument`. Python 3000 Nickname for the Python 3.x release line (coined long ago when the release of version 3 was something in the distant future.) This is also abbreviated "Py3k". Pythonic An idea or piece of code which closely follows the most common idioms of the Python language, rather than implementing code using concepts common to other languages. For example, a common idiom in Python is to loop over all elements of an iterable using a :keyword:`for` statement. Many other languages don't have this type of construct, so people unfamiliar with Python sometimes use a numerical counter instead:: for i in range(len(food)): print food[i] As opposed to the cleaner, Pythonic method:: for piece in food: print piece sequence An :term:`iterable` which supports efficient element access using integer indices via the :meth:`__getitem__` special method and defines a :meth:`len` method that returns the length of the sequence. Some built-in sequence types are :class:`list`, :class:`str`, :class:`tuple`, and :class:`unicode`. Note that :class:`dict` also supports :meth:`__getitem__` and :meth:`__len__`, but is considered a mapping rather than a sequence because the lookups use arbitrary :term:`immutable` keys rather than integers. slice An object usually containing a portion of a :term:`sequence`. A slice is created using the subscript notation, ``[]`` with colons between numbers when several are given, such as in ``variable_name[1:3:5]``. The bracket (subscript) notation uses :class:`slice` objects internally (or in older versions, :meth:`__getslice__` and :meth:`__setslice__`). statement A statement is part of a suite (a "block" of code). A statement is either an :term:`expression` or a one of several constructs with a keyword, such as :keyword:`if`, :keyword:`while` or :keyword:`for`. triple-quoted string A string which is bound by three instances of either a quotation mark (") or an apostrophe ('). While they don't provide any functionality not available with single-quoted strings, they are useful for a number of reasons. They allow you to include unescaped single and double quotes within a string and they can span multiple lines without the use of the continuation character, making them especially useful when writing docstrings. type The type of a Python object determines what kind of object it is; every object has a type. An object's type is accessible as its :attr:`__class__` attribute or can be retrieved with ``type(obj)``. plugin See :term:`plug-in`. plug-in a plug-in (or plugin) is a set of software components that adds specific abilities to a larger software application. If supported, plug-ins enable customizing the functionality of an application. For example, plug-ins are commonly used in web browsers to play video, scan for viruses, and display new file types. MCA Multichannel Analyzer (MCA) is a device for ... CCD A charge-coupled device (CCD) is a device for the movement of electrical charge, usually from within the device to an area where the charge can be manipulated, for example conversion into a digital value. This is achieved by "shifting" the signals between stages within the device one at a time. CCDs move charge between capacitive bins in the device, with the shift allowing for the transfer of charge between bins. API An application programming interface (API) is a particular set of rules and specifications that software programs can follow to communicate with each other. It serves as an interface between different software programs and facilitates their interaction, similar to the way the user interface facilitates interaction between humans and computers. An API can be created for applications, libraries, operating systems, etc., as a way of defining their "vocabularies" and resources request conventions (e.g. function-calling conventions). It may include specifications for routines, data structures, object classes, and protocols used to communicate between the consumer program and the implementer program of the API. CLI A command-line interface (CLI) is a mechanism for interacting with a computer operating system or software by typing commands to perform specific tasks. This text-only interface contrasts with the use of a mouse pointer with a graphical user interface (:term:`GUI`) to click on options, or menus on a text user interface (TUI) to select options. This method of instructing a computer to perform a given task is referred to as "entering" a command: the system waits for the user to conclude the submitting of the text command by pressing the "Enter" key (a descendant of the "carriage return" key of a typewriter keyboard). A command-line interpreter then receives, parses, and executes the requested user command. The command-line interpreter may be run in a text terminal or in a terminal emulator window as a remote shell client such as PuTTY. Upon completion, the command usually returns output to the user in the form of text lines on the CLI. This output may be an answer if the command was a question, or otherwise a summary of the operation. GUI A graphical user interface (GUI) is a type of user interface that allows users to interact with electronic devices with images rather than text commands. GUIs can be used in computers, hand-held devices such as MP3 players, portable media players or gaming devices, household appliances and office equipment. A GUI represents the information and actions available to a user through graphical icons and visual indicators such as secondary notation, as opposed to text-based interfaces (:term:`CLI`), typed command labels or text navigation. The actions are usually performed through direct manipulation of the graphical elements. SDS Sardana Device server (SDS) is the sardana tango device server :term:`daemon`. OS An operating system (OS) is software, consisting of programs and data, that runs on computers, manages computer hardware resources, and provides common services for execution of various application software. Operating system is the most important type of system software in a computer system. Without an operating system, a user cannot run an application program on their computer, unless the application program is self booting. daemon In Unix and other computer multitasking operating systems, a daemon is a computer program that runs in the background, rather than under the direct control of a user. They are usually initiated as background processes. Typically daemons have names that end with the letter "d": for example, *syslogd*, the daemon that handles the system log, or *sshd*, which handles incoming SSH connections. SCADA supervisory control and data acquisition (SCADA) generally refers to industrial control systems: computer systems that monitor and control industrial, infrastructure, or facility-based processes. client-server model The client-server model of computing is a distributed application structure that partitions tasks or workloads between the providers of a resource or service, called servers, and service requesters, called clients. Often clients and servers communicate over a computer network on separate hardware, but both client and server may reside in the same system. A server machine is a host that is running one or more server programs which share their resources with clients. A client does not share any of its resources, but requests a server's content or service function. Clients therefore initiate communication sessions with servers which await incoming requests. user position Moveable position in user units (See also :term:`dial position`). Dial and user units are related by the following expressions: user = sign x dial + offset dial = controller_position / steps_per_unit where *sign* is -1 or 1. *offset* can be any number and *steps_per_unit* must be non zero. user See :term:`user position` dial position Position in controller units (See also :term:`user position`). dial See :term:`dial position` .. _plug-in: http://en.wikipedia.org/wiki/Plug-in_(computing) .. _CCD: http://en.wikipedia.org/wiki/Charge-coupled_device .. _API: http://en.wikipedia.org/wiki/API .. _CLI: http://en.wikipedia.org/wiki/Command-line_interface .. _GUI: http://en.wikipedia.org/wiki/Graphical_user_interface .. _OS: http://en.wikipedia.org/wiki/Operating_system .. _daemon: http://en.wikipedia.org/wiki/Daemon_(computing) .. _SCADA: http://en.wikipedia.org/wiki/SCADA .. _client-server model: http://en.wikipedia.org/wiki/Client%E2%80%93server_model .. _ALBA: http://www.cells.es/ .. _ANKA: http://http://ankaweb.fzk.de/ .. _ELETTRA: http://http://www.elettra.trieste.it/ .. _ESRF: http://www.esrf.eu/ .. _FRMII: http://www.frm2.tum.de/en/index.html .. _HASYLAB: http://hasylab.desy.de/ .. _MAX-lab: http://www.maxlab.lu.se/maxlab/max4/index.html .. _SOLEIL: http://www.synchrotron-soleil.fr/ .. _Tango: http://www.tango-controls.org/ .. _PyTango: http://packages.python.org/PyTango/ .. _Taurus: http://packages.python.org/taurus/ .. _QTango: http://www.tango-controls.org/download/index_html#qtango3 .. _Qt: http://qt.nokia.com/products/ .. _PyQt: http://www.riverbankcomputing.co.uk/software/pyqt/ .. _PyQwt: http://pyqwt.sourceforge.net/ .. _Python: http://www.python.org/ .. _IPython: http://ipython.scipy.org/ .. _ATK: http://www.tango-controls.org/Documents/gui/atk/tango-application-toolkit .. _Qub: http://www.blissgarden.org/projects/qub/ .. _numpy: http://numpy.scipy.org/ .. _SPEC: http://www.certif.com/ .. _EPICS: http://www.aps.anl.gov/epics/ sardana-1.2.0/doc/source/index.html0000644000234100017500000000061612174204306020574 0ustar cpascualcpascual00000000000000 Sardana documentation Sardana documentation is too big to be hosted by PyPi.
    We are redirecting you the proper page. sardana-1.2.0/doc/source/revision.rst0000644000234100017500000000230512174204306021164 0ustar cpascualcpascual00000000000000.. _revision: Revision ======== :Contributers: T\. Coutinho :Last Update: |today| .. _history-modifications: History of modifications ------------------------ +----------+----------+----------------------------------------------------+-------------------------+ | Date | Revision | Description | Author | +==========+==========+====================================================+=========================+ | 17/06/11 | 1.0 | Initial Version | T\. Coutinho | +----------+----------+----------------------------------------------------+-------------------------+ .. _version-history: Version history --------------- +------------+---------------------------------------------------------------------------------+ | version | Changes | +============+=================================================================================+ | 1.0 | First official release | +------------+---------------------------------------------------------------------------------+ sardana-1.2.0/doc/source/todo.rst0000644000234100017500000000013612174204306020273 0ustar cpascualcpascual00000000000000 ========================== Documentation to be done ========================== .. todolist::sardana-1.2.0/doc/logo.bmp0000644000234100017500000035043612174204306016747 0ustar cpascualcpascual00000000000000BM6(  ɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺʿƺƺƺƺƺƺȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼʿŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹʿŹŹŹŹŹǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻȼ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷Ǽ÷÷÷÷÷ǼŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷ĸŸµµµµµµµµµµµµµµµµµµµµµµµµµпппппппппппппппппппппппппϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽöϽϽϽƺппппппппппппппппппппппппμμμμμμμμμμμμμμμμμμμμμνμμŹϽϽϽϽɿϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺμμμμμμμμμμμμμμμμμμμμμμμ̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸Ѿ̸̸Ǽͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺ˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹ʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶ˷˷ͺ˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷ȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴʷɾʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzĸɴоɴɴɴɴɴɴɴɴɴɴɴɴɴɴɴɴɴɴɴɴɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱȼdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzdzȼȼȼȼȼȼȼȼɽȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼǻůůůůůůůůůůůůůůůůůůůůů´ɽƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƱƺŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹķĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮпŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰķķķķķķƺķķķķķķķķķķķķķķķķķķķķķķķɽķķķķķķììììììììììììììììììììĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮ¶µµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµµμ««««««««««««««««««««ůůìììììììììììììììììììƺ̹ƱƱ«««««««««««««««««««ǻооооооооооооооооооооооооооооооɴDzȳμμμμμμμμμμμμμμμμμμμμμμμμμμμμμůμȳɵͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻ¬轥ɵʶDzĮ̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹㼣ʶ̹ʿ˹ʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˿޻̹ͻ¶ɽȼɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵɵںͺϾķŹȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳȳԹϽĸµDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzDzϸѿöŸпůůůůůůůůůůůůůůůůůůůůůůů񶛆ɶŹƹͻĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮĮŶĸȽǻ˷¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬鴘ʿǻȼȳ䳗íŹʿĴɾů߲Űȴʿë޾۱}}}}}}}}dzλ}}}}}}}}˲ݽְ{{{{{{{{ɵ˷{{{{{{{{б}}}}}}}}±}}}}}}}ݼүzzzzzzzz̸ȴzzzzzzzz԰||||||||İ|||||||̮ܺxxxxxxxxλưxxxxxxxxدzzzzzzzzǯzzzzzzz۹ǭvvvvvvvvоìvvvvvvvvݮxxxxxxxxʮxxxxxxx۸¬tttttttttttttttt⭎vvvvvvvv̭vvvvvvv{ڶȽrrrrrrrrŸrrrrrrrr欌ttttttttϬtttttttvٵʷķppppppppȼpppppppp쪋rrrrrrrrҪrrrrrrrrشooooooooooooooooqqqqqqqq֪qqqqqqqqزʿDzͺmmmmmmmmmmmmmmmmoooooooo٨ooooooooױ}}}}}}}}}}ʷ}}}}}}}}ʶkkkkkkkk{kkkkkkkkmmmmmmmmݧmmmmmmmm֯zzzzzzzzzzdzzzzzzzzzȴiiiiiiiiuiiiiiiijmkkkkkkk䦅kkkkkkkk֮xxxxxxxxxxưxxxxxxxxоggggggggogggggggoqiiiiiii쥃iiiiiiiiխvvvvvvvvvvívvvvvvvvףeeeeeeeejeeeeeeeutggggggggggggggsԬtttttttttttttttttt|dddddddeddddddd|yfffffffʿgffffffϽԪqqqqqqqqqqqqqqqqqqޤh}b}b}b}b}bx}b}b}b}b}b}b}b}b~dddddddǼddddd{өooooooooooooooooooרo{_{_{_s{_{_{_{_{_{_{_{_}b}b}b}b}b}b}bĸ~c}b}bҨmmmmmmmmmmmmmmmmmmz^z^z^z^z^z^z^z^|`|`|`|`|`|`|`Ҧkkkkkkkkklkkkkkkkkx\x\x\x\x\x\x\x\ªz^z^z^z^z^z^z^ǻѥhhhhhhhhhohhhhhhhhy]wZwZwZwZwZwZwZʶx\x\x\x\x\x\iУfffffffffv}ffffffffpvYvYvYvYvYvYvYw[w[w[w[w[{`Тddddddddd|yddddddddtVtVtVtVtVtVtWİěwZvYvYvYnϡ~b~b~b~b~b~b~b~b~bv~b~b~b~b~b~b~b~bԙrTrTrTrTrTrTfRTOűͺ̸Ο{_{_{_{_{_{_{_{_{_r{_{_{_{_{_{_{_{_ʶrTqSqSqShRUOTO]XxtUPUPrm˹͞z]z]z]z]z]z]z]z]z]oz]z]z]z]z]z]z]z]]P]OWOTOTOTOTOTOTOTOTOTO͝x[x[x[x[x[x[x[x[x[ĭkx[x[x[x[x[x[x[x[miTOTOTOTOTOTOTOTOTOTOTOTOTO̜vYvYvYvYvYvYvYvYvYʵhvYvYvYvYvYvYvYvYb]TOTOTOTOTOTOTO~zTOTOTOTOTOTOUP˚tVtVtVtVtVtVtVtVtVϾdtVtVtVtVtVtVtVtVYUTOTOTOTOTOTOTO|xxtTOTOTOTOTOTOTOȵ˙rTrTrTrTrTrTrTrTrTƺ}arTrTrTrTrTrTrTrTieUPYU\WTOTOTOTOTOTOTOtoqmTOTOTOTOTOTOTO˹دyuʗpRpRpRpRpRpRpRpRpRz^pRpRpRpRpRpRpRpR~zTOTOTOTOTOzv`[TOTOTOTOTOTOTOjfjfTOTOTOTOTOTOTOͼİUPTOTOTOUPƲɖoPoPoPoPoPoPoPoPoP{^oPoPoPoPoPoPoPoPTOTOTOTOTOTOTOe`TOTOTOTOTOTOTOa\d`TOTOTOTOTOTOTOпWRTOTOTOTOTOUPɕmNmNmNmNmNmNmNmNmN{_mNmNmNmNmNmNmNmNʿ[VTOTOTOTOTOTOTOidTOTOTOTOTOTOTOXS]YTOTOTOTOTOTOTOTOTOTOTOTOTOTOɕmNmNmNmNmNmNmNmNmN~bmNmNmNmNmNmNmNmNʾĀTOTOTOTOTOTOTOTOϾmiTOTOTOTOTOTOTOTOWRTOTOTOTOTOTOTOTOTOTOTOTOTOTOVQɕmNmNmNmNmNmNmNmNmNfmNmNmNmNmNmNmNmNʾTOTOTOTOTOTOTOTOʸrmTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOۀTOTOTOTOTOTOTOTOɕmNmNmNmNmNmNmNmNnOjmNmNmNmNmNmNmNmNɾTOTOTOTOTOTOTOTOƳvrTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOЀTOTOTOTOTOTOTOTOʕmNmNmNmNmNmNmNmN|amNmNmNmNmNmNmNmNʾîTOTOTOTOTOTOTOTOzvTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOʀTOTOTOTOTOTOTOTOnOmNmNmNmNmNmNmNоpRmNmNmNmNmNsVƳTOTOTOTOTOTOTOTO{TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOŀTOTOTOTOTOTOTOTOµpQmNmNmNmNmNĮμʸTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOWRȳ}νTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOڀTOTOTOTOTOTOTOTOϾTOTOTOTOTOTOTO\Wݶ{wvrϿ€TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOԀTOTOTOTOTOTOTOTO˹TOTOTOTOTOTOTOa\îTOTOTOTOTOTO{įǀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϿ̀TOTOTOTOTOTOTOTOȵTOTOTOTOTOTOTOeaUPTOTOTOTOTOTOTOUPTOTOTOTOTOWR̀TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹ƀTOTOTOTOTOTOTOTOİTOTOTOTOTOTOTOieҀTOTOTOTOTOTOTOTO[WTOTOTOTOTOTOTOTOʷҀTOTOTOTOTOTOTOTO~TOTOTOTOTOTOTOTOƳTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOnjҀTOTOTOTOTOTOTOTOTOwsTOTOTOTOTOTOTOTOʷ؀TOTOTOTOTOTOTOTO|xTOTOTOTOTOTOTOTOͻTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOsoҀTOTOTOTOTOTOTOTOTOtoTOTOTOTOTOTOTOTOʸހTOTOTOTOTOTOTOTOvrTOTOTOTOTOTOTOTOȵTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOxtҀTOTOTOTOTOTOTOTOTOplTOTOTOTOTOTOTOTOʸTOTOTOTOTOTOTOTOokTOTOTOTOTOTOTOTOïTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO|xҀTOTOTOTOTOTOTOTOTOmiTOTOTOTOTOTOTOTO˹TOTOTOTOTOTOTOTOieîTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO}ҀTOTOTOTOTOTOTOTOTOkfTOTOTOTOTOTOTOTO˹TOTOTOTOTOTOTOTOc_ȵTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOͼhdTOTOTOTOTOTOTOTO˹TOTOTOTOTOTOTOTO]YͻTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOűieTOTOTOTOTOTOTOTO˹TOTOTOTOTOTOTOTOWRTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOkfTOTOTOTOTOTOTOTO˹UPTOTOTOTOTOTOTOTOƀTOTOTOTOTOTOTOTO}TOTOTOTOTOTOTOWRTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOlhTOTOTOTOTOTOTOTO̺ZUTOTOTOTOTOTOTOTÒTOTOTOTOTOTOTOTO{wTOTOTOTOTOTOTOZUTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOmiTOTOTOTOTOTOTOTO̺_[TOTOTOTOTOTOTOTOԀTOTOTOTOTOTOTOTOtp~TOTOTOTOTOTOTO]YTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOokTOTOTOTOTOTOTOTO̺e`TOTOTOTOTOTOTOTOۀTOTOTOTOTOTOTOTOnj{wTOTOTOTOTOTOTOa]TOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOyuqmTOTOTOTOTOTOTOTO̻jfTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOidtpTOTOTOTOTOTOTOUPTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOokrnTOTOTOTOTOTOTOTO̻plTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOc_miTOTOTOTOTOTOTOTOgbνZUTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOeatpTOTOTOTOTOTOTOTOͻvrTOTOTOTOTOTOTOTOȵ̻TOTOTOTOTOTOTOTO^YgcTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOîҀTOTOTOTOTOTOTOTOTO]XvrTOTOTOTOTOTOTOTOͻ{wTOTOTOTOTOTOTOTOYT{e`TOTOTOTOTOTOTOTOTOYTa\TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOƳҀTOTOTOTOTOTOTOTOTOUPzvTOTOTOTOTOTOTOTOͻ}TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUP[VTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOɷҀTOTOTOTOTOTOTOTOTOTO|xTOTOTOTOTOTOTOTOͼTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUPTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOͻҀTOTOTOTOTOTOTOTOTOTO|TOTOTOTOTOTOTOTOͼTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOkgTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO­uqidTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOkgTOހTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO}okTOWR؀TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOdzTOTOTOTOTOTOTOTOϾ­TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOпTO|xνTOTO}рTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϾűTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOc_TOڀTOTOTOϾʀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϿɷTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOűYUTOTO_ZÀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTO`[TOTOTOTOTOTOTOTOϿνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOԀUPTOTOTOTOTOϿTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOYU墂TOTOTOTOTOTOTOTOTOϿTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϾjfTOTOVQ̺TOTOTOTOȵʸTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϿƀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹TOTOTOxtUPTOTOTOZUƲTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϿˀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOƳπUPTOTOTOTOTOTOTOfbTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϿрTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOîb]TOTOTOTOȀTOTOTOTOTOzvTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϾ׀TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOzvTOTOTOTOrnjfTOTOTOTOTOzvTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUPҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOϾ܀TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOʸͼTOTOTOTOTOTOmiڲTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOYUҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO]XvrTOTOTOTOTOTOUP]YTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO]YҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOԀUPTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOa]ҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOeac_TOTOTOTOTOTOa\TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOgbҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOνTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOƳqmTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOkfҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOͼTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOto[WTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOokҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOͼTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOWR̓XSTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOtpҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOͻYTTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOǴUPTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOxtҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOͻ^YTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOWRTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO~zҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO̻d`TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO~zχ]YTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO~ɕokzvҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO̻ieTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOtojfTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOȶid[WTO}ҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO̺ӚwsokTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOxtTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOjf~~hdTOTOTOTOɶTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO̺TO}ytpTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOƍeaTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOπTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹TO]WjfTOa]zvTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOWRTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUP­VQTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹TOTO}yidTOTOTOTOhd~vrYUTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOa]䰕WRTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOa\xtTOTOTOTOҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹vrTOTOTOplTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO껣c^TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUPƳTOTOTOTOTOtpҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹]YTOTOTOTO򪌉TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOgbĪ\WTOTOTOTOTOTOTOTOTOTOTOTOTOUPYTTOTOTOTOTOd`ҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹즇TOTOTOTOTOmiƋc_TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOjfȵ֨gbhdпjfVQTOTOTOTOTOb]űTOTOTOTOTOTOUPҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOʸű^YTOTOTOTOTOTOƳįeaTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUP}ɂWRTOTOTOTOTO^Y]XTOTOTOTOTOTOTOuqҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOʸ˹eaTOTOTOTOTOTOTOe`ǭ_[TOTOTOTOTOTOTOTOTOTOTOTOZU|įe`TOTOTOTOTOTOTOTO]YİʷTOTOTOTOTOTOTOTOUPҀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOʷkfTOTOTOTOTOTOTOTOTOͻп}vrvr|x̺蹠idTOTOfbЀTOTOTOTOTOTOTOTOTOTOTO~z~TOTOTOTOTOTOTOTOTOUP{TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO|fbTOTOTOTOTOTOTOTOTOTO~VQTOTOTOTOTOTO|xɷTOTOTOTOTOTOTOTOTOTOTOTOhdokTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOc^ݓnjTOTOTOTOTOTOTOTOTOͼįTOTOTOTOTOTOTOTOTOTOTOTOTOc_kgTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO]Yߊa]TOTOTOTOTOTOTOTOTOTO̻TOTOTOTOTOTOTOTOTOTOTOTOTOTOxtxtTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOa]܈_ZTOTOTOTOTOTOTOTOTOTOTOgc׀TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOʸUPTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOtogbTOTOTOTOTOTOTOTOTOTOTOTO^Yb]TOTOTOTOTOTOTOTOTOTOTOTOTOTOb]֗soTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOWRTOTOTOTOTOTOTOTOTOTOTOTOTOa\TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOǘtpTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO˹TOTOTOTOTOTOTOTOTOTOTOTOTOTOrm_ZTOTOTOTOTOTOTOTOTOTOTOTOTOTOִ`[TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO[Vc_TOTOTOTOTOTOTOTOTOTOTOTOTOTOĀTOTOTOTOTOTOTOTOTOTOTOTOTOTOzvͼ|xXSTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOnjTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOlhƳ~zvvrkfkfkfsows~ͻidTOTOTOTOTOTOTOTOTOTOTOTOTOTO_ZTOTOTOTOTOTOTOTOTOTOTOTOgc؀TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOzvTOTOTOTOTOTOTOTOTOTOTOTOTOTOkg]YTOTOTOTOTOTOTOTOTO|xTOTOTOTOTOTOTOTOTOTOTOTOTOXS詌UPTOTOTOTOTOTO_ZΨ]XTOTOTOTOc^hdTOTOTOTOTOTOTOTOTOTOTOTOTOʷ۫YTTOTOTO`[{wTOTOTOTOTOTOTOTOTOUPfbTOTOTOTOTOTOTOTOTOTOTOTOƲԇ]YTOTOTOTOTOTOTOTOTOTOTOTOieTOTOTOTOTOTOTOTOTOTOVQǴ]YTOTOTOTOTOTOTOTOTOTOTOTOTOTOkg߅[WTOTOTOTOTOTOTOTOmi|TOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO؏hdTOTOTOTOTOkfűπTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOUPͻTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOɷ|xTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOmiTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO|xTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTO̺ԀTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOWR|xTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOa]TOTOTOTOTOTOTOTOTOTOTOTOTOTOrm܋c^TOTOTOTOTOTOTOTOTOTOTOTOplTOTOTOTOTOTOTOTOTOWRڱe`TOTOTOTOmisardana-1.2.0/scripts/0000755000234100017500000000000012174204361016217 5ustar cpascualcpascual00000000000000sardana-1.2.0/scripts/MacroServer0000755000234100017500000000311212174204306020371 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["main"] __docformat__ = 'restructuredtext' import datetime __START_TIME = datetime.datetime.now() def set_src(): import sys import os.path as osp sar_dir = osp.join(osp.dirname(osp.abspath(__file__)), osp.pardir, 'src') sys.path.append(osp.abspath(sar_dir)) try: import sardana except ImportError: # try to use code from src distribution set_src() import sardana def run(): import sardana.tango.macroserver sardana.tango.macroserver.run(start_time=__START_TIME) def main(): run() if __name__ == '__main__': main() sardana-1.2.0/scripts/Pool0000755000234100017500000000307612174204306017063 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["main"] __docformat__ = 'restructuredtext' import datetime __START_TIME = datetime.datetime.now() def set_src(): import sys import os.path as osp sar_dir = osp.join(osp.dirname(osp.abspath(__file__)), osp.pardir, 'src') sys.path.insert(0,osp.abspath(sar_dir)) try: import sardana except ImportError: # try to use code from src distribution set_src() import sardana def run(): import sardana.tango.pool sardana.tango.pool.run(start_time=__START_TIME) def main(): run() if __name__ == '__main__': main() sardana-1.2.0/scripts/Sardana0000755000234100017500000000306112174204306017515 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["main"] __docformat__ = 'restructuredtext' import datetime __START_TIME = datetime.datetime.now() def set_src(): import sys import os.path as osp sar_dir = osp.join(osp.dirname(osp.abspath(__file__)), osp.pardir, 'src') sys.path.append(osp.abspath(sar_dir)) try: import sardana except ImportError: # try to use code from src distribution set_src() import sardana def run(): import sardana.tango sardana.tango.run(start_time=__START_TIME) def main(): run() if __name__ == '__main__': main()sardana-1.2.0/scripts/h5toascii0000755000234100017500000000763212174204306020044 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## ''' Script for extracting "scan tables" from Sardana NeXus files into an tab-separated ASCII tables. When data from multiple entries are extracted from a file, each table is stored in a different file. The output files for a given input file are stored in a directory whose name matches the input file name (minus extension) Usage: python h52ascii.py [ [] ...] If no entry names are provided, all entries from the given nexus file name will be extracted. Note: only scalar values are extracted ''' import nxs import sys,os import numpy def measurement2ascii(fd, entryname, ofname): #check if there is a measurement datagroup tmp = "/%s/measurement"%entryname try: fd.openpath(tmp) except: print 'Cannot open hdf5 path "%s". Skipping.'%tmp return False #read the point number data ptnb_names = ('Pt_No','point_nb','#Pt No') #possible ways of storing the point number (along different versions) for i,ptnb_name in enumerate(ptnb_names): try: fd.opendata(ptnb_name) break except: print 'cannot open %s'%ptnb_name if i == len(ptnb_names)-1: #if this was not the last choice print 'I give up!' return False ptnb = fd.getdata() fd.closedata() #prepare a list with column names and a table made of data "columns" namelist=[ptnb_name] table = [ptnb.copy().flatten()] for name,nxclass in fd.entries(): if name == ptnb_name: continue if nxclass != 'SDS': continue #not a dataset dshape,dtype = fd.getinfo() if tuple(dshape) != ptnb.shape: continue #not a scalar (incompatible shape) table.append(fd.getdata().flatten()) namelist.append(name) #write the table to a file try: datfile = open(ofname,'w') except: print 'Cannot create file "%s". Skipping.'%ofname return False datfile.write("\t".join(namelist)) #write a header of column names datfile.write("\n") numpy.savetxt(datfile, numpy.vstack(table).transpose(), delimiter='\t') #write the data table datfile.close() return True def main(): if len(sys.argv) > 1: fname = sys.argv[1] else: print "Usage:\nh5toascii [ [] ...] " sys.exit(1) entrynames = sys.argv[2:] fd = nxs.open(fname,'r') if len(entrynames)==0: entrynames = [n for n,c in fd.entries() if c=='NXentry'] dirname,ext = os.path.splitext(fname) try: os.makedirs(dirname) except: print 'Cannot create dir "%s". Skipping.'%dirname for ename in entrynames: ofname = os.path.join(dirname,"%s.dat"%ename) print "Extracting %s:%s to %s"%(fname,ename,ofname) measurement2ascii(fd, ename, ofname) fd.close() if __name__ == "__main__": main()sardana-1.2.0/scripts/h5tospec0000755000234100017500000001715412174204306017706 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## ''' Script for extracting "scans" from Sardana NeXus files into Sardana Spec Files. Usage: h5spec [> ] [2>> sys.stderr, entry except: print >> sys.stderr, 'Cannot open hdf5 path "%s/pre_scan_snapshot". Skipping.'%entry return _mdata def processEntry(fd, entry): ''' process one entry from a hdf5 file it creates a string with all the data and prints it to the stdout in the end. It could be evenually easily modified to return the values and to be introduced in a class (to get it out from this simple script) ''' #_myMovables = [] # This gets the motors in order to write them in the first columns mystring = "" # the string will construct the scan (and printed at the end) try: fd.openpath("/%s/entry_identifier" % entry) mystring = "#S %s " % str(fd.getdata()) fd.openpath("/%s/title" % entry) _mycmd = str(fd.getdata()) mystring += " %s \n" % _mycmd _myMovables= _getMovables(_mycmd) fd.openpath("/%s/start_time" % entry) mystring += "#D %s \n" % h52spectime(fd.getdata()) # need to know here the timer for the counting time. In the mean time # I use the last value of the cmd line (usually the ct time!!, not always ojo). mystring += "#T %s (seconds)\n" % _mycmd.split(' ').pop() #print mytime except: print >> sys.stderr, 'Error opening/processing hdf5 path "%s/...". Skipping.'% entry mystring += "#P0 " _metadata = getMetadata(fd, entry) for i in _metadata.values(): mystring += ' ' + str(i) mystring += '\n' tmp = "/%s/measurement/point_nb" % entry tmp2= "/%s/measurement/Pt_No" % entry try: fd.openpath(tmp) except: #print 'Cannot open hdf5 path "%s". Skipping.'%tmp try: fd.openpath(tmp2) except: #print 'Cannot open hdf5 path "%s". Skipping.'%tmp return False ptnb = fd.getdata() fd.closedata() headers = [] data = {} for name,nxclass in fd.entries(): if name == 'point_nb' or name == "#Pt No": continue if name == 'pre_scan_snapshot' : continue dshape,dtype = fd.getinfo() if tuple(dshape) != ptnb.shape: print >> sys.stderr, "Skipping (no data or not a scalar ???) %s in %s" % (name, entry), print >> sys.stderr, ptnb.shape continue #not a scalar (incompatible shape) #insert data and headers in the rigth order (movables first) mydata = fd.getdata().flatten() if name in _myMovables: headers.insert(_myMovables.index(name), name) else: headers.append(name) data[name] = mydata mystring += "#N %d \n" % len(headers) mystring += "#L " for i in headers: mystring += ' ' + i mystring += "\n" #print >>sys.stderr, headers #print >>sys.stderr, _myMovables #print >>sys.stderr, ptnb.size #print >>sys.stderr, data #print >>sys.stderr, ptnb for i in range(ptnb.size): # Movables (motors) come first. Then the other columns (exp channels) for n in [channel for channel in _myMovables if channel in headers]: mystring += ' ' + str(data[n][i]) for n in [channel for channel in headers if channel not in _myMovables]: mystring += ' ' + str(data[n][i]) mystring += '\n' try: fd.openpath("/%s/end_time" % entry) mystring += "#C Scan ended at %s \n" % h52spectime(fd.getdata()) except: print >> sys.stderr, 'Cannot open hdf5 path "%s/end_time". Skipping.'% entry print mystring def measurement2spec(fd): """ Takes a file (hdf5) as an inputProcess a hdf5 file and outputs the result to the stdout. One can redirect the output to create the file. Information and error messages are output to stderr, in order not to pollute the file """ mystring = "" mystring += "#F %s\n" % fd.filename outFileAttrs = "#CCC original Nexus hdf5 file: %s\n" % fd.getattrs() outCurrentDate = "#C conversion date: %s\n" % time.asctime() entrynames = [name for name,c in fd.entries() if c=='NXentry'] mystring += "#E %s\n" % fd.getattrs()['epoch'] mystring += "#D %s\n" % time.asctime(time.localtime(fd.getattrs()['epoch'])) mystring += "#C User \n" # Gets metadata headers (motor names usually) from the first entry (asuming all the same!) _metadata = getMetadata(fd,entrynames[0]) mystring += "#O0" for i in _metadata.keys(): mystring += ' ' + i mystring += '\n' + outFileAttrs mystring += outCurrentDate print mystring #Sort entry2 before entry10 (otherwhise, it was strictly alphabetic) for entry in sorted(entrynames, key = len): processEntry(fd, entry) def main(): ''' process the entire file (todo: many things. Do only the selected entries, convert it to a class) ''' if len(sys.argv) > 1: fname = sys.argv[1] else: print "Usage:\npython h5tospec [> ] [2> log/error file]" sys.exit(1) fd = nxs.open(fname,'r') measurement2spec(fd) fd.close() if __name__ == "__main__": main() sardana-1.2.0/scripts/spectoascii0000755000234100017500000000571512174204306020462 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## ''' Script for extracting "scan tables" from Sardana Spec files into single-scan tab-separated ASCII tables. When data from multiple scans are extracted from a file, each table is stored in a different file. The output files for a given input file are stored in a directory whose name matches the input scan ID Usage: python spectoascii.py [ [] ...] If no scan IDs are provided, all scans from the given Spec file will be extracted. Note that this is not a generic Spec conversor. Spec files created by means other than the Sardana SPEC_FileRecorder may not be converted properly. ''' import sys,os def main(): if len(sys.argv) > 1: fname = sys.argv[1] else: print "Usage:\nspectoascii [ [] ...] " sys.exit(1) scanids = sys.argv[2:] or None f = open(fname,'r') s = f.read() f.close() dirname,ext = os.path.splitext(fname) try: os.makedirs(dirname) except: print 'Cannot create dir "%s". Skipping.'%dirname for scan in s.split('\n\n'): lines = scan.split('\n') if not lines[0].startswith('#S '): continue scan_name = lines[0].split()[1] if scanids is None or scan_name in scanids: #extract only selected ids ofname = os.path.join(dirname,"%s.dat"%scan_name) print "Extracting %s:%s to %s"%(fname,scan_name,ofname) try: ofile = open(ofname,'w') except: print 'Cannot create file "%s". Skipping.'%ofname continue for line in lines[1:]: if line.startswith('#L '): ofile.write('\t'.join(line[3:].split(' '))+'\n') elif line.startswith('#'): continue else: ofile.write('\t'.join(line.split())+'\n') ofile.close() if __name__ == "__main__": main()sardana-1.2.0/scripts/spock0000755000234100017500000000321412174204306017263 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """The Spock startup file. This executable is actually an extension of the ipython file that can be found in /ipython (prefix usually being in linux '/usr/bin'""" __all__ = [ "main" ] __docformat__ = 'restructuredtext' def set_src(): import sys import os.path as osp sar_dir = osp.join(osp.dirname(osp.abspath(__file__)), osp.pardir, 'src') sys.path.append(osp.abspath(sar_dir)) try: from sardana.spock import genutils except ImportError: # try to use code from src distribution set_src() from sardana.spock import genutils def main(): genutils.run() if __name__ == '__main__': main() sardana-1.2.0/src/0000755000234100017500000000000012174204361015317 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/0000755000234100017500000000000012174204361016730 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/macroserver/0000755000234100017500000000000012174204361021260 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/macroserver/macros/0000755000234100017500000000000012174204361022544 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/macroserver/macros/examples/0000755000234100017500000000000012174204361024362 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/macroserver/macros/examples/__init__.py0000644000234100017500000000213512174204310026466 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package contains the macroserver example macros""" __docformat__ = 'restructuredtext' sardana-1.2.0/src/sardana/macroserver/macros/examples/funcs.py0000644000234100017500000000460412174204310026050 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Examples of macro functions""" from __future__ import print_function __all__ = ["mfunc1", "mfunc2", "mfunc3", "mfunc4", "mfunc5"] __docformat__ = 'restructuredtext' from sardana.macroserver.macro import Type, Macro, macro @macro() def mfunc1(self): """First macro function. No parameters whatsoever""" self.output("Executing %s", self.getName()) self.print("Hello",1) self.wa() @macro() def mfunc2(self, p1): """Second macro function. One parameter of unknown type""" self.output("parameter: %s", p1) @macro([ ["moveable", Type.Moveable, None, "motor to watch"] ]) def mfunc3(self, moveable): """Third macro function. A proper moveable parameter""" self.output("Moveable %s is at %s", moveable.getName(), moveable.getPosition()) self.ascan(moveable, 0, 10, 10, 0.1) self.mfunc1() @macro() def mfunc4(self, *args): """Fourth macro function. A list of parameters of unknown type""" self.output("parameters %s", args) @macro() def mfunc5(self, *args): """Fifth macro function. A list of parameters of unknown type""" self.output("parameters %s", args) @macro([ ["moveable", Type.Moveable, None, "moveable to move"], ["position", Type.Float, None, "absolute position"] ]) def move(self, moveable, position): """This macro moves a motor to the specified position""" moveable.move(position) self.print("Motor ended at ", moveable.getPosition()) sardana-1.2.0/src/sardana/macroserver/macros/examples/hooks.py0000644000234100017500000001401512174204310026052 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains macros that demonstrate the usage of hooks""" __all__ = ["captain_hook", "captain_hook2", "loop", "hooked_scan", "hooked_dummyscan"] __docformat__ = 'restructuredtext' from sardana.macroserver.macro import * class loop(Macro, Hookable): """A macro that executes a for loop. It accepts hooks. This macro is part of the examples package. It was written for demonstration purposes""" hints = { 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq') } param_def = [['start', Type.Integer, None, 'start point'], ['stop', Type.Integer, None, 'end point'], ['step', Type.Integer, 1, 'step']] def hook1(self): self.output("En hook 1") def run(self, start, stop, step): self.info("Starting loop") self.hooks = [ (self.hook1, ["pre-acq"])] for i in xrange(start, stop, step): self.output("At step %d" % i) self.flushOutput() for hook,hints in self.hooks: self.info("running hook with hints="+repr(hints)) hook() self.info("Finished loop") class captain_hook(Macro): """A macro that executes a loop macro. A hook was attached so that in each step of the loop this hook is executed. This macro is part of the examples package. It was written for demonstration purposes""" param_def = [['start', Type.Integer, None, 'start point'], ['stop', Type.Integer, None, 'end point'], ['step', Type.Integer, 1, 'step']] def hook(self): self.info("\thook execution") def run(self, start, stop, step): loop_macro = self.createMacro("loop",start,stop,step) loop_macro.hooks = [ self.hook ] self.runMacro(loop_macro) class captain_hook2(Macro): """A macro that executes a loop macro. A hook was attached so that in each step of the loop this hook is executed. This macro is part of the examples package. It was written for demonstration purposes""" param_def = [['start', Type.Integer, None, 'start point'], ['stop', Type.Integer, None, 'end point'], ['step', Type.Integer, 1, 'step']] def hook(self): self.execMacroStr(["lsm"]) def run(self, start, stop, step): loop_macro = self.createMacro("loop",start,stop,step) #h = self.createExecMacroHook(["lsm"]) loop_macro.hooks = [ self.hook ] #it gives the "pre-acq" hint to the hook self.runMacro(loop_macro) class hooked_scan(Macro): """An example on how to attach hooks to the various hook points of a scan. This macro is part of the examples package. It was written for demonstration purposes""" param_def = [ ['motor', Type.Moveable,None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def hook1(self): self.info("\thook1 execution") def hook2(self): self.info("\thook2 execution") def hook3(self): self.info("\thook3 execution") def hook4(self): self.info("\thook4 execution") def hook5(self): self.info("\thook5 execution") def hook6(self): self.info("\thook6 execution") def run(self, motor, start_pos, final_pos, nr_interv, integ_time): ascan, pars = self.createMacro("ascan",motor, start_pos, final_pos, nr_interv, integ_time) ascan.hooks = [ (self.hook1, ["pre-acq"]), (self.hook2, ["pre-acq","post-acq","pre-move", "post-move","aaaa"]), self.hook3, (self.hook4, ["pre-scan"]), (self.hook5, ["pre-scan", "post-scan"]), (self.hook6, ["post-step"])] self.runMacro(ascan) class hooked_dummyscan(Macro): """An example on how to attach hooks to the various hook points of a scan. This macro is part of the examples package. It was written for demonstration purposes""" param_def = [ ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def hook1(self): self.info("\thook1 execution") def hook2(self): self.info("\thook2 execution") def hook3(self): self.info("\thook3 execution") def run(self, start_pos, final_pos, nr_interv, integ_time): dummyscan,pars = self.createMacro("dummyscan",start_pos, final_pos, nr_interv, integ_time) dummyscan.hooks = [ (self.hook1, ["pre-scan"]), (self.hook2, ["pre-acq","post-acq","pre-move", "post-move","aaaa"]),(self.hook3, ["post-scan"])] self.runMacro(dummyscan) sardana-1.2.0/src/sardana/macroserver/macros/examples/parameters.py0000644000234100017500000001256212174204310027077 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains macros that demonstrate the usage of macro parameters""" from sardana.macroserver.macro import * __all__ = ["pt0", "pt1", "pt2", "pt3", "pt4", "pt5", "pt6", "pt7", "pt8", "pt9"] class pt0(Macro): """Macro without parameters. Pretty dull""" param_def = [] def run(self): pass class pt1(Macro): """Macro with one float parameter: Each parameter is described in the param_def sequence as being a sequence of for elements: name, type, default value and description""" param_def = [ [ 'value', Type.Float, None, 'some bloody float'] ] def run(self, f): pass class pt2(Macro): """Macro with one Motor parameter: Each parameter is described in the param_def sequence as being a sequence of for elements: name, type, default value and description""" param_def = [ [ 'motor', Type.Motor, None, 'some bloody motor'] ] def run(self, m): pass class pt3(Macro): """Macro with a list of numbers as parameter: the type is a sequence of parameter types which is repeated. In this case it is a repetition of a float so only one parameter is defined. By default the repetition as a semantics of 'at least one'""" param_def = [ [ 'numb_list', [ [ 'pos', Type.Float, None, 'value'] ], None, 'List of values'], ] def run(self, *args, **kwargs): pass class pt4(Macro): """Macro with a list of motors as parameter: the type is a sequence of parameter types which is repeated. In this case it is a repetition of a motor so only one parameter is defined. By default the repetition as a semantics of 'at least one'""" param_def = [ [ 'motor_list', [ [ 'motor', Type.Motor, None, 'motor name'] ], None, 'List of motors'], ] def run(self, *args, **kwargs): pass class pt5(Macro): """Macro with a motor parameter followed by a list of numbers""" param_def = [ [ 'motor', Type.Motor, None, 'Motor to move'], [ 'numb_list', [ [ 'pos', Type.Float, None, 'value'] ], None, 'List of values'], ] def run(self, *args, **kwargs): pass class pt6(Macro): """Macro with a motor parameter followed by a list of numbers. The list as explicitly stated an optional last element which is a dictionary that defines the min and max values for repetitions""" param_def = [ [ 'motor', Type.Motor, None, 'Motor to move'], [ 'numb_list', [ [ 'pos', Type.Float, None, 'value'], { 'min' : 1, 'max' : None } ], None, 'List of values'], ] def run(self, *args, **kwargs): pass class pt7(Macro): """Macro with a list of pair Motor,Float""" param_def = [ [ 'm_p_pair', [ [ 'motor', Type.Motor, None, 'Motor to move'], [ 'pos', Type.Float, None, 'Position to move to'] ], None, 'List of motor/position pairs'] ] def run(self, *args, **kwargs): pass class pt8(Macro): """Macro with a list of pair Motor,Float. The min and max elements have been explicitly stated""" param_def = [ [ 'm_p_pair', [ [ 'motor', Type.Motor, None, 'Motor to move'], [ 'pos', Type.Float, None, 'Position to move to'], { 'min' : 1, 'max' : 2 } ], None, 'List of motor/position pairs'] ] def run(self, *args, **kwargs): pass class pt9(Macro): """Same as macro pt7 but witb old style ParamRepeat. If you are writing a macro with variable number of parameters for the first time don't even bother to look at this example since it is DEPRECATED.""" param_def = [ ['m_p_pair', ParamRepeat(['motor', Type.Motor, None, 'Motor to move'], ['pos', Type.Float, None, 'Position to move to'], min=1, max= 2), None, 'List of motor/position pairs'], ] def run(self, *args, **kwargs): pass class twice(Macro): """twice description.""" # uncomment the following lines as necessary. Otherwise you may delete them param_def = [ [ "value", Type.Float, 23, "value to be doubled" ] ] result_def = [ [ "result", Type.Float, 23, "the double of the given value" ] ] #hints = {} #env = (,) # uncomment the following lines if need prepare. Otherwise you may delete them #def prepare(self): # pass def run(self, n): return 2*nsardana-1.2.0/src/sardana/macroserver/macros/examples/plotting.py0000644000234100017500000000311312174204310026564 0ustar cpascualcpascual00000000000000import math from numpy import linspace from scipy.integrate import quad from scipy.special import j0 from sardana.macroserver.macro import macro, Type def j0i(x): """Integral form of J_0(x)""" def integrand(phi): return math.cos(x * math.sin(phi)) return (1.0/math.pi) * quad(integrand, 0, math.pi)[0] @macro() def J0_plot(self): """Sample J0 at linspace(0, 20, 200)""" x = linspace(0, 20, 200) y = j0(x) x1 = x[::10] y1 = map(j0i, x1) self.pyplot.plot(x, y, label=r'$J_0(x)$') # self.pyplot.plot(x1, y1, 'ro', label=r'$J_0^{integ}(x)$') self.pyplot.title(r'Verify $J_0(x)=\frac{1}{\pi}\int_0^{\pi}\cos(x \sin\phi)\,d\phi$') self.pyplot.xlabel('$x$') self.pyplot.legend() from numpy import random @macro() def random_image(self): """Shows a random image 32x32""" img = random.random((32, 32)) self.pyplot.matshow(img) import numpy @macro([["interactions", Type.Integer, None, ""], ["density", Type.Integer, None, ""]]) def mandelbrot(self, interactions, density): x_min, x_max = -2, 1 y_min, y_max = -1.5, 1.5 x, y = numpy.meshgrid(numpy.linspace(x_min, x_max, density), numpy.linspace(y_min, y_max, density)) c = x + 1j * y z = c.copy() fractal = numpy.zeros(z.shape, dtype=numpy.uint8) + 255 finteractions = float(interactions) for n in range(interactions): z *= z z += c mask = (fractal == 255) & (abs(z) > 10) fractal[mask] = 254 * n / finteractions self.pyplot.imshow(fractal) sardana-1.2.0/src/sardana/macroserver/macros/examples/scans.py0000644000234100017500000006007112174204310026041 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ Macro library containning examples demonstrating specific features or tricks for programming macros for Sardana. Available Macros are: ascanr toothedtriangle """ __all__ = ["ascan_demo", "ascanr", "toothedtriangle", "regscan", "reg2scan", "reg3scan", "a2scan_mod"] __docformat__ = 'restructuredtext' import os import numpy from sardana.macroserver.macro import * from sardana.macroserver.scan import * class ascan_demo(Macro): """ This is a basic reimplementation of the ascan` macro for demonstration purposes of the Generic Scan framework. The "real" implementation of :class:`sardana.macroserver.macros.ascan` derives from :class:`sardana.macroserver.macros.aNscan` and provides some extra features. """ hints = { 'scan' : 'ascan_demo'} #this is used to indicate other codes that the macro is a scan env = ('ActiveMntGrp',) #this hints that the macro requires the ActiveMntGrp environment variable to be set param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): #parse the user parameters self.start = numpy.array([start_pos], dtype='d') self.final = numpy.array([final_pos], dtype='d') self.integ_time = integ_time self.nr_points = nr_interv+1 self.interv_size = ( self.final - self.start) / nr_interv self.name='ascan_demo' env = opts.get('env',{}) #the "env" dictionary may be passed as an option #create an instance of GScan (in this case, of its child, SScan self._gScan=SScan(self, generator=self._generator, moveables=[motor], env=env) def _generator(self): step = {} step["integ_time"] = self.integ_time #integ_time is the same for all steps for point_no in xrange(self.nr_points): step["positions"] = self.start + point_no * self.interv_size #note that this is a numpy array step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): #just go through the steps yield step @property def data(self): return self._gScan.data #the GScan provides scan data class ascanr(Macro, Hookable): """This is an example of how to handle adding extra info columns in a scan. Does the same than ascan but repeats the acquisitions "repeat" times for each step. It could be implemented deriving from aNscan, but I do it like this for clarity. Look for the comments with "!!!" for tips specific to the extra info columns I do not support constrains in this one for simplicity (see ascan for that) Do an absolute scan of the specified motor, repeating measurements in each step. ascanr scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. At each step, the acquisition will be repeated "repeat" times The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be (nr_interv+1)*repeat. Count time for each acquisition is given by time which if positive, specifies seconds and if negative, specifies monitor counts. """ hints = { 'scan' : 'ascanr', 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step') } env = ('ActiveMntGrp',) param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'], ['repeat', Type.Integer, None, 'Number of Repetitions'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, repeat, **opts): self.starts = numpy.array([start_pos], dtype='d') self.finals = numpy.array([final_pos], dtype='d') self.nr_interv = nr_interv self.integ_time = integ_time self.repeat=repeat self.opts = opts self.nr_points = nr_interv+1 self.interv_sizes = ( self.finals - self.starts) / nr_interv self.name='ascanr' generator=self._generator moveables=[motor] env=opts.get('env',{}) constrains=[] extrainfodesc=[ColumnDesc(name='repetition', dtype='int64', shape=(1,))] #!!! self._gScan=SScan(self, generator, moveables, env, constrains, extrainfodesc) #!!! def _generator(self): step = {} step["integ_time"] = self.integ_time step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] extrainfo = {"repetition":0} #!!! step['extrainfo'] = extrainfo #!!! for point_no in xrange(self.nr_points): step["positions"] = self.starts + point_no * self.interv_sizes step["point_id"] = point_no for i in xrange(self.repeat): extrainfo["repetition"] = i #!!! yield step def run(self,*args): for step in self._gScan.step_scan(): yield step @property def data(self): return self._gScan.data class toothedtriangle(Macro): """toothedtriangle macro implemented with the gscan framework. It performs nr_cycles cycles, each consisting of two stages: the first half of the cycle it behaves like the ascan macro (from start_pos to stop_pos in nr_interv+1 steps).For the second half of the cycle it steps back until it undoes the first half and is ready for the next cycle. At each step, nr_samples acquisitions are performed. The total number of points in the scan is nr_interv*2*nr_cycles*nr_samples+1""" hints = { 'scan' : 'toothedtriangle', 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq') } env = ('ActiveMntGrp',) param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['start_pos', Type.Float, None, 'start position'], ['final_pos', Type.Float, None, 'position after half cycle'], ['nr_interv', Type.Integer, None, 'Number of intervals in half cycle'], ['integ_time', Type.Float, None, 'Integration time'], ['nr_cycles', Type.Integer, None, 'Number of cycles'], ['nr_samples', Type.Integer, 1 , 'Number of samples at each point'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, nr_cycles, nr_samples, **opts): self.start_pos = start_pos self.final_pos = final_pos self.nr_interv = nr_interv self.integ_time = integ_time self.nr_cycles = nr_cycles self.nr_samples = nr_samples self.opts = opts cycle_nr_points = self.nr_interv+1 + (self.nr_interv+1)-2 self.nr_points = cycle_nr_points*nr_samples*nr_cycles+nr_samples self.interv_size = ( self.final_pos - self.start_pos) / nr_interv self.name='toothedtriangle' generator=self._generator moveables = [] moveable = MoveableDesc(moveable=motor, is_reference=True, min_value=min(start_pos,final_pos), max_value=max(start_pos,final_pos)) moveables=[moveable] env=opts.get('env',{}) constrains=[] extrainfodesc=[ColumnDesc(name='cycle', dtype='int64', shape=(1,)), ColumnDesc(name='interval', dtype='int64', shape=(1,)), ColumnDesc(name='sample', dtype='int64', shape=(1,))] #!!! self._gScan=SScan(self, generator, moveables, env, constrains, extrainfodesc) #!!! def _generator(self): step = {} step["integ_time"] = self.integ_time step["post-acq-hooks"] = [] step["post-step-hooks"] = [] step["check_func"] = [] extrainfo = {"cycle":None, "interval":None, "sample":None, } step['extrainfo'] = extrainfo halfcycle1=range(self.nr_interv+1) halfcycle2=halfcycle1[1:-1] halfcycle2.reverse() intervallist=halfcycle1+halfcycle2 point_no=0 for cycle in xrange(self.nr_cycles): extrainfo["cycle"] = cycle for interval in intervallist: extrainfo["interval"] = interval step["positions"] = numpy.array([self.start_pos + (interval) * self.interv_size] ,dtype='d') for sample in xrange(self.nr_samples): extrainfo["sample"] = sample step["point_id"] = point_no yield step point_no+=1 #last step for closing the loop extrainfo["interval"] = 0 step["positions"] = numpy.array([self.start_pos] ,dtype='d') for sample in xrange(self.nr_samples): extrainfo["sample"] = sample step["point_id"] = point_no yield step point_no+=1 def run(self,*args): for step in self._gScan.step_scan(): yield step @property def data(self): return self._gScan.data class regscan(Macro): """regscan. Do an absolute scan of the specified motor with different number of intervals for each region. It uses the gscan framework. NOTE: Due to a ParamRepeat limitation, integration time has to be specified before the regions. """ hints = {'scan' : 'regscan'} env = ('ActiveMntGrp',) param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['integ_time', Type.Float, None, 'Integration time'], ['start_pos', Type.Float, None, 'Start position'], ['step_region', ParamRepeat(['next_pos', Type.Float, None, 'next position'], ['region_nr_intervals', Type.Float, None, 'Region number of intervals']), None, 'List of tuples: (next_pos, region_nr_intervals'] ] def prepare(self, motor, integ_time, start_pos, *regions, **opts): self.name='regscan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions self.regions_count = len(self.regions)/2 generator=self._generator moveables=[motor] env=opts.get('env',{}) constrains=[] self._gScan=SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} step["integ_time"] = self.integ_time point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): region_stop, region_nr_intervals = self.regions[r][0], self.regions[r][1] positions = numpy.linspace(region_start, region_stop, region_nr_intervals+1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region # but after the first region, the 'start' point must not be repeated positions = positions[1:] for p in positions: step['positions'] = [p] step['point_id'] = point_id point_id += 1 yield step region_start = region_stop def run(self,*args): for step in self._gScan.step_scan(): yield step class reg2scan(Macro): """reg2scan. Do an absolute scan of the specified motors with different number of intervals for each region. It uses the gscan framework. All the motors will be drived to the same position in each step NOTE: Due to a ParamRepeat limitation, integration time has to be specified before the regions. """ hints = {'scan' : 'reg2scan'} env = ('ActiveMntGrp',) param_def = [ ['motor1', Type.Moveable, None, 'Motor to move'], ['motor2', Type.Moveable, None, 'Motor to move'], ['integ_time', Type.Float, None, 'Integration time'], ['start_pos', Type.Float, None, 'Start position'], ['step_region', ParamRepeat(['next_pos', Type.Float, None, 'next position'], ['region_nr_intervals', Type.Float, None, 'Region number of intervals']), None, 'List of tuples: (next_pos, region_nr_intervals'] ] def prepare(self, motor1, motor2, integ_time, start_pos, *regions, **opts): self.name='reg2scan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions self.regions_count = len(self.regions)/2 generator=self._generator moveables=[motor1, motor2] env=opts.get('env',{}) constrains=[] self._gScan=SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} step["integ_time"] = self.integ_time point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): region_stop, region_nr_intervals = self.regions[r][0], self.regions[r][1] positions = numpy.linspace(region_start, region_stop, region_nr_intervals+1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region # but after the first region, the 'start' point must not be repeated positions = positions[1:] for p in positions: step['positions'] = [p, p] step['point_id'] = point_id point_id += 1 yield step region_start = region_stop def run(self,*args): for step in self._gScan.step_scan(): yield step class reg3scan(Macro): """reg3scan. Do an absolute scan of the specified motors with different number of intervals for each region. It uses the gscan framework. All the motors will be drived to the same position in each step NOTE: Due to a ParamRepeat limitation, integration time has to be specified before the regions. """ hints = {'scan' : 'reg3scan'} env = ('ActiveMntGrp',) param_def = [ ['motor1', Type.Moveable, None, 'Motor to move'], ['motor2', Type.Moveable, None, 'Motor to move'], ['motor3', Type.Moveable, None, 'Motor to move'], ['integ_time', Type.Float, None, 'Integration time'], ['start_pos', Type.Float, None, 'Start position'], ['step_region', ParamRepeat(['next_pos', Type.Float, None, 'next position'], ['region_nr_intervals', Type.Float, None, 'Region number of intervals']), None, 'List of tuples: (next_pos, region_nr_intervals'] ] def prepare(self, motor1, motor2, motor3, integ_time, start_pos, *regions, **opts): self.name='reg3scan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions self.regions_count = len(self.regions)/2 generator=self._generator moveables=[motor1, motor2, motor3] env=opts.get('env',{}) constrains=[] self._gScan=SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} step["integ_time"] = self.integ_time point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): region_stop, region_nr_intervals = self.regions[r][0], self.regions[r][1] positions = numpy.linspace(region_start, region_stop, region_nr_intervals+1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region # but after the first region, the 'start' point must not be repeated positions = positions[1:] for p in positions: step['positions'] = [p, p, p] step['point_id'] = point_id point_id += 1 yield step region_start = region_stop def run(self,*args): for step in self._gScan.step_scan(): yield step class a2scan_mod(Macro): """a2scan_mod. Do an a2scan with the particularity of different intervals per motor: int_mot1, int_mot2. If int_mot2 < int_mot1, mot2 will change position every int(int_mot1/int_mot2) steps of mot1. It uses the gscan framework. """ hints = {'scan' : 'a2scan_mod'} env = ('ActiveMntGrp',) param_def = [ ['motor1', Type.Moveable, None, 'Motor 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['nr_interv1', Type.Integer, None, 'Number of scan intervals of Motor 1'], ['motor2', Type.Moveable, None, 'Motor 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['nr_interv2', Type.Integer, None, 'Number of scan intervals of Motor 2'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor1, start_pos1, final_pos1, nr_interv1, motor2, start_pos2, final_pos2, nr_interv2, integ_time, **opts): self.name='a2scan_mod' self.integ_time = integ_time self.start_pos1 = start_pos1 self.final_pos1 = final_pos1 self.nr_interv1 = nr_interv1 self.start_pos2 = start_pos2 self.final_pos2 = final_pos2 self.nr_interv2 = nr_interv2 generator = self._generator moveables = [motor1, motor2] env = opts.get('env',{}) constraints = [] self._gScan=SScan(self, generator, moveables, env, constraints) def _generator(self): step = {} step["integ_time"] = self.integ_time start1, end1, interv1 = self.start_pos1, self.final_pos1, self.nr_interv1 start2, end2, interv2 = self.start_pos2, self.final_pos2, self.nr_interv2 # Prepare the positions positions_m1 = numpy.linspace(start1, end1, interv1+1) positions_m2 = numpy.linspace(start2, end2, interv2+1) if interv1 > interv2: positions_m2 = start2+(float(end2-start2)/interv2)*(numpy.arange(interv1+1)//(float(interv1)/float(interv2))) elif interv2 > interv1: positions_m1 = start1+(float(end1-start1)/interv1)*(numpy.arange(interv2+1)//(float(interv2)/float(interv1))) point_id = 0 for pos1,pos2 in zip(positions_m1,positions_m2): step['point_id'] = point_id step['positions'] = [pos1, pos2] yield step point_id += 1 def run(self,*args): for step in self._gScan.step_scan(): yield step class ascanc_demo(Macro): """ This is a basic reimplementation of the ascanc` macro for demonstration purposes of the Generic Scan framework. The "real" implementation of :class:`sardana.macroserver.macros.ascanc` derives from :class:`sardana.macroserver.macros.aNscan` and provides some extra features. """ hints = { 'scan' : 'ascanc_demo'} #this is used to indicate other codes that the macro is a scan env = ('ActiveMntGrp',) #this hints that the macro requires the ActiveMntGrp environment variable to be set param_def = [ ['motor', Type.Moveable, None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, integ_time, **opts): self.name='ascanc_demo' #parse the user parameters self.start = numpy.array([start_pos], dtype='d') self.final = numpy.array([final_pos], dtype='d') self.integ_time = integ_time env = opts.get('env',{}) #the "env" dictionary may be passed as an option #create an instance of GScan (in this case, of its child, CScan self._gScan = CScan(self, waypointGenerator=self._waypoint_generator, periodGenerator=self._period_generator, moveables=[motor], env=env) def _waypoint_generator(self): #a very simple waypoint generator! only start and stop points! yield {"positions":self.start, "waypoint_id": 0} yield {"positions":self.final, "waypoint_id": 1} def _period_generator(self): step = {} step["integ_time"] = self.integ_time point_no = 0 while(True): #infinite generator. The acquisition loop is started/stopped at begin and end of each waypoint point_no += 1 step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): yield step class ascan_with_addcustomdata(ascan_demo): ''' example of an ascan-like macro where we demonstrate how to pass custom data to the data handler. This is an extension of the ascan_demo macro. Wemake several calls to `:meth:DataHandler.addCustomData` exemplifying different features. At least the following recorders will act on custom data: - OutputRecorder (this will ignore array data) - NXscan_FileRecorder - SPEC_FileRecorder (this will ignore array data) ''' def run(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): #we get the datahandler dh = self._gScan._data_handler #at this point the entry name is not yet set, so we give it explicitly (otherwise it would default to "entry") dh.addCustomData('Hello world1', 'dummyChar1', nxpath='/custom_entry:NXentry/customdata:NXcollection') #this is the normal scan loop for step in self._gScan.step_scan(): yield step #the entry number is known and the default nxpath is used "//custom_data") if none given dh.addCustomData('Hello world1', 'dummyChar1') #you can pass arrays (but not all recorders will handle them) dh.addCustomData(range(10), 'dummyArray1') #you can pass a custom nxpath *relative* to the current entry dh.addCustomData('Hello world2', 'dummyChar2', nxpath='sample:NXsample') #calculate a linear fit to the timestamps VS motor positions and store it x = [r.data [motor.getName()] for r in self.data.records] y = [r.data['timestamp'] for r in self.data.records] fitted_y = numpy.polyval(numpy.polyfit(x,y,1), x) dh.addCustomData(fitted_y, 'fittedtime', nxpath='measurement:NXcollection') #as a bonus, plot the fit self.pyplot.plot(x, y, 'ro') self.pyplot.plot(x, fitted_y, 'b-') sardana-1.2.0/src/sardana/macroserver/macros/examples/specific_experiments.py0000644000234100017500000001145412174204310031143 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Library of specific macros for performing specific experimental techniques """ __all__ = ["xas_acq"] __docformat__ = 'restructuredtext' import numpy from sardana.macroserver.macro import * from sardana.macroserver.scan import * class xas_acq(Macro, Hookable): """ .. warning:: This macro is still under development. It may change. Perform an X-ray absorption scan experiment. Data is stored in a NXxas-compliant file. """ hints = { 'FileRecorder':'NXxas_FileRecorder', 'scan' : 'xas_acq', 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step') } #env = ('MonochromatorEnergy', )#'AbsorbedBeam', 'IncomingBeam', 'Monitor') #this hints that the macro requires the ActiveMntGrp environment variable to be set param_def = [ ['start', Type.Float, None, 'start energy in keV'], ['final', Type.Float, None, 'final energy in keV'], ['nr_interv', Type.Integer, None, 'Number of energy intervals'], ['integ_time', Type.Float, None, 'Integration time in s'] ] def prepare(self, start, final, nr_interv, integ_time, **opts): #parse the user parameters self.starts = numpy.array([start], dtype='d') self.finals = numpy.array([final], dtype='d') self.integ_time = integ_time self.nr_points = nr_interv+1 self.interv_sizes = ( self.finals - self.starts) / nr_interv self.name='xas_acq' env = opts.get('env',{}) #the "env" dictionary may be passed as an option env['integ_time'] = integ_time #print "!!!!!", type(self.getInstrument('/instrument/monochromator')), self.getEnv('MonochromatorEnergy', macro_name=self.name) #ElementWithInterface('Instrument','monochromator') for n,e in self.getElementsWithInterface('Instrument').iteritems(): inst=e.getObj() print n, e.name, inst.getFullName(), type(e), type(inst), type(inst.getPoolObj())#,inst.getElements() #maybe I should use the instrument interface to obtain the right counters env['monochromator'] = monochromator = self.getEnv('MonochromatorEnergy', macro_name=self.name) energymotor = self.getMoveable(monochromator) xasMntGrp = self.getMeasurementGroup(self.getEnv('xasMntGrp', macro_name=self.name)) xasMntGrp=xasMntGrp.getObj() monitor,incbeam,absbeam = xasMntGrp.getChannelNames()[:3] env['monitor'] = monitor env['absbeam'] = absbeam env['incbeam'] = incbeam # print "!!!!!!!!",xasMntGrp.getObj().getElements() # absbeam = self.getExpChannel(self.getEnv('AbsorbedBeam')) #this should be get measurement group (e.g., second channel?) # incbeam = self.getExpChannel(self.getEnv('IncomingBeam')) #this should be get measurement group (e.g., first channel?) # monitor = self.getExpChannel(self.getEnv('Monitor')) #this should be get from the monitor of the measurement group #create an instance of GScan (in this case, of its child, SScan self._gScan=SScan(self, generator=self._generator, moveables=[energymotor], env=env) def _generator(self): step = {} step["integ_time"] = self.integ_time step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] for point_no in xrange(self.nr_points): step["positions"] = self.starts + point_no * self.interv_sizes step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): #just go through the steps yield step @property def data(self): return self._gScan.data #the GScan provides scan data sardana-1.2.0/src/sardana/macroserver/macros/examples/submacros.py0000644000234100017500000001345712174204310026736 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ A macro package to show examples on how to run a macro from inside another macro """ __all__ = ["call_wa", "call_wm", "subsubm", "subm", "mainmacro", "runsubs"] __docformat__ = 'restructuredtext' from sardana.macroserver.macro import Macro, Type, ParamRepeat #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # First example: # A 'mainmacro' that executes a 'subm' that in turn executes a 'subsubm'. # The 'subsubm' macro itself calls a short ascan macro #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~--~-~- class call_wa(Macro): def run(self): self.macros.wa() class call_wm(Macro): param_def = [ ['motor_list', ParamRepeat(['motor', Type.Motor, None, 'Motor to move']), None, 'List of motor to show'], ] def run(self, *m): self.macros.wm(*m) class subsubm(Macro): """this macro just calls the 'subm' macro This macro is part of the examples package. It was written for demonstration purposes""" def run(self): self.output("Starting %s" % self.getName()) m = self.macros motors = self.getObjs('.*', type_class=Type.Motor) m.ascan(motors[0], 0, 100, 10, 0.2) self.output("Finished %s" % self.getName()) class subm(Macro): """this macro just calls the 'subsubm' macro This macro is part of the examples package. It was written for demonstration purposes""" def run(self): self.output("Starting %s" % self.getName()) self.macros.subsubm() self.output("Finished %s" % self.getName()) class mainmacro(Macro): """this macro just calls the 'subm' macro This macro is part of the examples package. It was written for demonstration purposes""" def run(self): self.output("Starting %s" % self.getName()) self.macros.subm() self.output("Finished %s" % self.getName()) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Second example: # a 'runsubs' macro that shows the different ways to call a macro from inside # another macro #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~--~-~- class runsubs(Macro): """ A macro that calls a ascan macro using the motor given as first parameter. This macro is part of the examples package. It was written for demonstration purposes Call type will allow to choose to format in which the ascan macro is called from this macro: 1 - m.ascan(motor.getName(), '0', '10', '4', '0.2') 2 - m.ascan(motor, 0, 10, 4, 0.2) 3 - self.execMacro('ascan', motor.getName(), '0', '10', '4', '0.2') 4 - self.execMacro(['ascan', motor, 0, 10, 4, 0.2]) 5 - params = 'ascan', motor, 0, 10, 4, 0.2 self.execMacro(params) 6 - self.execMacro("ascan %s 0 10 4 0.2" % motor.getName()) 7 - macro = self.createMacro("ascan %s 0 10 4 0.2" % motor.getName()) macro.hooks = [ self.hook ] self.runMacro(macro) 8 - macro = self.createMacro('ascan', motor, 0, 10, 4, 0.2) macro.hooks = [ self.hook ] self.runMacro(macro) 9 - params = 'ascan', motor, 0, 10, 4, 0.2 macro = self.createMacro(params) macro.hooks = [ self.hook ] self.runMacro(macro) Options 7,8 and 9 use the lower level macro API in order to be able to attach hooks to the ascan macro.""" param_def = [ ['motor', Type.Motor, None, 'Motor to move'], ['call_type', Type.Integer, 2, 'type of run to execute internally'], ] def hook(self): self.info("executing hook in a step of a scan...") def run(self, motor, call_type): m = self.macros self.output("Using type %d" % call_type) if call_type == 1: m.ascan(motor.getName(), '0', '10', '4', '0.2') elif call_type == 2: m.ascan(motor, 0, 10, 4, 0.2) elif call_type == 3: self.execMacro('ascan', motor.getName(), '0', '10', '4', '0.2') elif call_type == 4: self.execMacro('ascan', motor, 0, 10, 4, 0.2) elif call_type == 5: params = 'ascan', motor, 0, 10, 4, 0.2 self.execMacro(params) elif call_type == 6: self.execMacro("ascan %s 0 10 4 0.2" % motor.getName()) elif call_type == 7: macro = self.createMacro("ascan %s 0 10 4 0.2" % motor.getName()) macro.hooks = [ self.hook ] self.runMacro(macro) elif call_type == 8: macro = self.createMacro('ascan', motor, 0, 10, 4, 0.2) macro.hooks = [ self.hook ] self.runMacro(macro) elif call_type == 9: params = 'ascan', motor, 0, 10, 4, 0.2 macro = self.createMacro(params) macro.hooks = [ self.hook ] self.runMacro(macro) sardana-1.2.0/src/sardana/macroserver/macros/examples/user_input.py0000644000234100017500000000630112174204310027123 0ustar cpascualcpascual00000000000000 from sardana.macroserver.macro import imacro, Type @imacro() def ask_number_of_points(self): """asks user for the number of points""" nb_points = self.input("How many points?", data_type=Type.Integer) @imacro() def ask_for_moveable(self): """asks user for a motor""" moveable = self.input("Which moveable?", data_type=Type.Moveable) self.output("You selected %s which is at %f", moveable, moveable.getPosition()) @imacro() def ask_for_car_brand(self): """asks user for a car brand""" car_brands = "Mazda", "Citroen", "Renault" car_brand = self.input("Which car brand?", data_type=car_brands) self.output("You selected %s", car_brand) @imacro() def ask_for_multiple_car_brands(self): """asks user for several car brands""" car_brands = "Mazda", "Citroen", "Renault", "Ferrari", "Porche", "Skoda" car_brands = self.input("Which car brand(s)?", data_type=car_brands, allow_multiple=True, title="Favorites") self.output("You selected %s", ", ".join(car_brands)) @imacro() def ask_peak(self): """asks user for peak current of points with a custom title""" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection") self.output("You selected a peak of %f A", peak) @imacro() def ask_peak_v2(self): """asks user for peak current of points with a custom title, default value, label and units""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4) self.output("You selected a %s of %f %s", label, peak, unit) @imacro() def ask_peak_v3(self): """asks user for peak current of points with a custom title, default value, label, units and ranges""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0) self.output("You selected a %s of %f %s", label, peak, unit) @imacro() def ask_peak_v4(self): """asks user for peak current of points with a custom title, default value, label, units, ranges and step size""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0, step=5) self.output("You selected a %s of %f %s", label, peak, unit) @imacro() def ask_peak_v5(self): """asks user for peak current of points with a custom title, default value, label, units, ranges, step size and decimal places""" label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0, step=5, decimals=2) self.output("You selected a %s of %f %s", label, peak, unit) sardana-1.2.0/src/sardana/macroserver/macros/__init__.py0000644000234100017500000000213712174204310024652 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package contains the standard macroserver macros""" __docformat__ = 'restructuredtext' sardana-1.2.0/src/sardana/macroserver/macros/communication.py0000644000234100017500000000405012174204310025754 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the standard macro module""" __docformat__ = 'restructuredtext' __all__ = ["get", "put"] from sardana.macroserver.macro import * import array class put(Macro): """Sends a string to the communication channel""" param_def = [ ['communication channel', Type.ComChannel, None, 'the communication channel'], ['data', Type.String, None, 'data to be sent'] ] def run(self, comch, data): name = comch.getName() nb = comch.write(data) o = str(nb) + " bytes sent to " + name self.output(o) class get(Macro): """Reads and outputs the data from the communication channel""" param_def = [ ['communication channel', Type.ComChannel, None, 'the communication channel'], ['maximum length', Type.String, -1, 'maximum number of bytes to read'] ] def run(self, comch, maxlen): name = comch.getName() data = comch.command_inout("read",maxlen) datastr = array.array('B',data).tostring() self.output("'" + datastr + "'") self.output(data)sardana-1.2.0/src/sardana/macroserver/macros/demo.py0000644000234100017500000001371412174204310024042 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the standard macro module""" from __future__ import print_function __all__ = ["sar_demo"] import PyTango from sardana.macroserver.macro import macro, Type _ENV = "_SAR_DEMO" def get_free_names(db, prefix, nb, start_at=1): ret = [] i = start_at failed = 96 while len(ret) < nb and failed > 0: name = "%s%02d" % (prefix, i) try: db.get_device_alias(name) failed -= 1 except: ret.append(name) i += 1 if len(ret) < nb or failed == 0: raise Exception("Too many sardana demos registered on this system.\n" "Please try using a different tango system") return ret @macro() def clear_sar_demo(self): """Undoes changes done with sar_demo""" try: SAR_DEMO = self.getEnv(_ENV) except: self.error("No demo has been prepared yet on this sardana!") return self.print("Removing measurement groups...") for mg in SAR_DEMO.get("measurement_groups", ()): self.udefmeas(mg) self.print("Removing elements...") for elem in SAR_DEMO.get("elements", ()): self.udefelem(elem) self.print("Removing controllers...") for ctrl in SAR_DEMO.get("controllers", ()): self.udefctrl(ctrl) self.unsetEnv(_ENV) self.print("DONE!") @macro() def sar_demo(self): """Sets up a demo environment. It creates many elements for testing""" try: SAR_DEMO = self.getEnv(_ENV) self.error("A demo has already been prepared on this sardana") return except: pass db = PyTango.Database() mot_ctrl_name = get_free_names(db, "motctrl", 1)[0] ct_ctrl_name = get_free_names(db, "ctctrl", 1)[0] zerod_ctrl_name = get_free_names(db, "zerodctrl", 1)[0] oned_ctrl_name = get_free_names(db, "onedctrl", 1)[0] twod_ctrl_name = get_free_names(db, "twodctrl", 1)[0] pm_ctrl_name = get_free_names(db, "slitctrl", 1)[0] motor_names = get_free_names(db, "mot", 4) ct_names = get_free_names(db, "ct", 4) zerod_names = get_free_names(db, "zerod", 4) oned_names = get_free_names(db, "oned", 1) twod_names = get_free_names(db, "twod", 1) gap, offset = get_free_names(db, "gap", 1) + get_free_names(db, "offset", 1) mg_name = get_free_names(db, "mntgrp", 1)[0] pools = self.getPools() if not len(pools): self.error('This is not a valid sardana demonstration system.\n' 'Sardana demonstration systems must be connect to at least ' 'one Pool') return pool = pools[0] self.print("Creating motor controller", mot_ctrl_name, "...") self.defctrl("DummyMotorController", mot_ctrl_name) for axis, motor_name in enumerate(motor_names, 1): self.print("Creating motor", motor_name, "...") self.defelem(motor_name , mot_ctrl_name, axis) self.print("Creating counter controller", ct_ctrl_name, "...") self.defctrl("DummyCounterTimerController", ct_ctrl_name) for axis, ct_name in enumerate(ct_names, 1): self.print("Creating counter channel", ct_name, "...") self.defelem(ct_name , ct_ctrl_name, axis) self.print("Creating 0D controller", zerod_ctrl_name, "...") self.defctrl("DummyZeroDController", zerod_ctrl_name) for axis, zerod_name in enumerate(zerod_names, 1): self.print("Creating 0D channel", zerod_name, "...") self.defelem(zerod_name , zerod_ctrl_name, axis) self.print("Creating 1D controller", oned_ctrl_name, "...") self.defctrl("DummyOneDController", oned_ctrl_name) for axis, oned_name in enumerate(oned_names, 1): self.print("Creating 1D channel", oned_name, "...") self.defelem(oned_name , oned_ctrl_name, axis) self.print("Creating 2D controller", twod_ctrl_name, "...") self.defctrl("DummyTwoDController", twod_ctrl_name) for axis, twod_name in enumerate(twod_names, 1): self.print("Creating 2D channel", twod_name, "...") self.defelem(twod_name , twod_ctrl_name, axis) self.print("Creating Slit", pm_ctrl_name, "with", gap, ",", offset, "...") sl2t, sl2b = motor_names[:2] self.defctrl("Slit", pm_ctrl_name, "sl2t="+sl2t, "sl2b="+sl2b, "Gap="+gap, "Offset="+offset) self.print("Creating measurement group", mg_name, "...") self.defmeas(mg_name, *ct_names) controllers = pm_ctrl_name, mot_ctrl_name, ct_ctrl_name, \ zerod_ctrl_name, oned_ctrl_name, twod_ctrl_name elements = [gap, offset] + motor_names + ct_names + \ zerod_names + oned_names + twod_names d = dict(controllers=controllers, elements=elements, measurement_groups=[mg_name]) self.setEnv(_ENV, d) self.print("DONE!") @macro([["motor", Type.Moveable, None, '']]) def mym2(self, pm): self.output(pm.getMotorNames()) elements = map(self.getMoveable, pm.elements) self.output(elements) self.output(type(pm)) self.output(type(elements[0])) sardana-1.2.0/src/sardana/macroserver/macros/env.py0000644000234100017500000002650412174204310023707 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Environment related macros""" __all__ = ["dumpenv", "load_env", "lsenv", "senv", "usenv"] __docformat__ = 'restructuredtext' from taurus.console.list import List from sardana.macroserver.macro import * ################################################################################ # # Environment related macros # ################################################################################ from lxml import etree def reprValue(v, max=74): # cut long strings v = str(v) if len(v) > max: v = v[:max] + ' [...]' return v class dumpenv(Macro): """Dumps the complete environment""" def run(self): env = self.getGlobalEnv() out = List(['Name','Value','Type']) for k,v in env.iteritems(): str_v = reprValue(v) type_v = type(v).__name__ out.appendRow([str(k), str_v, type_v]) for line in out.genOutput(): self.output(line) class lsvo(Macro): """Lists the view options""" def run(self): vo = self.getViewOptions() out = List(['View option', 'Value']) for key, value in vo.items(): out.appendRow([key, str(value)]) for line in out.genOutput(): self.output(line) class setvo(Macro): """Sets the given view option to the given value""" param_def = [['name', Type.String, None, 'View option name'], ['value', Type.String, None, 'View option value']] def run(self, name, value): try: value = eval(value) except: pass self.setViewOption(name, value) class usetvo(Macro): """Resets the value of the given view option""" param_def = [['name', Type.String, None, 'View option name']] def run(self, name): self.resetViewOption(name) class lsenv(Macro): """Lists the environment""" param_def = [ ['macro_list', ParamRepeat(['macro', Type.MacroClass, None, 'macro name'], min=0), None, 'List of macros to show environment'], ] def prepare(self, *macro_list, **opts): self.table_opts = opts def run(self, *macro_list): # list the environment for the current door if len(macro_list) == 0: # list All the environment for the current door out = List(['Name', 'Value', 'Type']) env = self.getAllDoorEnv() for k,v in env.iteritems(): str_val = reprValue(v) type_name = type(v).__name__ out.appendRow([str(k), str_val, type_name]) else: # list the environment for the current door for the given macros out = List(['Macro', 'Name', 'Value', 'Type']) for macro in macro_list: env = self.getEnv(key=None, macro_name=macro.name) for k, v in env.iteritems(): type_name = type(v).__name__ out.appendRow([ macro.name, k, self.reprValue(v), type_name ]) for line in out.genOutput(): self.output(line) def reprValue(self, v, max=54): # cut long strings v = str(v) if len(v) > max: v = '%s [...]' % v[:max] return v class senv(Macro): """Sets the given environment variable to the given value""" param_def = [['name', Type.Env, None, 'Environment variable name. Can be one of the following:\n' \ ' - - global variable\n' \ ' - . - variable value for a specific door\n' \ ' - . - variable value for a specific macro\n' \ ' - .. - variable value for a specific macro running on a specific door'], ['value_list', ParamRepeat(['value', Type.String, None, 'environment value item'], min=1), None, 'value(s). one item will eval to a single element. More than one item will eval to a tuple of elements'], ] def run(self, env, *value): if len(value) == 1: value = value[0] else: value = '(%s)' % ', '.join(value) k,v = self.setEnv(env, value) line = '%s = %s' % (k, str(v)) self.output(line) class usenv(Macro): """Unsets the given environment variable""" param_def = [ ['environment_list', ParamRepeat(['env', Type.Env, None, 'Environment variable name'], min=1), None, 'List of environment items to be removed'], ] def run(self, *env): self.unsetEnv(env) self.output("Success!") class load_env(Macro): """ Read environment variables from config_env.xml file""" def run(self): doc = etree.parse("config_env.xml") root = doc.getroot() for element in root: if element.find("./name").text == "auto_filter": self.output("Loading auto_filter variables:") filter_max_elem = element.find(".//FilterMax") if filter_max_elem is not None: filter_max = filter_max_elem.text self.setEnv("FilterMax", filter_max) self.output("FilterMax loaded") else: self.output("FilterMax not found") filter_min_elem = element.find(".//FilterMin") if filter_min_elem is not None: filter_min = filter_max_elem.text self.setEnv("FilterMin", filter_min) self.output("FilterMin loaded") else: self.output("FilterMin not found") filter_delta_elem = element.find(".//FilterDelta") if filter_delta_elem is not None: filter_delta = filter_delta_elem.text self.setEnv("FilterDelta", filter_delta) self.output("FilterDelta loaded") else: self.output("FilterDelta not found") filter_signal_elem = element.find(".//FilterSignal") if filter_signal_elem is not None: filter_signal = filter_signal_elem.text self.setEnv("FilterSignal", filter_signal) self.output("FilterSignal loaded") else: self.output("FilterSignal not found") filter_absorber_elem = element.find(".//FilterAbsorber") if filter_absorber_elem is not None: filter_absorber = filter_absorber_elem.text self.setEnv("FilterAbsorber", filter_absorber) self.output("FilterAbsorber loaded") else: self.output("FilterAbsorber not found") auto_filter_elem = element.find(".//AutoFilter") if auto_filter_elem is not None: auto_filter = auto_filter_elem.text self.setEnv("AutoFilter", auto_filter) self.output("AutoFilter loaded") else: self.output("AutoFilter not found") if element.find("./name").text == "auto_beamshutter": self.output("Loading auto_beamshutter variables:") auto_beamshutter_elem = element.find(".//AutoBeamshutter") if auto_beamshutter_elem is not None: auto_beamshutter = auto_beamshutter_elem.text self.setEnv("AutoBeamshutter", auto_beamshutter) self.output("AutoBeamshutter loaded") else: self.output("AutoBeamshutter not found") beamshutter_limit_elem = element.find(".//BeamshutterLimit") if beamshutter_limit_elem is not None: beamshutter_limit = beamshutter_limit_elem.text self.setEnv("BeamshutterLimit", beamshutter_limit) self.output("BeamshutterLimit loaded") else: self.output("BeamshutterLimit not found") beamshutter_signal_elem = element.find(".//BeamshutterSignal") if beamshutter_signal_elem is not None: beamshutter_signal = beamshutter_signal_elem.text self.setEnv("BeamshutterSignal", beamshutter_signal) self.output("BeamshutterSignal loaded") else: self.output("BeamshutterSignal not found") beamshutter_time_elem = element.find(".//BeamshutterTime") if beamshutter_time_elem is not None: beamshutter_time = beamshutter_time_elem.text self.setEnv("BeamshutterTime", beamshutter_time) self.output("BeamshutterTime loaded") else: self.output("BeamshutterTime not found") if element.find("./name").text == "exafs": self.output("Loading exafs variables:") exafs_int_times_elem = element.find(".//ExafsIntTimes") if exafs_int_times_elem is not None: exafs_int_times = exafs_int_times_elem.text self.setEnv("ExafsIntTimes", exafs_int_times) self.output("ExafsIntTimes loaded") else: self.output("ExafsIntTimes not found") exafs_nb_intervals_elem = element.find(".//ExafsNbIntervals") if exafs_nb_intervals_elem is not None: exafs_nb_intervals = exafs_nb_intervals_elem.text self.setEnv("ExafsNbIntervals", exafs_nb_intervals) self.output("ExafsNbIntervals loaded") else: self.output("ExafsNbIntervals not found") exafs_regions_elem = element.find(".//ExafsRegions") if exafs_regions_elem is not None: exafs_regions = exafs_regions_elem.text self.setEnv("ExafsRegions", exafs_regions) self.output("ExafsRegions loaded") else: self.output("ExafsRegions not found") misc_tree = root.find("./miscellaneous") if misc_tree is not None: for parameter in misc_tree: if parameter.tag != "name": self.setEnv(parameter.tag, parameter.text) sardana-1.2.0/src/sardana/macroserver/macros/expert.py0000644000234100017500000003223612174204310024425 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Expert macros""" from __future__ import print_function __docformat__ = 'restructuredtext' __all__ = ["commit_ctrllib", "defctrl", "defelem", "defm", "defmeas", "edctrl", "edctrllib", "prdef", "rellib", "relmac", "relmaclib", "send2ctrl", "udefctrl", "udefelem", "udefmeas", "sar_info"] import sys import traceback import array from sardana.macroserver.macro import Macro, Type, ParamRepeat, Table, LibraryError ################################################################################ # # Configuration related macros # ################################################################################ class defm(Macro): """Creates a new motor in the active pool""" param_def = [['motor name', Type.String, None, 'motor name'], ['controller', Type.Controller, None, 'Controller name'], ['axis', Type.Integer, None, 'motor axis'],] def run(self, name, controller, axis): pool = controller.getPoolObj() if axis == -1: axis = None elem = pool.createElement(name, controller, axis) self.print("Created %s" % str(elem)) class defmeas(Macro): """Create a new measurement group. First channel in channel_list MUST be an internal sardana channel. At least one channel MUST be a Counter/Timer (by default, the first Counter/Timer in the list will become the master).""" param_def = [ ['name', Type.String, None, 'Measurement group name'], ['channel_list', ParamRepeat(['channel', Type.String, None, 'Measurement Channel'],), None, 'List of measurement channels'], ] def prepare(self, name, *channel_list, **opts): mntgrp_list = self.findObjs(name, type_class=Type.MeasurementGroup) if len(mntgrp_list) != 0: raise Exception('A measurement group with that name already exists') def run(self, name, *channel_list): channel0 = self.getObj(channel_list[0]) pool = channel0.getPoolObj() mg = pool.createMeasurementGroup(name, channel_list) self.print("Created %s" % str(mg)) class udefmeas(Macro): """Deletes an existing measurement group""" param_def = [ ['name', Type.MeasurementGroup, None, 'Measurement group name'],] def run(self, mntgrp): pool = mntgrp.getPoolObj() pool.deleteMeasurementGroup(mntgrp.getName()) class defelem(Macro): """Creates an element on a controller with an axis""" param_def = [ ['name', Type.String, None, 'new element name'], ['ctrl', Type.Controller, None, 'existing controller'], ['axis', Type.Integer, -1, 'axis in the controller (default is -1, meaning add to the end)'],] def run(self, name, ctrl, axis): pool = ctrl.getPoolObj() if axis == -1: axis = None elem = pool.createElement(name, ctrl, axis) self.print("Created %s" % str(elem)) class udefelem(Macro): """Deletes an existing element""" param_def = [ ['element', Type.Element, None, 'element name'],] def run(self, element): pool = element.getPoolObj() pool.deleteElement(element.getName()) class defctrl(Macro): """Creates a new controller 'role_prop' is a sequence of roles and/or properties. - A role is defined as = (only applicable to pseudo controllers) - A property is defined as If both roles and properties are supplied, all roles must come before properties. All controller properties that don't have default values must be given. Example of creating a motor controller (with a host and port properties): [1]: defctrl SuperMotorController myctrl host homer.springfield.com port 5000 Example of creating a Slit pseudo motor (sl2t and sl2b motor roles, Gap and Offset pseudo motor roles): [1]: defctrl Slit myslit sl2t=mot01 sl2b=mot02 Gap=gap01 Offset=offset01""" param_def = [ ['class', Type.ControllerClass, None, 'controller class'], ['name', Type.String, None, 'new controller name'], ['roles_props', ParamRepeat(['role_prop', Type.String, None, 'a role or property item'],min=0), None, 'roles and/or properties'] ] def run(self, ctrl_class, name, *props): pool = ctrl_class.getPoolObj() elem = pool.createController(ctrl_class.name, name, *props) self.print("Created %s" % str(elem)) class udefctrl(Macro): """Deletes an existing controller""" param_def = [ ['controller', Type.Controller, None, 'existing controller'],] def run(self, controller): pool = controller.getPoolObj() pool.deleteController(controller.getName()) ################################################################################ # # Controller related macros # ################################################################################ class send2ctrl(Macro): """Sends the given data directly to the controller""" param_def = [['controller', Type.Controller, None, 'Controller name'], ['data', ParamRepeat(['string item', Type.String, None, 'a string item'],), None, 'data to be sent']] def run(self, controller, *data): name = controller.getName() pool = controller.getPoolObj() str_data = " ".join(data) res = pool.SendToController([name,str_data]) self.output(res) ################################################################################ # # Library handling related macros # ################################################################################ class edctrl(Macro): """Returns the contents of the library file which contains the given controller code.""" param_def = [ ['ctrlclass', Type.ControllerClass, None, 'Controller class name'] ] result_def = [ ['filedata', Type.File, None, 'The file data object.'] ] hints = { 'commit_cmd' : 'commit_ctrllib' } def run(self,ctrlclass): f_name = ctrlclass.file pool = ctrlclass.getPool() data = pool.GetFile(f_name) data = array.array('B',data).tostring() line_nb = 1 for line in data.splitlines(): line = line.strip(' \t') if line.startswith('class') and line.find(ctrlclass.name)>0 and \ line.endswith(":"): break line_nb = line_nb + 1 return [f_name,data,line_nb] class edctrllib(Macro): """Returns the contents of the given library file""" param_def = [ ['filename', Type.Filename, None, 'Absolute path and file name or '\ 'simple filename. Relative paths are not allowed.'] ] result_def = [ ['filedata', Type.File, None, 'The file data object'] ] hints = { 'commit_cmd' : 'commit_ctrllib' } def run(self,filename): pool = self.getManager().getPool() data = pool.GetFile(filename) return [filename,array.array('B',data).tostring(),0] class commit_ctrllib(Macro): """Puts the contents of the given data in a file inside the pool""" param_def = [ ['filename', Type.Filename, None, 'Absolute path and file name'], ['username', Type.User, None, 'The user name'], ['comment', Type.String, None, 'A description of the changes made to '\ 'the file'], ['filedata', Type.File, None, 'The file data object'] ] def run(self,filename,username,comment,filedata): pool = self.getManager().getPool() meta = filename + '\0' + username + '\0' + comment + '\0' data = array.array('B',meta) data.extend(array.array('B',filedata)) pool.PutFile(data.tolist()) ################################################################################ # # Macro handling related macros # ################################################################################ class prdef(Macro): """Returns the the macro code for the given macro name.""" param_def = [ ['macro_name', Type.MacroCode, None, 'macro name'] ] def run(self,macro_data): code_lines, first_line = macro_data.code for code_line in code_lines: self.output(code_line.strip('\n')) class rellib(Macro): """Reloads the given python library code from the macro server filesystem. .. warning:: use with extreme care! Accidentally reloading a system module or an installed python module may lead to unpredictable behavior .. note:: if python module is used by any macro, don't forget to reload the corresponding macros afterward so the changes take effect.""" param_def = [ ['module_name', Type.String, None, 'The module name to be reloaded (without extension)'] ] def run(self, module_name): try: self.reloadLibrary(module_name) self.output("%s successfully (re)loaded", module_name) except LibraryError: self.error("Cannot use rellib to reload a macro library. " \ "Use 'relmaclib' instead") except ImportError: msg = "".join(traceback.format_exception_only(*sys.exc_info()[:2])) self.error(msg) class relmaclib(Macro): """Reloads the given macro library code from the macro server filesystem.""" param_def = [ ['macro_library', Type.MacroLibrary, None, 'The module name to be reloaded (without extension)'] ] def run(self, macro_library): name = macro_library.name new_macro_library = self.reloadMacroLibrary(name) if new_macro_library.has_errors(): exc_info = new_macro_library.get_error() #msg = "".join(traceback.format_exception(*exc_info)) msg = "".join(traceback.format_exception_only(*exc_info[:2])) self.error(msg) else: macros = new_macro_library.get_macros() self.output("%s successfully (re)loaded (found %d macros)", name, len(macros)) class relmac(Macro): """Reloads the given macro code from the macro server filesystem. Attention: All macros inside the same file will also be reloaded.""" param_def = [ ['macro_code', Type.MacroCode, None, 'macro name to be reloaded'] ] def run(self, macro_code): name = macro_code.name macro_library_name = macro_code.lib.name self.reloadMacro(name) macro_library = self.getMacroLibrary(macro_library_name) if macro_library.has_errors(): exc_info = macro_library.get_error() #msg = "".join(traceback.format_exception(*exc_info)) msg = "".join(traceback.format_exception_only(*exc_info[:2])) self.error(msg) else: self.output("%s successfully (re)loaded", name) class sar_info(Macro): """Prints details about the given sardana object""" param_def = [ ['obj', Type.Object, None, 'obj'] ] def run(self, obj): self.dump_properties(obj) #self.output("") #self.dump_attributes(obj) def dump_properties(self, obj): data = obj.serialize() table = Table([data.values()], row_head_str=data.keys(), row_head_fmt='%*s', col_sep=' = ') self.output("Properties:") self.output("-----------") for line in table.genOutput(): self.output(line) def dump_attributes(self, obj): try: dev_attrs = obj.dump_attributes() except AttributeError: return row_head, values = [], [] for dev_attr in dev_attrs: row_head.append(dev_attr.name) if dev_attr.has_failed: err = dev_attr.get_err_stack() if len(err): value = err[0].desc else: value = "Unknown error!" else: value = str(dev_attr.value) values.append(value) table = Table([values], row_head_str=row_head, row_head_fmt='%*s', col_sep=' = ') self.output("Attributes:") self.output("-----------") for line in table.genOutput(): self.output(line) sardana-1.2.0/src/sardana/macroserver/macros/ioregister.py0000644000234100017500000000366312174204310025274 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """IORegister related macros""" __docformat__ = 'restructuredtext' __all__ = ["write_ioreg", "read_ioreg"] from sardana.macroserver.macro import * import array class write_ioreg(Macro): """Writes a value to an input register""" param_def = [ ['input/output register', Type.IORegister, None, 'input/output register'], ['data', Type.Integer, None, 'value to be send'] ] def run(self, ioreg, data): name = ioreg.getName() o = "Writing " + str(data) + " to " + name + " register " self.output(o) data = ioreg.writeIORegister(data) class read_ioreg(Macro): """Reads an output register""" param_def = [ ['input/output register', Type.IORegister, None, 'input/output register'] ] def run(self, ioreg): name = ioreg.getName() data = ioreg.readIORegister() o = "Reading " + name + " register " self.output(o) self.output(data) sardana-1.2.0/src/sardana/macroserver/macros/lists.py0000644000234100017500000001611012174204310024245 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer generic scan""" __all__ = ["ls0d", "ls1d", "ls2d", "lsa", "lscom", "lsct", "lsctrl", "lsctrllib", "lsdef", "lsexp", "lsi", "lsior", "lsm", "lsmeas", "lspc", "lspm", "lsmac", "lsmaclib"] __docformat__ = 'restructuredtext' from taurus.console import Alignment from taurus.console.list import List from sardana.macroserver.macro import * Left, Right, HCenter = Alignment.Left, Alignment.Right, Alignment.HCenter #~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # List of elements related macros #~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class _ls(Macro): param_def = [ ['filter', ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=0, max=1), '.*', 'a regular expression filter'], ] def get_column_names(self): cols = [] for col in self.cols: if isinstance(col, tuple): col = col[0] cols.append(col) return cols def get_column_members(self): cols = [] for col in self.cols: if isinstance(col, tuple): col = col[1] cols.append(col.lower()) return cols def run(self, *filter): self.warning('This macro is not intended to be executed directly by ' \ 'the user') return class lsdef(_ls): """List all macro definitions""" cols = 'Name', 'Module', 'Brief Description' width = -1, -1, -1 align = Right, Right, Left def run(self, filter): cols = self.get_column_names() out = List(cols, text_alignment=self.align, max_col_width=self.width) for m in self.getMacros(filter): if m.name.startswith("_"): continue out.appendRow([m.name, m.module_name, m.get_brief_description()]) for line in out.genOutput(): self.output(line) class _lsobj(_ls): subtype = Macro.All cols = 'Name', 'Type', 'Controller', 'Axis'#, 'State' width = -1, -1, -1, -1#, -1 align = Right, Right, Right, Right#, Right def objs(self, filter): return self.findObjs(filter, type_class=self.type, subtype=self.subtype, reserve=False) def obj2Row(self, o, cols=None): cols = cols or self.get_column_members() ret = [] for col in cols: if col == 'controller': value = self.getController(o.controller).name else: value = getattr(o, col) if value is None: value = '-----' ret.append(value) return ret def run(self, filter): objs = self.objs(filter) nb = len(objs) if nb is 0: if self.subtype is Macro.All: if isinstance(self.type, (str, unicode)): t = self.type.lower() else: t = ", ".join(self.type).lower() else: t = self.subtype.lower() self.output('No %ss defined' % t) return cols = self.get_column_names() out = List(cols, text_alignment=self.align, max_col_width=self.width) objs.sort() for obj in objs: try: out.appendRow( self.obj2Row(obj) ) except: pass for line in out.genOutput(): self.output(line) class lsm(_lsobj): """Lists all motors""" type = Type.Moveable class lspm(lsm): """Lists all existing motors""" subtype = 'PseudoMotor' class lscom(_lsobj): """Lists all communication channels""" type = Type.ComChannel class lsior(_lsobj): """Lists all IORegisters""" type = Type.IORegister class lsexp(_lsobj): """Lists all experiment channels""" type = Type.ExpChannel class lsct(lsexp): """Lists all Counter/Timers""" subtype = 'CTExpChannel' class ls0d(lsexp): """Lists all 0D experiment channels""" subtype = 'ZeroDExpChannel' class ls1d(lsexp): """Lists all 1D experiment channels""" subtype = 'OneDExpChannel' class ls2d(lsexp): """Lists all 2D experiment channels""" subtype = 'TwoDExpChannel' class lspc(lsexp): """Lists all pseudo counters""" subtype = 'PseudoCounter' class lsctrllib(_lsobj): """Lists all existing controller classes""" type = Type.ControllerClass cols = 'Name', ('Type', 'main_type'), ('Library', 'module'), ('Family','gender') class lsctrl(_lsobj): """Lists all existing controllers""" type = Type.Controller cols = 'Name', ('Type', 'main_type'), ('Class', 'klass'), 'Module' class lsi(_lsobj): """Lists all existing instruments""" type = Type.Instrument cols = 'Name', 'Type', ('Parent', 'parent_instrument') class lsa(_lsobj): """Lists all existing objects""" type = Type.Moveable, Type.ComChannel, Type.ExpChannel, Type.IORegister class lsmeas(_lsobj): """List existing measurement groups""" type = Type.MeasurementGroup cols = 'Active', 'Name', 'Timer', 'Experim. channels' width = -1, -1, -1, 60 align = HCenter, Right, Right, Left def prepare(self, filter, **opts): try: self.mnt_grp = self.getEnv('ActiveMntGrp').lower() or None except: self.mnt_grp = None def obj2Row(self, o): if self.mnt_grp and (o.getName().lower() == self.mnt_grp): active = '*' else: active = ' ' return active, o.name, o.getTimerName(), ", ".join(o.getChannelLabels()) class lsmac(_lsobj): """Lists existing macros""" type = Type.MacroCode cols = 'Name', ('Location', 'file_path') class lsmaclib(_lsobj): """Lists existing macro libraries.""" type = Type.MacroLibrary cols = 'Name', ('Location', 'file_path') sardana-1.2.0/src/sardana/macroserver/macros/mca.py0000644000234100017500000000317512174204310023656 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """MCA related macros""" __docformat__ = 'restructuredtext' __all__ = ["mca_start", "mca_stop"] from sardana.macroserver.macro import * import array class mca_start(Macro): """Starts an mca""" param_def = [ ['mca', Type.ExpChannel, None, 'mca'] ] def run(self, mca): name = mca.getName() mca.Start() o = "Starting " + name self.output(o) class mca_stop(Macro): """Stops an mca""" param_def = [ ['mca', Type.ExpChannel, None, 'mca'] ] def run(self, mca): name = mca.getName() mca.Abort() o = "Stopping " + name self.output(o) sardana-1.2.0/src/sardana/macroserver/macros/scan.py0000644000234100017500000017732512174204310024053 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ Macro library containning scan macros for the macros server Tango device server as part of the Sardana project. Available Macros are: ascan family: ascan, a2scan, a3scan, a4scan and amultiscan dscan family: dscan, d2scan, d3scan, d4scan and dmultiscan mesh fscan scanhist """ __all__ = ["a2scan", "a3scan", "a4scan", "amultiscan", "aNscan", "ascan", "d2scan", "d3scan", "d4scan", "dmultiscan", "dNscan", "dscan", "fscan", "mesh", "a2scanc", "a3scanc", "a4scanc", "ascanc", "d2scanc", "d3scanc", "d4scanc", "dNScanc", "dscanc", "meshc", "a2scanct", "a3scanct", "a4scanct", "ascanct", "scanhist", "getCallable", "UNCONSTRAINED"] __docformat__ = 'restructuredtext' import os import copy import datetime import numpy from taurus.console import Alignment from taurus.console.list import List from taurus.console.table import Table from sardana.macroserver.msexception import UnknownEnv from sardana.macroserver.macro import * from sardana.macroserver.scan import * from sardana.util.motion import Motor, MotionPath from sardana.util.tree import BranchNode, LeafNode, Tree UNCONSTRAINED="unconstrained" StepMode = 's' ContinuousMode = 'c' #TODO: change it to be more verbose e.g. ContinuousSwMode ContinuousHwTimeMode = 'ct' HybridMode = 'h' def getCallable(repr): '''returns a function . Ideas: repr could be an URL for a file where the function is contained, or be evaluable code, or a pickled function object,... In any case, the return from it should be a callable of the form: f(x1,x2) where x1, x2 are points in the moveable space and the return value of f is True if the movement from x1 to x2 is allowed. False otherwise''' if repr==UNCONSTRAINED: return lambda x1,x2:True else: return lambda: None class aNscan(Hookable): hints = { 'scan' : 'aNscan', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } #env = ('ActiveMntGrp',) """N-dimensional scan. This is **not** meant to be called by the user, but as a generic base to construct ascan, a2scan, a3scan,...""" def _prepare(self, motorlist, startlist, endlist, scan_length, integ_time, mode=StepMode, **opts): self.motors = motorlist self.starts = numpy.array(startlist,dtype='d') self.finals = numpy.array(endlist,dtype='d') self.mode = mode self.integ_time = integ_time self.opts = opts if len(self.motors) == self.starts.size == self.finals.size: self.N = self.finals.size else: raise ValueError('Moveablelist, startlist and endlist must all be same length') moveables = [] for m, start, final in zip(self.motors, self.starts, self.finals): moveables.append(MoveableDesc(moveable=m, min_value=min(start,final), max_value=max(start,final))) moveables[0].is_reference = True env = opts.get('env',{}) constrains = [getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] extrainfodesc = opts.get('extrainfodesc',[]) #Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') #self.post_scan_hooks = self.getHooks('post-scan' if mode == StepMode: self.nr_interv = scan_length self.nr_points = self.nr_interv+1 self.interv_sizes = ( self.finals - self.starts) / self.nr_interv self.name = opts.get('name','a%iscan'%self.N) self._gScan = SScan(self, self._stepGenerator, moveables, env, constrains, extrainfodesc) elif mode in [ContinuousMode, ContinuousHwTimeMode]: #TODO: probably not 100% correct, # the idea is to allow passing a list of waypoints if isinstance(endlist[0],list): self.waypoints = self.finals else: self.waypoints = [self.finals] self.nr_waypoints = len(self.waypoints) if mode == ContinuousMode: self.slow_down = scan_length self.nr_waypoints = 2 #aNscans will only have two waypoints (the start and the final positions) self.way_lengths = ( self.finals - self.starts) / (self.nr_waypoints -1) self.name = opts.get('name','a%iscanc'%self.N) self._gScan = CSScan(self, self._waypoint_generator, self._period_generator, moveables, env, constrains, extrainfodesc) elif mode == ContinuousHwTimeMode: self.nr_of_points = scan_length self.name = opts.get('name','a%iscanct'%self.N) self._gScan = CTScan(self, self._waypoint_generator_hwtime, moveables, env, constrains, extrainfodesc) elif mode == HybridMode: self.nr_interv = scan_length self.nr_points = self.nr_interv+1 self.interv_sizes = ( self.finals - self.starts) / self.nr_interv self.name = opts.get('name','a%iscanh'%self.N) self._gScan = HScan(self, self._stepGenerator, moveables, env, constrains, extrainfodesc) else: raise ValueError('invalid value for mode %s' % mode) def _stepGenerator(self): step = {} step["integ_time"] = self.integ_time step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] for point_no in xrange(self.nr_points): step["positions"] = self.starts + point_no * self.interv_sizes step["point_id"] = point_no yield step def _waypoint_generator(self): step = {} step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["check_func"] = [] step["slow_down"] = self.slow_down for point_no in xrange(self.nr_waypoints): step["positions"] = self.starts + point_no * self.way_lengths step["waypoint_id"] = point_no yield step def _waypoint_generator_hwtime(self): #TODO: remove starts def calculate_positions(moveable_node, start, end): '''Function to calculate starting and ending positions on the physical motors level. :param moveable_node: (BaseNode) node representing a moveable. Can be a BranchNode representing a PseudoMotor, or a LeafNode representing a PhysicalMotor). :param start: (float) starting position of the moveable :param end: (float) ending position of the moveable :return: (list<(float,float)>) a list of tuples comprising starting and ending positions. List order is important and preserved.''' start_positions = [] end_positions = [] if isinstance(moveable_node, BranchNode): pseudo_node = moveable_node moveable = pseudo_node.data moveable_nodes = moveable_node.children starts = moveable.calcPhysical(start) ends = moveable.calcPhysical(end) for moveable_node, start, end in zip(moveable_nodes, starts, ends): _start_positions, _end_positions = calculate_positions( moveable_node, start, end) start_positions += _start_positions end_positions += _end_positions else: start_positions = [start] end_positions = [end] return start_positions, end_positions #CScan in its constructor populates a list of data structures - trees. #Each tree represent one Moveables with its hierarchy of inferior moveables. moveables_trees = self._gScan.get_moveables_trees() step = {} step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["check_func"] = [] step["active_time"] = self.nr_of_points * self.integ_time step["positions"] = [] step["start_positions"] = [] starts = self.starts for point_no, waypoint in enumerate(self.waypoints): for start, end, moveable_tree in zip(starts, waypoint, moveables_trees): moveable_root = moveable_tree.root() start_positions, end_positions = calculate_positions(moveable_root, start, end) step["start_positions"] += start_positions step["positions"] += end_positions step["waypoint_id"] = point_no starts = waypoint yield step def _period_generator(self): step = {} step["integ_time"] = self.integ_time step["pre-acq-hooks"] = self.getHooks('pre-acq') step["post-acq-hooks"] = self.getHooks('post-acq')+self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] step['extrainfo'] = {} point_no = 0 while(True): point_no += 1 step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): yield step @property def data(self): return self._gScan.data def getTimeEstimation(self): gScan = self._gScan mode = self.mode it = gScan.generator() v_motors = gScan.get_virtual_motors() curr_pos = gScan.motion.readPosition() total_time = 0.0 if mode == StepMode: # calculate motion time max_step0_time, max_step_time = 0.0, 0.0 # first motion takes longer, all others should be "equal" step0 = it.next() for v_motor, start, stop, length in zip(v_motors, curr_pos, step0['positions'], self.interv_sizes): path0 = MotionPath(v_motor, start, stop) path = MotionPath(v_motor, 0, length) max_step0_time = max(max_step0_time, path0.duration) max_step_time = max(max_step_time, path.duration) motion_time = max_step0_time + self.nr_interv * max_step_time # calculate acquisition time acq_time = self.nr_points * self.integ_time total_time = motion_time + acq_time elif mode == ContinuousMode: total_time = gScan.waypoint_estimation() #TODO: add time estimation for ContinuousHwTimeMode return total_time def getIntervalEstimation(self): mode = self.mode if mode == StepMode: return self.nr_interv elif mode == ContinuousMode: return self.nr_waypoints class dNscan(aNscan): '''same as aNscan but it interprets the positions as being relative to the current positions and upon completion, it returns the motors to their original positions''' hints = copy.deepcopy(aNscan.hints) hints['scan'] = 'dNscan' def _prepare(self, motorlist, startlist, endlist, scan_length, integ_time, mode=StepMode, **opts): self._motion=self.getMotion( [ m.getName() for m in motorlist] ) self.originalPositions = numpy.array(self._motion.readPosition()) starts = numpy.array(startlist, dtype='d') + self.originalPositions finals = numpy.array(endlist, dtype='d') + self.originalPositions aNscan._prepare(self, motorlist, starts, finals, scan_length, integ_time, mode=mode, **opts) def do_restore(self): self.info("Returning to start positions...") self._motion.move(self.originalPositions) class ascan(aNscan, Macro): """Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. """ param_def = [ ['motor', Type.Moveable, None, 'Moveable to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): self._prepare([motor], [start_pos], [final_pos], nr_interv, integ_time, **opts) class a2scan(aNscan, Macro): """two-motor scan. a2scan scans two motors, as specified by motor1 and motor2. Each motor moves the same number of intervals with starting and ending positions given by start_pos1 and final_pos1, start_pos2 and final_pos2, respectively. The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, nr_interv, integ_time, **opts): self._prepare([motor1,motor2], [start_pos1,start_pos2], [final_pos1,final_pos2], nr_interv, integ_time, **opts) class a3scan(aNscan, Macro): """three-motor scan . a3scan scans three motors, as specified by motor1, motor2 and motor3. Each motor moves the same number of intervals with starting and ending positions given by start_pos1 and final_pos1, start_pos2 and final_pos2, start_pos3 and final_pos3, respectively. The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_interv, integ_time, **opts): self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], nr_interv, integ_time, **opts) class a4scan(aNscan, Macro): """four-motor scan . a4scan scans four motors, as specified by motor1, motor2, motor3 and motor4. Each motor moves the same number of intervals with starting and ending positions given by start_posN and final_posN (for N=1,2,3,4). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['motor4', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos4', Type.Float, None, 'Scan start position 3'], ['final_pos4', Type.Float, None, 'Scan final position 3'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, nr_interv, integ_time, **opts): self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], nr_interv, integ_time, **opts) class amultiscan(aNscan, Macro): '''Multiple motor scan. amultiscan scans N motors, as specified by motor1, motor2,...,motorN. Each motor moves the same number of intervals with starting and ending positions given by start_posN and final_posN (for N=1,2,...). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" ''' param_def = [ ['motor_start_end_list', ParamRepeat(['motor', Type.Moveable, None, 'Moveable to move'], ['start', Type.Float, None, 'Starting position'], ['end', Type.Float, None, 'Final position']), None, 'List of motor, start and end positions'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, *args, **opts): motors = args[0:-2:3] starts = args[1:-2:3] ends = args[2:-2:3] nr_interv = args[-2] integ_time = args[-1] self._prepare(motors, starts, ends, nr_interv, integ_time, **opts) class dmultiscan(dNscan, Macro): '''Multiple motor scan relative to the starting positions. dmultiscan scans N motors, as specified by motor1, motor2,...,motorN. Each motor moves the same number of intervals If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2,...) The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" ''' param_def = [ ['motor_start_end_list', ParamRepeat(['motor', Type.Moveable, None, 'Moveable to move'], ['start', Type.Float, None, 'Starting position'], ['end', Type.Float, None, 'Final position']), None, 'List of motor, start and end positions'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, *args, **opts): motors = args[0:-2:3] starts = args[1:-2:3] ends = args[2:-2:3] nr_interv = args[-2] integ_time = args[-1] self._prepare(motors, starts, ends, nr_interv, integ_time, **opts) class dscan(dNscan, Macro): """motor scan relative to the starting position. dscan scans one motor, as specified by motor. If motor motor is at a position X before the scan begins, it will be scanned from X+start_pos to X+final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. """ param_def = [ ['motor', Type.Moveable, None, 'Moveable to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): self._prepare([motor], [start_pos], [final_pos], nr_interv, integ_time, **opts) class d2scan(dNscan,Macro): """two-motor scan relative to the starting position. d2scan scans two motors, as specified by motor1 and motor2. Each motor moves the same number of intervals. If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, nr_interv, integ_time, **opts): self._prepare([motor1,motor2], [start_pos1,start_pos2], [final_pos1,final_pos2], nr_interv, integ_time, **opts) class d3scan(dNscan, Macro): """three-motor scan . d3scan scans three motors, as specified by motor1, motor2 and motor3. Each motor moves the same number of intervals. If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2,3) The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_interv, integ_time, **opts): self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], nr_interv, integ_time, **opts) class d4scan(dNscan, Macro): """four-motor scan relative to the starting positions a4scan scans four motors, as specified by motor1, motor2, motor3 and motor4. Each motor moves the same number of intervals. If each motor is at a position X before the scan begins, it will be scanned from X+start_posN to X+final_posN (where N is one of 1,2,3,4). The step size for each motor is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. Upon termination, the motors are returned to their starting positions. """ param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['motor4', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos4', Type.Float, None, 'Scan start position 3'], ['final_pos4', Type.Float, None, 'Scan final position 3'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, nr_interv, integ_time, **opts): self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], nr_interv, integ_time, **opts) class mesh(Macro,Hookable): """2d grid scan . The mesh scan traces out a grid using motor1 and motor2. The first motor scans from m1_start_pos to m1_final_pos using the specified number of intervals. The second motor similarly scans from m2_start_pos to m2_final_pos. Each point is counted for for integ_time seconds (or monitor counts, if integ_time is negative). The scan of motor1 is done at each point scanned by motor2. That is, the first motor scan is nested within the second motor scan. """ hints = { 'scan' : 'mesh', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } env = ('ActiveMntGrp',) param_def = [ ['motor1', Type.Moveable, None, 'First motor to move'], ['m1_start_pos',Type.Float, None, 'Scan start position for first motor'], ['m1_final_pos',Type.Float, None, 'Scan final position for first motor'], ['m1_nr_interv',Type.Integer, None, 'Number of scan intervals'], ['motor2', Type.Moveable, None, 'Second motor to move'], ['m2_start_pos',Type.Float, None, 'Scan start position for second motor'], ['m2_final_pos',Type.Float, None, 'Scan final position for second motor'], ['m2_nr_interv',Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'], ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] ] def prepare(self, m1, m1_start_pos, m1_final_pos, m1_nr_interv, m2, m2_start_pos, m2_final_pos, m2_nr_interv, integ_time, bidirectional, **opts): self.motors=[m1,m2] self.starts = numpy.array([m1_start_pos,m2_start_pos],dtype='d') self.finals = numpy.array([m1_final_pos,m2_final_pos],dtype='d') self.nr_intervs= numpy.array([m1_nr_interv, m2_nr_interv],dtype='i') self.integ_time = integ_time self.bidirectional_mode = bidirectional self.name=opts.get('name','mesh') generator=self._generator moveables=self.motors env=opts.get('env',{}) constrains=[getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] #Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') #self.post_scan_hooks = self.getHooks('post-scan') self._gScan=SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} step["integ_time"] = self.integ_time step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] m1start,m2start=self.starts m1end,m2end=self.finals points1,points2=self.nr_intervs+1 point_no=1 m1_space = numpy.linspace(m1start,m1end,points1) m1_space_inv = numpy.linspace(m1end,m1start,points1) for i, m2pos in enumerate(numpy.linspace(m2start,m2end,points2)): space = m1_space if i % 2 != 0 and self.bidirectional_mode: space = m1_space_inv for m1pos in space: step["positions"] = numpy.array([m1pos,m2pos]) step["point_id"]= point_no #TODO: maybe another ID would be better? (e.g. "(A,B)") point_no+=1 yield step def run(self,*args): for step in self._gScan.step_scan(): yield step @property def data(self): return self._gScan.data class fscan(Macro,Hookable): '''N-dimensional scan along user defined paths. The motion path for each motor is defined through the evaluation of a user-supplied function that is evaluated as a function of the independent variables. -independent variables are supplied through the indepvar string. The syntax for indepvar is "x=expresion1,y=expresion2,..." -If no indep vars need to be defined, write "!" or "*" or "None" -motion path for motor is generated by evaluating the corresponding function 'func' -Count time is given by integ_time. If integ_time is a scalar, then the same integ_time is used for all points. If it evaluates as an array (with same length as the paths), fscan will assign a different integration time to each acquisition point. -If integ_time is positive, it specifies seconds and if negative, specifies monitor counts. IMPORTANT Notes: -no spaces are allowed in the indepvar string. -all funcs must evaluate to the same number of points EXAMPLE: fscan x=[1,3,5,7,9],y=arange(5) motor1 x**2 motor2 sqrt(y*x-3) 0.1 ''' hints = { 'scan' : 'fscan', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } env = ('ActiveMntGrp',) param_def = [ ['indepvars', Type.String, None, 'Independent Variables'], ['motor_funcs', ParamRepeat(['motor', Type.Moveable, None, 'motor'], ['func', Type.String, None, 'curve defining path']), None, 'List of motor and path curves'], ['integ_time', Type.String, None, 'Integration time'] ] def prepare(self, *args, **opts): if args[0].lower() in ["!", "*", "none", None]: indepvars={} else: indepvars=SafeEvaluator({'dict':dict}).eval('dict(%s)'%args[0]) #create a dict containing the indepvars self.motors=args[1:-1:2] #get motors sev=SafeEvaluator(indepvars) #create a safe evaluator whitelisting the indepvars self.funcstrings=args[2:-1:2] self.paths = map(sev.eval,self.funcstrings) #evaluate the functions self.integ_time=numpy.array(sev.eval(args[-1]), dtype='d') self.opts = opts if len(self.motors)==len(self.paths)>0: self.N=len(self.motors) else: raise ValueError('Moveable and func lists must be non-empty and same length') npoints=len(self.paths[0]) try: #if everything is OK, the following lines should return a 2D array # n which each motor path is a row. #Typical failure is due to shape mismatch due to inconsistent input self.paths=numpy.array(self.paths,dtype='d') self.paths.reshape((self.N, npoints)) except: #shape mismatch? #try to give a meaningful description of the error for p,fs in zip(self.paths,self.funcstrings): if len(p)!=npoints: raise ValueError( '"%s" and "%s" yield different number of points (%i vs %i)' %(self.funcstrings[0],fs,npoints,len(p))) raise #the problem wasn't a shape mismatch self.nr_points=npoints if self.integ_time.size==1: self.integ_time=self.integ_time*numpy.ones(self.nr_points) #extend integ_time elif self.integ_time.size!=self.nr_points: raise ValueError('time_integ must either be a scalar or length=npoints (%i)'%self.nr_points) self.name=opts.get('name','fscan') generator=self._generator moveables=self.motors env=opts.get('env',{}) constrains=[getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] #Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') #self.post_scan_hooks = self.getHooks('post-scan' self._gScan=SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] for i in xrange(self.nr_points): step["positions"] = self.paths[:,i] step["integ_time"] = self.integ_time[i] step["point_id"]= i yield step def run(self,*args): for step in self._gScan.step_scan(): yield step @property def data(self): return self._gScan.data class ascanh(aNscan, Macro): """Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. The step size is (start_pos-final_pos)/nr_interv. The number of data points collected will be nr_interv+1. Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts. """ param_def = [ ['motor', Type.Moveable, None, 'Moveable to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): self._prepare([motor], [start_pos], [final_pos], nr_interv, integ_time, mode=HybridMode, **opts) class scanhist(Macro): """Shows scan history information. Give optional parameter scan number to display details about a specific scan""" param_def = [ ['scan number', Type.Integer, -1, 'scan number. [default=-1 meaning show all scans]'], ] def run(self, scan_number): try: hist = self.getEnv("ScanHistory") except UnknownEnv: print "No scan recorded in history" return if scan_number < 0: self.show_all(hist) else: self.show_one(hist, scan_number) def show_one(self, hist, scan_number): item = None for h in hist: if h['serialno'] == scan_number: item = h break if item is None: self.warning("Could not find scan number %s", scan_number) return serialno, title = h['serialno'], h['title'] start = datetime.datetime.fromtimestamp(h['startts']) end = datetime.datetime.fromtimestamp(h['endts']) total_time = end - start start, end, total_time = start.ctime(), end.ctime(), str(total_time) scan_dir, scan_file = h['ScanDir'], h['ScanFile'] deadtime = '%.1f%%' % h['deadtime'] user = h['user'] store = "Not stored!" if scan_dir is not None and scan_file is not None: if type(scan_file) is str: store = os.path.join(scan_dir, scan_file) else: store = scan_dir + os.path.sep + str(scan_file) channels = ", ".join(h['channels']) cols = ["#", "Title", "Start time", "End time", "Took", "Dead time", "User", "Stored", "Channels" ] data = [serialno, title, start, end, total_time, deadtime, user, store, channels] table = Table([data], row_head_str=cols, row_head_fmt='%*s', elem_fmt=['%-*s'], col_sep=' : ') for line in table.genOutput(): self.output(line) def show_all(self, hist): cols = "#", "Title", "Start time", "End time", "Stored" width = -1, -1, -1, -1, -1 out = List(cols, max_col_width=width) today = datetime.datetime.today().date() for h in hist: start = datetime.datetime.fromtimestamp(h['startts']) if start.date() == today: start = start.time().strftime("%H:%M:%S") else: start = start.strftime("%Y-%m-%d %H:%M:%S") end = datetime.datetime.fromtimestamp(h['endts']) if end.date() == today: end = end.time().strftime("%H:%M:%S") else: end = end.strftime("%Y-%m-%d %H:%M:%S") scan_file = h['ScanFile'] store = "Not stored!" if scan_file is not None: store = ", ".join(scan_file) row = h['serialno'], h['title'], start, end, store out.appendRow(row) for line in out.genOutput(): self.output(line) class ascanc(aNscan, Macro): """Do an absolute continuous scan of the specified motor. ascanc scans one motor, as specified by motor.""" param_def = [ ['motor', Type.Moveable, None, 'Moveable to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor, start_pos, final_pos, integ_time, slow_down, **opts): self._prepare([motor], [start_pos], [final_pos], slow_down, integ_time, mode=ContinuousMode, **opts) class a2scanc(aNscan, Macro): """two-motor continuous scan""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, integ_time, slow_down, **opts): self._prepare([motor1, motor2], [start_pos1, start_pos2], [final_pos1, final_pos2], slow_down, integ_time, mode=ContinuousMode, **opts) class a3scanc(aNscan, Macro): """three-motor continuous scan""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, integ_time, slow_down, **opts): self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], slow_down, integ_time, mode=ContinuousMode, **opts) class a4scanc(aNscan, Macro): """four-motor continuous scan""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['motor4', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos4', Type.Float, None, 'Scan start position 3'], ['final_pos4', Type.Float, None, 'Scan final position 3'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, integ_time, slow_down, **opts): self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], slow_down, integ_time, mode=ContinuousMode, **opts) class dNscanc(dNscan): def do_restore(self): # set velocities to maximum and then move to initial positions for moveable in self.motors: self._gScan.set_max_top_velocity(moveable) dNscan.do_restore(self) class dscanc(dNscanc, Macro): """continuous motor scan relative to the starting position.""" param_def = [ ['motor', Type.Moveable, None, 'Moveable to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor, start_pos, final_pos, integ_time, slow_down, **opts): self._prepare([motor], [start_pos], [final_pos], slow_down, integ_time, mode=ContinuousMode, **opts) class d2scanc(dNscanc,Macro): """continuous two-motor scan relative to the starting positions""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, integ_time, slow_down, **opts): self._prepare([motor1,motor2], [start_pos1,start_pos2], [final_pos1,final_pos2], slow_down, integ_time, mode=ContinuousMode, **opts) class d3scanc(dNscanc, Macro): """continuous three-motor scan""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, integ_time, slow_down, **opts): self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], slow_down, integ_time, mode=ContinuousMode, **opts) class d4scanc(dNscanc, Macro): """continuous four-motor scan relative to the starting positions""" param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['motor4', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos4', Type.Float, None, 'Scan start position 3'], ['final_pos4', Type.Float, None, 'Scan final position 3'], ['integ_time', Type.Float, None, 'Integration time'], ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, integ_time, slow_down, **opts): self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], slow_down, integ_time, mode=ContinuousMode, **opts) class meshc(Macro,Hookable): """2d grid scan. scans continuous""" hints = { 'scan' : 'mesh', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } env = ('ActiveMntGrp',) param_def = [ ['motor1', Type.Moveable, None, 'First motor to move'], ['m1_start_pos', Type.Float, None, 'Scan start position for first motor'], ['m1_final_pos', Type.Float, None, 'Scan final position for first motor'], ['slow_down', Type.Float, None, 'global scan slow down factor (0, 1]'], ['motor2', Type.Moveable, None, 'Second motor to move'], ['m2_start_pos', Type.Float, None, 'Scan start position for second motor'], ['m2_final_pos', Type.Float, None, 'Scan final position for second motor'], ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'], ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] ] def prepare(self, m1, m1_start_pos, m1_final_pos, slow_down, m2, m2_start_pos, m2_final_pos, m2_nr_interv, integ_time, bidirectional, **opts): self.motors=[m1,m2] self.slow_down = slow_down self.starts = numpy.array([m1_start_pos,m2_start_pos],dtype='d') self.finals = numpy.array([m1_final_pos,m2_final_pos],dtype='d') self.m2_nr_interv = m2_nr_interv self.integ_time = integ_time self.bidirectional_mode = bidirectional self.nr_waypoints = m2_nr_interv + 1 self.name=opts.get('name','meshc') moveables=self.motors env=opts.get('env',{}) constrains=[getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] extrainfodesc = opts.get('extrainfodesc',[]) #Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') #self.post_scan_hooks = self.getHooks('post-scan' self._gScan = CScan(self, self._waypoint_generator, self._period_generator, moveables, env, constrains, extrainfodesc) self._gScan.frozen_motors = [m2] def _waypoint_generator(self): step = {} step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["check_func"] = [] step["slow_down"] = self.slow_down points2=self.m2_nr_interv+1 m1start,m2start=self.starts m1end,m2end=self.finals point_no=1 for i, m2pos in enumerate(numpy.linspace(m2start,m2end,points2)): start, end = m1start, m1end if i % 2 != 0 and self.bidirectional_mode: start, end = m1end, m1start step["start_positions"] = numpy.array([start, m2pos]) step["positions"] = numpy.array([end, m2pos]) step["point_id"]= point_no point_no+=1 yield step def _period_generator(self): step = {} step["integ_time"] = self.integ_time step["pre-acq-hooks"] = self.getHooks('pre-acq') step["post-acq-hooks"] = self.getHooks('post-acq')+self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] step['extrainfo'] = {} point_no = 0 while(True): point_no += 1 step["point_id"] = point_no yield step def run(self,*args): for step in self._gScan.step_scan(): yield step def getTimeEstimation(self): return self._gScan.waypoint_estimation() def getIntervalEstimation(self): return self.nr_waypoints @property def data(self): return self._gScan.data class ascanct(aNscan, Macro): '''Continuous scan controlled by hardware trigger signals. A sequence of trigger pulses is programmed by time. The scan active time is calculated from nr_of_points * point time. It corresponds to the time while all the involved in the scan moveables are at the constant velocity. Experimental channels are configured to acquire during acquistion time calculated from acq_time [%] of the point_time. Temporary solution used to configure trigger device (pulse train generator): "TriggerDevices" evironment variable must be set to Ni660X device name or any other Tango device name implementing: +) following attributes: - InitialDelayTime [s] - delay time from calling Start to generating first pulse - HighTime [s] - time interval while signal will maintain its high state - LowTime [s] - time interval while signal will maintain its low state - SampPerChan - nr of pulses to be generated - IdleState - state (high or low) which signal will take after the Start command and which will maintain during the InitialDelayTime. +) following commands: - Start - Stop)''' hints = {'scan' : 'ascanct', 'allowsHooks': ('pre-configuration', 'post-configuration', 'pre-start', 'pre-cleanup', 'post-cleanup') } param_def = [['motor', Type.Moveable, None, 'Moveable name'], ['start_pos', Type.Float, None, 'Starting position'], ['end_pos', Type.Float, None, 'Ending pos value'], ['nr_of_points', Type.Integer, None, 'Nr of scan points'], ['point_time', Type.Float, None, 'Time interval reserved for ' + 'each scan point [s].'], ['acq_time', Type.Float, 99, 'Acquisition time per scan point. ' + 'Expressed in percentage of point_time. Default: 99 [%]'], ['samp_freq', Type.Float, -1, 'Sampling frequency. ' + 'Default: -1 (means maximum possible)']] def prepare(self, motor, start_pos, end_pos, nr_of_points, point_time, acq_time, samp_freq, **opts): self._prepare([motor], [start_pos], [end_pos], nr_of_points, point_time, mode=ContinuousHwTimeMode, **opts) self.acq_time = acq_time self.samp_freq = samp_freq class a2scanct(aNscan, Macro): '''Continuous scan controlled by hardware trigger signals. A sequence of trigger pulses is programmed by time. The scan active time is calculated from nr_of_points * point time. It corresponds to the time while all the involved in the scan moveables are at the constant velocity. Experimental channels are configured to acquire during acquistion time calculated from acq_time [%] of the point_time. Temporary solution used to configure trigger device (pulse train generator): "TriggerDevices" evironment variable must be set to Ni660X device name or any other Tango device name implementing: +) following attributes: - InitialDelayTime [s] - delay time from calling Start to generating first pulse - HighTime [s] - time interval while signal will maintain its high state - LowTime [s] - time interval while signal will maintain its low state - SampPerChan - nr of pulses to be generated - IdleState - state (high or low) which signal will take after the Start command and which will maintain during the InitialDelayTime. +) following commands: - Start - Stop)''' hints = {'scan' : 'a2scanct', 'allowsHooks': ('pre-configuration', 'post-configuration', 'pre-start', 'pre-cleanup', 'post-cleanup') } param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ["nr_of_points", Type.Integer, None, "Nr of scan points"], ['point_time', Type.Float, None, 'Time interval reserved for ' + 'each scan point [s].'], ["acq_time", Type.Float, 99, 'Acquisition time per scan point. ' + 'Expressed in percentage of point_time. Default: 99 [%]'], ["samp_freq", Type.Float, -1, 'Sampling frequency. ' + 'Default: -1 (means maximum possible)']] def prepare(self, m1, s1, f1, m2, s2, f2, nr_of_points, point_time, acq_time, samp_freq, **opts): self._prepare([m1, m2], [s1, s2], [f1, f2], nr_of_points, point_time, mode=ContinuousHwTimeMode, **opts) self.acq_time = acq_time self.samp_freq = samp_freq class a3scanct(aNscan, Macro): '''Continuous scan controlled by hardware trigger signals. A sequence of trigger pulses is programmed by time. The scan active time is calculated from nr_of_points * point time. It corresponds to the time while all the involved in the scan moveables are at the constant velocity. Experimental channels are configured to acquire during acquistion time calculated from acq_time [%] of the point_time. Temporary solution used to configure trigger device (pulse train generator): "TriggerDevices" evironment variable must be set to Ni660X device name or any other Tango device name implementing: +) following attributes: - InitialDelayTime [s] - delay time from calling Start to generating first pulse - HighTime [s] - time interval while signal will maintain its high state - LowTime [s] - time interval while signal will maintain its low state - SampPerChan - nr of pulses to be generated - IdleState - state (high or low) which signal will take after the Start command and which will maintain during the InitialDelayTime. +) following commands: - Start - Stop)''' hints = {'scan' : 'a2scanct', 'allowsHooks': ('pre-configuration', 'post-configuration', 'pre-start', 'pre-cleanup', 'post-cleanup') } param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ["nr_of_points", Type.Integer, None, "Nr of scan points"], ['point_time', Type.Float, None, 'Time interval reserved for ' + 'each scan point [s].'], ["acq_time", Type.Float, 99, 'Acquisition time per scan point. ' + 'Expressed in percentage of point_time. Default: 99 [%]'], ["samp_freq", Type.Float, -1, 'Sampling frequency. ' + 'Default: -1 (means maximum possible)']] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_of_points, point_time, acq_time, samp_freq, **opts): self._prepare([m1, m2, m3], [s1, s2, s3], [f1, f2, f3], nr_of_points, point_time, mode=ContinuousHwTimeMode, **opts) self.acq_time = acq_time self.samp_freq = samp_freq class a4scanct(aNscan, Macro): '''Continuous scan controlled by hardware trigger signals. A sequence of trigger pulses is programmed by time. The scan active time is calculated from nr_of_points * point time. It corresponds to the time while all the involved in the scan moveables are at the constant velocity. Experimental channels are configured to acquire during acquistion time calculated from acq_time [%] of the point_time. Temporary solution used to configure trigger device (pulse train generator): "TriggerDevices" evironment variable must be set to Ni660X device name or any other Tango device name implementing: +) following attributes: - InitialDelayTime [s] - delay time from calling Start to generating first pulse - HighTime [s] - time interval while signal will maintain its high state - LowTime [s] - time interval while signal will maintain its low state - SampPerChan - nr of pulses to be generated - IdleState - state (high or low) which signal will take after the Start command and which will maintain during the InitialDelayTime. +) following commands: - Start - Stop)''' hints = {'scan' : 'a2scanct', 'allowsHooks': ('pre-configuration', 'post-configuration', 'pre-start', 'pre-cleanup', 'post-cleanup') } param_def = [ ['motor1', Type.Moveable, None, 'Moveable 1 to move'], ['start_pos1', Type.Float, None, 'Scan start position 1'], ['final_pos1', Type.Float, None, 'Scan final position 1'], ['motor2', Type.Moveable, None, 'Moveable 2 to move'], ['start_pos2', Type.Float, None, 'Scan start position 2'], ['final_pos2', Type.Float, None, 'Scan final position 2'], ['motor3', Type.Moveable, None, 'Moveable 3 to move'], ['start_pos3', Type.Float, None, 'Scan start position 3'], ['final_pos3', Type.Float, None, 'Scan final position 3'], ['motor4', Type.Moveable, None, 'Moveable 4 to move'], ['start_pos4', Type.Float, None, 'Scan start position 4'], ['final_pos4', Type.Float, None, 'Scan final position 4'], ["nr_of_points", Type.Integer, None, "Nr of scan points"], ['point_time', Type.Float, None, 'Time interval reserved for ' + 'each scan point [s].'], ["acq_time", Type.Float, 99, 'Acquisition time per scan point. ' + 'Expressed in percentage of point_time. Default: 99 [%]'], ["samp_freq", Type.Float, -1, 'Sampling frequency. ' + 'Default: -1 (means maximum possible)']] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, nr_of_points, point_time, acq_time, samp_freq, **opts): self._prepare([m1, m2, m3, m4], [s1, s2, s3, s4], [f1, f2, f3, f4], nr_of_points, point_time, mode=ContinuousHwTimeMode, **opts) self.acq_time = acq_time self.samp_freq = samp_freq sardana-1.2.0/src/sardana/macroserver/macros/sequence.py0000644000234100017500000000656512174204310024734 0ustar cpascualcpascual00000000000000import os import xml.dom.minidom from sardana.macroserver.macro import * TAG_MACRO = 'macro' TAG_PARAM = 'param' TAG_PARAMREPEAT = 'paramrepeat' TAG_REPEAT = 'repeat' TAG_PARAMS = 'params' TAG_SEQUENCE = 'sequence' ATTRIBUTE_NAME = 'name' ATTRIBUTE_VALUE = 'value' ATTRIBUTE_INDEX = 'nr' ATTRIBUTE_DESCRIPTION = 'description' ATTRIBUTE_DEFVALUE = 'defvalue' ATTRIBUTE_TYPE = 'type' ATTRIBUTE_ALLOWEDHOOKS = 'allowedHooks' ATTRIBUTE_HASPARAMS = 'hasParams' ATTRIBUTE_MIN = 'min' class sequence(Macro): """This macro executes a sequence of macros. As a parameter it receives a string which is a xml structure. These macros which allow hooks can nest another sequence (xml structure). In such a case, this macro is executed recursively.""" param_def = [ ['xml', Type.String, None, 'Xml string representing a sequence'] ] def run(self, *pars): xmlDoc = xml.dom.minidom.parseString(pars[0]) macros = self.parseXml(xmlDoc) for macro in macros: self.runMacro(macro) # self.pausePoint() def parseXml(self, xmlDoc): macros = [] sequenceElement = xmlDoc.getElementsByTagName(TAG_SEQUENCE)[0] childElement = sequenceElement.firstChild while childElement: if childElement.localName == TAG_MACRO: params, hookElement = self.parseMacro(childElement) macro = self.createMacro(params) if hookElement is not None: hook = self.createExecMacroHook([self.__class__.__name__, hookElement.toxml()]) macro.hooks = [hook] macros.append(macro) childElement = childElement.nextSibling return macros def parseMacro(self, xmlElement): name = str(xmlElement.getAttribute(ATTRIBUTE_NAME)) params = (name,) hookElement = None childElement = xmlElement.firstChild while childElement: if childElement.localName == TAG_PARAM: params += self.parseParam(childElement) elif childElement.localName == TAG_PARAMREPEAT: params += self.parseParamRepeat(childElement) elif childElement.localName == TAG_SEQUENCE: hookElement = childElement childElement = childElement.nextSibling return (params,hookElement) def parseParam(self, xmlElement): return (str(xmlElement.getAttribute(ATTRIBUTE_VALUE)),) def parseParamRepeat(self, xmlElement): params = () childElement = xmlElement.firstChild while childElement: if childElement.localName == TAG_REPEAT: params += self.parseRepeat(childElement) childElement = childElement.nextSibling return params def parseRepeat(self, xmlElement): params = () childElement = xmlElement.firstChild while childElement: if childElement.localName == TAG_PARAM: params += self.parseParam(childElement) elif childElement.localName == TAG_PARAMREPEAT: params += self.parseParamRepeat(childElement) childElement = childElement.nextSibling return params sardana-1.2.0/src/sardana/macroserver/macros/standard.py0000644000234100017500000004524312174204310024720 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the standard macro module""" __all__ = ["ct", "mstate", "mv", "mvr", "pwa", "pwm", "set_lim", "set_lm", "set_pos", "settimer", "uct", "umv", "umvr", "wa", "wm"] __docformat__ = 'restructuredtext' import datetime from taurus.console.table import Table from PyTango import DevState from sardana.macroserver.macro import Macro, macro, Type, ParamRepeat, ViewOption ################################################################################ # # Motion related macros # ################################################################################ class _wm(Macro): """Show motor positions""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move']), None, 'List of motor to show'], ] def prepare(self, *motor_list, **opts): self.table_opts = {} def run(self, *motor_list): show_dial = self.getViewOption(ViewOption.ShowDial) motor_width = 9 motor_names = [] motor_pos = [] motor_list = list(motor_list) motor_list.sort() for motor in motor_list: name = motor.getName() motor_names.append([name]) pos = motor.getPosition(force=True) if pos is None: pos = float('NAN') if show_dial: dial_pos = motor.getDialPosition(force=True) if dial_pos is None: dial_pos = float('NAN') motor_pos.append((pos,dial_pos)) else: motor_pos.append((pos,)) motor_width = max(motor_width,len(name)) fmt = '%c*.%df' % ('%',motor_width - 5) table = Table(motor_pos, elem_fmt=[fmt], col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line) class _wum(Macro): """Show user motor positions""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move']), None, 'List of motor to show'], ] def prepare(self, *motor_list, **opts): self.table_opts = {} def run(self, *motor_list): show_dial = self.getViewOption(ViewOption.ShowDial) motor_width = 9 motor_names = [] motor_pos = [] motor_list = list(motor_list) motor_list.sort() for motor in motor_list: name = motor.getName() motor_names.append([name]) pos = motor.getPosition(force=True) if pos is None: pos = float('NAN') motor_pos.append((pos,)) motor_width = max(motor_width,len(name)) fmt = '%c*.%df' % ('%',motor_width - 5) table = Table(motor_pos, elem_fmt=[fmt], col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line) class wu(Macro): """Show all user motor positions""" def prepare(self, **opts): self.all_motors = self.findObjs('.*', type_class=Type.Moveable) self.table_opts = {} def run(self): nr_motors = len(self.all_motors) if nr_motors == 0: self.output('No motor defined') return self.output('Current positions (user) on %s'%datetime.datetime.now().isoformat(' ')) self.output('') self.execMacro('_wum',*self.all_motors, **self.table_opts) class wa(Macro): """Show all motor positions""" def prepare(self, **opts): self.all_motors = self.findObjs('.*', type_class=Type.Moveable) self.table_opts = {} def run(self): nr_motors = len(self.all_motors) if nr_motors == 0: self.output('No motor defined') return show_dial = self.getViewOption(ViewOption.ShowDial) if show_dial: self.output('Current positions (user, dial) on %s'%datetime.datetime.now().isoformat(' ')) else: self.output('Current positions (user) on %s'%datetime.datetime.now().isoformat(' ')) self.output('') self.execMacro('_wm',*self.all_motors, **self.table_opts) class pwa(Macro): """Show all motor positions in a pretty table""" def run(self): self.execMacro('wa', **Table.PrettyOpts) class set_lim(Macro): """Sets the software limits on the specified motor hello""" param_def = [ ['motor', Type.Moveable, None, 'Motor name'], ['low', Type.Float, None, 'lower limit'], ['high', Type.Float, None, 'upper limit'] ] def run(self, motor, low, high): name = motor.getName() self.debug("Setting user limits for %s" % name) motor.getPositionObj().setLimits(low,high) self.output("%s limits set to %.4f %.4f (user units)" % (name, low, high)) class set_lm(Macro): """Sets the dial limits on the specified motor""" param_def = [ ['motor', Type.Motor, None, 'Motor name'], ['low', Type.Float, None, 'lower limit'], ['high', Type.Float, None, 'upper limit'] ] def run(self, motor, low, high): name = motor.getName() self.debug("Setting dial limits for %s" % name) motor.getDialPositionObj().setLimits(low,high) self.output("%s limits set to %.4f %.4f (dial units)" % (name, low, high)) class set_pos(Macro): """Sets the position of the motor to the specified value""" param_def = [ ['motor', Type.Motor, None, 'Motor name'], ['pos', Type.Float, None, 'Position to move to'] ] def run(self, motor, pos): name = motor.getName() old_pos = motor.getPosition(force=True) motor.definePosition(pos) self.output("%s reset from %.4f to %.4f" % (name, old_pos, pos)) class set_user_pos(Macro): """Sets the USER position of the motor to the specified value (by changing OFFSET and keeping DIAL)""" param_def = [ ['motor', Type.Motor, None, 'Motor name'], ['pos', Type.Float, None, 'Position to move to'] ] def run(self, motor, pos): name = motor.getName() old_pos = motor.getPosition(force=True) offset_attr = motor.getAttribute('Offset') old_offset = offset_attr.read().value new_offset = pos - (old_pos - old_offset) offset_attr.write(new_offset) self.output("%s reset from %.4f (offset %.4f) to %.4f (offset %.4f)" % (name, old_pos, old_offset, pos, new_offset)) class wm(Macro): """Show the position of the specified motors.""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to see where it is']), None, 'List of motor to show'], ] def prepare(self, *motor_list, **opts): self.table_opts = {} def run(self, *motor_list): motor_width = 10 motor_names = [] motor_pos = [] show_dial = self.getViewOption(ViewOption.ShowDial) for motor in motor_list: name = motor.getName() motor_names.append([name]) posObj = motor.getPositionObj() upos = map(str, [posObj.getMaxValue(), motor.getPosition(force=True), posObj.getMinValue()]) pos_data = [''] + upos if show_dial: dPosObj = motor.getDialPositionObj() dpos = map(str, [dPosObj.getMaxValue(), motor.getDialPosition(force=True), dPosObj.getMinValue()]) pos_data += [''] + dpos motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 3) * 2 row_head_str = ['User', ' High', ' Current', ' Low'] if show_dial: row_head_str += ['Dial', ' High', ' Current', ' Low'] table = Table(motor_pos, elem_fmt=elem_fmt, row_head_str=row_head_str, col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line) class wum(Macro): """Show the user position of the specified motors.""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to see where it is']), None, 'List of motor to show'], ] def prepare(self, *motor_list, **opts): self.table_opts = {} def run(self, *motor_list): motor_width = 10 motor_names = [] motor_pos = [] for motor in motor_list: name = motor.getName() motor_names.append([name]) posObj = motor.getPositionObj() upos = map(str, [posObj.getMaxValue(), motor.getPosition(force=True), posObj.getMinValue()]) pos_data = [''] + upos motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 3) * 2 row_head_str = ['User', ' High', ' Current', ' Low',] table = Table(motor_pos, elem_fmt=elem_fmt, row_head_str=row_head_str, col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line) class pwm(Macro): """Show the position of the specified motors in a pretty table""" param_def = [ ['motor_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move']), None, 'List of motor to show'], ] def run(self, *motor_list): self.execMacro('wm', *motor_list, **Table.PrettyOpts) class mv(Macro): """Move motor(s) to the specified position(s)""" param_def = [ ['motor_pos_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], ['pos', Type.Float, None, 'Position to move to']), None, 'List of motor/position pairs'], ] def run(self, *motor_pos_list): motors, positions = [], [] for motor, pos in motor_pos_list: motors.append(motor) positions.append(pos) self.debug("Starting %s movement to %s", motor.getName(), pos) motion = self.getMotion(motors) state, pos = motion.move(positions) if state != DevState.ON: self.warning("Motion ended in %s", state) msg = [] for motor in motors: msg.append(motor.information()) self.info("\n".join(msg)) class mstate(Macro): """Prints the state of a motor""" param_def = [['motor', Type.Moveable, None, 'Motor to check state']] def run(self, motor): self.info("Motor %s" % str(motor.getState())) class umv(Macro): """Move motor(s) to the specified position(s) and update""" param_def = mv.param_def def prepare(self, *motor_pos_list, **opts): self.all_names = [] self.all_pos = [] self.print_pos = False for motor, pos in motor_pos_list: self.all_names.append([motor.getName()]) pos, posObj = motor.getPosition(force=True), motor.getPositionObj() self.all_pos.append([pos]) posObj.subscribeEvent(self.positionChanged, motor) def run(self, *motor_pos_list): self.print_pos = True pars = [] for motor, pos in motor_pos_list: pars.append(motor) pars.append(pos) self.execMacro('mv', *pars) self.finish() def finish(self): self._clean() self.printAllPos() def on_abort(self): self.finish() def _clean(self): for motor, pos in self.getParameters(): posObj = motor.getPositionObj() try: posObj.unsubscribeEvent(self.positionChanged, motor) except Exception, e: print str(e) raise e def positionChanged(self, motor, position): idx = self.all_names.index([motor.getName()]) self.all_pos[idx] = [position] if self.print_pos: self.printAllPos() def printAllPos(self): motor_width = 10 table = Table(self.all_pos, elem_fmt=['%*.4f'], col_head_str=self.all_names, col_head_width=motor_width) self.outputBlock(table.genOutput()) self.flushOutput() class mvr(Macro): """Move motor(s) relative to the current position(s)""" param_def = [ ['motor_disp_list', ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], ['disp', Type.Float, None, 'Relative displacement']), None, 'List of motor/displacement pairs'], ] def run(self, *motor_disp_list): motor_pos_list = [] for motor, disp in motor_disp_list: pos = motor.getPosition(force=True) if pos is None: self.error("Cannot get %s position" % motor.getName()) return else: pos += disp motor_pos_list.extend([motor, pos]) self.execMacro('mv', *motor_pos_list) class umvr(Macro): """Move motor(s) relative to the current position(s) and update""" param_def = mvr.param_def def run(self, *motor_disp_list): motor_pos_list = [] for motor, disp in motor_disp_list: pos = motor.getPosition(force=True) if pos is None: self.error("Cannot get %s position" % motor.getName()) return else: pos += disp motor_pos_list.extend([motor, pos]) self.execMacro('umv', *motor_pos_list) ################################################################################ # # Data acquisition related macros # ################################################################################ class ct(Macro): """Count for the specified time on the active measurement group""" env = ('ActiveMntGrp',) param_def = [ ['integ_time', Type.Float, 1.0, 'Integration time'] ] def prepare(self, integ_time, **opts): mnt_grp_name = self.getEnv('ActiveMntGrp') self.mnt_grp = self.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) def run(self, integ_time): self.output("hello") if self.mnt_grp is None: self.error('ActiveMntGrp is not defined or has invalid value') return self.debug("Counting for %s sec", integ_time) self.outputDate() self.output('') self.flushOutput() state, data = self.mnt_grp.count(integ_time) names, counts = [], [] for ch_info in self.mnt_grp.getChannelsInfo(): names.append(' %s' % ch_info.label) ch_data = data.get(ch_info.full_name) if ch_info.shape > [1]: counts.append(list(ch_data.shape)) else: counts.append(ch_data) table = Table([counts], row_head_str=names, row_head_fmt='%*s', col_sep=' = ') for line in table.genOutput(): self.output(line) class uct(Macro): """Count on the active measurement group and update""" env = ('ActiveMntGrp',) param_def = [ ['integ_time', Type.Float, 1.0, 'Integration time'] ] def prepare(self, integ_time, **opts): self.print_value = False mnt_grp_name = self.getEnv('ActiveMntGrp') self.mnt_grp = self.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) if self.mnt_grp is None: return names, nan = self.mnt_grp.getChannelLabels(), float('nan') self.names = [ [n] for n in names ] self.values = len(names)*[ [nan] ] self.channels = self.mnt_grp.getChannelAttrExs() for ch_attr_ex in self.channels: ch_attr_ex.subscribeEvent(self.counterChanged, ch_attr_ex) def printAllValues(self): ch_width = 10 table = Table(self.values, elem_fmt=['%*.4f'], col_head_str=self.names, col_head_width=ch_width) self.outputBlock(table.genOutput()) self.flushOutput() def counterChanged(self, ch_attr, value): idx = self.channels.index(ch_attr) self.values[idx] = [value] if self.print_value: self.printAllValues() def run(self, integ_time): if self.mnt_grp is None: self.error('ActiveMntGrp is not defined or has invalid value') return self.print_value = True state, data = self.mnt_grp.count(integ_time) for ch_attr_ex in self.mnt_grp.getChannelAttrExs(): ch_attr_ex.unsubscribeEvent(self.counterChanged, ch_attr_ex) self.printAllValues() class settimer(Macro): """Defines the timer channel for the active measurement group""" env = ('ActiveMntGrp',) param_def = [ ['timer', Type.ExpChannel, None, 'Timer'], ] def run(self,timer): mnt_grp_name = self.getEnv('ActiveMntGrp') mnt_grp = self.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) if mnt_grp is None: self.error('ActiveMntGrp is not defined or has invalid value.\n' \ 'please define a valid active measurement group ' \ 'before setting a timer') return try: mnt_grp.setTimer(timer.getName()) except Exception,e: self.output(str(e)) self.output("%s is not a valid channel in the active measurement group" % timer) @macro([['message', ParamRepeat(['message_item', Type.String, None, 'message item to be reported']), None, 'message to be reported']]) def report(self, *message): """Logs a new record into the message report system (if active)""" self.report(' '.join(message)) sardana-1.2.0/src/sardana/macroserver/scan/0000755000234100017500000000000012174204361022204 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/macroserver/scan/recorder/0000755000234100017500000000000012174204361024011 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/macroserver/scan/recorder/__init__.py0000644000234100017500000000227212174204307026125 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan recorder module""" __docformat__ = 'restructuredtext' from .datarecorder import * from .output import * from .sharedmemory import * from .storage import *sardana-1.2.0/src/sardana/macroserver/scan/recorder/datarecorder.py0000644000234100017500000001330312174204307027022 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan data recorder module""" __all__ = ["DataFormats", "SaveModes", "RecorderStatus", "DataHandler", "DataRecorder", "DumbRecorder"] __docformat__ = 'restructuredtext' import time from taurus.core.util import Enumeration, Logger DataFormats = Enumeration('DataFormats', ('Spec', 'CSV', 'XLS', 'w5', 'w4', 'wx', 'fio')) SaveModes = Enumeration('SaveModes', ('Record', 'Block')) RecorderStatus = Enumeration('RecorderStatus', ('Idle', 'Active', 'Disable')) class DataHandler: """ The data handler is the data recording center of a system. It contains one or several recorders. All data transit through the handler, then given to recorders for final saving """ def __init__(self): self.recorders = [] def addRecorder(self, recorder): if recorder is not None: self.recorders.append( recorder ) def startRecordList(self, recordlist ): for recorder in self.recorders: if recorder.savemode is SaveModes.Record: recorder.startRecordList( recordlist ) def endRecordList(self, recordlist): for recorder in self.recorders: if recorder.savemode is SaveModes.Record: recorder.endRecordList( recordlist ) else: recorder.writeRecordList( recordlist ) def addRecord(self, recordlist, record): for recorder in self.recorders: if recorder.savemode is SaveModes.Record: recorder.writeRecord( record ) else: # blockSave pass def addCustomData(self, value, name, **kwargs): '''Write data other than a record. :param value: The value to be written :param name: An identification for this value Optional keyword arguments can be passed with information that some recorders may need in order to record this value. For example: the NeXus recorder will make use of "nxpath" info if available to place the value where it belongs in the nexus hierarchy. Check the `addCustomData` method of each recorder to see what they use/require. ''' for recorder in self.recorders: recorder.addCustomData(value, name, **kwargs ) # # Recorders # class DataRecorder(Logger): """ Generic class for data recorder. Does nothing""" def __init__(self, **pars): name = self.__class__.__name__ self.call__init__(Logger, name) self.recordlist = None self.status = RecorderStatus.Idle self.savemode = SaveModes.Record def getStatus(self): return self.status def disable(self): self.status = RecorderStatus.Disable def enable(self): self.status = RecorderStatus.Idle def startRecordList(self, recordlist): is_idle = self.status is RecorderStatus.Idle if is_idle: self.recordlist = recordlist self._startRecordList(recordlist) if is_idle: return 0 else: return -1 def _startRecordList(self, recordlist): pass def endRecordList(self, recordlist): self._endRecordList(recordlist) self.status = RecorderStatus.Idle self.recordlist = None def _endRecordList(self, recordlist): pass def writeRecordList(self, recordlist): """ Only in BLOCK_MODE. Will write whole RecordList """ self._startRecordList( recordlist ) for record in recordlist.records: self.writeRecord(record) self._endRecordList( recordlist ) def writeRecord(self, record): self._writeRecord( record ) def _writeRecord( self, record ): pass def setSaveMode( self, mode ): self.savemode = mode def addCustomData(self, value, name, **kwargs): self._addCustomData(value, name, **kwargs) def _addCustomData(self, value, name, **kwargs): pass class DumbRecorder(DataRecorder): def _startRecordList(self, recordlist): print "Starting new recording" print "# Title : ", recordlist.getEnvironValue('title') env = recordlist.getEnviron() for envky in env.keys(): if envky != 'title' and envky != 'labels': print "# %8s : %s " % (envky,str(env[envky])) print "# Started: ", time.ctime( env['starttime'] ) print "# L: ", print " ".join( env['labels'] ) def _writeRecord(self, record): print record.data def _endRecordList(self, recordlist): print "Ending recording" env = recordlist.getEnviron() print "Recording ended at: ", time.ctime( env['endtime'] ) sardana-1.2.0/src/sardana/macroserver/scan/recorder/output.py0000644000234100017500000002440312174204307025726 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan data output recorder module""" __all__ = ["JsonRecorder", "OutputRecorder"] __docformat__ = 'restructuredtext' import numpy import datetime import operator import string from taurus.core.util import CodecFactory, CaselessList from datarecorder import DataRecorder from storage import BaseFileRecorder class JsonRecorder(DataRecorder): def __init__(self, stream, cols=None, **pars): DataRecorder.__init__(self, **pars) self._stream = stream self._codec = CodecFactory().getCodec('json') def _startRecordList(self, recordlist): macro_id = recordlist.getEnvironValue('macro_id') title = recordlist.getEnvironValue('title') counters = recordlist.getEnvironValue('counters') scanfile = recordlist.getEnvironValue('ScanFile') scandir = recordlist.getEnvironValue('ScanDir') serialno = recordlist.getEnvironValue('serialno') column_desc = recordlist.getEnvironValue('datadesc') ref_moveables = recordlist.getEnvironValue('ref_moveables') estimatedtime = recordlist.getEnvironValue('estimatedtime') total_scan_intervals = recordlist.getEnvironValue('total_scan_intervals') start_time = recordlist.getEnvironValue('starttime').ctime() self.column_desc = [] discarded = [] for e in column_desc: if len(e.shape)==0: self.column_desc.append(e) else: discarded.append(e.label) if discarded: self.info('The following data will not be json-serialized: %s', " ".join(discarded) ) column_desc = [ d.toDict() for d in self.column_desc ] data = { 'column_desc' : column_desc, 'ref_moveables' : ref_moveables, 'estimatedtime' : estimatedtime, 'total_scan_intervals' : total_scan_intervals, 'starttime': start_time, 'title': title, 'counters': counters, 'scanfile': scanfile, 'scandir' : scandir, 'serialno': serialno} self._sendPacket(type="data_desc", data=data, macro_id=macro_id) def _endRecordList(self, recordlist): macro_id = recordlist.getEnvironValue('macro_id') data = { 'endtime' : recordlist.getEnvironValue('endtime').ctime(), 'deadtime' : recordlist.getEnvironValue('deadtime') } self._sendPacket(type="record_end", data=data, macro_id=macro_id) def _writeRecord(self, record): macro_id = self.recordlist.getEnvironValue('macro_id') data = {} # dict(record.data) for k in self.column_desc: name = k.name data[name] = record.data[name] self._sendPacket(type="record_data", data=data, macro_id=macro_id) def _sendPacket(self, **kwargs): '''creates a JSON packet using the keyword arguments passed and then sends it''' #data = self._codec.encode(('', kwargs)) #self._stream.sendRecordData(*data) self._stream.sendRecordData(kwargs, codec='json') def _addCustomData(self, value, name, **kwargs): ''' The custom data will be sent as a packet with type='custom_data' and its data will be the dictionary of keyword arguments passed to this method plus 'name' and 'value' ''' macro_id = self.recordlist.getEnvironValue('macro_id') data = dict(kwargs) #shallow copy data['name'] = name data['value'] = value self._sendPacket(type="custom_data", data=data, macro_id=macro_id) class OutputRecorder(DataRecorder): def __init__(self, stream, cols=None, number_fmt='%8.4f', col_width=8, col_sep=' ', **pars): DataRecorder.__init__(self, **pars) self._stream = stream if not number_fmt.startswith('%'): number_fmt = '%%s' % number_fmt self._number_fmt = number_fmt self._col_sep = col_sep self._col_width = col_width if operator.isSequenceType(cols) and not isinstance(cols, (str, unicode)): cols = CaselessList(cols) elif operator.isNumberType(cols): cols = cols else: cols = None self._columns = cols def _startRecordList(self, recordlist): starttime = recordlist.getEnvironValue('starttime').ctime() estimatedtime = recordlist.getEnvironValue('estimatedtime') data_desc = recordlist.getEnvironValue('datadesc') serialno = recordlist.getEnvironValue('serialno') col_sep = self._col_sep cols = self._columns number_fmt = self._number_fmt col_width = self._col_width dh = recordlist.getDataHandler() for fr in [r for r in dh.recorders if isinstance(r, BaseFileRecorder)]: self._stream.info('Operation will be saved in %s (%s)', fr.getFileName(), fr.getFormat()) msg = "Scan #%d started at %s." % (serialno, starttime) if not estimatedtime is None: estimatedtime = datetime.timedelta(0, abs(estimatedtime)) msg += " It will take at least %s\n" % estimatedtime msg += "Moving to start positions..." self._stream.info(msg) labels, col_names, col_sizes = [], [], [] header_rows, header_len = 1, 0 for col, column in enumerate(data_desc): if not getattr(column, 'output', True): continue name = column.name if operator.isSequenceType(cols) and name not in cols: continue if operator.isNumberType(cols) and col >= cols: break col_names.append(name) label = column.label.strip() if len(label) > col_width: label = label.split("/") else: label = [label] header_rows = max(header_rows, len(label)) labels.append(label) col_size = max(col_width, max(map(len, label))) header_len += col_size col_sizes.append(col_size) nb_cols = len(col_names) header_len += (nb_cols - 1) * len(col_sep) self._labels = labels self._col_names = col_names self._col_sizes = col_sizes header = [[] for i in range(header_rows)] for col, (label, col_size) in enumerate(zip(labels, col_sizes)): empty_row_nb = header_rows - len(label) for row in range(empty_row_nb): header[row].append(col_size*" ") for i, l in enumerate(label): header[i+empty_row_nb].append(string.center(l, col_size)) head = [] for header_row in header: head.append(col_sep.join(header_row)) header = "\n".join(head) cell_t_number = '%%%%(%%s)%s' % number_fmt[1:] self._scan_line_t = [(col_names[0], '%%(%s)8d' % col_names[0])] self._scan_line_t += [(name, cell_t_number % name) for name in col_names[1:]] self._stream.output(header) self._stream.flushOutput() def _endRecordList(self, recordlist): self._stream.flushOutput() starttime = recordlist.getEnvironValue('starttime') endtime = recordlist.getEnvironValue('endtime') deadtime = recordlist.getEnvironValue('deadtime') motiontime = recordlist.getEnvironValue('motiontime') totaltime = endtime - starttime endtime = endtime.ctime() serialno = recordlist.getEnvironValue('serialno') dh = recordlist.getDataHandler() for fr in [ r for r in dh.recorders if isinstance(r, BaseFileRecorder) ]: self._stream.info('Operation saved in %s (%s)', fr.getFileName(), fr.getFormat()) totaltimets = recordlist.getEnvironValue('endts') - recordlist.getEnvironValue('startts') deadtime_perc = deadtime * 100.0 / totaltimets motiontime_perc = motiontime * 100.0 / totaltimets self._stream.info('Scan #%s ended at %s, taking %s. Dead time %.1f%% (motion dead time %.1f%%)' % (serialno, endtime, totaltime, deadtime_perc, motiontime_perc)) def _writeRecord(self, record): cells = [] for i, (name, cell) in enumerate(self._scan_line_t): cell_data = record.data[name] if isinstance(cell_data, numpy.ndarray): cell = str(cell_data.shape) elif cell_data is None: cell = "" elif isinstance(cell_data, (str, unicode)): cell = "" else: cell %= record.data cell = string.center(cell.strip(), self._col_sizes[i]) cells.append(cell) scan_line = self._col_sep.join(cells) self._stream.output(scan_line) self._stream.flushOutput() def _addCustomData(self, value, name, **kwargs): ''' The custom data will be added as an info line in the form:: Custom data: name : value ''' if numpy.rank(value)>0: v = 'Array(%s)'%str(numpy.shape(value)) else: v = str(value) self._stream.output('Custom data: %s : %s'%(name,v) ) self._stream.flushOutput() sardana-1.2.0/src/sardana/macroserver/scan/recorder/sharedmemory.py0000644000234100017500000002346712174204307027076 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan data output recorder module""" __all__ = ["SharedMemoryRecorder"] __docformat__ = 'restructuredtext' import os import time import operator import numpy from datarecorder import DataRecorder SPS_AVAILABLE = False try: import sps SPS_AVAILABLE = True except: pass class _SharedMemoryRecorder(DataRecorder): def __init__(self, **pars): DataRecorder.__init__(self, **pars) class SPSRecorder(_SharedMemoryRecorder): maxenv = 50 envlen = 1024 def __init__(self, program=None, array=None, shape=None, **kwpars): """ @param[in] program SPS program name @param[in] array SPS array name @param[in] shape tuple (cols, rows) @param[in] pars keyword extra parameters """ _SharedMemoryRecorder.__init__(self, **kwpars) self.shape = shape self.owner = False self.owner_ENV = False self.setID(program, array) def setID(self, program, array): self.program = program.replace('/','') self.array = array.replace('_','') if not array is None: self.array_ENV = "%s_ENV" % self.array else: self.array_ENV = None if program and array: self.init() def init(self): pass def setSize(self, rows, cols): self.shape = (cols, rows) self.rows = rows self.cols = cols def isInitialized(self): ret = not (self.program is None or self.array_ENV is None or self.array is None) return ret and not self.shape is None def putEnv(self, name, value): if not self.isInitialized(): return sps.putenv(self.program, self.array_ENV, name, str(value)) def putAllEnv(self, d): if not self.isInitialized(): return p, a = self.program, self.array_ENV for k, v in d.iteritems(): sps.putenv(p, a, k, str(v)) def _startRecordList(self, recordlist): if not self.isInitialized(): return arraylist = sps.getarraylist(self.program) if self.array in arraylist: shm = sps.attach(self.program, self.array) else: cols, rows = self.shape sps.create(self.program, self.array, rows, cols, sps.DOUBLE) self.owner = True if self.array_ENV in arraylist: shm_env = sps.attach(self.program, self.array_ENV ) else: sps.create(self.program, self.array_ENV, self.maxenv, self.envlen, sps.STRING) self.owner_ENV = True self.nopts = 0 env = recordlist.getEnviron() self.labels = [ col.label for col in env['datadesc'] ] env = { 'title' : env['title'], 'started' : env['starttime'].ctime(), 'ended' : '', 'axistitles' : ' '.join(self.labels), 'ylabel' : 'Counts', 'nopts' : self.nopts, 'xbeg' : 0, 'xend' : 200, 'aborted' : 0, 'command' : 'done', 'fitresult' : '0' } self.putAllEnv(env) def _writeRecord(self, record): if not self.isInitialized(): return vals = [] for colname in self.labels: val = record.data.get(colname) if (not val is None) and (operator.isNumberType(val) and (type(val) in [int,float,long])): vals.append(val) elif (not val is None) and (operator.isNumberType(val)): valsmca = [] for i in range(0, len(val)): valsmca.append(val[i]) sufix = "1D" if self.array.endswith(sufix): valsmca = numpy.array( valsmca ) sps.putdatarow( self.program, self.array, record.recordno, valsmca ) sufix = "0D" if self.array.endswith(sufix): vals = numpy.array( vals ) sps.putdatarow( self.program, self.array, record.recordno, vals ) self.nopts +=1 env = { 'nopts' : self.nopts, 'peak' : 111, 'peakpos' : 34, 'fwhm' : 12.3, 'fwhmpos' : 45, 'com' : 23 } self.putAllEnv(env) def _endRecordList(self, recordlist): if not self.isInitialized(): return env = recordlist.getEnviron() self.putEnv('ended', env.get('endtime').ctime()) class ShmRecorder(DataRecorder): """ Sets data in shared memory to be used by sps """ maxenv = 50 envlen = 1024 def setShmID(self, shmid): self.shm_id = shmid self.shm_id_ENV = shmid + "_ENV" def setShmMntGrp(self, mnt_grp): self.mnt_grp = mnt_grp def setProgram(self, progname): self.progname = progname def isInitialized(self): try: getattr(self, "shm_id") getattr(self, "shm_id_env") getattr(self, "progname") return True except: return False def setSize(self, rows, cols): self.rows = rows self.cols = cols def putenv(self, name, value): sps.putenv(self.progname, self.shm_id_env, name, str(value)) def setChanDimList(self, chandimlist): self.chandimlist = chandimlist def _startRecordList(self, recordlist): if not self.isInitialized(): return arraylist = sps.getarraylist(self.progname) if self.shm_id in arraylist: shm = sps.attach(self.progname, self.shm_id) else: sps.create(self.progname, self.shm_id, self.rows, self.cols, sps.DOUBLE) if self.shm_id_env in arraylist: shm_env = sps.attach(self.progname, self.shm_id_env ) else: sps.create(self.progname, self.shm_id_env, self.maxenv, self.envlen, sps.STRING) print "Starting new SHM recording" self.putenv( 'title', recordlist.getEnvironValue('title') ) for env,val in recordlist.getEnviron().items(): if env != 'title' and env != 'labels': self.putenv( env , val) self.nopts = 0 self.putenv('started', time.ctime(recordlist.getEnvironValue('starttime'))) self.putenv('ended', '') self.putenv('axistitles', ' '.join(recordlist.getEnvironValue('labels'))) self.putenv('ylabel', 'Counts') self.putenv('nopts', self.nopts) self.putenv('xbeg',100) self.putenv('xend',200) self.putenv('aborted',0) self.putenv('command','done') self.putenv('fitresult','0') self.labels = recordlist.getEnvironValue('labels') def _writeRecord(self, record): # uhmm. only numeric values can be written if not self.isInitialized(): return vals = [] dim_list = [] for colname in self.labels: dim_list.append(0) val = record.data.get(colname) if (not val is None) and (type(val) in [int,float,long]): vals.append(val) myj = 0 for val2 in record.data: tmp = val2+'_value' #esto me da el nombre del canal for dim in self.chandimlist: if tmp == dim: dim_list[myj] = self.chandimlist[dim] myj = myj+1 myj = 0 for val2 in record.data.values(): valsmca = [] if type(val2) in [list]: if dim_list[myj] == 1: for i in range(0,len(val2)): valsmca.append(val2[i]) tmp_name = self.mnt_grp + "_1D" if self.shm_id == tmp_name: valsmca = numpy.array( valsmca ) sps.putdatarow( self.progname, self.shm_id, record.recordno, valsmca ) myj = myj+1 vals = numpy.array( vals ) tmp_name = self.mnt_grp+"_0D" if self.shm_id == tmp_name: sps.putdatarow( self.progname, self.shm_id, record.recordno, vals ) self.nopts +=1 self.putenv('nopts', self.nopts) self.putenv('peak', 111) self.putenv('peakpos', 34) self.putenv('fwhm', 12.3) self.putenv('fwhmpos', 45) self.putenv('com', 23) def _endRecordList(self, recordlist): if not self.isInitialized(): return self.putenv('ended', time.ctime( recordlist.getEnvironValue('endtime'))) def SharedMemoryRecorder(type, **pars): global SPS_AVAILABLE if type == 'sps' and SPS_AVAILABLE: klass = SPSRecorder else: return return klass(**pars) sardana-1.2.0/src/sardana/macroserver/scan/recorder/storage.py0000644000234100017500000014221312174204307026032 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan data output recorder module""" __all__ = ["BaseFileRecorder", "FileRecorder"] __docformat__ = 'restructuredtext' import os import time import itertools import re import numpy from datarecorder import DataRecorder, DataFormats, SaveModes from taurus.core.tango.sardana import PlotType from sardana.macroserver.macro import Type import PyTango class BaseFileRecorder(DataRecorder): def __init__(self, **pars): DataRecorder.__init__(self, **pars) self.filename = None self.fd = None def getFileName(self): return self.filename def getFileObj(self): return self.fd def getFormat(self): return '' class FIO_FileRecorder(BaseFileRecorder): """ Saves data to a file """ formats = { DataFormats.fio : '.fio' } def __init__(self, filename=None, macro=None, **pars): BaseFileRecorder.__init__(self) self.base_filename = filename if macro: self.macro = macro self.db = PyTango.Database() def setFileName(self, filename): if self.fd != None: self.fd.close() dirname = os.path.dirname(filename) if not os.path.isdir(dirname): try: os.makedirs(dirname) except: self.filename = None return self.currentlist = None # # construct the filename, e.g. : /dir/subdir/etcdir/prefix_00123.fio # tpl = filename.rpartition('.') serial = self.recordlist.getEnvironValue('serialno') self.filename = "%s_%05d.%s" % (tpl[0], serial, tpl[2]) # # in case we have MCAs, prepare the dir name # self.mcaDirName = "%s_%05d" % (tpl[0], serial) def getFormat(self): return DataFormats.whatis(DataFormats.fio) def _startRecordList(self, recordlist): if self.base_filename is None: return self.setFileName(self.base_filename) envRec = recordlist.getEnviron() self.sampleTime = envRec['estimatedtime']/(envRec['total_scan_intervals'] + 1) #datetime object start_time = envRec['starttime'] self.motorNames = envRec[ 'ref_moveables'] self.mcaNames = [] self.ctNames = [] for e in envRec['datadesc']: if len( e.shape) == 1: self.mcaNames.append( e.name) else: self.ctNames.append( e.name) # # we need the aliases for the column description # self.mcaAliases = [] for mca in self.mcaNames: lst = mca.split("/") self.mcaAliases.append( self.db.get_alias( "/".join( lst[1:]))) # self.names = [ e.name for e in envRec['datadesc'] ] self.fd = open( self.filename,'w') # # write the comment section of the header # self.fd.write("!\n! Comments\n!\n%%c\n %s\nuser %s Acquisition started at %s\n" % (envRec['title'], envRec['user'], start_time.ctime())) self.fd.flush() # # write the parameter section, including the motor positions, if needed # self.fd.write("!\n! Parameter\n!\n%p\n") self.fd.flush() env = self.macro.getAllEnv() if env.has_key( 'FlagFioWriteMotorPositions') and env['FlagFioWriteMotorPositions'] == True: all_motors = self.macro.findObjs('.*', type_class=Type.Motor) all_motors.sort() for mot in all_motors: pos = mot.getPosition() if pos is None: record = "%s = nan\n" % (mot) else: record = "%s = %g\n" % (mot, mot.getPosition()) self.fd.write( record) self.fd.flush() # # write the data section starting with the description of the columns # self.fd.write("!\n! Data\n!\n%d\n") self.fd.flush() i = 1 for col in envRec[ 'datadesc']: if col.name == 'point_nb': continue if col.name == 'timestamp': continue dType = 'FLOAT' if col.dtype == 'float64': dType = 'DOUBLE' outLine = " Col %d %s %s\n" % ( i, col.label, dType) self.fd.write( outLine) i += 1 # +++ # 11.9.2012 timestamp to the end # outLine = " Col %d %s %s\n" % ( i, 'timestamp', 'DOUBLE') self.fd.write( outLine) # +++ self.fd.flush() def _writeRecord(self, record): if self.filename is None: return nan, ctNames, fd = float('nan'), self.ctNames, self.fd outstr = '' for c in ctNames: outstr += ' ' + str(record.data.get(c, nan)) # +++ # 11.9.2012 timestamp to the end # outstr += ' ' + str(record.data.get('timestamp', nan)) # +++ outstr += '\n' fd.write( outstr ) fd.flush() if len( self.mcaNames) > 0: self._writeMcaFile( record) def _endRecordList(self, recordlist): if self.filename is None: return envRec = recordlist.getEnviron() end_time = envRec['endtime'].ctime() self.fd.write("! Acquisition ended at %s\n" % end_time) self.fd.flush() self.fd.close() def _writeMcaFile( self, record): if self.mcaDirName is None: return if not os.path.isdir( self.mcaDirName): try: os.makedirs( self.mcaDirName) except: self.mcaDirName = None return currDir = os.getenv( 'PWD') os.chdir( self.mcaDirName) serial = self.recordlist.getEnvironValue('serialno') if type(self.recordlist.getEnvironValue('ScanFile')).__name__ == 'list': scanFile = self.recordlist.getEnvironValue('ScanFile')[0] else: scanFile = self.recordlist.getEnvironValue('ScanFile') mcaFileName = "%s_%05d_mca_s%d.fio" % (scanFile.split('.')[0], serial, record.data['point_nb'] + 1) fd = open( mcaFileName,'w') fd.write("!\n! Comments\n!\n%%c\n Position %g, Index %d \n" % ( record.data[ self.motorNames[0]], record.data[ 'point_nb'])) fd.write("!\n! Parameter \n%%p\n Sample_time = %g \n" % ( self.sampleTime)) self.fd.flush() col = 1 fd.write("!\n! Data \n%d \n") for mca in self.mcaAliases: fd.write(" Col %d %s FLOAT \n" % (col, mca)) col = col + 1 if not record.data[ self.mcaNames[0]] is None: #print "+++storage.py, recordno", record.recordno #print "+++storage.py, record.data", record.data #print "+++storage.py, len %d, %s" % (len( record.data[ self.mcaNames[0]]), self.mcaNames[0]) # # the MCA arrays me be of different size. the short ones are extended by zeros. # lMax = len( record.data[ self.mcaNames[0]]) for mca in self.mcaNames: if len(record.data[ mca]) > lMax: lMax = len(record.data[ mca]) for i in range( 0, lMax): line = "" for mca in self.mcaNames: if i > (len(record.data[mca]) - 1): line = line + " 0" else: line = line + " " + str( record.data[ mca][i]) line = line + "\n" fd.write(line) fd.close() else: #print "+++storage.py, recordno", record.recordno, "data None" pass os.chdir( currDir) class SPEC_FileRecorder(BaseFileRecorder): """ Saves data to a file """ formats = { DataFormats.Spec : '.spec' } def __init__(self, filename=None, macro=None, **pars): BaseFileRecorder.__init__(self) if filename: self.setFileName(filename) def setFileName(self, filename): if self.fd != None: self.fd.close() dirname = os.path.dirname(filename) if not os.path.isdir(dirname): try: os.makedirs(dirname) except: self.filename = None return self.filename = filename self.currentlist = None def getFormat(self): return DataFormats.whatis(DataFormats.Spec) def _startRecordList(self, recordlist): if self.filename is None: return env = recordlist.getEnviron() #datetime object start_time = env['starttime'] epoch = time.mktime(start_time.timetuple()) serialno = env['serialno'] #store names for performance reason labels = [] names = [] for e in env['datadesc']: dims = len(e.shape) if not dims or (dims==1 and e.shape[0] == 1): sanitizedlabel = "".join(x for x in e.label.replace(' ','_') if x.isalnum() or x=='_') #substitute whitespaces by underscores and remove other non-alphanumeric characters labels.append(sanitizedlabel) names.append(e.name) self.names = names data = { 'serialno': serialno, 'title': env['title'], 'user': env['user'], 'epoch': epoch, 'starttime': start_time.ctime(), 'nocols': len(names), 'labels': ' '.join(labels) } self.fd = open(self.filename,'a') self.fd.write(""" #S %(serialno)s %(title)s #U %(user)s #D %(epoch)s #C Acquisition started at %(starttime)s #N %(nocols)s #L %(labels)s """ % data ) self.fd.flush() def _writeRecord(self, record): if self.filename is None: return nan, names, fd = float('nan'), self.names, self.fd d = [] for c in names: data = record.data.get(c) if data is None: data = nan d.append(str(data)) outstr = ' '.join(d) outstr += '\n' fd.write( outstr ) fd.flush() def _endRecordList(self, recordlist): if self.filename is None: return env = recordlist.getEnviron() end_time = env['endtime'].ctime() self.fd.write("#C Acquisition ended at %s\n" % end_time) self.fd.flush() self.fd.close() def _addCustomData(self, value, name, **kwargs): ''' The custom data will be added as a comment line in the form:: #C name : value ..note:: non-scalar values (or name/values containing end-of-line) will not be written ''' if self.filename is None: self.info('Custom data "%s" will not be stored in SPEC file. Reason: uninitialized file',name) return if numpy.rank(value)>0: #ignore non-scalars self.info('Custom data "%s" will not be stored in SPEC file. Reason: value is non-scalar',name) return v = str(value) if '\n' in v or '\n' in name: #ignore if name or the string representation of the value contains end-of-line self.info('Custom data "%s" will not be stored in SPEC file. Reason: unsupported format',name) return fileWasClosed = self.fd is None or self.fd.closed if fileWasClosed: try: self.fd = open(self.filename,'a') except: self.info('Custom data "%s" will not be stored in SPEC file. Reason: cannot open file',name) return self.fd.write( '#C %s : %s\n'%(name,v) ) self.fd.flush() if fileWasClosed: self.fd.close() #leave the file descriptor as found class BaseNEXUS_FileRecorder(BaseFileRecorder): """Base class for NeXus file recorders""" formats = { DataFormats.w5 : '.h5', DataFormats.w4 : '.h4', DataFormats.wx : '.xml' } supported_dtypes = ('float32','float64','int8', 'int16','int32','int64','uint8', 'uint16','uint32','uint64') #note that 'char' is not supported yet! _dataCompressionRank = -1 def __init__(self, filename=None, macro=None, overwrite=False, **pars): BaseFileRecorder.__init__(self, **pars) try: import nxs #check if Nexus data format is supported by this system self.nxs = nxs except ImportError: raise Exception("NeXus is not available") self.macro = macro self.overwrite = overwrite if filename: self.setFileName(filename) self.instrDict = {} self.entryname = 'entry' def setFileName(self, filename): if self.fd is not None: self.fd.close() self.filename = filename #obtain preferred nexus file mode for writing from the filename extension (defaults to hdf5) extension=os.path.splitext(filename)[1] inv_formats = dict(itertools.izip(self.formats.itervalues(), self.formats.iterkeys())) self.nxfilemode = inv_formats.get(extension.lower(), DataFormats.w5) self.currentlist = None def getFormat(self): return DataFormats.whatis(self.nxfilemode) def sanitizeName(self, name): '''It returns a version of the given name that can be used as a python variable (and conforms to NeXus best-practices for dataset names)''' #make sure the name does not start with a digit if name[0].isdigit(): name="_%s"%name #substitute whitespaces by underscores and remove other non-alphanumeric characters return "".join(x for x in name.replace(' ','_') if x.isalnum() or x=='_') def _nxln(self, src, dst, name=None): '''convenience function to create NX links with just one call. On successful return, dst will be open. :param src: (str or NXgroup or NXfield) source group or dataset (or its path) :param dst: (str or NXgroup) the group that will hold the link (or its path) :param name: (str) name for the link. If not given, the name of the source is used .. note:: `groupname:nxclass` notation can be used for both paths for better performance ''' fd = getattr(self, 'fd') if fd is None: fd = getattr(src,'nxfile', getattr(dst,'nxfile')) if fd is None: raise NeXusError('Cannot get a file handle') if isinstance(src, self.nxs.NXobject): src = src.nxpath if isinstance(dst, self.nxs.NXobject): dst = dst.nxpath fd.openpath(src) try: nid=fd.getdataID() except self.nxs.NeXusError: nid=fd.getgroupID() fd.openpath(dst) if name is None: fd.makelink(nid) else: fd.makenamedlink(name,nid) #=========================================================================== # Unimplemented methods that must be implemented in derived classes #=========================================================================== def _startRecordList(self, recordlist): raise NotImplementedError('_startRecordList must be implemented in BaseNEXUS_FileRecorder derived classes') def _writeRecord(self, record): raise NotImplementedError('_writeRecord must be implemented in BaseNEXUS_FileRecorder derived classes') def _endRecordList(self, recordlist): raise NotImplementedError('_endRecordList must be implemented in BaseNEXUS_FileRecorder derived classes') class BaseNAPI_FileRecorder(BaseNEXUS_FileRecorder): """Base class for NeXus file recorders (NAPI-based)""" #=========================================================================== # Convenience methods to make NAPI less tedious #=========================================================================== _nxentryInPath = re.compile(r'/[^/:]+:NXentry') def _makedata(self, name, dtype=None, shape=None, mode='lzw', chunks=None, comprank=None): ''' combines :meth:`nxs.NeXus.makedata` and :meth:`nxs.NeXus.compmakedata` by selecting between using compression or not based on the comprank parameter and the rank of the data. Compression will be used only if the shape of the data is given and its length is larger than comprank. If comprank is not passed (or None is passed) the default dataCompressionRank will be used ''' if comprank is None: comprank = self._dataCompressionRank if shape is None or comprank<0 or (len(shape) < comprank): return self.fd.makedata(name, dtype=dtype, shape=shape) else: try: self.fd.compmakedata(name, dtype=dtype, shape=shape, mode=mode, chunks=chunks) except ValueError: #workaround for bug in nxs<4.3 (compmakedatafails if chunks is not explicitly passed) chunks = [1]*len(shape) chunks[-1] = shape[-1] self.fd.compmakedata(name, dtype=dtype, shape=shape, mode=mode, chunks=chunks) def _writeData(self, name, data, dtype, shape=None, chunks=None, attrs=None): ''' convenience method that creates datasets (calling self._makedata), opens it (napi.opendata) and writes the data (napi.putdata). It also writes attributes (napi.putattr) if passed in a dictionary and it returns the data Id (useful for linking). The dataset is left closed. ''' if shape is None: if dtype=='char': shape = [len(data)] chunks = chunks or list(shape) #for 'char', write the whole block in one chunk else: shape = getattr(data,'shape',[1]) self._makedata(name, dtype=dtype, shape=shape, chunks=chunks) self.fd.opendata(name) self.fd.putdata(data) if attrs is not None: for k,v in attrs.items(): self.fd.putattr(k,v) nid = self.fd.getdataID() self.fd.closedata() return nid def _newentryname(self, prefix='entry', suffix='', offset=1): '''Returns a str representing the name for a new entry. The name is formed by the prefix and an incremental numeric suffix. The offset indicates the start of the numeric suffix search''' i=offset while True: entry="%s%i"%(prefix,i) if suffix: entry += " - " + suffix try: self.fd.opengroup(entry,'NXentry') self.fd.closegroup() i+=1 except ValueError: #no such group name exists return entry def _nxln(self, src, dst): '''convenience function to create NX links with just one call. On successful return, dst will be open. :param src: (str) the nxpath to the source group or dataset :param dst: (str) the nxpath to the group that will hold the link .. note:: `groupname:nxclass` notation can be used for both paths for better performance ''' self.fd.openpath(src) try: nid=self.fd.getdataID() except self.nxs.NeXusError: nid=self.fd.getgroupID() self.fd.openpath(dst) self.fd.makelink(nid) def _createBranch(self, path): """ Navigates the nexus tree starting in / and finishing in path. If path does not start with `/:NXentry`, the current entry is prepended to it. This method creates the groups if they do not exist. If the path is given using `name:nxclass` notation, the given nxclass is used. Otherwise, the class name is obtained from self.instrDict values (and if not found, it defaults to NXcollection). If successful, path is left open """ m = self._nxentryInPath.match(path) if m is None: self._createBranch("/%s:NXentry"%self.entryname) #if at all, it will recurse just once # self.fd.openpath("/%s:NXentry" % self.entryname) else: self.fd.openpath("/") relpath="" for g in path.split('/'): if len(g) == 0: continue relpath = relpath + "/"+ g if ':' in g: g,group_type = g.split(':') else: try: group_type = self.instrDict[relpath].klass except: group_type = 'NXcollection' try: self.fd.opengroup(g, group_type) except: self.fd.makegroup(g, group_type) self.fd.opengroup(g, group_type) class NXscan_FileRecorder(BaseNAPI_FileRecorder): """saves data to a nexus file that follows the NXscan application definition """ def __init__(self, filename=None, macro=None, overwrite=False, **pars): BaseNAPI_FileRecorder.__init__(self, filename=filename, macro=macro, overwrite=overwrite, **pars) def _startRecordList(self, recordlist): nxs = self.nxs nxfilemode = self.getFormat() if self.filename is None: return self.currentlist = recordlist env = self.currentlist.getEnviron() serialno = env["serialno"] self._dataCompressionRank = env.get("DataCompressionRank", self._dataCompressionRank) if not self.overwrite and os.path.exists(self.filename): nxfilemode='rw' self.fd = nxs.open(self.filename, nxfilemode) self.entryname = "entry%d" % serialno try: self.fd.makegroup(self.entryname,"NXentry") except NeXusError: entrynames = self.fd.getentries().keys() #=================================================================== ##Warn and abort if self.entryname in entrynames: raise RuntimeError(('"%s" already exists in %s. To prevent data corruption the macro will be aborted.\n'%(self.entryname, self.filename)+ 'This is likely caused by a wrong ScanID\n'+ 'Possible workarounds:\n'+ ' * first, try re-running this macro (the ScanID may be automatically corrected)\n' ' * if not, try changing ScanID with senv, or...\n'+ ' * change the file name (%s will be in both files containing different data)\n'%self.entryname+ '\nPlease report this problem.')) else: raise #=================================================================== #=================================================================== ## Warn and continue writing to another entry #if self.entryname in entrynames: # i = 2 # newname = "%s_%i"%(self.entryname,i) # while(newname in entrynames): # i +=1 # newname = "%s_%i"%(self.entryname,i) # self.warning('"%s" already exists. Using "%s" instead. This may indicate a bug in %s',self.entryname, newname, self.macro.name) # self.macro.warning('"%s" already exists. Using "%s" instead. \nThis may indicate a bug in %s. Please report it.',self.entryname, newname, self.macro.name) # self.entryname = newname # self.fd.makegroup(self.entryname,"NXentry") #=================================================================== self.fd.opengroup(self.entryname,"NXentry") #adapt the datadesc to the NeXus requirements self.datadesc = [] for dd in env['datadesc']: dd = dd.clone() dd.label = self.sanitizeName(dd.label) if dd.dtype == 'bool': dd.dtype = 'int8' self.debug('%s will be stored with type=%s',dd.name,dd.dtype) if dd.dtype in self.supported_dtypes: self.datadesc.append(dd) else: self.warning('%s will not be stored. Reason: type %s not supported',dd.name,dd.dtype) #make a dictionary out of env['instrumentlist'] (use fullnames -paths- as keys) self.instrDict={} for inst in env.get('instrumentlist',[]): self.instrDict[inst.getFullName()]=inst if self.instrDict is {}: self.warning("missing information on NEXUS structure. Nexus Tree won't be created") self.debug("starting new recording %d on file %s", env['serialno'], self.filename) #populate the entry with some data self._writeData('definition', 'NXscan', 'char') #this is the Application Definition for NeXus Generic Scans import sardana.release program_name = "%s (%s)"%(sardana.release.name, self.__class__.__name__) self._writeData('program_name', program_name, 'char', attrs={'version':sardana.release.version}) self._writeData("start_time",env['starttime'].isoformat(),'char') #note: the type should be NX_DATE_TIME, but the nxs python api does not recognize it self.fd.putattr("epoch",time.mktime(env['starttime'].timetuple())) self._writeData("title",env['title'],'char') self._writeData("entry_identifier",str(env['serialno']),'char') self.fd.makegroup("user","NXuser") #user data goes in a separate group following NX convention... self.fd.opengroup("user","NXuser") self._writeData("name",env['user'],'char') self.fd.closegroup() #prepare the "measurement" group self._createBranch("measurement:NXcollection") if self.savemode==SaveModes.Record: #create extensible datasets for dd in self.datadesc: self._makedata(dd.label,dd.dtype, [nxs.UNLIMITED]+list(dd.shape), chunks=[1]+list(dd.shape)) #the first dimension is extensible if hasattr(dd,'data_units'): self.fd.opendata(dd.label) self.fd.putattr('units', dd.data_units) self.fd.closedata() else: #leave the creation of the datasets to _writeRecordList (when we actually know the length of the data to write) pass self._createPreScanSnapshot(env) self.fd.flush() def _createPreScanSnapshot(self, env): #write the pre-scan snapshot in the "measurement:NXcollection/pre_scan_snapshot:NXcollection" group self.preScanSnapShot = env.get('preScanSnapShot',[]) self._createBranch('measurement:NXcollection/pre_scan_snapshot:NXcollection') links = {} for dd in self.preScanSnapShot: #desc is a ColumnDesc object label = self.sanitizeName(dd.label) dtype = dd.dtype pre_scan_value = dd.pre_scan_value if dd.dtype == 'bool': dtype = 'int8' pre_scan_value = numpy.int8(dd.pre_scan_value) self.debug('Pre-scan snapshot of %s will be stored with type=%s',dd.name, dtype) if dtype in self.supported_dtypes: nid = self._writeData(label, pre_scan_value, dtype, shape=dd.shape or (1,)) #@todo: fallback shape is hardcoded! links[label] = nid else: self.warning('Pre-scan snapshot of %s will not be stored. Reason: type %s not supported',dd.name, dtype) self.fd.closegroup() #we are back at the measurement group measurement_entries = self.fd.getentries() for label,nid in links.items(): if label not in measurement_entries: self.fd.makelink(nid) def _writeRecord(self, record): if self.filename is None: return # most used variables in the loop fd, debug, warning = self.fd, self.debug, self.warning nparray, npshape = numpy.array, numpy.shape rec_data, rec_nb = record.data, record.recordno for dd in self.datadesc: if record.data.has_key( dd.name ): data = rec_data[dd.name] fd.opendata(dd.label) if data is None: data = numpy.zeros(dd.shape, dtype=dd.dtype) if not hasattr(data, 'shape'): data = nparray([data], dtype=dd.dtype) elif dd.dtype != data.dtype.name: debug('%s casted to %s (was %s)', dd.label, dd.dtype, data.dtype.name) data = data.astype(dd.dtype) slab_offset = [rec_nb]+[0]*len(dd.shape) shape = [1]+list(npshape(data)) try: fd.putslab(data, slab_offset, shape) except: warning("Could not write <%s> with shape %s", data, shape) raise ###Note: the following 3 lines of code were substituted by the one above. ### (now we trust the datadesc info instead of asking the nxs file each time) #shape,dtype=self.fd.getinfo() #shape[0]=1 #the shape of the record is of just 1 slab in the extensible dimension (first dim) #self.fd.putslab(record.data[lbl],[record.recordno]+[0]*(len(shape)-1),shape) fd.closedata() else: debug("missing data for label '%s'", dd.label) fd.flush() def _endRecordList(self, recordlist): if self.filename is None: return self._populateInstrumentInfo() self._createNXData() env=self.currentlist.getEnviron() self.fd.openpath("/%s:NXentry" % self.entryname) self._writeData("end_time",env['endtime'].isoformat(),'char') self.fd.flush() self.debug("Finishing recording %d on file %s:", env['serialno'], self.filename) #self.fd.show('.') #prints nexus file summary on stdout (only the current entry) self.fd.close() self.currentlist = None def writeRecordList(self, recordlist): """Called when in BLOCK writing mode""" self._startRecordList( recordlist ) for dd in self.datadesc: self._makedata(dd.label, dd.dtype, [len(recordlist.records)]+list(dd.shape), chunks=[1]+list(dd.shape)) self.fd.opendata(dd.label) try: #try creating a single block to write it at once block=numpy.array([r.data[dd.label] for r in recordlist.records],dtype=dd.dtype) #if dd.dtype !='char': block=numpy.array(block,dtype=dtype) #char not supported anyway self.fd.putdata(block) except KeyError: #if not all the records contain this field, we cannot write it as a block.. so do it record by record (but only this field!) for record in recordlist.records: if record.data.has_key( dd.label ): self.fd.putslab(record.data[dd.label],[record.recordno]+[0]*len(dd.shape),[1]+list(dd.shape)) else: self.debug("missing data for label '%s' in record %i", dd.label, record.recordno) self.fd.closedata() self._endRecordList( recordlist ) def _populateInstrumentInfo(self): measurementpath = "/%s:NXentry/measurement:NXcollection"%self.entryname #create a link for each for dd in self.datadesc: if getattr(dd,'instrument', None): #we don't link if it is None or it is empty try: datapath="%s/%s"%(measurementpath,dd.label) self.fd.openpath(datapath) nid=self.fd.getdataID() self._createBranch(dd.instrument) self.fd.makelink(nid) except Exception,e: self.warning("Could not create link to '%s' in '%s'. Reason: %s",datapath, dd.instrument, repr(e)) for dd in self.preScanSnapShot: if getattr(dd,'instrument', None): try: label = self.sanitizeName(dd.label) datapath="%s/pre_scan_snapshot:NXcollection/%s"%(measurementpath,label) self.fd.openpath(datapath) nid=self.fd.getdataID() self._createBranch(dd.instrument) self.fd.makelink(nid) except Exception,e: self.warning("Could not create link to '%s' in '%s'. Reason: %s",datapath, dd.instrument, repr(e)) def _createNXData(self): '''Creates groups of type NXdata by making links to the corresponding datasets ''' #classify by type of plot: plots1d = {} plots1d_names = {} i = 1 for dd in self.datadesc: ptype = getattr(dd, 'plot_type', PlotType.No) if ptype == PlotType.No: continue elif ptype == PlotType.Spectrum: axes = ":".join(dd.plot_axes) #converting the list into a colon-separated string if axes in plots1d: plots1d[axes].append(dd) else: plots1d[axes] = [dd] plots1d_names[axes] = 'plot_%i'%i #Note that datatesc ordering determines group name indexing i+=1 else: continue #@todo: implement support for images and other #write the 1D NXdata group for axes,v in plots1d.items(): self.fd.openpath("/%s:NXentry"%(self.entryname)) groupname = plots1d_names[axes] self.fd.makegroup(groupname,'NXdata') #write the signals for i,dd in enumerate(v): src = "/%s:NXentry/measurement:NXcollection/%s"%(self.entryname,dd.label) dst = "/%s:NXentry/%s:NXdata"%(self.entryname,groupname) self._nxln(src, dst) self.fd.opendata(dd.label) self.fd.putattr('signal',min(i+1,2)) self.fd.putattr('axes',axes) self.fd.putattr('interpretation','spectrum') #write the axes for axis in axes.split(':'): src = "/%s:NXentry/measurement:NXcollection/%s"%(self.entryname,axis) dst = "/%s:NXentry/%s:NXdata"%(self.entryname,groupname) try: self._nxln(src, dst) except: self.warning("cannot create link for '%s'. Skipping",axis) def _addCustomData(self, value, name, nxpath=None, dtype=None, **kwargs): ''' apart from value and name, this recorder can use the following optional parameters: :param nxpath: (str) a nexus path (optionally using name:nxclass notation for the group names). See the rules for automatic nxclass resolution used by :meth:`NXscan_FileRecorder._createBranch`. If None given, it defaults to nxpath='custom_data:NXcollection' :param dtype: name of data type (it is inferred from value if not given) ''' if nxpath is None: nxpath='custom_data:NXcollection' if dtype is None: if numpy.isscalar(value): dtype = numpy.dtype(type(value)).name if numpy.issubdtype(dtype,str): dtype='char' if dtype == 'bool': value, dtype = int(value), 'int8' else: value = numpy.array(value) dtype = value.dtype.name if dtype not in self.supported_dtypes and dtype != 'char': self.warning("cannot write '%s'. Reason: unsupported data type",name) return #open the file if necessary fileWasClosed = self.fd is None or not self.fd.isopen if fileWasClosed: if not self.overwrite and os.path.exists(self.filename): nxfilemode='rw' import nxs self.fd = nxs.open(self.filename, nxfilemode) #write the data self._createBranch(nxpath) try: self._writeData(name, value, dtype) except ValueError, e: msg = "Error writing %s. Reason: %s"%(name, str(e)) self.warning(msg) self.macro.warning(msg) #leave the file as it was if fileWasClosed: self.fd.close() class NXxas_FileRecorder(BaseNEXUS_FileRecorder): """saves data to a nexus file that follows the NXsas application definition """ def __init__(self, filename=None, macro=None, overwrite=False, **pars): BaseNEXUS_FileRecorder.__init__(self, filename=filename, macro=macro, overwrite=overwrite, **pars) def _startRecordList(self, recordlist): nxs = self.nxs if self.filename is None: return #get the recordlist environment self.currentlist = recordlist env = self.currentlist.getEnviron() #adapt the datadesc to the NeXus requirements self.datadesc = [] for dd in env['datadesc']: dd = dd.clone() dd.label = self.sanitizeName(dd.label) if dd.dtype == 'bool': dd.dtype = 'int8' self.debug('%s will be stored with type=%s',dd.name,dd.dtype) if dd.dtype in self.supported_dtypes: self.datadesc.append(dd) else: self.warning('%s will not be stored. Reason: type %s not supported',dd.name,dd.dtype) serialno = env["serialno"] nxfilemode = self.getFormat() if not self.overwrite and os.path.exists(self.filename): nxfilemode='rw' self.debug("starting new recording %d on file %s", serialno, self.filename) #create an nxentry and write it to file self.nxentry = nxs.NXentry(name= "entry%d" % serialno) self.nxentry.save(self.filename, format=nxfilemode) #add fields to nxentry import sardana.release program_name = "%s (%s)"%(sardana.release.name, self.__class__.__name__) self.nxentry.insert(nxs.NXfield(name='start_time', value=env['starttime'].isoformat())) self.nxentry.insert(nxs.NXfield(name='title', value=env['title'])) self.nxentry.insert(nxs.NXfield(name='definition', value='NXxas')) self.nxentry.insert(nxs.NXfield(name='epoch', value=time.mktime(env['starttime'].timetuple()))) self.nxentry.insert(nxs.NXfield(name='program_name', value=program_name, attrs={'version':sardana.release.version})) self.nxentry.insert(nxs.NXfield(name='entry_identifier', value=env['serialno'])) #add the "measurement" group (a NXcollection containing all counters from the mntgrp for convenience) measurement = nxs.NXcollection(name='measurement') self.ddfieldsDict = {} for dd in self.datadesc: field = NXfield_comp(name=dd.label, dtype=dd.dtype, shape=[nxs.UNLIMITED]+list(dd.shape), nxslab_dims=[1]+list(dd.shape) ) if hasattr(dd,'data_units'): field.attrs['units'] = dd.data_units measurement.insert(field) #create a dict of fields in the datadesc for easier access later on self.ddfieldsDict[dd.label] = field self.nxentry.insert(measurement) #user group nxuser = nxs.NXuser() self.nxentry.insert(nxuser) nxuser['name'] = env['user'] #sample group nxsample = nxs.NXsample() self.nxentry.insert(nxsample) nxsample['name'] = env['SampleInfo'].get('name','Unknown') #monitor group scan_acq_time = env.get('integ_time') scan_monitor_mode = scan_acq_time>1 and 'timer' or 'monitor' nxmonitor = nxs.NXmonitor(mode=scan_monitor_mode, preset=scan_acq_time) self.nxentry.insert(nxmonitor) monitor_data = self.ddfieldsDict[self.sanitizeName(env['monitor'])] #to be linked later on #instrument group nxinstrument = nxs.NXinstrument() self.nxentry.insert(nxinstrument) #monochromator group nxmonochromator = nxs.NXmonochromator() nxinstrument.insert(nxmonochromator) energy_data = self.ddfieldsDict[self.sanitizeName(env['monochromator'])] #to be linked later on #incoming_beam group nxincoming_beam = nxs.NXdetector(name='incoming_beam') nxinstrument.insert(nxincoming_beam) incbeam_data = self.ddfieldsDict[self.sanitizeName(env['incbeam'])] #to be linked later on #absorbed_beam group nxabsorbed_beam = nxs.NXdetector(name='absorbed_beam') nxinstrument.insert(nxabsorbed_beam) absbeam_data = self.ddfieldsDict[self.sanitizeName(env['absbeam'])] #to be linked later on absbeam_data.attrs['signal'] = '1' absbeam_data.attrs['axes'] = 'energy' #source group nxsource = nxs.NXsource() nxinstrument.insert(nxsource) nxinstrument['source']['name'] = env.get('SourceInfo',{}).get('name','Unknown') nxinstrument['source']['type'] = env.get('SourceInfo',{}).get('type','Unknown') nxinstrument['source']['probe'] = env.get('SourceInfo',{}).get('x-ray','Unknown') #data group nxdata = nxs.NXdata() self.nxentry.insert(nxdata) #@todo create the PreScanSnapshot #self._createPreScanSnapshot(env) #write everything to file self.nxentry.write() #@todo: do this with the PyTree api instead(how to do named links with the PyTree API????) self._nxln(monitor_data, nxmonitor, name='data') self._nxln(incbeam_data, nxincoming_beam, name='data') self._nxln(absbeam_data, nxabsorbed_beam, name='data') self._nxln(energy_data, nxmonochromator, name='energy') self._nxln(energy_data, nxdata, name='energy') self._nxln(absbeam_data, nxdata, name='absorbed_beam') self.nxentry.nxfile.flush() def _writeRecord(self, record): # most used variables in the loop fd, debug, warning = self.nxentry.nxfile, self.debug, self.warning nparray, npshape = numpy.array, numpy.shape rec_data, rec_nb = record.data, record.recordno for dd in self.datadesc: if record.data.has_key( dd.name ): data = rec_data[dd.name] field = self.ddfieldsDict[dd.label] if data is None: data = numpy.zeros(dd.shape, dtype=dd.dtype) if not hasattr(data, 'shape'): data = nparray([data], dtype=dd.dtype) elif dd.dtype != data.dtype.name: debug('%s casted to %s (was %s)', dd.label, dd.dtype, data.dtype.name) data = data.astype(dd.dtype) slab_offset = [rec_nb]+[0]*len(dd.shape) shape = [1]+list(npshape(data)) try: field.put(data, slab_offset, shape) field.write() except: warning("Could not write <%s> with shape %s", data, shape) raise else: debug("missing data for label '%s'", dd.label) self.nxentry.nxfile.flush() def _endRecordList(self, recordlist): env=self.currentlist.getEnviron() self.nxentry.insert(nxs.NXfield(name='end_time', value=env['endtime'].isoformat())) #self._populateInstrumentInfo() #self._createNXData() self.nxentry.write() self.nxentry.nxfile.flush() self.debug("Finishing recording %d on file %s:", env['serialno'], self.filename) return #=============================================================================== # BEGIN: THIS BLOCK SHOULD BE REMOVED IF NEXUS ACCEPTS THE PATCH TO NXfield #=============================================================================== try: from nxs import NXfield #needs Nexus v>=4.3 from nxs import napi, NeXusError class NXfield_comp(NXfield): #NOTE: THE CONSTRUCTOR IS OPTIONAL. IF NOT IMPLEMENTED, WE CAN STILL USE THE nxslab_dims PROPERTY def __init__(self, value=None, name='field', dtype=None, shape=(), group=None, attrs={}, nxslab_dims=None, **attr): NXfield.__init__(self, value=value, name=name, dtype=dtype, shape=shape, group=group, attrs=attrs, **attr) self._slab_dims = nxslab_dims def write(self): """ Write the NXfield, including attributes, to the NeXus file. """ if self.nxfile: if self.nxfile.mode == napi.ACC_READ: raise NeXusError("NeXus file is readonly") if not self.infile: shape = self.shape if shape == (): shape = (1,) with self.nxgroup as path: if self.nxslab_dims is not None: #compress path.compmakedata(self.nxname, self.dtype, shape, 'lzw', self.nxslab_dims) else: # Don't use compression path.makedata(self.nxname, self.dtype, shape) self._infile = True if not self.saved: with self as path: path._writeattrs(self.attrs) value = self.nxdata if value is not None: path.putdata(value) self._saved = True else: raise IOError("Data is not attached to a file") def _getnxslabdims(self): try: return self._nxslab_dims except: slab_dims = None #even if slab_dims have not been set, check if the dataset is large shape = self.shape or (1,) if numpy.prod(shape) > 10000: slab_dims = numpy.ones(len(shape),'i') slab_dims[-1] = min(shape[-1], 100000) return slab_dims def _setnxslabdims(self, slab_dims): self._nxslab_dims = slab_dims nxslab_dims = property(_getnxslabdims,_setnxslabdims,doc="Slab (a.k.a. chunk) dimensions for compression") except: pass #NXxas_FileRecorder won't be usable #=============================================================================== # END: THE ABOVE BLOCK SHOULD BE REMOVED IF NEXUS ACCEPTS THE PATCH TO NXfield #=============================================================================== def FileRecorder(filename, macro, **pars): ext = os.path.splitext(filename)[1].lower() or '.spec' hintedklass = globals().get(getattr(macro,'hints',{}).get('FileRecorder',None)) if hintedklass is not None and issubclass(hintedklass, BaseFileRecorder): klass = hintedklass elif ext in NXscan_FileRecorder.formats.values(): klass = NXscan_FileRecorder elif ext in FIO_FileRecorder.formats.values(): klass = FIO_FileRecorder else: klass = SPEC_FileRecorder return klass(filename=filename, macro=macro, **pars) sardana-1.2.0/src/sardana/macroserver/scan/__init__.py0000644000234100017500000000216712174204307024323 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan module""" __docformat__ = 'restructuredtext' from scandata import * from gscan import *sardana-1.2.0/src/sardana/macroserver/scan/gscan.py0000644000234100017500000025475512174204307023673 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer generic scan""" __all__ = ["ScanSetupError", "ScanException", "ExtraData", "TangoExtraData", "GScan", "SScan", "CScan", "CSScan", "CTScan", "HScan"] __docformat__ = 'restructuredtext' import os import datetime import operator import time import threading import numpy as np import PyTango import taurus from taurus.core.util import USER_NAME, Logger from taurus.core.tango import FROM_TANGO_TO_STR_TYPE from taurus.core.tango.sardana.pool import Ready from sardana.util.tree import BranchNode, LeafNode, Tree from sardana.util.motion import Motor as VMotor from sardana.util.motion import MotionPath from sardana.macroserver.msexception import MacroServerException, UnknownEnv, \ InterruptException from sardana.macroserver.msparameter import Type from scandata import ColumnDesc, MoveableDesc, ScanFactory, ScanDataEnvironment from recorder import OutputRecorder, JsonRecorder, SharedMemoryRecorder, \ FileRecorder class ScanSetupError(Exception): pass class ScanException(MacroServerException): pass class ExtraData(object): def __init__(self, **kwargs): """Expected keywords are: - model (str, mandatory): represents data source (ex.: a/b/c/d) - label (str, mandatory): column label - name (str, optional): unique name (defaults to model) - shape (seq, optional): data shape - dtype (numpy.dtype, optional): data type - instrument (str, optional): full instrument name""" self._label = kwargs['label'] self._model = kwargs['model'] if not kwargs.has_key('dtype'): kwargs['dtype'] = self.getType() if not kwargs.has_key('shape'): kwargs['shape'] = self.getShape() if not kwargs.has_key('name'): kwargs['name'] = self._model self._column = ColumnDesc(**kwargs) def getLabel(self): return self._label def getName(self): return self._label def getColumnDesc(self): return self._column def getType(self): raise Exception("Must be implemented in subclass") def getShape(self): raise Exception("Must be implemented in subclass") def read(self): raise Exception("Must be implemented in subclass") class TangoExtraData(ExtraData): def __init__(self, **kwargs): self._attribute = None ExtraData.__init__(self, **kwargs) @property def attribute(self): if self._attribute is None: self._attribute = taurus.Attribute(self._model) return self._attribute def getType(self): t = self.attribute.getType() if t is None: raise Exception("Could not determine type for unknown attribute '%s'" % self._model) return FROM_TANGO_TO_STR_TYPE[t] def getShape(self): s = self.attribute.getShape() if s is None: raise Exception("Could not determine type for unknown attribute '%s'" % self._model) return s def read(self): try: return self.attribute.read(cache=False).value except InterruptException: raise except Exception: return None class GScan(Logger): """Generic Scan object. The idea is that the scan macros create an instance of this Generic Scan, supplying in the constructor a reference to the macro that created the scan, a generator function pointer, a list of moveable items, an extra environment and a sequence of constrains. If the referenced macro is hookable, 'pre-scan' and 'post-scan' hook hints will be used to execute callables before the start and after the end of the scan, respectively The generator must be a function yielding a dictionary with the following content (minimum) at each step of the scan: - 'positions' : In a step scan, the position where the moveables should go - 'integ_time' : In a step scan, a number representing the integration time for the step (in seconds) - 'integ_time' : In a continuous scan, the time between acquisitions - 'pre-move-hooks' : (optional) a sequence of callables to be called in strict order before starting to move. - 'post-move-hooks': (optional) a sequence of callables to be called in strict order after finishing the move. - 'pre-acq-hooks' : (optional) a sequence of callables to be called in strict order before starting to acquire. - 'post-acq-hooks' : (optional) a sequence of callables to be called in strict order after finishing acquisition but before recording the step. - 'post-step-hooks' : (optional) a sequence of callables to be called in strict order after finishing recording the step. - 'hooks' : (deprecated, use post-acq-hooks instead) - 'point_id' : a hashable identifing the scan point. - 'check_func' : (optional) a list of callable objects. callable(moveables, counters) - 'extravalues': (optional) a dictionary containing the values for each extra info field. The extra information fields must be described in extradesc (passed in the constructor of the Gscan) The moveables must be a sequence Motion or MoveableDesc objects. The environment is a dictionary of extra environment to be added specific to the macro in question. Each constrain must be a callable which must receive a two parameters: the current point and the next point. It should return True or False The extradesc optional argument consists of a list of ColumnDesc objects which describe the data fields that will be filled using step['extravalues'], where step is what the generator yields. The Generic Scan will create: - a ScanData - DataHandler with the following recorders: - OutputRecorder (depends on 'OutputCols' environment variable) - SharedMemoryRecorder (depends on 'SharedMemory' environment variable) - FileRecorder (depends on 'ScanDir' and 'ScanData' environment variables) - ScanDataEnvironment with the following contents: - 'serialno' : a integer identifier for the scan operation - 'user' : the user which started the scan - 'title' : the scan title (build from macro.getCommand) - 'datadesc' : a seq describing each column of data (labels, data format, data shape, etc) - 'estimatedtime' : a float representing an estimation for the duration of the scan (in seconds). Negative means the time estimation is known not to be accurate. Anyway, time estimation has 'at least' semantics. - 'total_scan_intervals' : total number of scan intervals. Negative means the estimation is known not to be accurate. In this case, estimation has 'at least' semantics. - '' : a datetime.datetime representing the start of the scan - 'instrumentlist' : a list of Instrument objects containing info about the physical setup of the motors, counters,... - given in the constructor (at the end of the scan, extra keys 'endtime' and 'deadtime' will be added representing the time at the end of the scan and the dead time) This object is passed to all recorders at the beginning and at the end of the scan (when startRecordList and endRecordList is called) At each step of the scan, for each Recorder, the writeRecord method will be called with a Record object as parameter. The Record.data member will be a dictionary containing: - 'point_nb' : the point number of the scan - for each column of the scan (motor or counter), a key with the corresponding column name will contain the value""" MAX_SCAN_HISTORY = 20 env = ('ActiveMntGrp', 'ExtraColumns' 'ScanDir', 'ScanFile', 'SharedMemory', 'OutputCols') def __init__(self, macro, generator=None, moveables=[], env={}, constraints=[], extrainfodesc=[]): self._macro = macro self._generator = generator self._extrainfodesc = extrainfodesc #nasty hack to make sure macro has access to gScan as soon as possible self._macro._gScan = self #TODO: CAUTION! this may be causing a circular reference! self._moveables, moveable_names = [], [] for moveable in moveables: if not isinstance(moveable, MoveableDesc): moveable = MoveableDesc(moveable=moveable) moveable_names.append(moveable.moveable.getName()) self._moveables.append(moveable) name = self.__class__.__name__ self.call__init__(Logger, name) # ---------------------------------------------------------------------- # Setup motion objects # ---------------------------------------------------------------------- self._motion = macro.getMotion(moveable_names) # ---------------------------------------------------------------------- # Find the measurement group # ---------------------------------------------------------------------- try: mnt_grp_name = macro.getEnv('ActiveMntGrp') except UnknownEnv: mnt_grps = macro.getObjs(".*", type_class=Type.MeasurementGroup) if len(mnt_grps) == 0: ScanSetupError('No Measurement Group defined') mnt_grp = mnt_grps[0] macro.info("ActiveMntGrp not defined. Using %s", mnt_grp) macro.setEnv('ActiveMntGrp', mnt_grp.getName()) else: if not isinstance(mnt_grp_name, (str, unicode)): t = type(mnt_grp_name).__name__ raise TypeError("ActiveMntGrp MUST be string. It is '%s'" % t) mnt_grp = macro.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) if mnt_grp is None: raise ScanSetupError("ActiveMntGrp has invalid value: '%s'" % mnt_grp_name) self._master = mnt_grp.getTimer() if self._master is None: raise ScanSetupError('%s has no timer defined' % mnt_grp.getName()) self._measurement_group = mnt_grp # ---------------------------------------------------------------------- # Setup extra columns # ---------------------------------------------------------------------- self._extra_columns = self._getExtraColumns() # ---------------------------------------------------------------------- # Setup data management # ---------------------------------------------------------------------- # Generate data handler data_handler = ScanFactory().getDataHandler() # The Scan data object data = ScanFactory().getScanData(data_handler) # The Output recorder (if any) output_recorder = self._getOutputRecorder() # The Output recorder (if any) json_recorder = self._getJsonRecorder() # The File recorders (if any) file_recorders = self._getFileRecorders() # The Shared memory recorder (if any) shm_recorder = self._getSharedMemoryRecorder(0) shm_recorder_1d = None if shm_recorder is not None: shm_recorder_1d = self._getSharedMemoryRecorder(1) data_handler.addRecorder(output_recorder) data_handler.addRecorder(json_recorder) for file_recorder in file_recorders: data_handler.addRecorder(file_recorder) data_handler.addRecorder(shm_recorder) data_handler.addRecorder(shm_recorder_1d) self._data = data self._data_handler = data_handler # ---------------------------------------------------------------------- # Setup environment # ---------------------------------------------------------------------- self._setupEnvironment(env) def _getExtraColumns(self): ret = [] try: cols = self.macro.getEnv('ExtraColumns') except InterruptException: raise except: self.info('ExtraColumns is not defined') return ret try: for i, kwargs in enumerate(cols): kw = dict(kwargs) try: if kw.has_key('instrument'): instrument = self._macro.getObj(kw['instrument'], type_class=Type.Instrument) if instrument: kw['instrument'] = instrument ret.append(TangoExtraData(**kw)) except InterruptException: raise except Exception, colexcept: colname = kw.get('label', str(i)) self.macro.warning("Extra column %s is invalid: %s", colname, str(colexcept)) except InterruptException: raise except Exception: self.macro.warning('ExtraColumns has invalid value. Must be a ' 'sequence of maps') return ret def _getJsonRecorder(self): try: json_enabled = self.macro.getEnv('JsonRecorder') if json_enabled: return JsonRecorder(self.macro) except InterruptException: raise except Exception: pass self.info('JsonRecorder is not defined. Use "senv JsonRecorder ' 'True" to enable it') def _getOutputRecorder(self): cols = None try: cols = self.macro.getEnv('OutputCols') except InterruptException: raise except: pass return OutputRecorder(self.macro, cols=cols, number_fmt='%g') def _getFileRecorders(self): macro = self.macro try: scan_dir = macro.getEnv('ScanDir') except InterruptException: raise except Exception: macro.warning('ScanDir is not defined. This operation will not be ' 'stored persistently. Use Use "expconf" (or "senv ScanDir ' '") to enable it') return () if not isinstance(scan_dir, (str, unicode)): scan_dir_t = type(scan_dir).__name__ raise TypeError("ScanDir MUST be string. It is '%s'" % scan_dir_t) try: file_names = macro.getEnv('ScanFile') except InterruptException: raise except Exception: macro.warning('ScanFile is not defined. This operation will not ' 'be stored persistently. Use "expconf" (or "senv ScanDir ") to enable it') return () if isinstance(file_names, (str, unicode)): file_names = (file_names,) elif not operator.isSequenceType(file_names): scan_file_t = type(file_names).__name__ raise TypeError("ScanFile MUST be string or sequence of strings."\ " It is '%s'" % scan_file_t) file_recorders = [] for file_name in file_names: abs_file_name = os.path.join(scan_dir, file_name) try: file_recorder = FileRecorder(abs_file_name, macro=macro) file_recorders.append(file_recorder) except InterruptException: raise except Exception: macro.warning("Error creating recorder for %s", abs_file_name) macro.debug("Details:", exc_info=1) if len(file_recorders) == 0: macro.warning("No valid recorder found. This operation will not be " " stored persistently") return file_recorders def _getSharedMemoryRecorder(self, eid): macro, mg, shm = self.macro, self.measurement_group, False try: shm = macro.getEnv('SharedMemory') except InterruptException: raise except Exception: self.info('SharedMemory is not defined. Use "senv ' 'SharedMemory sps" to enable it') return if not shm: return kwargs = {} # For now we only support SPS shared memory format if shm.lower() == 'sps': cols = 1 # Point nb column cols += len(self.moveables) # motor columns ch_nb = len(mg.getChannels()) oned_nb = 0 array_prefix = mg.getName().upper() try: oned_nb = len(mg.OneDExpChannels) except InterruptException: raise except: oned_nb = 0 twod_nb = 0 try: twod_nb = len(mg.TwoDExpChannels) except InterruptException: raise except: twod_nb = 0 if eid == 0: cols += (ch_nb - oned_nb - twod_nb) # counter/timer & 0D channel columns elif eid == 1: cols = 1024 if eid == 0: kwargs.update({ 'program' : macro.getDoorName(), 'array' : "%s_0D" % array_prefix, 'shape' : (cols, 4096) } ) elif eid == 1: if oned_nb == 0: return else: kwargs.update({ 'program' : macro.getDoorName(), 'array' : "%s_1D" % array_prefix, 'shape' : (cols, 99) } ) shmRecorder = SharedMemoryRecorder(shm, **kwargs) if shmRecorder is None: self.info('SharedMemory %s is not available'%shm) return shmRecorder def _secsToTimedelta(self, secs): days, secs = divmod(secs, 86400) # we don't have to care about microseconds because if secs is a float # timedelta will do it for us return datetime.timedelta(days, secs) def _timedeltaToSecs(self, td): return 86400*td.days + td.seconds + 1E-6*td.microseconds def _setupEnvironment(self, additional_env): try: serialno = self.macro.getEnv("ScanID") + 1 except UnknownEnv: serialno = 1 self.macro.setEnv("ScanID", serialno) env = ScanDataEnvironment( { 'serialno' : serialno, 'user' : USER_NAME, #TODO: this should be got from self.measurement_group.getChannelsInfo() 'title' : self.macro.getCommand() } ) # Initialize the data_desc list (and add the point number column) data_desc = [ ColumnDesc(name='point_nb', label='#Pt No', dtype='int64') ] # add motor columns ref_moveables = [] for moveable in self.moveables: data_desc.append(moveable) if moveable.is_reference: ref_moveables.insert(0, moveable.name) if not ref_moveables and len(self.moveables): ref_moveables.append(data_desc[-1].name) env['ref_moveables'] = ref_moveables # add master column master = self._master instrument = master['instrument'] #add channels from measurement group channels_info = self.measurement_group.getChannelsInfo() counters = [] for ci in channels_info: instrument = ci.instrument or '' try: instrumentFullName = self.macro.findObjs(instrument, type_class=Type.Instrument)[0].getFullName() except InterruptException: raise except: instrumentFullName = '' #substitute the axis placeholder by the corresponding moveable. plotAxes = [] i = 0 for a in ci.plot_axes: if a=='': plotAxes.append(ref_moveables[i]) i+=1 else: plotAxes.append(a) #create the ColumnDesc object column = ColumnDesc(name=ci.full_name, label = ci.label, dtype = ci.data_type, shape = ci.shape, instrument = instrumentFullName, source = ci.source, output = ci.output, conditioning = ci.conditioning, normalization = ci.normalization, plot_type = ci.plot_type, plot_axes = plotAxes, data_units = ci.unit) data_desc.append(column) counters.append(column.name) counters.remove(master['full_name']) env['counters'] = counters for extra_column in self._extra_columns: data_desc.append(extra_column.getColumnDesc()) # add extra columns data_desc += self._extrainfodesc data_desc.append(ColumnDesc(name='timestamp', label='dt', dtype='float64')) env['datadesc'] = data_desc #set the data compression default try: env['DataCompressionRank'] = self.macro.getEnv('DataCompressionRank') except UnknownEnv: env['DataCompressionRank'] = -1 #set the sample information #@todo: use the instrument API to get this info try: env['SampleInfo'] = self.macro.getEnv('SampleInfo') except UnknownEnv: env['SampleInfo'] = {} #set the source information #@todo: use the instrument API to get this info try: env['SourceInfo'] = self.macro.getEnv('SourceInfo') except UnknownEnv: env['SourceInfo'] = {} #take the pre-scan snapshot try: preScanSnapShot = self.macro.getEnv('PreScanSnapshot') except UnknownEnv: preScanSnapShot = [] env['preScanSnapShot'] = self.takeSnapshot(elements=preScanSnapShot) env['macro_id'] = self.macro.getID() try: env['ScanFile'] = self.macro.getEnv('ScanFile') except InterruptException: raise except: env['ScanFile'] = None try: env['ScanDir'] = self.macro.getEnv('ScanDir') except InterruptException: raise except: env['ScanDir'] = None env['estimatedtime'], env['total_scan_intervals'] = self._estimate() env['instrumentlist'] = self._macro.findObjs('.*', type_class=Type.Instrument) #env.update(self._getExperimentConfiguration) #add all the info from the experiment configuration to the environment env.update(additional_env) self._env = env # Give the environment to the ScanData self.data.setEnviron(env) def takeSnapshot(self, elements=[]): '''reads the current values of the given elements :param elements: (list) list of tuples of label,src for the elements to read (can be pool elements or Taurus attribute names). :return: (list) a list of :class:`ColumnDesc`, each including a "pre_scan_value" attribute with the read value for that attr ''' manager = self.macro.getManager() all_elements_info = manager.get_elements_with_interface('Element') ret = [] for src,label in elements: try: if src in all_elements_info: ei = all_elements_info[src] column = ColumnDesc(name=ei.full_name, label=label, instrument = ei.instrument, source = ei.source) else: column = ColumnDesc(name=src, label=label, source=src) v = PyTango.AttributeProxy(column.source).read().value #@Fixme: Tango-centric. It should work for any Taurus Attribute column.pre_scan_value = v column.shape = np.shape(v) column.dtype = getattr(v, 'dtype', np.dtype(type(v))).name ret.append(column) except: self.macro.warning('Error taking pre-scan snapshot of %s (%s)',label,src) self.debug('Details:', exc_info=1) return ret def get_virtual_motors(self): ret = [] for moveable in self.moveables: try: v_motor = VMotor.fromMotor(moveable.moveable) except: #self.debug("Details:", exc_info=1) v_motor = VMotor(min_vel=0, max_vel=float('+inf'), accel_time=0, decel_time=0) ret.append(v_motor) return ret MAX_ITER = 100000 def _estimate(self, max_iter=None): with_time = hasattr(self.macro, "getTimeEstimation") with_interval = hasattr(self.macro, "getIntervalEstimation") if with_time and with_interval: t, i = self.macro.getTimeEstimation(), self.macro.getIntervalEstimation() return t, i max_iter = max_iter or self.MAX_ITER iterator = self.generator() total_time = 0.0 interval_nb = 0 try: if not with_time: start_pos = self.motion.readPosition(force=True) v_motors = self.get_virtual_motors() motion_time, acq_time = 0.0, 0.0 while interval_nb < max_iter: step = iterator.next() end_pos = step['positions'] max_path_duration = 0.0 for v_motor, start, stop in zip(v_motors, start_pos, end_pos): path = MotionPath(v_motor, start, stop) max_path_duration = max(max_path_duration, path.duration) integ_time = step.get("integ_time", 0.0) acq_time += integ_time motion_time += max_path_duration total_time += integ_time + max_path_duration interval_nb += 1 start_pos = end_pos if with_interval: interval_nb = self.macro.getIntervalEstimation() else: while interval_nb < max_iter: step = iterator.next() interval_nb += 1 total_time = self.macro.getTimeEstimation() except StopIteration: return total_time, interval_nb # max iteration reached. return -total_time, -interval_nb @property def data(self): return self._data @property def macro(self): return self._macro @property def measurement_group(self): return self._measurement_group @property def generator(self): return self._generator @property def motion(self): return self._motion @property def moveables(self): return self._moveables @property def steps(self): if not hasattr(self, '_steps'): self._steps = enumerate(self.generator()) return self._steps def start(self): self.do_backup() env = self._env env['startts'] = ts = time.time() env['starttime'] = datetime.datetime.fromtimestamp(ts) env['acqtime'] = 0 env['motiontime'] = 0 env['deadtime'] = 0 self.data.start() def end(self): env = self._env env['endts'] = end_ts = time.time() env['endtime'] = datetime.datetime.fromtimestamp(end_ts) total_time = end_ts - env['startts'] estimated = env['estimatedtime'] acq_time = env['acqtime'] #env['deadtime'] = 100.0 * (total_time - estimated) / total_time env['deadtime'] = total_time - acq_time if 'delaytime' in env: env['motiontime'] = total_time - acq_time - env['delaytime'] elif 'motiontime' in env: env['delaytime'] = total_time - acq_time - env['motiontime'] self.data.end() try: scan_history = self.macro.getEnv('ScanHistory') except UnknownEnv: scan_history = [] scan_file = env['ScanFile'] if isinstance(scan_file, (str, unicode)): scan_file = scan_file, names = [ col.name for col in env['datadesc'] ] history = dict(startts=env['startts'], endts=env['endts'], estimatedtime=env['estimatedtime'], deadtime=env['deadtime'], title=env['title'], serialno=env['serialno'], user=env['user'], ScanFile=scan_file, ScanDir=env['ScanDir'], channels=names) scan_history.append(history) while len(scan_history) > self.MAX_SCAN_HISTORY: scan_history.pop(0) self.macro.setEnv('ScanHistory', scan_history) def scan(self): for _ in self.step_scan(): pass def step_scan(self): self.start() try: ex = None try: for i in self.scan_loop(): self.macro.pausePoint() yield i except ScanException, e: #self.macro.warning(e.msg) ex = e self.end() if not ex is None: raise e finally: self.do_restore() def scan_loop(self): raise NotImplementedError('Scan method cannot be called by ' 'abstract class') def do_backup(self): try: if hasattr(self.macro, 'do_backup'): self.macro.do_backup() except: self.macro.warning("Failed to execute macro 'do_backup'") self.debug("Details:", exc_info=1) def do_restore(self): try: if hasattr(self.macro, 'do_restore'): self.macro.do_restore() except: self.macro.warning("Failed to execute macro 'do_restore'") self.debug("Details:", exc_info=1) class SScan(GScan): """Step scan""" def scan_loop(self): lstep = None macro = self.macro scream = False if hasattr(macro, "nr_points"): nr_points = float(macro.nr_points) scream = True else: yield 0.0 if hasattr(macro, 'getHooks'): for hook in macro.getHooks('pre-scan'): hook() self._sum_motion_time = 0 self._sum_acq_time = 0 for i, step in self.steps: # allow scan to be stopped between points macro.checkPoint() self.stepUp(i, step, lstep) lstep = step if scream: yield ((i+1) / nr_points) * 100.0 if hasattr(macro, 'getHooks'): for hook in macro.getHooks('post-scan'): hook() if not scream: yield 100.0 self._env['motiontime'] = self._sum_motion_time self._env['acqtime'] = self._sum_acq_time def stepUp(self, n, step, lstep): motion, mg = self.motion, self.measurement_group startts = self._env['startts'] #pre-move hooks for hook in step.get('pre-move-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass # Move self.debug("[START] motion") move_start_time = time.time() try: state, positions = motion.move(step['positions']) self._sum_motion_time += time.time() - move_start_time except InterruptException: raise except: self.dump_information(n, step) raise self.debug("[ END ] motion") curr_time = time.time() dt = curr_time - startts #post-move hooks for hook in step.get('post-move-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass # allow scan to be stopped between motion and data acquisition self.macro.checkPoint() if state != Ready: self.dump_information(n, step) m = "Scan aborted after problematic motion: " \ "Motion ended with %s\n" % str(state) raise ScanException({ 'msg' : m }) #pre-acq hooks for hook in step.get('pre-acq-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass integ_time = step['integ_time'] # Acquire data self.debug("[START] acquisition") state, data_line = mg.count(integ_time) for ec in self._extra_columns: data_line[ec.getName()] = ec.read() self.debug("[ END ] acquisition") self._sum_acq_time += integ_time #post-acq hooks for hook in step.get('post-acq-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass #hooks for backwards compatibility: if step.has_key('hooks'): self.macro.info('Deprecation warning: you should use ' '"post-acq-hooks" instead of "hooks" in the step ' 'generator') for hook in step.get('hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass # Add final moveable positions data_line['point_nb'] = n data_line['timestamp'] = dt for i, m in enumerate(self.moveables): data_line[m.moveable.getName()] = positions[i] #Add extra data coming in the step['extrainfo'] dictionary if step.has_key('extrainfo'): data_line.update(step['extrainfo']) self.data.addRecord(data_line) #post-step hooks for hook in step.get('post-step-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass def dump_information(self, n, step): moveables = self.motion.moveable_list msg = ["Report: Stopped at step #" + str(n) + " with:"] for moveable in moveables: msg.append(moveable.information()) self.macro.info("\n".join(msg)) class CScan(GScan): """Continuous scan abstract class. Implements helper methods.""" def __init__(self, macro, generator=None, moveables=[], env={}, constraints=[], extrainfodesc=[]): GScan.__init__(self, macro, generator=generator, moveables=moveables, env=env, constraints=constraints, extrainfodesc=extrainfodesc) self._current_waypoint_finished = False self._all_waypoints_finished = False self.motion_event = threading.Event() self.motion_end_event = threading.Event() data_structures = self.populate_moveables_data_structures(moveables) self._moveables_trees, \ physical_moveables_names, \ self._physical_moveables = data_structures self._physical_motion = self.macro.getMotion(physical_moveables_names) def populate_moveables_data_structures(self, moveables): '''Populates moveables data structures. :param moveables: (list) data structures will be generated for these moveables :return (moveable_trees, physical_moveables_names, physical_moveables) - moveable_trees (list) - each tree represent one Moveables with its hierarchy of inferior moveables. - physical_moveables_names (list - list of the names of the physical moveables. List order is important and preserved. - physical_moveables (list - list of the moveable objects. List order is important and preserved.''' def generate_moveable_node(macro, moveable): '''Function to generate a moveable data structures based on moveable object. Internally can be recursively called if moveable is a PseudoMotor. :param moveable: moveable object :return (moveable_node, physical_moveables_names, physical_moveables) - moveable_node (BaseNode) - can be a BranchNode if moveable is a PseudoMotor or a LeafNode if moveable is a PhysicalMotor. - physical_moveables_names (list - list of the names of the physical moveables. List order is important and preserved. - physical_moveables (list - list of the moveable objects. List order is important and preserved.''' moveable_node = None physical_moveables_names = [] physical_moveables = [] moveable_type = moveable.getType() if moveable_type == "PseudoMotor": moveable_node = BranchNode(moveable) moveables_names = moveable.elements sub_moveables = [macro.getMoveable(name) \ for name in moveables_names] for sub_moveable in sub_moveables: sub_moveable_node, \ _physical_moveables_names, \ _physical_moveables = generate_moveable_node(macro, sub_moveable) physical_moveables_names += _physical_moveables_names physical_moveables += _physical_moveables moveable_node.addChild(sub_moveable_node) elif moveable_type == "Motor": moveable_node = LeafNode(moveable) moveable_name = moveable.getName() physical_moveables_names.append(moveable_name) physical_moveables.append(moveable) return moveable_node, physical_moveables_names, physical_moveables moveable_trees = [] physical_moveables_names = [] physical_moveables = [] for moveable in moveables: moveable_root_node, _physical_moveables_names, _physical_moveables = \ generate_moveable_node(self.macro, moveable.moveable) moveable_tree = Tree(moveable_root_node) moveable_trees.append(moveable_tree) physical_moveables_names += _physical_moveables_names physical_moveables += _physical_moveables return moveable_trees, physical_moveables_names, physical_moveables def get_moveables_trees(self): '''Returns reference to the list of the moveables trees''' return self._moveables_trees def on_waypoints_end(self, restore_positions=None): """To be called by the waypoint thread to handle the end of waypoints (either because no more waypoints or because a macro abort was triggered)""" self.set_all_waypoints_finished(True) if restore_positions is not None: self.macro.info("Correcting overshoot...") self._physical_motion.move(restore_positions) #self.motion.move(restore_positions) self.motion_end_event.set() self.motion_event.set() def go_through_waypoints(self, iterate_only=False): """Go through the different waypoints.""" try: self._go_through_waypoints() except: self.macro.error("An error occured moving to waypoints. Aborting...") self.macro.debug("Details:", exc_info=1) self.on_waypoints_end() def _go_through_waypoints(self): """Internal, unprotected method to go through the different waypoints.""" raise NotImplementedError("_go_through_waypoints must be implemented " + "in CScan derived classes") def waypoint_estimation(self): """Internal, unprotected method to go through the different waypoints.""" motion, waypoints = self.motion, self.generator() total_duration = 0 #v_motors = self.get_virtual_motors() curr_positions, last_end_positions = motion.readPosition(force=True), None for i, waypoint in enumerate(waypoints): start_positions = waypoint.get('start_positions', last_end_positions) positions = waypoint['positions'] if start_positions is None: last_end_positions = positions continue waypoint_info = self.prepare_waypoint(waypoint, start_positions, iterate_only=True) motion_paths, delta_start, acq_duration = waypoint_info start_path, end_path = [] , [] for path in motion_paths: start_path.append(path.initial_user_pos) end_path.append(path.final_user_pos) # move from last waypoint to start position of this waypoint first_duration = 0 if i == 1: # first waypoint means, moving from current position to the # start of first waypoint initial = curr_positions else: initial = start_positions for _path, start, end in zip(motion_paths, initial, start_path): v_motor = _path.motor path = MotionPath(v_motor, start, end) first_duration = max(first_duration, path.duration) # move from waypoint start position to waypoint end position second_duration = 0 for _path, start, end in zip(motion_paths, start_path, end_path): v_motor = _path.motor path = MotionPath(v_motor, start, end) second_duration = max(second_duration, path.duration) total_duration += first_duration + second_duration last_end_positions = end_path # add correct overshoot time overshoot_duration = 0 for _path, start, end in zip(motion_paths, last_end_positions, positions): v_motor = _path.motor path = MotionPath(v_motor, start, end) overshoot_duration = max(overshoot_duration, path.duration) total_duration += overshoot_duration return total_duration def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): raise NotImplementedError("prepare_waypoint must be implemented in " + "CScan derived classes") def set_all_waypoints_finished(self, v): self._all_waypoints_finished = v def do_backup(self): super(CScan, self).do_backup() self._backup = backup = [] for moveable in self._physical_moveables: # first backup all motor parameters motor = moveable try: velocity = motor.getVelocity() accel_time = motor.getAcceleration() decel_time = motor.getDeceleration() motor_backup = dict(moveable=moveable, velocity=velocity, acceleration=accel_time, deceleration=decel_time) self.debug("Backup of %s", motor) except AttributeError: motor_backup = None backup.append(motor_backup) def do_restore(self): super(CScan, self).do_restore() # restore changed motors to initial state for motor_backup in self._backup: if motor_backup is None: continue try: motor = motor_backup['moveable'] motor.setVelocity(motor_backup['velocity']) motor.setAcceleration(motor_backup['acceleration']) motor.setDeceleration(motor_backup['deceleration']) self.debug("Restored %s", motor) except: self.macro.warning("Failed to restore %s", motor) self.debug("Details:", exc_info=1) def get_max_top_velocity(self, motor): """Helper method to find the maximum top velocity for the motor. If the motor doesn't have a defined range for top velocity, then use the current top velocity""" top_vel_obj = motor.getVelocityObj() min_top_vel, max_top_vel = top_vel_obj.getRange() try: max_top_vel = float(max_top_vel) except ValueError: try: #hack to avoid recursive velocity reduction self._maxVelDict = getattr(self,'_maxVelDict',{}) if not motor in self._maxVelDict: self._maxVelDict[motor] = motor.getVelocity() max_top_vel = self._maxVelDict[motor] except AttributeError: pass return max_top_vel def get_min_acc_time(self, motor): """Helper method to find the minimum acceleration time for the motor. If the motor doesn't have a defined range for the acceleration time, then use the current acceleration time""" acc_time_obj = motor.getAccelerationObj() min_acc_time, max_acc_time = acc_time_obj.getRange() try: min_acc_time = float(min_acc_time) except ValueError: min_acc_time = motor.getAcceleration() return min_acc_time def get_min_dec_time(self, motor): """Helper method to find the minimum deceleration time for the motor. If the motor doesn't have a defined range for the acceleration time, then use the current acceleration time""" dec_time_obj = motor.getDecelerationObj() min_dec_time, max_dec_time = dec_time_obj.getRange() try: min_dec_time = float(min_dec_time) except ValueError: min_dec_time = motor.getDeceleration() return min_dec_time # def set_max_top_velocity(self, motor): # """Helper method to set the maximum top velocity for the motor to # its maximum allowed limit.""" # # v = self.get_max_top_velocity(motor) # try: # motor.setVelocity(v) # except: # pass class CSScan(CScan): """Continuous scan controlled by software""" def __init__(self, macro, waypointGenerator=None, periodGenerator=None, moveables=[], env={}, constraints=[], extrainfodesc=[]): CScan.__init__(self, macro, generator=waypointGenerator, moveables=moveables, env=env, constraints=constraints, extrainfodesc=extrainfodesc) self._periodGenerator = periodGenerator def _calculateTotalAcquisitionTime(self): return None @property def period_generator(self): return self._periodGenerator @property def period_steps(self): if not hasattr(self, '_period_steps'): self._period_steps = enumerate(self.period_generator()) return self._period_steps def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): slow_down = waypoint.get('slow_down', 1) positions = waypoint['positions'] duration, cruise_duration, delta_start = 0, 0, 0 ideal_paths, real_paths = [], [] for i, (moveable, position) in enumerate(zip(self.moveables, positions)): motor = moveable.moveable coordinate = True try: base_vel, top_vel = motor.getBaseRate(), motor.getVelocity() accel_time, decel_time = motor.getAcceleration(), motor.getDeceleration() if slow_down > 0: # find and set the maximum top velocity for the motor. # If the motor doesn't have a defined range for top velocity, # then use the current top velocity max_top_vel = self.get_max_top_velocity(motor) if not iterate_only: motor.setVelocity(max_top_vel) else: max_top_vel = top_vel except AttributeError: if not iterate_only: self.macro.warning("%s motion will not be coordinated", motor) base_vel, top_vel, max_top_vel = 0, float('+inf'), float('+inf') accel_time, decel_time = 0, 0 coordinate = False last_user_pos = start_positions[i] real_vmotor = VMotor(min_vel=base_vel, max_vel=max_top_vel, accel_time=accel_time, decel_time=decel_time) real_path = MotionPath(real_vmotor, last_user_pos, position) real_path.moveable = moveable real_path.apply_correction = coordinate # Find the cruise duration of motion at top velocity. For this create a # virtual motor which has instantaneous acceleration and deceleration ideal_vmotor = VMotor(min_vel=base_vel, max_vel=max_top_vel, accel_time=0, decel_time=0) # create a path which will tell us which is the cruise duration of this # motion at top velocity ideal_path = MotionPath(ideal_vmotor, last_user_pos, position) ideal_path.moveable = moveable ideal_path.apply_correction = coordinate # if really motor is moving in this waypoint if ideal_path.displacement > 0: # recalculate time to reach maximum velocity delta_start = max(delta_start, accel_time) # recalculate cruise duration of motion at top velocity cruise_duration = max(cruise_duration, ideal_path.duration) duration = max(duration, real_path.duration) ideal_paths.append(ideal_path) real_paths.append(real_path) if slow_down <= 0: return real_paths, 0, duration # after finding the duration, introduce the slow down factor added # by the user cruise_duration /= slow_down if cruise_duration == 0: cruise_duration = float('+inf') # now that we have the appropriate top velocity for all motors, the # cruise duration of motion at top velocity, and the time it takes to # recalculate for path in ideal_paths: vmotor = path.motor # in the case of pseudo motors or not moving a motor... if not path.apply_correction or path.displacement == 0: continue moveable = path.moveable motor = moveable.moveable new_top_vel = path.displacement / cruise_duration vmotor.setMaxVelocity(new_top_vel) accel_t, decel_t = motor.getAcceleration(), motor.getDeceleration() base_vel = vmotor.getMinVelocity() vmotor.setAccelerationTime(accel_t) vmotor.setDecelerationTime(decel_t) disp_sign = path.positive_displacement and 1 or -1 new_initial_pos = path.initial_user_pos - accel_t * 0.5 * disp_sign * (new_top_vel + base_vel) - disp_sign * new_top_vel * (delta_start - accel_t) path.setInitialUserPos(new_initial_pos) new_final_pos = path.final_user_pos + disp_sign * vmotor.displacement_reach_min_vel path.setFinalUserPos(new_final_pos) return ideal_paths, delta_start, cruise_duration def go_through_waypoints(self, iterate_only=False): """go through the different waypoints.""" try: self._go_through_waypoints() except Exception, e: self.macro.error("An error occured moving to waypoints. Aborting...") self.macro.debug("Details:", exc_info=1) self.on_waypoints_end() raise e def _go_through_waypoints(self): """Internal, unprotected method to go through the different waypoints.""" macro, motion, waypoints = self.macro, self.motion, self.steps self.macro.debug("_go_through_waypoints() entering...") last_positions = None for _, waypoint in waypoints: self.macro.debug("Waypoint iteration...") start_positions = waypoint.get('start_positions') positions = waypoint['positions'] if start_positions is None: start_positions = last_positions if start_positions is None: last_positions = positions continue waypoint_info = self.prepare_waypoint(waypoint, start_positions) motion_paths, delta_start, acq_duration = waypoint_info self.acq_duration = acq_duration #execute pre-move hooks for hook in waypoint.get('pre-move-hooks',[]): hook() start_pos, final_pos = [] , [] for path in motion_paths: start_pos.append(path.initial_user_pos) final_pos.append(path.final_user_pos) if macro.isStopped(): self.on_waypoints_end() return # move to start position self.macro.debug("Moving to start position: %s" % repr(start_pos)) motion.move(start_pos) if macro.isStopped(): return self.on_waypoints_end() # prepare motor(s) to move with their maximum velocity for path in motion_paths: if not path.apply_correction: continue vmotor = path.motor motor = path.moveable.moveable motor.setVelocity(vmotor.getMaxVelocity()) if macro.isStopped(): return self.on_waypoints_end() self.timestamp_to_start = time.time() + delta_start self.motion_event.set() # move to waypoint end position motion.move(final_pos) self.motion_event.clear() if macro.isStopped(): return self.on_waypoints_end() #execute post-move hooks for hook in waypoint.get('post-move-hooks',[]): hook() if start_positions is None: last_positions = positions self.on_waypoints_end(positions) def scan_loop(self): motion, mg, waypoints = self.motion, self.measurement_group, self.steps macro = self.macro manager = macro.getManager() scream = False motion_event = self.motion_event startts = self._env['startts'] sum_delay = 0 sum_integ_time = 0 if hasattr(macro, "nr_points"): nr_points = float(macro.nr_points) scream = True else: yield 0.0 moveables = [ m.moveable for m in self.moveables ] period_steps = self.period_steps point_nb, step = -1, None data = self.data if hasattr(macro, 'getHooks'): for hook in macro.getHooks('pre-scan'): hook() # start move & acquisition as close as possible # from this point on synchronization becomes critical manager.add_job(self.go_through_waypoints) while not self._all_waypoints_finished: # wait for motor to reach start position motion_event.wait() # allow scan to stop macro.checkPoint() if self._all_waypoints_finished: break # wait for motor to reach max velocity start_time = time.time() deltat = self.timestamp_to_start - start_time if deltat > 0: time.sleep(deltat) curr_time = acq_start_time = time.time() integ_time = 0 # Acquisition loop: acquire consecutively until waypoint asks to # stop or we see that we will enter deceleration time in next # acquisition while motion_event.is_set(): # allow scan to stop macro.checkPoint() try: point_nb, step = period_steps.next() except StopIteration: self._all_waypoints_finished = True break integ_time = step['integ_time'] # If there is no more time to acquire... stop! elapsed_time = time.time() - acq_start_time if elapsed_time + integ_time > self.acq_duration: motion_event.clear() break; #pre-acq hooks for hook in step.get('pre-acq-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: self._all_waypoints_finished = True raise except: pass # allow scan to stop macro.checkPoint() positions = motion.readPosition(force=True) dt = time.time() - startts # Acquire data self.debug("[START] acquisition") state, data_line = mg.count(integ_time) sum_integ_time += integ_time # allow scan to stop macro.checkPoint() # After acquisition, test if we are asked to stop, probably because # the motor are stopped. In this case discard the last acquisition if not self._all_waypoints_finished: for ec in self._extra_columns: data_line[ec.getName()] = ec.read() self.debug("[ END ] acquisition") #post-acq hooks for hook in step.get('post-acq-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: self._all_waypoints_finished = True raise except: pass # Add final moveable positions data_line['point_nb'] = point_nb data_line['timestamp'] = dt for i, m in enumerate(self.moveables): data_line[m.moveable.getName()] = positions[i] #Add extra data coming in the step['extrainfo'] dictionary if step.has_key('extrainfo'): data_line.update(step['extrainfo']) self.data.addRecord(data_line) if scream: yield ((point_nb+1) / nr_points) * 100.0 else: break old_curr_time = curr_time curr_time = time.time() sum_delay += (curr_time - old_curr_time) - integ_time self.motion_end_event.wait() if hasattr(macro, 'getHooks'): for hook in macro.getHooks('post-scan'): hook() env = self._env env['acqtime'] = sum_integ_time env['delaytime'] = sum_delay if not scream: yield 100.0 class CTScan(CScan): '''Continuous scan controlled by hardware trigger signals. Sequence of trigger signals is programmed in time. ''' class ExtraTrigger: '''Helper class and temporary solution for configuring trigger device. It is used to configure any Tango device name implementing: +) following attributes: - InitialDelayTime [s] - delay time from calling Start to generating first pulse - HighTime [s] - time interval while signal will maintain its high state - LowTime [s] - time interval while signal will maintain its low state - SampPerChan - nr of pulses to be generated - IdleState - state (high or low) which signal will take after the Start command and which will maintain during the InitialDelayTime. +) following commands: - Start - Stop)''' MIN_HIGH_TIME = 0.0000002 MIN_TIME_PER_TRIGGER = 0.000001 def __init__(self, macro): self.macro = macro triggerDeviceName = self.macro.getEnv("TriggerDevice") self.master = None self.slaves = [] masterName = None slaveNames = [] if isinstance(triggerDeviceName, str): masterName = triggerDeviceName elif isinstance(triggerDeviceName, list): masterName = triggerDeviceName[0] slaveNames = triggerDeviceName[1:] for name in slaveNames: slave = PyTango.DeviceProxy(name) self.slaves.append(slave) if masterName != None: self.master = PyTango.DeviceProxy(masterName) def configure(self, scanTime=None, nrOfTriggers=None, idleState="Low", lowTime=None, highTime=None, delayTime=0): if not None in (scanTime, nrOfTriggers, delayTime, idleState): timePerTrigger = scanTime / nrOfTriggers if timePerTrigger < self.MIN_TIME_PER_TRIGGER: raise Exception("scanTime is not long enough to manage this amount of triggers") highTime = self.MIN_HIGH_TIME lowTime = timePerTrigger - highTime elif not None in (lowTime, highTime, delayTime, nrOfTriggers, idleState): pass else: raise Exception("Missing parameters.") self.master.write_attribute("InitialDelayTime", delayTime) self.master.write_attribute("HighTime", highTime) # 162.5 ns self.master.write_attribute("LowTime", lowTime) # 2.75 ms self.master.write_attribute("SampPerChan", long(nrOfTriggers)) self.master.write_attribute("IdleState", idleState) self.master.write_attribute("SampleTimingType", "Implicit") for slave in self.slaves: slave.write_attribute("HighTime", highTime) # 162.5 ns slave.write_attribute("LowTime", lowTime) # 2.75 ms slave.write_attribute("SampPerChan", long(nrOfTriggers)) slave.write_attribute("IdleState", idleState) slave.write_attribute("SampleTimingType", "Implicit") return timePerTrigger def getConfiguration(self): return None, None, None, None def start(self): for slave in self.slaves: self.macro.debug("Staring %s" % slave.name()) slave.Start() if self.master != None: self.master.Start() def stop(self): for slave in self.slaves: self.macro.debug("Stopping %s" % slave.name()) slave.Stop() if self.master != None: self.master.Stop() class ExtraMntGrp: '''Helper class and temporary solution for configuring experimental channels. It assumes that experimental channels are implementing: +) following attributes: - Data - an array of acquired data - TriggerMode - Soft or Gate - to configure/unconfigure channel for hardware trigger - NrOfTriggers - to specify how many hardware triggers and acquistions will be done - SamplingFrequency - have sence only for sampling experimental channels +) following SendToCtrl strings: - "pre-start" - "start" - "pre-stop" - "stop"''' def __init__(self, macro): self.macro = macro activeMntGrpName = self.macro.getEnv("ActiveMntGrp") self.mntGrp = self.macro.getMeasurementGroup(activeMntGrpName) self.activeChannels = [] self.nrOfTriggers = 0 channels = self.mntGrp.getChannels() for channel in channels: channelName = channel["name"] expChannel = self.macro.getExpChannel(channelName) expChannel.getHWObj().set_timeout_millis(120000) #in case of readout of position channels, it can take really long... self.activeChannels.append(expChannel) def isMoving(self): for channel in self.activeChannels: if channel.State() == PyTango.DevState.MOVING: return True return False def start(self): for channel in self.activeChannels: pool = channel.getPoolObj() ctrlName = channel.getControllerName() axis = channel.getAxis() self.macro.debug("Pre-starting controller: %s, axis: %d", ctrlName, axis) pool.SendToController([ctrlName, 'pre-start %d' % axis]) for channel in self.activeChannels: pool = channel.getPoolObj() ctrlName = channel.getControllerName() axis = channel.getAxis() self.macro.debug("Starting controller: %s, axis: %d", ctrlName, axis) pool.SendToController([ctrlName, 'start %d' % axis]) def stop(self): for channel in self.activeChannels: pool = channel.getPoolObj() ctrlName = channel.getControllerName() axis = channel.getAxis() self.macro.debug("Pre-stopping controller: %s, axis: %d", ctrlName, axis) pool.SendToController([ctrlName, 'pre-stop %d' % axis]) for channel in self.activeChannels: pool = channel.getPoolObj() ctrlName = channel.getControllerName() axis = channel.getAxis() self.macro.debug("Stopping controller: %s, axis: %d", ctrlName, axis) pool.SendToController([ctrlName, 'stop %d' % axis]) def getDataList(self): dataList = [ {"point_nb" : i, "timestamp" : 0} for i in xrange(self.nrOfTriggers) ] for channel in self.activeChannels: dataDesc = channel.getFullName() channelData = channel.getAttribute("Data").read().value for i, data in enumerate(channelData): dataList[i][dataDesc] = data return dataList def setSamplingFrequency(self, freq): for channel in self.activeChannels: channel.getAttribute('SamplingFrequency').write(freq) def setAcquisitionTime(self, acqTime): for channel in self.activeChannels: channel.getAttribute('AcquisitionTime').write(acqTime) def setTriggerMode(self, mode): if mode not in ["soft", "gate"]: raise Exception("Trigger mode must be either soft or gate.") for channel in self.activeChannels: channel.getAttribute('TriggerMode').write(mode) def setNrOfTriggers(self, nrOfTriggers): self.nrOfTriggers = nrOfTriggers for channel in self.activeChannels: channel.getAttribute('NrOfTriggers').write(nrOfTriggers) def configure(self, nrOfTriggers, acqTime, timePerTrigger, sampFreq=-1, triggerMode="gate"): self.macro.debug("acqTime: %s" % acqTime) if timePerTrigger == None: raise Exception("TimePerTrigger attribute must be set") acqTime = timePerTrigger * acqTime / 100.0 self.setTriggerMode(triggerMode) self.setNrOfTriggers(nrOfTriggers) self.setSamplingFrequency(sampFreq) self.setAcquisitionTime(acqTime) self.macro.debug("MG: nrOfTriggers: %s, timePerTrigger: %s, acqTime: %s, sampFreq: %s" % (nrOfTriggers,timePerTrigger,acqTime,sampFreq)) def getConfiguration(self): return None def setConfiguration(self, configuration): pass def __init__(self, macro, generator=None, moveables=[], env={}, constraints=[], extrainfodesc=[]): CScan.__init__(self, macro, generator=generator, moveables=moveables, env=env, constraints=constraints, extrainfodesc=extrainfodesc) self._measurement_group = self.ExtraMntGrp(macro) self.extraTrigger = self.ExtraTrigger(macro) def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): '''Prepare list of MotionPath objects per each physical motor. :param waypoint: (dict) waypoint dictionary with necessary information :param start_positions: (list) list of starting position per each physical motor :return (ideal_paths, acc_time, active_time) - ideal_paths: (list representing motion attributes of each physical motor) - acc_time: acceleration time which will be used during the scan it corresponds to the longest acceleration time of all the motors - active_time: time interval while all the physical motors will maintain constant velocity''' positions = waypoint['positions'] active_time = waypoint["active_time"] ideal_paths = [] max_acc_time, max_dec_time = 0, 0 for moveable, end_position in zip(self._physical_moveables, positions): motor = moveable self.macro.debug("Motor: %s" % motor.getName()) self.macro.debug("AccTime: %f" % self.get_min_acc_time(motor)) self.macro.debug("DecTime: %f" % self.get_min_dec_time(motor)) max_acc_time = max(self.get_min_acc_time(motor), max_acc_time) max_dec_time = max(self.get_min_dec_time(motor), max_dec_time) acc_time = max_acc_time dec_time = max_dec_time for moveable, start_position, end_position in \ zip(self._physical_moveables, start_positions, positions): base_vel = moveable.getBaseRate() ideal_vmotor = VMotor(accel_time=acc_time, decel_time=dec_time, min_vel=base_vel) ideal_path = MotionPath(ideal_vmotor, start_position, end_position, active_time) ideal_path.moveable = moveable ideal_path.apply_correction = True ideal_paths.append(ideal_path) return ideal_paths, acc_time, active_time def _go_through_waypoints(self): """Internal, unprotected method to go through the different waypoints. It controls all the three objects: motion, trigger and measurement group.""" macro, motion, waypoints = self.macro, self._physical_motion, self.steps self.macro.debug("_go_through_waypoints() entering...") last_positions = None for _, waypoint in waypoints: self.macro.debug("Waypoint iteration...") start_positions = waypoint.get('start_positions') positions = waypoint['positions'] if start_positions is None: start_positions = last_positions if start_positions is None: last_positions = positions continue waypoint_info = self.prepare_waypoint(waypoint, start_positions) motion_paths, delta_start, acq_duration = waypoint_info self.acq_duration = acq_duration #execute pre-move hooks for hook in waypoint.get('pre-move-hooks',[]): hook() start_pos, final_pos = [] , [] for path in motion_paths: start_pos.append(path.initial_user_pos) final_pos.append(path.final_user_pos) if macro.isStopped(): self.on_waypoints_end() return self.__mntGrpConfigured = False self.__triggerConfigured = False self.__mntGrpStarted = False self.__triggerStarted = False #validation of parameters for start, end in zip(self.macro.starts, self.macro.finals): if start == end: raise Exception("Start and End can not be equal.") startTimestamp = time.time() #extra pre configuration if hasattr(macro, 'getHooks'): for hook in macro.getHooks('pre-configuration'): hook() self.macro.checkPoint() #configuring trigger lines oldHighTime, oldLowTime, oldDelay, oldNrOfTriggers = \ self.extraTrigger.getConfiguration() self.__triggerConfigured = True timePerTrigger = self.extraTrigger.configure(delayTime=delta_start, scanTime=acq_duration, nrOfTriggers=self.macro.nr_of_points) self.macro.checkPoint() #configuring measurementGroup self.mntGrpConfiguration = self._measurement_group.getConfiguration() self.__mntGrpConfigured = True self._measurement_group.configure(self.macro.nr_of_points, self.macro.acq_time, timePerTrigger) self.macro.checkPoint() #extra post configuration if hasattr(macro, 'getHooks'): for hook in macro.getHooks('post-configuration'): hook() self.macro.checkPoint() endTimestamp = time.time() self.macro.info("Configuration took %s time." % repr(endTimestamp - startTimestamp)) # move to start position self.macro.debug("Moving to start position: %s" % repr(start_pos)) motion.move(start_pos) if macro.isStopped(): return self.on_waypoints_end() # prepare motor(s) to move with their maximum velocity for path in motion_paths: motor = path.moveable self.macro.debug("Motor: %s" % motor.getName()) self.macro.debug("Velocity: %f" % path.max_vel) self.macro.debug("AccTime: %f" % path.max_vel_time) self.macro.debug("DecTime: %f" % path.min_vel_time) #TODO: check why we have 0 here #if 0 in [path.max_vel, path.max_vel_time, path.min_vel_time]: # continue motor.setVelocity(path.max_vel) motor.setAcceleration(path.max_vel_time) motor.setDeceleration(path.min_vel_time) if macro.isStopped(): return self.on_waypoints_end() if hasattr(macro, 'getHooks'): for hook in macro.getHooks('pre-start'): hook() self.macro.checkPoint() self.macro.debug("Starting measurement group") self.__mntGrpStarted = True self._measurement_group.start() self.timestamp_to_start = time.time() + delta_start self.motion_event.set() # move to waypoint end position self.macro.debug("Moving to waypoint position: %s" % repr(final_pos)) self.macro.debug("Starting triggers") self.__triggerStarted = True self.extraTrigger.start() motion.move(final_pos) self.motion_event.clear() if macro.isStopped(): return self.on_waypoints_end() #execute post-move hooks for hook in waypoint.get('post-move-hooks',[]): hook() self.macro.debug("Waiting for measurement group to finish") while self._measurement_group.isMoving(): self.macro.checkPoint() time.sleep(0.1) self.macro.debug("Getting data") data_list = self._measurement_group.getDataList() def populate_ideal_positions(): moveables = self.moveables nr_of_points = self.macro.nr_of_points starts = self.macro.starts finals = self.macro.finals positions_records = [{} for i in xrange(nr_of_points)] for moveable, start, final in zip(moveables, starts, finals): name = moveable.moveable.getName() step_size = abs((end-start)/nr_of_points) for point_nr, position in enumerate(np.arange(start, \ final, step_size)): positions_records[point_nr][name] = position return positions_records #TODO: decide what to do with moveables position_list = populate_ideal_positions() self.macro.debug("Storing data") for data_dict, position_dict in zip(data_list,position_list): data_dict.update(position_dict) self.data.addRecord(data_dict) if start_positions is None: last_positions = positions self.on_waypoints_end(positions) def on_waypoints_end(self, restore_positions=None): self.macro.debug("on_waypoints_end() entering...") CScan.on_waypoints_end(self, restore_positions=restore_positions) self.cleanup() def scan_loop(self): macro = self.macro manager = macro.getManager() scream = False motion_event = self.motion_event startts = self._env['startts'] sum_delay = 0 sum_integ_time = 0 if hasattr(macro, "nr_points"): nr_points = float(macro.nr_points) scream = True else: yield 0.0 moveables = [ m.moveable for m in self.moveables ] point_nb, step = -1, None data = self.data if hasattr(macro, 'getHooks'): for hook in macro.getHooks('pre-scan'): hook() self.go_through_waypoints() if hasattr(macro, 'getHooks'): for hook in macro.getHooks('post-scan'): hook() env = self._env env['acqtime'] = sum_integ_time env['delaytime'] = sum_delay if not scream: yield 100.0 def cleanup(self): '''This method is responsible for restoring state of measurement group and trigger to its state before the scan.''' startTimestamp = time.time() if self.__mntGrpStarted: self.debug("Stopping measurement group") try: self._measurement_group.stop() except Exception, e: self.warning("Exception while trying to stop measurement group.") self.debug(e) if self.__triggerStarted: self.debug("Stopping triggers") try: self.extraTrigger.stop() except Exception, e: self.warning("Exception while trying to stop trigger.") self.debug(e) if hasattr(self.macro, 'getHooks'): for hook in self.macro.getHooks('pre-cleanup'): self.debug("Executing pre-cleanup hook") try: hook() except Exception, e: self.warning("Exception while trying to execute a pre-cleanup hook") self.debug(e) if self.__mntGrpConfigured: self.debug("Restoring configuration of measurement group") try: self._measurement_group.setConfiguration(self.mntGrpConfiguration) #TODO: mntGrp configuration should contain also: nrOfTriggers, acqTime, sampling frequency except: self.warning("Exception while trying to restore measurement group parameters") self.debug(e) if hasattr(self.macro, 'getHooks'): for hook in self.macro.getHooks('post-cleanup'): self.debug("Executing post-cleanup hook") try: hook() except Exception, e: self.warning("Exception while trying to execute a post-cleanup hook") self.debug(e) endTimestamp = time.time() self.debug("Cleanup took %s time." % repr(endTimestamp - startTimestamp)) class HScan(SScan): """Hybrid scan""" def stepUp(self, n, step, lstep): motion, mg = self.motion, self.measurement_group startts = self._env['startts'] #pre-move hooks for hook in step.get('pre-move-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass positions, integ_time = step['positions'], step['integ_time'] try: m_ID = motion.startMove(positions) mg_ID = mg.startCount(integ_time) except InterruptException: raise except: self.dump_information(n, step) raise try: motion.waitMove(id=m_ID) mg.waitCount(id=mg_ID) except InterruptException: raise except: self.dump_information(n, step) raise self._sum_acq_time += integ_time curr_time = time.time() dt = curr_time - startts m_state, m_positions = motion.readState(), motion.readPosition() if m_state != Ready: self.dump_information(n, step) m = "Scan aborted after problematic motion: " \ "Motion ended with %s\n" % str(m_state) raise ScanException({ 'msg' : m }) data_line = mg.getValues() # Add final moveable positions data_line['point_nb'] = n data_line['timestamp'] = dt for i, m in enumerate(self.moveables): data_line[m.moveable.getName()] = m_positions[i] #Add extra data coming in the step['extrainfo'] dictionary if step.has_key('extrainfo'): data_line.update(step['extrainfo']) self.data.addRecord(data_line) #post-step hooks for hook in step.get('post-step-hooks',()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise except: pass def dump_information(self, n, step): moveables = self.motion.moveable_list msg = ["Report: Stopped at step #" + str(n) + " with:"] for moveable in moveables: msg.append(moveable.information()) self.macro.info("\n".join(msg)) sardana-1.2.0/src/sardana/macroserver/scan/scandata.py0000644000234100017500000002161612174204307024342 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan data module""" __all__ = ["ColumnDesc", "MoveableDesc", "Record", "RecordEnvironment", "ScanDataEnvironment", "RecordList", "ScanData", "ScanFactory"] import copy from taurus.core.util import Singleton from recorder import DataHandler class ColumnDesc: """The description of a column for a Record""" _TYPE_MAP = {"short": "int16", "ushort": "uint16"} _shape = [] _dtype = 'float64' def __init__(self, **kwargs): """Expected keywords are: - name (str, mandatory): unique column name - label (str, optional): column label (defaults to name) - dtype (str, optional): data type. Defaults to 'float64' - shape (seq, optional): data shape. Defaults to [] Any keyword not in the previous list will be converted to a member of the :class:`ColumnDesc`""" #enforce that the mandatory arguments are present try: self.name = kwargs.pop('name') except: raise TypeError('"name" parameter is mandatory') #make sure that at least the required members exist self.label = kwargs.pop('label', self.name) self.setDtype(kwargs.pop('dtype', self.__class__._dtype)) self.setShape(kwargs.pop('shape', self.__class__._shape)) # create members of the ColumnDesc class using the remaining keyword # args self._extra_kwargs = kwargs self.__dict__.update(kwargs) def getShape(self): return self._shape def setShape(self, shape): self._shape = self._simplifyShape(shape) def getDtype(self): return self._dtype def setDtype(self, dtype): self._dtype = self.tr(dtype) shape = property(getShape, setShape) dtype = property(getDtype, setDtype) @staticmethod def _simplifyShape(s): '''the idea is to strip the shape of useless "ones" at the beginning. For example: - () -> () - (1,) -> () - (1,1,1,1) -> () - (2,) -> (2) - (1,2) -> (2) - (1,2,3) -> (2,3) - (2,3) -> (2,3) - (1,1,1,2,3) -> (2,3) - (3,1,1) -> (3,1,1) ''' s = list(s) for i, e in enumerate(s): if e > 1: return s[i:] return [] def tr(self, dtype): return self._TYPE_MAP.get(dtype, dtype) def toDict(self): '''creates a dictionary representation of the record''' d = copy.deepcopy(self._extra_kwargs) for k in ['name', 'label', 'dtype', 'shape']: d[k] = getattr(self, k) return d def clone(self): return copy.deepcopy(self) #return self.__class__(**self.toDict()) class MoveableDesc(ColumnDesc): def __init__(self, **kwargs): """Expected keywords are: - moveable (Moveable, mandatory): moveable object - name (str, optional): column name (defaults to moveable name) - label (str, optional): column label (defaults to moveable name) - dtype (str, optional): data type. Defaults to 'float64' - shape (seq, optional): data shape. Defaults to (1,) - instrument (Instrument, optional): instrument object. Defaults to moveable instrument""" try: self.moveable = moveable = kwargs.pop('moveable') except KeyError: raise TypeError("moveable parameter is mandatory") name = moveable.getName() kwargs['name'] = kwargs.get('name', name) kwargs['label'] = kwargs.get('label', name) kwargs['instrument'] = kwargs.get('instrument', moveable.instrument) self.min_value = kwargs.get('min_value') self.max_value = kwargs.get('max_value') self.is_reference = kwargs.get('is_reference') ColumnDesc.__init__(self, **kwargs) def toDict(self): d = ColumnDesc.toDict(self) d['min_value'] = self.min_value d['max_value'] = self.max_value d['is_reference'] = self.is_reference return d def clone(self): return self.__class__(moveable=self.moveable, **self.toDict()) class Record: """ One record is a set of values measured at the same time. The Record.data member will be a dictionary containing: - 'point_nb' : (int) the point number of the scan - for each column of the scan (motor or counter), a key with the corresponding column name (str) and the corresponding value """ def __init__(self, data): self.recordno = 0 self.data = data self.complete = 0 self.written = 0 def setRecordNo(self, recordno): self.recordno = recordno def setComplete(self): self.complete = 1 def setWritten(self): self.written = 1 class RecordEnvironment(dict): """ A RecordEnvironment is a set of arbitrary pairs of type label/value in the form of a dictionary. """ __needed = ['title', 'labels'] def isValid(self): """ Check valid environment = all needed keys present """ if not self.needed: return 1 for ky in self.needed + self.__needed: if ky not in self.keys(): return 0 else: return 1 class ScanDataEnvironment(RecordEnvironment): """It describes a recordlist and its environment A recordlist environment contains a number of predefined label/value pairs Values can be either a string, a numeric value or a list of strings, numbers title: mandatory labels: mandatory. label for each of the fields in a record of the recordlist fielddesc: description of the content of each of the fields in a record. Can be used to affect the way the field is saved by the recorder. If not present all fields are by default of type FLOAT and FORMAT ".8g" """ needed = ['title', 'labels', 'user'] class RecordList(dict): """ A RecordList is a set of records: for example a scan. It is composed of a environment and a list of records""" def __init__(self, datahandler, environ=None): self.datahandler = datahandler if environ == None: self.environ = RecordEnvironment() else: self.environ = environ self.records = [] # make it pickable def __getstate__(self): return dict(datahandler=None, environ=None, records=self.records) def setEnviron(self, environ): self.environ = environ def updateEnviron(self, environ): self.environ.update(environ) def setEnvironValue(self, name, value): self.environ[name] = value def getEnvironValue(self, name): return self.environ[name] def getEnviron(self): return self.environ def start(self): self.recordno = 0 self.datahandler.startRecordList(self) def addRecord(self, record): rc = Record(record) rc.setRecordNo(self.recordno) self.records.append(rc) self[self.recordno] = rc self.recordno += 1 self.datahandler.addRecord(self, rc) def addRecords(self, records): map(self.addRecord, records) def end(self): self.datahandler.endRecordList(self) def getDataHandler(self): return self.datahandler class ScanData(RecordList): def __init__(self, environment=None, data_handler=None): dh = data_handler or DataHandler() RecordList.__init__(self, dh, environment) class ScanFactory(Singleton): def __init__(self): """ Initialization. Nothing to be done here for now.""" pass def init(self, *args): """Singleton instance initialization.""" pass def getDataHandler(self): return DataHandler() def getScanData(self, dh): return ScanData(data_handler=dh) sardana-1.2.0/src/sardana/macroserver/__init__.py0000644000234100017500000000211612174204311023364 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the main macro server module""" __docformat__ = 'restructuredtext' sardana-1.2.0/src/sardana/macroserver/basetypes.py0000644000234100017500000000726212174204311023633 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of the macroserver base types for macros""" __all__ = ["Integer", "Float", "Boolean", "String", "User", "Filename", "File", "Macro", "MacroLibrary", "Env", "Motor", "MotorParam", "MotorGroup", "ExpChannel", "MeasurementGroup", "ComChannel", "IORegister", "Controller", "Instrument", "ControllerClass" ] __docformat__ = 'restructuredtext' from sardana import INTERFACES from sardana.macroserver.msparameter import ParamType, AttrParamType, \ ElementParamInterface # Basic types class Any(ParamType): type_class = lambda p : p class Integer(ParamType): type_class = int class Float(ParamType): type_class = float class Boolean(ParamType): type_class = bool def getObj(self, str_repr): return str_repr.lower() == "true" class String(ParamType): type_class = str class User(ParamType): type_class = str class Filename(ParamType): type_class = str class File(ParamType): type_class = str def __init__(self, macro_server, name): ParamType.__init__(self, macro_server, name) self.filename = None #self.data is supposed to be an array.array object self.data = None def set(self, filename, data): self.filename = filename self.data = data class JSON(ParamType): def getObj(self, str_repr): import json return json.loads(str_repr) class Env(ParamType): type_class = str class TangoDevice(ParamType): def getObj(self, str_repr): import PyTango return PyTango.DeviceProxy(str_repr) class Device(ParamType): def getObj(self, str_repr): import taurus return taurus.Device(str_repr) # Hardware types class MotorParam(AttrParamType): """Class designed to represent a motor parameter name. Usual values are acceleration,deceleration,velocity,backlash,steps_per_unit,etc""" def __init__(self, macro_server, name): AttrParamType.__init__(self, macro_server, name) self.attr_item_list = ["Acceleration","Backlash","Base_rate","Step_per_unit", "Deceleration","Velocity","Offset"] self.non_attr_item_list = ["Controller"] def getItemList(self): return self.non_attr_item_list + self.attr_item_list def getAttrItemList(self): return self.attr_item_list def getNonAttrItemList(self): return self.non_attr_item_list def __build_base_types(): for sardana_type, info in INTERFACES.items(): _, doc = info class _I(ElementParamInterface): __doc__ = doc __name__ = sardana_type globals()[sardana_type] = _I __build_base_types() sardana-1.2.0/src/sardana/macroserver/macro.py0000644000234100017500000024427112174204311022740 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer generic scan""" from __future__ import with_statement from __future__ import print_function __all__ = ["OverloadPrint", "PauseEvent", "Hookable", "ExecMacroHook", "MacroFinder", "Macro", "macro", "iMacro", "imacro", "MacroFunc", "Type", "ParamRepeat", "Table", "List", "ViewOption", "LibraryError"] __docformat__ = 'restructuredtext' import threading import traceback import time import sys import operator import types import weakref import StringIO import ctypes from taurus.core.util import Logger, propertx from taurus.console.table import Table from taurus.console.list import List from taurus.core.tango.sardana.pool import PoolElement from sardana.sardanadefs import State from sardana.util.wrap import wraps from .msparameter import Type, ParamType, ParamRepeat from .msexception import StopException, AbortException, \ MacroWrongParameterType, UnknownEnv, UnknownMacro, LibraryError from .msoptions import ViewOption asyncexc = ctypes.pythonapi.PyThreadState_SetAsyncExc # first define the async exception function args. This is # absolutely necessary for 64 bits machines. asyncexc.argtypes = (ctypes.c_long, ctypes.py_object) class OverloadPrint(object): def __init__(self, m): self._macro = m self._accum = "" def __enter__(self): self.stdout = sys.stdout sys.stdout = self def __exit__(self, exc_type, exc_value, traceback): self.flush() sys.stdout = self.stdout def write(self, s): self._accum += s # while there is no new line, just accumulate the buffer try: if s[-1] == '\n' or s.index('\n') >= 0: self.flush() except ValueError: pass def flush(self): b = self._accum if b is None or len(b) == 0: return #take the '\n' because the output is a list of strings, each to be #interpreted as a separate line in the client if b[-1] == '\n': b = b[:-1] self._macro.output(b) self._accum = "" class PauseEvent(Logger): def __init__(self, macro_obj, abort_timeout = 0.2): self._name = self.__class__.__name__ self._pause_cb = None self._resume_cb = None self._macro_obj_wr = weakref.ref(macro_obj) self._macro_name = macro_obj._getName() self._wait_for_abort_exception = False self._wait_for_abort_timeout = abort_timeout Logger.__init__(self, "Macro_%s %s" % (self._macro_name, self._name)) # we create an event object that is automatically set self._event = threading.Event() self._event.set() @property def macro_obj(self): return self._macro_obj_wr() def pause(self, cb=None): self.debug("[START] Pause") self._pause_cb = cb self._event.clear() self.debug("[ END ] Pause") def resume(self, cb=None): if self.isPaused(): self.debug("[START] Resume") self._resume_cb = cb self._event.set() self.debug("[ END ] Resume") def resumeForAbort(self): if self.isPaused(): self.debug("[RESUME] (Abort)") self._wait_for_abort_exception = True self._event.set() def wait(self,timeout=None): pauseit = not self._event.isSet() if pauseit and self._pause_cb is not None: self._pause_cb(self.macro_obj) self._event.wait(timeout) # if an event is set because an abort has been issued during a paused # macro wait for the ashyncronous AbortException to arrive at this thread if self._wait_for_abort_exception: self._wait_for_abort_exception = False time.sleep(self._wait_for_abort_timeout) self.debug('Abort exception did not occured in pause for %ss.' \ 'Performing a Forced Abort.' % self._wait_for_abort_timeout) raise AbortException("Forced") if pauseit and self._resume_cb is not None: self._resume_cb(self.macro_obj) def isPaused(self): return not self._event.isSet() class Hookable(Logger): # avoid creating an __init__ def _getHooks(self): try: return self._hooks except: self._hooks = [] return self._hooks def _getHookHintsDict(self): try: return self._hookHintsDict except: self._hookHintsDict = {'_ALL_':[], '_NOHINTS_':[]} return self._hookHintsDict def getAllowedHookHints(self): return self.__class__.hints.get('allowsHooks') def getHints(self): return self._getHookHintsDict().keys() def getHooks(self, hint=None): '''This will return a list of hooks that have the given hint. Two reserved hints are always valid: - "_ALL_": which contains all the hooks - "_NOHINTS_": which contains the hooks that don't provide any hint :param hint: (str) a hint. If None is passed, it returns a list of (hook,hints) tuples :return: (list) an ordered list of hooks that have the given hint ''' if hint is None: return self._getHooks() else: return self._getHookHintsDict().get(hint,[]) @propertx def hooks(): def get(self): return self._getHooks() def set(self, hooks): '''hooks must be list>. Exceptionally, for backwards compatibility, list is also admitted, but may not be supported in the future. "two variables are created: - self._hooks (list>) (will be a tuple regardless of what was passed) - self._hookHintsDict (dict) a dict of key=hint and value=list of hooks with that hint. self._hookHintsDict also stores two special keys: "_ALL_": which contains all the hooks "_NOHINTS_": which contains the hooks that don't provide hints ''' if not isinstance(hooks, list): self.error('the hooks must be passed as a list>') return #store self._hooks, making sure it is of type: list> self._hooks = [] for h in hooks: if isinstance(h,(tuple, list)) and len(h)==2: self._hooks.append(h) else: #we assume that hooks is a list self._hooks.append((h,[])) self.info('Deprecation warning: hooks should be set with a list of hints. See Hookable API docs') #create _hookHintsDict self._getHookHintsDict()['_ALL_'] = zip(*self._hooks)[0] nohints = self._hookHintsDict['_NOHINTS_'] for hook,hints in self._hooks: if len(hints) == 0: nohints.append(hook) else: for hint in hints: try: self._hookHintsDict[hint].append(hook) except KeyError: self._hookHintsDict[hint] = [hook] return get,set class ExecMacroHook(object): """A speciallized callable hook for executing a sub macro inside another macro as a hook""" def __init__(self, parent_macro, *pars, **kwargs): self._macro_obj_wr = weakref.ref(parent_macro) self._pars = pars self._opts = kwargs @property def macro_obj(self): return self._macro_obj_wr() def __call__(self): self.macro_obj.execMacro(*self._pars, **self._opts) class MacroFinder: def __init__(self, macro_obj): self._macro_obj_wr = weakref.ref(macro_obj) @property def macro_obj(self): return self._macro_obj_wr() def __getattr__(self, name): def f(*args, **kwargs): p_m = self.macro_obj p_m.syncLog() opts = { 'parent_macro' : p_m, 'executor' : p_m.executor } kwargs.update(opts) eargs = [name] eargs.extend(args) return p_m.execMacro(*eargs, **kwargs) setattr(self, name, f) return f def mAPI(fn): """Wraps the given Macro method as being protected by the stop procedure. To be used by the :class:`Macro` as a decorator for all methods. :param: macro method :return: wrapped macro method""" @wraps(fn) def new_fn(*args, **kwargs): self = args[0] if not self.isProcessingStop(): is_macro_th = self._macro_thread == threading.current_thread() if self._shouldRaiseStopException(): if is_macro_th: self.setProcessingStop(True) raise StopException("stopped before calling %s" % fn.__name__) ret = fn(*args, **kwargs) if not self.isProcessingStop(): if self._shouldRaiseStopException(): if is_macro_th: self.setProcessingStop(True) raise StopException("stopped after calling %s" % fn.__name__) return ret return new_fn class macro(object): """Class designed to decorate a python function to transform it into a macro. Examples:: @macro() def my_macro1(self): self.output("Executing %s", self.getName()) @macro([ ["moveable", Type.Moveable, None, "motor to watch"] ]) def where_moveable(self, moveable): self.output("Moveable %s is at %s", moveable.getName(), moveable.getPosition())""" def __init__(self, param_def=None, result_def=None, env=None, hints=None, interactive=None): self.param_def = param_def self.result_def = result_def self.env = env self.hints = hints self.interactive = interactive def __call__(self, fn): fn.macro_data = {} fn.param_def = self.param_def fn.result_def = self.result_def fn.hints = self.env fn.env = self.hints fn.interactive = self.interactive return fn from functools import partial imacro = partial(macro, interactive=True) class Macro(Logger): """ The Macro base class. All macros should inherit directly or indirectly from this class.""" #: internal variable Init = State.Init #: internal variable Running = State.Running #: internal variable Pause = State.Standby #: internal variable Stop = State.Standby #: internal variable Fault = State.Fault #: internal variable Finished = State.On #: internal variable Ready = State.On #: internal variable Abort = State.Alarm #: Constant used to specify all elements in a parameter All = ParamType.All #: internal variable BlockStart = '' #: internal variable BlockFinish = '' #: This property holds the macro parameter description. #: It consists of a sequence of parameter information objects. #: A parameter information object is either: #: #: #. a simple parameter object #: #. a parameter repetition object #: #: A simple parameter object is a sequence of: #: #: #. a string representing the parameter name #: #. a member of :obj:`Macro.Type` representing the parameter data type #: #. a default value for the parameter or None if there is no default value #: #. a string with the parameter description #: #: Example:: #: #: param_def = ( ('value', Type.Float, None, 'a float parameter' ) ) #: #: A parameter repetition object is a sequence of: #: #: #. a string representing the parameter repetition name #: #. a sequence of parameter information objects #: #. a dictionary representing the parameter repetition semantics or None #: to use the default parameter repetition semantics. Dictionary keys are: #: #: * *min* - integer representing minimum number of repetitions or None #: for no minimum. #: * *max* - integer representing maximum number of repetitions or None #: for no maximum. #: #: Default parameter repetition semantics is ``{ 'min': 1, 'max' : None }`` #: (in other words, "at least one repetition" semantics) #: #: Example:: #: #: param_def = ( #: ( 'motor_list', ( ( 'motor', Type.Motor, None, 'motor name') ), None, 'List of motors') #: ) param_def = [] #: This property holds the macro result description. #: It a single parameter information object. #: #: .. seealso:: :obj:`~sardana.macroserver.macro.Macro.param_def` result_def = [] #: Hints to give a client to perform special tasks. #: Example: scan macros give hints on the types of hooks they support. A #: :term:`GUI` can use this information to allow a scan to have sub-macros #: executed as hooks. hints = {} #: a set of mandatory environment variable names without which your macro #: cannot run env = () #: decide if the macro should be able to receive input from the user #: [default: False]. A macro which asks input but has this flag set to False #: will print a warning message each time it is executed interactive = False def __init__(self, *args, **kwargs): """Constructor""" self._name = kwargs.get('as', self.__class__.__name__) self._in_pars = args self._out_pars = None self._aborted = False self._stopped = False self._processingStop = False self._parent_macro = kwargs.get('parent_macro') self._executor = kwargs.get('executor') self._macro_line = kwargs.get('macro_line') self._interactive_mode = kwargs.get('interactive', True) self._macro_thread = None self._id = kwargs.get('id') self._desc = "Macro '%s'" % self._macro_line self._macro_status = { 'id' : self._id, 'range' : (0.0, 100.0), 'state' : 'start', 'step' : 0.0 } self._pause_event = PauseEvent(self) log_parent = self.parent_macro or self.door Logger.__init__(self, "Macro[%s]" % self._name, log_parent) self._reserveObjs(args) ## @name Official Macro API # This list contains the set of methods that are part of the official macro # API. This means that they can be safely used inside any macro. #@{ #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Methods to be implemented by the actual macros #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def run(self, *args): """**Macro API**. Runs the macro. **Overwrite MANDATORY!** Default implementation raises RuntimeError. :raises: RuntimeError""" raise RuntimeError("Macro %s does not implement run method" % self.getName()) def prepare(self, *args, **kwargs): """**Macro API**. Prepare phase. Overwrite as necessary. Default implementation does nothing""" pass def on_abort(self): """**Macro API**. Hook executed when an abort occurs. Overwrite as necessary. Default implementation does nothing""" pass def on_pause(self): """**Macro API**. Hook executed when a pause occurs. Overwrite as necessary. Default implementation does nothing""" pass def on_stop(self): """**Macro API**. Hook executed when a stop occurs. Overwrite as necessary. Default implementation calls :meth:`~Macro.on_abort`""" return self.on_abort() #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # API #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def checkPoint(self): """**Macro API**. Empty method that just performs a checkpoint. This can be used to check for the stop. Usually you won't need to call this method""" pass @mAPI def pausePoint(self, timeout=None): """**Macro API**. Will establish a pause point where called. If an external source as invoked a pause then, when this this method is called, it will be block until the external source calls resume. You may want to call this method if your macro takes a considerable time to execute and you may whish to pause it at some time. Example:: for i in range(10000): time.sleep(0.1) self.output("At step %d/10000", i) self.pausePoint() :param timeout: timeout in seconds [default: None, meaning wait forever] :type timeout: :obj:`float`""" return self._pausePoint(timeout=timeout) @property def macros(self): """**Macro API**. An object that contains all macro classes as members. With the returning object you can invoke other macros. Example:: m = self.macros.ascan('th', '0', '90', '10', '2') scan_data = m.data""" self.checkPoint() if not hasattr(self, '_macros'): self._macros = MacroFinder(self) return self._macros @mAPI def getMacroStatus(self): """**Macro API**. Returns the current macro status. Macro status is a :obj:`dict` where keys are the strings: * *id* - macro ID (internal usage only) * *range* - the full progress range of a macro (usually a :obj:`tuple` of two numbers (0, 100)) * *state* - the current macro state, a string which can have values *start*, *step*, *stop* and *abort* * *step* - the current step in macro. Should be a value inside the allowed macro range :return: the macro status :rtype: :obj:`dict`""" return self._macro_status @mAPI def getName(self): """**Macro API**. Returns this macro name :return: the macro name :rtype: :obj:`str`""" return self._name @mAPI def getID(self): """**Macro API**. Returns this macro id :return: the macro id :rtype: :obj:`str`""" return self._id @mAPI def getParentMacro(self): """**Macro API**. Returns the parent macro reference. :return: the parent macro reference or None if there is no parent macro :rtype: :class:`~sardana.macroserver.macro.Macro`""" return self._parent_macro @mAPI def getDescription(self): """**Macro API**. Returns a string description of the macro. :return: the string description of the macro :rtype: :obj:`str`""" return self._desc @mAPI def getParameters(self): """**Macro API**. Returns a the macro parameters. It returns a list containning the parameters with which the macro was executed :return: the macro parameters :rtype: :obj:`list`""" return self._in_pars @mAPI def getExecutor(self): """**Macro API**. Returns the reference to the object that invoked this macro. Usually is a MacroExecutor object. :return: the reference to the object that invoked this macro :rtype: :class:`~sardana.macroserver.macromanager.MacroExecutor`""" return self._executor @mAPI def getDoorObj(self): """**Macro API**. Returns the reference to the Door that invoked this macro. :return: the reference to the Door that invoked this macro. :rype: :class:`~sardana.macroserver.door.Door`""" return self.executor.getDoor() @mAPI def getManager(self): """**Macro API**. Returns the manager for this macro (usually a MacroServer) :return: the MacroServer :rtype: :class:`~sardana.macroserver.macroserver.MacroServer`""" return self.door.manager manager = property(getManager) @mAPI def getMacroServer(self): """**Macro API**. Returns the MacroServer for this macro :return: the MacroServer :rtype: :class:`~sardana.macroserver.macroserver.MacroServer`""" return self.door.macro_server macro_server = property(getMacroServer) @mAPI def getDoorName(self): """**Macro API**. Returns the string with the name of the Door that invoked this macro. :return: the string with the name of the Door that invoked this macro. :rtype: :obj:`str`""" return self.door.name @mAPI def getCommand(self): """**Macro API**. Returns the string used to execute the macro. Ex.: 'ascan M1 0 1000 100 0.8' :return: the macro command. :rtype: :obj:`str`""" return '%s %s' % (self.getName(), ' '.join([str(p) for p in self._in_pars])) @mAPI def getDateString(self, time_format='%a %b %d %H:%M:%S %Y'): """**Macro API**. Helper method. Returns the current date in a string. :param time_format: the format in which the date should be returned (optional, default value is '%a %b %d %H:%M:%S %Y' :type time_format: :obj:`str` :return: the current date :rtype: :obj:`str`""" return time.strftime(time_format) @mAPI def outputDate(self, time_format='%a %b %d %H:%M:%S %Y'): """**Macro API**. Helper method. Outputs the current date into the output buffer :param time_format: (str) the format in which the date should be returned (optional, default value is '%a %b %d %H:%M:%S %Y' :type time_format: :obj:`str`""" self.output(self.getDateString(time_format=time_format)) @mAPI def sendRecordData(self, data, codec=None): """**Macro API**. Sends the given data to the RecordData attribute of the Door :param data: (sequence) the data to be sent""" self.executor.sendRecordData(data, codec=codec) @mAPI def plot(self, *args, **kwargs): """**Macro API**. Sends the plot command to the client using the 'RecordData' DevEncoded attribute. The data is encoded using the pickle -> BZ2 codec. :param args: the plotting args :param kwargs: the plotting keyword args""" self.pyplot.plot(*args, **kwargs) # data = dict(args=args, kwargs=kwargs) # self.sendRecordData(data, codec='bz2_pickle_plot') @property @mAPI def pylab(self): try: pylab = self._pylab except AttributeError: self._pylab = pylab = self.door.pylab return pylab @property @mAPI def pyplot(self): try: pyplot = self._pyplot except AttributeError: self._pyplot = pyplot = self.door.pyplot return pyplot @mAPI def getData(self): """**Macro API**. Returns the data produced by the macro. :raises: Exception if no data has been set before on this macro :return: the data produced by the macro :rtype: object""" if not hasattr(self, "_data"): raise Exception("Macro '%s' does not produce any data" % self.getName()) return self._data @mAPI def setData(self, data): """**Macro API**. Sets the data for this macro :param object data: new data to be associated with this macro""" self._data = data data = property(getData, setData, doc="macro data") @mAPI def print(self, *args, **kwargs): """**Macro API**. Prints a message. Accepted *args* and *kwargs* are the same as :func:`print`. Example:: self.print("this is a print for macro", self.getName()) .. note:: you will need python >= 3.0. If you have python 2.x then you must include at the top of your file the statement:: from __future__ import print_function """ fd = kwargs.get('file', sys.stdout) if fd in (sys.stdout, sys.stderr): out = StringIO.StringIO() kwargs['file'] = out end = kwargs.get('end', '\n') if end == '\n': kwargs['end'] = '' ret = print(*args, **kwargs) self.output(out.getvalue()) else: ret = print(*args, **kwargs) return ret @mAPI def input(self, msg, *args, **kwargs): """**Macro API**. If args is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. Depending on which type of application you are running, some of the keywords may have no effect (ex.: spock ignores decimals when a number is asked). Recognized kwargs: - data_type : [default: Type.String] specific input type. Can also specify a sequence of strings with possible values (use allow_multiple=True to say multiple values can be selected) - key : [default: no default] variable/label to assign to this input - unit: [default: no default] units (useful for GUIs) - timeout : [default: None, meaning wait forever for input] - default_value : [default: None, meaning no default value] When given, it must be compatible with data_type - allow_multiple : [default: False] in case data_type is a sequence of values, allow multiple selection - minimum : [default: None] When given, must be compatible with data_type (useful for GUIs) - maximum : [default: None] When given, must be compatible with data_type (useful for GUIs) - step : [default: None] When given, must be compatible with data_type (useful for GUIs) - decimals : [default: None] When given, must be compatible with data_type (useful for GUIs) Examples:: device_name = self.input("Which device name (%s)?", "tab separated") point_nb = self.input("How many points?", data_type=Type.Integer) calc_mode = self.input("Which algorithm?", data_type=["Average", "Integral", "Sum"], default_value="Average", allow_multiple=False)""" if not self.interactive: self.warning("Non interactive macro '%s' is asking for input " "(please set this macro interactive to True)", self.getName()) if self._interactive_mode: kwargs['data_type'] = kwargs.get('data_type', Type.String) kwargs['allow_multiple'] = kwargs.get('allow_multiple', False) kwargs['macro_id'] = self.getID() kwargs['macro_name'] = self.getName() kwargs['macro'] = self return self.getDoorObj().input(msg, *args, **kwargs) else: if 'default_value' not in kwargs: if 'key' not in kwargs: self.warning("%s running in non attended mode was asked " "for input without default value or key. " "Returning None") return None else: return self.getEnv(kwargs['key']) return kwargs['default_value'] @mAPI def output(self, msg, *args, **kwargs): """**Macro API**. Record a log message in this object's output. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.log`. Example:: self.output("this is a print for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.output(self, msg, *args, **kwargs) @mAPI def log(self, level, msg, *args, **kwargs): """**Macro API**. Record a log message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.log`. Example:: self.debug(logging.INFO, "this is a info log message for macro %s", self.getName()) :param level: the record level :type level: :obj:`int` :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.log(self, level, msg, *args, **kwargs) @mAPI def debug(self, msg, *args, **kwargs): """**Macro API**. Record a debug message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.debug`. Example:: self.debug("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kw: list of keyword arguments""" return Logger.debug(self, msg, *args, **kwargs) @mAPI def info(self, msg, *args, **kwargs): """**Macro API**. Record an info message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.info`. Example:: self.info("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.info(self, msg, *args, **kwargs) @mAPI def warning(self, msg, *args, **kwargs): """**Macro API**. Record a warning message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.warning`. Example:: self.warning("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.warning(self, msg, *args, **kwargs) @mAPI def error(self, msg, *args, **kwargs): """**Macro API**. Record an error message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.error`. Example:: self.error("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments """ return Logger.error(self, msg, *args, **kwargs) @mAPI def critical(self, msg, *args, **kwargs): """**Macro API**. Record a critical message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.critical`. Example:: self.critical("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.critical(self, msg, *args, **kwargs) @mAPI def trace(self, msg, *args, **kwargs): """**Macro API**. Record a trace message in this object's logger. :param msg: (str) the message to be recorded :param args: list of arguments :param kw: list of keyword arguments""" return Logger.trace(self, msg, *args, **kwargs) @mAPI def traceback(self, *args, **kwargs): """**Macro API**. Logs the traceback with level TRACE on the macro logger.""" return Logger.traceback(self, *args, **kwargs) @mAPI def stack(self, *args, **kwargs): """**Macro API**. Logs the stack with level TRACE on the macro logger.""" return Logger.stack(self, *args, **kwargs) @mAPI def report(self, msg, *args, **kwargs): """**Macro API**. Record a log message in the sardana report (if enabled) with default level **INFO**. The msg is the message format string, and the args are the arguments which are merged into msg using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) *kwargs* are the same as :meth:`logging.Logger.debug` plus an optional level kwargs which has default value **INFO** Example:: self.report("this is an official report of macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return self.getDoorObj().report(msg, *args, **kwargs) @mAPI def flushOutput(self): """**Macro API**. Flushes the output buffer.""" return Logger.flushOutput(self) @mAPI def getMacroThread(self): """**Macro API**. Returns the python thread where this macro is running :return: the python thread where this macro is running :rtype: threading.Thread""" return self._macro_thread @mAPI def getMacroThreadID(self): """**Macro API**. Returns the python thread id where this macro is running :return: the python thread id where this macro is running :rtype: :obj:`int`""" return self.getMacroThread().ident #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Hook helper API #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def createExecMacroHook(self, par_str_sequence, parent_macro=None): """**Macro API**. Creates a hook that executes the macro given as a sequence of strings where the first string is macro name and the following strings the macro parameters :param par_str_sequence: the macro parameters :param parent_macro: the parent macro object. If None is given (default) then the parent macro is this macro :return: a ExecMacroHook object (which is a callable object)""" return ExecMacroHook(parent_macro or self, par_str_sequence) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Handle child macro execution #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def createMacro(self, *pars): """**Macro API**. Create a new macro and prepare it for execution Several different parameter formats are supported:: # several parameters: self.createMacro('ascan', 'th', '0', '100', '10', '1.0') self.createMacro('ascan', 'th', 0, 100, 10, 1.0) th = self.getObj('th') self.createMacro('ascan', th, 0, 100, 10, 1.0) # a sequence of parameters: self.createMacro(['ascan', 'th', '0', '100', '10', '1.0') self.createMacro(('ascan', 'th', 0, 100, 10, 1.0)) th = self.getObj('th') self.createMacro(['ascan', th, 0, 100, 10, 1.0]) # a space separated string of parameters: self.createMacro('ascan th 0 100 10 1.0') :param pars: the command parameters as explained above :return: a sequence of two elemetns: the macro class and a sequence of parameters :rtype: :obj:`tuple`\<:class:`~sardana.macroserver.macro.Macro`\, seq> """ return self.prepareMacro(*pars) @mAPI def prepareMacroObj(self, macro_name_or_klass, *args, **kwargs): """**Macro API**. Prepare a new macro for execution :param macro_name_or_klass name: name of the macro to be prepared or the macro class itself :param pars: list of parameter objects :param init_opts: keyword parameters for the macro constructor :param prepare_opts: keyword parameters for the macro prepare :return: a sequence of two elements: the macro object and the result of preparing the macro""" # sync our log before calling the child macro prepare in order to avoid # mixed outputs between this macro and the child macro self.syncLog() init_opts = { 'parent_macro' : self } return self.executor.prepareMacroObj(macro_name_or_klass, args, init_opts, kwargs) @mAPI def prepareMacro(self, *args, **kwargs): """**Macro API**. Prepare a new macro for execution Several different parameter formats are supported:: # several parameters: executor.prepareMacro('ascan', 'th', '0', '100', '10', '1.0') executor.prepareMacro('ascan', 'th', 0, 100, 10, 1.0) th = self.getObj('th') executor.prepareMacro('ascan', th, 0, 100, 10, 1.0) # a sequence of parameters: executor.prepareMacro(['ascan', 'th', '0', '100', '10', '1.0') executor.prepareMacro(('ascan', 'th', 0, 100, 10, 1.0)) th = self.getObj('th') executor.prepareMacro(['ascan', th, 0, 100, 10, 1.0]) # a space separated string of parameters: executor._prepareMacro('ascan th 0 100 10 1.0') :param args: the command parameters as explained above :param kwargs: keyword optional parameters for prepare :return: a sequence of two elements: the macro object and the result of preparing the macro""" # sync our log before calling the child macro prepare in order to avoid # mixed outputs between this macro and the child macro self.syncLog() init_opts = { 'parent_macro' : self } return self.executor.prepareMacro(args, init_opts, kwargs) @mAPI def runMacro(self, macro_obj): """**Macro API**. Runs the macro. This the lower level version of :meth:`~sardana.macroserver.macro.Macro.execMacro`. The method only returns after the macro is completed or an exception is thrown. It should be used instead of execMacro when some operation needs to be done between the macro preparation and the macro execution. Example:: macro = self.prepareMacro("mymacro", "myparam") self.do_my_stuff_with_macro(macro) self.runMacro(macro) :param macro_obj: macro object :return: the output of the macro""" # sync our log before calling the child macro prepare in order to avoid # mixed outputs between this macro and the child macro self.syncLog() return self.executor.runMacro(macro_obj) @mAPI def execMacroObj(self, name, *args, **kwargs): """**Macro API**. Execute a macro in this macro. The method only returns after the macro is completed or an exception is thrown. This is a higher level version of runMacro method. It is the same as:: macro = self.prepareMacroObjs(name, *args, **kwargs) self.runMacro(macro) return macro :param name: name of the macro to be prepared :type name: str :param args: list of parameter objects :param kwargs: list of keyword parameters :return: a macro object""" self.debug("Executing macro: %s" % name) macro_obj, prepare_result = self.prepareMacroObj(name, *args, **kwargs) self.runMacro(macro_obj) return macro_obj @mAPI def execMacro(self, *args, **kwargs): """**Macro API**. Execute a macro in this macro. The method only returns after the macro is completed or an exception is thrown. Several different parameter formats are supported:: # several parameters: self.execMacro('ascan', 'th', '0', '100', '10', '1.0') self.execMacro('ascan', 'th', 0, 100, 10, 1.0) th = self.getObj('th') self.execMacro('ascan', th, 0, 100, 10, 1.0) # a sequence of parameters: self.execMacro(['ascan', 'th', '0', '100', '10', '1.0') self.execMacro(('ascan', 'th', 0, 100, 10, 1.0)) th = self.getObj('th') self.execMacro(['ascan', th, 0, 100, 10, 1.0]) # a space separated string of parameters: self.execMacro('ascan th 0 100 10 1.0') :param pars: the command parameters as explained above :return: a macro object""" par0 = args[0] if len(args) == 1: if type(par0) in types.StringTypes : args = par0.split() elif operator.isSequenceType(par0): args = par0 args = map(str, args) self.debug("Executing macro: %s" % args[0]) macro_obj, prepare_result = self.prepareMacro(*args, **kwargs) self.runMacro(macro_obj) return macro_obj #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # taurus helpers #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def getTangoFactory(self): """**Macro API**. Helper method that returns the tango factory. :return: the tango factory singleton :rtype: :class:`~taurus.core.tango.TangoFactory`""" import taurus return taurus.Factory() @mAPI def getDevice(self, dev_name): """**Macro API**. Helper method that returns the device for the given device name :return: the taurus device for the given device name :rtype: :class:`~taurus.core.TaurusDevice`""" import taurus return taurus.Device(dev_name) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Handle parameter objects #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def setLogBlockStart(self): """**Macro API**. Specifies the begining of a block of data. Basically it outputs the 'BLOCK' tag""" self.output(Macro.BlockStart) @mAPI def setLogBlockFinish(self): """**Macro API**. Specifies the end of a block of data. Basically it outputs the '/BLOCK' tag""" self.output(Macro.BlockFinish) @mAPI def outputBlock(self, line): """**Macro API**. Sends an line tagged as a block to the output :param str line: line to be sent""" if isinstance(line, (str, unicode)): o = line elif operator.isSequenceType(line): o = "\n".join(line) else: o = str(line) self.output("%s\n%s\n%s" % (Macro.BlockStart, o, Macro.BlockFinish)) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Handle parameter objects #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def getPools(self): """**Macro API**. Returns the list of known device pools. :return: the list of known device pools :rtype: seq""" return self.door.get_pools() #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Handle parameter objects #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def addObj(self, obj, priority=0): """**Macro API**. Adds the given object to the list of controlled objects of this macro. In practice it means that if a stop is executed the stop method of the given object will be called. :param obj: the object to be controlled :type obj: object :param priority: wheater or not reserve with priority [default: 0 meaning no priority ] :type priority: :obj:`int`""" self.executor.reserveObj(obj, self, priority=priority) @mAPI def addObjs(self, obj_list): """**Macro API**. Adds the given objects to the list of controlled objects of this macro. In practice it means that if a stop is executed the stop method of the given object will be called. :param obj_list: list of objects to be controlled :type obj_list: sequence""" for o in obj_list: self.addObj(o) def returnObj(self, obj): """Removes the given objects to the list of controlled objects of this macro. :param obj: object to be released from the control :rtype: object""" self.executor.returnObj(obj) @mAPI def getObj(self, name, type_class=All, subtype=All, pool=All, reserve=True): """**Macro API**. Gets the object of the given type belonging to the given pool with the given name. The object (if found) will automatically become controlled by the macro. :raises: MacroWrongParameterType if name is not a string :raises: AttributeError if more than one matching object is found :param name: string representing the name of the object. Can be a regular expression :type name: :obj:`str` :param type_class: the type of object [default: All] :param subtype: a string representing the subtype [default: All] Ex.: if type_class is Type.ExpChannel, subtype could be 'CTExpChannel' :param pool: the pool to which the object should belong [default: All] :param reserve: automatically reserve the object for this macro [default: True] :return: the object or None if no compatible object is found""" if not isinstance(name, (str, unicode)): raise self._buildWrongParamExp("getObj", "name", "string", str(type(name))) obj = self.door.get_object(name, type_class=type_class, subtype=subtype, pool=pool) if obj and reserve: self.addObj(obj) return obj @mAPI def getObjs(self, names, type_class=All, subtype=All, pool=All, reserve=True): """**Macro API**. Gets the objects of the given type belonging to the given pool with the given names. The objects (if found) will automatically become controlled by the macro. :param names: a string or a sequence of strings representing the names of the objects. Each string can be a regular expression :param type_class: the type of object (optional, default is All). Example: Type.Motor, Type.ExpChannel :param subtype: a string representing the subtype (optional, default is All) Ex.: if type_class is Type.ExpChannel, subtype could be 'CTExpChannel' :param pool: the pool to which the object should belong (optional, default is All) :param reserve: automatically reserve the object for this macro (optional, default is True) :return: a list of objects or empty list if no compatible object is found""" obj_list = self.door.get_objects(names, type_class=type_class, subtype=subtype, pool=pool) if reserve: self.addObjs(obj_list) return obj_list or [] @mAPI def findObjs(self, names, type_class=All, subtype=All, pool=All, reserve=True): """**Macro API**. Gets the objects of the given type belonging to the given pool with the given names. The objects (if found) will automatically become controlled by the macro. :param names: a string or a sequence of strings representing the names of the objects. Each string can be a regular expression :param type_class: the type of object (optional, default is All) :param subtype: a string representing the subtype [default: All] Ex.: if type_class is Type.ExpChannel, subtype could be 'CTExpChannel' :param pool: the pool to which the object should belong [default: All] :param reserve: automatically reserve the object for this macro [default: True] :return: a list of objects or empty list if no compatible object is found""" obj_list = self.door.find_objects(names, type_class=type_class, subtype=subtype, pool=pool) if reserve: self.addObjs(obj_list) return obj_list @mAPI def getMacroNames(self): """**Macro API**. Returns a list of strings containing the names of all known macros :return: a sequence of macro names :rtype: seq<:obj:`str`\>""" return self.door.get_macro_names() @mAPI def getMacros(self, filter=None): """**Macro API**. Returns a sequence of :class:`~sardana.macroserver.msmetamacro.MacroClass` /:class:`~sardana.macroserver.msmetamacro.MacroFunction` objects for all known macros that obey the filter expression. :param filter: a regular expression for the macro name (optional, default is None meaning match all macros) :return: a sequence of :class:`~sardana.macroserver.msmetamacro.MacroClass` /:class:`~sardana.macroserver.msmetamacro.MacroFunction` objects :rtype: seq<:class:`~sardana.macroserver.msmetamacro.MacroClass` /:class:`~sardana.macroserver.msmetamacro.MacroFunction`\>""" ret = self.door.get_macros(filter=filter).values() ret.sort() return ret @mAPI def getMacroLibraries(self, filter=None): """**Macro API**. Returns a sequence of :class:`~sardana.macroserver.msmetamacro.MacroLibrary` objects for all known macros that obey the filter expression. :param filter: a regular expression for the macro library [default: None meaning match all macro libraries) :return: a sequence of :class:`~sardana.macroserver.msmetamacro.MacroLibrary` objects :rtype: seq<:class:`~sardana.macroserver.msmetamacro.MacroLibrary`\>""" ret = self.door.get_macro_libs(filter=filter).values() ret.sort() return ret @mAPI def getMacroLibrary(self, lib_name): """**Macro API**. Returns a :class:`~sardana.macroserver.msmetamacro.MacroLibrary` object for the given library name. :param lib_name: library name :type lib_name: str :return: a macro library :class:`~sardana.macroserver.msmetamacro.MacroLibrary` :rtype: :class:`~sardana.macroserver.msmetamacro.MacroLibrary`""" ret = self.door.get_macro_lib(lib_name) return ret getMacroLib = getMacroLibrary getMacroLibs = getMacroLibraries @mAPI def getMacroInfo(self, macro_name): """**Macro API**. Returns the corresponding :class:`~sardana.macroserver.msmetamacro.MacroClass` /:class:`~sardana.macroserver.msmetamacro.MacroFunction` object. :param macro_name: a string with the desired macro name. :type macro_name: :obj:`str` :return: a :class:`~sardana.macroserver.msmetamacro.MacroClass` /:class:`~sardana.macroserver.msmetamacro.MacroFunction` object or None if the macro with the given name was not found :rtype: :class:`~sardana.macroserver.msmetamacro.MacroClass` /:class:`~sardana.macroserver.msmetamacro.MacroFunction`""" return self.door.get_macro(macro_name) @mAPI def getMotion(self, elems, motion_source=None, read_only=False, cache=True): """**Macro API**. Returns a new Motion object containing the given elements. :raises: Exception if no elements are defined or the elems is not recognized as valid, or an element is not found or an element appears more than once :param elems: list of moveable object names :param motion_source: obj or list of objects containing moveable elements. Usually this is a Pool object or a list of Pool objects (optional, default is None, meaning all known pools will be searched for the given moveable items :param read_only: not used. Reserved for future use :param cache: not used. Reserved for future use :return: a Motion object """ decoupled=False try: decoupled = self.getEnv("MotionDecoupled") except UnknownEnv: pass motion = self.door.get_motion(elems, motion_source=motion_source, read_only=read_only, cache=cache, decoupled=decoupled) if motion is not None: self.addObj(motion, priority=1) return motion @mAPI def getElementsWithInterface(self, interface): return self.door.get_elements_with_interface(interface) @mAPI def getControllers(self): return self.door.get_controllers() @mAPI def getMoveables(self): return self.door.get_moveables() @mAPI def getMotors(self): return self.door.get_motors() @mAPI def getPseudoMotors(self): return self.door.get_pseudo_motors() @mAPI def getIORegisters(self): return self.door.get_io_registers() @mAPI def getMeasurementGroups(self): return self.door.get_measurement_groups() @mAPI def getExpChannels(self): return self.door.get_exp_channels() @mAPI def getCounterTimers(self): return self.door.get_counter_timers() @mAPI def get0DExpChannels(self): return self.door.get_0d_exp_channels() @mAPI def get1DExpChannels(self): return self.door.get_1d_exp_channels() @mAPI def get2DExpChannels(self): return self.door.get_2d_exp_channels() @mAPI def getPseudoCounters(self): return self.door.get_pseudo_counters() @mAPI def getInstruments(self): return self.door.get_instruments() @mAPI def getElementWithInterface(self, interface, name): return self.door.get_element_with_interface(interface, name) @mAPI def getController(self, name): return self.door.get_controller(name) @mAPI def getMoveable(self, name): return self.door.get_moveable(name) @mAPI def getMotor(self, name): return self.door.get_motor(name) @mAPI def getPseudoMotor(self, name): return self.door.get_pseudo_motor(name) @mAPI def getIORegister(self, name): return self.door.get_io_register(name) @mAPI def getMeasurementGroup(self, name): return self.door.get_measurement_group(name) @mAPI def getExpChannel(self, name): return self.door.get_exp_channel(name) @mAPI def getCounterTimer(self, name): return self.door.get_counter_timer(name) @mAPI def get0DExpChannel(self, name): return self.door.get_0d_exp_channel(name) @mAPI def get1DExpChannel(self, name): return self.door.get_1d_exp_channel(name) @mAPI def get2DExpChannel(self, name): return self.door.get_2d_exp_channel(name) @mAPI def getPseudoCounter(self, name): return self.door.get_pseudo_counter(name) @mAPI def getInstrument(self, name): return self.door.get_instrument(name) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Handle macro environment #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def getEnv(self, key=None, macro_name=None, door_name=None): """**Macro API**. Gets the local environment matching the given parameters: - door_name and macro_name define the context where to look for the environment. If both are None, the global environment is used. If door name is None but macro name not, the given macro environment is used and so on... - If key is None it returns the complete environment, otherwise key must be a string containing the environment variable name. :raises: UnknownEnv :param key: environment variable name [default: None, meaning all environment] :type key: str :param door_name: local context for a given door [default: None, meaning no door context is used] :type door_name: str :param macro_name: local context for a given macro [default: None, meaning no macro context is used] :type macro_name: str :return: a :obj:`dict` containing the environment :rtype: :obj:`dict`""" door_name = door_name or self.getDoorName() macro_name = macro_name or self._name return self.macro_server.get_env(key=key, macro_name=macro_name, door_name=door_name) @mAPI def getGlobalEnv(self): """**Macro API**. Returns the global environment. :return: a :obj:`dict` containing the global environment :rtype: :obj:`dict`""" return self.macro_server.get_env() @mAPI def getAllEnv(self): """**Macro API**. Returns the enviroment for the macro. :return: a :obj:`dict` containing the environment for the macro :rtype: :obj:`dict`""" return self.getEnv(None) @mAPI def getAllDoorEnv(self): """**Macro API**. Returns the enviroment for the door where the macro is running. :return: a :obj:`dict` containing the environment :rtype: :obj:`dict`""" return self.door.get_env() @mAPI def setEnv(self, key, value): """**Macro API**. Sets the environment key to the new value and stores it persistently. :return: a :obj:`tuple` with the key and value objects stored :rtype: :obj:`tuple`\<:obj:`str`\, object>""" return self.door.set_env(key, value) @mAPI def unsetEnv(self, key): """**Macro API**. Unsets the given environment variable. :param key: the environment variable name :type key: :obj:`str`""" return self.macro_server.unset_env(key) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Reload API #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @mAPI def reloadLibrary(self, lib_name): """**Macro API**. Reloads the given library(=module) names :raises: ImportError in case the reload process is not successfull :param lib_name: library(=module) name :type lib_name: :obj:`str` :return: the reloaded python module object""" return self.door.reload_lib(lib_name) @mAPI def reloadMacro(self, macro_name): """**Macro API**. Reloads the module corresponding to the given macro name :raises: MacroServerExceptionList in case the macro is unknown or the reload process is not successfull :param macro_name: macro name :type macro_name: :obj:`str`""" return self.door.reload_macro(macro_name) @mAPI def reloadMacros(self, macro_names): """**Macro API**. Reloads the modules corresponding to the given macro names. :raises: MacroServerExceptionList in case the macro(s) are unknown or the reload process is not successfull :param macro_names: a list of macro names :type macro_names: sequence<:obj:`str`\>""" return self.reload_macros(macro_names) @mAPI def reloadMacroLibrary(self, lib_name): """**Macro API**. Reloads the given library(=module) names :raises: MacroServerExceptionList in case the reload process is not successfull :param lib_name: library(=module) name :type lib_name: :obj:`str` :return: the :class:`~sardana.macroserver.metamacro.MacroLibrary` for the reloaded library :rtype: :class:`~sardana.macroserver.metamacro.MacroLibrary`""" return self.door.reload_macro_lib(lib_name) @mAPI def reloadMacroLibraries(self, lib_names): """**Macro API**. Reloads the given library(=module) names :raises: MacroServerExceptionList in case the reload process is not successfull for at least one lib param lib_names: a list of library(=module) names :type lib_name: seq<:obj:`str`\> :return: a sequence of :class:`~sardana.macroserver.metamacro.MacroLibrary` objects for the reloaded libraries :rtype: seq<:class:`~sardana.macroserver.metamacro.MacroLibrary`\>""" return self.door.reload_macro_libs(lib_names) reloadMacroLib = reloadMacroLibrary reloadMacroLibs = reloadMacroLibraries @mAPI def getViewOption(self, name): return self._getViewOptions()[name] @mAPI def getViewOptions(self): return self._getViewOptions() @mAPI def setViewOption(self, name, value): vo = self._getViewOptions() vo[name] = value self.setEnv('_ViewOptions', vo) @mAPI def resetViewOption(self, name): vo = self._getViewOptions() ViewOption.reset_option(vo, name) self.setEnv('_ViewOptions', vo) return vo.get(name) #@} ## @name Unofficial Macro API # This list contains the set of methods that are NOT part of the # the macro developer knows what he is doing. # Please check before is there is an official API that does the samething # before executing any of these methods. # If you see that your macro needs to execute any of these methods please # consider informing the MacroServer developer so he may expose this in a # safe way. #@{ def _getViewOptions(self): try: vo = self.getEnv('_ViewOptions') except UnknownEnv: import msoptions vo = ViewOption.init_options(dict()) self.setEnv('_ViewOptions', vo) return vo def _input(self, msg, *args, **kwargs): """**Unofficial Macro API**. If args is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. Depending on which type of application you are running, some of the keywords may have no effect (ex.: spock ignores decimals when a number is asked). Recognized kwargs: - data_type : [default: Type.String] specific input type. Can also specify a sequence of strings with possible values (use allow_multiple=True to say multiple values can be selected) - key : [default: no default] variable/label to assign to this input - unit: [default: no default] units (useful for GUIs) - timeout : [default: None, meaning wait forever for input] - default_value : [default: None, meaning no default value] When given, it must be compatible with data_type - allow_multiple : [default: False] in case data_type is a sequence of values, allow multiple selection - minimum : [default: None] When given, must be compatible with data_type (useful for GUIs) - maximum : [default: None] When given, must be compatible with data_type (useful for GUIs) - step : [default: None] When given, must be compatible with data_type (useful for GUIs) - decimals : [default: None] When given, must be compatible with data_type (useful for GUIs) Examples:: device_name = self.input("Which device name (%s)?", "tab separated") point_nb = self.input("How many points?", data_type=Type.Integer) calc_mode = self.input("Which algorithm?", data_type=["Average", "Integral", "Sum"], default_value="Average", allow_multiple=False)""" if not self.interactive: self.warning("Non interactive macro '%s' is asking for input " "(please set this macro interactive to True)", self.getName()) if self._interactive_mode: kwargs['data_type'] = kwargs.get('data_type', Type.String) kwargs['allow_multiple'] = kwargs.get('allow_multiple', False) kwargs['macro_id'] = self.getID() kwargs['macro_name'] = self.getName() kwargs['macro'] = self return self.getDoorObj().input(msg, *args, **kwargs) else: if 'default_value' not in kwargs: if 'key' not in kwargs: self.warning("%s running in non attended mode was asked " "for input without default value or key. " "Returning None") return None else: return self.getEnv(kwargs['key']) return kwargs['default_value'] def _output(self, msg, *args, **kwargs): """**Macro API**. Record a log message in this object's output. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.log`. Example:: self.output("this is a print for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.output(self, msg, *args, **kwargs) def _log(self, level, msg, *args, **kwargs): """**Unofficial Macro API**. Record a log message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.log`. Example:: self.debug(logging.INFO, "this is a info log message for macro %s", self.getName()) :param level: the record level :type level: :obj:`int` :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.log(self, level, msg, *args, **kwargs) def _debug(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record a debug message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.debug`. Example:: self.debug("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kw: list of keyword arguments""" return Logger.debug(self, msg, *args, **kwargs) def _info(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record an info message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.info`. Example:: self.info("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.info(self, msg, *args, **kwargs) @mAPI def _warning(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record a warning message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.warning`. Example:: self.warning("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.warning(self, msg, *args, **kwargs) def _error(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record an error message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.error`. Example:: self.error("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments """ return Logger.error(self, msg, *args, **kwargs) def _critical(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record a critical message in this object's logger. Accepted *args* and *kwargs* are the same as :meth:`logging.Logger.critical`. Example:: self.critical("this is a log message for macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return Logger.critical(self, msg, *args, **kwargs) def _trace(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record a trace message in this object's logger. :param msg: (str) the message to be recorded :param args: list of arguments :param kw: list of keyword arguments""" return Logger.trace(self, msg, *args, **kwargs) def _traceback(self, *args, **kwargs): """**Unofficial Macro API**. Logs the traceback with level TRACE on the macro logger.""" return Logger.traceback(self, *args, **kwargs) def _stack(self, *args, **kwargs): """**Unofficial Macro API**. Logs the stack with level TRACE on the macro logger.""" return Logger.stack(self, *args, **kwargs) def _report(self, msg, *args, **kwargs): """**Unofficial Macro API**. Record a log message in the sardana report (if enabled) with default level **INFO**. The msg is the message format string, and the args are the arguments which are merged into msg using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) *kwargs* are the same as :meth:`logging.Logger.debug` plus an optional level kwargs which has default value **INFO** Example:: self.report("this is an official report of macro %s", self.getName()) :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return self.door.report(msg, *args, **kwargs) @property def executor(self): """**Unofficial Macro API**. Alternative to :meth:`getExecutor` that does not throw StopException in case of a Stop. This should be called only internally""" return self._executor @property def door(self): """**Unofficial Macro API**. Alternative to :meth:`getDoorObj` that does not throw StopException in case of a Stop. This should be called only internally""" return self.executor.getDoor() @property def parent_macro(self): """**Unofficial Macro API**. Alternative to getParentMacro that does not throw StopException in case of a Stop. This should be called only internally by the *Executor*""" return self._parent_macro @property def description(self): """**Unofficial Macro API**. Alternative to :meth:`getDescription` that does not throw StopException in case of a Stop. This should be called only internally by the *Executor*""" return self._desc def isAborted(self): """**Unofficial Macro API**.""" return self._aborted def isStopped(self): """**Unofficial Macro API**.""" return self._stopped def isPaused(self): """**Unofficial Macro API**.""" return self._pause_event.isPaused() @classmethod def hasResult(cls): """**Unofficial Macro API**. Returns True if the macro should return a result or False otherwise :return: True if the macro should return a result or False otherwise :rtype: bool """ return len(cls.result_def) > 0 def getResult(self): """**Unofficial Macro API**. Returns the macro result object (if any) :return: the macro result object or None""" return self._out_pars def setResult(self, result): """**Unofficial Macro API**. Sets the result of this macro :param result: (object) the result for this macro""" self._out_pars = result ## @name Internal methods # This list contains the set of methods that are for INTERNAL macro usage. # Macro developers should never call any of these methods #@{ @staticmethod def _buildWrongParamExp(method_name, param_name, expected, found): """**Internal method**. """ s = "Macro.%s called with wrong parameter type in '%s'. " \ "Expected %s got %s" % (method_name, param_name, expected, found) return MacroWrongParameterType(s) def _getName(self): """**Internal method**. """ return self._name def _getDescription(self): """**Internal method**. """ return self._desc #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Macro execution methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def _getMacroStatus(self): """**Internal method**. Returns the current macro status. Macro status is a :obj:`dict` where keys are the strings: * *id* - macro ID (internal usage only) * *range* - the full progress range of a macro (usually a :obj:`tuple` of two numbers (0, 100)) * *state* - the current macro state, a string which can have values *start*, *step*, *stop* and *abort* * *step* - the current step in macro. Should be a value inside the allowed macro range :return: the macro status :rtype: :obj:`dict`""" return self._macro_status def _shouldRaiseStopException(self): return self.isStopped() and not self.isProcessingStop() def _reserveObjs(self, args): """**Internal method**. Used to reserve a set of objects for this macro""" for obj in args: # isiterable if not type(obj) in map(type,([],())): #if not operator.isSequenceType(obj) or type(obj) in types.StringTypes: obj = (obj,) for sub_obj in obj: if isinstance(sub_obj, PoolElement): self.addObj(sub_obj) def exec_(self): """**Internal method**. Execute macro as an iterator""" self._macro_thread = threading.current_thread() macro_status = self.getMacroStatus() # make sure a 0.0 progress is sent yield macro_status # allow any macro to be paused at the beginning of its execution self.pausePoint() # Run the macro or obtain a generator res = self.run(*self._in_pars) # If macro returns a generator then running the macro means go through # the generator steps, otherwise the macro has already ran if type(res) == types.GeneratorType: it = iter(res) for i in it: if operator.isMappingType(i): new_range = i.get('range') if new_range is not None: macro_status['range'] = new_range new_step = i.get('step') if new_step is not None: macro_status['step'] = new_step elif operator.isNumberType(i): macro_status['step'] = i macro_status['state'] = 'step' yield macro_status # make sure a 'stop' progress is sent in case an exception occurs macro_status['state'] = 'stop' else: self._out_pars = res macro_status['step'] = 100.0 macro_status['state'] = 'finish' yield macro_status def __prepareResult(self,out): """**Internal method**. Decodes the given output in order to be able to send to the result channel :param out: output value :return: the output as a sequence of strings """ if out is None: out = () if operator.isSequenceType(out) and not type(out) in types.StringTypes: out = map(str,out) else: out = (str(out),) return out def _stopOnError(self): """**Internal method**. The stop procedure. Calls the user 'on_abort' protecting it against exceptions""" try: self.on_stop() except Exception: Logger.error(self, "Error in on_stop(): %s", traceback.format_exc()) Logger.debug(self, "Details: ", exc_info=1) def _abortOnError(self): """**Internal method**. The stop procedure. Calls the user 'on_abort' protecting it against exceptions""" try: self.on_abort() except Exception: Logger.error(self, "Error in on_abort(): %s", traceback.format_exc()) Logger.debug(self, "Details: ", exc_info=1) def _pausePoint(self, timeout=None): """**Internal method**.""" if self._pause_event.isPaused(): self.on_pause() self._pause_event.wait(timeout) def stop(self): """**Internal method**. Activates the stop flag on this macro.""" self._stopped = True def abort(self): """**Internal method**. Aborts the macro abruptly.""" # carefull: Inside this method never call a method that has the # mAPI decorator Logger.debug(self, "Aborting...") self._aborted = True ret, i = 0, 0 while ret != 1: self.__resumeForAbort() th = self._macro_thread th_id = ctypes.c_long(th.ident) Logger.debug(self, "Sending AbortException to %s", th.name) ret = asyncexc(th_id, ctypes.py_object(AbortException)) i += 1 if ret == 0: # try again if i > 2: self.error("Failed to abort after three tries!") break time.sleep(0.1) if ret > 1: # if it returns a number greater than one, you're in trouble, # and you should call it again with exc=NULL to revert the effect asyncexc(th_id, None) Logger.error(self, "Failed to abort (unknown error code %d)" % ret) break def setProcessingStop(self, yesno): """**Internal method**. Activates the processing stop flag on this macro""" self._processingStop = yesno def isProcessingStop(self): """**Internal method**. Checks if this macro is processing stop""" return self._processingStop def pause(self, cb=None): """**Internal method**. Pauses the macro execution. To be called by the Door running the macro to pause the current macro""" self._pause_event.pause(cb=cb) def resume(self, cb=None): """**Internal method**. Resumes the macro execution. To be called by the Door running the macro to resume the current macro""" self._pause_event.resume(cb=cb) def __resumeForAbort(self): """Called internally to resume the macro execution in case of an abort. The macro is resumed but instead of allowing the next user instruction to proceed it just waits for an ashyncronous AbortException to be thrown""" self._pause_event.resumeForAbort() #@} def __getattr__(self, name): try: self.door.get_macro(name) except UnknownMacro: raise AttributeError("%r object has no attribute %r" % (type(self).__name__, name)) def f(*args, **kwargs): self.syncLog() opts = dict(parent_macro=self, executor=self.executor) kwargs.update(opts) eargs = [name] eargs.extend(args) return self.execMacro(*eargs, **kwargs) setattr(self, name, f) return f class iMacro(Macro): interactive = True class MacroFunc(Macro): def __init__(self, *args, **kwargs): function = kwargs['function'] self._function = function kwargs['as'] = self._function.func_name if function.param_def is not None: self.param_def = function.param_def if function.result_def is not None: self.result_def = function.result_def if function.env is not None: self.env = function.env if function.hints is not None: self.hints = function.hints if function.interactive is not None: self.interactive = function.interactive Macro.__init__(self, *args, **kwargs) def run(self, *args): return self._function(self, *args) sardana-1.2.0/src/sardana/macroserver/macro_template.txt0000644000234100017500000000015312174204311025007 0ustar cpascualcpascual00000000000000@macro() def @macro_name@(self): """Macro @macro_name@""" self.output("Running @macro_name@...") sardana-1.2.0/src/sardana/macroserver/macroserver.py0000644000234100017500000007743612174204311024176 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## from __future__ import with_statement import os import re import codecs import logging.handlers import time from taurus import Device, Factory from taurus.core import TaurusEventType from taurus.core.util import CaselessDict, ThreadPool, Logger from taurus.core.tango.sardana.motion import Motion, MotionGroup from taurus.core.tango.sardana.pool import registerExtensions from sardana import InvalidId, ElementType, Interface from sardana.sardanaevent import EventType from sardana.sardanamodulemanager import ModuleManager from sardana.sardanamanager import SardanaElementManager, SardanaIDManager from sardana.sardanathreadpool import get_thread_pool from sardana.sardanautils import is_pure_str from .msbase import MSObject from .mscontainer import MSContainer from .msdoor import MSDoor from .msmacromanager import MacroManager from .mstypemanager import TypeManager from .msenvmanager import EnvironmentManager from .msparameter import ParamType from .msexception import UnknownMacroLibrary, UnknownMacro CHANGE_EVT_TYPES = TaurusEventType.Change, TaurusEventType.Periodic ET = ElementType #: dictionary dict<:data:`~sardana.ElementType`, :class:`tuple`> #: where tuple is a sequence: #: #: #. type string representation #: #. family #: #. internal macro server class #: #. automatic full name TYPE_MAP = { ET.Door : ("Door", "Door", MSDoor, "door/{macro_server.name}/{name}"), } class TypeData(object): """Information for a specific Element type""" def __init__(self, **kwargs): self.__dict__.update(kwargs) #: dictionary #: dict<:data:`~sardana.ElementType`, :class:`~sardana.macroserver.macroserver.TypeData`> TYPE_MAP_OBJ = {} for t, d in TYPE_MAP.items(): o = TypeData(type=t, name=d[0], family=d[1], klass=d[2] , auto_full_name=d[3]) TYPE_MAP_OBJ[t] = o class NonOverlappingTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler): def getNewFileName(self): currentTime = int(time.time()) dstNow = time.localtime(currentTime)[-1] t = self.rolloverAt - self.interval if self.utc: timeTuple = time.gmtime(t) else: timeTuple = time.localtime(t) dstThen = timeTuple[-1] if dstNow != dstThen: if dstNow: addend = 3600 else: addend = -3600 timeTuple = time.localtime(t + addend) dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple) # PY3K if hasattr(self, 'rotation_filename'): dfn = self.rotation_filename(dfn) return dfn def doRollover(self): dfn = self.getNewFileName() do_backup = os.path.isfile(dfn) and self.backupCount > 0 if do_backup: dfn_backup = dfn + os.path.extsep + "backup" os.rename(dfn, dfn_backup) try: super(NonOverlappingTimedRotatingFileHandler, self).doRollover() finally: if do_backup: mode = self.mode if 'a' not in mode: mode = 'a' + mode with codecs.open(dfn_backup, mode, self.encoding) as dest: with codecs.open(dfn, 'r', self.encoding) as src: dest.write(src.read()) os.remove(dfn) os.rename(dfn_backup, dfn) class MacroServer(MSContainer, MSObject, SardanaElementManager, SardanaIDManager): All = "All" MaxParalellMacros = 5 logReportParams = dict(when='midnight', interval=1, backupCount=365) logReportKlass = NonOverlappingTimedRotatingFileHandler def __init__(self, full_name, name=None, macro_path=None, environment_db=None): # dict # key - device name (case insensitive) # value - Pool object representing the device name self._pools = CaselessDict() self._max_parallel_macros = self.MaxParalellMacros self._path_id = None MSContainer.__init__(self) MSObject.__init__(self, full_name=full_name, name=name, id=InvalidId, macro_server=self, elem_type=ElementType.MacroServer) registerExtensions() self._type_manager = TypeManager(self) self._environment_manager = EnvironmentManager(self, environment_db=environment_db) self._macro_manager = MacroManager(self, macro_path=macro_path) def serialize(self, *args, **kwargs): kwargs = MSObject.serialize(self, *args, **kwargs) kwargs['type'] = self.__class__.__name__ kwargs['id'] = InvalidId kwargs['parent'] = None return kwargs def add_job(self, job, callback=None, *args, **kw): th_pool = get_thread_pool() th_pool.add(job, callback, *args, **kw) # -------------------------------------------------------------------------- # Environment DB related methods # -------------------------------------------------------------------------- def set_environment_db(self, environment_db): """Sets the environment database. :param env_db: environment database name :type env_db: str """ self.environment_manager.setEnvironmentDb(environment_db) # -------------------------------------------------------------------------- # Python related methods # -------------------------------------------------------------------------- def set_python_path(self, path): mod_man = ModuleManager() if self._path_id is not None: mod_man.remove_python_path(self._path_id) self._path_id = mod_man.add_python_path(path) # -------------------------------------------------------------------------- # Macro path related methods # -------------------------------------------------------------------------- def set_macro_path(self, macro_path): """Sets the macro path. :param macro_path: macro path :type macro_path: seq """ self.macro_manager.setMacroPath(macro_path) # -------------------------------------------------------------------------- # Report related methods # -------------------------------------------------------------------------- def set_log_report(self, filename=None, format=None): log = self.get_report_logger() # first check that the handler has not been initialized yet. If it has # we remove previous handlers. We only allow one timed rotating file # handler at a time to_remove = [] for handler in log.handlers: if isinstance(handler, logging.handlers.TimedRotatingFileHandler): to_remove.append(handler) for handler in to_remove: handler.close() log.removeHandler(handler) if filename is None: return if format is None: format = Logger.DftLogMessageFormat formatter = logging.Formatter(format) self.info("Reports are being stored in %s", filename) klass = self.logReportKlass handler = klass(filename, **self.logReportParams) handler.setFormatter(formatter) log.addHandler(handler) def clear_log_report(self): self.set_log_report() def get_report_logger(self): return logging.getLogger("Sardana.Report") report_logger = property(get_report_logger) def report(self, msg, *args, **kwargs): """ Record a log message in the sardana report (if enabled) with default level **INFO**. The msg is the message format string, and the args are the arguments which are merged into msg using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) *kwargs* are the same as :meth:`logging.Logger.debug` plus an optional level kwargs which has default value **INFO** Example:: self.report("this is an official report!") :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" level = kwargs.pop('level', logging.INFO) return self.report_logger.log(level, msg, *args, **kwargs) # -------------------------------------------------------------------------- # Pool related methods # -------------------------------------------------------------------------- def set_pool_names(self, pool_names): """Registers a new list of device pools in this manager :param pool_names: sequence of pool names :type pool_names: seq""" for pool in self._pools.values(): elements_attr = pool.getAttribute("Elements") elements_attr.removeListener(self.on_pool_elements_changed) for name in pool_names: self.debug("Creating pool %s", name) pool = Device(name) if pool is None: self.error('Could not create Pool object for %s' % name) continue self._pools[name] = pool elements_attr = pool.getAttribute("Elements") elements_attr.addListener(self.on_pool_elements_changed) def get_pool_names(self): """Returns the list of names of the pools this macro server is connected to. :return: the list of names of the pools this macro server is connected to :rtype: seq""" return self._pools.keys() def get_pool(self, pool_name): """Returns the device pool object corresponding to the given device name or None if no match is found. :param pool_name: device pool name :type pool_name: str :return: Pool object or None if no match is found""" return self._pools.get(pool_name) def get_pools(self): """Returns the list of pools this macro server is connected to. :return: the list of pools this macro server is connected to :rtype: seq""" return self._pools.values() def on_pool_elements_changed(self, evt_src, evt_type, evt_value): if evt_type not in CHANGE_EVT_TYPES: return self.fire_event(EventType("PoolElementsChanged"), evt_value) # -------------------------------------------------------------------------- # Door related methods # -------------------------------------------------------------------------- def create_element(self, **kwargs): type = kwargs['type'] elem_type = ElementType[type] name = kwargs['name'] kwargs['macro_server'] = self td = TYPE_MAP_OBJ[elem_type] klass = td.klass auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) self.check_element(name, full_name) id = kwargs.get('id') if id is None: kwargs['id'] = id = self.get_new_id() else: self.reserve_id(id) elem = klass(**kwargs) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret def create_door(self, **kwargs): return self.create_element(type="Door", **kwargs) # -------------------------------------------------------------------------- # General access to elements # -------------------------------------------------------------------------- def get_elements_info(self): return self.get_remote_elements_info() + self.get_local_elements_info() def get_remote_elements_info(self): return [ elem.serialize() for pool in self.get_pools() for elem in pool.getElements() ] def get_local_elements_info(self): # fill macro library info ret = [ macrolib.serialize() for macrolib in self.get_macro_libs().values() ] # fill macro info ret += [ macro.serialize() for macro in self.get_macros().values() ] # fill parameter type info ret += [ paramtype.serialize() for paramtype in self.get_data_types().values() ] return ret # -------------------------------------------------------------------------- # macro execution # -------------------------------------------------------------------------- def set_max_parallel_macros(self, nb): assert nb > 0, "max parallel macros number must be > 0" th_pool = get_thread_pool() if th_pool.size + 5 < nb: th_pool.size = nb self._max_parallel_macros = nb def get_max_parallel_macros(self): return self._max_parallel_macros max_parallel_macros = property(get_max_parallel_macros, set_max_parallel_macros, doc="maximum number of macros which can " "execute at the same time") @property def macro_manager(self): return self._macro_manager @property def environment_manager(self): return self._environment_manager @property def type_manager(self): return self._type_manager # -------------------------------------------------------------------------- # (Re)load code # -------------------------------------------------------------------------- def reload_lib(self, lib_name): return self.macro_manager.reloadLib(lib_name) def reload_macro_lib(self, lib_name): manager = self.macro_manager try: old_lib = manager.getMacroLib(lib_name) except UnknownMacroLibrary: old_lib = None new_elements, changed_elements, deleted_elements = [], [], [] new_lib = manager.reloadMacroLib(lib_name) if old_lib is None: new_elements.extend(new_lib.get_macros()) new_elements.append(new_lib) else: changed_elements.append(new_lib) new_names = set([ macro.name for macro in new_lib.get_macros() ]) old_names = set([ macro.name for macro in old_lib.get_macros() ]) changed_names = set.intersection(new_names, old_names) deleted_names = old_names.difference(new_names) new_names = new_names.difference(old_names) for new_name in new_names: new_elements.append(new_lib.get_macro(new_name)) for changed_name in changed_names: changed_elements.append(new_lib.get_macro(changed_name)) for deleted_name in deleted_names: deleted_elements.append(old_lib.get_macro(deleted_name)) evt = { "new" : new_elements, "change" : changed_elements, "del" : deleted_elements } self.fire_event(EventType("ElementsChanged"), evt) return new_lib reload_macro_lib.__doc__ = MacroManager.reloadMacroLib.__doc__ def reload_macro_libs(self, lib_names): for lib_name in lib_names: self.reload_macro_lib(lib_name) def reload_macro(self, macro_name): macro_info = self.macro_manager.getMacro(macro_name) lib_name = macro_info.module_name self.reload_macro_lib(lib_name) def reload_macros(self, macro_names): lib_names = set() for macro_name in macro_names: macro_info = self.macro_manager.getMacro(macro_name) lib_names.add(macro_info.module_name) self.reload_macro_libs(lib_names) def get_macro_lib(self, lib_name): return self.macro_manager.getMacroLib(lib_name) get_macro_lib.__doc__ = MacroManager.getMacroLib.__doc__ def get_macro_libs(self, filter=None): return self.macro_manager.getMacroLibs(filter=filter) get_macro_libs.__doc__ = MacroManager.getMacroLibs.__doc__ def get_macro_lib_names(self): return self.macro_manager.getMacroLibNames() get_macro_lib_names.__doc__ = MacroManager.getMacroLibNames.__doc__ def get_macro(self, name): return self.macro_manager.getMacro(name) get_macro.__doc__ = MacroManager.getMacro.__doc__ def get_macros(self, filter=None): return self.macro_manager.getMacros(filter=filter) get_macros.__doc__ = MacroManager.getMacros.__doc__ def get_macro_names(self): return self.macro_manager.getMacroNames() get_macro_names.__doc__ = MacroManager.getMacroNames.__doc__ def get_macro_classes(self): return self.macro_manager.getMacroClasses() get_macro_classes.__doc__ = MacroManager.getMacroClasses.__doc__ def get_macro_functions(self): return self.macro_manager.getMacroFunctions() get_macro_functions.__doc__ = MacroManager.getMacroFunctions.__doc__ def get_macro_libs_summary_info(self): libs = self.get_macro_libs() ret = [] for module_name, macro_lib_info in libs.items(): elem = "%s (%s)" % (macro_lib_info.name, macro_lib_info.file_path) ret.append(elem) return ret def get_macro_classes_summary_info(self): macros = self.get_macros() ret = [] for macro_info in macros: elem = "%s (%s)" % (macro_info.name, macro_info.file_path) ret.append(elem) return ret def get_or_create_macro_lib(self, lib_name, macro_name=None): """Gets the exiting macro lib or creates a new macro lib file. If name is not None, a macro template code for the given macro name is appended to the end of the file. :param lib_name: module name, python file name, or full file name (with path) :type lib_name: str :param macro_name: an optional macro name. If given a macro template code is appended to the end of the file (default is None meaning no macro code is added) :type macro_name: str :return: a sequence with three items: full_filename, code, line number is 0 if no macro is created or n representing the first line of code for the given macro name. :rtype: seq""" return self.macro_manager.getOrCreateMacroLib(lib_name, macro_name=macro_name) get_or_create_macro_lib.__doc__ = MacroManager.getOrCreateMacroLib.__doc__ def set_macro_lib(self, lib_name, code, auto_reload=True): module_name = self.macro_manager.setMacroLib(lib_name, code, auto_reload=False) if auto_reload: self.reload_macro_lib(module_name) set_macro_lib.__doc__ = MacroManager.setMacroLib.__doc__ # -------------------------------------------------------------------------- # Data types # -------------------------------------------------------------------------- def get_data_types(self): return self.type_manager.getTypes() get_data_types.__doc__ = TypeManager.getTypes.__doc__ def get_data_type(self, type_name): return self.type_manager.getTypeObj(type_name) get_data_type.__doc__ = TypeManager.getTypeObj.__doc__ def get_data_type_names(self): return self.type_manager.getTypeNames() get_data_type_names.__doc__ = TypeManager.getTypeNames.__doc__ def get_data_type_names_with_asterisc(self): return self.type_manager.getTypeListStr() get_data_type_names_with_asterisc.__doc__ = TypeManager.getTypeListStr.__doc__ # -------------------------------------------------------------------------- # Doors # -------------------------------------------------------------------------- def get_doors(self): return self.get_elements_by_type(ElementType.Door) def get_door_names(self): return [ door.full_name for door in self.get_doors() ] #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Environment access methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_env(self, key=None, door_name=None, macro_name=None): """Gets the environment matching the given parameters: - door_name and macro_name define the context where to look for the environment. If both are None, the global environment is used. If door name is None but macro name not, the given macro environment is used and so on... - If key is None it returns the complete environment, otherwise key must be a string containing the environment variable name. :param key: environment variable name [default: None, meaning all environment] :type key: str :param door_name: local context for a given door [default: None, meaning no door context is used] :type door_name: str :param macro_name: local context for a given macro [default: None, meaning no macro context is used] :type macro_name: str :return: a :obj:`dict` containing the environment :rtype: :obj:`dict` :raises: UnknownEnv""" return self.environment_manager.getEnv(key=key, macro_name=macro_name, door_name=door_name) def set_env(self, key, value): """Sets the environment key to the new value and stores it persistently. :param key: the key for the environment :param value: the value for the environment :return: a tuple with the key and value objects stored""" env_man = self.environment_manager if env_man.hasEnv(key): evt_type = "change" else: evt_type = "new" k,v = self.environment_manager.setEnv(key, value) evt = { evt_type : { k : v } } self.fire_event(EventType("EnvironmentChanged"), evt) return k,v def set_env_obj(self, data): """Sets the environment key to the new value and stores it persistently. :param key: the key for the environment :param value: the value for the environment :return: a tuple with the key and value objects stored""" env_man = self.environment_manager new, change = {}, {} for key, value in data.items(): d = new if env_man.hasEnv(key): d = change d[key] = value ret = env_man.setEnvObj(data) evt = dict(new=new, change=change) self.fire_event(EventType("EnvironmentChanged"), evt) return ret def change_env(self, data): env_man = self.environment_manager new_change_env = data.get('new', {}) new_change_env.update(data.get('change', {})) del_env = data.get('del', []) new, change = {}, {} for key, value in new_change_env.items(): d = new if env_man.hasEnv(key): d = change d[key] = value del_keys = env_man.unsetEnv(del_env) env_man.setEnvObj(new_change_env) evt = dict(new=new, change=change) evt['del'] = del_keys self.fire_event(EventType("EnvironmentChanged"), evt) def unset_env(self, key): """Unsets the environment for the given key. :param key: the key for the environment to be unset""" ret = self.environment_manager.unsetEnv(key) evt = { 'del' : { key : None } } self.fire_event(EventType("EnvironmentChanged"), evt) return ret def has_env(self, key, macro_name=None, door_name=None): return self.environment_manager.hasEnv(key, macro_name=macro_name, door_name=door_name) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # General object access methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_object(self, name, type_class=All, subtype=All, pool=All): objs = self.find_objects(name, type_class, subtype, pool) if len(objs) == 0: return None if len(objs) > 1: raise AttributeError('More than one object named "%s" found' % name) return objs[0] def get_objects(self, names, type_class=All, subtype=All, pool=All): return self.find_objects(names, type_class=type_class, subtype=subtype, pool=pool) def find_objects(self, param, type_class=All, subtype=All, pool=All): if is_pure_str(param): param = param, if type_class == MacroServer.All: type_name_list = self.get_data_type_names() else: if is_pure_str(type_class): type_name_list = type_class, else: type_name_list = type_class obj_set = set() param = [ '^%s$' % x for x in param ] re_objs = map(re.compile, param, len(param)*(re.IGNORECASE,)) re_subtype = re.compile(subtype, re.IGNORECASE) for type_name in type_name_list: type_class_name = type_name if type_class_name.endswith('*'): type_class_name = type_class_name[:-1] type_inst = self.get_data_type(type_class_name) if not type_inst.hasCapability(ParamType.ItemList): continue if self.is_macroserver_interface(type_class_name): for name, obj in type_inst.getObjDict(pool=pool).items(): for re_obj in re_objs: if re_obj.match(name) is not None: obj_type = ElementType[obj.get_type()] if subtype is MacroServer.All or re_subtype.match(obj_type): obj_set.add(obj) else: for name, obj in type_inst.getObjDict(pool=pool).items(): for re_obj in re_objs: if re_obj.match(name) is not None: obj_type = obj.getType() if (subtype is MacroServer.All or \ re_subtype.match(obj.getType())) and \ obj_type != "MotorGroup": obj_set.add(obj) return list(obj_set) def get_motion(self, elems, motion_source=None, read_only=False, cache=True, decoupled=False): if motion_source is None: motion_source = self.get_pools() motion_klass = Motion if decoupled: # and len(elems)>1: motion_klass = MotionGroup return motion_klass(elems, motion_source) _LOCAL_INTERFACES = { Interface.MacroLibrary : get_macro_libs, Interface.MacroCode : get_macros, Interface.MacroClass: get_macro_classes, Interface.MacroFunction: get_macro_functions, } def is_macroserver_interface(self, interface): if is_pure_str(interface): interface = Interface[interface] return interface in self._LOCAL_INTERFACES def get_elements_with_interface(self, interface): ret=CaselessDict() if is_pure_str(interface): interface_str = interface interface = Interface[interface_str] else: interface_str = Interface[interface] if self.is_macroserver_interface(interface): ret.update(self._LOCAL_INTERFACES.get(interface)(self)) else: for pool in self.get_pools(): ret.update(pool.getElementsWithInterface(interface_str)) return ret def get_element_with_interface(self, name, interface): for pool in self.get_pools(): element = pool.getElementWithInterface(name, interface) if element is not None: return element def get_controllers(self): return self.get_elements_with_interface("Controller") def get_moveables(self): return self.get_elements_with_interface("Moveable") def get_motors(self): return self.get_elements_with_interface("Motor") def get_pseudo_motors(self): return self.get_elements_with_interface("PseudoMotor") def get_io_registers(self): return self.get_elements_with_interface("IORegister") def get_measurement_groups(self): return self.get_elements_with_interface("MeasurementGroup") def get_exp_channels(self): return self.get_elements_with_interface("ExpChannel") def get_counter_timers(self): return self.get_elements_with_interface("CTExpChannel") def get_0d_exp_channels(self): return self.get_elements_with_interface("ZeroDExpChannel") def get_1d_exp_channels(self): return self.get_elements_with_interface("OneDExpChannel") def get_2d_exp_channels(self): return self.get_elements_with_interface("TwoDExpChannel") def get_pseudo_counters(self): return self.get_elements_with_interface("PseudoCounter") def get_instruments(self): return self.get_elements_with_interface("Instrument") def get_controller(self, name): return self.get_element_with_interface(name, "Controller") def get_moveable(self, name): return self.get_element_with_interface(name, "Moveable") def get_motor(self, name): return self.get_element_with_interface(name, "Motor") def get_pseudo_motor(self, name): return self.get_element_with_interface(name, "PseudoMotor") def get_io_register(self, name): return self.get_element_with_interface(name, "IORegister") def get_measurement_group(self, name): return self.get_element_with_interface(name, "MeasurementGroup") def get_exp_channel(self, name): return self.get_element_with_interface(name, "ExpChannel") def get_counter_timer(self, name): return self.get_element_with_interface(name, "CTExpChannel") def get_0d_exp_channel(self, name): return self.get_element_with_interface(name, "ZeroDExpChannel") def get_1d_exp_channel(self, name): return self.get_element_with_interface(name, "OneDExpChannel") def get_2d_exp_channel(self, name): return self.get_element_with_interface(name, "TwoDExpChannel") def get_pseudo_counter(self, name): return self.get_element_with_interface(name, "PseudoCounter") def get_instrument(self, name): return self.get_element_with_interface(name, "Instrument") sardana-1.2.0/src/sardana/macroserver/msbase.py0000644000234100017500000000527612174204311023111 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python MacroServer libray. It defines the base classes for MacroServer object""" __all__ = [",MSBaseObject", "MSObject",] __docformat__ = 'restructuredtext' from sardana.sardanabase import SardanaBaseObject, SardanaObjectID class MSBaseObject(SardanaBaseObject): """The MacroServer most abstract object.""" def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('macro_server') SardanaBaseObject.__init__(self, **kwargs) def get_macro_server(self): """Return the :class:`sardana.macroserver.macroserver.MacroServer` which *owns* this macro server object. :return: the macro server which *owns* this macro server object. :rtype: :class:`sardana.macroserver.macroserver.MacroServer`""" return self.get_manager() def serialize(self, *args, **kwargs): kwargs = SardanaBaseObject.serialize(self, *args, **kwargs) kwargs['macro_server'] = self.macro_server.name return kwargs macro_server = property(get_macro_server, doc="reference to the :class:`sardana.macroserver.macroserver.MacroServer`") class MSObject(SardanaObjectID, MSBaseObject): """A macro server object that besides the name and reference to the macro server base object has: - _id : the internal identifier""" def __init__(self, **kwargs): SardanaObjectID.__init__(self, id=kwargs.pop('id')) MSBaseObject.__init__(self, **kwargs) def serialize(self, *args, **kwargs): kwargs = PoolBaseObject.serialize(self, *args, **kwargs) kwargs = SardanaObjectID.serialize(self, *args, **kwargs) return kwargs sardana-1.2.0/src/sardana/macroserver/mscontainer.py0000644000234100017500000000243712174204311024155 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Macro Server libray. It defines the base classes for a macro server container element""" __all__ = ["MSContainer"] __docformat__ = 'restructuredtext' from sardana.sardanacontainer import SardanaContainer class MSContainer(SardanaContainer): passsardana-1.2.0/src/sardana/macroserver/msdoor.py0000644000234100017500000003011312174204311023126 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the macro server door""" __all__ = ["MacroProxy", "BaseInputHandler", "MSDoor"] __docformat__ = 'restructuredtext' import collections import weakref from taurus.core.util import Logger from sardana import ElementType from sardana.sardanaevent import EventType from msbase import MSObject from msparameter import Type class MacroProxy(object): def __init__(self, door, macro_meta): self._door = weakref.ref(door) self._macro_meta = weakref.ref(macro_meta) @property def door(self): return self._door() @property def macro_info(self): return self._macro_meta() def __call__(self, *args, **kwargs): door = self.door parent_macro = door.get_running_macro() parent_macro.syncLog() executor = parent_macro.executor opts=dict(parent_macro=parent_macro, executor=executor) kwargs.update(opts) eargs = [self.macro_info.name] eargs.extend(args) return parent_macro.execMacro(*eargs, **kwargs) class MacroProxyCache(dict): def __init__(self, door): self._door = weakref.ref(door) self.rebuild() @property def door(self): return self._door() def rebuild(self): self.clear() door = self.door macros = self.door.get_macros() for macro_name, macro_meta in macros.items(): self[macro_name] = MacroProxy(door, macro_meta) class BaseInputHandler(object): def __init__(self): try: self._input = raw_input except NameError: self._input = input def input(self, input_data=None): if input_data is None: input_data = {} prompt = input_data.get('prompt') if prompt is None: return self._input() else: return self._input(prompt) class MSDoor(MSObject): """Sardana door object""" def __init__(self, **kwargs): self._state = None self._status = None self._result = None self._macro_status = None self._record_data = None self._macro_proxy_cache = None self._input_handler = BaseInputHandler() self._pylab_handler = None kwargs['elem_type'] = ElementType.Door MSObject.__init__(self, **kwargs) def get_macro_executor(self): return self.macro_server.macro_manager.getMacroExecutor(self) macro_executor = property(get_macro_executor) def get_running_macro(self): return self.macro_executor.getRunningMacro() running_macro = property(get_running_macro) def get_macro_data(self): macro = self.running_macro if macro is None: raise Exception("No macro has run so far!") data = macro.data return data def set_pylab_handler(self, ph): self._pylab_handler = ph def get_pylab_handler(self): return self._pylab_handler pylab_handler = property(get_pylab_handler, set_pylab_handler) def get_pylab(self): ph = self.pylab_handler if ph is None: import matplotlib.pylab ph = matplotlib.pylab return ph pylab = property(get_pylab) def set_pyplot_handler(self, ph): self._pyplot_handler = ph def get_pyplot_handler(self): return self._pyplot_handler pyplot_handler = property(get_pyplot_handler, set_pyplot_handler) def get_pyplot(self): ph = self.pyplot_handler if ph is None: import matplotlib.pyplot ph = matplotlib.pyplot return ph pyplot = property(get_pyplot) def set_input_handler(self, ih): self._input_handler = ih def get_input_handler(self): return self._input_handler input_handler = property(get_input_handler, set_input_handler) def append_prompt(self, prompt, msg): if '?' in prompt: prefix, suffix = prompt.rsplit('?', 1) if not prefix.endswith(' '): prefix += ' ' prompt = prefix + msg + '?' + suffix else: prompt += msg + ' ' return prompt def input(self, msg, *args, **kwargs): kwargs['data_type'] = kwargs.get('data_type', Type.String) kwargs['allow_multiple'] = kwargs.get('allow_multiple', False) if args: msg = msg % args if not msg.endswith(' '): msg += ' ' dv = kwargs.get('default_value') if dv is not None: dv = '[' + str(dv) + ']' msg = self.append_prompt(msg, dv) macro = kwargs.pop('macro', self.macro_executor.getRunningMacro()) if macro is None: macro = self input_data = dict(prompt=msg, type='input') input_data.update(kwargs) data_type = kwargs['data_type'] is_seq = not isinstance(data_type, (str, unicode)) and \ isinstance(data_type, collections.Sequence) if is_seq: handle = self._handle_seq_input else: handle = self._handle_type_input return handle(macro, input_data, data_type) def _handle_seq_input(self, obj, input_data, data_type): valid = False allow_multiple = input_data['allow_multiple'] while not valid: result = self.input_handler.input(input_data) if allow_multiple: r, dt = set(result), set(data_type) if r.issubset(dt): break else: if result in data_type: break obj.warning("Please give a valid option") return result def _handle_type_input(self, obj, input_data, data_type): type_obj = self.type_manager.getTypeObj(data_type) valid = False while not valid: result = self.input_handler.input(input_data) try: result_type = type_obj.getObj(result) if result_type is None: raise Exception("Must give a value") valid = True return result_type except: dtype = str(data_type).lower() obj.warning("Please give a valid %s.", dtype) def get_report_logger(self): return self.macro_server.report_logger report_logger = property(get_report_logger) def report(self, msg, *args, **kwargs): """ Record a log message in the sardana report (if enabled) with default level **INFO**. The msg is the message format string, and the args are the arguments which are merged into msg using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) *kwargs* are the same as :meth:`logging.Logger.debug` plus an optional level kwargs which has default value **INFO** Example:: self.report("this is an official report!") :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" return self.macro_server.report(msg, *args, **kwargs) def get_state(self): return self._state def set_state(self, state, propagate=1): self._state = state self.fire_event(EventType("state", priority=propagate), state) state = property(get_state, set_state) def get_status(self): return self._status def set_status(self, status, propagate=1): self._status = status self.fire_event(EventType("status", priority=propagate), status) status = property(get_status, set_status) def get_result(self): return self._result def set_result(self, result, propagate=1): self._result = result self.fire_event(EventType("result", priority=propagate), result) result = property(get_result, set_result) def get_macro_status(self): return self._macro_status def set_macro_status(self, macro_status, propagate=1): self._macro_status = macro_status self.fire_event(EventType("macrostatus", priority=propagate), macro_status) result = property(get_result, set_result) def get_record_data(self): return self._record_data def set_record_data(self, record_data, codec=None, propagate=1): self._record_data = record_data self.fire_event(EventType("recorddata", priority=propagate), (codec, record_data)) record_data = property(get_record_data, set_record_data) def get_env(self, key=None, macro_name=None): """Gets the environment with the context for this door matching the given parameters: - macro_name defines the context where to look for the environment. If None, the global environment is used. If macro name is given the environment in the context of that macro is given - If key is None it returns the complete environment, otherwise key must be a string containing the environment variable name. :param key: environment variable name [default: None, meaning all environment] :type key: str :param macro_name: local context for a given macro [default: None, meaning no macro context is used] :type macro_name: str :raises: UnknownEnv""" return self.macro_server.environment_manager.getAllDoorEnv(self.name) def set_env(self, key, value): return self.macro_server.set_env(key, value) def _build_macro_proxy_cache(self): self._macro_proxy_cache = MacroProxyCache(self) def get_macro_proxies(self): if self._macro_proxy_cache is None: self._macro_proxy_cache = MacroProxyCache(self) return self._macro_proxy_cache def run_macro(self, par_str_list, asynch=False): if isinstance(par_str_list, (str, unicode)): par_str_list = par_str_list, if not hasattr(self, "Output"): import sys import logging Logger.addLevelName(15, "OUTPUT") def output(loggable, msg, *args, **kw): loggable.getLogObj().log(Logger.Output, msg, *args, **kw) Logger.output = output Logger.disableLogOutput() Logger.setLogLevel(Logger.Output) #filter = taurus.core.util.LogFilter(level=Logger.Output) formatter = logging.Formatter(fmt="%(message)s") Logger.setLogFormat("%(message)s") handler = logging.StreamHandler(stream=sys.stdout) #handler.addFilter(filter) Logger.addRootLogHandler(handler) #handler.setFormatter(formatter) #logger.addHandler(handler) #logger.addFilter(filter) self.__logging_info = handler, filter, formatter # result of a macro #Logger.addLevelName(18, "RESULT") return self.macro_executor.run(par_str_list, asynch=asynch) def __getattr__(self, name): """Get methods from macro server""" return getattr(self.macro_server, name) sardana-1.2.0/src/sardana/macroserver/msenvmanager.py0000644000234100017500000004056612174204311024323 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer environment manager""" __all__ = ["EnvironmentManager"] __docformat__ = 'restructuredtext' import os import shelve import operator from taurus.core.util import CaselessDict from msmanager import MacroServerManager from msexception import UnknownEnv class EnvironmentManager(MacroServerManager): """The MacroServer environment manager class. It is designed to be a singleton for the entire application. """ def __init__(self, macro_server, environment_db=None): MacroServerManager.__init__(self, macro_server) if environment_db is not None: self.setEnvironmentDb(environment_db) def reInit(self): """(Re)initializes the manager""" if self.is_initialized(): return # a string containing the absolute filename containing the environment self._env_name = None # the full enviroment (a shelf for now - can be accessed as a dict) self._env = None # cache environment for keys that start with door name # dict > where: # - key: door name # - value: dict where: # - key: environment name # - value: environment value self._door_env = None # cache environment for keys that start with macro name # dict > where: # - key: macro name # - value: dict where: # - key: environment name # - value: environment value self._macro_env = None # cache environment for global keys # dict where: # - key: environment name # - value: environment value self._global_env = None self._initEnv() MacroServerManager.reInit(self) def cleanUp(self): if self.is_cleaned(): return self._clearEnv() MacroServerManager.cleanUp(self) def _initEnv(self): self._macro_env, self._global_env = {}, {} self._door_env = CaselessDict() def _clearEnv(self): self._env = self._macro_env = self._global_env = self._door_env = None def setEnvironmentDb(self, f_name): """Sets up a new environment from a file""" self._initEnv() f_name = os.path.abspath(f_name) self._env_name = f_name dir_name = os.path.dirname(f_name) if not os.path.isdir(dir_name): try: self.info("Creating environment directory: %s" % dir_name) os.makedirs(dir_name) except OSError, ose: self.error("Creating environment: %s" % ose.strerror) self.debug("Details:", exc_info=1) raise ose try: self._env = shelve.open(f_name, flag='c', protocol=0, writeback=False) except: self.error("Failed to create/access environment in %s", f_name) self.debug("Details:", exc_info=1) raise self.info("Environment is being stored in %s", f_name) # fill the three environment caches try: self._fillEnvironmentCaches(self._env) except: self.error("Failed to fill local enviroment cache") self.debug("Details:", exc_info=1) def _fillEnvironmentCaches(self, env): # fill the three environment caches env_dict = self._global_env for k, v in env.items(): k_parts = k.split('.', 1) key = k_parts[0] # door or macro property if len(k_parts) == 2: obj_name, simple_key_name = k_parts if obj_name.count('/') == 2: class_dict = self._door_env else: class_dict = self._macro_env obj_dict = class_dict.get(obj_name, None) if obj_dict is None: class_dict[obj_name] = obj_dict = {} obj_dict[simple_key_name] = v else: env_dict[key] = v def hasEnv(self, key, macro_name=None, door_name=None): #.. (highest priority) if macro_name and door_name: has = self._hasDoorMacroPropertyEnv((door_name, macro_name, key)) if has: return True # . if macro_name: has = self._hasMacroPropertyEnv((macro_name, key)) if has: return True # . if door_name: has = self._hasDoorPropertyEnv((door_name, key)) if has: return True # (less priority) return self._hasEnv(key) def _getDoorMacroPropertyEnv(self, prop): """Returns the property value for a property which must have the format ..""" if isinstance(prop, str): door_name, macro_name_key = prop.split('.', 1) else: door_name, macro_name_key = prop[0], '.'.join(prop[1:]) door_props = self._door_env.get(door_name) if door_props is None: return None return door_props.get(macro_name_key) def _hasDoorMacroPropertyEnv(self, prop): """Determines if the environment contains a property with the format ..""" return not self._getDoorMacroPropertyEnv() is None def _getMacroPropertyEnv(self, prop): """Returns the property value for a property which must have the format .""" if isinstance(prop, str): macro_name, key = prop.split('.') else: macro_name, key = prop macro_props = self._macro_env.get(macro_name) if macro_props is None: return None return macro_props.get(key) def _hasMacroPropertyEnv(self, prop): """Determines if the environment contains a property with the format .""" return not self._getMacroPropertyEnv() is None def _getDoorPropertyEnv(self, prop): """Returns the property value for a property which must have the format .""" if isinstance(prop, str): door_name, key = prop.split('.') else: door_name, key = prop door_props = self._door_env.get(door_name) if door_props is None: return None return door_props.get(key) def _hasDoorPropertyEnv(self, prop): """Determines if the environment contains a property with the format .""" return not self._getDoorPropertyEnv() is None def _getEnv(self, prop): """Returns the property value for a property which must have the format """ return self._global_env.get(prop) def _hasEnv(self, prop): """Determines if the environment contains a property with the format """ return not self._getEnv(prop) is None def getEnv(self, key=None, door_name=None, macro_name=None): """Gets the environment matching the given parameters: - If key is None it returns the complete environment for the given macro and/or door. If both are None the the complete environment is returned @param[in]""" if key is None: return self._getAllEnv(door_name=door_name, macro_name=macro_name) #.. (highest priority) if macro_name and door_name: v = self._getDoorMacroPropertyEnv((door_name, macro_name, key)) if not v is None: return v # . if macro_name: v = self._getMacroPropertyEnv((macro_name, key)) if not v is None: return v # . if door_name: v = self._getDoorPropertyEnv((door_name, key)) if not v is None: return v # (less priority) v = self._getEnv(key) if v is None: raise UnknownEnv("Unknown environment %s" % key) return v def _getAllEnv(self, door_name=None, macro_name=None): """Gets the complete environment for the given macro and/or door. If both are None the the complete environment is returned""" if macro_name is None and door_name is None: return dict(self._env) elif not door_name is None and macro_name is None: return self.getDoorEnv(door_name) elif door_name and macro_name: return self.getAllDoorMacroEnv(door_name, macro_name) elif not macro_name is None and door_name is None: return self._macro_env.get(macro_name, {}) def getAllDoorEnv(self, door_name): """Gets the complete environment for the given door.""" door_name = door_name.lower() # first go through the global environment ret = self._global_env.copy() # Then go through the door specific environment ret.update(self._door_env.get(door_name, {})) return ret def getAllDoorMacroEnv(self, door_name, macro_name): """Gets the complete environment for the given macro in a specific door. :param door_name: the door name (case insensitive) :type door_name: str :param macro_name: the macro name :type macro_name: str :return: a dictionary with the resulting environment""" door_name = door_name.lower() # first go through the global environment ret = self._global_env.copy() # get the specific door environment d_env = self._door_env.get(door_name, {}) # get the specific macro environment m_env = self._macro_env.get(macro_name, {}) # put the doors global environment for k, v in d_env.iteritems(): if k.count('.') == 0: ret[k] = v # put the macro environment ret.update(m_env) # put the door and macro specific environment for k, v in d_env.iteritems(): if k.count('.') > 0: m_name, key = k.split('.', 1) if m_name is macro_name: ret[key] = v return ret def getDoorMacroEnv(self, door_name, macro_name, keys=None): """Gets the environment for the given macro in a specific door for the given key(s) :param door_name: the door name (case insensitive) :param macro_name: the macro name (case sensitive) :param key: the keys to be retrieved. If None (default) the complete environment is returned (same as getAllDoorMacroEnv) key can be a string or a sequence. keys must NOT contain '.' characters :return: a dictionary with the resulting environment""" if keys is None: return self.getAllDoorMacroEnv(door_name, macro_name) if isinstance(keys, (str, unicode)): keys = (keys,) door_name = door_name.lower() g_env = self._global_env # get the specific door environment d_env = self._door_env.get(door_name, {}) # get the specific macro environment m_env = self._macro_env.get(macro_name, {}) # first go through the global environment ret = {} for k in keys: comp_key = '%s.%s' % (macro_name, k) if comp_key in d_env: ret[k] = d_env[comp_key] elif k in m_env: ret[k] = m_env[k] elif k in d_env: ret[k] = d_env[k] elif k in g_env: ret[k] = g_env[k] return ret def _pairwise(self, iterable): itnext = iter(iterable).next while True: yield itnext(), itnext() def _dictFromSequence(self, seq): return dict(self._pairwise(seq)) def _encode(self, d): ret = {} for k, v in d.iteritems(): if isinstance(v, (str, unicode)): try: v = eval(v) except: v_lower = v.lower() try: v = eval(v_lower.capitalize()) except: pass ret[k] = v return ret def _getCacheForKey(self, key): """Returns the cache dictionary object for the given key :param key: a string representing the key :return: a tuple pair. The first element is the dictionary and the second is the modified key that is applicable to the dictionary""" d = None key_parts = key.split('.') # global property if len(key_parts) == 1: d = self._global_env # macro property elif len(key_parts) == 2 and key_parts[0].count('/') != 2: macro_name, key = key_parts d = self._macro_env.get(macro_name) if d is None: self._macro_env[macro_name] = d = {} # door property else: door_name, key = key.split('.', 1) d = self._door_env.get(door_name) if d is None: self._door_env[door_name] = d = {} return d, key def _setOneEnv(self, key, value): self._env[key] = value self._env.sync() d, key = self._getCacheForKey(key) d[key] = value def _unsetOneEnv(self, key): if not key in self._env: raise UnknownEnv("Unknown environment %s" % key) del self._env[key] self._env.sync() d, key = self._getCacheForKey(key) if key in d: del d[key] def _unsetEnv(self, env_names): for key in env_names: self._unsetOneEnv(key) def setEnvObj(self, obj): """Sets the environment for the given object. If object is a sequence then each pair of elements k, v is added as env[k] = v. If object is a map then the environmnent is updated. Other object types are not supported The elements which are strings are 'python evaluated' @throws TypeError is obj is not a sequence or a map @param[in] obj object to be added to the environment @return a dict representing the added environment""" if operator.isSequenceType(obj) and \ not isinstance(obj, (str, unicode)): obj = self._dictFromSequence(obj) elif not operator.isMappingType(obj): raise TypeError("obj parameter must be a sequence or a map") obj = self._encode(obj) for k, v in obj.iteritems(): self._setOneEnv(k, v) return obj def setEnv(self, key, value): """Sets the environment key to the new value and stores it persistently. :param key: the key for the environment :param value: the value for the environment :return: a tuple with the key and value objects stored""" ret = self.setEnvObj((key, value)) return key, ret[key] def unsetEnv(self, key): """Unsets the environment for the given key. :param key: the key for the environment to be unset :return: the sequence of keys which have been removed""" if isinstance(key, (str, unicode)): key = (key,) self._unsetEnv(key) return key sardana-1.2.0/src/sardana/macroserver/msexception.py0000644000234100017500000000407412174204311024170 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer environment manager""" __all__ = ["MacroServerException", "MacroServerExceptionList", "MissingEnv", "UnknownEnv", "UnknownMacro", "UnknownMacroLibrary", "MacroWrongParameterType", "LibraryError", "InterruptException", "StopException", "AbortException", "InputCancelled"] __docformat__ = 'restructuredtext' from taurus.core.tango.sardana.pool import InterruptException, \ StopException, AbortException from sardana.sardanaexception import SardanaException, SardanaExceptionList, \ UnknownCode, UnknownLibrary, LibraryError class MacroServerException(SardanaException): pass class MacroServerExceptionList(SardanaExceptionList): pass class MissingEnv(MacroServerException): pass class UnknownEnv(MacroServerException): pass class UnknownMacro(UnknownCode): pass class UnknownMacroLibrary(UnknownLibrary): pass class MacroWrongParameterType(MacroServerException): pass class InputCancelled(MacroServerException): pass sardana-1.2.0/src/sardana/macroserver/msmacromanager.py0000644000234100017500000013461612174204311024634 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer macro manager""" __all__ = ["MacroManager", "MacroExecutor", "is_macro"] __docformat__ = 'restructuredtext' import sys import os import inspect import copy import re import functools import traceback from lxml import etree from PyTango import DevFailed from taurus.core.util import Logger, CodecFactory from sardana.sardanadefs import ElementType from sardana.sardanamodulemanager import ModuleManager from sardana.sardanaexception import format_exception_only_str from sardana.sardanautils import is_pure_str, is_non_str_seq from .msmanager import MacroServerManager from .msmetamacro import MACRO_TEMPLATE, MacroLibrary, MacroClass, MacroFunction from .msparameter import ParamDecoder from .macro import Macro, MacroFunc from .msexception import UnknownMacroLibrary, LibraryError, UnknownMacro, \ MissingEnv, AbortException, StopException, MacroServerException _BASE_DIR = os.path.dirname(os.path.abspath(__file__)) def islambda(f): """inspect doesn't come with islambda so I create one :-P""" return inspect.isfunction(f) and \ f.__name__ == (lambda: True).__name__ def is_macro(macro, abs_file=None, logger=None): """Helper function to determine if a certain python object is a valid macro""" if inspect.isclass(macro): if not issubclass(macro, Macro): return False # if it is a class defined in some other module forget it to # avoid replicating the same macro in different macro files try: if inspect.getabsfile(macro) != abs_file: return False except TypeError: return False elif callable(macro) and not islambda(macro): # if it is a function defined in some other module forget it to # avoid replicating the same macro in different macro files try: if inspect.getabsfile(macro) != abs_file: return False except TypeError: return False if not hasattr(macro, 'macro_data'): return False args, varargs, keywords, _ = inspect.getargspec(macro) if len(args) == 0: if logger: logger.debug("Could not add macro %s: Needs at least one " "parameter (usually called 'self')", macro.func_name) return False if keywords is not None: if logger: logger.debug("Could not add macro %s: Unsupported keyword " "parameters '%s'", macro.func_name, keywords) return False if varargs and len(args) > 1: if logger: logger.debug("Could not add macro %s: Unsupported giving " "named parameters '%s' and varargs '%s'", macro.func_name, args, varargs) return False else: return False return True class MacroManager(MacroServerManager): DEFAULT_MACRO_DIRECTORIES = os.path.join(_BASE_DIR, 'macros'), def __init__(self, macro_server, macro_path=None): MacroServerManager.__init__(self, macro_server) if macro_path is not None: self.setMacroPath(macro_path) def reInit(self): if self.is_initialized(): return # dict # key - module name (without path and without extension) # value - MacroLibrary object representing the module self._modules = {} # dict # key - macro name # value - MacroClass object representing the macro self._macro_dict = {} # list # elements are absolute paths self._macro_path = [] # dict # key - door # value - MacroExecutor object for the door self._macro_executors = {} MacroServerManager.reInit(self) def cleanUp(self): if self.is_cleaned(): return #if self._modules: # ModuleManager().unloadModules(self._modules.keys()) self._macro_path = None self._macro_dict = None self._modules = None MacroServerManager.cleanUp(self) def setMacroPath(self, macro_path): """Registers a new list of macro directories in this manager. Warning: as a consequence all the macro modules will be reloaded. This means that if any reference to an old macro object was kept it will refer to an old module (which could possibly generate problems of type class A != class A).""" p = [] for item in macro_path: p.extend(item.split(":")) # filter empty and commented paths p = [ i for i in p if i and not i.startswith("#") ] # add basic macro directories for macro_dir in self.DEFAULT_MACRO_DIRECTORIES: if not macro_dir in p: p.append(macro_dir) self._macro_path = p macro_file_names = self._findMacroLibNames() for mod_name in macro_file_names: try: self.reloadMacroLib(mod_name) except: pass def getMacroPath(self): return self._macro_path def _findMacroLibName(self, lib_name, path=None): path = path or self.getMacroPath() f_name = lib_name if not f_name.endswith('.py'): f_name += '.py' for p in path: try: elems = os.listdir(p) if f_name in elems: return os.path.abspath(os.path.join(p, f_name)) except: self.debug("'%s' is not a valid path" % p) return None def _findMacroLibNames(self, path=None): path = path or self.getMacroPath() ret = {} for p in reversed(path): try: for f in os.listdir(p): name,ext = os.path.splitext(f) if name.startswith("_"): continue if ext.endswith('py'): ret[name] = os.path.abspath(os.path.join(p, f)) except: self.debug("'%s' is not a valid path" % p) return ret def _fromNameToFileName(self, lib_name, path=None): path = path or self.getMacroPath()[0] f_name = lib_name if not f_name.endswith('.py'): f_name += '.py' if os.path.isabs(f_name): path, _ = os.path.split(f_name) if not path in self.getMacroPath(): raise Exception("'%s' is not part of the MacroPath" % path) else: f_name = os.path.join(path, f_name) return f_name def getOrCreateMacroLib(self, lib_name, macro_name=None): """Gets the exiting macro lib or creates a new macro lib file. If name is not None, a macro template code for the given macro name is appended to the end of the file. :param lib_name: module name, python file name, or full file name (with path) :type lib_name: str :param macro_name: an optional macro name. If given a macro template code is appended to the end of the file (default is None meaning no macro code is added) :type macro_name: str :return: a sequence with three items: full_filename, code, line number is 0 if no macro is created or n representing the first line of code for the given macro name. :rtype: seq""" # if only given the module name try: macro_lib = self.getMacroLib(lib_name) except UnknownMacroLibrary: macro_lib = None if macro_name is None: line_nb = 0 if macro_lib is None: f_name, code = self.createMacroLib(lib_name), '' else: f_name = macro_lib.file_path f = file(f_name) code = f.read() f.close() else: # if given macro name if macro_lib is None: f_name, code, line_nb = self.createMacro(lib_name, macro_name) else: macro = macro_lib.get_macro(macro_name) if macro is None: f_name, code, line_nb = self.createMacro(lib_name, macro_name) else: _, line_nb = macro.code f_name = macro.file_path f = file(f_name) code = f.read() f.close() return [ f_name, code, line_nb ] def setMacroLib(self, lib_name, code, auto_reload=True): f_name = self._fromNameToFileName(lib_name) f = open(f_name, 'w') f.write(code) f.flush() f.close() _, name = os.path.split(f_name) mod, _ = os.path.splitext(name) if auto_reload: self.reloadMacroLib(mod) return mod def createMacroLib(self, lib_name, path=None): """Creates a new empty macro library (python module)""" f_name = self._fromNameToFileName(lib_name, path) if os.path.exists(f_name): raise Exception("Unable to create macro lib: '%s' already exists" % f_name) f = open(f_name, 'w') f.close() return f_name def createMacro(self, lib_name, macro_name): f_name = self._fromNameToFileName(lib_name) create = not os.path.exists(f_name) template = '' if create: template += 'from sardana.macroserver.macro import Macro, macro, Type\n\n' line_nb = 4 else: template += '\n' t = open(f_name, 'rU') line_nb = -1 for line_nb, _ in enumerate(t): pass line_nb += 3 t.close() f = open(f_name, 'a+') f_templ = None try: dir_name = os.path.realpath(__file__) dir_name = os.path.dirname(dir_name) template_fname = 'macro_template.txt' template_fname = os.path.join(dir_name, template_fname) f_templ = open(template_fname, 'r') template += f_templ.read() f_templ.close() except: self.debug("Failed to open template macro file. Using simplified template") template += MACRO_TEMPLATE if f_templ: f_templ.close() template = template.replace('@macro_name@', macro_name) try: f.write(template) f.flush() f.seek(0) code = f.read() finally: f.close() return f_name, code, line_nb def reloadMacro(self, macro_name, path=None): """Reloads the module corresponding to the given macro name :raises: MacroServerExceptionList in case the macro is unknown or the reload process is not successful :param macro_name: macro name :param path: a list of absolute path to search for libraries (optional, default=None, means the current MacroPath will be used)""" self.reloadMacros([macro_name], path=path) def reloadMacros(self, macro_names, path=None): """Reloads the modules corresponding to the given macro names :raises: MacroServerExceptionList in case the macro(s) are unknown or the reload process is not successful :param macro_names: a list of macro names :param path: a list of absolute path to search for libraries (optional, default=None, means the current MacroPath will be used)""" module_names = [] for macro_name in macro_names: module_name = self.getMacro(macro_name).module_name module_names.append(module_name) self.reloadMacroLibs(module_names, path=path) def reloadMacroLibs(self, module_names, path=None): """Reloads the given lib(=module) names :raises: MacroServerExceptionList in case the reload process is not successful for at least one library :param module_names: a list of module names :param path: a list of absolute path to search for libraries (optional, default=None, means the current MacroPath will be used)""" ret = [] for module_name in module_names: m = self.reloadMacroLib(module_name, path=path) if m: ret.append(m) return ret def reloadLib(self, module_name, path=None): """Reloads the given library(=module) names. :raises: ImportError in case the reload process is not successful LibraryError if trying to reload a macro library :param module_name: module name :param path: a list of absolute path to search for libraries [default: None, meaning search in MacroPath. If not found, search for a built-in, frozen or special module and continue search in sys.path. ] :return: the reloaded python module object""" if module_name in self._modules: raise LibraryError("Cannot use simple reload to reload a Macro Library") mod_manager = ModuleManager() retry = path is None try: if retry: path = self.getMacroPath() if path: path = copy.copy(path) path.reverse() return mod_manager.reloadModule(module_name, path) except ImportError: if retry: return mod_manager.reloadModule(module_name, path=None) else: raise def reloadMacroLib(self, module_name, path=None): """Reloads the given library(=module) names. :raises: LibraryError in case the reload process is not successful :param module_name: macro library name (=python module name) :param path: a list of absolute path to search for libraries [default: None, means the current MacroPath will be used] :return: the MacroLibrary object for the reloaded macro library""" path = path or self.getMacroPath() # reverse the path order: # more priority elements last. This way if there are repeated elements # they first ones (lower priority) will be overwritten by the last ones if path: path = copy.copy(path) path.reverse() # if there was previous Macro Library info remove it old_macro_lib = self._modules.pop(module_name, None) if old_macro_lib is not None: for macro in old_macro_lib.get_macros(): self._macro_dict.pop(macro.name) mod_manager = ModuleManager() m, exc_info = None, None try: m = mod_manager.reloadModule(module_name, path) except: exc_info=sys.exc_info() macro_lib = None params = dict(module=m, name=module_name, macro_server=self.macro_server, exc_info=exc_info) if m is None: file_name = self._findMacroLibName(module_name) if file_name is None: if exc_info: msg = format_exception_only_str(*exc_info[:2]) else: msg = "Error (re)loading macro library '%s'" % module_name raise LibraryError(msg, exc_info=exc_info) params['file_path'] = file_name macro_lib = MacroLibrary(**params) else: macro_lib = MacroLibrary(**params) abs_file = macro_lib.file_path _is_macro = functools.partial(is_macro, abs_file=abs_file, logger=self) for _, macro in inspect.getmembers(m, _is_macro): try: self.addMacro(macro_lib, macro) except: self.error("Error adding macro %s", macro.__name__) self.debug("Details:", exc_info=1) self._modules[module_name] = macro_lib return macro_lib def addMacro(self, macro_lib, macro): add = self.addMacroFunction if inspect.isclass(macro): add = self.addMacroClass return add(macro_lib, macro) def addMacroClass(self, macro_lib, klass): macro_name = klass.__name__ action = (macro_lib.has_macro(macro_name) and "Updating") or "Adding" self.debug("%s macro class %s" % (action, macro_name)) params = dict(macro_server=self.macro_server, lib=macro_lib, klass=klass) macro_class = MacroClass(**params) macro_lib.add_macro_class(macro_class) self._macro_dict[macro_name] = macro_class def addMacroFunction(self, macro_lib, func): macro_name = func.func_name action = (macro_lib.has_macro(macro_name) and "Updating") or "Adding" self.debug("%s macro function %s" % (action, macro_name)) params = dict(macro_server=self.macro_server, lib=macro_lib, function=func) macro_function = MacroFunction(**params) macro_lib.add_macro_function(macro_function) self._macro_dict[macro_name] = macro_function def getMacroLibNames(self): return sorted(self._modules.keys()) def getMacroLibs(self, filter=None): if filter is None: return self._modules expr = re.compile(filter, re.IGNORECASE) ret = {} for name, macro_lib in self._modules.iteritems(): if expr.match(name) is None: continue ret[name] = macro_lib return ret def getMacros(self, filter=None): """Returns a :obj:`dict` containing information about macros. :param filter: a regular expression for macro names [default: None, meaning all macros] :type filter: str :return: a :obj:`dict` containing information about macros :rtype: :obj:`dict`\<:obj:`str`\, :class:`~sardana.macroserver.msmetamacro.MacroCode`\>""" if filter is None: return self._macro_dict expr = re.compile(filter, re.IGNORECASE) ret = {} for name, macro in self._macro_dict.iteritems(): if expr.match(name) is None: continue ret[name] = macro return ret def getMacroClasses(self, filter=None): """Returns a :obj:`dict` containing information about macro classes. :param filter: a regular expression for macro names [default: None, meaning all macros] :type filter: str :return: a :obj:`dict` containing information about macro classes :rtype: :obj:`dict`\<:obj:`str`\, :class:`~sardana.macroserver.msmetamacro.MacroClass`\>""" macros = self.getMacros(filter=filter) macro_classes = {} for name, macro in macros.items(): if macro.get_type() == ElementType.MacroClass: macro_classes[name] = macro return macro_classes def getMacroFunctions(self, filter=None): """Returns a :obj:`dict` containing information about macro functions. :param filter: a regular expression for macro names [default: None, meaning all macros] :type filter: str :return: a :obj:`dict` containing information about macro functions :rtype: :obj:`dict`\<:obj:`str`\, :class:`~sardana.macroserver.msmetamacro.MacroFunction`\>""" macros = self.getMacros(filter=filter) macro_classes = {} for name, macro in macros.items(): if macro.get_type() == ElementType.MacroFunction: macro_classes[name] = macro return macro_classes def getMacroNames(self): return sorted(self._macro_dict.keys()) def getMacro(self, macro_name): ret = self._macro_dict.get(macro_name) if ret is None: raise UnknownMacro("Unknown macro %s" % macro_name) return ret def getMacroClass(self, macro_name): return self.getMacro(macro_name) def getMacroFunction(self, macro_name): return self.getMacro(macro_name) def removeMacro(self, macro_name): self._macro_dict.pop(macro_name) def getMacroLib(self, name): if os.path.isabs(name): abs_file_name = name for lib in self._modules.values(): if lib.file_path == abs_file_name: return lib elif name.count(os.path.extsep): file_name = name for lib in self._modules.values(): if lib.file_name == file_name: return lib module_name = name ret = self._modules.get(module_name) if ret is None: raise UnknownMacroLibrary("Unknown macro library %s" % module_name) return ret def getMacroCode(self, macro_name): return self.getMacro(macro_name).code_object def getMacroClassCode(self, macro_name): return self.getMacroClass(macro_name).klass def getMacroFunctionCode(self, macro_name): return self.getMacroFunction(macro_name).function def getMacroInfo(self, macro_names, format='json'): if isinstance(macro_names, (str, unicode)): macro_names = [macro_names] ret = [] json_codec = CodecFactory().getCodec(format) for macro_name in macro_names: macro_meta = self.getMacro(macro_name) ret.append(json_codec.encode(('', macro_meta.serialize()))[1]) return ret def decodeMacroParameters(self, door, in_par_list): if len(in_par_list) == 0: raise RuntimeError('Macro name not specified') macro_name = in_par_list[0] macro_meta = self.getMacro(macro_name) out_par_list = ParamDecoder(door, macro_meta, in_par_list) return macro_meta, in_par_list, out_par_list def strMacroParamValues(self,par_list): """strMacroParamValues(list par_list) -> list Creates a short string representantion of the parameter values list. Params: - par_list: list of strings representing the parameter values. Return: a list containning an abreviated version of the par_list argument. """ ret = [] for p in par_list: param_str = str(p) if len(param_str)>9: param_str = param_str[:9] + "..." ret.append(param_str) return ret def prepareMacro(self, macro_class, par_list, init_opts={}, prepare_opts={}): """Creates the macro object and calls its prepare method. The return value is a tuple (MacroObject, return value of prepare) """ macro = self.createMacroObj(macro_class, par_list, init_opts=init_opts) prepare_result = self.prepareMacroObj(macro, par_list, prepare_opts=prepare_opts) return macro, prepare_result def createMacroObj(self, macro_class, par_list, init_opts={}): macro_env = macro_class.env macro_name = macro_class.__name__ environment = init_opts.get('environment') r = [] for env in macro_env: if not environment.has_env(env): r.append(env) if r: raise MissingEnv("The macro %s requires the following missing " \ "environment to be defined: %s" % (macro_name, str(r))) macro_opts = { 'no_exec': True, 'create_thread' : True, 'external_prepare' : True } macro_opts.update(init_opts) macroObj = macro_class(*par_list, **macro_opts) return macroObj def prepareMacroObj(self, macro, par_list, prepare_opts={}): return macro.prepare(*par_list, **prepare_opts) def createMacroObjFromMeta(self, meta, par_list, init_opts={}): code = meta.code_object macro_env = code.env or () environment = init_opts.get('environment') r = [] for env in macro_env: if not environment.has_env(env): r.append(env) if r: macro_name = meta.name raise MissingEnv("The macro %s requires the following missing " \ "environment to be defined: %s" % (macro_name, str(r))) macro_opts = dict(no_exec=True, create_thread=True, external_prepare=True) macro_opts.update(init_opts) if meta.get_type() == ElementType.MacroClass: macroObj = meta.macro_class(*par_list, **macro_opts) else: macro_opts['function'] = code macroObj = MacroFunc(*par_list, **macro_opts) return macroObj def getMacroExecutor(self, door): me = self._macro_executors.get(door) if me is None: self._macro_executors[door] = me = MacroExecutor(door) return me class MacroExecutor(Logger): """ """ class RunSubXMLHook: def __init__(self, me, xml): self._me = me self._xml = xml def __call__(self): self._me._runXMLMacro(xml=self._xml) def __init__(self, door): self._door = door self._macro_counter = 0 # dict> # key PoolElement - reserved object # value set macros that reserved the object self._reserved_objs = {} # dict> # key Macro - macro object # value - sequence of reserverd objects by the macro self._reserved_macro_objs = {} # reset the stacks # self._macro_stack = None # self._xml_stack = None self._macro_stack = [] self._xml_stack = [] self._macro_pointer = None self._aborted = False self._stopped = False self._paused = False self._last_macro_status = None name = "%s.%s" % (str(door), self.__class__.__name__) self._macro_status_codec = CodecFactory().getCodec('json') self.call__init__(Logger, name) def getDoor(self): return self._door door = property(getDoor) def getMacroServer(self): return self.door.macro_server macro_server = property(getMacroServer) @property def macro_manager(self): return self.macro_server.macro_manager def getNewMacroID(self): self._macro_counter -= 1 return self._macro_counter def _preprocessParameters(self, par_str_list): if not par_str_list[0].lstrip().startswith('<'): xml_root = xml_seq = etree.Element('sequence') xml_macro = etree.SubElement(xml_seq, 'macro', name=par_str_list[0]) for p in par_str_list[1:]: etree.SubElement(xml_macro, 'param', value=p) else: xml_root = etree.fromstring(par_str_list[0]) macro_nodes = xml_root.findall('.//macro') # make sure macros exist self.__checkXMLSequence(macro_nodes) # fill the xml with macro id macro_line self.__fillXMLSequence(macro_nodes) return xml_root def __checkXMLSequence(self, macros): for macro in macros: name = macro.get('name') self.macro_manager.getMacro(name) def __fillXMLSequence(self, macros): for macro in macros: eid = macro.get('id') if eid is None: eid = str(self.getNewMacroID()) macro.set('id', eid) name = macro.get('name') params = [] # SEEMS THERE IS A MEMORY LEAK IN lxml.etree Element.xpath : # https://bugs.launchpad.net/lxml/+bug/397933 # https://mailman-mail5.webfaction.com/pipermail/lxml/2011-October/006205.html # We work around it using findall: #for p in macro.xpath('param|paramrepeat'): # if p.tag == 'param': # params.append(p.get('value')) # else: # params.extend([ p2.get('value') for p2 in p.findall(".//param")]) for p in macro.findall('*'): if p.tag == 'param': params.append(p.get('value')) elif p.tag == 'paramrepeat': params.extend([ p2.get('value') for p2 in p.findall(".//param")]) macro.set('macro_line', "%s(%s)" % (name, ", ".join(params))) def __preprocessResult(self, result): """decodes the given output from a macro in order to be able to send to the result channel as a sequence :param out: output value :return: the output as a sequence of strings """ if result is None: return () if is_non_str_seq(result): result = map(str, result) else: result = (str(result),) return result def _decodeXMLMacroParameters(self, xml_macro): str_params = [xml_macro.get('name')] for param in xml_macro.findall('.//param'): str_params.append(param.get('value')) return self._decodeMacroParameters(str_params) def _decodeMacroParameters(self, params): return self.macro_manager.decodeMacroParameters(self.door, params) def _prepareXMLMacro(self, xml_macro, parent_macro=None): macro_meta, _, params = self._decodeXMLMacroParameters(xml_macro) init_opts = { 'id' : xml_macro.get('id'), 'macro_line' : xml_macro.get('macro_line'), 'parent_macro' : parent_macro, } macro_obj = self._createMacroObj(macro_meta, params, init_opts) for macro in xml_macro.findall('macro'): hook = MacroExecutor.RunSubXMLHook(self, macro) hook_hints = macro.findall('hookPlace') if hook_hints is None: macro_obj.hooks = [ hook ] else: hook_places = [ h.text for h in hook_hints ] macro_obj.hooks = [ (hook, hook_places) ] prepare_result = self._prepareMacroObj(macro_obj, params) return macro_obj, prepare_result def _createMacroObj(self, macro_name_or_meta, pars, init_opts={}): macro_meta = macro_name_or_meta if isinstance(macro_meta, (str, unicode)): macro_meta = self.macro_manager.getMacro(macro_meta) macro_opts = { 'executor' : self, 'environment' : self.macro_server } macro_opts.update(init_opts) if not macro_opts.has_key('id'): macro_opts['id'] = str(self.getNewMacroID()) macroObj = self.macro_manager.createMacroObjFromMeta(macro_meta, pars, init_opts=macro_opts) return macroObj def _prepareMacroObj(self, macro_obj, pars, prepare_opts={}): return self.macro_manager.prepareMacroObj(macro_obj, pars, prepare_opts=prepare_opts) def prepareMacroObj(self, macro_name_or_meta, pars, init_opts={}, prepare_opts={}): """Prepare a new macro for execution :param macro_name_or_meta name: name of the macro to be prepared or the macro meta itself :param pars: list of parameter objects :param init_opts: keyword parameters for the macro constructor :param prepare_opts: keyword parameters for the macro prepare :return: a tuple of two elements: macro object, the result of preparing the macro""" macroObj = self._createMacroObj(macro_name_or_meta, pars, init_opts=init_opts) prepare_result = self._prepareMacroObj(macroObj, pars, prepare_opts=prepare_opts) return macroObj, prepare_result def prepareMacro(self, pars, init_opts={}, prepare_opts={}): """Prepare a new macro for execution Several different parameter formats are supported: 1. several parameters: 1.1 executor.prepareMacro('ascan', 'th', '0', '100', '10', '1.0') 1.2 executor.prepareMacro('ascan', 'th', 0, 100, 10, 1.0) 1.3 th = self.getObj('th'); executor.prepareMacro('ascan', th, 0, 100, 10, 1.0) 2. a sequence of parameters: 2.1 executor.prepareMacro(['ascan', 'th', '0', '100', '10', '1.0') 2.2 executor.prepareMacro(('ascan', 'th', 0, 100, 10, 1.0)) 2.3 th = self.getObj('th'); executor.prepareMacro(['ascan', th, 0, 100, 10, 1.0]) 3. a space separated string of parameters: executor.prepareMacro('ascan th 0 100 10 1.0') :param pars: the command parameters as explained above :param opts: keyword optional parameters for prepare :return: a tuple of two elements: macro object, the result of preparing the macro """ par0 = pars[0] if len(pars) == 1: if is_pure_str(par0): pars = par0.split(' ') elif is_non_str_seq(par0): pars = par0 pars = map(str, pars) macro_klass, str_pars, pars = self._decodeMacroParameters(pars) init_opts['macro_line'] = "%s(%s) -> [%s]" % (str_pars[0], ", ".join(str_pars[1:]), id) if not init_opts.has_key('id'): init_opts['id'] = str(self.getNewMacroID()) return self.prepareMacroObj(macro_klass, pars, init_opts, prepare_opts) def getRunningMacro(self): return self._macro_pointer def __stopObjects(self): """Stops all the reserved objects in the executor""" for _, objs in self._reserved_macro_objs.items(): for obj in objs: try: obj.stop() except AttributeError: pass except: self.warning("Unable to stop %s" % obj) self.debug("Details:", exc_info=1) def __abortObjects(self): """Aborts all the reserved objects in the executor""" for _, objs in self._reserved_macro_objs.items(): for obj in objs: try: obj.abort() except AttributeError: pass except: self.warning("Unable to abort %s" % obj) self.debug("Details:", exc_info=1) def abort(self): self.macro_server.add_job(self._abort, None) def stop(self): self.macro_server.add_job(self._stop, None) def _abort(self): m = self.getRunningMacro() if m is not None: self._aborted = True m.abort() self.__abortObjects() def _stop(self): m = self.getRunningMacro() if m is not None: self._stopped = True m.stop() if m.isPaused(): m.resume(cb=self._macroResumed) self.__stopObjects() def pause(self): self._paused = True m = self.getRunningMacro() if m is not None: m.pause(cb=self._macroPaused) def _macroPaused(self, m): """Calback that is executed when the macro has efectively paused""" self.sendMacroStatusPause() self.sendState(Macro.Pause) def resume(self): if not self._paused: return self._paused = False m = self.getRunningMacro() if m is not None: m.resume(cb=self._macroResumed) def _macroResumed(self, m): """Callback that is executed when the macro has effectively resumed execution after being paused""" self.sendMacroStatusResume() self.sendState(Macro.Running) def run(self, params, asynch=True): """Runs the given macro(s) :param params: (sequence) can be either a sequence of [, ] or a sequence with a single element which represents the xml string for a macro script :return: (lxml.etree.Element) the xml representation of the running macro """ # dict> # key PoolElement - reserved object # value set macros that reserved the object self._reserved_objs = {} # dict> # key Macro - macro object # value - sequence of reserved objects by the macro self._reserved_macro_objs = {} # reset the stacks self._macro_stack = [] self._xml_stack = [] self._macro_pointer = None self._aborted = False self._stopped = False self._paused = False self._last_macro_status = None # convert given parameters into an xml self._xml = self._preprocessParameters(params) if asynch: # start the job of actually running the macro self.macro_server.add_job(self.__runXML, self._jobEnded) #return the proper xml return self._xml else: self.__runXML() #return self._macro_pointer.getResult() def _jobEnded(self, *args, **kw): self.debug("Job ended (stopped=%s, aborted=%s)", self._stopped, self._aborted) def __runXML(self): self.sendState(Macro.Running) try: self.__runStatelessXML() self.sendState(Macro.Finished) except AbortException: self.sendState(Macro.Abort) except Exception: self.sendState(Macro.Abort) finally: self._macro_stack = None self._xml_stack = None def __runStatelessXML(self, xml=None): if xml is None: xml = self._xml node = xml.tag if node == 'sequence': for xml_macro in xml.findall('macro'): self.__runXMLMacro(xml_macro) elif node == 'macro': self.__runXMLMacro(xml) def __runXMLMacro(self, xml): assert xml.tag == 'macro' try: macro_obj, _ = self._prepareXMLMacro(xml) except AbortException as ae: raise ae except Exception as e: door = self.door door.error("Error: %s", str(e)) door.debug("Error details:", exc_info=1) raise e self._xml_stack.append(xml) try: self.runMacro(macro_obj) finally: self._xml_stack.pop() _runXMLMacro = __runXMLMacro def runMacro(self, macro_obj): name = macro_obj._getName() desc = macro_obj._getDescription() door = self.door if self._aborted: self.sendMacroStatusAbort() raise AbortException("aborted between macros (before %s)" % name) elif self._stopped: self.sendMacroStatusStop() raise StopException("stopped between macros (before %s)" % name) macro_exp, tb, result = None, None, None try: self.debug("[START] runMacro %s" % desc) self._macro_pointer = macro_obj self._macro_stack.append(macro_obj) for step in macro_obj.exec_(): self.sendMacroStatus((step,)) if macro_obj.hasResult() and macro_obj.getParentMacro() is None: result = self.__preprocessResult(macro_obj.getResult()) door.debug("sending result %s", result) self.sendResult(result) except AbortException as ae: macro_exp = ae except StopException as se: macro_exp = se except MacroServerException as mse: exc_info = sys.exc_info() macro_exp = mse if not mse.traceback: mse.traceback = traceback.format_exc() except DevFailed as df: exc_info = sys.exc_info() exp_pars = {'type' : df[0].reason, 'msg' : df[0].desc, 'args' : df.args, 'traceback' : traceback.format_exc() } macro_exp = MacroServerException(exp_pars) except Exception, err: exc_info = sys.exc_info() exp_pars = {'type' : err.__class__.__name__, 'msg' : err.args[0], 'args' : err.args, 'traceback' : traceback.format_exc() } macro_exp = MacroServerException(exp_pars) finally: self.returnObjs(self._macro_pointer) # make sure the macro's on_abort is called and that a proper macro # status is sent if self._stopped: macro_obj._stopOnError() self.sendMacroStatusStop() elif self._aborted: macro_obj._abortOnError() self.sendMacroStatusAbort() # From this point on don't call any method of macro_obj which is part # of the mAPI (methods decorated with @mAPI) to avoid throwing an # AbortException if an Abort has been performed. if macro_exp is not None: if not self._stopped and not self._aborted: self.sendMacroStatusException(exc_info) self.debug("[ENDEX] (%s) runMacro %s" % (macro_exp.__class__.__name__, name)) if isinstance(macro_exp, MacroServerException) and macro_obj.parent_macro is None: door.debug(macro_exp.traceback) door.error("An error occurred while running %s:\n%s" % (macro_obj.description, macro_exp.msg)) self._popMacro() raise macro_exp self.debug("[ END ] runMacro %s" % desc) self._popMacro() return result def _popMacro(self): self._macro_stack.pop() length = len(self._macro_stack) if length > 0: self._macro_pointer = self._macro_stack[-1] #disable macro data for now. Comment following lines to enable it again else: self._macro_pointer = None def sendState(self, state): return self.door.set_state(state) def sendStatus(self, status): return self.door.set_status(status) def sendResult(self, result): return self.door.set_result(result) def getLastMacroStatus(self): return self._macro_pointer._getMacroStatus() def sendMacroStatusFinish(self): ms = self.getLastMacroStatus() if ms is not None: ms['state'] = 'finish' self.debug("Sending finish event") self.sendMacroStatus((ms,)) def sendMacroStatusStop(self): ms = self.getLastMacroStatus() if ms is not None: ms['state'] = 'stop' self.debug("Sending stop event") self.sendMacroStatus((ms,)) def sendMacroStatusAbort(self): ms = self.getLastMacroStatus() if ms is not None: ms['state'] = 'abort' self.debug("Sending abort event") self.sendMacroStatus((ms,)) def sendMacroStatusException(self, exc_info): ms = self.getLastMacroStatus() if ms is not None: ms['state'] = 'exception' ms['exc_type'] = str(exc_info[0]) ms['exc_value'] = str(exc_info[1]) ms['exc_stack'] = traceback.format_exception(*exc_info) self.debug("Sending exception event") self.sendMacroStatus((ms,)) def sendMacroStatusPause(self): ms = self.getLastMacroStatus() if ms is not None and len(ms) > 0: ms['state'] = 'pause' self.debug("Sending pause event") self.sendMacroStatus((ms,)) def sendMacroStatusResume(self): ms = self.getLastMacroStatus() if ms is not None and len(ms) > 0: ms['state'] = 'resume' self.debug("Sending resume event") self.sendMacroStatus((ms,)) def sendMacroStatus(self, data): self._last_macro_status = data #data = self._macro_status_codec.encode(('', data)) return self.door.set_macro_status(data) def sendRecordData(self, data, codec=None): return self.door.set_record_data(data, codec=codec) def reserveObj(self, obj, macro_obj, priority=0): if obj is None or macro_obj is None: return # Fill _reserved_macro_objs objs = self._reserved_macro_objs[macro_obj] = \ self._reserved_macro_objs.get(macro_obj, list()) if not obj in objs: if priority: objs.insert(0, obj) else: objs.append(obj) # Fill _reserved_objs macros = self._reserved_objs[obj] = self._reserved_objs.get(obj, set()) macros.add(macro_obj) # Tell the object that it is reserved by a new macro if hasattr(obj, 'reserve'): obj.reserve(macro_obj) def returnObjs(self, macro_obj): """Free the macro reserved objects""" if macro_obj is None: return objs = self._reserved_macro_objs.get(macro_obj) if objs is None: return # inside returnObj we change the list so we have to iterate with a copy for obj in copy.copy(objs): self.returnObj(obj, macro_obj) def returnObj(self, obj, macro_obj): """Free an object reserved by a macro""" if obj is None or macro_obj is None: return if hasattr(obj, 'unreserve'): obj.unreserve() objs = self._reserved_macro_objs.get(macro_obj) if objs is None: return objs.remove(obj) if len(objs) == 0: del self._reserved_macro_objs[macro_obj] try: macros = self._reserved_objs[obj] macros.remove(macro_obj) if not len(macros): del self._reserved_objs[obj] except KeyError: self.debug("Unexpected KeyError trying to remove reserved object") sardana-1.2.0/src/sardana/macroserver/msmanager.py0000644000234100017500000000360312174204311023601 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## __all__ = ["MacroServerManager"] __docformat__ = 'restructuredtext' import weakref from taurus.core import ManagerState from taurus.core.util import Logger class MacroServerManager(Logger): """Base Class for macro server managers""" def __init__(self, macro_server): name = macro_server.name + "." + self.__class__.__name__ self._state = ManagerState.UNINITIALIZED self._macro_server = weakref.ref(macro_server) self.call__init__(Logger, name) self.reInit() def reInit(self): self._state = ManagerState.INITED def cleanUp(self): self._state = ManagerState.CLEANED @property def macro_server(self): return self._macro_server() def is_initialized(self): return self._state == ManagerState.INITED def is_cleaned(self): return self._state == ManagerState.CLEANEDsardana-1.2.0/src/sardana/macroserver/msmetamacro.py0000644000234100017500000002364312174204311024145 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the class definition for the MacroServer meta macro information""" __all__ = ["MACRO_TEMPLATE", "MacroLibrary", "MacroClass", "MacroFunction"] __docformat__ = 'restructuredtext' import inspect import operator from sardana import InvalidId, ElementType from sardana.sardanameta import SardanaLibrary, SardanaClass, SardanaFunction from msparameter import Type, ParamRepeat MACRO_TEMPLATE = """class @macro_name@(Macro): \"\"\"@macro_name@ description.\"\"\" # uncomment the following lines as necessary. Otherwise you may delete them #param_def = [] #result_def = [] #hints = {} #env = (,) # uncomment the following lines if need prepare. Otherwise you may delete them #def prepare(self): # pass def run(self): pass """ MACRO_TEMPLATE = """\ @macro() def @macro_name@(self): self.output("Running @macro_name@...") """ class MacroLibrary(SardanaLibrary): """Object representing a python module containing macro classes and/or macro functions. Public members: - module - reference to python module - file_path - complete (absolute) path (with file name at the end) - file_name - file name (including file extension) - path - complete (absolute) path - name - (=module name) module name (without file extension) - macros - dict - exc_info - exception information if an error occurred when loading the module""" def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('macro_server') kwargs['elem_type'] = ElementType.MacroLibrary SardanaLibrary.__init__(self, **kwargs) def serialize(self, *args, **kwargs): kwargs = SardanaLibrary.serialize(self, *args, **kwargs) kwargs['macro_server'] = self.get_manager().name kwargs['id'] = InvalidId return kwargs get_macro = SardanaLibrary.get_meta get_macros = SardanaLibrary.get_metas has_macro = SardanaLibrary.has_meta add_macro_class = SardanaLibrary.add_meta_class get_macro_class = SardanaLibrary.get_meta_class get_macro_classes = SardanaLibrary.get_meta_classes has_macro_class = SardanaLibrary.has_meta_class add_macro_function = SardanaLibrary.add_meta_function get_macro_function = SardanaLibrary.get_meta_function get_macro_functions = SardanaLibrary.get_meta_functions has_macro_function = SardanaLibrary.has_meta_function @property def macros(self): ret = {} ret.update(self.meta_classes) ret.update(self.meta_functions) return ret class Parameterizable(object): """Helper class to handle parameter and result definition for a :class:`~sardana.macroserver.msmetamacro.MacroClass` or a :class:`~sardana.macroserver.msmetamacro.MacroFunction`""" def __init__(self): self._parameter = self.build_parameter() self._result = self.build_result() def get_parameter_definition(self): raise NotImplementedError def get_result_definition(self): raise NotImplementedError def get_hints_definition(self): raise NotImplementedError def get_parameter(self): return self._parameter def get_result(self): return self._result def build_parameter(self): return self._build_parameter(self.get_parameter_definition()) def build_result(self): return self._build_parameter(self.get_result_definition()) def _build_parameter(self, param_def): ret = [] param_def = param_def or () for p in param_def: t = p[1] ret_p = {'min': 1, 'max': None} # take care of old ParamRepeat if isinstance(t, ParamRepeat): t = t.obj() if operator.isSequenceType(t) and not isinstance(t, (str, unicode)): if operator.isMappingType(t[-1]): ret_p.update(t[-1]) t = self._build_parameter(t[:-1]) else: t = self._build_parameter(t) ret_p['name'] = p[0] ret_p['type'] = t ret_p['default_value'] = p[2] ret_p['description'] = p[3] ret.append(ret_p) return ret def build_parameter_info(self, param_def=None): param_def = param_def or self.get_parameter_definition() info = [str(len(param_def))] for name, type_class, def_val, desc in param_def: repeat = isinstance(type_class, ParamRepeat) info.append(name) type_name = (repeat and 'ParamRepeat') or type_class info.append(type_name) info.append(desc) if repeat: rep = type_class opts = sep = '' for opt, val in rep.items(): opts += '%s%s=%s' % (sep, opt, val) sep = ', ' info.append(opts) info += self.get_parameter_info(rep.param_def) else: info.append(str(def_val)) return info def build_result_info(self, result_def=None): result_def = result_def or self.get_result_definition() info = [str(len(result_def))] for name, type_class, def_val, desc in result_def: repeat = isinstance(type_class, ParamRepeat) info.append(name) type_name = (repeat and 'ParamRepeat') or type_class info.append(type_name) info.append(desc) if repeat: rep = type_class opts = sep = '' for opt, val in rep.items(): opts += '%s%s=%s' % (sep, opt, val) sep = ', ' info.append(opts) info += self.get_parameter_info(rep.param_def) else: info.append(str(def_val)) return info def get_info(self): info = [self.full_name, self.description, str(self.code_object.hints)] info += self.get_parameter_info() info += self.get_result_info() return info def serialize(self, *args, **kwargs): kwargs['macro_server'] = self.get_manager().name kwargs['id'] = InvalidId kwargs['hints'] = self.code_object.hints param, result = self.get_parameter(), self.get_result() kwargs['parameters'] = param kwargs['result'] = result return kwargs class MacroClass(SardanaClass, Parameterizable): def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('macro_server') kwargs['elem_type'] = ElementType.MacroClass SardanaClass.__init__(self, **kwargs) Parameterizable.__init__(self) def serialize(self, *args, **kwargs): kwargs = SardanaClass.serialize(self, *args, **kwargs) kwargs = Parameterizable.serialize(self, *args, **kwargs) return kwargs @property def macro_class(self): return self.klass def get_parameter_definition(self): return self.klass.param_def def get_result_definition(self): return self.klass.result_def def get_hints_definition(self): return self.klass.hints class MacroFunction(SardanaFunction, Parameterizable): def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('macro_server') kwargs['elem_type'] = ElementType.MacroFunction SardanaFunction.__init__(self, **kwargs) Parameterizable.__init__(self) def serialize(self, *args, **kwargs): kwargs = SardanaFunction.serialize(self, *args, **kwargs) kwargs = Parameterizable.serialize(self, *args, **kwargs) return kwargs @property def macro_function(self): return self.function def to_parameter_definition(self): param_def = [] args, varargs, keywords, defaults = inspect.getargspec(self.function) assert keywords is None assert len(args) > 0 if varargs is None: for arg in args[1:]: param_def.append((arg, Type.Any, None, arg + " parameter")) i = len(param_def)-1 if defaults is not None: for default in reversed(defaults): param_def[i][2] = default i -= 1 else: param_def.append( (varargs , [[ varargs, Type.Any, None, varargs + " parameter"]], None, "list of " + varargs)) return param_def def get_parameter_definition(self): param_def = self.function.param_def if param_def is None: param_def = self.to_parameter_definition() return param_def def get_result_definition(self): result_def = self.function.result_def return result_def def get_hints_definition(self): return self.function.hints or () sardana-1.2.0/src/sardana/macroserver/msoptions.py0000644000234100017500000000334612174204311023666 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains a definition for ViewOptions""" from __future__ import with_statement from __future__ import print_function __all__ = ['ViewOption'] def ViewOptionMeta(name, bases, attrs): for k in attrs['_DEFAULT_VIEW_OPTIONS']: attrs[k] = k return type(name, bases, attrs) class ViewOption(object): __metaclass__ = ViewOptionMeta _DEFAULT_VIEW_OPTIONS = { 'ShowDial' : True, } @classmethod def init_options(cls, d): d.update(cls._DEFAULT_VIEW_OPTIONS) return d @classmethod def reset_option(cls, d, name): if name in cls._DEFAULT_VIEW_OPTIONS: d[name] = cls._DEFAULT_VIEW_OPTIONS[name] else: del d[name] sardana-1.2.0/src/sardana/macroserver/msparameter.py0000644000234100017500000003162712174204311024156 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of the macroserver parameters for macros""" __all__ = ["WrongParam", "MissingParam", "UnknownParamObj", "WrongParamType", "TypeNames", "Type", "ParamType", "ParamRepeat", "ElementParamType", "ElementParamInterface", "AttrParamType", "AbstractParamTypes", "ParamDecoder" ] __docformat__ = 'restructuredtext' from taurus.core.util import CaselessDict from sardana import ElementType, INTERFACES_EXPANDED from sardana.macroserver.msbase import MSBaseObject from .msexception import MacroServerException, UnknownMacro, UnknownMacroLibrary class WrongParam(MacroServerException): def __init__(self, *args): MacroServerException.__init__(self, *args) self.type = 'Wrong parameter' class MissingParam(WrongParam): def __init__(self, *args): WrongParam.__init__(self, *args) self.type = 'Missing parameter' class UnknownParamObj(WrongParam): def __init__(self, *args): WrongParam.__init__(self, *args) self.type = 'Unknown parameter' class WrongParamType(WrongParam): def __init__(self, *args): WrongParam.__init__(self, *args) self.type = 'Unknown parameter type' class TypeNames: """Class that holds the list of registered macro parameter types""" def __init__(self): self._type_names = {} self._pending_type_names = {} def addType(self, name): """Register a new macro parameter type""" setattr(self, name, name) self._type_names[name] = name if name in self._pending_type_names: del self._pending_type_names[name] def removeType(self, name): """remove a macro parameter type""" delattr(self, name) try: del self._type_names[name] except ValueError: pass def __str__(self): return str(self._type_names.keys()) # def __getattr__(self, name): # if name not in self._pending_type_names: # self._pending_type_names[name] = name # return self._pending_type_names[name] # This instance of TypeNames is intended to provide access to types to the # Macros in a "Type.Motor" fashion Type = TypeNames() class ParamType(MSBaseObject): All = 'All' # Capabilities ItemList = 'ItemList' ItemListEvents = 'ItemListEvents' capabilities = [] type_class = str def __init__(self, macro_server, name): MSBaseObject.__init__(self, name=name, full_name=name, macro_server=macro_server, elem_type=ElementType.ParameterType) def getName(self): return self.name def getObj(self, str_repr): return self.type_class(str_repr) @classmethod def hasCapability(cls, cap): return cap in cls.capabilities def serialize(self, *args, **kwargs): kwargs = MSBaseObject.serialize(self, *args, **kwargs) kwargs['composed'] = False return kwargs class ParamRepeat(object): # opts: min, max def __init__(self, *param_def, **opts): self.param_def = param_def self.opts = {'min': 1, 'max': None} self.opts.update(opts) self._obj = list(param_def) self._obj.append(self.opts) def items(self): return self.opts.items() def __getattr__(self, name): return self.opts[name] def obj(self): return self._obj class ElementParamType(ParamType): capabilities = ParamType.ItemList, ParamType.ItemListEvents def __init__(self, macro_server, name): ParamType.__init__(self, macro_server, name) def accepts(self, elem): return elem.getType() == self._name def getObj(self, name, pool=ParamType.All, cache=False): macro_server = self.macro_server if pool == ParamType.All: pools = macro_server.get_pools() else: pools = macro_server.get_pool(pool), for pool in pools: elem_info = pool.getObj(name, elem_type=self._name) if elem_info is not None and self.accepts(elem_info): return elem_info # not a pool object, maybe it is a macro server object (perhaps a macro # code or a macro library try: return macro_server.get_macro(name) except UnknownMacro: pass try: return macro_server.get_macro_lib(name) except UnknownMacroLibrary: pass def getObjDict(self, pool=ParamType.All, cache=False): macro_server = self.macro_server objs = CaselessDict() if pool == ParamType.All: pools = macro_server.get_pools() else: pools = macro_server.get_pool(pool), for pool in pools: for elem_info in pool.getElements(): if self.accepts(elem_info): objs[elem_info.name] = elem_info for macro_lib_name, macro_lib in macro_server.get_macros().items(): if self.accepts(macro_lib): objs[macro_lib_name] = macro_lib for macro_name, macro in macro_server.get_macros().items(): if self.accepts(macro): objs[macro_name] = macro return objs def getObjListStr(self, pool=ParamType.All, cache=False): obj_dict = self.getObjDict(pool=pool, cache=cache) return obj_dict.keys() def getObjList(self, pool=ParamType.All, cache=False): obj_dict = self.getObjDict(pool=pool, cache=cache) return obj_dict.values() def serialize(self, *args, **kwargs): kwargs = ParamType.serialize(self, *args, **kwargs) kwargs['composed'] = True return kwargs class ElementParamInterface(ElementParamType): def __init__(self, macro_server, name): ElementParamType.__init__(self, macro_server, name) bases, doc = INTERFACES_EXPANDED.get(name) self._interfaces = bases def accepts(self, elem): elem_type = elem.getType() elem_interfaces = INTERFACES_EXPANDED.get(elem_type)[0] if elem_interfaces is None: return ElementParamType.accepts(self, elem) return self._name in elem_interfaces def getObj(self, name, pool=ParamType.All, cache=False): macro_server = self.macro_server if pool == ParamType.All: pools = macro_server.get_pools() else: pools = macro_server.get_pool(pool), for pool in pools: elem_info = pool.getElementWithInterface(name, self._name) if elem_info is not None and self.accepts(elem_info): return elem_info # not a pool object, maybe it is a macro server object (perhaps a macro # class or a macro library try: return macro_server.get_macro(name) except UnknownMacro: pass try: return macro_server.get_macro_lib(name) except UnknownMacroLibrary: pass def getObjDict(self, pool=ParamType.All, cache=False): macro_server = self.macro_server objs = CaselessDict() if macro_server.is_macroserver_interface(self._name): return macro_server.get_elements_with_interface(self._name) if pool == ParamType.All: pools = macro_server.get_pools() else: pools = macro_server.get_pool(pool), for pool in pools: for elem_info in pool.getElementsWithInterface(self._name).values(): if self.accepts(elem_info): objs[elem_info.name] = elem_info return objs def getObjListStr(self, pool=ParamType.All, cache=False): obj_dict = self.getObjDict(pool=pool, cache=cache) return obj_dict.keys() def getObjList(self, pool=ParamType.All, cache=False): obj_dict = self.getObjDict(pool=pool, cache=cache) return obj_dict.values() class AttrParamType(ParamType): pass AbstractParamTypes = ParamType, ElementParamType, ElementParamInterface, AttrParamType class ParamDecoder: def __init__(self, door, macro_meta, param_str_list): self.door = door self.macro_meta = macro_meta self.param_str_list = param_str_list self.param_list = None self.decode() @property def type_manager(self): return self.door.type_manager def decode(self): macro_meta = self.macro_meta macro_type = macro_meta.get_type() pars_str = self.param_str_list[1:] pars_def = macro_meta.get_parameter_definition() if macro_type == ElementType.MacroClass: _, self.param_list = self.decodeNormal(pars_str, pars_def) elif macro_type == ElementType.MacroFunction: if macro_meta.function.param_def is None: self.param_list = self.param_str_list[1:] else: _, self.param_list = self.decodeNormal(pars_str, pars_def) return self.param_list def decodeNormal(self, str_list, def_list): str_len = len(str_list) par_len = len(def_list) obj_list = [] str_idx = 0 for i, par_def in enumerate(def_list): name, type_class, def_val, desc = par_def if str_idx == str_len: if def_val is None: if not isinstance(type_class, ParamRepeat): raise MissingParam, "'%s' not specified" % name elif isinstance(type_class, ParamRepeat): min = par_def[1].opts['min'] if min > 0: raise WrongParam, "'%s' demands at least %d values" % (name, min) new_obj_list = [] if not def_val is None: new_obj_list.append(def_val) else: if isinstance(type_class, ParamRepeat): data = self.decodeRepeat(str_list[str_idx:], par_def) dec_token, new_obj_list = data else: type_manager = self.type_manager type_name = type_class type_class = type_manager.getTypeClass(type_name) par_type = type_manager.getTypeObj(type_name) par_str = str_list[str_idx] try: val = par_type.getObj(par_str) except ValueError, e: raise WrongParamType, e.message if val is None: msg = 'Could not create %s parameter "%s" for "%s"' % \ (par_type.getName(), name, par_str) raise WrongParam, msg dec_token = 1 new_obj_list = [val] str_idx += dec_token obj_list += new_obj_list return str_idx, obj_list def decodeRepeat(self, str_list, par_def): name, rep_data, def_val, desc = par_def min_rep = rep_data.min max_rep = rep_data.max dec_token = 0 obj_list = [] rep_nr = 0 while dec_token < len(str_list): if max_rep is not None and rep_nr == max_rep: break new_token, new_obj_list = self.decodeNormal(str_list[dec_token:], rep_data.param_def) dec_token += new_token if len(new_obj_list) == 1: new_obj_list = new_obj_list[0] obj_list.append(new_obj_list) rep_nr += 1 if rep_nr < min_rep: msg = 'Found %d repetitions of param %s, min is %d' % \ (rep_nr, name, min_rep) raise RuntimeError, msg return dec_token, obj_list def getParamList(self): return self.param_list def __getattr__(self, name): return getattr(self.param_list, name) sardana-1.2.0/src/sardana/macroserver/mstypemanager.py0000644000234100017500000001223612174204311024505 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of the macroserver data type manager""" __all__ = ["TypeManager"] __docformat__ = 'restructuredtext' import os import inspect from sardana.sardanamodulemanager import ModuleManager from msparameter import Type, ParamType, AbstractParamTypes from msmanager import MacroServerManager _BASE_DIR = os.path.dirname(os.path.abspath(__file__)) class TypeManager(MacroServerManager): DEFAULT_TYPE_DIR = _BASE_DIR DEFAULT_TYPE_MODULES = 'basetypes', def reInit(self): if self.is_initialized(): return # dict> # key - module name (without path and without extension) # value - a dict where: # key - type name # value - class object implementing the Type self._modules = {} # dict # key - type name # value - object which inherits from ParamType self._inst_dict = {} path = [ self.DEFAULT_TYPE_DIR ] for type_module in self.DEFAULT_TYPE_MODULES: self.reloadTypeModule(type_module, path=path) MacroServerManager.reInit(self) def cleanUp(self): if self.is_cleaned(): return if self._modules: for _, types_dict in self._modules.items(): for type_name in types_dict: Type.removeType(type_name) self._modules = None self._inst_dict = None MacroServerManager.cleanUp(self) def getTypeListObj(self): return self._type_list_obj def reloadTypeModule(self, module_name, path=None): """Loads/reloads the given module name""" #path = path or [ os.path.dirname(__file__) ] m = None try: m = ModuleManager().reloadModule(module_name, path) except: pass if m is None: if self._modules.has_key(module_name): self._modules.pop(module_name) return self._modules[module_name] = {} abs_file = inspect.getabsfile(m) ms = self.macro_server for name in dir(m): if name.startswith("_"): continue klass = getattr(m, name) try: if not issubclass(klass, ParamType): continue except: continue if klass in AbstractParamTypes: continue if inspect.getabsfile(klass) != abs_file: continue t = klass(ms, name) self.addType(t) def addType(self, type_obj): type_name = type_obj.getName() type_class = type_obj.__class__ module_name = type_obj.__module__ mod_types = self._modules[module_name] #action = (((type_name in mod_types) and "Updating") \ # or "Adding") action = "Updating" self.debug("%s type %s", action, type_name) mod_types[type_name] = type_class self._inst_dict[type_name] = type_obj Type.addType(type_name) def getTypeListStr(self): type_list_basic, type_list_obj = [], [] for module_name, type_class_dict in self._modules.items(): for tname, tklass in type_class_dict.items(): if tklass.hasCapability(ParamType.ItemList): type_list_obj.append("%s*" % tname) else: type_list_basic.append(tname) type_list = sorted(type_list_basic) + sorted(type_list_obj) return type_list def getTypeClass(self, type_name): for module_name, type_class_dict in self._modules.items(): tklass = type_class_dict.get(type_name) if tklass is None: continue return tklass return None def getTypeObj(self, type_name): return self._inst_dict.get(type_name) def getTypes(self): return self._inst_dict def getTypeNames(self): return self._inst_dict.keys()sardana-1.2.0/src/sardana/pool/0000755000234100017500000000000012174204361017701 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/pool/poolcontrollers/0000755000234100017500000000000012174204361023141 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/pool/poolcontrollers/DiscretePseudoMotorController.py0000755000234100017500000001475712174204313031540 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of a discrete pseudo motor controller for the Sardana Device Pool""" __all__ = ["DiscretePseudoMotorController"] __docformat__ = 'restructuredtext' import json from sardana import DataAccess from sardana.pool.controller import PseudoMotorController from sardana.pool.controller import Type, Access, Description CALIBRATION = 'Calibration' LABELS = 'Labels' class DiscretePseudoMotorController(PseudoMotorController): """A discrete pseudo motor controller which converts physical motor positions to discrete values""" gender = "DiscretePseudoMotorController" model = "PseudoMotor" organization = "Sardana team" image = "" pseudo_motor_roles = ("OutputMotor",) motor_roles = ("InputMotor",) axis_attributes = {CALIBRATION:#type hackish until arrays supported {Type : str, Description : 'Flatten list of a list of triples and [min,cal,max]', Access : DataAccess.ReadWrite, 'fget' : 'get%s' % CALIBRATION, 'fset' : 'set%s' % CALIBRATION}, LABELS:#type hackish until arrays supported {Type : str, Description : 'String list with the meaning of each discrete position', Access : DataAccess.ReadWrite, 'fget' : 'get%s' % LABELS, 'fset' : 'set%s' % LABELS} } def __init__(self, inst, props, *args, **kwargs): PseudoMotorController.__init__(self, inst, props, *args, **kwargs) self._calibration = None self._positions = None self._labels = None def GetAxisAttributes(self, axis): axis_attrs = PseudoMotorController.GetAxisAttributes(self, axis) axis_attrs = dict(axis_attrs) axis_attrs['Position']['type'] = int return axis_attrs def CalcPseudo(self, axis, physical_pos, curr_pseudo_pos): llabels = len(self._labels) positions = self._positions calibration = self._calibration lcalibration = len(calibration) value = physical_pos[0] #case 0: nothing to translate, only round about integer the attribute value if llabels == 0: return int(value) #case 1: only uses the labels. Available positions in POSITIONS elif lcalibration == 0: value = int(value) try: positions.index(value) except: raise Exception("Invalid position.") else: return value #case 1+fussy: the physical position must be in one of the defined #ranges, and the DiscretePseudoMotor position is defined in labels elif llabels == lcalibration: for fussyPos in calibration: if value >= fussyPos[0] and value <= fussyPos[2]: return positions[calibration.index(fussyPos)] #if the loop ends, current value is not in the fussy areas. raise Exception("Invalid position.") else: raise Exception("Bad configuration on axis attributes.") def CalcPhysical(self, axis, pseudo_pos, curr_physical_pos): #If Labels is well defined, the write value must be one this struct llabels = len(self._labels) positions = self._positions calibration = self._calibration lcalibration = len(calibration) value = pseudo_pos[0] #case 0: nothing to translate, what is written goes to the attribute if llabels == 0: return value #case 1: only uses the labels. Available positions in POSITIONS elif lcalibration == 0: self._log.debug("Value = %s", value) try: positions.index(value) except: raise Exception("Invalid position.") return value #case 1+fussy: the write to the to the DiscretePseudoMotorController #is translated to the central position of the calibration. elif llabels == lcalibration: self._log.debug("Value = %s", value) try: destination = positions.index(value) except: raise Exception("Invalid position.") self._log.debug("destination = %s", destination) calibrated_position = calibration[destination][1]#central element self._log.debug("calibrated_position = %s", calibrated_position) return calibrated_position def getLabels(self,axis): #hackish until we support DevVarDoubleArray in extra attrs labels = self._labels positions = self._positions labels_str = "" for i in range(len(labels)): labels_str += "%s:%d "%(labels[i],positions[i]) return labels_str[:-1]#remove the final space def setLabels(self,axis,value): #hackish until we support DevVarStringArray in extra attrs labels = [] positions = [] for pair in value.split(): l,p = pair.split(':') labels.append(l) positions.append(int(p)) if len(labels) == len(positions): self._labels = labels self._positions = positions else: raise Exception("Rejecting labels: invalid structure") def getCalibration(self,axis): return json.dumps(self._calibration) def setCalibration(self,axis,value): try: self._calibration = json.loads(value) except: raise Exception("Rejecting calibration: invalid structure") sardana-1.2.0/src/sardana/pool/poolcontrollers/DummyCounterTimerController.py0000644000234100017500000001357412174204313031222 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import time from sardana import State from sardana.pool.controller import CounterTimerController class Channel: def __init__(self,idx): self.idx = idx # 1 based index self.value = 0.0 self.is_counting = False self.active = True class DummyCounterTimerController(CounterTimerController): "This class is the Tango Sardana CounterTimer controller for tests" gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 StoppedMode = 0 TimerMode = 1 MonitorMode = 2 CounterMode = 3 def __init__(self, inst, props, *args, **kwargs): CounterTimerController.__init__(self, inst, props, *args, **kwargs) self.channels = self.MaxDevice*[None,] self.reset() def reset(self): self.start_time = None self.integ_time = None self.monitor_count = None self.read_channels = {} self.counting_channels = {} def AddDevice(self,ind): idx = ind - 1 self.channels[idx] = Channel(ind) def DeleteDevice(self,ind): idx = ind - 1 self.channels[idx] = None def PreStateAll(self): pass def PreStateOne(self, ind): pass def StateAll(self): pass def StateOne(self, ind): idx = ind - 1 sta = State.On status = "Stopped" if ind in self.counting_channels: channel = self.channels[idx] now = time.time() elapsed_time = now - self.start_time self._updateChannelState(ind, elapsed_time) if channel.is_counting: sta = State.Moving status = "Acquiring" return sta, status def _updateChannelState(self, ind, elapsed_time): if self.integ_time is not None: # counting in time if elapsed_time >= self.integ_time: self._finish(elapsed_time) elif self.monitor_count is not None: # monitor counts v = int(elapsed_time*100*ind) if v >= self.monitor_count: self._finish(elapsed_time) def _updateChannelValue(self, ind, elapsed_time): channel = self.channels[ind-1] if self.integ_time is not None: t = elapsed_time if not channel.is_counting: t = self.integ_time if ind == self._timer: channel.value = t else: channel.value = t * channel.idx elif self.monitor_count is not None: channel.value = int(elapsed_time*100*ind) if ind == self._monitor: if not channel.is_counting: channel.value = self.monitor_count def _finish(self, elapsed_time, ind=None): if ind is None: for ind, channel in self.counting_channels.items(): channel.is_counting = False self._updateChannelValue(ind, elapsed_time) else: if ind in self.counting_channels: channel = self.counting_channels[ind] channel.is_counting = False self._updateChannelValue(ind, elapsed_time) else: channel = self.channels[ind-1] channel.is_counting = False self.counting_channels = {} def PreReadAll(self): self.read_channels = {} def PreReadOne(self,ind): channel = self.channels[ind-1] self.read_channels[ind] = channel def ReadAll(self): # if in acquisition then calculate the values to return if self.counting_channels: now = time.time() elapsed_time = now - self.start_time for ind, channel in self.read_channels.items(): self._updateChannelState(ind, elapsed_time) if channel.is_counting: self._updateChannelValue(ind, elapsed_time) def ReadOne(self, ind): v = self.read_channels[ind].value return v def PreStartAll(self): self.counting_channels = {} def PreStartOne(self, ind, value=None): idx = ind - 1 channel = self.channels[idx] channel.value = 0.0 self.counting_channels[ind] = channel return True def StartOne(self, ind, value=None): self.counting_channels[ind].is_counting = True def StartAll(self): self.start_time = time.time() def LoadOne(self, ind, value): if value > 0: self.integ_time = value self.monitor_count = None else: self.integ_time = None self.monitor_count = -value def AbortOne(self, ind): now = time.time() if ind in self.counting_channels: elapsed_time = now - self.start_time self._finish(elapsed_time, ind=ind) sardana-1.2.0/src/sardana/pool/poolcontrollers/DummyIORController.py0000644000234100017500000000363312174204313027226 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## from sardana import State from sardana.pool.controller import IORegisterController class DummyIORController(IORegisterController): """This controller offers as many IORegisters as the user wants (up to 1024).""" gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 predefined_values = "0", "Online", "1" , "Offline", "2", "Standby" def __init__(self, inst, props, *args, **kwargs): IORegisterController.__init__(self, inst, props, *args, **kwargs) self.myvalue = 1 def AddDevice(self, axis): self._log.debug('AddDevice %d' % axis) def DeleteDevice(self, axis): pass def StateOne(self, axis): return (State.On,"Device in On state") def ReadOne(self, axis): return self.myvalue def WriteOne(self, axis, value): self.myvalue = value def SendToCtrl(self,in_data): return "" sardana-1.2.0/src/sardana/pool/poolcontrollers/DummyMotorController.py0000644000234100017500000006477412174204313027712 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import time from math import pow, sqrt from sardana import State, SardanaValue from sardana.pool.controller import MotorController from sardana.pool.controller import DefaultValue, Description, FGet, FSet, Type class BaseMotion(object): def __init__(self): self.min_vel = -1 self.max_vel = -1 self.accel_time = -1 self.decel_time = -1 self.accel = -1 self.decel = -1 self.init_pos = -1 self.final_pos = -1 self.curr_pos = -1 class Motion(BaseMotion): def __init__(self): BaseMotion.__init__(self) self.dsplmnt_reach_max_vel = -1 self.dsplmnt_reach_min_vel = -1 self.dsplmnt = -1 self.curr_instant = -1 self.start_instant = -1 self.positive_dsplmnt = True self.small_motion = False # position where maximum velocity will be reached self.curr_max_vel_pos = -1 # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = -1 # necessary displacement to reach minimum velocity self.curr_dsplmnt_reach_min_vel = -1 # maximum velocity possible self.curr_max_vel = -1 # time at maximum velocity self.curr_at_max_vel_dsplmnt = -1 # time to reach maximum velocity self.curr_max_vel_time = -1 # time to reach minimum velocity self.curr_min_vel_time = -1 # time at maximum velocity self.curr_at_max_vel_time = -1 # instant when maximum velocity should be reached self.curr_max_vel_instant = -1 # instant when should start decelerating self.curr_min_vel_instant = -1 # time the motion will take self.duration = -1 # instant the motion will end self.final_instant = -1 # steps per unit self.step_per_unit = 1 self.inMotion = False self.lower_ls = float('-inf') self.upper_ls = float('+inf') self.power = True self.enabled = True self.__recalculate_acc_constants() def setMinVelocity(self,vi): """ Sets the minimum velocity in ms^-1. A.k.a. base rate""" vi = float(vi) if vi < 0: raise "Minimum velocity must be >= 0" self.min_vel = vi if self.max_vel < self.min_vel: self.max_vel = self.min_vel # force recalculation of accelerations if self.accel_time >= 0: self.setAccelerationTime(self.accel_time) if self.decel_time >= 0: self.setDecelerationTime(self.decel_time) def getMinVelocity(self): return self.min_vel def setMaxVelocity(self,vf): """ Sets the maximum velocity in ms^-1.""" vf = float(vf) if vf <= 0: raise "Maximum velocity must be > 0" self.max_vel = vf if self.min_vel > self.max_vel: self.min_vel = self.max_vel # force recalculation of accelerations if self.accel_time >= 0: self.setAccelerationTime(self.accel_time) if self.decel_time >= 0: self.setDecelerationTime(self.decel_time) def getMaxVelocity(self): return self.max_vel def setAccelerationTime(self,at): """Sets the time to go from minimum velocity to maximum velocity in seconds""" at = float(at) if at <= 0: raise "Acceleration time must be > 0" self.accel_time = at self.accel = (self.max_vel - self.min_vel) / at self.__recalculate_acc_constants() def getAccelerationTime(self): return self.accel_time def setDecelerationTime(self,dt): """Sets the time to go from maximum velocity to minimum velocity in seconds""" dt = float(dt) if dt <= 0: raise "Deceleration time must be > 0" self.decel_time = dt self.decel = (self.min_vel - self.max_vel) / dt self.__recalculate_acc_constants() def getDecelerationTime(self): return self.decel_time def setAcceleration(self,a): """Sets the acceleration in ms^-2""" a = float(a) if a < 0: raise "Acceleration must be >= 0" self.accel = float(a) if a > 0: self.accel_time = (self.max_vel - self.min_vel) / a else: self.accel_time = float('INF') self.__recalculate_acc_constants() def setDeceleration(self,d): """Sets the deceleration in ms^-2""" d = float(d) if d > 0: raise "Deceleration must be <= 0" self.decel = d if d < 0: self.decel_time = (self.min_vel - self.max_vel) / d else: self.decel_time = float('INF') self.__recalculate_acc_constants() def getStepPerUnit(self): return self.step_per_unit def setStepPerUnit(self, spu): self.step_per_unit = spu def __recalculate_acc_constants(self): """pre-computations assuming maximum speed can be reached in a motion""" self.dsplmnt_reach_max_vel = 0.5 * self.accel * pow(self.accel_time,2) self.dsplmnt_reach_max_vel += self.min_vel * self.accel_time self.dsplmnt_reach_min_vel = 0.5 * self.decel * pow(self.decel_time,2) self.dsplmnt_reach_min_vel += self.max_vel * self.decel_time def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): """starts a new motion""" if not self.power: raise Exception("Motor is powered off") initial_pos = initial_user_pos * self.step_per_unit final_pos = final_user_pos * self.step_per_unit if self.inMotion: raise Exception("Already in motion") if initial_pos == final_pos: return self.init_pos = initial_pos self.final_pos = final_pos self.curr_pos = initial_pos self.dsplmnt = abs(final_pos - initial_pos) start_instant = start_instant or time.time() self.curr_instant = start_instant self.start_instant = start_instant self.positive_dsplmnt = final_pos >= initial_pos displmnt_not_cnst = self.dsplmnt_reach_max_vel + self.dsplmnt_reach_min_vel self.small_motion = self.dsplmnt < displmnt_not_cnst if self.positive_dsplmnt: self.curr_accel = self.accel self.curr_decel = self.decel else: self.curr_accel = -self.accel self.curr_decel = -self.decel if not self.small_motion: # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = self.dsplmnt_reach_max_vel # necessary diplacement to reach minimum velocity self.curr_dsplmnt_reach_min_vel = self.dsplmnt_reach_min_vel if self.positive_dsplmnt: self.curr_max_vel = self.max_vel self.curr_min_vel = self.min_vel # position where maximum velocity will be reached self.curr_max_vel_pos = self.init_pos + self.curr_dsplmnt_reach_max_vel else: self.curr_max_vel = -self.max_vel self.curr_min_vel = -self.min_vel # position where maximum velocity will be reached self.curr_max_vel_pos = self.init_pos - self.curr_dsplmnt_reach_max_vel # displacement at maximum velocity self.curr_at_max_vel_dsplmnt = self.dsplmnt - (self.curr_dsplmnt_reach_max_vel + self.curr_dsplmnt_reach_min_vel) else: # Small movement # position where maximum velocity will be reached self.curr_max_vel_pos = self.init_pos * self.curr_accel - self.final_pos * self.curr_decel self.curr_max_vel_pos /= self.curr_accel - self.curr_decel # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = abs(self.curr_max_vel_pos - self.init_pos) # necessary diplacement to reach minimum velocity self.curr_dsplmnt_reach_min_vel = abs(self.final_pos - self.curr_max_vel_pos) # maximum velocity possible cnst = 2 * self.curr_accel * self.curr_decel * self.dsplmnt / (self.curr_decel - self.curr_accel) max_vel_2 = pow(self.min_vel, 2) + cnst self.curr_max_vel = sqrt(abs(max_vel_2)) if self.positive_dsplmnt: self.curr_min_vel = self.min_vel else: self.curr_max_vel = -self.curr_max_vel self.curr_min_vel = -self.min_vel # displacement at maximum velocity self.curr_at_max_vel_dsplmnt = 0.0 # time to reach maximum velocity self.curr_max_vel_time = abs((self.curr_max_vel - self.curr_min_vel) / self.curr_accel) # time to reach minimum velocity self.curr_min_vel_time = abs((self.curr_min_vel - self.curr_max_vel) / self.curr_decel) # time at maximum velocity self.curr_at_max_vel_time = abs(self.curr_at_max_vel_dsplmnt / self.curr_max_vel) # instant when maximum velocity should be reached self.curr_max_vel_instant = self.start_instant + self.curr_max_vel_time # instant when should start decelerating self.curr_min_vel_instant = self.curr_max_vel_instant + self.curr_at_max_vel_time # time the motion will take self.duration = self.curr_max_vel_time + self.curr_at_max_vel_time + self.curr_min_vel_time # instant the motion will end self.final_instant = self.start_instant + self.duration # uncomment following line if need output concerning the movement that # has just started # self.info() # ASSERTIONS if self.positive_dsplmnt: assert(self.curr_max_vel_pos >= self.init_pos) assert(self.curr_max_vel_pos <= self.final_pos) else: assert(self.curr_max_vel_pos <= self.init_pos) assert(self.curr_max_vel_pos >= self.final_pos) assert(self.curr_dsplmnt_reach_max_vel >= 0.0) assert(self.curr_dsplmnt_reach_min_vel >= 0.0) assert(self.final_instant >= self.start_instant) assert(self.curr_max_vel <= self.max_vel) assert(self.start_instant <= self.curr_max_vel_instant) assert(self.final_instant >= self.curr_min_vel_instant) assert(self.curr_max_vel_time > 0.0) assert(self.curr_min_vel_time > 0.0) assert(self.duration > 0.0) if self.small_motion: assert(self.curr_max_vel_instant == self.curr_min_vel_instant) assert(self.curr_at_max_vel_time == 0.0) else: assert(self.curr_max_vel_instant <= self.curr_min_vel_instant) assert(self.curr_at_max_vel_time >= 0.0) self.inMotion = True def abortMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() if not self.inMotion: return self.curr_pos self.curr_pos = self.getCurrentPosition(curr_instant) self.inMotion = False return self.curr_pos def isInMotion(self,curr_instant=None): curr_instant = curr_instant or time.time() #we call getCurrentPosition because inside it updates the inMotion flag self.getCurrentPosition(curr_instant) return self.inMotion def setCurrentPosition(self, curr_pos): self.curr_pos = curr_pos self.init_pos = curr_pos def getCurrentPosition(self, curr_instant=None): curr_instant = curr_instant or time.time() self.curr_instant = curr_instant pos = None if self.inMotion: # if motion should be ended... if self.curr_instant >= self.final_instant: self.inMotion = False pos = self.final_pos else: pos = self.init_pos if curr_instant > self.curr_min_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel pos += self.curr_at_max_vel_dsplmnt else: pos -= self.curr_dsplmnt_reach_max_vel pos -= self.curr_at_max_vel_dsplmnt dt = curr_instant - self.curr_min_vel_instant pos += self.curr_max_vel * dt + 0.5 * self.curr_decel * pow(dt,2) elif curr_instant > self.curr_max_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel else: pos -= self.curr_dsplmnt_reach_max_vel dt = curr_instant - self.curr_max_vel_instant pos += self.curr_max_vel * dt else: dt = curr_instant - self.start_instant pos += self.curr_min_vel * dt + 0.5 * self.curr_accel * pow(dt,2) else: pos = self.curr_pos if pos <= self.lower_ls: pos = self.lower_ls self.inMotion = False elif pos >= self.upper_ls: pos = self.upper_ls self.inMotion = False self.curr_pos = pos return pos def setCurrentUserPosition(self, user_pos): self.setCurrentPosition(user_pos*self.step_per_unit) def getCurrentUserPosition(self, curr_instant=None): return self.getCurrentPosition(curr_instant=curr_instant) / self.step_per_unit def hitLowerLimit(self): user_pos = self.curr_pos / self.step_per_unit return user_pos <= self.lower_ls def hitUpperLimit(self): user_pos = self.curr_pos / self.step_per_unit return user_pos >= self.upper_ls def getLowerLimitSwitch(self): return self.lower_ls def setLowerLimitSwitch(self, user_lower_ls): self.lower_ls = user_lower_ls def getUpperLimitSwitch(self): return self.upper_ls def setUpperLimitSwitch(self, user_upper_ls): self.upper_ls = user_upper_ls def turnOn(self): self.power = True def turnOff(self): self.power = False def isTurnedOn(self): return self.power def hasPower(self): return self.power def setPower(self, power): self.power = power def info(self): print "Small movement =",self.small_motion print "length =",self.dsplmnt print "position where maximum velocity will be reached =",self.curr_max_vel_pos print "necessary displacement to reach maximum velocity =",self.curr_dsplmnt_reach_max_vel print "necessary displacement to stop from maximum velocity =",self.curr_dsplmnt_reach_min_vel print "maximum velocity possible =",self.curr_max_vel print "time at top velocity =",self.curr_at_max_vel_time print "displacement at top velocity =",self.curr_at_max_vel_dsplmnt print "time to reach maximum velocity =",self.curr_max_vel_time print "time to reach minimum velocity =",self.curr_min_vel_time print "time the motion will take =",self.duration print "instant when maximum velocity should be reached =",self.curr_max_vel_instant print "instant when should start decelerating =",self.curr_min_vel_instant print "instant the motion will end",self.final_instant print "" print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =",self.dsplmnt_reach_max_vel print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =",self.dsplmnt_reach_min_vel class BasicDummyMotorController(MotorController): """This class represents a basic, dummy Sardana motor controller.""" gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) self.m = self.MaxDevice*[None,] def GetAxisAttributes(self, axis): axis_attrs = MotorController.GetAxisAttributes(self, axis) new_axis_attrs = {} for attr in ('Position', 'Limit_switches'): new_axis_attrs[attr] = axis_attrs[attr] return new_axis_attrs def AddDevice(self,axis): MotorController.AddDevice(self, axis) idx = axis - 1 if len(self.m) < axis: raise Exception("Invalid axis %d" % axis) if self.m[idx] is None: m = Motion() m.setMinVelocity(2) m.setMaxVelocity(100) m.setAccelerationTime(2) m.setDecelerationTime(2) m.setCurrentPosition(0) self.m[idx] = m def DeleteDevice(self, axis): MotorController.DeleteDevice(self, axis) idx = axis - 1 if len(self.m) < axis or not self.m[idx]: self._log.error("Invalid axis %d" % axis) #self.m[idx] = None def StateOne(self, axis): #self._log.debug("StateOne(%d)", axis) #raise Exception("Cannot StateOne %d" % axis) idx = axis - 1 m = self.m[idx] state = State.On status = "Motor HW is ON" if m.isInMotion(): state = State.Moving status = "Motor HW is MOVING" m.getCurrentUserPosition() switchstate = 0 if m.hitLowerLimit(): switchstate |= MotorController.LowerLimitSwitch state = State.Alarm status = "Motor HW is in ALARM. Hit hardware lower limit switch" if m.hitUpperLimit(): switchstate |= MotorController.UpperLimitSwitch state = State.Alarm status = "Motor HW is in ALARM. Hit hardware upper limit switch" if state != State.Alarm and not m.hasPower(): state = State.Off status = "Motor is powered off" #self._log.info("StateOne(%s) = %s", axis, (state, status, switchstate)) return state, status, switchstate def ReadOne(self, axis): #self._log.debug("ReadOne(%d)", axis) #raise Exception("Cannot ReadOne") idx = axis - 1 m = self.m[idx] ts = time.time() #simulate as if we got it from hardware return SardanaValue(m.getCurrentUserPosition(), timestamp=ts) #return m.getCurrentUserPosition() def PreStartAll(self): #raise Exception("Cannot move on PreStartAll") self.motions = {} def PreStartOne(self, axis, pos): #raise Exception("Cannot move on PreStartOne") idx = axis - 1 m = self.m[idx] return m.hasPower() def StartOne(self, axis, pos): #raise Exception("Cannot move on StartOne") idx = axis - 1 self.motions[self.m[idx]] = pos def StartAll(self): #raise Exception("Cannot move on StartAll") t = time.time() for motion, pos in self.motions.items(): motion.startMotion(motion.getCurrentUserPosition(t), pos, t) def AbortOne(self, axis): self._log.info("AbortOne(%d)", axis) idx = axis - 1 self.m[idx].abortMotion() def SendToCtrl(self, stream): return stream class FastDummyMotorController(MotorController): gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) self.m = self.MaxDevice*[None,] def GetAxisAttributes(self, axis): axis_attrs = MotorController.GetAxisAttributes(self, axis) new_axis_attrs = {} for attr in ('Position', 'Limit_switches'): new_axis_attrs[attr] = axis_attrs[attr] return new_axis_attrs def AddDevice(self,axis): MotorController.AddDevice(self, axis) idx = axis - 1 if len(self.m) < axis: raise Exception("Invalid axis %d" % axis) if self.m[idx] is None: self.m[idx] = BaseMotion() def DeleteDevice(self, axis): MotorController.DeleteDevice(self, axis) idx = axis - 1 if len(self.m) < axis or not self.m[idx]: self._log.error("Invalid axis %d" % axis) #self.m[idx] = None def StateOne(self, axis): #self._log.debug("StateOne(%d)", axis) state = State.On status = "Motor HW is ON" switchstate = 0 return state, status, switchstate def ReadOne(self, axis): self._log.debug("ReadOne(%d)", axis) idx = axis - 1 m = self.m[idx] return m.curr_pos def PreStartAll(self): self.motions = {} def PreStartOne(self, axis, pos): return True def StartOne(self, axis, pos): idx = axis - 1 self.motions[self.m[idx]] = pos def StartAll(self): for motion, pos in self.motions.items(): motion.curr_pos = pos def AbortOne(self, axis): pass class DiscreteDummyMotorController(BasicDummyMotorController): """This class represents a discrete, dummy Sardana motor controller.""" def __init__(self, inst, props, *args, **kwargs): BasicDummyMotorController.__init__(self, inst, props, *args, **kwargs) def GetAxisAttributes(self, axis): axis_attrs = MotorController.GetAxisAttributes(self, axis) new_axis_attrs = dict(Position=axis_attrs['Position']) new_axis_attrs['Position'][Type] = int return new_axis_attrs def AddDevice(self, axis): BasicDummyMotorController.AddDevice(self, axis) idx = axis - 1 m = self.m[idx] m.setMinVelocity(0) m.setMaxVelocity(1) m.setAccelerationTime(0.01) m.setDecelerationTime(0.01) m.setCurrentPosition(0) def ReadOne(self, axis): pos = BasicDummyMotorController.ReadOne(self, axis) return int(pos) class DummyMotorController(BasicDummyMotorController): """This class represents a dummy Sardana motor controller.""" ctrl_features = [] model = "Best" ctrl_attributes = { 'LowerLimitSwitch' : { Type : float, Description : 'lower limit switch position', FGet : 'getLowerLimitSwitch', FSet : 'setLowerLimitSwitch', DefaultValue: -9999.9999, }, 'UpperLimitSwitch' : { Type : float, Description : 'upper limit switch position', DefaultValue: 8888.8888 } } axis_attributes = { 'LowerLimitSwitch' : { Type : float, Description : 'lower limit switch position', FGet : 'getLLS', FSet : 'setLLS', DefaultValue: -9999.9999 }, 'UpperLimitSwitch' : { Type : float, Description : 'upper limit switch position', FGet : 'getULS', FSet : 'setULS', DefaultValue: 8888.8888 }, 'Power' : { Type : bool, Description : 'motor power', FGet : 'getPower', FSet : 'setPower', DefaultValue: True }, } ctrl_properties = { 'Prop1' : { Type : str, Description : 'demo property 1', DefaultValue : 'test property 1'}, 'Prop2' : { Type : int, Description : 'demo property 1', DefaultValue : 531}, } def __init__(self, inst, props, *args, **kwargs): BasicDummyMotorController.__init__(self, inst, props, *args, **kwargs) self._lowerLS = float("-inf") self._upperLS = float("+inf") def GetAxisAttributes(self, axis): return MotorController.GetAxisAttributes(self, axis) def SetAxisPar(self, axis, name, value): idx = axis - 1 m = self.m[idx] name = name.lower() if name == "acceleration": m.setAccelerationTime(value) elif name == "deceleration": m.setDecelerationTime(value) elif name == "base_rate": m.setMinVelocity(value) elif name == "velocity": m.setMaxVelocity(value) elif name == "step_per_unit": m.setStepPerUnit(value) def GetAxisPar(self, axis, name): idx = axis - 1 m = self.m[idx] name = name.lower() if name == "acceleration": v = m.getAccelerationTime() elif name == "deceleration": v = m.getDecelerationTime() elif name == "base_rate": v = m.getMinVelocity() elif name == "velocity": v = m.getMaxVelocity() elif name == "step_per_unit": v = m.getStepPerUnit() return v def DefinePosition(self, axis, position): idx = axis - 1 m = self.m[idx] m.offset = position - m.getCurrentUserPosition() m.setCurrentUserPosition(position) def getLowerLimitSwitch(self): return self._lowerLS def setLowerLimitSwitch(self, value): self._lowerLS = value def getUpperLimitSwitch(self): return self._upperLS def setUpperLimitSwitch(self, value): self._upperLS = value def getLLS(self, axis): return self.m[axis - 1].getLowerLimitSwitch() def setLLS(self, axis, ls): self.m[axis - 1].setLowerLimitSwitch(ls) def getULS(self, axis): return self.m[axis - 1].getUpperLimitSwitch() def setULS(self, axis, ls): self.m[axis - 1].setUpperLimitSwitch(ls) def getPower(self, axis): return self.m[axis - 1].hasPower() def setPower(self, axis, power): self.m[axis - 1].setPower(power) sardana-1.2.0/src/sardana/pool/poolcontrollers/DummyOneDController.py0000644000234100017500000001700212174204313027415 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/axisex.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import time import numpy from sardana import State from sardana.pool.controller import OneDController, MaxDimSize from sardana.pool.controller import DefaultValue, Description, FGet, FSet, Type def gauss(x, mean, ymax, fwhm, yoffset=0): return yoffset + ymax*numpy.power(2,-4*((x-mean)/fwhm)**2) class Channel: def __init__(self,idx): self.idx = idx # 1 based axisex self.value = [] self.is_counting = False self.active = True self.amplitude = BaseValue('1.0') class BaseValue(object): def __init__(self, value): self.raw_value = value self.init() def init(self): self.value = float(self.raw_value) def get(self): return self.value def get_value_name(self): return self.raw_value class TangoValue(BaseValue): def init(self): import PyTango self.attr_proxy = PyTango.AttributeProxy(self.raw_value) def get(self): return self.attr_proxy.read().value class DummyOneDController(OneDController): "This class is the Tango Sardana OneDController controller for tests" gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 BufferSize = 1024, axis_attributes = { 'Amplitude' : { Type : str, FGet : 'getAmplitude', FSet : 'setAmplitude', Description : 'Amplitude. Maybe a number or a tango attribute(must start with tango://)', DefaultValue : '1.0' }, } def __init__(self, inst, props, *args, **kwargs): OneDController.__init__(self, inst, props, *args, **kwargs) self.channels = self.MaxDevice*[None,] self.reset() def GetAxisAttributes(self, axis): # the default max shape for 'value' is (16*1024,). We don't need so much # so we set it to BufferSize attrs = super(DummyOneDController, self).GetAxisAttributes(axis) attrs['Value'][MaxDimSize] = self.BufferSize return attrs def reset(self): self.start_time = None self.integ_time = None self.monitor_count = None self.read_channels = {} self.counting_channels = {} def AddDevice(self,axis): idx = axis - 1 self.channels[idx] = channel = Channel(axis) channel.value = numpy.zeros(self.BufferSize, dtype=numpy.float64) def DeleteDevice(self,axis): idx = axis - 1 self.channels[idx] = None def PreStateAll(self): pass def PreStateOne(self, axis): pass def StateAll(self): pass def StateOne(self, axis): idx = axis - 1 sta = State.On status = "Stopped" if axis in self.counting_channels: channel = self.channels[idx] now = time.time() elapsed_time = now - self.start_time self._updateChannelState(axis, elapsed_time) if channel.is_counting: sta = State.Moving status = "Acquiring" return sta, status def _updateChannelState(self, axis, elapsed_time): channel = self.channels[axis-1] if self.integ_time is not None: # counting in time if elapsed_time >= self.integ_time: self._finish(elapsed_time) elif self.monitor_count is not None: # monitor counts v = int(elapsed_time*100*axis) if v >= self.monitor_count: self._finish(elapsed_time) def _updateChannelValue(self, axis, elapsed_time): channel = self.channels[axis-1] t = elapsed_time if self.integ_time is not None and not channel.is_counting: t = self.integ_time x = numpy.linspace(-10, 10, self.BufferSize[0]) amplitude = axis * t * channel.amplitude.get() channel.value = gauss(x, 0, amplitude, 4) def _finish(self, elapsed_time, axis=None): if axis is None: for axis, channel in self.counting_channels.items(): channel.is_counting = False self._updateChannelValue(axis, elapsed_time) else: if axis in self.counting_channels: channel = self.counting_channels[axis] channel.is_counting = False self._updateChannelValue(axis, elapsed_time) else: channel = self.channels[axis-1] channel.is_counting = False self.counting_channels = {} def PreReadAll(self): self.read_channels = {} def PreReadOne(self,axis): channel = self.channels[axis-1] self.read_channels[axis] = channel def ReadAll(self): # if in acquisition then calculate the values to return if self.counting_channels: now = time.time() elapsed_time = now - self.start_time for axis, channel in self.read_channels.items(): self._updateChannelState(axis, elapsed_time) if channel.is_counting: self._updateChannelValue(axis, elapsed_time) def ReadOne(self, axis): self._log.debug("ReadOne(%s)", axis) v = self.read_channels[axis].value return v def PreStartAll(self): self.counting_channels = {} def PreStartOne(self, axis, value): idx = axis - 1 channel = self.channels[idx] channel.value = 0.0 self.counting_channels[axis] = channel return True def StartOne(self, axis, value): self.counting_channels[axis].is_counting = True def StartAll(self): self.start_time = time.time() def LoadOne(self, axis, value): idx = axis - 1 if value > 0: self.integ_time = value self.monitor_count = None else: self.integ_time = None self.monitor_count = -value def AbortOne(self, axis): now = time.time() if axis in self.counting_channels: elapsed_time = now - self.start_time self._finish(elapsed_time, axis=axis) def getAmplitude(self, axis): idx = axis - 1 channel = self.channels[idx] return channel.amplitude.get_value_name() def setAmplitude(self, axis, value): idx = axis - 1 channel = self.channels[idx] klass = BaseValue if value.startswith("tango://"): klass = TangoValue channel.amplitude = klass(value) sardana-1.2.0/src/sardana/pool/poolcontrollers/DummyTwoDController.py0000644000234100017500000001705212174204313027452 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/axisex.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import time import numpy from sardana import State from sardana.pool.controller import TwoDController, MaxDimSize def gauss(x, mean, ymax, fwhm, yoffset=0): return yoffset + ymax*numpy.power(2,-4*((x-mean)/fwhm)**2) class Channel: def __init__(self,idx): self.idx = idx # 1 based axisex self.value = [] self.is_counting = False self.active = True self.amplitude = BaseValue('1.0') class BaseValue(object): def __init__(self, value): self.raw_value = value self.init() def init(self): self.value = float(self.raw_value) def get(self): return self.value def get_value_name(self): return self.raw_value class TangoValue(BaseValue): def init(self): import PyTango self.attr_proxy = PyTango.AttributeProxy(self.raw_value) def get(self): return self.attr_proxy.read().value class DummyTwoDController(TwoDController): "This class is the Tango Sardana OneDController controller for tests" gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 BufferSize = 1024, 1024 axis_attributes = { 'Amplitude' : { 'type' : str, 'fget' : 'getAmplitude', 'fset' : 'setAmplitude', 'description' : 'Amplitude. Maybe a number or a tango attribute(must start with tango://)', 'defaultvalue': '1.0' }, } def __init__(self, inst, props, *args, **kwargs): TwoDController.__init__(self, inst, props, *args, **kwargs) self.channels = self.MaxDevice*[None,] self.reset() def GetAxisAttributes(self, axis): # the default max shape for 'value' is (16*1024,). We don't need so much # so we set it to BufferSize attrs = super(DummyTwoDController, self).GetAxisAttributes(axis) attrs['Value'][MaxDimSize] = self.BufferSize return attrs def reset(self): self.start_time = None self.integ_time = None self.monitor_count = None self.read_channels = {} self.counting_channels = {} def AddDevice(self,axis): idx = axis - 1 self.channels[idx] = channel = Channel(axis) channel.value = numpy.zeros(self.BufferSize, dtype=numpy.float64) def DeleteDevice(self,axis): idx = axis - 1 self.channels[idx] = None def PreStateAll(self): pass def PreStateOne(self, axis): pass def StateAll(self): pass def StateOne(self, axis): idx = axis - 1 sta = State.On status = "Stopped" if axis in self.counting_channels: channel = self.channels[idx] now = time.time() elapsed_time = now - self.start_time self._updateChannelState(axis, elapsed_time) if channel.is_counting: sta = State.Moving status = "Acquiring" return sta, status def _updateChannelState(self, axis, elapsed_time): channel = self.channels[axis-1] if self.integ_time is not None: # counting in time if elapsed_time >= self.integ_time: self._finish(elapsed_time) elif self.monitor_count is not None: # monitor counts v = int(elapsed_time*100*axis) if v >= self.monitor_count: self._finish(elapsed_time) def _updateChannelValue(self, axis, elapsed_time): channel = self.channels[axis-1] t = elapsed_time if self.integ_time is not None and not channel.is_counting: t = self.integ_time x = numpy.linspace(-10, 10, self.BufferSize[0]) y = numpy.linspace(-10, 10, self.BufferSize[1]) x, y = numpy.meshgrid(x, y) amplitude = axis * t * channel.amplitude.get() channel.value = gauss(x, 0, amplitude, 4) * gauss(y, 0, amplitude, 4) def _finish(self, elapsed_time, axis=None): if axis is None: for axis, channel in self.counting_channels.items(): channel.is_counting = False self._updateChannelValue(axis, elapsed_time) else: if axis in self.counting_channels: channel = self.counting_channels[axis] channel.is_counting = False self._updateChannelValue(axis, elapsed_time) else: channel = self.channels[axis-1] channel.is_counting = False self.counting_channels = {} def PreReadAll(self): self.read_channels = {} def PreReadOne(self,axis): channel = self.channels[axis-1] self.read_channels[axis] = channel def ReadAll(self): # if in acquisition then calculate the values to return if self.counting_channels: now = time.time() elapsed_time = now - self.start_time for axis, channel in self.read_channels.items(): self._updateChannelState(axis, elapsed_time) if channel.is_counting: self._updateChannelValue(axis, elapsed_time) def ReadOne(self, axis): self._log.debug("ReadOne(%s)", axis) return self.read_channels[axis].value def PreStartAll(self): self.counting_channels = {} def PreStartOne(self, axis, value): idx = axis - 1 channel = self.channels[idx] channel.value = 0.0 self.counting_channels[axis] = channel return True def StartOne(self, axis, value): self.counting_channels[axis].is_counting = True def StartAll(self): self.start_time = time.time() def LoadOne(self, axis, value): idx = axis - 1 if value > 0: self.integ_time = value self.monitor_count = None else: self.integ_time = None self.monitor_count = -value def AbortOne(self, axis): now = time.time() if axis in self.counting_channels: elapsed_time = now - self.start_time self._finish(elapsed_time, axis=axis) def getAmplitude(self, axis): idx = axis - 1 channel = self.channels[idx] return channel.amplitude.get_value_name() def setAmplitude(self, axis, value): idx = axis - 1 channel = self.channels[idx] klass = BaseValue if value.startswith("tango://"): klass = TangoValue channel.amplitude = klass(value) sardana-1.2.0/src/sardana/pool/poolcontrollers/DummyZeroDController.py0000644000234100017500000000454412174204313027622 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import random from sardana import State from sardana.pool.controller import ZeroDController class Channel: def __init__(self,idx): self.idx = idx # 1 based index self.value = 0.0 self.active = False class DummyZeroDController(ZeroDController): """This class represents a dummy Sardana 0D controller.""" gender = "Simulation" model = "Basic" organization = "Sardana team" MaxDevice = 1024 def __init__(self, inst, props, *args, **kwargs): ZeroDController.__init__(self, inst, props, *args, **kwargs) self.channels = [ Channel(i+1) for i in xrange(self.MaxDevice) ] self.read_channels = {} def AddDevice(self,ind): self.channels[ind].active = True def DeleteDevice(self,ind): self.channels[ind].active = False def StateOne(self,ind): return State.On, "OK" def _setChannelValue(self, channel): channel.value = 100 * channel.idx + 10*(random.random()-0.5) def PreReadAll(self): self.read_channels = {} def PreReadOne(self,ind): channel = self.channels[ind-1] self.read_channels[ind] = channel def ReadAll(self): for channel in self.read_channels.values(): self._setChannelValue(channel) def ReadOne(self,ind): v = self.read_channels[ind].value return v sardana-1.2.0/src/sardana/pool/poolcontrollers/IoverI0.py0000644000234100017500000000322012174204313024762 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of a I/I0 pseudo counter controller for the Sardana Device Pool""" __all__ = ["IoverI0"] __docformat__ = 'restructuredtext' from sardana.pool.controller import PseudoCounterController class IoverI0(PseudoCounterController): """ A simple pseudo counter which receives two counter values (I and I0) and returns I/I0""" gender = "IoverI0" model = "Default I/I0" organization = "Sardana team" counter_roles = "I", "I0" def Calc(self, axis, counter_values): i, i0 = counter_values try: i = float(i/i0) except ZeroDivisionError: pass return i sardana-1.2.0/src/sardana/pool/poolcontrollers/Slit.py0000644000234100017500000000744312174204313024433 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of a slit pseudo motor controller for the Sardana Device Pool""" __all__ = ["Slit"] __docformat__ = 'restructuredtext' from sardana import DataAccess from sardana.pool.controller import PseudoMotorController from sardana.pool.controller import DefaultValue, Description, Access, Type class Slit(PseudoMotorController): """A Slit pseudo motor controller for handling gap and offset pseudo motors. The system uses to real motors sl2t (top slit) and sl2b (bottom slit)""" gender = "Slit" model = "Default Slit" organization = "Sardana team" pseudo_motor_roles = "Gap", "Offset" motor_roles = "sl2t", "sl2b" ctrl_properties = { 'sign' : { Type : float, Description : 'Gap = sign * calculated gap\nOffset = sign * calculated offet', DefaultValue : 1 }, } axis_attributes = { 'example' : { Type : int, Access : DataAccess.ReadWrite, Description : 'test purposes' }, } def __init__(self, inst, props, *args, **kwargs): PseudoMotorController.__init__(self, inst, props, *args, **kwargs) self._log.debug("Created SLIT %s", inst) self._example = {} def CalcPhysical(self, index, pseudo_pos, curr_physical_pos): half_gap = pseudo_pos[0]/2.0 if index == 1: ret = self.sign * (pseudo_pos[1] + half_gap) else: ret = self.sign * (half_gap - pseudo_pos[1]) self._log.debug("Slit.CalcPhysical(%d, %s) -> %f", index, pseudo_pos, ret) return ret def CalcPseudo(self, index, physical_pos, curr_pseudo_pos): gap = physical_pos[1] + physical_pos[0] if index == 1: ret = self.sign * gap else: ret = self.sign * (physical_pos[0] - gap/2.0) return ret def CalcAllPseudo(self, physical_pos, curr_pseudo_pos): """Calculates the positions of all pseudo motors that belong to the pseudo motor system from the positions of the physical motors.""" gap = physical_pos[1] + physical_pos[0] return (self.sign * gap, self.sign * (physical_pos[0] - gap/2.0)) #def CalcAllPhysical(self, pseudo_pos, curr_physical_pos): # """Calculates the positions of all motors that belong to the pseudo # motor system from the positions of the pseudo motors.""" # half_gap = pseudo_pos[0]/2.0 # return (self.sign * (pseudo_pos[1] + half_gap), # self.sign * (half_gap - pseudo_pos[1])) def SetAxisExtraPar(self, axis, parameter, value): self._example[axis] = value def GetAxisExtraPar(self, axis, parameter): return self._example.get(axis, -1) sardana-1.2.0/src/sardana/pool/poolcontrollers/TangoController.py0000644000234100017500000001533212174204313026630 0ustar cpascualcpascual00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import math import PyTango from taurus.core.util import CaselessDict from sardana import State, DataAccess from sardana.pool.controller import MotorController, CounterTimerController, \ ZeroDController, \ Type, Access, Description, DefaultValue TangoAttribute = "TangoAttribute" Formula = "Formula" class ReadTangoAttributes(object): """ Generic class that has as many devices as the user wants. Each device has a tango attribute and a formula and the 'hardware' tango calls are optimized in the sense that only one call per tango device is issued. """ axis_attributes = { TangoAttribute : { Type : str, Access : DataAccess.ReadWrite, Description : 'Attribute to read (e.g. a/b/c/attr)' }, Formula : { Type : str, Access : DataAccess.ReadWrite, DefaultValue : "VALUE", Description : 'The Formula to get the desired value.\n' 'e.g. "math.sqrt(VALUE)"' }, } def __init__(self): #: dict self._pending = {} #: dict>> self._devices = CaselessDict() #: dict, str, DeviceProxy>> self._axis_tango_attributes = {} #: dict> self._axis_formulas = {} def add_device(self, axis): self._pending[axis] = "No tango attribute associated to this device yet" self._axis_formulas[axis] = self.axis_attribute[Formula][DefaultValue] def delete_device(self, axis): if axis in self._pending: del self._pending[axis] else: del self._axis_tango_attributes[axis] del self._axis_formulas[axis] def state_one(self, axis): pending_info = self._pending.get(axis) if pending_info is not None: return State.Fault, pending_info return State.On, 'Always ON, just reading tango attribute' def pre_read_all(self): self._devices_read = {} def pre_read_one(self, axis): attr_name, dev = self._axis_tango_attributes[axis][1:] dev_attrs = self._devices_read.get(dev) if dev_attrs is None: self._ self._devices_read[dev] = dev_attrs = [] dev_attrs.append(attr_name) def read_all(self): pass def read_one(self, axis): pass def get_extra_attribute_par(self, axis, name): if name == TangoAttribute: return self._axis_tango_attributes[axis][0] elif name == Formula: return self._axis_formulas[axis] def set_extra_attribute_par(self, axis, name, value): if name == TangoAttribute: value = value.lower() self._axis_tango_attributes[axis] = data = value, None, None try: dev_name, attr_name = value.rsplit("/",1) data[1] = attr_name except: self._pending[axis] = "invalid device name " + value raise Exception(self._pending[axis]) dev_info = self._devices.get(dev_name) if dev_info is None: try: proxy = PyTango.DeviceProxy(dev_name) except PyTango.DevFailed, df: if len(df): self._pending[axis] = df[0].reason + ": " + df[0].desc else: self._pending[axis] = "Unknwon PyTango Error: " + str(df) raise self._devices[dev_name] = dev_info = proxy, [] data[2] = dev_info[0] dev_info[1].append(attr_name) elif name == Formula: self._axis_formulas[axis] = value class TangoCounterTimerController(ReadTangoAttributes, CounterTimerController): """This controller offers as many channels as the user wants. Each channel has two _MUST_HAVE_ extra attributes: +) TangoAttribute - Tango attribute to retrieve the value of the counter +) Formula - Formula to evaluate using 'VALUE' as the tango attribute value As examples you could have: ch1.TangoExtraAttribute = 'my/tango/device/attribute1' ch1.Formula = '-1 * VALUE' ch2.TangoExtraAttribute = 'my/tango/device/attribute2' ch2.Formula = 'math.sqrt(VALUE)' ch3.TangoExtraAttribute = 'my_other/tango/device/attribute1' ch3.Formula = 'math.cos(VALUE)' """ gender = "" model = "" organization = "Sardana team" MaxDevice = 1024 def __init__(self, inst, props, *args, **kwargs): ReadTangoAttributes.__init__(self) CounterTimerController.__init__(self, inst, props, *args, **kwargs) def AddDevice(self, axis): self.add_device(axis) def DeleteDevice(self, axis): self.delete_device(axis) def StateOne(self, axis): return self.state_one(axis) def PreReadAll(self): self.pre_read_all() def PreReadOne(self, axis): self.pre_read_one(axis) def ReadAll(self): self.read_all() def ReadOne(self, axis): return self.read_one(axis) def GetExtraAttributePar(self, axis, name): return self.get_extra_attribute_par(axis, name) def SetExtraAttributePar(self,axis, name, value): self.set_extra_attribute_par(axis, name, value) def SendToCtrl(self,in_data): return "" def AbortOne(self, axis): pass def PreStartAllCT(self): pass def StartOneCT(self, axis): pass def StartAllCT(self): pass def LoadOne(self, axis, value): pass sardana-1.2.0/src/sardana/pool/poolcontrollers/__init__.py0000644000234100017500000000200412174204313025243 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """sardana-1.2.0/src/sardana/pool/__init__.py0000644000234100017500000000235612174204313022015 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the main device pool module""" __all__ = ["ControllerAPI", "AcqTriggerType", "AcqMode", "PoolUtil"] __docformat__ = 'restructuredtext' from .pooldefs import ControllerAPI, AcqTriggerType, AcqMode from .poolutil import PoolUtil sardana-1.2.0/src/sardana/pool/controller.py0000644000234100017500000015131212174204314022437 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition of the Controller base classes""" __all__ = ["DataAccess", "SardanaValue", "Type", "Access", "Description", "DefaultValue", "FGet", "FSet", "Memorized", "MemorizedNoInit", "NotMemorized", "MaxDimSize", "Controller", "Readable", "Startable", "Stopable", "Loadable", "MotorController", "CounterTimerController", "ZeroDController", "OneDController", "TwoDController", "PseudoMotorController", "IORegisterController"] __docformat__ = 'restructuredtext' import copy import taurus from taurus.core.util import Logger from sardana import DataAccess from sardana.sardanavalue import SardanaValue from .pooldefs import ControllerAPI, AcqTriggerType, AcqMode #: Constant data type (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) Type = 'type' #: Constant data access (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) Access = 'r/w type' #: Constant description (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) Description = 'description' #: Constant default value (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) DefaultValue = 'defaultvalue' #: Constant for getter function (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) FGet = "fget" #: Constant for setter function (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) FSet = "fset" #: Constant memorize (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) #: Possible values for this key are :obj:`Memorized`, :obj:`MemorizedNoInit` #: and :obj:`NotMemorized` Memorize = "memorized" #: Constant memorized (to be used as a *value* in the :obj:`Memorize` field #: definition in :attr:`~Controller.axis_attributes` or #: :attr:`~Controller.ctrl_attributes`) Memorized = "true" #: Constant memorize but not write at initialization (to be used as a *value* #: in the :obj:`Memorize` field definition in #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) MemorizedNoInit = "true_without_hard_applied" #: Constant not memorize (to be used as a *value* #: in the :obj:`Memorize` field definition in #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) NotMemorized = "false" #: Constant MaxDimSize (to be used as a *key* in the definition of #: :attr:`~Controller.axis_attributes` or :attr:`~Controller.ctrl_attributes`) MaxDimSize = "maxdimsize" class Controller(object): """Base controller class. Do **NOT** inherit from this class directly :param str inst: controller instance name :param dict props: a dictionary containning pairs of property name, property value :arg args: :keyword kwargs:""" #: .. deprecated:: 1.0 #: use :attr:`~Controller.ctrl_properties` instead class_prop = {} #: A sequence of :obj:`str` representing the controller features ctrl_features = [] #: .. deprecated:: 1.0 #: use :attr:`~Controller.axis_attributes` instead ctrl_extra_attributes = {} #: A :class:`dict` containing controller properties where: #: #: - key : (:obj:`str`) controller property name #: - value : :class:`dict` with with three :obj:`str` keys ("type", #: "description" and "defaultvalue" case insensitive): #: #: - for :obj:`Type`, value is one of the values described in #: :ref:`sardana-controller-data-type` #: #: - for :obj:`Description`, value is a :obj:`str` description of the #: property. #: if is not given it defaults to empty string. #: #: - for :obj:`DefaultValue`, value is a python object or None if no #: default value exists for the property. #: #: Example:: #: #: from sardana.pool.controller import MotorController, \ #: Type, Description, DefaultValue #: #: class MyCtrl(MotorController): #: #: ctrl_properties = \ #: { #: 'host' : { Type : str, #: Description : "host name" }, #: 'port' : { Type : int, #: Description : "port number", #: DefaultValue: 5000 } #: } #: ctrl_properties = {} #: A :class:`dict` containning controller extra attributes where: #: #: - key : (:obj:`str`) controller attribute name #: - value : :class:`dict` with :obj:`str` possible keys: "type", #: "r/w type", "description", "fget", "fset" and "maxdimsize" #: (case insensitive): #: #: - for :obj:`Type`, value is one of the values described in #: :ref:`sardana-controller-data-type` #: #: - for :obj:`Access`, value is one of #: :obj:`~sardana.sardanadefs.DataAccess` ("read" or "read_write" #: (case insensitive) strings are also accepted) [default: ReadWrite] #: #: - for :obj:`Description`, value is a :obj:`str` description of the #: attribute [default: "" (empty string)] #: #: - for :obj:`FGet`, value is a :obj:`str` with the method name for #: the attribute getter [default: "get"] #: #: - for :obj:`FSet`, value is a :obj:`str` with the method name for #: the attribute setter. [default, if :obj:`Access` = "read_write": #: "set"] #: #: - for :obj:`DefaultValue`, value is a python object or None if no #: default value exists for the attribute. If given, the attribute is #: set when the controller is first created. #: #: - for :obj:`Memorize`, value is a :obj:`str` with possible values: #: :obj:`Memorized`, :obj:`MemorizedNoInit` and #: :obj:`NotMemorized` [default: :obj:`Memorized`] #: #: .. versionadded:: 1.1 #: #: - for :obj:`MaxDimSize`, value is a :obj:`tuple` with possible values: #: - for scalar **must** be an empty tuple ( () or [] ) #: [default: ()] #: - for 1D arrays a sequence with one value (example: (1024,)) #: [default: (2048,)] #: - for 1D arrays a sequence with two values (example: (1024, 1024)) #: [default: (2048, 2048)] #: #: .. versionadded:: 1.1 #: #: .. versionadded:: 1.0 #: #: Example:: #: #: from sardana.pool.controller import PseudoMotorController, \ #: Type, Description, DefaultValue, DataAccess #: #: class HKLCtrl(PseudoMotorController): #: #: ctrl_attributes = \ #: { #: 'ReflectionMatrix' : { Type : ( (float,), ), #: Description : "The reflection matrix", #: Access : DataAccess.ReadOnly, #: FGet : 'getReflectionMatrix', }, #: } #: #: def getReflectionMatrix(self): #: return ( (1.0, 0.0), (0.0, 1.0) ) ctrl_attributes = {} #: A :class:`dict` containning controller extra attributes for each axis #: where: #: #: - key : (:obj:`str`) axis attribute name #: - value : :class:`dict` with three :obj:`str` keys #: ("type", "r/w type", "description" case insensitive): #: #: - for :obj:`Type`, value is one of the values described in #: :ref:`sardana-controller-data-type` #: #: - for :obj:`Access`, value is one of #: :obj:`~sardana.sardanadefs.DataAccess` ("read" or "read_write" #: (case insensitive) strings are also accepted) #: #: - for :obj:`Description`, value is a :obj:`str` description of the #: attribute #: #: - for :obj:`DefaultValue`, value is a python object or None if no #: default value exists for the attribute. If given, the attribute is #: set when the axis is first created. #: #: - for :obj:`Memorize`, value is a :obj:`str` with possible values: #: :obj:`Memorized`, :obj:`MemorizedNoInit` and #: :obj:`NotMemorized` [default: :obj:`Memorized`] #: #: .. versionadded:: 1.1 #: #: - for :obj:`MaxDimSize`, value is a :obj:`tuple` with possible values: #: - for scalar **must** be an empty tuple ( () or [] ) #: [default: ()] #: - for 1D arrays a sequence with one value (example: (1024,)) #: [default: (2048,)] #: - for 1D arrays a sequence with two values (example: (1024, 1024)) #: [default: (2048, 2048)] #: #: .. versionadded:: 1.1 #: #: .. versionadded:: 1.0 #: #: Example:: #: #: from sardana.pool.controller import MotorController, \ #: Type, Description, DefaultValue, DataAccess #: #: class MyMCtrl(MotorController): #: #: axis_attributes = \ #: { #: 'EncoderSource' : { Type : str, #: Description : 'motor encoder source', }, #: } #: #: def getAxisPar(self, axis, name): #: name = name.lower() #: if name == 'encodersource': #: return self._encodersource[axis] #: #: def setAxisPar(self, axis, name, value): #: name = name.lower() #: if name == 'encodersource': #: self._encodersource[axis] = value axis_attributes = {} #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = {} #: A :obj:`str` representing the controller gender gender = None #: A :obj:`str` representing the controller model name model = 'Generic' #: A :obj:`str` representing the controller organization organization = 'Sardana team' #: A :obj:`str` containning the path to the image file image = None #: A :obj:`str` containning the path to the image logo file logo = None def __init__(self, inst, props, *args, **kwargs): self._inst_name = inst self._log = Logger("Controller.%s" % inst) self._log.log_obj.setLevel(taurus.getLogLevel()) self._args = args self._kwargs = kwargs self._api_version = self._findAPIVersion() for prop_name, prop_value in props.items(): setattr(self, prop_name, prop_value) def _findAPIVersion(self): """*Internal*. By default return the Pool Controller API version of the pool where the controller is running""" return ControllerAPI def _getPoolController(self): """*Internal*.""" if hasattr(self, '_kwargs'): kw = self._kwargs if kw is not None: ctrl_wr = kw.get('pool_controller') if ctrl_wr is not None: return ctrl_wr() def AddDevice(self, axis): """**Controller API**. Override if necessary. Default implementation does nothing. :param int axis: axis number""" pass def DeleteDevice(self, axis): """**Controller API**. Override if necessary. Default implementation does nothing. :param int axis: axis number""" pass @property def inst_name(self): """**Controller API**. The controller instance name. .. deprecated:: 1.0 use :meth:`~Controller.GetName` instead""" return self._inst_name def GetName(self): """**Controller API**. The controller instance name. :return: the controller instance name :rtype: str .. versionadded:: 1.0""" return self._inst_name def GetAxisName(self, axis): """**Controller API**. The axis name. :return: the axis name :rtype: str .. versionadded:: 1.0""" ctrl = self._getPoolController() if ctrl is not None: return ctrl.get_element(axis=axis).name return str(axis) def PreStateAll(self): """**Controller API**. Override if necessary. Called to prepare a read of the state of all axis. Default implementation does nothing.""" pass def PreStateOne(self, axis): """**Controller API**. Override if necessary. Called to prepare a read of the state of a single axis. Default implementation does nothing. :param int axis: axis number""" pass def StateAll(self): """**Controller API**. Override if necessary. Called to read the state of all selected axis. Default implementation does nothing.""" pass def StateOne(self, axis): """**Controller API**. Override is MANDATORY. Called to read the state of one axis. Default implementation raises :exc:`NotImplementedError`.""" raise NotImplementedError("StateOne must be defined in the controller") #def SetCtrlPar(self, unit, parameter, value): def SetCtrlPar(self, parameter, value): """**Controller API**. Override if necessary. Called to set a parameter with a value. Default implementation sets this object member named '_'+parameter with the given value. .. versionadded:: 1.0""" setattr(self, '_' + parameter, value) #def GetCtrlPar(self, unit, parameter): def GetCtrlPar(self, parameter): """**Controller API**. Override if necessary. Called to set a parameter with a value. Default implementation returns the value contained in this object's member named '_'+parameter. .. versionadded:: 1.0""" return getattr(self, '_' + parameter) #def SetAxisPar(self, unit, axis, parameter, value): def SetAxisPar(self, axis, parameter, value): """**Controller API**. Override is MANDATORY. Called to set a parameter with a value on the given axis. Default implementation calls deprecated :meth:`~Controller.SetPar` which, by default, raises :exc:`NotImplementedError`. .. versionadded:: 1.0""" return self.SetPar(axis, parameter, value) #def GetAxisPar(self, unit, axis, parameter): def GetAxisPar(self, axis, parameter): """**Controller API**. Override is MANDATORY. Called to get a parameter value on the given axis. Default implementation calls deprecated :meth:`~Controller.GetPar` which, by default, raises :exc:`NotImplementedError`. .. versionadded:: 1.0""" return self.GetPar(axis, parameter) def SetAxisExtraPar(self, axis, parameter, value): """**Controller API**. Override if necessary. Called to set a parameter with a value on the given axis. Default implementation calls deprecated :meth:`~Controller.SetExtraAttributePar` which, by default, raises :exc:`NotImplementedError`. .. versionadded:: 1.0""" return self.SetExtraAttributePar(axis, parameter, value) def GetAxisExtraPar(self, axis, parameter): """**Controller API**. Override if necessary. Called to get a parameter value on the given axis. Default implementation calls deprecated :meth:`~Controller.GetExtraAttributePar` which, by default, raises :exc:`NotImplementedError`. .. versionadded:: 1.0""" return self.GetExtraAttributePar(axis, parameter) def SetPar(self, axis, parameter, value): """**Controller API**. Called to set a parameter with a value on the given axis. Default implementation raises :exc:`NotImplementedError`. .. deprecated:: 1.0 use :meth:`~Controller.SetAxisPar` instead""" raise NotImplementedError("SetAxisPar must be defined in the " "controller") def GetPar(self, axis, parameter): """**Controller API**. Called to get a parameter value on the given axis. Default implementation raises :exc:`NotImplementedError`. .. deprecated:: 1.0 use :meth:`~Controller.GetAxisPar` instead""" raise NotImplementedError("GetAxisPar must be defined in the " "controller") def SetExtraAttributePar(self, axis, parameter, value): """**Controller API**. Called to set a parameter with a value on the given axis. Default implementation raises :exc:`NotImplementedError`. .. deprecated:: 1.0 use :meth:`~Controller.SetAxisExtraPar` instead""" raise NotImplementedError("SetAxisExtraPar must be defined in the " "controller") def GetExtraAttributePar(self, axis, parameter): """**Controller API**. Called to get a parameter value on the given axis. Default implementation raises :exc:`NotImplementedError`. .. deprecated:: 1.0 use :meth:`~Controller.GetAxisExtraPar` instead""" raise NotImplementedError("GetAxisExtraPar must be defined in the " "controller") def GetAxisAttributes(self, axis): """**Controller API**. Override if necessary. Returns a dictionary of all attributes per axis. Default implementation returns a new :class:`dict` with the standard attributes plus the :attr:`~Controller.axis_attributes` :param int axis: axis number :return: a dict containing attribute information as defined in :attr:`~Controller.axis_attributes` .. versionadded:: 1.0""" ret = copy.deepcopy(self.standard_axis_attributes) axis_attrs = copy.deepcopy(self.axis_attributes) old_axis_attrs = copy.deepcopy(self.ctrl_extra_attributes) ret.update(axis_attrs) ret.update(old_axis_attrs) return ret def SendToCtrl(self, stream): """**Controller API**. Override if necessary. Sends a string to the controller. Default implementation raises :exc:`NotImplementedError`. :param str stream: stream to be sent""" raise NotImplementedError("SendToCtrl not implemented") class Startable(object): """A Startable interface. A controller for which it's axis are 'startable' (like a motor, for example) should implement this interface .. note: Do not inherit directly from :class:`Startable`.""" def PreStartAll(self): """**Controller API**. Override if necessary. Called to prepare a start of all axis (whatever pre-start means). Default implementation does nothing.""" pass def PreStartOne(self, axis, value): """**Controller API**. Override if necessary. Called to prepare a start of the given axis (whatever pre-start means). Default implementation returns True. :param int axis: axis number :param float value: new value :return: True means a successfull pre-start or False for a failure :rtype: bool""" return True def StartOne(self, axis, value): """**Controller API**. Override if necessary. Called to do a start of the given axis (whatever start means). Default implementation raises :exc:`NotImplementedError` :param int axis: axis number :param float value: new value""" raise NotImplementedError("StartOne must be defined in the controller") def StartAll(self): """**Controller API**. Override is MANDATORY! Default implementation does nothing.""" pass class Stopable(object): """A Stopable interface. A controller for which it's axis are 'stoppable' (like a motor, for example) should implement this interface .. note: Do not inherit directly from :class:`Stopable`.""" def AbortOne(self, axis): """**Controller API**. Override is MANDATORY! Default implementation raises :exc:`NotImplementedError`. Aborts one of the axis :param int axis: axis number""" raise NotImplementedError("AbortOne must be defined in te controller") def AbortAll(self): """**Controller API**. Override if necessary. Aborts all active axis of this controller. Default implementation calls :meth:`~Controller.AbortOne` on each active axis. .. versionadded:: 1.0""" exceptions = [] axes = self._getPoolController().get_element_axis().keys() for axis in axes: try: self.AbortOne(axis) except: import sys exceptions.append(sys.exc_info()) if len(exceptions) > 0: raise Exception(exceptions) def StopOne(self, axis): """**Controller API**. Override if necessary. Stops one of the axis. *This method is reserved for future implementation.* Default implementation calls :meth:`~Controller.AbortOne`. :param int axis: axis number .. versionadded:: 1.0""" self.AbortOne(axis) def StopAll(self): """**Controller API**. Override if necessary. Stops all active axis of this controller. *This method is reserved for future implementation.* Default implementation calls :meth:`~Controller.StopOne` on each active axis. .. versionadded:: 1.0""" exceptions = [] axes = self._getPoolController().get_element_axis().keys() for axis in axes: try: self.StopOne(axis) except: import sys exceptions.append(sys.exc_info()) if len(exceptions) > 0: raise Exception(exceptions) class Readable(object): """A Readable interface. A controller for which it's axis are 'readable' (like a motor, counter or 1D for example) should implement this interface .. note: Do not inherit directly from Readable.""" def PreReadAll(self): """**Controller API**. Override if necessary. Called to prepare a read of the value of all axis. Default implementation does nothing.""" pass def PreReadOne(self, axis): """**Controller API**. Override if necessary. Called to prepare a read of the value of a single axis. Default implementation does nothing. :param int axis: axis number""" pass def ReadAll(self): """**Controller API**. Override if necessary. Called to read the value of all selected axis Default implementation does nothing.""" pass def ReadOne(self, axis): """**Controller API**. Override is MANDATORY! Default implementation raises :exc:`NotImplementedError` :param int axis: axis number :return: the axis value :rtype: object """ raise NotImplementedError("ReadOne must be defined in the controller") class Loadable(object): """A Loadable interface. A controller for which it's axis are 'loadable' (like a counter, 1D or 2D for example) should implement this interface .. note: Do not inherit directly from Loadable.""" def PreLoadAll(self): """**Controller API**. Override if necessary. Called to prepare loading the integration time / monitor value. Default implementation does nothing.""" pass def PreLoadOne(self, axis, value): """**Controller API**. Override if necessary. Called to prepare loading the master channel axis with the integration time / monitor value. Default implementation returns True. :param int axis: axis number :param float value: integration time /monitor value :return: True means a successfull PreLoadOne or False for a failure :rtype: bool""" return True def LoadAll(self): """**Controller API**. Override if necessary. Called to load the integration time / monitor value. Default implementation does nothing.""" pass def LoadOne(self, axis, value): """**Controller API**. Override is MANDATORY! Called to load the integration time / monitor value. Default implementation raises :exc:`NotImplementedError`. :param int axis: axis number :param float value: integration time /monitor value""" raise NotImplementedError("LoadOne must be defined in the controller") class MotorController(Controller, Startable, Stopable, Readable): """Base class for a motor controller. Inherit from this class to implement your own motor controller for the device pool. A motor controller should support these axis parameters: - acceleration - deceleration - velocity - base_rate - step_per_unit These parameters are configured through the :meth:`~Controller.GetAxisPar`/:meth:`~Controller.SetAxisPar` API (in version <1.0 the methods were called :meth:`~Controller.GetPar`/:meth:`~Controller.SetPar`. Default :meth:`~Controller.GetAxisPar` and :meth:`~Controller.SetAxisPar` still call :meth:`~Controller.GetPar` and :meth:`~Controller.SetPar` respectively in order to maintain backward compatibility). """ #: A constant representing no active switch. NoLimitSwitch = 0 #: A constant representing an active *home* switch. #: You can *OR* two or more switches together. For example, to say both #: upper and lower limit switches are active:: #: #: limit_switches = self.HomeLimitSwitch | self.LowerLimitSwitch HomeLimitSwitch = 1 #: A constant representing an active *upper limit* switch. #: You can *OR* two or more switches together. For example, to say both #: upper and lower limit switches are active:: #: #: limit_switches = self.UpperLimitSwitch | self.LowerLimitSwitch UpperLimitSwitch = 2 #: A constant representing an active *lower limit* switch. #: You can *OR* two or more switches together. For example, to say both #: upper and lower limit switches are active:: #: #: limit_switches = self.UpperLimitSwitch | self.LowerLimitSwitch LowerLimitSwitch = 4 #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { 'Position' : { 'type' : float, 'description' : 'Position', }, 'DialPosition' : { 'type' : float, 'description' : 'Dial Position', }, 'Offset' : { 'type' : float, 'description' : 'Offset', }, 'Sign' : { 'type' : float, 'description' : 'Sign', }, 'Step_per_unit' : { 'type' : float, 'description' : 'Steps per unit', }, 'Acceleration' : { 'type' : float, 'description' : 'Acceleration time (s)', }, 'Deceleration' : { 'type' : float, 'description' : 'Deceleration time (s)', }, 'Base_rate' : { 'type' : float, 'description' : 'Base rate', }, 'Velocity' : { 'type' : float, 'description' : 'Velocity', }, 'Backlash' : { 'type' : float, 'description' : 'Backlash', }, 'Limit_switches' : { 'type' : (bool,), 'description' : "This attribute is the motor "\ "limit switches state. It's an array with 3 \n"\ "elements which are:\n"\ "0 - The home switch\n"\ "1 - The upper limit switch\n"\ "2 - The lower limit switch\n"\ "False means not active. True means active", }, } standard_axis_attributes.update(Controller.standard_axis_attributes) #: A :obj:`str` representing the controller gender gender = 'Motor controller' def GetAxisAttributes(self, axis): """**Motor Controller API**. Override if necessary. Returns a sequence of all attributes per axis. Default implementation returns a :class:`dict` containning: - Position - DialPosition - Offset - Sign - Step_per_unit - Acceleration - Deceleration - Base_rate - Velocity - Backlash - Limit_switches plus all attributes contained in :attr:`~Controller.axis_attributes` .. note:: Normally you don't need to Override this method. You just implement the class member :attr:`~Controller.axis_attributes`. Typically, you will need to Override this method in two cases: - certain axes contain a different set of extra attributes which cannot be simply defined in :attr:`~Controller.axis_attributes` - some axes (or all) don't implement a set of standard moveable parameters (ex.: if a motor controller is created to control a power supply, it may have a position (current) and a velocity (ramp speed) but it may not have acceleration) :param int axis: axis number :return: a dict containing attribute information as defined in :attr:`~Controller.axis_attributes` .. versionadded:: 1.0""" return Controller.GetAxisAttributes(self, axis) def DefinePosition(self, axis, position): """**Motor Controller API**. Override is recommended! This method is called to load a new motor position. Default implementation does nothing. """ # raise NotImplementedError("DefinePosition must be defined in the " # "controller") pass class CounterTimerController(Controller, Readable, Startable, Stopable, Loadable): """Base class for a counter/timer controller. Inherit from this class to implement your own counter/timer controller for the device pool. A counter timer controller should support these controller parameters: - timer - monitor - trigger_type""" #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { 'Value' : { 'type' : float, 'description' : 'Value', }, } standard_axis_attributes.update(Controller.standard_axis_attributes) #: A :obj:`str` representing the controller gender gender = 'Counter/Timer controller' def __init__(self, inst, props, *args, **kwargs): Controller.__init__(self, inst, props, *args, **kwargs) self._timer = None self._monitor = None self._master = None self._trigger_type = AcqTriggerType.Unknown def PreStartAllCT(self): """**Counter/Timer Controller API**. Override if necessary. Called to prepare an acquisition of all selected axis. Default implementation does nothing. .. deprecated:: 1.0 use :meth:`~CounterTimerController.PreStartAll` instead""" pass def PreStartOneCT(self, axis): """**Counter/Timer Controller API**. Override if necessary. Called to prepare an acquisition a single axis. Default implementation returns True. :param int axis: axis number :return: True means a successfull PreStartOneCT or False for a failure :rtype: bool .. deprecated:: 1.0 use :meth:`~CounterTimerController.PreStartOne` instead""" return True def StartOneCT(self, axis): """**Counter/Timer Controller API**. Override if necessary. Called to start an acquisition of a selected axis. Default implementation does nothing. :param int axis: axis number .. deprecated:: 1.0 use :meth:`~CounterTimerController.StartOne` instead""" pass def StartAllCT(self): """**Counter/Timer Controller API**. Override is MANDATORY! Called to start an acquisition of a selected axis. Default implementation raises :exc:`NotImplementedError`. .. deprecated:: 1.0 use :meth:`~CounterTimerController.StartAll` instead""" raise NotImplementedError("StartAll must be defined in the " "controller") def PreStartAll(self): """**Controller API**. Override if necessary. Called to prepare a write of the position of all axis. Default implementation calls deprecated :meth:`~CounterTimerController.PreStartAllCT` which, by default, does nothing. .. versionadded:: 1.0""" return self.PreStartAllCT() def PreStartOne(self, axis, value=None): """**Controller API**. Override if necessary. Called to prepare a write of the position of a single axis. Default implementation calls deprecated :meth:`~CounterTimerController.PreStartOneCT` which, by default, returns True. :param int axis: axis number :param float value: the value :return: True means a successfull pre-start or False for a failure :rtype: bool .. versionadded:: 1.0""" return self.PreStartOneCT(axis) def StartOne(self, axis, value=None): """**Controller API**. Override if necessary. Called to write the position of a selected axis. Default implementation calls deprecated :meth:`~CounterTimerController.StartOneCT` which, by default, does nothing. :param int axis: axis number :param float value: the value""" return self.StartOneCT(axis) def StartAll(self): """**Controller API**. Override is MANDATORY! Default implementation calls deprecated :meth:`~CounterTimerController.StartAllCT` which, by default, raises :exc:`NotImplementedError`.""" return self.StartAllCT() class ZeroDController(Controller, Readable, Stopable): """Base class for a 0D controller. Inherit from this class to implement your own 0D controller for the device pool.""" #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { 'Value' : { 'type' : float, 'description' : 'Value', }, } standard_axis_attributes.update(Controller.standard_axis_attributes) #: A :obj:`str` representing the controller gender gender = '0D controller' def AbortOne(self, axis): """This method is not executed by the system. Default implementation does nothing. :param int axis: axis number""" pass class OneDController(Controller, Readable, Startable, Stopable, Loadable): """Base class for a 1D controller. Inherit from this class to implement your own 1D controller for the device pool. .. versionadded:: 1.2""" standard_axis_attributes = { 'Value' : { 'type' : (float,), 'description' : 'Value', 'maxdimsize' : (16*1024,) }, } standard_axis_attributes.update(Controller.standard_axis_attributes) #: A :obj:`str` representing the controller gender gender = '1D controller' def GetAxisPar(self, axis, parameter): """**Controller API**. Override is MANDATORY. Called to get a parameter value on the given axis. If parameter == 'data_source', default implementation returns None, meaning let sardana decide the proper URI for accessing the axis value. Otherwise, default implementation calls deprecated :meth:`~Controller.GetPar` which, by default, raises :exc:`NotImplementedError`. .. versionadded:: 1.2""" if parameter.lower() == 'data_source': return None return self.GetPar(axis, parameter) class TwoDController(Controller, Readable, Startable, Stopable, Loadable): """Base class for a 2D controller. Inherit from this class to implement your own 2D controller for the device pool.""" standard_axis_attributes = { 'Value' : { 'type' : ((float,),), 'description' : 'Value', 'maxdimsize' : (4*1024, 4*1024) }, } standard_axis_attributes.update(Controller.standard_axis_attributes) #: A :obj:`str` representing the controller gender gender = '2D controller' def GetAxisPar(self, axis, parameter): """**Controller API**. Override is MANDATORY. Called to get a parameter value on the given axis. If parameter == 'data_source', default implementation returns None, meaning let sardana decide the proper URI for accessing the axis value. Otherwise, default implementation calls deprecated :meth:`~Controller.GetPar` which, by default, raises :exc:`NotImplementedError`. .. versionadded:: 1.2""" if parameter.lower() == 'data_source': return None return self.GetPar(axis, parameter) class PseudoController(Controller): """Base class for all pseudo controllers. .. note: Do not inherit directly from :class:`PseudoController`.""" def _getElem(self, index_or_role, roles, local_cache, ids): """*Iternal*.""" elem = local_cache.get(index_or_role) if elem is None: pool = self._getPoolController().pool if type(index_or_role) == int: index = index_or_role role = roles[index] else: role = index_or_role index = roles.index(role) motor_id = ids[index] elem = pool.get_element_by_id(motor_id) local_cache[index] = local_cache[role] = elem return elem class PseudoMotorController(PseudoController): """Base class for a pseudo motor controller. Inherit from this class to implement your own pseudo motor controller for the device pool. Every Pseudo Motor implementation must be a subclass of this class. Current procedure for a correct implementation of a Pseudo Motor class: - mandatory: - define the class level attributes :attr:`~PseudoMotorController.pseudo_motor_roles`, :attr:`~PseudoMotorController.motor_roles` - write :meth:`~PseudoMotorController.CalcPseudo` method - write :meth:`~PseudoMotorController.CalcPhysical` method. - optional: - write :meth:`~PseudoMotorController.CalcAllPseudo` and :meth:`~PseudoMotorController.CalcAllPhysical` if great performance gain can be achived""" #: a sequence of strings describing the role of each pseudo motor axis in #: this controller pseudo_motor_roles = () #: a sequence of strings describing the role of each motor in this #: controller motor_roles = () #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { 'Position' : { 'type' : float, 'description' : 'Position', }, } #: A :obj:`str` representing the controller gender gender = 'Pseudo motor controller' def __init__(self, inst, props, *args, **kwargs): self.__motor_role_elements = {} self.__pseudo_motor_role_elements = {} PseudoController.__init__(self, inst, props, *args, **kwargs) def CalcAllPseudo(self, physical_pos, curr_pseudo_pos): """**Pseudo Motor Controller API**. Override if necessary. Calculates the positions of all pseudo motors that belong to the pseudo motor system from the positions of the physical motors. Default implementation does a loop calling :meth:`PseudoMotorController.calc_pseudo` for each pseudo motor role. :param sequence physical_pos: a sequence containing physical motor positions :param sequence curr_pseudo_pos: a sequence containing the current pseudo motor positions :return: a sequece of pseudo motor positions (one for each pseudo motor role) :rtype: sequence .. versionadded:: 1.0""" ret = [] for i in range(len(self.pseudo_motor_roles)): ret.append(self.CalcPseudo(i+1, physical_pos, curr_pseudo_pos)) return ret def CalcAllPhysical(self, pseudo_pos, curr_physical_pos): """**Pseudo Motor Controller API**. Override if necessary. Calculates the positions of all motors that belong to the pseudo motor system from the positions of the pseudo motors. Default implementation does a loop calling :meth:`PseudoMotorController.calc_physical` for each motor role. :param sequence pseudo_pos: a sequence containing pseudo motor positions :param sequence curr_physical_pos: a sequence containing the current physical motor positions :return: a sequece of motor positions (one for each motor role) :rtype: sequence .. versionadded:: 1.0""" ret = [] for i in range(len(self.motor_roles)): pos = self.CalcPhysical(i+1, pseudo_pos, curr_physical_pos) ret.append(pos) return ret def CalcPseudo(self, axis, physical_pos, curr_pseudo_pos): """**Pseudo Motor Controller API**. Override is **MANDATORY**. Calculate pseudo motor position given the physical motor positions :param int axis: the pseudo motor role axis :param sequence physical_pos: a sequence containing motor positions :param sequence curr_pseudo_pos: a sequence containing the current pseudo motor positions :return: a pseudo motor position corresponding to the given axis pseudo motor role :rtype: float .. versionadded:: 1.0""" return self.calc_pseudo(axis, physical_pos) def CalcPhysical(self, axis, pseudo_pos, curr_physical_pos): """**Pseudo Motor Controller API**. Override is **MANDATORY**. Calculate physical motor position given the pseudo motor positions. :param axis: the motor role axis :type axis: int :param pseudo_pos: a sequence containing pseudo motor positions :type pseudo_pos: sequence :param curr_physical_pos: a sequence containing the current physical motor positions :type curr_physical_pos: sequence :return: a motor position corresponding to the given axis motor role :rtype: float .. versionadded:: 1.0""" return self.calc_physical(axis, pseudo_pos) def calc_all_pseudo(self, physical_pos): """**Pseudo Motor Controller API**. Override if necessary. Calculates the positions of all pseudo motors that belong to the pseudo motor system from the positions of the physical motors. Default implementation does a loop calling :meth:`PseudoMotorController.calc_pseudo` for each pseudo motor role. :param sequence physical_pos: a sequence of physical motor positions :return: a sequece of pseudo motor positions (one for each pseudo motor role) :rtype: sequence .. deprecated:: 1.0 implement :meth:`~PseudoMotorController.CalcAllPseudo` instead""" ret = [] for i in range(len(self.pseudo_motor_roles)): ret.append(self.calc_pseudo(i+1, physical_pos)) return ret def calc_all_physical(self, pseudo_pos): """**Pseudo Motor Controller API**. Override if necessary. Calculates the positions of all motors that belong to the pseudo motor system from the positions of the pseudo motors. Default implementation does a loop calling :meth:`PseudoMotorController.calc_physical` for each motor role. :param pseudo_pos: a sequence of pseudo motor positions :type pseudo_pos: sequence :return: a sequece of motor positions (one for each motor role) :rtype: sequence .. deprecated:: 1.0 implement :meth:`~PseudoMotorController.CalcAllPhysical` instead""" ret = [] for i in range(len(self.motor_roles)): pos = self.calc_physical(i+1, pseudo_pos) ret.append(pos) return ret def calc_pseudo(self, axis, physical_pos): """**Pseudo Motor Controller API**. Override is **MANDATORY**. Calculate pseudo motor position given the physical motor positions :param int axis: the pseudo motor role axis :param sequence physical_pos: a sequence of motor positions :return: a pseudo motor position corresponding to the given axis pseudo motor role :rtype: float .. deprecated:: 1.0 implement :meth:`~PseudoMotorController.CalcPseudo` instead""" raise NotImplementedError("CalcPseudo must be defined in te controller") def calc_physical(self, axis, pseudo_pos): """**Pseudo Motor Controller API**. Override is **MANDATORY**. Calculate physical motor position given the pseudo motor positions. :param axis: the motor role axis :type axis: int :param pseudo_pos: a sequence of pseudo motor positions :type pseudo_pos: sequence :return: a motor position corresponding to the given axis motor role :rtype: float .. deprecated:: 1.0 implement :meth:`~PseudoMotorController.CalcPhysical` instead""" raise NotImplementedError("CalcPhysical must be defined in the " "controller") def GetMotor(self, index_or_role): """Returns the motor for a given role/index. .. warning:: * Use with care: Executing motor methods can be dangerous! * Since the controller is built before any element (including motors), this method will **FAIL** when called from the controller constructor :param index_or_role: index number or role name :type index_or_role: int or str :return: Motor object for the given role/index :rtype: :class:`~sardana.pool.poolmotor.PoolMotor`""" return self._getElem(index_or_role, self.motor_roles, self.__motor_role_elements, self._kwargs['motor_ids']) def GetPseudoMotor(self, index_or_role): """Returns the pseudo motor for a given role/index. .. warning:: * Use with care: Executing pseudo motor methods can be dangerous! * Since the controller is built before any element (including pseudo motors), this method will **FAIL** when called from the controller constructor :param index_or_role: index number or role name :type index_or_role: int or str :return: PseudoMotor object for the given role/index :rtype: :class:`~sardana.pool.poolpseudomotor.PoolPseudoMotor`""" return self._getElem(index_or_role, self.pseudo_motor_roles, self.__pseudo_motor_role_elements, self._kwargs['pseudo_motor_roles']) class PseudoCounterController(Controller): """Base class for a pseudo counter controller. Inherit from this class to implement your own pseudo counter controller for the device pool. Every Pseudo Counter implementation must be a subclass of this class. Current procedure for a correct implementation of a Pseudo Counter class: - mandatory: - define the class level attributes :attr:`~PseudoCounterController.counter_roles`, - write :meth:`~PseudoCounterController.Calc` method""" #: a sequence of strings describing the role of each pseudo counter axis in #: this controller pseudo_counter_roles = () #: a sequence of strings describing the role of each counter in this #: controller counter_roles = () #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { 'Value' : { 'type' : float, 'description' : 'Value', }, } #: A :obj:`str` representing the controller gender gender = 'Pseudo counter controller' def Calc(self, axis, values): """**Pseudo Counter Controller API**. Override is **MANDATORY**. Calculate pseudo counter position given the counter values. :param int axis: the pseudo counter role axis :param sequence values: a sequence containing current values of underlying elements :return: a pseudo counter value corresponding to the given axis pseudo counter role :rtype: float .. versionadded:: 1.0""" return self.calc(axis, values) def calc(self, axis, values): """**Pseudo Counter Controller API**. Override is **MANDATORY**. Calculate pseudo counter value given the counter values. :param int axis: the pseudo counter role axis :param sequence values: a sequence containing current values of underlying elements :return: a pseudo counter value corresponding to the given axis pseudo counter role :rtype: float .. deprecated:: 1.0 implement :meth:`~PseudoCounterController.Calc` instead""" raise NotImplementedError("Calc must be defined in te controller") def CalcAll(self, values): """**Pseudo Counter Controller API**. Override if necessary. Calculates all pseudo counter values from the values of counters. Default implementation does a loop calling :meth:`PseudoCounterController.Calc` for each pseudo counter role. :param sequence values: a sequence containing current values of underlying elements :return: a sequece of pseudo counter values (one for each pseudo counter role) :rtype: sequence .. versionadded:: 1.2""" f, n = self.Calc, len(self.pseudo_counter_roles) return [ f(i+1, values) for i in range(n) ] class IORegisterController(Controller, Readable): """Base class for a IORegister controller. Inherit from this class to implement your own IORegister controller for the device pool. """ #: .. deprecated:: 1.0 #: use :attr:`~Controller.axis_attributes` instead predefined_values = () #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { 'Value' : { 'type' : float, 'description' : 'Value', }, } #: A :obj:`str` representing the controller gender gender = 'I/O register controller' def __init__(self, inst, props, *args, **kwargs): Controller.__init__(self, inst, props, *args, **kwargs) def WriteOne(self): """**IORegister Controller API**. Override if necessary.""" pass sardana-1.2.0/src/sardana/pool/pool.py0000644000234100017500000006405612174204314021235 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the main pool class""" from __future__ import print_function from __future__ import with_statement __all__ = ["Pool"] __docformat__ = 'restructuredtext' import os.path import logging.handlers from taurus.core.taurusvalidator import AttributeNameValidator from taurus.core.util.containers import CaselessDict from sardana import InvalidId, ElementType, TYPE_ACQUIRABLE_ELEMENTS, \ TYPE_PSEUDO_ELEMENTS, TYPE_PHYSICAL_ELEMENTS, TYPE_MOVEABLE_ELEMENTS from sardana.sardanamanager import SardanaElementManager, SardanaIDManager from sardana.sardanamodulemanager import ModuleManager from sardana.sardanaevent import EventType from .poolobject import PoolObject from .poolcontainer import PoolContainer from .poolcontroller import PoolController from .poolmonitor import PoolMonitor from .poolmetacontroller import TYPE_MAP_OBJ from .poolcontrollermanager import ControllerManager class Graph(dict): def find_path(self, start, end, path=[]): path = path + [start] if start == end: return path if start not in self: return None for node in self[start]: if node not in path: newpath = self.find_path(node, end, path) if newpath: return newpath return None def find_all_paths(self, start, end, path=[]): path = path + [start] if start == end: return [path] if start not in self: return [] paths = [] for node in self[start]: if node not in path: newpaths = self.find_all_paths(node, end, path) for newpath in newpaths: paths.append(newpath) return paths def find_shortest_path(self, start, end, path=[]): path = path + [start] if start == end: return path if start not in self: return None shortest = None for node in self[start]: if node not in path: newpath = self.find_shortest_path(node, end, path) if newpath: if not shortest or len(newpath) < len(shortest): shortest = newpath return shortest class Pool(PoolContainer, PoolObject, SardanaElementManager, SardanaIDManager): """The central pool class.""" #: Default value representing the number of state reads per position #: read during a motion loop Default_MotionLoop_StatesPerPosition = 10 #: Default value representing the sleep time for each motion loop Default_MotionLoop_SleepTime = 0.01 #: Default value representing the number of state reads per value #: read during a motion loop Default_AcqLoop_StatesPerValue = 10 #: Default value representing the sleep time for each acquisition loop Default_AcqLoop_SleepTime = 0.01 Default_DriftCorrection = True def __init__(self, full_name, name=None): self._path_id = None self._motion_loop_states_per_position = self.Default_MotionLoop_StatesPerPosition self._motion_loop_sleep_time = self.Default_MotionLoop_SleepTime self._acq_loop_states_per_value = self.Default_AcqLoop_StatesPerValue self._acq_loop_sleep_time = self.Default_AcqLoop_SleepTime self._drift_correction = self.Default_DriftCorrection self._remote_log_handler = None # dict> # keys are acquisition channel names and value is a dict describing the # channel containing: # - 'name': with value being the channel name (given by user) # - 'full_name': acq channel full name (ex: tango attribute) # - 'origin': 'local' if local to this server or 'remote' if a remote # channel self._extra_acquisition_element_names = CaselessDict() PoolContainer.__init__(self) PoolObject.__init__(self, full_name=full_name, name=name, id=InvalidId, pool=self, elem_type=ElementType.Pool) self._monitor = PoolMonitor(self, "PMonitor", auto_start=False) #self.init_local_logging() ControllerManager().set_pool(self) # TODO: not ready to use. path must be the same as the one calculated in # sardana.tango.core.util:prepare_logging def init_local_logging(self): log = logging.getLogger("Controller") log.propagate = 0 path = os.path.join(os.sep, "tmp", "tango") log_file_name = os.path.join(path, 'controller.log.txt') try: if not os.path.exists(path): os.makedirs(path, 0777) f_h = logging.handlers.RotatingFileHandler(log_file_name, maxBytes=1E7, backupCount=5) f_h.setFormatter(self.getLogFormat()) log.addHandler(f_h) self.info("Controller logs stored in %s", log_file_name) except: self.warning("Controller logs could not be created!") self.debug("Details:", exc_info=1) def clear_remote_logging(self): rh = self._remote_log_handler if rh is None: return log = logging.getLogger("Controller") log.removeHandler(rh) self._remote_log_handler = None def init_remote_logging(self, host=None, port=None): """Initializes remote logging. :param host: host name [default: None, meaning use the machine host name as returned by :func:`socket.gethostname`]. :type host: str :param port: port number [default: None, meaning use :data:`logging.handlers.DEFAULT_TCP_LOGGING_PORT`""" log = logging.getLogger("Controller") # port 0 means no remote logging if port == 0: return # first check that the handler has not been initialized yet for handler in log.handlers: if isinstance(handler, logging.handlers.SocketHandler): return if host is None: import socket host = socket.gethostname() #host = socket.getfqdn() if port is None: port = logging.handlers.DEFAULT_TCP_LOGGING_PORT handler = logging.handlers.SocketHandler(host, port) if hasattr(handler, 'retryMax'): # default max retry is 30s which seems too much. Let's make it that # the pool tries to reconnect to a client every 10s (similar to the # tango event reconnection handler.retryMax = 10.0 log.addHandler(handler) self.info("Remote logging initialized for host '%s' on port %d", host, port) def serialize(self, *args, **kwargs): kwargs = PoolObject.serialize(self, *args, **kwargs) kwargs['type'] = self.__class__.__name__ kwargs['id'] = InvalidId kwargs['parent'] = None return kwargs def set_motion_loop_sleep_time(self, motion_loop_sleep_time): self._motion_loop_sleep_time = motion_loop_sleep_time def get_motion_loop_sleep_time(self): return self._motion_loop_sleep_time motion_loop_sleep_time = property(get_motion_loop_sleep_time, set_motion_loop_sleep_time, doc="motion sleep time (s)") def set_motion_loop_states_per_position(self, motion_loop_states_per_position): self._motion_loop_states_per_position = motion_loop_states_per_position def get_motion_loop_states_per_position(self): return self._motion_loop_states_per_position motion_loop_states_per_position = property(get_motion_loop_states_per_position, set_motion_loop_states_per_position, doc="Number of State reads done before doing a position read in the " "motion loop") def set_acq_loop_sleep_time(self, acq_loop_sleep_time): self._acq_loop_sleep_time = acq_loop_sleep_time def get_acq_loop_sleep_time(self): return self._acq_loop_sleep_time acq_loop_sleep_time = property(get_acq_loop_sleep_time, set_acq_loop_sleep_time, doc="acquisition sleep time (s)") def set_acq_loop_states_per_value(self, acq_loop_states_per_value): self._acq_loop_states_per_value = acq_loop_states_per_value def get_acq_loop_states_per_value(self): return self._acq_loop_states_per_value acq_loop_states_per_value = property(get_acq_loop_states_per_value, set_acq_loop_states_per_value, doc="Number of State reads done before doing a value read in the " "acquisition loop") def set_drift_correction(self, drift_correction): self._drift_correction = drift_correction def get_drift_correction(self): return self._drift_correction drift_correction = property(get_drift_correction, set_drift_correction, doc="drift correction") @property def monitor(self): return self._monitor @property def ctrl_manager(self): return ControllerManager() def set_python_path(self, path): mod_man = ModuleManager() if self._path_id is not None: mod_man.remove_python_path(self._path_id) self._path_id = mod_man.add_python_path(path) def set_path(self, path): self.ctrl_manager.setControllerPath(path, reload=False) def get_controller_libs(self): return self.ctrl_manager.getControllerLibs() def get_controller_lib_names(self): return self.ctrl_manager.getControllerLibNames() def get_controller_class_names(self): return self.ctrl_manager.getControllerNames() def get_controller_classes(self): return self.ctrl_manager.getControllers() def get_controller_class_info(self, name): return self.ctrl_manager.getControllerMetaClass(name) def get_controller_classes_info(self, names): return self.ctrl_manager.getControllerMetaClasses(names) def get_controller_libs_summary_info(self): libs = self.get_controller_libs() ret = [] for ctrl_lib_info in libs: elem = "%s (%s)" % (ctrl_lib_info.getName(), ctrl_lib_info.getFileName()) ret.append(elem) return ret def get_controller_classes_summary_info(self): ctrl_classes = self.get_controller_classes() ret = [] for ctrl_class_info in ctrl_classes: types = ctrl_class_info.getTypes() types_str = [ TYPE_MAP_OBJ[t].name for t in types if t != ElementType.Controller ] types_str = ", ".join(types_str) elem = "%s (%s) %s" % (ctrl_class_info.getName(), ctrl_class_info.getFileName(), types_str) ret.append(elem) return ret def get_elements_str_info(self, obj_type=None): if obj_type is None: objs = self.get_element_id_map().values() objs.extend(self.get_controller_classes()) objs.extend(self.get_controller_libs()) elif obj_type == ElementType.ControllerClass: objs = self.get_controller_classes() elif obj_type == ElementType.ControllerLibrary: objs = self.get_controller_libs() else: objs = self.get_elements_by_type(obj_type) name = self.full_name return [ obj.str(pool=name) for obj in objs ] def get_elements_info(self, obj_type=None): if obj_type is None: objs = self.get_element_id_map().values() objs.extend(self.get_controller_classes()) objs.extend(self.get_controller_libs()) objs.append(self) elif obj_type == ElementType.ControllerClass: objs = self.get_controller_classes() elif obj_type == ElementType.ControllerLibrary: objs = self.get_controller_libs() else: objs = self.get_elements_by_type(obj_type) name = self.full_name return [ obj.serialize(pool=name) for obj in objs ] def get_acquisition_elements_info(self): ret = [] for _, element in self.get_element_name_map().items(): if element.get_type() not in TYPE_ACQUIRABLE_ELEMENTS: continue acq_channel = element.get_default_acquisition_channel() full_name = "{0}/{1}".format(element.full_name, acq_channel) info = dict(name=element.name, full_name=full_name, origin='local') ret.append(info) ret.extend(self._extra_acquisition_element_names.values()) return ret def get_acquisition_elements_str_info(self): return map(self.str_object, self.get_acquisition_elements_info()) def create_controller(self, **kwargs): ctrl_type = kwargs['type'] lib = kwargs['library'] class_name = kwargs['klass'] name = kwargs['name'] elem_type = ElementType[ctrl_type] mod_name, _ = os.path.splitext(lib) kwargs['module'] = mod_name td = TYPE_MAP_OBJ[ElementType.Controller] klass_map = td.klass auto_full_name = td.auto_full_name kwargs['full_name'] = full_name = \ kwargs.get("full_name", auto_full_name.format(**kwargs)) self.check_element(name, full_name) ctrl_class_info = None ctrl_lib_info = self.ctrl_manager.getControllerLib(mod_name) if ctrl_lib_info is not None: ctrl_class_info = ctrl_lib_info.get_controller(class_name) kwargs['pool'] = self kwargs['class_info'] = ctrl_class_info kwargs['lib_info'] = ctrl_lib_info eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) # For pseudo controllers make sure 'role_ids' is given klass = klass_map.get(elem_type, PoolController) if elem_type in TYPE_PSEUDO_ELEMENTS: motor_roles = kwargs['role_ids'] # make sure the properties (that may have come from a case insensitive # environment like tango) are made case sensitive props = {} if ctrl_class_info is None: ctrl_prop_info = {} else: ctrl_prop_info = ctrl_class_info.ctrl_properties for k, v in kwargs['properties'].items(): info = ctrl_prop_info.get(k) if info is None: props[k] = v else: props[info.name] = v kwargs['properties'] = props ctrl = klass(**kwargs) ret = self.add_element(ctrl) self.fire_event(EventType("ElementCreated"), ctrl) return ret def create_element(self, **kwargs): etype = kwargs['type'] ctrl_id = kwargs['ctrl_id'] axis = kwargs['axis'] elem_type = ElementType[etype] name = kwargs['name'] try: ctrl = self.get_element(id=ctrl_id) except: raise Exception("No controller with id '%d' found" % ctrl_id) elem_axis = ctrl.get_element(axis=axis) if elem_axis is not None: raise Exception("Controller already contains axis %d (%s)" % (axis, elem_axis.get_name())) kwargs['pool'] = self kwargs['ctrl'] = ctrl kwargs['ctrl_name'] = ctrl.get_name() td = TYPE_MAP_OBJ[elem_type] klass = td.klass auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) self.check_element(name, full_name) if ctrl.is_online(): ctrl_types, ctrl_id = ctrl.get_ctrl_types(), ctrl.get_id() if elem_type not in ctrl_types: ctrl_type_str = ElementType.whatis(ctrl_types[0]) raise Exception("Cannot create %s in %s controller" % (etype, ctrl_type_str)) #check if controller is online #check if axis is allowed #create the element in the controller eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) elem = klass(**kwargs) ctrl.add_element(elem) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret def create_motor_group(self, **kwargs): name = kwargs['name'] elem_ids = kwargs["user_elements"] kwargs['pool'] = self kwargs["pool_name"] = self.name td = TYPE_MAP_OBJ[ElementType.MotorGroup] klass = td.klass auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) kwargs.pop('pool_name') self.check_element(name, full_name) for elem_id in elem_ids: elem = self.pool.get_element(id=elem_id) if elem.get_type() not in (ElementType.Motor, ElementType.PseudoMotor): raise Exception("%s is not a motor" % elem.name) eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) elem = klass(**kwargs) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret def create_measurement_group(self, **kwargs): name = kwargs['name'] elem_ids = kwargs["user_elements"] kwargs['pool'] = self kwargs["pool_name"] = self.name td = TYPE_MAP_OBJ[ElementType.MeasurementGroup] klass = td.klass auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) kwargs.pop('pool_name') self.check_element(name, full_name) for elem_id in elem_ids: if type(elem_id) is int: self.pool.get_element(id=elem_id) else: tg_attr_validator = AttributeNameValidator() params = tg_attr_validator.getParams(elem_id) if params is None: raise Exception("Invalid channel name %s" % elem_id) eid = kwargs.get('id') if eid is None: kwargs['id'] = eid = self.get_new_id() else: self.reserve_id(eid) elem = klass(**kwargs) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret def delete_element(self, name): try: elem = self.get_element(name=name) except: try: elem = self.get_element(full_name=name) except: raise Exception("There is no element with name '%s'" % name) elem_type = elem.get_type() if elem_type == ElementType.Controller: if len(elem.get_elements()) > 0: raise Exception("Cannot delete controller with elements. " "Delete elements first") elif elem_type == ElementType.Instrument: if elem.has_instruments(): raise Exception("Cannot delete instrument with instruments. " "Delete instruments first") if elem.has_elements(): raise Exception("Cannot delete instrument with elements") parent_instrument = elem.parent_instrument if parent_instrument is not None: parent_instrument.remove_instrument(elem) elif hasattr(elem, "get_controller"): ctrl = elem.get_controller() ctrl.remove_element(elem) instrument = elem.instrument if instrument is not None: instrument.remove_element(elem) self.remove_element(elem) self.fire_event(EventType("ElementDeleted"), elem) def create_instrument(self, full_name, klass_name, id=None): is_root = full_name.count('/') == 1 if is_root: parent_full_name, _ = '', full_name[1:] parent = None else: parent_full_name, _ = full_name.rsplit('/', 1) try: parent = self.get_element_by_full_name(parent_full_name) except: raise Exception("No parent instrument named '%s' found" % parent_full_name) if parent.get_type() != ElementType.Instrument: raise Exception("%s is not an instrument as expected" % parent_full_name) self.check_element(full_name, full_name) td = TYPE_MAP_OBJ[ElementType.Instrument] klass = td.klass if id is None: id = self.get_new_id() else: self.reserve_id(id) elem = klass(id=id, name=full_name, full_name=full_name, parent=parent, klass=klass_name, pool=self) if parent: parent.add_instrument(elem) ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret def stop(self): controllers = self.get_elements_by_type(ElementType.Controller) for controller in controllers: controller.stop_all() def abort(self): controllers = self.get_elements_by_type(ElementType.Controller) for controller in controllers: controller.abort_all() # -------------------------------------------------------------------------- # (Re)load code # -------------------------------------------------------------------------- def reload_controller_lib(self, lib_name): manager = self.ctrl_manager old_lib = manager.getControllerLib(lib_name) new_elements, changed_elements, deleted_elements = [], [], [] old_ctrl_classes = () if old_lib is not None: ctrl_infos = old_lib.get_controllers() pool_ctrls = self.get_elements_by_type(ElementType.Controller) init_pool_ctrls = [] for pool_ctrl in pool_ctrls: if pool_ctrl.get_ctrl_info() in ctrl_infos: init_pool_ctrls.append(pool_ctrl) old_ctrl_classes = ctrl_infos changed_elements.append(old_lib) new_lib = manager.reloadControllerLib(lib_name) if old_lib is None: new_elements.extend(new_lib.get_controllers()) new_elements.append(new_lib) else: new_names = set([ ctrl.name for ctrl in new_lib.get_controllers() ]) old_names = set([ ctrl.name for ctrl in old_lib.get_controllers() ]) changed_names = set.intersection(new_names, old_names) deleted_names = old_names.difference(new_names) new_names = new_names.difference(old_names) for new_name in new_names: new_elements.append(new_lib.get_controller(new_name)) for changed_name in changed_names: changed_elements.append(new_lib.get_controller(changed_name)) for deleted_name in deleted_names: deleted_elements.append(old_lib.get_controller(deleted_name)) evt = { "new" : new_elements, "change" : changed_elements, "del" : deleted_elements } self.fire_event(EventType("ElementsChanged"), evt) if old_lib is not None: for pool_ctrl in init_pool_ctrls: pool_ctrl.re_init() def reload_controller_class(self, class_name): ctrl_info = self.ctrl_manager.getControllerMetaClass(class_name) lib_name = ctrl_info.module_name self.reload_controller_lib(lib_name) def get_element_id_graph(self): physical_elems_id_map = {} elem_type_map = self.get_element_type_map() for elem_type in TYPE_PHYSICAL_ELEMENTS: physical_elems_id_map.update(elem_type_map[elem_type]) #TODO def _build_element_id_dependencies(self, elem_id, graph=None): if graph is None: graph = Graph() elem = self.get_element_by_id(elem_id) if elem.get_id() in graph or elem.get_type() in TYPE_PHYSICAL_ELEMENTS: return graph graph[elem_id] = list(elem.get_user_element_ids()) return graph def get_moveable_id_graph(self): moveable_elems_id_map = {} elem_type_map = self.get_element_type_map() for elem_type in TYPE_MOVEABLE_ELEMENTS: moveable_elems_id_map.update(elem_type_map[elem_type]) graph = Graph() for moveable_id in moveable_elems_id_map: self._build_element_id_dependencies(moveable_id, graph) return graph def _build_element_dependencies(self, elem, graph=None): if graph is None: graph = Graph() if elem.get_id() in graph or elem.get_type() in TYPE_PHYSICAL_ELEMENTS: return graph graph[elem] = list(elem.get_user_elements()) return graph def get_moveable_graph(self): moveable_elems_map = {} elem_type_map = self.get_element_type_map() for elem_type in TYPE_MOVEABLE_ELEMENTS: moveable_elems_map.update(elem_type_map[elem_type]) graph = Graph() for moveable in moveable_elems_map.values(): self._build_element_dependencies(moveable, graph) return graph sardana-1.2.0/src/sardana/pool/poolacquisition.py0000644000234100017500000004774312174204314023512 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the class for an acquisition""" __all__ = [ "AcquisitionState", "AcquisitionMap", "PoolCTAcquisition", "Pool0DAcquisition", "Channel", "PoolIORAcquisition" ] __docformat__ = 'restructuredtext' import time from taurus.core.util import Enumeration, DebugIt from sardana import State, ElementType, TYPE_TIMERABLE_ELEMENTS from sardana.sardanathreadpool import get_thread_pool from poolaction import ActionContext, PoolActionItem, PoolAction #: enumeration representing possible motion states AcquisitionState = Enumeration("AcquisitionState", ( \ "Stopped", # "StoppedOnError", # "StoppedOnAbort", "Acquiring", "Invalid") ) AS = AcquisitionState AcquiringStates = AS.Acquiring, StoppedStates = AS.Stopped, #MS.StoppedOnError, MS.StoppedOnAbort AcquisitionMap = { #AS.Stopped : State.On, AS.Acquiring : State.Moving, AS.Invalid : State.Invalid, } class PoolAcquisition(PoolAction): def __init__(self, main_element, name="Acquisition"): PoolAction.__init__(self, main_element, name) ctname = name + ".CTAcquisition" zerodname = name + ".0DAcquisition" self._0d_acq = zd_acq = Pool0DAcquisition(main_element, name=zerodname) self._ct_acq = PoolCTAcquisition(main_element, name=ctname, slaves=(zd_acq,)) def run(self, *args, **kwargs): n = kwargs.get('multiple', 1) if n == 1: return self._run_single(*args, **kwargs) return self._run_multiple(*args, **kwargs) def _run_multiple(self, *args, **kwargs): n = kwargs['multiple'] synch = kwargs.get("synch", False) if synch: for _ in range(n): self._run_single(self, *args, **kwargs) else: kwargs["synch"] = True get_thread_pool().add(self._run_multiple, None, *args, **kwargs) def _run_single(self, *args, **kwargs): """Runs this action""" synch = kwargs.get("synch", False) ct_acq = self._ct_acq zd_acq = self._0d_acq if synch: ct_acq.run(*args, **kwargs) else: ct_acq.run(*args, **kwargs) zd_acq.run(*args, **kwargs) def _get_acq_for_element(self, element): elem_type = element.get_type() if elem_type in TYPE_TIMERABLE_ELEMENTS: return self._ct_acq elif elem_type == ElementType.ZeroDExpChannel: return self._0d_acq def clear_elements(self): """Clears all elements from this action""" def add_element(self, element): """Adds a new element to this action. :param element: the new element to be added :type element: sardana.pool.poolelement.PoolElement""" return self._get_acq_for_element(element).add_element(element) def remove_element(self, element): """Removes an element from this action. If the element is not part of this action, a ValueError is raised. :param element: the new element to be removed :type element: sardana.pool.poolelement.PoolElement :raises: ValueError""" return self._get_acq_for_element(element).add_element(element) def get_elements(self, copy_of=False): """Returns a sequence of all elements involved in this action. :param copy_of: If False (default) the internal container of elements is returned. If True, a copy of the internal container is returned instead :type copy_of: bool :return: a sequence of all elements involved in this action. :rtype: seq""" return self._ct_acq.get_elements() + self._0d_acq.get_elements() def get_pool_controller_list(self): """Returns a list of all controller elements involved in this action. :return: a list of all controller elements involved in this action. :rtype: list""" return self._pool_ctrl_list def get_pool_controllers(self): """Returns a dict of all controller elements involved in this action. :return: a dict of all controller elements involved in this action. :rtype: dict>""" ret = {} ret.update(self._ct_acq.get_pool_controllers()) ret.update(self._0d_acq.get_pool_controllers()) return ret def read_value(self, ret=None, serial=False): """Reads value information of all elements involved in this action :param ret: output map parameter that should be filled with value information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW value requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing value information per element :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement`, :class:~`sardana.sardanavalue.SardanaValue`>""" ret = self._ct_acq.read_value(ret=ret, serial=serial) ret.update(self._0d_acq.read_value(ret=ret, serial=serial)) return ret class Channel(PoolActionItem): def __init__(self, acquirable, info=None): PoolActionItem.__init__(self, acquirable) if info: self.__dict__.update(info) def __getattr__(self, name): return getattr(self.element, name) class PoolCTAcquisition(PoolAction): def __init__(self, main_element, name="CTAcquisition", slaves=None): self._channels = None if slaves is None: slaves = () self._slaves = slaves PoolAction.__init__(self, main_element, name) def get_read_value_loop_ctrls(self): return self._pool_ctrl_dict_loop def start_action(self, *args, **kwargs): """Prepares everything for acquisition and starts it. :param: config""" pool = self.pool # prepare data structures self._aborted = False self._stopped = False self._acq_sleep_time = kwargs.pop("acq_sleep_time", pool.acq_loop_sleep_time) self._nb_states_per_value = \ kwargs.pop("nb_states_per_value", pool.acq_loop_states_per_value) self._integ_time = integ_time = kwargs.get("integ_time") self._mon_count = mon_count = kwargs.get("monitor_count") if integ_time is None and mon_count is None: raise Exception("must give integration time or monitor counts") if integ_time is not None and mon_count is not None: raise Exception("must give either integration time or monitor counts (not both)") _ = kwargs.get("items", self.get_elements()) cfg = kwargs['config'] # determine which is the controller which holds the master channel if integ_time is not None: master_key = 'timer' master_value = integ_time if mon_count is not None: master_key = 'monitor' master_value = - mon_count master = cfg[master_key] master_ctrl = master.controller pool_ctrls_dict = dict(cfg['controllers']) pool_ctrls_dict.pop('__tango__', None) pool_ctrls = [] self._pool_ctrl_dict_loop = _pool_ctrl_dict_loop = {} for ctrl, v in pool_ctrls_dict.items(): if ctrl.is_timerable(): pool_ctrls.append(ctrl) if ElementType.CTExpChannel in ctrl.get_ctrl_types(): _pool_ctrl_dict_loop[ctrl] = v # make sure the controller which has the master channel is the last to # be called pool_ctrls.remove(master_ctrl) pool_ctrls.append(master_ctrl) # Determine which channels are active self._channels = channels = {} for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] elements = main_unit_data['channels'] for element, element_info in elements.items(): axis = element.axis channel = Channel(element, info=element_info) channels[element] = channel #for channel in channels: # channel.prepare_to_acquire(self) with ActionContext(self): # PreLoadAll, PreLoadOne, LoadOne and LoadAll for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] ctrl.PreLoadAll() master = main_unit_data[master_key] axis = master.axis res = ctrl.PreLoadOne(axis, master_value) if not res: raise Exception("%s.PreLoadOne(%d) returns False" % (pool_ctrl.name, axis,)) ctrl.LoadOne(axis, master_value) ctrl.LoadAll() # PreStartAll on all controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.PreStartAll() # PreStartOne & StartOne on all elements for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] elements = main_unit_data['channels'] for element in elements: axis = element.axis channel = channels[element] if channel.enabled: ret = ctrl.PreStartOne(axis, master_value) if not ret: raise Exception("%s.PreStartOne(%d) returns False" \ % (pool_ctrl.name, axis)) ctrl.StartOne(axis, master_value) # set the state of all elements to and inform their listeners for channel in channels: channel.set_state(State.Moving, propagate=2) # StartAll on all controllers for pool_ctrl in pool_ctrls: pool_ctrl.ctrl.StartAll() def in_acquisition(self, states): """Determines if we are in acquisition or if the acquisition has ended based on the current unit trigger modes and states returned by the controller(s) :param states: a map containing state information as returned by read_state_info :type states: dict :return: returns True if in acquisition or False otherwise :rtype: bool""" for elem in states: s = states[elem][0][0] if self._is_in_action(s): return True def action_loop(self): i = 0 states, values = {}, {} for element in self._channels: states[element] = None #values[element] = None nap = self._acq_sleep_time nb_states_per_value = self._nb_states_per_value # read values to send a first event when starting to acquire with ActionContext(self): self.raw_read_value_loop(ret=values) for acquirable, value in values.items(): acquirable.put_value(value, propagate=2) while True: self.read_state_info(ret=states) if not self.in_acquisition(states): break # read value every n times if not i % nb_states_per_value: self.read_value_loop(ret=values) for acquirable, value in values.items(): acquirable.put_value(value) time.sleep(nap) i += 1 for slave in self._slaves: try: slave.stop_action() except: self.warning("Unable to stop slave acquisition %s", slave.getLogName()) self.debug("Details", exc_info=1) with ActionContext(self): self.raw_read_state_info(ret=states) self.raw_read_value_loop(ret=values) for acquirable, state_info in states.items(): # first update the element state so that value calculation # that is done after takes the updated state into account acquirable.set_state_info(state_info, propagate=0) if acquirable in values: value = values[acquirable] acquirable.put_value(value, propagate=2) with acquirable: acquirable.clear_operation() state_info = acquirable._from_ctrl_state_info(state_info) acquirable.set_state_info(state_info, propagate=2) class Pool0DAcquisition(PoolAction): def __init__(self, main_element, name="0DAcquisition"): self._channels = None PoolAction.__init__(self, main_element, name) def start_action(self, *args, **kwargs): """Prepares everything for acquisition and starts it. :param: config""" pool = self.pool # prepare data structures self._aborted = False self._stopped = False self._acq_sleep_time = kwargs.pop("acq_sleep_time", pool.acq_loop_sleep_time) self._nb_states_per_value = \ kwargs.pop("nb_states_per_value", pool.acq_loop_states_per_value) integ_time = kwargs.get("integ_time") mon_count = kwargs.get("monitor_count") if integ_time is None and mon_count is None: raise Exception("must give integration time or monitor counts") if integ_time is not None and mon_count is not None: raise Exception("must give either integration time or monitor counts (not both)") items = kwargs.get("items") if items is None: items = self.get_elements() cfg = kwargs['config'] pool_ctrls_dict = dict(cfg['controllers']) pool_ctrls_dict.pop('__tango__', None) pool_ctrls = [] for ctrl in pool_ctrls_dict: if ElementType.ZeroDExpChannel in ctrl.get_ctrl_types(): pool_ctrls.append(ctrl) # Determine which channels are active self._channels = channels = {} for pool_ctrl in pool_ctrls: ctrl = pool_ctrl.ctrl pool_ctrl_data = pool_ctrls_dict[pool_ctrl] main_unit_data = pool_ctrl_data['units']['0'] elements = main_unit_data['channels'] for element, element_info in elements.items(): channel = Channel(element, info=element_info) channels[element] = channel with ActionContext(self): # set the state of all elements to and inform their listeners for channel in channels: channel.clear_buffer() channel.set_state(State.Moving, propagate=2) def in_acquisition(self, states): """Determines if we are in acquisition or if the acquisition has ended based on the current unit trigger modes and states returned by the controller(s) :param states: a map containing state information as returned by read_state_info :type states: dict :return: returns True if in acquisition or False otherwise :rtype: bool""" for state in states: s = states[state][0] if self._is_in_action(s): return True def action_loop(self): i = 0 states, values = {}, {} for element in self._channels: states[element] = None values[element] = None nap = self._acq_sleep_time while not (self._stopped or self._aborted): self.read_value(ret=values) for acquirable, value in values.items(): acquirable.put_value(value) i += 1 time.sleep(nap) with ActionContext(self): self.raw_read_state_info(ret=states) for acquirable, state_info in states.items(): # first update the element state so that value calculation # that is done after takes the updated state into account state_info = acquirable._from_ctrl_state_info(state_info) acquirable.set_state_info(state_info, propagate=0) with acquirable: acquirable.clear_operation() acquirable.set_state_info(state_info, propagate=2) def stop_action(self, *args, **kwargs): """Stop procedure for this action.""" self._stopped = True def abort_action(self, *args, **kwargs): """Aborts procedure for this action""" self._aborted = True class PoolIORAcquisition(PoolAction): def __init__(self, pool, name="IORAcquisition"): self._channels = None PoolAction.__init__(self, pool, name) def start_action(self, *args, **kwargs): pass def in_acquisition(self, states): return True pass @DebugIt() def action_loop(self): i = 0 states, values = {}, {} for element in self._channels: states[element] = None values[element] = None # read values to send a first event when starting to acquire self.read_value(ret=values) for acquirable, value in values.items(): acquirable.put_value(value, propagate=2) while True: self.read_state_info(ret=states) if not self.in_acquisition(states): break # read value every n times if not i % 5: self.read_value(ret=values) for acquirable, value in values.items(): acquirable.put_value(value) i += 1 time.sleep(0.01) self.read_state_info(ret=states) # first update the element state so that value calculation # that is done after takes the updated state into account for acquirable, state_info in states.items(): acquirable.set_state_info(state_info, propagate=0) # Do NOT send events before we exit the OperationContext, otherwise # we may be asked to start another action before we leave the context # of the current action. Instead, send the events in the finish hook # which is executed outside the OperationContext def finish_hook(*args, **kwargs): # read values and propagate the change to all listeners self.read_value(ret=values) for acquirable, value in values.items(): acquirable.put_value(value, propagate=2) # finally set the state and propagate to all listeners for acquirable, state_info in states.items(): acquirable.set_state_info(state_info, propagate=2) self.set_finish_hook(finish_hook) sardana-1.2.0/src/sardana/pool/poolaction.py0000644000234100017500000005533112174204314022427 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the class for an abstract action over a set of pool elements""" __all__ = ["PoolActionItem", "OperationInfo", "ActionContext", "PoolAction", "get_thread_pool"] __docformat__ = 'restructuredtext' import sys import weakref import traceback import threading from taurus.core.util import Logger from sardana import State from sardana.sardanathreadpool import get_thread_pool from .poolobject import PoolObject class PoolActionItem(object): """The base class for an atomic action item""" def __init__(self, element): self._element = weakref.ref(element) def get_element(self): """Returns the element associated with this item""" return self._element() def set_element(self, element): """Sets the element for this item""" self._element = weakref.ref(element) element = property(get_element) class OperationInfo(object): """Stores synchronization data for a certain operation""" def __init__(self): """Constructor""" self.state_count = 0 self.state_lock = threading.Lock() self.state_event_lock = threading.Lock() self.state_event = threading.Event() def init(self, count): """Initializes this operation with a certain count""" self.state_count = count self.state_event.clear() if count == 0: self.state_event.set() def wait(self, timeout=None): """waits for the operation to finish""" return self.state_event.wait(timeout) def finish_one(self): """Notifies this operation that one step was finished""" with self.state_event_lock: self.state_count = self.state_count - 1 if self.state_count < 1: self.state_count = 0 self.state_event.set() def acquire(self): """Acquires this operation lock""" self.state_lock.acquire() def release(self): """Releases this operation lock""" self.state_lock.release() def __enter__(self): return self.acquire() def __exit__(self, exc_type, exc_value, exc_traceback): return self.release() class BaseOperationContext(object): """Stores operation context""" def __init__(self, pool_action): self._pool_action = pool_action def enter(self): """Enters operation context""" pool_action = self._pool_action for element in pool_action.get_elements(): element.lock() element.set_operation(pool_action) for ctrl in pool_action.get_pool_controller_list(): ctrl.lock() def exit(self): """Leaves operation context""" pool_action = self._pool_action for element in reversed(pool_action.get_elements()): element.clear_operation() element.unlock() for ctrl in reversed(pool_action.get_pool_controller_list()): ctrl.unlock() pool_action.finish_action() return False def __enter__(self): return self.enter() def __exit__(self, exc_type, exc_value, exc_traceback): return self.exit() class OperationContext(BaseOperationContext): """Concrete operation context""" def enter(self): pool_action = self._pool_action for element in pool_action.get_elements(): element.set_operation(pool_action) def exit(self): pool_action = self._pool_action for element in reversed(pool_action.get_elements()): element.clear_operation() pool_action.finish_action() return False def __enter__(self): return self.enter() def __exit__(self, exc_type, exc_value, exc_traceback): return self.exit() class ActionContext(object): """Stores an atomic action context""" def __init__(self, pool_action): self._pool_action = pool_action def enter(self): """Enters operation""" pool_action = self._pool_action for element in pool_action.get_elements(): element.lock() for ctrl in pool_action.get_pool_controller_list(): ctrl.lock() def exit(self): """Leaves operation""" pool_action = self._pool_action for element in reversed(pool_action.get_elements()): element.unlock() for ctrl in reversed(pool_action.get_pool_controller_list()): ctrl.unlock() return False def __enter__(self): return self.enter() def __exit__(self, exc_type, exc_value, exc_traceback): return self.exit() class PoolAction(Logger): """A generic class to handle any type of operation (like motion or acquisition)""" def __init__(self, main_element, name="GlobalAction"): Logger.__init__(self, name) self._action_run_lock = threading.Lock() self._main_element = weakref.ref(main_element) self._aborted = False self._stopped = False self._elements = [] self._pool_ctrl_dict = {} self._pool_ctrl_list = [] self._finish_hook = None self._running = False self._state_info = OperationInfo() self._value_info = OperationInfo() def get_main_element(self): """Returns the main element for this action :return: sardana.pool.poolelement.PoolElement""" return self._main_element() main_element = property(get_main_element) def get_pool(self): """Returns the pool object for thi action :return: sardana.pool.pool.Pool""" return self.main_element.pool pool = property(get_pool) def clear_elements(self): """Clears all elements from this action""" self._elements = [] self._pool_ctrl_dict = {} self._pool_ctrl_list = [] def add_element(self, element): """Adds a new element to this action. :param element: the new element to be added :type element: sardana.pool.poolelement.PoolElement""" ctrl = element.controller ctrl_items = self._pool_ctrl_dict.get(ctrl) if ctrl_items is None: ctrl_items = [] self._pool_ctrl_dict[ctrl] = ctrl_items self._pool_ctrl_list.append(ctrl) self._pool_ctrl_list.sort(key=PoolObject.get_id) self._elements.append(element) ctrl_items.append(element) # make sure elements are ordered by ID so that a multiple lock always # locks and unlocks in the same order self._elements.sort(key=PoolObject.get_id) ctrl_items.sort(key=PoolObject.get_id) def remove_element(self, element): """Removes an element from this action. If the element is not part of this action, a ValueError is raised. :param element: the new element to be removed :type element: sardana.pool.poolelement.PoolElement :raises: ValueError""" ctrl = element.controller #element = weakref.ref(element) try: idx = self._elements.index(element) except ValueError: raise ValueError("action doesn't contain %s" % element.name) del self._elements[idx] ctrl_items = self._pool_ctrl_dict[ctrl] del ctrl_items[ctrl_items.index(element)] if not len(ctrl_items): del self._pool_ctrl_dict[ctrl] del self._pool_ctrl_list[self._pool_ctrl_list.index(ctrl)] def get_elements(self, copy_of=False): """Returns a sequence of all elements involved in this action. :param copy_of: If False (default) the internal container of elements is returned. If True, a copy of the internal container is returned instead :type copy_of: bool :return: a sequence of all elements involved in this action. :rtype: seq""" elements = self._elements if copy_of: elements = tuple(elements) return elements def get_pool_controller_list(self): """Returns a list of all controller elements involved in this action. :return: a list of all controller elements involved in this action. :rtype: list""" return self._pool_ctrl_list def get_pool_controllers(self): """Returns a dict of all controller elements involved in this action. :return: a dict of all controller elements involved in this action. :rtype: dict>""" return self._pool_ctrl_dict def _is_in_action(self, state): """Determines if the given state is a busy state (Moving or Running) or not. :return: True if state is a busy state or False otherwise :rtype: bool""" return state == State.Moving or state == State.Running def is_running(self): """Determines if this action is running or not :return: True if action is running or False otherwise :rtype: bool""" return self._running def run(self, *args, **kwargs): """Runs this action""" self._running = True synch = kwargs.pop("synch", False) if synch: try: with OperationContext(self) as context: self.start_action(*args, **kwargs) self.action_loop() finally: self._running = False else: context = OperationContext(self) context.enter() try: self.start_action(*args, **kwargs) except: context.exit() self._running = False raise get_thread_pool().add(self._asynch_action_loop, None, context) def start_action(self, *args, **kwargs): """Start procedure for this action. Default implementation raises NotImplementedError :raises: NotImplementedError""" raise NotImplementedError("start_action must be implemented in " "subclass") def set_finish_hook(self, hook): """Attaches/Detaches a finish hook :param hook: a callable object or None :type hook: callable or None""" self._finish_hook = hook def finish_action(self): """Finishes the action execution. If a finish hook is defined it safely executes it. Otherwise nothing happens""" hook = self._finish_hook if hook is None: return try: hook() except: self.warning("Exception running function finish hook", exc_info=1) def stop_action(self, *args, **kwargs): """Stop procedure for this action.""" self._stopped = True for pool_ctrl, elements in self._pool_ctrl_dict.items(): pool_ctrl.stop_elements(elements) def abort_action(self, *args, **kwargs): """Aborts procedure for this action""" self._aborted = True for pool_ctrl, elements in self._pool_ctrl_dict.items(): pool_ctrl.abort_elements(elements) def emergency_break(self): """Tries to execute a stop. If it fails try an abort""" self._stopped = True for pool_ctrl, elements in self._pool_ctrl_dict.items(): pool_ctrl.emergency_break(elements) def was_stopped(self): """Determines if the action has been stopped from outside :return: True if action has been stopped from outside or False otherwise :rtype: bool""" return self._stopped def was_aborted(self): """Determines if the action has been aborted from outside :return: True if action has been aborted from outside or False otherwise :rtype: bool""" return self._aborted def was_action_interrupted(self): """Determines if the action has been interruped from outside (either from an abort or a stop). :return: True if action has been interruped from outside or False otherwise :rtype: bool""" return self.was_aborted() or self.was_stopped() def _asynch_action_loop(self, context): """Internal method. Asynchronous action loop""" try: self.action_loop() finally: context.exit() self._running = False def action_loop(self): """Action loop for this action. Default implementation raises NotImplementedError :raises: NotImplementedError""" raise NotImplementedError("action_loop must be implemented in subclass") def read_state_info(self, ret=None, serial=False): """Reads state information of all elements involved in this action :param ret: output map parameter that should be filled with state information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW state requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing state information per element :rtype: dict""" with ActionContext(self): return self.raw_read_state_info(ret=ret, serial=serial) def raw_read_state_info(self, ret=None, serial=False): """**Unsafe**. Reads state information of all elements involved in this action :param ret: output map parameter that should be filled with state information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW state requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing state information per element :rtype: dict""" if ret is None: ret = {} read = self._raw_read_state_info_concurrent if serial: read = self._raw_read_state_info_serial state_info = self._state_info with state_info: state_info.init(len(self._pool_ctrl_dict)) read(ret) state_info.wait() return ret def _raw_read_state_info_serial(self, ret): """Internal method. Read state in a serial mode""" for pool_ctrl in self._pool_ctrl_dict: self._raw_read_ctrl_state_info(ret, pool_ctrl) return ret def _raw_read_state_info_concurrent(self, ret): """Internal method. Read state in a concurrent mode""" th_pool = get_thread_pool() for pool_ctrl in self._pool_ctrl_dict: th_pool.add(self._raw_read_ctrl_state_info, None, ret, pool_ctrl) return ret def _get_ctrl_error_state_info(self, pool_ctrl): """Internal method. Returns the controller error in form of a tuple""" exc_t, exc_v, trb = sys.exc_info() if exc_t is None: if pool_ctrl.is_online(): return State.Fault, "Unknown controller error" else: if pool_ctrl.is_online(): err_msg = "".join(traceback.format_exception(exc_t, exc_v, trb)) return State.Fault, "Unexpected controller error:\n" + err_msg return State.Fault, pool_ctrl.get_ctrl_error_str() def _raw_read_ctrl_state_info(self, ret, pool_ctrl): """Internal method. Read controller information and store it in ret parameter""" try: axes = [elem.axis for elem in self._pool_ctrl_dict[pool_ctrl]] state_infos, error = pool_ctrl.raw_read_axis_states(axes) if error: pool_ctrl.warning("Read state error") for elem, (state_info, exc_info) in state_infos.items(): if exc_info is not None: pool_ctrl.debug("Axis %s error details:", elem.axis, exc_info=exc_info) ret.update(state_infos) except: self.error("Something wrong happend: Error should have been caught" "by ctrl.read_axis_states") self.debug("Details: ", exc_info=1) state_info = self._get_ctrl_error_state_info(pool_ctrl) for elem in self._pool_ctrl_dict[pool_ctrl]: ret[elem] = state_info finally: self._state_info.finish_one() def get_read_value_ctrls(self): return self._pool_ctrl_dict def read_value(self, ret=None, serial=False): """Reads value information of all elements involved in this action :param ret: output map parameter that should be filled with value information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW value requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing value information per element :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement`, (value object, Exception or None)>""" with ActionContext(self): return self.raw_read_value(ret=ret, serial=serial) def raw_read_value(self, ret=None, serial=False): """**Unsafe**. Reads value information of all elements involved in this action :param ret: output map parameter that should be filled with value information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW value requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing value information per element :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement, :class:`sardana.sardanavalue.SardanaValue` >""" if ret is None: ret = {} read = self._raw_read_value_concurrent if serial: read = self._raw_read_value_serial value_info = self._value_info with value_info: value_info.init(len(self.get_read_value_ctrls())) read(ret) value_info.wait() return ret def _raw_read_value_serial(self, ret): """Internal method. Read value in a serial mode""" for pool_ctrl in self.get_read_value_ctrls(): self._raw_read_ctrl_value(ret, pool_ctrl) return ret def _raw_read_value_concurrent(self, ret): """Internal method. Read value in a concurrent mode""" th_pool = get_thread_pool() for pool_ctrl in self.get_read_value_ctrls(): th_pool.add(self._raw_read_ctrl_value, None, ret, pool_ctrl) return ret def _raw_read_ctrl_value(self, ret, pool_ctrl): """Internal method. Read controller value information and store it in ret parameter""" try: axes = [elem.axis for elem in self._pool_ctrl_dict[pool_ctrl]] value_infos = pool_ctrl.raw_read_axis_values(axes) ret.update(value_infos) finally: self._value_info.finish_one() def get_read_value_loop_ctrls(self): return self._pool_ctrl_dict def read_value_loop(self, ret=None, serial=False): """Reads value information of all elements involved in this action :param ret: output map parameter that should be filled with value information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW value requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing value information per element :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement`, (value object, Exception or None)>""" with ActionContext(self): return self.raw_read_value_loop(ret=ret, serial=serial) def raw_read_value_loop(self, ret=None, serial=False): """**Unsafe**. Reads value information of all elements involved in this action :param ret: output map parameter that should be filled with value information. If None is given (default), a new map is created an returned :type ret: dict :param serial: If False (default) perform controller HW value requests in parallel. If True, access is serialized. :type serial: bool :return: a map containing value information per element :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement, :class:`sardana.sardanavalue.SardanaValue` >""" if ret is None: ret = {} read = self._raw_read_value_concurrent_loop if serial: read = self._raw_read_value_serial_loop value_info = self._value_info with value_info: value_info.init(len(self.get_read_value_loop_ctrls())) read(ret) value_info.wait() return ret def _raw_read_value_serial_loop(self, ret): """Internal method. Read value in a serial mode""" for pool_ctrl in self.get_read_value_loop_ctrls(): self._raw_read_ctrl_value(ret, pool_ctrl) return ret def _raw_read_value_concurrent_loop(self, ret): """Internal method. Read value in a concurrent mode""" th_pool = get_thread_pool() for pool_ctrl in self.get_read_value_loop_ctrls(): th_pool.add(self._raw_read_ctrl_value, None, ret, pool_ctrl) return ret sardana-1.2.0/src/sardana/pool/poolbasechannel.py0000644000234100017500000001343512174204313023413 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for experiment channels""" __all__ = ["Value", "PoolBaseChannel"] __docformat__ = 'restructuredtext' from sardana.sardanaattribute import SardanaAttribute from .poolelement import PoolElement from .poolacquisition import PoolCTAcquisition class Value(SardanaAttribute): def __init__(self, *args, **kwargs): super(Value, self).__init__(*args, **kwargs) def update(self, cache=True, propagate=1): if not cache or not self.has_value(): value = self.obj.read_value() self.set_value(value, propagate=propagate) class PoolBaseChannel(PoolElement): ValueAttributeClass = Value AcquisitionClass = PoolCTAcquisition def __init__(self, **kwargs): PoolElement.__init__(self, **kwargs) self._value = self.ValueAttributeClass(self, listeners=self.on_change) if not self.AcquisitionClass is None: acq_name = "%s.Acquisition" % self._name self.set_action_cache(self.AcquisitionClass(self, name=acq_name)) def get_value_attribute(self): """Returns the value attribute object for this experiment channel :return: the value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._value # -------------------------------------------------------------------------- # Event forwarding # -------------------------------------------------------------------------- def on_change(self, evt_src, evt_type, evt_value): # forward all events coming from attributes to the listeners self.fire_event(evt_type, evt_value) # -------------------------------------------------------------------------- # default acquisition channel # -------------------------------------------------------------------------- def get_default_attribute(self): return self.get_value_attribute() # -------------------------------------------------------------------------- # acquisition # -------------------------------------------------------------------------- def get_acquisition(self): return self.get_action_cache() acquisition = property(get_acquisition, doc="acquisition object") # -------------------------------------------------------------------------- # value # -------------------------------------------------------------------------- def read_value(self): """Reads the channel value from hardware. :return: a :class:`~sardana.sardanavalue.SardanaValue` containing the channel value :rtype: :class:`~sardana.sardanavalue.SardanaValue`""" return self.acquisition.read_value()[self] def put_value(self, value, propagate=1): """Sets a value. :param value: the new value :type value: :class:`~sardana.sardanavalue.SardanaValue` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" val_attr = self._value val_attr.set_value(value, propagate=propagate) return val_attr def get_value(self, cache=True, propagate=1): """Returns the channel value. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the channel value :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._get_value(cache=cache, propagate=propagate) def _get_value(self, cache=True, propagate=1): value = self.get_value_attribute() value.update(cache=cache, propagate=propagate) return value def set_value(self, value): """Starts an acquisition on this channel :param value: the value to count :type value: :class:`~numbers.Number`""" return self._set_value(value) def _set_value(self, value): self.start_acquisition(value) value = property(get_value, set_value, doc="channel value") def start_acquisition(self, value=None): self._aborted = False self._stopped = False if value is None: value = self.get_write_value() if value is None: raise Exception("Invalid integration_time '%s'. Hint set a new value for 'value' first" % value) if not self._simulation_mode: acq = self.acquisition.run(integ_time=value) sardana-1.2.0/src/sardana/pool/poolbaseelement.py0000644000234100017500000004206012174204314023431 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = ["PoolBaseElement"] __docformat__ = 'restructuredtext' import weakref import threading from taurus.core.util.lock import TaurusLock from sardana import State from sardana.sardanaevent import EventType from .poolobject import PoolObject class PoolBaseElement(PoolObject): """A Pool object that besides the name, reference to the pool, ID, full_name and user_full_name has: - _simulation_mode : boolean telling if in simulation mode - _state : element state - _status : element status""" def __init__(self, **kwargs): self._simulation_mode = False self._state = None self._state_event = None self._status = None self._status_event = None self._action_cache = None self._aborted = False self._stopped = False lock_name = kwargs['name'] + "Lock" # A lock for high level operations: monitoring, motion or acquisition self._lock = TaurusLock(name=lock_name, lock=threading.RLock()) # The operation context in which the element is involved self._operation = None # The :class:`PoolAction` in which element is involved self._pool_action = None super(PoolBaseElement, self).__init__(**kwargs) def __enter__(self): self.lock() def __exit__(self, exc_type, exc_value, traceback): self.unlock() return False def lock(self, blocking=True): """Acquires the this element lock :param blocking: whether or not to block if lock is already acquired [default: True] :type blocking: bool""" ret = self._lock.acquire(blocking) return ret def unlock(self): ret = self._lock.release() return ret def get_action_cache(self): """Returns the internal action cache object""" return self._action_cache def serialize(self, *args, **kwargs): ret = PoolObject.serialize(self, *args, **kwargs) return ret # -------------------------------------------------------------------------- # simulation mode # -------------------------------------------------------------------------- def get_simulation_mode(self, cache=True, propagate=1): """Returns the simulation mode for this object. :param cache: not used [default: True] :type cache: bool :param propagate: [default: 1] :type propagate: int :return: the current simulation mode :rtype: bool""" return self._simulation_mode def set_simulation_mode(self, simulation_mode, propagate=1): self._simulation_mode = simulation_mode if not propagate: return if simulation_mode == self._simulation_mode: # current state is equal to last state_event. Skip event return self.fire_event(EventType("simulation_mode", priority=propagate), simulation_mode) def put_simulation_mode(self, simulation_mode): self._simulation_mode = simulation_mode simulation_mode = property(get_simulation_mode, set_simulation_mode, doc="element simulation mode") # -------------------------------------------------------------------------- # state # -------------------------------------------------------------------------- def get_state(self, cache=True, propagate=1): """Returns the state for this object. If cache is True (default) it returns the current state stored in cache (it will force an update if cache is empty). If propagate > 0 and if the state changed since last read, it will propagate the state event to all listeners. :param cache: tells if return value from local cache or update from HW read [default: True] :type cache: bool :param propagate: if > 0 propagates the event in case it changed since last HW read. Values bigger that mean the event if sent should be a priority event [default: 1] :type propagate: int :return: the current object state :rtype: :obj:`sardana.State`""" if not cache or self._state is None: state_info = self.read_state_info() self._set_state_info(state_info, propagate=propagate) return self._state def inspect_state(self): """Looks at the current cached value of state :return: the current object state :rtype: :obj:`sardana.State`""" return self._state def set_state(self, state, propagate=1): self._set_state(state, propagate=propagate) def _set_state(self, state, propagate=1): self._state = state if not propagate: return if state == self._state_event: # current state is equal to last state_event. Skip event return self._state_event = state self.fire_event(EventType("state", priority=propagate), state) def put_state(self, state): self._state = state state = property(get_state, set_state, doc="element state") # -------------------------------------------------------------------------- # status # -------------------------------------------------------------------------- def inspect_status(self): """Looks at the current cached value of status :return: the current object status :rtype: str""" return self._status def get_status(self, cache=True, propagate=1): """Returns the status for this object. If cache is True (default) it returns the current status stored in cache (it will force an update if cache is empty). If propagate > 0 and if the status changed since last read, it will propagate the status event to all listeners. :param cache: tells if return value from local cache or update from HW read [default: True] :type cache: bool :param propagate: if > 0 propagates the event in case it changed since last HW read. Values bigger that mean the event if sent should be a priority event [default: 1] :type propagate: int :return: the current object status :rtype: str""" if not cache or self._status is None: state_info = self.read_state_info() self._set_state_info(state_info, propagate=propagate) return self._status def set_status(self, status, propagate=1): self._set_status(status, propagate=propagate) def _set_status(self, status, propagate=1): self._status = status if not propagate: return s_evt = self._status_event if s_evt is not None and len(status) == len(s_evt) and status == s_evt: # current status is equal to last status_event. Skip event return self._status_event = status self.fire_event(EventType("status", priority=propagate), status) def put_status(self, status): self._status = status status = property(get_status, set_status, doc="element status") # -------------------------------------------------------------------------- # state information # -------------------------------------------------------------------------- _STD_STATUS = "{name} is {state}\n{ctrl_status}" def calculate_state_info(self, status_info=None): """Transforms the given state information. This specific base implementation transforms the given state,status tuple into a state, new_status tuple where new_status is "*self.name* is *state* plus the given status. It is assumed that the given status comes directly from the controller status information. :param status_info: given status information [default: None, meaning use current state status. :type status_info: tuple :return: a transformed state information :rtype: tuple""" if status_info is None: status_info = self._state, self._status state, status = status_info state_str = State[state] new_status = self._STD_STATUS.format(name=self.name, state=state_str, ctrl_status=status) return status_info[0], new_status def set_state_info(self, state_info, propagate=1): self._set_state_info(state_info, propagate=propagate) def _set_state_info(self, state_info, propagate=1): state_info = self.calculate_state_info(state_info) state, status = state_info[:2] self._set_status(status, propagate=propagate) self._set_state(state, propagate=propagate) def read_state_info(self): action_cache = self.get_action_cache() ctrl_state_info = action_cache.read_state_info(serial=True)[self] return self._from_ctrl_state_info(ctrl_state_info) def put_state_info(self, state_info): self.set_state_info(state_info, propagate=0) def _from_ctrl_state_info(self, state_info): try: state_str = State.whatis(state_info) return int(state_info), "{0} is in {1}".format(self.name, state_str) except KeyError: pass state_info, _ = state_info state, status = state_info[:2] state = int(state) return state, status # -------------------------------------------------------------------------- # default attribute # -------------------------------------------------------------------------- def get_default_attribute(self): return NotImplementedError("%s doesn't have default attribute" % self.__class__.__name__) # -------------------------------------------------------------------------- # default acquisition channel name # -------------------------------------------------------------------------- def get_default_acquisition_channel(self): return self.get_default_attribute().name # -------------------------------------------------------------------------- # stop # -------------------------------------------------------------------------- def stop(self): self._stopped = True def was_stopped(self): return self._stopped # -------------------------------------------------------------------------- # abort # -------------------------------------------------------------------------- def abort(self): self._aborted = True def was_aborted(self): return self._aborted # -------------------------------------------------------------------------- # interrupted # -------------------------------------------------------------------------- def was_interrupted(self): """Tells if action ended by an abort or stop""" return self.was_aborted() or self.was_stopped() # -------------------------------------------------------------------------- # involved in an operation # -------------------------------------------------------------------------- def is_action_running(self): """Determines if the element action is running or not.""" return self.get_action_cache().is_running() def is_in_operation(self): """Returns True if this element is involved in any operation""" return self.get_operation() is not None def is_in_local_operation(self): return self.get_operation() == self.get_action_cache() def get_operation(self): return self._operation def set_operation(self, operation): if self.is_in_operation() and operation is not None: raise Exception("%s is already involved in an operation" % self.name) if operation is not None: self._aborted = False self._stopped = False self._operation = operation def clear_operation(self): return self.set_operation(None) class PoolElement(PoolBaseElement): """A Pool element is an Pool object which is controlled by a controller. Therefore it contains a _ctrl_id and a _axis (the id of the element in the controller).""" def __init__(self, **kwargs): ctrl = kwargs.pop('ctrl') self._ctrl = weakref.ref(ctrl) self._axis = kwargs.pop('axis') self._ctrl_id = ctrl.get_id() try: instrument = kwargs.pop('instrument') self.set_instrument(instrument) except KeyError: self._instrument = None super(PoolElement, self).__init__(**kwargs) def serialize(self, *args, **kwargs): kwargs = PoolBaseElement.serialize(self, *args, **kwargs) kwargs['controller'] = self.controller.full_name kwargs['unit'] = '0' #TODO: hardcoded unit to 0 kwargs['axis'] = self.axis if self.instrument is not None: kwargs['instrument'] = self.instrument.full_name else: kwargs['instrument'] = None kwargs['source'] = self.get_source() return kwargs def get_parent(self): return self.get_controller() def get_controller(self): if self._ctrl is None: return None return self._ctrl() def get_controller_id(self): return self._ctrl_id def get_axis(self): return self._axis def set_action_cache(self, action_cache): self._action_cache = action_cache action_cache.add_element(self) def get_source(self): return "{0}/{1}".format(self.full_name, self.get_default_acquisition_channel()) # -------------------------------------------------------------------------- # instrument # -------------------------------------------------------------------------- def get_instrument(self): if self._instrument is None: return None return self._instrument() def set_instrument(self, instrument, propagate=1): self._set_instrument(instrument, propagate=propagate) def _set_instrument(self, instrument, propagate=1): if self._instrument is not None: self._instrument().remove_element(self) new_instrument_name = "" if instrument is None: self._instrument = None else: self._instrument = weakref.ref(instrument) new_instrument_name = instrument.full_name instrument.add_element(self) if not propagate: return self.fire_event(EventType("instrument", priority=propagate), new_instrument_name) # -------------------------------------------------------------------------- # stop # -------------------------------------------------------------------------- def stop(self): self.info("Stop!") PoolBaseElement.stop(self) self.controller.stop_one(self.axis) # -------------------------------------------------------------------------- # abort # -------------------------------------------------------------------------- def abort(self): self.info("Abort!") PoolBaseElement.abort(self) self.controller.abort_one(self.axis) def get_par(self, name): return self.controller.get_axis_par(self.axis, name) def set_par(self, name, value): return self.controller.set_axis_par(self.axis, name, value) def get_extra_par(self, name): return self.controller.get_axis_attr(self.axis, name) def set_extra_par(self, name, value): return self.controller.set_axis_attr(self.axis, name, value) axis = property(get_axis, doc="element axis") controller = property(get_controller, doc="element controller") controller_id = property(get_controller_id, doc="element controller id") instrument = property(get_instrument, set_instrument, doc="element instrument") sardana-1.2.0/src/sardana/pool/poolbasegroup.py0000644000234100017500000003616712174204314023147 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = [ "PoolBaseGroup"] __docformat__ = 'restructuredtext' from taurus.core.taurusvalidator import AttributeNameValidator from sardana import State, ElementType, TYPE_PHYSICAL_ELEMENTS from poolexternal import PoolExternalObject from poolcontainer import PoolContainer class PoolBaseGroup(PoolContainer): def __init__(self, **kwargs): self._pending = True self._user_element_ids = None self._user_elements = None self._physical_elements = None self._physical_elements_set = None self._state_statistics = {} self._pool = kwargs.pop('pool') self.set_user_element_ids(kwargs.pop('user_elements')) PoolContainer.__init__(self) try: self._build_elements() except KeyError: self.info("failed to build element information. No problem. " \ "Probably one or more underlying elements have not " \ "been constructed yet") def _get_pool(self): return self._pool def _create_action_cache(self): raise NotImplementedError def _get_action_cache(self): if self._action_cache is None: self._action_cache = self._fill_action_cache() return self._action_cache def _set_action_cache(self, action_cache): physical_elements = self.get_physical_elements() if self._action_cache is not None: for ctrl_physical_elements in physical_elements.values(): for physical_element in ctrl_physical_elements: action_cache.remove_element(physical_element) self._action_cache = self._fill_action_cache(action_cache) def _fill_action_cache(self, action_cache=None, physical_elements=None): if action_cache is None: action_cache = self._create_action_cache() if physical_elements is None: physical_elements = self.get_physical_elements() for _, ctrl_physical_elements in physical_elements.items(): for physical_element in ctrl_physical_elements: action_cache.add_element(physical_element) return action_cache def _calculate_element_state(self, elem, elem_state_info): u_state, u_status = elem_state_info if u_status is None: u_status = '%s is None' % elem.name else: u_status = u_status.split("\n", 1)[0] return u_state, u_status def _calculate_states(self, state_info=None): user_elements = self.get_user_elements() none, unknown = set(), set() fault, alarm, on, moving = set(), set(), set(), set() status = [] if state_info is None: state_info = {} for elem in user_elements: if elem.get_type() == ElementType.External: continue # cannot call get_state(us) here since it may lead to dead lock! si = elem.inspect_state(), elem.inspect_status() state_info[elem] = si for elem, elem_state_info in state_info.items(): elem_type = elem.get_type() if elem_type == ElementType.External: continue u_state, u_status = self._calculate_element_state(elem, elem_state_info) if u_state == State.Moving: moving.add(elem) elif u_state == State.On: on.add(elem) elif u_state == State.Fault: fault.add(elem) elif u_state == State.Alarm: alarm.add(elem) elif u_state is State.Unknown: unknown.add(elem) elif u_state is None: none.add(elem) status.append(u_status) state = State.On if none or unknown: state = State.Unknown if fault: state = State.Fault elif alarm: state = State.Alarm elif moving: state = State.Moving self._state_statistics = { State.On : on, State.Fault : fault, State.Alarm : alarm, State.Moving : moving, State.Unknown : unknown, None : none } status = "\n".join(status) return state, status def _is_managed_element(self, element): return True def _build_elements(self): self._user_elements = [] self._physical_elements = {} self._physical_elements_set = set() pool = self._get_pool() for user_element_id in self._user_element_ids: # an internal element internal = type(user_element_id) is int if internal: try: user_element = pool.get_element(id=user_element_id) except KeyError: self._pending = True self._user_elements = None self._physical_elements = None self._physical_elements_set = None raise internal = self._is_managed_element(user_element) if not internal: user_element_id = user_element.get_source() # a tango channel or non internal element (ex: ioregister or motor # in measurement group) if not internal: validator = AttributeNameValidator() params = validator.getParams(user_element_id) params['pool'] = self._get_pool() user_element = PoolExternalObject(**params) self.add_user_element(user_element) self._pending = False def on_element_changed(self, evt_src, evt_type, evt_value): pass def set_user_element_ids(self, new_element_ids): self.clear_user_elements() self._user_element_ids = new_element_ids def get_user_element_ids(self): """Returns the sequence of user element IDs :return: the sequence of user element IDs :rtype: sequence< :obj:`int`>""" return self._user_element_ids user_element_ids = property(get_user_element_ids) def get_user_elements(self): """Returns the sequence of user elements :return: the sequence of user elements :rtype: sequence< :class:`~sardana.pool.poolelement.PoolElement`>""" if self._pending: self._build_elements() return self._user_elements def get_user_elements_attribute_iterator(self): """Returns an iterator over the main attribute of each user element. :return: an iterator over the main attribute of each user element. :rtype: iter< :class:`~sardana.sardanaattribute.SardanaAttribute` >""" for element in self.get_user_elements(): yield element.get_default_attribute() get_user_elements_attribute = get_user_elements_attribute_iterator get_user_elements_attribute.__doc__ = get_user_elements_attribute_iterator.__doc__ def get_user_elements_attribute_sequence(self): """Returns a sequence of main attribute of each user element. In loops use preferably :meth:`get_user_elements_attribute_iterator` for performance and memory reasons. :return: a sequence of main attribute of each user element. :rtype: sequence< :class:`~sardana.sardanaattribute.SardanaAttribute` >""" return list(self.get_user_elements_attribute_iterator()) def get_user_elements_attribute_map(self): """Returns a dictionary of main attribute of each user element. :return: a dictionary of main attribute of each user element. :rtype: dict< :class:`~sardana.pool.poolelement.PoolElement`, :class:`~sardana.sardanaattribute.SardanaAttribute` >""" ret = {} for element in self.get_user_elements(): ret[element] = element.get_default_attribute() return ret def get_physical_elements(self): """Returns a dictionary or physical elements where key is a controller object and value is a sequence of pool elements :return: a dictionary of physical elements :rtype: dict< :class:`~sardana.pool.poolcontroller.PoolController, sequence<:class:`~sardana.pool.poolelement.PoolElement`>""" if self._pending: self._build_elements() return self._physical_elements def get_physical_elements_iterator(self): """Returns an iterator over the physical elements. .. warning:: The order is non deterministic. :return: an iterator over the physical elements. :rtype: iter<:class:`~sardana.pool.poolelement.PoolElement` >""" for _, elements in self.get_physical_elements().items(): for element in elements: yield element def get_physical_elements_attribute_iterator(self): """Returns an iterator over the main attribute of each physical element. .. warning:: The order is non deterministic. :return: an iterator over the main attribute of each physical element. :rtype: iter< :class:`~sardana.sardanaattribute.SardanaAttribute` >""" for element in self.get_physical_elements_iterator(): yield element.get_default_attribute() def get_physical_elements_set(self): if self._pending: self._build_elements() return self._physical_elements_set def add_user_element(self, element, index=None): user_elements = self._user_elements physical_elements = self._physical_elements physical_elements_set = self._physical_elements_set if element in user_elements: raise Exception("Group already contains %s" % element.name) if index is None: index = len(user_elements) user_elements.insert(index, element) if not self._is_managed_element(element): return index self.add_element(element) self._find_physical_elements(element, physical_elements=physical_elements, physical_elements_set=physical_elements_set) action_cache = self._action_cache if action_cache is not None: self._fill_action_cache(action_cache=action_cache, physical_elements=physical_elements) element.add_listener(self.on_element_changed) return index def _find_physical_elements(self, element, physical_elements=None, physical_elements_set=None): elem_type = element.get_type() if physical_elements is None: physical_elements = {} if physical_elements_set is None: physical_elements_set = set() if elem_type in TYPE_PHYSICAL_ELEMENTS: ctrl = element.controller own_elements = physical_elements.get(ctrl) if own_elements is None: physical_elements[ctrl] = own_elements = set() own_elements.add(element) physical_elements_set.add(element) else: for ctrl, elements in element.get_physical_elements().items(): own_elements = physical_elements.get(ctrl) if own_elements is None: physical_elements[ctrl] = own_elements = set() own_elements.update(elements) physical_elements_set.update(elements) return physical_elements # TODO: too complicated to implement for now # def remove_user_element(self, element): # try: # idx = self._user_elements.index(element) # except ValueError: # raise Exception("Group doesn't contain %s" % element.name) # action_cache = self.get_action_cache() # element.remove_listener(self.on_element_changed) # action_cache.remove_element(element) # del self._user_elements[idx] # del self._user_element_ids[self._user_element_ids.index(element.id)] # self.remove_element(element) def clear_user_elements(self): user_elements = self._user_elements if user_elements is not None: for element in user_elements: if element.get_type() != ElementType.External: element.remove_listener(self.on_element_changed) self.remove_element(element) self._action_cache = None self._pending = True self._user_elements = None self._user_element_ids = None self._physical_elements = None # -------------------------------------------------------------------------- # stop # -------------------------------------------------------------------------- def stop(self): for ctrl, elements in self.get_physical_elements().items(): self.debug("Stopping %s %s", ctrl.name, [e.name for e in elements]) try: ctrl.stop_elements(elements=elements) except: self.error("Unable to stop controller %s", ctrl.name) self.debug("Details:", exc_info=1) # -------------------------------------------------------------------------- # abort # -------------------------------------------------------------------------- def abort(self): for ctrl, elements in self.get_physical_elements().items(): self.debug("Aborting %s %s", ctrl.name, [e.name for e in elements]) try: ctrl.abort_elements(elements=elements) except: self.error("Unable to abort controller %s", ctrl.name) self.debug("Details:", exc_info=1) # -------------------------------------------------------------------------- # involved in an operation # -------------------------------------------------------------------------- def get_operation(self): for _, elements in self.get_physical_elements().items(): for element in elements: op = element.get_operation() if op is not None: return op return None sardana-1.2.0/src/sardana/pool/poolbaseobject.py0000644000234100017500000000374712174204314023257 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for Pool object""" __all__ = ["PoolBaseObject"] __docformat__ = 'restructuredtext' from sardana.sardanabase import SardanaBaseObject class PoolBaseObject(SardanaBaseObject): """The Pool most abstract object.""" def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('pool') SardanaBaseObject.__init__(self, **kwargs) def get_pool(self): """Return the :class:`sardana.pool.pool.Pool` which *owns* this pool object. :return: the pool which *owns* this pool object. :rtype: :class:`sardana.pool.pool.Pool`""" return self.get_manager() def serialize(self, *args, **kwargs): kwargs = SardanaBaseObject.serialize(self, *args, **kwargs) kwargs['pool'] = self.pool.name return kwargs pool = property(get_pool, doc="reference to the :class:`sardana.pool.pool.Pool`") sardana-1.2.0/src/sardana/pool/poolcontainer.py0000644000234100017500000000342112174204314023125 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for a pool container element""" __all__ = ["PoolContainer"] __docformat__ = 'restructuredtext' from sardana.sardanacontainer import SardanaContainer class PoolContainer(SardanaContainer): """A container class for pool elements""" def get_controller_class(self, **kwargs): eid = kwargs.get("id") if eid is not None: return self.get_controller_class_by_id(eid, **kwargs) name = kwargs.pop("name") self.get_controller_class_by_name(name, **kwargs) def get_controller_class_by_id(self, eid, **kwargs): raise NotImplementedError def get_controller_class_by_name(self, name, **kwargs): raise NotImplementedErrorsardana-1.2.0/src/sardana/pool/poolcontroller.py0000644000234100017500000007541212174204314023337 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = ["PoolController", "PoolPseudoMotorController", "PoolPseudoCounterController"] __docformat__ = 'restructuredtext' import sys import weakref import StringIO import traceback import functools from taurus.core.util import CaselessDict from sardana import State, ElementType, TYPE_TIMERABLE_ELEMENTS from sardana.sardanaevent import EventType from sardana.sardanavalue import SardanaValue from .poolextension import translate_ctrl_value from .poolbaseelement import PoolBaseElement class PoolBaseController(PoolBaseElement): """Base class for all controllers""" def __init__(self, **kwargs): self._ctrl = None self._ctrl_error = None self._element_ids = {} self._pending_element_ids = {} self._element_axis = {} self._pending_element_axis = {} self._element_names = CaselessDict() self._pending_element_names = CaselessDict() self._operator = None kwargs['elem_type'] = ElementType.Controller super(PoolBaseController, self).__init__(**kwargs) def get_ctrl_types(self): raise NotImplementedError def get_ctrl_type_names(self): return map(ElementType.whatis, self.get_ctrl_types()) def is_online(self): return True def get_ctrl_error(self): return self._ctrl_error def get_ctrl_error_str(self): """""" err = self._ctrl_error if err is None: return "" sio = StringIO.StringIO() traceback.print_exception(err[0], err[1], err[2], None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def add_element(self, elem, propagate=1): name, axis, eid = elem.get_name(), elem.get_axis(), elem.get_id() if self.is_online(): try: self._ctrl.AddDevice(axis) except: self.error("Unable to add %s(%s)", name, axis, exc_info=1) self._pending_element_ids[eid] = elem self._pending_element_axis[axis] = elem self._pending_element_names[name] = elem self._element_ids[eid] = elem self._element_axis[axis] = elem self._element_names[name] = elem else: #TODO: raise exception self._pending_element_ids[eid] = elem self._pending_element_axis[axis] = elem self._pending_element_names[name] = elem if propagate: elements = self.get_elements() elements = [ elements[_id].name for _id in sorted(elements) ] self.fire_event(EventType("elementlist", priority=propagate), elements) def remove_element(self, elem, propagate=1): name, axis, eid = elem.get_name(), elem.get_axis(), elem.get_id() f = self._element_ids.has_key(eid) if not f: f = self._pending_element_ids.has_key(eid) if not f: raise Exception("element '%s' is not in controller") del self._pending_element_ids[eid] del self._pending_element_axis[axis] del self._pending_element_names[name] else: del self._element_ids[eid] del self._element_axis[axis] del self._element_names[name] try: self._ctrl.DeleteDevice(axis) except: self.error("Unable to delete %s(%s)", name, axis, exc_info=1) if propagate: elements = self.get_elements() elements = [ elements[_id].name for _id in sorted(elements) ] self.fire_event(EventType("elementlist", priority=propagate), elements) def remove_axis(self, axis, propagate=1): f = self._element_axis.has_key(axis) if not f: f = self._pending_element_axis.has_key(axis) if not f: raise Exception("element '%s' is not in controller") elem = self._pending_element_axis[axis] else: elem = self._element_axis[axis] self.remove_element(elem, propagate=propagate) def get_elements(self): return self._element_ids def get_element_ids(self): return self._element_ids def get_element_axis(self): return self._element_axis def get_element(self, **kwargs): k = kwargs.get('axis') if k is None: k = kwargs.get('name') if k is None: k = kwargs.get('id') if k is None: raise Exception("Must give either name, id or axis") d, pd = self._element_ids, self._pending_element_ids else: d, pd = self._element_names, self._pending_element_names else: d, pd = self._element_axis, self._pending_element_axis elem = d.get(k) if elem is None: elem = pd.get(k) return elem def read_axis_states(self, axes=None): """Reads the state for the given axes. If axes is None, reads the state of all active axes. :param axes: the list of axis to get the state. Default is None meaning all active axis in this controller :type axes: seq or None :return: a map containing the controller state information for each axis :rtype: dict """ raise NotImplementedError def read_axis_values(self, axes=None): """Reads the value for the given axes. If axes is None, reads the value of all active axes. :param axes: the list of axis to get the value. Default is None meaning all active axis in this controller :type axes: seq or None :return: a map containing the controller value information for each axis :rtype: dict """ raise NotImplementedError def check_ctrl(fn): @functools.wraps(fn) def wrapper(pool_ctrl, *args, **kwargs): if not pool_ctrl.is_online(): raise Exception("Cannot execute '%s' because '%s' is offline" % \ (fn.__name__, pool_ctrl.name)) return fn(pool_ctrl, *args, **kwargs) return wrapper def ctrl_access(fn): @functools.wraps(fn) def wrapper(pool_ctrl, *args, **kwargs): with pool_ctrl: return fn(pool_ctrl, *args, **kwargs) return wrapper class PoolController(PoolBaseController): """Controller class mediator for sardana controller plugins""" def __init__(self, **kwargs): self._lib_info = kwargs.pop('lib_info') self._ctrl_info = kwargs.pop('class_info') self._lib_name = kwargs.pop('library') self._class_name = kwargs.pop('klass') self._properties = kwargs.pop('properties') super(PoolController, self).__init__(**kwargs) self.re_init() def serialize(self, *args, **kwargs): kwargs = PoolBaseController.serialize(self, *args, **kwargs) ctrl_info = self._ctrl_info if ctrl_info is None: kwargs['module'] = self._lib_name kwargs['klass'] = self._class_name kwargs['language'] = 'Python' kwargs['file_name'] = None kwargs['types'] = None kwargs['main_type'] = None kwargs['parent'] = self._class_name else: types = self.get_ctrl_type_names() kwargs['module'] = ctrl_info.module_name kwargs['klass'] = ctrl_info.name kwargs['language'] = 'Python' kwargs['file_name'] = ctrl_info.file_name kwargs['types'] = types kwargs['parent'] = ctrl_info.name if len(types): kwargs['main_type'] = types[0] else: kwargs['main_type'] = None return kwargs def _create_ctrl_args(self): name = self.name klass = self._ctrl_info.klass props = dict(self._properties) args, kwargs = [], dict(pool_controller=weakref.ref(self)) return name, klass, props, args, kwargs def _create_controller(self): name, klass, props, args, kwargs = self._create_ctrl_args() api = self._ctrl_info.api_version if api == 0: ctrl = klass(name, props) ctrl._args = args ctrl._kwargs = kwargs elif api == 1: ctrl = klass(name, props, *args, **kwargs) return ctrl def _init(self): if self._ctrl_info is None: if self._lib_info is not None: self._ctrl_error = self._lib_info.get_error() return try: self._ctrl = self._create_controller() except: self._ctrl = None self._ctrl_error = sys.exc_info() def re_init(self): self.set_state(State.Init, propagate=2) status = "{0} is Initializing (temporarily unavailable)".format(self.name) self.set_status(status, propagate=2) manager = self.pool.ctrl_manager old_e_ids = self._element_ids old_p_e_ids = self._pending_element_ids elem_axis = dict(self._element_axis) for axis in elem_axis: self.remove_axis(axis, propagate=0) if self._lib_info is None: mod_name = self.get_library_name() else: mod_name = self._lib_info.name if self._ctrl_info is None: class_name = self.get_class_name() else: class_name = self._ctrl_info.name self._ctrl_error = None self._ctrl_info = None self._lib_info = manager.getControllerLib(mod_name) if self._lib_info is not None: self._ctrl_info = self._lib_info.get_controller(class_name) self._init() for elem in elem_axis.values(): self.add_element(elem, propagate=0) state, status = State.Fault, "" if self.is_online(): state = State.On else: status = "\n" + self.get_ctrl_error_str() status = "{0} is {1}".format(self.name, State[state]) + status self.set_status(status, propagate=2) self.set_state(state, propagate=2) def get_ctrl_types(self): return self._ctrl_info.types def is_timerable(self): for t in self._ctrl_info.types: if t in TYPE_TIMERABLE_ELEMENTS: return True return False def is_online(self): return self._ctrl_error is None and self._ctrl is not None def get_ctrl(self): return self._ctrl ctrl = property(fget=get_ctrl, doc="actual controller object") def get_ctrl_info(self): return self._ctrl_info ctrl_info = property(fget=get_ctrl_info, doc="controller information object") def set_operator(self, operator): """Defines the current operator object for this controller. For example, in acquisition, it should be a :class:`PoolMeasurementGroup` object. :param operator: the new operator object :type operator: object""" self._operator = operator def get_operator(self): return self._operator operator = property(fget=get_operator, fset=set_operator, doc="current controller operator") # START API WHICH ACCESSES CONTROLLER API ---------------------------------- @check_ctrl def set_log_level(self, level): self.ctrl._log.log_obj.setLevel(level) @check_ctrl def get_log_level(self): return self.ctrl._log.log_obj.level def get_library_name(self): return self._lib_name def get_class_name(self): return self._class_name @check_ctrl def get_axis_attributes(self, axis): return self.ctrl.GetAxisAttributes(axis) @check_ctrl def get_ctrl_attr(self, name): ctrl_info = self.ctrl_info attr_info = ctrl_info.ctrl_attributes[name] if hasattr(self.ctrl, attr_info.fget): return getattr(self.ctrl, attr_info.fget)() else: return self.ctrl.GetCtrlPar(name) @check_ctrl def set_ctrl_attr(self, name, value): ctrl_info = self.ctrl_info attr_info = ctrl_info.ctrl_attributes[name] if hasattr(self.ctrl, attr_info.fset): return getattr(self.ctrl, attr_info.fset)(value) else: return self.ctrl.SetCtrlPar(name, value) @check_ctrl def get_axis_attr(self, axis, name): ctrl_info = self.ctrl_info axis_attr_info = ctrl_info.axis_attributes[name] if hasattr(self.ctrl, axis_attr_info.fget): ret = getattr(self.ctrl, axis_attr_info.fget)(axis) else: ret = self.ctrl.GetAxisExtraPar(axis, name) return ret @check_ctrl def set_axis_attr(self, axis, name, value): ctrl_info = self.ctrl_info axis_attr_info = ctrl_info.axis_attributes[name] try: return getattr(self.ctrl, axis_attr_info.fset)(axis, value) except AttributeError: return self.ctrl.SetAxisExtraPar(axis, name, value) @check_ctrl def set_ctrl_par(self, name, value): #return self.ctrl.setCtrlPar(unit, name, value) return self.ctrl.SetCtrlPar(name, value) @check_ctrl def get_ctrl_par(self, name): #return self.ctrl.getCtrlPar(unit, name, value) return self.ctrl.GetCtrlPar(name) @check_ctrl def set_axis_par(self, axis, name, value): #return self.ctrl.SetAxisPar(unit, axis, name, value) return self.ctrl.SetAxisPar(axis, name, value) @check_ctrl def get_axis_par(self, axis, name): #return self.ctrl.GetAxisPar(unit, axis, name, value) return self.ctrl.GetAxisPar(axis, name) # END API WHICH ACCESSES CONTROLLER API ------------------------------------ # START API WHICH ACCESSES CRITICAL CONTROLLER API (like StateOne) --------- def __build_exc_info(self, ctrl_states, axes, exc_info): status = "".join(traceback.format_exception(*exc_info)) state_info = State.Fault, status for axis in axes: element = self.get_element(axis=axis) ctrl_states[element] = state_info @staticmethod def _format_exception(exc_info): fmt_exc = traceback.format_exception_only(*exc_info[:2]) fmt_exc = "".join(fmt_exc) if fmt_exc.endswith("\n"): fmt_exc = fmt_exc[:-1] return fmt_exc def raw_read_axis_states(self, axes=None, ctrl_states=None): """**Unsafe method**. Reads the state for the given axes. If axes is None, reads the state of all active axes. :param axes: the list of axis to get the state. Default is None meaning all active axis in this controller :type axes: seq or None :return: a tuple of two elements: a map containing the controller state information for each axis and a boolean telling if an error occured :rtype: dict, bool""" if axes is None: axes = self._element_axis.keys() if ctrl_states is None: ctrl_states = {} ctrl = self.ctrl try: ctrl.PreStateAll() for axis in axes: ctrl.PreStateOne(axis) ctrl.StateAll() except: exc_info = sys.exc_info() status = self._format_exception(exc_info) state_info = (State.Fault, status), exc_info for axis in axes: element = self.get_element(axis=axis) ctrl_states[element] = state_info return ctrl_states, True error = False for axis in axes: element = self.get_element(axis=axis) try: state_info = ctrl.StateOne(axis) if state_info is None: raise Exception("%s.StateOne(%s(%d)) returns 'None'" % (self.name, element.name, axis)) state_info = state_info, None except: exc_info = sys.exc_info() status = self._format_exception(exc_info) state_info = (State.Fault, status), exc_info error = True ctrl_states[element] = state_info return ctrl_states, error @check_ctrl def read_axis_states(self, axes=None): """Reads the state for the given axes. If axes is None, reads the state of all active axes. :param axes: the list of axis to get the state. Default is None meaning all active axis in this controller :type axes: seq or None :return: a map containing the controller state information for each axis :rtype: dict""" return self.raw_read_axis_states(axes=axes) def _read_axis_value(self, element): try: axis = element.get_axis() ctrl_value = self.ctrl.ReadOne(axis) if ctrl_value is None: msg = '%s.ReadOne(%s[%d]) return error: Expected value, ' \ 'got None instead' % (self.name, element.name, axis) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value def raw_read_axis_values(self, axes=None, ctrl_values=None): """**Unsafe method**. Reads the value for the given axes. If axes is None, reads the value of all active axes. :param axes: the list of axis to get the value. Default is None meaning all active axis in this controller :type axes: seq or None :return: a map containing the controller value information for each axis :rtype: dict""" if axes is None: axes = self._element_axis.keys() if ctrl_values is None: ctrl_values = {} ctrl = self.ctrl try: ctrl.PreReadAll() for axis in axes: ctrl.PreReadOne(axis) ctrl.ReadAll() except: exc_info = sys.exc_info() for axis in axes: element = self.get_element(axis=axis) ctrl_values[element] = None, exc_info return ctrl_values for axis in axes: element = self.get_element(axis=axis) ctrl_values[element] = self._read_axis_value(element) return ctrl_values @check_ctrl def read_axis_values(self, axes=None): """Reads the value for the given axes. If axes is None, reads the value of all active axes. :param axes: the list of axis to get the value. Default is None meaning all active axis in this controller :type axes: seq or None :return: a map containing the controller value information for each axis :rtype: dict""" return self.raw_read_axis_values(axes=axes) def raw_stop_all(self): try: return self._raw_stop_all() except: pass def raw_stop_one(self, axis): try: self._raw_stop_one(axis) except: pass def _raw_stop_all(self): try: return self.ctrl.StopAll() except: self.warning("StopAll() raises exception") self.debug("Details:", exc_info=1) raise def _raw_stop_one(self, axis): try: self.ctrl.StopOne(axis) except: self.warning("StopOne(%d) raises exception", axis) self.debug("Details:", exc_info=1) raise @check_ctrl def stop_all(self): self.raw_stop_all() stop = stop_all @check_ctrl def stop_one(self, axis): return self.raw_stop_one(axis) @check_ctrl def stop_axes(self, axes=None): """Stops the given axes. If axes is None, stops all active axes. :param axes: the list of axis to stop. Default is None meaning all active axis in this controller :type axes: seq or None """ if axes is None: return self.raw_stop_all() for axis in axes: self.raw_stop_one(axis) @check_ctrl def stop_elements(self, elements=None): """Stops the given elements. If axes is None, stops all active axes. :param elements: the list of elements to stop. Default is None meaning all active axis in this controller :type axes: seq or None """ if elements is None: return self.raw_stop_all() for element in elements: self.raw_stop_one(element.axis) def raw_abort_all(self): try: return self._raw_abort_all() except: pass def raw_abort_one(self, axis): try: self._raw_abort_one(axis) except: pass def _raw_abort_all(self): try: return self.ctrl.AbortAll() except: self.warning("AbortAll() raises exception") self.debug("Details:", exc_info=1) raise def _raw_abort_one(self, axis): try: self.ctrl.AbortOne(axis) except: self.warning("AbortOne(%d) raises exception", axis) self.debug("Details:", exc_info=1) raise @check_ctrl def abort_all(self): self.raw_abort_all() @check_ctrl def abort_one(self, axis): return self.raw_abort_one(axis) @check_ctrl def abort_axes(self, axes=None): """Aborts the given axes. If axes is None, aborts all active axes. :param axes: the list of axis to abort. Default is None meaning all active axis in this controller :type axes: seq or None """ if axes is None: return self.raw_abort_all() for axis in axes: self.raw_abort_one(axis) @check_ctrl def abort_elements(self, elements=None): """Aborts the given elements. If axes is None, aborts all active axes. :param elements: the list of elements to abort. Default is None meaning all active axis in this controller :type axes: seq or None """ if elements is None: return self.raw_abort_all() for element in elements: self.raw_abort_one(element.axis) abort = abort_all @check_ctrl def emergency_break(self, elements=None): """Stops the given elements. If axes is None, stops all active axes. If stop raises exception, an abort is attempted. :param elements: the list of elements to stop. Default is None meaning all active axis in this controller :type axes: seq or None """ if elements is None: try: return self._raw_stop_all() except: return self.raw_abort_all() for element in elements: try: self._raw_stop_one(element.axis) except: self.raw_abort_one(element.axis) @check_ctrl def send_to_controller(self, stream): return self.ctrl.SendToCtrl(stream) # END API WHICH ACCESSES CRITICAL CONTROLLER API (like StateOne) ----------- # START SPECIFIC TO MOTOR CONTROLLER --------------------------------------- def raw_move(self, axis_pos): ctrl = self.ctrl ctrl.PreStartAll() for axis, dial_position in axis_pos.items(): ret = ctrl.PreStartOne(axis, dial_position) if not ret: raise Exception("%s.PreStartOne(%d, %f) returns False" \ % (self.name, axis, dial_position)) for axis, dial_position in axis_pos.items(): ctrl.StartOne(axis, dial_position) ctrl.StartAll() @check_ctrl def move(self, axis_pos): return self.raw_move(axis_pos) def has_backlash(self): return "Backlash" in self._ctrl.ctrl_features def wants_rounding(self): return "Rounding" in self._ctrl.ctrl_features @check_ctrl def define_position(self, axis, position): return self.ctrl.DefinePosition(axis, position) # END SPECIFIC TO MOTOR CONTROLLER ----------------------------------------- # START SPECIFIC TO IOR CONTROLLER ----------------------------------------- def write_one(self, axis, value): self.ctrl.WriteOne(axis, value) # END SPECIFIC TO IOR CONTROLLER ------------------------------------------- class PoolPseudoMotorController(PoolController): def __init__(self, **kwargs): self._motor_ids = kwargs.pop('role_ids') super(PoolPseudoMotorController, self).__init__(**kwargs) def serialize(self, *args, **kwargs): kwargs = PoolController.serialize(self, *args, **kwargs) kwargs['type'] = 'Controller' return kwargs def _create_ctrl_args(self): pars = PoolController._create_ctrl_args(self) kwargs = pars[4] kwargs['motor_ids'] = tuple(self._motor_ids) return pars def _read_axis_value(self, element): try: axis = element.get_axis() ctrl_value = self.ctrl.ReadOne(axis) if ctrl_value is None: msg = '%s.ReadOne(%s[%d]) return error: Expected value, ' \ 'got None instead' % (self.name, element.name, axis) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value @check_ctrl def calc_all_pseudo(self, physical_pos, curr_pseudo_pos): ctrl = self.ctrl try: ctrl_value = ctrl.CalcAllPseudo(physical_pos, curr_pseudo_pos) if ctrl_value is None: msg = '%s.CalcAllPseudo() return error: Expected value, ' \ 'got None instead' % (self.name, ) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value @check_ctrl def calc_all_physical(self, pseudo_pos, curr_physical_pos): ctrl = self.ctrl try: ctrl_value = ctrl.CalcAllPhysical(pseudo_pos, curr_physical_pos) if ctrl_value is None: msg = '%s.CalcAllPhysical() return error: Expected value, ' \ 'got None instead' % (self.name, ) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value @check_ctrl def calc_pseudo(self, axis, physical_pos, curr_pseudo_pos): ctrl = self.ctrl try: ctrl_value = ctrl.CalcPseudo(axis, physical_pos, curr_pseudo_pos) if ctrl_value is None: msg = '%s.CalcPseudo() return error: Expected value, ' \ 'got None instead' % (self.name, ) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value @check_ctrl def calc_physical(self, axis, pseudo_pos, curr_physical_pos): ctrl = self.ctrl try: ctrl_value = ctrl.CalcPhysical(axis, pseudo_pos, curr_physical_pos) if ctrl_value is None: msg = '%s.CalcPhysical() return error: Expected value, ' \ 'got None instead' % (self.name, ) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value class PoolPseudoCounterController(PoolController): def __init__(self, **kwargs): self._counter_ids = kwargs.pop('role_ids') super(PoolPseudoCounterController, self).__init__(**kwargs) def serialize(self, *args, **kwargs): kwargs = PoolController.serialize(self, *args, **kwargs) kwargs['type'] = 'Controller' return kwargs def _create_ctrl_args(self): pars = PoolController._create_ctrl_args(self) kwargs = pars[4] kwargs['counter_ids'] = tuple(self._counter_ids) return pars @check_ctrl def calc(self, axis, values): ctrl = self.ctrl try: ctrl_value = ctrl.Calc(axis, values) if ctrl_value is None: msg = '%s.Calc() return error: Expected value, ' \ 'got None instead' % (self.name, ) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value def calc_all(self, values): ctrl = self.ctrl try: ctrl_value = ctrl.CalcAll(values) if ctrl_value is None: msg = '%s.CalcAll() return error: Expected value, ' \ 'got None instead' % (self.name, ) raise ValueError(msg) value = translate_ctrl_value(ctrl_value) except: value = SardanaValue(exc_info=sys.exc_info()) return value sardana-1.2.0/src/sardana/pool/poolcontrollermanager.py0000644000234100017500000005132712174204313024670 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the class which controls finding, loading/unloading of device pool controller plug-ins.""" __all__ = ["ControllerManager" ] __docformat__ = 'restructuredtext' import sys import os import inspect import copy import types import re from taurus.core import ManagerState from taurus.core.util import Singleton, Logger from sardana.sardanamodulemanager import ModuleManager import controller from poolexception import UnknownController from poolmetacontroller import ControllerLibrary, ControllerClass CONTROLLER_TEMPLATE = ''' class @controller_name@(MotorController): """This class representes a Sardana motor controller.""" ctrl_features = [] MaxDevice = 1024 ctrl_properties = {} ctrl_attributes = {} axis_attributes = {} def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) ''' class ControllerManager(Singleton, Logger): """The singleton class responsible for managing controller plug-ins.""" DEFAULT_CONTROLLER_DIRECTORIES = 'poolcontrollers', def __init__(self): """Initialization. Nothing to be done here for now.""" pass def init(self, *args, **kwargs): """Singleton instance initialization.""" name = self.__class__.__name__ self._state = ManagerState.UNINITIALIZED self.call__init__(Logger, name) self._pool = None self.reInit() def reInit(self): """Singleton re-initialization.""" if self._state == ManagerState.INITED: return #: dict #: key - module name (without path and without extension) #: value - ControllerLibrary object representing the module self._modules = {} #: dict #: key - controller name #: value - ControllerClass object representing the controller self._controller_dict = {} #: list #: elements are absolute paths self._controller_path = [] l = [] for _, klass in inspect.getmembers(controller, inspect.isclass): if not issubclass(klass, controller.Controller): continue l.append(klass) self._base_classes = l self._state = ManagerState.INITED def cleanUp(self): """Singleton clean up.""" if self._state == ManagerState.CLEANED: return #if self._modules: # ModuleManager().unloadModules(self._modules.keys()) self._controller_path = None self._controller_dict = None self._modules = None self._state = ManagerState.CLEANED def set_pool(self, pool): self._pool = pool def get_pool(self): return self._pool def setControllerPath(self, controller_path, reload=True): """Registers a new list of controller directories in this manager. :param seq controller_path: a sequence of absolute paths where this manager should look for controllers .. warning:: as a consequence all the controller modules will be reloaded. This means that if any reference to an old controller object was kept it will refer to an old module (which could possibly generate problems of type class A != class A).""" p = [] for item in controller_path: p.extend(item.split(":")) # filter empty and commented paths p = [ i for i in p if i and not i.startswith("#") ] # add basic dummy controller directory(ies) pool_dir = os.path.dirname(os.path.abspath(__file__)) for ctrl_dir in self.DEFAULT_CONTROLLER_DIRECTORIES: ctrl_dir = os.path.join(pool_dir, ctrl_dir) if not ctrl_dir in p: p.append(ctrl_dir) self._controller_path = p controller_file_names = self._findControllerLibNames() for controller_file_name in controller_file_names: try: self.reloadControllerLib(controller_file_name, reload=reload) except Exception: pass def getControllerPath(self): """Returns the current sequence of absolute paths used to look for controllers. :return: sequence of absolute paths :rtype: seq""" return self._controller_path def _findControllerLibNames(self, path=None): """internal method""" path = path or self.getControllerPath() ret = [] for p in path: try: for f in os.listdir(p): name,ext = os.path.splitext(f) if not name[0].isalpha(): continue if ext.endswith('py'): ret.append(name) except: self.debug("'%s' is not a valid path" % p) return ret def _fromNameToFileName(self, lib_name, path=None): """internal method""" path = path or self.getControllerPath()[0] f_name = lib_name if not f_name.endswith('.py'): f_name += '.py' if os.path.isabs(f_name): path, _ = os.path.split(f_name) if not path in self.getControllerPath(): raise Exception("'%s' is not part of the PoolPath" % path) else: f_name = os.path.join(path, f_name) return f_name def getOrCreateControllerLib(self, lib_name, controller_name=None): """Gets the exiting controller lib or creates a new controller lib file. If name is not None, a controller template code for the given controller name is appended to the end of the file. :param str lib_name: module name, python file name, or full file name (with path) :param str controller_name: an optional controller name. If given a controller template code is appended to the end of the file [default: None, meaning no controller code is added) :return: a sequence with three items: full_filename, code, line number line number is 0 if no controller is created or n representing the first line of code for the given controller name. :rtype: tuple """ # if only given the module name controller_lib = self.getControllerLib(lib_name) if controller_name is None: line_nb = 0 if controller_lib is None: f_name, code = self.createControllerLib(lib_name), '' else: f_name = controller_lib.get_file_name() f = file(f_name) code = f.read() f.close() else: # if given controller name if controller_lib is None: f_name, code, line_nb = self.createController(lib_name, controller_name) else: controller = controller_lib.get_controller(controller_name) if controller is None: f_name, code, line_nb = self.createController(lib_name, controller_name) else: _, line_nb = controller.getCode() f_name = controller.getFileName() f = file(f_name) code = f.read() f.close() return [ f_name, code, line_nb ] def setControllerLib(self, lib_name, code): """Creates a new controller library file with the given name and code. The new module is imported and becomes imediately available. :param str lib_name: name of the new library :param str code: python code of the new library""" f_name = self._fromNameToFileName(lib_name) f = open(f_name, 'w') f.write(code) f.flush() f.close() _, name = os.path.split(f_name) mod, _ = os.path.splitext(name) self.reloadControllerLib(mod) def createControllerLib(self, lib_name, path=None): """Creates a new empty controller library (python module)""" f_name = self._fromNameToFileName(lib_name, path) if os.path.exists(f_name): raise Exception("Unable to create controller lib: '%s' already exists" % f_name) f = open(f_name, 'w') f.close() return f_name def createController(self, lib_name, controller_name): """Creates a new controller""" f_name = self._fromNameToFileName(lib_name) create = not os.path.exists(f_name) template = '' if create: template += 'from sardana.pool.controller import *\n\n' line_nb = 4 else: template += '\n' t = open(f_name, 'rU') line_nb = -1 for line_nb, _ in enumerate(t): pass line_nb += 3 t.close() f = open(f_name, 'a+') try: dir_name = os.path.realpath(__file__) dir_name = os.path.dirname(dir_name) template_fname = 'controller_template.txt' template_fname = os.path.join(dir_name, template_fname) f_templ = open(template_fname, 'r') template += f_templ.read() f_templ.close() except: self.debug("Failed to open template controller file. Using simplified template") template += CONTROLLER_TEMPLATE if f_templ: f_templ.close() template = template.replace('@controller_name@', controller_name) try: f.write(template) f.flush() f.seek(0) code = f.read() finally: f.close() return f_name, code, line_nb def reloadController(self, controller_name, path=None): """Reloads the module corresponding to the given controller name :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successfull :param str controller_name: controller class name :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath will be used]""" self.reloadControllers([controller_name], path=path) def reloadControllers(self, controller_names, path=None): """Reloads the modules corresponding to the given controller names :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successful :param seq controller_names: a list of controller class names :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath will be used]""" module_names = [] for controller_name in controller_names: module_name = self.getControllerMetaClass(controller_name).get_module_name() module_names.append(module_name) self.reloadControllerLibs(module_names, path=path) def reloadControllerLibs(self, module_names, path=None, reload=True): """Reloads the given library(=module) names :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successful :param seq module_names: a list of module names :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath will be used]""" ret = [] for module_name in module_names: try: m = self.reloadControllerLib(module_name, path, reload=reload) if m: ret.append(m) except: self.info("Failed to reload controller library %s", module_name) self.debug("Failed to reload controller library %s details", module_name, exc_info=1) return ret def reloadControllerLib(self, module_name, path=None, reload=True): """Reloads the given library(=module) names :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successful :param str module_name: controller library name (=python module name) :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath will be used] :return: the ControllerLib object for the reloaded controller lib :rtype: sardana.pool.poolmetacontroller.ControllerLibrary """ path = path or self.getControllerPath() # reverse the path order: # more priority elements last. This way if there are repeated elements # they first ones (lower priority) will be overwritten by the last ones if path: path = copy.copy(path) path.reverse() # if there was previous Controller Lib info remove it if self._modules.has_key(module_name): self._modules.pop(module_name) m, exc_info = None, None try: m = ModuleManager().reloadModule(module_name, path, reload=reload) except: exc_info = sys.exc_info() controller_lib = None params = dict(module=m, name=module_name, pool=self.get_pool()) if m is None or exc_info is not None: params['exc_info'] = exc_info controller_lib = ControllerLibrary(**params) self._modules[module_name] = controller_lib else: controller_lib = ControllerLibrary(**params) lib_contains_controllers = False abs_file = controller_lib.file_path for _, klass in inspect.getmembers(m, inspect.isclass): if issubclass(klass, controller.Controller): # if it is a class defined in some other class forget it to # avoid replicating the same controller in different # controller files if inspect.getabsfile(klass) != abs_file: continue lib_contains_controllers = True self.addController(controller_lib, klass) if lib_contains_controllers: self._modules[module_name] = controller_lib return controller_lib def addController(self, controller_lib, klass): """Adds a new controller class""" controller_name = klass.__name__ exists = controller_lib.has_controller(controller_name) if exists: action = "Updating" else: action = "Adding" self.debug("%s controller %s" % (action, controller_name)) try: controller_class = ControllerClass(pool=self.get_pool(), lib=controller_lib, klass=klass) #self._setControllerTypes(klass, controller_class) controller_lib.add_controller(controller_class) self._controller_dict[controller_name] = controller_class except: self.warning("Failed to add controller class %s", controller_name, exc_info=1) if exists: action = "Updated" else: action = "Added" self.debug("%s controller %s" % (action, controller_name)) def getControllerNames(self): return sorted(self._controller_dict.keys()) def getControllerLibNames(self): return sorted(self._modules.keys()) def getControllerLibs(self, filter=None): ret, expr = [], None if filter is not None: expr = re.compile(filter, re.IGNORECASE) for name, lib in self._modules.iteritems(): if lib.has_errors() or (expr is not None and expr.match(name) is None): continue ret.append(lib) ret.sort() return ret def getControllers(self, filter=None): if filter is None: return sorted(self._controller_dict.values()) expr = re.compile(filter, re.IGNORECASE) ret = [ kls for n, kls in self._controller_dict.iteritems() if not expr.match(n) is None ] ret.sort() return ret def getControllerMetaClass(self, controller_name): ret = self._controller_dict.get(controller_name) if ret is None: raise UnknownController("Unknown controller %s" % controller_name) return ret def getControllerMetaClasses(self, controller_names): ret = {} for name in controller_names: ret[name] = self._controller_dict.get(name) return ret def getControllerLib(self, name): if os.path.isabs(name): abs_file_name = name for lib in self._modules.values(): if lib.file_path == abs_file_name: return lib elif name.count(os.path.extsep): file_name = name for lib in self._modules.values(): if lib.file_name == file_name: return lib module_name = name return self._modules.get(module_name) def getControllerClass(self, controller_name): return self.getControllerMetaClass(controller_name).klass def _getPlainControllerInfo(self, controller_names): ret = [] for controller_name in controller_names: controller_class = self.getControllerMetaClass(controller_name) if controller_class is not None: ret += controller_class.getInfo() return ret def decodeControllerParameters(self, in_par_list): if len(in_par_list) == 0: raise RuntimeError('Controller name not specified') controller_name_or_klass = in_par_list[0] controller_class = controller_name_or_klass if type(controller_class) in types.StringTypes: controller_class = self.getControllerClass(controller_class) if controller_class is None: raise UnknownController("Unknown controller %s" % controller_name_or_klass) import parameter out_par_list = msparameter.ParamDecoder(controller_class, in_par_list) return controller_class, in_par_list, out_par_list def strControllerParamValues(self,par_list): """Creates a short string representation of the parameter values list. :param par_list: list of strings representing the parameter values. :type par_list: list :return: a list containning an abreviated version of the par_list argument. :rtype: list """ ret = [] for p in par_list: param_str = str(p) if len(param_str)>9: param_str = param_str[:9] + "..." ret.append(param_str) return ret sardana-1.2.0/src/sardana/pool/poolcountertimer.py0000644000234100017500000000415712174204314023672 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for CounterTimer""" __all__ = [ "PoolCounterTimer" ] __docformat__ = 'restructuredtext' from sardana import ElementType from .poolbasechannel import PoolBaseChannel class PoolCounterTimer(PoolBaseChannel): def __init__(self, **kwargs): kwargs['elem_type'] = ElementType.CTExpChannel PoolBaseChannel.__init__(self, **kwargs) # -------------------------------------------------------------------------- # value # -------------------------------------------------------------------------- def set_write_value(self, w_value, timestamp=None, propagate=1): """Sets a new write value for the value. :param w_value: the new write value for value :type w_value: :class:`~numbers.Number` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" self._value.set_write_value(w_value, timestamp=timestamp, propagate=propagate) sardana-1.2.0/src/sardana/pool/pooldefs.py0000644000234100017500000000252312174204313022065 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This file contains the basic pool definitions.""" __all__ = ["ControllerAPI", "AcqTriggerType", "AcqMode"] __docformat__ = 'restructuredtext' from taurus.core.util import Enumeration from taurus.core.tango.sardana import AcqTriggerType, AcqMode #: A constant defining the controller API version currently supported ControllerAPI = 1.1 sardana-1.2.0/src/sardana/pool/poolelement.py0000644000234100017500000001230712174204314022577 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = ["PoolElement", "PoolElementFrontend"] __docformat__ = 'restructuredtext' import weakref from sardana.sardanaevent import EventType from .poolbaseelement import PoolBaseElement class PoolElement(PoolBaseElement): """A Pool element is an Pool object which is controlled by a controller. Therefore it contains a _ctrl_id and a _axis (the id of the element in the controller).""" def __init__(self, **kwargs): ctrl = kwargs.pop('ctrl') self._ctrl = weakref.ref(ctrl) self._axis = kwargs.pop('axis') self._ctrl_id = ctrl.get_id() try: instrument = kwargs.pop('instrument') self.set_instrument(instrument) except KeyError: self._instrument = None super(PoolElement, self).__init__(**kwargs) def serialize(self, *args, **kwargs): kwargs = PoolBaseElement.serialize(self, *args, **kwargs) kwargs['controller'] = self.controller.full_name kwargs['unit'] = '0' #TODO: hardcoded unit to 0 kwargs['axis'] = self.axis if self.instrument is not None: kwargs['instrument'] = self.instrument.full_name else: kwargs['instrument'] = None kwargs['source'] = self.get_source() return kwargs def get_parent(self): return self.get_controller() def get_controller(self): if self._ctrl is None: return None return self._ctrl() def get_controller_id(self): return self._ctrl_id def get_axis(self): return self._axis def set_action_cache(self, action_cache): self._action_cache = action_cache action_cache.add_element(self) def get_source(self): return "{0}/{1}".format(self.full_name, self.get_default_acquisition_channel()) # -------------------------------------------------------------------------- # instrument # -------------------------------------------------------------------------- def get_instrument(self): if self._instrument is None: return None return self._instrument() def set_instrument(self, instrument, propagate=1): self._set_instrument(instrument, propagate=propagate) def _set_instrument(self, instrument, propagate=1): if self._instrument is not None: self._instrument().remove_element(self) new_instrument_name = "" if instrument is None: self._instrument = None else: self._instrument = weakref.ref(instrument) new_instrument_name = instrument.full_name instrument.add_element(self) if not propagate: return self.fire_event(EventType("instrument", priority=propagate), new_instrument_name) # -------------------------------------------------------------------------- # stop # -------------------------------------------------------------------------- def stop(self): self.info("Stop!") PoolBaseElement.stop(self) self.controller.stop_one(self.axis) # -------------------------------------------------------------------------- # abort # -------------------------------------------------------------------------- def abort(self): self.info("Abort!") PoolBaseElement.abort(self) self.controller.abort_one(self.axis) def get_par(self, name): return self.controller.get_axis_par(self.axis, name) def set_par(self, name, value): return self.controller.set_axis_par(self.axis, name, value) def get_extra_par(self, name): return self.controller.get_axis_attr(self.axis, name) def set_extra_par(self, name, value): return self.controller.set_axis_attr(self.axis, name, value) axis = property(get_axis, doc="element axis") controller = property(get_controller, doc="element controller") controller_id = property(get_controller_id, doc="element controller id") instrument = property(get_instrument, set_instrument, doc="element instrument") sardana-1.2.0/src/sardana/pool/poolexception.py0000644000234100017500000000271312174204314023144 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for pool exceptions""" __all__ = ["PoolException", "UnknownController", "UnknownControllerLibrary"] __docformat__ = 'restructuredtext' from sardana.sardanaexception import SardanaException, UnknownCode, \ UnknownLibrary class PoolException(SardanaException): pass class UnknownController(UnknownCode): pass class UnknownControllerLibrary(UnknownLibrary): passsardana-1.2.0/src/sardana/pool/poolextension.py0000644000234100017500000000567712174204313023175 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines the base classes for sardana value translation""" __all__ = ["CannotTranslateException", "register_controller_value_translator", "register_controller_state_translator", "ControllerValueTranslator", "ControllerStateTranslator"] __docformat__ = 'restructuredtext' from sardana.sardanavalue import SardanaValue __CTRL_STATE_TRANSLATORS = {} __CTRL_VALUE_TRANSLATORS = {} class CannotTranslateException(Exception): def __init__(self, *args, **kwargs): super(CannotTranslateException, self).__init__(*args, **kwargs) class BaseControllerTranslator(object): def translate(self, value): raise CannotTranslateException def __call__(self, value): return self.translate(value) class ControllerValueTranslator(BaseControllerTranslator): pass class ControllerStateTranslator(BaseControllerTranslator): pass def register_controller_value_translator(klass, *args, **kwargs): if not issubclass(klass, ControllerValueTranslator): raise Exception("Cannot register controller value translator. " \ "Class must inherit from ControllerValueTranslator") __CTRL_VALUE_TRANSLATORS[klass] = klass(*args, **kwargs) def register_controller_state_translator(klass, *args, **kwargs): if not issubclass(klass, ControllerStateTranslator): raise Exception("Cannot register controller value translator. " \ "Class must inherit from ControllerStateTranslator") __CTRL_STATE_TRANSLATORS[klass] = klass(*args, **kwargs) def translate_ctrl_value(value): if isinstance(value, SardanaValue): return value for _, translator in __CTRL_VALUE_TRANSLATORS.items(): try: return translator(value) except CannotTranslateException: continue # Fallback translator return SardanaValue(value=value) sardana-1.2.0/src/sardana/pool/poolexternal.py0000644000234100017500000001013312174204314022763 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for external objects to the pool (like tango objects)""" __all__ = ["PoolBaseExternalObject", "PoolTangoObject", "PoolExternalObject"] __docformat__ = 'restructuredtext' import PyTango from sardana import ElementType from .poolbaseobject import PoolBaseObject class PoolBaseExternalObject(PoolBaseObject): """TODO""" def __init__(self, **kwargs): kwargs['elem_type'] = ElementType.External PoolBaseObject.__init__(self, **kwargs) def get_source(self): return self.full_name def get_config(self): raise NotImplementedError class PoolTangoObject(PoolBaseExternalObject): """TODO""" def __init__(self, **kwargs): scheme = kwargs.pop('scheme', 'tango') attribute_name = kwargs.pop('attributename') host, port = kwargs.pop('host', None), kwargs.pop('port', None) devalias = kwargs.pop('devalias', None) device_name = kwargs.pop('devicename', None) if host is None: db = PyTango.Database() host, port = db.get_db_host(), db.get_db_port() else: db = PyTango.Database(host, port) full_name = "" if device_name is None: if devalias is not None: try: device_name = db.get_device_alias(devalias) full_name = "{0}:{1}/{2}/{3}".format(host, port, device_name, attribute_name) except: full_name = "{0}/{1}".format(devalias, attribute_name) else: full_name = "{0}:{1}/{2}/{3}".format(host, port, device_name, attribute_name) self._device_name = device_name self._attribute_name = attribute_name self._config = None self._device = None kwargs['name'] = attribute_name kwargs['full_name'] = full_name PoolBaseExternalObject.__init__(self, **kwargs) def get_device_name(self): return self._device_name def get_attribute_name(self): return self._attribute_name def get_device(self): device = self._device if device is None: try: self._device = device = PyTango.DeviceProxy(self._device_name) except: pass return device def get_config(self): config= self._config if config is None: try: self._config = config = \ self._device.get_attribute_config(self._attribute_name) except: pass return config device_name = property(get_device_name) attribute_name = property(get_attribute_name) _SCHEME_CLASS = { 'tango' : PoolTangoObject, None : PoolTangoObject} def PoolExternalObject(**kwargs): scheme = kwargs.get('scheme', 'tango') klass = _SCHEME_CLASS[scheme] return klass(**kwargs) sardana-1.2.0/src/sardana/pool/poolgroupelement.py0000644000234100017500000000761512174204313023661 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = ["PoolGroupElement"] __docformat__ = 'restructuredtext' from .poolbaseelement import PoolBaseElement from .poolbasegroup import PoolBaseGroup class PoolGroupElement(PoolBaseElement, PoolBaseGroup): def __init__(self, **kwargs): user_elements = kwargs.pop('user_elements') PoolBaseElement.__init__(self, **kwargs) PoolBaseGroup.__init__(self, user_elements=user_elements, pool=kwargs['pool']) def serialize(self, *args, **kwargs): kwargs = PoolBaseElement.serialize(self, *args, **kwargs) elements = [ elem.name for elem in self.get_user_elements() ] physical_elements = [] for elem_list in self.get_physical_elements().values(): for elem in elem_list: physical_elements.append(elem.name) kwargs['elements'] = elements kwargs['physical_elements'] = physical_elements return kwargs def get_action_cache(self): return self._get_action_cache() def set_action_cache(self, action_cache): self._set_action_cache(action_cache) # -------------------------------------------------------------------------- # state information # -------------------------------------------------------------------------- def read_state_info(self): state_info = {} ctrl_state_info = self.get_action_cache().read_state_info(serial=True) for elem, ctrl_elem_state_info in ctrl_state_info.items(): elem_state_info = elem._from_ctrl_state_info(ctrl_elem_state_info) elem.put_state_info(elem_state_info) state = elem.get_state(cache=True, propagate=0) status = elem.get_status(cache=True, propagate=0) state_info[elem] = state, status return state_info def _set_state_info(self, state_info, propagate=1): state_info = self._calculate_states(state_info) state, status = state_info self._set_status(status, propagate=propagate) self._set_state(state, propagate=propagate) # -------------------------------------------------------------------------- # stop # -------------------------------------------------------------------------- def stop(self): PoolBaseElement.stop(self) PoolBaseGroup.stop(self) # -------------------------------------------------------------------------- # abort # -------------------------------------------------------------------------- def abort(self): PoolBaseElement.abort(self) PoolBaseGroup.abort(self) # -------------------------------------------------------------------------- # involved in an operation # -------------------------------------------------------------------------- def get_operation(self): return PoolBaseGroup.get_operation(self) sardana-1.2.0/src/sardana/pool/poolinstrument.py0000644000234100017500000000700112174204313023350 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for instrument""" __all__ = [ "PoolInstrument" ] __docformat__ = 'restructuredtext' import weakref from sardana import ElementType from .poolobject import PoolObject class PoolInstrument(PoolObject): def __init__(self, **kwargs): self._parent_instrument = kwargs.pop("parent") self._instrument_class = kwargs.pop("klass") if self._parent_instrument: self._parent_instrument = weakref.ref(self._parent_instrument) self._child_instruments = {} self._elements = {} kwargs['elem_type'] = ElementType.Instrument super(PoolInstrument, self).__init__(**kwargs) def get_parent(self): return self.get_parent_instrument() def serialize(self, *args, **kwargs): kwargs = PoolObject.serialize(self, *args, **kwargs) kwargs['klass'] = self.instrument_class if self.parent_instrument is not None: kwargs['parent_instrument'] = self.parent_instrument.full_name else: kwargs['parent_instrument'] = None return kwargs def get_instrument_class(self): return self._instrument_class def add_instrument(self, instrument): self._child_instruments[instrument.id] = instrument def remove_instrument(self, instrument): del self._child_instruments[instrument.id] def get_instruments(self): return self._child_instruments.values() def set_parent_instrument(self, instrument): if instrument: self._parent_instrument = weakref.ref(instrument) else: self._parent_instrument = None def get_parent_instrument(self): if self.has_parent_instrument(): return self._parent_instrument() def has_parent_instrument(self): return self._parent_instrument is not None def add_element(self, element): self._elements[element.id] = weakref.ref(element) def remove_element(self, element): del self._elements[element.id] def get_elements(self): return [ e() for e in self._elements.values() ] def has_instruments(self): return len(self._child_instruments) > 0 def has_elements(self): return len(self._elements) > 0 instruments = property(get_instruments) elements = property(get_elements) instrument_class = property(get_instrument_class) parent_instrument = property(get_parent_instrument) sardana-1.2.0/src/sardana/pool/poolioregister.py0000644000234100017500000001214612174204313023322 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for """ __all__ = [ "PoolIORegister" ] __docformat__ = 'restructuredtext' import time from sardana import ElementType from sardana.sardanaevent import EventType from sardana.sardanaattribute import SardanaAttribute from .poolelement import PoolElement from .poolacquisition import PoolIORAcquisition class Value(SardanaAttribute): def __init__(self, *args, **kwargs): super(Value, self).__init__(*args, **kwargs) def update(self, cache=True, propagate=1): if not cache or not self.has_value(): value = self.obj.read_value() self.set_value(value, propagate=propagate) class PoolIORegister(PoolElement): def __init__(self, **kwargs): kwargs['elem_type'] = ElementType.IORegister PoolElement.__init__(self, **kwargs) self._value = Value(self, listeners=self.on_change) self._config = None acq_name = "%s.Acquisition" % self._name self.set_action_cache(PoolIORAcquisition(self.pool, name=acq_name)) def get_value_attribute(self): """Returns the value attribute object for this IO register :return: the value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._value # -------------------------------------------------------------------------- # Event forwarding # -------------------------------------------------------------------------- def on_change(self, evt_src, evt_type, evt_value): # forward all events coming from attributes to the listeners self.fire_event(evt_type, evt_value) # -------------------------------------------------------------------------- # default acquisition channel # -------------------------------------------------------------------------- def get_default_attribute(self): return self.get_value_attribute() # -------------------------------------------------------------------------- # value # -------------------------------------------------------------------------- def read_value(self): """Reads the IO register value from hardware. :return: a :class:`~sardana.sardanavalue.SardanaValue` containing the IO register value :rtype: :class:`~sardana.sardanavalue.SardanaValue`""" return self.get_action_cache().read_value()[self] def put_value(self, value, propagate=1): """Sets a value. :param value: the new value :type value: :class:`~sardana.sardanavalue.SardanaValue` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" val_attr = self._value val_attr.set_value(value, propagate=propagate) return val_attr def get_value(self, cache=True, propagate=1): value = self.get_value_attribute() value.update(cache=cache, propagate=propagate) return value def set_value(self, value, timestamp=None): self.write_register(value, timestamp=timestamp) def set_write_value(self, w_value, timestamp=None, propagate=1): """Sets a new write value for the IO registere :param w_value: the new write value for IO register :type w_value: :class:`~numbers.Number` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" self._value.set_write_value(w_value, timestamp=timestamp, propagate=propagate) value = property(get_value, set_value, doc="ioregister value") def write_register(self, value, timestamp=None): self._aborted = False self._stopped = False if not self._simulation_mode: if timestamp is None: timestamp = time.time() self.set_write_value(value, timestamp=timestamp, propagate=0) self.controller.write_one(self.axis, value) sardana-1.2.0/src/sardana/pool/poolmeasurementgroup.py0000644000234100017500000005454612174204314024563 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = [ "PoolMeasurementGroup" ] __docformat__ = 'restructuredtext' from taurus.core.taurusvalidator import AttributeNameValidator from taurus.core.tango.sardana import PlotType, Normalization from sardana import State,ElementType, \ TYPE_EXP_CHANNEL_ELEMENTS, TYPE_TIMERABLE_ELEMENTS from sardana.sardanaevent import EventType from .pooldefs import AcqMode, AcqTriggerType from .poolgroupelement import PoolGroupElement from .poolacquisition import PoolAcquisition from .poolexternal import PoolExternalObject #---------------------------------------------- # Measurement Group Configuration information #---------------------------------------------- # dict with (at least) keys: # - 'timer' : the timer channel name / timer channel id # - 'monitor' : the monitor channel name / monitor channel id # - 'controllers' : dict where: # - key: ctrl # - value: dict with (at least) keys: # - 'units': dict with (at least) keys: # - 'id' : the unit ID inside the controller # - 'timer' : the timer channel name / timer channel id # - 'monitor' : the monitor channel name / monitor channel id # - 'trigger_type' : 'Gate'/'Software' # - 'channels' where value is a dict with (at least) keys: # - 'id' : the channel name ( channel id ) # optional keys: # - 'enabled' : True/False (default is True) # any hints: # - 'output' : True/False (default is True) # - 'plot_type' : 'No'/'1D'/'2D' (default is 'No') # - 'plot_axes' : list 'where str is channel name/'step#/'index#' (default is []) # - 'label' : prefered label (default is channel name) # - 'scale' : with min/max (defaults to channel # range if it is defined # - 'plot_color' : int representing RGB # optional keys: # - 'label' : measurement group label (defaults to measurement group name) # - 'description' : measurement group description # # UxTimer # CT1 # # Example: 2 NI cards, where channel 1 of card 1 is wired to channel 1 of card 2 # at configuration time we should set: # ctrl.setPar( , , ) # ni0ctrl.setCtrlPar(0, 'trigger_type', AcqTriggerType.Software) # ni0ctrl.setCtrlPar(0, 'timer', 1) # channel 1 is the timer # ni0ctrl.setCtrlPar(0, 'monitor', 4) # channel 4 is the monitor # ni1ctrl.setCtrlPar(0, 'trigger_type', AcqTriggerType.ExternalTrigger) # ni1ctrl.setCtrlPar(0, 'master', 0) # when we count for 1.5 seconds: # ni1ctrl.Load(1.5) # ni0ctrl.Load(1.5) # ni1ctrl.Start() # ni0ctrl.Start() """ """ class PoolMeasurementGroup(PoolGroupElement): DFT_DESC = 'General purpose measurement group' def __init__(self, **kwargs): self._integration_time = None self._monitor_count = None self._acquisition_mode = AcqMode.Timer self._config = None self._config_dirty = True kwargs['elem_type'] = ElementType.MeasurementGroup PoolGroupElement.__init__(self, **kwargs) self.set_configuration(kwargs.get('configuration')) def _create_action_cache(self): acq_name = "%s.Acquisition" % self._name return PoolAcquisition(self, acq_name) def _calculate_element_state(self, elem, elem_state_info): if elem.get_type() == ElementType.ZeroDExpChannel: if elem_state_info[0] == State.Moving: elem_state_info = State.On, elem_state_info[1] return PoolGroupElement._calculate_element_state(self, elem, elem_state_info) def on_element_changed(self, evt_src, evt_type, evt_value): name = evt_type.name if name == 'state': if evt_src.get_type() == ElementType.ZeroDExpChannel: # 0D channels are "passive", which means they cannot contribute # to set the measurement group into a moving state if evt_value in (State.On, State.Moving): return state, status = self._calculate_states() self.set_state(state, propagate=2) self.set_status("\n".join(status)) def get_pool_controllers(self): return self.get_acquisition().get_pool_controllers() def get_pool_controller_by_name(self, name): name = name.lower() for ctrl in self.get_pool_controllers(): if ctrl.name.lower() == name or ctrl.full_name.lower() == name: return ctrl # -------------------------------------------------------------------------- # configuration # -------------------------------------------------------------------------- def _is_managed_element(self, element): return element.get_type() in TYPE_EXP_CHANNEL_ELEMENTS def _build_channel_defaults(self, channel_data, channel): """Fills the channel default values for the given channel dictionary""" external_from_name = isinstance(channel, (str, unicode)) ndim = None instrument = None if external_from_name: name = full_name = source = channel else: name = channel.name full_name = channel.full_name source = channel.get_source() ndim = None instrument = None ctype = channel.get_type() if ctype != ElementType.External: instrument = channel.instrument if ctype == ElementType.CTExpChannel: ndim = 0 elif ctype == ElementType.PseudoCounter: ndim = 0 elif ctype == ElementType.ZeroDExpChannel: ndim = 0 elif ctype == ElementType.OneDExpChannel: ndim = 1 elif ctype == ElementType.TwoDExpChannel: ndim = 2 elif ctype == ElementType.External: config = channel.get_config() if config is not None: ndim = int(config.data_format) elif ctype == ElementType.IORegister: ndim = 0 # Definitively should be initialized by measurement group # index MUST be here already (asserting this in the following line) channel_data['index'] = channel_data['index'] channel_data['name'] = channel_data.get('name', name) channel_data['full_name'] = channel_data.get('full_name', full_name) channel_data['source'] = channel_data.get('source', source) channel_data['enabled'] = channel_data.get('enabled', True) channel_data['label'] = channel_data.get('label', channel_data['name']) channel_data['instrument'] = channel_data.get('instrument', getattr(instrument,'name',None)) channel_data['ndim'] = ndim # Probably should be initialized by measurement group channel_data['output'] = channel_data.get('output', True) # Perhaps should NOT be initialized by measurement group channel_data['plot_type'] = channel_data.get('plot_type', PlotType.No) channel_data['plot_axes'] = channel_data.get('plot_axes', []) channel_data['conditioning'] = channel_data.get('conditioning', '') channel_data['normalization'] = channel_data.get('normalization', Normalization.No) return channel_data def _build_configuration(self): """Builds a configuration object from the list of elements""" config = {} user_elements = self.get_user_elements() ctrls = self.get_pool_controllers() # find the first CT first_timerable = None for elem in user_elements: if elem.get_type() in TYPE_TIMERABLE_ELEMENTS: first_timerable = elem break if first_timerable is None: raise Exception("It is not possible to construct a measurement " "group without at least one timer able channel " "(Counter/timer, 1D or 2D)") g_timer = g_monitor = first_timerable config['timer'] = g_timer config['monitor'] = g_monitor config['controllers'] = controllers = {} external_user_elements = [] for index, element in enumerate(user_elements): elem_type = element.get_type() if elem_type == ElementType.External: external_user_elements.append((index, element)) continue ctrl = element.controller ctrl_data = controllers.get(ctrl) # attention: following lines are only prepared for 1 unit per # controller if ctrl_data is None: controllers[ctrl] = ctrl_data = {} ctrl_data['units'] = units = {} units['0'] = unit_data = {} unit_data['id'] = 0 unit_data['channels'] = channels = {} if elem_type in TYPE_TIMERABLE_ELEMENTS: elements = ctrls[ctrl] if g_timer in elements: unit_data['timer'] = g_timer else: unit_data['timer'] = elements[0] if g_monitor in elements: unit_data['monitor'] = g_monitor else: unit_data['monitor'] = elements[0] unit_data['trigger_type'] = AcqTriggerType.Software else: channels = ctrl_data['units']['0']['channels'] channels[element] = channel_data = {} channel_data['index'] = user_elements.index(element) channel_data = self._build_channel_defaults(channel_data, element) config['label'] = self.name config['description'] = self.DFT_DESC if len(external_user_elements) > 0: controllers['__tango__'] = ctrl_data = {} ctrl_data['units'] = units = {} units['0'] = unit_data = {} unit_data['id'] = 0 unit_data['channels'] = channels = {} for index, element in external_user_elements: channels[element] = channel_data = {} channel_data['index'] = index channel_data = self._build_channel_defaults(channel_data, element) return config def set_configuration(self, config=None, propagate=1): if config is None: config = self._build_configuration() else: # create a configuration based on a new configuration user_elem_ids = {} pool = self.pool for c, c_data in config['controllers'].items(): external = isinstance(c, (str, unicode)) # attention: following line only prepared for 1 unit per controller for channel_data in c_data['units']['0']['channels'].values(): if external: element = id = channel_data['full_name'] channel_data['source'] = id else: element = pool.get_element_by_full_name(channel_data['full_name']) id = element.id user_elem_ids[channel_data['index']] = id channel_data = self._build_channel_defaults(channel_data, element) indexes = sorted(user_elem_ids.keys()) assert indexes == range(len(indexes)) self.set_user_element_ids([ user_elem_ids[idx] for idx in indexes ]) # checks g_timer, g_monitor = config['timer'], config['monitor'] # attention: following line only prepared for 1 unit per controller timer_ctrl_data = config['controllers'][g_timer.controller]['units']['0'] if timer_ctrl_data['timer'] != g_timer: self.warning('unit timer and global timer mismatch. ' 'Using global timer') self.debug('For controller %s, timer is defined as channel %s. ' 'The global timer is set to channel %s which belongs ' 'to the same controller', g_timer.controller.name, timer_ctrl_data['timer'].name, g_timer.name) timer_ctrl_data['timer'] = g_timer # attention: following line only prepared for 1 unit per controller monitor_ctrl_data = config['controllers'][g_monitor.controller]['units']['0'] if monitor_ctrl_data['monitor'] != g_monitor: self.warning('unit monitor and global monitor mismatch. ' 'Using global monitor') self.debug('For controller %s, monitor is defined as channel %s. ' 'The global timer is set to channel %s which belongs ' 'to the same controller', g_monitor.controller.name, monitor_ctrl_data['monitor'].name, g_monitor.name) monitor_ctrl_data['monitor'] != g_monitor self._config = config self._config_dirty = True if not propagate: return self.fire_event(EventType("configuration", priority=propagate), config) def set_configuration_from_user(self, cfg, propagate=1): config = {} user_elements = self.get_user_elements() pool = self.pool timer_name = cfg.get('timer', user_elements[0].full_name) monitor_name = cfg.get('monitor', user_elements[0].full_name) config['timer'] = pool.get_element_by_full_name(timer_name) config['monitor'] = pool.get_element_by_full_name(monitor_name) config['controllers'] = controllers = {} for c_name, c_data in cfg['controllers'].items(): # discard controllers which don't have items (garbage) ch_count = 0 for u_data in c_data['units'].values(): ch_count += len(u_data['channels']) if ch_count == 0: continue external = c_name.startswith('__') if external: ctrl = c_name else: ctrl = pool.get_element_by_full_name(c_name) assert ctrl.get_type() == ElementType.Controller controllers[ctrl] = ctrl_data = {} ctrl_data['units'] = units = {} for u_id, u_data in c_data['units'].items(): # discard units which don't have items (garbage) if len(u_data['channels']) == 0: continue units[u_id] = unit_data = dict(u_data) unit_data['id'] = u_data.get('id', u_id) if not external and ctrl.is_timerable(): unit_data['timer'] = pool.get_element_by_full_name(u_data['timer']) unit_data['monitor'] = pool.get_element_by_full_name(u_data['monitor']) unit_data['trigger_type'] = u_data['trigger_type'] unit_data['channels'] = channels = {} for ch_name, ch_data in u_data['channels'].items(): if external: validator = AttributeNameValidator() params = validator.getParams(ch_data['full_name']) params['pool'] = self.pool channel = PoolExternalObject(**params) else: channel = pool.get_element_by_full_name(ch_name) channels[channel] = dict(ch_data) config['label'] = cfg.get('label', self.name) config['description'] = cfg.get('description', self.DFT_DESC) self.set_configuration(config, propagate=propagate) def get_configuration(self): return self._config def get_user_configuration(self): cfg = self.get_configuration() config = {} config['timer'] = cfg['timer'].full_name config['monitor'] = cfg['monitor'].full_name config['controllers'] = controllers = {} for c, c_data in cfg['controllers'].items(): ctrl_name = c if not isinstance(c, (str, unicode)): ctrl_name = c.full_name external = ctrl_name.startswith('__') controllers[ctrl_name] = ctrl_data = {} ctrl_data['units'] = units = {} for u_id, u_data in c_data['units'].items(): units[u_id] = unit_data = {} unit_data['id'] = u_data['id'] if not external and c.is_timerable(): if u_data.has_key('timer'): unit_data['timer'] = u_data['timer'].full_name if u_data.has_key('monitor'): unit_data['monitor'] = u_data['monitor'].full_name if u_data.has_key('trigger_type'): unit_data['trigger_type'] = u_data['trigger_type'] unit_data['channels'] = channels = {} for ch, ch_data in u_data['channels'].items(): channels[ch.full_name] = dict(ch_data) config['label'] = cfg['label'] config['description'] = cfg['description'] return config def load_configuration(self, force=False): """Loads the current configuration to all involved controllers""" cfg = self.get_configuration() g_timer, g_monitor = cfg['timer'], cfg['monitor'] for ctrl, ctrl_data in cfg['controllers'].items(): # skip external channels if type(ctrl) is str: continue if ctrl.operator == self and not force and not self._config_dirty: continue ctrl.operator = self if ctrl.is_timerable(): for unit, unit_data in ctrl_data['units'].items(): #if ctrl == g_timer.controller: # ctrl.set_ctrl_par('timer', g_timer.axis) #if ctrl == g_monitor.controller: # ctrl.set_ctrl_par('monitor', g_monitor.axis) ctrl.set_ctrl_par('timer', unit_data['timer'].axis) ctrl.set_ctrl_par('monitor', unit_data['monitor'].axis) ctrl.set_ctrl_par('trigger_type', unit_data['trigger_type']) self._config_dirty = False def get_timer(self): return self.get_configuration()['timer'] timer = property(get_timer) # -------------------------------------------------------------------------- # integration time # -------------------------------------------------------------------------- def get_integration_time(self): return self._integration_time def set_integration_time(self, integration_time, propagate=1): self._integration_time = integration_time if not propagate: return self.fire_event(EventType("integration_time", priority=propagate), integration_time) integration_time = property(get_integration_time, set_integration_time, doc="the current integration time") # -------------------------------------------------------------------------- # integration time # -------------------------------------------------------------------------- def get_monitor_count(self): return self._monitor_count def set_monitor_count(self, monitor_count, propagate=1): self._monitor_count = monitor_count if not propagate: return self.fire_event(EventType("monitor_count", priority=propagate), monitor_count) monitor_count = property(get_monitor_count, set_monitor_count, doc="the current monitor count") # -------------------------------------------------------------------------- # acquisition mode # -------------------------------------------------------------------------- def get_acquisition_mode(self): return self._acquisition_mode def set_acquisition_mode(self, acquisition_mode, propagate=1): self._acquisition_mode = acquisition_mode if not propagate: return self.fire_event(EventType("acquisition_mode", priority=propagate), acquisition_mode) acquisition_mode = property(get_acquisition_mode, set_acquisition_mode, doc="the current acquisition mode") # -------------------------------------------------------------------------- # acquisition # -------------------------------------------------------------------------- def start_acquisition(self, value=None, multiple=1): self._aborted = False if not self._simulation_mode: # load configuration into controller(s) if necessary self.load_configuration() # start acquisition kwargs = dict(head=self, config=self._config, multiple=multiple) if self.acquisition_mode == AcqMode.Timer: kwargs["integ_time"] = self._integration_time elif self.acquisition_mode == AcqMode.Monitor: kwargs["monitor_count"] = self._monitor_count self.acquisition.run(**kwargs) def set_acquisition(self, acq_cache): self.set_action_cache(acq_cache) def get_acquisition(self): return self.get_action_cache() acquisition = property(get_acquisition, doc="acquisition object") sardana-1.2.0/src/sardana/pool/poolmetacontroller.py0000644000234100017500000003372712174204314024211 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for""" __all__ = ["CONTROLLER_TEMPLATE", "CTRL_TYPE_MAP", "TYPE_MAP", "TYPE_MAP_OBJ", "TypeData", "DTYPE_MAP", "DACCESS_MAP", "DataInfo", "ControllerLibrary", "ControllerClass"] __docformat__ = 'restructuredtext' import inspect import types from taurus.core.util import CaselessDict from sardana import DataType, DataFormat, DataAccess, \ to_dtype_dformat, to_daccess, \ ElementType, TYPE_ELEMENTS, InvalidId from sardana.sardanameta import SardanaLibrary, SardanaClass from .poolmotor import PoolMotor from .poolpseudomotor import PoolPseudoMotor from .poolmotorgroup import PoolMotorGroup from .poolmeasurementgroup import PoolMeasurementGroup from .poolcountertimer import PoolCounterTimer from .poolzerodexpchannel import Pool0DExpChannel from .poolonedexpchannel import Pool1DExpChannel from .pooltwodexpchannel import Pool2DExpChannel from .poolpseudocounter import PoolPseudoCounter from .poolinstrument import PoolInstrument from .poolioregister import PoolIORegister from .poolcontroller import PoolController, PoolPseudoMotorController, \ PoolPseudoCounterController from .controller import Controller, MotorController, CounterTimerController, \ ZeroDController, OneDController, TwoDController, \ PseudoMotorController, PseudoCounterController, \ IORegisterController from .controller import Type, Access, Description, DefaultValue, FGet, FSet, \ Memorize, Memorized, MaxDimSize #: String containing template code for a controller class CONTROLLER_TEMPLATE = """class @controller_name@(@controller_type@): \"\"\"@controller_name@ description.\"\"\" """ ET = ElementType #: a dictionary dict<:data:`~sardana.ElementType`, class> #: mapping element type enumeration with the corresponding controller pool class #: (:class:`~sardana.pool.poolcontroller.PoolController` or sub-class of it). CTRL_TYPE_MAP = { ET.Motor : PoolController, ET.CTExpChannel : PoolController, ET.OneDExpChannel : PoolController, ET.TwoDExpChannel : PoolController, ET.PseudoMotor : PoolPseudoMotorController, ET.PseudoCounter : PoolPseudoCounterController, ET.IORegister : PoolController, } #: dictionary dict<:data:`~sardana.ElementType`, :class:`tuple`> #: where tuple is a sequence: #: #: #. type string representation #: #. family #: #. internal pool class #: #. automatic full name #: #. controller class TYPE_MAP = { ET.Controller : ("Controller", "Controller", CTRL_TYPE_MAP, "controller/{klass}/{name}", Controller), ET.Instrument : ("Instrument", "Instrument", PoolInstrument, "{full_name}", None), ET.Motor : ("Motor", "Motor", PoolMotor, "motor/{ctrl_name}/{axis}", MotorController), ET.CTExpChannel : ("CTExpChannel", "ExpChannel", PoolCounterTimer, "expchan/{ctrl_name}/{axis}", CounterTimerController), ET.ZeroDExpChannel : ("ZeroDExpChannel", "ExpChannel", Pool0DExpChannel, "expchan/{ctrl_name}/{axis}", ZeroDController), ET.OneDExpChannel : ("OneDExpChannel", "ExpChannel", Pool1DExpChannel, "expchan/{ctrl_name}/{axis}", OneDController), ET.TwoDExpChannel : ("TwoDExpChannel", "ExpChannel", Pool2DExpChannel, "expchan/{ctrl_name}/{axis}", TwoDController), ET.PseudoMotor : ("PseudoMotor", "Motor", PoolPseudoMotor, "pm/{ctrl_name}/{axis}", PseudoMotorController), ET.PseudoCounter : ("PseudoCounter", "ExpChannel", PoolPseudoCounter, "pc/{ctrl_name}/{axis}", PseudoCounterController), ET.MotorGroup : ("MotorGroup", "MotorGroup", PoolMotorGroup, "mg/{pool_name}/{name}", None), ET.MeasurementGroup : ("MeasurementGroup", "MeasurementGroup", PoolMeasurementGroup, "mntgrp/{pool_name}/{name}", None), ET.IORegister : ("IORegister", "IORegister" , PoolIORegister, "ioregister/{ctrl_name}/{axis}", IORegisterController), } class TypeData(object): """Information for a specific Element type""" def __init__(self, **kwargs): self.__dict__.update(kwargs) #: dictionary #: dict<:data:`~sardana.ElementType`, :class:`~sardana.pool.poolmetacontroller.TypeData`> TYPE_MAP_OBJ = {} for t, d in TYPE_MAP.items(): o = TypeData(type=t, name=d[0], family=d[1], klass=d[2] , auto_full_name=d[3], ctrl_klass=d[4]) TYPE_MAP_OBJ[t] = o class ControllerLibrary(SardanaLibrary): """Object representing a python module containning controller classes. Public members: - module - reference to python module - f_path - complete (absolute) path and filename - f_name - filename (including file extension) - path - complete (absolute) path - name - module name (without file extension) - controller_list - list - exc_info - exception information if an error occured when loading the module """ def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('pool') kwargs['elem_type'] = ElementType.ControllerLibrary SardanaLibrary.__init__(self, **kwargs) add_controller = SardanaLibrary.add_meta_class get_controller = SardanaLibrary.get_meta_class get_controllers = SardanaLibrary.get_meta_classes has_controller = SardanaLibrary.has_meta_class def serialize(self, *args, **kwargs): kwargs = SardanaLibrary.serialize(self, *args, **kwargs) kwargs['pool'] = self.get_manager().name kwargs['id'] = InvalidId return kwargs @property def controllers(self): return self.meta_classes class DataInfo(object): def __init__(self, name, dtype, dformat=DataFormat.Scalar, access=DataAccess.ReadWrite, description="", default_value=None, memorized='true', fget=None, fset=None, maxdimsize=None): self.name = name self.dtype = dtype self.dformat = dformat self.access = access self.description = description self.default_value = default_value self.memorized = memorized self.fget = fget or "get%s" % name self.fset = fset or "set%s" % name if maxdimsize == None: if dformat == DataFormat.Scalar: maxdimsize = () elif dformat == DataFormat.OneD: maxdimsize = 2048, elif dformat == DataFormat.TwoD: maxdimsize = 2048, 2048 self.maxdimsize = maxdimsize def copy(self): s = self d = DataInfo(s.name, s.dtype, dformat=s.dformat, access=s.access, description=s.description, default_value=s.default_value, memorized=s.memorized, fget=s.fget, fset=s.fset, maxdimsize=self.maxdimsize) return d @classmethod def toDataInfo(klass, name, info): info = CaselessDict(info) dtype = info[Type] dtype, dformat = to_dtype_dformat(dtype) default_value = info.get(DefaultValue) description = info.get(Description, '') daccess = info.get(Access, DataAccess.ReadWrite) daccess = to_daccess(daccess) memorized = info.get(Memorize, Memorized) maxdimsize = info.get(MaxDimSize) fget = info.get(FGet) fset = info.get(FSet) if default_value is not None and dtype != DataType.String: if type(default_value) in types.StringTypes: default_value = eval(default_value) return DataInfo(name, dtype, dformat=dformat, access=daccess, description=description, default_value=default_value, memorized=memorized, fget=fget, fset=fset, maxdimsize=maxdimsize) def toDict(self): return { 'name' : self.name, 'type' : DataType.whatis(self.dtype), 'format' : DataFormat.whatis(self.dformat), 'access' : DataAccess.whatis(self.access), 'description' : self.description, 'default_value' : self.default_value, 'memorized' : self.memorized, 'maxdimsize' : self.maxdimsize } def serialize(self, *args, **kwargs): kwargs.update(self.toDict()) return kwargs def __repr__(self): return "{0}(name={1}, type={2}, format={3}, access={4})".format( self.__class__.__name__, self.name, DataType[self.dtype], DataFormat[self.dformat], DataAccess[self.access]) #class PropertyInfo(DataInfo): # def __init__(self, name, dtype, dformat=DataFormat.Scalar, # description="", default_value=None): # DataInfo.__init__(self, name, dtype, dformat, access=DataAcces.ReadWrite, # description=description, default_value=default_value) #class AttributeInfo(DataInfo): # def __init__(self, name, dtype, dformat=DataFormat.Scalar, # access=DataAccess.ReadWrite, description=""): # DataInfo.__init__(self, name, dtype, dformat, access=DataAcces.ReadWrite, # description=description, default_value=None) class ControllerClass(SardanaClass): """Object representing a python controller class. Public members: - name - class name - klass - python class object - lib - ControllerLibrary object representing the module where the controller is.""" def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('pool') kwargs['elem_type'] = ElementType.ControllerClass SardanaClass.__init__(self, **kwargs) self.types = [] self.dict_extra = {} self.api_version = 1 klass = self.klass # Generic controller information self.ctrl_features = tuple(klass.ctrl_features) self.ctrl_properties = props = CaselessDict() for k, v in klass.class_prop.items(): # old member props[k] = DataInfo.toDataInfo(k, v) for k, v in klass.ctrl_properties.items(): props[k] = DataInfo.toDataInfo(k, v) self.ctrl_attributes = ctrl_attrs = CaselessDict() for k, v in klass.ctrl_attributes.items(): ctrl_attrs[k] = DataInfo.toDataInfo(k, v) self.axis_attributes = axis_attrs = CaselessDict() for k, v in klass.ctrl_extra_attributes.items(): # old member axis_attrs[k] = DataInfo.toDataInfo(k, v) for k, v in klass.axis_attributes.items(): axis_attrs[k] = DataInfo.toDataInfo(k, v) self.types = types = self.__build_types() self.type_names = map(ElementType.whatis, types) if ElementType.PseudoMotor in types: self.motor_roles = tuple(klass.motor_roles) self.pseudo_motor_roles = tuple(klass.pseudo_motor_roles) if len(self.pseudo_motor_roles) == 0: self.pseudo_motor_roles = (klass.__name__,) self.dict_extra['motor_roles'] = self.motor_roles self.dict_extra['pseudo_motor_roles'] = self.pseudo_motor_roles if ElementType.PseudoCounter in types: self.counter_roles = tuple(klass.counter_roles) self.pseudo_counter_roles = tuple(klass.pseudo_counter_roles) if len(self.pseudo_counter_roles) == 0: self.pseudo_counter_roles = (klass.__name__,) self.dict_extra['counter_roles'] = self.counter_roles self.dict_extra['pseudo_counter_roles'] = self.pseudo_counter_roles if ElementType.IORegister in types: self.dict_extra['predefined_values'] = klass.predefined_values init_args = inspect.getargspec(klass.__init__) if init_args.varargs is None or init_args.keywords is None: self.api_version = 0 def __build_types(self): types = [] klass = self.klass for _type, type_data in TYPE_MAP_OBJ.items(): if not _type in TYPE_ELEMENTS: continue if issubclass(klass, type_data.ctrl_klass): types.append(_type) return types def serialize(self, *args, **kwargs): kwargs = SardanaClass.serialize(self, *args, **kwargs) kwargs['id'] = InvalidId kwargs['pool'] = self.get_manager().name kwargs['gender'] = self.gender kwargs['model'] = self.model kwargs['organization'] = self.organization kwargs['types'] = self.type_names if len(self.type_names): kwargs['main_type'] = self.type_names[0] else: kwargs['main_type'] = None kwargs['api_version'] = self.api_version kwargs.update(self.dict_extra) return kwargs @property def controller_class(self): return self.klass @property def gender(self): return self.klass.gender @property def model(self): return self.klass.model @property def organization(self): return self.klass.organization sardana-1.2.0/src/sardana/pool/poolmonitor.py0000644000234100017500000001273312174204313022637 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This file contains the pool monitor class""" __all__ = ["PoolMonitor"] __docformat__ = 'restructuredtext' import threading import time from taurus.core.util import Logger from sardana import ElementType, TYPE_PSEUDO_ELEMENTS from .poolobject import PoolObject class PoolMonitor(Logger, threading.Thread): MIN_THREADS = 1 MAX_THREADS = 10 def __init__(self, pool, name='PoolMonitor', period=5.0, min_sleep=1.0, auto_start=True): Logger.__init__(self, name) threading.Thread.__init__(self, name=name) self.daemon = True self._period = period self._min_sleep = min_sleep self._pool = pool self._stop = False self._pause = threading.Event() self._thread_pool = None self._ctrl_ids = [] self._elem_ids = [] pool.add_listener(self.on_pool_changed) if not auto_start: self.pause() self.start() def on_pool_changed(self, evt_src, evt_type, evt_value): evt_name = evt_type.name.lower() if "created" in evt_name or "deleted" in evt_name: pool = self._pool pool_ctrls = pool.get_elements_by_type(ElementType.Controller) pool_ctrls.sort(key=PoolObject.get_id) ctrl_ids = [] elem_ids = [] for pool_ctrl in pool_ctrls: if not pool_ctrl.is_online(): continue types = set(pool_ctrl.get_ctrl_types()) if types.isdisjoint(TYPE_PSEUDO_ELEMENTS): ctrl_ids.append(pool_ctrl.id) elem_ids.extend(pool_ctrl.get_element_ids().keys()) elem_ids.sort() self._elem_ids = elem_ids self._ctrl_ids = ctrl_ids def update_state_info(self): """Update state information of every element.""" pool = self._pool elems, ctrls, ctrl_items = [], [], {} try: blocked_ctrls = set() for elem_id in self._elem_ids: elem = pool.get_element_by_id(elem_id) ctrl = elem.controller if elem.is_in_operation(): blocked_ctrls.add(ctrl) continue if ctrl in blocked_ctrls: continue ret = elem.lock(blocking=False) if ret: elems.append(elem) ctrl_elems = ctrl_items.get(ctrl) if ctrl_elems is None: ctrl_items[ctrl] = ctrl_elems = [] ctrl_elems.append(elem) else: blocked_ctrls.add(ctrl) for ctrl, ctrl_elems in ctrl_items.items(): ret = ctrl.lock(blocking=False) if ret: ctrls.append(ctrl) else: for elem in reversed(ctrl_elems): elem.unlock() elems.remove(elem) self._update_state_info_serial(ctrl_items) finally: for ctrl in reversed(ctrls): ctrl.unlock() for elem in reversed(elems): elem.unlock() def _update_state_info_serial(self, pool_ctrls): for pool_ctrl, elems in pool_ctrls.items(): self._update_ctrl_state_info(pool_ctrl, elems) def _update_ctrl_state_info(self, pool_ctrl, elems): axes = [ elem.axis for elem in elems ] state_infos, exc_info = pool_ctrl.raw_read_axis_states(axes) if len(exc_info): self.info("STATE ERROR %s", exc_info) for elem, state_info in state_infos.items(): state_info = elem._from_ctrl_state_info(state_info) elem.set_state_info(state_info) def stop(self): self.resume() self._stop = True def pause(self): self._pause.clear() def resume(self): self._pause.set() def monitor(self): ret = self.update_state_info() def run(self): nap_time = period = self._period i, startup = 0, time.time() while True: if self._stop: break time.sleep(nap_time) self._pause.wait() self.monitor() finish = time.time() nap_time = -1 while nap_time < 0: i += 1 nap_time = (startup + i*self._period) - finish sardana-1.2.0/src/sardana/pool/poolmotion.py0000644000234100017500000004646712174204313022470 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the class for a motion""" __all__ = ["MotionState", "MotionMap", "PoolMotion", "PoolMotionItem"] __docformat__ = 'restructuredtext' import time from taurus.core.util import Enumeration, DebugIt from sardana import State from poolaction import ActionContext, PoolActionItem, PoolAction #: enumeration representing possible motion states MotionState = Enumeration("MotionSate", ( \ "Stopped", # "StoppedOnError", # "StoppedOnAbort", "Moving", "MovingBacklash", "MovingInstability", "Invalid")) MS = MotionState MovingStates = MS.Moving, MS.MovingBacklash, MS.MovingInstability StoppedStates = MS.Stopped, #MS.StoppedOnError, MS.StoppedOnAbort #MotionAction = Enumeration("MotionAction", ( \ # "StartMotion", # "Finish", # "Abort", # "NoAction", # "Invalid") ) #MA = MotionAction MotionMap = { #MS.Stopped : State.On, MS.Moving : State.Moving, MS.MovingBacklash : State.Moving, MS.MovingInstability : State.Moving, MS.Invalid : State.Invalid, } class PoolMotionItem(PoolActionItem): """An item involved in the motion. Maps directly to a motor object""" def __init__(self, moveable, position, dial_position, do_backlash, backlash, instability_time=None): PoolActionItem.__init__(self, moveable) self.position = position self.interrupted = False self.dial_position = dial_position self.do_backlash = do_backlash self.backlash = backlash self.instability_time = instability_time self.old_motion_state = MS.Invalid self.motion_state = MS.Stopped self.start_time = None self.stop_time = None self.stop_final_time = None self.old_state_info = State.Invalid, "Uninitialized", \ (False, False, False) self.state_info = State.On, "Uninitialized", (False, False, False) def has_instability_time(self): return self.instability_time is not None def in_motion(self): return self.motion_state in MovingStates def get_moveable(self): return self.element moveable = property(fget=get_moveable) def get_state_info(self): si = self.state_info return MotionMap.get(self.motion_state, si[0]), si[1], si[2] def start(self, new_state): self.old_state_info = self.state_info self.state_info = new_state, self.state_info[1], self.state_info[2] def stopped(self, timestamp): self.stop_time = timestamp if self.instability_time is None: self.stop_final_time = timestamp new_ms = MS.Stopped else: new_ms = MS.MovingInstability return new_ms def handle_instability(self, timestamp): new_ms = MS.MovingInstability dt = timestamp - self.stop_time if dt >= self.instability_time: self.stop_final_time = timestamp new_ms = MS.Stopped return new_ms def on_state_switch(self, state_info, timestamp=None): if timestamp is None: timestamp = time.time() self.old_state_info = self.state_info self.state_info = state_info old_state = self.old_state_info[0] state = state_info[0] new_ms = ms = self.motion_state moveable = self.moveable self.interrupted = moveable.was_interrupted() if self.interrupted: if ms == MS.MovingInstability: new_ms = self.handle_instability(timestamp) elif state == State.Moving: new_ms = MS.Moving elif old_state == State.Moving: new_ms = self.stopped(timestamp) elif ms == MS.Stopped: if state == State.Moving: self.start_time = timestamp new_ms = MS.Moving elif ms == MS.Moving: if state != State.Moving: if self.do_backlash and state == State.On: new_ms = MS.MovingBacklash else: new_ms = self.stopped(timestamp) elif ms == MS.MovingBacklash: if state != State.Moving: new_ms = self.stopped(timestamp) elif ms == MS.MovingInstability: new_ms = self.handle_instability(timestamp) self.old_motion_state, self.motion_state = ms, new_ms return ms, new_ms _NON_ERROR_STATES = State.On, State.Moving, State.Running class PoolMotion(PoolAction): """This class manages motion actions""" def __init__(self, main_element, name="GlobalMotion"): PoolAction.__init__(self, main_element, name) self._motion_info = None self._motion_sleep_time = None self._nb_states_per_position = None def _recover_start_error(self, ctrl, meth_name, read_state=False): self.error("%s throws exception on %s. Stopping...", ctrl, meth_name) self.debug("Details:", exc_info=1) self.emergency_break() if read_state: states = {} self.read_state_info(ret=states) for moveable, state_info in states.items(): state_info = moveable._from_ctrl_state_info(state_info) moveable._set_state_info(state_info) def pre_start_all(self, pool_ctrls): # PreStartAll on all controllers for pool_ctrl in pool_ctrls: try: pool_ctrl.ctrl.PreStartAll() except: self._recover_start_error(pool_ctrl, "PreStartAll") raise def pre_start_one(self, moveables, items): # PreStartOne on all elements for moveable in moveables: pool_ctrl = moveable.controller ctrl, axis = pool_ctrl.ctrl, moveable.axis dial = items[moveable][1] ret = ctrl.PreStartOne(axis, dial) if not ret: try: msg = "%s.PreStartOne(%s(%d), %f) returns False" \ % (pool_ctrl.name, moveable.name, axis, dial) raise Exception(msg) except: self._recover_start_error(pool_ctrl, "PreStartOne") raise def start_one(self, moveables, motion_info): # StartOne on all elements for moveable in moveables: pool_ctrl = moveable.controller ctrl = pool_ctrl.ctrl axis = moveable.axis dial_position = motion_info[moveable].dial_position try: ctrl.StartOne(axis, dial_position) except: self._recover_start_error(pool_ctrl, "StartOne") raise def start_all(self, pool_ctrls, moveables, motion_info): # Change the state to Moving for moveable in moveables: moveable_info = motion_info[moveable] moveable.set_state(State.Moving, propagate=2) state_info = moveable.inspect_state(), \ moveable.inspect_status(), \ moveable.inspect_limit_switches() moveable_info.on_state_switch(state_info) # StartAll on all controllers for pool_ctrl in pool_ctrls: try: pool_ctrl.ctrl.StartAll() except: self._recover_start_error(pool_ctrl, "StartOne", read_state=True) raise def start_action(self, *args, **kwargs): """kwargs['items'] is a dict. ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for""" __all__ = ["PoolMotor"] __docformat__ = 'restructuredtext' import time import math from sardana import EpsilonError, State, ElementType from sardana.sardanaattribute import SardanaAttribute, ScalarNumberAttribute, \ SardanaSoftwareAttribute from sardana.sardanaevent import EventType from sardana.sardanautils import assert_type, is_number from poolelement import PoolElement from poolmotion import PoolMotion, MotionState class Position(SardanaAttribute): def __init__(self, *args, **kwargs): super(Position, self).__init__(*args, **kwargs) self.get_offset().add_listener(self.on_change) self.get_sign().add_listener(self.on_change) self.get_dial().add_listener(self.on_change) def get_dial(self): return self.obj.get_dial_position_attribute() def get_offset(self): return self.obj.get_offset_attribute() def get_sign(self): return self.obj.get_sign_attribute() def _in_error(self): return self.get_dial().in_error() def _has_value(self): return self.get_dial().has_value() def _has_write_value(self): return self.get_dial().has_write_value() def _get_value(self): return self.calc_position() def _get_write_value(self): dial = self.get_dial().get_write_value() return self.calc_position(dial=dial) def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): raise Exception("Cannot set position value for %s" % self.obj.name) def _set_write_value(self, w_value, timestamp=None, propagate=1): # let the write value be stored by dial using the current offset and # sign. This way, retrieving the write value is done in reverse applying # the offset and sign in use at that time w_dial = self.calc_dial_position(w_value) self.get_dial().set_write_value(w_dial, timestamp=timestamp, propagate=0) self.fire_write_event(propagate=propagate) def _get_exc_info(self): return self.get_dial().get_exc_info() def _get_timestamp(self): return self.get_dial().get_timestamp() def _get_write_timestamp(self): return self.get_dial().get_write_timestamp() def calc_position(self, dial=None): """Returns the computed position from last the dial position from the given parameter or (if None), the last dial position obtained from hardware read. :param dial: the new dial position [default: None, meaning use the current dial position. :return: the computed user position :rtype: obj :raises: :exc:`Exception` if dial_position is None and no read value has been set yet""" obj = self.obj if dial is None: dial_attr = obj.dial_position if dial_attr.in_error(): raise dial_attr.exc_info[1] dial = dial_attr.value if not is_number(dial): raise Exception("Controller returns not a number %s" % dial) sign, offset = obj.sign.value, obj.offset.value return sign*dial + offset def calc_dial_position(self, position=None): """Returns the dial position for the given position. If position is not given (or is None) it uses this object's *write* value. :param position: the position to be converted to dial [default: None meaning use the this attribute's *write* value :type position: obj :return: the computed dial position :rtype: obj""" obj = self.obj if position is None: position = self.w_value sign, offset = obj.sign.value, obj.offset.value return (position-offset) / sign def calc_motion(self, new_position): """Calculate the motor position, dial position, backlash for the given final position.""" obj = self.obj ctrl = obj.controller step_per_unit = obj._step_per_unit backlash = obj._backlash # compute dial position new_dial = self.calc_dial_position(new_position) # add backlash if necessary do_backlash = False if obj.has_backlash() and not ctrl.has_backlash(): dial_attr = self.get_dial() if dial_attr.in_error(): raise dial_attr.get_exc_info()[1] old_dial = dial_attr.value displacement = new_dial - old_dial if math.fabs(displacement) > EpsilonError: positive_displacement = displacement > 0 positive_backlash = self.is_backlash_positive() do_backlash = positive_backlash != positive_displacement if do_backlash: new_dial = new_dial - backlash / step_per_unit # compute a rounding value if necessary if ctrl.wants_rounding(): nb_step = round(new_dial * step_per_unit) new_dial = nb_step / step_per_unit backlash_position = new_dial if do_backlash: backlash_position = new_dial + backlash / step_per_unit return new_position, new_dial, do_backlash, backlash_position def on_change(self, evt_src, evt_type, evt_value): self.fire_read_event(propagate=evt_type.priority) def update(self, cache=True, propagate=1): self.get_dial().update(cache=cache, propagate=propagate) class DialPosition(ScalarNumberAttribute): def update(self, cache=True, propagate=1): if not cache or not self.has_value(): dial_position_value = self.obj.read_dial_position() self.set_value(dial_position_value, propagate=propagate) class LimitSwitches(ScalarNumberAttribute): pass class Offset(SardanaSoftwareAttribute): pass class Sign(SardanaSoftwareAttribute): pass class PoolMotor(PoolElement): """An internal Motor object. **NOT** part of the official API. Accessing this object from a controller plug-in may lead to undetermined behavior like infinite recursion.""" def __init__(self, **kwargs): kwargs['elem_type'] = ElementType.Motor PoolElement.__init__(self, **kwargs) on_change = self.on_change self._offset = Offset(self, initial_value=0, listeners=on_change) self._sign = Sign(self, initial_value=1, listeners=on_change) self._dial_position = DialPosition(self, listeners=on_change) self._position = Position(self, listeners=on_change) self._backlash = 0 self._step_per_unit = 1.0 self._limit_switches = LimitSwitches(self, name="Limit_switches", initial_value=3*(False,), listeners=on_change) self._acceleration = None self._deceleration = None self._velocity = None self._base_rate = None self._instability_time = None self._in_start_move = False motion_name = "%s.Motion" % self._name self.set_action_cache(PoolMotion(self, motion_name)) # -------------------------------------------------------------------------- # Event forwarding # -------------------------------------------------------------------------- def on_change(self, evt_src, evt_type, evt_value): # forward all events coming from attributes to the listeners self.fire_event(evt_type, evt_value) # -------------------------------------------------------------------------- # state information # -------------------------------------------------------------------------- def _from_ctrl_state_info(self, state_info): state_info, _ = state_info try: state_str = State.whatis(state_info) return int(state_info), "{0} is in {1}".format(self.name, state_str), 0 except KeyError: pass if len(state_info) > 2: state, status, ls = state_info[:3] else: state, other = state_info[:2] if is_number(other): ls, status = other, '' else: ls, status = 0, other state, ls = int(state), tuple(map(bool, (ls&1,ls&2,ls&4))) return state, status, ls def _set_state_info(self, state_info, propagate=1): PoolElement._set_state_info(self, state_info, propagate=propagate) ls = state_info[-1] if self._sign.value < 0: ls = ls[0], ls[2], ls[1] self._set_limit_switches(ls, propagate=propagate) # -------------------------------------------------------------------------- # state information # -------------------------------------------------------------------------- _STD_STATUS = "{name} is {state}{limit_switches}{ctrl_status}" def calculate_state_info(self, state_info=None): if state_info is None: state = self._state status = self._status ls = self._limit_switches.value else: state, status, ls = state_info if state == State.On: state_str = "Stopped" elif state == State.Moving: state_str = "Moving" motion = self.get_operation() if motion is None: state_str += " (external)" else: motion_state = motion._motion_info[self].motion_state if motion_state == MotionState.MovingBacklash: state_str += " (backlash)" elif motion_state == MotionState.MovingInstability: state_str += " (instability)" else: state_str = "in " + State[state] limit_switches = "" if ls[0]: limit_switches += ". Hit home switch" if ls[1]: limit_switches += ". Hit upper switch" if ls[2]: limit_switches += ". Hit lower switch" if len(status) > 0: status = "\n" + status new_status = self._STD_STATUS.format(name=self.name, state=state_str, limit_switches=limit_switches, ctrl_status=status) return state, new_status, ls # -------------------------------------------------------------------------- # limit switches # -------------------------------------------------------------------------- def inspect_limit_switches(self): """returns the current (cached value of the limit switches :return: the current limit switches flags""" return self._limit_switches def get_limit_switches(self, cache=True, propagate=1): """Returns the motor limit switches state. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the motor limit switches state :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" self.get_state(cache=cache, propagate=propagate) return self._limit_switches def set_limit_switches(self, ls, propagate=1): self._set_limit_switches(ls, propagate=propagate) def put_limit_switches(self, ls, propagate=1): self._limit_switches = tuple(ls) def _set_limit_switches(self, ls, propagate=1): self._limit_switches.set_value(tuple(ls), propagate=propagate) limit_switches = property(get_limit_switches, set_limit_switches, doc="motor limit switches") # -------------------------------------------------------------------------- # instability time # -------------------------------------------------------------------------- def has_instability_time(self, cache=True): it = self._instability_time return it is not None and it > 0.0 def get_instability_time(self, cache=True): return self._instability_time def set_instability_time(self, instability_time, propagate=1): self._instability_time = instability_time if propagate > 0: self.fire_event(EventType("instability_time", priority=propagate), instability_time) instability_time = property(get_instability_time, set_instability_time, doc="motor instability time") # -------------------------------------------------------------------------- # backlash # -------------------------------------------------------------------------- def has_backlash(self, cache=True): return self._backlash != 0 def is_backlash_positive(self, cache=True): return self._backlash > 0 def is_backlash_negative(self, cache=True): return self._backlash < 0 def get_backlash(self, cache=True): return self._backlash def set_backlash(self, backlash, propagate=1): self._backlash = backlash if propagate > 0: self.fire_event(EventType("backlash", priority=propagate), backlash) backlash = property(get_backlash, set_backlash, doc="motor backlash") # -------------------------------------------------------------------------- # offset # -------------------------------------------------------------------------- def get_offset_attribute(self): return self._offset def get_offset(self, cache=True): return self._offset def set_offset(self, offset, propagate=1): self._offset.set_value(offset, propagate=propagate) offset = property(get_offset, set_offset, doc="motor offset") # -------------------------------------------------------------------------- # sign # -------------------------------------------------------------------------- def get_sign_attribute(self): return self._sign def get_sign(self, cache=True): return self._sign def set_sign(self, sign, propagate=1): old_sign = self._sign.value self._sign.set_value(sign, propagate=propagate) # invert lower with upper limit switches and send event in case of change ls = self._limit_switches if old_sign != sign and ls.has_value(): value = ls.value value = value[0], value[2], value[1] self._set_limit_switches(value, propagate=propagate) sign = property(get_sign, set_sign, doc="motor sign") # -------------------------------------------------------------------------- # step per unit # -------------------------------------------------------------------------- def get_step_per_unit(self, cache=True, propagate=1): if not cache or self._step_per_unit is None: step_per_unit = self.read_step_per_unit() self._set_step_per_unit(step_per_unit, propagate=propagate) return self._step_per_unit def set_step_per_unit(self, step_per_unit, propagate=1): if step_per_unit <= 0.0: raise Exception("Step per unit must be > 0.0") self.controller.set_axis_par(self.axis, "step_per_unit", step_per_unit) self._set_step_per_unit(step_per_unit, propagate=propagate) def _set_step_per_unit(self, step_per_unit, propagate=1): self._step_per_unit = step_per_unit if propagate: self.fire_event(EventType("step_per_unit", priority=propagate), step_per_unit) # force ask controller for new position to send priority event self.get_position(cache=False, propagate=2) def read_step_per_unit(self): step_per_unit = self.controller.get_axis_par(self.axis, "step_per_unit") assert_type(float, step_per_unit) return step_per_unit step_per_unit = property(get_step_per_unit, set_step_per_unit, doc="motor steps per unit") # -------------------------------------------------------------------------- # acceleration # -------------------------------------------------------------------------- def get_acceleration(self, cache=True, propagate=1): if not cache or self._acceleration is None: acceleration = self.read_acceleration() self._set_acceleration(acceleration, propagate=propagate) return self._acceleration def set_acceleration(self, acceleration, propagate=1): self.controller.set_axis_par(self.axis, "acceleration", acceleration) self._set_acceleration(acceleration, propagate=propagate) def _set_acceleration(self, acceleration, propagate=1): self._acceleration = acceleration if not propagate: return self.fire_event(EventType("acceleration", priority=propagate), acceleration) def read_acceleration(self): acceleration = self.controller.get_axis_par(self.axis, "acceleration") assert_type(float, acceleration) return acceleration acceleration = property(get_acceleration, set_acceleration, doc="motor acceleration") # -------------------------------------------------------------------------- # deceleration # -------------------------------------------------------------------------- def get_deceleration(self, cache=True, propagate=1): if not cache or self._deceleration is None: deceleration = self.read_deceleration() self._set_deceleration(deceleration, propagate=propagate) return self._deceleration def set_deceleration(self, deceleration, propagate=1): self.controller.set_axis_par(self.axis, "deceleration", deceleration) self._set_deceleration(deceleration, propagate=propagate) def _set_deceleration(self, deceleration, propagate=1): self._deceleration = deceleration if not propagate: return self.fire_event(EventType("deceleration", priority=propagate), deceleration) def read_deceleration(self): deceleration = self.controller.get_axis_par(self.axis, "deceleration") assert_type(float, deceleration) return deceleration deceleration = property(get_deceleration, set_deceleration, doc="motor deceleration") # -------------------------------------------------------------------------- # base_rate # -------------------------------------------------------------------------- def get_base_rate(self, cache=True, propagate=1): if not cache or self._base_rate is None: base_rate = self.read_base_rate() self._set_base_rate(base_rate, propagate=propagate) return self._base_rate def set_base_rate(self, base_rate, propagate=1): self.controller.set_axis_par(self.axis, "base_rate", base_rate) self._set_base_rate(base_rate, propagate=propagate) def _set_base_rate(self, base_rate, propagate=1): self._base_rate = base_rate if not propagate: return self.fire_event(EventType("base_rate", priority=propagate), base_rate) def read_base_rate(self): base_rate = self.controller.get_axis_par(self.axis, "base_rate") assert_type(float, base_rate) return base_rate base_rate = property(get_base_rate, set_base_rate, doc="motor base rate") # -------------------------------------------------------------------------- # velocity # -------------------------------------------------------------------------- def get_velocity(self, cache=True, propagate=1): if not cache or self._velocity is None: velocity = self.read_velocity() self._set_velocity(velocity, propagate=propagate) return self._velocity def set_velocity(self, velocity, propagate=1): self.controller.set_axis_par(self.axis, "velocity", velocity) self._set_velocity(velocity, propagate=propagate) def _set_velocity(self, velocity, propagate=1): self._velocity = velocity if not propagate: return self.fire_event(EventType("velocity", priority=propagate), velocity) def read_velocity(self): velocity = self.controller.get_axis_par(self.axis, "velocity") assert_type(float, velocity) return velocity velocity = property(get_velocity, set_velocity, doc="motor velocity") # -------------------------------------------------------------------------- # position & dial position # -------------------------------------------------------------------------- def define_position(self, position): dial = self.get_position_attribute().calc_dial_position(position) self.controller.define_position(self.axis, dial) # force an event with the new position self.get_position(cache=False, propagate=2) def get_position_attribute(self): """Returns the position attribute object for this motor :return: the position attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._position def get_position(self, cache=True, propagate=1): """Returns the user position. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the user position :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" position = self._position position.update(cache=cache, propagate=propagate) return position def set_position(self, position): """Moves the motor to the specified user position :param position: the user position to move to :type position: :class:`~numbers.Number`""" self.start_move(position) def set_write_position(self, w_position, timestamp=None, propagate=1): """Sets a new write value for the user position. :param w_position: the new write value for user position :type w_position: :class:`~numbers.Number` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" self._position.set_write_value(w_position, timestamp=timestamp, propagate=propagate) def read_dial_position(self): """Reads the dial position from hardware. :return: a :class:`~sardana.sardanavalue.SardanaValue` containing the dial position :rtype: :class:`~sardana.sardanavalue.SardanaValue`""" return self.motion.read_dial_position(serial=True)[self] def put_dial_position(self, dial_position_value, propagate=1): """Sets a new dial position. :param dial_position_value: the new dial position value :type dial_position_value: :class:`~sardana.sardanavalue.SardanaValue` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" dp = self._dial_position dp.set_value(dial_position_value, propagate=propagate) return dp def get_dial_position_attribute(self): """Returns the dial position attribute object for this motor :return: the dial position attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._dial_position def get_dial_position(self, cache=True, propagate=1): """Returns the dial position. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the dial position :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" dp = self._dial_position dp.update(cache=cache, propagate=propagate) return dp position = property(get_position, set_position, doc="motor user position") dial_position = property(get_dial_position, doc="motor dial position") # -------------------------------------------------------------------------- # default acquisition channel # -------------------------------------------------------------------------- def get_default_attribute(self): return self.get_position_attribute() # -------------------------------------------------------------------------- # motion # -------------------------------------------------------------------------- def get_motion(self): return self.get_action_cache() motion = property(get_motion, doc="motion object") # -------------------------------------------------------------------------- # motion calculation # -------------------------------------------------------------------------- def calculate_motion(self, new_position, items=None, calculated=None): """Calculate the motor position, dial position, backlash for the given final position. Items specifies the where to put the calculated values, calculated is not used by physical motors""" step_per_unit = self._step_per_unit backlash = self._backlash ctrl = self.controller pos_attr = self.get_position_attribute() # compute dial position new_dial = pos_attr.calc_dial_position(new_position) # add backlash if necessary do_backlash = False if self.has_backlash() and not ctrl.has_backlash(): dial_attr = self.get_dial_position_attribute() if dial_attr.in_error(): raise dial_attr.get_exc_info()[1] old_dial = dial_attr.value displacement = new_dial - old_dial if math.fabs(displacement) > EpsilonError: positive_displacement = displacement > 0 positive_backlash = self.is_backlash_positive() do_backlash = positive_backlash != positive_displacement if do_backlash: new_dial = new_dial - backlash / step_per_unit # compute a rounding value if necessary if ctrl.wants_rounding(): nb_step = round(new_dial * step_per_unit) new_dial = nb_step / step_per_unit backlash_position = new_dial if do_backlash: backlash_position = new_dial + backlash / step_per_unit if items is None: items = {} items[self] = new_position, new_dial, do_backlash, backlash_position return items def start_move(self, new_position): self._in_start_move = True try: return self._start_move(new_position) finally: self._in_start_move = False def _start_move(self, new_position): if not self._simulation_mode: # update the dial value from the controller in case motor has been # moved outside sardana. # TODO: also update step_per_unit self.get_dial_position_attribute().update(cache=False, propagate=1) # calculate the motion (dial position, backlash, etc) items = self.calculate_motion(new_position) self.debug("Start motion user=%f, dial=%f, backlash? %s, " "dial_backlash=%f", *items[self]) timestamp = time.time() # update the write position self.set_write_position(items[self][0], timestamp=timestamp, propagate=0) # move! self.motion.run(items=items) sardana-1.2.0/src/sardana/pool/poolmotorgroup.py0000644000234100017500000002404412174204313023363 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for""" __all__ = [ "PoolMotorGroup" ] __docformat__ = 'restructuredtext' import time import collections from sardana import ElementType from sardana.sardanaattribute import SardanaAttribute from .poolgroupelement import PoolGroupElement from .poolmotion import PoolMotion class Position(SardanaAttribute): def __init__(self, *args, **kwargs): self._w_value_map = None super(Position, self).__init__(*args, **kwargs) for pos_attr in self.obj.get_physical_position_attribute_iterator(): pos_attr.add_listener(self.on_change) def _has_value(self): for pos_attr in self.obj.get_physical_position_attribute_iterator(): if not pos_attr.has_value(): return False return True def _in_error(self): for pos_attr in self.obj.get_physical_position_attribute_iterator(): if pos_attr.in_error(): return True return False def get_elements(self): return self.obj.get_user_elements() def get_element_nb(self): return len(self.get_user_elements()) def _get_exc_info(self): for position_attr in self.obj.get_physical_position_attribute_iterator(): if position_attr.error: return position_attr.get_exc_info() def _get_timestamp(self): return max( [ pos_attr.timestamp for pos_attr in self.obj.get_physical_position_attribute_iterator() ] ) def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): raise Exception("Cannot set position value for motor group %s" % self.obj.name) def _get_value(self): return [ position.value for position in self.obj.get_physical_position_attribute_iterator() ] def _get_write_value(self): return [ position.w_value for position in self.obj.get_physical_position_attribute_iterator() ] def _set_write_value(self, w_value, timestamp=None, propagate=1): assert len(w_value) == self.get_element_nb() if isinstance(w_value, collections.Sequence): w_value_map = {} for v, elem in zip(w_value, self.get_elements()): w_value_map[elem] = v else: w_value_map = w_value w_value = [] for elem in self.get_elements(): w_value.append(w_value_map[elem]) self._w_value_map = w_value super(Position, self).set_write_value(w_value, timestamp=timestamp, propagate=propagate) def on_change(self, evt_src, evt_type, evt_value): self.fire_read_event(propagate=evt_type.priority) def update(self, cache=True, propagate=1): if cache: for phy_elem_pos in self.obj.get_low_level_physical_position_attribute_iterator(): if not phy_elem_pos.has_value(): cache = False break if not cache: dial_position_values = self.obj.motion.read_dial_position(serial=True) for motion_obj, position_value in dial_position_values.items(): motion_obj.put_dial_position(position_value, propagate=propagate) class PoolMotorGroup(PoolGroupElement): def __init__(self, **kwargs): self._physical_elements = [] self._in_start_move = False kwargs['elem_type'] = ElementType.MotorGroup PoolGroupElement.__init__(self, **kwargs) on_change = self.on_change self._position = Position(self, listeners=on_change) def _create_action_cache(self): motion_name = "%s.Motion" % self._name return PoolMotion(self, motion_name) # -------------------------------------------------------------------------- # Event forwarding # -------------------------------------------------------------------------- def on_change(self, evt_src, evt_type, evt_value): # forward all events coming from attributes to the listeners self.fire_event(evt_type, evt_value) def on_element_changed(self, evt_src, evt_type, evt_value): name = evt_type.name.lower() if name in ('state', 'position'): state, status = self._calculate_states() if name == 'state': propagate_state = evt_type.priority else: propagate_state = 0 self.set_state(state, propagate=propagate_state) self.set_status(status, propagate=propagate_state) def add_user_element(self, element, index=None): elem_type = element.get_type() if elem_type == ElementType.Motor: pass elif elem_type == ElementType.PseudoMotor: #TODO: make this happen pass else: raise Exception("element %s is not a motor" % element.name) PoolGroupElement.add_user_element(self, element, index=index) # -------------------------------------------------------------------------- # position # -------------------------------------------------------------------------- def get_position_attribute(self): return self._position def get_low_level_physical_position_attribute_iterator(self): return self.get_physical_elements_attribute_iterator() def get_physical_position_attribute_iterator(self): return self.get_user_elements_attribute_iterator() def get_physical_positions_attribute_sequence(self): return self.get_user_elements_attribute_sequence() def get_physical_positions_attribute_map(self): return self.get_user_elements_attribute_map() def get_position(self, cache=True, propagate=1): """Returns the user position. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the user position :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" position = self._position position.update(cache=cache, propagate=propagate) return position def set_position(self, positions): """Moves the motor group to the specified user positions :param positions: the user positions to move to :type positions: sequence< :class:`~numbers.Number` >""" self.start_move(positions) def set_write_position(self, w_position, timestamp=None, propagate=1): """Sets a new write value for the user position. :param w_position: the new write value for user position :type w_position: sequence< :class:`~numbers.Number` > :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" self._position.set_write_value(w_position, timestamp=timestamp, propagate=propagate) position = property(get_position, set_position, doc="motor group positions") # -------------------------------------------------------------------------- # default acquisition channel # -------------------------------------------------------------------------- def get_default_attribute(self): return self.get_position_attribute() # -------------------------------------------------------------------------- # motion # -------------------------------------------------------------------------- def get_motion(self): return self.get_action_cache() motion = property(get_motion, doc="motion object") # -------------------------------------------------------------------------- # motion calculation # -------------------------------------------------------------------------- def calculate_motion(self, new_positions, items=None): user_elements = self.get_user_elements() if items is None: items = {} calculated = {} for new_position, element in zip(new_positions, user_elements): calculated[element] = new_position for new_position, element in zip(new_positions, user_elements): element.calculate_motion(new_position, items=items, calculated=calculated) return items def start_move(self, new_position): self._in_start_move = True try: return self._start_move(new_position) finally: self._in_start_move = False def _start_move(self, new_positions): self._aborted = False items = self.calculate_motion(new_positions) timestamp = time.time() for item, position_info in items.items(): item.set_write_position(position_info[0], timestamp=timestamp, propagate=0) if not self._simulation_mode: self.motion.run(items=items) sardana-1.2.0/src/sardana/pool/poolmoveable.py0000644000234100017500000000317212174204314022740 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for moveable elements""" __all__ = [ "PoolMoveable" ] __docformat__ = 'restructuredtext' class PoolMoveable(object): def get_size(self): raise RuntimeError("Must be implemented in subclass") def calc_move(self, positions, ctrl_map, trust=False): raise RuntimeError("Must be implemented in subclass") def set_value(self, v, propagate=True): raise RuntimeError("Must be implemented in subclass") def get_value(self, cache=True): raise RuntimeError("Must be implemented in subclass")sardana-1.2.0/src/sardana/pool/poolobject.py0000644000234100017500000000341012174204313022406 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for Pool object""" __all__ = ["PoolObject"] __docformat__ = 'restructuredtext' from sardana.sardanabase import SardanaObjectID from .poolbaseobject import PoolBaseObject class PoolObject(SardanaObjectID, PoolBaseObject): """A Pool object that besides the name and reference to the pool has: - _id : the internal identifier""" def __init__(self, **kwargs): SardanaObjectID.__init__(self, id=kwargs.pop('id')) PoolBaseObject.__init__(self, **kwargs) def serialize(self, *args, **kwargs): kwargs = PoolBaseObject.serialize(self, *args, **kwargs) kwargs = SardanaObjectID.serialize(self, *args, **kwargs) return kwargs sardana-1.2.0/src/sardana/pool/poolonedexpchannel.py0000644000234100017500000000456512174204314024150 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for OneDExpChannel""" __all__ = [ "Pool1DExpChannel" ] __docformat__ = 'restructuredtext' from sardana import ElementType from sardana.sardanaevent import EventType from .poolbasechannel import PoolBaseChannel class Pool1DExpChannel(PoolBaseChannel): def __init__(self, **kwargs): self._data_source = None kwargs['elem_type'] = ElementType.OneDExpChannel PoolBaseChannel.__init__(self, **kwargs) # -------------------------------------------------------------------------- # data source # -------------------------------------------------------------------------- def get_data_source(self, cache=True, propagate=1): if not cache or self._data_source is None: data_source = self.read_data_source() self._set_data_source(data_source, propagate=propagate) return self._data_source def _set_data_source(self, data_source, propagate=1): self._data_source = data_source if not propagate: return self.fire_event(EventType("data_source", priority=propagate), data_source) def read_data_source(self): data_source = self.controller.get_axis_par(self.axis, "data_source") return data_source data_source = property(get_data_source, doc="source identifier for the 1D data") sardana-1.2.0/src/sardana/pool/poolpseudocounter.py0000644000234100017500000003344112174204314024047 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the PoolPseudoCounter class""" __all__ = [ "PoolPseudoCounter" ] __docformat__ = 'restructuredtext' import sys import time from sardana import State, ElementType, TYPE_PHYSICAL_ELEMENTS from sardana.sardanaattribute import SardanaAttribute from sardana.sardanaexception import SardanaException from sardana.sardanavalue import SardanaValue from .poolexception import PoolException from .poolbasechannel import PoolBaseChannel from .poolbasegroup import PoolBaseGroup from .poolacquisition import PoolAcquisition class Value(SardanaAttribute): def __init__(self, *args, **kwargs): self._exc_info = None super(Value, self).__init__(*args, **kwargs) for value_attr in self.obj.get_physical_value_attribute_iterator(): value_attr.add_listener(self.on_change) def _in_error(self): for value_attr in self.obj.get_physical_value_attribute_iterator(): if value_attr.error: return True return self._exc_info != None def _has_value(self): for value_attr in self.obj.get_physical_value_attribute_iterator(): if not value_attr.has_value(): return False return True def _get_value(self): return self.calc().value def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): raise Exception("Cannot set value for %s" % self.obj.name) def _get_write_value(self): w_values = self.get_physical_write_values() return self.calc_pseudo(physical_values=w_values).value def _set_write_value(self, w_value, timestamp=None, propagate=1): raise Exception("Cannot set write value for %s" % self.obj.name) def _get_exc_info(self): exc_info = self._exc_info if exc_info is None: for value_attr in self.obj.get_physical_value_attribute_iterator(): if value_attr.error: return value_attr.get_exc_info() return exc_info def _get_timestamp(self): timestamps = [ value_attr.timestamp for value_attr in self.obj.get_physical_value_attribute_iterator() ] if not len(timestamps): timestamps = self._local_timestamp, return max(timestamps) def get_physical_write_values(self): ret = [] for value_attr in self.obj.get_physical_value_attribute_iterator(): if value_attr.has_write_value(): value = value_attr.w_value else: if not value_attr.has_value(): # if underlying counter doesn't have value yet, it is # because of a cold start value_attr.update(propagate=0) if value_attr.in_error(): raise PoolException("Cannot get '%' value" % value_attr.obj.name, exc_info=value_attr.exc_info) value = value_attr.value ret.append(value) return ret def get_physical_values(self): ret = [] for value_attr in self.obj.get_physical_value_attribute_iterator(): # if underlying channel doesn't have value yet, it is because # of a cold start if not value_attr.has_value(): value_attr.update(propagate=0) if value_attr.in_error(): raise PoolException("Cannot get '%' value" % value_attr.obj.name, exc_info=value_attr.exc_info) ret.append(value_attr.value) return ret def calc(self, physical_values=None): try: obj = self.obj if physical_values is None: physical_values = self.get_physical_values() else: l_v, l_u = len(physical_values), len(obj.get_user_elements()) if l_v != l_u: raise IndexError("CalcPseudo(%s): must give %d physical " \ "values (you gave %d)" % (obj.name, l_u, l_v) ) ctrl, axis = obj.controller, obj.axis result = ctrl.calc(axis, physical_values) except SardanaException as se: result = SardanaValue(exc_info=se.exc_info) except: result = SardanaValue(exc_info=sys.exc_info()) return result def calc_all(self, physical_values=None): try: obj = self.obj if physical_values is None: physical_values = self.get_physical_values() else: l_v, l_u = len(physical_values), len(obj.get_user_elements()) if l_v != l_u: raise IndexError("CalcAllPseudo(%s): must give %d physical " \ "values (you gave %d)" % (obj.name, l_u, l_v) ) ctrl, axis = obj.controller, obj.axis result = ctrl.calc_all(axis, physical_values) except SardanaException as se: result = SardanaValue(exc_info=se.exc_info) except: result = SardanaValue(exc_info=sys.exc_info()) return result def on_change(self, evt_src, evt_type, evt_value): self.fire_read_event(propagate=evt_type.priority) def update(self, cache=True, propagate=1): if cache: for phy_elem_val in self.obj.get_low_level_physical_value_attribute_iterator(): if not phy_elem_val.has_value(): cache = False break if not cache: values = self.obj.acquisition.read_value(serial=True) if not len(values): self._local_timestamp = time.time() for acq_obj, value in values.items(): acq_obj.put_value(value, propagate=propagate) class PoolPseudoCounter(PoolBaseGroup, PoolBaseChannel): """A class representing a Pseudo Counter in the Sardana Device Pool""" ValueAttributeClass = Value AcquisitionClass = None def __init__(self, **kwargs): self._siblings = None user_elements = kwargs.pop('user_elements') kwargs['elem_type'] = ElementType.PseudoCounter # don't switch the order of constructors! PoolBaseGroup.__init__(self, user_elements=user_elements, pool=kwargs['pool']) PoolBaseChannel.__init__(self, **kwargs) def serialize(self, *args, **kwargs): kwargs = PoolBaseChannel.serialize(self, *args, **kwargs) elements = [ elem.name for elem in self.get_user_elements() ] physical_elements = [] for elem_list in self.get_physical_elements().values(): for elem in elem_list: physical_elements.append(elem.name) cl_name = self.__class__.__name__ cl_name = cl_name[4:] kwargs['elements'] = elements kwargs['physical_elements'] = physical_elements return kwargs def on_element_changed(self, evt_src, evt_type, evt_value): name = evt_type.name.lower() # always calculate state. status_info = self._calculate_states() state, status = self.calculate_state_info(status_info=status_info) state_propagate = 0 status_propagate = 0 if name == 'state': state_propagate = evt_type.priority elif name == 'status': status_propagate = evt_type.priority self.set_state(state, propagate=state_propagate) self.set_status(status, propagate=status_propagate) def _create_action_cache(self): acq_name = "%s.Acquisition" % self._name return PoolAcquisition(self, acq_name) def get_action_cache(self): return self._get_action_cache() def set_action_cache(self, action_cache): self._set_action_cache(action_cache) def get_siblings(self): if self._siblings is None: self._siblings = siblings = set() for axis, sibling in self.controller.get_element_axis().items(): if axis == self.axis: continue siblings.add(sibling) return self._siblings siblings = property(fget=get_siblings, doc="the siblings for this pseudo counter") # ------------------------------------------------------------------------ # value # ------------------------------------------------------------------------ def calc(self, physical_values=None): return self.get_value_attribute().calc(physical_values=physical_values) def calc_all(self, physical_values=None): return self.get_value_attribute().calc_all(physical_values=physical_values) def get_low_level_physical_value_attribute_iterator(self): return self.get_physical_elements_attribute_iterator() def get_physical_value_attribute_iterator(self): return self.get_user_elements_attribute_iterator() def get_physical_values_attribute_sequence(self): return self.get_user_elements_attribute_sequence() def get_physical_values_attribute_map(self): return self.get_user_elements_attribute_map() def get_physical_values(self, cache=True, propagate=1): """Get value for underlying elements. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the physical value :rtype: dict """ self._value.update(cache=cache, propagate=propagate) return self.get_physical_values_attribute_map() def get_siblings_values(self, use=None): """Get the last values for all siblings. :param use: the already calculated values. If a sibling is in this dictionary, the value stored here is used instead :type use: dict :return: a dictionary with siblings values :rtype: dict """ values = {} for sibling in self.siblings: value_attr = sibling.get_value_attribute() if use and sibling in use: pos = use[sibling] else: pos = value_attr.value values[sibling] = pos return values def get_value(self, cache=True, propagate=1): """Returns the pseudo counter value. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the pseudo counter value :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" value_attr = self._value value_attr.update(cache=cache, propagate=propagate) return value_attr def set_value(self, value, propagate=1): raise Exception("Not possible to set_value of a pseudo counter") value = property(get_value, doc="pseudo counter value") # -------------------------------------------------------------------------- # state information # -------------------------------------------------------------------------- _STD_STATUS = "{name} is {state}\n{ctrl_status}" def calculate_state_info(self, status_info=None): if status_info is None: status_info = self._state, self._status state, status = status_info if state == State.On: state_str = "Stopped" else: state_str = "in " + State[state] new_status = self._STD_STATUS.format(name=self.name, state=state_str, ctrl_status=status) return status_info[0], new_status def read_state_info(self, state_info=None): if state_info is None: state_info = {} action_cache = self.get_action_cache() ctrl_state_infos = action_cache.read_state_info(serial=True) for obj, ctrl_state_info in ctrl_state_infos.items(): state_info[obj] = state_info = \ obj._from_ctrl_state_info(ctrl_state_info) obj.put_state_info(state_info) for user_element in self.get_user_elements(): if user_element.get_type() not in TYPE_PHYSICAL_ELEMENTS: state_info = user_element._calculate_states() user_element.put_state_info(state_info) ret = self._calculate_states() return ret sardana-1.2.0/src/sardana/pool/poolpseudomotor.py0000644000234100017500000005727212174204314023540 0ustar cpascualcpascual00000000000000#!/usr/bin/env python from sardana.sardanavalue import SardanaValue ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the PoolPseudoMotor class""" __all__ = ["PoolPseudoMotor", "PoolPseudoMotorFrontend"] __docformat__ = 'restructuredtext' import sys import time import collections from sardana import State, ElementType, TYPE_PHYSICAL_ELEMENTS from sardana.sardanaattribute import SardanaAttribute from sardana.sardanaexception import SardanaException from .poolbaseelement import PoolBaseElement from .poolelement import PoolElement from .poolbasegroup import PoolBaseGroup from .poolmotion import PoolMotion from .poolexception import PoolException class Position(SardanaAttribute): def __init__(self, *args, **kwargs): self._exc_info = None super(Position, self).__init__(*args, **kwargs) # 130226: We found a bug https://sourceforge.net/p/sardana/tickets/2/ that makes the Pool segfault with some pseudomotor configuration: # It can be reproduced by: # 4 physical motors: m1 m2 m3 m4 # 2 slits: s1g,s1o = f(m1,m2) and s2g,s2o = f(m3,m4) # The pool will not be able to start if we create a third slit with s3g,s3o = f(s1g, s2g) # self.obj.get_physical_position_attribute_iterator() raises a KeyError exception # so we will flag the Position object as no_listeners for later configuration # We should still investigate the root of the problem when ordering the creation of elements self._listeners_configured = False try: for position_attr in self.obj.get_physical_position_attribute_iterator(): position_attr.add_listener(self.on_change) self._listeners_configured = True except KeyError: pass def _in_error(self): for position_attr in self.obj.get_physical_position_attribute_iterator(): if position_attr.error: return True return self._exc_info != None def _has_value(self): for position_attr in self.obj.get_physical_position_attribute_iterator(): if not position_attr.has_value(): return False return True def _has_write_value(self): for position_attr in self.obj.get_physical_position_attribute_iterator(): if not position_attr.has_write_value(): return False return True def _get_value(self): return self.calc_pseudo().value def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): raise Exception("Cannot set position value for %s" % self.obj.name) def _get_write_value(self): w_positions = self.get_physical_write_positions() return self.calc_pseudo(physical_positions=w_positions).value def _set_write_value(self, w_value, timestamp=None, propagate=1): raise Exception("Cannot set position write value for %s" % self.obj.name) def _get_exc_info(self): exc_info = self._exc_info if exc_info is None: for position_attr in self.obj.get_physical_position_attribute_iterator(): if position_attr.error: return position_attr.get_exc_info() return exc_info def _get_timestamp(self): timestamps = [ pos_attr.timestamp for pos_attr in self.obj.get_physical_position_attribute_iterator() ] if not len(timestamps): timestamps = self._local_timestamp, return max(timestamps) def get_physical_write_positions(self): ret = [] for pos_attr in self.obj.get_physical_position_attribute_iterator(): if pos_attr.has_write_value(): value = pos_attr.w_value else: if not pos_attr.has_value(): # if underlying moveable doesn't have position yet, it is # because of a cold start pos_attr.update(propagate=0) if pos_attr.in_error(): raise PoolException("Cannot get '%' position" % pos_attr.obj.name, exc_info=pos_attr.exc_info) value = pos_attr.value ret.append(value) return ret def get_physical_positions(self): ret = [] for pos_attr in self.obj.get_physical_position_attribute_iterator(): # if underlying moveable doesn't have position yet, it is because # of a cold start if not pos_attr.has_value(): pos_attr.update(propagate=0) if pos_attr.in_error(): raise PoolException("Cannot get '%' position" % pos_attr.obj.name, exc_info=pos_attr.exc_info) ret.append(pos_attr.value) return ret def calc_pseudo(self, physical_positions=None): try: obj = self.obj if physical_positions is None: physical_positions = self.get_physical_positions() else: l_p, l_u = len(physical_positions), len(obj.get_user_elements()) if l_p != l_u: raise IndexError("CalcPseudo(%s): must give %d physical " \ "positions (you gave %d)" % (obj.name, l_u, l_p) ) result = obj.controller.calc_pseudo(obj.axis, physical_positions, None) except SardanaException as se: result = SardanaValue(exc_info=se.exc_info) except: result = SardanaValue(exc_info=sys.exc_info()) return result def calc_all_pseudo(self, physical_positions=None): try: obj = self.obj if physical_positions is None: physical_positions = self.get_physical_positions() else: l_p, l_u = len(physical_positions), len(obj.get_user_elements()) if l_p != l_u: raise IndexError("CalcAllPseudo():: must give %d physical " \ "positions (you gave %d)" % (l_u, l_p) ) result = obj.controller.calc_all_pseudo(physical_positions, None) except SardanaException as se: result = SardanaValue(exc_info=se.exc_info) except: result = SardanaValue(exc_info=sys.exc_info()) return result def calc_physical(self, new_position): try: obj = self.obj curr_physical_positions = self.get_physical_positions() if isinstance(new_position, collections.Sequence): new_positions = new_position else: positions = obj.get_siblings_positions() positions[obj] = new_position new_positions = len(positions)*[None] for pseudo, position in positions.items(): new_positions[pseudo.axis-1] = position result = obj.controller.calc_all_physical(new_positions, curr_physical_positions) except SardanaException as se: result = SardanaValue(exc_info=se.exc_info) except: result = SardanaValue(exc_info=sys.exc_info()) return result def on_change(self, evt_src, evt_type, evt_value): self.fire_read_event(propagate=evt_type.priority) def update(self, cache=True, propagate=1): if cache: for phy_elem_pos in self.obj.get_low_level_physical_position_attribute_iterator(): if not phy_elem_pos.has_value(): cache = False break if not cache: dial_position_values = self.obj.motion.read_dial_position(serial=True) if not len(dial_position_values): self._local_timestamp = time.time() for motion_obj, position_value in dial_position_values.items(): motion_obj.put_dial_position(position_value, propagate=propagate) class PoolPseudoMotor(PoolBaseGroup, PoolElement): """A class representing a Pseudo Motor in the Sardana Device Pool""" def __init__(self, **kwargs): self._siblings = None self._in_start_move = False self._drift_correction = kwargs.pop('drift_correction', None) user_elements = kwargs.pop('user_elements') kwargs['elem_type'] = ElementType.PseudoMotor PoolElement.__init__(self, **kwargs) PoolBaseGroup.__init__(self, user_elements=user_elements, pool=kwargs['pool']) self._position = Position(self, listeners=self.on_change) # -------------------------------------------------------------------------- # Event forwarding # -------------------------------------------------------------------------- def on_change(self, evt_src, evt_type, evt_value): # forward all events coming from attributes to the listeners self.fire_event(evt_type, evt_value) def serialize(self, *args, **kwargs): kwargs = PoolElement.serialize(self, *args, **kwargs) elements = [ elem.name for elem in self.get_user_elements() ] physical_elements = [] for elem_list in self.get_physical_elements().values(): for elem in elem_list: physical_elements.append(elem.name) cl_name = self.__class__.__name__ cl_name = cl_name[4:] kwargs['elements'] = elements kwargs['physical_elements'] = physical_elements return kwargs def _create_action_cache(self): motion_name = "%s.Motion" % self._name return PoolMotion(self, motion_name) def set_drift_correction(self, drift_correction): self._drift_correction = drift_correction def get_drift_correction(self): dc = self._drift_correction if dc is None: dc = self.manager.drift_correction return dc drift_correction = property(get_drift_correction, set_drift_correction, doc="drift correction") def get_action_cache(self): return self._get_action_cache() def set_action_cache(self, action_cache): self._set_action_cache(action_cache) def get_siblings(self): if self._siblings is None: self._siblings = siblings = set() for axis, sibling in self.controller.get_element_axis().items(): if axis == self.axis: continue siblings.add(sibling) return self._siblings siblings = property(fget=get_siblings, doc="the siblings for this pseudo motor") def on_element_changed(self, evt_src, evt_type, evt_value): name = evt_type.name.lower() # always calculate state. status_info = self._calculate_states() state, status = self.calculate_state_info(status_info=status_info) state_propagate = 0 status_propagate = 0 if name == 'state': state_propagate = evt_type.priority elif name == 'status': status_propagate = evt_type.priority self.set_state(state, propagate=state_propagate) self.set_status(status, propagate=status_propagate) def add_user_element(self, element, index=None): elem_type = element.get_type() if elem_type == ElementType.Motor: pass elif elem_type == ElementType.PseudoMotor: #TODO: make this happen pass else: raise Exception("element %s is not a motor" % element.name) PoolBaseGroup.add_user_element(self, element, index=index) # ------------------------------------------------------------------------ # position # ------------------------------------------------------------------------ def calc_pseudo(self, physical_positions=None): return self.get_position_attribute().calc_pseudo(physical_positions=physical_positions) def calc_physical(self, new_position): return self.get_position_attribute().calc_physical(new_position) def calc_all_pseudo(self, physical_positions=None): return self.get_position_attribute().calc_all_pseudo(physical_positions=physical_positions) def get_position_attribute(self): return self._position def get_low_level_physical_position_attribute_iterator(self): return self.get_physical_elements_attribute_iterator() def get_physical_position_attribute_iterator(self): return self.get_user_elements_attribute_iterator() def get_physical_positions_attribute_sequence(self): return self.get_user_elements_attribute_sequence() def get_physical_positions_attribute_map(self): return self.get_user_elements_attribute_map() def get_physical_positions(self, cache=True, propagate=1): """Get positions for underlying elements. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the physical positions :rtype: dict """ self._position.update(cache=cache, propagate=propagate) return self.get_physical_positions_attribute_map() def get_siblings_positions(self, use=None, write_pos=True): """Get the last positions for all siblings. If write_pos is True and a sibling has already been moved before, it's last write position is used. Otherwise its read position is used instead. :param use: the already calculated positions. If a sibling is in this dictionary, the position stored here is used instead :type use: dict :param write_pos: determines if should try to use the last set point [default: True] :type write_pos: bool :return: a dictionary with siblings write positions :rtype: dict """ positions = {} for sibling in self.siblings: pos_attr = sibling.get_position(propagate=0) if use and sibling in use: pos = use[sibling] elif pos_attr.has_write_value() and write_pos: pos = pos_attr.w_value else: if pos_attr.in_error(): raise PoolException("Cannot get '%s' position" % sibling.name, exc_info=pos_attr.exc_info) pos_value = pos_attr.calc_pseudo() if pos_value.error: raise PoolException("Cannot get '%s' position" % sibling.name, exc_info=pos_value.exc_info) pos = pos_value.value positions[sibling] = pos return positions def get_position(self, cache=True, propagate=1): """Returns the user position. :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware :type cache: bool :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int :return: the user position :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" position_attr = self._position position_attr.update(cache=cache, propagate=propagate) return position_attr def set_position(self, position): """Moves the motor to the specified user position :param position: the user position to move to :type position: :class:`~numbers.Number`""" self.start_move(position) def set_write_position(self, w_position, timestamp=None, propagate=1): """Sets a new write value for the user position. :param w_position: the new write value for user position :type w_position: :class:`~numbers.Number` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" # SardanaAttribute position will raise an exception so we let it do it self._position.set_write_value(w_position, timestamp=timestamp, propagate=propagate) position = property(get_position, set_position, doc="pseudo motor position") # ------------------------------------------------------------------------ # state information # ------------------------------------------------------------------------ _STD_STATUS = "{name} is {state}\n{ctrl_status}" def calculate_state_info(self, status_info=None): # Refer to Position.__init__ method for an explanation on this 'hack' if not self._position._listeners_configured: for position_attr in self.get_physical_position_attribute_iterator(): position_attr.add_listener(self._position.on_change) self._position._listeners_configured = True if status_info is None: status_info = self._state, self._status state, status = status_info if state == State.On: state_str = "Stopped" else: state_str = "in " + State[state] new_status = self._STD_STATUS.format(name=self.name, state=state_str, ctrl_status=status) return status_info[0], new_status def read_state_info(self, state_info=None): if state_info is None: state_info = {} action_cache = self.get_action_cache() ctrl_state_infos = action_cache.read_state_info(serial=True) for motion_obj, ctrl_state_info in ctrl_state_infos.items(): state_info[motion_obj] = motion_state_info = \ motion_obj._from_ctrl_state_info(ctrl_state_info) motion_obj.put_state_info(motion_state_info) for user_element in self.get_user_elements(): if user_element.get_type() not in TYPE_PHYSICAL_ELEMENTS: motion_state_info = user_element._calculate_states() user_element.put_state_info(motion_state_info) ret = self._calculate_states() return ret # -------------------------------------------------------------------------- # default acquisition channel # -------------------------------------------------------------------------- def get_default_attribute(self): return self.get_position_attribute() # ------------------------------------------------------------------------ # motion # ------------------------------------------------------------------------ def get_motion(self): return self.get_action_cache() motion = property(get_motion, doc="motion object") # ------------------------------------------------------------------------ # motion calculation # ------------------------------------------------------------------------ def calculate_motion(self, new_position, items=None, calculated=None): # if items already contains the positions for this pseudo motor # underlying motors it means the motion has already been calculated # by a sibling if items is not None and len(items): physical_elements = self.get_physical_elements_set() s_items = set(items) if s_items == physical_elements: if calculated is not None and self in calculated: return user_elements = self.get_user_elements() positions = self.get_siblings_positions(use=calculated, write_pos=self.drift_correction) positions[self] = new_position pseudo_positions = len(positions)*[None] for pseudo, position in positions.items(): pseudo_positions[pseudo.axis-1] = position curr_physical_positions = self._position.get_physical_positions() physical_positions = self.controller.calc_all_physical(pseudo_positions, curr_physical_positions) if physical_positions.error: raise PoolException("Cannot calculate motion: " "calc_all_physical raises exception", exc_info=physical_positions.exc_info) else: if physical_positions.value is None: raise PoolException("Cannot calculate motion: " "calc_all_physical returns None") if items is None: items = {} for new_position, element in zip(physical_positions.value, user_elements): if new_position is None: raise PoolException("Cannot calculate motion: %s reports " "position to be None" % element.name) element.calculate_motion(new_position, items=items, calculated=calculated) return items def start_move(self, new_position): self._in_start_move = True try: return self._start_move(new_position) finally: self._in_start_move = False def _start_move(self, new_position): self._aborted = False self._stopped = False items = self.calculate_motion(new_position) timestamp = time.time() for item, position_info in items.items(): item.set_write_position(position_info[0], timestamp=timestamp, propagate=1) if not self._simulation_mode: self.motion.run(items=items) # ------------------------------------------------------------------------ # stop # ------------------------------------------------------------------------ def stop(self): #surpass the PoolElement.stop because it doesn't do what we want PoolBaseElement.stop(self) PoolBaseGroup.stop(self) # ------------------------------------------------------------------------ # abort # ------------------------------------------------------------------------ def abort(self): #surpass the PoolElement.abort because it doesn't do what we want PoolBaseElement.abort(self) PoolBaseGroup.abort(self) # ------------------------------------------------------------------------ # involved in an operation # ------------------------------------------------------------------------ def get_operation(self): return PoolBaseGroup.get_operation(self) sardana-1.2.0/src/sardana/pool/pooltwodexpchannel.py0000644000234100017500000000457712174204314024203 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for TwoDExpChannel""" __all__ = ["Pool2DExpChannel"] __docformat__ = 'restructuredtext' from sardana import ElementType from sardana.sardanaevent import EventType from .poolbasechannel import PoolBaseChannel class Pool2DExpChannel(PoolBaseChannel): def __init__(self, **kwargs): self._data_source = None kwargs['elem_type'] = ElementType.TwoDExpChannel PoolBaseChannel.__init__(self, **kwargs) # -------------------------------------------------------------------------- # data source # -------------------------------------------------------------------------- def get_data_source(self, cache=True, propagate=1): if not cache or self._data_source is None: data_source = self.read_data_source() self._set_data_source(data_source, propagate=propagate) return self._data_source def _set_data_source(self, data_source, propagate=1): self._data_source = data_source if not propagate: return self.fire_event(EventType("data_source", priority=propagate), data_source) def read_data_source(self): data_source = self.controller.get_axis_par(self.axis, "data_source") return data_source data_source = property(get_data_source, doc="source identifier for the 2D data") sardana-1.2.0/src/sardana/pool/poolutil.py0000644000234100017500000000403112174204314022116 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Pool utils""" __all__ = ["PoolUtil"] __docformat__ = 'restructuredtext' from taurus.core.util import CaselessDict class _PoolUtil(object): def __init__(self): self._ctrl_proxies = CaselessDict() def __call__(self, *args, **kwargs): return self def get_device(self, *args, **kwargs): ctrl_name = args[0] device_name = args[1] ctrl_devs = self._ctrl_proxies.get(ctrl_name) if ctrl_devs is None: self._ctrl_proxies[ctrl_name] = ctrl_devs = CaselessDict() dev = ctrl_devs.get(device_name) if dev is None: import PyTango ctrl_devs[device_name] = dev = PyTango.DeviceProxy(device_name) return dev get_motor = get_phy_motor = get_pseudo_motor = get_motor_group = \ get_exp_channel = get_ct_channel = get_zerod_channel = get_oned_channel = \ get_twod_channel = get_pseudo_counter_channel = get_measurement_group = \ get_com_channel = get_ioregister = get_device PoolUtil = _PoolUtil()sardana-1.2.0/src/sardana/pool/poolzerodexpchannel.py0000644000234100017500000002427212174204314024343 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool library. It defines the base classes for ZeroDExpChannel""" __all__ = [ "Pool0DExpChannel" ] __docformat__ = 'restructuredtext' import numpy import time from sardana import ElementType from sardana.sardanaevent import EventType from sardana.sardanaattribute import SardanaAttribute from .poolbasechannel import PoolBaseChannel from .poolacquisition import Pool0DAcquisition class BaseAccumulation(object): def __init__(self): self.buffer = numpy.zeros(shape=(2,16384), dtype=numpy.float64) self.clear() def clear(self): self.nb_points = 0 self.value = None def get_value_buffer(self): return self.buffer[0][:self.nb_points] def get_time_buffer(self): return self.buffer[1][:self.nb_points] def append_value(self, value, timestamp=None): if timestamp is None: timestamp = time.time() idx = self.nb_points self.nb_points += 1 self.buffer[0][idx] = value self.buffer[1][idx] = timestamp self.update_value(value, timestamp) def update_value(self, value, timestamp): self.value = value LastAccumulation = BaseAccumulation class SumAccumulation(BaseAccumulation): def clear(self): BaseAccumulation.clear(self) self.sum = 0.0 def update_value(self, value, timestamp): self.sum += value class AverageAccumulation(SumAccumulation): def update_value(self, value, timestamp): SumAccumulation.update_value(self, value, timestamp) self.value = self.sum / self.nb_points class IntegralAccumulation(BaseAccumulation): def clear(self): BaseAccumulation.clear(self) self.sum = 0.0 self.last_value = None self.start_time = None def update_value(self, value, timestamp): if self.nb_points == 1: self.last_value = value, timestamp self.start_time = timestamp self.value = value else: last_value, last_timestamp = self.last_value dt = timestamp - last_timestamp self.sum += dt*(last_value + value) / 2.0 total_dt = timestamp - self.start_time self.value = self.sum / total_dt self.last_value = value, timestamp def get_accumulation_class(ctype): return globals()[ctype + "Accumulation"] class CurrentValue(SardanaAttribute): def update(self, cache=True, propagate=1): if not cache or not self.has_value(): value = self.obj.read_current_value() self.set_value(value, propagate=propagate) class Value(SardanaAttribute): DefaultAccumulationType = "Average" def __init__(self, *args, **kwargs): accumulation_type = kwargs.pop('accumulation_type', self.DefaultAccumulationType) super(Value, self).__init__(*args, **kwargs) self.set_accumulation_type(accumulation_type) def get_val(self): return self.obj.get_value_attribute() def set_accumulation_type(self, ctype): klass = get_accumulation_class(ctype) self._accumulation = klass() def get_accumulation_type(self): klass_name = self._accumulation.__class__.__name__ return klass_name[:klass_name.index("Accumulation")] def get_accumulation(self): return self._accumulation accumulation = property(get_accumulation) def _get_value(self): value = self._accumulation.value if value is None: raise Exception("Value not available: no acquisition done so far!") return value def get_value_buffer(self): return self.accumulation.get_value_buffer() def get_time_buffer(self): return self.accumulation.get_time_buffer() def clear_buffer(self): self.accumulation.clear() def append_value(self, value, propagate=1): self.accumulation.append_value(value.value, value.timestamp) if propagate > 0: evt_type = EventType(self.name, priority=propagate) self.fire_event(evt_type, self) class Pool0DExpChannel(PoolBaseChannel): ValueAttributeClass = Value AcquisitionClass = Pool0DAcquisition def __init__(self, **kwargs): kwargs['elem_type'] = ElementType.ZeroDExpChannel PoolBaseChannel.__init__(self, **kwargs) self._current_value = CurrentValue(self, listeners=self.on_change) # -------------------------------------------------------------------------- # Accumulation # -------------------------------------------------------------------------- def get_accumulation_type(self): return self.get_value_attribute().get_accumulation_type() def get_accumulation(self): return self.get_value_attribute().get_accumulation() def set_accumulation_type(self, ctype): return self.get_value_attribute().set_accumulation_type(ctype) accumulation = property(get_accumulation) # -------------------------------------------------------------------------- # value # -------------------------------------------------------------------------- def get_accumulated_value_attribute(self): """Returns the accumulated value attribute object for this 0D. :return: the accumulated value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self.get_value_attribute() def get_current_value_attribute(self): """Returns the current value attribute object for this 0D. :return: the current value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._current_value def get_accumulated_value(self): """Gets the accumulated value for this 0D. :return: a :class:`~sardana.sardanavalue.SardanaValue` containing the 0D value :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute` :raises: Exception if no acquisition has been done yet on this 0D""" return self.get_accumulated_value_attribute() def read_current_value(self): """Reads the 0D value from hardware. :return: a :class:`~sardana.sardanavalue.SardanaValue` containing the counter value :rtype: :class:`~sardana.sardanavalue.SardanaValue`""" return self.acquisition.read_value()[self] def put_current_value(self, value, propagate=1): """Sets a value. :param value: the new value :type value: :class:`~sardana.sardanavalue.SardanaValue` :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" curr_val_attr = self.get_current_value_attribute() curr_val_attr.set_value(value, propagate=propagate) if self.is_in_operation(): acc_val_attr = self.get_accumulated_value_attribute() acc_val_attr.append_value(value, propagate=propagate) def get_current_value(self, cache=True, propagate=1): """Returns the counter value. :return: the 0D accumulated value :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" curr_val_attr = self.get_current_value_attribute() curr_val_attr.update(cache=cache, propagate=propagate) return curr_val_attr current_value = property(get_current_value, doc="0D value") accumulated_value = property(get_accumulated_value, doc="0D value") def put_value(self, value, propagate=1): return self.put_current_value(value, propagate=propagate) def _get_value(self): return self.get_current_value() def append_value(self, value, timestamp=None, propagate=1): cumulation = self.cumulation cumulation.append_value(value, timestamp) if not propagate: return self.fire_event(EventType("value", priority=propagate), cumulation.value) def clear_buffer(self): self.get_accumulated_value_attribute().clear_buffer() # -------------------------------------------------------------------------- # value buffer # -------------------------------------------------------------------------- def get_value_buffer(self): return self.get_accumulated_value_attribute().get_value_buffer() value_buffer = property(get_value_buffer) # -------------------------------------------------------------------------- # time buffer # -------------------------------------------------------------------------- def get_time_buffer(self): return self.get_accumulated_value_attribute().get_time_buffer() time_buffer = property(get_time_buffer) def start_acquisition(self, value=None): self._aborted = False self.clear_buffer() if value is None: raise Exception("Invalid integration_time '%s'. Hint set a new value for 'value' first" % value) if not self._simulation_mode: acq = self.acquisition.run() sardana-1.2.0/src/sardana/spock/0000755000234100017500000000000012174204361020047 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/spock/ipython_00_10/0000755000234100017500000000000012174204361022340 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/spock/ipython_00_10/__init__.py0000644000234100017500000000213712174204306024453 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock generic utilities for ipython 0.10""" sardana-1.2.0/src/sardana/spock/ipython_00_10/genutils.py0000644000234100017500000010263112174204306024546 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock generic utilities""" __all__ = ['page', 'arg_split', 'get_gui_mode', 'get_pylab_mode', 'get_color_mode', 'get_ipapi', 'get_editor', 'ask_yes_no', 'spock_input', 'translate_version_str2int', 'get_ipython_version', 'get_ipython_version_number', 'get_python_version', 'get_python_version_number', 'get_ipython_dir', 'get_ipython_profiles', 'get_spock_profiles', 'get_non_spock_profiles', 'get_spock_user_profile_module', 'get_pytango_version', 'get_pytango_version_number', 'get_server_for_device', 'get_macroserver_for_door', 'get_device_from_user', 'get_tango_db', 'get_tango_host_from_user', 'print_dev_from_class', 'from_name_to_tango', 'clean_up', 'get_taurus_core_version', 'get_taurus_core_version_number', 'check_requirements', 'get_door', 'get_macro_server', 'expose_magic', 'unexpose_magic', 'expose_variable', 'expose_variables', 'unexpose_variable', 'create_spock_profile', 'check_for_upgrade', 'get_args', 'init_console', 'init_magic', 'init_pre_spock', 'init_post_spock', 'init_spock', 'start', 'mainloop', 'run', 'load_ipython_extension', 'unload_ipython_extension', 'load_config', 'MSG_FAILED','MSG_FAILED_WR', 'MSG_R', 'MSG_ERROR', 'MSG_DONE', 'MSG_OK' ] __docformat__ = 'restructuredtext' import sys import os import socket import imp import IPython import IPython.genutils import PyTango import PyTango.ipython import taurus.core.util from sardana.spock import exception from sardana.spock import colors from sardana.spock import release arg_split = IPython.iplib.arg_split page = IPython.genutils.page TermColors = colors.TermColors requirements = { # module minimum recommended "IPython" : ("0.10.0", "0.10.0"), "Python" : ("2.6.0", "2.6.0"), "PyTango" : ("7.1.2", "7.2.0"), "taurus.core" : ("2.0.0", "2.1.0") } ENV_NAME = "_E" #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # IPython utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_gui_mode(): if '-q4thread' in sys.argv: return 'qt' elif '-gthread' in sys.argv: return 'gtk' elif '-wthread' in sys.argv: return 'wx' return '' def get_pylab_mode(): return get_gui_mode() def get_color_mode(): return get_ipapi().options.colors def get_ipapi(): return IPython.ipapi.get() def get_editor(): return get_ipapi().options.editor def ask_yes_no(prompt,default=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is empty. Otherwise the question is repeated until an answer is given. An EOF is treated as the default answer. If there is no default, an exception is raised to prevent infinite loops. Valid answers are: y/yes/n/no (match is not case sensitive).""" if default: prompt = '%s [%s]' % (prompt, default) return IPython.genutils.ask_yes_no(prompt, default) def spock_input(prompt='', ps2='... '): return IPython.genutils.raw_input_ext(prompt=prompt, ps2=ps2) def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number""" import math parts = version_str.split('.') i, v, l = 0, 0, len(parts) if not l: return v while i<3: try: v += int(parts[i])*int(math.pow(10,(2-i)*2)) l -= 1 i += 1 except ValueError: return v if not l: return v return v try: v += 10000*int(parts[0]) l -= 1 except ValueError: return v if not l: return v try: v += 100*int(parts[1]) l -= 1 except ValueError: return v if not l: return v try: v += int(parts[0]) l -= 1 except ValueError: return v if not l: return v def get_ipython_version(): """Returns the current IPython version""" v = None try: try: v = IPython.Release.version except Exception: try: v = IPython.release.version except Exception: pass except Exception: pass return v def get_ipython_version_number(): """Returns the current IPython version number""" ipyver_str = get_ipython_version() if ipyver_str is None: return None return translate_version_str2int(ipyver_str) def get_python_version(): return '.'.join(map(str,sys.version_info[:3])) def get_python_version_number(): pyver_str = get_python_version() return translate_version_str2int(pyver_str) def get_ipython_dir(): """Find the ipython local directory. Usually is /.ipython""" if hasattr(PyTango.ipython, "get_ipython_dir"): return PyTango.ipython.get_ipython_dir() if hasattr(IPython.iplib, 'get_ipython_dir'): # Starting from ipython 0.9 they hadded this method return IPython.iplib.get_ipython_dir() # Try to find the profile in the current directory and then in the # default IPython dir #userdir = os.path.realpath(os.path.curdir) home_dir = IPython.genutils.get_home_dir() if os.name == 'posix': ipdir = '.ipython' else: ipdir = '_ipython' ipdir = os.path.join(home_dir, ipdir) ipythondir = os.path.abspath( os.environ.get('IPYTHONDIR', ipdir) ) return ipythondir def get_ipython_profiles(): """Helper function to find all ipython profiles""" if hasattr(PyTango.ipython, "get_ipython_profiles"): return PyTango.ipython.get_ipython_profiles() ret = [] ipydir = get_ipython_dir() if os.path.isdir(ipydir): for i in os.listdir(ipydir): fullname = os.path.join(ipydir, i) if i.startswith("ipy_profile_") and i.endswith(".py"): if os.path.isfile(fullname): ret.append(i[len("ipy_profile_"):i.rfind(".")]) return ret def get_spock_profiles(ipython_profiles=None): """Helper function to find all spock ipython profiles""" ret = [] ipydir = get_ipython_dir() if not os.path.isdir(ipydir): return ret if ipython_profiles is None: ipython_profiles = get_ipython_profiles() ret = [] for profile in ipython_profiles: profile_f = os.path.join(ipydir, "ipy_profile_%s.py" % profile) if not os.path.isfile(profile_f): continue try: for i, l in enumerate(file(profile_f)): if i > 10: break if l.find("spock_creation_version") >= 0: ret.append(profile) break except: pass return ret def get_non_spock_profiles(ipython_profiles=None): """Helper function to find all non spock ipython profiles""" if ipython_profiles is None: ipython_profiles = get_ipython_profiles() ipython_profiles = set(ipython_profiles) spock_profiles = set(get_spock_profiles(ipython_profiles=ipython_profiles)) return ipython_profiles.difference(spock_profiles) def get_spock_user_profile_module(profile_name): return 'ipy_profile_%s' % profile_name #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_pytango_version(): try: import PyTango except: return None try: return PyTango.Release.version except: return '0.0.0' def get_pytango_version_number(): tgver_str = get_pytango_version() if tgver_str is None: return None return translate_version_str2int(tgver_str) def get_server_for_device(device_name): db = get_tango_db() device_name = device_name.lower() server_list = db.get_server_list() for server in server_list: for dev in db.get_device_class_list(server)[::2]: if dev.lower() == device_name: return server return None def get_macroserver_for_door(door_name): """Returns the MacroServer device name in the same DeviceServer as the given door device""" full_door_name, door_name, door_alias = from_name_to_tango(door_name) db = get_tango_db() door_name = door_name.lower() server_list = list(db.get_server_list('MacroServer/*')) server_list += list(db.get_server_list('Sardana/*')) server_devs = None for server in server_list: server_devs = db.get_device_class_list(server) devs, klasses = server_devs[0::2], server_devs[1::2] for dev in devs: if dev.lower() == door_name: for i, klass in enumerate(klasses): if klass == 'MacroServer': return "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), devs[i]) else: return None def get_device_from_user(expected_class, dft = None): """Gets a device of the given device class from user input""" dft = print_dev_from_class(expected_class, dft) prompt = "%s name from the list" % expected_class if not dft is None: prompt += "[%s]" % dft prompt += "? " from_user = raw_input(prompt).strip() or dft name = '' try: full_name, name, alias = from_name_to_tango(from_user) except: print "Warning: the given %s does not exist" % expected_class return name try: db = get_tango_db() cl_name = db.get_class_for_device(name) class_correct = cl_name == expected_class if not class_correct: print "Warning: the given name is not a %s (it is a %s)"%(expected_class,cl_name) except Exception as e: print "Warning: unable to confirm if '%s' is valid" % name print str(e) return full_name def get_tango_db(): tg_host = PyTango.ApiUtil.get_env_var("TANGO_HOST") db = None if tg_host is None: host,port = get_tango_host_from_user() tg_host = "%s:%d" % (host,port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() else: try: db = PyTango.Database() except: # tg host is not valid. Find a valid one host,port = get_tango_host_from_user() tg_host = "%s:%d" % (host,port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() return db def get_tango_host_from_user(): while True: prompt = "Please enter a valid tango host (:): " from_user = raw_input(prompt).strip() try: host, port = from_user.split(':') try: port = int(port) try: socket.gethostbyname(host) try: db = PyTango.Database(host,port) return db.get_db_host(), db.get_db_port() except: exp = "No tango database found at %s:%d" % (host,port) except: exp = "Invalid host name %s" % host except: exp = "Port must be a number > 0" except: exp = "Invalid tango host. Must be in format :" exp = "Invalid tango host. %s " % exp print exp def print_dev_from_class(classname, dft = None): db = get_tango_db() pytg_ver = get_pytango_version_number() if pytg_ver >= 030004: server_wildcard = '*' try: exp_dev_list = db.get_device_exported_for_class(classname) except Exception: exp_dev_list = [] else: server_wildcard = '%' exp_dev_list = [] res = None dev_list = db.get_device_name(server_wildcard,classname) tg_host = "%s:%s" % (db.get_db_host(),db.get_db_port()) print "Available",classname,"devices from",tg_host,":" for dev in dev_list: full_name, name, alias = from_name_to_tango(dev) out = alias or name if alias: out += ' (a.k.a. %s)' % name out = "%-25s" % out if dev in exp_dev_list: out += " (running)" print out if dft: if dft.lower() == name.lower(): res = name elif not alias is None and dft.lower() == alias.lower(): res = alias return res def from_name_to_tango(name): db = get_tango_db() alias = None c = name.count('/') # if the db prefix is there, remove it first if c == 3 or c == 1: name = name[name.index("/")+1:] elems = name.split('/') l = len(elems) if l == 3: try: alias = db.get_alias(name) if alias.lower() == 'nada': alias = None except: alias = None elif l == 1: alias = name name = db.get_device_alias(alias) else: raise Exception("Invalid device name '%s'" % name) full_name = "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), name) return full_name, name, alias #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # taurus utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def clean_up(): taurus.Manager().cleanUp() def get_taurus_core_version(): try: return taurus.core.Release.version except: return '0.0.0' def get_taurus_core_version_number(): tgver_str = get_taurus_core_version() if tgver_str is None: return None return translate_version_str2int(tgver_str) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Requirements checking #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def check_requirements(): r = requirements minPyTango, recPyTango = map(translate_version_str2int, r["PyTango"]) minIPython, recIPython = map(translate_version_str2int, r["IPython"]) minPython, recPython = map(translate_version_str2int, r["Python"]) minTaurusCore, recTaurusCore = map(translate_version_str2int, r["taurus.core"]) currPython = get_python_version_number() currIPython = get_ipython_version_number() currPyTango = get_pytango_version_number() currTaurusCore = get_taurus_core_version_number() errMsg = "" warnMsg = "" errPython, errIPython, errPyTango, errTaurusCore = False, False, False, False if currPython is None: errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements["Python"][0] errPython = True elif currPython < minPython: errMsg += "Spock needs Python version >= %s. Current version is %s\n" % (requirements["Python"][0], get_python_version()) errPython = True if currIPython is None: errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements["IPython"][0] errIPython = True elif currIPython < minIPython: errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % (requirements["IPython"][0], get_ipython_version()) errIPython = True if currPyTango is None: errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements["IPython"][0] errPyTango = True elif currPyTango < minPyTango: errMsg += "Spock needs PyTango version >= %s. " % requirements["PyTango"][0] if currPyTango > 0: errMsg += "Current version is %s\n" % get_pytango_version() else: errMsg += "Current version is unknown (most surely too old)\n" errPyTango = True if currTaurusCore is None: errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements["taurus.core"][0] errTaurusCore = True elif currTaurusCore < minTaurusCore: errMsg += "Spock needs taurus.core version >= %s. " % requirements["taurus.core"][0] if currTaurusCore > 0: errMsg += "Current version is %s\n" % get_taurus_core_version() else: errMsg += "Current version is unknown (most surely too old)\n" errTaurusCore = True # Warnings if not errPython and currPython < recPython: warnMsg += "Spock recommends Python version >= %s. Current version is %s\n" % (requirements["Python"][1], get_python_version()) if not errIPython and currIPython < recIPython: warnMsg += "Spock recommends IPython version >= %s. Current version is %s\n" % (requirements["IPython"][1], get_ipython_version()) if not errPyTango and currPyTango < recPyTango: warnMsg += "Spock recommends PyTango version >= %s. Current version is %s\n" % (requirements["PyTango"][1], get_pytango_version()) if not errTaurusCore and currTaurusCore < recTaurusCore: warnMsg += "Spock recommends taurus.core version >= %s. Current version is %s\n" % (requirements["taurus.core"][1], get_taurus_core_version()) if errMsg: errMsg += warnMsg raise exception.SpockMissingRequirement, errMsg if warnMsg: raise exception.SpockMissingRecommended, warnMsg return True def _get_dev(dev_type): ip = get_ipapi() ret = ip.user_ns.get("_" + dev_type) if ret is not None: return ret dev_obj_name = '%s_NAME' % dev_type dev_name = ip.user_ns[dev_obj_name] factory = taurus.Factory() dev_obj = factory.getDevice(dev_name) ip.user_ns[dev_type] = PyTango.DeviceProxy(dev_name) ip.user_ns["_" + dev_type] = dev_obj setattr(ip, '_%s' % dev_type, dev_obj) return dev_obj def get_door(): return _get_dev('DOOR') def get_macro_server(): return _get_dev('MACRO_SERVER') def _macro_completer(self, event): """Method called by the IPython autocompleter. It will determine possible values for macro arguments. """ ms = get_macro_server() macro_name = event.command.lstrip('%') # calculate parameter index param_idx = len(event.line.split()) - 1 if not event.line.endswith(' '): param_idx -= 1 # get macro info info = ms.getMacroInfoObj(macro_name) # if macro doesn't have parameters return if param_idx < 0 or not info.hasParams() : return # get the parameter info possible_params = info.getPossibleParams(param_idx) # return the existing elements for the given parameter type if possible_params: res = [] for param in possible_params: res.extend(ms.getElementNamesWithInterface(param['type'])) return res def expose_magic(name, fn, completer_func=_macro_completer): ip = get_ipapi() ip.expose_magic(name, fn) if completer_func is None: return # enable macro param completion ip.set_hook('complete_command', completer_func, str_key = name) # register also when the command as is typed with the magic prefix '%' name = str('%') + name ip.set_hook('complete_command', completer_func, str_key = name) def unexpose_magic(name): ip = get_ipapi() mg = 'magic_%s' % name delattr(ip.IP, mg) def expose_variable(name, value): get_ipapi().to_user_ns({ name : value }) def unexpose_variable(name): user_ns = get_ipapi().user_ns del user_ns[name] def expose_variables(d): get_ipapi().to_user_ns(d) #def _expose_device(name): # ip.to_user_ns({ name : PyTango.DeviceProxy(name) }) #def expose_device(name): # ip = get_ipapi() # ip.magic("bg _expose_device(%s)" % name) def create_spock_profile(userdir, dft_profile, profile, door_name=None): """Create a profile file from a profile template file """ src_data = """\ \"\"\"Settings for Spock session\"\"\" # # Please do not delete the next lines has they are used to check the version # number for possible upgrades # spock_creation_version = {version} # door_name = {door_name} # import IPython from sardana.spock.genutils import init_spock def main(): ip = IPython.ipapi.get() init_spock(ip, '{macroserver_name}', '{door_name}') main() """ # # Discover door name # if door_name is None: door_name = get_device_from_user("Door", profile) else: full_door_name, door_name, door_alias = from_name_to_tango(door_name) door_name = full_door_name # # Discover macro server name # ms_name = get_macroserver_for_door(door_name) dest_data = src_data.format(version=release.version, macroserver_name=ms_name, door_name=door_name) f_name = '%s.py' % get_spock_user_profile_module(profile) dest_name = os.path.join(userdir, f_name) sys.stdout.write('Storing %s in %s... ' % (f_name, userdir)) sys.stdout.flush() res = MSG_FAILED try: dest = open(dest_name,"w") dest.write(dest_data) dest.flush() dest.close() res = MSG_DONE finally: sys.stdout.write(res + '\n') sys.stdout.flush() def check_for_upgrade(ipy_profile_file, ipythondir, session, profile): # Check if the current profile is up to date with the spock version spock_profile_ver_str = '0.0.0' door_name = None # search for version and door inside the ipy_profile file for i, line in enumerate(ipy_profile_file): if i > 20 : break; # give up after 20 lines if line.startswith('# spock_creation_version = '): spock_profile_ver_str = line[line.index('=')+1:].strip() if line.startswith('# door_name = '): door_name = line[line.index('=')+1:].strip() # convert version from string to numbers spocklib_ver = translate_version_str2int(release.version) spock_profile_ver = translate_version_str2int(spock_profile_ver_str) if spocklib_ver == spock_profile_ver: return if spocklib_ver < spock_profile_ver: print '%sYour spock profile (%s) is newer than your spock version ' \ '(%s)!' % (TermColors.Brown, spock_profile_ver_str, release.version) print 'Please upgrade spock or delete the current profile %s' % TermColors.Normal sys.exit(1) # there was no version track of spock profiles since spock 0.2.0 so change # the message if spock_profile_ver_str == '0.0.0': spock_profile_ver_str = '<= 0.2.0' msg = 'Your current spock door extension profile has been created with spock %s.\n' \ 'Your current spock door extension version is %s, therefore a profile upgrade is needed.\n' \ % (spock_profile_ver_str, release.version) print msg prompt = 'Do you wish to upgrade now (warn: this will shutdown the current spock session) ([y]/n)? ' r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipythondir, session, profile, door_name) sys.exit(0) def get_args(argv): script_name = argv[0] script_dir, session = os.path.split(script_name) script_name = os.path.realpath(script_name) #script_dir = os.path.dirname(script_name) macro_server = None door = None # Define the profile file profile = "spockdoor" try: profile_idx = argv.index('-p') + 1 if len(argv) > profile_idx: profile = argv[profile_idx] except: pass profile_modulename = get_spock_user_profile_module(profile) # Try to find the profile in the current directory and then in the # default IPython dir #userdir = os.path.realpath(os.path.curdir) ipythondir = get_ipython_dir() if not os.path.isdir(ipythondir): # Platform-dependent suffix. if os.name == 'posix': rc_suffix = '' else: rc_suffix = '.ini' IPython.iplib.user_setup(ipythondir, rc_suffix, mode='install', interactive=False) try: f, name, t = imp.find_module(profile_modulename, [ipythondir]) check_for_upgrade(f, ipythondir, session, profile) except ImportError: # Create a new profile r = '' while not r in ['y','n']: prompt = 'Profile \'%s\' does not exist. Do you want to create '\ 'one now ([y]/n)? ' % profile r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipythondir, session, profile) else: sys.stdout.write('No spock door extension profile was created. Starting normal spock...\n') sys.stdout.flush() profile = '' # inform the shell of the profile it should use if not '-p' in argv and profile: argv.append('-p') argv.append(profile) user_ns = { 'MACRO_SERVER_NAME' : macro_server, 'DOOR_NAME' : door, 'PROFILE' : profile } return user_ns #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Useful constants #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- MSG_G = '[%s%%s%s]' % (TermColors.Green, TermColors.Normal) MSG_R = '[%s%%s%s]' % (TermColors.Red, TermColors.Normal) MSG_FAILED = MSG_R % 'FAILED' MSG_FAILED_WR = MSG_R % 'FAILED: %s' MSG_ERROR = MSG_R % 'ERROR' MSG_DONE = MSG_G % 'DONE' MSG_OK = MSG_G % 'OK' #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # initialization methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def init_console(ip): # Handy tab-completers for %cd, %run, import etc. # Try commenting this out if you have completion problems/slowness import ipy_stock_completers spockver = release.version pyver = get_python_version() ipyver = get_ipython_version() pytangover = get_pytango_version() tauruscorever = get_taurus_core_version() TermColors = IPython.ColorANSI.TermColors d = { "version" : spockver, "pyver" : pyver, "ipyver" : ipyver, "pytangover" : pytangover, "taurusver" : tauruscorever, "profile" : ip.user_ns["PROFILE"], "door" : ip.user_ns["DOOR_ALIAS"] } d.update(TermColors.__dict__) # IPython options o = ip.options o.autocall = 1 o.autoedit_syntax = 0 o.autoindent = 1 o.automagic = 1 o.cache_size = 1000 o.colors = 'Linux' o.color_info = 1 o.confirm_exit = 0 o.deep_reload = 0 #o.editor = 'gedit' o.log = 0 o.logfile = '' o.messages = 1 o.pdb = 0 o.pprint = 1 o.quick = 0 o.readline = 1 o.screen_length = 0 o.separate_in = '\n' o.separate_out = '\n' o.separate_out2 = '' o.nosep = 0 o.wildcards_case_sensitive = 0 o.object_info_string_level = 0 o.xmode = 'Context' o.multi_line_specials = 1 o.system_header = 'IPython system call: ' o.system_verbose = 1 o.wxversion = '0' o.colors = "GreenTango" o.prompt_in1 = "$DOOR_ALIAS$DOOR_STATE [\\#]: " o.prompt_out = "Result [\\#]: " o.readline_parse_and_bind.append('tab: complete') #o.readline_parse_and_bind.append('tab: menu-complete') o.readline_parse_and_bind.append('"\C-l": possible-completions') o.readline_parse_and_bind.append('set show-all-if-ambiguous on') o.readline_parse_and_bind.append('"\C-o": tab-insert') o.readline_parse_and_bind.append('"\M-i": " "') o.readline_parse_and_bind.append('"\M-o": "\d\d\d\d"') o.readline_parse_and_bind.append('"\M-I": "\d\d\d\d"') o.readline_parse_and_bind.append('"\C-r": reverse-search-history') o.readline_parse_and_bind.append('"\C-s": forward-search-history') o.readline_parse_and_bind.append('"\C-p": history-search-backward') o.readline_parse_and_bind.append('"\C-n": history-search-forward') o.readline_parse_and_bind.append('"\e[A": history-search-backward') o.readline_parse_and_bind.append('"\e[B": history-search-forward') o.readline_parse_and_bind.append('"\C-k": kill-line') o.readline_parse_and_bind.append('"\C-u": unix-line-discard') o.readline_remove_delims = '-/~' o.readline_merge_completions = 1 o.readline_omit__names = 0 banner = """\ %(Purple)sSpock %(version)s%(Normal)s -- An interactive laboratory application. help -> Spock's help system. object? -> Details about 'object'. ?object also works, ?? prints more. """ banner = banner % d banner = banner.format(**d) o.banner = banner def init_magic(ip): import sardana.spock.magic magic = sardana.spock.magic expose_magic('debug', magic.debug, magic.debug_completer) expose_magic('www', magic.www, None) expose_magic('post_mortem', magic.post_mortem, None) expose_magic('spsplot', magic.spsplot, None) expose_magic('macrodata', magic.macrodata, None) expose_magic('edmac', magic.edmac, None) expose_magic('showscan', magic.showscan, None) expose_magic('expconf', magic.expconf, None) ip.set_hook('late_startup_hook', magic.spock_late_startup_hook) ip.set_hook('pre_prompt_hook', magic.spock_pre_prompt_hook) def init_pre_spock(ip, macro_server, door): so = IPython.ipstruct.Struct() full_door_tg_name, door_tg_name, door_tg_alias = from_name_to_tango(door) #macro_server = get_ms_for_door(door_tg_name) full_ms_tg_name, ms_tg_name, ms_tg_alias = from_name_to_tango(macro_server) ip.user_ns['MACRO_SERVER_NAME'] = full_ms_tg_name ip.user_ns['MACRO_SERVER_ALIAS'] = ms_tg_alias or ms_tg_name ip.user_ns['DOOR_NAME'] = full_door_tg_name ip.user_ns['DOOR_ALIAS'] = door_tg_alias or door_tg_name ip.user_ns['DOOR_STATE'] = "" ip.user_ns['spock_options'] = so if ip.IP.alias_table.has_key('mv'): del ip.IP.alias_table['mv'] v = release.version alias = ip.user_ns['DOOR_ALIAS'] profile = ip.user_ns['PROFILE'] so.spock_banner = """\ {Blue}Spock's sardana extension %s loaded with profile: %s (linked to door '%s'){Normal} """ % (v, profile, alias) # the CodecFactory is not thread safe. There are two attributes who will # request for it in the first event at startup in different threads # therefore this small hack: make sure CodecFactory is initialized. taurus.core.util.CodecFactory() factory = taurus.Factory() import sardana.spock.spockms macroserver = sardana.spock.spockms factory.registerDeviceClass('MacroServer', macroserver.SpockMacroServer) mode = get_gui_mode() if mode == 'qt': factory.registerDeviceClass('Door', macroserver.QSpockDoor) else: factory.registerDeviceClass('Door', macroserver.SpockDoor) door = get_door() macro_server = get_macro_server() # Initialize the environment expose_variable(ENV_NAME, macro_server.getEnvironment()) def init_post_spock(ip): init_console(ip) init_magic(ip) def init_spock(ip, macro_server, door): init_pre_spock(ip, macro_server, door) PyTango.ipython.init_ipython(ip) init_post_spock(ip) def start(user_ns=None): if '-pylab' not in sys.argv: sys.argv.insert(1, '-pylab') if '-q4thread' not in sys.argv: sys.argv.insert(1, '-q4thread') # Make sure the log level is changed to warning import taurus import taurus.core.util taurus.core.util.CodecFactory() taurus.setLogLevel(taurus.Warning) try: check_requirements() except exception.SpockMissingRequirement, requirement: print str(requirement) sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) user_ns = user_ns or {} try: user_ns.update(get_args(sys.argv)) except exception.SpockException, e: print e.message print 'Starting normal IPython console' except KeyboardInterrupt: print "\nUser pressed Ctrl+C. Exiting..." sys.exit() except Exception, e: print 'spock exited with an unmanaged exception: %s' % str(e) sys.exit(-2) return IPython.Shell.start(user_ns=user_ns) def mainloop(shell=None, user_ns=None): if shell is None: shell = start(user_ns) shell.mainloop() def run(user_ns=None): # initialize input handler as soon as possible import sardana.spock.inputhandler input_handler = sardana.spock.inputhandler.InputHandler() try: mainloop(user_ns=user_ns) finally: try: clean_up() except Exception: pass # for compatibility reasons with new IPython API (>=0.11) we add the following # empty methods def load_ipython_extension(ipython): pass def unload_ipython_extension(ipython): pass def load_config(config): pass sardana-1.2.0/src/sardana/spock/ipython_00_11/0000755000234100017500000000000012174204361022341 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/spock/ipython_00_11/__init__.py0000644000234100017500000000214112174204306024447 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock generic utilities for ipython > 0.10""" sardana-1.2.0/src/sardana/spock/ipython_00_11/genutils.py0000644000234100017500000011301312174204306024543 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock generic utilities""" __all__ = ['page', 'arg_split', 'get_gui_mode', 'get_pylab_mode', 'get_color_mode', 'get_app', 'get_shell', 'get_ipapi', 'get_config', 'get_editor', 'ask_yes_no', 'spock_input', 'translate_version_str2int', 'get_ipython_version', 'get_ipython_version_number', 'get_python_version', 'get_python_version_number', 'get_ipython_dir', 'get_ipython_profiles', 'get_pytango_version', 'get_pytango_version_number', 'get_server_for_device', 'get_macroserver_for_door', 'get_device_from_user', 'get_tango_db', 'get_tango_host_from_user', 'print_dev_from_class', 'from_name_to_tango', 'clean_up', 'get_taurus_core_version', 'get_taurus_core_version_number', 'check_requirements', 'get_door', 'get_macro_server', 'expose_magic', 'unexpose_magic', 'expose_variable', 'expose_variables', 'unexpose_variable', 'create_spock_profile', 'check_for_upgrade', 'get_args', 'start', 'mainloop', 'run', 'load_ipython_extension', 'unload_ipython_extension', 'load_config', 'MSG_FAILED', 'MSG_FAILED_WR', 'MSG_R', 'MSG_ERROR', 'MSG_DONE', 'MSG_OK'] __docformat__ = 'restructuredtext' import sys import os import socket import IPython import IPython.core.magic from IPython.core.page import page from IPython.core.profiledir import ProfileDirError, ProfileDir from IPython.core.application import BaseIPythonApplication from IPython.core.interactiveshell import InteractiveShell from IPython.utils.io import ask_yes_no as _ask_yes_no from IPython.utils.io import raw_input_ext as _raw_input_ext from IPython.utils.path import get_ipython_dir from IPython.utils.process import arg_split from IPython.utils.coloransi import TermColors from IPython.config.application import Application from IPython.frontend.terminal.ipapp import TerminalIPythonApp, \ launch_new_instance import taurus from taurus.core import Release as TCRelease from taurus.core.util import CodecFactory # make sure Qt is properly initialized from taurus.qt import Qt from sardana.spock import exception from sardana.spock import colors from sardana.spock import release SpockTermColors = colors.TermColors requirements = { # module minimum recommended "IPython" : ("0.11.0", "0.12.0"), "Python" : ("2.6.0", "2.6.0"), "PyTango" : ("7.2.0", "7.2.3"), "taurus.core" : ("3.0.0", "3.0.0") } ENV_NAME = "_E" #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # IPython utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_gui_mode(): return 'qt' def get_pylab_mode(): return get_app().pylab def get_color_mode(): return get_config().InteractiveShell.colors def get_app(): #return TerminalIPythonApp.instance() return Application.instance() def get_shell(): """Get the global InteractiveShell instance.""" return get_app().shell def get_ipapi(): """Get the global InteractiveShell instance.""" return InteractiveShell.instance() def get_config(): return get_app().config def get_editor(): return get_ipapi().editor def ask_yes_no(prompt,default=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is empty. Otherwise the question is repeated until an answer is given. An EOF is treated as the default answer. If there is no default, an exception is raised to prevent infinite loops. Valid answers are: y/yes/n/no (match is not case sensitive).""" if default: prompt = '%s [%s]' % (prompt, default) return _ask_yes_no(prompt, default) def spock_input(prompt='', ps2='... '): return _raw_input_ext(prompt=prompt, ps2=ps2) def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number""" import math parts = version_str.split('.') i, v, l = 0, 0, len(parts) if not l: return v while i<3: try: v += int(parts[i])*int(math.pow(10,(2-i)*2)) l -= 1 i += 1 except ValueError: return v if not l: return v return v try: v += 10000*int(parts[0]) l -= 1 except ValueError: return v if not l: return v try: v += 100*int(parts[1]) l -= 1 except ValueError: return v if not l: return v try: v += int(parts[0]) l -= 1 except ValueError: return v if not l: return v def get_ipython_version(): """Returns the current IPython version""" v = None try: try: v = IPython.Release.version except Exception: try: v = IPython.release.version except Exception, e2: print e2 except Exception, e3: print e3 return v def get_ipython_version_number(): """Returns the current IPython version number""" ipyver_str = get_ipython_version() if ipyver_str is None: return None return translate_version_str2int(ipyver_str) def get_python_version(): return '.'.join(map(str,sys.version_info[:3])) def get_python_version_number(): pyver_str = get_python_version() return translate_version_str2int(pyver_str) def get_ipython_profiles(path=None): """list profiles in a given root directory""" if path is None: path = get_ipython_dir() files = os.listdir(path) profiles = [] for f in files: full_path = os.path.join(path, f) if os.path.isdir(full_path) and f.startswith('profile_'): profiles.append(f.split('_',1)[-1]) return profiles #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_pytango_version(): try: import PyTango try: return PyTango.Release.version except: return '0.0.0' except: return None def get_pytango_version_number(): tgver_str = get_pytango_version() if tgver_str is None: return None return translate_version_str2int(tgver_str) def get_server_for_device(device_name): db = get_tango_db() device_name = device_name.lower() server_list = db.get_server_list() for server in server_list: for dev in db.get_device_class_list(server)[::2]: if dev.lower() == device_name: return server return None def get_macroserver_for_door(door_name): """Returns the MacroServer device name in the same DeviceServer as the given door device""" _, door_name, _ = from_name_to_tango(door_name) db = get_tango_db() door_name = door_name.lower() server_list = list(db.get_server_list('MacroServer/*')) server_list += list(db.get_server_list('Sardana/*')) server_devs = None for server in server_list: server_devs = db.get_device_class_list(server) devs, klasses = server_devs[0::2], server_devs[1::2] for dev in devs: if dev.lower() == door_name: for i, klass in enumerate(klasses): if klass == 'MacroServer': return "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), devs[i]) else: return None def get_device_from_user(expected_class, dft = None): """Gets a device of the given device class from user input""" dft = print_dev_from_class(expected_class, dft) prompt = "%s name from the list" % expected_class if not dft is None: prompt += "[%s]" % dft prompt += "? " from_user = raw_input(prompt).strip() or dft name = '' try: full_name, name, _ = from_name_to_tango(from_user) except: print "Warning: the given %s does not exist" % expected_class return name try: db = get_tango_db() cl_name = db.get_class_for_device(name) class_correct = cl_name == expected_class if not class_correct: print "Warning: the given name is not a %s (it is a %s)"%(expected_class,cl_name) except Exception as e: print "Warning: unable to confirm if '%s' is valid" % name print str(e) return full_name def get_tango_db(): import PyTango tg_host = PyTango.ApiUtil.get_env_var("TANGO_HOST") db = None if tg_host is None: host,port = get_tango_host_from_user() tg_host = "%s:%d" % (host,port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() else: try: db = PyTango.Database() except: # tg host is not valid. Find a valid one host,port = get_tango_host_from_user() tg_host = "%s:%d" % (host,port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() return db def get_tango_host_from_user(): import PyTango while True: prompt = "Please enter a valid tango host (:): " from_user = raw_input(prompt).strip() try: host, port = from_user.split(':') try: port = int(port) try: socket.gethostbyname(host) try: PyTango.Database(host, port) return (host, port) except: exp = "No tango database found at %s:%d" % (host, port) except: exp = "Invalid host name %s" % host except: exp = "Port must be a number > 0" except: exp = "Invalid tango host. Must be in format :" exp = "Invalid tango host. %s " % exp print exp def print_dev_from_class(classname, dft = None): db = get_tango_db() pytg_ver = get_pytango_version_number() if pytg_ver >= 030004: server_wildcard = '*' try: exp_dev_list = db.get_device_exported_for_class(classname) except: exp_dev_list = [] else: server_wildcard = '%' exp_dev_list = [] res = None dev_list = db.get_device_name(server_wildcard,classname) tg_host = "%s:%s" % (db.get_db_host(),db.get_db_port()) print "Available",classname,"devices from",tg_host,":" for dev in dev_list: _, name, alias = from_name_to_tango(dev) out = alias or name if alias: out += ' (a.k.a. %s)' % name out = "%-25s" % out if dev in exp_dev_list: out += " (running)" print out if dft: if dft.lower() == name.lower(): res = name elif not alias is None and dft.lower() == alias.lower(): res = alias return res def from_name_to_tango(name): db = get_tango_db() alias = None c = name.count('/') # if the db prefix is there, remove it first if c == 3 or c == 1: name = name[name.index("/")+1:] elems = name.split('/') l = len(elems) if l == 3: try: alias = db.get_alias(name) if alias.lower() == 'nada': alias = None except: alias = None elif l == 1: alias = name name = db.get_device_alias(alias) else: raise Exception("Invalid device name '%s'" % name) full_name = "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), name) return full_name, name, alias #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # taurus utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def clean_up(): taurus.Manager().cleanUp() def get_taurus_core_version(): try: return TCRelease.version except: import traceback traceback.print_exc() return '0.0.0' def get_taurus_core_version_number(): tgver_str = get_taurus_core_version() if tgver_str is None: return None return translate_version_str2int(tgver_str) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Requirements checking #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def check_requirements(): r = requirements minPyTango, recPyTango = map(translate_version_str2int, r["PyTango"]) minIPython, recIPython = map(translate_version_str2int, r["IPython"]) minPython, recPython = map(translate_version_str2int, r["Python"]) minTaurusCore, recTaurusCore = map(translate_version_str2int, r["taurus.core"]) currPython = get_python_version_number() currIPython = get_ipython_version_number() currPyTango = get_pytango_version_number() currTaurusCore = get_taurus_core_version_number() errMsg = "" warnMsg = "" errPython, errIPython, errPyTango, errTaurusCore = False, False, False, False if currPython is None: errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements["Python"][0] errPython = True elif currPython < minPython: errMsg += "Spock needs Python version >= %s. Current version is %s\n" % (requirements["Python"][0], get_python_version()) errPython = True if currIPython is None: errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements["IPython"][0] errIPython = True elif currIPython < minIPython: errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % (requirements["IPython"][0], get_ipython_version()) errIPython = True if currPyTango is None: errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements["IPython"][0] errPyTango = True elif currPyTango < minPyTango: errMsg += "Spock needs PyTango version >= %s. " % requirements["PyTango"][0] if currPyTango > 0: errMsg += "Current version is %s\n" % get_pytango_version() else: errMsg += "Current version is unknown (most surely too old)\n" errPyTango = True if currTaurusCore is None: errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements["taurus.core"][0] errTaurusCore = True elif currTaurusCore < minTaurusCore: errMsg += "Spock needs taurus.core version >= %s. " % requirements["taurus.core"][0] if currTaurusCore > 0: errMsg += "Current version is %s\n" % get_taurus_core_version() else: errMsg += "Current version is unknown (most surely too old)\n" errTaurusCore = True # Warnings if not errPython and currPython < recPython: warnMsg += "Spock recommends Python version >= %s. Current version " \ "is %s\n" % (requirements["Python"][1], get_python_version()) if not errIPython and currIPython < recIPython: warnMsg += "Spock recommends IPython version >= %s. Current version " \ "is %s\n" % (requirements["IPython"][1], get_ipython_version()) if not errPyTango and currPyTango < recPyTango: warnMsg += "Spock recommends PyTango version >= %s. Current version " \ "is %s\n" % (requirements["PyTango"][1], get_pytango_version()) if not errTaurusCore and currTaurusCore < recTaurusCore: warnMsg += "Spock recommends taurus.core version >= %s. Current " \ "version is %s\n" % (requirements["taurus.core"][1], get_taurus_core_version()) if errMsg: errMsg += warnMsg raise exception.SpockMissingRequirement, errMsg if warnMsg: raise exception.SpockMissingRecommended, warnMsg return True def _get_dev(dev_type): spock_config = get_config().Spock taurus_dev = None taurus_dev_var = "_" + dev_type if hasattr(spock_config, taurus_dev_var): taurus_dev = getattr(spock_config, taurus_dev_var) if taurus_dev is None: dev_name = getattr(spock_config, dev_type + '_name') factory = taurus.Factory() taurus_dev = factory.getDevice(dev_name) import PyTango dev = PyTango.DeviceProxy(dev_name) setattr(spock_config, dev_type, dev) setattr(spock_config, taurus_dev_var, taurus_dev) shell = get_shell() dev_type_upper = dev_type.upper() shell.user_ns[dev_type_upper] = dev shell.user_ns["_" + dev_type_upper] = taurus_dev return taurus_dev def get_door(): return _get_dev('door') def get_macro_server(): return _get_dev('macro_server') def _macro_completer(self, event): """Method called by the IPython autocompleter. It will determine possible values for macro arguments. """ ms = get_macro_server() macro_name = event.command.lstrip('%') # calculate parameter index param_idx = len(event.line.split()) - 1 if not event.line.endswith(' '): param_idx -= 1 # get macro info info = ms.getMacroInfoObj(macro_name) # if macro doesn't have parameters return if param_idx < 0 or not info.hasParams() : return # get the parameter info possible_params = info.getPossibleParams(param_idx) # return the existing elements for the given parameter type if possible_params: res = [] for param in possible_params: res.extend(ms.getElementNamesWithInterface(param['type'])) return res def expose_magic(name, fn, completer_func=_macro_completer): shell = get_shell() fn.old_magic = shell.define_magic(name, fn) fn.old_completer = completer_func if completer_func is None: return # enable macro param completion if completer_func is not None: shell.set_hook('complete_command', completer_func, str_key = name) shell.set_hook('complete_command', completer_func, str_key = '%'+name) def unexpose_magic(name): shell = get_shell() mg_name = 'magic_' + name if hasattr(shell, mg_name): magic_fn = getattr(shell, mg_name) delattr(shell, mg_name) if hasattr(magic_fn, 'old_magic') and magic_fn.old_magic is not None: expose_magic(name, magic_fn.old_magic, magic_fn.old_completer) def expose_variable(name, value): get_shell().user_ns[name] = value def expose_variables(d): get_shell().user_ns.update(d) def unexpose_variable(name): user_ns = get_shell().user_ns del user_ns[name] def create_spock_profile(userdir, dft_profile, profile, door_name=None): """Create a profile file from a profile template file """ if not os.path.isdir(userdir): ProfileDir.create_profile_dir(userdir) p_dir = ProfileDir.create_profile_dir_by_name(userdir, profile) config_file_name = BaseIPythonApplication.config_file_name.default_value abs_config_file_name = os.path.join(p_dir.location, config_file_name) create_config = True if os.path.isfile(abs_config_file_name): create_config = ask_yes_no("Spock configuration file already exists. "\ "Do you wish to replace it?", default='y') if not create_config: return src_data = """\ \"\"\"Settings for Spock session\"\"\" # # Please do not delete the next lines has they are used to check the version # number for possible upgrades # spock_creation_version = {version} # door_name = {door_name} # import PyTango.ipython import sardana.spock.genutils from sardana.spock.config import Spock config = get_config() config.Spock.macro_server_name = '{macroserver_name}' config.Spock.door_name = '{door_name}' load_subconfig('ipython_config.py', profile='default') sardana.spock.load_config(config) # Put any additional environment here and/or overwrite default sardana config config.IPKernelApp.pylab = 'inline' """ # # Discover door name # if door_name is None: door_name = get_device_from_user("Door", profile) else: full_door_name, door_name, _ = from_name_to_tango(door_name) door_name = full_door_name # # Discover macro server name # ms_name = get_macroserver_for_door(door_name) dest_data = src_data.format(version=release.version, macroserver_name=ms_name, door_name=door_name) sys.stdout.write('Storing %s in %s... ' % (config_file_name, p_dir.location)) sys.stdout.flush() with file(abs_config_file_name, "w") as f: f.write(dest_data) f.close() sys.stdout.write(MSG_DONE + '\n') def check_for_upgrade(ipy_profile_file, ipythondir, session, profile): # Check if the current profile is up to date with the spock version spock_profile_ver_str = '0.0.0' door_name = None # search for version and door inside the ipy_profile file for i, line in enumerate(ipy_profile_file): if i > 20 : break; # give up after 20 lines if line.startswith('# spock_creation_version = '): spock_profile_ver_str = line[line.index('=')+1:].strip() if line.startswith('# door_name = '): door_name = line[line.index('=')+1:].strip() # convert version from string to numbers spocklib_ver = translate_version_str2int(release.version) spock_profile_ver = translate_version_str2int(spock_profile_ver_str) if spocklib_ver == spock_profile_ver: return if spocklib_ver < spock_profile_ver: print '%sYour spock profile (%s) is newer than your spock version ' \ '(%s)!' % (SpockTermColors.Brown, spock_profile_ver_str, release.version) print 'Please upgrade spock or delete the current profile %s' % SpockTermColors.Normal sys.exit(1) # there was no version track of spock profiles since spock 0.2.0 so change # the message if spock_profile_ver_str == '0.0.0': spock_profile_ver_str = '<= 0.2.0' msg = 'Your current spock door extension profile has been created with spock %s.\n' \ 'Your current spock door extension version is %s, therefore a profile upgrade is needed.\n' \ % (spock_profile_ver_str, release.version) print msg prompt = 'Do you wish to upgrade now (warn: this will shutdown the current spock session) ([y]/n)? ' r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipythondir, session, profile, door_name) sys.exit(0) def get_args(argv): script_name = argv[0] _, session = os.path.split(script_name) script_name = os.path.realpath(script_name) macro_server = None door = None # Define the profile file profile = "spockdoor" try: for _, arg in enumerate(argv[:1]): if arg.startswith('--profile='): profile=arg[10:] break else: argv.append("--profile=" + profile) except: pass ipython_dir = get_ipython_dir() try: ProfileDir.find_profile_dir_by_name(ipython_dir, profile) except ProfileDirError: r = '' while not r in ('y','n'): prompt = 'Profile \'%s\' does not exist. Do you want to create '\ 'one now ([y]/n)? ' % profile r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipython_dir, session, profile) else: sys.stdout.write('No spock door extension profile was created. Starting normal spock...\n') sys.stdout.flush() profile = '' # inform the shell of the profile it should use if not '--profile=' in argv and profile: argv.append('--profile=' + profile) user_ns = { 'MACRO_SERVER_NAME' : macro_server, 'DOOR_NAME' : door, 'PROFILE' : profile } return user_ns #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Useful constants #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- MSG_G = '[%s%%s%s]' % (SpockTermColors.Green, SpockTermColors.Normal) MSG_R = '[%s%%s%s]' % (SpockTermColors.Red, SpockTermColors.Normal) MSG_FAILED = MSG_R % 'FAILED' MSG_FAILED_WR = MSG_R % 'FAILED: %s' MSG_ERROR = MSG_R % 'ERROR' MSG_DONE = MSG_G % 'DONE' MSG_OK = MSG_G % 'OK' #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # initialization methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def init_taurus(): # the CodecFactory is not thread safe. There are two attributes who will # request for it in the first event at startup in different threads # therefore this small hack: make sure CodecFactory is initialized. CodecFactory() factory = taurus.Factory() import sardana.spock.spockms macroserver = sardana.spock.spockms factory.registerDeviceClass('MacroServer', macroserver.SpockMacroServer) mode = get_gui_mode() if mode == 'qt': factory.registerDeviceClass('Door', macroserver.QSpockDoor) else: factory.registerDeviceClass('Door', macroserver.SpockDoor) def load_ipython_extension(ipython): import sardana.spock.magic magic = sardana.spock.magic init_taurus() config = ipython.config user_ns = ipython.user_ns user_ns['MACRO_SERVER_NAME'] = config.Spock.macro_server_name user_ns['MACRO_SERVER_ALIAS'] = config.Spock.macro_server_alias user_ns['DOOR_NAME'] = config.Spock.door_name user_ns['DOOR_ALIAS'] = config.Spock.door_alias user_ns['DOOR_STATE'] = "" #shell.set_hook('late_startup_hook', magic.spock_late_startup_hook) ipython.set_hook('pre_prompt_hook', magic.spock_pre_prompt_hook) #if ip.IP.alias_table.has_key('mv'): # del ip.IP.alias_table['mv'] door = get_door() macro_server = get_macro_server() # Initialize the environment expose_variable(ENV_NAME, macro_server.getEnvironment()) new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr(IPython.core.magic, 'magics_class') if new_style_magics: @IPython.core.magic.magics_class class Sardana(IPython.core.magic.Magics): debug = IPython.core.magic.line_magic(magic.debug) www = IPython.core.magic.line_magic(magic.www) post_mortem = IPython.core.magic.line_magic(magic.post_mortem) spsplot = IPython.core.magic.line_magic(magic.post_mortem) macrodata = IPython.core.magic.line_magic(magic.macrodata) edmac = IPython.core.magic.line_magic(magic.edmac) showscan = IPython.core.magic.line_magic(magic.showscan) expconf = IPython.core.magic.line_magic(magic.expconf) ipython.register_magics(Sardana) else: expose_magic('debug', magic.debug, magic.debug_completer) expose_magic('www', magic.www, magic.www_completer) expose_magic('post_mortem', magic.post_mortem, magic.post_mortem_completer) expose_magic('spsplot', magic.spsplot, None) expose_magic('macrodata', magic.macrodata, None) expose_magic('edmac', magic.edmac, None) expose_magic('showscan', magic.showscan, None) expose_magic('expconf', magic.expconf, None) door.setConsoleReady(True) def unload_ipython_extension(ipython): pass def load_config(config): spockver = release.version pyver = get_python_version() ipyver = get_ipython_version() pytangover = get_pytango_version() tauruscorever = get_taurus_core_version() door = config.Spock.door_name if not hasattr(config.Spock, 'macro_server_name'): macro_server = get_macroserver_for_door(door) else: macro_server = config.Spock.macro_server_name full_door_tg_name, door_tg_name, door_tg_alias = from_name_to_tango(door) door_alias = door_tg_alias or door_tg_name full_ms_tg_name, ms_tg_name, ms_tg_alias = from_name_to_tango(macro_server) ms_alias = ms_tg_alias or ms_tg_name config.Spock.macro_server_name = full_ms_tg_name config.Spock.door_name = full_door_tg_name config.Spock.macro_server_alias = ms_alias config.Spock.door_alias = door_alias d = { "version" : spockver, "pyver" : pyver, "ipyver" : ipyver, "pytangover" : pytangover, "taurusver" : tauruscorever, #"profile" : ip.user_ns["PROFILE"], "door" : door_alias } d.update(TermColors.__dict__) gui_mode = get_gui_mode() banner = """\ %(Purple)sSpock %(version)s%(Normal)s -- An interactive laboratory application. help -> Spock's help system. object? -> Details about 'object'. ?object also works, ?? prints more. """ banner = banner % d banner = banner.format(**d) ipy_ver = get_ipython_version_number() # ------------------------------------ # Application # ------------------------------------ app = config.Application app.log_level = 30 # ------------------------------------ # BaseIPythonApplication # ------------------------------------ i_app = config.BaseIPythonApplication extensions = getattr(i_app, 'extensions', []) extensions.extend(["PyTango.ipython", "sardana.spock"]) i_app.extensions = extensions # ------------------------------------ # InteractiveShell # (IPython.core.interactiveshell) # ------------------------------------ i_shell = config.InteractiveShell i_shell.autocall = 0 i_shell.automagic = True i_shell.color_info = True i_shell.colors = 'Linux' i_shell.deep_reload = True i_shell.confirm_exit = False if ipy_ver >= 1200: # ------------------------------------ # PromptManager (ipython >= 0.12) # ------------------------------------ prompt = config.PromptManager prompt.in_template = '{DOOR_ALIAS} [\\#]: ' prompt.in2_template = ' .\\D.: ' prompt.out_template = 'Result [\\#]: ' prompt.color_scheme = 'Linux' else: # (Deprecated in ipython >= 0.12 use PromptManager.in_template) i_shell.prompt_in1 = config.Spock.door_alias + ' [\\#]: ' # (Deprecated in ipython >= 0.12 use PromptManager.in2_template) i_shell.prompt_in2 = ' .\\D.: ' # (Deprecated in ipython >= 0.12 use PromptManager.out_template) i_shell.prompt_out = 'Result [\\#]: ' # (Deprecated in ipython >= 0.12 use PromptManager.justify) i_shell.prompts_pad_left = True # ------------------------------------ # IPCompleter # ------------------------------------ completer = config.IPCompleter completer.omit__names = 2 completer.greedy = False # ------------------------------------ # InteractiveShellApp # ------------------------------------ i_shell_app = config.InteractiveShellApp i_shell_app.ignore_old_config = True # ------------------------------------ # TerminalIPythonApp: options for the IPython terminal (and not Qt Console) # ------------------------------------ term_app = config.TerminalIPythonApp term_app.display_banner = True term_app.gui = gui_mode term_app.pylab='qt' #term_app.nosep = False #term_app.classic = True # ------------------------------------ # IPKernelApp: options for the Qt Console # ------------------------------------ #kernel_app = config.IPKernelApp ipython_widget = config.IPythonWidget ipython_widget.in_prompt = ' Spock [%i]: ' ipython_widget.out_prompt = 'Result [%i]: ' ipython_widget.input_sep = '\n' ipython_widget.output_sep = '' ipython_widget.output_sep2 = '' ipython_widget.enable_calltips = True if ipy_ver >= 1300: ipython_widget.gui_completion = 'droplist' else: ipython_widget.gui_completion = True ipython_widget.ansi_codes = True ipython_widget.paging = 'inside' #ipython_widget.pylab = 'inline' # ------------------------------------ # ConsoleWidget # ------------------------------------ # console_widget = config.ConsoleWidget # ------------------------------------ # FrontendWidget # ------------------------------------ frontend_widget = config.FrontendWidget frontend_widget.banner = banner # ------------------------------------ # TerminalInteractiveShell # ------------------------------------ term_i_shell = config.TerminalInteractiveShell term_i_shell.autocall = 2 term_i_shell.automagic = True #term_i_shell.editor = 'gedit' #term_i_shell.editor = 'nano' term_i_shell.banner1 = banner term_i_shell.banner2 = "Connected to " + door_alias + "\n" #term_app.banner1 = banner #term_app.banner2 = "Connected to " + door_alias + "\n" # ------------------------------------ # InlineBackend # ------------------------------------ inline_backend = config.InlineBackend inline_backend.figure_format = 'svg' # ------------------------------------ # InteractiveShellEmbed # ------------------------------------ #i_shell_embed = config.InteractiveShellEmbed # ------------------------------------ # NotebookApp # ------------------------------------ #notebook_app = config.NotebookApp # ------------------------------------ # NotebookManager # ------------------------------------ #notebook_manager = config.NotebookManager # ------------------------------------ # ZMQInteractiveShell # ------------------------------------ #zmq_i_shell = config.ZMQInteractiveShell # Tell console everything is ready. config.Spock.ready = True return config def start(user_ns=None): # Make sure the log level is changed to warning CodecFactory() taurus.setLogLevel(taurus.Warning) try: check_requirements() except exception.SpockMissingRequirement, requirement: print str(requirement) sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) user_ns = user_ns or {} try: user_ns.update(get_args(sys.argv)) except exception.SpockException, e: print e.message print 'Starting normal IPython console' except KeyboardInterrupt: print "\nUser pressed Ctrl+C. Exiting..." sys.exit() except Exception, e: print 'spock exited with an unmanaged exception: %s' % str(e) sys.exit(-2) app = TerminalIPythonApp.instance() app.initialize() #config = get_config() return app def mainloop(app=None, user_ns=None): if app is None: app = start(user_ns) app.start() def prepare_input_handler(): # initialize input handler as soon as possible import sardana.spock.inputhandler _ = sardana.spock.inputhandler.InputHandler() def prepare_cmdline(argv=None): if argv is None: argv = sys.argv script_name = argv[0] _, session = os.path.split(script_name) script_name = os.path.realpath(script_name) # Define the profile file profile, append_profile = "spockdoor", True try: for _, arg in enumerate(argv[:1]): if arg.startswith('--profile='): profile=arg[10:] append_profile = False break except: pass ipython_dir = get_ipython_dir() try: ProfileDir.find_profile_dir_by_name(ipython_dir, profile) except ProfileDirError: r = '' while not r in ('y', 'n'): prompt = "Profile '%s' does not exist. Do you want to create "\ "one now ([y]/n)? " % profile r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipython_dir, session, profile) else: sys.stdout.write('No spock profile was created. ' 'Starting ipython with default profile...\n') sys.stdout.flush() append_profile = False if append_profile: argv.append("--profile=" + profile) def run(): from IPython.utils.traitlets import Unicode from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget class SpockConsole(RichIPythonWidget): banner = Unicode(config=True) def _banner_default(self): config = get_config() return config.FrontendWidget.banner import IPython.frontend.qt.console.qtconsoleapp IPythonQtConsoleApp = IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp IPythonQtConsoleApp.widget_factory = SpockConsole try: check_requirements() except exception.SpockMissingRequirement, requirement: print str(requirement) sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) prepare_input_handler() prepare_cmdline() launch_new_instance() sardana-1.2.0/src/sardana/spock/__init__.py0000644000234100017500000000222212174204307022156 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides spock""" from genutils import load_ipython_extension, unload_ipython_extension, \ load_config sardana-1.2.0/src/sardana/spock/colors.py0000644000234100017500000001003112174204307021715 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the sardana library""" __all__ = ['make_color_table', 'TermColors', 'HTMLColors', 'TermTangoColors', 'TermTauSWDevStateColors', 'HTMLTangoColors'] __docformat__ = 'restructuredtext' def make_color_table(in_class,use_name=False): """Build a set of color attributes in a class. Helper function for building the *TermColors classes.""" color_templates = ( ("Black" , "0;30"), ("Red" , "0;31"), ("Green" , "0;32"), ("Brown" , "0;33"), ("Blue" , "0;34"), ("Purple" , "0;35"), ("Cyan" , "0;36"), ("LightGray" , "0;37"), ("DarkGray" , "1;30"), ("LightRed" , "1;31"), ("LightGreen" , "1;32"), ("Yellow" , "1;33"), ("LightBlue" , "1;34"), ("LightPurple" , "1;35"), ("LightCyan" , "1;36"), ("White" , "1;37"), ) for name,value in color_templates: if use_name: setattr(in_class,name,in_class._base % name) else: setattr(in_class,name,in_class._base % value) class TermColors: """Color escape sequences. This class defines the escape sequences for all the standard (ANSI?) colors in terminals. Also defines a NoColor escape which is just the null string, suitable for defining 'dummy' color schemes in terminals which get confused by color escapes. This class should be used as a mixin for building color schemes. Basicaly this class is just a copy of IPython.ColorANSI.TermColors class""" NoColor = '' # for color schemes in color-less terminals. Normal = '\033[0m' # Reset normal coloring _base = '\033[%sm' # Template for all other colors class HTMLColors: NoColor = '' Normal = '' _base = '' # Build the actual color table as a set of class attributes: make_color_table(TermColors) make_color_table(HTMLColors,True) import PyTango TermTangoColors = { PyTango.DevState.ON : TermColors.Green, PyTango.DevState.ALARM : TermColors.Brown, PyTango.DevState.FAULT : TermColors.Red, PyTango.DevState.UNKNOWN : TermColors.LightGray, None : TermColors.DarkGray } from taurus.core import TaurusSWDevState TermTauSWDevStateColors = { TaurusSWDevState.Uninitialized : TermColors.LightGray, TaurusSWDevState.Running : TermColors.Green, TaurusSWDevState.Shutdown : TermColors.DarkGray, TaurusSWDevState.Crash : TermColors.Red, TaurusSWDevState.EventSystemShutdown : TermColors.Brown } HTMLTangoColors = { PyTango.DevState.ON : HTMLColors.Green, PyTango.DevState.ALARM : HTMLColors.Brown, PyTango.DevState.FAULT : HTMLColors.Red, PyTango.DevState.UNKNOWN : HTMLColors.LightGray, None : HTMLColors.DarkGray }sardana-1.2.0/src/sardana/spock/config.py0000644000234100017500000000271312174204307021671 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock's ipython configuration class""" __all__ = ['Spock'] from IPython.config.configurable import Configurable from IPython.utils.traitlets import Unicode, Bool class Spock(Configurable): macro_server_name = Unicode(config=True) door_name = Unicode(config=True) macro_server_alias = Unicode(config=True) door_alias = Unicode(config=True) ready = Bool(default_value=False, config=True)sardana-1.2.0/src/sardana/spock/exception.py0000644000234100017500000000266512174204307022430 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the sardana library""" __all__ = ['SpockException', 'SpockBadInstallation', 'SpockMissingRequirement', 'SpockMissingRecommended'] __docformat__ = 'restructuredtext' class SpockException(Exception): pass class SpockBadInstallation(SpockException): pass class SpockMissingRequirement(SpockException): pass class SpockMissingRecommended(SpockException): pass sardana-1.2.0/src/sardana/spock/genutils.py0000644000234100017500000000405112174204307022253 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock generic utilities""" def translate_version_str2list(version_str): """Translates a version string in format 'x[.y[.z[...]]]' into a list of numbers""" if version_str is None: ver = [0, 0] else: ver = [] for i in version_str.split(".")[:2]: try: i = int(i) except: i = 0 ver.append(i) return ver def get_ipython_version(): """Returns the current IPython version""" import IPython v = None try: try: v = IPython.Release.version except: try: v = IPython.release.version except: pass except: pass return v def get_ipython_version_list(): ipv_str = get_ipython_version() return translate_version_str2list(ipv_str) ipv = get_ipython_version_list() if ipv >= [0, 10] and ipv < [0, 11]: from ipython_00_10.genutils import * else: from ipython_00_11.genutils import * sardana-1.2.0/src/sardana/spock/inputhandler.py0000644000234100017500000001225312174204307023121 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################# ## ## This file is part of Taurus, a Tango User Interface Library ## ## http://www.tango-controls.org/static/taurus/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Taurus is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Taurus is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Taurus. If not, see . ## ############################################################################# """Spock submodule. It contains an input handler""" __all__ = ['SpockInputHandler', 'InputHandler'] __docformat__ = 'restructuredtext' import sys from multiprocessing import Process, Pipe import genutils from taurus.core import TaurusManager from taurus.core.util import Singleton from taurus.core.tango.sardana.macroserver import BaseInputHandler from taurus.qt import Qt from taurus.qt.qtgui.dialog import TaurusMessageBox, TaurusInputDialog class SpockInputHandler(BaseInputHandler): def __init__(self): # don't call super __init__ on purpose self._input = genutils.spock_input def input(self, input_data=None): if input_data is None: input_data = {} prompt = input_data.get('prompt') ret = dict(input=None, cancel=False) try: if prompt is None: ret['input'] = self._input() else: ret['input'] = self._input(prompt) except: ret['cancel'] = True return ret def input_timeout(self, input_data): print "SpockInputHandler input timeout" class MessageHandler(Qt.QObject): def __init__(self, conn, parent=None): Qt.QObject.__init__(self, parent) self._conn = conn self._dialog = None self.connect(self, Qt.SIGNAL("messageArrived"), self.on_message) def handle_message(self, input_data): self.emit(Qt.SIGNAL("messageArrived"), input_data) def on_message(self, input_data): msg_type = input_data['type'] if msg_type == 'input': if 'macro_name' in input_data and 'title' not in input_data: input_data['title'] = input_data['macro_name'] self._dialog = dialog = TaurusInputDialog(input_data=input_data) dialog.activateWindow() dialog.exec_() ok = dialog.result() value = dialog.value() ret = dict(input=None, cancel=False) if ok: ret['input'] = value else: ret['cancel'] = True self._conn.send(ret) elif msg_type == 'timeout': dialog = self._dialog if dialog: dialog.close() class InputHandler(Singleton, BaseInputHandler): def __init__(self): # don't call super __init__ on purpose pass def init(self, *args, **kwargs): self._conn, child_conn = Pipe() self._proc = proc = Process(target=self.safe_run, name="SpockInputHandler", args=(child_conn,)) proc.daemon = True proc.start() def input(self, input_data=None): # parent process data_type = input_data.get('data_type', 'String') if isinstance(data_type, (str, unicode)): ms = genutils.get_macro_server() interfaces = ms.getInterfaces() if data_type in interfaces: input_data['data_type'] = [ elem.name for elem in interfaces[data_type].values() ] self._conn.send(input_data) ret = self._conn.recv() return ret def input_timeout(self, input_data): # parent process self._conn.send(input_data) def safe_run(self, conn): # child process try: return self.run(conn) except Exception, e: msgbox = TaurusMessageBox(*sys.exc_info()) conn.send((e, False)) msgbox.exec_() def run(self, conn): # child process self._conn = conn app = Qt.QApplication.instance() if app is None: app = Qt.QApplication([]) app.setQuitOnLastWindowClosed(False) self._msg_handler = MessageHandler(conn) TaurusManager().addJob(self.run_forever, None) app.exec_() conn.close() print "Quit input handler" def run_forever(self): # child process message, conn = True, self._conn while message: message = conn.recv() if not message: continue self._msg_handler.handle_message(message) app = Qt.QApplication.instance() if app: app.quit() sardana-1.2.0/src/sardana/spock/magic.py0000644000234100017500000002107712174204307021510 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Initial magic commands and hooks for the spock IPython environment""" __all__ = ['expconf', 'showscan', 'spsplot', 'debug_completer', 'debug', 'www', 'post_mortem', 'macrodata', 'edmac', 'spock_late_startup_hook', 'spock_pre_prompt_hook'] from genutils import page, get_door, get_macro_server, ask_yes_no, arg_split from genutils import MSG_DONE, MSG_FAILED from genutils import get_ipapi def expconf(self, parameter_s=''): """Launches a GUI for configuring the environment variables for the experiments (scans)""" try: from taurus.qt.qtgui.extra_sardana import ExpDescriptionEditor except: print "Error importing ExpDescriptionEditor "\ "(hint: is taurus extra_sardana installed?)" return doorname = get_door().name() #=========================================================================== ## ugly hack to avoid ipython/qt thread problems #e.g. see ## https://sourceforge.net/p/sardana/tickets/10/ ## this hack does not allow inter-process communication and leaves the ## widget open after closing spock ## @todo: investigate cause of segfaults when using launching qt widgets from ipython # #w = ExpDescriptionEditor(door=doorname) #w.show() #launching it like this, produces the problem of https://sourceforge.net/p/sardana/tickets/10/ import subprocess import sys fname = sys.modules[ExpDescriptionEditor.__module__].__file__ args = ['python', fname, doorname] subprocess.Popen(args) #=========================================================================== def showscan(self, parameter_s=''): """Shows a scan in a GUI. :param scan_id: scan number [default: None, meaning show last scan]""" params = parameter_s.split() door = get_door() online, scan_nb = False, None if len(params) > 0: if params[0].lower() == 'online': online = True else: scan_nb = int(params[0]) door.show_scan(scan_nb, online=online) def spsplot(self, parameter_s=''): get_door().plot() def debug_completer(self, event): # calculate parameter index param_idx = len(event.line.split()) - 1 if not event.line.endswith(' '): param_idx -= 1 if param_idx == 0: return ('off', 'on') def debug(self, parameter_s=''): """Activate/Deactivate macro server debug output""" params = parameter_s.split() door = get_door() if len(params) == 0: s = door.getDebugMode() and 'on' or 'off' print "debug mode is %s" % s return elif len(params) == 1: s = params[0].lower() if not s in ('off', 'on'): print "Usage: debug [on|off]" return door.setDebugMode(s == 'on') print "debug mode is now %s" % s else: print "Usage: debug [on|off]" def www(self, parameter_s=''): """What went wrong. Prints the error message from the last macro execution""" import PyTango door = get_door() try: last_macro = door.getLastRunningMacro() if last_macro is None: door.writeln("No macro ran from this console yet!") return if not hasattr(last_macro, 'exc_stack') or last_macro.exc_stack is None: door.writeln("Sorry, but no exception occurred running last " \ "macro (%s)." % last_macro.name) return exc = "".join(last_macro.exc_stack) door.write(exc) except Exception, e: door.writeln("Unexpected exception occurred executing www:", stream=door.Error) door.writeln(str(e), stream=door.Error) import traceback traceback.print_exc() def post_mortem(self, parameter_s='', from_www=False): """Post mortem analysis. Prints the local stream buffer. If no stream is specified, it reads 'debug' stream. Valid values are output, critical, error, warning, info, debug, result""" params = parameter_s.split() or ['debug'] door = get_door() logger = door.getLogObj(params[0]) msg = "" if not from_www: try: msg = "\n".join(logger.read(cache=False).value) except: from_www = True if from_www: msg = "------------------------------\n" \ "Server is offline.\n" \ "This is a post mortem analysis\n" \ "------------------------------\n" msg += "\n".join(logger.getLogBuffer()) page(msg) def macrodata(self, parameter_s=''): """macrodata Returns the data produced by the last macro""" door = get_door() macro_data = door.read_attribute("RecordData") import taurus.core.util factory = taurus.core.util.CodecFactory() data = factory.decode(macro_data.value) return data def edmac(self, parameter_s=''): """edmac [] Returns the contents of the macro file which contains the macro code for the given macro name. If the module is given and it does not exist a new one is created. If the given module is a simple module name and it does not exist, it will be created on the first directory mentioned in the MacroPath""" import os import tempfile import PyTango import taurus.core.util ms = get_macro_server() pars = arg_split(parameter_s, posix=True) if len(pars) == 1: macro_name = pars[0] macro_info = ms.getMacroInfoObj(macro_name) if macro_info is None: print "Macro '%s' could not be found" % macro_name return macro_lib = macro_info.module else: macro_name, macro_lib = pars macro_info = (macro_lib, macro_name) print 'Opening %s.%s...' % macro_info try: remote_fname, code, line_nb = ms.GetMacroCode(macro_info) except PyTango.DevFailed, e: taurus.core.util.print_DevFailed(e) return fd, local_fname = tempfile.mkstemp(prefix='spock_%s_' % pars[0], suffix='.py', text=True) os.write(fd, code) os.close(fd) cmd = 'edit -x -n %s %s' % (line_nb, local_fname) ip = get_ipapi() ip.magic(cmd) if ask_yes_no('Do you want to apply the new code on the server?', 'y'): print 'Storing...', try: f = file(local_fname) try: new_code = f.read() ms.SetMacroCode([remote_fname, new_code]) print MSG_DONE except Exception, e: print MSG_FAILED print 'Reason:', str(e) f.close() except: print 'Could not open file \'%s\' for safe transfer to the ' \ 'server' % local_fname print 'Did you forget to save?' else: print "Discarding changes..." #if os.path.exists(local_fname): # if ask_yes_no('Delete temporary file \'%s\'?' % local_fname, 'y'): # os.remove(local_fname) # bkp = '%s~' % local_fname # if os.path.exists(bkp): # os.remove(bkp) try: os.remove(local_fname) except: pass def spock_late_startup_hook(self): try: get_door().setConsoleReady(True) except: import traceback print "Exception in spock_late_startup_hook:" traceback.print_exc() def spock_pre_prompt_hook(self): try: get_door().pre_prompt_hook(self) except: import traceback print "Exception in spock_pre_prompt_hook:" traceback.print_exc() #def spock_pre_runcode_hook(self): # print "spock_pre_runcode_hook" # return None sardana-1.2.0/src/sardana/spock/parameter.py0000644000234100017500000001322412174204307022403 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Parameter parsing""" __all__ = ['AbstractParam', 'Param', 'ParamRepeat', 'ParamList'] import sys class AbstractParam: def __init__(self, name=None, desc=None): self.name = name self.desc = desc def getParam(self,idx=0): return self def getParamStr(self): return "<"+self.name+">" def getParamDescr(self): str = self.name + " (" + self.type + ") - " + self.desc if self.defvalue != 'None': str = str + "\nDefault value: " + self.defvalue return str def getParamCount(self): return 1 def formatParamValue(self,value): return value def __str__(self): return "%s(%s)" % (self.__class__.__name__, self.name) class Param(AbstractParam): def __init__(self, name=None, type_name=None, desc=None, defvalue=None, from_array=None): AbstractParam.__init__(self,name=name,desc=desc) self.type = type_name self.defvalue = defvalue if from_array is not None: for key in ['name', 'type', 'desc', 'defvalue']: setattr(self, key, from_array.read()) def formatParamValue(self,value): ret = value if self.type == "File": f = open(ret,'r') ret = f.read() f.close() return ret class ParamRepeat(AbstractParam): def __init__(self, name=None, desc=None, opts=None, param_def=None, from_array=None): AbstractParam.__init__(self,name=name,desc=desc) self.opts = opts self.param_def = param_def if from_array is not None: self.name = from_array.read() type_name = from_array.read() if type_name != 'ParamRepeat': msg = 'Expecting "ParamRepeat" type, got ' + type_name raise ValueError, msg self.desc = from_array.read() opt_str = from_array.read() opt_list = opt_str.split(', ') opts = {} for opt_str in opt_list: name, val = opt_str.split('=') if val == repr(None): val = None else: try: val = int(val) except: pass opts[name] = val self.opts = opts self.param_def = ParamList(from_array=from_array) def getParam(self,idx=0): idx = idx % len(self.param_def.pars) return self.param_def.getParam(idx) def getParamStr(self): return "[" + self.param_def.getParamStr() + " ]" def getParamDescr(self): return self.param_def.getParamDescr() def getParamCount(self): return self.param_def.getParamCount() def formatParamValue(self,value): return self.param_def.formatParamValue(value) class ParamList(AbstractParam): def __init__(self, from_array): AbstractParam.__init__(self,name="ParamList",desc="List of parameters") self.pars = [] self.has_param_repeat = False npars = int(from_array.read()) for i in range(npars): if from_array[1] == 'ParamRepeat': par = ParamRepeat(from_array=from_array) self.has_param_repeat = True else: par = Param(from_array=from_array) self.pars.append(par) def getParam(self,idx=0): par_nb = len(self.pars) if idx < par_nb: par = idx return self.pars[idx].getParam(0) else: for i in range(par_nb): local_idx = idx - i local_nb = self.pars[i].getParamCount() if local_idx < local_nb: return self.pars[i].getParam(local_idx) def getParamStr(self): str = "" for par in self.pars: str = str + " " + par.getParamStr() return str def getParamDescr(self): str = "" for par in self.pars: str = str + "\n" + par.getParamDescr() return str def getParamCount(self): nb = 0 for par in self.pars: local_nb = par.getParamCount() if local_nb == sys.maxint: return sys.maxint nb += local_nb return nb def formatParamValue(self,value): # for now we are not able to handle ParamRepeat with special value format if self.has_param_repeat: return value for i,v in enumerate(value): value[i] = self.pars[i].formatParamValue(v) return valuesardana-1.2.0/src/sardana/spock/release.py0000644000234100017500000000434412174204307022046 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Release data for the Spock project. """ # Name of the package for release purposes. This is the name which labels # the tarballs and RPMs made by distutils, so it's best to lowercase it. name = 'spock' # For versions with substrings (like 0.6.16.svn), use an extra . to separate # the new substring. We have to avoid using either dashes or underscores, # because bdist_rpm does not accept dashes (an RPM) convention, and # bdist_deb does not accept underscores (a Debian convention). revision = '1' #version = '0.8.1.svn.r' + revision.rstrip('M') version = '1.0.0' description = "An enhanced interactive Macro Server shell." long_description = \ """ Spock provides an interactive environment for interacting with the Tango MacroServer Device. It is completely based on IPython which itself provides a replacement for the interactive Python interpreter with extra functionality. """ license = 'GNU' authors = {'Tiago' : ('Tiago Coutinho','tiago.coutinho@esrf.fr'), 'Pascual-Izarra' : ('Carlos Pascual-Izarra','cpascual@cells.es') } url = '' download_url = '' platforms = ['Linux','Windows XP/2000/NT','Windows 95/98/ME'] keywords = ['Sardana', 'Interactive', 'MacroServer', 'Tango', 'Shell'] sardana-1.2.0/src/sardana/spock/spockms.py0000644000234100017500000005023012174204307022100 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the spock macroserver connectivity""" __all__ = ['GUIViewer', 'SpockBaseDoor', 'QSpockDoor', 'SpockDoor', 'SpockMacroServer'] import os import PyTango from taurus.core import TaurusEventType, TaurusSWDevState from sardana.sardanautils import is_pure_str, is_non_str_seq import genutils from .inputhandler import SpockInputHandler, InputHandler CHANGE_EVTS = TaurusEventType.Change, TaurusEventType.Periodic if genutils.get_gui_mode() == 'qt': from taurus.qt.qtcore.tango.sardana.macroserver import QDoor, QMacroServer BaseDoor = QDoor BaseMacroServer = QMacroServer BaseGUIViewer = object else: from taurus.core.tango.sardana.macroserver import BaseDoor, BaseMacroServer BaseGUIViewer = object class GUIViewer(BaseGUIViewer): def __init__(self, door=None): BaseGUIViewer.__init__(self) self._door = door def run(self): self.plot() def show_scan(self, scan_nb=None, scan_history_info=None, directory_map=None): if scan_nb is None and scan_history_info is None: #=================================================================== ##Hack to avoid ipython-qt issues. See similar workaround in expconf magic command ## @todo: do this in a better way #import taurus.qt.qtgui.plot #w = taurus.qt.qtgui.plot.TaurusTrend() #w.model = "scan://" + self._door.getNormalName() #w.show() import subprocess args = ['taurustrend','scan://%s'%self._door.getNormalName()] subprocess.Popen(args) #=================================================================== return scan_dir, scan_file = None, None if scan_nb is None: for scan in reversed(scan_history_info): scan_dir = scan.get('ScanDir') scan_file = scan.get('ScanFile') if scan_dir is None or scan_file is None: continue if not isinstance(scan_file, (str, unicode)): scan_file = scan_file[0] break else: print "Cannot plot scan:" print "No scan in scan history was saved into a file" return else: for scan in reversed(scan_history_info): if scan['serialno'] == scan_nb: scan_dir = scan.get('ScanDir') scan_file = scan.get('ScanFile') if scan_dir is None or scan_file is None: print "Cannot plot scan:" print "Scan %d was not saved into a file" % (scan_nb,) return if not isinstance(scan_file, (str, unicode)): scan_file = scan_file[0] break else: print "Cannot plot scan:" print "Scan %d not found in scan history" % (scan_nb,) return remote_file = os.path.join(scan_dir, scan_file) locations = [scan_dir] local_file = None if directory_map is None or not scan_dir in directory_map: if os.path.isdir(scan_dir): if scan_file in os.listdir(scan_dir): local_file = remote_file else: local_directories = directory_map[scan_dir] if isinstance(scan_file, (str, unicode)): local_directories = [local_directories] locations = local_directories if scan_dir not in locations: locations.append(scan_dir) for local_directory in local_directories: if os.path.isdir(local_directory): if scan_file in os.listdir(local_directory): local_file = os.path.join(local_directory, scan_file) break if local_file is None: print "Cannot plot scan:" print "Could not find %s in any of the following locations:" % (scan_file,) print "\n".join(locations) return import taurus.qt.qtgui.extra_nexus taurus_nexus_widget = taurus.qt.qtgui.extra_nexus.TaurusNeXusBrowser() taurus_nexus_widget.setMinimumSize(800, 600) print "Trying to open local scan file %s..." % (local_file,) taurus_nexus_widget.openFile(local_file) taurus_nexus_widget.show() nexus_widget = taurus_nexus_widget.neXusWidget() entry_name = "entry%d" % scan["serialno"] measurement_name = "%s/measurement" % entry_name title_name = "%s/title" % entry_name windowTitle = scan_file + "[" + entry_name + "]" try: #entry_index = taurus_nexus_widget.findNodeIndex(local_file, entry_name) measurement_index = taurus_nexus_widget.findNodeIndex(local_file, measurement_name) #nexus_widget.setRootIndex(entry_index) nexus_widget.setCurrentIndex(measurement_index) nexus_widget.expand(measurement_index) title_index = taurus_nexus_widget.findNodeIndex(local_file, title_name) file_model = nexus_widget.model() title = file_model.getNodeFromIndex(title_index)[0] windowTitle += " - " + title except Exception, e: print "Cannot plot scan:" print str(e) taurus_nexus_widget.setWindowTitle(windowTitle) def plot(self): try: import sps except: print 'sps module not available. No plotting' return try: import pylab except: print "pylab not available (try running 'spock -pylab'). No plotting" return door = genutils.get_door() try: env = dict(door.getEnvironmentObj().read().value) except Exception,e: print 'Unable to read environment. No plotting' print str(e) return program = door.getNormalName().replace('/','').replace('_','') try: array = env['ActiveMntGrp'].replace('/','').replace('_','').upper() + "0D" array_ENV = '%s_ENV' % array except: print 'ActiveMntGrp not defined. No plotting' return if not program in sps.getspeclist(): print '%s not found. No plotting' % program return if not array in sps.getarraylist(program): print '%s not found in %s. No plotting' % (array, program) return if not array_ENV in sps.getarraylist(program): print '%s not found in %s. No plotting' % (array_ENV, program) return try: mem = sps.attach(program, array) mem_ENV = sps.attach(program, array_ENV) except Exception, e: print 'sps.attach error: %s. No plotting' % str(e) return # reconstruct the environment i, env = 0, {} while mem_ENV[i][0] != '': line = mem_ENV[i].tostring() eq, end = line.index('='), line.index('\x00') k,v = line[:eq], line[eq+1:end] env[k] = v i += 1 labels = env['axistitles'].split(' ') col_nb = len(labels) if col_nb < 4: print 'No data columns available in sps' return rows = int(env['nopts']) m = mem.transpose() x = m[1][:rows] colors = 'bgrcmyk' col_nb = min(col_nb, len(colors)+3) # skip point_nb, motor and timer columns for i in xrange(3,col_nb): y = m[i][:rows] line, = pylab.plot(x, y, label = labels[i]) line.linestyle = '-' line.linewidth = 1 line.color = colors[i-3] pylab.legend() class SpockBaseDoor(BaseDoor): """A CLI version of the Door device""" console_editors = 'vi', 'vim', 'nano', 'joe', 'pico', 'emacs' Critical = 'Critical' Error = 'Error' Info = 'Info' Warning = 'Warning' Output = 'Output' Debug = 'Debug' Result = 'Result' RecordData = 'RecordData' MathFrontend = "matplotlib" def __init__(self, name, **kw): self._consoleReady = kw.get("consoleReady", False) if not kw.has_key('silent'): kw['silent'] = False self._lines = [] self._spock_state = None self._plotter = GUIViewer(self) self.call__init__(BaseDoor, name, **kw) def create_input_handler(self): return SpockInputHandler(self) def get_color_mode(self): return genutils.get_color_mode() def _get_macroserver_for_door(self): ret = genutils.get_macro_server() return ret def _preprocessParameters(self, parameters): if is_pure_str(parameters): inside_str = False pars = [] par = '' for c in parameters: if c == '"': if inside_str: inside_str = False pars.append(par) par = '' else: inside_str = True elif c == ' ': if inside_str: par += c else: pars.append(par) par = '' else: par += c if par: pars.append(par) return pars elif is_non_str_seq(parameters): return parameters def preRunMacro(self, obj, parameters): return BaseDoor.preRunMacro(self, obj, self._preprocessParameters(parameters)) def runMacro(self, obj, parameters=[], synch=False): return BaseDoor.runMacro(self, obj, parameters=parameters, synch=synch) def _runMacro(self, xml, **kwargs): #kwargs like 'synch' are ignored in this re-implementation if self._spock_state != TaurusSWDevState.Running: print "Unable to run macro: No connection to door '%s'" % self.getSimpleName() raise Exception("Unable to run macro: No connection") if xml is None: xml = self.getRunningXML() kwargs['synch'] = True try: return BaseDoor._runMacro(self, xml, **kwargs) except KeyboardInterrupt: self.write('\nCtrl-C received: Stopping... ') self.block_lines = 0 self.command_inout("StopMacro") self.writeln("Done!") except PyTango.DevFailed, e: if is_non_str_seq(e.args) and \ not isinstance(e.args, (str, unicode)): reason, desc = e.args[0].reason, e.args[0].desc macro_obj = self.getRunningMacro() if reason == 'MissingParam': print "Missing parameter:",desc print macro_obj.getInfo().doc elif reason == 'WrongParam': print "Wrong parameter:",desc print macro_obj.getInfo().doc elif reason == 'UnkownParamObj': print "Unknown parameter:",desc elif reason == 'MissingEnv': print "Missing environment:",desc elif reason in ('API_CantConnectToDevice', 'API_DeviceNotExported'): self._updateState(self._old_sw_door_state, TaurusSWDevState.Shutdown, silent=True) print "Unable to run macro: No connection to door '%s'" % self.getSimpleName() else: print "Unable to run macro:", reason, desc def _getMacroResult(self, macro): ret = None if macro.info.hasResult(): ret = macro.getResult() if ret is None: return None if macro.info.getResult().type == 'File': commit_cmd = macro.info.hints['commit_cmd'] if commit_cmd == None: return ret local_f_name = ret[0] remote_f_name = ret[1] line_nb = ret[3] commit = CommitFile(commit_cmd, local_f_name, remote_f_name) self.pending_commits.update( { remote_f_name : commit } ) ip = genutils.get_ipapi() editor = genutils.get_editor() cmd = 'edit -x -n %s %s' % (line_nb, local_f_name) if not editor in self.console_editors: cmd = 'bg _ip.magic("' + cmd + '")' ip.magic(cmd) # The return value of the macro was saved in a file and opened # with edit so we don't return anything to avoid big outputs # to the console ret = None return ret def plot(self): self._plotter.run() def show_scan(self, scan_nb=None, online=False): if online: self._plotter.show_scan() return env = self.getEnvironment() scan_history_info = env.get("ScanHistory") directory_map = env.get("DirectoryMap") self._plotter.show_scan(scan_nb=scan_nb, scan_history_info=scan_history_info, directory_map=directory_map) def stateChanged(self, s, t, v): old_sw_state = self._old_sw_door_state BaseDoor.stateChanged(self, s, t, v) new_sw_state = self._old_sw_door_state self._updateState(old_sw_state, new_sw_state) def _updateState(self, old_sw_state, new_sw_state, silent=False): user_ns = genutils.get_ipapi().user_ns if new_sw_state == TaurusSWDevState.Running: user_ns['DOOR_STATE'] = "" else: user_ns['DOOR_STATE'] = " (OFFLINE)" if not self.isConsoleReady(): self._spock_state = new_sw_state return ss = self._spock_state if ss is not None and ss != new_sw_state and not silent: if ss == TaurusSWDevState.Running: self.write_asynch("\nConnection to door '%s' was lost.\n" % self.getSimpleName()) elif new_sw_state == TaurusSWDevState.Running: self.write_asynch("\nConnection to the door (%s) has " \ "been restablished\n" % self.getSimpleName()) self._spock_state = new_sw_state def write_asynch(self, msg): self._lines.append(msg) def pre_prompt_hook(self, ip): self._flush_lines() def _flush_lines(self): for l in self._lines: self.write(l) self._lines = [] def setConsoleReady(self, state): self._consoleReady = state def isConsoleReady(self): return self._consoleReady def write(self, msg, stream=None): if not self.isConsoleReady(): return return BaseDoor.write(self, msg, stream=stream) def processRecordData(self, data): if data is None: return data = data[1] if data['type'] == 'function': func_name = data['func_name'] if func_name.startswith("pyplot."): func_name = self.MathFrontend + "." + func_name args = data['args'] kwargs = data['kwargs'] members = func_name.split(".") mod_list, fname = members[:-1], members[-1] mod_name = ".".join(mod_list) if mod_name: mod = __import__(mod_name, fromlist=mod_list) func = getattr(mod, fname) else: func = __builtins__[fname] try: func(*args, **kwargs) except Exception as e: self.logReceived(self.Warning, ['Unable to execute %s: ' % func_name, str(e)]) _RECORD_DATA_THRESOLD = 4*1024*1024 # 4Mb def _processRecordData(self, data): if data is None: return value = data.value size = len(value[1]) if size > self._RECORD_DATA_THRESOLD: sizekb = size / 1024 self.logReceived(self.Info, ['Received long data record (%d Kb)' % sizekb, 'It may take some time to process. Please wait...']) return BaseDoor._processRecordData(self, data) from taurus.qt import Qt class QSpockDoor(SpockBaseDoor): def __init__(self, name, **kw): self.call__init__(SpockBaseDoor, name, **kw) Qt.QObject.connect(self, Qt.SIGNAL('recordDataUpdated'), self.processRecordData) def recordDataReceived(self, s, t, v): if genutils.get_pylab_mode() == "inline": if t not in CHANGE_EVTS: return res = BaseDoor.recordDataReceived(self, s, t, v) self.processRecordData(res) else: res = SpockBaseDoor.recordDataReceived(self, s, t, v) return res def create_input_handler(self): return InputHandler() class SpockDoor(SpockBaseDoor): def _processRecordData(self, data): data = SpockBaseDoor._processRecordData(self, data) return self.processRecordData(data) class SpockMacroServer(BaseMacroServer): """A CLI version of the MacroServer device""" def __init__(self, name, **kw): self._local_magic = {} self._local_var = set() self.call__init__(BaseMacroServer, name, **kw) def on_elements_changed(self, evt_src, evt_type, evt_value): return BaseMacroServer.on_elements_changed(self, evt_src, evt_type, evt_value) _SKIP_ELEMENTS = 'controller', 'motorgroup', 'instrument', \ 'controllerclass', 'controllerlib', 'macrolib' def _addElement(self, element_data): element = BaseMacroServer._addElement(self, element_data) elem_type = element.type if "MacroCode" in element.interfaces: self._addMacro(element) elif elem_type not in self.NO_CLASS_TYPES: # TODO: when it becomes possible to do: # some taurus.Device. = # replace device_proxy with element device_proxy = element.getObj().getHWObj() genutils.expose_variable(element.name, device_proxy) return element def _removeElement(self, element_data): element = BaseMacroServer._removeElement(self, element_data) elem_type = element.type if "MacroCode" in element.interfaces: self._removeMacro(element) elif elem_type not in self.NO_CLASS_TYPES: genutils.unexpose_variable(element.name) return element def _addMacro(self, macro_info): macro_name = str(macro_info.name) def macro_fn(shell, parameter_s='', name=macro_name): parameters = genutils.arg_split(parameter_s, posix=True) door = genutils.get_door() door.runMacro(macro_name, parameters, synch=True) macro = door.getLastRunningMacro() if macro is not None: # maybe none if macro was aborted return macro.getResult() macro_fn.func_name = macro_name macro_fn.__doc__ = macro_info.doc # register magic command genutils.expose_magic(macro_name, macro_fn) self._local_magic[macro_name] = macro_fn return macro_info def _removeMacro(self, macro_info): macro_name = macro_info.name genutils.unexpose_magic(macro_name) del self._local_magic[macro_name] sardana-1.2.0/src/sardana/tango/0000755000234100017500000000000012174204361020040 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/tango/core/0000755000234100017500000000000012174204361020770 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/tango/core/SardanaDevice.py0000644000234100017500000004313212174204311024031 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Generic Sardana Tango device module""" from __future__ import with_statement __all__ = ["SardanaDevice", "SardanaDeviceClass"] __docformat__ = 'restructuredtext' import time import threading import PyTango.constants from PyTango import Device_4Impl, DeviceClass, Util, DevState, \ AttrQuality, TimeVal, ArgType, ApiUtil, DevFailed, WAttribute from taurus.core.util import ThreadPool from taurus.core.util.log import Logger from util import to_tango_state, NO_DB_MAP __thread_pool_lock = threading.Lock() __thread_pool = None def get_thread_pool(): """Returns the global pool of threads for Sardana :return: the global pool of threads object :rtype: taurus.core.util.ThreadPool""" global __thread_pool if __thread_pool: return __thread_pool global __thread_pool_lock with __thread_pool_lock: if __thread_pool is None: __thread_pool = ThreadPool(name="EventTH", Psize=1, Qsize=1000) return __thread_pool class SardanaDevice(Device_4Impl, Logger): """SardanaDevice represents the base class for all Sardana :class:`PyTango.DeviceImpl` classes""" def __init__(self, dclass, name): """Constructor""" self.in_constructor = True try: Device_4Impl.__init__(self, dclass, name) self.init(name) Logger.__init__(self, name) self._state = DevState.INIT self._status = 'Waiting to be initialized...' # access to some tango API (like MultiAttribute and Attribute) is # still not thread safe so we have this lock to protect # Wa can't always use methods which use internally the # C++ AutoTangoMonitor because it blocks the entire tango device. self.tango_lock = threading.RLock() self._event_thread_pool = get_thread_pool() self.init_device() finally: self.in_constructor = False def init(self, name): """initialize the device once in the object lifetime. Override when necessary but **always** call the method from your super class :param str name: device name""" db = self.get_database() if db is None: self._alias = self._get_nodb_device_info()[0] else: try: self._alias = db.get_alias(name) if self._alias.lower() == 'nada': self._alias = None except: self._alias = None def get_alias(self): """Returns this device alias name :return: this device alias :rtype: str""" return self._alias alias = property(get_alias, doc="the device alias name") def get_full_name(self): """Returns the device full name in format dbname:dbport/// :return: this device full name :rtype: str""" db = self.get_database() if db.get_from_env_var(): db_name = ApiUtil.get_env_var("TANGO_HOST") else: if db.is_dbase_used(): db_name = db.get_db_host() + ":" + db.get_db_port() else: db_name = db.get_file_name() return db_name + "/" + self.get_name() def init_device(self): """Initialize the device. Called during startup after :meth:`init` and every time the tango ``Init`` command is executed. Override when necessary but **always** call the method from your super class""" self.set_state(self._state) db = self.get_database() if db is None: self.init_device_nodb() else: self.get_device_properties(self.get_device_class()) detect_evts = "state", "status" non_detect_evts = () self.set_change_events(detect_evts, non_detect_evts) def _get_nodb_device_info(self): """Internal method. Returns the device info when tango database is not being used (example: in demos)""" name = self.get_name() tango_class = self.get_device_class().get_name() devices = NO_DB_MAP.get(tango_class, ()) for dev_info in devices: if dev_info[1] == name: return dev_info def init_device_nodb(self): """Internal method. Initialize the device when tango database is not being used (example: in demos)""" _, _, props = self._get_nodb_device_info() for prop_name, prop_value in props.items(): setattr(self, prop_name, prop_value) def delete_device(self): """Clean the device. Called during shutdown and every time the tango ``Init`` command is executed. Override when necessary but **always** call the method from your super class""" pass def set_change_events(self, evts_checked, evts_not_checked): """Helper method to set change events on attributes :param evts_checked: list of attribute names to activate change events programatically with tango filter active :type evts_checked: seq<:obj:`str`\> :param evts_not_checked: list of attribute names to activate change events programatically with tango filter inactive. Use this with care! Attributes configured with no change event filter may potentially generated a lot of events! :type evts_not_checked: seq<:obj:`str`\>""" for evt in evts_checked: self.set_change_event(evt, True, True) for evt in evts_not_checked: self.set_change_event(evt, True, False) def initialize_dynamic_attributes(self): """Initialize dynamic attributes. Default implementation does nothing. Override when necessary.""" pass def get_event_thread_pool(self): """Return the :class:`~taurus.core.util.ThreadPool` used by sardana to send tango events. :return: the sardana :class:`~taurus.core.util.ThreadPool` :rtype: :class:`~taurus.core.util.ThreadPool`""" return self._event_thread_pool def get_attribute_by_name(self, attr_name): """Gets the attribute for the given name. :param attr_name: attribute name :type attr_name: str :return: the attribute object :rtype: :class:`~PyTango.Attribute`""" return self.get_device_attr().get_attr_by_name(attr_name) def get_wattribute_by_name(self, attr_name): """Gets the writable attribute for the given name. :param attr_name: attribute name :type attr_name: str :return: the attribute object :rtype: :class:`~PyTango.WAttribute`""" return self.get_device_attr().get_w_attr_by_name(attr_name) def get_database(self): """Helper method to return a reference to the current tango database :return: the Tango database :rtype: :class:`~PyTango.Database`""" return Util.instance().get_database() def set_write_attribute(self, attr, w_value): try: attr.set_write_value(w_value) except DevFailed as df: df0 = df[0] reason = df0.reason # if outside limit prefix the description with the device name if reason == PyTango.constants.API_WAttrOutsideLimit: desc = self.alias + ": " + df0.desc _df = DevFailed(*df[1:]) PyTango.Except.re_throw_exception(_df, df0.reason, desc, df0.origin) raise df def set_attribute(self, attr, value=None, w_value=None, timestamp=None, quality=None, error=None, priority=1, synch=True): """Sets the given attribute value. If timestamp is not given, *now* is used as timestamp. If quality is not given VALID is assigned. If error is given an error event is sent (with no value and quality INVALID). If priority is > 1, the event filter is temporarily disabled so the event is sent for sure. If synch is set to True, wait for fire event to finish :param attr: the tango attribute :type attr: :class:`PyTango.Attribute` :param value: the value to be set (not mandatory if setting an error) [default: None] :type value: object :param w_value: the write value to be set (not mandatory) [default: None, meaning maintain current write value] :type value: object :param timestamp: the timestamp associated with the operation [default: None, meaning use *now* as timestamp] :type timestamp: float or :class:`PyTango.TimeVal` :param quality: attribute quality [default: None, meaning VALID] :type quality: :class:`PyTango.AttrQuality` :param error: a tango DevFailed error or None if not an error [default: None] :type error: :exc:`PyTango.DevFailed` :param priority: event priority [default: 1, meaning *normal* priority]. If priority is > 1, the event filter is temporarily disabled so the event is sent for sure. The event filter is restored to the previous value :type priority: int :param synch: If synch is set to True, wait for fire event to finish. If False, a job is sent to the sardana thread pool and the method returns immediately [default: True] """ set_attr = self.set_attribute_push if synch: set_attr(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, error=error, priority=priority, synch=synch) else: th_pool = self.get_event_thread_pool() th_pool.add(set_attr, None, attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, error=error, priority=priority, synch=synch) def set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, quality=None, error=None, priority=1, synch=True): """Synchronous internal implementation of :meth:`set_attribute` (synch is passed to this method because it might need to know if it is being executed in a synchronous or asynchronous context).""" if priority > 0 and not synch: with self.tango_lock: return self._set_attribute_push(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, error=error, priority=priority) else: return self._set_attribute_push(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, error=error, priority=priority) def _set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, quality=None, error=None, priority=1): """Internal method.""" fire_event = priority > 0 recover = False if priority > 1 and attr.is_check_change_criteria(): attr.set_change_event(True, False) recover = True attr_name = attr.get_name().lower() if value is None and error is None: raise Exception("Cannot set value of attribute '%s' with None" % (attr_name,)) try: if error is not None and fire_event: self.push_change_event(attr_name, error) return # some versions of Tango have a memory leak if you do # push_change_event(attr_name, value [, ...]) on state or status. # This solves the problem. if attr_name == "state": self.set_state(value) if fire_event: self.push_change_event(attr_name) return elif attr_name == "status": self.set_status(value) if fire_event: self.push_change_event(attr_name) return if timestamp is None: timestamp = time.time() elif isinstance(timestamp, TimeVal): timestamp = TimeVal.totime(timestamp) if quality is None: quality = AttrQuality.ATTR_VALID data_type = attr.get_data_type() if w_value is not None and isinstance(attr, WAttribute): attr.set_write_value(w_value) if fire_event: if data_type == ArgType.DevEncoded: fmt, data = value args = attr_name, fmt, data, timestamp, quality else: args = attr_name, value, timestamp, quality self.push_change_event(*args) else: if data_type == ArgType.DevEncoded: fmt, data = value attr.set_value_date_quality(fmt, data, timestamp, quality) else: attr.set_value_date_quality(value, timestamp, quality) finally: if recover: attr.set_change_event(True, True) def calculate_tango_state(self, ctrl_state, update=False): """Calculate tango state based on the controller state. :param ctrl_state: the state returned by the controller :type ctrl_state: :obj:`~sardana.sardanadefs.State` :param bool update: if True, set the state of this device with the calculated tango state [default: False: :return: the corresponding tango state :rtype: :class:`PyTango.DevState`""" self._state = state = to_tango_state(ctrl_state) if update: self.set_state(state) return state def calculate_tango_status(self, ctrl_status, update=False): """Calculate tango status based on the controller status. :param str ctrl_status: the status returned by the controller :param bool update: if True, set the state of this device with the calculated tango state [default: False: :return: the corresponding tango state :rtype: str""" self._status = status = ctrl_status if update: self.set_status(status) return status class SardanaDeviceClass(DeviceClass): """SardanaDeviceClass represents the base class for all Sardana :class:`PyTango.DeviceClass` classes""" #: #: Sardana device class properties definition #: #: .. seealso:: :ref:`server` #: class_property_list = { } #: #: Sardana device properties definition #: #: .. seealso:: :ref:`server` #: device_property_list = { } #: #: Sardana device command definition #: #: .. seealso:: :ref:`server` #: cmd_list = { } #: #: Sardana device attribute definition #: #: .. seealso:: :ref:`server` #: attr_list = { } def __init__(self, name): DeviceClass.__init__(self, name) self.set_type(name) def _get_class_properties(self): """Internal method""" return dict(ProjectTitle="Sardana", Description="Generic description", doc_url="http://sardana-controls.org/", __icon=self.get_name().lower() + ".png", InheritedFrom=["Device_4Impl"]) def write_class_property(self): """Write class properties ``ProjectTitle``, ``Description``, ``doc_url``, ``InheritedFrom`` and ``__icon``""" db = self.get_database() if db is None: return db.put_class_property(self.get_name(), self._get_class_properties()) def dyn_attr(self, dev_list): """Invoked to create dynamic attributes for the given devices. Default implementation calls :meth:`SardanaDevice.initialize_dynamic_attributes` for each device :param dev_list: list of devices :type dev_list: :class:`PyTango.DeviceImpl`""" for dev in dev_list: try: dev.initialize_dynamic_attributes() except: dev.warning("Failed to initialize dynamic attributes") dev.debug("Details:", exc_info=1) def device_name_factory(self, dev_name_list): """Builds list of device names to use when no Database is being used :param dev_name_list: list to be filled with device names :type dev_name_list: seq""" tango_class = self.get_name() devices = NO_DB_MAP.get(tango_class, ()) for dev_info in devices: dev_name_list.append(dev_info[1]) sardana-1.2.0/src/sardana/tango/core/__init__.py0000644000234100017500000000603712174204311023102 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __docformat__ = 'restructuredtext' import PyTango.constants def __init_pytango_devfailed(mod): consts = ( "API_AttrConfig", "API_AttrEventProp", "API_AttrIncorrectDataNumber", "API_AttrNoAlarm", "API_AttrNotAllowed", "API_AttrNotFound", "API_AttrNotWritable", "API_AttrOptProp", "API_AttrPropValueNotSet", "API_AttrValueNotSet", "API_AttrWrongDefined", "API_AttrWrongMemValue", "API_BadConfigurationProperty", "API_BlackBoxArgument", "API_BlackBoxEmpty", "API_CannotCheckAccessControl", "API_CannotOpenFile", "API_CantActivatePOAManager", "API_CantCreateClassPoa", "API_CantCreateLockingThread", "API_CantFindLockingThread", "API_CantGetClientIdent", "API_CantGetDevObjectId", "API_CantInstallSignal", "API_CantRetrieveClass", "API_CantRetrieveClassList", "API_CantStoreDeviceClass", "API_ClassNotFound", "API_CmdArgumentTypeNotSupported", "API_CommandNotAllowed", "API_CommandNotFound", "API_CorbaSysException", "API_CorruptedDatabase", "API_DatabaseAccess", "API_DeviceLocked", "API_DeviceNotFound", "API_DeviceNotLocked", "API_DeviceUnlockable", "API_DeviceUnlocked", "API_EventSupplierNotConstructed", "API_IncoherentDbData", "API_IncoherentDevData", "API_IncoherentValues", "API_IncompatibleAttrDataType", "API_IncompatibleCmdArgumentType", "API_InitMethodNotFound", "API_InitNotPublic", "API_InitThrowsException", "API_JavaRuntimeSecurityException", "API_MemoryAllocation", "API_MethodArgument", "API_MethodNotFound", "API_MissedEvents", "API_NotSupportedFeature", "API_NtDebugWindowError", "API_OverloadingNotSupported", "API_PolledDeviceNotInPoolConf", "API_PolledDeviceNotInPoolMap", "API_PollingThreadNotFound", "API_ReadOnlyMode", "API_SignalOutOfRange", "API_SystemCallFailed", "API_WAttrOutsideLimit", "API_WizardConfError", "API_WrongEventData", "API_WrongHistoryDataBuffer", "API_WrongLockingStatus", "API_ZmqInitFailed") for const in consts: setattr(mod, const, const) def __prepare_pytango(): if not hasattr(PyTango.constants, "API_DeviceNotFound"): __init_pytango_devfailed(PyTango.constants) __prepare_pytango() sardana-1.2.0/src/sardana/tango/core/attributehandler.py0000644000234100017500000000522212174204311024677 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the main macro server module""" __all__ = ["AttributeLogHandler", "AttributeBufferedLogHandler"] __docformat__ = 'restructuredtext' import logging import weakref import operator from taurus.core.util import LIFO class AttributeLogHandler(logging.Handler): def __init__(self, dev, attr_name, level=logging.NOTSET, max_buff_size=0): logging.Handler.__init__(self, level) self._attr_name = attr_name self._level = level self._max_buff_size = max_buff_size self._dev = weakref.ref(dev) self._attr = dev.get_device_attr().get_attr_by_name(attr_name) self._buff = LIFO(max_buff_size) def emit(self, record): output = self.getRecordMessage(record) self.appendBuffer(output) self.sendText(output) def getRecordMessage(self, record): return self.format(record).split('\n') def sendText(self, output): dev = self._dev() attr = self._attr if attr is None or dev is None: return dev.set_attribute(attr, output) def read(self, attr): """Read from the buffer and assign to the attribute value""" attr.set_value(self._buff.getCopy()) def clearBuffer(self): self._buff.clear() def appendBuffer(self, d): if operator.isSequenceType(d): if isinstance(d, (str, unicode)): self._buff.append(d) else: self._buff.extend(d) else: self._buff.append(str(d)) def sync(self): pass def finish(self): pass AttributeBufferedLogHandler = AttributeLogHandlersardana-1.2.0/src/sardana/tango/core/util.py0000644000234100017500000011010012174204311022303 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __docformat__ = 'restructuredtext' __all__ = ["get_tango_version_str", "get_tango_version_number", "get_pytango_version_str", "get_pytango_version_number", "exception_str", "GenericScalarAttr", "GenericSpectrumAttr", "GenericImageAttr", "memorize_write_attribute", "tango_protect", "to_tango_state", "to_tango_type_format", "to_tango_type", "to_tango_access", "to_tango_attr_info", "from_tango_access", "from_tango_type_format", "from_tango_state_to_state", "from_deviceattribute_value", "from_deviceattribute", "throw_sardana_exception", "prepare_tango_logging", "prepare_rconsole", "run_tango_server", "run"] import sys import os.path import string import traceback import time import logging import PyTango from PyTango import Util, Database, WAttribute, DbDevInfo, DevFailed, \ DevVoid, DevLong, DevBoolean, DevString, DevDouble, \ DevState, SCALAR, SPECTRUM, IMAGE, FMT_UNKNOWN, \ READ_WRITE, READ, Attr, SpectrumAttr, ImageAttr, \ DeviceClass, Except import taurus from taurus.core.util.log import Logger import sardana from sardana import State, SardanaServer, DataType, DataFormat, InvalidId, \ DataAccess, to_dtype_dformat, to_daccess, Release, ServerRunMode from sardana.sardanaexception import SardanaException from sardana.sardanavalue import SardanaValue from sardana.util.wrap import wraps from sardana.pool.poolmetacontroller import DataInfo NO_DB_MAP = { "Pool" : ( ("pool_demo", "sardana/pool/demo", dict(Version="1.0.0"), ), ), "Controller" : ( ("motctrl", "controller/dummymotorcontroller/motctrl", dict(Id=1, Type="Motor", Klass="DummyMotorController", Library="DummyMotorController.py", Role_ids=(), ), ), ("iorctrl", "controller/dummyiorcontroller/iorctrl", dict(Id=2, Type="IORegister", Klass="DummyIORController", Library="DummyIORController.py", Role_ids=(), ), ), ("ctctrl", "controller/dummycountertimercontroller/ctctrl", dict(Id=3, Type="CTExpChannel", Klass="DummyCounterTimerController", Library="DummyCounterTimerController.py", Role_ids=(), ), ), ("zerodctrl", "controller/dummyzerodcontroller/zerodctrl", dict(Id=4, Type="ZeroDExpChannel", Klass="DummyZeroDController", Library="DummyZeroDController.py", Role_ids=(), ), ), ("slitctrl", "controller/slit/slitctrl", dict(Id=5, Type="PseudoMotor", Klass="Slit", Library="Slit.py", Role_ids=(), ), ), ("ioi0ctrl", "controller/ioveri0/ioi0ctrl", dict(Id=6, Type="PseudoCounter", Klass="IoverI0", Library="IoverI0.py", Role_ids=(), ), ), ), "Motor" : ( ("slt", "motor/motctrl/1", dict(Id=101, Axis=1, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("slb", "motor/motctrl/2", dict(Id=102, Axis=2, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("mot1", "motor/motctrl/3", dict(Id=103, Axis=3, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("mot2", "motor/motctrl/4", dict(Id=104, Axis=4, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("mot3", "motor/motctrl/5", dict(Id=105, Axis=5, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("mot4", "motor/motctrl/6", dict(Id=106, Axis=6, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("th", "motor/motctrl/7", dict(Id=107, Axis=7, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("tth", "motor/motctrl/8", dict(Id=108, Axis=8, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("chi", "motor/motctrl/9", dict(Id=109, Axis=9, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ("phi", "motor/motctrl/10", dict(Id=110, Axis=10, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0), ), ), "IORegister" : ( ("ior1", "ioregister/iorctrl/1", dict(Id=201, Axis=1, Ctrl_id=2, Instrument_id=InvalidId), ), ("ior2", "ioregister/iorctrl/2", dict(Id=202, Axis=2, Ctrl_id=2, Instrument_id=InvalidId), ), ("ior3", "ioregister/iorctrl/3", dict(Id=203, Axis=3, Ctrl_id=2, Instrument_id=InvalidId), ), ("ior4", "ioregister/iorctrl/4", dict(Id=204, Axis=4, Ctrl_id=2, Instrument_id=InvalidId), ), ), "CTExpChannel" : ( ("ct1", "expchan/ctctrl/1", dict(Id=301, Axis=1, Ctrl_id=3, Instrument_id=InvalidId), ), ("ct2", "expchan/ctctrl/2", dict(Id=302, Axis=2, Ctrl_id=3, Instrument_id=InvalidId), ), ("ct3", "expchan/ctctrl/3", dict(Id=303, Axis=3, Ctrl_id=3, Instrument_id=InvalidId), ), ("ct4", "expchan/ctctrl/4", dict(Id=304, Axis=4, Ctrl_id=3, Instrument_id=InvalidId), ), ), "ZeroDExpChannel" : ( ("zerod1", "expchan/zerodctrl/1", dict(Id=401, Axis=1, Ctrl_id=4, Instrument_id=InvalidId), ), ("zerod2", "expchan/zerodctrl/2", dict(Id=402, Axis=2, Ctrl_id=4, Instrument_id=InvalidId), ), ("zerod3", "expchan/zerodctrl/3", dict(Id=403, Axis=3, Ctrl_id=4, Instrument_id=InvalidId), ), ("zerod4", "expchan/zerodctrl/4", dict(Id=404, Axis=4, Ctrl_id=4, Instrument_id=InvalidId), ), ), "PseudoMotor" : ( ("gap", "pm/slitctrl/1", dict(Id=501, Axis=1, Ctrl_id=5, Instrument_id=InvalidId, Elements=("101", "102",) ), ), ("offset", "pm/slitctrl/2", dict(Id=502, Axis=2, Ctrl_id=5, Instrument_id=InvalidId, Elements=("101", "102",) ), ), ), "PseudoCounter" : ( ("inorm", "pc/ioi0ctrl/1", dict(Id=601, Axis=1, Ctrl_id=6, Instrument_id=InvalidId, Elements=("301", "302",) ), ), ), "MotorGroup" : ( ("motgrp1", "mg/pool_demo/motgrp1", dict(Id=701, Elements=("103", "104",) ), ), ), "MeasurementGroup" : ( ("mntgrp1", "mntgrp/pool_demo/mntgrp1", dict(Id=701, Elements=("301", "302", "303", "401",) ), ), ), "MacroServer" : ( ("MS_demo", "sardana/ms/demo", dict(PoolNames=["sardana/pool/demo"] ), ), ), "Door" : ( ("Door_demo", "sardana/door/demo", dict(Id=1001, MacroServerName="sardana/ms/demo", MaxMsgBufferSize=512), ), ), } #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def get_pytango_version_str(): try: import PyTango except: return None try: return PyTango.Release.version except: return '0.0.0' def get_pytango_version_number(): tgver_str = get_pytango_version_str() if tgver_str is None: return None import sardana.sardanautils return sardana.sardanautils.translate_version_str2int(tgver_str) def get_tango_version_str(): try: import PyTango.constants except: return None try: return PyTango.constants.TgLibVers except: return '0.0.0' def get_tango_version_number(): tgver_str = get_tango_version_str() if tgver_str is None: return None import sardana.sardanautils return sardana.sardanautils.translate_version_str2int(tgver_str) class GenericScalarAttr(Attr): pass class GenericSpectrumAttr(SpectrumAttr): def __init__(self, name, tg_type, tg_access, dim_x=2048): SpectrumAttr.__init__(self, name, tg_type, tg_access, dim_x) class GenericImageAttr(ImageAttr): def __init__(self, name, tg_type, tg_access, dim_x=2048, dim_y=2048): ImageAttr.__init__(self, name, tg_type, tg_access, dim_x, dim_y) def clean_device_attribute_memorized(db, dev_name, attr_name): props = "__value", "__value_ts" db.delete_device_attribute_property(dev_name, {attr_name : props }) def clean_device_memorized(db, dev_name): for attr_name in PyTango.DeviceProxy(dev_name).get_attribute_list(): clean_device_attribute_memorized(db, dev_name, attr_name) def clean_server_memorized(db, server_name, server_instance): server = server_name + "/" + server_instance dev_names = db.get_device_class_list(server)[::2] for dev_name in dev_names: clean_device_memorized(db, dev_name) def __set_last_write_value(attribute, lrv): attribute._last_write_value = lrv return lrv def __get_last_write_value(attribute): if hasattr(attribute, '_last_write_value'): lrv = attribute._last_write_value else: attribute._last_write_value = lrv = None return lrv def memorize_write_attribute(write_attr_func): """The main purpose is to use this as a decorator for write_ device methods. Properly memorizes the attribute write value: - only memorize if write doesn't throw exception - also memorize the timestamp :param write_attr_func: the write method :type write_attr_func: callable :return: a write method safely wrapping the given write method :rtype: callable""" @wraps(write_attr_func) def write_attr_wrapper(self, attribute): ts = repr(time.time()) attr_name = attribute.get_name() dev_name = self.get_name() if not isinstance(attribute, WAttribute): return write_attr_func(self, attribute) lwv = __get_last_write_value(attribute) wv = attribute.get_write_value(), ts store, raises_exc = wv, True store_value = False try: ret = write_attr_func(self, attribute) __set_last_write_value(attribute, wv) raises_exc = False finally: # if there is an exception recover from the last write value. # (don't catch and raise exceptions to avoid messing up the stack) if raises_exc: store_value = True if lwv is not None: store = lwv if store is not None: db = self.get_database() attr_values = dict(__value_ts=store[1]) if store_value: attr_values['__value'] = store[0] db.put_device_attribute_property(dev_name, { attr_name : attr_values }) return ret return write_attr_wrapper def tango_protect(wrapped, *args, **kwargs): @wraps(wrapped) def wrapper(self, *args, **kwargs): with self.tango_lock: return wrapped(self, *args, **kwargs) return wrapper def from_deviceattribute_value(da): if da.has_failed: return dtype, dformat, value = da.type, da.data_format, da.value if dtype == PyTango.DevState: if dformat == PyTango.SCALAR: return from_tango_state_to_state(value) elif dformat == PyTango.SPECTRUM: return list(map(from_tango_state_to_state, value)) elif dformat == PyTango.IMAGE: return [ list(map(from_tango_state_to_state, v)) for v in value ] return value def from_deviceattribute(da): if da.has_failed: exc_info = DevFailed(*da.get_err_stack()) value = None else: exc_info = None value = from_deviceattribute_value(da.value) dtype, dformat = from_tango_type_format(da.type, da.data_format) ret = SardanaValue(value=value, exc_info=exc_info, timestamp=da.time.totime(), dtype=dtype, dformat=dformat) return ret def to_tango_state(state): return DevState(state) def from_tango_state_to_state(state): return int(state) #: dictionary dict<:class:`sardana.DataType`, :class:`PyTango.CmdArgType`> TTYPE_MAP = { DataType.Integer : DevLong, DataType.Double : DevDouble, DataType.String : DevString, DataType.Boolean : DevBoolean, } R_TTYPE_MAP = dict((v,k) for k,v in TTYPE_MAP.items()) #: dictionary dict<:class:`sardana.DataFormat`, :class:`PyTango.AttrFormat`> TFORMAT_MAP = { DataFormat.Scalar : SCALAR, DataFormat.OneD : SPECTRUM, DataFormat.TwoD : IMAGE, } R_TFORMAT_MAP = dict((v,k) for k,v in TFORMAT_MAP.items()) #: dictionary dict<:class:`sardana.DataAccess`, :class:`PyTango.AttrWriteType`> TACCESS_MAP = { DataAccess.ReadOnly : READ, DataAccess.ReadWrite : READ_WRITE, } R_TACCESS_MAP = dict((v,k) for k,v in TACCESS_MAP.items()) def exception_str(etype=None, value=None, sep='\n'): if etype is None: etype, value = sys.exc_info()[:2] return sep.join(traceback.format_exception_only(etype, value)) def to_tango_access(access): """Transforms a :obj:`~sardana.DataAccess` into a :obj:`~PyTango.AttrWriteType` :param access: the access to be transformed :type access: :obj:`~sardana.DataAccess` :return: the tango attribute write type :rtype: :obj:`PyTango.AttrWriteType`""" return TACCESS_MAP[access] def from_tango_access(access): """Transforms a :obj:`~PyTango.AttrWriteType` into a :obj:`~sardana.DataAccess` :param access: the tango access to be transformed :type access: :obj:`~PyTango.AttrWriteType` :return: the sardana attribute write type :rtype: :obj:`~sardana.DataAccess`""" return R_TACCESS_MAP[access] def to_tango_type_format(dtype_or_info, dformat=None): """Transforms a :obj:`~sardana.DataType` :obj:`~sardana.DataFormat` into a :obj:`~PyTango.CmdArgType`, :obj:`~PyTango.AttrDataFormat` tuple :param dtype_or_info: the type to be transformed :type dtype_or_info: :obj:`~sardana.DataType` :param dformat: the format to be transformed :type dformat: :obj:`~sardana.DataFormat` :return: a tuple of two elements: the tango attribute write type, tango data format :rtype: tuple< :obj:`PyTango.CmdArgType`, :obj:`PyTango.AttrDataFormat` >""" dtype = dtype_or_info if dformat is None: dtype, dformat = to_dtype_dformat(dtype) return TTYPE_MAP.get(dtype, DevVoid), TFORMAT_MAP.get(dformat, FMT_UNKNOWN) def from_tango_type_format(dtype, dformat=PyTango.SCALAR): """Transforms a :obj:`~PyTango.CmdArgType`, :obj:`~PyTango.AttrDataFormat` into a :obj:`~sardana.DataType` :obj:`~sardana.DataFormat` tuple :param dtype: the type to be transformed :type dtype: :obj:`~PyTango.CmdArgType` :param dformat: the format to be transformed :type dformat: :obj:`~PyTango.AttrDataFormat` :return: a tuple of two elements: data type, data format :rtype: tuple< :obj:`~sardana.DataType`, :obj:`~sardana.DataFormat` >""" return R_TTYPE_MAP[dtype], R_TFORMAT_MAP[dformat] def to_tango_attr_info(attr_name, attr_info): if isinstance(attr_info, DataInfo): data_type, data_format = attr_info.dtype, attr_info.dformat data_access = attr_info.access desc = attr_info.description memorized = attr_info.memorized else: data_type, data_format = to_dtype_dformat(attr_info.get('type')) data_access = to_daccess(attr_info.get('r/w type')) desc = attr_info.get('description') memorized = attr_info.get('memorized') tg_type, tg_format = to_tango_type_format(data_type, data_format) tg_access = to_tango_access(data_access) tg_attr_info = [ [ tg_type, tg_format, tg_access ] ] extra = {} tg_attr_info.append(extra) if desc is not None and len(desc) > 0: extra['description'] = desc extra['memorized'] = memorized return attr_name, tg_attr_info def throw_sardana_exception(exc): """Throws an exception as a tango exception""" if isinstance(exc, SardanaException): if exc.exc_info and not None in exc.exc_info: Except.throw_python_exception(*exc.exc_info) else: tb = "" if exc.traceback is not None: tb = str(exc.traceback) Except.throw_exception(exc.msg, tb, exc.type) elif hasattr(exc, 'exc_info'): Except.throw_python_exception(*exc.exc_info) def ask_yes_no(prompt,default=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is empty. Otherwise the question is repeated until an answer is given. An EOF is treated as the default answer. If there is no default, an exception is raised to prevent infinite loops. Valid answers are: y/yes/n/no (match is not case sensitive).""" answers = {'y':True,'n':False,'yes':True,'no':False} ans = None if default is not None: d_l = default.lower() if d_l in ('y','yes'): prompt += " (Y/n) ?" elif d_l in ('n','no'): prompt += " (N/y) ?" while ans not in answers.keys(): try: ans = raw_input(prompt+' ').lower() if not ans: # response was an empty string ans = default except KeyboardInterrupt: print except EOFError: if default in answers.keys(): ans = default print else: raise return answers[ans] def clean_tango_args(args): ret, ret_for_tango, ret_for_ORB = [], [], [] tango_args = "-?", "-nodb", "-file=" nb_args = len(args) i = 0 while i < nb_args: arg = args[i] try: if arg.startswith("-v") and int(arg[2:]): ret_for_tango.append(arg) i += 1 continue except: pass if arg.startswith('-ORB'): ret_for_ORB.append(arg) ret_for_tango.append(arg) i += 1 if i < nb_args: ret_for_ORB.append(args[i]) ret_for_tango.append(args[i]) i += 1 continue if arg.startswith(tango_args): ret_for_tango.append(arg) i += 1 continue if arg == "-dlist": ret_for_tango.append(arg) i += 1 while i < nb_args and args[i][0] != "-": arg = args[i] ret_for_tango.append(arg) i += 1 continue ret.append(arg) i += 1 return ret, ret_for_tango, ret_for_ORB def prepare_cmdline(parser=None, args=None): """Prepares the command line separating tango options from server specific options. :return: a sequence of options, arguments, tango arguments :rtype: seq, list>""" import optparse if args is None: args = [] proc_args, tango_args, ORB_args = clean_tango_args(args) if parser is None: version = "%s" % (Release.version) parser = optparse.OptionParser(version=version) parser.usage = "usage: %prog instance_name [options]" log_level_choices = "critical", "error", "warning", "info", "debug", "trace", \ "0", "1", "2", "3", "4", "5" help_olog = "log output level. Possible values are (case sensitive): " \ "critical (or 0), error (1), warning (2), info (3) " \ "debug (4), trace (5) [default: %default]" help_flog = "log file level. Possible values are (case sensitive): " \ "critical (or 0), error (1), warning (2), info (3) " \ "debug (4), trace (5) [default: %default]. " \ "Ignored if --without-log-file is True" help_fnlog = "log file name. When given, MUST be absolute file name. " \ "[default: /tmp/tango///log.txt]. " \ "Ignored if --without-log-file is True" help_wflog = "When set to True disables logging into a file [default: %default]" help_rfoo = "rconsole port number. [default: %default meaning rconsole NOT active]" parser.add_option("--log-level", dest="log_level", metavar="LOG_LEVEL", help=help_olog, type="choice", choices=log_level_choices, default="warning") parser.add_option("--log-file-level", dest="log_file_level", metavar="LOG_FILE_LEVEL", help=help_flog, type="choice", choices=log_level_choices, default="debug") parser.add_option("--log-file-name", dest="log_file_name", help=help_fnlog, type="str", default=None) parser.add_option("--without-log-file", dest="without_log_file", help=help_wflog, default=False) parser.add_option("--rconsole-port", dest="rconsole_port", metavar="RCONSOLE_PORT", help=help_rfoo, type="int", default=0) res = list( parser.parse_args(proc_args) ) tango_args = res[1][:2] + tango_args res.append(tango_args) res.append(ORB_args) return res def prepare_environment(args, tango_args, ORB_args): """Since we have to create a Tango Database object before the Tango Util, omniORB doesn't recognize parameters on the command line anymore (tango, omniORB bug?), so we export these parameters as environment variables (this workaround seems to work)""" log_messages = [] ORB_args_len = len(ORB_args) for i in range(ORB_args_len): arg = ORB_args[i] if arg.startswith("-ORB") and i+1 < ORB_args_len: env_name = arg[1:] env_val = ORB_args[i+1] os.environ[env_name] = env_val log_messages.append(("setting %s=%s", env_name, env_val)) return log_messages def prepare_server(args, tango_args): """Register a proper server if the user gave an unknown server""" log_messages = [] _, bin_name = os.path.split(args[0]) if "-?" in tango_args: return log_messages nodb = "-nodb" in tango_args if nodb and not hasattr(DeviceClass, "device_name_factory"): print "In order to start %s with 'nodb' you need PyTango >= 7.2.3" % bin_name sys.exit(1) if len(tango_args) < 2: valid = False while not valid: inst_name = raw_input("Please indicate %s instance name: " % bin_name) #should be a instance name validator. valid_set=string.letters + string.digits + '_' + '-' out=''.join([c for c in inst_name if c not in valid_set]) valid = len(inst_name) > 0 and len(out)==0 if not valid: print "We only accept alphanumeric combinations" args.append(inst_name) tango_args.append(inst_name) else: inst_name = tango_args[1].lower() if "-nodb" in tango_args: return log_messages db = Database() if not exists_server_instance(db, bin_name, inst_name): if ask_yes_no('%s does not exist. Do you wish create a new one' % inst_name, default='y'): if bin_name == 'MacroServer' : # build list of pools to which the MacroServer should connect to pool_names = [] pools = get_dev_from_class(db, "Pool") all_pools = pools.keys() for pool in pools.values(): pool_alias = pool[2] if pool_alias is not None: all_pools.append(pool_alias) all_pools = map(str.lower, all_pools) for i in pools: print pools[i][3] while True: elem = raw_input("Please select pool to connect to (return to finish): ").strip() if not len(elem): break if elem.lower() not in all_pools: print "Unknown pool element" print all_pools else: pool_names.append(elem) log_messages += register_sardana(db, bin_name, inst_name, pool_names) else: log_messages += register_sardana(db, bin_name, inst_name) return log_messages def exists_server_instance(db, server_name, server_instance): known_inst = map(str.lower, db.get_instance_name_list(server_name)) return server_instance.lower() in known_inst def register_sardana(db, bin_name, inst_name, pool_names=None): devices = [] log_messages = [] if bin_name == 'MacroServer': props = {'PoolNames' : pool_names} ms_alias = get_free_alias(db, "MS_" + inst_name) devices.append(('MacroServer', None, ms_alias, props)) door_alias = get_free_alias(db, "Door_" + inst_name) devices.append(("Door", None, door_alias, {})) elif bin_name == 'Pool': pool_alias = get_free_alias(db, 'Pool_' + inst_name) devices.append(('Pool', None, pool_alias, {})) elif bin_name == 'Sardana': pool_dev_name = get_free_device(db, 'pool/' + inst_name) pool_alias = get_free_alias(db, 'Pool_' + inst_name) devices.append(('Pool', pool_dev_name, pool_alias, {})) ms_alias = get_free_alias(db, "MS_" + inst_name) devices.append(('MacroServer', None, ms_alias, {'PoolNames' : [pool_dev_name]})) door_alias = get_free_alias(db, "Door_" + inst_name) devices.append(("Door", None, door_alias, {})) register_server_with_devices(db, bin_name, inst_name, devices) log_messages.append(("Registered server '%s/%s'", bin_name, inst_name)) for d in devices: dev_class, dev_alias = d[0], d[2] log_messages.append(("Registered %s %s", dev_class, dev_alias)) return log_messages def register_server_with_devices(db, server_name, server_instance, devices): """Registers a new server with some devices in the Database. Devices is a seq>> where each item is a sequence of 4 elements : - device class - device name prefix - device alias - dictionary of properties :param db: database where to register devices :type db: PyTango.Database :param server_name: server name :type server_name: str :param server_instance: server instance name :type server_instance: str :param devices: map of devices to create. :type devices: dict>> """ info = DbDevInfo() info.server = server_name + "/" + server_instance for dev_info in devices: dev_class, prefix, alias, props = dev_info if prefix is None: prefix = dev_class + "/" + server_instance if prefix.count("/") == 1: prefix = get_free_device(db, prefix) info._class = dev_class info.name = prefix db.add_device(info) if alias is None: alias_prefix = dev_class + "_" + server_instance alias = get_free_alias(db, alias_prefix) db.put_device_alias(info.name, alias) if props is not None: db.put_device_property(info.name, props) def from_name_to_tango(db, name): alias = None c = name.count('/') # if the db prefix is there, remove it first if c == 3 or c == 1: name = name[name.index("/")+1:] elems = name.split('/') l = len(elems) if l == 3: try: alias = db.get_alias(name) if alias.lower() == 'nada': alias = None except: alias = None elif l == 1: alias = name name = db.get_device_alias(alias) else: raise Exception("Invalid device name '%s'" % name) full_name = "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), name) return full_name, name, alias def get_dev_from_class(db, classname): """Returns tuple""" server_wildcard = '*' try: exp_dev_list = db.get_device_exported_for_class(classname) except Exception: exp_dev_list = [] res = {} dev_list = db.get_device_name(server_wildcard, classname) for dev in dev_list: full_name, name, alias = from_name_to_tango(db, dev) out = alias or name if alias: out += ' (a.k.a. %s)' % name out = "%-25s" % out if dev in exp_dev_list: out += " (running)" res[dev] = full_name, name, alias, out return res def get_free_device(db, prefix, start_from=1): members = db.get_device_member(prefix + "/*") while str(start_from) in members: start_from += 1 return prefix + "/" + str(start_from) def get_free_alias(db, prefix, start_from=1): while True: name = prefix + "_" + str(start_from) try: db.get_alias(name) start_from += 1 except: return name def prepare_taurus(options, args, tango_args): # make sure the polling is not active factory = taurus.Factory() factory.disablePolling() def prepare_logging(options, args, tango_args, start_time=None, log_messages=None): taurus.setLogLevel(taurus.Debug) root = Logger.getRootLog() # output logger configuration log_output_level = options.log_level log_level_map = { "0" : taurus.Critical, "critical" : taurus.Critical, "1" : taurus.Error, "error" : taurus.Error, "2" : taurus.Warning, "warning" : taurus.Warning, "3" : taurus.Info, "info" : taurus.Info, "4" : taurus.Debug, "debug" : taurus.Debug, "5" : taurus.Trace, "trace" : taurus.Trace, } log_output_level = log_level_map[log_output_level] root.handlers[0].setLevel(log_output_level) if not options.without_log_file: log_file_level = options.log_file_level log_file_level = log_level_map[log_file_level] # Create a file handler if options.log_file_name is None: _, ds_name = os.path.split(args[0]) ds_name, _ = os.path.splitext(ds_name) ds_instance = args[-1].lower() import getpass try: tangodir = 'tango-%s'%getpass.getuser() #include the user name to avoid permission errors except: tangodir = 'tango'%getpass.getuser() path = os.path.join(os.sep, "tmp", tangodir, ds_name, ds_instance) log_file_name = os.path.join(path, 'log.txt') else: log_file_name = options.log_file_name path = os.path.dirname(log_file_name) # because some versions of python have a bug in logging.shutdown (this # function is not protected against deleted handlers) we store the # handlers we create to make sure a strong reference exists when the # logging.shutdown is called taurus._handlers = handlers = [] try: if not os.path.exists(path): os.makedirs(path, 0777) fmt = Logger.getLogFormat() f_h = logging.handlers.RotatingFileHandler(log_file_name, maxBytes=1E7, backupCount=5) f_h.setFormatter(fmt) f_h.setLevel(log_file_level) root.addHandler(f_h) handlers.append(f_h) if start_time is not None: taurus.info("Started at %s", start_time) else: taurus.info("Starting up...") taurus.info("Log is being stored in %s", log_file_name) except: if start_time is not None: taurus.info("Started at %s", start_time) else: taurus.info("Starting up...") taurus.warning("'%s' could not be created. Logs will not be stored", log_file_name) taurus.debug("Error description", exc_info=1) if log_messages is None: log_messages = [] for log_message in log_messages: taurus.info(*log_message) taurus.debug("Start args=%s", args) taurus.debug("Start tango args=%s", tango_args) taurus.debug("Start options=%s", options) taurus.debug("Using PyTango %s from %s", PyTango.Release.version, PyTango.__path__[0]) taurus.debug("Using taurus %s from %s", taurus.Release.version, taurus.__path__[0]) taurus.debug("Using sardana %s from %s", sardana.Release.version, sardana.__path__[0]) def prepare_rconsole(options, args, tango_args): port = options.rconsole_port if port is None or port is 0: return taurus.debug("Setting up rconsole on port %d...", port) try: import rfoo.utils.rconsole rfoo.utils.rconsole.spawn_server(port=port) taurus.debug("Finished setting up rconsole") except: taurus.debug("Failed to setup rconsole", exc_info=1) def run_tango_server(tango_util=None, start_time=None): try: if tango_util is None: tango_util = Util(sys.argv) util = Util.instance() SardanaServer.server_state = State.Init util.server_init() SardanaServer.server_state = State.Running if start_time is not None: import datetime dt = datetime.datetime.now() - start_time taurus.info("Ready to accept request in %s", dt) else: taurus.info("Ready to accept request") util.server_run() SardanaServer.server_state = State.Off taurus.info("Exiting") except DevFailed: taurus.info("Exiting") taurus.critical("Server exited with DevFailed", exc_info=1) except KeyboardInterrupt: taurus.info("Exiting") taurus.critical("Interrupted by keyboard") except Exception: taurus.info("Exiting") taurus.critical("Server exited with unforeseen exception", exc_info=1) taurus.info("Exited") def run(prepare_func, args=None, tango_util=None, start_time=None, mode=None): if mode is None: mode = ServerRunMode.SynchPure if args is None: if mode != ServerRunMode.SynchPure: raise Exception("When running in separate thread/process, " \ "'args' must be given") args = sys.argv name = args[0] if mode != ServerRunMode.SynchPure: if mode in (ServerRunMode.SynchThread, ServerRunMode.AsynchThread): import threading class task_klass(threading.Thread): def terminate(self): if not self.is_alive(): return Util.instance().get_dserver_device().kill() else: import multiprocessing task_klass = multiprocessing.Process tango_util = None task_args = prepare_func, task_kwargs = dict(args=args, tango_util=tango_util, start_time=start_time, mode=ServerRunMode.SynchPure) task = task_klass(name=name, target=run, args=task_args, kwargs=task_kwargs) task.daemon = False task.start() if mode in (ServerRunMode.SynchThread, ServerRunMode.SynchProcess): task.join() return task log_messages = [] try: options, args, tango_args, ORB_args = prepare_cmdline(args=args) except KeyboardInterrupt: pass log_messages.extend(prepare_environment(args, tango_args, ORB_args)) log_messages.extend(prepare_server(args, tango_args)) if tango_util == None: tango_util = Util(tango_args) prepare_func(tango_util) prepare_taurus(options, args, tango_args) prepare_logging(options, args, tango_args, start_time=start_time, log_messages=log_messages) prepare_rconsole(options, args, tango_args) run_tango_server(tango_util, start_time=start_time) sardana-1.2.0/src/sardana/tango/macroserver/0000755000234100017500000000000012174204361022370 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/tango/macroserver/Door.py0000644000234100017500000004302312174204311023642 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## import sys import threading import time import copy import json from PyTango import Util, DevFailed, Except, DevVoid, DevShort, DevLong, \ DevLong64, DevDouble, DevBoolean, DevString, DevState, DevEncoded, \ DevVarStringArray, \ DispLevel, AttrQuality, TimeVal, AttrData, ArgType, \ READ, READ_WRITE, SCALAR, SPECTRUM import taurus import taurus.core.util from lxml import etree from taurus.core.util import CodecFactory, DebugIt from sardana import State, InvalidId, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.macroserver.macro import Macro from sardana.macroserver.msdoor import BaseInputHandler from sardana.tango.core.attributehandler import AttributeLogHandler from sardana.tango.core.SardanaDevice import SardanaDevice, SardanaDeviceClass from sardana.macroserver.msexception import MacroServerException, \ InputCancelled class TangoInputHandler(BaseInputHandler): def __init__(self, door, attr): self._value = None self._input_waitting = False self._input_event = threading.Event() self._door = door self._attr = attr def input(self, input_data=None): if input_data is None: input_data = {} self.input_data = input_data timeout = input_data.get('timeout') input_data = json.dumps(input_data) self._value = None self._input_waitting = True try: self._door.set_attribute(self._attr, value=input_data) res = self.input_wait(timeout=timeout) finally: self._input_waitting = False if res is None or res.get('cancel', False): raise InputCancelled('Input cancelled by user') return res['input'] def input_received(self, value): if not self._input_waitting: return self._value = json.loads(value) self._input_event.set() def input_wait(self, timeout=None): wait = self._input_event.wait(timeout) # if there was a timeout: # - set the value to the default value (if one exists) # - inform clients that timeout occured and they should not wait for # user input anymore if not self._input_event.is_set(): if 'default_value' in self.input_data: self._value = dict(input=self.input_data['default_value']) self.send_input_timeout() self._input_event.clear() return self._value def send_input_timeout(self): idata = self.input_data input_data = dict(type="timeout", macro_id=idata['macro_id']) if 'default_value' in idata: input_data['default_value'] = idata['default_value'] input_data = json.dumps(input_data) door = self._door door.set_attribute(self._attr, value=input_data) class TangoFunctionHandler(object): def __init__(self, door, attr, module_name, format="bz2_pickle"): self.door = door self.attr = attr self.module_name = module_name self.format = format def handle(self, func_name, *args, **kwargs): codec = CodecFactory().getCodec(self.format) data = dict(type='function', func_name=func_name, args=args, kwargs=kwargs) event_value = codec.encode(('', data)) self.door.set_attribute(self.attr, value=event_value) def __getattr__(self, name): def f(*args, **kwargs): full_name = self.module_name + "." + name return self.handle(full_name, *args, **kwargs) f.__name__ = name return f class TangoPylabHandler(TangoFunctionHandler): def __init__(self, door, attr, format="bz2_pickle"): TangoFunctionHandler.__init__(self, door, attr, "pylab", format="bz2_pickle") class TangoPyplotHandler(TangoFunctionHandler): def __init__(self, door, attr, format="bz2_pickle"): TangoFunctionHandler.__init__(self, door, attr, "pyplot", format="bz2_pickle") class Door(SardanaDevice): def __init__(self, dclass, name): SardanaDevice.__init__(self, dclass, name) self._last_result = () self._input_handler = None def init(self, name): SardanaDevice.init(self, name) self._door = None self._macro_server_device = None def get_door(self): return self._door def set_door(self, door): self._door = door door = property(get_door, set_door) @property def macro_server_device(self): return self._macro_server_device @property def macro_server(self): return self.door.macro_server def delete_device(self): if self.getRunningMacro(): self.debug("aborting running macro") self.macro_executor.abort() for handler, filter, format in self._handler_dict.values(): handler.finish() door = self.door if door is not None: door.remove_listener(self.on_door_changed) @DebugIt() def init_device(self): SardanaDevice.init_device(self) levels = 'Critical', 'Error', 'Warning', 'Info', 'Output', 'Debug' detect_evts = () non_detect_evts = ['State', 'Status', 'Result', 'RecordData', 'MacroStatus', 'Input'] + list(levels) self.set_change_events(detect_evts, non_detect_evts) util = Util.instance() db = util.get_database() # Find the macro server for this door macro_servers = util.get_device_list_by_class("MacroServer") if self.MacroServerName is None: self._macro_server_device = macro_servers[0] else: ms_name = self.MacroServerName.lower() for ms in macro_servers: if ms.get_name().lower() == ms_name or \ ms.alias.lower() == ms_name: self._macro_server_device = ms break # support for old doors which didn't have ID if self.Id == InvalidId: self.Id = self.macro_server_device.macro_server.get_new_id() db.put_device_property(self.get_name(), dict(Id=self.Id)) door = self.door if door is None: full_name = self.get_name() name = full_name macro_server = self.macro_server_device.macro_server self.door = door = \ macro_server.create_element(type="Door", name=name, full_name=full_name, id=self.Id) self._setupLogHandlers(levels) multi_attr = self.get_device_attr() input_attr = multi_attr.get_attr_by_name('Input') self._input_handler = ih = TangoInputHandler(self, input_attr) door.set_input_handler(ih) recorddata_attr = multi_attr.get_attr_by_name('RecordData') self._pylab_handler = pylabh = TangoPylabHandler(self, recorddata_attr) door.set_pylab_handler(pylabh) self._pyplot_handler = pyploth = TangoPyplotHandler(self, recorddata_attr) door.set_pyplot_handler(pyploth) door.add_listener(self.on_door_changed) self.set_state(DevState.ON) def _setupLogHandlers(self, levels): self._handler_dict = {} for level in levels: handler = AttributeLogHandler(self, level, max_buff_size=self.MaxMsgBufferSize) filter = taurus.core.util.LogFilter(level=getattr(self, level)) handler.addFilter(filter) self.addLogHandler(handler) format = None self._handler_dict[level] = handler, filter, format def on_door_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() multi_attr = self.get_device_attr() try: attr = multi_attr.get_attr_by_name(name) except DevFailed: return if name == "state": event_value = self.calculate_tango_state(event_value) elif name == "status": event_value = self.calculate_tango_status(event_value) elif name == "recorddata": format, value = event_value codec = CodecFactory().getCodec(format) event_value = codec.encode(('', value)) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) timestamp = event_value.timestamp event_value = event_value.value if attr.get_data_type() == ArgType.DevEncoded: codec = CodecFactory().getCodec('json') event_value = codec.encode(('', event_value)) self.set_attribute(attr, value=event_value, timestamp=timestamp) @property def macro_executor(self): return self.door.macro_executor def getRunningMacro(self): return self.door.running_macro def always_executed_hook(self): pass def read_attr_hardware(self,data): pass def readLogAttr(self, attr): name = attr.get_name() handler, filter, format = self._handler_dict[name] handler.read(attr) read_Critical = read_Error = read_Warning = read_Info = read_Output = \ read_Debug = read_Trace = readLogAttr def read_Input(self, attr): attr.set_value('') def write_Input(self, attr): value = attr.get_write_value() self._input_handler.input_received(value) #@DebugIt() def read_ElementList(self, attr): element_list = self.macro_server_device.getElementList() attr.set_value(*element_list) def sendRecordData(self, format, data): self.push_change_event('RecordData', format, data) def getLogAttr(self, name): return self._handler_dict.get(name) def read_Result(self, attr): # Add your own code here attr.set_value(self._last_result) def read_RecordData(self, attr): try: macro_data = self.door.get_macro_data() codec = CodecFactory().getCodec('bz2_pickle') data = codec.encode(('', macro_data)) except: data = '', '' attr.set_value(*data) def read_MacroStatus(self, attr): attr.set_value('', '') def Abort(self): self.debug("Abort is deprecated. Use StopMacro instead") return self.StopMacro() def AbortMacro(self): self.debug("Aborting") self.macro_executor.abort() self.debug("Finished aborting") def is_Abort_allowed(self): return True def PauseMacro(self): macro = self.getRunningMacro() if macro is None: print "Unable to pause Null macro" return self.macro_executor.pause() def is_PauseMacro_allowed(self): return self.get_state() == Macro.Running def StopMacro(self): macro = self.getRunningMacro() if macro is None: return self.debug("stopping macro %s" % macro._getDescription()) self.macro_executor.stop() def is_StopMacro_allowed(self): return self.get_state() == Macro.Running def ResumeMacro(self): macro = self.getRunningMacro() if macro is None: return self.debug("resume macro %s" % macro._getDescription()) self.macro_executor.resume() def is_ResumeMacro_allowed(self): return self.get_state() == Macro.Pause def RunMacro(self, par_str_list): #first empty all the buffers for handler, filter, fmt in self._handler_dict.values(): handler.clearBuffer() if len(par_str_list) == 0: return [] xml_seq = self.door.run_macro(par_str_list, asynch=True) return [etree.tostring(xml_seq, pretty_print=False)] def is_RunMacro_allowed(self): return self.get_state() in [Macro.Finished, Macro.Abort] def SimulateMacro(self, par_str_list): raise Exception("Not implemented yet") def GetMacroEnv(self, argin): macro_name = argin[0] if len(argin) > 1: macro_env = argin[1:] else: macro_env = self.door.get_macro_class_info(macro_name).env env = self.door.get_env(macro_env, macro_name=macro_name) ret = [] for k,v in env.iteritems(): ret.extend((k,v)) return ret def is_GetMacroEnv_allowed(self): return self.get_state() in [Macro.Finished, Macro.Abort] class DoorClass(SardanaDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { 'Id': [DevLong64, "Internal ID", [ InvalidId ] ], 'MaxMsgBufferSize': [DevLong, 'Maximum size for the Output, Result, Error, Warning, Debug and ' 'Info buffers', [512] ], 'MacroServerName': [DevString, 'Name of the macro server device to connect to. [default: None, ' 'meaning connect to the first registered macroserver', None ], } # Command definitions cmd_list = { 'Abort': [ [ DevVoid, ""], [ DevVoid, ""] ], 'PauseMacro': [ [DevVoid, ""], [DevVoid, ""] ], 'AbortMacro': [ [DevVoid, ""], [DevVoid, ""] ], 'StopMacro': [ [DevVoid, ""], [DevVoid, ""] ], 'ResumeMacro': [ [DevVoid, ""], [DevVoid, ""] ], 'RunMacro': [ [DevVarStringArray, 'Macro name and parameters'], [DevVarStringArray, 'Macro Result']], 'SimulateMacro': [ [DevVarStringArray, 'Macro name and parameters'], [DevVarStringArray, 'Macro statistics']], 'GetMacroEnv': [ [ DevVarStringArray, 'Macro name followed by an ' \ 'optional list of environment names' ], [ DevVarStringArray, 'Macro environment as a list of '\ 'pairs keys, value'] ], # 'ReloadMacro': # [[DevVarStringArray, "Macro(s) name(s)"], # [DevVarStringArray, "[OK] if successfull or a traceback " \ # "if there was a error (one string with complete traceback of " \ # "each error)"]], # 'ReloadMacroLib': # [[DevVarStringArray, "MacroLib(s) name(s)"], # [DevVarStringArray, "[OK] if successfull or a traceback " \ # "if there was a error (one string with complete traceback of " \ # "each error)"]], } # Attribute definitions attr_list = { 'Result' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Result for the last macro', } ], 'Critical' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Macro critical error message', } ], 'Error' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Macro error message', } ], 'Warning' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Macro warning message', } ], 'Info' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Macro information message', } ], 'Debug' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Macro debug message', } ], 'Output' : [ [ DevString, SPECTRUM, READ, 512], { 'label' : 'Macro output message', } ], 'Input' : [ [ DevString, SCALAR, READ_WRITE], { 'label' : 'Macro input prompt', } ], 'RecordData' : [ [ DevEncoded, SCALAR, READ], { 'label' : 'Record Data', } ], 'MacroStatus' : [ [ DevEncoded, SCALAR, READ], { 'label' : 'Macro Status', } ], 'ElementList' : [ [ DevEncoded, SCALAR, READ], { 'label':"Element list", 'description' : 'the list of all elements (a ' 'JSON encoded dict)', } ], } sardana-1.2.0/src/sardana/tango/macroserver/MacroServer.py0000644000234100017500000004021512174204311025167 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """The MacroServer tango module""" import os.path from PyTango import Util, Except, DevVoid, DevLong, DevString, DevState, \ DevEncoded, DevVarStringArray, READ, READ_WRITE, SCALAR, SPECTRUM, DebugIt #from taurus.core.util import Logger from taurus.core.util import CodecFactory from sardana import State, SardanaServer #, ElementType from sardana.tango.core.SardanaDevice import SardanaDevice, SardanaDeviceClass from sardana.macroserver.msexception import MacroServerException from sardana.macroserver.macroserver import MacroServer as MS class MacroServer(SardanaDevice): """The MacroServer tango class""" ElementsCache = None EnvironmentCache = None def __init__(self,cl, name): self._macro_server = None SardanaDevice.__init__(self,cl, name) def init(self, name): SardanaDevice.init(self, name) if self._alias is None: self._alias = Util.instance().get_ds_inst_name() self._macro_server = ms = MS(self.get_full_name(), self.alias) ms.add_listener(self.on_macro_server_changed) @property def macro_server(self): return self._macro_server def delete_device(self): SardanaDevice.delete_device(self) self.clear_log_report() def init_device(self): SardanaDevice.init_device(self) self.set_change_event('State', True, False) self.set_change_event('Status', True, False) self.set_change_event('TypeList', True, False) self.set_change_event('DoorList', True, False) self.set_change_event('MacroList', True, False) self.set_change_event('MacroLibList', True, False) self.set_change_event('Elements', True, False) self.set_change_event('Environment', True, False) dev_class = self.get_device_class() self.get_device_properties(dev_class) self.EnvironmentDb = self._calculate_name(self.EnvironmentDb) self.LogReportFilename = self._calculate_name(self.LogReportFilename) macro_server = self.macro_server macro_server.set_python_path(self.PythonPath) macro_server.set_max_parallel_macros(self.MaxParallelMacros) # if it is not possible to store/retrieve the environment from the # current path then setup a new unique path and store the environment # there forever try: macro_server.set_environment_db(self.EnvironmentDb) except: self.error("Failed to set environment DB to %s", self.EnvironmentDb) self.debug("Details:", exc_info=1) import tempfile env_db = os.path.join(tempfile.mkdtemp(), MacroServerClass.DefaultEnvRelDir) env_db = self._calculate_name(env_db) db = Util.instance().get_database() db.put_device_property(self.get_name(), dict(EnvironmentDb=env_db)) self.EnvironmentDb = env_db macro_server.set_environment_db(self.EnvironmentDb) try: macro_server.set_log_report(self.LogReportFilename, self.LogReportFormat) except: self.error("Failed to setup log report to %s", self.LogReportFilename) self.debug("Details:", exc_info=1) macro_server.set_macro_path(self.MacroPath) macro_server.set_pool_names(self.PoolNames) if self.RConsolePort: try: import rfoo.utils.rconsole rfoo.utils.rconsole.spawn_server(port=self.RConsolePort) except Exception: self.warning("Failed to start rconsole") self.debug("Details:", exc_info=1) self.set_state(DevState.ON) def _calculate_name(self, name): if name is None: return None util = Util.instance() return name % { 'ds_name' : util.get_ds_name().lower(), 'ds_exec_name' : util.get_ds_exec_name(), 'ds_inst_name' : util.get_ds_inst_name().lower() } def on_macro_server_changed(self, evt_src, evt_type, evt_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return evt_name = evt_type.name.lower() multi_attr = self.get_device_attr() elems_attr = multi_attr.get_attr_by_name("Elements") if evt_name == "poolelementschanged": # force the element list cache to be rebuild next time someone reads # the element list self.ElementsCache = None self.set_attribute(elems_attr, value=evt_value.value) #self.push_change_event('Elements', *evt_value.value) elif evt_name in ("elementcreated", "elementdeleted"): # force the element list cache to be rebuild next time someone reads # the element list self.ElementsCache = None elem = evt_value value = { } if "created" in evt_name: key = 'new' else: key = 'del' json_elem = elem.serialize(pool=self.pool.full_name) value[key] = json_elem, value = CodecFactory().getCodec('json').encode(('', value)) self.set_attribute(elems_attr, value=value) #self.push_change_event('Elements', *value) elif evt_name == "elementschanged": # force the element list cache to be rebuild next time someone reads # the element list self.ElementsCache = None ms_name = self.macro_server.full_name new_values, changed_values, deleted_values = [], [], [] for elem in evt_value['new']: json_elem = elem.serialize(macro_server=ms_name) new_values.append(json_elem) for elem in evt_value['change']: json_elem = elem.serialize(macro_server=ms_name) changed_values.append(json_elem) for elem in evt_value['del']: json_elem = elem.serialize(macro_server=ms_name) deleted_values.append(json_elem) value = { "new" : new_values, "change": changed_values, "del" : deleted_values } value = CodecFactory().getCodec('json').encode(('', value)) self.set_attribute(elems_attr, value=value) #self.push_change_event('Elements', *value) elif evt_name == "environmentchanged": self.EnvironmentCache = None env_attr = multi_attr.get_attr_by_name("Environment") value = CodecFactory().getCodec('pickle').encode(('', evt_value)) self.set_attribute(env_attr, value=value) def always_executed_hook(self): pass def read_attr_hardware(self,data): pass def read_DoorList(self, attr): door_names = self.macro_server.get_door_names() attr.set_value(door_names) @DebugIt() def read_MacroList(self, attr): macro_names = self.macro_server.get_macro_names() attr.set_value(macro_names) def read_MacroLibList(self, attr): macro_lib_names = self.macro_server.get_macro_lib_names() attr.set_value(macro_lib_names) def read_TypeList(self, attr): type_names = self.macro_server.get_data_type_names_with_asterisc() attr.set_value(type_names) #@DebugIt() def getElements(self, cache=True): value = self.ElementsCache if cache and value is not None: return value elements = self.macro_server.get_elements_info() value = dict(new=elements) value = CodecFactory().getCodec('json').encode(('', value)) self.ElementsCache = value return value #@DebugIt() def read_Elements(self, attr): fmt, data = self.getElements() attr.set_value(fmt, data) def is_Elements_allowed(self, req_type): return SardanaServer.server_state == State.Running is_DoorList_allowed = \ is_MacroList_allowed = \ is_MacroLibList_allowed = \ is_TypeList_allowed = is_Elements_allowed def GetMacroInfo(self, macro_names): """GetMacroInfo(list macro_names): Returns a list of string containing macro information. Each string is a JSON encoded. Params: - macro_name: a list of strings with the macro(s) name(s) Returns: - a list of string containing macro information. """ macro_server = self.macro_server codec = CodecFactory().getCodec('json') ret = [ codec.encode(('', macro.serialize()))[1] for macro in macro_server.get_macros() if macro.name in macro_names ] return ret def ReloadMacro(self, macro_names): """ReloadMacro(list macro_names):""" try: for macro_name in macro_names: self.macro_server.reload_macro(macro_name) except MacroServerException, mse: Except.throw_exception(mse.type, mse.msg, 'ReloadMacro') return ['OK'] def ReloadMacroLib(self, lib_names): """ReloadMacroLib(sequence lib_names): """ try: for lib_name in lib_names: self.macro_server.reload_macro_lib(lib_name) except MacroServerException, mse: Except.throw_exception(mse.type, mse.msg, 'ReloadMacroLib') return ['OK'] def GetMacroCode(self, argin): """GetMacroCode( [, ]) -> full filename, code, line_nb """ ret = self.macro_server.get_or_create_macro_lib(*argin) return map(str, ret) def SetMacroCode(self, argin): lib_name, code = argin[:2] auto_reload = True if len(argin) > 2: auto_reload = argin[2].lower() in ('true', 'yes') self.macro_server.set_macro_lib(lib_name, code, auto_reload=auto_reload) #@DebugIt() def getEnvironment(self, cache=True): value = self.EnvironmentCache if cache and value is not None: return value env = self.macro_server.get_env() value = dict(new=env) value = CodecFactory().getCodec('pickle').encode(('', value)) self.EnvironmentCache = value return value def read_Environment(self, attr): fmt, data = self.getEnvironment() attr.set_value(fmt, data) def write_Environment(self, attr): data = attr.get_write_value() data = CodecFactory().getCodec('pickle').decode(data)[1] self.macro_server.change_env(data) def is_Environment_allowed(self, req_type): return True class MacroServerClass(SardanaDeviceClass): """MacroServer Tango class class""" # Class Properties class_property_list = { } DefaultEnvBaseDir = "/tmp/tango" DefaultEnvRelDir = "%(ds_exec_name)s/%(ds_inst_name)s/macroserver.properties" DefaultLogReportFormat = '%(levelname)-8s %(asctime)s: %(message)s' # Device Properties device_property_list = { 'PoolNames': [DevVarStringArray, "Sardana device pool device names", [] ], 'MacroPath': [DevVarStringArray, "list of directories to search for macros (path separators " "can be '\n' or ':')", [] ], 'PythonPath': [DevVarStringArray, "list of directories to be appended to sys.path at startup (path " "separators can be '\n' or ':')", [] ], 'MaxParallelMacros': [DevLong, "Maximum number of macros that can execute concurrently.", [10] ], 'EnvironmentDb': [DevString, "The environment database (usually a plain file).", os.path.join(DefaultEnvBaseDir, DefaultEnvRelDir) ], 'RConsolePort': [DevLong, "The rconsole port number", None ], 'LogReportFilename': [DevString, "Filename (absolute) which contains user log reports [default: " "None, meaning don't store log report messages]. The system will " "save old log files by appending extensions to the filename. The " "extensions are date-and-time based, using the strftime " "format %Y-%m-%d_%H-%M-%S or a leading portion thereof, " "depending on the rollover interval.", None ], 'LogReportFormat': [DevString, "Log report format [default: '%s']" % DefaultLogReportFormat, DefaultLogReportFormat], } # Command definitions cmd_list = { 'GetMacroInfo': [[DevVarStringArray, "Macro(s) name(s)"], [DevVarStringArray, "Macro(s) description(s)"]], 'ReloadMacro': [[DevVarStringArray, "Macro(s) name(s)"], [DevVarStringArray, "[OK] if successfull or a traceback " \ "if there was a error (one string with complete traceback of " \ "each error)"]], 'ReloadMacroLib': [[DevVarStringArray, "MacroLib(s) name(s)"], [DevVarStringArray, "[OK] if successfull or a traceback " \ "if there was a error (one string with complete traceback of " \ "each error)" ]], 'GetMacroCode': [[DevVarStringArray, " [, ]"], [DevVarStringArray, "result is a sequence of 3 strings:\n" ", , " ]], 'SetMacroCode': [[DevVarStringArray, ", [, =True]\n" \ "- if macro lib is a simple module name:\n" \ " - if it exists, it is overwritten, otherwise a new python " \ "file is created in the directory of the first element in "\ "the MacroPath property" \ "- if macro lib is the full path name:\n" \ " - if path is not in the MacroPath, an exception is thrown" \ " - if file exists it is overwritten otherwise a new file " \ "is created"], [DevVoid, "" ]], } # Attribute definitions attr_list = { 'DoorList' : [ [ DevString, SPECTRUM, READ, 256 ] ], 'MacroList' : [ [ DevString, SPECTRUM, READ, 4096 ] ], 'MacroLibList' : [ [ DevString, SPECTRUM, READ, 1024 ] ], 'TypeList' : [ [ DevString, SPECTRUM, READ, 256 ] ], 'Elements' : [ [ DevEncoded, SCALAR, READ ], { 'label' : "Elements", 'description' : "the list of all elements " "(a JSON encoded dict)", } ], 'Environment' : [ [ DevEncoded, SCALAR, READ_WRITE], { 'label' : 'Environment', 'description' : "The macro server environment " "(a JSON encoded dict)", } ], } sardana-1.2.0/src/sardana/tango/macroserver/__init__.py0000644000234100017500000000352112174204311024475 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __docformat__ = 'restructuredtext' from .MacroServer import * from .Door import * def prepare_macroserver(util): import taurus.core.util.log Logger = taurus.core.util.log.Logger # Two additional log levels: # output of a macro Logger.addLevelName(15, "OUTPUT") def output(loggable, msg, *args, **kw): loggable.getLogObj().log(Logger.Output, msg, *args, **kw) Logger.output = output # result of a macro Logger.addLevelName(18, "RESULT") util.add_class(MacroServerClass, MacroServer) util.add_class(DoorClass, Door) def main_macroserver(args=None, start_time=None, mode=None): import sardana.tango.core.util return sardana.tango.core.util.run(prepare_macroserver, args=args, start_time=start_time, mode=mode) run = main_macroserver sardana-1.2.0/src/sardana/tango/pool/0000755000234100017500000000000012174204361021011 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/tango/pool/CTExpChannel.py0000644000234100017500000001720512174204312023640 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["CTExpChannel", "CTExpChannelClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import DevFailed, DevVoid, DevDouble, DevState, AttrQuality, \ Except, READ, SCALAR from taurus.core.util.log import DebugIt from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.tango.core.util import to_tango_type_format, exception_str from PoolDevice import PoolElementDevice, PoolElementDeviceClass class CTExpChannel(PoolElementDevice): def __init__(self, dclass, name): PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def get_ct(self): return self.element def set_ct(self, ct): self.element = ct ct = property(get_ct, set_ct) @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) ct = self.ct if ct is not None: ct.remove_listener(self.on_ct_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) ct = self.ct if ct is None: full_name = self.get_full_name() name = self.alias or full_name self.ct = ct = \ self.pool.create_element(type="CTExpChannel", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id) if self.instrument is not None: ct.set_instrument(self.instrument) ct.add_listener(self.on_ct_changed) ## force a state read to initialize the state attribute #state = ct.state self.set_state(DevState.ON) def on_ct_changed(self, event_source, event_type, event_value): try: self._on_ct_changed(event_source, event_type, event_value) except not DevFailed: msg = 'Error occurred "on_ct_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.motor.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_ct_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() try: attr = self.get_attribute_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp else: value = event_value if name == "value": w_value = event_source.get_value_attribute().w_value state = self.ct.get_state() if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.ct.get_state(cache=False)) pass def read_attr_hardware(self,data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For value attribute, listen to what the controller says for data # type (between long and float) value = std_attrs.get('value') if value is not None: _, data_info, attr_info = value ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype return std_attrs, dyn_attrs def initialize_dynamic_attributes(self): attrs = PoolElementDevice.initialize_dynamic_attributes(self) detect_evts = "value", non_detect_evts = () for attr_name in detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, True) for attr_name in non_detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, False) def read_Value(self, attr): ct = self.ct use_cache = ct.is_in_operation() and not self.Force_HW_Read value = ct.get_value(cache=use_cache, propagate=0) if value.error: Except.throw_python_exception(*value.exc_info) state = ct.get_state(cache=use_cache, propagate=0) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value.value,quality=quality, timestamp=value.timestamp, priority=0) def is_Value_allowed(self, req_type): if self.get_state() in [DevState.FAULT, DevState.UNKNOWN]: return False return True def Start(self): self.ct.start_acquisition() class CTExpChannelClass(PoolElementDeviceClass): # Class Properties class_property_list = {} # Device Properties device_property_list = {} device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = {} attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { 'Value' : [ [ DevDouble, SCALAR, READ ], { 'abs_change' : '1.0', } ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "Counter/Timer device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/Controller.py0000644000234100017500000002337212174204312023511 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["Controller", "ControllerClass"] __docformat__ = 'restructuredtext' import time from PyTango import Util, DevFailed, Except from PyTango import DevVoid, DevLong, DevString from PyTango import DevVarStringArray, DevVarLongArray from PyTango import DispLevel, DevState, AttrQuality from PyTango import SCALAR, SPECTRUM from PyTango import READ_WRITE, READ from taurus.core.util import CaselessDict, DebugIt from sardana import DataType, DataFormat from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.tango.core.util import to_tango_attr_info from PoolDevice import PoolDevice, PoolDeviceClass def to_bool(s): return s.lower() == "true" class Controller(PoolDevice): def __init__(self, dclass, name): PoolDevice.__init__(self, dclass, name) def init(self, name): PoolDevice.init(self, name) def get_ctrl(self): return self.element def set_ctrl(self, ctrl): self.element = ctrl ctrl = property(get_ctrl, set_ctrl) @DebugIt() def delete_device(self): PoolDevice.delete_device(self) @DebugIt() def init_device(self): PoolDevice.init_device(self) detect_evts = "state", "status" non_detect_evts = "elementlist", self.set_change_events(detect_evts, non_detect_evts) ctrl = self.ctrl if ctrl is None: role_ids = self.get_role_ids() full_name = self.get_full_name() name = self.alias or full_name args = dict(type=self.Type, name=name, full_name=full_name, library=self.Library, klass=self.Klass, id=self.Id, role_ids=self.Role_ids, properties=self._get_ctrl_properties()) ctrl = self.pool.create_controller(**args) ctrl.add_listener(self.on_controller_changed) self.ctrl = ctrl self.set_state(DevState.ON) #self.set_state(to_tango_state(ctrl.get_state())) #self.set_status(ctrl.get_status()) else: ctrl.re_init() def get_role_ids(self): db = Util.instance().get_database() if db is None: return [] role_ids = db.get_device_property(self.get_name(), ['motor_role_ids'])['motor_role_ids'] if len(role_ids) == 0: role_ids = db.get_device_property(self.get_name(), ['counter_role_ids'])['counter_role_ids'] if len(role_ids) == 0: role_ids = self.Role_ids role_ids = map(int, role_ids) return role_ids def _get_ctrl_properties(self): try: ctrl_info = self.pool.get_controller_class_info(self.Klass) prop_infos = ctrl_info.ctrl_properties except: return {} db = Util.instance().get_database() if db is None: return {} props = {} if prop_infos: props.update(db.get_device_property(self.get_name(), prop_infos.keys())) for p in props.keys(): if len(props[p]) == 0: props[p] = None ret = {} missing_props = [] for prop_name, prop_value in props.items(): if prop_value is None: dv = prop_infos[prop_name].default_value if dv is None: missing_props.append(prop_name) ret[prop_name] = dv continue prop_info = prop_infos[prop_name] dtype, dformat = prop_info.dtype, prop_info.dformat op = str if dtype == DataType.Integer: op = int elif dtype == DataType.Double: op = float elif dtype == DataType.Boolean: op = to_bool prop_value = map(op, prop_value) if dformat == DataFormat.Scalar: prop_value = prop_value[0] ret[prop_name] = prop_value if missing_props: self.set_state(DevState.ALARM) missing_props = ", ".join(missing_props) self.set_status("Controller has missing properties: %s" % missing_props) return ret def always_executed_hook(self): pass def read_attr_hardware(self,data): pass def dev_state(self): if self.ctrl is None or not self.ctrl.is_online(): return DevState.FAULT return DevState.ON def dev_status(self): if self.ctrl is None or not self.ctrl.is_online(): self._status = self.ctrl.get_ctrl_error_str() else: self._status = PoolDevice.dev_status(self) return self._status def read_ElementList(self, attr): attr.set_value(self.get_element_names()) def CreateElement(self, argin): pass def DeleteElement(self, argin): pass def get_element_names(self): elements = self.ctrl.get_elements() return [ elements[id].get_name() for id in sorted(elements) ] def on_controller_changed(self, event_src, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() multi_attr = self.get_device_attr() try: attr = multi_attr.get_attr_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority error = None if name == "state": event_value = self.calculate_tango_state(event_value) elif name == "status": event_value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) timestamp = event_value.timestamp event_value = event_value.value self.set_attribute(attr, value=event_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def get_dynamic_attributes(self): if hasattr(self, "_dynamic_attributes_cache"): return self._standard_attributes_cache, self._dynamic_attributes_cache info = self.ctrl.ctrl_info if info is None: self.warning("Controller %s doesn't have any information", self.ctrl) return PoolDevice.get_dynamic_attributes(self) self._dynamic_attributes_cache = dyn_attrs = CaselessDict() self._standard_attributes_cache = std_attrs = CaselessDict() for attr_name, attr_data in info.ctrl_attributes.items(): name, tg_info = to_tango_attr_info(attr_name, attr_data) dyn_attrs[attr_name] = attr_name, tg_info, attr_data return std_attrs, dyn_attrs def read_DynamicAttribute(self, attr): attr_name = attr.get_name() attr.set_value(self.ctrl.get_ctrl_attr(attr_name)) def write_DynamicAttribute(self, attr): v = attr.get_write_value() attr_name = attr.get_name() self.ctrl.set_ctrl_attr(attr_name, v) def read_LogLevel(self, attr): l = self.ctrl.get_log_level() self.debug(l) attr.set_value(l) def write_LogLevel(self, attr): self.ctrl.set_log_level(attr.get_write_value()) class ControllerClass(PoolDeviceClass): # Class Properties class_property_list = { } class_property_list.update(PoolDeviceClass.class_property_list) # Device Properties device_property_list = { 'Type': [DevString, "", None ], 'Library': [DevString, "", None ], 'Klass': [DevString, "", None ], 'Role_ids': [DevVarLongArray, "", [] ], } device_property_list.update(PoolDeviceClass.device_property_list) # Command definitions cmd_list = { 'CreateElement': [ [DevVarStringArray, ""], [DevVoid, ""] ], 'DeleteElement': [ [DevString, ""], [DevVoid, ""] ], } cmd_list.update(PoolDeviceClass.cmd_list) # Attribute definitions attr_list = { 'ElementList': [ [DevString, SPECTRUM, READ, 4096] ], 'LogLevel': [ [DevLong, SCALAR, READ_WRITE], { 'Memorized' : "true", 'label' : "Log level", 'Display level' : DispLevel.EXPERT } ], } attr_list.update(PoolDeviceClass.attr_list) def _get_class_properties(self): ret = PoolDeviceClass._get_class_properties(self) ret['Description'] = "Controller device class" ret['InheritedFrom'].insert(0, 'PoolDevice') return ret sardana-1.2.0/src/sardana/tango/pool/IORegister.py0000644000234100017500000002051112174204312023372 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["IORegister", "IORegisterClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import DevFailed, Except from PyTango import DevVoid, DevLong from PyTango import DevState, AttrQuality from PyTango import READ_WRITE, SCALAR from taurus.core.util import DebugIt from PoolDevice import PoolElementDevice, PoolElementDeviceClass from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool.poolexception import PoolException class IORegister(PoolElementDevice): def __init__(self, dclass, name): self.in_write_value = False PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def get_ior(self): return self.element def set_ior(self, ior): self.element = ior ior = property(get_ior, set_ior) def set_write_value_to_db(self): value_attr = self.ior.get_value_attribute() if value_attr.has_write_value(): data = dict(Value=dict(__value=value_attr.w_value, __value_ts=value_attr.w_timestamp)) db = self.get_database() db.put_device_attribute_property(self.get_name(), data) def get_write_value_from_db(self): name = 'Value' db = self.get_database() val_props = db.get_device_attribute_property(self.get_name(), name)[name] w_val = val_props["__value"][0] _, _, attr_info = self.get_dynamic_attributes()[0][name] w_val = str_to_value(w_val, attr_info.dtype, attr_info.dformat) w_val, w_ts = int(val_props["__value"][0]), None if "__value_ts" in val_props: w_ts = float(val_props["__value_ts"][0]) return w_val, w_ts @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) ior = self.ior if ior is not None: ior.remove_listener(self.on_ior_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) ior = self.ior if ior is None: full_name = self.get_full_name() name = self.alias or full_name self.ior = ior = \ self.pool.create_element(type="IORegister", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id) if self.instrument is not None: ior.set_instrument(self.instrument) ior.add_listener(self.on_ior_changed) ## force a state read to initialize the state attribute #state = ior.get_state(cache=False) self.set_state(DevState.ON) def on_ior_changed(self, event_source, event_type, event_value): try: self._on_ior_changed(event_source, event_type, event_value) except not DevFailed: msg = 'Error occurred "on_ior_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.ior.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_ior_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() if name == "w_value" and not self.in_write_value: self.debug("Storing value set point: %s", self.ior.value.w_value) self.set_write_value_to_db() return multi_attr = self.get_device_attr() try: attr = multi_attr.get_attr_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp state = self.ior.get_state(propagate=0) if name == "value": w_value = event_source.get_value_attribute().w_value if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.ior.get_state(cache=False)) pass def read_attr_hardware(self,data): pass def initialize_dynamic_attributes(self): attrs = PoolElementDevice.initialize_dynamic_attributes(self) detect_evts = "value", non_detect_evts = () for attr_name in detect_evts: if attrs.has_key(attr_name): self.set_change_event(attr_name, True, True) for attr_name in non_detect_evts: if attrs.has_key(attr_name): self.set_change_event(attr_name, True, False) return def read_Value(self, attr): value = self.ior.get_value(cache=False) if value.error: Except.throw_python_exception(*value.exc_info) self.set_attribute(attr, value=value.value, w_value=value.w_value, priority=0, timestamp=value.timestamp) def write_Value(self, attr): self.in_write_value = True value = attr.get_write_value() try: self.ior.set_value(value) # manually store write value in the database self.set_write_value_to_db() except PoolException as pe: throw_sardana_exception(pe) finally: self.in_write_value = False def is_Value_allowed(self, req_type): if self.get_state() in [DevState.FAULT, DevState.UNKNOWN]: return False return True def Start(self): self.ior.start_acquisition() class IORegisterClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = {} attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { 'Value' : [ [ DevLong, SCALAR, READ_WRITE ], { 'Memorized' : "true_without_hard_applied", }, ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "IORegister device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/MeasurementGroup.py0000644000234100017500000002203012174204312024656 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """The sardana tango measurement group module""" __all__ = ["MeasurementGroup", "MeasurementGroupClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import Except, DevVoid, DevLong, DevDouble, DevString, \ DispLevel, DevState, AttrQuality, \ READ_WRITE, SCALAR from taurus.core.util import CodecFactory from taurus.core.util.log import DebugIt from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool import AcqMode from sardana.tango.core.util import exception_str from PoolDevice import PoolGroupDevice, PoolGroupDeviceClass class MeasurementGroup(PoolGroupDevice): def __init__(self, dclass, name): PoolGroupDevice.__init__(self, dclass, name) def init(self, name): PoolGroupDevice.init(self, name) def get_measurement_group(self): return self.element def set_measurement_group(self, measurement_group): self.element = measurement_group measurement_group = property(get_measurement_group, set_measurement_group) @DebugIt() def delete_device(self): PoolGroupDevice.delete_device(self) mg = self.measurement_group if mg is not None: mg.remove_listener(self.on_measurement_group_changed) @DebugIt() def init_device(self): PoolGroupDevice.init_device(self) detect_evts = () # state and status are already set by the super class non_detect_evts = "configuration", "integrationtime", "monitorcount", \ "acquisitionmode", "elementlist" self.set_change_events(detect_evts, non_detect_evts) self.Elements = list(self.Elements) for i in range(len(self.Elements)): try: self.Elements[i] = int(self.Elements[i]) except: pass mg = self.measurement_group if mg is None: full_name = self.get_full_name() name = self.alias or full_name self.measurement_group = mg = \ self.pool.create_measurement_group(name=name, full_name=full_name, id=self.Id, user_elements=self.Elements) mg.add_listener(self.on_measurement_group_changed) # force a state read to initialize the state attribute #state = self.measurement_group.state self.set_state(DevState.ON) def on_measurement_group_changed(self, event_source, event_type, event_value): try: self._on_measurement_group_changed(event_source, event_type, event_value) except: msg = 'Error occured "on_measurement_group_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.measurement_group.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_measurement_group_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name name = name.replace('_','') multi_attr = self.get_device_attr() attr = multi_attr.get_attr_by_name(name) quality = AttrQuality.ATTR_VALID priority = event_type.priority error = None if name == "state": event_value = self.calculate_tango_state(event_value) elif name == "status": event_value = self.calculate_tango_status(event_value) elif name == "acquisitionmode": event_value = AcqMode.whatis(event_value) elif name == "configuration": cfg = self.measurement_group.get_user_configuration() codec = CodecFactory().getCodec('json') _, event_value = codec.encode(('', cfg)) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) timestamp = event_value.timestamp event_value = event_value.value self.set_attribute(attr, value=event_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): pass #state = to_tango_state(self.motor_group.get_state(cache=False)) def read_attr_hardware(self,data): pass def read_IntegrationTime(self, attr): it = self.measurement_group.integration_time if it is None: it = float('nan') attr.set_value(it) def write_IntegrationTime(self, attr): self.measurement_group.integration_time = attr.get_write_value() def read_MonitorCount(self, attr): it = self.measurement_group.monitor_count if it is None: it = 0 attr.set_value(it) def write_MonitorCount(self, attr): self.measurement_group.monitor_count = attr.get_write_value() def read_AcquisitionMode(self, attr): acq_mode = self.measurement_group.acquisition_mode acq_mode_str = AcqMode.whatis(acq_mode) attr.set_value(acq_mode_str) def write_AcquisitionMode(self, attr): acq_mode_str = attr.get_write_value() try: acq_mode = AcqMode.lookup[acq_mode_str] except KeyError: raise Exception("Invalid acquisition mode. Must be one of " + \ ", ".join(AcqMode.keys())) self.measurement_group.acquisition_mode = acq_mode def read_Configuration(self, attr): cfg = self.measurement_group.get_user_configuration() codec = CodecFactory().getCodec('json') data = codec.encode(('', cfg)) attr.set_value(data[1]) def write_Configuration(self, attr): data = attr.get_write_value() cfg = CodecFactory().decode(('json', data), ensure_ascii=True) self.measurement_group.set_configuration_from_user(cfg) def Start(self): try: self.wait_for_operation() except: raise Exception("Cannot acquire: already involved in an operation") self.measurement_group.start_acquisition() def StartMultiple(self, n): try: self.wait_for_operation() except: raise Exception("Cannot acquire: already involved in an operation") self.measurement_group.start_acquisition(multiple=n) class MeasurementGroupClass(PoolGroupDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { } device_property_list.update(PoolGroupDeviceClass.device_property_list) # Command definitions cmd_list = { 'Start': [ [DevVoid, ""], [DevVoid, ""] ], 'StartMultiple': [ [DevLong, ""], [DevVoid, ""] ], } cmd_list.update(PoolGroupDeviceClass.cmd_list) # Attribute definitions attr_list = { 'IntegrationTime': [ [DevDouble, SCALAR, READ_WRITE], { 'Memorized' : "true", 'Display level' : DispLevel.OPERATOR } ], 'MonitorCount': [ [DevLong, SCALAR, READ_WRITE], { 'Memorized' : "true", 'Display level' : DispLevel.OPERATOR } ], 'AcquisitionMode': [ [DevString, SCALAR, READ_WRITE], { 'Memorized' : "true", 'Display level' : DispLevel.OPERATOR } ], 'Configuration': [ [DevString, SCALAR, READ_WRITE], { 'Memorized' : "true", 'Display level' : DispLevel.EXPERT } ], } attr_list.update(PoolGroupDeviceClass.attr_list) def _get_class_properties(self): ret = PoolGroupDeviceClass._get_class_properties(self) ret['Description'] = "Measurement group device class" ret['InheritedFrom'].insert(0, 'PoolGroupDevice') return ret sardana-1.2.0/src/sardana/tango/pool/Motor.py0000644000234100017500000007172212174204312022470 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """The sardana tango motor module""" __all__ = ["Motor", "MotorClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import DevFailed, Except, DevVoid, DevShort, \ DevLong, DevDouble, DevBoolean, DispLevel, DevState, AttrQuality, \ READ, READ_WRITE, SCALAR, SPECTRUM from taurus.core.util import DebugIt from sardana import State, SardanaServer from sardana.sardanautils import str_to_value from sardana.sardanaattribute import SardanaAttribute from sardana.pool.poolexception import PoolException from sardana.tango.core.util import memorize_write_attribute, exception_str, \ to_tango_type_format, throw_sardana_exception from PoolDevice import PoolElementDevice, PoolElementDeviceClass class Motor(PoolElementDevice): """The tango motor device class. This class exposes through a tango device the sardana motor (:class:`~sardana.pool.poolmotor.PoolMotor`). .. rubric:: The states The motor interface knows five states which are ON, MOVING, ALARM, FAULT and UNKNOWN. A motor device is in MOVING state when it is moving! It is in ALARM state when it has reached one of the limit switches and is in FAULT if its controller software is not available (impossible to load it) or if a fault is reported from the hardware controller. The motor is in the UNKNOWN state if an exception occurs during the communication between the pool and the hardware controller. When the motor is in ALARM state, its status will indicate which limit switches is active. .. rubric:: The commands The motor interface supports 3 commands on top of the Tango classical Init, State and Status commands. These commands are summarized in the following table: ============== ================ ================ Command name Input data type Output data type ============== ================ ================ Stop void void Abort void void DefinePosition Tango::DevDouble void SaveConfig void void ============== ================ ================ - **Stop** : It stops a running motion. This command does not have input or output argument. - **Abort** : It aborts a running motion. This command does not have input or output argument. - **DefinePosition** : Loads a position into controller. It has one input argument which is the new position value (a double). It is allowed only in the ON or ALARM states. The unit used for the command input value is the physical unit: millimeters or milli-radians. It is always an absolute position. - **SaveConfig** : Write some of the motor parameters in database. Today, it writes the motor acceleration, deceleration, base_rate and velocity into database as motor device properties. It is allowed only in the ON or ALARM states The classical Tango Init command destroys the motor and re-create it. .. rubric:: The attributes The motor interface supports several attributes which are summarized in the following table: ============== ================= =========== ======== ========= =============== Name Data type Data format Writable Memorized Operator/Expert ============== ================= =========== ======== ========= =============== Position Tango::DevDouble Scalar R/W No * Operator DialPosition Tango::DevDouble Scalar R No Expert Offset Tango::DevDouble Scalar R/W Yes Expert Acceleration Tango::DevDouble Scalar R/W No Expert Base_rate Tango::DevDouble Scalar R/W No Expert Deceleration Tango::DevDouble Scalar R/W No Expert Velocity Tango::DevDouble Scalar R/W No Expert Limit_Switches Tango::DevBoolean Spectrum R No Expert SimulationMode Tango::DevBoolean Scalar R No Expert Step_per_unit Tango::DevDouble Scalar R/W Yes Expert Backlash Tango::DevLong Scalar R/W Yes Expert ============== ================= =========== ======== ========= =============== - **Position** : This is read-write scalar double attribute. With the classical Tango min and max_value attribute properties, it is easy to define authorized limit for this attribute. See the definition of the DialPosition and Offset attributes to get a precise definition of the meaning of this attribute. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. It is also not possible to write this attribute when the motor is already MOVING. The unit used for this attribute is the physical unit: millimeters or milli-radian. It is always an **absolute position** . - **DialPosition** : This attribute is the motor dial position. The following formula links together the Position, DialPosition, Sign and Offset attributes: Position = Sign * DialPosition + Offset This allows to have the motor position centered around any position defined by the Offset attribute (classically the X ray beam position). It is a read only attribute. To set the motor position, the user has to use the Position attribute. It is not allowed to read this attribute when the motor is in FAULT or UNKNOWN mode. The unit used for this attribute is the physical unit: millimeters or milli-radian. It is also always an **absolute** position. - **Offset** : The offset to be applied in the motor position computation. By default set to 0. It is a memorized attribute. It is not allowed to read or write this attribute when the motor is in FAULT, MOVING or UNKNOWN mode. - **Acceleration** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Deceleration** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Base_rate** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Velocity** : This is an expert read-write scalar double attribute. This parameter value is written in database when the SaveConfig command is executed. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN state. - **Limit_Switches** : Three limit switches are managed by this attribute. Each of the switch are represented by a boolean value: False means inactive while True means active. It is a read only attribute. It is not possible to read this attribute when the motor is in UNKNOWN mode. It is a spectrum attribute with 3 values which are: - Data[0] : The Home switch value - Data[1] : The Upper switch value - Data[2] : The Lower switch value - **SimulationMode** : This is a read only scalar boolean attribute. When set, all motion requests are not forwarded to the software controller and then to the hardware. When set, the motor position is simulated and is immediately set to the value written by the user. To set this attribute, the user has to used the pool device Tango interface. The value of the position, acceleration, deceleration, base_rate, velocity and offset attributes are memorized at the moment this attribute is set. When this mode is turned off, if the value of any of the previously memorized attributes has changed, it is reapplied to the memorized value. It is not allowed to read this attribute when the motor is in FAULT or UNKNOWN states. - **Step_per_unit** : This is the number of motor step per millimeter or per degree. It is a memorized attribute. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN mode. It is also not allowed to write this attribute when the motor is MOVING. The default value is 1. - **Backlash** : If this attribute is defined to something different than 0, the motor will always stop the motion coming from the same mechanical direction. This means that it could be possible to ask the motor to go a little bit after the desired position and then to return to the desired position. The attribute value is the number of steps the motor will pass the desired position if it arrives from the "wrong" direction. This is a signed value. If the sign is positive, this means that the authorized direction to stop the motion is the increasing motor position direction. If the sign is negative, this means that the authorized direction to stop the motion is the decreasing motor position direction. It is a memorized attribute. It is not allowed to read or write this attribute when the motor is in FAULT or UNKNOWN mode. It is also not allowed to write this attribute when the motor is MOVING. Some hardware motor controllers are able to manage this backlash feature. If it is not the case, the motor interface will implement this behavior. All the motor devices will have the already described attributes but some hardware motor controller supports other features which are not covered by this list of pre-defined attributes. Using Tango dynamic attribute creation, a motor device may have extra attributes used to get/set the motor hardware controller specific features. These are the attributes specified on the controller with :attr:`~sardana.pool.controller.Controller.axis_attribues`. .. rubric:: The properties - **Sleep_before_last_read** : This property exposes the motor *instability time*. It defines the time in milli-second that the software managing a motor movement will wait between it detects the end of the motion and the last motor position reading. .. rubric:: Getting motor state and limit switches using event The simplest way to know if a motor is moving is to survey its state. If the motor is moving, its state will be MOVING. When the motion is over, its state will be back to ON (or ALARM if a limit switch has been reached). The pool motor interface allows client interested by motor state or motor limit switches value to use the Tango event system subscribing to motor state change event. As soon as a motor starts a motion, its state is changed to MOVING and an event is sent. As soon as the motion is over, the motor state is updated ans another event is sent. In the same way, as soon as a change in the limit switches value is detected, a change event is sent to client(s) which have subscribed to change event on the Limit_Switches attribute. .. rubric:: Reading the motor position attribute For each motor, the key attribute is its position. Special care has been taken on this attribute management. When the motor is not moving, reading the Position attribute will generate calls to the controller and therefore hardware access. When the motor is moving, its position is automatically read every 100 milli-seconds and stored in the Tango polling buffer. This means that a client reading motor Position attribute while the motor is moving will get the position from the Tango polling buffer and will not generate extra controller calls. It is also possible to get a motor position using the Tango event system. When the motor is moving, an event is sent to the registered clients when the change event criterion is true. By default, this change event criterion is set to be a difference in position of 5. It is tunable on a motor basis using the classical motor Position attribute abs_change property or at the pool device basis using its DefaultMotPos_AbsChange property. Anyway, not more than 10 events could be sent by second. Once the motion is over, the motor position is made unavailable from the Tango polling buffer and is read a last time after a tunable waiting time (Sleep_bef_last_read property). A forced change event with this value is sent to clients using events. """ def __init__(self, dclass, name): """Constructor""" self.in_write_position = False PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def _is_allowed(self, req_type): return PoolElementDevice._is_allowed(self, req_type) def get_motor(self): return self.element def set_motor(self, motor): self.element = motor motor = property(get_motor, set_motor) def set_write_dial_position_to_db(self): dial = self.motor.get_dial_position_attribute() if dial.has_write_value(): data = dict(DialPosition=dict(__value=dial.w_value, __value_ts=dial.w_timestamp)) db = self.get_database() db.put_device_attribute_property(self.get_name(), data) def get_write_dial_position_from_db(self): name = 'DialPosition' db = self.get_database() pos_props = db.get_device_attribute_property(self.get_name(), name)[name] w_pos = pos_props["__value"][0] _, _, attr_info = self.get_dynamic_attributes()[0][name] w_pos = str_to_value(w_pos, attr_info.dtype, attr_info.dformat) w_pos, w_ts = float(pos_props["__value"][0]), None if "__value_ts" in pos_props: w_ts = float(pos_props["__value_ts"][0]) return w_pos, w_ts @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) motor = self.motor if motor is not None: motor.remove_listener(self.on_motor_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) motor = self.motor if motor is None: full_name = self.get_full_name() name = self.alias or full_name self.motor = motor = \ self.pool.create_element(type="Motor", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id) if self.instrument is not None: motor.set_instrument(self.instrument) # if in constructor, for all memorized no init attributes (position) # let poolmotor know their write values if self.in_constructor: try: w_pos, w_ts = self.get_write_dial_position_from_db() self.in_write_position = True try: motor.set_write_position(w_pos, timestamp=w_ts) finally: self.in_write_position = False except KeyError: pass if self.Sleep_bef_last_read > 0: motor.set_instability_time(self.Sleep_bef_last_read / 1000.0) motor.add_listener(self.on_motor_changed) self.set_state(DevState.ON) def on_motor_changed(self, event_source, event_type, event_value): try: self._on_motor_changed(event_source, event_type, event_value) except not DevFailed: msg = 'Error occurred "on_motor_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.motor.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_motor_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() if name == "w_position" and not self.in_write_position: self.debug("Storing dial set point: %s", self.motor.dial_position.w_value) self.set_write_dial_position_to_db() return try: attr = self.get_attribute_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp else: value = event_value state = self.motor.get_state(propagate=0) if name == "position": w_value = event_source.get_position_attribute().w_value if state == State.Moving: quality = AttrQuality.ATTR_CHANGING elif name == "dialposition" and state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): pass def read_attr_hardware(self, data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For position attribute, listen to what the controller says for data # type (between long and float) pos = std_attrs.get('position') if pos is not None: _, data_info, attr_info = pos ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype return std_attrs, dyn_attrs def initialize_dynamic_attributes(self): attrs = PoolElementDevice.initialize_dynamic_attributes(self) detect_evts = "position", "dialposition", non_detect_evts = "limit_switches", "step_per_unit", "offset", \ "sign", "velocity", "acceleration", "deceleration", "base_rate", \ "backlash" for attr_name in detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, True) for attr_name in non_detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, False) def read_Position(self, attr): motor = self.motor use_cache = motor.is_in_operation() and not self.Force_HW_Read state = motor.get_state(cache=use_cache, propagate=0) position = motor.get_position(cache=use_cache, propagate=0) if position.error: Except.throw_python_exception(*position.exc_info) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=position.value, w_value=position.w_value, quality=quality, priority=0, timestamp=position.timestamp) def write_Position(self, attr): self.in_write_position = True position = attr.get_write_value() try: self.info("write_Position(%s)", position) try: self.wait_for_operation() except: raise Exception("Cannot move: already in motion") try: self.motor.position = position except PoolException, pe: throw_sardana_exception(pe) # manually store write dial position in the database self.set_write_dial_position_to_db() finally: self.in_write_position = False def read_Acceleration(self, attr): attr.set_value(self.motor.get_acceleration(cache=False)) @memorize_write_attribute def write_Acceleration(self, attr): self.motor.acceleration = attr.get_write_value() def read_Deceleration(self, attr): attr.set_value(self.motor.get_deceleration(cache=False)) @memorize_write_attribute def write_Deceleration(self, attr): self.motor.deceleration = attr.get_write_value() def read_Base_rate(self, attr): attr.set_value(self.motor.get_base_rate(cache=False)) @memorize_write_attribute def write_Base_rate(self, attr): self.motor.base_rate = attr.get_write_value() def read_Velocity(self, attr): attr.set_value(self.motor.get_velocity(cache=False)) @memorize_write_attribute def write_Velocity(self, attr): self.motor.velocity = attr.get_write_value() def read_Offset(self, attr): attr.set_value(self.motor.get_offset(cache=False).value) @memorize_write_attribute def write_Offset(self, attr): self.motor.offset = attr.get_write_value() def read_DialPosition(self, attr): motor = self.motor use_cache = motor.is_in_operation() and not self.Force_HW_Read state = motor.get_state(cache=use_cache, propagate=0) dial_position = motor.get_dial_position(cache=use_cache, propagate=0) if dial_position.error: Except.throw_python_exception(*dial_position.exc_info) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=dial_position.value, quality=quality, priority=0, timestamp=dial_position.timestamp) def read_Step_per_unit(self, attr): attr.set_value(self.motor.get_step_per_unit(cache=False)) @memorize_write_attribute def write_Step_per_unit(self, attr): step_per_unit = attr.get_write_value() self.motor.step_per_unit = step_per_unit def read_Backlash(self, attr): attr.set_value(self.motor.get_backlash(cache=False)) @memorize_write_attribute def write_Backlash(self, attr): self.motor.backlash = attr.get_write_value() def read_Sign(self, attr): sign = self.motor.get_sign(cache=False).value attr.set_value(sign) @memorize_write_attribute def write_Sign(self, attr): self.motor.sign = attr.get_write_value() def read_Limit_switches(self, attr): motor = self.motor use_cache = motor.is_in_operation() and not self.Force_HW_Read limit_switches = motor.get_limit_switches(cache=use_cache) self.set_attribute(attr, value=limit_switches.value, priority=0, timestamp=limit_switches.timestamp) def DefinePosition(self, argin): self.motor.define_position(argin) # update write value of position attribute pos_attr = self.get_wattribute_by_name("position") pos_attr.set_write_value(argin) def is_DefinePosition_allowed(self): if self.get_state() in (DevState.FAULT, DevState.MOVING, DevState.UNKNOWN): return False return True def SaveConfig(self): raise NotImplementedError def is_SaveConfig_allowed(self): if self.get_state() in (DevState.FAULT, DevState.MOVING, DevState.UNKNOWN): return False return True def MoveRelative(self, argin): raise NotImplementedError def is_MoveRelative_allowed(self): if self.get_state() in (DevState.FAULT, DevState.MOVING, DevState.UNKNOWN): return False return True def get_attributes_to_restore(self): """Make sure position is the last attribute to restore""" restore_attributes = PoolElementDevice.get_attributes_to_restore(self) try: restore_attributes.remove('Position') restore_attributes.append('Position') except ValueError: pass return restore_attributes is_Position_allowed = _is_allowed is_Acceleration_allowed = _is_allowed is_Deceleration_allowed = _is_allowed is_Base_rate_allowed = _is_allowed is_Velocity_allowed = _is_allowed is_Offset_allowed = _is_allowed is_DialPosition_allowed = _is_allowed is_Step_per_unit_allowed = _is_allowed is_Backlash_allowed = _is_allowed is_Sign_allowed = _is_allowed is_Limit_switches_allowed = _is_allowed class MotorClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { 'Sleep_bef_last_read' : [DevLong, "Number of mS to sleep before the last read during a motor " "movement", 0], '_Acceleration' : [DevDouble, "", -1], '_Deceleration' : [DevDouble, "", -1], '_Velocity' : [DevDouble, "", -1], '_Base_rate' : [DevDouble, "", -1], } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'DefinePosition' : [ [DevDouble, "New position"], [DevVoid, ""] ], 'SaveConfig' : [ [DevVoid, ""], [DevVoid, ""] ], 'MoveRelative' : [ [DevDouble, "amount to move"], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = {} attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { 'Position' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'abs_change' : '1.0', } ], 'Acceleration' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'Memorized' : "true", } ], 'Deceleration' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'Memorized' : "true", } ], 'Base_rate' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'Memorized' : "true", 'label' : 'Base rate', } ], 'Velocity' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'Memorized' : "true", } ], 'Offset' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'Memorized' : "true", 'Display level' : DispLevel.EXPERT } ], 'DialPosition' : [ [ DevDouble, SCALAR, READ ], { 'label' : "Dial position", 'Display level' : DispLevel.EXPERT } ], 'Step_per_unit': [ [ DevDouble, SCALAR, READ_WRITE], { 'Memorized' : "true", 'label' : "Steps p/ unit", 'Display level' : DispLevel.EXPERT } ], 'Backlash' : [ [ DevLong, SCALAR, READ_WRITE], { 'Memorized' : "true", 'Display level' : DispLevel.EXPERT } ], 'Sign' : [ [ DevShort, SCALAR, READ_WRITE], { 'Memorized' : "true", 'Display level' : DispLevel.EXPERT } ], 'Limit_switches': [ [ DevBoolean, SPECTRUM, READ, 3], { 'label' : "Limit switches (H,U,L)", 'description' : "This attribute is the motor "\ "limit switches state. It's an array with 3 \n"\ "elements which are:\n"\ "0 - The home switch\n"\ "1 - The upper limit switch\n"\ "2 - The lower limit switch\n"\ "False means not active. True means active" } ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "Motor device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/MotorGroup.py0000644000234100017500000001764012174204312023504 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["MotorGroup", "MotorGroupClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import Except, DevState, DevDouble, AttrQuality, READ_WRITE, \ SPECTRUM from taurus.core.util.log import DebugIt from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool.poolexception import PoolException from sardana.tango.core.util import exception_str, throw_sardana_exception from PoolDevice import PoolGroupDevice, PoolGroupDeviceClass class MotorGroup(PoolGroupDevice): def __init__(self, dclass, name): self.in_write_position = False PoolGroupDevice.__init__(self, dclass, name) def init(self, name): PoolGroupDevice.init(self, name) def _is_allowed(self, req_type): return PoolGroupDevice._is_allowed(self, req_type) def get_motor_group(self): return self.element def set_motor_group(self, motor_group): self.element = motor_group motor_group = property(get_motor_group, set_motor_group) @DebugIt() def delete_device(self): PoolGroupDevice.delete_device(self) motor_group = self.motor_group if motor_group is not None: motor_group.remove_listener(self.on_motor_group_changed) @DebugIt() def init_device(self): PoolGroupDevice.init_device(self) detect_evts = "position", non_detect_evts = "elementlist", self.set_change_events(detect_evts, non_detect_evts) self.Elements = map(int, self.Elements) motor_group = self.motor_group if motor_group is None: full_name = self.get_full_name() name = self.alias or full_name self.motor_group = motor_group = \ self.pool.create_motor_group(name=name, id=self.Id, full_name=full_name, user_elements=self.Elements) motor_group.add_listener(self.on_motor_group_changed) self.set_state(DevState.ON) def on_motor_group_changed(self, event_source, event_type, event_value): try: self._on_motor_group_changed(event_source, event_type, event_value) except: msg = 'Error occurred "on_motor_group_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.motor_group.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_motor_group_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() attr = self.get_attribute_by_name(name) quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp else: value = event_value state = self.motor_group.get_state(propagate=0) if name == "position": w_value = event_value.w_value if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): pass #state = to_tango_state(self.motor_group.get_state(cache=False)) def read_attr_hardware(self,data): pass def _to_motor_positions(self, pos): positions = [] for elem in self.motor_group.get_user_elements(): position = pos[elem] if position.in_error(): Except.throw_python_exception(*position.exc_info) positions.append(position.value) return positions def _to_motor_write_positions(self, pos): w_positions = [] for elem in self.motor_group.get_user_elements(): position = pos[elem] if position.in_error(): Except.throw_python_exception(*position.exc_info) w_positions.append(position.w_value) return w_positions def read_Position(self, attr): # if motors are moving their position is already being updated with a # high frequency so don't bother overloading and just get the cached # values motor_group = self.motor_group use_cache = motor_group.is_in_operation() and not self.Force_HW_Read position = motor_group.get_position(cache=use_cache, propagate=0) if position.error: Except.throw_python_exception(*position.exc_info) state = motor_group.get_state(cache=use_cache, propagate=0) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=position.value, w_value=position.w_value, quality=quality, priority=0, timestamp=position.timestamp) def write_Position(self, attr): self.in_write_position = True try: position = attr.get_write_value() self.debug("write_Position(%s)", position) try: self.wait_for_operation() except: raise Exception("Cannot move: already in motion") try: self.motor_group.position = position except PoolException, pe: throw_sardana_exception(pe) finally: self.in_write_position = False is_Position_allowed = _is_allowed class MotorGroupClass(PoolGroupDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { } device_property_list.update(PoolGroupDeviceClass.device_property_list) # Command definitions cmd_list = { } cmd_list.update(PoolGroupDeviceClass.cmd_list) # Attribute definitions attr_list = { 'Position' : [ [ DevDouble, SPECTRUM, READ_WRITE, 4096 ], ], } attr_list.update(PoolGroupDeviceClass.attr_list) def _get_class_properties(self): ret = PoolGroupDeviceClass._get_class_properties(self) ret['Description'] = "Motor group device class" ret['InheritedFrom'].insert(0, 'PoolGroupDevice') return ret sardana-1.2.0/src/sardana/tango/pool/OneDExpChannel.py0000644000234100017500000001752512174204312024164 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["OneDExpChannel", "OneDExpChannelClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import DevFailed, DevVoid, DevString, DevState, AttrQuality, \ Except, READ, SCALAR from taurus.core.util.log import DebugIt from sardana import State, DataFormat, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool.controller import OneDController, MaxDimSize, Type from sardana.tango.core.util import to_tango_type_format, exception_str from PoolDevice import PoolElementDevice, PoolElementDeviceClass class OneDExpChannel(PoolElementDevice): def __init__(self, dclass, name): PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def get_oned(self): return self.element def set_oned(self, oned): self.element = oned oned = property(get_oned, set_oned) @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) oned = self.oned if oned is not None: oned.remove_listener(self.on_oned_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) oned = self.oned if oned is None: full_name = self.get_full_name() name = self.alias or full_name self.oned = oned = \ self.pool.create_element(type="OneDExpChannel", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id) if self.instrument is not None: oned.set_instrument(self.instrument) oned.add_listener(self.on_oned_changed) ## force a state read to initialize the state attribute #state = ct.state self.set_state(DevState.ON) def on_oned_changed(self, event_source, event_type, event_value): try: self._on_oned_changed(event_source, event_type, event_value) except not DevFailed: msg = 'Error occurred "on_oned_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.motor.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_oned_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() try: attr = self.get_attribute_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp if name == "value": state = self.oned.get_state() if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.oned.get_state(cache=False)) pass def read_attr_hardware(self,data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For value attribute, listen to what the controller says for data # type (between long and float) and length value = std_attrs.get('value') if value is not None: _, data_info, attr_info = value ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype shape = attr_info.maxdimsize data_info[0][3] = shape[0] return std_attrs, dyn_attrs def read_Value(self, attr): oned = self.oned use_cache = oned.is_in_operation() and not self.Force_HW_Read value = oned.get_value(cache=use_cache, propagate=0) if value.error: Except.throw_python_exception(*value.exc_info) state = oned.get_state(cache=use_cache, propagate=0) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value.value, quality=quality, timestamp=value.timestamp, priority=0) def is_Value_allowed(self, req_type): if self.get_state() in [DevState.FAULT, DevState.UNKNOWN]: return False return True def read_DataSource(self, attr): data_source = self.oned.get_data_source() if data_source is None: data_source = "tango://{0}/value".format(self.get_full_name()) attr.set_value(data_source) def Start(self): self.oned.start_acquisition() _DFT_VALUE_INFO = OneDController.standard_axis_attributes['Value'] _DFT_VALUE_MAX_SHAPE = _DFT_VALUE_INFO[MaxDimSize] _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format(_DFT_VALUE_INFO[Type], DataFormat.OneD) class OneDExpChannelClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = { 'DataSource' : [ [ DevString, SCALAR, READ ] ], } attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { 'Value' : [ [ _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT, READ, _DFT_VALUE_MAX_SHAPE[0] ], { 'abs_change' : '1.0', } ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "1D device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/Pool.py0000755000234100017500000015162212174204312022302 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["Pool", "PoolClass"] __docformat__ = 'restructuredtext' import json import operator import os.path import PyTango from taurus import Factory from taurus.core.util import CaselessDict, CodecFactory from taurus.core.util.log import Logger, DebugIt from sardana import State, SardanaServer, ElementType, Interface, \ TYPE_ACQUIRABLE_ELEMENTS, TYPE_PSEUDO_ELEMENTS from sardana.pool.pool import Pool as POOL from sardana.pool.poolmetacontroller import TYPE_MAP_OBJ from sardana.tango.core.util import get_tango_version_number class Pool(PyTango.Device_4Impl, Logger): ElementsCache = None def __init__(self,cl, name): PyTango.Device_4Impl.__init__(self,cl,name) Logger.__init__(self, name) self.init(name) self.init_device() def init(self, full_name): try: db = Factory().getDatabase() alias = db.get_alias(full_name) if alias.lower() == 'nada': alias = None except: alias = None if alias is None: alias = PyTango.Util.instance().get_ds_inst_name() self._pool = POOL(self.get_full_name(), alias) self._pool.add_listener(self.on_pool_changed) def get_full_name(self): db = PyTango.Util.instance().get_database() db_name = db.get_db_host() + ":" + db.get_db_port() return db_name + "/" + self.get_name() @property def pool(self): return self._pool @DebugIt() def delete_device(self): #self.pool.monitor.pause() pass @DebugIt() def init_device(self): self.set_state(PyTango.DevState.INIT) self.get_device_properties(self.get_device_class()) p = self.pool p.set_python_path(self.PythonPath) p.set_path(self.PoolPath) p.set_motion_loop_sleep_time(self.MotionLoop_SleepTime / 1000.0) p.set_motion_loop_states_per_position(self.MotionLoop_StatesPerPosition) p.set_acq_loop_sleep_time(self.AcqLoop_SleepTime / 1000.0) p.set_acq_loop_states_per_value(self.AcqLoop_StatesPerValue) p.set_drift_correction(self.DriftCorrection) if self.RemoteLog is None: p.clear_remote_logging() else: try: h_p = self.RemoteLog.split(":",1) if len(h_p) == 1: host = h_p[0] port = None else: host, port = h_p port = int(port) p.init_remote_logging(host=host, port=port) except: self.warning("Invalid property value for 'RemoteLog': %s", self.RemoteLog) p.clear_remote_logging() self._recalculate_instruments() for attr in self.get_device_class().attr_list: if attr.lower().endswith("list"): self.set_change_event(attr, True, False) self.set_change_event("State", True, False) self.set_change_event("Status", True, False) self.set_change_event("Elements", True, False) #hold the monitor thread for now! #self.pool.monitor.resume() self.set_state(PyTango.DevState.ON) def _recalculate_instruments(self): il = self.InstrumentList = list(self.InstrumentList) p = self.pool instruments = p.get_element_type_map().get(ElementType.Instrument, {}) ids = set() for i in range(0, len(il), 3): iklass, iname, iid = il[i:i+3] iid = int(iid) ids.add(iid) if iid in instruments: #TODO make sure the instrument didn't change pass else: p.create_instrument(iname, iklass, id=iid) #@DebugIt() def always_executed_hook(self): pass #@DebugIt() def read_attr_hardware(self,data): pass #@DebugIt() def read_ControllerLibList(self, attr): info = self.pool.get_elements_str_info(ElementType.ControllerLibrary) attr.set_value(info) #@DebugIt() def read_ControllerClassList(self, attr): info = self.pool.get_elements_str_info(ElementType.ControllerClass) attr.set_value(info) #@PyTango.DebugIt(show_args=True,show_ret=True) def read_ControllerList(self, attr): info = self.pool.get_elements_str_info(ElementType.Controller) attr.set_value(info) def read_InstrumentList(self, attr): #instruments = self._pool.get_elements_by_type(ElementType.Instrument) #instrument_names = map(PoolInstrument.get_full_name, instruments) #attr.set_value(instrument_names) info = self.pool.get_elements_str_info(ElementType.Instrument) attr.set_value(info) #@DebugIt() def read_ExpChannelList(self, attr): info = [] info.extend(self.pool.get_elements_str_info(ElementType.CTExpChannel)) info.extend(self.pool.get_elements_str_info(ElementType.ZeroDExpChannel)) info.extend(self.pool.get_elements_str_info(ElementType.OneDExpChannel)) info.extend(self.pool.get_elements_str_info(ElementType.TwoDExpChannel)) info.extend(self.pool.get_elements_str_info(ElementType.PseudoCounter)) attr.set_value(info) #@DebugIt() def read_AcqChannelList(self, attr): info = self.pool.get_acquisition_elements_str_info() attr.set_value(info) #@DebugIt() def read_MotorGroupList(self, attr): info = self.pool.get_elements_str_info(ElementType.MotorGroup) attr.set_value(info) #@DebugIt() def read_MotorList(self, attr): info = self.pool.get_elements_str_info(ElementType.Motor) info.extend(self.pool.get_elements_str_info(ElementType.PseudoMotor)) attr.set_value(info) #@DebugIt() def read_MeasurementGroupList(self, attr): info = self.pool.get_elements_str_info(ElementType.MeasurementGroup) attr.set_value(info) #@DebugIt() def read_IORegisterList(self, attr): info = self.pool.get_elements_str_info(ElementType.IORegister) attr.set_value(info) #@DebugIt() def read_ComChannelList(self, attr): info = self.pool.get_elements_str_info(ElementType.Communication) attr.set_value(info) #@DebugIt() def getElements(self, cache=True): value = self.ElementsCache if cache and value is not None: return value value = dict(new=self.pool.get_elements_info()) value = CodecFactory().encode('json', ('', value)) self.ElementsCache = value return value #@DebugIt() def read_Elements(self, attr): element_list = self.getElements() attr.set_value(*element_list) def is_Elements_allowed(self, req_type): return True return SardanaServer.server_state == State.Running is_ControllerLibList_allowed = \ is_ControllerClassList_allowed = \ is_ControllerList_allowed = \ is_InstrumentList_allowed = \ is_ExpChannelList_allowed = \ is_AcqChannelList_allowed = \ is_MotorGroupList_allowed = \ is_MotorList_allowed = \ is_MeasurementGroupList_allowed = \ is_IORegisterList_allowed = \ is_ComChannelList_allowed = is_Elements_allowed def _get_interface_ids(self, interface, elem_names): _pool, motor_ids = self.pool, [] for elem_name in elem_names: try: element = _pool.get_element_by_name(elem_name) except: element = _pool.get_element_by_full_name(elem_name) elem_interface = element.get_interface() if not Interface.Moveable & elem_interface: raise Exception("%s is a %s. It MUST be a moveable" % (element.name, Interface[elem_interface])) motor_ids.append(element.id) return motor_ids def _get_moveable_ids(self, elem_names): return self._get_interface_ids(Interface.Moveable, elem_names) def _get_acquirable_ids(self, elem_names): return self._get_interface_ids(Interface.Acquirable, elem_names) #@DebugIt() def CreateController(self, argin): kwargs = self._format_CreateController_arguments(argin) # TODO: Support in future sequence of elements kwargs = kwargs[0] type_str = kwargs['type'] lib = kwargs['library'] class_name = kwargs['klass'] name = kwargs['name'] properties = kwargs['properties'] elem_type = ElementType[type_str] mod_name, _ = os.path.splitext(lib) kwargs['module'] = mod_name td = TYPE_MAP_OBJ[ElementType.Controller] auto_full_name = td.auto_full_name ctrl_class = td.ctrl_klass full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) util = PyTango.Util.instance() # check that element doesn't exist yet self._check_element(name, full_name) # check library exists ctrl_manager = self.pool.ctrl_manager mod_name, _ = os.path.splitext(lib) ctrl_lib = ctrl_manager.getControllerLib(mod_name) if ctrl_lib is None: raise Exception("Controller library '%s' not found" % lib) # check class exists ctrl_class = ctrl_lib.get_controller(class_name) if ctrl_class is None: raise Exception("Controller class '%s' not found in '%s'" % (class_name, lib)) # check that class type matches the required type if not elem_type in ctrl_class.types: raise Exception("Controller class '%s' does not implement '%s' " "interface" % (class_name, type_str)) # check that necessary property values are set for prop_name, prop_info in ctrl_class.ctrl_properties.items(): prop_value = properties.get(prop_name) if prop_value is None: if prop_info.default_value is None: raise Exception("Controller class '%s' needs property '%s'" % (class_name, prop_name)) properties[prop_name] = prop_info.default_value else: properties[prop_name] = prop_value # for pseudo motor check that motors are given if elem_type == ElementType.PseudoMotor: klass_roles = ctrl_class.controller_class.motor_roles klass_pseudo_roles = ctrl_class.controller_class.pseudo_motor_roles if not len(klass_pseudo_roles): klass_pseudo_roles = class_name, roles = kwargs.get('roles') if roles is None: raise Exception("Pseudo motor controller class %s needs motors " "for roles: %s and pseudo roles: %s" % (class_name, ", ".join(klass_roles), ", ".join(klass_pseudo_roles))) motor_ids = [] for klass_role in klass_roles: if not klass_role in roles: raise Exception("Pseudo motor controller class '%s' needs " "motor(s) for role(s) %s" % (class_name, klass_role)) motor_name = roles[klass_role] motor_ids.extend(self._get_moveable_ids((motor_name,))) properties['motor_role_ids'] = motor_ids pseudo_motor_infos = {} pseudo_motor_ids = [] for i, klass_pseudo_role in enumerate(klass_pseudo_roles): if not klass_pseudo_role in roles: raise Exception("Pseudo motor controller class '%s' needs " "pseudo motor name for role '%s'" % (class_name, klass_pseudo_role)) pm_id = self.pool.get_new_id() pm_name = roles[klass_pseudo_role] info = dict(id=pm_id, name=pm_name, ctrl_name=name, axis=i+1, type='PseudoMotor', elements=motor_ids) if pm_name.count(',') > 0: n, fn = map(str.strip, pm_name.split(',', 1)) info['name'], info['full_name'] = n, fn pseudo_motor_infos[klass_pseudo_role] = info pseudo_motor_ids.append(pm_id) properties['pseudo_motor_role_ids'] = pseudo_motor_ids # for pseudo counter check counters are given elif elem_type == ElementType.PseudoCounter: klass_roles = ctrl_class.controller_class.counter_roles klass_pseudo_roles = ctrl_class.controller_class.pseudo_counter_roles if not len(klass_pseudo_roles): klass_pseudo_roles = class_name, roles = kwargs.get('roles') if roles is None: raise Exception("Pseudo counter controller class '%s' needs " "counter(s) for role(s): %s and pseudo " "role(s): %s" % (class_name, ", ".join(klass_roles), ", ".join(klass_pseudo_roles))) counter_ids = [] for klass_role in klass_roles: if not klass_role in roles: raise Exception("Pseudo counter controller class '%s' " "needs counter name for role '%s'" % (class_name, klass_role)) counter_name = roles[klass_role] counter_ids.extend(self._get_acquirable_ids((counter_name,))) properties['counter_role_ids'] = counter_ids pseudo_counter_infos = {} pseudo_counter_ids = [] for i, klass_pseudo_role in enumerate(klass_pseudo_roles): if not klass_pseudo_role in roles: raise Exception("Pseudo counter controller class %s needs " "pseudo motor name for role %s" % (class_name, klass_pseudo_role)) pc_id = self.pool.get_new_id() pc_name = roles[klass_pseudo_role] info = dict(id=pc_id, name=pc_name, ctrl_name=name, axis=i+1, type='PseudoCounter', elements=counter_ids) if pc_name.count(',') > 0: n, fn = map(str.strip, pc_name.split(',', 1)) info['name'], info['full_name'] = n, fn pseudo_counter_infos[klass_pseudo_role] = info pseudo_counter_ids.append(pc_id) properties['pseudo_counter_role_ids'] = pseudo_counter_ids properties['type'] = type_str properties['library'] = lib properties['klass'] = class_name def create_controller_cb(device_name): try: db = util.get_database() #types = [ pool.ElementType.whatis(t) for t in ctrl.get_ctrl_types() ] properties['id'] = self.pool.get_new_id() db.put_device_property(device_name, properties) except: self.warning("Unexpected error in controller creation callback", exc_info=True) raise util.create_device('Controller', full_name, name, cb=create_controller_cb) # Determine which controller writtable attributes have default value # and apply them to the newly created controller attrs = [] for attr_name, attr_info in ctrl_class.ctrl_attributes.items(): default_value = attr_info.default_value if default_value is None: continue attrs.append((attr_name, default_value)) if attrs: ctrl_proxy = PyTango.DeviceProxy(full_name) try: ctrl_proxy.write_attributes(attrs) except: self.warning("Error trying to write controller default value " "for attribute(s)", exc_info=1) # for pseudo motor/counter controller also create pseudo # motor(s)/counter(s) automatically if elem_type == ElementType.PseudoMotor: for pseudo_motor_info in pseudo_motor_infos.values(): self._create_single_element(pseudo_motor_info) elif elem_type == ElementType.PseudoCounter: for pseudo_counter_info in pseudo_counter_infos.values(): self._create_single_element(pseudo_counter_info) #@DebugIt() def CreateInstrument(self, argin): instrument = self.pool.create_instrument(*argin) instrument_list = self.InstrumentList # update database property instrument_list.append(instrument.instrument_class) instrument_list.append(instrument.full_name) instrument_list.append(instrument.id) db = PyTango.Util.instance().get_database() props = { 'InstrumentList' : instrument_list } db.put_device_property(self.get_name(), props) #@DebugIt() def CreateElement(self, argin): kwargs_seq = self._format_CreateElement_arguments(argin) for kwargs in kwargs_seq: self._create_single_element(kwargs) def _create_single_element(self, kwargs): elem_type_str = kwargs['type'] ctrl_name = kwargs['ctrl_name'] axis = kwargs['axis'] try: elem_type = ElementType[elem_type_str] except KeyError: raise Exception("Unknown element type '%s'" % elem_type_str) name = kwargs['name'] td = TYPE_MAP_OBJ[elem_type] auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) ctrl = self.pool.get_element(name=ctrl_name) if ctrl.get_type() != ElementType.Controller: type_str = ElementType.whatis(ctrl.get_type()) raise Exception("'%s' is not a controller (It is a %s)" % (ctrl_name, type_str)) ctrl_types = ctrl.get_ctrl_types() if elem_type not in ctrl_types: ctrl_type_str = ElementType.whatis(ctrl_types[0]) raise Exception("Cannot create %s in %s controller" % (type, ctrl_type_str)) elem_axis = ctrl.get_element(axis=axis) if elem_axis is not None: raise Exception("Controller already contains axis %d (%s)" % (axis, elem_axis.get_name())) self._check_element(name, full_name) util = PyTango.Util.instance() def create_element_cb(device_name): try: db = util.get_database() data = { "id" : self.pool.get_new_id(), "ctrl_id" : ctrl.get_id(), "axis" : axis, } if elem_type in TYPE_PSEUDO_ELEMENTS: data['elements'] = kwargs['elements'] db.put_device_property(device_name, data) data = {} if elem_type == ElementType.Motor: data["position"] = { "abs_change" : "1.0"} data["dialposition"] = { "abs_change" : "5.0"} if get_tango_version_number() < 80000: print 20*"AH! " data["limit_switches"] = { "abs_change" : "1.0"} elif elem_type == ElementType.CTExpChannel: data["value"] = { "abs_change" : "1.0"} elif elem_type == ElementType.PseudoMotor: data["position"] = { "abs_change" : "1.0"} elif elem_type == ElementType.PseudoCounter: data["value"] = { "abs_change" : "1.0"} elif elem_type == ElementType.IORegister: data["value"] = { "abs_change" : "1"} db.put_device_attribute_property(device_name, data) except: import traceback traceback.print_exc() util.create_device(elem_type_str, full_name, name, cb=create_element_cb) # Hack to register event abs change until tango bug #3151801 is solved elem_proxy = PyTango.DeviceProxy(full_name) cfg = [] if elem_type == ElementType.Motor: attr = elem_proxy.get_attribute_config_ex("position")[0] attr.events.ch_event.abs_change = "1" cfg.append(attr) try: attr = elem_proxy.get_attribute_config_ex("dialposition")[0] attr.events.ch_event.abs_change = "5.0" cfg.append(attr) except: pass try: if get_tango_version_number() < 80000: attr = elem_proxy.get_attribute_config_ex("limit_switches")[0] attr.events.ch_event.abs_change = "1" cfg.append(attr) except: pass elif elem_type == ElementType.CTExpChannel: attr = elem_proxy.get_attribute_config_ex("value")[0] attr.events.ch_event.abs_change = "1.0" cfg.append(attr) elif elem_type == ElementType.ZeroDExpChannel: attr = elem_proxy.get_attribute_config_ex("value")[0] attr.events.ch_event.abs_change = "1.0" cfg.append(attr) elif elem_type == ElementType.PseudoMotor: attr = elem_proxy.get_attribute_config_ex("position")[0] attr.events.ch_event.abs_change = "1" cfg.append(attr) elif elem_type == ElementType.PseudoCounter: attr = elem_proxy.get_attribute_config_ex("value")[0] attr.events.ch_event.abs_change = "1" cfg.append(attr) elif elem_type == ElementType.IORegister: attr = elem_proxy.get_attribute_config_ex("value")[0] attr.events.ch_event.abs_change = "1" cfg.append(attr) elem_proxy.set_attribute_config(cfg) return # Determine which writtable attributes have default value and apply # them to the newly created element ctrl_class_info = ctrl.get_ctrl_info() attrs = [] for attr_name, attr_info in ctrl_class_info.getAxisAttributes().items(): default_value = attr_info.default_value if default_value is None: continue attrs.append((attr_name, default_value)) if attrs: elem_proxy = PyTango.DeviceProxy(full_name) try: elem_proxy.write_attributes(attrs) except: self.warning("Error trying to write default value for " "attribute(s)", exc_info=1) #@DebugIt() def CreateMotorGroup(self, argin): kwargs = self._format_CreateMotorGroup_arguments(argin) # TODO: Support in future sequence of elements kwargs = kwargs[0] util = PyTango.Util.instance() name = kwargs['name'] kwargs['pool_name'] = self.pool.name td = TYPE_MAP_OBJ[ElementType.MotorGroup] auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) self._check_element(name, full_name) elem_ids = self._get_moveable_ids(kwargs["elements"]) def create_motgrp_cb(device_name): db = util.get_database() data = { "id" : self.pool.get_new_id(), "elements" : elem_ids } db.put_device_property(device_name, data) data = {} data["position"] = { "abs_change" : "1.0" } db.put_device_attribute_property(device_name, data) util.create_device("MotorGroup", full_name, name, cb=create_motgrp_cb) #@DebugIt() def CreateMeasurementGroup(self, argin): kwargs = self._format_CreateMeasurementGroup_arguments(argin) # TODO: Support in future sequence of elements kwargs = kwargs[0] util = PyTango.Util.instance() name = kwargs['name'] kwargs['pool_name'] = self.pool.name td = TYPE_MAP_OBJ[ElementType.MeasurementGroup] auto_full_name = td.auto_full_name full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) self._check_element(name, full_name) elem_ids = [] for elem_name in kwargs["elements"]: # if internal pool element (channel, motor, ioregister, etc) store # it's id try: elem = self.pool.get_element(name=elem_name) elem_ids.append(elem.id) except: # otherwise assume a tango attribute/command elem_ids.append(elem_name) def create_mntgrp_cb(device_name): db = util.get_database() data = { "id" : self.pool.get_new_id(), "elements" : elem_ids } db.put_device_property(device_name, data) data = { } db.put_device_attribute_property(device_name, data) util.create_device("MeasurementGroup", full_name, name, cb=create_mntgrp_cb) def _check_element(self, name, full_name): self.pool.check_element(name, full_name) db = PyTango.Util.instance().get_database() e = None try: db.import_device(name) e = Exception("The tango alias '%s' already exists" % name) except: pass if e: raise e try: db.import_device(full_name) e = Exception("The tango device '%s' already exists" % full_name) except: pass if e: raise e def on_pool_changed(self, evt_src, evt_type, evt_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return evt_name = evt_type.name.lower() if evt_name in ("elementcreated", "elementdeleted"): elem = evt_value elem_type = elem.get_type() td = TYPE_MAP_OBJ[elem_type] attribute_list_name = td.family + "List" info = self.pool.get_elements_str_info(elem_type) self.push_change_event(attribute_list_name, info) if elem_type in TYPE_ACQUIRABLE_ELEMENTS: info = self.pool.get_acquisition_elements_str_info() self.push_change_event('AcqChannelList', info) # force the element list cache to be rebuild next time someone reads # the element list self.ElementsCache = None value = { } if "created" in evt_name: key = 'new' else: key = 'del' json_elem = elem.serialize(pool=self.pool.full_name) value[key] = json_elem, value = CodecFactory().getCodec('json').encode(('', value)) self.push_change_event('Elements', *value) elif evt_name == "elementschanged": # force the element list cache to be rebuild next time someone reads # the element list self.ElementsCache = None pool_name = self.pool.full_name new_values, changed_values, deleted_values = [], [], [] for elem in evt_value['new']: json_elem = elem.serialize(pool=pool_name) new_values.append(json_elem) for elem in evt_value['change']: json_elem = elem.serialize(pool=pool_name) changed_values.append(json_elem) for elem in evt_value['del']: json_elem = elem.serialize(pool=pool_name) deleted_values.append(json_elem) value = { "new" : new_values, "change": changed_values, "del" : deleted_values } value = CodecFactory().getCodec('json').encode(('', value)) self.push_change_event('Elements', *value) def _format_create_json_arguments(self, argin): elems, ret = json.loads(argin[0]), [] if operator.isMappingType(elems): elems = [elems] for elem in elems: d = {} for k,v in elem.items(): d[str(k)] = str(v) ret.append(d) return ret def _format_CreateElement_arguments(self, argin): if len(argin) == 0: msg = PoolClass.cmd_list["CreateElement"][0][1] raise Exception(msg) if len(argin) == 1: return self._format_create_json_arguments(argin) ret = { 'type' : argin[0], 'ctrl_name' : argin[1], 'axis': int(argin[2]), 'name' : argin[3] } if len(argin) > 4: ret['full_name'] = argin[4] return [ret] def _format_CreateController_arguments(self, argin): if len(argin) == 0: msg = PoolClass.cmd_list["CreateController"][0][1] raise Exception(msg) if len(argin) == 1: ret = self._format_create_json_arguments(argin) if not ret.has_key('type'): raise KeyError("Missing key 'type'") if not ret.has_key('library'): raise KeyError("Missing key 'library'") if not ret.has_key('klass'): raise KeyError("Missing key 'klass'") if not ret.has_key('name'): raise KeyError("Missing key 'name'") if not ret.has_key('properties'): ret['properties'] = CaselessDict() return ret ret = { 'type' : argin[0], 'library' : argin[1], 'klass' : argin[2], 'name' : argin[3] } i = 4 roles = {} for arg in argin[4:]: role_data = arg.split('=', 1) if len(role_data) < 2: break role_name, role_element = role_data roles[role_name] = role_element i += 1 if len(roles) > 0: ret['roles'] = roles p = argin[i:] if len(p) % 2: raise Exception("must give pair of property name, property value") props = CaselessDict() for name, value in zip(p[0::2], p[1::2]): props[name] = value ret['properties'] = props return [ret] def _format_CreateMotorGroup_arguments(self, argin): if len(argin) == 0: msg = PoolClass.cmd_list["CreateMotorGroup"][0][1] raise Exception(msg) if len(argin) == 1: ret = [] try: elems = json.loads(argin[0]) except: elems = argin if operator.isMappingType(elems): elems = [elems] for elem in elems: d = {} for k,v in elem.items(): d[str(k)] = str(v) ret.append(d) return ret ret = { 'name' : argin[0] } if argin[-1].count('/') == 2: ret['full_name'] = argin[-1] del argin[-1] ret['elements'] = argin[1:] return [ret] def _format_CreateMeasurementGroup_arguments(self, argin): if len(argin) == 0: msg = PoolClass.cmd_list["CreateMeasurementGroup"][0][1] raise Exception(msg) if len(argin) == 1: ret = [] try: elems = json.loads(argin[0]) except: elems = argin if operator.isMappingType(elems): elems = [elems] for elem in elems: d = {} for k,v in elem.items(): d[str(k)] = str(v) ret.append(d) return ret ret = { 'name' : argin[0] } #if argin[-1].count('/') == 2: # ret['full_name'] = argin[-1] # del argin[-1] channels = [] for arg in argin[1:]: try: channel = self.pool.get_element_by_full_name(arg) channels.append(channel.name) except: try: channel = self.pool.get_element_by_name(arg) channels.append(channel.name) except: channels.append(arg) ret['elements'] = channels return [ret] #@DebugIt() def DeleteElement(self, name): try: elem = self.pool.get_element(full_name=name) except: elem = self.pool.get_element(name=name) elem_type = elem.get_type() if elem_type == ElementType.Controller: if len(elem.get_elements()) > 0: raise Exception("Cannot delete controller with elements. " \ "Delete elements first") td = TYPE_MAP_OBJ[elem_type] type_name = td.name full_name = elem.get_full_name() self.pool.delete_element(name) if elem_type == ElementType.Instrument: # update database property il = self.InstrumentList idx = il.index(full_name) self.InstrumentList = il[:idx-1] + il[idx+2:] db = PyTango.Util.instance().get_database() props = { 'InstrumentList' : self.InstrumentList } db.put_device_property(self.get_name(), props) else: util = PyTango.Util.instance() util.delete_device(type_name, full_name) #@DebugIt() def GetControllerClassInfo(self, names): if names.startswith('['): names = json.loads(names) else: names = (names,) ctrl_classes = self.pool.get_controller_classes_info(names) ret = [] for name in names: ctrl_class = ctrl_classes[name] data = None if ctrl_class is not None: data = ctrl_class.toDict() ret.append(data) return json.dumps(ret) #@DebugIt() def ReloadControllerLib(self, lib_name): self.pool.reload_controller_lib(lib_name) #@DebugIt() def ReloadControllerClass(self, class_name): self.pool.reload_controller_class(class_name) def Stop(self): self.pool.stop() def Abort(self): self.pool.abort() def SendToController(self, stream): ctrl_name, stream = stream[:2] try: ctrl = self.pool.get_element_by_name(ctrl_name) except KeyError: ctrl = self.pool.get_element_by_full_name(ctrl_name) return ctrl.send_to_controller(stream) def GetFile(self, name): p = self.pool manager = p.ctrl_manager lib = manager.getControllerLib(name) if lib is None: raise Exception("Unknown controller file '%s'", name) return lib.f_path, "".join(lib.getCode()) def PutFile(self, file_data): p = self.pool manager = p.ctrl_manager manager.setControllerLib(*file_data) def GetControllerCode(self, argin): pass def SetControllerCode(self, argin): pass CREATE_CONTROLLER_PAR_IN_DOC = """\ Must give either: * A JSON encoded dict as first string with: * mandatory keys: 'type', 'library', 'klass' and 'name' (values are strings). * optional keys: * 'properties': a dict with keys being property names and values the property values * 'roles': a dict with keys being controller roles and values being element names. (example: { 'gap' : 'motor21', 'offset' : 'motor55' }). Only applicable of pseudo controllers * a sequence of strings: , , , [, '='] [, , ] Examples:: data = dict(type='Motor', library='DummyMotorController', klass='DummyMotorController', name='my_motor_ctrl_1') pool.CreateController([json.dumps(data)]) pool.CreateController(['Motor', 'DummyMotorController', 'DummyMotorController', 'my_motor_ctrl_2']) """ CREATE_CONTROLLER_PAR_OUT_DOC = "None" CREATE_CONTROLLER_DOC = """\ Tango command to create controller. :param argin: {0} :type argin: list :return: {1} """.format(CREATE_CONTROLLER_PAR_IN_DOC, CREATE_CONTROLLER_PAR_OUT_DOC) CREATE_ELEMENT_PAR_IN_DOC = """\ Must give either: * A JSON encoded dict as first string with: * mandatory keys: 'type', 'ctrl_name', 'axis', 'name' (values are strings). * optional keys: * 'full_name' : a string representing the full tango device name * a sequence of strings: , , , [, ] Examples:: data = dict(type='Motor', ctrl_name='my_motor_ctrl_1', axis='4', name='theta', full_name='BL99/EH/THETA') pool.CreateElement([json.dumps(data)]) pool.CreateElement(['Motor', 'my_motor_ctrl_1', '1', 'phi', 'BL99/EH/PHI']) """ CREATE_ELEMENT_PAR_OUT_DOC = "None" CREATE_ELEMENT_DOC = """\ Tango command to create element (motor, counter/timer, 0D, 1D, 2D, IORegister). :param argin: {0} :type argin: list :return: {1} """.format(CREATE_ELEMENT_PAR_IN_DOC, CREATE_ELEMENT_PAR_OUT_DOC) CREATE_INSTRUMENT_PAR_IN_DOC = """\ Must give either: * A JSON encoded dict as first string with: * mandatory keys: 'full_name', 'klass' (values are strings). * a sequence of strings: , Examples:: pool.CreateInstrument(['/OH', 'NXhutch']) pool.CreateInstrument(['/OH/Mono', 'NXmonochromator']) pool.CreateInstrument(['/EH', 'NXhutch']) pool.CreateInstrument(['/EH/Pilatus', 'NXdetector']) """ CREATE_INSTRUMENT_PAR_OUT_DOC = "None" CREATE_INSTRUMENT_DOC = """\ Tango command to create instrument. :param argin: {0} :type argin: list :return: {1} """.format(CREATE_INSTRUMENT_PAR_IN_DOC, CREATE_INSTRUMENT_PAR_OUT_DOC) CREATE_MOTOR_GROUP_PAR_IN_DOC = """\ Must give either: * A JSON encoded dict as first string with: * mandatory keys: 'name', 'elements' (with value being a list of moveables) * optional keys: * 'full_name': with value being a full tango device name * a sequence of strings: [, ]" Examples:: data = dict(name='diffrac_motor_group', elements=['theta', 'theta2', 'phi']) pool.CreateMotorGroup([json.dumps(data)]) pool.CreateMotorGroup(['diffrac_mg', 'theta', 'theta2' ]) """ CREATE_MOTOR_GROUP_PAR_OUT_DOC = "None" CREATE_MOTOR_GROUP_DOC = """\ Tango command to create motor group. :param argin: {0} :type argin: list :return: {1} """.format(CREATE_MOTOR_GROUP_PAR_IN_DOC, CREATE_MOTOR_GROUP_PAR_OUT_DOC) Pool.CreateMotorGroup.__func__.__doc__= CREATE_MOTOR_GROUP_DOC CREATE_MEASUREMENT_GROUP_PAR_IN_DOC = """\ Must give either: * A JSON encoded dict as first string with: * mandatory keys: 'name', 'elements' (with value being a list of acquirables)" * optional keys: * 'full_name': with value being a full tango device name * a sequence of strings: [, ]" An acquirable is either a sardana element (counter/timer, 0D, 1D, 2D, motor) or a tango attribute (ex: sys/tg_test/1/short_spectrum_ro) Examples:: data = dict(name='my_exp_01', elements=['timer', 'C1', 'sys/tg_test/1/double_scalar']) pool.CreateMeasurementGroup([json.dumps(data)]) pool.CreateMeasurementGroup(['my_exp_02', 'timer', 'CCD1', 'sys/tg_test/1/short_spectrum_ro']) """ CREATE_MEASUREMENT_GROUP_PAR_OUT_DOC = "None" CREATE_MEASUREMENT_GROUP_DOC = """\ Tango command to create measurement group. :param argin: {0} :type argin: list :return: {1} """.format(CREATE_MEASUREMENT_GROUP_PAR_IN_DOC, CREATE_MEASUREMENT_GROUP_PAR_OUT_DOC) DELETE_ELEMENT_PAR_IN_DOC ="""\ name of element to be deleted """ DELETE_ELEMENT_PAR_OUT_DOC = "None" DELETE_ELEMENT_DOC = """\ Tango command to delete element. :param argin: {0} :type argin: str :return: {1} """.format(DELETE_ELEMENT_PAR_IN_DOC, DELETE_ELEMENT_PAR_OUT_DOC) GET_CONTROLLER_CLASS_INFO_PAR_IN_DOC = """\ Must give either: * A JSON encoded list of controller class names * a controller class name Examples:: data = "DummyMotorController", "DummyCounterTimerController" pool.GetControllerClassInfo(json.dumps(data)) pool.GetControllerClassInfo("DummyMotorController") """ GET_CONTROLLER_CLASS_INFO_PAR_OUT_DOC = """ a JSON encoded string describing the controller class """ GET_CONTROLLER_CLASS_INFO_DOC = """\ Tango command to get detailed information about a controller class. :param argin: {0} :type argin: str :return: {1} :rtype: str """.format(GET_CONTROLLER_CLASS_INFO_PAR_IN_DOC, GET_CONTROLLER_CLASS_INFO_PAR_OUT_DOC) RELOAD_CONTROLLER_LIB_PAR_IN_DOC = """\ the controller library name (without extension) """ RELOAD_CONTROLLER_LIB_PAR_OUT_DOC = "None" RELOAD_CONTROLLER_LIB_INFO_DOC = """\ Tango command to reload the controller library code. :param argin: {0} :type argin: str :return: {1} """.format(RELOAD_CONTROLLER_LIB_PAR_IN_DOC, RELOAD_CONTROLLER_LIB_PAR_OUT_DOC) RELOAD_CONTROLLER_CLASS_PAR_IN_DOC = """\ the controller class name """ RELOAD_CONTROLLER_CLASS_PAR_OUT_DOC = "None" RELOAD_CONTROLLER_CLASS_INFO_DOC = """\ Tango command to reload the controller class code (reloads the entire library where the class is described). :param argin: {0} :type argin: str :return: {1} """.format(RELOAD_CONTROLLER_CLASS_PAR_IN_DOC, RELOAD_CONTROLLER_CLASS_PAR_OUT_DOC) STOP_PAR_IN_DOC = "None" STOP_PAR_OUT_DOC = "None" STOP_DOC = """\ Stops all elements managed by this Pool :param argin: {0} :return: {1} """.format(STOP_PAR_IN_DOC, STOP_PAR_OUT_DOC) ABORT_PAR_IN_DOC = "None" ABORT_PAR_OUT_DOC = "None" ABORT_DOC = """\ Aborts all elements managed by this Pool :param argin: {0} :return: {1} """.format(ABORT_PAR_IN_DOC, ABORT_PAR_OUT_DOC) SEND_TO_CONTROLLER_PAR_IN_DOC = """\ a sequence of two strings: , """ SEND_TO_CONTROLLER_PAR_OUT_DOC = """\ the controller response """ SEND_TO_CONTROLLER_DOC = """\ Sends a string to a controller. :param argin: {0} :return: {1} """.format(SEND_TO_CONTROLLER_PAR_IN_DOC, SEND_TO_CONTROLLER_PAR_OUT_DOC) Pool.CreateController.__func__.__doc__= CREATE_CONTROLLER_DOC Pool.CreateElement.__func__.__doc__= CREATE_ELEMENT_DOC Pool.CreateInstrument.__func__.__doc__= CREATE_INSTRUMENT_DOC Pool.CreateMotorGroup.__func__.__doc__= CREATE_MOTOR_GROUP_DOC Pool.CreateMeasurementGroup.__func__.__doc__= CREATE_MEASUREMENT_GROUP_DOC Pool.DeleteElement.__func__.__doc__= DELETE_ELEMENT_DOC Pool.GetControllerClassInfo.__func__.__doc__= GET_CONTROLLER_CLASS_INFO_DOC Pool.ReloadControllerLib.__func__.__doc__= RELOAD_CONTROLLER_LIB_INFO_DOC Pool.ReloadControllerClass.__func__.__doc__= RELOAD_CONTROLLER_CLASS_INFO_DOC Pool.Stop.__func__.__doc__= STOP_DOC Pool.Abort.__func__.__doc__= ABORT_DOC class PoolClass(PyTango.DeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { 'PoolPath': [PyTango.DevVarStringArray, "list of directories to search for controllers (path separators " "can be '\n' or ':')", []], 'PythonPath': [PyTango.DevVarStringArray, "list of directories to be appended to sys.path at startup (path " "separators can be '\n' or ':')", []], 'MotionLoop_SleepTime': [PyTango.DevLong, "Sleep time in the motion loop in mS [default: %dms]" % int(POOL.Default_MotionLoop_SleepTime*1000), int(POOL.Default_MotionLoop_SleepTime*1000)], 'MotionLoop_StatesPerPosition': [PyTango.DevLong, "Number of State reads done before doing a position read in the " "motion loop [default: %d]" % POOL.Default_MotionLoop_StatesPerPosition, POOL.Default_MotionLoop_StatesPerPosition], 'AcqLoop_SleepTime': [PyTango.DevLong, "Sleep time in the acquisition loop in mS [default: %dms]" % int(POOL.Default_AcqLoop_SleepTime*1000), int(POOL.Default_AcqLoop_SleepTime*1000)], 'AcqLoop_StatesPerValue': [PyTango.DevLong, "Number of State reads done before doing a value read in the " "acquisition loop [default: %d]" % POOL.Default_AcqLoop_StatesPerValue, POOL.Default_AcqLoop_StatesPerValue], 'RemoteLog': [PyTango.DevString, "Logging (python logging) host:port [default: None]", None], 'DriftCorrection': [PyTango.DevBoolean, "Globally apply drift correction on pseudo motors (can be " "overwritten at PseudoMotor level [default: %d]." % POOL.Default_DriftCorrection, POOL.Default_DriftCorrection], 'InstrumentList': [PyTango.DevVarStringArray, "List of instruments (internal property)", []], } # Command definitions cmd_list = { 'CreateController': [[PyTango.DevVarStringArray, CREATE_CONTROLLER_PAR_IN_DOC], [PyTango.DevVoid, CREATE_CONTROLLER_PAR_OUT_DOC]], 'CreateElement': [[PyTango.DevVarStringArray, CREATE_ELEMENT_PAR_IN_DOC], [PyTango.DevVoid, CREATE_ELEMENT_PAR_OUT_DOC]], 'CreateInstrument': [[PyTango.DevVarStringArray, CREATE_INSTRUMENT_PAR_IN_DOC], [PyTango.DevVoid, CREATE_INSTRUMENT_PAR_OUT_DOC]], 'CreateMotorGroup': [[PyTango.DevVarStringArray, CREATE_MOTOR_GROUP_PAR_IN_DOC], [PyTango.DevVoid, CREATE_MOTOR_GROUP_PAR_OUT_DOC]], 'CreateMeasurementGroup': [[PyTango.DevVarStringArray, CREATE_MEASUREMENT_GROUP_PAR_IN_DOC], [PyTango.DevVoid, CREATE_MEASUREMENT_GROUP_PAR_OUT_DOC]], 'DeleteElement': [[PyTango.DevString, DELETE_ELEMENT_PAR_IN_DOC], [PyTango.DevVoid, DELETE_ELEMENT_PAR_OUT_DOC]], 'GetControllerClassInfo': [[PyTango.DevString, GET_CONTROLLER_CLASS_INFO_PAR_IN_DOC], [PyTango.DevString, GET_CONTROLLER_CLASS_INFO_PAR_OUT_DOC]], 'ReloadControllerLib': [[PyTango.DevString, RELOAD_CONTROLLER_LIB_PAR_IN_DOC], [PyTango.DevVoid, RELOAD_CONTROLLER_LIB_PAR_OUT_DOC]], 'ReloadControllerClass': [[PyTango.DevString, RELOAD_CONTROLLER_CLASS_PAR_IN_DOC], [PyTango.DevVoid, RELOAD_CONTROLLER_CLASS_PAR_OUT_DOC]], 'GetControllerCode': [[PyTango.DevVarStringArray, " [, ]"], [PyTango.DevVarStringArray, "result is a sequence of 3 strings:\n" ", , " ]], 'SetControllerCode': [[PyTango.DevVarStringArray, ", [, =True]\n" \ "- if controller library is a simple module name:\n" \ " - if it exists, it is overwritten, otherwise a new python " \ "file is created in the directory of the first element in "\ "the PoolPath property" \ "- if controller library is the full path name:\n" \ " - if path is not in the PoolPath, an exception is thrown" \ " - if file exists it is overwritten otherwise a new file " \ "is created"], [PyTango.DevVoid, "" ]], 'Stop': [[PyTango.DevVoid, STOP_PAR_IN_DOC], [PyTango.DevVoid, STOP_PAR_OUT_DOC]], 'Abort': [[PyTango.DevVoid, ABORT_PAR_IN_DOC], [PyTango.DevVoid, ABORT_PAR_OUT_DOC]], 'SendToController': [[PyTango.DevVarStringArray, SEND_TO_CONTROLLER_PAR_IN_DOC], [PyTango.DevString, SEND_TO_CONTROLLER_PAR_OUT_DOC]], 'GetFile': [[PyTango.DevString, "name (may be module name, file name or full (with absolute path) file name"], [PyTango.DevVarStringArray, "[complete(with absolute path) file name, file contents]"]], 'PutFile': [[PyTango.DevVarStringArray, "[name (may be module name, file name or full (with absolute path) file name, file contents]"], [PyTango.DevVoid, ""]], } # Attribute definitions attr_list = { 'InstrumentList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Motor list", 'description':"the list of instruments (a JSON encoded dict)", } ], 'ControllerList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Controller list", 'description':"the list of controllers (a JSON encoded dict)", } ], 'ExpChannelList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Experiment channel list", 'description':"The list of experiment channels (a JSON encoded dict)", } ], 'AcqChannelList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Acquisition channel list", 'description':"The list of all acquisition channels (a JSON encoded dict)", } ], 'MotorGroupList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Motor group list", 'description':"the list of motor groups (a JSON encoded dict)", } ], 'ControllerLibList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Controller library list", 'description':"the list of controller libraries (a JSON encoded dict)", } ], 'ControllerClassList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Controller class list", 'description':"the list of controller classes (a JSON encoded dict)", } ], 'MotorList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Motor list", 'description':"the list of motors (a JSON encoded dict)", } ], 'MeasurementGroupList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Measurement group list", 'description':"the list of measurement groups (a JSON encoded dict)", } ], 'IORegisterList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"IORegister list", 'description':"the list of IORegisters (a JSON encoded dict)", } ], 'ComChannelList': [[PyTango.DevString, PyTango.SPECTRUM, PyTango.READ, 4096], { 'label':"Communication channel list", 'description':"the list of communication channels (a JSON encoded dict)", } ], 'Elements': [[PyTango.DevEncoded, PyTango.SCALAR, PyTango.READ], { 'label':"Elements", 'description':"the list of all elements (a JSON encoded dict)", } ], } def __init__(self, name): PyTango.DeviceClass.__init__(self, name) self.set_type(name) def _get_class_properties(self): return dict(ProjectTitle="Sardana", Description="Device Pool management class", doc_url="http://sardana-controls.org/", InheritedFrom="Device_4Impl") def write_class_property(self): util = PyTango.Util.instance() db = util.get_database() if db is None: return db.put_class_property(self.get_name(), self._get_class_properties()) sardana-1.2.0/src/sardana/tango/pool/PoolDevice.py0000644000234100017500000007651412174204312023425 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """Generic Tango Pool Device base classes""" __all__ = ["PoolDevice", "PoolDeviceClass", "PoolElementDevice", "PoolElementDeviceClass", "PoolGroupDevice", "PoolGroupDeviceClass"] __docformat__ = 'restructuredtext' import time from PyTango import Util, DevVoid, DevLong64, DevBoolean, DevString, \ DevVarStringArray, DispLevel, DevState, SCALAR, SPECTRUM, \ IMAGE, READ_WRITE, READ, AttrData, CmdArgType, DevFailed, seqStr_2_obj from taurus.core.util import CaselessDict from sardana import InvalidId, InvalidAxis, ElementType from sardana.pool.poolmetacontroller import DataInfo from sardana.tango.core.SardanaDevice import SardanaDevice, SardanaDeviceClass from sardana.tango.core.util import GenericScalarAttr, GenericSpectrumAttr, \ GenericImageAttr, to_tango_attr_info class PoolDevice(SardanaDevice): """Base Tango Pool device class""" #: list of extreme error states ExtremeErrorStates = DevState.FAULT, DevState.UNKNOWN #: list of busy states BusyStates = DevState.MOVING, DevState.RUNNING #: Maximum number of retries in a busy state BusyRetries = 3 def __init__(self, dclass, name): """Constructor""" SardanaDevice.__init__(self, dclass, name) def init(self, name): """initialize the device once in the object lifetime. Override when necessary but **always** call the method from your super class :param str name: device name""" SardanaDevice.init(self, name) util = Util.instance() self._pool_device = util.get_device_list_by_class("Pool")[0] self._element = None @property def pool_device(self): """The tango pool device""" return self._pool_device @property def pool(self): """The sardana pool object""" return self.pool_device.pool def get_element(self): """Returns the underlying pool element object :return: the underlying pool element object :rtype: :class:`~sardana.pool.poolelement.PoolElement`""" return self._element def set_element(self, element): """Associates this device with the sardana element :param element: the sardana element :type element: :class:`~sardana.pool.poolelement.PoolElement`""" self._element = element element = property(get_element, set_element, doc="The underlying sardana element") def init_device(self): """Initialize the device. Called during startup after :meth:`init` and every time the tango ``Init`` command is executed. Override when necessary but **always** call the method from your super class""" SardanaDevice.init_device(self) def delete_device(self): """Clean the device. Called during shutdown and every time the tango ``Init`` command is executed. Override when necessary but **always** call the method from your super class""" SardanaDevice.delete_device(self) def Abort(self): """The tango abort command. Aborts the active operation""" self.element.abort() try: self.element.get_state(cache=False, propagate=2) except: self.warning("Abort: failed to read state") def is_Abort_allowed(self): """Returns True if it is allowed to execute the tango abort command :return: True if it is allowed to execute the tango abort command or False otherwise :rtype: bool""" return self.get_state() != DevState.UNKNOWN def Stop(self): """The tango stop command. Stops the active operation""" self.element.stop() try: self.element.get_state(cache=False, propagate=2) except: self.info("Stop: failed to read state") def is_Stop_allowed(self): """Returns True if it is allowed to execute the tango stop command :return: True if it is allowed to execute the tango stop command or False otherwise :rtype: bool""" return self.get_state() != DevState.UNKNOWN def _is_allowed(self, req_type): """Generic is_allowed""" # state = self.get_state() # if state in self.ExtremeErrorStates: # return False # if req_type == AttReqType.WRITE_REQ: # if state in self.BusyStates: # return False return True def get_dynamic_attributes(self): """Returns the standard dynamic and fully dynamic attributes for this device. The return is a tuple of two dictionaries: - standard attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information - dynamic attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information **tango information** seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > **attribute information** attribute information as returned by the sardana controller :return: the standard dynamic and fully dynamic attributes :rtype: seq< :class:`~taurus.core.util.CaselessDict`, :class:`~taurus.core.util.CaselessDict`\> """ return CaselessDict(), CaselessDict() def initialize_dynamic_attributes(self): """Initializes this device dynamic attributes""" self._attributes = attrs = CaselessDict() attr_data = self.get_dynamic_attributes() std_attrs, dyn_attrs = attr_data self.remove_unwanted_dynamic_attributes(std_attrs, dyn_attrs) if std_attrs is not None: read = self.__class__._read_DynamicAttribute write = self.__class__._write_DynamicAttribute is_allowed = self.__class__._is_DynamicAttribute_allowed for attr_name, data_info in std_attrs.items(): attr_name, data_info, attr_info = data_info attr = self.add_standard_attribute(attr_name, data_info, attr_info, read, write, is_allowed) attrs[attr.get_name()] = None if dyn_attrs is not None: read = self.__class__._read_DynamicAttribute write = self.__class__._write_DynamicAttribute is_allowed = self.__class__._is_DynamicAttribute_allowed for attr_name, data_info in dyn_attrs.items(): attr_name, data_info, attr_info = data_info attr = self.add_dynamic_attribute(attr_name, data_info, attr_info, read, write, is_allowed) attrs[attr.get_name()] = None return attrs def remove_unwanted_dynamic_attributes(self, new_std_attrs, new_dyn_attrs): """Removes unwanted dynamic attributes from previous device creation""" dev_class = self.get_device_class() multi_attr = self.get_device_attr() multi_class_attr = dev_class.get_class_attr() static_attr_names = map(str.lower, dev_class.attr_list.keys()) static_attr_names.extend(('state', 'status')) new_attrs = CaselessDict(new_std_attrs) new_attrs.update(new_dyn_attrs) device_attr_names = [] for i in range(multi_attr.get_attr_nb()): device_attr_names.append(multi_attr.get_attr_by_ind(i).get_name()) for attr_name in device_attr_names: attr_name_lower = attr_name.lower() if attr_name_lower in static_attr_names: continue try: self.remove_attribute(attr_name) except: self.warning("Error removing dynamic attribute %s", attr_name_lower) self.debug("Details:", exc_info=1) klass_attr_names = [] klass_attrs = multi_class_attr.get_attr_list() for ind in range(len(klass_attrs)): klass_attr_names.append(klass_attrs[ind].get_name()) for attr_name in klass_attr_names: attr_name_lower = attr_name.lower() if attr_name_lower in static_attr_names: continue # if new dynamic attribute is in class attribute then delete it # from class attribute to be later on added again (eventually # with diffent data type or data format) if attr_name_lower in new_attrs: try: attr = multi_class_attr.get_attr(attr_name) old_type = CmdArgType(attr.get_type()) old_format = attr.get_format() old_access = attr.get_writable() new_attr = new_attrs[attr_name] new_type, new_format, new_access = new_attr[1][0][:3] differ = new_type != old_type or \ new_format != old_format or \ new_access != old_access if differ: self.info("Replacing dynamic attribute %s", attr_name) self.debug("old type: %s, new type: %s", old_type, new_type) self.debug("old format: %s, new format: %s", old_format, new_format) self.debug("old access: %s, new access: %s", old_access, new_access) multi_class_attr.remove_attr(attr.get_name(), attr.get_cl_name()) except: self.warning("Error removing dynamic attribute %s from "\ " device class", attr_name) self.debug("Details:", exc_info=1) def add_dynamic_attribute(self, attr_name, data_info, attr_info, read, write, is_allowed): """Adds a single dynamic attribute :param str attr_name: the attribute name :param data_info: tango attribute information :type data_info: seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > :param attr_info: attribute information :param read: read method for the attribute :param write: write method for the attribute :param is_allowed: is allowed method""" tg_type, tg_format, tg_access = data_info[0] if tg_access == READ: write = None if tg_format == SCALAR: attr = GenericScalarAttr(attr_name, tg_type, tg_access) if tg_format == SPECTRUM: dim_x = attr_info.maxdimsize[0] attr = GenericSpectrumAttr(attr_name, tg_type, tg_access, dim_x=dim_x) elif tg_format == IMAGE: dim_x, dim_y = attr_info.maxdimsize attr = GenericImageAttr(attr_name, tg_type, tg_access, dim_x=dim_x, dim_y=dim_y) if tg_access == READ_WRITE and tg_format == SCALAR: memorized = attr_info.memorized.lower() if memorized == 'true': attr.set_memorized() attr.set_memorized_init(True) elif memorized == 'true_without_hard_applied': attr.set_memorized() attr.set_memorized_init(False) attr.set_disp_level(DispLevel.EXPERT) return self.add_attribute(attr, read, write, is_allowed) def add_standard_attribute(self, attr_name, data_info, attr_info, read, write, is_allowed): """Adds a single standard dynamic attribute :param str attr_name: the attribute name :param data_info: tango attribute information :type data_info: seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > :param attr_info: attribute information :param read: read method for the attribute :param write: write method for the attribute :param is_allowed: is allowed method""" dev_class = self.get_device_class() attr_data = AttrData(attr_name, dev_class.get_name(), data_info) attr = self.add_attribute(attr_data, read, write, is_allowed) return attr def read_DynamicAttribute(self, attr): """Generic read dynamic attribute. Default implementation raises :exc:`NotImplementedError` :param attr: attribute to be read :type attr: :class:`~PyTango.Attribute` :raises: :exc:`NotImplementedError`""" raise NotImplementedError def write_DynamicAttribute(self, attr): """Generic write dynamic attribute. Default implementation raises :exc:`NotImplementedError` :param attr: attribute to be written :type attr: :class:`~PyTango.Attribute` :raises: :exc:`NotImplementedError`""" raise NotImplementedError def is_DynamicAttribute_allowed(self, req_type): """Generic is dynamic attribute allowed. Default implementation calls :meth:`_is_allowed` :param req_type: request type :type attr: :class:`~PyTango.AttrRequestType`""" return self._is_allowed(req_type) def _read_DynamicAttribute(self, attr): """Generic internal read dynamic attribute. Checks if this object has a 'read_'+ method and calls it. If not calls :meth:`read_DynamicAttribute`. :param attr: attribute to be read :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() read_name = "read_" + name if hasattr(self, read_name): read = getattr(self, read_name) return read(attr) return self.read_DynamicAttribute(attr) def _write_DynamicAttribute(self, attr): """Generic internal write dynamic attribute. Checks if this object has a 'write_'+ method and calls it. If not calls :meth:`write_DynamicAttribute`. :param attr: attribute to be written :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() write_name = "write_" + name if hasattr(self, write_name): write = getattr(self, write_name) return write(attr) return self.write_DynamicAttribute(attr) def _is_DynamicAttribute_allowed(self, req_type): """Generic is dynamic attribute allowed. Default implementation calls :meth:`is_DynamicAttribute_allowed` :param req_type: request type :type attr: :class:`~PyTango.AttrRequestType`""" return self.is_DynamicAttribute_allowed(req_type) def dev_state(self): """Calculates and returns the device state. Called by Tango on a read state request. :return: the device state :rtype: :class:`~PyTango.DevState`""" element = self.element try: use_cache = element.is_in_operation() and not self.Force_HW_Read ctrl_state = element.get_state(cache=use_cache, propagate=0) state = self.calculate_tango_state(ctrl_state) return state except: self.error("Exception trying to return state") self.debug("Details:", exc_info=1) return DevState.FAULT def dev_status(self): """Calculates and returns the device status. Called by Tango on a read status request. :return: the device status :rtype: str""" element = self.element try: use_cache = element.is_in_operation() and not self.Force_HW_Read ctrl_status = self.element.get_status(cache=use_cache, propagate=0) status = self.calculate_tango_status(ctrl_status) return status except Exception, e: msg = "Exception trying to return status: %s" % str(e) self.error(msg) self.debug("Details:", exc_info=1) return msg def wait_for_operation(self): """Waits for an operation to finish. It uses the maxumum number of retries. Sleeps 0.01s between retries. :raises: :exc:`Exception` in case of a timeout""" element, n = self.element, self.BusyRetries while element.is_in_operation(): if n == 0: raise Exception("Wait for operation timedout") time.sleep(0.01) self.warning("waited for operation") n = n - 1 def Restore(self): """Restore tango command. Restores the attributes to their former glory. This applies to memorized writable attributes which have a set point stored in the database""" restore_attributes, db_values = self.get_restore_data() multi_attribute = self.get_device_attr() for attr_name in restore_attributes: props = db_values[attr_name] if props is None or not "__value" in props: continue attribute = multi_attribute.get_w_attr_by_name(attr_name) write_meth_name = "write_" + attr_name write_meth = getattr(self, write_meth_name, None) if write_meth is None: self.warning("Could not recover %s: %s does not exist", attr_name, write_meth_name) continue self.restore_attribute(attribute, write_meth, props['__value']) def get_restore_data(self): restore_attributes = self.get_attributes_to_restore() db = Util.instance().get_database() db_values = db.get_device_attribute_property(self.get_name(), restore_attributes) return restore_attributes, db_values def get_attributes_to_restore(self): std_attrs, dyn_attrs = self.get_dynamic_attributes() multi_attribute = self.get_device_attr() restore = [] for attr_name in std_attrs: try: attribute = multi_attribute.get_w_attr_by_name(attr_name) except DevFailed: continue restore.append(attribute.get_name()) for attr_name in dyn_attrs: try: attribute = multi_attribute.get_w_attr_by_name(attr_name) except DevFailed: continue restore.append(attribute.get_name()) return restore def _get_attribute_value_from_db_value(self, attribute, db_value): value = seqStr_2_obj(db_value, attribute.get_data_type(), attribute.get_data_format()) return value def restore_attribute(self, attribute, write_meth, db_value): value = self._get_attribute_value_from_db_value(attribute, db_value) attr_name = attribute.get_name() try: attribute.set_write_value(value) self.info("Restoring %s", attr_name) write_meth(attribute) except: self.warning("Could not recover %s: Error in write", attr_name) self.debug("Details:", exc_info=1) class PoolDeviceClass(SardanaDeviceClass): """Base Tango Pool Device Class class""" #: #: Sardana device class properties definition #: #: .. seealso:: :ref:`server` #: class_property_list = SardanaDeviceClass.class_property_list #: #: Sardana device properties definition #: #: .. seealso:: :ref:`server` #: device_property_list = { 'Id' : [DevLong64, "Internal ID", InvalidId ], 'Force_HW_Read' : [DevBoolean, "Force a hardware read of value even " "when in operation (motion/acquisition", False], } device_property_list.update(SardanaDeviceClass.device_property_list) #: #: Sardana device command definition #: #: .. seealso:: :ref:`server` #: cmd_list = { 'Stop' : [ [DevVoid, ""], [DevVoid, ""] ], 'Abort' : [ [DevVoid, ""], [DevVoid, ""] ], 'Restore' : [ [DevVoid, ""], [DevVoid, ""] ], } cmd_list.update(SardanaDeviceClass.cmd_list) #: #: Sardana device attribute definition #: #: .. seealso:: :ref:`server` #: attr_list = { } attr_list.update(SardanaDeviceClass.attr_list) standard_attr_list = {} def _get_class_properties(self): ret = SardanaDeviceClass._get_class_properties(self) ret['Description'] = "Generic Pool device class" ret['InheritedFrom'].insert(0, 'SardanaDevice') return ret class PoolElementDevice(PoolDevice): """Base Tango Pool Element Device class""" def init_device(self): """Initialize the device. Called during startup after :meth:`init` and every time the tango ``Init`` command is executed. Override when necessary but **always** call the method from your super class""" PoolDevice.init_device(self) self.instrument = None self.ctrl = None try: instrument_id = int(self.Instrument_id) if instrument_id != InvalidId: instrument = self.pool.get_element_by_id(instrument_id) self.instrument = instrument except ValueError: pass try: ctrl_id = int(self.Ctrl_id) if ctrl_id != InvalidId: ctrl = self.pool.get_element_by_id(ctrl_id) self.ctrl = ctrl except ValueError: pass def read_Instrument(self, attr): """Read the value of the ``Instrument`` tango attribute. Returns the instrument full name or empty string if this element doesn't belong to any instrument :param attr: tango instrument attribute :type attr: :class:`~PyTango.Attribute`""" instrument = self.element.instrument if instrument is None: attr.set_value('') else: attr.set_value(instrument.full_name) def write_Instrument(self, attr): """Write the value of the ``Instrument`` tango attribute. Sets a new instrument full name or empty string if this element doesn't belong to any instrument. The instrument **must** have been previously created. :param attr: tango instrument attribute :type attr: :class:`~PyTango.Attribute`""" name = attr.get_write_value() instrument = None if name: instrument = self.pool.get_element(full_name=name) if instrument.get_type() != ElementType.Instrument: raise Exception("%s is not an instrument" % name) self.element.instrument = instrument db = Util.instance().get_database() db.put_device_property(self.get_name(), { "Instrument_id" : instrument.id }) def get_dynamic_attributes(self): """Override of :class:`PoolDevice.get_dynamic_attributes`. Returns the standard dynamic and fully dynamic attributes for this device. The return is a tuple of two dictionaries: - standard attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information - dynamic attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information **tango information** seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > **attribute information** attribute information as returned by the sardana controller :return: the standard dynamic and fully dynamic attributes :rtype: seq< :class:`~taurus.core.util.CaselessDict`, :class:`~taurus.core.util.CaselessDict`\> """ if hasattr(self, "_dynamic_attributes_cache"): return self._standard_attributes_cache, self._dynamic_attributes_cache ctrl = self.ctrl if ctrl is None: self.warning("no controller: dynamic attributes NOT created") return PoolDevice.get_dynamic_attributes(self) if not ctrl.is_online(): self.warning("controller offline: dynamic attributes NOT created") return PoolDevice.get_dynamic_attributes(self) self._dynamic_attributes_cache = dyn_attrs = CaselessDict() self._standard_attributes_cache = std_attrs = CaselessDict() dev_class = self.get_device_class() axis_attrs = ctrl.get_axis_attributes(self.element.axis) std_attrs_lower = [ attr.lower() for attr in dev_class.standard_attr_list ] for attr_name, attr_info in axis_attrs.items(): attr_name_lower = attr_name.lower() if attr_name_lower in std_attrs_lower: data_info = DataInfo.toDataInfo(attr_name, attr_info) tg_info = dev_class.standard_attr_list[attr_name] std_attrs[attr_name] = attr_name, tg_info, data_info else: data_info = DataInfo.toDataInfo(attr_name, attr_info) name, tg_info = to_tango_attr_info(attr_name, data_info) dyn_attrs[attr_name] = name, tg_info, data_info return std_attrs, dyn_attrs def read_DynamicAttribute(self, attr): """Read a generic dynamic attribute. Calls the controller of this element to get the dynamic attribute value :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() ctrl = self.ctrl if ctrl is None: raise Exception("Cannot read %s. Controller not build!" % name) v = ctrl.get_axis_attr(self.element.axis, name) if v is None: raise TypeError("Cannot read %s. Controller returns None" % (name,)) attr.set_value(v) def write_DynamicAttribute(self, attr): """Write a generic dynamic attribute. Calls the controller of this element to get the dynamic attribute value :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() value = attr.get_write_value() self.debug("writting dynamic attribute %s with value %s", name, value) ctrl = self.ctrl if ctrl is None: raise Exception("Cannot write %s. Controller not build!" % name) ctrl.set_axis_attr(self.element.axis, name, value) def read_SimulationMode(self, attr): """Read the current simulation mode. :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" attr.set_value(self.element.simulation_mode) def write_SimulationMode(self, attr): """Sets the simulation mode. :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" self.element.simulation_mode = attr.get_write_value() class PoolElementDeviceClass(PoolDeviceClass): """Base Tango Pool Element Device Class class""" #: #: Sardana device properties definition #: #: .. seealso:: :ref:`server` #: device_property_list = { "Axis" : [ DevLong64, "Axis in the controller", [ InvalidAxis ] ], "Ctrl_id" : [ DevLong64, "Controller ID", [ InvalidId ] ], "Instrument_id" : [ DevLong64, "Controller ID", [ InvalidId ] ], } device_property_list.update(PoolDeviceClass.device_property_list) #: #: Sardana device attribute definition #: #: .. seealso:: :ref:`server` #: attr_list = { 'Instrument' : [ [DevString, SCALAR, READ_WRITE], { 'label' : "Instrument", 'Display level' : DispLevel.EXPERT } ], 'SimulationMode': [ [DevBoolean, SCALAR, READ_WRITE], { 'label' : "Simulation mode" } ], } attr_list.update(PoolDeviceClass.attr_list) cmd_list = { } cmd_list.update(PoolDeviceClass.cmd_list) def get_standard_attr_info(self, attr): """Returns information about the standard attribute :param str attr: attribute name :return: a sequence of tango data_type, data format""" return self.standard_attr_list[attr] def _get_class_properties(self): ret = PoolDeviceClass._get_class_properties(self) ret['Description'] = "Generic Pool element device class" ret['InheritedFrom'].insert(0, 'PoolDevice') return ret class PoolGroupDevice(PoolDevice): """Base Tango Pool Group Device class""" def read_ElementList(self, attr): """Read the element list. :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" attr.set_value(self.get_element_names()) def get_element_names(self): """Returns the list of element names. :return: a list of attribute names""" elements = self.element.get_user_elements() return [ element.name for element in elements ] def elements_changed(self, evt_src, evt_type, evt_value): """Callback for when the elements of this group changed""" self.push_change_event("ElementList", self.get_element_names()) class PoolGroupDeviceClass(PoolDeviceClass): """Base Tango Pool Group Device Class class""" #: #: Sardana device properties definition #: #: .. seealso:: :ref:`server` #: device_property_list = { "Elements" : [ DevVarStringArray, "elements in the group", [ ] ], } device_property_list.update(PoolDeviceClass.device_property_list) #: #: Sardana device command definition #: #: .. seealso:: :ref:`server` #: cmd_list = { } cmd_list.update(PoolDeviceClass.cmd_list) #: #: Sardana device attribute definition #: #: .. seealso:: :ref:`server` #: attr_list = { 'ElementList' : [ [ DevString, SPECTRUM, READ, 4096] ], } attr_list.update(PoolDeviceClass.attr_list) def _get_class_properties(self): ret = PoolDeviceClass._get_class_properties(self) ret['Description'] = "Generic Pool group device class" ret['InheritedFrom'].insert(0, 'PoolDevice') return ret sardana-1.2.0/src/sardana/tango/pool/PseudoCounter.py0000644000234100017500000002152612174204312024164 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["PseudoCounter", "PseudoCounterClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import Except, READ, SCALAR, DevDouble, \ DevVarStringArray, DevVarDoubleArray, DevState, AttrQuality, DevFailed from taurus.core.util.log import DebugIt from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.tango.core.util import to_tango_type_format, exception_str, \ throw_sardana_exception from PoolDevice import PoolElementDevice, PoolElementDeviceClass class PseudoCounter(PoolElementDevice): def __init__(self, dclass, name): PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def _is_allowed(self, req_type): return PoolElementDevice._is_allowed(self, req_type) def get_pseudo_counter(self): return self.element def set_pseudo_counter(self, pseudo_counter): self.element = pseudo_counter pseudo_counter = property(get_pseudo_counter, set_pseudo_counter) @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) pseudo_counter = self.pseudo_counter if pseudo_counter is not None: pseudo_counter.remove_listener(self.on_pseudo_counter_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) self.Elements = map(int, self.Elements) pseudo_counter = self.pseudo_counter if pseudo_counter is None: full_name = self.get_full_name() name = self.alias or full_name self.pseudo_counter = pseudo_counter = \ self.pool.create_element(type="PseudoCounter", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id, user_elements=self.Elements) if self.instrument is not None: pseudo_counter.set_instrument(self.instrument) pseudo_counter.add_listener(self.on_pseudo_counter_changed) self.set_state(DevState.ON) def on_pseudo_counter_changed(self, event_source, event_type, event_value): try: self._on_pseudo_counter_changed(event_source, event_type, event_value) except: msg = 'Error occurred "on_pseudo_counter_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.pseudo_counter.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_pseudo_counter_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() try: attr = self.get_attribute_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp else: value = event_value state = self.pseudo_counter.get_state(propagate=0) if name == "value": if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.pseudo_counter.get_state(cache=False)) pass def read_attr_hardware(self,data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For value attribute, listen to what the controller says for data # type (between long and float) value = std_attrs.get('value') if value is not None: _, data_info, attr_info = value ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype return std_attrs, dyn_attrs def initialize_dynamic_attributes(self): attrs = PoolElementDevice.initialize_dynamic_attributes(self) detect_evts = "value", non_detect_evts = () for attr_name in detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, True) for attr_name in non_detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, False) def read_Value(self, attr): pseudo_counter = self.pseudo_counter use_cache = pseudo_counter.is_in_operation() and not self.Force_HW_Read value = pseudo_counter.get_value(cache=use_cache, propagate=0) if value.error: Except.throw_python_exception(*value.exc_info) quality = None state = pseudo_counter.get_state(cache=use_cache, propagate=0) if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value.value, quality=quality, priority=0, timestamp=value.timestamp) is_Value_allowed = _is_allowed def CalcPseudo(self, physical_values): """Returns the pseudo counter value for the given physical counters""" if not len(physical_values): physical_values = None result = self.pseudo_counter.calc(physical_values=physical_values) if result.error: throw_sardana_exception(result) return result.value def CalcAllPseudo(self, physical_values): """Returns the pseudo counter values for the given physical counters""" if not len(physical_values): physical_values = None result = self.pseudo_counter.calc(physical_values=physical_values) if result.error: throw_sardana_exception(result) return result.value class PseudoCounterClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { "Elements" : [ DevVarStringArray, "elements used by the pseudo", [ ] ], } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'CalcPseudo' : [ [DevVarDoubleArray, "physical values"], [DevDouble, "pseudo counter"] ], 'CalcAllPseudo' : [ [DevVarDoubleArray, "physical positions"], [DevVarDoubleArray, "pseudo counter values"] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions standard_attr_list = { 'Value' : [ [ DevDouble, SCALAR, READ ] ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "Pseudo counter device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/PseudoMotor.py0000644000234100017500000002625512174204312023651 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["PseudoMotor", "PseudoMotorClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import DevFailed, Except, READ_WRITE, SCALAR, DevVoid, DevDouble, \ DevBoolean, DevVarStringArray, DevVarDoubleArray, DevState, AttrQuality from taurus.core.util.log import DebugIt from sardana import State, SardanaServer from sardana.sardanaexception import SardanaException from sardana.sardanaattribute import SardanaAttribute from sardana.tango.core.util import exception_str, to_tango_type_format, \ throw_sardana_exception from PoolDevice import PoolElementDevice, PoolElementDeviceClass class PseudoMotor(PoolElementDevice): def __init__(self, dclass, name): self.in_write_position = False PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def _is_allowed(self, req_type): return PoolElementDevice._is_allowed(self, req_type) def get_pseudo_motor(self): return self.element def set_pseudo_motor(self, pseudo_motor): self.element = pseudo_motor pseudo_motor = property(get_pseudo_motor, set_pseudo_motor) @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) pseudo_motor = self.pseudo_motor if pseudo_motor is not None: pseudo_motor.remove_listener(self.on_pseudo_motor_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) self.Elements = map(int, self.Elements) pseudo_motor = self.pseudo_motor if self.pseudo_motor is None: full_name = self.get_full_name() name = self.alias or full_name self.pseudo_motor = pseudo_motor = \ self.pool.create_element(type="PseudoMotor", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id, user_elements=self.Elements) if self.instrument is not None: pseudo_motor.set_instrument(self.instrument) pseudo_motor.set_drift_correction(self.DriftCorrection) pseudo_motor.add_listener(self.on_pseudo_motor_changed) self.set_state(DevState.ON) def on_pseudo_motor_changed(self, event_source, event_type, event_value): try: self._on_pseudo_motor_changed(event_source, event_type, event_value) except: msg = 'Error occurred "on_pseudo_motor_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.pseudo_motor.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_pseudo_motor_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() try: attr = self.get_attribute_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp else: value = event_value state = self.pseudo_motor.get_state(propagate=0) if name == "position": w_value = event_value.w_value if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.pseudo_motor.get_state(cache=False)) pass def read_attr_hardware(self, data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For position attribute, listen to what the controller says for # data type (between long and float) pos = std_attrs.get('position') if pos is not None: _, data_info, attr_info = pos ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype return std_attrs, dyn_attrs def initialize_dynamic_attributes(self): attrs = PoolElementDevice.initialize_dynamic_attributes(self) detect_evts = "position", non_detect_evts = () for attr_name in detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, True) for attr_name in non_detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, False) return def read_Position(self, attr): pseudo_motor = self.pseudo_motor use_cache = pseudo_motor.is_in_operation() and not self.Force_HW_Read position = pseudo_motor.get_position(cache=use_cache, propagate=0) if position.error: throw_sardana_exception(position) state = pseudo_motor.get_state(cache=use_cache, propagate=0) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=position.value, w_value=position.w_value, quality=quality, priority=0, timestamp=position.timestamp) def write_Position(self, attr): self.in_write_position = True try: position = attr.get_write_value() self.debug("write_Position(%s)", position) try: self.wait_for_operation() except: raise Exception("Cannot move: already in motion") pseudo_motor = self.pseudo_motor try: pseudo_motor.position = position except SardanaException as se: throw_sardana_exception(se) finally: self.in_write_position = False def CalcPseudo(self, physical_positions): """Returns the pseudo motor position for the given physical positions""" if not len(physical_positions): physical_positions = None result = self.pseudo_motor.calc_pseudo(physical_positions=physical_positions) if result.error: throw_sardana_exception(result) return result.value def CalcPhysical(self, pseudo_position): """Returns the physical motor positions for the given pseudo motor position assuming the current pseudo motor write positions for all the other sibling pseudo motors""" result = self.pseudo_motor.calc_physical(pseudo_position) if result.error: throw_sardana_exception(result) return result.value def CalcAllPhysical(self, pseudo_positions): """Returns the physical motor positions for the given pseudo motor position(s)""" result = self.pseudo_motor.calc_physical(pseudo_positions) if result.error: throw_sardana_exception(result) return result.value def CalcAllPseudo(self, physical_positions): """Returns the pseudo motor position(s) for the given physical positions""" result = self.pseudo_motor.calc_all_pseudo(physical_positions) if result.error: throw_sardana_exception(result) return result.value def MoveRelative(self, argin): raise NotImplementedError def is_MoveRelative_allowed(self): if self.get_state() in (DevState.FAULT, DevState.MOVING, DevState.UNKNOWN): return False return True is_Position_allowed = _is_allowed class PseudoMotorClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { "Elements" : [ DevVarStringArray, "elements used by the pseudo", [ ] ], 'DriftCorrection': [DevBoolean, "Locally apply drift correction on pseudo motors. Default is the " "current global drift correction in the Pool Device", None], } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'CalcPseudo' : [ [DevVarDoubleArray, "physical positions"], [DevDouble, "pseudo position"] ], 'CalcPhysical' : [ [DevDouble, "pseudo position"], [DevVarDoubleArray, "physical positions"] ], 'CalcAllPseudo' : [ [DevVarDoubleArray, "physical positions"], [DevVarDoubleArray, "pseudo positions"] ], 'CalcAllPhysical' : [ [DevVarDoubleArray, "pseudo positions"], [DevVarDoubleArray, "physical positions"] ], 'MoveRelative' : [ [DevDouble, "amount to move"], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions standard_attr_list = { 'Position' : [ [ DevDouble, SCALAR, READ_WRITE ], { 'label' : "Position", 'abs_change' : '1.0', }, ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "Pseudo motor device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/TwoDExpChannel.py0000644000234100017500000001751112174204312024207 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["TwoDExpChannel", "TwoDExpChannelClass"] __docformat__ = 'restructuredtext' import sys import time from PyTango import DevFailed, DevVoid, DevString, DevState, AttrQuality, \ Except, READ, SCALAR from taurus.core.util.log import DebugIt from sardana import State, DataFormat, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool.controller import TwoDController, MaxDimSize, Type from sardana.tango.core.util import to_tango_type_format, exception_str from PoolDevice import PoolElementDevice, PoolElementDeviceClass class TwoDExpChannel(PoolElementDevice): def __init__(self, dclass, name): PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def get_twod(self): return self.element def set_twod(self, twod): self.element = twod twod = property(get_twod, set_twod) @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) twod = self.twod if twod is not None: twod.remove_listener(self.on_twod_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) twod = self.twod if twod is None: full_name = self.get_full_name() name = self.alias or full_name self.twod = twod = \ self.pool.create_element(type="TwoDExpChannel", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id) if self.instrument is not None: twod.set_instrument(self.instrument) twod.add_listener(self.on_twod_changed) ## force a state read to initialize the state attribute #state = ct.state self.set_state(DevState.ON) def on_twod_changed(self, event_source, event_type, event_value): try: self._on_twod_changed(event_source, event_type, event_value) except not DevFailed: msg = 'Error occurred "on_twod_changed(%s.%s): %s"' exc_info = sys.exc_info() self.error(msg, self.motor.name, event_type.name, exception_str(*exc_info[:2])) self.debug("Details", exc_info=exc_info) def _on_twod_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name.lower() try: attr = self.get_attribute_by_name(name) except DevFailed: return quality = AttrQuality.ATTR_VALID priority = event_type.priority value, w_value, error = None, None, None if name == "state": value = self.calculate_tango_state(event_value) elif name == "status": value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) else: value = event_value.value timestamp = event_value.timestamp if name == "value": state = self.oned.get_state() if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value, w_value=w_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.twod.get_state(cache=False)) pass def read_attr_hardware(self,data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For value attribute, listen to what the controller says for data # type (between long and float) and length value = std_attrs.get('value') if value is not None: _, data_info, attr_info = value ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype shape = attr_info.maxdimsize data_info[0][3] = shape[0] data_info[0][4] = shape[1] return std_attrs, dyn_attrs def read_Value(self, attr): twod = self.twod use_cache = twod.is_in_operation() and not self.Force_HW_Read value = twod.get_value(cache=use_cache, propagate=0) if value.error: Except.throw_python_exception(*value.exc_info) state = twod.get_state(cache=use_cache, propagate=0) quality = None if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value.value, quality=quality, timestamp=value.timestamp, priority=0) def is_Value_allowed(self, req_type): if self.get_state() in [DevState.FAULT, DevState.UNKNOWN]: return False return True def read_DataSource(self, attr): data_source = self.twod.get_data_source() attr.set_value(data_source) def Start(self): self.twod.start_acquisition() _DFT_VALUE_INFO = TwoDController.standard_axis_attributes['Value'] _DFT_VALUE_MAX_SHAPE = _DFT_VALUE_INFO[MaxDimSize] _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format(_DFT_VALUE_INFO[Type], DataFormat.TwoD) class TwoDExpChannelClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = { 'DataSource' : [ [ DevString, SCALAR, READ ] ], } attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { 'Value' : [ [ _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT, READ, _DFT_VALUE_MAX_SHAPE[0], _DFT_VALUE_MAX_SHAPE[1] ], { 'abs_change' : '1.0', } ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "2D device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/ZeroDExpChannel.py0000644000234100017500000002157412174204312024361 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __all__ = ["ZeroDExpChannel", "ZeroDExpChannelClass"] __docformat__ = 'restructuredtext' import time from PyTango import Except from PyTango import DevVoid, DevDouble, DevString from PyTango import DispLevel, DevState, AttrQuality from PyTango import READ, READ_WRITE, SCALAR, SPECTRUM from taurus.core.util.log import DebugIt from sardana import State, DataFormat, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool.controller import ZeroDController, Type from sardana.tango.core.util import to_tango_type_format from PoolDevice import PoolElementDevice, PoolElementDeviceClass class ZeroDExpChannel(PoolElementDevice): def __init__(self, dclass, name): PoolElementDevice.__init__(self, dclass, name) def init(self, name): PoolElementDevice.init(self, name) def get_zerod(self): return self.element def set_zerod(self, zerod): self.element = zerod zerod = property(get_zerod, set_zerod) @DebugIt() def delete_device(self): PoolElementDevice.delete_device(self) zerod = self.zerod if zerod is not None: zerod.remove_listener(self.on_zerod_changed) @DebugIt() def init_device(self): PoolElementDevice.init_device(self) zerod = self.zerod if zerod is None: full_name = self.get_full_name() name = self.alias or full_name self.zerod = zerod = \ self.pool.create_element(type="ZeroDExpChannel", name=name, full_name=full_name, id=self.Id, axis=self.Axis, ctrl_id=self.Ctrl_id) zerod.add_listener(self.on_zerod_changed) ## force a state read to initialize the state attribute #state = zerod.state self.set_state(DevState.ON) def on_zerod_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return timestamp = time.time() name = event_type.name quality = AttrQuality.ATTR_VALID priority = event_type.priority error = None attr = self.get_device_attr().get_attr_by_name(name) if name == "state": event_value = self.calculate_tango_state(event_value) elif name == "status": event_value = self.calculate_tango_status(event_value) else: if isinstance(event_value, SardanaAttribute): if event_value.error: error = Except.to_dev_failed(*event_value.exc_info) timestamp = event_value.timestamp event_value = event_value.value if name == "value": state = self.zerod.get_state() if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=event_value, timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) def always_executed_hook(self): #state = to_tango_state(self.zerod.get_state(cache=False)) pass def read_attr_hardware(self,data): pass def get_dynamic_attributes(self): cache_built = hasattr(self, "_dynamic_attributes_cache") std_attrs, dyn_attrs = \ PoolElementDevice.get_dynamic_attributes(self) if not cache_built: # For value attribute, listen to what the controller says for data # type (between long and float) value = std_attrs.get('value') if value is not None: attr_name, data_info, attr_info = value ttype, _ = to_tango_type_format(attr_info.dtype) data_info[0][0] = ttype # Add manually a 'CurrentValue' with the same time as 'Value' attr_name = 'CurrentValue' attr_info = attr_info.copy() attr_info.description = attr_name std_attrs[attr_name] = [attr_name, data_info, attr_info] return std_attrs, dyn_attrs def initialize_dynamic_attributes(self): attrs = PoolElementDevice.initialize_dynamic_attributes(self) detect_evts = "value", non_detect_evts = () for attr_name in detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, True) for attr_name in non_detect_evts: if attr_name in attrs: self.set_change_event(attr_name, True, False) def read_Value(self, attr): zerod = self.zerod value = zerod.get_accumulated_value() quality = None if self.get_state() == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value.value, quality=quality, priority=0) def read_CurrentValue(self, attr): zerod = self.zerod #use_cache = ct.is_action_running() and not self.Force_HW_Read use_cache = self.get_state() == State.Moving and not self.Force_HW_Read value = zerod.get_current_value(cache=use_cache, propagate=0) if value.error: Except.throw_python_exception(*value.exc_info) quality = None state = zerod.get_state(cache=use_cache, propagate=0) if state == State.Moving: quality = AttrQuality.ATTR_CHANGING self.set_attribute(attr, value=value.value, quality=quality, priority=0, timestamp=value.timestamp) def Start(self): self.zerod.start_acquisition() def read_ValueBuffer(self, attr): attr.set_value(self.zerod.get_value_buffer()) def read_TimeBuffer(self, attr): attr.set_value(self.zerod.get_time_buffer()) def read_CumulationType(self, attr): attr.set_value(self.zerod.get_cumulation_type()) def write_CumulationType(self, attr): self.zerod.set_cumulation_type(attr.get_write_value()) def _is_allowed(self, req_type): return PoolElementDevice._is_allowed(self, req_type) is_Value_allowed = _is_allowed is_CurrentValue_allowed = _is_allowed is_CumulationType_allowed = _is_allowed is_ValueBuffer_allowed = _is_allowed is_TimeBuffer_allowed = _is_allowed _DFT_VALUE_INFO = ZeroDController.standard_axis_attributes['Value'] _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format(_DFT_VALUE_INFO[Type], DataFormat.Scalar) class ZeroDExpChannelClass(PoolElementDeviceClass): # Class Properties class_property_list = { } # Device Properties device_property_list = { } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = { 'ValueBuffer' : [ [ DevDouble, SPECTRUM, READ, 16*1024 ] ], 'TimeBuffer' : [ [ DevDouble, SPECTRUM, READ, 16*1024 ] ], 'CumulationType' : [ [ DevString, SCALAR, READ_WRITE ], { 'Memorized' : "true", 'label' : "Cumulation Type", 'Display level' : DispLevel.EXPERT } ], } attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { 'Value' : [ [ _DFT_VALUE_TYPE, SCALAR, READ, ], { 'abs_change' : '1.0', } ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "0D experimental channel device class" ret['InheritedFrom'].insert(0, 'PoolElementDevice') return ret sardana-1.2.0/src/sardana/tango/pool/__init__.py0000644000234100017500000000762512174204312023130 0ustar cpascualcpascual00000000000000#!/usr/bin/env python from sardana.pool.poolextension import ControllerStateTranslator ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __docformat__ = 'restructuredtext' def prepare_pool(util): import PyTango from sardana.pool.poolextension import ControllerValueTranslator, \ register_controller_value_translator, \ ControllerStateTranslator, register_controller_state_translator, \ CannotTranslateException from sardana.tango.core.util import from_deviceattribute class TangoControllerValueTranslator(ControllerValueTranslator): def translate(self, value): if not isinstance(value, PyTango.DeviceAttribute): return super(TangoControllerValueTranslator, self).translate(value) ret = from_deviceattribute(value) return ret register_controller_value_translator(TangoControllerValueTranslator) class TangoControllerStateTranslator(ControllerStateTranslator): def translate(self, value): if not isinstance(value, PyTango.DeviceAttribute): return super(TangoControllerValueTranslator, self).translate(value) if value.type != PyTango.DevState: raise CannotTranslateException("Expected DevState got %s" % value.type) ret = from_deviceattribute(value) return ret register_controller_state_translator(TangoControllerStateTranslator) from .Controller import ControllerClass, Controller from .Motor import MotorClass, Motor from .PseudoMotor import PseudoMotorClass, PseudoMotor from .MotorGroup import MotorGroupClass, MotorGroup from .CTExpChannel import CTExpChannelClass, CTExpChannel from .ZeroDExpChannel import ZeroDExpChannelClass, ZeroDExpChannel from .OneDExpChannel import OneDExpChannelClass, OneDExpChannel from .TwoDExpChannel import TwoDExpChannelClass, TwoDExpChannel from .PseudoCounter import PseudoCounterClass, PseudoCounter from .MeasurementGroup import MeasurementGroupClass, MeasurementGroup from .IORegister import IORegisterClass, IORegister from .Pool import PoolClass, Pool util.add_class(PoolClass, Pool) util.add_class(ControllerClass, Controller) util.add_class(MotorClass, Motor) util.add_class(IORegisterClass, IORegister) util.add_class(CTExpChannelClass, CTExpChannel) util.add_class(ZeroDExpChannelClass, ZeroDExpChannel) util.add_class(OneDExpChannelClass, OneDExpChannel) util.add_class(TwoDExpChannelClass, TwoDExpChannel) util.add_class(PseudoMotorClass, PseudoMotor) util.add_class(PseudoCounterClass, PseudoCounter) util.add_class(MotorGroupClass, MotorGroup) util.add_class(MeasurementGroupClass, MeasurementGroup) def main_pool(args=None, start_time=None, mode=None): import sardana.tango.core.util return sardana.tango.core.util.run(prepare_pool, args=args, start_time=start_time, mode=mode) run = main_pool sardana-1.2.0/src/sardana/tango/__init__.py0000644000234100017500000000260412174204312022147 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __docformat__ = 'restructuredtext' def prepare_sardana(util): import pool import macroserver pool.prepare_pool(util) macroserver.prepare_macroserver(util) def main_sardana(args=None, start_time=None, mode=None): import core.util return core.util.run(prepare_sardana, args=args, start_time=start_time, mode=mode) run = main_sardanasardana-1.2.0/src/sardana/tools/0000755000234100017500000000000012174204361020070 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/tools/config/0000755000234100017500000000000012174204361021335 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/tools/config/FODS_TO_SAR.xslt0000644000234100017500000012017212174204311024111 0ustar cpascualcpascual00000000000000 PoolPath : Item Version 0.3.0 MacroPath : Item PoolNames ; Item IORegisters Motors Channels Channels Channels Channels CommunicationChannels Channels ; : ; Motor ; Channel Automatic ; : ; True sardana-1.2.0/src/sardana/tools/config/SAR_TO_FODS.xslt0000644000234100017500000013754412174204311024124 0ustar cpascualcpascual00000000000000 Pool Element Parameter Label Format Min Value Min Alarm Min Warning Max Warning Max Alarm Max Value Unit Polling Period Change Event Description -1 Type Pool Name DeviceName Channels Description MeasurementGroup CommunicationChannel CounterTimer ZeroDExpChannel OneDExpChannel TwoDExpChannel PseudoCounter IORegister Motor Type Pool Name File Class Properties Elements : Server MacroServer Description Name Tango Name Type Host Server Description Name Tango Name Path Pools Pool Pool code name description : Type Pool Controller Name DeviceName Axis Description Attributes sardana-1.2.0/src/sardana/tools/config/XLS_TO_SAR.xslt0000644000234100017500000012553312174204311024032 0ustar cpascualcpascual00000000000000 PoolPath : Item Version 0.3.0 : Item MacroPath : Item ; Motors IORegisters Channels Channels Channels Channels CommunicationChannels Channels Automatic ; : ; : ; Motor ; Channel PoolNames ; Item True True sardana-1.2.0/src/sardana/tools/config/fods_to_sar.py0000755000234100017500000000154712174204311024216 0ustar cpascualcpascual00000000000000#!/usr/bin/env python """ The sardana transformation tool. Syntax: python fods_to_sar.py This tool outputs a sardana XML file from an FODS XML file. file.xml must be a valid XML file comming from an OpenOffice spreadsheet in FODS format. """ import sys, os, types from lxml import etree def transform(f): directory = os.path.dirname(os.path.abspath(__file__)) xslt_filename = os.path.join(directory, "FODS_TO_SAR.xslt") t = etree.XSLT(etree.parse(xslt_filename)) if type(f) in types.StringTypes: doc = etree.parse(f) else: doc = f return t(doc) def main(): if len(sys.argv) < 2: print __doc__ sys.exit(1) filename = sys.argv[1] t = transform(filename) print etree.tostring(t, pretty_print=True) if __name__ == "__main__": main() sardana-1.2.0/src/sardana/tools/config/get_pool_config.py0000644000234100017500000001557612174204311025055 0ustar cpascualcpascual00000000000000import PyTango import taurus import csv import sys def checkPoolElements(pool): pool_dev = taurus.Device(pool) # GET CONTROLLER CLASSES pool_ctrl_classes = {} for info in pool_dev['ControllerClassList'].value: ctrl_class, library_path, ctrl_type = info.split() pool_ctrl_classes[ctrl_class] = (library_path, ctrl_type) # GET CONTROLLERS INFO pool_controllers_by_type = {'Motor': [], 'PseudoMotor': [], 'IORegister': [], 'CounterTimer': [], 'PseudoCounter': [], 'ZeroDExpChannel': []} pool_controllers = {} for info in pool_dev['ControllerList'].value: info_splitted = info.split() ctrl_name = info_splitted[0] ctrl_library = info_splitted[-1].replace('(','').replace(')','') ctrl_class = info_splitted[1].rsplit('.')[1].split('/')[0] ctrl_type = '' try: ctrl_type = pool_ctrl_classes[ctrl_class][1] pool_controllers_by_type[ctrl_type].append(ctrl_name) except: pass ctrl_properties = {} ctrl_elements = [] ctrl_pool_elements = [] for prop in pool_dev.get_property_list(ctrl_name+'/*'): prop_name = prop.split('/')[1] prop_value = pool_dev.get_property(prop)[prop] ctrl_properties[prop_name] = ' '.join(prop_value) pool_controllers[ctrl_name] = {} pool_controllers[ctrl_name]['type'] = ctrl_type pool_controllers[ctrl_name]['name'] = ctrl_name pool_controllers[ctrl_name]['file'] = ctrl_library pool_controllers[ctrl_name]['class'] = ctrl_class pool_controllers[ctrl_name]['properties'] = ctrl_properties pool_controllers[ctrl_name]['elements'] = ctrl_elements pool_controllers[ctrl_name]['ctrl_pool_elements'] = ctrl_pool_elements for ctrl_type, controllers in pool_controllers_by_type.iteritems(): if len(controllers) == 0: continue print '\n' print '----------------------------------------------------------------' print len(controllers), ctrl_type, 'CONTROLLERS FOR POOL '+pool print '----------------------------------------------------------------' for ctrl in controllers: details = pool_controllers[ctrl] ###print 'Controller',ctrl,':' ###for k, v in details.iteritems(): ### if k == 'ctrl_pool_elements': ### print '\tElements count:\t'+str(len(v)) ### print '\t'+k+':\t'+str(v) ### ###pool_controllers[ctrl_name]['type'] = ctrl_type ###pool_controllers[ctrl_name]['name'] = ctrl_name ###pool_controllers[ctrl_name]['file'] = ctrl_library ###pool_controllers[ctrl_name]['class'] = ctrl_class ###pool_controllers[ctrl_name]['properties'] = ctrl_properties ###pool_controllers[ctrl_name]['elements'] = ctrl_elements ###pool_controllers[ctrl_name]['ctrl_pool_elements'] = ctrl_pool_elements pool_elements_summary = '('+str(len(details['ctrl_pool_elements']))+')' print '{type}\t{name}\t{file}\t{class}\t{properties}\t{elements}'.format(**details), pool_elements_summary pool_elements = {} pool_elements['ExpChannels'] = pool_dev['ExpChannelList'].value or [] pool_elements['Motors'] = pool_dev['MotorList'].value or [] pool_elements['IORegs'] = pool_dev['IORegisterList'].value or [] pool_instruments = pool_dev['InstrumentList'].value or [] print '\n' print '----------------------------------------------------------------' print len(pool_instruments),'INSTRUMENTS FOR POOL '+pool print '----------------------------------------------------------------' print pool_instruments # CHECK ELEMENTS WITHOUT INSTRUMENT for element_type in pool_elements.keys(): elements = pool_elements[element_type] elements_with_no_instrument = [] for info in elements: info_splitted = info.split() alias = info_splitted[0] dev_name = info_splitted[1] ctrl_name, ctrl_axis = info_splitted[2].replace('(','').replace(')','').split('/') specific_element_type = info_splitted[3] pool_controllers[ctrl_name]['ctrl_pool_elements'].append(alias) if specific_element_type in ['PseudoMotor', 'PseudoCounter']: if len(pool_controllers[ctrl_name]['elements']) == 0: pool_controllers[ctrl_name]['elements'] = ' '.join(info_splitted[4:]) element_dev = taurus.Device(alias) if element_dev['Instrument'].value == '': elements_with_no_instrument.append(alias) if len(elements_with_no_instrument) > 0: print '\n***',element_type,'with no Instrument:',elements_with_no_instrument,'***' print '\n' print '----------------------------------------------------------------' print 'ELEMENTS FOR POOL '+pool print '----------------------------------------------------------------' for element_type in pool_elements.keys(): elements = pool_elements[element_type] print element_type+':',len(elements) print '\n' print '----------------------------------------------------------------' print 'ELEMENTS MEMORIZED ATTRIBUTES AND ATTRIBUTE CONFIGURATIONS FOR POOL '+pool print '----------------------------------------------------------------' db = taurus.Database() for element_type in pool_elements.keys(): elements = pool_elements[element_type] for info in elements: info_splitted = info.split() alias = info_splitted[0] dev_name = info_splitted[1] ctrl_name, ctrl_axis = info_splitted[2].replace('(','').replace(')','').split('/') specific_element_type = info_splitted[3] element_dev = taurus.Device(alias) for attr, attr_dict in db.get_device_attribute_property(element_dev.getNormalName(), element_dev.get_attribute_list()).iteritems(): if len(attr_dict) > 0: print specific_element_type, alias, attr, attr_dict else: if attr.lower() in ['position', 'value']: print '***',specific_element_type, alias, attr, 'NO MEMORIZED ATTRIBUTES OR ATTRIBUTE CONFIGURATIONS ***' if __name__ == '__main__': if len(sys.argv) != 2 or sys.argv[1] == '?': print '----------------------------------------' print 'Invalid number of arguments.' print '' print 'Example of usage:' print ' python get_pool_config pool' print '' print ' where pool is the name of the pool' print '----------------------------------------' pool = sys.argv[1] checkPoolElements(pool) sardana-1.2.0/src/sardana/tools/config/pexpect23.py0000644000234100017500000022424112174204311023524 0ustar cpascualcpascual00000000000000"""Pexpect is a Python module for spawning child applications and controlling them automatically. Pexpect can be used for automating interactive applications such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python require TCL and Expect or require C extensions to be compiled. Pexpect does not use C, Expect, or TCL extensions. It should work on any platform that supports the standard Python pty module. The Pexpect interface focuses on ease of use so that simple tasks are easy. There are two main interfaces to Pexpect -- the function, run() and the class, spawn. You can call the run() function to execute a command and return the output. This is a handy replacement for os.system(). For example:: pexpect.run('ls -la') The more powerful interface is the spawn class. You can use this to spawn an external child command and then interact with the child by sending lines and expecting responses. For example:: child = pexpect.spawn('scp foo myname@host.example.com:.') child.expect ('Password:') child.sendline (mypassword) This works even for commands that ask for passwords or other input outside of the normal stdio streams. Credits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett, Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin, Geoffrey Marshall, Francisco Lourenco, Glen Mabey, Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn (Let me know if I forgot anyone.) Free, open source, and all that good stuff. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Pexpect Copyright (c) 2008 Noah Spurrier http://pexpect.sourceforge.net/ $Id: pexpect.py 507 2007-12-27 02:40:52Z noah $ """ try: import os, sys, time import select import string import re import struct import resource import types import pty import tty import termios import fcntl import errno import traceback import signal except ImportError, e: raise ImportError (str(e) + """ A critical module was not found. Probably this operating system does not support it. Pexpect is intended for UNIX-like operating systems.""") __version__ = '2.3' __revision__ = '$Revision: 399 $' __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', 'which', 'split_command_line', '__version__', '__revision__'] # Exception classes used by this module. class ExceptionPexpect(Exception): """Base class for all exceptions raised by this module. """ def __init__(self, value): self.value = value def __str__(self): return str(self.value) def get_trace(self): """This returns an abbreviated stack trace with lines that only concern the caller. In other words, the stack trace inside the Pexpect module is not included. """ tblist = traceback.extract_tb(sys.exc_info()[2]) #tblist = filter(self.__filter_not_pexpect, tblist) tblist = [item for item in tblist if self.__filter_not_pexpect(item)] tblist = traceback.format_list(tblist) return ''.join(tblist) def __filter_not_pexpect(self, trace_list_item): """This returns True if list item 0 the string 'pexpect.py' in it. """ if trace_list_item[0].find('pexpect.py') == -1: return True else: return False class EOF(ExceptionPexpect): """Raised when EOF is read from a child. This usually means the child has exited.""" class TIMEOUT(ExceptionPexpect): """Raised when a read time exceeds the timeout. """ ##class TIMEOUT_PATTERN(TIMEOUT): ## """Raised when the pattern match time exceeds the timeout. ## This is different than a read TIMEOUT because the child process may ## give output, thus never give a TIMEOUT, but the output ## may never match a pattern. ## """ ##class MAXBUFFER(ExceptionPexpect): ## """Raised when a scan buffer fills before matching an expected pattern.""" def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None): """ This function runs the given command; waits for it to finish; then returns all output as a string. STDERR is included in output. If the full path to the command is not given then the path is searched. Note that lines are terminated by CR/LF (\\r\\n) combination even on UNIX-like systems because this is the standard for pseudo ttys. If you set 'withexitstatus' to true, then run will return a tuple of (command_output, exitstatus). If 'withexitstatus' is false then this returns just command_output. The run() function can often be used instead of creating a spawn instance. For example, the following code uses spawn:: from pexpect import * child = spawn('scp foo myname@host.example.com:.') child.expect ('(?i)password') child.sendline (mypassword) The previous code can be replace with the following:: from pexpect import * run ('scp foo myname@host.example.com:.', events={'(?i)password': mypassword}) Examples ======== Start the apache daemon on the local machine:: from pexpect import * run ("/usr/local/apache/bin/apachectl start") Check in a file using SVN:: from pexpect import * run ("svn ci -m 'automatic commit' my_file.py") Run a command and capture exit status:: from pexpect import * (command_output, exitstatus) = run ('ls -l /bin', withexitstatus=1) Tricky Examples =============== The following will run SSH and execute 'ls -l' on the remote machine. The password 'secret' will be sent if the '(?i)password' pattern is ever seen:: run ("ssh username@machine.example.com 'ls -l'", events={'(?i)password':'secret\\n'}) This will start mencoder to rip a video from DVD. This will also display progress ticks every 5 seconds as it runs. For example:: from pexpect import * def print_ticks(d): print d['event_count'], run ("mencoder dvd://1 -o video.avi -oac copy -ovc copy", events={TIMEOUT:print_ticks}, timeout=5) The 'events' argument should be a dictionary of patterns and responses. Whenever one of the patterns is seen in the command out run() will send the associated response string. Note that you should put newlines in your string if Enter is necessary. The responses may also contain callback functions. Any callback is function that takes a dictionary as an argument. The dictionary contains all the locals from the run() function, so you can access the child spawn object or any other variable defined in run() (event_count, child, and extra_args are the most useful). A callback may return True to stop the current run process otherwise run() continues until the next event. A callback may also return a string which will be sent to the child. 'extra_args' is not used by directly run(). It provides a way to pass data to a callback function through run() through the locals dictionary passed to a callback. """ if timeout == -1: child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env) else: child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, cwd=cwd, env=env) if events is not None: patterns = events.keys() responses = events.values() else: patterns=None # We assume that EOF or TIMEOUT will save us. responses=None child_result_list = [] event_count = 0 while 1: try: index = child.expect (patterns) if type(child.after) in types.StringTypes: child_result_list.append(child.before + child.after) else: # child.after may have been a TIMEOUT or EOF, so don't cat those. child_result_list.append(child.before) if type(responses[index]) in types.StringTypes: child.send(responses[index]) elif type(responses[index]) is types.FunctionType: callback_result = responses[index](locals()) sys.stdout.flush() if type(callback_result) in types.StringTypes: child.send(callback_result) elif callback_result: break else: raise TypeError ('The callback must be a string or function type.') event_count = event_count + 1 except TIMEOUT, e: child_result_list.append(child.before) break except EOF, e: child_result_list.append(child.before) break child_result = ''.join(child_result_list) if withexitstatus: child.close() return (child_result, child.exitstatus) else: return child_result class spawn (object): """This is the main class interface for Pexpect. Use this class to start and control child applications. """ def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None): """This is the constructor. The command parameter may be a string that includes a command and any arguments to the command. For example:: child = pexpect.spawn ('/usr/bin/ftp') child = pexpect.spawn ('/usr/bin/ssh user@example.com') child = pexpect.spawn ('ls -latr /tmp') You may also construct it with a list of arguments like so:: child = pexpect.spawn ('/usr/bin/ftp', []) child = pexpect.spawn ('/usr/bin/ssh', ['user@example.com']) child = pexpect.spawn ('ls', ['-latr', '/tmp']) After this the child application will be created and will be ready to talk to. For normal use, see expect() and send() and sendline(). Remember that Pexpect does NOT interpret shell meta characters such as redirect, pipe, or wild cards (>, |, or *). This is a common mistake. If you want to run a command and pipe it through another command then you must also start a shell. For example:: child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"') child.expect(pexpect.EOF) The second form of spawn (where you pass a list of arguments) is useful in situations where you wish to spawn a command and pass it its own argument list. This can make syntax more clear. For example, the following is equivalent to the previous example:: shell_cmd = 'ls -l | grep LOG > log_list.txt' child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) child.expect(pexpect.EOF) The maxread attribute sets the read buffer size. This is maximum number of bytes that Pexpect will try to read from a TTY at one time. Setting the maxread size to 1 will turn off buffering. Setting the maxread value higher may help performance in cases where large amounts of output are read back from the child. This feature is useful in conjunction with searchwindowsize. The searchwindowsize attribute sets the how far back in the incomming seach buffer Pexpect will search for pattern matches. Every time Pexpect reads some data from the child it will append the data to the incomming buffer. The default is to search from the beginning of the imcomming buffer each time new data is read from the child. But this is very inefficient if you are running a command that generates a large amount of data where you want to match The searchwindowsize does not effect the size of the incomming data buffer. You will still have access to the full buffer after expect() returns. The logfile member turns on or off logging. All input and output will be copied to the given file object. Set logfile to None to stop logging. This is the default. Set logfile to sys.stdout to echo everything to standard output. The logfile is flushed after each write. Example log input and output to a file:: child = pexpect.spawn('some_command') fout = file('mylog.txt','w') child.logfile = fout Example log to stdout:: child = pexpect.spawn('some_command') child.logfile = sys.stdout The logfile_read and logfile_send members can be used to separately log the input from the child and output sent to the child. Sometimes you don't want to see everything you write to the child. You only want to log what the child sends back. For example:: child = pexpect.spawn('some_command') child.logfile_read = sys.stdout To separately log output sent to the child use logfile_send:: self.logfile_send = fout The delaybeforesend helps overcome a weird behavior that many users were experiencing. The typical problem was that a user would expect() a "Password:" prompt and then immediately call sendline() to send the password. The user would then see that their password was echoed back to them. Passwords don't normally echo. The problem is caused by the fact that most applications print out the "Password" prompt and then turn off stdin echo, but if you send your password before the application turned off echo, then you get your password echoed. Normally this wouldn't be a problem when interacting with a human at a real keyboard. If you introduce a slight delay just before writing then this seems to clear up the problem. This was such a common problem for many users that I decided that the default pexpect behavior should be to sleep just before writing to the child application. 1/20th of a second (50 ms) seems to be enough to clear up the problem. You can set delaybeforesend to 0 to return to the old behavior. Most Linux machines don't like this to be below 0.03. I don't know why. Note that spawn is clever about finding commands on your path. It uses the same logic that "which" uses to find executables. If you wish to get the exit status of the child you must call the close() method. The exit or signal status of the child will be stored in self.exitstatus or self.signalstatus. If the child exited normally then exitstatus will store the exit return code and signalstatus will be None. If the child was terminated abnormally with a signal then signalstatus will store the signal value and exitstatus will be None. If you need more detail you can also read the self.status member which stores the status returned by os.waitpid. You can interpret this using os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. """ self.STDIN_FILENO = pty.STDIN_FILENO self.STDOUT_FILENO = pty.STDOUT_FILENO self.STDERR_FILENO = pty.STDERR_FILENO self.stdin = sys.stdin self.stdout = sys.stdout self.stderr = sys.stderr self.searcher = None self.ignorecase = False self.before = None self.after = None self.match = None self.match_index = None self.terminated = True self.exitstatus = None self.signalstatus = None self.status = None # status returned by os.waitpid self.flag_eof = False self.pid = None self.child_fd = -1 # initially closed self.timeout = timeout self.delimiter = EOF self.logfile = logfile self.logfile_read = None # input from child (read_nonblocking) self.logfile_send = None # output to send (send, sendline) self.maxread = maxread # max bytes to read at one time into buffer self.buffer = '' # This is the read buffer. See maxread. self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched. # Most Linux machines don't like delaybeforesend to be below 0.03 (30 ms). self.delaybeforesend = 0.05 # Sets sleep time used just before sending data to child. Time in seconds. self.delayafterclose = 0.1 # Sets delay in close() method to allow kernel time to update process status. Time in seconds. self.delayafterterminate = 0.1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds. self.softspace = False # File-like object. self.name = '<' + repr(self) + '>' # File-like object. self.encoding = None # File-like object. self.closed = True # File-like object. self.cwd = cwd self.env = env self.__irix_hack = (sys.platform.lower().find('irix')>=0) # This flags if we are running on irix # Solaris uses internal __fork_pty(). All others use pty.fork(). if (sys.platform.lower().find('solaris')>=0) or (sys.platform.lower().find('sunos5')>=0): self.use_native_pty_fork = False else: self.use_native_pty_fork = True # allow dummy instances for subclasses that may not use command or args. if command is None: self.command = None self.args = None self.name = '' else: self._spawn (command, args) def __del__(self): """This makes sure that no system resources are left open. Python only garbage collects Python objects. OS file descriptors are not Python objects, so they must be handled explicitly. If the child file descriptor was opened outside of this class (passed to the constructor) then this does not close it. """ if not self.closed: # It is possible for __del__ methods to execute during the # teardown of the Python VM itself. Thus self.close() may # trigger an exception because os.close may be None. # -- Fernando Perez try: self.close() except AttributeError: pass def __str__(self): """This returns a human-readable string that represents the state of the object. """ s = [] s.append(repr(self)) s.append('version: ' + __version__ + ' (' + __revision__ + ')') s.append('command: ' + str(self.command)) s.append('args: ' + str(self.args)) s.append('searcher: ' + str(self.searcher)) s.append('buffer (last 100 chars): ' + str(self.buffer)[-100:]) s.append('before (last 100 chars): ' + str(self.before)[-100:]) s.append('after: ' + str(self.after)) s.append('match: ' + str(self.match)) s.append('match_index: ' + str(self.match_index)) s.append('exitstatus: ' + str(self.exitstatus)) s.append('flag_eof: ' + str(self.flag_eof)) s.append('pid: ' + str(self.pid)) s.append('child_fd: ' + str(self.child_fd)) s.append('closed: ' + str(self.closed)) s.append('timeout: ' + str(self.timeout)) s.append('delimiter: ' + str(self.delimiter)) s.append('logfile: ' + str(self.logfile)) s.append('logfile_read: ' + str(self.logfile_read)) s.append('logfile_send: ' + str(self.logfile_send)) s.append('maxread: ' + str(self.maxread)) s.append('ignorecase: ' + str(self.ignorecase)) s.append('searchwindowsize: ' + str(self.searchwindowsize)) s.append('delaybeforesend: ' + str(self.delaybeforesend)) s.append('delayafterclose: ' + str(self.delayafterclose)) s.append('delayafterterminate: ' + str(self.delayafterterminate)) return '\n'.join(s) def _spawn(self,command,args=[]): """This starts the given command in a child process. This does all the fork/exec type of stuff for a pty. This is called by __init__. If args is empty then command will be parsed (split on spaces) and args will be set to parsed arguments. """ # The pid and child_fd of this object get set by this method. # Note that it is difficult for this method to fail. # You cannot detect if the child process cannot start. # So the only way you can tell if the child process started # or not is to try to read from the file descriptor. If you get # EOF immediately then it means that the child is already dead. # That may not necessarily be bad because you may haved spawned a child # that performs some task; creates no stdout output; and then dies. # If command is an int type then it may represent a file descriptor. if type(command) == type(0): raise ExceptionPexpect ('Command is an int type. If this is a file descriptor then maybe you want to use fdpexpect.fdspawn which takes an existing file descriptor instead of a command string.') if type (args) != type([]): raise TypeError ('The argument, args, must be a list.') if args == []: self.args = split_command_line(command) self.command = self.args[0] else: self.args = args[:] # work with a copy self.args.insert (0, command) self.command = command command_with_path = which(self.command) if command_with_path is None: raise ExceptionPexpect ('The command was not found or was not executable: %s.' % self.command) self.command = command_with_path self.args[0] = self.command self.name = '<' + ' '.join (self.args) + '>' assert self.pid is None, 'The pid member should be None.' assert self.command is not None, 'The command member should not be None.' if self.use_native_pty_fork: try: self.pid, self.child_fd = pty.fork() except OSError, e: raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e)) else: # Use internal __fork_pty self.pid, self.child_fd = self.__fork_pty() if self.pid == 0: # Child try: self.child_fd = sys.stdout.fileno() # used by setwinsize() self.setwinsize(24, 80) except: # Some platforms do not like setwinsize (Cygwin). # This will cause problem when running applications that # are very picky about window size. # This is a serious limitation, but not a show stopper. pass # Do not allow child to inherit open file descriptors from parent. max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] for i in range (3, max_fd): try: os.close (i) except OSError: pass # I don't know why this works, but ignoring SIGHUP fixes a # problem when trying to start a Java daemon with sudo # (specifically, Tomcat). signal.signal(signal.SIGHUP, signal.SIG_IGN) if self.cwd is not None: os.chdir(self.cwd) if self.env is None: os.execv(self.command, self.args) else: os.execvpe(self.command, self.args, self.env) # Parent self.terminated = False self.closed = False def __fork_pty(self): """This implements a substitute for the forkpty system call. This should be more portable than the pty.fork() function. Specifically, this should work on Solaris. Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to resolve the issue with Python's pty.fork() not supporting Solaris, particularly ssh. Based on patch to posixmodule.c authored by Noah Spurrier:: http://mail.python.org/pipermail/python-dev/2003-May/035281.html """ parent_fd, child_fd = os.openpty() if parent_fd < 0 or child_fd < 0: raise ExceptionPexpect, "Error! Could not open pty with os.openpty()." pid = os.fork() if pid < 0: raise ExceptionPexpect, "Error! Failed os.fork()." elif pid == 0: # Child. os.close(parent_fd) self.__pty_make_controlling_tty(child_fd) os.dup2(child_fd, 0) os.dup2(child_fd, 1) os.dup2(child_fd, 2) if child_fd > 2: os.close(child_fd) else: # Parent. os.close(child_fd) return pid, parent_fd def __pty_make_controlling_tty(self, tty_fd): """This makes the pseudo-terminal the controlling tty. This should be more portable than the pty.fork() function. Specifically, this should work on Solaris. """ child_name = os.ttyname(tty_fd) # Disconnect from controlling tty if still connected. fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); if fd >= 0: os.close(fd) os.setsid() # Verify we are disconnected from controlling tty try: fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); if fd >= 0: os.close(fd) raise ExceptionPexpect, "Error! We are not disconnected from a controlling tty." except: # Good! We are disconnected from a controlling tty. pass # Verify we can open child pty. fd = os.open(child_name, os.O_RDWR); if fd < 0: raise ExceptionPexpect, "Error! Could not open child pty, " + child_name else: os.close(fd) # Verify we now have a controlling tty. fd = os.open("/dev/tty", os.O_WRONLY) if fd < 0: raise ExceptionPexpect, "Error! Could not open controlling tty, /dev/tty" else: os.close(fd) def fileno (self): # File-like object. """This returns the file descriptor of the pty for the child. """ return self.child_fd def close (self, force=True): # File-like object. """This closes the connection with the child application. Note that calling close() more than once is valid. This emulates standard Python behavior with files. Set force to True if you want to make sure that the child is terminated (SIGKILL is sent if the child ignores SIGHUP and SIGINT). """ if not self.closed: self.flush() os.close (self.child_fd) time.sleep(self.delayafterclose) # Give kernel time to update process status. if self.isalive(): if not self.terminate(force): raise ExceptionPexpect ('close() could not terminate the child using terminate()') self.child_fd = -1 self.closed = True #self.pid = None def flush (self): # File-like object. """This does nothing. It is here to support the interface for a File-like object. """ pass def isatty (self): # File-like object. """This returns True if the file descriptor is open and connected to a tty(-like) device, else False. """ return os.isatty(self.child_fd) def waitnoecho (self, timeout=-1): """This waits until the terminal ECHO flag is set False. This returns True if the echo mode is off. This returns False if the ECHO flag was not set False before the timeout. This can be used to detect when the child is waiting for a password. Usually a child application will turn off echo mode when it is waiting for the user to enter a password. For example, instead of expecting the "password:" prompt you can wait for the child to set ECHO off:: p = pexpect.spawn ('ssh user@example.com') p.waitnoecho() p.sendline(mypassword) If timeout is None then this method to block forever until ECHO flag is False. """ if timeout == -1: timeout = self.timeout if timeout is not None: end_time = time.time() + timeout while True: if not self.getecho(): return True if timeout < 0 and timeout is not None: return False if timeout is not None: timeout = end_time - time.time() time.sleep(0.1) def getecho (self): """This returns the terminal echo mode. This returns True if echo is on or False if echo is off. Child applications that are expecting you to enter a password often set ECHO False. See waitnoecho(). """ attr = termios.tcgetattr(self.child_fd) if attr[3] & termios.ECHO: return True return False def setecho (self, state): """This sets the terminal echo mode on or off. Note that anything the child sent before the echo will be lost, so you should be sure that your input buffer is empty before you call setecho(). For example, the following will work as expected:: p = pexpect.spawn('cat') p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). p.expect (['1234']) p.expect (['1234']) p.setecho(False) # Turn off tty echo p.sendline ('abcd') # We will set this only once (echoed by cat). p.sendline ('wxyz') # We will set this only once (echoed by cat) p.expect (['abcd']) p.expect (['wxyz']) The following WILL NOT WORK because the lines sent before the setecho will be lost:: p = pexpect.spawn('cat') p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). p.setecho(False) # Turn off tty echo p.sendline ('abcd') # We will set this only once (echoed by cat). p.sendline ('wxyz') # We will set this only once (echoed by cat) p.expect (['1234']) p.expect (['1234']) p.expect (['abcd']) p.expect (['wxyz']) """ self.child_fd attr = termios.tcgetattr(self.child_fd) if state: attr[3] = attr[3] | termios.ECHO else: attr[3] = attr[3] & ~termios.ECHO # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent # and blocked on some platforms. TCSADRAIN is probably ideal if it worked. termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) def read_nonblocking (self, size = 1, timeout = -1): """This reads at most size characters from the child application. It includes a timeout. If the read does not complete within the timeout period then a TIMEOUT exception is raised. If the end of file is read then an EOF exception will be raised. If a log file was set using setlog() then all data will also be written to the log file. If timeout is None then the read may block indefinitely. If timeout is -1 then the self.timeout value is used. If timeout is 0 then the child is polled and if there was no data immediately ready then this will raise a TIMEOUT exception. The timeout refers only to the amount of time to read at least one character. This is not effected by the 'size' parameter, so if you call read_nonblocking(size=100, timeout=30) and only one character is available right away then one character will be returned immediately. It will not wait for 30 seconds for another 99 characters to come in. This is a wrapper around os.read(). It uses select.select() to implement the timeout. """ if self.closed: raise ValueError ('I/O operation on closed file in read_nonblocking().') if timeout == -1: timeout = self.timeout # Note that some systems such as Solaris do not give an EOF when # the child dies. In fact, you can still try to read # from the child_fd -- it will block forever or until TIMEOUT. # For this case, I test isalive() before doing any reading. # If isalive() is false, then I pretend that this is the same as EOF. if not self.isalive(): r,w,e = self.__select([self.child_fd], [], [], 0) # timeout of 0 means "poll" if not r: self.flag_eof = True raise EOF ('End Of File (EOF) in read_nonblocking(). Braindead platform.') elif self.__irix_hack: # This is a hack for Irix. It seems that Irix requires a long delay before checking isalive. # This adds a 2 second delay, but only when the child is terminated. r, w, e = self.__select([self.child_fd], [], [], 2) if not r and not self.isalive(): self.flag_eof = True raise EOF ('End Of File (EOF) in read_nonblocking(). Pokey platform.') r,w,e = self.__select([self.child_fd], [], [], timeout) if not r: if not self.isalive(): # Some platforms, such as Irix, will claim that their processes are alive; # then timeout on the select; and then finally admit that they are not alive. self.flag_eof = True raise EOF ('End of File (EOF) in read_nonblocking(). Very pokey platform.') else: raise TIMEOUT ('Timeout exceeded in read_nonblocking().') if self.child_fd in r: try: s = os.read(self.child_fd, size) except OSError, e: # Linux does this self.flag_eof = True raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.') if s == '': # BSD style self.flag_eof = True raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.') if self.logfile is not None: self.logfile.write (s) self.logfile.flush() if self.logfile_read is not None: self.logfile_read.write (s) self.logfile_read.flush() return s raise ExceptionPexpect ('Reached an unexpected state in read_nonblocking().') def read (self, size = -1): # File-like object. """This reads at most "size" bytes from the file (less if the read hits EOF before obtaining size bytes). If the size argument is negative or omitted, read all data until EOF is reached. The bytes are returned as a string object. An empty string is returned when EOF is encountered immediately. """ if size == 0: return '' if size < 0: self.expect (self.delimiter) # delimiter default is EOF return self.before # I could have done this more directly by not using expect(), but # I deliberately decided to couple read() to expect() so that # I would catch any bugs early and ensure consistant behavior. # It's a little less efficient, but there is less for me to # worry about if I have to later modify read() or expect(). # Note, it's OK if size==-1 in the regex. That just means it # will never match anything in which case we stop only on EOF. cre = re.compile('.{%d}' % size, re.DOTALL) index = self.expect ([cre, self.delimiter]) # delimiter default is EOF if index == 0: return self.after ### self.before should be ''. Should I assert this? return self.before def readline (self, size = -1): # File-like object. """This reads and returns one entire line. A trailing newline is kept in the string, but may be absent when a file ends with an incomplete line. Note: This readline() looks for a \\r\\n pair even on UNIX because this is what the pseudo tty device returns. So contrary to what you may expect you will receive the newline as \\r\\n. An empty string is returned when EOF is hit immediately. Currently, the size argument is mostly ignored, so this behavior is not standard for a file-like object. If size is 0 then an empty string is returned. """ if size == 0: return '' index = self.expect (['\r\n', self.delimiter]) # delimiter default is EOF if index == 0: return self.before + '\r\n' else: return self.before def __iter__ (self): # File-like object. """This is to support iterators over a file-like object. """ return self def next (self): # File-like object. """This is to support iterators over a file-like object. """ result = self.readline() if result == "": raise StopIteration return result def readlines (self, sizehint = -1): # File-like object. """This reads until EOF using readline() and returns a list containing the lines thus read. The optional "sizehint" argument is ignored. """ lines = [] while True: line = self.readline() if not line: break lines.append(line) return lines def write(self, s): # File-like object. """This is similar to send() except that there is no return value. """ self.send (s) def writelines (self, sequence): # File-like object. """This calls write() for each element in the sequence. The sequence can be any iterable object producing strings, typically a list of strings. This does not add line separators There is no return value. """ for s in sequence: self.write (s) def send(self, s): """This sends a string to the child process. This returns the number of bytes written. If a log file was set then the data is also written to the log. """ time.sleep(self.delaybeforesend) if self.logfile is not None: self.logfile.write (s) self.logfile.flush() if self.logfile_send is not None: self.logfile_send.write (s) self.logfile_send.flush() c = os.write(self.child_fd, s) return c def sendline(self, s=''): """This is like send(), but it adds a line feed (os.linesep). This returns the number of bytes written. """ n = self.send(s) n = n + self.send (os.linesep) return n def sendcontrol(self, char): """This sends a control character to the child such as Ctrl-C or Ctrl-D. For example, to send a Ctrl-G (ASCII 7):: child.sendcontrol('g') See also, sendintr() and sendeof(). """ char = char.lower() a = ord(char) if a>=97 and a<=122: a = a - ord('a') + 1 return self.send (chr(a)) d = {'@':0, '`':0, '[':27, '{':27, '\\':28, '|':28, ']':29, '}': 29, '^':30, '~':30, '_':31, '?':127} if char not in d: return 0 return self.send (chr(d[char])) def sendeof(self): """This sends an EOF to the child. This sends a character which causes the pending parent output buffer to be sent to the waiting child program without waiting for end-of-line. If it is the first character of the line, the read() in the user program returns 0, which signifies end-of-file. This means to work as expected a sendeof() has to be called at the beginning of a line. This method does not send a newline. It is the responsibility of the caller to ensure the eof is sent at the beginning of a line. """ ### Hmmm... how do I send an EOF? ###C if ((m = write(pty, *buf, p - *buf)) < 0) ###C return (errno == EWOULDBLOCK) ? n : -1; #fd = sys.stdin.fileno() #old = termios.tcgetattr(fd) # remember current state #attr = termios.tcgetattr(fd) #attr[3] = attr[3] | termios.ICANON # ICANON must be set to recognize EOF #try: # use try/finally to ensure state gets restored # termios.tcsetattr(fd, termios.TCSADRAIN, attr) # if hasattr(termios, 'CEOF'): # os.write (self.child_fd, '%c' % termios.CEOF) # else: # # Silly platform does not define CEOF so assume CTRL-D # os.write (self.child_fd, '%c' % 4) #finally: # restore state # termios.tcsetattr(fd, termios.TCSADRAIN, old) if hasattr(termios, 'VEOF'): char = termios.tcgetattr(self.child_fd)[6][termios.VEOF] else: # platform does not define VEOF so assume CTRL-D char = chr(4) self.send(char) def sendintr(self): """This sends a SIGINT to the child. It does not require the SIGINT to be the first character on a line. """ if hasattr(termios, 'VINTR'): char = termios.tcgetattr(self.child_fd)[6][termios.VINTR] else: # platform does not define VINTR so assume CTRL-C char = chr(3) self.send (char) def eof (self): """This returns True if the EOF exception was ever raised. """ return self.flag_eof def terminate(self, force=False): """This forces a child process to terminate. It starts nicely with SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This returns True if the child was terminated. This returns False if the child could not be terminated. """ if not self.isalive(): return True try: self.kill(signal.SIGHUP) time.sleep(self.delayafterterminate) if not self.isalive(): return True self.kill(signal.SIGCONT) time.sleep(self.delayafterterminate) if not self.isalive(): return True self.kill(signal.SIGINT) time.sleep(self.delayafterterminate) if not self.isalive(): return True if force: self.kill(signal.SIGKILL) time.sleep(self.delayafterterminate) if not self.isalive(): return True else: return False return False except OSError, e: # I think there are kernel timing issues that sometimes cause # this to happen. I think isalive() reports True, but the # process is dead to the kernel. # Make one last attempt to see if the kernel is up to date. time.sleep(self.delayafterterminate) if not self.isalive(): return True else: return False def wait(self): """This waits until the child exits. This is a blocking call. This will not read any data from the child, so this will block forever if the child has unread output and has terminated. In other words, the child may have printed output then called exit(); but, technically, the child is still alive until its output is read. """ if self.isalive(): pid, status = os.waitpid(self.pid, 0) else: raise ExceptionPexpect ('Cannot wait for dead child process.') self.exitstatus = os.WEXITSTATUS(status) if os.WIFEXITED (status): self.status = status self.exitstatus = os.WEXITSTATUS(status) self.signalstatus = None self.terminated = True elif os.WIFSIGNALED (status): self.status = status self.exitstatus = None self.signalstatus = os.WTERMSIG(status) self.terminated = True elif os.WIFSTOPPED (status): raise ExceptionPexpect ('Wait was called for a child process that is stopped. This is not supported. Is some other process attempting job control with our child pid?') return self.exitstatus def isalive(self): """This tests if the child process is running or not. This is non-blocking. If the child was terminated then this will read the exitstatus or signalstatus of the child. This returns True if the child process appears to be running or False if not. It can take literally SECONDS for Solaris to return the right status. """ if self.terminated: return False if self.flag_eof: # This is for Linux, which requires the blocking form of waitpid to get # status of a defunct process. This is super-lame. The flag_eof would have # been set in read_nonblocking(), so this should be safe. waitpid_options = 0 else: waitpid_options = os.WNOHANG try: pid, status = os.waitpid(self.pid, waitpid_options) except OSError, e: # No child processes if e[0] == errno.ECHILD: raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') else: raise e # I have to do this twice for Solaris. I can't even believe that I figured this out... # If waitpid() returns 0 it means that no child process wishes to # report, and the value of status is undefined. if pid == 0: try: pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris! except OSError, e: # This should never happen... if e[0] == errno.ECHILD: raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') else: raise e # If pid is still 0 after two calls to waitpid() then # the process really is alive. This seems to work on all platforms, except # for Irix which seems to require a blocking call on waitpid or select, so I let read_nonblocking # take care of this situation (unfortunately, this requires waiting through the timeout). if pid == 0: return True if pid == 0: return True if os.WIFEXITED (status): self.status = status self.exitstatus = os.WEXITSTATUS(status) self.signalstatus = None self.terminated = True elif os.WIFSIGNALED (status): self.status = status self.exitstatus = None self.signalstatus = os.WTERMSIG(status) self.terminated = True elif os.WIFSTOPPED (status): raise ExceptionPexpect ('isalive() encountered condition where child process is stopped. This is not supported. Is some other process attempting job control with our child pid?') return False def kill(self, sig): """This sends the given signal to the child application. In keeping with UNIX tradition it has a misleading name. It does not necessarily kill the child unless you send the right signal. """ # Same as os.kill, but the pid is given for you. if self.isalive(): os.kill(self.pid, sig) def compile_pattern_list(self, patterns): """This compiles a pattern-string or a list of pattern-strings. Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of those. Patterns may also be None which results in an empty list (you might do this if waiting for an EOF or TIMEOUT condition without expecting any pattern). This is used by expect() when calling expect_list(). Thus expect() is nothing more than:: cpl = self.compile_pattern_list(pl) return self.expect_list(cpl, timeout) If you are using expect() within a loop it may be more efficient to compile the patterns first and then call expect_list(). This avoid calls in a loop to compile_pattern_list():: cpl = self.compile_pattern_list(my_pattern) while some_condition: ... i = self.expect_list(clp, timeout) ... """ if patterns is None: return [] if type(patterns) is not types.ListType: patterns = [patterns] compile_flags = re.DOTALL # Allow dot to match \n if self.ignorecase: compile_flags = compile_flags | re.IGNORECASE compiled_pattern_list = [] for p in patterns: if type(p) in types.StringTypes: compiled_pattern_list.append(re.compile(p, compile_flags)) elif p is EOF: compiled_pattern_list.append(EOF) elif p is TIMEOUT: compiled_pattern_list.append(TIMEOUT) elif type(p) is type(re.compile('')): compiled_pattern_list.append(p) else: raise TypeError ('Argument must be one of StringTypes, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p))) return compiled_pattern_list def expect(self, pattern, timeout = -1, searchwindowsize=None): """This seeks through the stream until a pattern is matched. The pattern is overloaded and may take several types. The pattern can be a StringType, EOF, a compiled re, or a list of any of those types. Strings will be compiled to re types. This returns the index into the pattern list. If the pattern was not a list this returns index 0 on a successful match. This may raise exceptions for EOF or TIMEOUT. To avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern list. That will cause expect to match an EOF or TIMEOUT condition instead of raising an exception. If you pass a list of patterns and more than one matches, the first match in the stream is chosen. If more than one pattern matches at that point, the leftmost in the pattern list is chosen. For example:: # the input is 'foobar' index = p.expect (['bar', 'foo', 'foobar']) # returns 1 ('foo') even though 'foobar' is a "better" match Please note, however, that buffering can affect this behavior, since input arrives in unpredictable chunks. For example:: # the input is 'foobar' index = p.expect (['foobar', 'foo']) # returns 0 ('foobar') if all input is available at once, # but returs 1 ('foo') if parts of the final 'bar' arrive late After a match is found the instance attributes 'before', 'after' and 'match' will be set. You can see all the data read before the match in 'before'. You can see the data that was matched in 'after'. The re.MatchObject used in the re match will be in 'match'. If an error occurred then 'before' will be set to all the data read so far and 'after' and 'match' will be None. If timeout is -1 then timeout will be set to the self.timeout value. A list entry may be EOF or TIMEOUT instead of a string. This will catch these exceptions and return the index of the list entry instead of raising the exception. The attribute 'after' will be set to the exception type. The attribute 'match' will be None. This allows you to write code like this:: index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) if index == 0: do_something() elif index == 1: do_something_else() elif index == 2: do_some_other_thing() elif index == 3: do_something_completely_different() instead of code like this:: try: index = p.expect (['good', 'bad']) if index == 0: do_something() elif index == 1: do_something_else() except EOF: do_some_other_thing() except TIMEOUT: do_something_completely_different() These two forms are equivalent. It all depends on what you want. You can also just expect the EOF if you are waiting for all output of a child to finish. For example:: p = pexpect.spawn('/bin/ls') p.expect (pexpect.EOF) print p.before If you are trying to optimize for speed then see expect_list(). """ compiled_pattern_list = self.compile_pattern_list(pattern) return self.expect_list(compiled_pattern_list, timeout, searchwindowsize) def expect_list(self, pattern_list, timeout = -1, searchwindowsize = -1): """This takes a list of compiled regular expressions and returns the index into the pattern_list that matched the child output. The list may also contain EOF or TIMEOUT (which are not compiled regular expressions). This method is similar to the expect() method except that expect_list() does not recompile the pattern list on every call. This may help if you are trying to optimize for speed, otherwise just use the expect() method. This is called by expect(). If timeout==-1 then the self.timeout value is used. If searchwindowsize==-1 then the self.searchwindowsize value is used. """ return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize) def expect_exact(self, pattern_list, timeout = -1, searchwindowsize = -1): """This is similar to expect(), but uses plain string matching instead of compiled regular expressions in 'pattern_list'. The 'pattern_list' may be a string; a list or other sequence of strings; or TIMEOUT and EOF. This call might be faster than expect() for two reasons: string searching is faster than RE matching and it is possible to limit the search to just the end of the input buffer. This method is also useful when you don't want to have to worry about escaping regular expression characters that you want to match.""" if type(pattern_list) in types.StringTypes or pattern_list in (TIMEOUT, EOF): pattern_list = [pattern_list] return self.expect_loop(searcher_string(pattern_list), timeout, searchwindowsize) def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): """This is the common loop used inside expect. The 'searcher' should be an instance of searcher_re or searcher_string, which describes how and what to search for in the input. See expect() for other arguments, return value and exceptions. """ self.searcher = searcher if timeout == -1: timeout = self.timeout if timeout is not None: end_time = time.time() + timeout if searchwindowsize == -1: searchwindowsize = self.searchwindowsize try: incoming = self.buffer freshlen = len(incoming) while True: # Keep reading until exception or return. index = searcher.search(incoming, freshlen, searchwindowsize) if index >= 0: self.buffer = incoming[searcher.end : ] self.before = incoming[ : searcher.start] self.after = incoming[searcher.start : searcher.end] self.match = searcher.match self.match_index = index return self.match_index # No match at this point if timeout < 0 and timeout is not None: raise TIMEOUT ('Timeout exceeded in expect_any().') # Still have time left, so read more data c = self.read_nonblocking (self.maxread, timeout) freshlen = len(c) time.sleep (0.0001) incoming = incoming + c if timeout is not None: timeout = end_time - time.time() except EOF, e: self.buffer = '' self.before = incoming self.after = EOF index = searcher.eof_index if index >= 0: self.match = EOF self.match_index = index return self.match_index else: self.match = None self.match_index = None raise EOF (str(e) + '\n' + str(self)) except TIMEOUT, e: self.buffer = incoming self.before = incoming self.after = TIMEOUT index = searcher.timeout_index if index >= 0: self.match = TIMEOUT self.match_index = index return self.match_index else: self.match = None self.match_index = None raise TIMEOUT (str(e) + '\n' + str(self)) except: self.before = incoming self.after = None self.match = None self.match_index = None raise def getwinsize(self): """This returns the terminal window size of the child tty. The return value is a tuple of (rows, cols). """ TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912L) s = struct.pack('HHHH', 0, 0, 0, 0) x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s) return struct.unpack('HHHH', x)[0:2] def setwinsize(self, r, c): """This sets the terminal window size of the child tty. This will cause a SIGWINCH signal to be sent to the child. This does not change the physical window size. It changes the size reported to TTY-aware applications like vi or curses -- applications that respond to the SIGWINCH signal. """ # Check for buggy platforms. Some Python versions on some platforms # (notably OSF1 Alpha and RedHat 7.1) truncate the value for # termios.TIOCSWINSZ. It is not clear why this happens. # These platforms don't seem to handle the signed int very well; # yet other platforms like OpenBSD have a large negative value for # TIOCSWINSZ and they don't have a truncate problem. # Newer versions of Linux have totally different values for TIOCSWINSZ. # Note that this fix is a hack. TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2. TIOCSWINSZ = -2146929561 # Same bits, but with sign. # Note, assume ws_xpixel and ws_ypixel are zero. s = struct.pack('HHHH', r, c, 0, 0) fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) def interact(self, escape_character = chr(29), input_filter = None, output_filter = None): """This gives control of the child process to the interactive user (the human at the keyboard). Keystrokes are sent to the child process, and the stdout and stderr output of the child process is printed. This simply echos the child stdout and child stderr to the real stdout and it echos the real stdin to the child stdin. When the user types the escape_character this method will stop. The default for escape_character is ^]. This should not be confused with ASCII 27 -- the ESC character. ASCII 29 was chosen for historical merit because this is the character used by 'telnet' as the escape character. The escape_character will not be sent to the child process. You may pass in optional input and output filter functions. These functions should take a string and return a string. The output_filter will be passed all the output from the child process. The input_filter will be passed all the keyboard input from the user. The input_filter is run BEFORE the check for the escape_character. Note that if you change the window size of the parent the SIGWINCH signal will not be passed through to the child. If you want the child window size to change when the parent's window size changes then do something like the following example:: import pexpect, struct, fcntl, termios, signal, sys def sigwinch_passthrough (sig, data): s = struct.pack("HHHH", 0, 0, 0, 0) a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s)) global p p.setwinsize(a[0],a[1]) p = pexpect.spawn('/bin/bash') # Note this is global and used in sigwinch_passthrough. signal.signal(signal.SIGWINCH, sigwinch_passthrough) p.interact() """ # Flush the buffer. self.stdout.write (self.buffer) self.stdout.flush() self.buffer = '' mode = tty.tcgetattr(self.STDIN_FILENO) tty.setraw(self.STDIN_FILENO) try: self.__interact_copy(escape_character, input_filter, output_filter) finally: tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) def __interact_writen(self, fd, data): """This is used by the interact() method. """ while data != '' and self.isalive(): n = os.write(fd, data) data = data[n:] def __interact_read(self, fd): """This is used by the interact() method. """ return os.read(fd, 1000) def __interact_copy(self, escape_character = None, input_filter = None, output_filter = None): """This is used by the interact() method. """ while self.isalive(): r,w,e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) if self.child_fd in r: data = self.__interact_read(self.child_fd) if output_filter: data = output_filter(data) if self.logfile is not None: self.logfile.write (data) self.logfile.flush() os.write(self.STDOUT_FILENO, data) if self.STDIN_FILENO in r: data = self.__interact_read(self.STDIN_FILENO) if input_filter: data = input_filter(data) i = data.rfind(escape_character) if i != -1: data = data[:i] self.__interact_writen(self.child_fd, data) break self.__interact_writen(self.child_fd, data) def __select (self, iwtd, owtd, ewtd, timeout=None): """This is a wrapper around select.select() that ignores signals. If select.select raises a select.error exception and errno is an EINTR error then it is ignored. Mainly this is used to ignore sigwinch (terminal resize). """ # if select() is interrupted by a signal (errno==EINTR) then # we loop back and enter the select() again. if timeout is not None: end_time = time.time() + timeout while True: try: return select.select (iwtd, owtd, ewtd, timeout) except select.error, e: if e[0] == errno.EINTR: # if we loop back we have to subtract the amount of time we already waited. if timeout is not None: timeout = end_time - time.time() if timeout < 0: return ([],[],[]) else: # something else caused the select.error, so this really is an exception raise ############################################################################## # The following methods are no longer supported or allowed. def setmaxread (self, maxread): """This method is no longer supported or allowed. I don't like getters and setters without a good reason. """ raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the maxread member variable.') def setlog (self, fileobject): """This method is no longer supported or allowed. """ raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the logfile member variable.') ############################################################################## # End of spawn class ############################################################################## class searcher_string (object): """This is a plain string search helper for the spawn.expect_any() method. Attributes: eof_index - index of EOF, or -1 timeout_index - index of TIMEOUT, or -1 After a successful match by the search() method the following attributes are available: start - index into the buffer, first byte of match end - index into the buffer, first byte after match match - the matching string itself """ def __init__(self, strings): """This creates an instance of searcher_string. This argument 'strings' may be a list; a sequence of strings; or the EOF or TIMEOUT types. """ self.eof_index = -1 self.timeout_index = -1 self._strings = [] for n, s in zip(range(len(strings)), strings): if s is EOF: self.eof_index = n continue if s is TIMEOUT: self.timeout_index = n continue self._strings.append((n, s)) def __str__(self): """This returns a human-readable string that represents the state of the object.""" ss = [ (ns[0],' %d: "%s"' % ns) for ns in self._strings ] ss.append((-1,'searcher_string:')) if self.eof_index >= 0: ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) if self.timeout_index >= 0: ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) ss.sort() ss = zip(*ss)[1] return '\n'.join(ss) def search(self, buffer, freshlen, searchwindowsize=None): """This searches 'buffer' for the first occurence of one of the search strings. 'freshlen' must indicate the number of bytes at the end of 'buffer' which have not been searched before. It helps to avoid searching the same, possibly big, buffer over and over again. See class spawn for the 'searchwindowsize' argument. If there is a match this returns the index of that string, and sets 'start', 'end' and 'match'. Otherwise, this returns -1. """ absurd_match = len(buffer) first_match = absurd_match # 'freshlen' helps a lot here. Further optimizations could # possibly include: # # using something like the Boyer-Moore Fast String Searching # Algorithm; pre-compiling the search through a list of # strings into something that can scan the input once to # search for all N strings; realize that if we search for # ['bar', 'baz'] and the input is '...foo' we need not bother # rescanning until we've read three more bytes. # # Sadly, I don't know enough about this interesting topic. /grahn for index, s in self._strings: if searchwindowsize is None: # the match, if any, can only be in the fresh data, # or at the very end of the old data offset = -(freshlen+len(s)) else: # better obey searchwindowsize offset = -searchwindowsize n = buffer.find(s, offset) if n >= 0 and n < first_match: first_match = n best_index, best_match = index, s if first_match == absurd_match: return -1 self.match = best_match self.start = first_match self.end = self.start + len(self.match) return best_index class searcher_re (object): """This is regular expression string search helper for the spawn.expect_any() method. Attributes: eof_index - index of EOF, or -1 timeout_index - index of TIMEOUT, or -1 After a successful match by the search() method the following attributes are available: start - index into the buffer, first byte of match end - index into the buffer, first byte after match match - the re.match object returned by a succesful re.search """ def __init__(self, patterns): """This creates an instance that searches for 'patterns' Where 'patterns' may be a list or other sequence of compiled regular expressions, or the EOF or TIMEOUT types.""" self.eof_index = -1 self.timeout_index = -1 self._searches = [] for n, s in zip(range(len(patterns)), patterns): if s is EOF: self.eof_index = n continue if s is TIMEOUT: self.timeout_index = n continue self._searches.append((n, s)) def __str__(self): """This returns a human-readable string that represents the state of the object.""" ss = [ (n,' %d: re.compile("%s")' % (n,str(s.pattern))) for n,s in self._searches] ss.append((-1,'searcher_re:')) if self.eof_index >= 0: ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) if self.timeout_index >= 0: ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) ss.sort() ss = zip(*ss)[1] return '\n'.join(ss) def search(self, buffer, freshlen, searchwindowsize=None): """This searches 'buffer' for the first occurence of one of the regular expressions. 'freshlen' must indicate the number of bytes at the end of 'buffer' which have not been searched before. See class spawn for the 'searchwindowsize' argument. If there is a match this returns the index of that string, and sets 'start', 'end' and 'match'. Otherwise, returns -1.""" absurd_match = len(buffer) first_match = absurd_match # 'freshlen' doesn't help here -- we cannot predict the # length of a match, and the re module provides no help. if searchwindowsize is None: searchstart = 0 else: searchstart = max(0, len(buffer)-searchwindowsize) for index, s in self._searches: match = s.search(buffer, searchstart) if match is None: continue n = match.start() if n < first_match: first_match = n the_match = match best_index = index if first_match == absurd_match: return -1 self.start = first_match self.match = the_match self.end = self.match.end() return best_index def which (filename): """This takes a given filename; tries to find it in the environment path; then checks if it is executable. This returns the full path to the filename if found and executable. Otherwise this returns None.""" # Special case where filename already contains a path. if os.path.dirname(filename) != '': if os.access (filename, os.X_OK): return filename if not os.environ.has_key('PATH') or os.environ['PATH'] == '': p = os.defpath else: p = os.environ['PATH'] # Oddly enough this was the one line that made Pexpect # incompatible with Python 1.5.2. #pathlist = p.split (os.pathsep) pathlist = string.split (p, os.pathsep) for path in pathlist: f = os.path.join(path, filename) if os.access(f, os.X_OK): return f return None def split_command_line(command_line): """This splits a command line into a list of arguments. It splits arguments on spaces, but handles embedded quotes, doublequotes, and escaped characters. It's impossible to do this with a regular expression, so I wrote a little state machine to parse the command line. """ arg_list = [] arg = '' # Constants to name the states we can be in. state_basic = 0 state_esc = 1 state_singlequote = 2 state_doublequote = 3 state_whitespace = 4 # The state of consuming whitespace between commands. state = state_basic for c in command_line: if state == state_basic or state == state_whitespace: if c == '\\': # Escape the next character state = state_esc elif c == r"'": # Handle single quote state = state_singlequote elif c == r'"': # Handle double quote state = state_doublequote elif c.isspace(): # Add arg to arg_list if we aren't in the middle of whitespace. if state == state_whitespace: None # Do nothing. else: arg_list.append(arg) arg = '' state = state_whitespace else: arg = arg + c state = state_basic elif state == state_esc: arg = arg + c state = state_basic elif state == state_singlequote: if c == r"'": state = state_basic else: arg = arg + c elif state == state_doublequote: if c == r'"': state = state_basic else: arg = arg + c if arg != '': arg_list.append(arg) return arg_list # vi:ts=4:sw=4:expandtab:ft=python: sardana-1.2.0/src/sardana/tools/config/sar_to_fods.py0000755000234100017500000000061612174204311024212 0ustar cpascualcpascual00000000000000#!/usr/bin/env python import sys,types from lxml import etree def transform(f): t = etree.XSLT(etree.parse("SAR_TO_FODS.xslt")) if type(f) in types.StringTypes: doc = etree.parse(f) else: doc = f return t(doc) def main(): filename = sys.argv[1] t = transform(filename) print etree.tostring(t, pretty_print=True) if __name__ == "__main__": main() sardana-1.2.0/src/sardana/tools/config/sardana.py0000644000234100017500000022063712174204311023325 0ustar cpascualcpascual00000000000000#!/usr/bin/env python """ The sardana execution tool. Syntax: python sardana.py [-v] [-l] [--simulation=] [--cleanup=] This tool creates and executes a sardana system from the given file. file.xml can be either: - a valid XML file coming from an EXCEL spreadsheet. - a valid XML file from the sardana schema. -v prints an output of the generated XML file and exits -l if given, this parameter activates logging --simulation= supported modes are 'Basic', 'Best' or 'Off'. Default mode is Best. Basic mode will create Dummy* controllers on the Pool Best mode will create Simu* controllers and Simu like device servers Off mode will create the original controllers on the Pool WARNING: Any other string will deactivate simulation mode and use REAL mode --cleanup= either or not to perform a cleanup at the end. Default is True. If cleanup is True the database will be cleaned at shutdown time. Valid True values are: 'yes', 'Yes', 'true', 'True', 'y', 'Y', '1' Any other value will be interpreted as False """ import PyTango import sys import os import time, datetime import exceptions import imp import traceback import logging import types, operator import json from taurus.core.util import CodecFactory LOG = logging.getLogger() try: from lxml import etree LOG.info("Using lxml XML library") except ImportError: try: # Python 2.5 import xml.etree.cElementTree as etree LOG.info("Using python native cElemenTree XML library") except ImportError: try: # Python 2.5 import xml.etree.ElementTree as etree LOG.info("Using python native ElemenTree XML library") except ImportError: try: # normal cElementTree install import cElementTree as etree LOG.info("Using python normal cElemenTree XML library") except ImportError: try: # normal ElementTree install import elementtree.ElementTree as etree LOG.info("Using python normal ElemenTree XML library") except ImportError: LOG.critical("Could not find any suitable XML library") sys.exit(1) try: import pexpect except: try: import pexpect23 as pexpect print "[WARNING]: pexpect module not found. Using local pexpect 2.3" except Exception,e: print e print "The Sardana requires pexpect python module which was not found." print "This module can be found at http://www.noah.org/wiki/Pexpect" sys.exit(2) SAR_NS = 'http://sardana.cells.es/client/framework/config' class Process: ReadyMsg = "Ready to accept request" AlreadyRunning = "This server is already running, exiting!" MaxStartupTime = 30 MaxShutdownTime = 30 def __init__(self, executable, args, name = "Process", instance = None, logfile = None, env = None): self._start_time = -1 self._stop_time = -1 self._process = None self._exec = executable self._args = args self._name = name self._instance = instance self._env = env self._logfile = logfile def o(self,m): sys.stdout.write(m) sys.stdout.flush() def on(self,m=''): self.o(m) sys.stdout.write('\n') sys.stdout.flush() def getInstance(self): return self._instance def start(self): raise RuntimeException("Not allowed to 'start' abstract Process") def stop(self): raise RuntimeException("Not allowed to 'stop' abstract Process") def getMaxStartupTime(self): return Process.MaxStartupTime def getMaxShutdownTime(self): return Process.MaxShutdownTime class PEProcess(Process): def __init__(self, executable, args, name = "PEProcess", instance = None, logfile = None, env = None): Process.__init__(self, executable, args, name, instance, logfile, env) def start(self): self._start_time = datetime.datetime.now() self.o("Starting '%s %s' (%s, %s)... " % (self._name, self._instance, self._exec, self._args)) try: self._process = pexpect.spawn(self._exec, args=self._args, logfile=self._logfile, env=self._env) #self.o("%s, %s, %s" % (self._exec, self._args, self._logfile)) #self._process.logfile = sys.stderr idx = self._process.expect([Process.ReadyMsg, Process.AlreadyRunning, pexpect.EOF, pexpect.TIMEOUT], timeout=self.getMaxStartupTime()) except Exception,e: self.on("[FAILED]") raise e if idx == 0: started = datetime.datetime.now() dt = started - self._start_time self.on("(took %s) [DONE]" % str(dt)) return self.on("[FAILED]") if idx == 1: raise Exception("%s %s already running" % (self._name, self._instance)) elif idx == 2: raise Exception("%s %s terminated unexpectedly" % (self._name, self._instance)) elif idx == 3: raise Exception("%s %s startup time exceeded" % (self._name, self._instance)) def terminate(self): if self._process is None: raise Exception("No process") return self._process.terminate() def kill(self): if not self._process is None: self._process.close() res = self._process.terminate(force=True) self._process = None self.on("[DONE]") return def stop(self, max_shutdown_time=None): """Stops""" self._stop_time = datetime.datetime.now() self.o("Stopping '%s %s'... " % (self._name, self._instance)) try: max_shutdown_time = max_shutdown_time or self.getMaxShutdownTime() if self._process is None: self.on(" (no process) [DONE]") return if not self._process.isalive(): self.on(" (already dead) [DONE]") return try: res = self.terminate() idx = self._process.expect(['Exiting','Exited', pexpect.EOF, pexpect.TIMEOUT], timeout = max_shutdown_time) except Exception,e: self.on("[FAILED]") raise e if idx == 0: self.o(".") elif idx == 1: self.on(" (terminated before expected: Exited) [DONE]") return elif idx == 2: self.on(" (terminated before expected: EOF) [DONE]") return elif idx == 3: self.o(" (shutdown time exceeded). Forcing... ") self.kill() return try: idx = self._process.expect(['Exited', pexpect.EOF, pexpect.TIMEOUT], timeout = 5) except Exception,e: self.on("[FAILED]") raise e if idx == 0: self.o(".") elif idx == 1: self.on(" (terminated before expected: EOF) [DONE]") elif idx == 2: self.on(" (shutdown time exceeded) [DONE]") self.kill() return try: idx = self._process.expect([pexpect.EOF, pexpect.TIMEOUT], timeout = 5) except Exception,e: self.on("[FAILED]") raise e if idx == 0: runtime = self._stop_time - self._start_time stopped = datetime.datetime.now() - self._stop_time self.on(". (ran for %s ;took %s) [DONE]" % (str(runtime), str(stopped))) elif idx == 1: self.o(" (shutdown time exceeded). Forcing... ") self.kill() except KeyboardInterrupt, ki: self.o("(Ctrl-C during stop). Forcing... ") self.kill() def run(self, timeout = 0): if not self._process: return try: res = self._process.read_nonblocking(size = 10000, timeout = timeout) #self.on(" \t[READ %s.%s] {%s}" % (self._name, self._instance, res)) except pexpect.TIMEOUT: # no data was available. Don't worry: it just means that in the mean # time no data was sent to the output/err by the daemon pass except pexpect.EOF: # The process terminated. Maybe to something about it in the future self.on("%s %s terminated before expected: (EOF)" % (self._name, self._instance)) self._process = None class PEDeviceServerProcess(PEProcess): def __init__(self, executable, args, name = "PEDeviceServerProcess", instance = None, db = None, logfile = None): db = db or PyTango.Database() env = os.environ.copy() env["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port()) PEProcess.__init__(self, executable, args, name, instance, logfile, env) def getServerName(self): return os.path.splitext(os.path.basename(self._exec))[0] def terminate(self): tango_host_port = self._env['TANGO_HOST'] dserver_device_name = "%s/dserver/%s/%s" % (tango_host_port, self.getServerName(), self._instance) dserver_device = PyTango.DeviceProxy(dserver_device_name) dserver_device.command_inout("Kill") PEProcess.terminate(self) class PEPythonDeviceServerProcess(PEDeviceServerProcess): def getServerName(self): return os.path.splitext(os.path.basename(self._args[0]))[0] class PESimuMotorProcess(PEPythonDeviceServerProcess): def __init__(self, instname, db = None, logfile = None): name = "Motor Simulator" # Make sure the python device server code is reachable try: f, fname, desc = imp.find_module('SimuMotorCtrl') if f: f.close() f, path, desc = imp.find_module('SimuMotor') if f: f.close() except exceptions.ImportError, e: msg = "Could not find %s executable.\n" \ "Make sure PYTHONPATH points to the directory(ies) where " \ "SimuMotorCtrl.py and SimuMotor.py files are installed" % name raise Exception(msg) fname = os.path.join(fname,'SimuMotorCtrl.py') PEDeviceServerProcess.__init__(self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) class PESimuCounterTimerProcess(PEPythonDeviceServerProcess): def __init__(self, instname, db = None, logfile = None): name = "Counter/Timer Simulator" # Make sure the python device server code is reachable try: f, fname, desc = imp.find_module('SimuCoTiCtrl') if f: f.close() except exceptions.ImportError, e: msg = "Could not find %s executable.\n" \ "Make sure PYTHONPATH points to the directory(ies) where " \ "SimuCoTiCtrl.py file is installed" % name raise Exception(msg) fname = os.path.join(fname,'SimuCoTiCtrl.py') PEDeviceServerProcess.__init__(self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) class PEPySignalSimulatorProcess(PEPythonDeviceServerProcess): def __init__(self, instname, db = None, logfile = None): name = "PySignal Simulator" # Make sure the python device server code is reachable try: f, fname, desc = imp.find_module('PySignalSimulator') if f: f.close() except exceptions.ImportError, e: msg = "Could not find %s executable.\n" \ "Make sure PYTHONPATH points to the directory where " \ "PySignalSimulator.py is installed" % name raise Exception(msg) fname = os.path.join(fname,'PySignalSimulator.py') PEDeviceServerProcess.__init__(self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) class PEDevicePoolProcess(PEDeviceServerProcess): def __init__(self, instname, db = None, logfile = None): name = "Device Pool" ex = None for path in os.getenv("PATH").split(":"): path = os.path.join(path,"Pool") if os.path.exists(path): ex = path break if ex is None: raise Exception("Could not find %s executable" % name) args = [instname, "--log-level=info"] PEDeviceServerProcess.__init__(self, ex, args, name, instname, db, logfile) class PEMacroServerProcess(PEDeviceServerProcess): def __init__(self, instname, db = None, logfile = None): name = "Macro Server" ex = None for path in os.getenv("PATH").split(":"): path = os.path.join(path,"MacroServer") if os.path.exists(path): ex = path break if ex is None: raise Exception("Could not find %s executable" % name) args = [instname, "--log-level=info"] PEDeviceServerProcess.__init__(self, ex, args, name, instname, db, logfile) SimuMotorProcess = PESimuMotorProcess SimuCounterTimerProcess = PESimuCounterTimerProcess PySignalSimulatorProcess = PEPySignalSimulatorProcess DevicePoolProcess = PEDevicePoolProcess MacroServerProcess = PEMacroServerProcess #____________________________________________________________________TangoServer class TangoServer: klassName = "DeviceServer" def __init__(self, servNode, bl, createProc = False, log = False): if servNode is None: raise Exception("No XML data") self._bl = bl self._node = servNode self._tghost = servNode.get("tangoHost") or None self._db = bl.getTangoDB(self._tghost) self._complete_name = servNode.get("serverName") self.on("Preparing %s" % self._complete_name) self._klass_name, self._inst_name = self._complete_name.split("/") ########################################################################## # To prevent some disaster, just make sure the user knows that the # hostname where the server will be deleted and created. server_host = self._db.get_db_host() server_port = self._db.get_db_port() server_tango_host = server_host+':'+server_port pytango_tango_host = PyTango.ApiUtil.get_env_var('TANGO_HOST') pytango_host, pytango_port = pytango_tango_host.split(':') # Using socket to get ip addresses because one of the two hostnames could have domain import socket server_host_ip = socket.gethostbyname_ex(server_host)[2][0] pytango_host_ip = socket.gethostbyname_ex(pytango_host)[2][0] if (server_host_ip != pytango_host_ip) or (server_port != pytango_port): print '\t!!! WARNING !!! %s TANGO_HOST is not the PyTango default. You may erase the WRONG sardana definition.' % self._complete_name print '\tServer: %s PyTango: %s' % (server_tango_host , pytango_tango_host) ans = raw_input('\tDo you _really_ want to continue? [y|N] ') if ans.lower() not in ['y','yes']: raise Exception('User cancelled the creation of %s server' % self._complete_name) ########################################################################## ########################################################################## # Before erasing the content in the database, we will also create a backup # of all the tango devices's properties and memorized attributes "a-la jive". # There's an script called jive-save-config that given the parameters # and it saves the config into the specified file the # same way you can right-click an instance within jive and select the # option 'Save server data'. try: config_file_name = self._klass_name+'-'+self._inst_name+'-'+time.strftime('%Y%m%d_%H%M%S')+'.jive' cmd = 'TANGO_HOST=%s jive-save-config %s %s &>/dev/null' % (server_tango_host, self._complete_name, config_file_name) os.system(cmd) print 'There is a backup of the deleted server config in: %s' % config_file_name except: pass ########################################################################## if self.klassName != self._klass_name: raise Exception("Node name differs from expeced '%s' != '%s'" % (self._klass_name, self.klassName)) if log: self._logfile = open("Log_%s_%s" % (self.klassName, self._inst_name), "w") else: self._logfile = None if createProc == True: self._proc = self._createProcess() else: self._proc = None def o(self,m): sys.stdout.write(m) sys.stdout.flush() def on(self,m=''): self.o(m) sys.stdout.write('\n') sys.stdout.flush() def setUp(self): """Default setUp.""" self.prepare() self.start() def tearDown(self): """Default tearDown.""" self.stop() self.cleanUp() def prepare(self): """Prepares everything to be run""" if not self._proc: self._proc = self._createProcess() # Cleanup the database self.deleteServerFromDB() # Create a new instance in database self.createServerInDB() def deleteServerFromDB(self): db = self._db server_name = self._klass_name.lower() server_instance = self._inst_name.lower() server = self._complete_name.lower() servers = [ s.lower() for s in db.get_server_list(server_name + '/*') ] if server in servers: devices = db.get_device_name(server, '*') for d in devices: if not d.startswith('dserver'): props = db.get_device_property_list(d, '*') db.delete_device_property(d, props) db.delete_device(d) db.delete_server(server) def createServerInDB(self): for devNodeName in self.getDeviceNodeNames(): nodes = self._node.findall(devNodeName) for node in nodes: dev_name = node.get("deviceName") if not dev_name: raise Exception("%s does not have valid deviceName" % self._node) # Create the device in the database info = PyTango.DbDevInfo() info.name = dev_name info._class = devNodeName info.server = self._complete_name self._db.add_device(info) alias = node.get("name") if alias: self._db.put_device_alias(dev_name, alias) props = node.findall("Property") if props: self._putDeviceProps(dev_name, props) def getDeviceNodeNames(self): return [self._klass_name] def start(self): """Default start""" self._proc.start() def stop(self): """Default stop""" self._proc.stop() def cleanUp(self): """Clean up""" self.deleteServerFromDB() def run(self, step=True, timeout=0): """Run""" while 1: self._proc.run(timeout=timeout) if step: return def _createProcess(self): raise Exception("Must overwrite in subclass") def _putDeviceProps(self, dev_name, prop_node_list): props = {} for p_node in prop_node_list: prop_name = p_node.get("name") data = [] i_nodes = p_node.findall("Item") if len(i_nodes) > 0: for i_node in i_nodes: data.append(i_node.text) else: data.append(p_node.text) props[prop_name] = data if props: self._db.put_device_property(dev_name, props) def getInstanceName(self): return self._inst_name def __str__(self): return self._complete_name class SimuMotorServer(TangoServer): klassName = "SimuMotorCtrl" def _createProcess(self): return SimuMotorProcess(self._inst_name, self._db, logfile=self._logfile) def getDeviceNodeNames(self): return TangoServer.getDeviceNodeNames(self) + ["SimuMotor"] class SimuCounterTimerServer(TangoServer): klassName = "SimuCoTiCtrl" def _createProcess(self): return SimuCounterTimerProcess(self._inst_name, self._db, logfile=self._logfile) def getDeviceNodeNames(self): return TangoServer.getDeviceNodeNames(self) + ["SimuCounter"] class PySignalSimulatorServer(TangoServer): klassName = "PySignalSimulator" def _createProcess(self): return PySignalSimulatorProcess(self._inst_name, self._db, logfile=self._logfile) class DevicePoolServer(TangoServer): klassName = "Pool" def _createProcess(self): self.dev_count = 0 return DevicePoolProcess(self._inst_name, self._db, logfile=self._logfile) def _putDeviceProps(self, dev_name, prop_node_list): TangoServer._putDeviceProps(self, dev_name, prop_node_list) def start(self): """Default start""" self._proc.start() self.loadPool() def stop(self): """Default stop""" max_shutdown_time = self.dev_count * 0.2 + 10 self._proc.stop(max_shutdown_time) def _item_node_to_value(self, attr_info, node): v = node.text or [i.text or [ j.text for j in i.findall("Item") ] for i in node.findall("Item")] return PyTango.seqStr_2_obj(v, attr_info.data_type, attr_info.data_format) def handle_attributes(self, dev_name, node): attrs = node.findall('Attribute') if not len(attrs): return # Take into account the possibility to have the device in another Tango Host... dev_name = self._tghost+'/'+dev_name dev = PyTango.DeviceProxy(dev_name) tango_attrs = dev.attribute_list_query_ex() tango_attrs_map = {} for attr in tango_attrs: tango_attrs_map[attr.name.lower()] = attr for attr in attrs: name = attr.get("name").lower() tango_attr = tango_attrs_map.get(name) if tango_attr: attr_info = dev.get_attribute_config_ex(name)[0] v_node = attr.find("Value") if not v_node is None: v = self._item_node_to_value(tango_attr, v_node) try: dev.write_attribute(name, v) except Exception, ex: print 'SOME PROBLEMS SETTING ATTRIBUTE VALUE FOR DEVICE',dev_name,'ATTRIBUTE',tango_attr.name,'VALUE',str(v) print 'EXCEPTION:',ex c_node = attr.find("Configuration") if not c_node is None: disp_node = c_node.find("Display") if not disp_node is None: attr_info.label = disp_node.get("label") or attr_info.label attr_info.format = disp_node.get("format") or attr_info.format units_node = c_node.find("Units") if not units_node is None: attr_info.unit = units_node.get("unit") or attr_info.unit attr_info.display_unit = units_node.get("display_unit") or attr_info.display_unit attr_info.standard_unit = units_node.get("standard_unit") or attr_info.standard_unit range_node = c_node.find("Range") if not range_node is None: attr_info.min_value = range_node.get("min") or attr_info.min_value attr_info.max_value = range_node.get("max") or attr_info.max_value alarms_node = c_node.find("Alarms") if not alarms_node is None: attr_info.alarms.min_warning = alarms_node.get("min_warning") or attr_info.alarms.min_warning attr_info.alarms.max_warning = alarms_node.get("max_warning") or attr_info.alarms.max_warning attr_info.alarms.min_alarm = alarms_node.get("min_alarm") or attr_info.alarms.min_alarm attr_info.alarms.max_alarm = alarms_node.get("max_alarm") or attr_info.alarms.max_alarm e_node = attr.find("Events") if not e_node is None: ch_node = e_node.find("ChangeEvent") if not ch_node is None: attr_info.events.ch_event.abs_change = ch_node.get("absolute") or attr_info.events.ch_event.abs_change rel = ch_node.get("relative") if rel: rel = rel.rstrip('%') attr_info.events.ch_event.rel_change = rel p_node = attr.find("Polling") if not p_node is None: polled = p_node.get("polled") or 'False' polled = not (polled.lower() in ('false','no', 'n', '0')) if polled: try: period = int(p_node.get("period") or 0) dev.poll_attribute(name, period) except: print dev_name,tango_attr.name try: dev.set_attribute_config(attr_info) except Exception,e: print 'COULD NOT SET THE FOLLOWING CONFIG FOR DEVICE',dev_name,'ATTR', tango_attr.name print 'ATTRIBUTE INFO:',attr_info print 'EXCEPTION:',e intrument_node = node.find("InstrumentRef") if not intrument_node is None: try: value = intrument_node.text.strip() dev.write_attribute('Instrument', value) except Exception, ex: print 'SOME PROBLEMS SETTING INSTRUMENT VALUE FOR DEVICE',dev_name,'VALUE',value print 'EXCEPTION:',ex def loadPool(self): start_load_time = datetime.datetime.now() self.on(" Loading 'Device Pool %s'..." % self._inst_name) try: tgHost = self._node.get("tangoHost") or \ ("%s:%s" % (self._db.get_db_host(), self._db.get_db_port())) pool = self._node.find(self.klassName) pool_dev_name = "%s/%s" % (tgHost, pool.get("deviceName")) pool_dp = PyTango.DeviceProxy(pool_dev_name) factory = CodecFactory() elements = factory.decode(pool_dp.elements, ensure_ascii='True')['new'] ctrl_classes_info = {} for elem in elements: if elem['type'] != 'ControllerClass': continue ctrl_classes_info[elem['name']] = elem count = 0 # Setup instruments instruments = pool.xpath("Instrument") self.o(" Creating instruments ") for instrument in instruments: try: name = instrument.get("name") if name.startswith('#'): self.o("x") continue if name.startswith('REAL'): self.o('R') else: self.o(".") kclass = instrument.get("class") pars = name, kclass pool_dp.command_inout("CreateInstrument", pars) count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type != 'PseudoMotor' and @type != 'PseudoCounter']") self.o(" Creating controllers ") count = 0 self.dev_count = 0 for ctrl in ctrls: try: name = ctrl.get("name") # skip controllers which name starts with '#' if name.startswith('#'): self.o("x") continue if name.startswith('REAL'): self.o('R') else: self.o(".") type = ctrl.get("type") if type == 'CounterTimer': type = 'CTExpChannel' lib = ctrl.get("lib") kclass = ctrl.get("class") pars = [type, lib, kclass, name] props = ctrl.findall("Property") for p in props: pars.append(p.get("name")) pars.append(p.text or '\n'.join([i.text for i in p.findall("Item")])) pars = map(str.strip, pars) pool_dp.command_inout("CreateController", pars) self.run(step = True) # to flush any output generated by the pool count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type = 'Motor']") self.o(" Creating motors ") count = 0 for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("Motor") # skip motor creation for controllers which name starts with '#' if name.startswith('#'): elems = [] for e in elems: try: axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" # skip motor creation for alias starting with '#' if aliasName.startswith('#'): self.o('x') continue self.o(".") #pars = [ [axis], [ aliasName, name ] ] pars = "Motor", name, axis, aliasName if deviceName.count('/') == 2: pars.append(deviceName) pars = map(str.strip, pars) pool_dp.command_inout("CreateElement", pars) self.handle_attributes(aliasName, e) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type = 'CounterTimer']") self.o(" Creating Counter/Timers ") count = 0 for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("CounterTimer") # skip counter/timers creation for controllers which name starts with '#' if name.startswith('#'): elems = [] for e in elems: try: axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" # skip counter/timers creation for alias starting with '#' if aliasName.startswith('#'): self.o('x') continue self.o(".") pars = "CTExpChannel", name, axis, aliasName if deviceName.count('/') == 2: pars.append(deviceName) pars = map(str.strip, pars) pool_dp.command_inout("CreateElement", pars) self.handle_attributes(aliasName, e) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type = 'ZeroDExpChannel']") self.o(" Creating 0Ds ") count = 0 for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("ZeroDExpChannel") # skip 0Ds creation for controllers which name starts with '#' if name.startswith('#'): elems = [] for e in elems: try: axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" # skip 0Ds creation for alias starting with '#' if aliasName.startswith('#'): self.o('x') continue self.o(".") pars = "ZeroDExpChannel", name, axis, aliasName if deviceName.count('/') == 2: pars.append(deviceName) pars = map(str.strip, pars) try: pool_dp.command_inout("CreateElement", pars) self.handle_attributes(aliasName, e) except PyTango.DevFailed, df: self.on("Exception creating %s: %s" %(aliasName, str(df))) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type = 'OneDExpChannel']") self.o(" Creating 1Ds ") count = 0 for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("OneDExpChannel") # skip 1Ds creation for controllers which name starts with '#' if name.startswith('#'): elems = [] for e in elems: try: axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" # skip 1Ds creation for alias starting with '#' if aliasName.startswith('#'): self.o('x') continue self.o(".") pars = "OneDExpChannel", name, axis, aliasName if deviceName.count('/') == 2: pars.append(deviceName) pars = map(str.strip, pars) pool_dp.command_inout("CreateElement", pars) self.handle_attributes(aliasName, e) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type = 'TwoDExpChannel']") self.o(" Creating 2Ds ") count = 0 for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("TwoDExpChannel") # skip 2Ds creation for controllers which name starts with '#' if name.startswith('#'): elems = [] for e in elems: try: axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" # skip 2Ds creation for alias starting with '#' if aliasName.startswith('#'): self.o('x') continue self.o(".") pars = "TwoDExpChannel", name, axis, aliasName if deviceName.count('/') == 2: pars.append(deviceName) pars = map(str.strip, pars) pool_dp.command_inout("CreateElement", pars) self.handle_attributes(aliasName, e) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) ctrls = pool.xpath("Controller[@type = 'IORegister']") self.o(" Creating IORegisters ") count = 0 for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("IORegister") # skip IORegisters creation for controllers which name starts with '#' if name.startswith('#'): elems = [] for e in elems: try: axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" # skip IORegisters creation for alias starting with '#' if aliasName.startswith('#'): self.o('x') continue self.o(".") pars = "IORegister", name, axis, aliasName if deviceName.count('/') == 2: pars.append(deviceName) pars = map(str.strip, pars) pool_dp.command_inout("CreateElement", pars) self.handle_attributes(aliasName, e) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) #------------------------------------------------- # add controllers that depend on physical elements #------------------------------------------------- ctrls = pool.xpath("Controller[@type = 'PseudoMotor']") self.o(" Creating Pseudo Motors ") pm_ctrl_count = 0 pm_count = 0 for ctrl in ctrls: try: name = ctrl.get("name") # skip controllers which name starts with '#' if name.startswith('#'): self.o("x") continue self.o(".") type = ctrl.get("type") lib = ctrl.get("lib") kclass = ctrl.get("class") ctrl_class_info = ctrl_classes_info[kclass] motor_roles = ctrl_class_info['motor_roles'] pseudo_motor_roles = ctrl_class_info['pseudo_motor_roles'] pars = [type, lib, kclass, name] for i, e in enumerate(ctrl.findall("Motor")): pars.append("%s=%s" % (motor_roles[i], e.text)) for i, e in enumerate(ctrl.findall("PseudoMotor")): pars.append("%s=%s" % (pseudo_motor_roles[i], e.get('name'))) pm_count += len(ctrl.findall("PseudoMotor")) self.dev_count += pm_count props = ctrl.findall("Property") for p in props: pars.append(p.get("name")) pars.append(p.text or '\n'.join([i.text for i in p.findall("Item")])) pars = map(str.strip, pars) pool_dp.command_inout("CreateController", pars) pm_ctrl_count += 1 for e in ctrl.findall('PseudoMotor'): self.handle_attributes(e.get("name"), e) self.run(step = True) # to flush any output generated by the pool except: self.on("[FAILED]") print ctrl_class_info raise self.on(" (%d ctrls; %d pmotors) [DONE]" % (pm_ctrl_count, pm_count)) ctrls = pool.xpath("Controller[@type = 'PseudoCounter']") self.o(" Creating Pseudo Counters ") pc_ctrl_count = 0 pc_count = 0 for ctrl in ctrls: try: name = ctrl.get("name") # skip controllers which name starts with '#' if name.startswith('#'): self.o("x") continue self.o(".") type = ctrl.get("type") lib = ctrl.get("lib") kclass = ctrl.get("class") ctrl_class_info = ctrl_classes_info[kclass] counter_roles = ctrl_class_info['counter_roles'] pseudo_counter_roles = ctrl_class_info['pseudo_counter_roles'] pars = [type, lib, kclass, name] for i, e in enumerate(ctrl.findall("Channel")): pars.append("%s=%s" % (counter_roles[i], e.text)) for i, e in enumerate(ctrl.findall("PseudoCounter")): pars.append("%s=%s" % (pseudo_counter_roles[i], e.get('name'))) pc_count += len(ctrl.findall("PseudoCounter")) self.dev_count += pc_count props = ctrl.findall("Property") for p in props: pars.append(p.get("name")) pars.append(p.text or '\n'.join([i.text for i in p.findall("Item")])) pars = map(str.strip, pars) pool_dp.command_inout("CreateController", pars) pc_ctrl_count += 1 for e in ctrl.findall('PseudoCounter'): self.handle_attributes(e.get("name"), e) self.run(step = True) # to flush any output generated by the pool except: self.on("[FAILED]") raise self.on("(%d ctrls; %d pcounters) [DONE]" % (pc_ctrl_count, pc_count)) measurement_groups = pool.findall("MeasurementGroup") self.o(" Creating Measurement Groups ") count = 0 for mg in measurement_groups: try: aliasName = mg.get("name") # skip measurementgroups which name starts with '#' if aliasName.startswith('#'): self.o("x") continue self.o(".") channels = mg.findall("ChannelRef") pars = [ aliasName ] for channel in channels: pars.append(channel.get("name")) pars = map(str.strip, pars) pool_dp.command_inout("CreateMeasurementGroup", pars) self.handle_attributes(aliasName, mg) self.run(step = True) # to flush any output generated by the pool count += 1 self.dev_count += 1 except: self.on("[FAILED]") raise self.on(" (%d) [DONE]" % count) end_load_time = datetime.datetime.now() dt = end_load_time - start_load_time self.on(" Loading 'Device Pool %s'... (took %s) [DONE]" % (self._inst_name, str(dt))) except: self.on(" Loading 'Device Pool %s'... [FAILED]" % self._inst_name) raise class MacroServerServer(TangoServer): klassName = "MacroServer" def _createProcess(self): return MacroServerProcess(self._inst_name, self._db, logfile=self._logfile) def getDeviceNodeNames(self): return TangoServer.getDeviceNodeNames(self) + ["Door"] def start(self): try: TangoServer.start(self) except: pass class Sardana: """Generic Sardana system""" SimulationModes = { "Basic" : { "Motor" : ("DummyMotorController.py", "DummyMotorController"), "CounterTimer" : ("DummyCounterTimerController.py", "DummyCounterTimerController"), "ZeroDExpChannel" : ("DummyZeroDController.py", "DummyZeroDController"), "OneDExpChannel" : ("Dummy1DController.py", "'Dummy1DController"), "TwoDExpChannel" : ("Dummy2DController.py", "'Dummy2DController"), "IORegister" : ("DummyIORController.py", "DummyIORController") }, "Best" : { "Motor" : ("SimuMotCtrl.py", "SimuMotorController"), "CounterTimer" : ("SimuCTCtrl.py", "SimuCoTiController"), "ZeroDExpChannel" : ("Simu0DCtrl.py", "Simu0DController"), "OneDExpChannel" : ("Simu1DCtrl.py", "Simu1DController"), "TwoDExpChannel" : ("Simu2DCtrl.py", "Simu2DController"), "IORegister" : ("SimuIOCtrl.py", "SimuIOController"), }, "Off" : { "Motor" : (None,None), "CounterTimer" : (None,None), "ZeroDExpChannel" : (None,None), "OneDExpChannel" : (None,None), "TwoDExpChannel" : (None,None), "IORegister" : (None,None) }, } def __init__(self, source, simulation="Best", cleanup=True, log=False): if type(source) in types.StringTypes: self._filename = source self._xmldoc = None else: self._xmldoc = source self._filename = self._xmldoc.docinfo.URL self._cleanup = cleanup self._dft_tg_db = None self._tg_dbs = {} self._simulation = simulation self._log = log def o(self,m): sys.stdout.write(m) sys.stdout.flush() def on(self,m=''): self.o(m) sys.stdout.write('\n') sys.stdout.flush() def getTangoDB(self, id = None): if id is None: if self._dft_tg_db is None: db = PyTango.Database() self._dft_tg_db = db dft_host = "%s:%s" % (db.get_db_host(), db.get_db_port()) self._tg_dbs[dft_host] = db return self._dft_tg_db db = self._tg_dbs.get(id) if not db is None: return db try: id = str(id) host,port = id.split(":") port = int(port) db = PyTango.Database(host,port) self._tg_dbs[id] = db return db except: return None def setUp(self): """Default setUp.""" self.prepare() self.start() def tearDown(self): """Default tearDown.""" self.stop() if self._cleanup: self.cleanUp() def _preprocess(self): start_pp_time = datetime.datetime.now() self.o("Preprocessing input... ") try: if not self.SimulationModes.has_key(self._simulation): return motSimNb = 0 ctSimNb = 0 zeroDSimNb = 0 oneDSimNb = 0 twoDSimNb = 0 ioSimNb = 0 pySigSimNb = 0 sarName = self._sarNode.get("name") simType = self.SimulationModes.get(self._simulation) poolservers = self._sarNode.findall("PoolServer") SimuMotorLib, SimuMotorClass = simType["Motor"] SimuCoTiLib, SimuCoTiClass = simType["CounterTimer"] Simu0DLib, Simu0DClass = simType["ZeroDExpChannel"] Simu1DLib, Simu1DClass = simType["OneDExpChannel"] Simu2DLib, Simu2DClass = simType["TwoDExpChannel"] SimuIOLib, SimuIOClass = simType["IORegister"] simuMotorLibs = [ mode["Motor"][0] for mode in self.SimulationModes.values()] simuCoTiLibs = [ mode["CounterTimer"][0] for mode in self.SimulationModes.values()] simu0DLibs = [ mode["ZeroDExpChannel"][0] for mode in self.SimulationModes.values()] simu1DLibs = [ mode["OneDExpChannel"][0] for mode in self.SimulationModes.values()] simu2DLibs = [ mode["TwoDExpChannel"][0] for mode in self.SimulationModes.values()] simuIOLibs = [ mode["IORegister"][0] for mode in self.SimulationModes.values()] for poolserver in poolservers: simuMotorList = [] pool = poolserver.find("Pool") # Process Motor controllers motctrls = pool.xpath("Controller[@type = 'Motor']") needsServerNumber = len(motctrls) > 1 for ctrl in motctrls: lib = ctrl.get("lib") klass = ctrl.get("class") if self._simulation == "Off" or lib in simuMotorLibs or ctrl.get('name').startswith('REAL'): continue motSimNb += 1 if self._simulation == "Best": # add a SimuMotorServer node to the Sardana node simuServer = etree.SubElement(self._sarNode, "SimuMotorServer") tgHost = poolserver.get("tangoHost") if tgHost: simuServer.set("tangoHost", tgHost) serverName = "SimuMotorCtrl/%s" % sarName if needsServerNumber: serverName += "%03d" % motSimNb simuServer.set("serverName", serverName) simuMotCtrl = etree.SubElement(simuServer, "SimuMotorCtrl") simuMotCtrlName = "%s/simumotctrl/%03d" % (sarName, motSimNb) simuMotCtrl.set("deviceName", simuMotCtrlName) maxError = etree.SubElement(simuMotCtrl, "Property") maxError.set("name","MaxError") maxErrorV = etree.SubElement(maxError, "Item") maxErrorV.text = "0.0" for m in ctrl.findall("Motor"): m_nb = int(m.get('axis')) simuMotor = etree.SubElement(simuServer, "SimuMotor") devName = "%s/simumotctrl%03d/%03d" % (sarName, motSimNb, m_nb) simuMotor.set("deviceName", devName) simuMotor.set("class", "SimuMotor") simuMotorList.append(simuMotor) # change the pool XML nodes to refer to simulator lib # instead of real lib map(ctrl.remove, ctrl.findall("Property")) ctrl.set("lib", SimuMotorLib) ctrl.set("class", SimuMotorClass) if self._simulation == "Best": devName = etree.SubElement(ctrl, "Property") devName.set("name", "DevName") devNameV = etree.SubElement(devName, "Item") devNameV.text = simuMotCtrlName # Process CounterTimer controllers ctctrls = pool.xpath("Controller[@type = 'CounterTimer' and " \ "@lib != '%s' and @class != '%s']" \ % ("UxTimerCtrl.la", "UnixTimer")) needsServerNumber = len(ctctrls) > 1 for ctrl in ctctrls: lib = ctrl.get("lib") klass = ctrl.get("class") if self._simulation == "Off" or lib in simuCoTiLibs or ctrl.get('name').startswith('REAL'): continue ctSimNb += 1 if self._simulation == "Best": # add a SimuCoTiServer node to the Sardana node simuServer = etree.SubElement(self._sarNode, "SimuCoTiServer") tghost = poolserver.get("tangoHost") if tghost: simuServer.set("tangoHost", tgHost) serverName = "SimuCoTiCtrl/%s" % sarName if needsServerNumber: serverName += "%03d" % ctSimNb simuServer.set("serverName", serverName) simuCoTiCtrl = etree.SubElement(simuServer,"SimuCoTiCtrl") simuCoTiCtrlName = "%s/simuctctrl/%03d" % (sarName, ctSimNb) simuCoTiCtrl.set("deviceName", simuCoTiCtrlName) motRef = 0 for ct in ctrl.findall("CounterTimer"): ct_nb = int(ct.get('axis')) simuCounter = etree.SubElement(simuServer, "SimuCounter") devName = "%s/simuctctrl%03d/%03d" % (sarName, ctSimNb, ct_nb) simuCounter.set("deviceName", devName) simuCounter.set("class", "SimuCounter") pAverage = etree.SubElement(simuCounter, "Property") pAverage.set("name", "Average") pAverage.set("type", "DevDouble") pAverage.text = "50.0" pMax = etree.SubElement(simuCounter, "Property") pMax.set("name", "Max") pMax.set("type", "DevDouble") pMax.text = "500.0" pSigma = etree.SubElement(simuCounter, "Property") pSigma.set("name", "Sigma") pSigma.set("type", "DevDouble") pSigma.text = "250.0" if simuMotorList: pMotorName = etree.SubElement(simuCounter, "Property") pMotorName.set("name", "MotorName") pMotorName.set("type", "DevString") pMotorName.text = simuMotorList[motRef].get("deviceName") if motRef == len(simuMotorList) - 1: motRef = 0 else: motRef += 1 # change the pool XML nodes to refer to simulator lib # instead of real lib map(ctrl.remove, ctrl.findall("Property")) ctrl.set("lib", SimuCoTiLib) ctrl.set("class", SimuCoTiClass) if self._simulation == "Best": devName = etree.SubElement(ctrl, "Property") devName.set("name", "DevName") devNameV = etree.SubElement(devName, "Item") devNameV.text = simuCoTiCtrlName pySigSimNode = None # Process 0D controllers zerodctrls = pool.xpath("Controller[@type = 'ZeroDExpChannel']") for ctrl in zerodctrls: lib = ctrl.get("lib") klass = ctrl.get("class") if self._simulation == "Off" or lib in simu0DLibs or ctrl.get('name').startswith('REAL'): continue zeroDSimNb += 1 pySigSimNb += 1 if self._simulation == "Best": if pySigSimNode is None: # add a PySignalSimulator node to the Sardana node pySigSimNode = etree.SubElement(self._sarNode, "PySignalSimulatorServer") tghost = poolserver.get("tangoHost") if tghost: pySigSimNode.set("tangoHost", tgHost) serverName = "PySignalSimulator/%s" % sarName pySigSimNode.set("serverName", serverName) simu0DCtrl = etree.SubElement(pySigSimNode, "PySignalSimulator") simu0DCtrlName = "%s/PySignalSimulator/%03d" % (sarName, pySigSimNb) simu0DCtrl.set("deviceName", simu0DCtrlName) zerods = ctrl.findall("ZeroDExpChannel") if len(zerods) > 0: pSimAttributes = etree.SubElement(simu0DCtrl, "Property") pSimAttributes.set("name", "DynamicAttributes") pSimAttributes.set("type", "DevVarStringArray") simAttrTempl = "zerod%03d=float(100.0+10.0*random())" for i in xrange(len(zerods)): pSimAttributeItem = etree.SubElement(pSimAttributes, "Item") pSimAttributeItem.text = simAttrTempl % (i+1) # change the pool XML nodes to refer to simulator lib # instead of real lib map(ctrl.remove, ctrl.findall("Property")) ctrl.set("lib", Simu0DLib) ctrl.set("class", Simu0DClass) if self._simulation == "Best": attributeNames = etree.SubElement(ctrl, "Property") attributeNames.set("name", "AttributeNames") simAttrTempl = "%s/zerod%%03d" % simu0DCtrlName for i in xrange(len(zerods)): attributeNameItem = etree.SubElement(attributeNames, "Item") attributeNameItem.text = simAttrTempl % (i+1) # Process 1D controllers onedctrls = pool.xpath("Controller[@type = 'OneDExpChannel']") for ctrl in onedctrls: lib = ctrl.get("lib") klass = ctrl.get("class") if self._simulation == "Off" or lib in simu1DLibs or ctrl.get('name').startswith('REAL'): continue oneDSimNb += 1 pySigSimNb += 1 if self._simulation == "Best": if pySigSimNode is None: # add a PySignalSimulator node to the Sardana node pySigSimNode = etree.SubElement(self._sarNode, "PySignalSimulatorServer") tghost = poolserver.get("tangoHost") if tghost: pySigSimNode.set("tangoHost", tgHost) serverName = "PySignalSimulator/%s" % sarName pySigSimNode.set("serverName", serverName) simu1DCtrl = etree.SubElement(pySigSimNode, "PySignalSimulator") simu1DCtrlName = "%s/PySignalSimulator/%03d" % (sarName, pySigSimNb) simu1DCtrl.set("deviceName", simu1DCtrlName) onedds = ctrl.findall("OneDExpChannel") if len(onedds) > 0: pSimAttributes = etree.SubElement(simu1DCtrl, "Property") pSimAttributes.set("name", "DynamicAttributes") pSimAttributes.set("type", "DevVarStringArray") simAttrTempl = "oned%03d=DevVarLongArray([10*sin(0.01*x) for x in xrange(100)])" for i in xrange(len(oneds)): pSimAttributeItem = etree.SubElement(pSimAttributes, "Item") pSimAttributeItem.text = simAttrTempl % (i+1) # change the pool XML nodes to refer to simulator lib # instead of real lib map(ctrl.remove, ctrl.findall("Property")) ctrl.set("lib", Simu1DLib) ctrl.set("class", Simu1DClass) if self._simulation == "Best": attributeNames = etree.SubElement(ctrl, "Property") attributeNames.set("name", "AttributeNames") attributeNamesV = etree.SubElement(attributeNames, "Item") simAttrTempl = "%s/oned%%03d" % simu1DCtrlName for i in xrange(len(oneds)): attributeNameItem = etree.SubElement(attributeNames, "Item") attributeNameItem.text = simAttrTempl % (i+1) # Process IORegister controllers ioctrls = pool.xpath("Controller[@type = 'IORegister']") for ctrl in ioctrls: lib = ctrl.get("lib") klass = ctrl.get("class") if self._simulation == "Off" or lib in simuIOLibs or ctrl.get('name').startswith('REAL'): continue ioSimNb += 1 pySigSimNb += 1 if self._simulation == "Best": if pySigSimNode is None: # add a PySignalSimulator node to the Sardana node pySigSimNode = etree.SubElement(self._sarNode, "PySignalSimulatorServer") tghost = poolserver.get("tangoHost") if tghost: pySigSimNode.set("tangoHost", tgHost) serverName = "PySignalSimulator/%s" % sarName pySigSimNode.set("serverName", serverName) simuIOCtrl = etree.SubElement(pySigSimNode, "PySignalSimulator") simuIOCtrlName = "%s/PySignalSimulator/%03d" % (sarName, pySigSimNb) simuIOCtrl.set("deviceName", simuIOCtrlName) iors = ctrl.findall("IORegister") if len(iors) > 0: pSimAttributes = etree.SubElement(simuIOCtrl, "Property") pSimAttributes.set("name", "DynamicAttributes") pSimAttributes.set("type", "DevVarStringArray") simAttrTempl = "ior%03d=int(READ and VAR('ior%03d') or WRITE and VAR('ior%03d',VALUE))" for i in xrange(len(iors)): pSimAttributeItem = etree.SubElement(pSimAttributes, "Item") pSimAttributeItem.text = simAttrTempl % ((i+1),(i+1),(i+1)) # change the pool XML nodes to refer to simulator lib # instead of real lib map(ctrl.remove, ctrl.findall("Property")) ctrl.set("lib", SimuIOLib) ctrl.set("class", SimuIOClass) if self._simulation == "Best": attributeNames = etree.SubElement(ctrl, "Property") attributeNames.set("name", "AttributeNames") simAttrTempl = "%s/ior%%03d" % simuIOCtrlName for i in xrange(len(iors)): attributeNameItem = etree.SubElement(attributeNames, "Item") attributeNameItem.text = simAttrTempl % (i+1) end_pp_time = datetime.datetime.now() dt = end_pp_time - start_pp_time self.on("(took %s) [DONE]" % str(dt)) except: self.on("[FAILED]") raise def prepare(self): """Prepares everything to be run""" if not self._xmldoc: self._xmldoc = etree.parse(self._filename) self._sarNode = self._xmldoc.getroot() sarNodeName = "Sardana" if self._sarNode.tag != sarNodeName: raise Exception(" root node not found in %s" % self._filename) self._preprocess() self.prepareMotorSimulators() self.prepareCounterTimerSimulators() self.prepareSignalSimulators() self.prepareDevicePools() self.prepareMSs() self.prepareServices() def prepareServices(self): sarName = self._sarNode.get("name") macro_servers = self._sarNode.findall("MacroServerServer/MacroServer") db = self.getTangoDB() if len(macro_servers) > 0: ms_dev_name = macro_servers[0].get("deviceName") db.register_service("Sardana", sarName, ms_dev_name) self._service = sarName, ms_dev_name return pools = self._sarNode.findall("Pool") if len(pools) > 0: pool_dev_name = pools[0].get("deviceName") db.register_service("Sardana", sarName, pool_dev_name) self._service = sarName, pool_dev_name return def prepareMotorSimulators(self): servNodes = self._sarNode.findall("SimuMotorServer") self._motorSims = {} for servNode in servNodes: serv = SimuMotorServer(servNode, self, log=self._log) serv.prepare() self._motorSims[serv.getInstanceName()] = serv def prepareCounterTimerSimulators(self): servNodes = self._sarNode.findall("SimuCoTiServer") self._coTiSims = {} for servNode in servNodes: serv = SimuCounterTimerServer(servNode, self, log=self._log) serv.prepare() self._coTiSims[serv.getInstanceName()] = serv def prepareSignalSimulators(self): servNodes = self._sarNode.findall("PySignalSimulatorServer") self._signalSims = {} for servNode in servNodes: serv = PySignalSimulatorServer(servNode, self, log=self._log) serv.prepare() self._signalSims[serv.getInstanceName()] = serv def prepareDevicePools(self): servNodes = self._sarNode.findall("PoolServer") self._devicePools = {} for servNode in servNodes: serv = DevicePoolServer(servNode, self, log=self._log) serv.prepare() self._devicePools[serv.getInstanceName()] = serv def prepareMSs(self): servNodes = self._sarNode.findall("MacroServer") self._macServs = {} for servNode in servNodes: serv = MacroServerServer(servNode, self, log=self._log) serv.prepare() self._macServs[serv.getInstanceName()] = serv def _getServsShutdownOrder(self): servs = self._macServs.values() servs += self._devicePools.values() servs += self._signalSims.values() servs += self._coTiSims.values() servs += self._motorSims.values() return servs def _getServsStartupOrder(self): servs = self._motorSims.values() servs += self._coTiSims.values() servs += self._signalSims.values() servs += self._devicePools.values() servs += self._macServs.values() return servs def cleanUp(self): for s in self._getServsShutdownOrder(): s.cleanUp() if hasattr(self, '_service') and not self._service is None: db = self.getTangoDB() db.unregister_service("Sardana", self._service[0]) def start(self): """Default startup. Starts Simulators, Device Pool and MacroServer""" for s in self._getServsStartupOrder(): s.start() def stop(self): """Default stop.""" for s in self._getServsShutdownOrder(): s.stop() def run(self): servs = self._getServsStartupOrder() self.o("Running ") count = 0 while 1: count += 1 if count % 10 == 0: self.o(":") for p in servs: p.run(step=True, timeout=0.1) def getDoc(self): return self._xmldoc def getRoot(self): return self._sarNode if __name__ == "__main__": import getopt try: opts, pargs = getopt.getopt(sys.argv[1:], 'vl', ['simulation=','cleanup=']) except Exception, e: print "ERROR:",str(e) print print __doc__ sys.exit(3) if not len(pargs): print "ERROR: Please provide XML filename" print sys.exit(3) filename = pargs[0] simulation = "Best" cleanup = True just_output_and_exit = False activate_logging = False for opt,value in opts: if opt == '-l': activate_logging = True elif opt == '--simulation': simulation = value elif opt == '--cleanup': cleanup = value in ('yes', 'Yes', 'true', 'True', 'y', 'Y', '1') elif opt == '-v': just_output_and_exit = True else: print __doc__ sys.exit(3) try: import to_sar sar_doc = to_sar.transform(filename) except Exception,e: print 'Sorry, but some problems found when trying to convert to SARDANA xml:' print str(e) sardana = Sardana(sar_doc, simulation=simulation, log=activate_logging, cleanup=cleanup) if just_output_and_exit: sardana.prepare() print etree.tostring(sardana.getRoot(), pretty_print=True) sys.exit(0) try: sardana.setUp() print "Ready!" sardana.run() except KeyboardInterrupt, e: print "User pressed Ctrl+C..." except Exception, e: traceback.print_exc() print "Shutting down!" sardana.tearDown() sardana-1.2.0/src/sardana/tools/config/sardana.xsd0000644000234100017500000002100712174204311023461 0ustar cpascualcpascual00000000000000 sardana-1.2.0/src/sardana/tools/config/tango.xsd0000644000234100017500000001672612174204311023174 0ustar cpascualcpascual00000000000000 sardana-1.2.0/src/sardana/tools/config/to_sar.py0000644000234100017500000000134712174204311023176 0ustar cpascualcpascual00000000000000#!/usr/bin/env python import sys, types from lxml import etree SAR_NS = 'http://sardana.cells.es/client/framework/config' def transform(f): if type(f) in types.StringTypes: doc = etree.parse(f) else: doc = f root = doc.getroot() if (root.nsmap.get(None) == SAR_NS) or root.tag.endswith("Sardana"): return doc # it is either a EXCEL XML or a Flat ODS if root.nsmap.get('ss'): import xls_to_sar t = xls_to_sar.transform else: import fods_to_sar t = fods_to_sar.transform return t(doc) def main(): filename = sys.argv[1] t = transform(filename) print etree.tostring(t, pretty_print=True) if __name__ == "__main__": main() sardana-1.2.0/src/sardana/tools/config/xls_to_sar.py0000755000234100017500000000151512174204311024064 0ustar cpascualcpascual00000000000000#!/usr/bin/env python """ The sardana transformation tool. Syntax: python xls_to_sar.py This tool outputs a sardana XML file from an Excel XML file. file.xml must be a valid XML file comming from an EXCEL spreadsheet. """ import sys, os, types from lxml import etree def transform(f): directory = os.path.dirname(os.path.abspath(__file__)) xslt_filename = os.path.join(directory, "XLS_TO_SAR.xslt") t = etree.XSLT(etree.parse(xslt_filename)) if type(f) in types.StringTypes: doc = etree.parse(f) else: doc = f return t(doc) def main(): if len(sys.argv) < 2: print __doc__ sys.exit(1) filename = sys.argv[1] t = transform(filename) print etree.tostring(t, pretty_print=True) if __name__ == "__main__": main() sardana-1.2.0/src/sardana/util/0000755000234100017500000000000012174204361017705 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/util/motion/0000755000234100017500000000000012174204361021212 5ustar cpascualcpascual00000000000000sardana-1.2.0/src/sardana/util/motion/__init__.py0000644000234100017500000000227712174204314023331 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This is the main device pool module""" __all__ = ["MotionPath", "Motion", "BaseMotor", "Motor"] __docformat__ = 'restructuredtext' from .motion import MotionPath, Motion, BaseMotor, Motor sardana-1.2.0/src/sardana/util/motion/motion.py0000644000234100017500000005633312174204314023101 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the definition for a simulated motor""" __all__ = ["MotionPath", "Motion", "BaseMotor", "Motor", "DemoMotor"] __docformat__ = 'restructuredtext' import time from math import pow, sqrt class MotionPath(object): """Active motion path description""" #: True if motion in positive direction or False otherwise positive_displacement = True #: True if motion is not long enough to reach maximum velocity or False #: otherwise small_motion = False #: position where maximum velocity will be reached max_vel_pos = -1 #: necessary displacement to reach maximum velocity displacement_reach_max_vel = 0 #: necessary diplacement to reach minimum velocity displacement_reach_min_vel = 0 #: maximum velocity possible max_vel = 0 #: displacement at maximum velocity at_max_vel_displacement = -1 #: time to reach maximum velocity max_vel_time = -1 #: time to reach minimum velocity min_vel_time = -1 #: time at maximum velocity at_max_vel_time = -1 #: time the motion will take duration = -1 def __init__(self, motor, initial_user_pos, final_user_pos, active_time=None): """MotionPath constructor - creates and calculates motion path parameters. :param initial_user_pos: position at which constant vel should be reached :param final_user_pos: position at which deceleration should start :param active_time: if passed, will fix the constant velocity (abs(final_user_pos - initial_user_pos)/active_time) otherwise motor constant velocity will be selected as high as possible""" self.motor = motor self.initial_user_pos = initial_user_pos self.final_user_pos = final_user_pos self.active_time = active_time self._calculateMotionPath() def setInitialUserPos(self, initial_user_pos): self.initial_user_pos = initial_user_pos self._calculateMotionPath() def setFinalUserPos(self, final_user_pos): self.final_user_pos = final_user_pos self._calculateMotionPath() def _calculateMotionPath(self): motor = self.motor initial_user_pos = self.initial_user_pos final_user_pos = self.final_user_pos initial_pos = initial_user_pos * motor.step_per_unit final_pos = final_user_pos * motor.step_per_unit displacement = abs(final_pos - initial_pos) # in this case active_time forces that the user range # correspond to the constant velocity # and if self.active_time != None: velocity = displacement / self.active_time self.motor.setMaxVelocity(velocity) sign = final_pos > initial_pos and 1 or -1 accel_time = motor.getAccelerationTime() decel_time = motor.getDecelerationTime() base_vel = motor.getMinVelocity() accel_displacement = accel_time * 0.5 * (velocity + base_vel) decel_displacement = decel_time * 0.5 * (velocity + base_vel) initial_pos -= sign * accel_displacement final_pos += sign * decel_displacement displacement = abs(final_pos - initial_pos) self.initial_user_pos = initial_pos self.final_user_pos = final_pos if displacement == 0: positive_displacement = False small_motion = True accel = 0 decel = 0 displacement_reach_max_vel = 0 displacement_reach_min_vel = 0 max_vel = 0 min_vel = 0 max_vel_pos = initial_pos at_max_vel_displacement = 0 max_vel_time = 0 min_vel_time = 0 at_max_vel_time = 0 duration = 0 else: positive_displacement = final_pos > initial_pos displmnt_not_cnst = motor.displacement_reach_max_vel + motor.displacement_reach_min_vel small_motion = displacement < displmnt_not_cnst if positive_displacement: accel = motor.accel decel = motor.decel else: accel = -motor.accel decel = -motor.decel if not small_motion: # necessary displacement to reach maximum velocity displacement_reach_max_vel = motor.displacement_reach_max_vel # necessary diplacement to reach minimum velocity displacement_reach_min_vel = motor.displacement_reach_min_vel if positive_displacement: max_vel = motor.max_vel min_vel = motor.min_vel # position where maximum velocity will be reached max_vel_pos = initial_pos + displacement_reach_max_vel else: max_vel = -motor.max_vel min_vel = -motor.min_vel # position where maximum velocity will be reached max_vel_pos = initial_pos - displacement_reach_max_vel # displacement at maximum velocity at_max_vel_displacement = displacement - (displacement_reach_max_vel + displacement_reach_min_vel) else: # Small movement # position where maximum velocity will be reached max_vel_pos = initial_pos * accel - final_pos * decel max_vel_pos /= accel - decel # necessary displacement to reach maximum velocity displacement_reach_max_vel = abs(max_vel_pos - initial_pos) # necessary diplacement to reach minimum velocity displacement_reach_min_vel = abs(final_pos - max_vel_pos) # maximum velocity possible cnst = 2 * accel * decel * displacement / (decel - accel) max_vel_2 = pow(motor.min_vel, 2) + cnst max_vel = sqrt(abs(max_vel_2)) if positive_displacement: min_vel = motor.min_vel else: max_vel = -max_vel min_vel = -motor.min_vel # displacement at maximum velocity at_max_vel_displacement = 0.0 delta_vel = abs(max_vel - min_vel) # time to reach maximum velocity if accel == 0 or delta_vel == float('inf'): max_vel_time = 0 else: max_vel_time = abs(delta_vel / accel) # time to reach minimum velocity if decel == 0 or delta_vel == float('inf'): min_vel_time = 0 else: min_vel_time = abs(delta_vel / decel) # time at maximum velocity if abs(max_vel) == float('inf'): at_max_vel_time = 0 else: at_max_vel_time = abs(at_max_vel_displacement / max_vel) # time the motion will take duration = max_vel_time + at_max_vel_time + min_vel_time self.initial_pos = initial_pos self.final_pos = final_pos self.displacement = displacement self.positive_displacement = positive_displacement self.small_motion = small_motion self.accel = accel self.decel = decel self.displacement_reach_max_vel = displacement_reach_max_vel self.displacement_reach_min_vel = displacement_reach_min_vel self.max_vel = abs(max_vel) #velocity must be a positive value self.min_vel = abs(min_vel) self.max_vel_pos = max_vel_pos self.at_max_vel_displacement = at_max_vel_displacement self.max_vel_time = max_vel_time self.min_vel_time = min_vel_time self.at_max_vel_time = at_max_vel_time self.duration = duration def info(self): print "Small movement =",self.small_motion print "length =",self.displacement print "position where maximum velocity will be reached =",self.max_vel_pos print "necessary displacement to reach maximum velocity =",self.displacement_reach_max_vel print "necessary displacement to stop from maximum velocity =",self.displacement_reach_min_vel print "maximum velocity possible =",self.max_vel print "time at top velocity =",self.at_max_vel_time print "displacement at top velocity =",self.at_max_vel_displacement print "time to reach maximum velocity =",self.max_vel_time print "time to reach minimum velocity =",self.min_vel_time print "time the motion will take =",self.duration print "" print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =",self.displacement_reach_max_vel print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =",self.displacement_reach_min_vel class Motion(object): """Active motion description""" #: instant this motion started start_instant = -1 #: instant when maximum velocity should be reached max_vel_instant = -1 #: instant when should start decelerating min_vel_instant = -1 #: instant the motion will end final_instant = -1 def __init__(self, motor, initial_user_pos, final_user_pos, start_instant=None): self.motion_path = mp = MotionPath(motor, initial_user_pos, final_user_pos) start_instant = start_instant or time.time() max_vel_instant = start_instant + mp.max_vel_time min_vel_instant = max_vel_instant + mp.at_max_vel_time final_instant = start_instant + mp.duration self.start_instant = start_instant self.max_vel_instant = max_vel_instant self.min_vel_instant = min_vel_instant self.final_instant = final_instant assert(final_instant >= start_instant) assert(start_instant <= max_vel_instant) assert(final_instant >= min_vel_instant) if self.motion_path.small_motion: assert(max_vel_instant == min_vel_instant) else: assert(max_vel_instant <= min_vel_instant) def __getattr__(self, name): return getattr(self.motion_path, name) class BaseMotor(object): # base velocity (/s) min_vel = 0 # top velocity (/s) max_vel = float('+inf') # acceleration time (s) accel_time = 0 # deceleration time (s) decel_time = 0 # acceleration (/s^2) accel = float('+inf') # acceleration (/s^2) decel = float('+inf') #: steps per unit step_per_unit = 1 #: lower limit switch position lower_ls = float('-inf') #: upper limit switch position upper_ls = float('+inf') #: True if motor is powered or False otherwise power = True #: True if motor is enabled or False otherwise enabled = True #: necessary displacement to reach maximum velocity from minimum velocity displacement_reach_max_vel = 0 #: necessary displacement to reach minimum velocity from maximum velocity displacement_reach_min_vel = 0 #: internal member describing current motion current_motion = None current_position = float('nan') def __init__(self): pass def setMinVelocity(self, vi): pass def getMinVelocity(self): return self.min_vel def setMaxVelocity(self, vf): pass def getMaxVelocity(self): return self.max_vel def setAccelerationTime(self, at): """Sets the time to go from minimum velocity to maximum velocity in seconds""" pass def getAccelerationTime(self): return self.accel_time def setDecelerationTime(self,dt): """Sets the time to go from maximum velocity to minimum velocity in seconds""" pass def getDecelerationTime(self): return self.decel_time def setAcceleration(self, a): """Sets the acceleration in ms^-2""" pass def setDeceleration(self, d): """Sets the deceleration in ms^-2""" pass def getStepPerUnit(self): return self.step_per_unit def setStepPerUnit(self, spu): self.step_per_unit = spu def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): if not self.power: raise Exception("Motor is powered off") if self.isInMotion(): raise Exception("Already in motion") initial_pos = initial_user_pos * self.step_per_unit final_pos = final_user_pos * self.step_per_unit if initial_pos == final_pos: return motion = Motion(self, initial_user_pos, final_user_pos, start_instant) motion_path = motion.motion_path self.current_position = motion.initial_pos self.current_motion = motion def abortMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() if not self.current_motion: return self.current_position self.current_position = self.getCurrentPosition(curr_instant) self.current_motion = None return self.current_position def isInMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() #we call getCurrentPosition because inside it updates the current_motion flag self.getCurrentPosition(curr_instant) return self.current_motion is not None def setCurrentPosition(self, curr_pos): self.current_position = curr_pos def getCurrentPosition(self, curr_instant=None): curr_instant = curr_instant or time.time() pos = None if self.current_motion: motion = self.current_motion # if motion should be ended... if curr_instant >= motion.final_instant: self.current_motion = None pos = motion.final_pos else: pos = motion.initial_pos if curr_instant > motion.min_vel_instant: if motion.positive_displacement: pos += motion.displacement_reach_max_vel pos += motion.at_max_vel_displacement else: pos -= motion.displacement_reach_max_vel pos -= motion.at_max_vel_displacement dt = curr_instant - motion.min_vel_instant pos += motion.max_vel * dt + 0.5 * motion.decel * pow(dt,2) elif curr_instant > motion.max_vel_instant: if motion.positive_displacement: pos += motion.displacement_reach_max_vel else: pos -= motion.displacement_reach_max_vel dt = curr_instant - motion.max_vel_instant pos += motion.max_vel * dt else: dt = curr_instant - motion.start_instant pos += motion.min_vel * dt + 0.5 * motion.accel * pow(dt,2) else: pos = self.current_position if pos <= self.lower_ls: pos = self.lower_ls self.current_motion = None elif pos >= self.upper_ls: pos = self.upper_ls self.current_motion = None self.current_position = pos return pos def setCurrentUserPosition(self, user_pos): self.setCurrentPosition(user_pos*self.step_per_unit) def getCurrentUserPosition(self, curr_instant=None): return self.getCurrentPosition(curr_instant=curr_instant) / self.step_per_unit def hitLowerLimit(self): user_pos = self.current_position / self.step_per_unit return user_pos <= self.lower_ls def hitUpperLimit(self): user_pos = self.current_position / self.step_per_unit return user_pos >= self.upper_ls def getLowerLimitSwitch(self): return self.lower_ls def setLowerLimitSwitch(self, user_lower_ls): self.lower_ls = user_lower_ls def getUpperLimitSwitch(self): return self.upper_ls def setUpperLimitSwitch(self, user_upper_ls): self.upper_ls = user_upper_ls def turnOn(self): self.power = True def turnOff(self): self.power = False def isTurnedOn(self): return self.power def hasPower(self): return self.power def setPower(self, power): self.power = power def info(self): if self.current_motion is not None: print self.current_motion.info() class Motor(BaseMotor): """The motor definition""" def __init__(self, min_vel=None, max_vel=None, accel_time=None, decel_time=None): super(Motor, self).__init__() if min_vel is not None: self.setMinVelocity(min_vel) if max_vel is not None: self.setMaxVelocity(max_vel) if accel_time is not None: self.setAccelerationTime(accel_time) if decel_time is not None: self.setDecelerationTime(decel_time) self.__recalculate_acc_constants() def setMinVelocity(self, vi): """ Sets the minimum velocity in ms^-1. A.k.a. base rate""" vi = float(vi) if vi < 0: raise Exception("Minimum velocity must be >= 0") self.min_vel = vi #TODO: consult this solution with others if self.max_vel < self.min_vel: pass #self.max_vel = self.min_vel (original version) # force recalculation of accelerations if self.accel_time >= 0: self.setAccelerationTime(self.accel_time) if self.decel_time >= 0: self.setDecelerationTime(self.decel_time) def getMinVelocity(self): return self.min_vel def setMaxVelocity(self, vf): """ Sets the maximum velocity in ms^-1.""" vf = float(vf) if vf <= 0: raise Exception("Maximum velocity must be > 0") self.max_vel = vf #TODO: consult this solution with others if self.min_vel > self.max_vel: pass #self.min_vel = self.max_vel #accel set to zero (original version) #self.setMinVelocity(0) another solution could be to set it to 0 # force recalculation of accelerations if self.accel_time >= 0: self.setAccelerationTime(self.accel_time) if self.decel_time >= 0: self.setDecelerationTime(self.decel_time) def getMaxVelocity(self): return self.max_vel def setAccelerationTime(self, at): """Sets the time to go from minimum velocity to maximum velocity in seconds""" at = float(at) if at < 0: raise Exception("Acceleration time must be >= 0") self.accel_time = at try: self.accel = (self.max_vel - self.min_vel) / at except ZeroDivisionError: self.accel = float('inf') self.__recalculate_acc_constants() def getAccelerationTime(self): return self.accel_time def setDecelerationTime(self,dt): """Sets the time to go from maximum velocity to minimum velocity in seconds""" dt = float(dt) if dt < 0: raise Exception("Deceleration time must be >= 0") self.decel_time = dt try: self.decel = (self.min_vel - self.max_vel) / dt except ZeroDivisionError: self.decel = float('inf') self.__recalculate_acc_constants() def getDecelerationTime(self): return self.decel_time def setAcceleration(self, a): """Sets the acceleration in ms^-2""" a = float(a) if a < 0: raise Exception("Acceleration must be >= 0") self.accel = float(a) if a > 0: self.accel_time = (self.max_vel - self.min_vel) / a else: self.accel_time = float('INF') self.__recalculate_acc_constants() def setDeceleration(self, d): """Sets the deceleration in ms^-2""" d = float(d) if d > 0: raise Exception("Deceleration must be <= 0") self.decel = d if d < 0: self.decel_time = (self.min_vel - self.max_vel) / d else: self.decel_time = float('INF') self.__recalculate_acc_constants() def __recalculate_acc_constants(self): """precomputations assuming maximum speed can be reached in a motion""" if self.accel_time == 0: self.displacement_reach_max_vel = 0.0 else: self.displacement_reach_max_vel = 0.5 * self.accel * pow(self.accel_time,2) self.displacement_reach_max_vel += self.min_vel * self.accel_time if self.decel_time == 0: self.displacement_reach_min_vel = 0.0 else: self.displacement_reach_min_vel = 0.5 * self.decel * pow(self.decel_time,2) self.displacement_reach_min_vel += self.max_vel * self.decel_time @staticmethod def fromMotor(motor): try: import taurus.core.tango.sardana.pool if isinstance(motor, taurus.core.tango.sardana.pool.PoolElement): min_vel = motor.getBaseRate() max_vel = motor.getVelocity() accel_time = motor.getAcceleration() decel_time = motor.getDeceleration() return Motor(min_vel=min_vel, max_vel=max_vel, accel_time=accel_time, decel_time=decel_time) except Exception,e : print e return Motor._fromTangoMotor(motor) @staticmethod def _fromTangoMotor(motor): import PyTango attrs = "base_rate", "velocity", "acceleration", "deceleration" attr_values = motor.read_attributes(attrs) v=[] for attr_value in attr_values: if attr_value.has_failed: raise PyTango.DevFailed(*attr_value.get_err_stack()) v.append(attr_value.value) return Motor(min_vel=v[0], max_vel=v[1], accel_time=v[2], decel_time=v[3]) class DemoMotor(Motor): def __init__(self): super(DemoMotor, self).__init__(2, 100, 2, 2) self.setCurrentPosition(0) sardana-1.2.0/src/sardana/util/__init__.py0000644000234100017500000000211012174204314022006 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module provides the sardana utilities""" sardana-1.2.0/src/sardana/util/deepreload.py0000644000234100017500000002575312174204314022375 0ustar cpascualcpascual00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ A module to change reload() so that it acts recursively. To enable it type:: import __builtin__, deepreload __builtin__.reload = deepreload.reload You can then disable it with:: __builtin__.reload = deepreload.original_reload Alternatively, you can add a dreload builtin alongside normal reload with:: __builtin__.dreload = deepreload.reload This code is almost entirely based on knee.py, which is a Python re-implementation of hierarchical module import. """ import __builtin__ from contextlib import contextmanager import imp import sys from types import ModuleType from warnings import warn original_import = __builtin__.__import__ class DeepReload(object): def __enter__(self): __builtin__.reload = reload def __exit__(self, etype, evalue, etraceback): __builtin__.reload = original_reload @contextmanager def replace_import_hook(new_import): saved_import = __builtin__.__import__ __builtin__.__import__ = new_import try: yield finally: __builtin__.__import__ = saved_import def get_parent(globals, level): """ parent, name = get_parent(globals, level) Return the package that an import is being performed in. If globals comes from the module foo.bar.bat (not itself a package), this returns the sys.modules entry for foo.bar. If globals is from a package's __init__.py, the package's entry in sys.modules is returned. If globals doesn't come from a package or a module in a package, or a corresponding entry is not found in sys.modules, None is returned. """ orig_level = level if not level or not isinstance(globals, dict): return None, '' pkgname = globals.get('__package__', None) if pkgname is not None: # __package__ is set, so use it if not hasattr(pkgname, 'rindex'): raise ValueError('__package__ set to non-string') if len(pkgname) == 0: if level > 0: raise ValueError('Attempted relative import in non-package') return None, '' name = pkgname else: # __package__ not set, so figure it out and set it if '__name__' not in globals: return None, '' modname = globals['__name__'] if '__path__' in globals: # __path__ is set, so modname is already the package name globals['__package__'] = name = modname else: # Normal module, so work out the package name if any lastdot = modname.rfind('.') if lastdot < 0 and level > 0: raise ValueError("Attempted relative import in non-package") if lastdot < 0: globals['__package__'] = None return None, '' globals['__package__'] = name = modname[:lastdot] dot = len(name) for x in xrange(level, 1, -1): try: dot = name.rindex('.', 0, dot) except ValueError: raise ValueError("attempted relative import beyond top-level " "package") name = name[:dot] try: parent = sys.modules[name] except: if orig_level < 1: warn("Parent module '%.200s' not found while handling absolute " "import" % name) parent = None else: raise SystemError("Parent module '%.200s' not loaded, cannot " "perform relative import" % name) # We expect, but can't guarantee, if parent != None, that: # - parent.__name__ == name # - parent.__dict__ is globals # If this is violated... Who cares? return parent, name def load_next(mod, altmod, name, buf): """ mod, name, buf = load_next(mod, altmod, name, buf) altmod is either None or same as mod """ if len(name) == 0: # completely empty module name should only happen in # 'from . import' (or '__import__("")') return mod, None, buf dot = name.find('.') if dot == 0: raise ValueError('Empty module name') if dot < 0: subname = name next = None else: subname = name[:dot] next = name[dot+1:] if buf != '': buf += '.' buf += subname result = import_submodule(mod, subname, buf) if result is None and mod != altmod: result = import_submodule(altmod, subname, subname) if result is not None: buf = subname if result is None: raise ImportError("No module named %.200s" % name) return result, next, buf # Need to keep track of what we've already reloaded to prevent cyclic evil found_now = {} def import_submodule(mod, subname, fullname): """m = import_submodule(mod, subname, fullname)""" # Require: # if mod == None: subname == fullname # else: mod.__name__ + "." + subname == fullname global found_now if fullname in found_now and fullname in sys.modules: m = sys.modules[fullname] else: print 'Reloading', fullname found_now[fullname] = 1 oldm = sys.modules.get(fullname, None) if mod is None: path = None elif hasattr(mod, '__path__'): path = mod.__path__ else: return None try: # This appears to be necessary on Python 3, because imp.find_module() # tries to import standard libraries (like io) itself, and we don't # want them to be processed by our deep_import_hook. with replace_import_hook(original_import): fp, filename, stuff = imp.find_module(subname, path) except ImportError: return None try: m = imp.load_module(fullname, fp, filename, stuff) except: # load_module probably removed name from modules because of # the error. Put back the original module object. if oldm: sys.modules[fullname] = oldm raise finally: if fp: fp.close() add_submodule(mod, m, fullname, subname) return m def add_submodule(mod, submod, fullname, subname): """mod.{subname} = submod""" if mod is None: return #Nothing to do here. if submod is None: submod = sys.modules[fullname] setattr(mod, subname, submod) return def ensure_fromlist(mod, fromlist, buf, recursive): """Handle 'from module import a, b, c' imports.""" if not hasattr(mod, '__path__'): return for item in fromlist: if not hasattr(item, 'rindex'): raise TypeError("Item in ``from list'' not a string") if item == '*': if recursive: continue # avoid endless recursion try: all = mod.__all__ except AttributeError: pass else: ret = ensure_fromlist(mod, all, buf, 1) if not ret: return 0 elif not hasattr(mod, item): import_submodule(mod, item, buf + '.' + item) def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1): """Replacement for __import__()""" parent, buf = get_parent(globals, level) head, name, buf = load_next(parent, None if level < 0 else parent, name, buf) tail = head while name: tail, name, buf = load_next(tail, tail, name, buf) # If tail is None, both get_parent and load_next found # an empty module name: someone called __import__("") or # doctored faulty bytecode if tail is None: raise ValueError('Empty module name') if not fromlist: return head ensure_fromlist(tail, fromlist, buf, 0) return tail modules_reloading = {} def deep_reload_hook(m): """Replacement for reload().""" if not isinstance(m, ModuleType): raise TypeError("reload() argument must be module") name = m.__name__ if name not in sys.modules: raise ImportError("reload(): module %.200s not in sys.modules" % name) global modules_reloading try: return modules_reloading[name] except: modules_reloading[name] = m dot = name.rfind('.') if dot < 0: subname = name path = None else: try: parent = sys.modules[name[:dot]] except KeyError: modules_reloading.clear() raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot]) subname = name[dot+1:] path = getattr(parent, "__path__", None) try: # This appears to be necessary on Python 3, because imp.find_module() # tries to import standard libraries (like io) itself, and we don't # want them to be processed by our deep_import_hook. with replace_import_hook(original_import): fp, filename, stuff = imp.find_module(subname, path) finally: modules_reloading.clear() try: newm = imp.load_module(name, fp, filename, stuff) except: # load_module probably removed name from modules because of # the error. Put back the original module object. sys.modules[name] = m raise finally: if fp: fp.close() modules_reloading.clear() return newm # Save the original hooks try: original_reload = __builtin__.reload except AttributeError: original_reload = imp.reload # Python 3 # Replacement for reload() def reload(module, exclude=['sys', 'os.path', '__builtin__', '__main__']): """Recursively reload all modules used in the given module. Optionally takes a list of modules to exclude from reloading. The default exclude list contains sys, __main__, and __builtin__, to prevent, e.g., resetting display, exception, and io hooks. """ global found_now for i in exclude: found_now[i] = 1 try: with replace_import_hook(deep_import_hook): ret = deep_reload_hook(module) finally: found_now = {} return ret # Uncomment the following to automatically activate deep reloading whenever # this module is imported #__builtin__.reload = reload sardana-1.2.0/src/sardana/util/tree.py0000644000234100017500000000133712174204314021220 0ustar cpascualcpascual00000000000000class BaseNode: """BaseNode, stores reference to data.""" def __init__(self, data): self.data = data class BranchNode(BaseNode): """BranchNode, apart of reference to data, stores a list of children Nodes.""" def __init__(self, data): BaseNode.__init__(self, data) self.children = [] def addChild(self, child): self.children.append(child) class LeafNode(BaseNode): """LeafMode, just stores reference to data.""" def __init__(self, data): BaseNode.__init__(self, data) class Tree: """Base tree class, stores reference to root Node object""" def __init__(self, root): self._root = root def root(self): return self._rootsardana-1.2.0/src/sardana/util/wrap.py0000644000234100017500000000426612174204314021236 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################# ## ## This file is part of Taurus, a Tango User Interface Library ## ## http://www.tango-controls.org/static/taurus/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Taurus is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Taurus is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Taurus. If not, see . ## ############################################################################# """""" __all__ = ["wraps", "wrapped", "is_wrapping", "is_wrapped"] import weakref from functools import wraps as _wraps __WRAPPED = "__wrapped__" __WRAPPER = "__wrapper__" def wraps(wrapped, *args, **kwargs): """A wrap decorator which stores in the returned function a reference to the wrapped function (in member '__wrapped__')""" wrapper = _wraps(wrapped, *args, **kwargs) setattr(wrapper, __WRAPPED, weakref.ref(wrapped)) setattr(wrapped, __WRAPPER, weakref.ref(wrapper)) return wrapper def is_wrapping(wrapper): """Determines if the given callable is a wrapper for another callable""" return hasattr(wrapper, __WRAPPED) def is_wrapped(wrapped): """Determines if the given callable is being wrapped by another callable""" return hasattr(wrapped, __WRAPPER) def wrapped(wrapper, recursive=True): """Returns the wrapped function around the given wrapper. If the given callable is not "wrapping" any function, the wrapper itself is returned""" if is_wrapping(wrapper): _wrapped = wrapper.__wrapped__() else: return wrapper if recursive: return wrapped(_wrapped) return _wrapped sardana-1.2.0/src/sardana/__init__.py0000644000234100017500000000253212174204314021041 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This package provides the sardana library""" import release as __release import requirements as __requirements __requirements.check_requirements() class Release: pass Release.__dict__.update(__release.__dict__) Release.__doc__ = __release.__doc__ from .sardanadefs import * from .sardanavalue import SardanaValuesardana-1.2.0/src/sardana/release.py0000644000234100017500000000557712174204314020736 0ustar cpascualcpascual00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## __docformat__ = "restructuredtext" """ Release data for the taurus project. It contains the following members: - version : (str) version string - description : (str) brief description - long_description : (str) a long description - license : (str) license - authors : (dict>) the list of authors - url : (str) the project url - download_url : (str) the project download url - platforms : list list of supported platforms - keywords : list list of keywords """ #: Name of the package for release purposes. This is the name which labels #: the tarballs and RPMs made by distutils, so it's best to lowercase it. name = 'sardana' #: For versions with substrings (like 0.6.16.svn), use an extra . to separate #: the new substring. We have to avoid using either dashes or underscores, #: because bdist_rpm does not accept dashes (an RPM) convention, and #: bdist_deb does not accept underscores (a Debian convention). version_info = (1, 2, 0, 'rc', 0) version = '.'.join(map(str, version_info[:3])) revision = str(version_info[4]) description = "Sardana is a generic program for control applications in large and small installations" long_description = """Produce a modular, high performance, robust and generic user environment for control applications in large and small installations. Make Sardana the generic user environment distributed in the TANGO project and the standard basis of collaborations in control.""" license = 'LGPL' authors = {'Tiago' : ('Tiago Coutinho','tiago.coutinho@esrf.fr'), 'Pascual-Izarra' : ('Carlos Pascual-Izarra','cpascual@cells.es') } url = 'http://packages.python.org/sardana' download_url = 'http://pypi.python.org/packages/source/s/sardana' platforms = ['Linux','Windows XP/2000/NT','Windows 95/98/ME'] keywords = ['Sardana', 'Tango', 'Python', 'Control System'] sardana-1.2.0/src/sardana/requirements.py0000644000234100017500000000613012174204314022023 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """ """ __docformat__ = 'restructuredtext' __all__ = ["check_requirements"] import sys __requires__ = { # module minimum "Python" : (2,6,0), "PyTango" : (7,2,3), "taurus.core" : (3,1,0), } def check_requirements(exec_name=None): if exec_name is None: exec_name = sys.argv[0] pyver_ = __requires__['Python'] pytangover_ = __requires__['PyTango'] taurusver_ = __requires__['taurus.core'] pyver_str_ = ".".join(map(str, pyver_)) pytangover_str_ = ".".join(map(str, pytangover_)) taurusver_str_ = ".".join(map(str,taurusver_)) pyver = sys.version_info[:3] pyver_str = ".".join(map(str,pyver)) if pyver < pyver_: print "Sardana requires python %s. Installed version is %s" % (pyver_str_, pyver_str) sys.exit(-1) pytangover = None try: import PyTango pytangover = PyTango.Release.version_info[:3] except ImportError: pass except: pytangover = tuple(map(int, PyTango.__version__.split('.', 3))) if pytangover is None: print "%s requires PyTango %s. No version installed" % (exec_name, pytangover_str_,) sys.exit(-1) if pytangover < pytangover_: pytangover_str = ".".join(map(str,pytangover)) print "%s requires PyTango %s. Installed version is %s" % (exec_name, pytangover_str_, pytangover_str) sys.exit(-1) taurusver = None try: import taurus taurusver = taurus.Release.version_info[:3] except ImportError: pass except: taurusver = tuple(map(int, taurus.Release.version.split('.', 3))) if taurusver is None: print "%s requires taurus %s. No version installed" % (exec_name, taurusver_str_,) sys.exit(-1) if taurusver < taurusver_: taurusver_str = ".".join(map(str,taurusver)) print "%s requires taurus %s. Installed version is %s" % (exec_name, taurusver_str_, taurusver_str) sys.exit(-1) try: from lxml import etree except: print "Could not find any suitable XML library" sys.exit(-1) sardana-1.2.0/src/sardana/sardanaattribute.py0000644000234100017500000003244512174204314022645 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines the base classes for Sardana attributes""" __all__ = ["SardanaAttribute", "SardanaSoftwareAttribute", "ScalarNumberAttribute", "SardanaAttributeConfiguration"] __docformat__ = 'restructuredtext' import weakref import datetime from .sardanaevent import EventGenerator, EventType from .sardanadefs import ScalarNumberFilter from .sardanavalue import SardanaValue class SardanaAttribute(EventGenerator): """Class representing an atomic attribute like position of a motor or a counter value""" def __init__(self, obj, name=None, initial_value=None, **kwargs): super(SardanaAttribute, self).__init__(**kwargs) if obj is not None: obj = weakref.ref(obj) self._obj = obj self.name = name or self.__class__.__name__ self._r_value = None self._last_event_value = None self._w_value = None self.filter = lambda a,b: True self.config = SardanaAttributeConfiguration() if initial_value is not None: self.set_value(initial_value) def has_value(self): """Determines if the attribute's read value has been read at least once in the lifetime of the attribute. :return: True if the attribute has a read value stored or False otherwise :rtype: bool""" return self._has_value() def _has_value(self): return not self._r_value is None def has_write_value(self): """Determines if the attribute's write value has been read at least once in the lifetime of the attribute. :return: True if the attribute has a write value stored or False otherwise :rtype: bool""" return self._has_write_value() def _has_write_value(self): return self._w_value is not None def get_obj(self): """Returns the object which *owns* this attribute :return: the object which *owns* this attribute :rtype: obj""" return self._get_obj() def _get_obj(self): obj = self._obj if obj is not None: obj = obj() return obj def in_error(self): """Determines if this attribute is in error state. :return: True if the attribute is in error state or False otherwise :rtype: bool""" return self._in_error() def _in_error(self): return self.has_value() and self._r_value.error def set_value(self, value, exc_info=None, timestamp=None, propagate=1): """Sets the current read value and propagates the event (if propagate > 0). :param value: the new read value for this attribute. If a SardanaValue is given, exc_info and timestamp are ignored (if given) :type value: obj or SardanaValue :param exc_info: exception information as returned by :func:`sys.exc_info` [default: None, meaning no exception] :type exc_info: tuple<3> or None :param timestamp: timestamp of attribute readout [default: None, meaning create a 'now' timestamp] :type timestamp: float or None :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" return self._set_value(value, exc_info=exc_info, timestamp=timestamp, propagate=propagate) def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): if isinstance(value, SardanaValue): rvalue = value else: rvalue = SardanaValue(value=value, exc_info=exc_info, timestamp=timestamp) self._r_value = rvalue self.fire_read_event(propagate=propagate) def get_value(self): """Returns the last read value for this attribute. :return: the last read value for this attribute :rtype: obj :raises: :exc:`Exception` if no read value has been set yet""" return self._get_value() def _get_value(self): return self.get_value_obj().value def get_value_obj(self): """Returns the last read value for this attribute. :return: the last read value for this attribute :rtype: :class:`~sardana.sardanavalue.SardanaValue` :raises: :exc:`Exception` if no read value has been set yet""" return self._get_value_obj() def _get_value_obj(self): if not self.has_value(): raise Exception("{0}.{1} doesn't have a read value yet".format( self.obj.name, self.name)) return self._r_value def set_write_value(self, w_value, timestamp=None, propagate=1): """Sets the current write value. :param value: the new write value for this attribute. If a SardanaValue is given, timestamp is ignored (if given) :type value: obj or SardanaValue :param timestamp: timestamp of attribute write [default: None, meaning create a 'now' timestamp] :type timestamp: float or None :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" return self._set_write_value(w_value, timestamp=timestamp, propagate=propagate) def _set_write_value(self, w_value, timestamp=None, propagate=1): if isinstance(w_value, SardanaValue): wvalue = w_value else: wvalue = SardanaValue(value=w_value, timestamp=timestamp) self._w_value = wvalue self.fire_write_event(propagate=propagate) def get_write_value(self): """Returns the last write value for this attribute. :return: the last write value for this attribute or None if value has not been written yet :rtype: obj""" return self._get_write_value() def _get_write_value(self): w_value = self.get_write_value_obj() if w_value is not None: return w_value.value def get_write_value_obj(self): """Returns the last write value object for this attribute. :return: the last write value for this attribute or None if value has not been written yet :rtype: :class:`~sardana.sardanavalue.SardanaValue`""" return self._get_write_value_obj() def _get_write_value_obj(self): if self.has_write_value(): return self._w_value def get_exc_info(self): """Returns the exception information (like :func:`sys.exc_info`) about last attribute readout or None if last read did not generate an exception. :return: exception information or None :rtype: tuple<3> or None""" return self._get_exc_info() def _get_exc_info(self): exc_info = None if self.has_value(): exc_info = self._r_value.exc_info return exc_info def accepts(self, propagate): if propagate < 1: return False if self._last_event_value is None: return True return propagate > 1 or self.filter(self.get_value(), self._last_event_value.value) def get_timestamp(self): """Returns the timestamp of the last readout or None if the attribute has never been read before :return: timestamp of the last readout or None :rtype: float or None""" return self._get_timestamp() def _get_timestamp(self): if self.has_value(): return self._r_value.timestamp def get_write_timestamp(self): """Returns the timestamp of the last write or None if the attribute has never been written before :return: timestamp of the last write or None :rtype: float or None""" return self._get_write_timestamp() def _get_write_timestamp(self): if self.has_write_value(): return self._w_value.timestamp def fire_write_event(self, propagate=1): """Fires an event to the listeners of the object which owns this attribute. :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" if propagate < 1: return evt_type = EventType("w_" + self.name, priority=propagate) self.fire_event(evt_type, self) def fire_read_event(self, propagate=1): """Fires an event to the listeners of the object which owns this attribute. :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" if self.accepts(propagate): obj = self.obj if obj is not None: self._last_event_value = self._r_value evt_type = EventType(self.name, priority=propagate) self.fire_event(evt_type, self) obj = property(get_obj, "container object for this attribute") value_obj = property(get_value_obj) write_value_obj = property(get_write_value_obj) value = property(get_value, set_value, "current read value for this attribute") w_value = property(get_write_value, set_write_value, "current write value for this attribute") timestamp = property(get_timestamp, doc="the read timestamp") w_timestamp = property(get_write_timestamp, doc="the write timestamp") error = property(in_error) exc_info = property(get_exc_info) def __repr__(self): v = None if self.in_error(): v = "" elif self.has_value(): v = self.value return "{0}(value={1})".format(self.name, v) def __str__(self): if self.has_value(): value = "{0} at {1}".format(self.value, datetime.datetime.fromtimestamp(self.timestamp)) else: value = "-----" if self.has_write_value(): w_value = "{0} at {1}".format(self.w_value, datetime.datetime.fromtimestamp(self.w_timestamp)) else: w_value = "-----" ret = """{0.__class__.__name__}( name = {0.name} manager = {0.obj} read = {1} write = {2}) """.format(self, value, w_value) return ret class SardanaSoftwareAttribute(SardanaAttribute): """Class representing a software attribute. The difference between this and :class:`SardanaAttribute` is that, because it is a pure software attribute, there is no difference ever between the read and write values.""" get_value = SardanaAttribute.get_value def set_value(self, value, exc_info=None, timestamp=None, propagate=1): """Sets the current read value and propagates the event (if propagate > 0). :param value: the new read value for this attribute :type value: obj :param exc_info: exception information as returned by :func:`sys.exc_info` [default: None, meaning no exception] :type exc_info: tuple<3> or None :param timestamp: timestamp of attribute readout [default: None, meaning create a 'now' timestamp] :type timestamp: float or None :param propagate: 0 for not propagating, 1 to propagate, 2 propagate with priority :type propagate: int""" SardanaAttribute.set_value(self, value, exc_info=exc_info, timestamp=timestamp) self.set_write_value(value, timestamp=self.timestamp) value = property(get_value, set_value, "current value for this attribute") class ScalarNumberAttribute(SardanaAttribute): """A :class:`SardanaAttribute` specialized for numbers""" def __init__(self, *args, **kwargs): SardanaAttribute.__init__(self, *args, **kwargs) self.filter = ScalarNumberFilter() class SardanaAttributeConfiguration(object): """Storage class for :class:`SardanaAttribute` information (like ranges)""" NoRange = float('-inf'), float('inf') def __init__(self): self.range = self.NoRange self.alarm = self.NoRange self.warning = self.NoRange sardana-1.2.0/src/sardana/sardanabase.py0000644000234100017500000001535212174204314021552 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana library. It defines the base classes for Sardana object""" __all__ = ["SardanaBaseObject", "SardanaObjectID"] __docformat__ = 'restructuredtext' import weakref from taurus.core.util import Logger from sardanadefs import ElementType, Interface, InterfacesExpanded, InvalidId from sardanaevent import EventGenerator, EventReceiver class SardanaBaseObject(EventGenerator, EventReceiver, Logger): """The Sardana most abstract object. It contains only two members: - _manager : a weak reference to the manager (pool or ms) where it belongs - _name : the name - _full_name : the name (usually a tango device name, but can be anything else.)""" def __init__(self, **kwargs): EventGenerator.__init__(self) EventReceiver.__init__(self) self._type = kwargs.pop('elem_type') self._name = intern(kwargs.pop('name')) self._full_name = intern(kwargs.pop('full_name')) self._frontend = None Logger.__init__(self, self._name) self._manager = weakref.ref(kwargs.pop('manager')) self._parent = weakref.ref(kwargs.pop('parent', self.manager)) def get_manager(self): """Return the :class:`sardana.Manager` which *owns* this sardana object. :return: the manager which *owns* this pool object. :rtype: :class:`sardana.Manager`""" return self._manager() def get_name(self): """Returns this sardana object name :return: this sardana object name :rtype: str""" return self._name def get_full_name(self): """Returns this sardana object full name :return: this sardana object full name :rtype: str""" return self._full_name def get_type(self): """Returns this sardana object type. :return: this sardana object type :rtype: :obj:`~sardana.sardanadefs.ElementType`""" return self._type def get_parent(self): """Returns this pool object parent. :return: this objects parent :rtype: :class:`~sardana.sardanabase.SardanaBaseObject`""" return self._parent() def get_parent_name(self): """Returns this sardana object parent's name. :return: this objects parent :rtype: str""" parent = self.get_parent() if parent and hasattr(parent, 'name'): return parent.name def get_frontend(self): """Returns this sardana frontend object or None if no frontend is registered :return: this objects frontend :rtype: :obj:`object`""" f = self._frontend if f is None: return None return f() def fire_event(self, event_type, event_value, listeners=None, protected=True): if protected: try: return EventGenerator.fire_event(self, event_type, event_value, listeners=listeners) except: self.warning("Error firing event <%r, %r>", event_type, event_value) self.debug("Details", exc_info=1) else: return EventGenerator.fire_event(self, event_type, event_value, listeners=listeners) def get_interfaces(self): """Returns the set of interfaces this object implements. :return: The set of interfaces this object implements. :rtype: class:`set` <:class:`sardana.sardanadefs.Interface`>""" return InterfacesExpanded[self.get_interface()] def get_interface(self): """Returns the interface this object implements. :return: The interface this object implements. :rtype: :class:`sardana.sardanadefs.Interface`""" return Interface[ElementType[self.get_type()]] def get_interface_names(self): """Returns a sequence of interface names this object implements. :return: The sequence of interfaces this object implements. :rtype: sequence<:obj:`str`>""" return map(Interface.get, self.get_interfaces()) def serialize(self, *args, **kwargs): kwargs['name'] = self.name kwargs['full_name'] = self.full_name kwargs['type'] = ElementType.whatis(self.get_type()) kwargs['manager'] = self.manager.name kwargs['parent'] = self.get_parent_name() kwargs['interfaces'] = self.get_interface_names() return kwargs def serialized(self, *args, **kwargs): return self.manager.serialize_element(self, *args, **kwargs) def str(self, *args, **kwargs): return self.manager.str_element(self, *args, **kwargs) def __str__(self): return self._name def __repr__(self): return "%s(%s)" % (self.__class__.__name__, self._name) manager = property(get_manager, doc="reference to the :class:`sardana.Manager`") name = property(get_name, doc="object name") full_name = property(get_full_name, doc="object full name") frontend = property(get_frontend, doc="the object frontend") class SardanaObjectID(object): """To be used by sardana objects which have an ID associated to them.""" def __init__(self, id=InvalidId): self._id = id def get_id(self): """Returns this sardana object ID :return: this sardana object ID :rtype: int""" return self._id def serialize(self, *args, **kwargs): kwargs['id'] = self.id return kwargs id = property(get_id, doc="object ID") sardana-1.2.0/src/sardana/sardanacontainer.py0000644000234100017500000002027512174204314022622 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for a pool container element""" __all__ = ["SardanaContainer"] __docformat__ = 'restructuredtext' from taurus.core.util import CaselessDict from sardanadefs import InvalidId, ElementType class SardanaContainer(object): """A container class for sardana elements""" def __init__(self): # map of all elements # key - element ID # value - pointer to the element object self._element_ids = {} # map of all elements by name # key - element name # value - pointer to the element object self._element_names = CaselessDict() # map of all elements by name # key - element full name # value - pointer to the element object self._element_full_names = CaselessDict() # map of all elements by type # key - element type # value - map where: # key - element ID # value - pointer to the element object self._element_types = {} def add_element(self, e): """Adds a new :class:`pool.PoolObject` to this container :param e: the pool element to be added :type e: :class:`pool.PoolObject` """ name, full_name, id = e.get_name(), e.get_full_name(), e.get_id() elem_type = e.get_type() self._element_ids[id] = e self._element_names[name] = e self._element_full_names[full_name] = e type_elems = self._element_types.get(elem_type) if type_elems is None: self._element_types[elem_type] = type_elems = {} type_elems[id] = e return e def remove_element(self, e): """Removes the :class:`pool.PoolObject` from this container :param e: the pool object to be removed :type e: :class:`pool.PoolObject` :throw: KeyError """ name, full_name, id = e.get_name(), e.get_full_name(), e.get_id() elem_type = e.get_type() del self._element_ids[id] del self._element_names[name] del self._element_full_names[full_name] type_elems = self._element_types.get(elem_type) del type_elems[id] def get_element_id_map(self): """Returns a reference to the internal pool object ID map :return: the internal pool object ID map :rtype: dict """ return self._element_ids def get_element_name_map(self): """Returns a reference to the internal pool object name map :return: the internal pool object name map :rtype: dict """ return self._element_names def get_element_type_map(self): """Returns a reference to the internal pool object type map :return: the internal pool object type map :rtype: dict> """ return self._element_types def get_element(self, **kwargs): """Returns a reference to the requested pool object :param kwargs: if key 'id' given: search by ID else if key 'full_name' given: search by full name else if key 'name' given: search by name :return: the pool object :rtype: pool.PoolObject :throw: KeyError """ if kwargs.has_key("id"): id = kwargs.pop("id") return self.get_element_by_id(id, **kwargs) if kwargs.has_key("full_name"): full_name = kwargs.pop("full_name") return self.get_element_by_full_name(full_name, **kwargs) name = kwargs.pop("name") return self.get_element_by_name(name, **kwargs) def get_element_by_name(self, name, **kwargs): """Returns a reference to the requested pool object :param name: pool object name :type name: str :return: the pool object :rtype: pool.PoolObject :throw: KeyError """ ret = self._element_names.get(name) if ret is None: raise KeyError("There is no element with name '%s'" % name) return ret def get_element_by_full_name(self, full_name, **kwargs): """Returns a reference to the requested pool object :param name: pool object full name :type name: str :return: the pool object :rtype: pool.PoolObject :throw: KeyError """ ret = self._element_full_names.get(full_name) if ret is None: raise KeyError("There is no element with full name '%s'" % full_name) return ret def get_element_by_id(self, id, **kwargs): """Returns a reference to the requested pool object :param id: pool object ID :type id: int :return: the pool object :rtype: pool.PoolObject :throw: KeyError """ ret = self._element_ids.get(id) if ret is None: raise KeyError("There is no element with ID '%d'" % id) return ret def get_elements_by_type(self, t): """Returns a list of all pool objects of the given type :param t: element type :type t: pool.ElementType :return: list of pool objects :rtype: seq """ elem_types_dict = self._element_types.get(t) if elem_types_dict is None: return [] return elem_types_dict.values() def get_element_names_by_type(self, t): """Returns a list of all pool object names of the given type :param t: element type :type t: pool.ElementType :return: list of pool object names :rtype: seq """ return [ elem.get_name() for elem in self.get_elements_by_type(t) ] def rename_element(self, old_name, new_name): """Rename a pool object :param old_name: old pool object name :type old_name: str :param new_name: new pool object name :type new_name: str """ raise NotImplementedError def check_element(self, name, full_name): raise_element_name = True try: elem = self.get_element(name=name) except: raise_element_name = False if raise_element_name: elem_type = ElementType[elem.get_type()] raise Exception("A %s with name '%s' already exists" % (elem_type, name)) raise_element_full_name = True try: elem = self.get_element(full_name=full_name) except: raise_element_full_name = False if raise_element_full_name: elem_type = ElementType[elem.get_type()] raise Exception("A %s with full name '%s' already exists" % (elem_type, full_name))sardana-1.2.0/src/sardana/sardanadefs.py0000644000234100017500000004565612174204314021573 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the most generic sardana constants and enumerations""" __all__ = ["EpsilonError", "SardanaServer", "ServerRunMode", "State", "DataType", "DataFormat", "DataAccess", "DTYPE_MAP", "R_DTYPE_MAP", "DACCESS_MAP", "from_dtype_str", "from_access_str", "to_dtype_dformat", "to_daccess", "InvalidId", "InvalidAxis", "ElementType", "Interface", "Interfaces", "InterfacesExpanded", "TYPE_ELEMENTS", "TYPE_GROUP_ELEMENTS", "TYPE_MOVEABLE_ELEMENTS", "TYPE_PHYSICAL_ELEMENTS", "TYPE_ACQUIRABLE_ELEMENTS", "TYPE_EXP_CHANNEL_ELEMENTS", "TYPE_TIMERABLE_ELEMENTS", "TYPE_PSEUDO_ELEMENTS", "INTERFACES", "INTERFACES_EXPANDED", "ScalarNumberFilter"] __docformat__ = 'restructuredtext' import math from taurus.core.util import Enumeration #: maximum difference between two floats so that they are considered equal EpsilonError = 1E-16 #: sardana element state enumeration State = Enumeration("State", ( \ "On", "Off", "Close", "Open", "Insert", "Extract", "Moving", "Standby", "Fault", "Init", "Running", "Alarm", "Disable", "Unknown", "Invalid") ) class _SardanaServer(object): """Class representing the current sardana server state""" def __init__(self): self.server_state = State.Invalid def __repr__(self): return "SardanaServer()" #: the global object containing the SardanaServer information SardanaServer = _SardanaServer() #: #: The sardana server run mode: #: #: - **SynchPure** : Pure synchronous: Start the server and run the server loop #: until it stops #: - **SynchThread** : separate thread synchronous: start a thread running the #: server loop. Block until the server loop ends #: - **SynchProcess** : separate process synchronous: start a sub-process #: running the server loop. Block until the server loop ends #: - **AsynchThread** : separate thread asynchronous: start a thread running the #: server loop. Return immediately #: - **ASynchProcess** : separate process asynchronous: start a sub-process #: running the server loop. Return immediately ServerRunMode = Enumeration("ServerRunMode", \ ("SynchPure", "SynchThread", "SynchProcess", \ "AsynchThread", "AsynchProcess")) #: sardana data types (used by device pool controllers) DataType = Enumeration("DataType", ( \ "Integer", "Double", "String", "Boolean", "Encoded", "Invalid") ) #: sardana data format enumeration (used by device pool controllers) DataFormat = Enumeration("DataFormat", ( \ "Scalar", "OneD", "TwoD", "Invalid") ) #: sardana data access (used by device pool controllers) DataAccess = Enumeration("DataAccess", ( \ "ReadOnly", "ReadWrite", "Invalid") ) #: dictionary dict DTYPE_MAP = { 'int' : DataType.Integer, 'integer' : DataType.Integer, int : DataType.Integer, long : DataType.Integer, 'long' : DataType.Integer, DataType.Integer : DataType.Integer, 'float' : DataType.Double, 'double' : DataType.Double, float : DataType.Double, DataType.Double : DataType.Double, 'str' : DataType.String, 'string' : DataType.String, str : DataType.String, DataType.String : DataType.String, 'bool' : DataType.Boolean, 'boolean' : DataType.Boolean, bool : DataType.Boolean, DataType.Boolean : DataType.Boolean, } #: dictionary dict R_DTYPE_MAP = { 'int' : int, 'integer' : int, int : int, long : int, 'long' : int, DataType.Integer : int, 'float' : float, 'double' : float, float : float, DataType.Double : float, 'str' : str, 'string' : str, str : str, DataType.String : str, 'bool' : bool, 'boolean' : bool, bool : bool, DataType.Boolean : bool, } #DTYPE_MAP.setdefault(DataType.Invalid) #: dictionary dict DACCESS_MAP = { 'read' : DataAccess.ReadOnly, DataAccess.ReadOnly : DataAccess.ReadOnly, 'readwrite' : DataAccess.ReadWrite, 'read_write' : DataAccess.ReadWrite, DataAccess.ReadWrite : DataAccess.ReadWrite, } #DACCESS_MAP.setdefault(DataAccess.Invalid) def from_dtype_str(dtype): """Transforms the given dtype parameter (string/:obj:`DataType` or None) into a tuple of two elements (str, :obj:`DataFormat`) where the first element is a string with a simplified data type. - If None is given, it returns ('float', :obj:`DataFormat.Scalar`) - If :obj:`DataType` is given, it returns (:obj:`DataType`, :obj:`DataFormat.Scalar`) :param dtype: the data type to be transformed :type dtype: str or None or :obj:`DataType` :return: a tuple for the given dtype :rtype: tuple""" dformat = DataFormat.Scalar if dtype is None: dtype = 'float' elif isinstance(dtype, (str, unicode)): dtype = dtype.lower() if dtype.startswith("pytango."): dtype = dtype[len("pytango."):] if dtype.startswith("dev"): dtype = dtype[len("dev"):] if dtype.startswith("var"): dtype = dtype[len("var"):] if dtype.endswith("array"): dtype = dtype[:dtype.index("array")] dformat = DataFormat.OneD return dtype, dformat def from_access_str(access): """Transforms the given access parameter (string or :obj:`DataAccess`) into a simplified data access string. :param dtype: the access to be transformed :type dtype: str :return: a simple string for the given access :rtype: str""" if isinstance(access, (str, unicode)): access = access.lower() if access.startswith("pytango."): access = access[len("pytango."):] return access def to_dtype_dformat(data): """Transforms the given data parameter (string/ or sequence of string or sequence of sequence of string/:obj:`DataType`) into a tuple of two elements (:obj:`DataType`, :obj:`DataFormat`). :param data: the data information to be transformed :type data: str or seq or seq> :return: a tuple <:obj:`DataType`, :obj:`DataFormat`> for the given data :rtype: tuple<:obj:`DataType`, :obj:`DataFormat`> """ import operator dtype, dformat = data, DataFormat.Scalar if isinstance(data, (str, unicode)): dtype, dformat = from_dtype_str(data) elif operator.isSequenceType(data): dformat = DataFormat.OneD dtype = data[0] if type(dtype) == str: dtype, dformat2 = from_dtype_str(dtype) if dformat2 == DataFormat.OneD: dformat = DataFormat.TwoD elif operator.isSequenceType(dtype): dformat = DataFormat.TwoD dtype = dtype[0] if type(dtype) == str: dtype, _ = from_dtype_str(dtype) dtype = DTYPE_MAP.get(dtype, DataType.Invalid) return dtype, dformat def to_daccess(daccess): """Transforms the given access parameter (string or None) into a :obj:`DataAccess`. If None is given returns :obj:`DataAccess.ReadWrite` :param dtype: the access to be transformed :type dtype: str :return: a :obj:`DataAccess` for the given access :rtype: :obj:`DataAccess`""" if daccess is None: daccess = DataAccess.ReadWrite elif isinstance(daccess , (str, unicode)): daccess = DACCESS_MAP.get(from_access_str(daccess), DataAccess.ReadWrite) return daccess #: A constant representing an invalid ID InvalidId = 0 #: A constant representing an invalid axis InvalidAxis = 0 #: An enumeration describing the all possible element types in sardana ElementType = Enumeration("ElementType", ( \ "Pool", "Controller", "Motor", "CTExpChannel", "ZeroDExpChannel", "OneDExpChannel", "TwoDExpChannel", "ComChannel", "IORegister", "PseudoMotor", "PseudoCounter", "Constraint", "MotorGroup", "MeasurementGroup", "Instrument", "ControllerClass", "ControllerLibrary", "MacroServer", "Door", "MacroClass", "MacroLibrary", "MacroFunction", "External", "Meta", "ParameterType", "Unknown") ) ET = ElementType #: a set containning all "controllable" element types. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, \ ET.OneDExpChannel, ET.TwoDExpChannel, \ ET.ComChannel, ET.IORegister, ET.PseudoMotor, \ ET.PseudoCounter, ET.Constraint)) #: a set containing all group element types. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_GROUP_ELEMENTS = set((ET.MotorGroup, ET.MeasurementGroup)) #: a set containing the type of elements which are moveable. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_MOVEABLE_ELEMENTS = set((ET.Motor, ET.PseudoMotor, ET.MotorGroup)) #: a set containing the possible types of physical elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_PHYSICAL_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, \ ET.OneDExpChannel, ET.TwoDExpChannel, \ ET.ComChannel, ET.IORegister)) #: a set containing the possible types of acquirable elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_ACQUIRABLE_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, \ ET.OneDExpChannel, ET.TwoDExpChannel, \ ET.ComChannel, ET.IORegister, ET.PseudoMotor, \ ET.PseudoCounter)) #: a set containing the possible types of experimental channel elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_EXP_CHANNEL_ELEMENTS = set((ET.CTExpChannel, ET.ZeroDExpChannel, \ ET.OneDExpChannel, ET.TwoDExpChannel, ET.PseudoCounter)) #: a set containing the possible timer-able elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_TIMERABLE_ELEMENTS = set((ET.CTExpChannel, ET.OneDExpChannel, ET.TwoDExpChannel)) #: a set containing the possible types of pseudo elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_PSEUDO_ELEMENTS = set((ET.PseudoMotor, ET.PseudoCounter)) ##: An enumeration describing the all possible sardana interfaces #SardanaInterface = Enumeration("SardanaInterface", ( \ # ("Object", 0b0000000000000001), # ("Element", 0b0000000000000011), # ("Class", 0b0000000000000101), # ("Library", 0b0000000000001001), # ("PoolObject", 0b0000000000010001), # ("PoolElement", 0b0000000000010011), # ("Pool", 0b0000000000110011), # ("Controller", 0b0000000001000001), # ("Moveable", 0b0000000010000001), # ("Acquirable", 0b0000000100000001), # ("Instrument", 0b0000001000000001), # ("Motor", 0b0000010000000001), # ("PseudoMotor", 0b0000100000000001), # ("IORegister", 0b0001000000000001), # ("ExpChannel", 0b0010000000000001), # ("CTExpChannel", 0b0100000000000001), # ("ZeroDExpChannel", 0b1000000000000001), # ("OneDExpChannel", 0b0000000000000001), # ("TwoDExpChannel", 0b0000000000000001), # ("PseudoCounter", 0b0000000000000001), # ("ComChannel", 0b0000000000000001), # ("MotorGroup", 0b0000000000000001), # ("MeasurementGroup", 0b0000000000000001), # ("ControllerLibrary", 0b0000000000000001), # ("ControllerClass", 0b0000000000000001), # ("Constraint", 0b0000000000000001), # ("External", 0b0000000000000001), # ("MacroServerObject", 0b0000000000000001), # ("MacroServerElement",0b0000000000000001), # ("MacroServer", 0b0000000000000001), # ("MacroLibrary", 0b0000000000000001), # ("MacroClass", 0b0000000000000001), # ("Macro", 0b0000000000000001), ) ) #: a dictionary containing the direct interfaces supported by each type #: (:obj:`dict`\<:obj:`str`\, :obj:`tuple`\<:obj:`set`\<:obj:`str`\, :obj:`str`\>>>) INTERFACES = { "Meta" : (set(), "A generic sardana meta object"), "Object" : (set(), "A generic sardana object"), "Element" : (set(("Object",)), "A generic sardana element"), "Class" : (set(("Object",)), "A generic sardana class"), "Function" : (set(("Object",)), "A generic sardana function"), "Library" : (set(("Object",)), "A generic sardana library"), "PoolObject" : (set(("Object",)), "A Pool object"), "PoolElement" : (set(("Element", "PoolObject")), "A Pool element"), "Pool" : (set(("PoolElement",)), "A Pool"), "Controller" : (set(("PoolElement",)), "A controller"), "Moveable" : (set(("PoolElement",)), "A moveable element"), "Acquirable" : (set(("PoolElement",)), "An acquirable element"), "Instrument" : (set(("PoolElement",)), "An instrument"), "Motor" : (set(("Moveable", "Acquirable")), "a motor"), "PseudoMotor" : (set(("Moveable", "Acquirable")), "A pseudo motor"), "IORegister" : (set(("Acquirable",)), "An IO register"), "ExpChannel" : (set(("Acquirable",)), "A generic experimental channel"), "CTExpChannel" : (set(("ExpChannel",)), "A counter/timer experimental channel"), "ZeroDExpChannel" : (set(("ExpChannel",)), "A 0D experimental channel"), "OneDExpChannel" : (set(("ExpChannel",)), "A 1D experimental channel"), "TwoDExpChannel" : (set(("ExpChannel",)), "A 2D experimental channel"), "PseudoCounter" : (set(("ExpChannel",)), "A pseudo counter"), "ComChannel" : (set(("PoolElement",)), "A communication channel"), "MotorGroup" : (set(("PoolElement",),), "A motor group"), "MeasurementGroup" : (set(("PoolElement",),), "A measurement group"), "ControllerLibrary" : (set(("Library", "PoolObject")), "A controller library"), "ControllerClass" : (set(("Class", "PoolObject")), "A controller class"), "Constraint" : (set(("PoolObject",)), "A constraint"), "External" : (set(("Object",)), "An external object"), "MacroServerObject" : (set(("Object",)), "A generic macro server object"), "MacroServerElement" : (set(("Element", "MacroServerObject")), "A generic macro server element"), "MacroServer" : (set(("MacroServerElement",)), "A MacroServer"), "Door" : (set(("MacroServerElement",)), "A macro server door"), "MacroLibrary" : (set(("Library", "MacroServerObject")), "A macro server library"), "MacroCode" : (set(("MacroServerObject",)), "A macro server macro code"), "MacroClass" : (set(("Class", "MacroCode")), "A macro server macro class"), "MacroFunction" : (set(("Function", "MacroCode")), "A macro server macro function"), "Macro" : (set(("MacroClass", "MacroFunction")), "A macro server macro"), "ParameterType" : (set(("Meta",)), "A generic macro server parameter type"), } #: a dictionary containing the *all* interfaces supported by each type #: (:obj:`dict` <:obj:`str`, :obj:`set` < :obj:`str`> >) INTERFACES_EXPANDED = {} def __expand(name): direct_expansion, _ = INTERFACES[name] if isinstance(direct_expansion, (str, unicode)): direct_expansion = direct_expansion, exp = set(direct_expansion) for e in direct_expansion: e_value = INTERFACES_EXPANDED.get(e) if e_value is None: exp.update(__expand(e)) else: exp.update(e_value[0]) exp.add(name) return exp def __build_interfaces_expanded(): global INTERFACES_EXPANDED for i in INTERFACES: INTERFACES_EXPANDED[i] = __expand(i), INTERFACES[i][1] __build_interfaces_expanded() def __expand_sardana_interface_data(si_map, name, curr_id): if name in si_map: return curr_id d = 0 i_expanded = set(INTERFACES_EXPANDED[name][0]) i_expanded.remove(name) for interface in i_expanded: if interface not in si_map: curr_id = __expand_sardana_interface_data(si_map, interface, curr_id) d |= si_map[interface] si_map[name] = long(d | curr_id) return 2*curr_id def __root_expand_sardana_interface_data(): curr_id = 1 si_map = {} for interface in INTERFACES_EXPANDED: curr_id = __expand_sardana_interface_data(si_map, interface, curr_id) return si_map #: An enumeration describing the all possible sardana interfaces Interface = Enumeration("Interface", __root_expand_sardana_interface_data().items()) def __create_sardana_interfaces(): interfaces, interfaces_expanded = {}, {} for i in INTERFACES: i_enum = Interface[i] i_items, i_items_expanded = INTERFACES[i][0], INTERFACES_EXPANDED[i][0] i_enum_items = set(map(Interface.get, i_items)) i_enum_items_expanded = set(map(Interface.get, i_items_expanded)) interfaces[i_enum] = i_enum_items interfaces_expanded[i_enum] = i_enum_items_expanded return interfaces, interfaces_expanded _Interfaces, _InterfacesExpanded = __create_sardana_interfaces() #: a dictionary containing the direct interfaces supported by each type #: (:obj:`dict` <:obj:`sardana.sardanadefs.Interface`, :obj:`set` < :obj:`sardana.sardanadefs.Interface`> >) Interfaces = _Interfaces #: a dictionary containing the *all* interfaces supported by each type. #: (:obj:`dict` <:obj:`sardana.sardanadefs.Interface`, :obj:`set` < :obj:`sardana.sardanadefs.Interface`> >) InterfacesExpanded = _InterfacesExpanded class ScalarNumberFilter(object): """A simple scalar number filter that returns ``False`` if two numbers are indentical (i.e. |a-b| < error)""" def __call__(self, a, b): try: return math.fabs(a-b) > EpsilonError except: return a != b sardana-1.2.0/src/sardana/sardanaevent.py0000644000234100017500000001440712174204314021761 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Pool libray. It defines the base classes for pool event mechanism""" __all__ = ["EventGenerator", "EventReceiver", "EventType"] __docformat__ = 'restructuredtext' import weakref import collections from .sardanautils import is_callable from taurus.core.util import CallableRef, BoundMethodWeakref def _get_callable_ref(listener, callback=None): """Returns a callable reference for the given listener""" meth = getattr(listener, 'event_received', None) if meth is not None and is_callable(meth): return weakref.ref(listener, callback) else: return CallableRef(listener, callback) class EventGenerator(object): """A class capable of generating events to their listeners""" def __init__(self, max_queue_len=10, listeners=None): self._listeners = [] self._event_queue = collections.deque(maxlen=max_queue_len) if listeners is not None: if not isinstance(listeners, collections.Sequence): listeners = listeners, for listener in listeners: self.add_listener(listener) def _listener_died(self, weak_listener): """Callback executed when a listener dies""" if self._listeners is None: return try: self._listeners.remove(weak_listener) except ValueError: pass def add_listener(self, listener): """Adds a new listener for this object. :param listener: a listener""" if self._listeners is None or listener is None: return False weak_listener = _get_callable_ref(listener, self._listener_died) if weak_listener in self._listeners: return False self._listeners.append(weak_listener) return True def remove_listener(self, listener): """Removes an existing listener for this object. :param listener: the listener to be removed :return: True is succeeded or False otherwise""" if self._listeners is None: return weak_listener = _get_callable_ref(listener) try: self._listeners.remove(weak_listener) except ValueError: return False return True def has_listeners(self): """Returns True if anybody is listening to events from this object :return: True is at least one listener is listening or False otherwise """ if self._listeners is None: return False return len(self._listeners) > 0 def fire_event(self, event_type, event_value, listeners=None): self.flush_queue() self._fire_event(event_type, event_value, listeners=listeners) def _fire_event(self, event_type, event_value, listeners=None): """Sends an event to all listeners or a specific one""" if listeners is None: listeners = self._listeners if listeners is None: return if not isinstance(listeners, collections.Sequence): listeners = listeners, for listener in listeners: if isinstance(listener, weakref.ref) or \ isinstance(listener, BoundMethodWeakref): real_listener = listener() else: real_listener = listener if real_listener is None: continue meth = getattr(real_listener, 'event_received', None) if meth is not None and is_callable(meth): real_listener.event_received(self, event_type, event_value) elif is_callable(real_listener): real_listener(self, event_type, event_value) def queue_event(self, event_type, event_value, listeners=None): queue = self._event_queue queue.append((event_type, event_value, listeners)) def flush_queue(self): queue = self._event_queue n = len(queue) while n>0: self._fire_event(*queue.pop()) n = n - 1 class EventReceiver(object): """A simple class that implements useful features for a class which is an event receiver. The actual class may inherit from this EventReceiver class and may choose to use just a part of the API provided by this class, the whole API or none of the API.""" def __init__(self): self._events_blocked = False def block_events(self): self._events_blocked = True def unblock_events(self): self._events_blocked = False def are_events_blocked(self): return self._events_blocked class EventType(object): """Definition of an event type""" def __init__(self, name, priority=0): self.name = name self.priority = priority def __str__(self): return "EventType(name=%s, priority=%s)" % (self.name, self.priority) def __repr__(self): return "EventType(name=%s, priority=%s)" % (self.name, self.priority) def get_name(self): """Returns this event name :return: this event name :rtype: str""" return self.name def get_priority(self): """Returns this event priority :return: this event priority :rtype: str""" return self.priority sardana-1.2.0/src/sardana/sardanaexception.py0000644000234100017500000000621012174204314022627 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines the base classes for sardana exceptions""" __all__ = [ "AbortException", "SardanaException", "SardanaExceptionList", "UnknownCode", "UnknownLibrary", "LibraryError", "format_exception_only", "format_exception_only_str"] __docformat__ = 'restructuredtext' import sys import traceback def format_exception_only(etype, value): msg = traceback.format_exception_only(etype, value) if msg[-1].endswith("\n"): msg[-1] = msg[-1][:-1] return msg def format_exception_only_str(etype, value): return "".join(format_exception_only(etype, value)) class AbortException(Exception): pass class SardanaException(Exception): def __init__(self, *args, **kwargs): Exception.__init__(self, *args) if args: a1 = args[0] if isinstance(a1, dict): self.msg = a1.get("message", a1.get("msg", None)) self.traceback = a1.get("traceback", a1.get("tb", None)) self.type = a1.get("type", self.__class__.__name__) else: self.msg = str(a1) self.traceback = None self.type = self.__class__.__name__ else: exc_info = kwargs.get("exc_info") if exc_info is None: self.msg = "Unknown sardana exception" else: msg = format_exception_only_str(*exc_info[:2]) self.msg = msg self.traceback = None self.type = self.__class__.__name__ if 'exc_info' in kwargs: self.exc_info = kwargs['exc_info'] else: self.exc_info = kwargs.get('exc_info', sys.exc_info()) def __str__(self): return self.msg def __repr__(self): return "%s: %s" % (self.type, self.msg) class SardanaExceptionList(SardanaException): def __init__(self, *args): SardanaException.__init__(self, *args) self.exceptions = args[0] class UnknownCode(SardanaException): pass class UnknownLibrary(SardanaException): pass class LibraryError(SardanaException): pass sardana-1.2.0/src/sardana/sardanalock.py0000644000234100017500000000616512174204314021572 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines a *slow* lock class that provides additional debugging information""" __all__ = ["SardanaLock"] __docformat__ = 'restructuredtext' import threading import logging _VERBOSE = True def SardanaLock(verbose=None, name=None, lock=None): if verbose is None: verbose = _VERBOSE if verbose: return _SardanaLock(name=name, lock=lock) if lock is None: return threading.Lock() return lock class _SardanaLock(object): """A sardana lock""" def __init__(self, name=None, lock=None, level=logging.DEBUG): name = name or self.__class__.__name__ self.__name = name self.__logger = logging.getLogger(name=name) self.__level = level if lock is None: lock = threading.Lock() self.__block = lock self.__owner = None def __repr__(self): owner = self.__owner if owner is not None: owner = owner.name return "<%s owner=%r>" % (self.__name, owner) def owner_name(self): owner = self.__owner if owner is not None: return owner.name def _note(self, msg, *args): self.__logger.log(self.__level, msg, *args) def acquire(self, blocking=1): if __debug__: self._note("[START] acquire(%s) [owner=%s]", blocking, self.owner_name()) rc = self.__block.acquire(blocking) me = threading.current_thread() if rc: self.__owner = me state = "success" else: state = "failure" if __debug__: self._note("[ END ] acquire(%s) %s [owner=%s]", blocking, state, self.owner_name()) return rc __enter__ = acquire def release(self): if __debug__: self._note("[START] release() [owner=%s]", self.owner_name()) self.__block.release() self.__owner = None if __debug__: self._note("[ END ] release() [owner=%s]", self.owner_name()) def __exit__(self, t, v, tb): self.release() sardana-1.2.0/src/sardana/sardanamanager.py0000644000234100017500000000614312174204314022250 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines the base class for Sardana manager""" __all__ = ["SardanaElementManager", "SardanaIDManager"] __docformat__ = 'restructuredtext' from taurus.core.util import CodecFactory from sardana import InvalidId class SardanaElementManager(object): """A class capable of manage elements""" SerializationProtocol = 'json' def get_serialization_protocol(self): return self.SerializationProtocol def set_serialization_protocol(self, protocol): self.SerializationProtocol = protocol serialization_protocol = property(get_serialization_protocol, set_serialization_protocol, doc="the serialization protocol") def serialize_element(self, element, *args, **kwargs): obj = element.serialize(*args, **kwargs) return self.serialize_object(obj) def serialize_object(self, obj, *args, **kwargs): return CodecFactory().encode(self.serialization_protocol, ('', obj), *args, **kwargs)[1] def str_element(self, element, *args, **kwargs): obj = element.serialize(*args, **kwargs) return self.str_object(obj) def str_object(self, obj, *args, **kwargs): # TODO: use the active codec instead of hardcoded json return CodecFactory().encode('json', ('', obj), *args, **kwargs)[1] class SardanaIDManager(object): """A class capable of manage ids""" _last_id = InvalidId def get_new_id(self): """Returns a new ID. The ID becomes reserved at this moment. :return: a new ID :rtype: int""" self._last_id += 1 return self._last_id def rollback_id(self): """Free previously reserved ID""" self._last_id -= 1 def reserve_id(self, nid): """Marks the given ID as reserved :param id: the ID to be reserved :type id: int""" assert type(nid) == int if nid > self._last_id: self._last_id = nid sardana-1.2.0/src/sardana/sardanameta.py0000644000234100017500000004317212174204314021567 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines the base classes for MetaLibrary and MetaClass""" __all__ = ["SardanaLibrary", "SardanaClass", "SardanaFunction"] __docformat__ = 'restructuredtext' import os import inspect import linecache import string import weakref import traceback from sardanabase import SardanaBaseObject # ---------------------------------------------------------------------------- # Start patch around inspect issue http://bugs.python.org/issue993580 def findsource(obj): """Return the entire source file and starting line number for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" filename = inspect.getsourcefile(obj) if filename: linecache.checkcache(filename) return inspect.findsource(obj) def getsourcelines(object): """Return a list of source lines and starting line number for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a list of the lines corresponding to the object and the line number indicates where in the original source file the first line of code was found. An IOError is raised if the source code cannot be retrieved.""" lines, lnum = findsource(object) if inspect.ismodule(object): return lines, 0 else: return inspect.getblock(lines[lnum:]), lnum + 1 def getsource(object): """Return the text of the source code for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a single string. An IOError is raised if the source code cannot be retrieved.""" lines, lnum = getsourcelines(object) return string.join(lines, '') # End patch around inspect issue http://bugs.python.org/issue993580 # ---------------------------------------------------------------------------- class SardanaLibrary(SardanaBaseObject): """Object representing a python module containing sardana classes. Public members: - module - reference to python module - file_path - complete (absolute) path (with file name at the end) - file_name - file name (including file extension) - path - complete (absolute) path - name - (=module name) module name (without file extension) - meta_classes - dict - exc_info - exception information if an error occurred when loading the module""" description = '' def __init__(self, **kwargs): self.module = module = kwargs.pop('module', None) self.file_path = file_path = kwargs.pop('file_path', None) self.exc_info = kwargs.pop('exc_info', None) if module is not None: file_path = os.path.abspath(module.__file__) self.file_path = file_path if file_path is None: self.path = kwargs.get('path', None) self.file_name = kwargs.get('file_name', None) name = kwargs.get('name', None) else: if self.file_path.endswith(".pyc"): self.file_path = self.file_path[:-1] self.path, self.file_name = os.path.split(self.file_path) name, _ = os.path.splitext(self.file_name) self.meta_classes = {} self.meta_functions = {} if module is not None and module.__doc__: self.description = module.__doc__ self._code = getsourcelines(module)[0] else: self.description = name + " in error!" self._code = None kwargs['name'] = name kwargs['full_name'] = file_path or name SardanaBaseObject.__init__(self, **kwargs) def __cmp__(self, o): return cmp(self.full_name, o.full_name) def __str__(self): return self.name @property def module_name(self): """Returns the module name for this library. :return: the module name :rtype: str""" return self.name @property def code(self): """Returns a sequence of sourcelines corresponding to the module code. :return: list of source code lines :rtype: list""" code = self._code if code is None: raise IOError('source code not available') return code def add_meta_class(self, meta_class): """Adds a new :class:~`sardana.sardanameta.SardanaClass` to this library. :param meta_class: the meta class to be added to this library :type meta_class: :class:~`sardana.sardanameta.SardanaClass`""" self.meta_classes[meta_class.name] = meta_class def get_meta_class(self, meta_class_name): """Returns a :class:~`sardana.sardanameta.SardanaClass` for the given meta class name or None if the meta class does not exist in this library. :param meta_class_name: the meta class name :type meta_class_name: str :return: a meta class or None :rtype: :class:~`sardana.sardanameta.SardanaClass`""" return self.meta_classes.get(meta_class_name) def get_meta_classes(self): """Returns a sequence of the meta classes that belong to this library. :return: a sequence of meta classes that belong to this library :rtype: seq<:class:~`sardana.sardanameta.SardanaClass`>""" return self.meta_classes.values() def has_meta_class(self, meta_class_name): """Returns True if the given meta class name belongs to this library or False otherwise. :param meta_class_name: the meta class name :type meta_class_name: str :return: True if the given meta class name belongs to this library or False otherwise :rtype: bool""" return meta_class_name in self.meta_classes def add_meta_function(self, meta_function): """Adds a new :class:~`sardana.sardanameta.SardanaFunction` to this library. :param meta_function: the meta function to be added to this library :type meta_function: :class:~`sardana.sardanameta.SardanaFunction`""" self.meta_functions[meta_function.name] = meta_function def get_meta_function(self, meta_function_name): """Returns a :class:~`sardana.sardanameta.SardanaFunction` for the given meta function name or None if the meta function does not exist in this library. :param meta_function_name: the meta function name :type meta_function_name: str :return: a meta function or None :rtype: :class:~`sardana.sardanameta.SardanaFunction`""" return self.meta_functions.get(meta_function_name) def get_meta_functions(self): """Returns a sequence of the meta functions that belong to this library. :return: a sequence of meta functions that belong to this library :rtype: seq<:class:~`sardana.sardanameta.SardanaFunction`>""" return self.meta_functions.values() def has_meta_function(self, meta_function_name): """Returns True if the given meta function name belongs to this library or False otherwise. :param meta_function_name: the meta function name :type meta_function_name: str :return: True if the given meta function name belongs to this library or False otherwise :rtype: bool""" return meta_function_name in self.meta_functions def get_meta(self, meta_name): """Returns a :class:~`sardana.sardanameta.SardanaCode` for the given meta name or None if the meta does not exist in this library. :param meta_name: the meta name (class, function) :type meta_name: str :return: a meta or None :rtype: :class:~`sardana.sardanameta.SardanaCode`""" ret = self.get_meta_class(meta_name) if ret is None: ret = self.get_meta_function(meta_name) return ret def has_meta(self, meta_name): """Returns True if the given meta name belongs to this library or False otherwise. :param meta_name: the meta name :type meta_name: str :return: True if the given meta (class or function) name belongs to this library or False otherwise :rtype: bool""" return self.has_meta_class(meta_name) or \ self.has_meta_function(meta_name) def get_metas(self): """Returns a sequence of the meta (class and functions) that belong to this library. :return: a sequence of meta (class and functions) that belong to this library :rtype: seq<:class:~`sardana.sardanameta.SardanaCode`>""" return self.get_meta_classes() + self.get_meta_functions() def get_name(self): """Returns the module name for this library (same as :meth:~sardana.sardanameta.SardanaLibrary.get_module_name). :return: the module name :rtype: str""" return self.name def get_module_name(self): """Returns the module name for this library (same as :meth:~sardana.sardanameta.SardanaLibrary.get_name). :return: the module name :rtype: str""" return self.module_name def get_module(self): """Returns the python module for this library. :return: the python module :rtype: object""" return self.module def get_description(self): """Returns the this library documentation or "" if no documentation exists. :return: this library documentation or None :rtype: str""" return self.description def get_code(self): """Returns a sequence of sourcelines corresponding to the module code. :return: list of source code lines :rtype: list""" return self.code def get_file_path(self): """Returns the file path for this library. On posix systems is something like: /abs/path/filename.py :return: this library file path :rtype: str""" if self.file_path is None: return None if self.file_path.endswith('.pyc'): return self.file_path[:-1] return self.file_path def get_file_name(self): """Returns the file name for this library. On posix systems is something like: filename.py :return: this library file name :rtype: str""" return self.file_name def has_errors(self): """Returns True if this library has syntax errors or False otherwise. :return: True if this library has syntax errors or False otherwise :rtype: bool""" return self.exc_info != None def set_error(self, exc_info): """Sets the error information for this library :param exc_info: error information. It must be an object similar to the one returned by :func:`sys.exc_info` :type exc_info: tuple""" self.exc_info = exc_info if exc_info is None: self.meta_classes = {} self.meta_functions = {} def get_error(self): """Gets the error information for this library or None if no error exists :return: error information. An object similar to the one returned by :func:`sys.exc_info` :rtype: tuple""" return self.exc_info def serialize(self, *args, **kwargs): """Returns a serializable object describing this object. :return: a serializable dict :rtype: dict""" kwargs = SardanaBaseObject.serialize(self, *args, **kwargs) kwargs['id'] = 0 kwargs['module'] = self.name kwargs['file_path'] = self.file_path kwargs['file_name'] = self.file_name kwargs['path'] = self.path kwargs['description'] = self.description kwargs['elements'] = self.meta_classes.keys() + self.meta_functions.keys() if self.exc_info is None: kwargs['exc_summary'] = None kwargs['exc_info'] = None else: kwargs['exc_summary'] = "".join(traceback.format_exception_only(*self.exc_info[:2])) kwargs['exc_info'] = "".join(traceback.format_exception(*self.exc_info)) return kwargs class SardanaCode(SardanaBaseObject): """Object representing a python code (base for class and function).""" description = '' def __init__(self, **kwargs): lib = kwargs.pop('lib') self._lib = weakref.ref(lib) self._code_obj = kwargs.pop('code') doc = self._code_obj.__doc__ if doc: self.description = doc self._code = getsourcelines(self._code_obj) name = kwargs['name'] kwargs['full_name'] = "{0}.{1}".format(lib.name, name) kwargs['parent'] = kwargs.pop('parent', self.lib) SardanaBaseObject.__init__(self, **kwargs) @property def code_object(self): return self._code_obj @property def lib(self): """Returns the library :class:~`sardana.sardanameta.SardanaLibrary` for this class. :return: a reference to the library where this class is located :rtype: :class:~`sardana.sardanameta.SardanaLibrary`""" return self._lib() @property def module(self): """Returns the python module for this class. :return: the python module :rtype: object""" return self.lib.module @property def module_name(self): """Returns the module name for this class. :return: the module name :rtype: str""" return self.lib.get_module_name() @property def file_path(self): """Returns the file path for for the library where this class is. On posix systems is something like: /abs/path/filename.py :return: the file path for for the library where this class is :rtype: str""" return self.lib.file_path @property def file_name(self): """Returns the file name for the library where this class is. On posix systems is something like: filename.py :return: the file name for the library where this class is :rtype: str""" return self.lib.file_name @property def path(self): """Returns the absolute path for the library where this class is. On posix systems is something like: /abs/path :return: the absolute path for the library where this class is :rtype: str""" return self.lib.path @property def code(self): """Returns a tuple (sourcelines, firstline) corresponding to the definition of this code object. sourcelines is a list of source code lines. firstline is the line number of the first source code line.""" code = self._code if code is None: raise IOError('source code not available') return code def get_code(self): """Returns a tuple (sourcelines, firstline) corresponding to the definition of the controller class. sourcelines is a list of source code lines. firstline is the line number of the first source code line.""" return self.code def serialize(self, *args, **kwargs): """Returns a serializable object describing this object. :return: a serializable dict :rtype: dict""" kwargs = SardanaBaseObject.serialize(self, *args, **kwargs) kwargs['id'] = 0 kwargs['module'] = self.module_name kwargs['file_name'] = self.file_name kwargs['file_path'] = self.file_path kwargs['path'] = self.path kwargs['description'] = self.description return kwargs def get_brief_description(self, max_chars=60): desc = self.description.replace('\n',' ') if len(desc) > (max_chars-5): desc = desc[:max_chars-5] + '[...]' return desc class SardanaClass(SardanaCode): """Object representing a python class.""" def __init__(self, **kwargs): klass = kwargs.pop('klass') kwargs['code'] = klass kwargs['name'] = kwargs.pop('name', klass.__name__) SardanaCode.__init__(self, **kwargs) @property def klass(self): return self.code_object class SardanaFunction(SardanaCode): """Object representing a python function.""" def __init__(self, **kwargs): function = kwargs.pop('function') kwargs['code'] = function kwargs['name'] = kwargs.pop('name', function.func_name) SardanaCode.__init__(self, **kwargs) @property def function(self): return self.code_object sardana-1.2.0/src/sardana/sardanamodulemanager.py0000644000234100017500000002134212174204314023454 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana library. It defines the base classes for module manager""" from __future__ import with_statement __all__ = ["ModuleManager"] __docformat__ = 'restructuredtext' import sys import imp import threading from taurus.core import ManagerState from taurus.core.util import Singleton, Logger from .sardanamanager import SardanaIDManager _MINIMUM_EXCLUDE = [ 'sys', 'os.path', '__builtin__', '__main__', 'sardana', 'taurus', 'PyTango' ] class PathContext(object): def __init__(self, path): self.path = path def __enter__(self): self.orig_path = list(sys.path) if self.path is not None: sys.path = self.path + sys.path def __exit__(self, etype, evalue, etraceback): sys.path = self.orig_path class PathManager(SardanaIDManager): def __init__(self): SardanaIDManager.__init__(self) self._orig_path = list(sys.path) self._path_lock = threading.Lock() #: dict> self._path_info = {} @staticmethod def _decode_path(path): p = [] for item in path: p.extend(item.split(":")) return p def add_python_path(self, path): """Adds a new path to the python path. :param path: a sequence of strings each string may contain an absolute path or a list of ":" or "\n" separated absolute paths :type path: list :return: a path id identifying the changes that were made to sys.path. This ID can be used in :meth:`remove_path` to remove only the added path :rtype: int""" path = self._decode_path(path) path_len = len(path) pif = self._path_info with self._path_lock: path_id = self.get_new_id() for _, p_info in pif.items(): p_info[0] += path_len pif[path_id] = [0, path] sys.path = path + sys.path return path_id def remove_python_path(self, path_id): """Removes the path given by the path_id :param path_id: a path id identifying specific changes that were made to sys.path :type path_id: int""" pif = self._path_info start, path = pif[path_id] path_len = len(path) with self._path_lock: sys.path = sys.path[:start+1] + sys.path[start+path_len:] del pif[path_id] def reset_python_path(self): with self._path_lock: sys.path = list(self._orig_path) self._path_info = {} class ModuleManager(Singleton, Logger): """This class handles python module loading/reloading and unloading.""" def __init__(self): """ Initialization. Nothing to be done here for now.""" pass def init(self, *args, **kwargs): """Singleton instance initialization.""" name = self.__class__.__name__ self._state = ManagerState.UNINITIALIZED self._path_manager = PathManager() self.call__init__(Logger, name) self.reInit() def reInit(self): if self._state == ManagerState.INITED: return # dict # key - module name (without path and without extension) # value - python module object reference self._modules = {} self._state = ManagerState.INITED def cleanUp(self): if self._state == ManagerState.CLEANED: return self.unloadModules() self._modules = None self._state = ManagerState.CLEANED def reset_python_path(self): return self._path_manager.reset_python_path() def remove_python_path(self, path_id): return self._path_manager.remove_python_path(path_id) def add_python_path(self, path): return self._path_manager.add_python_path(path) def findFullModuleName(self, module_name, path=None): mfile = None try: mfile, pathname, _ = imp.find_module(module_name, path) finally: if mfile is not None: mfile.close() return pathname def reloadModule(self, module_name, path=None, reload=True): """Loads/reloads the given module name""" if not reload: return self.loadModule(module_name, path=path) self.unloadModule(module_name) m, mfile = None, None try: mfile, pathname, desc = imp.find_module(module_name, path) self.info("(re)loading module %s...", module_name) m = imp.load_module(module_name, mfile, pathname, desc) except: self.error("Error (re)loading module %s", module_name) self.debug("Details:", exc_info=1) raise finally: if mfile is not None: mfile.close() if m is None: return self._modules[module_name] = m return m def deep_reload_module(self, module_name, path=None, exclude=None): if module_name in sys.modules: module = sys.modules[module_name] else: module = self.loadModule(module_name, path) excl = list(_MINIMUM_EXCLUDE) if exclude is not None: excl.extend(exclude) import sardana.util.deepreload with PathContext(path): try: self.info("deep reloading module %s...", module_name) sardana.util.deepreload.reload(module, excl) except: self.error("Error deep reloading module %s", module_name) self.debug("Details:", exc_info=1) raise def loadModule(self, module_name, path=None): """Loads the given module name. If the module has been already loaded into this python interpreter, nothing is done. :param module_name: the module to be loaded. :type module_name: str :param path: list of paths to look for modules [default: None] :type path: seq or None :return: python module :raises: ImportError""" if module_name in sys.modules: return sys.modules[module_name] with PathContext(path): self.info("loading module %s...", module_name) try: module = __import__(module_name, globals(), locals(), [], -1) except: self.error("Error loading module %s", module_name) self.debug("Details:", exc_info=1) raise self._modules[module_name] = module return module def unloadModule(self, module_name): """Unloads the given module name""" if self._modules.has_key(module_name): self.debug("unloading module %s" % module_name) assert(sys.modules.has_key(module_name)) self._modules.pop(module_name) del sys.modules[module_name] def unloadModules(self, module_list=None): """Unloads the given module name""" modules = module_list or self._modules.keys() for module in modules: self.unloadModule(module) def getModule(self, module_name): """Returns the module object for the given module name""" m = self._modules.get(module_name) if m is None: m = self.reloadModule(module_name) return m def getModuleNames(self): module_names = self._modules.keys() module_names.sort() return module_names sardana-1.2.0/src/sardana/sardanathreadpool.py0000644000234100017500000000325312174204314022776 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module contains the function to access sardana thread pool""" from __future__ import with_statement __all__ = ["get_thread_pool"] __docformat__ = 'restructuredtext' import threading from taurus.core.util import ThreadPool __thread_pool_lock = threading.Lock() __thread_pool = None def get_thread_pool(): """Returns the global pool of threads for Sardana :return: the global pool of threads object :rtype: taurus.core.util.ThreadPool""" global __thread_pool global __thread_pool_lock with __thread_pool_lock: if __thread_pool is None: __thread_pool = ThreadPool(name="SardanaTP", Psize=10) return __thread_poolsardana-1.2.0/src/sardana/sardanautils.py0000644000234100017500000001174112174204314021776 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana library. It defines some utility methods""" __all__ = ["is_pure_str", "is_non_str_seq", "is_integer", "is_number", "is_bool", "check_type", "assert_type", "str_to_value", "is_callable", "translate_version_str2int", "translate_version_str2list"] __docformat__ = 'restructuredtext' import collections import numbers import numpy from sardanadefs import DataType, DataFormat, DTYPE_MAP, R_DTYPE_MAP __str_klasses = [str] __int_klasses = [int, numpy.integer] __number_klasses = [numbers.Number, numpy.number] __DTYPE_MAP = dict(DTYPE_MAP) __use_unicode = False try: unicode __use_unicode = True __str_klasses.append(unicode) __DTYPE_MAP[unicode] = DataType.String except: pass __use_long = False try: long __use_long = True __int_klasses.append(long) __DTYPE_MAP[long] = DataType.Integer except: pass __bool_klasses = [bool] + __int_klasses __str_klasses = tuple(__str_klasses) __int_klasses = tuple(__int_klasses) __number_klasses = tuple(__number_klasses) __bool_klasses = tuple(__bool_klasses) def is_pure_str(obj): return isinstance(obj , __str_klasses) def is_non_str_seq(obj): return isinstance(obj, collections.Sequence) and not is_pure_str(obj) def is_integer(obj): return isinstance(obj, __int_klasses) def is_number(obj): return isinstance(obj, __number_klasses) def is_bool(obj): return isinstance(obj, __bool_klasses) def is_callable(obj): return hasattr(obj, "__call__") __METH_MAP = { DataType.Integer : is_integer, DataType.Double : is_number, DataType.String : is_pure_str, DataType.Boolean : is_bool, } def check_type(type_info, value): tinfo = __DTYPE_MAP.get(type_info, type_info) tmeth = __METH_MAP.get(tinfo, type_info) return tmeth(value) def assert_type(type_info, value): ret = check_type(type_info, value) if not ret: expected = R_DTYPE_MAP[type_info] recv = type(value) try: expected = expected.__name__ except: expected = str(expected) try: recv = recv.__name__ except: recv = str(recv) raise TypeError("Expected %s, but received %s", expected, recv) return ret _DTYPE_FUNC = { DataType.Integer : int, DataType.Double : float, DataType.String : str, DataType.Boolean : bool, } def str_to_value(value, dtype=DataType.Double, dformat=DataFormat.Scalar): f = _DTYPE_FUNC[dtype] if dformat == DataFormat.Scalar: ret = f(value) elif dformat == DataFormat.OneD: ret = [ f(v) for v in value ] elif dformat == DataFormat.TwoD: ret = [] for v1 in value: ret.append([ f(v2) for v2 in v1 ]) return ret def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number. Each part of version number can have up to 99 possibilities.""" import math parts = version_str.split('.') i, v, l = 0, 0, len(parts) if not l: return v while i<3: try: v += int(parts[i])*int(math.pow(10,(2-i)*2)) l -= 1 i += 1 except ValueError: return v if not l: return v return v try: v += 10000*int(parts[0]) l -= 1 except ValueError: return v if not l: return v try: v += 100*int(parts[1]) l -= 1 except ValueError: return v if not l: return v try: v += int(parts[0]) l -= 1 except ValueError: return v if not l: return v def translate_version_str2list(version_str, depth=2): """Translates a version string in format 'x[.y[.z[...]]]' into a list of numbers""" if version_str is None: ver = depth*[0,] else: ver = [] for i in version_str.split(".")[:depth]: try: i = int(i) except: i = 0 ver.append(i) return ver sardana-1.2.0/src/sardana/sardanavalue.py0000644000234100017500000000354212174204314021752 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## """This module is part of the Python Sardana libray. It defines the base classes for Sardana values""" __all__ = ["SardanaValue"] __docformat__ = 'restructuredtext' import time class SardanaValue(object): def __init__(self, value=None, exc_info=None, timestamp=None, dtype=None, dformat=None): self.value = value self.error = exc_info is not None self.exc_info = exc_info if timestamp is None: timestamp = time.time() self.timestamp = timestamp self.dtype = dtype self.dformat = dformat def __repr__(self): v = None if self.error: v = "" else: v = self.value return "{0.__class__.__name__}(value={1}, timestamp={0.timestamp})".format(self, v) def __str__(self): return repr(self) sardana-1.2.0/setup.py0000644000234100017500000002516212174204314016246 0ustar cpascualcpascual00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## ## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## ## Sardana is free software: you can redistribute it and/or modify ## it under the terms of the GNU Lesser General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Sardana is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public License ## along with Sardana. If not, see . ## ############################################################################## from __future__ import print_function import os import sys import copy import shutil import imp import StringIO from distutils.core import setup, Extension, Command from distutils.dist import Distribution from distutils.command.build import build as dftbuild from distutils.command.install import install as dftinstall from distutils.version import StrictVersion as V import distutils.sysconfig try: import sphinx import sphinx.util.console sphinx.util.console.color_terminal = lambda : False if V(sphinx.__version__) < V("1.0.0"): sphinx = None except: sphinx = None def abspath(*path): """A method to determine absolute path for a given relative path to the directory where this setup.py script is located""" setup_dir = os.path.dirname(os.path.abspath(__file__)) return os.path.join(setup_dir, *path) def get_release_info(): name = "release" release_dir = abspath('src', 'sardana') data = imp.find_module(name, [release_dir]) release = imp.load_module(name, *data) return release def get_script_files(): scripts_dir = abspath('scripts') scripts = [] items = os.listdir(scripts_dir) for item in items: # avoid hidden files if item.startswith("."): continue abs_item = os.path.join(scripts_dir, item) # avoid non files if not os.path.isfile(abs_item): continue # avoid files that have any extension if len(os.path.splitext(abs_item)[1]) > 0: continue # avoid compiled version of script if item.endswith('c') and item[:-1] in items: continue # avoid any core dump... of course there isn't any :-) but just in case if item.startswith('core'): continue scripts.append('scripts/' + item) return scripts class build(dftbuild): user_options = dftbuild.user_options + \ [ ('no-doc', None, "do not build documentation") ] boolean_options = dftbuild.boolean_options + ['no-doc'] def initialize_options (self): dftbuild.initialize_options(self) self.no_doc = None def finalize_options(self): dftbuild.finalize_options(self) def run(self): dftbuild.run(self) def has_doc(self): if self.no_doc: return False if not sphinx: print("Sphinx not available: Documentation will not be build!") return False return os.path.isdir(abspath('doc')) sub_commands = dftbuild.sub_commands + [('build_doc', has_doc)] class install_man(Command): user_options = [ ('install-dir=', 'd', 'base directory for installing man page files')] def initialize_options(self): self.install_dir = None def finalize_options(self): self.set_undefined_options('install', ('install_man', 'install_dir')) def run(self): src_man_dir = abspath('doc', 'man') man_elems = os.listdir(src_man_dir) man_pages = [] for f in man_elems: f = os.path.join(src_man_dir,f) if not os.path.isfile(f): continue if not f.endswith(".1"): continue man_pages.append(f) install_dir = os.path.join(self.install_dir, 'man1') if not os.path.isdir(install_dir): os.makedirs(install_dir) for man_page in man_pages: self.copy_file(man_page, install_dir) class install_html(Command): user_options = [ ('install-dir=', 'd', 'base directory for installing HTML documentation files')] def initialize_options(self): self.install_dir = None def finalize_options(self): self.set_undefined_options('install', ('install_html', 'install_dir')) def run(self): build_doc = self.get_finalized_command('build_doc') src_html_dir = abspath(build_doc.build_dir, 'html') self.copy_tree(src_html_dir, self.install_dir) class install(dftinstall): user_options = list(dftinstall.user_options) user_options.extend([ ('install-man=', None, 'installation directory for Unix man pages'), ('install-html=', None, "installation directory for HTML documentation")]) def initialize_options(self): self.install_man = None self.install_html = None dftinstall.initialize_options(self) def finalize_options(self): # We do a hack here. We cannot trust the 'install_base' value because it # is not always the final target. For example, in unix, the install_base # is '/usr' and all other install_* are directly relative to it. However, # in unix-local (like ubuntu) install_base is still '/usr' but, for # example, install_data, is '$install_base/local' which breaks everything. # # The hack consists in using install_data instead of install_base since # install_data seems to be, in practice, the proper install_base on all # different systems. dftinstall.finalize_options(self) if os.name != "posix": if self.install_man is not None: self.warn("install-man option ignored on this platform") self.install_man = None else: if self.install_man is None: self.install_man = os.path.join(self.install_data, 'share', 'man') if self.install_html is None: self.install_html = os.path.join(self.install_data, 'share', 'doc', 'sardana', 'html') def expand_dirs(self): dftinstall.expand_dirs(self) self._expand_attrs(['install_man']) def has_man(self): return os.name == "posix" def has_html(self): return sphinx is not None sub_commands = list(dftinstall.sub_commands) sub_commands.append(('install_man', has_man)) sub_commands.append(('install_html', has_html)) cmdclass = { 'build' : build, 'install' : install, 'install_man' : install_man, 'install_html' : install_html } if sphinx: from sphinx.setup_command import BuildDoc class build_doc(BuildDoc): def has_doc_api(self): return True #sub_commands = BuildDoc.sub_commands + [(('build_doc_api', has_doc_api))] def run(self): try: return self.doit() except Exception,e: self.warn("Failed to build doc. Reason: %s" % str(e)) def doit(self): BuildDoc.run(self) cmdclass['build_doc'] = build_doc def main(): Release = get_release_info() author = Release.authors['Tiago'] maintainer = Release.authors['Pascual-Izarra'] package_name = Release.name package_dir = { 'sardana' : abspath('src', 'sardana') } pool_packages = [ ] packages = [ 'sardana', 'sardana.util', 'sardana.util.motion', 'sardana.pool', 'sardana.pool.poolcontrollers', 'sardana.macroserver', 'sardana.macroserver.macros', 'sardana.macroserver.macros.examples', 'sardana.macroserver.scan', 'sardana.macroserver.scan.recorder', 'sardana.tango', 'sardana.tango.core', 'sardana.tango.pool', 'sardana.tango.macroserver', 'sardana.spock', 'sardana.spock.ipython_00_10', 'sardana.spock.ipython_00_11', ] extra_packages = [ ] provides = [ 'sardana', 'sardana.pool', 'sardana.macroserver', 'sardana.spock', 'sardana.tango', ] requires = [ 'PyTango (>=7.2.3)', 'taurus (>= 3.1)', 'lxml (>=2.1)', 'ipython (>=0.10, !=0.11)' ] package_data = { } scripts = get_script_files() data_files = [ ] classifiers = [ 'Development Status :: 4 - Beta', 'Environment :: Console', 'Environment :: No Input/Output (Daemon)', 'Environment :: Win32 (MS Windows)', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX', 'Operating System :: POSIX :: Linux', 'Operating System :: Unix', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Scientific/Engineering', 'Topic :: Software Development :: Libraries', ] setup(name = 'sardana', version = Release.version, description = Release.description, long_description = Release.long_description, author = author[0], author_email = author[1], maintainer = maintainer[0], maintainer_email = maintainer[1], url = Release.url, download_url = Release.download_url, platforms = Release.platforms, license = Release.license, packages = packages, package_dir = package_dir, classifiers = classifiers, package_data = package_data, data_files = data_files, scripts = scripts, provides = provides, keywords = Release.keywords, requires = requires, cmdclass = cmdclass) if __name__ == "__main__": main() sardana-1.2.0/PKG-INFO0000644000234100017500000000325212174204361015627 0ustar cpascualcpascual00000000000000Metadata-Version: 1.1 Name: sardana Version: 1.2.0 Summary: Sardana is a generic program for control applications in large and small installations Home-page: http://packages.python.org/sardana Author: Carlos Pascual-Izarra Author-email: cpascual@cells.es License: LGPL Download-URL: http://pypi.python.org/packages/source/s/sardana Description: Produce a modular, high performance, robust and generic user environment for control applications in large and small installations. Make Sardana the generic user environment distributed in the TANGO project and the standard basis of collaborations in control. Keywords: Sardana,Tango,Python,Control System Platform: Linux Platform: Windows XP/2000/NT Platform: Windows 95/98/ME Classifier: Development Status :: 4 - Beta Classifier: Environment :: Console Classifier: Environment :: No Input/Output (Daemon) Classifier: Environment :: Win32 (MS Windows) Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: POSIX Classifier: Operating System :: POSIX :: Linux Classifier: Operating System :: Unix Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering Classifier: Topic :: Software Development :: Libraries Requires: PyTango (>=7.2.3) Requires: taurus (>= 3.1) Requires: lxml (>=2.1) Requires: ipython (>=0.10, !=0.11) Provides: sardana Provides: sardana.pool Provides: sardana.macroserver Provides: sardana.spock Provides: sardana.tango

    P(Lnִ#NAA3gOWIjjkbۇGD\ϻ= LUS)I\orsMՍb"6'清:c/ڞط":̦';}~GkKӲFKSTðڣcyz97l<[ Wl}il?jZwL.swuaL{q97 C@*[E[rOlaכSBf.K l`Ypyslͭ%. ܽl;PYJci I_~"B o,LG{fWA#Tj:T7K96vPHH(_TΝ;EtrriPȭIIIւ'JNnYCtGxq$n)YJtşL ؅L^ !9k*bG7yPhr+k~tD>Ge̲',-Lꢳ,޷  #ᙛ_n) +5ƺA;lhΣ"Yg`$SȔ9dNt}FCti_߹k{'#vvaa`ھr/S,+TRT8 J70Oo D y-6&q;v쨪 7ޠ666ӞgΜJOF:tرcc`pעPfffxx}JJJ/_Ĵ7nL2֭[)))ӦMУ)#,}Uc֛`V3+D3qtCG6M4B|7p_(مMq#j5C$m/uC$$ xY Sͬ7g0Sr?(]%϶^d kٴZ[W/8t^+"<3ZK\is1׫&Nۄe'"3qg3_`!ޒ]WH2vêZGGsF23_z5:B.{g4m*c4j~H$e˖{6n=z43t+fΜm677oܹsw %11qÆ `Yf޽[$-Z\zR">>T#A(y˖-׮]ꫯ|||pѽ:=aѣ111.\~@tc#OŁGGL4>,H=Ĭ 4@"}S%F*ƁKr)ӅbqOb8XF?XvB0o/_Z@=} z5LfB O1 ni/Uq|>y{TJu>GGGKKQFFFDD!C/]8|x'CBB/]0j&Ҧ55FޫxA__|9,, +()**tҜ9sN:xƱÇ=<Nj4&] 5zbS^xQT°+//^}¢@|Æ CV1Lr %D߮]RRRJKKM16]t) t4 5.((r`oo՚ /h i.f7]AClW:JGSCi`,3 gIt`LLZvzd3`y~ʌ%ofG*\Ҥy>hu~Ejơ^u6 +VJa{9oi|@3'&&:\p!. Vv.44"b:3] 5QӀVj.;t6TEa96%j]_k\U@k)@@W/%6}>k]h9H`&n3TTߤjÒ"&ߓN?3M_`ԶVxJ7Ťk9lA,%v"NWÈ;M9t"8p۷KJt1" APY(--G9֖]儉M/aMÚ&v9Q(|} JpWYW*h-r˟9⪲2Hh=Éٴ Jb% MbA~h~kkke2uAA}H#Ҹ;Bx& ܸ:Ǧ: Rff}3:C ,,oٴi=H {yzzF-?:u)}㩥 ;v 12$$$,Yʕ+| 5@-tKj.{xx|JUUkf(dݺuxhjݿocj>;v(|2kv\rС-o߾}Ϟ=t ?>8wܗ_~ ~avg}dHH믿yQQ^P8phr0d:S [ģ?kCM?N{&wAK.eR:f,HE  [^pabb"{bԨQ b6՟x߿MLx6lM%8ph7̬ɗitTVV }@Нl9tRt!O=@urk;QTz6Ga&\7<^>,tf7n4+Uwg'G@^h`SV)(V z~k9]z__n}ȁ݅iɦt;̤^OKp"8L=n_ wP IԵtzJ Л{zz< sF88d2< I`Æ K. a=ebbbJJj֧85(//wrDrrrKhnhçwϞ= Nh,T*\$-- ӧ d4~Crw`SXYYYOHDG/,Y" >=f̘Ϛ5˩YFyf,tC߅^hO`̈v~{-(()___P(x<VZ?:1聛`8. #@R]z5**$MKK[fr 86`Bn Zd84AϰT*ݽ{մi~)h?[ǎ;n߾ӧFDDtq5iff=((H?yKG ͛7Œ$8p6矧N*&j @6KKKějX)2&;@@B2L @Sl9PzzM2O>$K'_|y{y7KfT6ugGmXdOP4+駟6)6Qá \Kaa!8/~YuD_oBA? /`pk}ׯ#=C7g+++QMBA7z lG䔞ޞ8N S珟x,Ozk_ܤ{x 9OH9(bYfA,>vѣyyOyAdgd?x~c&ND`tܸqc999 1cg>sHN@>}:=j'Nxw`ž͋C?(-!!t@SO=yf(qqq ~j˖-QXݻwƌǎ_ "zMUj_#ęAK;uȕ!5"*"ETOQTW:|-[n޼bժ S+DĤ?=&MZl>꧶b `ʒE]g'BCC׭[^{1##6_~7E!=rǎO;wnԨQ EP)O,--e2x Z5bΝtow}tRˁޏco~]Gc ʢ~dfدUNR"5U MHBK.B}Bˢ`;AǏ¾_jh[jx+{l̙v8pFͦвC:k=k֬UFg+Y_--*"UVЪ괵Ƕ=݄QpGBh_BrkrUǦMP'IEuVQi40kje}۷/{Q7V< F]jj_ϱ1iҤo^x @n.}ܾ};-&&0 [n <LISBBBKŋ|>lM|ܳi o)Fi&āމz=7n\r0)) !Vv:lذ[B T*Y)ȼ}âܬ\MTD]OuD[ŌDF̘CB{ Y@H)!?m[|>E573R%Ϟ"S*OpK8t |m...?~)Sc  dY[[͉ %6GH߂[[ŋ_zL~ 66*m۶ 5FE"т _oem͛7׬YV)gςM)^^^C !@0 cǎ=x`26v~N7nhD#QX ,zh!j8݈xbT/uK4HٚF+"" HN6ox "?7[f U<3;v~x,TWN`w"|衇bcc ׍KXחBux;&Rlll`"…m-C/DA`Y*Br) )//wvvnL[k ClȻ%<;wy8: s n&LH/pssH3 4Yz>(00p@( Q:A~뭷(=CŹvLvIťKRRRpmtt~_#p89ͦ_;)HIHHΎD>8)i'|Dv!Yctk%!Ty0i X7nd]hgg:xzÆM5p/]BKBafk;{"c Bƌ[f w4pO>ĉ+˦,a@nE/ʠ;> ^^^Yp tG:r6: NQܹ… Mmȑ# i dS^^hrA?j3K WssTZ9nIZDLZ3yM i7OΝ8Hʔg'̝ۺa1=1QlۼfP\XYȍ:XiӦ˗űDEEE-, ~/"("  صk|HHa?:kر0.^ {0.KgϞutttǻz'.o arlʁC&)G3UnNNZ1*,SOؾN5ZFoP3GE>8jRdg-PX،270/7gt~e˖͞=:|pkk디o҅x)}ܹsaH>s~wߺu|UV9;;8p`s /㹹O<>߻wo~~~K|ρމ[o * h5_ !. c777-}UnI,Ƿᩧ2|Hk[bBzXYY\8pؔ8p*86 M9pcS8pؔ8p*86 M9 222z!LJ% {8jpl2D.tC8fffv8p0M9B= 8pplʁ8tr]Ǧ8pCWqj4R)z5z BնL.[pVU*U+L6~:_Rtx{{p;~|';$p֖=n`SjXZZL8n X$WCG\JϜrQYYy֭V2xyyO})RizzS555],X݌ ))0C lOIӬ{7nԩ/=??q j5k|.SP$g٥%%% z˰aϟZ$ _N 0M|?׮]ZJKK#""ر[۷o5kz$CTT aaa.߿2a„1c %//… Ǐ|رc <~<7 ӅCP8qN/$zү{>AAA>͛!8^y3g?~!xwժU_uoG.//(D!8{%)zqF+? T+>>ɓ'xx?wqqYh:'!myܽ{7 qvvNIIABܳgϳ>kkkbŊorٙ3gVTTZ(mDɋ=L BP '~>}Z n ҝ7o\.p}Μ9bOP__"ϬEƂ2Ħ@Yx1k@Ԙ-Is%?k D iӦ'AAp 'B$=874"-͕zW\i= >}#ag{@2'2aQaA0CP&,Q<E9;;)n]J+=Bӂ;eUZFRTA7?qRG+++`"ɓ'+njSko(ᄑy3/z8B,S>@鬧b-63Mbw;^v}TB>^B+v&Lh`lilI7f*ڼ捤uQʴe@)|lB:uw#55uЊqg{쁆wОJu 9-Ȓ9?e?<4K qy hEYY%%%^^pnxEgу'OcD:Z t7nCς_N80~bڍ &r,,qqZoM9r7BKMlS__?N,Ϗխ?mClm:'^~9H/56}t٠^@QRֵt655Uߝ  p(^|6ߥWzʸtV.'''7jnTŞH$F^*J0=e`iL?c nV(BbYp#[-T*vz\(0ʕJ!8n)ťJ7AT !"IJf[KJJ VTvfi'E[r;[s[.R=\@h&)UZ(*TD6mVv UӮ%Qgȃ,d2 r)]Ϛ[B"uݩcY܈999J5n@﷖APiɸakiLM;˥RuX3"҂oxՀp:OWRJ5:_TU+T<]9rzk+s$ovr衶J!,G"w[mLOٴp6\ I0Q[T`BJ ⏤ZhqUl7Z:v:/T(/7!(JZh봬z0bŭJUf\BZX;"&%N3~|t`͆e kMu"fd arEyFN= x5nHkuz,H*\Y<Faa2]g. z#>6zˮT aZJo+򚄉y&žBKܜ'Ng_[5,m{ HdՕ)It?*gOq~2Mɨpw-)WLǾLq5M޵@evlp(k9:5V=F'Vmgiڳ}fffM֚SMŶvۼJbs3)YT[lu_qrOR)P8F,EfaBPla{?,cs4B(4Z-Z yQ g.xp+ _.vh=/>7 􅚔zoh/7M!\-yCl Uո6}-';^?I(ܕZh` Jf>BO7aU ~"Wjly,tY -ـ0nFAAAEE݄zHIz{4q96֡#D3JANƁGKtʑAR Y#ՔWb#lx Ηt/\Skc/Zgܒa|NZf;xo3fxcg駬Z5r~Ka(>=M{'xGUT2wSJF| nH,*)W͘h? J!'UXx5Zthnz^zUbA֮w#K6f ,`(y*npx,[2 l6/_}a;-y/8ww_?C}}) H"##{8eS\q+C s؋yGS-E0MpIxna>Tfbms3&k)?]9 uuJWVKc|bNy?>xO?SҺZ6 kˆDR@0U{ !{X8F۝ R&9 )'jɒS)ֺ'vZL[@R/ǁ=fcxثLqNLӲYtC: gg+=݊"9+yB 6!,.Th}3&F%tC: {{˻pWa60((+\!nnP"nJ,Hsmm| !s(jiMOD[^R4V/ s,z -i56~T!M㩷3!Kէ @dWsMwO7<{޾,#ǟwsIoٳ7ZZ6# }ّ=ؘ@ tmPzX06=0=fOͻzݥZj}#FDzDz@ooj`jIۙSR[oeye+OmR q'MMUC/TSQmUy*.`@uD=%.DQzI՚ui{v617?7Vy8W+d*?^w^}[s[.mOu-R[D +ԙj>'NFDWn=K5/S'v6ןUZjlն v?>xsGkzBf5lڧ WrҧoۉX9%HoG@}DR3mAadߤrR~\4'}x3%Ȑ8gCZjM5A#D}@_'MdC$٘iuTŘ9<.kIEYFV)U.vvtJ]D_mWTPTTdg.6.Y}O?̋^gw\TPZda'ԨU*R]S,)(. t]O"e=ݎ.ۅٓ&Ѱ=|{&L&̊jpV* {1@QaAYY#R"B#zU](2*vM^-\Ix4;5DL&iDDxȶg;ࣸ]{/H 0EK缼$vj;ωK9MA Z?3#֢E'wwΝٝowΝ{hLFGɨ6hh[L&̔`fF#`{'f>7pe]YVm$Z+w-$:I@ӌzE%A#fMut׭@3f ݸ w46aOh;L-_%(/%ןw{zMg@O`l` h4A ?G}bJۧ+ e{Eyn)cnz{9>^^ԿZ ,uMD'}EY]Uuxa7vKKes-gWMm;-9-&,bp,w()<z]x *,] Z9g]gLVd⛶7T~!iJ)-2ʡnz7J(j^q5g6a4Ǒ( Q={vN T*l]l)'Qz>RJ,lllk~=DO= }x1K|FN|Ʀ&oDZUNIFԣI󸣙md՟[ю@>>>曋oС'ݏl<كfZ/}cri[?:`zϿRwǟ㰧, /r' 7gz1sSХvjFzudbI!y+mh7ý(X*4@9;2-8П4'Xbue *ʥ˖oܸ-;'o"#p';ۇf:r-녟8q5UUwuv=1Q@ =| AJ'W! `M^QJݴBzj OWUM'(3rĶ{<&2ѩ'Y,NЙ'm*yеm4P*yȻ1 eAa~1]W/a>mQՔh|biVfֶ_r9{Ti %L 6bs87UZZ1+%%qSSOTOJJ5<핧 vt1B)b?j3lrqk5_S3v&|52MO<>hvlfor6A’DDv;D^6P3+-#9145Nߴϴ^9n4c1D Lk ϼpNx|[$?F j;dyB? 1DnB=uKK'cGjڛGX,]1 l6GO1XB3= }#^PBtXj4/"p_k`Z'hk/Ĥ#$ 69.,nOǞ7|CmR;MgK<+I\7Fc+[|ZE"'Tr5,=o$t"+ݽ/}#D;~n7;?t]P4$5-],myDNӫhΜ+*//(81<<75ML8dw^Evɹ'Ldtͭ򐐐vs%C:0yy/sv%ٯ8>:ML+=_y)S[qB/?b_tsr_)!!ΛwJDX,2[&{cbbc, 5;;G"Pk*VVj&MV)V '|Ȥ٥m>~/=YE_ YLhE F&i&SC : hnɽ',RbM;^>{ 1*9J-iIz}V> H'7~_@,hi K+L;AoM=𺟯WGbxyx)dFs0L)^}|oHZ`5R{c͇MFS},77tj&h n\(c7(tڨeczoR W^wp=lԨ4C(<}=K(xHv}Ď PiËosgwtĤ\GBǎUS!"<ȥj|7TЦ(˓dśB׎ Oo6ʡ|JN!ֱUM BbCP8r ^<~j7Fl.[%P ebQzPYhdmCeã?{w@$2%4W$HѮʴmى'vXcۏ)( ȓPl;0˞\FwJ5j6~民69N!@GAs ]% z\6̊qlSMO b\f|zx|kY,VFzR9e92PJn|^Sp8h$İ;V5Hό12xzX+wan˕(Xp1!+!9N[1 ;yށdda E #`䑿8'"9Œ.=[(+6zBKz}sssL̍&[}ܩKm?D#L8*W-,.jUF{6*\ZlAzȻ @zXy%n+wdh @ DlE#%'f b}0?+OK8zr}^Քx OB!Ǔn1ȑ#555!!! Nij=Npt&ܦ}>>hTu/2=k`͢l_pLp0y1yԧGKekaDx7TzJ}oqQ4:ٳ 9sf'OWy//-[୵j*XG"~OkKOLzr$/XjARo°*{Mܫv_>wNePCcǎhEFFƢ,((jX*zל- uXAѧ9jX,>~T*ƼQ#ټF#DrCcǎlo )\tyMs!ON\.`] ˋ'V Qʙ3) |>ϥgد|;P<( BC 0bɉ$`'` `t8'N:m@hiַfc&w:U4^բ<_ ڥ(_({CwAD >P1?S9)rm]\asdϣނ?6r{mf!7 vJt31;w$vԃYxs tޔ !Ojԩ\׬5[,q\/#G)T^yÃ9v)Vɐ-1cnЩoN{.7]DȨkѴuVg ύZ,>՚X+ˤ-((Tft^uӝjLn kaΕ>] ((hhh!f0iTzY@^^i|$P[Y݇cùj5bh՛3U5(X]X,F]=z/ODz C0p$xp~sǡ4Z6 Řɠ=߿C5Űǡ=,2vOlv]Hb< O;;u68+^h yҧgCFH!;6mQui[g~A[ L& 6Th:qK~%CDm NXE4,Bɤi4feP1>vלZի` Ĵy@Tżd2gNEh4Ǹm[9R1׃:Wm zy>2M.+^>EXɳUN-xw?CKz(K9:&a^z{`ƚƴxZH@Dc-#:bt/9lZI] 4\FN|܎8#s.0ɃMl 1ѭ7-zæ aA9Gƚ $PE d76U^h]i-(B+6~{ : 2saL͍*\_?x"kHzpVfx_KjDnB fpjZx7lksLMb|hhh׮]΍Aϑ#GnYO>Q*,]t ڍ!2(91qIꛮ4y͢iΓj;RٳoȊb(wW9s 555zmᅬ򩧞ھ}{ssO>>::3Ϡ=uԔ5@&E7L{X#CcceJbCC&8p 22ãN>|x ^RRFuF[{5iNDUGx#`4A70 jAȃ 0Y`9$+`H eiPM=a$ijm2Ao Ψ)B/p5[JgvZR= R}+7,6IΏ-w2Tp)0GOMm~OڠA'mh23e,(XlAH[@@J>^斔P2аZ۱/}<A[@U5FRm?jD\CM]G rJӌzEʄe2n1\-Ҩ2!EO`շ%C,55$=9OV[ȠNKAɄ"n6 /AE~QݠzJ>c=DtP|t2"ߝhdYRr!)f w78Я"4`"Ԕx5^3P8艘tdIAb"a,ṕHh'iZMIs™ _>[l(6LLQΠL1c6> +.O!W,2r$7rФMbG^~>7 fN7DX iY~.K MG ] VBtH/;MO-Ғb¢;Y"QRx ^L`/:dn\sC/Mk̍uVyD j}?,O0]"S|6Q#V,ד ! bЮZt@Ecw1_=Ǐ?{,d47ŋ#_|Μ9LCKKKSSSNN4ü*/r7@*䃌PrVM?7,:6`PJO,LIl9|^˯H( =S6YX 6Ф'FUp49Ҧ3D?կnEP pȞ9{eX S7>6a)h? WJ䘐 [BtdR J-xjB=DJtH!ؓa_ Z a mbB#(H._c/xhr z???///TA,cgq5k֠riJ5w\V[UUYZZZSSrjժ;wfffFGGWVV644ӓm6l 6mBa۱cTGݾ}EEEbRD)c0#79rxK\[oԴ*>OPΝs\ N4`\K!>9w~/VDFN=bqgeN3;`G9; LPP~ f(D°PM k`Voc)$jDb6D`Yr9Z{npe5݆aٳ2eggZxcz Ub-^xƍ.aaaԢ:bUS(ca"_|Jull,nIJJBDp&)<<ĉNM9D*M<NzS{k5P7@Y4 gT8Qi` >"9FYl{8C0̂KaBX萦,9OjĶp82Pz(A R9EP4f;A>vS0&3 ,)g3r!5׌<t#e叏n8i>ie%M34hsy999nnn42zH[PnGFFjkk稈vwwcPH*b} vq;JX,^lEP\Fc*kjJ5"ԐIllqao N?}k&pv~gce& PjjN$|>V5E%>vuM*9(kpʡn; ݍ,0x<~heEuZZsr|C,fsMON S,fW~%?Sn_ J=7f3دRҋڒ:;rO\= @JG卻:zJ)[XXe|}w?cޓ[tb8Jv *!Wj@MN񤺢?l2{2 7Sn2K.IdfoM`E[$<1MIȜYsfܱxcJJ #J ގKJJx'xxb{ M8 PTSb'=ǐkȡ/Ve{ 8pզ-ml&kMV#c1n-DEEQ++VkKGGca^d U7NKooɐtljN-ƶ-x"N_ή|fv4wq=<"MX?p!(*(29r;} u[`0С۳g7|uS%9ydii}r@kk+k2$nՑ$#ˎ91dBAֵ e=>bD1rpQIQUa%^IJGGy~a/~/'}Td|(l->3B}+ H3)y)7kVTxzon\jᛀ<_Sa._Zl,BB/ <22(`Qm&/qa, AsOaBH_W o8r Q]9*PR:!IqR75`c& b8p=x/+ގ^HTSb `Prn49sL¦KMMkAA(117\~վ SN?ewFQ?w*j%҉k5Z wЏלIsuիWNC7OSR]]n:?1###NWS :ch|n4.sQptʅ+(MLf4"w|#sqwI΂_}mH>qg^Y'{؋>6|mG'))(?]]+ׯĦPh%RfTCH2_u*o2.\ @k˖-Ƈ~V8|C=mt?Ðj1$A_wIVx%]ffVG7 dP$nnY.`]>{ЖCdːb'ku)ӝʃ}|判"|6oy<(moYf]*X:w}+|JB:޽{'x+'I0#' H YF'. /2>BsoAا]f2aFԧ;k}ñf= 't&Yr[ATdJ[`,kJPC8>@LL ZC4`J=ux'N?K>9 |[`e8@= kT' Y OTjcŦ% $Sh2 @*Xp^BX#!RSS 7>L&>Nqo7"|d0m0~ ãDT& `0'b11^*P3" `x X<3dXfD=v́(z<n&!!a|}j\]=fdEڊnK<]LřuIcQᢩ>G|ބ7}#+r ݽaq>G]edo#Pؓ~98QG$B $ۋDQD j\}&×@>eKٱp# @ VfO$vpfq'5ݳ`?9Ku,ǿ{|,7MY }SNP'tTsd(ɕ[CL*<>jjb HE4 껈Inb07HN2dnNjݵ~՘f4ZGL<4f.әs1qŤ1贑Q`1mI7֚\ fGUf7XZc{xxx^g < {חPe <lŢ)GM$AH pz=aFU&&f mz+=:3MyNNoA≅ FkrΆh >zg?`cHW d8V@4>h4qPQG,ߦ3@.ۗ!=H1g=,m=CA,&]gO$MeVO{Z4 9/Oqb|} Ds1(>,BŐ˝6hFƆV-.ٞ>CrUmiCWR1d6+ULqq)ZexV~y*Fzg%YC}pd4fK5:zȘ cSӝi6mtt:Klɠ}_"dQMqmЖH\e@oΕR(-rǶ9V`zJD \bӍj0& ᧟²,(DA4r٠ÁfA^ NJ Yg0}rmU@ιK~^J?=]}Q/G=JLQƈ.:yaEVg %FE"ZMT/4kd1hJD̚ue [͡܅E?7l7H3{lGsȹ+? >91O:@vsǃE$hNJVk))@?6R֙*Pz7,-ک0G0LT^V&SIմU#3H$`N>էT2f& x4 Sb!Et¬IgG,M,-PiA7 A`!Q\\GdgLd7h FyGR;vf)s=Z!kCѿˍ;n轈 AUc3Z5u^LتO=Ybt~/bz#$e<bk^F#Bj޲D*4wHP)1x!oobnbz1_5lTr%gUSPҾ_]&%''֮[ѣ%%%555UUU/_5k֥K@M LAj,1Nh @&4sH;M$:wȲy_jV],+נd4dY>_j2ƣyDhmt3kQ5LI x{V.+ YLT0vFdgiwussDEDFFGQQQMMMAAA+-HwʚY> j`Oj?L{pBL[)dv1xѡ\|-_GmA00+icCD<Ob>ZAc¹d1,F˺3cA,d?N'zF?{::Î>h͚5s ``.˦6nDjDz2`=C~DvMVpl*$uo˗,j\$ $aV} )p)xH)W%(xd {"]tu+V`$"A7oC`Fgu""YAdd)Qi")NI0~xAoQUgYAhjn$ t:;/T]I'IA~300j* WZrx{`\qɣ|2w)<)TuG$&ƻ.@kkD[O4ɥZy/?Wyrjb4wFXXƦ@f@Y,.+ @TJRJill7IdIIgxԍ|L@Vq[r fjʭbJg:X_Jh"l 44SʑDޘvX|l&SO=?Cٰac˕"^Iqo _7N\?[=O,wd;'i?gR3=[ƪ'YYYW^Q((H|df[a0f@@߲sM pZ99q4/8~8zWDF, x`PP^{v77vGZBɵfs<;{Gs:AϑwWOLj5 2\y{w^^4=G̽}[ie~?|b؎C'2lҫ"C ::8Yj&gY1e0/_v07oZ,v\n~ӣy<^ocúuK,ϛ32hR)->g6G:Y1D,e4oqEE9_MHxpQL`ÞY$ eg{]ʴepQQ-M[hed7Ks=}<dhyb2T0*ۯE88; vAPgS@ƼQ3*AMH0B()abx{byd,Ŵ}7l`Lv>ɒ{zx4F-hP|ofW%Wk)f쾝p`x=<"|Mm)!a/dٟLyPx`׬i7بM1vy%4Oxk1iBIe׿~![/6e{+bOfsP4`)w*:=[(YhѾ} rP}laݺuD"/\]^^oyÇ?tҥ?ܹsS0~jjWO/A'"O}}Qe [ltD/MMh1e8٬1DB[jȈFA*{xxF$հ2`ZB|n"8 L@72O nr6*vHƠ<ߵW.xZ)ARTh'R_ BXVca5NOr W'HRbfZruzB[} 4nBhϝOR y/zH+HSZG/Tf;B8u5վlvf7 F>A!>s Z!駸=999-- م#2  NuV??^j5kK~uڿ/X-++ m6l˖-zCCkuW\)((hnn 4g~vR4속uwRSӛ<ɴanݫ,sb\B\t,D$8rebtEMH'D#}򩧧y|Qt 7P(DcSHI$pT(M▖&Wc-? qu[b@4b @@DJ( L&iL:Щu\>}lf6q#޺}}%qrHGg63M.\:y'berOfEJJ gww7:k'OC A1Z={,ZÿJէz`ЭS*H2jLs4xߓ:L7 khv[lԞzbOE+-|?:5ܔXIJmnCJ$y7CFasxg"C,`1hL߿$Z6,> #'Xfյvd0.Ǧ!ctӃ"#m NCLL DVW WX4\v|0o<*Z(UBeEwsO1Ő>;DZ8L5hؓ^Vlll*dffbPoLj^cۏ-j,c&.gaΥS$cƣVۿa?*"'("gʹQ5U'Fn?::2RBJ+J5ٷ%xkSܽ}|6##c C''&-Yt)U&1^HMMWa 8fw1c{({|?(*pק<|=RS0JNb!:-:,! C 7/7`#ێd7L9e9Hh$VWt'--B{h!hpw_%*ؠs~ت^$l903da' ԳUT?^Ad͇Q⢛7+ؔ*y%d& %fg>XrN2RQ\^, Lԁ2ƻ(أC@!R<.>2pY` w{j:Q'\86N(fgg۲̙qrnd?#g@PpjJǂrh?e4&},qUca}߇*1V k=B(̅\gZO+X?Bh'|.pT;oP;턒i=Ȁ8{= F~/ ,?^cç!ʓʧpx lуs'l1X|<" y{g$%%IM7mda$d{,&0I>75`F<KT!ׂf䌈r3 "v=֝|6'0cA88̂fnrS#|LITB4K<"$PYY7)4Ɣ# <+jj.syguRR5w wR}sL9zWGG+Z,Www7zm&22ӳceT;|$\.SN|29Y|LEfGJ$"']ϔ:Qb;\s {{{U*5cJ%d2ѻVD®.777Ri6c0Q ~<j~@c<;3p^I,Zuc'%(Wok A9 rprPS`egP3inHQo^2*%J#ϚU{v=UGMѣG˷n݊.??``СC</::zhSSS7nܸ~z4XNGDD^~gܸrJOhf Iɤ6^ReG&hun:#̒Fq6Q#rƷ@„Ćܐb`gF+;|œ)9h4RəO<8͛7n۶mݺu]577ϙ3'N ~0K$EB|AMd^w2Uk:`3 1Bc+A4HsTk"OXM<>/2!DuؤpgII &SNO}|kQ=<Cyꧯ},:;jbbn=* ^[8mnz'8;O{XԩSկ0(..~w ܹs1ܹsgVVK}V aǗ_~|r Y-(Ov2 2=ZʣD"Wəz<28wZxRxŞo(Ո*97]wzi_.::{;{}QAJ8,.aɻN]N>ﲇ<|=?X t©׋ܹs/;pP )))|>޽qqqŢcbb Ϝ9ၟ"O[v-V~G?`=G`RStH3j:aH8<B0qMbDr~\?) zNb( 1i1G_?10aІiNHd2f6l&0k{=xQCgJrbbbϞ= `T`'Ȟ;w xAt6!7\pۉhR4Jʃ(Ll*(8sg #Q1΃MNN'JO&twu>}T`͚S'JMJ9̬qD^A0#u#5:tyή5 bj qF޿jHoPAlи߼^'N9-k^A&1L8}O+]^.3Am4@ [[1}&{hN Xw1N(3(4O!fL?Lh0QAws8 n+qt:w19fa*B,F9].6n+:䔔6ܼyu>@Ad\;|]T߆/n-*")ƭ$WQWWǏgמKẶ;Nx$utj*ٮe?Sz |i5=AB~#Chi$:mNPf1#j{zj{'È{ߝ;L~>˜v ,9@,e(Q6pZ{|zkiHcfaLr)%`0|i̜q d@KE]4KHZ"#"?F+I\.W}B,2rlTy r9\ͳkJ76C0dmjjw'+JK. }gee;|>jm37]esz% y 혞 AFts0E'N*JPȦ&@mw)O==QQ#WtD]]uK0q E> tHUa_g0HKTΊ/1/`@[,3)G>wle`^a[B]u7BSDOL*dryy_X[[1?_KOCC; v:]!"w=ˢ_h6j }u/:V;v7 iZj,+k>wFjb9\gFFЂ^.\MMK;B_NhG<NGvve2*aDZALjln}ܬ>EKV9- ^ƒ99'|K$`I4] <0qWyx^7<ЊQT37W?{:vҥuffPTz^c'=x,.9&}HCPPZˋbp@`ĹtC?~Rtuv>-!\(HlNglx̝^ٮVK~ _2MZ/zl)LT9uAOU yMAJAA{^bʃԔDX@ߟGU{,#8$R(JEf3@z($^>׻QDVVƔb``h˙S!f1o;A>^R.U*QP\?\_?zw^S\L}^6;!5A;ۆ{/'pQlQ{3R3zƉ|lÇ\k}gz=sl DنB N0uQM=K.%xϻo`,}}}37=z\R"] DHq#Hlm%g[, `0-===ӫ)'ر}}| I]IW:%gL v:nO9@ýIq Simp:>ރ`GxxgeZjc2ng0vw<:;*SPq##89H?m'BP+nza3AĄX8 W,@?x*L[o7L&͡Wza_2*) “O[& t>P+FF>R@JܵpFF_>q9e}J{C`ܔy•/J*95j7_gqX3/>uTdr'o|p8R$Rj;¦G,0x\;o<\zT ȕ)mt>Ll)d)g*a420!QQ0,ljpXΙ7D$DTHMkdڳ Yl֗Wv l2Mt:ܨ v 4R\nBB۾3g\\ZZ Wbaa!tO1뮻jd\{`|*xbxxxyy9a7z 0 ЀڑMB9(uWSI$i?s.w ][՗U;;G&X&NMƇB?rfm˴ds1LcUzKʼnO:uNX'?-|oŅؓNv5w夵յƆJRfʳT|o7` i&R ~=6l⢢^zٳgagddd[[ft[nwɁ[555НR&''$y x}6@G/_~zWHubb"hVX,uuu!!!PIDDTuz>y| Ћb@&y^z/ONM(6U4. ]N çխQ=,+;(6IJ%x-|>'iôOf6P U`'&d'}玜  R>424,0V)I c2د[+ I(Z5"x|`PMT8& `?|č7;;wdAVh@8mKK G;}4 ]r%44;wnP\-DģB1De=]]]Uj a? CUݙN4og3cV`{jB&s0;iJ<lk02lci.k7J}"ʃK"S'moJqo, i0x}Ar9O? 0l__l0m:p /p1P\F&Z >?("9ٽtrPP Rf^s``\%5n:>fC|#ʥTȫA2bF?#&6/Jx|ަݛZ[A>k.EU((.'ܼopܴsGϙ fGPߐ324fϖwRFsZurlx,5'Dӿ3lW@uEy7`0w-ejX][SUSpt0B=DjުU"?0<zu[5U6U_&Yu4n =yp W_ogsgG};rf|dg%;! R0Qu 0^FW >FNV*V'+lh[0B #0"Ф7n-6tIPY: \.``鲜m95j ڿ[@M_uD.u1 fya#<Դ|Dp)l(k^Z +$@>G PƆt.O;:}u/> ȠSȸ|.`n*0xnضgUiE`#FK-WZ:wӢw׷GDëbʼǷ B .llZl{C_"okčDQpb$"M= |̸޶^^OYT5tobp@ 4GۢƒC󭰡a B>妩b3}fv[Jrp>_Y]CM>Ħǒ <NH:LAqqyTFv_DK'NMbO = ʃRh-|Txo!saLYc.7)`ٌ{= 2$)k ,.ٛ{gl *jsR.sO5[֤oLl_pd0 F~/&0jᰬoo%Ot>H?+LGuAzB+g.0Tmmm]]]A!`2n:w4ze5̎oXg 5fd-fy@yfٵJ`+Gc%=ذmv<:C+fU\3 .p53^y >I+cd+]ΟuOI"Bh2G630`dfm ن`!_ZQczJ63TlU±:`!ǾeTWjuJXѯ_xʣr@@'6A@@C}lF݃=\62g8tU'^t9xhZ3,v݊;vfD"jr<8xN TqD)Eik|9kcFpg_pb}G3N tV7M-*;Z֦ǫ/pk 6M =\şs׏JT j uBrePCő'F2u[ݩJLBn(05=r겋mYsYYN ec9 ݆uH uggR*%%zy( >$l6$nqxߔv,qo:Rv`A\ǁk ⤄/zPһsQJF}DWȒ^+'i7J٣DTAJb2sDD$-)K6G}smsP&BJG(?BaRiK "t8qb߾}򦦦;v"$QM O@fW(Y$ L 88$Gd̮nw92~Q{}m%N-De-eRzpz li70j *t> xNY4C0 6+8<@sdBATRaG%6 ]Nacs01{oXդ~q=RGc Ϫ|ڰ?g~{o$r- |gU-BBrtث*T*ucSCOOONn'(-)[..iw]P'B9V>w1ZM;oIW_23#STWW744 8~6ʞyM'ϻBWډ ,-G8,$z©Ybc###D8m8үOp8,!:VK˱,p0sKy#؉;m"1 C! SkҭqiT?W}?0 `7ϠJؗםJs AdQU KSE :pU!|X i+|#*.W]X_\+ u ۞(]|L.JjV$ :QUUyuum-l6;@=Q6zάޒdTalļi }`P3׆L}@$ʮ~)===))IV'&&[<ϝDvt/ٝo[DUw"3RCA";z677.l}`D^5Ҷ$2[/)"!7dO@Ed ")TKk(!!!L" ?1 233_W^ye^  "5x,]-;2Q7e0Ed]^k0;>}zr7OF ?na]8zLkVwy] -\.sǎ{JJK6o.T?殻&聦k>KBLN&DEݍP5A:e8PT0vkVVŽoBgzK_S㑭i,f`#>Ģ@[J)Xx`%.5:]#cۑ!jc˓D EbMeiRJ*ξ鑚W*{X50|F#ĘU[$ٶ}a0%$&I,řk^ۘ\;3=̚ި(ߛ̝RT:*$4b)OfWb+!L̆KwzRfVBbkǬ HIIHX H(Hsx5H,,~wGW, U:?6MosR^+l'p: p>d̗f&*^;4V,~b&y *$|.~׭y(,YsƁ yMJOxfjU[g8M oT&Ǒ.Ǡt4<<<11 {CBBjjjFFFx<^NNΔ ffS(Vh40Bε0.\Whz_C(gUg8}}}aaa'00 >7n2cAV2EOv%&x+$@t\48F6˝ys2(yZB^M#c }9MĊ=.gG?|Nzx]H`v,QQᮬ`, TjB Ƈ (}6 Yux 7?9zG (PK'|9Sz_!%{G\1A~ZCA;/r /RdQ.%I||^/++ ~Ç߿nBǏ\pze (mѳ7m, lt™z|at8*;~8.ˢҏ21>qy+O(ST5T68*fJtcO =xu6_|\;v ;{쁡iiip6XĄNc|gIIIGaE[Anb.(z=e}‡k5.+!+/_jC;:CC&~D;;jd0Ň <|2:9bMސar>z#\ yնm(sAoHRJNDˈXkFo>S(BO~Fddb*1t? uS#u 8ARf˚=_9/UIoͰ0xd"? 0-3𶻭;|V&(۟LL8j/ծ+Z'xy1l:]-$PˀܗpMZPUUe6B`t3rC0v0 ۷l1~tm9""$"硦}}YM)ނy*C\NQ//;YeTrTws7|ZE)ty2\& t}:DP@h;}|}ʦpG2)ܻˇ'&N>>GofI2( ZLhݠظq}`ϠhKO?p<6#BW/\ `j _ルLys+qO'<<^ϼ}ᇙ f ҂":WAutյUM&Jj[GG~VmP\664&ik񓃾7&:P=5쟑qID k '{[P?(Vnyߒ?؉[ ݳ{uQT#(%π %BOq([pu4 ]lض]UX4lܵ*d`oN٩[J˿D"n۴cӺ[$wJ N600B\eD,Sە|d*)]Sr ;b0v딯=*/W@&?39 PObۭjr[N27h^)m۸3&3%W*4Tz˯踮R!S$Gݱj(~I|]˛r%NueU #%]Ỹ΋ >^MɞESӛMXix͵}_E\>c?1Sg}O?mjjy*ё;, |wy_`V[[P(.]k.HPPXi@E9b2͜CD:;C$_`=#s3fR8]Ћ Fli34C8 .#rQpbtiIIIGGGLLR2{W~^͖[o0I> ѣG{pd t6I3}FsדdB,֫DACrAEWN1\ָ,N+0AS%Z g>uc: PIɵ]z7\.WAA#~, ?=7aւ'Dl )IV}[l`>>F-00uoDPd5RkԍB,ԯRUxF9駟p8)EtDg;)5 PpXd.22rɍ1 =G<@AIE,ydm* 'o oS|t\@; 2(|7ExlDs^ Lnݺս???Zޒf ܰaCnn. wnWz$sNhjjojkK*-_]lD159u}K|/I,0hjl|[(Fs4ZwK8!p]w 0))`t  ;9Jwf&?76 Ɏ)XZԻp8a)ɉq LəgvL5@ik~J듬9<ҘȂa,76m^ @:6:62"^d;ld\웕H=cVd2Wc0𼩯Q&LL,skUf!((y```J@n7C/ &x5eD~~[^!3'`W(W:SvPcj;g?f^XgW$9tO AΝŽ%))G8fo7pxrllLnq7 gz5w-a͚en f⯭`0;`0ł`0ł`0rVbnV- @&566'dN,QRiYYv< j-rì4@#be4 La`59r9mπ5eXI14)3-B0wx*`0ł`0rUMUj~~~gvubjupp𴟶z|NWpNR)8eKKhtu:aU5~ŋx" ` J,j-//wGǬ J,i^|y  y'g3 , , , ,+q@ HFGGy<\.tLa6$?v{1s9kZU0+桡ɗ,t͚5anWzЀ2e6҅mEy>ky}by9q%)J!&&村FDD|mx0f;$$O8 =j`0bj`0bj`0b$IȂ [3hl62)b,![sp8IE"HfΩ\`T*T*jh}}}׮]=b&wIENDB`sardana-1.2.0/doc/source/_static/gui_snapshot05.png0000644000234100017500000011145112174204305023602 0ustar cpascualcpascual00000000000000PNG  IHDR)O6\ pHYs  IDATx@zAM gQF lgFEbI^4*b#`"آ``@łY^T)V7qonvfvn-sϞ=D޵kU@@A 7o]~~~=bl۶m۷WcfϞMӛcٳgE"ѐ!C#){g999m۶Ϟ=KMM̏>hذam~miiieeB~vP >F4uGS QV^Ȑy&-\䲲2wA4ۦh?rROM388 w )!Z ĤY.MZR/Mi<3JnyIY~\+~m ںi{ :E畗s?ElG`͠3E9/hҡjgǤӤj8F ʁhӜۿ[  'q옯^T 5MR%K!6 A1th4=޽xLIvz`z߫WsJtAȳcS\tⶵFr̤˗/߿^zxxtE޺uܙ3S/?W]uG}ڵϜ9wo#EYYٛ7oJJJhw@$㕌L͚5|SA HeK.ځŤ{(>w~Ǝ/_ȸ~KƎ5oߞ=ghai=_?3GwnXϸq'L\}Ϟ=ׯXN#͛.\?9 C]vB&!,x ~@;2 E0UbR(g6m׷Cnֶ60k*Lb $Rǫ={Nm>w~|>2 !dҩ-;#w/0vy Gllh$Kٶy;FC 01*H$GafddܻwO|=:v]=}4LѨݻwԩ0,--,Pu !1@LX,]?w{UU/*_lqՇ*7{><ˁ]|G;{vپ=aAP4 tL!-n.]TFP_~iQf=ZoY/˅:dv=[8߿ꈁ׮] ?~ad2^eU ZOI%UR5Dыii*?,bZps7 (LWK*yJ80MMu@!2`Æ /9~x- ^ЦM|A d Ƹ|0`E>GVVVOASNY0O`/˂;Bq>C]\ Ty}qbG5.%DE"3ũ$ Ih.<%S(}b|G f!SH0  QQ*a\ΟWYN<}^&&,LVF".VLG3+b)# Tয়~:y$rڵk ݛ,r̗vٳg0:|0yyC5jԨ~ΝpWZE˰0^z[VeW&M;v,<| UPPyEw8q] gʕd˗/ܱcLĉxvpp0:!woٲe!44\ꫯ߿YQbX~#i:(޾A32Xs--6xRTRf~]-uڬC#elN^UEUiUf-8u_eosshLhmA3[ lYL$"IgBqգw1YOf2쇜899W7|ǏD"2p4@>Ν 8bĈ8oܸ,j{/w#0B 8i֬YԩLhɬӯ_ORm۶Q&NۢEr-[@L FQQ4H `0Ⲅevҧj#@>tPׯCMZ{Ȅ|2M;qM???!LGΝ{P*̊`*ip@իg>|8v@St:7𗜓A fSVV.]A9nƒ8x~BX&t l`6mB ZҙU˷fYX2x_J+ELBt: Y*[ubZ0m`bE,NVU%,:ƦpoTWԶ3cenocki1sٰwZeUB(r^dL(Lel ̿|2LG >C*Z#_Bdb`xŋ/&ÀS/oV~lS 6wwIa ʯ^,e˖TC@!} ڤ~XA|ϣC\ ܜ0y_~ tBBBQ*[_iEBjfC3O0hrh iGUVwnO9![?Ւ Hoߒ[JR 8qDdl6[dP ؖ4swR&M"snw=PuDI`o<&8t Kze\\ھꈁ" ͥK\a+?yɓɋk5qpp_/^Ȼ }۷oLsׯ_7kLeop#G̜9K.GL77{Lǭ[5k|'dOف20qsMBSfBB lСC5 )|?#iy|mڵ{ݺc NV%rp8NNNC yL4=bY:5Zh6o<~|I2ݼy[.Y$&&?~\ydip;v0W#;WYȚ5k.\@"nݺ}C7n܂ ̙CBB`9}CxڵkགܼJJKHH~KVP;ji:3΅]],FWϲ[1H]uaN>kWWں87kޜ&yߔa#5T:;|tcvL:3'̓fnE_۹CVG A8O] C^r Ciu  b>3r+8|͛7SiCy/Cy_S5ըf _ zN^5-[;3f @T!'.̇4@օ7 NG*=\>zeϞW/^xxvEePց /GGG(CG|T3dMaCFt{3څYWKEht#c"L<| 0,arHN`0&MׯC1vZղm kh)J~D 2l*[ ]WCAHzJn[5a"Db*PZZ jl]VvԘ@kZݪ؎5ŚZѶm[0L{ȥ6%,"q(o#o.%%%pg dSxu?zÂdh !iMzi# zvAAtsԩMAĴ`6uAA5= AAAt z k{A]ރ Ji]AD7{'S=F\֎?$8ξ} Tώi zrСӧGGGdZݑ޿?88ݻ]vݶm3U_~O5 -<{uڵnnn`lo A=鬬7 3f>|800_~nQTo6|pKy=p?w#F޽{IIIŋ &|R͛7CE;wzn߾}Μ9gϞmB!i57) ҥK!5yLTСCОBU˛6m}!5 1chWgBh-99^B)*[SW2$$$!!… aǏnS5eee_! y<>8:2'|ׯ_oƍ0m8qb@@yM21k,تG5'777==ܹspƄ<䄇O<[ne[Gy8HoٲE]k"HލFMa˖-svv>qDDDĚ5k4Me-Z9s=dnS5ػw͛ Ўl 5^^^ˋ/:::Ο?_ LHgm֬ٳgZϧAz=Dd0Kp3&ƍ uVZb $[Ӧ{'O\v-àE5u%@ θq͛e8v81!{ѣG)V+o-))ѣƣ\Vp왘 [8xbF-J!P9S' AZCkG40:u+I>xMll;wnݺ}$ʆQQQqÇ9V8RnVV41bu\X,UX߻{.t^aIA=ɏ=RȜꀓ)Gqqµ^ǩ3&!LܻwzKtgȐ!&LhժU>}me;9{lϞ=7%xƹsi2&OfRe˖I988hтΝ; O?ihASCMCNCA4tww?z̙3e7ay֖*:u[tdƌ?Ԣ#7=%%ٙD%5ܺu+忺_n[S\yf*?""Bktǎs}1XL2խ[ ŋ4aGԈS ༦\J\vM};vL~kqgggO0!''g۶mC%=p#ɼȑ#<-[-Z8s U |֭[WUUbnnnzzs`s%<8>>t ѣG VX@Wu*]l8q"""$CxP*{ [WZΝ;WiH7v̻yft>k0)@quJ!ǺqFPVFF#Gޣ|9$ MPh$,,lt:]CE%͛70Osέ[4tƆ\x-2%%ED^䒈|Ǽ<{{{ մf?}Bl@xg̘޳w;v?ke!P3'T&pCޓ>>WW%&&7|uM UشQl]` ZѣPe̙p*GnRx˗zsNuVXLZV|}};wu3fϟ?_Cy̱`¼jPKI&[pP=1RRR 4Q8*euݼyܹsM򎍍BVҴQ1\ ɗ*?ky?n8ݏ?pdp:FKEhqQXʱ?v옆d e۷LAa⯮o0|7P8DRǏDCîG;;#G(dRC%UAeoa~[D0̋/R/U~pp[̚5eee0ЕcF}ðz5f =0P0"a-z k{A]ރ ADנ  A5= AAAt z k{A]ރ ADנ  Qg#ELTn@1l|;JƕRai떭 cNlYæbWLP)PYiΟ~J4:#ҒR[`2_kld瓋Kta7GGiHcЌ) qkսs{g+K\EoaWЈh.<(DѷB1<@ftE9b}hW o˄-:ؽk56oA0ʃBT};(d`-$Uʂ TRV"D7--ЅQӔ'khX .LMMr#F*KjnV>ze l-$bL4 VUU@nRS"6;"tE22ʻtB~ԾӒp eFƵW޼y}OevmZɋڶoJP@Esnݺ_~>ܹsgu峲rf̘1z={¨%K|*KjnG{үء3RD\)$U2q 5ЙZvU|K~eiŁ&-po~znn}svsuX烢{A˖ׯ_-Z!&MyI{HoJsP`޳aÆAA{ѢEׯd12 _+#<<&_ի޽{^B89~xӦMKNNZZZ瘟ci`3%!Qu@GmV=dT}Unm۶,\ӳ:"xy_ ro/}imٶ2߾}/yͽϦ-,,ȒȞݹ!۷o]"2ݺuȵ6:vaKJHÂTN0Q?!4^6lڵ b!'Gnnn%̙2xxH䷂8-[O8f͚|=3":HHTLSdڻIe-6HLQ!ЬJz5=lJ /-[6R/t) k׬ZY~YoBڵwJJ:}Х7%qywr.;jEV^޻{?H}T*B7p^תM6X/]vڵ|j{ܸqS~I6j*БTo2ɑrEvJAUuG2( Yeivk*okk[O= ?r˖ dٳIKÖ3 ˖S%\`XLJ]OMѴ|79AEL~)Z o޼;wܺuKz^^țL@fu씚R  ƨAdպ J,xP J+kVVޫ+kk#|~aA :ڞ:L&665k@eŽ,-ȗ kDߔ"(PD_~}ӐPĠm޾}[ @3{իW+nȐ!&LhժU>}ZYYݻwbic_^-!j5YO:N-)2V-4Ve5t~Ɛ/ϟ?ӻU=?/ήޞ̴ŽH{vx|qd׾f # *BT0Q?>(ѱo߾$7?~7D( l6kueՑُ;9ZεcǿWǣoud /+Wڵk6j(.]-[ughR`иk(_#4=A &=֣I^~M!#S(R(C!*9J={V;;#GԶ[~5[n΄FWwKeaaǀMhmY=z\68[[[BwR?[VWA =q6$`h֝V+ˋ%UUt3X .ganٕNm\_ZEy54O[:4ѫ=G N9ܵsEE9q|=ڱq[EIB!ԢT AAZ0P{ *k][c .;ɳ\y3 6]VPZ-}4:ݣ jRV( Q%vP= 55xLV§J )n]:~ԣ{_b 榤\6u"jD iVV>PX^CXQ.le'׎6ֶvv zͷw }SH"Dc`it)CjokG:wD*drfffy<k k`0~;:ZZ@PV"h4Kh况MTQ *BK{ ׬]IX,&71L ,''ߎˣ;s] GԽ@t*BM=O.l> 3g]}Sz){ *B7  A5= AAAt z k{A]ރ ADנiii\.{ax7u/Q7J=  V;fĠ"ꀾc= .4u/ 6uFQ[M= 1 ﱶ {6mrvv[kA2ȗ2IAAA *irL{j|mݺuΜ9ukΝ;[l7n@ (--]~_p=E]@S jÆ KJCbҥѯ_O^z޽{SJ˛6md7&&Ɔ̄T Pb~.,--D%I09𤋮駟u릹Xnnnzzs@$7.]_H9r 9r d@ŋ sٲe'NYAA4 =7߿?… |>w"Hy+qv(IRRҪUX,H+22LLL\r%믿&k'O\v- A!:4-=+k[YYiڡC/_fgg?{sT~~~9$ Mf H888P%!ޞL?!Yt)piPAEƧSNCիy [akFsss[~}Ϟ=Y*bIP񊋋UTTږ(޽{「y6h *€0>EL:رcǏ'/i//ZE3SNAˇ&3 v@P&U%FROPH`rlذaܸq bccAhhhUTTG>sZppΝ;Lh2׭["_r)))111?(3D(ܼ֦M42 uΔ)S+FٓD%!T(oaaq!2 B@AD@AAt z k{A]c7}{RҰ"j)зAcl^ *"{ y:#A5= AAAt z k{A]c[[܅(\Z{4ALBm'*iMTD@Eh{'++1S>'qq A bRh# k}U;AQ|F!tׯ_!'Lm۶C1#Y7mڴԾ}بkIg' U) x|JIҝ b3̲7q >&_U*1-AΝ "i>ynݺF:rȃAz˖-Z3<"M G(-l$2CY&c ,`tV  GT"A{5 |D"ƍ uVZb"##5fx!k'OU@ϛ >!˚HD̓2dR9-COv`w"*Bk{j mexu|aar033 PHT-Ń;kjpL`~2]]$<%eir *"Gyy***@ ( y<^qqED A< t8i'eK3\R\^&r#{)#>A 8[YTo *PZޣuq//(%ݏ=:sLr`>mmm2ΩS>ݸ]1c ޡY+J͒-a]DY0F?Rg!q F˾VH- @Eh *Bk{T$BCC5 ?~|aa.gܹsNNUfZppΝ5α (dW9d b*Ay@=*D+DdHJN}QjF+d-1uQ u͔)SKRik׮ݷoB{{cǎiد:QORd Dmӳ'<Rk]Xӕ!Q/PZcރ ADנ  A5=A!QosIYHÂ-@A@>ڲ{4 :o@1"ADנ  A5= AAAt zrGyy{SixPuCc`РjcF *;cpBS8p`SwiDPEރ OO XԵVǏ/\055#FDDDUD@E xϝ;wl2n8PBii7;cƌѣGٳG(FEE-Y￯ؠ"}xիc>>>wޔM}!3!$~:n_2]\\(%$$,ZI???ȹz*wޅ044t,׿:w{n{{{,,,.Aگ_?jii٨ b"ŨҥK4 #G0Gy8HC0 \x6J=ܜ=zDm-ٳXis E+V,ZH>ԩS~~~&3 v@PGe˖)S@ OOO ߿T7nzСÇ9>>>gҥMإ LRW oEJ4\nnvKD\Ĵ޼YHKⅩgddt̬;Ġ"P$CέLM-0 i<S ##/eYϗΙϧƖ׿;W]jo/o qO)Qs2sՉ5B\ФLyb&)33l(:uC8rH246w%K@Ι3g|}}접: Co@E:CcCVkpѣ,Ji|Snf&>\4y@ HwŅ ˹\)HejrÑ~uŮ]2IڵeL&IS46%$N8t=zzR>m۶p8TÇ Bӻt b@ɻ<|5~ -ȁi;LaArݖ-%䦂:#Appgۿ[f_ 1CJۻcG|l<==!2HlBii4Fk/as,gϪ~+!_av j|߼5kV=o֬7 ݮ[ZJA]T޽,V k'17+ w-eff>}xC@WQQA.m.X料0LG=Ƃpz9iR%JByrł(eÆ _NNNYYY۷oCZCEgg\{{7ofddL:;" QyOe%q SKQQDRJ[oo9`X|Ν-sr ccK44 uܐ˗ O0bb4 :מ/6Lfffݻw9СCGiӦ͘1c4T O< IgT*€axfE9Kqԥ̩թTOD]4eʻZC |o;;#j#;yLEnӫJT =Gᦹ245|>ĉMA0 E(RnCa{%Dm~Ct*E mn B&Èq*ˆѵ/޶+`f',r2P@E1opw7Jٳ+z_իM8"Tѣki׮*#(2;qKø]4o.4H|ۖ-MnT|Q[˵yBL)==ť=W4 ?"*":7'?^s0(3=d?FTD7E׸kATރ ADנ  A5= AAAt zVm5^ѣ:KѷQM=yO\mŦMRfnnn蝞NU12Pu@#2_zwUi$A3.\U)}֪e%..NT2GkΦ{xi޽M=5޽ͯ]+jJ F*B%G޳r%dIϞUe4jVҤ@Ea{RRԳߛ m8*e3gVLxx=sYo""4h.56WM@{uOo]Ԋ^/^ʊFFF̚#M *B#syQiH,]*~M-Afa!m4Ar2_?1dZZxcsT (>s޿4;>a 'm[СF=4=;vB~YYYBBӧO[nY 흞^RRU\]] eKzI6md.E4%ͥ; ~]-p޲eBg'X5k56Q>m?)$,{w)ɕݺUMPi HJJԩa`bbȑ#|ܹs,Y9gΜFΟ??t&8 "{jfr>_ Nd][d!`СOQW_ܸZaO@n۶-á2>|8d:ޥK?`H]aÆAɎ;>}ZϕfL" RzOXY). iPQE̙zYBr&:???* >)/ ._Lh/TD#aR@QA^^ (޽,Vݹގ+ʸZffӧO4tҶ:` kn:a:@P,//qTT <`Vώc'&xV#=ytÇtggQ2Kf"0lذ_~z䔕 }65Ttvv͵yfFFԩS*I0EMlliP@ k.|ptAJ ٹ*&Fōoʫ!!ܰ0!L-, /?^PXH۾΅}Ie€033޽ɗ:rH6mƌ"LHHx䉝]@@N:kZ"QI{h2B 96SAykQRN9 7AT<'Nlnaރ 4 GGIFoO^eh&}~az*ˆѵ/޶?͛9|"ֲ08@Eha{\*%fϮcw\شMTѣki׮*#(2;qKø]4o.4H|ۖ-MT|Q[˵yBL)==ť=W4 ?"*":7'?^s0(3=d?FTD7E׸kATރ ADנ  A5= AAAt zVm5^ѣ:KѷQM=yO\mŦMRfnnn蝞NU12Pu@#2_zwUi$A3.\U)}֪e%..NT2GkΦ{xi޽k۷sz6vU+mX"]{ʕ\َˉCϞUe4jVҤ@Ea{RR{Nrv׶q8iU69;7V6sfe` +{!zTDvѵzEq&OZ(*mʙ3XR~W/⟑ѡC33H*ˆG!t0:5=6Oi~ĐiiYcƎ̙S1pVL {l :Lha!꫊ ]'s*cBݻ kkIhh:O @Ʌ /摇S>>>رc>}ںu뀀Gb@ooJ.[:tГ'Oڴi%vѭA0LM=ͥ; ~]=^y˖ N`EDp׬HDDi0ݥd#'WvVנJ⧟ݺ{z<{!!Y!!hlܹK,3gA#ϟ:thF0&LM=%RDp$s2&pW auPէx(שSS7Y[K32T<j!㻯=Ҋĸq$SB.W @Z@n۶-<|pȐ!t:K.*, d)vÆ ;v<}+1@E&C++ix^ UTnϜYѫΝ4}[OI֊2j)Zl,ƭ[c #k98l=7@`QeeelP HytdF5~TaRk˫a}[vɁ@oʕa}N' j{?$i8!CD&Tj%\ll$oV$WϞeff>}x!C@WQQA.m.X料0zLG=0gyyjGյj~v\[mӧ>;;KGU2s&_"ԩǎcӣDmJk={ӧW~:X6l/Btrr޾}*:;;߼y3##cԩ٦aR"{bcK44\s˅ӧ RRU11*n@S^ ᆅ a l0$w`ixxB5¶aCٸq8xҭ[fϯp$u\( eϵ!,싰M*Yݟ?N=tБ#Gڴi3f dBB“'Ot٦%R^x4Q0)eʥwKQ3GU׮ZhFB}:jٳ5uFzxHD@@GɡZBJ9(4SSl``TO81d"*€c̚?}UVFC aSwATB{% DUf?JCTDm7E  A5= 9mArhDW[v_w͠"O(`& ܪ=zwAEa(3v9s 8̙3111Ξ0aBNNζmۆe;W^]pݻw! ?~BX???˛6mZjjj߾}'666d K.~5UU"p87`+<<>aDDDNJJ ۽{7[?ynݺk?|A6 CTТE 0wލ7Ξ=jժ1c\vAAA" 9r eVnnnzzs稒u 21 (͚ezGTD5CGab:gԨQ h߾=dBqF( C-Pq͛7ʇL ol ӧOC>lDVP;(b ʗZТ^ YSwAETDža)G̙3asNeaaǔY%o޼sέ[ XXXPi;;;dVc 9M5tFsWFPbHޣz;vXr%^TTdiiYF 2dȄ Zj,C4 <X],@ݺ AE a{OVVVzz:>|~QWWW߿?**m۶u tԩS~~~֦Jݺ @E !yvHHHXXYl<R?~}9s8?ٳO:}zm^M5}SSN+qD(P;6;nݺ5++ 5:Ǐ7j(p٬>OTߟ4xt\C"##i6`6| l;bI?|ǘÍu~5=99y֬Y^ 8088ݻk֬U\\… ?#:D_~N; ,!8.;qmPs/~>-l6CE?=oeO6_?|Nb:R%nrgΜhԻ3M'{_|9xqN5m^]]-RgohߢQqYӊʖtmӎ?mVKt rCׁ9x$RG3/ooeJa=){RUU]S˝Ϝ ~vʂ8/khܬ{ L&3oSflg/./O.-|U")T(J?gΜ_Ǡ)S_~ȑl O?ږ+.]^:00<]/KOv?ܾաC'񉡽ԯe;G%^!=BhwN|M_lڬ9[˼AڷY롤 ST*D"SSN?dTN._iI 7o{bbbx͛7|'+V߄j߼ya;ݻwoDDrT4x楥k֬;|k:D˗/k._ѣG>MY[:v|gg ,vEEN}/tٳw(7wZtؑm…PӢGfܻ'|>*UJe6R׳D)T'WOWm;!)L=W\ٳgFbbbPPnݺܹm۶/_۷/]XCBB~QF]p4|c޽{>2d2ǙhJ Ņk]mdɴ+B-xzzht}YI W>w]F5cƌ0ZQQ:ӻw b{キj*N֒/^L+WR*..?gΜi&k?KaaRվϘI5+Sa@ִhs֦>8h%:`w/\KN%N]v~J>տysk-miY%`/3E #IUSnzN9G<)Ӡj}8 3`JvڵGoS~;a„ǏSn8q垣GߟP NIVܹsll,{Ӡ"mf-ZtޝÇnJS뤤e˖44hЎ;@i@{/:v۳^(7ҁ׶S.]bɒ%o;2=,((زe rZZcLZ{\q?<=={ܼ1=ڍ̾w=:FDF>(z:4ms36zL0S-|gz7VV5bn&9[)USYSh`4s{SFɵIQ]bjayQff&e'OQ樬rJFFK/TZZJ 6lKR=yI]v͚5j(,**b>DȠ\z<7i҄ MJhHّM@OʣlժoD,A//oG^^zy{sj{,w2L>;;K$bfeT?4Q=DEkx<̖Ӯ]Ft6m;1 /@Ѯ]zxxLhժUh*`|Sr.<=ڭ[{ ݦFWׯӌctŕi1xcǶiӦWZ?D }emb1]ݻG/✒VӦM9eo>Mc߄takO9[h͚6Qpo/* {7OcNW'7z&HM'=JH,lUYVi>}051"==}ĉ? ˗ϝ;}ќ9st]}}}{o߾;N:U>:Ǐ7j(pMq@AAu֬,Q~:p@SRR7nCʬjhCQ؀zʴL4iwSwj숈@s&Ɖۓi=ǹV"ۗN-сs?‹ǎ{\ݚ޿w_#"+k> ?H$ќG,R(kԣ"!JB\/Ōdɾa}mp(枅 ~G4H~֬YӅ?|MIJJkwޥK1cJJJ>s})gϲ拾e ,2eɓ'322xYtt4MUҁ7t:^hXJ_|Eϗt<ܩ1Zl١Cz׮]97tz.˖.N}V%˒;>`s ;+}_{csovύ5V̚&*z$RϷ)$LVT\L2֙PL=tNЩK!w Ѿr-[konp}L3+/^n+޽[W91#4it綥q=M\Km5m۶>b`p]K,˕={s@{Wlk,?k@<|Fo_.sTT׻G/잹w]6ק޷gG~6SWRO0"X=9Q}-ūEheyɓ[O~үS0zlo;xԐ=NQx\K$X$qvuh|`GHh%)u 3,T-رa_g\YY_*uZY _o䱟vqCqt<ךH}{Ú?}ο/(uvjC"+{#3b?|XUtK؇C,=)_~>|웛 J~RʁQ9\_ڥL,?Gg[W}=},XUPyuyEEW_U2 h"KnrCׁ9bX%QD:PAR**R'?4quqiX!8:z/H،ҢysO|n&&&7ؼysyyyJJ'|bŊV掅+ ,{]v~mٚ'N'ܯ8pV=EEE'O1Q޽322|||Hg޼y;w<}4;" &$$_l#Ν׵ka||1c잇{キj*xb*\Օ"gΜL[]xϞ=AAAld+'w,3S%ucaܹs58M;.[,4>ѓW_q.Tr3Zp F}رc޽g 23jÇo߾=++l}˖-n5nC1PSSóaaaa~~~nn.|tj0Ƀ ڱcLBqFnLZ[ ׯ_tѣG,Yo?رclaAA-[ϟPvڣG[n2|IIIB:q?9vYpaxx8’[R?)b)DymQTTti]|锠HfWfM3d„ trƲg8 gx#bܣ=qv:KFX4ѿ)LgnݺgCи6ٜ{gӧO7rO>֭oaΜ9t-ɡtzE>ҥKuzjͽ۷BN˗/Jtw1b"İaaaڵ8p :dt&lfҤIo@Eljj*.\`kp8)s&M@g6<<(!!׷rh(7xcǶiӦW^+Sս{h_PSH7mڴ~,w}GI iӦqF ׯΘC =<5E!Uur۶mtDTɍ4Ӟ={b~/7@g6.SeRa̘L4kصk׀j[mΝtↄwCF3%7nP$$&&=߿ hhĈ'NK 2<c@DE+0r4ΆY޽-waeeexkBsܣP(d2y2cCD06x{{|/O>gΜ1~}Nvv)S֯_?rHk+a/1yw`&$]RMƽT`k/X_6l"v9dDmDž͛7ujwވEWî'31sqELAn\ʿIxEEŦMbbb∈&=h8vHlϦz>Ν={kר&>>~̘1m:u*44Ņki}Cׁcb$LI̱!F-߄WQQQttŋ:;;O0"{9{Haaa~~~nn.=o\vq͛7hР;vP`>|8$$EݻwõBաFKsMco+11qԨQ۷o;w͛7jCD=4jsuu]UUU+s3ѣGO>:2D=ֈطoE{kjeQK7EE>`Æ \=7$'B}QCD=^^Udff^zWqANNή]f͚Eݩ^HH\U:rUը***rssBfʹّB8~3bccz<"¶8dD8D cRMxzzzR/d!sȈp#HjnܸҮ]DP?{8n8Ho_/L&h&s{=ͨ:tm%[rRѠgϞ 9{G= {.Wf͚bzaΞ=DEE%%%Q=W-VQ11\MSe$2n혰mWn1cT.5Xiyi׳wryHHHjje/Va;ŵu-[Ԍ`ӦMYJ .h^/j7ߦeqA_M4d^ ږ4Gvv6[x a2"6BiDŵ.% " F H А{@h=VV”X[y!8 ???((r{FVV{恈0]kW3o \~.(lHhcM % @uAD8r BC!А{)+ҿh~gݺuF ` DY4@&,lgΜ.A.]=z;wunq\ʿב;1/X_6D r̈]5 wވE͛7u `PrrrLLL\\ܢEtRM= ***6mD;ak3"?N 4R~fffdd$U;wn׮]cƌo,//ԩS...쨁;4` 8^jI bRMEGG_x1))I)9a"º3"1h+,,ͥjh(1o޼Aر #!!!-Z޽;Nq3򋗗C͛7s1K7ᗘ8jԨ۷ϝ;Wiee͛BD1#s72xӀՕwUUUl 7=z ~vo>4~Y*Ux2Ntco.-| zw>hJ5{\Aۃ233^ze+k׮YfCwww\{...9tu˜1K7WTTFf͚i׳'B8~3bcc~H "8fD/ |X71XiԊqTW)*j^,)U*EuRIQ:5gJw._ 1挪QDzUR0j\(k$L=#"pV= bƍ;wfR͛7oРA;vw_~ҥKG]dɛoycǎѩLA®@ l24#^XX5U[( ?Nᔘ>Nke˖Fھ}ܹs|,CK]`QԫU05JFF4"{;rO>֭c9s-=zsqww0aBNN ʪhhL'ҥKyvn8V4fnհX<|rTEFÇ-ZD|6l09Q*{*R2")#Q?RUh~V2*:j5j<Ԕ2*ڟmL` (J:G.\H(vVNaJj5k׮\ :vu֬,ICݶmW\itJEj]z"RōQ~q(䔮ꁞHƨD4Qaa=AD8knUhlտ5kϚ5^lٲC}]vn뫭~}_ff& ,2eɓ'322Jy]g$S+SsO4=jԷ/Vz7Z'=~ۇ "잠GDo۶-~ rHJ}֩<<(ht[g y]^L=l^c뼧ɩAˑL۶rN//YҾ}7:o7xs|1Ӽg3ߍK]Y԰ݖ.?>h3 )=Ǐ3}3w5A֭[ߛ1_cY8~FF kH7чnЪO}{ٚGQ>=zZU94cz,-?][S}vgS`e~3dp2}4c?ׯJu6w8uJtΑc&_Ҥۼj떯^z[l9spHΊ ǟ$~k U~=ap͛\@ak,=۹K7:wzXC8q];w,_d<ԇ=͸=vվ+{(IL+wlGItD" 8i'Tٳgh^މ6> ³1XycޓsP;2]UTTPvrͩqWWגB;í]ܽ{+cssH4`}iNKRx{{y=izlxN/op¸1yy'^}|?.bPjZ.]Xcn_>t} =w޾2*rP\܌===KJ\&@E+-&_csӟ?SkNu>olέ`-wb}`ެM{Ĥɯ9;|0{>x3wXm ?S,!kRBzofzklUUեK,\52`թ+ 5k޻W^/I{n*B׮ݫjʟ5ڛz}Ҕe]FrgvJkeLx͐{&vJ{(uMdrr_n?UrkW-ZZ?>MvyPXkeݽ75i2 ?{Y+->s1-QA@cd#|avyP5YH:t׶139[`7/64vvt?sF[X`Mv9}vrO@@ۻuO94{ήMduCgǎ~!_ c4iufK5vС+ܺu+;;;::[ٺZ6F+4mڔ1Sܼys׮]lݸqcϞ=\Sh'~ΝF0Kvھ}{(Ԗx{  YZʊڵi]Ukjjjj475b׻a-PgoVLiPMP@5TC? /0/\ِ-~YD"1eE*T"u] DDDŮ@***r9Ք;99R:ܨU74K RWJgS_gTo{\d?Wɓ'I*--uuq*|ʰK)+fHz893fyA϶H.Dʈ?%2F*St3RǯyEٓʊZWWWj6TW~AԼ =`ee]˞Ѐi[.+++}1| .p0* tjv929=NKt6d[[gx;Tr6r\I * (lAH~/ ϯzxx"BQYYIK]\\i»[KlS REP3V(_z{wXt&h?Г[>ԣC' F7osV&?)3l E" =R0>{e"N<"Maդ:OJ?RueIENDB`sardana-1.2.0/doc/source/_static/gui_snapshot06.png0000644000234100017500000031023012174204305023577 0ustar cpascualcpascual00000000000000PNG  IHDR ? pHYs  JIDATx|SϽ7;iEKRThYZWQ(eX]_R/SP(T Ad/"mҕss4_N=<#tciPVVu: M -V],Ye^ s(\?h5JKQ; կ֣^چ$)BR@H>(D`$HDdZF13b2&ڌ,ljM#!R9_lIY>wd/Ȱ (k6C& I_d4̕4 [J!jb"bh `P+`K N [E",& I{߿1AZ fLfdb&͇Cë9e&D4K @( drT*{(Eb /rL&SRٺukP"Yۿ !>>Mܹs¨:}ςrS$PYYy-dP2bqEEE]`0Tj$.]E{}KBPTTzЮ]; > q;qMHa\˭ߞ.*K~D(a40`0̿ ̋DٵsM_ ,,0i}{8q"''>3t|B[oߵ{6ww۷oN"ɍL8>>>c֥ `Ha#bP6mBy&{ %tÇ xWwa7nl١nYpم!ΫCph:t0? Ν;wyPuL~~>@NGXJ_HF5S+xdb V4bTJdrmO/k!..idˆٳ敗_/֯nE+g#=,S2o~t2jmX|et؞-[Dj4Zхw(SRRb>Bp޽{s_ / w4F͚5ߴiӦ3f +WP׷-tHaa߼ys'7;5'W׮]L9tW@RR~ Y~+'A}dϕݼfT+هRTם Y|o׾?-ldc M3AfS`h*)(>{CuJP-ɹ܂ LfSAW(1RLia*c8 ,,W^Ν;6l.2o޼믿lҤIQQoҼy6I>A|ws΅7x#)) ғ&MBwdל?pԺ_ WEUڣ5 ! 0U^Bgj&KB2.Q g20e;>4*|m!XC$(C"d 5SN8dRwY\V'LHI GMr$SHäLrT;u̵k~7B0QETT6>|8͛w a >:O%!{ JR"3/|ޜ?8{  Oh?c0͚52D$4$+l/ _A СC#Focڲe 0`@>}9s۷BA( ġ#ː͂=zԩSa %KJJ`\\QQ@x/Rhhq/_i&86{;襤>e:fB1 1~^{mϞ=:<tҧ~"H^x=d={łd^^^'q[spyьF}}jF#URֿ* P,-)~Gmv|;Ƌz#VT{ 9 % dm! |\d\9 a e)JHEV>rtKOO5kx}|3*p̹P(qXO.kUA]xo.??ԋ3|}}8l!<8S}DT5R dRNO&r}NW-Zt(7c r!!`zDA60?-;ݴŊϤZyJCh#)5a(W:_/,,<j*`!D9r$G֭[ u~0^* ZM*H,aB+)43߯4vu3$rʓ#S5AW2wt7y7ꝣ (TVz*$2= "zF˻S^F#DҫW-9rpPr$|& ϝ;wڵ~ze˖gy7owR3gN>}Zn wOt hZS,Yb0|bb3vѣGRȁA z`_QQ-rk}+_8 wݾ}{Z [a GfZ[$mЀN%uA!E@ B˗/X୷ނ wyWs^+?سV$ 2Df4wJK^6* 0\}M罼x E)C)U@F`ՃBGCRR%3f  ew/gAUTp>رcyX .ڵk}xS>ɾe.W^ۦMΝ;1d,7͛7{o莻5oopo߆^ccN<^شi$8y `훙n:H/]LІٳg:tbܸqOF{x8a(fs0LUy'͝y pOVD"!HNN޼ys%ccc!yaHIIwyOJJzrI.1hР}-޽{ BYf9ر@E_B *85`؜9sk <{  CQF<|+Vx`%x zgyŽSNYz.\8愢"H( H;OX <8###_K\QFa S%Z}%>r m'$$6<<xVJeDD? na=z 2駟n׮VeN'JKKKy0GՂ*.nܸͭ.c [NKSbccO}֭۳g#42lذwy'--!s޼y'Nt.],X?pSN3iܹ[n-|4.!!᫯޽L+޽{k4j?<.Z(55u5qSM6rcǎՏxpuN0k׮"3f̨eFUTTo >\.^e͔;\I&ϒ%Kƍ7b겄ylذaPPm @ SopIOL>jn rؑOs(m].=f.K?p뎼k3r8`yW\y?.H3c \:urZ[GnT'~X^5ׯtiiiSLY`9|#֐=Lm^dggo۶Mbaԩ rŋ555_Z\\*ڵ ܹs yݺu^tCKu}k66l;iW^w=z4s9}Xέy6lXdddJJ 'sH^,^U|@HDDDX 4~x|ͼyA޽:{Ξ=[(s5kc'U-<@SƍCUw}]aڵi{h"Pٟ~={̜9S,k֬;c-X0F.6ܽ{7==ǎ.pmȿpz{{sivQTT B4)J-i&//ﯿ:{lQx-n1mvj8לH^gp̘1s̱)=z 2駟n׮V .].`Riii)wp:e\$nݺApA8A2aA'' PܒKG90ra\ƽׯҥK@cǎ\>rrr@EN憅}֭۳g}{\&(Ν;a4n߬JEkzꫯZpׯ_?rH.ߴmvǎpG&A۸qСC.\XO<`܋ӧO4 0$-[5oƍ3jԨ~o6m8cǎ^aPf)))=+W2!Tf5W*ZSYYɫ}^{Cŗ_~?*y8 'O;K3X08El7l%Ycƌ٪jn ooﯿ&ŦهmΝ{g7n}uPZjJO.OvT*7o̥!=5`y`?*^ݻwWTT6ASs`y`?eVXQ `0 ,,m͖U!!#a N(PG<%V'`iPN  X )}0<.PO>cmÊFoIlbԱl*rڐ\ێ*6oLLb5Y iVI3ﷻcy`0n h%GPO2GuQyV blqW~_3A&L^q0̓K?!˰.%1{X=Hf6#3HEyy9LNN^n/0FB «0>rHǎJؾ}{@@sڷom/;;]{[Z}ԩ333'NXU1P^0@fϞ N7-(p\va`/΅3& VVVJҪl`06{>}12MDz^z@s Dƣ2޴m\{Yh~XS[yX~~jۼ`wi0 Cf͚Aq>I/UʃuiooohKRN8)ƣjAPAAxabF)؍ :'ʄ SF-WN26 D`Ch֗;x_CtΥ9aAiɕ[JW_}P(2\BVAgˆ<<<|ժUZhٲ """`t(CVVVt^C@pB'xڵkC\hEU6`0!E* &KAM7ً_Dy!eA^u(4A4VKcc~x>z-t\\\NNNXX؆ ֭[w^Ȍ;wIL.]&LlS\\%Zml.\`j?6ڥK J>aI Ozw!^'>K4ƸK50 M0jWO]2꛿.' 3$c*Ne_#sCQTxLkcQ+6-ԛBTr?oqľ˿/flěX, i޲r\(R$i_ݍ=;V B"¿ J% 6 ~̷S1 J@Z\FB^Ed6AA$䐎: BX;'-ZM_3kjowm PuˇH(r^>ѹS{dqֵ/h5 qSMsN`ܝ 2>}t/t?v@]U>rjS=`0'Eٲ U"$D`$A7SR藧ÊG|r-[[-9m6Z6`m d \<`07%o3Bg-yxX/(RM1_왘:vMENk۱V͙],f5A!8mj5izvv, Mmwi\f1BnUsq?*_7*26A 01.kfo 0塥>jPuz׍I[ۮ sVcj2Lmj)næL7uhKfe=esgu nZN&X0{IȌ$wXg4#^oSY&"6 :`ډh6`Yk]^<1jX0{cVa#$oLtc0&.$a&3M MAT=<>ӓ[O^pb;wLNN5jԴiWl>|k͛ǭV}wy'??2?`0 YIbl#imf.Gh ڲ;Zjihi'E|IHHͥ(/aÆ:TTTT~SNq!㧧?%K :tȑiii+W䪧̙3ǎo߾G Dٶ5(?Ito&#bLWKel*o^=!44400# ʹj 5deeEEEA\3gf̘QU1 W_}2!`(Ds΍}oٳgg͚%|bb"yO밵w<) HXD$ afl1=2ӈ[wz7zINN^n/0Ԇ\.@UEa}ȑ;BIJ}p۷߿۶m뗝]UGή=@XS̜8qbU@xm={6:1n8e bH\vfkQQQHH`%fn9A Bv -ИYg)jt2Ⱥ!C}X=sjqM]зo>Z.))XlW2e 6m wZZh Hxd28۽{w'jT< \Hٳg̙0w׬YSU1,0*..ľqN']D"huƍu{ƒ[<\LE @hH$ ֍I"oasjs5mb]rM=HB!7^/(Ha׮] c{=a„<@tС1c{GχF%[ '|>0422zB\1LR*o/BPa s쓌o ғR$8m$ 0}m;n~ҥ+BÚ:?So].wSNǏSz a"$) Pr`#Jg|[<$<`0 He$ ]ĘL&n$AB(}iޢ=Fvvay`0n]W|";Gg]6p]cy`074, ݹ~ cNW=BcԵQ#/|;yXYښ-P%BB$Ftc?>>uQ*%~yJ*9x˗/ײiӆa_e֦@qS"6axj9߿](|ڒ׋"$ŞcT!)kUlޜ8kVFQ9g|owm`J|e&#$V5wu"Si2f뺠 _ZZ5^wݘ>/ܱ ؊`0`A<&Z/#͔цƜ6ltSGʍdaV_>7x!}Z9/km.HyGuF3;e"⺑1isɠ3ozx nϝm#|>;o6BTI1#mIh24ǰi*nLsO<==|DAAAll*=Nܹ399yԨQӦ^)!;;{׮] 7oZuNNNJJŋ#""/_R;`ܝ c, F60+3 ]$ьew}ddd3[l@bt$cf1&%]26D7kqbko>s9jj8>,ʊDaa!3g̘1bү*dBPΝcijgΚ5K,CD._?Ɲ`0O /Ľ?.%1V/`" B[L4"AƝ^c{׭[a \ ,=rHǎJؾ}{@@sڷom/;;]{8$N N<33sĉUUa`JŐv& ֭`%fn9A Bv -ИYg)jt2Ⱥ!C}X=sjqM]зo>Z.))XlW2e 6m wZZh Hxd28۽{w'jT< \Hٳg̙0w׬YSU1,0*..ľqN']D"痕j v{U`1-N?a.D&H" 4$Ll hv t$7095 sZ9yWÚ6.9$BCаq_|Q"Xî]@{„ y0"))СCcƌ{;""ϟ ,K@I1O>B}`hdd$7b;c2`keeTzoqBW_AҧOl`0ĞOed }"\$iC%Q背7mq;.^i@֯_駟l}6r+؝:u?~sK`}]RTNhZP0mРA^ױ95jMn4lЦz||믻 6'ʄ SF-WN26 D`Ch֗;uwsqtŜ ʍJF0p Z l2LZUV-[\`ADD%z߿?ի8z.\Ov}k40pDEE襤vAle>vnBUa0MfQ~>J@dz)@bDpMf"Q^HDWr,Mo͸ؘ/^w񹇤z |u.aÆuqwΝ;wҤIPK.iii&Lp8fΜɥSSS!?ɓYdɸqFqMzz=z9s+VZW\Xr1L=f+: )^IAߐ[n?/^7Ayf. 1DUCkYp蔀T===ʹXiSrGo4J(KNX?N 1fDI/hL'P͞:} dI cBl>Сph42Xnظe>>׮] :t߶afHL:\sffĉ;Yw0{lЉqq PҥK 6mwZcF]"-vL L;KVdݐ!5[F0&Źs2WDZElwܟ:\0k)mܿ8Z`2y}ްNS9 j>VKJJ@-[>LM_Z2 {v݉9sI lHd4L6 Cnn.3sL¿k֬ eѠBS@'ZBdL7TACĎ"?@`Ȓ@ZjE~0M0g_%MCgxonqs~(%UJmU[S3}Q0/w5iso~Tm{F@Cаq_|Q"Xî]@{„ yvRRnjkDQK}TVVJ|?>,,sܾN|': <z]̢"H( HT*?`k.Zq{>}12Mpd47C%J ^xf_Or!$ES@Cg@mu&HB@m0\Sn~Υ+BS4՛@֯_駟l}6+؝:u?~<Yfvsҋ3yhԨ{pYÆ *f}]zUTPI1V F4 d /--w~顬Ÿ?cAaѢ)h;$Du4u R~Ƕ_;"Y3fk$s;00E!4c]:vFэ:sÂfgT_CQW_}c` Pyyyd0z_jUV`ݲe DDD}WTTHSJJ ( 7wHVVVt^C@pB'xڵkChxw߭[.!!v{6VUebZ5: U2 MwJX܄" )JCèk6:͉ZސJWȎ- (7^_O2`Xbj.vl/ۻj9MT従z-t\\\NNNXX؆ ֭[w^Ȍ;wIL.]&LYBmʍRu"§< zرp\& a,޵kWڹsӧ@Uy 8\M6ܭDXOX?q͛4օao_m[e3㢵'lZ7f'tCE6 R(!dF!o$5BT|$B6jYq{Ğw MF}6IHJHIdRYHIfO&/VsM14QelS\\%Zml.\}|d8rkRʂ Ft,*(B$2DTc^߭sg[AS&HR*UxX3VTzP5ٔuW ;*:M!/A^Z ZF@ ѢX,Q2L*z5wh6K$C1^lSM!6e0 DP`_&j<5QMoߚٺM뇷F1e.v`Mct@pd˟=Sz//hCD"(=wpQY TJߥ-/`p#DBP j)nIp+.ݚS1 W}T )e$ {1L&HnĐsաzR=&kd_Q MuGyTH-צ߷vvay<=n mjl_Y^ &Mj?;Gg]6p]cy`074,' 2>}t/t?v[5U~*ו7z }S:#/|;agikB 8 cЍpE:)DV[<O bX$yѓ'}4Q&=ze{q+^yT Æ^M_, [ٷBg-yxX/(RM1_왘:vZ]5*6 QO %waY#a?3uF5ʤ#Uysfb@ Y:# ȧ~NEM怞}ݵƭ@ɑ4Ӹ̤cQݪTnUd*m0<`b\P͂C')aDc_?D0Īkz7([T+ 7~6ٍq5/--uFӻnLBvb/s7b0A<&Z/#͔цƜ6ltSGʍdaV_>7x!}f)U{zzixȮVVQVYi2Wbɓ?{_Dg,m B^)b ߇b).|l!Ry,.@|" TT*RPd2 i"Iɹgm;7\JEZ'*G-Yy2 `Ʋ)E^(2MmYDY.< Z8l ߜHrԖh7u~T;ያ5,"ډ!T0=DZ@ꌰ ֠-.)S8ϫ{*`فc܃=vNp!&ySZU }gu&]شm{𛪠ڿ>D]mBCޖeee>}Z$$%%mܸh/J=K˗;*,,\rD@cƌxG=*;Oȇbk׮6lX j ^[`}oN0aϞ=MoQw1 Q!F9*<+xV,;W+Lj׬_!DHbY':o D:E2F%"(@Tu-F:uСPR'|bZSSSjo'͛VlIo߾ǏwTiii=p~:gWĤ&@'TBpK/\0==]R2~x{f͚pWuԩ۶m;|W^(ygᪿzMA@q/ 2(0H GBA#C^fQ{ԗHg8gpmD~AR%p:N `ڿ~POnذAv%%%CA׃@⩢+8p ##$M&SJJΝ;۷owޞ={VTTr0{10ȸ0 BE  E"NW/!k: sKo?휘t @/l%-vc@fsm)Q[屧TE7zOe[SbIbJ }>xyG0<$8ᘩQ _鳉ekBCbpoիݮ2=JO{C< {bb"GY~V|֭[Ccэ>VM&|Ї ^裏BzDއT(FIOsMpʕ+.\NH#dZ #Nu !$Bq$toWd?@pZ }Y՘^=tҥK׭[V DG>lBL%b/ BbjI0 MDD2#˫/̊0*pjR.` c [(e$AJ"p="u&ȃ1l@j.nߞ' StHc /Ӻ HA%$$lܸqÆ wʁBqM̚5 gdd@fUcfxJ9pK8-Vxڝuy>_&F a#&P:6cm­[-v_7<ڢg|Ӓم?&,80-zP >,>>PPb~>}̞=:HݻKK<ʳ|g֭RrWaW1{-22r׮]nUQWk~ ,߆]/a:lGUs \ :,ܠox@İA75Zwmy+1i9!!q"4:1̘cҹKNLs)Bz0_):+Hܿk͵kפj}wccce4쫉ء@A#Eywy˨Q)5u '-Ș*Byceb2Xnj]@Qo~'/-!9%StZmHZa1D-pg.ola 9)X5,oX3sA oBT_ ݅zP'&TUWfV -L9ԏO%5TX J|2 ӻ-s,n_U˷?L!!{P;~¥sk˄<˫ԔԤ.]Z=ERT[ lnO~hרݺ%s:=Ep"hO?a Q܃1fi]̞};wpTjW;&#",FCͬ1wڹ T92f))!1iaD Uyi7;=(R`QŊaXlLbxi$!ZT5Ai5Z96ZyTuA HJ uZm%*..nwwOoz0VyJd dk"aׄK9mh/p1(C݃! 2!¿Ή_p0F Vt$J{7Ún PI9L!{P DN:BE.A )݈o婃ʪ z!dQU=F3q a Ieڷ 4R܃?nL/*oQ|6 7 U~O^H$fn|Դ(P H4-19pʒk}sV&HPp:[]LC5Ϋ h믚Q%{Pۊ! .cf.- H࿏j5;vѲ+׭jN}ؑGMyu*A\Ϝ9V ^M"'=[=(jHj ld=TYW'}o;GrHϾ!f)q:.>6l2^dwدW_Jn0'y1lݺ9;{TdCa |5HӼ`Ȱ}5=j9 hSx ;h+JVy"UlB#m>SEͯ'6-[D1 XVW_6]Sn*RqM U@ԕfo1Y<޻< S(uUw`@avk9ǏtY5+\?沍chGZtx-T NbK;*;-V[_t2V5G}Y.OHU[س)d:Dq 4eS4PdFYgV]yq9a-ov?&WkYZE0Ca4]]Sz8ca6A[\R5pWU7+xҟ):N{i:W[U wZ#}/8ZAsTc4 ?,GE-oΘ7ynw;Q#Dmf0z@F5k©̞j TL4L!!A=@V+ӻwo鈞SN7 -O{xʁ#+ {wOϚ'Ueeeyyy`jJJoAT8;Ӏx;FײsBO .1E&G>=QcGy7bBOw:zС zQgN xVguM6 C߆)T:-pZVVӧO@RRƍb/CyyTX|رcz•+WJ ?f̘/~ѣ|,xԩrwsA -Z8$駟FEE⋮ 3gj޼yɓ=\0|KE1AyŊDGGnʽZ+.-x+"R]q#&L .:[-ͤ#Y !]"n1vZBsWĠ7uoڷhbWA {裧4]*@E;)8)) a }qT kA !8S@ ;PZ :ߝ>ة\a)d:+Ɖo^꯿*ӣw?<'&&Bqȑhŗ{hݺ5==4ݘsHhd2}ɰZh>(H}Hkjj<k  {1 }E bqN!13&{;x"vp$zxV`- eJn׾,3#3PimηeI vɍ6L!^=G!J߸8YF*f!ɐ+!zNJJ***֭]tyRRRfo-{o<ѣGpMyyya+JKKG) D %K|ɸ{&MPxxL fUcfxk׮}`CG>lBL%b/ BbjI0 MDD2#˫/̊0*pjR.` c [(e$AJ"p="u&ȃ1l@j.nߞ' StHc /Ӻ HA%$$lܸqÆ Ҋ́.\pʔ) YXX;k@urrKgyf111k׮mLsΕ,^xԩ>d,_|ĉǏ5k(XrUڷz ={JAcŌzIYsa/`6b %Cj3&:Ղaܟ՜jVٳukLKf8NxRުhꛞl?PUA4r+xJkBC BT?x CBmo3{lěT޽;|g֭RrWaW1ڞ?vܵk[lۜ 'ܲdv鐯9WY΁p5"(Dp2*I2stYԜj!ߵiC*$^cXH 0cb|aKS/_8U|0ͥ un"P~P IR^/ڵkRj;n򱱱@ZZ\DSPբUɼMOM⻼eԨЅdL J!͈12d1?,fi5.V[7?ߗt퐜p)jt:ED$IRo-}Qk|xPz8U3`W60FHq ,˚M7f| ن7d!*?Bl=QGRzFs3UKk̜Rq'Β*QUWU_|UUu*Ă=(PNf?}9seFjmjJjR|rz")o-jqx67 ?} kxkTn]Rع[nzT8XUA4 0F(Awf 3ѴVm{fϾ;uq8 CS*`b! ljfVdvtۻ}uJEfɔnZ0"B@F?ѧw/$u3 AjZq (P@q KeɎ5Ǿ9VokvpG|^XYTRTei.uۡQUnϋv/*i믚Q%{Pۊ! .cf.- H࿏j5?vѲ+׭vjN}ؑGMyu*A6UU=x3gJPifӇr򈲛Nw䋓xǩwӨ~0:D Ok׭} 5RG$W62N笫~ړ׾#p??gА nIm\Nm7/=})R![09Uᛕ0'7Xߺusv& ȫH?̷fi848f{Nz3/m Ǹ}04:D pC M!F{P$,ҢM-c)젭(Ygɋ/WVs qLO76Q-:N)mZb㱢ё^Zo;mtTyT~llMMSWvd={ntXuدi3Q[A߮ B_֢:^˞{B=7/eφR( [(p@jg9sHU¥c.8v5KJ7~ݒ1Z tč-XIWUWiZaZ9rZTu9}2Ъnfp4žoª>KAdX1 $ *ŭ>yJV)u>mN쩯N_n6de;1}~#uvXYR14^NblHai[\b㌉6T:$(Hvz-sԩqƝ?>!!aѢEIчz饗***rժU o\U ,{>ӳf5lUcj-{]#R8MpvveY砅z.o"΁quHߣmn; Ǯ gv)K-ыj,s:slڶɍo7TW{;ZهS#iQ[_I} =Xf19'#z\Ct۲ӧO?7\ ^r|c>S+W7//owߛo9a„={ P=!&]vذaM7T1xҘ1c.^qxbT³BHoŲqB aA˾ԮYCPN5"|E"# pu|p~s <_=]8S'뼳) [ %p4^uILz>}:;v^N.,,_.v߾}:ݻw07rf Rhvi&8ӧOwG}4w\_~bWyW1hi {*hEWdeel|ܠDR\#'W 3 >Bj 2P?dM _j;'&:9C3 ?He6ZK[~UqQnV/ e?&tl*5O51GN&U<~a8GJI6q,-L. ,p_a*gD!-q#А4?C=xbpm@s+t t$0Іt;oh'OLHH]rE"-[isj*HF -"1/ `aF6~{Z.d}G"Nb) a c@555MzBkm?H#dZ #Nu 15B$toWdI G8 ?2CLSk|8U~`Z{[mYERB£ܘqн]I1t8[ a"t'uHٜaҵodei]ސ}%o߾b踸8YF*rH2Juw.]^{[FDD\S^^x)G֥K[NViiȑ#СC!!XdZW1sϤI  |&p p;j?)%8aSb*{Y;ĘS#LahldlGW_aR.` c #ic$AJAp="u&H^1lr/j/7\ ݘ=YIO;~uyuT?8Fr8H'=N\ƳZѵģG[NpS} RyРAeee 7nܰaݻrO2d233 }g-^NNNt43,X &&fڵUHg*++8҂sJo YxԩSԺX|ĉǏ/71k,PDiU݉WkIb[Ǥ C90(!8g(qR6ɭ /̬-Z{f׭1-i]xx@8 c#xSFozy>xxUfh.V|s{yx~j_8#u“j\B` )ovhjdžw !}bq`Zxt@@}Y||"tXAZg$a9:n,Zwmy+1i9!ǿ~ljw!^xZ#)= UUfj-L9ԏO%5TX J|2 ӻ-s#6o6Ăe5'Lujzilt$M8]U]xltY\t('rp}9w2a'j65%5)>KrWVO7&'gs~G>.8}휰ЎGF%/u)J7QGUyA4 8_>u.j9VGvKv:"=(PLa&vժaٷs.ahJ6LpSlB9"a48MfMnߧ_]lɨTh6LI ᖈHh #WGU+ E*MpSw;=vTms,B zb6Z-&x{;=(R`@*2f^}M8^¿@0DMtAH­LFp/0La7QOUw@+M(z$*.n3*27W_p<~CTxKRp(A/U4p{gFa#sbj z!dQ=FSB  A\^̛~N9o@$wn[ChvNh)A7fCUc yqqؤO>{!] Rӊ{P@ дw{P_*Kv9ͱz[]{?r#Aʢ/Klu1E\Zz֫U:cG94թINpU UA~8oa=(P3MA,Bij"ngUZvY :achENFο{I _\IgiN zqtuM 8Rk ب9N [1Ɠ3L!!w z@m.3Wxw5BtȰ74 ?,GE-oΘ7ynw;Q#Dmf0z@F5k©̞j TL4L!!A=@VcsN:5nܸ'$$,ZH>A>~SYY9p@,{>ӳf5Ic޽=c*T8Ӏx;FײsBO .1E&G>=QcGy08bB$Qw:zС zQ3jN xVguM6 C߆)T:mYYYVVӧ_b@RRƍb?=,_|رO=Taaʕ+%3fŋ]%=*ӱ'do$]vذaM7_*xbT³)4Xv"V!,yԮYCPŲNu@*u %d0KDP8[8ٍ5L!!no;uԡC={@H-|'V555οF6h-=r:ԫW5kքC'͛Vl}?~=zHz9ɓI BtB%  !… ӽ#}DSNݶm j 'RA0.s# p+1;b9EJhO}=xcxgIw .U$@ moa Dnn dPRR ^BL| 4L)));wl߾W_}wޞ={VTT<@5=}9s&PSPP0bĈ͛7CP^bCoh HΟ?/}>/* L<ILxao?>!'JH{@tt즼*R]q#&L .:[-ͤ#Y !]"n16mBsWĠ7uoڷhb}?裹s_~11` AA_0YYY?*hAR\#'W )TQ$(pMgΉI~ DV1p7fd6iN[~U{zMխL_|ãLUj~5jHO~PO8eH6mCi4WK>|x~~ŋ=@Ts= 2$"Mu-[D"իW `0,U) @N'OLHH]rE"ndZ RѣGC+p шĹ&tMVA {裧4]*@E;)8)) a }qT kA !8S@ ;PZ :ߝ>ة\a)d:+Ɖo^꯿*Ӡw?<'&&Bqȑh{8qw *HZUkjjZn tDFDGG7tdd$Xc2>d>( WMVA`@ $1Aŀ1=T7Z)8Bb*$gMBvpEFO_QI T Z8s@7</"0Nݮ}YfFfTBBo*b3mBCzC4}vd`6!ɐ+!JNJJ***֭]tyRRRN=@{{>ʂH=zG뽢tȑRyС@,Yć{gҤItDk%8aSb*{Y;S#Lp`ih%""Y^}dVQSpk`B!Or# R 3@akJTs)wcg'=eBC^xU@*4,!!aƍ6lؽ{7T8p…SL|YKm۶k׮jf͚) pkFFʕ+ey Ȓ`ܹRYxԩS}X|ĉǏK.5fFUTX1ckwօ!b~AD %8ڌ Nn`}9gf5ڢg|Ӓم!#xSFozy>xx@U\ʭ)a is«{J!ׯӧٳ!n{t kˑvrLݥDpqA[nʐC n^VAP -KvаM7&끇{w{a Q*P (As|-.&~K\qLSkn޽%cۜj 74[,ci']U]esjkNujȑ/R8kQ | {V0L(Al bLShQv;r֪41C7',eu2ZpM݃NdjM:Kvb3kj@q,:#¦5hK#cJ8&XvoO0P)Mû{wPb\-9F1y҄xP7gL˛ III7nBH|c>S+W7//owߛo9a„={ 9=!{#Y x|ڵIMAyyҘ1c.^4ֿSaB 1QYӈgbىZ fRfZ !BEB:Yy!\)20,Aong70LԩS`!j>՚ZWWT{@hE\rek͚5Pyĉy<;;[W_Ƴ> Wriii=$=@Ǐ35yr [(N4V!_pazzWcHzuԩ۶m;|W^۷o~~>ǮT/KipĻ P)Y?%}E.oPT r8*Fq߆)T:6lCII 6z=x$* 1222@d2ܹ}@{ٳgEEŃ>XC CQQѧ~z3gB 5#Fؼy3+V 1n^/!-\(j='O4B(^rϟw~bĉaўƸ~)j-fTTԋ/{R]q#&L .:[-ͤ#Y !]"n1vZBsWĠ7uoڷhbÇ/^D999?s+-C"TвeK$ҨC*eLav:n 4 'O&$$Hˊ\"Ԅ+\dZ RѣGC+p шĹ&t>U2#ZiN8qw o`՚֭[у/\rʅ Jo]KGFF5& >f`x|㣏> EcxmUc*Z HD$F0#G_+0BHL IN;k?0I*X 1yF!Eҩ۵o> `Z{[mYERB,]rcF StWѾ}{or\\,#fsyy9$r%DIIIEEEݺu K.ZJJ iSho޽ڡ @=z#H\غtu֩jtȑRyС@,YW1sϤI 3 ޫ1#""C*rtKqæ,T"w!$F4 dKDD c;"Ȭ(p6- 0 R1 B/\F/*Rg_|,*>R8|zOz0L4F999/0T4hPYYYBBƍ7lذ{n8p SL|YKm۶k׮jf͚) pkFFdY<̂ bbbdIHs*++8҂sJoŋO:W1˗/8q}|ҥЫ +f{LzκːmݺU*Cڢ(@c7ƀ{tlSwAnY ^t,@"tXAZg$a9:n,jNڴ!UWb ms,CDCEhtZc11>ǰs/ *>RPÅ:7`( S(uW$~ךk׮I;iiirWMCGTV%6=5jcQR2jBNX[11T*4#ːdSݦ|FGRg,kdNQVi-""IzkZ{|Ãғ c_)4:@{P`Yl1co6! QQ|1vbyB=PU]e6Y- X__3e攊S??qPa-*u0O竪Z̍}U!,0L(A p"7 ~wxϙs-6,VkSSR⓻$wkI8~SmPijy?]}WvNX#^vݺv‰ v?H6)4:Dq ǰޕ@GQ3K2 dㅰ DYEFP %}\ .ܫ@j63=L`f&Ü5USkaF?ЦnHnv)R2p5>6!a0p0-c&NQhg ؽk7+P9h4L&1)!1i a?Wַ m@5dn iAFo<" bc,f ˱E) U*^jl E1#Kl$x*;)HZ!j4p #U\\={Jy VWh'<wlf7Rȣ2\GQQ0[,64fKCZ D6QQFDYa nQq\0ROxݺ}e@ Omf7RA 4Siq{iZ$t#:>dP*#Th6m\;|{h$L /JgV:  UhOп:o݃ 2d)@EnATpzk]?:fSAEʂүJu1m?6l1-OS?9v\/Pg'*.Ns]W2 6>>SN~)bg}fXRSS|;h mժh497nܘ4iұcaÆp<}… U*ճ>%+kZ<{l1]ZZڻwoԩS&O=f 0{/Y$--ce[Dx1cƮ]o>#SN)e gJA0qNs"k'x3bXI_!a8fiƙ߷]鸂@vijԌ |M ٲe "݆NSEA9F1%%e޽;vA?<طoߊd?xΜ9tCN^^ѣoe@zHq!X[QQQ_-F0a + v>i`0Tǭh!{Eh!byAE[~U('~ p=Ughx׶ uq)x7jn q 3g3L~mL|5k]t_.tСCZ}9pF Ô)S + $IBZ R(JGPinpx-H ,7xйPg3 P0 mDe %cm74"2ZIq]O9@4t&OCPG N5i&&+hHj.Ȝ-7/`1hսL_\ãHr~5j(O>Piw5e4l۶'Pa@F9ue˖{:;;"W^y^|MexZn7oABCZ̄4 e;|0D5jԙ3geE7n[,fy:7JXea00$?Ec> 78++ƒ:8ĕj.l|[gz%X ?4$ :0ᘱ^oU/¥RBAݳgO< Aj!Uk۶-==T"::څqĈ/tdd$h4._C+@M7>0h2pYtme! % j1PGLX坿VP VˇiC{H>6h*U 1iN EԪ:tſfg*p/HJWK.n 9:v0+I6bd2A )䤤=z@ݭ[z+%%C^^wAiРA>L|D1cƈW{1z,_ܥfaʔ)02 ce7GDD4 =VFGbo3])& aOC+Z#":(ʫ<0}R{/Bo 4 [e B!ƋR5nx6Ts)|s{lĄH\T&]eZ#~4#3[}%5eWpR2*u`|$-c¿6үTA4r/qU7F4v#ܠ@*A<=ڹsg=1Bjo 0o<ubb|922r߾}.K\J䌾}<g0ڹs1sf@|F~/O|K+Qu|tϟT8=FC+=M! ]mڸv.BHv2 ܙj^!t6 v- Ѐz?1?$u -2dRLJ"݃W,ڳ乓ֺvQt̐竕E_Ybڶl؈cZ*4~>r7_Py !鋓#D?K4jm.]lݦSNԪ~>yıA(ŋ^ThZh7-ó^Rq=Aw9hs^~n]}:T/byG%JavNu1ܹ=+kƅx1!p7Fg<`޿Wv2RZ[ UrJri3{5iC_pӂҮu(1+Y:ܮ{JmE;*.}DR8 55ޮ7lVrwPjya AžB,ղjWu+KQ0zy9q_4~Ԅ@҂ d6TUuqu8hAT'J{3ٔ*Gk=2 "2`A~(J1GV]8[i 9a;YeK=vO/ƨ5)P=M)xXe@i~6^SXT5?G*`فʸ˟o)p߻ᡇ!"]?D;ZNcq q? KFy=3wN`hwT+u"{D]3a|uv HV%:yfT!,#uS4HP`T8gϞ8q+W.]|Rtqqȑ#%!C;wv )!}999/ܹ>i߿A~衇#$8y?;S8F2S|N.1Ac됺G}v} Cڒ%1!'9|(P @T}ۮm.gTA0u~n qy[VVy`uVzTW=Zj„ /B~~uâE-KJJ@"ƍAyy-8_zd +0DD!Ίhp ([!@l-Czh7lވ!D(2yހy)8G4?KD8?Qqu="ꦐi:uO!s>3ŒZWWۡF6hV@<ȹqƤI;֯_ 6Cӧ.\R}٬,v:[?uɓF4pB& #>*K,IKKX^g̘k׮l}屶<ԩS>jG>ęowP`k0 G!( ̆:AB{WHYqm}#b&h: /`ڿ5xuS4;rrrl""mHt:H8Ub#GhLIIٻwoǎkσ۷o?3gݐ7z۷C^z5Bo(H\"Cܑ#?$ ͐Bf6m{%D3QE kxrY ]:8@F g* .ߢB m۶=j=߿\/[ D+o,@[кuk$Ȩ߼y3,, zb&Ti(pH硋Cg3g$$$ˊnܸ! XDcfy:7JXea00$?fd WrGquScIQBJ56 QM>x-3O=s^ \߁Zupd*|{Rb|G)DU}M! 1Qw}w.WWI' =11'Nؼys4pOٳ'P }Hm*-f=zTV'|KGFFBmF#R&~i^4VwX[iCI#hZ !Vy!$Dpq$P|'+6i  ?cxqL;q8);| ::*b咋2BArGW Kʸ[BAbnPTxuw Gܹ3 !5 7o޺1Hvo>{z%.%)wv)a ll& !s-1aX{=XɠO>R" GT6E 0oskcWcSkzBNXZ)bbTG玷!QVUFGQٗ,{dFFj4"" r5Z[tbəg.2' ҂c =R0 c20gլXюg"2?CL=wRZsVUW U\sWK 5ʠ(ꪯ߆iZUMͧ `2 "2<ӡ^|J~m#p*&5%5sr:Tߕ8A?~| .k8ĩR#k=tZI*q¿TA4 7BAd C+p 3)@v6-#]6Hʨ7؄pSD9 q"&;Ef4``ݬ@堕Jh0ƤpsDb0r_Y߂ؓe)E A 0[0 -,RP( ZTz^j)p"#x.qO j^`_ф1̏Tqqq{l++6[]8%J "dpEEFŒo񛗲ڐVk_CAT/݃i  DE f/_aFyp K%nfufS)t?IJ "2<@D~NY!T!i|Ѝ8^:V?C p~{P Vz4BAv۴q\d3.(ICZl$Z$T?~c@~H A,Zv2dȐE RYgs'u!OW+ J*ŴmذcǴjSӆncE᢭A <:]VQ4McV0:7u6=:]ۊvT\~[ p3jj]Yoج6+9M V2\=:X"(e?PeįpVa*s}h A'l63,C9*şV[_pЌR'Nfܥ)?Uִ{f)dDv2d4Pdbi1*GJq hm|s"cwLC˖,{!_\QknAS zSTuM ,ˀ.l026j~B7T7w/q?tS5HK.dY2CE~vbi10(DB;1{f~7V" ,Dmf 0z3 /@#ʑխJt?B&XF>ꦐi=H:3j gϞ8q+W.]*P E?C ɸq\)vq6e-k|Qx']DcX;!uh{%'K87bBOs8|QСz3 <5j:]\܃ϨjjOG+7ag* 򶬬,33… ' ))i֭ >DII$d:qFjo VZ5a„^x!??ݺubAƏU ^!!" qVD+?GcG! ibkŒDaF !B(q0|K)(?Y"$ ogU7Lԩӧ~ gY,Ժ:5A|[j62(--ݻ7qHS}u4z}YȄaC!_dIZZH2iҤcǎoÆ e3vuxMN>pBJYYYb#<2uTEF̷_;(5#iƑWAx`ofC p =u+$,8? Zݑt14WU0_qϺ)T999[lCQQ6$t:x$* #Gh4ݻcǎ_5[QQ㏃7VPPPPϙ3BuQ3A!@o>m4w:F -p Ƈj0ӧρ܄7jL98\|~?,XfoFaaacf ^kСL $ӈ^ ]2VBWXTR%fohɸOę DßOCPG N5i&&+hHj.Ȝ-7/`1hսL_\ãHr~5j(O>Piwk4l۶'Pa@-G9ue˖{X<;;W^y^|MsxZnuyF}̙qYэ7D3;aܸqPWtjj*d޼y3,, z2 Hkߊ&ixGcGd WrGquScIQBJ56 QM>x-3O=s^ \߁Zupd*|{Rb|G)DU}M! 1Qw}w.WWI<' >11'Nؼys4pOٳ'PX,|ґk4Opy|| TO? $> @kjj/նm[(|&>ӆ FHq#C_+(CHLx 4I=OVmj4LAZ4w~'q"SjU:v_G33EL u8O uΗU$%«%eY7Jx;vzaI6bd2 Cʄ:))GwJIIv~v_a-c2EzBu7`aV se9=]|M! wvv믿:l ZVVu-[8p2 dɒӧMFFF~~ԩS4ppAڷoqF1INNe_`.5˖-1c $3 Vp@x;`yA{V(9_rhv)a |Ӥ?vܷoKTDK\nq ;yO#nѝjv{M#\Z,\k5x@Ĉl^迖}>5FLrGl56ap8AjfH윀c؊ju p]l'J  9ns #*›zȐxDjSp 66v%96%'ᄥ"&L%ztx[2M}nY5/X!mtT۟}JbwJNIm$IjZF*"R ׮XcEMG>**xRX*Q }M -8݃ 0&y sV߯8}&"X>sz'>jUu` 0-Pͅoo>gzPa Jm`8+OUU4]| M! {!3zk?:n6r RiRSR:'wKHI]A9?LJ>)p2CZ-?CՑ'KDS>p3)4Dv2d0cig2>5niTz#\M7ED# 0'LhSTYmAv TZ$hLJH 7GDZ,CO*-qo=Y6BAZ{ϡðؘ8r,EQ EJF11qh`iq .2 ND RVzM9HwҼo^nz{8/C]2M A W@,|QTd!xy)A j 1Du= ѠMTmVij0̿T +^a6y_BDM {!MuZBEh/A ݈婃oi%*38Ԁ U{hG3)$kM1:{^(A};S‹ّ>fA®eABS?pĢe C A iQ[{q/E{62 8Gk*i vFGyffG'}[юKo+_?Q{fBM+ }e2G=Cs)D^*C+xuУPKr.}u=L^^yxܻ5! 76fe(UU]esjkqP*ĉ7̟6e~ њ6vl~7LAr:b죲R "m6QUbW)VoNXbqihْEwu>1jm"hʁ!TOveu߅MFF_=?&Xv2n i)=Pׁ,KF{ȶHS,-rEhÒQzu?f̝&J]ѿmLa_oeh]C9RUɟ>s~޼UG2 պӿ0!C;wt>_|q\oJe5gN8ʕ+ K.ϵ>v_׊ |wd-N+#ΆQ e/ hck:Qߡ]mo=d ǟCLq/ :B/P}fygF-Ug߶k{UP_h&LBA\ޖeff^pA$$%%mݺIuEeP^^.&JJJD9ɯHf7nάRYaժU&Lx׭['x~ǫ駟z_ 1 Q"Z9*'8 qVH;[f 7bJDq7#|^NA$OT\p~s<ȟ)dm|||N@ s>3ŒZWWۡF9oV@١<F{7n?uFx> 0{4K,IKKI&M~6l\Θ1c׮]Ǐ7 .TT%f~ߌpՇM#pۯ 4+ F0|7!ENО:hh}A-H +dw*F8g* ⎜-[Ht:<NHȑ#`i4SRR۱cGLP݃۷o?/..3gRKgP @o>m4w:F -$I4CL.VU+T*)rm6K}'gn p~ ,$h>D,? CVwB-}H51X4ECo%-vg@RsAmy+AS嶧Ϩe\VCBQCyY7J˷^àt'Pa@-G9ue˖{X<;; 0=n ̙3 Ⲣ7n-7f&wށøq㠮PT$Daaav`@\V4Mp8\a?}gϞ@aXKGFFh?5PWNrO?4 /0>;\T۶mPpKᣣyݺuK,isʸ08m(P`W:b:*RZ>Ĕ0NdEzߦ!A$Pp Z8Is w/"0Vաc/u4#=_TPP|YERB,\rQFuS4GѱcGw v\\d#&L&Syy9 2L zynz뭔aoGyyyPGy@KKKnj#vo]x..#D񺀑|؈ LXp˴6G66V2ӧno!CFժMm/zؕؔІV2Dѹmel4}Tfը5jp/=]iYLN)v$IZhZED*k쵶G6Q\ Ce;RЇ,Hص,HB~ǀ .|XdȐ!#H2-*u@v2\hφN[E1C *ڟV~UZgia#ƎiyЀz?qȱs|Bу+6*@HCdv/N"P,Ѩ-Ktu֋NU:RǦmP:Vw/zYJPi BADė\M"a"Aщ /Pg'*.Ns]W2 6>>SN~)bg}fXRSS|;h <mժ(;cȠwƍ N?uA4o|g!`ɒ%iii"ɤI;֯_ 6;3fصk 6:}… U*0geeqz9fϞæR8W l sqA^#>"\'HB@hO {q4Ks4폠pw$]M;ELWfon qGNNΖ-[$16$t:x$* zxȑt4))){ر_ {}VTT< =|śP]Tj jfH%۷O6͝N4s|âE' =z4@!zj[џ| yee%|NHr%RA tʸ/tV#L0~rq6 U0j d-#DB,/(Bx*<eį:ABl~ ڶp.q16/f@ }M! s̙&o-f͂K.K%:tH€O>3ǿ,Zx@() QYg njmLz|η.%wMTW2 {xwׯ_r_S|ݿ^{ "xPiaqĉ͛77QJp={bqw~. F @^8=0@P$FpRm۶B-v11b/oe4ӆ FHq#C_+(CHLx 4I=OVmj4LAZ4w~'q"SjU:v_G33EL u8O uΗU$%«%eY7Jx;vbb$1a2 bA uRRRAAA= 4֭[o"!//;x<(rii1cĜ{ ˗/wr6N284?̄\VDDDcuݻ7\x(н{wW;|0ؽ2/H]qc&+s;ńS!Lp`ihEkDD CEyUYFOj_-ab| _8LA(xP*F %c؆Uj.\o_tw'tS4Hc򝝝믃;C%$$lݺu˖-z!C,Yd`?uԦG- coܸQ́bA,X AͲef̘LªU&OR" GT6E 0oskcWcSkzBNXZ)bbTG玷!QVU6:͎Ͼwe1;%$6$5jViPkW"̦#GhAFaѼf9fŊv>Q\Ivb9Dr{d0·7L3WN_RɰVFY_UW}60OתnMh>U戀i=ȐNd Vk9S4)I%wit$pl CW\u_!N]{tHR vH "2\c1HQڴm}n4E*UF&""}pd4)6۠wf*TFd4&%$#"-g]ࢪ=+ ,2?"]^~!Z Me'OԲE 4 M*-r=6 3#B30ÜԸfg?aYkYK-z?B\ƞ, k@   51 1,R% [T(ZVR*1m]8sʻޕHRj!WT! kAW111_RӛEaZkk9/ !~J/)D=H H=  UՕ,6+*8DӋDy[ Dp2*VXJ0e]O4u[&$e7SH A)k8=4-DO7箃o:\i5|vp~yVp5X@3Z!e7A{[Ʊ)Z<Fn6A @"S̛T ׷7L&e(;UQ]a-jjvS Ƕ!7Gkؽn Ax} 6@aDZ^#ǮQZK,4]lhwr%^*JSv :QT[˲ /Ҫrrâ×d/sak@YkN0n $ydh;[(q c94?apT?e.l}^b߇H\ga?V~0 `^! "aRT)*-Yx'A,#uS4H=;wnW\]jɓ'A PY^^>jԨ;fqGaGedd<3N}K3bT èY׋$? 0)ph'x ŧ9~38K~'QzQ ` !*g,ڠjmrZyZS>`i.\p| w XWWpE4C֯_?uԧ~:;;{ӦM"5gffXwO? [9f999 ̔)S]EB cpY-GcG! e;bk„Klݞ!De3vy , '? '$@KpM3yv?_uS4=ztrk?7͉j@+W&%B?wܽ{~˖-S(OϜ9dIxуho >c ðaò*>l ~WP`oa8exFH/fVİnęs_!a99fiƙhb%.#Q _g, ⎌;v8!//2f(h4P$* i !!!]t4hg}6pzܹswP<//_GϜ9ӱsdd#GeЮ]+W8yfn2 DXp!x~~ٳݯ-*8N181/"<<_nM%0b]!\AUx95PcLinE=K0BR % 5@ȔE[[ `M: [0k9Z(w.a܀ }MA j1a„ygj~[4_ϟy݁HAK@`=Va1`Ç958epyG}jj*,Lr\ڵKv+(:thҥ+fw16ϓӫl!sih*AP,:PKz[/+.d)a@J-lw{"! c +|*V*eyL_4[+^9{gg5jHO>`iw&IRLa+Jgy8x HP㳲V^ ÈtH{9x5k3 D$.'O=11Qb"ivmп;=@ٳJ7n}.v6k$q qǢ$ N.>WQ{&s<#b.)](@^t"nwZȭx ,y_@I6Y ":P ?(7)h# yx6orw0x{Ȑ!/$@h\^f302rcAjbڡC{ zvddի6mZrtXXa0Doo_ฏx  #F2FHq5#AU)$&G[,ak]֬Y Aغ1O)#d2ٱcǜk*++łl\죣 pDS ."oٮ?}fM:rR[lPv(2D Sd0~jQ)B sxJJtf$R*U0ܸvj2b?8s),׌` "Ƀ 1̠3P히V5y^=zlVH 5ѱ!PS^qncFFQhZG ާWo DerҠ7 ظSh٬ܟ#e@jn  $yϡPðr,EQ2 EBUk*J2C0!P8sG=: |T6IF*JV Jb 0רbbbK?5Z[NYTzM AW@,|QxX^g/e9H^T!z^d&x A׊7aP kh?0R yJxhBm LF]Ӄ*tIn A8S֨qH{iZ<$t#or%Qi5@ށC 6`pKn ٫cS<>ע4ABvEN7[/ KO1A`vS+`AH V.hxiI$H !@4-2_ Ƀkz:KmNc<0qԣK\V%oKW%ڨƍI4QMcOV4zfv{v-Ȏ1LB>']@ȈUJu֭޴mxVQՊ Nyc.!9Z9K.r>[n aHH !8! Ĩ{{vu>pSoj- `R|˃7L "=*A+xv"ݣ9b3UZMnaZʦS(ה>'aޔ˭m dd21,C٩ +o WSWcӌR(EEů,hU?4g9ZwS4$$4 ) je9v Zf)dvO6FW.+[/PԦPcѴo݂Xe@h~A7V${<[+ t\sq?tS5 Ƀ@ć'; DFXcq q? K>/sa>G*P= D3a0  rJQY~[`7N&YF>ꦠi1z8wӯ\j*睢 Əؐ|ԨQ.;Y4pf}QFF3Ƀ8 u8O|WZ .\g, Q9t}ZmLLF,Ƌ/ Q u||-[zo&$$@ݤýkׇReff8K'N+ǍD5kָxs62 q-4"1)&aOC#";.V_QK HWXrJk6 #=dLL=A6Lmܸym] *.RX|%zwzI7M܉_z%Vg+<aҥK `zs6b$u!SjԆd"2CFLHa:gGH?T[/y`*sT{bC8.1aenkH0,)yݲ3Oͥ4'wK_uSp4ȝN^aѢE'N֭X9rHHox#F4U 1/**r9Q"wKߦgϞ=bΖfs=Fb8ڐFAk?ה[,ak]֬Y Aغ1O)#d2ٱcǜk*++łl\죣 pDS ."oٮ?}fM:rR[lPv(2D Sd0~jQ)B sxJJtf$R*U0ܸvj2b?8s),׌` "Ƀ 1̠3P히V5y^=zlVH 5ѱ!PS^qncFFQhZG ާWo DerҠ7 ظSh٬ܟ#e@jn  $yϡPðr,EQ2 EBUk*J2C0!P8sG=: |T6IF*JV Jb 0רbbbK?5Z[NYTzM AW@,|QxX^g/e9H^T!z^d&x A׊7aP kh?0R yJ\hBm LF]Ӄ*tIn A8S֨qH{iZ<$t#or%Qi5@ށC 6`pKn ٫cS<>ע4ABvEN7[/ KO1A`vS+`AH V.hxiI$H !@4-2_ Ƀkz:KmNc<0qԣK\V%oKW%ڨƍI4QMcOV4zfv{v-Ȏ1LB>']@ȈUJu֭޴mxVQՊ Nyc.!9Z9K.r>[n aHH !8! Ĩ{{vu>pSoj- `R|˃7L "=*A+xv"ݣ9b3UZMnaZʦS(ה>'aޔ˭m dd21,C٩ +o WSWcӌR(EEů,hU?4g9ZwS4$$4 ) je9v Zf)dvO6FW.+[/PԦPcѴo݂Xe@h~A7V${<[+ t\sq?tS5 Ƀ@ć'; DFXcq q? K>/sa>G*P= D3a0  rJQY~[`7N&YF>ꦠi1z8wӯ\j*q .̘1 7n )//5jT:mQp}G<̢Ew1$t}9o1$~L-U0jF";ٛ6m93374hǟ{C!aPqñ ?'''%%23eʔk׮5oA.!"qDQQŷBَ0!u?[`r$Čq * d&h~‰ g?\`~ӌ}]W4 G]vO!k>sٜX[[ۡF<@ 4 !1_reR!dsݻwoaa_l2BOg}` :7QRRҿ(ܸq|9sfɒG B|B1aÆeeeU|.%0qN(  _ͬa(z3Brr3+ R! w[J\F @ZyϺ)X;vpC^^dPh4HUhH !!!]tl>8p`YYC=tܹ;]^/_NgΜ922ȑ#HH2Ph׮ݕ+Wģ;u\o߾b% ġpB ٳg_[4UpƝbpc _|Exx/xJh+` c&C?8jsj" L5݊z`K:!j) X>r5 -Uku#`ps1Q6/]øAb„ 4 oh&Ο?2ݻ ggg$=zTVÀc9rd#jT/3p>ѣT%(X,EG-Z4n8xKjl6ۅ @|СKB+:_181І;y"cz-dn >w8? SE  4E"[]jtr%zş,>ES4 UmnOD8A`Lao^EJWU4ޜ鋖pkҋ?vl5F g, N@b ]v=JY<T9~իW<0"=={^g͚ &û iɓ)xOLLzXhvݱ o߾{رcsϞ=+4y QZڷoragFbw,< !Ȑ6vr"@7SsIBJ%{QwCBn>^e1½BOM_Zpa\:_)GGP}MA 1]{キyf9;C y )L=..EEE۷oo*`6|{ R{:õ###'%%8?:jx_:,, 0 p7cpn$ AII #h  V~ L#8u*#z#e6 cFctv F&W+:w|_''7pHp,>6^]0Ϻ)XģrtwH͵ZmLLF,Ƌ/ Q u||-[zo&$$@ݤ^{5Reff8}ꫯ-=\ 7'N(7n= ֬Y$/Аr\?Bb  ? -kP,X} lZF[/1 _a)YGhV /4?@21 2AsM8u}Ka=w'4 r'NOO饗Z ѣKKKcccwܹcǎÇCQV\9gINNj|R/ׯ9sSO=<+Vr@p@~m^y$ .]*]`V^=w\of^ !LI9Pˈ :0O1aJW#b"SKlyks׫Q)A DŽMV!zðu>~xw?4Ҝ`-}M w:oVxuE8q[nbȑ#!>|8:tŋGTyļs ߯_?G@=\4ٳG,٧*cpCAk?ה[,ak]֬Y Aغ1O)#d2ٱcǜk*++łl\죣 pDS ."oٮ?}fM:rR[lPv(2D Sd0~jQ)B sxJJtf$R*U0ܸvj2b?8s),׌` "Ƀ 1̠3P히V5y^=zlVH 5ѱ!PS^qncFFQhZG ާWo DerҠ7 ظSh٬ܟ#e@jn  $yϡPðr,EQ2 EBUk*J2C0!P8sG=: |T6IF*JV Jb 0רbbbK?5Z[NY( /)D=H H=  UՕ,6+*8DӋDo!^ Z= Xa rR*q0QOBMɨkz0@;zM ؖ I$4'5ܳuoWy4KUϨV2cR_EKЩOn݌ߞ|qUV 9Z0(K,q9Q;aϞIM4ʓG "j9Dےyؔ < ɃAvkh Gb-=Fv{>٣,wN 8G&tl.iöɍ YuRk"{vgW~ܕN~|[M}aXLꃏ|^wy𦛂A[%HpZ{u6R,W~J-,]Kt 嚒u>̛T ׷7L&e(;UQ]a-jjvS Ƕ!7Gkؽn Ax} 6@aDZ^#ǮQZK,4]lhwr%^*JSv :QT[˲ /Ҫrrâ×d/sak@YkN0n $ydh;[(q c94?apT?e.l}^b߇H\ga?V~0 `^! "aRT)*oyK,I$G4 fFwN>'OVVV+T5¨YܱQp}G<̢Ewxܹӧ_r.j*nIh8};S8+F0Q|>~Νuuu> WD3|ʔ)׮]s\b;<~)6 u;ۺ9̀srrRRRNOgggoڴIsٜX[[ۡF<@ 4 !1_reR!dsݻwoaaaòΜ9|7ƌ3-[&KJJ7nO8eɒG B'J18믿( OKK+=&_+(0 G2 <#sx3+bXkJhu^̹G4GL BTVfo(֯F^lon qGFFƎ;򐗗34 (v4Kp.]c4>8p`YYC=tܹ;]^/_NgΜ922ȑ#P/_~en޼٭[7 Q*.\$?{lSD3P`)`*ڵkw$90b]!\AUx95PcLinE=K0BR % 5@ȔE[[ `M: [0k9Z(w.a܀ }MA j1a„ygj~[4_ϟy݁HAK@`=Va1`Ç958epyG}jj*w%jfp:tRH_y\g{gbr9EQbeIhsUth44@L X(|X~ lAVvEѵ[ȭM0 W=1y+^Uxs/Z\íK/۽5'uS4;}$)0h}ᇕJ<WQ{&s<#b.)](@^t"nwZȭx ,y_@I6Y ":P ?(7)h# yx6orw0x{Ȑ!/$@h\^f302rcAj@^iӦ+WoKAt,cpѡCpbddd#ж02i4)aW;boZ)X5BbrSţzDlo!^b̈127qsLCN.sd҈jE.ODAӃ:ߕFë!fY7KxT.]@o>V Fŋ0pTBbe˖}t޽{ d7ipk0 q!Fpɵkn۶MP5%%%'Nƍ5k\Nt6kz so$/Аr\?Bb  ? -kP,X} lZF[/1 _a)YGhV /4?@21 2AsM8u}Ka=w'4 r'NOO饗Z ѣKKKcccwܹcǎÇCQ 3g$''ggggee5>jϜ9󩧞HNN]?rG"ÂKo,X#իWϝ;Dg-ϮX"**AJhsxC$ DeD ɧ0%ˆu 1ώXrɩr%_U߇ p\c¦x+אzaXRe?fKiN0h;7P+âEEO8ѭ[7Irȑ|>:t#Fh<@b^TTr=wqC80ٳgX1g3O18_~3)T m!۽f#Mʣf-6[M!\j,D6M F "%9]U/uz sׁV߈م)-+08dI2 Zvj͚.N@KA ԹCA>::a0`GK4% Z"zzgD#'% Vi uan'"I9ZL'y_XO+[/;7g4Oמ =m6+I*ZR ȍk7j&O ,3r#A̢$1L^ߺp_q^ iS՝j:#Q'0~t% )s);)I];\%^ Ǔ%5󅊊&C%wS4$$xi\G ?tB:F UbBb|{Ѩ4$pZڭ bFF/W9tŲ 8)媾+W>}5j IqCT4 {M ֭>YҰZM&G>p ;wI"!SLvseNN`tѣG_|Eq+bqñ 5O:駟޴ix$]l 8 p _([lGl _Czs0 b8OA^4?Dh.vi>.n qyۣG]~駐[5lNLLP^ \2)_2sݻpذaYYYgΜq>J'@,))߿?nܸ>%KsD3x 'x*=zٲe JIh8W - 紌)̊Zݭ8s+$,',8S pAye8 Aܑc~2to4hg}6pzܹswP<//_GϜ9ӱsdd#G_4~:@HCa…@gvh; OBv\"Vz LB#fе[0YWS50Tv`V#n#$Ő^°@ QL_U𑋬fPЄhZѰmurx W4 &L7ophxE3uwH8;;ѣj 8|ȑ#QzyA^F wԧ(A(|ŋpW_}6 4 :thҥ+':5,L,)+=&">WBs1U`@Y$b(uYFn!^W\S4EÀ_ZDCVUTzUJ͙hip V.slPS?kԐ|M Mvàa׮]?Rt$UB➕zjH!~u֬Y0i<O<D^7gC/PsXq7nҾ}{AzBܱViv%N.>WQ{&s<#b.)](@^t"nwZȭx ,y_@I6Y ":P ?(7)h# yx6orw0x{Ȑ!/$@Af_TT}FR/f9z oJ:uSH :r18cС?22)Jhs40FZ1 b?O!19Sǩ}=?R6x`c[/1f Qp O89!@'n92iD`rsΧu"yprGAJc 3A<*G.] q߷oVq؈xEXoٲo߾:wofBB$M={ッ FBBB\H]:rȈ#pyĉqÀ`͚5.':5=Zfff97}[hHEt9bSLH!1 GD(w]6o-pMZǭد֬m4l+F{zlrڠq&ںAT\@ͥKn }K@byѥ;wܱcÇrԨQ+W3g$''ggggee5>jϜ9󩧞HNN]?0k, kHꁬmۆaҥKţ ,իΝrYcygWX %9!SjԆd"2CFLHa:gGH?T[/y`*sT{bC8.1aenkH0,)yݲ3Oͥ4'wK_uSp4ȝN^aѢE'N֭X9rHHoxbH*vO]jju^^so`g cgfcpF~gS.B{GRGwR[l kC$"XVAm:@DJrZ^*0>(ճ ES[VapȒd8AJJu1lҿ՚5˳]p4>s[7I7SxL&;vsMeeX0|}tt`rchJ$>E-'Ϭ^GNJ|NE&H9!s OX-*ݟVh!^"2CIiT=zlV$UJZj&nXCMX,G3g.G6I7GE5$Hh50 c46u?@֑Ӧ"2;1uFIO>_Q]aK@T!&S[,Sv+_$SvzJ^WQ[} 'Kk 7MF K裂iI$H '2Ҟ_~zu)Ąn={QiHI][/Č_r葋e*/qSU}{'W\}jㄇhG?A$y 8tj&֫GoJ)W8#:6j ku8Nѭph0(=-V눡m\NFb 3z~ HS=YzMA ~$|9j2cc6Y(J&AP(jZV)U&c&>?^pBG@F1HRjaܠVBL!ULĹF`Zkk9/ !~J/)D=H H=  UՕ,6+*8DӋDo!^ Z= Xa rR*q0Q BMɨkz0@;zM {#AłDŨ`,&QEŮbIAP1FMcJ(FEW[vq|2v읂&dx vƴS}BY$KޗJ#/wG;# E³EB6x{ظCBp86* %%% E)CF8@ׇm) BgT? פPYgK$,3ˆL1 sҭK:LlcUX0x[GV2[6폼zj_SUR\ܻB)T9`cH!w8_s~w[*JLg?ݶ<( V=Tw(T  ~>MV!W7\m=,_cT7XRP!L*}^Z@ *RK ZW4 Ql=y@ 󛰱>3K<==?޽{gffθS~QQ֭ǍqF [g gMs<{]v&{VʣV4DΝՠ8Bd-]tRD"<$tɒRgg15)KՅBhJ_jJ-n 'j;MEEz䄅ݾ}Y(k׮={[ܹ÷ 2eJRRRhh) f3g\jՆ VvPvUv*9C3fa݇K>z[A-n%uk۰͙=34쭯6'd/7_골lq [42BQRIrOiZ?A:5*"QEѕK:܋߲e'NP9򋷷w,zX>} իt&Kyj&LF@]8򀀀ݻSe7/_B@QM>K믿[!Cp=#`7}We||T*'kDF pA7x7.^~ СC}|}_*OLOݷipLΝ###h[-na3}t譺ss /~۪)< MFzh=i NFN(c{nYϭ[7wNe~Ģn?ZRi )e-jTdB@%6]ԅd>7]!sgxhSRRhyؾ};bH8;;B@"??ҤIgΜիtww:==E ~]1vY:ftRtV9zۙV ܹwUa#=bPT+I+|ذa ,y0q0s޼y!<ԯ_i.0tSQyeƏ G>ʧ@ԔJ%t\-H43 0/ pu7%$$P ù ƙ}5,tD#G h]IAkXPڋN S(ލmԔ@*6:31 iw3b޿fRqom2]P=EJr,AB]L1ǖ{Kpɹ$)\NsoFo?CFjwHڵk0:oݺ5;vb~q\rA4ZR`Am"VeJ_p}́[pgG d3+4͕Vc\]t8y<ȭ6&裇ϺQhԏ@Rd`FԌ~6jU8j\BGKn :UM-Zpssۿ? |}}2TΝ;X 2! LLLر#ڵqUe˖A~gze:u0:t(8wyLn""" PŬ@?̙V5HNcǍzLߚZ%[kE W:[ 4x𐤭[gg䤭]te/xBv$h4'ڡWNdA8 r׮@۹߻<\bZt3'70>ٯ.ɓ''N W 4(''' `׮])))ǎ̐EA}-X2]`4mn3*< DC/ֆ f͚{Yb3McM6a„Hv²&:[g0L*omiF*Ƿ̋Xvʰon{\|e[;u{RTH/EhBqG:ȭNPfovnG̝qa>Gy7S4(ΝIe8?rXE!cz~"z 뉚5w#3ޕ OwOJvb?Zã35YXZ=TH^n ?7+c*D|u\KYQK7_& !U.gL็v|j<`å~\X3DtL pʌP :_OHH$Nu jX$j_1*0+|}})Kg`_ĴqB!oܰL.6rR;H]aOG:u\\j,.C TJJ nv-w/+Z`KFpkis.Y[:\&§ZV("bE"u:9:yzx2 ˮtt65\&+*kq{cy |ߎD&E:)ʫ;&?\ =_a܃P :}Ԡn7Wj a"࿠ nn6uy`oÕ{gŒ6¶$B`y`A[!XXpU\`e!Zaoqp{-~0DÑ,Q+Լ~dx vƴS}BY$KޗJ#/wG;# E³EB6x{ظCBp8C倣?_`TFVVhUic܅OƱͯmxK tfZ:pV0=?.Q*̖_#^Z.T!z`:5Pk XYׯO29J͛;dgg7.///((hƍUNBBٳuc#Ϟ=k׮ݟi̫!Us: :s'SǡtO5(0ceK])H ]dٙ}> ~ 9@RuFP+|A5RZ!Rɭ+ZdFdFSyуޟ999aaao t]v+..H)>z`}RRRhh(nذaҤI~\\͛)y믿}ݿGll,H̙3WZL\m({ *@F {3å7sr钺mLmp̞We2ٗ֯ZYJuK-pA(Tj̧Ah R ur (}Gʃ%K@vEYoٲ'BBB_~ۻCEEEUDม+0B޽;Ҏ/^o߾ .0z)Ժzjtt4=&0a`lϟKPU^/PqT7xcдik)~u9::BH4d\ @:>>^*5mFm/^~ СC}|}_*OLOݷipLΝ###b[-k^}t譺ss /~۪)< MFzh=i NFN(c{nYϭ[7wNe~Ģn?ZRi )e-jTdB@%6]ԅd>7]!sgxhSRRhyؾ};! |"9sW^Pb-Zo0矻v횛;bĈׯW֐z͚5ڳfͺ|2ߨQǏWV a{Yp!V@hZ@KǏ6Ps@^z<:uAM;^K#\L^^Lܺu 4l5jɓ}ɓ 0 9r䣏>bx޸q=uϝ?``6W\ otU7=\b܃ N_VP?£uPbKMr5vN* 5Aa(ށn>֬n۶wjy)< v >5Q$$ "d1=8Ȯ>hxFdpp  lڴ*F}.]Zo ^7..$qaDGppc1D -4h·sOa\ <,Νl?c'''hl`IIHDB2 jJ}|39 ѣpFtå/`A RiqLwF9t'8hK;7QRJǮz Щ!$/TB$RDа՞ⲭj*$˜Í^6>;/YѴi/m b)ϸ7uDURL)GRhjonU\I ynŝzi='ḭ̝{_6r-F!hHMM\*pa‡ `X#`?>͛Ö-[` ?~xtR xԯ_R-RtK)J(2h8Lx{{'@L( {i/\M TpqpCw QcZWb`5&2NX^{  6bWڞ&MBc+\i5VյK΃ܺN ic >zF poK.3fa ;"))iΜ9p:u7FQiOiw[_?d+J'cku윜KO"!T"3R;* DUzx;W^{KL+n'u^e?yO>| Aڵ+%%رch"(ӷo߸ S&Æ f͚{AZ˖-(66vk6mڴk6k֌{߸@}bLp:6a„HPJ5 wCD7jޚfkq|Y.OEkW \.ֽUkWc.Y7.!_HR6 $7IQ}$ܚ e6.FovpIܙ7sm/OCyWy9???TaݿO>+W0`UF虙zFK!RjE:ݹsgz]C+a#0h{W-#L.0D7m "KgӲ5݅zNWx-$t``I3b999,~k1{۽0kRG'HJ!&B;/"{aõ&˰&ێ. ǒ"Ӻ9T;--M] 88N5|1.FƼ U0kGvV)Jz+Vc͘C]ZT7P}?}]rD./~Rˑ@b$^.ίI= "ahR~.+_a[% >lCbO-{D=ӺkqU OYz N}[3 }֋ǶRE(z5k& Fg+AG*89/S Lљ.5G6>J>6"_Wy{~|k䆥yRpVD 4ŗCHU!ĨK`g>/xK\8z0,p*V-a|k:ZaY_gL8eFw^@(Ny‰{o'MQi$:zY, ݿИtSe|YYY̳p/bM`8A ]7nD&FrLT$.'ˣN:n.pg5|vaY;Ȯ^W4[,\ t{ MO3_oOoFP(D" E$urt"e]ԹmzkLVT.zA`Y~;*h/WwL~Kzd%dù@uAn/  D8::AA\(mГ?kޚ+7xPے:hthay`rGTWz4L鍪j p}1\ ZuI[qݰx @Y*@ERIm0B@ G4jק73$m.h4;,.pL՘!#~CSf+Ƀ5OW~8پrnULPw6Nle' , a``0<`0 , a``0w۶mU cIϨyjՂ2yvT}`02|~%`04pY1 fn)J13mvH<`m`j[=-+r` a``0<`0 , a``0<`үډ, rƍiߧwH$0퉗\**)jZӡo9Ƃ=O(mbIsa[y^@!<0 U,8c.0 W8|?uHj^u?V~^;c)c>,e>_y7gTr>[,U$eX}/:X*e/ ^֫'/ˆUˢ*Z#1{=caʲ6[@=zXdo)))]*oYcKa#dU!*bKym5_R$4DFu>{񬸤H&7 jzS?RӭK:LlcUX0E pjJ/e{V5UuXmn=<==UjTL!MŅJUB"q̚l^\nz[U^ncyTE8 DOU/9vD+6'wg:JE)PR)W( ^@q\'iZO)&lOgR<\7HFFԩS?(r)Sz[A-n%uk۰͙=34쭯6'd/7_골lq*r D0R2ڙJhj'EMjJ.USʃ%K@vEYoٲ%x*_~СCQQeDyA=8n cbbwcŋ۷… >} ^]Ҁ%zM9a("͟?˗" H;0\z5_ѣbVjaiGm>u!$2dL.Q/J \ #x㍋/Bb~0tP}WSEvm#\:ӹsHV˚|t.]az܃\ ߶nF 9OC'fd4TZ'#'o1=P^֭;v~'2?bQEb)IЪA_ R4&$8 B= ;59&\))) Ϝ9ӫW/(uzzz-`ڵknn#_^YC&x5k@kϚ5T~F?^Y-_ٳg…\ZUţoh-? z=x@oenD fr֭[`بQV'Oå/@'O Mxx8ȑ#}K-ƻƍ멻=lW춹r \x [-n^3{Bh¶$UyA'ԏD 5\BCPX*w`1ۻO5۶mZd^f/xB^UVjޤ5jԁyH^q=]}= >|ɒ%.((شiU\t) [jn\\h HpÈcǎ 8c&4Z4h +Oʟ6¸byY̝;799"-~NNNniiQRR"P(QAqq17\7#...੏= gD>\ !4@.6>t:jԘCs8с6cq EaK.%!ѩGZA2BqLE.D"Kt/ ]J ɸA .B!9Uk>߹sM6b {Sj2,Zpi,:Hgy t;ʷa;*l䲇[gC FxpÇA 6l؂ bccA aܩS>C7o8dD,/[lp TK-fRQ~}KH=,T*;ܼyP,h8Lx{{'@L( {9ʃ WwSBB0`9ܷP]BA0rԘ4y$m ]PD0Uމ٦ >QhU%SF'{=V|F>7!vFY3MY %ȃʢZR,*ܜ9eә;yK|;w~7z[1R3ؽ{hFB׮]y֭effر hh kܸqoRnݺ'www kAFʇn޼9&&oI&OmxZUTTq(}y5oMqp6t[JϬw |6WZsu §nژ`3 f~_; M O(m cO C^ʥ[ڿf*-ZX|0P ;wc5ȄAs```bbbǎo/h׮,=t-"""///G :; {]tE1c#d?F۶mH$| pIIIśԩS'5HNcǍzLͼߚZ%[kE W:[ 4x𐤭[gg䤭]te/xBH," rK 轀N_U RI/9׷W_^%K7sr|:첟{Ri!ԢmNwܙ^D￳ &8ֻw2rMtF @?,2L῰yGwa+^39 &XҌ;eNNN+>cOM] nV_Q"#!=$Y.YFW0=CKDӧOS ooﴴ4>>>t`:~p>&TTk=- [( [5czYviSP >8>x=mBT^*@(BQ/@@ Ik wn?PŕKF/0ۿsUo !ߖ=\@iM~鵸*Q'0mK9^o.H.b'Gɩ^"/兲:g-))[8P#`qjqPa ymS/߬䳎l= g򦭋"^{صCG/ <ϟyz?~у`yT KTRglk9f}%0!{P8}>O'ɽ\SڶnRgA V Fc[ULaWfee[SVGKg`_Ĵq"\hڸIL6O۴/˔J{`@k/:u\j,.C²-%%vh]U!&߽ԯh,#iYdAlp@#ԭMD+_H5j\!stttqqAEhѭK?SQ2YQ!_˃!gJH<X֣ѿT^1R/-Vb+ B!6h ;4ȗQ@"M+tSY <=\wڴߖFXC3;z6ҥĵУ`NoTUKC^wOxJOڊӗp'T+䌂3(?AJ$*cH &m@~U݅i6:t{hle9yx  iaׂMSJjf؉`0 `y`0 X0  0`0 `y`0 X0 @{ ǩp<#g+ab sX0u76;~~~EB0..XKIILJR a0Ս"e AXw8($44D"r< p v<|鋿Btǐ6[i딕|#"eN[A:Mڦ@NX*Mr+\Dz_aH. y> "H ""B $I~޺IENDB`sardana-1.2.0/doc/source/_static/gui_snapshot07.png0000644000234100017500000037561412174204305023621 0ustar cpascualcpascual00000000000000PNG  IHDRM  pHYs!!3>IDATx`TEgKv7lz ޫ X@O,׳y*zvѳ t@@z{$&/ c\޾7o޼{eF)BVc`! y<P( ehhYYYRlmmzH/u6@BP(h TVVveaL"i5z6E^^޾{**ff>~~,v̢ /Ȟ=U|o ;%߳gT(-\92jUUUV L.4 EP(7}}jₐN* m:?‚`Rb=fUC|jD"a_ƌI kF>{wo+077g~ɇ#{lJ׽oy㕗_1%PF.۠󄄄`QTYYY!~ݺu+,,,w 3fWiiirr2r1bΜ9cgg|>rʔ)O8~;=w!fffXmj(A gjPbfFOTZ*>^~kˋKSSF`7p`o$H6/M1N jҢ&ؗkKqT]1蕾5yyii#FcPz^Ϭ['psskmm'$P(O~gAyyyss3diƍ?Ν O?%%%A|͋/=zԨQwUcs#eP8n8;=|?Olbiiyر @P?s.,,l@Y:=!Gct ߓB 9SZ7Z ^GT-Pu!]&VG4K"3!Z]e|0)A^EfZ'Q zs 8Yt!>>a@B="gϞ ?پpX!A -l E R ZX@̇Lb5dRTT9rHWWWJg=:,C8'La2ABV9ZJ^RG'\u.XLi<mx9^(_K*vuZ^dbq/MKKKOO1bVB؆O-J\B0L_b%,\pժU6k&pRa=G8oE":HQD H{@[UncǨR,\͜C|kx)ڸ98!N@Z%Smpqpw1rc%Pl^\\tɓaaa:$'d,<<0O33Ǭ ("?{ؐҰd2HqѢE0 ܃>H{bӵY8F3~F65ohp76-\dhKncsxvp)rU N3K2}:}Yapio ] * HghIia%:rHHݴiӰRt񊊊ŋCfΜzj$:Q`=B𠋧N ;v,_|nƌ~aڳ(@\̝\[{/Z/jiHP]M5H`:Q*`| ͵H7Kn9 eh_ X>}:ښmH5###ͧN.@ W238٩@g͚q gtt4a$ў O~N)doWL& eo-7;'XI-#ԘEԍP(CDiݮ}(ʠB ] BPGRbaDD@BP(@BP(10+**$ BpOkk9q/ BPn3,--- B] BP s BmaNC^ycy]BP("13wuZU7ɏ S$S( eѤP7L踲uKV3&Ňo( B-eumY%Vs B͡:GP(s B0tܳJ=lgd\I  >x  ߸%;>˛lc 畯WtXy&̫{jV" P֠7𯔳CI_K]ab?_ӾLtwa o@:߫+*t*.'7R*:fuRwMslo+< Bp-X"B]Tie{{;BL~Efmm1 V6448::vͳQ*/ƮweUjm_gEi1Ggpvɢ:GP8:g`㚌R9sss)؟Jx0(h'k` ~G-#""M9 _ P(pnᲡfӶk׎%Ksr7~-nQNhnn ;vѣI#G&ngH4o0Kߝ\jժN6-//﫯˖-{뭷f͚diiiOuuuPǃb%.==ʷrNsYR2';[a9,,,$$lve%n&2AYYjǥT*C3_ z]}{|gO..sokmMN>0|;pzN[Q1cGnjҒMYYÂC.CPS Kq&K;Uo"UUU=s4lXYYW_Վ1sv'UsV11q>vɹy9 Gxxxyo>}rĈQSR,Bpŭ>i0\e;wށƎ(XR8TOO|;BaXu͝;w͚5^^^AAAO4iLe۸qÊa8ƍ ˗ /3=bFEH$u:.>a׮ ím &NȚ9/?F⇅~+y|+y}ԨQHJ EFLtڅk1 DWeQ1q1sv}]m~~nhHmmm#|^dTޠCO덚;3 P 2X͛YY׈(H YdTǦ7ٽkǘ}ڼ rBZ!yG&@"""kpAtmHH@G(4ǀ (44͵"V2O{x"''cG:ybq^ZMc}]\=< {214 B[{uKy>:?C~]xǝBgg'x 2[ؕIðI:]B4Cu'6}iW̝gZh삻;sÑĮ/1|tDD777+b&|޽d)5&&F=#$Y^ ..Xpqq68b쯈||mlt{"Ǝ?+d]8i>!Χ"'i3I&c!*:M2bH,t^P(rϡp~5 Mؽ-D3/Ÿ엫"%o^P(\qϡ ՜gtTǙ D9>^奝#TJe]mwڢTun2γP(<^"4MtpTk8::ZXXpo#⫍kp\wECt]l'Btf<--m$s7y/( BgQ(vԮEP {7e'O6iߓ'OFFFJnjj*,,}1?fݺu iΜ9999cƌҥK"Hjjjrraƍw9\|ֶYB<]pA.t}kkke2Y]]Ǎ2Wը||qR`V8NCXZ,//wtt\xqcA=tz> EapBףS'$z-[ 3憇а9,_KT>;"~h]ieioo A6Ξ=ǂمUB́J@AA-z =ָ555a6Ddun\.T 1-Ʃ=4xN8Q60 h*ggg裏pthH84xQ<:' .egϞ{&&1]_~A4Jp+:; ${l"Q]pshH C6d`g}d6%=P*0bpz?!Dݢ: H(wl:axD_"oMuѸѲac%,8|dvple#O)S `S"ڗ \bv\Y[[&&Lb,bt-rXUT u(Ol!DGQ@̇BbÍ@>01V:BE:q!`6qТpt:|;7G ㈚CzF[‚q6ƉOFFcC4E3Y-R` c '' Ź%D@N1 cpA#Eb~E>}: jMR:6m,*NА ׁ'uW4qII kѢEZx lbwuhaa^ MЌ{VW WD% 3ޅ$&Tw|U{VNJA㉈E߽4  ; :\!6+䅄pXz MF`)OXvC pؔ!{K|PRZZ1ЮyW֧ g`@sܹ45S{ꩧVXnnnʙe3- ġɱ>s,$7tk:nTBD0 t)(߂BPngQ( vBPngQ( vBPngQ( v;.AJK-ƍ 2%d,^wTSy[zs@.gee655DDD|EҒ{w= QQSsOBgZm{{;չ? YYfgk;{mmmǎmݚ7sӲ )V6vv߯N+Z:WWWa `@PRR3m4N5MzzZy`0XFN4o[$:,ܶmo8wJƐP9ٵTvSX3PW`13\]] pww C5"#~4DVh*-4ufK''CFO"mownn.NZju >OW㚜o/owf[56ZAonn,q8#LwyvJ4V)z!+9EcKD=tdP^uu}Ν;:qCa` og(F-Af UKK33;3޽{xzz~fB0aO?4֬YСC@H4uԓ'Od^N|j 33^N%9JALJ*pdr.`^ӛr8x`_cScPట4y4P  0IDN3{ԩ^{'jŋ?mC63ԕJ\^^l X.oiumZ %m=,TQJJJBB»ᄏzu=#鹹X@̙~W_}@߽w2~Amp` *4oN:g<@r]]ed:y<44<5|`0:V*wPnn*绺wf u]AظCΟ6wdBuVwq0AJX]v|Ĉ/ 9ssYt''^Q4&D-(c`lT8-y6K͡jjk`nBÓ r>>R wDDdvVZmT"9I"N"uD?P=IN#G.++3ft\m隷,S)BW7˅MMm.8fbIzXlFUYYq/_A6ضmz ˃J]u9lvIG 8~lʔi^>^}Ձf9s^@dfi 1+nrv^sWއh33uuVD?~ărDoC0F_|_nnVVsgh4ZțcmMMIIsP6wpp`,|~{F;}z }'vu믍2-ʌ3'N"ɲ05&O)GtÔ7|w}ş9s*//700 zɜp]:G}rꫯ󫯾#CCGx 6D#@=4j(|,\|OM~ر?Vu-Y;vU6>׳>iNj0Jό\pN-q<,H&yR1jgM.gٍ~JQ`htݕbbbrss[A섋,W?n}Df~~d2T3iljEGEԚֶajV,jz77P(:Ճ2a0}ETGY؉b0߈i '{ 5ł"33fTW66>'vYR;::sϕ'Zz^縉J)1<["2"##SRRؕ٫pVXG:ujHHHDDDAA׆ \Ǐcǎ?ĉBPD^*=ofO>蚖lnaz9?tƩ-,zk5{޼y۷ob'.g?qrrb*Jg+ WolF;Dz-Mb׳wʊCxqWk6nt/::>_7VN7ᕏnRUE@9?,`L:3>=\[_l׮]> v͚5SNM2Et}HP]] [3T as&?L\g.7lmS26 H$)B&嗇'& 3F8kkz_3!ӟN2BEEE 6ۛs< q7 M1^+ion0(vxUSm&t;:*Pn|DmVZEG6}rxȑ >o`C=rJjX^p!{c̙~- c!PKKKCVQQ@34O?ȐX:;ϙc| v0iVVMaO>;g`}Ds熎K'bPާaR8!`hhx쓟@YUU%$ 1u%4/* ;* m277 ,--dױ;'YQnWjrs99ț@hҥKM?!D 8 g]tω'_{oGMMpr T&k49ý<Чpj`Q0F1Jx YLHo61/՘QM&8;;j=Rk9e*7 !mzoO,kM6uUVUP"3z;pHBu6%*b EOh8()r4Fg}.&b|c\g86J8p@SS@Aۻ;Vǎ r͛#E+r!DY'aVF3uD!vfP?TiX3ǶUw۷-yhݑ}effΙ3'++ O>yG;l0oooX:H2~xLVQQa8g>Lm"A5|gFr.e t7nĹGT`hfvnNeMo?V4.&<"BctzW?ޒYp0oTGxćbPXD'L1Hu ?kvZQHG,ʱf|=" c{쁶) tYZZt:dfgiNUIy*9l-10OceD4LzPeMMMl0NM֖:rȁ. _k_.*Th)tzukʻ_pX/\ 'cW~/$vrbc3 ݈T666?fb̳ L&Cvuy666}t@|[JxejVQf˪~׿dGvvvR0 zVWW䄪@`=;' >3hl-<}~$3/ԗD3JR0XK{TVVfddH$  i2+CII S_6v,5ph1((ݑq7 }$r&xG83g΄B @z(j ʬYC@/-c+ n|w[LG2:Ү] ?>v%{piX'NCBAee%~4ikԦNyf6__ߙ3gBM8Ncz_HL]E_BW[Еst#_jy]E1rזyJ ;`#bC4 5555UUUYzHf R˄Ag'!,,co>rG@ !)S F`/tCDrIII)ye˖z%{9}P1.a֊LJ75j6BSFܡ"''˗^믿Cf臰D/km6$C.Fܩ)FGGoܸNLlh̥ѢT[[ABn=2@?^Lhs{vU]T x1!qLvsvz%bdAۅ )--'{! xIpyzzb=&8[!G䁁 1ph('DZP5g"e3F[dIVVٳP-жiӦyxxǭ\r6lȡG]]]2 9#'&<xʩsAP'7t7x]FL?A:%JNNX,YSv"'|^xM_y*V~e&9[[ǝ'P7!."SՈ2EnJ!okO,2]@CdJO3 88 ECO(t8ߋ3HvܹsUcޯ=gp[ Odi{@usht!PuWsQ\X+׼g{KlsMW7 MNvz@ ˌ]A|3fKOOGe_*y]A,/{`G%OS#+JÏ{)[al(GĆ$>qg{{;{}+ˑ m(3/taNr UtgG=Q7EլlwL³-\~{?/K|lb"F:؋nnn7Nޥ T:?l8^4:k]57NnAtz{ p9KnnDhEE,$a}}=BռŚ]"873A\u'^>^];J0]|VFX v0}dҺ^]B}:N// 6DFFJրիW/X`ڴi}>jo7*[՗2xEjFըUM¯^2RɾE}BE+'O>~RtttliiquuݼysppԩS#'rm;o?=3VNfl. eȣT)k;;D]\uСÇC xr!}r%fFG0[d;ڪ._,(+:ùe*}m9SŒ.e@u_A ɾw=m!s~.$Wж+8ā|3Ð R'Nqvv߿D"7nńJ|ݧ|ͼ?nչ =yxU G%73 /`Z?f̘+Thgq"&Ēv2 ];wFGGClll؁^Z-ٳg~Pۉ{h_pRMr8;/GU)x7~ZGt\MF> 29Jouxq)\ Y |C _]]AN۾};;KCCCSS;|/޶m;H;HP9,MfsչkT$?iltK{9)_~T#1IU>*0zp{,8JTNIpH/CPrB̙z( dO>5jD"innf+//wrrZbEZZG?hP3J930nbnDNN֭>:K&Plۆ[TU5 ;{_ۭ4xv,sW>c$|$Q\ÃKJ/?׷@h=CV"[+[G'+K+^OGMsvvF c( <(_KK ?@x{@s4C١N lׯ;wL&ʂhff6tY7VL]܊gntBg-nOTZ}"jI[/3Ӑm j^o~ĉХKD/bI!9JwBFo9F\>w6/ڒ2f9|/! y*ʡ8gʕ %%vvӧ99fª*\T\3.ࠆy^dldgz'6L:UR755pW 00JvLƏ_ZZ`_nٲ#CdKbn( @Fx"l%."Jx]AAV鍳,3N{1;࢜˄u?BbMnOTKH*&I5hAiL]VB"!Ċ<&OdxIDOH-!|^!|@]1;!!U0{Ie$\dHu… T3f6_ vرQQQ]MMMݼyի n )Μ77[Zp̺|-q8yGI V=d0. Ё$5zHP 0o7ֈ`Ak7͞\\\}Yv3wgm3k˃/xJ̈́kKws7An.GQ+[[|1cơpjSn:yQDfyf Gbs;$sa̳ӧ5xnjl")f+TL7aAb#u i}}=CJ̓`8zYC*U+1a8 !u\ ?ը c7.1˧9.<٢X37e[wx `HR=b􋒒( 9:HnnnHH|=v/,*( Zɩ26)n BLѢ.f7:1^¨Iljh˒5Wga;hLB\Mgv\DfCH#!kN!dsӆ07gafXd2Yrr2m۶͝;Jݲ*H`M~`XVVՏWWWlE)ݻ`l 9~B3aii3f췱i1W-XpjDzCwS<<<ˈ,]BBW(ܩS}Yv?׬͟-jeZsa:8Jmh$}X7x<;LKg@npȬ‚œ4j _Z,,-o.\8`'̤B!YvO-8 .q^H51'K]6\xu^]@0(z27h=PEEB:y?777њ'`aR)>[ZZ #"͚5 7}tvd!?,x-g¿[Y[?z 'Bj5Zssѣ![lYl֜;wn(uQ\ojjg7q%v8G|P;v9roJ5Jfmi)3Q@d&#@joy*'V*R=|Fuk)B3^;v,h_ #̃g!f=B#F`e\ܕϔIXX>}>O3mժmUU7Rdn* ` >!'&&/N#Y;j_FFEMQ W3*S@o3@fy|.9V1V۷/iVkC?8 !:| ,(G^}ئMjBr-b{Ao >rߏꫯ}O?͞={ 0ȉc7"t5QqV}̗^J20037y9\tッq uo:)W@Gk_,7.L ϛ7ybFX_tcY~gh+ ߖ%;s"!NN\XI9r䂃"hb贙Րoz]&u&w}b@ מ{T简,J\\\؇?%9^not`RС(o&l]қ.Kk4:,6N! -w. ev6/G3G||Iw=~_n|&'bP5в AojiM ^0(^mvw|#gORhe-j7m㷩e?|@24: T~/`9"dyk 4%ywp@VfߓnaaQ[[j㱜&H"##̆1*}_H[ ^FUkTpݯ֌7/P s v) Hbob-8Δ['33x?Cbbbbbmfee% 322 do8z4Z m *|5:/dWd zN&PpǗ%wxL`)ȑ#vASLYj /.''g= jkt8/pu^q];< x<^sssyyKd2YPPչ֭[G6T 7e+I5yyΠbԮH}*mZ[ ӧO8msww/--MOOwuu?~ZS(999 P#WR^!Y!w]4H$B\ d֣GP'N '˥R),棏>B|݈#M̙3hIII4}.-AdߴiSII ě[ꘐ =tHf#?Ǽb(!X ˜9j7 ++rM@o{Futw :Ν;wq__ߊ'Np84{SX}{TGG{{N eaH㈸0"γX.]ډTDXHv9r$kܸqTJǕ+Wbgԑ{-_ )S`\xY %~Ɂcrsvv,G,>>jkg<-:%LV /Fzz޽{ :`@kii1NNNs zq)/kqCb'\d^ >4{= E 'n͌l-ѣGӛgq"8_x)@Jo^!>PSFfZBZ{@LPT*|AZ n4Ҿ}P_SSS__ 7gzkO8?ܛ-*'k<*FK "FXAжj

    oN:1=ſfw-r%%;f䒛|Q,YFL34A?l'Km8NwS.MEAhU5V+B026Nnv~lW* 0*XB6%U>$*q+egg&0GT!Hg;dh{UJg$@)Mດ(RUЦc$i6m; +j%n s95]mw":Ĵo[ba׹ c$er)=;x*]97vUtO?S׫p};&L2MԎ,<#NcYV6d e3h$ ,C eͫː^}{]Ǚadh ;P XV{≛IR<,SԩNǩȸ= YvNV/RmI؊\dT:bъ/0vBaKbzx>S{nc%oifaCt ]Dzv;zݓy\tw:_G.zشu {oL=2сhv?= %Rx~=a70{XR(̡Mc;44Uc5ɱ '`YR u P'8#^O~''q okPgK沱#Ot#n5'L]bmgm/!'s7qh }[. &^ǛIF(7ţ&K? '֫߄ =k¡o@POW<.8l9f>cf"yoop'ǒ8iXǼ"2PQ n տ:0q oΆDJ-ufz %h RId!M!'!ME}uUJ=R1aT~1[`nz|yO>w !0L8iヌ8s#e?J0UIT;`bv؝f yDI=4G`?û* ä*zR},KlG(*m瞋p ,.W?%Et8kh=Z +D^);$r^FGGٷo_ YNSL}- u۰YzL'^||&C)4 9!t%;z(P|2ACLұ,i_1, K$d2y2Ex9S1ak=hX6)'ҵve%vEO?O`pJ>ơ=Dj9o ,E}<+|w3[/Cs׷.,Vӝf`Ut$O~J?&=z@2?IiA~rJW0z zc6!g糩+Md:2VWme@!Adb@#]ac|+}O& 睉cTguynk?g|l07=~:C\188zy{#L= JyP^:Cԁȟa5)N `$ ͐+n5Z @3FԂ@Ҡ♤MZ<}T:ja;:H嫍Tue9N2E4@>bJCR,2/:4Ѯ䪕۶ r4,MH$Х51RIjva@i@XJ =H)E/0pʉG `*ӲXi%T+ DF 3mY`Wq"zzO` J!H$(LQֽ:[>+}BgGo&_f7ssIK U$dXx{^RglbwʝȊe9d>V&$^~|<ЙIwmJV6uCF@ ͆+?ȖgdHa+ElJ: GԌШzTfHXeJL(ZyF(jY4BiR!/M|iI 07J՘^Ӳػ&%{+l1ɢ-X8K]n1y t K4ȯډmgXn۶v[->::QEM-Qzڊs0^5 oQt UA$~$O#,+/QXZvV{ʹG*+I*ʲc8ʱ؟ӱ,5&*j o'b< zs8G+N/⠠d?@^ũE,S`G[^n6_y37g{G/ ZVc:, ^)?dnAq_-p?_I7H=Lui 拊+͋^2u| 4.q"ʈ'Fvrޏ rm#3%~)#q(>5J̰4Gs[N6JGH\mf X:VYzH2exNN=8ad]@r( 0 mS$f/i]}c523yۓex Ckqc){ҕDT+>,id6@)!_wPR1Vԥ͚F4+4%l&pl  PulFPHbhNEFrDҩͨ ?e/ZPX%"ωeԚЛ;rqWq~{?Sg_w~㺫g$&ȧ}7o)]p|:=*!3J1?;{9wA)EGW7#cnW\KO d*왈 ے -:Zx+~vV`ڎ쫕h-Y0)FO7rv{&XB"shXIf-iԆ3JP*Cu|_177O\Ʊ,Y0LҨup[sKvP/[Q{rD"*U}IV%Ճ D#wkRu6MA96 ȉh6?VOVr,x)Y C`> ysq|sw3/H~TxHF&D-rvzu*B7s+T`(iNUIv?dSZE[*=!C, <3fU2,%tE G JTV;mdt[Eox?>>~NW_ `cjM$;$U&~qtE=sw6lxsL9s3xK*pqzƍd1,(ZuRCDÒMkr@S+s3:J׏E&Zʣz:T<'(zJbn%5^'0c/_>,t}Kȱ$e07b/K>X]рoR 4d2|Q mlO Ӊ=<4{z*9Pdƅ:h TtiSNGpӵS2v)l 2E G{磼d\z"47 hQgMU"3ψF?É I F pL.6f4jl'N IXd1Ȑ^V=ŗ?{|@׽f8BB }f C[?>DT aHj-p,cYh R) zR:|rEWϧkj1}*$i6eaoUB*TFz$'.U3-z"̞@%XTf>N6౞X8b$6tQ f;W`vHyom4Vl{L&E X(ktÕ^p#epiS0m*vdlF?#>DC? 'ZcRrfTpS14 Lbك&X`CP/_`ӰW=.|1$R5z@MRmC+GXT`@b+7v]xq{/Wx<¥/~/ϟ E% J)g8Cv3qp/ s3()tt10<8_r%=C$S D+M C(EP'ut[bՓJcVWb`Z{"\!XAR؃\xp\mRtn9i;C~{^٣y/i @[56a)vH Dj /6M3LBSbI^j&K X(%Y M  u|iKJImaZZu1a@UkD/-'+J ^ʓ!j1}߯COq&-~)d,`h>Ayl8Gne*1BOWM! 5~BGi-,P/Y*5'6hB@w= ;MDqaI 3*k0WGDAFo 4A/_1pcFca96|z(2=9K|s})܇R]ᒧsw?E+a%NLFZ?ɫN8>Sſwnw?Ӌ}f]ƛ?MD"5HouijZ\c~{s+$SiM(l ARihnwN:J++Dڽ}̀fтX)){z"0sG<!L` MRqѶe_nwr`f*}[~/)xB!-mJ;1 (ϳcl;E |_EYv*Mցah&ݏ;)pLܡL||E>錊 WߚoA`-`,*O4˱UeBS}:$W'X/d4|.O"2iZXꠣP,CsA9Se^:ڠ$4 yaT 2nQx6e 5E}~T'Y 40⃿0$aKPn⎇+Q>o헿ʹ@PEFlXJ+ُ2T%Xq2 v_T߫v;%̷yk_|" Ahh~CCF!m;t34?j- W}ߏ|^uVmv#}5 ^Eieۆa`vt] [\C=w{ijnNߺ*?/?~1y0s;g}?9f<8EpQ_;$4BLQ4(&&&J þ$GΠ7`r@4~tCwwyfgMGf.%?7GEl,A )-LM-72`_' fq'i!;B-~1-PŒ9Jɽ,/ tKץ`>ehdt}ލt˂VL=8SnFߺ^L{HR<§(SzZ}+ka1ڑD>RxFRAdP.ch'i97|^>"^mtgrs _Dzz+Dd>py|49)[PD0u`CKFi#κEFJ%y2@#jw܈ON~t?wDΐ@ s U6?m雙9t_{ż䅿F2Y\H%jq iF՗.()b>},L}|jOw`T&iht$U$([e0L4VvL퀦xZ}죍 6R)Tߋo쯩T 6mN{.?FlޕIXK>g6K|TJJ>-UWmRPA c( DJIgg'܆h4[}7 #edv]]lߑrlQ.dys-# Ox *@( ~" kQ4hJus*mɖ5{U*^>ZJgߐV_ي,H000PJɊT>'[ #;Џ*GL+Бd=1ШJDG#C;4`@#{rm{MyާIxgr!/z6n|W)Ͷ3FC5S~A6i8anzR&L7І\%ٍm;hDtq rܨ~0ޣ1Qr V2@[j+G;HA;킶%O]}X&\FīZmp͍m_W>2ǯyMpe"2c_zHJ|rda8vM 2˳Gl6:n4y !Њ0]A,Kf( Ρέc&eæ3wD ˛draR039~cZ,LPr9wi078QJ;k)VWK`h$`6AD{,'SJة";< K3Uo]ܸ' @R"D$DUήĶw*ڎ^gcߺ:UI[UInnIUk'^I|?foI$$«ntw> n`lRCэFw|-T"jrF[mK7߶}΃l$e< n^7Ge#gZ"<AM/#WB5g0ۆwN۸w XC2L=ə|6apܧtx 4X)C_K IDATrc M 3k>q RI6@D[Yly_}?s'\ tBl?` ~{?z ùq@kW}] 1$BP1ƀ;Bچ5P^YՏ?B-?{ "}fvt+l߁ŽШO@ NŽ$JwW۪8޿F;q⊵) J>h%kmx9/AXj"Uhf =t3O48vh5Y<_ō+/N!β`%?]Xl i!ihA_Y|p=_Hge0,Ӵ<z=З+lG"b=Ƴ٧)aaD QŇ)&LMu.0` K`1Nɩ=`YK(5%X^\Fp?Lǁj5Q4S H+vd b 1ބ2q|;D³h5MO|\[KxM8dRc--^+㽋oE,h^^Zc%,01QeaB3QJu5OTzTo[^\]zN[j+L&+Xr@lw \ERɆ6b984nS̀N8,d4m"/YE1@vƦarXfXR"?ej#5F %58uAetTG]n̒Q^3khw `)@vn  L,g32CaFLk19];qeje!giVl&TUHTZ USÝO>F}AX+MABơ* ·uDe#l'9ꗩ2h+X<`%~#nDю& 偞2ڴ3 4,j#ZXƞE|DC)ϙYUQS^{.`ZECUk:X/f"1l6K+Ir9LLL@Qoe(2t%%zeFݐFE$;pO#{dD%6n^ېeeI %xleG@Hy7-B=adòd94DXkg,l 8di?u%x^aE;N^6 )mka2IZ?AYa03,}˲e'`]3qoҞEKσeWځP?~{wg{yH~?{ fl @Km@+/ޡ?w$ 30x<("r|ll&''4*2suwī4qHE5bP ptS(6Ifվl B|D;Sjqc2ҋI0>@ vN#itN؝ X`)HI< uҵ0_0:aafTaz:zX-ÐD4,hiKR4 l: sy9g FQ8ohӧQ{uvc01O?g_/L6 2tVS,k٬V!^߱K:9@kY0 ,;%th]fk.l1%y,c'Z bX)Wp>~_B2.ѡهK04$ 8F8`l3`|4@ƠָQ 䨚de]gԖQ%Lj"JT]'1 0 X&juu?/ٝ 'pмxQ&Xݐ^~ ?}p< j`i`U {9+ZegtsVLӌe\.bR)E:),rA@>G&:(AF .IMj=Q D;yC,̵ V"t䊒R2y! "_ÀXDS7`Ϋ- yWn_{ 9ŏO]_/8 E0v<>m]pO!iȢ=>e } G=aHh[X5>e_ q16ע{O{Avgg%l&j8(%!JAOЮڪq0Ul6yXlݹX L,mF?Dס> ^!^ -v=Fӂin/KK @jJV搓IIHeYqJWn](ku|iZj䫟~PDA ҏx%hZH샺]J>6&iZu@-wju 7qsKKV>+73/};y|K?W1?>x4 K=D cL"!*ةIrt4kycT \dn۸,F_ZZRR>iex\qt)J<g<]KT<;FDQ 5wī;3%~5 |?g`Y{enBzZnF\7"![ˀ8X!u]f?y ,yO~_ᩄ Zg^[+xs??C])d2v ة[!u2ɆӰ4,_ʲo|+ T;j`AvaFa)#zQu6A?cTײA7 :Z_ƍ???8 r|#|?n[^?>A$ a=e5Fu XXZE/4eq(aeee% [0!dLq I( fQ(/^ #_~wzwa bQPc A}SA|{w?QxE+9|ٯ8{H?M4@^[No}|먲1(1ٟ{%!g瀸9>en;NڌfO4XIm ڃŶ=n{{a7 BV&tvD%ܨ%cUБ "5Tʁ0IĿ@ 677U{mZ7JC6犥W:eg@ܲ,Z*jk4nʸEq1ɠP(xa×_7ͻL\%WUKwJFڎG@ T1F;U/5ǹB@*K4uMG^Bf,_yW X8led8rGK'KO`7sO!yNx+yk;L{|cLgtA ,p r؎GXo_Ր@itN1>IKONv \|2lw$f10:04s6J'#J`bXd04l6Q=}+Da^%Iҏ!?.Xٴo 9C8犥*(T*2 E4eqqQd9S#_ccč7555JL4m%*v(%R C ?A:lb}O>VV*l߾'N#X$j%~L$(:/~kY2=T'~lBu v*g) LѐD &Xp1:] )O<-k EZl+ӳ 3v_hk$OaKTǨǭ~alk.|V@흷aGg?@j=,p׬fl\t[ZR2.IAg'eaׂXqMٶm2GP\²쪑/urImGݔADE4~±-)rVwd# '<,`1<>sx"*1M_8 'BLE2ktj:6ـCfz4nb;"Xr}eE _QKѢ^x6yXi׮a&OC//-{YH`I!4wŬTl+ޢu7Ev2MST*JRIqrʄ1'&E$Ied2ضm*ҭKeyท^._WwfJ>ql6a&=BG%:6qz'Yu q{}ނԼ*{`iu _D;;9ifv lXbK 8×KRr2.RdYPGWf:t)n7ypr%.pG  ŕ;:-N`"䃒@, _ғ0 0QW?Lķ -NGEب] ;v(c1~&ȶŽ-\' Q-FѾ=޵"q@u~+|{vC`__opFZƇ`RK7i-LA9 /.En6JL:%7Ա (c.%y$9Jy$ե+3{+^4Ϛxώ~x|Mx  nA7DZܨcЪ랩Z*zϫESQuao'TA0*p:E!nA CT\QwTa cha?˂.`ADa4p;F֯#.0nC,]?{jX@kZMB8|.///'ytR2,z$Ee9crrrM]<(3OX [*ȍ25bؐmybFNusW,5h}JA0 \.+r;DeO7q%*$`If.%w|[?>{:.]3Po5 [i E$DId00␐$Eh(R1L 9 >+ިn",A (cz?QǦ^#JQ2" f2{g}c8l苋XCy~TN@' c=؏̷_73YzinhXCL NHhz=ۃl=bn NR9Q̉Kzibµ:n.|zb@iB$e#$q,T$2" $=A+Vݏx?B7-? ٱ R*x0%jNF4~EzTbFPys%>e6t1P~&*arUw<8~\@I8#PςQHyc!0 XV[l޶#8+ޣ"ŧ _18F!7 ×KR *c I L&133]J>KQb,nh&TԛVj-\hr g?PoM,W 0 c Mg9L&9eQpOX݊f{OoRb~ $U@^رO\0 Q \X}D/ߠ & Y :tu!΁eY , JeY P>|CP{-#[ر1Wai:`uR=FӹbI>  gYK kh\ZZvrI+Oq'K$;)b< GRRb p7ZHo(jDar j趉w46M[iA7L,d I3in, ZRK>}Sw@gGDUj-~(O{aA6)=Zʾ7; Q 32Ѽv ǎaTOfjSOB0v[¬ކ=J#ihFA:|-n5WR*XR=:$e>M(,K,cbb۷oHZTw0Dib{:-|rzTU `! v'%!1(d9dcRXǁ(TM zzVQ=󰝓35ZIDAT$v[g(Fd$2<D[\<:{O^|׾.w,pͶ+BC6报˴ _,q/˲Zj.)xbeCZ*/ե1qk;eAmX悎t?PU]tE\j4B1q~X($hK\3\Hapڲ)]{~ 3ާa Z -,:Ud| ˲y>RUNBATAa1"b/<w-pW*K˖z\Ӛb0|m%)dUUUU'\G -(˲,K$˲̎#yL&Uy)$A$<g0O6Lr;*V쑯&.TQoXP&ƻ$`\aQs"XZ}3_^yIxvT[ݰYF};F3l w Na,GpUp².`:ʑön`u =4bH &-p[n0j<ڣTbiFV;|.NcfiiurG9?qk|".IĶmېfWRX !HHGT߸;u㞎;:\nzuMlgUDgF^POo ȨZNI;׀~\ Z@C¬3lRz Bpҭjs ABu;0. мv P>x۸wL6}> &SS,p?wpX882WՒr\.{_Ν$QQO,?11L&R&''=]$I.ErKAkYDR7pj•&  +-膅1zLC>zMTd1npE`1Rrq;9@~=8 H'!xIa ywE%|;ݰ d~wj&6a?{2D8SaP/^DTFЪUf >$J% 2Z(V{!lKh@AAAK 7Dјrt).I5@yޛ$d:S^6Iazdyr:)6Q&.~WǍo^EmE1ʏ+,&W~vZknlmZBӣG^h0cLa 0 . 6J9AX؆%a:`HW~2L۸:کSICWBίtZZTwAo%V~뺲2!'.Qqqe_\<g2J/] 2S߱euX3S4Yn#oaje쑯֦䲼mGg!;Id<;b*4 4d`FtV ^v((GVt6ÆI t6P9u CQEX]=,_? FQuw[~fc?bBSPPPl*2I1 CT*Jw$H>"Hl6;P')(X ޱvfM) ^ W ,m}Bf1tQDe-;F>6d'f[m^0MQƐQ ~EzmEGۧڐe=RͶ7JHD=Ƒè;wa-p@왧ί!Q0/MZ(\t^phϒNcVȾ~8l]ϧR)yxWR#_fh#_>ְ3S>9Ba 3䳂mGE#*kɇWa+A_ȆGXn/+R .0m"$3JW]ck [۸t cGQ9rΣU)~+ ,]ugMt\K((((((Cu@_Fj4~CX dA"ɲ,#LzKX"!Lihn.hҵ&|bf`҂iYH9;ѦLב" fAd֭cgS`KkkbyvkD+jVa?haT<t7ˮm\ܬ-?} [@cA ,pVy sR 4M4mfyyurdq/I$&Hԥ y):2Sڿtb[ۙ):pc75T M =Aq;'9GxfK`u!aFݯ c4vqr=l')l.Ǡ׆m!+Q]!t&}aӧP=|չ94?س`L"mk۰o8+nwz9|QpFZVRLU*m2Eۜ? ø]Y$VQ]J:F&mVHQ@$0yU3Qo؎^鸻u5 K-0 A:!Csn_\jt XoG(_eذaAƭ`DAP[~D/hjolw6uϜA[޻0u ħ+!w7tgj`jWsƑ\tޢh(;K_{jZmMqzIKt:|>\.瑔\.|>T*IVR!2Sn-~OG4\DfwS@JppzC>cbwS W\w䊴:^b=pDD!cAvt,yd4 4.]BqT6VLf!<8b_?p3S c6TuaRp6W,wEOq"p(jFUU+,`kSdQ]"Jq # Nw䧸%*~)Bou 諪˶D_oy -%ӼWY8 C@ AQENF'^/0^VQ|tplp\OFyn#GP;} ڭ 8ݏ"ܳHup;tGKw !JL7rGRΒ c TE*OsȻv1t;LBn ף 07lH>Q;mTymuaR9Ȇ8mY4?˂g?.]I&{Y~{j?b};b ×;q\\\.H ,+9Liidَ^(1JlWSkwRԦ'3=7t\DU5X1=J U]R:|?pB$!JaffBttө ҥCWfRWƂ5XIr'b)S5Hb>ʨUX7*9S^vl*zyY(v*Hih7oGwA|i*ݨT/N;MCz _,|F1h4 KKK~J$M$IXX>Ncjjj.]\] !H !bo&B:BY-BE>L|D [a+kdv'Àut/C{jn͏>Ez J9i Gx;W,iIAAAAAA0%(EӴiVVV\s rHN$IRL$q/K K\n?$]`*}7룒9@w6j΢vj'Nq" U;3 a_ /{MMcRjŲ[`[KKGAAAAAAAa9 ;)RJW*BR֤dw~PGDed2]ץl^7 ynm޽ k qB"GAncjǎyAR^q,p}i⍦f5o:;M?PPPPPPPP|r''[#MvFM?Ȼ+~0n;B%fQ;~X.?_ЎnnT8ᐍc.%~)((((((((,Cu(HQTb"IA2~ƞtĉ m'Ovӧ]0ħ@߃.0m \ajw: lXЯ2% :g"9DcشA{OQ^d'>,G?p6Ǐ6?0 l!qڻD/ \ނ-?;MRPPPPPPPPq[Cy . +Nʚ۱,;c%0 $q,j'N>;ŋ00Y{wC0 y0luI4X.QC+,5d c/d %-A K7E# Y B:'܏Zq"ss8[߽ ħD0H"a[-@,po8名劥JRPPPPPPPP |w#ncxWqy\[!nm\zjǏC=sڵO`q,Cx oQ4;T,^Xyh&~~(((((((((RRGuݰaN,Z?(bLjՂUk.GK-zQPPPPPPPPP)` %,$u64 K8u 꼣۸ym+@x~NND-p: \Tf%  jn(JϼٳnYhW>jg7= y0eGNA/) f 7.c1qs@X%!(ڮTmF &Oqp3f[4<8,KpQK&(((((((((((!\\D V~=h wBW>I0M $,wrR^.x,Ga5h}t2vj[Z޲n8{8b64(((((((((((Yv~aXh9dò.j- W,YRXl*zG¹e( bNO;% Ar]z)(((((((((67ӖZ>IENDB`PKL@-Pictures/10000201000001FD00000144CB691467.pngPNG  IHDRD- 5sRGBbKGD pHYs  tIME ( =ltEXtCommentCreated with GIMPW IDATxw]}9ޗ;7rNs@50^%Q-{ʻqm֖z-yk]j*)FFF4埒}kY-RYby%*U4-1Dְg>kB ~JJJJJ[E15%X\\dqq >_7iZq{ӿH?m^)S])S.)/.Q^\dyy%+ˬh4jZ"kBP(7I8̃XkSOIIIIIEV^fyq?WTDZVQը7t.Z Y~g_O))))))/ϲ"KeVuժfNÅ$kaۿX܇1E_$@K#<++U*ejVDӡhQovtcpRB`Q@P;JJJJJ(odmo TVjDQq !-p߅%g@t4?Sr"7pC񧤤\fH;vqiY\\d~iFskm/T9GoZu]F?y;R祤oq)u6p9ʵ&f c|JZYsc$8ZK?399TSRRRRR.їy~LD\mw0&B)AD8k,gnn)%7Pcزm+DDQ(hZ4[uKx8cM5`qĦK3LMϩT*H)/z!DZOIIIIIyQOB~/[neݚu|Kl6YPh)R!:&}@( 1aQ\^k#TSRRRRR. \w84T9HpIĮ$/pV \.j=HӱAir099(q)A;C ,kAXX#"USRRRRRR$E^xW^9N.ZHC&) gqƱ{VJJJJJJëBsdy?3vARƎ(︧t~4:K2c.qhTG?JJJJJJʛ,@2coYn4-iԚD]ӏԝQ1XgNl6Y^^xџ}K#~c k֬ꫯ`Z)TcE{9gEo%6]&Ϟ'Ͳ}VJJJJJO$~};5@Eqc֯_?Ʉ+@KB""ab̩3 9mێA|/G/o􇊾szT}B>%u'Z>gqR@pB|,cp"[lYF)))))?8zqiWNԜ*#wk-wy'KKK)))))?i$1Qth7[t;]Z蕸ץolɏ=ok4<M6qUWcǎY^EO:'oA)ʼn'_%* R %$bRގvMϿiA%Вl6K>g8~!nTSRRRަ4⭮#FE8?2ZvIբnvt-QEak>u%~!P(cϞ=fJㇿOcCCiapx\.V k-],!J s(-ryFJJJ;`Z{M,KK T*:8Q|Ѥwi4 ;qL[tz V\zZH4AP,ٴm+z+vGBʷܰiz Ga6sט[Zo# L&C.[bdt}|gQ"wIj94" NvI;vM٢u;]::M9N8 I 4\-[pǾf-.4Z6}_䳟, Z*r0G(":X'X3 a 5l>'҈?%%%-.&.wQיq3T**DTM6nnM^{)Nb/k?`(di\=8T d3: Cv{w/wܹOhRW#(;ZKt(`R0}@gÐl.T*>ž{gRRRRRZR6XXXpK,/,E!:[m*qKۦthu;>ĘɯֺKu0"PHj\4H+(޽[Z/}z}??d5ICg)2!B Q"k'Zk2YT}jğ\Q}T7OM{f~fYjF?jw51QG i;n쓔}7/X|knu$(}XgB:0ˬϓ O!c#|~PA'k{+F=uCkM>_ddD(p.HB#Oal|?qBJJJ];S' T*tu8]JG{3]֞*$~1zߓ+J$Xu1A{>)%B сP(p뭷?شyp\%^ն7WH>>CA1_b`G9zJ ]t%O JJJe.Z-9N?‚Nk#A"BzD6fp~:9okߗ]l*0]|ٹK).N^Rd҂|&֭?sn~~7/}K[8 Ð!KHqt;-b&!4J; QZf"~KR7dJJJ;եsM??t}}DX)#9}oc1=^y/W[J)\ceR˷_On_/P5R{_W_-Jzgdl8B8ټ_x0PºI<$i2 Ph K6w^>O& B#}))))oJ fg' BveeRمY&&&9qssWj%`.|k-JB&%P(d2(B z꾸_"=|ؿZ)KthA`)~SY];v[[\qՕr_w_RY\\g1r9/q:-HA&|{/9SRRR@uŭ^ovxou;Z-*s3;~{Sg责~Ts4Zka@H>'_)4ZonJ검WdlpXb+$X H=hk͆lڴ~77{ R_x_!: o&ɛm!6_lBRL1@=D.WHRRRR^H9GޠQ[y5'imh4׫`pq 4Q111s楗_\^Il3qBn,N@&aX8P" u?B`Ɠt 7yL9$|2}? D y MBIpذn mn75DW*>_dt| c R]n׿ \i P!JYranO/300 JJJ(FFnלst+w:Zz37o! _C8>#X Aw 8Ld$Z dd3E2YW^ͯf͚Զ7%%%5$cj+U붼c2zqhtZTuڍ_niɬdu@d|6P/Oo>A&('3}222B.`#TTǧyW"g/pUz?=g~ $l/ L7?oxS"7\WG|^dddħ"288L!6&oHd~W7 FBbyVoGo_Sޔ_ȬBuX\XxfvjJeٛ4;hvlۼNj7]{֨_w?T@j:rI/'~6ell$DBV4c5\PU^A ΗA&|vwFlؼq=.W]}$f)Z|s߳2::J|>lu q!6o+  uC)5 {o)M.4MjʗWh&ci4-%fgXѬ#u@ s\.03PQl" GadP(`p|4\ ^ekX?6ȈoUmv=Z'6ǃ3>!%X?߯]&%Ƨ^3Ҡt⎿vBhw>[nށV!ro[^^擟$>B~8\HaMD!2i!FL&$bz}?bHIIyGF* yת7.q#vNbphVH_<+ǎ15=KV# PAl vl_a/ ^TT*5=-H0Q\GP*X~=A݋^o_?X8aq{%)\p6{IP%t__XQOH Xt1ƠU 3&7) zYrR(RS.C @ dAHq.aBc^DHʫakž ~JJ;KlSgzIupVDiPB⍏l6r5װuLMM0?O,O8Xbڵh!aNg]/4hcߝr\cO\Aբ٨ }w]eq&Ri+Hx_0R!d !FiE)|u1Lwp& ߐ K_P֒x8v/"Al aA+OuE6q+={ÁH-yW(PJ]RRRRYXV78۵*gNvOcy33<i7ۄ: !M/ƆJzr3,/.yAWB.GDh(AkK)1`bE1_}57޸W`zz\6=H]KE7iaHPKsxzz˟obNjsy$ $HS"3BH"4u~Fx>p_fY[kd29~8/"\֛J_Xdg^_frr9J2EŸSRR!EF 7yvb@d9J"B P-9{v{'w;J%r B]p0䊫[nD3OQ./v1qLd,saؘ_$7wnwbiq'OEB]KB)`Nǵ^듩0E .rR~|׾q (!ROD*ZB$k-$V@"q85>}B!k{J_icZ  '83J%Jn ,YZl+9KΊ` >Ϯ;(JXg_{IIIIy[n2u;sمy++eX*/ӬpB044̺uٲi k7c|ڭ_x}yJy5 T%PBvɆ!_k^Jʉǩjt]+)EJId3 BMѾO|įF)pu?~v߼y*oÀ,gq~˷)K؟ X0Љ.Q"6ؾR~Z`rr[7348;Nsn3u++U*ezzٹyMԙS,b80@0 7p#bG=JAt N@uq N# G46ndp`_w^ס$Noa/CC<Esh.^^dtt K"{Ps"&`Ղ޿~w1ggQ*@)/h%))PJ"$81vOpdpp/^ e%T!ԫuo/)?{/pwq'qIDrSO~׌azi %%ri?"fgęfh6!J 9f`h̰TZ)K/rn,/xwr͵ײ~J IDAT8#jYa=b #lZIvٹc'wz+ G")eN>Cihŭ R)ﰗ.W_{ 7Çiw 7I)RYA##CßW~dR9-"—Jeǒ@%FH(RC"aRHRhޣ o$Ԫ+,lwϻZ33ok Od}8kyd&86Xk!$~X5$}1CX(ZGY+GeM?r~ !gN83WUVV*,--rnr,.c`pp165lظs K8R$qܹI <۷nchh뮿䥗^`Xb|sI[D&pǝw266SVT&NAK -5H僸v]ؾ}_xF?vIT;:ZHz ty!n/K=!I6%oҧ}%Jiߏ @ TA;ynn_+ ,ErϻX,# pđ[pqKNn6qZX,w_8ĝ./y@ڽ;SRR nsެf~n'&va~~CE(\|iRDE(Eԙ2Bڠ0P$ ?ϯ_aL^&"mm[8t.A$̀R% Th?HH/'e)| )QʯR'ҁM2q=$ŘU*e:o߹_Kl&Yv}rB. p<WR`L x'?%u%)vL=SRR.pΟwv n g,AUI79 iR}t:L(xM7LZCVi I ذY^.sQ:Vi5H#sE>N۷m6> q7u-L [ZTT(`lrIOL4Z3O 4.ƿ $JVA.)8_%o]|?@&}g#2}~߹së'{qeV^#,̗8'ΏRT,tCC\ϔק}^9}$֭el|k@ZZٙ)83n&)E켹hv8)X!Q$KcQ=GR*o;߰q{'=é004ry~<=֭[}|nbiE+ ?.%Nd[J&$Yq- /@yy ˕2۶lqކUqa[))vd |{OcҞǎj | kJ pZD_IB q _+N\.8 rU7g!Rעt,&r׾;7J_y-""~c k֬}'MΟ?O#2Ql(({MM:8DqL^9lٚ JJeCd~z-o68xbnqJָ^d-^*/ ߌ'Ye+?$9ql+{OHfwKvıeeJ :9$ޮ‰$mt0H6 Dエ?@~ U 7KҸ֨;7߾oï[NW 0<?G^~b!OY8{Z'?l>uWg#ȟNũ'ΰkn_^HjbӚJJ>VŹ?kwer,ǎ3>;ɉS'J36ճɼZHl#}l$ +6 2 R)Μ9Łbqi5kyϻǻ֮]T' CRv/7% x%ƧoP 0:D!cسk7B0ؤd}/eEpÍdB3txsAۦ٬nz,~F_)oa@bFH?~'DgERW~P)X2^*XEʤ lLEHb-mIFQ;- G8u$P(`# Z a 8|]X3? Eq̙3gTعl& ~JJOwCkCLu9*R,G9Zgb6oĦ[Q)sIZI_ACH@Oj%T2,-/O~|ۀ;=6mZP4T>Fzz%.F$~ًʅh \Gr)L֚r™ر~g|f"y 8ki~E Lfc #Ã30)t-3&Yߵ7-\?{%#B8F [Ur@b(,1>ScLLrp6L{ޒ颞0>"')8LAh>9D2i,Bdу&9Sl޲!^wƯ]Eĩ347;SZZZbaafNӜ93AB^ǎݻalܲ|"ꏵI͓-v!| C|OP}mvP(*@jP/^H?.}I'y)ÞpYC6_رcd28&h48q;3>6_EO$HA5a"$wݽQrd0"֨B s/gǾcݼ8p{q䟬fzH,uZ VVͷToIѿл}>Ll֓O:fu6N Op7N'#6I*F:Y"ĩSgcڵ觤d%{ٻcX\s߬K e&QR[Ch4tm۶pjMq`t%—%% x68Pafxk0=s[n{*kZ'+wMC:w{>-;eO]r6ƻ>LLL$w 3T5N:͞ݻk,JZ0 Ð |wgϝ'C?({i%2T3>O>U{RɏYߩo}؟l􇠾˞Mj>wX%D%5ssckv?a Tl{w1P,_C 3!Ԛl.z& Isļ7H68}:ٶ}[:ǟzTKNsKi6,,,bZgժ6mč{oX7 83:wl"7!|d2V?WeN:k"!{QJ"I)H~Z!0J?-;dUr#K1wwu.%BJbZS'+Ya#R8ؐ͆@!dY2 :9qo|Zm{:G^g4*@i2Xg!QR  b<,sP\XCaHO~ocl1cc:z}pϫ%_l_ r-lۺWtc2A՛0T8E.'P7bG'>L&u ,+Nh}C*)))?zjsninaVe~~9*e6KKK,,/E&r qM7wгؾe+Yqss=2'OX16:ab@'E2_W8q8;w?7D>'x t"8lRXHj—2I:~^X*K//~BԽIU8Kgiyg&ټu3Ql64@ `[6nUW]#Z͛q>}%A6d)/BSAA72Ħۿ ٽQ_5#;f ;!L*L6;CcL:_ ֭rL-R:mClظy;6)=qxüK=rB!OxkFc#~֊@JFw: SUl]:.G\^f=d2?%m ,L q5ɉ ON1yn33M Zu{=׭C+E6Cjh6ۜ:un2:$BJb1PklMw^>3bH| YʧUZ*$#V%d|YƼZ ^`&X,1??>9Ϗ20X"c?Ï7z_+%R300ٺy;\ B`cCU}27| _"MPQ 鴻($B޻i?ѡWp9/n/8ѫ[|~_O?4`Iy[d/_w`r6 p((|mchN/=\0)&'3ϐ ct]ɄY)џ(3IĦ}9Ӝ>=;>#wR/v,~yavonwbǹIΝ;OZfZjj5U)ر}C#Ac=fzz(Oq䥗CJؾu+0~ElF(-!*6m݂t`틘28-W%5y>wKsU(HWW z oRFc=ʟgͿ캮oPAIIX))I;tg^t?J<ĎlղlIe˲FR$$s@bQ(*޽?so2ȖwbxCY.L8+0,'5g&I^|v7JVq '>F׌y&tb38[앒b?uү\8wՙ]bsi<,EYQfӦMzvͪU$P&h[ĉ,377Dž XZy]qPG=eZcJ#>nwމYYz(XZbVl4ۑiYBomRObcX ?IUk3&"A@::)c^_a\ /}dttO?4*NeAIڔ4MIS{\|!C$^HCoax pgI|gwqe''~8K|)#wWz$O>6ndddTܵÏL+'v5;w+!0s0_u~~}k8hZRP IDAT+~Ԡk$4Ͱ]68IYOiIhuZ >>O >ۺW~w#(Ƚ#x!Hz2;m+?F'(0J}eɋ$"Y/ #@r5#A؄t8׃`ȲnGGFG~$4;î]O-Țœ,;2'/KYJ4YZX"_y&W%J=|m.\Į믣h^e;(38?HJϗɻ&Ν?z=S%Ez/[ _ 7vV$mE? 6\ ַ05k馛ذa/ckX5:BfI;NbyN)&OOrQonMє]J o|]+c[GÙZ*,2&~qO n7ДuWQtlt lW!(lbzE7z X{Oa| m-t®wc5 iB5i4M+! G$!PA}I xՈhb6(k8P QPxM {wׇw}KHR!9 Z#KFv#  @L'՝RMҚs8t0[^wq M4Ο 3ӿ[Z91>Jb Hڜ1U9/"k46odMuǝlܲ 7u6ݱkm8#z' lVL5|K<쳬ӟ4ckO{h2fݫNj[ !QCu)k-nӧOۿ/\頵], Z~s$-O &AcyHu;qSV!Kxfd>Vv^4FF&ԔеP$׉|b?Ă1pFEVTӦM|?K/ȩ'hڱKK;,P"3WUo -s8իViwe O}0\Gre={Yji|[ՉF B4{Z<jYh'sF+Sd xk[ubn{֊7{÷-gz=Vzy V%EP5q.VZ+c+wu xƀš<(2>I 鴻zsA իyG8r(#KERႧ(8hl5b'/;`rFv!r?8786' ' ']-233s?+t]֬#M : IKdWZE[bJ ˵U+^a%X-ix([Cb,%iuޓO ϓd)0oॗ'{22:Ç8zwC!jݳ,u<鰰~o:of,my=IMۭyF"kI␥%1P!5V t" 2l4 !`_x,\[nAykEV4-6mZ׾W-h4#y!nS悏@aU'!~W'U@q"]^qTh6ɗz{kZ/ZsWo6<#^Lf((-ޕ(mI#$($ Ivz7X0G0=3ͮ]䨫gp_uìM= >~<:qхAEz6CWtQ>g/zSC (V DRAZc9['Wh9;~\wN gp%\q\L*zΝ '{trry&Akիذy3GGk|޵BT VCHv!e!t1*-6zNk-zG+E^̩S=z%fgٶu+=p?ckױ{8r0_˯7ʱG{;<$QIc|5RWQ"X-M2˹_x"~2(脼ٳ7O=,6IqtB֐d.\d({腅 ={[-J On[Vj_:?>~ĉ_={,s,-ĬZVeʈGi%,yc!MKB 1}D{7Z]rS{٫+HVkzyYPsZ6JḴcGxKWp`>= ?Py9y?}O<Zۺt m leh8p_gґqh  F(-3IkM J X$;H L3򢈈$=\g+3?[nFa4*]G@%ëF 5 W{y^lx߾VMzטJܼX+do}իF8x {arrGR$](5ǩA|Y-VE$+|OGkƽwpSTd䋡Y"WhMp̥RDjO4 rW /J$MJSn/D"FBeY2>>g>>Z=5+3~/yK?|EdWкlr C#5BgrRE59㗯 AU|@{IB_AiKYziJ=Ěz!ߨceY~z>>x7|NMěO;lJ1YkE?齏}~%BY=JfӦgp'K/Kϝ9WfPZfҨ7m$k0aaYLn0qͧYBs&LV4T"U)%vxO_/_fiq1֯_Ϛ5kX7۷?Co͙3gI/ tS/ʥ_]XE"SSN2*BZt-ihZT{ Ŋ jgZ^yb,kk7 R1}lEzt;~䚭Y\X`|}<3Wf<&_eB~qѽ={CmP:G$t]9~9qnk "3_!AVJcMkUwhc4Ckie iP(#1 *W'_<@#HmB^5ZGIffp dYFF澂 |8f=z7|5emJ@KEd[5uB_UY <*|Y=:W|}y{tDnݺuzlPyoooW>|'(JGd䮔d*$`.VG 5-eΡrmF38?bc Ë LM]鳜;w9.v;N R*'J zȣ;S8Uh>|6 ĦQXF kȤ{6?Zcn"sg]^.LLj(L],/^q.]  ڝ] 3d-miuM WTyZIHף~|p\z7̆ Tx6pa鰴o&nh5)\5FYG~ګxh &14bVc V'`$]9W+2N*&jcI!WNxNk9?~۶zxАA~]ɚuLM]/ "+3 u;wetZ]G•(4C]?s?bl6t:PE+YΉGq5W)QޓDUHFͻ+gdYN5yT7+]ccYChE2*Sa|`vv#4~(Ibh4Z4-"w@;>h ~nT!IDV妛oE,{ԧ??/]fEyWC_=šC8o?334 >> E$"S1@C8w?O?c9RE銾^cWTkE$ֹ.5M+3QXRlNH]./$6eIɟ |QDAj4Oi3< J9ZcSZ&K/BpwNY~$iC;'xGh4ZW}gZ%&. -P&IB5IӘWQ]W3-Lj{'i-ӱV<鯜P ;'E`4tGx7h$)k׮_ 8A٢in1XVQFSX^Y_ez"hm\<* @&4gΜs> 'xgdj Jy^|a/:Obano]wau;nu4Z-\+[OfW^y__ku^U#ñ!bt"S,(m/3IY&DwMDzy,Iщ(8O^hPy᫊.EnA\q/`]!"f6abb4#Cl̗%Y:p3 c4O|;X,K{^,Z<:L$ji#2G!< v`C)y{ϠX;Dl⭵^!HM]m| '8x-OwhU }iJA6MISӺ,zJk;>Kװ6az1DyR}Ώ ϜztqaQB\Keq-EYȚ RkYXX`vvIՄ-UJKUtVFPuqAfs<'w>^{5FG?q,cor%7ɏoM7~z._HwlsҋwU,ir[o_eFV,0Xj1fX w^32ieNH!wq?o-D]Wa~c("P)15j˦96JXyP+ p8Vck[C AK2]ve|bTh1eR /ɒ5">`:BU+K{爾U$9 IDAT "@tdYʝwy,YZchhG>K}lb1F:`rX/ FfC7"MBHFy3/-q`>΍cktF <"qⅯ?sfb.$ȫ7 x >S'X32pId$T(Ŋs*8;NlҲUb,fvvgyo}ۜ8q=z+;w3=zvŇ>a6'x#aQݶon=w!(HT1M{a;?q/їG&&&&)cܧ0x/5I$IӠ&zF7~7~ʹ)A ڪ(q>ݰV=GK[_apboW)LTȝA$%8!]鴛عm%YyGP'lYgg=_)T 4VUs9P^8/;B/Żj dʽj Vr&J)nqWԚARc}͛7?V-CCԉ=^zE6lٲ?sLOMqqbYv^mweF6S'xIv iF1Y~*$ CCCL^?>{>r0I^P뜏zw}gq*NZi&4MmnDtwRHEYTچט0EꧥpQ"s)ZZW41_=Q^PpJk\Rn7RIUfMs+UCi[d/wbdHVy'V [{ż[yx9s v }i~Y˚ ZC/ߴG&~dBlK20o`fzknlu0PQLn\ą6Y^%"wL'(ҫ/kx?Nǎ9p=ݡ./EMóף_&Hpw;xhC1ڰifύs%nJ#7}ٵkX쾽m[Y~'OBkŭNd[V괙]O%~7풥Y.X0 BuAj+pJgm7Ij":1iԗjDy@裢JHt\ " LJW&V%*@@'Q.xIKK=w\ 4-YϺ"3 A)TUWSx򩧱1/qZ<(%(ByWAVG[v|^4Tp>ZPq+<>u4z"M殻<6 ~_:6l>i&ΏHs9 ^)'͔fh#A?e=ɗ xh{1:j6lS`?8?u{}mbW1{˜>~"<~ѥyZeSM @XRkI J&ϓ9v[\C#mpۜ>}Q:C}9N?N?cM4;WvV c?A@kk.&&&8t ~ť֯OcɒyQaF{އIRWJ]ErZ344Dwo/)v'"eܫV0ZrM۪8dۯ|04:Ym:feB[1q8 (4J5ч冯jlYya>Ւ> zyjy]& M(˒+s1jkw$.^WeY{K\.w<9I&Fe(OհV),*Ph䃑*]Oh6s8C\x_RE)D Ѣje 0P Q,,γdY?(qD+ӗ9L8wģ/]K&(C;N9=  ڬ߸v]kwlJց\9l.>~o6}ceg&: "GjV 7ɋ\t͛62fl0ܪo/2Ņpabщ 瘛[dhh8ǘh]*EK./7ӧ8<3WڬY^}eIZ&/_رc(f6Ї=tbj&USoEKa~  "K&<7K8us\y pW]땬`{O>EKVگrLl'HXT )PJIX6u:n]UΡ%M96N%}qqaA[KubQ^hHQ.u>?^EUYjCC4kW@7BU4߸@$!~~nظoGU1 A:k!467ZBc/b}b-jд@6 IʦMp펝 &M ~|~qI:N$sx\&ťERc0NRE \X7E))\DƠ`z2&Ο=&tZ3:Ff${:d,.-EZcz8Ie6KW&{SC}VPFE6 $4pڣ*{ѤqYE,ZVhUFFiy/>W+%VHRQ\ij_h)ʒ6(ʜ%I,\I? B 6p!yi>༃hENF@3[2BAI_"|&'R'knݡC}ݻyߛ;zF#Ú z}!"y/{f_ĄĦ"Ůc噝cIm/O,&&^=~gnn>ctC8W]>С8~˓X\\x_5t0iJfz 6aM\svW8kȮ\X[&i:bi*z/Cӿ҇^5rP:},K(:<]>pM(KA I JT5W%UЉ&;nQc/ŭ(65/P帲,t/Z#t˒•B&NԖ,juB"x߇IRe^ EyT@qM{2w~~yFGG񖛘2Aދ1J7 H#k<մZM$tģc:<(}e£˒qɟUțM I##kdܸck^Y3?/2qXI A,@΋~$TZVzG9q83Wؼ opަj2tqwN8g7N\fzvW 1zDh9zgy}q)8#G8~'Ӝ?ʼn zy9Dt $ݪUmF[|zW:ZFg= 2aU[٣]^ͯ0\/f_j3W?\l4i6Qʫ润k]}eb I^u qE42L76:u Йh:d"!b+ ܘ#_K91\&hc(9&J25*ԳNM˲$4MkBQk ܉m eQ_YK@ 9~%.AaH(giiM6ʫrܹw gIBш&O@I #^D_!vz* t|Ip! VdSĝİyf_cP~]Y?yf{9HsyQRtH"$]?/a^*ĨFU9 Z҅L\8pn=1y]'?{]SS,pe06$I|pϝ_:Pw~crlܰE%Ξ;rabk36:[O]{L Aǀ*)QVY§xW ;mz}4MZw}, ԶdZWDne\jc@ջb)*~?ĈaIד >D)ZLhb<OPCrᜣNCev/ i"yq h#l܂+]Hd\srݝ'1&gHX9(JXs}RY z̲i&vチqP((9{>84scI4IoީܷT-P(f<DEh23bEیFƍ}Msz[?:'N;4h+҉THiJ{A*SRRE35ygN%77N/gp~SyK&/sp_yG 1Klw4~PJSN֚E O)cs!&.N`[n{e [=!8Jsk)YELSISP*H#`bZ&wB~~ibB`0ys?w^t]џ;_e"~96U*WE*7H P~Uz&>~Xge3(cB•b Z~T/Jy %D4E% ,z]Cou4)V.eA?&$;W*CףS9 Գ("+eɚQ{̬XFO| N3鸳 ^`~QT:kܜ!KB|Rmę/6l-ܤ TqM7_2=gUڝ&ZYh5'M eYn5bEJQ22E՛9s%&8},?ЪaVf.|~38?$/{eS3}ysgN)TщmdJMR5p_$ EP:тJ~JW8c'K,o믿-{!y_Quqwp)Uxs 􋒥~AVrR> hE'?DD+x!^a Ug@84y?Mpn5_(k׎2??G#m|IY:~GדN?~4f|-KGj+K ={g125ckqjWj9?~ Ǐ;wy)%8)ybr}< wgqnBDsڧb5?; H؈dog]e |bOFH`ŊNEشiN>Ç LeBs3qd9.Gܳٳ暫$ J:KG,I*|+8.cV~ IDAT"ZƐ9JR > >߿V8!F>_>n%KS)A+|pV,r+ Xɑ;I9Dpo p4 q[1cdYF{eY@EҰ…޻XFmcWdΡ2gN&A P`PF>:Zbxx۩SXr%v@Ny _Z-aÆ xȠȵ ,CI hl r8c`Is~G[Cs<E 蚷<ϑe['!jc.h λqfj<$;PJCy1_42u7"$,+uqI=A\]SG0;ws"(JuT)Z{1|aagϭvH+V† fP.ѣGڵk8شe "G2 &.+]!o/>i h6x{ރ7a@RAcde[0dX 4/[p}kʂo68}$>OarjF2C 3,z+]!< yƇa5> z>w q}Lx6R"rdH枧*p8`FV @(L+(g*'([]КL3`ldKYjaՊ1\zNъiνѨy{IBlS[ J+%InH`E9c$odިGΓArPY!c$Iz+w]wyD/`f?O]b]D21@eXCTB\i[BZDEiX`bݳx'0;;|.ٱcݿbffMOcai szcccq^[&t'3n{+mڌNKEW4J% :z(yLNL`E77﹕\ ryx9ٔ Vto1cQryp 8s k_ jP{[VgxSkya#X8Hs&O~79FFFE( Ot+yE@3*Iܞ7"6g+k\DX@e v9=B^ %r⥀^C.9 Hlas$|q {Hi,"!)Lnӽz2X#@irH;fߏ= )P')i* 7hus@A+邔(͢d wtMHV`3u#wN~nw kpMoO|S(Wj0&~2F*!H$*%TtF03`@兀s;O k׮;n t-ka~yNe835aO;g&0s,ZK QQ 5HR#I 5`ݺqŮbdJkZ8~84ŦM 8p, 7ވoQX>s&\?IG/^C;i/P6=cKwKq1\qxߎK/ x硭ΝU,][SGvXh 51??{>h4(%dY X,kQnsZ~e N.D$NJǜ7.HN*@sXEK1 pe)5,\O>X4.qõLq(Fx;0FdkeV p AZc~q[lƚ5kikZ#4ju<裮"R QS΀!3"ttmG\Rs+sAx'Jb\uX ߥ޽/wݿj 8%EHZ Z Q$7uZؔX6h|&G'λjժXS~sg\s9t:-(kP)U022jD@Бq),̞GEرc6lnn XZZհ/}Ap&sN\~ <KkɬSHÀ \|_o_ꫯ?RB >%Ϝ!S_C^Cߏ|333Y1 xԗ(D=rѱϛiy?ssD?%+c #C3*=\C:c",, Ӹ0@,%T&Z7`X[pA6d: ar(N^ɲ IX gP|qHd>N Sן=ю  3Zˡs )< `MA|IرyF_FwlR)Ɖ0>>Gx3h[Xjw]0(@H׿{&l61:Y gEn[ aeEAˮI)a  > Y͒=wtN7ɕs$ )8ODY :q\ϝbɇeY $t?krLoQ0Rhkɭ,`a+~ '#%1c\*!9$b\ _F6B"SH 4G#rX!#hR#ma[b&pV RkAiEnpWO?4C11-Yjr)&rN\0G*(EэGg>g=x[ވZIllZCE?ImΌΝCɪthxK5:Q8r}Zv؁-۷sǾ(Μ91l޺ pȄBA.ZW cVSEHg`\7Kp2`b@Y5kր;Օ+Wc֭[QkGŧ>)|_ 4p}a|4㈓{oҁyHm Z Z<裸q!$q+WD>֧1JkD2Bĉxf9r196aqA6.>sid{ͱ 'Mg`1 RndeE&3.ʓLPg-G,"@fh?M3sC )֯l:|^K^_kQ;5>RI j /tv vyE̜GPUqm^g<(v6$a')84 $G9)cii 7_2^:tg&qnySS1>~ ?ԟcj FG $w?Ӕ$$+=qMq;MGd9dυ˭7e12J?3bo:N7(hK@ѱƩ'c̜$-w(ՆZ O%1[K9W|o-3ю/`lb9U gu`l>^̰mf$2U`0 X1hM 3Ȟ <ǙtIj I*JH[ G\Za׮O2#M _/<?RH)ip dA 2 W7e.C-\xDZ05AZ[.? eѭkLLؙSQJ#%rӇpߺ!lٲׯR>;^ V^a .TpcYr$rl.blnO>$/ѣhZXv- q`adlJWSxxb8a8pg=xݕW!rJszp\ȈHlbbbgO~'OBZFkMϪ}Ϻ89L_r r!])E[iS^p:ށOϽx>)8]Da,% wHx2EDN\ =]ȕX^iJ7Fy0]oó1tƿu6< GiM&g7o1iN9 uysZO?4gJpCo "p͂A Xpr<8~_CEIZݻ[.?|TJ=ˢ @9ɚv0#"9>+iil Ԅ (J^:#GN8+eB]5QZBCc > '`ipo% &~uq,$Hs]/3kI||o&T Np.Q.(Wjh6j!M*sBT_*E $}N)%*֬Y;ކoz"BǏ+a-p)ܳpf4.\.122ciahhyAeIUAbv)>|k֭ŖPBvD1}[&%'oUhcghZ˸i-sgzY?zX\\32%@Lyc`IUC[oF+U|[߂0rkqM7n{.^VիW둓_[N N[^gW|'N@9ѡq }!0RʝBk *‰5ZQTxoƓ_FK&#JA:$zwA|`߯⑿(¹ÅHKP/K_"1׆]ޭa\BJ/KܚCsH8Ma*̡pv 'gIHMζ2oJT(1VC;4874Y ׈*Vc5GE}Iˠ`"?NS@1HJ2I1d7;!%_p"9~f#X(4~dW8 ZeA9j:]|1"4ĪY>x1s^(1V\J\15Np{?ѓO`"`tkB$ ؼu vn9ef>s?buǿ?z 0E@RrLLabe#Ip8>gs!I\rgފm۶A)H } 0AR=dclJ(E{g!y u1Έ1@i0!)[jmy8(Zֺ&$4DK 5'{[U C^,10q,LM{$ IDAT`x?rQˀ&]1h2'8vB JteRyp' 8wzgwfȿ V }sN:z߫ T~!D*'|B_͛qCq[mh+2 N ]͂|uh %9:5GkW=TZf `iQe.J*tz`h( ,`<A{sDRBpzr_qƻpŕ(}\+|0:m_z N>V4Mn)K@ҭht]hMQ.AMk2I;v;6l޼VۢRdYTEȨ Z dGhM$Ixz022^\u;q]o;/'jȨ *$rRG//wC#03EliѿVUBJEĥ[YXD2F$"\i` yV4͛rxŢ!n!%$xDҹ*rp }uE/,.WF$N LGOH!f{PJ9~^*Z\8xDš/:'?" Ar$ 1c0NKnC"Ir$bT*_=ކewɯ}kܷgC/ET2@2x<: 7Jp [{]moy3MBYarc`7O6c 1 ILMMaը5o|y{nzmXkQ.q`Xq#UQR'yx9*%(8q^矁8j*u\Br*%4MhC`3ƙQXҜ2aDә e&t͸]Bp_ni^__vXlacW@T6?I 1q@"|:;;[lٸ V&Zax e1F!M{nE^8<-W~Cظe+ !i=8FRo|a6C#0Vh#E_Ox+ְV|O}JC%h/,iV _Xj+~0`ffS'O;|#KKKKp%`Æj*kd!3h9/`qiV yCF ­`ܖi*FϟR ;v@lA!$,gAmTJejT.L9|_Ŷ`tt uHqɥ.NCQ\:65_X'sU)!ϳ@'#F,E]%KNo qpd`Rc-4"I7yjĒfƝ@eogkMCyG&ҡ+,E%дxO SF;(E &ZXCnZ+Ho:`VZ+p\*xX#*){d.~/( I.gT)QYo I"Tk5 Jc 6oތnigyY3϶5:8$FP!eBN,4(r4(7K y tUQ`sI^(ί9~ef,%LTk E]F4vK!#5:.ZmtbV_ +o4`T8<}-8vȅI"yR3q׾78Sx:\~/<;.M7ߌ>0nu/ W_{-]ZeRW5y/}8ۇ$IPV}]xpD n rD<>GdzNP!"4Вҹ B3dqQFV@&wB`L{c!D 0g]0c<p<#*C)NB~.<9hU "XD$Ax:LtXl0yz/<Ξ=ѱa4(z sA9! n[1'xϝɣGcG?233Ej\ga =jm,Ρj#S9nHV`ʕv;Xr^Nq$1 }^ͩ NT*abbqlܲ ׯGu`^9z=s砵Ek:ص #CÈm۱rjG.MZw_wy1xL4!y5*e(E2XUˈ!z9NYGqDZs\/vdM YΒɑ߳cπ!LF?.7F$/| ,H>7,|o](yשhB92pJXo#(o0nxM`zJQlsK-˫/NZk(kLX ^k QL+&{Ch@Y0S$>o-kd0 *oA39־7A[x?gSt ֨tƄ ar(\V68I 7o;P+WE̞j9Ȝ"hzWbƍeBd=gfPy޺\Ҩ.( ׿F墿x9> gQV+ }TA^FR*-Wq!l`\ 8u\uq;$I2@Db+>38y$;3ӘDKa T2qkd)* 6n܈;/e;_!"' 0XZ\Ԕ9NVniݦBBaҀ47]$cp9LLL%:՚CM AFَ YΉ xnŞ1fg}clt_ZЀHoXo\ x'ڇ{ϠTPu-&Te(B}z6XLs8j@"s!3E+oFKg/׆Xk%$]o*$0J<$.9a\>ʧkBC)%z='ֆE9`5{9>D_h} l_u KQLW Fpn^ ^ATJBnCej:;_/cv~.c062 EJ3Ibk0bA W p144XZ.S#]w1 OT8}NS!)E8tGUYC lJ2RqLWxs&\{, 5QDs k2hÃA y؛B %ꅃFd >@ձzo\htAt-cNúի/6~F09e tc'N:5lټju؅}/RTn x[墿a_[6>???jձviXhШ^ ڳn7Vn.aI))JSOdRD[{n,-K/ı#8s nzWHD.<2AͰi}0=2arE(K,(`Kt?#&7i@/3v;L "mr#:B9 vAqغX蠋g<]j}g8?ѝOR04ku};.#H_{3kЇ~?(C#Cضus(!Ba)gE?cTUr_~Hp2 }{G?y #ÐQ!%GR*:`9ҔR4M4(E+D2")KX8D "EuX!U)'q)C;CVCT0&CR k׮Ŗm]Waڵ?[Oi3Sv4igngIvv;qt`SG0< ]h,%[E3I,B`X1kc$wQ*(+_{o_+VX =@Z;#㡇bld }) X&8Erc f}?@q:dmiHV(i V0 ߅S7/h!8^ &E0):冚,Pb𨿷|χ)^ Z k&CQ ӿ8'TC2 R(! Myp㳜TJ@ 1Ng/-aPfCf7pxw7fw@aH29GR)׿-,Cz(I J?כ$e)MXqw 墿Z ^?|F }2:*F)GheN^Z9cךTcp.:\FмQ!SHXr+si3pke*ٹJW.SH?pxS7mt[_=nzP5j^=ZHJ4Mq~=}4Auhw;t:vH4k]Ʃ"#n >YwVi{ymw} IDAT1(תkհAzTb8q _Z$6eRɓ?1]+\-6c ava/N/m&R^yn&^/L*nD]lɱ9w5rOb ~TOW&y T*8n|#o-B+ r &Oa!9,Sk?o t<V8ci#g rܙ {q9MRhoM0r(Q`Wd{C>OLJM?2*Lp/Xk!"&toqL TrKZmzyXݒy'(ɠHK4C lK[8膡5c,ψr2NpX!` >߃}3@} r.C?[`wւI׊9=(Dl(_2JS(>ODF B\cos + SG1ছnƒ_1\PְayP&*2j5*l,XK NlkObgXl`4j/n[I)r*pyW\ǤJS4j&uN9&NƩ'`j ֬;nUH\T)xc<ϱ8{W&''dvvNw}ehPJH(@Ktmu?PŽO4P+%} i&ЪUp4[K+isfƖM[9G/M rSR0A+׈ḱ9rκԿ.9RD}9`&y,$!ΧN*CnA2N#\3! Z( Z{ 1{ ͮtO\13A(S%)dݣȶ*r9NRI(N8/y0)d(eW.NboyQe9J .3vs+k}#*f,Qݧ13}zdYJ.8\PLF*ąߧ/\{+`JP%Vm\|A=)e'奥!~?,Xԑ÷ipxxȷѴslmma8nn1Nauk/޺wxћvx$;/wdS@Nٿ>Zc0MDB۶El=i@k;#%Kxgq.?1W޺wwGE۶nVc楳I n֗Bf>^ @L-m ~.wYk&sg` pw{KVǘ1Ν][x'0 BS 2;]KR1";Bvy =59 ıڋpL&DyͭGQTC ΑA,+th`!c-75$CY}WiAHU! [-{,d h[fLK#D/ډ3c0Xz1MykGH] +Xgi5BD[[^AQTp^'(zc+7~W7[03#kaNp]h778pr5*hr`;p8ļ·Q#|W ,wdgye05u),K!RVg v%++DY*Tnݺ/-om^Oa{{L Ymp4b2mYW$PODݮ>ٹR7)z)4 >"B ĝY8UxX0p09.x'at:{&'Yc<[Hqjs Ƹ1MrPɒNDwc "xQ.%{rhQU۝}0"[S8-ȆߊC%r;-bpΡ0jX3z|kA;Z&(>d r؂8e Bb);'"nY)Hmb*I[@9Dw韜"IaÙ>aus~}I+~hO$ CgE!`P%q䢮H;ߚeJ,KZYsOoe99Ɵwå~/;x _/ʈmegQJ|,"BV4'p%b}!666pzseYb4_@DP ZA@y7=-[:}ܾ};O 670^]@K<#y&Ef'S\~Ծ~T99k`kLŚɀge&fQ.}Qb C ":]IcpCm5 {r`t`&<`#0G8:zĚ^VuxpzvWlv!^-@&bK xItT#*tEXS6b˓d,POڊ'ݒrPp'0KJU_sN&)a88g=GY(M 1 dťPD!}&4zBK ,=+*1iEۡ+0)M|uYX 0{ ֱȪ >FX> J Hq!'zC NN"WW!#~QXpkz&,Érx8p8ֹxcAx~ROostp|䣯ۿͿGF//{L 299oѾ&ܹ%V0k>kP*Ύg}T ҍCD&S&t'Y,<7fتD#2?Nfsʿg?SWvLB;YS |)b7 KaCB^H;xT#d$,$L2Wi-VWWewBd6 a{[S 01f zt" B`2NT@r/w9"** K) Aȱ!pU߆pFH N@b9:Q¼.Nrs rS Qr씪o`֓C@]g;-eXh*^dۢYu$*K@LEȗH_eSƗ/Vd [ _XA=` badP_OM ȢNȡ'9%DmCɹ 骁 oJNDTJh Šh0O>_~:|RO?'u` ]>wO,/ǩ5 Cԍ}u [x0u1ayy(=Jia`2۬F~On›gQ]-m `әa(ư0CJlZb2.O&{e$KWy,M+i?*)qPuv,F @&)MEf4ĕKڍ1, Gs.;mƤJqBba6zȺ0F.>AtchundJ$kD5uKm lQ {ڷ%T s`` DD4j5E@^s au> DF_e^_rYO4>:-ncF1c Bd ?/sTGA#{$#0{$]A"XZP.')޹[қt$l͞{ۣLZ2(4iu$Δ{sF C% hIWB .ͪaʢ|1޴ cE ce*(`+i!xղ2N;h,`K{J E !"+gzH.}zpE){VEjuU?DmoIqm"8Y$;V ! .5/?)#ţ(re)Qn 10o ʤ C< Uv֔.t}UG ^(~ 90rgMSsWHٴ/" ~Hپ'1}"h%ٓ]3@6bOvU5//3 >W ߵ,oEY"hrյUQ B@TJt}sTU-lllH@P"{qvXWXQN&nDK,#ef4)ݾY#q6ȯwx;yL&=<< ɑl&)΢%ک#m/XK龪Y<ؒݗ(yJD RJLjW<}ډYCh[`&\qK1k W.?" `g61nmy.$pʠh$ؠ!KAJ|H_AQv'@]Cn@!e/"@ sA$$ѢsgH1 9>94a6c?j2X䵏< 3!ZCF>c`n$ I̱N]>r޳IpߣW({0%ޥZ]p祿3\poBԉ#" "RcFB42TNqzqxKbՓɨtI.e1)ǀur >k]!sROH#^į7{Z{{{?q}YUr( nߺ+.\S ';15°{ \sa0/@3KD?9a`{CSH5~OOO޼~cpmptt1OQi4#%2BVJp]YlDL*}♽%y{PȈFlzQuJw4@[7 "x>o&#l9; ɭgHpmOQ-]zPߴSVM(-O) VBV>Ok0%ǙL>I|ryH"zտW`d!CѯyB:&S*L|ߊN!=;e g,` ,@BDEı ۷? s^^j{1bQ`!YĖrzgLݲQt8kAЧQOYfD4΀MVOmp'Y& A7"`0`8bP`&eÇ_|% =$>)'wEןhS8<ڗ f1#>-o0,KMn @Q9ܹs;;;(}QiF5oggwlnմs̰~j X^^Ζo=3,--m??ؕnݺ|m+>򛙌0s4S@klu_itǼŸJғxiM{oaRr;8Cy}{.ܚxGh<^[z+888ʶ$KVTd_tduuBJ9QUnFt:̈́c6l(a*>Pd*BDD]鸣E0S>2_rzg#+Dʼn(D@*{h " M 8AC HNR' !y}0sL`p0x!=NÏ;6z_K꽻ƽLzR!']1 ,Xg)$b\0I/&ٖ+tʭ!%}Kꥆtlf3ܿehIԽ(PԭJIc|WOqz&ȏ>}ĠkDU9l0%066P8Y7`w>Nol#aMmq-ʸыéMlnmԩSc^<3vwwF}` ή{~~gK/-1̅7d?(ųV6DeH#֡2y!L|xxď.xQ#^An2(&Id}{zb^.#G/m[}2ƣ%M||wW>"ڃ 0`5%Nbv%(-=7DD_^AFRl%)^?zgZa3v1>v@EE)11P llksgΜ^A:)'wS֖0&vi߶->VWWqYI = ppx7n"zư$"Skp\=2m}=lY amd:/G?3?g>_NWcz)PBӢArYV+|]B` /a r?{1q0(!%غ#D8٩ "LЏMjg YQkW|dAY=/ 8ږf=.H!HDE7q6Z L6$x2UEو.), }2r ${zӅi3u#1Х: @"Mg\r9 ;m/OAߧm X,-  <wA;"@dX*6`A -l|ȫZ#TZ]!Y.iHܔh0!.Ui`@Vu٪G[>P5&= k/.#|De+ܾ <Rb#,1WPZz /}U--f{珬Vh8cd;*UWUy̌;L&X^YéLScLSuu2Ǹx"6776` b*ddYsllg,~]'S=[f>hS~Z3Ms^b .)Ll IDAT7x9b^2'6 z=qοO4a~ILF:U+SON`w;g";=bg-Y#R1w5͐Lvk|kYS#t0^>c6 u$!QR> H^d6DF<ڦɗ  [uo<"B:ԽY;Fl7bdBt-RX@L#ćE@җQ7.ODV=~>eCQ}u&A㏩>O]c6 i7j;ʕȪR@;Iq2B<0$Vv`޾t k gΜٳgB({L~%%!NA+/??>#ݾwoY=|ޠiw8e8(KBMT8\c1;r }sOiy15N\N~_P@u;ǥCUּrz $F٧f76-o`}΢m[`ii?{`k/7IQ&=ge}H z!F>(DdZi\)eBjB%#t8H^H _ WU<ˠSB#q$DX1r% 1$}B:$Eg@T+Fm$iI]x8BL#y!_e9iX9r(S,qc'?IO>&>)'Ec@ǧǚ0 Z 屓Ҷ-ښ8A4p76QQNxvw+6xS7 ~^{x㍷d%0WZ9BOgz?[ {Qa>yOȣ;؅@(6dC'JJbP-FiڏM6&d^B1+S6颖i.uWqC|REf\v+tKKV D{D)t7u)]8$&y,j2+A}҄)ڤ0q=8FlYL@ c:*N"ms' H12^j!0oP8)#r,y܂S,N͘ N[ڼH_ O OEeOV ]ː.[R'"N;`aN 匈[:Gwy1,Ӕ@1EߧiANrc hBİ7䏁Օ1pԩ-ȋ/O~8<xC:ְ( PVgL)77TPD`6uf[[[s Fowlcw>QTKhvpxxW^?c{> wp67‡u=Ged5LN #bvS*!49К&`n!vOQ)U.A-`5%E>gTY#_/hQEŰD4MFl00yex|nVY9ar!2W5%~ޝlBB yrТEY4ⷽp452ϔċbW˅hz] j+ZyM\~ R~/tЧKd,坋A'BmUK_z aM={UUO}Sxcp'E NZڥ9c IWg"!FY9hI=oqtt8= WaVa(`2C^`EQ|G?ß}W_Ew0 Y#߽$a êPqR!pcOdB?}VO:2ݮ5yoz,h'l) Yn `«QUY$ Y%ѹE>zCዿp[xǰ{q]A390EYk1.yucU )QO)& cW1†(O9S дk=)׍YԚ$裌sd ]VB[5Ւ) 6 5E EH^yww,Q%40$E;D? wa">2!Oo_3a1z^86O(%^˩ﭯR޽\tS^FW,Xi)|0X__/accilhӧN?8u %f(ZmCNoO>?7.]MpUUl5vpOy9|݈ڶ,;UF") Rz]zR;-F=dG,Hu`*Ko [̧7^~ꅐI5=;S>u u$42=?7oG.c:h:7| ++X-#xƠ -D{̬I牎XneZдֶ:0k2‘CkY-BC0Q(|emXp7kA, "`("Ƥge:yd*3w.,R@#"c&'K'6 Mm>q!{B<ɅӅ\Y&a,qί30- %ր ´!pD96Ns=חǫzxRhX6bcgwwヒ%cee%j)NvؽR'ը+"/>4n封۹fTlgǰ[Hf!,r^I$|\ CG7Saq!pT(.@PdW^d:}LS?{7nܸG\t:[YA wal.,d'b 'ݪѳb6F;-Dfɂ(JD6!r~_꺖.O '*.uIK$۶0%2" -fP{ (t11 du;ҡqjg?k`&F6VEZQ*cQb /MΜ^1u5BHӇdB܅8؂5blT+|$]B5XFfTPd 0m#]75ll_OO>D?<:6771kj KDa0F5Js u]c} bt̹/h]רIK /bii gΜݻknm™-^A^.$7D 8";{9#u#žXǂ!G3s7Fė/ qzf2s7D#sCDOd<8 ~= ^[ǽ;v:V.K彻,kc a1C{e;MKY; Cuf )Z9:C#6V*L&k<Ʊe)"峿f(GD-ڃ8…K_4`6mqMƃ{2.\s[g0sp\~o.uo`ǚpJtj:&݉J\|j,K[;ZH2p%+yh9f{] .]'/CFaA"M4 C1غ826Rtv@ƣ1G/7&& GSẃ-uI(H,65 X2hh:z-uܻ4D/+$#yFR`\E{k*`82:#| _|6//şG!"XA[ʼ3ce$Q ٲ,1PY'dfYHNX;/]Xk)޿ut2`XǯʕǰT-j㋗/a\v 7nlӧOc8X+x": 2Q=#il:r }aR`U .HV .>Z͉WST.sD>3Va`cM/^ĭ[wpޞ޻x o1* TE!MZl[ªrEy/ɢ1!$^_Y%b+Bc)$GI_~o mx**dQ:J&>f5lJ((s!9flXOHO } @jz~zF-*]&l/Ȳ[I";LדQXb{gK viIDDooeLSOMJRȋK#oOՄ/x饗O<43|W>j)Cܹs[;9BY XF#,F8uBlMF>{u=!`{{on޾X^٧¥ A)jTu_>ڵ7\Z`X.2uT\8N)Eҷ"Jn*ڝr4uũvzID`K Zأؤ [8֡կs™z#sp)hbs6`:n;wd 9UOs 8`MB0G)O$YS0 "lD)E +|..ie/鹿\ehP8H[|ߓ#FP2xI to% Gi#n")HPaVeK~"I3:$N4EgRi F&mH+/]ZS^3g`uuUę,q|SG ;><\=ɛnp"4mq*\tIv޽~©6Mhg .]5ܺs7ohYM-#*h{pht⼤ȓD?HB̅ԇ|7=Q^ýq{QMZw%YBг'3Is(y}Z($+JӂtH^*YÝ)ӥB<]HNR@R"BHy$'-jsKK8{%LO<^)54''E jaPL20<yt^gHxhKAs.]ڦunҡΕka!u'-اOp8`o{ Q.ЭF¢)H'IC=X`~gJe~"Ƕtq.wYy:=Y&GFGXbB;U/G]&Yn9_y@IvBY`yΝ{Z?tC\~^~ Ԡ%lYeCbanX-c 0: J1VG,ؤOSJJg /N/oAZrY $"@}2Y$YR S1$ôV>g_y$hE."屃^\NU7u؈wa/yLwʗ.ϞrFO!;=|nWD"96 o)A}:yy|/D+±+T/x9Cslnn>tmc` WLO)۫ IDAT%Wm2S o0 Gp`ec HjBφ +`xq\h rR\IJǑ `8y0 %d4 ɤ dP)A`M c^R )' ЛIY~:tVlS*޿w3-n`ݥG 7 UQm.lDDrV Qp Sms A:յ!}N(pӋg4jE:3$ga`(VHbKGɴȱIej47w==RCftcӄ$I$h95 )GY[U ?AcwLvs|vR?ވ>,]%67/?Hhbi.'E?1Fjqe @ GBx{yyaeeE)[ĴB}4ML t4,0to:D,2 P4k^tMB!k3Fx뭷AUUfpA?;j.9PbSG SC¨V`(lVGCd2ER BUCj;"wG?#$,k%G~6I 6 Y+]m3Rd K8B6X__x4t2amc]|Md5KR(J2=mTQt gHM?)Ʌd 9){ b2hЂ ?xq}C S˸7' Œ`tɔ@/MZb$EZ\-%t֪E.q+^$1{T*uYsN"^/">ʫ֝c ·j~u'EcCUЍ+R}D$ X/c27"t?a!|`ᣌ#J.xhm.ٳ :n{rn[Ak֠xi<4]c VWVwt+ߋ^d Nd*TN H40G B^iFucrIm L~"r\d9ıc0*i!О7 Dhdwŋ888Vqttnܸ!ѵeլq(rВ`#}L4;I *]+P( K!佾= !3 ы>P8Z2MAK E&iEz%Dm,q;iȐF:(e Q2_* Kp@\n\5$C}G|.?tS)`~;+II :yc{|a|>_US?؅!tK=T*WdN*\X,C>o 'a6S%AjZ3G(WȂMx%:~?>ߏfM"E!MqeuFQ 2qg۶ kH/x%L- a68M%0' _3|h(Eek N>Muo1yFeuj†P6p!x(6g5p{{h|Š-ps4Μ^Ci3{F6:'+kYt}]˜OIDԥa^u~?J1G.hC򩘪خH$Y Y$ƿE3(v7HdtxLk DWÁat)T?O>$>OӅI):y杛z 1V L@JԩSw:u* N`Y#[pmb&]$`$Z,P8󓄵䛽4xE %d? !\K(Y~l  0=Cr'7ʗ>0G)(dh ε PrG\d!ـsN.q^]nIuBa*6-EV K!Y+ALȰZ(Bx"^u|z MI :y3c8OO_-+`6G {|!=)6 FKbwwKKK/{okYvs7WCWuM]j&T7&{ Y|H$H>DbqI [0vBP e*vdXp@"[HQ]5z9{ʇ>VSKH#]z﬽qr#Du>(GЙEʍ0@p*Ѣ]Xڭ;7]+}Eq8R1FΝ;Z-n6n4m\wwb"q"=m=]RuEQt#Ѥh3 uQ!~LfRQ/+ǂmh=t$8( bdQB1Fm#b:8L3`h/^$|1ͷp>B⸐(EQx \w}+W8)Nqo\jNNza).o-BWCC@'v"#EVt`4O k/c~o H ^%o"0G@Qg\&. 'ƘQICݳPu逶_|/}#TUåҵ*O}cKݻ__8\gBk>&"$rBkR;Z8Ei1v}oVr3!@脇w왖9k+0-DA&2 ܄R wޅRU"RF?\,R !F#<-ciE7OD+ Uh.BNv,)BB]߶G>@S\6@%Vh{;w Z6mN)bQ8-eW{f3ܺ}(\-#`}֠@u⣗:&2xIjXmO]|HP$sݳ11{!edl}M"+N#rF.v9xZ9sBFƥ4EPYٯDS!ab.JPq$bp/daB}'dxG?qY*Pn> RC(" {IШ:[M=3-777lm a`125(Qxcx/;X,X5P.! (FoY$4 {ppЉz֫e^HW9,r1)ԻL`.MO¼'i'(ۺ<7=.x|#e˛. B#`ϩm  "ԴnU*!X=Fk8{m?H68>Jb{-4E  ly=AYyJ@.NwcssѺԭ.$ڜMϫ-N:}]y;|/BCV c"9=v_>|nׯ5yX-GoE@#?"Cˮē3%zw}Sz_ f"yz;5?B Z/x/⣗)>6z"{bԿ*˕N677sXkaBsƣu4MS ](Snݺݝ3;Z4|EB Ұ AU!D4u1 )Wm3`\ ,ؓ@PCkyxkQjqQ[bvR),]6%+5`tÈe]BBzͣlc˓pR (3-0#Bkjgٷ.Esr:kj'r K籨'8=5M밶^"I^ܻA]\_׮<8::·zGǧ! bȇź8<:Ck% +9H! dڇ(ӑ{"\UCΨx_Gk4 YD[TJ 'o! Yxh%-"Q|%'| rhH$$ ILJ{Oveׯ_+~ O>$%=ĻjV?Cu|у CC,tw#`mʻ񷒴 "|S9Y=)HcX0Jv-S( %s[d7`i xZ`8{,b>d*4IΪhrthRw"L㐤.} 'b5,*T^O 3Oׯ=AP`scܺwnA6(k8rQTGXhPgzE}!9'Y-26KjaNmfd P2اKwRQF'yO9ƀ Ff-P"}6ăX`p^$/pEO hbC }ҧxq| /@ ߵU_]ߕ>BmZP1ܾb}ĝBn89~Z;դb[GR/D3pvwDE.}⪓|:[a S(cǬL(tq6M# ._o}mٺXxwHyfK8;g$FgѕA)x{9*?/,9)*^(D "HhƓ {J(Ϻ D(*p'Yũkacc{{{(UZkAx2pȪ19mk2`w `2q`U+m[ .^7oAkRS׿CA༰)w6xœ P;tߣoj-T(X vK7\F.%T$t"Lit7 5MhC7;1N 񛿉r~ kkkZ ljZ`2}uD.EbXdG.bscC]ɻ=K2u!,!S; sYcoIvqa!eHKH )"A)( H+Ze Jw <9 oR^}JO8'Q*0>k/=~^S寊񯯯?#>Xk-{tt . AQ(5.Z{zۚ#s1 4}XB{7`1z Š--ƍ7p|| ,Bd(u'Ǔ 9:V)8::ReƖ:``VXBVe;G9[ΕLS Q3=<4@ݠ q6p^-tåT+5h6x#P 188k{,0_,}@Z !%1Cz>&4OE/,}ɍ9A}fR< H_C+ł jTRw$;]$ s@g}ÑЩac"he'LӁӠѶ-\O~xd0U_]X1c.]|&g IDATyk]t:Yw+Ng2GǦPd sl .@vQ:8]T Xm>sc|#7;;M\$wG]ۃ&zFhCy~||=lo[f $: a}]N VIŷocCH;Y 貀;}>s:_5R3R7A5<\PBCSaUcl{UasCy< 5CĊX׵0u \HXt2wcEdMC)[ʍh7-{R}Z |p,ʃS#")(|8ts.)B8eXޕ?#yHf}_:Fah!6?4*IDN737|a[`^}UKTAu*뻦]GP FN(+m}` MPiTIPt];8DbbPaw.H( @F%`(m\tϟoo֭[R ^LXXٹNն-nyW._.Cڳ*jhIx5 ٣MF2$#>ySƼ.%c O9 lp\q! L E1JZ]Rf<"Fb40h%8q1X'A GFs E2Fq4BK(fhYF88:Da*hU!?X[_gKAF`C= |(@wQPןuA(N'! d\dڻ8/<)}F'tODnX ~%'Y6x<ƫ| / mllsSL]K'>C??&|'>`U6bQRln (t3.9 [[[=q¥R Y@(|kK/}ff48 Lt bM@zG⤯y Cw=t$;l'6~uL3ih h9S Ѵmμ>n K\v ZԖ ucƈ!<^qM3F.Ұ p۶-4dJ!Z)Zi,se20{E%^8sCvZ<6- ޠ( ĆCh6w wpW6[J%䉷= x= A 3|VM]X[c}JT 8ۚpI<1> lR:l9ηIa QVkq$xw<Шz5Zt/L|b̳h 1mD$v&.(ã4 $8y.{9R\>D^¼w 4K<}SГbHZkhvպqEx&TK+յ*{=K׾S]0ē}pw d.>h=R1 /ױj4Q)(E}Cǿ%; s8>9ZwT6n:666üO!c,S02GamʦAARQ|-)>z4uRL9ݺ`4M+Z(e`-bڶ" <y~ԶE;gqdt{״N|ϥy$-.R (ds9wmm ш'Qen~~ JZ0-I)Q/2oҡyw6NL (F.Zra6ХZc+X,ABHz޵L&FX,:վѨ9?5b| A cޛ$, 8@]trʢ ILcQGLt UP4 0U [7j{``QA$⹦aO}h$^DTiڴ-CDexGl<"`|Qp.f.BWcqD!yXHJLYen )x{+#s9ݘZ/HB NR90$G8)1³{DKB&Q<Rq|?*@~")A!# '1B~-UdtZwi]dvh4믿W^moo/~Z=4_J'c?c?ϡ װ4kk#myZ +{8 ]tr|W\Ht:t2t>A4X5p0C#Lnk"<x[xcxptȞX@eRO6FUغ17$0pݧ=Ҷ- 11d(J ulTtOߏ6 52ۿ-!o]?_+596R"1"!:DF.G*"`sⷈ4<-Jn")MV| #u9gTRGNp-EA9k@P #:D+``ͻ~>r MZĔ,`'CsG<[P" /^K/^|?w*{K)%g~qrr_ſZ ; qbVEϛ:KHڶҍ8991)¶m= @."a}}]Y4>]Z"nyaA|:1L1* X?۾xd& 诮%Ycgg/׸[>5ιWEKҊ ucZ.y#n `&G#YUUa: EXж)9(XD%;d DbS_W /( f3nN L@0UɹD:xyCK:?O̓[ Yp$Qc`0X*!qy墄]iM'Jľ ?Ȣ='ԁGEP>}vʰS$);(OCڦ ko}*ku}ƛ6ݿ޽{ы9FU  h6yUfɔ5҈zv:AT68=#*I{}pT'''f3h9Q899׿u<֋0/D ;ut>[R#s_5w7>bKB+%z2::"ӑ; &`=Ack,5H>FI %etٳ@eQ(}fG@xXwnqpps{g* .=YBȻbc~0Lru `k} )J?:I=~ `>_:ڶyewh*u%qj} zs/Ƙ<7!xڤ_QrN4,`hMD(N@L,鲭&pG8r]} /%FQqAuY'FN]6BRja^O]5,{>FT1FY0EQ}GyqoTJ| IS= e3U'MJF, @ŹBa)"ȃ!Z`TLƘZǛ;.]~wWUVis®>ܳXY3CLbTi2U.!Y, )(l-N SNk xo9U5pPbQh]Jnn28<>h%ckk mpݼNtKqrr]cP:ୌ#*$#9uvemDU2Q* N0iDѦqe/P,ST^nXāGܥzsY ~\yAv {?"7Mx ipy|S‹/}{~_յw\@W\|EQ4˪H,f׺sg: pzzw Ցr6Re 0,>3w !^}]E`%"o}IT#`:c^=g0+֝{z2\.@@9 0AsR iݐs8ε5Ҡ1R%R.a84̀B@,6Mwc9|kP;sG!|zz}xr3V)xk>X; _TFDtD(Q׵Xb. I7͸T\C.#yz+ 'y6ܝõƈP-tPp{Z%w' 2E.-DhfT\Òb?uI?Frp5  4b:˪%q|:_i7{o%dEQ x^]BS'KioXgAaѠށTe>+>knw8qouZ]svwΠ}eYb:}|c#}^ # R.H"weB6̦8D"ИL&q8ږcg7qfw^;hR8xphSmk(o P5r\>C[LY¹m5 I谬`r0}aKaIg[)2p? F8{oUy 8ؑDĖ`:ha5\xQbb>"}CLԏ]{.2zQDF\8,d2b Pd!#U%C5 PxH ǏiҒGy99H-w8N |/_]cW]诮8ǯӵǮě7ob<d!M 1F<`5(K8O=(xb|E;(;N&8wvEaœO,P`c]sc霝D({{{q_]0ՀPhSLV'yY*ɳo^6=h7"`0(}DYmsϼY۳@ci<$w>J QtDo>k IDAT=,ѹ>']b:;x<6 G/42bG|wLţ-ENSd$@@(D4 r0T 'nBK]TJ̓PCJV)u1!BE5Mk׮o~}]W 诮ruaU=|_bE=q9 O&f3 \JE=01 z5}\~288:;oPZp`<֦TFXof'X!xwwEҰg`CP hU)#v>ek=ToLN;n :lk*"՚A۝fE(W.H\ qeOz QSG Y5Sa%Q!rxN)=QX__GYyfm^PORgLtBxQA- bH@)x*dFTR D##󘥨.Dl4Z <~-}F+S&lvm[looGGя~*;յ*kuAE;B,~;Lpmlo`{{n>fE!>X!.x鶀TlQDe1@]Pxq-/"(A/Mu ݿlIx{xOԕAs`6[䀔 9ٮu \dztFQ ;Qu"܅V`Kb\.cr3W:DD^D؋yxE!nܼ]̝.PE_bcYh(aQH = '9)no9(D(@fY4'7d2T'd+ s.C:E410x㍟8sO[VE~鯮g2|I<>8ƥO`ksG}6S?w]5a4 0@߷.&"3ڋ}9x~m\r{Mc11 0q:q (tzzʢfիhde h1VIv8mݗe #;v᠔ @!?B  /!zyr 6iO.e3hAKQce2PCs6wkkyzk) -} Q\}.#rD\40'_QA3W,lt\Ik -YJw¾Rxj):1O7|ukQFSO;u U_ukuCؿo_U\xyбSG?\뚌%]8ĎNh(v2ŮKc uuCR m- * GΝك(OcT0i "IQ$l 'u3t'<FJti04\B 롻B˲ 8Ǯ\ŧxzxVEu?ի?=::FGW<#`1a6I޶-w|rb^R/:]k䛹k13Lsb.lDkpf&?Y,Νm[# [c^/]3"4)l!ƈgYs0ْy)j|yqm/q{)a> S᭛oxhѠ.? r=_<S* {S۷4w`|q xz&~T:^D=q9kxR?յ*ku]},h AgyZk0UGc7>X.˅Et@ ~F#Aix"}.^x#4)L0 K4?i\0.@I<Ȁ | i߫cwdN "Zc?S'bnEakK_|o8~Y寊,ipy +iMDn>/xꩧ0L|ͼAb}Q:NNN`t,QVFKTcٌ)~|SqsQ ^nh<5ĐpC _4"Zf6d:kUUh_1t::޹sakk1DG*|M 1ò@mw xJokU;tP=5<)Ňʻ1 0s &;/: 5P)HDhɯ"PR߱^ʨM$Ķ_'ly0 y :"GRiFs^IYv=y'CEzk5_]RW?}ר5ȇ7‡F ߻/~ΝիW1pLSVN|)nX n'SJ:(Z L@@6hbWjuy]D9$emڌk=8>KBA㭷 (ރW%8^Nksa1c:00p{{y瞇 2ʗ_s8pwf$F?D4FN|9Lŧ^@FB߃2oi- !',K|M*aUg0 ] Q}*ΩΚJ| dǕmw"I& 0@yS}p8Iz7_JW$"x009=9 ÿA-I?/grng6,M~ [!?y0-0̱>W6%jaxLfSlm7o=u,s1~gmT(`9jp6BB&AUM"<$[^KCnD}; :Èԝ;n >}y:4:u>wH|C"\u~=тI1n[C%?>>*X}H!PR_ŧ>)QUU CB|տV;8899xB+prx:4u5EP: P9K2`>ifkhoQFqVNװnseJsDl1|>2X[!=``EPAY眃%kr'sM"hmd =dmy?e[?lSC~oύ@)ġ,Kܹ{,ָylll,VʫB7u>Ւ>5?4H>~B(ݐ3Tbn@?&w"L_# 59666K/OF[[[Kյ*h'GxƷ;w0sRlmn+_z£/<ܭVo¿o6_]LOp]&IGi$&+mG4ZNqQeJ٣|.ʶ~6ybJheO f}/ιE{g2'Yҍ{-lllsMl>G&%âxS-݆b^g31nDbpKz6w]w2!D98v\nZ Uԡ(8|M $4HݹL_8LketmTkSZ 1~^x:v}[ uht4艈|>w&*v&I=JɵvdZn4jږ 8hA1پ:KkuϬZ2˩7>яէ߿@u|Ō[n+/q8pp-، ZhKYkWS%g﹗QY׮^;7ﱾqw9k7tM\2[/O䩖|(ĀGu+EFM;Ùp(c۩leIfi7Ӹ@S/؝LYYd $١5RN yżZt}AbV{s%G!MEfZntZ{sc8o{[[>Go H9})^Aoy'PŊ /Y͝1ljc9}ںMzi;lҽ7Nhgd*oDۻ>SUlq->i6y/ωS{ǝwSO=D[Y:+"tvƍߺvoܼybeYJ1Pq.455LX8S7!zbc2lk?__WU;3RL^9>6p(_/AIt&u!e/-KuF2:ɼde9RrZ{ܲ(:V0e(9 1鯃ǚ(]vD(d:bvv9t$9ɚHtjb;B*Sbrc"Q%~QW}`-Sԁ}Pi@'[Z~Wp%6?Ȟ[^ĥ~ !iv,x[2tޟ BF֦h%.l[dGU2GS^&$tʱG+O<9U5: rܺ[o찷CԊǎI:u;vlލB ǜoA kQ'7(Wz*_WÏtwi޿w?cs{c'O0f{{NV?t{nMYkGyS7 Efoo뜓Sn:#EÜe@WUBv!VPPͦ4AdYY0LpQEbG2&C5 Lj5Ml!Ș>MR6dcF㥸QJ*ʣ05<ŀt}t}Zp`ݖDFs&AuGyZ ݾ_BVӍdž0Q~2x z@)2X@y's5i%]n{ȋ<%^'àN&xB Y2Krmk{]>ЍvwT21k|'TYulmNchZ`1h\ոhcO;s@Kca-+VO>RDJ.bAf /PAQ/^t>[V:!"9Yy4!-Z{|mi7Bez[IFVj'aFƖ1v!F1dj/1=BfZ1OiE6@('*Qm Z,q{p??o[4&Ml@z֚ S@SG婯?s:ΪK~9W/]ۛɼDqdžݥIpȑLta9DkE|gӸzQn1Fw1[h 'O-6odXte?j `1vp,)s1%AAcE[ q>2W-a6[P9yoɘdE.-.a61Lw.B`>iI&?1FE5~CC !Rj7MCED)倽ɘ{=ρ^qMI=>@kk B1NuFYbC}go}\9OŽ,ۻ;팙fllctƙOs1ָh,;;H$o@ƾw->:I`ڄvv}^ I"cg#< ؃;ZWgMUsP]9zj IDATUUq fN`m0PwkcdOX&%{+R)#˗aa67^c4NX*sskjin*Pڮ-J*!‚Ra[b<6t,rAIv}a3y-6Y1ȋd i<2,jG=DO bLEZT;a˷|H:2)CDpQ nqBރM:ރ &lWPݞ{ϵ(g5J#@_]n}2XumB,%MNi5ϰpg~dJC m#:F\PdvYT !XI{{eDT:bw  \rAkMngN&.z)>Ubǭ@uٺ[(i{1q-=u٣5Iky:q m-9dyV,;?R4}e"<&t۽~Y헉1yR%7]Gk,)2EJB̄>1Ni&=wj*Ģ>8,c2RU~Wd9e$C 6b|6j"6=ZUW脖xHzqe*7a2)Q<,%sqߍ%੎4t#xjxqK3lnĻ(Ed~I Uim7ʢ Ե%mHIuZ\niˇJnDc;>X)`I\T_/~Y Ek|:+7 7ڛMp9& {{{ub'پI~Dv>1ǀwt7|c3 ?8U/v*âd<ߙ8_ԲδM4*cqeYSb^/IX1c5A,K,#ֺ4(GV %ufZàXtk,߼vɔG@-6ZY~..2w`,XVed YJs>G 0c#;;;?~T֍*ˮ/kW,Bv׍>ӎυ/xۓw{xN%fU"6({- pqM.+A)Pm"]DjZ/-?`:(J$&xyk_WG&3}߾ WgO۝ut:e0)O6I~>Lef3y\r3ư|^q0]-I+UD%uĊm/}K}nmntxb$Zkkkݮ1=mbUxE`P}ݾ(MК,,˜Col3A\z Oxލqs^} n2J''ۣae Qv 2·F1oEh:}  l=|N:z$;1YWX*Pؓi 1t\,FBTdZu6 ƂZp?75mw}M&?׿uΞGطXuw#h|?'{X̩Ri笯w.dU5ҥ+9rǎU7CV"/1j-;yoPSOwEa,D,eβskoш`|>dԫu)xl M*L̄}.TcW jtjl6̩ lVvi%K-`Tu"96ImuZYvTMM@ۓی5R(OLA8ed6BX-{6$F!*4UWE@G\h2.V:Hz7lH{{Qse f*F^V欍MQ GFߢ:1ݧPZ}y3ϱWF^$jXTʄ%EhĽիWpBwϧ\*'O2)<$N_:kȳLuKs=ιsx ^qZ=}KYhL&yd9*J1zkrb<wݭ$Z Eّˢ`̌elmmil6c00͘' FiGx/d =I9߭$WUh#iMnѻN;xP&@At "$"FI|XvvwY[[[DG|p dpNF"a}K(Ta04|(t i?moh\%WSwnOC[fyk ^G%G-dXZ eV=Yma DHSt:iM"Yk@Xp1|I>/XhW:+_=ٌtʁz.~uUa ^2Ka3Nw|s)ɄǏ 1,GhM ._t͉'8tǏ Dc1b>pL'k2FZ&F%Gdo:YYHE>(יˬZPF{{{>|,fX4r{{{Mfd;'1w$9ƞ|;'}R/٥1Q8OU5eHthU)54M&3EcDy9ciOTm8ҤD:}/%O1ILD) 5=@DMۍۮ8]KG~S1];"$lW ,;3_dy#L҈ v^[H5iz]|􃂬uȒ]RrGf`>|_Vzw+F@uqvkDdp4"bAHtɢb0pQ+l`'v-u-2( {9WK:}96o]ǿ wy0,JvR2Evs]Wšc#:˹C,{ VY Yμ({`\hGXt6e9dw2fAA^$WsW"'4h~\\/O >TX:}}t3w(7(6(MFf2TyDg"N}/]^݋l%М6U) " jcWRbF1,tb!؍^{V-X,Us4/Rr~电y79X@uLN5. t,˘N;L&ܺytK㡇;?IJ+, >sY1*c}}K9YcWگ'>[<Ò"y AQr4bLش72IƓGF11v>asښYkE{|6FY'6 .8йpݾ1}!tpL$:"09a"Ťhv]m7:G)N F0x`͒{ٮ.w|0& cvZ(M9YJ]RwSu!&N7$M"PUш_O~EV$YYuJ#2U6^~e|mvw6u}7ar P?dV-xe}}K/>Ow~660Miu>@ʠ/AŎIc%Y>;ML.$bA<ʓO|S߉;@uu 33mdcbﲵwyw&7nϏ_Enu !ш~ࡇB/éS8v<~{uF:JYGjsb8է糟,>' aG(RYwq,Ե#+Sצ.LvpЊ|F PZ[R8 PEU:khcyΨOmB4#$kue{4 ()LB*ĤsS>z 8\rlEQPU>4`iBvĶV/G>hcX3Qr#^~V[@m:%ϗ=-&99m74ݮ{/y^u}?`trK9nͅHI;+esK늞Y?Qm+ k-?~m9G}uÑ'9kx뭷x'o|ֹ~5?tRZ,f8CGhFD.H jV42m,c>=͍LxGy7h6[:a׵68x,a6 U5PzFdVÏ.XdȾ0`{qeוK Jh(!1$(^bbiIn|7VXՈ^tz.Yt.(M z Y&`UijxV,\+m :xB*8V ~K AU7js#)NW%冉{bƠYz۷NFgԵdBe0:lzӁ^CÏS1drJa18s < #?}XY W?ioȭwNq`,w;.7o4N>{7x5^=wmڈ,xW'd}}<+ **t>FOB M"֒"t6e1'bkwtYs]7ߎǟYYt^!-`R|/,.vC&oL-G]|DGlx#pio#=5.xLi#?&|ŘIJTn5Qb*Sd r3^|!3遗k!iɄ`"iCEIJ$nRQZ H}Ndg%CNL꺖iǖ2- ;5/ +~toLq#G|\2a3n{sx]>,/*۷6 !~k=Iò,c^W"* \U& i&39Mp-N>ߑ 8ҁzKr>@Wt'ImV|kchRN$=Y3,sJld%YV:tbk1`2Cɒ}nDND!{Z!e=^u"ĵ}-;zrd׷0:vd{hӿ}}c\qM7'|g> F+1JcQmT ,@f<R 9v]ƻ; #{Av]O Q(v6UU@ilᚆU 7}Yf ɬ 2ptTnA𑺩-M)8/3,atZVo^%cTF,ʾ])ChQ1[1fiѺnA\[qh_R笵,Fk]֤Ƥ`miobp mz)kV IDAT#}?OFKrcsG)\ڍk䙅S=r ISB`j>7'|Jmll+@u~*{c:OS2)9Çy7w&㎓h Tgy+W.8Pg]gF RAjDL\\B`og,cC͗A- =#ɭEϞWyg+ᅬ*Tɬ@E%!t!78"EkjG nnMN?Iiu>@Z\R QQ* 51|5"J)6GU.Rv xLSyII7-%kY(9}ݭMbwg$[2@ѳ%}{u诪ڂV|n4J·YML?wekwLfϟ=áTh[F~, N:__ү#G~'Ƙl_Ӹտ1Mgܺ~x̑# .^6ٜބO=<(]{cwy7!{=\q7yqS :*^'|`!o;sQQϱ28͋kS\C8p;cǎRW5Ŝh!PU y^RU fb"M10*41MŁo1 eH 8%<քڮQ[<ZA^dd6Z06uߝRHgFLUrSɟ_M (m+wWYFSrK=tkƓ W._?MAb2!4 Oh) RJ@g91xٔwz{Ν#xG*djoѓud6Ep 5N<#>8ʡ !qiT X4Egcc,/G W}29iXX"LFiF1dM<9RsDpk9ZrW׀PӂYǼ" пRz@ɴ+4a1IQӧ9}4cdy<|_z7uXY9vrs|??fQWlmndox 'NW_C-=ԧ>k*67oQ vwwI<)xG?fs:_xݷUv|OSg("y9EN=%Ws1DWuub0˛Aȩӧy?fks`si nH k3QqO_d|55xh7pNX7 2Oѝ9M15 EQ.$ $>6ĚƅڶW*MT wXdvFc"ɩH1()<}&T&C(+ye{7BEX,vm'.\ vG)H'ҢJA{B^}J خt؎hesoYQf{k<}u11Fyo=r:s?!^zo71Ml0Nd:8z(>[o<9NkW`2í[4Gf{su^5N:|=o3Mɳ lFTfZZ,129s6o՗_E`0`gC1QBRSJW5u z)8'F ID)i^1)þ'h(۽- bShK)!BQIQdy.2æIeڈlF˼uŸFkCYʢ(KYHF% hUv{AChvfM:bw.A^UgY&+(PP gThpțo[[(8vϟcPEAVk7מzZmlbՊ:+_.?&Ss2v锨Ō] s`0#;bs&MSOq%9!z޻p/}q76tZk._D笭3Oi\9/i]-~h^cJ_*<ѣGD%9'O_Uu ]iWgkgQW,fstGClno3N18r.\d}4'«jѰ˗_EvLS{|kҫ&j*6w8x gDx]ww^2Mzaۅo{d֒e9;u ]^z%"r4d6^d6v Uи#Iq^<%w{ҟPZa.4x!Ȣ+_O k?\|'cv=!sn޼`Q3قdy聏o{wٳ\xZ]pwa{g n/];ĉc4011DFZkٌ۠b@%xBpx)tcYT ^u&:9ży%F\d]܆*}#$Z K8,(EgdY5mte;/ۍ<‡v}Ljk\̧~c ?q)/\s[m1 #Ɠ 2ŭ78wyΟ?믿z__3w+/0\qヒy&QE&yQ5ш9lfɳ+W.sa%+r _6!Fx33<ͷ~K>TYԃ }'*W;o͟<nb:\kә.u rx/O07sя^b2c>/fy]NS;@T,U]6qeÁt:egdGMl:$k]J39}TU͢*/Hh:bzkX{l#^to>q=E@ [/AY5錼]"suTjG;@ )'Fy|z^פ>WΘ÷1o?.οMɋSM)lF4k.a6s ~OWo:ṡVguV:9>˗kamFԚR_|fHK|PDԓܘ'^9()"y&֮ j't3=BZk{HbkiB@~}}`0~k٧Q Eцz tЭ1Z֡Ϛ(x=>>tO3-2; i)P"xh% ?B&2fɄPi-m ?|[R9hc$:x夷:+_A_kkW˯׮]'?qΞ9ˡ17 :~kz9;,Y52my-[l@'ՕB']tlBCW*$t5tB)>/1Mc0htey;a= 6 ~Ts9<`6SUUI fy')yѺZW%[[[{G}ysIwA" Γ9ٜ {[;w u])-k)6>[IUhc )MS uSqx8W'Ţ`^̃_.HZNӴU& RX|oe=9,L(O((h)Y]]8\;*@Jqi[a$I<tA׃)v\g/;k:Ϲ;h„@(o', O GZž=k!1ڄ[ȑu`#o}n;$r%/%??烽O,KY__\xc MSGidWH罡LYdyN γ( n^υ WBTlll¢,suKY\8bFQU@1Y5[yǫCzvwvFMIm{\b4u/,9EQcPbM07~b`Q\|#O>&Xh(q_lAu7檬>ϸa}mMCe$yF,ȲeY"kkxilCeNO? qgOsM7쥯TϞgsj#-*!e`4u,eg1ΝJ,gϜc:907f1_u. ѐ/$k]#\ݽ%L KYG`dA01* c$4Mf+4л ^`mC/Ղ,pbmp:f >7* \5|Ѡ.RcD]%n_t"y4=PM!W__!BSkkXcaq7\뢷e-k mݾa/N?5*yNdYWA`s9LHF˾2BGO<&S666y3<}oш˗д ٌkkdyhmJ:her- {eA 9{,u]12vwan 1)( .\EbF : eZZQ~}%Evwa q vצnmH+*õ^[]N޻؝sx><*$ڄF'}@N'@@Zs{}xK%I;N\|!#&*xtc  T L~*So}+yקu$.~YZw) ulOԓooo46vc=Ks+CVG+ &1\x<&IP%Mr囦kww8~+TMEYoǞ`Q,R ;u%$m$gww[oڶe0peHf̦h% )( ꦡmkVFY yꩧ|.YwI1:w}|]}Mm`xӅ=Ƿ IDATK\ا(R mMxg:AH@Ľ}[kwkMe1k[N} Pplos/$$zP]x҇7]XNITh)ø^h-mUqW=;hI"wK_ֲR/"u1}Fa Rv)I҄,I&C4%3`SUnu ˑJ1945W<? EkŽǣ>JUUxuk[fMxYVS`@e)/^<(" N:"i ?TɲY3ҥgJ2Lz/,Kڠ r(;k~ݍY.WJ樳]\m~w͝EA2<޵K3 Ƈ?Fyl@*8ȳa >mǦL;T!HԎ#]mw O:?k*%&IA],X[;C?|c.\fowcYZ_rM8K1_O?䧞W"dK>: 8%YJdh/0Fyߩ T8q-E* Zop1~Q;N~>/\b1ewoZu>}䀺m#n;߲$c;nΓf) ш(m,O OI+_fuu̥KςuŔQG?]|*;7`|:88@)EZz/3SO>+߸bu-Z:ml'J %'4K1ڄ=1m0$g=Y0 r ֵ8$EQ\.iۖo|>KO#a2p+ndccSh 2ma2kAFU8<8@)MQ,M Te^ׂͮRQ@eJCs$Hs{2t:k~a9=XTF';s625o u d BjDL # 2G$&QWZHŜ뮿ȫn/}KKӚևE1wwyΟɟ4{{{>}Oo}{w/kYk[;۰yOWc_ WrCKObҡ3MLd F'dY_c{,c8 c,`@b9ˍ7:UUY\96@/RU<eQP,f<{'N0qx&ئe8Q³X,pxAÄЊvnI %O>DYY]#Ͻi)M(x)|H>hʚSNWބR`ptwPIkхD#tq$fXM7/_om[n.s?sh,5}uBۄ6$e|QƕC Lt$~!p'U]SUдU/tk=u Gϫ۽{y}BNR]r,ZtD/m028nJY*O?wq:.Yֲ_F}`YnWqcc|F]ѥ, eB (rԻT1B/Uv$ ƒ2 I cڸc^f1̇q\ܠR$X,tR`[ _?炑d.gΜb2:t>aJQTTT c SOrm!eX)X'NڶeBm^?1ZDd2o/1Ej~g>WIECAݔLIpxp1}^?3?xv2&/5ԵCIC1FxHYAZ~k[tL˲,X {QǑ{:iߙS}t6ý־)__9'¾p шy+++t5/k5˱a- u[Ǒs^Ǥ&ƇS-d=Z w)qd#YzBsEsg9"?88y$ZW8}Qn}mMXWr 70L&,O%UCUU9؟p)IR'_#`TIKU֘D /Zldx^q,mmu >ޓ!'N(h4:(K[k-ן` D %=\RzZkR}M$uZ8N^ B#:l>V I[`“ h%OR,o|}o=K^G.kYZK دp>6!#c(dfCf C75S.֨|w]b'//%Õ!(&w8w>X,%h[HMd`Rc_w~?>boӧNPEYSy1q6g'dYFU6DSOw<%n&ʲd1/Hg-I!@"gϲ߃v Cn\$޷2='χ G~o7;w;h;8ěi!t:*a/$+\kqAA>;Ҟ$Q!  t(Dp#DŀwѵH )}d+BЍC&L&غZT[y衇;/|YZ˺gv67(X1F ׻G/@Q(Li$z&:lc Y9%״=m2 YK( 5n3f$P lZPU .]{=-o?a>'Ne US3͸xUn;njczys8^<4.?'x!EQ}~HSJZbmXۃl!n\8Mx//|h!L& ~ahe-k /z1}5mS+W.{"H)k5JD0et?Z6J$nljFq~w PJ&ّ1Yu]Ǵ##=eYҺ냾hVIaDN@Y(iZ4_}nNy|_@bxuQ{suy'RPe)KV._̝"31N:h]! V\x:ԊLGSVTU-~䇹o `oVph9y$?OK_ֲ=Xg߶-{۟ܺvwv}2*7xR^J96!JkP1T螔9 8G, m݆ĐiS'fK$1!,IB0-g<WGDUUf $a<CQU%.\KP||` xխMvwwY]YaQ klosYGzh<t"1qG BR <<3|Xבy.ґhI,(l>{ЉF.eO9ȯG?{} N҂(Y~dB 4@I ]\gFtؽO=(q3%w`] jDȼW'VuMӔvm}s˭Z헵%=._;;L&:tnZ]GH$07̵ |D+blj`'Ơe{ʲ=|V%u]rYVs`\cEQq*?`R Z+6}S韒lUaE]1>+GAwGhk"?2T0Q'NM/1)~$"+?L<}le6q|y'엵%7w{[[]2qj}$aPNC1&I82tTJcFHޅt:ꎜmhWMCb'-EJ(ʪs3eâ,,?vГɄo< |+4MEon97 tK&}eTUɓ'ڢ+VWWB2Zspp@M!:#9g1BaP8^u|>BE0GC>[?y̹_:CDG Jѭǹߙ?o}G~GeZk>8<℗} 2toPzfCO0uݚD}}`~ajly{w< <T\!hYZ_5N;Q5ֶyV\#Q*]=VICl)a*$޾劣;6|Vm_Xжbml<|p ES ƨ s|K+n LijKuYU<7x卯Q`[OkEJpkakkn1ٜIdY/,O 3\$φH 5|074E:.~'C|h&1yx^xoh% !^@B !Z0x:FIwXvnz*;BLēR/1q-PҼ-o_8uF&Zֲ%,l]L&̦Z92921!] &n7 ŋnzRb}6An~?N gJ7 mAuGVU UOdV\+'J4 YR!>Krʺ`wwz;_}kRMWMmlnoEBU7Hŕo\U7݄k|0Z1: :!sÔjYo<C3gΐ*Mٔ {>wFl >8]c_EgVV86,JZ<'0"%)cS{V fcν,˂Oѽwx"ߐAW%Z|-{^݁M AY8=|ṃOEyGB ut5m41u1ɳ#'BkZkjyuI0_Woy$o;[_ڼd_|&CȸG}]!a,P(VHRKcl4 eYӶ,:mP%eYHӦa>~**ae0Ux y _s_5Wt3/S5:1\wu|Y=.$AXe!qngR7Y2ZEJp8 ݨ%Ksڦ!ϲaF:O;}`Q=`leG-]Uq|8Bj*h >ARy O粜b<>Ox) HΠ2LX[[aXg,kYKnȷc'l}ro{STeIUwmZxc[Lb.I@~^ "%1xۘ.bTsM ,+fsw1YwS/E?a4kL$ilV]`9 $1u2UǞx[bΛf\},?;bLBٓ!&%.^w[(-QziiI !9Ѩ`F\R0g_O?ſ1\ Iz}[[lA~zauމ6;y7!guuA5c x;x{#k~7e-Ae_ǃ?,`W5uQb LNWl7km0waml1 C/}XֲsI+H`jC]Hq7'!C`IhRlrP*t:1ǘ2W)GJRlukRg3e xz1"tb_UU!]iȴ'W٠'c8S7)UE)P0 86fue%X%䬯 7{^~=\g)[ֲ2% ;[~:9`?TsdYk;ph^*_~ 1 l@IMň+E&I7[tHkڪU{:Jpù<$Ɛ' J`u{G8aAqoM]3iGJȲ!ɜllzȫn}%> vvwˊϓvZ9PL`#р~:GZ2c4 ! z_zZG ;9x㛿Wo_eD+ؓf l+Ѳ{2XfiJ第bӬTӧi'B#MI%g r\)r*/ZP7%iŶ-"훦JptmC[7nQ׸28Akq>7< ʚ$I@H2p "Hw\c ƨ^)|eW{yǙNL曏i!`&7 "q FoL%ԤL&Fg|> 7//${"+ă><HF9}7#ғ-4ɎN… Jvx׻ ]wWXֲpWn^UU}5}Q%UJ%b RȾzݻ%Į' L_6&%I4.wQMݒehe1_ئgw}7qI6h5i4 F4mEy49?HaL -:p" c)Y Ah }8Hs^1N;|wuWʿ_g?_+y9+++3TÓ6!ܹs>}c {x׻nt` Z_ޗї</nmldvHU=MH#x-Jt 0F"$v,@Zg`U }ÝM(NG? Is{bj稪2VEEG6v2:)QYj3 FC$kd춓$5-ѓ }Bjx'l6C"8 .]{!VzZ'&HMHmZR5uaBPw ʶ@bH9JʞilxGl `miba<$ =W^׳>c#֡A)| @uhMRUUIQTUmǕR!,KN &Xe- y`wgݭ/Ng΃Ciy 0q$&^Pt<Q#uuEX\웺daCޔ%U$hx録m\8mxO3X8cR&ZQRh%J#D!~_?Z 0@U,s&E MYR`^Kbi6X*YJaK4 f4|> mKv 4uJQL,/rɪl~Ͼ!꺥q|`Wpd($ UU1X0 W8w NiC>8FQt  V]u_,sN]xg{u|1c4s_Z%Ժ|H-?|ޛHzIBG]<20$&HA4#|ݾRD'<,-MR5mRU%ֺmco*[!m[ޣ¶$d*auL (~eGCq̦<M]4m>D.sN9~7|kw~?/>g| Cp-{@}vRPx-֡UB'c9YoY'"O2dSMdט$/mgY֧1IPGspU"x ƻFe-kY%^%;ۛ]~gZkflll6tg.#nZ6~bt3IbPJ#bVALzͽ8*FxwEmK4ب׺o~'?pN**˲È_ E{]Zi`w!y$:p mUun;rQ2MpkUO{gkyp{Xwuk5:4%G tdk B4--X ؀R/"!tıx]ruk;sX9.WuJ'Y5u=zs4|{HP%@#TI\)[';F󗗗)˒,Ou 8tcBX1[Iw0ư wapivhg>ttUH$Ek*1׮]槟ʙ[8kC 2y'!8Jmmh{d()15]؛OLs=LBZd%c(j )1S^xtc(ƣ, iθ` $C2Z`ЧHvP&#l)ék[g=j覦*._bҮ4UH}'.W~1DvzJ眣z\.\'>g 6 yi,)s}n}4G6Ȅpy.\?DEq8O~훟{ϱdJH] bY6T$inm|)hP'2 KRMx"g9vww3%CmYNr@RWehC;;C OwI3m6qjbzY@\ҋD" O~6C/?{Ν;ܽ{^Ogg!K+,B"XY[g?ۡ(a^*$*Xf)y 23fzh릂|(ʲkŨ躢1g,Ѹ,8kP* 3|PNF'˙mmsA H;ITdyNjWzRx)8uvgdH$VFʛ~o{ѵk$I*E]Q X[]gqaCm~~۷px$#ϲil|a~8{]UZ)c`? s$ sMMn[,1RW!Cx7nC?C{`f!Bilj"v >gp3c9w2'O./--Lˊ7zc~o@)1u]$IµB!p!ڬqE177 >>D"(OOf_裏Z󬭮̠DD"\vV*VWp"Z^o_dnq,s m(N0xYCtYk[U9tL=ۋ,>~^G9*CxNuQõf܄Ѧ YB IDATuF ? w{'@K:R m͋B:P&Z^ҥ翿q_E~ MEr9!?um)@>桦l;H$yEqBu+)\r|2lr<%OsJ9mCnn*CK}o,fH(%шq9.+TME4(?S >C^0bWw7;K#(:E]uN8Tߡr|!~D"s_5uO>wﱻ,|Y[[oc&¹oBm4Mpo ˇ(#vvjCFQWUU=Mpp?n*i2 F9.Nbz$ .8Gf4&O;4MLCh ;Xuh03eN=%t$D"OI$FB'{sgɳ\*.\64 "4Mh%[KڒcRTezp&챳CUiv 5,,eF9Tb#I4ܒOɓ䳗ynϭx> m;ڪubē9g^9ω}H$_8oa$D"O]y@Y!?CGHefګ_S7=VEQPW%`4SիWژ Mj+QYN2E;HURC4H!ƚ6w^e\5a9 496V9{D ǽQ#H$ԋe&߹~EQ,..RW bg{YtU5|zc^9h4, `<S%MP65M*}yNnbT iLn>$ReNL/L@$X:}QA݄x8,Z٭ﯭD"gR'"V+^ocj:"Q|zzk B~[9}fFTup\0Bۦuw~. Tウ~൯5e=Fp4a07K |*ITTYw+p5onkeing8r7ftbD"gVq# GVCkކ3vnS?3 ܹsֲ;QHFe<E믿*(n*IOYf|# qrb#H ΁Mm'z5n=)&K\< ӶUH$Evww .WRb=_\<Σ1 BW$Iv :]d2楔Hpb0À@ 1!MS^8S_U: ~$DyԩSͿ-_5 B9y[>`yqw9S3;߾Ny`0 T`Y$HkM$}(p!9GkPSg=xOӄ('69ufgH$i`066A!ZS5"Q\vR5j&F;i*^Xpo-Bʩ М;wow2*q!{$DNz9"ta.9yx7w!fggY_=p /by>}?ibn%aAoA"H f;B$x]cQB,8y'7E?'D"H'~HIt{+fgg9z(xr&Gk/~pkޓ9[:yC^3AJ!x5H"xXU\Odu~ϱoH)T*~E"H$R)kkmt❷Yy8kqHa8m&OR*$> @ N*2/pc&)Zd" 1dyc9z D"H$qޝCȦ$hg9sdR5nfBBO#$H$Y(GXsrі4I8|Gy(H$V37l ݻu%mOO tnNUU/QJN?i=;$IBk3rĦe xC+*_ܺu,뚻wpVW)%Ög5It<,k|N~H$D5c's01x*˩cp8d0PURl1BB#MS֎/z{}|D"3ڍڡZIENDB`PKL@NJ-Pictures/100002010000010000000100976EC3FE.pngPNG  IHDR\rfbKGD pHYs  tIME#_ptEXtComment̖ IDATxyU[{o8ӽg=IO%cٲdKj&HU3tHW7]jN52! MU3h0$ q03ncyҀy<{o{{Ε`e[UW3sZ[[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[o[oW"= tT]VdW(<#jH+#׷'~7?׀R+heTh Ȳp<~džM~pNwld@0Ѐ2`aʂmACB-Z)QcX.j6ݚlwyo >HAL}豶{ ;ܩ@i g `1,%d2A+[(%Q++TU9N&[d ?};wz_; z{P޹iD66d:?\P%,GU!3p&8@`RXVhgΞBg<+n~ηge[ZG~DJaDjӃ@>+ɋRo`0B*L@]W fe \tJʤTp偔MBIV RP<_Y.{s{/aO?7UcGZcl~1.f MS(%t D<+UUgW*b~J &B+mfжR ΁tͷ^/>D}Dz0_h_)QDZBk,lIeȲ 1.9֫cDAAk m+hD:> 8(h_?/޾?D3r:oN*[e,L[PJ\ %29}L6/@|!)a 68l!myn̅XFo z OdΟ33Adw3hi͐j%8#YAp z'hh֐%HDȳ`@R)Ҧ mӄL@k)x@*<EQ,ʳⷮ}O(; D^+`L1xG-,s1FcB Ź JA@۶U^1'曏^=.𛌈ypm$YcVR*188 dy4 <S"b?ŵz1';()N)1p!0 8|> 0NhgNw11(X.gPR287A@&A3S0q(M0ZW?Y76Wo_c?|>"8zN~eRr}zH4Z)m @d9DX.gh*JɵSF>!2H^"Zqa%QCi,36x7Rwqu0`:S@6֍Z?)uo3޾O<򧌱o^*9t̰O+%@%ں&p(|LQ R*'[ȳ mЦw /;.940^K"#dR*ȶEӴZ %DB]XW? ][z ?~k[qڸ7AmH˴Ӗд J3ƣ 9|`ƁuG)HImۙII1?Aю 'i4 2Bsa2?0f e6SM]Ck9'\Ao䓏ߠt)!U.qO#J+ŠD4J!9wiks2;MӀsXWK4m ڷ44xtJq 0"HM^W "8 !RpaGWMS_ on9z{ӧOKee?H=|=?imODPR( E"/|1ESv/ bJ [ huHI%APsLP[6,cII%%F]XRApnD&\9Ȳy#2j )۳Z_fyop%+&<ql 0 [mk{S,c[I3N$*EKDUU mӂ12 <ʲ`0DYfEIx6sQMSV+4us:˲kFPJe.k0݌2˲syt<:VůBc~oǗ{gy@VD,uGs'd6Nh]Yi=[>~'V/%4Ơj4L?+jv:l%bZ"8p2绐m5.f@`I?1D؏p my0&I{`<*AT(;g"VaO!0i@Og {A>=LspM&盦/7֗ |xG䜽Y œi - Vdƣ .^ 2BQBY.nt'J8H&#f9Iv/:|?3|Zp9t,'BϛAר8wv@LXR;A5P::i߂nxG je[}Rz)[tD%{ D{ A@Xr, P_Eti * ͂t"1](xFn~i{{{}k=?3@Qzk~'84;k.;1.aX`SQQ8=㖠Yt>d] ӒTqm+VDzqVۙ$gۊc&.@2Sk ;GSƸMt `j?5LVa^cI~^p'.󂋋uS4L,_{ |ë%<71FO b?4:(7>&s}оN.B$ -^0C)ʁuwbSQ^VMЈFtbi08(Sή;9v΂^' ( t* {lˬXBG'W817))DQf7F9q˯T.u8]$;*eӜ3H @RxJOr2Na @ϧ$4D6 i@ϐr<Oޞnx쾶'z4h[FVu#p$6} t]{4@ #>#pM~o[Z(]EՁ0P*CW:~]ڃq'CGX,>bʲ!&ɩ߽W\ūoK=}gL'ӻZqgu \0}sQٶ4`0F e9`0"Q1w[m2tڗ/j7 7ʤD10|A: V!9utv6g g3J1FQs9oh_ޤ[(~ OJNR>;jb^s5_s-w(fV dWlɶڜG>i/bR &aI3JH:Ph[*(;|y&TYbQØx䗣&Foq7T17AgXRu&$5-,Fc}!*(;W(RBf4/Ç/bZ}k;g K)G} 17F `\C_̗6:E_wCD.tcȲ`胐ڨZoʮJ_GO E Ds)Dk8!TOG?J4Ӣ(V@4HMJT粟TftԺ}J){bki!Yl!2#cN&[/mW]}Go=}}A;.E-}`f7f!4iOEya8a0{O)CUZ+T%Z+#fH ]ܪCuEoDH"p uR_'b"tr&8A( %2/M1C"_Zċ])" @-Lٖ d"-΋ODgGiW\q}mO_(| (XGq5Y` ـ @Lv7t io6p ڨ2bEeFck)#'mTK811 ݴɿA+'/sj3vsremeRȋe9kR E}nwٔ*rЮ^#[ZCuz B6&aѮ)#(vMtڌW6N(S`Tq@EL {|mAmg`4 uUԏq~}+'>ZI13҅&DB@l`9=DE4CQO:o+M65{Z0GlqyL&ÒPSm!u]a8@8 7}k8KqSƳo|'qpb瀔66IQy"۹,|m;dܶo9RF'"ruUʲ,Wo-_?#|/>> 5Q0`'>[b0@<KOd YFQf5 G[(VXDJ.j9+0XpzN~1Rzs4hm9#KMj#Iś8Ac% i-]."6 A(7;:Jo\@|9䆨k>6g #b:=HWl֫R"7v{M0ךI+VUC)3%ĠRbPS"9%T,i@GLȊ<8)jeekRfm g$.%f^#2UAWGQ""L{BG8fDd'紞-A (smP|a˲&MA/Gpǭː5vnNt{頸;DNA:d"yiPuЀgjc<4 [_U{?o\yՏ_.K)_CdD_ww B.[Xifzդu"D]Lq_k YWX.g6|})E0FQaxtG D0ik+(E?gE*!1RQshQBs[F: Z.?;`cLJJo.hW.p9,a,`2(I vx7”`&[Jb&sJq 4icL]7w.^Łz/x۾7zw?Я>ȣ1w㵦6 XAwAqE?!X%3}Nc_s#M@  WDUZ@iU=׶uCZf+WUJGs8\xDcSG/'<`10 2bD Մ:)&_^0Lv-^E@NAZvr1ƣ1Vd kKgPJcgg '>so~mOƸpi@iSWj@L5uFEGJC_%FZg"K-ZI IDATZ-Ѵ[9Є<2Sս>`F]kTrV aه-z8B4'qOHPI1t]99:%PE}H1C"Mh.Sgbg; Dfl,{1̐4-ڶFSר|1E2( k@kyrKq䪫 GYz/Ο;{;?ۻ? F3ΞwvB)mRnm@)Reڎ`#Aڈ| YW92{ 9eٚ`QUoa!/ C t!Pre`4j5bngYgMϰVPYr0xx EQBCmZ={gukׄH .=*Q֩ tm2\!Q;Y M3kma *G+wwT{lοg4&"V+*muUY_m\R5& Q e94uU GmcԟL{ &[[ON&v]xk2 =_ܟ7M:fAb~Se#[ 2622Cdbrm^Q51yf=Up gqijX̦h[e c+^v9.\85)!&mF2ֿ]~OyΖeCH)`*090Xpbb2:ufa:[1ۄ9ǒv@ .^$R\F]MO+3\WXWk@<AJjjeݡ=@ߕʼn_wy/~>ǻ/~qi~[S7jȅف#21r`P_7VAȵaSx}gPs1p7~qYxGXE "" I?Jg6@,>XdEC^YD?A;Od/O?u gϝC7 _صK%wQ,޷æJs@^TwpZix@4g,)"'MA7xDŽti::nNYƍ$#Kf}Ƀi4:IshD,eEAs 8_8,qNRIKJ'B/nu[+%5G^c/;_gyk&gN 0`b@"|sn~u6stNNJͅPJ JN#VG~u:d7L@F6oTp AH3=Sd|S\$żP̽0:⾾>pdljo_ggqRiې@Cp(M&+ž$ŕmNAI=VXjDcB u@) MSc8{5WQ '=vvb.Ν=`sf A㺮3Ow;;>C7 W_s]ŋ~Dp,CM`w".?,1M$L}Tg343Bw  wZC[ Ѵ9[1(mhɃ߂S'_s=݋Q5ڶE6n9z+"%XN;'5;F.Q3.OS1ۍu މ u;~HcGuZI qF2.T/w8)2HY$-KiU1:C/t"/ʠ-8C)eԭU^Zj; J+Msνe]?/|oM񖣷>zy皶%G.ɲ0䪺b6rؗ^kdn8Ȣv\satYYXG 1m&wJy$׵3n TUpgX,Tң0y"/ sM27=Req т7_Ȑ6ؖ#9AZpЩ%lwjװ.?NGGm6~}Dqo? :)ߝ|?D&'G}xOeea>;dᳺ=Ho2~N$+媾+r@p^|U{w;,3jBmbba~>"Hןaےl3&y& aHGauilrUa@<~8}Ӽ#otOf?0D=9ZپR_2ݷAڴߑ|Z)QUk4uml- .8s&5θt1EBZC:P9Ӷ0Jș-+Tmke̥`Pyށ?soj>}皦E oEajbXXhe`P,jՂǽn@6@@pn3;L[ڰvTfzmMm(Vkhc`Jken~k2g9ЇdꈺFi?nޟa:ݽ.ِ nǵ6}V #8´),Yf0CT#`non]j1̧p%֜ n@2ex8ֻM ~'?;-sK6r{ k,ssF-E7":q3B3gT] YX}^kNi零d%fK +}-(SHWo/8%D#DQ]w1׆(ĺ}_HOG %R^7Nj'OĉԵWDsɲ[ Jg9GF gâěux,qL' \.pp4 (Xjm'L ZiZVș{ͦ5,o{G>p_8zhU=ϞԘT QPH˸ T Шk]BUW&(0úh[!!  @l3 Vb$l:0k~ QщGS>wΔqT+,ei )P"vm$?.[/( El vv+MmǹK2;R9<7&<CUU`c4=Ɠ]bs'3O>zDt$(?ivt e1@XϦ+Pz2ӓ\ 3_dk8V<\ز8{,֫)K섡Gi' (G "= ڔ Ȇ&(`P '{F;}(ō+OXgOĉZ/h``ݷw4 V%F,l|7?s3.2:xɮt&-:2"pgg((12h*}r 0OGk+P59ڦȲ݃>5^w+_Q'?i'Y @p}M#\dhʠ{ 0l qkX.4_92aBqqԋ6!#a"g9>c] - Þ-O~@*4L DT}X|a3E\w@ĝf!Z}8{4v.KR*Qf{xK`wJI;Zt1ύ@1nřA!!CeτS/`sY1H .3D44ڶAQpLô88Ȅ*?o?3,^0_̱X!T[rP˯n-+&8{G?5M1[#)+@u\2rfWQZcZ`oz m1((CAQXlgy -@`^ӆS`wŦ頌AEVK;1;ݰNtC vI?_$%>#uN{9.%p Y&7ZxSoSn BӶ8yTU)N92 C8x)Μ:/<;v !Y! dVw"xcX;,̧dY'S/bUY!rr0BY 2V%B۴ uݠm 8 ׽cf<0\.1ϱ^͡;tПx뛟~g=pzcz]qɌnL`s~[1M&3U|| "xbHۏ 5zq+\pwPgEPĞ@r:-uB@Ip(ӀhN$7S^$l2(zM/Ggk,@ln4:e #{s>exuWedl\q>h($[l6Ns1DݲN M h#$F13vIDA*ym[i(k|õ$mɗ9zUaw.]8o .>)/m#&uN$#@Pßɓ/׃,*"@_"Z#ǠE0O]V#*IƥV LKyA3\.1O\. =O;e^u׿^_E@2|vwR`DCb<eP^1БvrKץbqTuX."x4F^9=xnAVa$֬7{ ~ JqFXҞK(!Kui3{ݎNB68>-0rlyĺ[/풖 g>!1K4Mt 7uL&w1m-rqڌEN[Z**Wxp'q "CjȌ4bB1f#'YV7'$Bܖ dTXXko]X.X, y^d(~ȑy[g~3ohG[~'j9c@mht#)Ew*cT YKY%*D1{q ?S߀1O ,+KSL&\}5ȲD a2a70szu%%!DلfB`9@s918|=rdǔ[T40jn;Y~~${DoubԬi4G`gEfmD @dZAc2XAUWF흏mxчXSVZ51&J? AEg9gPܛ^ją\,it2 o_' H)2DGOFvt=7YFC'Mӏ,YK]Y@{ ͏> za[PFEUQ+Qm1qX+Ԁ"tYJ!0&P9uI[a}RdLyFJEpH^.~OmY ݥ҈VUeت2v,vp7KZc\ RͦX,a]g/E7MX푇}6her9H)_$ h4a8C m`1b:p8Aiغc2ha6!ȡ 00ihNϞ:=ZpBi9OіJi+sP*̝]?wb:,,wml;iqw IDATK$Ҟ_tE@a7ff3̦3[jHë_wˌPLAD`_X⟓̋Y gw8(]y^h* [*fSg?CG^d'bq9dZ1fnmO]ibHjk'늲D!LZڌu\.!`8yJK" Ow?8}zsZA̓KM#uNe;qTgom!ZOqi,Is%#{w[8 qin͔7pOtY[]{q aƤ`@JއnBLѕ~)uNfZ/% y1l쇡`Sj!ƒM@6&DMhJ%ƈڰu{Q0M!>H0,2 mks:_̡2Ԣ@ ÀJŋNXUkyx4-NZw~w}WLӧ^OzoM{'ܦfԚ }UW*DIvDzET E1p4DSSO|x6J8'MDh(kZm nMj#ƩI9Vd<`8`4BSWⅳY` TX XTOke[fG3 &4b?tvx2:4,b?SD*N>YH40ْ-j̍Է^-E&$xS[:<ί-bzlnct%szx9<|=8l epmQՍ/e1mZde,:?ܱ,73웬]efWxY; \ M@k`0"s, 4u%F vvQUU46AޖVvzUYimLSO~g_'Ǻ~JDvC#ae?@,z(L`<`4HmlK΃1hmS2O~3SSRJķG 8NA2.:3 >:iO4hP[uD<{ԤC_69yGSltWy%\/=G[W3lk^{c40F Pk[j )Wn'b1[ NRdd\)rk3y0#EY" :3<m^CJ rx@Qd ( gΜ|1GHllc4, ӧع[+!k/oTAW1`Ē4Oө&Hmt開ڶAMA3,{ϧyAyHMvoZVS$#'RQE }(A*.1蘁HQzL6BW"H|h  |t/B4gųxqg@ d{pmqo<)bxbzc/.a/O1_OBM²tXP;`>ʁ`RNP;JDbm*yf]%e|`ŸrCLx{_"/ E^-zQzsWB9:!Rr8 AAÒ"^(5 " Mrnl7 3ybFQJ uv|@]XX׆ 7(P%xa%Lдud Ξ;/8pO_?xȯj7r3}gq)c𳠕HLs 4yS5Ntu̦9zƺ9-F#>|;ۇ0ҥsO !p5̖cZ@ J 3 Q!b m]IM)P CuzA+%~bu TcB@,z>e\RG{}GV2BL`P Kk/j@Bn*Y)ȶI\H4+8HEj6h  1rOvu8&eœMcg`NE-p|/[j]AXFkՋArD琙B6֨=Ǐ}xg^]nrEjemG$Z,XjcGYcTS* aP8d jDŽb(R. E$fH'^$Ye)^dY{w;[p^ln0 VJmh PU5hw[\~==1(d (N °+OFn P&7yr пa 3(m&)q}'JJfcQD+|cCQTSe<Ӹ7#Ta*.= ƒżi串2ADz.Asx n'kru]󎿈FcԤ"٬`fdY(Rp"vq&q@5oxpL~F:+EQb񮷽nZ;}Z7?n./BB>v\&ZvCڬ7hw;coG>!02\ư٥4#Kl1#CPB"`zŵ`^B2!oDlz${xL%ٮ;SR1Q@H.3Dh /=G9 Gx/sO0HuǶ.{4.TPBU ~H p)YC1VFOm: i Ŕ`c Xm6pzq+b2 Rk py:˴1.D4F۶?^ ν'?~?K7V*֥ !`apKv:IBE4 ,{68: O7ڔQs`m4Kb+p<C/#VNV~qnms"٠^B"nBa$~:'"?MʽdC5f9D#}1mk>t,ՁDaA †ۗx)-A% cM Ŏ,"3'ūAhm=*cQ$i/F07s%F9f12"s\iHϙm֦"vZn|O;w%|-o} p;!T@2J҆BZVi@)=13Lږ-[b6_:\<6rUY($;dLDAhCby v\&SeWtLAЌzdV=BdwXM\j>R2,*8B*Wx'PP7 qA0)Udv@S̆LBbKVUeU\UHۄ 0O Bb` %B I CxZ~@׵G Faf z$SJq)_㏿_ oW=؏vr׀{!耧xI 3X؂^qmdzn9 }ros[bYa'&'TSLjń@n?˃*a y:'かxZkx@_QsTؘ$~"!FmTL\7$q鹧pE\u͍G k*!J!Dh,PU UU[xߺ:~@" 31]X P2jh8Ǒ-MuDm 1'flvxɶ_-n}OqutG=Ub-{ˇVGIaR&`It]ﱮV!sv[W+ǬGj=sgai-pD6bFDƄM6qdV38{C,R V:3䏙$ ĈHӵ -~s¥D]DT*>?6X.DᶴY;(((߃OJ'?!RijT"&:1!E Zhm 3} =Ty  K9Pfj{'ϊMS,ж^[n}3ƣ< ý*UB HKTBde."-Ց޷O "qlh.`cE&|o e8,֫#~k& EA P8T eՠ(K 0zzf!#¼?2'xTH9`5 a Ӛ T84J"F$}O775 p ѾW<|Xe+֛ Pa@X]Bo! M, 1o3m`˲bb]b^aK,fe* :ΐH%bbE3f)7OQTe<0"qUW8n!>ꃓJ#B|_hi~-Uz\ӝ͗y(c$oq*˒]ꊁQʔXJAR*40r@vBlLHv^bB`Zm;}KI{6\ؒ:)m@?p8qk}O.8@ऄoB .%g=<@%GzAWLQXnX,X3fΣ*KeMY`Da ꐐ4cbLƹMR"q"s:h/]A;.U7s/r{?.9/8?uu)M E{C_?쥒P1*|}]zD 4/PMݠifl!0Ϡ@vص[Ƅ*,(Uԯa5HN|_re^8^L6~C5)ńD]56x$H2=2 R)8k"A~U(l@Mfyǚ S%ɀh<hcZm051hw[]u=qL5Gh>HXV*"ad<ҋZ |h,(1\ < {&+.S/`ʫ_&r0@@P?|Nh%jpi+8ctmmQ(15Yp x |`]P®ݡz#L%dIC" a~:SL)ҕ_j ;Efz~fټeM/<л/\8GGN(Ou ǟ*)`*hcoX1 rNlvX`u;և0GfK? ID~@h h a O0 2"ҊM07..J'9E'dmGO N@<kYNTG/B1+Nc^jqcrx^bl- ^.LC=EQ،6=, -u[MTD0 CS;G [Q}c`G@a=.Cۛ"9Oy%ڷ-rOYcqx[C0D%km RڱHt"i(hRD*  0جʒڃ^Pd)5Fr` Si=C1 ]*&@~\PM޴βxO}w  /]%T_lJ]ˍOXcx`4bbEYHBx s3m ьV$X!V-v]xϻ}~$,PXT+JZqK IDAT$جW IMbf$xsQ9Gy.i{XNo ~le6K-؃7rj2wq?@3k'=|A^蛮-Em)Tv1˰D/5ɤA[?zjN&V / . F&.Ʉ7(/1 >H&t ;{2qqd2YUujjEYaص-vkvh~*Q6|"AHe8$CdNv9|6*02%~ecT8ǥ[ÏEUVTj.vqmb^vP9*6RNےD 5B"$G@\<F">{DR35zg"~p,ĸ%.}QJ2mg.%u?[Vy # DZ#P>fsܪ6'vVhzww0H>9[$LZF Àn mw|?y{~u|`?"$Zqց\Ր=8h0g4hd8j$zryMLEZhD,I_< \W#'F{/ɧztJ3ևN[0#,$l_L۶(Kh˽},{XjnpxthUf6G]7|~/O%#L=H'z0ttMKBL_@1RL3c v m4ʲAQC'c!2ۊe E=o:ܚ̮R>Z`04j:(C9 闪*X`Gv*ꢣt\p;C*_`N|qm@pym"<%pL퉈`s/!;>v#MvG˽=f3 :}Qkwn6X.AfQ"`T rRXHT]?!G!>.YTM }цj2>)mMV를S rYJ !,dEU`٦,eC j,ގ6!&(AKS1c+ s~/16B$0uxPYRkl޴9N[x{yM2h竖R_@qE^"aF]dhdhD *9:9f8q6Èۡm^΢(+4"Bb~p܏cIJKL7S ( ΃'A"/F }GsN햌2Y%f f5f}/qR`X tl[%UQ sJ^E`"rDžvt葴Zz߆|Y m-G#azjFыUuݠ(h"$0$eDBQ4]N#M,}\iѷVh;ẘk9y-s4`\%i 0fE^wktNMw]0 NkD9lKpboa]Hbd_6# O{Ltz̾l;.ɞ*T)Zo1=8rIxeQRE]jn,CUo,ݸKU@DPqc9_;lk\xi'T lTwa4fefE~MHeѷ~i-ʲ1507ưAȸ~R?{%{):R.$7(rL3"D'2bzb/$J4[48-os9|36g|춻=]ID1Up4vS?\bE`hh"xN`MCgwǼbFI%炊5ŻM),+HSgpM3ufUʡZheQ*u6R^`0Ee,u;pEY!u=g#&h>dQRr&CCNz"Ȯ:حɟCѳp|}>><^7t AC$!q +g,)_ HZ<(9b#L\>Hȫi[IwDkys!I}˽%r Yh1DBPgUU,ɾ`_9>oɮBj41lDM{&15t ZŶBH, m}LߤE:eUk+7q oX=|o? o@H 阭k=oue=h W$$="R!.&mExĤh5U{kp_Β6O]ѧUUUmglH+q }Pv}6B-@Y*(#` 6pu0hA"FYGm$-J{Ucj+p$%&){* X}IJ"8Rs79n|ݭ_~/jc {zRI-Su YG.q8"Y9/`~xP)  >}HN1MIWpq-nB6LaZHU`6_'/FxXO*XvZ&`&Ld ӪDɾgШǷ(5hК6bqGs&cs] 8~-ORNU{_x8t?c0Wэ41N00RJYN`Y~:_p"&)-,a!!8 JA4odBGl `l4dWɬ J 1#YtdwvC)$eTB`U8WrBJju1dE8`K fDX1v% X%*˔V8:=lj,L`\Xha`v䀮m7D_XQ(m+5fz&c"n`|+%3}IM4ቃeK/ CZiك>2~d D*Œ ށH62 B',{90cC&^rl:8O^sJbi(0CGzEhuB]W,-XPVÜ EQt^۱qB?=6$8m4adyT jLN DZ$>E]Wĉo93~=C6 ǩd?@Ԧ_*`8)'Wb0\8xDž pWLJ*8mw&$aI@UE ELD*TU)%[h)&$FDR~thHAP4/ ҭϱ;ۢ?z =cxo{/~~u軟0s<ʐFj2`' S>xm1'l89~JKD&Yd<'P7L"qSƝr gΞÅ a􀲙)ZX.P%ʢ1%ʲfgRѣƨ5z-( (B# uiB :$>E!qr~Љ1CXsIbN@>Nba~=cxĽ|ℵaxS۞T x}HNLDXR$FO Z$b*Joz1I.E2" @J謓 nJ/կb g.Ps-LxeQCRJijѠ*R\l"ﭷp֠P+T5lǴSe8 ~YU.@UUS'Ox׻~%'ox{߾m֥PT$ 0Yx5B kN- 0q0:LT(ZSMI-Cc.H^23HlGx{?z +4׷eED*aіxD?x3%k P63R TE(X,[Fc洷c2,_ ǝoٳ6'oxȶk|`-+ˌA*$;>eQ0zZ kqD$p2J֋c_zW^u *$){ۘl%5L5,B=y AA󀲠 A*%C鿪4 !";H56&¹s==?zrx ZqOs Ar+."̴Ko1AE+x r uu %9i'ivEO?e\x'O]IF9s䇦qT EIȰs& ЕA #ɈaPX*XkvXW9LM|u`aljFo"' p 7-N6 ßFP rGo>I7p(D>Ik]qGy^HwZkE/3ObۢYm]Uݠ,hWoh !OŕP4w\k3`r P0#3 #K;&&URKU^u\;-_n֫} c~3%%c{՗bRڧ"$ /0Ṳ*G8 EDl`OllQ5 uEY`4늉Jމ82ʠ*+T(ULVa5(_R+GC]ՈH$\R到 H|&ͅdS%cIDATfsx#?]soquHt)T` <ű5~re+ {σHnit6lN kl8ёkzAߏa.}O^T(+pNuz45[I& E HYJnxdtǑَ4Á )oi6'IL8^9N[b6_b6*k = %QC? q|ly.$fMkoxM=;}>rx}uob,&A>)p(]Eqp{҄ L=) v҂HTcu6Tuƾ^;i4#!i / ,>-w|&UY( EERk G"#ihm%iG%i<@L~1r;8lEfUdSW.;'N-EN/Ccm[ 1iÃ1!$̽ ⎡s,&fiiB'7-oxx-(dx^lTUO>=eYYӰ[kTwڮ}ݥK=Ïl6뫵1Mǻ5#.DYz [>p#H|D$@(ئm1*p$K{ `Wƞ Mlsozӛ.n^q}3Zw[cξ"E_.G6% Dl)$bd֒^6t8Bo֧Oy?v^u~3hTPW%Om0`&G~ q8, כAYVMJ8T[ef~rG~z}tkz~:~0 ,F- of죧N]SO~g{WGG?8mv9ІA7l'~ ($`Q(64O \1 ~ԩ|!'_-Z{n{OiOSĥ1 k%Zz bг{zꪫu?+O|0 ]tκ]Wu?b`7_`1P °Dޠۨ%+WeB c*ID: -D3[b>[r9o{r|c_;f*-_I2Kh CحGNxӝh>s{駾wݼ뺶Fm@4 4  K8k0c ˾JI#` nPW%˽3Wo >xt3nДeֺ'"xtj[,蟾W;>yJ}޹lmw?; ǗxTt=ra}?,KsJ1uy@w('>sĩ~M7ٳ.'/x'v9۶;5 =Q'H bٳ4/ůH|媲,~n~z)<J+H܀ta@PF]WAQJb6bwmZrȑ'z}qaVBQ8n *%4M,t;w~C|9uGqtkwhoڜ>5EPf濴}w~#ߌך@xc_?88gy檺鬻Λn7pe񡫯W:s9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ#G9rȑ?uT4IENDB`PKL@dg  -Pictures/1000020100000124000001FD98C71D70.pngPNG  IHDR$ sRGBbKGD pHYs  tIME 5'%!LtEXtCommentCreated with GIMPW IDATx#f      g  z  g  Q{3   Q>p    g  =f\      QgG    \      q  IDATRR)       >f3   q(        zg     Q    ): Q      %"  (  # (( ] %F; IDATf   &, ) )      %,]           :S!     Ϻ 9              q\          ,%8#                 ;{|U IDAT             '    #$            Q(          ($ & $D 6        &" '%    A 8           51   q      30  pp )p          D  %>#~ IDAT          !               3(#(\          q          &%  pq)     !   -6!&  "  !$!    %  "<99  (" ; IDATz   132  ( !*    "   ")!$             f                       **         5!b IDAT         "         (Q $$$           =         R           fq\                       =^X$ IDAT         R         fq        z   )   R     #N IDAT                = f   )R   =  ; IDAT\                            =            {  &&&      G (((        """       "%"      -` IDAT                                 z OA IDAT                            (  R   #݀ IDAT                        ()&    ###                      v IDAT                   (         >       f                        3   $.    %   >4;4G    "        - &  IDAT   **        .-       2,&$       -)6.         !4*   '%     ( $!    ((!    +#  73%       &( $    Ul IDAT 2+   #  ,             !        "    (         #m6 IDAT    (   )) g    hs IDAT     &2   # 55-0(%  1   #                      ap IDAT                                             ;!      ,(      &(%       "%>6'    =P# IDAT     &(      4, 3-      ;2'&!   =  *$82&        f  +% @6*,      R  "$<2(5-!       2(93'0(  $ #` IDAT PD8          2*=4)-(         !+ 7.!,$    &  %A9,6+        %   &%,*#$!                  Q=)            4+         B H IDAT                            ('                     (           &)       $    "   )+     //   "//&  "   ),&     #., 9IK"#34,          &&  '% (AA ==)      #'  ,*       μ  !    $  0.7'%))+ CBF    /. &&&[3D IDAT      %"+! $!=>8          !-." +#  JI997         "        '' # #%%%%553&%()$           44   !&     @LG... !$!""+( -&'#        35288      #-+ 52                      !!  * "#.   &"       #"     +/%  *)$!!+,",&        '* 4:,   ף3         )  $#      1*               7^.C /7 IDAT           )    "                             &++/       ! %$453 4* !%3A   GGFK          &&.1>8" """   55??((.                  #          (=A!  !#    ""     3        ") 7;'       2<)9@ 921!             /1749?DB:),         " # $ _fTTVa'*) CF/2 -8991 01+%   #   U IDAT EC:$$% LYL     LPG4#9$+! )     aP% ,..Ľ !"!! 54"    !    $&    $ ),0 0/4 !!!     @:)&+    %  *#     ;8'91&     $()1      #        0A%"       ()  -(#)  /06      "%      )*#          ""!- "       "9F!   10??++    ## !"-,$ !!%-.                   '$*&#    &*#   HHHKE/+;6) )+ /6&   $       #+( #57*(*$" " @EA- '$$#      %  )3) , NJ9  %,(%) '*'+&( 79,   ## #$  -/#   & 720*   ) *+         **'1::    KB\ IDAT       '$  !2)$"        A2,$ #"($!87<         >     )(*  '-    0B?CF7 1-)(       +?*KIWUQEMI<5-      "   $$"      3    GN0( 41#?5     1& 3=xyXSI?A6 B5/           +-:+NF'?8'      &#$ .8&$ H,'          *$HE.;5#      $!VA6 $-A`T,$$   %  2. OM<?;!% N9/ !         !-$F@251   H8:½ )#+%$    o IDAT     . $+ 60!'!   ) 3,  NE(7/        q   / =6#82" /"F20! 6(            )-+ + )!61'$          D* *"F3/ 1/; 89%==.%&-"     # (&40      !?#  2@F   $!$   +8=Ϳ %#! % 91"#      " ;  $   !     $ $+   ,&44      %6C<B3,   ''#(          9,*&   '%1 2,)   %*)"& !$    Uf IDAT ''+   238   !! 848,     2#' +#.$!& ',$)+!   q  54;   &!5 ;;/)       '>" !/#)$ JK &%.  z  #$ "":9=6       /    , !" %             124905 C;A8   /77 00 LH(     *7 %    ',G%%#=@:2       2$̸iouFH=(      24@@0     81."(K:&  z   H=#OG(  !  @72-$##/!# IDAT    <<+=7$  "/   1'  ( -# 3+   #D; " P6            $  ':3)"      +,.#  # z        ( 3+         ! ."#         1)'"                 :5%         =[ IDAT  #  0' #           ) #!#   -&#5-    !" # %$) R  ! '   &      +   .1 "      "#     "  &&$  0(              &$(   !17-GKF=        ' H=D,+©3% M8!  )(&867#     %%%   SS9%!      #ͫ$&4    aY IDAT "#$       (')*    %02!     ' $&%$XVY''   -FHH#5       (   "#TU9   ÿ@I     #4::       >) 40:7(   %% '  R  +'& 1(   \    (   *"    R  &p IDAT               Q                  )      #        _+ IDAT                        (                !#%(      (  *+-.             "   R ##% $        .  &'0$$,      % ,70 0%. #&      %%,#  !%- &          (1+* #                J &ƿ    $#* -    ,,("0-  IDAT$%  62+ &'!/92    p     ,-   GF@&&&  - 0,*,$ !"*+(    !37 G,-        $%    $& "   "#      #!$"307   423 :7!)%             KJ?!!9'   $%/&#$&           10&!    G5'+*          "   &$ ==     Ѫ IDAT0.B  RR         -,&          p>     %            3 35#-         !!      G     B IDAT                     ]    p         *)  $*"                    &    -    g             !2  #=    :;( IDAT    )=J101         %"     &"!!   3      3.&     '29 ! $(       :8'   ,*0           +"&(߽#'  )) @A>      # *&     H?8+,! ,,,!,!       &#!"#        ,$-      "     (" IDAT      <"    *!                !       ,'  1-9                %!    !!!             $&#-#(&     '" "     2-#D@#     " GI;  &(         #  `5% IDAT    44"*            *    "      9/        /&         .(            "7.g   $$$)7$            !6<*$)           #7 G  "         񯳰 IDAT +(!   GJM(#   (+"   !'.       )-8       ,  &!$        7<9            $"       """    %(           %#'$0+' ( %%#           $ ==# )#     (((             )$   $,  #   %$  ))! # C!C IDAT0( '      !2=*$*  98@  008                -      '( <8!"    )          )  $    &($0&  ?@    "/        27 52   %! #          $ '%           $           1$ !!              *5/'$     +-"  ""$ q   hq IDAT "       %% 04D<+                $$      !         '"(@=              3  ]O# 86 )!       &$&!NL5                + ' %       #1"2)*% Q    ==!-/&   !#22('' 687#"&     79+$־:<3       JKFJ0 9;23! )%        $          >@3BH   OR3),  +#         - 66 +'         -.+,0  -/%*.    k IDAT  1,3        '!&'          59   f           * /&           ,/ ,()          .,/  %&         )'GH(    -    %    G)     (6&     ,,!  ::B# $                         &(        %*FH8             "      $$        # f            '                      45,##01!                                          &          $       "$    ER IDAT     11$        ! $     *='$ +. "# '#      .A         %        =  75ľ 6"%%              "                             ,) d"+/20 VR";  013"  %'$  )%&-15       9              '#  !   11)'+     $"#                       'qe5Q    &+    &(        !    #"!"  .,#                              781 ))+465986 #Q    &P0 IDAT   % #           437 %  36?   *,              "  #!#         "     "# /.$              301<          "        ( ()(    !#A>5      !      >?: 13. %%$  !""        Rq  % '+                  #+ DEA  23/HIF          +0                 (*;;=7 /+      o IDAT    $ $'          /0,>@7 ))1IIK!!"HHH#FE;   f ( 63*       #     $    -/       {!'1  *            ( &         =         "        "  #          ?;(  0/ $! %                       =     80'1/)  %      +.1      &   6('""("?  MJA +*"31&     & ,- (#   ' ()&           )   '(/    YR IDAT!     *           %%%  "               "$ "" ))                  G         % IDAT      (         3         # )l IDAT    f  (=` IDAT         f     Rw IDAT   3 $&(           34< GK@%$<@ &9<'   "" !!#+#                      !#-( &!             '4 $"'   20'              //      +TpY IDAT    ('    !    !(&,(       "%              IF&     =          " (                                  )                   f  !    #    3                   %'2$   $#            2 IDAT        !        ,   4  '     #/#          %+-(#  $&%!        '      "         !      %$!    + &!    %+ )    (,  *   /2!)'     $   {À     9)   ' #       )0!&          #         "(  #/"          ,/'           "(   * IDAT                                                 &%                      ,         !                               %&"    *(14.1)'*       ""   $     +&     "                             &' ! (       %'      E IDAT   ++        "))  ')R    %*-&   %!         !,.  '          '39  >  "  #         $ ,6*     !'$    !   **,8.2(     (G    "7"              "!$  "%  #       B("   #( $                  "!%  $    "#(-!    .   '                                )$   z ؀    "!  &      !$     /71          /%    0.          Ap IDAT  +7             '.<(     '6/    '(        "     (=6-    "          3=    %. 0)  "       "(   57"     #83            .7+    #0* (   %/    ) # 41"9=2/ RY0  BC0      12   "  03DB> 560  970  #  *#   DK+$+        #)) >  )         #CA $       10-/< ,+,,) *)$&"!  "%'    =       &!%   ,)  "' )  %.6#    %% ./) 97$ !*')$       JL/    )             '$'         " 065  5JG ':7$)((   >"   #3            :8+4/PM ; IDAT            &%  $W5-+           KI((%      2.!,+  10      !1/#(    CA )),33*ȼGHW  ,+--        $>D45! "%Y^     %& 5=%*222 # ?A!"      $%$ @B97C   %/:5" TO.4+ fg_(--S IDAT5 >C]^8 , @E  (. 64  6=7  "!997 "!   43  J- +    LQ1:   :+8(#,37(0#LK+ GB2!%!    54 %*  &) # 233 &15)99*    EC@,)'     )&"     ,*0     )' SOF$& /.,&%-*(17;<    )   !  !Ž &              !)#4  5*KD1%+('# GNREKCcmK/4 =A0>A9**'         $ܾCC5 :;;  !žGL    6.'& %#     *.!Ω       114;2'0/1<.      z&)7:'D?5 # 4;/99/ --  % (DOP&$-  *0'# ,.3   0/  +%,7 -47  $ Ŀ  )    "=9!D> NM3 48 QS[W"%.'($:44! λKA/̻GM6  &%  !$ 04-/-E?7;804: 32+*20$'   #R /,% $ G>!LE  D8@7   '! ==PKBLF0ʾ&#WQKD?  3)0D9TW;y IDAT@  /4пGH16 2'$     3/&   rhf'(#M   $ % VJ#.% ***)5#! /# E &  KB3 ,)"+'   "MB< @EDJ& -' \&.$/- =D 37 K@ N@ 6*!   0(8*'," '  6*'$   6( + >2$               "               $ #"!*#2.. 7Q"@T              !   " / ,!  *&/ =F9 "- QQ9      "     5M7L                  #               : IDAT                  )".10"###         #!e_&/          !              \                                   #!          '                       550-       6; 1 % '-0/" 3!(n IDAT                 /3          $  #- $              &( &"        1564'                     "        25   ¾ &/<0   CV-& 8 $$              =A& =E # 38  hk*,# D@&&'      + !#+.8       ;=/JP    !  )/%2__5ipD&,FM FM9A   ,-'       ). *,!   ! #          #"/6J',&ſ4=  -5++' 0: #)!C  []%*4  *++B@:#)   ;8  : .$ #,$  "#!        &&   $07+. ;F)[%1)    ]`J&0"  !  "$%+ !   %   0(,( %    +(%#          "% !":88  ((BD"$" +2 & Ž33#141 85ʿ0-2.1UT2Ǽ)(#!" -* ʹ"4  #     1#(&)'   $!#  I1-(  )$'       b: IDAT, xf  JE&-* ;8 51(  XU:6NE&')bX8ϻ C:)*+&.1=< =;'>:ǟ  76 <:+       %!   ## ##      ")#     1,)$ -'     !  +(  *    MG0 !"#    20$ 74"B< &""$-,                        "          ):1I                                            G                    p                       ʵ% IDAT                      p            g                            3"u IDAT4   % p   q p    \  ]  a IDAT   &            "        #  ' [ IDAT \      !   ,  ! *:?   \   "H ] (\ } IDAT%    $    (  &-  !    !    %$,6  3   $'R!4    < IDAT   %(3%  )*:   +' ] (    H     = $&&     !(+5<#(.     GUQ*9%0 fߙ      *7BV> ) IDAT  ,19:H4  (   #,%-   (     # #    (gp  9-<4B QR\ $,5"+ #   6>J{   ( gp   "$,$2  *=)g jXVIDAT      #)1)1 ( ff3   $&# #(.$) f{&&&  .,-&(& "VUU !%" $$$     (((=))(Q  W=GNbIENDB`PKL@ content.xml8BsV;B?ʬ9٭\>;kSHuIVRDf֧yx_v_'EI"(W[gH"H: z-a 8L7~:M<\lh8{~ixhmezW,.WzmvqٛГ]Yw ϞF_=ٕO=z6@h3-lf˗/ YkoyyjoYnefefth\bOpuhFQUp Eq]&E:p0>O/FӖ:fSBű` ޺2K: g¯p5u\AE gcj˹MW,`^.9 0Xw*Ъq#۬Fn Z$!CWU`Wm=BjrOf}0zDa<|S2NL&~7)CxYq鄫4\n4a=-&Xج+7'r6|qc"q1~4[!n ۂɋw'6hdxUz7._)1Ҏ_P"mC۵1YiN ȱg8M{ZonJm O+ Jh6lAyA/=3J&Z \xY$G׏ qhux4'[6xv7ïЂ*G.>`.E9cD^?t4ۊ˞Q\*5t")J1E|;G_T(6rneǑbL}yh,hF);pm6",'\\ґU6Kj{7+ou6|Zd6]>#_jہ0i+4n) 9yI&5ԫT}EALgzAj9O`mfk5s7\zsfxJj=`ԇi3cw6snu/yiz_U\m}ix|Oh64<'49WwhnGloO{ {l+dI/c6]bM7ѲQ]ȵʷa}4d4i~u`򵃴z.RO ׳ymƏ}vj]M0l+*o[v&}v.ÑUnV!Դz*.MWPlAwv29HQ9 7Dd:G91"ȅBd 'A\wi:\CmC$\Fi,Jpn̓x*rJ0 λw:ugZ:4EqpnٹNa|ZÇpbx! 87YCo%xŤtD'ukwA:ϧyz,G¼}.'ux??ڎOΪt8}+s:]Fya_/T'U'k߭1uP ^[/M&Ql1#t4D B!Qz|%|g3rv|lfkrOej^PH͢+s jWB*ڬ"5J?a:Ümo7| T.{ u{$&ً8zDk^_ uF@_]_}ŗh® 7h_D}c}Q}mAD}65Qm8_" Kb;s4o[¥M?~m%T/k7wz-u\ ލz|t k~P>א o۽Kz-.E&*gY;6Ur!&xgܥ pujx7མc\_4~B_6 7"D5x/||M_4F>8\em6e:T^_"!Y{^o49wŬsq[ќӗr:H/L8y Mo{aNdoEt=m\ t?9^ ѿ]4W /fy olokjA?>Ww)ةtm2L{ Hr'ċC9,O0ؿ Pus{%KiNkґp "3ii.M>)*68QcjGQ\F/:]x}+}sc~ ?CWf79ZDkh0;nƠ/O: %;g= *rK*h4El11a.|8ZOGh+\O ϻ΋3"B'I_[oyj:UB ,Y Xq4_¯|?O[[D}"uY1]|Lr^iBhwҊY;i|l~hHKGb;[-6C^NJ^,3]4tWxIvRyNkg'7Gb-<~m;b]1Tm'GyrB)fPv ' %K`GyXu}_GV~P\5+8{jCG=~GW3͝th|Dh srz~<_yK jo}SoR{O{=jBW6 * <Ӡ+5 um\ 3΋}΃'GbxWB5J]Db%z-_h*3温Q0y?x.b|nBsդ ]D* l]|ڲ_{\YWW^må^6]/.vgnWHq}hEѦѶ]v 7fh]Sj~wA>! Om¾іbm[\] 'yNǛ] ~-֍c7h>Z!HF* +G,wO3hAr׿I&߼.m;x~6ri$/øda =Kd澇9QIyxGm/n{i|М<Nh^Dgb_d RB3 q"RB3 N>W3 +PBi*ޑep8Uo8Ca4NSz.|˿8|r&<Ұ!AA&KZ+ ,)=}6I?&t5/<}4~Zb%X&zH3p!~pZxXe 1:vgp:,&g}uaNI2Mxt@&0NJf-.< P0:Lߴjpډ-ZM\嘻2.n. 1jd[rk%@D.WVΛK'N|!$ā{9{ Wx=øfͷ >̡'*eR,W | $_Af2L,Pk hkg7?C)>,1JSæG Sb(Py8EOQpv)|9h Q>#q$i6w埃h/Ց=q=]|F?~޲G eL[>r#GjƂ+A 3+CB:h5~βOÉwQrpݠa"ӯٻ)rSѣ+=z%ƫpXE"VώՇZu߈BD!QؑyF "D |TE2zȪ`,c8F"Q/Ol^]H5-|'Xق@. *$ŧgpom~ @x =CNOmA3g3 >6wڌ\Cج٬H|ǜG>w0¸%Yt6+oVoV3\FGT_o:;b=c9od$U+x?|ih|1c=m:.~} Vioi'7kOdxIOM]nx w.D.=@h)MCd\K,l c%aF ?.X` d v+R^)O熏FqXN~7l- ?  %QбQ1[G*jj:6jCeU6o8jDo_)~Cdt?LJGh|Mz?sNX+b-fJ> 6םEMwf9sϐi%t((ٜCn?UUt&\/ B(H\H \މYKFe 3x{q&K~O`<>l\Yit$(\gnXJdzzjO^bŗlT'Y|%l$CnzڮJ&K(gq&aq4}E_oK6vfW{w;F_I[5Q3[]4=+\f @ъ8(NF_{2Hzc*Y %0*ڭ Nv.B׼]G_{18'T=WDIc|e.i=̚Hp$8ՁNE%̈ QFweOWh5|Vߢf4m7.lڸ|Gb›$N/ (T$Iqw4[1 ?>eGDZ6 S e=Ψ/pW!_z^*|^}n߬#T G/7mYma{ vG*VBؑZ1v%ꖨ[n+ݲ碙]qfDK}n[$fYE^kyKiMX+kiM;V[-¶O=12N]YMO|E9[}[Ap!\NQ\H.$a~_d %rt#އ>'7f;Z\8 ur@hG#/ g}2ׄ Є&4!̲fBwqحwbhao^Q+*a5 LaӄqDzl֮!6wpmCJ(JeZ 6dP%SxY[[95q1!9ZkɸNNF2͌:0TI9&JS_KQƔl0 X\3x N$p\ *>Ǚ2izx%w WW˻Y!| ûzj!0F%P)(X(Ωt@jabR1@2GVa!@y.ڪ< PK_EJ]fo4QWcYe,'B8 P/ (2!-Pss@WІpy pyB RĘg[M:\E,*iM"xb~Ǐ#/4mY *e^`5 FAb)RG.(b5!rGcIzn%WP'Yxzj1RX65m 0nôT(B]t:6K -K2RB%`2Sfd۞xRS ?&&0-<mK8!{ҿT߿~VƓH)}JqvUtW,K78ws}s^nCfMLN GT̈Ncc(JI=(EFSŝ+UPpÂ@YWH8hJ2J+8c9;:3ō+XFaC []L+. vvMpc*&IcB1 Wjgʺ+Ӳ@v8Գf#DfmƻZ6l^so3$+07*0KΨ#yB5~ $Xr}[-,`Ƀ;}v]X8 z/Z,@UnM<{sǧb448bB2Gs$(. p¸MIjxߝޕ0yŊ_ 1P+# UEvڮJ2/c42>DLmiu[mƬ2}}ZoLzclSpKR:_zO0~E8m04ڎHch4 VTyPh*5E["%ք,mV=(aw #wԽhAO]eĸ4"EG {W(pW( `F.޵8E_nH7[3FW/89P|f,وerfwYrWB`vxfq mㅋ0ԃFS ge:7Pv ![PU|QdXA2 ;AQx5{uXAz*3Fc2Ӆ Oc/v"ѱ#\Y:ѡݥ8щ,; ^v :S1ᲀpu?pD8"wךf(2KBYqyLz!>>WШ~hyh[-u`8on|?7u5y:G'rph~nTg+hnGs;OV|vN-VuPQCE 5TzGsmUxas#nYG#ˑog۲Z{q:Y?gO֊߳8 *i{63E h0Gyk4vc[}0@0݊*n\\.zkgqy(3 |e[בo7UhY 'l_?~4٦\—t"gTOa̱n/:6GƘr96bs=Pph` 5ޏ2#Eo*@ o::QU:QƉJZA[]a1M<![oi9D}j=k7"WCщ[\eE[:y4D8"w}⎴29%\nnϣN4d82~a ?d'%en A֊.x#Ǎhp#1шhka}hQ{ O#I\m\pA{n8x8E/?{^~Yp ÌtC!vMLޭb7֠}Ma5侵ۯϲDA^J%l̤nPju%6/0\[yPr)Nl W5&BKG+\sjebBrи>2L3c UGRI!R1Ճ!DBe9; e@hCD< T8s8gʤ"xِ0kI(EVB;K)tq!VsAGg!69 A! &E C=M#4\lh;0]38j&Ka"PI<>}v][:~gcr6 hh9XoTԣVnGg%oƜ!]1Fth>o9 ʍVDt\:'_V~к*RɀDUW.ėjRjU ~hGHEi[bLjTnAscJfk:,L3zYqTυƢ˒X];@t5жۼ`Za{ia(74KZ2wVɅ(N+-.8ΡN`#aT 6og~(l"Y٪ P 7alKoTzEKwJuX+U5z=6o܀zva ɪ߰a_0Zͼ-]jըm&b9w.R M&5Ytk,4)`ͣ"@\=/6T׈b1m B!xc%T4jH)KI^aO yvy1q#&nč[24mEoMwo+ѬOͪfDz#H^ѻ]4´<(ޚض7{çIt=d82 Yd?a~-Yހr؀G#ő}xo,ތ烀Pi UUzwCTT n *j@*****Tz?VvœܻW9:*ꨨIGTNN%M%=Wi1LG\pD8"kATup{NMt!ɑH #y_Md&[QxC!o[h\G!n[7xC!o7 v)xɦ# x޺ hpC!7Jt`چ/&\½#\.1~:WzN ƩG_佀F_dE~۾U-M{kM7Oh:۩6$D HSisf%Y@=={1@!W&o$ьWXꀤ2p*024D kij3f%qcS w&h WDi)W%)/='ٍtƯz}7ztvrm8 ӇF0;)/(˷V*0#pR}7@V6ߖc((b)tꇪ 2ʠ*sam0 0[M@X,19Q7mh zPS1#JY=75@#iD LcHX =OKM G#p1y 8HۯVKb*9'ܳP9Kygh~|G Vpk>RTKp`Gf 1Z2?ZaS(SN&Di$XCUcR45eLi`4&Pp,3B*@"p\ *9S&Z~]s$3&y K,Y ,\Eǝl ]/azt2]o\?G\x4C$gL/lؤ.5LWei! &h0;0]ِM4ZjV?Y.(㧕) _x1n_b&cuӀfItXE'MݸU.Ķي ]KUk)ȥ LeK$S$['<SYU+@_gůW=Tk:<-sdh{ [=Y.nS\OK7O~[?F_ w$imd&U)2u#opxUAoPīI䵈ԧov?ɳPJX;#%(x"@~>R30XwVE֛Í5B {ާSVhuz!lfK}bΒN^WEƮh\%)cP^-VT$~jB-_WՕ{wEu= L `. -E}7^5 L*D[KDTI¼rke) w۟KbDpvjڪ]2Aۡ$g|xxՆi^LH [ׅbOH {LH Ѐ7qA}[NNF6!0RFzۄH pD8"wH pd82~x:lX0RFJ}< 0Rɑ&k7s)!S)j"%PƇ,°|WhXA4WcB%֡a0*怒j   G O&cɧWܯ+t#^/K;\+,—t1wf3NOC,cٗ 0 u=,ĂQr)^XhSnC, -@_C,mzկ`*Qˇ!/ӒEL_i/Yqkޭ4a45tuqک.@Pn=϶>:4cM0YoZNcp4߿n~Y.!nh X\B+i Q?b4%j4J {6UPą#]60 "|4gc CtcT$A}CT壂Gy *ڌ6a.*-%A\htp8mӆ{;Q'n'~%wr`r1e G1> OW3yݱ1U|hS'~h^'9 ,vC.\h1{3j^Ii"ܮlj啇`֐FmfKC.>Z?ek7I+s0̶~4Gމ£emTãipPpg/ŝ}t~ã!How]?hpD8"sf0<2 G_Hxwlz6 ãax»0<G{h9FUAL-׷.H͇G;Vxf^%D54yC|HM%":\4+!7DiD'Q6at6,+ra,{LeBdE=ռzh inݯӈWzWSīL˝{&"%mn[Y.:ՎƠ66bVFNb n/S؆i^^dژ: ΕY7A[_߈e.JXc.JD?bu9gX]MWK`,֝RȞ R`b)47/61xdj *&⻜:'[>Lq1wt;|zJ}0_/5{VzMe[X˗^;zg[Oa>̡|ٸg}uo%kђ='H_?G#6=bwGzǮG:;g<W#SgN'.GۋlV_{W8SڃAc]àh5-Ft^Ɵ 5 :ۿnUo~hn',?!oXlߎ[GD wc~7ß^S!H)ܧisP`!ݑHweѽ]Ӣ-|4^E' n[m;%u1m֓tBYed<).;?O!WG:pfhy$俭B#y׎摖 ǚ8LrJǛ 㠎:Nt[OxHxIxx?:ϓ/qa-Нa^tg GgZ*u<&]ʗ)O>L}Ȋ9-Z,- ]Am@B$ S-#?5p5Wˮz@u;/o;ZzSԙ7R~Q[&eA/r' H v^Gmn:`hȴ:x`OmóH & 8axR)WZNF+CUFj$J 0>3ОDwxC!Tp]I4wry#I@ zA1! ֋GAX a蔰 ͅh.Ds! h.lχr==B4"ƋC FD#"9v#FDㅡQ棑#FDㅠlFpW6 dp)Gu!vR%a_wD2  lSOTOՏzz>S{v/M}yޣ),lT j㤀['_NCN%>|xv?6'Н[/|6=58䒐.=9Bn/O(jND; ?&>;%?akTo&*^勷ywx]phT9U/Lox4b{]cޒH BvhFCM(8β +$s{7]C0-Ðʹ0BH1PLz|(a'GAXRka00yn%QV\6wu-Xn? R&JPgs0'j)UuߊuX 0u(:b,^\1pxɁ! ,us7lȠN-0aucCMJ&p8ް:l_Vi.M4j4JVZLLfXq#N>^6\E^ĵ4/N^ UXr1&8o Nw}OnzЁhсΘF)md)mq8bs׼`*r\{Lr5iZE`q8"|,#|,|,c~>+ci~zEҚX2 EteϤ~ob~Wi]{w\9&wSkn7okBk- M=6c=6csKجO>!&m&ڱюsC;p)#5HxdE"Y/&}_CUu }~ 1Ҽw.||xKM.PbsLwnx-t-Mok `{ qZjV㴺؜/R[,A b0K A bma0KPΩA b1 JB>H b1Ϸ# /QPvxd7#D?Fb#_gKffd,ć"?Y;C=dsUeOʚzQUY6~׬jEUZ^Oڋĉ}BJ9#[8hlj. z^;]k)et J"k|3d_[JWk$JW eG D+~!k]ķEQI“~Qز2`c "(N(^!\{DZ(;ٹ \xflPմ%둉rUPO^t^lM(ǵl)#b媍}bì0.+6\2`o:+bˎb*i 5ڑ &BUȠېȤE2\do;+3vgESFS=k4fVJg,ES;fX=0"RXea>DR~!L~~,ǂ~,Q7'Vͪ[E$]byaG#=%rNLXE"VUⵥQ(DA<#D"tϲ?Fjk$*DM~&دgxl$߫9jΟ]͹$=|z| cΈΟq-[b;;[qp 𦺌 D&ꚨk}&z0XCigRh0̉Ԁ6o"v+cdue-ЊthМM׺ Vr@r9m\ vm-=ntFf1W ed1m7o(K*F#IhэԶB`==;#9<(1C`iP]ŭ.| Y h;fH~W|SI¤4Rj]vL[}:OplDA Syb"BKrZↆq][+6 dǏ#/xO~R%>g}8YWl6ZЕP -phG#~[ϊAU F "a@;懏JD"UBCd b?E UN<{#i~MgPD#p VWW(F+HPrxmEPw h rfJl^b͗zU:h~$CaGx a $qs-gq&"qI/]d pVbێŎ-LLzIC>٦\—t"sSt?{ߍi}7_O.oI>,0U>ӯoy8Xk hk"l-fzz( I >k g8C}jK0@RxV?ÍynV+J`}.^XET8D"{gAD "٢HlCج WWjªVqb0r\읾yN 2-b1D gLJ*+nC퓒mpo 2L))[F]\D.M|)[F "aŦn0iHU*R';湅n&`왺yFÏE"qCyewSLFT# ˻΢!F:r9D/7wk-S2qsyD5Q}UI%bV< ۈo(+l<4C`# J%ץ4nVh5-ZlFﳌ&j3b&6@ccZJ븎@vOG23m2("h5Q`0OR~IAct!RVTmI("3WR=__gůW=v:<5$*xr?GR\<ܤ4ΗNoƖp~NFpJFOhROo)e.͌2K',8a [KLߎg?wK 0A b7մ /a0-]&8cHUP5wnXuOnmu%ޯy|-F.3\&U8%z 1Y@===Fk+7SbNk\իA# <'Gxe HOU9J8|fW.z[V[8+-bwY/db֛p5L">1=6$'ĝߟ8߳nN#nrp}Na1q'2-oK(6.euD/|kfJ34- ߸}TrpA '.z2ZMFѥ/xu>{75\3`Cg>ܿE g8/~_~)mO[~O' ]"[0.R}%꾾{(^d em!a3 Y=% )D "{G9>¶4GoBPoj:!*E"rg91(TA b1; -_x}U4aO*r$G%G0"S8A^`D"r0"Ky1n7,K*놿#Qh Զd=>;ʼL$W.`!RVx% uVr "xn_}:wRΦ_={tyZkhZ-UmiO @Ǘ{Lu@εh ]KSi,܎u<Sfp6=b Iȡ069:q`b~4G_fli"c}!̪>V+O6DTg|JRi iVMed Es֧qf~M)}=qi,m{Ը0 ;\ą6ٟS5E##FXHR$)^ɖ2A- E^Al LցmIe2BMBVD{z.`[HTsHT$E*KP(zM=@ i.1q8~ؗ5\D*"zH}uV, E^A_F7+DF")3#Aő@DE"Q/в'G"@kYv$0M G#ߴ!NШ6#Rԋ@eHP$(b;ېHyEhbtXAh Bg{\p߲wh,yzi~MgD(m"/% HP8a\+z{0Qރg5 xP8y_Xef;G2Vy$SS޴Pd~Ch>FHZE_FT[8+Sp.M:>Oӻ#p(w_ɷI4~r9!6PK ZOPKL@ styles.xml]͒)Tr7cϺlo9&N* H f|C/O@P#RHZ w!vh4wOk O?)womXxsCgQd8 Q%wZ8waNc-˚vgroHΔ7͛?1˽mv}6"Tp!I{ነNӶۭ0^jmf;_}:1}X 5&|W)ج8n "0Q`u]6"OξqYBqc;cySbr5"i@dyxxY7{Qc59? LTځOv&##8؝ZvNx. 8HM>{ #Az[0՘_Xq$dSeگv*X떲8&WjPo!0z c}omC(O6}"ez|Fi ]"j ; &uJw҉F@B/w-tf.T0|#S 8#׃Ot(J~5_CNq$ѳr(!t'%dG]ԩ%}ytPYQӮWnӿ/1[j,4&=jX!d :Pҁb(]mf_BP@#e]Mg6ǡsL K,G(T0TaTݭb k!4Cd&{V`)iemɊ.;W4!jD3 އmYDݔoOƏjFg!($% lL}`mAV{} XqQJyK#fk?*>4dY%yNsL(LkZeU볦X%exm~a_V);Q/}l4#U$z]h{o[ Z-V3kSx$)hC$B9CΊh)[ lpN21=*@Q\83u!V\a@i$K [ ,/@~3 .](j2vWAMؠVaO87" FQ|ރM.S|ނT%.qFA#`)>xV6V 8S]kpM@b族exBҷ7#į=uQVAI,qP=5TzA}%(e͖R'[PQRRTF]yje?<ܙgn +w1t(v&qY6jO-=tJi[e4k3Q27;0iŧoFoY@XҙyX!$mbGFѪR`|, T*b]d507#NccDD B)B-W ,.u R)i\JtM}Xr+|}ά7ɀi;[GNRh~;3iKvVU}z6јm :eZj*V^ea (FY{9fD$2T&u&wnIgY7ϴ;|nO:Cht~ӆD/QKtۧUj3l-|FIȷH-ۃ,Ų¼?OC+CcIz1*^HLlrٷ em$H4iۄL;L΍*)c*ft`c6ːVlPoO a|!Ld%uԮa(OWk\ 3z,::Z!nf1=zXR0̢ R@*t~LRicgudJ!*URqUvSךMk&w/ gěg']'>͵<ȦCc9q9z}WVNKM+3Ӯ*FgՊJ-۫UE #EtH+hʐJ%t<-ѹn&ukBX\"6p/3eቾ;ɍb8}]cd7UbǙJƷtpЭV #,OUpFsM E\@Ŗ{n{^ȭ\-tG`;"(瘯"vhoaX/94s BnDiɢ <0fMKRMP_׼TH[KY'hwi ,!'b宁57(6ʦ'U7TPfisvlH͎tF& >|HNj˕WnWvdz;C$B5v1Q !4[n);Ɔtcnr5dUMoB*;&oQwXdg/UeW[:ǢW>q !tD%Q8ɥ##JQCBmF+%RPcRUn3AjylZX)1cu bf Tm1y,bnuXK!6Al b׃جĦ1fd3/-x*#t/֞)P&neBeBeBeW&W&02*W&W&\ו LS~ c>_Ʊϗc }O0 >p >'C` %YW O QZ*H@+}a߿?'Vw }0A(x qyG!T}<wӑ%>8PnUUJ+Onbv2] K43. qBh|3>魧5lچ1JKU;fd0,@%5?_itf\w"",Ã>,9n/=Obc[nSfăE3+{c|eX qJ7jU[&pnGO 2H4&o<=2YSVrfx" mwmr)" (tT"%]⤇e|J/^[y_ 5ỏ=9Z_CZWiDEhY]Zd4[bqvq΍ťg҇DL|dE{GC_=|(ZzA& B,9;dEЬYmy`'arEiT4QNHUQ]X}u'ԱeɰC|g}1~\`%8فu!Ӛ؅?ղ'$#wn;>JG)䚇ObKž)VXgɟyoO;jdm)xii64+j1/y)K5'ꘗՖAk^\3 ˛k=RbV˻k||#^+pDܓyeLE5FyTc sTfݻucհ L+sdάiTak~PNڰY#6FUZg/7/kT5f(j(%lI:d 3u6-gd[O'an Tiago Coutinho2012-07-11T15:00:092012-07-24T11:36:25Tiago CoutinhoP10DT46M4S28LibreOffice/3.3$Linux LibreOffice_project/330m19$Build-401PKL@w""Thumbnails/thumbnail.pngPNG  IHDRd*1!IDATx\SW !0E qkqT_[A:}}ݣuѺ UhE %{%$Ͻ\B!@.{L}~<\VDm`5HV`5HV`5HV`5HV`5HVS?Ou:-d.$<OwUiQsn=x2ӤgX56{9!lƌG@:/" 2R٤Y ?J&6^v Inẕ!ñj]ck VN 6dޭl| >ͷ!slۘqj!u\v(As|[_`+s;y@gծ  W`{(q7O q5fVe!t.Pjq4snd# u_  XֳFkF :T \^0&&@ BamGM7P(@n.s~A-OSP̀ym ۬"? nqaZ)p҆vnF矙z^EEZOBE/mVL Z? RC1gukSwVzU3}@ @7+[|:|h+>SO$R|.avnٔ|R5pE:aXyOr8C)P߅z$ޟu(&&gAgգ?炆G\-{l*pmccCWu &Nr[[[:99D"qqqGPClSP9eFy7P* h=ssӴ)LJ_PpYΞᑑz 6TNi+|'mj`>)ԊZeM8m2TŲ?48ywn^̛_nYԤ^@MU]տ APEj[pkGfnߞ L)vҤIp;cD&kT 2oPHp^gCM|cg7|<'kp4i<]#ܖMJlB=18x`rrL77z{th$c QEɃJg?]3^}|_&ݻ 6tvvڵ+lZ<311ԙ0Q`ѭy{kd5kѮ~'[BShZ?~w)Cs/N?ȅϿu"<oy򬿼gH/10&'8 Ue-ZhC$ Lx&Wa /j箇M9yxY8QfD۞WIIb>H۹yc~5q$7-O ,vd' HjwSY?d![II@V 8qbԨQLX|>ǏӬY3ܜ~aZ?6ҥ ,\q=Lݿƨa8hd[@OXOjyd 7 &6mT D֭1;0M3 `_Cڞ+PgZ)/۷oرݠaņΆV.JCK ET&#uKBŠ D"XduёÇY522~s9tq8vbײ Fǎ6mCot/.۷;1C5%tHTM[檪k׮ P]Ԍ *pqqu%: ~W 3/ptčLo Ժ K}k PU78)_37bE{+ |UOIj 2{xsb^wi%656O * u =F8TqmC4a=kԨX"vwo:rƍ v4n݈h#sOQkuR> 'O8_p;W]_{5uє&/cw{j N dq?ܥnU#tiGFZrۻ]&{,XK. 4wj,2@!An;*ݫW/jÑ"\$"u6m133{ˍL(=}CG˺!.]!7o &f6bv6#Ӿ΀ciڎj@ FNmc4䆘y'|?YhWe -r# [:%uN6p QޡXXqsssvv;M6_z$#,#B&8X`ɡ(N7_&ZT@#LYW%ZL%s?ȗ{ >j jvvӦؓRNhe/jgFGظ<–>M/ner5 BTM"F p DG]ߨ ɾ<";?ՓeXr?N=¾#=Z"G|]jCQ37ChQܻM׸C"ۙkӫY÷>KlooefLo?cl>ypy{ja*coņX(Skd:44ջ3DŽ۵߱=+w:2)ykGIoިF:n'eP\(S9m6دQA9ĬN6vٔCACg?'eT0)1PcST슀֭[OݻPB+\\c|T((>ψw;M6)iSKf]޽2H*$2L„4CyV<)[YC̉[-φr|}gE7Xvt}joZaAU LM6F@FyζT:`Cw_X 1ws9_l̒u$'V2 |iĶP?=0皚pyVfܿ>?99YlH;&X%r.m*ݏ('8..\YxI0형EuF1OQgO&L֮C <,> YydĹ)0Q _-1g;L\=Vdm훶y=oE jmK3hܹrj`zxϔcӭ IbpKֶ}:di9İئ*JiGŻ^da]h(ߛ9I 24Cj-jtn J GЖ0ɓ zBV$p{E=%=MCmfp:ƨ/mvZz޷بTY@V~cg/ӤrM(EnjY(N-Skq/p@B!`J@P*I+sX%9i4aFAvZJӃ;NG)}n{/[lGN2DR]lsNvme8-ng> £^UJѸq A^& K(,jUwSjc:^('&By,^8==sE G,ϜZvCE>r\Us+!$zC3}d5(e1ZJ(+^$XWbBpqr v z5kx; .\:>EX0 ZT}II..0r kPBAA9W7l;vQOm\,^DX*(K%{Ф T-ҾeK!!J |[d|<̥L*m\9aXU$dah_w&|C{bh_h mƇ @甎NCUƸ)aGUKh VvD$}GhX^(3ԐS%4jAk6nx4)ʵ+ts.L`=P2oO+_bt4;4@5|xOOeF 0Utk2+yt/\J,!S,I~M-%@Vv]Rߛ6sy̒N^8pnǨ\]^q9ki}fBM'Ɲցv=+϶ۜ "27:7 xbgggU~ mDf~[#Ig[6=xU9[^ ȧ叵T+/)aZP?E4)|:jbnn.|WXP*^| ʲX|:.u?лr1Xh"Ww+[R S9/P9;g0U(uq(#/MP:{1@K:eSݻ X=uԲX/_,6$_^-_J_0S2~ ~mb}Zg[R=^e&|$=ֱ1u M{ilʂ1UG^)uAV*Dy-] jAigdUl˱~P?>pϴFkYn!3Wj&ŢqYyd)!w-.ydYWyЊ .cBP-%/Y5x4w#I.^K`r ,)>),VЃpd Uܺe;ZwşAL1hlmm鴥>+1=wk>0h(X"3oWWU!`Kwxט@l4PQ<:s; bZrxZfL-,V; ˓;Ly+~WO֧J@$V86i*=hܦդMnlpO2Y[7K>}p;O8fMJ:͍Z|! 5HBa[Ɛ: w\s1QE01eLh$o%xŽem]O7N53 >;dBSLl*ALJ[:d"3C<*CTitF`c@_wOz#x;OOg>v0\HUolql:dH9і9C-(rFDBIoL)Fо߼y1%'r2 TQ"AE# %T)PBebu(b-UDIa(4<[1@[O<}EuCzH;T`vUuKJ_t9T+J!@15 \eU5>vs..ձP~{#S˿j-PM##@1¶F <'f'{[igˎ+A]ʍ2kPH// rp4i e3pd敢!7m(=Gv_<{/}C(y1F r(WaJ2VMK<"MΖJ]yڻ@HJHK})$!fP"_^#ELjHFo 4t 0upnbj:RLyQ[UȾS[y?NibŸ ”u*h]C /  + 20Elqf.#~0o䈽CNL&`jGn}'FCHzh5N(CT=ruߌh) _@Sq ~~'g>^@[lH㳖M ;N?'Rz[D cg:|`>L*1#u!IENDB`PKL@ settings.xmlZr8}߯HQ[[sL&Lp wo2V68W2adoM-!9VW_@%w쵖dI-DdloS_˿}OOh K]z$"͡r /mnߥe3z>h5a2ϻA\.56+m6w9¨GX-gdn^HR]¦e[ 記^VkKI {}?gr S7)֮HBA9)|a!Ks| >Y=?7_u ds,~:0 &#!UVqCVoqoR! 7%>zpT$6f#O$Q;)̿RL^LO3tr)=WEƀ=O>91H9u+мIU[+m7ֲo i[ʙ_wl)bM.cS2?Q]o&=Z?K = YG,ćrE|v">8#eNG}"XR+UA6U&kԓXhM@P]b!\p# >dCqDܢ6x$NvAN;G;| \; WDZH)#I1R8"#>al Q"2)e|kE >Tj c=GpW#qB<8tOV] YK)P:`}v=X!Oߎ\Poz,#(Ca6v󯌶b~^o5 ;L֤Z3պo=:}ҍD?]9E4lH>iy82*y/]lպnMo{w!?·+'jޯ|~}093֋ kԳjߩ[{1Ec[ {^6{|1_`SۻĨg5ށ{oJ2znf5HfŠ2xYx7]̇jm^i؛ԍ\NQ썵Q+NWOcmш/pbʓ5K&ĵ~ Ch"d's̩ÕPKgP'PKL@META-INF/manifest.xmlݎ )ƿNib L~ٶnm0}6=u g{u0k.wW}Ks7w2$C=j2.0;Fh>9pK(^ѹ: HJL4q^(׭t%z]rN8kI/ M&Z5 t= cLZʑ– -іγҊs*~ܭI:,AIT긑i%5NO /S@:i6<pp_q4FjS,FIQV`0Rs'u ҥ 5]Y5K}ð*x1i~:OO*c*՜RſR)X;,˛_"Tuj>lfV+eno_'PKyԨ PKL@3&//mimetypePKL@UConfigurations2/statusbar/PKL@'Configurations2/accelerator/current.xmlPKL@Configurations2/floater/PKL@Configurations2/popupmenu/PKL@RConfigurations2/progressbar/PKL@Configurations2/toolpanel/PKL@Configurations2/menubar/PKL@Configurations2/toolbar/PKL@0Configurations2/images/Bitmaps/PKL@<-mPictures/1000020100000184000000FBD728AE96.pngPKL@8\o33-~Pictures/100002010000008000000080AA8068AA.pngPKL@ϣ[[-,Pictures/10000000000000200000002000309F1C.pngPKL@ -^=^=-b0Pictures/100000000000010000000060D74A0B29.pngPKL@ǍAA- nPictures/100002010000032000000212CEBD1D00.pngPKL@- Pictures/10000201000001FD00000144CB691467.pngPKL@NJ-I Pictures/100002010000010000000100976EC3FE.pngPKL@dg  -) Pictures/1000020100000124000001FD98C71D70.pngPKL@ ZO Bcontent.xmlPKL@ 3 Astyles.xmlPKL@x)meta.xmlPKL@w""6Thumbnails/thumbnail.pngPKL@gP' psettings.xmlPKL@yԨ META-INF/manifest.xmlPK1sardana-1.2.0/doc/source/0000755000234100017500000000000012174204361016575 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/_static/0000755000234100017500000000000012174204361020223 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/_static/gallery/0000755000234100017500000000000012174204361021662 5ustar cpascualcpascual00000000000000sardana-1.2.0/doc/source/_static/gallery/gallery01.png0000644000234100017500000071116412174204304024177 0ustar cpascualcpascual00000000000000PNG  IHDRX3sdsRGBbKGD pHYs  tIME  +0H IDATxyeWY}gyyttȐ Qd29 E%xUDqDD3!I'=wT\u=uػNDEP`}?9]u}p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p` Kx@~L=P} FD!x=ڸp8!ʇ">l$y DDDdw{Kp-XQ(eQ++ [D[z?%Q2FؾODEGqD"ޣp8Z`EI-ŊH!JP:qEv%a?׈XnhW-?#;~Ɵj]صnl!Wat2乁H- JAۢ$j)~>*"s@$ ߫p8g9XA-@e:rK|+Z4k:ky}l"&jI^kb[5lyJJW2rTk[[W sDg3<*JN#G?6p8[ 2y\DL<9 ~K阻C.>}祗T]-Y̘S+2!4V 3A)DDv #GA{g8' _Bywt8_Fo8!>,J xu7\>'OYqI'7-> w]qp_i=k,튍; nuPuñ @_hQ0bTRtܘd:`J摣/Gl,~%뛉ܱ!p8 g9X6 W`+ Oo]oXkL̉E9=Zr1Qؑ:x s3 -o@}gBP0&'1"J`Ѐ(E!ۜBDѣj/+Jr"rhxz/8E{Ċ*QcJ씵J(ݿ.H8X6ͧDE8^ "d yz_<20,"2^LNBdyt#;T g bHDhժ -9E[Vvp5YytLWNmk+z}{̅ҜýB'Wr[K;VJsA5ɀ!;9BSe&kQ603^G~&Fp8 ?e”Q2tX: }CNbJ1O24 TajB $+*2,Q$…slQ<2?^Vf,V#&"JqDj6y' iv "ck AR7-}_D&S #rTaN3beźO%t?vp *caYK?䏟]ƄS|Lg.n|kYgsOw6 #K9/ ss3C3kdH6H2BkV-7 @juPRq 慗痊ĭZn5?7liN9""FDj" AR#/i!l<:7w.`p8 ޿ d=)*8-0Q&D!J#[i%QxZ2!uոMni hRVxD̽b?s!,dXPTZb`t*^X<T=^'Š!X|y6۹sW)U4ܐ/4X7গrax_GɪJ -KkК5e y֘;|^{}u*B5( ժa|ܠ1OJ&&LFPi> /=qg/0DݵT5AKVHؼS"hs&FHUFn{g8E3(u2le^.p8K8X8X}- ^0PPZ8oŠ#|^ \fr[_"qe]lwơbS"u"tbʾPI(шxQt;yE\| {56yx Lr"rb98`2ݘp8XkJ*7E!~u^(LφkCX7 9zc65w׿TB恀mȲ zw31RaCQʵJ: Gb#3O)(=U+ 6yVLFhY+47eo!ycIyhDƃitRC` 2!͙5^PۭjQc#C6/Rw̗̿ZTRؕfҝ%ZDd(yQx JjB0GQ?i`옧q+2+[z p8Zh93^\UBSNAg51[4e)(ZEk/eoo nbUhr@e}o^ɮ^_'댏5ѳW8#:m0kuBHM'b@Q>$Fk5O)v\Jqf2[L-E4-c)L2QVeL4%PiYyۍ1ƈƎrh;+G.4?VF̪L*j7}c 1+`̩=w# 2gQS =?+U˝rt8XZ:ZP3Eraom2Y91sh `XL OhըRlk㊋s,&9>{Y7_xKY ڂ:Eicz&/sfebZ,uɐ_uSc|m " a'h]~zNx Z+XRh%hVv':qB"L0>g9>b83i23LW,` M#peKWSX"͊Ni%dcDj, #8iCVQ #&eWp8N`- oGwy-LEDQ>Y,Z#Kj9t&'CN#h-Ąkל/s`4xyMkFsGJ'~nwk=?o'uрSu:/$B0|DzXTcd]XO3WK&I }Z6J Vt4튝47^x1P e`ph0]G &-XXDITzh͏R+&O+.Q|r>Ό4Z ҋN?zS/b%Af~FP{ c9 1C <|9H`h Eg<8]lܾrq( lBS6]hC7_EkBŷ MĜ8:qf2"@5(jȳx&Ţ1>Sֈj%*S""x"%XE )B/Qάeǚ.JLQ5G&0 @D^K'lRjʂB!%K_n|"5dc(a`02c93i91'Kɒb*A2v$ˊZ/d.nPT3_j%N֒SKzT0\.""Ny"-b0 <5 ktɊ䕮^qX͘`㈮{Z1qLDa+#8& Y O b*LƦcfcb0>szpz2ftڇqTkhWIZ>C% kq؈CX =S%O}%+[(NL pջVyu'urT?|+U/`HrL,S"ѥY/fִdņ*qDxPaj)[N f,dž#FgC-H4dեPݭSKxТQZn\/qVRT/)kVDb ELhxr8Jp |f+p8M΋+ ǟ`+ٵc;-G术i`(:Z^8&j}wi@lRN^&ACFCFBD5MQX䙇fYY0 /K=PТCa=\8&r8-(u"YiQ(JgsDqL`M-it*`2UCqFEˠCa`&cQd%eM/O=˹Rgvs嗄ŧs%yy"%":}K süJ6k4w/pX l{>-^]K_q W_-M"G5I"q2²Nu}BSdb!c3t?jL`dP[u[#Ću^R+Yf5 F=-_=~_,mCmJMZ{%3&ħl,#C;1Q kdp8yIm xdbNn~jϕ^MkmYĿ|Ks,SXPvS/%;FDaD%/8ÐVё]mt"/?}ugt8=8Xd3 XN<$SBčKݪs cu v;ژ.w)&Ҋ&Z%>!`I^k O+ Y6̱mF) bR-E؜ad95nL,H <OyͦZh\E"m^Dž1e#qQ-iW2UQID6)8(PAd(H~:sG8Ⰸ +I ? . ,6)RʦK^[C\?][?q_㟮\mxݬV0:7c.`͵1_%=@Y 1A?`ë~gGYeϻl=_\6Hx8¯)V}2Nz:[!5Fy ߯Q:*[(^F H]Nl4A,Z (2;;KR" |O2ڢ$`i1輻3=d\Q^BkB 64a=m\MmvQtvuQ.R^>JZh)E/$j˻`Eb:P*=i~rjpfpx0>gtL QdϐZKQ <"\\ )l/|v!CLͿ/=D4J(J2Q]!l%/{nX`堈d&$Z7Cȹz p;}]ŕk8L`kضv1ן(\o%dy/3r)n$_߸XwLV\u Ia*<<0EW۸MN8\-˦-hkm2Y QLOQt-:īWbXA[ETjuJ*rj5z(3V- `p`2:qB2]uVQiZ[*"OlB1̕&P,B[Of2ªX7\ Q)YFg Sduh2U O) BHZ:gՄ}5_X-͉ҜK{lq~RƅWXF!f* ja13:;Z5w8'b/va /SWLLX~ż捜ehWK'1/lf3y>M~@ׅ{\@04LhXٖ6GП_amo6qD1:̗oe.I9, #rg-&u(NWGA@BZTDw!#Ciخ IDATRA@PCjz::ӳ'IkEi줽JjuSt^Vի Ubc`IG}{,,1G$+u< ˻=j>F[jBK>Y˩jM"@ xM;d;EQ˫Bxege)=e(] Ѵ*-ԖHD()P MW{GpZ4b(eƞYr8HuvjAls'J-غB\5+}^:y^:뻀-ɋ7&jmb=>Ưf  ^6]譵(m?rOD[_5IK+_V,-MߌA:3~/E;FWþV@;GMKbc0Qk5A^WcX+XQu?U>gfȯ!RalDPbӬSߢQP̖ƉK/gHT/yG41JK^h-^e[7K-Tj04e953[ :ӴL{%g/^zR<뇖z5>&+RQd[9+"(E~EF#8"JC?wDYM8(XPWK/7=d,/KʯaFuɞ~oqߝ_wlu|wnӋ犃nĭ? cbLlJ6Mܑ ^ξU+,X/4ef>}g=UW^o{̦f>}قG/b.ʹMof;"w]ɳ3_[YSO2磍i 0V^/-0Ifm,ݞGa(]GXP+c="( "b</I/D)sĽlӣDA.Lx-*>RYK؈̤@ՠTT[J/kuCTcW''tj>MΠm%bGGmRiz ܌X5ɮ( c%3/|c0bc A),ZYX_{5 tѫe!qhsLKWHBؤA~iع3 Szs]˪U=ԫS|εde|Q+pX6lX TD c xe83_XGdOgNbvEk8ř2=+ױe$-rʉ[ cL1ņ(Xq Mސ@=N*,HDi1x:ٮMNfǏyl&-Өg!,AslR`qD02xI|Մ%E 1=]g]j0k.jQmdRjȓXD˄3DfО;!%VDaup|K^s9m}׷*-oـr ݾl ܂:3zf3mk;\I\+l}evړ|xOCu6n:E~/c٦YePGבѪ!zno\{Ɨұ|7Ԫj~VX~.PVetjx_{9JXiވ&-jmk#3\adx$sxl(K[x".X$?sm@>Oǚl5/Bio!;76Y:mi> 0u"j"+ɪtP[ (eZ#֠$`mGOM{s«jjSX -g Tkd8>b0FL-%L,}r1]ܽ$EC$q)GuLISȒfA4洉 wƚF%R*(z*;v%u(FWz6?ue=YH.nL@k^~/9>Pk]'}OKt>dVq7q6{n.rUajs}x ةA:֬g9WfO?'} e0~dF.-۹~w>?cS#t8|W%o9J{{/ae ^ j S,[_)Μ<fx݅۸g|s'Su"H\>řY]r</I[W6Z(q Khqdd,b"kDxa(dt˹o}Pķ+^!yRJt2jbY'hݕe`ԓCӆcÆÖɘ*T$˂cb'E :Gx~>h/I~,eja'D(eEh-kތbar! GqI@qFGO׍Xsa^[*Қk_Fm|Bn{F}n[Gy>Gt~+o>ǞJԹ }Wm]I[k/,١'sˏe :zaڅu?qץ~a7+֐ 8xdnLmb[#YkxVLqk73zbݳuPd=g>'\|\w5Y$B.C+AgA62IG11QMl! jф86`b6iI~>5}z?v\ۼEX/uw).ߖ|Ij)lR3qj"fcRLهP H'D0i[Us؞D9ؒ I[EWX%fQRa9 xrFTbf%*!(RU֢ lX$K?xϥԊSLL*#odrŎBZ(wSe;mמ[*ytT'{kXunNLr͖-,j( KOGƙnO&~d6Zۗ*i~ͪլY:w%6oGdY} PwWL-]9|,y%7052Dлr532G)Vvy5w}1,!]8HG934Eײv$anIݪ8~Q℥c8"*MƐb$ 7Ə %=e[=5UM@glLI:\O>&"I: 3J5|%R%u$K8Z]ͧUSVlj_ UIDj)E|rc"H"f ECm==YNMup#G}`FԷA}4,@E ߾[(%=[mknfy,.F ?g5T.I| ٖgjZ%^x9/KVO2ۨ\^οW_ѕ:@1ZkPAg`mmm HrԊ\J<~W-ewdr|o9ٶ7N7sO,_G._ ӆMST2[8|«nbUiBy4N.dMz&N{E!a8a82J*[YAŖ8hBKCF("x}.kg h -B{i* upApb,|7kP^ZYJ8i|^BoWHiij~i6%tHw]DYQbhc2Hnb}NDϡ3&M?3.p8_֢+} wFl-_ft`ʖ=r^XAHGg;ۯq^wFnܻȂ^\N;#<:2̗Pecd龤p˓ӈ Ov WkwM+ x.[f|J?0]zC1M8L]V%p;Ɏed}^̌yI! Ԟ]! WW1b)d1dvi!i.ܧD/xzT"nzo3scn8_b0s1nEyݰ]30o0Bmrj[`Yg8c8|oy+RXɇ͌}oc6 W|P4}hM C,Jt_6ͧ-]P ]o}Fncʕ ((gႅ}{j={s]1tG},hk("8|(xTה|V8`M>ϟÕWm”PƋ`' 2o'Y,둜`]m$8SuWy8v]ʄ/UÏ#lx ՕUlXgrg$Ɓ})iCJ L<^ߴcݠmSf,|5m( Қ$µp W}3 }Sph(3xUk4}#Mbdfp'5S]c L<)*Kx N~Yr32H-R2,$RG[J9TqD+upaà{5sscn̍5?K>>W^OD"xLq YfBr` $?,S&, DqN{Uެtyh }g<5l:Q`u5alyB, B| \A{X[)CGؼ͠$^{Lbx|~<^/*9IW-'t@ {|\ H@宣@9}A)`%Eʚ ^zcw36 /I(o0!<(RlY4\V=ydfxx -H`=۴"yJn߅>FzNR"sBJ9·z+K\ (yywRۯatւܒ瘸@YHi|y,\$BH/8EJe.^~tT,# !RTCIfbUgFlj[Ӯ2qvC/e闳:̮m[|tg`h?&S~r\S_NLrˏq[a[xstє*۽!kt.spDBŹƲL4#1Ȅ{H\hX IDATSsױ8j&R״ dEl?[fF'QHB "O: (_yKbW CmP#an̍,pFW^]KGk-g^@?2 .9o|]˔oxUFCȩض< CG4s{;U:b iUMr y;wk>˕?= co$IgA2JJ9kҾd>GURIii ^"rw[6]/;RVHdd")&i% `%Z_Z3J/jFT{=Vg^mGM2g2^Mvlc4=}^=n~ݻqI]?Iybb"˙Mc׎x +bj$OM&H9DONBَϗ ٖk=ZXJ`);Z)[2NvvH/Ŵ? d7}MVG掠f|&4CnMߨoL32!4S ANT,N0R*;'%'t?Z113bw"UrlCRB$Bf)B -877[XٶOGo%Z5YH&^f$di,MkP6c3ϥo~Kz{%I'M'PâeZgQ+.c}y+ϧnitւ>ţC'k.eٴVP]g4 })ԯ8 !p_B UUY!בT5 &cl;1šQFG!(Gi`y3TDYc= %Bn]fmsܘb |, m:ky3mWgz}h]:>77Q[3iJo7,*/o$|ybѾf7FGQҏ񺙂"ˏJO=b2^N3$>-&rB +8$}&ͭ'' rB@I:(@%e5^&ǘ'AOp1Ցd@~ Bc '4n:@D7MD 1RkbcN #ƼX}ýL%4M5^F&5ĺlgyu;عmMZ³6SP:z`\KO>U89Dͼ:r^Lt)5}xBC:0x9ɤ#- K)(m8!Hl I#W#*+n~ދLcLara7d6MZH'0s@#}}Ǔh&`J)%OnƬ%vk]BAJoJ) Y"}%".q 1f$@RE݆4)c` aϭAscnUX ,*KV N5jv~4d;Z3bdjR;h!-z9+Ck4`Y`R,,+Q!Dji 6 7w ;4jRPZ2o~n̍הd_8)fz,j-,,,]˗p^gσc<P"QbIqT(yPkue$Fzɨ2𫸨hx͍0P@`\ů{>R=r2vl~H=յMoŘ("v!֯L0m4>Xx)Tuc;LKX] L[#sת }WP چU㛱VpF+ɋb?}+r* ۼNeWOMHIzSTث4'xƳQDn)-,gQsG h]Ksɫؿk#^0cv\˪`H'/FCb2xcC<_A6rxwKhhnxHH} /@*eQ&藬=bȓJȡaTO#w3V,)'C}a5yx 0k!cE''!%vEW `d.9xq㡥4 JΥ=A0ԵE 0@ )"B!=#v¶!e:쑐ndRec;_㪐ZB&CL$(~9]5ûxӥ{l5$q&&0 꿲:O`Y-rfgFZ$ #Zeꍴ,D,CiEqC7P_Amu.[ P0f .$ϡ ۞-Ԉ~ZOm_˗PRVMN~T$R^/n|L<yZӱv5Z <2;cJ"yW.+kbP.ʎ-NpRNc=lŤe*qKG~ɔD |5 S=_UD11/3(͇jش(R4{5ൻ˦gD10rT5y>b>+"(](E$;_c_xʗ7έsCEi4/\Ыl[/(,++u~+/ae44/ɣk(| L&@Jڝ-Hr~dRF#P: 4k[ @589@b )נ)hoSJ^3;+ZZ{HтEk#E–c۲[/VhQz7”8,z*9gyŠι a3hZ|QsGX\II^Oΐ% ~SN)/qz_uUuCEt "{2*uz!HI(ǃ栦7h0C]m*Ď?O|ppj">ƦS__ &P.~c8**vhfb1ӘCdm&,XU7]~P* lec[D*Qy-QZTNStהt::2Ј9؝ `sf1*?ڀ弯# CY!kSBLa8Tt(]CN$-HiF*1rM cPɩMeblE$ 񩦹uxn3e8Z(Ok]y(Z [N bJ(GIuyŕ$ 艡 lg5e#^ ^i{3IkPt @Zqc*Q㨉~~t"b)_:mutJ鹛] ˟H>3SK+C*:~pNm (LSz6"T2V6[}焀۾ 6ʧ+>yE %rɊ]<쟼@{/mpW>Bb:t2 7[S3;~碚֝X62ͫ_6̓ ' В_2d4t;? Ǻ˯&'7H?CT2~Ӡ ?sqp(^qD nSw gnWBcK/=J_Lae+keJ$ΡhǦzxf H^R:L >2uBẂT)C*זAkrvcҮ7t2ןxVDsy)lk6Ħ4)+C{PsOstz4q<aJLS8D "l$"9=H_ #h?+^Ydap-ʂ Fl?CvA$= 螄gc0Yp}~ F 2c`g:l$fLB%@ DfC z5 #_ c/|R])ѩ2X$pTYܻtwVVbDJֈMGi&3 $zc"rF\yCx &@ukv]/`2Gw>ŝO%_%y_p7?LJ>&?go{/kznk8ZlY <>F#NDʯeYΉYy1w睷xχħ&3=p5M1&H39.ϻ{XLnY&V 6𯈩׽磜Qa +93) iz{1F[q VnD3XGÐ')^#&N!B;庐[!˕޼lB[qj;lZ 8Ҋ''XYVᯙ~BA{v4Fxs}O4v8|IKNPH~j`zX/^{}I@c%-45$miNxQǙ308 =qC)=JI:{E[6: r⅜Ҁt& bՀO_}%[. WPQQ]q'P}_Ga`ܢ?p-PI.jwG7C>7 E fI`^}Eq0jVHXj P]SKs.ZL$m.u3Σ=ɻ?I+1Mc*%c9ӾI>(@ŗm)s o9w 4׭`"HSLY^d~z3_[͆QGbTq;g& gAOíw%:N7sVSqd0 -^y;SD IDAT~ 2Z3P%Ddz). w"o=o25i1ey݋9oxbQFEאWZh ٳcSq8Iu)\}t݁a0b*:+vQ^U`_7 ƗWNAPbiI%j| 0_ٱC/pms!Jl%H*EIaB`c )b|3_dj0ܒ#(0san¨ljqY,J+KXrq`%H,g=S>N il!I(t| gԿYǵ c'8xQ1, 3|W޼CM8s;^%*1~_hq)M8YM03 ,;'>Q^8u!=q;AT_7HXl5%RH)9W˗N Nxa`"Z#DMg3zlFJɥE~N+xϸ-0? )A )|x=Nd\Ʊ{ya!KCydūVAArr5}',^R2d0 kSqmD6ɫ5a-*&Z4}ʂFl܄6 ̅K%Mj*( 7aL saO_ˮn،#XX[Yv1c9% h~rHળ53můg 7bY[JE|lU7lJ&͗kq%rNL$-JYmq5_И-27D3[X~ʜT9tr*i:`zQnn$p~++W,aUw,%R\̀w!5?'PZc qJwk+i]iF`ܳ&X$-ɷ(VY H=+8w}/4׫F#5$7 ]2ZL޾/hl,KJ!+鉠sǎ`[Itҹ֬ :xa~EWQŎm;([Iud2QLkZ*k\7_:|O(ksedx{.ngrW +) :'.,cʓ,)(K/-L+}71|rpMq+P|P(_HF;X>>y|gEAq 7// k6LE?Є(v`Tԑbphbʊsd"#̫NӅjJ ,KLNX6SØ 8˔pR/ezʏ ?Gj7<8xy@DsFSc]E8^(gYSV4'/ 4,m 0ݽpq I>C^PJih;^dwJLhO,eXd8;Uf,K¶5X !=$_m.t6m7c'lǰ 3=9\]7ջ*/ABynGOMӦ! {)w['n;'#o /cPPRzrk77쎠LMĹS7sG?TB3>2w~Feax!;>Arㇷ^Kq:lCtuGgX ?r.-?t#+||5￾(e] !098};n!v=DKQX!^_,]@hOaB61qK"w_3{YH$j|x‰,Y0bAq3!"/=ca&'&JL4xi!d.Ŀ0z) t˵ym6eJ\u%I6+O[X}7Pm`Y nۉQXIue f]Y*G05i*7nȹnQ+NH'\;K)g;r,'"|!uҜ:AjtisWLᑿQ4DᦚbshsSceAQI|`R o>#RI@n SQS0al‰H ,5h7 i`ilwxߧ# jzgb''m'O-*bz *iA84 he9= ݏ}XI`9!Xz3zCUhe=AE"KY]Vim +ʍFF Kz6[M ~+9g"6Wr-zy%y} 6lvNѽv^'~#*<#{q'nbդ'vb?9IMib]l,,o =DY zmhzfQa)ib'HJ6\Va`}M? ).Y{I[s K|rnc([8?5Ds0/ 8Y+U7 Mg;wtaiI3w|@]~!.|BlًVDIC 5/h QZ"&PVO^I%/؏%7ǒV˽`x(Ae ANNE!d^zjV,2K(&0# g`C+&9I kN氥i@9CUYtT'n$``iʀـc&Svu?$C Ah *.NṟorBcZx]?4Oݦa-.̋{g)- aJj0y ioW{Yk?[Ot'm7/\SQ;ixYx'?sޒլ4/HN$HD {?ù18/8$BlyY.ܸ00 3- i~Bb|~ȚBH >ȔG2uÃ,YHe"⭗sښ<_[wr3im'Ğ8~mAQI9 u a}ӸS_~aʻo8 著m~uzzr<|㾝;[?0̻nhqՍ-T7gp?7OM}+$'5~|t-7l~|gQe096dO?c\~Q#)XF1HMI.n\ LbॷO?pumh{`Q6AnݹT_eUױ n<<dY_.B4L=%`Xx 施Seg3 9RP)]¶yCi=Y/KS@9{CjGx<ʔTAaoHù2dMELڪ!i+l[mmֺE XbW _Q[:}0S)yX-М2.'N:[4 gܛf}jS3|3ʎ:s0W=ÉeF x A]*V3\vLu|7`azu+$9de ŊOҽ{;#Oü. f>e{ND/~HyG"~;ם{y$#( hi[@/GFrĉ=.YKۢnCqxh, a=,* ]7|HEƎ*,"G+|쭋Op#m]{ij,1݉Ӡ &᷇ϡ|GxY4-o5:6ǸWO0ttǞicӥɗ5M(ϊʕa}x5OgKx;W6W_?x0Fslt6 c`hVtsʐ1EXhqvwH$xMل7Adٴ/]Ή#/[Q}n;C L^H>:YsE~~o7 i]ȶ9ez{)F*B RAl* H^BOH o>8zby7L9Tҵ7֏߱#ؼucJ) {?y%sAYz/{y s6=Ț#{='Y8'sm=af'7‖Y ~s}M\J_1'yW\loln -XO]HזöNPX!ǫa]뻔N Ǽzm6Ec5wn@yY (s )? 13~++ QfpH ۮY9P0LN_ʁOȰԴ"~xE^<I̴ l3L*j9,)Ijq;OX-tb؝L""ZSEvgYHC; er_Y@_Aa9a㛂A2+yW90`s1hy޳C>@~0@$MH¢m OXc8W^7B"y0Eg̻[I ?6жmI\s5]ۖ\A E Vv9P@#~#2RJ4yp?ʌ;LQ5)~1i7w6.'BXв@q:efܞ8T% :x#?kJ|^.N` Ho?\v( ѓKE:]QOȃnf2+OE"G; **2'[Ԍ~d@q֫yKUs/̺^xHJJ P^BHRN0Hi^jq[ѥͮg]L.Y̗h4L"رP7۬8IdzJ¡FjFQ FZ_/ӽUill٭v[aX)D&$+$Fu'45U">d7W\&ioi0oCAy*=]8r4`ιlsfn0h &$R(,hv0΄zjlT< 6]ACq?z .\Jrj9I;n4N><[NaIB_V@cO*9Wpڬ 0]9>njb`,>on2}ZBt9\BSXo_͆nCپDHU[0}4BQ1f$.KqƦ {0݋o IDATߊB_}FFT!L,ʈA<t"48ē."ȓ_hcq|Ƿhr۸گ0a ~wםUip⹿hjڷk*)+w>GW]cg?Os:w<{xJ{W_!FMٺy5p9Pa?d$a>m[eGJ8s>k<}t A^0Z vz'ԏQXU\EmI= Zh(i[݆a\:VnE8sؾ#/ [>b'5TŖG_n)aTY.HB ߇Ʈ]9H椷 \.PIQ5RP4DubTTM_>rv₠VEEIa/]A.g!`-H&ILKHU;MR%=HAgז &Yʟ5Uq'senhC3 &̴A/?8 V&4-َgE*8 <*%^JWQpU *:5%U%:>W!%%fRO&$&fȀoSaIA(bHADQكp GǶݫ3ori;9{B$Ln^LlEx$?p 4(<)G_K o2tL:u'ԙy`[9&USJ&;`Z:bΏ>*&ՖX@WU{u$ܶ F0b2-el ]B ҳNCol,aO(7x~J,\Nw廷gdK0o#[y퍕ԎAme p`]vXas9dr<0>C>=]ݍ߭*:HgTNgxa֬#$]_ՊKw0رM1n(`T.Pt7bpƥW7x VbPNWU-I;= i=qpZ4%3O:FqH PX'k/ފfrW{}|*T,mF5c!u;W0u,sR`UQ)#G#yqfF^Gli~7X?W׾v<t}6j14 ?l~<~j=~o2*.2ELϾ)4v.7KaF}:*(';UDl"`NɌd&cו ƌDzw:( ظc]V/g捌{~Dzv3|d緺FȬv)۝C;0UE릏6"0UUQRR "y񊁑6^WXXXrKJJF46 JJ}ނrWEM}GE\nT~L%R$!I=Hˇ,}[rx|iRZNpE~P4X8~J74%mU7>}\idgC]˔FhW2bQnVy˹m_3fߖ1t˯y-l4LWE\s$<qCx.$8-7Q3g&cFL]x k{D@Q$GRyʸ۬sdx=j\n'JZ Y\Փ2l<= ՎǟdÎ. pXS<MtsØ3H=˦mSR JJ39u"5;i63_@ =PVy_PA&4ڈN3JiGBtwmt}B1ӵy5=1 *Um*来+Cۋ̘=-E[{ i1zQ\6ӏW'V `Dq\N:7]UJ !py<(C D PRqQS/Xj}6Sz<++_ťE.P,%e/G 1Mh$$#+YȔgi@=oZ9%¾bD~$9p `/ph})٧9|@TAT.*BNMR l@wh4U茮3*ڕ>}ĒTJQŔ27$MA2ᤠ#lRܥ[awX!>%݋ъHwReKZu{vt[ޮ|`ibDRRmkskhYж]~oL8z,txPT rE 9#3y,R:[9$$,{CJ'e'Ӻ}-(-kyv1$cSe1W^Bٱi|L#[?X3lm:x=ȑrꑓQ"{n݆NY)mWoTǿ+3O8 X,pE_{9,@Ѓ0F^{h2Y.>,&|lBmNJˆTW~QdxLy ;X0QW|=3:nm"$6'ܳc\M3c_4ʀlNݜv%a˛h=_Fne/n[,L(U .9'+a]L<~Hxr=rw .r!̲|>?)H?l)JBwXz :+T":IUb5*hB4w!aDL']R;GƷ"hd&46HX oS׃w1O)b:V>+a{e|Z쿜s\gZCrI . 4[/fUJ;JEP@,*~BI@,S^RzU4==LVp)I& d*,I #S*\]QA{TQ BqH`Ehbc',uN āHXM->iV ? r[u-^zE)?W?w) 8Z9tTުמ`#-cGd؍ ĕ0mlħ4MC+bH$ť8~- #^Ĕ8V ΔcMxũIrItmC8K7wǯgLֱo2N :qK.orqʼQ:I4_ʦN!2`hcT94c&LC(*e*RIjv+)+,#ys?HMB_RA4@aHoF*I$yX᝷3$~t;wwn&*GXۿ==my޿"^swjMG3 3P.Rs6?}^RipyiOEA)R80HZ(ϰ% D>󎨪lll Eނ@iU.^6a=f#vzS)i|)AGJK 3ݦEȤu}V(b1jD|fmi },T6 uC=U( \.+Gp =}t\|OT+tZjhQU(8 6 tMAW 6U!JzBkbtڣpB!L{M+7gȾchOB(MJl/Y_ ar2B2*І%P ]|%}OR|K:n^=kpj!DwgW d>;wA9IĻ6˾#B\sߙ>wɽ7]ʨFv+.efj #U)+-$~YKJs@hVZ+9ςFC$eD, ӑ +VdGHwϐ -)r@QT)1)"IWD Ҝ(/% !Rʪa4Wy}:3z+jՂz"zP}  2!D$ @HD!11T: P t c7\aOE/0L>|]YS2A4$")Fr(FU;`R:;u !'%$U-9N iIv;{6wkWС[aoDM*u3 3;~zgoe9#%y$}Vn/ͮL4T2.` d3߃ٹIofky}*$S@JX|/Ԝ2;9QȲFnCTz^~}]|Kij/x=ɕ?17OYdn[h eϰvg% 63WxiGT,Ĩ PTfxw?afQ 0#$d)ɓ^#s#q\jfŢ7ncyo<.ϔ`o;ǂEsqfO{IsX8 %Q֭Wq9 rՠVI8)AQm1g JKK#v9s"d !#2$ۃiRbJ?㎻p HEC(Zbή:W1iQ4G*LS(v~^YFGHЙݲfd|N{f) ٝ^LDQLӤ7=iߛ#c`|SmEUIIITXX\Z\ժUY\ZqWc+D VEѝRR&)JSMj9S˪k#M$r}r6Η<.r>o+'.|Xߓe6Li"iW:~kSpC!ר+YecT ]| I4aZQRs6eBS"7*B ވʶnm=*;{]1A2eĮD&n4&HR_4;lDjLIYQc9K")aY0׎ka=$R6N68}zwt 5z)x$F2>ZϞ[JiP0M;-jȋ%OWr7H njx+E{u!x|hUhaLi1m;=ϬYlaMP[]+8|N_|vu*FDeeܳƱ]jf4NO$?Pͷh{I~;:ک()g;ws:?&s Eնb ^{?~Añç7yutݘ"2'SQ9x~;r|ۓ0 t|>=#&J}x.lLy;g/ףؼ",۰ʒrEhW3ˮӶ;W`#wnݕI9)zF:Hb[M$Ҷ};{پh,N*`jk.B-/4(E 7%d8EgOJ#xH貚K[C2¾4 Cr?@̛4J{Øse7}H W!^ ORe^DŽ=i1UKPXQ[PSSQWq.GЧf v 6 :2Bw$% DTvZ;"PR B +1+ Jga1Q"Q}4jN%p޼|rh ,v2do=Hj8 J﫟)(gJAyfN{igЏvCs?GLJy8w0d2EObH.R~%yYf-'azf=k/-H${W7&>deZ=TMT_a!c&dF'}Ivu7/t .sWZҁtOdb2BAI%-_m}wƬ9yaKqyH.?WDwܣrܿY!Y{0GVDIWrBJ7ɺ۾+y?0̳iw7sfӏJ0{w/Qwm˳LYubpjw? tn0/:-JC`pRE}3%5#,3Q4!NjJƫU48:Qz6e:i̫ob۶=4: (.Ů)1 @TKww7۷uttgnޅna`#PRAITJЃ lrc~8R)0 E4V6g9X?P哩rU W̕.˃Oy7O*_b|}w,e`mT*l3:5%:MiuT\)iMM(fYѸ-Sg}.!JFqސ`=L}OY&V v8ȟf-o IDAT}5@hnJJ\nH5ƥjxeD#Q]mO/= %BQXK8[9/~ҧJkt;#Ijgï/;߭JN_??,;Ӽ1Gsndfe x]64YJ{BL=]ke1UFA%x j# '^g~"A{- QTr 椢O7a(l^_=`vUc6~ɚN92\c^]Ϟ{7//>6y0vvQ^U"8E.'an ,;(}7Il+JBULU4=s^E@J9ishP=XmJaY]8l5ե;w 2УhWS6 L0 z{{须-[yfzzBڳ^ h e5MU.$U?)';zHHIZ2ls:8`I5K>oRv3\Il͊e O$ ri+! ЊՔhDlPeD΄z;Rg܆ϭ!I$M YȬ;)ESZzR3+RЩCeSƎA(2,RW$6U{9$97"&+[(EM-|PЛ < 4g_F6?{ӽ'VPp}Tdг+g/~ǻc =?ySoˮ4wboT܇641- 6"ΘDžTn!9]jj&sCMtnN_~eN77('~*dd]ӷ' pϙS2n8s+,>hoןY}|Jv=O|`U3g^|T+*&0u\JGMTǫZ:x W6Rs E6-xݏ_͠lQP(yuJoNs9#I QJ׿=fJ *)+̝dFDO< =xI~/Ia Sߚ.mF]V_C~#oG#sYwy| yu x?5oE԰QU[Nm]%Aw.{w΁=f1eגal 1fjߗ9:,D"A4h$J$}/hD"NFb$Mޮ PԔdܬH+k7T)* \x<*Ee:: e:vP!I%$f)R S7,xoRNDVHRTv*tDK3A]b&^%Tdΐrt<o4A+`T T=B@!+ί߈+%Pɖ}2Р> %ȡ^œ 0AInqO]Faix0H`{,dt&^Og .X\Ϳ}@ٵ.6GY=l%F -g$\#Lȫ+|`h֫.JJgqfojE!Rhzs_b;K9^XϮ }9@Ey%c*xc'晟S$n8Ξ3ˉ%L@ w[O,ƫ6y >L{Qn/Rr6vI)Ib LH!, )$%!~ 򁛁Avc)=ޘ+0D܁nZPk9,Ɣ_1a}yCAWk2i,QaRT@Vp8p&Ar ?+ۦ`-r>E }a ۖ.2OMWBgb)#P)5)^va4E nLa% )Z%J{" 4uhPҭ7"$ ӊL')waUɬ H cFL ) DdRRZk㧟sDT2:+)V;4~tcF6v*|#r,7a 㳛܇HԮ=Xɂ3`[;ؼ+/'3RũI"H0S)d a/aRCwԠ uwrn/9(b/̛_` -Mcٰ,̗~_eu\|غuWNIRsg|Gy)6]LC/[O=ŢiZ~x|@qƢS<@$C|mrӅⴁi˄I8~TUgW&^=xd'{i:z|/>MS).+Ca$x1%صgcM>(00 D"a$ :{d޽PoBi+,'X?b|J-UH=D 5!e5G`Y#rbr䟃2`e8p3Xֲ]nv7IPՌWSc4٘htL\p^p\\G1`9]Ln}c3OaFh$BOO7HiDхOGw q {xbc'% :SJ)1쏱{>x sKCW ge&̵M0myzf/ana(U8t%\vAW$`ItABYP4qZTuӡdRܓIdJeZxeNߩ+SIXY"Y%Uh(&DhQĭeL,ߕ` I]Mo*ܒ xް>ݘbޓb^&UԘoXUv8l׽NGjTwqqMlc)UИc2a*XrD ]!p&l*7X a1R2eCpЃȀ0r+AⲄIPvny'K(QP$Wt&"y?0Zi"eGf N;#-zz\0))Ax;n1%e{Eո/GmhQ‹Ky7򝿣,̯|c#<=:A;HhI4Qv_9>M<;M?xLn`ƍlxOwW,8xNopͿaYfVe.aI-cѬV96m 0g`w@Fgc hݶVBvlo# xHIT;ނrC(G]MρH'b7)H%FTf!0. f(1"Z Bn$w<mj2T^Yr_iECcxK('0--O NBiP#Q,Ԩ*z A߭k.+XY"+҆$#*z4tklQ{0;3wU:$I(0G0DZ=cplj0`r @,us8}bG9}:Hžo~N駻uOU{z׻ r@7AykiXccpithRFtAq'x0F @Lanﰸ,Ic"\\?Opn hy4ah"XkNtf]㧏km;M}daSyL`Kv0t-t&oXA*lN*.B) ,d(l=uܲƣݼ6Z/7^Pn[}Q~ ORlo%R^KsslG~ x߇]4p0):HESeb pQW_Իe /f9gn_8|lʷ}w9Q+0d'C"tL_S]= f50>5Ňo<&;7aL#{KgsX?ww`y7u!K >Ki&˱10lm$I$ݻcǎQTU%/GGUq*`HQ.yIp?MȗD Sbca*^'quܱ0킠z}"fd_ !xo~lwB3No4b^JǪ(.wĜ4*A<"iTe6V)Tk~A( $'Q5tTzݫ9 _H6E{ pL^0h-ى‚[1>S;C}7SO^[`q,#v2o\)eŗӑΪKGo<]A_7TŕfC뻩[p:kf`:~/|냮 i!-{ ,% GE c5A:?~G{o_}hyק?f\uu}ǭTQaga i"qͭbـm<ĘAΏǕ]Docޠ7m4k5 CDP D„b #(:H$\m !$RN'se6ifXIcr,AqN3qbK 띊+/qj6긾R6REg< 8.BZ1ЎJh>I"&((DC QAmJ""H\ Te\!ļȖ_)$Ͱ]4q ҆$k}2/"Y$/q1J7{P9伹R7ؤqL3`NIǰ5W\FHrl? jr,~6ǜr䩣Uve \~Z#G<>5BO8%oįasܸ$H<Dⓘ)C7 \` eSQ-+羍:߾,k ғ19K7p}ܘʲv tW=l#:i=:!X=aƬs@P4<MJC/c1-K bQڄB}BΛs$ 1IEL2PG"Az7t@7LӝCxYB+T?$"v'tCV=gM(ϼsw_G`wK.k Se{coCòY|h E3ر`Cxjꨠ\t*rh`Izq%H!0s:E48b8JCUlJQVhc`/dudq{F {Hd~:̨^1ºuxqv6$1\r-05RΩ{,eey?b\%X{V _Hv;pY?Uy9cN۷7nN=RYL[CU)j~=X2ci|{+hnnbuye++hec2w|yXY"#;-gK ,0Ƃ6쳇7 Y{e6G:Br1[ܥK~&vn̼f6>4vsi~i֬7^{K ,z{ D+!3P#mi֊I]MP/Xx/L&`] 38O_O"ØhDUu [8ib >~?kX(؎İE.@98nhɂ&WEaړ{rבs4%5q_V4>ŞBd}qq4PSiP&&ݟS|1nn\ݓkYUPhV)DDX!Ti@SۢHoH^7-KFn@V!Cp(r|3>-PS8NLa:X@[y+#OϽ6Ӛ}|*s!cp<`p7Z5AQ9 ;"՝c;NYǥĄRĆ҆`9S ޅErdGl>Ӹr>tk=rTƪU1|xz.C<}_ؗk.dEPI ^zt3ǿ~w%g |Mo6۱fv.z=V5SZuo( DXh]i_uJlu{b9E~ƙ+Rvżs\p{ ֣3 &ӘVM╗W";hc[ꗟDD1Vv̠-q:k>'>+V˯Npkx7ѵuX,zr;y|k_eAC#]{ٹ9.`&堨*͔:%&gl60D9>tŪ =HbDbE[`.x \V|7H};wcϻ+߷g~gr܂jpAD6StK?KEclj[X#,҇Y!Gß!|/OĂ;FΥv~z κ#0sj2O(짭c;ȡC3g6?_`]O lo!Үp| '9fPbg \''QN77Q36f1M۵Px]0ZV z899/^;W'a01 ] ^P9A#~aa69!l:ܢs7pP lf$s}SwHI=xG#[_G  0@D}: Y#CFQd?iE?%cj1E Lv]ZǜVslhԈذB)6gK?Q\kJU*^[ļ۩4J^Bp$qaq?b\g2[@ ɗ^Y@xG _^]V@$FB |Z#d:6BFuve9yT}cc0Y>s>FxA3t1zh}{|Kc!o{?0苒凜X_Jjj_s\sA 0cTq2a׫/K,X2-< ?Z(NKcfuYlSXr'hosGd*4]p Oo>ϻ ~}O>B@ی8ō*n"9'4n;3-d%1Lg\wU>~ei!Y`v|QA?hDL$Q6aƱLC@ژE1,d́@p-5aaȺ$p^5'b[t20h&_O*c>?*Q}I;s&0!^TBf#]TX( ZbTs&:S^3꿡2Ds$q/ X924>pS+l(:X|O€!P]ӈ1Tf*б5kXGmuaqQ_!թvDQ>y+뷼%h”7?Rz>owgl%u?i׈͚Ke3qߑ:1h?;ֿϲk?%VP"sd3džX4G)S() ܫ#0c|Zw[PuL`8N~v$N T4uf6l,\p76) Ǒ!2_b%QTY|>gFWlVUԈTD9w3}He׬3wS2w*uPyfv.GMu#{(OsS *ҧ2)%.'r%/ ʃ1^OnΖEiL;JP΄P꘤L`aoP֍"Q=?OPwR`E5G y0& TT,v`6el\G=U>V@d3pҥ{J['^uYOPVKaIETPPqT7 {q-$h+VoY{)͈bWpVПUiOyIބ!Hn&^a!4m2] [G1F[* F@2MgGZ`vžpΤ- AߠŨMޮ 5WMzpڦ7V1BoEJ\u0ɘ(UoK>{CKdxѶ3K3xG7D !"vs^ؔ#cID \atH9 B+2G"U܁$ɃO b m)̡9Q EWlLa$-"]$kP3 dz"tN,Hjݎ* J$,X˂ÒDĵp{tLY6fY>-ml{ s;58)[߽m)=5a"3_XTt6~5 "~QRR1,q?H !8VFG..ފi!ǿ>7}4ɩ*M酁c֘{oW8'cbtdKI8&hTxEh_t:ǹ7s*N|w5T*.}F Z򉯰|,:%}~?pFOEǒ1- 2}#i V\D`x؇ne!+FQU$>p(XS RiN{^ϛyY*n^z!O|G{x?ela&̛TEzp 7rե25djDm3p! c7RpLwظa2V_pr?a z;bsFFr=&o?+H_`fLڦaWi4 '~GL,MQ:P|Rhl.S<ASj>ဤ\q  e 5*1*]Jr^^"ݹmXn\pC2Hړ$uAVd ȘȎYx֘.pAsBeRY]70 ̎$f 69Ȧ~Ò~jf[|dOⵌC]ªVԐ{ [e ?o +ߔTybC6+ڃ(e L.G?wx|AhRړg`ALP-|0 QM",y5`32U?GnPU׿&H`<fgjvO{p9<\;lض#I6%W prA5!Z b=s2=CLW٠1IenY-|  K9x]Rty4 V)kۦ1M L=ϑͤf҄1*k@ˀir ˛s`ŃpO˚bHt% =]B`~y?{(uyG%e(kO8'F d{## Ic}9f2{e-eKKƁ?MS%-aYoK-/$/.N2ee,4Bn2V1ڋO>x%SQ|wD?pX>+kl\LDzP*Q O7y |Ibw۝Gw1vnM{~UznÊwG:wH;y)Q1"~ea*[sisH ]͟)TH3-.JsNYZ,rE9OTӱp1AMb=sQʰ"T46 ڂ(V-ow?ҳ-kO3g٩+Q6<ִTcݟ9`5޷]N/QBjehBgZ)АmGL2[SP/iqJ_}#o >] =+}0 &?s5ccAB"j#r2X:M*MywNu` mRO^$`F:RW\.j w|-L5 gJFuAoZ70gzҒcC': q!o"{pBivR9xca1Xؐ<ĽR k |x(<&~N7bO(cBM 8=( xLV2V44*~6 ApS'&/'BaE/` H(%K(ZF,X-IDÉlUr#/, 'J%z29xcSN$Ff瞃\y+## Zw%)/#ƴ(*1SY6U!) țhRiAQZW'sh߷[LbFu[tQ]k{%Jeɂ|LƁnEI'̽cF7l܋Y$I#(e~2wyak+ 8 y-L[:x`\gbܕ45/Yh:Bv?\ꂽE+.}5k8/`> ^IłY(l۽P|Nm󵗡f: OH$s2*ìe5 th&NC4%ivKT(2=~l}eլ^{;i۹c}_(>qX#N]h3Qg6RQYÊK%?pg`}̝ ִ,ȻBtM-?}ޗ3PXM EK^=SVMeaW-޿OoξU-_3]PdJrNPa<_0-!!"M293c[A!9jT5Iodn]q7h .i. Nѐ "A|Kb!ᶏW#^|K-4'<'v  )Ar- F!H鮷PN#yɰ rT+v a IDAT0l.J:#ԱM,~kMͦsO63B~@ЗlQg0bΚh^ {sͦ6aͦ.'F^s4"a34H 1]]mF tŏ ,M":G,wU0-{^"M;,nN;2QTxCT؂M=1s`c+'vogQ T*tU aIMlhRP) K4()7a#i'=V/O^Ye9 L\&M>sXiLL4 ²mTCcq" bHjidsylƶl.\6CLuY;7ˆٙ l=aj`2^oux̠Sw41 _a/߸}>1o~ MÝ|In8'Ć^Ƃv~!D4Yc{h^HK$Aʤh|wβ%m\$uGDp@! 0wC4 Nt"/8|dX1gj!~Դϧ}OԸO27_aX&`M#<-ˊy2 )">+4 B- u7KIeq߱f,YA؞421L]ʺsJ'j/)sAED̍c)4U:I'\IS\5^; saI20g%YIF A2fݹ-+­q1,ccݜSx=1&l.~ykAmWw%9T96.V̐XؖpV04"x i5>?!ӓ㵠J( m[e]ɶF3&vG[QC&, a̪<\##~*BhɀqͅT_9l[ 9Ft l {>!QytoI V\R_IBQ%.R504 H $ (:nl'p@2RUVZA.->ތo- Ra+NT`Яհ `%K0tTں~~߽!Hp *+b\r^_Y xK>sg'vj9?yS}l}#H Q&ٻe?׼o 2GH5Ýlh.dVKDzKp ?nR'# i[fi$)Z,zo_;^k̼-L&_~mu Ǣ`,7,h:ց)|I:6LOQUAS-C[NeGgok ?pcmt w_Ŭ obyw/|h,=/%=6@짶.J#$MKV,GIrl(OV t]G>=xYY!)GnƄkEpZd7pM$ &JZcvF*g[?^)dM0$ ^ݝ&ޠQlΛ8hӌG+M1LȾ 6lؗ 9'-:G vmaITHg-,~ӕ)v- LTAH^%?UW&iQM(ԕ+()$zu :'!|RT N+ erc)Bd M(dcˏ]Sy9MUڜ)`MֵM'YY ~6! 험@~zFF)3?B2B6eؖ|b7=;ʒ9}v6x}An[ARs#)< Oɑwrs,tmt6,jiL|2uwL40&7(:'O(nzlTU(l1Ec~X |;{Y>hbs#Qlr {mI2 wAr6ːL1<`C}$G! "*(Ӊ!|>?")݆9!5M%ք(T7?^RSd%Rv} A(TF,P4pH J0&zr\M8xB1)e;d%s'X7o%.}>+둣,gT.MPM$SJy4s:L.J)b8̼r,ut=xHԅeʼn;2aC,94eeok1nΪEH4LmN;3XB d|8a#xlj7`m/e?n2L06귨\njc/ 7~UqWuYH_'byRdRtug̠f4hw۟'jv\UM;>U7v)In1k.:|P2:{{x_?eg^F4-sϢ̏NwA6ez;q|*B;~sPiZh~8cbfZe!~bQgh =:4COjGux*Qvh"-pByqtX(ppz~ y5-t2l Y='?K}˻[r5-B4 -TT'$ *$ Tv3L ҆Bd PVНVIsnTp^3R_,4l.ьM(,UQA:6ݮH)J֝ɢ3wn}Nb:n[Av >?Cp% }ņSwUPa95B\Ma&iC#ےdr6mT{yaiЏű)|=㛳 ~He,yY~o= :'&ctr%8n")' "T:}nRDXa8 ׎]ރpp#l \-l,a9R2ň: 6Ƞ2Ȱ:̨%GLDel~EP|TT2}2*A BnͰ8H!1L|vw{Y`>?3<9Z0JqT X] FawڄNAWKRYUǗ\NW+Rۆ_y!୴6.)'X'Ƕy,oIū<\: z\p1N{7,K>:=Ì$rf]ў]_4ʶTQlAvu&p1e!E0gfرQd}yG8r$ Ґʱd^dcCH ҹ!F6ݦ Z}ؚ䵽Y% R&Ž$ 9h?cΧø^3 v;b!Au\""U^]<,VQ Z݆.uXҺq]H˴3$iC2 Ut=R(96X _ 9s<Μc<[S635fgBԦZQdgy@k?TohsC6疡*XA҈?H8L.vcQHg} LFI<㾅b; Myn͍^qH&9pxv`ٞW}ZAJ/D$qIML:") KAE r?^x]v  CXd%-lLa9J%'sR66̑VҌ* a"ˑCG3[@G'CdDגnʪXsף~ hV, IOb,3;{zTH$ޛ"X= P{lf7 {N^ym23;}_>ͻaX&_w- |A* eIAU%\?WZe fHB@G}dt6e6UKr!W0#:-z jUJY̩gO4]TM.l*zٴ-)DB2'?Fˣ9.ıMbð;cDݷp} UBмT^hl<'N<';{ްj]ec پK}͢wzxo{#>s5;_s<, ;sR~xؤ:Xqذkd=2uQM]c2*o\O"Jc( Lb)d{2iw@xdYGKc>”js9KJBu\Ԟ,L" `mHNcQd3!=OsD( m U`-ٌ̛Y85?I5߰@?Mk7qgfNZ~ fc&i"r9̀uN3kb+m.s2Ppyc2@+MYTX#XEdT(4:*TRMHe!A"/*U?ESDY$KC%;Æ#љ6 !l)8E#WQRE4 3ˣ7Iԅs)k$aY#u%rx_ Y̭m`$/q+t LWӴ6`VMEHn.=_k[S 8^|~Su)`ahk8~a'h>g7Α.FH# !"vU(s{(mJjۋeG]ȊTJC} 3,3h1'*][3@Kx,FUm+'L)IV%IAvޔC'gp`^]V>:\ vDsQ%6y刕Ǵ4>^>bޠ4 /`d󂞬_+HdL yK*UQ%cfHS~;ç]4U7,"d4hT=tgAt,^d01q/Z4TϡVLqI~?\yCZ2eUF(g xx]mق@H^1*b(Fe_ןdy^r͠oX3u ?6.3I!?OдKQ亐w]nG8< }z=jj/y**JqȐStr }a`zֱ66^Ɍ.y#_/ trVJFB߸03;? 6WOggsaq[;).,#k8c8*kIR{%,&0q+Y1>Dоx7vL8Bd/,HqU/B;x[72n<Q9e2vn.O~w9]X2L.k2$Mh`ޭaaB߻S饚rylsO+dS[B=b~ٰ^ @[ X=$ۿ[?d~7c"Q j1t!Ҫ=?)YYXt&?+onxm#|z8&~&</Lnrl45,0cx&H `#uBLf#xf;8u$ǵQe$5'ZwSBҨ]GJpZd#9c1L9Uȅ:Rs&+g/b|FN~Փ466pӄXS6;cKfpH;\$xE_."h* !..V'Q[LoIF%Bh-6' 2 `,9`A ӛ>xr|'C%m0ZRU.Lh}Qb( Zr4Sp,*4tnq Z2$$tP%?&/º hID$Q_T(]Ygc;E;u×3_S/D-[:!wOp9˸|~\ؾWpӷÓ,.|<%E-6Y_2M=<:Cy8$!j"AYPTIo60ƺ PȏzGv!CDި%՘<-[u^‰:;myuS:ky?:A%Nl^=}aQ 1mf On=jC>E9s;wr_rũMؽ)vb̙VӣA$Ȟ1yJXKDΜ8quIN;i_?@%7X$EӇW:K;_2{ LtOlן{Mo3Eǯ)"Th9Kw7I_WJpʑ>Rn<:{q*cx@4H.|]S,$ɘLmL"OѠoGP?( bU&fcw8e_Kllb?ìہ"(EQ QZ;2'޵? >^{-Oyԅ /_[~ÜjjO9[~avhmhcV[ ,ñ @nت`*@H0u$!^bWs(=\W0ۜ#wP"5_?;{9u _%.}ijuޟ'WH˗D7^Bl询Г'ui ҝJO>If>iGɅA5qԡKpu] N_ʟ~01 oim$*\FPE5Ng@/}T x2A-JHhQo@.id ߚ ,8RX~&`Mu{,<>X2%XP] pqrz?oFxwcR}C{B|ƌ@|0zGX azYjUC"Ģܯ~߼ ]p<y"+}7k,_K;f^GMkh ejrŜEǕ~[ҫCȩ"hᰡV5c"g8KT ?%Yke2ѐD<}K H͓_b(p!'o %r2=y| +-NE4ːPۭ`*DE-?獙MXb^6L\ RTh8qJcie ARqbV2WXf.߬Q]SX󏋱pDrر;{]:h$T3ox$^ˣ`m[$u6L̐pN`SbRIȠ~@0(%9t}LcuΘP)gԩ?~$o0y.BNX}d螺1?XfS<Y|[e@p-Ā_?@p+#r7!x>U1G,Cfy~v]q ՚=y>! V`>=Adt`8d*8cKM<Y誆eXU<ryl 1u-kFnQ.z%BqкI==]\r~=k ؎CU={$zYU* :GAع I._E |*q++g8pzٻ7ϴIF(w͉N$$K+4qI@(|(0Xj-n-EUn@xA!ϩ&`b5 ȶCOY֙x2?x8o2.%JWyO缉\p4 qՒ/1.\h E1RCF@"Dw't)k̚,C0Hofw'Kض?-[:^i5=JǙ8KXh!.n=T#gCy \_c-v_cmEE]|E  JtMKdmnC0hH*e 7/QyZ*EU+,#Ų]P)/Ϗk)}d@ 5[pY:;Z^PM߼R:{8M]θ٠ %y cɄǪ3ya <ӣw"p ٜ`AS, `Nr[r!ٜ]\od71M#o̪Zp,@?aoLJ;_]B4* !AXm,jcu U*5qƤBkF2*NσOqS{̲p1Y[[іMf˻gҴX:oc?;9cj̻nm IqNpM ajQ$:wн>nX>?]X*5H}9g#ʞa6~'0>g 8~b|8NeWTFN7_C+~ޮBnC8";Ԁï,v9BFۨ=eR<Og[~me őyCO3N.IKO^5ܘ3VV ;-^{~Ld׫+j:[n^C0g~Gd +2`8 vv"7͉Ӑ;_XmAʐ D_^&mJEgrSDj(FDڹ6J'M%'p2̓kl`SÉsd{,PC}LY% = ̘iB&D6&+<SA֬H]2yЛLYԮЕ)PlYFgxZ*ج#{6'T+wX7_`LĮmlDf̲7I,<$ j~wHQxX"H4U,T""Sæa ]v~[sʫưRv yXi Q5ro4ZC*UmZYOy<t[Lj_{RaGQU+Ir9ȡ!7kr.;A6I"繿K:_ ?M\-_;O|<$NO8IƚϵpdUݻpJKS#}\~X9 q^puq- grEr/q” UQsC|tׄe"6Թ=r2M.ϥYQfMEK{Q-+i>ï*Ӱʾdx Q2LbXPTdM8hn,?X|-$@:@+WmAUk\#!zPX~8p 7}6S:r#V39cϹg*&:3dp\?+/ɧc׸Wk mwt@V!kEMȚB@ '\PUʊ'\imӇR0YCZ-- X|-^/{2󶓹,`Mo jLS"B oʦ:~ Y.I*n6MCWEIC^J \y BZOfOaMQ.Uo=W\g.cqW^N՟d}o\v-YLxק+cֽ ډIw|eWquL}Rc׶-SאjYB<:9j)-Ά Aoɻ;aa{c?-͛毠U;y̖/ ǏJRٓ;F3) BǸg*xebl;.&k)gh&a{h`ff8ɼ ]L鑸udn0ߪ1ewdrmev_wAŵl.!sٵ1H*m3yp8Qb;7 :v4J C7N&9Er]-?>͟$?J N!kRsrr/;ސI(LE SCRZ6&SiShL*Br"'$iX.*#8ͮ^ X6 - 6܌?cJ]2}<%^z.w!3f@vJ!  |X"M\ڳ9㬅z,?O<7~ }b3=`IHШlŒ Ɗ<x AXr[\vGn^̭ B P㧟G ɀ´d)KF<%rwsx!K5vEpcߑh 5쳏B~Fq.}]b"!lZNbJq\ږ78Dٗ, $A0!$ʃRtyroqeŷU 7/texnWb`$| #J'xxc/4=س ,N@-ExqL8=fZȳ c9]9Ģj?|?Oh2]Z{&_7+Lwxy}'ki;$dCk`>+0>4t%܂M:"9yϲ(6;*[;MD!n YDnd_f`Q{!fΩ,(E#IAQ@ -JҢVJ!{P˭thY2T>E5sJWE۳2y}>i3J)+M/%mH?d>옆THz051!$;xխ&FԆ9w]'ofn\2wULYS[Δ%˱pO^˂jMUQ!R8qIZ/P>n[qtFOf#dIpװG98(Q0zg'v}*;%^닓OmCN1KLx wkpc}TAg9K@*0ݘДd݆=,^4Yɤe'gfLKmU=[ _>"da}~H|[QU-P._} $E%yBaY%TB4~KbDM%oXDkB2/(0MmR;ܿY:L^apbƚ9*sej$BoFha'ض+Ǯ >vFYr=6,6p,SΡ{ymb*~u}p^yuWW;AUE ɨoxYhNTE}߯Xw|Qx@5}M_K5 IDAT6Xئe(ضl.2"J"fZ'-WeB5" l#㻦29V}M `f,V-OA/x9\\cqml+/y<+X~M(pOSHn6 *7B6йopsIEٺ!͢ڢܕ|u\y!?wX,r?hG!$C6²LdIFa0z j +*>IVP> +W0Ly'ک#1]!1` Q{y~eO`ïSinx6Mm}"ӛuߚ$ 6stYyzbUu\zsO4E's5 j+$_佋Hn_z74$ /aNApx=ڪ=2?5%nDX#\C$YAA"  KMc5CMOD e4fpZt䧴 !8+9q,I|6RiP@_ฯԺz.Iղj,9B&@|{ED*,)o`Euꃨ0R ˱w6:f!.B*Dϵ:_^I = qy%7uoz 8 o{8dyh¡PI )#n2\ybw8d^ZAM(~xaaY ] j])n)TUrX8=ʹ^_?`3,xff;zl>hP:8ECTؿJ^1Φ3WP>UAn4%~oL{BM8]*LC&& %/y:x2޵VAR?ܾ_OR=/JdYMczlc T"w\'&|U1hן/]P:š$"&z3Yg!VO$X lTj[ T< ߀aޱ!'Jk+fN/kjk,>I좯Q8Qɧ2t]/wTj&ѱTw`?/Kgs΍_g_ N!)ߺC;Ihҁdpi 4rD~ @^WU?up 3RHWW!gR6 ʉj0OA RO0%P(B]}#S~ΟHTUIS;GhzYVD{qm?:-vZ{9í/ϥgЯ4X=W]#4o+GȉeZr#;\ͬ N㪊| 1Nk'U;{XpDMO|:V>WVQ3]bʜ&m̛v;Q9$U |x]$,B(W"3.LSM` 6˞a@L1=vϿy~?gG+d$I"!|_~{ Gb\z\ðSY x}p9t.h[O:](fL ]._a!ŭO_mҗuI( qMӘ0e2\l'-///C= )Xϲ l&vq6vFOd=6{+p8LP  Tlf4ӹnCSƓJۘGzPpWbֿ ,QNvHe]neMxdvfQ4ƒޢC0ԁhiqȠIpP "? &&QUj51}>&KR] @ٸ8XdI01dl$&q<z1M qUCUU>d@peCe A=pq3^5)` ${ϳ(8 L= q-lZ3dad0L8O;/j֝a"J(i~ɱ*D9Qs0ݚHT?" @ !$HQ%F8qn ERIՙq jEQq\캾>(erF,QeHWDSe @?X3h+ gNڻF1"(SvAaUിJ.aٰy-Z8;HXV%G(DD*M"!3k`μ) W&RH"͒+=w2~$B1RPV9bM͉}i`|V4 4Ϛ]|DXvle $:Rt7&Bo?:i@cCcYӱdسI>|Y9yE]QӪfOblS ($[W` Yv:::42(MmUy?ɶ$R ڵ wdSi4q*#3URA 8qhv:餝vZU+2xGTokko&姈1mp ~N@ O#*i7@(Q񪨢D_37(0'ӌS';@}dsz eGI4AK&d:C4 `Ԉ+Z6![_HeNJbQbTME[H7h;A県}5e)t1VK`uQi,xQ&xWJafR\|^76a&'SOjدaE v/]Bt9Ba˭`π[<ZLCb|mМnMSkwsRVl ,;q]x~R/'p?c)? m9Vb]<:+<&)/Qs/+fa[>靯ڈx%===L<_(R*Pacs L lKQtLWϵ$ݭ椠5m,I$шz9srEY (pKYqA,5dQdP2h RLQɉQHAɓDZatF{<>acۑA}Chb]W?ŰVý"na%S2aʰU)dZ0:z7ԿfѢX"&ӚsgfǬd\f]]3y&s-`?]S}oGϞh33N9(݃<sI C( .6,ǟJSsu~¦M0 %q'4%)t5!+9e2lF4 I.VAMx kV/V(~2KAhiPhqqq[OU|"%B뭤82EhJ3<AX}᧿.x#x7bpI9Bz;pC X,XJIxe5LKҸ^L{`$hF#l{)r ISF/ ]DD2e7Lo4iE.{6aDV]h!>?sr1gDHŒ؃s8c&OWϭĢT&++Hi$:g) ;*VLec 5ԶFTZ>X¥(dSzy# ,#*ʊ,bAɒg,gP*`$mDcqb$x2,bZ-~h+,Wq3N7ⅇqThU }<%Ù &&[t!ODɗCOUCW";. fBdmXCSg |Dh?w/sYg0uSnVj)2amޣV3M=r5M@qE3XN;2"*OZb06drͭ9iܿA/ cG矵{L]r sAv?˴|֧ y?OeL[7`JҐtJ30Mh}CTX#or D{ 74AY%}@ 2E6)eQ$J4vx?Ç 7| yQ3zʄ' 3 ܾ ^&`5ܺJR9pAO\tdMAMaqPlAvOgzK֏c0O 0MR>&LJ>B#N!+L !1͝W?uzemt\! |uPeկ}k 0hj7+Lc#a9LTz etv<_x /ΟQ޴'J\wB5Si_`+ŜJzdk8Nhi3`C7qCw|圶`:]-oz=9.1^ޑ#MKhօ30=S= ]Ѕɭn^칳0 '߰ +^p#ʷX,FP@JmaPvs-v$R*i4Ҋ4W{[ LLJ;8^@ݻ- O_wKIBF#NQ}8eȕ.(>/x <1@T3m'N8 = ݢ_W0i-m;vD5D]z޲ѠY,X*a l5 ص!~~7ʳQ~3Myx˔L5^>s;Jܳn =|kt x^!ִ9X f,M"-'!ZZ^qSQ`D4 i( CR. "l.&2%0Sysu1%^uM1> 5shF#s;vΘMbOa:T,FPJ}iθ$Ynݬzp2,Ҫ)q@Q>՛i9s.]!/1,?mA/JXI,bm_˘)ٞgOcXfC 7l\U Ívv@ B1[$%Y^2V,B.g[Lc+ 5L0,BU{iOPkE *j'!x x,x xLw60,) _aD6 b[дwBd(ඟ= o]i8d ΄GOWn+y.4jAn <,G`],YtxB_{ Gi6|$Bm20~@@i .^L`oh;-ʰ7~`Tg@!!ENk5 cGp^[ `΅wY^?n^Qٖ~gx_b~g3wrϒ/:_t!|_$3l\,baC! yژs)K%XG|[şN*1 e%ͭMaYKƷr%̐IibZahp 0CDN { eaߝ2"L (N>oN]Aˆ MQgP0djo@7}lm Mu^`v(?kC߰SfҒ%IS,hK$:2+ß82>#FxO骚pp{/N0P(W7rД7>zXQn~{9_ex |39]6X3OC&۷?Ϻ6:y1h5rulm9Oо%z.w[gL-!RA!֨Ju V9CĂ~Z&C>Wї#>=ɜ΃P-Vipg92k?3F~w>˯p(P.p.pl 7ND)sOɩmk qSWpբ@x˜ŧלYU[?yYĴ !.XĎڙVFoc`O%fagi/o76o=|hg!͘x7|y9  vnxv olX K=<fɗ &nsWu%:003v&=N8z|O2Mq#jp W~ϛ$ S(^ܺܺ 8͟LC#W"񪗒9>qQO>e`0/$\y uʸ}OJyv#EUC5+c8N)4)H$(KD-I8ٸe#屖'x')b-\[_m۶X|/'?ofȝ7~l(Չ 4'*@q;Zh= <<Om4 <<4&;Kosa \ڒ0f Lc:5 " >"vҔdɸ[vmOd_CJh- 79 LSRt@1jXD SUaOiF 3 \$5j#qg0p\t:8`𶐕%NVHdH"(5  (ZO_s̴ WGI`–oqAv2E!F#!m%ρ 9j̹ ?~T;)ԥGÂ6W렑־dEplGquUa%9SØ1"@8p?=X+/ޣϡkZ^O'r}, kg{t5c?n⸫KG{ypc?4YlHD?c2S1Lmx,Y<)`Fatdݽ0aP* 51|Fݺ5=}Ht*Q;[aǓu湜/~Y]Q\l[;w]k 1FHaGgw_bgӑngiWb~|bj*03q_b^fw6#$ZIzqKX8QVcIOHT?hՊ{@ӨMV0e;9+|C$e`mժQѮ8RD,J bX扁լ s8Y^GF$ng>4}qi \4OÎgfjmRNP.\Ww]2K$b`5BJnGJҭa,v",@d\gv "G\,aLW- .ViQlEc!7~ 'OEpn Fq-@ǾQH8Nd p=39TVꚌvaJl+O89?Y2zyiDJLIhnNwnq}R4m"c/o36;T |g/>g R}/2.6\6T[#}t݅ƣ#Q!Cu{"Ǽÿ>O?'D#\4)%]gy\31aLb7""]ǒ xG8帎T:v >XMEHߔr\W`PǣTիgKe'ɠi>h79rԤ"]̚TsX0ijiqy>x;ǎLiFV}}4'󨸨\|S6c EW$yB\$"cL; @6-'7=;쪿=?Sa o#;ïc'us<5]vјϮyȯ}]>9h|@1hʫN l <cQsek+v֦u ܥT?o13M;0ݝ9Y&rϿH߃clnY:l&͊72KX(b'$gNaeUÆ~OpȻר.sU+_^ڄ3ͱq܆ tNGs*`L&)PP,a@] ~k/@VOC.a6gE'IjOBA>BFֆ\\"$;GT+)9|ŶXJx2I"&Lat4- BVXL"OPMHuOd=FQj0YÚY6^~}e㸬4==,8Pv;Y,5ֳ掵|˗- b< ’JL&j " p{Wwї:q1KOp¯ &_ A9l:T&&^~]j0]s* JajW7*45-Oo!o)|<+iS}X8 sx-x0G!{SXaly'6KN>%[E0S%O%vGQ*xFuM /ha)mc gj3K2!V J1kڄԦUqw6 7׬zߙ'~z <:,_np)NL_#>G޹tb3}?9G-KW]%/'4<'?asc]W }>; з^7i-vF0QnPwM=kA>{1g#6 EGf>yr+9 558ۊDUԉP%,:;z9<] ed{t&&7v~5,S$LI-HtBk ${&f&Lm²mLK?.MCa\.=5KԭJpT}y|@~b'45 ˂aEP)4hq+Q݋vqܴe=$N ^ 𢿙͗=b???vLnJr/ns|5EPHw,W_t}+x>J7&XF5q-s7>(WnZxA5PX5D5pCicb#/i  ) P8s)ϠRݴwsi$ek>H (ZE aG"tZ{@c4){E"+}y<#8nY  |Gn@ټl^"V_u|^ .Ug-wP[uT-3nefLF'.\ˁКP 1~YVNJfM4r `FZ"}7~zjDEĎdJef:Џ301k<@mn TcWϻ?ÎlwTM$%Bۨօ0;<~V-̯1.{ͼ,0R>b(dq\(Jt{Ѥ__:UB*ho 2#\4{hK.?*DcQ稓rk`_E:#OgÅvV ut6v ˎHƿ{vG|Dy!IL˴KOW-9E&|y7O3mTƜ(=/?C@xO?H*Wʴ0~xxc̝?c鲉rKҥ-ThD"APĎǣ,#R`&%pgK9ƛ95lʸӪҊT kATEkȴ&"$I AQ$H&-l"DՈq׍wnTIAz?$="*,Lj߸*v?Q.ՍK@ }sK2bb>S:a0L"ai`E"DIbB$b-h3UMyElaB ?j^Qׇm+@A.2 bKc&u3ncPrAe˶-<-6+[BN<|K/b,p(!ql""&ʸ]K*sLlϸ> ():Q%# /ia~Xu-jbG+ن`+@)r} зg7}| IDAT{v`/gG0&$vS;e)Kk5kpԖ!MPa4" SvݢMGSѰ~+AkA?$P?8;Pn4`p|L/fNoEIǫdϴ4mR)hZL׬КW~V#Ec1&L?f\u">E֑tJx/WX=HK/g'nZ qbM~w$oZv6SLw9Nq COVoAKYJ\ʼn'lts8qbA Eԏj)LT̏abj`H.Z<ʸGYys~MP.{MqLxf(5in|7|)d!1.Xz pkehԚw?[]]Xs\BK(M}\]- _˥{{۳ޞ fpB>:H)Fc$Si2M-dhnmc:xD)$ގ `!P5NH;<]?v4@lxfilbPkh{iɔ(+538 E h{>\Ԧ_R((48sFr ^VTBA4"V vg_H)npZ V6N/5[a%PA@kG=An_[>STSg)O\+bK$H33-d2tH2TRҶ#_@JAWY꓅3M~hj>p۫׷׷oR l F,] R ⶤPOSs}K_X¶/cH1]]L4۶GWSIǴzw"2i _՟,Q*J,RH9¡(e^?2yg@ yJ{lj,y)QB?PBL,CA!Ì&XLӬ:T+aT*) EZ _ 15 l%#j%1 !@JxIڲ´DJ#ӎ螖 "Bc7EP<A9@yCU{n.*I$ <Jx\E딹<4X~ ۷Wt0#1:׼޽rݥ‡}rDtԪ3wDkFx I*AT fa! K̙]4iXH$J xP/gQ%KeY((WHQqq)RdP %K!1%Q:)V| V*BaZ!l{TB z;mŋnzͷ0i'-#b! "ñm] yWiْZ;`Rѽ3IO}嘴 z1qb7%8@ Aho'cIH` "&B=&š J%q}TL2 %$Y*x@()|w158<86k01i6+24@kj+*o,,Ҥio-D)RĈ! ӀZ[ R C:H b$P'Mbc=dfG{8Ӡ}P%eU"SJAB#{ :.Lʥbrqx2ԕnZQkЮWϔ۽ڢ(㐈Jdޠw_=刼?V 9[bl oy 2H%JɓENrWM0aT;5h&G8diF >uP3liB@IJt* P'r~N月!8.#7#;ېS-mӂh6eĉ,;%AdR"m.l-s̊I6jMr$(%t$ ҟ;bu[x™l,`YX6#'E ZhfTIU2n+ V6 ?A*H4M4)"V!=a%-.h W^FmO2Am@ ]6gr-9ABR:;n-(XX,F[:aElLägNMSX>'9Z߸!fWwDwlp9׷׷VҜ '\Xy\U>nt섐@ PVATFQGQGg;8:2 :(# @ 魶[U̯Ouj}]y|! ?^xLS4%q'^p{[Ym zI#$>ڼ+>7}B >p(oG3ʓ8VvW "N=[o0Ѕ(4kbΪSu2~fA(` ]ƯqYӲ3Y-tOʜ6r-mdsԍe6:[ԭH! vSJҊ[hÉ|S]XSOڎ\bph*t{)oom`&DǡT.)Z02o(bΝC EDZeuj;Ft}ÎS~Nj~\$*Y{_'mG>|XKxxD"0LOfseJ2US"LyA"mʦ [8؋Xfu L*2l(#cqUԸޏ URb'u9λBb2 e˖#=c+üU0kaXBT#L"Ji J@a~_ϱ, j[;\qLхW&;iX]N1Jiwc֟5>NFT]RrÔQJg)vsԪ#uL yoy5N>5eM *0sxfl=4$Aێ<h=sСhYV HEIK&- .SOf]3WsV:9m|c9~^ȗ~U7MNx[\D@b6Jǟzɐfغmk;FeAqk&'e< x6< 0 IP4o%9G88SIJx;jckߏ8d@`2@(0(02bʸ՜؞6wOs L R)nbkӊ!˶xx ADes7z޹v$QXUϪW͎=)MČ@%~h%",0oQ ty+G7b·湇ę}g 䗔[V1%N^@jIu[U0- CΟwDlK&x9Ycdx|?4V?{ è\kd`u @T#4IEV|ƥPjCI Pga1sY{O\w/<7z9x%Q(p}}4hJ㜳si4$H&ux*^0&xK4 * Kw+zFX"E8g  _^0<|4.M sOva)(mqd2ul\͐lnqp'E/uPL&CP$BBS؆ፏpGœzB^o{=-W喻oeufT7 .W=5(X9Ga J6'ʠÁ-hZ~`pB:g%&J4Y<޿h p4acoyRW|y)#&Qޚ紓:Sh?ޮf VklxER jxGYrpPJYZ?x`)tubʠoƘ-ew#oNl}s7]>]I5<ݺpN@ CX0vSD*B>BQ cTM$Wji%W=Keٻ;6$*л) : (T,ĕץ/Nʅ^z6# AzN1>ۋpj.x;Gja <uT*\.S.)JJ%[\.-.y^ .!ib&0 yr\ݽef)K4&D;u]#xX߷\?J}<HQC 4}`֎ִÈc?.dg : 3,;r 7>v]f> c&n?٬w jp&-NCB\j-,Պ'75$itOQlZѯ}JPIcI|_nJFH͂uՃAZXE>D8T[J91rlZτ'A7x6| $jq٩>a%I-7piU߷p3,r|7]Œ| 7Ԑ C*Rt%*!aUiޔmy詬;S9v -p!e:mgsz8-'9Q?8̋Re)S1 zf`Ξ A)0TjR.d+ٴi3gL]jR^lْW PW P'cLӬc.yL`k1\2ۓG{,&q|GIΑT|%D"F,Q.ilKϗHE9.np! <=%gàeozDaGAFeJ: MZrqh  ¸J94ďC.$V]_Zu]0 =(ROR\,{n,{eCôd r-dxɴ^ǵr>|]z xP̪R#y>Qdu+16|cDC[=5 qz#< x:%|KŒ%2~w9;67Oݰ >&?(q՚e=cyE~Y 9g0̯߷aR)q˚2-[gҢ$5^sR" ?="fql[d0aҰc{a{ÎJytX0xfjBUY>TR,\}O|_NoK \)' IAAd O>qXl/[J)'JQD*F7mz,H] ^1DgCoR1:y{?l(̙s֏[*aZv]d+ʤB%#h(Sh=#G8⛍'R_DFsF>[(h \{CyhEl$ڲRJDEԪ2Xơ^ \ |&\ IDAT1wA^.B`'Zvd34+ّqksFv;d~UZ"ϝTxl.TzzְB5cϬSX5Q"%lznӦN ssVq 0 [bm[ 5w@ 3\8^ @X)%|11Ioxenb hooE"RJJo=> Cs´ ,[Í? lB(d>6a>f)ROv.{[ia.;e1a<6KY3Xh$2V*QZٚ[bkc9ؑB5qh*IهIJ$\ 2KJ0 B>A!эGhUo48 YIj]ƃt--adalcoÐRQB iZ7=ƖN!|~]}~%'_W{?e.;c)F  0f.A_~v`{|}@騭$DS` )D!my\{wAe۝|sU+_8o\etLfqfϛx+(>˔jD*DJm;+_[tQ6֞wcGc:U}? 8` ǣ{kˍ^!.ԈCw4j]]]ر#8e{$gFt%CaЫc,7ټCe`՜q#hH :{@U.&VZQThѰIhQZh!OL|˩-r(_Y@*ʤV%2wDYRf-J(L'a6VT("BTQjPEQ:Rۅğ>~}Ii0 a{o-zN~^հFꃨú~2Ru$a8=Uh1[y}ӵv]چgIn[X~5 . %G?t|R~n.:}gZ>pG1?zw>|-߾{k7_f'?r OE.u T:$ R-##cpІĕ1[e3g91HCڂ&0BB+u]oqeoa sl}@?QE1m[IpM\;Ĥi1FH(TTJep'pIkϡR5)rWHxD@%smc*hJN:ݻwV2aD{U:p^ 7I~qh[mrq"L:ΐRVսLD $'UQݖS92dM6Ҿn2=Վ Kn`MUD4-ZK.~DTF6 44hRJaH0D3ò0i9y&ab&ia0o{5eQ!Ϥٯfsޛ-ݍr]R-Ys5Vly3ؖ D%\(B.c^{>/?BT;:X.rnv"v,)hkNYDO<^yW﹓z|,+Mr_&otRB%#ÅX3"Wo_ 6b<2kpdW պ)"ZGs߿|}a=fo<R [f~\6 E5ѝs国6ꯧFљHzƍvmXիW?b۶m[N: ;'D;8զMݻ_TW!~m^]l\ڿgW'GE)&^Hv u<ɫ.o懿-~N]OurދNrC><5`pV?.K(z<㧶>a*E`V;LG vl`" I59J2<f.߬Nm1X~ <#J%V^[ra6n[8SkTy56^;vC VFH)E6eXtUjft G9L Y'&3 4yx'<*)2%Y"4@$ .n*YePD"%JRX*P)81M#D@ =twwyOFWWg ڐhQ ]TE݂t }T<7PDJ[T<G}v)>mj"E4E:WG*Q){M D}$s|W:u1gj9Ha2ZVCtMͻCyǣL>O=I S7. R{35gsh, 7gPIΤT\n$GU'!t[.S*Q, w6|RKssL$K3X޼K,?D<4i\! ƧRL6N; u6lԧx;\@6EJCز*Sd$^ &KuuuOC)]EX:F(n7;L:)OzϬgh$+D)WD%LEu-H>~jg'HiKfZ/"HTb]$ljnl,C.;n\3t7$aEXdjO+WMU"5| , _kBNnH4mU)uR<_ۙRRv5ؒjW*aYAPe*КkEb%m::t5KNGW@YbY 9>G6qD?@)4LC5{:%wӲ( (txu:\7byMu܂={.W|0jP&!ɒZ>c\R2YC<ٿƒ< Z`hfԎ;MTb޼y̚5.({E$%x|X\z)̛h/APxYD,%XdPeCjg3qzx [SH@Y'|"-@B*u ( eB[[a$}6r:}kW/N7?-Sw^n[? k:oz8uagIRJ `R$ Z_˭T[H,AZ}*n !)3{Lm7>%b/}1\ŭ뜅JQs<_ŪݒYgsui NpYɆ2-a1W>w.٬mP ">a:Dsyd.zX6Y]̢:0{aB5 YXH%_rA c2SQ\cR71KumؖiۺX")gg Cny~,;-S-3\@֔@c4m\h@i_ J6 u4i\I&YfMZ[ޢش)w oxyDpZmT"Kf-S #:00evVY(-eCwɫ`+ɅPhGGb<an )'6~ 1^z",%'y~^q;!NҎYJ * biyn~xmA`/~)+b3MQV֥]nw!`)K`6pD.S00f"Y($8r27{ȷ)EDDVh > Xh-njHpP׿al&%[fy %gYt\)R4cf$J-~C:9Zh-Ӯ6ZD Yim9[2H̞ AɰS38,^ . {q'SRRQt t&5åUT T"5.#>KRdhk :(:Xcƚ$ߚd;wg͚ŬYꐮ(ʕۆ&OL>bMNByދnsf"`c$f!B%G3c Llx폥Yi`H*ur h ҈}o]h!K!EM L+?vnw~9sw'[=pkq|3_Y2o 6Q#޵0PQ[*2 BT VqkaނEwvXZL +KƱlc4l{D?_`I+d& dPaI,+4tաmh)0`霳Lൈt̍]\򺋙=gvP{>Z&΀>9r_aHlT7V6M&ID- ILG)$4)XQ9#ڼӢZE9*K&յ&& EAHI:1jԂÆZ]Q9*ȓT AX- sRyumX$D{Gh Ǚւfˆ5u3]=K/~ '…0?cmv'imO{gy *Os滹9{8D0)B̸Z0M8քd`4$G!n^18]uON PDq$1mF2DU9u\@~M04l&"00b_RЫ0mwtWhrA#K0Ja%f`)i ,S3'mqƩ3XgY%2ds6aONpl.>BN?*CgD~x)63؂[ZLLEhbXTrDի Leb)+M[f)+լJ%E"bJR}q5 *^_'G!al[+VD-@(eRWZ893t"<ؖAM3J#2M;ӂR{c{\5J ^2 /d%Kg?s΁? DhMM l \}QVd+tVIRa>l j'K ;i`SZYbiK)(rأO2g\nocYp:QWFe. zroc5p|#ڲ~X `N'%Kd,h&B1I.TqJ@MZC FT4].gKCʲVɖ(#eQ"+.,*~*Clyn#C%*[<,EJ Z6`gtrɑdq2YL|[mNNO'iqx w,Y~4adڠT*i3ggp?m,,~!' "k |S' p&Kť_+WNhɹjYRJ`ٶM\%#"[ݺBgg0nۜ e k<~]0'iH~sͿpWyӍ'~?ǿQڷo3]~&;+Vb&+)wj߅f4DK3_4|νR~מgp5^<>x+m`~cyŧQOЌ!}y}dDf05<Y2FBzG)ōceE|'ښNXjZ;fBDct-gzH J gh>ThOz @A(QJYO$\N'@v.. E^Bw'ә`9\'Mm%lr'H}QE ero~KSPQ+Ihy= t+0LLx(B䕠Y_.U+<1ƾ`IACPFER#_2Xp"T8^:0 2/14^3NrBqNN?AAC:vW;T_w!TK"Y^qι“; 8_'Ƞj3]lAW +R tذ2e~s|mo|'u'}fI:/~B%@+oLJ j~A\~dj>o,@W(4h$GRIqbһKk"EL&C.íqEOvo,;h R⵮p eC,REʊUyVˎQ R*uQm6V'qaѻ׼0m$JܐrmOpl֬>{ םaHS7 9!as~=R,(z̞X7,l)ȪgzŋXbQYg JKQQX; sb% u8N,PDUDzBԅ%s%FEҹl =W&…Xi9[.fB`[P(kk铦۴)e3@ϥ%kg̞mEoJ:/_<>AvRV̟JN`ղXk\L Btd2Q̴at~l\-?w%J"nZu IDAT[WhUPQ'ir4 43LG,er{iA&ラ Ԅ"כT3.D eЯрx9dcec&[ٸ9,(ulє5&y^)k$lgog^1E;MkIsDiB0gf |>v_ǹn3333ƱucȦ! êeVo?*p`AEzrE6T*\;St(\ `2v?Ȥxd1+׫ShСF 4u0eD.D{ب8xa8d@D,_)Obp_3geCd c%6QL*i,}ʴy|NxytL&g\&r?=۪M6Q8<-1+\9[0лG ~*f@M+UI&v2?Ke 5 --fQknH'ڋ,Sٟ\z=\A(A8}g_{_X).]],8&wM P3AC@[.>0:'pⷠCzm-Z 15ZKT0 6yCtQ.7DW_j'o;~~9Ws>7LuNOGwB2QR*UbMz<Ҷ)=|3_Ž}3 [62+mGbYxN};OGDVag1l˰ӻ1&w1!{5^\3|…D{ȍ^ֿ*e "tOwW7Yv_~Gv0{r췞EbEiًW PɣTI5P`*,ٱAH@<:8dɦJܵ)!ʨ D!dj}#ճQڻmfLCƞj5jBʚڼ*'z֬jP5J*Z0@,v6_7C/$8kԮC ؒ0Nrڲ !(Jߴ 9s&-V [l[GMy^{,YdT hGČBaQ qp]PXz"<Gh p pA7G'tǁw&'DĠx_w9]|ϟYBzzs\&/?]_.aɔ6wRW[TEmccIY01n;ͪc%osMi⽘XNǔ|VTK3hr#q`BƁlZӟ4Wllb jvR_k|7]x K.osӦLמŋލBT+.GGr$GbF&Y&KYXUvt.c|]wDHIRBW-!H0s+ۃqxЏC'|mxK1TD[d+S "מö38,$# CB O\*6jd+pFkđX m}p'} W7c۬mVUذ9~}ǯ8lλs#@VTxOwQn_Ț3DlyVnx`7-C轋/.E.5.Qd.}0Lw/[MW"TNY"/ 0؇lAb]z :tFg{駵K#u^v=NY340k{?2(^d٫Xf6[b~WcR<0XaS3vpo3r e&IIqL^" _H T>>Nh +YX/<ϦF#)0m`ZL| 1- vmӲ$KأFʅ>r\cpٴp ^=Z^V3T=Io7 9^U$lR-6|N#xd󣬛^(L%*F2H)_gn.oȧXW) YV8ԟɾ7sgŔ+矋 P` Wq:;SB$5Kx?^[J'K 71Ouvvy'I.\.c-΅ 9AR٨Zތ'nB_8maBҺl! C Aj^Txvp%P@BA!Jn-۶pĂ`?.;FWqؤ *dß$z|yfui33|~{w֬NIj|UgXdmGor/'Mrg3r8xgM[ĂY(_{X9rB4t+16~˛p]w8qTLۦeɖnz PB' !$ $zI !7NnɽI NhBh  ۸wk%mr~ծ]$qg_ٙ33ϓ63&(,/JU;ok:B@o"|֞ ^8uҖq9K^I=#G(%mq^Q5059X"d#Bt+.RWKn7w[ō}ӟAppv)j>G~TxW3D~_'ߢ*4`rJPê⸶Zb_c)Dhb߹MYheͰ۸8F(ӟvv2{m{!t"e:|2댏W!;;r?s.X./ҩ ^rz9v_Aql4} ŨAU1r:傷bRbX0X5hU?˗D,ֿd۶mtLԲ܎d-][wӗ#0yfL rSB "^d'؊LsAW8}tM&.M# }m0PҚ±>vnNٸ2^y m:=ğ|Æ")[b9X0Mh^xm' d0wb|_Ea踞KwX2D .H,n*e kxo*bu1I3C ŻtMk [ '瑶SdN<"Ĕ-3WC߆ 8sW_?T8h i=(by*XttLvA%a!J(69)F2S5)T;I&"Icg288"!T ='LCvg}=˿:Db? $"Wii^^ +'iJ7&zxi1c, ;o:tM44,i Փ < \ < PR,t4-#adbt4i@DfV;h( k_āe5McIJc$hpe-f[v3 ^UE4`ͪ4ez-&n 5mӉ临 =ڤit8ܼ4Ppy2 RE ̟ n k )m:>~eb޳ĚB!ҽEi:WwrC.ZXl+OitRRmSACCSXY+%JT !pkhR˂;DCs, idvC2QhF*0t6E*(!K,Dmň[=Hi+D/My1Y dS0þr,elW+XcAٜ9?4SNd vɵinЌ=jϲK .aH$hF3*Gq&VGֳjml# UmZߛtww3nܸˣ%{p·8Bw1qxo]W %QJ?IT:>nYrH4w?;|ffs8gі\OJVr%G浂 Goi P)FLNe֗c,(2`I <2ytL_؏] $D0Sp'cξs0MX2}R", ߆BJCRh@*J ~ @P4$b4l8"6Sp%Y.}_m]24v:M&ΤI%LOw.o4ilizeY6Wcӵ֖@K¢Fz]<`1zd˂W_5c՟#7u# uY{TUUKccn{hAfd?i7C;;xnhW).q]7{Gۘ޴Y@ݦ\d^~\6dQv^T8;u ǁVH=&sWWk>IxԔ(h9kw ׎gLRDsiHPMr10q=I*"JJ&IS)2i쌭>Yi(+ ¡V8VRQ@gq,*}-v`ݎVByr &Awj+a7f_b~8׺g8K,;uilldƍ5 L)H۪jNGՑanGFnǶGttf?j焹SX>,%XڽNdbkmvy81n2 6% 0K1H` 4|so)UM|g2i* txtO@u ]:~%(З{؊U |- =4~ SFۦd;8Nn8" ~TNA DIoS;%IRIgsGX䀲8qnzـM<ķmôB  GG#Q" IDAT55D"QBacB9M>$%XւVTnr}OB!4`H& !؁*ܨj+\mݺ_~08'JR)~F;w.&M*-*5+XQy?^Z\jSU~{ݜ7<=@kϲ}燹Xv-s-#xf*++IO6Z ҟS4 ӗ)Eo‰$XL>͛L>~ }g45$!wZJ?NPuWO\> dSj-.w^V7v]i*Tv'tt&M`{)M=m&AR ^u14J_TK ɳk)WcE9tHkqVX+0]Jt'%RYiR+@ z 0H9PE cNx~'ygjˤ ʣN?82SFJ'uV~mƏŋ1cW+2fd2l0?X޽=ޭSiK%gPn,$bF殷'/ޟyȑxq=Ku]XjnUIJ&E,w+:F6Ȅ2h1 a.\a477 ^3EV0uP5^ V'~:ʚJRbhrX$ʗA4j5)q;VW&l_mgǯ_J@H?c5Xb]!t,)mW0 Iภk**ˈ< ,Bߩ n4O#Y)P1덙S` ^;װ3iƂvx/ȩ8`i@_?&M_.ȇih+`ٞeo#QJ6|=CSɔ{ut%yGc#3eÆ |TUUq}N,#<3~阦aY>0aBY_1|Cϙ<['8r ta >t](N . ͳ\Y@,b<ûDQR4pmzt?]0hqZpY" a\ԡvjh!7 K"*v:ihY&,P`B}YUI z,_wʚ5+-4i:fHi YV˴W(B]C44@ t]=*}Dr*/FC@J9ܦ"X%+dT_*Ai@\@U΀;(Xp,a 6D0INA)>(b4"J`0|ߚnlJ*ҏio.ZDO6˞TUG40LwS?N {ScҤI<qiihh#$N3ϐN1Mu2e Ext'Hl٢d,+:zd2ITFy\-]h l[R9|#?` yf;Q:@R%8b$E" MT /]zʫCSR',  il+=[E(L@C*&Ey7٨iRb8(ʉn0tOER!{tnENE>qX!E!Us̹GjcIkGqDUGY'ؾxn9E'FyNU˗e̙L }|?elX1;/1RX/K )**g.0u C7b^zzzyo2AC{=f5,ܰ$WID}CB2 ڈ] 6o*\sۂ|%- x2}ʖ P%CEH_է60Cx0N2/?UG~A\-~]>i~2q<_&1Ng6\r(n2՞=_$88 TDbM=) J鉧jLD/Qֱ420ؿ ;TaWngh{)7n^zivٳˋ\i6Ɔ |tߏfIc駇,! L?dgT5qJ0y)*?|qؼ{b\슊 Ǟ%ݽ۟G]]6'lil&g2e\E5; SOUOi I-z rrrDSpvl N b ەJmg43tpltn0w~rٗPYUQu ]ab;}aj k7+"zLKkQ &qP@?u8`iTO0ql`rs7nCM~%:cT둡z.:(&pG&}DWjpT\AP®:#V ɼ W|k,fm&0wrU=ȈY:g+dքft}Aه~NSRӷ]SYRKV9;,5Y)%֖>q45)Up̞z^|q=pTtvYr.S&TXek+ⳟ%1oNrAaŶyz6~~='pRC>bOޒNwsr–NƖخQ 1`z_"ѤF[QDbcqprrAXEr傘bb)mrD[B(@ idIҲ*ZטWuQ8lvX˦-'v˷1jKC< 9'CK|斷W?Mu,ƿO1}|i'Ί7kF,w]0 }et5:࿀yrC( G9X>h2 O q\7 `2vxdz8Mf5QhaR`݊t=.f'FD{\A &>sp=7+,2_ ΠO<{¤"-'%Bv5 SG~! p1 >UEBT"V^׈"MOec1c,P[R};{0aF՚5O碋)%:y3;Vp9/i;˗sns3i _M&GuK0uϲ{/qQ![H =fy_ ˖ ;BࡘuJ1Q8=w6#:+vN~_/t~e3Rsw- Xնż+<~籠!+W7v'طr>_s#oa^Ͽ ~zד$d8+y(ޒ;Stw-/|48cWP^ K6EcU\,ϵG7e3ß 'UwˠL] \|Ƒ YHjʯy ϳw1 }(2Ma\!=l[89RWZqrL>н-2cHQ0uijP2P+" fyr\ϥ@Qs3D"DZP5 <:jD%`gM':[o~Ĭ(ܿu+56277mmF2aF\P yYM'M,KSS7o͖X,F*$ l%aeb?\9 o8ߪPn{S^4iCׄ Xo0`0#\%%n\"Ӫd@H%=EkKg<̜ ,DY6E_W_ɦ 3eD7$`p՟ڏru| wm1Axnb3 L8bNSd&.8iBs]¡T[vEue%g~*tUs {Avmqn?ʄdJ.bC03tCQO}J~Kts߯* ͠[v3[O77OXׇ.>./b/sAs3wws|zȖq(ß]Ynn XiضM4HˬRXPԫTZ\hg,QN+cĕ#PǬh}5X.!HJt_v%ah^K(KK2%uw,AZz6DֶNIWncIHyrNeOQ6N-ǀ}[QUY(>|;Ϩ*B_0GTTAe6ߺ3tg&`-3yesB@Dp=ṜpDa|{1uṾL(*lWNBJu`" No֦>wDយ{IX&TOB]M~>B.nn΂Ɩ8੧3H'<62gC) F)[ZKgg'k֬aܹz("cDÂA_R@VXShֹcFc=bhzKۻr_l)5ڱ25 &p<.h'kh0}N|Bu.Φ-TTTt%cHroz.m}H*Ќ0@/49 bmV>slV(?<?΅6a:JǮՠgˇ}mFPLC$k>c448أ'H(~U}#i$бF` y;6o`c|#?/?;֍twqC X"kj4sMG1]o 1"ZG$ܵ."u\qTaCv%C#nlY]YGGn}B0mS f]*}Uo:۩+w+eGX<V(4M$JJ`,8tm^[k?7cVavHēK<1GiqD/Dԯ39A(},=T˱睋dp]Z=`&'8O]Ye] mrRh+Wf04TL*I*$LN&H%S R{tt:I+bmޚC:M5׶2M4ea|-X o5XE n&;C{*wP gHHTsWuBzHm!(u"xC>u6>s!tm:}[I`yJ\=9<+@!{_jp >Wo2q"'&ϙCT FxD?{VsP-EwfljSN 6o{.Yq֌r4|m ϫpYs3~8DoOu$8Np H<7MJu+ѺRHk,jiJZaRrXpUʈa@< ˵FThS)hQ.Uv/mDG r+\UTgft.;̅7ocIS$6&RNU$:&MU8 NVH &^78^o MS~ |[=Z#hʵw ;B,\$MI3_Ǵ,,+ a„;" aYaL0,4]ye{n'SC}zN4-Af'a<=9vw)mRvH}TҠF?*6Q(؊ǘv <`Yn~[by?\)Y]]|:C'Ve^W 7sQ3Z}Vɓzu!lz>1nՆSW)6 ӦWý Kre=1q6p p: #ڐk8 8GhLkV`b$> dS_~MS(yp8' =+{WOrmW0g=b8DBHd!;^!Ẅ5:дt IDATxQl(WA;w/eT-Ɉ I}AG=@'NhHb Q 8>#LG҉T !1wF5aK[@XeE~QBV`fZ+[:߫V]w!ĢIT&+~bYkؿu}QU"F J O>9`^MED58gwvjjO}0jjࢋ$-eoq2 Ygg/=M=]hsE6,55)70!~۹CI9gsPUQ]Gձ2xW9ʼ"u8<ѡ𩮫^~Y᡽:~۵陛8jQDjT?_||Zٚ-կ`Tu>+V(u!CM>ηoĔp6My,J$ =W. *~UepХjn!~VOԲ|_MjhB;\*00Rs`xRJ%3 ,o..J<%0W8Xl'FJ_ז!U &M-tL,~' =Qrv(E\ 4@*1 ͠9sW5n(Vs3K/CBfpMF~i7O%/(x 馑.xIWɱOcSy~@u[7mM+m|C.\(%.Z[9 {vC(0[-% u܏ΟO>)DTdH>1# >eGG~PUDC3nwon#*e9| 9>wm^q핕#ufbnLjUx&C2k}l:S0s&z߂588 " mRO9\BhdrSux2:rTc~(\w9)Q5 !0 TpYOѶfX-l<<ϓm [2"mk62dD "cg&x9Q*c@ba qFFkyRV Lސ_` u0Ln)>Ru3eY*"!Sv01L#Kh#,x1:&N$h)+˦*,Z"EXXIU{Ueܳ 8 p/OF\"I&`u*7o&0#11lR]ͻXI#%Y ?UxpUuuqnmބsΑ(KAvڙ9}VPW+9S=N_͝ 6s⻈8q#nDOJٲqqXN>9/%71ᒖVnߴ= ,ⓟ47*\T+[~*E& b.*>Ku֛ǤW3FT>G?MQ{pȆDדtv4n&sN0}f>ʽ*++TUU,۶A!A2# bDq@).S\*7R4VIU,r5m+v\bm*tFͳkjGh˹LirW.V+ ϰX -•}}'%\9!{zj &4-*7+NcY&p3]=4~Ũ.vGa<4 #X2,g;+Ek)Jn[O H=ê, |M5LoO^ N sʝ p֬ARx4^2\Z; 8ÊJ"mT<4+Щ0"\wu dxlcY}04/q~c#Q]WGyAs T ~|s >OĈs nin{N>w<– eJ$kO\B618Jg,iR\NV̜Ki}+LCLy8:Y<>/]/?ݏ#=ʚ5ks_j,] ˋrq]tE=K} $I"E,K Mq]gׂ+),|AŽd* =XWKe)@wJ}W;7{_=0˿~0P38cXXEU"i7MUeR «u E5R8|lR{ډJ8e|x>߿H"1U68$FEޯ1A\s{@9,ڼ#&ASESN0೟Uҭ[J~RbR2i6?8mxeglh9 L._j=/%7,8`b d> ǷEs.2T-P=[;P BMvY:i9L6o@J=[pBm-~hGV__B͹Ύ#я_TVg[h` Cy}uy PϓB7B6Ќ (sS)8ψL>%+7SJ h?(7t nw⢯~Ǟy_|R\;+R= .c9 0- c XMzli*JwUUPUMSQӮg4P>j*j NJU`J\d4t6G `hm\>bDՖ>k36bXA}>Wg^8Bޟݱ/2)3f࣭-k9<w*s%;ez0TE1V#GJ6m]on%Wfz &,➆EZR 4(qLWIԚ]QN”؂bfgW!ECX4vQ~10jGlW_Bj>.KJ&T(.7~G\qemnǝr qv&㎓iInaMʚnؾ6"oz1hH4r3X N(3A7 vg{{vsvGoT>,¾ rtLK (86IKDks+K7ʡaǼh‹/F[|صMع>zƽYSxvmۍi7Y[:[;=;u+^a'۱KJX/9?.hڕ|̅|g 2ĒAa]U`-v2sNO`p1~o(@U4//_<7q͟J A f]u='?7\.Ƚ/TEq3 7G:ɱhi;*D:ٳg/:eO TCv1{#{Be{U46,V E*0M>`c J[6E(9As\twb˛pȄ~/S0\M0TE oH&@ԩ0g}woRɬYޕYv)s 0ku1cO7fcDTf8x&v5.'tcoߕ 8<jbfh`X Ά2f4w}D[c["*M 0kX-_ Y]AfY2fjNJu%_|&OFsLmmhoD׹uf.V0(>^z N=յ b)BgGmg#ӧX~2Zd{Εc8=|sa\y3JhG=TTL 9}w)G9+r B@Զc.7_p{[Mi4s ICPs,_WĿpω3mr=]?VFUU-[vH,χi8R NFhWH\ 3`2 F%mN_> z !Z.BGRw;QIG6:pNi)M 'ױ^u!7 0Y܋v2{mW7>ϹӛdL>|%G ŊKy(n7P}x+nýr(hNJO%W5=W$^p<5>WK(*BQ3Kx+/˝̜m+XV MՐʯ[&9ҕk)PU)-徆:-]6/Orv%t㡬-.M)@("k{6L fIy7wW[ߏ< xn #"!mS(b栙DbjF>+_Z%X&3_ST&3&ɣk Ĕɔ9xkfqom-Mn|@]W!"'D [e7L>Nտt|od_'k 4uly :[vYmhǎ;( ^}5X,6fUoa1&ͭ0 gCGƂERo5/="ӏ޷Y8p`FG3f)uF 3dT ȃ`UĚ6]:z[I@fFfa<&Q|δi3t8Ow+/)Rʼnxo*s4gy;Vnȃw?ΌSbPdNMHp]߀jo IDAT 'ZKʩ(+% .(  ut]UPp7gk'|E nnneoHOo$|:X}C~Ymݩq0 ۳D(jq$7om / zȥ~=69hm-[xJKVu55~J5s^$Oΐ;k5C2'?au1G˥K]ńAz*6D"XiB̶mn>E@ЫzaDgYWMݍ4{8JIGȫēa*ycg~$٠\oXa')ZnГ͈;P,Y?wثDD#JJPsNLy߿=crJ"*l(#O; qyj{xb|k ސ!A lkUN1*c*AmMP| h~ n~ 8)%קoUUv<|6r;QbM70pɔ.?&]{<ڪ _Gv,DZuy xY|mw>MS4>`mYmX}v_N2O^ڽ.*(Y^ \C<)6qM7q_{"7ફ.ctYQfVbfD7l zD[Z]tٳlPWi.ʚ.fB8(٬Z_ؘ_}aΜp&m~͏29;Oݤ^Ӯ*nܾF*4WT0SƜһWijrM@\o~{#$,Q'v913ˊoK6=c-D<t' v oDUM3G~'('}]t~P[H|ij) qwbϻɦ/H88n:B7;Vp%Ss`֫*]C(3X -:fڽ;W! uvG)DoQzϬ/tب|r/{4U!h˔ض2nX6UC98M 5( FD;P5g39ٔ`vP۶E\Ӹlj3o|>ߜ1 KfL~**3^^%y۞- uuMI`%@|=뇯x8?5ǯa% BU5]K:Av?^N/,(H!s`]zyr $]/ ;+}w_ެkzoyϋ$I_T\ې!n7PS4~XR#X onLȤ )ľ>&UNJee |eG:_W3H#/my qX^0RR͋S N/Is&R9,mnNEQv?|JKтRy?yDQҁյ?~<{"]P:,Axً}dV8@ E}7bFba}s(¶! 㸎30|vӁEـJ)S1fT7efAZeW__SBplw0~Αd8@aFXE[[~d9:;;Cބm43>./]|1gUW`L,(`\8@5Bq2:*T.v1}jXշIKJ&9b+OrE "{ސ@XQ8;{:̈́ Y)l'9EDY=EyWQGԶϧvLRٜu8=hxL;oh@}G=SN QiaN 0ۻNpMy҄H?\Co5%;ٞD)cOaRdxqμBJEg²~bf8Cf&Š6i?,G<GK[5<_?RhJupc<͟/ E_w2Kҽ$qљK<4F0@QIE%>=BLƍ1 r֜H*,FP4d"}2 4G0h~ u˸[6K,Kᄯ~u#ĥ4wP6!/r'|!&¾Tm琮( =s* b[v=PYH' -;v,-bܸq|ͬ\vopUWQUU%\H A&ݯ_y%<,l X۱>icNôM,JOB"LXՃ/ @:_؍o}\1jS':y%L9?_RZ*x),D2&n^5\.fiJ=v6ظ.܋YT8lFёcڶX2e  WOQ8 :{ذ'# )1Ci>"A):Rd9(,Ν\fZJ84-.x~k? XӔpignDA` P0&&yO?RRPig<:_iSژVfAHŰ-O]b2ƎÕw^|}bpe%1G9`0أ v^}Lג2#'dnjn xWxV~~~v$ŀA9g.َc{Mɗ;e/4Mwabe`~Lgyev(ejt|RR^92F~/OnnX8X|>/^ŋ{;6" W'7cmJ ٭%sߪT8#` 8N]ua9O VT M]sm_g8x0,Y" :qQ5uG__WTU'M ]SO*RXL|y5Q*$PqU!BYpۮ]\Z]^_ݖ|Aa /]AyEEٯi Iza4?_tQKӻs) Q*Om=tR?~tՇ,,CE\Q3]wZZTV"ACJ~XE@jߜ|d F٘|br<"ON¾Vӗ\oaXЅ!ӦN'~IJƏh]ۊj+ .1ý^zʊ+`n` )L:'ӽ *j=.9o/w444*/Bk"*esi#wFP ((*(򹪡騚騚澫j: P4 MQT MSQTUռwE(EAq'%)&n>d}ʸ0egQ8Hz`Sz޲⾗þ}5+mi`mZ -&i7#n5#*-'!U5c.'&僴z mS "ngbU8 p*|!,UpԄG?H>FMI7 Zp" mVg;Mճ2ǗA{;lsew+e@XUr0߾\s;puhǏ%¢Qع6oضS$#GVKV?pcKASu?n'Mr|! '!">PzI}i@zyի?=: p>FGDS W~|e R͒pV,^Bޠ~o}~CSHSH8+@HAt+k]jz$`ri.$*wۇtG'e$qGdi%ضb%?sPDf@E068_K_id+9!`u5'8֦pqﻓQGo:L _{[O|- V˖/0qZ-pY9AX\8k™W |pw*(az*|1P-<ׂެ6 Yճ( pwpkV L}$A]ʺLZ46;y2fn8\1EE{>b)Yh99jlSNqՊnYkdňnu=u gxp"FZlFWu '쳘U!j"Ll@!ieYS*1 7oa>-O.|K¡ߟwaeIB~"f+\&\0/h0>%ng3;"@!J?65? \ ]h3y,aOH$Hs OϚ>JƦۍDLaK,$%1,aJİ Sbq 7$q;t}tMSbߦ-1-,(*0=̒KIχEx0S\j{@1#JGc7✩kQxegJDAWr]YYjM޴M E̬8!=.x5!Ɍ !UxpDKWK;N=hHQ|o8^zسg_v0V =U$Ȋ\s?xaC4E ڸEEfԨԣSNIqL'gw y6r,hAA(0LzJ4zKJ}y/_6.Y眬vv V*/Q&!E*w\QD;Y*:73O=B'BY"Jj'<201V{J:.pđeô%K遊$aJb!y"}޾PI0%q[ӒXmuW,QWзJOQ\1Uq"Mq%>tՍD55& >_t./H~>] OSZ\]]蚂*PTJ^AZ.7ja\8Bz(鈟xv .̅F׻bUU.0 ' &`g+X nQ(ù`޳'7<_S(%h}cr#Z55Ĺ~;WJbV42楔hB0gߟsb<0O06&!b )`=)-HE&q&tfBd2 oS'5 ;;;;~4ZWGJouNr&e]s"Ԣ}}tc&[>;n_IG8.L< mus>i&6m? O: `.ΟaBp33_'bFX4nQ7\q/mbE\\1wnC?)JU'Çs֭|k`+,ٹw_Oɴ.,knjB{zx!Wj3ٷy5^ur[I f`@ԵH`K3}tĝ>WDžY75}+PAEkD Iݥ53!`ti-XXI}'=CjRKNNUHt! sʊ#%P"1,H!ȘxUEP='>BE(uI?[/aZKF R \AQҿsSϨDtɱċ Uon}d}LɌ1A $ϧ awS>y\ p5Դ uD*۽,J+`3pL]w!';f8XUDznwqYg閥lo8I/BeeVREmm;DΜunyZZ?OIDJu =DZ[|9r|ĠAiI{sc4ҖNdң6aXO\>9A2j0_(d`I~n~:neee4擋`P*U9kA7d&x@|#T5e^EvuߊgS@O=.c 4IXM 6mG*Npv`}7&/=[e;MD*&XHw+ IH0)%j7'"C8`I2|wwN=)3cGr_ԛTlLGx\ZR~DGxu!YT}RK?G~=8%_ir,#gnf?8et>sLݝ`3^}N&tc)%#KGì߻p|+A=Mro?P IDAT/RJ-)G2 fy$R̶YL/,LS&Yܹ.wꫳ ]ߢc?۠(J20T9=&')/RgL4"oOHp|!㽲 3L@HM8-I4]yQimGҀH:(&a;mx;  ntB C1"cw$c^G=LLkHЄdjeT˴QJYwtհd7n\i5 ^ԝi=;ѝnJ_ z~.Ӛ+7G-APUxϏG``o0Cs1{n£FAgghy% O B1L;d ս^㌻nȲNZN`.ӶIg'aqUC^Uk)J(a.-6`tϮ}mI@.tM}*˶H61iNMNL2;`Wdj*Y+SC \ugpY,:Y[386 )L`ݟ5K0~F96]d4 Z]qL&q<=?L/4dGz|8O-5S@~ejA%exg |}_:$ -}~se?(`TW4]a|`_ȯM%O@ U!vWxy4DuuҌ`K)>h/Bܲs'm%UUXɲV~8t(#L,r޽{'p8LWW2\SVKcy<%Kғ({!`SЯ:Y7UEJN Cw[>۱vJR:3fHLթAkZ-Nc0 S}(HWRqNiUoÖI>vM-nA=<|.f( Wܔ%>]8)P C nA!\J``317:X6LyEvo…Eoxå<[?`tr$-|y<ʺoDz*b$%FKL\Yk 0rά䂁S7 >׭Cph4/T̾NXԠI҈iX%Z f&$2=Gd ?Ef2 m:'9:`C,,OsC-[H8<{}dK;GI+;$A݅+15ILr`88RP$fP\qHҏLBqcˣlUCm ;0yΐtF$dK$R9BgP@zɧ-NRΡHq:aAN&,x}EOL+Orʼ mq>h|a [㌟6_b]_*C:yj-|O>r]夅LuB͵tlГWξ_/%W}v;T9@-c]Z1"?Sa"ds&˾=50Y62FMێͲeZ*7pf8 y͈w75}? ˒R"Hno$] |X]]L eFEg=Rb(K?qt4 +jv0%+Cq5NɆ6lGB$ R ӋeӻL9E)PeR9Wkcu^p| KC4)\8O')X/wqWY4?ĠA#:OTi4fW:,Ġs˙*vY#oNð:2kcGy_w`*m5h>yc|w7XAcj)N]BakN1<?1(3kʦm1_g,_cS>+ȐdG1|gOs$+Xl3{HbK]>iU^~B/Y4هb92/_4gY͂iAj‚bs͹BLP_FѳB2C|)>vo'n#ixrԌ 0lsDܝ؍uEEq|, ,ů++na;XB\j(1) })rh`jb۝i iL){_`kaG(M>7VuҀ/+$@7Hg1eSXc61iٴ]<*Yجr0bvK+?g[]ɪmQ?qWƯ^2X |a/-@)*rze{z\0/3)jܐX0Ȕ[;ۑi)6{%ێ+xeNnqzK!JÑ^d4gcKR &D֮]tL?2dgdL^9yΩdtW/#Ӑ`3`v.bW&OJ?\0wH2{lY׸s93j }zVu JR-#OMa!ˆz^ҡ v+**ظq#f6b`q(* ae! 3&15ɂQ WY 8-Fh?Yـ"ۤ3j%qeI5F?,*dAW$GNstֈऱ ew*kQ3G+sxe/GV&GLS`Y&8py9QAf tyytv{#G+ 킪Batv(9u Xc0il! 8,9#GiCX]쌸xrAw1FO)`tء1Me 8.ﱾ;M4u[ǃLMb* > Z:-]FtwDM0Ra{}ʧ8х%%]ʤ)~0 lMWI#&q_K4GM Bj(`9@Q]{bA6vE%'J:L]e%A|K渉Q:Ba!m`]QܢqG҉!bXޒ~T^4SuvUIt\ZߕU5]誚畓_KT%)OQ\uı WWtUzl47j"鳩2]+EQoUbJj_"M/.Լ_$`2h$%L=z;~~4F`0}%QzGu{>hj 'a4E8g9Lj!E"ۿ8 ikkmKAAh]U(61Ca[C;> )ZX:"1;.ٰ5N&8g ;b49 wppO:l⬭~{}X9NT=H8mCeXzuO5׎жٕ6)t Q546a~ {My`RT2&@yX 6?1~Bla|qDTL>!l1ŞVع+Ƈ MRD6{ 5[I#44Ӣ$s,T[t/G?e pgKtlcㄧ|W쌺NwЌcԔqYFZBNkT-xÏ s,ou&in,N '.抱N2"6O~f̤-`Md nxR%0ߌih?Qo (/~àS|̎jԯ`S8lg e;VA6DYYWf O߮@[w3dTN~1dzk[0m?FzNISe/2f~'('Eh"c-B7's*z\/(s%N}'Y3z{؁2X4_u2=,x]XN;̀3t1hFV mx۷ ?V]aT6m@&`c0M#nbiQr!{Cu63Q2Alv(1p\-#bjZM}$9"0 nZFCt& inw(gEWT?{-jXjEc4挖Z`516+51HwX;6uvʧFaFufc EjS0g#GXt4Tjd#ttǢbUcEC esh06" QPp>I*/m1b˃#7|w s,lq3?qӫtD[ <#-VX²&qYȨ2uhh:꽺 nc tL!$@zgfw&$$6 e!!!)tj[dk-ǝH#if$5/ݙ9έm|up[o9+tj mx_hɇݻwBXAYkyE `ώՠ3jp0Hu"h-FR-[Shj}$\z }8l^ hvDy ל=gnK3HJ&Q-E&,A'"Cƞ{ؓX9o˃ d nsQJm <9/lSI8f(D*X$n1*_8mD쳳Ρ5GLK~0$'Ugp~#"mAIz0&TPp6:X& 3zKŧƥ&WRIf\!cNA"gXd ry=> _`h֦Ls=>Uutb8E5e\H'-?&'%'vS{۫ N!?gUB~wqjE"a4[WLGt򓼜4E i<-b$JgdL3klF/d$~d Ff2Ҹ1l_RӶ8v}Г`I5D"Q*r}N_Q`GiG=ֹzt\^SXYOX "Yq]nڷ7(vf49s64%ʗ \MP%BU!•#?.‘  罽.r!k< 줳nz{{  p~`H4>qX؃D~#1\h1y92,d{-YF]x -S(<%~a+W1VFu-c$ÙWoylRHΪ)ƚĊ4t9W${2ϟP@R_Tdƺn\L.𺕔˥)XVn>@񂫡zv\Xq S()DS!<XsNӯaۅj$қzT5y㚌uݲ"DJ4ő'Hf avM+.ߞ(p=\S!31]#+3Zq3)$BG|h# K&G__a(i"@4t]rvqNuu5eeea~?iǑRv)**vxx SSlg{^Jh%44EӆddL}x}>Eul,bHHl֘W6⃵# kP3'/u豌tO\G. c "DzG"8=ױ(_K37rŞT#yP>\rϒ7 IDAT%{|>6m믿g̘1#=&A***FAh*NI"EQlFUU<~RiӦ#۝53r\u]7ᦛno' =uM4?y.Jqu}`2z{{UL1vb3WѾ5My/%ud>ζ}a`G=_c(F}P5̇~ʣ˶;&⢋.b޼yx㍄a=\~?---qhiiA&sm 83={Ԇ# ƶ$0Rnp*) REu]Q\\Lii)TTT0}t)))eꫯfӦMj*/_NmmY !hjjGKk&ZWsA.@uv`GlW71[K˳ L6RmPPS) FI N1LwVz1}ݸqn2">C4#%,U1z)bllCCCa.8*RvA:ݮ#M~/pCQ /'(ؘ+ǓAla )///(-m۩أp8L8&⒒HI@J+)4Möd&SN@ tZ>Hu{e[=#PYO4R jmtRk+81@ڽ4Z_ᕗ_N4;m_eKgxV3Xg-.bʼ U[O3NXfϳ`Tq^~yӖlZ%=h\҅KR+s& l `p&Xf0H9M0}\*l{v3Jc14ThϢܗg&kɂ l߹ TMM m+֡6BӜ2w.M:FSѸMV?4aZr}zDkC^1OKطX58F3b%6p '|T̋i׿f޽\|,Zǖ-[hmm.C\.(//vaCPFRooo- D" H ښrzx^~?^χ륤]S\GTSu߾}|(sΥ7z#^|iii3ȋ:XBalj$>-;XLUv)yYԌ{!s e:b[v' R4>>d֜ ?64{"q3VΨƴxr` @X-076i: T࿁Jp cb"F<d|,UunWj/g>y5[涟NL \w~ǝL?|O"N(hm,ZNjLij@QUUEJ{&X`"̈JWXQ^o*+OD HTRGQ0L3|Unסii"U\x=<ď̪E>cJqYn+ĶmPU@ @]]gzQ ̑t ʴ$Y$XJO?|0]]]I4Ų,Ereג)---RRRB 4pȲeˈb{455vWLLި;x#ѨSI H. MEKơD1< va&6_\+O=<ǭ9Rg ox w.jpgNᒳeC(P)݅ >PD*N6.`p#L vʝUE/Ӂˁ/c(FEhT bn}wypNj`6sg?O Ƶr?wpšT[EӰmql"xX ;!nG?OE!k@P.Ǐr#5fƶܺHt =~p-|~"}qq۔~ ݧ\ F 3{r9C )%R]]=粝BS)%eafWmuI9p8L0$  RR2?) iZJ)0577cYeeeL:5+X,7w\kk+D"zzzR.cx\a(D⒚R7RLGHC XF%3Ǡ;òQ=7ED6.н~*+}\,!WgoVrzND`WzGZ$P|x#peb(%\ ,FA'UK0IPRE%K8nG}:FJ}lxkh, k"atQeƉcP'OX~^"A[G”n<G@PyBq,It4a)?O:pJ7z( 3rx(--ߏKrK۶m'66YHт .~֮]|3UHo!c&~ x./䝧fVy#ŭ J}*6 QfOGYS$]ʧ4y'隷ƒj[Evʲb#i+W)+gr_ x]DS=cHs.`f&@\`J$\U@7Z`K2ADDTUO[$ O :K0존xw S9g C]؝+-%I"\:FF(iDPDAWD ~ ]&]A?&6ر{CUTN1ABōÖ?>G?p,7d0\OW>,DˤlCDT,6a~VSSS-B*s-2u۝C WEEEJ$J%iZNleÆ 8sR)%>k&u>f͚uX\.aPW YdUSlo{M^|V1MBr躖5ձ(Ggy}iU+c15a:-\SAŊC0Ms8n~%:,= `צM gߓ rd8 8? ;+ĐB&%6W}N}-Jkfs8ȏn ~rfxo|#a1='9o4!WiӅ-u5;p"0HJjNYw6oX⽢:C\FWG%fm!(e8V%i** ns[>&Wo߉ ?'#nl<`:+e"B(H?}2o7Ӗ\.tR I$_`kuuNx,pVh]`ts8Z:&&0AJ]$W@E%:)AC]-|v렸2?-2=@qTz8)uml"7)-+PG9ёH[9dMdR"Ŀbc݌"ƝTeT7J+HGGl$ Hp@k>M!*fۯ|br\_#$"\rT˲ؼy3w}7wg}vJK^Ld׮]<#nVX񾖛kv!2hQhhu"1Gl԰m=ȣ_2cDzr֭؛qhtz)-ŴYs(ؖEGò 6X !PPJoVA&^ɖN[$m=Na}\ĉ/QGPoX.?S6T(c֜-fꡓfg#iRYQԦF^~ VZ׭H,i W1eIxJ[A@4dj m!N~\?͗7YuN)^eC`F&n{k[oeܹ̝;=K2XfbΜ9GMO_v-EU1lma+@ǶpA&(n8>wp,$MsS#Wz:#DO認6P4۸Yv)P2SW#*(0 #!v 3[8SYNelۉqZ…17"U9#^)gpy<)ϙӧXۥ#mEeda)<naP\Ԗ*h*؅Œ5`bI-x\B&\=LWDRt֬Y444| kV_m" t3HCw7LOAE@lہH Q'2KQ~)S^e̿l)ep 3-b^gnQhnLӤX%(H)%P?j`G+<0Y9 Tx{ Pk1la(,@XVVe`KF4*jضe'FNf_8_ W%$("m9P~(DAi YW.4-KS!)Ke<j,[\&:>PVf2Dǫ?k#̞HC bxʯT$dJxqq1?رc7yᆸ2<š$Ie$Ķlq +qxq"ʊ@$BۧwiD*>OEuOjݔ]Y,y3._CmXT@is:Y(?В1Xa8lHzGlu Gpu%3gP:4teϒC?O^)KXXH!Q.uPjgP?}NK{HJRVPHXWA$ uט-[8@ϥ)H{Vf e;sui{!r 5Rl\Kllr>/d|Cr/E(%믿CqWԹ%R1y@Qwœu\|9vEc #5UhvP_s٧\Ow{=̫|Yy3>9y o 2\CE׾>c e{b}%~~ZF;ڴ9h8ɦj^zj'ۥEa] $tTt f˚M2#GsuAaGiF?>pIN2orLnoL#1rqp&m;#&j,V*`05t[n]&J]lKBU'J}22'WHBaE@n1Xr)lhhp3-GRM`IeygLX ô=zhsC7sϿ+9ot~ͯEskٳs=$V2b<9̿\Ic/UېRE-̀p'z~b?,m୭30Af_OLcW(ZIs+Ŵ,21qP۴MӜ|2s}h69~1sK%QO?uPVVLɌc5Y: %C(yP-ba _e:*wcKyy#Es4|[]ϭ~7ܠ#3Gx< %x 1ށ۹)MSx}ݹ79w9hlH7f0.cc)(A; 5Olih)Еs 7dzX@ پm}ث+O&EAmL %'[H[bK;_ZV w&TOE\#Gr~iMQS b6Hr/cPr/LtFdreZИd|܂VGXb"k yc&:Ai祧v~κr4#⼳*}y}먱6U3o9$G ~V֯% /G7#=v*}ZaƲLvlbGk;r?ái/p0`*f to wv𪲃gWreKyy. }  sܜcx`xo AuҶ)壸H%u'~&5, C؊FםH%? R>MTi(KK"Zx}C!X6C\LM8+[ (QY<((Da£0ULѠ-3mּMgL ,%3Io7vQ^U"_dCA Sc1X#ކ,+E)U8 m0|X\@d1f)3Rd|k(s~B aFLLVm1,-x;II=C#MV^42IlKg)<#~? ʅ{;%Bh4/:^19 YO^1K?xCX'ʀ ee44_\MWƻ7|ly˨Z}`rr%Py6;꯽_GXIDp̚KظVIfdΊQ;x (BRJW0 </Pwm{(2^|YY,[4<"̅2j GH6\z]KTEa-<xX+OCCo/'y`C,{u)+]Z_8Օ~eׇ<^"XוޥJK:X =}t PlX0S2h ؖ!kN[liSĢQ2veN9 , LˉKK&Sl<\H&7~$\|Mh`%?ё,Peԣliѝ̻h1ѝ(ǭma^Ҳqy(/CĂt—Nk9,i YX`NXO-̘QR3vB5DKF8*}]l{u ++%4T4SVv+J]K(9ܾaI[o.n7 IDATW{rU`uٗdzEdI"bf6 y5`O>r _ffJeu^/g}^Ldvv'>c⳯2ڣo`ٶدJeV/'C5P= y7=ˢŋ\ZYPox/r^oxwW6sټC".9KZ[JylOr׭w༏Pspчϣܧ9 Pp‹@J3؂S9pB'spB8 K))%P0O>B2ՙT `k躎m45"I9m b4m0KJLNBX9~0-0MD1&R-d-T{4ϾF̘|xb!.?R9A&c~ߛG䢿0XE-ܻ-Dԩ:3aYb$׫۸s/qߝ &폼Mߩ,UQ`I 85 g(ǥC::h?pmZ?=Qt-Oo~[^>hMBϴrc~|RJ+i68$]8]|Us5q'KTU0p`w1,]ŔkD_І')Zpbۣ+8 M  c{rX2vʷ}:-3˩ lxf޸b5p߭f~AO*lVtu)&P5{ |< HTE$IQKygVv'f:.2ӔЗX4}!9}y9Y#|R_Qogi'2wgv{" `[O[1imě[+q< Ľu}wNu\p z iezz xX~q1V4,37!p#b+x +T$K}})qWvl6=mrbضV . JqHd(-I±=}DT j*͍tѳ7_صyT-U5vz%!ky7ipiLSgj; ؊Sy/N ¿~SZ8 8JAUӰbQ2|c_yh>N=}̟}n7^9;9>&s_/b-D̟7/@<I"m#W+ fG;o"](n'bg7j"Rrݲ%5vU!N\MF0dDUC+_M^%{SFBV"mB(Iɻ5*j <ÏM Se.x|J?EN+>ݽ0PR#wϿ<:H `;G%3i__=\]84Uظ%.Ts{<%6%7x2Rin((FYfI2+)mQ4PA6>KsǧAn|ʋė/WX;< _=Gih폳or"l6~.tR6ë6cU5%u=!ƢrιzwMm}3fOcY_Zġx%N87GqA4.AHN[NwK"#I!LwEpE\n=8Q܁ZD~: *nBλìX؂̰CKx ~>|Zbڻz1 to5X`  N:~Qeۃٱ\|مl:ژvi|Sv~#Oxcu;300M[X xi'[ auMGtg9rr W$ 2U௪5F$\RJdLPeO\L&x+q<,W>,T@)@[z1dSP 6\m\ nyG|bBaf>;zэ=Sf2W~Wލ5|3SkТr?{2]0B+^77 Drb0{Ņǥcv3\8>3)ɀ܇$8,sRh[7cт̋%%2鎄&@5˖o|oig_6 /7o#5@yvI&Sư"N;g IB!Ҁx^̖EL8S8u 6u+j;`{j LJO  ǁZ5kly67쉰l|(LQq ea[6BEqlmYHxL5Ca,S;H07tY3Px-ts7ΡԲҊLϭbNb[X؁\4-RHwDAvN?LW6R5ȅQl+yx}νyaBh,\ҕM,=K/(-eý|-Y~y2|,NPN@d,;y~S?bjl:"sWn&RW@biᦛ~-fA7Gu4 !%Rb6"S6~~6~zoaw'y??Vlٶ6L1KR=ehbiiqÛ~OÛ)y6_Oy9=:ϹN1*",iG{._䷖ibqeؖb7ئd98G&xŔWU"tTz0SE".Z /rǓC["ݦ/8K-& *i:Ҷ)-*T4" ;~m?B5KEt PQkmɵ_"1r82 .BGUx)0^TjOosF8KK'NTDGU1-c׿g]H巯lKErϯUp9(׭w3mi,Z=j(N-Dˠ˖ҺjlƲ9Wy8S}pv>$Ify]gm㙳T%ctiEǥ eaKB\b`LA*hl. 5,!R*,;eNLnLSDb$`%]s oӰx]LYZO}u ~F՚\^_gbeXWU)zٱ$n&%,nǧ8ft.дL^0A:pb)X-="D#ax۴KD(.WqEDzTz]&mtDc&+ؾBEU%D4N9q 3`ˎw_cc>UUiIe~g8ʲOg(i..0A@/%VB7eDFNRA; HM|^%NP{L$JQ}WU,LIk//B'?1 >p ׏ ._RAf젪X7GP_]8,N0[C f>4PqB2l:JtGQB{TVaN,6dܑr \MfٟE)g]U˛2ɑlTiV/wYJSOmί27OM˫cvw싖t>|fHS=Re>{+V_ Qewԉsʺ >q ږ@(KxJ)8pd gP\/&в3.97&wKUmINгJgNuܽW.~2.I֙K8010p#Ų-TU /*Uӑ2!ؘPŶm2 baaMH+aF j\HPQT3p j@41Sb7 f$"%P-"ftXWh]UQME#LĈj4M|/8vr^?3_DJ~n?;cݡ 0A4vo}D@EC8E(UML4RUEU0Q_WCSC-ia"aÒ\ eQ9/e)bԺ&)Adv.\[$27/_D070}5?6tMtk+S:;|z9a~}ޛG[ux2Ȍ̌!ARDF.nl]Rr*&-VmXh 2$$ $Ifd< {?9{}/}Ak/ފ^{9{2*6>{#\woeb(6L) $yQ~GNB~Ȧ2pg/7ǯpNpp!v2$"1ݟ#755S?Owh'=͌ڏ ƯSJkT1Y0)Up{_+,1q9"Z֛R[1*ǘ5TI3E7tE'UdAbaanמ|`fBߝ_HRk5ѿUB.E' 5'.([594" O Y\=yxN> |[B8ϐ?[+>+rwoUo(^EO<[hScM24[|f9P*)K9~l\{ 1,t*$!$ihQNms`t>nف/YjJmnj/6gڿ {av{4=nٱ@/čU!Vyg׹jyѣ3HaY_ndC>+&9dמw?t:'X9^߂@0{d )ZMÛ8S|WEbarrV:i6.m%(?;8bҜkQyH~g_Sa}.J)™z,岢CwCm~&TNim7[Igv2V,d~ηV=xu/ { Z333ש(`n.#CtE AnRN41I}b##|_:S8*444<9 5YrD98c9</: {`emS}^Hb2)m0$Sڤ+ߏr@ CYbz(#H}.6CNoF6j\h&vJh^n;/#+fءG?)Capn h ZoO ϕY:s1|J[2@`>D$ $a(]x IDAT P{}{{sX2K$ '$nz| ^ (zRlݧ=QAcxNzuԪdGI<3ur7Io4/z[k8Rݨ}Zeo%[hnvayb+|i_ڊG'~?: u̯-[ `MM>pO.aM'\& BnWU>1y~##~g SX1Z iFk,!K:$iCv] ^\קOM36¸BȠk!/yIz}nٸq"s%<#K4!O!Txl)H+OELN,c!J{4ЬljVWs6$iVh ڛ8g*vo &cC>e IdG`H=RIKpA%ܣI>67_3s4Y:g^O;(ģ@Xa936c|(( FgJL+͗延'^eY0]:|}7ת?<$R߃@: / P&4OBBz8+dy% =T-<[W.@mcPHds9dι\9vO[͠"͕%W}V'MxE,nXGmJX'KI|1r' `? ]=>6Flh7(IoR2qI7Uw;.q3寽^wΉ$g"]`ʹ j31s0С S6_y4OHXyC9yED!fv9l~ì `;ߌ=ʓ3 NA$M: $IzM_,M1fkBP ^142:W!G'dF1 `uFZ+~kRP:Iy2QB%j^H(B!bf ldu@v+/e1-HDW9'08aǽ* $ 0 <#MyU'TYyd T6(yMyn ]Y+zUܽBk&1 SB :ݽ ʻ5lq" EJqƓqƟQ,82uHb†sS>]e 9 fuN9@A_=vuNaF%W;!g7cݬF̙Fĕv@+ 4DR *>kT33YlFWSNU( T0 !Pʣ*tyYY]GxOt>{fu%]|^_" R(D![sɭ4|_Ov>Ȩ @Ykf,uC|ywLoW/7h*yс-9Xbv+R^ TbE*T $)fGDq>ܾEnݎ2dډf3,oR:IFGP64Mf[da*}ӖG ` LՊ3J(TC[LI(;ul*UHyU[An(#PViI%H&WQ_ y/O|u>g>u~0?K?LjG_;ǸH䞤G\[DݏN__g+*#Iu`gY^ti@V752Ɛ]ҤKt.y,BX*DHIV $CD>Hj8FN!IXi& g3HLpςe`.98 4%?d@X(( gŗ.QA;l>+ģrA3hfQr_b!_Xϳ.&ܝj,rOvk(o*ր4HߚH6< &d TLO;`\9d^:y_&<@ZsToRڙez/sMm5EsW ^X^vw]Mm_:Sm tzH#W|YE/;1P;nb h\7\J.v\˶#6ʎXVYcs|s{;ߊqA^[Wm?uYU*"`Q"Zg9Ǔg~:xcyϝczV| i->/Dr3 |?^N7w<ӗ< 䣜ZAI`ɕA&c~~+s }0wZh&8b_]ܾIw8v{Q6vn˥iDAT#'u&' ZlxraySK IR/-uiˡ99xpY31 /o6F5Z#O,o=YGYA7XJۈ8ӈ8s hdT2tXSf:mJKXf=nUAQ6Lӗ XTCLTImZ WDaVn&Y__'&&.^Y7ȍe6B 4<pa)IoRN'2| D<94S~ ŀXȤ<}:s1bmB0nK78f1=>uFCؑR|%'?j5%LM94_P/&x31 QLD|̫/]fy;,ϿI~]w2IAPIoG "槃;Ole昝^;6.mZ]Nvn,MPJ "kSL;HIU^:KrMYi\^U_V\XιXkhLI82=dɸ0k&Js0ˤoƽvd-. @]%YK|.Ј9B#R3d-Hr>pIM /aL)@;4(Re{gd6. }Y{x]Vxz11xN/nY]6v2':U1FqZHqNʟu AQ^qΝnݮnzOkJ6#/'9|W_O?| ?r_~!w_ ?*/y 84#pp1~-H{ &66t'@?VX^Zlw2S*G9Z.UTN K&BKl6ZL-YEóyB,li4 5=a'O՘$g+S =Y~E 9# JKhl]pR|, P)6vfWwYo!ЊaVk]WK1\]SM>!y+BMww} 8AxtyI? 0 4#4Yoyg_1$e\z~77o53Q~/nK?^Y Q]qqFXqc^d΁Vȁgr,I~;Q2i> }6?8t{$|;ej6?|7 23Yo`gdā 4T%܄ exO<0915153Hh{$XgP9Ɇ]t6B_yaIWXZi>&s~S*"_mSK<7eW;\X:+#SVrѢѨh+62^:M UT-Gd-dGkgH5rbPƧ̹0,HC\KxE`22Z|lw`vE,Lp5)dB.Vo?iήӍ$Jm1<{=*af' Vcx>zx(:ӘYScnZ8ؾ_Šj7.U~e8uZtZMv&K^ qmxj0!+S-EiijXojήi/).ubCp<O:3xǤtT#e:p1 $3ĞƑcVoDmFss(AnܺpQU[J`F]4 M_G_.Ϋ4yl>fUQUb3 _!ijK9!y8cj:0">ZdMDp,+MH2W(%&7|1$w &3 ɮ_8\O|QlRu*|s#y(ꆢ𕍐|,gvyŜOh5ݎ¯it ۰Kہ+ cL8&p n $e"ƼN{\vHE7Mh [i\RdtavV >AP|xݜ~GizsA8'l/S@Tڬ$]TAzARǝ. C;Oy|s;N ] :Zh '^h/ɛlƧ|p:F%K5f06i p#AږI[ D kA74;ҺqQ4$$$& YQJcf|i`a |0h?;xخ,fK%@< 6pOc#L L Ő#9:k-2ZBž~tIè IDAT6F*2re.z&0Oy8v/k U\+(K%1}(BH LDųJCmѾhŒ|S/TѲ%+>7FZYR\včIoB)~s-!k #EWaWd=]m$Ez^fP=Pr61;!3/ 3Gمy'v=zUqm~mBW(J3A}^{inV7ٞmnl\%rF=Qаq\KW" N "TF>Q!}"q&njYk.+._R\ZU,mTy4[MlLC-D!.هQI@gcumC}nTb%p-;i|~,b Jy,wtB.kڰ43Wy*g* NiǮ%\a{)6^#[ȷR"X#BU]@MFzF+LWjmP H`VprCS$'OQ=Bfԛ׮]x2WQ~H#&S[yOR#ctaa&+CF)E$X~e 97ya KE2 5,oozltkk]T 4OSʒ1뭗`6'vCki%nj yے(KډevB f˶E'`*{1hsq݁Q`znzH$ZբH|_^ytY dR*v]JAJ>DG#6z 45Fʿ) &{l#F˄uXc\ACMN,gvY $33q{5bڱJJι.s.Njk."@v3nxlմn6ˋrcR(k!YG%;$}dvëh?$' !.!x gϝ[ZF;rCUa_O~ f9_`6yxO=| _LHsuV_NOMO|Jrg}s&WB~}*|xku.n)]QuNbGL`{fEc`3 hmC;q>nj視nf首Njhv}q{Ѷ©Pb9ߥq.Ã.QlزQh:aqÔ!Rnٽ!now+ [7~mX`\s/t VH1Ro6c F؁ŊkvIS"NJ9ESm}s ĵ:~#Zֆ<7"nҡ֛0-ohVxk{x^;Kq~X9 Jߺ4tRA+a8TpӔWDQ̈ ,]%ifE\(|N:>$UEPZ"95,ᆿ{gq=D7J; jȴͰ~̶WXncZ1~G۹nR;3;n}<9,9 [\c:v+#mtt^?y&/\dfyn)1A tJAЗK_J29'1݄bjz0ϋq>۸sQg'>z3fo<~q9f4c&C;fkK\DyBUKq(* .dkN`>ΨVZgdNVεc*91f.8V-$lIC^̐ԅZ4w2k٢nzͽ^?Y**X `ȁb/ E}7˸\깺i[|,{8 oη@==&1/)V9dBi][g+@HK.z>9a>֒Nכk9 FkfGvc/jLĖ:; ٺ`P2dAW 8ˋZ+uf@_EsiKn$]ڪlf>z걑J*Y<֓g342uJ @@K Yܗ B0|imVuCU!Uifȫ#@Qe7Zc޶tVL/H@nGTRT^d>eEo pdFpxJ%3>!_ ?+XiMՄ3Mf&rmouNIEh,<(GK烱 ՘(kƬci]'?=IM[1|lKEK-!Ӕi<.|8Xs1IḐnkB5<nkyZ_Gg3Yw7A_ p{7_.`N!a؆B D [T9JMk{iAYcJFݳuM7ʢr4w75tRK;u w+=siѿ3͍cM ;_σ7!R-#{-kq\K='n)G~dqV7sޝu[ \t:m!~m|?IKW5$eat.Jƕ.KEA|aGeqڲZork[ )tsU]{3KicNpZ/J" 0y{q}ꖻirMCPurAjJˊyn^\Znñ;U(?ѶzkVlzRy!Àm -zU%f2S%sÒx}EOm*"q\MNn.]ÿp EKpuMLKgViP WPM7.q4ZUE41\.c-Z f9) pHh5<+gvG,㌂7u>f?qa!7U ^i, К0\NOvTr6F|{e?y N:Giz4`\d-\ v0޿}Yʥ@\;SGj],k*KɴqLc Ij.$XEq'sn}#.'W tr7 nR{ĽzW74{NFuJҤl(i.*.(.(75.S?1^@b=dz ?Cp,+ȍMD:yzN@` -lt -_o4X6d5rmV'Νg>*KXkG09n ?FxZqɀ8]<+n؎kyIVc/W?1{a&n\=Ǣ ٟFWemb>N#8&nBgǔƁ)k-s>ɒ[m7-[[8m2e~0.k51j?i>±N ְrM6ZͶUtK4K-tUu'`qJ0]x~qqJٷNY۬V`{1d4^nKDALS%wkiħSڅ_XBaV,ȩy(ǂ"J>+0$EX K^Ď6iE 2AU#VU|Wd41* ptEp߮EkQŁ)_H|D>LG0 ̌~;uAsH2$VJnvQO\]ûr %WYZ(,RRb< Ze[R#|a-1bGWGW}p`IYƟZ%Ca1O~kSS:d7L0"EpZLkMjL;&'330; [X. >{a}NߎmzU@xLUĠ9 L &+@NH'jەQM}'T-;(lGC2o̓8`KT;c+ eCen+ɽ&ʏnTWme Favރǡ9ϴwT2&"A8yŃ- )XڴhG R]տ`M墖 8sgk]Y=֜iC4 myO`@ն*{"EWeeJ\./p/סy¬djc~.dv!bn.`vc:L.Q\Y\[AY:fIфFh Mfn!xk$=KN!cZo Fwu*[e,XPW3!Rtsn 66 A,E!-].o_;OĻNCȉ ra9?or~11@!Iii6 4^*k51[Rv+GZH zz E R8ǃdl@iWH=PXeCJ'Ifd^丛%Ek ^fanVl8^37oG -/->*7$-Ybʾuf*]/B<[HST. ڹk{:oʺծO;$ʱT%dS50AzPy9p%KVVٙB.KsK7sO[: i\(3JvT jƷv:m]xpsc]BJ!L <.yc8_27OFz BXm/޹ȋWkv(NͮԺP(1B%2J-ݕa UX[F`Ykɬe>M \& 3Q fO#}Op *WmL&`=8t:En z݆e;naNDRTA!~& ]j7ոgQm&6[ B +P%Fx [v-_I.Hy ,Jy=ܷy<^ǟ$vS Iw=c܏C//R_b,*ᄽmF,ji*ב#^dk8!7kpk\9mNne0Rs`9_ɖb )RJ r[,uL$ܣKRŕawr'D3+ jd] .MeVKU\̲1M:iy+9Sż񘇧 .6*1x,-eг!o _]]cc+>Wgx"{0 o ᎯL!^ϛï~) 0XiȊS\_ώs|6ˈr-FeNK6,jB !FY"ٿIpf%G\Ed]"-<o=z )A:!0R&U&+;2q؃U}l^^{ -e9FTގm`X*l^KP:ܑ2_L>Lf>!4F֘mJg'eL.- wb{qm'1㤍"-ڎ>z+3*Z}lܺ( Mmޭ+I0|eE$U:&˵d[ڤA7Lx>fh6 :=|^o`oG9x8(1iӤL{뀚 hcS0)ƱWc/ʲ)М5)kWjdS#r=q-%&7ex \zz1b>=4Ed$_c|}A>S˷|>ߵ@ bù359of܍[*, >'˚SLcIX>NWK?r_vYvhYL(,jx>˂ʾm߯RZ&jZєee agR.pLzt;KHMES[=6D=]KKءgw>o䊏]CG&(^j xk{.R/S3!.rK'rX_&c%CWU3rB~>|` ͣ<_~g* ȏ{_ŏ4o1!ocfJ1B@kN7CDsA9>r\#ЖS)X5{9rB gETw,R4dHm 5o^s0#݂AOO162>1>2:OPaKD%“ {/!3sYEdd[ )E`3R:jVbV`V+5S֩#:NjB6nD!PxR۲o&FPLc)4/JJ5ƵNl6mu% 0 %vj fWV[ǨM<،3vJ~|jNڂ)\ uݘޞ< Y\G03oV?FS[21[s渶Z|Z⢬Ȑ5.J$i% cm]\#?&km$eYUKؤZEC6<qztieӾ׺ug4&A0&1# ƍUI `l,5P 0.^FLxUy.޼R↣1~6do8j;ܮҧ doxQGZB÷;JL]d\AW?w=Z3 NWu{p.`a2w gj'85kvyxB ndTl6H5ff݆%wI);vN4 hr d_/fn1qp|pǔ&./Xf9 [൯yn qY˜%,ܳgoNzi乒r`;:BԷNARiZt8x,׈k(SN@)J2d,Yxx 咀3 *f(Phg-)cS"Cf<ɒ9r6k Ԛo!!Sg"R;cfiZ34JkeӖ8BJWjn9a(PC?b;.lVxu3ȃ\a[qc!cp}~+]r|g>1n{/TSRhfc.|p% -YB;?fxs/(nȏ\=_#x^#sxOŸ{g#2] ) w4IxG5i&z0T$x2]6 .gdۈbG;!R.UD~(qN:qc'pNA$qUb]7sbJ%G=EU XFܽZow O&gdAz&s0p7mB8NꫦQֶpakr͢GV+ݎ jGYwjoۓ8b "V +!a54./Z58'0Z#D2V,:qijgo+Z+4<Ƣq-.u; >3d]T6eʒ˸Yf$ּj71[H,kUM"QB5Y3@H\"J.(P;.ɑ#CjzA6~;N tb %iRay%bLΖ7jr 5{c w~|{4~U!=6fpǯ^w~;u;L̿,[su{Iͦ^(c8Wāc?F3/={%pڏ(Y q ~ڇ,d0RL `O'U : z 9$]ŋCd_+=6m"r+" % "X)aG%O݅&WzhaؖW=g4NTC6rR3,K:pI~\gF[q6oFl qjpae`0TDY4D*BowAdyZNv^ض%GJ ]ٕJшYSŞ{X&) oL&KZYMlgyԳ.oWk] /e6²RɆ(OOv;՟k>w~nffLW\t?v@aj~H5"P.~ #I:sG!So|g88ij( r үyQFy5^X֛o?.F*Q~;0  $#I1-4V,L*0FJ %R*L/d,^&y8iQ.rr#D2e Em7_q%$ߙQp$kÅWv/xtcw)~#|3ڍ3. _֧BI4N,k #nD.$sAż&IBN &%L(v 6)$قeR!L8ssȳ'QwF8:}1=](UCDVRHJVB`3TR0cVEvVpnDu0&WC6e;:X,4@JΦMd"2lۆCf\.D(0MR Y*-vM;jVV&vM䫁q,VC bffP##5rE{ofpbvzQ_!8zx߀זVX5)%J% b1|"pxreL6]Afb8"IO7X+;E>ac<# lܲħ>o{~oxct8|M!*ф |3GfͯzS|]؁]\uq|z>/p6O;zh_yxa߅~ %˝׹llRuYA@hO1:&1qS#*_#kO&쿈,R)T8.l Lޱw? JbLj)UߗyVmS>Sۊܹヲ7^ G|"\3ڒw[&-HWeyiʫ F['y2lƆ;%{7*nR\0!:*2\!DS gP=~2><39XX@A8 %::`Td5]kmW>Pڕںw%ng WRjݻK.!s t߇j͒f5.hW)'&xIC.uf{;NĹ]:8*T*8c)TO%!^ɻ8H\;B\dp~M!_htR-R M |]Vj[Nm]=yqm vTɄ*DARl#xir0djޛܬIy:g&hh, <{sˍ\w9QzyN?M]c,{/{{|NC8> \s5;1kxLp6L:ƭ7ɻrZ 裚N%ZRrpL}bshYi.LZh;?yug/߯rx9ajUdI*iQLGT%z1=pEj{`I %=| YcDhygyW4HA6;GqL`\%WXL |-,nzqJ/"ȴ>:MUGE]ԭ RpcO)P@!==|>R۷ލ{7֭%V60 vax~~2;9.+1Q\;mRnёm~kCP-^tQr10lTPX.AJOjxac[X38>L7GG;cc,û%̵j%֪+2tR"3YLx{"lw`Q4Ŧ3o`d+B*8 ~J\r>DŽaD8AzV52Lˤ'tK(TM!l_}-T\`ZdvzZ|1ﺔ_1Tlr{͛qI+C3ftv5̑c[/}!8_|k?LYȄuӗqw]@"]H0NV<`*~0瀷><j\nv&Lihg5ο]~\֛ꝟU.aH (4=}}M Qr y;` KixaxZI@yibBmT{M]#nA&+$ %E%{z6ь:w$ӨIVMX'F'7-hDZnnodc-1"G1YO!a|+i5!3Vu -_dWUcTXn,U󒲱xTlPP#B Y:YIԩX:qI[`{zpw;xsC qv@.j#[`}?),T}pPmh8lu et|t`k288nB6ݕ&KnkcQQ ZVV:}֪SkҶLI{[ V=`ggN{]T\RSI8Q\c'exX!u~u%,(Uk QGZ GDQR:aݒ@JI&7O6:fMJÄrTg@vyds˶饫|;_\ O>W@˻ޱ WgnG#MRr@R.sy9~[ ?;*xÐS0~$rWT᫕*q lQHh6k7:`i*5|w7rh9<@$66l݊uk22d5.AI=Jef16'` RO)k 1ZG xd3+ ZDԩs!㸸=(M|B.X])D&]q()$ΪӠΊ`ͲU'ӶXhYt\lNmkp_=~8J I2[㩖 d֠S7KqpR63A,Xv^x9Қdh5&YH8`6-ln;'Rm֎T8 Vdβt7qvWyˇ>#?{U4G< 9sʏ!Tie݉W,B?ک=*h8yDS3s\FV*|L&q. dϥ%@b['Ś1pFSI`E'=Bü},;0}݅^2-8S \ G9nӊWJ% 5s.,Ě8c4?S bkрk WJa"q/M:(ӬR cGbkζm8ccKO"Ol 23EǾ0I.h`J&S-Tij&-CFJ HIL3r14V B%̜h;MGRGivoZS)SZV3 ]K9p%Vkfn ͂IwvZ שׂ!6[)%}=Q V*bd|C!( 8ԓK0z]H[rbQvxNq-V֚Ao MJI]8J$)>4UT p!Г#/xyd*^/fQ,Ok9Z c|̃0$W~yJ  pv>~Q~m_caW Nپ=lW_TX HAjmbpDt~Z_ı%AΖ d22 X )єbKIt:@S#8uR}s2 !ćw]39.u$enz̗,NZ*ϻ7|~}9 2#Qp<?A@E1LPWCMrXe%C"OREԾ` V%@ݷ޽86 1^RkL`Vk-A5kL88DqcG} B>qM9FM-ۺj>Xc"C5Y#N6V%fvX'v^+iځNNGsI \MICG0{Y9Yz<MWk'F P[8UٌJ ۹N'wk üg\%v1>Imcۡ/~/#cy| 97ym ~2'rst|_ҹ`]Զˢ<g@V'%w\gosoy2KTaX:/^ZJ.#U8 F8y1L-q/e[ΌT'A.#c :1ͫ\ͬZ>ɯn~NuX5>)ʧIXg75u慄H\w&~BJv0O&MX *KRH=k| 5J'EhcӪʼm2"ib=yv?k "%)*0CqF2շmOq1B!|q. fr~nW2}NZ~/EDa\20]+N=yn-2ܕ-}*R2Gdd47`: x<Ԕi ~Q u3<EL(Ou+8HFs)Նm4ӛ`J%,dHEtwlق{x^w/Iied$%0sscÖ_v=F?Zĸnf6#LJ8jx$@*By Rl|e%_KUæ ).C 18)Wq#:'YM$n4GǖAwbZAJYǵ۽Β\~*`+d.PZkqX#]yFo dr|AIg~CܱNЩ5J8#<ދd݃7-K` 0.ߵ2y%{y4vgЛa&MaXdsG  C#8<>}^ʮpݷPKʯJʆ5OItH1:0/㋷|y~l7t^x%t"Jfڰ513:D 7r E+0a,&JbI|C [Io(u5qcDWS('ۈ~ԍk(Η¥4<(΅VD[N[5uDS`Zw5g+bvࢣXKŖ:"պam6V,v\:>O`aJB_/TB%O#w̏^ʷy3SE|7su_h8[˟S ށalaZY"JbWMZsaIZ٥2Kk ]KJ"gBO$B&1LCiD@$""*UjFM$,J|/30&""$$ hbb"0ga֦jwݪaM?k=Xj3o{O5T/?M3G]}/B~#?ukKTMmvw6Z'~WcN&XNZ3s/ gfrr wYeQ?KŌ})|! q95Os -- b-]]\,!jbj1?nLXAĄô BhJ^ϦUOXtZvQ]HE"֭x\@מ=8v!7mB !{{<ieZO8ƔP*-9H+:۴7 )DյPq6)Jp$438(MQShiglC}BAFeƛyj֒׼lUwpHPL ?&/$ KFdV`(K88+?˞Փ x˘vo +_NM[/Պc]]P( ydWWvݽ;ۺ5:P}20nu1&NpeeD1ӈ0!oJ9Z2[6!y[[9 sva_x?/ǫ [[bu` iƤiuv2Y#x֘Tv|T*5 c+6݃+Y,R>Tl|+auU+9ןK I 1rˆj i<W#gHZ+#:ז%A!vz3q 'R.*5s=5(, +KŸ a詩di޼J_xJ5"[TըN-h.@(q6qAR]pH/%XXZHN}ib*X[vݗp~ l%̕+ '|IlFc_JbF'AX(JD:.p\8,k n:2tZ}2j/ΙXlGO[|ū4o`~QY`D-?{'U{ϩarޝ]mPU@ %$`01\ 08aƾk1`ɀEPBҮlة9ٕzfCUu9=yN>=)8}=$( %K疑ո:AZG^hɢLu5i"GDQH]*>֫5jǃz8R^fV,zk7IԵ3?&ϻ eUB_nmg1L( *6Ha]xXP WFM٘Qz'tC񢉥J ̪ߩH-LX?vEed[.H=t>Pa>JJ<>Q, ҈4d]AI߶ PH ±lll>O.O6G&^"%k#ohj^"( l^ZGO3䖘aS192 aWD+KUdn(60n:Ԙ;jI >@Qӂ@)Y.U2֫X[3vvFZ%d^R&$@g'vZa񠬁0"AҲZX k"Ne? NJEɵ\޿dm7sbp݋vsc=[BQ1+ d<ʥ"Rr 'Gfr}N&WUXzպeCt;yVv@AyH&*}yt\{pɻf(Bk(J$W*cKM1E<:w`itl_S*kuCpIn(QoYl*6D&Hք2\\!Ȥ-H>prWL璵t^]Z`&B wċ|l ZeE!,̓\*?rFQm(ڪؒ5d:wcMne)>ċR0ڄZ(rEmֺiȗv!?kM)RSdR0}GfGx'{^ ̢@ 4q NDWMpЭh!: Tko_kF( CڡW!jdEZUw!Dys'3I>#(y! ǎ=p gk_A6fKnPj 4\ifAJZSY!bo;OA57EA[PTp a0-L;d>Cζ ;UTŠ-!,,b ˋ,ay~-cLL3e+̳䳫tp\fZ*vXӔ̒jG+-\7@;]k1?Vp(ʈtl@4'xidWURW]RM3#ЋI]U+s_E넎[F5ۘn+WSo uYة ۞`(o/~u|O??R6u~okn˼7We|B#P0 o[n(/rکӄ^0,c)4(I*5L\0 0(FQUs%mg M2lbXf\SA%q4RDp+%*nVG{B4=>1l5^ZSmA6ƛno|eÌԺ]t:yP-f_!֦MDGVGt6ɄlI4M nYK1%qijγ|8N 9vz/¦.2~ĊHuBuZYUh PZLW:/zom[X"{'&"Y렪͔uײb}MZ(d}A'_n x5nBb7`tdanA97s3_¶ ;Kջ'7|k^* &6';yV.==ԩ:3O=r)g28 ~nuvߺBF!A4T.Fh*2rML dr8>9,c(JD)WR*BjfPw),-8wc),-x.i7S#d9l'C&O~v5\|sHCU[.@xB֮@ԉ zʹWB"̱1M D5)ع~,Jr2%nqsW$r,b/)*h4_%\u)%x<tFv 0r{6-k0سMCJS)WC@} C:āOH6Ǧ#'hPLʞ SmYAVY^Za }<~S'_v_G{z^u7n:K i//%}g1 L'C&}<#R!]|aJѩkc( |~|'(u^Fȷ6?|{rQ&*Ɓ ˳=<}Hào`L 0L+UۆfV R]A@a=YJ+Ìm¦mu% ave.k0p$Jz^U5^@j6fCpwJV'R'x5|Hc{f*Xn j˲V*O[.,SP4J@OTe.Vk7|;n=zmZ{otVJ6)4p醔eM;12<{p2nsgsNiT'WO) 4}C\/w,-tڋ@?u_bי;kwC# l=]w;>Ƿ?\aL3'?E!4BfE/ kS-w=Sw39C07?R$61=F(WUǶU qD>4:W_Wp5:"IE| 0D%[T\81Je0 24:>&ס Hz5,s"*H!ض!ItgdM'.6@9iUuC6 L|x_wq~̿K^*m؊M\Є PdZY:lQu_={{V]kl\_ۍux<+>yUB!xvZ(mxS/=1kI) }~(G<3S̜4-wab^S? ߿35?b4! r;ߺsS3Sml/='>|Uoxo5}o/> ,-T:G̓!ם{9w{?Q/zrw~'ֶks.4 CTR07sPOBJTi9a6:#%%Fd8<ʅeʅer PI`&3ySC\w8lq{pHjCzt]*jk= nc`0Mtb*J93_.a6rޤ`vn\K9w|+9ߚ "$E CmÊ}ljfkbuWZiȤiBcHѕL/zn̉6MP~'n5݂^iCHO'J-VfN/329{geeeݓ4> a"C<6;U[ /,n_#?x{|3wstxrCwWK.߻p 2}Fθ_;=Ǩ\vq!{1/{l_e [fՑQZW~V8Ia̲8W.! \ds}؎e;N&6L{uB0CZZ$ofHXvt]\wB_[aSSDslݛ" u_ F~ ؒ!?ٻO|cGkazgk :`H)ĕQiڈ\j\u+iEJ? Rlӄ-`Z2sO4uPVZDIlvZ5AuhWBGptNYG**EK.Ba#DafQW۲1 N.{EA~_o~.3ײI5/Y[7 `ݼMA (HfJEL\&^.h8\@4bG-bPo0~DMƁgyd2i)挩$wwWI\aۖMe3e*[Q JRf2풜i4JX{"?/P^Uf teoV͞9I4k*bz"VTgEo#ZYeQkUDdlEI0 Pn]^AWJDQ$%h)p= aල8Z 3S\v {0(g]0E?ϹZRKsHgM30κB/ j]kɫ kH%H A")^[RwhΜ"%J &>т72g^/O7~{K^ l;4a*J~J380m f|t3e#-S:ӪVYLN+ժ2I ^:8;vPdCX(dpr }_|t d=qGR"r.L뒻aƿ׶ްUa!˿/n iJ&ղjnܴV:`%Uc)P.8M.ULQ'Bq(+%E~/.=ncc~QXZ$/r T(D.*pcR4$T"}?۷WmVEo9@B¿Ԛ)QQHMҚ.VmmЯX=xj!TզAi&2 " ?q/Y)RI\PAXK, jR: }(ڀo|{X{bHݿW?#wuyy ѧG9w/۝QaվFP]EmX8CZduq4km5 vdU m곛4;U۴R[~rxhaLV 26ף',xr/̰R, :4eJ"p]ww 㾦` ueYYdaT[ouchkZVCiG"Aj#C%I,M]ٳ:)-WYu3n8zgRa[^߫[U7JKTH42 T@V,1^B)aa89D_iH 7}^̶TQRjM{}SpEjJnDګW'VQRğ' P04C 7q}oPrR1~,W Rwri #g 0e +㥿L<էs/7-+whןr|WEgїQ8Ư2Fx~@ C" i:n? : Jc8x3-T+zo=c&mZQ5F;U?q7GRqBVsw*˂?@Rݏ0 T\ ,B̓!u::5^OUu͏Il AU `W0^,Q UCEݹ z t[VvNÚ][N+n譺+}Xb׭S^qƊb/Tb*F(]s6O7~3#"c03YTxy_X- T@E*6  -]zT1 /kPqDP"UpYٽe\pEH 5Uvv%ϭHbkڡ% HD* P2X)K ;B:GHp\6xe(CVq1+|tC罛M98̎=?;QZQi(ib~3:1torԥ;a~}..w~3YƬ{q3q啻ؒ[[i%*( R !LB"E-j]I1IAi±#,;JX ׇ! L"cYVr7;2ήx7a;n`;? u=O ~*=, I.-=Vm6?P(-p̈ K f9}߄&ˆDi6Sss:B@S 6\vZZo\XJVV3X=8/WWLfSY+VSU*UA!M]_j9:":WJDlO/Bۨм}\"F?\-Ac/Q9bՅXKUo<033[y_}qc͈{o .q(jJKt\Entt=ւH$P6~d&ߠX`+%("B)bT%N"E`enY ,X{“+6'Ns68e#X@ %";.n')SOP\DZ^ Q K9[;}ġGp\2A.G~AG(0.4j\ E2K :"p+,//2wx#80dbVLcb?%RVJ,.,T:񺹈Q}ͪLڎnVUTh8YmP"doJ*Pd0)=,'݅i(NV[VV28<8e& öt`]M4y:B*0# 7qoRT5Q1uQa!:O&g )a : ri <(/ͣ~7Yr.*Ư;tS^Uwg?E8%?$rわR]u$dpW^2f+&'җCLPIE € |T\Jg5C" a$9)کR0 #\ X8vba(R<9Ϲ-[mgթW) $q>Ou4׿:vjyFcמD? tκU%k 0P2J%e5("V iH /s +y_)Z\qaՆa!Waa~29?i;#Lq2QlGe?4}"^B by:u0zJX/dյfk$SX R Y#`kv)NDB}X\Yudk8ѐcJhM20G׼z>/k6vojՑK\twxH]^҉WIn QhDJ)Epg!GQl։U>R& R"!PH@&%Ϩ*.T|p}CXd.e<& YG"I{<̲MHn6:o: F:^CV5eM״XI{yrUUOW u: mY_QK%l}IIx{z*땲r[}3zo8*Gԁ6ymWuk'+"R&~dRc-T,Y.K eA/juPMb)JpB*73lB\Ž]y{G@vsً^é'g 94FgS-~r`ނ(>IAڰΛX?s;D~0헱gBL1G)nCEw]3/Fzp&D+/0;abT-L= T+ĪdEkS` . ǘ?zG)h~GgĦj4O6'a`~h)%arUW`6cc  ▋^)avh!Hkv3NdZ$8֭(BK]|wG{=ƛG>9p9ܿQ".>MěoF*@ač *`nAރ=HT2i)3 F*ąۮ–qm2[:Dqq{%ˡ JD+64,ƆxbUJ/Z%![a~G2wdEQ6mi]4N&FىٚU:+`eLύ/G8ڬc]`+˅@YG'i;yS:A^$1S¥x<3yKx[9SL\<.8~J#<%i>ynt_8rϟc __(g>yvn~66nx~'ݯ:p;|?ޑ!fjoDz׾3^W2ѐD(U+ Cb@ՎQ:,PVƎu4V'[/[&TwB( }?@( ,QX^A1y '}cSӫzYUvQӏs! C0 L"jU ZU]57Ҭ(sc=|'`,[)ܹy͛~aY!iR^*quW~;7OMl?y\_|=2Xaaa; Q+B`T\9r9lۦ\.ąu#/R #iLmA`xZDt N$UwC_6^4VRޓlL?4>tQh#w"n;zdf)vjl<nfF֧kږvl^26e)0wp,yC۾\܋-$>^a'_̦A/&1};c{aD^Hn`)%q߿5 Y>}g^#/~h?7̵`IbXPb۹',1WxׯB^<)QʯW(P*ZwmǮ] !m =aiu]JVX\^0 ;rcFVku<5\S3v<>DРB0dee1!qvFtm~'fml$]J}miᵯV髮qCMBD9`HIH2M"̍,f3g}">S2G֙ }x]/dcpH-pt/?YU{\}%M99ȶ6o{ӗ:}6>2߾|.A' `yN,Dܙ86dm9/e4Y;"c8fm2”iD R@F@ˏ @%G-/?fai208NfϥW3<>k5=Ć$j<ᕊJ~~0b Ea˽dҮTnlU!k$]N+^FlːqО5ciPߐď |=XR 5!΍8贛jXZr]ZK`aX}LaQUne^E z񾝾z*x!uI vKY:wҫ{/UnAF+P'ZXQJ?EXK+RegQbHcx$ws;_[w\ȅ*k$-p׿~g2Y~rM~&'nOC\[Uv}}Ӝtٙq4X};9?|'+ܯ_;$ Ue[ڨ$6kC>%^DΉpTR!EB rJ$҂HIH$w?0#_032928r ou +eͭ_,~r\kSuTRp'9v[A+02:ɑʑAT-:^lv{tL LT;0yq'9$(yy֚9\]e TS9S5\i'[&i/Q)!Q>V } < R Vm~<4_T: h5P `٦I)zz[:v[97^kz=OiUAE]Kx 2}#~ݿ·p%1^v*004ī~ܴt-VW7<]E*T']f"e}<=%s;3'p/&.x NvTٴS:5hB_I6y&F;9'c؆0t}>هT7$T(1F "?4CAbIqkqT_R $~d?xAɃ +IlEQecNiL0%n7sGs6偐ꍜ|~k0uټc~o MU8vcyqO婽pgd|;N]8ՄlIَkifzfڧVtuiF?ҍ5juҨ<c|1!h&۷^z=X2^ȱ IDATNidAb$ C2 ؖ VW 1UN@E XKCAXo8Nm(S^_T(JՊX m<ڭ֟ 靵2Y: Sj ^~q]Z[Lm{i&8Ǯ+@54<*+x͛.kܕ1׽eD/J^DZ`j@*[B&ED*:WdR$Q82NmLeX(2"cE8f%HxOa;H"*j M0PחAl%=n P{0IλL82#2"*[}ȺmIe d|qx0`0cXXXaX3;30.0 ܖ,떺껪3?""+*+̪yR]ʌ̌ޗq24X%vV`6\SF`h+DI3O=}?3MsY0%?oi: bo&mx]곜>X'm] 3 kfe/:I&W(>Z'm i23sJ`>ۂQZDGכGs5|v+W;J`B'iW8cQ8|[e;lt(L°Az~agg,DDyȟv~˧Fق;iMS$؎%id^9':۩$8X]翎WQ~Gp#~籁 > ߉@ɽ+Kx\pupΑ*EhNCQ5ĵ!Vȕ}(g9YD=OT{HDe&<ϑɀ "x qn2 ;-םey'`sc6ɡW"~>g!Yc$ L7WX0 yD=m\|AXxY 4AlO,A"~$AQֳ *tVj4 xj&y\r0Ǩ jϞ}Шx* w`8q E)CNR;~_EF+?1p q0̜ IBJ#pDNeezG)FJgw`BLd% @c _w߭~[ʀE$PeJ;@D 7F1H+--ꠀ%(\F5^{k`T` .MTa&5 W2`2mՏ 2砀׊u$>p {-I lەcP׎ܞ"OR2cO JjVӏ2k;{Xdoc0 8xv|_ ACK$oe&4 fo P9@veVCr?!+PD (@Kw>4G`\a,e0< ߆(``ڨL]|g"rmxNoe@V;m(Y8qϡR Qp{JoÝc| Ɲ@Zֺ ?vJ2 em,_:KNʥ Ps:fuo=_m4'feJ{0Qڧ2Ms+Ԋ}]lK'fF)pc0q'*/ W5kܖ5xaK$z(Mna#uWX` *03Kanp 2dZ@;[Cf5CȐ]@=}8(6d`jCVglgL"}H(sG{W%zw.ےhk|ss{?3n:_E/~wY|B ׯQX73_- z=@QΡd< vMCEQc ,cu}v n8XDC3>,Mέ88Pװfb00PiPUԋY\C( LK_FKk34\jqߋ}BEʌ(Gm*|f,ы? ˡ\.?k/m.>([Q,ĹOնdžaMOZIm2<׊d`R tQ=}0X1A.aj[q vn އlOe:`ԳAtRyL`c{<@% Tg 5ش)ei#-WǍȪrn 3Dz₯uxw^㩷6pI\x^YmfU+UM]ՐQUș,D1A0^@/w(=usǝܢa:m鵒چi㾘qu%h9%*|=*nn؛WPxO/}_/zȝ/?37Dh2}H|Ȇ1F10A(8N䍋$raۋbNҲ9I`1'gg1ڢ1jilMG z!0 F VAEU H^#XX)L2!w-^mדg`⦒F4Fa' jiKI ,``  L! Zi~:iq 8\<{+ 2nm|߆{v!W (kOuj:fpn[J s(۶038r#рspV ;֒GOIWQ8X}ɬZR49 lk $ 41No?=|?e7׮`\ӏ]]D6vz,HB1'j8(K(K e)0> %\]SxlyųgqǑcC=q%t=؎Ew+aD5<'EװFdm)Fqa>O,C lYm/C|PV/,Mh!2{f9Bo5^O⡕tߨx4'-=@1KM|+Tj3"xW"qWq폰EvbnK{uR6gx=^QU7' Zt`i_͉Ȉ3w/}x6}z7Γ^E|G:mX18E7?\]n IQ`!qTCe84]?0 lG(qlNUŅ2'ѫ(-( 4?I_(KȚ~~hVgkO+ "9I$19wjUx/;oW>w&gh.܄˛‘wny hJ)8Er Q/aB Ck 8u,"?~ (9]vDIp Tfl6pYl6 fU4alFa\CTl-N$mG;9FY0_lc&M)q*ʎmEv:G譒و7Op8`@,ӀqsW5i s* GkmL4d]{Q:pDo}+ M is ܉ GVv<3TQ`޴$!fQ]e0=g'M¤&I Iȓsq\%}qx_4"80~ǁ/Jjں X !G6oo6s@A&<'ZۿDC]'zT*,hȟ^g|7t}m-`b^00>ٶ o;4,Ӥq4i?$8a 1o`K!+&IrdQvrq4@8˓Ź_Fh>I>J:Y2 Q:mI@`5EF)2A)ˡ@! 2CFd=CTIQ` C$v'E¾Cy˨v_}_Blؚp񙦤'MynNq0urP.;BIs"hgm u-/o|%ylXȊ=~˗//"ZN)K*!DF!7 I4 j5iEA.CV8ւNϾՀϒ=F´DQ` dT`L^dX~&$]Vw( ipFU"j%*~%Jj;^+;4A-@?i*sM7(^#yt޵gvB@E YYe0,'WQv ({|P!nkO5Gp j#+!3)"uȌƤ &Y&-ΣqlT8v+lb`TN\xbT"J|l3gϞ]kw{<5EIꊢ BUZ6rbRQt]u]G 333VVh4VPl @mȠSj`+0핖-rFڔqcRI$@l\., za#6Ko\MΤjyB{㯭{Moo~~΃ yx-,!# ,lKgOK8tp7mX4(&Y/̎{`";U@z, J,2HJl.wcjrCC4}17*-4*< q"I"I-Ui>I8ڄik&WUV8pfRb^N-a~ߢ Ȃ dR$<{FЊM0Kw^ʮykP<cB_ ԤI&W,½1X> |((_/Y;ykOy(#۽M&NY s\qCE:Qp RILb__P-2fz$`f`ZI=qڙQ@3JX6IM/"yPmAxۆyx's^{ލʿ ;ϻUpu':y`R2!d8!-ŋhXf |X(ԅja~~͑B@rL&I8!̖ߊua~ҏ aQ^ Iz>=տe}?]{nIhO"ޫ~b IDATNMܯ$a氽`s[U K^ŸF:f㓟~N>,`y<䥇I~75Hc80:)/G\)uuRR2->ALI M=?_~-Y/hR(#́ {_faۋ:h訢ir\l* j&NQnf;mHoD^0jjYq/tZFX앁^g〫kko Fٸ:eVj Ć%w#?Fg_sσ lnX׿g𞻮Ȣ.1 1H7TDJ@^4P 2 ]v ^h-ǝ{#,l>s."FEi4/鹣F_ IHҕ%qGi>'cUŮҡ̕+XWCUUpƸC("mιEy pح7s(ۻu àa @XR$,B)-BEIJ&L/ taassshZ"Jt]bd2黚7_ ;ˊn k٧ މ۫6l++o;3?Ek+md$"Nb 6XIZiARu ՂvςJ,$B Ā;:=X??gp4Z^Yk{7_U?ރvqc7ZP2Z)Mex"s{sctXh ysa3 iSq vRĈG# 8űLI=i4Ma9z<.LFjNVi%Zɣj ې0܄BWy B(orq"nweO> p,RJLu] @'xb ^[2j)k z6TuEE rf8⛱ZKtH8ߨsXd`:ȝ14A4bk6I~,Nô ZbƉ;>/&[AdN[É$g)o9vrox7,\Z m}НW'),z,Gλ̑=/)ÖyƷ^wlsZ8 cҴђ@Pvhĵ8i1LꌻO#8+%}F;RNFa`mm촹=h9ǎ s?C rӬ9 ˺Jο:{3]bqSKŠezjKKKg}W_ڒeEQZjZP(u]W*^P(fj|>brRL&9PoE C0ҟ / I`J,Mj0Ը.-+4j/Eڒi[〣IXCF; "]׉ ۶S,Wφ/pBp0fù.spz8vc6(v 2ő2p.S| zJ[;/s]n={\$%FO>ۋ\IQ'q XV@\_JSY@pNQ~Xg?]t.; a0 yt\D_%<%Ʈ;<ߐ~g\" +KEIfl3 d2rj&躎Y,,,hh`aarb@epd"_t ‚v_X5Xvv5 iQ(\M_'e&H K6nsڼcds,[;(wQ0K`N 3a6 DZt'kz "Rma|6Jú>z  $ᰘ(t?ʂEw" -q^I[Ҵ_OKT1I ӂDWQװ0/|_מ$zO:[UyUUt]/huq>d$ /fp,Z]z ;ypID Gյ6Lsi׹a^rZn=5 `˻]|}^zܩS_pf!EM*BAd+JfffFb¼X##|%|vga g2M<|ːEL RQJ@(1Q~IXk2 G>n{nڏL q**'&cs=1Mv3 A0v7cNԺKcQj) :!CLtDa'z'm7]<=#IJ]OEXǏWa^ {ЇM."!OGyPM!_۽Ķ΀g[vv!Dz{asR.\pAkSPPa.֊bT*UUr9hbjyJ%J%u _A H?+0q5/VWz}pΑm(ULռ]f2$mWc˽G#\S'c >&m?Z>>ͽ4dBvlRwɑ)I z~TqޝJc14g%<6_J)I4sF_ Iۀ1l=?It$,@ww}yd2PI$-PpW8ٞiM`ǂ8Rەݮx 5aJ$I3, H)-i E4T*aQwnk4#-VS6k1Q qݯ?Η/UZT$^@m6 $w/y{yy jcNkZq9d‚ lYmll Ɇ Z$ͩZ*l6;fb-#sssARAVCQ EVRK$`򢼲08~ }Y @q_ba^w[3?~d+B${f- 0鮀sӥsZ p%yBP˲M)`RzR:#brҐeY\.' jpA *: g9*8a0wZvz peƩ>mo0n9lJ^@A+3% -KS(d)iN$y~Y6$qSӂG}}7:(rs Ccv c~ L؁I"m7 KaZ/Pe'F?5J_1 VE~PhS`@8h?6(Vx(rogg!dzM׹|r-ӵoZ;-ÑՅՁkS1ua^^/Q Ŷ>oK5M+jjl6zNC"  A \"B` C`m쒉u zXk;Xݴ54dT.Rh*u[@ڑ T'@$i\`J;G\FTDyFP˯7p޶qeB` \\5Dm- kr8Pt3LPT"ˈ$R4nSQ$:ӲVu0{,B? 97 d%7 MeJ%m;0?%G5|Vg,l@f!P:]}ap\ ;̍7pD)@5$%$ g쳼?κ pZ6HִT"}g.]T/gAQg%Ie9IfEQ4MS"û籰Z,,,T*UZ'tv` 6N̰8]ja2lt(J(j"rYيBND.Kd\a;<|1., H۶d7F Q@ 1cb⼬|--jd%Sj4bsK >6ͷc[ N>~^T$ٷ| rxܲ9 g39wZӚִ kf۶a$YƘng˗/r<3I*f+Jj)Z-S*ąUbE Y* 9̯͒?{n-xbt8ظxҪ&~+&Tpԋ"jE H] ] th[@6 gNe"uZdR#Ŵ^keKo VQ q)Ij_F+3 fŵv]~+8(Z[G'S0._ rVDvC!$%nZ`𼽴|_jukzִ5xY \YU677ӧO7UDQZ(u]˞UXP,IP Z" _lЬk,o0ll cmʆ `;]͑]isYj޵PJ^DN)DwtIDAT8B=&)5cy5b@$I$N=W@\ @gT[LB_}Y(I67_G[ٴ5i}w û܅Յm[[[V^yAj(΋xRZeYY]I> :fF`vvz^%s(r#ƀ9 z5/ðedv8E \VLYb#gYfHHZW-u{X$0W! D1_QS/Q`3z8dF iq۽T@Mq`^GC8ymPy/j!T*[׳`矜=iMkZ/ݬvf#˲+LP\YYYW?:u kF+ ]\\^8pT*h_FE -K(ʠpB$8x~a=6\6pf3icm#q/5KW,63)KBg]PWȳ[+BLEv6{sbZF'm? ܌HWau;*QA'׃s</S9s $qu$ߍ" k|?{K9p~2=LkZӚִR?%y+8DaU=]X{ kLF4Mi4Z^WŢ\V<*uJf@UU:J>*|'w3\5k:Oв#i3sܲxSYi]$,a-Qv'5ui|[>$4xLzݑ$ B&3t;z=t)86:f 7A@s9QXc Փ| g[n4=GLkZӚִALV_x*ے ,˥\.W4fuUU3rJ%yj58pzrkO֡iZ ZUy7evM[6&f,>o<7SZ8&4)B'n;z@ynKcpT X64_=fE[c :!욎0%׬ eB\Si#Lw6Ae5 ァb! >X'#S}HG@筨~G ̓zqp"O/љ~w5iMkZOˏ. y |F`N2Jbv9%ͳk;mӍi" @T<z< {cxu\VVP,(*!<A*8 W\Z$LkZӚִ5Vql{-(l}.+,_m6^)8mTkjyaگ$pĄ x@B@m|̧yQk+@[?t lnIeunjZӚִ5kW,b+´S~Pߠ ccifQ~Zha/!(c تVcgxw,oJuSa+QյQ*%Uf.ʿ]E|ͤGu7fd$KG'err!3d]A+Taz_"T_YQu,3oى1?7ʎ7UEQ7%]rG'm֒Qk9[4tOĵ V.9ծQsmUu5J%5UpSi+pُ7~^Аs]]2;;zd$iax|z >k_jo60y/py/r9,U|Yѕ9՗>.+x_W_Rv|r<\>rN%~΢hW*e):Qql+`kq}\>P T fUpAyʎ—^ܭOzZ+e$N#iƒuI,hJ+>;їHA&+o)-|‚ W*/IUK%E_lUҊV<{}} |BOzR.^Rt ~e'Ɣ gN[fp=)̶dvՒ޾*vY_|^Eszo/XK.YuMO)sY9oq#q}٤+J쎖yK 9'K)e]ӓ K?|.8vLr.FinK᜻^%}9$5 'GmU=9|JT^s]4$Hsqq|ʸl%UIENDB`sardana-1.2.0/doc/source/_static/gallery/gallery02.png0000644000234100017500000140666712174204304024212 0ustar cpascualcpascual00000000000000PNG  IHDR XvpsRGBbKGD pHYs  tIME  73 IDATx]we>SKPBB (T *#Hi 5@h'>?vrIvޙ݄}[fyߧiƙ|>&rF>b bu>=*/Z~(٪S?SxI8kÆ1Uy ʵxaSA*BO]Wwx|S -* o6|)cCEE6ntf*?׺XaE Rq֚:CFTd3O9z?Xa nw|ob +җ -^Z1= ?\S _z!tQȪPp"K +&Y2{Bw/,T9h ѐ"rīb q^~Urr9;( nI*cT׵S rϡڏ!}DNq "Ru]#&"ZIjg(.BnF{6`l:ZV4t,mW[@hUcW6yݨAk(Y߽w`_h;l\R90CAD,d-xw^K4,\ [2a_]m @u<  ͉$LlJB"l>̌`^Blns9}骎a1x mZ$N!6 =ۑ !EE\ƧXUTWƪXUAnʼT=nUY׹@{Y)ϒ_?V#\,uncђy Ƀ֤zbE W5я1TiטtWR "I'.a HC-/!'ƢddQ۫O^yK#ثJ{Pn2<ზ퐂PGXc8-竌EseBMӀd= YVtMTS?=ƎͪWM̺Ñ3%VӤx, 4WV1Q r>. U}q?hS0" 7O/">X9qAҜkߋJL7~T gRU ͙F2$UbC(ӧmjV 1mq6zDl=(e_~Y\NY9cGNnJì b\]ϱSW(PS 0q\µ^%><7T&Y5d֋2ᕯTK~Ri/g)7Y.ޢ/Wك<; h_2ew[=\6j[Wv -+, R:gaU{l"!PYUjhFch0KeAEh/aVcQb.i56iVn #DW:kܜ@, VB3!Chy V ^Bu 3F!t2C! vt{Dd=]+Hu6߽¬yc 2rCTi>+Cg^Nm$VoTiY69 RJ HBJf-$r¤a8ꧧӨ["̀bG"x{i9j`;X(`yHᜟYHl hN{WV4_T2#4XmR9 `A l#$$Ce"alO:6,=e5nȐ 4zi~- *㩺UBY6,J]gn \qqK*alc|5oRx%Ϋ{߫P!nQq -pox*{ 8V̮>W"q$ۛWU L_';].y^L[ fT}vXؒC=qO~mF Cm@˥Ii0m^ZyѽJ1RCX?הs,6$7ϰ\{umH>q [X1$:# 9G`,\999Geㄟµuu?)xlDb18hY0#!+F!Gjc.OO?}2y3bXIBJRv X0#vgVq%:g 42&L3]7+H[XJXxu,nb߫z 8bpo|@=BY܌ F$|ZU~kUr5 %#0./dn{*_{9۸*npng0{Ύ*XpTCT T9@>U^RQ>ϖY[v *ݩ-s$3;y僄d:2`-\ُLt+V+E8T#84Gp x#3礤# r6Dcqa>S:g?aCЙ0c d G2y f#sd1@&9s$GcY@0(!;WwJպEneT6a;*p*6>+m*Mh<%iB~nI)nt@s^S(.{yn^/aE^ʺBb FL2^ȱ#X_| rn1V9x9{l5;J!0v:*Lq$:p-o⾳wgM ޻V;NÑn{A!4} 佡64'2<ȌٕʑPUJb7TU˅zU[-!O@դbʹDNnj?{JKUL~1[p% j4 `[HA#pD_TMn@Zہ#9!8i!:,*"!AL6 @r(e98`:m!)H8BR.?l`888pN?d9Ol'`[rC` I`2`!$!AY& n`UlBtLD$%#g 4-I^= ([XpTRɏJ7Z&{0Znk4善jݥh;o= xA/y 6+'>U<  ,6dpF&%cȖ8 ?7_|6f OgҤ-ks?Jna @<"RIb&3@!0em@ r @6;Vb 손XW: xX NL#8hKdQW땛g@!)3T,Ŭ^r^G>䩟BPP"W/PhĬAu7GHkD0t ,:g}>1?WIw>N;bl k*Tz: A3D^AE$L ^Ut`yQ4UTgakח-+,ckS*幥Vү2] */d RDm3Ѿr5hD 5 $;1)OkKPQ#^;SyNҹGՒL߸Sp뎧㿻 /Nc$ #RM@5b^ooIn)5R_Jlk9e18` WveR .*M!KCV5uUI7pd`ڿ~ӛvk鬯_Fcc o}8!fK.؀ 1 ^׎`$ M4Ic6`t_eC /B*9IM-˾`D`4H!!@,U+I4]b0 F,AW`*vB0iG8F]u5# K( vP_W_7{aHh*\}:6\QBby}l .Zyc`MDd/MSUM,V݅^©R\~BT^P*@XoT!X¼zTKG^&U:4ZUȫxt`Zx^۾Nhw;wT5TO>.JRBJ ,e2At7e1:FeLGb|N+:-UըIӷQPo7sJT$>eƨza4AO>F]]%̚/^md0Fk h`چ,R7GzMR>Khriao*eG^r{QD1(4%g rJTծ<(WT{UR:{|3td蚎 ضQee|dw7m}D$EKgQ DQaa\PLzH!`;N1Dc(_Q'@JI`lL03*:9 DL0˶ e! %[Xk%}ڭR `$#7 ݋D_T*Uxx^.k&]߹ۋ"b1!k.W7]/תN(U<~=u^ 7CGU`HO%S[DfHĭ/@FTF BuغgT[LI x8(L zZ9H(\+@O. @A/VH*Qܺv&.C34O'rJ'r n{S;BUOUҵ=g'"4hb 4R^)tMDHd-t&-M€a1VP4 K,F,cM4`|`#. 5 WӌCB;Nݶ94r2M9rӨ׷mↀ؋/1#OӀlgmACC-kh ^S,?6,?cze w|h:V!gm1<D4Jڕig#D$DCM76\܊kN/ip}-t]MDM؆>s-i!Jٗ6vJ[b@je ZŞfRYeQ[9XrVڔQ^\*U%XT G@-LP,T TÍTR5^5*m Y#$ l:tS)pLIq*re!d|y!/&/ՇT)QU=n ?p/ZS\R kJ.|VR#^l*X.b˭4(!DD46t֩#"b)%! CAklO![#֢6RfՍû5JA~VQmz?࿺B9{mTX^ڔ,|Jx{T<'P<|e_){ ǺHӺmfLW9[AB/4OK]}Or˩(~+'75]pA ؆[n@gC!ohQzMGX[@{a$]/d^:6hHn[LOYƭ&f`A_UPagpc ,9uyLcpAXH,҃An]x2` 8ZM_tÄ6( $93|%w뜟I`:IǁL $CmtӠ\LيnWf< IDATaesDdX :$9X :19@P @0 l$9]z8fc0 !)xD.(<Ǖ.L 0ڀ-+(K4v {2u:ur7Q3u\^acPeJrUG>9dP6^.5oS3-9\i TQUT*n_kaEm*(xPd *\LUeUUTk!<4rOg0P:x_*Ky5J٭2WKR [7$%='^;B$ -mhimeh,<|Bo7o6 GyB:ف6iБ5 I()`ƣXҽ|>a?5~zY|I X57q;͙ 0d#jP kRbs`GSy~k'?qg]gZ`2"\[WյQ:+m3 <Ó_tT݌W`B2K̵Z,$b,x*vy$erHF+E'7 +#ʠLUzЄ`=(`+"h0KP]YA*և #pCmO|؉gS3S25:XWQScA:"J4*k qUu hGCMB%3 ɤ96gv)P`/x"vݼr,HL NθkqHh%hhuՈ~0QÀZXcXu=7Řd)3l㪰ɴ6<ׅ-p$3 Pap{ʚ+N??\KU(ҍ_YqoVBݮHh|ub|M@~.`8* M bf2C۝_OY]9qOX45A, bܒI\g06!At}=de; 5j@8 Ұpͣ[a큡v%lwV^5C:|IWl 1ƌAmZa#_~lq;㈃wdzv{Dr>p;g\#M+{c-wZJ#iS2/.pNu$Ic^5;XbҞ;B}%>~ELRA#f/5ñ`\aᬞy UvqFi01h!I#BGSMx \r05Y[)ʝ)ś>]"ҀٟvULNp4Ċ/CDcwGlqv-وay| kel~߶CdB,YǀQ\̼|aށ_RCKx|ƞuul7QNw'cꬥhno `O[8@eD4R397Y~ňCCf]J&#ʺA V[{xK֠';^A'0kc91,AzUA{ތ+Rhl/|W]z==3'%ބOk[iyeHğ?u/_r r~V{0_V 1ZI#-+)9;ּp٥G!ҳqiއMG6n2c>~mlG.Zg_Vkaz!,F?\[_Xf>'v:v嫸kt3Xkn];HҪ4 Ǹ;}Bt[ҜO߫ID n{xsdy IC}dE~gL N9F)vѣS3No1F}M/}La17^ _3#eQ 5věؗ񷻯oGA'Cug!%#ih'-"tN+r\؃i &Ju!Ϲ1x0{ٗ/nzn4>&f즏覿~@cNy6馯{yF_2:2?RؚF(Z(sLH6pG*'URy;#?EtL`nȇ HQ2@nWyBϪ(&HA([:,U\#Yy6O 4qt;ͤ/M^Cb %Gw;#יYшyٜv'MDC@BAIJ@h0YN&Br.z4v8K|o8NhwD2i8`"Z`Y"_2 ; f#xzp4LUxO9as,] RX@68j0 c#ByX܌f~G4  @Dr Wu4XMH4'ЍB®FB8^F\]#䳟 W/A`!8bA.&<9 1Ƽv^\,bw *A@Đҁ# N5:el2T Pb.ef9w\xOQ1{5#+ltXG@H&&I#Mƴ$/]88z-a,h\>Kzr1,jG퀽F܇3g8dv_}>jƶO0ΓPIl}]GYd)u.1߿o })'й}X8Uơ1#e3|l}gGלĘb[~OYVa\*yP˜~¸Jy_*j6 T*eehܡ8TZK>K +wk@T"Mx ?-r EC%m1F\}bVށV=udiR3kiح0A: Z+^a05PlNN.!VQˆA,a Pqvq{d;#IM! tB+ :BkYEB2ȅE@tA7ݳ!8n:tlNk5M7I λO 3`it''+h.zx k IXE~ɑt:Yz]3*Cs,2B0BJǁza8p #@ ;5 A9!rBC0`3StPt蚆 O<O_@fsdg+>zڊ+{~8p1ќBWtl^DAS/V`#LՋ[`X0X%=ZD Shd5r*~  h5% 8e @E2I,Zԉ!djWքD ^3)D6,l*Ҏ^elGoz]'baU$DAO+HaVc1[YfH3 a 44=x44uHHtA mbAPPTRQ< F2o/k+e ks+xet(~*TF;)(v/U!EZ$&EQܯLpJ%જtF>e 5orpFYnx?_,^ ؋'O?];_D~bہuKLPMc =ZonvF^(#Rx%'kmPzTVϟ֩bu|ۍF|*In}RQO~ AБoVla"cT,bpn, ~? + ǎdyRq~dͪns^ kGY;LC;:V i!b!>ۡ6 Iȴ,6eh v>"9}ktA'ێoVl5{CH>DӉ:3ϧ/>S E'L'f>l[uؾfp͞lX b̿ߤVv~k l]*M0Q5s%I"" LaaG2wc'׫ͨ5p ̔^LaGG:h$~qH3Y]\Cf24dV-d6x]')D#vc[4zʏ=Vyԑj#HG1nl'-'qlNZYa,y-&v{ j_1NN;bN~Gn ]'Q^=sH:'7R6|L'CyAƖ:4BA՚^VƕpP՝ϊs-zT񬰇Wϖr$xdMMJR<_*$sSŋ|U= ^ _)'U+1PPaXk(!X_U契jSsb@uh^}-9u=XTF|E f8XLf ` #@ѐL2:"tTƆ!Щm囿X4bqL#"&0\68N̒AM#F:DA&HùEn!@D`F2|&L36`{ ٱs 0iD2 "I!sz?0q4J'3%D"Al ɜD(fC;zNTV>(L[,#r)P(Df ;).Xa8 "JRVu݀N IDAT#5hKS"Lj䫢`@5rridlTK3h5V's຿] ҢTbhBt,d-wzQVM#@38YԕȰ`4btiq2!4car$r09 I!c30EĩdR$h hkl: A#_eҶY$&2tr%SEoa5dRi] a B/8Yd,@,phڣ7:p%2l9GpQZ{y^oU\V{/=UXP7UX\W*R0a㨔4.m@Q6A%|pCy@x91kлϗpNR"Վ$Ob5|=@:FieCzT6rmX7]`dؚI@#@ZLZk=;س-ǁ.lg==ʘa 3:9ܞC $;.(T$r,0 aJuA# i N dѕVdl&l19H'qo6D:E+^WXf0 2)xty}k`Scu.vet%sa{H堃םcζ23n,d3ɞaHt% xD^ VZC2[ԋ.Ez9H%Π#FFHt<\: Hl^oEiD?+t:DFWF` L7TnED)ܔ/ƞ|}StR{IzMY~7EyMYQ1۔qx:FOQ!6Oqi1ˡ wt-X=1ݟ|_'Se<[gWGr>4jik Ձ 51= kקV'@mM5|xil$Y¶z>tҙLwn09OPhokzJ mxӾ^z-Uck-3NOUήiHUN5ް/ޱrЉ /{p9#}9(!AdD$ HL661k]gN8 6``rFDF$$rLǤU{oy+-mE}OXek&~Tt?. tU䭗AATKnZggfG)NND@" C&r W ( MJ**~xB!Dȡd{r6)AR-ZRkUs6ɔ#mk:ܑ /T(-c Q Qzg> ,䩿rӴo ]*eYkTUL"41M*i TTh Y՛9,c TOWwnNaϨe:[Iimۤ:6XZXC9Msʍ2 (u'`Ԁ = L )'@¡g8u־2|VY}Ӿ_>U#.5y\vJu ׿r$ޞ. !C<Ah (Śч=}Vr h9 فx7{v0 - NksQ^b>ƟȴR!(N0,ВגSTS?ޜxv:UVm#H7 9A}-]iƚn*w+\&b-bjѦ'=R4E1H9`m0A~[Zp0rR s R3gڗZ3oypv*mm4ZU򭷁=b BB~dd̓+ hjC`d{W,֡QcCHH"qSsZOǓ8jQkd* `ZM'O4)YI9LJ HhUcFgӮ9j`{kƛf=_d@jbrZKA;s 6 1ŘjaJ[8-3 [# H"%e@j Hi+,%`bd0Jpɀ voI7ApOw'50eѵy>\8[=LKu Vf'R&r6۫EӬ{-Zixkѵli~DՀjOhv 5GZ=^ Zdi[֢ileklBK-Y]gi4ݲem/TI;Nۇ}F0PxF䛙9,*d.2Ð+GӉW*/5I,%JP7roZJNQeμQriJ qJ%;~\Gѩ[Ͻ|[wCae.%@ e]u>)#aIȎ;Y:"x9ȇLN/Ⱥ039"Bf-|i {%ˡ$dP]Gw)[2%Dăiv2G_b"ΩoM*Bwa~ P>~?%^3CDąLȧqOr[HyQ쩜W;b"v;Gu9fw(^;(AB/pmG^}QiGB`bz`M|ve§F-$}(>nf.w+y (r)^eG A \할;@PcQ̱y"U~i 5(S>`RڐJ펯֢Sw2, . , wN6VU[.I/3(LuTx_V֎y.%$B " Fmȹ.SWl&@X6|+t"XӢ>Yӊ={kE 0PA]}. 5a;uY"dɮ;˱G;~\|[:;װ6wy˝/u>4)m ؏gM w+Sy<hNG֓ρמj+zwaeـ@,n^5ݽL*q G65]i#W"DZ=/hcv:g"}lĩEy؆DRԊèx@e\ ;ǯXljꝈ8 opPe*+w#ҳͱ&; T3R=XBΫ ?~z\.רk 5l:~O>D܅]TzV Vym}>dbF{:zTJʃuѠ~ ca?ItKTlNA+__vI9Ѡ&ye"ZYNpTh1I<͇=Bۏ:߅q?ި1Ad-Р`bv] 5p}B#?@"J90K T|;icq>#lWO~|{uOSw&Ew˼zX`R%]9K/m/wPO5L0[ZJqVHn@ 'F 'c'O!ܹ7/8@acyptonDg@'\w`I7Q36N? RP4]V ݟLf|\Y#a VD@\DԜt,1C|=9!4s'vۮ r]v^˝xWΗ:Np!8JBLZ:P" ӿͳ J 9TvK !B7jʝ94zV *DT!V!iROj -t0]+\B4O ?ڎ2 ҍ.;L\nq6](D ıHZ"a q.4ܧԅ6$L葴S[ߕ0ʽqu Tw0PXqǡtQ nf.Sb@cp ぷit vg84Ȳpiϑ .$L׀Lb[#2iGi a˲4.ə3%! 2{o] X&cW帡q|md݃lLʩ4M-ȜA7[[KSdбe#֮^A/<%kzY˱zV^b 4g 2DiB=s~ +s4~j=dlیQ!B ZJcO`ȴ !q AnAK5R=C8G܀?! pCu*ז==xth> 朳)d?n|OL3;'YyS4nxM}Y 5a FdVo-Q#]#T0V?+{FйLвY.Єax yQ8#Ñ z1ο0FnDDƘiaڎ s={3.z k #]v%?̻TGq0d`ޜ;.Y`z k*) ?I~ij:}*of?Ot-%p>8l|#vv&̠<{̃'!SO[I/!w vh*"7,aG'" ~>{UlC<ǢDM;N<W~ xdQo2u,]ۋR\ux -‚Ûƈ:B u>'_;OF& 7{-®ӎGrϚxiXѓSvF6w~ip=x ;FM3␗{{-k [7W5>+쁖z7rLq)y_^~m>c)ЏD!+{1C gw*6Gڼo,ڌL'ޝM#!ZGw&W7T)dB@[e|iعp# gśx7A#!Ӱv*:o 08mB&7_܋c\lB^k1'z})LA瞘MK[ÏI!dлr>c)ߑH&*mȠI%2$" ]+"Ic[`x,j*\AwhujI 9?zkS,P2I{e?*ۂ*9؂jF?4h\+Z62b{` )>xq kZFR yfJw2,01MF%Za\++N;3Z[Ҋ !S.3‰'a񼗱î{(|+0 <:Մ141Bsʡ%Uwl&dql^ۈՅpPgsg,ǼѳTi-hm M0`K2V45ąE} i۷``R;v?EZYRMx<s"܄lY͓fb9. (> wĤR3?٣iut)&q;qy_o}/ޏ[]IGN̬{!0'|Tc0M\ǰrRp|wݿ o=As~<|xs|]ߍ,\=cܗg/"`qϵW8~ ۪茣>&mznr౸faXո>6y [pAߖax7Ϙ>G=}x3GO,f}rbaxrJ,[>'5 OC2] ?Aƶ`ыfcՠV ]S1c^߇}8“1"g IDAT#z۸3a7>G=g\Eݸ7wa䑧cȺr؊Ǒ?y`(DyHG"u>':Xp{x洎: >3bl<5T΍MӉ&0V9}g dw N~PigɫCރ~ DhZWɓVp&Zv vױvɱ 4ߡ̖6$8:U2xÚF@]ܴCECSs+,ֶʽ @>7Ǟ [-; ly~??_zvyodS祛0@ww?23s=+x"9׻^;}%e<wJ}b_.#-a2E/ðOﷀff.D[ 9\ vr^&u| xu s?u5y2Ba:;zPY><3s7ꔩ|+;\Zš[ʻWSw'| CUsz1sE%Y`f~sy܈t õ]; ߍ=7%6W(oxל3G/{8|y ȝoEJx|eO2׊y>?ϮJHϦڎ=+4f/Gşn "n,gi~ʍ>}.|گ^df_pC/wCC?{y\ˎG| /bf^tj$03?;~ y-<>×ܳ:df^qgx68i>O̅BΗ)o  g>{Ґps/^ͽyfsWxO^%|G ^9.K/㽧[I>xSg]>kx. ~~|cqǎÿ>ϠgC2ʍڀgu{xOu&3UOĹ7 l)| {8Hh!eL?hqW3DO#ƴ8`[J= w;`陏{+2AY8 xgˮ/]ӂ;Bc@ЋyauKyˆC:W7C纍E)0(rYWބÄ 0漾G< q潈G#qw7 6Za-kAdQc+0ZV5:5cL*VbD,0>V b`Glͻ)2DİxYے֗$&; !W8 fON("f#뢒xp«L1!C I|,+0@l,+(ǯ+,&W)m5-\-3\_MMhljFcS3؄ƦfnljF}C#( 9@" :Nko ;.wI۟Bŭ/duM %yBً1rDA}idtʄ7$/1&Z/- @lB'3B͖jmAȷ҄ lc ZRȱ܏y,N@H!8nYXR]߀yι_Dw~x-ˇPa%lׇyv_GWJB}9Gaɽ|y.?]x ^ Ol!A6[߈~|suh, 8$jh|UKD3_]p9q4U+-Ċ~Vu-N;]c.¹ Ի BӋ 5փ˟1zzןEC]D>dU0)ٖ&dЅMN4/?t7IN~|yn+3BL}٤J|MYr@2h% ƀTU,F=p)Y\&% b!ɳ䃝J{BQ*\u)Xek}0zI{Q)ٌbKb#hVyj=bQ&=2vaUXWs>G\`[3PxP Av﬌{`vO-M&M7|5E0$[\FcS`[B)]@mN0:1,]@eͥ^JIL_5 -Y-LN9dN 2n_̀'jK?:,zX}&eѾS@߲k7Xw,èQ?~~\k1@&֌Yw8was)Za̹q:c6W>CG%X@(exoIMD}^m˿ތڰJ0:n[\WV-VԃӉ -h9 #1m~8xl?03#hp>ڂRVO;E)g=|::[B^Sa,\zzLAA@ByH}/>^1L!Q8++\-Wb{T&0Ѓ>"S؋50jCרlzF"+YŸ%|6ū>GFl^*漺v\ (@0'~D]qᩓo;vp\/y۸q kdʝȉ;n3( v7`Cf=r5 4w9xfU/yn[:ӎ 4셏WX5Ѕ') wŬ#&D@ڵ{#6a"<6z?;˞y 4 3G?ft6 oSJ݅|pI8 /Sl2(Ɍvoو0}qNJ-uŬJ ͛ko-?cN3qz4l?\w; l5W\5ASh.;Goz?>PCOO/B*T{2Nܫ?ek;ڼ4z_6e$/ǰl خ5>bi8"($ Ź;1̕{cb‰c;^te}AoE DݸK2&/ZpZ?_Ѭ[FD/yPM)Ei}EI,iX,iҮdCt^Fp~i~=>L[G6Vw,|;O{4.`ߋ[?GZQiԈz={7#ݾܗv.[ϣo _FfO W_x:stgO]}ѡJ_4y1?PyiG=`iѹ ?>.=(:E XhdPA)я1|i9"r\L:spRsȣaqCpgqu>0~_p|V:|ߩN١L[`hS6rhݥsyzg2;F<?(P+х3_=] `I?0?n\0uqSD9/щS㌯MO:S'!_/D]Nٗ y :{8gOSgSOc?}%4̠;vM9?(wˎ(}p=jsQ5ٱ3yZcw1Y^v& ųn2Z1j']ץ({fWbcݞ)eHt/6k^5B)[ *[=dlV靵XtںTF&qXI;k,jפ@@nP,Ś$u W;*&_?p %H' dC|VCl4Ì 1bpGh]vN&BcƎŘ10jh7kV.nd2l}Uz59 9}!9F9ÙL]};?|>@E:B)  uB?82f!ĭ~ !r@8UXm\5@LXW8n5po,GCa[aa u)@A2O~ PȇBb#~ܻ߃~dZrgGf6 0T4 ZaHyU'W#i'^+(@@>?(s36T knŷ?'3CO{ɧL*Pu@X9D"=7-Yٲښ9(2@hmiC(- hkDl' ٦V6d؆FkK' ~u],ZJ +2TUh/ yc(=wfU{)Lbh#;t.֚1Ŋ'Γ%bwWj ‡ L}C;Jq[v5w.JxG֝{1W,`*\IY*)+gɺ$2q,tM&p!,OU}gkCXC}Vs^9qb}`qdy3M1+R5}sWv4#uڗ1{o|n2֯\ b…hl> aVخ:} aL׬YK|nH7KV 13w22BAPԵg1UL buj[2 %τZ7Iꩌb\a+N,B]+e~$*|N׷Vu_ eŧpQ(E4XAUlt|fiHCs چcq*ŕ1 /͛tRXjHy\ KˊSFAAdn,)d:[>24\8'&QŔ\:'ɖAwPQtSY˷IFybu) Me}58Qk@\܇\`7W1G|Cɕ2mR]Y笲"nZhǔ'2 Fi#2E *l7,ҹ<b;&7Tschf,h2kxj@UXF< ȋOFEA9Ɉ\ݕ},WXhe?츑BG.b-pwT y)kّ"ڍD]{< l9&"JZ+6ʤ7 ὏]'Vm"害 `O]A-cEıRKB'DYBAEc!%x?Bk*~5=p&3V=Z_ٗVKZXԵ>aLH{]&l&"j֕/Hˆ5aRR4EnZI]ͨqZdJ1NXh֤]w%K $P^yR7r$u4fal6*a8б:.4d<:} }x)MI+9t[B]ܮD5#>h1|]Z ZԂ$l@S AVCn O #lrgNi) {[c"YW*ԕ^9ȳ{>%h,C{Z0gf"?#~bMr.)?e&ӎۗMf#C'_:%4т`ŲT8R٧M;-%xY)xX͊HX*Y$T бt6Vix͖UZCp-Ee[{Zrs&PT(XV eD+)v־ç&k (FSF؈T:<n0bf`bR7N!B͕K[C"bxl:$m eH+aɒlk5 7$+RX!βYSxK|%teܢUڤwYlPd-}_xib<,eS_ þ-#wAKiW9A=5M: Z`s|6T;KoZ}_-ӹcH+=/ZjʝłEt(*$#$Q"Ƙ"RB2T`DTȀHVwSEeԐsL&FĽ_dr.t)v+TdL:Bb"}G!bHEy3%DunzG! 2WahjcȑYȹ5gv i5]ʬqaF*ǗBO|4if_݂8bmrCҜ4)- 2c9[%"-.qÈǞqeP)O_җʖpt/MFf}\>D +NW QB)0oIrN4<0`L5VgOׂWxQ]sD N%UoXIFuHYoKYHA9LGLj0 r.[hpQ퇐Aj;Aۿ^d@.dYcBt0l cb"d{XF;;Q<& E/A!,eImjtydZG]XwӞobod,}-"<k Q}`YsņSZb*sS~lDhDIȊZXJyN)'iRYN1E)zy $T@Kg'e;`-JT6 )sK ʴ'A> E2o@cbQ3+M[;cmh ld[Xo ) RA+-&Ì  lK}|SIdcdL0 6Jqhd)OWWMZ0X,$NʳT-q\YxdG""282hإkoWX,eJvk (Gj]~[j!%@ 4(`ѓ#c,a+,(/MF;"Ͼ_~$[j#B!XVsC44Yy ' /$uohMD-rP-ԓY )#Թ1-*!Z{j-46.cʴ7Ő~Aܧq1kRvqNL$0[.Zh knvۖu zH:R 2udP:WXA2- DX? kdYY3HV m|{(-)dU D3 O#c.uȓ„UE+@KAqvy%J{W'H?.ORm#:z(_4.-ldYtdO·Y8~9V;SJ316N8c?+kac5sRY[ $1^z5}WGG( xb^݆҇ 8@ahl4ى_$zx{Co ,ز%քMNU46=&sgܱ죕٬9iZgoh!&- jbUEz$QRr}- JgpfW:Yʟ yRjXTҭjדoTE4f?HJڑ4xE*w $DaL7I> J:FÛRd/ɀE`"J?j VγRBS29Ŧ%Z(qn]ɇt>V RSkt=%h/A4ؠgz2آ{ eꦔǠZE顬Zox'X6} 2Xe>l\{lFEYEP4f'ү>7 il\E/QTR $G~z@Ydjs3L g 0=JVtʹ3OXzShA _U Xeq'5:HhdV#A{Ĵ+>‘PeBYd (55&;kO;3@cU\Kb茯fC|"a>ug.  rOh)׾(e0\HOd1vGhh&#HwwViPRR6ROr=q9YٞZ_-"i1i%5GJ੷"j-Z 7YiXMd9&@ao͉Ң/ccPUIԤmN罟"m {j'V3Z>TYa#h^SK/_ @γƴi{|-.HhJit҇4/j,K+>j, }A鏏 MS&~c5͍UͶYMRkܳ)f M MNȬ1SXeH=]FΉ7K>TuyG.+q+Z3VJĆX[ؓ l)V@+YlELHDMk##fˆ"ǚIØ`iZLkeqgТVq{VZ06ڲ6F}-Ylȥ,ZLȳV'ӠXfgYq$8agkgf{} )Ÿ"M.&h2"+I 6fef$ڨPl%vN#nKO;u$PҚHVerm:V1wV<4Q_]TyEQ EI65tWo|5Q&fOS.f&SV&3}B#5dj@8!fk2Sk1y475 A !9Y[=# LA0dP@Y F;<6b{1oAQ4^{k\|`gJ :|h&¾CsJRm]6D=k *q&N4ʒ]șxId Ae4X' 2Mwe",3#!Sl8)E(ꏌG}F][Ŷt:=|ֳ<},V [34βW[<V4f546Z`9澂j/ Tgd<V;J"Y^v|=,aOc/[س==J BqS!n#˜V+ȯ"~{RWuNy[Si3gS?~{)(.R4p T-EIVI+]J]-\!x)~~߇ge? PyR(0/Ǹ价R1{0$?/C~8z,%LF!P \ȍdյj-2iˆ%Fو%`S~ W]Xx`[ҀYмXq]ee 'u(WR 1\ 'kJbƪ϶L -~$D4h$lRPƩ͹+ltǕ{˷z=pL/6T'ZXGDR!twnݢh )Z?1zH)؀[$@kLJ6i/5[`5um Rfk|AhzΈJȋ1GÒ|l*"g8Gv;7y]2pBAv,]p;nw=G喌"()sU?9b8fFI:_Jt?fNLŁN~t8L"dÂl]R|`Vo㎛7iap!%נy~PY9hjp=/yEB>a@;ٗO{oœaPg*Bh8r8_,aCaaa/L?g؄\!Pc){#*~Vuo?y]} fJ=8oh, 󺸍Vc0C'w؀>~&f>@F,lxy״fqLd[ȑh3,z6~gwvGX[bAUo{奝8[K/[7t4n(y/w=|죣`P& yXՈǝɇd(@ۈ|i44d5V4[^ŋ+S?vlQ}wTE;KΒQ2I$A@QP^Qŀ AEA$ "9(D$ l;qgftY3owuwuuթS1H3{q_H\i[tlZAٷxږJ IDAT(ݢ+j2ğߋ?nFsމIN1 ɧ;}0r`ӊMmOT$ʕJ@Q.mGYzI$ӎp|Aܽ=J3 V\)[aqSmucS&kPzvI*+C|5 uRr!`Q@`CK4Ruvq1PBe/U#,δVEX]X*ݬIfᬛ;:PtOdLG8lR] u8JoiUF[u8"%jۆYAʺ˔R#R`o}j*mz}#EU Tg|]GLlҖPvv*mD :Wnxl솳5䈠mkU;a'/9t4{qjD !r^Ic>oFj]LZN@0+̣([nڜ Bx镫F..:=M]5_"iO{%|=R*h@J IcHi3*7Ӷ\`2}8{p5,`:8M8~\Ns<͎0.T!үȂT@2s~:sw맰t)[W;qdWkpMَQo~ޅIÇHMC.FQb߉HF E;#!~!יz{ *m9sWOCIǪ7ov :8MQ1 /åcyn$"5)E2Qbr s7 l*N혇Q/L_Y@ȵeoYuד_G+N/*>*W*@|#IU?2;:>{_WOJIElK(KYB9^.FPUWSLT>szj䡣eWMQN;9wg7'bI@';gGsT뿖8[>^3YIh*#쩞eknSpasѱ(V B(-DՖyXhqA<@՛ˆm^xCvD ШU 5CC#,E">5vAe) 'BX51mR 5b+C߿*~ }Bt{?`ܺxQJ Z ʉ4#"Bg~j L/|gv G :z/oqSSt䟿}L잀Pf\SxɨloS3f3 f{pturS85 x 5 w76D?K%ʖ^?*P{2~*Zdzfpϋs/7DZXI/D݇9ñg!T,mmr1ݩ?9._jY=!B0(y$[9> GeP:O7 T!^0[؎*,Wy勘uNȞ,~%ɖuk]LQcg=r͛') n錶iǛk׮:a9!T:>R/dȎ" 'VdF+oc#vc՝+\zZl: Sԭm$+l;*Y4wrm M~:džd/O/ůRr^V=|qX6W4\yY /:r2A.JMp'ѥ=_PϔUd<֘Ȼ ϻ993(="jTy|GjV8._A~(orȣj,e 6eo|3+3d~uq|gjݢ xt-@Uv>' vi4Rxx`DeZ?Nb뢷i$7-31@"t3_|RptmjؚƚoUBn2F4kU{CX,(YhK:PQ'!r BHӞ4Pf+i r`T!P,L OG'">6?u96?6ODQGV&YV6@BU[QEPjР4%^8 =,X'6on}GW}}=+2.UICk5NÞjK>@3';-|D-=:Q1a\$faQ(Ia1\0DE3'3vO<WZ^=cϩhM%/Kv+!O=o~z@A7FE\R9)ɾaTc6ԦޓhV*(U4>zQT*n-)~/G8K9֮_,d0IiƊ[d:[Et{Y3W2}Jl?OK!eLzGފ[,k:e[Y=$Sk G$6:SJkjBMDP{?*}/Sc}lA:G.3I9p2LWXjxcf -p0؅,P+f##)HH`]-NN/4ng#5`/t 3L%׬}^Vʵ| .u1hn [¨T~u!,jHESF\"2DdY^(sSȯB6Uǿ?{OzE rzXᑙp;0Ys^œΥeo29l Ջ@ 4Q˷.8  rl5 @½T<02Onj_Tk|/Bჸ @.KtƽsqսS̃ow2S BXL r;o蛝3r ٜ.N8"- ۣ 尵MRyu 9#\P!,:@Jo"7FmW"/XK3.9B@!kتKLP*e*EH% h h<'+պR1y-{ `{2rDUn/%}]},;:k3)dᗿ mMqRNͿ ݫ*BBo:&_=|el1x<@~F䫻[&"LeW6RSҳxAMm5+px3 0+bul E6@fedTIWhHcrB=TyF0"8*: a!Dx\2v~/Fϧp/a{@]0mLl?zϝ-؎ڍ[f|ׯi_lDLg]p΢C|M>T~;@Y9o]É?a " 鉹\<||T??MaIQB ݁EK\NinT=.Q8NɯuάT$dk̙ɜ Gl {ky Tk,Ǎ8f/ p[h |! `1 +;Y:6b5 ] Fƚ/r-V0[k1MTAdXQgqɒő}W=:V5sᵇ/;1ټD."#]HMI`)r 895=+o]>MMט4hzA-u\J?i!f-3V$«2>Ofǖ9LJ $,XJ) e)W5}P̏l.,T}1(I6ԏ*V_KlփV>t$ (8uaG!c&SAUV̟PgdaΕһtu>ِaF*6V"ӕe.EP o&巗5"LsAݚRp,M5yU7ñ"/VOꟊrW"%Ԕڹ\Ȕ?Y?PHŹ^!Ww;?|z/av,(jիEx{VDLS!A(p  6V4Ǵdž`m#xU4*ߏL;A뢰&hu2Sac U4#ռzL4n L-‘}nʠxܿ+\4g;;V(T{}2E$ff \6 f@&o1ӗl5ݭVgBOĄݐ\P+j@v&?.y;Nuڣ_ u} uzǠ4{s)ޭVgeU:׫YMse? 0~~ߝ=s\FL@11Mʜ xi cQnM{=NģoV @C){gbkbTE#b-ڡauN.\7&`s(TDs." >~f lC?Jd|@d9 FPFiԩ CDT(bJTB*63܅+ө`sa㡵z_Y3FٶrwPybIO TyXUR%?>`MAeEb#0vfr>5kȰ?o]$O6U9 }_/@Cjr OHcT;(f`l8k!,ˏNJG>h($MDd/;XTcG~r |Ё(Z?XT{-ylvy}NGkyőbswhڱb 6vy2 !`xp9`r b!27f= n ~ BN՘ )`OI b҇!So5Tjs78<u- uK042oVB>'y% *Z%9f}fdPb+bS7v5O_gAF̻9z!>c`ֿd5s u0Xj つH@@#USA[YV:lX%'zFOY U#' >f̤ACKmy'(lG:b2 M;gT5?;a}ӨHxO(~y`K8tgsh?YYREU&V# `S-vV{ŌI65|bhiڵ!9]vMtrtY.́tQ>;t~=h#_ҵiW1XsZ~:[=/1]hM~=֤]gcSImڬIa+"[ݨNϏ<(PG~[/ƫ2h3~X^~tS-+I<NeO/5d {-J٫8 i@ut\ unٴA|v*.Bk1y ymQ 1$|vyI&cė"Xo4]OӲ`L6Y5;EN>1󊂝N)hi򪼌V'ynU/v;^eB:/1nfpȍ{Hƴ<]ˢ|X|kTѾR=|;߲,ߺn ?$~@TENH'E Ef>BWW-|X`U^j)mg HﶅH ^%^_u)ׅuެFI:^]B;tS˻ycS:H|QS"r$&d"z~U˂ W]|)O%OÒӃI(cc?(kB^$dYUcyKV7B";cT#O; e4"F^$tvu#: U"}>/Z9 EQ:1H]-虺,P:,ŭ'iR dJD r1A,.[* "/Ï aI-_a҅SNVR%C̫ d-%!Y"b`(U zMNF&+Xe;F! l f"!{1+لT-!vSȂg#t%qc,sF2Kiv9L.dεxv.L0RIY:`U $}F0Ҭ=yV 9"]F `DY rNdy#Mκ}$0/fjQ^]UE^&A ðI1m{\ 0 ;hE"!Run ~sJEcw^i8gV̉|R%>[[?!S]xoOY .~~JXBRk GL4xLg,KIOE6L^53V>pJ+KbGVYKeB.NZK22 hR3| J>ƠLQkDQ}H}%E*Ӝvy|Y $[Ke²$;u:',{ " Ad0$2`8L"U"Ꮆx7awA'iÐg%aI|2 Q.` +kJ+>\'>0 82š2pXRKEO gRk[ 2pwP%cF-2r,|8p8<^}<&Y'A/t,0/d޵bIPq|`3JHd[5/0 rr!pzv$R"C0v_'ÔA|xѻT:},9jo޺dbP ' oL2`G( ?Lwzdj9N2yԑ<V: IDAT0 2Ppq_)|+S֖bW;yXle?_39``zxVΆAlfJ"%ĥ0].)xUl*GM}yiTn͆A,[žcP@Ww;"{f v^^#?D,z-a_G'$sZ˳,%'$sZy_/d,"b 6(>Vg2 F¶jvkQVc[rć6[>2f~PC6}#nmhsURf:ZxIZ[BPv\jG[g<օ. :a]?:dR>$)8CeRq%]STqEXa먾6m ҹKt,(SjΛt3yzdۺ G`|C=T~7VWx(ZMZyazD|NrpÚ5OXn}GazBcZ!5Y?,:."LoW%.6:-~\Lv*{v}wZ鑣m='\wB00(@:ѸV)3~%XΑeu!\E>6{(%2=܂ =O%k#zXA"վ6*:_`Ayk)"ⷍ[p.1̺rKu5Fys.=쉦8XAq#7-W /#zk ך  p .ztw,]F'2kR-<բ'Q! g(vEpd8s֬ۆ 莾m#Xl~sgOwR"≖<;Ld>S~@юGO)]cU}~׭D*9F' 蜸>FgXȪ=v~!gנ{y @WKɨТ7 ذi-rV6P(ؼ(οbx@n;=*V|ŅQNâcQA}<^@cq6@Z-ѯWs:V ǣ @dH*'5*g&2.aI,_g:a:7; HÑyQIW Z"ʱ.t7cZa؀V\a{Z h dp ǶGn V; ۂcr;yզ_q7;;۱rp R?lЛ_VajL0;Ɠ{2B xtC(_Y(MHp kW?wPRc.bʟp:>1j7eɭݓ{.<&0_ٿ Emh] I,_WcѺPZgZ<u1(… "}=aΆ?j"@ՃXnFmolq|&Zm̧@Y'θVL搸C8  K; d]HغJ6û5.wM {A98g+K?ύ˅Wl*l[( o%cmPԎ5/EvX)4;?YmO2aȸww>4ec@(Jru4G,1w?(Z175>XqD}w$]t` p0#čkr&80<ߗA)\ !V"H- ݇MgO7Ʋn]spJTxQt2cR-sy˻?#:C1#' 1NxoHKF߈8` CxD$EFSXXú6)Eda֐j`fƝGad(P$#ix^s <5>W?B đE1lJ5tEy@ 7ҒA.(<X[a34ȑINo%_4HJ~?,QDw[i]$ҷЬC4wo|*l=ly\}@vz&iWN$ "Q0ţˑ0GlGӆwf`ř{i"+vW_:Kd"*Sv^C5˗@P"*i[sȗC\hH 3FC>.v}=ZJNHƹ @A*^0~xLY{Ҧ{Sp2=R|!&Y QxxBWgN͡ zt(}gO.#'-+1npWh^ZkruR׾0<7q9=34ge)lp5n*CߍE|a~IWr}̑Bx$GT Q3Lվny o/SW='# wzVJ|W+}l "*k"&$9|(>Bd3vwz|Nnktv/X#(rMipHF|JvI!k}&7Y tEző̼cK\.!E֯)>_a~-?[g}/\8#N:%.| 2=_M[g~%y.ⵏilfEO\f8W(֑fA / 'e]ődOE:y\.!]qDZyҺ,WJ8-cNW9_0'#T㱫?;sEEʓU! fiQHuU+*~xYR+Ն2ƀeUr]簓5RbboW[rE`[sx(lQ`qܻVX8]RGևOxt?JͲbbҢk~J#,/Lf'xHբgqI:yqR ^B&pܩ3øG13F9HI)99teK9g:߿sWd;C=N2V%.)b+EFOrϭ V੻23 DɢxK3}b=f23Dbylֿ\[wM>uZ:O]w2ŅU/aUyY̗yLBR9#œ[WYp˻--J"=v`mQG+GbFj僣),Q+V\`> QB_qCjx].#~VC{i#qw)Nr: 7O" z/eJR"=3t䰲k,>k^zV<^t-ov$"ˊgt9oGYң?W2!;?u?G)#dy_YJ2[s7 哳rف;qPY*3A:'`폡cǹZrs W.0qpf">@A3$0C/#PRipP'> 76/XmŞANp!\-ܴNZu_$#% Ǖz*r/W-B K%L>vuQ(MS2L aG$BxJP,O.Ь^߾{1OIpbuFϸ|jNMj0WSx"f_yP1wqOρ8^pp|jq*Cnӧ\A W6DƐEZɦT3l(Xt:vH$2.3W*}PY7u8>t ZP5[ Q.D""Ӹ  (f,pT/C8u"MnG QxU^I*YCJMg!ԩY^: ,N,4Gyo/  b;HHɄo&Z.2)KUk47EC N{ MK̀+;T>@3kLӬ oNE%_.#&<QQ2&0 qקKBx ~˗n +LQ϶m#;p^2Į/1|k BT^[( tC>lMڷ(`$̯Ɩ]OkW3;s]E3N63-$GE2ac#gVyؤtyVdr;$ޖ+Uk%0&J&:$~I*n?8i'ibJQ`rLO 5" FTn*8 Ղ$Z1`d%QJr\ _!N{|nt`$\eyu^0 7?vc1^> 9^@N6z0"AC:^"FU7q0;0Ae_؋s,Aͫ›BpT;h[>Xb"~'9BlN}.?BA }%(>6 LP8 b#(|G4ʅ DaXr\uBgHQ,5pRyɜݿTg<>"UcɳDA ^qس3^z4Ǽ+6?OeۋftɣuۙSa<~}8?̐(}#t9[|>)}.qʵ!apDFD#'cCʡ gN"߼s>NIK54ר?|#!.5d88/N0WTD#4{h s!ᑈ C/2]T\9>뮣 ;1./ sv+gGeX +#zzww,Ī [!ayI%!-ׇPlRR2=-ǪܣO}.8n50SåBҧyiv_ )o-lFcfl m->zp0<;d<cgeWb<~NJq˱HLILɂd+f7^gM.>禧!]$gQӖVϦ/6dsӘL\.!K5Y`o'o0񝥸yXZf(^_/ډv,U v5$pG/ȿ#`GH(""8o 7~z0B9籨]; O^[q`uv.6LCJDX3/hӳ3'}班› ~CQQQEC^jyWp>9lO[L^}MwDf2R W2HODryȏ=}@ʉ Ε*=…N2@Hƚ9"kn"p"]%c!s99]ĥDZB(ӡDŽe/'Њd?ӿ3R%0=JagM!ܽqYN1ߙwsY2`ejaXA 6W]& LV]xK7h*$Vk6XsS+Ǻ> ]|)%*Zh![ Z}(-ݰTAI`/U=i٢9tjdC/U$cJ^Y]m'ashZOK<@r]ab˔A?>[]K!˴ 7ɒA齵1=e]̎@fuF//M3Wc߈r*"cj%vszMzS3J |m4}A>YU!dA%.ŘE S9+ާrB6hS=ޛ 5.bT4{>?7.L;ۿ~-[;B5zcS;q-%{UFY 샙1#XQ!tZz}j3;kYec8lOxU`4܋:֊ĐחQ?b +'Ci'o7fdaH\P FˏOS^#byWT 'PO7`N1?}Ӆl\*Tӿ|Yp C! rx0 f+.Dfҟw$(l_= )ߡ~Ҋ(pgRb1sP+t~S:Mș$2JmsLC_ ن`"jիYl=GOP S0cM٨w1Fp5m@h qoC|H0zD_Bk qG.DDzF/}:mZ+ QD7r2Hp |#SBO=^@8_?Z7)^|4/:bϡch򉔼a2%F,ime'IѸuֈ*4G[7GƏ*}0?&@Vb޹*P>7|B)wreLejּ!b@@EʁŴ7)BW,uRV-!$r 2HO\te݋L+n_}}b0#B)HF#{ 5 M|4Г͚Sab+u0|4u!.DPBOE r!iEQ9%iLd-IPKK:WKNW%Z%X_8ˉ> ANF+KJWہ *b@EQQ1#:814:E1sBńb c # `n7Sj}>3v߾']vUk)㑱VƀDlBlN'A#ACkVcvVH\Krj#2p+VubxN{&BӰk Ƀ|ЄQCP K@TwB=<8}8Z6)%a|SAF{N߱/f&_ȪQ6qNSua4Zj:&r<DW~ۨq絁5 RKYԅ2!|ƅ+6n9#:޳T߁2!0VϪqס`1QͤƼ_ZϦ\.'OI[ ; 'd u|D8 } 4όlLưwpty(:~M 3(*2lT,ҳyj޷nDڟG7㤏5,6P*9:L)Y<1tGDB;@4zXOBX`g |}WbY#@_.JܻBa!i0nrܜ ?̛Mʢ"!ـ#Y_PM|6 (74QAi:(Ï7V!׈ޑ $}\6rb0ȋ?` =HY/=hHu[]|Ltߖ.x ^_V! |,0M$ClPc̮5 XJ5.~*^7*LDr×uE?9l9. Qk n+; Yn27p7b+.J&GxSߑYΟXi8s6|YX}vҕuٚo4)Νq,8+=8X#P\#jC mp-$u☂lv؛[RvrN4pcCccpdX9g׉3n$4F#&rCcEVl|`*f1Ev֤ؿ#2Z՛$ B\WxfD>{P,|V{78wΒ(0\]oOX]({i#(bbsD`H2MK4XK ߢ^ ՟=JpcBMc&oP rPC(Ršu$q5'm/cLJ%;D)F.~V+;*idÏ֧Ge=r(qy *(!1K Tx O4@(H`AZ\vAȘ ጒN^d-C,XvM-c$ ~1(_ z2k>%cÉZl1T\4{ ߽,\IlEX @wFFS9Yq1Y[A^A {{ib+%.${Kۗqm 7("_xlځk[R-@bcUƴD״Cg4ù( uK?ax>eI2|& &1_aY@;,NzʘYϯ]iKJ2NZE^!(c㠰?i1m2VL\IjR#wʵb$HۃT#'!-{L['J= 00b?גfVW3 <_إ,icOVy*Gl[s&ؗX"-)d'rLwU+S_+8՟fd@C2_E-MJ$cRs˘pvǾcw d6q ;p3".eEav m|r^Bcɕ_`!wi/9="ߓ2]kÌqYLAQ^Y zN9W-ʵ-Yx k}?Y\)"󣱖k[w|zmig0x~kr5*kk-µJsu!k1=m}+"͗E|=r-,FG54?)6Ե"&ij{&NuqDi謹Ϡ+rL|LVPS/kb,b"O [1։wl/bh%S}]3b̴ kPi$3l2~'}c]T^uwyZ&bϵ!B`7TcsP)588UY'Zc(`P N\:\SPI{<(f _lQ^)TӲC1D.L+[ q[#b:.ݟ3C<'I֣{76ձl/,G71OY3XCڍb'H|$ | Emob9w]Ru =qӬ]$^S2aT%fX}Sgzv/noS2$2a_-݃YƳϫfoJQ kL(,$mig,$haH٬iSsaIgI3/0Jio+"l3m+^>KsG]S4="߳|oz@j#sf^{ˇn/63y5ݽgs|G;w6vߙ?g]+|1 7v4ߞR@R5qޏ'uK"0ّM5Squ&ږ7W()Irf+j\*fXb<=6E Fk41Qu{C1!/3 C[Z1Z_(:+p$C#m\fX֚SΏ';sJ<!y֎dPRҡ^|Ml|E_[Or\%o]؞ڷ}6Ǯ$ )k^'#Hi#(ʿ18.LBCb~C#y|8Г1R{HE"#_{+zjROm'9g"n Gهּ}H"=P7 hKMjSL1<H%cŐJ*ì /]/)Wkං{S|ڒOkrs?לksԜlRlͭUz=̐ȌĖkvg<* DOj'`j6e JH ʀNa|Sw>4_i %s2}d, =v}bjU+9>;p+J G WVs-Fc9' rAiPU6>!Q>$z0O|iycaE_dIia >X*JoGd76kBwj!lBw161|D .*BE"f٭}5F@0h{@of=XXIWXK˞a/6STwyqVl ]LnWEohZhJ;1o\gbG(/L*0摍C Mvm{zUϼu_w\&h#YFb='m >gkl4۫,xnåU1AkC [A%Fjzànx$浭|l;>x6Y4JSg %}T2  JV ϧ*nQ&l$.4eǘɆ/W4~OJ7#@zA IDAT(kv@bAzFD>pNJ…%yт0"i=j4,A =& vb ,kЧ e͟&_R mWͣD)u?w) (8ϧ>a?c#c.৖ YG] *GI@=!2U =JC hiIgN-vԮcimjLmP~,(C ,`VJF;V&OVN6y&XͰӼH_ 2h2%<`\d>ʧIYRΏGZ Ҷh }6o8̌YTEZ9e\)T*O\P4_UL $"M/#EKfjMf$O|Am^Xv4CpuaVxcB¡WV$D=O ^í y|P<~٭hbt.͡!.a9)H) waIkC7A<4 ىVJESͲQ[MX졯4ߤ{Yb;C0)NINL]SPisB | Xmdc0BFpTgbY}c$GaA``\a^h"Δ 3 [ {zv ^9lj,DeϑGR1Uy mYN§]`Y^&Ҩ,c/4gS!_!;GDq*#S9?;}å,~ß}=RYpȿŻϸ{%YHaB#ŖɈY`oY+VTD|sq50wJuا>HًI0Ɋv~9$Fk;( !Z|Vˌ,{#IREp_Vf:>FjDՆP`5mpI{䎅6R$װrtO$(>5:ڵw.` H amT`Y%qy<2A+j >iXw||gSObGltl=/ٲQ-ZN4~OX?OXfݱjU! Q1>Jbw$@ьOFCf+~ϲ+C,,g.*MrA1RB,(9*AF>;5u|1w% bc@aܐG%t@nZmP29#3J[S@t|r1`:;}b>_e°{gP"M sc+IXUxi7B7N#ȖiU@|"%$YE!pPLHPaC0VRi"C"8JjCJc2#{d۽'IU,+#͚Z/OU/fdEKy3F|Hikxd)x(UD!Bᵻ Z&&$iyFY73vSVFbQa&bVE²({STNnA:d5G~?e5ȧA ,}CU#)ZU1h$$DSdh"f]=0J)ӫ,Z R[1MCs{s+]IfA2[%z1i劷"BUezZ#+pXmMsVC@-H7a^+#v=¥AvLdOPMZ` U+#dh4hh3Vld,&FY >4vMAX`im'`)B"D[%TX'EN< %uʦI~yip acllT&-i: sQ# *Q{=ޛ4`$H%e}js+n194+4>;ײ؎cW)k z4UBn!(){h05 ~X -hq"Mk,U/bM'Ypa s"Zoeݑ' |0l* 7Dl~* $:,7Yē_l(0oNQ<ĵ]g2CAݭx]W ꅥ/z}[Eɹ$߆` \̪œk)wM-~'c"KMشfCP@4[ӗ+pkjiZZ_:SɃN;H&0pI$n!rϩx9f]%hi |!AGC_#feuUM 0;%©o*+ Y̛.6aCCz-Ӣ 1.x} 2?VmAfWq˖w` r_Ɇ^C]W/բPɗcXaP٣aa?e!BC ]pI0Ռ̦'C0YD},le@=\,kAd5gZsvܹNȠ2JE>4(_=ԼZv^ M}:)[JK$y͆Z'lYTFQdIie̵55f"~mrB4*`6ћVS)AceVZ^R*;$boO 4K]؝3DBӡ{*%n`O ݧGW h)HS=hS1wB:|u%UqY_c0_Y:4$3hQ~Y 63 =[Ya8PT2'f`2Pρp6m@e7=n& ȏIan+Ɩz`]36CO/ºhE&Ц!e͐XٓQ48"D^===v&5 6ɟ샀3GmK?,^d26C# :wT=j=$LnU22ɩ>HVUlT/TQʍ*}[S-6 @knu2*"H6esaI A_ʷXلQNVG94IBh$,ȓշ6Xڇ /'}gwd,#eߴʱ'@Uד)޴ H+d,3h鶴Z=V%UuN띴 k|VJJy*V)0@(>Ib U%q&BgS`$$XIΩ9 $4ߕ=``lnK_8MvN|_&ث_nV]'#9KA(ˀ=M;O|>f.m M[5q5i r"8QYX2}6f#L^|7g.biȟ|tRf7޹-μiPkauf CMZ#a[7۽?݃u.nhlrX%Fr x]pN c0]Q 골+YT4*ǂO/O @%DRfur.AV_٨iM(@QQ0{! F#jVbwbIZrafs*lUeUT4c/ E-YEO,kmEu=fktMK=G;J7YbMօkZeT.E9P"Bw*`Q᫆~ bG1E ʌ:| ~:f|3~7y|X:C&͸frl܌{tbZh+aYݻ2wchjj1{nۂ* Qr5.m5k2wO&KKD qȼñuBRj8 =Ϟ}{m1||96_3S="d-RXOV)A7݀Ms:Vis}MheP={>\8T-BE\@i4.!hJuL+**Wɤ60Й|(m'![k,= ([P~Ȩ@ye +\&cmlIfXPKGe )6&JkT1Zpx= :<-1$zfwv#WBj Sut<\IFWcabΊ 7kmZcU?.y72 %MOa4.T~]FI,jjgBł]Ӷ;`O/;7܏%Dn¿m;>x=neka'onՆcǴ (6mq(Qi2Ԛ mjSQV?SD-W Dڰ9I}%ZI?mE"}Ӯ|B(NaP*5F4kwmkkdg\WYsHP6$Ҙz=sI$H)a(kU *Q44ŚH1c [F>!Y[?Z_ND zӷiAXzYSσu|-|E饳l:eT!Xk3}g8|RkhZ{?I?[D?.v_΢;apo<IZĆ/jyt U/_3y hc4zC=}o8{PoLt{tдU{.ۀ?zKeP8mГjAm1 T+mdP^VTAoSU`7+SR@ 6;@r/LH$5|٘x_nGwSڃ5|z4L[jhbv \nɠF rc}pi In 9֕eIAiCk%EzJg bv^$[Iinx#MB*)m1E;V/힗pCi*DIk&c<Υ:R\ hO}0}o@úX[7[mB3_vc/ B<1׍-mwo<4ʁll=l|м%\cv whBxs-7&lM1J%F Zvw.sirASjـx2A ۷W] AaN}m1ʵz:&ܻz1xy}q9a˚2(W,\37@&k~Ze`+crfYd6NrMh>Љk>"6&{C v^Q*U-z:6ݲ$&C7i9K*Vbͳ5{Z0Iu#\AWum_`ﳨA9y!#Cuuf^Oک^Rm]Ee{0BohP 4F>erzTA@>?9̋ OGPDd0׿$G4;(t!^yQEs,?23Yw{q0pӧ OT@0g|_fd,@d [ 2" ƒ!8,Z|'sPW;kc0L}2z~xr S=0 m̽Xc=U!KYf <ʍظʆZ̮Ur§FsA *ypִeXscc`4ʪ4-57|si}7Ūy*V-BBK{$_7BiHTK>q"~i+$i'_?֙"e߲仹ÈłsDQXWШ-tFY) bYL&3) 2kO212=8M.  "- pȜi kS^rပsAL2Q|:g23]ɔM %T7h0 a0R\$LE[7I2q,3>fW*6dTJcIc9M`/yNdmV-{'ؘ+&IX+a[3xglkj=P ^,+oDuł:u3ƕ529>-f>7ihhf4 qem}sh=c$liֈ|vkjOڳh7@,?D#Fzbqc UF~'_ZeTؕ ChX>lL_ZpE=Eu5E u/Ta~i}ǟX1 y|̞+x8N8qA8T d0^&BerT~㍿&E U@;FGѓ1WhFڷ؀X()rjJJEomRh%)ۤÖzK;S .GFcZF<SfMrG-cuX>]sL, +NaHy,VlxHaͷh5iz{3V*#ϴ [rks_&s~M}y 6 ښUUx,%Ȯ*b>M{6\#,$VNffҥi=h S3ՓQΘz>o!XR;24(1>.2oT/CYnwIl%vPL3::ꭩ@*%J 'jd>TbZj {Ulk$M1ayL )gx(*kf7*uNk G˘[#)W  nY4X=%+VQf4eaW6gQʞA52۲yV';WR>TCIV\lTWf&@"NH"Km?*J%v(cbP3\`螵KKQ-fȊ6)(xR!ĪݑجeeU8!TĆb1Fd0%!cU}#{HTjPHSq49 Y ro~5y*j\ľZ̪у]‘E`%TM@!u8pĠ~ܝ*-a>Z* 9lդ/N9ثsF=k|\a&Cpygbv\>;!38 c 6z V|;yF- ̺YRdݟCP̄!G(xKVnu 2@9V̙WFA'c37`^_|ޣaϘlC=w ˁ,j"sa_ a8FC73\A^*x ;+N=!+AGa{sa~%N:ڵ{Wl>,>*G =7̌/;Wgl3`(z8go}?s*؆E7Av!tЩ d71|Ͱt)IRb5uDNG~?G#bĨp'R-7CסcPK=MC#G]sWEw6l vaCpph1WǪ3L65h_zH:86ڀ!X^jp++'JG_lDɄ0h :@ $B$ȜLm UM6zWg>-6!k3i RV@%4ѫ )B#(l /l=!ikMMIJC 4ϧ5W{L:̐= JIAD-!kEeiz_} y|\ЂkppcN ! "P@aU8tY @A~| ?xy. X>=\|0=W480.L ~f})E@E9bP=/q!q];B @K'{G+/.8^(~Y DDA@X+<9\|} 8[ťGib~h+ ;w<#)`gߧA&@?+1#YW=ISQg7FOW=V"*f[gg/_qg]/  W!$0$џ^Ǐ?G -СEEn\r*8 ׇ(Uҫ\Cμ/Qּ9lޔD);{}ѻ/~l~4{8Gs]o|o'L3ަܬ/eB}Ǎf'X[+yͧ1dNt؈@atUW?ДF;p5.~ Lg̘,uNyϧo9.}?if8}oW;7?O'L?}x Uy|زyOL6ÂE NF@bV77&?3(" f4;lCvfA1;G݈z]g"}+Z}u8îx9QX?O&_lv!V|sX0o;h31> ]`= c'r^Vsј,=˷=/`2.>i$^;rY W~Kq1%?b Wy5q;͏YoţFNP-|iA`ÏcxĈۡÚs+87]Y'Z[zӇo*ݩ>ˡ,M7@]v?}-3#&W~ov5Xn'tO;H0+dW<0qc[6@vJvi퇝,tܢܒ]p"?5Fv=;w^7 }V4!Z6OoT˜Czλͭq++EB𙷾y[ YѾIɅlxlN)ۗ_̣z2МO=hdSlu?U#>CpOxksNNa0\1yޫ)qM'q[" \fʹAC4}:Um'އ&;C-ZsEرg[7شz2Va\ѮҊpͶoɴv,XD͚?6m&[= V[]1ZfS XIrzR H,M]$[.{E'qn960rLy48)^;J`N^\Ee"rMa J+1B[׆_hZ6o*h8_eY6$pF (ه)DcRz\VИr~jt>Y靋MXkI}/ڼ5T1$^^AeyfO܀ޅ;'võX;=<:zn%=N +2sCУsC"@<3STz Cnܾ ҃p_Aϖ66xщ\Xkgl ?gmuos}aҼ!mcN8ۧx14[0ʮ]A; /pFSU_ijQ٬5cwi_+:u%Ѧ˗/ЊAcӟ}\O@\OJ ,|shYхU}[.<CU1r< 7e2ȭ 6Qhs\n8|pp4/_~X:u娮7r6%xAA9*+*(ZOpDp)K Դܜ7L W?Wȯ]_ 27pͳKqś n!]*“ވ:f  9/]~놛\N?4 L9*wN潆]_L;~RC,? >]cN[*ăny8!mZ vn8uKQ`AVlVzIahndilWw( Y 5E1a>7J;i} F6jZ>@D[1 Q*V>CWīefidY @hED ?mcs*{gR}k5ZGx|6mtE}p7&97`h[.瞳=m( uYuu1J-6oqʺ*|--5ln%P௕Լ2(ʟ^EWB,o)~~(kDtvO{)#`<`<;M ]o?BwӶ;wѠ/2hV;=wnJO?]?1к8oԥ@J̮dž&p?f6jF2)t!b{"d!G+w ]fCPv6\[*T:s9 ;1quBÏowЎ3o>K\ sn)w\zڅGs8 )i +**_OM]-?aTvb44آL#7]턮=@/X9NtE8u3ߖӨ7Ϲf@޿S0} QYv <6vOZ+ċq {`uKyC{К/A_W{scg_/AK<IPMi7wH&D֫ [aV2ŭ'()MHj[r F7fPl,\x.kmZ"w,y~l6,tx*3|qՏ/ٮ ^TFsCepEWbUmelNG]W>?~&4.~WQx{OŽw%Y9 .VT 몱v]5%9:4kwƢV#մa2h^DbWV#;ᙧ^7A/e2׭@ƥKcEخܗ@n96ǦMB1un {2-;Vwe:.QjXlW mӷnM ۷\ < wa|6}mMn9MQeL#wx̣Ca!+:^Ƨc_1[5 +e ѨpV[gKC 8|$__,,Co3~ >|!!gwÖ,L1}krc~.?sxdnq7Ce&@"A&mE֮IAApzZ5YㅯukhZs| 2h##8pM֮kPRC]Q>kj;'0't+l6ZAe*CDYUk֡ΉGǞ_k!p#`cQ`W u( ,?q8j&(TM ZSC0r*^-ZBWš8|8sy;]8Zp}dIv}XO'̖7KPNO IҪu;9c,S];eUĄUqCѪ֮EUժޟ챕;=v p.FhuʢOgjءcyqnr/'s8?R\8:^sZһ"\~Vmu*Flxp#q'ĵcnpᢇ֢׷cZq~|4k;nO_}>=÷9oepcWǵ-^CJ#) W1㿞7Ygc=wp{{NڟIK? K@_8 Xf&眓HAAE &Y*bU9\%"$"HpL3{=8gUju㧸i<3"–禣}P~t! emg4·OMơ-ϑkgoƸc@Ao߉쨚⋋pѾ<0h7e'WNs{EKpa=.WFFI9꾻С?۾=/4R6x˷RaC\u|#ΓpA:l c=z 0jƣlY:to陯G2D]/y]n|o߅Z^  "RGr5;'d#Jl{,s1V.9)01=}KU!TʊKQp-.{HJ ~ƤG 8!CqW虫H98 `#('Ƣ,5ͧ$U/̿v]Թ"C1URLF/{i=J{$nҭ S2VSu*RC 21a2E(}ʲ*jv"v>b$mX[G8(ضs)$@T]N;~ߟcGa T *[Ͽ/ŭ3NVx_x[0-ԴMKdGm=*4,|V 'uC7Ӌ?m[Ъ[uϾܢv=8deVo5NSRh Lꤐ-S q⠞Qc<|Pwt(TO1r:p:)@:Mj`Seش qAewڴۿQN@ѿ_;⯟gO>o笧<'@chԈس;ny5d8P׻^ZMqҠ>\9B̧O?n?ɻp$.ʷ884I;P>pBz: sa]jW1h8yPzRTX-^~#R95v]Z]K-a5Y灥x7͕OzX1ʓaP` hgMToM}m؃Ow ,di4q2[%QijA؏ųSQZpsѢ_sV'1j!8| xѿX}*7Ce ݨu(~[͛G GN' !ax7PР-ujP Sc{ghg8[wَB2 #ZAEsj}`ʤQ (ٷ՚֠m+chE]fC[H0L :wGr[0{jܾ!r74c^\8OUuɲ({q5ُ?~s{Op"f; 9S|"X. C[=R m\a5qЁ(Yv=?9E;0kW N|- thjaiCѬ|d.>>NU.Zm[n ?V,-s%KOhVZLp)Yg>ݓS܃0gRڰuU=hώj7hJEۻiP|e[bv͔qP!7nvTXO vUKS_A5=-r,.f[ ✮rFY.,!ه)v Vu\; 8p؆M0 A~1ZxɋP!_a>>G4FU,*-hiGg~s#ua1%*׹˶u XrYAy,6|ƿwEsdl!ymqLq])+AǂQeYK@[@+ߦ 0ͯSt]W|;R%p 1s͇l93{%39o_̒-??D:+*B ؾzwYvdAS;5[{j+*범I=MDgpʋG3$_:<~T폃ĵ˴'&x͏1&bHpw4NW 2]v'8xP[L5.Bܺխa#؈S`?8Ș?Iovr"+")Ax϶?aOV}ײ:Y.,$f欓Ŷm;ЭbԪ]7 d ,"f8NL6lC6o[8zfm,bu8nHm[dYN6 7.Qʶٲ|8.,f ./=Kxk}^ .e.mNĮÎ ض Olۆ ^f炤?6夫ٻP-S6Y>G,Y6ٖV8y]ݏqqb?.=mǿl| :.@/Ub>D'%; V^N%FȲSm0^LA+ VT,?KPYJ[r{J箪Ƃ*-_eSRI+e> vL%oP `Sl-"^"p5xEڶSrL9 ekmjy1/K,*9,La!m LTeQ$ S p!NGNj6DElp$ӎ +Zv*xVqzk*HkeȲ%1B*9Lv:?&dcMdٜESl,c9ܜIۯImvN1㩰HڼRi:m+# tyCԁPO/X'V͊?R_ (TZht8wl;_I`}B`TK(߯ةxD, nRSض$|54l9H&gRYVpDLṕYDŽ@DW nH(@pI1Aw{!+VLEB'N'j?o.cZ M!꦳5cHi]" MRBUsRPJ3ڐI0+IĊN<X$q 4Oӧxz7M-4Ch /{zʟ MPK> FC>2](10%0t%".Az f! ƂAAڏ0 nD.J! K]RXýfƆu,$2 4(uIJ*b=+q|,ˈJW*Rl\yVYQDRY148^ueY8v󥵫i0h=O.7u_X02l*'+#T8!*)g8R3Ta5)3 @ǘ#B,tgowt-6 #c e7U;J2U $7eF QN*̥Y,w '\g"مnlt"i磥,}̾ϺCX8ٯ6.Hu*!e1^^t\YkwuȄBqlzAț ;V&+Hod&?Vmx4_*v w/eBR)-F8I{QKa ai8P b5%J 3mb UZB;YW;XAn(}aaS`uBYݜIj*4$ncl*Gsnnc q3צ2}G $, K\X uT-& @^G:ȑ_zV(b5_ IkN>YgE#,"%( :UitDjڤ 0MP|M՘!;TI %(<Ɣ$1nF.w"b"ZS;ihuY? l&qM0ΆbA$\kq1'2-=hy2m$cHA3 Y12(kD?,Z>fS @\ltj6K!eUKs11j04Ԃ^*eJQXM((e4AZߑ{>+d?Gz,X{iMhǗ5XBk_s]39(yF@[T}xۑ3?*sĥ)&[GL^>hyTq ,JҼGT*{$4'%^H8r1q?KFmΐ@ӮKYgD7e]>DiIRuKH&CdwZu1 **{b-e$4gĎ J}((_>)RF 51~$9-1oHT 2SN3;'a1KeR8:Kڦjg0io!V`0'YJ:C@̘.b8+HGkҿuYȘ·)7dpM_2 R_KX fŹ8&%eL,%Ћ}BJHRȉn,sUݓBu~(DXMsrbGa} joHS;-UfEv4 |1嘊Xd(}c]lazao丹:LRuŌ)X^];8IktWVsg66C#,XBX'[rLƅp:`҅ 4lZ}d|BD{W ^La5 Uȑ=L-cng>uTtjv1x h:CB.ureh B wRK2FɄ!gN;& )[K%cIqf8@sF0@B:s!cibU]qPJ^R_qIHQư)bat a4I3ZUOVM7(%+j³bZ*^ja V0(%j8|'16ʄU0CÖ="Q֬i-/t w:v1 Lvl6޴►}ƴ_J1- R Ly:\Jm|HJ(IbB<;A,JjiX' $XaJt pT$uQX+$gkJjʈ$3$g3${؄dC%jXG%;$}^U.ŰB?A9R1w&h6].B f,-Ky*Ss[0SZȞE|1RjG;h᥂U{W?% {)ѭi9>D ~:%VeCIs xu$[]h׈Ġ)wI5uteMG`UԄF=E IJ$! R3SLl8К0?BQY٠-:cҽ%0$H1 z3ʳaEb A'%"'Q1baZȒ)@԰~Eq|6?% Jp޴2ݬ3@Վ )4eAuJMwԗ0)pZ)']NZj3r&U5.$q  ߹vݩcʨ[*GuӥwHu ?*V` 6eSS邽r#@l.È,rYVB#XhK6B$Ȗ[f4U9A2ߐ4⢦%aĂ\խ3@jetK:&R1-UĤ5̞T0R"A厂B糵`$cfՊkC tPEi} +IMeC.%;HPJtjNpJ7Vpl(.{iM$m'At[F&O$6sLjKW#* Y8cU2TX}IPuA_g`xuj^[RUnsjjV.EӦH?U%tA헄g!Kb-)NGlHRU* !)5UȪ*7SZWmǣS&ͺ *@KU4թYm >3}HUUEbZVR$$f#Bn\+?T5YPAYXSʲ.GX_]F.qE|A_A꺖|pPw@`,}Y.P{PXmPU7iF x w$uuDzd KH XI%@UBWGwQW㼸9S %*I$wXbI:Mie5i 0jUO  {sTᦨ-U@ C ("`qЇldY8n e2o~[٘>{)vQwmųǷ†K z%Ez"0 ~ef{2%%TĻ8{3 0٘8 ~f9~]bp q\ׄ.+K7&|{k а˷iܸp^@WagbyQ{#̙i3E` 86*d.3Iv͍ eٌCr0o\E.Y)>?[N_s1ml)אE#atg}kHXJm0CflַLo;[p7..؆_]E)z;x- fB16C$_&7d\cK7GVx}~@6 ascн23P?6%%d7GWsٲk6lEQ8?xo5m:~ް;oDLnb.X,)? DÛTĴ4ZQjt7Dx Kc )$jeWڏuA@|n H;I2,\HDGL OD#tLq%i~`>]<*%$.-Cu,IGJPu+\gY-e8p\bo\6Ri+JKxq/9.bn{]Y .|K`ٟGpsM 0)Y[-Q#gمK,[k@+PN=`Y6,;>-؍wb'j~(~ѡ2^5Fcsƿp~Je4OW7b  L9G2Y,;E62K[_>]8ӶW㊅;a$~H.`qÍ/˱#ؽn),ImS(CEXeo.,˂B:.,b2Ř<*M3% |ųAM<w]r-؛{z tY% nK X|+Plu e#Na6q郹xmhmv!o.FIx1_Vh=ة4Bu}dEɲAկ܄KV?>aٳ\zѩ: os;p'?rwk|- Nԡ^ ”uKZ?e`Hqi6NIM~Ex/+Ie;ղؓ1MJ"O ZZ>>^r 0[u T ,C_EV[;,c ;\^t%Gҕlsgo)/ӄBu?4>t r:d6h2pأO ^_ oFw2]-[>*=|tAdq6hF̦\>"4P 2\&"", xK褓Cޑ9o_9N;j-;z+99.ëB= 0pd*Zy2\=U|ړtWҿeY }1#/ , [m 7 J_v>{nvƂ h{М') bTV` RuLq,¾_?]_G7\}} ku8gh^eY@fz)Ȳ-t G1|tν/zě?/ŔYPVS|3g1-^3MX*$dH%\.oKP 2q)>|^=Wx;^+$t\:Kzn7S(T{@diD #JYGĭc.wOƇ,FOSfm#,"y̡tڨYdvzs8'i_辡aYѫ˼nKU lC{1˝/!D%ܥu$h&Y8B,ֽtְtG@E42sC/,($f?u- 9n -fQi\R+ԙ?1Xu8ud`6nڍ\˟E7=݃o} O-wO@Ͻ럦kxh_Hu/Pm# 'xq~;/plz:yh6J`n9,'j@g\?75=cBz'^tjU6mbb Ӻ1@$Z &# +:82 jr&νRXRp{cgоעm8L8.;5`p͹8S5O3k61ͫѦuc?`ԳE(Ss +=3IeH0V|XT\gOukOgL'lqNØxL8p!]N~zΛqbJQsƠ=po5Z|9QnĽ;1(k[T{ɯӊ p\=|Xo}7KԮ~D='[欱ƳмV- `,&y4q֝u#ź([䕸-8}ܽW@N;\w=8߱jsԦ"cqEr̝@1[b p\W;1¹Pr%nblSL^..3 ,4&X u%).;-HFIڟ$!YZ# ě Y3#*+bᒟI4Ğ3<8E&b˰9u #TBmI,&w/. : 6|T(;4Y7߃:VC5+`ټ@E]_uy#qfC,y{w&[Pٻ}6gAJ563/P tIg1߼ܗU̩\,0~yp=nzs1zCxl( ^֖6M*a>F'9TͪsKFQ\flPm86g`17݇ծ XNafFQ,0(|ZZ;xn>7g8RpQIxsʯ^ ,7mّOۚ+Um~CsѸ"ݼݭ jl=C—qFUPo>@Y7Fȶ,2deX?aaz _C#0[ѣNS6f> 2~?ًK{8B~f}\~ƻ@֤ܶWi'ڷ@ {b_(ux!f\ ]ϯŵwv , mT|dsgٮ^;︐[Vn&އugw3/ގo'JZ)аrn}=UlݳŪ.@ǑwQ/>}|O) QZcZc}_6wl7x0~_w1U^}3 [i'u*ks[~ܲ\!ut`.p歹ϐ>\rUt<~Mk@mS{Vji܎Wl{._!xM{Ǿ5U +K>o`*Z}[CmqJܣc.ޑ_]ܼF{ʀb_)HYػCh Y'E֟R g Rz_Ė%v-*qlcͿYdā5؋&uYdynŵρE iob jKoЕqfMq7mE֏6k*/JVfi˂;4?pΟ1`K< z2Ա(iN"K`[mDM{ٰ-sexʳ0S7i_{JS ©ҐVTK*ҮH~k{=;iZLXLYrz E& 8tO\ZEz?PB{;kAQvsM.gM-PA^0&u.~ 41qI;j:e.~BW\&4o JԄ-ea%䤫RZe{2hڹZܲڒO"r8ܤQyg`/ap!Prn.M')&$8'uV el rP±RĜETP9&}f3j[?ǥG2fPqf˖2G=!l*_ou/5=yN+PN$γҿH)~FYr2TBXp2aڶs,yq4=;;q){ĻIC_LŐcav? ʧBo}Og|AW2`1Pe:v@Y(Q0 Yi2vV΂JQ aylu{7S}(:t p;C*8kdL'ely5~ۍ/شE ,vt:dH-:6W:5C;.qܗm.@(8POmzƸhP 8܂ؖ-]Uiȸ1ypSMS4kW (S0dHqL>J# D6Bx6+U2? FاtaR+@hW&qOiW. &ADiMORVx l*4V?UH)"J !"dP1XBP2O\Eƴ1M̗h0:'XiA%j%`Iq"M:bmjm?nc4U.=ecz''Sj`{czoXiM~W9ԨQjh/-q\ [ԪQҁLWFڲ*_,, ̻ҡB*]"%)&U+ *i wQh9M_YPUYr(<1q=x1aت#qؾ1- =*WiFܩ6c$P6'eSuKK^aPW*F EJbjbtLSг^| 5KU,e2~ i"ƸȆ` #u`bCTК5ʝP~C-gP6MRdsm֧/޵Gk/M?OD[?cOeLtbsōPUb,v)z &.]dܲhT&׮Ma֭^՜]XMxض /}{``Xp l֕G:lԩ:\} b f})сAcsZTqj%Xj+YuZ}/bX4Df˨EAt\k@}[vDfͩQ([5m\eJK$7r,SMoyv7aѺCTaxneKjpSoۙ?эiB^W@]{< &=}VܳEQ#T.2u[&t;Ժm]ey*JWlѽt8Q I*Iρy"4$ѠBUm"!B"]W6t᪇gXH)NEJ b@@ )$Z\Ϲt/󣗏&犮<锩r.\vܵ4|Lx)wpY0RiT._Lw> *q;5!4gx-iE߼#=5?xrihU*D2WK!b20 ki]GӨ_Zk@W*/1v^w88vμע9;A-iT"~qXb\x?p~_t#ξlz{щ'F@iH[آN1$VW"n1G%Çr2Eطw`w^@o]?i>H7wv؃/uhU F }]|}[WEgv{~￘Mk =sZ 8(V3s_; 8VuE# `(>U.m>u7B?it9 ^};_^*C;Gfq͝pPgc,|yz8hua`#p߷pWby{i!|kJ]ҏ w=ԨvhtSf~qă8v~HiC01o7Kߢ3'g&{ u,q 0`}{HrZz_*?߼##KݻQTQ_]{pIξ`w11}V;-+PT~>8t/8cg(k'҅Wcܫ;{|SM0w[t+wǸg/KMOAz73butpݲZR+8D u 0'#Bg+ AI87{C{?/qUC @&^FpRGo1QO'?Teʲت$~2I>+N`04&,ip(´)^!E0wID`HacΠ`gP i~GNL/ݣ{ q([ūjf>U8E{kغ'^x&n]*`a28rXt=+j;mc:_FiQGU6o8xx( _: *¯m>WqLj {_fᕗ^NJ&8{lY4vTvE%BSFG]7g.8P'6 ݛV*Q碵 0oɯ8\N;{:7 m3qy7TfSpRJX=wVMrxھ]f_{uVfTv"KЭowTOРM7oR Эw'i=Ϙm>'an>`լШ)hSP@ R cNSS@'?! ysi 'tlG]Ыmdtn)}AѷW+":酺emh6DSFZ|7c%ӀZ *̯ůٳ+jm8?hw?(Zj`׆6u*f;BgܚsAآrлO;iiaCCYN ul G+ڱзwsR};f)o[: a98PD<4i g$F6] CZ <:l:84Y^Y.GIӡxSEM`ᬟbw(F@նѩa,/HShPhk$܅N_zCn.E9xw 4wЪGnP J5^ 2&90ЮJ I TEKq{im ~ۋeAQ¹J2T7*nKhTUqM1ס ʻ^VZKs$[I2&It_tω;{v uPAS*:`}Hۄr+* ̀СBo :P"6t혫ܗJ2>U¿Oʅ#B{R"ZzkE%ӛt%~׍\t"[ w:?t0{'1B'0x&6=Ħr;@Vu1G =Bi3 Pf_'R]B%VBwMf~Es4bY\ؒR]xH`%Bs  HM>14Δd$Cb5Z`# Ƅ$iu*;$(M}2*ѕ_nxڽu'6߀iBfXEHa!\ᬓ!v޶m7SZk"iL$TNRN4N^ݮB#amݶk] EM9*η8@@`TE, Y%T-73f5an)j0iP:cvT Gm(nۼYgUעjqY"x #NaԳ湷Z? Z_-0uvt'ngO| d[ꚰ89^ڼ8Ķ4F :AνDG2@%fX2F3ʅ#z"B0?a5]08(@82@hj!q X;̀oh^]QlY`;ݪG)jo5f\`eS3[h  jNm¦rڄ  4lnAi6[I\i)Uj#.БTLa @͌l)BC`PѾXȹK:ywkv ]̀rgMw$]FC@"l ?`j Y/Бi.8i6j4XQ@ f8.@\ѱ$s2Za [>cIc\U\tkSm]:fCfss|<[\_xs+.|X M^H! @3:96ht.Lmp9&{9JB_olF"  [o Skzꚗ,}Z-74AM.up8i^_Ta^8ek?R/kX :{"͗|xKRʑVl=|_}P=WJf VW捩dNUpG Չ2+AA)7LT:_OWβ*<pm Ȩquoy^wd9=ETn5H92 {HuE4弪@_T_߿j%צ)">m IX obPXWs+/ߋ *enX"T}ǚ'WV|}GTd飺X<6p,׺nU k:kxM ().AJдqEpb7Er\nHv'ܮ9AsBo#wXQI֊ŎҔ<2U2Kh.,c\E=E=) c*Zto 2}\"-cq=GBz3ԘYaTx\J?Ǽ{NY5\s;~B@/>E  .}llRguUgؕc}4*9ure! πS'N]g*ef0y"&ƈ5wg@k&9u/nf#VgYU h=RDS$8fNR韤gAfX Zlxm‘gz 6ƩLSdǴ ׺))3鈲 Ebm諕cOС/G\MU?V2?,z jNE}$aub}̨.T_/*@Y,3t7^3#mmSx/m0[H ǺBo#.N) `ucތ#P3}'G[Iqsf,sՔ!ZΈݛ7ah]EL#Uh4oBY$tvC/*P]Åp=9a[վXbh ΡBiqvjr;Z{!لUbh:q (NXkvX #樞.ƶMx-"zsMJPhB +e@tKD M{" x.br{&.%/-bڍ}ZH@tq_3v)@hl kK PBI֋m+u 2>ID  M:lYDl{Q "*PߠT,_"6FtB"(ڪqRT]aΜnh oy4\Y v'XT6م׵# YRVƼb~+~k|wIJr=LЏ9e|u3!fsRf 柗p]^a=>萝>s81 FɎxq~ղ0 .d ff^o4:noW3+K:{q} fsPqs^GH槳P2,xq_5X&pPaeݛ6kvRÙۏ Y0>V6f5Iy8w3anovt[80?EW<{ RX2YhwMeMNp4v<7SN׮杣3^<ǬG[=α:McfP'rڳs-A.´$9Z|ëRo(%s+ =~)?}RSxÛS`$RߝsBtc8x8>RW[*82/6v9r. ^K07/5{ҡ;,:캶?(7ʜA|ږϾ9?U'iԽQϥsנIz*fr`Iofo6P\WoĔ"*ekxkL)lKO9gfRN d۹sNG0)`1p]5YzVh3hKNι2)}s@N,e3I1O7L-~Y~,ێ]+.$$wbDl!](9l }sd2;V6̚5rzR$'Oyq7)ٴBNwJr٩qg?=LS'*H˖w|rc gRd.#Q Ll!%7$FIʧ0/h'Yx\q7kIrocѷ4>ølf䞾d~p͕z8{db~}$k3:_%Iy⟷KY+'Gss+IR:u\TG8)>c$罫c\q1䷷KtWi!oo]k/t8)Rvʹ]"ɣ܈>Zd[t36\v-}\6䶷,_XJRkeAsydWe|x:_(%*?*1LeͷdߙD~S{dc(]dXMmEݒ*q ^jֶ$?3Irf2"n"TQo?q>#Rzn$)׿|HJQHW6$?{̹;Iyio$˨y$p\Lg$ctC]]5{/4/֦ƥ=FWK12骿CiK29"on҃ 9|-%)/ϕ|o;%YuqGH=+YU(yTt\ՙes[Rn*"I{5xu<#c's3I,t>>HEٮ|F]+e?H?=ԏQٷ7Rė̋%oA{w_y$|̈8>A_ݜ'?o:v+SÓ8opK V)^|ydO~Շv{9P5Dβm:yc/(f} $Ik;^.m;8%$)5MF$N[Iro̊=ZW'0"jkp̷A7ʏ4EIJOoGzqIC.&k|T9UY-<5=20mTdiyf&MV=KH?K[ix6VsnHsb̶Hu_6ڀHU-6R#+6db c%-~>Hwc/l:؀HDX.~\Dz|(A6 Ұ+VɝH']K&iCtuKBM?u\< +N&+cg.l*S۰|fNȽ|6ka&zUZM~Sf!dUbk[  4jȝg {6a(̑W`뱻۱rưXW"zjl=:R%Dĥu퐆-LV 6c r -YٜʜeK"llf袕Xd: âAd8*%}ry&}}#Ao WnB*`>7ƅpY\up 0~  W` mhOYyi,\Հ!W_H=cfdٹJ&Vk޲*scѮLf"; #ObՊ#pșz6sɡ^r(d܈ȃXP+)Ei^lގUS1c@@kѷq*m+Uecg#f+mmvoR-ћz˗70yF@bKt0iAUEnmbg`q7mc94,i*l?1b;fy\с !U ˅"t4 0n[xI߻TXD㋋-mH*PͶ4wCȉO8?HچZpIwX_.Ğ0xy<ɑ-khEmC-ڻ'}k(+oφ#)m /d.BbhjچzW<V>²\ 84d4ޑ&Nih`H|,}{7F-'bDf&?oE+{,T5^`DRz^Ʋ4k/܍NC<]bݟ2wue 18|spNiF t'p9َ/0Ӣrƣ< Reտ9oV"d}}mϣ9:AG>ȢKohdcc-.v.Gº6Ԣ[Qt#Yچ:{$%"ր&%AQϓĂ󣚆F&W#w= =q5-6+LjlATRwn{jNxG#b~ Z߾Wy_DU8vtJ׽vtK¯/ek^E}8F]&]z_c :!)<71S_[I݈f]jm(̷7 &+xƱ,Cz3g|`tgT] 5 X  IDAT݈Ԟ4D2?\o@c}5ǰ3_)]hhFkC /D!؇UT t:+ >v8oI~a쪈M&"D'U^ Z(M*rt*Slr<,65Tm;3@PZ+A=ņ>ɃhĂFV%M оe@Ui'1͑](^x)<:!/[0Z'1$"jZC" 6"6ǯ,j."28?>ٸE{XH.Ջ+rzBA$} _$2Y'AbM&>~Z t{w1ahiA/7ZjlFxM BD@Cu&> nF"RH -ѼYl"R@CxQ_]|tՈ Z$p6}ox)A $ EtzaV_wBv:\6 CqMv!BC½^Ph$Zj)UBC RX ",$a!a5ՈYӷ1{[EXH !yO]ZQ]$(ЬA3*C".6 ~̓sz3J8tq t*  5M"o=K5h>>{Z+h y&tn-(䍠ϲȗc""6Q"x{:tN2HQ Q/|7o$jPZD݅nJEkUBD(/b/xB\# ބxqϛ_hj YhCt0 q {CtGMm+B"\3 ( mh4T' v!i]GO~9 -(X_E{qx0##U@HH8CE`K-?}w15YM6Zb$40) '@"UqH=7ty0D+ܣJކKm?cj0v39b/ {1z#6ucNNslCqt^פ<]܆uÑ_PaGZ $6mƆ#kE$25MDl]+ND^~.5SR{߀U (ݫ74IAclE>R%,477bw983ׯEuB!St{;&p▥<5%1ضf#S;4mZ(MŊUؚї]͍cK.@ijO_2 s{ڥ=f6~ЪΎK*$.ʽKVKV% 14yUz؅p2CYK#.g&5sᦳYO+݄2I*~Imu3rP| !0@,J.b+C~I,ш{VwhAo5Q\Ի3QuםGR~̴oÒ!*HwU :?\ 앍CXS{ +j蚂lml#wj7qMCWgES!wcn2zX!@L:Zcdau.F+O͵(tҝ2:VQdPEG*MJU]zoAlv=l5hq*qbB/)UPrz*NJ~zKɦE2HqaIluOʜUo'4# 9|#moll,J,/"߶-sbY7ċ}$)Wu%3s8w<> /u.y}G>ɱrJK:G 7:$/d|(>9H78P6a3s>(%p+@:~@P4s}Sxj~to?&N3˒dy'p-M?})w&Lq;_yi$OyL~=qs2S89KlfY 9c+2e8kϗSy'?ķ}sz}U,]Ǥ08ᄅLN, 6~<D_ K:XjyD>{LHv790uOƯ菫WK%W?97 g\(~`9(^|˾?0PTx+εsVMz|Gyy [/\ se38!vl5Xx6q9*;S^\6.n4Fɹpxfq_3c9gCrpz厖_fBΙ&򆿮Qɂy 2bed~q >3sde7ylOG܀~?EDdguNmԤt򴃈c+qwyOcJb!~e̜p=TʿV:aI̟r?s<F^X@LZ8㠮;oɡ7=fʸj {xG I/qݶ#N%9W>0 sC[Sc8y yLr+-'?ǻe1aZj׿&$sڃQ2{P E?T,J`cOk{)Im<^U7:z_%֮ebj!}YN-L?ec׾7 |`ӜTQK6s2>}qO+[}e|'8:'K. 5p+-ث ۠K 2l 3bUDJ//y%ۗջU:eTL`VR1gŶ;nKoLRLվ nA|J5B%b;,jAK波{n^B_ƂJYTu@Oi{V?mGq'/!1H?Y Qu!gdDBNF.b]Iv.^}r )B s".99m$(3bzkTa/ۇ !QEmð(p PgddXx_6Ec'!6쾀yfApq;vcKسn)Vj'eN[]' Z.!Ġ/G]8c2+|"=. cĄ?Ml=^z;["+qBv)Dl0nNlwxsiwX@3@v $L?X)|OyJL|oa{bZV@ sڸ$ixꭷ0)-T?•cPk#Ng3%9SX_*}ҍ=!^vշ!u-xOs{bD,ZS&_&NV6I : I)c-B˛$s $aTYX Eƛ@@>JLm#bx_5;ymxD pOJ%P0wmAh;c'N=cy k} d ՠ匧S.49ԩ'zTGؐ1x Jcmi8Or;=|2 `͖p x9mr-E(=m_/\?݃)]g_`YE=Xr .;Py, NS0O43c=!%'FN3۱\4n;kP,;`c'\߶bgMwq=kba-{x7u%hJEJ쿐fD: vDpt !tTôy8; o@02?AzKغbt\_A.zH,g IJ$EbPoS[P7%4~)vow^/ԄPV**I;OLM"vxKYC0 9^ń9"h'^ 2Q vvebd187E'ONE'H0aȿiDD@ ;lH4(~^, &{l!aLYh̲HUeu35Lu.*p!ڨM짗%RᥝozG*jqNJiGڎUFB*Lt"Z*ȢqH<2eSU_l ,0t NHat#Z0Bn6Peu@@hB)u@ELB(YDyo ~({:w1t#6p8^wz-)$5jK9 JIi:dR&JH -iE 3 AӋ9.(j Q/$};CBRMS:ʔv;& 4mzga,AI R@ӌK V J!Ijͭ zb H8Y$uBH)BBhZ{kB#)y2kp紕nh0FexĎR@ rlM9ʝw̃:$u, 4$RJ@fBw>w^.½$bHe0Vn@: ɊSAZ((M 3=u]U: pYzP!*39.rbdJv Ic%$5 ]0rKѡ_&* ܮ 8nt>7Dso'Uq8nͽtx&-~йu5tOSjmkJ(R&IGq YO pȒD2_2qm>ntpSǸX UwMirh 7Gn(PC} -t< m.l5wL1ޯJ5ָΚ!gBA 3Emq]Sd0:ڜS, ;ǸdDU\ǺEu{Zciwռ臙[5>mD{% U:x:w)aل]J\pv^jov>}EeC!Zѭ{w<3.^7eNCUW٦#RdCs8z5\s53!FXh&6: w\3tNީ^:6fuœhpz\A5w1fF6C7q9+z}4ϱ 6{LĀXEK:HxN*#LЉ`3E\uyͰ3L@wʱChk2ʤ2ᢾuv>zzix' *J_fr|uBm:}ӻYFrQMBip) %=RVI:-2-胻^wj9)Ly0i7 fˎ s.= \~͡n9R?uԖKh5϶x*~PXbkL묊J5G̦^鸕X6VS%%7Yg[.<~ʾƉ~``p!;PC>e mVaOy1UOMx̐4{`5>:F1gZR@:VQX lQ0y?b+dl_j@V)"cQ>22/ 1fE_rc1lo勵re(r89~"*嗃_i5{6P>zV%Z9&*QS@VjHt Wp\ǒj=&kd"/^ga1lo~׹lT1+m黕,%181_7mV~vޛW-vx?6~^7exPsMǯ 0/ s9)/Cf}3}_oc+ d6Mxm,6M´[ȹ[T,^*mqM .[2֢j7JN|L 7z(P[|4oDPRZ-lΘU߽{;'dԼp /v^ulg,dSSK,37,?C S6: 'ҧvoe-q%fX͕zZ [(MWT-x{bA1f0&\37'ߋ{y fVyy " Yȓw•Vp#9BɚґiOIwf,9\/4RY r&8s7wCsS-+|vϔX3s\ G!)Ҋ:u^w䌻һG3/GVL:" >^J,^486Y)6lߏz@B0nh/\3ԘNBݑ}nrOkp^ԞQ]tkquW  '.6L!) (Nlل^HvH&4HEL 8aqfD3s(%Ե{]TVyFƢ[d.bϪi.[2c . lU{葂^hM4q{h>J="tA7bi*l=pA=RD0D/4:V@,pqiԯf.J[#o> %DP&vk~QzQIs)4 t+(V8NiҽTiS\G}S)H8˄97nn)P"p"\H9MÅ߶%Vpæزu"$0Dž/B]͞?"v#!-! v/bO BdVa1Arb3~+ )""koۖ+7`˖-܅Hمu޻J|`hD Mґ涳w;kQm놔QBt`ũmK.G]mbF4BRpѡ{*~h ](`pmfqZxD=cNV,ϫvCHF@ s6Ql];4K`ɆC"(6 lM@bX(CEPͩ{Y 7gxBt;fp&C tw5MMǰdB_nɈ p'9%DA,'Ti=n5f?~o1 EX8gVƥljP!H~~X0<ӎX8F¨f&G^X|h8p} FrmArB78H`ܒ+x- )qat[.\ӲH&$ @՞8H Rdz;֊*]/)\ky*#Uu2J8%T=azͤ%f96@P6/՞.b~v.̜R谳j}x ss9|`ftX뙝S2+w0Zuʭ-*f8?} ͛?M]}0+W‘CJg,?g{n"q"fN׻({G̒+݁$߿y,:Cd0TgO:?|p8rT'F3)?G,`fᐣG01#3k鸳)!Lđs5:zQ{ΝX0#e3{\qVZQKkyVVS MbZH+HEW>˃y}uy4f !y,UN24,ե#xQC_xd Á }z} YAcY5tJ9]c,>ɼOz2T-ΏN.R(ffWsl 쟛Ʋ#'3ugX΁#F 3|?L1|:d5׿vVrK|>x{Fol~2!tʛ}_>oMnx+jOs{ޟVBGXNǬ,eV5 u@pJҰQ1U3S|sJ!ocKޞI}j$)~8[FN&Jr!#J~^7ޙ.#qE-:U+Q^IRya̺I$%18\:gʿK'%~/NK\@٩Ay<_9kyϷz*$)?;N"k~N0` D"9(k°Y7kN}7kX_*fDD"A$ suOmߏ{Vs K9jU%3a{Sffu UzIjm=+j~~OkbfsUZtIbޡftn=re$Htu2pcI޹n0g AfV|U5 -bfL,P/^R̝F>HvI~[ԓ ?*?ܠLy$xr甞ѩp3uw씾[G]}6R?wtY_ƽ~_V>DL'X>HTE]-MM?_=<[^Xqj^^}lbfŽSTJϟ̊ר|35OT} ;IYm-gA׫}mALi:٘ky׸\U=)#3sʕm:YU~rKU=[U͇Ծ#UafVo/笴AaV̕j*fV_]:Wog|R-mnrqiWﭱñp!RMiy xbޠwl>?lQ>(^|Yq{<]GuK# vRfŧ^AiYj'3K}QMQxbf%TǑISHnJ1jjQJD? &Pwz/~Q13{L?t,!j[ߩC2e23^Fw>ŊyZ?GI>w)fOVV|E45'/T)gu̬Eij=[3qJBYEijY cI$yQŹeQC_s&HOiDtJQN$(wi%ythot9Ϧ/>z̹kHƨLU6gISa;A53[|Oirg%%v0;;f :n}۰7f4ΤfEw[8k&ahh9<9-ST|Iԡc't4#fMt4LB̝qMۨ`&&6s'Am |Ks4S=9s&q'ܥ'/D2!+;`/.ZCΟ= |Z]dt5w"e"PC%`횽{!Q<\<Țpiɔbs@>H]&-F*Ԡ7[oVCcD3wS^J]f&jv= sqkCW 1t"7U&}.m64qx[1v|+Q; rK /ChW؀M-Vn'p&R1s 6> Z{gUջۺ0djxj`#J( ky5ӖaZ@xLzdÚc2~ ;*o>7'(:|IWa SH@:o!z܎@_ag`( F3L]a׏@/7stCϣ7oT[P!5keIMk_~ f`JQ L{xl>M붢<[z p`BZ!uv f^KuHâY#Ԛu~N$\Q5Th`S:ZcdoЗLHp&b8@5V=_†JQs{`yT͡)$$YJ$%ժr}̿7U&m<.m$+7Ta TI5~/0f6WRM mA0Z(&xKStB{a@5bKйg߆;Io8/i9=wj>|}-[k|̝9Pu8f!F|_5wbciw;}|B ߋ/w2pklySz܀‰ ѿj'6mtߓ@MB)(VC@Wӻ|Vo ˞d)4Y vQ4Ruz}Ezlc$BY/TVEJ*ɫ${_ukg1";x F=0QC^dPMRPFַi@MJNS_7q~Buu97T.-GsK?*gug  M}ØI86pUM#*+ђٙ~#OŊI55-w쌺-a3TtMFE tuSCGO%e5m].!jZ-9!7xz4n)oGGdP qbN1e'& #ky2.AH ]ůxU./r{vpB fotK/|Ur9C@y1/a*F.yr9=pkPHʋ9G_wnS܄f.oK7OkrtUКumۡΝKgGx7pdܿ<5!7? Z];p>J.gpvwm5\{ @ *c#'y?^ݶA1WO?oZƢE2T'g#56xFg2WUNߺ2ԥ"g0dU\]]ƌ\ЁsñKkz@sf.v=Q??% /+QQ]ɪcg4n{G wKSkR5jjdFWyBtU 't¡׮b:InF'zuĎdگ}r:A}mBz l Ԕ5~Z'NV 2̣VDvj9+$$!  d],%%Srb2|Ue ӘҩNQrB 2$^{I:'N5& %D\QNio_;MEiS""~ T%'$RSyu{zU*%) XV™ЛM4*8$ġ=?@o>;*j.G%ePJl[$`WeV=/Gr| UѠ%/Gn})jHu 1i qSM4O UTXbpx!j(ᣔFy)0ﻘOR/K)1SlyQc2re6('lKQjPuуS~^w[-V54J Ԡ6 ? ˕#Qw4D$sL)zM1N?!jn;/e(&1=bHld,!Y{~`#}lG qWҾ t FOLC|]8!^Xo,,$:Y㧤JJL2/VwĞ Pu ۧ;hGOܫs{|n=* !}!C^u1)m}cUxxqql:d`j6#E w8Ƚ}Ĩa8xu@> NnX]{rvdv/A"Gz>ÿc\꜉!v`oQʚ΃t禯>ķI蝛l䆞%~\u 7`d?_Owv;^z`f>UP9԰n]Դngs~P!URf^Khd*Yx:OޡܟR-U ]Urnj[ԼՈKS'UK+qQmMM'׫+;/r_w\ջSZx[*ͤ6?u*^'O(fV_RP<r[G橼ڛ.G*xIz`&>K-5{z]ST^E'>izs8oݺ=ek $kj 76+V?6PuZ~B3#{__^5[;³/KgnC՟8wnubU4H൦-{ps/U/=OlT+͗LTy=&ֶ bްռoh8] b|o<յ3!*M{ԕ0nuu|п9ٗ,WWNͅg]i߳9j¥Pӓ{MIl ^=WMUR{qU}?jxQg5e-ⱅ3M`\m69߬I,(V 5c@:Orf!pup>7^_p֭?_zMjj<5WjC׶>D RW|:oOuUz_{ UW|;O͹Bx\|sej\q/|pji!a<)[!&t[4Fфdt7ŚХ{eY쐫99A 3`7ϧ)xme[mx5Kr1^ly/+M:&tmۭM-Ma:k+uޗHjқ*ɳ1eH{*TCf҄WNC.<$AQ> ]hJ E D>djߵM?=`AhDju&aHACihzv}׌I7O_4hB=g6%Ê-n[0>n$0i?I{hof!\ބF@3}} vM3%Y:T1e@Ki ȠӦsME&]~.ZSU-΢}WDtU3r Wvjи.䧎t( 7<(.  )i;7C@q]0m?y~[EgߏSi VB̙>Q6Ocϸi4Wg QQF7?wI>|ht~̣t+&vBOP€?z9>g-!C7QXP%yd`( Hо60>JE3o L1ꈉ'QĠm$3hR{>eP t.I=J1}7NEJHgΤy-kiw"1@ܽtkGk|/&Je;ImnuurgYk{iRI#l!̉~.ʈTj# JB,tp[$ DZS=|, ?!x@?QBbRpL>13A* P< tUWǟ| ^~FM^LzAY7$ U Ꮰ }PP u{kb8SdV G>gyO5(ტ!Zx  >' ]#D塕EA~X*XU}~8U8@ϩ*}03XR;v9V|)(q=C3<|w]c|>!0\ D+_h,BO$"DASR/ `ORL>/!8~*HLTP%bE'pvk",Ρ[u#f=j.R8Da9Aɲ=Cԅ1b}Oׯ3Kr|"]'HYcfyWhl{rvI1KA|t"{_E{ל$w:VbAR&C:hĽJKP١bv-:4^?Fp{V ^Pβ/°2 !bd횏$Q'"t8$3W1+f]H&jP}/tAjpBcX=p@$hL:!l$ԲXDgfA'#M+I#8 SitN8a:9 G[8ZB@ |ˑ>?, ZCc}NHGB^hĂ[6_+0rhD'O:Sq ssSh JW0XNy3b nm !%C{ajkQxtx\P+^B[I5WM6N5鍭>[_8#Rh:8F_ǧieؙb EM&g.w,=0rFW %kNh&‰q5mr~9Gj a I4/ Oޜ5 ZGkװ^?HI/M&$E_fʅ/–l>lO}#|#_ЮɟESNCB2Sg5Hǁa[V_xslݣH!?Ժ7G蚮w"+hAÛ_P ج$dЇ.Z0tZ9|+4Gt% ~̲~h s7Eb2E$ dE-,T鄠vʄZfAY-Z׎G2ȳIX2w♤ÝO,})t> r@EwY(043MMFTELdM\HҢJ-akKxH|o8ap\ό"ZCin WH3kdh,tn?֊lDCǥH8$is4޹0memBv:>+a=I|d Q.eXX[kuQG4#Fk_MQMCP7}u8A%]s·~o7Zu^Q#ɽHJlP?$QLعs~tx/2zGcn?u.(}*}tLAG6g%?`S; AJn9kCfSy ?$ğۖ)3pXg+"4BU TN`֣6o[>/}FO҉EyZdΕӠctF"Q>-a)m%X9JJ;'-t.|MG-,ee+QR:c!: L@b/ёO2[ZTޤԅfPWV-ԋT!ȓhL|\8k4H=S99".Fy˭T̐^tHf"#,DȒ9iv TM!a->B`@ܘYц 5]ęRQ_SIwty6)n:iКa( K4?.%$u4~Iw%'TC7m&C #H^%9Q-$EHɞɩ'qt n{BDo}z&Ȣ۞> 8Էbv2r-)D1l9P5[Lk&XZI4 ؟~wW1ÃQcg-φ{?1 Qg:8IAyasSp4f\HN8lHX02AZ9?α8KnlFޣ&a?dz@z>of;ȒntIfĎNn$ȵH7N R;(]1B"ŋN qk%ʢxD줓  ˫i"H̴wmxo] $p:z{nS%BMF6"͉i.5fGLu:Mjzjפ}ڥ+݄6V{9?/F|NXqq쉺Vs"]Lg!1:kR\DV>&ͻ(YpE${&FHMLnM>Sg9supRNdҵ7IK]vvͧiĪL|j׾3 ɫMBk? $rLၴLcݐN &8@ ^3nJKl2qp) *4n`))I%šT35wtbm^9ډNmͫκ{isYx;KrY#h|[RܳT&7KN?*`{,f~Mp̂aU1t.{f&l~Zbr}BEd]s`BOzLjW4Xڗ |#Is!$_C`f aNMS6ɫ0v\>w9p ]l6dL-b:?N7aIg48yΝFx=\/2MY&ܷ IDATW1fȀ?xBQ~h> U!F9x)z-R 5#Ik>_hMϊ@Eg-gyTDPH=M*Zi\3V8xη )JwhA1 Ok|HQykŶLO4f~_R3u _;g2Ir߬.ړ33+l>IEQ:yPOQalx >RF3Ɔ5.3R=X ~ek$Kφ nVk:\*d[`my0}zLMBo@=< nuD &g2ȵ690!KH2$8"o>?Ce #)m횩NH g2 a_30@ڐE ~-Lf Hϳf&&(Aά =*,Db=^{fU\5dz}P/{jcܠZYl`yԸ(=OcvJ Rt)Qj\ ,)Ulf`7Mzfֈ&=NU[ k.7j7f0}]ZlR}4Z u5_^#S?ސSYЅHotel(͏ s5 !Q` l.Bϗ.2.KZ_50 q飞Ka]X+5=MN5;jSCuDmRsBd#v}!$[,fvӾ =@nfvW_^sał \&(TwB:LХKUoQRG#^gu91&ڌ*| d7">OPŊ#-дjRj&[s\J XCm'(5M oKu5P ,Iud!Ew &YliA,*usjj6 ఘ^58lhQ R.k" r$dMN<@M z!AL-k`bP4/=lls~t0L͢08Z-#"Νf\ϐE 6#r@ʅfdi3ȨyEt >Ԁ˶lM F+2c JTEیm(D6-!Iv5[X$eDc^(-:&:r 6):!A:pM3ihCKؒs^C3+dⲕM|U:І籎Kxe l* i}Snl'}TC%5S_** ~mKe7ͦ>g #SL3:mHAK߉D3&f(G4aTcKi?ls#&% { a|K\,ռ99ST50^}^8lJ%Xl"a{ldiJ1dJe26zQlvI8'cUCYSTS@K,[8,v_{.>"H,uFb#؜Y`R?.[+KDvKrù5dOE~'quE=aCF7>O^1,I<j޵1J%U cKβ@8k{,a"$NU$]vKkK8G^(ۆN> w{J.eD)j,RU".q'-{I~ ~s0vWzJV7YѦvZaT VW^JHK)p:Br,H(бpRنٮP<#hp0o/A3 I^S QR#ħTg+D'd*Д4jYJy:uT'%`ιҫ2]tYdl_J! u P  {"=tTơ9N;LJ 韃 C.ʧt^ b@V,YuK5J#}s̙іЗ|1 !2D52 ujĽpy `#짎F@ѿ7 `O}4?AHTWxwIC$KYF LSUY"lBsT(!9!^t~>;ȧg`_J ); {Ae_?Yѳ(p%-Xth]`D=$B"ǦlSj+3|2c* +NHWQs.h OңR1>\:OA|Je$,>Jv24 :B&l l*ȐĈw4Gs] C%hPwlxcO"_V2eE$6[6wsWj=$Y?TgeܑG6ɔ!tF 84uH/-l [zЌOV4}dLʇX >}F3SvgIJKL\dr&ǦfdInwCTL%6R}m pzck5J5#2^˺`E-[}2;l4Κ-%W)ְRʙK̵w&C6+<<M0S0!q՘qEX1n"m$qxHrd#lY f˪gX$J>42*^PUض;ڸNZ3 Vk#)b HZB H.G%肁%*@z6-RPʋpJi&׸uRZDHBsPF&Y<9Mx&<d`d xY@O"BI3a5ELs-E=x$| dw1J4&(/BCڸ8M'oؿLsb[<| nGqāzr_BǢې|:wH;1u^ycqE x=:n٨H.zq SX$4փZ!$=G -j(舚>E}^\۠SO&ofTë/-4 'il_|KY0oHꔌ)9t(e*m{Q Gc\DKv8phXZIbڷ }eWќCF5xl~< iԖsFr#c®oRr0p`d8iXF>j~܍; .*BB Aڂ9EUa߁塚N}~L#N؆GŏnP+8@YьtDFc!=tBBَMH0W)*JXԄ6$1$ cT!C(֧e"%9jtHUGgdB f<,hl&F@ہ)l;P:J"„fdh,kc,v T8  |"dU <$Z>} Uhs'թ&OvkdtR^N;k(3dI_ iGtѫ\_q)$dAHx߲+Q ]l Zi[%=n+j߾QGvwXMw|h4SD` q UV| !Kˉq>ؘBtX_e'f:~TC!1={:e䳨jx{ 1AI[܈LBK BX2/VN:J"GFs͸q%XYy?x1<@&~OgWWp; SjHV3?Сao?,[l߃hqN6t"Ί Κ*݂j2z"b5o;\>?&:@bj޺<\EfYVYGk}bWiqTlU|'vSln!/; P`E÷i:2v7sdk>YC*l~_Ae1&tBmUqEdG$ `'xMIm!bpP m(J&\[zȗ$` dRy]Z9$Dÿ~?|, $Bc yM*sJO[$ɭP-\U^ {z/˩ [BK \N0ybMX*G3 c쩳TDj[; [i^>AL\.`i#řwJV?Qe6eؐcb#׆v8A?PSڏԴ8 kIN:z`9;|3_J>3/>4VK^%9OcMuAVuX8-XI+ f(lzn58Iŗ8X |qc~ F}>B'Ï5o_ G*lfQj:]%*[oH  =wb3t( 2.8X|臵`y#пFM[U۔b=t  Omv⯿\@Kаac{_c ..cKpmG%O@#)W]0zz#'↿}H|>|m5 ܴ"7f4-5:|m]xg🵫h豷?og/6̉#qE"B+A˛?7"o?, Ʉe6.IG^wŅ1VnwseWƛRݶᮠ\6#pZ_"\y"\y}_`g)\[/\I\6GVOa"CNKa7вOV*P <s,¥_sGt#b7=N&o(uDc$L%U&|{C!R g#6`jzj}F2y %.[J*y0pX5␑#^xr:+B9R[dnxlHU _-qӥ,=Np&S ׳ڸn؃s3ZF3Q'ls@l)erE/ nSxoC {8^.!k|&|SByo.8D"$O^nÞC \;wۛnqu$!<67>EA(_{zM<^x!hBi}-JL*&}yp~ T!xw5~۱#Z44(b &q RWg`LZ2bk@lA j,Qڎ IDATn@=% -\풉4Nqe3Tѣ]&,NcN6J[SFSH4Rsi'%qO/}^Hii(k ):"8Ǿ oyS@ ^⹙Ȉ5/?2ovH}/1 7*t?׬fe.c;ޜj{E4oQ/bX?[)amөkTZ5Get|zl^n\#Yԣ]:f=ƽq ͞sO^{wNuT՘2_J?۰f7ݐ`(\f6ijͺ|elVRODJ*G3C)7v!Duhmܵ۬JI(y;:7}Г2|v:D7' OzR&RCDZyHѺP^ "9-|-5IĥJ6Eڔ:T@^> \O*RвM㘖H'@ @_~W# @2BTQY]{"!9tl#Pʈ9U/U\"qBuRyw5!]d^! S E$dxOh88t`b%zzKܾ 7GGM]ӟ nYIǟGa4_7SpxJ~zo *зJe}s.bLC~ϯ>tiXMw0 c ҽ<erBTf&~: p#<1]y8߮sU)N>Z3BU&87<80 ]sWֱ(Lz_S\vOHqy^N:5<n[3 FNAOŎFĆབྷIK|G7Π V_؉¬ncQ_@bM b$-[:f^.ZbkO#0fK!^Wc0{ ̚hE/=_;#-}>\tdzڛ"iEu*`rR2ZQlıק\xX Bq 2@y}9r`,) h,KaK}1#R:vļټ2wo Iq r2psw;g݇-d N ȸt)) &GwV=lqwPwdY'x0Ϻ>vo`WdY.Uˢuw6;xsfa\hak{Z`k^'~}!2Szc#/׺`]jd&G _5GJD톞m`bmmkT]YQX\]F3E A_] v X6 Åȯ#qXz$h s'aQ('se7x٫.J4TXd's*8:r $l,JI${I~:oWvU>U%铺ȟ(/V:zk{]ƿV -ϛ$|eEe1~6Bޏ#6:Yc>F6Q24i6&|0Cioq``H\ebQ?w}pܗ?}:/_PӉ`&-02֊i4y@40IFLsp0524_t_aGN#R% vEh|Cx1U74s#1b~;6E4l@a4 ʺ0Ò4BD搿ۣ(9Kb߶:bi}A ls= &d 3BDb#ɴa0kEP"%08vya#zvXHQIg:H0i`LjG8 Yv鈑%/dqsIuP]y^Ņֹ"WGѤ@[T,'7/j$`QfRzdīB(hdQ5ʀe9*jϴs.ퟓTKkg$D*9@C"1#᫑9bŲ2m"OP-F2(9=.fXqu} $|NugYR@5U3 5!χX[*=qkYu>ydᑡ"/f$+߇vmP0]]AO䒢8z( Ma TWs0 6\Tt}ENxgL|UOƐ]nc %Wa HI#Iw >vuu9ʫI))42 _xgq; =g}%@}G9SU1AӠɼMt5ev%#4t#m&SRp1;e|Iʹ/34]잣pSUq`f"͜izt.j2U\1xfYX.O{]< «4ɜ4K+F8yN l/|. rnNrjk#^R.z #(&)<Ѧ0ETG8jP}ҊOh5 g7K:cqB]O xRCṴ ^+WdI xv+dKfS*,QI^yB' (^]u˲K.~=#K>{YGf5I##i/":ҭf,FM7zDt!ly(k 'ى,ˤj?2qc PMA&OM9eR&'*AtY/eQ2-U= GߖNQ.qϥ%hx셬Uhҕ[#SJ!$X$b&]UBW &y8bg`G!Uj]XcV 2#+gw-"*B)ԁ8RQ@ڱU{eĶ"%F^$ Yd!f*hqm1I "qk$iR:lxC0𥶄˒e$']ǺDEMn'Vpv=[KM{Us3Lz*6"Kj}\߅;5'+칪nZw¾7^6!WSRx)<3!a(w]5k(]x=m6пJC<8i;Æ[[&Θ8CaCBB68&H0hWAŢ}0l𔧺FD0VJAu)ŋR"Y(6"uPD9(JathLxɄqNZN IwwF&^(EB;Pj t>L58CBc>/zpH_\!#qς=Ǟ>8 dM0cR셪=l:ClЭ1{_8k2Ʉ,'Q O{g6 Pt"QG1 qcOEFYMc^q \2I>Q#@()¢|3,n@<Bd"PNC?ݛط3f-\<~K>;o曥G϶c/qGa'pAhJnƘ1WE'OɪIE_|( /Flhd1Uxe74b_2_8 Ʈ+b܁hwAC-~+iM#\8P,*@ 4[0B_l1 2K:4"a)N^F9iaGDI#P?O=..B%iYDXV:9EI#gaǿ๿l ϯIm(TO&oN_lAaO{Nj* )$Fn[׌{ 5d {ơu(b&\VN}-DVA+=' UhiLy?T8\qBȐh8) 7+*$C k7%UhY^lFz29ۻ_Ń[*!"q5p#U6#C"}~ Y&ꒅΤFblAU)zAT24;q0)nWW06=#l{O-3,Fh,R ċO|^d2*p\Y2bsD@b04c#,j/و/{w,Z4cKNxgH0B`./΄G-i ~dKBjݫv`{>x5sS86a1%Ȩh-Fd|:8-3qƌw00ٱL;NFuؒh7~V抍bېGV}Oġj[BsD 9>h#z*2.W@bm8'9 Bk+Ļ"cәj?c?v>j,~efAP9ޞ_Q ^3_?A4#jZeKCgv 9m }Eb IDATdB5†r1~IX`拺dd$KP'ai^ 0.֠:^9&1o;mg£lĦA^pm(MJѕg {o1V3V />dI`F*ȚeOe *Xٟ'-Q*րŹ \7EVFeUe ]7" ɂϲ9w]E[eJ#"+{$Aՙ6ED/(v5^^윉L {:2};aiO8;Ql,*3!A=^) kM*+YEQS!, ʥ8'3 $ˮ:'nɾ,B9{cyQ5|r5}Bs@x;Gk—4``]E;ջf25Ba=8mzvC? ?~s_1f:Zqr+[4_hW-dL~GB0h o6u9FL@{L/?'=͡~}o24^kgιU9qNi뜟iD}Mzba6h0хԵlxZMʹ ӔQпxh4xKзlQ*AWQcfg"ԞSSϟ{|7,"`yt/hQ mA"͠/^@ǯYSxyaG.DPF {fI*f1qxF˅C~?ZSCN $'1Ѱ֤za{(|Nwp-9 ߕa7Fov|:ْ_6#S/:?%z.ۋQ,EĊWcϩGqD K.;z7`mAЈIu7I_Kiގjg._9q4JO7џðHL ꄄz9x{O.Øn)@ [9!s6.8@`l#Шdn k/+` @ Hk'^N;H GH7ub\+*Z?WIT +"$ 2hWţ+crUƢb&9lҭhl0ߕ0b֞yPD/]LΊWeo ]N& ;뽪,*yPb 2,ʺ|DdP&w$k! ݪEIl5P=s.&<o I18w/tsHUѥ\G[ѰuC@! *]"$v!_|BR娬T/Ǝ4 G+W]%|8Zw֏Ow⍙c(_f.XFVak(o|W/]W^S)\[Ic<$țZǬ髱;4K~dMaXJ؇k0CpAH' p?xix,?@mF1 >ْ[P ;q1<`OjJbT ǏT`Z)\I^tF/(9Ji^l{@M*V58:`wנ۾m~n䧎c3gϭM?;ˣ +ofmqc{0⭛gˍx&HL] ,Ľ[Мu4Jxx2G} |XZ"G$tں" g+ yn/~o5 {e]*mCsկ&aγaiؼJ+Ö5qwO$߆9mp{ }rǰno}2?<oo5Vė[c(P%ۂ.ڋWEIWwǭ#\U@0V 0"_!:_cj=J2,MwWCBז7a巣0W al?oƌS9s= `C(h*Q'ہSs}+p@k:Rp O֚,g@R2:6೿,]>a9k2j֬@͑l)Ҝ&I EjÊ"!15mr.+;~Q*S)E6 غ-MDKLֹy"j/2X I.XU@T( zJA+Rhe/ẳ0k#Exe׸D㾎2[C5I $q"ze} U䐪P{H J.[SY f yM]dq~2>YzR93jxߔm0:WC4e@y BQ%0T1&OZ+.bJ™3Ty=4ZM,4/)<WJ܆6zb.j6“Ooy8SP!% ѧC2@~IٺDLیNnS4~72Ǧ"@湘>1#Z +eIdgcР?^ӫ7ѕSoqDQ9dd&"+ PH#F˜BkҞ-6omGk ~I Ûr%Xp3BMc@\B m!6@isitn濾OuA3 ]F w d1#}9%5Xzr ,<  1[:77t@*(;t$Di$ 3+I2C $&45ܫ k`^#cE}0S&it ),5iSok^a0jLc5}CO Lލ& OKNCi.]O)3?Btro!}|qhsiHLa2mFH(&.ԦYCä ( h ΞL[ [WA}Ѵ':&h^d8QAnd6 _7bU=c+_#I4vHu7`Ʃie-ۈot$4Tr:4+Fe:C)CQ$֓GXIl)#ĿJ@҈ZÞiR<.]HAFuqVq/%cF… (pDUFGh(t]pkCePd+C$;x(Y'eA /'CGɜTRvH$eYVQB(|J2ZJXACHş#fvI ؁&,8/MKL@: BJj"0 ]GB/MI`Vky 1vXS8'n&gÈPY'!7U3ϜƽW}w6йO#-0ᨹ`tM  NM1&"Be_LC656; ٽ*9j[8w,)MC_LR&Mn(lpv$C8:XC ݯH:ЫҒ9چN"%e4ohǣ5ÎMɪ!KH1h ߭77o+z,· xl$5iqCR>.hWw&j|Cs163Iifh-om0!Vu@Ֆ<"/ kO 1Xmq@i! ?54NIf]jG5/D?s=m"z@"LnDMへC=_ 1ɼ{]<U%IϱDy޳<6|.x ڇ9IA0?]bڷtBZ0FC` }u3ؽp&ÏQCLHV$* %o՘ @86Y\/Hųէ_Aأ5)#PmYwt޿VkC\Ӏ4Iܶujӣ >CDݎeWc8i^XlY6B-a` L%ύ`Yz~AE0ۑX+"DC?Β.d"ߴ S›+^wȂ /.ʩpYB!qVʏ g]C(ϷK֛:_j"zC(2dIk~sEְ"!{t/TOrn J/Dz7ʲtP4u*Jy|$ 3B(Ol#I׷!+9!j z2X7{Mѝ}8_#H# \(KU- Y2R}DNyz m3͆=PB:0 ]'-k4 >r^pMٷ3mkoУe1i~4Fb##m]mJ q2!D`%O`>vˏEAc=st&tĄkZ]n:'E3vfH OBnQ"`z@L/rc.R4U%;[WeUek2>!%3)`5]w*W3 ſ}qKHNԸtX#֬ѬNH>RUس(_X+V]#ٲxcsZ?\mh"> zT8Y | u Tp0j:nh1C6C-P! f\*J PQǕ3⽹I~>02ѧe rF.8H˟^'vtzFڣ0WR&Y0 _slD5cyʓ8^I1z|:Eeu~?558{!!K67HBAu.SY쪝_Ni+^فޭѽP}-!5J4땍 cKOrar:vI#b+f/8eD:OCQteGHRX 5Y;fYtP(+5TE6cM唱 3RYP* g5Qc/ǾUmx^n%F%{@TR!9['*rd5TmY08HX24kˊ,>b;]|Z8HJxm/'\2gCZ٪KuKyGZqe󌺴<NN]XfBOi_-èyl8wPc ^[3gbJ2S@.^-== 7 ў00B8_T'Q\(y8/yߞ@&U1_骉G7 n?A nl+8 FC?Ζq˃wxxj|#_/>e8[TI+j8;4+ַ> NWb)ԨZ&ƱSC~mVgC& pc]<枎`1zZ?<5ŭutwG91ӓ7&aBϪt!Py':֠!xpwvIŅR$D߼ٖ}Va  #>\HBP)uċWg&Lm/2]@X:.\7,q0IhԿņWЯN'NV˄xƸO%h]QD /ax8KHm X 󷞡U_W-k`eq)@qbK+QRaDNjsu>c; s< }f^G6)@qq5(;W @gϛpL?z!S3MXZ\>5ⳗ7$ԁWӎ_jX&L*?B0kԘC!_=O}p0-_J~rJתN2S#D ei#>G@ޯaLu0|_G`?Ӹk!;ʼn-vSA?p}5Xr*]`f=M#G0+)_+6{7SuS@̬y0R*IAHUD$v3`p2~fZw0ݫEh^A)c8#!$c"5Pإ̙1ZۜRLD8 KN9.CMU|2 'Rj\$ "4^Gc j!$V=[$>WvmE(.OrIq=rI~ M6PSUs0$+`i>2F]nL9Wg/N}$F`y71fAlSȰa EѲapIIPl2 Q>iB|5N}0z22%!5&c~HK[&1Ug#{k4M↲Ou~0!glbH"䤮=0Хa29$T MVТـpȀӢft*fdzh68^,p8dPlIdc%dH8ϽxtVZl_ 0>"d.ޏxhv,R/c "[T%p`ޗ]ƪKX Nwd8AfX jI,8ҹ+ 3R+f#̑Jf(:$=hbfo[-aO9d۟'bP&#DXIR T7xȇzd#ov3++`q`*L; CIA n$+:E+:']w( 0-P(@l Fr4G|*CY͝9_܅mE9 ń8]98@kdG:OHVuu(ЬBs|yFd4sZLoF1E4!!HӢ5"3GX#gBS5"^Hi˔FNDZzen M(5X<9^N \2]f )Gk .)D47tFrDp-'Io=8:u!)@4m4,+V OqRCgs1N] k.@JNÀA ᏈKLyQd䈲DETפ Zl~4:k 1`T;Ith0\ўɑ] D:7w5/Ѷd%s|nb=+a:fdvjUDhX΋&f@d/XenL> RAəcW^"b'DMīe~W%sEI⼨ˢr:\5b1bYǬh{*|$C$uDDn`6@tN3\'E~ Dך2gѩlj't#4MXC s~%)uFdMt,Qd3"Um3A* Ǣ*9Yu=έLMƪ.dRyVzQlaob %[ybXl:Ĕq#+GL+F(]JK=FOeKw$  Q-8VzSIaHcwdӏWfvEX0hkxuaULn"NHYO.3 e$=n3JUWDwPqQDpaP8 a HHyKwsr^Dfٖݼ"E) o9f;%e=R8J=-YkUVQ Zȼ"Pb,ȁ!!BzW]-C] jp!ۚ!l>L[m,G(hPun;bF~<(p:Sldr=C4 M]XC.ڍ?]BQ MlLnW\P-^s9gkt3n*| /yj~]WU9 tYNS0b|73jڶ(_F"[94pviG{xo Mҁpl/ze"e]v>;&YU-K#ڸ;̟M=/oepӿ?5 TxA (u40.`b> zfI :GT W\/݁YfĆ%nq@ Q6A#pBXKcE3WoaXD\kk6\E2Cpa"t`Zq:Nl+lhyɒ43ooY`]Y a^-v͐ n|%j3#HOq_A6_\ɝL3kgq>G+ EΑ:Ρ4#ä(0YvX’ӒsP"bxQYī^$Js9 &w驩]LWW8T9yσ$hr]r/U+{3Y_橢3*@:&` Vz[.p | '8S9+_Oӎ`{{j˰3;Ca>"brĄvYRȝ`Z@BH* ͐E% ȑ́";KP!f0EUE&#RH!wQAL' 33:%Ä9*P˖`&9)tȾz$-DT pb޳ԗ䰆%+Ut%3]% ody QMN;*za=7W'&uK{hG!j!IRҰ7|ns/v+i;_ͮz`~do.]v7' PYYoQ຃ٻ>v_nb:C(.)ÂqFע!6ddW]ϡ_EO:r97G&3 b"T웷2S(C;TE1'qi}6҃'q]kh}6_?An5P2oK +`@e ӟEiw1v^ bMƿfҍ7h}x 8|{e|PU3ōj9iW0 4hMu-dQ@ @sZgg@m:I+'"tZ:NxA@fqVԯHgqm*.7=%ErR<63\PM+[?$s+蹹ߑ,]qS.gҗc}K 蕁M7K=(22 7wo%W"\ @Y1f~YSkq/^ܿW$r27?tUc1da^9%*Qݣ`n0! zQt1 o\T 'ЧtW#lEr.n<<*ٝܫ⸍}"qrp+7ґ|[ 0V'"Iw{-;4,B.qzp޾*6gs#^Mv'b <0ʲUxF!?O/܌;E>#z`<$h싧ܢb{kȌkpΡ%oƔ/3IGZ : Ubk.VS?.ߠo>8}7=PK ٤o폎Hed}q:Z]&\_߇7j(b xms+|0O)>|pB@͜_Yw_[+*+%Pl*2|2uJe^{9f$4p$Yށ:sP>(X̏ *9%A0@Vsq<Uׅ*d8PW  s ϓl~Boax03 n+` ,9 ! J A5Hd-篍|d'=7a!I_g*->'"9iqUezOѼ7ClTz?gzL_bSUkАaNDf+{[@]ZLDM=AlDDn-W)&jis;/9X�V=py=:7%Dnq|/+g_xֳiēG芃 X"R=DDP!MDDeϋ~fm?E G:ͦ.W/{\ -q"jjj6u4?%*ҮԲb!W}?:SvPsh'(C>0Y*9xKm[杺.f_('΢]QWoTNDܭQW7ӚLQe1zv)uh o~=U8r/ 9ڷM,!͡w_DmJ/yEWndž--|Gֺ?Q.рIV@}G~}{%g!\Km}Knؔʈxm<"7hTLlm- L~;*.#s)е4 {z~_i E7\AK5]T=v)7({z߸s;]'t"W*,wO΃ P|tܻS KN B"޴Dϥ?sODTz;ՋO~+~yO%HӀJ& {qތ{EZ~dhNl7[fm\w=nlN<+ .A\ ;~A\^%lu:{x'"*/^73^(;``K)y%7D&i\ Mřwɮxlp˷蓚i?/fӼ尻 QQip ˫}ݱIeyYy ]+0$M{?apT@cL uT IDAT0,JOބm[ƭ7ڢw[aOмuSnؿ~,vh3fҏ߶PQ=eٕ` ԭ!CU㐹K 7A٩Ӹbˋ+ݍN'OcpqעRãh"㞡cfCbo]7ewD^_cF"P@kQ|T' N9FY#8 @љ$5Btt1:]e1eh03 u*}.ܸFIox b2U9sT{G`ϩ;>&i=1`8}C ذ}O Hscɧ͑yU.!{+Zp$MEȁxwqP}f*2esŅ%Jdt8e቉{GO4v#^[7LƕwSKG'7x{SF%3.Mqp@m~ڦb֎iwv0`HHW< _NZsz.HͿ4ggލsbͻc5lWctt0 $5ƯďO7Ct:1{zrwb%`H\>C6к9]S kLY_{*g!AN䡨qSV%)zܞ|T6oޖJ:}{xv5 J!2Rfv>Yoή2:} IIDNIh&wzu=<:IɃxX3s;wلmٚb_hs [Cb%XS#4b& 's'.xfP-cPdJd'iW{En7B*zQҟM/ {ot$zt YeTThL_ Or ՚:ME(3b9MYXJw~ޅu^O/vr'A]w ޻/z|at5i`4CD aQh"[\u{z4 8xal %&.vo GUnX$F*ܴ^Ghsl)/ض!]F4m%~.q#}-|HzvD<⑎G8p9ʈfп &{@ݸy /Eg:H]&RkZnZ"cGF`ɒ-c <[(40a`x9"Z!r:pq)NeoBC3IKheP,QSR= ˸+4 ͻp_Cm⡗{cp?4 Qv,5W5jo?ߺ%~aD O/i=Qׂh3 ؾ}nT^B6m@FvDIBJH1hp]pF[aɽf׻~,Q RnĿ3s6mVoe0 "C gma |ᣆP!0} TųeYw+A|q ]ʳvFɑE&KΊ0b\<g!×/l‰%HޒM-5ksNUpڃk@pȟ賏N`;$ Pb⓾&3#"[Cou/ zu6:b/uQasa"8/x Mh+3ŒtQ/Pmwj.=hίihOyy#ՋRQ1cO }峕Or=f]HO:Q$6އ#4S^n@uKAxwx*n\ CEdb$v=M vr&E-pquP@Q C"*Q0Lx0jHH{?258-(!&LiZaKpen-Ϳx/l,(0N!.fTą@MCvЪ׊{k )d,X"CtxmVS27oc3{6ûՌ%ֱ,ܵ'S۱&rc/FX7 Gd:bzuf,[ (we]('U,嗡4w<FhGDz:<\Jkd/?.o > Vo?I7S'PfR҃q#Tn쁻R8ꁛA"u|Ӌrk?kXEݚѤYj:nM Nt?| }IKą?vaG;^шt<'xk?-X% Qp\D%@Q(\i)ieFqZhiSSEOVc/E 8XXiO8V28*UfByT)YΊAqtʫ:#)6ܿF ҋ4Af|=XgQ|O_)5JrE_ U{=9xil{_8c1uָF 0ҡs *K F\DТg da)m6F @^)Hu~Y Mt׮b+ֻ1ѯ>Ж,e+#Sq$쥗P Xٜ*[4P&"Msm5؏|#̘~N`]__Y+%[wѽh^o-emS@a 0{ <>f޿ōID0 pmf\(,#Of:c#H EoZmj@ LU4GXI29=!p4UtT7 +Z&ypRF6?AaD]`L+c*y)x?{EB྾4xscq <>GΡ-t[f3{hlE:&C6Ǣg Ne7i=evcUa%S7vC&-l'K߭Ƚ鍙=.Lo02.g5ے>Ϝ;ێ=7yG4Vo1xbsײɌCX:r2<:d O폯iДk0ao [}R%u)r'Ǹ$!@{( '{SM[m1'菷`4xuD]&@HÍqϋܠX “ Ƹo{OĆ>6SzFa=4I Ȩ(>ϸˉjʩF?; ncbCph6? n 2_= E|WՊݍ{UT~7%#"4mO#3Veȿ.i;y#nuźOcI^9]6Qw_G7=+u|f+*Ē7av^iPy2}e2ʶ'ET`h~ />{1*ÌH;3ʴؚD,KOwD@蕎/d[/uUʨLfYV0+uXVǍ {v^V@m*x`2"DN27Alĺ2fycDXA^\&gIH  $杄|^| 2fd 0mMYQ ,3\M9/0/L(d2#DtkN`~G?_Ҟzb/ظ'y&Z!/F~&:4ဪY,Y=q@EN1W]( ^^6B%ݺ&ؐ)Mc]8Z.)v葂@Q%8uΚwMD|wlqKGqrMf$KyTv|+EKAs 'vdJuiFw Hb (̥ -(+h-ԒR?D>)HCx| MY8qņz[и^u0vgEеO#tl{l%&}r<111w{d Ytd*G|FQDuU`Fˡm1lZ&䞿KX떀+lטtÞ-Lg5vm+iR8^1KHjA1oCydnF̔K2|5"$□Q cޅ-Ħ9ȣH݆W'xXMW5.ڙKVYJaVu@h& а"[ xŃbcfJ׎\Ǒ FaHMo[C/G J:pm}IUp;$2q эm5dI‚PKD:s= t˻;(V9e0<t=MGФg39Bo7`+.}(qzPeS5҄dvFhIi 8@i֛qu9^FQdQacm: [RUv%lk7@*riiQg TR[MFb%5=,^ljC-1Gv ڑAv@Z7I.v|o6Bzau;P@a z 0H8=/tPkmR7Nm͠H܆ 7lf;mxW*.޳64m#(m))NtI  n`34PUmo"DE$B)*+kplKgH͹ W(u IDATU+nLa|*p0֨]푄l׺,\CHoR,+ƾ.r#Y}:L+ 0(1[v:1G!-Ə0 Xҋ7n_vh}`ׁjI/E|z*Է*g`%R63)%k#úQW^1{ ]]E;12mƆt9PR6WZސEv=]qEy8zبz ظ ﬦny.(11>8׳0p(P]t:=S#ˆL7,`ݛ{epL:z0@y;9s ,^dR$h3!:5$5H(lՖDHXv!1 evf6#R3o4 +*9w'IUY #EKgH o"̕,2ږ@LL/<EzbE9(+Wa gHHH1XU DUg &vz߯d_Fq.p $"E61Ky1U-na _hf1O%WZT[X/ ,8kd:L !✘, )jaP:m(Ri~e! :=$!?U֪W{+ # ~(RAarq~i 5@Wm0Qb"]mL'87ZޠD- Yav ,i#E-lx0SLsYj^=I=c&=yzzɜ8 Y=CA6\r@ s*LNa :t_iTymI S6U2ɵAc>`(D^T9ߎdQ-랮_&^eBVLCΊmJ(y"2$c!%JfaA{}*ض@VГIƄy/]4'+`rT]xNV6'/1Ę)ds# Q9xYteDlX,fvB E$ !J䑄 !Dݘl6ꎘ#pa G^ "N]@*~I㵲1.AY”8E$Չ i=ЙX;I81o{ YXpЫ, _ЗhLvS1Љr` A.&Ҭ1_"}6bd#:n, # 4=d«9`aLb,Igd,xR”T:JW7+K0nP}k>$Lؑ4) _4|c佘 rAc%OaLQ &d K1DW1fhC&*$Ry,ˆ)le12Y{ F{0_U!HQBQc#'ڋޡoײ(Pa0*%lAYrDV!bmnFwV̢fGI"F=F C6U>bEWNȷx^NB}~`n̷ bt++!NzCb^)T IP,&ykCQ yҵ4i]RLLA\PMP!b$$PI dF+,GI"0L) *'mmWKd$8Pdz <.f5=vs7`gu@BBp JzaB}ndV4c 4fb?T 4m5%63T2/d{!Y1{WmC$.gy0:mjaJjP} J(TR?aqk?Y]eɕ-/՝P f02{29IvjJ [3'['پYOe&rmP&)pfg hH_]Iߍ}63yCJrkCfOks~|372 1_jS'Zz}( iz01aYsf0߮! >,uh68.Av}c1 `_$`Fb/1ap9 x˄iŤOA !Tnhk#G"zD `$D5 =z{A!P2CT `=u Zwgύ\YX]\̞䐙{qYL5 fr&1%ӑ12}F %k76DE%:df&əae:eA _&(s2*V3Κ52;OY2"οLk+ , ݡ6& k2 wO\mfek!9BZ!uCZ$z(tf^„+ dd! 4VHUfCȧ(vIG2{!;:Y2 v&}>(403[k&/M =Id5$,7/Ù6VmQzlؿ- UqQD4n D̘ KnF$(&7 zGDlC09!犅hnB) C\l=P cPP)2Q@12E!åp* JʠEmn1BP܄PPmZyeu;C= ]7VRX(a+Iȸ~ЧPj3ZtQ)%zD  e&g%=f]UrّyNd(M5Q^R>@Cgl:~T\5Ed^ag̑jb58UB'-q"fN?.θPz;@!Ԙ{=.)j6[B%8dXmZ)Y|ȉeUr"=ě %?Pv,Vu%L!Oi NIFxX+o/󡡧h$wA/EBkq}O%1Ec@0Xȋc!hҲ.%yk_#?ÞgC_A#lh5N:3!  ȉ;3͂cuN{]b\Sy )7wh:}5 X?3;ÀgE6ePGq /&?G0z3D ggl1V-1_ە#$Z u53u{dAQe gBNq w3u059'a1ӫ߈7zc# ;/5Aj{J.jGS{*([2#QjW^ 3'BoHq<]mmHb5rdXf!/Lsg<$bHE/ӹ:̾YjUVVM$z<^9jZΘewb]ya9*K(w b\(p+e]v2,zbi.pxPZJJJ̭^Ce"댽BqKUT;XI% TQRf*z֞r2ɵK,tV7u^`eUj v'+*qI:VnGq9UCA P^ 8<"CBȼF]I9 TЫ!iS600 F.LDo`bfbt -ym`0B2alfYfY4;D@d&2$kMqK H2$h@m2*EBD⤺f g= (l?MȠq T#L8t} 1쑽؛˽{Я_xm졻k$ۅQpƦb_xmiÖ|-ĄG7I.šB.lf#Ycsǐ츰MOυ? wNUm`;pw7Ǐ-E~B}M>uvG2|Kѳk>{ (eǫСj~z*г"ַ?^--n5 &tAL`0!?qHhA7"4¼fs#BjMm &9ӑ dVP@eb5BFDٺM~_S}()麶$&d0"3P: >bVcWڵ kWLaQVM B1zIk8@N+ח#}ٸ6,{:^ǎ,N gubR[Yٍ 0u#S/_܍V[^#c1櫭!D/щ#BB$ˉ,A ogf YodjALe"-Cp) k :pJC|0螶4vB;+住pE*~f"g2P•rTH aA$py\8H6C剋x|<)rR֞YCunl{3nYv7`F {Ә.PE(y+NC8\̉`xn}wT[gf#KHP$#HNbzŀ9{1z DQA(HaIl3?΄>} QvgNP]]][1U.r#jh3_@7êbdi\ZS.deHZ\TYu"spm,-k]=Р_ :Mf#s<5lCy0 c1X&AUa0G=>$p^c͡0XmgĥC L}Ag4 d2}ɴ:"hYBF5,Ld5krK6CHۍp 6C\l푠> '%`u&2 ^> &F&80-#xN&Fc5 d3YOdF? ֓<1 Ff3d 4tȟQiSek cH~jO 8P:F>8N55.]q&{˦ػ`; k[|9VgpFn>D~t]!H2+.ФSs4߹ ~r0/a6D8` i&Loԥ8^W]&hs5wlj䫨J[QŻ_ϼOQj'JS:5sc%'n5M;;s{DPQ+"ÓyռsKr=]ę0+_3gl#s }zþ9x0Pi3wqvh ^\ZZ8.-j+I <p k IDAThTfIH,dº 0wB:˕1|1B:X4!qӫjЍ$样Y4c,Q }~C&pىX3y1 %uh #< 37IP5Cc3 O":gx ֌S  Be'j-fLh= 6$?Cʖm\u,Ⲃ:Dau$|Kh2$%ȝ[ TU3> pI $UK /ia!ЀMЉ=(IGݿ2c} L#IVMNO 0Kį`Q+ƾS%eUTXQ}?CR~p\͋Xiw-D[oD/'a;﷕K u3xM14TZuԭŁU(.p1xa,؂17kPuӅ5UQ6D*pi֣ct;] ppo芓]^or[@[6ͱ|4bw4iTc߬Km…[hَ8"}4}s[o//-ԈG\; agov`-XRFUcp5GY WϦEA93޹%j/NqفJ*.N4emh|D˳YS5Jco.KQ$Cc9\Evlu /{.| &\GvLGIB$LBl“\H`Em`C]TCz敍ȠZ2*9bڢx}c1bAV<]4<4zuȬ]DehR_Ge\Q[꘤O#SCK0[o;h'}j.M+k-=F^A@taٿ}Z>ƨ+kU" 6㺴ERXt?hM#-*ʍhӥ 7b9܍be==@}NnIkq_KW 8_c8>_˶pDVt9`P&c׺σ(GоWk.G~ށ+Р{kܳl-EEpo-(.wn<=P?6ѱgcԍ d(bX`'VoaIg㔗j7T.EnѻMvZ+ZMsT[+ qAމ9ˊ֯F9.VusYI[y)~i6d5¾1wE u +݅hp<"ܢb]PH -x^lEϮuAWEEF*nE9XwV#Ҡ =-8а1z͇kX[u+ I:MjYM#rZ&A/-~("EwnDI!X )ozlywڛ鸛=16ߪ5QzZaB0,2~">9dl06gr鐩W%(]+ØńXj^To/sϤ91\ہ>m4铰vt9!=D18CyteM})NδfzoQFXd&='0%"c1b5|۹wm†oÉDPYQfZ0{w!0 nm54mʷqUƹ6DN ܓ*Hp*]戣rp pR7 J(cDU/M5L˃‹.C޹'׷L{ޖb.(\ f e$ RD.pءGmDd(Fr>Re ڼ/#EN't?݃ B:x`'b]M/ScDp]"E,Rc{%E:v 'BRSCҚebBJ6}}t!$x}D$f&MZcAJiP^W,Te-@d}VmIS%?m=))]c(yt/r&lOZZRӄ94f[q)oLDSFzdIk,E9cu._bpо[Y>8Žr,VKnDŐ )N|8Q>t&8m\AfFD<:Ezo/,eU' [u`6xotc'9 UEiܦoNIL 4F䰣W=^D#hO^ lsGuɐi.#rh|OёFYTޡ/)o{{ps*锤]HS+:Iiy8@źn, q!&P !Ipzo-m&(!&Vؚ05R6J tcGliPN} 2k`wKkG:aPǟu}&גzXlӺk0F93LLa$Ôm֤L v[IyY&VN2Dn;I?Z"Bdr>rl8쳰X eK\]wr@$aK.O AKz_bR ]\5Lr>oQ@l5Ń!y2S FNAЃ5%=bNP)L:\<g ǚ5:>Nu5 P1h0ܶ;Ly&J"=ui'thz4auHo^ہBtZ)D@! {4e$? ѫ˻ ACЃ^I}aKq*3m_=o H0bTq_%6=pLjhҼl+R%D A !$F@$}-x0uh-QLeGɗm2yaxaУF(RL0oLY)b:QаzDE̻Y}^{i_3xhl :vB=ARDҰa}`m~hsi -q T,vLޒ8-{%?PsA@2h$YOIDIuQCiw-O©KԤ}(ﮜ%57!wQS8\1Fe}c"p-/RUq%)7, J ]ֺ`&rѲjH(qғ&R5Qq,F]AkM'z=j>Ntۼ뛭PW(uʌDrt[*H3_tZS]¨\}1aYGaגx}|j,P-y*֖0Kԛz} $}=8Y*s/Kz*`8J&iIjI.TēVw# R[ebI.XBLA^iW֝ɰ6{dA꽄Fnl5dƲ6$i=bmStݥ*YŹt:`XsFս~4tc:QF{(Z:IRBtTG,jy6Ï\#\FSs}+\0n7bu]' ;;F$﹮+ygzͥ1ЫF(L%}2܉c[5 J]fD[B4J>x8Úh gZBvM^^ࣹdG#xHL0hMP4yP,ƕ4"ǎbݠm0mm%䜙%k",{JHv͗gZ~٫+#B؅kjiԲdtF!:A GWgfVO췞.qE'f8kuۑggK;b Yp%gW\LME1Banq@ac})!yHźYow F8)gB}ƞw!xSƋ Ou-. ١sLٌ]ژs[Q /NĔ%$J<"TS;<^ L+ބ/_}W]r.&L+*jH,6W&zk\%籸qTyq<~\4B\~毃 I@TY^yaa02Z6rCˇx쵯qI9 bgp poac.8qn7‰8>P&/ aE?NNK!m16~MNCkL(fv>`ϣ›dZۙ:21Rx#5:w37dʸ2^ddS\',5U0TMSDW)`+d3O2%ͳO>S/?JGUf|;`/BMuI^ƅMC1(]7?m(K_TYw4)9C6$Q$($ hJўx9=byerbkp`.Ǟ c+t(d-y0xEtXP v``cxeEصc;v-yݸW'N޲cW=q^2N;Рcu &AV^_Voæ_䗞 5(%)Ri&HKb@.ރwqQyc⵨ڍ)UsW4-zuŖn9׾ޓx_Ƕ}W&`!\\3z£ xLsSBQlߵ+jT஥*6c4=vϚhۥ;7<0yd'̲Ě䄰 /P*2&0;s1TT&_7({5^v2v=Kg};e'`7pϽxx[Ԉ h%=/[JRTLM}uHEF-LztQmTBt&Gbv<[~:6͉n4åتϾ`)uΣP6+ϖk(bֳ~S$R20o>@BZDDpՄqŧs1n&ˮKL/z?]y{&:uݘ.sx|K]'1`fvK;w<+w҃Ϲ{ {_ܲ;lү{u/֘7os>|ROp٭޿+VrW1 jz5A\W ߿ >rxw`.nY?mc?' r;47m_+b{N<3~{mߝ_3V.s-?7;s] XstReI_]֗6y7twڕvʧ!W0= M:sNݖynfjm|aL[)OsQ-`Kbe,ukZ[_vօ;;Ľc:}`#AP~].3WsvKԽKs\[Ww.S^_̱x`uYpu%ɕԗFgIV֛:<[n];Fw?[g[6޽yBfMu]x{t^e6~%|MCz)vcqQ7hca :u( 1Ҵ^]m_qu)IG^ګ]5}aΒ~W `\C\]}l=摾ֶiLS9qMfImџ-%QtMĹlJQ5٠#Xmzh%\f;6zڛ.q9_?y3ϧ?|&dqmp/<{GM9/߈O'ݍwm6ƻݑ.X6 f (rvŚ@H ~w' y7bsS$=VẾ} EYuj+CdtZ^xpϯP\1a}d)ౣ0TYw-El1\jw+pUASP`%OI?'%'1$p?)P0qi{|x*[vLۄ[W=1鈬pf1`LFaa Fgm']$\0fXA3{`՜h[q\sLY@7zJ(V[ 7U"?'ؑ!LHq&USo˞\{fƍX/ʭ. śMN^DFT]Gqy ,f:5튡MJfGD X< HuM cˈ^L㢯`,%Exl8.k~%N.D}|tY3~^ckc|w6mGMmV+ǀE9~LcX3JiF6zI4HPrkCQq1 <\|ktO`\db 8|аӟQx,X2cT7kK'elX8;yOQo`-Pr IDATE<5)ϕ:ÂQ/S!42GԺ5K5-O,0*Su}b4%!I'032-x!I7  PH2DȤ-^ Ղ]`3%}FrK!/Ɛl}%[O"a/]Fd |Y'0 3&[Q ~M6 JgбTβa9-OsރCGCェf\p?||,:d1h< ^28*kbV27ZN(0> *:9Qdgǹ ĵWe/j߾t@`YJplU6589y92w#N%I q&q`5$h:|DJc{Kx=f ln>j\(*})&?獟?KjP~?p A!qf cOn 0'7!A8%8z,uqc1aLhT|aG؇-Ѧ?ll_ 9WղFҐxmWE W/O|gou9 +Гe!|e0GlUGQd7SG.&rd5PU]H.^14[Qu 1ָyn[NHyEH}j ‘Kp>FKO{XIᦹYhy02GUV Q]A!kc`1Տc-f_ٱT%)CmmJd9` bt,KP&E<1Q;Ȩn=4H2/kPSnUr.m”IE\~q }W1k6Ɋ7dM&"0+Oi&i>5XO' &}`"5 TlizioWi-|I˦:?j^/::$|6H%đ&$@ؘ2 8@h).:Aɋa `ylnRM^fЖxBvDqd<O]mrr1˯ /W~=d18DuSUKIEpm=W(EuǀdEG87r,O _/c:iJBf*PRXp3 =rY"P$HIVNGkZ\V!v_J %1!;/l"'+~v(}~z=~ mUejuÔ:Dxh[|KyƿGbPU PnXVFS}\2Q[KO)/hug[ b{P\0 3엇EYhԨi-R&0THu"gQd&.r 7+ LDD=g r<`4[(W6pZ< 43P@f -ι?$Ś]: ̍֟Z|՟ܤWYq|s^X[ۿrysD:ELK(ʞ@̆z!Ի6]t3;ݺ IDf{1tG5`7=:e d%E gFMT9&ص;as!DnV>X8` kbBoxba{ƴig(:5{g7O}L8](x+͆ѐAX2C󈾸 #qY<z6 w`9#NM߼e*볷pSqXvڹw޽N~.KFt`D5StĖ>3gEy拘6]q{y2.^+"` _+FS?d5|S }5eWw}_~1tl]0z 8m琽)ph0YKNѶM!ER%t)2d1ؔ,D!x!NWvVjBáPTLDFIBL *rK Q.Z١atq &ֹ.+R ~ŖE,̏2 "yP(+ +N×eغE3'mG1TDS=-=rEv4p7im' VJ+sFJhx |t2?x?s?5dal(TmTEõxxx3#%;ƑbµwcePMړBOq:wPyU fIEB!Bum.׃ ~FG>a}~Dv~}ˏPkw4k[@E%%Ȏ͉+`~]<]m%N1NZ_07׀i)p#b1Hy[3#u$|{/)(%)"|Kwx <N:i θY7]j зr:N3ο?Xzƭ>L/ݎ]yF6Yһ/a-:;RzV.8TSϊS(SةƼ7"N :z5 5# CuO%IKqф3 z\3{GOǬ;ϱ]1/8`"]ض5H s,F!LCuDͷHTLyn}&?t!p<<ٕ9 o\rN=w h/P&pYk'8RZD{ 6;=L Z)_]RQ ҽ©a̔Bu)<}asL'8#/ Sm6\p .9F@]{)/z z; p4jrZn-Q~na"U ЩN[l%֖R1TRLK8j&[PQHt MߒЮ(>6RE1B_!@{Eg)W`R۶g Aa$CHȱMcl)PD+4^WoMP<۶iK[Kaݎb4::4 K.Wh'i$c2`\V_ Qi)n?e,rm mchֱDK$)oUo۷OÚ-UwZUPK@Y^k IiB2wTE\n鰔x╅fr8$\}&XۯXZ#k8O,YU @߾,{v宿۹~cq\ qοm92=N{m|d,C{j np"įKV`_uu퉎-'R@56X?7F`p ;V-ʝ1g 7`َ͛w5 M:cp6&'`{¤s2]C8I][)ߜu"){|rl;Gㆣg,^?~Yh{k^5izvAN]l zVB7"X;JQeGu" %8Pg-%Mѫ@J0:¥ݲ ui b5(o[׷Ӥ+mä{u=pV=ffhD3IeMojF6tAX?M2et"Ll=2 |Gu4LCY#I9i?9dTn>>t>n۹ڄ 7 7 ߠp⵨,/'X-]]X^FMq0AyV"&y䰓< zbMjp&/`q.:(q7I fY|zC#2,mx!φ&i h"&0ڢM[w~(7w FNo:Ӓzxꀡ8y(LomΌ::#fx ҟ&:Yc&cKCꁅ zCv$k1SnvH$a?&a( #k 8jQY^pw.^[[MM6[ ,-"-RB'k$k+#a0^v [R81r~@%BOB2'2y^y{4MλqPz|pf*9BK& @~DJx=cI!(j멘)aA2 C6>B!C@`@W;zw|cϓ| X)=ISw~Hq"P,'XX KRR^0Waɴ3ؼ;2m]kάcoLu(#Iohls]|~a2h(.Gn>P:e~-t.k6&4i?Et--] Z,HEҺw(Bh8IkŴ6h^LJ=2"mT%7m}N wȉ x$faPtX\BNl9]۔Ǒ%X,.G<ˀ" x d$xFJlg492a'1Jr". lqL #+ֵ!ɏp6AX`wI>=&*$# C@FjZD"i:'8eP.mЫ_ '~AQYD0DuԧDIѨi.Y҉D5BleX`f}Bv$DI$8Ӧ"3yp 3ao;D|r2'!w#]xED pDp]M 1HZ&$] {2;D//M'+DCup-꫰R p ,e's䃑WrX NTdPahPǛԷpyN6X9$/lkm[~5:LRΨ6}k|!,x3>ido;&iNl$(<%K#0" ֈa&2)&!(P7EC<{VBY-=o)vh2>& zaq`?y1zuF;btXO`3dc7LqQuŋ7ዩo`pbkq9[!=nDã~äǞÜW݉NvE3݈s0 q AϳKESc_nG\q}tJ$_o5KxM+ʡ0(|&ϛX(zIXr4u:{<:.X2c>h?]R~ހ/\_t.+>YkcqQZu8|^ջEgDW(chn!)"rk{'k˛59_=0O8usqp)9<28~e:FAjv<|VjVœ `3e_<*>Ʃ}[W?{ِiuX#kBʤOnk@C>= sz5ٌ.AboI[0o HZ2aAΌ-*3J qQLV$q,PȠX-zm0;36͑DmDf :KP۠؟s~(|xAHq :$YjsWĠQC} t-6r Z |j<ѴyW˩'аsit?_dd*&L IDATWOw$͜!V{WƜMS GJhYOвω{^xt* wފ<$ܾϏ^k4+Ρ,,$N*M5^PSPլx w'=zEeoy-wsdX'חM3JCKj\k(*sh#XwEGIٗL"&qp~F]qN&p iԩ:ރ2\xif};>9ׯ>Z;}ߣ)aԸIϠN9h+%O޷oO8ƏuفyYoEni'аOQC["%;}).NIu(R+um>4Xdߪm[u.,^{w!*e!H}ֽ6:azK]G֓o~H?aIK{/}p/6"ɓZ Ez!eD_&c`?˭~oRG1uCkHסd+ZS x665ɱi :}W7 XmQkXdA?"t#-5v! 'OJwϾ _DwSڎ/W\wM NԂg GUw+$|}Ӕ.MUpl.[zhaxB(Z;xU6q'`˧oOvOa7[Onj?}[bGs.gu@@щ hȟ^g?AގW744CzdlߘXNf B&li@f&v0hW۰˫w'^Z#vA NZ U,=iX,kG]/b /<1{^^8:?)n !]&Ǘ] ;z>{)1V˥f?ܡIu"D{hHeӧ!HZb ?3߽|2;Vz+.)m%ʖDɯur(qrWnp@ ?-&Әn|1\؂|׺q XP}ּz'7V_wF'OPSާxϪ &vE;λ.;uyhѡ <&>L Da*d\3|]M &̺m#6.EiOԐ6j(-\?֯e%mPϊ4xg\#- )$*]} 6NzACTBDh7 u__qj1QM$'$."3 au -!mS A}fcLөm<7kB[;X#:Z\ʀn_'G DLq(w=s@يcRaEԬg4;Hh{"h?&y=ƌZ\D/q f oىmmҔ/` I.jj\hF"f*^]6Ba]l}t|V(rJ=|.]69St$ϣ%όpIFo=>v?~9y-T($I>+5>}S](gJX!'OW T(yךA'/rZ$ߴn*VE?㿟v}ѡ| )El-h`+ΤΤOWH_ w1x'-AZ#Taޝu&Z;=|:rz(wX @^n٦^xC.HRFזT=LRpJRVCfw"Agr]TT=;I\('+!&>S߫7%?SX5U NMzٟ<'J//^7]ѕwx-J+W"n.[,>U<ģ_[zݎgLAF\ R|'wq6z\AIx:> ?m(k#MN{dϪҍnA5/&0g-G#+4T[7qS_5d6mU\IynOޜs7skj*T߾NI^Ƿ|?#F|}f c-[}`D%|q1ʤ/Y]Sȯ[7>ƖX8UM̥Rm9=;;s/c6_l p;\d2(B~r-*ߣn3alkQcԩKX3=~{Ưp[UJ>`r- 9-b ǎL MOfwx_?wi׾^P]NHIXZ$'kI1h>g޻8MQy>!>Kt=SH= Aڦxwd[O Vg]k.E./xi:TVwmVi?/M.N3 kd Rit%%{CoFt- eƚ-6 H=ھłm:~&tcci4kXTN{q/<߽~4-P_Mc@’hy{U~-vmϥ_[@7h\./\KwW@d<PX, S -{h(^ 7zlV+܀X>denFnŚ qU*zA\ nC45ճ\a̤ "=uZ!1dZӾ6 \xԣ=2e*PSuϸu|hKOjs.%Y Q^%E? i :g$cEd$hsJ#Ɇ"Vj_M^/׬IZHVɏm3d%~L{@ʸ$Or*#y1t8JUý ;/؀drf6v٦iH0$?aAň*<*p8>}W#s;c`e~bxYH]"O<%=N :]=pJ2|{_NƜ#0lX+.'V],r. ׾? g$u bF~ykљ{u%bDGڼBt=z>EKx(+OuI aCDL ê]55'0Ț3&0aœQQT4 09/tW׽s~qpﭪ[SX!{m矘 #(ǍwOu/XJ4*=Eq{q=lRlbzʇTF&23ѡ$ Ƕ˳Wh 31%:|D (?ϯN>]Avzh~m+<|o< c&Ù[e8|y^-6zPl,|osb#wy߸ТS[ڱq'q]nj},T"Ss46|GZWcw,dt͔Κa,2,DR*D!9Ivc㖘~m^=9$iT,F B95=dܵ:V싑r^i,uPu!̆/+~~ (/L N15;b"a æ )wVo +{6kC2̥BB$LkGtYg3aǡu6$^A~:1C@Öehi΃:8b-=a!dVcJǠVi-PУnVڸa WV uKw.Jsk\u@n=U"tfVB=R}޴;ZFJ窊ؼvVW'{T~ >#q'֬\ś\^X#mZ 6VqI>4|@8R/9Oa="anZD9c6gIH-AUa>dƓH0˔cpgI=hCfY*۴)c ݇`^Yv`݆(.65kWjT60i!(/MߖaJjvJc.ܣ нW1Ō 6¶/YܘˡʮCW/%c(lTTqz^Cn=Ѧ XkWZ@-$}W`ؔ2}e1ZSȮ~Mmhc*l٥=ֺj2lз{9T?aFX;:;#bJvPSmbdh$MHc-mUWpD;=t;6 CtRq M I1֚ ;-A)[Mhc{)IVŰLO$KI/+;6XȠ%i;%C\_̥ma-1V(|)Rɿc O 5`ɃAYabڧ֐ڼOszCI AFe,IPFAMc%eѠXMxErh'-{&q&3@cp̶l{03l sH\2.?/;fê!+oʦS%-_d?p\d3ԀD@4V,z-εh&)**0NņǎGE(E,!S(N7/H;( 8;N6#[*9߳H+\7RhmA+쮱VP),LǢ >)} ^xi3A4q$+gl KDt^ L T`&1=T=FHҖhEџHB4 EH 9_FJ, *gYe<66  U83Ca{=F{.8i, ;"ɶ%g) (g.! ћlg\g3Cj*` x0F@0rP d(V$I[ N!$R=TGf ePX답"Qd~Ktf JcKy8R>_$V5;$Q^j# {*mٓ-DZo-;{, `) ebb  jBٟ% RZ#jZ]`4'[=Z(* Ky_Xh0Ҩ*ʦgicing1 k \KҫFbrw:Yg1Ш5 ,"Zր V "v$ +(8Ρ:VAOMQ,6= 8%:%s.&MVɲfTg*dM'҉MYeő6R,@)@ia W)6cv/\ܯC4GBqmj*eR48f vXȭИä'aYӂ ۶ d_0#EG{BM.?˹.C5 ߳8kaY[yUϕ=X;JAk#` @C4էU%#N.gI{gm}߃Ӵm_16w"f@'-g3.%H -YUhBMf2t&Џ#x /d?ս 6;xHD"@Hzk3ดH`/ ٌg{K&1Q̾d҃ 0$.9D p.Z7Z+hY`AP&-><Dp\n@LbE^Iϧ Xqh L!!%F=52Zl9g1g IDAT pԚb^SauVyIE)Tu3@k'"m !eɌC:*my~ DTNdTfHudRܩZZ gCT@`82fȠ2a'$.+QHbbY@ Nv IrR[k PAs[3LP=3&jĐ".a[d<&gy+YGkoQa"U(i~jApG֯52H2dܵA##[ATOOg*}DvS lAq)dq`X:N:J/M8$;'b`$8n P2H$\8n|&" 7Q=EB]4aMS΅!7:Q0|?CC꘭џM1r&7y3*'LD6LuA;aj/ѤzZ>zR^(gDAa]|Om2H ɴeTàmi;Lq]yOp hOzp. b#[3kC7[ϝput$ٕL ,:)?ńOe |"rӻ_}~7qz`Ƴpvu3uax[i:pkAL llDa')!CBXN Zʡ$aH͊4DavY⣙Spsߡݨ#pՔ0CZ|ϰv}/3pߺ"L jJxi3%=B0Ad1VZ>QF!NKOx[*M1`7ݷތ1Z$.fL޳+ei B 36ESa`:#%\qcN&>clښc=yЬ[GNb$KCw_7*?}262tSd:d E05*$"lTw-Fǒ;WΣ} _/_A5 *%5RLǐZ 1?~awcJ= ~iސ"yaae)ˢ_6\ާ*zP 7~9ɾ*  v'.| #ʸ#YYQ pM ^Y#uLiBpR.!Kc#}@lY5 7 -˱rq bQGSƺe蔉]1Zj-ոs;6oPч8qjV~27B*^I|&hLKfE]Uc=7|`Sq=OoϹ?`J~wpM=xk8KW>xq6ow=ϑغz#dkO+7 2[|sH 1dDP>5k_/6o*m6  =H8CK(dզHzTuc%BopPղZ!BnSigl;˃7J1&BlAޢL32~liREθzИ4{#`Ĭ@LlBہX%s ZB@D챲j k;=Jδ2Jx6h P ΘqZIs=gd: F;'=# *+HŴl~9GI'lvCRJʗD  ny~OGS'Gaytٍh]x!]wvIs[@\u(/>dn_=-GᚋejeH>#5;-DqP}t퇉wG4&``e8w-ݪ %v=Q9t)LWːaB:zC8&}Y'] A绅(f؎]Gahʩ1kH&HhtͷGzO0/qAWS Lh Džf3:=;(,.&4TaKez}F(#q0P6m& NVNO^#oi}v.^w?T1 **JaG*iѣɑ,9K  M9=KN)="ޟ6:c]{s:>C@uu-ع{ H/f+cгԒVmsl-.#ux~Ēg>RH&Z,;4DtWʒSm&C 1#)Ybç+p" r=y@sN+vלST:<\&懐ǖ:( Gmcyk!8jƷ\5{u'1-JkA0+~xyr^Mq>aɜdb@(%A9#xf~ohl057;i3u6{b>yGIgOÖ{:lXPʖ`aa,t;2Gi?VO^Tu- ibtl4}eiE QaLP(ِ hPc!Fl A]q |!{,H'*մ9M1.ݺw^'{bJf5ZCUjj, ! ^l ՞m&@+\lĤ2+HlJ(CYRy0TNuiБgr)6t| ?ͽ[G|:<}n?{-vĺ*o 8]V79ݕދwv_O 0e/ߋ7zԷ7`m}#j?c}k}k>l-KR=p̄Xh9것4+暻 0=$NY'*AY8g{A–"5{}{&w2gL:YN聭9ʉeXh[%2;;oCgᄻoEMEV֣ 'LFyz,_̀VYs^^֠ո+cCWtmSh"R:[XũvűGE/˰ٱ|ǘ#K~lً|zbˊju+{m@]>R >^~d*Gl:-Z0 8hX~][6g4'7ɛٞga;;͔d{7tڗ/{͉6N9GW6W>Lnʙ&'z:kcמ^q"N:tB'm &1xݐL&G1ijAu1AL|hxq8aEﱽ DSr.NȚ[ª3 '\3%syԻp\;I#]QGK=<Z {431'=yy,^t+~1XxnU5z{2_JGdF3MOSoh&44 ޱi|ɋ(95n;//GCJډ}A?ڌ:Z[!My\\TI&[>/'NAj?|eꛛ7Sk0X(6uXHl1:O'V:f3>545 Ǐ =ϴwX- 8Л HoDZ]d.F":! MrQ梛: Q 7Y[UM׬u6H"{buoh5j}jb&M,"gdk>G_n bF{ޛ d'ɶT;v~Wu&33tYYj//7_,?xߗ;\X֍~"??_};1\~7C.#G}G'wfP9?cyOjw.J23sw|xwi7)n˹[8Rٳ1n^Q/Gӷo5ѿ{>1ܻC)E\k7>ט#z3>nm(eޱOj 䩼=ǭ|>=zaC{a|rsݣBeM| W~;+_&ᾃaW'o4}t#xfV'0ZǏ#V1s|o|sY?Z˲_2w*ۧ;mۗ?Y\!ۘ|lMLv,oOÇr6 z w1h[Zґ|k5y=g.{{t06<+/{~/%o.+_=_aW]~k+uѴw˂y/= ޟ~8z%Wff=?}ͼd'{$9gg;?1m۳~"bЛ1l[+UeC=AV,F*Wv8s$Ȏ^PB5`  S>+(k߁K Q٦ZTno@iv\RFh"ewOVdbMJýMtX$90B41GHclWZ;q+E]R-g'`mEv)-QSUu3+hCA;6 [wP3[P"`Zb5 gs/…*qJ]f&[V 6d(ʋ"F5۸Gv唆qsoް[w~{ujOcSQve*pסal\4Ɛ!=aJO-ѡ]+$2A+ڊThe-}&֚kaMjQڡV(]X~Ķm?FDëqD2TnY;J4`kewlxI.msA^(dؗ#vFf5bfʓ |# Yac{ɟqfzjo"E'U]Wf!dYPfH]D'4cR d֢ƛl8|C/Kl]D"r%ʞlb_SixwSt^Fw>֐8Wl\^%'ay2,MK&8ذm\W8)k q u5 '$̛7o1onDrkԈ͕BP S!lH} 3(J ƠqSi*M` ݷbtK0% IDAT3]ZLp҅9g98A`nS=:RR/l]Cjiְ[܊ʋS5kH|ĦBPiβlVC48 nK68NyaA3Cu k^A.2Ҟ&q} r2*[ԭgJ|xڹ^:9bЊM[笫vzoEMxW:nr?58n1 +]34&Tjz-hM1H5aURN te αFJ 7JXkn\4ekLvM01M:xԵљٴZcZ6{%L7z=5*ng1HrP:Vj"@bs(Ű|4P`Bг:&JY0؋fijt;pCc0x'[ѧqoiyaAg+ zL)c&GxҰƢGB$&,x;i<  c?2aeDT:k`p$c[,йsp!jdC꓉^ ?^|C~d Gc:8 =Uk'L]A[_( ?Rw^Sb͠qεɥij1mbjgv8"ZgtL&p14a5]e|M-خ5Ɂ!cdd4z~Ap삍HM}u_O?c)#ulFr,G_I+.MQy0|p0֍ O> uyj.nmw(5eN*(W"s`;+Nh7Wj h m2o0*+2#8rGRkFѦ6l[+%Bv6}(ĹƭW1C_reI/ M,(vSTV@^v4[6VCZFd +{uZTKZR6l_,7d~Dl 2Bkݓ5*ǠgY)defȴI?ˆƹF>~/04# dh""n+zmBI=f=1XAJ3᥸qu4+kE cL#XsCKb# A"!dv7fT0?@@4:bNcY^˺ (jDJ*Rd; _WMK]k7q! Lz^t#ΧBsA&v\7u@ $0J៖i^Tx>átR)*4rM8p|2\7AF q;~VpRABLyp\H3?Rc+D) 4C #bbLqL>3;GZRY. )L-]oJqa܋?V Ȝ&ัO3u'QJV~rDE139nq`mxTmvDM'&cڳ,qV0і$J[FDkYZPi6}&($Y9f*:5;.a4LNHiQy uԊRB-1B`&R)V%R\-4B S gLhX@DbvD&jx昛&JȒ >  BI- S>a-!Y1   ˸ׅ:fUC)rs.lArgC j2DLK! Z2F>Nن`%!XZxّ2 yeX{4a3޺rL>w8DZ>v=#VAK'#ĒB2ݖ/|lv% p Ih Dh|_ ǝWm74,CW<-`rvz>}1qݏ7 : u˸1zI';RǶ9Db&i×IgA|Ёcq{vd~M LfLdά gLo_xIWNjWm#v<{^cy¤|c ܻ`u{q!`߸8) l|aCvCkv"#;¦Bwc\0q|M`γ[3)Ҟ( &;a2EQ]@OLM^(;ȚN1Xqj^SYl@2mYi R^dqdx6Ay  ېQwnlJo161V1 A)lΚ@B&SNp'eEyQIzXtd ?@Ԁ>CE.t#ݩ|ΡQg_ 7x+rT#Zfc?F4Hcb1H!c(yg6/槯1VywbMԢG?0g3^Z7fиm4ݱqVٛHj]& )Ύ%CPR;jl$=mc$+O:_*8nf\g\4^r3aa9?aOܱ-rU5lJ@&DEs-jK0>I@d~8jOcp(]E0PQ .j _nCwl\ 3_5lmehDu&,0 PZ[,.JPI]=+6i |6^3];ژ*IGȲ; bɎ&Q NY8dko`- F g7e`le -1`e1n8jzKѷ@4؈gm"OdJXV?ja#N&J#=J@>%) ӢФu ay80cp /e5O{iԭ-FEKܨtN9vOqsier? @%Ilu1v8@o|uͬxf$.$7` \S7o]NX+]K=˭-,FS?/e4?(aOzr 4ab.⣯G/>/6 ?_Kg ˉ8~DЃFE|f㪦Q( ZD>xc#3ń~ߡ\Ͽ?O*M ,Ra3>o|<,};PIIj7w4fp{="ݔ^䬤hos70w( u_t[~FV|o_|FHn!ZظGZe jn ɀCT! Jq @Xb:rݙObiӱֿRkC;}RpEq|.i^;[ OPP\Dr.^  maZ ktgAdGcuci}nS5-Z8:ZVRKCa34,N a>00^iZL/8asap$Ud?RUibv&}7 }$ͮh+bwUO`±NJ ˀ70|L,{lU8!R-=06sQ%_+x#CKjT`AYC\kYbฃg[c XMGtJeSzIڝ<ہ#' Cc%-gh=n~>|Сд~!?qx&xmЃ>W cv?] !Қ,`܅5ʘ~/  Z^< O Sks$ePY ɺ|=Al)NS(#^ʕ=7nkK>._>yz=t@޷g\8l$a/2{r_j7݋&59q8l\ * LqqCo1~8<`+,@r(pYBs #'z^?t1p`.\#okdǑVxtֽs؃_U| ,1б!s\"/,aA,GR?W}S2Y +snb:!gcnZGgKEbiA$ \Pl68V{N4PIZA֡!Ab?gwn8Y:TF)6[ua1냔k${G|MZ_kX)XϼVtSakM`-**kp-k /G։j+`a99t?>P2⏸gG߿]z4~iC@L?L&%@JTqmpDOq?:N@zq{u}U,4?<6\"Y)e2@q(k  QI5 (J|gXŅdslg _N=}S]O]xG]z)ziu{o)[Ci%C YZ2|]PXoR ДgLrwW~ o|)>j1ڊtos:[FMԲZIȶScIʫf$ġ˾߯hV0!U΢Lʼg Kg_ozm=f7s$Y$A$Dʞ̴j?sÇ-gjh^YHJ+T57*#BvK/%`2v&L?1< m~i{{J6dE> Ϸ i"GG!-db{RUu?cDe0\دdt423 (\CkZ|h^ܛr? 42F(1;?3 ;}iH? Bd bU:x%\PSϿv.+/Ĭe5,O2|qIQՅ8 ;] ZཱW658"P1xWo:kףM?WL[ep$^9<GH@oPXdW9.GPp*N7ˈu( >D R9l49\EcoJ7BeMce㼚d2DG1D@KۡF-ώɨ<< 簿lVʝF`[n#0 =Rq j]Y#KW\1=j -"Σ?;% )4E}i-k99Ej-=:3# R EըQ"u\. >S+i@׌qzV:[Վ`.X|zEVLK^|Cۇcy+t G!vYޑ.QOѻ+@}kh_/`kub:1B' 7Qِ5*&2mHݭ_>#ϙIܝPr*zߨv}exyC%CZT.j(4#׋ "v75:I/L*3w x@g>@yєWB4?'iqٓщ@u`E㎕ъP vgwE&7!C"5q[fd1^c]O'&Ӧ?K>1svIg_v=}-{D.>XH[뛩r4שOq ɮ#ˆ>DDʦ7$l>joT>36ݯ-='@E C5gѹ̦-/N7N9: bcgM5}7r<1>zKY$}$C\iYN4j>f 2#qddgT%-sy?d 5 l3\ip5ͱҖ|q #1 {6=}d8 ۰=@y}0EYeMw IW S3לID1c̤)&[$3%<ވza‡xmcyqXί"9 }W Ky3a]{ 7>s??pnC=z?0!y eLVY|慥\c~7y?]>Cw1wyd铛~di^ h۟w.}b/8Cǜ࿰pk0}/뮭B״qe7}O{V}?qAܿsՍ g˻twu /@{Ky~jbw4!Y k^U<y7Gٟ2>F,4~!_v(dfg>wួg5!10%Iȱ(!? zʔDv'kvʸ |Su|7rUt#g"Ӿ Z0 wȏuGb`+rCeE:2׸͑ɖ+¡ꆢk&"7f^6̷6`|l/ȢYlQvd[ׯY^~_l^Λ_=?xQw_0[% >}=霳3f˜C)QxCm^s=v!GuM ? ]vBiJIv4A,Y"CQ^NQ&6EK%dlFMТe++kĎ-n[=/NuXItmOnF mUQϭѣGG.[֬:썲u~s=*nκf,Gm`KEZҪds:"5;܈4y ZweHWa 5K0pge:"Tg(l,f*r3 ;F6|!S)!F^ ϫGUu}_n):wVE[e{5TN=ʟ8if4A8sapAr҄Nz`Rmx 5nbl&^*q@:nV_M3 ؖl:‰Ȭƚ*4P1Z#{~64Av*U5Vc 4(iە/d)4\nC#l؁km]n*w4uyt,+ɹ;Ko~Eb9.e#9l|_6]ͽ/:h:lH|Ӟn;OuD.h+rɈr?:rG:˚e0߽3߹>& F C km*X@6uԄ01d-4j8MP^J@*j&#ޱ:1nA v(*))M9D+|?3P$IO[ R $[8xLu"n۩df&A+czbP'O:t#F怘L.:쏎2е:i0t$Jgg3h`7GhMRoeYv">#QҚlJ]:i9Ḽ4}R?Xʰ;dU}q,!!n$h$332ˠ!xp 8q#~]]dwgnHu]dZ@hAp] T3lץ(,+дyESh&;Ӧ}I ]rnT8j *n 4DS|nХsoY6+03RMRhپ#lCЪePT= 45_ց oU'n)l?g&-PwU5o 3h-n¹vU BǙ0⤠ "5ZYP+[][_q[aѐ+ELA{MӼ*j1hkH(`O+4"hY|JM+($G/X@Ո=R sҬIB";3\sI}SIZNt=A;_es$PCM/gKiH%R+s]Vr8x 93 INg(t,z 94RJR,jXPTeViG{XX-^5%XP4R)[ͬ%|QZ]_AbPRR)VMk[C ҵL\C5eQ9<fk,.)F)"IӥTLO:# D׵#~J}|u=J7J)H%,Z9 ?njsΑ?Ęti>%P#(ٺ.&ziK9~9 )19,*!•'~J-+Fk뛍D{~Abb-fà uNG!{A*aLq~2M̄Mon0 H&ZqRCk:Ҹ޳v" WX08k+ĂkX r^F\6 31EYc]V{wٽBP/YA>b^nU&21 ـ-x sXf582I6gBg-t'Ud\K7z߀9R(qQ$i.iv%VKvfFЬ*nI7?6j,VP2[Kee%O-*+a)^k2 f]/)$ ]? =[%taʜlP3k_HJgԄ)1.on3*΅D=ZR+*YtV-' FAظrF3<)%8`rp38dB Hb*."ɥ_nx_ )H($ T|PV"(9!;V;0{")?5#6r 68d TJĹ{9bbJ(gbMy\C$*&:ҶR 'rJq'>U?  CA@bQ5D82&Tw93$R*%r/{( '5NpdQ#Ch ʆ ^FTDgA H0AJ!Κ`yɮmh/r"Oo98)7p|VpE "!0' R [ vpk D\%x@59ZRIrK&DR@.X ) ZSBS$tlbO.r?naB^EbƎz iHȘq[sըgp^S05B ")zOV+9{P P9rbE/%'oq?;]c m#H^i =w1e 8r _"1$zHs$!58ʵ)\v4?}Ms+?3NC`.GoV Hk1g?7c1#c̱.Wј0|h Fq'<58׹O]8]w~\A(3OgT,1[EWZ\p: }sg' 4#w;w̜´c;v <o3^m y|>G ﱷbivJNM &0.^ <1>`utE a(f@[ƾ;0JA \~caο}p3IUl*6`Hۏe^1.;n<NcJYÆSvCA @!ʕnUvR5܃)ĐW~;"=!: C =d>6 jӐ9XK8눉1?u)$M `RWesfX +T ;FtXOv&=A^PRRa717@$<2n1߫A>(~)0$PRy8´$f <ϚlJtϊKi$yb3{"0$l杰ϱ[xKQ/Gg.n;DZkZ۔=Sy-f፷cgvn9`.<+M)2?o{Gﵘ7L=9?xa{yWwGXݒ[/IuMq9#WF]ңV >wnm&f5zP;p^{^λOh!I͐km[ci+_C[aa'pqn/#,QHT ;也6 KϞa#&(p)*ʢ)z+ISNo\2 EECdRT+Cϓ+>Q.%gO ݴVt^k}2nf[~I8x}޸r"ʢwa4sܒH2ņ}xyL> ^80id~|1ot{qK_1 @%Fx4Z \6GOh c/]jb Ϭ%+솕n Ŕl >ܬplxo=Qopiډv$#9 eVgX3j8y~?vo[sR?R $F~ᓝȽuB-՘N< ben9 IĽv>ta|{)FR=$յ'ay% ӽbISl<;/#W( +g{Tg:(}2l,6o wwd#su [G&ҲsIѤs4I;<2T7?7R1p׉a QhsOgƒ&}=zt`j]9m?md/v#l;e"~.ytN4/9#NE5MH|֮vC> e(A's&lob Oyot2>3h(:g C5VTURY3p=0V&(,^'R X_sq{n 3ߺ.ۣiaCl<pX@6e$,z0p<ѭ!'rYK5l=äJbW>;v<}yPle*ߩ T7৏Ltà&Sr`E%$e%O';3RhcA /;Vº3su?;_DAt!=eUUD7퉽'Dsp؆E6it\&h|c]6Jat`RMF8ڬvN FR-8y+Ece-EaѪm0=Ԥtè> ٶ6ELײ6,C{Bbǡ/[]=ԏ#g7_¶Dȁ/HC lb;g^K~E?b!xKp~#xP64ޭ3/ w=t|WifQ0gޜ=/R|^e !6YXvP˰ic]1_ǀGi)I1!|օdad#"O0$>:ynu^ҲJlZL#7pAG"ej rYMgľY'Ǜɘ>=%aa33NĊlٮR`_v(Pb'O&TY5Op30z2ud<@Z˲t58owH@H/](u2,rY~6A#'QvWS}%;`Q eFs*)Η->CcLoKveObvֲظV۞N&\7Iz5 NZszY#cPܚi1C=@@=5=/~M+qȁ摃;m\FaJ-شC_:`oXȺ@|^[ '4`%&e&^@=8{ |Pt'c"Ym؃kiA,ʃ /X!41P+ /;CՓqտwiQ[2Ak}t?Xx#l!H9Lrq¦}ꬱbץu\T?~B{FZ*swIP L)M Xf Ǒͮ;wei HIwrY/i1V{ľWS" IDATL :٘WNb(cbdC&5row%qk0D~td4yc^ U@f(UǪӘT7Vm/Bۚ*}f޽b"P|/3n4 @cNmʴe,e(O;/6[@kj7yd>+&Fh[cϫYEa܅bAUi; 4{hCp@\+ h5C;7_kAh!%tJc90h ]Aƀ"&R(f^ =u}lRe9v]2/qZMĭsz^d?5B;0DOZ RH֙BoK% %甴6بL$^7ܰ̐QoBab L_a+6f P[fYTW |O3|?_uӢ6[aiYRX$+4:&j%}v)+?TE?_W߿.yt0;TbʟLJ* ؝݆qC?X=v7mt$UE,nD I ;+^_D~!^0lt$4%"Ēe+iX|1.df)ʯNHF|Z՗i濾U뻷aO˱}m f[wf#=,TpsM qcck_i6>{dm&Z5H Ui=uu3ӊ4~tϙޠs̹Zz咉8e8h-6ѪUk R[= /=:`9,y%wQP+zWJ:Qaѿ#,ͷ?ʝvGvetg;s ^zCZf=}4.e8tDR5:|-QX'cTY]v҇T!Ql*np8nx4]<+RP`?]_ÝϮFrGǧo?KW._ߩ zVRH bͽ'l܄^kadMlp[bv, wy,2I()Ю)U.)i,#'$6aEWoY;2IX| 5t,I,ƒ-Ŗdwkev(־׫=Ggd(A0<]H%mVIvVŎIyFnŲ+ٰtJQ) |BK[\(ZF- XpR~ M@n|÷ф#%W!#eUeUeY/]-8JM7a ݘ U-)a\(]Q5\^x cNŽ~KG'g`3]0eArz~y]+B| e)U8U}҅ݯvQ 2 M11tWNCho $4f@@XsăK0h=kx~Yv|2 ;hÆ>֊RMFb՞V'{@}No9cgŧxu{\|hvӜmvd2aT >z¦MPo|/ݥua/~`r1Ay"'bBHA+fOO^W.Æ7#p-~ig !ߐBK)J6Ԏ[д*%`[aA|!vڹm |gf?]Ɖ{< d5 =ۓzoF/jf|" Fƀ'Ub5M@ߵ~{+v1KT4&2Y֒1\-!yMYb $H>Y(κ$y-I E=)aBX+fZ5c IݧZLV"{JIV%#gP=畋`oQY4k !H57`u3F x0|4†zi;"[ 8U,Ȟ˪mUS! ̕x5GW EOPݬ5W7s'h*t9U 3$"Mt jrAAn sIU#b4S(HEh{cMUܐKQ)L 4U.r0h֪]^ׄEaPQӴp(h{w@8UU*Uvi>%tZll "̫[:tpl@y t*2ըiD͹]uZ6 ┤-\8 cli{%P~(% gOLAs{3W7kfU< )T]-ȑR.e!`}}nUǡ $ 4-m@YchѦ=ZZhJ_ŇO|DRTyluUM S̈́| JtweƐ  XժZnE*RkBC s4BJBci+DK2k6c$Ӣb=e,WeHHK65Tf,)ΖB}kvGdA@%^V矅~)C "D8f'AҲ%'j[ 5ȣ|Fc+RsZ5s{TZKA_O1ԫ,>ϺZӣY*Y1peJq7"[%v](5{ޫ Ctr*4יZ$lٓtERՃhc jD}JȞ~{OU> ^QPg%qd|z,` h Z~ڣ*F&MoNN¹aNԷ{ӷ>Zp}dI\b_,dtJ5ެ32I ǖ#*]@xsкRl7kD-]wHŊqA1.4sK)L#3Q p#!56&[C&rּ`T"tO)vap:Gl$!N`uNJ w<~V G5ϩѝ!ES<@C[>d*]p !R==bXbq)A bidK>QA?_D#JdYAcLFNdц(lIAkY'ndO`Fspl` fU*gBl!*&%u'I1) 3h2RV6S*E/r{\w,FQ.)7)i=@JK)*d͌P!1c0f|gE;Y>(2{\N,)pz n(#"]4 |Y@ ?Y`A+cq萸ni|דjB. +%VqrE \|X$ԙ 3…P͒{*0 jFe\F] Cb#P&({jx]Qvٔ.٤_ f^I 7l. +{U]BWB]SGjEh=د=/m?C& FD{I)`0ɕ rRԭJ^YE*w # O9 '-f0 X7I!|`QD|0؞J( ꚹFZ wK8[6MBcύr0l0kѲ^:5.Wd5Y$X2l9d8)!9f"Y\27!BӁbk4V-є , Auq-m#EI%M,ƀlYcqӉby៏|38DH\Y( {V6$WV|g[BIuТh"XS+ԥq0uЈmDXlQ#Zf2R) z,y: J%{,ugˇ8gTY 9Cd >`䚺uv.:B}d) Npmufg5V%64Xy7Oq#3u`_AUY,u-9oUh giݛD+R`l1J=nF1ײX+T}ӹ4t$Bepŧz@mavru3~vi ^k5nRam9!Eč?ᖿzp߿X]buե 9GЁ=AӰ>Ј.=0tT!{Ca +hϑt: ޹ Qi`qCXG2 ߣ3}zOg/ʇ}xQ\Hrʂ&ȡ*EJUOS[g J#aK`@~/ 2Jͫu#_plIHp?sg{6zo7Vh̐v%L3psSt /|:z/~s1WcUscg?<@CPI.}cz{ M3f[Mדу`С1rzO_>-{r;8Ƚ.o90FR _1a>A09gɻS^;b3_z {ԀONZL[[3&(T'!=jjn(3k-X* 1x)@RW}xw/j%DM5$/E"~Dz<6au jU5TWS%G Zťvn81p爍ta3ZO{Iw&h_Μ|hM`[XEt北Ѥ,42)Ue7AԦ.nSY]'n8^~Zjn1VUuBӱIw=݂cU~v(Ì@s(.]ŋda-Z!|tsmqSS0eu[,Ř5:e}&݊XA_l˝xaX2{)ZnͩS7X~" %%96B8n9OByN]Oс=369Ѯsk8p,W cBK,؄(eI ZwHArYKt&Fk-C(6ҺVkAZeШ~Qx} ɉ xN3lBߪ9X"y=Š̸Z> Q n̖xU5[N71JMj^t@!워{"-1[gu;'Cj~љ" H$~L~38ųpwG]7]Cǂv,tiv^xguW>pk:׶ xHl:hѡ FwsvG8 Pz.Eu37Y'Xv%J{87uk:vØݲ+,/0iqVxW.a6-$KdG  m l1?G\QYI˾<˓@MRuj3*\qh=pUÁ )#=o3 CuV2& z|.s8xV@kgZK}'4/J=iw sJGrTW4^{C&"G*>lhS,$c] b;7W՟v?9#;[}`zA*_+U*ZzjdG6 lݺ0[DpGY߲ Q$RXY _ȄR)mN½ U >2c|#)ǵf/;M[w[w^⧦sAt啕h\~tڦ&1#d@"[R%XeÄ(f~<7U`%|rV@̵[_K=ga=Kۑk%˜yK8: ,C;pu ɹ ux3figy ۏؐ Ms. 3lyvch6ٓORDYƥP)?SwYc(!0XsץA4NhkYZ :K[Ʃ]J > YzHPEQɑ<@!pVwϺ#:N.:n7i!.d't`6PWOw?=Xl߾ď;| &؄oy>Oz89v#{u5&sxNx0ں P7.j0^wEwXùk();e,ՠ=hA[vʵK;_8!!iXӢ܊KnXɊ❔  EXb%.TLd? !r 2R\?n=}His}S8#0q=m" ՛B d,)1K7!3!7ÊkЀj(D&!^0M#s|Aqߧa[V-<2D;ʸj`%ҐTn*SЈR 7Vh+ݽЍn3Tܽ[*5;8oe) {ӓPh,Q[=.I&3CE|7ji48i{jZsxHgBKb'ŠR\~L$;MB>hL4AXXDjXq]BR|1VDe`Wg,m!&ޓ5b ixq_nWWnv=,|GP=y_޻+պۧ:uWaxMAT6Sd;# đ SP/*-݁10q10ڛ}T8t)Cfآg_to=ż&ۤƊ!'G˃FΣ .K?n4lK,7bo)>GcuF @VDRscu7G+iO_ mmXX;Nݩfˎ/bS)v6SB !^x?fKc @"NqYξcpƵX<5B%!*Ghߢ([0+w^s:*33!gש92Kbm4BB78^r͒XB#[h[aO+0x~oY@ ũ B\?ȃW!{-FbPX:wfZ=yZk-G%t\Nޜg"ҩQ^O(?:>~`ݯh2$b4[ܕ4 o _sl ܯmz<}.>drO>=oO9׽ʝ+tM_ͥT <~Xd9׽: e ?0񲇰8/Es`=۟E;NB?eP^ qj AjHg+ ԯey +}}xU}K{RR$K}fOQTڊ! Lݰr58 :K"&M8P笖Xd. Ьm+HWƑD(! Ć:iY"q}/ Wl=sꇷkL9V?n瀘8C$ЅOW<>k|=C:.x\0p)!3PPQTEhËAØh QIOEVV-|/ńЬCOǣwf0$W›/GM\}W}>Q7n[ێ {t؀wϿ(Zw?r za& J*%ˑDQ&)T&˖U$S1tǃ7sGzqx㳬o!a,Şu㪟yb!=&]/?6G f֠"2-4<~vǣui =ncJ'6PYN/WME^yV%A)Wp=o6|ܝO[G]]g;9,:@) syaWvn-!9spɭ~E8P&*k.<\8uY6OUiȤ;WCJEkgunI|5)h%>f-@O% HQkp_>3i=FڑR!2Q_5 Cr)=&M1IWu1tb*>Ƞ県ł˄}0EVx#&T |<{1ɻ0|hֲ5+t~1$h."ht'r0E H+;3S=$ښ=4q#VQ&Zds:EP0]4y3 u J;ϟC|_4o NQ^A)wp,?l"jٲ)>TX8dǂ%!!6Kfh kdT4iU a j׭t3jVH;e1mĊŀH^}jhb~\gv^Ag֭^t^Hr0bf8QXks2Ay~&P7}8d " g'MQQ8C&1g FVmDMЪ0NJ 9UbclX*Aw>'ځ(XXxJ×LJ2}gHe6ua%hR!TÎ0*)U^[`fPajMsu:( Κ $^& ӑ$ZZ&k*Հ?ա +Ӫ(2&&A$<#[:$}H$T$`:48O( ad+GHJ (#!,84Ik?jL93"9e.$2qg +& 'gl-)WEaęXAm,]%63 V"mR+ +i<{-ZV P=畋`oQQ4o*/ MXg2 ^t mڶιZ6b!.ҖO'(#JՇHq5mҵ_|#H!@W9q+дyG тI)r(?@,bu,$8{+4NhU00Ls+kj4H(H.(1!KW89).ZQ@}>0OR1k0yJKwFU*3F:נ>lIN2ps{ cs@Vf(Ǫ OaeD솤U+EI.}}67b,g!-`L}C^Źb$ kb;RS[C0,+KC/~FE*&UC< /YH7ڽZ($fًu˩2F;YTI%8j%Ώ* k*EL7=,X!j:eAs՞]PD"X?8"bR,P'Vu]~YÖ}ZA=7qWKzYhU(̤eR`1,itLtH4HK6⫀缺 =38`[©;d%#ŞȲAMYKg j>VJ7n,d:SЅc0RER, "& /lƯXUϝHXY0`uu/|f68ra3O)5 a=pZf;TJ7[l ZtVKφс+s LGuzD" +PS'UEO61q1em.F2yLN:=\nRhak_Z l>qՉv`U@G[heTB~!vh[ bh* G~C4 <;yn+]s uo^,t+g/RBz7s3_66 A@Y̍ƄI} gg ,gےȋĐ] 3X/O"vJJӸ$DŽ.ϖ&̑Z8Et)- 7AnvTlZqBRCZx}B4E"!g$Hd3jIoB 2E \RΤ<JjW%-H"5HHN-m)?@d\9J<]IzgS#S Fh-*RmsOUH6`C-Aޡn\2)7RZu^|?!Ύ%@W%R\ }&\r P < fAOQ2eYBK m8>(3ņ i̊hf5pɳZъ),TR`bT%法xq)0,h֍ XURa.IS-ţ <]ؐWKn wcц3QĂ2xo2}.Ebz2h. bKF&fX]+VшjV}]%Vu){"!- ԥׇ CvUFڴ"-ޣF"f"_Fm F`PNW`  Saˆ~ԻO_z P;G]7?Xt{At/QP7ДQS4h@/tp^u-(P8pDgs =Eow9 ;c iί]O vP O ^;v&_om8h`ݣn|'_6;%Z~}T }ݺcn%q,ؐk($T]l\ؿ9.1}D(sE{aԾs"} .=; za)  WC mP׮om4fbKj^bžG|ݚwQ%tg/f/akFP}y f9k[(LѼ]ѩ`:k>9Vk]^w2hɵS~":5Գ('rG,!"Z>Ѓ HC FN;ҾKA`ɋahУ@ӳ;q.f竽^ =+J[]F֞G{ ˿{Nu <9 ;JԦOt}ך/Th-Շ3P,wKj%}؇d޾ ;޴g ᮉuXI`/Mں=6UE _ O? L9Z[2~j<|=ػY;7ż9VmǢA"C:0(*6[LJבaOv` !@R1k@y34]:Mx1Z|7;76˰r}:]]OGD+"$I"% _%GRkȔ#P <ЭktZW[SD'ޤx_Uݤ(d\/X3@ Κ.(d3U]b,HFdbFLl6!s_;Y!*AI]RX~J* r%)j%Ml J/+HVGQI8rAA䒝"S5 HL/oQw&/)ToׯǗ}A8b b,>l{ā8FQh>yZӺ#yeٖ8CìZD#6[vHۄFtQM;`hڪ/Ծ G?e B*m'vJ=J7X?5w#A 9,A,ATPDP1Ɍ(* "QI"eީ7T ߟv]]]]u4Fᖹ->WiQB[uUOWٹosDj08 ~/uO= ߬ t'm)\aN,ܓ:bUC= Y3*6؀~8Z߸h*׶D:["XV9 7W2Ř=v*֙4mc_:Z%KߓH 5]WV*сlVd)yI$/x^g)A]cO4җ 0D4PΚlX&/wz7tMBp-/6Y6>\@nf5%|h5%pl7WTPQkd5K?#Oo1LvhXE#(fdfeQ+_!qHi8D%'NH$X== 2D(p  F3=?JKrX&Ӛ}, BBEWbcYJIˌ {=wK}ޫ5ulӌn_^<e{O3U=PM0kS[^`8uץMĹ+QyC N.| /Imr㟩Ьƌ>F7#̓RMFA"$iP#HXivXTMhh}E4I~ aݵqC ¥U^%г\Jx|.`kXs:܅ g{44 "[{tvk)*F?@Jx!$٬VPH $^51c tUKhs]54AuXc@D X>#q&8fR ?M5yظalތ7Ҷ[i?{矽ػwM[ErE`6QPF/B}Nu y>&3t}Fk0l׶tc+hG' 0s P'oBwbTG O޳:ι|:柠=~>3 É_8 "hw<7@q[u&`gˆA>M5il&F@G#BS)UcvnaF'[\_ecu'mڠ9[bD`DZ׬Ë\M@R3 %xlf NT~7<'{YG!,,kLe^SfHy>'ׂlWD.\\>kwƵvM|v.UZq}FM}B`Y? I\8r"8qU&-S=`|on*g^g'n9"mt>C "d5^GBL&B4I~P:'L)Kl[F&j'A C8=ŢBhAiV? }4j Xl4D!5M&VQwUu@C'MJm-M/X4ʧz$WIyǯeʖ£G]7%4q|CfxϖۣB >x@-x0 acm*ԂUz؝E-dT+o$ڂ i& = n:oC:{o9^(&u؛[Ѱ4|+Z>_UѮe<~ϜxZh׼^y''6[ "(*A>WHcEr#]gcД7qkpYК)5L #rѬj}H!QHP˓P,%ym{!X Pݍ pιO@ךuRGD<0/o@w}/~,N+Ȉx^P]hziY`S]SA3V8s0{^Tu*e*ϓZ{9D~s6WF^$od3 !иJ&uzQВwx QEQ''IHch"=Aϻ #USCZZʦh@kR6BWLoap@N&lYҶ踰_׊0Q(LmҰC M!\hTVPÞ˶ϫtX+:MW>- % ֧CldS>A/c10AL \@`*سg΁As`s`.́ڴ5$XhCX4̬ldeHtu ;K*%H& 9',~|fڼv]{lduE[%R>2-ʿ$d)ŒV@7>U{]pQp&P!`-҂6zlٻta;иY%,Xs^\MEMQZG^;~N6Ew-: HҗWcݦki3*X[i+Qg"7m]d(K$^)8uF*P, 3^ZW0-ޔ `茡Pk  i4CKV<Od:w_|kl+<Anʋ>+ .ۋnd+됓oDåc={gJ^ p D:H|RKAZ -mǦ\O-6ҖuДw#Vp՞DS":lȐL $dH"zʮv۩?_@3yNן K_g Phڏhћyfnx=vI_j%2IkJ>AK4\!_$<"N pͣio_=}FFʭuY<]JXWP Ds>yezh?aѺ.щ*J 2 ԠW04Qg*+! HDі?KG|"Y j$&Y*WJ H*Hj* 3s1W5 %) ca3eƅ@odʴo0#m"rguB&7ٜvA]#aR۬O6 J1bƢŢƢF)"-,@>\+ 7>ct  -(|^hnܦyJ@.%|;{KAwarEN;PFscIEcPwa]I9s]@X4i\Ù_xv"vrA8} /kES'W=񗱠kcѮk0sR?<^ j1z.@1>^)v1~}"2Q*BOĔÃ\(ט_6uEpfh"kh98*11ۙ8^z'[9u#> ?~+J+9MxA>/Z}jo{Gf_&+u G P'iͳqzb4::XPcv/+v1>pC'~!A ́ Ίӡ{*N@3acGqӛ98xxP=_ݿ|E_"֭YI.ƈ2E  G7~E9edu.}pAC5_ 3LƷ1b=V\%cp0~ckT $ig415Y,RAAo $%zy,6Vؠ1,D! b:鉅N0&ͥ XVVE Һ:\P E,mjD' ] kG?D w2q gq2jUW\.X >x)t3T;6VZ7Fq-=q.e";+x^7]Z]d;0$\]' #O%7hA8WLnv0#z߹%}]͍DINVe:q]ˋQ>QE$;2ȯib5z 6 [ӛ $Z9܄F 8ZRHF&23H`< h D,^4[0>,)2}lNjXI.1R*DqI"pIXX{Dm[6_akkEqq 99ОSpD)(3Ww>dbQ |L].Dw.(?b'PfSN>vlS<|s7VRr#'t{r aA#9,Q8%dd!31mC`K TtP$H 6{1dXv|k.hhS) l}6h7D%hֈao{;٢xѬ=zc#Mdc 8$c3KkRaնhE-;{vNx a<GEǏaߞQnNdNd) CQ'FJ‚p8#\oӵCX;|3 8k!fKIl* /$ Ȧ2 HLd<}''s2ԁONedыo$@ņ Q28)66L4%^fFNp 9mwO9YPݔ@K!}aUgqW6Jlxf%cgKX*@fNN@yJhb⑝\&F=(=J*X JZɷ5F/a ANHʳ0ΜXJdDa7.5OOA%d8{oȌ2782]Bq"ȉ퉑Ҕikh{ HʺTz?/u2('7#q]99O TQ+$1H 4`h iF ̫ .#ރ􃧤IgFȀӲe]|7 pLRR0OB *:Bf=>J 0u&:ިAq}]_PkGt*jλg2Ѥ0_b̬Yg D :yȻ|kױ'06v$/H^aMf f nΧ)V,Ϩ9L>s)bcq?(`aQD%9ael{02B&cۄt5 }҃YIq0 7@(~_U5D{'N{#WgVn$! *(1My I9JV;XO7\>2ctcN=6ТJf'ރLR]z֒ȓ)IلޒbTµK OR0hVH P *Velt"@`\C0 \3y\4QJxEJwP&CYG \ @4xm"˗pdKUD۳7 P?Kd)X."tj] @P @,B>ҟ_<WjvY Ak! =k)lZVAr``Vʪ|3HYk5dMs(W}G',%;JҚ՘H%a”[E薺}2+.S*>.& &w ` &ͦ.¦WڬX|>8K6TLWj`HY;Úu!U (P03|Rq:)cφCR$PE PmbbžEcaU?>ԓ #.k=4QC`B-L|T}7EE4H{oTõ 6^$AUS2Aʒ^9`y}C5 _ 6'C|rsV2TbM!If96юIeprVBU=x"y@N,hC:s/Nbfw{jJ8ԂdJJtŶ!s"urYR; 4tfhE xF+<>ɭ@dzsN>Tʡʸ֞Nq "(7aKveյ%=r7Fk2-X@*Z·P}ϠdARjК~d+o~E<\:#~!lvc}.#]6}3$;|&Ѱ^xh}&w6ߢnl*Έ,u*)S(MO u1r; 5`SkI)83+^TW|~_a-tCiNz5bp@@B%o!0ݎgشHl,g |2}ͱl-( $T#Sr9Gw`F}tB6V+ࢴ4~xr{z !K.1C,e2FQŰS{+JM4j(+%% IDAT]%uɍ.Z#V5W &`IRr ؔL;'@մJyMbp݄ 6ωeY]6k4J(K'[awXz;_$B m_=Ӱ*k?u;E MڊW{A 4(" jx-3*h+amlEˊMה6T5v(5{jԂv+ m!Fihu[A5I ti\`)Xm}^7$dZ1s >GmBiO6|GZbil1:S_,'#p3=6 "oH?gmc uZU[*N:[D3EV-дYģ(&\,<YZ4JWgoj׮- >| rA5MBvԮi>m)vk~l&N;wN]R5РKɂЭ]>9)!h's輮hѴcfa !x>z:ͧvmۢX^s:P %ˆ/N˄UԜKP j05hs|T-9DشJ4WZ@7Gfafg{8 L ƾV{6kYԹXzBn=x7Kn.m۠Uvd| kΧEӦ>_) n#UD@4Ἆhִ_=6#Uo,?`<j7@;Ep } b?N $,YbzoC-[t>MT}=DԦq j۾ujE[?^1m@o܂ͥ; ZhDd'HSy~]' "޵K1oW4}*u5Hfo &$݀0_؁p%l'$$ ]JHx5,]`A4BOǤd94d|/Sk dIjj ڶúzI6aسHKQkϒXxzL A7Ʀs C_gNR2C 0 a CوlGlNs.tU_Y.l/Ii8h57% 1{Jd)qע$g0f'rh =/[1ၹhK1M7Ӥ1>*ޟ֗; Ω*?ƁhCFFwe׿MW,7(~0xrmxnY↷N܁a}cB^C,ۗ܊qӾmZIaԆ| o Ja9d̺Ϧ⬠0qɭKghй1-PX}8; x`Q`'{HkBH"(+7 /#0QХ p$hT=vG9 g7d|h r9}>tޝvsD~@&%?FOOI>Qb<-Mdo83UWOB"- p'~RSS{U?Li7JU" $ع)å9QHX/bL *^\8ymT#`Х|]؀: ~q@pL|q (p%.8vl /|J1Z$6.LPW6t1e ê'"Fpɨ4<~+zX t6/n0!_ppgL }j*%U\/j dKAfHy2=Jo#AS-BHviGDEkP@Zg 7OJLχL16 '7^4 DJ(4A e4Hq9Hi;[6}b?PYsMv!"/6!'Cm]գ?(L<.Rl0+{}l)je~>Z5jǷbіvl@dVi 7-Z֭wP0 qF3Ąfӭ2̭0u>8ilxE$MIdqwARxT=\i-PPG!氱}l&P08#-+ɰA8 nl@NRc%>~[w*U㜡wcS)PM1||fА,!$'3cFhݼ?9뛥XN>뿼/pC(,Qէ8wce1[S7ˏO\a!ئ ~}v*9D6Ag PcCxB\Z cQi?,xh0;԰LwVOljK|mfJ:s~F3S /▵xëYc]Q\BF YX젰ْe}\;ͩ~ J}ޝ$Ǔ]DK8xWѴpw2c.5+Ec Dܨ!1 kiдhaEi}ܽ{'ooeg`mF}n;@Tʎ13rM1lUf>g W wM qrZrb%{aIu9,YXcKK( 1*+yאmbYp6%HMM$TeZ,nTؖaӜOC.ٰ>=5!H1QܟycJ,5{eզURO_Kʶ Mln='/~pIM%5ME Gv僘tNy,5 O>g=}%9x=€1A8=5ڠADr=·'ǡJG|~ eFSw#sV"3W`> ULr ' 8|:ҁ_RZ}C}0,lt f?o\Gٲ'/i U{R/4fb.(#UC b="7LDZ p"F*Qk> x5q m%h$ASO_cfT) ux2yVEH# ku+uJFnQg-.ovdSI& FK᢭/MUE8& )A5aÜi{W/[6FZ_Uz3׸?_\̜=Κz::]eKFLFa)f5_姓N;SpM&?"QPK$Z68p@0ڲ>XI" to.x(e)DUQ\7|K,ZbQbXtH hz4B#0ϡ^>~},i]6bFnbC(*CcBHI=67,A  *.E̟7/Bifv?P/TƕNA?R8~0pPEiĆQcRN1oW-Ý1c%m)VP\0?1p:T#/k_yQҷ/Gf<мNeu5̹bnCURS^_Ng}'O< 12N6aJ$"lV'uV`^Z_8zT.p 4C8rX2z7ڢa !7,fsj![̥~ZN*Tzwrp/LmH+>yseF#uz͚Q%y AiB'S[N ߯Y62 Nl.U8buG#'hڤ.>FpnsoSD.eѴjvۉ3C]{7IUѩT oZ4|bŢ{0]/ߺ$,OFS4^ o! 6 QSIXXtזƲebLB|RoȺ,69h#lY}\I<$hוBWך K5bM c"V?wxUawՎ{TRLԨ!#dFn|Q#?{&6ۍ7>ߔo <&_MɴȖklJKVPxtx?/a_hQ=-hoV#& b{˱۟3c=?`KV%_͠@,љߦ]kY<طg. EQ<0_ 6<<giu"T,YB=PazWyήj1'F H)ء΢gdŇ j1Xa2.r ]J,9m̫5hSv6 ٦Mt4lq:< //M1y.Q]pś.n9nmJ>ū \5a&"W;+P@l+/ {/$f4G& ޣ/Ϊ3^-[>rz7>7_|=|փ6|4bT[K:E >8a Χk$8q>#Co1uwqDmq?H/c2r({/>xq{=Z8}$ᑣ;)7{,JA4-3̆-߇׭w|~.;8IcI'#DL|2 Suy6Y%vo)XC }" C蟨j:T,}QuDm(%[:;J6HE_5 A,A  HTi4RD2䓕3tMׁ--a_ &YUa*hQ{ܿ!0'jc;pqϗ]2kę!; xc ( nמ)G\27;/G6}<‘ `֨|1Qn#q4d 0^od1{18;MwFb81އ) 0[f넧^[Sn)D㵇F" vi%va8R.g'KǼʣ Kд>1-,nzb$gaM (sxLg,,ǜ j+ݛxs~j>Ƙ~D"d#Z<]Efwp}u\d4 Y sh7^ vl c`'c>-*)`  t =MBa#!c.l@Ȗgx&ϼ I i{TҰuFD`a ׅ- {!q!K5D.x(15qhb.|5:'-Ԛ ~&x!*b}4r^uWB>CpJzIMU4m gwP0mYɣq T!yxc P-5N j kq]vE0" ] /i t=E.MIM@[%AS}x/椌aH#eN8m#29% +_қ_ֳ|ɰhC6~X Z7uSl֗ ǺwzWLF6A{==tL @E@Am Vgc#5~R_hX k5 [Ӷ1;> ZYaN&fɬaGqݷet`޽wi}K8WEqPtى5kᆛ@<;M] =FPD<86L$S"@VM? NZm +T#)yKe$ (늢vfKk2DR LY&QȢ]M.͢oy ?4lS&?מӇP9MT8^&KD¤ WȦY`mVеwClΓ(C-ú4KCRd{b$@(~@O1 ؊ ʛƦ?^#9'fJE`h TYV{ ,8 D}I`LK /IC'h{!z 6J~#*)ȴ }RϬ/HxPoa>((P&Ɨl8z%Z_SXJ- ӣcгBBdL|DqV:a[Ul|&mDBTYRĈ 42nh~PwT,C0^)2'VEF6N'4,'RM bʳyI#} {lA޳i03Uz_h 0[>N5A8umdҞ@GA_7R0b_IjWYK!&,i_RZG8h?7as}ZڰtKhyk2ռ0֥D7 0L~mczR!c lo)1VHsHëe'MGQςS)HyйKS]#qiTX1bQ :壘ɱ3 A L-PB&Ռ?@9 [Ιg ) T#4)Œ9 6膭M IDAT. !8󬿰P7!JMɆyV׏gQ+G_F]!}NDU%imz(_|) РXģfxϦjF -$cy0ٳ6,0ɯhAlƲ̼eXRωW}oZSlrcR&Sb˵ h{K{eSǐu$ﹷnH= a~ӌXWq$ T2^3]Db4^uϥ 8J$,Ti FubmTzitFROdג9hqb zJCп'I/%pBӬ-+Nd(ADb*L ~Fݬx•2I1Sņ{+Rtx e4`X0eDl &ff`h` 6Yj` fTrD!|wڵWuQ47gZ'cBp2 %!PN`j<&hjZ2&IòLQK[$۲˕xa ߃>BO' bf>1oYvzbWlzxxqGmHPYaHTlATWl[!dw$9u~:T*" lI 8 acRMFQ\tvFV.3peD$Rm 'XSVgTɧrQ1Í(Led &7vκ'x1l,$sR$8į;%*.+EFF.f9#mU#3JyBj`RRx%r3b.JO4!!2 e8N'D$OQ? d";' ОԯaR43ZJ˓ԡ&F?HٲDUA&\nI1@29)nN@ *:@EYYq !$%xt,g$c8Cr(Rٲ9 7(!KήDD]r93 FQmT.|.\W|0͇Q l*8x3DL'Npi4$2PL6uCK Eq '99ى&up,0CuȌ1٤W[Ċ~(sQGאʶl-,Y Y3ߔM{eƅ9s2NN̂m*cJ6/$T3jBi+gZǔ|ccI$ =6C!˖/0QO3 U5`wɎUB)+ԦCe3 HZ+*ZJGdX"ۧARm2\` R_Zt\h[h߹ ZUG TU+1bL8N/uQ*k,{IѪ6Nm;WǍ7b_ԣ#[ycBӸmky:m a>3pzܡKWtԯZkx08S{nKn_x_„>q~ih۲-,U EzߝL&ٍ诘=l.ؙ;wh ǟ̻fF箧{6(W:=ʕ"`Z ڴV-Z9Za# n9гC{ǞK9$w-Nڡ]8,Okr՛rhޢ>ig%,IP9o8kL= ~0a<PItRf쫝'[2ڸ-;k3@1|zܾ= ڴFas1,m:,@Wκc&"|j4ѶM+t=vl)5W>O-I;GڅhHAsOi /Asʚ%6=c@"(`"!{ldA.˞> t ,z6 &;TvBAmٔx4ţ'ɞ"zq/T1j:?;Ae/S؂(KL~.v:y=a\: >?.!E$<ԗLm`{QwG1祸<>~o5%N9\+^;D%i 8yځ{j-rJ'dTlއ+F? 'ƮHL)5\fǯ>c<6V} WoѸV7|ps[_ps!"e c8g,}m{=.=rJ gwe1Ulx?O`xx]|r6\JЎUnމ1^uƌYŹ_=(InDBllnІO>Y99;߾7ƷϏC9e}{y]xSLYDf ]P9"=j4&A(%Scqc`pW!qqF(!>'PngphDk'G<C^@dxQf ւXC_kbihX}7ID:LB!˖Dߌ$AqQa ͖W|sPҶ-G@v*R!5 NrJ&r:Ըi34]%Fq_L&2\9j nxΣLJWHgl\"0C:,,b{Ԫt 쏟tD♜ M0~4:=j7 =v rP.>[z.?{gdV(#L2M ٪a1@)_~8 <U*`q`*f lZ]ŭƚ%k  UkahT  {1]ӯ@nn6l| ]v&NK#A>#_:|U*[ 13KC nklf3LIy,xqQI1Qu=ur# oȀlU\A]߳\ xa'dlZ:tΩpR;;ѹ?X>-j3 \Cgf9 KV98KNTC8uoϿ #Xu1HnҜLaOヲ;$s8EÙ]CޕҠ hsTd}$}П mse7-KnW?B{4Bhϱ3牻 ?ϿTUZ;ZxlDA{K/&(jW›'LixҸIsUAWyK$3^ jZm:z<~UK@ ~Os_Nl8j$9,bԱԳ}ڻz9{W_Ws׵)PFihWKD!m-js@]39&ڿ;"< 2-I MxZ]08QzBSĊЀE4̹9ق} ("LMzͩ˹tɘ[TN8PjoQDK7v~io%`8\ס A_$Fiɑ#"aˁ(jUGѐ/\T&ڟ3_ :Ͳ7Btյ5|H" #|oP6H(c S$~<+*y.y|״+!L .=_Cd |_JỐQɞثaú GX"Gϣ3%:g{(ϒ>F@}5Г}z2})'|p}FA#9E4JzC:q$=qÓqc1Ti-S"9N`nzzݘe76,EQvB? yȲQT^X|&Ʃܢq )utʨw?a +xt@7 D2 3fV2YШ [Fg%r";Zќ%weї|OӬ#[PM>ώw!%Rdf˻{K[unoYP`6<K R1nwn9+[A,lY8depOg O0+f=..#ЪIxDӈ*Q2R T2MկCDqVźԪeyT8Kp~LA fB;CWNaTD$E0ĬdH_A'0'j (:2@E,FT֠ߣMhJ)$hwlûSY(LΔ|߼oݝ NT bTd/s-CRJI\v&C̫Jͬ7JNldYVB$ c鶭UXTgi Yd$*]}uX_B8@qm]`GU18wIq%Kѩ^}k6MbžD:Gq@RcݔH Xq OWoNכ$g64VCHKEG? @"KiG24[+/xfm,2\P@%f}uyk:̣+~ʱ\Z29NW6UXQFvn>j׀tGŽiGT;ϳs&Q(m=U3D;޼Y>^mΥ楮ԤvEw?p2f][7ҡ*-zV;NNe*@ފ,esV$=;!مw-Jͣ _rފgE~W"pKVQԽb:#I?Eeס3qhqJ `"~f,jH29gʫK6kDco軝DKٺ130b8V} 5ĿxUkס(AaQH>> >ATNi?}Zu/m>w<mƖH}ԫ.5qB:U*NDŹf{4_!.Ud3H# hk"jE  ;P*`E7 Y3@@c'ʊXB.AKX2Kf! .R*\31Y2ncJ/g2PO߿{L]Uפ2~CQUwҹS|߃Dm'ͻ?~yA{qK^'>#qx}y! p }}YG Sh7~Uh >~mxŷ_6vHb=šHED? Hʭ.׎G+̫~\ [ q|^jP ji/WoQ%c<+>Y 2w[08Q2f[c0FÚ4J%ߪ=ލ7;~zS\ BAT7,MN/Lqx+'߭^}S>{̅8Aʺ=TW֖y`gu8\eySnŝxy}؉WHpՐMxG[]ʏ*KF?;Nby~l,쒖$AD "*((\ŀIP9,,lޝ91O3 ̞]]]]4l,y L{ ,[g33FXOTDSK'CwϪa߱z>k~} ?V㾬|俹^QUu?[UEeO{0gs"=*˶bu/1*vC( T{͇*֞ڞk~_]6g3$ÃJ]R,`K>}G/;k9:vяK{h c1 H WW845 s^Fd Q^Z[k'vc͖j4SO'݌ p"o͘Aqd|{d:|=h >XfE˰ZO/uMuPzWzO{CW,iՙ"T (p*@Hej5:YWedS-OYH 8R F߃R.$Lx.M6i;8d93AtH`v$ B*d{ Z::=L*m?L 28h1-|?M|k,lyOBb6bm;p]AT*Xx9Aaeػɛ1Ll@r:qyo3Ê0j :>!>"W-n0:N1&*JH p8 B#P$"L #FfD:'LHP\BNWh EV G l_ȴAyΫ{.z.[qWyqP9k0Λ4\1{l(eMg IDAT5Z^C֐ơ; $}BB|mA']HC/?a¶{ٟl㽩_Mk[;s;Ib6үAU 1ę'L;֜pFz#c5\×\ T$iB"ݵךSe:H~ԃhY;'VJxJ3ݿn?ƸDWk~ k? 1i-l+=iJD[ׯB MhԢU yT09,!|Cyi GG!U@t'pBÙeCGu"RZūΤG*e!2Z ¸7[ S"3GZE{X^)T62^tKGb#jV3#=hؔ1 ?`( )[f? tR([<-ĹTotc޺J =ƒ&Xwn jO=":Q|6MKV5+izkXq:qDxk:T>ѝbL]oX҆5bx4iA*]+Fc ì+6 5!lHf]=9)ӸhWgU^^3K`ּ2K{gk J̗̒ߋ/Ho#@cgl! XP!QZҟvMkV3=xz \{ISڏ6uRSNj>MX#Kp}Ph߈E=a&{&SO/1`n$K%dpc^d+ J$.fp`hQz^C <)%u/`@',8l!7.ꩲvR %'oQiD_(l(lӸAyxROuJ3 YcgRƒУ>7.2 To<`rIâ`+.)!N9S^>CZ{{aZ%HTzƤ. b*Oi^AQ [8gߓԪY_g}KxW)k 7g}QsgxKM߈@iօՄ_"{DH:cCϰGL!3))4Z+I9'k>>IvAJ'8H |>XcM  &t$%D I' @gnBʭPGBҧ+M wyJwdS"M sGBlLNn`%()zNjX=u@L:*2J)4ʌ*NovSL/s0W d;*p59B:vq}㨅I&I>CZأ_%ˡ8+1x%b8HIxUט?0Ub=)",3QH pB،Ctc}jߔI=Y&=tϤ4)2AF\{P?쫰PVB!l!!|`VQ  eҡ,$IS 5,=K/ZO:>?uhI3Mz/*)I0k I7Dƀ:(J9cSU_KG%0KT}C95At$ :'p/RnwrܸlU1(GjNdB(h&f3lt@"`<(/`$!S*v+R(s>)'ze#]JtT1lX Wx sR:eeE{h 8QBHJGVf:-,EDLc Ra>uT U68L' —I "mVǟˊ QTjfu,)%YܱWWB0#c'؟L)7,|xOXB(?uՄ { PVZ1S2)3#%rōLh9'26m)EX"PcEáf]Gt̀+Q\\Uٜ {ƒ^NkmL5d-%'T0rkI qT^\eጊO m 2*)gFN%IGIEC6ob#1K`RTSSStF!@ volبW?`;P6!`9G袮q!HsR0OmXHbIbӺ'nCHb`YqJ]>ojB"I6%60j&%$ߣ>M56Db)5 |}Me7B }E ]X$V}؂IPԌAEQa< 7g9z4=D^gK#M\Xs\GMx '&^=őHC=4k8؈ju W?yiOiu΢~*T[cXvzJ|EIx.ݝ]E_l< {yFOGc'u|u"}1s6acKp ѹqR;IеGխ':|Ç/=Png`[`]RzNh"QH@hO8֎rئ@" B gvJ=@˛PvN4`@o\zd/CjP7r̗ r)R/CM ,x݋z艳GAo gXG7A^8<#0ArcФ0zwZ WEa 1'=$Tʏ*$9B{eHk~闼9ϣo|G=ܑbݮ=XU?5?¨1/uӱan2Itؤ$g"5_ʥ7>G(Q {;n<*,zu(7Orxrj|;u f5ϯ* Xn XHTUg9̖W xXr!nn74f"VX'p.slkvoYg =χx+n;gsc#/ŭޏSgOߠǾp=oTWB*i_I[5kx?X~Z%3E8cPG@ѱ#Hju3m۷mInROM{iXӛ?%yl*8#*@\\q^>Ë`!vW@$ARB$/)$ G֋zsĘshQL; Z3 gՋ%פ gLkܵgZ#&M][+>׺W4 //_AxHb>4G'̉Ch\ f곹\~0wK^w(y ͚.C^ɷK8?7å 6&O/Wu Ow,0u9o )Q1xť5kpn~|*gxD,n>q7~ ]ߎ"R7d x=TY!00 }h-sQn'>=6Ecۦ݂G{^Va>VR9+]|[?sEz P`lT4V=ʺ?|rZJ+<0qX8 Jʼn#1%{85NYPm?dIPAWAQWWC]l2M'W2H&D>N;7Ǡ~)ϣ_dIiWVc2ɘty"HVT))>+`\*jy,.';HLӞXa:-{r_ ,u ?Ǐhal}'Jvp \0 yh(]o2x 5$ C ZCH %UJ8h܊;SFuA{t4iQEozy'4nY\A>0^ fXB< e`#GZb&-=EԱ\0Yl#PUn<'rٍt~6L:{xqt i8Ѯdy"JYcOlG`Tt 1+|jNqD5E֋ gw =F g㶏+:$e(QӁ!C(yA4 8:@~\̝| }5m;p,A(Od}F߇QhvNxl}y@gG|( b2-fSSgBsRbbLeS;IJ?>W]ct;:gBi}sOނ@+h[`9PrL|35Őb]I\,8*)؈r}deQYY Pmu@z*~S(:7\@i%p'cG]`r]aU)J!''8F\B݄o7I`rڇ Cꊷ͝7Ҙv>dYWq pD:(, :P/y/>,+}'@~.ˍfgbOpU!:bpiTtB^%iÂ`Bk6 :H\($罏oG#p_CS_[KujRBK ul`݂m"M:{KvNžH\;BP1'PSt4٨*cw4IdWbS0_`#z%!.5]j)I(ܽTI]!`*<ă*$`@<;/=<ޝ ffaOy"%!"&۸@R›13Bhr}U .9xI.YQ{xm&*4u7÷+{KjPP2\Q?#8Lc?Ymp63DƱG"=YT䴌4ΫyӐNff&\ YlΫƩɡd3n^' yyH _,s%ȑ gHe|1N륧&ؾ<ķ]ԁo<ƭ65+u >w W#xtR~*h]wF8&s[7-l "i`dkG77/NK w>mkƀY W]ǫc`Ó9oFsN8w;8ࡨAgʠtw({38e:zӴK,P,'Kapۋq/ IX*{T !VZki< 7ozq~nLW2XIS+5`W"pj;x[`ĘHmbNbޛ/W?/MvM7*JvA.نlR ]Tg v'? IDAT/ax⵼PqT9^o{JYԂIֵ &!(T= 6a 0&)x(̮̅ԣ2 A!31A" O6&{M!WN:ЮNq$f:9BF՗d8؉~AJD3Ðkts'VԹgW*4KY~ "ALYged@4X%"ק?@Z{~G'MÍCz~w=)\ڒ$f-ȸ$(O)3W!Z"n2o}:]*/D^]PB|hSґ6>:o|nD^q`dLk8fz-__Vo0?W" ¼/s4_֗O^6cgOn4LtAP/ !؆iLĊ#<} 3&_oHý/ߋ%)M0y<.TixɫtXϙ1-B/a9^zx6χ<LSo:^%[1yȍhZ}Q F?8__wK%>s#B ׿+HODht"3>Dy/JyI%́W5Qb?4dlB63~nߘ}?M|k沀c 7))jRΊfXe6z>WD)$ZvjI*+Z)Ia]TRbUjPf&E LXVDƆ[* "t"XZP%g('41JgT@Q߄SY8$5mlYNXaV\둻f Cp؍K\CN;VSSK-0x61aa;}XF ysU)Ee#;OUXΘbnui - %01! g i,)9K\QBh.ߥaUa0ն\bW;XiOOjELdER&ÚaѰ,9ڔ6_F+ 5Ei&Lj,kÆ}<`m\P7ٔ06$T9܃J҂@!gq59|Aӱ~utCõlκ-Я@U*!&;$(+Rk5@ t9X,T$%wȨ}ht1IִttHdX_oo] *n߽/wnBHP^ZQ?Q! %b20aQT #I˳QM6&reO|(N0y-NYV3B8> a8346g"5(2^0uK-QG65T^2q({IP#SL}XMzMnZ?n~ 0YW{pna=2l!^8(:p7fM?3T(̧N ),K[_yteX2^QXX)5NšuHy^B/Ȳ`Z)?g!YV<@2釫1v}TEK=Uh{ nL"nz_Mhv.`4;#˯Ƚt=r%(NTB\jѶ`=XCWD6 ;Tn4RgZ SP@`{-tbCj ܣ ]TI,hRQIL20y_# oJ^S&YnBE<=3A J-˂eYZ\0mM^Q C. [O9o~8.Yhcpwð?y,ع16f"X:|?} =l$k! 6yTs,k-DAQ[كzVl*@$@hU+Ru- Q{z43-b8Zaz3Ծ10"Յ55Jch,R=I;NLJ#9KDObDKjgt5G{K+2X׏֫jRRED9\xz^BVn6LSw,` )|C׌MqYm"|kU!]HRaHܷvځ^zffy/tISfvZ&6]i${0f05K/5KRo6t`N e0*>/&@?E!Bx$ `b 0VMڵ)Y@JnCI skh\jj5 ͸D+pHM 1h8\Lky7jj6$ 8$rBMpm@}Ia9h H5H $p QCɵTap"kV$ZMhIO_/l:d  y̆#=|Msni^5ɨ%ِ ^l0Y t%LyLIP]:p3%wM+U`c kG`2ŐTes^qa@'boەտ+6aq@ %zڰI$p}& :! uQ>eh p:(99Em \ TY⻎ 1U|g/`* 2ⲉlF"N! ۉTrU{(\0|)NIpM#AtGA 4Gs· _U8%T fe \SHK 5*z<E|o; LL^͈? vA^'PY]1Ac`7d'NK4$_Jj`Q<؅!A lC$!@ A'Q`"іm).iąS1IP%SKlB{~/UwJP(7AMqZ곗M:Ht : P8a8;84Az1v!X X{q4@6LSjC/1+]4iD: ;BW&:Bi="+u51.E~ 0,s?'<2*1<9Y-D iG?G.j`QZOm(p!^\*q$"Vpx)9} }"wX؁*YU%>Egax:ctXq23̺>3Yy=)VW-*-wo1 OL⁴ {Jl @@*.}go J6ı?a.;%{ 0h5 *7Af=W10[@y2FT&V*ѯ)ÎfH@pUaR0v (zQcuWz =jUAnxesyP + ۚi{p |r&Gx\ >sz#OD-C}ٙ"$PƯ?mֈ[`++b[yƒא3|V<1G!-#Nd0T-M@Ky,vBgjY[ :h@.R}ZXj\׍뀶9>k`NJj9# VoOL#8i7|c ]RH׭ѹ9xuxwIeXT*moW͹m9Pp\x 5r}^*k̷kь7%7"콿i nT :'JZh+X@'I:=ach {A+;i}@I~g#-Xbˆ|J'>|>4!_ kc%0DEx}7QK[tCJWk_ A}x] P: >'>_3FТWxÎc߄hEBbL*^9PZuf?E1c2u+/n!Q]qyH̏`'8˳ j42{qe9X6!+ ŽFi1ֵ??~G]Ý XNGZCDAoaTOGߋsrGw j0]y5r5ĵ7*, w_fa̦͝0f+߿@:3.kGC{fDe,ˡDU/ ' [l{i\p(FOw&@JdH n/gnZrf}vę›oލYS0OٸozfX&ö)`Ǖl,\qG[<_wlf5$[X3Rg/TU kFHL0A8I=gJ A Po@$C̥ i<TƒٓT&dH%JhgrDy%vvn ? dy ͣVz7_3n%x3;9yMNڲǍ_u%axyz F?JԬ]r 7sesu]tN }6NJ0%X'|@ ޸ezsj|t~awh(+c?]j?,M/lGRvZܺSWpN5Q7. ]\ RkpǦğ? n(wU1jNJ1BJ|W=S7| l`Ű;sPYd!5YZ_' [HNTПէxap+q6&:rJaqJxaZ ȝXuaz!1nGܵU 󸾯7:"a(8p^-M+[~ن_w1lça 058U޲[o~km8/PYe?+/6cUGr=;)ߊZ2Huy{~#];oxsk Kϳ;Pʵ0<x}\H MS| _P l۞/Z3t讬#MxHYraXm*@`fl y֠UjCyY"+㍑5Ppe jV&,%;jיg<\>^>{X*@=\+"2:"Aב+5JlثJA9X0/ j2~q sK5^xU=Um]JZh O01j\%Uz` 3j`c"tGUr8&5T@WObңE8C:TRר#%FNG7.J-'{; 9ٗdHSmc1.\:=}5+S7u;S>єZw# J$ vaC-!əpSKs nlU/~:հjTƓنt,U8c@6 ]d㙙ŽܡpL^Eۘ>XhRN 2y! JG,x?=S zBNN|4\]1OJz9r_j[= @_?茫k^69kL9ل{OS-Ihк=hGBGWmO:hݛ`YJS^8:7jdXOO{ _$gqjʾ4yO_+[w;+S)MhdT0'^X3E{+`TϽ$ ǟ3E,슆pe\\AAp s&gf1ndZ6u^ޟz:bKYJ'j kO<}vP~*]t{?nȠY %ezWͦI2݋P <{R#d?,+R XMM0q =SJĭC@exVO >.ǫ0i>P^:O%#x*QkM?RˏXyjʫ11}kNȰTmBdSd@4yt&5o@ˑC]0UR JѪKU,:(쯷!|/No g_gN)%tSfbK>V`uPG<CB Ij|5mAdҔ ې XLL< (ul/ OmV FEHNNQ>P^PCɨC_m"5yʊ23C|tNLd_396?\ɓ~`[;2S㢙U #҇6멌9B^3ݹ->z7'kƔGrJsZN JWT 7#d&?A -_ bҪ+m?x䋅d`@ 5hC\ˈ93|͟U uylقEȨS[]W|+Ne D2p.=|~5wC\co-mnuF\f Q#:{E'y1o1<"OuxB}9w߽-^߻" (܅mse0BTAmա׊;~cFM7X6#A~V$ 1kVW3l"X{}I>BdUk1\Om%sT[6 Qx~Aqo;l:E в+c (-t U6ώ\ ؓ^Qԛf(iMг:d$r@YL~VM\ҒQ c),aYAX{oZ%͙##$TIСF$*Ѭ 6\!H7Ldr-kk*rx7AH!b߆ {b')WLs?5H*9TIE; y߁blR9q&k)\|4i'_}kRTV>W cXm +(nʖ1%!VU4Rpz/~mX}*+PKNCí%/Dο:G'څ_ԣna#[ [z7[t5ME07UQR^E7뷖Qz s~ pE ߕO4rPW ;XFE=} 36թ>ET`pIJd + 4 6C?/,ǠZSǥӦn7]nI@5 n%N2;bꋅhsag4PP]][oe L jq3r͘]9[im,0}Q̙4kӯ& 符/vg`yu@~5Dd`aиn4ex=06y!ukOژ5X9 C>x9J" N+GmЊO%l@ JHBǖz?%hx||qf8uej.vy*G[3t?˽a2Og%D=+kʎw)%dLR\YO2MvKp UdЂ)+l ͫA@!WTJ Fz㭐2Ms?T=$}®L=*-ȫH_3lOjZ +PfސFOl *5czB  v઎i6<{,UB<4X ՜˄SML}6n+7y9ɿ`#+۱ = ]-%(ɩ-kc݌_6Ol +J~ey8?)t,}Q Hdu@XƓ_H#As{֦L=ࡊ Q{h7t'4<~o#;V=rx.y/mUӾO<}6jֿ{x0u>ݛXc}A͸Rѳ9ա#f5Z9wm~f3Z*;Ȱ|߬d͙MCZ  >GLe#geMѤF5DߊlNMu&=ۣMxR\%x,g,ܒڡ"-=ĤBœtہO^$?PU@\ l_K@S@[ڄE녥SEȥt%زɨ?M?FJx~8/ KϮ}ץ5/9zqڡvA-1lYY8h_ h Z{qg |@hֲ3͟DUR[mf5|eUÏןnQa=Dnraސ.<𙹘>F`_7th&0tbW7n*?;<{:3NHH ^D@T b{l "`A tB 63=g~_.̙s^{zg[q+J"e{ΥGЛcmu(g3\fAur_ g#¬f1)SSsE{wDM0i6ɘ*Ý2hY0B\e TCV("msf<'In:M`DLAu1 0tfsB+S5nr2 e Nr4ݾQ%$4FsAњFm.e|Ah!GD׍}C9Sbռ=/}*Dž0ݝ$C=rdBR{q?\.X$ۤ8Yj KdTUc,HuC^;sbx޹%o)t]|hj7~տo15aMQҤUns;um.w@іvE a.s1gG.1skt-~$Q|H:h>[JDMUGIf{kwSo.QhBB3D0֨bq.l깛؜U3tgk.;nyٜp&ds CGSL w<! ^>Yg3 U}uMdS&vBsS)=9:GH9?OTN/VC%eLn)Ӕ9⺍νù^9,4KPl8vOlNҭN?r=|4Mjܮj-jkF=w39M-Q@?!9Dn8& (Q n4/W$'AJ#E^/Y͝׍ihC4UCJ 4 R+24MNEcN4(c fPLVQnlIbwSEYe̷(@P..0X4DץuBDDƬJl(L)}*ta[0S]KyvQJ\ohx12ݛT5^C Np* alܹ㹮;E r7kU34*pUM,n[ P)'?5@nհk]W"4%qz0;+mATYc*҉`4]JσEf|G# ߜBnQF$H'XjY]y)4*7і` kQ >4ߜ4]]$(k,f T̸&f32L2!9'Lٽ)g HM0 `?B;MG2:Y#(m23ki+h(L0(ߡߚ|#լ ^#%-3DΌJLMQcr!Ѭ9[!_xѼRn0` Vj,*@;Y>Q%^5PP>"IYԸ^(qɢ+>Zg b" @}^4/[l'jh):kϽU748.\9R*jDo/澎 nb،{ܕ-DoM(%b÷iy ivA&XNܻr=AtŢ9cDDto[ ]$F]< "e }v!DDsܳ<=APsifH=EpI;Xw-@0MgL*DEDBب`ILB(c733u{j\˟p>`xsh3,4i 杄_@`$<.  WfH!GP# a%56j4 (MBڸ BB&M9>,ie9 暩8B/G&nم "̏tgd2!O73^-TL/1fh)N)' B=; V.3Fj;!=8CkTԫ歪7W"|52/uML"D-i5 7MS(eU#. <@/@$TfT3ui@H;x]dqf c)f&ThlSBGRql6k~ئAP'^w5<7#8 Fu X3D" eL` &"5hoH(?4kh"_l{B0Ty 凂_aICD=,8EPO6o>lA'Al\*A6/&Օ@TW}<*f"$k%!ֈGE|cM4jN`f_C6 /:3妅x 5\ٯZǬ 5H܍$֨jҵJYGQ\tLb=sFOrB5A;|+_F~@mw~n dfb]L5:AE?B%ϳM6Ӛ0TnS$_{mt]P 4;ě\5P=IBzSjCh"K,TnyUv҆]ևI3_m כ\ ڟmfl~pE|+Tyњ:|8+IO-!=:"NfBEevttj*m E]e-eO+!52GxDP~3^~KK9&sԳέ9t*uWF (XZ9dZ T!\fK()LlF)gjpF`dxt ;vݐ5+-4-P$C)ͯ$="%js)rdkzs*xZ)ɩ%6&MGm=yn-%3ޜդ)dn}&yp:8YN2 k?t*kVwۏ4%NnFi6x~oey\vEQ]0W}٧J9~ LQS@UNSY)ϏS.EW[L+="B=\tv "睋J<8hTZ’2[_~eq<{AUPԔՒ]IA.:eTRXזD 0܉t`0RRK8YoUWSEq3`8[gedtۙΤY('E9r<2¨"Mak '"8ujNe5'xULt?K7dYCe9(onK^T}&<0IvO'"7.9܅ؾ+1S6wr~{;c*uʰG;E`4h\,_9/Zʊu5aZà^1x{Ի{`2@C]g{ktWTw6E(Aq`N}*G+h{I96**f(,;6<͎ᄄ6<΅(};XOA ljtItkIȖ,ӉֶO8Dըnd͛r9%rX6;а;Yz?(uwS V1ݙ7+U n֥qW6xQ=lxk#?:ni?y|=W)8 zO ~a#,{|q?btya+^nhUtŇ7 u~vO}_-JFEsrqXc3Tۅ>ȄvsFs<7sybc;~>~-3z;E4hmOMdp\.ȏ\K?d?5K.Tk E  rW>?nb~;wإ,਋rk/*h FD JL+P|"9T nкX J ^򫼺/E/M4ʺc_wmd8sIvB 8@֑h}n?E@DZ+7%}w+䑙84b",8Jٟ[gɝ5oR;_L;Ӫeó y=*?OմJ`|wUXǃkbS%Z/)NkRZ YГygYXZLUԙM(:rԻoTK!:`A>:$^,$h;[)#!g͸nQ[~Jebj;k0s'ƉbOoN#֒:?l:W7FxKV>-'@I?Y*7F ._((Wn.o* aD/1\sI"^̃? vΑI=R֢ikBl0!2]>:!gxf:M z[!weaLϙU[0w$GZp)%DaMHR3].<ؠ EE&#nP9U/pRVmw޻A+9~W*-.ڢ#c5HeC.2Oĸn+o€#W2)V}ҒZ;k_2#&KljC.n~fġO OˉwY4'#vMX2o}ݍnHQ/wY9o(nUUg^&޳[ƩNYX }{*}x\6U7ɼ&⩛:Mڽ& iSC/K[KNT!x>JzZw巽>FMx&K6ב`班y6zx~gӌ}ձ ^{'U˜8'emsY@L R?d.  -djUӻ} ٗݩD kb%90 Mm[vu5oA)x'mMzx,7<>/ݠ؈8 t^Iڋj38Wz;CŵkM(' (+wIi߆5dŵVޜ%_)oWu^hEIΠ'r`F&(=\mQ 7{Mad/^F2m>fnj ޚi=6P/axrՕưH pq|@풸jD(`Y.t2N{[+e[{^ӂqM *AekGٴܚ}!ᅽH:}2z^]np,Sb*F:IpBWqUP?A]YF2 @~Of[V~ZT]{8m Oʂ;;"xxX:( r}016׿-e Qԇŷܹ:G+Vxcb_lˊRҵ7Z6/OWR+)gҰiZ^:B-+ԝˉp2ǴMKWPN,XǞD԰DZ`L ;HjEΟ+0qOOG3arŠH%@޶4VZXQ+3}!GJDu=&ÐlV yd;"d-Ù5*ʒx1(,/M\89Y:;3LLF '_ΐvqL_(%ٔVKXj`]΄sˢ L4aCcՆ2z]=˺X֋/'m) P {(]xL@\\w#NWS\Qi])tƸ}bBkZFZtig[*t~ӓ iךqC39 ov_KŞB("S\?]rI_poEKp\qn{aL+i$D$z׼Vvb@L!}tϞwŝ0er[_ |Shq9׮珚ږr-+yde)?k2xU{y:ݻhg7-ԍ.kŞĉCz2 U3?ׂZ3vXúGne^RX7 CFf`y7s7|_c׷F:~KlƩͻ?a j!m>-c# 19KXiw +\޺ LG wQm7H(B`imТ5ygsX(Wl{wwM1Qy[eG9@Gwf)-)R_c5yso ϼ0dEC-Щ#$ k.lMƃ̝N~84BO[7udgZ0ne?LB^}d'9'}:֕Dһe%_/ܿ-oCbl8=Fv)݀9,Iw$28J-Çjs҅Bf2x;ײ6A y}|pieByRۮ%%@%n^[3;|afO ߑ|7~7ȧ`*֎-iNa 4 QE g脎KlB,#'uqIvK|WH`;yRu٧S{eof>"y~[w-Eg&ffi,&EHFD(+PeE v0BD(+PβK=k0=S^c+ g̈dZX|`džPo\^d$=~*2Sڧ0U=-Q_?kJ()&^twTU}/ Q %FvƅC |6u`9(*C\5,jN˳9,y-]?5L]΂-.+/NbFrzF?˓J=~jY{az^N&"EXά&s-l{u{15"ye;_R b¨ʪxw.?-Tt6̸m&Ȧnj!mh ?ɃYDgWoRσdH:fҧv=I|'y܉D* ]:8}-+L}U}ZOJHW8P*ƕ5:\Z'+O2*>Rŷ0ïΪOPa?=fM&@-gkTtp$}R$./9<Z'sӭTVV-uA#Mzt 1]ݵz?Ϧ@R݅E۽yXGj!>=djOpy֞۰jkL~}>)Ԫ?O𣯮BgEVNn-.+H܍{֬;.IV=Oj{Ƚ[cUɩiP_>,C=X Sy߈!Ta֐O܃KRkkJ#+gX;^4L}C'R>lLK+S7H#t6ϯoc2~9pj9m27gU=:YT$+i;hFQ\X"z$qpɸ֐bgG @ ͪʩӪ8^:ԞP/qyh*`N3j8!ҍ;titО]|M1aF+"Z:oFO~5sUUΫTQQUob¨UY{wjNhtx3tS 25|Pߢ-ob95HJK θ9 lRSOU"`:s'TǕݥ* \M_8qg!Zߖ;_C**hBSjrZU#\F9jg{3=W>v-Ww)Ř:I o^0cC\{%m:Ǡ-NUv1okb$LY%abW8,͛8t=TME0]9=9mfЃh&1mc@R;*̜ۏTx#0pv)rb`݋O$][]l>W7"{G'DWfJ hc@DiT  3'=l+h>R垱TQTU”ӥ|f2$\B(MQF k=ȚZNr*,TCb& eW*2ӢkG0gao"r:]Tmuo9@`@)R?! OT{kAwL&E>3}| 꺑o~c5ɯ[w!hڏ>MjUmA9- 'ry77=̔#mԁ\wSBY/_~#XLW.MCTz(U͢AYXGv1YՂ@ڴeH:9!fǝ˜_Xw7=uWn%)9;tMfQfҲ7zhORб IDAT1S#Y)IhAwbT6:A  ?̥i%s ',8ɯ'ydkw%dzi8p&h[E{sGC<1iVaMLdlUBMp gUHtbFuB1چUGšY}s͢Uwȃ?Q@Jn>%7V`у$o0}S禪Wsu)Ӄc]|IK_ŧߗ1mQ1b7'EoWeluDq̓J]hVqMT_In[Pu}FשwiBI%56#S~jjb0WY^B%vRT$5Z+mKկ;'ث3i9 ntꢢNg]nE3Ǯ$&JYhI ¬ *t88onia?Cb =~0ų\L;#eۙ|ikUz=?Xꔅ0F>}v+_RI'D>zZEc/*8]Fu Hl,&C8,V 䅊6%zxmZX"X,NNۥ$}#}%@ ():lǓ,po? /tiLFJ74Ow{yIr([PUNƐơʜOpgdxHU/VXJý6H>,:? \/tB Y*aKqd8۩aI6t H4TTP.FRE!fp?5zMy+j!B[L4#@Y-((Tg*EQtFeEcSҔ;_~xgZnjz>4mObb,8 . JgɗLM "SjTVz%ko6iа$IF&PdTyCЃ7%G{1|rk~QsiV!XAۀLW}< O R÷#rmu]GlsϮjAJXP%NtNXZsCt=Y%N%ܻA?1c%C2O}|<8rJo(!.gAjt$*$FkDupA.a>Fq@IYviGo|vL˙ρo3v;q)hb3y6ue4l(Ӆ5:eW6GmFwoA(:}Z;Kb6P5"uۡNGhcd.>Y=?/TrfQG (>ݥ\JXT?t:'و/P_ov.%GenڗpH??KԂmDFu.p4Y:??H/2pm[Di6;q ]1 zr'M`s=7ݦC4KMOQ4Ft筝˥46q6JTQ DPY5` xwӏJTC${~(Gi* E'0xRNЀ)V^YLw1xr%I^.V"4c,hk$φ:.UEkƺZȼgƩ}Gj8u]TVy~Nܾ<:֐k,2(]\@ht'}wW|ʺcUg¦ٚWZ۬hD華3l(.MUt 4ÇYu<1H==RPQMQx~v><_2ʨ(sr骺{y\1wnW}|/Kc=2UՋg g3jkk.R.a.B)V㬪@5@,pt uQY8\ qkE-JL?]M֬tte:Zm!#hԪ 'J ]7n2o'sV[mTpCe9HhqQk7X\5UTshm}hƒ#*a `)huCI)lajFgO $^- 5ѹ!Ec~_ɴ+Pcn,a[EYi;zhf{>^xdL;<S4pEa-=ӧ,W:_jjm83=JfdxIHW4x1V re4^m=#ʅZظv?%xLXwLɅh:rhds!!@:CT58(.:w{E܂̇s^D-#Ϗ;tmI׷pӣ'p[_F&ć5׌J)dɚ3m|~N@t))ZyGMS O:r/IN`"\x6 -̹( f>y 8/MZ.v%鞏-h7ȱCU &u<ےY>y :3aꤠĎ̞22YJBn̑B8@llde#Wsvע$X[ӌM {H]2c,}7yMkGreb󚭲r)>y{SW.C+P^(K>S5?B!(.xr2NMߝ`oMDt=vDGe%gŖ:ŧdpTUSK7Ien2 './3ߡ+W^mlO9!.8tJIbDs`t+}] ;_8$ݯ't2bܴ|YavK*~ϕ<'Ba\kObz?ŚeG (IVlSz Y‹Qh#& Dː6_>ˡLC 51IaNN&kqy%UMCPN)9@BJf":NmO(c_e8V!@v (~PYOaI=e7&~ƺʊ?DgkpIܳ_tʜE$khqvfĎr]uL߾XYpRO]1,}W>L :7pWV*="xC$r㝣&NdHu3wtD'd8A66aU]e٦rfWٗ^h5Vyd%%kn,B 9to7ԗy ҙg4_TE%˱ʒXKRiirQWy/ $Q䗲e1\za\?hU.Q}wTEd:'YYJɩ2;@n2w|2sX~Fγ3~]`a`h\}Hޜ/NUIA2SKؿ@NgVphWt\v)-wt'%EؕZrtR. fFZ}FˑF5ӯ*@X0 #YA6m>n\O ߃T?ryL]Gzho?5|"Sk&%-?9^1aKCEje=exbt$2{2~|$ RQZGu.))R.J k(iszIr~?ڥ;Օrݽeb{%N4MuL2N˶#df̺X Y&k6~ uL%%T;{OC~C2'G*d _Wy~i@:ň=D2*2j h%I]-_]R{COؽigL(zAER2ȱ~0RT7R:%uu6PPT/ёmyXye=pݟuqrқG GV8Y[ jIvo<;"Px_Cer,%<mwcbmK\:,R2**Yh l kS.FA%avY1][ Zl$.D},?bN2xxN$:2V52Y20nLB:4?+Oh°LO1@sFtΗ;8lbzKdx#a +Lg(jߞh GB_FDKJI W LZjbKiucwm1|brUv 93{'1PX8gקCc ?<ޒ:~VUݡowߞGihdlT@4F}Fc$%j1o&DcШ)qi>'% ̃ C7 ,+Н{ag6Z8˷Ȍcxp*^y{StbG~xzA8n~|+v'C?{ ](~H*Mf8Cecȧz?+ Lm!/1n1m WavcLG姛a|F÷|N>4HHpشuc3[/6ˏ[F\8.ذ =_>w1$]l~5~%{Z[ӫ391{?6x9vѩ 9dwnt,³exiKoKؑv.YW])mb.[.o?~.έ*~xs*Moc.X@s,\; 7|.\q_&ox0Y/>{|NFO>zxڌ'[7ʶW\, ܔĵxg)+3-;nkrqMd:=O@[Q%gΗQԉ#vl% $;w VGG|]Rvl߿F;)!'`nl!|粇p-1~N[?s/6/:|>^ۏKo 3Q\kdVY:58__.`\a1̟sOKo~}f6=c%_0..Xsʼns&U~졧--Oގw K0gV\+WaGNbW.)ǝ+ft3g!?c&|"YY.>?j)N]=C1GPW֬? 932.K%I$''>z3SLࢋW`Ǎ &gy|WLq|q>5 rD,ƝN*3Ɨ.I˧sZw"-0 eK`\x}cqÖMS8zbslWʡG,NU_S}~ɋO#N[ӏ#+>{u 9E8U8aYj)*|؉C[ ߼e0CKv||B/ÙǤؼc |bٻi O_)051)gGnX#ډo}~\}vLY< Y2K(Y^_S53B`vXSqqsʣ˶/ȱ+A}uw{d.f+ޅ#\gϖk>}e_cvۿ]=ua0s,BVqڞ$M%;КEWɾ;kS3<ЃS-8H$A3wbI\^|⓸ em(/y9,~//{mBK.v<>E^ K.ɠl<*ΉOy.$|r裪]GeV%hBc^-7J}cEںİ_zȸQ;ka'F7>[~VGxE $^PW{T>Gmg(xaaJSkZ z94M; i>*\o?Bt>H9q} ^q fxDžt„2 G\6'vpGwaLI)4IeߞxGlAodŤ{%ή<ƤI>?zP(MDS)^)E.4A&nb,檽\%I:Z')$՞ 46BH̟Tq(ͭyO귚$$M4Qn$,Qs@Z>^_4) k$PEDTJ QjkAIJba*Q-)<Y  2-Kf c6ϒf$@^0QIGAUAn>VfhZ ^.͆JԦQ YսKf' qlp@A&A? 0&4k$ -ZtYYR͆Si&Hv4^ٔ-Ò^YJhi63%IʚPT4ImS)l,AM$@@f  5L:J`$q3edW&adjg$uTs5/U,GD}R%H^Ȱ[>DYR}΁{)}@ʒ"0//0o뫶Obں d (6QDLp]>)܈8\wh04M)u -cUuQ&ÃI([iV'PU$i"ah>i&*ߔJ$\GgYJ_;vʚokCgTFlXhMȎ r-aQijR.TR /)Y- yh~4HԚ b;!J2-::{BVP\Yif~YiX0Acxd&8錱{faS, ׇTI*d{)ٗrIaJ dAV@}{/> [G E* +m_z=KwH:'Κ m{*tl+RO8pq%a:*,!co$o0eE+d/N ZTBNB]@WVNKXZLlCPel *]p1 hf&ΪD [qwBR53e]ہ/ZVȼ-EԴvg-y0 Xmd,I!ՠZ>FL`Ajo1\ Yl Yg=՚운!𭶯: ^ح0uz>{/4i}YMM~Pk=\QM <ۇO`O}ݚ__3FكOIVUϙ}Xpܒ$`%1s%dӋg^` [õ=ήߐ512kOVk`ki/co=[RCLmRI5sο [?OhAc]P)ςI[SOƞ-4#Ƃun pu_e+_)ƞO#_f;UG6xy6vq}ze,+EmHcN!Vs`)Ͼ"wm󬱱W#e_}w{qc3\ ֖cSk3:gfΔ*v}M2fv /6pt[l1?S6O3Sv@bk8Ҙ_vlO!ËybH1a$={7۴:;ۣPq|̯y>v$r ;Z HlkQ7dˀ'Πֲ,ĠR,W NڦGW=;eUVچ߷a'i} !9=*yB;r6b7kt0LLlrd1&4:ZTxd%bRɌ9_k"2,@m`&HXv%漯*)m3J)lݱjFUtur폶ko=HZX@*91l0Q;{J=NYi35b*;=Uos dhd޲7#2dBkRECy*ND#Ef-5YEβ9lAA"fJHn1Tc<،bvlzYz_[6 sS#ϫ^fk Tz܆JV8~ae],}0L%̧~A e=Y:vbbԊT9BqeURr|8pTՔ] %F%jrs|*@<ϴ;\ףÚXp:WmQYy8Eɵfxk{֖8dr b>6yc>M_O͕ݣ;ξ͟${*jcdH3pUkjü"^<Qd)P)lbR߄ B&Am u$<56lsAx4 yYAX4`MvAyVs٥=iV6YA4c0m<Ĭք:!=x=@(j44+Kx}'sSv#YAn&k8}σVr}5FMfdԃf`!L:&jo@$8CYv5>SI Β,C1I)5ob$:Z |*燁%iUy·#NVQf-I ޵qܐPs }ڤJgg6q`,A^,KE,U_^ ?M|X}~5eq0G:HqU}%Z4x!B(,xZӴ^+52)WR 68MIgaM38֪Dg d,-\Ko!e>$k~&%p4VUz0)3K<&l" 떞&vHaɶC;4|fo^b%ik6}25+>;Xr_P L4VJ11LC3Dasmquũ|5&mO?p"$P~7 |N o EunZ=' f|?ƾBopbnbf[[ṯƬMc9gwG"15b/UMF1hcem'ת5{JB8ygFbUC8Jb%WFm>QTyg-&m0p Sq<8A>{N]` .:kTd&ϳf{EmCxlj68"p!nLEP=:^@i7_/ 7QZ:^7a֓X;2WkILn—t$ڵk|xs6p ŤC06ñiu|m8J'] TMgv= ֠9\C&Q%WQxX?/-,8 -xl^@?Ozs(xg]SFB1Ny(^S=:Tx9P mc!^uDt6x_4֔ӫ$̾؋0y'i#c}.][FJEfⓓH^DYRRUc3 N}a!#ay;dA1xٝ~Ж3kPjvءb[0#Y(+2g3mv`x|%:n`k1=$q !ĦgDXZD!h&mzk =Ez[#kAaPhe{hT&xLI z{SEzJ7eE%6 a9wzH܅z0d$" :1KHe JzHHmZi q:~PT{:dI Y7NB{9qj{.^T!ݪW2CޑWXu X hSL$K{p@g3 &Fu\C -QL#BL]-l^6+2r ^&6ͷ5`!KcEkA }JR?P6m39HC360NׁɼGCD-7`-ޓ7_6ӆ'F3&V~#pka_ϲ٥d%U1)[ڕ,Vd9aH]ޣ lw(~WjIcp|,$?kdRFRc* <_E@Ahd|ߩAx~A6R hX m_#װ~VĮhMeUV!`PTQz0N&B0~QX9杙nĊ u.ē"$0I׾!Ç5\0 h!>AB `rF{cYf[, !5s lll1yoRrKR yv/=$!W$뤉fW8N'2ZV`=_ ׌S_kLL̩hUlV(pl#Jr{ k,~:?=SM@г13l|\'J{8XUl_-=с03_+ 4|ۃcۈ~A?fCK#oilê(F*1M-w~Ԇ:VˌyD<3QFA4/nZ;j3 "vf 5G2VYJX-יL;6$)b4uFdURz]{f,Ų:U]u(+Vרkl]8XjWF-DMQ)z+v1*:#%(3ۍ@S*><=])2nژ烔ӳbk4Oa#*S3L7AV$5<ںQ2Ƞ+[~ݸ6o+H3$16NaTݵPg}\=8Zᚢ ,y*+&c\^gC`_WJJL FIxd߮5Aob]T/pi~َ# ;AK$"iSyנ}>fSl=;dP"(N%JƷ1?˨= /J P>"zǀ2ޕ&f`OګkoܬnU:=t{n7T'G/fz:N|E<Ʋ|'sOo(]|sy7W5=x}ᏮOvc'pOM+ܽ兗`r%V IDATUAZc\D^NN^ˁ`jj n^Kst055N°v|Sn*vV+`$tf,!L9;>MZAXyGO d܆f<S֜;4BL*ʐd[`2zegG9 Ec!* +MRJצ2mv5T2ĸT1۠oN`Bd+c6A+3Oo0A9G\44;b2O,Mμ,5{~%&t"TPoQ-HZQ!Ÿ}r{&`u&Gft$d]4&f)SEUA&}\vn٥OHddks[6@rxX{/=R\G 4CO @G;b}>WA*(aP"E44 ^ %Wh$$cIR$LVo6mܢɬ##Y0&+UJDwCe2dƗ0dBc%4sD9{Z-uS{H!V 2:*O RI!d*E MH\)؇3&P MY %d=a4[md dthm&v%^g|{6!&ߌd"AEc!0Fp> k{bdKjkNJ a:jE Vdϲ`lJ+N%PɢmC$nʪϰ}{LV=1nپcaltUĜ[HUH]:q,Ik!DXD 1i%7s/xo>>;p مM?"{>ϟ yqҲHFƱ`L+KW]G`ɈOKjղ`G j4A] ,sk9 #wL*Ymjx5u>hUhLg^1Q>yNϼ9Ow bӁND۬/[O;華<H^q.zCUSmC!@UdQ]ѫvib_)3y[/~ݑxWCN7$[VZ\wK2wwڳ?=ʿ]Ufn;+rF*o~'ʛ&Ytw|kW7 o}eݼm)$&^9cƏA򹛋(ǣj1Z{/ Z64b F񸦸mQ'jPF ~١dp6t:ҳ̥F^FJ6q!Q*F< 0Ψ$-e6|/so#pzI/ eiM5u:Z!iװ8YHIJ֔UYB&+Se*ޞK=%epv ["jb|ecĨނVD}K! .;!QUi?^:v>08{8&^"hә7[^\|~>Cʙe93֔{~@O 43Y;H?Z5Sy7-܋|'9fa䓧c羍?';ʪA/|)xUy&V|c_ًW}h=ߊɥx OoL?V w|8b;_OP,`Jhx# jHglSطO0>.a6c bQ dh3yg> [ ?V<o3[/}^=0Hg\ǵOw5랃??G/t;q,?^n͋O/1ve@VJi7eN47ThqmAcojD1illb iQ:H{Øp#d"MQеTb- \HN2\CAI 0m%צ#MBM2mJьѴhD< S g,#ۧwu@}- X@ (F_}So\W?+rUID\W^7|+=UdI6BQ\;ə"1Eg'1K惍~g~Ѕ;ĶAK#H ;LQoxў3&hGןZrF^^<;4S[QvJ4BC/LyͲh,@]?-S%;iP;O٣1ZKཧ\Ջ#~E7sqާP"W_6ay,˨ F(`[> 1̿yg+:,605D&!{Z}'+7AC?CJzs-jqK+ 9 5kƹr 3_b]&A*B?_oB+#p뗬ƥ3g+Nlx`ǀl3:o8o]#"P۹ ;L݋[w!G;lOuoK|\7 />{~g>W'?~v>1yr07<SewԮmز}o>c6i2Pw!V,ceNie9M&͕1saNc'ih 8bdhJTvf),!F0``C(XO1:;DgmnӠص0ȡ!^il&X6$;O4@4}~vHƚޭai99CD֓B5jÒlVbvp?F4h$5kX p66Ri!rZߒDvLv ;fK̝//zboSr .7-8g`>w:x6~gg񖗞PL7.rs^7tYՊd"3:V{#Icj+L gl5c=''hi;4̋{шL9qk%~pz\5xpT]dr6뢖%jixա6n v^"'FqL&1~Q znsal%Jj+6m*&Tb>*I"Դ$LeD+x`T'Uk~:cdֻAD`la{.bW@ևC(PWoݷahXky.TN/'qٗ?3.x &-(˧el; {3D6sU$eW*Jʖxg !HDgu9o9Oԓ's S Tw^!no},tL$Iҟ<-t<0!}&&56>nL^I_$|TF-6= k!شo8ż6["iƎxVܨ[9s6ݏH0\Q6ߵ0HjpH@_ڡ e'b[5 T*S93͖"rHvc1a`qVÎO *@XpëDBt]lvm&^1VV}~&V[c!]v-.)$2T⩢<;t1&U=Mer-d˃VaZ]1!Y`A{Z$yJOxV}R\X2с 9v5V3jb9vHrPS'+9{t;Sze_ޅF3> *MS۳O>(-?wqVz]+i4@R,:xt)LHw+K8X 2W=E Kɒ;H0%HPY$AyHZx1nmx3pUx( "i&K+"LbA*KOzt$E*n)RDuPI&{6B iB5Gە$M)c-I,M)4/,C n=$Ȳ "y;O4:Nuj͋6D ר܇=L2琖o]l~ꖭsÛ[gŹc=̖S8y/y a&.'` LAV{6FYiA(6'HJh{Eg jU<7 H؇ 63+MC {bY bONe.)Gdv3vJBG{w:ձ̽zsˁQ`$Mv0^1>8x sf'S^lC`9j3*:̵ -$H<M * 4Iԃ9?;V``Yb,jG V0%t[pO6Ĉlؒ3uLU=(6F`^B"$JBHVP2UwGMYےA{ڃZ չMhªAU#P:nvS2(CfYLxG>9%4%XvERbϓX jcBUdWc؈NyyDb֌1L|/# `a\c߳]wxm%@pA ^uj0a{oLտ+yow?+իc+13v:B3k'wad='A$`4Xo nlkO^,X& hjM),@U|m6!Ʋ۽`E7L&/2,+F޵˻LC"VyY[ёHu [ d+a7TUoOt;8 'oڪHPVwFX, ɉ@ԁHRr/pA8b\qUMKċ5/30bD!ZbDQ[Y? d=lȶqZPS Z@)L&WK+ ZrN1r;[K@NM+l###Ht%WA6:,qg~՟bT{9%a]$:9Ms!{Ý63EPHPD8kBqd3(SePW}&: ˺tZn M!/013~2w3ȃxI1_BDԚ3m8 Z@jzuXD*8אxx61y0r9%Lg" IDAT}\ 1-NSV6&Fc2I4j4רΓ#kRV'){/5H p5k+s q z`4:[b(N`D@j;NV!,>"cV=JKhqc_rnĒ]Macx1YTk `UDe1S9rpl<T!aeSv=TU-<ӕwc)V=QcVWQq(,,rI W w`:^O3i$@oJDadt iEbѼC&q_ǽnC>G{8ʛꌉlsckW}+aq~囟{ =Q6}`hj]$KΚAIRg%GI_&Zt &d*f;lOwUhywhLkTdX-ܱ1EWml'o5A{1G؏ ʕؗ2J](mP) [',J|>/֎Y?vZQcaXeiЖ/iF(F2D5용 V2L7HGr ˰y'Q6pLgy̳D3=Mיtj9sOOhuxjj{y_Λor&'s&Sdb*Wo xrdKɺkKpO`+T׭? ]l|׏ϿdHφqlwurӤ![ZXFdJ]_U 6M,_hx ƇVU[Q{vviJR5rmX&׵Vz;T3 "2I5 \gd*8B$4BiQ8 4m>Z<۱5&%cF3SR&Q@_!̪5q[  !Vnc Q(1gb+]-Eܔ257 6Wcx8(Vkgv1ZE "ب:߰%SO>BYޮGK GA*ZT 0z'3xeN@zȉ j9l-6N֡`8G[>{ibOUmZ-&N!qxoaFpcTzg2sb[\s=,:]:tLvK/8 G.q W`rygLt1sJ>_= s3l̛3l;JRrb)z\ ! LUg8 w!n"|B>Bg\2{$Qq$QDxn`-6[f ́v[|>YlӸ!8a AW||C?IGWؽT}텦W);F%r?&dl}^'$)օ`Ӱ;/xh?++m9q3bXH&lE7]ևرI;b0g&5A{|xV7BkP $ B ztz;G0bs sJ$\oU16yXєkӤI/0+`\LAQ5>*˂ߛxxz9:S9FU~o֍#=,?!G ݏ㾛09;C+e ==?  OV@@\\tyثMteIZCCW%7dכD2oL -׺yZms6jza;hC{ҬO9s@5/t}ZFZS%s,f"g +͋6t5i XCYg*4ZaǖՋds͈Bln1cuF8H[_#;pk"!%y%Xk:"8[wƃ̾zP&$hJZJUo6䊒=H M)#h֟>UH,[ZTqD-u|>{ٳ* nZvl1&&QV"TJ(gDmӧDt!OCH]l{;v({۝ޝʎI+v[P:8Av`Ϟ=I;w`_wY߿}]kOp`q8&{15EˑK`yyikiMiR%i,ZN812ym3FZE6)M>6~ _V\m 5 dy㌯cNWb_&Hfv}"YVsfrL޴ߋ=,4Q6QQG֏ oq1Fl' 4]u>T뽰;:{É{qX$d!7z5+yٺ7&W`d&*4ʌϓFIPlw eN(f¬Qӛ:$A9<s&3 5 v`s8~Ï~7=?kDDЉ7wctLOajnھE&O'[e'cH:_;SSP(:S`H_!04:Ϸ^htm{}ڎt'6mHZ%+mU=6ΐXBXVSGf~dY0 &6] C$+ uC $fMIs8eYu4Z:ʴNo t(1:Sp:1 ipe_k_D|M鼋a`̮*ljar47fd$-O4Ҭ1myT>"DT]/"2K!bTlկI!ݪqҔgShI*H ֿf 5mCE3kpAÞ)Hupec,n$ZJۀh1a쐢M5H_F~n[Րp7w7ȡd3;sk:P"0$tT5*؀TuP; Uf8HSĒ7޸&O-vERQ҂Rx2SUQv*/cs͚8nW0q#5!OlҰPw`4KXٓ?{e9VHLIBMv2-4O'iZMǦX2;{d8"4`IjQ!7.:DVM@e8kSm"4b0_!0=koT U&^ ba#i-tI=Oߗ&്M'f%VonN[4.pJk,"F&5W XIl2iH,z f-?[HֱQ>-[Kgb T#ctҙst|fܬ0uItOxc0:kWDF3AaG$+Kt8N@cc`h8o@Ua1L<\_\2hX RDz;b6{Xӹ`N?@$ A~hEycb:֫אz<i a' AENL$\(:0JfMNAcD,D֌4U3s&ʪ) SE16/E(4TFI7l>,K>Ęk*&nFA]tl' MTj%2+߷dW?t5$4Vׂ diENkhphp\#\w1]K̞W$ A<+ +`[ 9UM~Nm,1aATkdk*τ|lJd#8`'b5Vٻ8RuS#8;0I `D9GmoT{fgMAYh1V;b!-q T9ۃ N^93g6Pc݊e&q5=CYD G`Z\XkEPNᵬR!`xA7F@#w[M}N+19'*@OȀHvZ@NUFY.Rz̲o&kndV;SSGpj46 xӅ4]G[~g:O guޯ.m=It;Sm`5YƘ'V%E/;ig 5LV9\Oz³r(  /.y4,#"ƮKhh=ʣe=XzYrT2.΁%nm*k([\h#vSXbtWiji/ClbOȽp罖`㱍c䣑Y`C)4a_f96 j1cD)nr. hܧ(8˲1Ȳ O:@WbG,/1 ܯ=jLjh#a,J%NBߩ/qLqUA (j>q^rc +C2^Y;"_.<#%Μ9<`zA:~{resXc/bs(|gd.Iep-"eA,3D({漝Lf/D9(;`$~{]95,5|6={ p}fWZՖd- z*Xdؠ7F+DT";OV ;Č6vjP9OI`+"1FƗ,.sF3Ф`[gge41ILF3=2>3abrw{o/ٯFKzd"ɰxٜWB ٕoX+62L[̮1x"*2P3v>PAzKO*n{!>,`R/;,ŀ},bgr=I $@wcg#Z{\cթu^b{usw]eۤ04Tj$hKZ+x(SvJVޠ].m,R'ϗ:!e$}+c+  يE[!]M|p"^<2DAYA)bev#iV6wD[Zi},Ȳ"+EyRh wx~{7e\-l<'ذگ_?7u {~_bFL݀X|?oпOo$ܺQ8կ>~ȳ%` vDԁFS53-Au&F)_w:"Ъ< d[Ψ2 r|PY}KߕW΅'o[SٺF,?U4o1 ΘLep Qj z;uUHU(uhU**x56*=lpK'4d*ґnIYr{I>_UWmh #owۓe^*yihT< d.Gt=35={s:*{ Vr} `ChQz82\|:u?u\r/?^o: IDATa솉aw< qtzL}4>pqc)NwpͰ~qܩ8}e7.o9 q۞Gܳ 'h;xI_Ik7xIów>wxp}-S O߬#-w㴏{.opő~ GX]3(A m1&{wʅ"(6ȳ5RsWl`1=Vu [dڬeXIix1(۞Y;ZmE5xytGĭgOQ{`AFTOb +Dfgl'%gK@^jByiDBb@ t/|m26 Z7F:Voy&kwP)4$+Yl10D{B@S("dY dF52^GI/adcsLo֍1JS_fxc6+p w`|޻s*&Jo }}rb &L$bjYgDd1#(]+ :縗Θ\wg#=Ꮁ(Yk$MqRfEJw &rSA6l|w+rPCiFR$|){ 0N2a4(1W"kF 㩩Ȧ|:~dgO}-X5S_sUق;Mt>g{_Oӿ hxδ<W+ye"8\-OIǾ+B JID+6IEFXW6i &[Tbc@`TtN]T-wEr)z™>g {8Xk妆4 `osXU%9+ZS{$"̜*xrZay#Aψ}Ź3##Y3Q3X3GQcl+x6(#ӡA'2x쁍n2k'^9 ~Գ5BjS$/mVA422F Mb6H0`'r*Vyڞ* ܴ/B' Đ%$[4smsDFc`e2{XZ9+2pVHHUiY#>'E6~ǖK%qӖم?avſª1q<{cap)6[{]tS?]x >{V^ ئoeK~wg ?;e*\T,d8b[Aq,‘~eTT 0rI2F41,q^٥{Ly HB{~d?,<ݟUQRT}C S=oXKRa1iScRC{ܑ|3݁ԾEa΄d -(wvQMuM{T&Q}hJݥXetf- Z(oUGFyN,cMΐ}{_Oΰpg'*΂™VרS>Ȧ?6(t)J7T-JܑAEȁnrL|>VUJ+_%O ,3HAq }YRM,tP,ȂPH1 eVGSf!4iKdk+y6$o L {cqn&[<o{;'{ncN$~ک8gcdSjWXr?&|xW'k}}^?e?,[?{[ݞq7qi/m~x;FXu=uFdbDߪdxv'(TYX <4kH"ox' YjYHT1„l9+ϓ "|*Tf(2[Tͦ,q'i!HYU5fXYŁz: sU@S&sQG n++W=Ll=*iŜl sn#N3Ўnc?Y6Pfr*َUAV=ۿ0k RP ?oD-#:[7f㝵&^1НvX;jP1g3wpuXj V7/]䇊kky#M;ja) ĵ?;3pJdBGek4D{[/8,Μ5zr({(}#0kLaض#=FFKsKl%Xnٰ;d=K7~Kvmuzm' >.ta3߀/nZ=bםԔcbγqЫot]lќ(8AnSFV ;2Y:XX>J%mPYϪB̾AYօV՗\^J=Œ-{X&@ kEoF@m$3@JQhAmb$Tf])Qb<JjhWxNҿh3*oI$(ęc:&xɖ^#c30n$IYIlF3 Vz~N1+(W1hB'}Pg!vU;*`ұc4Iɐ;{!9_73<P82ެz^dNq.p!΁%<ll.+kxv;1ɭa. p?J}cIꞑ*l 0!dTwG 2*kҳcv.;z۔.&3TG]{#1:o'~`&1Y^fN a{#:Ng]EB笊Xٲsc&YO7}FZ-H{Y/2k45U?)tzX2SLr$/ֽmy샜aIgsgQم D=lhGfNF3IBTw\܈5Tr I߷ ;?! "ϢPaԬD9 yޖz;P;t)EO@%2U{2N\Ry&{軷`Xert< &i5]ki<\49g(F-ɺtL]8&r*~q|&$0 -Όtɸ_Xx F21d[Pw`S9_kIuqDd>Yd672VCJ:=jd[rY4\#|4C3 Cb'%#F̂Ys"3=Q)4˶he;م]>K"=:h߳(Z%Nu. 23%oe\ސW7,fe6WY|!3bliVQe|Y.SLilޞdAc$i !XEEz$*Dvfj_=p:V5Kzi$"WU2_QtΪދѻNsuRѩqϑɬ°4ޑXߢLv՝HIu^-T Y2`?KOV]!e%HM}o|7-;\?J0UG_(L+J}J @4zI)EV|~ BXB'x PUi)66oN2cۑ<3V*P(v :iiqZ$X`e\/y؝dtVXyoE\9u]zAfm a+4UyԅQwM9g jSظ yqG9T@) PYК3evQ]BHIND[HoFꬵ-iIP='hN[o[HBh>z#R!oؚ̓+i_vhUKJd;[]1'{Gp(h.ߪ6bU"y6ZeZeUT*$UErb J,Sʳ}fD:8N'i S-J+3f{s0bq^f?n):&^XS'e?\Th/xg R1'-.CJ\«G&ϤG  ^UV'RmH⮵OR5KrٲځغTkTl`LG9^ӳ*i8x[>KhY˲~?2fU,Ne)'L֔dYK[le= 0a:1F6913}L11+`\I.7=]cL}MXcKV < SE2YO㹫 UA$#dwUSv (Y @ehhUqLP8b6jcsbJ* .HY*0 ,$áu% +WZ :+ޓÄTT *DgI["2gЪs} G aVDic&hg5P "u]eeeǕ>Av 4V "U͠:E6g#I@sa]-]+[,T$ N)wW4Q-|׬b :ʛ/\`DQ "BaI-iP-D\d/sb?:sL蘜&&؂ 9c:&`JScF#&Wy,[091ɉ #8~y{ל3?x:{8U3˾3ǟ>8w6Lyտ/hyGǜ9'>Z2сhaB)u Jnё5Jϋ1=YKb I$(!6T;<4yFsoKzUbOϞm9#+lv"{tJ2}p+xt`0`,YU@mQRjFxѮg|f7tQH{ɒ,q$\hU0kJ$>uȎ^+LCǟd۝q$DgV4IWd셈2ΌAVC3kfzChIkS )$ \/.0]lo㔷;,8cw\8 #lɑxWg翸nxŏFXz7ox>"/N~N:gq'b;,GO~KpNa")A=Wx.Udeh2Q˲xyωYdU*V3#Vh˪*2NF}먞HQeVI΁dԳL k&tۏ{[d+b&x2Ldz3mg[ea8dABCXw9r *eM%u PQzMU 8Alo2/ZF"'t_jBKOSĖufGKj[5*Gu |&҄jxj$HR%ڬLQv<ӳ5Js"Kcq$C7V]!%_fd [wOx`W\w Vu;[[a/ +=zvXܱ|_<߳.>;`;[{ȀM_sQ24/jSFR] c vf4E vjEE3{_[*&Mg8"e#LlÞFDQRIgeY[sXOj!Bh%BpEےڮ4S6 BVXWcķHh; uB* *j#;7#8c"Z2i²a[eIEzgVA5Kg i6oX JvG X+C9l:D'd%K E62*6VhVL'7 IDATwln<!! e,hP?-~b*4RϒSO94Csn ]+Cs&|15edf|8|sݾ;Ntv.ݫyj]?xÃ^b}vvsL$=b;lr ^}ոݲfs[wZZkZjZXcsxAj<'Mp<-ﳓ_߾_q#ek'?[׫S?3 39oWݸ{pq7كco39D<+_7~?'h@,LY2B\XƁ;:b &_#>{WEe9Tbz+ L"w@0WzD]3ՙ8y 1¾/"EH˲w&1PC[%v"M=+㜌h w"[DNveSs4 |#>3 ~u3q97sG6GK$g;` sCA0ݜE$|0`N(6T$z$lj'9Ve)Ka*g :GL1ơP07Qq b^"b0`K8gjʱӎge^x7∂Af6t솣N8 G~;? /+i0//~3xqwV CqTA8Pp2S~Df6k`xYkt$3c M0Rgr eO5`w8: *!l4 Ⱥ3@s8TE$!Ag% ~~wUE5Wq39f :OQy4ѾdL鿸)-^S$2 D< D*$1L^^P05liJ,U0uD"o6C~kQ>'Q2 2 4ڌ45#LLӝ`·)!Njg٬zba_HmO!">R>s@6 Pgյh4Q9ؗ df|4 Lӡ#zmB.5+"yX`azRsĪ8~Vh0;yR ax_1 !g4p_,kx3(Dq=e5lG {G;B5J _t 4ogqY2 {z\mWʧ&{IlV{CȆK[Ȧgl1=3ڣ}LE +Zf>\7!NJb8K%P6F: CfPClU lIQ7H_TJNVwn1Jתbzx!9,\ I #TIuAUu=O45 %F(©dB#^ڞ!xܟDq||,MD:mI@@/MHΕ>o{}UC"YaQ2e+Tb @B\XBES!^O$:A3Vr ާrC0g:h0j_ `p"" ]A+@fUVAgyBB3tZV(1H"H\0uR#N Plp^!*IMP Qgvh̑ ^&HQb*2 %HP23%J"P3] N3C5$' ]]%W+=>xւ)}#w(ɚ(?[`%-G XV>؊ ;#aDv:Fu̪A"7i}%%-M2)eI91%oJ.Rưvz8)uOpXyW;$ IE<9>_Z <4pd6L6}R)C}I #Zg P|L(;Bc`QA) tV-{j ٴ.U lb֫@[&zPrn\豴 "IأzH+}|[J ['QJV@姵Z/a#S+X 6$-X)lhWe]vxr2MP*̲eE tdVʞ5fu ӊ%$g̼V6]2 '3EQ+cO|@݂-d^(3r;Q*]ϔrvV љAi U|ZLHNdBkXYv:d<FnA :>_t4uwنY=:wwAmglQ9bW`U+kSeE3ֹۗVчa8GoJHe&>jk ev !T YIc }|74!d=fTu.4}uTz>iNo}\g>|:"Òi{PD3 |`rHRw֎BJÖ b{ vaZː~f\Uǘo$/{jj0`?SS>5Ko%'|ވ`ճ҂ƪn5 譧3ETPYy6.PeV21F'h^ZY@J' i >ΪdnSyqvb`iB"t-gDv&3]:J5ѶFI" }NJeaQ e6N9p}RDs=Ss'QVs:!Md?i]6HmU˕d\[l6Yy#Oڶ'Q_xWw1fI#F33%ѪqL']O˯⥋g8['5ϼ݇/56_;$TE'F u A dޠ]ff .P3ܼxϠP,Hɕ!e(Nt:2"Cc<6&&_4f/'&&1}4&&! /bl;pgbeT+(Gъ^< 4-^I8>JnZ(5}5btv--'U؆}#"G.u *:պІ~2*r WTV-*Zל }]?}o?t ev /L$2l X@T.Џ,i Llld"PF@ o{t>{?3k!eNڬ\W2[E!*[}&d6ޫ=-KXqn8DL+݅/L>@ZwI ]%UԪGbZ:#؜|=:E+\rqiʄ)$௘_u*(WE *U d~TiOehd= TXEVd@2,[U'CPh5,^IS}r#Sh`4ѓ6Mf.+sc=gW>_y̑~QC|6PU GX D~V *;P(kMAENU.heD:*)MqY*,3:",jsLEHukjeWTddcLQԠs**mDհ֪R:lG&#N23q"!E N*6ca'C랴yFZ}MK;HCtRU- YaIntQtKBe@/6ZPkV"|ʡrqE@xb/lVV-e( v1JP0Q#i1|4*dE'JGf{S~~9kw&)HTD;#;bDd$t6ȁA6]%A,ORZ$mI Ɂ ֮ p-ZcZyݯ[Va h4{n.٥߻\uٿƷ~_wϯ^??w7_㲫=>}[Ѵ'X 27YOQ5XƄL噰/ފYLv _Cu*LS/Ȓ;gWr%vSMWw@T"R؁TOICyIH 3ߞkIUX 1E^V^TK\s N`Yi_(,p,d,+wFWqZ6=nq?kO>#x`v{O ~s_]|nK<߿]]|g[mCw2}= f,GVx0vf۸JL[Ek8S)X%3kM)D N &Nգ )R=:*PQڷPeI3:M9Mbu2Br A 3%SdAOh5pWh!-le]E8B6HTa 6H'ikqe+ t-ę͂Vj,$gPl$Df] {GZMuG<Ђ K)!f\({E*Y렛 KW.I DzGVQCK CQ 2j ;Y!wώ\ jXRxPveS Mh ͓gG]:]OqOoM#63&-d] rvVTH!n0PvB8PLnj1wGr/X)7ń'bгSkX6l`Ce Þg<;R}[ k! 7JΝ6Tag=tTCȳlPd,>mY"]Qm/ d?"WmB] HI|K4τDy$|bٽj%S+Zb+0iaqժL/㿢n{]vG7E>` ׭`w} -.@ʫ ;hsDծK?'d2Rk}V (ˤGoXƴ6|kZ-<ɰՂ Ja -ϦYգ,n=֏aeav{Z%|ývUW[</ yޫqՊ3o_5O,.ۺYW7K8@bfIHQ1PS ـ\DXuXI{Jh۲Պ^Y'ې$ YD˞5)Tвd]6moS|?L?1PUL@ikIhT=b-ZVq#r5!wU QxxcÔ15xscLK~ N7txe;oEs4Jo29o |q͟3_mIp Ilr#QZ(8 nX2 {̫XyUp0NP8⾵NY$r6 WeZͬҢC`٠t: DUϠbֶ7dLL٩JH# ~VNtm(C'Iż7־S8UioDJMuO&ty]AGG% 1}`v'OIgJPü>, w $@V4ڍm!O|StL&"Ua#ZbG0*>&Y[2sX,@#̦-2k(^BTXH&%$s̞,ZtLOM}֛ma=nd?f?ٗK`ʗG<Os7V` Ȧ?{'o]p}+Xc_=Ӟ S7?;~ݶ!:FcIue#cFXLTrAYn2 +3P })5fR,S6l֒V /ﰵ0qXk8d=lB@r2QL, fϲ8oTT95Z8cC~&>@bjύWKUec!lJ 'U,ZYb3Harp|g{uwwBF߄!dMTDM<]GC*Eh$πr*1*#tP0Ulyy W6mY2."̟b]Kf:T 3weCnJڕ%\ƾ]IN0oP1eΈ"$wYhd&F|;< վ߄>Ϻl+߁.Eox%'q=y IDATAq1c8̷og<6X ?W:Џxyve#c,:x9hHE5Gg}5d$Q < :=A07 _Rf!f2 hBJb b;@L6X@#9uM{ս$]١2Ԃ+&w֓**}S/*0PWH&Ǎ1]!V}n*z5Vx,zuõ9VJ\Q%,!mҍfhty.o1_y $~~ Uzb`?1+UTgģڧg;KDST^Q" MG `1D F"z7JK}la1kf6ۊW0AESFqIw 28EG>tJu0 #< l:oN,^210a[/``mǣ{*tLlo熅`%6A0,"x p+(R.C&EBԅlNT̳w>Dx?]JDFAYQ=BF2ZϜ" CݻΜ#gtw̑ ^gۅA Jdf{,H4Nt3n|XB]ݻo7YVC+[F+Й<?5CSAыsUz(EI2MxoXUQxzkttRcz%#ryI2:Rr ddJqdfMJgF=XdZe^Kt T .\vvG~YPbN2Xi[-[sL9krA i&9 eJl Ͼ>tٮ=:U!ǵ߬jg}jgS&+ {7zR-__ 2#~Y%zm^GpcjW:e#x,D93T!cpiY]lNIdxrAA/1sT CpL1-d=cUȥS d=3sR}f}jFg3Z*C @;J(@8yGO5!q*D6c&?k9!7]Pֹ ZNgy@KI&ע #aTl-B5l @+IH'17|YcHN3DѲ@"s,[cXX:u]ws$P˸gs҆0Oɪc,xI;bO9zz||t? !09H2X2r6(Jl9Kt4IS) pi0Po w* ϊKg 011ܴ.}ADzDQ3n(`tTg! FL]H24j6MhkT+Ȟ2p v "sDpSAJ d)4u,DHaP,}b؞)_D^M8a&-XJ?1*pYGo"F#o2q : 2!Yݭ6U,쓲l[V5pJ~~Q Aà VÆ$A2!Krd*Fι$elI6#| ť~d DΎ̊QaxD`x$Ad2ɧJ ' L  /Us*EڛZFES*=Ai1RhGTBIJהdSl$Zeqɲ? TƱիpqDuȦ0Kx}"l 駷ݡ[YlS̲Jԣ'ZYf"H'˽֓%Wml)eY]Rv²g%Hd͙ϼB`ZkogaU]oTi|&k"v”U]zއ^\*_C#5 C PLn _ou)IP~>~Ъ1߹G͝F0(X!BPWf;L"q5û9N:hgPw(K\!{ Z_)|A\l8x6Ԍ Go_.j#Pu%g/٥IGdObnkV6;= }(ꖟsh'B7611D L4 Mcbbd";_aygq3H^qxlBptn 7_Ϝ=Kh*c;g|^vٸ88J. с%0 Fى\!vB@fY7,SlJ uk˲݄FkpZW(w; V:'#lågg ;"drV-$~ÏAƣkp2g9Vk n|vNƷBIPBNWϺ*ETC²jpvٍFΉ`88QVO8\eQmao,t.N˓*a%YEk>3ZF& YUJa$yaIm*'0Y鳹IFۓT*| >?겪4mIbh0b=؈yU@XvrEnEnDG\E,8B*)ˬ5"`oiD jHCe.5OLLx/~vy!o=o=;l`U}߹rvƑ7wK3?t.va遯{_|lyE8\9zgg矈mw| ^]w§'`$d9L9 Y(dI@=gP٤Z1˶ SRuug!0w97QFg2 EĊpe3.9DсndV&k<BF]F1l`CWj~(㱊|.#,fpL'{NE;PRu.ܔ-hو @cgU/ugTU! WP\\ !RQr&Stݎ2kUepȠAO1`U/uALwRVf1 7KBhpoBC]Pa9`d3 qBjê16.3:céq ImCEf08ZaƁ;8+lV?\θ۟?_mJ:v[{}?<.{`o> 5 @ G'mcv .'G@2.6\< TeN$D $S* 6{A툐O X@&ـ{FAa,)_H8Yywؾ2]&3G,5׫$swlxz: +T" 2ȨN gwa~7 .|,[@}Ui b#u(ZhXaKA$ulc3%Պ@{zy: .+1T1L_IMa$\ȵzrNvN wu;"-O{1>οĝ_zXO/}4 ~A<Onl%/]k;oߎ [v+,irB߅4%0([)=e-ZG~WCQ='B\g$vgiLX}'[{&f=sgZٰK,~W+?;q='~:D}De@jL1t$7𪻤2{LHVfZ ^UH>?j#m ƺHLYll%cw,s( Y/HȄ(%T#Z:fB@ %l7;8b IfcCf42^$>% M@Sݜ9 4/*)XVz&[̪kI⹉( ,"G* T`7u)ϱ"x#rl"쯡 Yl(Cfؘi#ՠiE.7^{)i>1@))~J'dA67c\Vg0Wi%cg tSGlMoyVt߰vKll3{ǃeXzۥnx>{c?NJ#wln w􃞲o䗸} 賁Dوh:BT\칲 >דݬ,y9\E%e:^d1TW.ASwy4tL"䦟QR$59?WbMz>d KqG{`g@ PȒ2)*y%wްJoYpG "^X٠(  ~hߢ\G9 Wv[tu5 { YܧV/=EczC͍l9S[K1ORIdCu㉭Ps+Y)rRsQ\u̞IG8{p޸kj.پg>6α ?{nMY =Γ1Pl@ ~lF͋ JF0'4*נQxޏKxE'O:, m)By좍nD;{Neb{F  ŋ|)-,o*Y⬣rLuZJ)_6{JвZúPR%dݝMs %sFm)r⹚Y+KQH0h ʔ}60*y!@FJ-pG;? leZL , L`y{F 4y:o )yi:gJOK @fQ͓ Ûx2zht7ף`XfAУp{6Gq[#{8ls;Wc"lgiCynrPXBw X#*SVGdq*&k(0ĩluf\|]J2risyyvUJ,R3 x.2% 㼡Uy07IXBe#T" YhPMAS2Pl##S5Q|&(5dDo=+.F( h.#Flef⏘QU.Cj1xoG3͗!ИΔ)Fpؐ/$HzLν=jFYteQ"ueУ~x_bţZB6oS߳D"gVz7 IDATƐ"-Cp1v,FdžպLtg2l^A HtMdORc]% K9GÖ12DhpM +EB#5D|k\B &ɲl.e0Wxo.9/q/ xȢTÐENҝ<àHؠc2_ˈ;=zyޤ\ WCbnp~lVp*섇9uS#ßỜ貲T* xcٝ 1 /ZmA^V6\'2XɳJ2=rqFxCF;4/ęp ޫ&HK{-GυNM`f3̨n^'z'ϕP-*Nf<>o NgVla1^ g^AGɩs vυR$3"d^.HTMk2i!.E])僐z!Kr#؃t,vP4r F(*Le3%X8| $_9,3 ,0DVFSԚuķgQ-FWQ/CA˩p\SpT46pU`@L!sܑ,PhPɧ PXNF%;DM,Ia*:N2N5{H$Qx/eKݪ, d˻V$%- Fq뙬)>$@r3'V`sι:d{E@[#HεD+cN[hR@ͣ3 ⍎GN= L˳ E?G#AR $e~MdVkW7E9y:CٵfBJ VǴՆ_)pZjdmZS(ka$n,1be[RڽzJt5Edn1t˖5 K(!bHTA0l cme*qUz&1bfG)$2+&LI#2b[8=R^~ƒ39KVN$l@p,(cg=Lռ?KX[s*К 1h$b̦KT(_9s&z t/SdBtqLVRp7XRغuiWغDbW:3;Lgd-jDXoŀ_WZ@Yt L+~;1jP T&-37DnOExW;$:3L ñs~:-^~Qa SA=|Ef)MǙeSeBpF 3JCaaYx n)s>x<h47OaUMBQ=Aŋ=BC!}i1R!C9uNLV\9 M!XETq-;ܤU'SCc^[&2$34#tC1)gbv<uoЄ>M,82Bזg~;;$22HI%>D!t!pcC݌ˆ,e$)0 ^٭+#!2>}=QQ,6MX AHr˘a*CT!%f UKm-IY-=1ssSc /y~dPcT:9%"d-T Hl=~ ⟪ab'zJFɧšh)]g- pVo?]`o IL >{Q0fgPф/c;'=RWW&-y$Rfc[О2V~&gN{gnT)I=QN9/y{ً̗w!$ר{qID"OtBV|7 ׃ְ׳Pr@G湜`Vd@mAkECvR%sU2.L{@*`Bƫ8IېpاA;auZ~A l&)X)&594D$3W]n<%׬fR(sL2bqF4AOL Raw1+! t%l\8es+!OPY l^{PY$F͡U Z{@OW${W W#phܚ'cs9ՠgts<1 @-bHO2ې} 3&*ճs& 3tP_͕S$ LV`AytK{gYYB* .!cXH 8ёI+NyRz&ɝ J1xXbg^ qN{j[ظ*KU?la([Ƞ1>V= @`!!>AfՂZPmPLK(.VJQkCmWw׈TmO!UNP iY=igFٕ?J#EsfѠMB!!amJX/. p>^r9 7leG=Í47%}I ЄB*A( "ZQp$,wvBI@<$F 3Z#' b33.Mwv4J L&4 i"t627ŞpA'm(YAݮ>,f~V"i^h360+!ff{low_Sx9k"47*ň33K VK}P04uNߏena½NfU%)#lNompj8˜^Tr҃ {]&ݸb,9Om,i! RI %kzܵ}8O׿+>N>|W7}_SGƗ/8Ow<_?x;;?|_[OyԿ}}`uom|1^v::MҲwu x< 4 RwiVپHr.˚!@EK }}| U'.|IG leiwl*i(du)E5G<#vߩ(!aTmYB Oo ;:N>vﻟ~}3b_={}_ulM/6XgXeWڇ>IW!__>jO{}{݊oA+N '$Fʹ$`˘Dj5~)ӉR}ʯ%(Ryo(MRr% 5/ry8-oolI6w;Kנaot{I+@w{AV(C?C"L > d  >J3{~w e*(H(hNm>{D} );hzi(B"l>hE7=E!DLP1؟F|d*[&zar7+؁f$s2)Tee %k[7+m3ruX_} X,~b61Ͱk\5̣>U[W5nVn2~Oy/=\yUxk^w]~]igJUB7acaQeROċRhVZ.JTHTD\*xcR"P#$[ˤ!}ـI1RWMPd>(Rb}Γ(nd5dȲlN2(ho7Z?-HQ-7; NCFټXW%Y*n^mfpe ƛ$#1nVmP,n]mF랝`I{WD(JEݸW"uЍ.u-&1$`bp_;5ܲo'{'w!<,<ƹ{f?9r҃]'ۻ>M~'<𩿅}w7^3vm,XO]9J.m!ɍ%fR!Z~8<QffW7E-A!`R7= d~T(ƜJ͜#&dL^PA8Dh㋗A Y !f]SAJ)`*7w .0)fƂ~}1Hb Ld 2ȸ(3Esb z^:h=<ӒQQ1"@~þuL  Ќc@`ys wO-)1P& 4Bd'_2)wBJ\ه"J3`3d&l lwgGmؑw 0`?϶>v9|ٷ0H׽n}8ţu\vЃl29x n6deRRPZ8pee `F{T1)G19)%"٣Tg+XRdaXj9 >8eN$<1Tl30(gqG2˜̾f*9L c2P:pc13D8cev@dͳCR(uo_>/hA=:y/]d`⛀OY$D{3?-YW3eI2zvܵp{4g \Qթ2QdX>{Zi$l q[hN6Q"0fddJ:C <96Vp!3:g"Xe?Ӿr{1bS܁cq>W~-lω~Oy;qi-x?>W=tE 6IJԻ=EIe1&Y) &`UɷC6㷣Fݪ`g?`P&_X@_^ƥrd53/'1XDږ{/UY,]_*{Wu jt([sE?tdfصD?cO{]|{G7o~ 8g[be;b P0$`t5 IGFl#I5: sՉmm FB?e{TAuxYLAezփPY+?Ɂ6V@4X,9L':r,d1-gvгcupLE,rFnOzV0%I,znU†:UPL6ieypxihor"#S1rh.u=4]";s$ƾ=Xp)ūˇdϋk41E9ٜ˳x4~/\W e}L:i U6>_(n_\#ޔ$ޛ5v%XJ@hĆL$,;Ls?LF5* $LtG6j TfEL?tdylvY\221#]T4JϚUNΈTM뿗Lxe>NyGRSm/'*ףoG*A,nal8D|@e|(˞U5tBQ213 Z?dmhӶ3I]D OQB).z\;HK|FRajM1%UY$$~O81uYXˀgWr(Ac@TieZ&Ԡ ; E,(K!(w*+:z EV4MRmoFB Ɯ &&+FYgg->쩨Yo#[uP"-:ҳP#JJ =S{=R^h߉zaw2 Ȉ:qo$ mVFΔxhR+}zt;IGw[3긲 z t}B~d߰~ܿL?HӶ$ɨfIPy.Mv&QbZ˂Y%;2҈teqU՞&٤a=2H6ߛFeLP]~D~[Ei;g$sg".AHXAh$Xe=XtQgw*l7g& G\x<8:xmYd ڹKp>2>0? +- IDATV# %pxKuHZ{- +瑿[F B0LjM  J,Yn DWG \* qyb#삐ٯЃگKP<ӄխa=l|4ԨBTыN+oN}0iҎ[nL+UŞutzF|Q&~$ *S:6LGAޘԸ!H<cn%T]G*KOA$qDK{n~l f}kPdUT֌u4ەE/r1F}P\{Ne_UsGe !*גARa \O3V`N*`5U%$s(ixP2#u܄~>::so&01ԈD =~w;̘<"&Rt"L`&lsZuXQ◝-Vk FXb˄֚"E5>UM2{-+3M0ynVBJȪJ9Yyx rPyamjmpgMT&y"^F)uر5lllRp7`ߗ/}9 ނ]eO9~4~{ouc}}chs~Xllm}cX߂]y\uX,6|ոo}Q|fe{pevMlE$S ن. 0Np @ɒ=2Dv68Uv2tdb( ^4^2jݖ,>ϪzDByH/ FlU{MUHs8ª?e!P~M 9T"1X2kKzNqg*bKxM!^Y|88CaBEc`֣m^caq`uԲJ“%b-1:4U0>E@na6|mn\ś>IU?[<oexP l6|>b g30)`# xۧkm/ǜz0*_E? =K`]+x-$P6PP QvB!0}Y^d&L! -nKrCNlT@CғT0/{.G<П4Uމc0QƐqŵGzJ0QnVc%G 8==²ՕbsV腈YJZ )7zvq9*xB+R=kBaWxƋ?ߍf5^x7;ۗn[[/|5>yK{ ڷ?cw=^kךͶw?K^<ůyx3le쳗y>/>KV`»핿A?vAWƟ̀av_[[SwíQTک)tlW,kE)#i67lM߳!Ȧ !o h$KgjށADV ab깤A4P DVTJd) F@**k$id.{X ײb1GshR8Rw@&4EX8{-6(f\oPhYuɐRn[*1& O0e vRpmC\#&Ħ$ R(o?A οm*fdN*Fα.Ng"p`YMtD%*d% UI%C*W% G`|.l6_|8'Z+.Dܗ?to9t<E}?]<1‘ Ogw$|yO{<=e _z}p8 p?oNc/}:Hǣ ^2<.q ?hOq?>+oq׻zftu a^eپR P*hBYV2E)eu\?$s KɚS6;KA`E Ġ/&& ʠNN꒬YG{v 62)RdϙL2Nl);,ztqӧ;j{sp{c~^?wq2#4Gx}]0rSok-v?='\dz-s|7.{NY;v~}A;_OEXM\wKc1 e¡BIԉmQXZmN9:g!נ{WA]g[ɼR[LTN ֋GJTrs9fHF;z/m2]kPRLL>fi:[l2Ąs q.&vd'=1\8N0 .zMFrK}-3v-L37|AU );+FN֤ SPhlt!j#mT=kMu21wc߯bg1a8=E{U^bG`,H͕ WӪ_,XfTR1IJ*yfM-FJ8$If">n7^-n;du)8mwq [l7ml|p즭.`~_{dgGU?ݞ𔟱?u\{56vﶵep)>~?^b9aضn__ƾ[ly [f;aū_|}8xyqWͲfL۲1v!$11kt5(:w־)"ֱ :W,3Va K&S4ҕ?E&6,"$H2f9U)'cDDUw*^EE{&jL";!uO Fhl^3e/Tg;c]M;-u,IB"b m'!`,L*TB6w´˪@"LeɺX *3=3 LlY3xǚ՞H] NU'5A:,Xv$nH% $1mUTqq` %Xv9RN2c{`Xia<`l%9Ep=Gg\e\ynsd{?^cë~x^hw?.8pϿ X,` oŭl>sZraƷOx߾vq)wiCb3uؖ(+3hK~O_(#y8)?go1GO>^KiGop<~ۏzκ?g=?w}a+?6~Wn'/]W_Z~j]̅`5Kbriv ٮmUij7Ζx`kCm(:FhIp5h7R%q`Y?Y&FidAwbbw+K'¦.-de*ՊB Q;#jk p1HuaÞiDЯI\.\vk 'J/ɘP% <2/[,F{4/jTҗ' 2Fs$cscʝ}`r&~2Yd3 aFEUl eΧv'gv`cqg+يa'q%Y_k m7s~f"YE Š%ZKq {o\TP)mf/g8A~/?7Tz'_69qꏾ#bG >G٤p<1}a3O͟{kx<+X+K\Ck|<ď?|{3?t_w˿U;/? o3_xOq§6s_lC‡/o]LWJ`]'ZV4ʝjpoXS|œ;zM)/2WҗA9F%*cП!ДΨl_'_Q{0^پ.*.⭮(!|qS3w(^Lv}BZ19sI0Kog6˗4@J9Yf6BGV@MHC$!ٜMX, {צڎ%l=u9~g_or6fwyEܼl߃b<Ŗ 3suw,]'/xvFfOlp` ?_k50 񸟊sp`mvMecg*dX)6˒t6;$ʥbvF !i@l,˃@b.YbڤeVe4eaXJDHZb*)",B>CVC<񿪂cl*sFAƾoIۉvYrq&`JQ@<*hFU=iWi*CF.Sw_`c} wWVV0\0lX07}f3:|uwl,6XlNl++[f776XlZle+`}aX8fsgm^'l{o}fn뾱hlfXms`>S2`iRN9u2eb$z&˜R%DQDZ(.- W\]<*E#!& &n?(lۤ-=3hXN.4 c8Z2%-3d)..X`5f1M@ MIpNlI_1TJ(t$xS2咮հ B.y$rvAy#qM$L'J~W+iFB`~S:dL8 U/+!L9Y[֣cûL`B'(Ӱ_`u]hi1"ߓ13yq)$2(B;GgYPB8l,2bb6_]/Ws6| ݳwD+sg%fXYc6SՆ|5\waj|:^9VS5;fj*2=zȑX ދN`&Vd'?QN~]ˠGG\P%+hl]VBE5*aϹ`*'V VgR\T8q|PׯD1^؋جlT:#dTS+7B}%hO8Yɻҝ!!#Ubxʒgli#k&d#i0K/!\˪~7 s&XԙN^FlΓ`|Ώg1c8" VA3FuL\t,{& 0XCYfb[ UbRz뗰aCJ`ṠUcOXwRJQʚ$ؙ*XUEDUnڋWd-Ec=V>b|׀]7VM y`/ZqtEDY ~slي逿ʹ䫘Q(j6˜XT(G Ңޔh\* 710hn4%u`:6ܳy!5hL0"T:aw*^Yeit̫ZrQa;h(G6r\j .Ce]E1l\ Gl o^P|Jv,?{S8-  jJ3Kt0{.1bǶ`{gx IDATTб1圴6-.YR' BN=6ijP=3֪v"y6&.F]216q%}eGvm0u3^`ꊾӘ clo'YTKԱ &.T} "$X"D6ub%K*Cݥgӌ.}C /z9P~ D{di,I*?o,,Ώ7|7w4fI5g]VeJKIk cAܤ+)P ,a/Hk۲" &`r΂&x@Y+i|g#$.B Rg2o j#0s6פ16mi'{?~5RpCQAC9OQd5P`hE(;ɼ:+ǪX'Z#J+Ʌ-`64K(] `" y& wA漵Q0vP*ô(3%i(tz(7y9 z+Jֶ18՞ gԬ]Br[%JiD54v0@ .踧Tlb/b"<Y,-Ӊn>Fi|Z6-M/52C 9XKILD:yfd4T5y[c+ F>. ca}(ٖ΄ S&|꒦*]K+Ygq#jo cR$G,VkA ǁcY7PzÝ6 &qv\Ko{'\0xi Iѓ{fFH1|+QKʾ9Oq('Q[F@"DU}doKR( ġ*jr=mVGxdLΨHWgc`"K_Д(*4X:ߒ#~}#E`YqX z73ʸ)E梛09hԚ@&3f-:nlx-Cu{zy XL43У'(.eǵDYa'R81Y{y\-P }| #,g\V#~Mf/-6!`~FH;C¸yJR]XX%N&DY]}'dWA·f>TbgwD4{S꒕.Դ K+=[_hP]]ĥƋDLb{ɳ,;!9@T"sJªh(K8-)*dI$HHl[T 8N13d8ٙBaul+ ] eE.cjqf 3mi"PC@N >FJǒ%/.g˚[dp+L`'#6i]5iSUXw{(>Gm1#: 2K |A^_AwAki18 Uɼ1,,fː1b6@zXvdzz^ʞHkA)Y-bU .:Ȧ踎;P ) wkcs doFzEٿXg'"kv^:JL1P}̪*bb*1ѼoM/%P`wU}$.cO', .s"!47~*%գIM{& WOoӛޔ$ Lq`6 ^WQq,MƒgeoyJɪE#(]*F;N)eez׫עOX-ێrYmGlaJ1Q.6s@qZA*| +\dCWT2Ԯ`c_`.uUԽDYM =(jaʞسG a-ŊQW]2%2l͞;eLuF`:?2hB4}_ {g_[dQDq'\WAda_}P+}9lTZة UzoWUp3faL53w.Y6vrVA!K7?mVܸ0pe.@Y Wea2"l((R2D{2w_>s@yAxLTr𳓋B9瓏e$%̯g{b/[ 6J4L eV9?G{(e%&Ӓb9 ǜ˄Vd(tѣ .2VXYP^&RMg$ԓ8 <$ '4u:ܜ5d쇜˓R>L.u \{T)n'Cㄪ3;;XM0͌Q#v&?0QE(lyLJ纹0]YSx+qc>S-miGKWm/<֝|?I1ex ٲ8ք_d0Yl. un dd]9 "/Q$i"]9S"W ZZNg#H!΄oegC)G"吜wHvzx7~"l_Fx0!/S>r&ɊРoH29g.gilFσ"qP5 L%@INO[.pg4 jTޑ j#iB#" )E[ްn떼jȕԘvbwcR uH3t*=Izp$mbeMw#}t]=ijl䲐=Uaj)`m2WS o_;VEe4y{3a6"Şg<êD[MW&=lAmQ`u*i,9m$Q#ω}fo>Fh!gRjg- rwPzӹzK3Izc%`R 6l ?핚9K!/7t)0<v΂ Sd Bd@8n_^܂-ِ4alUdr,}7XWiuhd ;8Ά#γbY̏ZOf+AK1M=0]u3>6c!t^A7C৴uCc]!j w1 z.QWq}EGc]uxoM}~rru`6ׄWe%ӛ*}{3 .FtsV@plsWuus1FUBok%ιU 66uV^ˀk~ zw6J[(#I ScIb"N2klXS혻( VҤӕІ{HgbliCdld.#|Gq\&{:^FkcQT@X@[9X4/2|djX}f6`\l2]3w$5ƒybLl`lL:{|/W{gǴ1Awbgԯ(J#j؇Qڷ@)lkL(lؐsEA 3y~ bOٞPjN?ݧ9>wY'j ;/λ?i0=d=OI%oU seds,|,sTMUgbe< NklMFVBԬ*W̙1ͬߍXJAH&Yw,gkYRA.[prUYڨy]RU8Bى}EU],*]%HU 4zj\Y3=&Ύs p:l_`gt{w.Jsl~o1UIM"5|dw*5SWA+ nHuUJĒUi*YU(˂ > ߜ -#}؀wv0QJ)Λgj]Ó,2)e J?KţqJq.q& %9|;?6=9h75`ge (CXL܃( +39qL.J`q0Fx"?l,k#@R3&`'PeC - D2 snxc]be,7LEIM .Hؚ2$ m11c: "5{m"d%C"uzqo,E1Spǩ UpP1?]]wED v\5/[BS=E?/eA3!>`9oK=KQ?`RcU/'CuU;欉c =#;MΝz*1߶ !kVBW,T "RRXdg}1M.ޝ5G|Ҙ2Ba#-I`ق1nD{41hd䠳䠒7q +ͺ$"YQīM\c*lt3f q&v3ʾaU`βkO M=? ٤@IjBKnD9~ĖhUYFT,cHeEd0~UoUPjV/UIsS`Bl 8 Ib[3Ya8gmOD%ىU \8;u"8 'nv& صbs29r*p9yu8o$0qLT(fz@ VRGQ:C3ۯɣJDPe=^-V3ݳԺ $k*+ӽg :Z2FbbD%PbNU6HDh!.9EX{kנ7TU/U+4q`^5(CvyG܏lo4{u0_0T6@oľMd2Z ~|Wjos9CKg7Ǔg0LVFUHxδF);6JA;|hxu:)4tsɳ8lLe8q+B 1FR6 b04&|KKEB1Mgͯ\ںS Aw,~gcX`X% ŞeC֗:LY= /Mۭ'Y`6I-(+QC ʰLyy2G8d X:9*MY{4L= /X^z8&ccq̬nX 29 pe*pC0[ `h=e(j{Yəa**R|H/aZf+h$YCC+ IDAT*(\!dCʻXQVić0b XQmh _!BͲLwQtPTVDuBY*o#m~UتU.U8iaපYuFKΗh;rW21UB[& q$-e$VMY\@,~[nwK/ ns$ NL@0f}IV‹v":xwq"Tg`"BUA=[)Il" Z:"֍a]Ȇb(MEƏU{1HR\ʨ1^"5[FO2&D)N3{ĩE݁lJ{:5Bl&;diU@wC!QT"e\2XLaGl5J)5E-^ -vW=Qa\ 'jKTs$I IRSmJ*M; ZzH$bIv^nX`׮]ەyg;w(UdBݚtgMjqMaşW)EXaE1tm+S H*q@3mqUp5Ľd-tj` _dΧ9~F4=dJKLN Q`~Tzt&"fr N+QhK|6fk.0R9t;Ե{Ubvi A`T̶ePiUc,h`1Hh;":kzs=ġ&s[>W9 HUR{#ڀ)ߒĜVGVb;Fx,"êzxR$*}ycmmŢٖF7ֳ o[ ]4PD% Q@h{Sii;:n2NZ}~RBЗ*8WLU9)c l"u(7[\Kenl,)#*?7Vy8@DYVLT> \;8D-xTs?wWWU_uQ/K0gW+'N7Κuw33:z|ۛiq(+ ^?#TI;avS(zSc1ijos\=OT} ~.muijuF{?GdgJ$!«xK^Tc1(s5uJʆu`_ھ}[¦l6ʼle0}aM}ϻ䭿yuWs)d~wDiIlpPSA}MԊd|~l$0 <!%#*2v"[eɥ Ua4ĻfXI\\]#I .EF؝E@`f6Í]cy~Q>ϩ<8GPevW 0gs6lDw>0{8nۇ՚N܀n'x]䧞7W.8=֮ ͖t_^ؒc\la0puAZK/F $SfleY IUp B'0rb"YGQ6~#bbLUep7.\W-|1ON붤_[6 % 3y֝1s.s \ڒps?T͝qf.,ķ>Ɲnڏ޾3ڋc3v'/Pa>s_`ff{9_m/0N<ᄵou_. ^q}iO~lg8)$;d-tTd.}04=bE&|M2׿IV5Bmg̀D@5FFBt,t>c]{qh,l(D{`` j!YH$R(m;.mYXgk5yfm3zVe٣{43KI=Fd+ d8}0ԙPU 1w7#{E~Q%ZQ?j⃟ǒՊX ^U [ڌ1kͰvl|vtRy晙s\?^_ o]w~{}3W|߿Nǩ'?K|붳/SVJ}>wˎ6Vl}}x|9տ,+0 O"L6RBACE = R}0WAX%<lAdLD@(=^!L;w\`yz!Fnj;R'a'N!jժA~2n+\pпxw tڕ kfW^7oOSNe1{:cnݠHPbEWSOAt~!ב#G(hP՛oA;m 7նB_Xo?{ =={v   eNb_2eBdAU[ѢE~#ىFCq_;s l(]4@?~H'tģ؍ԩSaYdAl}`..tH2eʤKSԼRJT >kժ:x_6mZjUi1|R-[-E}dc):#iF rj׮R ,?Ab+Vܹ)6|֫Wԟ?aׯOz?Sy[*D%،Wl yRrLƌBa3tX8kQ!{.+V S?#*vr OГaZ1 v@ ֎/ԩ=ȽI&*ꘂ&L`WhwiVvH!4MaUVׯ%ifݺuI?0"gϞիW֟+lnͰCR2;DjcY(&H "r#22Ұ2öm۾K+hҤq뮻RZBΝq ǍGr#-\ KXn VK.6lq$R yjŚt(C9,KXvrʙ=X+Xd[4n޼Y~YZdΝ)tOrncDzѢEu_G=gΜd S4 p?gyL˳಄e *S̓g^>كXH'Oj77n4qn/ 8Oe<~p~bŊAdXrll,_,@&GO/W\bHs 8'ׯ YfsݺuyEFQyzٲe4h\z%`֭Hܲe ǛYpk̙TqQoڴ= >}: ,> ]#h"6욆.k(Xb6~^@&ϟJ.hGʔ)-ɺ RJ3 y55je 퓖x2egYCDDSO='O5ݯ_?pl޼q 57xDg~j(ȋ_~vjNY`S%ƃ~]P.6۟| zvĈT_߿U wh(,-0ΜucuaϏ :[oMU0.Y8L3Ka*%$Z~s-pà?9nO?6JK< ew0_~s))6z8$@ 8q.Ur/Deev1l#E.] a8)Q#GISרQc֬Y n6d￯~;nhiӦ!jU~JH㰁ZlB!zGЌr< ?'"K=D_ 3z0$5y-[@U?W%FK :i|=Ҋ,a~MS7}7dк馛fJ}1gΜǏG`AOTL <3h!e1UV(˳>-S{-_zNVz+8י#G߽z% ͆5{Y6 )s!) p*PpKiE.u֗(ߗ\SzzN2Ɣ)SDX alN4ѦMBX:ͨ6mژԠhѢT',ɱ*vbX!,^zqթy F',a%¯={M%ėdTVPnذANä{hQCy0Wݺu˖-& aΪjj.alJ8H٥XK.ُ'>b ^޽bf uHӧOɗ^zI1~_46}] )5k +)g vfTٔWx =G 7C+zVcFZEMGWAg& %%4&Խ|@'\zôfϞ=!-[hO:uyAd0TC^[ٳgƲuAw0ļI~ ýrtg{׮]ttle ND*= 1*$5$:4=vWTO#5+*Vh&tO 19=0̵x2dL`QC>qP-|d єKO iN EX)!; رCerw`=z`b+W.z sҔs4h'gd@8s0,T%5lc۷):f> EL?P_K@:u򔀡jMtA۶m{eҤ5W\?FGy$Z8p[ZBCg?"͛Q AO( 2ltG:hV惑W3gNgv@MI}M[+Jb8 WIllz'M'N@O?pH  +n7̵D H Cd=ceL 8ax\"X²H?o-2,_}*U*gΜ9zhFV\ŋ?}֭[\&NܹsyɓSRUXAx SN2eJl5f/HZjRÏ>/HO*kΤ ضm[s)o֬UXzm%.BEXN#L5k֌bDEE!N>իw_~xגN֍2ϗpdF^L9`cyP6q2glR9$~ ?E>#J ĉVȗtƞ={+`Q*0 ڪbŊaWf޽zrϖ-["E;СC1AsOtFdddb ZWroӦUXW0? /?*2ȑLаעEC"Ϟ=k a r;% 12ZHL ޥa۴V:] [n֭n{ڶmOpá"*#eT^jմi,X~YW[`0yrS%#$a q^pa~°`[qq%1~4ԻUʔ)~zLJftAM̛RwNve˖۷ԩНÇ Z /*)Ipr,s ٳg_~1`bJ3@w90\O6D~gEP" z>R?RpuF,^xРAs)_|b+{=\5#GYn z2;hGyK.R+8ᲀYImvjkݻw`@UXºz`JPf?UQNn ㌌&tܥ_^oY.a-$[a!џL?M@@G)DLQEoҤ{Y/u)RYTw c֮] /`h:&& 64(QV ak$ 89r(ZF`dոCa+􎖰mذA͋O>}"MONOM0# uXh@%T yp}xleBT+ H5]Db%{ ttT>º,YafĐ+,-+\AkIJC<حn${ I)bccٳ'2*,4CV,$E kꁸCI]jJ7r̯R apfܕY =A*wKM$P"$*>>^[YJDMQIKBddȐ'9rTP tTxw~aҥKTb +S.\`DRK-stР1*+~'EBdϞ%+͛O:UP$55N-"3R)Ry LA &0?eIQV% [f\ JݦԲeK3ٶm[?~,u=`%=jԨWm9:fcǎu+Z.]`+STo6l믿_}HjСȞL͛7f͢0C^z]sK0T 믿 G LQxʡ48+8l r'ʧSwLB{bn'&8ǯԇ#XGi0)/_\rIJpFh"=QmYj;IMTg>5S,] 8! .Oz߳=PUSrPlY$q\ HI&ь4Bil Fj ȔjGEE6dAa_&;!w]NnԪU urv ~5jpi $a\1`Ԛ]'3!3n= )RU/qO?c(J" %5U5h@=g…۷b({m۶ 64nX M7Zꁋ_5wc6lHqH2}zJg=ݕ+\xqqq *ݺu3WOp"5kL(cWNӡ5o%U1+u`a "4˱RE7BgUG) R޽[IR ԉb#Q1_{2qms111hKHApT`Ŋ7nD I:m4;8n͸W_ܹSiIѳ)"##ٳ~z"jŶxM6ᯤ6ܙ9{Nd;wLSĕrf̘! `ˢO>/o0h@m[ mժ謃ww^D|2$hQ^[o^Pg8W_48h I*NM^!5;b< W6m`%NXme(?Vic"!r2WxP]OG$  u"'ŦgD`@"XL^%)WB*ɓ6l@Y M̺Mܡ "B]NЇ!MW^!͛7WN4SD0s=Gw1{uQXŦmS:{˖-={<LMTN0ಽ# s9j/ixms0d +c[! <T5⅟$؏aARzЮeA0IoU/lX/jSS(F'hh/B 8v/:w+JSm5o޼qƱSYڱ%,@ ȦMwl4Ym%K炝  R4zpVi޽[ d{$H(\*~tm<&MYPg+8P:'|&fUngM6jUXw=j>|Yvˤ.0xi6mq9C$k=b!Y˔)=@ҹsg%:аUЕKxwp 5A:tqV^=轆`1Ϻ-D[jUۤG*Up ! .eqyg:~x8>tzJsU|Bv <8V*,nتZj)ʃݾ}{͎g(AO-RTR%,+cǎՄ{֬@M[\MeaaqaYXXX²eaaa E!m ġC#cɒ%6lСCJxכP`5A) —((ƽJKX|]vmڴaÆY!C 4Hr_B/"Ny+Vi9** 7o罨ѣG-ұcG;~PӀ^ezճgO.!Nҏ13… 9c֭:&Bj^xᅠ>|ƍ  =_8%sa\!g=zJ(Uսa+v*=󫯾z7NWs #Gq9, ˗/-e(\Gu\Ab|zO'B>֪UoS[9sܹsէ37jar-%Xvy A%p1 >L;HQ͏?n*k2ʠ/pcއ芎=9ȑ#&D PFS ~=t\3EmMʏ[+Fk|w|*zTA\?pRlGq"2Lp۹sI3(7K.vZmd˖ŋB qqq' ,X aj2O>_'6lٲE{k"w3 /cW[x˖-oWR%i9p@>0T rѢE|>SiepwM$?ym [ݻwHk7UTIy&T!gr 5Maz-44m۶5;l厖Urw}7hQʤO 8mذ%Lɒ%`،4[gȑD_G )C1Z(}V8D&|DD )15p ;wnsFȭ8EFDG\wuz2H '&P* t,["@R^'{WOδoD`!T^~=DŽG#*Q \RoBI.4Jb&G\`mi)) 8q:\HcZy^V$;' T 'ބ87oNiH*wDI8}4w9ۧ=e6j}Gܠf(ݙ٦Y 8H`O>MařoUX P^?٥/f|yPW7Dp'#X8E鵓@֭M/eH߱s -#E|.%h R*<& AgC;ރ?8o<#hÀ"" cP%KpST4Zw?^H%#fjܨ !)`+4?{xIݺ}v=]6z¤t B@np&_BDZc4' 御h0V9%uP,Vn`RQ KXei"""B;wM7ݔ'O=eH(G k2_\. hg/!!o>\,U=Y0$:"CRq[ )9sfą)-[6F-h^k`SQRh" ,NZdI9]v1\COHFK"8tƍ/\0LE:X 8)uQ~(5kƴ$^D ._d -aKR)5W~hy3Q@똫<3+vDt+, #hs \t.CXeW&* HǭeՓ&M qutZź >{vӬOcƍGjҊ;:Ln_CX(0j*, 4 !R.E1l0 < 0K9k' IENDB`sardana-1.2.0/doc/source/_static/default.css0000644000234100017500000001334612174204305022366 0ustar cpascualcpascual00000000000000/** * Sphinx stylesheet -- sphinxdoc theme * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl. */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif; font-size: 14px; letter-spacing: -0.01em; line-height: 150%; text-align: center; background-color: #BFD1D4; color: black; padding: 0; border: 1px solid #aaa; margin: 0px 40px 0px 40px; min-width: 740px; } div.document { background-color: white; text-align: left; background-image: url(contents.png); background-repeat: repeat-x; } div.bodywrapper { margin: 0 240px 0 0; border-right: 1px solid #ccc; } div.body { margin: 0; padding: 0.5em 20px 20px 20px; } div.related { font-size: 12px; } div.related ul { background-image: url(navigation.png); height: 2em; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; } div.related ul li { margin: 0; padding: 0; height: 2em; float: left; } div.related ul li.right { float: right; margin-right: 5px; } div.related ul li a { margin: 0; padding: 0 5px 0 5px; line-height: 1.75em; color: #EE9816; } div.related ul li a:hover { color: #3CA8E7; } div.sphinxsidebarwrapper { padding: 0; } div.sphinxsidebar { margin: 0; padding: 0.5em 15px 15px 0; width: 210px; float: right; font-size: 1em; text-align: left; } div.sphinxsidebar h3, div.sphinxsidebar h4 { margin: 1em 0 0.5em 0; font-size: 1em; padding: 0.1em 0 0.1em 0.5em; color: white; border: 1px solid #86989B; background-color: #AFC1C4; } div.sphinxsidebar h3 a { color: white; } div.sphinxsidebar ul { padding-left: 1.5em; margin-top: 7px; padding: 0; line-height: 130%; } div.sphinxsidebar ul ul { margin-left: 20px; } div.footer { background-color: #E3EFF1; color: #86989B; padding: 3px 8px 3px 0; clear: both; font-size: 0.8em; text-align: right; } div.footer a { color: #86989B; text-decoration: underline; } /* -- body styles ----------------------------------------------------------- */ p { margin: 0.8em 0 0.5em 0; } a { color: #CA7900; text-decoration: none; } a:hover { color: #2491CF; } div.body a { text-decoration: underline; } h1 { margin: 0; padding: 0.7em 0 0.3em 0; font-size: 1.5em; color: #11557C; } h2 { margin: 1.3em 0 0.2em 0; font-size: 1.35em; padding: 0; } h3 { margin: 1em 0 -0.3em 0; font-size: 1.2em; } div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { color: black!important; } h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { display: none; margin: 0 0 0 0.3em; padding: 0 0.2em 0 0.2em; color: #aaa!important; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { display: inline; } h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, h5 a.anchor:hover, h6 a.anchor:hover { color: #777; background-color: #eee; } a.headerlink { color: #c60f0f!important; font-size: 1em; margin-left: 6px; padding: 0 4px 0 4px; text-decoration: none!important; } a.headerlink:hover { background-color: #ccc; color: white!important; } cite, code, tt { font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; font-size: 0.95em; letter-spacing: 0.01em; } tt { background-color: #f2f2f2; border-bottom: 1px solid #ddd; color: #333; } tt.descname, tt.descclassname, tt.xref { border: 0; } hr { border: 1px solid #abc; margin: 2em; } a tt { border: 0; color: #CA7900; } a tt:hover { color: #2491CF; } pre { font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; font-size: 0.95em; letter-spacing: 0.015em; line-height: 120%; padding: 0.5em; border: 1px solid #ccc; background-color: #f8f8f8; } pre a { color: inherit; text-decoration: underline; } td.linenos pre { padding: 0.5em 0; } div.quotebar { background-color: #f8f8f8; max-width: 250px; float: right; padding: 2px 7px; border: 1px solid #ccc; } div.topic { background-color: #f8f8f8; } table { border-collapse: collapse; margin: 0 -0.5em 0 -0.5em; } table td, table th { padding: 0.2em 0.5em 0.2em 0.5em; } div.admonition, div.warning { font-size: 0.9em; margin: 1em 0 1em 0; border: 1px solid #86989B; background-color: #f7f7f7; padding: 0; } div.admonition p, div.warning p { margin: 0.5em 1em 0.5em 1em; padding: 0; } div.admonition pre, div.warning pre { margin: 0.4em 1em 0.4em 1em; } div.admonition p.admonition-title, div.warning p.admonition-title { margin: 0; padding: 0.1em 0 0.1em 0.5em; color: white; border-bottom: 1px solid #86989B; font-weight: bold; background-color: #AFC1C4; } div.warning { border: 1px solid #940000; } div.warning p.admonition-title { background-color: #CF0000; border-bottom-color: #940000; } div.admonition ul, div.admonition ol, div.warning ul, div.warning ol { margin: 0.1em 0.5em 0.5em 3em; padding: 0; } div.versioninfo { margin: 1em 0 0 0; border: 1px solid #ccc; background-color: #DDEAF0; padding: 8px; line-height: 1.3em; font-size: 0.9em; } #gallery { overflow: hidden; width: 90%; height: 450px; text-align: center; } #gallery img { height: 450px; } sardana-1.2.0/doc/source/_static/dyn.png0000644000234100017500000310016712174204305021531 0ustar cpascualcpascual00000000000000PNG  IHDR$, sRGB pHYsaa?itIMEK^ IDATx&{މ444xxxwwwEEE D IDAT"""\"""DDDxxx333͈gggVVVUUUggg"""̚EEEDDDwwwxxxUUUUUUwwwmo IDATgggEEEDDD333DDDfff"""VVVUUUxxx333DDD333މ"""VVVUUUfffDDD޻xxxUUU""""""Zʆ- IDATrAr IDAT&{xxx; IDATG IDATbx&0 IDAT c IDAT&{ޯN IDAT΂( IDAT"y IDATu IDAT&{Y IDAT IDAT )))@@@???& IDATRRRSSS%%%@@@???` IDATRRR SSS&{>>>> IDAT""""""DDD﫫"""333DDDDDDDDDWʨ IDATޫDDDUUU333ͫ333DDDDDD"""DDDUUU"""ͼwwwDDDggg333"""www"""މwwwDDDxxxUUUwww4%6 IDATEEE333DDDUUU"""444gggVVV333444EEE444wwwUUUEEEMC IDAT333VVV333VVVVVV"""ggg333VVV&{EEEfff333DDDUUUxxxSc IDATgggggg444ͫUUU333EEEUUU"""UUUVVVDDD444 IDATfffUUU͙ޚUUUDDD444"""xxx"""333333DDDVVVVVVDDDVVVVVVDDDVVVfff444EEE###"""###444###444"""DDD### I@ IDAT333"""333333333DDD333""""""""""""DDDUUUfff"""DDDfff""""""DDDfff"""UUU333xxxxxxVVV"""xxxVVV"""333""" IDATxxx"""fffEEEwwwDDD333""""""&{333EEE IDAT333333333"""xxx$$$p{ IDAT333EEE333EEE333333\P IDAT""""""333333 9D IDATUUU﫫gggUUU͚DDDDDD"""DDDDDDwww333333wwwUUU&{ IDATxxxxxx﫫333VVV333EEExxx﫫333333VVVlll"""xxxwwwVVV###"""fffEEE"""UUUDDDxxxwww###wwwVVV###"""fffUUUVVV>>>䈈###fff""""""މwww"""DDDDDD333މwww"""UUUEEEwwwUUUxxx͈wwwxxx333UUU444ffffff/ʒ^ IDATDDDfffEEE444wwwDDD"""UUU333www333www333"""UUUDDDggg"""DDD###ggg333######UUUwwwfffͫ333gggggg333DDD######UUUDDD""""""www333xxxgggUUUwww444333ggg\333333wwwEEE333"""gggVVVUUUUUUͼ"""DDDiuJ IDAT޻333VVV333fffEEEVVV333333www"""fffgggDDDDDDfffggggggfffDDDDDDDDDDDDDDDggggggfffwwwDDDUUUޚgggEEEUUUDDDމG IDAT"""""""""EEEEEEUUU333EEE444xxxxxxͪ"""www"""444333ggg333UUUUUU﫫gggDDDxxxUUU"""gggUUUwww"""fffEEEUUUwwwxxxUUU333###EEE"""www444VVVޚgggg?~ IDAT&{މwwwDDDgggDDDމͼ(((xxx333DDDUUUDDDͫEEEwww333333DDDDDDDDDUUUDDDwwwfff333wwwffffffDDD"""333gggDDD"""333www444gggVVV###www"""xxxfffDDDwww333KKKgggVVVxxx333DDDgggxxx"""UUU333DDDDDDͫ444333"""""""""333DDDwww333fffޫwwwxxxDDD\333xxx"""﫫DDDkkk EEEUUU333DDDfff޼ffffff﫫333xxxb IDATމxxx ===UUUDDD͚DDD333333"""333fff""""""""""""ޫ͈gggVVVݼUUU333wwwxxxUUUDDD111www333މgggDDD"""VVV###"""fffxxxDDDDDD###xxxxxxDDDgggxxxDDD???UUUVVVfffUUUDDD""""""UUUfff333VVVxxxUUUDDDމwww@@@ͫDDDxxxwwwމwww"""UUU"""gggwwwDDD͉DDDDDD444"""fffDDDggg333DDDDDDfffDDDgggUUU333333UUUDDD"""fff"""fffwwwxxx###VVVVVVxxxxxxVVVxxxxxxxxx444﫫UUUfff333DDDSSSeeeVVVVVV͚xxx444ޫxxxxxxEEExxxfffͫUUU﫫fff"""fff(((fffu IDATwwwDDDwww"""fff"""wwwfff"""HHH"""wwwwwwwwwXXX"""fffUUUDDDwwwwwwwwwwwwUUU"""333UUUwww&&&ffffff333DDDDDDfffEEEUUU"""DDDxxxUUU刈fffxxxUUU"""xxxwwwމwww"""fff"""###333"""333ޫfffxxxUUUUUU444333gggwwwwwwxxxfffwwwggg###"""wwwUUUVVVDDDxxxDDD޼333333ͫUUUggg###"""wwwUUUDDD333VVVgggEEEfffwwwwwwDDDwwwUUUDDDfffwwwfff"""fffDDDUUUxxxUUUggg777fffޫUUU"""ggg IDAT333xxxDDDxxx333nnnEEE777///UUUVVVHHHDDDxxxDDDggg$$$VVVDDD###VVVwwwUUU"""DDDUUUUUUUUUUUUwww"""333333DDDwwwUUU"""݈333wwwwwwffffff333UUUwwwwww"""333wwwwww333"""݈UUUwwwDDDgggfff333EEE333EEEEEE333"""333444ggg IDAT"""333UUUUUUEEEVVV&{VVV"""މDDD̙VVVxxx444DDD"""fffEEExxxxxx"""DDD"""333"""EEE"""333""""""gggDDDn IDATfff͈ͫ333""""""DDDEEEUUUUUU333fff333DDDDDD"""ͫ333DDDDDD﫫333DDDUUUxxx͚UUU333ggg###xxxEEE333ݪffffffDDD###"""444333\DDDUUU"""DDDggg333EEExxxwwwDDD"""333' IDATUUUDDDޫJJJ:::ggggggwww333"""wwwVVVޚHHHxxxޚfff"""wwwxxx"""DDDDDD---VVVxxxwwwDDDDDDEEEwwwfffUUUې>>>WWWϜxxxUUU""""""޼pppDDDVVVވDDDxxx333333dddDDD"""fff"""wwwDDDxxxgggVVV3339X IDATIII'''EEE"""DDDEEEVVV"""ggg333fff///XXX...fffEEEwwwUUUfff333VVV"""""""""fffpppEEEfffUUU333VVVVVV"""͚gggDDDfffDDDfffggg444UUUgggKN. IDATfffxxxxxx"""www333EEEfff&{xxxUUUxxx444DDD"""xxxwwwxxxfffޫfffUUU޼/23 IDATfff"""fffwwwDDD"""xxxUUUDDDVVVDDD"""wwwxxxEEE333͚DDD"""333Lx IDATxxxwwwgggUUUDDD333fff333xxxxxxEEExxxxxxxxxggggggVVV444xxxEEExxx444xxx###gggVVVVVVVVVVVV444UUUUUUwwwwww"""UUUDDDfffDDDfffDDDDDDwwwwww"""ffffffwww333"""DDDDDD"""DDD333DDDUUU""""""333DDD޼fff444"""UUUwwwމwww"""333"""UUU"""333333wwwwwwUUUDDDUUUxxxDDD333p IDATމ"""ggg333"""fff"""fffwwwwww"""͈wwwUUUEEEEEEDDD"""""""""fffwwwxxx"""""""""xxxxxxVVVxxxxxx###ggg###xxxxxxgggVVVxxxxxxxxxggggggxxxUUUfffVVVVVV"""DDDfff"""333VVVDDDxxxfffwwwffffff"""DDDͫfffVVVDDDVVV333444xxxxxxxxxwwwEEEVVVxxxވ######UUUުDDDEEEwwwfffUUUffffff333DDD"""UUU޼DDDfff333DDD333"""DDDfff벂 IDAT͚ffffff333ffffffwwwwww""""""DDD333ͫUUUwww333"""DDDxxxggg﫫YYYxxxUUU"""xxxDDD""""""333﫫aaaEEEVVVVVVމ###VVV&{fff"""xxxfff333\ccc333DDD޼www"""DDDDDDfff"""\[[[xxxxxxDDDDDD###xxx""""""UUU"""www"""\ͫ333wwwxxx###333ggg333""""""xxxVVV"""333\EEEDDDUUU"""fff333gggfffT IDAT""""""LLLwww333333333wwwwwwUUUPPPEEEwwwwwwDDDwww333gggEEEDDD333fff"""xxxffffffEEE"""WWW޲DDD"""DDDgggDDDޚDDDwwwwww޲DDD"""""""""xxxVVVfff"""fff"""""""""pppϏDDDxxx333DDD333"""pppϏDDDUUUgggfffDDDDDDxxx"""wwwDDDggg"""pppppp޼"""DDDUUUUUU"""pppppp޼"""̉444"""www333DDD޻gggEEEfffޫfff蠠~~~vh9 IDATwwwggg"""fffDDD"""fff""""""XXX͚gggxxx͚xxx444xxxxxxxxxxxxEEEEEExxx###xxxgggxxxxxxVVV###xxxVVVxxxEEExxxgggVVVxxxVVV###xxxޚggg333wwwfffwww"""wwwDDDhhhUUUwwwUUU"""DDDwwwDDDwwwDDDfffxxxgggwww333"""DDDUUUxxxwwwUUU###DDD333"""333މwww"""333""""""333wwwDDD͈DDDfff.../Z1 IDAT""""""333wwwfffVVVgggxxxEEExxx###xxxxxxVVV############444xxxxxxVVVxxxEEE###͚xxx444333DDDxxxxxxxxxxxx444gggxxxVVVEEExxxxxxEEExxx͚xxx444DDDwwwwwwDDD̪UUU""""""fffUUUDDDXXXfff"""333wwwfff333www333wwwwwwfff"""DDDfffDDDUUUUUUDDDxxxxxxfff333"""ffffffUUU333UUU"""fffޫfffDDDUUUwwwxxxxxxwwwEEEDDD333###EEEUUUͫxxxxxx͈ͫ޼\######UUUޫޫDDD333VVVfff"""xxxxxxUUUwww333fffDDD333xxxxxxwww"""fff"""333333"""333fffUUUUUUDDD"""ffffff333ffffff333333333"""S( IDATDDDwwwDDDfffDDD"""DDD333"""DDD᫫""""""333"""UUU"""UUUEEEwwwDDDDDDfff444333UUUEEEfffDDDUUUVVVwww333333wwwDDDDDDމVVV###EEE"""DDDDDD333޼EEE###EEEVVVDDD͚DDD\UUU333333DDD333""""""\DDDggg"""333333"""333މ"""UUUfffVVVVVVDDDggg333&{̈333333www݈DDD333www"""www"""ffffffUUUDDD333UUUfffUUU"""www"""333fff"""333DDDwww̻www"""DDD"""fffwwwUUUwwwUUUwww...fffwwwUUU"""333DDD333UUUwwwUUU"""333wwwUUUDDDwwwwwwwwwD5 IDATDDfff"""ffffffމEEEwwwDDD"""fffwww444UUUgggwww""""""EEEEEE444"""UUUUUU"""EEEDDDDDD333wwwVVVxxxdddQQQ333ޚwww͉wwwgggUUUDDDVVVwww555VVVgggv| IDATEEE"""DDDEEEUUU333EEEgggfff333444wwwwwwfffEEE___LLLUUUDDDgggxxxfffgggUUUDDDxxxPPPPPP͉͙xxx"""EEE333333KKK fffpppVVVEEEwwww{ IDATgggVVVaaaKKKpppgggwww333ggggggVVVfff333333EEE ٴ333fff444EEEggg333fffUUUdddDDDwww444333gggffffffwwwDDDUUUgggxxxxxxVVVfff IDATEEE333444EEE333DDDwwwUUU######ͻ﫫fff###fff"""xxxxxxDDDfff444UUUDDD333ޫ""""""&{xxx"""fffې&&&DDDccc333޼UUUUUU333EEEͫ"""333UUU"""EEEEEEwwwDDD{ IDAT444333...bbbppp\""""""333www"""DDDUUUwwwwwwDDDgggwww333ߣpppDDDUUUUUUἼ""""""DDD͙DDDgggxxxfffDDDDDD͈333UUU333333333UUUJ IDATUUUxxxEEEEEE###EEEEEExxxUUUEEE333UUUDDDfff"""򭭭333fffDDDwwwDDDUUUDDD"""---UUUfff"""333fff"""DDDwww333ͫ򲲲pppf IDAT333wwwwwwDDDwww wwwwwwwww"""wwwDDD"""DDDDDD333DDD333"""DDDfff"""DDDDDD"""UUUDDDfffgggwww333򭭭"""333DDD333333333333DDD333333xxxfff222111dddSSSwww"""wwwDDD﫫wwwxxxDDD%%%CCCVVV333333444""""""DDD333DDD111DDD3332= IDATDDDxxxxxxDDDDDD###xxx"""͖%%%CCCVVV333"""VVV333fffwwwwww"""DDDEEEDDDUUU"""fff333xxx͋"""\ffffff444DDDfff DDD"""﫫333444wwwwwwVVV333DDDUUUUUUxxxgggEEEDDD333fff"""333;;;[[[DDDUUUUUUDDDffffffwwwwwwxxx&{""""""VVV %%%```ڟDDD333ggg333DDD""""""wwwDDDnU IDATUUUgggfffDDDDDDxxx>>>```ڟDDDEEEވ"""̉444"""www333DDD޻gggEEEfffޫfff"""UUUUUUgggggg""""""UUU333333333UUUxxxgggfff333"""wwwfffE IDATUUUDDD"""EEE333333ͫDDD333wwwDDDggg333DDDggg﫫333VVV###"""xxx333www333UUUxxx"""DDDDDDޫVVV###"""fffEEEUUUDDD333xxxwwwVVVxxxDDDDDD###xxx333wwwVVVfffxxx e IDATDDDDDDwww"""މwww"""DDDDDDDDDZZZUUU"""DDDEEE333333wwwUUUxxxUUUxxxDDDUUUfff"""ggg"""333fff"""333UUUxxxVVVͼfffxxxUUUfffDDDVVV"""UUUppp333DDDxxxDDD333DDDxxx"""DDDwwwfffwwwVVVfffgggfff"""333EEE"""333333333# IDATDDDfffUUU"""www333"""KKKwwwfffUUUwwwUUUwww333333fffwwwwwwDDD"""DDDwwwwwwDDDݻwwwDDD"""DDDwwwDDDxxxEEEwwwDDDgggxxx|||sss""" ޫ333333UUUEEE\333333UUU"""EEE333"""UUUDDD333UUUxxxUUUEEEDDDwww333UUUUUUͼxxxwwwUUUwwwxxxwww333"""xxx###ުwww333333www444xxx&{"""UUU^_ IDAT"""333xxxVVVVVV"""̈"""""""""VVVVVVwww͚gggfffxxxVVVUUUfffffffffEEExxxxxxVVV333UUUxxxwww;;;444UUUDDD###VVVVVV333fff$$$"""333fffggg333wwwVVVxxxUUUDDD***򃃃J IDATggg333"""gggfff333ggggggwwwgggggg444EEE,,,###xxxgggwww444EEEUUU͙޼UUU"""gggffffffggg333QQQh_! IDATxxxEEE333xxxxxxxxx333YYY zzzDDD333"""UUUxxx444xxx444""""""xxxxxxwwwwww444###̈ppp""""""iii###EEEͻ﫫333DDDDDD]Q IDAT"""333EEE444މEEEEEEޙ"""ggg|||333"""wwwwwwޫxxxUUU333UUU"""fffffffffDDDwwwޫwwwxxxDDD\333͚DDDxxx"""ޫwwwxxxDDDxxxwwwxxxwwwgggDDDfffUUUfff333"""333 333XXX888DDDDDD""""""DDDDDDwwwwww333wwwUUUwww"""www̪wwwfff""""""̪UUUUUUfffDDDDDDXXXXXXwww...DDDDDD"""xxxwwwwwwffffff333VVVxxxUUU333"""DDDfff333444www"""ffffff"""fffDDD333UUUwwwމwww""" IDAT &{333DDDfffDDDfff޼fffgggޚwwwDDD333""""""333xxxUUU"""UUUfffUUU444fff333???xxxUUUxxxfffgggxxx"""fffwww333މ"""UUUUUUDDDUUUUUU\333VVVccc޼wwwwwwwwwwwwfffDDDwwwwwwfffwwwUUUffffff݈"""333ffffffUUU"""wwwffffff333DDDDDDfff333"""DDDwwwDDDUUUDDD]7 IDATDDDEEExxxDDDDDDgggEEEEEEgggِgggxxxxxxggg޻UUU赵gggggg""" EEEDDDwwwUUUDDDVVV IDATgggEEEUUU333333wwwUUU"""xxxEEEUUUDDDQQQ___UUUfffxxx""""""着ͼfffͫxxx333xxx"""xxx555xxx"""333VVVDDDwwwwwwDDDwwwHHHfff"""wwwDDDHHHwww"""wwwUUUUUU"""222UUUDDDDDDgggfffwww޼fff"""444xxxDDD333"""DDD"""wwwDDD###333fff"""DDDIW IDATSSS"""fff"""pppjjjޫ"""ͫ"""蚚VVV̙wwwfff޿EEE333333333333ọ̃UUU޼͙333fff444xxx"""www333EEEQQQpppfff333xxx333EEEwwwWWWfffxxxޫDDD%%%ttt333xxxUUUUUU"""'''333EEE333""""""ͻDDDޚ333"""333UUUwww(((\\\---333333333DDDxxx UUU xxxUUUwwwxxxޚDDD"""333""""""DDDޫxxxUUUUUU333@@@fff"""UUU333DDDxxx###DDD&&&ffffff""""""﫫UUU222aaaQQQ///111"""xxx333ggg"""333www333om IDATfff333wwwDDDfffwwwwwwDDDwww̻̙DDDDDD&{fffffffffEEEUUUwwwLLL"""xxx"""UUUDDD333xxx"""""""""\333\333﫫fff"""www333333"""wwwwww"""wwwwwwwww"""www"""DDDfffDDDUUU"""wwwfff"""wwwfff"""DDDwwwDDDDDD444̈fffEEEnnnpppDDDDDD"""DDD޼DDDffffffDDD333DDDEEEwwwEEEwwwxxxxxxUUUVVVfffVVVfffxxxxxxUUUwww"""333UUUEEEfffEEE)))333%" IDATͫ""""""xxxwww333ͫ"""EEEEEEEEEEEE333######333DDD333"""gggfffDDDgggTTT[[[EEEDDDxxxUUU"""xxxDDD""""""xxxUUUVVVVVVDDDEEEDDDEEEޚgggޚgggޚgggxxx333333ggg111ޫfffDDD"""DDDfff"""fffVVVVVVDDDDDD333މ"""333މ"""ޚޚޚwwwfffwwwRRRRRRvvv www݈333"""333wwwwww333wwwfffUUUwwwwwwwwwUUUfff"""333wwwwwwwwwUUUwwwUUUwww"""DDDwwwDDDDDDDDDwwwfff...)))www̻UUU3Xo IDATDDDwwwDDDDDD͚EEE"""UUUmmm ggg333DDDUUUfffxxx޼ffffffxxx"""www"""KKK )))www333UUUDDDwwwDDDfffDDDwwwUUUwwwDDDDDDEEE333ggg UUUUUU޼fff444"""333"""xxxwww"""UUUUUU333fffxxxNNNDDD.v IDAT333"""DDD333"""ޫwwwfff޼888 """"""444fff333wwwxxxUUUŁ555DDD"""DDDfff"""\333"""DDDggg333"""UUUDDDxxxwwwpppͫVVVxxxވfff333444VVV333EEE###gggUUUDDDEEEDDD333###gggUUUwwwVVVͻ333gi IDATUUU333ffffff333DDD"""333&{wwwwwwggg333"""ggg"""UUUUUUEEEfff333﫫ggg+ IDATDDD444EEE###EEEEEEEEEDDDxxxUUUfffxxxEEEEEE###wwwEEExxx͚ggg777DDD̻UUU"""333xxxwwwUUU}}}"""DDDEEEDDD333333UUUfffͻEEEfff"""333wwwVVVffffffDDDUUUfffVVVfffDDDDDDDDDDDDDDDwwwDDD333"""VVVwwwfffxxx"""UUU﫫DDD"""333fff"""DDDwwwxxxxxx"""wwwVVVDDD IDATfffwwwXXXwwwwwwwww"""wwwDDD"""wwwUUUfffwww"""wwwwww"""\\\333DDDDDDDDD222"""UUUDDDfffggg"""xxx333"""UUUDDDfffwwwwwwDDDVVVfffVVV׻333333333333DDD333EEEfff333wwwXXX~~~"""333\333DDD333ޫ"""###È444fff333"""333333xxxUUUfff"""333UUUDDDEEERRRiiiNNNRRR} IDAT444xxxxxx"""\444fffwwwwwwfffwwwxxxwwwVVVwwwffffffwww333333xxxxxx\EEEXXXwwwDDDDDD333333DDDDDDXXXhhhfff333333DDDwwwwwwwwwDDD333"""---%%%qqqwwwwww333wwwDDDwwwwwwDDD"""fff"""333>>>)))DDDxxxEEEfff͈xxxDDDUUUxxxwwwDDDfffUUUEEEEEEVVVVVVމ###VVViiiYYY333ggg"""DDDffffff333wwwEEEggg333DDD"""444UUUxxxxxxDDDDDD###xxx""" IDATΨ@@@RRRDDDgggDDDDDDwww333DDDDDDxxx"""333UUUgggDDDDDD﫫DDDEEEDDDUUU"""fff333@@@RRRDDDUUUUUUDDDDDDͫEEEUUU333޼UUUwww333&{gggEEEDDD333fff"""xxx333333333333޼UUU333UUUޫUUU""""""""""""xxxVVVfff"""333444KKKNNN""""""UUU333333"""ffffffxxx""""""DDD333333333"""UUUxxxgggDDD###DDDxxx"""DDDwww444KKKNNN"""333"""DDDf IDATUUUUUUͼ333333333̉444"""www333DDD޻gggEEEfffޫfff""""""DDDUUU HHH333DDDDDDxxxDDDgggfff333EEE"""﫫333VVV333EEE###xxx333wwwUUUDDDwwwXXXwwwUUUUUUwww"""ffffffC IDATDDDUUUfffwww"""މwww"""DDDDDD333UUU"""DDD333UUUxxx͈fff"""333fff"""wwwUUU333VVVUUUxxxfff333DDDxxxxxxxxxDDDxxxwwwW IDAT"""UUUDDD###VVV"""######UUUwwwfff着DDDVVVwwwDDDEEEwww"""333444###"""EEEUUUUUU"""wwwEEE쇣 IDATwwwgggxxxfffUUUxxxwww&{͚xxx'v'6 IDATVVVggg333VVVEEEfff333DDDVVVVVVfff333EEE͈"""=@r IDATgggggg""""""444444wwwEEEEEE"""xxx"""މwwwDDD9 IDAT333VVV"""DDDDDD"""﫫͈UUUDDDޫVVVUUUDDD333ޫDDDwww333޼"""???"""""""""DDDUUU"""EEERRR333333EEE7& IDAT%%%UUUUUU&{uN/ IDAT IDATߕ IDAT޼޼EEE444EEEEEEEEEEEE###xxxVVVVVV###VVV###444444UUUVVVͼwwwd IDATUUUUUUUUUwww333333"""EEE###ޚxxxEEEVVVgggVVV444444xxxxxxxxx444gggxxxxxxxxx444gggVVVxxxxxxxxxxxx444###gggxxx###gggxxxEEEgggggg444VVVxxxxxx###xxx444މ###EEEEEE444xxxxxx444xxx###EEE&{wwwDDDDDD333""""""ݙfffwwwDDDwwwDDDDDDwwwDDDDDDwwwDDDDDDwwwwwwDDD"""UUUUUU333fff"""wwwwww"""fff^J IDATUUUwwwffffff"""www"""DDDwwwDDDDDDfffwwwfff333wwwwwwffffffDDDDDD333ffffffDDDwwwwwwDDDwwwwww333DDDffffff""""""DDDDDD"""xxxwwwfff"""333""""""333"""DDDxxxwww"""fffwww333xxxwww"""www͙"""fffxxxwwwwww"""ޫUUU"""UUU"""""""""UUUfff""""""###wwwwww"""DDDUUUUUUDDD333""""""""""""DDD333333DDDVVVfffޫDDD<$ IDATUUUDDD333UUU333UUUDDDUUUfffͫfffUUUxxxDDD333UUUUUUUUU"""333DDDwwwDDDDDDDDD"""UUUffffff333fff333DDD"""333DDDUUUUUUwwwDDDUUUwwwwww"""wwwDDD"""wwwDDDDDDUUUUUUDDDwwwwww333wwwfffDDDDDDwwwUUUwwwwww333fff"""fffwwwUUUwwwwww333wwwwwwwwwwww333wwwwwwwwwffffff""""""wwwfff333wwwwwwwwwDDDUUUUUU""""""wwwfffUUUfff333wwwfffwww""""""wwwwwwDDDDDD[b IDATEEEDDD > IDAT333&{9W IDAT7 IDATt IDATtl IDAT( UeIDATRxxxDDD IENDB`sardana-1.2.0/doc/source/_static/gap_offset.png0000755000234100017500000003751212174204305023057 0ustar cpascualcpascual00000000000000PNG  IHDRsBIT|d IDATxyeyyjޗfeaa j8E(nF1F='9 hL\b4"j1APVaٚa}}}gP醩9uڿ&t&P(FVJpzeYA:ap8ضm۸\M'ur2cccm`||\Bis}yf_@6@ ms!Ld||B0 s~gBG3u%P,)cYNbH(bnna,r; u IX B\Nt:IRx6Of`Sa6a{˅mhÁmx<t]ra&Ld2$:>S Ác`Ν"X, ~TOOϖ$h6b12 Mжmn7N˲xCujaP*?E,H]ׁ?$)PTp*fbi:vSh4x^LӤh(A4 Mp8*p8p\mqN'LJ%<~M\V@\>Ǐ糟,D"A^g~~J4vMX$LFT*\.FFFHhN_az#`~׋^#h4u0u]4X,m aFq\d28G!J4 Qv @*0 4^۶AXp0::Uu3#V\.1Z!ei+Y()J[ASKR4q\*_t7299IV!zOOO?y^ƟٟD<Dz,rIDP`||J{+#L/pƲ,ug|\.N'jۍPI{qEq뭷o>U#ϛNqݸ\.0B,~_|LLLh48väiFGGrڵL&i$ Tzo_~y$ύnNDŽB6MMmDp8E,#F 'O}~-^idFdY&''1M\.\.3==M*b~~rАZvb||m۶(_ %E۷o5r<:th333\}:tx}Qa``n 977eYN__=~D"ARavvxrwO|RDOORCr G^'ե ===+|fX?bz[dq+6m#P0 B(tdjyv碋.ؽ{7q8iuii]]]MO}rHWN өakp8LV306rHW6<v8ـnXm^G6T*!BUSSd [w\r9.B2^!{/mo{iFI&B!xpx<lp(r:mCB4t,tCx^/"0==M(& bX&jӔ3M!^n]f3yl&m3<8C<*.܇t˅@u:´ɐ NBNyK^B>'#PNO8sN/f޽8fffHRtwwrp\g@Yrڸh^k\B mX9cd`ޗ6<@T㢽B eR( 2y a044sʅ".ܧ>bG` o4q?N /r)M bqBJ׼50==a Ǖx<4MSI z $RMͰ&dB9qP(#0??~h4eY~b1j5a_gϞ=AzÉ ; AG6NSiz4kv|x^^x^FFFf~fggd2޽ǏH$z|>%"VJiI[ aZ夷KO/zN.Jf94/.xzMѝL7 nzT. qj[#L YjA31;;\# 6ۚvqhFPVa&aC6eqqQJYs'c.@<涄%evk6G\.~lV%}kzdW {urԬMRmA8NuN@Uil%ti!+6Mضm~_`{R.gqfggUVzAj}>zòe @LzT"ɛ&LdqqQi ZrLZ2fC_k7@k#BӖax^U7'Cl?_yLpw^&''ٱcx)R*X' IM ZI 4mZQm x<.R/F)),4IZdnn%jFQ*y}i[j#L2m===\8pFe׮]D"lۦMp:(jG" KKK8N(D"nUjT.UJz^LR(p9̀75mھo`M\D;w{.ƠBkϱHqDˎ[adB&UmVn<@lVQTbxxL&CXd۶mʄr(b1* t:ˤR)ժQTT PXR`jmѰCsl<Я['rLNQd~ӟ#G0::8z몹KWWF|>t׺ZS=~ mA\.G<P(h4A `aaロt:MZVRT lBX6=-ώk-fhSZ_|>I$ɽT*|#|;ww#b'N`tt>4M2رc\qSW- B!^/<={/j* u}0eLfبX4|>PZFV# 7/}K|_擟apQbm399wMP>X&R.y }݊zxee}k2;;K^' M?OCwwLMMw^VVV۹馛8vbjJ.\.2H9* JYh_K$oBG3mAAJdY^'xWU êCzիرc_YYYabb|; _ϫ_jN8}Cx<zFFFXXXPهh4ؿ %jMع&CZKz׿ΕW^zrJnjhTQ;&!![[~~RVe("Q,I$8qd2m@$!)~t:׾5Jr6"VөxH$AX+J$!5 1330JE!KKK*ݍi)FWYz+˥ `Rjt]G4R&_8wnChN'>i:XZ"===?*333ajfID",..2??c=!XۍiJ% RE%ǎcddK2T}S Zi}ejjH$B"K;7D"PV@^ZL&'b=|ݺmm$Xv0g``(333n8K\E(h2XJntGP@4By6lϐںu̬jz#ᘚb߾}ahh 'uGXl6Ҍk%0i4~^m}N Kcke4Z/lt 4j|rrK/Bdou:yk^"zq:Wٶ-VWW B|>r2:ѼrW/N_62N'q]`0f !Na;:W4Me[].|~@> [k.k-F)Zq&noZ~z=ZAX@$a=^@p}_T9r266F^ꫯf׮]yG>m۔J%:"P۶>m۸+x+^O:fxx[n@ u]}|A<)$v7'mֳn n>.VlV_.ڪ7b_t:Z߷VrHXF34llujF)ok=-ko7 [LjhL'VD"z1==w.//Ӷ[dLY=R5 0Ѩe2"r}k;~VJ%p\B!jbpw/|;w_4׽u+p}/333tM\vel۶;BٳgqדJ|lk3Ŵ~J=j) mr[H[U7:=-_Ow 5F;ؖmzmsw3^c,4Nou|.e|*P($frrѶHB.RrlT+nNVV*rpA0ģk??!Ͳw^n6OIo~y׻޽{ٽ{7G? 5\Á[H$E󖷼/o o~O~e/S_dlfǙ|ଃ,2,*NgXEqXp' bM b>O$eu%ajpmj0,K F]V#JaYZ j5UӪeGGGf*X,2Y̫V*5^j%z{{d2\.ŞUv}U* u]QJEQFFFVd2??׾ ?W_Ϳsmi?OرcWJ$tuuF EFn5cNYgŜ.~VtB޷.g6!Nܝn鶟iB͆=-tOk'rQ~a<,,,UclA4Mȑ#رh0ell MHtuuH$n`B%HϷ ~{_`|>(/:xSB /n5vNr뭷t:yx,'xοۿO)VWWU9x ݜ8qA~c6HZ6'Z6g8Oح}s8ݝqYPtg\gggV͸ ۙFw{ rJia;M3jO5ە6Sjvuu)H$Rdڲ,b|rڀfءC&4j]"Ɉ|>/$q%)aYx!bppeY"L @tuuE>^W'?p7 C]i4Ma0 C.z!m²,j?˲Nh4D^z]!lkݰHJ%,,,^Y9,vSV!D{^OYNuwghz}`|dϷXD$GFuHzCզS54 HDME|>###Er|>_U*uD"A6UeQGpqnnN8R(dMNN !رc)F!t]ضmD PD0TۢѨ:pMӄBݶmQVB9u=|λ^jG]zIIDATa Mmv?2aݧ֨ Ci}r\t}B4T* ۴SVOtk?!@JX^^Vua|T*bh4O96u].K|>e=ɇHV8 Upx[z_PmyƸNd_k拀JL0¶,& .~+~^/|^Eܤizzضd2SlU."fffH$sXSIk$˧Ɯm녦unimi!_Dh:P:L6[g{}ukL|kBA5Cf xn۶q ) )H2i*E+++*I;==[MBiGQ[6,ibN0R/fjhϔTsˉi6iv 䄿@N8(@ d \@6 {PN' .d2beeE^STTO쬪f!:´B$ѪN9fM3Z+OyBlzLJapiD 0L-hb&² B+5S*Dwy-dQ0n[ZAC2M͒H$8|0wV@۹[5' tZr)4hyލ ;FTDU%_t&Is8?kT k 1??w( Ӳbcޯ5)$}$Y{iu!ǭ%\ZZ"  XYYDڈ=3kjAh`i`}0OI5/ѤpN.MjUضѼ F~vBRl\儍jʺmظ.LB;|ee^5)5P$If9p8sbZO?&< :D%nw[nR HLLLD)Jm~Q"gΝ(UxoUt̼T[Ь޳gtwwf]٦QVU$o44֮X,iԐ4@Myf J4%ͪsm:8kx^BAͻuEWW;Ar| !gyyY+BD\>-VEG6q WZ[c=2 "o 0HFA("T=+++ɤb N$O.`#L dWU5tNw!NhR+ PL[8l>qr 5G?B.7ٹvfd2bJE~tVD\.Dž^HTR7der&H9i(Fy|>:ϷdHu*ml6K*Rjx>#L Ͱ|:i]r95WNZl[+IUZ 욦)iݯuڡ%ˡQp:,%P'??B1rY B"ixM˲XZZ"*nuuN4o!XZv+)W\AXvzx<^/>M4U%  p8e~Hn_?8Z 0 &&&V#(!J>rdB+CRn%P0Pz4L垞"KKK,..B0$ɐH$mUE%䘡BEʤ:´ɐ4,RCCC7tru D+eYMjc!pHo(uIjY,q8aJ%"HDMA ϧk]rh4O}6(+ti!5t]YN i :ircgjt0&LVZTBr9"חfDQExfqŭ| DtB IrzfiiAB!*|twwӣn7Dáwi%&׫R)VVVê.( !Pp8| ӭԪ.b4h"JSOj"mӞOhMF+W;dhh˅aN0$t:ܹP(I_X,"P LOOsTFԤt:FdYl)T.xǏg۶mJG<P(t:UKDR!)G434E䅆0m2N7tB I&Ν;q8<A:n)ٷoؾ};?IRB!vء= vmbbb_z PFAZU9sI#L[HN x<ɓO><۷oht:k4Mse1>>iN,#裏2<ѣjV 7߮*d.5}.[tR~?EL9ao޽:-oy ~݋ѣiHR`OS*k0@䩧/~1Tx˲:BFdⴻT*E>y'0 ^W388DK^B###<4wqX/\EZ~a67|3W]u/ n"۷o\.xXXX`q* Re\3έorT-Zקh??duur7M&&&Q\ >?mE$wqb1fffYYYa .h4яL&C^r )L&eY*BZah˥'(;vppw2??ϋ^"B|tr뭷266_rV,B뮻s;w$r# Hp=pW233[V$7tN|>O h`YP^өrT/ 盼>${lۦVaY\COpafggپ};>hT,]]]tuuq78p|{o}[yGy+^ݻW"v7|3jɶmۘ&L388Nyի^x㍪_"333r-|3K.auun{w//u!4wq\/˼/crj>C{7L.A6 :́[ߥ`r-ڵD"LӤG)4wV)ipczN&GE3mȢ:=hjU[UwrZF*REn|>O,C, bYsss L&U7ؘMaqqW rj4~?]]]]NZ 1<< #G駟F4p:D"Ԥ /{hVtefffx')ݻ˲T*y՚!"o%4 G4} SG3mLp2&52\VDA2tBNB|>j۹sj"MVkܚò,I4l6N{wP(iJ;^jnr7*:i!#f NMTiɺ+ I,KQ˲۶vަi*Ǭn\)nG*3ѣI2TeFG1)I %5i$aeezJEIO zȿ&VBG6Gj4j4-RUٺv$KD+]dZZFbeel6KOOm6l&v9x 'N^DV* aP(|$ 뮻d2fz\6,euNYTTl flt̼-I^/z \VcZ)ZRbFڶ"ϫ*h4eYr#z4?~\1.,,]e+++|[Q,T*qs%("{/d2 (36ah4Ha1 M=˲6MdWHJV(ȇE4U/ h4gzzx<~Uo}Ez{{ eYtuuH$({"0;;ҒF=zTj P.1 jO?C=^366̙87adض$Ţp8jJ3 P"i2 `||RD^4M333;v#Gp10$zLMM W.)˪FPߔ"5Q LYXXt  &gܹx2 BѨ(UTՔMҼT*?~'N𖷼SZZGֹsElۦ\.s355Ů]x_(%Wn'^aP.Y\\ѣ<#(ox,'xT*O! QZp8dzz@ __fyߍ yRN`PUn->G!"?x ͑J|=zw]|+_Wվi* !K0 UU,zV M$j|@$Eh q8ށ~lz]i#Gٽ Bm4 ׏p:ffb1l-YZAr9թQjk+`ii^5Pf淾>9,~_x^~ {p:;w$Jh487 5r1t:#Q.OG3upxZÞfVT(p\m–e jj&''D9>*g(J&,--glsq'=z߯h]vozӛ"% BXgadb@ ؗ~˨jD[F-}}}kO4YZZR_'>jox [T?4|G+011A:fpp F#d5mVe lBَ0m2Z۹pȎT êhMmS[#|~|>O<Gu\g3KЌٳzjO<+++|>2{^:2yG6%KYY]+٬!68|Vl#L 95B48N:mM^WuYHrJ`+Y(ϟduسQ,zjipV364E{"9-ND;qL .ޞ^r'N:qL!DTB\!/L!cfa^ Ht 1(FhSƳr:ѼN}sQX,LuFGGYZ\![EZ<XǶBp0jh4DG:8;@sFo.Uw\XDJ] Dpq $`Uq躮 tYף+mX,'0d_6!I*"fI۶1MS|gv:m;T-MRjc\4ٱcwy'~n7O=vDs8Lrh|OJp\*%9cpp63!jӐ7g6|w388H&aii @TN@z񰲲BVh+! EKQekme8nFdDXN7Cf,Ku>:gaH, ˅mYTUB-zֶ,N'zY,NDm]UuX:lWV)~)']46?'~(k֬'Oy{ߏi|'? \k\.ǩ'$bqٱ`0>z)>ğٟ3p)|<ȿpUWeCx$g0~vT2eUj Gy0 p^7MIvi|>LӤnzQ$UU$v WvjȲL8FeZ~?ۍiȲ99Ͼg LCR0 t]Y5Dߦʹ\.qNWg$!22}mZ^C$B7 / =|,5M]lhd7]r:]=^χ7eQV㘦y<\.-XFQTUz,?%v7ڡ%dSPL$Eeb( eu p. dYr!˲8MlS*y^/PbȊEd-$rhZm\.~M0MǃjdLE[.|.ji;C j:֦Q*07vO^k- ^_ _oa&*JR#љH0;}C*`afH4)T*iŐeYLd``RDdhh) ```]9y8]8smVXAT"W344H$iBy~PEAFBY$_P@ƒ#XZ.cM?sl4ixק'$IמiWu(J ^]i-<^7eQWD"nqa!Y&^”$t$P, dDo(IT}~@Z(U@WW|FA__еO~?Slig'ghZs $ZL&$XP(DP JQiT쀯vD"[GDg||Y  Y;7Ah"9L/R eQ\z:IX,CJ z8z(BGʩ#N r;KIVBZ3ܗp{5MQu;jlM,\H("l6uO^'HPT||>dYJH)q>$xq\A^p4j0pn6$])7MEnh4ȲL. 5L]hxLf`H2-tY cdQ ct+ nEA3t SGIW H(@ D$ey[uϳQT%:eJ$I`YRIDR)LӤlR.Fe<~5k֐xaT^/fS8Yo-ωHW|֒/H܊nVZENm 2=}>$KH&HJN8lñ{``0(tBUUyȲ|CNI:jҬَ w(nQ(lѨ#:n@ @ YVXlbNZj";1nT*X\.l6q~9|>Lvr,6auEq^6(EpK.VJM4Xn;J4VbM񰰰@nRD:#Ӳ,<@uj>KNp:b<\ ^B@GG4~]DD"\.4M^XD"G/'D"Eq(N&yZ-n7dB@$m-"b`bQ)P\v檘&a`y 8+ rlG+05 bg\^EM[0 ގ\Ȳ,2n$gY/C:NV/d=mj/x ,4k׮\.ƨT*4M$I"% :ΤT*qq t4@k<'vB4"2dg)H0GUU6>ocn\HW: Fn}Fx deag9.֩T'h˲t]Mu]*pQb¤X,bmzöy_Aӆ=Ldnn`8a%EzF#ɈچGH4MQWQ4VTUVXAZx)2 pB@բjJ6%R(k:ibVe![~Ƀ˥6-F"݁NEÆGYvzNgC0Q^nJt:-$I0<OLVRVuJf~$_P@Ģ2 EQ(dnk(Kd^šXaX<\ng0<2 #h4Dvxaz=A6-P.!%I >#' (\CyuaF朅:$ v-B@6EQ"~߆en8f:4MfggE6t9;F*BQ&'')rtdhۄB!˵9O0h,d2~/qw.ӴK#Q׋!P3( +>J)HooxfSH8ӧY~=}}}xVq2Z'0wyeaa%/-G /c߸,+X#2f-} eFGGٲe e ETaH/8ҒIHf~~cǎ1>>q\TU!w۸z(o߾uVnJ8Eyk4SIZfƚK7 |x<>ڦjBj} .&/+bKUIwi?ix(^RXZdsq~|hZ""?w/Vp _B@(dJj yfffd2b1 "rrDHrT*nB0bHHD#Q(r #į\.q9 \.gϞܹs޽}k":qD ~z2B5MC4B BZ-::ʵɹq \ʎ;(x۷d2ɦMPU:::( r98JEdZ{}oP. Hn7BhNdY_dǎuEn'Rr?(rA* aDtzQUFA$m0\V ڔ%ʕ2h?p0˗s5004fzz~Ah6ٳl6K"D"!`p8,O>$A Ĝq>5͋L&Cgg'dR@%VEݢh.Ġubr9q;v( D"DL&Þ={V6QV;AJ:D"!tOuAښ'RT__pd2'I(^$gzzT*EXW("(J"%DDv=<0l$E~?+Wdhhɓ'9r333D".r֯_Ͼ}Db&&&(J\ve4M*l6dǎܹR$bHTQ,caab(hzo/ Zk<qy 6l s!٬(ϣik׮%0::ʹsVE,ĉ|k_ы(߿ 8199P\/"J* XecؚGDbrzjK⯸8k֬ꫯ[|UUd2|_fpp"\#Gpa,^z~l6)LOO wǩ8(eYS,:W[bׅɞu5WjP(P1 F'@炙]י̙3,..RVO~ž={_f5M-'rSuy;q诇d,H$BooEYիF)B!fX]>TUhD"fggZr`4>>ιsE=*~Ο??0ظq#VEXayQcfȲvzٳg8n܄Nj\~)I E ! c)T*Q3x(> cccv!Ypǖj5d]h\|eFzc3,Kz{{) x<9ʡ!dYfϞ=b1ǩj?~P(?qGOO'> t]gff\;v`bb_|??GufÆ =f.z!>FZ?c >͛73;;ˊ+8y$?Oi6|T*}Q~]dB/)wŹs"LLLޅ9,swH$LMMКNEcXPS| _211]wӧ>_)fggxɳ>+2fP;4}Dž{cƸ馛زe K^ڵk E"˿K,_:lN6R|;wr![=o%:6(p:nم,~ |?яD EM1$Eo;v0?? _җegB!:wM$?);v젯oۜ8q]O~=,#ǎcϞ=y>333#n 7 24f_0EFD0Ea``b(tr$IdYFGG4M6{w^6```0b]y饗x{w}h7 y>vų>>Q7x<N;R&i@D"A`vvi~w^ /t:g>r r2LWZŽm݆|ͤR)*?۹HRǶmۈ|m۶rJm[u]GeJ#7G.cllnQqz`-/vZ~sW6Ȼnz{{G>g?Yb+k֬W^ɇ>!>0<?N ફ" `ݺulw+V`&@K%AUfLNNǡ{kFvލgnnͱcPa/;ЊܽHDrᲰMA.;u]޽;e||M6I"`QzzzH$\y!E!S.ERVggA:$8Z-Apjx vmy睌iַhۼ`llC111_Χ?iowovsTL߻wȔ2.bf..x]vya[PHd xop;9َٴi+e|``|3?&he♌/#~?]wcccD"QYf hl6+*- w(nyh4,b( SZT*/"˲l(޽FA\fff\.GP`֭b$p,`{-[8pCCC,..rWdh4=zO|;ߡX,yfE!*qqlB>%!~5333#f1ge.#(v OOrOoo/Oﶛ/b$rUVd" r!Ρ!M#J˲zc1.ݱi:u!l޼Y0 ~5k(=zV"-?~\d28B,{]+nc_5wy]뚙!LqF|I* G! H$HRRV9v}v766&Hho3/q9Mq,k׮?$ӜziZI955DGn?s>я3PՈ,,,ff==Aoo/X UU0 ~7~C@gΌ"E?>>ΏyzNx<ɓ'B:r;3/xܯM:NM2aYׯgӦ aY|ロ~MD#c"@u ص\Gz[9}4'N`dd]Y\\̙3OhffF-P:s$I"l69s xh4J:FUUz!4McݺuLNNrwSOq~PP`7c=FR+_ 7|3ٿ?w9}4zaq~_h4H&=zBַp3g'>ɓ'?̝wɃ>$I|_;䗿% @QEN'NPըVA٬P2'êVh(333|vsuבBu"o{x'ٿ?GaӦMLOOxg㩧j*YEu9599)hiioŻnfggyF5=|~ܹYyHR!^/uu16q=\!t][0YGFFv}vz)Z={D"ٳg(JqmۆeYY9)r᳼t`ݛ6D;BadZ+VQE0N8133#z'&6l r9j|6YΜ9#j5RT ݻUm088qڵkygjtttp72>>NXdhhHt+™12nK[V$:3gΠ:[laanzFe$;w\𖷼rcQ5)dIvyM#)ǻ,`+fy/|Y^sssFIRhFToϐ[ ݅$I\RPdzS fhhx< /,lXbv1 #kґBlUd&^,ϧ0u~Wӏ fx96Ns`:/^qq~^xB,jPhB^afvZʶmhڵD"uqT7f~/D"tuu:ϳ>囯`phڢex~a`!El6΃_TLOOdpHijaZ l#:;;+MmƎ;شisss:u Yy[ނVΒJp"p;s ###~dxS,MC,\ A4~"q!?Y^$]޲[Rϖ-[8qf+x<,LLLpWb&rBoݻd23V j5eaa9h] -MYįZ톘iM;+#\ud~S!\n,~5\CQ'ёd>e"sYjE5kT*MoNQLi6 QCjv# "_8Gx9z}%4$!Zt:M& w/Jz󕨭G9<֭T* 8z(iN>alذQ|>zAQ[~=jײ㯨 ǃvŨ%1e)Yu^Љ^h2|nJIYp2 mLj:+W~iXjH$LNN'T3L&CPxgX.]QUX,&2jM7݄abΚCIoδNfggUV5Җ7%LY[m6= HRJ Ҩ6,4]'I6ٵ#'N-i;pܿY^vӉ|ILe0dW+¾ܔ m` LZCH(ews[ߊdA8/yJfg|(.7cQAta`i[&-]߇R C4Z*IP^w.<3;0{ J’%dō) F„cQ>}/. H$;7U<>/S3Ӕ*e6\~eJP-RN$T];cnaU+iT Ͷ}Zgg8rpa- !Չ6eHsq G!PUUǝx\hzjѴ)W+\Bȋ/Ȫ!&''t*dbڴ=hY2r$V=ErYYndjNQǰL,^˳1{nkyղK Z:)|bBBT糇eɤ7ozn;v؆WU\2.E )(g\MzOdhdX"NX`nabk 4:(  N<)F;]ᴑ^LKދ3 faddDt[N*yEM$h48{p|)jUL6 Q* r9++VmšC0 C| 2-&`lٲpvd.+)~v>CʱɎN0MܖL0@k٬KxTә/1 {ʂ[vώ=Ӣkq TUer<ۅ䒙ejfUCDB~ZZή4Kԙ/.5p뵖lej:B]dZv0_\,Iw!YPT14ɂgFti5Uf9uZm5k5fggyM7188ȹs疱Հ`ix,S.UZr9l6KPKGkފ[vѨ871I)_ ՑĽ"!͊#xռ ryΜ:ͪ\agh-0211!:岀mDY-/h|n߾]I 255Ocl,l좐˳cs\2 x+W U*Uλp6|)isfEQDT6z ֭c%~abX%y^/x;H&\{,,,zEGόvAn~~sSS NW7?:~zNw;I:+!,GE/tPaA}YqGGggFׅqF@QPÚ,tuΩ:U鄐DU>}Nݵܿ}|d{ ȝعnTK#NS.:x׋Z2El}QLw0a~t=| UUYv5ŢbEv`TjDBa24b*x竳ղjlՊI߮((LM<>NR,m-mޗبVń\(ny׿mf;G":;;>Bm݆3<<̲>&&&ˤ2YV bŊQ&ΒNyÏ<^YXC07;Ncc#=;v Eࢋ.Ė-[xQk5nf(`|rIڼIr:t[nŇ>!FGGy駹袋l P(p(D7g>b6 !dL"I4"5'wp7LopOR桇` (6B/xyOi{'}>BRm6XnXx<ժ)nw}}}d2~?{att /T&QOvOnN?EJhIlVvCzG'PpXC5b:$!:B6r⹧1cE_?Wp;&8]9۫sF)J>OIG^+J`7|3nIؽ{7W EEQ*я~D0$ һK/VcՌPT8 `ED.H("4 |C4biP+5@0 %PmhiT.! L<7IęO䡞vNMe}x.hf7p /ͩ?67rB!~:ׯgڵ\ill8(+:Zioi%( tuviP([l+.r/===GLNNj*: ۷oCl]L~QSSS\Z: IDAT,B֯_ϽkL74vM8à,`bl6nOm~Cʲ^Lh9nP.Ъ59czZL P.|,]m7J%6}vuV4 b)$ m_]ٳgwuW]u\r 6l4gy&-b1o@WK5kpדhkk#qxfH۽|Pt"w?xgȥ3B1 h) {?X㡩Jɤ/~˹+*<<3Z[|w0s'n z{{k(Kr񥗘 ց,(88]>?wq+֝AUV'l2t:"ٳaF:J LQ\}]>/czvs<+D"o7݊yY=%KxBU%?Xf W欳vcl6?O:Or_}FXt~b-:fl8|Jc5VP ˱rJԪƵ7Zo3I*{^jl޽{9s=kCwg'>+~=Á}[oy\Qٻgf>?RC3= zqÇF)JOLݔ桇bӦM166ݻz6g9Bʅ#0qb(Rv< vZZ[[=3IJ^ <_zlC<^T -߻$322w_.6n8 qGm4X0M־_>Ciؕ9 >,F$=x1.8cYO6ߏ";xƍYnJ;v Zj Y@yg%^]g;Щi5ҙɝ\{qޏbblb.g,/"6m0K.Сag}6uwsg`ZD"6OCC~qwι/z`;w gf=uqg~zv֭j5>pmmmZ>򕯐fYlYi8BSMK*z#ދB/q%p饗2<<Ν;Eʕ+ٴi{Yѿey5Pe37 Rh"ŅF4BHT+&a͚56ou?44dspuj/z+%]󖷜YuJk5 (J! ֬ /d`JvnA:Dda.o`llJIal>$HȒL(:OCbp|}e͑H$,__||+_V3+b{Dl9B@&Z+>+!U222b3?\x\檹T*1??OX!^.&''m}Kۣ[n֖U9eMb= 찭%X,dV^q,Y&?_$ºulMp8lY Սd֬Yヌ>.ڴk{f-F~2 2<<̷-<g}6>r~OZfԨ駏 mxK8nnnYѨ%˲H |y?.+VxOB.G$.\p447316fND b-7k:ߎYZWJH8'\7 ۿp8lϠLNʪ:a2?dKZPp:BSUvBCMMMR)6nhW577MgyJ%6nHP Qի|œg5 `=KP<smar fVJŜ`f9reVYUiU|> ƒ]r2tVjw$Q=zhkcjbC]?e\¿[<~,Jtww144ĝw[hϞ=vLZfS[X\QrAZ42 ٶmsssR) Ė瞳!YtFj%2ÙR7HD<۷3;;gӷ[%bI2{R(Ÿ ?3/_rq饗"#Fj`2g,d;"`,~dYf||>6m޽{mq q 73z[_w+(BPYSDZ^˦4 p /5k#011Akk-yo>"8p8i楗vuVZYrZ!1bԿGic&)ITŊY~qf"TUnثT*qr߱o>~xH$;:LQA`ڵON(b1jn U$CCC6 x3'{jn A7U4hp !:(%|I'ք Yt)t{ UUinn&fTUA;lȞ8xxg$~%rdbHɦk[.NJ5kFů駟skr9{d_z%|!~Dxgxl;wez׻6I$IE[jVױi}U_"lعs'###Z^z)r|^/SSS455m6 1jNss3t!qIf. :>,؍vҰ?t gͿ}_|.^z5`JK+fP8Y_UfB~Z~1c׮]=sJ24SR)lbZj7t333zl۶X,Ծ}?fٳ!uT*e3d)*e6j$q*"RH̸@0 F D_ "|Ə!ؾ};֮^C($25>γO?aCU3NHd2i'_Icf#fQ ӽ/dx YP`顸7BEqI,[ZZL ҹyUSM aC244>éOEٻ?_z W_s .}\W!͟$gKp&bRimF*mo{ׯ'OrSl<<GOOnT&E$F5D[qR{-nZ%fkYeblܔ%-lE}b vc=Ɓسg=---\s5[+G|S7Ar$F8cIZ )㜣qLSC#)G3%/E; 955E<祗^" "2_|1###$Ij|x^ʕ hԤjQ+F.&QdfW66LƮU֊7k/}KG>֯_O2og?r7SO=_{#avH=Yz kׯwO1fgw293M[)~::;;94:֭[g>w)JvwHS3sk:W_`֙]q9_yT&FFFUU 0]|%2 CZ%#2>FG4ώ B.+bi?` L@Y&5Ų 7OXe˖J?ݴ155e~ӟͥkPZZZ0V5KeCQ8~%ePN qљgݻ)_oVϵH$ho70$ :@s9Ϊptww ѨhJGD|>_Sp j~Sk>A3( D\.f6mdĦR)4tM300@:|'pf/miiazz&9b(7KZ[[IR|~^#~z. rn"t*Sf^R,N?&TQruT=8|IqLn6{98;,gh^&֬YC?蠽իWs׿u^/XYv-Rs9YN'_=,]|>$sYZDl@w8^ ]eJ" T ;wnFK088ȊO@*i gW lbiR'jd:w ,9qzȒb+7*B.m3tvvdfͿy,{/+Vjt;vazJKaR1Qfjk!3?;=wTj$NO]hiTN H~j&4ID"P;|-[64T۬\)}}}l$3t|/ã E~e dyR$f@CA4:;;ַ?I̸,K&QQ8T*vuX9#+m%[ZZRT*o' 6ؘͮ8*mנXv^`9?@њDz& PjK,,#kMQi6an,ڵ A4iW)B&};Xbf9j4/bPHaV(y188HsW3$ɮ\hDWXATb||\.\.gA&OO :$@Ut*Lp9ffaVgݺuY|IpvȬ]QB?û~pz=X,6UmRTT Ce8p8 iBK,wcc#+ٷo?a> 222V(===T*fffL]WvfFUUlG)d&ݠDBUU QBW%d2S2(DnwU011A1ݻq\CSTI̛e3Y4MMMH*> Q*="GOt8)"@J瘞VRsG2^[CRԉ8Jsguch?@wR$ͭ-tww4Dc򁕼|/ɗwnjK`ٲe}v$X$(圙hho7cR?Z0;7KKcqt^ r`j䳦|,,Yf4|!2;7G{WQH&&M(itږ2mkorנxND]3si2tR3(V-MLOOs"]]]fj @hxXp "guJlRDD$De@ !6ᠪaB2q{{BjdY"No53cX 6 g.Q)]ISa!۷ IqպCfUM1>9YgE6# DBMOs!ZZ fX$SOneҥ1 oٰ{"#w2؋RÔwIEN]o6t4LGGMkV]ϳdN'󴵵dcR%R2m팍|vLKS3mmMvSAtԴ z ͝b #SôQ#Rr53>3E,4P4b&h+19g'[ 2"rt2Esk 11$Kٵ{Nj8p;]~.E!_,ee.3D:& r+Q_ y1 MC4DAO?kJ ՚^*:WF.V榛nn`n/~Wぇ/ww]6l%\O~:w>1;;??co>,7|7|Cp }xU IDAT[o~﹇an\uTk\C]XPSj*POC mm6gBǠRVQ\NR$w8$233,+j^7{Pj4eIr 8pMMd2ާh_C̻ˍZ.Q+hja(W5$tR? jYi"EMsb`%|D*I($R Ccvv*2rK6G!/Q*"(b.n$r{)+00\R!q6Rl iƸ͜u|߷s%wy'?<y{D"<ôq饗r=iԧxyivJDQGeŊa}Q&\wuyf9< 7}|書gxdo_za/37𮫯du$tpms8^L p9\326R,)WT3Cà\R3@x,ĉ4TݯvN5CGDyf˵\Z5;N70 k!S?}XmAT=w}u?&,p|&\yn =tpڸ H`E0̕9괽U@v j +gtT4APqj է4h͛q:$B^;d`]|kЫag8~~fp6 lsV;K&'j:,#ʂ?mlBuSn9 Z V<7^COu;j'H :X"8=&#mk}'*PPT|!` !YJ 8(+e_.3kfaD(t|(0+J2HdWiG_ns#B~ #2b9bb,/t "7NxY'Xڮ:N *& L(JfZQc@u\.pZ`F= _8ѯ-¸D_ /bXk]_ PxpFCor}sPCAh8(PChD@ E7$*uQEM VYe OǘO3ǰ:8>sGDC]X"h85Ś`=> 踁@@CqxM)ӛiiq 8j dm|1s|RIF̭c ZLArdI^&81 +=,uxeXqѨ,bxcC^'g2 pхwY z`t|^k9^CKZ?*C\O*PC1O=)/tLn4tj?N@F ;iD"7NS^ K٨F\-52)hcLJ{[xy.a|lynbx}N,=cnPfffs9CLD"ivX,r:,TUEӴn(aA "~+Wrra^Y_A9==MRavv|>o0g"H _ds;IByPd%5[ SDgsh(je.r)Xo0K:Lf@@d~C$L#HUUmw]G9?;dYRH$\.֍^Of(pbP\h(iT`nlgS@ՀLV!_%)R! ?O~;frT+ z:mdʎ.^"'?:A}t^`}ΚAWk%Q,m,,pD"AKKI ˡmLz{{9x `N@t:(UR)dY=:zF3,ljb$I"c%633CWWSE% (kA7 C0'B ,f)t9gLlnBQ*C]zDksZ%K>5a|S ;a8Mby" dq^V3`.UZCM%@ŴƝBcil܊u?GQUj", Ȏ,T8zPGOn@VCUUWRX,0v,j5n7R ˅ e[ftڃVp8°8^8hXcKR444rT*T*kQUSh:f]@[[xM:zQeNLj ^IBčQ׀JF,:3f(`%%δUR H$(=Np8z‚>z\}>YEV@GT7K}jrMnz+{ijX`3N(bvv% U<1"./J/ BV)1I1GK0, JP0<jd2I0<):HArcdZCE a M( |>J]( ,PJBV+@ ]B! `vv֞gffz[y;А_ ~`br_J>_͋ Eʕ"rgdŌzWp`t0;7$@/׫c%L GE_>p2::) LOOc5 HciP%sq<^w Cp 8cᏞCxSVUO2.b5fAJ!x[@ q8DNمSr!NdمPuuu^ISSΙgIPc,3z1XeAvuVfkv:T y+Zlډ݉KYCl'oO.#bhwk ~jP `] Nr X,Z"P<> n?<ʒ3+nEUG\@DxduAaq<"Π JtR]յe~3~oOꂮn~ωs3Oܸmߟi}BIk5RQ ]h}\gL&?FjA@Ea#G{]t@e02R&XYix &8=⸇հU|8nmFQܠIqjcgRItv(arW4S._ 4Y[[#%=]gc!5Srv4]k&OS,,,E&e,-IU歭qC!"s dR qB- E`W:/+ $YT1H+Owi>*>JdQI`fj:~ H6 㘯|+}ɶ]$8r2O+3f 'o7T(daif*/+C0?i]/3ljcx"^Aw{S{ Q]S"1 㰾FC8=ԩVhFTbmml6c@(Ov.1[vT|^kOQPbh sSh*hB vB@Xdss\.G^g+10deem.`s ]:gnhrm oFP>gY.w?q6/~iڜY[_h ~?яH߮ sMPdrYvZ!Z`ӥkPVLL苾@d0BW'hi4|Jv@ Cl/[ IDATUko8C@TY05>z!VB]uӸ&ogu^oʿ <Ʋͯ*ArUh]EDS&> B8XqZ˛AFI_4 b(O~_ڝ*;?7N(-T*>#߱}n*G_2 n('D%Ky6bC'IeilJumո[x'ѩOŀP0Ad2Xr>휅ә_v̙b١vjtR9 ЯbkюDŽef3&[[>(N>UjQ(' qg(ko]c@({ׅ?BƆbP[ ۆKZYF8#2EcvOm#q|$Zidr~ĶDzamOω py0 %ݗY"N"C#P UQ,oTwZ MDXDbHH iN}Hn*0 =Bfzmơ]2Μ=C&a|l VWVדgR~* 0eP2THT, DD]h"@5]ڇ]Dup;je!FEʨ$'biT4 y'"G8b~n 7Y]Y2"r`˂ah 54@񱗿1~uũӏp Qmj~O1SP\rph n)P*y{r=?o{'g> "Mי[TqߣFKc/"kdzk|?ITz /@~Sؠ26I4z.rFP.v:`ˊAaS,l׎6B@w:wlg tb*ǃ>7d;fVeV8L6}?cG[`}cnYZZ\0>5'o3]_!25F'i=9=0R:j"2J[[S0<'b 1seTMuP H+m1^/jWZvG$"HH 0 BPVr \xq:l}d{1* 6bʡ sLY**+❷Cc +NYP xZ%\\_k[ا9soYqMy6[~i@ʤ]gzaOC 4>}(l 0e c(Dj o}#Y&2* !*0<W_,]P-`]^aѣGg>$q3;; ar 79я[[s _8xL]<_s\Ugf1KmerkB-EQ󬯯fDl dzM9?*BJdd~hc^HδPC`j\,FPwB'KmqlAV.CuN*uYB;‘ܲ&^pyK_h 9SZf﨑WLe/2eǙ`mm)\n`mmɉ c!B|H!),ڭC/RE@lC>eoZ@0d Po*({!}|w0&WCdv'+%HV|H%>F1'CH.ƕ`  ǡCf 0wı%uB@ۀQMNzYĂfKs] Ӥ^kP >VFi٬T^M鄡L(F"\ IٻF^,ds x6BU) wS0Ӏ\ÐZmlmml6"hwbbk ^ hRCFV/A,fLݤ [U) Tsdrquef>?mӯp+?@b<'OJŠiVĊ$LJuK]&f.+.+BzQE-T(TZ]WBdtŔrl#L2 u8tsl:0wֺ o~cz6P"AӏYn'DM>8$k'1.J"oQ)ޕNjA[K 0B‘dmT²,N:tHwWVn e,#aIgm,nOssMozs3=U8eύh,,19 C%zKZ̖bqqB0jJ&J'/hj|x 0\1 )<#x5$Cz EOlZGL0є"QC x[un)LvJڧϕC1.+R}y,BQ j]3==C8h菾Q~ڄoC߳z'/kp?9&n::ob\n[?]7EWcUrx^I h|BE[]@*4&|D;bxwlm|X(Wkf_rhhNAѨıF!;Iyhŕ3@ʹ b@>X[Ȁ7ԷJ`@sˏ9#粺e:#'w]W /?ٲߖ"21&͵*#c T΋rMG LUZ(* ~Jydd0G4iFR{}! ԆaL;ݝ+;o(yw `ہ=*;"≝y?HJ )ňz")*崧nq24G]\tV4 EQV @GGGi]l 6D6!%lRTLꪆ Xd:M- tcq#P Wxw>FDz]\\E{&Zz^̀lPb ;QՆPclzE&&y1ǧY[_JVK0jj%8Xcccj5* vM0M󢟏Md2,t0B.PiQgT!aIiWI)ObW/ $Nִm(7-B%,/K&b] <@%fm=ޅD-.Rx1i\I]Pq#.v_횋,%z܊Jٌ.ۓ䠫ʧ4&.9F2<-RQ tW=BKtZ_ \D 9T3~H 74 [lc|\v\>Ƌ_bN?2uwej XYYZ0p1DQD,,,<RjJXD~^'zN\ZRTX[[czzsΑى;[n'O>-:\ǿ0 c@(OPHf aLO<_''Ӳ~T Yo!d4 MJNsiM4T IJzTI^̈ q:O|&Uy 70. 21 "CAFlT7E xhX^GQ \Qف |jr,vL@f' Iq9q<%Lh0M۶8Qql6 ٳgfJ%y\?vWx "!]^]ApcRe>΃ V/dw7QDvƗ@!j+@dB)!1* 8ndy|I@Ri&P ɊS a0l)t) QPnǦ꭭mG3 biDQDբP( T*]h'K6ϦD> 䔒(( }n;!a.rO8^F8{Pb%"VD?RfKIС(I8]ȚW#(:WQz¤B$\'.&vli&L+OH}D"8KKXgq[51TTM@S45<|ʊNieG'W fGiOuݤѵ~ͻbHe~~B@^G4Y__8+=" Q_&aj`P{J❒IRM^_uAhֿ.5r],Nӵm )OF*ߟdfl&ϭBӆE,lN:ڻ0 cCyAǵqRWN"kWʹd&r˛"BUQ$'!T8<(5MVI.CU5\A5-!pKƦCѲ 3HNJua(vI wN4ArR袲bTǣW]8Yfek]䅊v#g~G|<̵:|NM~8Xy|+F0gu훥zcLͰX`0,9v-V?+gѠ406j>qu:R IDATh<9 Eb"eTvihnaC{22I-60s'S8)qhr㻮K>׼OOm˲X]]effs%8Ʋo}}eTTtLL Cgp n`&*&g@+5 Q |Aш<\f9L QZ"U2zfa uh+4pz.>>d:$t']bK:XE> 0~=|@z5GF8yj΁) T{ fƨҋQBP\zn@-4|ddb]WC?X "% +2*WiULx!iN븜kkkI.%*J\<=)V\.\KL&eYK lfee8(8ޝYn8.T3vGu Xo bM#h*o>:Y|Jt0Y;} .#wp8[J (X &^ * ccc qI6")z20v} Cd"4JSDNWj aً*4} l,YP άnҰC dKxs<:QeD\uwwD[ ۴UJyrj_O$Ͽ'4M@Zqs̙~c'ZtO-v})mJEj5z^V3mvO()R:nL&f!EqrQ!LL7k0bzX B&EP]*SB#ns$bU|<5@d*Њ;lz52epEmPAv }897z~:G:>=&DU,jj5ؿ?Bͱ#075 'aj{NU< ӂ @+D2;kak8mX߀tTJWdM3 !-j!ș*lĜ<','tQXxcz\}߅G8ӪoBLC]wߏ1 Kۈ3am웁qpJWi:+?{|;?1-G0>:L.' r]2CqI(qQY86^R#P$:5Ed#9CӡR\=VVŲ,N:+_J]g/L݁6m\<==r} LbO ̊I{ws?M+ͤ]%T4E%T4BE%No{g>ñÇd ᡳo~6wq'NE+wfx/^:?Y{NUW=Ǘ8t~Oh&:QcJ<( ]w<kkkxj5lϓ=m(bBANs8 6[04.3 Mȏz=! Y01).'Wwy(M/|e0,.ԄLM.e QxA~ Ɨ{Vyx?4gK34R ?6g .aylll(ʓ&Ja҉~zzo~Ðy666z:to>۶BvkY[[ ҆u(Oq/\`}0]%T1LB%RȘgO0?Ufm{4W߉댿=V( s09]?>|/-7ɎMWݜ~04sK˔&>n36L 5U?!n)KK$֖,\KM5B|ZX |.!FR<$FԵ)gp>сѬR/U W![R#/y}Ym_Q"0BTt#F E|=@l@oM.y5s;dt%:B%V(:+}."g~aӧO033m,A< L7;d@SEZ=0~r*r1::ӧBԡ\NDQD<uu]ǨqW?dگNË+<[o`fvzO " SYn"3A>?X\=A@c2ϟ+3_knahF<o|3jkG9sbtjzLA%,A U(K&tP!yLhYGRLF>m%EN~! *ejku76]29hyzՓcQRäGZt`\7]2و8y J| _`nv( cno9{/zK:2zVmV"]OC"ݥΟӌxOKVi=>K?<OXʓ9|ò0T Vv % >ѣGj5ʕ NbEj(tQF2YQ2ʿoGL_ 6j&ƠhTy9KY 9]UX]$x %aOkELNN%|RFFF.xBIWlqSױm0 eWI~y`IĴ F:P#j{L(>~3wȷ? j5yraiއ>ˏ>>Jz>psUط~]>>&7U;BD5f8YWZ8CSp Y‹nff嚫9pW[ 2^ʱ~[@vKyB{_UJ$3s4_$1dZZRJ|6KyT]c^=ET2sU@7CH(Bnt5Fhx/g=. <2̮zJWW]uqA=|~\Գsì4DaÈvcoJ'p=&':.wyFY? ?C؇Yh۬;LYн)TᅮgG=B-?lӗ( ЦG.~e |'UollP.BQݠ2:zNŐ"?@hh|iDlCCWT. ]JJߗE<WB&;>+ ~щ~wxdT[.tQn U!tAU<)N<ݮz:_Ղ0>"J펜%Ξ|?ěcŮv[066e  ̂!,`=a``୙a3 1`cAmdVnPt~sNݪRlk}o9Q{_Cs:!)u!k0P_>W~7-/̱sK< 3r,KGT'FmڃB G(^֠{^ӳ!1,&)씀1U UFUW{L#,;˩겄F_aUsDq'1c a٠ J+¸KlkcT~Cr]ǡR0??sƶ7(I&)vA*rzE&!kdڃ6|ΰCӡX,R-(p'tt,!Ϣ,e@1] XHEffrno| {hf-pqU,@S9h_=;ͧ?[pO=y[`M29>g]E3h<}Yn5躎F= :(ɉv-޸؅5EMY9v QC!HCk,4qvJn>h'55tAա:K9=2UPQ=**V!s8̳>|3Na6@yhR.)7ȱg61$Qb=j$4al2 yB0, oAIL݈=*{+a9e^vU'P\ʠ\\~CҫH)Skm wiyy[o{LEaH ũw~|ݪ/ϳ{B "t5ʤjT䓺ZR)E>e6Bb] 2(RWR'D l>t+Bd5s/]`0yHM<mƘ\!^Ǭ=Ϙkhvw!  lEre&Cw>ƹvPtP,3 d |_bZ;^Z-(j/^uaP0$YZZ?|;XYZnqpA=~  fv&g+++LG,,يA8ź{\ )<"D`cxo I՚Z4!$Uw|,;^ 1"2mkZD^,.rG:vna_ ms07*#\U,# áCRntukjpwQ,ABR**4aD6S嵃mJܽ\.h4t|2|K%[`zt Sbc$jJ+1> a```cabP c*D8|" "r5MyVD`E@}xGʥYА)lO}BQz㒱L"hӶ49+A`,%_3Xrb0s|ƽ$8NZ>㡼@$7TZhFpȞ{ /<\;gU5L : %U٠Yfzp̤/AH &p{hD1'r 7$qm0_]R6Cz9} hn+$9 _%Or51qFz|yqȞ=BRl9;v¶7(\uLDu&zz™ylh=JxZgX8t͒dq,yDEOFd[3Ȉx,5+*`kjAW^c^73r FkIT}@w$/0M$P&xz c!..ZDF,2{bƋNA A ur0 WK"B2-ߍLM0rT>+_uV9hr>V#]h5G=yp58em} PlVNþ}p_ F1K5njIWj,pݥ\bk-fODįQS@ C􀐐(t?iCjj{8IceKD2"r$ :_ȈgA`Z1y_eONOi3G{/!`_2l{R(X\\LrjJӣ\(bAD%2膔2BOjw]rtpE<^*!4I1 Z 񍴍ИLHcQi-JQ 89˳uOy8V|i,5iƞI4|72`5q7PBф6I^(BKK!O&_YWg{ՆܔcqbtM։$蛄㋏?/6(QKH2\Gmn mnr˽d|t8 `S&I2aӾƂS^P\~jEts7*y4p.L\Y; BTp}#l) Q:#rǟ?}dڝ+ÍqB 䋄nYQǩ:6 zꜤ?*/,>ڄXY;~`B"C5`wdiM$3hq N.<}-eԺQKL꯽}{dFgx;"wsH&5YYo ;(л,-@*% 9_Wy'ˏiyQ g/bo{9ɭT|SȀg >uE.?ϟ23|c2( :%" 2$Th"5X3ЅF70NDF{Z?1D:C?P(IA9Bbmcr=b8lbY 4"S,F IDATހ\.O=Vy+UMtZ$JT^-}}r9|ߧll_`gt:3s VVVft?\lv("ML!t:LL:|srӾh,! hhD A("IIVVp\Lh9A"Y]]WM,zI)_cBO,բzESw:HJ! ]g0 `@0t;pǾMz 5,/F)8vތQ}] s{ȣ*ݽdr_y&\51R~?~2wBeAömrpXz=O vNnw>.aBFq>Q 1}}j)7Yoc:BSlVЋ'w$*PPc3Tݡ=GK <>&,<\0h4[.C1ȕC$%($νPDBKvl{2ޝ=,Zv @jTZH]zK-I~}? Cfgg1-)m!X]]<.SSSdTnTnIJW\A@Kc4ݮ:&wgMA?#叠:P_}]L̴E@j'){_zB+bߍQ3>Bp` '"ER}}Vb;vk d.?l'C0Qy>Nx'bk/P'ԵdUгx^@$=n7T}1@7\y9$F#45CH |WjCL,//ID\^M\o;\V? 2ӇL]u>aUOy53@j.J|[KmoP4M* \`{;033ihF&桇6B>JEyEk㤆СCJtPRբbYrGtO޴RiW\ݏ ۀ2|GEJEya`I>s?'?aEѽH|a| CM,+C6[4!A&>eGZT[&xQ|%X¨b<2z>HC7p8^)*,]򀎷cTA\$MR)Co\d@DCdm 0 "i361M j9#C8lIt=imfI n4H<9$:;$ WzC7bzz?!&K+ˆi./f5E&kp^|lqK7۾S\<lN.IhѷZ-:v0 9|0ΝR.t:U$ _H:(R! 7 8ry0 SUmG$hSUGfG`f#?mߵ6 ֦Н<ǹ{'>["Z!{guven>7ac@ Snkt'N=WB\vg)CƂNIᦛSr]1:r9>24 Sn~4|훾LF "tF8Ow1UKUu)"7"FL;g&{#fDM  K1߂ZU<)%Bsw'O/29 p vU.0}R" K ThuY^:}\i`ɲ:$ؿ9uKux[~O"K+Ѝ:7ܨۿ 3#O\.%RPJH}t+nOOB^LqSB9jK%p pG;' n1Z&6U¹s03Qո=Ï|?~fSD1P"[0m 13Yxfw"þWΝٍm PC{ XY^FJ%h4\*~s! ЄJY Q|ޠ18ppHBJIb4 um(vWgkkkLLL\h48n5x^Xuh&Z055h44QJ֠\46#Yg^+!qKar݊xmKLC<ǞyLյ.9ˠ߇BN*fgؖӲ(e}u@FZZ!2 ڟ˓X&2ئ X&rģ菆bC ʗrj2b }Kp2qeJi7tA ;,fjIDf+V@O>}]B!C^eqqzmP)ÏcT5~$^УR<)&#}!&vUiGᅰ=b߾y癜u̯0GkW>]#w'rGGN3<!x#J  k eYdY~bH)u=͟\8֏On]7yi^rg4B Cڣ2,hЧX*Y4kLvgԇ  >׿A=7ҥ2t|WoHc:r?Dz N9Fl6gCmJ ׅ\. >#=RxC^>tYyd49eY8q"}/tx 9z(a"#~!j:SC5!E.0>S|^ T'&AFXF9e͐1waYZ=: 3|}de2E`Els [4fK`hZw>B/T,K f&mt| iu:t}"4M9GK#DE1FZl>K ICRR*Rn/Cŏ~OѠU-`lZ4M6L鵻A6t:}&k!6>,};3Ab@*ebB vZ5??>8=h#Q^PSUUuTSZ̃"n=|+O?$fDfoE0 0Hz^u+}$nO7`nn$,-15=zNMv:h4JC7>j%,N{8NڟUTRbYv!B>_e1921 "ZkT'p=29nO<,-299xP9ӧϒZH "`mKI:\t#"+s=pa j9 ꗲmR^ 37{}kkvvAj `:ܬ*600?_jae?Dd^x/1P'ü "& up Ŷ7(;qv0Md(-B:Hх: aGn{/ߌp!NtrlԀ-;n~0TܵZF#?׽tz隖eQO@PaiF<ɥ?H *sssΪo3eYy^\ ^/`0`nnUJ.sαw^BNCZ%>ۧ:YO)aid͢i1O[d>- f?Gtra/Ϟ2RS>O33 MtگyU1GYm@RE7"W&,>ƾ^w|?mOvy; l﮳XټB!^de2sϷ0-57/ Gg0q=.XX^]bfj  xW}%MOOr]wKb/u+|Evڅ8Wԩd$ 8}48T}GE!tGTKUGX^ZǞ"crE@#")-GBn8Ux7 p&u,DѧZ- )꾫T+l>U5 A@J,+>+{y5Cz-j.bP* w Si4j(3 6*\ ,J[VZJZ<,J;a BNsϫ_ɓ2Y ݤnP,8~9ʕ j :-U&^ycg4nOae2VbnIz}^yv>OR)O2kQhpv|⡟T㱃o@lHqG|\O~/pd_MT0Y _"E|%R(㼺~7w7'Os`+9쐃oʼn4K!{x,GZ<7XFm , f֊Cu2sxAX__OLq%e_x 8Aq`&A# e_8]DfƤwRG 00S$14Wa@&k8>, F8~_%/CɆqQVzUyhb80~6w EX2g =9FKT4#e4QpT躞niIäpo4^~5H HNBQMK @huhD0t|*'_xHXW R*~=]SU}k! G}nKIu6Cj;L gal9yX 2;;vST u,MJk .PB$.:#4"> 7jhTY5uaPF)%n7кR`aضzҷ2gRMeĭFL&C6kA q%8F,U G@Gl1H4 jA1Q\M1R.-tal7U Sjdb^cjZ!#Օ `4t!&35lv "83 хXt]~O^X, pH&}zR)eHJP=Pa^{׻i& ݻP >v:oBܷSSS`YVڻ:Cd()sFFM/Zhp}HL;͔SM ['iIM; sHɞ_$ wYкd"'8[}-(T0Bq-EMz&n?S =@ g`zmC(`iat/ak:#ه^7#g IS+G*'I\.GEh_.Rx(:R<@۶/fzXf\0 #Be5 4$Hi#.v6p@3f " >pts{C(K8yw'h:X}׾9sSzNB쬆&LMa**y2 FBO֌ʣ*4zA05\' ٿw|k~MF]c#LRh5MGʐ^C'iԥ@ZtN>k_w/g*1}y(O5n'咘h$QLay Cw XG%XP 7ޔ0Xbe8mY{VaL$+~ޟ9w9FsKtM9‰VrF禛PAyP%Dd`kMx.6挊N4r'MLGg_t r/bѠFYIPp AⱵdrA^c4ee 'UP\6cY?B IDAT:tp gffh֑ۛRƎA%D0fk2 ؀*\զ /E̬5fxѸ ֊hĞ={X__OCۗ*a )Y;mdX[[K{fKa5 "oxg?{EriRDӴTb~~gyI_q`{,;n<8|W\P"& b:H^c${~# jQp'-HH9TJrx9w!$ ƫ0c8s 333aHX__0??uǛ Er. VWW|B#%}Ur|ĉM5 w[R(}Y#V\IV&~]gϞt QrKYCbLnꩍ{ll6ٵkWgQmbG ymsll6a`&IKlԆꀑ+V/r= jj5 $PL8_.RHH\&ͦҕ9zbNL&z333^*le%ϙ3g(鵁+3X/;6ǶPܹ2P R3H|"j &1"wɆQfGx_~\ ;N*J*AJyEbI@hz)!Rf(~(OxXLNN$S,++++ P_ W9*.lP0$iP((H?p1 PʯbY˰hT5d,lXAJLn5~H|6i4vEP'v._qR~#.x)&/^2$}k uNjuyR˂بB2a0fy0fj,0mK#j# F#N릪{QDVa/ɬ8a1( )ۯiM`G:`04MTRIyd~cD@%R"H}hZMd FjF-ˁD4$峝Nvky/RU|% R 0J qXVFD`eUq#2''|\Е"OWKV)aGuC;!m嶕xO Nxv;RB}E@HWBrCB DfӅrh6 `8BZduS nS8T`ŽApT344p|%#P`̠},ݠjS,d˿}}V2v' x<9 ǟ`0qW5Ϟ8FJMG 3(}1}nw5" $8ȻnG "#$n4NW1zayr9mJW1 jy3}PHg0"t]BcO0~"sE7U ^{ LuܷoW~뛹{z $2bk}qqF#GRK4(!0~wyl"", A~ EV+!|$/_JRI}eCq2#trRZ̀ǡnA؅OrL=d9덧CN5lsm]7dk}<}e|y4&8PDiy^*{!$INj]i _Oj_dɾAfiaeYK%ycy:uꢿ89ƒ.z$v99s& }fYBrE\AƛJ8DċF'J%5Fr5Q,zfq̥t~ؤtv'$5DIu`Ƿvsi3%bvn^ص{Jt 1MOE,3 = YȔy m((RJ^\ٶvտŲ,F#_ ë޾2`3Mui(7jhrm9jʩSҁ< t%Lht&[y!d2X^vc]RK466F(U%࡜V71;=^Ys1 yZrszKrHiCm_I[IONqbݢӓ${]З @oy{-ׂ{];!KKKjlnR x5VvM>OI5M[oɓF#JRڧa:SߊiVl64 LdzzgϦ)$9~8RJmaa9FrO ĉڵFIZ^%ԒH&ӡAI%#,!Ž džƶs%f?8yU'2m|yyV,`bb~:6 ;9+ͅ3PJk˒E[k0 $+bo.~xl0p$  !@ڋD(FF+)rHqCY6?P|5s}$69s ? ߧjh4̌ڵkk:!5/ظ///ۘt]_no8Vīj۸KX4a8%qKz{pc״Qws$Ĕa7v/,plŒ͘ؠX@*yOOoIHIeYS(({(QLӛq)d3، -|Jh0s(?c *d3LB[l6\J5d 3 &ؙ,l\ pr9~v%otLa_q`0Zb6>7f0daaJI.K*u]?:˲ ,y Gd21h4q7n)x&ֿA7al6KәRJS~?]);QJ2Z'1;vwArCI:&vlT,2.m#)=.B~ofq>loo!eّ "Zӡޞ2wCIx{XSOA0+Zd͐ [aȈH+DXӏFd3U|`DHb?z* ՜>}+WxҴɲ,VWWMncaaPJm4TU3)y&bѨA\xjjRxLoqqvmr9&zǏ#fyyl'd^p&/ ADek *ҹ\nn2yJ(fz6J^>0G&3ytq uԩS%4yI+"ys[v/xguMcLD?a{P(h4¶ǿEcy(*_!g !?*] d":6s+4#o}(B`krt:(bii鑬J{Az(XXq)#S-:b&/.B5|ϖ~{O~7E~Ǽg"8a,b'擜9D z3IKlT"I,BeayuZW^~+r5;'T8/~Fw "ŝ5/C0>Dɓ'~:bx"J)S)+na2P.qrLs*I>aqqR? CÜu;Kg8G.?$?G¢[3B2ھװ~+&]2'6(ƨ؄̧ ExzdYZ I}uo믳Ό:n| oqͦiz%<$2 ;0 ΐ?dF/a1@"įĘ|+_'? gΜa2ɓ'gXg801{Anph _W|;hSYa6z?Q."# kK+2v콈!qt`i{,,mzJu!6m؅4Q,MM#BNAfiӃʾ%T0,29;J\}DZk8W=m{izG__֝OjX}޲?_B7og?_+zW|J_Y?:WzkhOtDkh=J>kkkin4zmmM&ٳ74zZkl6SO=]uPЀVf,0}o[T4sjzggG7;ηhJ)]TRJO&ҭVKkh4aZk=L̶=kFEz{{EVJinZ)5nK*: aW*%ZhQZc#OkH{:.־:KkZP:Q|ph}%;iիWgRz뷟E)"a#yA`~т+2~& ̒ŪKDߣZ*[\|&C l4_3vY>u7 P]BP-?TEVO$epspȢbEH8|ƕj㱡v:mdYCFA\\^X:"= ?BE~_ob)Ⱥӛq-.a>_9w^MS RLJ= i .!+ IЅ^ I{֝ϚQ}" w^0 j,2@c#*&Tvp⳼vO+o{V8 k.IDATŗь@'&0 }>h3gxy(b0P__ӠȌܹsW,vP0beCŋ Bl%ryܒUN"E˗xgtm>ӓzcc[nrחi|ϳݢ2}@= ?ۿΈg>ϟo>4&l]yT6L ڊ2.~bv,m${0pi͛,//S,2-1}SN1 t =,fFn#)5r j+D+E ]~dϞ=OS677Mdkk'5<թe)Q,͎%5R]#RBZfbFG)_0laG P!q؃x;;;wl+W8}/!az~G+mBQR짔zCz@CIs({APJ[os=g\ذ+'7/N:<h2Ӕ" {# 60v\f2\Lv\46O)rrcz}ϐWRB.d2jQ RD]pao6D*Ξ=͹<΃DjPR;@ JI&1};X.vZmʋ5PNkMg.)VY ^H&3- RxG~dap~aRp󓫬oL[XC9~p ڤVWբP(X\^?hzo:a tKTԠe/>/škEG2)0 $'"GV(}-Bh4RcB<$‚`Euq EA""(H &4neI˞*Ƭ83ZItb@p0j+O"RqF7HLO xy饗a=0h4VeIB{ͮi_h;f2]&xBQ`ސtE,?$ i2 |L jM[Vz/ $kT( 9$qXXX8zg6(K|=vYG错%oLn_]SvR"\< =O KQC!Č&i;vSW⺟Ùfb;cm;]Mٴӑveu>A.XG6,ޗy Ɏ:7 A`:u> ⎨[w:2L˲RcBL& γdz2XIn8Ĵ_g>$YZTxbPCI"ECh}xJwx=^H"Eȝ"E)AI"EԠH"ECAjPRH"š 5()RHP)RHq(O?vIENDB`sardana-1.2.0/doc/source/_static/gap_write.png0000755000234100017500000003663212174204305022725 0ustar cpascualcpascual00000000000000PNG  IHDRs8sBIT|d IDATxw\_ {8Q='av:ֺomݣZGUP*"3p%w%y?Emhӹ  0iذo"#u`j!Kn&:n<O<y ^cMhѾ{û|L,]T~1gAt=*H._ =!INL1Ԩ[ZE*6e4N\n~eKL2 6Â%B!X񿹂KC0krJe9͚ךL&ô?F_( P(0};#z^6Ě#⋘l\cׯ b,I&M]FIsE @6.q(qy9 omS^ t(^R\ǙQXP:EbOt^<Ǚ?4_uǪ?Wx\~$Ri,6Q+l^s?ŽWcPX騰ݘ<0~#~Osh ܾv`|_P6'ظhA 1}lY Y !d\!XZLIbtݴ#۵٨#܁ӇYDQٲbF ĕX#۵5>7%({7o`hL>|-D=fm |>b(8 BrBb9Yyrl,ko^csmHB\s~Fp>1]<žMp0}C4hΜFJrwɉ޻~fY;͛(t*!f>x]P\pGj~ NJ2DMp~k~ӦF^pߴ)b?;3UѸ,Y>,ufprrBp>ɧ8q.=#Xo?rsycjZQjDp>7e*=r Q)c6\$!.L4kΣ/^ptfR39ُq=DFڝ;x[Շ[\Ts~!%/_fz:NFF qd]R,GvDׁu]={{+֭qIq1Nx0=W#1޺Zz4d2;#&| QK[RR3G#jO^<'k4\=+9BQQpݹ{эo[Uc(s?BFZ*l x&솑۱AJ v[[7Ӱi"?6zkfn8LWr]I Ʊ}@.]Hl_ #ZM30*n^9iFo];t諘гU^}Nd2hKQXPKg hT\Th G~^&Ў}[K oA~>Ο<;ׯq5?xUr9~gWWTSI.""t+v>y#vbE8s'hyYr!p^s-~}wrr U&̶3܏?{wgx+}PR\gLGCxxzbϞ%\ܽy ?rc.KQ\TH8yBgZBY3PaCTRǍ'u mdea?]~V3_`㢅(*,!A4nrzY |̟5l9{-ڵdžc 0OFGaI1xsXy0.ׇ>P^=RyחΞAA5_K8C>868s8}0~^}!t,`󲥨ߤ)=Kb7__%8+[^]r %g{p^ J5?\/p`fvcQ8Ѡ?!~:bЬM{}aEPXQ  uqx4AݺNRUR EСg/MP~},5/r+[Cغb9*_+fgC?q̜F,7i`,U+zO.9h{wӋ= W77TEWFzV"[w8`gSppx.<<=1l$z6v&gڳ;j8ml_J'߄S'QR\ 5Ѿg/yxֵԷuCAѹ_{h,LvF88v`FЪc'T^̏f5hѾ\1q*2UWGC>}G{]0۠٧c\AEh"6:Lư Ooo:v<9 pDNů)Ȁ}dd$J%.Ţyc1xhxw8Q&S&-[f6:ӲS7mdAJ N>+q|%*V'aYp[?D\Q\9wGQRRo2jv[ {xc߾/Dq_LhQBe+q!<+T&kC{-AѦep0ZvFqa ^cж[78O?ǁm[иEKԬ_mѴukTZO"Ԋ*5gT^Mf6p<5ٵLzpuw+sAZ*d2V񁛻La'!YS]~^rkn1|Ru #5...j#G&} Ϟ7ww 'ňRSu&Szu2ר[@k]<^z -|kք3޸n"hu2<.1U̙.ժ}YҮ')jWv޴8{3 o?P]+\ gQekVjT2 ̖䕀eOe__} DnEJQbE<0~U񁻇' yIR O`[,k Q\Tp9,UzJM8걁Z#Q(JJP\T|tJUgfb*.KVnXu뮓vETtXt"h &XMuEo!˝8<{UR&{#I3~pBtC^{ZTXyy]WiIAptt_glFxTYW:S}ؽn sXZ5yx l: vx) Uh߫{u;ꍐ%7\ƽ7NITbGw6: ʃoߨY>lݪP 5RO5OkdqtX#}]fK3tlX*pӡWö́LT\xW# qy}H} GuKsQGܫtď}ѝ: jnnU+u2"6: ߶-xul] .صv &%aؿ9M{7o"Iۿ?+[ .]ĕXğ8۷1ox,8xrrg,W.nX/BׁhLݸ@J84d{Nx4ϟ];Q~6GJp6* iwn#&<2 z fL-!hݱbbsͿܯ?yZ3f"3=MnH`~ZBBü/`t}*MQMmݱ#6/]=кSg NT6h0RѢ}mۢ1{|8ۢs~6;cBnHNLĨ?K0S,Żd2\<8r+qGZB3غbNĸϿ@]7!س; `午Ŵ1os\\\fgل=a8џ~X.R \KHx7|_Cm*WFqQ1ã D!#-yϟ#*l>޼bw{HGp~ /z:e]Tj>r\+JJ [RR^[r\:]BL\BGTB&|^LJJKJL4i϶`  aE}%Z5ɴtOrbb1m˪YjޏҲ;?igtٰ/J(#۽P_^wP:vl˘Ϧ`/|cRRYeu'''}P_Q* Mfz9¶ ~(J9r_z/mWW{t!JcE&,ІJC}];<~LLB^.NL@]f_3vOhdd\*}aO|%7cLW1NMיc{Uelu޽5d23ĄFݸ6BFtpm\~##ʒp-۹_kQ,5P(L]nKl}CXOmkW4OTe?~ShݱỦCܻyCg?)5Hԛ+6C 7׬W?IkI qe<@x2ldgobIH9PR%h{6MKAT"}qܤUk8;s_ @v%.7\F©(*,Ro_|6:ypvqA&M©Suusv>>F&:=cûByx`sZG##&g|.km96: !KUۍwEӜlY /$NLkt0c>JUbǿpy8DV_޸t1ޅBӱQH} Cz ヌD@a~v!cYXP,WG/ ժS~57@媾TㆍʮG.cD0g{7ݰ1O=a 2( ҵlcop +Bkp L&G}::!(*(*,ijj4ƅ дudge3?QN( fZ]5K'}^1]p w96v*j+JJhLt ?u E䄇iidhNֺc'T]=ZfK֢XeɏsѲC0F=PiƯvma0|$|8s6؎ǏѬMܿw bφPa#jM[+-ZM AF÷F ڹl sx\rW6U$˃;RR4oӱ3ocد?ed@P  A;Xl<ā[ܻz4 nBv%.xx{E/7l h:Pէv=vkgr'8ɝPٷcxX:gi<-K??t YY..P.pvqЭhף' woĄHYgWP.Fׁ5c٣j~\\\0ax_2[1,7K"2UB@#м}{̙.w=`ǿq" Ơ7j\O5?;݊ gh쌠nql_8QfR;u_ާZ5re2?q\}ȫضLCtr'9V߱!*~~dHܼ|ΪM^8x/?GJMc5t4*UU-/hܲ`^j.]eTjWSѩ_4m`:+UDVcQOiNPKQ(P2WʕY)eK8+̜w `Y>ƷcGY` >?ɣG<{( lŮkXg?Aӧ_-vr=}':*ybQ^=CԨ'^NP P\\Y()1NjhA/=jK)0p۸tL]Nk3aw޳gzkJ@ 5cն–[.K%%(.,3r=Ƌy(,Gh!}t4|/z fo\"oDf痟w EIDAT5Gx ,)*FIIu5bһڽ %8uD3Rů:Rq':^<mӜ'u.C 7q*21vrqF?+C~w^ hEGvBP<ʂ ռ'RIV>1 wD̾pT)3n[ -,=EEU 1=TsЭX=Ws>n_ZfvK1O#c+E(W".9‚ܼr AqQfqY..H{(..\xmxDBcDUWjIq1TS֋H̘86bݟq~%oAYsahIwo}SAPdd^oN'`tDnŊ~D0= KBHINƣ rՀ>P޹f 3 {l[#kXQwOOU~ @'K\=>ժ ||r\fW&-[۠d }{p{N:`&| /URn=jύ>#^ n&^Aeߪxt]zՖt4og>Eb~e+-Z`%f.^W774Ysgzq"U׉_J,[6Aj N //,ؾ mO_{t&0!]kX(W5RvE짟꘱V;{7u +^LʏˮRһ"K !wE^}'_( c]eֻ1kre㢅-f HtN+by0B@0dge9Cn B&3P|3mܺo7YpaQcn}!!(_ISh jB.+[Zڈ 5m`oڈ" 7q1Gq tF ލAF#rvQGРiS -!ƠGx~ofl#1v.&a%xi}Bz-feZ7XioRY4o~ЎY !xOD\Qܻy]@qq1N>MyP;7OO 5wwH} h!jDZ:z6aסFFɓ{# EIII -ڷGpuwǠG1n"Onuld?eqg-F0O;ިMyl]'drݹFq,a>mݰXDVs\iKbhՇgC{Cc.AH Kc}{#ٔqq%e<LVCpG0!υ [b AcRsQ*?|aL<2&P AVlI_Ej#s$ũ4Z<]6v*2dc^Bm( !^֛ ZD)dN֊|c gȫ#EX]6sn5Ɣ&L!N kӅɜ@ARq+}sDL0p,H\Rn36C"Ȁ)}Ro74% P3!kKBwasAAƍ[BOCbz9g굽:A8:OE6s_)y00bK@GoRl}oʌ-Ӓ bcwla +u.}1Nj0Fn1s#F|Xw 0;keSwSXz"5X\27Me.+ם1=gzM1:mE1߁q>$FL!|! UvE{Tdh`+*UzGhՇgQAn'mϊI *TxMʔ^ R8y.8bhՇgî= >!q!!HᐐCBcy٘H)#>cm]6h̅ <y@aQDoi1ӿ< $.e0 1W=y< -Fjcmm,=sè{̇ !υ0.,>qā)kmFffHLL@%W_ !m!ll1nQX%P"~*V!IHXy.pOBR称S{Mqg _u7 ',ykC'q1#L~Aą@BAЀ"c>< A#!Q!<QaB{MkLq s!̂Iu\ q!B[H$PCBF\ˏ5 s!DX A miLǵۿ[w1DH6T8Ol93ֆOb[*RC'ǀą`*69BBτ15<AXBj% Ląi~C%Ɨ!" ![k )@B&"oxc9n1ЖDXi0m}M;Z`3LԿnM ՕO>ᴯ? {-4ݗ !mCFD[+hXǀn <-`Cgbo_$~K-f)̎6fM2JL&Ӽ\ƌ:XTu|X8 V=P l#X51]Rᅞnxdc.a+5יЕfX*OA@c.1„)0l30]gmo^_G\4bsL%lc(\[\W3]3$,F>~ Ă<XUg2 ym3ρI6Л5} ך~.ةNwԺ<{$H%@rgWȀG.A^+!p)ve@іv ' a6,̟ AZ䖜e)W3>K5en+MШ>A76Ο ؠn1 ch$2 mѬYOOmiў>-fE)][qqZq3K|tRvp斗 \,4JMe$L[9.2BjBo.j+vyf 1}&$.]]$1. %Aą QN:WH#uLK+!c S ^5F.+6qqMAb\'Xs$A[]fl]_kOUvS<0L4YbXskzG5bui+j uMLi2eM$q0F#dbD,AAj/2]1۽j,_>qT[A}BH4 Y1qpǐ) ńAZS,%x 1eЍ {i^͚q7/4ąplŠ{% kݜn+cI BD( BBoCdoE|>pA೓8lave0&L):NVΎV_}l4 cނR$J !=5uz\kbB ]U<FN(ΎV_} ۺņAPZsQ=M qq@KB %:՝  Ѳ0р>Aa \ KwBCu0! aאX  @bAB]T*>aX# ą AAXj"q!q$*jH\ x Ci dq )>ײ ǥLbC A g7x3gKP>LGYt$.AZŽIp1\=cy6X =g^q5\ֹU8И a$ q(^a"p̓i7c#6I0,\7=e lc,[#υkZx@HVHXl>|ØxBtMw9-dҫ/!6l2qw? +\ťq5nhνrElĶ-FHm#[`2ZQ!i'V|Z i-݈@r@c7\[.kPooN뜯SP+W۽uK !S[8k#)S3J(S1ǫOCls!c.@\SOy3$:BxR?<6h\ҋxg߄ajLffHv`Y`\=G|Hb{ f|/[\<;6dh KC⢅$[6)iUyG4rH D̃HwHB ub e/n1K@ FÈ}osÑEn\ Z^4B"Ĵ= g[G3A $.H5/P\weH\JXvQ$0a{И2hL0:tM;!={8[|@ υ'BfM=P<>SSVXX.G!]H\ `j9sv-M ![1wS<2ps,6L7c-qstÆЫ }/o:ƥƉ\\=PKK$.gqュ?>AP7 .eJO?_s)@\$z!Ӷ2̬)k]$`laŒB ywb먰mc,:]Ѐ>GL¦KHB_c{eZcڏOhq(.ą >;#RnP1RnOCe)[+sXYro㙘 y.VKlsq,YxwRx.xc-*AZ%4t2\ űpVk{V|.A°#PB:XRPI\ LJLϖą Š5eͮ? ;E_ņֹAfcO$.Af\k%b#υ \kJH;+s!,)B A q! \ xb,25=SX < +b@OC&sKM26y.AZ0yƼއA`a]>olBC AD)L | b/ńą B S~o(,|JG H\ 0U`#FT s!B=~ /!Ұd2*RC̍꤈#>cmy÷Bd.\C0n[mh[B8غo1Bu-Ka$%ᖨjJ%/qʗeiG+\q>V mAضp.v ]ƕyh_StXA2$5gcWdר3c*t乀<Nk_7/y.6[1K>baL$ĊK,BYSJLaӮ:K ) Api5 p\mhu}y,4Ib85QvfҐ@87[3|C"bw&a1 ۲24зg%IENDB`sardana-1.2.0/doc/source/_static/gedit_config.png0000644000234100017500000141762312174204305023366 0ustar cpascualcpascual00000000000000PNG  IHDR! 2sRGBbKGD pHYs  tIME :@gtEXtCommentCreated with GIMPW IDATxk{M<4K:2K:3?3-   E71H930")N}x9jy,M:+UoQH4q@@?/ .'$8,'"/Ai7)C TkZ ( ) IDAT%28")& ιE>,@gw .\6 Ų 8G |Qm+   o|y i@~"0 " 5QX5C_  >-%(>-%  |  )RYdS0( ׶1Z]dR.$ʧ El^YB%  A+y=a8Rmh,T*Bg_'9Y;#@ckA7+ڤt1Z]dR.$ʧ7Nk4[^dR.$ʧ=ckA7+ڤt1Z]dR.$ʧ&Mwt;( ӳ "KVfV2+"̟1Z]dR.$ʧ"P_td7#զw:*$tsz  (g[ 9,,i|W-?pP=}}s> ' ơ_*/B;Q=# I|W-?pPG}W-?pP ;Q=# I|W-?pP+;* -WqYv#c|a ,i|W-?pPEys: ) 6)#6)#$5eYgC,!"/i 2eVrC.$'?i >^:8[>ږY9'#0Hc'S'0@bue*p3$'1>a+bVrC.$'?i >^:c'S/bVrC.$'?i >^:p3$'1>a+bVrC.$'?i >^:m1!$0QIE5j^rI0$&)5Bk 2eVrC.$'?i >^:#G'+5Bk (0x IDAT3'!3'!&  %GG- 5   : !1 GG-  (5 GG- !1 GG-輬z4-")!  'GG-1"qS       Ƴ                 WPBA.1IcL-#   81fe=Ԣ  ?)Çe~  & >'.fiC֞  )QBc'S  =)Çe~  & <)Çe~  & =)Çe~  & =%,mvSړ#<)Çe~  & \em -#-#  Uu2'kkQY=yyXKUR"ccA= EEZY   •LY=yyXK•LY=yyXK•LY=yyXKUJTTkY•LY=yyXK5_+-$-$   wsԑp[} ҍpfԻɌq     /~ IDATՑp[} Ցp[} Ցp[} ˄khՑp[}ͥuh .$ .$ .$ .$  &!^KB0-MMߋBA                PQR4;>&:ozq(ȗ                      !  4:>깃u  ((1Cw IDAT  )k{ju~m> IDATy IDATefz IDAT #)"-8@    $!$%,2$*$ #,7  3@+6ġQA IDATk{xbH@ Z2:#2:#2:#2:#2:#2:#2kcQv|Z||Z|Xqq< kJ0rLI 1D t_L@ bB{0A ~ #AktW& Ǩ(:H[tb:b}$2P^`\> nkLIJFa;;˷DsJJ 0A zbH> #zଇz6["Жrm_otg# Ꙑ IDAT D˸lOED9BGq #HΩ(-[MaDh?;1D ğ~$4Vltm< ']g`~8TO " ԟ}$s8 &5G&5 /DaPIb$HH@Mպ@J bDpʥt^S57@3H^iV`ZtSWϒVy]̫v? 1̓D ˏY2oo,҃k\´W'ĜkZR37F@ZypdIJK39@-7@-B]inC@-7@-7p *b`5 ĜkZR37F@ZyĜkZR37F@ZyqQMM49@-7@8^խy`R37@-7FBh,bDpbDpزj_@=@-7C6GXUrbDppdIJK39@-7@-B]iխy`R37@-7FBhGM@@ԶGe"ҙfTuz,lh H<~h"۷KELC"'vh99\vMjP  ̑`T~-Ӵn}3 cJ fl& 0A  SWe_D|l 5*̑`T~-Ӵn}3 ̑`T~-Ӵn}3 YM }c@ )ל\k+ip) hb_*cJ fl&}c@ @KسNF>w[5  9gzY"E6ϫE!ۮGŪBe_F2!96Jc#b3n8V/}ah IDAT -> :""0A$緆elI jv[#:""0A:""0Abd%jmT6Nb`RF% nC@ '6MuS6 C1 $ bd%jmT6Nb`RF% c>c 99 3hqw -Mqg3 PlHɈnA0[S"?t{khHgy&}rN9r  /?T8&  3hqw -Mqg3 $bqFT"?3hqw -Mqg3 ƪ 1Tso*$bqFT"?[p+B 2ezT% ƪ 1Tso*;74<U2C IDAT6AK1=@Pʿ%+0a}^&")0ju~;  D Ȳ &@OvK  [['2'2K IDATż%*k{BP^BP^#)/ d IDATčо IDATq3 IDAT`O6%'-"2G_ͧqz]m  ɽ .ATU0ʈPeiY~žѶ]Xqk{"bˠW%x͹d#'dwH֧S>5:[}5ٞE !XX1ũJ oOya;035`" =__/JyX:" ̰dJX+fjJ-*Nja.*Use()REOr IDATo} !?fy< Ϝ$g_A*θz\†12â "   6 0*#_e2dBm90[vJ?I&"F5 vK+v!uj!LqOb{OOnIR> AjMfw2_W.#:1;A).Ix6 EK5  $@b@EuF' ;~`="!7a> -SI* /S\!;74a˞żBP^Y4n5̞E آ IDATú2;Dju~_ A+ IDAT28=)/4 v{a IDAT¼#ER]9>B6>DEQ]k{kptqjX5 IDATuNowPpuNoZXVZXVY'-5̞E e`QM`^]FDCMLK|yYBbE rVMA ʆO^x˪G |yFDCB@>OOlb:V@('-!(9>\lS6/-!+<@VvIPMewQ IDATޙIIY5bʟnVJ1+-!/AIlf4-!'-!'bR@('-!'-)?Yrems5  Wʩ/zDrǪcp]"K@װ忾AH$̉UqcϷyD5ٞE $a[n]֗r0R $ ?b`"!MP;) -Gm|"%K<˥K%٧@J"%~sG* (>PI#    .LyP-xq/ݡ|9u6w]<30!'-$A1?%I=,om^%٨:M%B0+ul1 mrUԵ{/ &R@ᱡ7W57S$تAN( ]+(bb(U IDATcjL1   ú4)ZT LZ+ =V+橡 ZY'6  E؞::ثG 1Ƥ~`RwINd vb[$?]<|w$`RNwLix1e_v-̈́L73#(/'F"(72S='+1+@a}_v0 Be9AjD7bE @e> 0qYV@7&,33S24X|UU-0CWYUSYUS;74żBP^ap~.01  |ws JT]ú2;Dju~}!'-{vqojf IDAT k{>ENý!%).4:ۙ IDATOYc[ IDATx~ IDATwPpxY:2.!'-,SuNoδ#3MVLJHYBbE e`QMĆog+δ 7-'ο876LJHrVMA rVMA dS1rVMA 8,( "xyvsoؘ IDATOO B  #j~eU?;9()-!'-!3MaҤqTA('-!'47\ƛlQB)'-(9OawcG?;()-!'-,Qf4-!'-!'bҤqTA('-!'47\fT<75$'-!-@C\V@('-!(9>\Ѩw]N5,-!'6\ʟnVJ1+-!/AIlbM@('35Mlg5-!'-!'-!'bf4-!'-!'bV@('-!(9>\lS6/-!+<@VvҤqTA('-!'47\  g~mPDhO ~y^t*rkE# ΐ]Y~/dq)^R 5E rkE# mRϷa]䟩w/  W`řqsz2TҒUjE~"ΐ]Y~/dq)rkE# hO ~y^t*rkE# 5E ΐ]Y~/dq) W`řqsz2T̉UqJ~9 ҽtȆV{Y1ϭx_7 5E 5E  W`řqsz2TDr, ǫp]撫3 rkE#  zf   f~{ib   .LyS  .0 B`9  "?lb      .0   !;]w $ ?b`"{tG)  *)B`9  "?lb   .0   .LyS  .0 B`9  "?lb  $ ?b`"%~sG* (>PI#(}i=  "=c}& $ ?b`"!MP;) -Gm|"  .0 f~uf|\NH?'+ /ps.[bC=[mmaL+S4< /ps.[bC=[mmaL+=FR /B2S4< /ps.[bC=[mmaL++ /ps.[bC=[mmaL+S4</B0B00?U/1?T /ps.[bC=[mmaL+&A IDATk{md gf~91-iSI QbRFY(zԗA QbRFYmrUԵ{/ (zԗA QbRFY QbRFY(zԗA mrUԵ{/ mrUԵ{/ QbRFY|r nd2[O碝7 2[O碝4cjL1   272[O碝2[O碝 7cjL1   653 cjL1   ú42[O碝{q  xn OzRjt1 ׽nHsI1Qq=ԀwOzRjt  1OzRjt1NwLixMp=ւxĝs@pH11Ƥ~`RwI #~n $y!:]. 0r%f 6^#X|UvU-}7lc&y!:].湈Z+:Zc3 _v}L'L;}rKo6gf) 0r%f 6^#y!:].y!:].X|UvU-}7lc& 0r%f 6^#_v}L'L 0qV  2T:}|] "6Vq:X|UvU-}7lc&_v}L'L72S=z".?`Z0 y!:].;74]żBP^γ!$2KTYBbE 73!'-!/CPulE60!,?Eg^G,(-!'8elZC=;(*-!'-!3L`ڮWF;$'-,MƛjQB('/-B]xlZC=;(*-!'-!3L`f4-!'-!'b^G,(-!'8lT5ٞE !XX1: @:ɺ"bˠW5ٞE L˹G1оr/㱰%ḓq'HL1оr/㱰5ٞE "bˠW5ٞE !XX1оr/㱰۫(e^+  ,]]'ӡ+fjJ-*Nja. 9C$  9C$ya;035`(msN, $   1SV+,d_9 !{S20:Bq  1SV+ya;035`+fjJ-*Nja.  1SV+ʞG1i9     o}  o} Se IDAT!  6 0\†1  066! z"F5 vK+,53CjQqK|K:5'2BEjNuTޢoC52%9tPxZďhC95&,51?RVt"F5 vK+,53Cj2dB)>z"F5 vK+,53CjLqO{OEXsOnI@iQ Wj9Ѣ+mf:  0G:EuF' ;~`="!7a>_W.#:1EuF' ?kI-8znJ,+A8 4v}Y8#  )*EuF' _W.#:1EuF' ;~`="!7a>;742żBP^ú2;Dju~_΁ IDATK IDATn IDATuNouNowPpδ#3MVLJHY4n5̞E e`QMe`QMe`QMδ 7-'ο876LJH5E rVMA rVMA rVMA rVMA I IDAT8,( "xyvsoOOOOOO  #j~eU?;9()-!'-!3MaV@('-!(9>\lS6/-!+<@VvƛlQB)'-(9OaV@('-!(9>\Y5bY5bf4-!'-!'bbM@('35MleU=97&'-!'58T|y_M0*-!.@HiV@('-!(9>\f4-!'-!'bY5bѨw]N5,-!'6\f4-!'-!'bY5bbM@('35MleU?;9()-!'-!3Mak{ "  "gdJ?hŸgy^ Wʩ/zDrǪcp]ΐ]4vťr/уd Wʩ/z5ٞE ȆV{3vͻv/{_kl(kӺ^k Wʩ/z5ٞE ҒUj\ȮrHhŸgy^̉UqcϷyDΐ]4vťr/уdhŸgy^5ٞE  Wʩ/z5ٞE ȆV{3vͻv/{_hŸgy^ zf   f~{ib f4-!'-!'-!'-!'b  .LyS $ ?b`"!MP;) -Gm|"B`9  "?lb  $ ?b`"(}i=  "=c}&  /Vq[#%,! ,TnZѺ $ ?b`"{tG)  *)  .LyS%~sG* (>PI#B`9  "?lb   .LyS $ ?b`"(}i=  "=c}&  .LySf~uf|\NH?'5E +/1?TS4</B00?U!/B2+B0S4<+/B00?U+\8 IDATmdng91-iSI mr$u+ZP(zemr$u+ZPmr$u+ZP (ze mr$u+ZP |r ndcjL1   ú47cjL1   !  53cjL1    267 cjL1    53{q  xn1Ƥ~`RwI$ OzRjt1&VNy1Mp=ւxĝs@pH11Qq=ԀwNwLixOzRjt111Mp=ւxĝs@pH#~n $f4-5̞E_v}L'L72S=z".?`Z0 *mSwoC&F0r%f 6^#_v}L'L)jqVz 2NX|UvU-}7lc&:}|] "6Vq:_v}L'LX|UvU-}7lc&;}rKo6gf) 0qV  2T 0r%f 6^#X|UvU-}7lc&_v}L'LX|UvU-}7lc&:}|] "6Vq:;74żBP^γ!$2KTe IDATú2;Dju~=^h!'- Qh. IDATIxxxxxX IDATxxxJjwxp= IDATxxxxxJI78JIf" IDAT8I9x9xxxxx(CIDATxxY@6Y`O6} &A@ l}oȺ&%ٹs̝)g}]x^gX` kkkj<^ظ8аy͚ZпTظf횚߽rm"4O.kk\kVV.#RH$B!B NïliiX,F4$ |UTFdtH4q9>"t]`q E ժz OP]Z ̚zu!5ka999%''㳫k>iḿUIWUd<$2EΊՍu;BbO6p뎜>88yh`Çcǎիב#GШAUUUaaa NB:rO>\hggW[[`Gg]]g] #"466ೢTVVfddTWW9s3&˵kFn@mSFost|#(oOlҞiw YH__fUVsIhN  3oooڱc8s̯J.L幹`-[wtp/Eʈqp/e===X6&TyӣJPE? cf+=jg !>0|JMZ1,M`%?~{]`^h M6#% ( voժUvss+**ڿ?nXzaVXۃ0-- jDDDJJA 7n܁/_͟ŭ yģ{HY1'/)M3. MM~\qCcFo%;^_|00AoQ,0(a%$$TTT Ѯy<hc/LOO'-GE!t?li<-:zh|R|v*OWЕ3>I\E()m5R4*Z zu8 ,3@T̵ل[ ,XAgJX`jX`Ӥ`APPBzO~~Ç; 6l(**F~~~؈tl[UUUQQIǵŁ$Ihh'Nh{ԩS111mQ>VEn\\\<==E"%MF_uYPP|d/Jeljeː={"Z^J[ZZJ?޼i&Lx;GX{qi&޽{_yY`dfff||<. сC:erXeƹsB!;aзo_tv1c|>Bk}իWN3,d֭Cߝ $FߚJ!G'6u}S Ν;Aq/LKKpr+++CBB 2.JGe^Șh~=|ѣ##?(:d\/PNYYYNNNK^^c߿8::ւNPbgϞ5r %܌2qvv+* 2x/B!|߾}۲e 4 nE w5`W\ͭ7ydڨgC!& 22ҿ6 ,у?9%!Wv*(xT__^Ni`ݢCG $׭kע7GK!$ *++{AZJd!F+1 ?$L!Mt0j藑2zm%( F/-A#z@vFm6S 08xݐل>'̙3r,8"Aȉ"}Q~ ]RRB%tr+# Uo48 h!ɶI:xw<$i9%% #؋% >ĉP&VX!1Ԋ\x0! m\_P 7ofi 7IX94ꅎ-U={D7{DAʑa-V6(@] Fx+ dalh ftД ; H=2{kРAY@yQQQ! S5k֌1_+ҁ\|9$At#fzAcH<ԅI! +A@B`CN-..&ƒ nE0T[r> /5Ei  ,&ܼ@EǏ7 7CBBR90sn@mi0{â<[=| ZД!v`&|&~|ذa!d$qEڋ DDDې<ji \*^gfE8Pbԩؖ ĸHHH!?V}轷cQ\xPZ G`Ejtй{X\SrJR9Z,Xh vC ,X`.]- ,X`q` te ,K,X`E&;MgL` ,K*12ۭ a ,n(,X`E`i ,Xh,M` 킥I,X`]4ɂ ,X &Y`v$ ,X`.ڥI WY`0x h&>p) ___˳Y`ZPՂ\K$""rC:|ԭ10E6A,~F^t ,X`CCCD˨teRthnRR=z_~LHHw䄄,۹yv\0gEy K,X`q_j)ɦ?pѢE}oq ///BQZZZ__/:F5]vFrt&$ر}kj@_?йIP,X`qaݖgӜ.ku//=JuN y5e 2I#+ϯ:+([hT)*ܵi~"y"Iѕׯ+={HRd;ضm%M관ByiԴAhiiϝF8,M`ŭpF5 u]h_mk>`ج#ő*j{vO F`yA-H 2 .o_nHP[[.! 陙x$004  BȰ&ybߗ@B92GoP,X`5:(wQfpk*Kk[b}x82bEbViBݤr{~.5;Hs4&1H^RΡC4d_-jiMTD"\k4@h<. s4^IY`ō Z*򹑽`crpNp:hIC̱:@g LL@܂?UF$yHa*vIþ4=XtABcdӿ{kX`E{x8U"0ҁ^WW_`ϣke4.s9"P򫛜L& WW,X`qs(((&h&[ZZ=ڹ͡NN-3Y1T*cbbz}NNyhu޽M644GpwwҰ`q##;; *]HH}WÂEW`0Jp8]+ϵ ,Xh,M` C4 :33ZKÂō''ȮYLi}~E3v]"O!t^z]kiXpY^ nortnXu(3_`Eh1Mxk* 7 .`^QbFj4[\;ceCJZ"Hy xOFIk YSTT]HA RlWnB\^׬YsDa1wܞ={^/ZXw!":yĉRj;cm99z>}`[pWKI)))uuurxhRED"qtt\jՀSvv6XP*Ǘ[paTT~zO:d޽{aawCC( BDDSWg5Zeӑ=v`GK,AѳW hFkǻqԽp4̘v[rJeyx\R 㴉""X jJwvv޴ec}^s̎f#@%iXIϟ?svD/TWWS+W9s4]^o߾`A888??߸q#m @Jӧ7oތp 3<kdF2"RB ODIbN*&&!x)>_k==aY&R)WqKTӱ@IRυF\١kKKؗ{q+)m!6~qm5*7ce8k\q$7. >KiD$pD- ,++^RnU7)\&كYpbKM͛kQPH$PkEWWWؔ]2Ci6voQG/y7K,X\k0VO H4yMn& &j58/AZUUrooﮚ/kMp$i+W ?r1k֬;v,j1Y`qɫNQ*L XEXr7|"AvvvQ qƲK4k@Wb$Mۙ!Umm-D£a^p00H`o0kjk<%+;{Q&uLpرzqqqEEΝy<*&/k]BS7) o_F%meԍdX|m;NiY3:9.6N٢ܵw %KB{؛^25dDb;VGk;4tw/xQlh :D4hNGJ6m"kOvaSS%N|p:Gظn QWQ}}H(ڸqS^=+**ǎQ]uk*u q= KMَs].v-޲J{׿YED\Scvܜmoɜ9ёў#oشA֠F}HIHȽ bcbmGc ٌj5U &i zI&hVK`;i~g0숱@ dP2SaqrFh:,\;D ?diMR>۫e_ܤ^*uoiQDCqrrBС)_rEBW_;dZ-7'' (ȸ:e`7E6nZ< (޸.Р{~ \_/Z`lwǎOξA(;9$m(C?.u)†5kˊQK{$5^}Rbڷ";:gLNbCY=<~ROhn#wh(bBr<.!$8D&>Ҝd-^ӒUqm߹=\&wwws߲mKQq/Nzcx[d*ӷK,4y6DVGoaAƈ~8&XA;'Hl;kjz[`ьw@1wAiQ[{4j??? Aޑk5Y#r7WP\}O?'&:iP_WWbgW\TvAT'g놵kEb+/ ?ѪAQARIKe}SV\װѣm_a8:.sۑ!FNvN-/-h]38\nMuע }vww1h<2社I޳OKspt!91Fʊp9\ZuVw) *# b[TUP]-ڋ/+o_$JNVB3'?:-E͋Qfa1 ])x1*vL!881uvkD$G 8-^ʖ5a$*&i~g1j2Gpׇ%^e~}aG1- ?ؖ쳳0yRǞ~ YboI:A|\#F8;9\[Tшu,vv`6_~..ǟ\r?2eʖ-[(?OUP&OƐ^y啶/~_/_~gн<#WƯvvvo񆿿̦Z?xʊXQX+sw;+ s;S͵>>5D(l^y8&)(x 2hTFzs+۩^YSU|)0 MiLC|hƅ&!'*:˃ b\bGsRB 4Cz(;a\2CA#dz2AUidLv M||چKr{x՞¦xަ7OThVWLt H>K%C%W]x[]&9{$h:]tN+ѣGx#G1T_}ŋ 9oذrי3gܹsR+..G4^ziҥҁ',Ydʕx.\xݳo;'V655(-; ,̃=B3-$_PmYJ?[# Ξ9uzGgكuՊiWHHZi5sI0)RVi(FF8*O!}iQ8T5 6ZSUU4 -]F2@WXz_gO>}IuYXyO8q]w#33 !CZ >얗)--=pLu֡'qy̙Hm߾}_: ywFNwruX{Jl'tr؝9=b H|݁/zH3g˽b>jth5  mԼ #/COØj;ڒv< P#,QTf-'@WP *=MvҽĦ ڬID}Q4]xLR<--\>ױ&iZFu"#/5@`\|s!g(&[:$m*ₒjheЏ5j^5N.OB[Pg>Xđia >Z=Mj1cPP& C͛49uTt M Dc^jPj1jrIF4IsT.\@rqqA k-hUhDEhhc1|g~*((())ׯihh?~<55_!>X$H<Ξ=z6OC C<%'+}EP- ?)L v5Ź9 -YXۧ#*[ڲJ]I]C2lKP+\YK\wG6$Yis5J{{hDdyT*\&)a{v'˾^yQa^u]M|L{n?7Ϝ;UV^p;yxYEmŲV5k I}ϳy5Jupᇵٙ|oĬ]ţQ^IKnSiC]j/\SSNcٲeK֢ҜΝ;~kׂ֬Y&=twy?@Wqر4N/116WZF;*P\jP#4ΆZ4md/₆[ɦ4SY]]h FF|Em*--cW܈+&YTm۶v$À:(AP\8/4znݺ͚5 ۷)))䯀2؞;:ZjDLIܩx(a dP;#^ݻsSS Gj\7;'"+=QEeOyݭTs_ng'|je: -1d@(n趪]/Db4,~ӇӇysvej>?}n)F>r}>1DnYVMW^~xnEp#r񤂃Y3_>5Ϭ]<YY! .[f?l]l44~:}5~f'叠c9rV}y9Zچ<V_yh #yGP +d瀆:bĈ۷?}pc=֤KT?|ƍKHHk3IO+lʌ8PA| >kR)gnʳo $cuB&zS"Pv1A;MZ+!#G;w.;;̙A =d^\Cꫯ0pu={D"HW^asxݻ7y  A]>|8,_TX}VQ b<#r\YZ^PH՟>mhi¥KϏ6nllX^})ۤ*utw?}ï|ؾM.mtz"+*Kz*M6)Z|!v։S -:esՑ#R|ZE X>E}AWPCiQӥ<1(يnviq9sNթԚ_‹|}G2\}MjMeeYD Y[Y+_zmx?}%CG*wLF{ܵ|xP`ddA@ET %%%!ƴJ;"7²dLN8ׅԠ'"GH 8q>@{xV߾}in1a,5IxDȸ;=sh,*V_k0(5*C\ؠ5ѷ0zȻm6*F73:Dnd sFsdN(9V6(u miXn-]UhU\k10܂joٲP[ot3:=jEϸ޾m3:#܅*F͇4ԡNa*@aNVLFeӞ=c5rIqWWktzQjMe]EI>ϟ*| !0O?Q⋖!` W([&$}Zi^J UTT ڃ"CB4C4(}̓% ăPpRFGfh Kq;mjۘHեKҬ!9btrxr / P @~0" ջ{;\KB~Ư4{-ͭ81cS2#ig9ܷ<+ǀ^\π O[`8cJFI˱ޢwT\MG[opeI$LC]N *jԋ2oo%F}Toyqx\>fg\mThSg\xg6hM{8BO%:2:H.׭ ܲFFcFe2خIeqFQ(ZJqF/[&h5 :}Zh v$+1X+ /7U" DZWW?;gwߓO>I7@9"$4N:%%eǎDƙ/ 5*!tWhф tx.V+~Κ5kȐ!SO=A^N:իW/3MҔ- Y|*Z{XE >1ab?#=xm;3#pg_-?HhgxryY/?֨թʴ"_|s,$BaPЏ"^(r w,Mf5 '9uF!O`\ʵ]\ HyȐDpxجn:lB=6 :D}a5Ӌ@lf}j6 wrXڣE`&/qyyy@$ooo؎vZ1?{13gΤ\a&/=^ӧ NBLfk쪬"kuM梃J l׭[7gPP[`AZZȑ#!>xUFX< ŏmfJDdL[|/]> 3k52ɏĥGZ뱉b&_]UK Xߘ>tdvNͿ;H9:NgQV&_^z{o %B{{_(ԋȶ1O,WoiyL=Y֮_/WǭZ9/ rO^d4gIe;Bl=e X7{I8NN[MVܤ rtylܙ6sR̤yRJ_lZ-SWNvcy>>nsSN/y̝1tpL|LТ@駟̷ݻo_+9@`f{D"A7uVQ%7N?zw R)5b{Fey*q3oe|U{>'TP yA5:y]p#3`Ҫ'NDGG:uǯH..TlNk6,PP2&DZcAӧOlZJC`ʦ&ŷgopkQ/RRޗL>~AF{qrrq#"ا`;ɤ2~%ņxD,؀=sJ '~...;'O:(6(ʸmgo?pАظ8$s]rлrⲓI8dⲱ֨Q3{z~ɒ%1mƌ%"j:-C,((_5Q\!蚐gςxȸqh pvw_?]W(C]mniΕEcf'v~~k$Z>j#fUU+o%0Cyx֪UF=`5;U $<ٓ&MIGCd>u9YLg:<Ʉ@ڒSzwü&vt ]bg VKֲ tۆʺm~~>BQ-Js]d\F[U^]VdӪfCiEɬP/q-yn a߲'TKc:}Rb2XbU99%%EzvASq5=֪*.䉆 Me uۚCHh:N`!ǎk"rAwqэL8 wh^G|]gU).* 5jWɌ 0(cqzC\JpW4&ML~p&A~^^^aQ; aÆ=쳤DN\۷oK?Z#jZY$c^^bbb <ŋW2sa]{i8;;?CB[744h .|ů+֎1~S'{}˶>P~'EL͙'.̐>|{gu߸/(}샍LtW2j~oo@|aO%zFUvy|@k&wK^}\tLie~^:&}¬YW+s|/s$mLladdU>{W}sfzp/ə!R^~îF/87{嬐pCXcBw봐 1))… iii{ j|rt:<ʂI5ۻ-+;wߣU?5e'70CT+EWUVdr;.Fn5$E:O}F'UkG>,--rwG~S͍5M2pHo^\[[QPPϊ :kݺu=.܈  2dƍhG%o `zػ`k+BO<ټ,FZPN8WXaw5!yA b1b` =lO?vv*) ,(xݥW䌍_5hRQm:wF|J _a= |Ǎ+޲Wܻ_i׾Ӌ#Qɩ*y^nwzяVF{DŽV\Jz%uϾ?,DD/~ 6$݊EOQ{劝$OO{K?ο55SOӨ7?gWШ+ZTwMrtRWfC?mdeߗFMYBN޶%eؔhr >,^}E7ژ AXlO?M6]Xч1 s;Xk$ą_$9CmZQO>_8p L0|l唇3SZØQ\:u Mlj{ ޽{:T]] 1 0?`LN %G]EY`(]0JJ%,`mȇF r%/WX0/qqq@ُ=:uٳ)EƑ k#נpָfΐA0kz=Xvj5:A4ZUܹgڳ[ФW_]ېkU<[xdϯ;ѩ5GTVWf!OCb뀜\֠Q3fL2ba]m]]M^g8P(g4eF<&T.JQ\NݫLqUmKlViݪt<- ed=–&5W]3jӬf*y]zNruu=qDP_ M --0~2e%Dt;?<V\暜awuq$YN @U4K#駟{=9k,??pXHfr44:T*At$Yl4 z1~A<}Ĉ#GDd<Ih6peL"s]p! leѩ&_h,;p@  Aihf 錌![hh(w "CjȚ3E3e*e #eҮ1zf \_v0\Nm,W0&qo/ym=Rl`\<7M;8:%.8fmkUBm}4hֻ 5J5ڵ -*'{7FhcU_ЙE9;RxY/,4J<}RQߢa*[@ePӕ͝vO~g#˗/kt>twwB?!>L׬Sr:47NѢuց?k֬YRZGE m@i̗^z' &AA ɾ$j H t2ڹsk^C)灟@m %fL"k4<hQhu&EƟ{9lƐ .***/^ OD|7`B+h0- {WmO yLƃo-H/+1Q4KнQ } udt-v^NLS>}̙-!!cSޢEPMNO)))T: R-`)ZFn Ѐѭǩ}z$ޗvc'ϑ+ty;yH>6Yѱw]Xw*xHC:;!g@F2 vƏos &XTM2ӠmŮ],Y5kVϞ=hWe4"!“n"rpp0 IU-4ɘl 5&8q>!IOq+++ V"eko%[*4 r4̶lRPP6I>R)1P&P0L(@uسgφ """fϞݷo_+bG e{b,%V}U]]Y2NdLnZ_^o;z{Z7➛G+X.zuK0|x/MҼnsnY$ L#/̞;jdOϨ7'Ww o0Sn'Ř|;?uB̹Q_bEW_~8}Ed&uAmryczY@wQ_,Jb1QWrI|y y"@xhs郜BHO?q555x@@ ӣis͈kYC3x,9b˫15&=8֔p`/?pCDP,eGTpAoiDVqu ȏ%<<]u-6\#ƤkRO>I̷p,Vio D V%ch U&V^gA iuzsCL2=; z\GctvvF%Ex,atޓm6G^U*cի$\>R`"Q{ :dL, 2CQ(Fڭ5Bg sZH[t 2??(̙׿&Lׯ "ErLqMZmVS'~(߀ɓgطoTTj]i[Ҥ<<ۋq҂ғ%ގ!ϊ !G.+P8Fym{P;ETUV~ݒs5}z1~OOKxJb7O))-6c}1ѝeTYy5r%N~F|1q;#ޭQ)m!g^+6˻ /O)))={};%$$P'FNeeeo69֭}?hO>$wڅf4zMvQ!//]tǎ=UV㳪 J{+\Ki.sf'q#qsͿmA=fۋ NaФ弣yxi i  \o>2ɁsQQLüpŋivذa7n;w.LӧC@;44Mj/KLqyؑǟ{?< (2t_rgV'VUW< iuSk%v;>XY9jHFlͱI-On}?Vm{/=lDBgi£9;gNxyx{y2^H`70S/x'nnh^yS'#Âszfߧꫯ:thѢE˖-c,NK(//_|s͛׽{kЃ,MJd IE_9.z꩒+Е:#ާOѣ'r@Sz4ʹx( nX+Z2h>n51 @|`AZ #ls Ϟ= G~Taa. IܺBdQJP]"LGMag񫟟6+5//~wh+V((( u,lতITO+n=(jѣGk]m 0> ‹6+iӊl%.^2is=eFF X脬+l-=<3^߳gOH`GRKQdA*ҚU22bvqqq`qP>(ۭ[[ {'O޼y3( yU0cڢhhuu@yy3'.vZƴ^GSysk4}ﺾLMqAk,h뙂w+VwX63Zɫϲy P]Ys-m3_n_9MnټA56<m^yoۤ7AnEn'{nkJR}B+ˍŹ\mEbZF ԕyׇ&s4im (ZYuu .+Y44装ϲB:Yp$Ȇ3/7l۶-фtؑ*޽*ZzE˥sA%QgJ60K+hFOm%'''>>~׮] M6A0`mmΕ*MyC̙3;vOA0C A2{0ʕ+333Q3BBB^KG&^Cɿ"ٚ4Ikspmihl{QN4 Κ578;oi\.G-ZiDDz3:z4EHV"}Pf)S(s\u]555`7|sŊ.f7>)N:|2cf ^u øTϳs:JY?z;vk \9.>Zg&C|9g=n!.'*F s 70~iy \ИF>+贠R:^G*٧ύvw5J,a02P3ݭG@T?GX8 ¯<Ѿ֮] uf+̊pZCfEaeٳn:t)SK y{^gggCwFU,< +W|w:V6xԸwA]ugPSllXL쑦TnŜF]v;m;:hLyrh {TWk7yT^)_- `ڴ{\ݬuIpxg:VнЩ3WgO7n\ٷȩrO[ǯ:^{5|>쳖h7on9::P&`lUMCzgtt.cӦM%ݻw :p ٳgW`P25,HZz"wҒW$Ły߅DFZ[QQa^ODZ4Lo{^ۧi Б)XǍ7`e˖=#ĂW 400y?kLK<пMM%Q2g@Qk;Ho QlcWwQT[dwM$$$BQiglޟ]DҤiPz{6?s`^HO ;w{ϹzL=ZeuG"$ڬvRj4 b5{-'Ma74DrU*1㓒f{xx%juofdZd,|S#٘ Sm?K ǏGEE?V+t5k^z'xbĈHݓ$q idEA{PǨ` /AWw$ʆ'ϋ&4PKDQ{H_s||s2AC_更4bdd$y}@'T3fL꫆Ah_侭H$vs;ݮ~[W**/,HٿU!EL ]bW?zajvAaAqQAj>R%?Nqa겯oUi2{xhG00J&ɷ]p.E6l6m$%/ wp[sѢEPYbcccbb@{{{CG9s P(Y^ SF%VQX?2)dÜ EVH:B O6:B"g iaWpqW#Wj-j1c{`0pqqU 7ϿdvΡO ܵ[iwk?3qu֔[*|0k[ާ8X޷v^7ڇU+ Gro7TE\-Cšij߿W  _-|DjugHmXqqc\kd::QOS*87ۢ|-7jër$YHcHklM7J窫ɴr-/"R3Dɷz ) x:YWfκB{A(!7t,"#C5)._)g(~҉!@=zcD"邂@ gC/_TUHZKش>>L Sfͦ;Ç Ӵpqi8)Ԝ0b™Qε\9O6-E|kr^KO~ i y?.>:H*rgg~Um߿>-kqڕYMtɡVKdz :#Թx2y[>k3kŒSkڿE}D{'99rB &iBcnNFq[hBSZ\2|~5k9s@-q#i)y'i"Pw k.\&i7:%^9c(oC !@W׿ٓuC-Jt)Ug$Jw89pׯ_7wmM˯ݲL]PQUrXNj)Xqi05}5PY+*ou;n[Um9Q!563NdIT\y20>6_ڸwj2\(mt&o_&pVVle?\8LeKOlBQeL(8Z '0C^GtSG$ٹe#@RZ͉'5  ME˦A\7o޷~KنΈ5,o$g> &.\#S۔07=xk0͖ 9P]JAޝm1BvԉLIIټysee%tǰ0;B0KP).wBjV_j ern].'%dC*6ou:M-`. F01OsΜp2N##7('PഊsX`MFu۶N:;zͮ ']PؙxqB`664Ư5fSjdXS V++.+YP>)Z+,, Q^^裏 t|aYVV;ϼ= .Q_~:)4+J_Z_SJD֢WoiyeƮA0%a}\;J-6mږ-[v 9'R$$$8r&(ETW(!˹Jƨfd@ 4˭[&%%*y .l7\p.tjZZx1̹=!\ #!tKiK-o1D}^kx p޶6o(FmX'馛@PYӃ8p,GPI)tM^w5_$"t(UUU6m2tya@݊šV~!~^l"$|gZ` }>XçTS7x^;DL-o iG.2pw4jYLM˜Ty trŋ _{J"]4n\gv|_?}SYmy]9]mW+ʪB<|ĔھF$yPnZg#3g@_ϝN'3~͛yJME]kAApZ#GEEi/UepPv@AƊ#奥 )hhRV˜$5hw,:R I߉GcM(1cW'Ohy>?yP( %]2m8'9w-fPRJ4񲾜5V푙9g}s*Fu`NS_D嚖8z"=<Űj⌧$ j }XwJf/jufs}t^5V}~gOa0ԠrSӨ٭WHH$e4qiJ#}_:Sk%%C6y.P.TFݥ* Iv8"R呑} EƵ^ak6wu NY{ ~6ڎ;֯_IW7lkT^g+V+,X`ܸq_}oKm-[y>sO?4iz~՗et`7(m̬Y<@NNرcg̘+@bO6K{^^^xx80cִBx:€C}pWXxxNc-wz~c5J^Hi0cN(;v@(nXWoϞ Sc0hY;C${`IIpv 4-X"Uxv^'-of'4DtN>Cnv1 Deؒ "7V~<["ɓ'|I3g8p Oj*0=h1Z['??o|~3 }P"QQQ.fvv6_4<%z{{/\v+P"+3S2X@RS>x#wUXZߟ#xKmO[w͌IK77gfj>[^L4Höc-6g.~KH<̢FU;; \{xwG;KN槰=b*Rvp୒g o޽K,;w~c$.c;+|y|b`4~ih}A!ٻw5\C|gwqGwr$a Tǟ$XbE޽rB^3榛nA (Iy9@Gkg_#Ni#/  HnۊkzGh L1$0 ~L?KdMҚ=B\0ϭ ZKLܥQ#qΌ}< =a! 4(&&S+)x¯Ԓں#vf[ʑo.^ݲ5JcOkle=ݲ2Rt}]ot{ʖUM כ-|aH\pe6L9W_E۸Ĵdr3_Jz϶3wp5[EG/ԥTȬ>i5χ;SU]K999?xuuKJJwuJ]qPgӡtNz+kWg&Oӧ?~ĉN333_{W]#v>9~Ϝ9aÆ#Gɮ]`-[`ȯ:ڿ1ن4dB| 5VV*(PzcN0-s~`Nw0Qq3gXWÚΞ&)O6K0x tngNea'** '^￟0aBZZaw}ʲҒYra^c>ux0_iLUQ 0&Xos[4Y nqgs2;1: a:SEʅ{uq7.g-snzea[:|IQ.LyߐKYYYxժU'Ő;0ऄWBL>y9,}thNDO$6Vr6Oc,Eng Kt&inyDhP*M p#$[+Ġ_~*04bFzw#2e ^ ]}ʤJlJn)Hr1jޅ!22 #ouoƢbB.q[Yh{:Zj-sN*&(<:AO^j+@<# W9IFdYो)^\\pGewߑyAW^}A[-[lN:W^|U~7ym۶c .\%Ҽ_.5LR)"aeHa:}OÇcJAޖ@MWRz{ :r5.S$ ELVx Q3lttXψ!>-Xt}O +кLy??/Ajkw xс|?Hy%LSKh1\_8E0HY]R?Xݢuz&dqwAdnRä+`?;5:^xᡇ:s̗_~wAhIw?X'?҃t08/n_Ν7MpdyBZ:O_ϰMש59{~ޞ^|x^R\$pPr蜠А 3N)H/o6EÍHъN#tqa@qɤ$@APyM].'1{㒑Rz[MCfy0!7M[|׮? nkШnHZZM˗ i|-FS\8'nɊ~5CR{t^>z>wjOm}#oig7Q1^n79|ˌwISĆ:%N&We&)1\N7nSVVp FZ-0q'q&H;,Lj4d(7GZ,YGSRݍpX1 (=@ Bucl dPO(\d1ݻzrCR(+g+NVmӮ̵wΫ42GqCS'HU5P0Ff?rPJjʍEaE?@I(x yy=zDG z܋>\paddСCᶊiJċDE{FI.iVF^:o`<=5ZN hQQ*գGLJ՗ ^7}ClVJ4W[5g- @xht^tWH5 J/y),29(7r+.5Lr[}R6RԎ=zwر\oIɮFI!FI( !o$yxj4xi/Wpo/չƫbCk[`5MF8RsG^f{Qt27S.4f8S5[J6}?oǃsRiKCLUW(q =( Sc=yyyP(s0dÅ6lnQq(駟-ZCOQQQSyr24(8z>z_O{  Yyf/XyuW0rrmv뀄APǻR1O1tj=tT$I*/Lc͗i 2i$#@~eѥIUgP2l`͚5bccIW%ꫯWuXmGM ǧˆ^=gD:` Np͹Kg'Mf53ϕ4F䬪JlV*vfwk_~x~K.CR(26[ӷHLʖ[m6Urסh*0\q(YBOV %uU 5?c~33g@h%`@Zj]vH八j~km]H~!{r+/E^:WyZafN8! N=v:&CVRKIƖHtrss0(ӦMqaa!%Aapp @%Mj'$NlMd39jLCJrҢ*qȬS4KRj\n u8Mഺnx*EXzlQ?EtD”U6;D`0&ȨM+_/Q\~Mi%>woJ#:ZUUa=Op>uT0Tq&/s[o'|覸z蔗0aQnJ_UhTx>~fz+{qڙ像U$?dq]ڟ+dtqXfɜ'%ZDkU"qwTN7@YIMZS]h081qr0GP^QV:Gh4a Pt8^^E۷l6ʊ +-*Xҷm 3cc.&NrɁC\܈.B{cDqg0h tĬY vMs=I|f0i b[!Vm NGMu"vȡcgR^2V)&u \g܁q2ߚçKzdž7d?ZbE*Xzlmrm۟7>qw-Y7?vv]+,(H?tGJƘdY^^ 8G`icyOxP/--;1[n8p =Lђ+K\t:xW(U[0ǜ6c-*?S3&r|2Q]崸6fa ɼ⺣fo"blNXKv%!nnB!WE׮ߵ#]$ܟ#6K}$r^?sVueL.>{h\lY+XYQ҅ʆr@1zb1}xVxdDqao?u򤗷5e`Ce>rYfLuiՔ.)LhoW*++ȑ AQQ\\\tt48>zhMU N VΥT~uRoccIC≶H<.[ >W6wjd:ʚ:ƭZ \f0`=&Mo ڤ^nXg3k.uGvi']6TqMS);`yó:5ƍ~o11q3//722O)( mR*P AȰM0dKz) 0@}H=qF\_BRjR)C'N VQu.# &(pmV%hnC.v6cȸ}``J V'cqJZo["L'Ou}_TɤB ?h%-Sӥ2UJE]m]rGz&$%i@LKCe//-Ur U2<"⣷߹{6O*ev-*&@+ =<='fxZ t[@5;0tѕ2{}}}}#F@F=x`hh(Π0TlJCD3*p^1ٞ &"r,iG _]5?;12 oi1u#n eYeRJ")묳j,\J bg.pI:I̘\0S{ \mfܧTEc0jN:frM{ ("p JP6\we~ #ۧOHP1Q4`B?xo:uE, WKpqNZ?:qH4,iԢG!O lHFFI+`00*yC^f)$ y*["|+8_eL^΅äjqh9) NTk0=<(dS&B?5g:O'kJeFlgR'1p߰0bQ-j{%62adPi@7oq`@- OڵKӍ?P_|c=Λ JNґ)+^ _KD=)xWek<|VOI?71֐~j1-# jC8d>=b#Ȅm3*V4Q ia[@/7#4 tLopq$R߸~}Rrʎ[j!+80:6a'u,)|˃q1!P+Wx[nk׮MLL|/_~nٲuw[y侟tNK/py9u?\bT#և3d F{5{FEGs}QH&TbuK F?@*mfn  l6kiIJgKFsK>lj.NY[qӞ-|ξ23iq{CF7Nzqq!.LR1Yl۶7裏RRRxGCZ۰a̙37[pw &P f HiҀTm.đ3%ENor V). <@(9d`NDbwf\<|6 i%7kzVZxJHf7D8}UrIwb JR_hgn7 j8m6q֛}*dҎ5kb؀YN ŗGcd)yi8R캆" Ô^RR‡," p۳gcN2eРAwy͛:0ٷoP}%Zoko'ڭl)vh{+xlnQ_ߞui>?TRgG7ᨣ4`#U-,aA`ڶ ^UEydT4O0bD.SL‚` Hy{%55*RDf4ʤ2O .t:*L}IѪ sJKQ>HsAacbb/$?"8%~~~(v?)0,M. ठ0m6N(.L{L6s.*פ Cz+%2&$̖ mVWMiw2՚G3 a)w7<9jiY,1ER%R0B) > zH1uw~}2IBTXݑx0"n{bh=p=cC4yvQPRu"N djgٵ"n(E(Kk|tR =Y]aJPxX e>}v,'3aϞ=yyy,X0{e˖ۘIhwۢ)I%[nq*_7yJu2O> &IDRߤ;t]mM_BBRyW"&H& iv`[~VXJK oˤRCfJKJsssU V[TTPmMU%΢B >H]ve4Ya]"mo|(@'W >> Ձjn݊z233IIIQFF̙CV!>j4/&S{`rrQիj݂:H6.م.l]ϗ6eTZe#o{GN&XRIĈuyӷM sr*]"ucn;S"P0 Ԟn-%k:dq OUʛYٱ/E+̳Ky;{&54uxN&h9kTBZyd/YOilBg(ѣG!OTX?HcQ@N #-Z{bߧ9(BIvevpe{HĢ.BG@WĴdbX*2 <B߅GylqidMJր[w8<x@MLjl+aVg=c=&sV_[)=.-RuvSBus^:9.Hi|=w{f Kmu?/?F_3 #RI#SmSݬO N[$s %H,Q{GCC{|{N%]3S9D'fV1mEe[! tAZ*2\,\pDŴ39y=zۡ^ B2k֬>^?gΜ7n&*IEYnXÎov:k\֧A˳ e :h ;դC.y ӭPPطJ̸Jvn]M}.#=4:2}vRVh-P p6&.OWߢ+kKoVU[F6 ED &тk]i$̐˗·zA+A2m_n3L;~>;^]n璗}O?q@*9G3jS'u5DvKE+Y)zyq1TfF@RuMMM^VMDit:Y 5]蚟6 oΝ"Yb7tåu{キQpJ1HV p ӑUWWUPP֪ 2Љ* C4bkC,w,(kn؍`hqrtiIA~E%&E";C"C}u .Vgl%!+DHIP{QB!*O`k}mtVm0 ͯ*cA.ZBfݻ5Ν;7h)׏BuK|GEAH-HưXq.:,>\n/ P©fp`|oZ~< G@B&{ilv6>HPow9nYV#X\44s6)]vaי5mAj.ዐHQlP~1׏5_˗cdxC$Bb@8p:%ʓ,*inm(wt؋N#{ ݧu9\ZV育ݽz^xPmmmv4b|59NϽv=VUQ&ae7X?.^-ɩ}o={ŲeO?h`V*wq3v^$KC;vH@HsaiVp.yEEXY|}}Xnv'8-1\&P RRRPN6,5q z){H(j́R&ĜÝ`6-!6]j6+ #vZ]zH("P*R(Q;[gvZ,N(l^: TRKf6¯T H"6?e[+B[(W"6jUpxi8%S:Mt`hDb! ـA\-m>1j۶m;qDll,JbkmsD x zbb"-))u֬, %B;nri y7k*}=Z^͌f_xble/Z3 |QӃS8!:tHf5n,?oXЁ̔~QQl{岟>WXDIJ￯L@]zFr{Q BG^D؆*{HHh3:Cu$ 8nQ7DnAeBxm0*Pg0=M, -QIqAd25q4m젼W,vܢ Z]JK#G7yGſu5^A~rvrHaX}/*7x8[fCKy/1F!:xtsk z ?).2To*HjKmFknI? Cl.-VRP~ 蓻9wCmz!|=Q&Su: .lݺ'HDLΝ;4Ȥi0f̘ 6n/((`n5kZr馫P|}i:u>4„ %yvY6e!֜P&d sP &yn)Y_Rmꫯ}]c \rɒ%@0R f%|)4yuN˕w8]K~X դח͸SVVVz^PrL屢R(d}zX8V)>^>z/Rq v.+5^,"y<ن #+TP8מ/KBI3ya6>}~(LC:s PoѠANW(0Y7]ԵٴTsSrqL+#GCЌU]]E!UT{zj89= )** bM&/ K~Ǐa8.ä#&A555!Qr.WJ.Lqt@={._fgώ8x^Go3)C!5In%BL&E3gݸyOO:h"@k5ن"FMqP<);*ROjCϋDb\*HTJRe@Az憉C˫ -~.)N$WNO Sޣl/B0朦K)Ve}KKK### (B}CRi+?|jj*mbjAfnKFoyl-Bc6+9BC 矱A~~@GOxͲ36;;+*jE|̌=}ZЬojˊ $JKl8;0$UrIa?LHHK/MF҂ށD 7h ~\ɓrq2 ֥kܰ+:?Oɐ C+0dKB*G,)rMΈ Ɔn*]d~TQ֪VUΙ2R.YRU@H&^fLԅTUU7r^xqځpҚ.>+f~I! Yǖ[ Mt C𧯯/jE Op .񫵘3fXbE޽Q|Q4 MtͰGv&TZ*blX|ǠhCf C͆MoJ4vVir?/Z%OMN, 1N}42+nFPj rSRiRQ^ y2@] 04"( Ȇ݉J$'qnl㤤FW{Dn})܃Dlص@2,2R(9p=)}CCЕ( m9_ p lذas1nŕ9 IL(0ܓ6u,'%T7?+ %+;-}RUkpΌ"Ϡ^H{(N#cn+pP%zaJ*܈..L4^p1]fffdddEE/H>$yNWgH.hk}{sCJoI[.3JB,ʹɓdɒB% r\Y-6ж+ h%yv$us.FZ*_٭ֶ=3?:6+-6 [̖+W] ` cxL2a '@;-HC]\RCr 0L AyB>ըV&V;F(8-\ +cJ9aUK7,B%ϐ+.bܞ3>biiOoDg܎km=7͙J0GjÎ\yo=y;7r;)yϞ =h:;,0ѥ#0;99yʕ#bXtiii/6i7n>@{4$Adf e~*L F#rI. nf'vʴ?_?:U$EudjmZX&KnDs0%!%dMz8 }6:W1 [:V r,{092ÍmZz 9zD 0r1_e']vn3ս+)vN6%nJs}Wg/2ܩyK&|v& 3̥Hpd'MZ/0]0iF!k֬A Ы@ٳ禛npA{uw}\uNb֫!RrN.Je> @?qEw+ZݟOSO V 5VIyO ?)rN|eѿ׉O?r7@ȴl9Aô4xn(}7&Z®[qĢD\Fڛa1(/;;TcGP('HD;OAL0m& ~Pۺ=Q;A@B|,6Ҋb%12ffAUUAU$?*r߹+HFE-'.)p2ߌB1OlQ՘F~ ^-_!?(ܛ-feedR3dtL+.$L@ڭ3pM0I01!ǃ)]y J7.&=Ѵpم{*!>g(g'̿f|vF<1 $\C* -ޮFݹQ M~"$.uEkJrNJZ,:E]xL3GmRB.-- +P’0L~Ԅ/>\뮃7xaY0Ftzr^;P߫Wwη`C}ah.nb[sk3tRk5#-/wwp^p xͫj7ܻS׏=~8t^^^^__?iҤn=o߱2WvR+qtA| lЎҪ흎` mTJYŔ`64R/몷2,v'Q"BE&254荏x| )clCJ@l&PgMVUν; b̓(,b '$R f a3220'2{D)ؚ;wUJW`>cBBBW)p̰ETSW5gϝݵoW )XhI鲦&NV zH>x;q϶}V_Xv V.\riDh"ǽm6]"446$& }JЋIdI@{6)q?<{&%%8,Z$HM_hN(1 =u& :X,Ҩ'$RX*+2ij,Pj%v#nۃzMP8Tt<6??XԄ$񤷙& D"#Te%+7-5֨eD08c ՠ1"b2X,_|1>>~ѢE8i 﫪@|,\ρJJJ=Am1[|MieRق =Pr0Ze &,=9n8`Rtd#Ǐ+g,P$2aqb<Ϛ5݃4+W+5aNs asc$"XJ%bBNى? BBkge=*@? 7Amt~ '׌&%+%xO @߀9N_f& KnYYY֭Sànᆞ4iT__aA@OiR Kā`#/`ϗ K_l~)'ėS"ygk )_!`&"'.pY6yyy9X}'`>4 K1Hꌌ Պa[(=589)0]? Fb|"a93lJɥ)B#Тy!wᐑ09]axe!X ,3&P!-벺 ^mӑa~|䙋.fY(;e3G?6͖\x]@\FƗ|?!=o:m|3ئmT!5 >W}E&N#2n.bm;f FYUo޼4XB 4x`}+#rGk%GUjq{ qb2jiV({dVJt@!&:oǎd_5u'O_6H1 VbA{vt3 =%s{ޝG%&ϷcdXz4IdTtrtMDl*23gNMMĉcc%w2/! 6i0^]'z{  >KKKAw#Lw.p!ݸX ~+!uecxf Nu֗6q?wC@L\%vn¯X#qzj7.NV-9w֩L0:/#9Q/ (L /c94(VwttpS>p{ed$;|,>1~׶]ПYg4@d^n\y"I_~뮛W?!&Lי;n^2.gӖߴĩiF^ΘQ;G̃瞛{n`Z-JE_C&WW)* cw b^uۛ)@ E"5"ù}1=rEh\Qq>33k`#\?ϐSG$FG$i#y/|}\*kD51-F7iT[B7[cƠ CfDFXl?I&^k2ZT*!TQ\ \&  8pff 0shBKD,B^Er7Á%2x[ARV_1 f.V\>\1` ygښ 1$K󺺖`& asxɉ5mlɱ[*(eRѠm.{|Je[[`OOgpxvFSvĄLцi4"̢kI䞀>%ĕ5JCH&>9,NW)[Ǐ K> bB̥,L8}! MĞg<1,d|x`NQy"P((sk1˄!0X֭[paVZ0#Ga.!b>))kVQ1D"^vĢ9װ0{˫m^<._v,sR j+[rҖfϙ3 k$^Xc+rrk5?RtKzݽkur^OUڈ2>O&$ʕ2`$XOjϞ=;ӓe# #r?otGE1YPXt9[F bŶ|!2a"~^ VP6ZlFu1 GuA0{RO':2aiaH-1ap6leis-yx䗼%2cy1NDA2\+IVlr\@ 6vEkIOy eo'OQlNHH@nU^]E ӕ8 =RJGOWv0 Kţ€+$ԴqȻhJ&f\q[[>nr`rm>5“A^l2|Xw s2hshGOQ& Ͳ/Y/sK.rUJHl9@ \A5ʨ7ۛd05=hg3, NsX֨z1O?}a`yO+Ʉ^ 2Be!|Ξ St(C |v&W> w3! cJ (p ?@ e 9~Ag!33;;;| UJW ӭ*f'[>q:/[{H-f cJVd8z^"^LhUJQL&S{{;0(WP{MB )@'Y0*)Q:BxBb7,{>cj'/RgA(>ܓC@Ȗي1hA $7B GEu0ׅ1gΜ#G`{ѹ:q7xtyqŤ+=tRUTV ƗL*{GWŜ2iJٲzx_ ^Mx /AX-96#E`G8qXmh~17kjj;d y H>Oש_k XjI4kGSAY%ө/FyG0&/,Cp+:4 $'%$9s^o #W3ՃѠsFO$F ˠŝ-[<.;n:* .G.hl ׼*&Uztm~>vxl =5GwYEIb֎VRHDY1&I`G\s56m"/~=,jIIc $<o/aRh|/)Q]0<Gv"< V+-L1aC-2l&X1YZZ:x_x[n[by+#bd$pXl:~tEuíR FЩ܅q^[WNjZπvs[.0шIF6yatŭV2ID'9-% Sͭ"ec`<|Js2FVW6}]&Sn2}ިa[MvT#]cD]Nʀt؝⺧Xwt'OnfcIQ]~W^bRڷJRW):l-nd7jV#^wֿ*M0+l1k5MJ1c#BDn2رcǒ%KoQ_}*`',R2H%g(;xTn:$TVc'~5Ь5ɺ2i}Cq>ÿxNaz|h܃dap e/^Y&K\<6! Kl-uw];}Yb1TjCނހ="D[P bXk?[]"md-PrǢ&fQ`, J$ f*H,r9]%r@ݙ1w) %l8\r:#oS`scԙS5[*" =N6Ka盶90fvrBӡT+]NT*A~R`J/IaW0ȶT"Vrm #O&&:;B@%n?69sژp{S ,HdtJ%"IuT4E~]_Aw{lVPQ0M-QŤBIuhHv/eg~ӆ憙SgN2مམ9}&0#'L6–UްↃ.tV\(,]nXDOlˡ`Bx!L&SEEnY /ŋI"p9+/cl4MeNJbPr;^[mLb#qmP>%qcM"nȢgΜ1MP?~ZcL$ON^k0xWgA3y8NMA_[_|p_ޭIp tc^)udXHgykB]v͛7/33̜OuU|O/䄱Ʀ{}O~9 @כ/ERq`L':m[gK_?a0郁oY9cތ̀ߜ1cs'N'VfN3vTG8&w輾_! (2FTvWk9y9f:uTT6tqJ .%VHW 0ޓ D9s&wuF Gϟ??)) `(ɞC1i u3o_%2|lB`" Hj˯9ܼisTXX{6=z |~7յKb~Ͽ\XXa+mtC4so0Cy'{UZcQJb RE &铧R^N$FL-ߜON\!?!?7/_'rmftF7{do7/*#UhA,RLvۛd{1C)&qMCErs'l\]]  ̩xaʥ â=}u~7g/dM~~_Ǡk aF*|w}ĢW(ts}'W]-)n9' @@LmԂ4Vד' G 6l0o<,ʈ0f\{Oر,|H(Fݭ]_eR^hCჅIDv3<-C9<x F36v:nM[(-Gd7"NfR$U_x\'6[$_>_[g` Y?Oy+H8B{CG&IuT,&#u8XxqCڊ+3u/>ZQzY?uq/8 wW5G~|I_[h -oo{&s==b";MNnO[}o_ly8_wX[,h^|)\c]B /oZǾrvn٫R,ЯUMlB92T"-9VRXQF-&$F)S81>3,rUUҶS~-x(!IW+Q! >I]Q3Ȕ1L "hE"0n Ig8i#H,C\e}ɲ\M MLJэ6J[}syPOL?H!ƙζSÆd,DC'S,8!3.dI9 Lz5k #84#ic[g3ZQʫ_gZEMbrzO4=nO_*&Jv䩖R*䧃n칦 U#2WLz<{nVGQun7rwml7qښP^*k?G P'HP 'ϗ']&(`?ڶOi9M̹֒3gϨv[)FsE # !lZ`x|]Q8KA$y!Ljb];{ =Z@,755.b&A$(j6liqQb'Pf̞վ؝?%qTuq?co_eͺ! 'iuqgfF8F#p8:twl ԩS|f:sL8@ PVzfKbbTɺ)XJ*kZ0y" KJUP;pg >+E2?6`wkX`(}Ŀ>yϳ =HTkh(;MIbB|&~ekF ilBXBt!"q :0YR9UFk T cQ@OmGw'k_l֐`-E `z" @"bE6P`Z, NUb٫$KnZ/e!_Hd>ÿ_>wꂨ]tÁtZʈd]R~ۣ6|kרu2!+!p"ho9w)zMX)hɱX̠ޢ%hNW" ;v^{WE4*3ҵ360{7q+(rKA1KG6_?ihapX>2|>-ZoKYePd/\ 3 k(KLĄc'0N,|MbIruw?^qfMjE֐$߽hܲ]C5 ӹ}={D#1b,HtÂD̛yuTOw̍?<+M f6Ԃy*'J  Yɚ %yR|7=7"m{Cn]F #hޞK,nCanD$gDn70o䝁GJOM5hTq{t bTUG|=Th|dF?k#L_uG$/2kV-{ْ^_9] }#c:j`~oUA+۷ M@*+@'3~nY7tSZZ/CDh`y~Wa7hqv_R J b0~o[G0, n$;;Q ^O59$:\dB;H0NFᗯl߭I^aD/%ƛWBCPAb'ephYPjΝ+~z;]WB1[`!NQx^(21 Qq69U!jJU+0|mGP14>>cz#'ǫWF%zzwns %EޯœǎF, E%yii q(GwmSS`Kx4ct`2Z0b2k}H$ɏ7N C|C_~:D93lSN]|hvena=>FHZ"RIDz\KZgBѣ-qR^"VwbaVU"( OjtSKөSz>-1M!W ss-&1t%J7%FE{l7z#jm]])p-׳{w>( __kMm /ojn*9\+':/²X,Se'G?{ol~ i6"-=`0 wtߘ1qŻ>N'ӧ755ukS[[p8z{Х1TUWAQV| s0 ``h$;1Q`)~H" byNt!hyk%|bbPd& fgw}r访ϵ5"ܣ$2e03>H%bVf fa/buhd2}c_jljx䕻 oU]7wa?SU+oj7y,^\bù-ϗhE߯=BIAP'.VӈcF%2X$,X)3<6w(7я{Suu,[5z #??}]>[o5#-wloo_#?ԯ*-+-Py?*VJH &pU+)S Rs1zx8@IЈ#>ttWWW㴴)}$Vv`CF3~;c}Lf¨1A^Pސ z7?2(0Ћ̡B\:rV{~iIDOk+j'qBslU0]tev"߱-RS _4t)@O/Lj`YÏA- ˿f}o4PxfԨ(լ>݊8S|jސvǪz6>YvbC׊?~ЄTŗx{?_y~fL%{ǎR\0{W=ˇ6&--C;2B(=[j6 ЈIhD I>_5k,wygrrUaE&TC_`߃U Q 4S]kT8'hdND>D##jhY:;UHGm'H1) MFR8:2 /SŒL"9sA0 ;8|g6z>0F3EH2R&lZD}v2Qtzkk>6mYq _jkS OV[jUͱz֭<璅IUVVVTT8p`?:r$]$06g"H5A c@s/}c:jY*WGdFmtފG*fEԮr-'zOnvSZBcZvx,'jcXo~ZL7v̼QR E :*^7K(H##'by Ѱm%mzΤ2t8~qU"^&+.\Wz*UquRB<,h݈*W5DB\ɌV4*XLwsdCtqqիѣn=P7 ,kAAf 4.}/I}sX*.yu$`iTd ?ϫ=W~ƌ##/αf0J8n4ku:::mqa)\V (PEU %E"4Ao=9)sB'TopmxuQϨļV .J4-w<䋯gh#X.6YVV6~eu6nHt|Hbo__j}85ʛn-^M?YĴo9+YijxGJrZoG捾uUljmo^6XgЯX?2:c珙qonu~HWž'i{bbe1^e:9-u|rgij zTh;%h>F--Ng~vF h\BMy|) I>-1@;DI=c=ɓ'% &] c8C%@L$?v:gd|rVB*?zaZ`".| /t WRX`y}$EP8|"{.:{eH»b5 Y.=U2 x([;17^A=GYydÖ,1u#4d2!>b$`)N0 S]"4cxZ֛n_ضOh0xd29 s jZ">B,Y,q10t;-+{wtvRɤ>j$drѨɾe$ XUkUBE!_^ S&)!($CZ>'x.vL!U,7﷝ Cy uQ HܓʌQ2 ̙믿{YYY, DAb'$WT\eR^H܌!w*=v#Q#?2W$-kQW-=ڞ x,gvz>Dxi6rJbr4E1 ͈Q|ѺOv\0U$'/\+zц|`jwvvbBNa-MLL*-;!i zCi  q D@ <ΖT,[]2ɺdvRvjf&6 9 8ZD"Lfé]ԛGId2 /hfIJi3HLaRF59l;:gACWtWؠ?E$:m.0[.'w(AxoRBuȠ\J%&&Ο?Νo8nyؽev4*A F5n\􀈞$biI9\ɗJ&651N(ҰBeH"E2Zn0!wڍOq9OBZ"\GЁB"3?]0}BмC3(KXw̹ʀ.F2PA]=T!`NhcFKUV׸^壁OF&)9߬_;bXAߪaFN'&߱l9=^[:ݘ[sʟJO's2!vǦ oW7 ~O(F) b}.}֦J)C~:u-a{pT 4 \9Um~9lln۴ͤ\uFb;0FoŀnИ$2jpo]w8g{ۙMegT`!g}>J()9:VF 2sXn<''PɁm۶=RbkDu{{; Wp eWiM2a#G< Z+gƶ`ve2z\Rv=<;jeISK*4|IN?hq5-Rن%U8M|7&y fOJ`ZWSWC딚ږԤk[Vt3]*SyaPǸ1J9B467YXi ,ڠ3Y, ,u4b^mVWWwzGE2=nC_LA$Lt#ލ!cj+3O{>Ef nAtPRn2b% M} )#V 5L"^Q0.i0ȠHC&$g姰b B&kb ]'D]@1@Q:wtt pNOҦ7WF>qdl@#G~Wb =nB ᫌ}yE̫|yE>|6[||E!gA 6ǝ!*.>'ω!zu_P.3XD{=@0:bXbԣD`~ŋp7|sQjllD9]B7}̽% bgmjgT΅)uu N!&S8X j7+S}LGrl/RaD\58>{ #5Z {Xp@l^GDK:r?{A]s"𶄦[xD|ed,Mzmlͻ>cn귎7N λy{F_ ǷLMvy0+N2N$NQgN>gYzgcRQL144MmVd=gNãMP,y씔d/(Pn%}>2>zuvV6ʤsRfŀHL4CgQ|%-"ƍ{Ј IKt1l*' WRHG.ZUa1&ܩ!Z톉(UG}Fƪ\.k􄙱cN^N>g8rLX9!k봥3b8;/*,nXs#eu97WQ8 ?A4샜.g[{[tn^tR%ˤ=D<811Hf[`@J^!&X!AT*V}g>OYk[(5S@զF͉۸G_xH٧NIY3&r~)NE%nJIϨ'J)!],:T4fTdZ&dE}d#A6|R_c XоWrinn J{,ٰӓǞF rrϙ<(N2bA,,PAhc]Ȉ8ެ5hkjUMύ0KdrVʞsM7׷[5:l GCAʠ mP̆ &1GUxx8TƷz+...;;GY hu!62ɸb-چ?=~SLuTykD&enk Vh..^ⴱL>I>Hcn?NenZ{xE&`5VBzXOUKЦ'JU҅H Z}?B3<6$>iKrL $XM)(""`AKK˻O%5D:m^:/Kyb5_hV>3Cƅ P/EZB2"kHUQukNVywMKI6!R/#7%=xnk[,:P]SiĒ1<8(f*>^r6HQfy$JNo' vQRRaYcfNmUfr_KNNmtر_)߷*!+nAb2X/n/kt8\vYS+ô)^u9tvY={h+Rf8L`CI-{(@zVAtQ&}Mv"b ,=fj zH)˧Lcw7{<{SNԑctyRCqIg}s[twvy ('R`x)Tg%V}%Ymq2LnJgTKoW*uLJ歛lXg'zm_^Ǟy,59hK]r+HKN5}ְdMc b=$?sAغ{qÍaI_ ̠d1P~<-wbp ``nqN {DNHxDwt~!򥴾B5\CW4hjj={O<P%G2YCzͭ2]N&H-t#qxoFp\-*8bSRUhpc!8b r웾Y>q)| /5㬳:䶝V]eeL˼!9NHņ{.ۡ$_%% X2c2H졫 ԥ.YW 0)Q98HvN[$*!g;O"؇JwBКxp c+t}ЖU36*bR~1bx U|`A)FzZe ֓_ZZ}$`BCP!i))%o>kb4Ѽ*dg=A:\?m;h.*elONzG:xEF;{$]Cr/=::0$ݝjoi/;VMGG%HvgYqـLWɄ+[t-770^_0Hjj";~/QZZ/NEuZBv2 f駶V+OQf۱:chjn;Xl_̔|oX^l*uX.J;kj4Bv9mS|cz^{BG-?u3+#h~А;nXW_iu߮m6pi=:7葸$.rC kܸqO?3<#*n`ŊhKGө뎘J$ -ެ?Xaey'32,lKf5d(&f`(ɻɤ_؛-AQz ~e^:1=;Gl` !S2,o3{ "SQ}}=Vx(i>Yh!Rhr삀e4 6l/&C6o޼hѢJ{aMkFV4be х P/-s$d5q73fN]L?qM<'ݻ@r#q9Z^.qQiWKj.d4ʞp\a=^XqڣG@'aI;ڝaAɠ+4A!:Rts{t-nG;|.4F#FOX,W_q'蹳A_X3=ev%nk}=)920ܜ`> LR#R])_{?Y/sc@.&X8#{&AjXswqY[U&6TkFJLJ1Bt,t F.M<;2C!B]-- 'r+kwmVXcf/FGOgnF21~cH$V  CCCTRRq;x533 [ۏd5%%HeȅUbrakw|崹l7ZQv ZZKrG>84(>r-U}4%@u:)g;)."r.!.~D߮\bk*p֎NɈbN".tA$UJNvmvw9'uZ+cjmpzFWPN] LA$"')ꝬBno,$ĉND opppg!v?~`Nfj-h3{;I|~IWJK5)yR#td[Xzɼ%J%ܓ-XvɅs*!?zqHtcC4lAfM?^ו_CaB$O_ADWC3J9lmnWXT舙rն(`{¬xɻ87t1utWX~lLvӭ U<]lΔP1|W)ߧqرqqq|tLGeD,ZD _o&唫iI\w9)mNK]e6k[)9#$29#u,. VQj舸=c刉R{4Ӵ%(m=\xG.X^ң 0Riƍh)*&PT*atQXȪd1j]YQGT_nIBDOޜAExrI+҃'[ۆmDHdR[˥] v;YjcarO%y D&H~B3RP}}="L={O#._?Ƣpg#@ʏ; 78GA?hN'~%=ȦK?J$xy8*QNAl]Lb͓K-IY֍3QԣGήΓFI1,9+%+:::<,7G6O!MMMJl/^\]] ^W_-Z/'I;uTrKm". P*AwOں͝N$#T<'δqQfB>4s Ql?iEjʼ fImPcPJP(;g[ϥn<$;0nbjEEEq͚5K&);NA_=99yŊUUU;#:ZZO8;ǨeH'Rrj&Ӊ*\=Ep$pKoYJ@yC)֑b̈́ & Ր G|y睻wΝ;xZZ̙3H!aVV}3VŭժǏJw [VGGEDB9D٠/aTdǨHq.3`NKH K]VNvbTPMp719n2\ExT8kjjON1nZQQg"vر~o?';%mZϫW]PhHd=M+_gB5'Jhӓ2ν;ˋ[Z[#4$8f|\|rBrTdTpG<Q`8)qg3233,X@III7o=ztxx8J1٩\jFv%8HrN MR!:'/~_oK?DY{Cje&H[]NURȎ q%q;XgyUx૔ˀW ȺLh0]g!Yt3ۿ yQFeee.\ rcQFJ<Ę~衍hWIL)xHpPpJRAoȮnlj<2`5#Ԩ5՛pv &H w4i>$Q*E| n}>mpOR*ڬ u.ßO YiXHa;koSJA=~:6+D:! .J ny/UR9/U@tsrFv'GqG+s9<F M`'Q ZB06m?~<='~YYe0eG?yx<^ʻtɷo9UF)x5CG@4` %ళ,{R9F&/FnaT٥nH*m޽{ԩbc~ĉ>hjjlKsQ@kmDb vH.#C,&i_ +MEgc"{`l'^jjqEkuU[PUJ!pYjg 9 d;eeЃy&1.k%:|R%daֈa)ު*VZ^^~6áCNq*4Tk2οbז# !Qc億.1@rP'?L?--X_7púu͛'BQ;s0,!?M^q}R6/3)u]h%Ni f^sC7N{=w,]t g3N1R\)1ʳ^:kLB՗dm8x H´lܸ1;;;77MD0 󙕕E,KTT=iPOOGmL2b1LP @)HvF9eDyT0iҤ;w^{x O6?P%&2]b`>FE mŝ)7/moa1)p}+r͎?xsdb2 dCNOކp7QbUBJ 3_wV2\SZR|,ZYO$!DȽ77ԉ16}RFNؤA666_=P͜2'XV]w_JUO7^r%G>y.eh$iFֳJ0X*EIg %%%ZNJX K* 0b'}~f3AvhƮe/Q%u',D/&eI{CP^Lmx#%ixg+FzG"aZɴѩ ֪1`knذl6!?&:&񘔱!  njMIGx"21ʅ?VoP%oJA/~ԗ^zIPȏ4cƌ'|rʕsc+1X@pjhH(3k}-FW JCw[;$1*w_^]]נg2yHiwArƀ!``R,L+R}n֤܈p}aiEU(mbii Ғ %&%ٳj;ttAN:p@tt4JT壮—O>RZ|)GBy(@#{Mpq ehpNe> t$+m۶{A">/UUU);;;g ܧ~N fGyG|7+;Ql'kiw >$Rd;)97gusvtyS`5e<&S8s{=ş,PL'G;NUdAJ\WhLapy ycl6&FHScYY֗*Z Ǎ1+VAKğh` :xTҧ~g @ Opjkl.[!8G_zxsK{ϝu7N4P 4I? z}[Hۖ][j3+{s~Q]"b9s~_Ȁ6׿522T]LZP7}zxablTɟ["`QdfneN!m!d:xTG.Zb(eu)V[m.onQ)Q3ƏJ`V:V'5coa_nD:v„ 6㙙K,4𲲲2::ZP%8 F3qmT :#b^T\d2{-^YN&suk&j`diC!|s>:5ǻo}[ǎ%obTZ4I2Ĺo~; )P}{dg'N@^ˊWwÆ g}6CHT[z5^r ouYK/w(`䧟~ ų0믩+8p @#kr% cRX}S??3<pB!uVX?W]uӇ%ٙtЁ{vL0OMNpهI I;vHINĄqcqGuun/yknmvKT 8IRKHYTp:zNq=5$&Dhn|B%Kw%Ɨ'455;V}')%B] of$ˌ<ةvQj8a=+Ϲc./3yPӞ։ H zFh{_DWҘfS%X6w]vN/{LʮNUp4,4,//nEDD=HuV,..Z ;~x|||VVF&Y4|kzSN4'|ia"%a v Rn J'[o*\DOpwy?^Cd909{{cOӖ[fM[T\ k{+`yyEEG|wMf#;Ym9/&![Q>L|뮻+~?csC{_~e`C18q˖--"X< cCD}Б#G~7.;K\! lG[tJJ"k TMt[+))ܶ|MnZuS3ٝN/}5KAFGWgw77 pKlZB^2B_@WKK^gA!Rlcc#"Si&"g. Ν;'O,F{yM&r 5 \d۶m!!!{$MGG ?xoᆙ3gq`iO*6GG*++1swxJcE##4Eay=%dE4|M["yVCޠOh{!) ,QIшբ) `G6/[ PAA &MD~c֬YGIKKïd8A :DŹ z2 j Җ5y7'ID4߸n՗}藗f&y6=Oǎyv4?~<~es\4{P%nu'TP>˵ZNp׸'OU͹yb8?$e+7y"t)%xLKfU;HNӧOD$`x$a!***V[$'+֝ HG!]1%G@u mIL!\ 'XY;F/G}D@[p!^ 0o7߄2$y&ijMIɱؘ8F#=o.y~.eTxt|MZ띻bt.>1?wo?tޙ1&2:]ʤE0Y‘{uEej0~z=G+[\r;Ţ9qԢLF68)B$f+ XS»SuԖ̓:X?s D4^x1= Xѵ]A|=%@ػw/@H[2~Czb £L^@|Gʬhկ(l K/[Ht`$N& ta{{K%$XP%\wlp$/,!&%{nžy< CDotoLzj7zcC#7" @|&䨟|/U? hd=m9wpf񹩩 R"ɯl[S sfj8+ƍMd9:'^o43|8H{gƧOuyN#5Yihv!{ #NHrv!sHxqX G\{&"gToP x< b ^ +u|X۷o/++N oժUNy饗x2DCत.XVJ)u?0:`Bso!>yǛ@PCN"Hmd*",To 2:w]vM*;:gkJp.fǯSj$Ͽ|쉡z_VkEyr] jQڬz1`|ֳڋr&׹J.JDr]&]V:W7Yi6:Gh^\\6cƌ,_~7ߜ8q%K(bDBh y~bꫯҗ <$-~ gzzu\~x$Tظ.jގ8oW*EIJ@:npQ`UĤ )+hTưԕ߬HJN>Hjt:uG Yx'.SL۟p%'ѓ\]-+a=ۉˉ1y39K1EGBϰ2)(#v MheXK  ~fE{)QF"!!!x$@,**yb`WB0G4L(ԱS~`v(Ffg%'mo:-0I_/ Kܹs?[ohz饗ҥK;վxw*tөSHI>gstIm2BΓt琼1X".\ۈH/QF8x7եӦhǴc aI'L3S3m6a2F1fb S;]0IDxRU@&QE9>Sz!|,^XzEs9g͚5ٞT/;4ROJ34 WջgkuA:w5\RX!_KHn=ہO26N knE0u#9)l1⻧O<-Qf1<+w:e:Fp%[H*QL]quprCkBi1wyܐ?'<><9 b|ֵq.9_F(5)EBqO"655=zncǎ{wR̀2Eؠ.gKB C48q&`856v`yk?#0ߊ ("BJx0b9`2܍Md ?+9-6bOk0/QI5Tjxa{2m?R2{e> $ZYG#QprV"hvegCjq'sHs\ 8~|UOv)c$vugIdvEg I{:#"ԟDJe@t111WIƓ7222!!aѢEW]uOX+.K=@S]>]VS;V~ /#Cl㪫7:ow'%\a2pJA. ^Bg&DXʈM67@RҥKov (5.8qڵLJ1 qKq/7 =F=RdF⣇`KϾ煯Le] P(9y/S 3xe !|m/-9oRDwֺ>)/+i֣gCʍԣnVrgySX>+9[cV!GΞQ\~664Ho1Y[ZN\\dwiLZ6)1@1gӦMzW~Aڵ {+ &3Ei--|j0rxDѧOΕ?lWJfctulnFnN.1Qƿ.h׻/Hxw3D@bs$R +W_+**̤ꫯF#N衾_qOƗ!}ELs[߮t^"Hv/+4EnbBs;1w? fl̔Ƀ?U'+ISmv:TѬG?Tjr2][.iԪUUi)Z};6~IRh l6 hWWWSJZMMM[lp SN}G@٢XA}_.@iЌR=~-*&d>.:HgNwvFQ-hJ MC44gjonw3 (I2ݮ7Jj%>,ݻwgggSP DR^zd2QHI~"B N%hPtzd:[#온(Dl:Ы/~1.tu(bYٲPfby H)R9#J݌?Se@A "j,*CC\JR usn'wOI_ qb`R$,ܪUf̘*.W{]|X#spv``:KSIř^)SdǍZ,]#yGKٌݽ(vv2qq?Wt99'*B`praR$S)&v\oo{޽{/^LSh3n8={ d3/y444Imll Z*Jʮo\G~XAb jö#}QkyFZ"C՗LϜ5qTg!>:aٛ8pbLvvr2:EY>)^jop4j=ٖ=yvܞG!UTTm߶9<ܤP*v9a¤1 SvY)nG'[oAnga{9ǀHQ**=& mzTDXzR^4UJT<~a>ͦLMJ W v}m]|񝔅Gx;8@£cǎۍ\p#GsFRJlweJcSYfr઩9:u*&?Z`hu֍7.Y$11_xNjNU=#,)Уݽ\*?/~CcC\Lٿ_BCB;:.U^[l֛)4(W)ɕ뷯=a3Mt;pXYJJ9LO<ĝwމnA'N${)΢-s:*d&*-܂z!ʾ6gm|9v?˒3,d]N%i5AT+ %._0#6¸vۮek9o |ɼcGI%ߕ8QPO  *.)F?U'NDY#}ljj" ]4Z|'X [M6=#_|1~o+ޝSn1ǯ?whЎ;JKW^vڍkof䍹ڛ_{5kx UUW֫ɄI0)&tw!̰yiESIb|Tt`c=VZZz=q)tJ Nokhcx7;v/X&%%^CũƬys&*){0b&tOk_= TgWIxCj3]!Iik8] OM6CtZXGŀ{p_R322~$..ϰXb2bF@x^!@ *C-EǏ:::(7hPIiIWgh*CvVq~_hm6 AfE_RZ;[;QkrL=da3,, irl|B㏡^;`2%%Ap /jU4VOj82I>qEۅt *K@QP,JF7Lj\F꿟%C'`:=9eRZj_ʤEYܭ--A` RҐ~7BÊhstvXۤnΙl~}MB SsG :M ]Rfz$GxJ@6Z.[ sܹdPA=#]ݑ_x=:6ZH4aYK0<+(K$TjZ3%&Z 3DɃv`x.HvMaS} O xp@Ax*aZ*:2Ǐ olljXp]pprd|1-uBN1y^۷Bqq1iNDEZb-Jzä;^t=6mb|w02Je|{߾}wF{,1 tɒ%ޑX?pIL: `+h@A$gFعX33?`ceZE@B.i8 n[-}<quZ0it̿@0>I믾>!.stT .ދ ,NI U7&—:lĐid$%.o?!Z,..~嗗/_^WW?y馛pj@ۜ{ bY0.CW/Y__ȑ#gwI'83Ay0N6}ŊAA3)9鮣& L{n PUU h6G0ݾgN?=BL;IQ](>p!`>cȋ+`OC2bM)})^Dp۠A71vL>H|`NVHeXK4aIm`wtc~mBGBl;\t\24h 3͜6Ss޿% ^1!lb#ޞP-~bS|""";=-׻XvvQ ;wnıobI"ny>1Nz֬Y$a L5V4&jiQjܐ%UUU^x!2$h;7BNѧ.""#KBR<#H-ee=)9](b075nl[ ݀#+FOA ? ӗ?-%of4t:^={7rߧC"ѭDk}*!fm|YXXkv#0*CpuR0),QCwR 𨩩JG@׿~g4ne=9K.t]vj!tEh;@A*$FksN?666RLR)UޛLK +HtG~_$y&'[B4 vh:dF@#_rq㒓X,yo&qeVzTTTEEw}7c:DEHR) lj23n!Lgc<}I4aG |zL |zl|Dž ^3pM:+`6d+LҶd0xFLKB_ğW\qˏ;MN7`Ë.!t,@Gw&X[[[]]mXn'X68;!+%D2A| 9 nݪ1;oeBq7gd'I`ܺukzz:~Xٳg+rrr()J;^ӣsNN)t) FW*7#L@Q$olmi9:f m0ID乊4SŘnqccYg5vX(t`` )!? 򤭫;rtJnNU(΢XE\ ;/!3=G}߯4Џ_)x,hIN-=q{ƍG-b'NX~|{gt/dnذ+z(BN!%z?z>(@8%2c56z]I\^v^fZfbBb!Gct%츥J^{'k||̓5r|GK665ۼ\*1?D"{WdF8L"B9i@Tn uYf$M=ӦMÉPGSRRs(+wqfNN%}x?! ) RO?eLN w'Wѳm,q&a)Ǐ VoرcЧ}=rJNѫgN\p(e @l# Z]\ltF[ΣQiaLa&p?d!b<]n۷}ݿ>S)j͔8 ??YYBRҫ_WxOue*dK=^H.x`E^LBgј_IRJ29WOh\ ȂS d$\Pٗ-[__`@?S,bJ<HJ9 39$h ehHl^pnJ+Ur\O-zLwJXf(tW׏?85k̟?s9w\鄒tT %L?w%*B TN)"(o \~ZӰẔ_"Q3#8F;zO:͊^oO6 =jԨѣG֭袋h9IFqi`ݑC6&ӎ`P1ͮGVR4 Lqq 0 ~ܪ˗/;2SKQY{aÆmܸ2d]])ʡYNw-<٬|GDI"<-B9u" SLy8PYYy%ф50ɓ'^xaP(,Kk;SSJ.%%'GeciX@|ISR<S% NNM=@ ir?&ꪫJKKk$A|AW_}L[w}(NŞ- 2;0k֬2$,, IU!hѢ \ykmm4ixcǎm۶UWW_6o IJ+Hhx h& (%G`S=!4 |rZ$qCSߪWMMM/RKKkzp6\rtpX?Ց<3f 9=2uMT=T"FFHv:#q 4Uު#qvf$luu5d"L8*|=f4_4-[#[t)#]B+t4,^DscӈAێHes m /Dユ,++[|7 v( 'W`u,h Au A|4^ RTTj Z{pD}h?⼤N_/{AL *c=aeqj 8Ww_3VI^xܺcOaK2wmy׾v±җl2&?_`/x0hh?PWɄzݙ3kp o?AQĩ ,_2}rN#`%G`p$NgDg>A~!x_fc2Dǂ~@ԭ,ACM#GU8zH4կ~Opn&xlE}Q Rhˈ [Z``B2?k#vj*~o$J1X^~?iF^{-N y,ʄB+>ϡYr-@'Nƃv@Ѣ:'^9);#ئ,3'Lk_~Ųeo;~Æu`P՗ 6|hew1jښn$oj^إ&|{uuu(jovN<9𨢪( Я?h7ML`'9Fu90xp/BXSz#:9 ͞=⣏>_:e0.̞={˝n Ԋ:Yè`hI)P&͕VT8T84W! a_pKؾiӦD%ឃ{o7hᅬ 8pJdҤI?_}ݯ:$rOHW$K9"~ 2_*OSdHss,*Lܹs ɓ1O:ֶ2ƏB͆sd4dgeU3'+++L!Gæ8#IAkƒL$A~DE|IX<|gL&N]$POlӲ\!řz8k%%%سuV۷q`_PZ)lz@-[? 5,9eO<ӧ;GQ+sb_lx#wxLh-h`2?4|;;k6lئMv_~ye&+++!Rдx:=ܳtRJ'QWNs9N?-*'nW3eC;xIq?Ws Bϛ7v(a LD7|3S$=M{⯸rq0C u \ɏo&Z]AaAAr ʺw@dewM_ um>ZB鍣 q @, 9k _={Dt~ph".H`#=0m ,mhn^\Ά `@rԧ`. .b;$ DoǏKGk :{͙3Jtt/w2MkJn%ώ)( ]@%l~ .tAe@,;_7q?ФJY@#R Fgy5A'IoqF _9 }P?^pp~mr"du%H}7 _}UM'o3Y.0ߞ^KLTLyCYԭVbG d'3qD|>;(41홚˒Y4qe||<57anzN*|ؑbjĈn98Oꦡ4dDYx r̙3qPú:o_җ?hm,'5vn m>;cl`#qc<R qF,{ [ܝ?u#wy|pGVZ?mUU|G1x/sPSw_)[vlLBd$Ɲhƒ4+%Pi>8=}FC}gw>q/kfeu;З[GCD`Gw_|1gg>R$bC=|FJ[ )g[D~1cʕ+:~7|/Le3ËӗI/ƍ gM @S b3?s^{muu5Nʾرc͚5O>$|s8tBc[1ǰCHI<%M,V|ʹH'Ȃojjկ~USS_:pʤiߡ30`~$mO:$=p H^r%f&8ŽVpN@b> aF{'? tfdɒ*j9 g]vpom\;.ӟ4g?]/aÆ:'4`_fI &aA ?7n8f̘>2\?iwI?񏐛3f̸+++)u˖-뮻F+6@j;׹s炓***>OܹsڵK,+f͚e˖Ѻy9Z@.0q9ET9+AB$Kn)J+TA pԨQV;v,ڔdY鮈A$<"uKť^O SD[@؁Nn[x1 BSrtǎ'N0a0v,-~y_q\VNND' `8pff&(X{*rJ|*-\rذa6KZFS]4 %8%+Aը޽{Qs@lĤ lRtWăӉsٹg?a͟< h$!zpٱdP# "tOw|A0ԩS *(4P n n4(ʄκ:'JTG/Rrwiʞl)q,;ݵ8^ hd%A*'jC݁,eVړhU^ c 2 lUdss3qMi? C]|q^H< Qb@$㩧slٲTщ=#G1bDSS4r@3$q!͟a0a%a'?mzUY"߸oٰ% hMAaq{=ҒܜA%ib@퀦[otW (={&)єÂFJs;;; P8l0NtH<™᭛^&3;sݗ|UW嚶gU=X E{̿hߟXݽ[ ==߻KOA4MQ &uAz]1Qh&222hLHydaC993gr9SΊ#Ǝ۶l0:jٷjo^ԒN/)Λ~m~q=n,سk)Xң3`P(D$v5RJ*EM))J^?J\ OZ^;i=36}(z*cGT2o2̇G>f`c1v]/c*>J#y3z3!c1v"q43sEC˷mGu윬 k8yꕫg;/=# q Պ9wz֊Y-Z.zҗΚ3kߞ}&+V~jy$x4yY!t($AIK`8Ƨ(B4ς<< PNhߗcPΊmE@ o)_l1X5Yl?+ 3c:c/0vai=M6:14c'Ħ;slvZf*Ǎ1l=g;Px4yx &''iذa`JJɡ\iH8&~1I="jIg~b ?&h3V-Hbel9c#ӸsMv =  >T ?ID(B~Q'{\ƾ];Ʃ[ 2dMi)B!gv`0=VX3 [+"3Ofɤ|OML󿂢ng,Kp3!4袜kco2 N;KAf iX, KA _0Qy)GAr Fu}R˂_۝{23MY#!"A<@;4&㽼S#DdPpKB%HnЎՋy[E|U|[jw {IGBDBT}n{Zg>!X_ه3$*s+UOcƚWл [5\sVѤ{#`$54`w+Je?[҅t~2c=ՑFl,X(D䋌lsLf) \Yߺ1UHB~  %&Ʈ^h727`jn=IW;!0XG[3dCPzPPI>ih ѡJ9j< \-fu$0V*'3'A!E%^cO:Ǹ V{TH%zP,bl;c`:^tC$Il_vHyE𸁚\)d |أܥ)̝EZ,M.WNJU+o ;[:|?ʐH}e- %E |- ѣ34鮋g6B9cn ӿD(˯ %;.JܙD|˂<@}V[ae&_IBUHGEQ=_Wr)6Ɖ|I2'M{OdP~(|rpEOӂ)O]w֖穴l8cs]UaP -[3eLvveQ?{{8,h:#O%>%KZx8k{K,|_*rE.cs#K !<>3`QJ{CVqm;yB"Ǎ ?&Շx!v?Q?z_5 _<|uǏV9]dDZ1dȐ[_n99'-M>hUރ3 Y#Ńǃ{\|ᯱh춻o{7'_}X,z5WȌY3_2ϫǍڶAŃh9>wdbX^^ڵk2s+ٙ=:& kjJ&i͛7J{Я! kW\5+֜;qǵoڰ+/[|ڕk/7-YӏeF:f tĔr#a=&Q'$+g)&M OwEĔP /?CW,P(=^a_i/|Bk fϞ=jԨHȨ9c"zo=*z~ ]Efa`RQФ,pdM;w B&M YYY9|ٳnݺ܌ُ's̩V\up8eq̙3WXQ__wŋ?#\p⼼<쩯7N "HUU6 srra6'˗G?ҥ#FALwQ WhS}R},*2rHl>dYPPѣG~˲@SLYnݎ; ŵkbc̘1a555^z陮&=}(ýܹs:{JKK3f`$:n8l,\ ,ؿiHѤߘ1c֬Yqedd@_&=xIǒ%Kyo'Φz _ҥKAfzqq9s{9ڢE6lOhQ_7oԩSx^} @m;:2.@`իW 6 h҃< IqĈ۷oooo e3dff644,^$ZUUuu͘1駟{~aG(8ҡh4J@d HLw ^Ճ<6\ve=>XH l ^, 4A,X8?lmm%AhOصk7??ߣI59D Ӏϟ5kqǎooo~HG|UVV6hРT)ɼ3E(e=,u+j909Ƕn"uUVK}'K ;o^ F +ymNUnz]B_)EY@Rqxm+l۰^N,3qcE"z\9\|M r33RǮ9os 5ȇPl(+k-YR`I5 a󫶥dzoW=o>Z8y)LSe,L g bb˻麂$#ډP2>!tYd*4 .FQxގ֏ lfF%VLK F_+_@¶~'zWBn<V0"?*_H68O8aEv"x,;eh9&[ZRX "L0~ں#ewEIJV~5[ȢwQ"ァ*hĶ,S'קm@%0(1lHFbC"]]]qISC 0Mբpp}8F<2-af\>M`JöC= PxB<@R*+> Nn>%űgwEꜲT(Y]9!>G{P4&b7 N4l[U 3z\-M]5K|9]tMVS/2tuӦ%(SOM3aw j2"t9 ;iл-u`'z{%$7I*hl1<,P^r$ 8,9s–4M`VTK˕ ؎Z=tdA2.[VTd z z{B9 O/[pG" '6WA-PtWR2lu"!IFy{F=wRו%l*c\vT1%ٶ&bqYn%K$UeS1DOs Q$)I7-U#fLGV 43㢊ؠ -ړ0Q5w$e˾'z_/E=8t_vN@2BEν12b3"K[dCʒ-'"qtB^2te;H>tR]a8s|0a!eSx?˖e1&^q8=\DLA[JPT2X2`j3j\]w,)dG$/LN Yډ$'{oFb',ɧIv˺nU:Q  :CM%nt&NRS-EpXUTU̒ 2k!"Ԯ3&ۃx 4 Ь'otzN}i2ѳ> m)vBr ߧֶlIpcf,U0,9f~ ̶]'(cYe@jw _ΙnlWIփf_RjzdyJµjrO fW,I*j:Oй@AaeY<&%٢Kv&T~>W={V9J˒ϯ-3nZF".% v%rZ12YݷG!/(x̪ |zCi%wrϤZMb o2-:thNN-&ST:q{eLv1j6=N[prLYWKFȼǃƐ䨂R$U;Ơ?M1^jStT/cREĻg"5|9K Җ-hBɆi0+M>Pv+ d$mk-gvc1K Ȓ_p;eغɤ-X2`@ݥeĚMR If=!,v;2JG_Sy^'/\WU 6z+3\ٔU$MR&-ԕ /qgJ}@LPwnMR!$ޖ>ɬ޺>%!\'CxLa)QfrNwݛD9.e3iv]Y;aEOMV J:Jq |RlA֪m1_ܗX7/NR2L[|"Y7dRâL )N%~#%]TFJtm)]j9c mIxJ]v2HR9YPrz]ɻEU7* 9 )M @uqڄS\+ɝ~D+v܎ d@3SZ 8'\CaŊ9s<3gά?gzw{`zlnn~z?I^xᅬAy_C_?aÆEmڴ_c=w^Mn2dȣ>i:gF@J}@2e+dR"/ MZg\)7-%zH8q }Rd>>VVlE$% K=m/lŒ-]6T脎Yvd:ꎌΘQ7N+)%rCȪ<{E2b} hSl"fk#:ZlY/4ՉLOGpIӬa~,&6E‘%Gi[@N9RhY '׿3;5j5--m=\[[~H+0[gsgyZo2 AfggA> GAoњH4Y~GCccuji/[̍IjLѐxD< lIN$R"'I)"2)n .)&Mmb>貰0ъe 2<'*7-OƔ,1.pD DoRv9Uf J[GmPM$TvEYкsz-;:Zn%Dfq']4yMvU'L1 ZbKn»%a:DlB N4R /b9%KeR2wz-dːi~ʑljիWiԀÞ~땕/Rzz:/|;g͚3|db~؃oAP ,XbEkk+t &@P; <|ۿ޽{A8l2IDP*B &).+)ף-xWe[V ωI8TQohڢA,+^z9'Bܕ#,Q$7wU>U̹O}* 1 R>4W |S瀛⌚m FfneSSy-`p +%$1a5A Q1"=;cFmܨ]kgm١x40_zoLJAZ't7qm +y_J* ;7t_PӌHQ{e GczE {UMi!Abxҏˉ"ȀwKJOvo`Ib8!.R{8_ iq}_}T<2n'lD3d))bԅh/[5ڍ_ O&2,*ؔ:LD$ٌLE* fH!E-(E4xɇM1"⤺"$ot)wR3vNcnIg/}nDߛڙ)3]6<֧U48rgZ+>*\`Y"Yّ-'ll1e"o٩E@S鞝Wi{]G=)D#Il\(%d,-(Lo|=ztQQь3/_>##uM7AށG\s50+ooܸ{n9h ?l1}u]РXhVB+Mj H؀đ8cMF:vsڲx7G:+Vkj$M9=[d%'(hp 3bZ0mcDrUӻè(b'RShG`!L1'b>Gt=W9ujr,䝉@`>#uKЕ{2H řC1ύ{enm#FKejiيdiV"1ijzDjn)n/"1i#*,}S6lgxo9 ƕFۚùUT Ò/;.*(Ejb>|1$&afm>D۸_,d)Ѓ;[…߀'vR'P,RJTtEdM  3ԈM ?sPp `ĜN#\B<ي'''S7Head`4YnۙܗgJm`R4&a 4Ɲ2-)"VOZcw*RL}fx\..r55.>cOcMsvd%3kWTMBvbX'#+0;~FS\1ωLݫjB4_-&C´C8E$3fAE1y0+|<8RH)pC7,6MAG 'LQx7s#L$"~ɔtoo92 ^veZ6ϟΟ/;7pߎOvidv­N ̺ $p49fP]ih(V%LR=89qh.QEL,DcmiZܪ=87yOAHʈY" z(⯑e߀l9EX ⷣ>S|Ѭm.+lg;"pdi좑ۄV͐PPliWLnjev+ nlk8wK꺋Ld 3brwm$vmSҠY.~9#?|/& .n;*lSt/ٝq9a()FYbMC}CwJ.L ;߲!`RdۑBA15Pu֩d3[3%ȉXKZ@D L{9Qʖ71 mScOaM-ME!Nm>D={)kk[m~i!!dtRMphqF1+i||'db֞V b\`0P\R2gy~`n^?䳖" ]kS; 2!XꄽG WrYd'' q!T?NVE7ew M&ҹa?ݓD_ {&m֞S6l-\ Dߪ`Yޝ>^4}^l+A)E@[KvّZmK.8;_Uu ԅYqeh[vYkL׷1vۍk;bVt)1wtAqkj4͇U9#)xJsȯ5l),rnxѨ k||mW|!˚/Œa#GJgP#}ν6,~MkϡLwy:{FieѨܩYh/V a!CDc{v7钒4*GVڏ7(OӰ(1¼R2`ϹeA+J$@Q^GzM'UFi}x$Ģ/[ӑ+C3/+,CۧVPu"3yhd%+%4yb",2%WmM"aGLEk[Nv''Iv' 8{x}M, Ӵc~jolLUP;n乳̊chERY\lv3/2uUA}+{ W!<֡Y GEQPN+s@wEгsF8)<4@ff;ee\֮ښ?3+g>=I&z,PZrfڑ5RtHbyyZdXDQvE;;1S̊L =hQ&OLjBhTbT5M3mKSDG[H_Ұח>rظ!,\Be W  W,ae,WmgAn]x,كdbhM?|KۺAu#:Zi+;u3睢2=2lCR[;Hǭ4)cjh,7Ū,%XvgQe0uԷQ#^\oE[£eV̚¶4} ,);R-vCo5)BuԭyӄLf+W= .QN#O.4vNi<2j)bY]u;V- *a3̝rިQuG7)jo[z}9͟Ji\CmR.0,ޛǛ 1+T[wo"ÆTLCፌuv kwT̞ f椧ƖW}2$"|>ƎET4To隥IPmYbj/^kY>$=A3w˔,2VxDx.3ܝ p)P6^N^eR㚂Fm -b>h&j1j!4wKqDwyswXTkS$%*BQ$RpEOesEzzԩ6Èb={WZN:+,٥cٺ1ϝN_f[D3{IW&)MId&3%ѼE|.I ^龍3򻭇+MBb xx$AIqWB$MN0!==G;!qx0̬meBjbDv,`Ě?nk]U%!??s>{E4\,23K3 KHRx2iY[7fL)egBR̊U-Jiz`gm^i )-)jw Ȗ aAlx}mle- !@RuPUS`,jעKjϞh\ܱ1y#PZ /_'r+z6lr_'kZp΂z9_nG:U YVܸRg;v(L֤R@U6M2fM>coA5TM4غ{vΜȩܳ+b6KRT gԗdťhnRm.hWZ/9kym9Ymz_mRI'>BTWӚq@S(CniG0h6|ᯑå >%-#* k5UPZ}}SiQ~݁tuݲLvvOsӶs`"@Uk& ;0QSfcA|8bR0^#fU,~YUihHM 촪 $Chn=`9_'dR PL"yg<Mud%VGNԐ^ j5l_W;ў2d5WO_?48+rt-kk[J5bJI$SV,غ.'?Q,=݌Q-Sp^MrCᳰr4'xP䀢3)bQdDyJaowOpv_(0㬩 NNɉ~ԨxZ?^nkSc~E*ZsHvr^O'n@kJyz{HrR%߯bDH nq21-;4,1nVFFѣWXa%iRksssQQѠArssSg>Yx,ZJM :ri'Վ29=].TG^Q[ 3Z36,opc/')*F-{SYi"[2X<(=WockƴCj4K0Ԭ&8zbPcCNM>PiyNn2>8PC{˲gO YOz|k}}M[o(03ѳ:,  #9߾ȔH| [WxKWL ʕHiwyOo PЊMT!:ZX d,Ƴ9LR$|۽4s˫<Q1&K5'"dBa6DbyUSM8JR('u{O xk؃?%VN6WO`/\؋a8ٜhvw鍗G(PIúOT]?=??-߾|maF77#Su`JR3YM) c;wkkĩfzr2^'Fl1hn1I| ;g;+-uX,(d}'M{QvqF<㷁\)gbqU-Cr- ,JLM4C1"ޠ>ٺ1ol"LB#a$U½[/!2 @ -)5i:Y 1xC&D249b_АN掜7!ǭ#9t4ѽrx_;םƑ''j@N"N4?cp: QMzqtFXu~3I5ɒЧ& Lem貕RgY3:TcE6 t]1r`0BHHo;鵥]rH*ArՀv|)BiC$Us01{5V˷hb~P&f߻~K>9}U'#u7 "y8 RTY{¨2@f!ӯ?{NB`f-{裮,[T.Z%dŭJ֗ 5[u7Υ{]=qhZy{FչР=Ћ cڷf)"^9/fIāLȭ͖&e;kn!,ǺSEc0??W2wh>vHf~_Ê$CkrY~3#d[cYΑt-Sz^60oko7.9!MUҬpG4,lc8 cͽ؃ [;Ce},儾Rߓ--u*KUeEz-w|χ&;w\.}x^dBPlTw{ޱԑqX } eYT|| {-"ֻ-lOϝpwۥpDaY4}KNi8'̑Cԡj.!ˋܱc<.[OIȏ~RG:PiSBUMТ'ڝltdqk߿SG{=[|̮EzixF$7S,>|ݕr9_877<Ҳ  ba &zLsd!'v0 UTZkh}s|?&M}=H2 a_nAбMp)ؤEh7[]"*U;BGE~^\vǐJ[EZ>GM,jz#T~= ~hx-%vӇY W/;h„  L-3(0V'}O\29\'HW-(uԽfsJF_fșG3~0?\$u8lfժ ;M:bѲAG8Lu^OF5 6@weLhz~';6,펧r1@`bpxe&EZfT3xHRJTXa6@0ƥԉ xТ irRa!dNmҐŌϱ-?$&y $ yH~p%~MxF4 X,iĭ81N )OS^RO>oeΡB}#?cT>5`B(.p;9nxƠ7 줰_oQ {SRi: =^6n(FEԶXP).HbE;XvbNJ6 Z yVKhj3%&m-=9`P<2w;Os.93iV0ӗZ/AiH*4KKcԉ/}%:cUH[GsI{.-ebh9u=tbjl"au" n JڈGsFq:x453@ D>qd"6&d Co >V|Am|GjVKf[a8MEuU]◅TYŇ~gQpQT-*JccIÃ30D:ɴt)p wQW(EZB; NQJ:<Nm.# nFC)=VSe͛oTPcl|آ QΎE^7ttܨv <&"ɸaCOg~s"vxZ q*^XU칈tzT\ :; OWђĺ '5Ź74DY'0%|w"}~0L$w !TVxռPxD,6DDS n:WOQ<(^ qy#S9E+=YU9t?IqMYՔV֪){͑s/;{z~h4wks_7K aA'Vbq0I- ހ7Պ6.zP"GY:1`$pЎH; b~"FҢE91p'qj}ymrIJ[dStF\5$Jgb3okW`[>5Q{/N(kVvDW  i a2*\o8XcC=y!Ca!$amz 9A5ĭFM6[m B_"yÏW+gFOOX҄Hp=LS5A,# ?{FYNm|?h` " " S$ĉMPnoYcpS#\<0P!w }#J w]ȽҘvdsdyg{l|*nW+⬿sFLB$_݉f?+Fh iG}~GӐ"9.(4: !¢#BϝM?|!;d$]%< q.(FKJ-ZwG Ċ2,En|yR&[iBE% e&jEݕRrY 4/t]N|i45Df+/!0a]5HꕏdCܾq;_ʛU]nsT vH%Ozc smT. Ԥ'LU"ҾxϜI$~vԯԏ|(nX@%eR $\Eks܋NTsf,r%I*mBHjFQq]aO, P ybՄN3d"smҧ/?g  c̉4b]`U8~FF+mث~X=WMHQ^}kdN !f?޾;PIUcon+dkH9͖c:R4gl^lHu <tB=1BioUa:O:3{T&t\œ0*- 6?Wceہwꕗ}##&qH('|]̧n|Źi!*Koc@86Bh/MꎪA4}SEDʞpGhoo/OAnxJ*]ߒ>2Pc GMC=Au{?d=3 V$ctE(rAe;cMFoŽ䭷Zݜ+[]i%\2Ul&2UhTZ5)~oc=҈E͠׻:_VRMx܅X_К?|"97Ƨ2Rlsȗ;Ghk2#:gg!wt_S\ߓr׭^ۼ8{=_%SOj*E?s]4ELUv\}!u %<k8BEF%>?ap.b큤*='0f!2Y)sCm_oSO~-l?=v!POUUWLƥDЌuE/F0by+P.w߼FRgßxJbʕ[{޽Wz|ˡH25J4BL<JW M [Wf'[vtg\e+N:6YV djq>dzlt\Sm/'y(2}<)yvXM_k,?V (pg3s_Ք.b01mfRZ."))KClQG i(E͗"Tu^?d׼A8J=!$mYmA( 6n-շw=Lɾ"k6~(-ehoP}Dq&;y[W+uglVRN-%񛃄=e8T2D"<L~o@_8c޾_Kem"阦 :2W{F|gW=P669Z޼T: IzTFxH^TdQLh87M9"dPJgS*QTMO3(1Q.@>tv#0_n'֍J2;~̣Vyn GlUنFoLAϒlѶ {5?i$DEea'[o:R,fռ>;/ēQ?RwPN;__/j4J3Q衡i?9MF$B$OxLRdC%8E8=BTwGgN-Ҧ^%fD~Ӣjqt[[}lmoO?I s:k/s3k-[?ʽY=S:"3$v~uMTkynqdVI{d\6IBI-jUY]. }L.V uEL* 4L,bXJNOgjYx}}#-m%qZfW)}5[j~vGNQ~}g6s YRR>YERo|- W.KD"s22#o9" 't8!Ê?~"$%8ԪG>l_} M\X!YжUΫ tP~"q61Xrcc*?X*/0`dx<'koj jr45iM rHg낔)/e=$qGwZiD^E; Y AXIh)E? afq1}l/_BOv3P4SMɚyo:2cj4{;Ij&Lsn?ϏO~ c4ﮣ?ΘgٙF3֙ÅSG%y2'uȳ*EQ-pz%!>|aKDDEH:T4}qΊF2wۍ:S9=/S28{;YTDtn/,=-&r5NQQay80 K}_x076*ҽ=YFeEPa;Qe0d!ϠjoW7}H{A;L:}ا[+b1Ș &K>fE Å˰YM$(!g29~nbfOKէ1}[2|IpL B,8.Nϕf)Z * ~M PznYnW& BFr6b2Ot,WH٫بtogxQ@Ŝ~ ߹T 4 sl¢LXˢ/T7r`fkeP\$a'.$$ȍq[n./kR<1~F|nzzc/y3R*rEU.GQMH[6D8X!8 #bq;S%݊cy_ ~of=,9<{n5w:y-,,̅,uݦ>TZɔ1|b1r\< 1BK(Su{8^"z B6 c< =B_~#x'%9UY$g EaEFqZFvCY\WIqERHFœTBM̗ =i7UE Wokf|m^5IdYj0 P |nik> #PEar Όf|\{oؖn1T\J3ApR.}ܹܠ5<l #b(J $Ϥu0iPUBxVgi֔aYto/Ä9JeAue3r=?Ԓy< c& #[knë5h|ұwn)(MT<فe*E|"\hLܛOoAkɔ%'{-Kmf(y7_ +hz%~S竊.Q_̃$+77oZ{Gg^!"r^-L%Gi|PVp#% e>1U!7sCfa˭l A-4~ WZ#i .%4>f39Nfc{Lߞo7s׫7ƙ#%Vn?a w:s*uLsFFv+zTdS^UV ɭ!CIRi8I?Efcϟ|+zeL Rdh9,;[ux)Xb˰>@bDАb{'r˗8>}&Y|CːFE#Q>.JJXA6'9B˚[L<[t ?4$av%V'HqE4D4n3kGRd`(mCKFsSr&Ơ7?yRcPՔSS~fIᰦ)ۯ^5:5PCJю1=mmZߩ}ΙKx6?\>Y>9XtY`f* v܅bnvC82=?6ڲwbE1֌ΜʌƒT++kε7d9 +om{g:C}]I'wg(I::N+!&;Lzۅ2hQ \uW'hׯ$`N+fb TBA3`) {,i9w/ę؋Ki5A ب a&2hYEch1rWFL ~F *8Lt29 a` % B䒽rғK2c}?t5~i78?ozj9ĂLK00002xJׁՃ6 ~(+J(&0U+oHFW`ņvCVG}]H$F*xMLd3X ٧&lO9 ʧCTRM$witf&|R[ns0 GK㡧Yz,1R88` ~&2*(Aٗ߉ͥAhC<a$8Pv8bIA:~7m;Y/n&k#XdNYĶ1C)G3vkUtFet&5NFwN@I^%47׷&g k^lUD(JFj\dB: t!QCfQx^ȧî}e[8Bb' 8+>u"C>S֡Px*yiL35(4E!¯Sl(Dr PmX&̯o&)ϟ]H:PbdI y8x)Egb&Zx @QЗG'> r*#N鰷3c%ӧUUϕhdEN_o/bLv+{17:r_ۗ~/&\DR$J4Fǒg&;`1 qx ð ' ؁d<̌](jl~[%;[U7M||֭{=[{R!t!ܷOy~m7c'ޤnׄ&׏!fQ$;r;Mq{kkz7766Zn!W,{gϞs{^>*\=(P,^>^/ەWoP4;%',-dmڴV`䥛O+͏Vt["gWh#-IDl 5\ÈYtx3'ǰ1,t\ KKaNIAlX-pUVk}X8i(PIb'^?9$`+ #Ght/\p`A . i ]qឹ]W~avͱ]:JEYUIj|PxB>ݧ*!?Q[Y+ڳ=pi{J9[ 'Xql4 .[f)tYFp%ٍM Kj˟=wX.^P'Iɲ&ChN[~*!'i̶h86e\iRݼU,sc+_wï_Dh,Sk'Vӣqчkʒns(f6%% 5|`H3&nv@*]((ԙ 03HY嵭W/١|(VX:Sek3+\DžÕNV$WZ,?R M4(qu!Rg \~83jbbqy6R'KR+RJMZ7e+?ʂC͍kI*Q3wr\t7P,:D$"Z[ū(l yD5>Aj. ͭ [)a#:O >hﴚ|c_¬"kZ:t 0˥cE6V9ڞ ;\O.l]\[LʉəuUPZ~th; WgMT9]J(j =Cueb[(Ag{N0{los ҔذⅣ@b@SDT_(٬a$ܕqi u.֎v#j#ڝhW|hXzś 3m7;=Y٩ñz*$W^߳gnYͺ-5eOf}(¾*ylrӥ"ͺPB%Tm"&jt]쉟x4ϷhsE. pĨ[[8|VVg4Htz9J_Y}:l%{qhYnlouGc E5-"Y] k&]3{n; =w$d hXwesH[nd奵p:{+_tC2/Jt p({kߝ#.A^Z%ܳ&aҽ ph>y1uo @h"|ڀDf}C!e}3sUf=y 2ǹ-;{8W)ź5Xt;s2.3x'ֿ_~#z:_x=/ A@~WBea;as|˧Z.k;MfjrwӋTPI@9S3j;{~/<͏<Ԅ7[&Q6%CLyJ K?dWC'cgP_$UqI͐^=qoueWo6% 7Wۿڭ\T0@yd{.Ez.#(;^7cW_{#nnXaim*CщF G::H+FS{PMZXԾO:%~QPO[̅ĽCF7bݐJ5c@kE&1ƶrJCzB0~x tV?zyr4eYeap? _{7x\vcUf?p# ڼcT^4-h("d @qA5skS)m߼vl*+GXq5Gܮh֓<–oM>X !dOhK¤PˑSrwm>T΅7}O96S^ѩ;v7N{,=v,t{θdĘ~# I@ 0=`A0.Ims<7Y,?pRa+(a6Ql:1ڲurMG}F\=…||I*Ol|lvmeS$ه~rq3ɍ吽vAFƲk3Z^|Ķ_? XXE@Y 0J5/R ]~gıe^DޅKO(׭vuisuq09>6yJik+W?>љq^?F!_+I5Q3h}{*quٶrv 9 'E,P I^TW㾒5H*mCEեfPW/DQn֖Չ)u_x o޼rrnڅ(C-Ɯ6[[w:5"tlF8Z!5:#eMF ʲTe?\o]Z('lwh@6yKeۉhC>]F*b.wUJ:SQKp[Ihe3Qv<̄J \GD¶x{݋Fƍh8̯P{AJG^efțJCkzdb(-n,KAVNR^|6 ε3rcsf}Jpm6Z(nn~QmM5ܼ̎q YQWY4kMfȝ7ٚ+;+V״}D=VV~?=7hA,GaG{ӷOPjۤnNi ,P?#T*sIUibk=[NZwNٞрnr3yv1qmͭ|kbyHr#@%7!jp(nҚsuHAr*ӿVOGYLտzGri%˶u7лze?PeE@" Ԉ( bYl~?5{XC -ˁbgu 7.\idmeU ʣ.vJ2S>_ZlmU;mu'Vi1tm" jZUFrЩGPɂ\"v;ҵJc)fd^ày\r\ٳTh֕~vu&qK]ύCl5*_=r @n(f>~\/ke[ QNC)I 8#WJ=P\r便[hj(ڔGj?RꆡrC?T BIN$Gt{+jy$v#q4N mv;Q!d Ju sAduG+[/^8D51-.}BNH. >7ß,őUi3Uo`.Ǿܩyrfw맮<:=uJmP]Wf9u+Ykl!ʙJFz#*䷅-rM4[M2ڲ+7&U QTd͔z(WNir*Q&Shq5tG3\@uNRFztݠ.;ѕUoFqcPX a@$&HntO8Kѱtau{䧞~trm :v/o8~vY@s#d h:OLُcv>}-e;QF͍ K =צ󶥬ß_]xĠ5'c(Bq_eHS[(0z$cwCLIX2@*L4,HP+_6wܸvjzXUi,<8$;PQ}Rۨ7nXT˺gp`_L6pʍNuQ-|w -$rEq"%!myESxԗDũ}n$[;¸5YoJC&u9I8UPMCT[zYR,L5`geL 7^ IJ7K?8]w ?4+d$jR&ω.0bt3,\@#M=Zx* AsC{%3l KP%Q&u-l+,գ.L<`5V_Ⱥ/ ݰ]-W A jNI~Ԟ]dX /o O?0\Sg}M9ڱ\]E9o, >##g"Ґm篭6~%w`[yZu+bsf+ʕթ٣Ҙې(|3{-QXƸ~~J1rlZl>sJU22Nό>y#b "}F |PG91zux;-o,.ΠGx7$yze9%V.\"D#ڨ`@ "Lm$[>oGB.%\j[)Qw~ e&PYJͪEfrQΊR 7[V^y  $eͰ#- ۬^Rs҆Z!r,pWָ[ID*8 #VÀd`}Cv-\t*\:EPLE]l9p/ Ć;ܰs-U6c[([Rtd# ړhY* Z&)cYm8\`sSGg ,-w}N[ClӵD+Ӗaes|v'MdlZ3mGY80nqjJeqkHJ#CEm@4v'=~2` ٽ,BVy- %@LRLv$1$ס (+qeF֟_|@ԟUd˘,A$|1Wy–24N|:|Brug ?4^OyzY}\F(˴KC `MWݞ)FtR(,( ,N0{r7[YXvS"Ca0n*lk_!MšRw,#wɌv,CԤ!E&ꙛ ѣO<'חng:NQ7'PRsRK]_DcM<|5-|3Ώrm32"bM>z_XL.sJ;Dz|ұO#댰ʮ[^HvshN6&g6Pq]094TfqІmqx内=i>Թtuy{m=B*ŅnPiVn!p`B`H3hoR3~ 8P\4Rm+_DcȴP2IRC4IGPMfH;&7J(K[ }Q\mH=& x r"d$lS6tj]ۢ bBYfTv3v'/w%a+#:!uԭ`Aユ(Ȧ-Fbv\{=.#`}|+%BvQD:Mf5T"`-ֆcjjEIz+Ciu Ƀk$j֜E1<\s%Fu={.}v6wYSҙk[,TIZ;S}K] !+`cН=t6 kz/Tzu;#F+gX2<>и)HjCC^Z_ֺ --{q}+خ#r!`]%gHI@"‰Y_/fpc$o0m@/X&C\..Tp2QN_;9^Z㈸Y+kwx$\iJ;nZK95n[rcYS;q.R3*0GV]Ͼ'? >'xK[@:<>_"r1 dǸѱQyfǞ\ $~fKNǛy#*oT#֡$"[=tv &1r}hBa)pˈG:4ۑh()r!!MBrjpACc*x*"]LB6.GNe6gN_-ц??z܁JiWyKUYSޮ@ 51LjހQC=@Ay%RWxTX=MbwT&X&'LϗiвjT tu@iǂD@MCu%D!?wnDP;D֪]Gq.g\D_.J`}JfJwLx7<&UĿ!+d0m5quXIoCO(* {1HBYN}E.YPC98($˓12?Rej‰}oEI0>Z22vXE=뗮64h0R ե>olIiqijDžf^9(dK!^[DӝkivY}Qh"Ϩ7NzSbWv镅CQ)d~T@V=Hr2hD(Pk ?HvP]6]>cZY茁?SU iqs;ޣI*LH1%%$sf}~-0\VqW[g#O??ګ/H6s'mʄ] Fpн)4'If[hbcZN!܃ % a8M+;X]ON]n"y}-wOS^ׯ_?w#H! m@voކR>,B  ʨdaS_EgV6߸يʢ\b ?qiX!Ly(jpͭ|z!b_+^V*lJS0os6jK(w&S~Q pji$adir0rFZ3ʕ&6m(zu Ӑ!qYD]-n ڜ]y`ŧBvk?֩}rZyb.Hs(hle1tRJo6-]"Ti(:!qi1gUr5٩6d%Ɇd|Y :vN) VCf\ڞEXzA'W3 Bok)4, s \v `a`V+9~~ . 8QdJ3m(zcP΀u},ұ i'qxLU;MA Ky|XŮlzmhQvO}KMnݰ "yab+ J}+{_bUjaEfƋ o_vUxkȰJy]x';o;ۏn|?\Z)}OױFxK'M=I:uҳ/*潿?aǶ?䃿x?؎Ö a*5E9>>ytcSBnʨIP`%ZJ]څ #-@%:w(Άf}VScrT-2!Wy\<}]f6#[dsDS!N)PKXJ0 g[W4p` 弤|RFZ-,nDaňNt%'bMc:EA ?y8gvw&7ԁNsMKDt VQ%PV9 ,jGWPAZT3hU4K <`L,NJhB[P=7_&fH{Q$4+=dJ!ĉRizqqؐI;3`*dȺeRPHV'-z FW9dբuϖ.9 -YVu 2 \ڦEZ  8%N/2am[ [ E+_UME7m[: ڤ4a7 2IFüŅ<~|pSִdѕuFB -? gY.rzGf{6>Ɲy!Za Wsśج ]ś.L8Hñ::)%}r1T;sjt0nR`tWv&nU'/Y~A`]y5;;g4h^(|.MD66_w$X4%87Xp8tմuV XmB-cTT6=rxeBUr.Q$P& ق46W4MNonnh]o# 8Nup庲毄^A-zueuk=dTy -"Yvn;F1ԢIk /BBASZ"9RJ( ԙDže`pƀ*!<[7̃觛p (oA=<w4r}iJD` >-:>>1H:xc(%8Dzb{M23,w%27+m!Xd =!45tXc[Jq!82@pYy_ c@n7VN F/޽WcsmN#4Aun RòZ.0lR[DI:4u8ڜk}s}Z[:t˓3Չډ%Lp 3 dOtbc 2(fC˥9nVy>`} eA2,ҥ<>F\dޕ %$hեȊ2";Ԯ[ G6 {`\XMo/̛hlr=Ѣ2 e;VYf}sѣ|&_z46ge,HMfh|/\p`cw_:urR~]Uuӗ>+秔|'_)'݆^%JEJ_5iSg \'RvQVc o)HNHC7.~as4괶NH#`"3!F.F=y_|?ܸ N8-(Hg^Q +] l=iߝ棃G"SYrx MZU%2@&g N9Uz[,ɵ`ZS:t-b=BqOl*%w&3 $p2qo͂:`3(ay&kncmuP'9Q֜rÐ_.:%,f_?b;nqݭ]ću\ vc :v8AՃ\$jMR<) 7HUdA -U T?VfX)7?0kj*ϧ uґiR1H5,{;_>cR~~v_[)g~7>O~~bV>%GGˆ<~'%Ssj4R _u]uphlޮĸ9gOŻ1;y/t$/ĔA1qF6Τv'V5v4^o[[(bϻVtp:Ԥs^LĽkmJpYܖ3qp/X݉h3B=gǶme;Gx\#3g%^DY3P#!b)v_@}L;T>AwbOn~`Ł4{ԚI* b8㓽WiJBQ.L4ad-&^)Zm*7B1,]BɡK?*dNEH;:% DbR"nmօ_RץRЇ6G뇈mۆ2VA-K Mf%h[Y4N}"4WG桙rDxMْ&tILV03C$&׷πI̫_<&Rͩ(D -B1ApJJ~Δ'~*edmB :9ZνӲa2aICʋL N6dvDO\.xDYF]=> DaU'J♫öydr;vȠ DcȨc•8đLȄ]B&gfw]TvpLc8@·Y$ n"p8[g0~S22 ( i \ZQN 5ka7+r9nO||bhp.Mnfx|O?^x6 P^eM@b̓ X@hKc!p)쑉c۽3ྜྷnԣLW Mza0ЇY`102I_`T*'"#[8 %rG}n"ee96䷠Q$ӭ!Q/w#RT)lU L>L vl1cP:FOКU[nVrlT jת đBo;54Ϡ]OCMVѓח۩4q׬4WMz68;U]_rb3H~Ap7=ŅvYa y)'9XE]1oZ:=*{0.7K@%(rx Ū I![Y|(@MV & fY;郗Tizj'S[Iޢ'S:奟2Py|)(9R$ fsV_|orrūW/sٿw~8xh?ըoOi{qǐm-dNtE*ݞ'qº*(63ui^43۵]3핾њj@xFj(zTx%NXǓ+6G]}GsMoHٮ9ZN'v1(tFkܸ {w2TNrs]_|(kNB5̉0JPYH#;[惉i{OwkuS Mn]bsuyV'9h ֈZu ΡpDBC]o͎Yg6+Y5iJY6͂Fk#e+GY\+@=H4/:_m]QbbP{SK(' e Bf]7`刅x_[QW>hOSj W؅9jʐteFwꌂC^3kn0da"b2Y_#5u0"|CNvȑgμZ׫ɓ/=}m䒚Q\ `_uziz8ӂ?17Y^_v)Pc,Q T},(96G C(nnA;_yUq $6_pE8lMNr&zIEGcjNXj7BLq>5i\A,(w7/}8CFW7[Hcj()Yw֠ZTPGr2c4һ>Zò/y7&A2]! Ϻ[lѥ7.Й}F"΋Tjn5wbf%CkjVP3nl(K-EG"gF;;P&M or+N_/zH5jlXys2n+XJNJ(מx >SJMuc.%tL}/!|8ft3b?4މxդ^ & h^`t۴IFz{x2'61 vG٪^uwм p7~"&y57;i]jVKQzuD8BL<u@ӱ^*1y7r}fMŠV}t\9{e=q(BUsrᝑս!b{#w mR0nl)n[ yHEW} 85nzҾ!盞A[#>N}#u[8&K}Fmk 4hJ1~1LҢX pɄmDqv/fg#N[rß2~rᚏ??soYc !={`r 9޷2fi0Bv nS-K@`F@*A 21$ {gWy1R pq@uGN^82@{5f0$F4\Hݕgݚ=s> "1IH+*yfy\áuGcޙ˫N؈drdm~vb~xls%Yxَ3:D|"zU:wL\ ˄!{g"-W(eI<Ҥ 0F}4`ap8$ZRo;8= \sIW띎UTghX O) (t Ԟ"6ƘπV.q Pc>k"}FQFw0t Ȅ^1%ta$`5nn]rZlnLw:-e,^|R.WQȱry??1]o_cJ{0˘0]1vĬzz{]8q<Ѕ80΃$Gȕz[Z LG'zAo h1Ŗ&22N2H ('CۨNmYqR̎\cˁ.,*],/ |၂]s]QGT0!$ PAS24ҔD'v)ٟ#HX*RaZ%jg:#]ߛc#TC8[wL']Ҷˎݻ{UBT}S_?ꭹ3}bab&ܪK, ,?xx{qCJP z9i;* i6vՒi=?On1&ydQ92"*KTM&=z4GyG39|!l(gh8 Fkc;\&:\ހ+!:x#?~oM .62%H&$@$e&O H$tC/4b#\b<<G SY ӫ_ïҝ4F GEd&X( d (S#fk@T9r|N5 1m$,=ٴ[M- JM|giZVYmsFnnOX J[k^:5C1?pz*Jbl.U>WxC4#й}'=&Y$-c 'cOK SV+G,X醞;Mde#McCrS-Bt$#X=o2*vIt4[>M|C-ؙ[JxvؚqG\$4j;D j/# A Pk~s(ZQˢ(+)Lξ<̎I%܅ zKa2BIzhtLV)3ӉeGfpEx[2'MfDxzތ{G.Đ5Q~"'%DMm|BU+ŮOr"עt-XLa$ٜ: h|iXjcI 73HFyE ?Q?)ח0$4ܗI0\?Fk"k$NOH%ROgg0 ::&|7\͖Tތ{%|lz@aGt)4jq0ɰ$qPC5ӓf1=1*(Pɷ&g@Yd;oƐ@SĚz\@50$I58< wX62ec `t#XDZ+jL;9}lϿ2ٵ2vBV] eό J/Mq3rfTu n,XGjOKQWgCfɺ_6yO3Š6՟v\PrZ& 66ƍ]5BH0]<fガ8~QFϔcL20M{ēZmP𑦚5;Z3F'qeY˂!bO*ŮTBtZ HSjlym$ή*V؄ebJ46ֳnOׅp%)#0sqR30d]Ofݳ*;PẚOC@%ā~߉'(ñYc.,"DJ&Sޝ29ru$@-hgy b:2&Fa rFXȾQspΜ&0%5k1.)q3G [Gd: tK\O 6dMbuPunGy]Yҩ*y!1x}-(t&xgiK2"Qn:%fm4H1h 8]3dܧL/qVVƈPXQJHR8(Vqm@ef ^268p?F@ g6)?@4dcpޗWeðzɰx^u0%AS =Zh/$QfB'pY) \6( H>F/]2CArlx;6FSꐅ!7Xvf6RENaMmf'Q(=IV &f!3!i!(m &ư7drG,'bȦ I(绫q;vD2cΡ7 ׆-6WXGqb-t;B}qo6@$qT/u'={%"^%piLnw\*!ԕ14)oPH3!el fr A;%iu`ҫ(XYhrbMsLDfIPi\IO"ض-DB0PR:FM} bH ļQz:їBh+&i|Z@o^F53İ~ۿP{ ;y3\e,3sZEJ&__|qLm "&GObMqHb1hiT)hpL @"8MKRrTgĐ42Իj}`W>}P{;4.tӒ^Nx8rWGoԷ_''3ONN{c'Z֯hoil~df #3zKCA/zK[5`C>,'*Ib\UIb]V+S_dq=Uٓ֔Ke?pd(J:&q 59i\pG4&Jk2ȩ'4=I-sw:2L&}+=OaY ''Agj7`9~"5D2imi;`$;3=Mg/;b c$j2nhQڈ1@jVR=9Ղi2C[&hw)yd@p(!icOuzFXw4k78QqY= XoӷW "D_] mpNHPCb߁_]YWky$W֎=pVޫ+WǎiA y[7CljEڍQv&C^pq-bOs26J QQV:Pm <מj$xYe5Lvd#VwZ?!6-G&hU*o}ېGRGjuk.IL!l1it}`2H<=}9T#\U6ZeBй %:SG%]z-^! f (.9U.+Fr[1ҀGC*r3L[(!Ԡ6!x!Q [TYo c8ס:k2(NԆhu(%WW_g5=yj!3P0I% s[ eG hUOPl(fNyL'׈pN.@uȥ1AŰ=y63:oknUZmF"|!w0B+da$ (rg(W\p!"c7fh2LR\9,ɅtDWeT%` ԪwV".a $),y lpc`Ŧ]ى #qT@2i+I3*@T1 ^Uʎ㟼rdzAYẅ{}DC؎J\Dn眀ca2E"zpYu 8ai`˨2Tk)2 B~驝T#Ux_e^0BK&i`- YHӮwK_g]8tGJ eypc}O',B"7Tۋ!|]z#CA5dBe[KRR_/i"ayOX_K^^;XkGĩuRgfC&j C V8dǃթ_P/Eܱ>:EXH͂4rEm\b20W$'XXbR:*pdz-9ԠD8g)Ė,wXd mBIAGȋa`s}&72oN 7X<u hZbhox!ږxhtU Z1˨+쏌vWyDONxnDWiIBB(t 56WX^/$o(fzU, 4 G`I-~gWBCʀ "#ܞRYƅ 9,3^Ɋ4_INJ$D€-:i0kSsj`5K 90B[ʲg!V̓\/{5\*!•ո#R]XlD$nvҒYO^WO\r RKYD%cIlVB4I,Dx) >@ky=!MH߶"[e=[\E.,CT lyvm. O0i3FELYU;Ffy"ϫnI 3MzvN0wf  ey22rͼӊ,%(x4gɨm07J\3KB4u)SBNDbn`h&L{Sȭ2IkX퍶nIҫ >`K%pЉ@$ 628qnj$*4(V Auao,6%wARX1r-5*D>a : ₋xaͷr!*93|)s>ӿXz入ff[&<)(3VI~Yy+hX 4\6*4lJRttďB!IS3brXLZ*=Bz 3?ӶXPR|\,C4im]sQ3<\eP}v ((@!0V8Y`eE"&Zu a,jo7QgG}y5d }SbGtsk-cP}e1;i]FxʐE J?CDBpuQ-$~)-@u 3E"[tv(<  >nETGg$ LV.S4^,dW)Tө$#~#×#355@['0ƅh|؉vSpvfzYpg'?̶g'^)+oȕ'Rkp5̢R-^ ɛZSKL %țe[@ QN"H5k4`ҢEP!0 1YHQ+bx%j bz@`2SG6Z` 0DQ <<1 ocL}6Q{MK Z\*6\+^~T)USsWӁBT*y7m~*A]+yvB7ǡ]vg$wQY5EI7Jf'ˬyk ؼт_8#]~Ni@7 &Q#XR `:^f]dP]h6| kMȼZ^޽{wO=7t貝{^o/ҵUj&k;i I%DJ"/ة8Cx=ȼ22+iڵ4NK`2E:M[J0do&Jc4"rI F&l\ Dk?/k[wUQKv>oVWR-`ؾh2$6jHA@,иgyfp-[tx7O5p UcZ>tSJ 2e%s)B"N~`R\^L2f!n&ٝ"uaB;0+!(t0X bbI#=xK#~kL ^S.O2Ve0]":'OJg>cG+N򡍜j 6`qtemТK,$VH% @>R_D4-4]ո {=ٻx+~/w_݅y+>/}ߨcǎVmn???O [cOW0ۏCWG{vO9sC2Pa˖=S?^}֬)oMYϨW"/U\<>d0W-'B!# BŊ%ĵtB.L3gPeEN+ hgQ\I@- j 5qp(5nj0CWm[3!C((i0}\Sʈ܅̣twv1鷏:S EtZf|j^|=dL`pb?(PM!5J4B#_8Ӵs<k뫾ݔgA="7.Czp^fXm@,!PʲhLܲFIv54&\2dB/ e.ImOءV̼-٬g[I۷ر[ӟ}W*{}ћV땮y7W]{'nMյU dbb~wn;cvsdD.C!H'O|i]Fa[s2kV*պF}:BL2s k[1`bZ#F…XæFrAS ҇qOn>:=;IdVAk>c<>|F>险?{}Ϸrz^ߠcR&`Y!%С.qn2}Nv<Ԅq)4Nc'خ%6S<%)M-\)֩?xwN|b TshE,w;ᤥ4zɰrt~HlWDžEE?V=G{~aoZ ٦au!b<ax@)34>!Bs^G.0|d`=QZj\SVA jFQIԔ]{8((ģ'[rfHآi'(KMF叡ݵ" ʾ}[~7c ֣!dҫ Phqծ! : p-- ︣kj;Dv^I: e]5ll;Ԓ4&[7&Xr PuD7Le\j ̀V+nElsa{UԔ284mäQ@rT-m*T42 v^ 9s?v{^2|>6mOzPv:`.6z3`kDBkQoXNc&Wy޵{k`_:uZJNz(Q\X-3hմ&D==N]D˕Gd!UH}7D[XR?I<X*W $nfb(5X|_!_(הNÆ.Њo\CjA ' ѿ癑=skֶ il4bH0-|3Bfm ! XݺZ@z̍K 6[3'Znvge}͚5 ANv3,G|%^A p!!!P|ͱcƌ3|psݸq=Ҥ {nH[cbbb HLLܱcG~P86Ͼ.]:u*66vѢEݺuSٳ!>cJ]]]KEfΜ9w܁֫W/99yƍOFNn~ڱc+VX#͛7/\EI lذO>c]N'Yc re?вnnn_= ]{A 5O{o5fCJ^r=$~"d$4%=#KW0>^(dxtBXj\CR"TU.\TI$P`4Uzi9-1P p|vڽ{矃zׯ&%%vl+W?003gÆ [`A׮]թSwyݻ۷7n\)_۷q8m5'吧i`3-- ʾon_+~&ve7(iP̦+[@.Pvqc/$={O=rRML6)4?֜ݵd1\۽nuMo,EdE*U%lKu&9 ڵnheFezJ``n pUVswi% J͡-[믿ԨQرcy,W|x^7\{m quuEfW*R488 ݬY3f@geeM:ɓɨiӠ7hԨQBBDٳ믿dnΝnڵ{ꩧTė^ziرLPgΜqqq5jԘ1c?nڴi^~{?ܹQ7?O&U{'i& 4Q͛'rk.]wߡZj}:y*ٳ؅a h=TΦC~!44o \v F h®!L 騅Kk>|uݤYgW j/OL5s*,KJ7JΝ;o{'.RD,`0jyB ֋v_I8W_xj]2S"K&%)$Y4gхB=*={BIpMh,۷7"ot۷o0̂oڵOЂVHs]EVZM2eʕDo;wիAA_nذ_]xQ+իWס}YHphÇ2;vx z9sTZ566?~ .]4iҤ;*۷>ںukFH$*炢k֬QOޢE%K1Վ:=z4333Oo#""^yy[8bP8իW(P`7={^|EWA<&--;Mf/CR%j\dJujҝdvyy||S `*7\)@g,*E!Qdz=+jb>nnwWwL d9Jgeo G`+PN80DXڍgfdd@BA`iZBݺuPrsHqFP(&M@AA;B2 k>y$_@t@GEE?"${AsP{}8;#5nغ: Z 4@b>O XB.PPҨ6o(t6lxhe__:`oQTzƍ[UVttHd$܄,։s >O!-ZTF lB4Cv`$ݻC=~A+(D6'Ors󔻹KՖ'6LT.$yr_zvKPת+WS{ɼxJJ&̨cr ($JM-VRzy\]*.:pjרO"A̴A֯_B~p}@,-?#$[oǗiiie<: :k֬-[@^vnݺ@(փ_UctttA_c=?F FEAsGDDp!l?bs…<HӪJ4<< U~ <ӼdT PP ]7@0iа](zF6mMU.n^jiڲt9+[*a&A n fVAfW/y]\Isv6"`ҙӲbE3S˪i5nnZYJ-I/t쌛-RH۟LLL<}tPPPVV^ˆ\["!k]u,?#G^roVC&M0d!^x??<6f#VQF۶m2eJׁj>yWnݚٸqc2y&5kyf6LNNF=ya]v߂V߿9gk5CY)t|Ν¶||2 VZ\;A#Pmҹݻdff ST"(&A"73tѷݽZ]u[u:qK,Bp.L2L0嘓N3Zt:WheL(R=I%lsvVon*VݻWR;Z?Rرc Ȍ,>щ=x"-uցZ 3E7r޽{Pr 'ODb1[UR_}ڴi;t۷;ud{vs-[ Ʒm۶YYYo6A2gjհc.\`Hadtqq8/2""VZzQTTB~Gk׮y`[ax=Wd"߰aC _ r 4˴K"BkԸ1l%=}*UQ"gR]05jI?@h~lV'o@J]Y0J9,'15qʆ=FX/98O"UkjTh2.=]& `U9GեT*{ 1uV['dGL\\KIw ilWLL V#JXjժmڴ>!XΝ,YZ~كrPg}vΜ9M6ׯ_/8(CzBt:Č1¶ڶ4i_|mAA{a)dЦH߮[n({?s{\BWC$?mO.ܹ3`5Tº "##;tЫW/4)SBmwhb@KbӶEͯOZl~0(ma5SՎʥo_|%-OMM-({OoUظZGG W.2kC&=z=-"iSBuj$.E_>kJ^f'Q9w\bb"$ufv d۸ey'O1"y"y9s6W [TuBBFPIII^^ |駹vzWaѣGԬYs͚5iiiժUOk!z:mڴ'KرcժU|ӠA_ޚh4"ʕ+Q\.e˖䍋W^ӦMqtk9&M/]8'ږaGxI~6lخ]t% §O>y>',,lܹ^^^BxjժK~v(BOy1c,eɒ%Hjg̘ѤI<%΋5LǏo &L`\pm+>}Pw._\V-!͛7׬Y|=T f"Oޘ;3vA(?~R}ĵka333%=xV^uօon׮ Էo駟;`+niOЎȋDMȑ#g޻w Ǝ 421yq>!k}A_3)^x={Ϊr`?̙3su֝={61ŰvljŨ7** ?S޽̙Ss!ǡ*qp7ypW^@1 NXkb>>>p^RZl IBBfVx[0ݹs__tѣ+V@Q}N8͛8jԨjVVz k.2СCG{M{RDPzBlllHH|租~Ļe|vD{aĪ0q&xԩGίbO:UpVUbX>\YLAPBvtbdɒݻ{TVmٲe? E1[ڵk~o6bĈCN:...P5RSS֭[s!ǡzގȋBL,##c„ R@&F8/wi}^@78q8EqܹsQ<YMU*UÆ 7߼͚5y~ڵKgϞǏ/$5s=@Fts)J2!!!wj43!\ĊJDA&vaÆw-|21Rq,K )3ҥ2Sqo#2V;Y+WXbvmРAg0Q0Fb 43jժqqq]ٻw[0fVZAy1Q~|||6mB,.X N:D.]ڧOǷ#OU&V"/V"ؽ{' 0ĈFA&fE\#+r/'d^i̙+X{<>V,׷nn}: o'MU,pww?~\bWTZ,Ʀy'\.*RP% :h!yу$$$;ky94#K !r?vݔKTA8cbT21ّ%%%eff;&%ݴR_E:  N%  **2@։AAY  I!!KAA8%2WX  )޽[:&AAQdJf˕AA3!S(fY&;&AAQdJ29 Y  ™i4AJkBAA%@P*FcEZZp~;w,3+J@{6ѕ";sgO=N 7о͓O1IMM=|pll^www]vÆ ˸QȋBy0 ٯ Ycr g25*H? SȲo޽{!aM&D"qqqy֭[3yd9-R" hb'XC xeRƦ\ɺ%~}zAM5I8aۿҫπ-l*/;c Hf͚jڰ .䤥a;fΜ٨Q=zAeHȋE91 "daR kW%ݐe Sv9}G?ɐ0)|;ݣnD_[:{Gח b6]b+J###}}} bbbb<==322233!g!aի|򤤤aÆ9g11bp1K bWB}&sIwS1U] Y&C^UfھwMCWn^>Gך ,8 (\VZh4YX^]YYYt o&;viӦ5AXp #/F8/71:]fd6̷2KodlcNrNB7&cAeУ!f|1(&[n5LЬ  hY`V؅M#iӦzڵ,Ab8:^7]Gd̥ 3:Hd6 3[3,ueO}G7A8|,[$gϞUި*+4+"u:D"1Č**&&۷o֭N`b&&[Gع#h@+3g tQcYv>lY6gFf ja_aEQ@Ntt4>e2t^GvUY啖v)Dyy1qt:'gǥ̜ 4- |S 0S%FrXk wsQ|j JZ7BirNsT –rnbg&!?8}8Z4A0] -Klf41S?Fe_'FcYH[u/e,++!&炼A<&~?~5y|B(C02A=fWIulSf1MqX87X7뷬 l7y2???rYp8ȋΎM̹ZP7̀IJa+ˈ,wm0eZXU1'8 ([neggK$O q'_YY "Rӑ&\ʹ#s A>sȬ7aLi9!b&>#0UDhԨ۷SWJO.RmU,_Z6$$D1!/Fs ٮe2Aj`fs*0i/0i,YA,.WkVem#~xZ\uqXpjժ%JAF1;;[kW=\L|;/J ȋΎM̹,hR2C3[NH 6ѲHϤ-Tv9GW ,n߾VʾAAAPYYYA&\ŢnC>xg-D~XjjFe?P5$/F85bN/dL]~dM^3gRe+G SzU| Oq=ZCv]t5kVϞ=ʾ ¡cbbj֬T*u:WP(P5/ԩS$5իWw޽ze?D^pjŜ^Ju3x>j&KL2tLdR9j/W`R&8fut 0._\PH;ven޼٠AlrBVRi4*V.Q%K/effp%ňGYz1 /pgk fɇ4lfz*xI}dժ#L5`c=YYjnD~86,**͛7U_`T*!a; `s„ 5AX(p({ȋ΋ýXEFs%$dU̮}++!ky .Nab&V,G*0ػ1~֥Y7fR0nz5vQer)(78 (> j*%%ʕ+ 2,444 88XP8aʼnL8*]ׅVe?ղSF:]+VU+H]ep2j`  Bd2AT*h4...J~ Jy1xd*`f#BXpO#WRqը5jK+tQ^pX8pHE UPrhY/\&F^pZnbAJ%RѰYoAj 0eJ%ܴn +VUTYYYjJiQ~p #/F8/7 dDLVؿ[T.%1tǓ(?ԫhٷ z8leyRU*8N ( s5|HDLt B֊?rE th߆68y9e X\&F^pʉU4!KN}$AT*T)&FB  pJHAAN Y  )!!KAA8%$d  ,AAᔐ%Gѵ(uRXԔQ!#RL@BQ{ DyL J2 Y>0;H>;C&F X%,AAᔐ%  'Fq޼y+W\.]oUhXEpk3rꋑvM+!Ջ9*zsV!{u֝={0@?fff7ɓϜ9C믿OӦMѣѣGL4F?p+V(ʖ-[n߾ȵjժ9s jH-ZԥKf csǝ-jSIu)x ӈȢRʉ'`ӧwԩBtҥW^y5##d2uΝ;j{ Aܹs*U^~&0:ݻwE&9vXsRi`` GΟ?1 m0gϞժUshT\0Esk[V_WV,6--bynҲ1ki1TLVWVzz_vRwwwƥձcǪUr)Vp0*2{k)X0vb@%a\ڂ#y1g"""k5j8qb-.]駟 @#Gڵ Ϙ1]RK=t%|0ݫoA߶m":t(d2fnR!*`2WnL0v=3c e%^νASxʢp²ejԨax t_ot羞i,~b8x`\]$ *$*2{1x%qR我kcqWpd1T^YB(~S*U`4mڔD7ne7]\'0E LjˏVowXs^b 嵋B7(G>L@@@RR]]WxJ&\ -C@"DGGo۶I&UV ڷӔ p~8[_JJ'1O_g]YRoMK{mz|EVkץlIܒ++M./ /V)܋1֊H1x/XQ2q5) 2W*/Bgyٳ8`}޽m۶*z)S$޽^{ +V^SN#G|7Wq?ɓ>0 'Owܪ)Ad̏b켸ZSqEcyo]1|^G[? Z-oh 4cǎ:Vr7 #'LΝ&߿N?xc'CwFpE&yZ)dZco&fwy3[ې5XL 222*LyL^cp|[LRDς" ŜO̚5kڴi{NKKSTN-Gsκu{Mk>|xu֩S۵k2dUVqϊrh|);_$Ca;}{;ƌ+j# ;e1(V1~ȑgggʇUׇ~]xT* hu֭[wٲeHM)$$}QQQL8p ի{ꅞB*TT3P0~433Lo_zt;mddYTy K^a̍ +b8}(F>*Ջ9SE7n ?~AOaPę=zTbyOqf_d/ly Jw=Ʋ.7./M̔Ē~$Sc.z{b\ /V)܋ϕ!'P*sb!dYٳ/^4$$믿vt\%'h4Z_"k L& it)?ݻuV'<_He:/f3-Ccؽވ@^}] (>}h4-T/x#*'$d (#fAA%  }RXʿٿ]R'ap dbQUHv L  #RL@BԔz(WDB&Vy !KAA8%$d  ,AAᔐ%  AASBB(w-aɱs22TѾn])8>|866V׻׮]aÆATȋU0HtbØ)Ù5=??CLoaJ:w^HX$H\\\b!go޼uVL䓚5k~ї_~Å֭[k;w&)qelAn4jL:·o2:&L:T-+lö»&6x饗^h,# '55uҥ ձc"3ڵkĈw܁%$$@onwoG.@6lx駭5tF)ɠSz={*O(]//SN.dYCǧ?̳I8beyʀ YNLL K,8qNsaԿٳg<E>rŌFc^ǥDi3g1nf%`3ofJH=YN|х[?~~7,X0a… Kᄈ;m߾"zpVg9lڴ{}&*.nnnP҅ya..._؜H |j*DME\.pwރ_'~:#@^T!/Vpn!kKPP̚5kŊDbh {iD~W="#""dD0/( ĉ8p}1l0 /o|-X~ǎ?sdD>}`8۬Y3 κtR$8}8gLi af_,6/0Zdhb.p>aX}._pRRRudggj4cǎ;w+00͛Ld|6+O (GR]z5j<.Tݚ5k;w Ʌ۶m&UVܹ)W\ٯ_e˖ٳZje6 _'&3#F]W-/E" #4XyXelXXŸ={Z x$<<믿%V^E۷жw]t)Rn޼yرnܸQV[o5yWz;v[/Di%O:w}kܹ]v-3-cz!l3z-6oZn9bc\Y۟鋱y8q8Ei|x pȘ́FڮDGG߹snQFM4Y|y||OscQQ7j\rFPeOe2Aj`fsNTpa&ë}Ic f_fu]6"gkٮ)˖-5kD!c(?@[;w9Ν&Vzux6m |…Cplu^m۶!,np Ww/FDD,X5n=~߾}YL\/j*pDt͚5OAǍӣG »cA:=ޗ1rpVP2ߦ1Zԛ.A9~Sdɶvcǎ3gik@7e ӧOwsuu֭||-)>Q#I&+Wdmާ~3E׏\{F2zLX5m6#.2" JzLW+Av^z7p}N MP\BC 9%>[dɶIеhsFO'ȋ6*<*dVQfGb8o!*D *HDxw'윿1HHڵ-/̙2&2-fϤZ rV'$xyz>շRs 3:m7K턈o#5~x8ԃZg `ڮIN@-ۨQ/:8%o@ f)QLȋ *<*d `ً/%_;F΍T*[7g_`it$I$J&3Fru x+e>OӸj├nz1zm:J?Ӂyl2KdqIddd䉴X_t@;vٲe7o`ZBBBCP) A$!Ş,*<MȺē"/pgk fɇ4lfz*xI}dժ#L5`c=YYjUK"##7~R٧OH+3I|(77aÆEEEOOVڗ̙DŽ1,Y'Qd"ePy4;9J<2hO(Amݺȑ#ǎSTAAAj:))Ν;P}۷ǰ8ܐbDJ/ z)n̮_u)enhV*Ց #֬ר^c\&>Ə"DEVZ\r%!!?ė+ V bDH]Bd벟j٩~D#.`JwWw檕H 9 V GNNNxx8}Q٪ROѸ(AVȋUlHE Gj>>&.hǎgφ ~a ̟nݺ7n,J:/L&;Wll}W^{'ێ=!YjLx"xeT{S9yyBNlv)U/7oݻjժh\|~#&.-#/VڐseŜU>!l:u@^V=k֬uݺuc[J?ؗGDQ^ 5`o=kssU]^V8ݻc_\6xȰ3OYnʈ'M=wN_ *s+XsڵBm ƚYIme}7L tnŋ݃tPy}}}V('u9E{Ϝ>9tУG枽XƄx{޺}?$6&Mcz*J"8kcbC]2)#/VseŜSkڴitt+Wj֬h`L\owǿ˭Z_ɜ˒ŸTGj׾C*U9a>~?+O)JfCԱSӧO[VK7DTF LHHP(0_7oܤIU۷/O^8߯"z-E R=Zwdw iaYA')ʵhKXPZܰQ'+.T7熍Yz5\6&F^!/(؋91}ȇ_krݻwwm۶}W9eޭ :???OTRr'@?ƨ$5o:O67Ābbk֪EeEykuk3Ϯ󸮮pQQQ:u ~;wNF7oެR lMm۶Hy^({l:yzBbFq1Zx%%DI|["W見Vfii^^ӧUؐ֬gyR(c/N?]6.\׭[w̘1F}?Ν;wmƍpELs7evb6m>zg$yĚi#G6t\.W>3gfrѧU9 dϞ?TJ:ӨQ-Z$&&nڴiR444? VdiWիWjhu8&֮S7jj۽G8ϜoIoo:me4<<$R ˽#TjM^&++ Y&F^T!/(؋9EDV^}ǎM jٸqc=0l׮]+;\^76cWPGvoPPsWJE&.F sx7kzw`Q{_z`1 %APb4!hM5&䋉\MnL$" ;6٣'-}Ι33gyg9(,,̌@`` dy) /YFrx؋7wCnխ`!֖<^[$x"mh)S@͝۝MFY66jXI B(,16@q\OI~P$٣'s Y6 fJ)$VPT"IJ\!iljJvMLb@A`Sʕ,..O(@b* 1d`.2pH;T$@b*gd\%C@ `HL{S J,{rqdhy#S %K F+aoܳC"HcCCGR&x!M@#T$ @b*Db9r$x"ڈ-Ogv, 1i Q`dxFQu-@b(HLK ,H`dF# 4YF'555''GյO/\ 1\ 1 dRUWDٽ;.4t{ΓW S!6%K F6oQMHC}-?-xց}e5HL@b$B,1Y T] mG PĴHLU(Yb0@<Uu%,-nZT$-@b*B\VUt HLKTJ ~?GىML-oI4GGG_tI ̙3˗/OKK`>Iq(fF5j_nY̟7[c/ZT##G455>>>~$Fx*%%%&''/Xt&$аk綡~>>7o7AB1bTc*@ґOi/"1bEVT<;d~m'P4ȾYYY{^~='NMz)f={Ȕkd^<.O"YimmIK; \ Q6%%י3g:::677ڵk޼yb{X4t=44[nm caaQSS|: ڕt^^z< F 0ΦJsu0)v$/%x'UA%F֭[;w~:sƹիW_vo0a;/9[oEJ9u?bzill\RRv N%EW,ӭTUU-Y;}癙\vƍ۶m1ѣW^oC*>3f O:D;*0qDMիז-[ƍ6Bw]^UYYV^kF|k|iJc3gҾmL1~^Ntuuˇ=87lJۧdFY:hoܸk1?lذBRcǘ륟4$PJ__瞳>N] T. ׭['.Ғ2]$_ j=i+1&&7n\rg/_nm_Tu{dJN>6cRbU9g[X$/^QW \'˻ϕVV߾}+0p\9vi{osQLL{-2r؅$Ķ$f'%1b-:uħ|_ko?SOޓ`mms ; g1(yT#KޤEc4+8OaÆUVV޻wOGA3f=f4$YDא?_z%hxWWW?/Y/͏ysmmP)?Q 9;;S7wj HSccٸsg+.Wd-5ҹ[#+^ (M$1."gGу1rd}il RŅDc''f( Ӈ-Yao޼x@Q2 4HӰUZZJn0_N)ꯌ3th`}.L5i+(ٳ"#nڎ33s{ uu6*p..Y}SSGԏ5뛘tߛ[ꙛRC[8::ܽ_ܼb7I,l^[P$&Q3,1ګ}e GzͅrR 7.99ٖE>ӦMc'N8h #㏋iY8MRYرcP̼yHCW~"##`3=HZcs-^ǏGhL6yÿ^ҽ lي%/GQ@mutt_$sƎ7zxSqj`g+Lw,)<0pTEжwh4 GɣY_#|;v3{nWaiep-|2[$-=w M} Mj9g;ݾ}[fP bģǙLR)&6|Ip9/ΣyބCllNqZě:&VpwC:\J44Iv#Sfffd=)FDNUOT /@(sblll9(ْ%K(͙3g+looں9a EAc'tmS9xM7m[die<}sJچ N:,{~adG:6442>p [[+yܼ"kkYlG%{F>|0s%˄SWLC[$Z]]mmmMիmovʔ)yVf`JX2dYQ-$½-s=g '>=0KV& )*?ں윿{zC$&`r%uFVp~ىXZZ2wԤj8 %DNjjjGVĚ $4]bŤS JY %˪ ?]$x=Y@b*C%S8# *JO%@bvJP`dxsYt*Ǒ屏4HLU@bZ$*,1Y //qh# "II4?@T$ @b*Db9r$x"ڈ-Ogv, 1i Q`dxFQu-@b(HLK ,H`dF# 4YF'555''GյO/\ 1\ 1 dRUWDٽ;.4t{ΓW S!6%K F6oQMHC}-?-xց}e5HL@b$B,1Y T] mG PĴHLU(Yb0@<Uu%,-nZT$-@b*B\VUt HLKTJKkk~Vf``0{Xl3g,_<---===::ҥK.\xWϝ;'S!!![ff&OglZv ϨVT<;d!uuu]]ݢ6~^z_9~ⴔ٧_zkŲc)'#/?{LLJ \Ĵ|;IZ:322iw700POOOl >|8""8))i…?}r&n"Nb vn֦E~>{NH9+LJ敗 CBfxyH̟R(}[m$z͕:;vW;;;tL0AR|eA #,ERZB7330LkH쭷222vˋpptfi=eJ]n~TsyGS::gy-H B(*,1M5YYY4~z=' 4qY':tZiڵ'NdWΝ;777ƌj4]bҨO4_|P>4!N.[|~ьz(>|XRRg3Rk˖-ƍS~ɌKL sՀȡCZ|<ͬex5T+W1P_߱ILK1cp]]ˋ# hr Ȕ;6SÏEK'7VTTܼy^377'PЎ;};wFM:"s&5**---4HSVcǒNݒC28{P>V  E3\C$R>$dKKˆ^PPܼyI,dwo2{v+^^禞L 3'TSRGGÆS+/蘖U](LO>_H[@Zž600HKE=$QL`SʕYX>}38::.XYt?}u vИO?۷TFԭJ!DY~= Ʉ0 9s|nܸu֞={St4HSow _`b/h3ʾr,:wc#677yy*+/]$=mƠ1c8/--ٰqӐ!&9z̒ 4O2|93nŕ+//8y*MOOSWl^OsIbE4t!MZUUS7y#ZDډ466&y޽{ N>zhĈNNNni.]Zl>S322;|H$ m%Y߿gϦI5 |2E;,J94:9t?z,_9|>uef^nW^MOD{$VWWKߣ;S͘bLYY YsY嶁j؟D̛$$QL`SJ4M`񾾾7nϜ9CVI 8O_ݻ&{yyIz Sߦy6]]]IdĚqAܥ+)좖1Nj߸q}။_~ٕ} ϻx|]} 3x 0w޺S))dw~RN~~Ҷ^P|V=P @q,Y%ʼU.dooO!祥%Gdgh]f&*e֥LH kMM -ix @Z &&&2f3Ia]]]}֠+sIiyPMs5.^ׇ]D={:|Ν! &&o梈h!?l`.P9Ǚ.,-(wrr waDqn>lX9PQQIY:t($$811qȐ!nnnNNN2ѡ]„_\>yyyRC+e7\`ѣL>$Kee%" n3f߹}Cuuiٴ~>\\\ϟ;GvTW)O__{x 5ɦXYYW4hIYQ8wѮ?aH (*}]&DٙtZC(q{ ^ŗ/o׫~q Am?7ws* 󋌊$%f*,wttJ;gݝKrxK|/c'$=/{33O^Whnݺёw^:-,,=zdjjjmm}yWWנFrrrH\Zʪ6ECÿ̈́NbC HT %KDeeׯ18웙+F K ]Nkك GGɓ&T:y8RwV\>;tA$ii֒ԾSզfȫ67}~BKkkss ?NvC{KK+9 xܺq$I,t|%K B(*P)÷oߖk[Ueeeu-d>:La7,tEwРg:*{1yqk2]$&Vd "1;ɏݤ.,,yCU 008991|nϘNMɾVl>(z}2)i6lF*l*y) xLRAGoN~}?biÇv>c=%fn^mYL.bNORM+0)b*A`#  OE S*g#Iɜ.jiia"ɹ2/ѷ$^bm#[P}*E͑$l߼4Ok+^n֖;ϲ [[WǤ.;~Pɿ I (b*Cђ 'Cch 1iJP`dx0U8]@b* 13@M@x!T$=`%K FG=p@9{]HLU@bZ$*,1Y //qh# "/I i'|fHLT%# 0rHRuEk+ [,Y@b* 1dZeP(# 4YFh$0@# ,H`dF# 4YhMMMQu-C2@b(KL,UWN`֭'U]@W@t\bZgdЕze!1ЕP(Y5 ,H`dF# 4YFh$0CK E=? $P 1)%H F襪&{w\h)5<&P&@b@z 19P7![TSH$oi(@br@$# :x&#}bV?@b@& 1YQ7Ȃq\UWBb^$&+ HLFMb0C`.++6j$&+ HLVMb0oٲEOOillAӧEh6mdz̬amC||217o(3nB L:r`ɕ+NH9+*1-NRVE%@b $$&3%1Y\ObSXXXԴaCCCuVYYoffP.Wx+v%ݫA[3<=}=6%:T[\\dogC%Ld_ґ eU$&%@b @bnHUU;; .^x]]]##c ?};w{GFY\\B}D]]ݔ)S(Rw@#8mSnݚ6mj6#;zd-\~_8۷23/a66mx#Zέ4î ) yL>;LZ*ڹ3gNΙwdMwm[7JJG#u' T@b= HLVLb0O漼 ZZZ޸qcHC3`&ݻ7ŗ/]ښOsss;222"""JKKo>f̘WR_@=Bmm6U.w _b`b2oܸz߶C48gα^XX{o$WXY}"[T:l?7?I<2@b $&$>`dųaj}:LMMGq!RUMMKss\'NE¦îCV WWWjOInn.͌i)eРԍ]b`c L<ŕ9(kll8&$]sSÂZ-wtξIɭmGYi~~aiYIKsu'c/aQÇ}ML:*ZDEe XT  sV&£,$&-@b @b2nϲeHL8鯡!)+|0t 䔚s-eРA.]UK̷Glc}cRSbϞfrW9m W]S&lZj?nn.ϝ͙K$_ܻw_===DiP/]kl @bR $I $&+&1YTpg? =zTVV2KiJDX 5/GiE˨?,))Q= ;D^Ni(((o˽3g;8^|YJ;'BBGGɓ&T%9V VYU-uyM OsFu HLF 1HL* 1Q7Joll,i`>`R?@s):fZ& aÆ0+++h~ܭ[>1ڽ(XZRdhh@vC;M4i>a7fnϞvmfio@kyt!9::׷r$utr:l8Vݝ{bu;WMF,WsƫI$&HLV 1I@bbdE$#+ɲeˌE' 6l9^[[ļTҒ$mff@f)Qtt4>,((4i39S6v.5744]D^I<]]dkk1WT^^̝ں۹߿OfclOPW;|p#CC-psf&}za>ձS)Z|Ee,5hHLV 1 1YdB$#+jwj|cH42(]J춺 SAF5El(ipld[?T<Oss۷n+VI??LReW0{LI{D-BOIC@b $$&3j&1Y&MMMxz$eҨZ@br@$# gȑahVҷid@br@$# :H>]H i:0@# ,H`dF# 4YȂZtYK)H @b j 襪&{w\h)'Z$&HLMb0@~HaH:@47HbӂgQVkɁI FtT] MG P 1YĀL@bnr&нHLV 1 `dA\VVm. HLV 1 `d@~ҥz]]ݾ}镔$&&.\P u(**:uTyy9UiԨQbS&''/X@ON>|8""Cm;%Τ8Xʜ23ܺ@ͮٳa:^&UhUT$&@b,@b2^ñcǪfϞmggG={RRR&L,֭[uuB+ښ@%4~3**J| i2L(e(0}t\ZQaݺWV>niyT2ũ~޽ϝFnE5˪HLz 1Y8,@bn͛MjkkI0?<,MLLhiKKݻiH;v+E>}Ν;]#G,..^d43i{H̴Vffŋ)`hh8fn:PHLMM)v֒kר4'L[IKK؀\CihlmmiNSdKKˆj 7771%Ínݻy-,,Ancc[UUyn◗ZZv+*.onnyv؈GvݭK+:S b$)H I FV:IVVV4ev)ۛOG;99Ο?Oj/(( GFFDIE޽{SKZ[[2-ZD#GP@lJ`%..^b7 xܸq ):///$[sK:wN5jH=G1QzZzׯ/\qis8mZ}@zj ٳg{4 ̰<;ԉ.55sZXt+,,8|sZY[u{z@~#987H C#ܢ?7?I.8BbB 1HL`d ;OԦ& ݩ# a_ĉJKKIx4H M%Io)jjjGeZz;v0Y,R4>>>4}ann. ̙3bbW:^zP*fLTC"JCh==z&ьfbHPRVƂiH-r F:::NS5545IuIjy;oL@1l.9BbB 1HL`dcEE+_* ;#<  FsTf-}}}(dtƌ\+++iI} 9ggds_{ZDyR-M7n5m[CfL91WnE666?${{3iulʆԒ1 Cy.ڵg6%GVA 1$H 1H)uXjNҧO{3HLJJ255%9R4=5]]]hK}̾>>[ň9jԨ8IP.O~٣GOkM2Ύz"ѵ IaÆRͧMFPϲaÆ3+RQhh(Bv^=A0 316n⡞'57466>nɉ4v9efꬤ@/B, $Ɓ 1En.Mhzj``LH٧eXXaf;>,YBS3gΰ32$f''ٳg3QGt.kQJ,yR'RL )`0ժo߾̊ Y7V0,J;`aN=H(P5441r=%TUה]H i:0@# ,H`dF# 4YFh$Zgdn n؄@W@t\bZgdxPé"tjMH t% 1J%uF` 1 $6Y ,H`dF# 4YFh$jjd >:I_ 1SaFS?H N@<jjd9 @@b(5,H`dF# 4Yt}#/ jJ\\\eek!']Uu:ɓ'WZuEYYY111֭c^~5kְi$G[lʝCBC 8ж  8ж  8жDF\o$%<<<::ѣ OOO>{?w\&2+ O>$%%eŊ;v]VYY+̘1߿… ϟ?o``K Va(FEE{IIIbx{{e~'++Ν;nGvZ2k92x`-3b(`333cPLϞ=LMM)fѢE'N_<>|Ȇ_NB%A*@*@*նE*,[ ׳?)lnnN2yЊnU!;q7@*@*@*mQ#ۻw]o߾L;wxxxOnn33f CxkN8"-[spp8eى|؟Nbà JNNJti)3y V=|(loܸu֞={Ǔg%#K񇑑׭[GŋH;; |JY#),J.^7n߿̙Z>>Ç$%%eŊ;vxjbd3OM<y7{、$i@kV:N@qׅ VZf͚#G Щ<) kBΨNP:tIаr~ ߺWGăVhWbCPhXšڶ])Á# 8O2SN=y=J@ҝB7$dR#:LU^. Vz$Z+5I8AۉtA+vj.C аmAd3_~%X_Wϧ7n:w0K{e]v#uCh vv@?~~׾Æ [n]XXXJJJ'VNVp_, ҟ|m6=쑚Ўe_.lF.bn-))jLg3UOB0 ]ٌYUUUee%=\A9puZG9,]]`DWym?g8$!KkKHlFv˅Q$ׯ_UMvpVxjT Nqp [6ohl)rd3dd׮][[[߿k. *R[ 0[Gʷb|Sha-]{Ykf!5kֹsl%dsΝyu׮h݉|Y)E 8BqV\:V|m?O6_~9|qq1ѣСC.\8n8ETQzpFˠPAl;X򁣕XX!pVQMZ*@ldQ|d]++++&&&##cݺuc8uo}޽~]ߟ"ׯ_f6޽{3ٿv.!G+=*`gUsa*ĥ[g:{ǂm;,҅+$-өwu ݊zh rX<OpoƦUVV+:::3f/dXRRRϞ=/^Lcڵ7<All,&LhV@6$@|4uBh-c8OSѣSꆜFhѢ'N/BFV3 Oud%7OC׆ZX(mpYDbU( mۭ[\QXv6Sb~,v+DS m( 9BהL4=z9:Vjwz-BL[n JJd3gّ}1bDƂ?EEE֣SPy<5K?O =p_~yFWWw„ ˗/&ìr֭c7&ȩS~{oڵΟ#lFvTō&&&>>>Fzɭ%<<<::ѣ hIIIXXG}uĉs璯$en(yrqq*++_y3f|_p! ))gϞ/رcwoJPEy%''ۛ}B>}466? ܹ*uEFNЧP`ѣGIII&LHOO?vؤI2kBWC$hXŁUhXŁUhXšڶ]H*4bٟ677LлwuEGGSo߾/{$=.'dpU6|C%aVAaVAaڶȒOxaaa ƏO=9sfpp* UY???M6}< ***ʆ[o͜9Sm۶|O?%66Ɔ?+W[n>߿||E;ڃF .rlLVVVttteeeTT 4(99Y(ԩSlx>)sy4| _5tk׮_DiU4k֬ d~zyy_==wyG*YYY111d׭[7rH^z/_d~z*Mwޠ IEAN#;qC}Ν#ح[C.[,00Pl2GMHH?~zzlhhڰaٳ/^8uԀ~={ߟ;w.V ._LVYY+̘1߿… zzzuS)K's'$p@{Prrr/x}L@nybbbZ[[KOO;w5jڵkSRR9rdJڃFVM422rss#?ky]]ĄbW,**gϞhѢgyfȐ!yyybN8/Y) kBANAC$hXŁUhXŁUhXšڶ](\wN>#x֭?jlzhBB hCCCTTԆ fϞ}ũSOR0ڃFv…w3E+JZZZee+3cƌ~L zzzݺuCF@Kj S еa|ӧOVV`rn͛_zzz@Jڵ؟&&&#(22믿={vjjEy!CkBWC$hXŁUhXŁUhXšڶ](\wN;#ښnݺ?RB.IasssGݻ9s8~l߾]JB7$dw/p5 B\Y04sJ B3L{)\%7eDԒ&bs);ggt^χ}||z>%{ZMy^Barj;T W^N,,LX̎.iS\\,622 UA688_~YVC)77733ȀyxxSN999+$$d׮]NNNݼy ^UAٳt?7_yf\\ܜ9s6n7("Ѷmۂ"""i~hh'e ܹs֬Yգf}S /UV=z {-??? YꚘ(33))I2ݥK黊!T*Y[[w)22&&&L4ڽYC |r??5kPwM(Av̙[n:uXB\:T "hv)ڵ *|Jzzz@@@jjòe:w,(I&I2dȚ5k(ϛ7O2s޽ .bh@ա-,,;~x||ÓA>cv:--mر4M9$$dСCkN@ǩd?>ucǎ={L,K?TWm;w.//o^^^k֬9pȑ#% JDAAY[hAw/]TZhJ3fO Waٳwޭ|L'''Hleaafܬ,]tYpɓ'i#Gڶm[ޫ`h@աb=x FDD=˗/)JSh|ׯ_GFFZM6w9M>}z֭2AVPf҅>%;-GPXAaom}}}x|ud Ϗ QYov!Z6Ų(޺uK)ed`g?eZMy^Barj;T  ڸqÇ5jL{ggLX^jo%ÇwT0… >}:ye˖Q544T,222 iii4ԩSvvvNNNlK-=۶m>>>G=vW* PuT.'v)o"hPPPDD}tt5 MJekk}YfM6訠{xT)=+{WWDIIIiܭ[gr9(3[ly zZfNnP M{WdC @6r@AF˗M6o޼Ν;Kf9sfܹ+VhݺFW9o$*uBg2-LW^-^8!!A2Rׯ?ܸqcMwRY"+CU1&͆ P zrAo0|aaacƌΦ+WT~e˖I_%[n4i!CYR}䏋>>~~~Ǐ>|xrrA}tZZرc,Wau$I8+OAKE15-  h O<ێ;?^L}K;w\^^ ֬Ys#GJYfhBɯSGP[ WIkT\ҧE催ųg(}<+577W~iNNN/m޼yzzz-襥3NMp ɯj*`ԧOh+KAxVכZ~_oKP ~*,@.6mڜ9s yfm˖-_˗/)Jf_\j$JS+9<7[Yl(d.@2Rg4"]~qҵ[g*\a$OUʐ3KVl57m K`OmAmׇV eom}}}x|uU.Ȏ5… _xݨQ#Xڵ}W.RehR١CLLL>2Rw4\?Mf3`?S믞,X Kҿ_=>eWs%5*CA+ںErAȯ@p;$ZW%)m|"j+uD: Y|ly " C=;1"h7MRuh V^Y]Za7V\g\ xD8,PZL ҫ k%^), ~_e\][!VG}_ːo\^MOOHMMuppXlϠ3gXZZ~W_5\bży$mۭ[^Bǿk"*Ox$J_5Z >>>~~~Ǐ>|xrrtCڵm233RؽpBHHik׮Ut0Tθ>]pg~i)Ȟ;w.//o^^^k֬9p׀Q` D... ͿtRjբ)Θ1bY2!FKA633I\͛7OOOnpv}111mڴʢۥK .R}򥅅䮙͑nD qqq׮]?~M׮]ݻgnnN |}}O>uV x }K(,wP[Am9rR+]n`bbR^PnԨщ')Ȳ)մi[n,YɯKC Aarj;d333b1; ##[SaaUÇ3aqZ nnnfffLKKN^TTjժ &ܸqc޽;wlܸm|||=z1jRDG"""i~hhgpp0ܸ8Xxq:uϟߡCj}YfM6訝"&&&LJJLlAݺu;{/{n5>Y(,wP[Am9rU^}Emt! yd@/U oIdyRzֳUGGAm9r VMU1@ABABABABABAB|JGPXAarj&Y$Y$Y$Y$Y)**͵#AV\ӭ[7KKKW?jllw_͓'OM6#zRE"իzÇ[lI/B\\ܠAakX, <~Kz}{',YknnNESzj;sL;4hwb)iܹZigϞ};;; )+VҥKq㒓.\w_ A[RSS/^klٲgϞ:u |>}߿aÆ|K.5%%ի5jXhф wO:7K.qFRRBCC׭[w􄁁YV4hбccǎ1;^#TڳgڵkCC? WӥK$-ɓcbb<<<=0jz .\@)Μ9gϞOiҤ]vY!)w>}o^~ӧ;;;ѫwTgz 6$$dtrE`ǎҏ6oޜ_}4Yɓ'7lO?Z_3{3|SSS+$2/h@']Lxrߝtzիe$?(v5kּ>e?>Y _H1c6>>mF;_ 0PLa=JUCX,رʕ+E"ڵkCCCd+cekv-ZHWݻw ȴ寳B"SX:PYgϞtŦXt` Ϳrʇ~ooE6mJKKbS, ~ !"3pUV|dY9(?҉Z322h嵏ƒ[_啗Gً-SzNF-1xKyeÃlqq!یNjx [.))-cDzs^xajjJ)>CU^3gNLL h&bAeY[:Sl{{{! ŪȲꓯm~h_v|T0k4_8uTÆ c8q] [N6S 2e PYXXԯ_&(̛7Օv;vHHH~:l1cߝ2 ѣ{̂:=8p``` ߝVS{.MӞ l=wjk6mژGEEю;JA$ڷ=zTzd|!O{^5j?]&%hwN'S߿?6JiUjjE<<Iz|!e~`K ;{WZYY[.;AJ2@ǎiHQPf͚ݾ}QҞU}ں)Á_dSf|!7Ap(זĠo)K*,,R*-FY-wͫt:ERϞ=?p0P5(,w*m~~~nnNOAarDAa---1pS Ȫxɒ%.☘[[[35a|aeQwիvĈ|uUXPXQVdUlٲgϞ:uN/_ާO7lPV ej۬YL:(T(,wP[(SX T je*tҎ;د}o^~ӧ;;;Ϟ=wt~Eڵk%Barj;-_dEUaaavQi^zE++xuqʕ"PvMj$;-GPXAa AVY|͕+W._lnn{1c~K*~QQ;-GPXAa AVY?éS|,Xjժ}>|)S̚5 Ԗ#(,wP[Am 6mڤ۳w'NHC 9~xvvv h5߿?;-GPXAa AVY>>>m۶mР;V[xqXXXff!>PC(,wP[Am9r*wy'((h uagצvOPXAarj/Ydee5mӧ~}lmmiG1[e(,wP[Am9rl?~ӪU+H3oҥj?~I,,,`Am9r V *.. ٽ{7T>|vǎ49rdNϟҥ3g]{+ (,wP[Am9rM\*99ի5j ۳gϸqd899mݺ  Ԗ#(,wP[Amuu%%%תU{رRXXj;-GPX eaa~qvvy\]]wؑt5pXve |Q Ԗ#(,wP[Amu_f͚FeV?ߟ  Ԗ#(,wP[AmulzzzvUfesN^&M4b~;)D(,wP[Am9r}%<<<^~zj镵Yf|NPXAarjdKH>,C~euAm9r V!;-GPXAa&2+s簦j Ԗ#(,wP[AmulK =r Ԗ#(,wP[] "??27oĉn߾aÆhoU,,˗罽i"%%F4ajjJ111緟 A@Efh‚C)f͚ bxxxԭ[ϝ;755QFb8<<<++ٙ21uAEEEK.ݶm[nnӔ)SdgȐ!})..vڈ#ho߾FFF7n9rdJJH$:uM)믣Gwt,LEɴLwMLLBKiA A A A A A A A A A A A A A A̙3|B;w͗_~I֭Jm+Sc," NyN:z:KviN.67ùVs+-@1yaya9X llwG4oӆ5t[aݽ{w^^GnQЀ, =^bƒ6CJeANjacdA(z믿}10alAGN]ouk[|PZRy`+CA! *oΦ '.w/4O/(`כ,Օ6Ν;GEEmٲ}666Y! a3a% Sa0 W0Lۖk㳳zA""NHed$cÏ[] x0!dKinm}KO9fuN+*..sJOpd߹m[7ծ]+ll/.4}a?ٸa=Dm"2ըY3|nssjnmTlnGG'Icgфeаy[Pҥ EGǨ(::ԫ/dM2tH]:%gG5jԠ67nXj՜9s믾0nWRa35YF'sf(\ar7>PTDlIeڗ\zko7o$'_ݛ`ll:re=MLLMeE))ר CuQ֬.yA@/'~D{bf͚SI3g~޴Z>.]gϮظ!3>_LOٱ+zׯ';t9##֭[/_޶mo֯_Pkkkf۷ WLNNn޼1B5ۢ7<'wn=#S5?M5)V⽏V⇩t!Ȳ$;6Җ-[)VO>磃z<øMf 0G&t\h,@N١O?.,X?~ov+W.|Z~U+W郱_o]_Pҭ]6M1֟zvZUz=˩+=}YYբ^Λ7'#VRiwb͠Co\GoO<> 3gÆ_EM6laR7޼yɓux&}sǼzب;Q:m.( +F\ئLK)n#=@ Ņ~40 $4###9rN c- 0n|dAYa/xtnkkr?~>u(v׼EW4mDb҅g/^<3tEK떾c.W=jԸۗ<<[ MHu9 Q} l?nN9˗;w455uu=4__~ĉ-/^ئMg322rss)=|p̘1vTkRV]>'EYXXU{ɛ^<hnY[)5b~k,'9u06ǔ-x۬9Cln9nnntc?O4f<,WR egsrvnQEE&zۖ_R#}n[fuJh[SN|deeu&«g/zyX[[o-y>p9|QVǏDf͚CfM?FŲ'~аQÇ.]Ӓ 3owoaaѵk7 ={O/w#ӠC-]Hv3l!-6b72C v:[016+]|6qգ`hhؾۈzVKk%)Caؘ2yulܸ1 @k֬9nܸ(6ȶjՊߤI9sHzrʅ 255\fOaviϾY1lM+?٪@g\kɐ6v.?󦸸ƾ{ݾC27(wwwZ{-?W/osXd)>y;Fbb# =x^ԋa.0LҏߒF/g\oz |}Wv7n7op=9F)V~Ve+և$ FNԫwF:{w ץ#|23xRK0?̜٥hӧ=jVJWWViiBvڢ@e^D"W wvBAҶ(Sedd7)Fln)))uYJ0`d)"a04!Ȃ5t^P| X,9dx P1G?߽Puӭ-ߝxVHS2wRUDY8. ghb竼 XȠ3c YΝ;3hXM Ie耪#1TM%:Ikf)xk+33sϞ=cƌa0@R|֭+{N.f܃NbmllY86b,Czz}$)1o=2H۷o3FAtV)1l544仓~KNNN"6"NZ^1oU'2"qrr1c kTo}YիWK͛¢| <ċn^40]5#Us+zscm؆%L'2ߚl@3k&nceΕ%ɷq?gHߥ0fIŔOKfTHdLDՌMLLLMML8K@4IENDB`sardana-1.2.0/doc/source/_static/gui_snapshot03.png0000644000234100017500000041242512174204305023605 0ustar cpascualcpascual00000000000000PNG  IHDR2m pHYs!!%IDATx]`UHB `/wxo=;ٱzгb,4Hh ޳2;vfwv$z73o^ޛ7޼صzaO0h䀉3A4y3,aaLM!E||%{3Vog(Ej*P b"f"Ro2#PB34>ZL(Z ⰱB?*JK*Ȃ _h4+"K ZX~EŠ1jW(ZL}x.E(!$&bb >>+*RSg3іa?0'&I!|1CL?Hαg1lJA;`ʃ*:$ɓ # %ۇ aV j'nA39 -Cf@rHIS"[#FFƘ"9Hi(B?x8"! up$‰3ΒH֑l7#CqȉtS,i"z7މ-ʰ7\BU\ȟ܅C"2(\L9q{,rtHc َ=;\BبfL"2Pꪁ1E)ZN"2R̽`/3}mE رcF\  E{^-z("h)$h k餃p2e*44ͼ[^:H3j]ʣbVw"8tIr~Үv"');@YòewpdB-CmU=CY5G=s]o x) Sj)] dhpAp]ۋ@>R(B\'vK9aF)>ZtSȬ 4L#N w&|ר02xhBcKhs\!1OKW! HBHYΌq 8h4#6F21Ep lH[ppԗ:6?KdV,ó~t.@%``3yq >X"']?ȑҚmcå:tUC f}Y[[D~hќ .o/n\A b A#m^vYXf0 #KR 0n9퍞ldXtjJ{m8q ЏG\$=0MH$YR$QN+WW†u%_tN ,u.D)51>јH2^hbKmfnXHgs^$@1.Ss'a^EEhEr8)2|'*hc8f ۹śGLAur&Clڸaʕƛ12,#)F]FF/p4Lu=|%KB6t.+<spO|H. ~رV|-aSAndFTPR=yɠwC!~psk|V'[ =Pb@_P#ǽThB-쾠Zcu=\`&0V)|ݏ 0_u5{sClWsu (oD֋œS8b|NLlʓ_,F glp*! J1Y'Rc։qva{ R!g̺NߞIDn"Mfa9.i3&SGG٧Fh?A+R@d] wl>/L%d$b#+şH.g&g , ꣒l2`g@hC %Ykщ68"9AbTPXelZDaI(#0'mDx':-/L,7'F8&(F&/䐗 1hGP`QW.&Ƽ5-pE@HQy؋tD݀t*_-VZ7h?wɹnz]+hYInS;捵ymڱ)Vͨ6t]hB`!h8hz.C"ʀmLN)pLп ;qɯ2=z5Vd\&(@rZt23NLDxJ@5})qRa=QRpby O) A|0W$ ҞzFԃcDNf@xQW%Z/8VE)':?Bivl 8\c5lG.ICjOdzz|H65Gc(oŖ æEX Mۜu~'ttB|+;VwjR1r yKrZ!HN02 $`"4TV:]I8fb dfiw Io屬a#"Be˖5 mg޾}ۈ# 0]u˗/OMM?~ {ǦgtvvO~ܸqPĄZzp煃S^W' B EO-1 bO#ci J EQA8#`pYW5@T9x2)wq$"=A! b)_ FLn:8,crj_ȯ7QboM"'}54t:8ρ]o&G&Ck.k׮9vM800W-󒯾ͭRkkkVV)S)*Ny %8Y`ԅ&#(ӱ9e!9~0slbg$I8a4:얤$M$ "=*B/G1ޒd‹0 =pj yIIIbɓ'k~O?QT 0P*tp޽^xab1cN0q<%%% M2TQEf퉨 *'(]NRO'B,)+,'> C>=Q}^IH)v3fDuQju.//OLi4zɓ#GLFB &NL?##袹8͖sСCB>"b|dN dð*[N3?{M[${:(ērɘ7IjuZ0_x4qm %t%'\#bO<ҹT` a! 7--4:jhK^@.Bqr.GO B#[ cF] 41 #zKpktzAUqh}a29pih8ZBiS]]5lp.ޒ%KMjO"DM<~T$~t4-˵6(A<$n 8c(lnnRJdX))&M<#U!B^ZW_9c@ KUWW䶷dR6nn_N q|)6m,**jii?W "D[A*+)rfЇ7J$Z{I% "\׃{dɒS"D[y=r'Ÿ )~o֒qIb-i4 &pcǎ r!BEd2JJ>xK_gze_"De@#R0RNc`  d[!B"Nd {}X%"Dqs"Rчe TD㿙ﲋ!BįI_T׷q*C"[C%&$v(/%1I "Iq9"D =tB:dՎ8;uڨR4~ >KIEZ!BGRv'B"DB$n[d@g>1)Rnnh9 'HI $R9ㄔRz04!Ha%cF*S$A+(m^D"XA>Жlu t0C"~chP`tRAgh奊rijIVё r8?~Q5u-AbLT 벮걼.G{K}^uҜv{pnxzϷAM?\}?o 5(PWVሬ\ ȺCl *~*3--mѢEӦOOOK**n5??'d<|p=޽{YUUɤRH  \NgVvvee;Ϙ1RAe.++#%%H[֌ dff657+0``0}E!Dd*-/XsR߸)Tf$)LeR$;Zҟ4Sɧ8ix٦V88+XN@ H9m*mաy#mT"UrY+~NIKݮ38͉y_n___޽W\~+L&L]}l&Irr-˖-h99;w;v,PLMMߪ@0'Cl߾:t[W\T*vDɢ쪬dXYU }Op lݮn?jgw6=b9v0+z쑖rJ.Y@^Gwkwg!_FBm)W lCJmnoLXuqyknZgn! Elذ<'tY?9ΎW Rܚ rd@z}>Hؿ1pѸ~j`ozz:D؝0 @;% oټ`4!Ie Flq"~C`iI>F.ՊTFQb( , xJp̨So*)z\*ښ1š78}-ruaSZ%CfX]2|(S9nKiYǟBSEM3Wo8-cf*5;s挭[Z,+bϞr٠27n,BPk4 \. xlk7o2y$FS]}xajU͛7655M2yΝ͝{сgϞE}PJYYa7u*hƍ^8trNRQ\^ 0a<@K#Go)V ẅ́!B_5»Ђ &T+Pnת$ hsHdL40;FyA햋&<0 ϴ<&Sѿ:gyTRa%B"NBB>H-ujzN9wS8;bOCʦ@GÓ6mwPRR:+ 0pر:6##-.7ZO>VMӁ@p={"DBwSr-V2ȇ#Hr f?Inp?lًcX-c](h(CR"&ϩBZZ܋.:u!BiA*aJJ2v?UÑΟ*dd@VH P ՑƶTV-I%Df[:QTqV]f>1҄~y"D F#f q Ҡ(^ð`}7Q 8G8T5fEKѩ]ba V39Гמ"D8afV9d+NUF ib-{aH`D ' ޠL+"DqqkU3FOR izʽ Bg};v;E8!p0T ~ccS^^.Hi&gȐ!MMMiiiymohh0LjB؟0ZE~qntjUhOT'ҙ;}oFQ&=s)))I=wqǞ={No̚54iLoȑ#Gl߾W_| L`֭GSUuH+Jo޼YRUTTΆǻdҥwy''\| 85D H$#,E&DmjlIqì|.\sݼi)8=ztgg+,N'OOOӝvw QVVeJ P@˖-:??B 3]8٫qzFFYi)ܻzwuuuZPP  vL}}0~By  ^x%ffC=h4P:_-Y\~Ӂ^5kVOMՇ û+)pJiyP766>#@E d`onf裏u{9p{Ƈx;|wVZU@ٳgs/4O<w?yW7o_p $=u?Gv9r${V: ^!C}@I&ōmB;:mauRBUJ%ԂBu /_~#F5 3ofذap rn޲eO?̙3}]`P`7ܠd{7@P?ܹswڕ^UUjmm-ïjKz^q啫W1cxЌp h&_~ g"uuubࣀ$P TTTY$r |͕/4ܦqA}G}'xip Ch[B5C@~gyf\M^yhRng]]-T`o,|G~$Ž Wkc%x΁{'L7d.Ůc'k~'%è C@PTP1q/@*$@[B-bRK]UCpscA=A"iBZT&tO[ fvPG # #'RY=#w}7(ܐ\r`@Ղ=wwyڴi{Gz_ǀ@3L4<0Лk\CCNb %\K/]:Am۶ 7b2`m6p9^f5k{1P/ PNFm @u`A2)S+_@ Wp>ʽ{9G=ρ[#29q68YBeAr!(noCM7n>8I gSPP e*袋}{٫pЉl=z4>K(V?]*a:E   < n! TՇ$pov h8)y/GsNG{;ą &hh b C$ 40$1[ |~vV$$)Bb!p$HZ,$1!!zd}$c[H2=SQlaփBp\CY;UH }!d?/E:Ro݆M'q_@킥 X`. V<ɴZmcS Ms8YXZ *h=xA:l#l? .HA1U($ 6ԅܐ>(>e'NUFqn>WRRNPR7o}-?V q[T*5M<+cd ǩuȠ &$uBL&w0P"yB}[8oGBSA[]{@\x1T= 00!Cp\YRSS^^&pNɓ'.B3Z 65BKBL.76'-Tj@?_WhٳϿ렉@xb&^oT A±Ӄ~ wk)? UP` CfCߊI-IR:R0i5BuB85` O M ^T+:EAib:F**i3*tReBzZ{%`d2ԑH}) w$8]R} t45JgĈs85pB WwJ_E4:xj`/d:aǠM?~!+`e1Ps\)%A;\86m;j /X{i/<*p@mٲ{ऋ/$6e `ZP\_@;g_%-.|Ix㍶6nZ.OC?l] \+hPD@Ր8"q- u_híH- XK/^gjBWz8~;[oYy r{jwSN>;`@ v 4 07<)@ ~2@.? ןfD7MwE6z!Bwj|`oڴ T/@kSWR@~b5j(J2]nwFz:<{/\ꪫ@{3Mi 27@z (gS7o T1»! 0Bo`'5axP)=A?&Md;*g#^5@-\qVABp E+ Bc>fs'hXc -D=?ޠ!?eUV0G]J]. /\W_=mtnd([rO'?Sp%jv,*w8 *ă232 [ rܲE ~&Ohvnߛo8{hw73κueK6/4(nCq A_*nIAnwp®-Mf W^Xp\rnHH)|X"rr#N".7Py}!mҜi\4N$HxU8 }qeSFs&qfp2f `gp@A@ l>O.\IrA(pxMmSh6ZY"=7wF!-*WR`NnHQϴP 09K.agc EQ*p̽!hOnC ' 8v8-nMOPnM@C#+V@"7(꤄$la}Ou!p6/fg!WtAL0r@@8AT!1kǡ'8>E0;ithB{>>$ +^bHp4ATp @ d &Ax^2e!*Uuuy<ܐ.r=ܮЮ LD:S O8]tlGJhJgOI͈` 񋑟 BϞ4o|뭷 W\)2[`0@iTUx3vvB @4W\:Κ8'2~ry?]<сSܼ:;>̐ m ԼFHK$ə:W``# g;Y~l1)48v]@Kvuw#Kp<_s<<=eŝsNކj5y͚5,jDOwҒZ\iwAK^oGZ:z.AKR2[Z7{8 Jld&]xfr^J%o)))`ART9uwwLܢUV-uZiۇ]Ob8v<_aqI}n0}ٲ2o:p\`3}cǎ۱sǼsB4/onnΆN y4 %:;;l:wE(mmm[" @ yUU .4mGTādiT6(@%ZXebR.`qjyJEQ;1MM ̫ωВr$-uIdA?5uv8hZk 054|m|tIzP\\,Iv;< ~8!MB/&Z;=eŝFڵܱrwȐ!\rt[ynG},RFr9Ҋ+ ,YrtOLEQvo,j0, 0Vo(!Xcwz蟸o#[q.N0q$JaYv/×'I:(&  Vnww>Sϩ/Cm*ĥZ ~} 퇐K YUOqŅth;TFwMJ=[-|!E_ȓ^ ދFB!@@+ʼbju+ݞ#;vVx(nD8R( i)1N87v݌L o>pCd/mljUYW=`'͇_Yj}ҥK믕Jennn'a]LbӦMװ 4ZE"65p"RSC['577s5%PVk>u9ûk-9"3V]2άYVhCsF+ Sx|ޅH`ZL#n7pJO%WmݡѾ7FK(pf˩=z{NӤwI nÏ B&~T8M`ʳz|\q8-}~zpذnpT~ΐѲ:\7~M~:tEIr0bءEY〓"n[uYE,@EQpO.nc\dܴvFcݥ,EP{qVV w zmN_͝oxQb?8+%%͌ wϓeqI$;e1~_Ź׿3N|&$yr,|(JZsiGgYku=[VqMZ0@QV`"9ٳg s. !xK`\8Q r7AB!h51 SC%rQNc>NgR:wGx i5$݅;7MuYpS2xQ ~m`.J ȴt0Efx=OnQSIaNʮ] 9AE.(hih)U ~TBQFN/MIRa4ʯjLzfo~,)*{ڵJS;[R"I= 5B(iLh%/X]m_YqvHvVKjڈ?AΪ::+sʔ7dewu>gvgN&ӟm||>Tk'OY5}/2Pԇ1_G2nb$x*e[+_v|&hVpgQw>N&5y+/q>ߧ,aǁ =YmNW;qfٳ]$Bį- ɓ'Y8BQSSOuv2ҭMvzAJj4RIEu?2Z?VWտ䦣8NMn)}yCdTOީX{{4*ɬ'lhX ~ZJsl*EcQ)ҷɤO.gss5zM$$JiW(_a0e%uFӧ>.+Z!?Ğjt4KE1 ǵ WGt:t鼭N+Z`ﲪSL;oT' qj uOth蔇Nvu{$]ݰ/-wv#AE ^.pCu*kաCDsV:V~*9ߒWtVCV~cȿin֯5*Ui:uOZ\G&_³VL(wdiw+{@mB._*g ٺմvm~]W@j!n̵Yecwt9^0~܏紵@>PŚ-i=nkh8t̬z>4Tͅ|Tb?J\ : :+ViĸARU֩\^KHl/۶m/=Jr/G o&%.U=8j}K0l˖3wEΪǎz3- <͛7sDY#6hKX #G*BVj2 *3ZKuDXe)ew;&#sZPeؽWI#IҌ[sr?__7Nuze72S 4{q|ZB4YXF{%qg4^#".Mi\o u+°F(kr@*} -,OIf*M-q04nt+K ?R-z#2N%(rf_YBnj*} \xt6kr;9D[-+46NweO3"@ C7nT^8x0wTfars.878|XsW;?qoPaNeKʿZoUsݯRBl2L읺%O7Rw]"?:g})U%8nZy[qK328.NW2G[{tm#/,Zdɣ ㅅMap0'p풒]^VW/s|S7YA6aCpl?uZJ$砒9%7Je2m@Omۦ:+t,XPv]…EoeٳB2~ nT!|f \l7p-KQtB i>e|Y/ >b1{X䉋9g~t8ͬvol.w^羧>T>_\.#IC{4}ƅ =&cZ$) A Qգ9DCH{M2)?<\Z~~C/ "yx&R).X/>kfM"bZީ^JdwIæ[ 鰡jz!]h>W ^6) M r7h_~0ʗy圏w1[xæ҂'q ڴMm αOw#3Ձ +nEI+#t!?mP?r0tܖg}w\eudgQ|ph #[d}< 2IHDHje>K]Ф)^~IT:˅-+̛ ݿA޴ӑ|at2jNU|eI%T` 抔j߭ pwe䁣D?Uס}:7wU+d8%W/z]ْs0(6^vPe J*V*W,W5t~@7̖m_d{6c*(Ixa-hǕ?SK/F2z;-O&8x}OB*KB~"d"}3*䅉-AS$rU,Y}8l&ޣqR^xn80Jvϟ?kUVt pu E^3!贽G.$ :d\ UԧG=4cZOofV ։-cۭTH> :Cqpo^}{CSnM^nj^y)-*i4Wі?謉sկmƩ5 zF3ԠNQXZG#/<=8mXOx:[MNmlo_C-]}z(%e-v_c mRe1E60(:tz@=xW3^=$)vKn[wlVu-Z$wngfˋ?|ܹȓ{=Cqn`qVcoNa>ƷEa'-j> .uvuuHWu#cr7 Ơ*iH7-0! y^*R y ls; +>umBVb۝ ='İ쫅rm Se6[dy4ykM_Fqθr\m7{4;ۥEXS}W