sardana-1.6.1/0000755000234000017500000000000012555673001014756 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/0000755000234000017500000000000012555672777015546 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/man/0000755000234000017500000000000012555672777016321 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/man/MacroServer.10000644000234000017500000000240412555672634020623 0ustar zreszelaComputing00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH MACROSERVER "1" "July 2015" "MacroServer 1.6.1" "User Commands" .SH NAME MacroServer \- manual page for MacroServer 1.6.1 .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] sardana-1.6.1/doc/man/Pool.10000644000234000017500000000234112555672634017304 0ustar zreszelaComputing00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH POOL "1" "July 2015" "Pool 1.6.1" "User Commands" .SH NAME Pool \- manual page for Pool 1.6.1 .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] sardana-1.6.1/doc/man/Sardana.10000644000234000017500000000236012555672634017745 0ustar zreszelaComputing00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH SARDANA "1" "July 2015" "Sardana 1.6.1" "User Commands" .SH NAME Sardana \- manual page for Sardana 1.6.1 .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] sardana-1.6.1/doc/man/macroexecutor.10000644000234000017500000000175612555672634021264 0ustar zreszelaComputing00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH MACROEXECUTOR "1" "July 2015" "macroexecutor 3.6.0" "User Commands" .SH NAME macroexecutor \- manual page for macroexecutor 3.6.0 .SH SYNOPSIS .B macroexecutor [\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 .IP Taurus Options: .IP Basic options present in any taurus application .TP \fB\-\-taurus\-log\-level\fR=\fILEVEL\fR taurus log level. Allowed values are (case insensitive): critical, error, warning/warn, info, debug, trace .TP \fB\-\-taurus\-polling\-period\fR=\fIMILLISEC\fR taurus global polling period in milliseconds .TP \fB\-\-taurus\-serialization\-mode\fR=\fISERIAL\fR taurus serialization mode. Allowed values are (case insensitive): serial, concurrent (default) .TP \fB\-\-tango\-host\fR=\fITANGO_HOST\fR Tango host name .TP \fB\-\-remote\-console\-port\fR=\fIPORT\fR enables remote debugging using the given port sardana-1.6.1/doc/man/sequencer.10000644000234000017500000000173212555672634020370 0ustar zreszelaComputing00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH SEQUENCER "1" "July 2015" "sequencer 3.6.0" "User Commands" .SH NAME sequencer \- manual page for sequencer 3.6.0 .SH SYNOPSIS .B sequencer [\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 .IP Taurus Options: .IP Basic options present in any taurus application .TP \fB\-\-taurus\-log\-level\fR=\fILEVEL\fR taurus log level. Allowed values are (case insensitive): critical, error, warning/warn, info, debug, trace .TP \fB\-\-taurus\-polling\-period\fR=\fIMILLISEC\fR taurus global polling period in milliseconds .TP \fB\-\-taurus\-serialization\-mode\fR=\fISERIAL\fR taurus serialization mode. Allowed values are (case insensitive): serial, concurrent (default) .TP \fB\-\-tango\-host\fR=\fITANGO_HOST\fR Tango host name .TP \fB\-\-remote\-console\-port\fR=\fIPORT\fR enables remote debugging using the given port sardana-1.6.1/doc/man/spock.10000644000234000017500000002620012555672634017512 0ustar zreszelaComputing00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. .TH SPOCK "1" "July 2015" "spock 1.6.1" "User Commands" .SH NAME spock \- manual page for spock 1.6.1 .SH DESCRIPTION ========= .IP IPython .PP ========= .PP Tools for Interactive Computing in Python ========================================= .IP A Python shell with automatic history (input and output), dynamic object introspection, easier configuration, command completion, access to the system shell and more. IPython can also be embedded in running programs. .PP Usage .IP ipython [subcommand] [options] [\-c cmd | \fB\-m\fR mod | file] [\-\-] [arg] ... .IP If invoked with no options, it executes the file and exits, passing the remaining arguments to the script, just as if you had specified the same command with python. You may need to specify `\-\-` before args to be passed to the script, to prevent IPython from attempting to parse them. If you specify the option `\-i` before the filename, it will enter an interactive IPython session after running the script, rather than exiting. Files ending in .py will be treated as normal Python, but files ending in .ipy can contain special IPython syntax (magic commands, shell expansions, etc.). .IP Almost all configuration in IPython is available via the command\-line. Do `ipython \fB\-\-help\-all\fR` to see all available options. For persistent configuration, look into your `ipython_config.py` configuration file for details. .IP This file is typically installed in the `IPYTHONDIR` directory, and there is a separate configuration directory for each profile. The default profile directory will be located in \fI$IPYTHONDIR/profile_default\fP. For Linux users, IPYTHONDIR defaults to `$HOME/.config/ipython`, and for other Unix systems to `$HOME/.ipython`. For Windows users, $HOME resolves to C:\eDocuments and Settings\eYourUserName in most instances. .IP To initialize a profile with the default configuration file, do:: .IP $> ipython profile create .IP and start editing `IPYTHONDIR/profile_default/ipython_config.py` .IP In IPython's documentation, we will refer to this directory as `IPYTHONDIR`, you can change its default location by creating an environment variable with this name and setting it to the desired path. .IP For more information, see the manual available in HTML and PDF in your installation, or online at http://ipython.org/documentation.html. .PP Subcommands \fB\-\-\-\-\-\-\-\-\-\-\-\fR .PP Subcommands are launched as `spock cmd [args]`. For information on using subcommand 'cmd', do: `spock cmd \fB\-h\fR`. .PP locate .IP print the path to the IPython dir .PP profile .IP Create and manage IPython profiles. .PP console .IP Launch the IPython terminal\-based Console. .PP kernel .IP Start a kernel without an attached frontend. .PP notebook .IP Launch the IPython HTML Notebook Server. .PP nbconvert .IP Convert notebooks to/from other formats. .PP qtconsole .IP Launch the IPython Qt Console. .PP history .IP Manage the IPython history database. .PP Options \fB\-\-\-\-\-\-\-\fR .PP Arguments that take values are actually convenience aliases to full Configurables, whose aliases are listed on the help line. For more information on full configurables, see '\-\-help\-all'. .PP \fB\-\-no\-autoindent\fR .IP Turn off autoindenting. .PP \fB\-\-autoedit\-syntax\fR .IP Turn on auto editing of files with syntax errors. .PP \fB\-\-deep\-reload\fR .IP Enable deep (recursive) reloading by default. IPython can use the deep_reload module which reloads changes in modules recursively (it replaces the reload() function, so you don't need to change anything to use it). deep_reload() forces a full reload of modules whose code may have changed, which the default reload() function does not. When deep_reload is off, IPython will use the normal reload(), but deep_reload will still be available as dreload(). This feature is off by default [which means that you have both normal reload() and dreload()]. .PP \fB\-\-confirm\-exit\fR .IP Set to confirm when you try to exit IPython with an EOF (Control\-D in Unix, Control\-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a direct exit without any confirmation. .PP \fB\-\-pylab\fR .IP Pre\-load matplotlib and numpy for interactive use with the default matplotlib backend. .PP \fB\-\-matplotlib\fR .IP Configure matplotlib for interactive use with the default matplotlib backend. .PP \fB\-\-term\-title\fR .IP Enable auto setting the terminal title. .PP \fB\-\-classic\fR .IP Gives IPython a similar feel to the classic Python prompt. .PP \fB\-\-autoindent\fR .IP Turn on autoindenting. .PP \fB\-\-no\-automagic\fR .IP Turn off the auto calling of magic commands. .PP \fB\-\-banner\fR .IP Display a banner upon starting IPython. .PP \fB\-\-automagic\fR .IP Turn on the auto calling of magic commands. Type %%magic at the IPython prompt for more information. .PP \fB\-\-no\-deep\-reload\fR .IP Disable deep (recursive) reloading by default. .PP \fB\-\-no\-term\-title\fR .IP Disable auto setting the terminal title. .PP \fB\-\-nosep\fR .IP Eliminate all spacing between prompts. .PP \fB\-i\fR .IP If running code from the command line, become interactive afterwards. Note: can also be given simply as '\-i.' .PP \fB\-\-debug\fR .IP set log level to logging.DEBUG (maximize logging output) .PP \fB\-\-pprint\fR .IP Enable auto pretty printing of results. .PP \fB\-\-no\-autoedit\-syntax\fR .IP Turn off auto editing of files with syntax errors. .PP \fB\-\-quiet\fR .IP set log level to logging.CRITICAL (minimize logging output) .PP \fB\-\-no\-color\-info\fR .IP Disable using colors for info related things. .PP \fB\-\-color\-info\fR .IP IPython can display information about objects via a set of functions, and optionally can use colors for this, syntax highlighting source code and various other elements. However, because this information is passed through a pager (like 'less') and many pagers get confused with color codes, this option is off by default. You can test it and turn it on permanently in your ipython_config.py file if it works for you. Test it and turn it on permanently if it works with your system. The magic function %%color_info allows you to toggle this interactively for testing. .PP \fB\-\-init\fR .TP Initialize profile with default config files. This is equivalent .IP to running `ipython profile create ` prior to startup. .PP \fB\-\-no\-pdb\fR .IP Disable auto calling the pdb debugger after every exception. .PP \fB\-\-quick\fR .IP Enable quick startup with no config files. .PP \fB\-\-no\-confirm\-exit\fR .IP Don't prompt the user when exiting. .PP \fB\-\-pydb\fR .IP Use the third party 'pydb' package as debugger, instead of pdb. Requires that pydb is installed. .PP \fB\-\-pdb\fR .IP Enable auto calling the pdb debugger after every exception. .PP \fB\-\-no\-pprint\fR .IP Disable auto pretty printing of results. .PP \fB\-\-no\-banner\fR .IP Don't display a banner upon starting IPython. .PP \fB\-\-profile=\fR (BaseIPythonApplication.profile) .IP Default: u'default' The IPython profile to use. .PP \fB\-c\fR (InteractiveShellApp.code_to_run) .IP Default: '' Execute the given command string. .PP \fB\-\-pylab=\fR (InteractiveShellApp.pylab) .IP Default: None Choices: ['auto', 'gtk', 'inline', 'osx', 'qt', 'qt4', 'tk', 'wx'] Pre\-load matplotlib and numpy for interactive use, selecting a particular matplotlib backend and loop integration. .PP \fB\-\-autocall=\fR (InteractiveShell.autocall) .IP Default: 0 Choices: (0, 1, 2) Make IPython automatically call any callable object even if you didn't type explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically. The value can be '0' to disable the feature, '1' for 'smart' autocall, where it is not applied if there are no more arguments on the line, and '2' for \&'full' autocall, where all callable objects are automatically called (even if no arguments are present). .PP \fB\-\-ipython\-dir=\fR (BaseIPythonApplication.ipython_dir) .IP Default: u'/home/zreszela/.ipython' The name of the IPython directory. This directory is used for logging configuration (through profiles), history storage, etc. The default is usually $HOME/.ipython. This options can also be specified through the environment variable IPYTHONDIR. .PP \fB\-\-gui=\fR (InteractiveShellApp.gui) .IP Default: None Choices: ('qt', 'wx', 'gtk', 'glut', 'pyglet', 'osx') Enable GUI event loop integration ('qt', 'wx', 'gtk', 'glut', 'pyglet', \&'osx'). .PP \fB\-\-logappend=\fR (InteractiveShell.logappend) .IP Default: '' Start logging to the given file in append mode. .PP \fB\-m\fR (InteractiveShellApp.module_to_run) .IP Default: '' Run the module as a script. .PP \fB\-\-ext=\fR (InteractiveShellApp.extra_extension) .IP Default: '' dotted module name of an IPython extension to load. .PP \fB\-\-log\-level=\fR (Application.log_level) .IP Default: 30 Choices: (0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL') Set the log level by value or name. .PP \fB\-\-colors=\fR (InteractiveShell.colors) .IP Default: 'Linux' Choices: ('NoColor', 'LightBG', 'Linux') Set the color scheme (NoColor, Linux, or LightBG). .PP \fB\-\-matplotlib=\fR (InteractiveShellApp.matplotlib) .IP Default: None Choices: ['auto', 'gtk', 'inline', 'osx', 'qt', 'qt4', 'tk', 'wx'] Configure matplotlib for interactive use with the default matplotlib backend. .PP \fB\-\-cache\-size=\fR (InteractiveShell.cache_size) .IP Default: 1000 Set the size of the output cache. The default is 1000, you can change it permanently in your config file. Setting it to 0 completely disables the caching system, and the minimum value accepted is 20 (if you provide a value less than 20, it is reset to 0 and a warning is issued). This limit is defined because otherwise you'll spend more time re\-flushing a too small cache than working .PP \fB\-\-logfile=\fR (InteractiveShell.logfile) .IP Default: '' The name of the logfile to use. .PP \fB\-\-config=\fR (BaseIPythonApplication.extra_config_file) .IP Default: u'' Path to an extra config file to load. If specified, load this config file in addition to any other IPython config. .PP To see all available configurables, use `\-\-help\-all` .PP Examples \fB\-\-\-\-\-\-\-\-\fR .TP ipython \fB\-\-matplotlib\fR # enable matplotlib integration .TP ipython \fB\-\-matploltib\fR=\fIqt\fR # enable matplotlib integration with qt4 backend .TP ipython \fB\-\-log\-level\fR=\fIDEBUG\fR # set logging to DEBUG .TP ipython \fB\-\-profile\fR=\fIfoo\fR # start with profile foo .TP ipython qtconsole # start the qtconsole GUI application .TP ipython help qtconsole # show the help for the qtconsole subcmd .TP ipython console # start the terminal\-based console application .TP ipython help console # show the help for the console subcmd .TP ipython notebook # start the IPython notebook .TP ipython help notebook # show the help for the notebook subcmd .IP ipython profile create foo # create profile foo w/ default config files ipython help profile # show the help for the profile subcmd .TP ipython locate # print the path to the IPython directory .IP ipython locate profile foo # print the path to the directory for profile `foo` .TP ipython nbconvert # convert notebooks to/from other formats sardana-1.6.1/doc/sketches/0000755000234000017500000000000012555672777017357 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/sketches/daqboard.png0000644000234000017500000137270612555672634021652 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/sketches/icepaphw.png0000644000234000017500000004573612555672634021674 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/sketches/multimeter.png0000644000234000017500000221426712555672634022262 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/sketches/nanopiezo.png0000644000234000017500000036736612555672634022104 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/sketches/sketches.odp0000644000234000017500000327050312555672634021676 0ustar zreszelaComputing00000000000000PKAF3&//mimetypeapplication/vnd.oasis.opendocument.presentationPKAF~CEThumbnails/thumbnail.pngPNG  IHDRd*1IDATx{LTW/ E\LhW`k۵XMlTB5MRku Vvi@-!*UR[DaxN{z3w9'dr2ss~ss7tjjJ@@@@4 4(DӠMõ_lqqqAAAlv'׽0>)AkjjqV.@yydz7챾2::;9r{a|RL o@N}`ɓ[nMNNhkkkq幹vѱsN(]㧽0>)AܼysƍyyyW\㏧V\Gˣ>CxݼyoQXXlO?4}~{ ‚bY~3g=tYUS$we4O8/;Dϟ?_WWgN=K,)--^G[,?~塇"k ˂,GˣGeu30ݖ-[wP2>)A;pY'**)))qwAWj8eTɊK.Q=BCe[@DcrIh \RM9k H;G,{[Xv0ޝO|: 7WR|S Dx-ŋӷ}}}?#<"Q"̆ONN{/v ܹs~L6i ɂ8ud0Ç洴4fa6X ٱ#RR 8˗bqlfÁX؞\>"EW\1 @C, 1*b9Ɖ.Y"kBoFc32b9Ɖ.YZd0ؘ^{ l83@۳c?G$%V!Fw]mTKJƋA#GT|jίuGT O|B k0ERiIIWp-7(DӠ<PM^{McW< 9^akXK III===mDDh萰9sܺuql@ccck֬CCCo$222,, `ЏbyVU xACtҪP0A¯ kmm}ǡ7L s%&&: ?A D*f9$$iʻwzW 嗬,_>o<ȈDHׯ[SSuDP`0?07~Hll#DIxX*r < ]]]t%@H61b264X23FGFF& H[lر^tБ#sɚ_ :x0wc#Ċា;GG'[ZYY:]kޭ[7?gA_}BOoWHEuu5yȀ9)}:x"0|y߆[~8R O< TK.%ZF[ԍX,ǜ9swg6o^ئM. BnL}:A9={gt3vmtu}~~7=](dJ))۷᭫C,e||<4 w|2†,YY誯OF{!EX>%߼9V%K"KK{&&"#{h#X(6lr*Ȧ`m e:t߸qAw}<D+ x+-prssFe˾Ob#Rƙ3@K";>>d2544dffBzdd`0}W^+׮]#'<"Pjqqq^^^AAΝ; CCC7n'***sCmV^^ꫯh k,Ϝ95o޼M6]tihh(&&? .W&99---P~b*lV@\\\ZI&;;;**1p ںuk~~>,>}t:y@Vȍjl_ݓb]켒c [ ܹ~.BM˜VNU#ȷӒ2 ()~SCoP\C|,X0ySSSdd$&]cRѠx*Fg>i&x}G! '.eee&W^---ݼy3nhh 0O@׭[w^hrĉ^x Q򊊊-['|0OZqq!l>gڵd>졚/өK۷?0nC.a"EfDBBh{XF\lɤ&##ݧ+˄L04*=[ɷ`;dᢢ MhѢADקSr?9H臨p0" ws>_"DFCObb(wI:7jNQ4X [͍|s='~CܓQ_ ]vހӧOcwH@xxz4'ɤ&IIg.]Wd.배YQ(pqRaxPLJ/:O(92&/8gk~I2 y}iT 5!n(88hϞ$N{6%ڈ䭉aҐ"2y-)ސ\r"xݶiNfFe)H߂ z~A)8y9Nj"^4*d _aqTӨ  bS_NYh/9<'';w,[ . 2Zzu[[oN31110';BG|.\0|x u?ԲӳtЀq<`('t ڕ+WB"9dZe|KEMM `Æ + ptw̄jzH*6p… qʛoYwtt@ a o ݱvTdٕoiq< cCA8qw : nPxgy@h$S۹sBAPjNS(Q^>|{d`4.]ZZZ mkUN9!LߟWRRB%O:%fӥ[nڽ{74m6YXhQsssllZ'՜4r+{__g}ȑ#`طoYvڮ]z뭐WXNxOƬV*'Eo%ʧzμkVIRq2W:bnAj]i,z5Z'պz @]x166vVH[x}?hGUmy _^mmm;vmiiV03M)"^cǎt}}}}QQQee%I (_6"޷oO<+RܱE"cbb:::V _QkߖWp-׭))e<.h?֏+2>>g:wlHxK*vLR%6|7+<߻؂322[? ~]"o7rjkrb+ұckӦMLO҅u3U:_HȼFwaa H{1J͛d N@=p*69% TL{d`ٴ`,xfS˗/Sr bu c'sOU+'L55'4))x%VC d@7'L8 mnnA4Rƞ@M&)1T:]H{]F P)Ϩ (W0{d,h4 +py*;:?{fl6n||djhh1 $4԰~ˍcxZPم jaa_ 2 uDDDnnneeett_U{j ^RZVF ࡿ*L1zj7s; 5 U7vjM @rj+UiU"_h4*]fE%P7r٤OM*VlRt:ԂX6bP6 @I 4(~ATp-(-h~[))CtYO98ou36_삂9_~9Cڤ3E? ~&- S—;A3&UCB_첲^P t:Qeru?6Vch(4\ 7ȅ}> ^;ߵSTl+ ˎw w-(X^Xö/ `P{"PʵVQ Z^/;갭h{m@ly W[u7+ Eks!Yk|Z͊:lgdd(^ xd 7!gY^F}S2jooɱD8l| oذ.d}NNnkkCk8-#(NCLLRJ@\\6z_Skf2tVP"1@nn7 kkk,o@U8-5Qv===bVUU.Y^4G2a=]͂])51& kedŕG8agy~qUF+ xia"]A%—xXh:)pvjjjKK .kxC!.\رc0S^.SUV1/ Z(˃8:w\BB©SP"{qL" ^[;ٝöl~W^z%Ad Ra;$$#5]%BaՍvQQ$9'NWma澪öje`_@dk sfs>zj}@~L^[a[_R5yj=USZ4@1^ʱHbڞrYf^KJy dc|o/utlDe[])c_nT]fĐ艳p1m~q f4e9? pb1RUNQ,4JlVV%%ڠ^rEM$X9ArA;MgY4ML'ߟ;ۓϬ%Zb*7"a|J+?eJ ? Ly;S,Hcꎋ᰽ùm/F Hջu}-NvS ߗ;WN Lfp/PKYBPKAF settings.xmlZ[s8~_aawv($&;NCs oYr%9 d)x<$ Kw$؟^ 3z+/!j3sw}bFUlETRup*˷9**.UiWnXuw5"۴BJZ(A>g)4M+DWw]=22<169e{mg/%rCymm) F}?fE:Gd^nwQ=uSkRS{YƢ_EzVI AYZ_*s.BB QX.<0SH}pFzi/ 6wH_W4 X.O2`xWɘ %Pz`}vNXWGFp(cW%ϯgT#$#Ol =xlAlWϰ4yC_qj>NuA]5oKk#WFU|:8u5Q;]ړUqgo= *_i㶶 0?L'fޚ2W8ćbkub$mG{2;}1͉)s %_fq׿ }20q5'WC g5I`vpZV{)>c4[Vm1/OL0rE` M0pb<lNfhzӘִ=16:6xACGNc*$k"#o+YE%MSPK@'&x@'PKAF content.xmlےF&xOA^S6=|-M^TwHSkk2&`$$#2SW{73/O8A 2)H?>/`o`5 g??}!|zOwp V4\^ھ~Y 'j vw:XW˷~=+>}Y}y8.;bֻv'GW6O^Z/ v1~ -՗n^|/O'#1=lHyL..^Ѥ&Q]omb_Mnƛ_oGϮ2O_&Y؟*lvTaf|dyY,#t3_qaf]uċ=.Ř?ƿs?li3\bQ<\VͶ#8xsS>[Dۚ c|:k~%XN͍v7Y)]Gm[3i'S-- `nv=ShFrQaly3U6a,{i 3KFy^p] NT3s[,uSEt;Z'2ǹ;xLj,R^6a8^nD 6\]qs4=XvvU΍˷L-yRNԡߥrMcoOi0?);<~c k{<,H[U%wazZLfoanyi4z&mC:ǾM6h6<9Vu =fqsS2MꚽQ}s /ѹ&aѥ.Xvӟ7APӡܩsC2ߍyGk"To?NV}>q>݄V}k:IX.tt'C65t>ѽs^?8^[lv`;򔈏>LGnjAYot=|6߮/V wNM:$]N=Mۺ|>4GC+K05 ^yS,ϛe>M'g~㋜>lfiKTqԊ&΋O]O|H =]f?gN#&3:VWnA=e/_obl{n]>7[έT<#d+S!we)4_Xee.泇-B; E\ !daَ 9{W|df%L SR^LOO$ k[ ي7OO`7xâwn1fX~>KUM['Ł#>#MkU'a:MUЂLP,ծYgpkf=Oˉ]8; f X~\&w0]>l: .q}r|锜lO o6n*Ei3i6s%lsN#]e!h|_v?W/ f'i103dk@SřjVy=^}]oP`Wz2s ]Rm;=1~aչE)T™MƧLZ]&c,)1ݴU$Mi9Q=Xm)?"G*5F)R}Hr#ŋtsH+6[=QFfؠ9=@0p0uYs0~aÖﲹ_m_OZ޹irꝏ|ǁV]Ё;^b W.$uoDsۇ8>wɺў /6;xSӍJeM`mor nww9/VOl_ZR4XוYi]ekyou0qM`{Zf+v4&'z4~w暛5 p76`1t' ,|5ۀ=X;y]GCh=]LhC TSƅ PP9KJ*8P92*7RyQR#+ ,J {Z/\fLC*j'Þut3H zM~-n utOxxQ1yH(y?l+Zd{ѶWNQ_uTі#qĦuU\(@׏ԾTR|Qz{GUۃAkf@,NW{N]i0w2\j[(ǵ|3LB&274/uWX¹;jSqN[C%9L3r. X7j- ºqZ3h9 fէ%|ݹ8Y_9A\t}bF" \NM:'~,>9mbQBKLc R-jM\r&&pzS pCbuqqňJZDBǬ6uWP >g>C*O|ɠdϩ B)QQ= [N!ϩ5wQ{s+{ })9j򚚼HsN6~ETs8g惫Ui(H9e[5I]@%w4{'9E3Whʎgx97î}+ҜS+!}fDLU,Mx&͵9PJ$n9a9E!1zr×9'( L:9S}fT "㧙ם͎/ ב)98\ZfT!>j$OPj60bn.ϻGv(9\|_9PmhA9o=kSDxy.Nޤ֦ )xx ƭ= U3{.Af?Qf/y}TU̞իCΩ 2YnkgK&t([:Ev7@@gkM˕ ZQ@M*:h^oJ [Kщ3 i؍W.ض3GMܡm:R~fu0nv$ad7~Psks~ U [ZKgcq)% U]Oy(c1\݁} ++eSd;`_'>5X9{-#Ӗs'g=?e.׋—nլ Ygd ?%]dq1pQMsT趩h*a5%kǙ^uO9}W~qך>%ey\KlJ+(T]2Yt 2/׻^QM6o_EWܿ=mnڼ=FE޿q4I{,mۓ=(hX>/C~e'd NaEҞGyz%xG) m'oZ-yak9<8`,Mcu/ 픽6LK=%H;ti \%ZEKְ"D܂:46ԹVֲH˱ln'R Kca1DΣ&mi@s&}M9|Xvrmij]K=.JoނE2>.C3>5Lsnct?&,?;ݺpKL^5x<.l ^ūғ^5&º)Q>=tqG{M'cۣB$N:uw=RH%Do%dobwI}uowӦG 'NÞH$n sq1|zO(si5i|bٗG>:?Dsr&17|"Fgkw:M5IF{[/&_Tw?d]t4,sN_ ewr^|ςyTO?&/duP~M3OQp@ q%M}9,aƗ>$7p6_oCuGHMfy:|+s7Y+1ꊏ߷|fvdB,$ igv~f:K;7ʧh;0G$ϋ`lDK;db&M_fDg_noic4l4bDT(ɱK?c?}I-d6ȵ_C&gm/h?5"t;}_$%xI5x.\W;|*QBd;5>KUVav& :|^htԒOs;埜LVܾ-/_]rx*;ƈDʎD7_SNjG.afrW??M6j2zS\Ӕͭ@h lY?${?q; 0(8(>2qdP>|0\==@vX"Cf2KP6rpfߣKE"}K>]w]@҉ӊ5pђ1a;_}X?|?`DG%l4"wܳ%pP|Y h:.|e$2]ͫ2̪BR;)KlC'!rp9~P?/泴D%j ?pS]n?64_Y;? Uo t 'MSy j````|$ZxmuZZ_;Y    {1ψ0000ph·@;o#ZE}nb^Rcf-H;1 ,uk:"L%G;-Tp:Vf[c mj߻d[ <ބ!JgY_]ޫoc9_$kF /opKw5 bO?PWMXYgFͬw4^m 2¹ Ks,`3DJ)AW>8G#FJqAW: i|iD4^ϗ.b&xOw`H\P8G74J?!4Z Yzhbo=ٖC8iԝGDєpSIaVȁuTL,TcaE8Ebj\l5yG[D!,|cU+h?\[cwN4`3,cv\ V_KyK4hyiP$I  !'??9.ՀF}AA)"!&:A(oyhپ7Yl'N}1ab@Ta}vD zt#.)~:qKݓkA3Zx-*bbeEN;+JF=HR/0YY&lM2j2_T@3kFngu733p b,1ыݨjV8"Ɠ˪: -w.&%\̂45yhV ??<{9 ^^sCxJ.zzc7% ONNg72oV"wL4V+IOPpA n#2✈W!\FAY3lZ{6eu=f~~~~5_Mf[  wY𝃧gzOVic㲈DTyG!z1M,Moj7Yd7mZqVێSF(fo᧤Q: Kڦ j)OA pE 7%5=|+Az:޶?~1-`[} ϯI[\2mI "&0!T#NU5d|Ft`_^SJY=TB&2HDh)vcgiۇd}c.Qc1 C9K(:H+1Q- +-LԌq)( \q"2Xjvψ^"Fc1#lߊI]̉sK'/YM; ©d-֫Е-֛oVx vAdN'"X=G|`'Ev1I,eG$sΒ3y`i-;KN.D5ɬΥ|zz=ѿ6 b@lx S|\RXvͧɅ;'K3UzV=,OӬyUa"REA"Le6XR1dJ p2CVf,Sʶ6L]G,{ZPx8gpŴ1$ƹ2 [qlAY3,r(•_XAGҶ? Dh ^`{ƹ#-bL\:w::N&oc{9+.*hĽLrAFRȔhG.۟7&92Y*[]˦h0Ɣ+ Jhc)46I{$$w zX>Lfx1{QˢźK~Zmzڕι$"^% YvHW&cX*'8:R?h> T8BGvU@~@~@~@!P 4`?`?`?`ŶbO$ﳖ6$芤{ޞ`$r;>rD{ +WS1嘺/#peLMFٵpGJì!9Y~k?G`ZA9K8&5k&\璠(0Ve;[$FjL>^cHg*'|f/Wxɫ lJC.Lʡx^yH ipfS|aũ (-e2hfZPQ!Ì+!0RI,s6b(Tqvv)rck*hg"i"ZF`´d1+X]Lei9P[ZQe=ǂ&̾K¸xSSֶkU-ʋ/ 4xZ'iGKQc<-j.fN3>E~JX'+;#+->[,ʿ&9]ÝϾ/}sFFna,F`1ёrM2p4]9Qj2_TjLy˧̰ɐн#6oA 構v0Vf7l1+MaQ0K/dD©b2 ^,H%"~~,hYaL[#,w,xXN`3{YY.%R)R{DZ(IkoyTYr&p7o +#pQf3HԶ#f?[U[Up"+WPdr-E )hz | )ȧܛ)0dhɱ݄?G~Xǒ8vROPPPPPFm"=Ҧ/Kf1vyO|Z< I ZnT !M&*WN$yoaDg#B|]STXV3pЌ\ >A A= أ=p|aX#eGic VntDɷHDI Gyw0]*S82Qe2PYa:z0>0S䨖VYQ k%* cR(klgFuaelLѷ*Za%RJJFXz[rrc'+}_!}GQuQq>wvD-՛>8"y=F)Wݶ/Eբg={cHyy7'k9Hi2nw,'s8dI}BKLD#L{n[&.~XXpRk}6MRAFv& `ޖI[#`CfoA} W( 2M},VG3z)- Cp\q7| /Rپ48np Θ!*Ozpbi{}h*eP 4@@^ 3WyF,D)$ ! OķA%~+ 3f]^!4- :H ^`Fo.t4O.bT\š#dD iDz ޴ղ+6(%uA6Y B!!VEwCs=-bDR0o9 6k2@@@@6@P5G68.Cq:G%,Qmqg8mqy\L9ZljO,X b0 w`,.R\{97^X"*G)ȧ ޖ|*Ms0d|abѴ`-Lg ((((~[(ΛhDh)x#(* d)!$X-{@r3$(&7w_=npA 7-L~E<&7wƈ " ێwWeSh}fO׋/Y?Ɩ=#ajG9#AX;)˺Ɩ}U hɰb? |j<j0>T^;&A(S`"]%bT{c {etw ހwщ1iҩ /&7!i`'h=B ;hⷆGDEy3#U ETo?MRh_=C(Z@( EC"ѮA=w !!c7C5n$_(DjP|_rFQa( Vnln; VF-i?/VH: ?=eJKҴPw*CTs#9[Nv7VTF{P4V3"蠽X)D؃i1NȍQ* De #1*$Vٽ&DHihL$bJ#$2DTQ<{ a98%B%"o"9Ϸj%S-ZWi +[*ٳv&B$kg~ h;^n(vjX[fl\8w4H\^u,?΃n< p'Ʌճ,̻\ͧmca71 lgb?5H&yK{)K,SZUҳ2{XeO"c), @pO0(HۢƊZP;F5LIA .Ssʌu XI#eZ [#g 63&Jʘ/0loűeͣX̰ȡWa XAP-m{nc*c˃/>{璏 ,1-6tt͝xqMo Nyr}pSiݪ]Q=ru8EĝeזPrB% N;}_I&],]x2CܞJ8qx%D֜Z1"PVZtJeWFK4n5_6{_4GlcN =(-^*8\wYiem: 0000|P^ktTa8''eo@97 ytNlOa314M wVQBQ9;(jDTQAD>ET-Q "*'Ue,qOB]οvdTQAFuH28VEkrLL %[o u[%c 0b=:(o ˇG#vh Fc0^-M(xxxx  77{ݔ nooooooooo&;xxxx;iycj>+qVrHjVD7y>---U\)R=:D |M V߭]-lMe؇^^W )0ͬRK тVe&8e#+ H=֢k N\Skz,?[ј+Aj<'2u˪:ѼpjLp1sF@ ?gy,cbξ'.xSZ,']Ďν&]ùq|E?;>=ͧA#E{tډmZ.>^/gv[1=C5Y{E MbU$g>XQBRʇ"E%QȨbgkY@QDe@(svcaT0kLI8 (77׍jT)%*zCZpp;ǤѪA4R=. {gwiPmYʟwsCk+0E^ަQZGy[.'LO+* Tu>c,0r)Qt(*4VJcf%}afb1N192+N$QKq;BbK`B6vH*틌Y(B5 ;{ a9XD(f7sd(!jHbJ[]b f8ek k-H۝cN'"X=G;]:;i,4.&]2A/n&dqXn2 e'Ʌճ̻\ͧmcaB)& DFR:E~IJ9w{lUu)=+*<,O iVܼΪBD \*B0(HۢFcTsɔ b!2eL1XXmOm@4"X`-85Rq&,i!0cV"s%e؂Q,fXP+t fDf#n ι4/{璏 ,1grm,;⚼T W+;j8H]wNn܃p.p~8ESr.."!AzǟN(;ƒ.ľr];vuJ;BbDS5|;PV#{Nw3J^ -${ Qj *ɧsSTCX }QGW<}W_Cȑ+rӻꓜ2C*)Jx!}C*'Pј=`>&7<ρ"{ǁb4sNVh+lɬo#mjuəKG/˙"EYe!4=%vj*6굸^O).+E[ɱgX q"} -Ee~I7Ll^YSDI: Z \8A=1'{ O-0eT$郠fLѪajMQFIV|4% I6g*\X&R96' g_}E)LbtxYԑ۞&o.&cڤ)y؊؟e82 vX%ڮOH͝JddyZOK6-oaK]%^%﮲ۜL1"pJ]"F8#PAH>Ejgj4oc҅ D~&@҅rn`S?3! @ @@/%$]zwLI¯ Y 888$]ŕ5$] tit.\&Ƥ PqwI|rLy{̪%eivPAd?X2o.^{#,,C z#,;DXeTB vioUsG$NS6D_ӗE_p4}O_ ar "ϣ*6t3fm~ hc7 )uⅮR~ykvT%ot bY!+HmY`8 l>YR]OCI1GEt '_6ON@Xݔ"k38 liLi2N8pGG]we=.~޼>m=dtcMǵ6;J޳igFl~e&c]F~jtR/-Ax,b+66"~MSԤ=nH4Y6# ^6WCl<;zMhWˆ^οH67CѠ GC^s4oτs4r44F4]n4I%Hu2=$'=myڕι$.`&?E|qYӻn dn_ vlu9t m4ӹ0 JFIفxOc[ɒ3lя? &gT8r2 rny-]<.+n-]3| ~Wpov<"!PNy+`P0x(OlwxRxEX4{1?G8XcU0),/8G}Pq42,DADDaÈ 懀vRy* iJu5˜'T%']www'(=EAO/?N`R[[[np[W怣D#:sQy1(1 0q;-Tp:Vv,E%P{F/ѠYis&#x,@Di&t6>d%+owybo.O($}%.z8CM D{123GSy;ޜ[lB`1f:D*{so|8{;']yGA^Y*B?JCTZ }f(aHS߅ʓW/4f{;o3\3~Sf:"=hL# VHBrV%gs HQx{ 2ď%^ ###׉r qx#Xysg~O/dH88`.$ޘFVsZAP&߀]79"+ft6u+UQ5;*:*,|B %ph&(g tsH"2~#3k[ɐ=|/?@1nr/::.Y%1G* 4XO֭I=/˜< Z Sb8? T-lƣ+|ҐJ~V\8F>}8*}^,l,cz(ԋCh$h(~9?tzCX.s,mgFP8##AxNUs]WaӧQu3&z e펥, 1H1eoR@q!xOLNӦۙ٭D/LtΦ c#J,T8&U1pת)JD#:ADzGT'7{HPcEŽW@d[rFRI |I5-% Ir,!<3F)jUHf)o16jD1cb1m9.WciZ1xl!T>e'#JA8׹:}۾?V]HyYUÕ]P'uyCL<pvJBiG(~5y_5xWP]^x (3b;qGXGqtƪ:ܯÛmWPU\|***@x_uFz1 <x a~aa0 kYAa0O( saǺ p\30̞ d{!z&^05bO{= O~f̾9\Qňg}bRZ8xF-??#GkU?5bd}^,_n 2h/\;qͤo~ڪEy>pt{~Tۤ5YZUظ&FTe ^*$OUh._֙8P-+rʘ]"-ȭqZ ʦ;YDAn+-[Γ\`R7q 帇Pa~9n"o>i޲wh|OsbIq˴wœbGq%*GU_T[!xAp 8Բ83QZoY;./iV;Zn+˻OzּW<Q^ aYp˱r.BEȹ9B\,T@EVw__z*/'ۢYoc?zǿ W_ǿO~~~BRZY*t!> ]6w Bifٛ' |(rFU߇f *6@*@*@!5>W+|4V̏m_&!Jg#PھLugFͬJr3K]{) ?{7t;[n3p8]MJ* q"m_*qɂ hx8EF8ix>‰dp283(w!OF)BGZDgb{9Α 68bEZ1s~q@bW({)sxV!#ɟǟGi>#5ׇ@f%1l-5o \3~Sjj'{ИHGx0cUEV+ݹ$t+$0.)vkA3^J}eEn0JNڢC;iWQRT P*ixZNQ>>f ]f>:k |k`Ɵ47G_N}*yr (A Hsߖ4d>>F&7k aXXX~<4o'q:c'C8`TH    ϦwkDw zH {5/r^7 qb:w_{ݯlt$K; MFFƁǏM&^7w׫s,@T_Сb( # # ЄK*&:!!!Ѐr|:yjjj_o^Wdkmäsmy3җ ZqZwz< ?lMirVlbT4&YO$egX6*O2z^yXTԲ {} VVVzl.zwpl;[t}'黗db!# q%:_"B#wdev=.&[ BQ6LakzCjyn~%"WB "sideUݏpjLp1sOzQ? &-֑9w\s!%rq<ѹu+8#n/!|zOhmGɫ)7$O׋/Y?Ɩcel&DүND7? `AJ%#/ܿ/@OV))^1[m0\Ә0׉Ai(GXA S1%TPRAIz>ٜ3'Q J:/j^J(hyR) pl6I߄)(UCm ^XlT"%H8ϊpppppp8xzzo9oQwC n'k(ՀՀwվ:?biV,HVi j6ԊP+vbҐR}479|ʼ- E;rng3~ 7n6-s?lvi$RpRNɹuA%(A]ʃp~W2E2E2O˝~BbdUEVRN{ ˏ@ ZbM\%|J}^W{OuldbQ}`FL O|Oc֫˵#e|lZ,?z-Շp2}w %͆Oq3 (.= 59vK4X=]3 pP?-ࠖ]'wCH zX֛`vћ[`[ٚk=O߽.?&E%F% Ycĕji|)mzߑ{.&[ BQ6LYkzCjyn~%"WH<7 ueUݏpjLp1sOzQ? -֑8w6\HɴlwfDt}4y]=[K.u Zgۑnj'l:~ wxlϫ;AzhK *47hOoz\$! A鴇=p=.;]VR/vbg"mWy #s A0\ 0(_^> oőxK}=E'4T';^ ucEXXm`wp`RyqPB|)     ͇!\B9pppu~>ry;e 8(8ȋ8(gSUaƢ`E?&\,' + + +IiR;(-8<@H@&+}*}`PPPjmz 84y󢊷    ^PHx`Qi{ހzGPˑ.yToQv7zJw'us,@V߀:vAddd{Qu /λ<uW盳m %Hm.S..ZX`)y,GH^fXڌ>_2կ^6}|{[;f4=hz~H.M]Ηk'dǶ/o`[OveNfy|wP6&jh%.TQQDwp]Eq54WL.dG+W?Y=ͷ-]jɑ)8Q/P(4efĻ'Gxx wSizL Vg.n͘2G4 jR%`fgv8J_CjN_69ڳBgql #_Kn`llIަJ/d|8^hh^4!#e1'|_*V#E ?!{}STM!gC}t]tT ?O4Hh,"c4`%l\VpظNeiMR@g((((qJjBBBB Bw;C("tޢYC V>+D]۬ Ctψlg+p$k222m%| @LLL L>ܲ @(@(@(@}AOAwC*&&&&]tɡ@ zz}-dQ@P@P@P@Bг ET= PPPP6=D^ 9^BK^    bpKU'N4zu:x+mOs|ytjd]rK#t DaR Z:*rGhrhOR&d59C^A%wg%=]'׫ƜF YGݿҠ15 W ܇撘%6A.GOP\vF'MS...`x;M.jzbXm2?yV4A~FTDtW+'{}xgg7 GƳm /@()!    M0ø܋Xo/t=": tM%!!!|ڷAܣ5hE@U@U@U@ջPݶ7țC7/xmoBBB¡oDޠMi!F[>@F@F@F@K?pp@xHoLyϛ~UBw; 222M:vTNzwuJVVVVZ8Mb+| d&kSTиMiPڙfw۫ߗ ÛYͷ ,lƉz!~ȇ26ҌG~g'/ӔI-yr&R@MVIMYCM&w4c/cg9 #=כ`v| wLٚձ{y]~\MJM(KTT]dN`H el?3\IE2I(,6n~%"WEyB"S%YzYU(Z/&%\\G"xK^/s6N[857Us!%rq<ѹu= }7yh0?*Mkh'ŗ,ΟWc+tU/O^ )g _~]P6u"YYT #>9uRE$ 7QcLJǩ7.7pM늛{8Rz:x̽a՗kZ3)2h!Htu'Bi,zᾚMW(TM'{1D-4U#fR"kߔz2w] ~S G\nD؍MTM5_ \DU3T1)Zdt-X&*9cjn3YmNӿc1Q\0j p~?ڄV FR!,3~`H1v4}?{6"D?F < W="xZ/n^'|vݬMҖD0 av)KVNob No ^!m0zg$7E&(m5LRɂl$;2ōf3Rs>|ccnGyc1]9 /v3_P9HHl ܄ "$!) `!y;8(ҞBW&TޢHo@\4_RY9D x}@(8JhK Ҿ"4l ܄ i1Q݌`5&#) $m^Xp%)-v7`|S\$(4R"">b} _J"Az" "ARhhr念Nȉqt"= DÈZ( LvTorلKvVU>d4r'T*r7 ]>8B (t[>&w'Ik+⼏qjȦ stIH/xn[EyE%ݑS5X̾Y} a 8v I~iX֋DVҶ)>O\ |Ș-{'gӝ}mROIq_l߮K$~oaXoJ[L MZO-Sg{WM͘)Oq~Kiז"oz0w Nc,9>Ni}d wkcmWoS7K8kS~ѩc9Cgi+H/"9D]D Npig D紛 9ox0 B% y6"QvQ8QiҞovZKo: E9};2*Dߓ&F< $`Ùsf{1:I:Rgx6+u 6s`a] 6l0hn gPa t]`sg l|`ٕ  ˧^W [3= qJ: 6o&ad3軸VM0d&ln nem l 6` #PlgM` /7g  db &h5` 6l$\cF" 6l1wW`; 6l|l 655ZE?gه6qهv}_p_n}} 5;@_6V@_k]םU}ؕv]h5zyoS:hVU}PKQjoPKAF-Pictures/1000020100000184000000FBD728AE96.png\Y&ʱ:r+ ؞xlv,6׀1n=?wp.;|Yb =AV:箪NVK#su3ՕN/y; ?_>3'`ʿ?`|_~Gok/~ɗ:?}c/}G'>_O|?oh>> 4Z<c666#n7*\.Z[kkm7WcTKp;E;SZ8a+|[ 4NRNbJOdTCn"xJ%$I=>K@0a nF׺jU߀\4Z[k?QM֫_ákk|iykfm|+ZzP8"033w)s(/p1\B.B&)s* 6 @ʹ䐿<rRѿ}> h\>0&WAW:l#`.E(Vs+Z!nE_pWȈSyk-W_5 vmx<>p>KC8{,#JX,R[/s\jܺOW&H4(j hi qzy;r#7hGO>o׬I]&Z[kk6YC>/9i=~.µi ~%}oHQ🛘S8qu,. uJ ?o =vW"L5yaHY58 p:khх`ȏ;-7hxj+f uEY__9іD"|sU, ?(˩)U+Ykk']Kx_ V庵ibR)Jst!BZ-&o\k?ަ` k tt2 8B:PX6 7@!*C; k zf.N 8y^ ]X@SS:34 J=2BYM_Zws0ZhW nu ;r)Vu>DoaT^ \@"cA#ʥrAt"'DI{UE&/°"Lk52x_#ud%~QLV@Ww1:>o7xۚyfkd]NOOtZK$\޳&y]g/9y~a1<*۰k.C|k\f@P}l|R˩T8~.gR^m` GD/ba_ POW n@NG⏝ظ~ ,UN0alAzu~RIlٲ `Sud?:V{(y]Ȕ827"֚lz.xוWVȏZ ]=vGWKhw39.!>ڠ&!#*E8W1ISNTYNSݚcN)䬩mV~fu͚[;¨_:׼/6S+]D!ߩr5T6^rL)LQݙ_8ؿـ[(y5jr nʺfi֋Q'N'^#K᷽K 4DΥ)<4ψ "Z|31?i'mYz@|N>ݢ+1òFOXٌ0q&WuR 3< 7<^ j"d!H(ƅ.ﺝnë*Cy@mB&i"A Y:tȔψOAC`p lSFUC^v-i B>/Ss~.uv$,0tD89E.}ávQ?)*<aQ?(uD~ڇQ2uQltW&BӐTG[Ҕնm0(r|(ޜ *FY"7g3怫{\v,ޠ q~PZۇ՚h8f.[5͟T2%R LYὐ5;K"yDgʋСn,iGlOhUsZO(|y{" %ֆj mᩋ1tX=n:|;j*[HŹ KY.d()Wyؘ UE%1\v'Y/wE/5q'[L.(;kx{ߋn4#њWEK ^xSH[9$BQdZ{sKTۥNGmmGK ĴSەId[=Ne NNbN㚚;XK2f-lNf J[߷m+Ebrl'xo_/[&C&?"l`k/eNZ߯4ks=qeԓ{6L+zc9n='rz$gњƕNƫ.j7W^sNt7F!^ uU魈]'yp:OGs:2 +ZeP*N `Pe@ 8VꕎWC*V> j6Omؾ|vഄ3Ǟ-;8&5qɍ%tt5L zZz( ˆAE01ZӰr-k,bU$ M~=A4'Oqir^9JI(}=mJ؂'N(S馛؉s I欘ڛ\V=tz$]ⵃ V.AR"ڐG؄uZ׶ayYlY5]l\jvj& A6)Đߕ0٣Gc纬8vMM9l# s~ 7/%0PXen+bM~?^U1U~71:F\xObzx>]-Wf5ڟ[P}*s^qZMC~/=^(~ yLiJWc6 #H$S8WK*Cb~vQ EgȦ((Gؚ<]W|֨6!78bqdfq}{|~R)8A<hy=Y>}AOFs4F 5p&HWȼű#m{n U|:õEg_T|ͭOcs({v݄ήn,s&i*es)M0R4z":Bh8Q\OhRFXLds_;S!>sVb 27jd~֐t<M#*2'H9gqfLN΢B-'ĺu`mhlCOO?obddZ4yKCQS0IJ*.]Td Bv*aZ6DL [Xy4t9lڴ .MU~ m+n׾f?^|8E.|bo t8U[v?H9&:kRj/yff'a+ښ"zʾpau)U1Lk^ND,>__NU9o6QNFt5vJ!/qrA"$QΦF ۊ, $Yv,UjxWIŨHɞ%FSbm ֌ۃ0g.p[@4܀PW5* M(q>wވ_O#ևߎ-P \*u$,NYafɱ]qb:x*hN^SvHOTL ,(kIoj# qYNRu2sarc㦶@=ٮZ]h޳ǩ-T0Wv`*15I0wѽ SÈvՠN6*]H2 O/7wq+8b(3RsCKLT"F揠KJG1 +Ycw^/|>_ԯ_[qr7`y"Tt*P92O~*mZ ko.ُ~B)ɗ%aH3.WATL+t^Opвz|rɈψC@pvjk߯vy%|F455L^8fb(mJHⴢ/kj}ry\+H\eag &̌bn|&$N];Co}E%tt {|ʺ#5.<$_ @j`&_)oՒ{PL0+gC7.]BWk7|.FuI$X$9̚C+}i/P48?(i,_/ *j:j {dw"h EHSm!LXHQ7#ݞ&&Ԅ$\^B;wQ:v'ϟu< ^O5 brj P}.22 E?6xin;Fogvd ˘L V7+Y-'QmF9Rk*!]mzPvQLMH{Gis" f]=5 OWO=uފ7VT[4ڦ"~ n^b_dI[0Gh5A.z1s/X^GzL9JaFH#·\b wVzvyNQSJLTTȸ{8q؎ƲI#K8j MWU", p!_KG7QnEs?IP-RS݌م4\Y J9 48t\`czbgr=,%XV٪1hkE0 o(L=إEpE2$jɍ7fg%EaqwފJIшRF19(|G28% ]<Y\'}q<`*W3u-\Q>2;E`zT*N c_',YLw6Cvկ=9j9-Va 7kDn0)}߰ gQjƝoİٍ(F4pJ톗,<( tj99iDpQ!9<5jE*,LO_o9K/i{3o!2ԏ,lR~j䣘n[n<\b%Ϸ+ pBtiW|L5`fjœ%/jTV< :BVxiS>+O!$"ڷؐ%k4_(i2Sz~Sq-\V4]X/\޾~lÖfaZNT󂘎\KՀ`O+6q&@J"&yKؽ}'oٌKpI/1ZoUN(J6W+j38͍u[n&N9,5gjf\T?Ns<H"9S.;>758{rLLaoPA?džې-|)KA#,e]N+Zq492P~ix>++YURm.47wqvxs\O9&Q69] Ajs܉jA S,)]R#d7Yl p<5Yp1ܰw" &Er ai1T{EK_zޝjڋmk#j@jo=unQH̢U g\wiQc'r\7Q.l؎ū^RӘxKABg$iN&.H丟;7vڌq<6:m_5lټ?bYÒ,Gݛj;'1ZV!kƂr!X*[DҲi4pI(bja GH wip*}}R `9w8zU^;|j۩fC>kH,mwWA.Pld+٬9tqۉQUO•=ANE*֠4bzr \Be 6!;}D]d]GCBЄp#i2nVywCW.3bvP%5lp)&\'aR^_T[jS㡽 ,lH`7؟) Ze0>u'oكYc.qf2"Y(Nzn$b_h܉\Bd./!R~7"@j#*ILd\n շyDgص:D:((4%)eqJjGP܅|_&#S3hEpxc\e=dg"ʅ !&DJ`- "j!7,~7w?%xs^ضc;eGe>,>Eww)[yko AtOw=3ZQNhY"5w߽_Bm0ޜ?^|E%.(Phjl$u# Xnks%E{4`ZsI/T_B謏)8'd"AH*> xz&xCjC!EE/fX^n['VRh3Q Z[{n/NOOp\!jsRSR.ӗAP*'vuNxP!sͥKo6jCȖdjQRsϢaRI.x۩$ RAw<"DHt]X~*&,Z,nDTJXQߛڻ%XNƱq}J&HsQvlИTa/fUjy!ဏB} }pMg32zzى\*!rQ5(TĿ!U RcZL{|hi7܀Brsi8|R_G_K;c3AF42< .AE!(Q)x(݈wqН(Skv:%'hv_E?U 8*Z m[n>twS%H,N ~oW(3,E-s˂J<2I׎(uT mjAg{AO@K=%kmAcK3\~T3![BG\~ )y\ŶZ>1>L*G` cYFd ˉe=2LBO{,zp!23T>}sz"?&ߢ)~P3nۮ!F!2I-T0f<[a?[7[Ƌq##iLdɱ~C? 'q9grjjR]",&AlMLZ{w=nfnj#̬ 8kcq1qйr|djZRGz(谪4JI|Aur} 5%p)"dzD)_\"+iſ7+"Bj~k`ۥm!w.%.,,HrՠX!t$!\تRYUMv8 !(L1.;*D)zsqx iݛ[ZA͉߯b? ą Hz.hLt؁_MWRLvr}*,JY.5Xq*Bg9ykĦ FWGyZait~F'0:6KatY)d%oUW!͎?VHs @`b&-n/P//H=5z| U' bʀ~-#|^$ >ZMTeuK/'N):{FG&y$u0(P+9.Gws ťY[.O~wAM`G«!&o_YrY~d$_XBY+k.dyfj.Q+]NHf?{(KTnx6#Z,>D/(53YEՏp]`/3j ۱^#wߏKg|}Pvj?x:ѹX CN xeЃomL +;t,Hة36C~u1 V$bbFK!PpM;@FJ܈ 5};AF/{f֨x:XCGݽi$Č[Ҳ\1BBfM6]qsu~.LяEW_KޯHR|ezjPMܟO>iWl bioCI:G pZ!ۡ#BBRV'Q4w}7z.m*ͨ3CoZwUc˖-.rJ8D7m0v<|0؃(h;m:FlڼYt:!Q8nby9ɩq;ڼ~^wcn~ Ssa,Ƴ۷Pa Ȭ3h߹tM5nluwO}>o؋C"$ݮ17} O5GCw%[ɭem-O9KĬ$Մw e(bsPsW5i {!&ek/@bqQj&M"Vvo t;/l9RsT)^|ʅdex&)anP@wj 9d-&0cVAZ'kOO[NE(`Oʼ>'=>|c4v#2)C5F[twb`..hw2*!Ez y[f"Z`'`/h G98}u|?B{{;5ul8Zۺ4W$a7ںvPGה]w MI46au+PBӽ'_y  V,/#NED7L6o="A"p;H={NG1=}BM˙,9g+ݫW"O>ce`|@D I zHv?_] ׄ~@/ Qyæ'kOx饗% Gt^ʮY+BH.5~{#wmk֣O5DPn`. sZ:y_^R($PK##jn `;Z%:s7߼W&+UZ^+\2d3] FYp;;㋱sNSX݊l]}]d py +ـa!qbhDS.VIGfƻ{KK-𾋘#ĥa2 x\c4339rNaiq HS/-I=NSZHG"G$ukX~:XJcϞ}Z#r9vj*țG~F.NnGoof|`ЇHkzbz"X -$)La%> hj>4u6"ɋ`SްW3M:;7OGP~ZM2':U wT/`mBM]yV ڋ{(wދnj1B%N`y]#ƾ?}CjORpSS`TC 1խ=pd~ :Q_ߏ6=|nٸ!GWw>Yț\oŮ={#&I|o{a4E;݆[o MHgJx㾝t#u'iUJN"@WSYL"ju& 1gc(@ Zbm!2bN"O^%*[oJ B+uqD07!/., ijn]mWG,Ikm76/_&QAuیWojBZ.+V=aMx=Obu*VQwIAyD,/ 9snyl۶ ~݆m #Ac]#;l.oM5N虹) __~^m"qa c~aFoYkF;09y j&|]g^ |67`u;iFJIe٫nJAnG[]sz>$sr1ɎC@!1|<V*\:e= \ԬM k"Kڽ]]U'My1b0JR ljHX,zض}N<~'8z{ 0AEK!8Ο;0JEI#s6ہu]`@!B#%撦JWy8* Q ϔy)Z ޯ晙iNL`t(2_ow\>pVZ_yiw L{c9|xUYy衇4Qk"DLCÁ+u$Ő  Y Q &^k֜W6'9(15H=iYjb߱c VNkE[0[`li/}KQHs!J y3[֓$ǟ#'tٿ?SsN9rD\Gi1`4Ocsl۹xocuZ_Bab?5WW ]utsm^|6HŒThBZk3q޹?ٱS4z38&ASS+b|*q& O IpG;;LL` !f<6a(Yh7 G׿=ZOO,5u-K?Hש%$ᓟX(̛oٰeضSN_!;,cxߎhklov`uf po8. l۶EcJ1TȥA#f JMʹJLZ8vJj< $f=hrb={{&&ﶻj}ǩy$Z!p|[UuL`K nfeVc5-X7uIdzl2@ۮԿތѱIPa%*xjFpa=8sn6wiW&)bk~=ebӦ Tg16>^5ִl,(ȋL/[6كZ8fj͛ Sc#uujV[p3f+\Gc7TBp|p= OԜ.ĩ| W+H%1Џ" ϠK7=4J2W)@bhn@M={k:6!L[*G|;1D-T։ߡ1گNrn$\a_=xBVpmŒ)Dͪ I"YV2!5 `2ҒkM#Dl)hZ Q .CSK]>іfcpyKqaETCM'",97"g #n5B6|'!9-/P{.^-[Bdf/X_c-"wDȺS`Hd6~k%$7#>۪O-QVyLIڒ.& 0ܵC<κ@O՛D~i0K H-5Cw9 O=U?vӍ7߶}෿RɒV,DD9]T8gMsX2 bvp t3Y v֡7pO\|ᕃ/cvv[yC8ꕻX+/ PJlyjTaF.sRbvz\KvH}^@#::%nHY(|a5f.q\8)鳚09v  VԄ\Az{ݔY{~/</j6n|)˿I}عV\ZJ)j~G}.D//B~ϟFۑ!M'0w<{N:;qIAn$=s(J;7ݒbQӓl !\A2F X!N|l-UF ނ2,,j FlІRŹBq~9 8selX^:>. n&h/Ȣ6wkxh?/wI[AXH1J.4mZz*V(>]6k8Ϣ\%PF7!;PAj& -yaF^A/#NućSrUdTHR iDئ\v Ok17r ^ցFmY.ObylR+"3y:֞(]_?ӧ-;o YQ6~_N%X.9s~z-T>+NY$UKZb;}Wo@A֟Q߹6Z~QFiz'>z}-*ZŬڔdŷӃBDكbwjiӮ &vǎ_~E#=8>vҌzK,JҿkXq˰dXXoh(&a}}ݺ[ŋ^D|=mpsy9Zv ^߈.0'D@ ]}}oʽX%%X;ՒNpy ɤƯK3㓪1jM-԰H/'ApCSl (wܧzy>pݞOdrUw>8Fyv&=BV2{n۾zs>4jMT*EI4IfŅyĖb$&Ip\J$O*:KRrUoWba/h6Dt#Zdo߲r(hXϹ%N fóhh_K8q&Iݪ)~,+|xpYj),, g;zȂZ1=9^>n]m_?S u<%``ڎ ـ(!Ij|Q3ӻދ_"(=L|x 7n‚Md53-;dR1)T9J&cTJR?n>CV;v5j.1E$p8bf'0:n~I|?n@mu|E0-ѣ~wcS{]ܳ_%JCCs m=PG|^l~wαomVxC3Ze?ڦ[^;av$. f1+WnN)!̫˧ŖH$I+KSkq-`ۦظaضc/sm5#%oQLtϯ>G "jhi@"XCGCCőSÍ i&  F'&ԏ!f0ـ[gP5}UPHf{R0\ jړlJ ShhTxbyI"Mϱ'5g*صKKU({ٟK/Y-SK^Ľ]h5x>3OC ֋@!$h- %%h@ImdSwܗ |{ abr& \Y\EGrh !%KDcCfI5$EeN3>483t*5ŧ!%[R24 lW妹i=ӇqM I$IUVjvļs8\ߏo؋?\1Z@:ZnDjz^>0k-ʎY?@`7gw_,KӓEN7r2i5$!P֔W'o D޳7x#n&ttv,' t\14zi+5zraS(iv}Pf`ζIP`M7lڊS %;n̘l {PsC @z{vw?, L8&Gg{X~ Kn)tz5RE@DI~l(Ŵl-7xqwvfI[#uێ~aO+xޛygO7@F}[,GcILdklUBT25٭MÛ)ɶNJH qnt>hIm3 E {罞G{ȍf Ẹ3$*'Et#QƍF4F#q꺲ĈUQCt {!J,(,Fi93OiNy^w SEw5gT(A`y'-NIW[eRs{LG-֖J ˈ*L$D<'{6mc^&"乴EYjD.Agॴui>::kM+ AO3g4"c#_UH`ks3>}ZLo4ښ> p,IE)^xQ}\mgSo粽?+灨;!Rn R+BPMkꨶ~hfQtF$wȡ'8pQ JYgt/52_(5 K_v3:ݛi%3(IS%Ãŕ9鋖#?)vɗ8Z:[]wꫯwxv'yQ3ސu /14rB<>3At7͎=1Q]U"e9zT6KÎYttDan~i>G_/t#C^^^ F HDJ`'¥*Mi_F\E7P2Ӓ+'„`e%XzPע ~:4*]; %ʓ Ѫ OѦQ 1Jk4C+P- Nh?xE5#{vϢA~Bhk/8AA5,_+EWh?i;{<~‹hlj2XcK}QF14؇+(:sIHf I{'Q31ҹ9Bh(pzz#ƹр@HTjfvloA9҅K'̘y-3.-M AP5 *D$3 vE`tN'KI'tD@ĘKK!ff̢McF~൐+3yF3y(r7ܜ0fgK-0dÖ߻|{9!NkZGت#-Z98tЉ=~)`I7d ;1n֕^Y\ ==/]:_x)CXj=Ao:'m'dGId,<"N,b++D3ca.5UhkEnA`Cq)c!n/zA,\g\vn}kG~72jq Љ~ ͎#ĵw9$*kO'984GA4#ծDt3 hYP3JYb }s7tpB5Jx$!ܺ}o| 7 psMƮldf`R2afh !-*M4M2+# WB++( gxVFRY!&t2`ĕBRd#]}79F#ɆZ7z~aiђ&Cav{ M1!x ]br~N]>'4#Lg!ub]qE9\ŅX \к4#緂%Q]WFT紽~vc X_ ?\GN(@YUB,!%fg`NJ2a~,/#ysY0#A! |^,(|t,BhbT %FdRi^t$ $B]bPe/-鼇DK^Ј1 v,O|XkDAaxӨgD"vu4-I; DY]=v݅V\x.ܸ/|)0ߏ۷.^ZiFںj1Ǔ6=ط{cҋEG gm)_.GF.o@QBaaLi"tF# C=R@Jhw[qY4K \w2\K˄}tUJ^KggrMV?)8|pfh|^:_hJ:_لHϭ{Qg>P׾|[7Vp*At;b>l6,ct6KsMWjв/gt*`g`+BVzͩ6!7ΐ~rZ |#E$-SD >"̐ld:~xx`|N߻ q>x xHPTrFc 1N/g7R3gХ- !.'ꛑGT)iAF0"b_S4wi*  )|(#"CX).jk=7bktJk;aѧhCˇ_ǣI^O#" #׿] 􏣷:(Ǘ Zr173vJF&Egű BSPHHBVFQ-БRpUZD7 ݼӊRqON`}qM-ei_b=< ҹ3ng҈3Ii/#鄯8c3pҹLQ+gp &:5ǞE'H%#]ՓFi\-t qMa`tmS| dj+ss Yixx#8]|7iqnt5,BġI5*a鸊8`~)8|x#{0#VTqij I4@ee /\9Z-}O)QqaiOvNYpa&L KwtE|D0ZE3-1xKUÝ[3PY:\0'|>^:7AQ):|RldcխG;tf Il'xPٗrV7_:nz=#f&m_~O節:q<2)v$O2Muel5.*DfE7[CT6a |J~,ca9}5Hn019t:-,Ho QPc/3IzatAL+r8@IY=>}Y۵ uxPۀ{@CCT6i6C/'ч 0*RKKc_W`砿o^xzH;K n h,),źhivBfS5 KJZl e~u-&'ZcCX=Dǡ#x)Z KQ;Q+FuyVV2>_;x׹6sz˱{ M|}عQtt1L+QIM}|I O͖={vcסC8|?c*h-+K5q_Ѐa\|EGm i*Z^FF z_pu=8j:.YKxcs\Go_/'GtdDceuZ)IdqjzdI[Rb :n2JlCM-iL,!ؘyNF4aiG Sm*('*W6ATDd4ۢHY@@gI%b#ަ;v•kUpbZ|i>s9[|vvzvk9ȏ)յkמ}gNeڤ6;ȠVRUys:~5/U*AilJA(D3WZ?'pߓd–,וh>AJ.]> {7s*w!$49 Hw7[՜qqiiX ӡD+̧ CEE3Q F0Lbzb#C#&&bB^/ ./aǮjVʴ'gp'F\vx1% 7c.r|4oWUx!i`!4u/z܈i\m+1/侳# ĭ;W~4sJ,Ta8{tBHHE:wx xNFa}ZVcxZZ+%<*C5)L%G¼YLiu9Š7?_IP)4ٱ1{\'2dN ~ܾ ,Qֳb:ҝ}D>Jb$U/_Lm-+D; ZUHh 9s:]{ݷLM܊"^(-.ƩN)jsg&`VqTp_ \Hn7vыLl Q}F[]ȥ$DzuetإH(//|0=9mtxijyoj4Hc#G@&6ŒNov+) ؜ )5!*YY51N [h ==y:. tl&TȄW^.a?х9{}MyJڅ:O+-س #W2hC"*xph]O({dIEm/<Ku(JBaÌʂX:J7@!Af!ޙ;wfhtmvSSD|-XĕfUtWgyOLMcx "J:<9  g1Rh4 Pi;sR'j~wzjZ ~hwj{ueSYg-=8Z~s l>Jڦs* m<ʈ˦̝ݰRI/1WI4vp)hJ\UxOhmN(.inxL*6B'a>5x|n44!uUD4V!\ޥNK019Ƀ>^'J yCD$aV߻;߿OK^K/~#%* ]GeX;/[BmE9i"a!CC'?!m !">bR/ߣ}i"]av+8q)4nG5`!# >/A *7Pε_<+\;ۈە.*<+@9Y 5 ِݢC/tjVFz>o{m[3y%69ɤg'0˄IJ ,* /G>BGuiSʥ/v=܊u'.5-nIU&t8ߥC:X,.#Ǫ:k$F{ʽn3W݇F'Ũ)Q^tt/ʘ E4BXfX!FU8N._-2=(s{7糠KVNj(c'xth;'AX?KO!$6{COA41i0 !HSNU4܈g*üt=XSаUS9:}#@v$XCWh&z*)!kh: 9'IC`WQd-X%4MHACic fxgaf6cxJ[r-"T2d1ࡕW%Hazf }}'#z5snwEOſA_7lk"ҋ~lɰ^¯k8;x4/KR\$:eѕ>șVbtj R02ajr᫘i!mꕫ:4r`t2B٨5ŢZXYW} qܻu NA;ZhɈ-)FUv5l ڽ[[M.؅8w|6VFyh؝e(s%jO NnS *S`Zt!T՚X$};ЗhD{Pqsu˨.F8vs"i.2)SX]c8quT ||:"ܯ:X"uPF yܸ~S ~p-seo<sDת縲1EuV.qFf]Ge]dTk_(C?Ә]X~i4:Q~}vHd ۷Dvwk2O!rR??V)&Qv8=Z( *IR{*<C \92S[@cYC]z!CR(#0<#.&t5lNNLuhhl=p;:&-lz\N/q j! Qu5hCFaq1!FtDV,ۇ~֜O97>v*QoiJPYrЎ<)Fd? &MKIv" ʋKQSYW^}ׯ`σ9{]~iG8ArnWa`aqDas[!h4}˫s޺~Vb '%#䡍UJ;wq 0TWZ\vӑ~:6OT5ZBC׀mՄr?k '|A-͵jG,B'} m-zw`F޳[SsVwQA %uÑ5m3#:NJHm F3:ҹ{gS.$9ghV a]I}"5 q ?AB61Bf2?=*Ǚ8ԫ.k^+Dʔt\LT,hnm3ئ"5[Gߴ a#3 j jd(m'mlM *m][ `QJW@U]3t& MuEr 4ڱUϏꐅ9[~j,h}NZz34Ƒ fzSqk~te&adsH K8|qF'gbϚK8,w595Efs ^}U *շ̱DdS6+9 "{ӥg{ JVBFqd:vi0_F7ﵩ=]{ʳ543tRӗ}d)3II,3c;o߉7$L[˕&Tmuvtۇ!t(ä%Q?w{L%Th{g Bw8W??;<7٭n)3Ts3ʍs `M*2bVdY\R*+\Yn^Yfm+)Fu{GZgvTaqn ӫ܌v~*/M}%)8zXl6J {W+wx/J\2($nVx_f%]DgcH* (GM;5 CӳSeܺխn:%W5|3?OG#?F/E xU5jւ1Uz!]^ !Rsu%*CsSFz g6c_<_$xc?GPζ4Rn .ׇux1>5A|կu絡@0?A%͜QUHkjNK, GQS]>|PY"߾St 3X][FkhkmZƻ`|bqLj`di>\䤡miCd M&M܋2qy42* tX 1<:&:N>9ѹ!~r1{*tmp[GWW _$2 ƈHq `d@gG ۷c w{/+`}shq2#!5-?#Spch^milAmM5.^#ashsH-ۦ^ o)DR>/2>|D&Hml%;t{2"&@B948JT$ar<ΠiϽ^W5 cJc1h Ǘaw GX߽KSJd%Q X 2UqJQl1o@x 񉒏!uF"<^=SFpTխ$8ad"Hz|,,h^|`5ոBׂqxy\ p;淾8gw9m686"6N\~=쌌Zd[_&rѨkXUT0*4b~8hA*DhAM֌ʚ6_c[_::[Sԩ7P+T~34ԼreաAcv{~HH,sHijjo|zbrB$eHe$r:m;9>"jڴ7jpm!߅Y?jntï AG0S^[TUhF+NÞ8r^^1vܑ!H?/P40{z07@uU3 ҥ[ETP D(&EmU5kk_ Z[xpm)V |$'*kJoTCM&ށm طk/za<hlhlDhWi,7^ݻw[HQ06b %=%R`kE kH(HzHW>1}-)jӅyZOf}WP={!0d(5BD-~鳟Eya#`XS*XY+0is)׿#j 2Ft" SݥEe\WUW؅єȱ%R s-Bj&?֎X-ſ|9ǹBB݅"<ԧCk:(Nܘc!BYE=.]<+5aU5#"VpFԿԺuwgX74b這893F=[/K2BNNl{Ҥ}8'2ڿ#}O&b%oO<ɍ ѥg\X)Ts356b]T­<]Q״d#$2&/!uh, u~HnR'44qܾOt[" 4Z9yuV3/LkJ0 Lqֺ<׭ރ٢ ֝8pp/zgfu@&>D>>jmiDrqE56 &5=e 瞢Ey_Yxw1Ľ{()#a\UA";7124{XN:"eaK4tsX[# z.⍴2ɼKK+Ro;4b<|I334mԉwIP(CQwzR.tr] (6֡!?x@cnki$83;KGXѶ-U-gOĕg2*iX5XuՋvs8sL6Mj<ܷLCidm[fWgNFl*6+2C:GҁWWA%Bw阗@2c)mbyeζ4Jx<:BsYq2i&d46Ԣ@HԎwЁ]xშF>ѫtlh7_ Ha<}nkϓ\jfbDZVUIG@eŌt]3)F[[;}!H*М)lKwK"vnrbJ cڤDefiLնv# m~:"<}#'<=|riCZa23\5In$Z}^k@ؿgvwƍ[]*k'EκseF:"?V Nsui=cM{rD Xז@F`0|\҂D.(Bl- gQDiG1ҹ]8Q"Y8 ?ΕiWKߟb+;)_KDU [PY]B/~[8/?3;5(tyn䇕V9 b gf3Bʢ2ͷagمqܽsG :1'1ɤSЫF*((Ԏ%_IzU"MĩI!3şۿo?nګ|-!TP<5irBׂyF v^W> <>Ivh\eg[r,5XU,IYHʕIk&My! 6ky:؛u}10&!UeY/!O`Ɂ%mF{4bE4KۇA)hSp8\( )d/IlkjEFZWnNV8ߺ4•UTF0ccZ`ͣi\1Xsv4[p:!> 繑. i4-kotuäҙT}H4,aY-4oIҪbqf'0B) Ƈ5ڋ0omڮ1vΩro:93&=)EBBCVN1g-)8\[ZEa^>v@CsnݺSreƒP~U6$c+_QNBZSF*ѡON[RpP͚5 WTU``n"\N:w*;] N/"Lf;k#OSo٥LHQL44v2rѮ&:!_Y&!ZLX>dN`Ӗ4b6ޣό"6Vtz3|FA93 @c >lo+}&0KGYů(s4 QF+ rt|Q~ ~KUHы`xȏʅm(.s a!|xgS4./ ߐ6GOY<ڕW6C;qԴԡU动o߼5aF>%m^qqIPPȋxw( }Ͼ'_PP$Z&t(R:eZDDe#fkzJ$M%,f:ka8sǨE MLIXs"m;WcyuO?vN?E9-f7댊Pn73J@ 6#~fVUg~eV5%! d}^xk?;}'2k\&rtH>"7ơLA1] )4 \48~xn }U |Uri=重ƴ(6ݾ pX`Ƀ]BԖPDs.9R_#HBY@9_ws'hj0{Sضę3g d0; OK÷ B=V̨iJNVu2b?iAue Fl5EEh֬?PG>mxÇʘ.P(D8) sw+C54PCZAxv"ʋ$:{7p Ư:J*-y5\ RܤV-Dt4^l؄AGG i,.#ž{S`ݸrga$1"m G3OEh0A>vԴ.<8h(1.KR8n.rF<1ё1\Ћff=}$ EF{!.6TTDmamň($>UٌXYBO< K%n-M|cC#uPo )_?џ;ZvQ:b<#hlD[k'FʫiwѓO "~x8a~>>,2ʓO,Qnb+SKRI"h2uQC }ֶӌ@nV:IƗ_yY5 64= e[Ln(aq<|vQ0R1R:0?H wTv3gsY +;͜,qm4s}/mq̆vm[^LhrTUdsע+r_O_0N l9o^").]ɕtjNU, D[ =`CH2TB &ԽBU[[Wu+ 3=|,zKqEu|gnj15tj3ʪv=^d&AHD/?)Va"=3ZP}416>z C,3cCn t@=|ffԡ{~a^GrCC|uܽۥُ= 9_3~qШ"f"I:-Z/0u=$b01,7BWRF*ב{!TK,APj$ uCOA[c~N-sHsD91,u\;p&f'QPHNC&Z>,)GYu)&&й{;|FPi}1M'eDŨ @i7OJ:9gϞAEE>7ޝw 26QRG,k+?r;tyTk-޻wUeDO_EN:Gqv'%՚+C4&7V1?3!@J;*I E ]̺T2WVF/t\s:rO,-) "#&ڷxnяp=BBFA-& ؐ:Aڠ"`Z ,3]ƞ{uHP-ܼ!89RcZ#dII7EEusbU)h~?_7'xs }'S/,S!{&ԟviLai Fm}MHFXw\;1dcI]IM権'ωp(Ȃ _;*-}Of`\7]tֈĽJy<˰z8% :l&:Tӂjjxhq~xq>zzgRZK\%={Ȑ_=MIMB³VR^jCT23Zl b4b ,q 43k8@I[2RQ6t*\j5b$L*BMY)|#D~nx.C=@I6w_;"zC,.ÞNbhtVSv|`,BW`ieQY /u  3!l߾h׮:/~Kx꺦8LL<O37nI%*Q^KT=v/}e_0::S0YmصoJ*tuF#]sie|Ҫ'ѳEv(@G>+iHxJϕez(5L`܁nzzZBR?%53j>޻DҮ L;:1H'lG{72"L2߳'Ǟ{{~{#-yEyM{` N- Yaa+3#lfUgΜ!* rɯ-,"vya0;x@QH44N^{pR ijnAbKJX#*[[StCDey7 vssHQ_\MD2h cHrrhbebEYfg5U624<8%QTG/-@HUUĤ{:u-Lj Z8+:y(ܸq 'OVUS_5m 5b?Ã6y1]Ý;wTm]e »cn=t\z NpZX73vU&x.}l/qjm[ -()2 N>nm<:602zKe1! "_57{/}_oo":~;DpqE?¸OߒHTswHTKTzwNX/-JРZ[;d`eKk<dZ{22bjhYA_H5T)4&qg>4_5@ .:/_Bԭ<5QQKQ`(奐Og41JsrtUn6a4v!HLD9߹(okOrGP8ʳALE - ikRޗQU= AQGG :EqXF\餳Rd#=D)A;a3g߸5jpz`]:V3ً}שN|!'@k&)Zlkoyhg%3c$sI©2'Qq@a)HƯjPCTaa*0đBdg7P ZVdcA'o);ȮY{iC,Fܔ<.>KSFRV|Zze "koY5$sZ{#yԫS<-mizwON2䤶%SScF/ |LY>'ԣpnbzܫ޺Nՙ*֭MvG(O* +N\Db{]{ (O<5u@Vpmӫs[F$ksFv$+nK 'Jp؎u^hC3lN&R0b;Vラ%`|C?v́{Zc̸ lD ުܽ{޻OX!0 bV3'` |=dۿ#F:+UNŦI]#{C?H+ˏN~d3};{r4""e_ymii\0j|UD TGgD1hK;9 o&?o%m|aF^rVR(>$453I\vݘ*dw6{O:Mww'+:vˢ[SJQ,vELڃV2enCv Խ;JYt"F>ZJvgr}nnؒ\zMw|\AyyiU q>e +lzUD {Z6Ve}e"K3:y8\V̌6WT$>.NSJ5D mj75y3 Ug} р׬\E'#-R\ǓmJM iSXDLɁ$Z{¾Y #mQw:p>pױ"'6G45pĬ4/'7GI5yW|-)!RJ7jt ~'TwJI<nh .s/>U_}RJޗni6y]aWHkAUޘThHL~ޜ $8+~_؅d~a(Df" [-c7q8p#79bR/`4L?Ch%&cp}@:q%okrB S &SS8DV88*GJ\"z~I%`D]ٟʂ: uZ-\Zw?=O?  |49A|i9r]0Ϩc]rolLfߗƆ 8-D { Npv/_5/ԏB~Zc^2Xx#{@Dªژr,i[WukvvJB@|;Ajh7i@Y[v8n9A,'8b3{ sҟG;%)K(v<8`5MIǏ9J"7n9`&$) 滺 d}D wsA>$8W+Vaÿ)`8;NY1:)[s!әp@?F&_z+?dps[(@Kf' :(f&lna(w5e΃*`Y"!+9ȕ|"VnWŮZ@e dj$3 ʼnZIcO㏎k{UNG]Um,LǐXHCX?GCd6P>\ ls24(NIkVoD 5M{ ł: #;I.duTS4f|n6hj5Y\Mk/O=5$ gCF4.iu=$퉄Jݼ~KػmC  F d֛ӽsj"YVYeE'/̉ö*;2)S^r%8 Jy|LQx/A^ D# %&ɕb Z+3Z#nNՍfe?- !459h;;_9y䱩͟2h^G/= /}OI:DGX֌9E=:/_m(4٪>iEFμŦ<(PN!L]*  ųdoN%/ DPbpxxU-Ñ٬j 4T;K{U;v[9{p5=:V@? #ERﳶ$mN}ǸVߗ )*֡Jke׍IyuMQpOD4Lk֛dΑTH֜i;ڋr[Jj^MG%@▱)2%t]ڢJbH/F)hrHqhzīUD5C恡YyrI~gq!+u*tHpv̚ԪRN[4@9_;v 4Ȍ`HJd2X*up0k &cԍZۨAw3k Tb`u6Bm ϓŽqv6xgUv4iNqu\A8v!~ O^3pe@TJ(ϓOIukE"!ٻwN\NNMkSY.F aPY`f甌iڶSBfRj%Q|pt+R-d$vfuZjEjvqU0ES 紕`{ 'I GB+#skx]v?b͜d6@>+.D ܾ gb6Bg."0+ [:b>V)+aޑTzEϝ:2Z6Uqt^&5خI!9u^pB↴E#o k-L/j¢8 S6i BI6 e}{vY~"z` ZTJ USW,R+8t6S |2yՌ=A:XǧFq}yڗe2enMNa.ʁC$~K2lZ \Ƶ0^la?7%@2zJK/fVAɼ窍z#@SuQx*&MF΀rE8Ku:늪Tлn6ZLK, 'i[ 9cRS6:Uk5MfpB0K2v<>wvgJX_T1SR|?Ңqk3O6*5f&y~elhH(3۽>eJ:;aP^kPc܃{i\]۰ 4i8pgg/< emq٥k6%.ۏ^jAlij~&>_QwWΜ|yWqAp-7K0i lh.Z,1ILlv" ҧT>#hG^kD xv8. wb~ *};4Bؿ QU-rVEȠFDfWzI(q>8B&ȭaԶX޸qEN|:tDo:z)IA1SH6>뎞!á(hzXɹ OBFʁK3*կXSqh22VԺYSS3 Gw8V1NC$#\uч$ox;iWcrEYʮ=fȍ9U'k5"AU5 d`wޒa8旿\8wNԗazu_}T'#W'ӍI 0YlUt欎l_qG",.۠bTDk!ĽIɤp/K\T}KԲ~A6&75XP1=%abQ3DP~W)04H~TՍ8ժF!nu\MYx7s섻qEݺ-22')9hxyt09%@daS0k8;7dnά{D ^g/I}>D딍$Pt]53V9i-T,˜z! $ˍ9{uJGg=IdN.-U`SR̥dsmAŐ7;"=Q7uѩ*xX/$ZCF+9UZ5@shBvK槒:,zʜYUVYE&<odVp{X|A09ѫam& ~QsYhc/_FW6T9vaٵ{[Zú)MF& <0:ah~PitC>MjeN 萑-{_;e|t";vun)/BSN$(O./zC@;P*:@W^z4kڋm5,_VE>Hj  Lca|sEq l:/oP%ffpH:T2zwFE" E]&4pUI3<Lq֥]u+GC[ShUUb\ÍtHM<.v=Z+_֔![نH imȐ6feiì"LuP2v_a\Spj~K%w$:4ϲ;E9@Ep^kE[sg٦k_}OH2t+y)*6d%(sSp02?wW9B_WwO VolNu&0L1k<b}/ө0uhR6fLnp-?ύ!._+;pꈸi\Ɯ;zDDHv2uJ֭0pL%m Ƨ(ǙR.]bkA4^\Vm ȑaPŘaRirM590̍_ߏڇ#o<}MG4M1׍ts}yf\]VV=ٻs rOŽ;cessMo]SOc}2>1A,,r.5&DU"ˢ'eazB_>+k+K:uʭT2rd b/i(By>Nóu,%ǹv+zl5DӮ:G'`WPiwYܹG~Dm,#*5Lr2x\:_*xv#c"qڪ'4 VcrjX쉉ʈ:08,ӳ2"/$'߸yEzs'yP[kKiA.=M혚 e|0ŨxR?81٨| QBM~tw V*%2=0fkaK2z{BΞ=:N)9JK8)=)j_^N}Խܹ[Z:R'skO;۩]T#]Ha1jivC)̆U{TIC;ըI0%Sk̑m8hb GN~#ۦcʵޏ:c{Qw A(NKS+'on:D!/;)7þk \)IU6K*lM5vPC_zzz:%$C)`9mO yE9"k[w#hE6 K9RɗrZZA1uculVus=ޛ7%EM.|wx#m]>{emd4~ϽCC dVMPݻ9OFh8 oN|Fe ̵Af/sk?CsӱlH,reû/? ogÚGRϒ+kZW?bN^>wE.ccߺ{Gr[p N,>o#q=8J)Mnx b̼pk Ԏ;%LVT$ĭ!y4U7Od|:)5:ʡA#,R{CO~-]I,tkhp@؎hL_8*7w‚] @{Ve-5kf*>W0v\/ ûr%YZY#ϼi1P#4 _Ԝ {pu3Z[U)ZTd9m]A;ՍiavѡJe kFK'Y?/kD ?8|2Vhj MO4k !R7TuVL^>yԉuឹ`TRm $gnh oL<W[@ƭ t? ]CbF57/adbtUƐjhV6 R~42"B-uT8􉤳Kz&Ynj|N-$0IrzI &@˲v)V#;Vu/ }$S>JR>#Evt8ROh7:yˀfi"Zw mnXl%?Q#p;BPWŤϝ?/ ^y/JlSNE'M ^vܟޮ^YMr{i"84tA- fy ,l^p* 3Fk߃3F=L}-avɮdoX;"282(>j `ûeaqRf&`<݁ĜkўE\+'s|'oN={%ݟTN%{D=K$kpֈ1UPyݷ$^2ˎNDQp0[Jsk*si߆?}#?%i@&8Tfn%)h(kHZ%Iꭚs)DͬuX,v- VB19n/\J6+Z行S9=}6GM~!M暑FQ-pMYæANXJ5N-MطHN/-2>>*lZ٫]{ kkUi8 (D Ҽ~M7'dGH&Zңfj b?SNBD7XkF KJCgeIDt[ؤvvMJj5Q)jg27E]wKW6syY5S8.lnDpLܻ-0.A > YFoޗb$c)=5qGG%!>oHv"/-Vz`KL*v|Oܺ"sIРQ[=JM|(6Ҳb(|^f8J? DBNtvK\kaMEgY.iu,mD$AY+)^{Ti8)/sRy`p6aV^)u)*X>j]D06EET`Y T$W]ΐxNKK-~`\NAN ҋK%A9: !"`'k&+-:P9"E[U&J &6]jZ[b#MxAT* '}t&54Htbt˾6 >(OEygdoLtK^t+_{I/n,lj hm̦N=1:>J$όҐAv(ֆjcUJ6MoZM.+ބx]yLO sR&ɄmJj*+zĪ9da]2٥onvdСodȐvo3R@TgN $d%ۖ`닷S P uӶ5Vo!4g D#J[vX[05q9w"HW 6J]ikj>hw%!YC[=`dJ+)K*skkrQS`ER,9y H:nDH]wH$ C.)D`ezfNNvJt╭Ǻ_}K_R]0H_z%".a@!m {@xϵLݯZk[utهsr-(Y9k* b9aXI#|XT: sDv-$ u9CU+5>19)vyG2,Rrbrx? 3@Ť 2눵䡖8 p(hՖJȒMM3rHiޭbFoLuLή n]\+nRFS[!Fե.}_sV|>vjQ}wnҙgJiٔR:;j@w,*謒ymg}=Cw߭Ic^plU{gYNͩMr8qݚ_BllQs^y>cI7@XҮ'?hL1 [[KϥWoDdxpXV85,OY@Z$ d6Ӱ30R.,ҀkYS si>KI 9gWHiK9oF"]Cws)]c1ZY GB Qk\p [wnhS2T04tƬ YSz6 \vZSNb4]8reN+SMjk çDوmsԹҖop,z1+ߒt!S E4" 24L[+NOkX.|0hs1|V7P %rV2Eiu`XyW򮔋UZbbn*xn ACMV1V/frw<"-1~,LTNS$蠔&bXSw[򙻲gψ:k7|Aqt?q=Z6X y>&"@'}&vY o<7&BJ? |6]j$"+5'jJ*UyRge߾#@|WQ/(zQ0VQ ^talYi~0Pk7QL_tIe?<Go\"*eD{p7o"{9BR;?ݻlzm=%W a`d֝ZL+/ܜ=:+~ܾ{Cw.m6]{KTؤ|rgaWaHojF~ p~NEm5ǍLvYJ%+_߻*K+23;)}Ҭ#*eŏl q6EweHKr5T i)rRi>g% }L3m$*,{;%1 ׄ9l0&YbS&4)\Y,K 0+Wv`K2͝J+#?7+EZ46*I-nF(s^5dռPIU) +bق*'eJY8]m<3LJůNY?CӃ @F&\SƂYp#mPt5"Jwěڡ\Xr=$3Sa<"]mKC6S*20xD !Q7pF$o2X29ڌ}K[ǻ[/m<ߙcoUc(/Qfk$(k+8'k* d{!<OU) )deѶ$_*e?[۠xVF~cp!5k`|<]ܹsRԚ5h$|A{\pdcN΄CJjQ_g=LAWDf0 }=vtts+]! V\g P+gejn^9Q!$'vfkUrXgISC"6IK\Pנ3 i.P ɕkTE. JD۲j#U3Uqʤ;Y< ,ӏJe2;HZ%z)ӷh2wq$wdijLFlgС9]򕴟\)g.жn4wSx8zUik !I_π/K5"g`LertcއuUmUJ;P[38# "4R>Gm` ȾGPP뒕cVR灤Yp:}u%hFH_Sˮ#;ut VD_àh2Y''>4b iqr5.d6`P֊/)aZIPűæAwn0~ D:dQckKL*l7ꮉiXrKŒFumtg״h((fmk(]9DFOL] 9qL;ڤ$IqZ>k:C'UR8c lR&Gj./k[d +j7KYO^ѩ/A5#⭫x4`,RAdpfp v-0akjҴ yX8=:AʵXaӘpEdfL2J=qr) ~Op = E$Qj-p{6-ϙ?XfmhGņkϊ &nl71}oQݖPp4tP~.6&n甩_^|e;1i)c{d7D&̎GLO8)?Rjiӟğخ,{I=<Md(w}}ػ]jY像>MytҪBIlx0s|a F6hQ@װ jO9yT.? |/I8dj80,_x|_ÇGEInMA9uZˬQP% ׹gw^:u#_fTQ*lY,DɢsEebeR{oTfEΚI'R(5j1=˰cqm$C;HO[(Yv: @3t#rDNeG0;~VW[S`ՖM- 7I|q ,~"+i7S!2NI#R![Xr9 :dg߼$+$cD1 kEzI"E)b&jR Ĥ8BR-WMRx;z;{D\&1mٻgܺ5evq/j Ukm xxl)&-㵝8p-E[ys ?gU˗oʉ%-#H#"*O!|ٳg'͛T{oP[ <#YYZI%}{w2VISj֖dk8;!p8"j6&EPErH7Bn x<-0N0-<=eP+LF /U}9erT8B[ + '!?#hf ƐS.!,lnʦE<˒(j*@;/IIO!FZR˪qӵuuPXBM9bиQ7%:FlXch.5KRS:L)fե d٩QjE&pfM9RH0lsb XMƬ悓jr^_f!MDmm ̈ĩ ZW-۪դ ny%`pfCҐ{*(okJ]I$pgzqZcC6*J #C1\K7ЫKNDN?=+HX7:L5ly9H)|N)H^Ƒ;c㲑Drmv^9q>7ո]GAyX?s>С^z~u#ƚ<ls{TS=ĞqǗdW&0)?Ơ;yZ! ]r>@0MP$,h7 FMW%Lv] pU2 &Ś {de?o}[,~t\.^>-h߈XXKd 43LnVWY`jܷcҍ׈݁k L49涹WŅy铧hi1g/>"lHs7hzdnvƱjtҪ}h2o[bX-~<!  [;V)8O@D`f069to'h~ %8!;z>]pId_*ٲņ"-, s6r=xDKs)REO)>Ņ"S #G*u*>hyGGq׈γ,ϣ4)ؙIYU Q{~>C0AOa%BK0$ս]8pqX*|2 ߖ9j}wۣmq&Hf` Й3gť%J7^2 ޕFY1{ |%fϲIҏ~CzOs !."!Z>v CeV|ހQ;-<נf]f"8 C]t0r&B "ҕqi%}K| =ga{>.ФBl .`R٬̙$8CiccMжz?}zy=E)sBv 9t5vEtceuE{-sp,6~gG=eҒH?^v6sgc*66! /˼Pff>2\>Pf=l4sA#A덭D]&#߷ۣ!#7՚xƑ7z<ӹ]E6R̮)0 2&0EB4ɑɩ3t%zN?OptH0L;[bA'']>"YS/`זr|=1'R)ixapĝݦF5J 8 (9EIxCQT(LhPRtCC<7Gk]eѸ8*3km8h{}hYc`f7(a wk4|g' 8yx-,/`NIqBp㠢mXO\ êrLrgh!PP!ݝ$vو<$HŊ "(=eHM!r15433;:+lb} ϟ9NAGD(I ;ThjjZW76yR |H0gvGV#MA8!2!%MԒZ4::B\%X_]κ^l*SL7?ya["ioD]q#(@lumrAk IcLV~dn M"5 V f(@&3pS#+E9u2i6|y>O GI*9B4j+҄!s=1:H nNw![Snj*ZY3HPJln~ӿh|\PP2t&[Yz(~ܸ^xU6yHi9g QO| =y<K#M< )g z-BT4ĘbEi&vY$i{sɌHa%OL672f̭Α/P0~mnQ*- <hOnl&&no/(PZQv,@U>T`4e-r#j5~A5H =WHF)Pq@~ )BPs*9vrTَoHoҍWhcM1̙ҸMqV&9xm"C*P:D!a\{G>΄ý} P# h%fZZ'51%[0!`d .\숊|EONd5^sK/o//o>bw"zmmf\&xo;S ) c?9]v8,S9t ,g N1vfn Pb5Z΍kѩ5Ip!;Rc =819=у7Zr`/EN%#*ZKG8,"6b>_ =)6]dm:bB`= 1P}!dw`qerv{%`*qdު6dmDy_H nhlG]yxx!;r0rG>G=(sТK2-UJu{.KPo{|!1G899%fjn&*BgyiF9 ,gm`]gj'5hR-;64M"cJn@C˕$itd@IH\/crg;M^WL/BD.6wܧk?oۯh JbQG!v:id/h>t#!@$yS4q:y oF6m*AZ lLϝ8#S7ߦ)a[0{]E)NS<9%l#Y![`l#JIkԪ~.?(>獰D! 0q !p;') rU4T'&= ;Dтv gg1{xN"rD\[jՖpT.,BM(6HƠQk NE$KneδBڴLE/;zL{I_+gG0],V,)M6U*(Yg:Ǟ&(SAP)6A?uTٲZQ. #~?'nda t8ʚ<֚-)˧|DE^Ә@i vIzѩsTɓEseynnE8f|c.k{)}j`)jaZ{n߷8raB?"GMMogel4%/C@$ 83љ_Jѻ!;ewH 鳔4Q8ፕdiH54?@?E djwJ~f`?jvưBؠwo{igoeӃsз");"~{܋ty ]?oB]lrG&F'ElsuFFNѽRp ~g p8) c(G 9x>U8S+d}p3kssm0^x'-?(z]E( pK[fq 3v™CEvvU(L"v6hW,>jjkBԀUSS ]d-L_Hz"'2ΙPk>툱p^[Դ۝$z1".1*HjB,(I`jdUdR d?cUVaAP 1,6 '2@"շiNGMA{38_@$ ?n6(qVRSG$f!Gg#4dPA L5YQGc;,fPz `uqz_Fi\H4I&:m [0i]ERg4mĤ87vY0 '`J(˔Ie)D.onH$$"9Rdu$ԳݛW}(ۧ1+,@-^EHA 蟆zɣ42 N3%6<c~"<2ͭ[0C<"X @@gG޼s9a~6G!Pv[M #{3|ms4xUHhS[_ %1.`0/nS-0 RpRGm)IVV80ٳ\{GVJL]}mj } ."mnh^yN{ -I0؈X YQZ 41 ET:ʎT*),pT0r^4qGP#ZE-xyPĆ6hzU1V;pPFu5 +CI2-hLغ!@ؙtΎBYN1ZvHBWdMF%dd(585M33f !FCv_Z.@̚btΨvE()#רy Ai _=~L ]҇\>7(@)[r%?*{M_:ɕT˖yYc(ѕvYUT[9,ܖwg0wShLL,+ vnb.Ï@(wfg=t9`cduevPB`f/gZk>GKz ba Wr,lWE 虇ҙ5$@`p!M]p8=z@逯{"\;N6j(i&v@ސDyu ܿl %p%_tYh;6YEugSd@'bϯu{c^c'F}EiT2)NvQQ;S8nhRnEh3y!*Q[[\;u7,P40* 6-V-Kuu!?ژVlGZpsQє2))8"cK]RZmɡ>؜F[ʭj%3nbwN8# eثEf.ED2q^~ߨ%i֫+=^Zk7)TmBU=рv{9(sDV(Y8Aeި-Le[p!S?@#t:K2' 12NU2 ᄠ{@Wg]˺oZ}GDv)trgK2Q(߻r 4@E&GgM8;5 ͼ mFk4`.^<- :"j S戧Ƒ>q>!޿#iY !/./r5idd>\t}Dolfub =9G(@Quhʥ`]&0$ EҰ4*k)J #-|pͭm)S 7vPB&3Slp$K(uyiUI`a,<^v)%JbQREfلsc-R6GizxߣM~M ㉉(J'h y0^5MR&GyH[/;A;cXX{@C妦ץ1h"[WGAfذH$4ب4E`Hqp-zP,Ϸ':lls0Q'0; 4b1lI&ͰHw65j(t .+ 0&[c' )˚DҸoµm0#tip(!3{UhQh+ 85Я N2Pw`:Cj=-09:a?YŇeԮ'/ZL| T6+XO'37n蔍b+BK/|",WU~NPGٌIOj: n8Ae$Ŷ'  K_:K_WM6yr*9؈Wp[k1:2H~db["ل.S>y)`HÿJ vT u DBh ǏQ<rt/h#TC=!l3/U2?54DU6$<2(|AaXPIf`=9C|J邰3]!*g yY5vў'}c'NPLj&Je3:Y:[ 6h7#S~T,$pt[ YJs0] U-E{@&yLaC@kAРsقdBGb!vAu^!8pfRVM 32Bl \ %8l2Z|N5KsY-%g f-8'fuB1q|Q L*; 'NA6hhb2U!Սهw'j,zn Az;EC6-Cs.%c_tp|k*RNr$;NM櫞]qk}~hɜm:"@,c8|=2!{jԚ UaE)a /Noz.?KΟHvg{_F?~9oQl zh; Dž=-IeskC^ kb\)ݼ!C@+!$g"l Fc48 d2C)8VA\2W 83DҁiL EWO , 3j,Vd .D/Y&JyM&[!1^ z 4KI6f'23.qti is!G3Q<$#R54u4 :*x*@?R;;So7Fwn^"o68/fSZJ 74!KC0u$w) hZ6g(1VIiN+0b|a/Gj'D&[*핉Z3b!/Cuow>(<6<|;F|#_/w |RW+T]hYlb4;'lXu#6!]+J?C\ Ѕlrٕ3g..gPr}6 js$2BXVI8@fS̙ċJàjHIrMizK}K.}<~A^vnг q߆sJ&ӐY7(%[HTLw5 h2G1[JwB׳n!'.%rmf2|zO? &]\ӡݻH=.߸qsf~nI@؀8Pm E|Krձʂ[]W++%v5?;n!xg k.$$tK;;T%=xl{y'DhahtX:H sZ࠯}d7^HH\قVS4"*T_n߾K`t޺-0@<,apnt+ Lx/[@F$A , (C+ JRTQ/H.!9e9=p&jĆ[*x9(@9:1BH82ll ׾*HUboGOa-l'ByZy]yHfӂ'lӢ'Kw+tiTg=nED))HoMzzqW$ nv!`#Sk OC2H :2x}tͼMmU8!H7)hb2khIBn'^ϟJEj?~/a{J^=Zxh4{'|5bF=͞h D$JiRfnX `l3KB=k0?k1.lG6MZCȭ+$d^w 5ؐ*5M:Q/]8QE,B5AF09Uz@)MPzsܻzd賈gƉ9_Ji)&ɪ;Is !0!rY&*CE@4 Sa/ X?>5tyѓrEux= XV~4=Ş" I} ,,7&;vqQ+.WR ^kOkc\7#3D,904$|ZY.^\7H5&(X}MkQ8*Q<ubԽ5ϣ-9xJTCoPM/'Mo~5$`P]FȦ^g|_x ##>|8nDd,<|!R܎A WrD+6DK CxvC;"DA `LC 7bRr?ZA1A?^r^ħ!Ee(ڲ|w_@j*ڦ9Z\O^>[H.LV0k78l8fCȔ{.1-Vzp|_jxU4yb&PZU'Cr5K416BRF䈼GyeJg82vQo߀Ҳt9 ̳>ܤ}݄h?qlYL _|-6 A# VoKflt9#'*yL'mlHsx\eFutMQ̬ H8&F2IIyf,étog5k!t¾ެh ~j.;nl%aHvvF!jVbD6aXI1'&8j4tծ>.fFIP }/1)X)A^mou eԙ@{SL3ek$;=X:? P]9z!{j!Y)tيk~ς#=hm9O, tpsGGF9: h1]r7JJhܻMßP42,ʛ5-f6Z*,MMN)8^[9@YgCk#<ܿKs$R ]Xl`G$@uQ!qPO?ex>7*erTʗS/ԠV 4on4) `w9xT̊e DVZKA\^r^ip2oE8%vznȈuYʋC~~ndg0|Fa"f"z#{+; R`B촱-и rmW7%hY(1("%NAUOܜ}h@DAaD -#s"<" ྕ9ًBڨLzmA+3e:>}͍8 V; :9m.D3fW[eeT)>f &Zz{6:F+F Q!P !Zg?xUs{30O #vL_0x6Bdy: p*qclDX'?ㅱ鵙vd}ZP-pTn:g͡$uCDJCuߠO"|~Ѓh&Q֣Yu:y#x?\BT6я*R]DKAFW_U1ДE(frI:tlrZp 871j&YZrx770M^̵QiXN1m}Px 3SFﺙvei>갱bC :/>-qhpW{b+hj4yo_Н{4z8UQzzd@w#k%`cs]@Zm-(y6cO,"-} 6`HubYnLqlCeξUz GP  `8Ntu`6S]B8FK*h< (EɵaJZx۬֙s/Xi9|B[!!@]HpׄW4ܻ˙]~Faad2h{V+;pv,FZSRNB qahO/2G1Z\X9{>2\ XZAޞxwuMv[[\ ʧDs8K[__3_"-Ƥ%ƿ̋~Wj#óe,!&4EI@9H *)J*V= {j =𢀮+P"p,$shZDQ^ ˢs1pSz0N}Xkp> ~m!tÖ«vO8 ݮˢ%E"!W~Ǝgee4l3`JOf#$ʴp867/tʲ#H @+HjY$UVh.6e} Ptj]ecƿT+g24 6T/+Օrsv9$M+0;;KR.P*t:E1/t8 O9nAv;5~ڡt zMez]6Rn\D@#z6\hO`J;n8y`kOhZ ٤Lt av))|=wJ DIMaeSET軜lPc@<5?W^3J*z]qm 3Ѩ7UnXj 烿$#FI0^^px]?8*=:5˪ơd4}u,7vF™GV7(2'·g|!ߙ~Nj5\@ 8{p PMűAɏߣJ'h $p AI[+X0GgsȤ}M$GSnohpnldq_]:9Q?'%7`?Y8w "h!urzRcǏXGQݤEz|ݻ{~66# +fS;ă1*"P>'s "y Z-#u@;"{%!il_FlDU83$PӅ%%5(&zU ѩS8ҫhkuqָ@^{m*d16gVԥ٫3\SU|̣BLG~Ss*|h>WelA뵲LiVd,Ly0^ JFd MH(B) a嵄p(Eq&+%dLW쵊3 SJIk=!0)i3!ͦ*Cq6 B(@!k A>c|?!ǽ¿Q:ӀS@(w`Q2p8LCCCt?Sll|8zjRn3PTFial(;lz01]Ɣ`wƁk69uCWWf> ~#+sޠ 4 lFCSBGiqzS@dTϪA0"Vv9J"MVmtkR , r$eKm6䳴MI+9 /rbhN=XPՉG(m.ȃ;K47Nk Ptlvj r$Ύ*EB$J X̉";ǨvQRQY-(/@JYvrMY&)?09< Xq[džS&=(uiJS)W*3m~l⌧ݮR:IFsqԊ4N;E{{2LSn@PqN5Gjjhvdzhx;@lS{AYыP(y~fgmLS4ӄ'PZ0ߑ)J8Y{ta8JcaMP=[k)rh$ޞQ_mZZ^n@HWWR eSt_U|'_:g<[m6 h Žulk: PC$;?;2)4S͖upd‡ʷ&{i4_ ,B]/LYQ 7dIC, w'h*xOGhw;):L GIM!ε!"-%ìc6*sءoP`ehmn/H̔w2;[`DF lKFnp`]11W_}nܼϋ{B(zI"TOV"e8?luCmf=2Bd;'/> !!A#BV6/$6jzY6ll?@sO5Dp:>P" RNh..SB5sksd&G qFc:?1Jy6Ё@@"~qqsٜ8*PGTAl8,? +W!6;9$J2D.JvENJ2I6?8LdyNYWU~؇vatQFȻ̼fs4o{?zv Q(%vdP9#qԮP0䡐/(cX B/ ,wWօSb9ad  _1zU"i#3́tZ6# W#s0"C\vD[]^Z>gW~ \x2qE^%@ʭMazkkC(Cjz/ʂP8$8g$&ƶP x%c] ]3?/C5 @}FP坝GIꑪa(ڂS'itdPLm$9 h8EXFb;0"yyP~VIןΞ=-}PQAC*19_`(8sMALA_OZ_ېHd*bAf2% RL8H>GpPO}viIuP8H#P1E|5iMMOЗ~^uzQgL'a%U0@>I=az!.ŋhc}hyc][W>' "z$Qԩ'KP7_|/~N{K+|Igմ)ye8[ PÄf9B{tl6-lm8YdM+?0µ($H.h$NIv h@9zX(H+p6Tw6KvE EZ(f0Y$lsϛ-|~-q?z^yd@T9ql^b))-Qbu]8`C(R5pg Ke)%pttmno'Thv^̗nsJ։5$Ґ+ϾGdM#3(=~E,p{rDRD>e`t:! |"clvjA$HA 8?d-JN@w3oMcHP5ԖaK04mnlJǎg{!4]9DSf =gN߀lAa|El:f޹+p5ub?h(JX/&e h2*BТRfտtI+D)t*'krbL_zX:EQg@ 8GCq[oJ7n]}^"F H1Fmc xcl8бs45y Ttg,fʍTu<' |I;2Ba%?,0Y)?`a71G-s TT&dF߽'G/tP.ed*M o.dMy Ѭ6|5hO]WqmG.62 LWG}i*CJ!KucrF^9-:Sod 4c( Jqt] 1d~(K;27D٘ Մz4'Od))•/%iBp -2XΊn ~-cB#0N%l{{){4 OSg)4We2f ,dfwo3f!kPjUU)H2kw2dCmW;;084}|51 j8m/eY1EA撡L_ﶗ::ΡBG^wL$`vh2[8zr9Th O#gM,c}p j2{w^W>B}IxaiVv?~LD2Im(U,&j)/;hF{46|F#VnOĎ]Nd\;E^Df#&]zYa!bC~/ի%s|r x!O(ש,nGj)UJPPuU*TJ:nTR X85MN|5Q0ɜ"gCn\^yx_zHe{tΧ|d\>"TSm hO/Ge,h䎄(>>N j*d;* ;Hz60*wi7)C1nHb.Ɵ7 ?A64xA38$z VjR2ޒJK^/䃋zL8BnAl7Wsro?@R叏MNjv۔ͧĨ^YNȩ(i|7s|p>~O?;-J&.o|ʛ!=1[HOuF|0es}ivR3 >0^6)& џpT(I\MqYlanP|$Ch)4&I39p]BO,F15Mkho}V(Ο_|[ooEkeGս:y|~AH.o~.cZ޽}qχ"zqؠ\ 6~a7whw:.Em) 2.} "Iх_x֨+P׹R A})]CrU"bd KrO_|%G?IhhpIoOq8kbP_ ?ي|!+h;%(JPT+jzG5zDr3N _]@k"6<lll!*mY\]SMWYê ,L_J'hrw]}%jCLhdD +b'p9v n~J/8&uYTvoS x-ӤH|f^n^,$+YH LNlV{Y̓my/p ;'*%A ?G'"2y;mtLi_|>:\|/һ{q"uR |lMhsƀ 6LV waG&қ G^7U>ņ2~ ;cOnǿ-f+_;NAvpZ3J1Bk5=;M"};y=͆b|N_F[hJd홆X??GKw(Z~$}3̡K|U9;<GS4u4-ƧʁU!;tG_SϐKst~%ؙ  F \YoZ^}DfWGкUFgD7I3Z74PMC`萰E ].e>ۂVxez4? DLrJ /@EϿ/[&AEwpH9 <oݹ'vA%^&(hs$e7QSeQc Ql҆%-f'SZ@P>pGŌNϳ?~Bd?,~G?h#]f1s$4:{}` ^5Iejst?k_cMRMSi!)S!*'6}ﯿ}=z,}}Z7*.dznN8Jl}a㹇|&6r8][C|-pKN[xM 4ׅF8JfU(!a^c砵8%;@P`8S6`|DRK3IU4,`81z9 lB,teC̸̟G  a8[S ZR(f#כjH S+o[^7q C}ǏɬK!6u: ,U_kWSX uB-~OXyQ2KZ롽TJJ%hԗky^WNɲ܀lk:\莠>"RFx+Jn<>Gߢw$Gy:;<2"bۗ]z5:}8v᠎?oJssF愒b)=pHLe:ߣy*̳Kl'\wзlx\ &/y!KA.WT4}Z;;&8No\Do]x^8ñ~Pՠo:|᳅s o~}]^LpA)-g?]@87EPԶ Ӳ'H#*Dw#`J|G 褰zn+'FѬPF?io:_AM!AKY@OZU6T.s4SvKhau7IkB6 666So/]ZXܠ`,$hV Z lR+ZMu :-rS+P.daf7E6h8cЬRmG%V%t%廙-nvy]O&E>̥nrԷ0/ 7gB~~?=|xœf_tIn:=}('_V61P7i|YZG ܣ^IWZCQe5_Q6(8#xxۿMϽL ~.5s1RNۜm@Ϝz}J&,4hHt4 8j8df 08W-X6qe0"kG;MLL$  @ z}YWBA_X 2wQoۄ!0khGO?&n*ͪrת2kD᡾H&Ghz|{44DS!~@7^_Ad5{Z/J޸.S>|-&5cpT,e_ uwYQ& zbF`C=^*?&/;KNПҵWi#&&"T3wb\gΰ#la׌E޽;[pt~8?'Ut- pPV0qh:sTnԏ%|;B7cIz%?3EQk&5 쓘W0[Mw|kuEk :-yGhtP猢ըBU+RFCG8uǎzvz }d:0sPms;n'B?2~V a8q?;qgӥDQzJqεvTDBJ]n0(QoJN {gאivt(9N#1JatN󢵣SF<3E^+)N3! ?0RL3feB>N_줬&PorفiERUf[-ak9.+Een宭|!BҠC(޶MS/f'%Q wFp4~ArM 2E:g;HFlV)QM l=3s{]RNWPXcc6*Yɏ[86ώ.QD4VN=~cbW6cr,uJ(DޠK7)/2ss3Z*Ldya r7 mL&Ln7\2RҪe8Jr6ڰl%uŎ#jU1l<%g|YPj|Ϝ>V' LWd*j5Kۑ٠qbDSwE`3 N%q1lǶ U!8nX?9+?7ăV YaAG(X%W隘57^[fL^;f"#/GGqA)g2^ Ç(Oڵ R=q`,#(Ԛ`|(נU[`'4!}dvqᎠ,ERgPAX-Pz86|R{ 촟Y4ʚbUE@^-#T*Cjmmp(e2&ᐐ-,/5>lZAJ#Gvcg˵΅i3  *FgkU"s]H)R {t? w4w>|H /ԙG0P"y?A8_,{J"E+C0Ƈܟ#fC">Œ^oUSܸqC+tt@²֮hL,`v$|:c YPwz H n=)yeEELkpOx~mu>-fl7`oQ 'JqNMV![(I^@z:Pkh@ruYUQMzu5TE7Q,07rs Lt&8(̥)"!yG -]T<O4NZ[WLݽ CÎR~|\`,Wﯗϔu?Z}c~lF3~HƓJAUMN:K%3;s 3^){(Aw7o/V'¼*;1 fkIӓ-q$U1F^q ӭ/'#~ǧ$/y"&u"B 3FB)^4;%8MFl,`"*#O 8}dnč17?ܚOA\Oo8.)q~oiy9zBKp!'a#8P&*pf! ѳUE=+;K0󼭑.}Y6O0֩_M{M܎08jZԵ䈅Ʌ9\[  *zFk>xz#=ᶳ.W4B"sq/4dlvk~TU S6B.)eSrU9~+ӡܛ(YyA3"3Ϟ@PM/HNOH o=$S؋bǑEw7">DX_iU ?Uno}.OF"_Vx{GUەjˏ#Gu ՛ӯ_=.g+@Fg_;ޛo$XhuBoJӵAmb([t=IH.ɒaTIe6_q ~N /9:=k,0X]DCwgPFgiNU-~1m~\dR{SAaSMF_Ԣ1h~2(hIz 5c~-Es68h'1LjE]JhyBjfB ptF?-f$rYzi}(*X]ߧ'Ц7so'O< ;%|x2%"6yvct *S(Ag}б#hi @OQ{xh#D(9ur/vgMtdLnb[3W!!9D gn|jd!ToN47TOMH5p yqmS XXhpz(|E&0KFGTMɇϛ)$Jyܔ!v1H/*w}W򿧟|} 8yIɹr[DD$J/(Zk8zt˄,XQ#1%hM*JUGsho3Jo~ xxp*QB֧QX)69#L#1 n `I:R䨵"jA)4+)D\oQ[M&l0*iBzKƥs˫I1 M%v|g~64{ }TL6b!'ti%Ҝ2uH*z^s{w.PE5rN ge鵪)ƦdE䡩xKǃ&$:Oݬ~hrgpd2 $KeS`W"+#0%^F~ye.xRML®x.KKwiiac7q3)Y qsKxi6Du PAjOFH]4S2T:NFr7o^+0;~S̶؉bc-*EaA(GKB_*wSHbi\抲^gMJ{|[˳d C"NR.KPPԑ4 ~&ӡ2FHjwJJgGg3vZ˺'N -w*Ϛ)qANQjC*[hMǥ/$<~ޏ+,+}UCu(A ; Vi{iT//Lczjc̅~ܜgOfS J *2F:t9'ndFE $nS5?7`Ћ !ɵFCÇ?0L된Aw ӳ"D.(6# 8u;*ȝmm襀iuI7)RsZ*b~z\8 e,H_ f@'*h]㯩JkZY_UݯWE>bw%dή~eP"j hi4 +2ubsJG]#US1Bn<9 Zv6VI3>O8.m0kW1*_JÔ6"0ΦQ EpKD66,Lbzr SwEeܮՏ>)Hin!R-fBG &W+fmǸec{:r-*䳻0ic 2RkFnQ5 2O8.Ea`T d<&&T٢h_{{g<>7I;Gn\~0ut}٣8NDͮ&rw&ɪUCۄc\] [__$虞,:ܢ勒 AORkxX!u0_#VIRU V#OeMH# _LG UpfN.EmhikE0AkW,wuc-ܽqF!#)Ĺw/ab`y<t.A tlw*nm1Ŷ [l]F1/8֣Q:w4(h!ġ`$]E%&}aru3膟{ˁ"sp/!sJuVQ饨Յ$K~=@YOhfaJu&=no5&qպNj@}e$8Q,הydBU&)tC PohΛ[((NJ=OFW \L*Vq?QfKj2gcwNC3d˾~:n߼LF`ȦȀAvf=ArBR3Q4\Rh1kyC7J1ywd^X̉Z(oo՗_vÅy1l\yXX(#];,%w7Y;v>*V擨`?O<:Wj2+Ѳ1EzBRIN_1b̸v"d bٗ `ޫ*~"<4plat߬=z[踵3M5M I2Snh @u|8(1纚HC 6@NqjFNPpjEj'NpćX'!#dz rxxS/3/ꭈmatz KHEim!Di…1|):z+Y(z$^v;VRix$ci=ڡ ls;SOJ <*"3]OmmH#/c!|.Ty@1M3fHIUwsAOkj)CUz 4S֑ԥOuak.x4JO78q(V 08n3ŕ-ttC"QNiO '@cOTX9LAA!In!SiJ+ܠP߂}9w?\.LtIB;+t vO! dv ܊DȨ@¢DP2P*AaV "{ZA @[$ IV+Zۻ01,-.)vFe.HNg^aG!";"Q#p柟ra'GE +BpOl{?r\.{ ]2sVzC؂ bB+"hVu*]jMc^A+Fs:k+k ȑ*s1 8r`p/5].0H=}13n vj8{VWw@cIf(D!Bts8^׮]({HI?_Ǿ}t/AZ'm,U-`2"jέ2=WUbHYәvZqњ+9A8N)B1CbޒzfzF:WVK"^0&,|sl3!'\\BfcJ^;:m8v H@%b>Efqd,a,7hOйP0;k"%q^x^& ^[!'W 7"ʊ?:#J/[, <>qs4?xBoWUYk/Lk.-e-|Wji,Wr܀VU֙vBU1Z Jo:l3H4 iT)$eiitRO/P==hokSp>v#@BKQ;qBN\v(Q- }aRKLl.+_xʢL/̭r*NG.WL'-ZکWTnlb7TKuѺ%ؑZn'`w8rl?"^zFۄ JʅB( >!FW{p 9%hno9[DWߐq. r^˺hBϗ9E!&&'7q}l nߝ@ V %$O>%\s9OV&kj0:;>>=LEљ#Sݝ;hf=\L E,18z0Fi E9vBXHWBt} k@M?Ɗ2{-*ӓw1>y4);l8~ ulVҡVX|7VQ19*i"&H g%Y :璸'l{Y%'*ve1OMsN$+qeis,Q}4{0uYy2S#&luì虳:FFEWV'0ѫv"f&-!C6M3BkGg^Unc[n>ŋdBm<_&=N?9id8(B @dU\j"fKԒ|NLjkuaBF@*S=w9:8N`%,"ܥ<2]9PU"{2A*<6mOGжV;ܴ';mѳv>ؖ j'%䠓bvf[Vxq9lnq,,7k-h ˫$,yqP@{QMIk8b;( 5;rK9?o:I}r45XL7[],,.Yg ,Lח3x՗7Bi"#tvHtJDn2b+d`rqij (9<jj .br̓?F)ت 1c*9/ i |1)cLc'U>eЙ5y9C!%"5J;:[ߢhɵXW?P@FFk@>+cx;إYMd!S!3 2l &.6?_[=,/Γ%x8B- [Rh Qs" Rq]-dl"%,t7V<;7DP@xѭ >mGo}`g:o?y6g; 0QO`J$eEF0-*.S?G4VVT{LP(mYf4bkԠSBSʺzEr&&C$c4ۥqNy@3|٭ؽ01L2HU25ͩfRP чAglhMUzMl`鸴Dj/f293JΐWUUBq>Irҽ]qaAA22?!6BB=]9:7!<4 49 EwSV'aF^]/z&ENk+/JS#۷a0Y*ENU&$A~Jw0.+EBGlk¾* ߸yv ƜU|=: *0!IfPZe~M2ц29;!`DZxkpōel&T(װS.ԄDV0R$m|μ؁1Ak^&;QD@_oR4GAP)^Ӈ:NӦu/>B< +fE&{&--b~ܸq 6ZD^҄j^Mg_&ǵu_¹KWs µEkwq2] oqit#+چy7o~'hc&{DRt %P8 ,-%:MegyS)6JAR-R{Jb#F 'Yȃsr*72u y,&H]V"r()gޙ_~g)!]'#=x^| 5|t)O!  >/^yC:q5PKv颹 )GklnF圵\v_s{2;NAw @[(c:_ը$7p":t7S'6E([62&%w!Y!-.VGl#u++wXp)6Kmad U͍!Hu V~ar)8v,Z&'0}K0{;՚YWڮ'a&D8t~ "­-؉mo69,O"mJa2Hq+9dBV62^ ɼJ8E7?((oH5kbcE`cθ} ZE\SO=:qD+fb rV7?_ŶNN](X<m:<4"JW4D)&HW GcC5Ḛ4J4\W"0/,.]}}pO1ۘfITmƘD-owwRݭ`3&\G"ywQW_g7KQSmF#fIgNqiv" / y*5v-L*cx׽P_Knjc sq*Es"ƹ9rIahe)9ݟUK{p;[ !4byp}(t &b߁s'(Z@V)FhP+ȑw{[kshĠsJieuASt{] LqT ]n@]@{|ؙoqg Ync-qW竈vH8A [ϡ/ w0D.[B$_zZEA:*+BɎ?NN.EEH胩=|^u u.!?!7<эzzjNA^+D8~ZG `{v˳W)xjGtk-,n9t~ƛEpk6wSG"+ʬ" :npI~FlASş'B`S׿;R?``^y5h~;?ĵwoQ/4ڦՄLIZd9L"2~ES&?_qy'W] p5] VG.Wb3EE8"L(e/^vU 5El5*UQ +U)`"*qBODͱ rJ @B#oDq"EtHwȱh6֑CGSOᩧ!B"M/!.F\(w+ O׳v7GgiFKo /Vnv LS8BdeAДr,\k%UGgKV+&3 ;m˰bޤJ&95!Q'RQ Ά.;[(iPȖfm4B" #CyױQ8B*ǯX,8<_{S 'mC`jv-C ^DيZ}XIbF s)Pv2hw bX*y7يMB+X:?9|sxU{gê}vOV#e85]#?{I'Hf>O~lT,+y@+ңMCH5s ɑ!rL'v*veS'"c rڰUwtvM*#=8|P0, Dp2dX9-Ϫ8C}t["-8v2{EckUJ{a{; z $vPLpf][éϢwu6rތ eƅ~2B\fkpug 9f+<ߏ2N43%#>rE\FXOF'A v~ \yAOVgp yCRx%9e\<_7G׷6ೳsu3+&̑!ݼYB.I.?wK'p N;~#1pÇ퉛3hҒx;8r6h/AY|g ]1}*4) KNiQ;ߠ=`[onLgMA:IbE{;ϋ~53cUCSMFFɕ(/I<>Jgwwӯ;w^ډ4Pse~nsK8vT\ }v0Bp2VƚaJ7ZΡ?7+l}uFˇLh2',ʬ҇q8ᤅat)Gȅ "zg.^8'Ήǀc1ؒ<2I80FKcH%P׹]+Sc{`f+F ];1 s9)ߢzKKRPZtBVu륑?3=T<2 AUq(8BT%c4$i;Spp`/N?vL/]]z"P29-}-0i:45.bZ0405.L![6;٩9zFʨT zq ׾'feuzrHssw}ְ\viЙ`bԛ\j IcXIG3/v|>h ߪQO6*E~_rU䖘G1JeNO19uWDdt԰ X?0ޞ>ژ9ibnfJ9!& {nTIqy,i{LJQ#^K)fE6ގ1lY2ONl3AFUџAEbLz"6vbJ"&"$W.^Q[/e(jU=BBF[MhyuIDf"*+jb3ں4sۿ#.5Z]ͨ&xa7F (q:od8iը)j-P m,rOOPwB$õȐEA"~gsAb7ZO'߮.[Z)zՋ.t)\,^JAVO2+ۉLisޞnӎ%r7F%'KiegCƜxb**S`X<0B5 \V 6|\ĢT5)M}>? IVص0Wxأ;qzՂ[7my?̈mmiLA{AlDYމLc6#'G[;#hŇއ۸K=a.A8i8辮mmcbz3 :h:yq< +<9k9)"Pp^(?E8>qs4r,s-+1ѡ,Hnm)A^_" +̂W,ʄt>q௮?NS籨ך(J^OZs߲2%*.4/]xp1_uz5v :(5 ,$CƳB`(b ho !( #Lox?EQ2ثB}&#Q ǓyyJ-!?;;PV$P@G^/-*+KRs: )e ,| GtDX_&Arww&SX~BiX=6Ti}x Y12n;x?;qxH) @Mnjd=_1ǣÚMĶE8q?=Ӄt (VjBs'8] x(e(mLI9UA, e*(Vo篸jyP-cJc` c>kV:BGԬHY`1Ԯ TZ.,,Pc܆RfR.kҶ-L924&V;o2ƎVEfՈL:{D On 0K/k׮Y^U{é8H6St[S+HX!_"f09ykKSȑ#/>"L݁DDSϾ;DGmqa>|tX]J!2b.q킈4zNr~mTwRZdJh(ڊpM~47#x>J:9;7nAU@('WUp3nk'GfF;}m4Z$%{yڍƹŌkk[إuBKAZxVq5BȭAߌ\th™c&Ԫ{N(mJʊ)019}H %r]}#!6D{+JL9B]ddr؍ׅW_&K#nX%h 9>PXZ[,n:ɓϼ8 82}+O2JRk=Z 7NAp]?ȿME;>q?|s |2^ȆrezgM<U|AsWOѐ"Q>S2,Vd8VhOGc> TYa̫*8d*5jNF&5s}],vkVDT}s7ݡ E=;c~++Rv ٽ9&;rd; lNan.G`qQnQ$T?g>[{i5ǟ`0bq8?492hP"er#G+#:sddEиGbK/09X#viB0uH?@F5(?`3Suԩj0? NLGjROxyj³,7]o6{R9!r;8y-.܆*^i p!D5~2K(173EQ{W7as5,X^XDZ05Kh 7Q cr ,-Zn&><׿-iǺv&݇LJoB=vwVY#'C-(3g?%@oY'Gly0D9gY Y,or?\wl vq?t |<*aA>;33嫗u)dD,Hy]4EL ˃љ3]>#G !?1Eћ(֘qڥ*ܗ#ͼ0TΓAЊxU`q0!"?<&]&fFEP":2EJú9N9 &r A$0D K֒$_[믤uص%Y-J3@0 s{0zER$Qg4f}^P8CYAEY<]o>|sy<^FzZ>{)gѱ19J tyq5q(1w;I??x/Y="A㽟k S}g"})JO&ƚ&Y)/.04+in[ZE+4[VDa** }wۇ0Ye{C,LC|Q+!!18YfINLn]Yصg;057N; />q7:I,ԣ ;[H@HIm&x1\FLƼ(emf|r9ұFӄ!%<}e̡ʉ5 %X[!@y~ѵ\Gש7KKJ*wyUq.s/Z/bӖLt!mG:e/\ c/@ax2Jm8R1>?K~]8|v|䮏)v|tS棹yGd4_.iq?V^ˈWNm,~CSGSht>t؋Ƒ?trlz~wK_RwB"Evir$AIEr㘝'D,~XDsk%""#pOd8R1,;/c|ly7r aw}}Hr%YiYHNH ̉*@@%qxּ%&`xEEBK G`܀IFel+]3,/͓H{Ӧ:/,/H_9Mb\ҜI ?υʔ39e f`UDN dOI}Qu_Uh{w7;6ɔ-0'[$ɨUR}7 I_*͍2Y0Ern8.gnٚ^//&=({XGyI ɞ>q 0@c<4 %+lL%S3ܴ#ðqcK ;o&d'9Ei_#.GRtfPH@,J*vbwU'5``U]&'&:PGk6؅1Emˏ`;q#3ػFz{.= 1>>)yAlŜ>lۺhNNQC̰ߍ6 )(D9Sd#vHFvytѻ)Lbnr)hqa>:U}29C^gfUuZ~;s+y=p0zɤ ;sGR=/`ue eF???߈P氕"ᏒIHZ&F&pȹNenԔT=~ &G fPALΊSOKKUQM5 \F1r^6U{#(\(2 @0Jٍh5 qNi6sl}<o܊݊ 6W( M̓`p` 9H賂C?{7!h4kjϣRA8 LivaQbA^ד Sys+(;(sEF>=)SoUR1,M%gC? Қ`ǥn-Yq(x񭠪<~fp) +a[+ja.(HX_6b`pn #˧ (aQa5=_y <(*)D_4EޘDOp^ J Z_|/Ɋ'ye:hSm0pA$]s)As09rr4=#(0+Wx_ohWfU-~8o!s_A?c |3U<;\䴍Rieu2:z9&P[8$-’u@`3 yGST.H!GP"G|UxS\Iv%"ɽ=}8w"ƲR29 8d]vf&NM,&"ۄ?KW)!M99f*;eB>y*h;`c? &&YD7`s17=)?^U *Md͚<ܲf|w[QQ4z_X_3BMJ)9Bg;7KOmv.N#ѕNJ;sULrԐyɉSQ 3zO$B1E2 oP-N$'Eڋ2]TeBLp %=X,Gd3#4;c~`eVs`?f'QRLtCic O"ݗP^hB ;lt/` ]'GQt{鵻(,ƥ/j;F)sJv58x ,Oa셋=/GʤB5܁GsZdJnQNiZt@  IPBss?t) "¢<|s]AJ9]>$e)=Nށqz 0nn>j튈Xe.:~3D{X듻fV 8K.B[cbq;n܍lqs(% ]98x=)Ѝ aQ~*nٿߺy, t,.B[3eRG8d`#'n'N53Sg17BPװuu;9)k̄2nkD( EF/Ę,2&`a<]g},O E~1`ί‘bN#;цZ[8\yՄH2#hԄqg,Be+zuy'Qy;ecHNBOecy^ t~AF[Y^Kj168&>B~aNt # I*q${>݆msa2445o;R 66,{QkԠ4b^F7ϭ+jه?ȢuI)++yEJ{L>>D1fbJwauc%n*,{޴Jn뵷L.Eaii} J&1lP |  7bah2ɑ;mɦ<.})wqTMzh?|伢!dgyLJbIJQ7tfr }}lCsg3{~aI6c2VV112MǍj47BQ&ddcSu ͘e>&'ThHh9RӒaa\Brv$PT>EߥGW[G0nt t˖1S.Hg Db gQ8LDʢT'RӐZGˣ+ YnA  󝔑(=+8{+R]X;n PYHϤ</_8f-t)B\Fan)Wdb{;](,@`Q߄_{HJK铃x) J 'Ps 2N| 칄In'SPRR÷߁|mvfG68͜g'@`;$B|ʔ))qƅt@ MP)5M&4S->ӟ /&zUr'73YrsNLu=.2EKXpiGs;i*!Y%cьeUS4W/OB-<f1w|IVWa''VY]7M0?ŋRO9\iVJxQfAAV.ԒLTWWC%PXyy֫Rd^T;vC~?.>w039N&ry^HF&v+붡f Rs)rQ[@ށ~lٺf"\Kp٭$\V #7;KT||7 p!1>f&,O>0;=_"R <#KZ޳ k+1dfWLG`n}<7/̕ ,\rj;C;qPʪP@cbw<  $ 3gfczOmM56mD5ʂlʇ-dEoANQYNc 0;.S, [aZ蘷q5a^,ELݡ iZlƬ7 oYSaO÷S>vWr kJI oNIǓ>BM{r1z:?Q8}g "lhs|'N@F<ȿad4{ z(hY@`?.>|Qt6aqaCh޹ } yM[ӇSvރo_c2tp9;]]a2dD\0xII PUUY~33rrmkkаLDs+JTs-7k_*{yE.E늌dɡ*Nx=^iV|~٤Tq c8),6mZ\dC ı%%fG}lRb[nwvcui6lfgS R3ՌDp@2xcw]?O=oY'beeUv88KLɒ^ZF:.^@ٳtlC2EvCDnyko1‰Eů} PY={yNG 6:pڍC{En??,- }x8b'`&NY"d UD9*(38`2KmL]^1$ӉE0ۘ,oEw2r31ǢgyŹHl|j)INdaԕ䢀͙Ȧ_٘EӞxˆPDTO'-1@gGKs3E@]\C4abb \ K(݆VIT=24BMYgXn-[d}n~A{/x9E s=AW|GM ΑH4?,EB;2n S8{418Z\xr#Pe PC`8m_/عsODnpEw4=2;03f#!M15=%OśPTT6^c Uu93R r9rG܍Ͳ$L1:Fk4..cy01ǚ_ QUeZE3r~_a/,LݰtY~΂2.Fm__1?9%Ai1 * {b"JRSp<5lԔ3")%Grk7 ʊAYӧPRYLP3hvƇ0<6{1?dwh޾mN!%Ղm8{dfI/@O):E@fŊ^446 xG_ЙU5qM];wtUqf0rKol@0HIGwt@xx7:::E=)5QkǙӧqKB5}Pkksf0??+KAHPނk,\>h[,"t<lENԹ~e|RDˊNhiI<74'=QFPTP*T6ӳ-P5t\ng\* ƜD|\v*ċv&#F^:) )lCII!e kca&ư:Sx xŧ?ЉKm籸”kE{2Ekd-5nUlFu6$gȮ@xPlN%5p> tbd2:ŗ1FkˈQ3a O ˆl@ (ˁn'jEQelt>^&[H]ygcꡟ`vr Giˍ SJ @jEEn*Rr+p4e鰛3ObS]|Z^B~^9yL{hhO_霯Qv'T Kƍ${Ž;,UUGSӏrۣqhL&ݴPQc}(M^wt@xMt~ *׺~ǟ$1F8q,\\kbbKKMjfQ Ko2=0THFU >3pHՉz);?ts DD ęٙ g~)aX]]Ic~f0?= ێ:Pfg -&Qzr+tG* x#z ZgGHN_HΞ=O=G#MXfvXrϴ]cg51}А]`c~ +((T &@4Q,ڦ(]p%y)fp/;/ ڱ2YZߌ{aP_U^Qh7GQWW,/N-Y]*j x\YL0iCU6L F WRP /3/Anf.;ܒJ{xԋ߂y\h;mxꙡ)?{%(('@mcv^kDEE)nns>h++Go?UJ{bF:*V CAx ~HC}f?;b"7./.cym<AoP6LtSI"Q, ^.qMAe>p<0 %9´ F#[O0l$k!RQnS~#4v[X٘!Kp[)lȢݓ9̓?2\_p~9plKQxo:e* 5,SQX!LHI gu'#!iDOcrDZd'UYXN R3z,(Pe13= O<:+F ã(FY>+ f<>NLwgyiJ-;>Ŏ-[y rҳg~)k;>#kĉق?\SOyyExUMx_9x?%HWwgֈNaϾ}d_vy۰2qn.$*)/ǃp;w5y2/:==-ԤL8.ڀ歄i.Ku{2IF[K58{c4-PƯx5t{m7 q:;?lq=KQc]l6d@}HK+g`ͻ"wSjzP=wune5$ggGǡww܍-[Hdhh?鯐]$T`'[\o~(((БRj/px{`pP;ŀenlB`5T,<'?RRqI^NQ rTn;􅑓C`ha_¤L),Dfn.)U0ҹT;,KM Aܤn4BE(ǨM5״M_m` ?K 9[n.ܧ0;>3y]X\gOMG019'p=<ηǭ~'`zy3ز6?"[Z+_K_[n'O, 9_lnW,l޼YTJK}c: eJeկž+S!ϭiDkomE?%Y@ @낪ـ:Zčv`LMDq>]ܬLbxYzS#O~LCy j`l2Tfz̃?"Y@`Īgm-qqerzq@klx=E ^*sŤOqC>xƓT;MtNNzFZj N|2BdqTrWӍ{мk/ Vy;6y~ٹiLML`rbk X^P{:yi>0@eIYފ4jT1\M hd}cFkշv >OےG1ްX2aq-{op7.,߲ >oNu;a`lN>uuu8q8w^_3Q???<6oެ𹴈Č/I 2=Cxf B*ҾCUuMO.!/")Ʒy5Z9NcV.5,/T 4Q#j$cg`*B*kt&-I#@(֖zmȾ95m"[/_?~x]2qUSjyt19 ks$NVf0ETXTEC ,-/ު[w=%R\t6095%|cc}Xc|pZ)[L-;Ԁ;niՔ1uF (* U|k] fHX ̠kb2v<n9a44b$d+_p>Eٕ q09E0nN,(Gܦft.1э4p6he-Ua&.2 'xU-}mo foƸa2ry+;O}QB;If8D߸t%VTy}uř[(JxcnVfaax[\4ǦdE.4G vlۉd> J[[[|(..FiYd$+W7S(m@HMOCŦZYNOFyE9ο,ހ_&V֗.(Tm^LPVa x֖`rRyg3ny?ݰ]UFb<}hP#.Lkq/sj;O|ʉ'b.H&c瑕z=} ۶?Osޅi~\;=NJf:)? e 9efپ}=i?z)Cl,8hh1Aܰ+^є ((xċ/%J4҂>(n?|/dx)4mr g0;7Aǻ`l̩ĥ‚bڵ^kb CZ5 P3A~5>`0h׋!N7)5OSrIx|.t:3SL@8߬w2Z/?xs Dn81c_[Uk v?<;9\Ci& SvҋgP=Le1?Qy u1Bb | RXY]ɥ6mU! ~vޭc?eGedp['kܰ]BijϼLa2(JF4)ʨAaY*6cn P)5aC4;vicR/,َIt@xWne`>g=3(--"@eF"B}}8%o6eV>\%g^ 5l~7hh .qeH*e\dIdgi'c xԊYkL6oƹ 0VS.6~f,+DjF&Sa;$/EIqV}p'e+#'7Berva-Ìw^,*ŽYڱc޼xsrehy_߷ `tb~} gd ~s >LMzG h^b`ϝ}΍_LdE45nu ƢWK,WjI+U0\9!WR<6v}ԩS2rɥ =r]hnn}쮻[q(UPͲmmtFzGn{}TA@b!' 1.,hnA>rS  ݍnuX`y,"CRdƪ ãc8q)5)ؼY҄|"F/# OlI6k6cmS{.š{זB rc=Ҏ?[' /+Ite_YIJLOX1hHIZno`: l֭Jaaa{ < { 7pkBuu{{??G@VKfeIM/w`rg~d$  Ha[WҗV>Қ_"+'u n5K>$~_A 8$F0;X$e#-3ee&p&$XVN`զPqǏ?Qg7ًq7Q~KHrPƝ㵎_w hCl*O|\W_<<jkVSLI+=YXݿM7k: x=w-Zdȏ;[ P/cuiAFYPYwud#|$Q$Xܔ㚝ua ;܎`3 rrn@rJ_cpOٹHOܢ*i*3Ղ? !f r$Bʗ:^- 8x~T+:H vUt!@XLkcf&@N/A̽6C߫ A_y~ 't{=G"6î}hA@:={(G׾&z%%ʁguQ܉+61Kg d楌$clE.Gs3DI.4ԡ2R](-+FyUe5mS3ڪw}1V͊ZjbuMރ#E&Ҕ V/ : /I9xcQybW*&X&hck6Cn_;ɤmkfL%.@) F6ZiϾ,t YY4#-BDEYz%!ۊOr*yA^LWE^^z9 #;>9hUd1CɂaF,A2ܾ³ZQ_^yNyU1])B#$xl|-he:vmΡq+Ro.0ّj`7ղa=Cвv n|_ Ie(jpxm|?TdY3CXS*X17?Q׼79ik<3׿oB۶ hJbl -s2a5c(-N&幮4^hzkPf%m\AWlܵ/@f2PnT fŶ1՜3S]tɾliid3RSPW-S3帰׭[2zx*l@H\{;V*]kzL7}7*-Ȳ4gnOӱGy {P)P7Qج+; Zԭݖ:AEl.Ŷmѿ8ڇ bޭ98x.bFѝO@(uZr@DT^nTܖ+t)-ʺ~HȼMaѡ+*g??Uif> rLFv+fM1ն6l0h(ö0x=>hjjr`ǾEryi.loLǼҔZ_`̊a]ApLC+ڤ6no}spW#@i\g/10j!JnЈr-IX1AAO8Σƹgm CS%&q߽,;v4JZ&yl*)DKsú`YW2l1v7ohWdluuuGw+VTTϠ:EG3+}[6/ Ҷ A,"6)YW%;}AT#m \doB8bPE LFUUbܸ0YCYy2ĕ(* tMmmu"nvZ>''7 g /50YM=x&1[Тh0I M`y?Q֯ "[H!eF(6z cs)H<|_R{w}3ǒEs|69ȨQu2tVa +0@477+{׏o:7Xz-3* Ш.4>%PXg923?%Cq f f@7RGPsHIqCa>;;+x#4Az<ˆ)Q WL$ime#8 ` )*uH8,_:nnt~fMXt+Kقg0ڗ֌XZW b0&srJqÄn\/®sӶ4;6T&''c]89cBP"@P̉]֘L{2SyQ?31_RZCFuLFB =gMt@m#6[̖嵍ݎF-*V(`(cg6Hзѩ=S0"]*8PN`Dej `kZ;طuf: \綱s`Y^2 H͉ttEȑSuvH r|_ҴfAOUgs5``fm Aht4pJ`LX2yVJ DN9Q-#2' SB`4Ul<ڪu_K7t{wQAuѴ.׍㼱QdYE ɓ'qyYpX_b0Et' ƽͿ7S:qϥ!nhoo,׹iA9澾iϯxDaLs);z,)?AYG%&eu֔AFnΚ׹mtkg`ѿ4C&`a 3=IN$&$H7Xe3"GH$~,릛no造FZl3Go61Hh;P3;vےx܇3~ ba@ah |)@R 錩VOuǟ ev!Bœ6Qo^4Lf-LӶ!$D X yL@%r.:B _\\|Cx"yBD|qxKI;;;v~DhnB~ 향v\;#!Qb޾=9+H X @ p{T*e-?T\_8U]( AMw߮yimƐش@H'+vf-i-9M<++Ydu)PRbllnAR#^C3xO 5Y]]E}x1l` $r-E`k[+RwJf$+ٔ+rxT߯;UIg.˕TR^ ]զKvjsŚ-w\O_oa $R(mFGG vmsowe+&0`hcc6)w~ۧ5ǫf(QK''9GWZTy prZWb(0.(a1Zj "}= BZl}i `RZ30@(`̝~js HTmvuyO h|w/%X,^4?Ԥlށ&H.;Z^ZjH;ozHXрӨS׾NN[ӊX#G- 1qnk/_5iqtr|QӪ911n@[u vi,p9y,BB:#IbU#Dngm2.k?mRLNNڐ@Gv1s3 |9zo Dm>D_i8^]nM\/;s׆r +N#'α\+s +lBH4PHxr67м۷#f a 3C~.hBp.y.PHEaZ= 5$gM::!BA N;']o?7G $^($VDU5BzxC C(0)@!BA  þc.&-h>"t w#`_@ $x|·Ps ~Bd[ 2+Xǜ"eff[Pa4r߷¼!qAA 0h.K١ucpOo~y9wI#}}2z%Jg`vk DG~lQ&Ie'{ [A;|zn=XzgPK$_E"iyG_?O>w_/ǿK>_.-~g_g̞>g>/gҿw/__^/|Wç^_ſ/^Oӏ9 xtaJ) ;s# ><#ݶ4|oeLoHwwZޛDKcS~?K}JW~|u%5xQv9]{Ku^HJwl7.Ӗ]P& 8KF&ԸOi%ڦ|^'[>w|FlْbNi#6Q]s/<_ϥ,.?eP"#mx&k[]Շ\ٰ{oO:;um)yƣ6?TU\ Rϵ`F|6?$l@6wx߅SGg72P~ƠH:q}gʗ{. ?yljjz͸ծ^=+*|W21Pt-RE{5e);U'c+$ 3$lM:yB3HT>\zqyZNmɱmL $)MfrL2]\$Ź_ÛOǓ|+~h+-(N Ї9V6|hB]Ү`SvNM?)|@*{2̜1dkj9тήnpOԋoHJdNng3`8SώC] +Ѡc?FZglK,>ǍV;&mט4XgpSsfH[% 2͖ȟ-|M1{&GD@A=ʷDxf"ǺP OdM eG>_vc si_c@Jtq9뤔–hdwӢ1298 |$S)as[ޗ{t6T1_001snrY=؅M_̀{| bODߝ ȬzƜkeqvjWsLJmT?0]%g%0$Qy;9E sba2V_ uLD: e0WtrF @OI?AE@ T)V+fNX"r)0MXޑ~6X$ѺӑfLs}8dA֔v(K\@$hYf3I k:q0g {$, FY5- 36/ w nF"{2mۉ)6HS\.URPsF15 2%{Un{8 Z`PSQ?[_ayf#PV 4*Z>I+uʈծxԪa=SjME]oRyfBaST9MdRKAա0P40' ~N |uĤMn,$p/r mu(2#@WviP>p[R\X&" _߰>?-0*`3kJx_Z\%J>yF`a"D^ C_NEP ]ƀTПbm%A,/49K~|t3X ZIf #vI]4iXfFDZZ#Hе+$7J#Ov"X` QJ߇!#‹1k&tJQ̲8_+[^IPDƻ`=>:CwIyo6}iӾrEOISJT$KOwTϸfIERBܛA-{!`ED~YrkW~Cab) Fo}DKiV*Tk.!7qn?̸C[\%D̅qcA p_Eݻϑ[?7o|[x@u[ɤZ8Er§` zuMŌFByܼ^Xhρ Srj{3X*n"x[mU} : sm3zI?o]`0i;}56XO+ 26 'Jnp`ѹ K;pgpxzUU ]'X\o<&ΘI|qoQ )oHU6!34%UbwȲܞ,vzW5}>f'g3/EL+Lߢ g== DZSڨ@奂XjDYm)X*Uщ0м(XT9;t<dqm Vw$5bqlW YY $z x({{y1|Oz`@n`@l;u8,|F#I-'`KlMtsPsv`Y̢:./ XUwilj38L"ⱸ%3Fd$@=c HuOd4zx42 z5/Qtn%&t4#.;wU>-)ܖtf:Ӂ^F <30aF"j'^ZH@GM܉SUwu' %Zet`X@"ݜTaApd<~N] 71n`UmsLF)+ }S3H$b7\^fbUlJ[Go qs BrCb qjJNf-lZL4{g)vhSDK{4Wʒ6 eC&h.\C' ?Zh]5?dHk_e+ԬoZ<Q*PVY6I QH`jߐo)_EMW 7)R)8 Δ.  .jCM :gw _S<,do)OeHlf@&b iPj#N2_,غy4sHdh yz|l lR7Pb$|I&陊 :n$(>&"(1nP7M7QL2j.B})@KGIb?a1`HYDGJ\:7bQ=&buZ?d Jj(mھI3i/0^&*s8BW]Psy܌YR1}1J)) EWN|laZQVs! 3"ЊYZ<a H'HB-* UՅuVjV[nU[*ښ(8Jma:H7G?t5ݹJbu ΍qhhrL}&'@mD5cz+.&zVY;>K8D.; fW CX<Ǻ0$mr[7 UKJnʨnU,xWr^ ΎE:A[Ͽnyf/P~?CtEB+h[74[Q/o H&4J$%ߤt)Ԟ3 %2*vNC'\Ǣ"C-^֍{E)w0CY_;[ |:5r]7= &ePvZ6zd$d@uqcЙ*vl̆Ut^F8؇ `A7Y䐣އCw+jxW9n48Gƀ.D^.Lf,j7WG񏝼<00W6/UCjEltXh,Rq)ڻ^":RzoOtr}39m?818-՗^Ugԕ0N[NisC935lŒؓx:,cA=$LŅ"+n3!e@3fӦD<]E-U`Ԋ"#Fwwp*$QHBX$x. )#FN|x$Lqe Hpp6ޕI0m,$O>F"<'8y*q~E-E{A bF$(%HBb-r\[p[:ɋLOpA~`N&J4 J**+ kKw0D"NpDl\6$`"J?Iuf`3&~46s/_䗻#N'k0㎠jD]@eRwG~dl2 PPWtNmQ~;֚VC-\@ԆM|^.kRg^SoU+"^tllv/KddDvT2`]_ga@)pi[5d..xbH6[Cz!pZ$"Ne,`n@OsJ54{QỵR2~ )2"a`i1芬n#K. ^k{ s%r\ ,0B*%.)|2,0bvy ta>[(OxHL̈́Q]ob} iJS!:TaX+LN?KtΊioOǟ"qj*GfF*r[a\LtʣM\NxK ծxX +YUO/)zˁ@ӓމNfr?nԫ({jBQ:ؑ txiB/EDi,bB Si|eŀR*^9|<]k-w"Kɴ `4fUƇPlGxv}"1F"! 0>D'AdѢ-d`e9;bA^fvԟDw?s:x&Jrۆ /'2~ʄ!.}v7c>WjPgz-%\'UiPXO70V,/io. 5`62cf7>~9/Uo1 ji9 Qx+7JE9(:2YŻ;0ׅQlt_.%Soq;V64ȺWCwt?,~ydNAVdTNO&lyvB0bh/5u6yhDnN;V6` ~=F^Xl);RdDK ^9ȷ0=3Cpfc"XNL<;FF[W%] > H,oEdw8L 2"\r YamC 4kO37D8_ 0f|q\Q{\觢eF4|Px3T1++{͆uH+֦ !=oHѻ8 aWЕarJIt1`FKfbYA{̚A]+sϘEA L n"m`5 vv!2Θ]U܆pxt#D`q= ǢSu1 mB_b0i$`K:ZP9]3ڧV<m R 4DM$ʰ Ey߫h 苺+Z}wY̎]X(7܈h7 J7[7xq16pjX!1 ȭS+m+f6Ro@,&=<95?Y7trpf:e@j"5ZQJb-" ЏpyF&y{DԟHV0fdMőBta``\ z0 IQe-mI/FY4Yǀ4anqKYC2}qYJɶͅa&bfd1ךf:@]}4S'?VB h-%tmQ2gn^cQѳh9.g̶fUB3ܜ\}@}2eZXC1b~=d:(>`2gt~@޷(cen+қC؉QVi`]s+_\=Y"5rH?+LĎ4%='qК(2gt7Ga:_gܡr%PEg΃bitL yE &QHn,#Ѵj`b0u7V9$Zq QlѥLzz;a=7ѼX%Gg~`1QՔaW &ZxMԆ`7, N<3cmO/H~28՛5]XU{!m~Vj-.&wiL:7=q/"XDhƠd$äZl%mLň-Q[ouJj~rpA~yD^I{=Wיԕ ' D^xG-%Aǁ*υR}NM;=67;T,!)Zu+~8eACԛfG=p+zGCa {]3gX邢ًxuhetv|A%cze@΀tB|LLkaYۡLdj"7-3Q+0jNP'PC/!St<tL$x 0kbp |QQ$7թt? ؛ E>'=Y\63{ Zr]10=|M:+k:zzE3͓:`ֲuvƍ]9^0(̲<32*IeӅ&'>U# {n`O2eIdq > ޛ|&͟>B!'BSyW v>$ Ry@A{أ(y[5PyQgR]J"7t^1DUĹVSE,@{33ztTzӊO?:a&Tf5 \RJ4̄;=DG.Ys*CZІ*c R<(q "f 1At}4[|eĖL-g<  f, MiBB:(C.Μ"Ӿ6KrR.AI~avuʟ}*qq TݦYÄn]:Ytn^s XpY|D|fBpǙe7P'\ \ȑ!ὴY3>tnQ4/'C\}st(@=P5dғeiEJD\IуhӐLrg 1^t'Pg//D꧃ƀMɝXE4XtzV yG2a@*iŀt|0 1h`XOQ=bM% Q$ύZm{P‚ZJTQZwŔg, OMsi+p [MDvm@]0N|U,.qv]eD]]i1 Or` Oq,rStEH u&b\$|&}bgpL7[\1.BdJX;fJ>9GR^8aH{6+BMڭt0ݣ./O|搮CHw痴b*ܓ>rrHDͽ=kџVSBhXTэ"|x#`T/ZpT/!Hջ]Ƴӫ?cq2U(#LS]d&d? 2)8iVҋ!!wެA#ǧtr^цL<340"߲gW>␷ZJ049 Z@23St2,'uhYPƪjx+)3M=6la}ݰ#, K" !5;)@+OW.: ۼ/{KdEsЁ$mk|Dۅ,ZD+Eл6\.t9L\%$䘺}~EHA_<@E=<|0ڿϢvV=CU23V<1ާ {Wޢg驧!ɝn$}!y.*>3u٫S~8c`Ǵ~ ts:S’h%dhRP`#v4 ޞO|l%xN >ضPALd0شvttvAtjN<:ULhE7̒R6OvKM52ڀp"ħ4S+-@Y^<,ա7%R]YQu``d;cpkj+jUyrnu?8ʇk{w[8Vdg&ɡWR~ՇUxVy >o2IN+vfؤ0\L~v'wH 3LZִO`Vi}|!,"7gζ˜gE~ h^R\͓G5}Zh,np?-e=DBZl64Yi:c ck1ˣEyW_q]}ۓYߨW4Gؤ}=#ڼWپC Z)h FM(}TL1| T[O{G{A#&c8́[&7%h" x673 |e nwe@_:TDIވԶ7 6['p\E$l'HQ]'3 ~Zl2 a萩Wޠ}z>gϰpr3+]N6 mKM2YNʁwʲ݈UH'Q_Wbs?0!jm|{@ :#1Y:I K.`̰HlO=^Y|dYWʵj̉/_C:+,n}O%E2gl|+N*f<:k3C T`@5g޼M}ߪߖT2+Pw~?h- _/6ihLuAz\k%ѩ=^uYƔݦtt᛿}ߦ=:9-9O竅hdH߷!4H*K@ _~@.>(,E r^w@*ʙ8qocAI:Ŋ( c@Aj i lmq#kż@Jt`@qIīW?FjveM\)NT4bvn KraͩHs޴ꚚRN:NnJhFh QD=ߓR- ld2b'-C%mg:AMhD Gbq(a,fg]$fiݞϩ+J[O9_*GQ.} [.V_GW<2!07?xeOQmH\OM$ Iu O󗨼 zDW>fVB}I CC+f-! M+FBl꟭K'`G7$lI~~:mn7k;pǬlg=fDMլPTV ΍tp;QUu2#:x!;NN.1ܱ^$1Ye m{fxH3ba| pu hD&yY\Uާܽ[V̼Z;6f6R98 Kj2 R:E6 xJ=y>30zJ$O75a"K`V<,>0k~ KU]拻t8VF7s? KR0?O= 2'k]+.ʆţw_'߹U)[_rE>bHlǴΝcRH +|iA;Kѡe˻Ux݄ިY-2jR١M}sQ։BNFN$If?_ooni_gЪNiɲ>I'Dxi`~B)-Y-;vPxncuYkRRӇ S/;pw/Z'a̧m HP $("-tam/J,*I,AdWvOŖkjv=jsC2bQ̡* ıhvwRsK$7"Sa8(="R`@{sj:&"z 7>3n]g =),)(O{g'7ȟF~C${v%@ .uIYըM k I4>JGo̞]-f+oۇ61u%a@QKu$VD$A{r#7Ujʔ=n=8iYP]#'?Izga9Z%3C"qwv#9h@QGC=1_pLgb>ҨxvU* ;-FlƎ#g^mח#{}tlx0M#0=<-H`&w쨷IIFiA߆OQۧDYgR¸$ ... HlVӔ`teJ:8OM̰؊i^2jy˔4ۿMoлg =~yvfW< {vpe{QĒ4qYFtAWfg,>+'~:.*K^gfFXZMB"[iܮ>INCY yr5G5fB9s?T,3Z3%>a zȍ N/֩M4zl2Nf`s^n:`/)Lmv5ndiݗlF3`cLwi3hqsW}>K̠ŀbqY*,X%0aPqnŧD~}ZE1^tz :99~&޷UHu Qѩ@څBR<,jVRrv|= ($kTDiS!={Rt]#@^Bvsbҙ$T! As/ "=Z ߡ?z!ݸA7?,.̒K4Y^oQ;:m%wiM;Kri ^ B]{({6*~Tffl(1JBz*pԱi׽kxțAI:yFxr;%~%9CuU}LOqڻœ 1T MJ%x`L=rpL}(evޣ{o4ggK7p[*)d ]?>Y GE82h;a$L{DowFyDgGoߥg>w.t=Pk-Bq m/x۬Z64#nQy7r<nj"1$OK0ئ`>/=E1X.Vmj1nRi\ ] JOȤKL5N9yZ/;ځU[.2R%`Xhl4 =~,~o$ rN :]ҋqNpaI&ӵ5\t-0yE'Μ*c!6P|_!Qkc T5M_g`Z=T<]/Ghdݬ\a*!_f`fY&bvW*^~X_ iHc]ߊr5CgQXά 2p Kȕ1=OGoByڿ (j$+Ɠ켠?ј+IwX,磙wYYqS֡%m\ (x׏7t4\;d 㺱^zHl0Ӽ-{`HJ@2$:o,8Svz(1wZbXbAEG^}G5aWSx"Ii'jtI1-BSt ~BGLnlz0]sJ>H3iȯ?V)|_˝h]'g$Y^y Z,sM+i-h`YgfǡS!ݶ,lzVd>a;gxę>=f(6ƿ ǹzEb%sBt=x!'Axi)fb`)ʅSTdO\M$@g&cA) 0Ym6e|,ٓxWwY|ܠ%h1lo@'V}Bl>Qr}Ōۂ6wN%1ݎ8XNE"u#`,[Ҡה J{tq.^nof00 T18IH%f%lh\ߺ8OэVaMYIh^Ȍ^BHnTuKzCzqIڭgsz|QIrATHɮԕ$7ZhXj9Lƍ=X5J~`7]I@?kJ<7N72DB[r^qGH2gG$ Lb!P$#&/ :8 pfNw<:Wox7IHu)Q=u`ѻ,bʂc(/ʁs<YL(L|ޞ $vXH|YG(cmKskRZ}fERhRP(US}䠏C9p>ՠF(Ue!0p>̓9>qnE[r6JT 7 yaB-sw7r`yNb6tm~@mн7%=ga`,8C&^; MI:bH;GZkYYIL@+3Ѱ$M"Xyz\WY7:}#6L $T `LЁ)El2lrC mƠ<\(猅R4/uP.Ac(KҦnTSE<GlPf)c0+oʐ\Ob}Fl ~*qeے6">낣NyKQ=Q&}i:|qScC?g8~2,G[Q\MkFeEU6C5GTAv*%Akg>إBpDq#V_jBS:w5$޼XEyMmh]qCX15 LSndLokLƐlƏgX8NJi$RAo`3`2}7˞uH']AI:(VZ0K$Bl&sd@g;Acʊ$k KKNA){7uiW5_hIiϤ7cn*bxj #XvխSĸwp(_N]J9Uc})Rv)m 4!,`Z_zTwLzB'-m?^tW+2%+p =dȑW}.I&]Vrﶿ{- 5˨eiJ;ôm@Pb٪g[IY,Os{$i=xV\Hu~#u!l4l ~l.Kae,jT h7hNyǚ ,y'1p_I}Gv 4F}>|p$D Iu_a"3<#r=SOEl5tNua wx7e =>: lĞ Y.Kyպ*ږ{욞boyB0";'flG|~Qn>= RI* KHۃ)VB܏MߣKHru>b}/%^ yl'cU# qI{"[}Pk;X0kqQeGw!R esx&@'!sScbup$:.6c&7BÇ޽{2ذl5$5` ^Ӄӟ ~lyٻA4F:lNM8rw]zTQcBg<,>mz43JL߸6tQ=OϤptuab[b+.Hv} *3 \zvlrnL< k9#<^#/q Y[$E Y/TBc>7+U}LL]Ym7-+T϶t g,٨m'l$S`Dg _5;"f"k!8;K*ݿCijTy ^ Q LA\󬎺0CL3m' `lE>l##NrIYV(>ox~51MOE} L4%7: }@`6%|ϒ_e%]Mls) Y{N-}EoY :IR<$)Կ2*$:E kZkp? 6&,=u<@ vmDe@z6t 1@PlȶXE e= jV- ʁYQKåtFc3+at DWWlۃQTAlT HWlfy=$-TG%`0cy :J"~aqhC|oH7"Q0ߗ@I[v13 HA$I{*m{p Hwjٰ݉3% g9. 3(n,vzv=NY>88f{I;4><3bnDHXX6 zȳ5!-$>^VWIu> 1nDN']*ӝ.D&o͚S:D4!eI|G>}L˻"wX\e|7eBSeG)V\N=y$YFM\zhU|4ZWwj.dhG`feZęuuEEI*÷Gӆl>Dn!sMd f"T[ܒq#ezN6Kegd9xBVDbcTBŘݪf @ ݼyS@AANN\4Wу}{:`8%>J63RMke CQg(=_djc`Qi``)we?cfeeYhp1pݠٔ[)^,pn 4\,ߴYZb4hʍwYd]~>8Rqh_G:CJ͡e9gS##ܯjIl{NcȬ⫨TC$U U '6Y_;yKۓoQi5myOk]#:Eҫr%+'27nNFeNOSwfib9g6TL,J@pƩ<.h3ssm愈  Uze3[[V3^׃MN$16=`[A^;tr8;"}XtJ\Llu $uгσ~DY<gVkc|{o%xܹu6qߪZ 39`fVo& X?/yF,~:ڀӚ>y|,ʊ5.U˱`MMV#8.%֚JIa%n:MRUlz~vr98&%bfj+J>ʂ0}erDX(eտ3kΊx0 \=L3M )OU#ߠǂ>^P`C5UA5s,Ͽ6]{%,vG>_$mFd:,Uj`g},L0IJș?Xl(DtwDX$AuML.O,e52c"?m:$ZfJb%&V!uRg$nCESu%bqJGJ?ЁX!li#̒ƖH uf %ױu5')wSsjJX`^P]w1 2:Ɗ)ge b`VDBԳ*(qtLZ֛n'N~(e9q(ե,2#o89Xlzpp}_u5zA3%d%>=j}oՙ3g'ǮgU'Td.~ѣŰ8d9?ha%@*·')Id{XJ_7Aͪv86 08oSl^ nwAw1 gz>5" X+}f2ǡ;R6Hl` AP&Sx1<EVWb*^eodswlXfr-2`Xʗʔ349|l׭ӮWrG}d*L¤([;鏻+͏gKU{r8O`UdDZۙ-t*f ڔs~@[8H^le~` ǀ%%`5JS5%0_#tɢ(.+pkv@c)T`>w.Fz):6^kl;.ihl ~}x8$6Lq88l6<%(0]Szt#+'c+T}ع K&~az83i\Y=m%MGI g&ώ)IxZS K)fm3q &U @)[̢ ZfմIHcC1㸏1#.Qfޓm:XH/3]ĥa@nguf6?@-~(T.,إbvjߔiߪ1,jL&ǀci\[>}mD3b@iA䲾"W~Ҕ2&eMGv[Ǔܜ"_Z_p=a mnب/J/".&8YQ8PK9C|,Ϳm*`伢ߞbAtGŻ/)bw0ljST۞7`1XLŋ8#Vֻ_ ubǟ8/6[` AtI6q=eٖbTOz&-kGDp{NUee2z_H2))= Txµ^ND1D Hv;+OV&bQMfHRY;Ԟ.6wšv A€ wnymYx͊z`9qn2bi&d]XKSr#&k-\Fvu&`k* V1PZ-cnQ7MQuwsbF[Bu#QԶ؈kQ^<ud*VyD_3bH yc6ZhSWɆ HR K:#prF(_OO^N\);",kMlJajDЀlUEv;[UރS:"tfW)I!6 #'2nAӊP>8|hPd,&6-1Zhq;Ye@6<$8 {5LtY$H=G〬<+$H-'B_ܾ=ZHa̵z:b|tF<#X~CO96_!JЗ!vMS!7 Ee@e88I=o,lɁ%jôEj,^ S0"fZȱd"R:4@ͥEw]s76QP{uB" 4HM)+W\vsshxֵ)fG1LG a&:{]cq7q  | s츕?԰P(bZ&}W]'fU=$ΛLLm}I+eH$Dg i~I$tr}/zCGqBFanHhB!yߟ{tݐC+[mH. yp%@3'Y;jQ"OfBq]1@\&iMI%_xIdNG(H Ɲbޖ.Z5\q+'9.OtZ 8W.d{t!N;6%tA1v)Z?#g!tty[VE4OA4% Ew[p,O YNVaLž%ޥDWfT\ bC'NД4LwC"-b m P֗مFgvĤ]yπm3$!q)Dw?zq&1;g.h-x}Au)-)|J)t%qW%4ǶttЪZRFIY "%ݶ\oB<]`+X($FN|ƴ\B.D&YKd)q Mն01ҸKuFbC2ȅv(UE}@$ [`Y:k4-எٟÇtbw߯u Ƶ:_ux=cq DkqrZJðtB{=Ē~$rg1O(<7 b #H"K|n\-haZ!I ѱBRHyxx,2ܼauvŬX/ܽi4VtuX'$H2CbPQ& '#}fI tUuk˙:r GΗr8{([ط\t9qT]ww=] ߩ(2.}٤7, pmt9ѝ3jG^X!JN¨t(rC ffHWwY(YKJ R?'J:w2-`2f6W̌bID6S;HT Vó-p+Vi瞓[Ks:&u9eoP(xh:O\"B`ŸtHuz\>1Xs$_JDQ7CNb~V)DueΒ*?:zLxd0!3=|q{ODV~"@(͔6tӱS OTZ:YR@'+v/He3IVDdܜD20.F{.&>F 9wi&ܮ;[Sb_yZXD]߲`VSi$7s"k24o@=]jW:pe2I,#A9l%4m\k{onLof= -5fcY)b6xKy(# } Y8^&bXzp%tU%iHI^t,WM?Ti4~~ml 1;.3}۔B]S$#cR4r75Kk8_Sq0d7v6 py,DTHq08WΘvt3~| *E/Hܧ}^@ΝHc8Y 1 ub, QHR]B}Tď<ĭ>mQ @@mb\XQǽ  ޹s^xZ@2fe3^eYpo/~E*+q&U[ Ӊ}bg$I4J`Q NVV4u.y~C%>X"HZiX@BHZ$Ch%|YQEב.>s^nL%$6}Kvv)4}^{Ї-)`@ L2}h"RFzԱ8`8 $F#2KQ\S>(W^~ea `o(ӭ[0pwyR+* PEYXXOC u#JXt@ϒhRb榅Տ>Yx7|[b3ؖf+/tBHLil*Iz;o _}:# =8N]py.> 90(o삥EIV'Ifp2>l.R6,D|u355'|Vb.yŖM-NL-dW^[7$ƒ$=͗ŋȬ̬jVw 1j693Hhft  y`uAgn `$ Şf\"3b_Ȯb+xo?o˨76}n>[@[Z7G9@Z>c:t_[`:G)hmO>~qki(hI0@P^=~M0EKgEA~gIx!Zi)װE\MBS>mo\cYt厇sB$X3Y#{շeعdm #m/YtY[R$5'$jΛ fRޢv͠I B.QphYل>Q`a>OMQ/S]ĺIX O|wb4sڏ~̔:F'q*,R,~4ӮP4 }ʴc ow',>{~@ hm%!]MӄKXC7 R}SA3¸)5wM8B Ԛ+-ȡqjJM \.ĉl_|Ct: _Gu]f-"pUtG]4<5uL@벴} V9>SgA,̚-![CV=Zn𹧉CL3#>6V$ 6Ғ3ַ4G=^ΦWdW`oD\]Ph}P9|͵Qwe0L$Q.t3%(=%jegC ÚO%JȰEh*6χj(T ]}m(lrOrR.՞"apN۱m@Ŏf393#OGכ7S*Y2f~cd9H_:^(WKM0a&b&= r)a4I7O0_Y($.)H 4t3޷6ݢi0aS[DH``L1ٹGrn ;Ю[ῶƪ5LC#PK~6!Ks" br]4kgĒ9L"4MLMϩ634%}[v.h(X͌J©).4iִ`ͮo-|X 0=}GUX'hic \kH=\\ >&]l`5*\Q8ync(%3aspydmʭw״ƾW_@e)-Ƥ8Nb0F.L oA 痈إ&X\'G8ᮖ8]w{4T˱nX;=_iLvWFbt׶xJ͟tAܱT+g>&6þظvgPumS@.i5q7ԖRA9-}ͺ瞚Mv-J*dGfB"(54ZѥwR=V+ӒP\J2hEJf@&l -? 3i ltE~nȒb;6#JP̒-\9P]OUhE>:+_:-q&N<OB ԳQ\- Α#2oC3 _rEI5dG̹$s]_0?ܔV.Y`h]9a&d"DHDG.:/ulvQIHdpLJ?n+L,8l5"/;G L3I53s5]Γ 0}>Tk TP_C0sIA"Tg+Q6̿eNrJ't#$ 0י|;ҧLMkˑiɽҡoȞFOZ:-O˃-y( e4cd)p"˄`D`mX/ݗ-W}^ O.坏"'7K:;`,2|݀fFEnі|LfD!aIZID@H`DRY cnQB|4` @kk5IfBڊ}.a"absq|dPB|M$g2,H3)Vf8=",6Ѡ-qiБj~ɔAĢw'/w ) K+lshwLkoUB!2wzlDjNS7<*J~׶$oR \E"pa!2ODKf-ٿ1 c<&Q[ S?T.  >RW9M0[-M pVZUd-جqtr VdyfLfK1"lySܱU9S_FK;6Sëf- *ZH:z)5[yM{L)gü+!kf9-P6]nHHk\dN|PjA8;IOwL9&f5g¹Io'5oNC*=4CkH i?lXh,sɁws3Qx=4|OR|aC 9 \cȸHN3k-`o,2w]hoB V6炅Q014qaa*qU ȂooL_Y]d"H˫cE ^@ȶ9JEО+֘ qeI:X\:Ka:cjXS}IsB_Įi~)w4LԴ0e'uh暝xgV=d8&}CS `&f,M!Ჶw-qV3_~B"/3GPcE<{l(T^F$k\2#'}^uHM.6dB}/n7$b>E^3ʃŎ7!׊]+y.u}xRm! 5Vrftjݿ}oŤ7T2d+*vѮ'll᥋30@{T 45flb ᴦ itrLa}Cp7yZ:)D!2E[ڊqk0g~6O$Dʈ ѽ3/:}_R{kmѻHh09BR,w&Hp:#@.'cda*@t]ఉeTk*ic$.5gq6b펄>yͦL)РFsiu蘐t^8i(0S<6>*'EYI qF3k=X෫d!!П~i-hMi?ϡ u{e=h-sBCEd,D-[UdBh#RlR)v N크V؈GVBJ7 2 *S J-zwmpmva7A@"-eJS.616d&Ib) )cSl;7}2%HmVó@TP00 ‹#u'MJ;d"KM &cqjPOq$W=k醑"ѓ2` j6_8Gˊ *jknE4;WdaklN@߶!`V4' >0vÔ@,e)GHMxH}}^=Ks9 $Wv3 ׵R{{|?X&-.k8DI!ظYt,eM-x=4t A !$-G_@Q`ԍ,"rˮ-ll (S"\ӄ,~~[I^~C ɹ:9ބ,NJ9*]G>6c[Q+2A?x>ɨzAwnkꩺ&[H:ʨi00rU32/E̜b* NÄ`j+ŒzY87/XROHuWHM6v &s>x",~`Zysm1dijSy34~o,[iUZilkC8n#d~(˝>OhD~Gq{&3Ro}~ܹsY..qfu;u1&X tNb. D }o{3%VfIЊYSz}]֜`Jnb<aчy?YGs0z!X3*#TA{͊23SA+ 8{'Ǵ94n,ڨ)/%tzF^~m8 &jA$e,kIR>4T[dNryo4Ts㾻xf"@3`D^ص EZK#B?9ËJ<]?nm :ٱ!@ xOx#9tϣRd; eY >7ߘŴwd@UY LRZ|<՚vj̩9(& t4;)=qm,J\ 5%;0cL dbKfkt:AEU~iYBA_ĹiY5cWU8:УQJu h.k!ISH(sHΑRgKiRl`#Y\\je'6y0Gk9:Z/stKw5sq 3WQ3%}mJ%!}/J.uC,f_ `ߞ%|xF{py%+WFXbf!/ =˸x/ ]$ |HRt7H?m9\0VվȨa~z D_ [PF@ Ag SFt|,Ţ_ɓg|^[xV1rhD8'pN<{2I)] (|Fv_>6sɲo~ӱ)Ix7Ɔ[M~Nn4; }NǸs(w5A|> &Z7ߧ(Uмr«+zgjBч;G_ ׍ g-_  G l-=M_$<iS84uYI#KL2kMTX M6MmOIw]' S3KLc[$>h!M|LJZiiR@P<ɳmK}aqi]\ 9I:T{m0}B͏A*xFEǰYmq -1}3M 6-LMKhOJz _H~ ^q?0r9I-g%M&UX'4y.#3X T(6_R`ߗUbA}+ @c.HjD[0G6gJbor\).ہFR6ͣOhTO) `շ;nZ'wo/8Ϣ0BK1O-&~>HM#j2=DQ9cFbf7Is`x4H1f))SRLL.`+֐& %gjն|p#z/hl>VS1;!t;+VtAl+j dq%&+uEkH_|{z{;z}_o3b[J%I7ṞN0.4b6SPם>pjE?^{ 5{L^ޚjs" Dow$5437AdZ@Gpikiu4 RW TtB؉;?q`4$sAr^LPd6f΍߅L2D?&4";?\q:ӣL s| z٧6ߣ%"o"w Y 20G>:{GaN$QʉK;{ 7$f( MI5$ Roa(KՐV,|1 2 e>U]z)&` %|ˬHe!H`ltŗT[pdEX(l;yc 2eNA8Z{YIS@x&$L~kiX PxCp.G_?cgABsm`>| wc0gc+r N|f3|;s:xcFGoq88Z,z#V}.v*+ OV&?Gfke\]_=T )fm7XψÄ6iUMՑN̈́)Ty%}|^㪠qPl4e\s0aU0/蠢^˕e(hВ7ԂS۸>`CȢ -\wt{yc\$}{RYL0R%HN?cAw¸M¿?|v"|i[A ' _h>ѷm?9O @YA.}Р TVAV C㟅eI Z2l8X`X0e6b\(Av:)vF1 `M;T4"W򰰅 aއފ0Vd/66YT &AsrxBRl$,fEeu%k+M#ҧ%o:x*#DL:}4-{#>~&c$zFb>{Q! "csƆ 0.H&'pAdd!ӖvL*d9|,Â'<6G![. |xV>o7̹2Xu0SUZ{h * &s?|~w)[ꋧT+-YRd;pKED덱RX.Qjkn}ԢIaG7z I![HN'"Cf,,nASc^xc ۵yFm8:3o&՟0a0a:(fKp$kU3A=Xg|NKAd1G"\$v SG9~$hk"'la ۏ5[D2I/ˇƹLRʉHi*}h`PNrQSlq9S86BXpuY ;ohMx!8ró8"Aq-apf2Ǒ^&#}g/b ˌ{9& 0 Wx& /0X33|F듐癘x<0ero,N9J0Rm+MPFDn~(ZV∿AhC;)s-3:V82-=[h<#m9ǀ ~M`5Hq?:',evezLR"Țz,~4x߇.x:U_ηeO u|Íf¬M<8~[2yvBw2:c^ߙD>;1t?ٌ |~QS]߻qH4#R~)Pƾyֲi*GRk,iK݃)Owg=ysRCW#rw 'v4ZqIoWpQ9 pB&hN{5_'A}(h3:͈>cLjl}Fmka w)Hm:,JZX}X,7a^ k>oÏ nsHmU0{4#@*_i(ރ e;?F[ Es5tB[ѳ\\<~U4>}XO%hvub^AA_@ wk8h;@%)Mp So>L K݃o%5:Aequ:Ǧa{|y6J4:x!g゠F˽Egv-~3, KA:HawPMyD&̧`N9::9& 5TO0zQ^-mZLlon$i971ǖW[U.Z܍ 0ӧ?ћtg6Մ.4HΩWε2!]Vsd^)EY-/gX7AI]Y4XK( 6J"L'#1 2.78sќ1?Ț+!͎] %\UF%(/gjjhG!焿%(+ƲL [רER 49֠23~ sP'Eǯ ؞&ТdQb_iF->I?fxnWcH},TaGٌ!4+'A3; gozwh>>/htxpB~Nbѳ.K }˫ۀRwJԐ+ukI&-7J@;r ɋn#b&P+ Qc u~oGREUDx&g'0°^Mj! 4;.#. (LB!^>g8{%RT%e)V#G(H3Q8! -ۊա 'h]EF8pEL!Qi8Zr( rG1ͱ=ՐL Cyu 9uݨIy~O4Ďg$icTdhdzѴ[ 8`]*R+N3q YyL^!*Û`?1dxV׊sjV?z!}3wxA矅rzH~Y aTCnhG[}W+̶[5٤(IRC["N8|:ǚEoQh~A6/?_| :;?ovD‚-%~SmarB/fU R.& ZQl.T :h{-0Ṟ oh1B"erlQVj3(#R:3C~Yf*_cMdʟV!kW<` 0A(7)Ynfd,WBMK1(`c] dla^9ͅZe[Lɝ G2!hJg44ڄE4(yYN9}c:~>= b~!q[:,X {88N*)D#@UwϬ/pD4ӂ~),'"k#Gx<  |EК :sHrʤq@~L_|vSz|CH!̦ASzJͼtAϟ5eIv h,L TTk"yޑhXCZa,&1@?Qغpw#%80(L( ؙ}]eelrCLclԑ,ck^@=c {v oD#"g)Jh ѤCIY~ANnh͘qr4xz4 ƒ.1ݢ$~ӀghuH(tΉ<*Hy J8hYr)WW.;l R[N(ga|jy ~4>65c*&Y)~suSe|`n¦c_ 6(h LF9nonjJ#|+?>G:A#jp 퀽O0}9 ]\s( ut6PE"W,;CӚg/iV^R]%m.Vt<_I3b-tJB[:1MamZZ|ͧ|#5x>PeE4b6Q7HݴspaW԰Z8‰).;LlH=& g&1QX_ 1RDsS RhZtx&K#F"qρSGcRΑ:uȴ_..ΐsDo2_싺;i2l*P]#)3@AB;Lh]0 G:qYM"s NV,MmVǽ ~nLnh~^] + |T}gXǵ`y }-Hsoޯ- iJ4H\ע 7vs#jeuIBt3exXAŞ 7QߡtzˋsUlDŽraK:pwq1\L;`^ hTvU,J;2%Sߓt!`qhaq߫1 2NR mD4j]0hd#B:GB,h2ӣzy6tnWp@bmES p7hB11v^[ɹ3'tN|RS&+Ո/)ĖkX|vcOq,*h9 & Cbs)ÏՍ6 E֮J7~WAB9MPo!.&yǫ!Eyu M"a\߃.R)M qHњ$*݊D!/xɖъ`do3ɶ0֪qhh4vniyگ$Hb,„*kOr=;c3eq_%C95k'M0I?A;ω`27L:o\yes}2xzxJH6"Ŵ݊@[#-JB5j_Ҩ>'4۰I] ƦcɌjyE?g쒂M9Sp4M"/er:3V!;'y'n%?J4"0{T$xP2װ-zO~#,zWg]> ;r>r֤+6d]N\GyNeR'q/PƟ+~\ob2(VuiBX0olc ||Fiªjo]|л,&g2 °pRhd7afM.4 s|۫٦c}O(IvY~h\|4<3c) MZet}GHa/ AQq#~FQx}o/]^-=H(ϓ Y({xBvkM+x1*8y6:`UM.Sʑ NBz!Q|MV:HiYk^iO$O&*u]7[vhgѕG[!a\>fVy-SU"MN;$-Cf0ޱ~$  ի( $Lz]+L{{Ȓ13i&,@r2 `mY79zUY .^.T0;'"'wϥIPqG횕 Z@bO|u>m5JRMFW2iΰ..p&deWEh E[+#@?rMb12Gs:Y[vN8};G% 1985dx8VbBGhֹ<{lxw/o8}?)ѐddNy%[@SQZ/l7M"*Snc6H>%v*UpjA"* GhἘ gV `b@ 0K>\M@<tL܌r#+M@ꈙtvtrCSsd'4 {bjH:: &x׆Tti{ʤ>z+:R&?Re;-z:-:lRLɸ[CjQP,~ vj PtBѐb eW;_J\bNjF]/bN+/L5HG/NUnĄyL]XQfy~Ndb &^s p8ڼlWQNKH."_iƝdsjČ}atm=k-XCZHx e@D-N?13&fː,G`@/VFOF2\ga55ٯ!k6B31y2}ujw+)I LVv7 >īvQY \{ܳ;m^yL&^їoqws8|elv B_(qh-: zk7צNk/$Ja׺e[ @5BM Y|H4_ݞ@B/ 0@!G$[XH ;#H%qbiGa"Q ׾x~F+*^ۚԩiqQ8 W`jD q$|ɔ||LME> QM5% :"ozEj_9S^G N# &|f‰rc&LDl…\{$.e`[}/QRo-1vL鈿s%U|Jݙ<a!d(69psjDnNpPD L2QM7}D$&3I) ɤ:tM$5A'͖i7aVS%z5OzMfe|;]zG')M?l|KƫV` U 06TA3($m:4yP_&->My%6.9L^MD԰#EǦ=^X&.ڭ4 b9 H!촇3I@~+hE#2`$Xjj(ǧq HtF;; 0cBcH\:YiG?pٯUr35yUT:GQfvGOWB$[WN ؠ**W?U4aX)qY%{'sZ&pIЌIh9X]M*43Bw6X2 4 r2xB10`;Aάh:σJv +Yhh$Hٌ^ӟ_?|F:MkM<:FW+А H a?4yI}N?m8lZӻwFt*Lb,F=:Ŕ!BdxW][:S7W5:7%>u W;9snⱌP^uD1*!P8zr>J+L,?߶fMkQ̛WW&ILN㆔^NpXHZ h_G_ѽޡmbJkLXn+ ̿a.o):=Z(]Z.\lÿg[64ݧ\$1WYD߬a~fVuiGlnP>N4R9]٫7A}ͻDf4ʼH~{bd < 8ir|<_&-% }纈dLm}FC } 73Œ@6}HpliC#!Y+xF рO~N_xNU2EPA7GaR:pE揭Vf {K ]QU#;-S7NϦsc{[@V8=$I+Y9y͉Kai>+bflεUM4C)6r 34:u82i]03i-ɸ 儝(8H-2Yfa͊...itwFO,k:_t)yaQnj &1sY˯zB"!Q8TkIgsU$oj 9lawi=&Ű w 4 H0IDG;ygzV6NQȕȐEH S7mERn:1 ^p^58Ng 8VxѾ(y~p0t$\]&$By;lf\ߔboxn 0W ɳǣ3"um-= H$zy fwS=&e6 z*Vni>rjX sRqZCoV0a;4f\DKU=R -#0: Nxӻz64`|]q4{R-/>'k=cO+(Ek]p%4]zɞQ<_Zj&ly߱>ۦc^M0x!Ux0v+i}? Sw#>) T vӆvD NQ[3Dmi$2> vv: u#5sJ_D /ԭ]lLbݦpt ƒ<*H M`nsڮݧ tN4;<,H%GCz悆4hz͎؁ ;jy: a="^,<_wc|xJwF'< Q˛bKJtJk<$ˁj]۴ټBSdD m#K=25{A$ƥ/ʯ0ڲo> #uD`Y$%dQVXޟV:\,OBqM4tBq.4W $*^3 , =NgV6ˁ$=wIU.| ]i:MU ڲWJ2.8F 03*Ȝf$]gWrvhLD~EnKj*+&.¶0`ShSx0Ǎt~Nˏ.7T-7 GKH3Y4; `Φc<裏^_*hn`KkQ8hi[z Kچ{spƨG:Ь2o9m ʋkĻdJ#yEjQڌ%(EjLy3fh-,H$C6: @0Ey=3~W5RƙLxA՗2ټ`K23 "Bݼȣ@e`2vSs}F /")j(倱4i* Ype1e:X(Oū#H|bVP'0 'G4lCO??܁Fط\`\W]oTɆhئdc5?q|@a>[9[spd /hH.Y jxǚ8 Zzfg` 2%f0ǎ&k><=}dEјoE0GAM^5:rF.t~7)2Ȋ.0 !&vvY̽Fp j%"y}[|N )ΰh0Z&\Wy|! Q0"Ln\B VͰ-$}hJ31 $aԈD2)hP07n^MEKqeq/S mhb8[W0fm| ݄گ.j:Au{bZ\TАF+3B(. =X2"3b9aabIp8ü/R܃jylv8|M.faጂ)vŊ1NEEwz S®p?Y>mϨެį>,ΰdՂ{-:>q,m}+ F:aX/"4jSbGu+c,\ګe/B`z6k\Ӻ#42l#-cSFVDXN1($/QSw4/ vd՛5ג>+^}Y׶2SLT?ʨMJ9jX*xEi#퇟{^}jN`k\ͳO$sZ"${U`dN穱6Q;1dTZ;EUfMP!hz^!}3h`8ղZt<.NoEsE(yZ6RA%dDzq>mg8GtSyv\UC"QߖiELʧr[\֡0m 2MZ7;Sv4&B'O4 <|5CõaE<>6f7!՘Wi>?G ݘ434l7^߰wP9_{`(sHGRy;M7C|f$ WMPe ?}JkA`~$uX)kВM5+RB7<ՖCC>C3â[C av0gb3#Fs&sR:}^]J]f u0mϟbE~0n0WH) P|ސÑi%N.ȃ + ߂cE,H:M& tD&?"Edg׮4J+u,PO Q9J/o@Ua3&$-&*NBl@C\)KR,XMB.c,Dd`~ℓhq~>էWҸ@Nj rEՇ : t\tfu̶vH;iR^!SsHyBY* @.D*(5n5ϗ$lrOEcteKE-k Pg24ӻ=0p*6ƕ4Rcbajzc4mC i_/j:kiZ_ղ=IyUۍZa"=k~k\:7giK畚+ He 6L(Zl i\13"al~+A @A91pSzqK^E&E&ߜ= {~(iZT16)2*TKbY--{/yI͌VYaA~_jXV킲Q( F<:fYl7A6i]ZK&ȩdtľ<9oa~,m~-g_8}_k5Ҿ\׊}̷U{M6q|9Ef&GV`RwG{/6JC(Je-$Gb8|sB9^}L]9HBe~B,Z6Pû&!%ăm>)}X+9{T,)(Uݞ~xs+=Wj9j*T/6[+tj2D[:vsIZmjN`$B"<I^xXPH'|^:t9M%̓F`~^jN?E J]t%u[fj8#@>dZ+< &^t{ᅒ##È[j{},5/ i~o0nH79\W(Rs,K-ՄwZ^/Ӥ&RzmmɁ:hpv3|Er 0+B@IIpONpsgBSʥ_8|{^P-Ug4 w7B&( Y&OrI4eMшΦ0;%;Ϙ: ].쨞@LI8S\Um4X{6[h Od`A/?MST4BsoMHj9BӑfX\\t&u?hzB~dŠv5 ې rRHGkIa^eٌڍ-hoi;u%hIfBڔF#],z%ysWhBa͝/kuw0?d]r}1?k  #ngܕ*B uX-b&2VLƶ{2 arA՚~ùec@Y4oп{ߡs?hi/^mQ+&T/t&&|@E6fbXg`;QF? nZҽLJ4Tx6LIZQ@&D񃲠f`srI)P(oKv֭m%7%¼b2ҿhz^5h]h$V8[_J#ӽJ,̼9l1ޚ@X{W9)6CzI!sq_ħ7Q-=2`R@5tqvFŒG4.3&B)%US*D-~A8mgLq)Nq~\`ZpS |3!⇦T-ʶS-nz0g"g,"0({BJtE<+&Q i )U,j4o4Z畘S=:72j]qF˕;ìlѳ6h2 *M78SU6@VIΜv]tRƛCjlVEg&${;reZ(sl>|ӫWb]H6G%;otp_ݟWѐѹ޵5$#GLȇ~7.?>" }IAMZ..Z#B]q5%-FZ#8~ J6vNfDo>&Gߣo~HwA ڜ aIr`xKDLUT=hʊ6= 9r~x6;Xo6#:9GixD#/.gǵY>miqēaDXqQ_mN5ʇ*<_u}E2k_yTO#yҰC+O9E.2eTbF)9u&=GukUPsDZyK-3X]/hDJkMe6fc|' q}\ y'\!kʂai߹OߢfPs>9LMGA9w$֒M-˵Fi6 ˏچ!VT GS:w'.&Bhy!vV.&e4^C!; q5uZ"iz|\*WYQ;`W!"%sa}>W}}у/)ILLqVʃ@"IED7ՆzP2-=h~@a.VZa5-;{햓uwNR~ Ԙ~ A;7ͷw߹OIjOhy8 Jǜ!GG͈hG p`GΏ9SmErI;w.|."30 րS5& r"oQh@2-SGMH1 6~yz?φ}wC7u/Wث܁Y]9n)hXqXCVX^B2|dxP!QK^Cdyt`m0G hKEs!D^ϨĊYϪł`͂M7^Gwh^Oåѽ`ty@rN%-.΃#ԂLP'&!u|xAC%~~F}Y27{GO@ 7S nahBck/~LH|tO-lb >BtC3p91.(DKIۜ?.Z q/Ñ}}C2 Vny[suHoj~"Gsjm> ]y$30H~!9ٕM!َ[C^ӞZG)-iHPŇImmNchҍR𺤪–ԙ=oOc(UBPmPgzLӰ'IZ2Tz-o{yGt8sPdTW3+qa,T<(J $$S Z hőԊ I4dtZvVUhْ|f3z+Sd3h?jѵpVk ,D*hY"+BhjRx g7)Eˆ`j$rٲ?1>III B'jtfBĥ9|r9 fыr1E%hSJ9|@hN+(H-|sjV] 2nbg(>@L䕳0ک:L5\xw䴬Ši4>1/HNڑw+:NfAcr( &bE@ @2jW# TcN _=3GP;$\2< kT#^۠ٴ\GI0wn[c#JG\Q 7tp\ҝ{i~}e&> \Ԃw0FUpι/@t)˚G#WLK1~f5y6}"/+yvbui|9a:q,ְf4mq; yOJKsi.EZ'Z$OXݿLXF@Ze2(=dxSy.|FON%>ɓv&bM:5K,v0TSicA_Wro8`$s:ZF(%=R6rфÕv>g;=Y(N]t b3`}IdJsF0ETh1@bBGEWZN<Wdqj,Y#"etׅThVXC>[@VG#ٗIX fPfޕy,.if'5M,/]{E"iDŽA[ B4d4{ng(nu4K'jH԰۠E1\-qU\Xy'}!g$mJnl%]&dn~LE 5N㭫.<ާU]ik܎Yg򲴽ˤ@j@ Qs4HO>. F):T /ֺhCb*-V?+v⼻dZb8 H ~@fgcE*3zz8`\xT%,Δqem fJհI%*,|-,4#?Jv?Kc cZ'g2zGYG"G.gxxӆ;:*q/ZĠ!"|3dT:32qҹ@ji ]w@ |jv I[2 BHKSE%}Iijyl+IKfҩdËNK"O(4ڢG<[;Bxspmj"Fiih_F,._b-TFil|ܞ'|\"δ Rrc4D~Ew{m:]A_*C)Aok4MT+UZ&_*ktE /QeW)`qnABv6E\""d]ZQFhg?p h t2<2GF.=6>tsIlmnٰq\7n.jgi|+!6n߬jmZ%*kHJ)m ҥY6 ?c}7y4:!w$Ȇkh^i*MLjFr٦[$'=LƂB=gL\N*?SrUpL<*|d#ԖsG];:{%YQgs)Xq;=sVEE$eu{o{RDEB~䕒Kv1yj:\B?uQ/ ω[d:m2tr)sC&oQ[tjIR"f!>fgK8}~MgZ p@sx!`u+f >nRJ2l6nݺ#b.SX9F7=;G71RMp8(qdb 9@"|NI)D-ИjB~@yڻ&BA_ȶfXhpXrp3XfF4Ώ(Y 8߾k!42W9(CZZ=%|*,'EI}U2r2I Iρ[ r{0T LWB-2ȖD&-PPM(F_0|.dʸ::U`~U%u9=3:8PSph`o'`e$MAa7I|{DS)2AW?L\1%?sd,vDzyH4 j]){QU!҃ꇸ̬܀0 &vw1NFbͮmS{%F7G* <<er^x!%܎R©pJrxptplyl"#ƛ3Γai"nu,Z&`cw1fhooPCnV{ʡLp`B44f4oMzK0Jb9/7N5ސ/tʉ ܷPpdQM׀KPKnA,w&ӎfL[>}Mj1 7g d8=rߖLr.ҤNrfH֪kXIayuiz [nP=ybMCTRfM<&B&ƌɍlw먵xpLbSM.I1:⛇@}0tVFJk`&{@nG<]X3aebb hCWk]K"CgKq"u*vc1 ,L-cݱQʑ,".+acX,%s|p$ny,h3;>}:/vI2HlTtM(@*gD}_i,77h8},vp*=Fm%/.USAWĒBdUW5H!gmp]jgz,FSOw=1&J_חœhM`հ?SX RH/ ֟5Wf4 +mO(Y4btL)3`j1#`\j I8! 4 9oFdZ1>\[NC5[+z/ Mhf=6X*7Z:j@G K&fKYo7*_J 4tӑ Kűct QQ?LvdnnV i1)b莟D--xܗ>NlAjjGlP{*rx̸=W]F#= QN2ӝ Ea i;>aF\Inv'N, DFh~ qV:"M:ܾsHH4SdZmsh50=?v avoǔ(/IۖO8w"dR1&(!kwLZd i$/+#p}-c it'_e)8ǓLBMG@Xx`!F2XIJ?DyqJ j5y)MFHRuKS4VXzvXbi|Gg' -rߪ)#N񊧒RgJO\x ߿GnErN* J\BҡUe,=['py<ј GB*ɥ%C|3Aȗ hחE; +41.qHBbt}t\ʇ [ PBBId:s2O.0AJh96 Ug+`؍JnFYjl+AS091]񆠾[-4kC1H+OgtuBBsgN}PQM3H5q22Gh"jY!Cq% qrGHiZ| ҤڸEmʘ!"YDH%rP&"%w`YwNXIts5cI.SCn:)4ve}73=OPur.]WvB. H,k2tی1"̬Ⱦ8Zp䎦e=!Cjs-8.|H,$!-sŸf!XDҶFQd* B 4ȼb/gP7dď Fo2V`;]SjED! 8{,+ݜ$vkkƑ!r.4B MKo ֤KSk&1h-і"q$&pp=OHG7'zRFcCږ?51R) R澺)j,@K"XUڹg4:4!e *S &'Hƪ@%Vא ~_;#5mS[(].X<^\wrAh8-X$w=IcphYkJ<OG6Zա͆\-LƖತml FI Jez5R>l4uhmz[ƜHnoXCC1(;S$sʤSk!iqcy0WWXBi!荆:{ aѝJ[4K.qaOxsf U׾GR17eE(IQW\∔;hVs:D((>֌>`坣BNWՆnO8 ɍ,l;\q毈/ NEsҫ\ả? N\4]gS!0yIɋx #M4IL(vt'>N,w6/3K2 $<Ї=zTMDv *e ~/ta Suz K#9y3SE΋- G&RנL1]'׮,{(7@&CAFC4GPXX&C\ 9K'%:y['m'pf7#8˗b*GFc_pf bÁ@6*m^\,$[ & 9PY736 8ZB.pF< [OE8~)r7+9tdD-={$b!Qm ݗ ʍ:xQ{frMxj@A\)+ o) R߶f5mr~ ]X+ ʁe;aeH<29aq`_EWHb9] M؃@9I$#"w F'HtT Zd8QO%<9P_ ЅZ+BK|h 9̈]v5M/(|/\iIӥE.5s6~I3 'ɽcU٨l\mkp| idʐ doOܼ0tG^Ô &ږ}i+gbCH\r#)Ŭxv̇%-ݔf1Nѹ%wbJ%#0 &Q#.-.pԋ@UpЗΪa&r44S&)|!#:y-k&1oEǝ+>$ &5`8-cg>qXxV$;j'`HTnj8@ nM x6EX ~EiwtxAuӑ=] t( QD;)bH=}c7ϒu(/_*.y4ΕS_}W~;{7S(L'Knoղ$RHrI)\w f"y}e8=UD2G[w6 LuZ({~{ ?G\^ ?LAd=辪ɆCK[>"tyoF)҇Yr0KjtfYGKKYԷ7i1==h^Y$R ,"`KdHLGB S OU)1)i"Aq`| Cք;2}{ q1L}0ڔyJ`wD# Ţz 2FL\(EC$:m sL)C) N҉FaХ#ԁuGN(E c-! }x>xjz9 M_Luc)Qd偈%M_j3]-"c2]i[&SbɬiV{ҷ*AK~r =C4Tȁ<8 kK\A&8ob}rqZfKܴa wUqwe$! >w~vN4t# KCY@T 8U Q:)q  D727l1YyL<,6Y@Z ~k _A^@~О{G}d8vH vZr7%"Y~QHU2?g R3i #Gj,Ri'+x`f'N8XYHj*VW=Qͦ`*FI* AT-l<:A6͛lՇr4m=~ !P3aȮ(~#t(F]6-gEm- ^.5coF֞[-wyja|o Šca2T"G;>;4,MҷLN#>B^xni[$LVigK63Mk +hޮo`qi+48:haot(@b V^t dH̐\$HKë[ $Y$١"ҙ,m,*(6C$%4y7+[fgX}~4ݲ=+v7Q[JW^iJ4JS.,Bc~>dԘR#vf7YV.7L?tnrr5@>7:[[5:vL.RѬod)Xqt|t[^ $:BzZ0ni>u4Hؑ `8BJCY;>L'":͹Wϓ A܉~W+Rfl —. J hK&E4*D 0.F/g'obP[V\Hqvk;iقIV|A"L~،p?;Qs%. j5HnGKMܻf[Jij*{C!U'#m3%%=䙂bNv=:3gpuvBwAuc }3/fᶹ΀$F\8`vvE"H \i Jdɧ尵H6n6+"l3ߤ0@rok7n?D.灷\ >m+/i,Q:sufd-;s ds!lT1uOzo} kd?=,gS(dӳhϏ⋘6TmdN pd'Odkkȗ@ Q%@+A~j1h`t̉q4_Dgw sdegNۮF,EZ!On.Ao<*Y![ٟp}͐`?wu$K-UG78pbv"Jcwg6qï"0\anHO"+m[=.8r.O-I:xM׋hT#޲s_ fu|Ĥv`)Ͻf_,NP|6?(7_9qUD;AP'IrH5`E-_"f @Pdإeܰ1Ti8I4фi/ c_Tʊvĸx%zCZYHeKW_]X!EoԳ4"¥O>nŸIJP.Onr:Q/bsk{#|xsI%\fztVGr4(C%8ۡ)B]!~uϟ/OoݮI Uђ 74%&q+Z|7-K8W҄F:?x L>chFIs$ډjlIQ?i͝;K.hD0X0,qE`e brodhaeUJU1"s\ *1Y55'h1̑aYBJzmI,DnАH"I\asB;%5dBVjH:V%=L<:'Y\?t&5,Umg[w1;?K2-Ba)x2L6m6C;1b̗*eqB#ϩ`&d=^Ys4X'pcGd65v%IVЬ1#cm s6^YM JR*JEZzVEn/բn[&~K{>BQ(݄G9U(&7Rh.&J 6ҴȊ*.\CA%nDZWiW4oN-"/}65}2LkQp! 5=+R"4$cj`9{&=Mw>&Q5$J4U{<6' 2":A"#^iR!UDyVaK5RpYԛ̇sN? E[2X-b[q,uVfoB=S4bD\W^|.S9 /&"`nCSRsbk3ʩgϏ`JC1( ۋ,.I98lm)ҧgJdlNqzkՂ4F4d#M-=xV]h-ti/ n;NE?֊Q-Mڝt!HKPm|4X *(i*7K#]jG#MGxX|ԤɟC>477n(N͑+MjndW$ "7WEu -`%#2.="'#Zd0hF!M*%;0!d.+ٚs](w `'CHfvBh ZM ezkODvvb$m=G3 QB8{@z&2cR o˗H`'ɠu4߲HRh%'#nƇ} a}~֣G(`c?}t 'OannC\}z/o* : 롬`ҟdi@hzo`gPY:M+VFvQ)4y1nR/x_5 SaHŲB֤)rMJLIØ)ypM˄8*QA ^RșZ)WФ][G~ۓRWDGG(H %- ĒZ@P}o 0w, ͮ჻/6$]Nr"bf1#y1] r ir+lmH.%R.5N;Gۄf}yBcuܼSG] 72AHPX$`aΟYs%nC(ߣ몈pO4A"Nbantgy}%v SaۍApOM6^~AmϒZ4@ɛ]KG>' K9,q'8¥"Tpoݡ粎#l4O-Lca~JJ~[ oV~6=]$׍.2ɔ鹙.^P*(W6iHΡәD͢V A \u%a#@`vؒ `@&S(-Ν]Q-4_:R$2"6b6&3cp qkX=iah&eYp[!Ql77mwIe)T'01 {D!v vHPO~ϚZgK(x Bm(`j&76?!ۗW$B‰<dwd8v )o\g}Jm&f .ԩU,[TTXXa&3!)>>>Y[6>|9z)ڑ_ CBP 萛GEBZLNNQ]WvQUi!rh+9LeTI|~O{adi'&JH@܊zDX:;z{k-iLFz>&v%*8ŽZ|鋐S6!i*9g/VS\H. q4Si\\[īYǝ:nW,`}J v<3ܾ]d*m?z S6d^}4j=.fiqZ8i/(QN?UDkQ,^V~o|U'hX'!G@[W?H\FQ\92vyF {ֺ#c7ii =u%BC&LE8*AzFGퟙWqXTv о*2mrFq~ Dnm%t&W?R1$QVjNt Lܤ+Y!ߞDi~-l8&=!Ĵ?0?-gV gki6I"蠳<JdꘛpB{\l\ S<*+0Ó] J+b$iYt4B?u`V?mr8f LU._:xKCBYB8;HFgPȕhj3ir% 2mt0r7زh,NXf-34y{b0-aWApzN`Őh|)e2mGe=FC# .h-$&l~ )x4T+ #HmP{+ifb"xVȨ ٷ&m*| ִcDi8wi8YD, hEܵ$y#i0 /\B2;;p}'tv+<Kf(x| 螸b8dfv\[t#0nO#A$`!fgY3!mZ\Ɵv˸q@E ]a6r>F/P{%@nZKocz1qS6SZ} ]'=.-, [*]>%N}"6zUd*y& %%"Z;ڶ& e⛂0 gyѦ d:Ä"ZMdu3XFKx߾۔jBǿkxEd'ɇlER)2E-z5mOL^Hydwe)s(B{qcvjl]'"CZf:dd."x67t8sfdž|T<.2܉/jl8#'2z܍b8g--Dcޛ}@pELesz%J7 I$qSO;Ni!G_*FfjN)8qxWdٴ$dI} vF}BW)1hbogWϟ>2< کKS_86+-0Zh?$6a֓{=[>lIm-vF:X߅X&!HBVHOαKAc)dD`0wq\[pPT'D hZŽ%savp*OOo欰\n lTE_8@_FqEOԢMlL mg6߅Oԓ/ZQ?V+ 4(ri LckswF*!Gwb)iV0h5:¤k\.%,l &FRԣT*^/,X\ T`\E:] gsD MpQD7xo%*/2s-U@J߫0*B!KOP7hpf$"]t%·>Ϯ?5w\, Sp*e4 gEHFYyf~o ʠ6H"<)"-9Jʽ3wBSOȲ]c/ Ly`4N$s=`ĉ{3 x.H2c(hXɑ"42Hv)s%I 7sN qk2"fgg<njkܣ֨H*C>C-,#$wsTf2i':..%ٖoėHvPj8A$Hn4+6~|~{  YWhFt$JRheܖ!ߚ ?8yg@-kxƬ,qaIBsh fXl:ұVOIN\CtX go_^D"^C|}Z-!O@M @cGV*Y* -9t@iH tʛMH(>A35 Me\m% 'E{!kJO&Ws]; !$$w+ZPaۈO1_:['⣟5rO˼E-tǢ,d"*;Mh-;ʓjBd(./\x50Gˇ:Mqe-u Ԍ̦5:64&lc:쎕$#sC׮oFwA1" m |3S}?J(p&=phnGkKY&+2E6Im<2F 5n F3!+Z=%"~AÙT ۖ]Ydm)*n_lC$WY\m2t;6<.fazi2nKK).EdS Qb`EŸ![09) 7Z]ԛ59O<Eah,T;I/?B6DI/j.fd^{q x?Z=Rx)FR謁f=‚P6lC13&U,"5 #qD&ϵDrBP!QOx71hDЁo |<}< IɲfA&dBb<!A3D$t ZU8:F dF{AW㬽)ܐ9Pf&%ۣv[hoa_;7_9ݡ)M:OK Qh"dܹ̀/^Qewʣup{U$8aZw0pύ۴Z*u,+8Zq(q_B00BZֆgT1 Z\.CTҺ7@=D9DA M=\N.bj-1Ċ>_2]|BYJnLEJY+Hh ;5+pgԍоiv^Π mNl*E`b1ZGU2"bq TBR2*"B8Pff>zacLBF1/c#~,Y5 ӸQ.K,hPȭB'1sAK_f_ Qnq&b,vlAoj+"ɸr{8UD D"8RF;xLxM;jxt}-VsܤE ehƔj5u_,}ŭ'Bhm88<4xq?~s|~R2J P;ަœ9|?&wn>Q J22\"·DUi= %(M4UeNn0m]or-!1>.dh XPbgd"Kh{2c1kHLJs9 <^)*2b?q'm$@ 9z:O#&ٌTJh3"$RF V6bo\*"Dȧڭ+*{x)|իt=2XR/0݇K8:v(oܸs.7EaGۄwF(7:Ϯ}.i,IigϽrjeNXXV9a*d,>(4Ʋt Iy.MI GWл{6m|W>T7g(j+6 sdjD5fWv 2/ˤMP2_&K<=iuĵr[<#qAe7vlc*-zwN&*f)JrNz|T&jG:'XKZ-[uh;x_lxp~OOhuat6!2,UʷϚ!l#,F\˫d8-lloZm8= -rI>==[(^/3C (!#&o.J07IX9<®Qׂu1 Q"<|O;CJs//ۙ̂|xIIM)>TDc5zB!K" 4s NDa6,1fLd#]%~owAգ' 싵C|'ԐBn0ܤxk,RaA;8{boS3P#=  ӳFuAk"Ĩ <4 yhh :Ww`23L=[$XwZcD4ɅNWA%-F@\9c wItH2&ı #%,1(S TsUtL*o2DqF~Y|>.V>y24sqr!| i331oV? "*_1"L-%7HP',6]ue8[cq&X`fa(QzpxR47VCƠH;۔dS~mb9Xnt2Nqa 7"GA4fװLk:Wҹ).1ڡ"o2-F^gA '7aݨ65^Βv:xX׉2Sҽ5.h#=iw!-eCTEM\=t\=b)%h].\;HW _>;)hti r:KYD_-&%Qx_I^haRU! 4TF^S aZ`..kf7-U5:pl/GLt @Hi0]~5Q/WߤaYn[À'xeĽI,u&{9/%~JpxO+4!4ubtPdA~+Wq]}hPkPMp[[_ĭ;{xЦ\4ԁ ŷ[4÷rKW yzDnWu"}r)=]kAw ^D=Gp }~mVưniaF'RXJ$T0$S*3\M֌ֱƏi\(+ŲU0~@Uղ~hh/Sxs FHrXiI*d 1ϻ yT.ϑ":&\kxbW/~>?o`{v=r5=;dMT pFw*~7X^ a Rِ s\ukt!&n~Fܸ͍ĖFOl3Gz%N$gIZ%@C)㬜6z++-|L1Zj QMkaӎ_'IwX4EĂԺ|èPvt0a,d1WsR䬘g4.5I<﾿O;{?A'߽QxҴ='dLw}r6Acc e\^D?E|W.+t3<##5A{|Cyt'"+Yql(c4l{QP%gXNIv;8]B̋3}SO+ĩu$|'O3LʼnH) пXD77&/%3FPc$WJZ7Bja<4U j$HM`!Hܾx$n j΋bo֮`&M;{Js`&KM<}M.|AOwBy&HG58PL/:pxC2\m\LjnJ4vKwj_jܕ˫8a$;]A"݀A2d {hQ"I,$ 1+2瘑enZQ2_)\D^4gD՜c(s?;gXww?Ec~ͣP02 ڵn_V\+^C[@j08l5x#Vw}I9+&=BWhD3jL&Hb=1sXŏ4>\yao+|.k#c%K&JУ) H't,IQ:bG zw DDyY\(O] KDCјb`Lʛioa .I{vYTc\rdGYxקqEȈuZ / 56'#xcD+Ko|cz_\a@TOyx2 P*=YSkLEd| MO\%Ǻ`\&Ǝ$-#1()eY ݼ>i ۡ!0G\5UgKFILeDdv5mjXص e=9NGUY˟~՛I>uɒD䆉}#upN -p/:Lk7[>k{|,8 e:+Sz5nIȃy%2^ؤEpݑRɵZKkËxKpMܼ|{|KtGBD疗XSesl%ʞCgzX}Q kSN Ϧ͠$بc~ST{Cܻ$N*dJ**zi-;cm$AIVoǁ{NzxOqm,%rmE0-{$1isrf<9Ml~N*;{40tqq_?_ et?FKK4w:[KZyZBZwi`K01)+X|h.pً WH? B] rĉoŝfh.;V #Dt ֱ앍(,GǦ 6V΢x&su,M6Ji/Wm#/NWolaCc/mDfRVC%/\$,؈vwh#Fs(m$ ݿ#//._}E}Kznpj۳fe fxiLYy[v3(5'߳c'o=˳v6kIY%7:Niݕg%$xj쪍hhև C2IvqIDĵ>+7AVCT#5^n]<{pnmGpXX}A|[(U<$i%X\8'BA-9睱Mny5IRO&i~fin8^9ݰ]߯]u٩nj*gJ(=t%ļ 21UUDSּ"VяK|y ;@D1џ)ǣmcΌTzά:ݙ.҉UzѿZMHy&[}}uTP}cBW{9Vί;ڍ٫BE 0m:z|fbz T}}hk&3Ƭ3ȸekwk4#nIfFqT 2P uzE]R0)wbHf5ĩ =QJ>2r? n\\.{Tz D.Lfq☜Va ^ ~Awj.\W7n`e!9l\\H"HZ:YBW*\[8bsM"k炕8L-RVh==$q8YتsʖU֓&rC 8/sY)'*UM[T+BbmQeP=+1d;k/5FBvz{xw`c?>6p-]kfUʩ@`]t';e1=ˍXor4xe#ɿ? J6$;?#45RLx̉d7J0/Ӊ{Ivc}":J6hTi\JT'լ1PވnGVh806ϔZc=// wykKc\]/rˍ'D0qbSn$N{#ͻiEa0OK;&=;'}fDB}g|jhTn8=XS Úֻآ8& @[7?QD#1`O ⻥PDB 36֔/J$[9DXp]Uy_N)wTN:AW.8,'HJ\=o'']*]DK`N<>,D> %[R>zB4YCs-ϔ {"oFI,aM'"Nj kJ땔C{ q;#}/0C@iq#jM #81CΩ3( (,RFJSK&Q cgSҡ߳Lq *vT|DrS¡t\PӰVlPAb88Я}NY:齎I(( #' eP\DbD#* 95W5lmݷ0_q}D8ӽi\@-㭇]<=Q|C9,;(e $$k<~n9beZOaIoy1T:^>y, k L:j4k9F%_my GzƩJIGܲ|(MUtj8? '%Zr~QVG LY[1 7cuU9>y!vXZsvG^t_9|{ p?g,J&D~1Z*bNM]= }λl||a&LLSװGEiadg%ƝX dlGNcJ&P 駹kN)Y 6G!z_fI'M\Q -1Zʫk` XZ?\/F'h-,rOG GTpUBqJ5*I`.LH^T 303<{Qs]w!8Ѡn(S !xFHbdW'')zƝ*zngW L>qQ1cyieJE UƖZ'B*,R7D9&.wHN=Jz]@wBF v;+붶j䆬__n,Y6hwm|eC\zg>8Vhξx9rei\*H~ӐX~gJec$ X, c9lAKe2`vEװhG2.WzCqńhrMUhjMq #/@ِIlgH(MDKje3_d"q,TB.R|3"l%WDžE u"dkL1Qщ ͭ_+h z'L}|_u}!$G)#y `@Qn.5u /][ Kg2=̐b YDhZ#HS%g#i,i1f@'˜d]RU(xΚAy߇*?TKs~>bz(:[Jc%#V=pZ-295@4HP1v3\h2@uGQ&}l?yvme ɓ{ [۫>|z:ub 2\n-Er#ddQN঩1Т| $=+'NW2- 9^ YX2Rpقy;VSS[ `Lxv;kbbHI'$}_di>2r4r>6"gx02✺pBYͯ ZD55(hb,XӑcnXgCD 0~3A[n/]L[uOS_P&p0A\* -*<=x2EZcY.IĤ8-F'!! Ӑ۲;.mc>.6~Nm0Pj1h۰6jI߄"e1 [&ka"!X$&|BA+\@X 0<l, jz>ۘO{بtɁŊ =o>APcP8FG ?p+ٔPSs5  _ZCm~IS.W،XO eH$44{ ۫W߼ث`tю΁<.<n3X0Y߉A:f4\fI2l M@$ՂX3Xma=#[Ǖ #`9 Kip톶q`[\HnMP#3Ocsad_`a:hJ;XWKWpE2zAm-mL$4SMF~ u]LN tte%"~HIE5Lȁ^nG`<3-&e!b$6Le] iN뻪/J'th=LjSXo#CoPY}}iA\;OQOOW1ոQR7"4ƚ|Ҧ%rBl Ѵq*KWn,Jd8;ɺ,MY,'mΧf||rxU_-Fjl*&i:k.'κ3swŤ駘)ԲduǢƼu1"ks-QYa϶qNܫ_5mx wPi%>IT~G,]`9^u_z #tN+HEUiǡt' ~g'h(`]>S 4b?ǐ\(T/kgK7Rpi^b$`Okc$}| 즱(DɞDnZf8s D*F@-|gpeV9[9JQtf-򼼟DkP:u-A>vE%R6RVzF%jYo>hu&DhOJԞ4OpS{"q[B.Z/]iccVgdIrh,gG 64gaIie;  7q+p%."<6QR1@"F˰Uņ9Z!!cMGu8.ij.q^'Kev,lJfR2Hl66 z6AjCeJJhL^iȄ?0bmIƥE7v,X\TC{t0B$@Y֣OA'EHM2DSR\ȫ]']I1Hf`܃ =Ñ$nql0 }=YlN[vA+:gv~**!M@m~'au&LIʋJ)25.{άMUOU\{qqu{׿ŕ!&}QZ; &bK!q5Ee-:U3t2 I",B6™e.܃@_/wxEy܁I<]$lQCq9cfȚjp̈EXz1B"Pqb3ZbxmM}MuXڭ㜳Lh"ijv̪~c%Ft~W.2c4Rܠdl u}J.ZuVV*x=׿+7{s/**ÇE7˄0=|M1 zՕEloas=/xp:,]?GҧmOM:fH l͟Pk g'%D2VVCDaDk512z4%2$":dI>@BD'Fރ >pRc$oz٣.TPNTLؗ+6' i']WћP鼒nf zx0ـVp_(Qjq\l>n޼9B54d\g"<ǿwp8}8ƃg/D\OkyJC7zH;fI=(9 @?r.^K$T~ş>zx)Yod*٤u~ZPƃ*8mew \K4 =cg;mXb=K!55Ӧe7Qa@Iču4T)jK%qsACVW21l-6%7DZ>yK7% =Z:/^;D9΋-P>RP3b7dY6cG ʈ>q5Rwjmvdqʋt[mJl1H燓㠟`P8-6,h(mZ#1*?6mEBԙ _%⸑ea xwC;P`DHrD{3Nw`buc,.~Ɠ!ÁVJt![e,G9H~çm]],ww.f(Mv̈iRcr\p1F.ߝ1 (VӸ|; H9-M󬚛ok*߈0w%ξ7j>bC GI P!e( ZZE\Sv701s֞<ߡGǵ` vPFΘ:^0_?-t%§3{˕xx]r?J6ysi殖0,(WkR9 F<RScǓ<(:{PI1Lģ,Y:x >+$ j^27 Hl!N*Ouu!vxw<?ӹ.|bq_95F=U4VӁS(h)-Em;~yC]}%v#Pw]6NYWm# <2uXrLP7)ꦬg'jk;S7AK]st 1T gŻ 1 Grߙ'0R$qd[+K>B`q)&vIJ8@;wqs}<#<+-B`st{۲o ϣ Xm;F#-EnlfuKơ)~p9ŀt`)%Ɔ~Yv FZdX^ZÆ4oiٔL2o)FCp<1,[u+AcFd}PÌԡS0G!.JKx/APd,j]䙰c˵Kq&~nta?|-K/"H]\QCw$j43HykϜ.ӯ2LA{^Ėls:_t1ؒ^N m.Ro ːt|  =skt El`F"CƳZ1pƞ Diy.2 ^T' o니rZ1.z\%3ޏpnkm|J nЙŵti.c,Yf\8ʕ5qӹ$thݧIGٵ>["RL9qWDތd WI ht+XtYRlt1+"tŎeTO_ӗH|,w|DQjgPտFSR_'T_[K]-ሸnikwNjfeop|?F!leBXM6fK}UhƒyP{1Ylj(wVȿVxtV\* B%Z#ч1K&i&Z{36Fߝ.XQhߏB8#4I/}0"̼YFȬ~[mI64o/ӭ~zm/]eQ? u*a8*K!nocRξJavE?'ov7ceL8oGʠ o^!NW-ca#e:qШ|y\4}0 3iP% RCdqCk,؇lhrY/ rmqCZ_g4ɧ;/oVڍ LaW,[e* HcF_v⎮_GMq`fviRw^\D[RZUxZg6s,LCzUTp C7FVcdk&ޮđBiVY7yq9"1 I?&s0T.̘"NNVgqރbadjv]?ǸyOpQK (W(7i,GPu4{3OyMiKǞS_fLۅcHA6F%-kSγ?65t6K%#YߊFbspS8]6+dU᫋K37.dAPOrc"H, Szz%emD0%'nͪ*ܹ'xmrbst.{\j2.;wqIϑe)E᫨ f⤺13bIE;V{=5B\ D()`Uԥ͠Ygq@ '!~b -#`#2FLDhCS3¨sQ CBn%Txe1=exQsFv9rϽriSt5~w qS.;yH4jiHrCluRfg(̻Řrd|'QU4QDKs6Y< Y{ZAX0Y)Le3$|(]0M5^\0h?ÉZDSeo8* T!]5aE1Mfy޲{]xY9.r X]lc}yoˤf[C&R7*~Y?\KhlvxOз5[JRb`;GJSKԞ'(8k/foyEd[eOw)}̖gWm9XLA":>Yܩ$ +5phbccHҬ޳ s#8tȂxE* *gߟkݞŋxvM>)B..j 5,v|Vˑ-NcVI{CLyA[ySW;grFJM{r} &ęX"gR0.w^U&y6F;y%H3a/D.SL:{2 Ӑ侒G$Fi,URҏI-੣|ڼ)42BñonvpRza 7sTiBND~ZyݚVy3yFОeI]6e؇Yt|Ə1 Wyq[,,KE_^<ߕ=$3#Ԩ3%&&+%"9R-Lݬ۵mPI}c\1LØσ3ɉqg9Dz6CGu2> i"RBZ>\Ѐw>d@ٙ~0ft iǍ'dk޻c^O2,kkup,{BnU㱵t4 ],-Q vO-ȅdϱ+˄ L LJ*ڜas& % z!R~_Bt~ڱ&&D&Zѯ">"AH*}e+S04 b.[:{'l dH7MYк2btYD5 !`602q[ k{]clY@5U$X\CVgZXOL(dVaeH6\MC?M&Y[Mb}VҘ_7'9q}|58[X]D@>4Ω*K9D:+q>E)Ȑr 3'$hfˡ`~g9 LbN/e+n%w&IM#RYZ&Hf*GPܱ#5spg(m\Zqnf5 Ƹ" i H/ޏ%lSvSiF:|B3w,+df!.^"_q_j&YxrE7GIJ*%<[$ j_6-S&,kݡ {K[{dH>9|*S+upyXFNB@̵Iz 4"#oK_2oU}Y2sĥ+|XPջP}/@AzO@g,)h]L닎A\"9VKyH" Y)E1$<ȯ眉qJQI4tA9/rVK|ʈt(C'ia =sE2>\>^06,&r2Òͫ9kUi,Jʵ_FdTcƪg;ҟ',3 Z = J땉 5ĩċԶ{_-U$.V%Vo}<ɛ>EJLVGpāZeFZ]%e&- 9L w2EJgڽ5BCaI:RBq!JY-ώyw Ɂ"<(.#a5vNKF*c]8H|?Ԑ[m9?+65M$m${6sZHEJC]j zdCņ gi1w5dN?B!|._5sc],Be%H&p=ZJn7 1p]wbf@7sE@~Ui?6F8w{CX<>D\hޤdK4/Fx rYZ)tNbQ--l'1_v`OKKEͱe>f()˨L[`AE2:}>{خTW2̦]Yb2}}5'Zz:j?1?g"{1󦸈 T,68Կ̺G) ;>{= 8 "'%,x( Fy+߽a:e}IQVtkļuAs,"/ D(Ϳ*h"NJAJիw~P?11U|6CɲIr5p7g[tB g1\5F"C!6244 ԇ3Fh1|ErDؒҡ-gR 42Ai4M#42lAeI7%mYEaM2T['Rab (Ar0ܩfs2K2v99]O2L Lm*_tƜT쥤ٌ/. GH,T'\tc+>F\"jh"%*4ZJDm+t3 ɅTג"$/J5uY4 H)l2kENac5DHkj:0c{$2s)@w?>BByؓ,Ѵu;oa]VЯqSȏba&.7DoWFKjUbNF=iT%<+ "mU4sV蓏{Zr5%i ZmaXL -`@tXcoIfe~4"F:x23KůK2 ve6ЖN,|(O,*jL.v,,V)^__ z:keHXЮ|(@N>;>%7|gan1*v* :ю*N߷t(|$;"O-~Av/ _BJ~?vIVoI%tG]kaVss2G1j ޤjS}/P_]{ӥboKdî.6~NВhZ8}ף SZOtNPJ4d0&̅AY)+M8ȮHu|nɿ,MIvڮh1 D=M Uyp}rЫX۸Hl> xYFe!ϭatt@7)-#X͝}fsNpjo % :-ɱ}SoF)>52!tyrs6cfDnT6уlf}tayl& BKHZ-Qn'Y{} թ Qop?)@[06ˊy ^V{ 4*XՀ@uLWyHXIRybrZfrJUԚV#NZ&'ϚMBOIGQs#H/(NM6BFV3Lp1kdPtDPYM:Цcnc2LƧqAjj}Owh.hým=-4О C LʊwVq,fʜU$s ,Vb.q̕Ʊg/Tr ,}"&H*$9XH)al({!.%}en9lE4NŜO?ēv9-^#Fuf F;i }%Q3bA ̮+ȮO,yAQN?.-mcvo|30aEΨ c _⧺{Ȧekh>0GFL 9V5ԣxcAȰ=~>iÄ6Ɏt OŁڨ-STKR`Fʽ't;$'cYո 9 &Gp#HsʶCa?Q}Iʼn2=GkAp1dp\QD OoD){V'(N69VȈ.;v%8:ͥ2߼#Q봋 ?zC 0UqnKzqO[KFO.`o\ݧ7D VVϣA.M\v,rgx.ecZurt7FsVdtF~f&+6FҨk"w.4W+ݴx]G# 8 3(i1"6i-Q5beƈ]RT,2YmrjgYRWOhP#y7:gY2ox1AΚɍ\!v>ʈgKp?BPӳgh aȽ7n*rwC xJXL"MT-:XRZ_Hhh}V!/|;4T"eڵS׹ I!-AT~֚?D{O.}riH!M;^2H׊*Y%k҅X[?/¿o-ܿEl7^r^< ;{x?8"#Ras䮱}]\ՔR4m.-T!; Ԫb7eDF8 !u* 4BVFa no"CY$_:]rAը;%zd XA"/x*T> :Jjlk͒ąbe-I78A9eSl3)Io1/"`HϱtEQr< Je6y#T yU,hlupfᄫ7_9o'/!p{y:#0thxoѥt锫кT֘DC,JQr0N+q3gfHIJx:ʕNݧ YW. E1c&ʘȵ>"^DJ0^? vj9 -.Ң yb0Q5h`mۘk`~#Z+dw< S2Iے z49-Gm4ćn5eVY&"@ʅߴY"=U56#Y(d9m_-ѧ!R2zu"/9n&lC&=ߏA/ߺ0Sgg H#BIAYc0\1Lz1l67^W@%^\C: O C8$%{xDiN!ma"B̝V[wVZޑĮ}BN[x].hxv?} *d%q8.h=L8eB4q E"0“9g N?t%#v1$i58XOX@־ w4WV&*lx[RZ)ABQͬz9lm?Bs01JQk7P^ċG)?Eƕ[K!d9Q1$ױ*NM}qf އ7HcTDM"eTnx[ٮacc =@ߓ''bh>d]^X!p!z̐],8K(X"QF$!UQt&ؚy,d"F0;~ee4Њ k\g3YLcAif"F,tɠV}Ik_m%xyGT{= !no'j-1!=K CH:p76"*Ɵ 6jokUܺu RH)Ac32͸*1(KK`*~1?K; )>8ޒዀ{BX|2+Gc2P&T(5@SΙ3Ή׮u6T4|3'*HhxV%43$i>y|#Ob(8KXwU닁lFkXq,if -+?vVx)߆*PKϞakXkO~]ܽ{*'Yz]z}GOp._z&ka;?BXa1^KCZC|q{zk69 Gzz)%r1ꍱ(GQD#(!/z8~$B'3X›ǃtiEE'y\xmQUnaOs7Q`ŇDN1{Hx &NǴ+dPtR-vE%p Ϟ=!:9l&x+5qhqՎPe<MLҺSc-*S?a-2jD85[*i YgΖQ&y}VdI g( KdD?n# n VzkNxZ٣n#wlR 'ZگnT:M}Tt=(?&pƪk(OȪXNkCAμ|6MOQÃ=HmjLtvse5 T$#))!V7p<2jdl".Sܸv[cWy̡1sTX/$1(.y=B}*dKMՐO<Z*6P5p$[+TONٟTp< KhN6(dǒKVUדdKvŮ]ʲ_<ۢ%,!ڋ1Z6Z\Ѩ^B,!.p?>^V&PY$ʄ*Fׯ ocܸv_x hU{ ډ\Z}?$Q\1! )ۑ k uM94re Sm4$s[ӄvű%zkB|h'o"]e}HR>FRx!y_1qIR03laN)qcgO<^{ޟ;cY;ow%S'd'1{4ke67XY>/~ xkWH{ri_~*>usі5\rI;zl +58k166Jij{},3C`5BiG:*,1iSYP#9MMWV+N9ωhmզ bZUjphJNٶʸ c882lq{$?(ڙoMe"ɤwtWj<>A\f6&Nn5(K{ETKuo}xzWh}<{6%pJSn%S%tlܴ J'meb .21ֱZDp>;q]x}ȟAl85J ɷu>fX=gä ^MlBJC7l Im%{m0:N3jRC$"X%Dґe hsuGo,n][XZ`)梱0yFeg!s╈CF,G:7rw&fmMH0|H=7\i#ީT7Ph7ȴ)J:d:88ĆuCNO92n"v;4m{2%?DصR3B?dF"WC(T % :]!h!:VU;!jhéԣ#}ojMк?#_ߤ Th.9|>ywf6 N[dc7&82fhUX?Va _;5.F|r^`9X+©iro53[gյLգde7GA|D'',ֳM ]H8s0O-j>H9ğ`7#>ldU,\Ÿqk_z |C>dp$]_e;CR՘ Sq +-xDr,, R )HOa72 lT|L'zTXMcL^1iH,ߠ5v儢E,V0$KxVLۧ6IO.YQi h(A-IӴ&$2ǒhkr h Mڠ!UF@A\Rknœ,Ź%+H~ۏo<WrF/9|,ď1]h 8vZ齘A"5=4`ҊVnĎe ]ĉ&.8 ZcZ &A[ܱi #I Z׿Λ'rQU>uT*_O+^jH7|!圛IxZA8aڔ iZABF31ݓ 7v>@tx7Wh^9,qGDV)rHƽ\-+љ8!sPC&W䚚V[ C{wVk-b"&rFNŠB/Ό,ۦdr66л*z) xUzoS[(k>E~J.'{WTLK`LJݜ9\F^6Ӯyast<svܶD2Pf"l(L0H'FM\46ܔPQ%%R/ V禡[d.D>FPؽ6 Ld*&smԛ-)GbumE1Ɗ~6&?BdBsgU)EF4K5_M~- 4iB$I݈nۀ|ԚB97D76zcaYV? V1"PUb AH&[(tvqv'h> {u$ɏj\yvptD܊d -~O,d-}tq/YS$(d0x;n68+*s*5^h,'0 ,;!v *zx]MUDֵ!?N"a*fN +}|m*fȓ&/P%' `R~&M,0 }}CBD|Я,!{R:A%Kk* r+ؼ@+8D j vs\0LNם_H3T;oj׿COjD<6l@IZDUj/e?dSZG!IK4&˲1H<IL* UI4Z*OJ6E+3)X4QJn>h5/SW̳CK>ʢc՝bE1B9溿Ar]i ا8b?>@{6e|A\Y\A1w1XC^5@~42[y 6t r*LTKj:]iTD v ]:l9X{oŰՀ1~I}7jR-/%7fnrI71s u]+,nSkߔU`IvrfךWED+P#?/Vq.y^Q)6\ӵ1J(Wx1_`&)rئ EMۄdgE9q]b.^K $ě uk.xҍÓăPHs!'iRg릇TJT }"pO CAʨ}A{5*7`W^oR^efu;T uC[N2tl:.rEtB/U11'CfMkrXQ Q\|Uj&̳ IM2*.s%2#qY3PL~Դ~`SFu$,,1ʜ*S8L%'˶ (ɽU:pfgqjd)w<#O8ʇ7|lvc+$\s .Xn^/BYE,isŸa)~ 5EĔ Ykؒ$]AFQj$;Ixp8PQ,Jz |eBg(y;˦3'Iзn#^i(f8]#y}uwR^Vǜ;%~FGprx~~vxnoP/G1*"RĔ Cfz  ΔC@!~S$Z3ss.^w2n.Y6dE֒B-bZY2Ls]to1a[oP#@H$s&} L l+([s*1for'/0/)SDU7.J~YtݿUڕ a&{c^pBA4[=*d:qLV*R'㳋"n2PlUTGh2=c>{3,&ѠVG yȢ)1RZm;,uUt1q\N9-N:%Y^Z2j)ssDݴ<|8. -tZ=V>{WnE&&r7_ ]DI=f74 A.0?O6pfG79ccκ23 jMX>@ª=3jWvYhl2hDԫWGB5a*75:XNL#d'd%@7⌖ 2$ vqnr6'«0~1#|Vnm霆t.p\5j%ˬ6T9YWD% A?VuqͿULoJǚ&7u^l5O!>vp"iWod^EjSV/DhOC~`ֱ+Y6hg:-BΛ+{G4 2$& {:TVAr tΫC2+5oު@5~!]YF"K+q3^.:e.]@K;V2bN%w\uID7QT5 w+ԅ.$՝=+rGY\J)ZR@5*kx\vjrOXՠvhMyS2SO-! L+Ww\A>pF\V/d:"Fl!R+UukY壙ڂsU57Pil)u:jVxlj P[PIS0?S|$VHzA6ܕ޺{G2a!;Klw@T`FWm҇f $ٓ%βz~wVcxYzlFdjrhH!wn)@_O&ZĺHlAKeH[pU{ΦmtbEHFM]4*Epp2< 1&а/j6fy&:"5OFSq0\REҰ|Q #N8*tF4" r2fDLUe1fԲ`D:u5|^w/_G5ćO\^ŝ6M@)k/ؑT8GVcY 6] `ė*s 3&&}ZDLck.-ms-L}2̷-::xv*]Y,ï[ǜx\^G1Gr..%e9@!I;GFpE3kURw.}s-,xDXZ{pt08`9ODw4FF7ߐ(ĉg>DŽ Wh~ p*a9L񁊁tzඟ,A"?tĘόAGd""moj55ei*<(P5oOV"l{Zj'Xoka.Yѓ΁5_,O[շ0@qybtBT$1U[tz:NV 2#_+Tb@[a4v6vqt<Ǖ8~F?ۘX-inE5t[]fd؎ qYlA]daHMX:ٸ51Du N]~ ?lT>W 2t%%&E0.C%.yjnrO6&Ɉ^fBǪLn%Z[晬E#c,:c&uκV&rSŀn 3Έ% `mORq%: 3D2URx Ύ}[RD?PN{6dGO'{BΦ1Br&a3m\O8'\"cR Y]5%+#Q X1ib%+nJig<0c1!2dxA|BhK 6pMD52|X ,2 Tv}#ı2mDƂ8&-.`"eBHi}tGvMsld˪r*bNC[.q:/ C E](eݭˋRAQ"򋡊}Ѯzb~ 5572U=Ba 7k!q!1q-)y ?d~ 7q74z?zNmao=z,&DFrJo i"'HO7ݲJOb-Q5+c)?"vL^O Q!sd im"a43Y\<~1ˎYH1Vbob<mt9dV 12^ h6E;ړ; ҈"[oܡlMw@w~Nٱ.T xc۶ }}LdqDŽ6^\WHӍ"6H M]pSM jRPǻq"DE$]?`g(7\r‚p|/rgnʼn.n[@# 뚕1"[[.InGQPx&Vʬ=݃fG]3&Oӹ'GSg͹=y!{{q[4r%dL1g-^>ONˏM2$&%xqǧ88C3cNFgp6s`6`!n_?sBބVz▋8z"!F Al9S&@< ,֐ө.UoI!'I*|9>xeż&8<^yKW;qLnǏOqxu覜-Sl6=- yVM7XSLf73fLVU,% 'eDE^0e P.WŚC!]r- tFoݟjڹPW̎ek+EMfxc\^OِL(0ZX )n ġS8=|qiѵu.zrMjJRѶ+MИW8]WSZ wGӥ ZPS4\Bh0`tC"BAtvcC<iWSPr.J־›23݆/yf2aܩ)!1!%rkk:d43"`tzx9D4Lg#8:9Y)9X͡Tt k\,M\9*tp֔r*~Ax% k2Eh)K$!HRO7nǃcTrҰM'S /R\O'H9\)oQ{tv2.gt.`n%p1wQ%g,[GJ/*"r*B1ߙ,r%fXst/Q3 i.&(+Qs᪆ޛW QN-K#VQSl*TZ UǣgZݫHPu:ώ1={V.(8.ɝ>O_h8F4:h|ѓŲI_zcv \y0i1^injv)Y6Βa"DP@eRaILmVQU~W_kø݉n!R,jA[Vބ_APǯ*m`*E`s\ܦ!oEr<<`S &毫E8 Ц !Ƶ/×w`?z`į/pN?g=2(> +ay+Zʗ?'ə;w`kw xӓ$C׮]ߋU(?$FNM-_w%J0@"u\P HVXO;| 7*h%k)ltԛwq 5t9I2CC>7ܙ#AaF/e@_hj߼)] &l>zjK\-s/hrxumBHfd+qith'miJ~7:mDKJ<(ph2sIB/U c)iyi\#6)]2գ' )*7E) %5%a*ǂUr/_{E:xY:Ri1<^sdhuڎ^"J<<8Ôw7‰iy1^$ÂܰɌ[03\;uz1"nL7g w|5tpL{>޺F+mvؼw޺EO|JؽK fl4hzo?J5W/S`rNӂ)5!=maLe.J(Mx\8"@cD_K=W!] Ėx607*^ؑN)| L1){s#C߹0cY9MJ_o6=NnbLƤ&‹)޾{? %& d)#lKkbk~h{lf(e|.R(Hvg灣:QQ r+u0rbXgDziLXzBX˥:.6.g s% ?ʂjMkfeϋsqSi6wS/3#8U xvuyp-+eU+ER,q];!H4l%SUN&d'1Ll08AkZi{VkZ9R}&jD7`DIpz:N='lo, UMMrLݧ񱸈qd -z5Z{ Ը˯rS)2 Kyyuąd3(gT]2bJ`+C#ۡC(G2A2jd2M[vO*i0ӡ0nLܐgM@('sV9E#^YVï>Bڄfӗw9ku/2߶fVz&J^]N2ȡ̸`qf+$4d׹f~}e$KS_D}lPJEn]HfEpi?k_&$:MږR6) ?~ͪ…5.Ŋt>m\6| avf7Mon7:]bp n*jc@Fpc3 )Ɯ -_E U}e ˤd!-9W&d1iK{%2*|0$6OHnQnZ.3dxu6"v׸pt1f֑QQsg& i&:Ը)kxschWs@lOhx]_$h$Fk4I[8}P-K_tRzܺ]Ci*OK(DOufc(3&lrt(c\fSt21ͻFt]< Br|z:N#d9!*w3ގgC Dk`$OLx[L}UyJ+t&7L*P|CAFgƣKNlb0>ƐfEXey33$ƍ, }' Ei-KU T%F2mGCkd N>_ډI2s=x`eO \ g<^]k|6ģIhRH}5fT(}gGsٛeeܖɟj@kFĴĬE|s8=lnl`Av9[LnFa% (\L`ywvD2t yE\%ŀH07M 6YJ%#9^{*YeGv8r l-'HFLxR F99"ӂr?/$L4Z.")i0ͧѥF,/!7߹g5h!ZE5pJ5ef4lnh*h]6ָ"-2ޅ랫7KBPETГ. ߘD3vY:\"]MVA0٠okr Nh;sFY a:yn>|N'OQj"DLg_BIp=j{-.+lzN0x>ob>^`Nͭl♤Ag9q3}@v.U$h?)6ϳ;E2f5YǠ$VWVN涕p߶]s6kI rP DSyx򵥾 Q!O JW|)c$Yq'\!h. FV;$ _mp[X'4oS̏nVMg th*zi 6cU jfeoÐZ| =m6_W僧?Ix՛f­Dh_ߢ`*I%Fӄ8'C¾U{2 7"`u Ljܭ~[=YLFwn?q/kmϞpF7g<!2f9&G#sZKfp.??<#g|=ileTZ`^ȜʫiLeИ ) R2;Wʰv!6ncʪ\⾹e'Ͻx U7N1=-'_xH.b Y^p/8="r_ #e, 2\-=ij7hllc5J*{ Wժ2[oUy_UFmpY]fA/bvrCte?D\$ F; s'4P~`Ot2Nf%}wCJ$#4Mqr|Hd)wn˄ k-tZ5lthr1bZapEa<9m԰EMFm'FY=`Ak q^@3$9"/Gp=}TRK7*/bEz8cDFEWTЏQJf_@y*JJ?-Ydlũ"&UE8\Цr Ksjs7o rUӜhڕ62iS{:p;Q+xG _IO>#3QS;2i^5$evuGBe~Z.ꗹ:JU-Dق6DK{ g2'7TIq1HRb5g Xo{Fh4]dL%zt&<[7o%{Vy1[ Zr_vIKB;C ^6Nߓ v ^)Dj^TDNOq q,l&E"kᙞ2P|+Xܢkw2$aa6;sLh;1ܭiN1!ѣQY.ǢyG.WNv<>btf2!D;D_ۅ7Yb:>v"VPJNCkC?*-OSѱ_#w8ԔլU0宀2j\+F,hiY4KLjEY̜̚O;uMɼrBaL'  Xѥ{t_ov~RcmbGK,Aђ6_]K&VݺM7h~P ;װ52dƠֹZQ 3•"ev n^<unpho HSd|-*PY~/kϡI~Og1Lw_ N~pz=^,ELypԀ[7 [&ήLR7n|ܮ{6ݰtJPX; sG͵1Մg}S\WvC\4^䩑U F鲾T G9v7T:we/ŲBW^SE!q\X4?LǕΧNY&dD8Ñj km0ޗ˔Vx=M9]ddƺ^el4vtdeo+qjLUy1k7UiX+t%Rdq XMˏ"/+mp{.?m|I8%i *r:jEm"ΜU$eB-2<<_c>ɁN8&^hw鱙roZs,[k='fɳw= 4=ui_F@ SD'Ҡq }qUR >!bau}93@_U"*?9/ﱋWG)@w&P؍T _! ~8K) JcdHW‚]`7D]&cDȨ} |r1f+Է t;x)ݷ\$1k;Z ^HSBMŴ77oypeWJF] ARk?*F^54'?^`iRu<#:0u6 %+(Uk%Q4T"q 1 hn ݋dLOD L}Lh?6g%!f*̯Rj1>E!ۍs}ȏrd(yDS5~bUC@*c{Ƨ{w}K?O;s"jhns;Q 傻,0&w^ C3$/4+͜1\dt!$!-մ}0޵>H$+Y 񭞣u#1>W>ߝu}}kȔC瘎agszyχ32DG#z7!ل5RW;,p!:$ Xe e*?Lzkskt,e"p+W6;Ia4,٠%<|.],ܹ% Uϙ')e<ҢpJȆvuiIJ̊70L " ހ"=+bFr ڥ2ٮܾ$d+Q)@k.䇥AR,dn/q(xC{]0^?sD`vE0.1^zؽw{tJ/He2>i#;HsJaJT]V-h[w1\%<8"O0&6~ w#7i1;q`TGVJ,afwZr8̐,k7РgVρڦڗ{Æio)wF. &?ڟU<%T;ښ!3B/(sN ?lptju<6L%j""NXښԭr_+b0O"iZ%iU_{LbX9n4[uǸ_+@xϖgS/pUN0_⸰VGK3~M(VΑ>M@-(H ,/|XW)q,~eeVN7LzkLXH,MR z8gdƭ J繖1^OjNjMӔ 5vn21a(.\X"#pB=2D+a}% pa+oIs9&ܧ.7~ xg!`HZZ/EG&eNp=́fdDS=Q)OBM&=L0 vLZ̄Z/%fHu2\(خYQpJj6UE\A{\i+ewԏr,Dlc{'Iu}t+q: q5݊>Zyѩ/bZr9Xҙ?j 6[ |ucO\(W< s՘%uKo;EY8O=v_bwol9gllߣc8:\!E*0˺dvmcL릸!)e^ϴ D\oHS~-6WDwhq.>b0$%oL`r%!v3r|tnM 2XZhCk+Yj$1ө`rC-C鵔|[2.ѧn}>fGPGtR ͪ$yJpu$:LYވrDW)!+`O?/^FB7Ȟ${ՕhBI`Gçx}?cGvb{]P@[g =^sȤQֈurkxNOtO4q.M<{'/34h_5i!:vhx\@N6Dz\~-/"ֵh۔~STKU$eJp䌚4{bȳ۔:?(w!R,W9(QbT[NXv|zʩcOt\JŃi 8V8=ݨ6:6>|t}[Wo⭝{xv2'4'6p69[wv-[1ȓP$@f).(K&2XfcdqAI!$BvisQJXD,7`B_NcYKlX "T u{l/e?̭umKhhmA H\LgMht#޺'tIh:%~Zxl2G A;r+WpɖXl M: a4<T9~D*:cE45]tWMJ>5,=_=/Ɉ hBkNԚ $aKn`&x|.ٌ~&#v`xm32OɍaqNe֙4_*^7'x ݫ޾&~|4i"a-jnlDB+nNh/*h&lF! R&6xŃahp/MW^։ H^; bBLuY3ckgB'PL ~xO4S>Q5B-b#ژ-C}27{ ~ч4T>N'|{i>!@Zds j齓3UD\j%jδEv>ddwsʙ>i&& 0Hȩ!K\hQOn|H{)q+.eHfXk-9PzEJ5vh=S$ q[h}'k \rKY MDd>W2H"uN t|&k&-To6S'e"]2ߑџ3ſ5Fw}O%›i|Lշ=ɣR"rwo_ u褗/PUCs='{cFxbpd" I^lHr 1[*>[}x[xqJg!8_,1_#WƋ%O2!$L͖1TbN rwXEٮ˕K*|8Y<8wwZ8#@ByyIIf%eZlEլu3I4ёmhWQFL˄v`2N7 h<=)j8exٱ|ńR`aP'pXW啬ʚ2+ZTpS娿>%ʎtXQѓ3|6h=ɥzvzљ]~&]Au?qcYwa2"#T75&"9dS aZ -@+A\KZH!h`hf8flSgu:9ߍȨlRދͱNS U]q$Ë5HGUR2bO_6v$6 b"iEҮ# 4>:+AkĒe[Ui۫"Gt0Kgz6AO.vt lqͳw d9r2uAG @ULVydydMD $+&.! ϯ.(p锁w! ~WN֡j\q4Ϛlrӈ~O]r:'8MՈJ1u=DֵMɨA7_)>>NGhw" }=G@/0p5P4B0gkFHÓ'6mestpS{]Z6`1|B'>[!5y!AFR4+JBa1K(څ7-)dz Y_bGǨ8dy!RU,p214ܞ MgG2FRl |6auRXẀFlAf~-MךcZQ oݤv혞<~&lik[µ93{úlvKL|EBQLAfّшI3Vyà j{hNH>I-!n^oPwg Ie=I1[JuX%_+阦6ڽEį4+'_eBie^_%RQ+Ro 0%J02C/괽@)J@9ASR3.h\I6 c4ೈ>oأ+:)ༀQ="~j4'ttׯW=Md7PUѢ•Iz> D{:R\`kΥ_bU\1}GA~d٩:}Ъ;S[ӻW?c 4ku-MHPrr0-hB|ͨ[jXCvB+L%P,)ZuXr1h+a)u>:& ɸ*.:!_͵{M;*<4YR  K3vMU6Im-氺YxS)M\jUii:O&]'z]z%mt+E|x#tcHDEHkKځ/d~ȋ OPHB oݻ',T O"@ݒd@N;  ޟfRT5Oxfk= Ojɣv!jyK@6"Gk@Fd0=[ asff,G4g4Ȗd!^Kke1 e obXKXB.D{I6ˋڼN+$rSh"Wfig[T3k ~?'Y& ⻚ZkPWEvsمc1_ϰ IӔvoλMz7]MG 8ծLAjU}萶CڮZtJO3nGݿXY7Uڼ֡Z]f94McAR#7bd< w[1d!ba* $` ;[;BOMTRQɒ-V2zmS]k)pB+ʻouL$+a݌/(W^X 7l%X+fs5Ha  3=|UzgT_[*שb S X OS*GtH]hG|)wߠV(qHhkE3 عKO} جvׄn:I*[5)!ڜ]ǩ~_Fכ>=bA-!MNFs6{l=vmzr2*nVFSzu&Gy-*|,kfa Bb]]`^46%HzT仅5kb脅aw!1KENE܍6h*|㡺:!}vO1[*hq8C$Cں^ߺ&ΐzS|`VXJ# 2ĪM:UolМo8! ^WVvwX ܤ7=yǖqgs}6 5 " 5n5U-1[?FHHK,Tۂ ;E_@i2ca6 c f7x^ɉ+C,Wblo$ @\*XR\R$LrΥ$+ !ȴhn5oPV!5m]" v7]+?O[QjR 㱫zN mJF`,iz ,t%%63[bD/w7dal1eˊ^AAT~wkvVh->/T ۆ)U*L !݉:&0$T>b |ؒd:TFlh*jVפN,ńB 3^TEtڠcv?D,C=:8Ƃ x3 >gCztx$| uiA/O [O9(0RBJ?e+.M^ʊJZ<{Brpy,xUZP]\K-e(<')KBcɼ[$ C#])r!pe(=}rBA/&b;![llUcbR .Ӊt lWLTg;:LD f<0[MYd@/ṣ\koP'B91o6.+PwVTt/m&ts5Ϩ >ƛ,>G?KkkOQ |6'),h7BU <4U$I1$ݫnfo<$}(ci`13'%Bb,xQUQ+5Iўu@5p N9o6?E*+Zt#IK<`|>C}ѫoo~w~oN Ϥw0Hdy=˯hp|*cevX[oJUZORj* h(=4%.(fR(?bt7. jkm*1NٌSGt؟7)l\$g%cѽMN)>96ؒ6, 6M<,[=zzDɐoBk]x|Oٺ;+J?P: !~Ʒϖ9x ڒz$ K_XRT`z  sĀK*m }s 㬲zF [: bqق׬5}Ěa@dRX6Xf#ҥ7Yiw $>c~xǃ1Swh&~@)TbB+R}0Xju=a`IGwLH{Ѥl AF l5`"v#:5OLV#Ds&(l$ (g7_-H͐v6m=yʛpҍgt݈kxD?]ں=;ySIRÝTNVi:ѐ˲ÛqΛ u $ j eKmkqFwا Իb⑶Ey=kd2vfSnF c!Xmy}S4,+{0OҒO- řXp%5~2YG7"$3ROů'9dlɨf4uphe+cCHN$^/")x,Vja hvrJzoL/uJm:S"'fkEQh.`W+܈"bw>1=r5 9i۔tFc-77i]//T )Af'3W cF m#'41S}.ۑuOR~)?4c / ˇS"eK mݳ&#)zSiʩ0(=Ěpd4~Bu9/ "3$Wqdwl8BVʒ%zk~%d&^G*Y|L&G6AoWcLw/儮jUԮd͕֤HZiZn[X5.X-%mx4(%$`~D!̋v4HJ> |{%(a$[_=Qocz:n iĥң>|(Z[ܜ Njа _A^HKј7HJ<BzxijvzU7B8cW.˄Ņ_WNi@c]Dp&}}, "uKR w! )-STk>iN gelAY#f?%n\P |An蜸R Nhhd?MlM$-1Bi< XH̰uRJmRPcB**E VZrO(ą"YƟ["F @z35;Y "zKk\2E<^q (1Qt= ĵUq_w~#_x!T|3iA{w( Vi4I`\PlXMP2s)%E.F;!}kR1,JXu^NO!اv3͈nv5j=dpyZXA:S sSxAo[,n4#6N৑S=~ԑV *6z)Z :X#.ggb]"* yo~4 U!u͹&Z] W +:/䧆6Kp5_&ݹuS@Xlf҂XONX) %ݺ h4JEXCWhZ?yy3l(8S &ԊXFL ukK8aG"(=,LO4 7gB)\(U Blz6f7yIJli Y x;w1G YV v zK_b-V14cԥ2W}x01É!`g"nn/E!l:^! Ƃ7 WH!` +#SAkPڙ=u]a{|CB7%R^F v!_h{S+碁jc k--fLt )mx9|&M<Cz*u;ӟǂ)$DoK@pA:ROD1-&FFܡO?ڧ'XNH7 \H >K NuP=B0%*E6]{u q_h$H/ Y6=#Ck8V-<忋APk0ށ B=kfǣow;㓏P&uhly)Gf(~3jPӢ/?JT7_}7铟~L?яٲmv_g4>ɼB$e5n\̩^J]ۿKx<",w9Brf:&[df/@;x\g& F^"`9*X JE-lwx9GC󘟫֋`7O~GxyBE9-|ILfH,r3ufH BqaP+bg4>bM77Yc@k y7XItGB,5.^rŇЅ> = %NeH@Q ^Vj_|wë+w6u*,-Vgk0m5b63ÒcYDɡ٠j VgǴ( eoy~f6)GtcPkե]n+ZPq*;Mkje#2u3S36 5I,HŽF\IdvJvJܺ+nq u"RWˈx(}B5i }B}Z[o\ x\χ#^AD^ RKXq 5Z(WnhnW AQ 3zG?&IWuuιXb'w alEx}\eT ;ë\ #rV|:M.||&H~`h\W,XnZ$PZn_l`acwDv*,u j⟻) X$ rA\&/ s>_JR-JZKP6Sc!IPx0냉5H6bMXq>_c4Il< i4ky ^ hc=Hoݗt{kǚ_ceRe&؜ &Y%( <@73Kfk =}v+C(&`(=A-Bc r0lA+TdZ>+ybIόߣӓc ;Cw]*oW Xҝ :.Z$G5;/nDcҦ1 눚[_וjFD)9@OXyl%գ:SH+6\H?srTIيufbH˂4Ȋk!3rk9FwEW9Ec/C"׈xpH kü% *esxْWCUXኤp=ReNJ6ǑBMx"=I汈U ,$Tڋm6>aK&(d,rzBuAd,\l}Mք@!`ݰY4aH耆nl0[(Bwu]2 gx}}y HJP ɓGMV:l)ܨ?lQek ={MV ;?1 f,̖=/|u K,h_oZouPaPJ},49dH I$2#Ơ^q w>]f- #Y/{A @Y0rr[:Ua"BrjkEݣ[M.N.<2gg;2jxk$OV>S-'wp5ڱƳ%cF[Kt ak=JFJ2qqL~<.L;9ڸ=VP!d`Ϛik6iޟ R{C:UHeIHtRS%t,ǩ6_.Wx9SwcI7u?xDo\1cաƴA UA˭O_cy:frϟ{OfUFCW}?͵ _^o%הꀎNcW"ڝuh;L$%k[>U͎)Qk#=?&Hwpphm~ژ`F!RBx nǹzU$̣ ,Z ĕh;MmMWau4y('& OGn͇ϥ94O; &Sk'zƄyLpH>Ȏx;Q>Zn` &?f*T73 #AQޣh drF^YL'2H5Pf,b !&㔾޿C?IyN*MpWY2ei d) wxOPRG[k)'`+.b[,]Ui)>x\b?ba*Fca,v(`ȏt .6'Pp@TR+4(%'e0#XCƖ'@fqoD3uL _А/,"e7>NQz-]^c:䱕AʗSK`z!y,ʫR趐HLܖˉh}a۹-?a:TX>ߣ;R/YpF!όCoK?pJǧ'J͂ VH"F--b>lAciL9򕋡冋, ΀W*TR^!$W9AB2׋ztW6phtggHjLGܳa4W*j(gP{5; Z7Ylb_7ݥM֮c8[Ra+)EscQE H@m  ZJ(\~0ϴ:%+gd{J"Q;ų+}S`E>"R~<ؤ|mVbuXK:uRB32#ExLK㤘Drv%ӯH[4F|4H vcڌ䌿bHf3Kae|8C:͆T-RMg,(G鈽Mj l*u/n \v=_eL x-[XiDtp| & ݺyCƽ^M1{"I:{k1oU?1~nz.T֘_eaP/H9O<۬=Q4j>,% f oP YRO?I_P?W v K'j,RO ,LPE)U*qEpA/{J#iң#z] -yBٌ-I|j餿Oń'*:'cO9V^dm^|É%s ~ġϳވ&éQ% cAz~ݸqCJPa(3UR $ZuuNy9Wd+7J-Iv; V yR1URm˕%,G+u+SGժ^$1%Ce7LH5.M՟~Jc҉C3X/M}գoxVk K/Kw 3)FlKnuH逭˄-#v+ƯGR]}OweOgFoY'!)I81GKus6@˯MOŪ>Dibswӽ#,s}넀VDy]9TȇGծ?8f}RɴzɌ槁(mV4ҋi__Q5O|8 vyq,VR1/tLGX䱢t>օD%"SPn~Q'O6PFy_^X/P!}:P=zDs: *j%'{hn)p&q `NYmeW^$cN#tڮąz[]`7٥tVE'hºgMUȧ/ })deK`Fgj4aڵlOgbyƍͻA, =}:cKoC-[sDϿc<7|~}/=!};~WOO[77;a[  wа-9+dIyk {Nٶ, +XyUqmhE+%+Q{=w>K~u y A= 1 @4vT]0/܃GN.tyv*Y tw4vzkRCA[[TUi9x, BY1jf( Ii*,G;Qx֎hmIV@+WX8{4ۛ(Bߣ L>ɾrҐ޽Oڧn)',Tnhӡck u-_{ GɒnT&L:x CT Gb4,E|h]8y[lbе-k$BsVϰV,QUDV+ trJ-T%GY-+\(+e4JE2ny˓.+aɨt!/֌>q/n>Z|F,4voE'{ ȁ43l)bWU0lzq٦έ[#-‹"h7&T 7(04߰CH)΋_E[/19fKhvk{SQUQf̠ΗcLU6p+75$07B1nH\c=uÇhw&⧴&:I2I 1[eV\JuߘzeR&Q2JVԱ japiɯ !ݝu ѥkl6) 4_;ae5lOiПQ%dq6eߗb;\~)F!ܞwt(^hcn0`NȪZ\)uY-KxxCD fLBr5a0< ,?4]Z!d @($RԄ\UϾxmN!8^s&E +W I+o*,3qH>7/*JE@,98-<6io ugwOZxD0 )z{Y=`!6[lСřOk;tMý{|#^fk/d9U]:K͓^+wڴ֒3 /):t6{>5{x:]\D`PF< B?gE9)[8KAg^挅B=CLp(m]X<7mKdM _~ 9uX攡0S+ށQal36|(WBQCpUC #>B|py'R%-=5d5^:|p56Oy;SyC׾?jȓ~727eswAɧYΛ,~3z奐?n -jTI@mRsWRٺN4_BBˑɠ/ !)o?ҘY6%XX0A,;KW1]HTJǴū}S2U"5ԬvOMRUkµzTMpMVɬpHM۴D@72SLv/bL-2YI[JimmN,rNUh::)'T(HsVjQ_; k]k5x-?Ö-Y#ݦѰ—f(_PJf)RGJj[$ +X`'/c3XWI鍔;3/U8B7W&3˲dJ7w-lFϐ*t7G]} mw~#0`d ! ^` ΅*o4Tt o8=Pg)!NI)LuGg-wߤGsl4&|5n#l//CFN tJo:ټCoic H ՝&Eպď)t%ޢu 5] -z;Ѣ{ݻ#vXjƢl|{j9B#я\d G#7o&Oe&ڗ/SyեnJ>J,,!=vg> %!SRM`i !Dl%S|n yNdb!e)X ?|7\1U@5W l#4)% =~ҧk"-3 ǮOi/oR'dx:K]7|Mhܣ')ml}^ [ai8MSb'vmoR&8hxɭ$(Xte/ Uwp,#UgJ%8r- )5ѳs 9k,@PDwz{R#TzE^f 9{: ǁqȜ5%Z\4lUC~MuIRDT~*c󏫬T:(>[XwVjބ%)t|n$,ҡuh&G{X)4)NX84;҉+^ Mg݂]_䩴rV.?eXD)KQ*e&#{7%ףbZQ/Yujܛ*Ȍ/ϋ0=W20X9b#QBJQ%ŭNA!=x7{&ؔtɱDzJC6R1"d2^]F3`1oLryFIQ ACϥCh0wka*S(9u1 /Njr+V&^nOe#@u)Τe6qkfL4ap0me+B9fYpv/93x ZJ-/eD#2>'R.v̓Cme{U,`^tMVodVNTҸ9v/IϕNkW>~ gE$"-(?A5B!) JB[m~*UOLFPJ݈ )mo`4[YMmG{p`xB*5Zyn`xD+(LpaǺ BLfD缡d4) á$DJt>3$`F`{}Uʛ.(UI!r- pc6^!hQ~aDwdx.ۄ5jm7bc/D!IۆEd*V2ggD< -i~xlyi Bh=YMܸ޲cݨ%^m |Q iVf#ԸŎK-$SD"_r2)trBr!XN#X9xKTq yhˁIBeJ!^.eJaQZԙN,rO_,aB)JCKiġPl 5/ǚ :S]:yfTHf]8׋l9?Q F#F(޷)@*\]fk.z~:%' a_Z;0+Lt7!ֈƦ6B8u6P+d vNe\>@Fl[; ڕ-Ь*l[_ꌬ>bEx&])rH90 Z$ťf %qh ձ҇z)L( q#NW mu\&ޡC;dpi$OҦ֒9bZt3 ϒ|@$yyZ3)E %фI6P[`҄*b3/s$xidf ⎕Hk8Z KV1%ge‘aK@nuaJR˙m;yh,/˭զB{_ 2ڲZ,ܪ[h~#0qev-.Yz#7I{\U tw(eGK9i)YT[15aY֠q?J>\XHe_2R:kz1f?-I!m0I kRM."3/2>h t~2\b*g5M5ݚP0w' ާBB)ofV#"'2Hc'T0d%Z王VP^Vt@r}ОRȤ|'qgeZ+!.{pTrKφ  (]cQ5hxdVfXLCy]uRc3udѽ'\N3_Bv]f~@  2͎aӅ.h>g!ЀE7Qz T!9o<_ulvl62*BV05|dZ !V N8}z~ g#{G " Y&D1<^bUaPߣ9n!^zGCMYoR^8bhPȁNdw\tlZMt`aɼDM d#dS))d݃P\,|_ncy]@RWG_kmVq*Pq=w*Y'wd~?w% ղYłpXYn-$3[)|"ustI̝cMQV#[+I&-'K^-hhu*d&E=8C&&[n/uB5P9f,M! 1&Fhi_0/B^$abѮIYa+ZfYLL1$Lz%@*+b3&) ٶ"D ilUMȨR%:Ҡ>qLP'“4vCԛГsf-]5. 1*g|Lg,5|ݰAWqERɝ~Ҁh E8Epx%ֹP%:Mh.DP_V,-eٳg {zG*٥gR憧Z ԸlϋHߊ4s2VƁLهcOVGFJxah3 0Ǵ|G #{b`,a$qDTZc"5ndVR0GJ8椉LZ'p UyKBy"|wtp,R R5g'-{Nv;2C,QE*"q\?~|bjT3%i>=e18Sx⩔>;,B&M}*Đ 'Qeb8]UdLg`٠k[}&*̣&:EխH R'MEnbWi)$(~aXYǺXΛD 3rua:1.K fnM~=("9_ڕE\জ?).@E$z4m-&`י֮Zr9| .# 1|i20~2h*Zت\XW.#oe_?қ֚9klug.i6q:Q\,ǖ''͝'f 7l69Hx|* Ixxm1A1|}#rK|OwT8s5cg1m6 FfEe&26qKxU!jآ8LmiG3Rc+ҪIP>ˆ"mb.حxR2gdAklJ٘+ifIL_פ#AeXe)=6P{+J%S"KπPK 3k{k֗c*'UW@c@~A*mPWQn֗3_Db!fNu D˕H? ,Ődh Ehtoljy=K& 2EߕLTBxdITixMmuxv0zܜ~+C_([rn14u3sp Jd#IbRݤ Q`FuaK kIdwU;+[Ɨ˞^@+ܸ8kوSqm1SLJ4>mTY8ZF c 2+6;7E5 g ] B,\SHix *5w~Il}YU IV;H3H6w(lq4_-'] HQ$O$"h]fWn")_^YQ Ţ_+(is#l- Ҽ啹L#z.*-wiIyb2:W(w5c:Y5 Gl!}/0B+: Mǎ"q. -ٓg2wr=#E87Z].vU=w8_<{ X:ʊtm<6+ v.\z;ndJ ޹M֔#,p1X)wQ8:veߧ{4VloY'eΊXJZ>RyP ںx RP`u'8J'EEd˫@PR]b. D֪L| SY!~5 > PMz%ɲc)!ntn@v6q5wK# iI\@%v̌g3ss5Ev1Zx>LQMeQIƮhYIlξF{8Hv[zAΖkg5zߚ-4Xۊnkֿw{]+99AY5N&c>9¦yv %01ca3*(07jtZ+D[a~.Xa +}%_qJt~C>D-5I' G|߆tPRm"EBr `M&=5ȼm"j$'9 B{m^nSO% Um߆BT@ "-~qcL(.koH:id;1j >_U1oxǬu\:T{tZ\mRf1m:+X;}~;n]u)ިS\z/ٴ̔-td}5+WGiRk8Ҵ\lD%iqIFeݎ@|Bܯyߡ2yM1^VwP~\o5eɌA۶k&|F48Qlc.JcMv~Xw%n t8=u8CS;ٿ#4zhw2%k~٘;Ao If -5FHrJ;>hmLi'e|k,po'M;wЩPk߭V%P6֚߿6`S8h'09,ɐhoi +Y|6ZjwO*POEg嚂0nWLpd+/56ם(UQkZ;W tLkjg˯sB6R"cW߶6ޥܘ˝+T:2*k;F3[vu9T׷ק}O;F)s-ЌHr,\ 96l*jVU͓V0F1DZ ^L[K: Ki>3]oA6ײk&S|#Њ>{|n¶Pht6L#(_a4gi1%ߖFٿ= Qǻ`X[ ~ԍS_Tme.R]$v62h3hа冕ȎOK(Dk1k?dԃ<+o [|%~ O2 )I<L&(*W7bGM3LQJ']sD [Rm׽Nƴ ׎^ӊn*l5^}m%cV+kErf^5fY_@#cRYn}nw˱̟4Q`7d_K\6]k9; ;[D^<{ycrLmM+%rʄw5;W%OaAoL?ZDnhN :tK *Z4E]ol+LJTg<"r7yj\vqk-nLdlT0MS$?[oLF779GMO152eYHO9"a$tRn- )dv[t'0m &$ABǨaxJ ۮW22/i>[",YBF | A!nLƼ2c[fdl?aPt7ӭwd,kUH* DTxJj0BCL*Z(neDg-Zy^$;U7"6warGyGjNyva c]CcPm V[%cܰEg1iS/!Zwim&o%\5 |hLM.؍P%M_WEXx653߄Zf:us![%&;mTnȪrzM:mC# N ~X~Mh (|F)qԚTe"B:4YY31XPI 063E\wsv$1߈gK]+ſGIuow4ZDH r6#5jvmMg ]+GE,lPhE05ʺ*T; hV%u3^vY?\wdlhUӪXT&k&&Xd"XD8jrɎO'2Ʉ!!FWŗQ9!k&5u҆AghH{B{wH0pD5)6P%g=,6W|´(@\)wD̳ky۟!DLFP1S(g^۳!hjVzc|T~# 7K y#1Պъ.ӳnI `S:9Z,5ev.FV*7{ɀ(=%,[&OԆLlDZ"M3|4O%֙O~=xI})hSfEʣ.vdu.Mςwbd2H#dLRQL/mFש/E='Zm%/SwC(2ӝ󯄢o)9qoѦa `{қE؟& Q24u+ON1yν0c>֦5!0{*{j;^E"i(Z73AR/ld֍7vрY@džM<'.Vһ ?| U;!כT.6zJ\PP.)hHo%{9!S%t( :*?[7f&6us Ce p77bPWSȳþvnʊ75X7 I5dF\tDhcE# BtPJ[ LCX6\&-ssƟiJ4HMm= #\JBk.=Z/Ԕ8Nmq gd[bYf{g)ZLW=WoN1g:8}AGFiAh{{@@KxyNNҟ]`9?bJϞ[.SZ-*:yԓϿPֳg@%W_>OHg}\]˸qAwɶQ<;v@͙«̞Y _H' RԥJWѶ/>&huLXO@YiAyu))+\w ]JWsAD݊2=ukw&2-fUT&E55E դ^xQxЙ\acqO sd$7 ı^!ʚ̣ul/OPڪST6  S? LR=L "LJ];A8ȥldGֈk{r4-_4\qT 1L+3%%lޢZ1BmfTG՚A͔KI*k?3Z52><%,A\GNP6 5H2d}nZh1Ε5} g/B.K2wۓŠУ'{<,ֲiȱPO|Ctiԋb1R9أn8t!v}ٸoS4]evSRu)8}bʭYyNAaߗDKhJuu3)$oÅ.#;2AܠB7nAM㋥ IrM]N'2xp%>E׭놑\x }6ldQԚ{k"5Yl!s4E|AH([ycU4IaSoZٖd]hCM^5N˓ *Ia7C̼u$Kv?P3$-isMS yP7\kijmvs(kބج^U7Q=%Ȋ-TԗJ,d[8W}eBM>x^W)T} 8٫TQ3Hl_Njd^ L;^[%&QUuA86f@57G}*~#bM73z%>OB 9D5PVӻKNHN  V3IxC75,'Od}̧]__r>tp%Oy᥸o!|bǵN'hnTuw6.@*R3 :VqĒ=43k\W8%19@8E1 W{U^M+&E IiEлqk;$N?RqF 쫰q_H0"Usah߀5!gg~bڼCfh00U"j;)!hIԩ56U].Y3Ec]ݎkhLR267YAJ]e|jQ6>W>pr)dE#[ia(lŷd YTeɵ}'9OV¯Q&zÄ ~_QG BZWb-}K@p LdgI)¹^@ X3BaX@Pӕ5g_GϞjzwÞ\ҏB/hkLN-s } j6󐰶j񉶘 jtcNZk/qRyTfO!Ց;]QӛtڐGlISTjeꖵQIu)dVF[l9Qt[XY!q7k[^#Ohۛo eR5]fCLTP7Vh [3v$U@^6ELv bBǘcwL83: /i^ӮoR5T8MQ/ߟ!)0*8]|R w|m!'6<s$&6Wx D 1Œ1Iof+}+Ƭ5/4I*90M ":wwv!@9kBZX/i{ty޾^SruF9PO$ޒ5%7|nS%GD/p::>J՗_%<ڧ7@]+9 aG>qVb4a B[0;X0!3sk,MޔZU7'M:7M[T+§/V@J6Q:׷GUmtj"ei?eZn)[$K9*~KRF3b<2LLHQ@`=SW%Z4>1&uF c񵤮͂ t& K±6 ̣cA\% ,,M.(i!"deg hcZچVW%NcO&\@R#us81{ L,iMWCcRBs5D<᎛6Ur\JLΎPS Gtzq*[~CR5&z#\rTvkID'A)o,jւfgS#'Au-Y& RrZw~IÐPY9KR4I<吵&5JB*idx*bSPShLǚJ?7Q4a39l9҇sPZCEz)]t/g 4,Ũ'K6?0)IPGB@/ 1ϪrF" Pf^f!-;؇pL>I%e@;)enܠ~ ʨ( A}GmiMu{}1c u F`oLzhhDݠdF;;{C\ό;> !4cv!nhq{|VLCӔNFt!@IWOi1.|m <]z! Rą73]eJ67YF¨ ga5Mn\Ct4>idHAZT8 זqCNJ㲚+)+*S%FGvMmso+f}d!DFΧ~ 5&& vlf(Rs#lvucZA94="bzqKQ@nЕ"%fDG}1R2Y`8Fã!wkLޚnم8M%ܚd4c\y_Pg 0\xm ٵǓ((Ui$Zn{q.;H7KK=֚@Sͮ뻒|}yMXflI1Ҷ DcıZStDB~ij@Q.ǜ3 GX BAX$H<\lg,/(tpKa748uKSD/ 7vebWW} dі6y7bsB."bJikɉj,0+vw,KE9ͯ^am$MWS)HV5xZ9ۃ`tDh4ҤǢg"b*LX 2)hi [qpAVc\> v}aAɩ]X#c)y&Rj0to!Mċ;֡UoL,qxLT:8CHq|=SS(׵ytn"nG$2W-R{6g3aօnR= dʼnZ--<ۋ*oM)#Ώ394P8sVKZ\ ++I4YԵ|^̱9HMxͰ㋘:\vuMZέ36(!LN #TXk -AGqzW )Dm܊vh歚\L_c_'մC %c&M*68a2O22}BQʿaBo9~٧O.aN pye2"o\N椂l00 R2MGLYWŗq(e8WIdѮPy”Ch8q1=C+J3퐳ZHq 0u9ۜv:24Z_sʘ"3>7O]V\}49Gc J@RF:E֚('[ٸ&f4U \ZwomsgȘo}I-9-/u'~ǻɶp)>$5̤wjj& Ց{IпmwZU67c"q$s%o^ y\ lUEk2͜ ( %,Y8b_I5`s Y}1$g-6#jT XH*y9٢Ք^|˘>~C?(jR#Xrb'4MUDLaba=ˊV79sQ85agP^,`'zz _oM1aq3iwo+ß lu*1@@Z^҈JJ$i&dFC%q5+5&a:g 0}#2|.w#cGǹdRGH+Hι;M솮Χ+@0b]=hz`7BE5v0["GنZVϒ:p) p=:؆tP#%.il3PoaUM:2S0K?5v|҉?vjummI> 4W8tٌRĘ#) IW Kh{6l<.ŖҖDMGr^i<ĵ4D QӂJ.obR#qxqkJҝPJs" 15fF(]_QZJhG[:#{Q#XBBsNxnЀK+2l~ّFs6CbHJ-rT'IDkvT3ViA=jm=uT*rld%z)*GZ2ij&maPԜر.q(NX;%R asX\AQȡ =-瓸> -ztC[onIǻq[! pٌȧހ#m"z7!>?OŬڒk{y |@)RB`OQĂ2d~E[{،<8t𴷢~yCޚ(/&7 s2T{5K1-]j[mWW|4h5߃aoD6dX0,u>@| ٴ ƒ])) 9e$4KoyOsZ$&&gs$ P!&^Xd e-agLV:% Z.")tt!K,%:>ڤGh?KNBhiŤz9QPpZwBvTfJ;)E ؤ PFtE۶rhɞ[2҄*3K jx[u 4z'MAR! pNa˞R&VE^4$wt@G!-g>]_rBN"Jdҏ]5տfӲ'%s]( ΒՔ㏞C(/_C` 2wN.E N0(0/| %st3[g~I?@9\S$cZ˦-h$q=f0UV@ l -l2%+-D-zo !b@m JX4X`ٻ Hjظu jR2S%BIeA(%i&Bi1]3f@R0O4m@j%XA }KʅKH0|^,hmإԂd3s1CjǕCB%{CR)f7:٧7gbFųk:aԤuخ#iƻGKPV;ϖd=q ;<:9xB8} sAL*@p G`c寁N3ixѧ?ܣ+H1@I|y>@/J-"aq!5"È>ABRb]"uBTbS4SxD2r:7Gnb@ LҟZ(dfx^uf3*Քk2rŽCp*~4s LuA,5WG!SVRNקG4d3͔5[DW;L֓U=˭6$&IES)ߜ-Tgӯ-u\(̌M3J T%k'J<6ַTOIKMG@΂VU\hw-9`?j:=h0Pf1|52JS7Q#)tFRZ]LfCSc ݓ}:|?ū)Shԥ`p(>%S=!",,/~ǡc3ʱhcNEJJJI#5ۣ6YJ l~RN0{ͥ}ZgR֥k`;d&;zSn MԜO XFjukvzzl? QҒޒ@\5>pz.'H2C[`sΊL$y%c#:xsM)%(SUlCQ !c2׀poΥ*GG!~dٍڣ)<$knVL/'w"plTz{A!LBU(3*/f3Miy eF3(ݢxI7?tP1~:R#5'V\\NG&d*٨P\Żamv)zE˛T$qs(4ɩSiw4&v4;ȧ1$G~CjChY+>%nj+Ʊ)MwJf ?ncBUa6dDlý 8A.tʡj&=%ww].}Pf\zLY2Rp&rpB g<إ(Sh |BM:[I6euI"E StD+Xx8>PgR-9f>pxJ"䛶:ܯ+"spƉ+^H8z)XR09YJ4㺍h2JĬL"VI czQgͽ&S n }g@^T4vܧ|5l1(K">LworռF+kWX.V & BN90%Mnf"|8-eofMa!@ yeL$Yô?NTXV)-blNn f ֬OIM.!k݁*間%"l77D0[F1Pf.) %ah}\,9;e]~/󃔒Ld[Rr axx@(WR@U2|H.6a$El\XGl3  ='K!<2_- %)%чmv).72NECUwQq ^Blh͋$a=&dxvANRQ<,kc}Fwƅ>NߦЀټ0}\U7@  %;{@#1j0Gl& ݕ+[Aw>rG@}ZPnw9 2yIbU59ZdZrngً+̤OrZ*&wƎwdzŶƢXiǎGfbS3 eفHDĴܦ$7Ipx ^  G6u#,Te0b-v|3^bI}o ^H^o9IUJ_X (:tetږs5't’^3R*[f{wD\C0۸BgG61#dl<|-^`&}6 L.v$3#.U(Ux0ą.WXJT9P OuJ>5d7zp UK^k<-zX|klR*z m2Jy] Ɣ :mD*Ս+խ'kvm\S<ϻ.+3ē/ djE| _ ߁Z,p%펤P MV#.Hu6[.OFH}lsp=m7xL Gl4m}Ֆ(\ m tD4,xɊ9cI)[MVpH4w4uYQVtU4;8/#(5R%8-9#:HaB]!R h dV].$ lr]y `#*!KLjE@Tyyw Shڴ BdG ԫFtyH]o\t}wH;Ohߣ٫%톇T-^.+{fyM(?MVTCB nJZDJi SյIL7T+))¼¼29K k AbJ_#\&}6׹UmMwRMJn| ﵟ_(`Fa֒E"!(M5%UB@6:tt0TZjBB4~Q*=:21Eb%6y Qvnw=DY1T,,8@ ")hȜ~Aݩi{gH;ZP2ѷfϊpp sChf/!d]P1#qt.^\pQ`r}3ШuJ(#r (7km‰@V=:eM:0sr"EY5'N¬cme5Õ+*=Bez \4KUV'pJym{U thogÚ(0yZǔ|qM5aR^8;2}9>=?zVRߝMkqoqkۈЩu. Zu A,d K [K >BȻ\B&5C0",.IL)gb-p(GohܡuGPvCn'r p{Ԏ!Z}uhɎ;o/9FHF-jr 5+%3LׄըM[BT;yc`D5wtXJ9r4!4wp~8igf/i&U2}~Iׯ'8 &kj@V=oo9N_KzsˆC{#'Rsuan;)&E BZw2`A&)"XR(cJ,ܥMZFG zHxh9R-SK-̤avQ@?32yAYITt(~yM7$8ԥ/ a5/}E夢h xO8K!>ym4c~ ܸGvp}ln9p#/^%!lLqڷ!uMcDXIץ| 'm_1ìƸ- CWLu LZ|lGFiF+pk7`sl^T@8u59ֻ []hLYW Rl"5MgvWdD''d]6! ꎄl 9;96gH 7#YBeZ6jX*VgN\(߻X0@S 9or ☼ݡz?C*esb-ƋS H`@|,DG.νb}(#C9+< RȜ!8z@P(=zԥh.Niyik{MZ\W#V_)t#0mAwL)Yh'ɗk7_X| HE;b e6}% rjiRo%Q<DZagEC1*L${^$6GPXW!]nDu;t8@Ӝs"-GOXSe%Jŗĉ³bJ_Hsԯt9W/Jɹ֖\B2!gðC\]ET:.߸yAKr5>5$W4]P $qPu}%e8Ủ}Kv?ڵ&AA쥰q9y7 6 ‰OE6]]W4] W`cA `k6 z{ zdL?C@HsO+a 3\,_^E[f8c~jEa ízgohȧCzɉT,|]MV+aӍQFRfjI&ΘإMJW3S2O{%wsX^Whwƴ@=q3yl$҃FK$+O'K|ԋ`j2F"<+l L989,%M.R',C8Z_ĒLYO>hdH*'ؼ~su)NapYh-mKBi*% 0+Y;{;K7ϏV^e+Yh<3Z #( yus]a' 1+Ed=KDnN\=״W1̱T2oc5m%-0/KzX19߁j;/`n::ɶŕ$/O cv)Uddv;{4f{omsn-[绋Ul~ %(ᮉImot:UF4մP3p2@N膄H5zC߆5aǫ[: 7!+Wk?zv@9lR憮ޝGþ3G0",& g7,I<ѣC;ŀ  a;RRI+Q1eI\3dB8vy 6EPHw7Y $r{Y#OB^ RĦ?W|^Kw 0eMoG]l~ߧ^K,I7ӯ(Yv>%1 GܦGt"|r}(pc%y]ߜ0@r jxmG\ZS!?;% {Z ]0ڂ:&߅0ނ*{Zd, -1]%xMDB[v:0K|4/~M_a@%yqi Pm%蠦D?I@' IʹS~ރg0X)=yPMh=k Rr;}$ڛL9L/{P}#+69j5\L~mk وw9|7>Ō 7=}j!ԿI6i\ Wս L2 #㞒QP@.KPN# .ϗ4~uAC[!=gRmT:s%E4m,Ai@k0!}fF̑4\?~Gc4םyLn\e0mh` 2A-ra vVsfwdmXhq/?f]SoܥND֕\$\)$?,fm9*fcz h>׿P3g0?hL:Xr|ߥg6Lt|q'Tfrlɱ0uɇGDh%W)eW9IV*ѼU;5]T !difе\9Wx'S?>q{15]>` gg/!L%=AKMR)yO>Wf  3-t.cgg|A]nօ *\syHLÔ|4m$r)8j̹WڐL; >T85ap`pK$rc)L\ŵOқ/^QTIE^~yNC? Q;X R:xsM<sqաm)=BA Áb#NZ,Kj* ̹c2@P[ Ɇ}~v) w͵;Nw}tmSO3+axta ]dg$#i>3)-GWmA{pzqI7Ae0 qݮ; Ibꆎ ʥ&C{-$g$+Je=I:`FsR>\'kT*RϹ8/9(ŁKƾ$sm;kҀ}2vBH卫a=_a7J%&f-ńOE!}ֻ,z'_!ӌO]RT.ւB"H f D0\ x%CZrH1-0돏w}i-% ;} a^s17G*@mv +7(N4y,;vJ䱬FG+/U$GNy"~,YKX pp ERH@g6@\ߜZsm<Woq_U,SZf0W0` - 7p5rSd ~ra&s6'X /üIMC:Pwf-TD՚F6IV[%lڶQB[٨'],={RXZv:>3Y1Ƿa(O0qi˟ϱ[(إ x],zUdLnHNԕZMϚ2 KPˈf,^wf`S/V] =_\ . -Z\x<:f Bt$w_ 7zZ!bnüLqj @uEj~OR̽^sq9lLHV,A1-a5pY]%|WtdN~1^~ +vbq<BfK_z2hy`pKxa̍Kf!E[uCfZ@$-++¾(̆#i]}mKH)\.E /O~O~Wĥx1yѥ%"~5VFV @Y`]6rFFg\P0Xb*к( shו܎I3{K[\2M>=_ӂ[:j/N]:9u?ӹg&Ww!s&0k.}cr.cT-i=lA1q{u!ݺz-%\MyDȏ`paWka~(\`@BA=sW:CQy $0޼=x~gRRA//(.0Ly5f;69i53Ԏ\ {F=i~5]i &MBgW紂|!9L/?$3D<7scqEϫ9dRٺ'f+ f(k+\-/zo36r 3\JuK3߮"-E<½R k 4S: =ɧ˦BH,S9_U7B]b kۥVoc6&UZNqq+:ɌOi/?>Kٜ]c1U0^}`ܡ툺ؑ-}t<yW p}Biɍ:689aELPqy2N427c V2"0Hzg >y`(z7=%sBWD@;"zuFNdcnϞ47`կzBg^ҧ{ ׽70SML] .jcuTr}o{k8p)fYA]zl=LZ8w:!y"o]0dYPr?Ltzfv0?Rx$Z̉(',H;eDUY`AH6 .f[sڤn-cGf2I?3_LWfd6zir$@DP@P>,d(h,νs>ڜp|Uќv;')1NFЦq"rLmAZǽ^.:G O2/MT{_]dӴXޠ{M c0"N8KF-{,"ޜpY600bSfbgaJuDПM>3ۑ&>Ca6t.'eLGk=C!4cZ]L֚Jk\w:L8''J:|$B't5q-2z3n}x%K/[GY& .b  bMzKtldMF!IN Mjg|6h"hb5Y lNtֶYB 1vjMl+H%9nINH3V3Q({(Tf =P$M.[C&](difvVp܀.^ W/D8=K56DNgڞ+e/>)Y{'s&L;Bx9 bӽj.Y*K]\d9:F&fY( GG#b`=EBPTtOJ8H_n9AV5ȠGGhVXB3t w`e`|HC$5NsZê -2H5񴹥[:D&P[ rB"|G跛!u[ـo\ū*F W8~j! "-r(qRQl\@ޒl屵EnUMϞpll1MveB-ph7otRt,q~!)ܯ#s9Ad8 ;w'kG&.Vƒ2nB$J#9vHsNY{6fm" }a0qNȠ;uڜR],Q+6@mU#GHC%<x,3in<5K=AmL2RMfjz lKRt+K=nqNWB,aMAF\Qo<91&Smn]F =ɕhh"Hn Jg g66gNXti7h*ȃ"@sBQuuBѨy$iФ&-^v茔U nXYFs]Z:@zuILvwJ^⩔=Zt. h}a^ ŭv6nc$7)dDZT:BL T*%{(5$]-oNdXX$'LFH t}#^Fjy;t XKhA2%>e+{^_NO);Cvl:޻DccKEѽx05 j @Ft-{ߡ0#ac [6ɐ-֭Uثa%U|ZcaB-{g5֏nl pT:F, HL3xB:{xiiBELCtZ\f KMit:>uX#zR$i(B;`~Տe=42F0!wa Geqj;H!I`1S (e 0<=gD\󨶱y52#";Ég氱Cħ|~ArۢQ6t?R^U2 :@rd`"186}' 4ؿ?I%uѣ~q-A?;Mn>25ܾAAo5Ņs\:V}8H5c6M/B*D_-EGk"yZ\<> XcڢdFRK^^ܢQxYRfVhM{r@B!h.Vy^knM= td Gx Ѻ&aāAѣp yMTC ]A\1/x8umBidtX J/Ane< Sir$,fcP6DչL/QpF>:{o"d/ Il?6B;rnP &STǛ 2i-&MTSx5՘>qh c)]!.ܠ2]H'XDI3 M¤a2n,"CD߯qqgM(ʵd<,za̦dK8x2'i=rħӈOlK}\ĨvēY uȰ52x~a1GofyKő,[9 w4zhSWa dT Mbfz])r775mBh8 eP-*DY(t1fk46E~J\D`yу(wK go]5>!ooӱs8|$֐kTY{ɅB;u/?Mς_FdWqPME@cA6,2[N7eS*wB)>ܒ-yސtuنRm'=72&Yr.cq3@&v}VXhQ5ԔN鵺Chˤ*C4lC_4EȹauGQs@wjN4g K%8Ʋ*Y=tE44ffY: ͐( '%n)pN*p6"c)__0A['kbXmcqTrf4AF/<7& yXc,{6kVMXbq@p)&h{uÔji{8EgΓuyYd\ W/\MfӊsLkʳVɣҮH0*F*UAS12ݼtH>\+=D7u[dLƹH$A: pw~ 4@럐EVFELO|fB6B̗C;5yeEny7Z8|(_~`s&F9o]ՏNu yR'<>sPjݍ \EMxcz5B-Ab0A=Ά26,t tTA6tjj',UNvk6֓0*wXSJ_cµJOZKn=,\f\BC6\ƤRBs4OfjAc3 bv, e=n_[1&*"Os7&rE2V0Ei Xa,Ȥ 0eވO"cj2N92^!?.G- '?h4XJΪd'|9f@2^&1 \`>z/8EPaReqgEF9@ǎ!DeS~,//봰159I~E|&eFhmU_ Glj2.0sdhp:Jnȃu=d ܺv*NܡC.:5B#R bZL]nIҦ'f<A0MI.F&,h2ZÇa~Wo\%g<.|&1p}Oq{p ܘ3DPXkEhni3*)d!kE9&gEMGS<-ZфѤpH>I~%,!v,'I4F0o=2'0#}kϣ/f;k Js 9}`,A:b*B\RTkMs؋rZ l>=I&CNԌ4Iak{8q: |iZ +aI.]Zw"UU!?4&' hK*"ec\5 extOQoXb$\&$Q,aB0=3)NJ^&pUC2Wy, rn߫&D=(ɱjjPpbO'10ng.AH/fh/Fikd` L|HV;$TH,YYh/j-]:UD.ЅkEްgo>οs#huTubG0l8xkм>7-w[ŬkΣ_הX__|>k.Qi#PCzۮڝm{`4$\d[`au?w\ڃ8Lf fYz0'[*#@U +=H$2%Lqw率侱uʿvMi a r}\ ƭjSPrI ؕhuJ*4 hŅJ#iHcHmjT5lr/Pq?Rc#BXngdl WnΈ[ HK^'u(fKASK~uأp{uyYmw2=g359C>ա# c>1þdනv"a<9E4)]߫aϞdͳfۃMHAO;kqTSegZkt.Is]ˊqib@=SXXGI\8KlKVFxc,Dg?@BF/V6y՚U}OH G+nc 3t|7}(&|]& Nm{.u~Yۖ٧nI8OAn<]\:nMiY-]g 4 -q.RxkUM,;t-R-n>zrWAz&ްma%o;;&Q|'Bԇz`OiM9&ܩ,mq[|vxMDa6$)=5J5)"+]uAJfSH'j+Nl١uٺCfw* {!BjI "TAۖ3XsBUg!vnU{ jF]ܥAO1k ee6H=s IY5DGn'h҄)KMn.r:cur%"Rx8 QN]866ۛ}eh{`kRaΤ $ -}+EU fZ4K F#Q$n> (f 6p1}9(1Q!>=|SwjN8e:#ថ>>y͔Rju!2\ C8CV(ɽ့'sv|O*>z$'5znGN ;fsA[hKs1.tx CJ{Y)YFBqm4#cX#1*MY̑vkKc!d'c%Uq KNRAm4%iͮwoUe39s)rF|6Mdra  ;",KI36[o,5&Kd7Fn5Tm#dyMԫ;djeJmuBF!u!"-ysxȕNF0瓍C DrKCGYAFM.[仚{FC?H7Ks tuMA2(Y&_5,ߪ ;F44eD>qJ9p\=DzqAl1ЎhlJ"g¸ww7l $EEJd|i'CgW( 13;gN_l!E2Θ9Ed9a jXL3>l=EQd'(4[y} 'J+7c`!R{k}Jn ;K,Z ӘnRt@USgIIN"EDVBH<:C M{PWE;'~78q̏g^<͵ v6 !~J]bfaE(t~:޺&GU;$ݧ4|fo}rl'%pn\;`?V~2nx̎>JR|W%En\&ǧ&פCd#d:gep>)=.Hʥai9Rk}׳L:ױ^~=_l{['O$P)|1ĀR b){ sN~c}CH)Mr- |7oVq)&3#&r tm]C Y=]#Pf!4[^/?[B󒛥i :ta= Xe(жT$MsLֱHZ{_<>8XSDCu pvΧ׮ + IG!J ;%wpƪz/Ml!%j'9(5,. m{!:~{ yms.^3Mx?ft_јo Ssx70O1{ Xqڼ̇o|s5KJאѰ]ȓ_8@H![aAp6]JJ[[L4'Ht9r:7JlF)8IA#z9x.SAIV߀=t7)kѝJĒg#γMލze+wt֚휢ZC΄Ε9KtfAB(@2vB IոړըkvQfQR"Ķ/e0K#gtZ9V()OufV[%nDv1HvQ=+ijzvhRg ]dG΍mp>nZ8aee6ibv2 'n[cݠyԐZ%R2p!iZ)4!iaiݤIq93A{QN\sO,"V~Bp9 BM+|7\E,eŃm\F Jl4dt;1QR\Rh=r] K^Տ(+8եק^*U茿081b77xD;M7+'Ҁõ!FƌBlI@\z^2]wuD(hpͭUU+E7j(Iq=D*hm5m.vt<[LekN(d ﺎJr8,mVR1ßUo'z+oJAYSgTEgCu;IR#X䇔 d;C1}1Dڲ0Gk#+kJq"Fr!vv+YaqT[6\G҃u\e;_ #4`>Av424l uu9]nT!N >Av 7HnE /5G54/b$#CĊlԅj[f#7J:Gds }ߗ:Nvݒ@?rwhN'K'Sr ٢*.6[Aw:Kpym^EB4Ә!ШNEi T؍jYt:];[}\xFltPC^9φhkBA"SĻ}C\cѪ5̉Qf\uT D ?]Dڇה5JYٓ~$A/ʧbg= 7~uf'T8Cn\/q&M5Usݓ;')G`1CBwD7RdDCeav8Iwf+$uzb#a8XG2: [VkX{7=7eJm{?@INW*fUϻE QOVRɵ9q'Pd_elΣjA ;%nPL$lEhPQOqQ,.?Ը;sSL#VyrHK0$P,ѫ<(IK:^PGc_4*xM3P~ǫXKR`853,oa$F}lN޽ScX]lmi2ƾv6CgܚӪJFH(E 6,CHgi:mrV\UiAD2d+nzajb LAˮ-뺔- n'ECb#8w lRH&YiBqUj*D%emDtI|J(&707D-WMܧs8qpt |ANSLz駄б5;p6BM~ΛɨEGc#.<,fy3ݡ"L:BV9Fxj}~ KgMeHɭ}ᰇ-F j1fpv߭~ζ(s̶ܶ>@䷡}8ֿmvo,q.^^bZM7p-$)A I~~ Nm M:(J%CoG3vȞıv&d@Fz?{gp/#N.w֫#;&wriKt{"Mn-scY1V d+5@`WtZ6]ԢטElsE"t뻽 A.mkr]rbzJs~ؾr9B-JDb鄦=߸\0"r#}֦5ڈb~0d<.HΚ r ymLWrT70GH4!"|SNPKl6ppSq~T@s#w,*eh5 C6?tmz@\0Wޔ {箪~Eۦ g`^wS-?YƢks~T_S/t!z! G.q7 u A\5dk^Λg%.ݓH]'}ﰳ]%5Kqt|~\W6'YI{tv= %Ź RjBJ;z#1-1Rǥ"\)aG\kj z*n"6=fU4`YR뛸mI~'L/jTb߉l ^z8.m0|n %C["qNuwok&{L^H:jrkG lB!LNYhH˃)'".#Ƃ}BJӠEn)0<Պ!pYIv .eyNfu438L9#.fiA/2a07[lCiҗGŨe_r!7Ѳ|: %ȉBM4& kKʹ136^΅Ζl}3'L1-=Q ImIa YbӋ҇> ˱a߷^}OMvh#Orv{)pc*cgi:5n 6d)d[jk.Mhe +0)KEE!VԮs!;(B\63vچ\Ջb;X+pv<%M4\1ߠEdoB$t'D×mR?3N/e llzx;G@%I/Wȍ QZ "r|W 7J|B*fA "j<跍 zB6S.@28NGhAu/".nDYFNH  Axt.5lW27taz-%NMcb_+-/#73N=͝0a JL!F*jY#ccJC@KҬjΑVg]Yfj24 0 rn3K(F"BWgxE,L. ӒU rYA*} Z5ȻaWP]&#?96IAKo#ƓKP<1ݫ9ѷr K<<}#)i2D&LADe0%E1.JIDmfٚSQG:FG7 нR::pBIiЮ{H(JvGnI?FCÊe|s=lך0CƎ 8U LBUa7-6iA s+ޖ58.5o¿Z4o!7xm右r86!a0^b]a1g5Vg9Oƈo]NT/6bȸ; !UΞ0j@g}r㽑uM2pB3\G ]MUhE7Godu u7T 0 y0rԜ".Q)p2!*3kܨ?F=rk56V91zI+WZ6&*ijn}` yBa%'7^7xuz% [5[UovoY+д~][?٤=|QzOrnw3n*z;KsxHM2Vv1|`ԣۖ%\>lMQdaԣ!rBD(W[3^%P){OFlH )IT)l0:{s`y?JHȕ Ő_\E,?3JBpr?YE"Z2v-!x'(GSrH쉇v|obqj5]"uRGHMIk2̪^"jf(d|6oL*J2m RHRG*!O,N׃BU`CGqvnku+DBӃ`(JH-iܝv l(!;aTUE5˰Tp_sz@k85y2 :jyc]J2irrFvgG˃6N!7..Yg"4cca֪E |Zdl2yJK(]TeKF[bz?n+ya=w~p@6b4:)?A[XZr{xEObjKֱ] _/pR405SG?ҙcdvJڂYuz> Lw@ LI\+*_91}G|s~W̏r \lcόc۸peL_ڳ~vPBrSk{A]:V[w&@rgG*LF&}|SR&KBe_tvmɵ7::Aۼ-L1lI]W:=>Bd1suy ;*;/<GܖO%yZ}=B}(AP4s"ѡY}^F*rw8c)&j rBnw&V>*C䕌yȆGw_DM恒ת4 D$Kh)̑IAܯ2"^2\S XFhNOIO%QBdU]iO|51N6 !~F^c/=.Cw4%}ےq$ɭiDv)C ~؟pbHz*rŔ3H:u3J3FQܹUQDzc fz5#^2F)ʴ~[o3%P[縠r{#7?çu)3Y\Q(X"QnncyS$ǀ?OajBW?]qnR(䎪sҸA\厩HS( ]ȍI#Urz8}L?G{g_E(b/M MJ{|U੧ղ۸qnO]L *m9@u )g.VL.t?ʣܰ/q;ۗH>*G&pr Fq=<enBj.% ?L·b7D*\^x: ?<ޕ"B?nUF8K:I[-CL*Ӱ]e[އ2^ԓմ]Yήs[[~@*5o4ob$?áy5ǡ'.1OcFpcBS0BϟLPW1D)wGxH#⶷=!9o.db mġ)6)Q[99Ds\;be@k;ʥp -> 4 .nC S(AUV /Ż,2>H"n24~ϼ$ ><)}z {!gPix"D Hq)Y#;hiǓ e\&,4C$ T;yHv!~(+1!&ddY{8r#) ِp˗{U"[CW"z51ͱE gSsJM0 ͭ-ɩ ۴*4"f >|\cGN1^',hr\6Z'M obhT_Vl) R%OBL%Ւ!N#kP,4~ tjm oΝ%x|i}C Q؟ GhSƽ{i 3A"ߺ/ʳ/~5l\ <,G!c̗lΦr͐`8DNBt>/(SwqmAr65Ԃ˙ͮ2d0dm'J;?[ŵDEO&iaǐnC򄒉6lOj Xa*7QBufi_j#kFqa?ִMBF}.*92, C&PZᛯ 2NSFfR?o_ɧ ɘյ4YrX߱O_GsR]4z%4q!DU;#2) +m|ocv9L=Ux=2=Աv` M볿E s̾d"^'i+O'nlA PrN[=j&SȘܻ6v'_IVS1͓Gا2X.sTsᵩTt%m'β|AnGiiwoR@#y뫫iI"7zyӴX=Q_凎\S R ^xE8$@(K 1)2fuwd:(V MM~'xD  bO"CI_"Pq5kݢ1YOGaSυ$%Xm`Pe59EˬFNܻ~?M+reGbE>-Tn- .b39tʲ 2}=r(*‰0mBuܾG3ik+ iG?-w G  LcD8+Wakkí|tGq4 ,JpW*S $2yk(odqZ\D|)(47ux;юP#wS ?Id2qFOn`il/VqaVXx+] ]%TMrctEWbvnyd q XZ$75S2n\{Ay{cЫq0ÈL B8r B=hTx%]؉7 UƂ(6taikNN!3q]fJ30[k۲;1pvޗdz?&_@|/][HHCƥazj9:ܝU\>&#?KOvıgøn.Lt*A%DMǟz%ZeMn7`%ZC"ziu:ο+A5i\m!IrmSBH0G?_ ~oay~ V^'T؞کdҬD˙ n>AiMf&}Oͥ&2\#s>7Wi ~z obK4^Z=ad&k_Z;II.Ư[ oO*}3N.iV^9fvM$@LMћbTӕ㐧C}FwӄYdaXka) n!dMf{͡k"*b(Hw+J8v_K=)P= }C JMH=\e^H?s?Ϲ2c^eXpIp e 73+h7oY?[ uMRG怟h 5ru;椎"CxO} tÍvw՛TQ!McVkB"Sx͉'8+/]ǭ[ȥ '%?g<*d!۹pPm܇":%űnf&#lsأ{o WU`{W:*ӡR`4;堜׎Bavx戎m'`<$FVddq3ؚƽ[KxxKڱ03@~c[K[%Dzi{kwKOVh7ogwAL?H6-XŕvCsߧ:Zՠ0;qH9-p/I 8+2E ̸IG㐅sobC( }bwgÿpJ!)#.@WGHt'¸")Q_vwͦH3Hb?r#hǢEcO;QqVqxbOA !` !&eA6&F'`NFq.MRDcbHg]oH0+oE\[#8.ڦу4l!)'l *jfnn{-Ig^:vRt=%aQX]@jt/ O/7kDLP_cpb*Юl`,>%#}6^{|8&~@1;b`kg{&dB}'"C8QzU=ܪPjeu۶u t_Iжdp)<^iaBsbcB^ L @F-DnQX&kF{[{:k] deh>vwV=>B68]38:*tOzf>m:^fdr7C]orBt5mmuneU9OVP>1$<ןŮ*z]gݝ5??~]v߲'>tPdWOѬ|Me%EFoj2{R'ܟCygvF _]Yҿ6a]Em'Lд߈-Uh$sCt@A_C&GK7<赢b"}~'4{hRh9"d/Ps|_q];]Xґ{o>0H=\ +p2b_w(I$UBNYX=kVM&IdT kn1Z" QN#Ta{i 1}';.Yob'*.i\]A*ƭk΄`0baA]ɈswY|*Д}iqD!ÍlNinQW1;=&=oݸ1ysֻڗ{zg 9MP+#@6ǿ ؁-VdINƲD8ӳ^u{ϚwsoUWu%5ֽg}ysbCo\¼t>8zb <). {?4^x[=t12Dəx{RJ"W"I蝞oi k3d:oJ9!OQi.?EHy7)3Obu7ۘ^>]UF<#jn$ƒJWI_үPMTxAag t}o#%{>aAEBx1/5H=oBGZ2B@joyBR%ۺD&dF-Zin΍ظ9F%>IȆo:l*(IPLZhڏ2'i z7e JkOɠqDsxyjAQ6rpWtcOiA3$Ci2m" 9W߃v]Vt>F$(& s&U.~pɥg4fkLneֻ<+DK QeZP?Qx3pAtc!HU*[]6#7yjcmV2s8g(8<]TY͆$+=U! \)sȟ1(8]Iş1,h,WlrF2q0g18L i7ʁ+?=H9tc/ǐIIt6Đ@N2rA|[=L7d](@O%c!gF1MH]( g7?@H|51ŝI]v /} ǾNMKG uÝd>*EH&E4CH$܄њO[=8˴iN/fxsmd'csCHcjtіPJ:*O?$zʍx 33/(+)!QxBN!aDf0sĭܓ i<=PEc,\7ֱ&TB8.T lh"WbҕQv$0a"f(HJ]|5Yp3i,0,xQysCYhXm\%1L. 5k phs24>id#.@r AzL1jmE,HS|F)5暎D񥞀MzIn *tO;2>L}8X"DLݲ7;Ag _n썤ZYRijY; %K ~ֲQdi[Vf42#A2Z`4a~cVlh2Vh"эCG>#)"$+!&Ӌf!AcOjigL6$+|iq(#&̱||Ԇ=syxHԛ${_|0]CT~A#nMd :2Vk:-  'xK7oÄF PY`cto檸< #dW *K?Ɨ)8fcr^tꍵ3n?HD71 {+. ΜHc:F,03Ǯ1 +ֻ6JB٠-;epbs+ z}`~"w,]CꘁL#ϐ:BsgWePhXhcil40ϋ爐H{J͐IRhH/+e!B‰q$EӸM4J`-WI'JӠfGKAVUre$Zp.E4P4"36RGć< !O0كrR+{'0l?A0FGv,cK $D *B+SsCZ8;9_@ܸ,S' )U'&5c3X`6<ws#Nʪic"kdXx2}::{lr;C&?;U)x Xrާ/>hmk_8wr*8VOpǎӉ#wHHI*hrHd 8S9J= :B51 K)bDC}&V\+T>{rY&d\Tgbq2ʕ@,;6inۼRqag?'dLVz`@q jÅ3Sx8(Ry!űpw<|h'MDלb>mgB{F<#O%mJ C6 0&?e_D&d2N>1qJ\e֗H M;gJ??`s 2IuHmGJML81=Ĭ3 [I,}Lkvri$q\PHR5GĐsX7&I0+.3&M;{==sGZU{p o*&ж"tqq43}x&}#$ i!m.6x4/lS}`@iICa^MB܋(RL! ϥ ٰQjGv}o3=RGl)ybwߓj-eΤ9\"ʢ~V3w[0 tW{,I-Ul,J/d阽xTxk1=-ixɽ;> h&~\C5OJ늰ɕ<A^zJ ȫK&1{*LO>˷%--2|O#Fpߑ֯ץakٟpL,NTɞ2 {Cy_߃65Rd3w^G 8-J:9r:;ҾѽGP!tkb|8]s,D#aWiQ:p+? HקBN`n8}MeE:><4,X9qK-Na6`m G^^4N0&Q,O'F8/ Sܜ;O9/>HsNx㤼rlTD`yB7X2AV RbV+eu)AI*"F17C60$k4 i>sq)p'-Mx E2}؄#M83󧅌In&YdӴ+}w6ͫ8fx;,s>u}YYfPCyD< @+)BMcg@x=Ѷwh{vo>`r$lh g@TTYiOL ՜K(ȧtӹSo`ù3U; =B!07dCRt^ċP#&ɢsXxB[|z.XZiJG6}oŒ4ׄv?Sޤ .Yv:[)2櫷*(tEC&IO×\i&-x y#_% Q, eC6+lgւC$mvqJ-r4F"FAi%$'ƚwHBp&_9v`GFJHhollҢ^pX Wx# rȹaLe im!(V8yzƑ#8@Z. aBLq7%DbA(~s YP(ݓWIP&RjMRE6 9wkJDZutVsLmQc>.Y, D5 4bTgʤ4FƟH H :mti쫳!kXdkd=]%XCNz6NwnOCoܣ)dP=ZS}ZQ(#Dסlގa: K/BSBLɽ~p;^ &vIjT I9ZJ1mB,*TyZ,DҳobKS4Kp|&@ZM{d~q)ifQiHKdN{ LJsPQwؘk3h`QHJӹtHѕDK%Svhxz't_KTRKP\v˧rd =Ҹ7Z7WhIתm%E6VKu#::/_|kѠJCؠ筠^ 13,c֠ -tOҠd2%2s8Vy!9hSڸa}2gRkiCFgߍאĺ@ Qqlh8j u~غ6[4`R>l5$3Pz3[>wyX Y#4È+;w$K$;D> RyE|gU}λ@(h0"+i\}ĤgPϱꑂbn.bk=Dcj٦v Z vHayl5 72GHQ9,!4nu>+G]%ҖqQ$ RrMѶ*:p&ZJ?ƅ̓6 =T@LT&O#j]3W`M3a9&c}Ξ[ l6tx`U;ee rW-5I^)\Nț䚏#.chOv:m)ɦ%2Z')| .1ie3SmԹ!z^Ɵ|gҘ0[x-W+BlnUB+d obds ypc2 X1\8w픇ε!*f#QE$̐HB@q'HhA0˹RƁ&nOᙓKJ IMȦ"'brh{,ȋ$}&8t\)ǝt@ "x}Gn޸ICa13B[)%q{7%s3uZ/>KL;BC&Py":\AB6:_^oѹ+*>vEl/Ľ A?)p0>2IƔh*%4˷?$CBW&*sĘ[OU\DBk8;?s/ _l*nݾU<b&\Bֳ8"KH)w;4C,̇X;.m̹_ V/ѹ>Żonc{'J͛-[z?r0w޹MIKO2^y O×~4 2u!HxU+8{fG" $T-5p59b抳1+DҞ`$KG{ax<*&2 La{uu37ۼ!'3HvL$Lo`.N"}}r"0E-t0Mpm72v\^[c'HcLQ}4*w#`T榴1"}!L˄p*9Ip]m/#J"pm"FUJ+.&%^1ͬ Ls"}yXMec8ԫɝr^Hв[гWIv˿iI2Kr]foq \_yx67Gp-W+X_?!Թ:?+۫.^E}~k N*n`xM(m'WҏbK$ ;dCUNA6=^CZ]^Eß**0FW)ܿvbG@iTywFj`1:=l?;kb950]g`xsf. r$rő@D. i7ع7b-:9` hb)dS;Ȇ)I IC7m昜Tv cI8̱] 'Z8 m+H*#*$^c~nC)Fr m!ٿ BSM'@X;.?s8sa N}4g{RBe(x[$^xeJN[pı3?mxpo/_\ 15Efy=cq p\ᓏ'._Yk$z*.fD9A]3b8ؠg! Ŀ"-ɴ6R;$$ "F& 6#xw@6vn͋oD8~q ӄ:)vi~'VNҺuB L/-ouT+u?x2DZ|jJ#$ Y*1;}#y-lmī_. < =5,U"K;оumnޑFm_9{vobi,!>cQ^V{l­ K7F ,{M" 17lGBSk+Z嶲ӱ!aֻoy{_grl ƐM0bA=P(CShWp!p~ܖ& D嫘=~G`eBI!-t#um2\8C$8"`[T$#GnYyzyODaNХMIf d&''&C[& !",Ά(@ܻGC7 .2{PErj,l>EZ"Mm"{"31dc墥)|He”r0c#}п?A@9׾:NQ={6M̔ʗ ?NfO6wlahB?$4? ?x_$%Dgy O?{O\")qqok_'W8$'V7qIl}ǗBc%Qŵ˟_{M}klLМqӄ8}$2aFA舔έ{滤r񳶶Û.v2Օ˔̌'ƌۓ^2@l4VǷ.3ߑۖdoϹ]#T@<&ͲGk8^6Q$"y0ʖ߳_Gn: 3¸g8_[]*]h1h 2acI1&&ÑZlqi2ګae! ‡"NO8gk\qZ*M` ϟS,X5B=4 Tsx>s yW@'dU_ěG$AuVIDdAgZ΂Lǝ][^kh7e|]pS_ pY(aEn޹Bgvn- E.R _\Hs' BU#nVj()tzԟR?AA2c >;O2BL6qZƒ$/h;+pLI$7H#Mצ0]i41")`S.fdpJTSK\OZ轻X9,lJ$h{3gpɒF9eJȵUK\B~L+R 1-i:ne Stȼkmu{ y{} HE$̃2m)fd5q}XZcMY#"VrM+e5HfhCʕR,aWp"'Elu':{ C?kg2Ž}r(i8rz4!m$4~8Mܾ!aa 8[Bkvkv.`ׯFz}JʭU|zc=$djd e uƔGܓkLh¹pD= 'ṔCs @'+/dt&g67t8u [w6􅹆|BGIޓInBp7iƳ9nb QNfoX92nX,)$y>ȧ{LCIT)ThvY7e0w~Aj4wBq΋v AW4$E)r!!7J;{d{'H8N'6~Jε|c, <͏ѹ1PÉcK89BRqo?XLJWGpLk:}2 w(!mE.VJ17SAZqAZVH{CLG،<$~ULgpi vbcG cz9M~i$ ˠ ,\m kEbmbMʄiB鵍~LzfŜGš9,wpP J">|c>1B_ }&>yocqpX~aoa]mR[@;.pSq |9 !OKT$ӧb>!:C{!M{"N^;oG8J+)i960NܤCАFxs@+RI5VT:1t5)#$3̹Ca"yro;`2 4f|B8o/\XVr}_jPeYi"  L +GAHnفGhcn"F!4ر"8ԟТD8 j5'8;$x/JfQm΢nhcfi+3X[7YS:Q~bN~p@aĭ6R! K +wѨxy/:Gp[|sgc^~ 3zo+PǗCks=}/<]my3ǧ~9mqФ }5Wd@;66o\]mnIoypC_1ϐąCp N%x@ȊؐM8 I%Trŝk xGpaq >[Dv- i}7)D:a$]XH{!lFDqTܘ.5;DC?'f#N'N;CiZFRwcU | :ZFF;0Vvw}pdl߽Q@r!F4AԚ3{2Z'U:y M*i=&KtX@+|O.@Vd +~ND@Xsoc5OMV$g\ϱt"3w ׀Ԃp Ϝ]^'W' ӶJ0B:6vi~\_{H7̴_<~w4[/㏾)omT?cY¥B6; O> )x9qx%|cܢ{΢r_{刴rvz9hỿwi-Кh*>\DL[ƣ6ZB9JK#zVGLŹyBҢ71T3f2%3K8Ʃ{J3\KO@+[&T+%e.TK:~L:5A\-L\Bn@WOYsDfF|bx*DF$3B.O=J> d}p;V6sG/$Y3zC_cyxƲaS-iPD¢>]!Hϵ]lmV Mړ &ab>d'Lmz^k9Vrr6cqV9Ei\3>,ٱ%-p[ D&N:%aHR6(l&Rư;Lfфe_6c0\%b0^_~"L<姃!)n"0qCze5Z;ZO39w;h6P'0{_sMlm݃Kh,$R 8Zol³:6'% WI暙 }$t8- h > #2AUPf* !}G=~kQg7ñiacmͰYdfC/'LE?:Gr9 9cIAjC" RTd͊5GIr]_Zrq"Z}.qvYX!\rƍ4pv^C*tlOI%r,6vi:3mw۰qҜч--Ҫ9Z#AɌrLKjhsJ>w(d g|M'ĕ7S@ {ǝl w'U`BOkN'ƋPZp4%ð!67͟FEM(e>~G,+*|8OC˴ eD!;d^X̍b xc.K531u1?v9$k1#^k(3pf 9RD<}V֭Gty_(+u;kdU1s"3)myreL;B)0A|ForFtے0 )c^4yH9`WpijR`K*'S&ٛZǔk>WU-&>W%ADFeJ*T}cχ-ь2ak@@UJ1Gi qM 1RW...J; zmjd\Ι:’&WYĥQdO.\`+)<~Y%yƄtZts+=O] lqgL£\;hJI&fpB)tFP;[|ąIPFC%*6:Ma?rd׾0 q8lAn]n^s'.ŕA^VH_ -j~\z84/k9Uׄ~<[G!xi;E`8+̳rTeL\L}9P߂"M 2g|6Jōټ1MNc$>]"JB;hTl%ϡTMؘ4:bNYsUMwX_@4IpQ-LXM!7H4/LQ."Z7Gcdњ,7ϑ*J".&ESFŽk}ch@2W$~AFB ݰ(} d MFģ6IjL&tI53E'S_Cs5&9o#M=nǚWJэ$0 iB4iHJ]Vah^"53O뒄(@XQ4Q4達 2 "$3ji+R 9:+H[]"WSIt{nP_sc` Af( g31(,ZmqZb7c S:ٛٚFl620"@{'t+:86Uʍ8\)apPZl~R&+BӭŢdFua‡J0.7OX90],/J͋c;2 %6䦲(ݼlP{eS#?P3HV%pO26O=EvLq Tf4.MƬCd.$Kvq6{SZa{KcE. a4w< H2+[-V%͖5J: '&nPG6fu SJcmܗkL27 c.nFs$BZi䑣B멻  2_/#aJ1%LP1KiHHsɼkЋ5lj/V@B%+z =܁X ?RBΪxz4dב6 >*4טI'+4[S}W@I&4ψt`eqtŗVuPOƳhNhgjS rԤLJmmJd  ҤU)/7 H1$%ʦ͊+LM3" )sќecZ`8A9s#dUyߤ(4 lcM՞wM1OqrJ,~ZC'R;h4}H0*9Wup v &tZ4h}#X"H5wi]&Q Y!@}uĜ2*˗ H/!eS6X pGO_ m~N '/ͦyfLB\;Mnˌ#EpIƟIJh畵5o?GRҮ4׹DBf6Nwp+Zb<)lTYG'n!C\X4%3Q5$\w3LO }>t-$^Bfn,:g_@ sJJ4ff# :U'CǹՂz;#9B\<0n 3L@ѐgցjN4DPMƦN#Kg`BUA>~>H /'Ser ϯg~6Ngi:#r im/T>\~~p_IzM%ٞnsVTkm;D7k;`u6x;x@25WIt, 2>!uLT52 Rӫ^Ѹ"iYi, i)`jj`Σ yٔc!B/cL]Cd]̯m4D%uӾaJN r%tmEќW9&c%Zob0V 7hPE tofsŘ|{+~"/2'tiiYbjxCaSޡHkzENed R<&)@Ў^_ ITV'cbpd9R1gpKi-LpSn/tp'W/Z3`+} j~^T07G !9* Ȭg~A#pNJ͛"uXq;[MF8}]cd*YDf32 GnwPP|DZ^ݼGؘ)Ѫ췊fDKnZamj$  $`2ͺw̽ &!Eyn0k̺v)DIŃdO綘m~r `;\h?8 DBS:j_5KAK,+nZ0f Εܤ@"Ez(l"㔔ڙ,ʼn ؗ'^d`aa QIf" , 3``ѴjRaHԬ C'dǠq>XYͨ~F̐Juu c"*aYEy5X|CL.=^;s\q4|U6Wx&j+֑Ru%LFh//b3K"̳A[hwKh+0&#-ce>+MIgN)jmgG*QZ :}= G&3>(&25T(@+ݟ+ ^3/"l ٍ\%Vw5ryMu'73㐕_;xK2iK!:Añk밬^GQ,$_ead:FV+ tvS>y%dfKT/O D<5 aSHOGfL/Ma_ 5+Sx;Nv$/r#o{?4cGZ\ܖ7EծgMRo04aI8ߓh"?UKR4GY6q'1Kjޥf} pB:"(k}l,̠7U)?T : Oμ|(㶀&r Tf sRb;J!=EGBZa2HjguLZm֑X1_e$¿?N=L9(y6;5k5q `p3.ldE]coM Ȕr8myQr#`&7H6muM"3Ckg3i4A/:$QN緥FZ @TcMXIQGkr]vD>db' 65,,r?4hlk˂7&FfúbyE>OMS btTRm~!'z_{zBpD,3{r'n9&B(H"+bSEY/{丘6Ҩ:(S+@$,T,4pɹf\0͢tBik[9 3Y$#B IZNmSImHeģ"÷@&"Ϙ8ջPԼMVU mlφ1<00+17y8- "5az84Y^5">I7Ѡι˚k+m 䪡&K>‡rBDH",7$EHʩ#[?Q=s OZV`k(6$ En)xrGcW4q bDF@qJg z~= 6]/!M4qk!5v^x>| $qv0!D,\x^(H!Mh3?D{Zȩt xuR#Xigi[`v~44j"ovE~kj }͔ 0(q+*^{^-oMNhFHveF[v{cGrWwۜΐ3rrWʈ#فV`@$y<Qd~ț^ g8M"k^]]~ID׻׻ד]jy N=u2!W-qyTqkfnAVD6qE" ZFsys7 AcNgVԤ(A /9A|d }${w~)wOJ?ȅKU\'-Ypi'ec[U- g0I'J9 1a<͖#>2><EL8藬Fb'BrdȽPi#SP+D,JH~?r,vMY 1+G\]Rz@1`*r9$ uRh'z Y4u=I\WW8#XQ$ >2k1 Gs ܔ lmcV[ E7^DN\bEu!P7+%߇WTPZL޿ү5A+Q1?bM,51@ޮ ~@ii(f\M@cė[u$`i˕FDЈvT5.})v?sb]2a|mrB ݼeO\~3؇. $'*"ƍ ֺh:2vɈJ'%fӘ4L!:k#*:[D.&eŚ۞Ȫ+Wv=Ziz|A)\LA]' 8ޒ\ʪ(~~fvøGFRI dq"U) mBLMLy8ClDE?) &1t MWv{┽?.d,y':@Vt7B8>x .Oamb(G~b'~% -X>&}SkZ[Mr<]ZyeY8a(*{EW&Z\+% DYƸ; nɫ0ۜsc"/TPA-`/-s%±kSنJB7;}(Ӱ] noB5J;UBw*v:7\" z 55%Ĺ;bws$(^0GMLa1ES1^Q -5si{xF>Rċn:YYb&6:UnH:E%% FI׺fBu],q.e9 jba-FIܢ*qZZH5\<g*]"jUZp!:#գ !']uD(QQ])'B;1H (K$C:J*tj=ڲl|h`31ى7$5X =/C–EBh}b>'s w^6`iɳ`bV3HX*H`ˮ_Jq*nH1ZRZw8=2oيzj;NKD>7@ȁ%&p@,nZ/Y/}"CX(Xqknِgp7iX[4Fq8Cb/t;,c$R\x- [yLkS%LPKb"ij %_$F^L!*boW'/L)D&D?6 }!CS) O_ Ja e^Z#^U ,,41Fpp]H{kW_l`: =_I*K-1I3XCy1h]`BM! ѐ3$&.eIBHAi($@KToBb*Un!^p]A^4W.eI>rQN +x"/|(=$)⒌`V/7Y0㿆9+5_\Ę4Q(%j-63 7pr<<Wvvl9.5NJ>j0]x?zSvvLt]?%aV'?tJsOV'Y1[N"B*Z>%}K q-t&⨤kK`ܶL3*vtBo{'p蹣 !؂.%…$Uއ:ErFO1Y9慾9vg;t|%S"1SKR5%%@s2?| FLcPm[eS4⤳xmIRj+Q>~P/eA| \b870„]|ƚ-aur7&̈́'10ɽ%^Ӱ"), \d$B?ؤ"`&T1xQ'gdGDpϗgk,:36 1H"Q@Ju-4)l{˝+8<>ԤNLpD1cL#SJ,XkCxz\Rb5bE;`\t9}Rr7g|{%NGdI8'e@ S(ʷU") @.i1eAE(cAN`IAkV<*N8NBHN28Yqm .rz?A -feUMsЉx$lܼѣMdA 4df6nS)Ʀb$ztN=>\tE¼Ҧ'9Y6 VUmY*#"AXhL] H$&^dRH]W+wZÖ$fߤ$ުBy \$D1>e׃;$Gl w%NfA$ 8uv|gc>}Ωg-'$ eK\֋~ɌӢRNzL+j*m"c]`x_,hF[~U1P#PX/DLU.[Y#ChFT8U/V s,0n$bDFp)E ,&PH, 脤zBm%4/0bnܸ^06 I3;{iHt}6qv>=9xt6:Lu瓹^RbYTv茤LϤ?W+ ϻ^ tu0V}Ws];`?-]xw^]-l=]˺"g16 \YXu"8NQBq"e Ò2ba%(bNHT5!eJ;QrM\ $3f^( d6n1r킡%Yz@01s p2;fsHpր!r:4-=IY*b@{6|%0 yB1:7)LӹrQs Xb(`h-gv, %b(}9b /\ߝEvi4mEzShSz'S K9F"r9JDGFz;S>yo⎔ &)rЖ K6Wϙ{Z`}u0OMYXDt@J^iiҞn"Q@{RKNil~ .2Ze.)$nJ 3"1M=U۪ÊFAew.ڂW(s 9:uz0X߁p/z{_,3d(ȶJ";7҉HJQ 릷ziL=g6Rvc­$S"+>H^~AW$Vr~Y[4Q4*GrPa(%+D" w$#Qk̢J"R$QlW],O ù%'XrD O;` W^gmSh^4Yy&C=Vg*3v+ɍGÇ?M/{cOf`)sHYց^6㓜5n"}+Zw"'u`UT"]ŀe*5?ǒ@x"@A?}ڊ]i\Up8:G"B)A2eHHBÐe;#WB!7c렩ѥ'\s7Moc[p[p߆mC0' z asg cQ3-Aki|Lh utR?;ʪnZNp_Ng)Ӿ|+KSz* h{+&[0CWBI8C|-)'6D. $Ũ Aݒ&:ӁcWe\W:*ꬿ' cTo;_+X%LhbkvD J懫_E‰eq`Չl3ަmB}G?!̋62G's /&d]]'Hc >)`g6aRqPne%I]qwQUɪޯTJ?Sw{p3&(R+`QB" X!P@`oB=@$Z}g#8~;]x|,p6oAGVP$A#bS 2f8d0ʼnxŹu~gO?Ï>KSR6br|K=ȷNb|<>-۶Z_ XҦow.D7;@`VҪ,Y1@ۤb10؍S4eE; jD ?7~{'By 6\{v_}6@XqrSy -`gا)5BtЇ|>w>\bnk Ċ*1s&zO$UB8*=d׏_I DO>[ y a VJ\]g#V)刺Uޯk+p|WVp^ }Lwn)UX#j7?UXLn|~P DZ]!v쥑'rsrAnǓ{3؂39 .=[SYYĺRR\9<z_Ӈ0zk?O?ؽ?hΉ#AbҦa%ܥD0?B$KR?MiA#y\$gl"A#[N0\(' hr%MyuUr!I5-s'*ܖVVP'+d X/cx~Zr@q|ׄ*L](WR"))}"aAbiRVbߍrn2:@d RH|?[R@ocQ`:j?o*O9`msG$+o~|[?WZcrauꋫn{7o<%Q ]N0r̼aY"*͆~lt`u~j¥7q]^?Sy)%!c`5߸ڼG)L3R{pp;D8s#*/fd#P )+ݽ̝8bu4PE|ReЀTS/镔!"" YQϔ̦De&|RY>hlꖚbEw8NUϥu|<8mדIsz8'Ѡn^$@Dt` :8Cin S˟`m!JJ 1d8elyh~ nEX \_b ߣDX,$YݹH8A`V1Srg;š%S0>>#O<:ts/={ cF$oYeͅ;tG (0qw,` )mN2R['/gڑ"Ix&ϕ/vn'Hm25!#]v^ךumFʩOR7$@ h/oU8DNdqY%5-LMn!Dm E`!mlno?lKaB\o\yXD*!56y?ʼ9GO8k>‰z{Hjx;Y%Bbn e.JgOz谨XRZ%jU,.dd1{ \0"*L -I )H(U:6ivʚBbh)ЛDΚ\Ng hC8Sr?ۄ7ύk}0 +q_"u}w?=3tbe\&H I<ߪZhSZ**SܶBov|S^&#_1y6)LOɘ.fS!-+pl6 %N`@d$ZϮiu[(/P*9KlRxLY)Ě85;U2L~ۘFrM+_?.n@ANJ1VBEKa;f-׵NNFbb濻gsckoł-stYs6x/PUpjn4}^㶝3vym )) ~ oؠZfs?5w ^FۄW`\t^?$D=`m&!$OR8Eϐ cP8ĸ}ď&|[)US SkjRU4+?fUKg81.foL> ȽG^> 糜zB%#x&}íMo{~/˟y5wC-غtS.\.߂W0^3YWzF(tse;Ek&Htch T~u.$Sڣ"rID#Z!M&!ۢqJ9qFN+*K)x@ O?I<UB|&H2jBe}7+=>t鸞&NЎ#$ơ+'e dddo X}ܖN,cYCj[REXŞǧJbճYYۮe4n2{DV 榦oZ:Ke<Y.4;e// tq,\!~|ˠʅYi!EeNCbτ/-RzLE9T1vi>HI&S[ZiЀ 9]} vd%1ƭ4&JF _6`XI5KF2O;@B#;q'ׁtkT{z ttt؁8WFqxʿnEP#g DZ׍LXmVII, ,5NFV)t?EsYu&T!RC|ףf2Ci]sssF\ͳ"jQ62cM* U 4͞ᾚ AK!UaNΟW,a0 ӿy*qsIXg |0U8}}_-2lŵKSl 5'L^ }|ѭC@Wd.~>deɥ(:"U_ww7˗SSSWQњ蘐ʲ`n7ьN5aCÓHy u2hӥ=B&_>&DY?)3;OcOײ6`6s8%$.0F򚚯c|V_TҘU?} F~"+r5~'>=j) հz0cxIG N4A,*]b>5k;8ZLX\rW F,.sp R9B9R ۶p t-. {وfof4.}J ؙn |D(Y u_ ( =waH/i߯Q6AD73;{C /Yz d CaC$w=#D߮kwQqj /,D"yRVs̍9I7*m D -cK!+O!Ɂ ɞJL\ny/nZhN|~{Uc~#3k4^zҾ[:At~~^n<=Ǒ;8njm%1$t f4*DIH7y 5(E~${v/X8 B(3n[q=D>m/ϛq;fZ4P#,PV< rUU8&}j/qgw1b-66JWP3lbӻ H lHok_D:K輼^gHo?n}6qҡ8 ìcRI6j)ݑOO^_"NWIGFN'E‹@UAJɜ+,dkݷG ьbE5Q$sqlKU(UV#B(E BNNFF9x'8|[cL?/6M̔lJޭVaNYH47ˉL_/;Ae֓3R݁/?~&}^PMD Ȼ iT)[,gU.N$|ؾN;* bSCc]p[ 'Ixd'yk` v<ō2€"Ƙ^{BaYC?95vcE?Cs9D$~`@swݮ73rV׌Vo/Jj-s4;Yҕ/7DE{-Sqsrږwe~~G^ N+H/6$jdo|MRufDntIJט [9L$'+ BO] .vҋTIp^(pn%"LwB'gHƜ[9ʢql-B5>>o[ÿ~ <&w=oVcEF'O[֒D`/`vL^F(ҽ\Fu6ČG bԏ_Mow*ks3v_jyl a6 e9KY. (2p/j  \Z{}98rv}n k,yO3b"-7@ pX6"qB/213Suu\0¬R՜D,P>ꑵz &󍯉e$@/!D.9ux|jΊ1E*\A3l|Ii֠AmWv~Hi?0$Oq;!kNsS;21G es#!猯 |ZjeQ%T1_$ZxBz؟f؄b7ΟsJpkC{fqxzb,Z62"2bvZ6rkg35]// V[d Kƈu?'(,Qx -1y϶g137k3VW[;R:Tk&9 d:}F7c5 z,zᩯ;å֢l$0=D8UyAvL 3(Eev+}XR) lXGh 5X~JXY1,k2i⥭qA4Pȝ< P}pv*'yx?Of!|.ժ(rm+ zX1\(eo'^{3R:hӕphq,uCkpCMUVD^$$$,XrrsJr튾o !C&-j>hg=i\1?N{A!![YqO;ĕqVpI3*9yxhPcǜ5kg&jkq{h&]Z+Ƣ\@"-.=ϱHa JIѩJo#/ʿ=lX0ʠсj%*@iOL簺&?}JE|IѦJcooO GW{B&wָ{pt( GXe|ZtFTӆ)!$@x t`WЦnibxxxBi&hQ?~6/v6.28y~V 1j}Ȃxb/:z&Q dT.bRJ|$E211}z\w4qy,Ǹ]ȣ!p=FwCN²PkD4V$q[_1jАXؿxla))+ǐ[iibE0#*'ŎWO!~bAdt&Btkjɫz)]do^@W o?:7-1Ȱh6ċÖ> \W2;<*a0õM6H?>܆#y6VKy7hgڬ0ҥ}O<nnq ~ZD_jEL qtƢ{oop> 羾'ɐ{(d"2$sĶvY-Ќ`J1_eI>YX%Xdj0Yun%r!hIPcb+$'ǔckjj QguBvLO-gO/6 9ʸ:ՠ8'+T$W@#""`s뚚 _\_Oi9}Dx5_V 6WfK geXUNNlDّ>jhht~){TdOZ R-f*^,h./Fw[y QGED $&~AӢ5yw1j= nԞ?t!wC`ik$9TC?K7-**MhF/B6oٺfZS~B G0LȿYx{ i5cT#>e|S}渠BM!FiڥJ|tX aaaz6SMȏg?kjjEEƢ g}":F7$L@}ݟZY"ؕPљ%2gq?"ȗքHT,d xlYvcOʰٔLפ+M?ʏ1dDxexL"HRUbK-lkkŨ4&Ą\~;JGp%گM Rm|S[u (}a*3)gۃYjEXwI4NQmɴpc5W%dl\@A&šeKG;^XU̷pVxWI>QG3OmOAFԠ0u䉟2'BiUo\ڢհeד%E O0^6o_ڞ>ⴺ8G,)hH/n,iLp},Vfd %ҋPb),/G%ARXEҍPRE@o8kH\viI>]@IȚTĴP2h!eXn-0Z^,KGTtck$_3!tUývc8.exe[Mi; |h*cef$,U}z8h ueSƄr:cN+!c;H"nvV;= <8{abUHo*U! +!F\կ/ZAqk6я/>ŀ)#؁h?[\rZ@ƃadYzwG, JK񑛃( -<ނE !e- <˃tšHʊDIA ޔ`X7ܽ|E^ƙTCbmLY}cAkZBq {r( DS)yy#Эb'ׁ+++C]ʍ.ŧž,hl$~BwGݚ&2RG[D:B^gszDdxg?@¤pJJJVG[YoAew;1x^*>hS1~M= 1,GICRcTŸZ>F;  umCLLkeFPYN(ҕJf`I [$ 1GBgTܓKԓCrR*gзkE B6^(T0iLr"brXJBB,T +Aϟ`M;ݟ񟏠j湝s(ItZ::X].NN\]]yy9'!4Ecee>+,)R=a\'ίe0,6&R]w7u%&&>~$AsSl͞b5Ûp dvYP ɞj^ 7IT3i {:!m⎮^c!KݷNQ+`v5.FtQ'vMzB*S,3\BM#.o101uaL HlFn*@IcLc+7h%|Y/& >V JmzxLE8v<6iKB &S>Ӭ$!#&5:l=y(MvR#3C&  I9=E χL.,jVFG7E—+,` bfA l8[|" G ]j^^^{:G>\j8&"|LbB8v}V(f@o!<=3;X5BC^?g"-0`CT>hMV^H31++8G XnX"=\ŝ2L5 kR+itFӅȐ'oQkևvqKB6Gڊ [M|#eg ~~&}7,4`iB?=.njO<>˟HYqi̽ MK_>'jL?BϪ$7jkeS.@f㤹ZO٢^ힻǮmqq2TTT ~ B vOWW?{tF\HlfTfOnh_!^of_X|Ӫ!uH@lnnqjRf!;]$U*~aTij_cX3qU+NJά}X@=h.˶}Հ.a]]]~[}պg) I3^woNzs{&'+*)*o?Pb7w8Y(*ӧ[LFZV#GcKGj$x_C ߟԋȔ?e: ]Ҹ1ц/_d"ek5z4.$JD@N˻Ä() 3q|Q=$U&Gg*ϟD6W@V!gǸ2޳fyVڙmx.A? ,uj'SE=Okhi/fWLFAʡNNjf% "!,H1%88-G\nʌA[Ȋj L-|$b(XK,Sd !O9ZZoN]@}=*59$d:&Shד's#vN&eJoJah|H:!lO]Vvu uq& D#T)VB-p& 719e/L $sb6)qY|.R^s(m/kTa/x/:o|hjU9Rgb`oOff j\:U+HW`!6pr6f;[oaQ=SQs]hMY|5B.hHIC-/T9#H!;vwёcvK2]". cЙMl@@GuJ7Ϊ@}ĭibfok1_cacBzl"Ų"إ+cB{҂]F`fI¿k;烴}뛗w<4  S`'5X#϶V:"F*:|- h2udQ3>30 (NN\Iԝ#TLyRamp~iMM?D2FE}NMIW!71>̼V.U1s%00PTG2po^(42Xj1bG(XcA[ق/}(tBY@{riAQٴ" ;D`B,'hWY$?~_ı@J"f!?`|@s a5ދOi2x̒;ؔO;;2HhV mclyrv9we'U16E D^ؠtå֍9#(}b4ΙM?'qr ~۝KOOGy7Ϝb_[eҡKğ0EK59AtmS p501 oJZ5*P`'pY4E۝dL{IR4//g賭T%f5Ĩ*^=)Yb5(4IG.EXin⢡^@T @}*S'1MMJ"bnS1~ kRo*WB@iKmUGHL <D>1G Տ/񹊺@fggG>5g:Fb|WfTm.=SqK̠/]CnWD4LkahU$E XƮ4y@ٿd;" vw +Ku@V"TL&TL~:jk(g, ?etm"O)!K {(zꄃ4XYMB  vgZBWRU'*J8_yxԴmO;#f[J޿R)>M4*pajR8gf -u1kT4'}'^`GkOMf‘YM;Xhȁ2uh,46ϻ=dpWkuqJi^n$B9011&18HCa^ iC̆ \ [d^)HWs_-8zt,gpfϓj:7\ZRowI[Tsuo7 t1!!3*om#o * ʵũ6P'kf+*'H8OCVsWzG&;a-%z/ 184_crȟ}J`z#777U=1]yh!>R[9#6UU;QMlS4wGȏ=l>jh2jQi&Q'Yj&k)r+Dc͢ Lfn^j`c&$-?v^miooo/͎I8K-!#qԔfzW_wtv_HT ˆ4Gm\ 'CRlN+.{F۬pPz:Nr}rO9 5b%tmXat:p&ZIYy"Sp&Z۾_W *j]=w=3`0XeDZɚm0,Tig9iE،v/3H~ƣ ZU:q:gogϮ&݇iof]l;z.l[$H KY.+ "9CbxF! ( K89 M>pW @W vd\`d5{-2$_7.vioV*SO$#[EoR*V\?w 8e ۸^8뎲ޭcԎ⚊IFzt6n":f$Vـ:4VSwj6̈́D!ROc -%[ %Jih#C\ה6nm|s w$rSF,vMoҮ=[bh-q}>1씿?ϴWO_o͚>@nFmC_F(x),w @$ގm,)ii$0G>xEͺC召ٟ\Z ^\E@zO1 ڹ=V$QS~ vo;墤V`kٶo|eiF,pь/?tjS)-a`]Sr(+z|`,b%"Fbc ’>̹=&2ڬc2[my>v<, [{9~˻Rbq1la)`;Ŝ6uY5T$t☙ڼ;e,@R'>]Pep|_.1r"wbgcczDt\ Tl::ʒ錥 z[(]So|6#?T}Lأ;Q*'+w¸.s&#찺, buG]mXBvجjj~C_ ʡ@{Xoq{t39wGhCX?x*ifClռKJ8SVصZQE;7&!V]q:",M57z8R4ו|Zx)k>=So8p Tss~%Z?w*|OYM5~JJ6Pf8oID guB-۷!!$_{#ˢek ̻Yq$rĬte@%}c+{X%D"T+kwy/Y(ʽ'8 SMk22Fo;{VvMcW9I|AO/qEИÍTJ;ˣ.hyԀoyxҹ|Ӫ1)%9,G@Yӿ6;/ B:{p!{7Ðo((5==`*¢lFm&$Su a延/2A?1SS`L]IkO@W 9?3E<`N8HJRU)iBvJ G_f;0PUS[֬$7JQޘv9'EV1E3 :2ڞtp♬A>UA@[}5Dֳn/(UEF&Ck݇⊝(YM,?X~Xvݘ)w +@;҈!.an/); C0eŊ@{l99.w{C2-&!Эep-98RzRi=+9UA4; =dUI)x:I <|@_Fch2[GOKYsi@430&hʔ& UhPŋ_pු/Aeݦ85<['ҡ S} 2rBwz*QC3Ā(ٻ_ _.1JDnd}&&TchX TuyʻՌfe"J3H^M9]Z mTV=Zd'8P P(D{ YBCA.3 SY\9^5瓵cIU3`Vde;2˾=W21XP9/OXY]$Jx^}e&贁 O5䉓GDM_C;Āiqk@% xI_Bꈐ$?9&ыggN#Q"]Jor}@F  @^zyGΗ9YGbWSi I*lZ f49qfeP( ߇$fu'e\_ީ}a;HaSٵ ٲǶ+/aBkss 55EСd_fv)jO(|-miQHaThoB|tV?HLi";YGK_i3Ƹ::(a/g܋H 1 ?S ̌ y,s8;hոPo_c\B:LT[ZսmمL~O.4r$T:IXt鿏uMn7YD]) sOҁy2Dq})OS-Uv|b#xoo s I>_⿑$|{us$әpǷxmFf;O5聵xw{I"t1{hݹ{ʟ>ƹ5Xƣ"ޞm=+G7RAz?Rټ/pCm2xF'ɒPӒ=O\brPICsLǧ,XEyC૱/^X b )h0.#.& ˶þIukӤmBGH 4:?V:,BMlwYOo~$4}WVḦ́-#E?60pV](ދ dC⎴ӊ<}h&%c b|J8 `Pj(v<.sBdn\rIY'Y``>pY?r6Q=ǤúQB{y8AF♅?u=*D=H(s_e1[t,@B`y6{OH+62QQP$)c5+]8;,9?XЈﵰ$!8.۪MwP!ݵQYߕ|3B,KG<>))H {szU[BgPx7[R!lf(BsRhBlDRK\fe Eo#cwtѨo| `"4v&xk*ՆgXQ+}"֨Ĉd>*m)=<ª/R}X;SDǛ;v6XKJZ݄`% & Ӿ<^~.Xw>Or1T3ȃ.Ά^Gc*CF_ ؎\.h1/0n2F&2>rj^ۿ"u뜔'z벢Ejܺ. 4!S';j!`yz p?ƉmR6{.;Ob?m`0Wu)Yt@T*Y@>cꈇ6݁b ik3J}>#54ୈF-3D2 -fׂ䈌Ƶj6#P_/?yTydb,h2d/>|f[@"șV(k:MҕI@+U@؍3sWcLqC1/Bh(k-4j`LWZ{>}wM+i%J ePPޏ)#p?>W8FTګ98FhMrqϓm}0dv|ymG O;`PYLA ͽR$$MG)?GIMNZAU ZJ?ࡔFrHAئBx8MCJ$ i")!j[Q޿N7}܎*ԹLQ켐ex&-]gF4it!~@y J", By;̦RBvS}í"@"{98G+I  WHnj{Tu~I-l} .[GL22x+K Bc191L 25]ԡU^q wygˉӣ5A^QWC4&nuۏ3fL.`ƃM}RH\TxӴ `!"B*̪3Jh-|ne> [ (:H.8.~:ܜVZ_KO$H&/Qpz,H2Iߊ/y݀OR'NkTCI2qhKIq>ظ! aUxGm BxviXqsׁ$v92DbڝL>i_W`#}?M!My;FK4h=.ȸ)WGtabNUQ?#Pl\@<Ńt+% z px*IvcכZp[ nGu&Xe\ۥfbdՆ6#]'˄dX3`e8ndWҳ|bba 3ʤETjL.XxJWe^+,Jkrx2ZcMY[C z&#Xm@P=CAΆnVX!ŬR$vumRKB[~]ٯ#{}# tMtlg.EsmfNLib^,7,'#f[/Kw*{y nD-l)9HHVAx:\@FWCk Ny?*jVF|7|kTXn;>?RpԌA7EM|(-js׻pv Or-n>ꭹz>RTФ{%K!zyp!Cg̃s_ɡT%3ǞٙS.}L׾ybJ2(<}u2睻#ц>~/M!z8E+g.q>5oZOcuPxtPN=7-etUP`zEɷ >8˟p}oX[e";6] 7/ZLaVޙ,:#t*vҶk-w1sj-EAlO㔽g[?owj?h"f÷nZ?y:WlvNP+|.CBN얞O3s\{>'_`Bg2 srݥBІRVy7d Qrw< )/PWXvyqd)>F:Q1G.J Hl쉒#/@h3{StTYX+2\VO8^Vi7NBnTO&y}qg5+ kF^jFfIrdibhI{?%t@\X3"ݲluY8= j3|]QI )z ="-d@8jH_!C;J'(?3V@^4!_;)z_P/ DL6=CAj@IG%u7D{g]C%Ai FdU-C񟣍/1m#@+I_( GݖQ$NA!_pɪUB T(4=4#9rmq2.4{P4.mր!eg1[)L%6CI؈8ѴMGv.A8L Ud'!X,o Bn[R<jF 6͙C( YCa ٯОyWtXy\''K+QȾc) !Ӹ xBhEDDs^Cv( Հ$㣍MuW@(/όݿ.pn̳+ \jKr+j%Yfgcgc7?E.1"{Wa͑`ngu8؝yd<`Bbtك{)ԷDT°gEU h fQ##c!8[H89iLiw\Pn|){L ;z!\|v8So҆l:ybbKbZ2l^=}n-GMR wqƧ,2ȫ"nmN@_4yR9rF4Y8bu < RC˘BXrm|\5(%@zkx{VQJOycd묖|6U՟:k?qGmplH帽\zsIqߧyq2be|sB.r*_ieFeU^w*$=zw$!'_p*k#Ǝ( smOիNh].+(yݰ+ @[kK2~1b;UB^!/Gy zS}yI g@; -TEV{*F8v 5xكDxgݯ~6>ŁdT. Uv$lzќ/]9L{];ie<WKxč@2nDgbas|?j;o 37hy֍1m#Z.6?/9Å9r#iuhAh'[_쳌M? <9DM%PaB$Ĩc ߼UBql+"Qyc^}hl4,k4S \81_$h$/A>I^'@!5}Kͅ[DWÿ,[: zlg]^_>-FN8ab+kjZmgTREy+W}`WMΟ Hyو -@3yg;y;A?zWj~xjzT$N,<ȝʃsk#7p/9JҤߘ46OiS4-%Laz3Ϗ720\W+fNu^ Ws/݆ۄa/~A~MR!p0m\RT01j}zX@aZ`včq_ٰm,NAJ3; zFdIdCCHn0{\W`;>X+rdQۆ3eS_Ѩ#&)iJpP_JdR2~ i ltS(K.?cXځv(]ŦcΔ"&{~_qv<Į}QG&G>vܙZ墥xTXPQRlћ24 yΩȈ>qNNehKm;Wn|m}?& `bkGwj3w=s fT[Wq re`}ƭ6S;fFgˋ;$ @D=._ؙ6yF(^^d(!j:]q[S9xMG/w3LJߏ]0% xǸLhD#`ѼsA€=1f?t%Gd)k8"OS p,fF~DQQz;oJS(МrD#4xȒZ."Ctm :j1KAwb–6x! ˡ\YdQTm_!+vvL(BgxoJr^VF|\07nbsG_=&_~U5;G$Vڭ άRGB[ioHu|GF|\avtEx[-x\oʼB! (GʽR8jxDZ2Gp,Sӧ6X^ui3\d8( hDsdCvQgqVZuoUV*;Cᒍ"-9FXH*t R-fB*ڄPcI nE7hcKo\KKާM̚alؤ ×#O-"UJOx L/S~tVEtej؍o]T61r^ka?j=!c+lGK} lp"^ރod,:>H6w>_<:Ջ  qr[o52hFHW?+ۣepi:ܜ\ڟ<xԜhpa|蝙daк5ãܿ]f~V9)k&_Vra~<"PD,~a-`.)GCC`B \dEt,#7>'" 6kk^= s[`kg2Am_&KCuOJ)Nv`F!RMmʐkA AM (-ԥE %>0;$A>^5L8l%B_ ijsCs(ʶlLG4+FԳJs ʬ{>U"^Txǎ;YxawLk ]GsqdnՆf|OO2py2f1ǏSЀHv(_/̻4 D,z%xyzoܟ7.Zgࢅ=/-gEM61 F'C!|ڭ,qm}|E׏L6%1;6y~bfC0 ITS?sGScY m.W%9Fq࡞Ckc" Υ]+D賛*ܸycכqƃ @TETȷPfb 8! [Tچ"{ iwWt[ r[f4\Nyx=u\Uӧ%BU%OgѺ WO܉m<(?,\.]^!GqJ3%^ <=]{R)hhbW‚GayR{[5['هFwPEOV܉}_*վk_.DEc~;C [zsܒW1P!Ş"??Y7&-İ =ޑ@vWm$WͥR.$68JC=QByrurop%eC#-+m&_Ʌ>Z4aޞ{9, Ix)-nޢ8֊V =g|/$s"JMCgP-'Wğ;^jUP/F4^s[݌)}G{/&)N)* yXg!g_0Reh~FQ dyY\@;dn{v8}Pz-.} 5YaW;tۍUUgHM z*HY[ߌ4j mK[Լ+T0G)%}Lť9U.|GQFלE!6.g ޭna:@1{Sޗ2+?]eK9IYxWBix-'/kס~K`pRMيS4A]Coզ\JG,B2NdШ湉FLqPt;S~h>X?-phqTQ(yz~OvˌCSX59F|MYjaR߶3̊<<)OudzdTg,G7._b_j`TϴR{[JQV&$X7j &~AFtE ;qVȯJD%ki,q=('C$kD 싞HyCG3"1zXQKH -]Vg9 &6+j;QQɲTe{9o xl,fN$li]$S[MbvA4xf=ٷ9!qp">ܥ:k|GѕԊF6>jl;"[ Y+|w0qCfnex-"ﶂVg`8XL}a2}_SMvMmɶlm['dۮ8}`YxHUzHYCPesI "<9$U֪g^WSYa* sJJ6@֬}sc?{rژQltdfՁgp H ĩãʌtИ%j{x8<$֞K$`.yRxs%@AW Sjġ\ xSjKibjeu Ugw~\|FFAj7 xBnm))x1]Vu=x\c ŗ;򱇢d`۵xy79Vgj4mM0WsN2jadWj%YK7+WT`Bv+# 8&@Q9a6Br Rv*Zh%g> (`FQ/ .b*lrzgUw%nJFI_(bxC)y E UBIߋKh \o<%עhFGos~uo|rlbVQ W*uz۔|+M= ޠ"ŠáW^Tm$ux2󦀘t<)ݾݍߞ p!kp [ brLc cѕ+QWYs}¿.)Xd%UP%R !\[ƹ4XE~\MMMgDF8jpW?y ROQoUVISB"mԬOE%:)HW}e"XS=fIxwq^ynYCJ}:F=Y|Na<~}iQn2QLiZ},Ƅ_0z|cQep&ʝp _6E0#y6zvb$J:0pr+ӬLb:}"3e&6I +b=0?D,C'UV?δ-T}E*WQLmu9dܶQ*ң29D@TȀ|AJ;~ӭ~Hn&g5 qnce0Ǥ7cOtޔ>R(u1VýR: Y-?"3&F|?aPPylp*I@-(R^w/B O}GR#OgzbXO/~<*'X"& ^Fl`)V%4"N~4 ^ n:ݧy\WDM/Z2ZMgĵW"J]Ȳ(.Y~?x x-!ݢ]_XwƁy4"ZH&τ9׾s00|:F\y-n1Y^|"#0kM.>,b^9~],#I&R!TøȜ-1S7r0O[w֩IܨuZ1U܈aW c^{dr0*\ƕFگ|w:ƕ .=msS} =sՔGx\YmlZY).RVFT^9\m'U  %v*Xk#Jo!Jvl2-yf69d97 V]rJNq(G)kRgnοQ(I+^QgDqSp<\7a7t^S#JA n^-y學 s5G풽y]Bϝys;Sj\42bcЭB|Z42p $v3rcB(WD"kY̥>i}ny$՝]D1sފ1xK*lvΤiG2f-<VDV8 JL\VUMI4?.rZ-,Q+e_?a< Q荛,B!,\#؟HoHJ6t0H(\yJ$rwzjLf#3WwvV}I5V}2l"8{kqqzD@g@`G-X#^0yB'7[7}q1wd?K2}&ԳpA 4TOz*}t戫 ^7LMN)n_h5ɾZmy8h˦Jq g VS\NANЧ+'\mɪ>U.8YI7t`==wphۜdPl 6>'yTɬ]|c0*,)ςR;3WvLy(b; SmW#=F3:)jW4Kkj % EY #m1RUeu3N0Wd*!ʑ^\m5Y3)^ތ4⿥oX864U$=/!jZPf0ϛрDPX0HPgѲh9U!dРa# or)۩Qޓ@tq/wa9ȴҽԴH&%VQ$}.ih C'돹{7Hq>mCW^/ >f]6҉Vt5F$SȐԜhX2CZ?+!/w q䁤%hΌ['Ruf8KKG` 8&f~2Z.">dNf$:Q0XZ'0M! hjy9DΗ.׶1u/ ,@/vmbL(;jݩ<6ܐ[Gb+Nt:ӊX ~?n&]lYs2O\fsۣ}?UodgM.Cvi4ķc53F>&c=3}Xv+2O׉V΄LSGbuGӞm!{UZ]殁cpܷE! YoN$\Xt vN'm˻D8.TgUbIb` $8PBF'm OK*e.sC8;[R^ qM;\m4m0ߒIlK#u;/ w\6>IN- q( gi}rMkf!t "%(+AA_hXT~ ga-wN&dVk%hU \z~* ?v%bBDrnz݄~rT2DvLl'G4c< ūf.`W6pn" PC^(1E m rxtu3;ؖFWFuwݼlObgh=hCᮩXuPcC+mS bONPk`Tw%Gw*;2F%%-3tFj_,qQ#uDʸҘx%['c<f(,U;f7j.gfJ`dl q1CPQ/6:yC,+cg$4p Y.VXs]{D5#9Yҏ7 J_#|{`x|O +UkQ,{3ٛ' s#^#-[Hhj:鵔 s}+2jFf.6q|DatnT]̕d^%FL vN,14Ŕ`P1Dk2.OP"H RF#U^,/gkɛQgFD'ӯVT/65~BeB|u ]_| 0PwFmn-1֕چFy|)4J%"okmt)3A^esmp]ݰTBo?E Uef4.8'%hV]7+-{_H:?a>wiY #pZUVvrO'wfT2d^ÝL.|hM0$,[^}©>Ɯ r?t ->N%T,ۗGޠD7z )~{#\FQq7NV}ݯ^h.CY\k]å @.!ڦ0F5F؜g]~5r߶PCPpadaeAi3LHhbk`/|~GWZq0 I^6w~{ gnyqyvGRL}G0}rHݻg#B4N\X%P{baiieryjtWkKYZN%%\fՠ?!62Jcu6T}*􈨬-<',sj~g,13 ~<k&PS֊ k<Vrws+vFþuVY?`J?ND@jRo  Kwd9x}{tZTIbcRͲ#F,+*z$F736cFFVHǓ~7c0,eJ1,U|z d~,J\XItyI/TD87λ~ ʷ^wB}@܎24fN9>&/U+̥wǃ@5F@c8w(h$ka; R4r+Ȓ?p04?1̥W 8w; F# 4I!4wWN2AJRnH\;LE -g\ZԹ:0_Vi,d1 A΍ĢEa9oty n yhT - \B@ H ٷ(Ǥ4TR5Yqo/ E]a:4R@ =k+˧ۀlNNOto{/}TC?6#cX\wPi YN՜s@ \VtSӰ U'L`œ9hT|N"_~-̈́j֓@F&uy)Wvԕز[E٤\z)"/Pl5uV,lڪ9W\i2;ԥj/RpQ00JBtR܆bOϷ}Xͻ^SõH4ۓ`x'/"[1$ώ/cFLxx=UUj/"Co:e"I nš3`mpƕ~nvfMY[>=rrwO0sd+٪7!))hIЈ+b KOhXqD[Q叛b鈤Mt,R7L[= S$_ ]yS= I'겫mrskN+e. zk+Fju:$hh,@ xf7XX4|a؛wN {ydTN<\׷DwEf YܝuEV,:["28q;Mc7b5tF9-dKE/ɾe9=%8xsӁs$fMaE~O%?P`LN`‚F kZ%WW:Կ*ñeO]c$烛̐8 JPh))`s_.&,)[<; k17#mÂk %kֵ>mgѣUսOuzb%ts y u>`d:w( 4,fJ2is[1[C6 ,HN gȱmsF}zw}`ɸ_Alhaj&/9ێ>6<[|려zW,/Vثv$AM}@g5Kw$6)MnF/B%>QnM![|BYz;Z_U=ldjxzI%e")0!'dxoѮ-r [sgNj >8\ȉʺI15û<ۅ]?_BVH?gqy=z}Qͺƶ]`VOac e1DIW`VL!VY]Q0^sdi~('ʠFP׋?!D:vTS^S'[1".+ RhZ*j*?jSm%PἌ|h\vϯH?hIWd˿ LGDq S7j9fSsq;0AJJ'Ƅ湌Q3bV13-żqEFƱWnsT_,=LjE(/QoJU"ڟA2:ڶ6{7 #R/T 9~U)Rjۃ1}!17Nt2jCi3]ְ3HS}WiT8d}M{FļHl͆ݻl (/ΊZ'GmhG d65LOD/VVdBZĶDaE tgҊ;--{o\Hd.YE3޵Pr6!m9V9}3r t eRF&UV<4<$k#*C}cl<ʀP)2C`bl~rS#מ%&+4Q0D͵u\*p&S<+2֨OS.{ypEK.M_^^Wt¸ѕ6%{=n\jw hxP|g#ˆڏ#N(4 1(jrbN y'*p9=sqAg}/xڸKki`>q vɽ{uUWiui& <)FP>R4&Bjy)H&8Ty2fRb&LOn,eDOks=(bרрw:>>,NӜjșkʽ w?{N2Zߺp 3u]ޞlRP꿛wH_LBd~aZvWpi;=4;a\</s-O_Ly)jMK>JWU^LzIIkÊp-/;W[L{PRWU KDY+K Lc =UfGF<'t[K\q949ͮh&\㪓-%6n) c.*,叉EZ}Ip - ɲA+`i]e#YNqOE2n+aʘjQ)y`)=68s:z"s@̌(60!MO"k+R do4qC0׏O/IC9p656LC "hO: e28kPI:bioz)b筯FZVsLB9+7M莬07!]I9iam#WqP[ˏF*xpwACx_=yZ*44d=K!L2g aJ QW"E܍MPv &`pL,ʶ^P~_/ah4d?/VհZ8C8k=BPݍn$-OO_0 Oʐ1XԨ_0{om/W3DGO|qN&QJ#w¤IG?x4jnLZ&>Z;.aw뭵;|e4[x/oI{&׺OSU=8E9i1/+3/"4*2.P{ҨQܛ9mX MUK zJvܥ㌼qD+7(lVp3jQFȣוGl")FVb#C _f7 -,1|f4--,p{' èK&ܦ&g͙LW˄Ƃw/VG8 'ijAҸv# z9sLˌNb9SՌ⇪;nK#XpFؔHf7<"D<}_ot7H=/eC N 7 A47qOkN`g0/oG})5L۷]\"#n%$ g9 c"#&^0?Qo|f9&H @+(C&@5W~\CFgWs6N|a*SepN-[~OW2DzKtө`,. Faf_XX%7`OUג{tǹ ŽthKOsԌX߱MTgRcbPӚtQ"2bgX[aIVtmIlD6T1RװZ*»M'zMarP'jt1jt.;I%#f^tz|K ݔhxzw'a37~\Z횮]`YõG[N? "0 A:/]~E (:`iV<ɮ$^W-6`/r a󬌕7f'}?dP'ɍSm_@`ɡ᛺Qޛ=?J2;Mƻιt>^l}--'cW:vsx*?uwyzݙ;cm[RY-/HF|9ޭ shKM-aw&"K;!q{K/Bvy4!4:1c݅ܔE&7޷ ,d9 $.VkH9CF 7ߨ#tGȽo=Ou|fVvG|OIR=wR뫲lX@D)UE;܎',`e9nYQQ S$yʘxihTʮXy|*:CeDɝғ`#&n? ,qUۻshLvzڏD)v굩Lg;Ql2#/y-&gf4.~ّ/W+m}2ti~bPFv<P⭁ | .[2kqƓxU-o>EN&_꧕hzlD@}^ٿ}ξ@̳KW,G1PZ{1c I'Ns"G2[*rOnz R^IFۺOn~/|~b3KL2Lhq~rmnHLx[^7F=aGȞ;R Ӈs1A=r"Qӡbnmߛ&,aF!N-Hf<(%艈e qM6`hݶ=\N~hXپy.~>sLmh{`߽iWeWyqHkuBr Q;t-JI:gzWV >(uβ"rsmM7sg!7UoHaGՑ>1W`y͡]hŀ W* z7Ƃ=cAOq8-mHn$DXVcN1?fAGٷ^Q {< gN (]F3UIV Z;R ̈\vZYQϐ} TNߔzֵk2N0Ȟ5*3D'Elqʪƨ5?pJ! 8舘ravso BiF5b(Ҥ*0>复M%E%)^83ёլY8mgjA66Oz yyyfhq?{RWYT7F!("yPp`(181 JMP9HqedXRMћT`SմBKtjx74~+c}\uW h|@l=/ m4xfRؒkiwn<)Y? ta|i{J qgxثF[*CpVY[Fg - ߅J[- |LibUT}{[۩~h?|X܊BD{Jz7ޥg2}!ը:ʁ91+s& szZ68O8mNIǞcVݺOUeBO- 3%!LM}J+@Fql.7V{䚒r2Ed2M$ UaguD5Yйd_·gNA=+f\>\> 0-Z|ς7K͇嚐pp.o#}VaS6 $.AA瀣 i #wP %*!x1YۺuIRGI[UahmߩDEJML7P̢40-?VHрDpS{Z|`AѠ+EȄGAPhVĊfq׹S֥ICW-#څ@؊Gь">yQ Y7ApD_ռ6 ,sp#d-O]n3[h)`$P爒X6IJtY|CFy)%J_ėOuTn Ƒ{)$?g,4Ăz[ad#|v'aUؙ<55\<*=ibQH|Exְqj?ڕ#ztcaȎi̲14Zwj AֽECxnUJwú4?+8YGNi17y쯰Z}`k{OvdwswnR6I]euLLTmR/2̠%7슭X>UR1M=GƐib<Z55հjuOn1vw:l?T5MqeռGWWmBu&-TnB͉8HA@a[<696l %٢)4ҒmQ*bڿg~ m ړ$ڔZTţs(ox^bVR͌T|p9b\w.J̞FpmLi!-mM(U^3^PZd[jݓa_W󏯨qoy=fHZӌ FrJFֽۧ !Ie̞dkwM|.硍7T1{t8.>]K32f|aԹ[HBXmhlͻ,\|t/3=ʯ)Ma(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 R@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}],3@̿]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,I0J@(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|uPZ@@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 \7t5@{z8'ś'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*@o(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 MX3g@ii2+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Ļӧ@T߀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}@o^=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 xf}@lS`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##V@(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% "E@'ǟ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)ϙY^7' 0O@iGn<槬\\P0e6r ȪQO͢Y@:Tĺ6?9+-}{z* ~=l4Rih\ g&!no2[zAe<8Q&h1yꃘyGoK /*?Dst ; qE{pob/ [t7ӵ-sOJ(_;Y] m×w˂tnZ/Bjhyl.nųhyNKq\̹UY~~_742my W#O%=YIk"],!@io0\)ٝUubL*N599J'Tϓ4E)WX伥Q/?/z77ԕBS d]3xKgVPz/lH$kj $s`m{꧚Kx S>৕!~Q%)j7++ |ܟ8 "utKVt,劂: !WTdMkVmx8v+\p^X S] d mf-h~hkdy4y7{ķPꗆpEΠ=1t?2K v1Ho}y*k;sgUжK@2+ ,STnGϱ"hs ,1rrbh0o Ը^q ,da2:D[@jNqu%TSpuM51qFUΏT T]\ʫsK׏JSF (LTKsAP4 1w\(9 IL`Gevw36"*яWԸdY%RBd%^䒿~~֡jRnG%=syfͨ'`K+ge 3mՋJ!uB/.v]ˠˈe")t+Xchxՙ}Ar1 0j~z0OD,I"VCyȘDJO(yъQc<3\O[r,8ǽҒn醾Q(xLWbŘ3/|m6JSd6 ~Ef'\L*f[(f!|M#f5[P&n*!| k@>DxPV%OB3jw|<\"AsDTBaVBATmآ[0݊z m R'`ԁ'ɸOz"ݰ5УfQ^ӹT]nl'6n|'-)]#.i޳>O%{(A|( yv=Xs-rr*sqb,Wm $ r*$G_f}U0@.b{7y1v蛹SnltYZ&om>U* ; Y;TP$.ppl[yODPϛ,i>_?<;SP5t5;x)]dR5#|LX_qFI'1g+1$p}Ԝ\]]~X `N uo%mOVV>/9F9,-?kk"zzMxC7v1,lν[/Sa{= 3UP ]Lj݊u7.c|v!žzz{/Wf{+$zKCM%}U!G]׮օ2wuӣRcq&&Ә)9S'1Pa"hM5lN~m䷹qupRȪCCcLT>t_D2?&S9OyJQ-*{^\|P|3$w~$vn'DܰSsx'ڸٙÒ.&.\ȢaK݀_7pyI8B?[(hLMSG,C_D}| ={|Uy UWk8yP)k(S_ mesTmMwCoձ9'{;H;kQy{:4|gU(K^F'k}& 0G&_V-mu9 7.I;q% ~`VmlRҧҘQT {})C4++NLݏKt~Z5!#Dtȓ@SPE[;!YC GޗM-JWѝW-4mMsB}U~;쁁H+5YšMƗsE1D>䤸ʏS0m"}Ê+o0pj|9 K2+Xe$ iFG=V TS5Ȓiý[a qŀaUT,C!0cP^^.LJ2yޥƶNb@'^-N@9}g=bYj  v f:\>.;_J555J BE jq9{>eF*b ;يa=^ ącr_=Mo-HꮀjRQnuFm)ً#W$4gT!gSȇ(^|Ҍ@4!2j-0&4 ~WsV#))gwGKmQ8wLJEJGluU)sdvW񵂱v UsI7'Ϫ'Rև53H akpW[qY|ݾ [9Q TF=[1%pV*wiAvxՆfk1t~}G4hݼZdQեBS` /B(H3ZC>޴pG<ƏFF })'R]t8)q*VcPHMW,?Q*6^kt`'m4Ϸť3}MtS ㎧CJK̪>{%SL- ~S e]3?ss<ϙ UzȊ̇@䏔/sd\e~0@\4ګ<'ď忓xa͟hqĎ@b?|]: qΓTQ>ghр 'd܄:+ T^*n*7YdxPo8v{ c}=rB|3]lBtna)=Gad\A`re`/!Ja[/\\;{g=kmV$/‘X{e:slVUذ3g4zSH {p eχd%`_-r-9|ic]JV;(6zuZ P i}R}nXLgh:[-YbUz},;ȀSb tO!EŐpT*xh/)R0HÌoeH 2͎TfBUc}:X=tBx52HQDŢ87Z9EY߹_]0%*($q{c`AHDD/[yV4Dظ0OJ`ŜHNO;/KD@]g,37Z &CJ ^C͕bzmu HS*}ۥl{X3m/mYv^iFMS-',ۮ֘&궕+4"8MZ.P##I `)c}R# ` n{u}%4]qloT%cb&+l?`H, q–H 3[D=-5z`+oD~}Ac踡jNb\?P8Ҭe;5M4 # ;O"PQ!Pqq*1l202DgKQDPH9 ZNa(Gge j+%J,yVS7jvp*)-,'KODM}ma~Ȏߨ'=Դ'۝y|V7H{o6g94ʋ4.zC>Xܟorh;, ƅ.> 븀|2|39NTTO%n*|N@/!dPdJ0͝ddqU 4MPoXS._|i఑BJ E++kϴAj!g,!fQL3'ΞgCv@ ,<'ucu8g27|T%&4<]""+/B,$mPFQCEA+a'Bf./UA׫=G:9'2S:H1^z];Ma.Q'\qheЌl(e/(GX2tTrBbqG7 M1*^JBB< $ *ӗXhJTuEmWP_ ݲgsKW5@|0UǢyhUۂZ􉮠ꅼ_2ŭ;ƔWCInќձ8 >DG#? 㳷p^_o"Iz./% Q{2䕇x]{2󪔖16i §9KFc2$fVh'$:l]%֧eqV 뭎~r*AЗ9Q؋/= an0m221,ibV[DUc\6kER2 J$awE=`xUeQʜMh3FF׌ѢSϾ<0tJ|7oEOƍ%LY*]nS%l'P !]x@9ae㾌UѴ=pnm"Vrkm f9lX _#Vs㉵0j,'NZ _2o_xz6ho>6 Y5Z56-Qm*o !R< ޮ }tqj7 aŋI1 :v(cU-@gḺO߾ҞA(hv,.5Θʪ \5k0g| Əf%^&S@}0?f|.UPȓtK2'W}FL8䱴C5Ji 7BFiiǕRːحr&|sM -'u'&b/)Ή2hQ1-q_f,ՌqplBmMܛolXmp4!bV-@~v8z0q؎+H嬽~[w656'\zQJ{@y{7"(|L@Hpd_`X}R̝= HNev=A\<κ'F, dӽP`0ܓ 4?wߤ~+uxG] bmRzlN߷.6]mM6l&a"R;RP.$d|s/BG>!͕ QW ,N|Noy"tƍCv̘v(ؼސz7q`A0 JzJN&"Be {^ENhN,9S6%}52K~Ba1'Qh{ގH 8#x zpBĉpC46&Zyp&ظVLBe;Р}h4RtC,A#rSLh0:)UtG@ʃ[(H}Z`oº SS\ "fBY2Gk9`-!{s%ךy8qnʞJoWЇ6؜| @p K7Mo~º#("O1Z8/Ykir\zNq*]60J!EF"z#3reC{u"D5 T7} 3$((hR HpSgْZQ?*UzHsjC]nLW:ޢnhhONܡ\A XWHnwuցL)W,rV|x`kk,ȁ%橕ua+B% YS.J,L>ׄ"LObPwkkf7Ia37@A1q$a  n@a>L )VW]oR?jk6 qb ps%;IƱ,y|I'q!Ҁo89xkϘ(-TI DH֕'?dK=@֗zgtc  =s~xe]4 N}I>R"]3GOEvXF~O-IEe36M=Z{iiR"ݘ<ઃ:MܵJT.UB!193~mdWI%"aj*a0+R_m}[n";:n.,XdI~R90_8 Qq~;C4Ut~'-d6R6/2{< ss66劳\|!9=#P=Nrm ZH\O qO8N̖Z:N|z8 Y/Hr`ddrY O mC%r|ARߖ?;Xs YiiV\˝ן}I}9m_¨w vqgY >cy3{tȬl=3FWS ZB[iL@>O(*fĢ yY =ރob=#v4k[wi-GR3 61XҐU5`~ /KR/=$hX5N,UL{IC81"#QWAZT(/_Cqgi:g]ۈ<k#2I@,|c2k*47l )YL^k0:g H,=CUBM|N{cIl6Ĉ+`Y9ZX'_`Na'>&0UHGl x]`SkJX&*!s^?f NR#b36^1@#hʸP:) ܰJ+܊<(/?M(}P V,e77ՖP]m I (=48@?v9:k$pb:Kߤe̿f\݄QNC+RpVYOؖ!o90HcfJ2Sš\D<}Fj<^b2 _\ސ$A)Jcibf_+:_aby#@.[ɐն c`!_|7S҆cV.om0I4ܧN1U$%{IuK C>W'>䑧>`.fC^uڀhJ |OBŴ}!/]cvuP;0y%*'W2DAW 8լLً`lcޯŌ4G+b[NM$KNR{8KjUWLȐ,_PMVFB 2t*N?p޽xox"CPY8,_`T9׃ܶpp*8RjZm.% Ɂf~ 9nm O/58?:J̇ku!s9²9 tOdw-#B~0ί+b9'ɻg x?C Uܧ~Ϭ( tBi76מBZ`,K8yK %0B@o2OD/m̞0SLJ?z|Í H1{AO,tQ[UU5qWv)[ =&ⅴkd`%-92q:Ga a7 nEͽG2N4Gf.aZJMXLG?TK&\_]_aXB (b _xn#/6d=/Qc,kJ)+B(,Gr-)DB "3Ppw>q#dCbݣ>̀JmoiUl ߬hj֕͏ ].a~7_d?9`Ũ}~Enm 3I9xo`tΥ1VT}`mW(?)0YWcZi!T:gf sUm(# Ma&Hʖ,*[ sl*;pEM#!PP/OWnhK^!➭!ۯO:߿蕂7Ia S_5ðcj4dς:ئgցIa5aHJK4l&0+#jɗ\Oؽ*c-L^!Dsl{0Z- n⎚Ô1cN8)6} MbzmLC7B$ BoG?H eFpX'Tdh /3ѐ#VvKkXQcw e|0JQ#;@#:X?"Or߆de09`VuZ)ma4I !Cqᵱzj'6l/Z K lw9Ij?`iWBND::5;?zo*T~U yRAPKǍ?APKAF-Pictures/10000201000001FD00000144CB691467.png4zP[6VHq-KiŽxJq+R݋\|~ɝ̽gydw#51I0da *2;>? MK^ zLY^'T 欠&DqWTEYAd/"quvrpttv4uuWT "S` ."6P.f^3}p{1|/5ӺIZLLH\pTfEA㛠@+~*-'&8՚Յ+<_9+K˰/a@.ߧcݰל(+@nG,,7>n"^]PӔ4VaemiD(cTzJ-Ѧkk5 u8>7ygeLF]0=%k ̼[GvX?-pZO{ *H@P׆ecwt ,\\↧1F+m.1M{g3c7/)"#揆9ҙ994 ,YG*+gm4)hp4ʧ;]SZk,Kd\zF` ͊˭{=^ut9:Q2xMjkd/_sBztGv{OnYYc: IZC+4/ef l4<ۉ͝iϓfǾ2|&(؈+y2=;Y\v wzEF%%y~=7;R?GgiҋJ-(Bek6z MkuCsw_F{4ˁ_(DµK{JqC *NY`DZيpCj*{l^98I6*\1/~ JIҾqMV6\yT˴.N;xq1H1K@{cP2޼\Y;:b1?t~_' _S5SX^ed4#l|u}_7 %UCM\zKyUTsk^.'ʵY9q}e"ͧ;T'Tr5B5^ O/[Æ9A:O8?RonUuF{v57N)Z jqOW(!4A!_'q/gb/[~*ԁ/$m'\V︄B"a4O,61+ *۔ȶhW%MEs{ҺiF7ݺ[{2z5SHH# k`+[! BXݻq=k:߉JKEU)l7 g^ӿ%Z}qLQp2@ \8UͺD,G s'fGDDDdfkku#-O %/L./iWnUQlRbePCodW|o ֲ8zC\z?aÁ W X. X5ưndñJ(K/R޶:_GDuaW_|kcĢ=Ob.Z[Rc~lΏH%A4{*-Iέl6%cך7/&By7tJd{BּG‘Q-1hϿ~Y:YBBC`<U{q=ݹ*"ߗvriT%@`~3N˜,( pF86lL*mPmɽ8h=dqa[Eg̈́QE5e1ml26gKAfCp?jPl^*3!=LKsR dCIyUێ] "0mSFO=qe56|6 /HpzsQxDlvt]deh è X'KT G-Qt6C'?PK3M5KN@\|LUQòlr0S$s_$}#=K*z=ݒYVfz> Mm%O& (Y.N[Zis2VUu-Ҙ\HIl3@|'YX1W8sYޜNzJ.[gS`&0_0'rEO@Vm{Jc{`^uIil8[S 8">۱ L'ܘw]a 70]ܛ|HU Vl0$pW1ULeۼGIy,BV6CIPW/FڼڼApJm-ŅOv,y3

.1$cq㠆!&k\f!#/劷_s,2dmUU #Hz/-hBlkF܄6R}a+LVlew͋kUݦj]keyIy=@hNEnpa*W&og:2HɓFI(f=;&Wjtuu8d;fg`w)Sn^.;X~KZ塚{eM. /+a=|(XKv.a|tx (9} qq6~U kfdTjT5Qi@P޺E]|`7/៪2x6O>6"k`IN LskvMQ568f#%$Ɵ$Os~k%k-jsOf@ֵ~#%9Ry3٤AmN[}$hw*^& ?LxofK۩[X _3F:s($HѦاP%\^_S1 %5Qd,N#=BHxw0&zL-gN_dn6FF*][sxp']PDBւzz<pohUC(97]t|CI/梃~+dNCJ8@ZOBA52›:wvZn) >%FtM`˜+ vuwe-r1gdm\Uw/=%keޥ=(^w7ny l7j,ۆ.*1? [j48pj&'/ъpf ._(W9FLGI̘X\̲qܑ AN8Tޡ+ӂ Ǐ\5HH\ۘ20DZֳ[@8OY0CɤjLڼ!]ZVXU71Y0D*.B T588ox.분o: *||zh >r!Ga*9&6v3H $$L)7#5zXUҍCD_'z8_kpé|SS! +/D_tu5`&.4 ]~6ckO^S,ӏZJ8W,Dkg =A)vQϡD́'0R2Y1{$JQO*BTu9]{?G:%[9e3eMU x~ _0ʥqݖ Lg;C@bM,@7{>Tng*oj!oWGG߆IyZZNke,100l!͸|F>dtώ]I!>y-xJ}j:[7iD )Pans%kϤ9` hzf(y7pKr~o5e;x߭.cv\Q^f8\#RH $)ޗ߭rR$#u %OIT6{6=!nU9MyCM, n"DA)"J)vS$ G N9JwGt,'IK_uk(aJZK<3AWyKх/jd0n1l"6p$-[ |<d݈e$dDHobƍ푤㵢T~&sK!{آ2: O(]e炐|Z7}3xҡlƆBŷ~gз|]n{%ƥFK.wRlj ɦ Ry`d% Gzo0ʊPDݔcz ^e8 >{~ C5TJ%?apu&mwO+G&\@v*p*[Ӭ0W|B0IRRic[0'/1 @w nU^WM؟p>? qSF100>xl\4Z'D #+ #Eg=P.\]h\-؃"}^8.b뮳j(>y;F![`=̬cv'`kxؤqnCGǨ4`B야VƩ J[^!]j%bkɂWG@hj,s?1Ogӯk0Qsq6@m2UsCI!-C~{xNby'zFe^)6iZu큲yw:4֜}6 K)E~Klߚ,`|/D=FjUI#M^#sEZGw]D[Bddaa[vD7P\LíV@N z7)/=NPNgaƿ>gɇ+=t tZy~yS\:#m(--kf ľ4E5q/Oc/l$|m /C$Y>SƼ,K{Р \=7o*:ͷ#^h ~*6ʐDOJ2\yxuL-v@9t O5%V d0#,D>'6q0jqЈ2K-Pz^8*an¬zoMJ|en8]'-McV qms).}JZ *Ÿ!n\w ${D~S%N &gׇ,,_H*#1*]qN۟33lޒ:QRS26}L8vY7&f0,?ZKN\OE2LÊ=TS\ )r3OmH^@[g7:BGė|C\)ЄoWA4C |rEːb0fGqo7d$p츧i5Ϻ& ~44kܥ>kf?/8gkR؃PuǑOƉlw^ LQ_<޵u. z{V!HZ\ ),IQMk z%3y(ѻaH:kډ([9sbvvjgq0:N)G/0df̨.K66B PbNyld@mf8K5Q1o6ܥ-;G)PXeX*5LgN ?[?S׮KiD`{c> 9׷xeQ%<4GD4%qFI=u3о2xԎ&>aFDu[PUGl˝0RVV]˽}"]Ιg).>6z[ ;JsSҿU_ssJbcikHMyS/ (5 Gn܍!a:+oߎk1nije7j|DN0P\$ 崫{ۚ/Ur?29\fǘ`6)Cw,x^I1jKJu=٥ ʯX>$ o\< ;}uu:xvdžuv @G ,潍 [ԭH< MEMz-ٞ4%f /`迥fSr7ǭgޙQȌEfeDFm$Tv\mIţhKWz3fmP vЅ#"IILlGֶh9]/8A_uzdo?ݹ5-L*Uq9 u/z}fhD$ŷ@ŶCϥVsFTt=4̩Q)#jybҶ6}U3!Z̐h{/f`COWՁ"sdN$-ܞ< }q.;awR@R9I}ix-ℵ?hNt;H󽳿X&)Ӏ7Nv6- ;е^E5MԠTGIP("j@M}tٓ0\ z<zKd f^ۑ%˱as ޘM6&au@r6> 1۹7͂|ge5G .v.˘8ЛI)/H$v!pt[ pgdx4 Ɨe*yL7HU SCIlno6#+>8IePU4cw]*Eux#22_N;5h޳ڻ.Ҵ67(yxϥx6x\MyJ>Ӟ> -[E̋6Ϟz.9,7;o dh}D%OZӑ`+j\)yW}=ɉ;*(f_xͺLjM+ޜz(T$FVQaԬ涗_wpl ;,eYyޗөT@aqPH}3?uX le9 9u PR*D3ZeH]r%$5]v_75J 6R!޽zSobpքJ"XaVr~3ՃL**!Sllt{zz=ދv^~17?/ 97RB(Pc޶km-Ì7Fo]ukZft\X Q/Rb%Hܚ%=eMZ )ΏRm:;s>QkQ?d"1 W›l uZ=ڕ+[jt>,|ҹ |dl;Œ%KݡN/SaƋZ_ݠNnVsMoӾ;Oњqe%N ogNEuGA`$^]n)JSt~s}\bSVghqV ZctItO#~|lZȇ@2н͢q܃١w+#7K-BmDMiEQCoy}XIrHЍ}=kѧGkwοYWPlXdcE;͹+cY$b}M ^6"X$b)<6 90VhyayBz(ׇHq!'vdF̣;}mh(Nn]y`<[Y$P}! 򸉠t܍R&O쒰aj 1T|xbxt> $ "^~>܈E(R ,:Z_\q]h~j'!&V(}}luS:]nnp8z"x[ީB*oh@>t~nMQPXNNY Pi r2+`'!?]ou[`$^{W[B`9 tg鑖m4}X;F@{~/- I81HY(4*O?;+oy  m:21˞tֆyqu5QS5EIXDk]}k@Xo"D{j]3jvG?Wcf9EȲ#sЫ%Y(1uՃw)ao^%wL,sZ b *W37N5ZU&iQEd)~)tŒE0؉a%RtȂ!ÈCiYɏn4 u#^#8YSC.as:@LNBHr{iHgcR- R,|*>6/L1A/2о~0^ U:Eӓ3L.TC4q >s%;<Q:˼cjNpI*kr8d"0ПӲ:BvŹ'B7B7ɲҥ19c%S|x(xcLVs*d|)@9AwfKndpq w{|Y yfZE9uBH;#,B & >ڷ Coo~C[[5A.?O[f([\SfW+ \#+'#W(%eDa g ||gΎ iLooif%"P8V,F(w^}S= wmZlGG&סש- SK_ȑ*GyYñ #0H+w=eV>ڝpX;'(ϊ; ``rzlۜI"M _Bkg'<뺆wAo Y@< GOG&SQ2?JQ0q}4WQ!uk_{vH.W]K* <,J BނҼ^22\_T%qmvdxl+߰IXL`2 \_6w #Z亷7OP#435MjPkXژlmj2![mo1دgӄ7)ne%o??yRdbHϑ?]kWwvb9 x6j0&H|LԈ/4R/%=/Ui\b,f:I d,֙[ll.I9"ͼb8m`c?t 8 SbYxUP|URukip;L ^N@gyj`y5qץg}'G-10Ãr5HIRJX3T{8l?SOVO#VP{Kt^N,vH+"' [ԣki-hMLIa~jqWH^Flkpm2%]9/n%LjkkK}wX]wN< N{,}Jw:=sR p.D;v\nOgy98,v@Fi&u0i}!ߚv|"vcKuCWJ*d \ ^c~vbR;6G`'n;(*jO_}\=D#x'-υ#hzb!PPXX˧1_7C}zNyX#_ļ~`%/AyIALpz 67=H#|&]9`8(2>Z8Eȩʹa@Wz;6f[H¨K`(sG{XyT-mDyb+Vi"ܷ.-O!*ոL!sWNtGX?Ce^iQiPƮ[p,xs>aO耡j];AOGv4CԾϚJ4M'-S G@j8Og^w^RJf p7e-{Gz`SZ-bXOwHA z0O| txs~ /2;hx"aţk=LOҦԃYgaM ]BS \#sPndss[rؠ07\q]f_n |sn#;K ˑΨWlCIAvͪdS?py(w6;:.KɃi`gˀV!T˿clld1}r*8敻3i |} ^^0r u%D=H0&Ru^?\7zy\c*=&7`߬:;N1Y8 (e{#D|Z3 Q3e @ ;qƚVKe!8XP>h!8$&kݟt h?+ A{jNlia/s~^efYI%Q2ء S{DN"t|@34u{px9+44}C&Pvۯx)EB={X0e_0b;l̲f\xF7xѽȊcd=+n@gm1c3 qQ֨!8>>q$OlwWŒ%)s؁ﻈT=Rь򯏾z8S~0;ǃL fȻ &SruK8tBxOldO4}'|dMu0\ :)Lr)fX^ ! vnԌGYS7'lp!g`N(aA۴-/:#lPQyXqBwx ^#FFbԦvp;^Tke n#Շ+*e{JfW=QvߏI2+oXp:/VҤ%+:Vo)7aWO. $?+T7{^Nƻh,3,TPϏBA+i@ڸ.'DDDB.mJP^ .'ܳl"fk Y:-Ysrlz٩P(^j&!AAwI.>ƾjR[Æ$d;:k31*e$;ϔp^M4\gn>OFTRf@3sG܄v#`(kM7?^{ؔ8 [44q2c=![6嫫5!hwn\%&,T_`:*-n2.%<)ilDf K3u6FT8e LtтR,? 85r'VO/)]d{ma i3D 52T0&1T1X,HEÓAd~9A^_ $˧#hW@|C1YG./&9_Yb}R+q,Q7b=cJpf~-DɓD-]cc,4hDPc0DbUYTPwgnWEBUBqꌷ7WԳk ;HoE,SB(G[{D@̢xyuu.nt\O+JQU~3 J@R7Έ:5V6'b4.f<7b Eq{;&]6fBЁ X뾢 UҬ߾rG6e#prRY2woGլՕ^#s^J1?L=2Hz ]$-gh *^tFZcJ CI.ľ؝PD<.MxO`!OpMq+=/ן D6oD;4)s鄱OȄ4\x7RXX֤:llg{Zkɛ*qșh: o>4V3S]4N2s@w>ebZ[v2]V0`L10N\N$סS` e1Oi<aUC- ^ɘ;!&'3NZ;lަN7 ^fdC9"M@`̗/*Pɤi{6%qja<^t,')lFe$=#/KZiӃu+/@^ t=*Ea5$4Ga7]:/Vp൫Scµ…%SV\Q׿wA^"ˈߓZC'mO$g J_?$PqQ'+*13+[Wڒ瞉ܓ>GWm9R/EE'a2 ]eψ9% Uz#}9;[{jK5q-.XKάq.P: gwuDSMlCmxOx7/>ܯE܃F&f4dLG&1L~Lf+Y,{|)-#z!!I Q8!?Y22s2^:˾v*&]>s}ϼU*[o w h â)Ĕc>P!E\1.΋-y_=2oBOR=k ^{sf{E{mBd5c*fJUO^|Ui3/oFⱍN avZ{V ]4SE+,Ii&"|t+;fmP2woȐu1מ*~c-+Th1O&]GdaOr F_W\r6P(g( %bSO[^wWZ:^k aч=/c5 H+<3 ƅC7MqIQa;]̼aFcOgu}ؤkh|,j)seiST?!QK(K;&.Ŭz^~S茼oMg]5by9?>3#70wȜC녥v;X|~=b ƞMd"lZRo;zFG UƜ-@ml#IKs@ϡ#uiF'6bgFKB.{Ю_iW9ge/kj)b~NtAJ:4|8]?4o~k8vt|cdwW7Iz)6<>W()u*嶠rwHg;z~de2 hR+$6812Qr) [nECRZh83A񐼍Z\|ףDo?Š:{%C  !&1$yyy95|?D { .vԧ٧3(Dx9I2~uSzit蕞D8 Zzkl,Ea&4W^>0CF/ÙYi #M +~.nC=t}0ߜՕorXXkΙXhnR({{qw( [qww ݝs?}H^SΞkm[m.~q} P~K&AtD%ȱ#͡Y|:q2"cpn'ӟL8ƞ>Ntwί{J]Dݍ `]oWR"6Nc˴2[t?60 jJ])jV+d 6ꝯK664S<-Ja^+5~n]&rKKwRc4>%VEA#ESyʔo>&ǻ"lKࢥvIO75z6Nԃ gOOs4ƪiV> xƢSeh, -W@g /ELļ5嚵浟&P'>UXݾKiq1 nXtcjjRdUTK}Wdzp}uajj;0$Ԇ?ܠkZK- 3ͫ ƻsٹgkrA|Bbz8&}b\{э|^Mx  ?cTFohy`y{?/wumpӷ|QBsg8qu mt h]csԚfȞozk3nS$xbҟ^!M"/` f9UT\2vܯ\SPfv? X3  ȉC?i`W(ykupUlixx-G_奒U>Ll/[q@i>'2"0!S-4%rDw1{MѳvJK7LCjp)P.~** ʹtMP* 8Qc! T+ژLqָz&T`5F)d]9+тVQ_,VefgvvP^|ȲD29z=c/V=;`UcQMMMOhy߱~">>((N W>] JSVv~Q)ǓsiQ4cDD&>kYǸפ F<-JԄOkrf0qN.vݥ,h%&3"QmedW&Uc~GoN KF B(( L~`8\`1)΀OD}+'ZT-1X԰%n ;i14$3UptM# `S+x>=<.::,sXz&tV,_䭞 -\ VB^@FJ5 lWFӪ}Dֿ"()E6R~r|wFI7BC,.NKK{ǁ GLmF#L:fM\]J|k>}`;gnZTe5! U~ph[F,TTDu`ary'Z;̰UBy3ȺFk dZޭ/)*dYS\ .-=hNmusp Jh2~V@4m6/T gY!^+:u?By% [c8 rۇ޲s S$fpr~~̪35aaB!>Ϩ}s }̞޻)׸h. {u1|x m\X&ḎVȫgErԁ~\γѓ$4 p*tˮ;_ev̌6;08)!!g>1!ȡ4m s+F" p#!;zYF%]j Ѱdk*F%9Gy:6 ,|6]e^ryd_:xMQsՍ뗯[k*yU>D+p ʤr 0o`g(D$ڶDf߾1egnU辏~&x|*yߪ"M);VaeJ`R{2FL>Ї/dSCS8‚(,냖8 &[ϡ3M:ݸ@f/_(J_.=ŕ~}Rh8eW\XաYpt9y1B.j]~I`%(̈́IGiCR>'H| U p:Nzrr$ }U_{BN6.BBC6[qZqd(U#'zfl~\دz~yG g 5 sP$K] z!#t!m%]oH&џ LOv嚲V;'c뎋ShZf?j8n' s\ݩ;B=R>r ^IԉahKSv\2)u]buz`8-EP`tiYThHU&^ E 9EnRFN~āE"ZZ\]XxR@4@W( ?;rA y€2 jm[wAZv%^߰drF"u7wR}$6(]3&~e%f-s Jk?zƾ]o-|3{1שx ^ {l*( d,#( إ`JuƖ#?|KjՉ!+-E4,,z- e<mYa;:$ϹƵ'PWV~;WEQT8F2*T0uּitbdaoһiJ>[mB MpO㰬:(f'q@Rkވ-| Cs9+N^=Ĝ5^ܾ58*j1]u"qߝLhH,wg{om8ڹ 4Xd{DzX fLhDr/VyHu@mZwVK,J[:ժ>#m9NUY)3ue= Y%(b{ɹaP^pS@{/"Ƭ8U{DB29̌Qy_Y$fz\F:Ȑ`AtZ>aO o7s3/;k#bŽu^cmVN& {D3_!߷5ePfs2O5\4ٯJ7{k3BGF|S0>=Hhk[g!X\ѱ V :#>C.Lyu9Iv4D hc- iL^P,*q(^38N1tcWmM",9roJ|źpD^p:%ȍ;ӊi*!!{oyDE:qU9{9`p&V!HRIZFxX2/RwH.aiOV%D؈:Q H4fZҬrIV 2V`jPdl\FeQZY;02lI+Z*JOȃ ^ +a"/*/(ul7G ?A zDtMs)\OΚk-' :. }i'4D($$(̠17>E"`t+m=qzg1/ڭ?:u-} }XxŀfuƈbwlUf:61@kT]aE+mQ`fB1e;~-*} xh&-etjǸN;^>Of{w/d/@>oON#Cd^aDU<CЈ.x^r:W؆WauY+.s.y$Jg*5#NMSTM￉)=|Zcp 96Ч  /-EOtX}wnj<~5oIuNQd,":G m^?e5'o;}% XՅ,ⷨʁvƔ˹bεv0cۥɂϩ)YAn!!N]|t˪RVMFE7.7^H@k^"P6cjzpLgƸǷci~ײU';#tgmy]g9_ uqpsq5rhbubEvc6}k:b^$-k~gNq;{w̕}s1~Mna'ϚyGFO! jF8]גX3zʹ I8pprf ?^ ǡUcm8kBߍUى?9tOU( +&7VmCRBk 3g *eڑWv#q,;!ls@&ޟa cI1aYkAi~-o >FPXΏLcS6rJs8 ~h#mDg:xu4l>їe[[A(5@<تss*\|4ne҅ߍݛ0\j_,nHH n4uqq.E2DjqZG8.}}%쵼\f wI듹Zdg*ZL1??V~fژ=r_/xT<"@#ՐT3 {R&lNJvjE^t4@21Bе zgOq8#4Kxz3hF F#*9%uo|nˍ.BWQ[MX(Fe9w M'0.?E%T%%5B(ɑ>ԉ:0dru b.Z]tRR*ƒJo&aJBW- MOWv}ςWȨD )?UDgP7OO_^17pܧ?]kTi_nzE=ѓ臫Hi8L_os~>Hsb>Vq ]=B=XXC';GGgL9 ,tǹV_iinnRG> ݳ0?^߷%-}b9Ӈ[ 8͇xx-[W!V?k=ЈȦ=Gr$mihEz ģ"O.(,'2wn@;/Ԙ<_mz>,%J&D+OL[ zJǣg Z`[#߃aZ87 w}x$,P@?Nv_TB4lI"/`#`:6pW`*"G8]A\ AL?9%yaU> L~ )T: 8M9|ކٌ KMPFm_ @P~|xJ?zO6h JT6V␿~"~y"R7_A#{`Da3kI,FԖPÚmg)gK( x)_6^;kbC}f$q=\/`,4[.7K3Ԗ@SDp ҧ}1;&VplHE, 0(pӛ/clZo8`n!u h R.'V4qLg4 Ȩ=owZw*LF1Zw΄M;Vfv4 rtD>E5LB4ぐDt[$Bq( G;9"DZ` I)13le׬lg)dDWK,pS3Lexgl@슙F4iiMX7)W%:cZΡZP;!Q辿3x^ "c33*Ҁ6IHdVɌ&Sz,5Z@Ig' ;AdnkW,o"g68^šLk%Cg.sH߄ E^󛒂I@Z@U:1x4.DTA8}:%һ=f2Oс.ǀ+C0؄ΘR<ښz}-1st8$ݦ` U x)=uTW VqIg'2EbEI""FMZ?4LEFH DmjXќ??XDzPtGhY'Rg/}wܿ !TՒ3r8w|{dULw"'RKP`z+-ү˂RWHBGe:R-$rbn]\t1KH&Xzʍ};W=bܛX>¡u3)˯Z KŪ覷ڷRvzJLƕu.qʦ4y0hʚIT0[823sK,~ 6c [ ᩕߐ'Y%j"-k7.htUݠSS[Rc֣ cz?<> xag .% @t0(~}]_D9;wj؟׺+3N;IZ?D}7$,u$r9R}9B͎揬:r> U{ K#e"/Jb[q㈯X@|JRa8*AV%]J$|P GC'FxG~VkH4G\#|~3qq(<%JA{ ;,9=)`C-$.=_K@0MHgƄ;1S^TCQ wB*VXt:ɊE~R@j}nR@q;{,EJWQ}")USp@_`R$}37::}^Wwas_σp9B8%nGXi]6\LlJ"hP迨2U.}n2TO$(q ODaA֌3_s^4x넲yae.Yh~9aO&׵F meHm; 'Դ%jokZXi[cJ t.YDѮn(S6_Wƌ^TY;ʾNkQ+A LIohDE] ~nJ'FP_@*Wqd&XVt3aJ*ҩNF}m8{X~82cz8J0(܌,$ {HiJGe\W<o=um~YZu.pk|#(L%Zx[_98VgS&6pB+`٪Un`߻r alP(F'E,t-CBe wLoG\5~dgy5١<\MXjX)J,4$|}ԐnXk[J ( ` ҵWwgۯ6;?eyqhνŐ ŕns@[wozUjno40~ELzhDDF ; ٗUz up_4}f~StVIv@o}1~Sz6:'{x%G+ƨ0!>zVzf&R^HZ5_kNDG?*)-( M|~`Er'88FInpdvӞƭk N$1Ug)Y$(mdk@}t=%m/&D /^"cӓ<<#hL;#D25 3qQ7ܽdZ_ vG,05&s.SPgTqV&nކH΅\22:%q\Ā`z8*YO]8o\G5ա-_?cҫ\P p7Z4XW>n)k{V "oaţ@1|'")͟^c$yE7c+`]'EVXz%ۨ,(3)qg׆wtfNT㘮fUܖFu sܽCq>vUSsZVuCQ?C\<=Jn̢"d܃ݘU@c1Ɂ>@<<#tA~ 1rl-k%(V*Cџ=]Bl`ʧ$fttxn@'se~dC6I_%|!< b ^@'zb/6:LӲL } ,[ϝJƻjjC!!$3!$-Eԭ]WkF8'c*/05_4oK:t aHB6mSovEhk;R}ڈ~7ك&/ljnb!閘 5\uQ.dmKo|"rjVXC ɭOq]hQh~ cPAS"ULY+io¹Xs[`qwNY"u_+wģm 2b(p=7CgchRّś@u{|jv((-#r ۈd-[z>} oUsK(7͏ o87^ZҖBEq+o؉I5 n:# լW}ao,F56Z"O/Of83UF˓pCvl |GLPRy>sll׺Vt%OYQL2~539Ƕ6GmeJG-uWTH9VG©`K*cxcNtatDQ:A9ETmQ!bi DW.kd/0j8Q|@vHIЈP}^Hne>`XrTM3ڴ¥EQȠ[Gyxm}·' TQMwL2!gY71-Cknw&8>a*,v?WH^6ѕM )ڬ݁y9+wS2% odKǰGX,tdn&-U 7%5;{jj"[`I"7?IӝRTL7&)t7*mg :}% CZq'DzZ/߮רu<_qf(Ve\Ek7*lp0ѷ0o7 %2tYATzPq,8c*J_`A:Ajzg ;`P?e=-`6ڲ.]L{Vv뎯J(uֳ? ]οChi f~yC+!¼`WLS@}'#1C#ksL8;ʴ8%R=VXXMV E-*~p'o!]( pZe2E oW%+_ƫ '3V*LTLJQgt5u"Sl;}L}1*[C]G*g h[YNuD/K!),^S3+~s8>7yD  fsůӑPVA;W/^ޢ~7a~\$AWDh?2mԼqJV⇣4DMcRYKg;ǀli!A`٣1|sQ:ʖ¹.rĄA"# ﮀ:pi(־>=/%$ ,,UKß`{1%->2:tĬlL4בm3xc AQ"/cGw€GBl \ԏg//L,!8}Q{؉s =qX\NF(0+QoKbhBMh3I&O05 z *' $Nt xH7E 1M`U$+l)X`IzOXCcT KQsl'y.\O|eE@X>p/L<5 ʿ>zI6.S6E->Up,qM0.)-*.)Sgrr I;ñZ+ypۼQjUV DŞ{8#7Ov 9Vh(=#Cނѿ'7/Y}ݧSϦPݳ9M*GH%6=!k-RHE(d\iRزyGE .9pRb%"zTP#vbmiUmcB6#]#}0g;~M1EjK1G8?go[C#K/+9f|^f̮uɝ8Jx9~2 d8,!a/siTJfCP3^G\CO7>ᓐk&K g 8+{>ȫ38¦`j&20!iY zI t;BPڝB8[[`bLtq1V{SuDfjnkKۣ~?&N3}jEeOYVe=e+6~+AS,_/̯{csTMՅj쇨"a.Syݢq HHcȇJ:F ޛj`MI 6|k3(WZ/U5W0&Sj0Yp2|Y/-Ԕ ma)G'er@D)109-ˆsݝ'g1!C 3G(]ܧ766 W+9yGVk0pZË#Oۡ5?eg4+BN>Z(3'%M54# ~-@o>x o*{nkRZW0:'B6? w_+3ӯ.05d*sA]cE8LOX]B*/؛/pNf%_^ն~/m<¥YDKssg['IkK.1-^+?2$Hl Y@7fzDӱ va4XX}}|/o^=4finv---]BL i/VR1W|ZV%RmVAL|VVU6*!hO7A|qGXIC(ԉswp\yz^sDw;@~"gU?6ܸױ (zS?+hAWcj|ɇ2PAH+jLٯ sw2Źk1(y{lF z֡)w"&4['wʂ/MX Qݎf蹓.vؔ ʎd>dzTv͠7[{" cSto eIev]u=ό|D;nG2%`CѠ=oU[uH"ZWPy;zN]~` ?4nSY=;-Z 6 #<)5#vm,{ WY8Ee\[IZn""pDbopT]ԠacF"thCvl! $RDwĺ V[Xa+2 N縇Urw`?^ՆfDۈ"rj7#FJk4 ǖk/%d7}5wö V'$WܚQtyc #t%^]â鼺/dAMZrz<bb/ĢW[܄48VzOmGFf~X7Ak5%aқ#9|۬1Gهa}Anz2JmaasDC|*nȚ٨aRmcWTYPMpUZr0|B/Y|y%.Qj Ar^C 0 p0lueҁT߅oN ravJj(R54(K( ݿ, E4ܘ?n^atiU8F=7og 67ض={paw1Shd>Ec{]DYal#r^e4-Q\z/?Lw/"JЫ}+i v _4r;_pd3|aM5i/ vf3]v'e:l@9;"30JĪ^okbpw;T5 '"BJE:.]$PzUk7@/oÝng"] ?>v9 o>lWUz-Ѭ!>|Lsa)&_LAR&Ṙ#C'n]&y@/,:αsks.a$ b 6$CcfFo fgފ23;?0 qൂ$ND2wRͩ7ҧwd~"o- V@گ*]*MKP…gP1Q2W%  EnHE]+.7@e+cН 4|2Cs5pO+Hy͠.(xb7ҏ.*l%y +ˌwASm))eǷ&!JQxQ EiMIgRyjʆzyR@T;j٣Rɩd**3מ w51wpC5>]fqllm*_(ѱ$@iÞ\vCwE'l/];ȣvc+FHI (Fr\ OA ~Bm6K\^}O&סO< _dS;,N {%xdEbyqٶ5EAzG6.gAҧCϼ..}j۬/o( lG2C̢esx< > 89hb*TJ猻aX<5&h/-XxWɾ~ʁtK8" }`{,ZON]~  +;5kgkB׆f3D,FllK#F #T+7eF?Q3M#dInjx%)oSRR\QRنhRD}3_ؚ6cqBk)EXRaߜ@J ")Ū}%ۈٴxnDt+98lH`)|;%+h8ڱ_^aJ<3P?4]!>-r0jk[Ht@hCF y4LRՠP[ Y׍jY7%#oofŗT| 2. .3ZVn-jH+DLߑ#?^wRa|/y|+ m@ ͋G%m/.G3.L;+$$;@iNɡhyCqxd./O9;nvXVS KHtOS*6/w f(QE'Vq2Ĵ\o6,r3ـb*#\7?jJ.fP@+ &q^l0fZs`)RAFNă7;|g]ۄJxDW7B!kKɣN [si4Lumھ0aaN xeqBdh!bS1 @]c^$%+$ =}4PQ9AxLf{}\!Gfdd~Q}rrZl[\~b&ݚQ Lf`=weޮI V'(h+ZDF !@aQ]wq7"?q{9 4=;s^$~o(zEEC臱†ΐ<əb>;w(bihcOh60d}F4ji(RńиG:V\mvloS8=Y9o 7Cԙn#"$Bi;[BRcn;X8;6sζ<[blt1#rl53rNW= Jz⿾6'w)/?\ZOץpU 6j/\q*x;Ptjyq0RU[א ٓ02Zδ__~URZCeQcʦ 2ÆvKZ&jn/QLCi@f|+"@\yl=iU"#ŸD%z8&Do'v|އ0e{Np5 ^adf;Z">YR;U'n)i5܃_u< yX5Բ пҬ ;ڰ'GK]3a~-b}vKGGT0Tgw-4&˦2fr=\1I@j~1[}&;'hm@Һ.!D2^C=E yJ|?J?Ԩ釕?vcp#.ݦNI 34f[R(_D'Ʋ=( IE^K-_B=) u94|R3уbClkϸ5}*!!8mU$d}}~W+Wwj6+jztvZ\8=M#D)O&aTrL֒5)B*a.'CPi]-CI$mD;E>QldV: 5,'0M`f(;!8Kf u_th7!Ix(I&f#F[)}gJ~G80*;32`"pwd/[Z)Gv4)|LQP#1D}6&I dVJQ 3L8*{, /zuȀtP`?7j C(=;rܠAl-oC[[ Of@.LSqX\2ѩ5B,@W\PԱg'2۞ rDŕ/-HDJ:ɖeo1|;1 fw;B(Zw|bmP[tjJl 6,4+ɴy #SoK-tAA=OҌyކ59& DBBA`.]:3PJ|1mRjQĤ"]'9eV{JLmÛ_6 _v{cÃg_لs4؊y4(HH0@M'!t?n aB₳|Mt'f`˨&@bV\!`q~JHZEu_fkcK&bE  (J /?l_чVNطh|VB7DR@y6{A>_$tNJlzj0òKjcpi"3-cDx~Toϝ?cGZkM|4^Ϥж&FfT|۞ !SQ*y5/EL)8*"6jэ$)MeK-ܚ3NA9wz<<#BF-(?B=L,r:)nisH qOq ,E1wu W,ye ' 2̞)nU!818C8J׭ WV("iMw('^QU$€2t[ $8TSrOl[:︂ӄ-PH薃GyWl6U܌: 6=578( O=KѶQhǥ޷M X,ѧA$S?)NTCj;"BX ƍQ>ɶ&')c/\)d A34 \a>۰fgckN;H@m.}M9 ]g{7`H EȳjUݩZ@P EhXsB̭EϬ07&| L׮'o- I,Ѯr6]Љ邈0-e|m(@[)9Ч±8&ă:Q) Ay'ν,vRwCJx`6} tK0s\wt·0_7!U>6|ᨡ?? KuZ#a"ָזt{?cJ}vfd4y ]=:Tۙ3 _{vz~+AAFIwSܬBȣ(gʌx]4-;q|JJ vf- - 'gj ٍqT_w|Nziyr;K覗K݂@tЏSQȯ(kfvx֣sOG>fQ(̩f°nҚ'Ŀ*}\L߯3]F1֮@U'PFL~qL}ehTs:2)լٺw۪|j4JVrF\Tx=.y m\:lt䬭GiY]wh/4Vn LYɥŢڪnVH"moHm 3Vk8 Tgt<4:l{.2b4#Fe_e^YE.fꓢ./7}}V5>^K* .o/F ~o /[~zxY*%>~Z/%g·!ofjZ;Y!JxBZ>۱D*lƥ>ZE-(2+P"@6uLPaɒ/j)Wo'ZW̮R"oF3%Q=mb7Z5`ѱx:>/ŗT'o= qO uFt;R/|Uu]1iZ%h;QQPK?9q[hTO)Hեp,)jQZ1Ai^ÉE6 _A}\y};,_`^i$ HÝb+g7 ,Z7B.L>-`K>1ն3n-ax#6A3}3]}%=sh0ߚ|խ+ޞR+BqRt >J' 䟟M҆PKk0mU2q1ۏb͑*JPd A&`-݀76kqrt[BA]~v9('u^B)*vض[T*5S5/|$?5VE)m*\&oքBkEd Ak d? CR ^3Psj(Wyg2qIB΍7, ~ed!%4M!_%.|c}uhɻjr0FY=o6;_g syɣ$Gڷ^BHzNT ȱSvA335wu:ٷ.M 0U~_r[̤QFA"}~WxKgKz5F݋bն a#lsPbJIUjaOfI@/?ʬ Ƽ$2e74: o)*`dA]#R^M`Dl>#>ppUF LNؑ~Z$|2Yw洵 ;ƔxYCp Z Q&§A1F79mEku"m]rśYpY{w|~LlVU|)#FޭJϑw<]:0P߯g1 d!e0iF HBUjQ\@f,ܻQ =|޳q'D蠼>q- J[wA\N7L*cLӚ[' L#~ cӚ YF qi$F1}Dkp3^zTKp Vp-ؠ#!?r{n&xODH߉\R#zGatB đv![]OFZ.F;j̛,"$(տt"F!%2F\]M7~~(NZ3Sg5*sM:7=u{{ GD2}i3ߟM[$or/fn &S ͸u{sc#_qqq+KUɖsO͜{(uRLRyX3 wXBIe?$s6F=Nx<]g)8 HQ?Zm^2GO؄΄XU6.D_{ݟv&1:i ;;1l5Z>+X!iӢrIV>=~u %]ɂ.+6zq&'dr/%42;jͨ1;0&Ɩ0UJ9YR i8=N/wK7uؓ5aK.VEqQȴxP>@ $H'7 mˎ"8j$TҍCΦu.i+֝=&6#2 JOI{Qoʚ|F-bV]oaP"}T3`)!`(.9W>b@b)t EWMLS+6MF in̨݊$TijMD&^hvo46GBGw[K s}͒n~v@> W H@jBLQ8 |.-S "6 #.#dH2'8Ҿ΀{aGwٱfcc=j]gB:' yd񵫾 '\p R.Cκ?y "!n2Wf$*ҡo r-* $ěOӞ[di$^Cޗ<訌q%Y$2z_&С(}TG\ CF) l0QV*ϷQHgSƒ7,qA eR11BsYjm{f,l]Q!?xUc{ȥ}gp[5cKX{YzNht8S*Dp`isT Ke'Vzpˋi^0&Gy@rO"^ ͪF &:d+h|2}ؠ9D9!|>GBT!YU ߞ[g9"IcfsFʌfK[ekxqL?SVHB>C}բ4xv":9HnXؙcjzLr=&'HHE%ıg,W!V)WI/@ JzIZ x0F$Ab Ͻ莽o̓%_yN[8g x4lF(@`1;#4|\\Ag`$E#WUڱA F"RN+\@ZїA5n͊R;oC;z_}PQY4QŦoF)=#Q*4hן6}ålʼn1k]S:C04GL#1N/;Ip ,I@eB`{Wh5"/V_ !m7+ܠ}B:ȡ d}3a#K]h.%'J7be-i%bzFF`J+h]fի9d\_;B dFN2OmYM]@ $Cx/͟Fov8!-D7RH"~pgKo(#ksT1yעHL#(v)>J I _ĜS!:s.^:)Z/K\<3oX #O1|M@YYp7Qp!{DJ%9QB6m% J07]Fxx!"{E;q>fz'?Ŵz&( F~I/ɨj+om#f/e*|9$܇ϧ ѮCJ&($')SuoHeҍKiu+:XVf ܥIn0qbeWNS'wŰFoU<<Av]MoNW%bZiS7F}IE#dr`xGǢҦi ߑJ5uɋrVeOa$/& `"((a]`%(off SJ# ~S)R8&ܵ[H8Ospscl?>Oh}T4J)!{3vb@N8@)SOqENWmHhThx0(pָF1"O CshC }E+ԲzTfĠkYbEC% :'h{ria}SSيRfr25+qKKx;SSVUp/ cQR ^mЌLu1^ 8-6ݺuOx7.ǁt__ۀAߩXf ~;Nm4{({:.lqI![y)Y "T+ұOf'diNIC -TD-W+-dvCnEO @P׈85͙\FaΜ5}qTV8̓y!p| i;*⽜#!NLy}< ᡲV k>N)XFYg,{ U=l՛a(deіt|S7싖ΓkDʏ"OPxvE rqqm=),-\4F5j?66v5VFҹ,Cɑ&QB\cj6)%LB %i "N蘇Yyvb$B鐰7n+E+=!yhlp\Gd]k}ٞ{HhT}_)>PXĜ2AJtz32w1*Z>g.$#WG~Ц2N[t+e!7*AIRc8M~r?F0Zf/v: _&J%oD| y ?.-7)${g.b/md,?u4Uޙ!nHN,jp0I;,FYtwfsi1a*c܃o#2LAQ(B!R)KdJɾWE@4B4!G3iRo+6%^piasfF<)?.\w,Y=+δTdѓqLGfZد6Pm^B^h d*2C%β8:Rʁ;3'L#}F%0!\ QEE<g`?N~ÀLG˟+ZўoIxu_Lܥ xZf-G^}n>&.kge" Sgf% "  ?p$ }0h)=H[&8ۛO-řYD@ֶݸFvWvmՆW)ނѬbrfUk8 |3F8Г90< 砀&kfRKZN%sxԔ3B bVXsoXR5<Øʂ^{9o$EY`7W8@HX;Ы8?c:$ :'*\ [eRv3+L~:a+[]30ɚ6(|}KQUm|tT^K[ҡ{Pa+ji z@{6MyYCPn8gJwz  #Zl]%O/*GSyo4ZXgP)HA[f8ѐaIM>:\#q#ҢA5>p٪7ﳄxIɩi ADX摙QUCj}/)Ұ=Kjoؔ_c7ȏСu. I<^86mxlO![4,,SJa94,X;f4g{I_%6Dò$T3`;6uka iziB"Wy]7lEDmlԺ(A+xlF9o|kJj1uXod hwWn]xՈ5䋘7[ŗZc]tʁK!߾-mTAh"`y$ik{8Y4ifwgV^Ȕ;_P8DϵoS=s_,| j3IBEz.5zg}o\8_A >1).?L y[4R8LFa,9o  6U?rQ7TT((Ѭ7^w̤}1aS~`qlmhj(3vkX|KI%rUk>CV{ʼn!GftLrbd B;n\:F\Z5s±瞂{tVep+d Q-QZތE 4>b%-ިG/156&afNeteZ@%zNs6)|W=50~],aO7k]\vT-MY^ElVyՙMHAI@܎z ]9BCpuvr2 %닙q~أ"x= fpԟ(W҈NbgL bhlf(Ù? +Y&,(,cI4:B'E>r&(6cOkյg4ы}x <)zJFF1rZvC_gBк (m8> _~<'mDC9*ԣ3U䍨7Gl'26s}b :R.L!PFϡՌ{ƞްX\୛k4R͝a5ԼCZ<]:3lН=Jb5hCqKgm_"m4/K ap.-݇nj3?C]1P-O/~{Z & MnN&rWx__Nq *3JB2T Tmp|2M}v 2Tpͼ@*QquM8ww' wwww5 r~ί9kMWWWgsusxD#Mxğ?$ƛ?bfLQ>8鬋x΁L3AeUB/u03!n::hbEAr>}̮QDoLrj*^߈N!QRa?Syֺ;imrMgJUyƉ T$ 7>..Rz0Bt=7:E{ 1QF>S{ {>O>p|iGD)פa(*oetWѐW)cf)>`LۧaU)1qVOT"g1wwߕ̈́f7f⭲|/[>u=+/JVA|]t263_RƕA\Xs49A>_?qaKϼ<Òg'L'AcMתR'/fW;{{S>IVL;t-m0fnv@/ޫІk/ju;XJZ9;)@9DJyUN\`s$1 a w|iP֬wakjpYE19.:۝<=诲Xa9G%My$7+%E?ŔVqX!nr^V- O-1$mU /vXQlaK;hsXNq?+ 358(%V=66SZur 7ĮB6;)] ТKyȪD!~LT6a jBa }B- KՓ6r. c(4Y# wb$iz>]2 BcXRaa̒;:f 1R;\KԵIԩ[BT߿&BK&QTPղ|>YFڨG^N>a;,#&1 &:ED/y T9neܜ@}}g}o8o3}?Q o[Qt">'2B/mafM\6?L؊آc%MA3Ff&4ZEol\jܠ w;2 bw~[*M*zV{3by_^g(%I 5%1dś"(J֥^J̑ zu}ܡ`E"&U))icѹ>끗߭E6=o$?`2ZqkD8-i©5L`ͳxXe^u"c)Kk'"hIF~9Ds_,9A@}r;uWeյХEE=%"dag%9FS*frsVrVƚhb$НTQL)Vz<]8'X&4e4MpSX~$S\d)Ō2"&ImxXuY ?|Pb O,e_)9^_yE *g9~9%D~D>|>y~2A5Up#GJ.L{?ͽ>q䐘z{TUU'/ g*4ۘrnTgɤ^: RO!1d!IG6][^6I_ V0Z>*ewAFbƙ e% B{K|ܜɊ6Bg2Qߤ* j^Rԁ*~dVfy9N.wۈ228{0v ]$2ܣ+KNUL?rC3fY'rg폳G3%nMSOx|/;GeXEKݫ,~SۢHqC+B_!Nad۩#&ct}Ev11A^3-=&i4^Bl<'B.;B$bakDf xR:4%<*`>>0&0DDes'.N[D=KKoWsY%MrEǰݡyWs0 :~&ΗzHI&ɝz6%U"MfJ^Gr>Nx?|D|jA;k $pnpQ&*ѩ"{[KutAݎ(B( Z+)n0dZF7.myVSwI :rk$lgG)rkt di4[kɀ|Î/bfPEa1&{[$*qn6Ulxe70\<be%5W<Q՘ۜ-;w-aE/y":M;-u̎]k-xƈ-Zxb_O ?]j԰ɉmPbB;_x Oba@f9Hm>,q2\nJ:k?HyV\=1^% &RmF|bG[0[XO^M5nOD¦u[ ZًG]Q 5L0[=(i A3.GB)Vmy%(ez9^U<.Q?ޝO{o@}-S3.d>q]ו5 "h5!$*"NJ|EaeͯA8V\.D0[Z{Œ-R ѵWzud%ẃ܊_&ϵo c k\^ YG%:T9 Ly&ā1@ +?ۜb(uTu$4SCV ϾL]Gv_SָgYSv(6/=R%Y&x7rPܰo/w룣GhWNdDNnna~cHUf9Q( $BYS!nX*9F?|/'MpBb^G7GxbjmN+nHDE Dh.=:Et}4j6*ldBs9N{|vIRl5$AT؎ϗ“ÁiFJゞ ;PWGor8"__nS>D4܀C!#, ˯."2ikE^DN0IӱƮM31կsj|FAIŀ t hJ{}@Zu1IR`k@* {Rt l I.1qD|X >hPhD6ډO2i[g.btȚ]A(.m ы!8b|~ɏe\YayP^;9 g#)"RRF2 53#[2+R};/큟"6C1LixiD|bTx5ĸHh;[wWQFuIK3= * 54gj{%*|#MN+Kv?E1OEW+ׁgSӖCpه^(xl_D8S)}ʖjn% ]A+xgLx~&qsl.qλ4qk竝TR|kk(CJV8%@~(u[ ث,ykx4PxlxdghzZR׷Ea\o 9& )i^Xg؞?#z8m(JI-%f,Vup 73huXGLzC{{:gIX5%/oS:ϚIVLWWWa!ʤ];8y*-y;pNSYǁu&L/ʮF7fx Jv7 p{ŏdVxzjGǃ 127eJtE\=]"v3$z,Օt=CLQYyeI!vukU vp ,' LGh֯v6IJZn4zkXzS~ EAA9!AB.gb#%%^:X#D)<,܃5ipcјS"ʽLMIGU.޳`Ii \[% %;B9fOk569nh Jy<4Q+*+{ 96y^wfD?B}B!<$S`*b'Ba hJ<03D7I$6:σpuY ̅nntvvaز%7ZW/[eݮ9KoP+ /H#zLECv5Θұ_+'ufz6P1~#qb<bj plBAzu!.Fwykt{wSlVߩ?PO] &BX`ݲD@pX!2/!ގ^[Y4҂疡0I::,:0 ].k%mҁMЇ%)LX7)sN;J33yXx|AI JA~(TۥN6ٚi2"d]]Rz[6Gas˶GNŖ%6$Cb..g5/q;:uu 2+مg.&3$ZW_6 v;@d`qF2IT&r郯xkjj=OѢd A[˝̍z"DSflzia ]'BoE#$|'yQzA4Sۮж7PF@1K%AwA!wmd=:;k{ y bC`q\x/L$Fa#BYjJp],ʑ n=>葽#S/tD5r6_\2tPNY;1FR>lG(NW I TFC?0J"9c՟hTL1)$++ٟ0UA8BƫȒ`^J} )Tr3onm f-1\_}uϻ sZKɜԑP si$}s$;l^(V!ag:5߳:wSBȠ$ ("mw? / =/Fc>6 oyPy#sQ݅e--1Tfx\ X%YOه&q8# Zͬ J@<(ܱZc6B{>G^=b)8Uhiمs?xlTo[d^(I4| }4"3Yd -dM a[QqxۦN“#幅1 ҇4?DW{WV/Am\-oPO^YVs=km?*&&]B*|zRߗrtݫz˒֚7{-'I"0 ˰$:eFou'83* c_btw: =h1S_,,Zp7c/TύcVfXAUr ey-"D#9,3E_oپDxRqR8~T)49faK՘ЩLc [M8{5|__M"% ;b{z}wwǃpc_Won/ ټ!c6PӿgsSEsR\lg$MX Y!f*PC;×**;o~x#⨆G+[ eH|jǚiь;:SYڊs[{ER5U؎-g/[RHЏzE/t̾tsMv3v훦mȵ^hdPfwgxvR~~l2Bdx/ "lwʉL 薟G%euNOXna#OYFo'@7Ғ&;ÝMij'[Jm.q^^YŎwuE~k(bv)"!7}瑩J28"!4sFMqJ:(VdO@X=<+if:ln%l3tB#zڱ2'XeϛB mU-4^@IMЗ+JPu6PF*@ȡfeuW,*ha@DnyeVKXF׍#"(3=Fp9~O+ѿ&)2W<9z%;@ǏsQ7EfY(lЀ,lN#4n |HSk$23XL $uGGe}U g?2涳=>H獉V~ogn}T{{?>NXI?Lg5<w\%Bsky%.?11q⨙tGۧr"fŜ'B|Q3&|`tr+矙d)x ^4n$ƫ2bΆB*#ͺr !}DmÅ]9ʛ.s3Ά\MR+,9.+.aDQ^Uk*NT}-j2_%v02tX`ǾvZz}k'kaOayX,)c G$ot֮r"\!!-9m/ I#f8xLw[gn*Olũ~gQZלA"2 P_r0BRczbJ[cд8ۯ=\*.a -I tl-y_k[aLb5}<ݜLS3ё5u9Cۤc+_'ƮDo.U_w/Wrw~ !84hm">m!+7zY(P>`b ?^\&<Ώʛۣ𾀚uNV W}+v[W< iY[[c+Վ&cYNi ni˶ 'b0C)i?({)yDT}e`H )c %NV_ _Ņ(wi3(lsoGíƣh[lcAm?wgx刖Y6R~j&?s&%=J>"όMio- Ɋb.#XhG.ΉM@+ø#^cm}gK#CyS>Tn|P0wN#,o5rbƪ=SJq,q,YJ9xˤ VEovqI1QcSuzɜhfqM 2}cmqL8ëTC7~H~<lol㏑C:* &)(uq'wvv࿘[6S##52sǫb`W ,`@r`[,[S֖mCSWhv;V瘉^Xh2u+ a.fL՜O7+!RGz)~0d &N30/!kmT$=|x>l̺-1yMBX*BRЙ7sإ95usf]J $p4vv.vjB##R?Wide8=;}J@7D!E2# .ӝĎ9qjnc,$}G8c@\98bkH]@Y$d[4: ^z+)hjw*"RwFrhߌ醴'?o2{K(n$.ZUCKHN]? =[o!55e%.=qV6ItD6fYl#ThLpx3紸rTy7KU`+ֻ[-Z-&O.':IsBT`mz| 1tllMX"*(@R wE3 Q>_;fO?Mz`kSjPإgHbA9C9xc {cMbUhdED\X\YAN?T$Q~sz#9AҌ#tYZx+ĭZOmpc( IKbL/-H)Gd DRpI[Ak)Ao:Ť&lxʩfX*(}»X%3SӠL}MOLb:P GTY~N/aWo;~DnZI/4Q/nF-Vr^]!bVλBy xEdleT X 7JakAԄ}DDzMaN|ïm`#ٶ/r:|M`!CT_,(I n%IJ@a%NX3+'[@:I++#[;k!!H+kXFKr՜t9Əc\V-P"!4nś۟]?u -4 I4 @>\'c-{%"aLntY̷ه7Qf 9e_WU5+U2 K7\IԔbP@j|&u#lPsmB^a:ծ74aC(jQkLJfoyhdgEQMlJ/MP鑬s.2{ܒfՅ) Aa?@I)J~Z|GqꁕQPYio!|wqQ) t 8!^lczTz59$vj ?$q61dg^B 7\afh t8H5NJdB~]XN}:xJXQnC_2 ~#[K@S8  YN[em]w_{yk|S rqgEz& '#Lkt/ !A ΞUU\vZ/Lqr)ݨWOۊnKayZoYIԱ6."Ps( 9L&^ֈч.ɍ=c ^A c?AW`'P: "D19ضEA+o8:2yף9J/|儬>e`0M=La*X?D1cg7#L_]*3'=WE.D#(ˊ |!>`|jH/s 17Rui^[('x ]ƄِꌽgFY=%k2FH*60qlMۺ\a] COљw H8k`QYs>| B*wܵ3Y8&EbW8Ke{<JN}$SQI?ms]m6i{z*!{ѳIHYM.Gm l>WʹGb$+*ő>./_1_ZC_/ܬ\U>( ɠcJPVAU 6T]:C@Пys; Ď.0*qDbQD nV@ePae^wOɯlct>}*77&8X䣵S` I\OHlSH>j)je: ? on8Wtt؉Qϴ-q碖%͏(|ȼ̆RXx)]9zÕ ֕ ΁] j.JKTayV4qPPU!d5 i4bR7l8Ř?2ՠXT TKy# Dr TnJ,잿 KH#Kwwwҍtww J7" KtwIJt}~u3g Fsw>VUCCt9d\fHڇ`AIe yca41dn?A.v_":ݱùWXm⎘VʣņGRͣj,%}"*Jف];ιM 1[MD Uk8;MGW1gsl}G|3;e8rEU3;FVYáI`m_Fė$[[2b֕}fcv4 +T̓B@Ks=Iި\6AhōϨ/xk?04u2`!w %KIgW7xj>|jʼn1l1ZcrΕʲAJ_eCM6 >Ȅst[U6Lb pu sݍR]_Bx(;{'Q Pܕ/b>b7 .X1 BVjLeFz,?Bph1ݨ |UaHD  s'(ՍKA/opX1ϱx"45  YԪXrH\'lk=IU.XQ~s0$"6ïqؤԁes~Zb[T>g &χrxaև 4PB6q=B| %y㮱Qm|Xy2V M?q{- an10gc%W I2D33&!g~pYΚ;yt6.q_i3 gxCIEH! gtt@Yn y7aBƓUKӷg[4Lݞ@DFݻXxŞ#շ(CW_8JVs+oe{݆atsCS9kUZ]BL/Tjqqf1v8#) tftã,I!;U<h+T8r2@}JxhaqQ ts#f-h,,4)xg` "H5"/Ev̰L悦 QFat}Bv]MVN-]k"1!'CD W=>}ӥJѿaS>;;e`1>p =qld3e{T3K}UV_b{X+JLbBX ꥞ÂET?%y<&IBx`B21%j?ǔt7819x^C ^S:X=US|Q5bѽIhvPW)a&>(ĬwxȘA%M*QǃU;v)n'W;[lTBC6Fsi(+^'Zq@N!dݝXYY۞Vmi~!9{WU5飧ouOzSG%()[7" 92zݤ4chLnVz 4Cx ?gy;3iG)(˼7в^_9:@,d5IJie‹\ĺ]5?d'c9$p±'azK£msēѥZ rc_ξ\AܓkݳJ,Bi@kێ4vEnj(c \Qd5]h' lrQNhNP=|dgKuulD,42@rvЍnx[!ʖ%1dD}n3JssDpt߱}3o`0h DLj) ]1=iuzSjF{.ԖPqqٞX-z)Z3+-| zhƣ:eNhg{$)`,ĝ%d?Wp hho%6eݡ) g}Fi٫Ly:]m 7/40+Oʴ4t\ةIlxΧqlN_wN@ꪄ(AHx2ocIn'(20';㊪VVBOBqZtičX. rH"׬dsJ7,1`|n `O NSsiae2 GZoX!ɓlh܌N΍L0kgZ--`/ώ\푑tBQ15{5?WZ|OWFp%i=f۾+s9M7[Bo#<N>6Fݦ]-~N<*$_N5pF袜WkaiU]֣Vm_}Ui@jNAr;mlnEY8RrsRʎ0R~I"n$RĆMRqc vܩfAFT,$ \i[xxO[-{H]kEn5ZvY2 /y\{";!iRR^_-GZu$,-8RI?.6;; ~$3]8QmoM*W0U9jTMWZ)/Z$L+.@q"BBݍk^d@ 8R- ")]SeKOZɜX7&@h6NL]nڨ/0%%+95[ڶz_$cDPfOrsX1t`C;x5&FACOfrQXkGIΨ$i:~66VV@8a0_i:\LE{[ . #G>uxr FN(ar zBcc2e_n%K5~#UhϮcDW zJn3ڹ`4zCB+fO(ef,?,ӭHx6BJm(p\lZD5]h6E>U$f-G'sBtqԹJmb ??Mxś.8Ai~$l'Ne۞?E`ONX0@@&-wȡnNJѰ`=,NRczْ uUr5 pE_XӘ M;`Чh߿aVlVo7;"Sy>T1] )๮.09pHC5\%ė4>7P4 ܄zB)E4%$wxM9&ڋ^ݪ;ij7.vXY<\>5)umg@wxygx͔Z) l <[0g1n-cp$wON]`;c-ddV}J| h˲28˰#O*ʹ%¾ne\oDZ"BR™;>NDI2X͍1g} j>d]4+ۦ[Ѥ VTeMb6"PP<ޘ !yeŘV_kz^Ft.ABQpO'ι3bl[dsdX@d J7.A@:mʗInyGC1e y32uDpq>CCq*!{l*Ow w.=`Zx/COWQPۛ쇻lZ/Φf2)J3J78 5\K~:žBScGB)UaKNN{c`+[P;X?[Ζ뇙>W73vf`!<IS@:}M~6toHh`tXKGFr[ϷxS?UwŪAu"Ul7[fӹ u|j.{pG{ͬnCϤo;#on83Ȣ&]j$Q&$c,? C75tMi=tjQnRؾ2@WiX= Os@gzxnC-qE_n?&XUVVn?ƿ܍oOFŁmA..lT!y`d 3sΉ]<zRfG^}9Aȹ 02ߖX2~ b)+p+@R[-%Fл+oKI`kkk ҲN23|'W:D0 iX 6TspבH j&|#C[q kw®4n^$>.{w=b 6Apnks 㰆0 .LiVKCo!+xl8NNSͻYrddd^->80Ox=Y^AQ:=~9 ŝeG[)}*ܤ1.uZH,cmXr-0bΎѾQwu; %}s}u㳪@ct*w."~&)o>'S==VD#ReS_ᅷcE E& ҆[uyӊs݃U{dz{ ׃BGy6 sw)^u b;ocZye> Ů $}?h*J3uA*?hͻ &cTdR o!d}z'~m`Z Z3TJs2b'X+Γo?_/gqP>;G."  j +lww%5Hi  `Rdى9SYRB^LB8M؈.6"ӫo 3r6Ҟ~>>1'_ON~@ngX;|NrKZ!pN8~H& ikTW$寐m@ o0' ov!$}:=e k^,)7APy3+7_qZXSA3h4Pz(\qӃ-ѲVA7Q]ñ 6Z7 $>, ZFpZ"r46F)k$qqڮgOLB mCy+L3dԎwJ矈} IVQ^N)NI?&'ZΊS~o_ʟ5_k`ʥ큙|Or1kU[5>+jS d0or?aC>PGI!қ)oصwA1jq9i~sP 7..n}`B%JOaYm'{6ӞS\Z6W BUz!qA\ɡtb;mQmlBzK uA#/FgjL(,gqK.Vy9 @|2J O^; }4^ !$UWCFl/^ܔ#Խ2oqN@@HƜF+ B<}^cF)@9W2-L.+ 86@n&-=/8剠,~pޯq; *p<^|S0QS Z%o![- S0BZar/X ;.2m_*sZ2@ }"HJ4{4/_vg_~jW<*3]H̋?E&\2u6Yh*9ʶ#khhRԱE5&NK"@p}l;.=GVujnz>䈠 |/I#tB`n:h,ޡBnC-'wٟnݔGmZ>\w-vz_8x:aH ضԱH3 LL `Γ1ZaNx(QT\P-T%ö * =IagT5A.t‰"nќc+㴏TEfQA <}vz( >Z>r {|7lQ_iH6}xNҵl)jhRle??5S>.-, zBL]sї1NM i\$64CDC0#Ϣ㓭{,Qڋ]%3;;LgrNNV8H nEv9G lb`Ue _8,v8m:ӱջIWLs3Q])E"&aǎӪrlqSU@ < [VDJe%,c-$\ޓ&}s$$[NZ E |ɛk9`0i @ {4"&eS;Ce>)%FQ ј%G0ɳrq}FZƆ(P -$q'=^T͜ȟB~󗰹-\no|([ p}9ٵ4q?^M?M79n#*۞5@)yOQ,5[!s49:}ocj1o)h9|Bn>]( } X ]ssDa=D.ʩG.ܡR@w|9Ryr!t;^ `% sɓ {2#whoR.@"eE(8_"Jt/ٜ=s%<ݚm>᭄U7S5zʬPPђZbPRpsss H ļB/@.*QG> jwl0 Q!{BrdR[ 3B~u{:rx~ xu_xGdx,C-#2)1{nsG=W =-՞H"PX#3qmpmɶ=ylS(3w/6#>=Vv>*.wmok8{| ܣΨЬbOQlE&8Ӗ٫?nci2P@6@vFONIQ(L, &HfZ5~AUFg~N9d9JɟS?uK%C4}Xsvcĺkx]UW[xH_ej ڌb=[jHxt^íGG+ u8jU=U֨6-j8ĪY032P:= >HqHX ?Y2J\y`x:lq6P5$ZP@Bʁtfh>%RbnMPVN /d[$`ڛ">u(~h1<ԏYgK416j,M Ujqd^+26ksgMzfݪ` oNu‰]<KWc!ZX\<#R"]OSy mz,B%G)] 9(>hkt,h $]ȝɇ60**.c?u4y@(Ͻ5ffÒt;+[E9s6Ht&i2:X2]w'?{dk:}`zc9(C U@V3icLGw4 a=t5-[BZd-dߋ֞ |hD#gw7 E2YpWIg-S\q&.C\ƇIjڌVTRNV?$dV\]cOߐzmx*;ޛ<۳>uO̙(1l[v] į-ò_~0J;xlmi)j[< އW]K.'F G r\\$yfx]{`xtJ1(VFqddZ!rj]LKON_{n uXY-&oj`E+qZ(`[(׮_rZuz]##7p|h\˝ ]X̅X%(|ZU4?>N}j!lQ6i&[,38ѭƈRVH4EPFՀw>/y:ZHj$ᬲol%Q TueBH2 33hXS*f$D 7xpӌaj[:(mC .M+niu-`B'_w<̿X>sAS}_g4 48vdzz5S1~.v[c;=5.?<0 {% (8.w7P؉KLИ#E|ExK"lw sfp2? C;lMǰe*cin\f ^,S_ |[" p]e ռ5J !Pʦut_v5@x|wuDHXhcd' qTvMEh|%BEeW0M~C fqVj wpR Y֧.j@|u;h/;+-?~Deo2k|?k~$TBs4`{l}Iixv]Vtuͅ266X/d[zp&pB_M# [ v+nt0ڟ_Պ0VTPB$8tne2Z=*B6g$5Jā䙍Kߩ%Ovj:z9eۄ ]] aZpY7oMx!bĤR^\B?h f[T!VklHD#".¬l2T عPO9H{yNDaނL^hQ,z$iwtl΁p?r#kQ ɇj*sʥ5UiY9Z$ϮF9㴧A Q tlkm>O&-PDLJrt* Nf+LC^ViW0^;lQJNwVH vYÆ\˟}1U&e?RqD.Dհhb}?c eUXSĤGveSn/J[kq7}|K<~û]jhlttppCasȖ$Zء"5jaRǡrG&M!w }1\iB\HHԏL,Tujn:trB7 Ϲp? [$p]T` t:*$$S<-ĨAdjE*,5eo"E:п 'HPI%495~кPp_y#I{ZO8=95i|2q3zBCB7ȯn{|[">=U9Z)P0F7V|PbڌU`}hyJ_U-s {pDj !{$\$К3!H|`萇ML7%\0!}2! ]ן2޸>Y.IGd O.=V5'42Lt`Η 5\xR"+pWJcK#bLj*VXKNM/C(wÐu"fW)խ<"jWةn f񞣜"B`+r[HHK77I-:|V Rr{E1kܺ JMr tf)sFXz 6MY"`00JAΜJڣAt =9W8͸%}̣nvO/b+z/Aҳ*:O\lp9,eT/Qij{fTPjlщTPRNUJFL+otSf@%u嬱}IGQ6$U(v]pLRNL [0QVWzoy^|z캓n] fӳ/'0r$=^@fS/$-sCJ@G]oaU8)R(5!Qꎽl"jh%!B#Mx3z܆pxH{2uX0phJ$tZ?9`mOf سqћR ;ɉ1du,בoO/?\k \< +zQ'm,_# jetN*=gƧּ~ Q;SR`}p=#|TA}0#Ɠ*x[TKR7qBF\'σ?AO~I=s ѥ(NXB@߻;n{b].&*O)H -L/yOт.8j0sDX586|w}ڦ-ApOkK{{S0UE}ryy𥆅`e.+*D~W+Q9!C"7oi4#8bRuy8iݴGj`,_ɪɩ}^ӓױ<8pǽcĽ]`ɸȄ5Za(N6Et3ib#q=P۽<|a+a =6 Cw&eȩAGSW[铳"VS'ĪCr"MzNr*. I.(=>)-pwÖͭ~%Y4,Nڍ;,k#32QdB'ig/8lYaڙUn11 !Qy7p4Tk_bD':dOc9GHi-s>oaVrz!a`%&vjpfˁXy-L6?ʼnzNgk?] 3 iOxx9>gA/ΰI!˪mi[H$JGlE,eyP'@AAE:pK _~őptb$iJo)kg @v"BU ؜5~%:,G{rr0םWEt%ZȊ!!0ǂa+o|z@5)VƂ~qp0N}.vVAD!dDg&2fIohP$2Һ'[يՃtbwUbDžR T,ٶ]&bIY$ .g~ l<#|Ӷ~ѭ4B%w_ߏ# cHa,~™*sv_*ͼI'@_E9a^s.ݩs=ڮB0a4dQaY<)I/ʕEBt(>zQ6RyӛrR:aaL3󼯿k}8s1B!i0㣫ĉZ|LaCFƹpT WP#[^A@!G]qRC'g3䋦JUک5#l*vRn 1{F)I*BP+jgħ3ŤIWygy7̤J$P9L$׍0+\1{r[ĚG t)_ Ey`eqhkY{:ȍ^J&uId[f!x_a61-ـP]i -7ɬfѨ5oX \>kfo_+t&`2<^1|c^ )KL|4U@\Mӭq4!C! .wwww2g]\EݫYջRy9+gaޣ:}XZ tq)p/^s~o~*'<U2:! #9U(O U<\M. ʎ"R(fP:O5ȫ>C#6|m;^y[,Jd[TgOϱo9ÅxKy7V%AYc1@s]l lA)4孜ğhbTբ({٩ J= = ؁SdBoa,,sri]ѣvGC{nws^W鏨&] PGsNLLO8 ]=CWKPjnK|YADǃ1(|lH7SNS p:8[mY ;RL^ɠU&E_"el CPbN,\9r0\J]:?mv߳R2aOf0(<=sY !PFdEY'-FKGpLO&4w["}vߊMn3U(^pyn:1\?X v'Dt_ۦ)RY%P.., z"$zUZu+tV2Mfx@wש&VˀIGSCUv¡anz+0uz)oL jf*IJY \%{@8>-2xmGGJNjffԚj(P9;Oj eT%9Zӄ m'FAGIJ#&H{CU;i(:W }{IH Veή;eLqSS(ꍣ5 n,G4?`\R,?fZ1x/$3vW=|DPR*7~C?XtwcL@ -|Na@49Z]BUR&^B T)$$)P](,6|:y<Mc0 wcLZlžЄQaR%Kl,׹ejѰI!|wߔ[SKEA-1FQ5TͥF7".P +<=~*uR}.nqu[K#ڮsTc\LrDa,@4c7,Fs$${"9W))Ks@ߙmhO,$#c( veR!j%ktuE\_'ϭ>||i=y3n{ -wS7^XSBBAAhG9_A8Kin gˡJ #wH.Uۅ:IQp ncu%ax-8P(ز>3%}=6[ͱe +[O]z3{+u=vGmr5)dlRLWP%NCc%Ol7zDV{oxO)gD,T_iIء= Rw꼈 6Cwܲsl.QKB`{ UnNuUΘ>ㄍLU'V(|ğjl<*ͼOPh)CvNoiTʄw\.=il>?_fnGtX?x{H`P~}Zl<<\+H?KF!0MQH:QTT4vcQOkΕS7 ^dEV:v;e3@jʳlzmۂ! 8 1ՔL\`pu8ayh,0)5_[^ #I!`^UE ׉ِŗbNb"Jjw ш|tFQbl y5~rs@pe?=:)yƭ8Er9|Ͳ2*lBYef᱕p2e)e )(|#>0c:MZf]uJznE}[0 tFuYʳ 62'VպF~=Y*D| "}O v:q};_(Oij&P^e%$n@[DlKJ 0`.‰Xjlsx:1/hl Mߩl~ԢŽk6T:M{z88>{yzTTƜBBq99>vc[d3byu`!5[L/E9cguŚԛFEv"8{M46} ze28 'MŇitg2 wU>; s?)$_6nԲ(t=ŐNN<^ղ|(e=S7y7zξ4E밚楏GSѓ!ݭ⩬X0 1kSloR`H>385>CZ\Hg S[+BC#Au>F H% EJLM:,1{] \ E[]1FiG=CN¤ϱْQك~(#>w9qbn󙂶8h">1\."n_c?cvAܹ=;l J>ӊ`70bkP`|*ɪTQ 5J9=W?Z,rqY;tM3-e}#r?qxG76rWTVb 9>9{vuw}rBdM(t]=}e_!QFϤe[6ٛ. YD%@*.BYC_.*bmxnyyfנ" vW,ƭYi iu !~Gھw, {rjP!"E K)$B2gh+Ы9ej$KN8 asx %uZ9 _N1Cƛ\V/{ Ŗkk\(<ͱr| XY^B| NS7hWfW_XP,'+`SR[pQ:jy#KtJ#xxuZP~[r!G>,X Cw28Tׇb7+D6;{F}B땯qHuv}$gr2ϤQ?d d6;IX9FeNiU$69 ][_W͖YIRQ^9ug@^1ַ):sCQhYٟ.$m6lDi^ Nǻ.ܶ5oAg;+''U7NͶEx&e[8y !װ!9nDPʡۋCNȜٜ͇ԾTSm7Eވ̕G[Öܨᖅ7 EXil „Ay S VjO;1\]?L5 9剨;+SuRciTl["s 11|NJLY)pbKX2qJῦsn`|մY¶fRP9w^ʸ?&+=2V~~-e PTI&pf!ڶMIҘzyqyߓ 𼼾{}.sev%by1uHjYчfab`ps%BZMdWTrs};Ѻ䤙.JǴ0O *[IS?y^4qRJ@\m/t[4N~O2y(썠S<|j'N0k_Z8 ot#mWv50+gX'#kz3_;-vKw4DzCWߺ3/M&5 B;XgB6㹝h5g)]X $-]OSn*St8K;[xEfb&o7cqZOoHfAfBv_|[ˑC (r:d%U@b-]֔zȩ Ţ1#Rs߅&ok'!6-c!fx~JAs@jMi4.6a_f|ۥ9<f !u{)p"؟e`SZVoݖSIE6gŻ} kSc_Δסә85GXFx{ͽ^S1ء܃CyהY. mIԷeؓn΁ƭӡY$ˮKO/{v^D.cFC?2qYazeptBLp0aj['ulg|Wcu-F?wKveO#:7lU7PqBNFe^ј53 øR(8)M#k](9)fP*g dLB"(PY,Jo%1~SA`6x`6 (L|UO;PF1 h#J>/O6lF]# ^B Zly)Dz+Af0+`#E=6~BKCSRY +sj԰dY|]bx4Ǯ,NbHA*R۠ܫ)PHECͳzyؔX I{^rK竨»&cQ*F>t!b< JXxd Smf)ҥ4I~ЛH!%(RF]+ ?9ϛ鐋o%" R.=.J!M.^4Q݆^9Bu{Xg*LCPGbF𨚘bkFbZ麪TY=Y6*ZkkC;ÿ6@BYݑhy~IԎwr"tE[w Y/} +ݺy3BtGAjIYك1B;5%e @+(lF$ IZa£aw]Vf.VXʖVd“Hpc۠0)`E'K' F ^B>HկZ5cWTQR$#=^PᩀC}}ҪƝvGG1?`+߯+gڊ |sUR_4ZId7k3v%eKlg/+^2XE>W  &ͺ\R͡|ߣGĠx^,{ԍpPt=; lP^u\s6I1 e@ ˡ?elÑL43QҦܭxGs7B4NL"Mjx+y fBKڀ?6NmWZY "N2! lmg.C\+.cXVndHyg;FUI8gGaI%J$)A*ﺪ/gQ%)U0( m$ K@8puyS2(˫{+64 {2W YL,[Nst+DUG02 % k/Ø9&&8Dt=@upk'6΂l_髓F\ džR%("5^fԱ0sJ}m.(t$B TJv%Ec:ȫ"c1T2篿GH'+t›|5&~a:ρ~P2^QOqOSm3 gfvdY)a#v4zxkљdfע;EMQw9\OֶmH+ R歾吏e5*^mzy/7BPlI_wȾw%*-Էzfq,b $r>ƈe,OBB=g9gyҿw(|xn`~_]MO؟Tx`t ^^^.=mU+]AHٮ"Ua:"g^oOj+1bD_4[\̅6Rn'z?(qr;q -:$[j#L efyXY,rc,4;m\C w=2!.'%usH:au,2b<=:lGHəluKIudnƹ,mښey:_FEdѳf8phIE}ˢҰIBƫ@-0BĜtץչZ6kQ/l.o5?0zta 9(T13W+PWdKh$j\ y}޴<.Uu66Ŧ9Q~RUʡ>{y4ilv5/?`wz& MĽ7H#)V2`fF{82N(.'V.e~-t B$2-Fi= dHL G`6Srr;>b!4 O!%BOݟo;ʝ8bvKɪTȎ;šɬN1mz7{(z/ڮ.?IVSj7C [yB7d1 s4fy?GhSp~ Nxd) ߯)q $$ʂlrMP?YW4ϟ 5tϗ1"'X/#Rcqǖn[ Ǥ󏶃kܬ?mA+ֿ4]r ֎1cvj~<rH ΒˣOWu,bk kܪ J|C`s0f&ı-OߦMyGTL\8ZRb2?a,9 "5ox>\E\Z}*T9p!KE~`ʉ6[t|^-jrS&Lz#/L *Yܤ}qimV_0bfħumKєg, V~aheD pmiВKDXtނ|NT~'SrR"'UE#Щ:R/˪K/œS4d={/p{vAW'SN'ٲ2U|+sXVf*D\ k;%8g;?1O$ErBuM5GoztMt>N{9plfC?F<8- K 6ۙqEAwe: +>]%Ҳ(]]t$ezvOH(_&> 93D>0Pgh+dYK}KRXs57xzg<5/822 I(Mں,b57O?\ؘa]AP$9w X(PH3BVIR-eb !?կDyxw{aR1Ia)gRؠnqiCFvcO pXd*ק,ތp'#2K缏=E)yg0BjAHq4JI` -_|!ah_J%U}K"޿XVWi'r$!"(o+|3YFuCȏ4M}"KʾR847 )ip'Zd}q޶,`RH7B Dd&qÿcgnks@RNʿ"ڋRbV'`=Qg>#'8B2S[9sǂ܍.2q'-ꐊ zF˝~|RL}}N um$rHOQn ǷC BVZ,RAoW3(^uUX(lHV?1|׉֬Dn f$q+V*+ <}H_MkOu STBG }P=*WB{=≹Gck\WM ͊T%^FfA%ɏvd܆ cr>.+U %hwyΫ!i46$|o<h0 d tur$`e$X㷽#tX0%|[FJM9~#I:2ӆ /a/QO9bsb]?[]IE{7[!XNR/^jŊ]>HSͯ!=WB9KC˪ 3BߵhJ?D-rd"$R!_XθOr X=s \kyì"MDKt qiq fʂΈ?,.94oxS;*.z-%#HBvfZr$sZ.[TӅHUsIwiB>0pC"nټ>v3ǥ4NpTu6a:?B)9_$}/^F>I$ޢWr冻L^@sDlAqߝyFVoLj (A2̜.\4j\tBo3 o*6qu?wW"tvzA/^OcbDΰyq^N{\tH~O_.NS e7R@DP$ڮ ! `4~f Z]ღG8QRځS(SLC/MVmq`'^vXuyQ|̦Ĝ6:Rۉw\$06hpotq^?z4MX*w&H mOL}7a™G }bT'g2JqBsV#^:^h-FG` e%^r+dZ6<q*Lm?lI#1ձ/ ZDŴh?mg=J?.\')'sn՚ B=xm(=/0~c9V,|6Q, IA(f8hˎ1ft)c@i&39%bZىVvju]ck}]kB=ߵN%3رe*?{72);&# Hkk{on\Ez"Lf/WӈuR^Cށ<u0w'xӈl|ӭCY dP w3}(|GN"!_&W y}QS6}21ᕌq{+ UC!^+Ulnc tWf :?;>S\M&{T3gxMAE{ u>JA)A]r#v}Gs%!LE~X$hU)k'dFl0"6%!#Rͺ0ic񱚛wW{ҽ8)geΣkjm<ۍNB*04#`Nٺ 5jR'KO*YG=^0lsm,ꩈBߘ`.a!oL9s{Ll qkH }/ƿ#y2QmI+-胕H%V[t>v\sEa+fL@("y7_ov OݲNNlvzVC+Xv}|2**E02OrN@UؕEW^d_CvMn!i(:8NuyK::mdTs1Is,l~fɗ LD ml7 쑱Fr# fs? /*z&b뇉]񷂻QŔI1S71UvΧ 1պUh)1bg\)Y}sm[8*9'w_| n̿WW~W uؖl?x$zcX<<ϕYR Q"Dnuӄ;ǖU; xWS*%h⸀zUA1y-Cp7Y `#sdG ]7;V^hЙQ_a$]q>L2\7/ZńZ{=YX y-93ia3=ۋV kHb[Mo*>UY >6'ٴ(boiKh @үt;MtAB촙Qՙ#a9 ]coIYˁ #m._ SMHo;ǵr-X!cV_/ !Бك [\ʠ{RЮkĮsEn&ck6h#rdEa6s:d0P]ѮÑMΡI6!oWжaBo$km*kįpbWɺ3J>9(GY[=@\ (^Lk{<̙^6FX`k>#TX'߈$ Xȴ: aYLq1cύ%>0$`\IbI*l|]c >L AO%x"󶪔O usBS+++[nuo#ݝ/U3J lv}uy I6a^D| ,$_Mg^_waZf<(vX x#ڨ[zn&y3D|c|HO^&xS'\fN|5KT!.WGEeiVQSW!DLi0.Bs)|x6 |)GTD bp]NJ5QB듮 }d>*LV,t5U#=5S LZɆsTWip+Ln?tQeˀeQ] )@L[̠mT8^-Àe|* Qxok`t& *!. s)&6z֓qSk`)h`}Dn`AfWNxus2o0RM .iىV#v,~'{&1k;A,rx?E)?Cxm d (-&ݮA9S!PAކJ,!@/kۚDW=#Y-oCyzɝCi UP;vCXF?GNE ҄VJfOemG-~& b ъ$\)ڝÿT'Tɝ|(R2% #y[EyCȲV`sЀ?m**EpLDspE܀%n󖯌<25JT]Qȫ})XeIܣku{K m>ʃs#̃g83db' 33ʹeW]>^.e?5IqamOt?(ȋB2@7o{SQ%IXzҾ$),IYF F{/%om}]n>$̵mc.t]L?| ⼉q"J(8HI %Fj209n {O#&ˈһtK^%IwL~;TvPA'B JEuȉL`-PgR>{͆U#3f,5yj[0="V9p0!s v^Yغb/|Ky!زŠ*=!;8]qCssa]8/ DKSjFP{ 7҈fi5 ]k q$pfEj ێCQIS_&ZtOC?cx:Yv- ٭*v6u6 ܮ;eU2"LmoWnAԩN„Dn u5KK`_ ;hrD~-EK7߾HWO -Vr}$wv<`dGsӘ38f='zaE!?>![ø)'׻ %c**6*W7g$+}2ǽC&)j q<5GL’˄9I:DF7kQOSO{ZFIX!"@&^;tW7֝]lQ03EFӑv#/O"NIm;߅)p:meS"@R+s4(c K{^TソSәBPv;YN~jzq7}i!K WizIĪ}`OVr,iK,5~: 2op {a[OH~za6B򐏍hdQmbU*"6y𫸬餬VBXYĮ^r˻[ v tjOLrB,UFr^[8WNgb#_Oew/۸J x?9 LT^etȝY.~dz>X]yc&~-_ =u@az JK?LFH-#Wi[a[[J# sT>lXߤ]1gʒ~ܦUk1 !,\eМg ɞr}wla*K6nmf& n הVB &MsGGfd }H:a ŽbÄہto[1AB,VFUsT'GʋPih{^P&E$7YY 1\A-ĶO7&c'V{LA=*U-I#ϝͪeST=#Q[N)]]ٽ }Ff  r rۿ$uCNㆆİlK-Y[k{>6"oD~erJo1F61gv/? 1N B:y;jɝDISjaz9B@֝ҁ ׄsUwQSw3QEb M>0 n)4Zy\~Z#! E[i12MZH*džKE Џg؂u) (-9i8gQ8ЁGZaOcs$D%Y}nH4,nNXP"o˶&Qq(JXOgt< &!D&̍wϺ g'h EavX[+^2yjumL>r{a]=ZV1-T"N#+?ޭa/ۣ?nMe=U}|m3e[y_XAp6HN=׍+;ɳ Oj7y:rΥS]e O"\5Fb6mW^+!Jn+wZp2]LD*&@>3!朼48C ^d"v{хp`r K6A}ωr,=bbi&]Wbnuiyxf5v9-lg)a;f'vsXky;gPi9\=eؼ==t<ʍ&nYZ"e1!rn[Ͻ< |1.F&-XH24xJ;{X"F-u޾7F 6/ )9++P;Ydr: ݂q Av.f+o|nE'~.hц=aq3(~}߁FozD]Cysss$I:- n#2DxOlRBh i<4oys*kdTi\q=U:I{?( w [ 1y{ML*"Jԗypfӣe)9  9Q6е8 С i ;#Jщyz')q+A^~QҸizl^t6ƕ ɭ'daM^$^/ z|דhE=t6?Oh)I޾h* I˰ŵֵ.v_vx` Um,]^w2LVوФ-~2:T}`B$cXsJb&u,`؍_!$,괻UOgX ގ~_#L->']3jFZ/s+ͰJMs m$ 7IT<):>)Jv>D:ZRnԽ1w\B6LSVP^N[ُ=DU/eN%1}E*ދ%'6{0~{b5jqx*$< 'S";9dD`MY0a%%O/-|Ge2"W#3Q`4{_^?.fJdomsk⑟NT(m2Mi_4i =ѿ%aםˏ6I /BĻGt<rJxˀk(fd}N~W#C5aoS##pۍ*8qJths|뚕ydlw.ؕ3nʱPHӇk.`x]i nGG?멇JkI9^27 KLUe{U`4"ScDqOi sX$fZ4bf$b,|!84^LEަpݖh_ $IKq7 k4.Sߑ-]&~p훪t>L˘c.:\>w9 X}iQ?Bjz#2vH3qg6]BpkFr0jelBY'ž)SPi .m aҸeIe"Kh~@r{a?kaVܼF >-~̿T&Zr%: 6OMRD|p2ݲf`hhus&O#'gXR CC>ŁMkЍ~ -FD"Lhv1c}ǰ5C|nRqm|Q@J0 >{hTk,e @Mș%F}uJ;j"zbW!ͨmbATgf.he7649bTJJhJu54O=<6K( /5rs]Ȿ64fhUy4'70 ݜly_ Lgv:dbĠ>L-dғ/, Ż/.Q=ڬpkuA? Dl۬Yΰu 1# jR&z`W755jıPՖKE *g/+/BӦZ g&!onG:gu=M珮uDF`H 9M$ݐṙ >W-&GyQ V[pi5iP~:PN%$y` o^"\b@TI>eW bAuaߵsrϧB3@cՔwxLsĘtDR_[ !qJ2(^Dإ o5g'.`툴⬺PR[-S_7yŢiŷ!%Ak7\8+6.IنKi|oQ'P[?u2OęyI,aO).SZ.^:[=1s O=UIKCLaIJ>#.M O:=aQv2)jX ['OOϫO?:]Bfm]gU fuKaY6_q"X6%n &2Jfm&3,S2s?L׾Es5띎ߍүbOfv *pʉأf VI'RܡVKv^*lS9ԧ&f2r& d'spH^w}ge]M@w .>"Ӌ2ND-KQO7YT԰_}V>]0#.Vȭ gna^bgpSus41z' d4s@`'%Ջ J ܚvut`sIQVtvwó!{em[KŹ`b)D\hΕW #czyNޝY~NGTMս]J)prmPN+M ZDêrTaXä|v_!X޶?&9~׬3,LWɠĦba!Ϡekww#Y\\Dȿڀئn-N0B(Of^aY;u@oZQPxU pl &u? ٥T%ޖql[G\Kb23N3_voN`Y=N )EMhnDZ"wGU';̘yΆ5oŋU? 6/ԆBQc}3Vһ T"Oia)ӳ`ɾv?"C`&ɛ][5*0hX pwLv墧Ҁ {΄!$Ɨ <5aRIUԱEem2 [2m9t]NǾ`c]VWU[Dlh@]˔; /2 |~63 wb^UquQ8̮8|N*07,sϞkǪaL Qx%P4/^$%<%xsq" o Ŋ+&t'~D@VX^UBh&ٜh2ɯg.-GS]_K(H+U9\B>{|ٞ)QuϮ<,R} XD7VSY)16sz3)e~!֯)#uB*Iȕ[ =d$5T|`!Nok74 5u(b~|C2sb_t לmK|\~Ǝ00(J2閑8E𽴤""4j~Y׼}Ae0 J]n( |զGkU).PF-XȠfe5- Qda,]Q ௼1AmզfBO銜ߣ瞪0]g\U,V0G`@؟qP9T_ʳisaO͵--#IM ~Ξ%y}g^T Oٳ=(IgٴINk3KLk[^ߎ`W'J@pZdg_L aɮ rܖY6mƛV`-Ɛ E폁 Wc+-1zes&zz,E\MG3zGҷ<{7 -XWD/SsPXljiAE] %E3=0jNEʗp!u[{&?"ߑ lSB% [kb!Iw;uP_A_6z3%YJT{4}FZ2GZ!Ӥn1jB nf~he +'M_7 " 5#Hžpi`Ykj=`R&td\(쉉%<|UUX記.~NoLB:n=I >d;]v6mvtݾPN\~@Js=sO/Summop۩$:бuU5i;p6>2!VNO@h=9&FF߹Iؙ QX@wyNy=A#'^~l ߯,I:XE i+AS6[J.n=G V;i esyqv<@KSL?3cǗ =ePt{\F4z] 3?: ". k)h=A@洵WA\  |GS ϗ퓑$ͮ!= Wtt^TԷaElQK\d}hr#&NA@L..BdfF ?V|;f=5*鮥7Dˉx%Ad)vHMIV_+s܅٦iJ_N?ÿ PGe\MIƕ%c3HK!цV ܒdA-JBdMk+4c-X Et2_m|Z[` {\zzxBhwzX%4f?U=7/,Bn:/D:{m"Dғ O`p4nSQŬ1WsWٌ.-RR5"3Y'Ǚ4ԡhnYk>*MO*Ye`PQIOE00.2Y97tt-RNy <lO`1ZQͷb#qIk3׫{w1oϓ%^ [bQU2 ׉58D#+3G𡠠:}?RQH~moϱSG,Ik.vz7ˤ`>}LH"ɟ@FNN|BI.{,R35hrO*k"4 3&>CŔL#Ьc`Aur9hޞ0iy=c4ҝQg cXX[wZ!ҩv@lZOxɠyi)37:#8 Pe gpZMf Fo(b6gct)Wqb`e~.Ϗ^Y7;'D&ō2d&~>k<_HU)DRMy'wPcY/Ap_ bbWK<2Q;G'=9%efTdwXg"T+ITVRk 8Mz!Y~}eTޖ~tplĥɏ5Y0E#W"gIWNY}l:,ozkЮZ׍>M,PbҜ׮1gbz}qq;ld0LZg9pOD nѩO^e7/6$⃥_Ț!I!' ;ilz5] ɥ''iW H&p̰2KʰH3ж{,f$M`x2-ͫ` #Îի5[ćض7 AwkS?'ԧs6m\%XçtM€_醾K܀?ZC)q1H?n>ݔ,/#cڱT0΢=Xs݇ɝik,RK#uEciXfU3eÓc@0~i8ZQ>6MTa=A6ϬZ?*]$dut9:Bbš_*bZ|; zmuc7FhO_1hLOpG͸|U)WzIo$_L ~-e.'T+-*C7гpY %^Y5Ak7|Nd^'AXT#ӺrXH|c \j09UBJGA$$CHNw M .Q^._,#y N]j3}V.Dُ`W-a#zևr^w/AWwzsQzM1""N=I9^.03ϱ  r uPn?D{[΍"[Z FqYo8gm73{.PĻ|Vr[ oN6aֻBOCU'C>T~hIjS3)!yE1Vha7F6rn (k01Ԑ5f S$3cp쐃/J|tWMZXvh{r2?Q_ΰ yn~L4=kQavs4(3^ەP'MLhzV`ali 'j'`ciBdwWc;mqQ5fبFIEY.fSZ)o *VE/.WaGms3O$UpMW4 j ! `'чwwl)NU0!-ۋr7R߭몓[`},1"fcR}Bs"u J݃ozU6T6&O6.feu('; @diNH@a\Wޤ/C(N2D{8VŤ1·>|)GRiq".hl{@޻g"}zz1T%=""N)e@,i6,t% !wjc zgˉvEvg -4PA/aisa-h#mgYU4ܚCeMAqFԺа]5oIE¥`Pb&ǔWk@.]cŻP!nULR X"Hj03 ^^ܑWEZ cjb9mQz{ Vu+ PG=yyTwK=ڢŕ ɝTb Fsx|%/4ZәX`/8UM{/{/6 $RbUcy^ a0wnS|u PyZ:&iUpKMɶ;tVx4X7wL*bhYjy=+S)F& qW9{}r t;{GʖdZ!@8 7i mQD$wG^oM;]Ma|Uzn\|#gI1H"8zOsk[xI4.`p+k * ; b@*] i&k̿C!Yz Aꏷkc\?3kUuEZQG릆TTJ gM۳@Sd&Y;4ɓiI!r"g'Ce5'ζdvԋP%ɱW'tkEylЉA5PSqT /dtጌoq9;ZNY蔹bR䰳eԎ}vmF)v.O@d%αy++*#Hv=ō1$y7u;< G,&ҡ+bj[1"q0"$iĽĢ b%N2v!!3ٜ2w]zhŚw4BfQrhEۦbt~IePi`DpuWVEghl/Um8(_ӳw\&=Y*-vLJT{Gnq9(yJ7yXI5ڲh]c^Dڽ$3Sw>|ҍF5s %v;YZɪ ckZ< /# &﹏Ad0sQW,3O?;w@2@3M)mVWQCSNرgEm '3AVo+; F>oLF1`o=ht- ((H̹q ~̾Yf^PV_nw€U=糵y%x{`֘yk Po@zHW: .qPb(hek]~鑀/Ԣ(@/ %rhtp=Q=/G9[Iͤv1VkJc`dkk%󓒇N送!\dƑJF9-5Tr1JnR <}oxS%m'=mDglmj)٦0 nr ݭR2?1PlWUTX>AglX qxNNf{D `U6W+@^[o)-Ҡ>4rdIEմpl岌C"yBg)p47Rwe܇*BSrQ[ ˱)jz{oEЂΔ}QRi.N1*䕆jhf3bş_桧шˀ db媐FuSYbt@;{ZX>Ԁgϲ4mMwkKM ԋ"BzsNO/G/m/ɦ56~-$}Di~)=tͼ-ϧvJYJV),hş yD)zs>?=淃v`4ёCnfPpmV 4?lM-1Iө6)Ql1؄}mX6b b!P_aW9I{^X9kύtAP9s$xr6'tکB-GIWTةq~G2B(6AN)dxkU z['g>^Ã?ՊTvc6hJ0Q^kQ`=MVe/C'fW_n船 '@z|^?pĆ`V\L_rtPMN0Ɠl2cn^)׍z[6~܃1&R+kFhcF;KWݛZ\Q&/WO<3i; )g`c,G 9K~ϗc(r2oH+V |Ӊ~'_p<&eh?8{|ZiZ>z)fbTV-KP0mGNe.B ɋih,P@Rj˷K*$/]FD%z s+|~hO/RWi[H_}p6Cczt VjfiEHaB !m:+bHcTG-?̵Ix|]ro6 a?tY.vɶAk*޾"%]!nCZbttKKIJw4H:)#Cj(5`3~go\ֽsfY_Ž<?ַaѹrG{9GRZnuGZc;=lbJ~u:lN..cF"8,(0jMvLVSEn=ˢG.v{,8Xy@$n:dʞ|zȴ!࡚!嗁C8UG;W~ǰ! 8`Vav?D3,p#|/~pz^+73XTՄOLE%ACfa[HS>LzmW;pӏ fo8oC]&_.-P~}كYa篗r]'wJ/ ,-ǫ*ܲ24d>$VRû&羥{BNEf*~+]S9dX/hsh5/w#c`ÒʱaM*wU笳qY~ZS\j6qp8Z!k%^y&SΌADJ"ǥ rhS^3URdhCO=.X}uk35Ƙuz4KIc$W g>T:@ED? ӿ9Hn׎2pDC?,6d g~iumM@kӐO<.27G0o\8뫫`}`k1Zw{dxIcfgVi⎲S㸘/c$%Mq-}8SXoK>FR/5ëZ$Z?L:|eS g;yGNZ%32ky=xĜ&ceift֯/;t9: jcC.wdž(dU$|`ec)gL 8!NEEzuL"Ut+ ' Pwu Yӏ[ٓ9ھ@|uEt S2Y_l.1XCV-3)p "}xK8{N̾I:y644D+].Ͳ6kU Ȕ[PܺpajZJ5UqHH}^,Sg جi9DyLbҸ@B^A5]`?<e]HZ|/ G׸)!p)(j$߿rURz=Tp>{Hf';m!mُƔw4eS, Wzi#)3CX@8 >1|s"\BWx>Jt皖'+2ۜQcFHۍ:krדwݵPsRcZF3Z.kC<[&?*og+ZeOBIc0G522բ0|n>W@v(#|Y/'] SH"ƸK|,^ʬd-*ao`ɣ) y,ʗ@#W_ n_jg^%3tKZY[hu>]cO}r9}؃@YCiԈk&RyiI{D݇+D ׌&&*"\,X7$C::f PŠ=Ub6O R+{X }I/<zӬ {߹ko6qahEl{A>_i2[zѨκEaKImU(Uo@A2Ve֢*-zE2?pvP-K!E2ʥ8;>?Y '7*5B(g$sE#pA"se@x9E1wS?w:R 칀5OD 4|Ls.@ض/w]tm[n:t>ׯ[$*|].< B k1-m.?EOT< 9@[_=-@]gIwޖςp 'klygKFsw*pzzk"sn0 9(k ( IznG!VP@k F?ąm+drp+.dDu7򻄐|Nz/l*`Y mgǶ'W?Z{-DUntIWŏ,ؿoBp Va,ovCF\ 6CDfkJں~[J& HiSd )p*"a`qOYϊ3e \nf9I7g [¼^`rFHАm鎯x_llJ6md5d([h,(< şTk6& t)5@E:ɀ]_;䡃M:San^{Iln#!Aߢ2FǸ^u76bޕ[(腲Q ƘȫӚ~U\SSPQ-e{{ y>KADBמJ琈˰WSZ^6O94#5b5iuDLet 3wK/iU=~)e'ψɹLѸbV TĚ!^_ISX)Hz,xf[ ܥ-JɦW;? =#C0裩N7\ͯfmBBCgnimUr^8 hs}i M*/GGKD-XNYwOvJ>|tuۖ @o|%Pjѭ2R3 {A`Uu}3aҢ? GV";BH#%Z!(Ix64(<YpO'|"~֍|/Tdx~̝鰚䫢"-\[7_^~8t}; 565 BKb82,~*m8h@;”RZ* ]ppU%Y 06;\&IxƜdi4O&sT}XLE7SH73&2E_!=,8)!y*e⬨,oAS6/~Q| i\ީX= D_>|][ߧ_IvWH.[W L. Ԥe]1[Zqrs]58oռq,GN!ED5iuU- Mv%aϑtuQfo褨:l\QPr5֖GC~zϗnްcn 0 S^DJ̳_W\ [vpstz[Z}Ax:6>T˽(K\?Iy__ ԧv L3(z50xA=]D>s ~ | V:U#ŨGrhU/c܁7\u>:f+Q V P}J5OďHو(Lqh;9J\.77L]8u_pw6[gLm:V=wfJ{ޮb՟K4 rRC=0o`nVO\$:3_* meK l:2kT17-`:}QOqrM<&:ox|dg+ {g}b8TFtV&zgiBN6gxuK3Iklw- ^azAFfd.!`_`-K}})^"N,g3օHJ2-aÐAzH>kȟ7+&ҝ率jF =>xi K0@4 Bpn:3ׄts|.F<'l<ѫW[,Hbz?/Yv˄H9Q\ĜbzY /P(/T~ %=_&?ͯt~pVPuMϲJ$n/,ӽ@Yz< n z5(8F7v:zDftK9>:x1ǾbM;ə\pR} 3 a7d܈X_[|Qv%0'D[w3<q6YwzN2nY]1K4<2~/06-i똝dASէCIĽ|.Vʟmc^X)n2t~P.33@l9 8Y}f"V,$u/aOL|`^qcPoi[ꇠ^ ~)g?\֓y 󼂪b ,9*hݮ0ԂmT -rYC&սP$o@-[Dnb2tFP$.Ć9(9ϾUQh@lpH8O)K TbZڋnYNc/Ucrqak ID]Ȑ, a\׶v!оߏ Z`ssJG=2ʫ=ͮЬldU{4|eޗIh7ضT's4jA7Ոn D$^4}KKq&| #)|)70{i{He$% BH]3@}R\<M&h| &^xD mNeQVOz ([*_Cn|3X(X:^xC&h0peTOG2pq*|J%rh,FR SreryZ}ʉI`$}! vj\Z ʠR+>Q9m͸uX JDqߐljEEdy1{K}蛽GnB)^>bqyY% bPcZ}n?@X(ι(ы˨fDZ;~+Y;[˕8,P/\e4M`5oUzoWQŁ8OAwyyFtP=- Z#v \#RyD@YVVE´5@%ڱp[ 4Kf:p>sfwu7:+楠Y?H˪ݘǏ` {ڷ AṋI D3T~*P@OA ڮu6;DxOnkyYzff>뺞)E?c炋7+DP$c?I dxO.ȯfWU%n4$)|Y|!SVnS9?z1ʈl[*vJ̳?vMyozK T$Lxrq/*5ypℐ48S,2W$8 #4lkٞA2|T^]ҳ|2"SdTVT,Q屉y_0BY3>uoNekI^1hnLR_bN~3Pl4w}ȃd񾇅y虘 j)XZenbovToN8wV],%|D$@];xoۜRLug/ T 4یo{${"+pl SSC):+WuF븷#<-X?V|yMaFD :6DVYW tY뇇APߐ]lX(ݻ*g}72_FhqRSmV?PK+PKAF-Pictures/100002010000010000000100976EC3FE.pngS5;[pY\-n@.%8Wo=ᩫfj>\ӧ骎VUAG!Fr  c1tcA0W+HAvsPq7`9yMD9%)eD "-$)] gp?P$4}VO|V/kQ<]8w=t˩4Z[*45{ns%j\-'4Wv .']9hyejк߾o '-M {;%箻7ӚNa%uu/:GٖQ~N8>#)Νլw@Sk_SMg;䬊 6X5^(H8ꍙq ޜ$_1e&Mxsq{`вivPS5䧿⟩~S]Gou€叀bMCݍӟKZ6,Ϊ[td|Ǿ9J6:Vt+-J80\+;R IIa(ХGC Dی3w0J4eAOMK4- צȹuf[4M۲۲`drh}׎ctyG[[yuKO1rw$Bi-)"X㢌 דJAL &^FQ'QmC+ÿ2!лjdu>u70v}X `3SZ<>YdX`4/ 9XqJmY(iiz=iؔ B3'8ZZD6:LchtH `qfLsz0jpmTQHįS—D._MFlMS#[;$),' F8X/U/,$#"[!̳i$DPv&loMDEenv{0E/1%ҋ0.g`I. BY& THHXfFtNREhpIq&#_FqN#wi2\7141A:u f͹a* B`節< [9;}˶]կD{Z>1aԽH_ÏnSlIlӖie%GHBK@(<uƅEŹg|"ءu^ OH1Fmo~a.(o6F pa2\.c'aIS4PYXɿh11+Kk s $++BW$uƿf?AqtPXkb5H2&fS$G2Y2ݷ8.$AXYCmxbN9P%ҿ&7n lώ_E"@:>Q DwGQ<7P k5AA7@dH,\U p~|x])!wɒdb2O|&'5a $ξ2,ר[YSg\='6Sq޺[]կ,קDB[r7vMP3Yt8+w<G C A,cNyDܖ2c* ; Ag?W!NR M`eQU/KNɉƎAtk. ?V,%N}Q=;}IQE65_/ʁVnX9H_Ts3&m'A`K G3ɏ5_k0o8eۍ\qh$Xy/؂{@]S= hăx[ׯ]e)ݺ ۻ"t]W=a|t|LvNhW&@i)t. j(Lq h5bL=7% ۾ \k#w;lqH!@;jI4,58E:HBgH6V-"Ͻ],|}D$>Gd5Dw9TbT!Ad'3":B˿4ƣVnK?Q3 {0ʕbCֲb8b hEv@q' Vݚ*G#ZHᅟeoqjC8מ~ĭ"gFA-փWv@cuOM<%P<<.7F;`;<= A'Zm ;#8wE]aX]PH%5T恒af Eb&b29ى_yeW!x|ܐU,\ Px$裡$^ERUeO*ןCJcyЋSgluT/VbEjMaUA&ˠŸ\ -med&`8H=" {I} h&8csâwM}\n^i1}:",GDJvFQ܂bT(MRz^1u-3Luh[w;Iތ;9e6 !'3L1Ԧ,S%3setY $$d*%9(3]hw%^Mlyq٘K)inn%'Z.!&i>|1 Vt$T-ͅpp EbK&bYHM,b4JkH~h3s{ LWV:Hը[:opÿ9'} ^ wpQZ}(}1'/)-P-G9`iٞMb(ƭRMֈ1/C?XR/8Hs Kt״C# 0C Qc|h3xp؞ ɻQv U!cG8lnw-l+H; k~޸O=r9yБ!!C:ph 6}̖=JNtLƳn% -0s.YP%mHmFrHnV9:G-à~wA"&"؊}eL itw})-C7ܟzrjQ]#)9aՈjʿ띳.8cxcÒ񕓟$ˆbX˥y oDcB/J}B5LE%݁V#MC*cgM U Ie5!|/h}o9~?=zׯJtx&em]8 -ӝT5|Ś+ Iv& ުn ѠC%݌T=Kk#$U+95C;IkvZv/='G+3=N!ql]JnWXEk:c_&%[Qjf7M&SԺSnG蛎eUky(YFe+ +g`J7I")炉fd$@{D_LFHdr~TABe~ gnlµP$bv*+pH@v+;8WB`΋ԘɽU]#E,~W܄`yjq)` ՚mTg^y9Un+DSdwйÅt+G} JA|a.86MniܮtU6(an7^㈏!VcpF0au2b\JU@DH@bE^;LCR!693KĞZi }O=o]^z}9"\p@&X;رt?\P{\[B- %̬7ϗr?:}lvGX_pE#fU.Q(=">'rީk> WhqpNёv?=|_7=#EMzۺ֖O,XovR>luieyqn?lrO&R[-nJF b<}% ,bI+fe5Nƀ֕OB`=+oaîUy,+/Ea FVWb>F$D)dVj/\;~IG k=XF^#ygCo:^" e2V[Y9[C:Ol>BhNǬi9[bO:#2jX qy~2SX|{֒WP`B @`?YD^ J̥}z"Y_gQQ+R` uv3w3{E,7Asb"Yq/VtJD’ B7w*+Lc#C)3OG$F+\[;MttYmyBaػՖ}-itIs:mPWX nD;X2I#}Vcůw@<˧ǥ5_nDgj"ã޻M<4ZD24L.7 !dʹ2ٱ\ C䏹c[x0$IVr%俑ݠ,aFe^w 7 V uMD/"M(vU IPw+2@ĝfL 6 J=:LWr~.$x0(BKlSBߚQG(W+gݰB.a!ym΅KVM? &s مMׄ7b7# 4CMb]4D3Ae!9Ku -kreMM%vշ_z!-% 01%jh%0q5w֎XQ?nrCюeG=vPU2÷7V I9HpW2IL&Ƴ)GRE2 gҁ$bXQ1;Śgc+XnW ql hc5\ʡAUh 666$*? njqw!ټ@*í.o!Dv5d; {pbŲ/ҡDjy"4Zi} vjцzL=*&.Q >Ͷ)f;,"ó~OH쿌c"V[F ykX;K&WT}~7!b$S\Y tܚz妣fcJ8z&AU'R/tqjhoVHZ;CY;}25K0BE?82ږײхϵ'ꓰz!͝EyNƆUBc yA<1'6!'g%Ѹ9te~V3V[ 'koڸ^6N[Z_2~Dym)?!f& ҡuK=Fá*}IN[2($`eaMsCSt]93kJ?4y^]f <tV-"e"֥jNڏ^"h9B9bLUMxׁEIb#wMf;sO>/~٨52HG9@ .wwفz>û2!߀IUF''*oSc)*P kX^!`h+a"n rOaCRqԴ<Ͽ/g!yKfmk/QK/PХG7M@j,-:Q23;fR!T]YtRyTF0HXOR4WLBŒ'tDU I o 5͖$uXwšs]ͰІ1^)Dg$,4.B|#ब7FΚ$(`,tՎ[@=Ķ^Ū]*F/*{ڄ%εRY]nZaF^ӀkLEs6wA-{: i\ґzFYnjniO]u' 4 qP>>!+,VjF=[&hd~gSeg(bsKW:Y Ll^6KL_SPgd@?g$"\,IM@6;6mAv9kI` eJtE!P!brںs)(k'% >ŵ-___uHjm' {zmN ^ |o?l'k\N6hxa0<ӤgQ}:f[BUWЉuSl4v(%Ю-YoG'X.{k "]zIp |e([͊ ] ,P'; O#A͊SaGF"U99}i2A((m m8w7:'jg'Hd>a9%/˔šo3}]}_#K=A7g="?L>!IcfP@JhzQۆ'39]JkP^CTeTƤjF`}{i!׼;֗k qږЦۏ"Hnٜ:q갷P,Ěn}ו?`T{v 47C#7K]0E a T~ǫ _-;>nV4UBfMq&w #X wo5mOϕwW שX@IzbnySj<R%O+6W$\}\?kh H)2DXheVIpF1'%?itS~Μ\ )LfU{:g W-OӘXDތޥLID ݱ ՗t=xDʽ&a^Ҍb&kJ[ygtXZ+PDh=![ވ,5x>8 Fjl$IW}{#@6B3+ˈt ~TJǽ6%W/AѳFTCcDnnyVGh*32'? ?hv>qdJN'nmX^)XM452O# 7v 8PPk(ⲱ;O0<<>뉅˾KXB@?%|9usE~}#3K̚ɲ1ӘU߂PDџ ]7gu9RO [RfV䥊or9^]q5 N(D9JҴ: Uʄ0vMʾ7w:8a':r$M䟉wII\#o刁 Y̟ާ-JK_ԣgyGbUfu$#?A*|UK T떌te=Z4j$g073 ާ5.%"=e!˟V{nJ${]{-ͺb1mtb;/,--~O?p[lU @.|}v0]m!UFgKv BoH\KIǀdhfDU?HDΊtruP=i4㙗}:.vcώJq$@VH<݃{*QI=?ȺTZ/?nf{Θ6tƩ^UB@((kǵA|zB (xRO(S^^E5 J6LNdak! P} B,4~9"ՐT rtA&"($B6'mQEKT ! h^kγ1b``x,'}J?FYFLWOs}u)>,%@uy_!R_ssR+~q`YD׆hxjr,퍑 )%^U'~3e")! EvT/)U>d7wF j'A$̘NV!noM_3AP~嫼[u'Nvz1=M١K(Oh:FGCnJ ZGS}qmʃR\FxJUPZZdX<C+^JΗ c&L^G --8 nb憮׋1.s`;SקIjO v=^dMxp[M5]Dw4*RW}C .l>Bm9|~,KUM a2ev) 2h]cմ:)S3tz?<-DT ߺ6Qs*gg>PfkjZ=Í]E+]]29Bt$E SS6;VHY ߐe E$8G# gl=m)-@E&"!Lu jyhF("ȗ='̵&j0+W!]vkzogՕ[7YYdhi;^ïrxuġKw{$ *Q^z .k1>!K*h1 PBY2PY_| y&9;."r$!AYp<_g]MRPTVpr; Rg677'|Mv~yw FqLǃ;9樨$ð40 Კ68d/X$˸WAj9.]|x|aLε\,u5&uTkn1/yN=|~djEN1(bs02{] v9QKѷh7u\`@`@Y{瘟c뛜G9les=a/%PQQX_T– G O<2 h~I$',OC?qVڅ.T|W}Yg '2f>kxM3` N4D R>A T@4.P?/q^$ iKmo~R ݪnA͑ K2z1 6m-D*q7 gS._!$|(]Bx@h{OCV:_3dݧ>'CpLa__,`\;M 8BBqBgAy\ Z5f:gZ3I촘? []UcmN T bCnϞ u9Nyh.m'9 oO8*QR em=NV4X~"V >H:qVc$ՎuGD7~?'%a߃[n{-u{Q$z+Ȼ+TzCwFXpӬXxukutY?ʥl;b%\`Xb1 O[X$}.}jI5zDJ݄|\`;é7Mo^<<$sْoGqI؆0Pmܔ D zEf@scFOϚ*bDe Fcx^~6p<ٻS^rF=L*:!wYT['"ƓY.xB>9z1&a]3C<@'8XNW-3 V#HNH֎IƓ00&M0g' aD@X*۟ˡ,L- jD0 uGH~-HQ{Ѳvcs)\p6bNqB1W[G  t7v5 Zy.5-Is{k^BV) 3^yn e|\5=ûbuYG|~@}nŴɉ>- } z>@ D:_r՝+Pa@lRt+x6ql$+|>|FplGH0`;K(̽ؼC:AzAxr»q뙥HGٜ'ԥl4{Ĥ)"9}vyYw!ǹ%լMr7awEØ^sX_i6Wdg|^@Cllmuu6Ze%e! !pg4w`֠=`xlO`%оh M.ŎŮXke)Ϛ5ޱ u!@,wd0KG|jM{mdt7uAX䭪M!xaMto̤;!W-e<;&vEy_}h}>ۂ9U,q@C0h$>/ Z*!Skq`~p-ש)p%HA0fbv{'AO~g ?#feLۀ6RcIl eEA{Y~bHˇ+> 5A_Z8E {NSgl@ H\~˪|ÛX'UN;ucHGp}PxiTᜮ; ^=i!zDa^& #APGRD̶N?Tճ_"ה_ubH'KiUa ^3A8\uʘQwDzyTti<~OR̍g4L"a,KE_&b];eYUV zhesQZV+9IjX\x- ) P,kXǎ03aKzzRD%Gw]_r/%EJKe,0܃nMlG,Y3(4pKLnaiVCh8o9=ζ(By@($5,Qy:9)\+}u=㡏(ͼ -?^0+n+=-rj!<AdN}żeF\d^dHIpDqЎ?K3t6Nn༊y])e0y2HH(XgG]Az?}+0='w 6㵞,2U6}ٝUϕzwz< i'zjd|q7O2/SK3 Omff?owvc?YN olŲamFO r-2 *?r*E ˜/ -O rZ=~q'{1i0M}trw b9!;}j @t?_1B׎4_+aGZ?@jXtmMˈ!/ isy,a:bj]i[L&cE @+)pAox{-[叶mw8s UTck!Rv9(CeMY!Ӻ1]t:ƣ-hd_G'gJQ` 8Q <%$4cڌ!iQ "uf#R$]E>_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>[[-g5,5ռd3kx̙ճl3Rr>4L*uA$U¼" xϧ|;[ÜWsxߙ e9"{YSbڈe׈F`s@DV06hխb+ewAgo([h}x0uݱwOE`EN}zo }epڱy%mKC(fQkȮhʚcj~mopA^~>>C)d:Uܦ{ H3&.YzsBd):4(NJICaWpY =T?tL3"^\ 叽osҦRUE=q'B=t#y~FE޾WVONXz_5 ONpOX]"9\Űj_iZv] &~(d7Կ櫠5"M16RzLx#HYWԾ47]frk&>Ҏcg"d־﬽l$XJ牥M&xӁھy]NW3 )2!Ns9VU_и2R*3A{* At݈Rm.cc6- |V_h],H?x1 `gF ͻUTy-Jun0K`X; Î6=O/\^sygO0~fe*@o7Ii^_U >\3d HSL 0E_vYWF̱O/~(cP"[W,)_GL^=7'5 NU ^aO ^߭,*%rw y{7k"'*HnO(+}.\>('e"5>贶lC5O-Y]IUpˬ>*U*@cxyk^n k:yrl$zhsp (;Y> acE=b-N9kҧƠ#1/:`.v$PK҇PKAF-Pictures/10000000000000200000002000309F1C.pngRJ^Q`#R>RR&M3`D t/2uj˯V>7l^!r{of]{wG'`_N,n@Aw_(&DE@*D$2Qd*b#(riR+;id=eG0!w$3YXb؃Rf5{@ӐQªTŚ2"z̨!wVTERtvTG6CE Yb}TXjh˫2{C5]=ʊp]=BCO2KWNK2{&Ze ֥˕<$NZ=3bƲ{FHO[]e#23ʲ7Ϡː=~9 6бX_Wnn|{yէwW^q|_PKϣ[PKAF-Pictures/100000000000010000000060D74A0B29.png^=‰PNG  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" }VF0) myG'P03Ibc:4naHH;5|-"[P$_qg*(H9'$ÁFcᨾw>  LT| "| U>gSᙞe[մЌkKyBl\ J4䢑l½m1x<%m a@C+~Cϯ$ـwc4 V˦=aC SU޴^;R瓽`>q%~L>YƧS&`{%]>GG=~B5TsVJttiΌ? M.I%V,^Yhry0.jL9 I#4(bI@#G%kA*,e*;߮bH}o9xdҟÍf:r(\)bZ#`dEf=QHNCkUDÒ CAƲ1򝄞nGd2Ɂ~m2ͤe+-k/1L6zO@>YΧj88c%!dK6(L?JV}FdSEJm(ˠ@oĘ5ե*)˟`J߁zɬ Ul4N+"v2jLO9 M ^њ'Y)BUk/Uyis@1co@1IlKB !SqͮIgY* !*vϕYgN;"tv4:h DNρ\mMNEK0?(P R, i1 : Cڤ!糰g=uUDLNW1,WZ Q\wnw9K#&LHA.v6!hnh/]WF!*)c="t,{)W]p zaEp)KE$jxI y^^ E mpuW&)T3TŐ.|Kgfh+td%ʸ݂8KJV5EL7'meOM$mZI㋸6Բ=?1[9ght%[3Ӷߤ뼐.*!h73m B4*\ˇ[qeH9G9%zSu%+/)N]woIv*xj&x/WG/E qpVd"ǭ&2UʘkݑB7V|L{(kM|*oma d!F&pjI@Xm4;h˘~skfkrx2Hx&d)R\NK0<.O ṡ /5o},X>S&ˋWq|a#SPz;47u6idfwRLt'?ϤlȒGϊT &8v7~dJS\%BdgD^j2嵦1)C.JK^i*\wU]2i\04/TtJ}8}UŶJg!fBK n !+E~dKrQIo}.oRn0N|\X>9$ b>17^.7`>1ooz̛c>iys̝n07<̕y՝_qRɘtA >׾Mf&nKKK\IﻜBKMww I!_jTx/Q)xIQ>ч4FCPC}Hi!P)2$1Vч$ IKy_hH+ I1-?'b '-%sF1+e3(%w 6hC{XҜݘ~?OǶr'Q(_eO&I6s|f!v >is ifկh^n"|Yc.1Y);jxg M=G:j'uGǚ U{c{խ"eX䎏'1# LMž@nU32)7kUL\z˷^Tz^BП dȅ[=? }D׻ZUXpnbe~unsxW`[v*Xw+ӛ̈3->߃i]y)Ǘѱ3e {K'CyX~%X{%//$>ߡȨOش&L/ $$ C+Ѯ[i-RO[z`;۽;Plvlvl_6B-fWf5H0<^ʮDhg~t ARӥk#n*Y]Ci&O4t1*YH+f7t $.B I-d|Fv햫M΋rt)E鶓e=3irw7I+Br&=k0JWʎ),PPM}d=r O- YbKXְfY\3պ'<Q-?:t}Oz`g-w#WA D'5":ՍTB Cα3nx<9_3}':/ubKT>Rz1~Ys Dfy9"Dx^o< }fO[*AUzQmVW,՚ Zo}7Ͽa eP mVmvꍵ:nLMK6gdGLo3 p+, ݘ6/E+(~ Xnunf"Tôj3hgBnM͒Y:rp(Ɂ[gG餘_'buPKRPKAFConfigurations2/toolbar/PKAFConfigurations2/menubar/PKAFConfigurations2/images/Bitmaps/PKAF'Configurations2/accelerator/current.xmlPKPKAFConfigurations2/floater/PKAFConfigurations2/toolpanel/PKAFConfigurations2/progressbar/PKAFConfigurations2/popupmenu/PKAFConfigurations2/statusbar/PKAFMETA-INF/manifest.xmln0}%M!p}י lWאfT !ڪ>JO\GK\}PK7 ϖrPKAF3&//mimetypePKAF~CEUThumbnails/thumbnail.pngPKAFYB~meta.xmlPKAF@'&x@' settings.xmlPKAFQjo T#content.xmlPKAFl$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.6.1/doc/source/_static/gallery/gallery02.png0000644000234000017500000140666712555672634024456 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/default.css0000644000234000017500000001334612555672634022631 0ustar zreszelaComputing00000000000000/** * 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.6.1/doc/source/_static/drift_correction_disabled.png0000644000234000017500000027240012555672634026365 0ustar zreszelaComputing00000000000000PNG  IHDR"S_ pHYs+tIDATx٥ץҤ#et.ETDT( \ATEJAqAzUR^!o~pcf$牓9sg%) -   xC 71@@@@ >@@@@ 5B@@@    5^@    @ {@@@&@ k@@@Dp    Dx!   @@@Qs @@@ =   ^ 5j   "@@@@k"F́@@@@@   xM@ר9   @@@@ 5B@@@    5^@    @ {@@@&@ k@@@Dp    Dx!   @@@Qs @@@ =>|:eʔWwU޽{ryaÆq .xEDD,8pp(.@ GO\waBBB,< Y{P 7o>ѢEG57n%K3y=z4W۶mY~}')}J`jժڵk]BX@$0{]vxSN}ٺLQ/ڝ:u DF >_|>|8O~/\oٲlhh8eN mr"ED+whym/<ߣx. pL._tV?;~enɒ%UN/nH ”amڴUH=smYx"T.]ZG *w޼y-'N|WyyΜ9J(۟ZbEڵk?SMyݽy|@_/ gs<:VRJv̎@\?~)R2̮f]tl!+L߾1S5<-w.O ;/iҦMYh;v(ճgOcȍ7R\~=eTc:h<J4*USKau˞='OfS9ɓ'k֬ RA]s .W޽G{Şc352k֬6[m A taFTݴ-<ݼy3ȑ#Fs_|W 8(Э-[aAdoZݜ^z?+m֭eڵkommf:k ׈i^Q:5NX@cAr}i͛*`9s>h_~껦_ 5|ݺuq܏D'-r؆苞ifzڱ,+B踝 ia!\) kE?DR`ƌ47_F/^OΪ("_@H X uGG~S=szNS: ח󀀳Yti_~yj4i.\Fɒ%pg\p~s $eʔٺzz9sժUϨrm~/ [sV,~k tС5ѿ/y"s^8w\6mR_A/_nhڴ1cm={ԾylL:eYf߹D!w(`|0ڮ@ܹs[:"4аaD5Fu)D<{#|0ŋ"f͚+@ gժU[e֥G?.Gc4Y5Vj5?;5~,w.x? ,h:bĈײe˹Wh֭e;"#zq)4PXF3g>"oJA.D__ X;Fc:Qy*aP@@@S k֬GG/3u kϙ# j@@7 p$  'O6@8@|T@^ٲe$CHO?;#D:N>#q?odϞi=+@ ³   C;v|7F^J*hт/s8@@@X,-֗ѻwGA͛R×@)@@@>|h[b}=j)ѲeKCA o]y??hT@@@3A={+Wu (>o$@@@PPbڵPPJ*t=h   ~(Ě5k,֗ѣGVZ!ƍ3 .gU&.=y[n#bP@ [½[#jýHWӷ΅{˷G &I$Ƴ>khFYRN sĹʼy&7\=]Q.\;OCa[Axѽt[^poE)soy :Ӯ];?lƍ\:m؂   k#,,L {@ )@@@|SH& ]NX@@@H8-вeK@K@9    @ (P~Gc>ׄ@9"   @< L:5$Att+   A#@"/5@@@ 4"Ea9fn:ΒSD@(SL C PpE@+JA wfʟ8ڱ[fފ c[l]@ΐ!CbrA#@ "h.5'   @ k@ @@@As9Q@@@_@D_j   @K͉"   "\-rݺupiҤ|ܹLNIR <|0tʔ)|/ڵؽ{̙XÆ  2\<,8tzS2} ~G/_3XDDIJΟ?:UNr3h z@ ԃgV}i37nܸ7w>S$Oؼy-jdf/0z^oqƊYd9cD'p\m۶f6^_ sF={v]N{nSl]z83ݩS B4jh˗Ço… hm } ҂S]y=u|,"}4}vRի6kM ^#uV;v]@D,Ԕ~ԨQ׮][ŋӦMYbō={F+RM*iux;Ϛ5M֭g[O>#?L*UAigϞ츍D%_O"ō򐎀nf]tl!c+2E"Lo;~NMB ~D?}NRS]B_رcX@fD%`~*<#(Ai|F[jcUZucV\yҷmVv҂W]{=q|*e"?"\p?x`>VVfܹٳg?AԒCVjnfʧZ-!TZgӦM{IgAl9Cȝ;g7oCJ׿ζxZW|+@ O5sNM3wɓ'a}4BG'Ov8 lذ'|NƌϿtg@^ZJ:Ug t5# ߯6iҤk*'O~q@O SD`|.dI+HA/|Q#C(_n_SF?P ""##f͚(]iQup0ǻr<qbsO*:I!"\F)S~ʕ0}J&ev! 63ftচWBM &P@Y-"_@T`}vnOWwͨ1"E|Ο?-[ݻwo!$T`ҥu4嫂W+WQd?f$q2el]zuuMiT\>~*Tύ|p#&E\~͂@`p:FDD,S /R{c[l9wȐ!9n .68w\6mzAA'дicƌ١4]ƌ0ԩS_f͚}gF-+wR'@ ]N7nܛ@3d|h]ruŋ.\ؤo߾#4eoP-.h޼|uȜ9YW'o |tED͚5Wvm @j֨Euѣ{} c̉'רQceŊ7F_[@ *v쉀 pΝyo帛Ʀ5DWSֶm~cJs43/kWBBg5^bEM}yw41#jwӧwR@bɒ%+Vl}᧦M}(S1] ~/.^/u(Znu3g$J^…jݺ7|s9+EN8fRPuP9GsN)D\пS۶m+=hР43fɒL ~8p`ZH.߯nǞ'W$|w!'DUYBAܑ ~-u듢*=g~bʔ)rU|p?DC@\'j   @@I    ":QK@@@B@D@\FNWӲZҦM^+`RlY-8t%o޼ +Ds-@ ݢ@t Jv)E=ʕr% -/Ya71خ8ApႱ`f͚Fr   @P"üy+VX߿oY&@ާT @@@ @&, א@@@@o:AoC*   $ $w.    F@@BD\vi襁'TV9>1 poŨDpoE}\rE"   DxΖ@@@@A@@@@@s"4ҧOo˗jK@]@D? ƍӦM#[Dc 4@ ᓗJ!-Ю]X+ glb|t,3#I@ )@2d0ra8qș36.i;=j0@i)@C"<K @ 0nJ "oϟ7ԩc(  ?D@?P9sX"""Tؽ{Ѷm[05EzA xF駟6ݻg\r A( ,57n4fΜA~/p ? E]@?Vo>t~Vu_ܾ}(R)S&/D@@"@<&ТE[ʗ/cPpp |4h[N幥R(L /"߸Hf͚]tuǁ;wnct =rȀpRvT^=]6l0zM" @v@dɌbŊն`qN244x)Rض&OQ._y}T!  %Ww1J. *@ U)!I~Ə?ԁԩS? BL>8y#K_y}T!(5kx#ӧ{P@I@?]-@Cƌcê ۣG\_y[CҤI}ϟ7&Nh<쳶V5'6 fD]FDҧOoܿ8v옱b ٳF^TRl.Ζ9s5k4tM… -{ժUڵk?լ;w>J֛;vo6Qos@ ۊ @'7o^3g ~.{FJ =ŭ['NئQN$@DDDOԇJ  "/ @+"SO5[sx^~g~;Çm ŋ H] BX,[ m۶قCYd=7l0KUE~k֬1_nkU9r*T"֮]kes+W5)St<># "|QA@Znb=âMhР@׫Wz,QQF [W/^:umWj}隘4Q@g֭1Vdɒ<ʯ@h,PujQcݶL<tRsζ+{2m\  k&c@ xddWjͤᯋ {egj1ʖ-k?zc3T!XVvPpEmOشiGsl'e֭݃O׀"<'co@इZOfxZ7٢a"rl3i0[Ĵf%Ѣ%-:l_M%n!tKȗ/E xD@GX)@QiӦ!&M .iҤUgϞўp<۷]*q' &l˘Ǐ[F|s\@p # $`'6-~͍~Lvs慘 X\/"BS,)AiߍO?ntQ9@ Dt@H>mKMsi/q{ È# W:k VQKs\sȕ+G~O]M}WT@D<1! *Pn]Ck ҥKF֬Ym(hF8s-QXZjZӍzN luy4,$! "|QA@ pڵk7X4?."*Wl̛7Sȟ?Q^=c׮]5MB|uꔡc5o΃ zSoذa1c Ƈ2"xE@W9 )33ʗ/o&o Bhg3>}:V!o]1Wnkغe+^ 0* "|V<$t!5JhlKr;y;9|M}˖"e5xlj?z^߮]ZDީ!'y'e3 dѢEwmF?ѱcG#GFs B{P@]@ W:U }4i*UR<8|!d b~FɓTj?bę?t幣GR,Yy晔qѢIw;¶_ Otɒٖ-1dșvYK>!=2I(:F.&A+sb_n@y>u޹Vq_T8%>;֦M7*\ MXX+e&ҵkƉMyԮbſ6*y>!![,znmS nT3lϞ9Y[9s&>ִioW>e5ڵ׫^x?}ڴ "+VLgL֨j}fYYi:l3kOި?^x5jTŋɓ'Z>(PH6P5&UBwkھ}oǡ9& n iG꫋ͬ7nx BYFb/sJ|T?|h }SM|4e:x i6{FժUd8<(o>^z<E# ]1xXYڷO?1Eco[`-KK>ZB8s˖i*uE,' Rx$IB(-K2mQ}֘;S }H{ la}4hçUyf^{"4uf* }@*1hS-"2ttg՝GqѬ! Dk6_{΋:ď@5Hߌ[f`A4ڵk tx@? Å;qnve)T(cSvLgE_jm ұ}Sɷ;ۖ#GJ?u^LS _qXC9`vjQ޵.=H‹ٵG>E:Õ V8qv=Gͭm j8cT9vnNg]M/FD[6gNdy"[;ԮWͼ1.2#ǟh}\m>kMk Is+d&6oYY߭YSZHhro[7/f 4h<ṈuO{4^)dɕgЀrtƄxUwʃȧu Wp\-[4c<<_~}uI<Ѻuk޽{ٳ7:vh$NQSLi,Yښ-hAо_ţxk`.5HhX (@ "Lpŋ']i˗__~)P`, ֻw.1] rHm~Y|r6Um(`̠}7N2kV6e٪`5 8'Jʓ;w#a׮*UJq?=g=(i7Հztҧi"Or@A{orv}71|[ ]tFΜ9'N־Zۆ f,7ou@ňCX0!k,[6E4i4բ9O<ٰX,}'y_UK(*yƇmž >(@ "Sɶ+1wndK@f6Eܹ0ҲeKXANa~ j%ḿ>!ك9Zi{)~:%l[ӦisS`Sdf~gGLXrC@>qbή__zAehҥoYdGssN駟6-jʕ8zkp]Ο?oԪUH5r! "bH? .71L_uGЬjY+=9kBvs95EhhCM! G6C{$!&2yٲ{1I|Xc̜y"P^H[jRM7*4mzpfP@3_q|Q#JWԹ}o\ ͈9s NԭA ~|T ^_{-&N",JP^t?~֯E>""ղAm+=yxΜi>5J?)=@o|fPΝ3|ѽ{汼֘۶)=h~J=zSkb }XX+`ZhzNaBaðŽ{g۴I7K]"B:ԝF,'+\߳gO5)m[cǞ@ZBkZ'H`Z(PsR3geI(lzL[ɨҥڡ<鹸;WIQF/|>u攉Ac<8.z U !22Ҷ]ca/*Ke|ժ~3cr][J  h"\jj?|x~z9fנJK&~ä^)l}Z͚Ve |2%+l+}6]zZ]mѵ0jZDuؗm^.OWzlpԘvwe@V}Qx0[9۷m3jU9r a_l ~'@ "K_zA|k@i%K&q@\WNlc&Jȵlp9GkK7td;;' DE]N Яݰaѵk@? Å0PAXl-j6<3f\0j*c_P@H,u`% ,E.'^Z4 $s Tܻwq11Nm$D/EC[ CD+@ODp>,[j[n*kYv'L4@uF,XKɓN@-꒡@_Xkqu,Y "o~]N>mԫW:TΛ ܼH9 xOWSK &6mҥo!m}b( k9rd49|oŋ)S*,>}z[{~]onfJ@@ • #Gf ٟ(KT">Q T7g3g߼yV'Z0~Ε+l@Kmr)l͖fˈ2@ _ k eDy@D @ ٿWnݲ" q믿+e˖ .1#E]6ʔ)cg3:,,>'ec|]ԲFc'O  @ "."@6m_|ѨZOҥKl343 ɓFlٌ֭[K,1dԭ[8rqĉǜ-Ü= $D)e޽Lg @+y  Pzuۃ~6gFRH"ڵ뱪X,c…I|nݺ-ϵk׌E-#GǏI]:k֬1>Cex/ @?Du @@ hʕ+8p<{ѯ>Qpa_~1xp\.\`L4xg 3VZeܸqq#:±ԢcN P{#v*F@Dϵ @P4o7n HF)@ '/ B@&My"U@m֫W S@xL@c$$ @V?WC=pmی^{R  ,@ —uC\ gΜ;Ϟ=kdΜ958@H* ,[F]\@ Z@ V߿B "wիWm„hC@Dr mڴ1:vhTZ J௿b΀  "\" @TRŸtq-C3i '6֬Yc|ᇁp:  +.2#x[ A3<b DXʖ-79 O@%@0$pէOyرcʗOe˖\ԩS=u.S\@ |ל3FNZjƹs;/U8$$09  (@ ":xNXRr lڴB͚5W/^|Urˤطo_>˗:| 2\9pevkJVzջv*rO?o@1@@\hҤɓ\pa ͛ժUkkRE>}:̙3/ZJڡ}%JSe%0a Dx[! . ꫓Μ9eܹ-OYLЩS B4jh˗Çoھe˖F۶m֭g@o 8C@\Pw 4EwYtiu(Ty浰NzWyΜ9aOXfڵն6mR0BZºR:   mq ^xa }5BҤIoWReBO!4Ę1czղ᭷Lc.Un.f+P1Ty=t@RPP BF:[ƍo>U A\T?~몋@o 4A@ _|7>0`P*Tشdɒg+VѾՂ=UT(\_>1mڴz7nh;޽\ronSk^zV *9{1"rBGA]A=uWv\MDif*S۰aC%2GoIs@oؾ}8 j8l85?+Vlޫl[l9W[q><6}vRLJP$IZ-4_1.v]> xK@9 xUĉu@$իW_,… b@c4hldЀ'4p-GǕ~ԩpg.^^5}^,4Z`hN3\ sN3]k6# P  us)Rpvt]rL Jq_sL% DL:ifz1ҕ.f1p, K@$)@|J@5AZ\|9c5r:356T O }?+q&8s>}:ƴpؿQ`}QeXBF:  I]F@xȒ%p8tPŋtի;cD/uTGr^Ѐێ;SifP ZH6m6/SV_/gZjQZ/fKe6# P  uՠ@ܹs[:"4Z<8VΝ;I-[ 􁦿TK@'O,1gΜV*|; D(,Ѵi^Tٳ3,C]6N>7k;3\k j 3k@<%@ S *`#F Bc&h֊}p6vuQ?f }7oC1z7g0OT-[ѻwQ/Ҵ# i|@֭[Ϟ4iҫ꾠)5̐!Å5kT+Rk5C/sS_r~+Ѷmoq7͛Wp\숈eBkVmժ|j1}N H,YYi>OM6%yݺuU\zY@os<@Z0 ޼yZ@̙ϪY]ϬPv}ҥt &9r$ƙP̯V{)s9s L2gۜiNQv_mY@O S> ^` /%3*)'^+W4; aRǰx{Q-E^hذⰰ+̮ %Kq/|~w)Q"b[O} 04@w p$  #i" ked̘hX73=Ĺ.u F[aѢEŋUc]|7輻m&x Xl-LR3i̘1èQz;v͇vKqj.J"4ēY;4.yORE@@"@`u*GeXg0((Q^=#y1u*H㧟~u: }go{gC6f@9^*vufcX k _f_" n<@|Tի7|cdɒ>Fi>uddvtR֭[G'a}85XfQSK &i=ҥKoС ~l Hr}LΩEZ04id;L 뵳]We~ɴ͛7XyW%   UD@ &LhhW.\hDݐ^l_ݍ;wX]\9ȑ#:NUPaq-O~~ [@E)@`ӦMN˵>͏mW <lуw?xlHGp]3o+WYqQ9[ׯ_wVuV !anbm!a+СCsf2:ٳg5c#Xd5h0Q39]@x #,` DX͛49WxՌ] V '=z4iR[G vCH"ʁ 36vҴ٢V 8[ԭBuq\PZ ls=aQ<'ңGC/%k׮]8}+W.?4rD@n}9{@/O J*Y3ڴicX 0 1 b}B=:-(aoO:! D@Z\X|hѢm*Ok91:Vɒ%C/cȐ!2V.gΜj@@D8aTXQƪUlqh @@ &1 @?xF P|@cpԪUK*+  M@7 "лwo %Jj3  M@7   xM@ר9   @@@@ 5B@@@    5^@    @ {@^`ʕ5u6ӤIsܹstQ ȦM*ԬYsEwZdɒ2o߾}˗/u2dl@nݺzwULO?o@OR. {jj|C*U+=nܸ7w>b:&M,L<ͅ 6Bl޼\Z_v-YӧΜ9E)hQTo\D?UQR s xB@'T)@|Fɓ _JvŷlR6.|W'9s&ܹs[2xAN:MWQF/_|>_~v744h۶7j5̲X# PL@۷o'5+nZ% ,hZZ5-Zg_ץKQWB 7o^ĉv}3gN+~ؾ}S+VYv_M6P~k*  PL@e">쳷4F˗ӄ])[얮]NT+Vܨ<琐WPx} 6T3fLϞ=YryiӦ x3fx,\oܸQz]ŋӧM6Ruٳ5jXiZ-fm֬YmZn=Lw6lػJ̧zߥKfܦϯʔ>}T 3 0t"L1   UD@ 9;.\aɒ%ꥇsA>Olϟ?ƕP7sw&?K5uԗȞ= s;SQ/^pر0u.kmnݺ8JZZm\rZo۶s2բȑ#sk@)@  رcG)z@_ʕb={v#4j Ct;B,4fXzu7|sѣGs)*OUΝ;zK->.jQN"|A<ƍokO }*7oCڮ:km.*Ke?ux뭷>3F@"ܩIY LI^U@-F׬յ@/@=C>*3uW^6l8SLիt-zxsNuk>M5^w**ᬪ۷@+;jZ…Tgaѽg.]Jg_:̰O7߷k Dh H3-׾Ŋ sN!̼I$jaEݻw5X# n<@.PE{E @(I^"ޫRD U+TҥJ^C@dy7Lffwyƙ}~Cb;眛 ,F-Zs͚5a $-?WF hʜ9 mZ/A0QOBA5CCC} RH$3}͛73xO$@$@"@!^$ <{,  5LzFu+QQXL2?Ě ҥ7ߌZe<}45CXN[G I&}͗pɀ>}2_k# ٧#HHCBDth. @ЀXh-Z.c2YC… #D  ѻw0{q ,}}}c2nLΝWH`z'  [Pې@޾5{u1c ǵ\E XA;A vӧ +Wm`i}}kﱸǁ7p{s`-!\r] Ā3@7oFBv@*UaKܹںu녅VZQx"`5!y˖-u;EGמ߼yx7\^K!bѸquSN E$M4E72R Yg    1ǶnAȑg%5ѕ+W Ϫ_3p kz9k=L]v]-(_dI tbGcpM{C֭W̘1O mC .|RPnk%e͚9_' >7dyFHĴѴiӵpH6]Y?ĉEa≒@hs<~T\?݄ w_2g, nB)y|J5cL&am[Hi;x0Lp[)<,Hg7j}6cƓ1pLXpe|3l٤Rj]" 3gp.ϿBFeѢOdCC$IoR?. _JM?@our9!׭"i;_8˗D9s&ԡCʥ~flgt?ΐC2V޺U+2ߚw!Fu1~0{TYN$@$58*T|3\u/׀pرӧOq"@pJ5A&pP uܹs'kl) w>}H(KȰ֭\vCnA'6la7l }`#Gju߿$UQF?'hРF$@$@$`o" 7<xժ_Y&;"o.Wb|ƒݜ(˰17 zyĻ>ڼޤ㏐8M7n، *Tl'ʿ ׭ jsvhEŋvx(GwMl\}?$D_<%;ʚa>kǎ۶IX2%Nzƫ{l3!]tZO DBI QKT 3e1Vj׷Zo͛lg!Bxx0X@)<|xIHH 2""Ʌ5'zNC 2.g"WGivjΞ}_;Ĝ9Jn&d,˰6,X tѤ/X=, Z6n׎ MPOpc3&p)gOtaafXk̝ۤIrKeG,(Veܵ˖7@k ,%Ku̗_ u-V񀀧ee`J̇Āi'CX st߅~O$@BvB v(VIƩӺxPg "c` R ^\ƄêUZٳVΘŶ$@$@$ QҔkV@<[82XRh!ZB6_^o B֏PN-p{FiȺ0n}}=e>%pݡR=mݻT[>t(4` FvȣCO +֒D[ޢjgѽnO$@&CKTXQB5[1:d* _~QSNa &ɱ=g@@@Y؁_aˈnлwCb֬Y=mmHHH :(DD,%2ʜ9 2W_eýQIKˁ_e=.""֭薁r̙O3'i,o|7o"C7ʕe-\X`}{H Ć5VYP(V,q}%kX['9E]X7 @lxPva0+PvV&MJ|D.>t*ۑ @t P.[TbW=#,4S9ԯbv;T` X4k^AǏߦ *uِE(K|"[?B >T"Z`Ć@Ks$H`zyQ;1&E գGgB_/V,qW bmpeX"3f YFv$A + m9jգ(=q6BHyΜ9#6ma.ӧO P#=~)bBO :SD+"y=Xkb8D7˗OEJlҌk%1@W\)VX!Ο?.|ݻw7*^^hl8/I?Ԭm+?}uᛔp<8pvv KpƄ wOuVV/KA>o^s3th8.#aㅇ) ; `ڵAM6'm 9pI`={+ilS돱Ǘp5k7m6(l.d< 8x5EC??[+BY#,Q"V,^b_v07}lQk˽6cAUhѢ}u,$ʱ|rzjqR6lckK"qIKbY ?2 DdI|B]E)0  N~ x4)~nL7P)J`L Lno-{3A[rhQ]qGmp _JHrki9W3qȾRJ`Ϟ?}Vi'c5Ǯ-?dHxm\Y.Z d E.vȮgң[kskm [Ed㱌H\͒eg֭EMF1+,@*VhR1m4}voHHHHZ" k[ *b*wMĎŋuUp?><_C_ҨLAlLp";Cx민5Ζwai=Xj| 'ѸqcjZE$i֬YbbժUfD$@$@$@Q!+ϟM31ZS"!.  #vZSʕ-btQF8LpqG >IHH qe:Q!+THoԨ _,:\y}҇&M;cwr~IH&PF+9uHHH"#@!"2:,S L_wBaAL FdG$@$@$@$@$@$%@!BK׆ K!?&Txc:\ڦra3IHHHHHH(DUҧ=qbA8jJ xlJ$@$@$@$@$@.NB NHHHHHH qmYHHHHHHH Pp @\"@!".M> 8 .8=      K(Dĥg!  PڗalN$@$@$@ @<#PNy^s<{f>. s Pp.oF$@$@$@$@$@$@x$@$@$@$@$@$@$\"˛ @&@!"^~>< @T^*ʖ-k{nTUYT"vڅ\x0`ٳ.I&]~<<7 @ IFd͚U\vM̙3ـHHL&% .ZlHH _0Hj֬i:|B}7  ׯ_[Fl$@xOHC;gXBԭ[7:XHH b̘1.83NH6 qHL\rj<RsHK૯R9r]wv`NR-XHH^(D؋$!7*T`Rx5aECl`Ҭny 1qxoJ$`;ҥKVeClEEDlHHl$@!FplF$ 4iD5J/_>B͚5>>>*$IpEFxA$N H O 6486 W"s LEgϞV6 'O.B,^X?,2'  ">}X~wݻW̙3' @|$@!">u>3 @M.]2+宍$}`;SmrEv>&D  ̞=[Ԯ]D„ رc%,lc{ŋ)S7o(sNq]1`,Y2ׯ_"͒%VXM!΁ɓ'+V5jo+vZqԩ|g\zJȑe3H\%J\HH |bӦM.>U)S&@XH@hyyW^}>Hd̘1o޼"{bҥB[v / W69{lx+\\|v‹H- IbBCbl6 |ItTX1ѠAwyfq!w~DΝ 0Ya H, B, ;ҥ5k&PG DٳG<}T@^̙E2eT!8x[*`K=z$@$@N"@!I9 @"+W.F5&uIH(D80'ԩ1'B$`Q|qg͚U{/t7ɓ "ʛs vډaÆ %kGӫQ!H s*D,X0˯J*9 EF2SX!&W&  %~5./N$@H:rN;\|Y"`f͚S6uOVwֈP! g/2" H"!7'*T ?4 VZSLpTٳg\?BCC9a_pUwՆL pc"q$@A7)[יQ8|0\ &M]vǏ t|ENZdƿ΂܏S-z|gϞE޽{ˬoݺ%0VӦM9rd. +2 @4P,V% #m۶?j9`TybÆ "D…C?۷oG"yH:X|\*Jb;OX(\zUܹS=Y2QW:k֟Qrl!z!1y6e}  H ~EN*=<̰߿Fϖ-M^.TomEsc=".Tm۶Qʔ),}w%,$I ++VtHH 0HC@ f:ՅEׯ_GEF&$@eݜ;wN Nr#w{m1ڵk)fҜ( a"壑 8|+ժyr$ 95joܸb VPҳhѢ\r 'N`EΝ"sX '{ @fDnLH܅͛EǎE̙E .w";9 @Z٘I$@$|"Ϝ# AePBҥK`q H$@qÇܹsUˇܹs ???w!"X-ċWJgsŊStHHc.% hL7n4S6:6 eO>[nUX݇p;UvH$@1#@!"fؚH [Å :OOOw^1tX '@$@$(D? ^ @ȑC5i)33 .&I.\8v'IH!@!! PϫxRG& {y&2  # vɮHHUV⣏>UT!   X&pQ_pX~H(DHb@f͚"88X Ħ$@$`3N:{E7oބw2eJQre={vwv|ؽ{xQx.*V( &wYIF,^XF$IQzu{t>HHHBa+ ?rҥc&g,(,WTI-9ra\rϋy&JH`.^.jBBB `[%K۝ba0aBKuti/o߾ $x143IM` ˬׯ_+W#BdȐA .~dJ4(Rț7*Zܽ{WEz\[!sٳ:Yf  NV`학HH\z @ ШQ#Ӝ9s1"0B/ʗ/oT *"yD@_d bE mB!k֬n˖-/^ŋv^&w#P~}qa͚5ɓ'GFw*B;wNl۶M ___|sf9 )D,_\^-Փ.6mlN<)6lH Gf$@$` 6@c @6mĐ!Cԯ59kAa4uB%XB@5DڴiEz]C={;rC'?~QV-%6/F|:B?Z+KNd˖M\r坶F7 ZN:ZPAk׬mzڷoD$@$z(D;Hܜ|G6Xؒ  x=O֭[k֭[b…O>Qs-Ο?^ڵkU>fgϞU D=H\LH@Rٳ'ztU$V((F"0&q*`l aHHPpw k6:tl7"֩SG Zߢ!]+x'B"?Z!K~m}3^rz/r C]v @RH!~_M""B E XdɒpHzY3܉,(~ YE$ć&GYL#D W^9{PzNk^z1>?  vnHH@KnDm{ 9Uc7|3̱L|I.GڵK Vٸqcb.X@P,IDXX@=mrE;I@@d c:`$],;jՓyRh۶Rψ+a8v)wq9BȜ9*XD XTApL$@$@IBkΊH qƳL2zg/( ~Q%Ă@ e˖wk!_ )#he&Mi7oM6~Iu0@\' Oi^]! rwדR޽{U+e@@̊+ jժ?ӗ/_3:"ݹsG f" pM"\pV$@q@fL#F0GWp%a`t[JB Aò wH SZ+5\iõ$` \$_0J;ZP14|i ؅իWxlٲB/D<~Xm~e8,$ ;aGH5j$vAŰ2@%|ıݝ5 ǏŊ˗Wu։͛ 8b@tYm6Chh9w>O$@$`"ϔ= JB…կ25h5b9eK9oܸQ5F< XB`qq5ȠMpbm;^u[AXKhB&G.^"rI4HHF1_l!p|0.\HHu PpwÙ q 6#DD^PTPAM6ꫯԲUV XC .8TRjilgꛨ҄;C $0&Xښr5 h|$&!JdDDklHR8KqBڲ^cGލi?lO$@$X"˗ s۷&Mg/(ox&EeCr;5៎$*7r.2¿ܑ8&w$+"p Lx VJ%JPےHgҳgOj¨Mʕ&'i`)qYۄHHbXaIٳn>}z #GZׁq-v7ni@ [}er[̙.؎HHI(D8 4!ϛ"}촑*U*o|,TU%_ºC)}n|E Ӏ|'Nh׎ZD$ 4ϟ_`_Q`jX,{NX v V9rPEG4x7o6t,oܸNޠ?tzh#sE{%]HH\G! ]pA]G84!uV("FyZh5 ;={B㖄~J*S믿:ě[o2 > 8C 8@qƦ3ga `Mr5a:Zk~\ `Q-sn:ay!0=b(npt˰'TE$@$@!p5 HR?h [[Wʺ8B;WG_;r蹳p6]dʔIԫWO x#,\!%KL v bҥv헝 8DZe$@$NL H#Q‡ۚ kn:\k\EXBtIݦsV9G য়~NL3L$@$@AB{'ΒH S) l gG/^,I 00P3ƙCF:vؘ7o^ubRx%nlK$@@BD,@$@@۶m}ڂۡ/v" eQgbÓ @tP-% (Q}G\5HHbFBb/^> ]?~\1nvNHHy(D85G" Q~}5WD„ IHHF؅Ӣz6f$@$@EBDl$@@ĉE"E˗E|%>4 ؃@PPRU&  "@!½gK$(V_~L!"L> @8wC-#&  P[ Mڵk'[ڲ b߾}'  7$@! _L$f*۷Ea8{ wxBx{{xȘ1Ȓ%;g$@$@'@!9 D$PfMqy 0ܚE 8gX$@J9ΛH źuWTiOhAb. y=f͚pe@roR\ŠvYF۵mᎁ|'N$*U޽{+*5 7zr[m˛6x.\#ҡI&(<A, @ 񜰘Pn3 @l96 @!4iR8I!–6Ϟ=K~K,yD=C@'`Iqnj3B3 @l96 @!+?<D pɒ%CAp" d|{1  &68#lvڦ*{-?\.lw* >oWm۷o"u`퀼+՗|q>vXqJl|ͨ r[ڔ(Q(\0`eX/y>yda\/^>,` rlJ-5 8@/xgHHHH\i J@·X+qÚ@~yqXP"vh:u8s_ >rNeqΑ#e$)HBE_Զ_KaÆܴu T҂ҥK9q*!0RApQo=/@fȑ_ժUk+C&M4b#3pI $x88c|;]hyM$@&@!9 ,1O>ÇS.S?6bhP{dɞ@@\ ,ZXeeի ' \reXN%^OpAЗaK@іf|mQv\o}1]v?j5Q'+՗qr"txO$l"M [Do~~Ű>$\6u}O2 K-Z(ʵy/^̅{9 /^YyH%z3,4p*BOIJngΜ)0nܸuȾliJ rp5g90'm^ @l9& @#,E?<͛73aCU\/|(;b4U X0j*w )Fg)D(;nc1 DO#\qEk _~9J0iӦm6p{?G]v] n#ݻw:uM6]Xp8KQYhHEBȲ_   pcpOkFr#"$D3pۀHۊ`Kqh.ܹs_}vzĴ0".\}4\%nC_g=WHemk׮hAۏ["(ӟrޓ 3PpeA$@$@$@nF ]tw`p :>[l Vz׮]˪otkԗ]~= 򤋁\{.X 2\m0 F-!p&1MVj>Wھ_|Ȩi-]4BZFyO$@$@!™9 jzz! bX<E.3f/ *b#!B.̱ۄo" F 7^-0V .p}}&M~m)h"nCj`ɀ1N*IኡeׁRnm'|pl3+ X K,e;y6 47ÇBX+tea߾}˺6lvX)L>dжA cǎ6o\یb;]wж_DB<`};.GwV" Q U &Ν;/ya૟ IH(D88#  Lʃt8Z :w\^k36O^CPlGYZj;q X a޼y-8u b|GvmK?epDַ ]5-5  Ac `oRN"HXÆ  !Wcc=' kP  ܻwO(;!?P(;N8p$ƢJ,y$ҥK;L4i z3r;~h%"qnxxXrf$@HB;5ΙH W(A?<1ӝ (3wQ8BٕB(dU4}V(;L\E6mZ?7 !F4\U|=g@@@=zFFaq5֭[z\@f͚3>'HPpw @!JP6Qvml'qo^&L/_V_~E([G*! ]A'E",!LR *^:,F ]ҤIsVqBW\Al"%3?{,Ν;aOa p NIHE@c uJxPE l|0F@.>(4`@'NàخY@eʔ9xLpǶ\:T9 }"; @!|5+ I1VE&Mlٲř䃸?Epzۅ"D$@$@NB!ΏHH@XXYo8pP`%d7lLp$_(_EΜ9a98rHH\x  @L ([ C1B˗τ%"]= XE@7LR| XXN[bŊfmz%IFGdz{{ %___a$|xzzɓk#a)xl$I]5CFRܗ dɒ52eϹa3IH\G! @<#!!!OK:!F _}B`mvW7oވ'Oh¯_xaqwOZ\=~X( LN<ϲܹsݻw ſ]ȑ#|eUcV" Jʔ5kV̙3M=2cG eDcß?amMXdD l%ԁI#~e +j4)((ȰڵkXj h83IH\E @\%|4- F#F|u4J|P|դ?# kҗ[q0ڋ)RD/e EP bŊVZ ]5ޒ v*pܽ{׌X+WVb~,Y(;@j>g9 q" .k$=z4BɓGnZl!4JbliӦ5Kyy͚5}HHH%PpI D@̙UD%(>D*Կʕ+fnRĉ:/N$@$@$@!™9 `ެY3B Gfl gn2d$\\a ؋{d?$@$@v';wVj֬NڋbX (W_EU$@$@$'PA$@q`sO@FĹ @ P!@6'      Y& @ P!@6'      Y& X$+W.Qzu4H$@$@$ @$@$ g>ҥK L$@$@$@9 =W8$@$@$@q$@$@$@1 k׮zy\K,`(6=x`jժ,TЩݻwWI8s9oFرSJA͚5}嗣7g[ l9jԨ/nj3f9ĕ+WkC> 8e$@$@$@.N^-[\%,1eK~3f۷tvdss4jh}$I_V8|p)%Ŏ'O$}ܾ};eoܸDEeQmϖ6ǵkײifG6/< .\$8?E Dֆe$@$@!@!99  (E,sK~#GeݻϹsNիWȐ!-,:u"D 6?~HΜ9/]r%!CC@9,mϖ6ʕz1իW ϟ['.`g sPpgB$@$@$^x-S~ym)_;lwu5TҞ͛u֭ஐ7osk֬i0aW(UZ‚vYF۵mmϖ6u+M"dxVMJm# p c͑HHHD`۶m5M1}SHdɒG5fre˖ @yo2̸.S1_qrSNw礪+@,Y7nx'|}ԩ~9 IݻÇS*;aRj]ΰT:t8'bŊ֭ZZ)cǎ|m{Y֭\)B2 4n gḴcǎK~>>>r֜ 6^z"k 8e$@$@$@N&0qAaw%իW)Q= 8p($@$@$@N pĉ`=;w^5kkĈ#FKX(`Z@kY_|1'K_UO>3PuҥK9Q}b~]tY1 Zjm!^KsCoذV[B--sq3Q%[MTׯߴ곌HH(D8/{'  CemAaDWy9st@˃ & X#^… @=_|9ڠɓn ߔ&M{u݌˗/5m"{Wpdܹ!m9۷Yx Ir9o\kXpQC[?[Ǎ=x=BDt> ؗdo$@$@$w rz+>(b/`^o~~/Dɓ'J=СRmn۶O"LQzxb.-Xi>dN}|Y7QD/q ٖli)+P;sLk Pp[L$@$@$dǐYhhȿ~zrk-ZԹf͚۰vcիW߁y#Ao}yeΜ6_m;A0qO-GPPĴ~-õ $IL_ftoK1;:y͛73E ؟3e$@$@$@DٳgI0]dg4K(q_֧LBbM@toFh2>}Ԛu/)D$MQ=d@ K>m}#ϒ놾-F?nt%kEtg}   Pk 8 ?BZ.B4&q(p\p!7v(1!zx?NEopLƍiܹs_@ X_ x'O֌eKf.$ ؗdo@X7Nj=|_dIx~}MC*UHJ;A vӧ +W~0Ҏcao"dZB rxȑΝˋkK)S>D?? }X(SQTFgKgO*:. @D""2aN#0cƽ>}ޘn6th7o 6vZ.=yk5 W6]:;r^ ؏3@7oFBvh*UQ\rΝ֭[X/,jj%r ēw} /[lӷo-ZX=z/d%Ļ'Z #ƍ:uLe(5ȶ$?GoҤ/2?-&9XSvƍ̨g)v5} }PGyVӃ"iR'gШDL/w~Zw?\*Q93K/ġc @|$гgYg`pڵhE%K:.X+=z>0{C֭W̘1O mC .|RPnk%e͚9_' >7dyFHĴѴiӵpH6]Y?ĉEa≒@hs<~T';\"ԯbSYתuaMϜ)(DH8< `9iҤ6nܸ8C`1-u#FP۷׸rJz(&N8HHv~\|yL`d { w6m,ubڵkb+Ӗ-[Җ /^ bZY@`ogޖli#n47o߾ S|ں& p> Q0 y\?݄ w_2'|N7s甋ͼy>:(G?|x1&xm[Hi;x0Lp[)<,HgK:ܽ:mƌ'߾5{9S@"<{zΘ6Wв&wӊITlҀLZ5.amB샙3by=^TtߨQ,Z4L:chhq$I<·Mj"1JM?@ouOo9;C[E2w8qYї/͉rLtCK?4T//k<~!Ce&=XuV+e5B֍. =nwI[O>3%JR?7Xxtm.\;`! ד 60`6lh騇>0#G~yO *_~,.8ڳ-F;ft!L4h`ctڲ. P)ܨyXUZoelr܋]\]Eɓ ts,â{Ĉ['xԫW2j`90~!8poM@kk:X##Gxv%UC:uA0*3ʋG?[D5y#18#F۳g~R= 8@9ù('o}Eٳh>2={^/GO?eo۸:,:eҥ;h'WzXI n")fMxW j5bD7ߠƲe}Z[lAVԓtaѣ5F.fucXo}ݿ)j%ߚ79Ca@)S&xxسCg}۵tiCSfpĪ,1 .ÆukZrlO^gvj.ȑӧaI-{ݰ!l=n<i Vw; >  Q1Di~=4[we B\*HԖ="v9sw6&L8Xa=lX ' >!I_ ?zY XY@mnz ^0fLSgϞ ֘;AI2 ˖=j2XPh2ʔ9k-ojAA$Y2'Kd/2. dZؙO|+sR|C2 bʕZE&Dv}*r~{ԩ쳴EU$@$ʮ  <eI (.Gǻ.pG@wVjgϞJ`PZH\hvVx [_!qeC=mnCտסN[Nua`6 Sݺ)6z|KCCWm{*MdCBK zA n4o~ylǎ< >X:h [3̙ސ82,@Wʆ{ȗׯʂ{$]'D#D[-3|gN(&X,h-]߼*MdQr, ,4of@J# }Ŋ%9ýd rk$ kF=X@YyI-rNK$@1!HJC)S"p*JԬYSWtUJF|W3o3+c';@4i"V~׮]U'Nɶ^ݧ㹱)N̞3% MBD4ޯv7}ʴue,Pm/:v]@Pʠ~v=(q@[O]˹x++/WxnA!F#mTnm?ھ-z3 Hmؐa: Y #@4XhsɅc: ,$QCX5,č׫⃲55)S 1ˡCTNHH"@!"*Bv.p-*+DyGQuanB{{H 4E)HQ" AtB'?荓av$og;yؙo=G^dרӤIZDr @ |iGHw(]!۳"8J mQp* ~-!9%3=>¨LPZ!h,-GG-A)`Yͯo_c HLXFd?t/ -[ N@o.]R\`ݻQJgn$@$@$@$`  Prb\_8rq# WW" yA"䲌b@|RED DpKpL>ap0 )uZ߰!x3岕}.=?9 knt.¦Bھ`b|X+< H(&,"BXe)ʕ+'8DR4dt9{]'$@$@$@nEBDNS1w7DV إtH}{ Gr8S'f~.|7l`K3۶ ^>aB%|!bz!-&M6R_ODf wu "ڀ z ˖nec$Đex :(?%E=!^@8qPփs'ڗogϞ)K٢bEFFBFҼGZ]uUK՞>}*>4\& Xp}5 K * /% 6w=… O>mqN4iPBKF% @^F!-6@Š p. y92?Sʔ/x0.&dFQIKu/7/X>$@$@$(D$m|_͞}|Ҡgtdzʳlw?VO,nvhxQo"*k#l}tK^I?{֬1믇|?vlX<-v :<|Cۇs,ׇes Q+Q+8-X0)1"#KF ⅗) E0sʈV?*|-o|ΐ!WQCo;ٍA(b4 K8kŊ6Zx? >6fq`(5klT$@'0uTÇ Rhx15,f^BMb/_>yixA5zAFjG~I@y1կ__kNuf/'G0 Q]֢o[j]O$Xbf$ĠĘ/^^H:ՄHdgu _1*+Q7o^PtCokŹ6@$(Dx}I -Z,YbNB3rʥ>T"SL$@$@$ʕ+:t\'O.v%&OeBd=p"<'Px?PDEEykxnݺWlI&7WyHH $?f%KAfY@ϛ7A.HH v"bg$r!ҧO/\"p[ԩE  $q…իȚ5kt|۲e>>!,ϖYfgY ,(r-/^, d`@^x{ׅwt6-[upk׮0H i4GMN'Preqmuݧ;HK(!6m*FnC?d$@$@$IpXvj-cʓ'*Bg, : ߙ2eR&MPFA@ԃVH˞=(_→_E b'yHb#@!"6B'!SЪU3gΨ>IuAAAq{ )-ZQjnpjyG ſi*DHݖ)RV$@$@J@mX~؍u s\.7 D$@!"kpE!駟޽]$^XVa/Z2$@$@$' ă-3gNe>M___+$yp$@ABk\@|hwl\f\G=mڴlr$@$@$`/+B D @TTT|4mK.^{b>3HH"Ų$!֭k:}9) ϟWJ*+Vt 4lP?~\R+ ge8" Hd ʕ+﫿-p4 A\-U?;sX,x3ĉ,"!f CB=X<@NhԪU+!<ֲeK}vqhsR<=>"/H)+/^d́ > 8BHڵTm7   j׮-+._.R>X!FEŊ Y1 ]A`)TȐ!C5J$(DH ! 1&[  &믿]ٳ.]'Z'd" IBX<@FL7n4Sι J <<\̙3G|ȟ?  p q9dvC8 *!P P E_Xg x:Dڴi ؊+nS|HD\@…U @|H5meĕ" FTF$MnݺL!" OHHLB:C>2ē͐ GB,xF$`@}75k4e ;H"Zj8' D&@!"o'W'P^=q]q}HHH@ ""BԨQC] @!"^ e˚Μ9c.U>$@$@$f*u&nܸ!,X ?cpXzuQZ5qȷ"mڴj;s~~~ѣGj;v۷o6HPlcRݻ 2 PYѣGE˖-,fb,H$` bYP-Zg"=˗O+WNO>|P={V޽{FUuƌc؎Qĉph.HH#*U*Ϟ=K.}I ZٳggYd]vɓ'n_4Q`AU É#ud [o+Umv{͋(IH!"J$Y:w, >B".ø<N:r1RN *p/e͑:0O$@$ D&MĀ+VK L)"7n,fѴiSm]Lh޼*B:uJl޼Y`IC4i~O^y5Μ9l6m;RGʞcIU/ӧ"O<`bk# {P˒y!!!@q`0.fFUDiӦ"7߈~[];?~qi5ߑ: [8N,[ٔIJ$@q!@!".X<믿.ϟ/$`ftGBAЯ"o[ bIJeDdddlGc4   $7|;w.FXz<`}a]|YMp!#vdXj>wܑdGՆL$ g l<Uk5ػp3LRM%}C~Qؑ:F}4,'O[&G}8  CX ;ÂNJo6K5 KHYב#8m^^^֊1HDBD2 x%I0;"Dp3XűVWT/oW^EUO%2G{uyN$@$29r ^؞IICڥѷk䡵4jΛ\ai$@N%@!©8 ?-[y/6x0[fr(]j 1P߱cG.Xwh7Gh=EP34pS  !D3J#!"mڴHP;C$(DxIX1j(U:ҎN|<$[`oeʔQbd9RG to[[$@$@'#/E:ZD$9sLa"9RGu(-!md"re4 p* NH xҤXkc{8L… c yԁ_ 8DhN[6[mieHHB"B |iD`ɆCg9RGuRجθ|2e8 H&@!nd@$P^=qa_ `Vzu07on݊q (~Б:1V./, eЖvXHH@۷o39c̘1*q +P5kVѾ}{pd4h@ݻpႺLPVtQFːoi4 p: NGI tI,YD4lp胙CD(XBsݺuC )RDԭ[Wݻ,5HYW`[e< X'8 FǏL}^tЗ5^Zt]|i7G1ZJ׏={jQX=m+V4f 8#e$`*Zwl0.fF}oٲEՀR]ty,!R9RG[l=ː CԩS~W^6lPfZ.Ι(;w8Ry` x` `ύH>H TZU iaá3̰vΜ9XF`YHTT,>]q͚C0YǖCYG  DDD`,4ףU!bߏkTtG65'@ps&S߿?vg$@LBD<f$Zn-F)Tbmy8DC>Y{(M6MT 9RG Vmy83IH^"k.UR7OP>3ܹsL!:tH7 H("4!7#вeKѳgOCMaLL=,+  [?` ZĶw2`FeF/-4*4 p6 &HC@|(YIYk.^Mly84HH!eٲe7pЈmOS/bqΝcNtA$_(DYK@I&j [ á>zH$@B"ѭ[75… B6{ʖ,Y2u>>>ᅬ!J`޽bĉd^ @x8 7ŋ/l͇C# %/]Ν+`󋎪k  '$l<֝fΜ٤4Cc8%ˑ lYf(@#pѱ" Ԯ][8qBPN"$@$@$@IYϘ1# #%p"Vr"$8v튯) 8+ 8Dl66mZӕ+W9rϮ6 _ec5 cǎ꾾^x=~'Nsi:_~޽1cư l=zlٲ]1j:Ϟ=3gΛ˖-kwر"H:=eQ%^zK<ǏVVm o߾Fr0i$@8;$LzIq$@$@$n޼ySJHqF\/B\x1gǎٳf(=_ 6l'|qs}lsjCցQ^ th۹}v0D ,iӦiҤ?7@G).][z<' q$@$@$@$@$vzO"*9j't}8L>o<Ő)S })S^W^(֯_ߨqƿ ߑ:@%Ktļp -[)k֬*T؇r y|Ŋm`1l;΍H (Dĝ![     p^_~eoӧ L2rʻSxe>444Çbҍi)Sx1bG(Kx_͛L0}X(ΣS͛b{;3百5,>vbC|{x㍹zX2`X*!G 8-҂ԩQuֽ1SNi9QJy`qݻ"=^c(D8ƍHHHHH ٹso'O/z'X/+ .|piFGXBmv9D0צ={6eڼ83g@4'NG }ⅷߑ: XA"lGXCm<90&# @P?&    \  <#ߋjժ4J|y,U%V'" VFyٳgWf1צ5"hݺuSN,솨Xxq6cp|@H8 !LeXvm,ҍ]vU< 8FBcXHHHH HJૼ"Db -bN:=y="###SjӍΥ(?>YD.A4=zx)d̘1L۷uDe޼yz9_h#{:}7[j$C(Yfs (DX\    @)y$^ehNm26 %!B zg7` x{{Ж7:Njr@¹XdIl'@!vV,I$@$@$@$@Ȕ)uX8?>O"E+ >MذaCJxbN}ykX!>ҥK9&?_A˖-k~kժ'?y$Q;ZQ4BZFyM$`? 3c     H D,_^ 1, r֬YCyX. ,%`$DsDзBĈ"N4ᷡPB'_Ò"ZlsN;v“b)lKr i8O(_I Pp˹ $8֭[jժ'O9skZ x6ld#pl#F|4Vȑ#+*O<sʕRډzu 2>r%g BY6p/_.늢E;z !unvBЦ[ :t `Jtn#u0w8|w?~!n߾ жQ-CF@9n$@q#@!"nXHHHHbh߾ү7` 6&^A𲌨eXNgϞJxѱc%ӿGEEy͚5?| L6m/hN:嵥#|S@߫knQ9)*1!rF|>uҗz+6qޠA O߽{weUTi>$@7"    C` _bE,s@ԇ5jl2 ir_{|p…\3sYV9r\a>6m~e(pѣ7 )Z;6kgJa̙₵DBmb`O.|{,];RDէÂ>"U]&pǸ 8DŋBP]V" H zI&kG=HӇԗK#GN #!"ƕ5j}w"pI+8Bs8wsX9( puJEۋ~IʕK|.1dštL4/^eԩC0Pe0| ,Iipq%0<0X$ $"]I܊Wo XD.qq\L*u?~9?z(նmj"gR;IIr8N '|( a޹|T^=2eJ?'H$@ZCGzjU|P^.=hÂ@|L''8<Җ!(eܖTQΝĹjw! @DDXhvs@@hԨJp## pKVRw%LeRpR$@$?(DWJ$@,߿/YՄ# $GΝX)Si96V" D!@!"QSpOJtj+`"*cƌj:aIKa"vK$|iҤQx ҥKr :RT oZ|-尡k! ! 8Mܱ!8\˙3g!ڷo/Ga&ooow9 @ $4d3g@PE >m_ǏDԌ| t"HH6"lR$@$R8R`HHHHHV"l%r$@$BJ./.t?8     PK x ۷۷gϞ͗&M;7n ғ Y"E۱cGu__rO.~uZ7oL.][uM~Ѣ͛ BFlٮ vի|# 6ZsE9c|=z/,*"K$P[mf͚,jAƌcl#9R8ϟaT/K0*4  yKa}Oe(O!BO$@$|"ϔ- g8xХ  v[{dok+7A"8h۷my$--/x׿gz={6.\Q}SBE$ CY;:Ҟ#uƀk%ˏ?:88Q9'p}̎4`ޏ x15kVʕ+ #Æ-Z";@l9sWn>lذصS4^-Ԗv[lqƿ"Ŕ)St,8ҩS,Y̓G,W0([X.ѱc%^ 8BYre+2m׮2m`… 6ziϑ:1bCZm *RywﮌJ*HH(D8)[$  pQXPHcΝ;ioKb h˴ ,:t̙3Y)$4|H< IrF`ڻMν߾"8U*G <լYd} 5.]2O>]`WCP%۰jddTaڵ"<<ƒ!K,_~'g.G{& &@!³G~֬ L+V0+ @A-^K6^1h?F[HH0|D :ihqĒFҭaܖD Km*&E֭_B&7  pq"bA0 R>upᄏiΝ{7G䗆 4{ ܹޘ>=ᥳWtF}n|X>d7o>O^mtӜϞ}zu#FdWSeqZ,+8MpÇĜ"oR;^di㏯1"#d2T?о}Rn˽eG4ڵg;tx! F$?)bڴiK[JmKQ.BCCΨPB`_d㭷2)rX|yҥ?>7|jDʴ8%+)CglHHXE?],]!*NE7xi>zqѡCLyx'ݷo/e:S }+hnzn{IPf6(SDK:8_*jlՊ w<v kiv&3gf>''1O7%>C[[ޫys:Gv^v×/?^{!Pz8"ʕwZQzٲ~O>׻ 6=ssc*^]GmݺuЏa/[6U|g s૲9y`+s玶|(^/ٲe6)8{P U8~Ҵo΍HH܍@ MY_fѧsB8xK_K އ(_o"*XȼŋûhÇWzXI i )rL~_җ.hK~ӦiT~"X"B9"Oq Qe>~!رWt峺uSoB4YCPEM,СG%7/y(J]L?h1}zw=>`0pX21rI6+!{7L7Iq(o {fWQ|c="kÇg;^h۶Ssr/1Wellr$@$f*p. vƜ/_>]9rD(K7? n$@$@$@CBD,ZXcD~;רe~]X0fLq;/<YH_ +,ۘ<9k )^G4 bxonѲeOx!G`eBw,Xڑ<)/&N: mܹS:*k9sn9uj!2oowF,(V߸1 ާZ@AEru}啔t,Q??W%No߾d2e|E~2gbҥ["d=KG{v,K 5KرYϟ⌥:L' ">}z,_}Pu9>bŊ e7M0A(a"H]m   !@!ŽѩSw/̃%,#D !D:wBĞ=+!~4܀eX1hPd|eGȆ MLr wXi=;Wצ[:㏇K} 7ڴ9Bukut\.RɅQ>Ҵ$2m-qFnﹽwa4"dxN$*l٢Z>(B9ECp其}  vXAh#LΞ=eỹPMpi.\9Dti\cò;1U^^ُ^זί\y y 0\QZNKu -[X3Y%ROk!FIN [F9,Jy<˖n'aլyjΝa=m,  vIm4}5kyڲҗ畂2]C]@{YhI4s9??o1{6$w*~wT0HQXHs&L|ú'y=sj4\oz_aCrɉ,Ǜ,/dcu鉥veB?`۪ϗ D}IHHHHHSPH;  "νhRժC)oPvR[u !O]"O}  pif۶'L>_] D,_V/D ŤIFɓ8fv7D$ + m>H-'n %,轐G/X.FCd_*B jKT}]^ w5{> wAϞgsʕg- :xY'lޢEUGF`B~Y7cD_!#<"@|I „=ψnj:Gn$@$@$@$@$@$(D$]BxyG]];X Lmp¾ǵ8 f2% ީSwKڭTTb :/뛽oK_bmK֮]*tL3N5LGԋ={ V>BDRf$@$@$@$@PU^=''@!ogO d~l= @yUH"E*w Q@6J$@$@$@$@8vhڴ)e‰ٞABgge)Dx_'O$@$@$@G UTjٳg' 3  .t38!4͙3L× X'eyYd^$!(Dxȍi+VL&2f(8w    D pYѸqc.H5 PpQ99sB9    %K&v!VXa sIPSmݺiȐ!*Ux2ΝHHH1c~ƍݞSec#)J,ic #'@!1gh֬ڵxL#Aqo\e?SLIj88^   @rDÆ ĐX;Pʕ+QFd (DxM)*4-ZsuSYnc-# @%/ *!/1Uֆ$(AP"II "9AVFdeU . &$HE@t T,YP`jTLwy}kxsϹNTsf9@!"e$82ƍKh!ON!ƌc6oޜr:e@@ ,8Ӳ:{+V,[̴n:{: 8L#cOzG?ndIΒlڴiuyfj@@ g *T 2رÌ9ҴiԬY(P<&ԲR-OhРkz)G~̞=(™c9`>2(UTɴhEt;w4 .4+Wt'XVRڱL<|w)ٳgiܸ)Zh4N9 3V3Cf@ O75re-Zlܸ1:#6ٛYڎ- @y U/ZN߮uTU:˜yfرB t1^~LS%Htm?Ųp1C".i2[jU\wرc*G~|YdIN#@,Ld! >HH!c*U\"99ٵВ}D)WtCF„QyYU(bŊaÆF/wKnܹsSO= Hx 'XԳgX_WdI#Jꆼo>O87oHf׮]nѣG۠w @B,2C3Juq6LoD|G4dƌkqE<(eUV#a;"ε`$Q ЬY37d޽{MţpƜ9e矧kn3}Y ^!@Cf]"bŊ4Ueg=z)f,^{o߾ڨ`i*RƆ ܐtzN Ѥ>\zFٙCp=\?-8x`v"/3 I Ds!7 s9Fqmfʖ-s]tQOXvj̙cp ^7sȌܺY| @@D;7`cСCoanֈjesu-GIϩEgsƲLqA!"..#@ڵkcRسgy]vF??ܟ8n!D @qE@N-Ǎg.bc"Kz@%fϞm7\M\ - Q-ׇy!Cd)!P"r3Y/={&93c5]رhygadA:ܔ7pF=@ BitO}4Tr fRDD@^'ׯ12ׯQj-i)ԩS35P}:S2 @1M@ J.mV^mŸ.7KKgc5ϩ<7rBDNsUW+LKOcUϋ+W-[΍L@"ǂ$?[Aa+I @9C`׮]fԨQCMɒ%BN%@Uv9̙YUK3#=֜)(W)__LJ @03fp3D팷|rBDNߘ!WLrd BD0d'^z)S֭['Τ) @@PXʕ+camD( Df~͡C޽{M3O@ x ( BÓ  DljZqL@N4ib֬Yc4h3ej @M /4N$6f7\[q{iXft-iذaF]@@ oa=jjIIInDYjGIUAӦM+êCu#ix+r)F>31Țu/0wVM8/sҥK ]z?ۇ*p ꫯ6eʔ1cƌ17oN#N:o| u _)@!УGs?ӜxYfyA*vufP ժU3^x8 ,hژ+f܅ "]uU@)-jԩc:,W8ٶm[JvdڳgO[PT)7|kFmC}7^~6Ծ/=g:C DQ FfÆ 6+u3n7*JɓSN-EO>tSW} '}U޽Qo$PzVn޾ه @ tw5OuZjۻMf:v옪<3V7nYvmXMѹsgW%̙3]%J>l|ԨQ&999O}pH!'~m;:/=]r%棏>rh+\,M˖-pQ _ڵK5kVh̃(5îbP,!$BFpB׊Ae˖u2N;4Id sN\*"D SIᦪU ğġo߾s[o/Ns%1F4hȀ@"Ca"Y/Ak e!I;>eh۶iɒ%!PM۟u@~$b覯("6s9 7o[{,w?74@@}D˴>,SeGg=vPFP%㵂yv+gJe(ʓ,RJ/ia;#D Ds!7A h"Y훹I+o=j}CozHQ ߿ٛ= Y(׿BN>9^zRJFy&$(ƍS^WJ]BIKDMvʕ+4񐕃>hLg7CD>B@$ у 2 /훹_ɒ%]R^)YHJ!o˭0 Y~J,,ɶ2s3mB BYd(ѯ_T]BAQ͞=̝;78rHJw.F"Y AI<$D'=!B .; "B$ hyÎ;\e^7̤hR/Q/u驪+!Ῑ5rf٥KTᩴC?9 Z<`8 @ X+k'B ϟZAo#:֩_~1ׯwJI{~]‚?gĉ󞧫]= *i\%9dYFz(@hPTPkh58 ʱ9sB,z'!GO"6lR携jy]d 5ZswvsH#K_ 9po6ח+8 @ GDFRo% ^+ʭ[0jS&.!B>$2@diyGEػw{9 $f9駟fYF(HC (1 t)iرə"}3*6ra],-oyl}ʔ)MohJ1m҃yf.4BD87s۟w/z A 3\SI@4 WMz&!k씭?Tpvܣz?~|KY-!ۗWNYmh* <3EӧyS-AhѾ˄QN3 AJHɣ,?d o-!!;wLվF 'ne-!'K,qIz@I1)> DO+DjfgP!GӲeKӹsgULjمu|-K 9IVZN!UYW0[K2D["ƍ]KVF͛5b\I6Zuo+s1eʔq I!"LPTK,JXE"h3OPnqꩧ>ȽikEZuj#_$gL!k5|kDذ))> D^B- PAɊ 2ㇿeѠ𡰗З!>T,7uTsWU[n%UZum }CI)j–yof: '@"2fD$ N8$'er "yXU5k93ݯ ǬQN+ҤI܇ \sM*j52zl!@.իWg996ddu[oVuq-1TK; !"׃8_y#N*Pp=- *ȏx(?i7Nq O!"|VL0ZOph#Z8j(ӨQ#2B u2] Cʑ#GadU2ŋݯ1et3 PpG Y[.ñt7J;dAdE{gYdCz}qE>T`Aןs G!"}|򺎣+6!d]ORdߜTRBw=lҥ|^x4gmpn喗!yP @ C?J&9:P?SLҬYy=zH_FKUW]EeKg|"C}H6lݶ/?~ӳ>ZFk߾*,+vܸq}5/+ҡk׮UPaE]H47IѾԽ'}| DQ! @Q˸^׬YSPB' d-Pn2y ,C :t^eY Z`“p,INv|7s֏=؃ 8rHU8`_=:ŀuN,l{e5Zm۶: ]H4h-BD$m:tWX0$K !?L7BD0r!@ (k^7% 6X G*ry }oРWr^kBǎɏ#k'\ ,h"_6?vÆ gΚ59דϳR]aBmSBe+WT Vly$m.oCVaە+W矿iۮ]B#6nx6zه%f @ -$Bȧ, $Jr)-[v 70~yWxoK$B(Bó> -|u^/yX+Ez/m*U8p[o_B, $Dȧߊ:uzߎ_'kvW!TCܹT .5jX/c`"i#p g4Uן/  ? / E}';v,mIU&+!t~oݷ94&~~"C @ p1ca/guꠖ_|ܠ|-QЗwhRY2az"d5TVbşe˖A޼]vcEڗcM*K[8p' T o Yt;v#6a&C"„:|hɌn̛7sik-cB% @:H"Nd1 'ZXԧN>}AeÇ *Y!hѢAoղN(XOrnΟ"viMC=w+”-[v]fhѣk_}ɱ7tm|Ih -ֲ"ۆ#xלC @ ЋG߆F}ɡDEPLR-в׋rJj?h,NfTN- lJHȑ#o~:uV:+k׮ٲHT^}w}WKIev9<7öcX"z3[@ '8Lr2&;H Vս{ISL2t!vگZ! z2d rlɿ9I_WXQG.wJ*sR^>:9sf@837(BCuVz~j-_+j׮_?"? uo%h߿AQ:_~8G!<Tbē{hʩSJRE59_ݻw!n;(҉ag ~~"C @ {+ܨ% jEf;eYQ3K)S/";NeǏ1b0|;m{U߭[iCmBbkT*ONٳgh޼{j+E YfMi>_ʺBK_n}9TP (q_8%aI @N@ 2THK-sPk5W=;~K_%&lܸ Ћ/+ Y hyAJ~Va>;v8>L.]Z_~d  zMo۩S.+~dm{խXAS ?e!M9"i>uM&TV"طocr>-/PsWw *G?!` DXl!l#82NH-̶> %ZVW>Kyr-Gͳҋ`iDfLvv% r )癟~iHN%m6v]~{˨[I ?ed|D(dT%מC 8k1&ʴo^ae]X9v>: @ sF9T[:tAOk]:z]"dY"ҏh<2fƙ;"r;g@Hvb~~9"D_n$PHp} 8>… M68ybzi5-(Cz3IE;vgy. 4hA^k$_4qE{ r)VL=nΗ;"r;g@B8tPsc69I t8*X0Y@@V 1ϰqƒlݺ(Dxky>hbWW@-ZtM74RN#he˖zZ/d^G!"X iSlsnK.I%A* & Bq` 8~mr;S8,Rv3ɒ%Kv/0`XE;q{_L%B]*D…։}o|x:I?3^ʼBD'@ >YSl4l%W@@x$J8\yO>x`x P-Y 6nrzX9ʹzJV˒%K.ű3#{9s G/NاGɗBy^C}p sC*JOίq%[JO=6mڔyfcB  ? G6Zr1sH>9 -"y₀cnܻw8j)TP`Yb 'wsBQ& :SGς? E:OEPyPRAִjժAMqkAIռiŊɡDRJN,eKo1 @ 8g͚)$ALu@e@Y fi x&Lڽ{w h@e#">$5g x≦}%)|Nϼ7XF$L @  (J,_޽{^%" Y!@ +/+,K- @ @9N!"s@ dE8|0)=AQ&e@*U«H-@@h޼y͘BF!"ޮ(@'גi@ @K!K}@ Isi~-nݺj%Jس}2"T~&ϵ/nآEٵj/ĉ̚5kj<[رu3z衿WVm6"iㄯꫯ^޽I't謳ZݩS |bkN_|UVu ;A@"2fD @ H?;c$BtqSO=uoժUܰaÙ{S-T˗mjI=zu! ,xDV{_Bͻv:e̙ 2tڵ51c x5^xᶾ}ŋX 9Em@ B\PȔʷF"DhŔ)S4kl^=uƌj3= (uH\%49 o9 ȸ  8%/=`سgOŋW7tHi;!=NJJJ~Æ  .lEm۶RJ*ԥK)v KaE]35_d4;N9TyvlNYO5>--Ћ% 9IV^z -P=:/T'(ǃE¶֓PP/UTYrYیR$E&h~犚?,_:_W_U~_c@6 @kwقW/S"9Um^y%Bk_^k$DDzWQ[y'Ӿ5t2el?ѹ#GO1gy?~WUƁo! E=TOK2$Do%O;_uPK7#/6XB,y䑇E>Ad!D OEG_$mdeerYTٳBNn!$"D 4ABīz}hjԬYyig"C%gϞbʔ)]B޽KؼysۥIH?v;} zgϞ{mw{QDjroABD.]<``ʒdk׮I93gNZj}w]w=lS|*/ }!@ } !p71&M, dž ]J{O&M]"T\y9L:!C?o6v+i![nlٲl+˗וw D'Nj(A@Q?f͚55<94o|? _I+ߖq}=)D+Ty۶me~DsTd;WZ2!@ "2ό !dt=睦^*nzrJ9k֬V6l8}ʉaZ "qD/ƍ뫟-[-WhРWZ.ѷoq_ J›g,XD7汅 DDΎ -q} "hFV,aaٲe?MQVrN)珲&_BBghY֭[˝x*s`Gc 70JK;daCN:w;i|zev>4~EO.߱cGiYHTy衇Ņû̶<Ǝ;@coYE["˗wlڗp#ر4mI 5YGk@@˖-?/i0~e9SOݫ_ ­zzacpTRe. xh۶ _AeAyPi :1T|pGDVf)gzC@"gEM@ '$DhiJ(!"!x&h<{م ,@Z&8 ɎD|!vΝ;2edy>΋2e+>8~ ̱c8JI ,.Y8wB_.\AЧrZtq0-@ @3@bc`>3oӴiSWҥ=7{/aي 6\=K]˒%K.̛cTbBD_Cf@U/KAOz"Q(aiӦM^1*\:BDN)@e|8= .ك ҦMӫW/t֯_?~|$ۺu%] kҝgֺ5 @ > DueV %?~ӪU+W|PZmd\$4iÓSٵkW΁!@ÝBb4kwnJ.9dZ|5qGHjѢoĈɳf2Ǐ7SN "T_C w Dk @y@ͳ>k$>TPAc6!GIm۶59>Ox2T{!@Ȼ"ad  @1F!".Å @ 2Xz @ c"b1\@ @@,@!@ @1F!".Å @ 2Xz @ c"b1\@ @@,@!@ @1F!".Å $zbr  'L ?KYC "3k@ @@@ @ "3k@ @@@ @ "3k@ @@@ @ "3k@ @@@ @ "3k@ @@@ @ "3k@ @@@ @ "3k@ @@@ @ "3k@ @@@ @  "IENDB`sardana-1.6.1/doc/source/_static/drift_correction_enabled.png0000644000234000017500000027055412555672634026220 0ustar zreszelaComputing00000000000000PNG  IHDR"S_ pHYs+qIDATx٥ץҤ#et.ETDT( \ATEJAqAzUR^!o~pcf$牓9sg%) -   xC 71@@@@ >@@@@ 5B@@@    5^@    @ {@@@&@ k@@@Dp    Dx!   @@@Qs @@@ =   ^ 5j   "@@@@k"F́@@@@@   xM@ר9   @@@@ 5B@@@    5^@    @ {@@@&@ k@@@Dp    Dx!   @@@Qs @@@ =>|:eʔWwU޽{ryaÆq .xEDD,8pp(.@ GO\waBBB,< Y{P 7o>ѢEG57n%K3y=z4W۶mY~}')}J`jժڵk]BX@$0{]vxSN}ٺLQ/ڝ:u DF >_|>|8O~/\oٲlhh8eN mr"ED+whym/<ߣx. pL._tV?;~enɒ%UN/nH ”amڴUH=smYx"T.]ZG *w޼y-'N|WyyΜ9J(۟ZbEڵk?SMyݽy|@_/ gs<:VRJv̎@\?~)R2̮f]tl!+L߾1S5<-w.O ;/iҦMYh;v(ճgOcȍ7R\~=eTc:h<J4*USKau˞='OfS9ɓ'k֬ RA]s .W޽G{Şc352k֬6[m A taFTݴ-<ݼy3ȑ#Fs_|W 8(Э-[aAdoZݜ^z?+m֭eڵkommf:k ׈i^Q:5NX@cAr}i͛*`9s>h_~껦_ 5|ݺuq܏D'-r؆苞ifzڱ,+B踝 ia!\) kE?DR`ƌ47_F/^OΪ("_@H X uGG~S=szNS: ח󀀳Yti_~yj4i.\Fɒ%pg\p~s $eʔٺzz9sժUϨrm~/ [sV,~k tС5ѿ/y"s^8w\6mR_A/_nhڴ1cm={ԾylL:eYf߹D!w(`|0ڮ@ܹs[:"4аaD5Fu)D<{#|0ŋ"f͚+@ gժU[e֥G?.Gc4Y5Vj5?;5~,w.x? ,h:bĈײe˹Wh֭e;"#zq)4PXF3g>"oJA.D__ X;Fc:Qy*aP@@@S k֬GG/3u kϙ# j@@7 p$  'O6@8@|T@^ٲe$CHO?;#D:N>#q?odϞi=+@ ³   C;v|7F^J*hт/s8@@@X,-֗ѻwGA͛R×@)@@@>|h[b}=j)ѲeKCA o]y??hT@@@3A={+Wu (>o$@@@PPbڵPPJ*t=h   ~(Ě5k,֗ѣGVZ!ƍ3 .gU&.=y[n#bP@ [½[#jýHWӷ΅{˷G &I$Ƴ>khFYRN sĹʼy&7\=]Q.\;OCa[Axѽt[^poE)soy :Ӯ];?lƍ\:m؂   k#,,L {@ )@@@|SH& ]NX@@@H8-вeK@K@9    @ (P~Gc>ׄ@9"   @< L:5$Att+   A#@"/5@@@ 4"Ea9fn:ΒSD@(SL C PpE@+JA wfʟ8ڱ[fފ c[l]@ΐ!CbrA#@ "h.5'   @ k@ @@@As9Q@@@_@D_j   @K͉"   "\-rݺupiҤ|ܹLNIR <|0tʔ)|/ڵؽ{̙XÆ  2\<,8tzS2} ~G/_3XDDIJΟ?:UNr3h z@ ԃgV}i37nܸ7w>S$Oؼy-jdf/0z^oqƊYd9cD'p\m۶f6^_ sF={v]N{nSl]z83ݩS B4jh˗Ço… hm } ҂S]y=u|,"}4}vRի6kM ^#uV;v]@D,Ԕ~ԨQ׮][ŋӦMYbō={F+RM*iux;Ϛ5M֭g[O>#?L*UAigϞ츍D%_O"ō򐎀nf]tl!c+2E"Lo;~NMB ~D?}NRS]B_رcX@fD%`~*<#(Ai|F[jcUZucV\yҷmVv҂W]{=q|*e"?"\p?x`>VVfܹٳg?AԒCVjnfʧZ-!TZgӦM{IgAl9Cȝ;g7oCJ׿ζxZW|+@ O5sNM3wɓ'a}4BG'Ov8 lذ'|NƌϿtg@^ZJ:Ug t5# ߯6iҤk*'O~q@O SD`|.dI+HA/|Q#C(_n_SF?P ""##f͚(]iQup0ǻr<qbsO*:I!"\F)S~ʕ0}J&ev! 63ftচWBM &P@Y-"_@T`}vnOWwͨ1"E|Ο?-[ݻwo!$T`ҥu4嫂W+WQd?f$q2el]zuuMiT\>~*Tύ|p#&E\~͂@`p:FDD,S /R{c[l9wȐ!9n .68w\6mzAA'дicƌ١4]ƌ0ԩS_f͚}gF-+wR'@ ]N7nܛ@3d|h]ruŋ.\ؤo߾#4eoP-.h޼|uȜ9YW'o |tED͚5Wvm @j֨Euѣ{} c̉'רQceŊ7F_[@ *v쉀 pΝyo帛Ʀ5DWSֶm~cJs43/kWBBg5^bEM}yw41#jwӧwR@bɒ%+Vl}᧦M}(S1] ~/.^/u(Znu3g$J^…jݺ7|s9+EN8fRPuP9GsN)D\пS۶m+=hР43fɒL ~8p`ZH.߯nǞ'W$|w!'DUYBAܑ ~-u듢*=g~bʔ)rU|p?DC@\'j   @@I    ":QK@@@B@D@\FNWӲZҦM^+`RlY-8t%o޼ +Ds-@ ݢ@t Jv)E=ʕr% -/Ya71خ8ApႱ`f͚Fr   @P"üy+VX߿oY&@ާT @@@ @&, א@@@@o:AoC*   $ $w.    F@@BD\vi襁'TV9>1 poŨDpoE}\rE"   DxΖ@@@@A@@@@@s"4ҧOo˗jK@]@D? ƍӦM#[Dc 4@ ᓗJ!-Ю]X+ glb|t,3#I@ )@2d0ra8qș36.i;=j0@i)@C"<K @ 0nJ "oϟ7ԩc(  ?D@?P9sX"""Tؽ{Ѷm[05EzA xF駟6ݻg\r A( ,57n4fΜA~/p ? E]@?Vo>t~Vu_ܾ}(R)S&/D@@"@<&ТE[ʗ/cPpp |4h[N幥R(L /"߸Hf͚]tuǁ;wnct =rȀpRvT^=]6l0zM" @v@dɌbŊն`qN244x)Rض&OQ._y}T!  %Ww1J. *@ U)!I~Ə?ԁԩS? BL>8y#K_y}T!(5kx#ӧ{P@I@?]-@Cƌcê ۣG\_y[CҤI}ϟ7&Nh<쳶V5'6 fD]FDҧOoܿ8v옱b ٳF^TRl.Ζ9s5k4tM… -{ժUڵk?լ;w>J֛;vo6Qos@ ۊ @'7o^3g ~.{FJ =ŭ['NئQN$@DDDOԇJ  "/ @+"SO5[sx^~g~;Çm ŋ H] BX,[ m۶قCYd=7l0KUE~k֬1_nkU9r*T"֮]kes+W5)St<># "|QA@Znb=âMhР@׫Wz,QQF [W/^:umWj}隘4Q@g֭1Vdɒ<ʯ@h,PujQcݶL<tRsζ+{2m\  k&c@ xddWjͤᯋ {egj1ʖ-k?zc3T!XVvPpEmOشiGsl'e֭݃O׀"<'co@इZOfxZ7٢a"rl3i0[Ĵf%Ѣ%-:l_M%n!tKȗ/E xD@GX)@QiӦ!&M .iҤUgϞўp<۷]*q' &l˘Ǐ[F|s\@p # $`'6-~͍~Lvs慘 X\/"BS,)AiߍO?ntQ9@ Dt@H>mKMsi/q{ È# W:k VQKs\sȕ+G~O]M}WT@D<1! *Pn]Ck ҥKF֬Ym(hF8s-QXZjZӍzN luy4,$! "|QA@ pڵk7X4?."*Wl̛7Sȟ?Q^=c׮]5MB|uꔡc5o΃ zSoذa1c Ƈ2"xE@W9 )33ʗ/o&o Bhg3>}:V!o]1Wnkغe+^ 0* "|V<$t!5JhlKr;y;9|M}˖"e5xlj?z^߮]ZDީ!'y'e3 dѢEwmF?ѱcG#GFs B{P@]@ W:U }4i*UR<8|!d b~FɓTj?bę?t幣GR,Yy晔qѢIw;¶_ Otɒٖ-1dșvYK>!=2I(:F.&A+sb_n@y>u޹Vq_T8%>;֦M7*\ MXX+e&ҵkƉMyԮbſ6*y>!![,znmS nT3lϞ9Y[9s&>ִioW>e5ڵ׫^x?}ڴ "+VLgL֨j}fYYi:l3kOި?^x5jTŋɓ'Z>(PH6P5&UBwkھ}oǡ9& n iG꫋ͬ7nx BYFb/sJ|T?|h }SM|4e:x i6{FժUd8<(o>^z<E# ]1xXYڷO?1Eco[`-KK>ZB8s˖i*uE,' Rx$IB(-K2mQ}֘;S }H{ la}4hçUyf^{"4uf* }@*1hS-"2ttg՝GqѬ! Dk6_{΋:ď@5Hߌ[f`A4ڵk tx@? Å;qnve)T(cSvLgE_jm ұ}Sɷ;ۖ#GJ?u^LS _qXC9`vjQ޵.=H‹ٵG>E:Õ V8qv=Gͭm j8cT9vnNg]M/FD[6gNdy"[;ԮWͼ1.2#ǟh}\m>kMk Is+d&6oYY߭YSZHhro[7/f 4h<ṈuO{4^)dɕgЀrtƄxUwʃȧu Wp\-[4c<<_~}uI<Ѻuk޽{ٳ7:vh$NQSLi,Yښ-hAо_ţxk`.5HhX (@ "Lpŋ']i˗__~)P`, ֻw.1] rHm~Y|r6Um(`̠}7N2kV6e٪`5 8'Jʓ;w#a׮*UJq?=g=(i7Հztҧi"Or@A{orv}71|[ ]tFΜ9'N־Zۆ f,7ou@ňCX0!k,[6E4i4բ9O<ٰX,}'y_UK(*yƇmž >(@ "Sɶ+1wndK@f6Eܹ0ҲeKXANa~ j%ḿ>!ك9Zi{)~:%l[ӦisS`Sdf~gGLXrC@>qbή__zAehҥoYdGssN駟6-jʕ8zkp]Ο?oԪUH5r! "bH? .71L_uGЬjY+=9kBvs95EhhCM! G6C{$!&2yٲ{1I|Xc̜y"P^H[jRM7*4mzpfP@3_q|Q#JWԹ}o\ ͈9s NԭA ~|T ^_{-&N",JP^t?~֯E>""ղAm+=yxΜi>5J?)=@o|fPΝ3|ѽ{汼֘۶)=h~J=zSkb }XX+`ZhzNaBaðŽ{g۴I7K]"B:ԝF,'+\߳gO5)m[cǞ@ZBkZ'H`Z(PsR3geI(lzL[ɨҥڡ<鹸;WIQF/|>u攉Ac<8.z U !22Ҷ]ca/*Ke|ժ~3cr][J  h"\jj?|x~z9fנJK&~ä^)l}Z͚Ve |2%+l+}6]zZ]mѵ0jZDuؗm^.OWzlpԘvwe@V}Qx0[9۷m3jU9r a_l ~'@ "K_zA|k@i%K&q@\WNlc&Jȵlp9GkK7td;;' DE]N Яݰaѵk@? Å0PAXl-j6<3f\0j*c_P@H,u`% ,E.'^Z4 $s Tܻwq11Nm$D/EC[ CD+@ODp>,[j[n*kYv'L4@uF,XKɓN@-꒡@_Xkqu,Y "o~]N>mԫW:TΛ ܼH9 xOWSK &6mҥo!m}b( k9rd49|oŋ)S*,>}z[{~]onfJ@@ • #Gf ٟ(KT">Q T7g3g߼yV'Z0~Ε+l@Kmr)l͖fˈ2@ _ k eDy@D @ ٿWnݲ" q믿+e˖ .1#E]6ʔ)cg3:,,>'ec|]ԲFc'O  @ "."@6m_|ѨZOҥKl343 ɓFlٌ֭[K,1dԭ[8rqĉǜ-Ü= $D)e޽Lg @+y  Pzuۃ~6gFRH"ڵ뱪X,c…I|nݺ-ϵk׌E-#GǏI]:k֬1>Cex/ @?Du @@ hʕ+8p<{ѯ>Qpa_~1xp\.\`L4xg 3VZeܸqq#:±ԢcN P{#v*F@Dϵ @P4o7n HF)@ '/ B@&My"U@m֫W S@xL@c$$ @V?WC=pmی^{R  ,@ —uC\ gΜ;Ϟ=kdΜ958@H* ,[F]\@ Z@ V߿B "wիWm„hC@Dr mڴ1:vhTZ J௿b΀  "\" @TRŸtq-C3i '6֬Yc|ᇁp:  +.2#x[ A3<b DXʖ-79 O@%@0$pէOyرcʗOe˖\ԩS=u.S\@ |ל3FNZjƹs;/U8$$09  (@ ":xNXRr lڴB͚5W/^|Urˤطo_>˗:| 2\9pevkJVzջv*rO?o@1@@\hҤɓ\pa ͛ժUkkRE>}:̙3/ZJڡ}%JSe%0a Dx[! . ꫓Μ9eܹ-OYLЩS B4jh˗Çoھe˖F۶m֭g@o 8C@\Pw 4EwYtiu(Ty浰NzWyΜ9aOXfڵն6mR0BZºR:   mq ^xa }5BҤIoWReBO!4Ę1czղ᭷Lc.Un.f+P1Ty=t@RPP BF:[ƍo>U A\T?~몋@o 4A@ _|7>0`P*Tشdɒg+VѾՂ=UT(\_>1mڴz7nh;޽\ronSk^zV *9{1"rBGA]A=uWv\MDif*S۰aC%2GoIs@oؾ}8 j8l85?+Vlޫl[l9W[q><6}vRLJP$IZ-4_1.v]> xK@9 xUĉu@$իW_,… b@c4hldЀ'4p-GǕ~ԩpg.^^5}^,4Z`hN3\ sN3]k6# P  us)Rpvt]rL Jq_sL% DL:ifz1ҕ.f1p, K@$)@|J@5AZ\|9c5r:356T O }?+q&8s>}:ƴpؿQ`}QeXBF:  I]F@xȒ%p8tPŋtի;cD/uTGr^Ѐێ;SifP ZH6m6/SV_/gZjQZ/fKe6# P  uՠ@ܹs[:"4Z<8VΝ;I-[ 􁦿TK@'O,1gΜV*|; D(,Ѵi^Tٳ3,C]6N>7k;3\k j 3k@<%@ S *`#F Bc&h֊}p6vuQ?f }7oC1z7g0OT-[ѻwQ/Ҵ# i|@֭[Ϟ4iҫ꾠)5̐!Å5kT+Rk5C/sS_r~+Ѷmoq7͛Wp\숈eBkVmժ|j1}N H,YYi>OM6%yݺuU\zY@os<@Z0 ޼yZ@̙ϪY]ϬPv}ҥt &9r$ƙP̯V{)s9s L2gۜiNQv_mY@O S> ^` /%3*)'^+W4; aRǰx{Q-E^hذⰰ+̮ %Kq/|~w)Q"b[O} 04@w p$  #i" ked̘hX73=Ĺ.u F[aѢEŋUc]|7輻m&x Xl-LR3i̘1èQz;v͇vKqj.J"4ēY;4.yORE@@"@`u*GeXg0((Q^=#y1u*H㧟~u: }go{gC6f@9^*vufcX k _f_" n<@|Tի7|cdɒ>Fi>uddvtR֭[G'a}85XfQSK &i=ҥKoС ~l Hr}LΩEZ04id;L 뵳]We~ɴ͛7XyW%   UD@ &LhhW.\hDݐ^l_ݍ;wX]\9ȑ#:NUPaq-O~~ [@E)@`ӦMN˵>͏mW <lуw?xlHGp]3o+WYqQ9[ׯ_wVuV !anbm!a+СCsf2:ٳg5c#Xd5h0Q39]@x #,` DX͛49WxՌ] V '=z4iR[G vCH"ʁ 36vҴ٢V 8[ԭBuq\PZ ls=aQ<'ңGC/%k׮]8}+W.?4rD@n}9{@/O J*Y3ڴicX 0 1 b}B=:-(aoO:! D@Z\X|hѢm*Ok91:Vɒ%C/cȐ!2V.gΜj@@D8aTXQƪUlqh @@ &1 @?xF P|@cpԪUK*+  M@7 "лwo %Jj3  M@7   xM@ר9   @@@@ 5B@@@    5^@    @ {@^`ʕ5u6ӤIsܹstQ ȦM*ԬYsEwZdɒ2o߾}˗/u2dl@nݺzwULO?o@OR. {jj|C*U+=nܸ7w>b:&M,L<ͅ 6Bl޼\Z_v-YӧΜ9E)hQTo\D?UQR s xB@'T)@|Fɓ _JvŷlR6.|W'9s&ܹs[2xAN:MWQF/_|>_~v744h۶7j5̲X# PL@۷o'5+nZ% ,hZZ5-Zg_ץKQWB 7o^ĉv}3gN+~ؾ}S+VYv_M6P~k*  PL@e">쳷4F˗ӄ])[얮]NT+Vܨ<琐WPx} 6T3fLϞ=YryiӦ x3fx,\oܸQz]ŋӧM6Ruٳ5jXiZ-fm֬YmZn=Lw6lػJ̧zߥKfܦϯʔ>}T 3 0t"L1   UD@ 9;.\aɒ%ꥇsA>Olϟ?ƕP7sw&?K5uԗȞ= s;SQ/^pر0u.kmnݺ8JZZm\rZo۶s2բȑ#sk@)@  رcG)z@_ʕb={v#4j Ct;B,4fXzu7|sѣGs)*OUΝ;zK->.jQN"|A<ƍokO }*7oCڮ:km.*Ke?ux뭷>3F@"ܩIY LI^U@-F׬յ@/@=C>*3uW^6l8SLիt-zxsNuk>M5^w**ᬪ۷@+;jZ…Tgaѽg.]Jg_:̰O7߷k Dh H3-׾Ŋ sN!̼I$jaEݻw5X# n<@.PE{E @(I^"ޫRD U+TҥJ^C@dy7Lffwyƙ}~Cb;眛 ,F-Zs͚5a $-?WF hʜ9 mZ/A0QOBA5CCC} RH$3}͛73xO$@$@"@!^$ <{,  5LzFu+QQXL2?Ě ҥ7ߌZe<}45CXN[G I&}͗pɀ>}2_k# ٧#HHCBDth. @ЀXh-Z.c2YC… #D  ѻw0{q ,}}}c2nLΝWH`z'  [Pې@޾5{u1c ǵ\E XA;A vӧ +Wm`i}}kﱸǁ7p{s`-!\r] Ā3@7oFBv@*UaKܹںu녅VZQx"`5!y˖-u;EGמ߼yx7\^K!bѸquSN E$M4E72R Yg    1ǶnAȑg%5ѕ+W Ϫ_3p kz9k=L]v]-(_dI tbGcpM{C֭W̘1O mC .|RPnk%e͚9_' >7dyFHĴѴiӵpH6]Y?ĉEa≒@hs<~T\?݄ w_2g, nB)y|J5cL&am[Hi;x0Lp[)<,Hg7j}6cƓ1pLXpe|3l٤Rj]" 3gp.ϿBFeѢOdCC$IoR?. _JM?@our9!׭"i;_8˗D9s&ԡCʥ~flgt?ΐC2V޺U+2ߚw!Fu1~0{TYN$@$58*T|3\u/׀pرӧOq"@pJ5A&pP uܹs'kl) w>}H(KȰ֭\vCnA'6la7l }`#Gju߿$UQF?'hРF$@$@$`o" 7<xժ_Y&;"o.Wb|ƒݜ(˰17 zyĻ>ڼޤ㏐8M7n، *Tl'ʿ ׭ jsvhEŋvx(GwMl\}?$D_<%;ʚa>kǎ۶IX2%Nzƫ{l3!]tZO DBI QKT 3e1Vj׷Zo͛lg!Bxx0X@)<|xIHH 2""Ʌ5'zNC 2.g"WGivjΞ}_;Ĝ9Jn&d,˰6,X tѤ/X=, Z6n׎ MPOpc3&p)gOtaafXk̝ۤIrKeG,(Veܵ˖7@k ,%Ku̗_ u-V񀀧ee`J̇Āi'CX st߅~O$@BvB v(VIƩӺxPg "c` R ^\ƄêUZٳVΘŶ$@$@$ QҔkV@<[82XRh!ZB6_^o B֏PN-p{FiȺ0n}}=e>%pݡR=mݻT[>t(4` FvȣCO +֒D[ޢjgѽnO$@&CKTXQB5[1:d* _~QSNa &ɱ=g@@@Y؁_aˈnлwCb֬Y=mmHHH :(DD,%2ʜ9 2W_eýQIKˁ_e=.""֭薁r̙O3'i,o|7o"C7ʕe-\X`}{H Ć5VYP(V,q}%kX['9E]X7 @lxPva0+PvV&MJ|D.>t*ۑ @t P.[TbW=#,4S9ԯbv;T` X4k^AǏߦ *uِE(K|"[?B >T"Z`Ć@Ks$H`zyQ;1&E գGgB_/V,qW bmpeX"3f YFv$A + m9jգ(=q6BHyΜ9#6ma.ӧO P#=~)bBO :SD+"y=Xkb8D7˗OEJlҌk%1@W\)VX!Ο?.|ݻw7*^^hl8/I?Ԭm+?}uᛔp<8pvv KpƄ wOuVV/KA>o^s3th8.#aㅇ) ; `ڵAM6'm 9pI`={+ilS돱Ǘp5k7m6(l.d< 8x5EC??[+BY#,Q"V,^b_v07}lQk˽6cAUhѢ}u,$ʱ|rzjqR6lckK"qIKbY ?2 DdI|B]E)0  N~ x4)~nL7P)J`L Lno-{3A[rhQ]qGmp _JHrki9W3qȾRJ`Ϟ?}Vi'c5Ǯ-?dHxm\Y.Z d E.vȮgң[kskm [Ed㱌H\͒eg֭EMF1+,@*VhR1m4}voHHHHZ" k[ *b*wMĎŋuUp?><_C_ҨLAlLp";Cx민5Ζwai=Xj| 'ѸqcjZE$i֬YbbժUfD$@$@$@Q!+ϟM31ZS"!.  #vZSʕ-btQF8LpqG >IHH qe:Q!+THoԨ _,:\y}҇&M;cwr~IH&PF+9uHHH"#@!"2:,S L_wBaAL FdG$@$@$@$@$@$%@!BK׆ K!?&Txc:\ڦra3IHHHHHH(DUҧ=qbA8jJ xlJ$@$@$@$@$@.NB NHHHHHH qmYHHHHHHH Pp @\"@!".M> 8 .8=      K(Dĥg!  PڗalN$@$@$@ @<#PNy^s<{f>. s Pp.oF$@$@$@$@$@$@x$@$@$@$@$@$@$\"˛ @&@!"^~>< @T^*ʖ-k{nTUYT"vڅ\x0`ٳ.I&]~<<7 @ IFd͚U\vM̙3ـHHL&% .ZlHH _0Hj֬i:|B}7  ׯ_[Fl$@xOHC;gXBԭ[7:XHH b̘1.83NH6 qHL\rj<RsHK૯R9r]wv`NR-XHH^(D؋$!7*T`Rx5aECl`Ҭny 1qxoJ$`;ҥKVeClEEDlHHl$@!FplF$ 4iD5J/_>B͚5>>>*$IpEFxA$N H O 6486 W"s LEgϞV6 'O.B,^X?,2'  ">}X~wݻW̙3' @|$@!">u>3 @M.]2+宍$}`;SmrEv>&D  ̞=[Ԯ]D„ رc%,lc{ŋ)S7o(sNq]1`,Y2ׯ_"͒%VXM!΁ɓ'+V5jo+vZqԩ|g\zJȑe3H\%J\HH |bӦM.>U)S&@XH@hyyW^}>Hd̘1o޼"{bҥB[v / W69{lx+\\|v‹H- IbBCbl6 |ItTX1ѠAwyfq!w~DΝ 0Ya H, B, ;ҥ5k&PG DٳG<}T@^̙E2eT!8x[*`K=z$@$@N"@!I9 @"+W.F5&uIH(D80'ԩ1'B$`Q|qg͚U{/t7ɓ "ʛs vډaÆ %kGӫQ!H s*D,X0˯J*9 EF2SX!&W&  %~5./N$@H:rN;\|Y"`f͚S6uOVwֈP! g/2" H"!7'*T ?4 VZSLpTٳg\?BCC9a_pUwՆL pc"q$@A7)[יQ8|0\ &M]vǏ t|ENZdƿ΂܏S-z|gϞE޽{ˬoݺ%0VӦM9rd. +2 @4P,V% #m۶?j9`TybÆ "D…C?۷oG"yH:X|\*Jb;OX(\zUܹS=Y2QW:k֟Qrl!z!1y6e}  H ~EN*=<̰߿Fϖ-M^.TomEsc=".Tm۶Qʔ),}w%,$I ++VtHH 0HC@ f:ՅEׯ_GEF&$@eݜ;wN Nr#w{m1ڵk)fҜ( a"壑 8|+ժyr$ 95joܸb VPҳhѢ\r 'N`EΝ"sX '{ @fDnLH܅͛EǎE̙E .w";9 @Z٘I$@$|"Ϝ# AePBҥK`q H$@qÇܹsUˇܹs ???w!"X-ċWJgsŊStHHc.% hL7n4S6:6 eO>[nUX݇p;UvH$@1#@!"fؚH [Å :OOOw^1tX '@$@$(D? ^ @ȑC5i)33 .&I.\8v'IH!@!! PϫxRG& {y&2  # vɮHHUV⣏>UT!   X&pQ_pX~H(DHb@f͚"88X Ħ$@$`3N:{E7oބw2eJQre={vwv|ؽ{xQx.*V( &wYIF,^XF$IQzu{t>HHHBa+ ?rҥc&g,(,WTI-9ra\rϋy&JH`.^.jBBB `[%K۝ba0aBKuti/o߾ $x143IM` ˬׯ_+W#BdȐA .~dJ4(Rț7*Zܽ{WEz\[!sٳ:Yf  NV`학HH\z @ ШQ#Ӝ9s1"0B/ʗ/oT *"yD@_d bE mB!k֬n˖-/^ŋv^&w#P~}qa͚5ɓ'GFw*B;wNl۶M ___|sf9 )D,_\^-Փ.6mlN<)6lH Gf$@$` 6@c @6mĐ!Cԯ59kAa4uB%XB@5DڴiEz]C={;rC'?~QV-%6/F|:B?Z+KNd˖M\r坶F7 ZN:ZPAk׬mzڷoD$@$z(D;Hܜ|G6Xؒ  x=O֭[k֭[b…O>Qs-Ο?^ڵkU>fgϞU D=H\LH@Rٳ'ztU$V((F"0&q*`l aHHPpw k6:tl7"֩SG Zߢ!]+x'B"?Z!K~m}3^rz/r C]v @RH!~_M""B E XdɒpHzY3܉,(~ YE$ć&GYL#D W^9{PzNk^z1>?  vnHH@KnDm{ 9Uc7|3̱L|I.GڵK Vٸqcb.X@P,IDXX@=mrE;I@@d c:`$],;jՓyRh۶Rψ+a8v)wq9BȜ9*XD XTApL$@$@IBkΊH qƳL2zg/( ~Q%Ă@ e˖wk!_ )#he&Mi7oM6~Iu0@\' Oi^]! rwדR޽{U+e@@̊+ jժ?ӗ/_3:"ݹsG f" pM"\pV$@q@fL#F0GWp%a`t[JB Aò wH SZ+5\iõ$` \$_0J;ZP14|i ؅իWxlٲB/D<~Xm~e8,$ ;aGH5j$vAŰ2@%|ıݝ5 ǏŊ˗Wu։͛ 8b@tYm6Chh9w>O$@$`"ϔ= JB…կ25h5b9eK9oܸQ5F< XB`qq5ȠMpbm;^u[AXKhB&G.^"rI4HHF1_l!p|0.\HHu PpwÙ q 6#DD^PTPAM6ꫯԲUV XC .8TRjilgꛨ҄;C $0&Xښr5 h|$&!JdDDklHR8KqBڲ^cGލi?lO$@$X"˗ s۷&Mg/(ox&EeCr;5៎$*7r.2¿ܑ8&w$+"p Lx VJ%JPےHgҳgOj¨Mʕ&'i`)qYۄHHbXaIٳn>}z #GZׁq-v7ni@ [}er[̙.؎HHI(D8 4!ϛ"}촑*U*o|,TU%_ºC)}n|E Ӏ|'Nh׎ZD$ 4ϟ_`_Q`jX,{NX v V9rPEG4x7o6t,oܸNޠ?tzh#sE{%]HH\G! ]pA]G84!uV("FyZh5 ;={B㖄~J*S믿:ě[o2 > 8C 8@qƦ3ga `Mr5a:Zk~\ `Q-sn:ay!0=b(npt˰'TE$@$@!p5 HR?h [[Wʺ8B;WG_;r蹳p6]dʔIԫWO x#,\!%KL v bҥv헝 8DZe$@$NL H#Q‡ۚ kn:\k\EXBtIݦsV9G য়~NL3L$@$@AB{'ΒH S) l gG/^,I 00P3ƙCF:vؘ7o^ubRx%nlK$@@BD,@$@@۶m}ڂۡ/v" eQgbÓ @tP-% (Q}G\5HHbFBb/^> ]?~\1nvNHHy(D85G" Q~}5WD„ IHHF؅Ӣz6f$@$@EBDl$@@ĉE"E˗E|%>4 ؃@PPRU&  "@!½gK$(V_~L!"L> @8wC-#&  P[ Mڵk'[ڲ b߾}'  7$@! _L$f*۷Ea8{ wxBx{{xȘ1Ȓ%;g$@$@'@!9 D$PfMqy 0ܚE 8gX$@J9ΛH źuWTiOhAb. y=f͚pe@roR\ŠvYF۵mᎁ|'N$*U޽{+*5 7zr[m˛6x.\#ҡI&(<A, @ 񜰘Pn3 @l96 @!4iR8I!–6Ϟ=K~K,yD=C@'`Iqnj3B3 @l96 @!+?<D pɒ%CAp" d|{1  &68#lvڦ*{-?\.lw* >oWm۷o"u`퀼+՗|q>vXqJl|ͨ r[ڔ(Q(\0`eX/y>yda\/^>,` rlJ-5 8@/xgHHHH\i J@·X+qÚ@~yqXP"vh:u8s_ >rNeqΑ#e$)HBE_Զ_KaÆܴu T҂ҥK9q*!0RApQo=/@fȑ_ժUk+C&M4b#3pI $x88c|;]hyM$@&@!9 ,1O>ÇS.S?6bhP{dɞ@@\ ,ZXeeի ' \reXN%^OpAЗaK@іf|mQv\o}1]v?j5Q'+՗qr"txO$l"M [Do~~Ű>$\6u}O2 K-Z(ʵy/^̅{9 /^YyH%z3,4p*BOIJngΜ)0nܸuȾliJ rp5g90'm^ @l9& @#,E?<͛73aCU\/|(;b4U X0j*w )Fg)D(;nc1 DO#\qEk _~9J0iӦm6p{?G]v] n#ݻw:uM6]Xp8KQYhHEBȲ_   pcpOkFr#"$D3pۀHۊ`Kqh.ܹs_}vzĴ0".\}4\%nC_g=WHemk׮hAۏ["(ӟrޓ 3PpeA$@$@$@nF ]tw`p :>[l Vz׮]˪otkԗ]~= 򤋁\{.X 2\m0 F-!p&1MVj>Wھ_|Ȩi-]4BZFyO$@$@!™9 jzz! bX<E.3f/ *b#!B.̱ۄo" F 7^-0V .p}}&M~m)h"nCj`ɀ1N*IኡeׁRnm'|pl3+ X K,e;y6 47ÇBX+tea߾}˺6lvX)L>dжA cǎ6o\یb;]wж_DB<`};.GwV" Q U &Ν;/ya૟ IH(D88#  Lʃt8Z :w\^k36O^CPlGYZj;q X a޼y-8u b|GvmK?epDַ ]5-5  Ac `oRN"HXÆ  !Wcc=' kP  ܻwO(;!?P(;N8p$ƢJ,y$ҥK;L4i z3r;~h%"qnxxXrf$@HB;5ΙH W(A?<1ӝ (3wQ8BٕB(dU4}V(;L\E6mZ?7 !F4\U|=g@@@=zFFaq5֭[z\@f͚3>'HPpw @!JP6Qvml'qo^&L/_V_~E([G*! ]A'E",!LR *^:,F ]ҤIsVqBW\Al"%3?{,Ν;aOa p NIHE@c uJxPE l|0F@.>(4`@'NàخY@eʔ9xLpǶ\:T9 }"; @!|5+ I1VE&Mlٲř䃸?Epzۅ"D$@$@NB!ΏHH@XXYo8pP`%d7lLp$_(_EΜ9a98rHH\x  @L ([ C1B˗τ%"]= XE@7LR| XXN[bŊfmz%IFGdz{{ %___a$|xzzɓk#a)xl$I]5CFRܗ dɒ52eϹa3IH\G! @<#!!!OK:!F _}B`mvW7oވ'Oh¯_xaqwOZ\=~X( LN<ϲܹsݻw ſ]ȑ#|eUcV" Jʔ5kV̙3M=2cG eDcß?amMXdD l%ԁI#~e +j4)((ȰڵkXj h83IH\E @\%|4- F#F|u4J|P|դ?# kҗ[q0ڋ)RD/e EP bŊVZ ]5ޒ v*pܽ{׌X+WVb~,Y(;@j>g9 q" .k$=z4BɓGnZl!4JbliӦ5Kyy͚5}HHH%PpI D@̙UD%(>D*Կʕ+fnRĉ:/N$@$@$@!™9 `ެY3B Gfl gn2d$\\a ؋{d?$@$@v';wVj֬NڋbX (W_EU$@$@$'PA$@q`sO@FĹ @ P!@6'      Y& @ P!@6'      Y& X$+W.Qzu4H$@$@$ @$@$ g>ҥK L$@$@$@9 =W8$@$@$@q$@$@$@1 k׮zy\K,`(6=x`jժ,TЩݻwWI8s9oFرSJA͚5}嗣7g[ l9jԨ/nj3f9ĕ+WkC> 8e$@$@$@.N^-[\%,1eK~3f۷tvdss4jh}$I_V8|p)%Ŏ'O$}ܾ};eoܸDEeQmϖ6ǵkײifG6/< .\$8?E Dֆe$@$@!@!99  (E,sK~#GeݻϹsNիWȐ!-,:u"D 6?~HΜ9/]r%!CC@9,mϖ6ʕz1իW ϟ['.`g sPpgB$@$@$^x-S~ym)_;lwu5TҞ͛u֭ஐ7osk֬i0aW(UZ‚vYF۵mmϖ6u+M"dxVMJm# p c͑HHHD`۶m5M1}SHdɒG5fre˖ @yo2̸.S1_qrSNw礪+@,Y7nx'|}ԩ~9 IݻÇS*;aRj]ΰT:t8'bŊ֭ZZ)cǎ|m{Y֭\)B2 4n gḴcǎK~>>>r֜ 6^z"k 8e$@$@$@N&0qAaw%իW)Q= 8p($@$@$@N pĉ`=;w^5kkĈ#FKX(`Z@kY_|1'K_UO>3PuҥK9Q}b~]tY1 Zjm!^KsCoذV[B--sq3Q%[MTׯߴ곌HH(D8/{'  CemAaDWy9st@˃ & X#^… @=_|9ڠɓn ߔ&M{u݌˗/5m"{Wpdܹ!m9۷Yx Ir9o\kXpQC[?[Ǎ=x=BDt> ؗdo$@$@$w rz+>(b/`^o~~/Dɓ'J=СRmn۶O"LQzxb.-Xi>dN}|Y7QD/q ٖli)+P;sLk Pp[L$@$@$dǐYhhȿ~zrk-ZԹf͚۰vcիW߁y#Ao}yeΜ6_m;A0qO-GPPĴ~-õ $IL_ftoK1;:y͛73E ؟3e$@$@$@DٳgI0]dg4K(q_֧LBbM@toFh2>}Ԛu/)D$MQ=d@ K>m}#ϒ놾-F?nt%kEtg}   Pk 8 ?BZ.B4&q(p\p!7v(1!zx?NEopLƍiܹs_@ X_ x'O֌eKf.$ ؗdo@X7Nj=|_dIx~}MC*UHJ;A vӧ +W~0Ҏcao"dZB rxȑΝˋkK)S>D?? }X(SQTFgKgO*:. @D""2aN#0cƽ>}ޘn6th7o 6vZ.=yk5 W6]:;r^ ؏3@7oFBvh*UQ\rΝ֭[X/,jj%r ēw} /[lӷo-ZX=z/d%Ļ'Z #ƍ:uLe(5ȶ$?GoҤ/2?-&9XSvƍ̨g)v5} }PGyVӃ"iR'gШDL/w~Zw?\*Q93K/ġc @|$гgYg`pڵhE%K:.X+=z>0{C֭W̘1O mC .|RPnk%e͚9_' >7dyFHĴѴiӵpH6]Y?ĉEa≒@hs<~T';\"ԯbSYתuaMϜ)(DH8< `9iҤ6nܸ8C`1-u#FP۷׸rJz(&N8HHv~\|yL`d { w6m,ubڵkb+Ӗ-[Җ /^ bZY@`ogޖli#n47o߾ S|ں& p> Q0 y\?݄ w_2'|N7s甋ͼy>:(G?|x1&xm[Hi;x0Lp[)<,HgK:ܽ:mƌ'߾5{9S@"<{zΘ6Wв&wӊITlҀLZ5.amB샙3by=^TtߨQ,Z4L:chhq$I<·Mj"1JM?@ouOo9;C[E2w8qYї/͉rLtCK?4T//k<~!Ce&=XuV+e5B֍. =nwI[O>3%JR?7Xxtm.\;`! ד 60`6lh騇>0#G~yO *_~,.8ڳ-F;ft!L4h`ctڲ. P)ܨyXUZoelr܋]\]Eɓ ts,â{Ĉ['xԫW2j`90~!8poM@kk:X##Gxv%UC:uA0*3ʋG?[D5y#18#F۳g~R= 8@9ù('o}Eٳh>2={^/GO?eo۸:,:eҥ;h'WzXI n")fMxW j5bD7ߠƲe}Z[lAVԓtaѣ5F.fucXo}ݿ)j%ߚ79Ca@)S&xxسCg}۵tiCSfpĪ,1 .ÆukZrlO^gvj.ȑӧaI-{ݰ!l=n<i Vw; >  Q1Di~=4[we B\*HԖ="v9sw6&L8Xa=lX ' >!I_ ?zY XY@mnz ^0fLSgϞ ֘;AI2 ˖=j2XPh2ʔ9k-ojAA$Y2'Kd/2. dZؙO|+sR|C2 bʕZE&Dv}*r~{ԩ쳴EU$@$ʮ  <eI (.Gǻ.pG@wVjgϞJ`PZH\hvVx [_!qeC=mnCտסN[Nua`6 Sݺ)6z|KCCWm{*MdCBK zA n4o~ylǎ< >X:h [3̙ސ82,@Wʆ{ȗׯʂ{$]'D#D[-3|gN(&X,h-]߼*MdQr, ,4of@J# }Ŋ%9ýd rk$ kF=X@YyI-rNK$@1!HJC)S"p*JԬYSWtUJF|W3o3+c';@4i"V~׮]U'Nɶ^ݧ㹱)N̞3% MBD4ޯv7}ʴue,Pm/:v]@Pʠ~v=(q@[O]˹x++/WxnA!F#mTnm?ھ-z3 Hmؐa: Y #@4XhsɅc: ,$QCX5,č׫⃲55)S 1ˡCTNHH"@!"*Bv.p-*+DyGQ}mnBhBBEt޻(( *U@A RTDi  "]j N fwly3s ys&944mQ;~*_*R/ݻσ"#Kkl=H#bRB_a'JB_ Do8vdL<7j' DŽG087cё{aKpP(#Vo-XHQ,^?]˱QFUV&)ŋ lعs9FD$@$@$@a %'ɛ7Ç%zA Hf[gvшHV:a$D[|6֮aAK Y{!7n<ܱc//'kH<Ǐ~82w}<::Zk|BYTTa6hk0<-w請4{xp盀 `(q:T2"##dH6mz+f>u5YgĉB -ۗ(?2!hs}e 9R L5򍢒IFiqWPpl^ W5f?Aep Ft7Vo,qvjxQo2rk#mCK^4k~9Maߏ} GDD<ˀÆ]hؾ9còe V [.$qc[F ⅟)E0sٲ?*|/ox/tȐS(_ai]? G1AQZ4m"#φh }u,#"JiX| :uСC[z)E%K/keX(PU$K/TdYzFњ{1jԨ8ԠAѾ}{ՙSg֭JhDzjoeu>ߒcI 1FHA=1ϟ0t Ȩ/KgΜ1Z4bTl{Wti1wCHHĢES:5琷߾4㏯O;X Lspbiq"fμ92-٥KwLb 6:,=؂ѿ/}e̘֎)r̓L5?v2|I":u S6%)_>p)x~3gкeӦm",?䵵#,'T+!hoDܹgTy[]VڭʙO$`?y־"cƌV lX~ \KS~xGNk׮U GY FBQN_`q= PHf-x޻aE8{D*U4(g<֩vsn` [hc{Ɩ-k_5  _  4*B|"f%/z jDzv>kV~`*6p^Y݊bT< pGԨ^jЦM8᠈v+₩]v??*jX<8'   agz}uG *ڵyxx,h v,X6sl4)p})&ҧOg#6mpS"edkga†5Α{a4 FG$@IABQv >ȑ 6m߰4w%†k׮۷o/_.,YXm1a x/ {o2Xr!Dx[_ FNCΎHH#&OZ-͛kCBBL{㿱eDBlG:}z9yU=ɨaDy$@$@$@$@$@$@Z"4xnHa8/R5׮p&+vaQN!m Wl883IHHHHHlMs(~7ʿ=cbf$@$@$@$@$@$t(D${L$@$@$@$@$@$@>GBr.HHHHHHcϑIHHHHHHP[ @t92  >w˹`  p@6d3   "HHH8{de$@$@$@$`  Pb       HHHHHHH"l:$@$@$@$@$@$@$@N!@!) 7q]$gg@HHH>:,$ O%p-q MO$Oea)S unV>U K*8$@NB@Nl!pB!Cl:nL`͢vژdݘF$=ѱcG˗gQ>5kֈƍo{.%@!^bOH_ *$:u䁳A̙3b޽R  :!ƌucݺul6rF 'ܝ@-L7GGGw.g4YR   Gu(p$(DxI/0hGSV%   f͚a I(Dhi@&Mƍ)Dx=HHH )=zTI14$P"sn˰H$@z"DxM^JhѢjׯYz*,   Wܹs?W˱H<Ͼ= E 44T a$:t :rU$@$@$@"/v%.\!9 %7 [(&ųÇ{:HHHHQS|(D#%@!Go<RH!*W,`FYti߄U 8+WDFSc'$@CBkT[_~%{   H7x#A}1 oamڴ1gϞd saÆܖ0E6$%߽\Ȝ9ȓ'px饗|M$@$@$wQ{M6!ݰ- 7m?(D?HHGVk;֎V:?#%N?#͛W} QQQbʔ)& r*TPC:K qWŎ;ɓ-QlG>NB}@Rdn3fMʪ[adr=9IH@RcٳgOZn6|ntIGᑷ&S8uO ҥ! 0d2Þ$@$@$-[6?Sܖ %@!co'N #Ю];UTIXGZ5U.{9HH LR 6LܼyS̚5K4h@+VL`ĉm0,_xWD R]xQlٲE oCGmܹsڵk 큵,w-9֯V[nl[9e˖Gݹs'q[+s R"rY$|P|EǏTRW#s̩zY`m/_{ϟa }9r͓u6mrHH H @@=[R<ʄ -R AЧϟ:w,c!HjJmsĉ|w8k׮oa> g&rʉ3gΈ%J$tҢYf 98 ~طo,HH^ ^WV-``)ϟ_!3TEYPѴiSa u B?>x@@^\DŊDOIaÆ/'uH#@!">B,'/&ТE @BDpphҤz{4iҨkUjb{Y֛;wz4zs=/ǥ BC믿cɒ%:!A&Rqqf͚*aѫW/U-pÇ=zl8  O%@!SMN СCӨQ dA C%j0I͛_xszY{[lY'\9 [⇗s}ĉm^޻w ׸q㆚>wJibɒ%Diœ ᶷ#'0tȓ'OH#`.ҡC G"y3HH6ї\(!1jm!F}%v)SF ݙc &@!»/WG?ӣӫ4hb  G ****j ]ir|ȉe|m*HJBDB = x8Si{J֖"E [el%TNH,",fcBAg$F1$lDqq[T$ϡI rܾ}cM->}O5jb8yBb˖-޽{mu~JWѴiS[3Bׇ#7ov 6$@CBkPlL?, .yiҤQ! _+֔T{ΏHHOu2lظq)[OaTipu؎;r[s<b"ri$`.]I& |KwNFg/=!]Z ԇ|@#q9m6q@B c¬Ç̙3j3‘6pYlYQxq!2yɓ')LY/s@I$@$`@ԩEmK,#B T֭E\,mx Jh ݻܹs]8*"%"|ns$`#BO>=[l62fa-{{/2ak„.\X.=UP/]tL2hѢjrMb6|5OhHH"Pzu; :tH(~m 2WNԭKo>ݤ/\ $@ڵŝ;wăTSGHP})h( ,W'[M pa!Q~}uˇ"ieXk׮RYOVrM9/IHl#=Ϟ=khŊ2}b;ߤJR/_>qI|\" 8B"ꀗvX7k$K.ٲQm^ʔ)KKoRH 泹s6|tYO=?IHl#q [ m6h[B }B=JpD$@EBDbe$>3;"DɒpH!!!1DEE 8Ƅrl'(E#mn֭ʖ-[׫b|D@؀@ѠAC}0wyДsHHv,&HI)D>|X :2" 8'dW$mڷo/y5,Pړ{XC $4J 5mrM|xN$@$@!>sy# $ wI "K,N[JIFuFi$DdȐAI$[OʕSmrM޼y.N8*ܹsycxB$@$ 4c/#gJZBHY-7vG$@5!#PNӧ=2a}Hp(TX10IQߡVb!4s5 B~" )1OزB [H 3PpEA^N3|MQZ5W3TTI`ݻ_-2d%D "[l>nݺB16 |Ehs :DZ!ݾ}[=jڹHH>:Dy8Bvv -C:5of ~ѷo߄wHH"l*$4h|C\N(c 1GCb;d4lPڄ0MGV/ǎVx.\Xd̘QYFmŋzuw)`!"{meh `HR$v.<' v)RD Dc ˿SB}X\&LpuBD)l]\x$@>JBx.! |xM_LlyXhV^my`]<6lPf/i 2@lІ8IXN$@$?;vB& F۷-L[&&pHT"H& #\K-)1l]$僦2HHjVdGւM9~ |t9 o&4jȤ=0*D8a͡II~t  xX̙S4iD$^IiӦU H nsYL0Ev@$`/ c}a]v-|Yk4=N$@F>~ѣG5ӂ ^Cm|%KCNwV8`0ac?$@$` 6ab% sFBhN%9a͖qܵp.HmPp[Ȗ-"wܞ3qΔHHH@ v%DLHH$AI 4ltA3Ͽ\ o *vmjIPpɐԩ駟DhhL3%  cƌ!  H2" =&&PR%-޽+<{1= O5H"qI (MN2/_ VK8z{O# ׯ_ S$ x7 }:8u?!CDŚ5k8<&"ҥK'bH@…] AŊ+kDyHɲ_ #@!"sdx5j׮]sPi&\hDݒ @H6:̿)I{+^}޽k׮xGmV3UT?5a„p?m][/MEegP,YF5.gΜ:4`Μ9}aM.=eʑvԧOɓ'T3cǎۺuk *3y$@8;$O";O[+ $17ofjѢŊԩS?R,(ZE .QW/޵kWTz6lO>=M?ҥK~6۷o1D[noB۷o@do=7lP/}wV\>|dƌoiH a(D$[ xg+$*)9jdɒ8L>w\Ő\m=j|РA3g|/_Ucǎ?:t_ v?"+&N~F~ TR0CNٿ?pf!Kpg]K$`|XJ$@$@$@$@>E`u/_޲z;ڶmTxE9sX*$Dv bʔ)CXʕT{6k6nҤɯ(w ,+vŝ.#ҡUVȑlA@։Kń!H (D$!{     }^JB)SZNT(U!|rJbc;ɓ[ k֬4*'~(P^ZA8w[%HGFe˖=؆s$XR`\/AB3(    ի7 .. 8Z Q"ʤD\n ,[5+!Ԗ[5kٳg&x>ٹsgUzж5: ˷iӦJ,Ҩ΂ z;wΝh'O F@aE;ҦL2a ,+B%G)W^yñqk#Ο?WI<'p@kV$@$@$@$@$@Z B, JdȐ! >|R߾}/>w/ضp:bX}?s;SL7[n $C(Ygms (DXR    @)y$^ehNm26%!B zg7` ?7:Njr@։ ƹ\dbĈ( _>\.b!>-[/]7n:dȐ/_0D(>l 9tP)XW(Q∾k)hހ(+Wl~ĉ"Ц[ :t `Jƌoɑ6X;Rbpx on(҉!g @PH?&    taٳ_ Ԇ 5"3a(!N*d4?gȑi:|a]/oWiyÆ !|>ΝUWJ]2^ 8FBc؊HHHH ǏpҥmQjժ,?:w=CL8|^+ X `{Aܹ/v0͚5[6X8뛁ΐu7o/R1c@`#e`O0&XDO>swP߯#m' „JVS U݃#L5={w 1W?^ 8FBc؊HHHH, lO_ɓ>};ڲO'!(X ծ]{ ~#1$g_}b`O.|{Yv 2YW @T lwїH1"V$@$`3ϟ YHH @0BӦMWկf޼yITD0"j^I1.`>`BR1I[ P;u B 5k"vPlPmƉ 'PB- ^/"o޼O?ue˖=ghѢnSNm;p?h`KEO;sLbeys<"<.q$@M ""<|U4iĤx<5Sq$@$j7nVRɡP",烘1ooc{ި"i"={*o4":5ի|/䫯RqyZ.H ":$Yc,xbSEEPE EPE Å /^y|J4lyS+M8,׮]p&+֭"DHlG 9s%B]"DT'OOiTXGRoٲ6|z9O"/\`R"%KvDs$rʑf$@^DBL.\MZj&O۳jF/O AB%?z_رcn5#ɲ 8 >'H:B Z>( LAAAI7L$@nF`bȑ:$`)?ϟ?f3tHH%@!^bO$@ /jԨZ>i ɦ$@>CTR & AB,]|5a 7Mwk!pKʞeQjUѮ];Lᖷ"iJߴiL۶mSE_~~tzl      H ":$      %@!Gor $@$@$@$@BP   'uZ̙3ҧOƍRۻwoڵko)^m۶L*c9SN裏Fn޼͛73e̘VhhQF+PY֣#9yqFM08bǏSըQccNJ>VPaka=  %@!"qw   7'о}rLR3samm.XG-VNъ+ZhEeW:ul~Zǵkײ}]WZ ERɲH… y:ux׮]U ]re%JÇb HH\CBk8s   7%pʕR rn)8p@YG|g_~=O?.{We ѣ͚5[5iҤ/ٰ|Ç/Ftt?G`%Ktׯ߬O&;wn%͵4/cނpVe$@$@!@!59 J)S~yn)_˗/oYzm۶] aB…O.]mɟ?c{XߥlRnݺmϑ6cǎ?)Rl7Om F`h# p c͑HHH\D`ƍӧO>ܹ>((L_NRJ{PG^L&3+Vdnؽ{w?ó`+@ܹ/lr[oL2ݔ={*M:uQ-"""Cppp$0hРjժU #FXɹ;tD'N>e=ly߾}HB^zСS!‘i9v}_|f``C9g[&M "l!:$@$(D$._N$@$@$bSL{}֭[ׯ_?um{Η-[~%@v#G d̙,_`A|׶^3B=bŦMb kUV}T ǃc|ɑiya|1*oܸZ%*Q= p($@$@$@. pСR`=={'O p#GKX(`Z@k`-?Aaذaae_Ұ} #_Ϟ=O̯W^%*^zE?KsCo޼JV[B-ϟ1gKHax[2  %@!"qw  ʩqB%"gϞ:XL^,mw?GǵZ^? NBXHHH @hhH˗PR@p N>]9 Ja%B`'ěoxw K~$d܄-Xi`B e,Gs-s!-mXHH(D8'{#  HB ǎ+VrH"Fzk~'_ٰBD8pɓ' Ç:R/C ~%888R9 gR(W~}[kGs9Sg\% KBD\&!  P!믿~H@ ,z;D8ܲeK˗ :tX!ʕ+9'!O?}V2_׭[p3ڵk?g/Жs)D@0"Zl? B_l KsuV~֎HksҥKPϒ [`  HHH _͚5IbD޽!^.\}޼y2߯_Y .cǎ?̜9s@ժUwbƑaCK(qDPncsVXbذa7dyHѺueޑ%KpY?СC`≒*B@9uTwysVZ[MM&Ui#QZv$@$@ '@!"  KԩS?iix[ mkN)7mT7,,,_&M~E4)S qK.-^~L]|bDN˺z1@Qdٲeʴ}?jp ,1~-, @ѷtHs7ٹsgUԩR.m] 3$@$@$@H[/~߹s'}HHmb+o$tx |eƌWZ VpN 珰&:t >]@( l~zրhvL"`ѷo9kT_O^7o|\9IG=;vo͛`AQeԨQY\qGGsvL{!L4kl=mYHH(D8){$  Hbuٌ0QˁI& ׶$$Fv8kWRX<4lpQJ/ 2`/k% w%@!] E$@$@N$8j˘PL A4jH(N8qWʶfDlKCIu| lG8tZя?~ǎv[;vʃ;8΅HH<QxTֶ;V)R}\KrH~%"YveO ~e҂y{3k @`4.}xY&Y9***N~ttxA|1ݻwELLLB|X8`6)Ҧs8'N0Z)'͗/_}k׊;a2D뀀&M2嫷H2aڠQX{o_"Xr|KI2 KB%x=W _~y?`~ezeF͞=jn AnY# si|8~~~"(((N?нֱO^[z  3ď;wm5֋۷,Y25Km"Phbҥ֭[Y<ᥳOs? K_ȧO6ܹ<}PݲeS/Ӭ-ү@,9r?~X"ER_ :zʕ9d e{<4uj?xP _僃#+UJgР̟ժvgQy>&שSQRZ5q㲏*U*ա9_r%:Ç'gkڻ/\x':65k6bDMy\Q+%s? D_7߫qccҢ,U*Xoܗ.=U?!Pv8"βewZoVfrF͚]9ѣΝXR ѣ–۴ Z=˧],#@m̚/ՆS|hڴy6C-L. )_UQ/)/ŋ ""88L^ }:Di?Yr5÷xW?~!J|}-[_+YhQD7qRJ+CN5EDX , _ "| {aΣG1GnǸqFAP!pzDTG0~tlx7l(XO-yC}f~8ALo{W>YN+(VZY''-!*ھm=Ԝ :zձ|<90[۳ $Xԯ__kN(|"h8V|cKlP,+b fՈ!XHHH P&klx_zhm~]0zt:6ڲ'h=RɓsľENXxonѪU/x!Ge`eBwjtvlHd_|&LuLs;uj!oowE,(V+]`J٣Z@Aʅ v|lQ7/oҥgσJ2_{ |r"2gb͒%;X"d;KG{~,K 7Or̘c LqR @bD%,jвeK>lڴiE׮]MODDDe˖D$@$@$(Dqt N[⁼euph#kאo!D סaàueLWvl(c]ctH;wBĶmkj-` F۶6o.CbRa`T<%Nv?A8ͷ{aowa4"dxN$*}/QKkɐ!:6D$@$@$@"7Kmui׹r%$qe ?͋k#Ǔȗ/>]+DyAX< !ȕ sB6X{m9QVp m5jn-^aiӽآk8k4QtyabTnkdϽoV=㏷I{kܲ}{خbO_K$@$@$@$@$@BBwR BZP/e|@v=HpJT"Z |C%s(T]dapb4}]k׎ kWֶmRrK|YN$@$@$@$@$@HBj޼>cQ*WܭC=m|Ph-cp^@3HHp(/:kրn8wISշ߾A }7oX`CDփMynFVr R2{!}tm$(¶˥`QG_k     "\|OB_|H@ Lz;S)n}P ~>R[硡6Bw.V_nݽ^Ѯ]OgP_.]:"~)^@to'ObR#Giث>4$8GT#!P^|8ښ`AK Y{!^] 2U_|yjՖ&     o!@!w72}5k~GAep Ft7Vo,qvjxQo2rk#mCK^4k~9Ma#d$GDD<ˀÆ](ؾ9còe V [uF1-#a"plYdk>7n:d`/_0ۈ}vc裘 (a x-]ٶueςg{a40X/ : DgY0WǢ"D$@$@$@$@$@HB:t/M#NVӦ\Xc|c{3o: cy{vŷ;|m*S&_XCM!KfϾ:`Kd_3&cGE;!q,0DO#Ů] ~eN Fubb̙n}nٴie<U*A]DHȽ0Wl&Rxm8hgjxN$@$@$@$@$@DBD3π>^}XyJ4 Yi a֩vsnܸ,3׮vj/؞eׯGg 0EW k-,|??fMWǏ!#'ƯU+ֱcΙ3eYO,n~ ʄHhhڍ 68q"ѣC"'{kXQ2/`Y{aD{a4DEvk$׹so5N` 2} FG$@$@$@$@$@@B w_-Us ~57=/Ũ(/ aTfo^'M1?}[8D^ xXשf6k-m]Ko/lPmB>D a * zX7, `AAwMy%K:/5 8{֋å $ IEރ+֯נj4;Ǎ>l#,iE"M>=BZJ$@$`/-Z . {m^ޮS;T[&؊@!ˆ HHHHHH(Dhiܐp_k]{1,!L28?WR-âNBYa$      P?dpmʔCA*YsnٔHHHHHH Pp) +w$      7 @! n@$@$@$@$@$@$@BBiHHHHHH܀7   rN      p"&p $@$@$@$@$@$@$+(Dʝ:IHHHHHH Pp) +w$      7 @! n@$@$@$@$@$@$@BBi/[gxx(_ҥK^2ZN͚5֭[ho%   t|9;HiҤ)~~~"mڴΚWݻcG$i(Dx|U3fbРA"((T< }{Ѷm['OlvHN3;dɒwyGtє:ujwB.#@!e93 @mPԩSf2™]/pO# @(VX ΑDD NB@_~ӦMٳE×1p$@$@$@$@D*?x=TOBGPG#FhQ9 8F ybǎb̘1uV$%(DxɍedΜY˗OB "HHHH`{qT/ATI(D8){t!PӾ}"\C 8D… ؖP[6"o"@!›s}s$@$@$@$IL&?“n((D$ Vv*+WVU,YjXC$@$@$@$@vH68yY]Xo>UN>mc7%   "pMQN"E 5JCBDpe.$ЦM1rHQZ5ʡHHHHHvG͚5 ۑ7W!o߾Ǫb_Y7I$@$@$@$RN5kgL$D&@!"'/^\9sF(Q"$@$@$@$@$`h?~={v;Z* x/ {o}je76XL!§n;K$@$@$@A̚4imq8IW # tM|"&&F%xHHHHl!,Y2m6tR[  >q 2d/_ss$@$@$@$FnرNsʤlQ2+bc V#'@!ϬvڦSN=Qp׼yW_}UL3P   *T 5j$%~=CXLܙa/;^"ڷo/z-BCC}nrؖ("jy.|x$  ^I ܹ2Pp' w d"*]t"Ă ĕ+WbGt?Ʊ $"lٲ%bu6mZqAPf)5"|{zEŊ˗Z^!ty  H26ly5khР(VH<8q 3qEe˖k<6|ED$EDX2U,aӺk]PPQŰ** H,A]$'WŚꙞ>O[U7߷ح=l޼YF/C!/:[r5m̼y̲e 64͛7?e„ fcqk.S~}SpX 3xk3SfMCfĈ.tSrYgz8Cu֥YM7dʖ-{<>tOk'  @y hk h8IլYxU?sM [o *@OGu]}Fl ѹsgosQq|w-#W & D䦻\M@U`˩VZ}iM2,\0//C G (d, d0yd"!#+VtETB[L2օvQٳg{V+W,c^̙GxȬY̠AKIO!" $%J=֮]kVgWxqӶm[wzꁻg׬FI& ?`o5j{ z誏< C WV(Ŧ>!cf /t_uZJ=;!SN57p+J/%'bVR\2C!" f%W\qEO05/ 2o_|A}zpkF֮]|Q"G7 @ oZ-K.MWUk׮ʼ ,^[lq6jX qЇ1T'A DgBN'of?~TZdI\B9XN& @kx$Ah;NPCU3WNi.MMyBDuL<kM ˥KU-W+V̝wߝ<@Ia o?XGFY rbYxKtcqE A DgBNhԨQʪUR= S: @ X  5_!玉~ӪU7e]"-t|0x`W\u  @P Y}ʢuV)_2Ox>}ؖ"I9IFફ27|`qGر(&駟nI@:M6BDj rXÆ͑|.\8رc}%\BB%1H|PիWki͚5Q~}鍊~ʕM֭ͷ~FHW!X?3 E $ZEg6jSC  D$NVXє(Qs׶[m8sڇ((6O0wnԃ @ Ⱥ T_L6W,XJACg* +X&EQ y0r;~_4o<1KBDS G'fA0ĩ @@B/%K+V/ڼy(\Oi䙉3QĘBD3\l \wuE @p>J*k+ʺS!=k֬iի_dIvyB~z!C䥛\B!".4V$@(f=-Z4V2 @)SDʕ3{~yUϋe˖f͚L@, (&uݺu_r% B@۷#GUT1ŋw'pKh95/wzlƃ@^#2; YFG@ UT:ujǹ3Ys3' D$CW^fȑ#&銶Q$V$@  *6lX",5@ D8b7R(ϵkךU{:?))q @A@aI˗/'C'`yBD^c7"ZJ3gN*BDDh@ իW3>AO!O$pW_DB]@G@ѿ+obyBDaL72k6'xټy)]td  @8e˚>}-[ѣG~xN SQ$7n?iùhذi޼yUכRJ7xlذ!vѨp);w-0#i D$ͭfzZ**BD,bS7j-@\KY@o>#/ٳ'| 6իWwr&y! yoѣG]A'I @@\G3cǦ!-jtbʕ+|aםK/dvH+Jhݺ4>hd#lw<{UWRֳb ifׯTtWqBiˬMv/^,mI"T;۱cG/0z44?"*(B"Djj7oY`k (3p/[!GYOZb$e˖34=y;W ė@ yg~Gwߥ,!m!BKOie>ׇ4N=T>r[@ D$OK|Y]FVzKhW\/vCifԩqFYwnRYrr=&LQa d߻M7ZTHPC·# @'`Ξ=;p2K,1m#B2EDVuO!ΜJs%mE!A@5cF*D-GNRcpBoR1=4BD򋿙{mrzRv< ė@bŌ>~ĉ#ɴB,5KsXќwڕaKTiQ@gI@@~ d;eB~zo)]2}XzZAL2fFL>?*}Z/T!f\@ 7TZbEm95!vSm< ?eݺu6UQ 1Nr쭏2m"@/s9ǔ(Q[yv>ŋw>Hq׋FIfr)bꡬ$QśfΜ:ԩ\1Bx=%P\y啮xzwH]T_AfI GBO?4Mu>${$Vv[K|\tE.3~!bn[1vO-#p/) D$mf^RkpʊX?xʝ;wsz\7Zj?[Y*Zk׮СC6=B*M6,] )ǪU61zhaON>!@TI@,͛3/tm';G%^$ )qƑ4 BDH>W^=w{0b|9h˄DpӤI\D9t%2ԃZB۷/Mwڒjxe%uf.rw>+8'99 @%cy%lɛ9 8Q+8NS !"4hء7hܸqFJ2[x?թS]O=cMxfq[ 6_G+N؏&޲z{l.H'-ɽ=z{ّ,I~jkF:)]6MײQ4΅KE9O7 ĕII/BD߾}] ~0[#dOv nYh몶;!$70I@'+U侐B8)G}4䴬%Nqm۶iuA< )? ?dIaر#Mȩ|Ȁ @ @ҥ]q 3Bml2ӬY3ӱcG#ou?$o9êQk)!ǑdeXH%NA;$;dwb81SKvf(bl>Az(+F%C}j#_$B9+L C~$S|do3<" PM+DdE?A__3+Vt?(T?\kL2(?Y?([׫VJ7luHc$!$,wNOk#ް'8}tSBs駛޽{{J~?%V򲖨\`?Un*ۜz Xb+]+O?4oC4g)Kη~Յ^Zbh˨>h; !aEJsƞ3g߿J$#d%Ffbl>A9rH7*,#رc@:!&zȗ)S|,&M$*Ak# PXq҇msՇ  !+mw… ݟ]kMiv U-H[3., ?Xp6mjd^o[^^NBʗ 37/18 @ w={+D(xfۨQ#w6ܨN6mڴqFc:@@HrڵkʀR 'o8VzGk~@@ @菘%L>,4ueq&eaD^c[F&(@f"2#DyBh׮KA11?9<  CNN˝KY؇p@r^z꩔  @  D \qQ2 @@BX`AݦMΨ^r <;v,߫zѣo9[\}٫ڵk7(mY3eʔ/ .tEK.UV>#uY?6ȑ#o7n\˗W_OuqeݺuM7r>p@ƍfΜK/]4>y@ @@ lݺc)ĉoإK &MjrժUUzτ ̟?2elgtOO?{]5k֬CYm#q+\B;v&E? +SNmYX]~a bt #Wp"B@ " {Iz뭯lڴ㻝y튞;%B.\x(P^oׯ__{dĈm2:ʪA" 'p~J*E/7|sqϞ=YdI|S_y!'|A'ǙN'1`g:?/Zz?y8d @ !%r˾f|AFڵy7Z/]wݛL2d5Ѳe˩'OnC3<3WN̙Q|'mڶm#i# 3fL/KJtܹe˖peW=Me@tv/O@ *A @1# ? z׋ʕ+|4h0WNT%2aÆ+C }zs %r'Qßg%ܻÖ:ڵʗ/>$H\|h ,+e˖-sc^tEmmڴD,;bݺu8isXGg38B @ !@%N?/t-_moՓ =]pm[XhQm} wA@}Xb5{-o_+!B"nŊ:|h^Qe?_!mVBKժUW$زH<Ӷ )C WbiCN,%{CN<$;_,D u/C@$8B @1' zwC=a'Pn}ٕEZP?PSOU"6ΡZjG(lxWOP%瞡T4hcǎ푙! mذMͫ'%Kܪᶓ,9E7$ŮZ<6M4Ib5\/8:5B{*\L,4!OkK!’@ <@񑠽y`Mцk8餓eR[6uujվչ,l^QAݺu/!B(ʽyWk;,W_}UOQe!!bF,ᄏ੧z@V$jslHڨR47Y9h?e yМlG Dp @ \L^`njxY?|Z{+Z6nxVP(˻|4h,o=Vy*+WO߸qA޼۷kE:cM*KZ[ӧN꣨x뭷zY>"i#vn8$)LJ)ʇhٳi{KGWo",  @@ X 4xŀDj @8bAP+RȞ2EPO*Y!p{AG^  8$ A-YnՁI4xG"Lҥ7{e辌5o5ۗkz뭯hKI.]&ȗpr-,Rm8O>wY1 @r y^mhNloJJPϔom%vm8zEk9`ܹ΃bd(K96 mak l=˷ /\jtj3g6Q; :Sͧ+ONAeڿs D @2elÚ5k*V^}" #ϳ>">V^g~Aײ&~dzUn1jk$~h Kdޣ"wtMB/~[7ƍ>5kE}3O?tP~h˭%s @ @ 7 !bB^e}A.[ Xjʩ> \&}!1"HO={#~ [*'pG}VB|Et}[I*UZ|yu'V ۗ=gQ:t ێcr@Hj!@8Ye1YFHyuYW]u{|A<3~Q o cK?OIt "_|*VF!>'LE/iӦ{B *B>wnPJo:\%KԔuE5=*? uo%ܿAQ:_?_!<Tbē<6ڶRDm:W. -9Bر4 ⦾"h6z ''5 @r1D ٣GʭڂްzVd{g^5C?{B1-!W^cT?vXN@:t==-ZLסM!cΜ9 w>_O*'36iduu\j𶏤ʺB[_~>u.g ϟ;wnկ_+",  @@ ȂA? imsm&g'wW[_%&[Ћ/+ Y h{gmg پ}I_בY8ȩd~ۺ;t^e0|~֒[Huvb!O4X92Gd!뮻MQ' *+Y}ٳ1T)GK$\NA%h^5,K# 68_()6T @hkU篳bŊs'g޲;yy\BFl=mʖ D!<>oaev̨D~>2ǖGFDl?eA!.է"ÝQ!p/^TZ5E΃ԩS8%n, /z:A0AWxp0M6y嚇ak{>ha[W@ϟm4*G:5oƍg~/j K/7QɺG!"z, Ǔs82W 65f,@@^%8 48p8aΝ^!M3S"O>i#K9,^Nrq޽R #x;~R"B u <୓οZOQLԵ@Kzh`rE px&  (D8pE>u߾}Y"eA3 /'#]nzNy ^ΜG!"~9\I&vq|L{{/N8(osQ۠2Q۠<㔇kd%DZqLٲeʃ jcǎ5W>.iԇ|t8* G@q#N>!Kh @ Dċ8~2oQJ>xx:۷1bÄD>"$!8A wyCϞ=9CxpD @ *.BRx `#Qb_2ذ~9&AxPgL$˛ݻj@} *36.L!CYf1cƤFHrvGE;]‰-_y1E@H 'xb!»*|rBHl)0}k)ᄖ X۞s@  ʌ#p7jE v_Y $9n۶~)5ydWpB|&BY   D[Ƅ!@ 5!/e݆YGm@ "˓ @ -Z4WϏAO!"1+ @ V0@ dN@2Ίz)הCz9?\;N}ސѾ}I RJ?]?H5n|vI?vvˇ>iԨQ79iTy)_~p!Ȩ>e ( RNdoCX#">ԨQ]v};שSvs=wŻN:r]7,Ԛ1cF͛O :Hh={s/AAM2"lZ&'} @ v"bǚ @iӦ6lXHصkWE]"}Mq디T׭[N1o޼z=]:n޼}?v;ㅒ%Kn/2dȽsi}Ӌ/Ssu"!̴t<ͳs{wzc:>* r-#at}7:`g!!""i9^wuo⋷*Ths8|ɶm~$ %| xgw}O{ݶm[>Jrn_Խur>a„.+- ,[~6 !㬳ٖ}F[BR>yvÇ'֏-ӧOo[jY;(aÆse_W:.^"3KIC 3OPy6m>Yb[' G ĆBDl83  @1 dɒd=_˯#F_Y7,diYkCF?8XVE( fj|w>/c_pŕTO}j~7pz1ּdw'*e˖SEBAPsS$СÇ ]zXk:f"/6#rqYSң2O ,K !hmԮ.TbnY+rY 3@r d2{ꩧ;5L;ThKo݌r׮][m۶*3<3k+đk_cƌ饟-GmWKO%z56_G"&LPݻw-ӹ}$ȯ 6v#/6vAP >sm:[s@=3gD@r8T^}}ߵkWN;m^@A7;ŋ_4|~&Mj/+9GY 0 ]H( mشiSQHQm;/P!dq-YszCs=C?%]ԇ裏mʔ)nZR$Uy2xIY90!jӾ}IYiK]@>3G@LYf_4m|r`РApY#S K̎+V\;,ZjiPJ/X~VMfsC>"7o>B kC#bC!"6 Č>mM %Dl2` E硇z"L)@HzIO qh /mfRJiӦ1?ԗmvdc`;nܸgn$ο6# ďBD32 @ f_ H=SM6mRcBaԩisqFㄷ4q-=zԌ1"!";ToϿL;C+o5g~/K/71V* }y@@d|!/`+tE I)ViѢEJ؝T\n+<8_zرZdł@R"BV;v8s&=?s(u+,Yrkns c"W@HR΋]2zI'ǜt9yy3%Jʊ+Nd4a9Bnݺ "#N%,\\>M@ ) D$mg >l0:/wEN:):DҥKb@@(Ȑ@H  {5D\/_~.soTbV^y=a*B  Dd!@ ݻ7]QjjٵkW|e9r$TVWzu 8@@&oS <쳼e!ȪD۷7ݺu3[HHҸqc#.j+qgDtxP⎿^]\gG &ԷC@2ж|p[mY~)wIrB#F~F[7h!;k $;d!@ OA-L=L,9[MRڶmksl*رcG}Fȇ @ 1 D$}eU 4VjFOWYć4y.RHH @ @  D$f @ x@`|@ @@@HR!@ @&; @ $"D7B @M!"w!@ @ID!"n6K d@jNc@ ; @ <_^EjA "B @ (@2P @ @ 4l( @ @ " @ @M!"4J @ @2(;@ @B@͆@ @L!"@ @ "B @ (@2P @ @ 4l( @ @ " @ @M!"4J @ @2(;@ @B@͆@ @L!"@ @ z5-IENDB`sardana-1.6.1/doc/source/_static/dyn.png0000644000234000017500000310016712555672634021774 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gap_offset.png0000644000234000017500000003751212555672634023317 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gap_write.png0000644000234000017500000003663212555672634023165 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gedit_config.png0000644000234000017500000141762312555672634023631 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gui_snapshot03.png0000644000234000017500000041242512555672634024050 0ustar zreszelaComputing00000000000000PNG  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

;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.6.1/doc/source/_static/gui_snapshot08.png0000644000234000017500000035607712555672634024067 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gui_snapshot09.png0000644000234000017500000034227412555672634024062 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/hard.png0000644000234000017500000344106712555672634022127 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/kwrite_config.png0000644000234000017500000271200612555672634024034 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/limit.png0000644000234000017500000034307212555672634022321 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_edit.png0000644000234000017500000007720012555672634023306 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_fractal.png0000644000234000017500000016510312555672634023775 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_input.png0000644000234000017500000003501512555672634023516 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_input_float_title.png0000644000234000017500000003723012555672634026105 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_input_moveable.png0000644000234000017500000004103612555672634025370 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_input_select_multiple.png0000644000234000017500000005301712555672634026772 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_plotting1.png0000644000234000017500000007261112555672634024303 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macro_progress.png0000644000234000017500000015530012555672634024223 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/macroserver_pool_server.png0000644000234000017500000370157412555672634026162 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/motor.png0000644000234000017500000223417112555672634022344 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/pm_pipeline.png0000644000234000017500000014645212555672634023507 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_pool_server.png0000644000234000017500000652757712555672634025257 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_screenshot.png0000644000234000017500000104066212555672634025051 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server.png0000644000234000017500000320271012555672634024176 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_controller.png0000644000234000017500000553767312555672634026466 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_empty.png0000644000234000017500000017131512555672634025417 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_icepap.png0000644000234000017500000452302512555672634025525 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_icepap_np200.png0000644000234000017500001050074712555672634026447 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_0D.png0000644000234000017500000206371212555672634026423 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_countertimer.png0000644000234000017500000226203412555672634030676 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_motor.png0000644000234000017500000256356712555672634027335 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_motor_read_position_flow.png0000644000234000017500000645755012555672634033301 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_motor_read_state_flow.png0000644000234000017500000671234312555672634032547 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_motor_write_position_flow.png0000644000234000017500001012343512555672634033503 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_internal_pseudomotor.png0000644000234000017500000561003112555672634030533 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/sardana_server_np200.png0000644000234000017500000433421112555672634025120 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/snapshot07.png0000644000234000017500000032753512555672634023217 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/snapshot10.png0000644000234000017500000061606512555672635023211 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/spock_snapshot01.png0000644000234000017500000025321312555672635024400 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/trend_a2scanc.png0000644000234000017500000007745212555672635023720 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/trend_ascanVSascanc.png0000644000234000017500000011564712555672635025114 0ustar zreszelaComputing00000000000000PNG  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"oMhome

  • project
  • download
  • documentation »
  • {% endblock %} {% block relbar1 %} {{ super() }} {% endblock %} {% block sidebar2 %} {{ super() }} {% endblock %} sardana-1.6.1/doc/source/devel/0000755000234000017500000000000012555673000020121 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/0000755000234000017500000000000012555673000020672 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/0000755000234000017500000000000012555673000022303 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/macroserver/0000755000234000017500000000000012555673000024633 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/macroserver/macros.rst0000644000234000017500000004037512555672635026677 0ustar zreszelaComputing00000000000000.. 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.addmaclib Loads a new macro library. .. warning:: Keep in mind that macros from the new library can override macros already present in the system. .. 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 .. warning:: Prior to the Sardana version 1.6.0 this macro was successfully reloading python libraries located in the MacroPath. The MacroPath is not a correct place to locate your python libraries. They may be successfully loaded on the MacroServer startup, but this can not be guaranteed. In order to use python libraries within your macro code, locate them in either of valid system PYTHONPATH or MacroServer's PythonPath property (of the host where MacroServer runs). In order to achieve the previous behavior, just configure the the same directory in both system PYTHONPATH (or MacroServer's PythonPath) and MacroPath. .. 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.6.1/doc/source/devel/api/sardana/macroserver/macroserver.rst0000644000234000017500000000063612555672635027737 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msbase.rst0000644000234000017500000000104712555672635026656 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/mscontainer.rst0000644000234000017500000000063612555672635027731 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msdoor.rst0000644000234000017500000000057312555672635026712 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msenvmanager.rst0000644000234000017500000000070712555672635030071 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msexception.rst0000644000234000017500000000061312555672635027740 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msmacromanager.rst0000644000234000017500000000076712555672635030410 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msmanager.rst0000644000234000017500000000067212555672635027361 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msmetamacro.rst0000644000234000017500000000136112555672635027713 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/msparameter.rst0000644000234000017500000000054312555672635027724 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver/mstypemanager.rst0000644000234000017500000000057012555672635030260 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/0000755000234000017500000000000012555673000023254 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/pool/controller.rst0000644000234000017500000000731312555672635026212 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/pool.rst0000644000234000017500000000064012555672635024774 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolacquisition.rst0000644000234000017500000000067612555672635027256 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolaction.rst0000644000234000017500000000221012555672635026165 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolbasechannel.rst0000644000234000017500000000066512555672635027167 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolbaseobject.rst0000644000234000017500000000065712555672635027026 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolcontainer.rst0000644000234000017500000000065012555672635026700 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolcontroller.rst0000644000234000017500000000172112555672635027101 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolcontrollermanager.rst0000644000234000017500000000072412555672635030436 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolcountertimer.rst0000644000234000017500000000070112555672635027433 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/pooldefs.rst0000644000234000017500000000033212555672635025634 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.pool.pooldefs :mod:`~sardana.pool.pooldefs` ============================= .. automodule:: sardana.pool.pooldefs .. rubric:: Constants .. autodata:: sardana.pool.pooldefs.ControllerAPI sardana-1.6.1/doc/source/devel/api/sardana/pool/poolelement.rst0000644000234000017500000000117212555672635026347 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolexception.rst0000644000234000017500000000162512555672635026717 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolexternal.rst0000644000234000017500000000145012555672635026537 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolgroupelement.rst0000644000234000017500000000122512555672635027423 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolinstrument.rst0000644000234000017500000000066112555672635027130 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolioregister.rst0000644000234000017500000000066312555672635027076 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmeasurementgroup.rst0000644000234000017500000000072312555672635030321 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmetacontroller.rst0000644000234000017500000000224712555672635027754 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmonitor.rst0000644000234000017500000000063712555672635026412 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmotion.rst0000644000234000017500000000127412555672635026226 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmotor.rst0000644000234000017500000000062112555672635026054 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmotorgroup.rst0000644000234000017500000000066412555672635027140 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolmoveable.rst0000644000234000017500000000064612555672635026515 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolobject.rst0000644000234000017500000000062312555672635026164 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolonedexpchannel.rst0000644000234000017500000000071012555672635027706 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolpseudocounter.rst0000644000234000017500000000071112555672635027613 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolpseudomotor.rst0000644000234000017500000000066512555672635027304 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/pooltwodexpchannel.rst0000644000234000017500000000070712555672635027744 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool/poolutil.rst0000644000234000017500000000025512555672635025674 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.pool.poolutil :mod:`~sardana.pool.poolutil` ========================================= .. automodule:: sardana.pool.poolutil .. rubric:: Classessardana-1.6.1/doc/source/devel/api/sardana/pool/poolzerodexpchannel.rst0000644000234000017500000000071112555672635030105 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/0000755000234000017500000000000012555673000023413 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/tango/core/0000755000234000017500000000000012555673000024343 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/tango/core/SardanaDevice.rst0000644000234000017500000000124412555672635027604 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/macroserver/0000755000234000017500000000000012555672777025767 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/tango/macroserver/test/0000755000234000017500000000000012555673000026722 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/tango/macroserver/test/macroexecutor.rst0000644000234000017500000000227312555672635032355 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.tango.macroserver.test.macroexecutor :mod:`~sardana.tango.macroserver.test.macroexecutor` ==================================================== .. automodule:: sardana.tango.macroserver.test.macroexecutor .. rubric:: Functions .. rubric:: Classes .. hlist:: :columns: 3 * :class:`BaseMacroExecutor` * :class:`MacroExecutorFactory` TangoAttrCb ----------- .. inheritance-diagram:: TangoAttrCb :parts: 1 .. autoclass:: TangoAttrCb :members: :undoc-members: TangoResultCb ------------- .. inheritance-diagram:: TangoResultCb :parts: 1 .. autoclass:: TangoResultCb :inherited-members: :members: :undoc-members: TangoLogCb ---------- .. inheritance-diagram:: TangoLogCb :parts: 1 .. autoclass:: TangoLogCb :inherited-members: :members: :undoc-members: TangoStatusCb ------------- .. inheritance-diagram:: TangoStatusCb :parts: 1 .. autoclass:: TangoStatusCb :inherited-members: :members: :undoc-members: TangoMacroExecutor ------------------ .. inheritance-diagram:: TangoMacroExecutor :parts: 1 .. autoclass:: TangoMacroExecutor :inherited-members: :members: :undoc-members: sardana-1.6.1/doc/source/devel/api/sardana/tango/pool/0000755000234000017500000000000012555673000024364 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/api/sardana/tango/pool/CTExpChannel.rst0000644000234000017500000000122112555672635027403 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/Controller.rst0000644000234000017500000000116112555672635027255 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/IORegister.rst0000644000234000017500000000117512555672635027153 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/Motor.rst0000644000234000017500000000106712555672635026237 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/OneDExpChannel.rst0000644000234000017500000000126212555672635027727 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/Pool.rst0000644000234000017500000000103012555672635026036 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/PoolDevice.rst0000644000234000017500000000304212555672635027163 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/PseudoCounter.rst0000644000234000017500000000123512555672635027733 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/PseudoMotor.rst0000644000234000017500000000120312555672635027407 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/TwoDExpChannel.rst0000644000234000017500000000126212555672635027757 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/pool/ZeroDExpChannel.rst0000644000234000017500000000127512555672635030131 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango/core.rst0000644000234000017500000000034412555672635025113 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.tango.core :mod:`~sardana.tango.core` ============================ .. automodule:: sardana.tango.core .. rubric:: Modules .. toctree:: :maxdepth: 1 SardanaDevice sardana-1.6.1/doc/source/devel/api/sardana/tango/macroserver.rst0000644000234000017500000000041112555672635026506 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.tango.macroserver :mod:`~sardana.tango.macroserver` ================================= .. automodule:: sardana.tango.macroserver .. rubric:: Modules .. toctree:: :maxdepth: 1 MacroExecutor sardana-1.6.1/doc/source/devel/api/sardana/tango/pool.rst0000644000234000017500000000111412555672635025130 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/macroserver.rst0000644000234000017500000000124212555672635025401 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/pool.rst0000644000234000017500000000340212555672635024022 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardana.rst0000644000234000017500000000110112555672635024454 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanaattribute.rst0000644000234000017500000000230312555672635026405 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanabase.rst0000644000234000017500000000117712555672635025324 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanacontainer.rst0000644000234000017500000000066612555672635026376 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanadefs.rst0000644000234000017500000000267312555672635025335 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanaevent.rst0000644000234000017500000000145712555672635025534 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanamanager.rst0000644000234000017500000000070312555672635026016 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanameta.rst0000644000234000017500000000114312555672635025331 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanamodulemanager.rst0000644000234000017500000000066512555672635027233 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/sardanavalue.rst0000644000234000017500000000061412555672635025521 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/sardana/tango.rst0000644000234000017500000000037612555672635024170 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.tango :mod:`~sardana.tango` ============================ .. automodule:: sardana.tango .. rubric:: Modules .. toctree:: :maxdepth: 1 core pool macroserver sardana-1.6.1/doc/source/devel/api/api_0D.rst0000644000234000017500000000104512555672635022535 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_1D.rst0000644000234000017500000000104112555672635022532 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_2D.rst0000644000234000017500000000104112555672635022533 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_IOR.rst0000644000234000017500000000077212555672635022731 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_controller.rst0000644000234000017500000000764012555672635024464 0ustar zreszelaComputing00000000000000 .. 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.6.1/doc/source/devel/api/api_countertimer.rst0000644000234000017500000000103312555672635025007 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_macro.rst0000644000234000017500000000074212555672635023376 0ustar zreszelaComputing00000000000000 .. 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.6.1/doc/source/devel/api/api_motor.rst0000644000234000017500000001645312555672635023443 0ustar zreszelaComputing00000000000000.. 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 writing a server extension to sardana. At the time of writing, 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. .. TODO: Once the "caption" bug is fixed (see the next TODO) move the following .. text to the figure caption The following diagram shows the motion state machine of a motor. 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 omitted. .. graphviz:: motion.dot :alt: Basic motion diagram .. TODO: Figure captions for figures using graphviz (:caption:) does not work .. for version 1.3.1 of Sphinx .. (see: https://github.com/sphinx-doc/sphinx/issues/1788) .. It will be fixed in next Sphinx release. .. :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 omitted sardana-1.6.1/doc/source/devel/api/api_pseudocounter.rst0000644000234000017500000000104712555672635025173 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_pseudomotor.rst0000644000234000017500000000101712555672635024651 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/api/api_sardana.rst0000644000234000017500000000107712555672635023710 0ustar zreszelaComputing00000000000000 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 Test API sardana-1.6.1/doc/source/devel/api/api_test.rst0000644000234000017500000000316612555672635023257 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.test .. _sardana-test-api: =================== Sardana test API =================== Macro test API ---------------------- .. automodule:: sardana.macroserver.macros.test .. rubric:: Classes .. hlist:: :columns: 3 * :class:`.BaseMacroExecutor` * :class:`.MacroExecutorFactory` * :class:`.BaseMacroTestCase` * :class:`.RunMacroTestCase` * :class:`.RunStopMacroTestCase` * :class:`.SarDemoEnv` Decorator --------- .. decorator:: macroTest .. autofunction:: macroTest BaseMacroExecutor ----------------- .. inheritance-diagram:: BaseMacroExecutor :parts: 1 .. autoclass:: BaseMacroExecutor :inherited-members: :members: :undoc-members: MacroExecutorFactory -------------------- .. inheritance-diagram:: MacroExecutorFactory :parts: 1 .. autoclass:: MacroExecutorFactory :inherited-members: :members: :undoc-members: BaseMacroTestCase ----------------- .. inheritance-diagram:: BaseMacroTestCase :parts: 1 .. autoclass:: BaseMacroTestCase :inherited-members: :members: :undoc-members: RunMacroTestCase ----------------- .. inheritance-diagram:: RunMacroTestCase :parts: 1 .. autoclass:: RunMacroTestCase :inherited-members: :members: :undoc-members: RunStopMacroTestCase --------------------- .. inheritance-diagram:: RunStopMacroTestCase :parts: 1 .. autoclass:: RunStopMacroTestCase :inherited-members: :members: :undoc-members: SarDemoEnv ---------- .. inheritance-diagram:: SarDemoEnv :parts: 1 .. autoclass:: SarDemoEnv :inherited-members: :members: :undoc-members: sardana-1.6.1/doc/source/devel/api/motion.dot0000644000234000017500000000331012555672635022721 0ustar zreszelaComputing00000000000000digraph "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.6.1/doc/source/devel/api/motion_complete.dot0000644000234000017500000000463112555672635024620 0ustar zreszelaComputing00000000000000digraph "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.6.1/doc/source/devel/api/tango_device_pool.rst0000644000234000017500000057056312555672635025141 0ustar zreszelaComputing00000000000000 ========================================== 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.6.1/doc/source/devel/api/tango_macroserver.rst0000644000234000017500000000223312555672635025161 0ustar zreszelaComputing00000000000000 ============== 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.6.1/doc/source/devel/examples/0000755000234000017500000000000012555673000021737 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/examples/ControllerTemplate.py0000644000234000017500000002073112555672635026150 0ustar zreszelaComputing00000000000000#!/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.sardana-controls.org/\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.6.1/doc/source/devel/examples/controller_examples.rst0000644000234000017500000000046212555672635026571 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/devel/examples/examples.rst0000644000234000017500000000026112555672635024323 0ustar zreszelaComputing00000000000000 .. _sardana-devel-examples: ========= Examples ========= .. toctree:: :maxdepth: 2 Macro examples Controller examples sardana-1.6.1/doc/source/devel/examples/macro_call_examples.rst0000644000234000017500000000051512555672635026501 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/devel/examples/macro_examples.rst0000644000234000017500000000046212555672635025507 0ustar zreszelaComputing00000000000000 .. _sardana-devel-macro-examples: ============== Macro examples ============== .. toctree:: :maxdepth: 2 Specifying macro parameters Calling sub-macros Plotting Asking user input sardana-1.6.1/doc/source/devel/examples/macro_input_examples.rst0000644000234000017500000000077612555672635026736 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/examples/macro_parameter_examples.rst0000644000234000017500000000054412555672635027550 0ustar zreszelaComputing00000000000000 .. _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.6.1/doc/source/devel/examples/macro_plotting_examples.rst0000644000234000017500000000067212555672635027432 0ustar zreszelaComputing00000000000000 .. _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.6.1/doc/source/devel/howto_controllers/0000755000234000017500000000000012555673000023707 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/howto_controllers/howto_0dcontroller.rst0000644000234000017500000000243112555672635030305 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_1dcontroller.rst0000644000234000017500000000243112555672635030306 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_2dcontroller.rst0000644000234000017500000000243112555672635030307 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_controller.rst0000644000234000017500000005231512555672635030067 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_countertimercontroller.rst0000644000234000017500000000674512555672635032536 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_ioregistercontroller.rst0000644000234000017500000000251212555672635032156 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_motorcontroller.rst0000644000234000017500000006242512555672635031153 0ustar zreszelaComputing00000000000000.. 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 writing 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 writing 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 writing 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.6.1/doc/source/devel/howto_controllers/howto_pseudocountercontroller.rst0000644000234000017500000000252412555672635032704 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/howto_pseudomotorcontroller.rst0000644000234000017500000000251212555672635032362 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/index.rst0000644000234000017500000000147712555672635025576 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/howto_controllers/sf_ct_ctrl.py0000644000234000017500000001007212555672635026420 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/doc/source/devel/howto_controllers/sf_motor_ctrl.py0000644000234000017500000001144112555672635027153 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/doc/source/devel/howto_controllers/springfieldlib.py0000644000234000017500000005253112555672635027301 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/doc/source/devel/howto_macros/0000755000234000017500000000000012555673000022625 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/howto_macros/index.rst0000644000234000017500000000037612555672635024511 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.macroserver.macro .. _sardana-macro-howto: ================ Writing macros ================ .. toctree:: :maxdepth: 2 General macro development Scan macro development sardana-1.6.1/doc/source/devel/howto_macros/macros_general.rst0000644000234000017500000013210612555672635026360 0ustar zreszelaComputing00000000000000.. highlight:: python :linenothreshold: 5 .. currentmodule:: sardana.macroserver.macro .. _sardana-macros-howto: =============== Writing 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 writing macro classes. Classes tend to scale better with the size of a program or library. By writing 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, writing 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 writing a sequencial procedure to run an experiment then you are probably better of writing 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 writing 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 (see :ref:`Using external python libraries `). 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 writing 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 writing, 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 writing 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_writing: 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 tuple composed from a macro object and the result of the :meth:`~Macro.prepare` method. 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""" ret = self.createMacro('ascan', moveable, '0', '100', '10', '0.2') # createMacro returns a tuple composed from a macro object # and the result of the Macro.prepare method my_scan, _ = ret self.runMacro(my_scan) print len(my_scan.data) A set of macro call examples can be found :ref:`here `. .. _sardana-macro-class-writing: Writing a macro class ---------------------- This chapter describes an advanced alternative to writing 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 writing 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-using-external-libraries: Using external python libraries ------------------------------- Macro libraries can use code e.g. call functions and instantiate classes defined by external python libraries. In order to import the external libraries inside the macro library, they must be available for the python interpreter running the Sardana/MacroServer server (see :ref:`Running server `). This could be achieved in two ways: - Adding the directory containing the external library to the *PythonPath* property of the MacroServer tango device (path separators can be ``\n`` or ``:``). - Adding the directory containing the external library to the *PYTHONPATH* :term:`OS` environment variable of the Sardana/MacroServer process. The external libraries can be reloaded at Sardana/MacroServer server runtime using the :class:`~sardana.macroserver.macros.expert.rellib` macro. .. _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.6.1/doc/source/devel/howto_macros/scan_framework.rst0000644000234000017500000002542412555672635026404 0ustar zreszelaComputing00000000000000 .. 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.6.1/doc/source/devel/howto_test/0000755000234000017500000000000012555673000022320 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/howto_test/tests/0000755000234000017500000000000012555673000023462 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/howto_test/tests/index.rst0000644000234000017500000000052012555672635025335 0ustar zreszelaComputing00000000000000 .. currentmodule:: sardana.test .. _sardana_list_test: ========================== Sardana Unit Test Examples ========================== .. toctree:: :maxdepth: 2 test ct test list test scan test wm sardanavalue parameter sardana-1.6.1/doc/source/devel/howto_test/tests/test_ct.rst0000644000234000017500000000064312555672635025701 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.macroserver.macros.test.test_ct .. _test_ct: :mod:`~sardana.macroserver.macros.test.test_ct` =============================================== .. automodule:: sardana.macroserver.macros.test.test_ct .. rubric:: Classes .. hlist:: :columns: 3 * :class:`CtTest` CtTest ------ .. inheritance-diagram:: CtTest :parts: 1 .. autoclass:: CtTest :members: :undoc-members: sardana-1.6.1/doc/source/devel/howto_test/tests/test_list.rst0000644000234000017500000000277212555672635026253 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.macroserver.macros.test.test_list .. _test_list: :mod:`~sardana.macroserver.macros.test.test_list` ================================================= .. automodule:: sardana.macroserver.macros.test.test_list .. rubric:: Classes .. hlist:: :columns: 3 * :class:`LsTest` * :class:`LsmTest` * :class:`LspmTest` * :class:`LsctrlTest` * :class:`LsctTest` * :class:`Ls0dTest` * :class:`Ls1dTest` * :class:`Ls2dTest` LsTest ------ .. inheritance-diagram:: LsTest :parts: 1 .. autoclass:: LsTest :inherited-members: :members: :undoc-members: LsmTest ------- .. inheritance-diagram:: LsmTest :parts: 1 .. autoclass:: LsmTest :members: :undoc-members: LspmTest -------- .. inheritance-diagram:: LspmTest :parts: 1 .. autoclass:: LspmTest :members: :undoc-members: LsctrlTest ---------- .. inheritance-diagram:: LsctrlTest :parts: 1 .. autoclass:: LsctrlTest :members: :undoc-members: LsctTest -------- .. inheritance-diagram:: LsctTest :parts: 1 .. autoclass:: LsctTest :members: :undoc-members: Ls0dTest -------- .. inheritance-diagram:: Ls0dTest :parts: 1 .. autoclass:: Ls0dTest :members: :undoc-members: Ls1dTest -------- .. inheritance-diagram:: Ls1dTest :parts: 1 .. autoclass:: Ls1dTest :members: :undoc-members: Ls2dTest -------- .. inheritance-diagram:: Ls2dTest :parts: 1 .. autoclass:: Ls2dTest :members: :undoc-members: sardana-1.6.1/doc/source/devel/howto_test/tests/test_parameter.rst0000644000234000017500000000066412555672635027256 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.spock.test.test_parameter .. _test_parameter: :mod:`~sardana.spock.test.test_parameter` ========================================= .. automodule:: sardana.spock.test.test_parameter .. rubric:: Classes .. hlist:: :columns: 3 * :class:`ParamTestCase` ParamTestCase ------------- .. inheritance-diagram:: ParamTestCase :parts: 1 .. autoclass:: ParamTestCase :members: :undoc-members: sardana-1.6.1/doc/source/devel/howto_test/tests/test_sardanavalue.rst0000644000234000017500000000071612555672635027742 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.test.test_sardanavalue .. _test_sardanavalue: :mod:`~sardana.test.test_sardanavalue` ====================================== .. automodule:: sardana.test.test_sardanavalue .. rubric:: Classes .. hlist:: :columns: 3 * :class:`SardanaValueTestCase` SardanaValueTestCase -------------------- .. inheritance-diagram:: SardanaValueTestCase :parts: 1 .. autoclass:: SardanaValueTestCase :members: :undoc-members: sardana-1.6.1/doc/source/devel/howto_test/tests/test_scan.rst0000644000234000017500000000243712555672635026222 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.macroserver.macros.test.test_scan .. _test_scan: :mod:`~sardana.macroserver.macros.test.test_scan` ================================================= .. automodule:: sardana.macroserver.macros.test.test_scan .. rubric:: Functions .. autofunction:: parsing_log_output .. rubric:: Classes .. hlist:: :columns: 3 * :class:`ANscanTest` * :class:`DNscanTest` * :class:`DNscancTest` * :class:`AscanTest` * :class:`DscanTest` * :class:`MeshTest` ANscanTest ---------- .. inheritance-diagram:: ANscanTest :parts: 1 .. autoclass:: ANscanTest :members: :undoc-members: DNscanTest ---------- .. inheritance-diagram:: DNscanTest :parts: 1 .. autoclass:: DNscanTest :members: :undoc-members: DNscancTest ----------- .. inheritance-diagram:: DNscancTest :parts: 1 .. autoclass:: DNscancTest :members: :undoc-members: AscanTest --------- .. inheritance-diagram:: AscanTest :parts: 1 .. autoclass:: AscanTest :members: :undoc-members: DscanTest --------- .. inheritance-diagram:: DscanTest :parts: 1 .. autoclass:: DscanTest :members: :undoc-members: MeshTest -------- .. inheritance-diagram:: MeshTest :parts: 1 .. autoclass:: MeshTest :members: :undoc-members: sardana-1.6.1/doc/source/devel/howto_test/tests/test_wm.rst0000644000234000017500000000105312555672635025712 0ustar zreszelaComputing00000000000000.. currentmodule:: sardana.macroserver.macros.test.test_wm .. _test_wm: :mod:`~sardana.macroserver.macros.test.test_wm` =============================================== .. automodule:: sardana.macroserver.macros.test.test_wm .. rubric:: Classes .. hlist:: :columns: 3 * :class:`WBase` * :class:`WmTest` WBase ----- .. inheritance-diagram:: WBase :parts: 1 .. autoclass:: WBase :members: :undoc-members: WmTest ------ .. inheritance-diagram:: WmTest :parts: 1 .. autoclass:: WmTest :members: :undoc-members: sardana-1.6.1/doc/source/devel/howto_test/index.rst0000644000234000017500000000055512555672635024203 0ustar zreszelaComputing00000000000000 .. currentmodule:: sardana.macroserver.macros.test .. _sardana-test-howto: =============== Sardana Testing =============== .. toctree:: :maxdepth: 2 General test documentation Run Sardana tests from command line Test-driven development example Sardana Unit Test examples sardana-1.6.1/doc/source/devel/howto_test/test_example.rst0000644000234000017500000003125112555672635025563 0ustar zreszelaComputing00000000000000 .. currentmodule:: sardana.test. .. _sardana-test-driven-devel-example: =============================== Test-driven development example =============================== In this section it is presented a practical example of how to code a macro by doing test-driven development thanks to the tools provided by the Sardana Test Framework. Consider that we want to write a new macro named "sqrtmac" for calculating the square root of an input number. The "sqrtmac" specifications are: 1. Its data must be given in the form {'in':x,'out':s} 2. Its output ('out') must be the square root of the input data ('in'). 3. Macro must raise an Exception of type ValueError if negative numbers are given as input. Test development ---------------- First we design the tests according to the specifications considering the features that are required for the macro. For doing so we will need some imports in order to be able to use the base classes and decorators. In this case the important base class is RunMacroTestCase, and we import testRun and testFail to be used as decorators:: """Tests for sqrt macro""" import numpy as np import unittest from sardana.macroserver.macros.test import RunMacroTestCase, testRun, testFail Now we will write a basic test, that will check the execution of the sqrtmac for a given input x = 12345.678. For doing so, we inherit from unittest and from RunMacroTestCase. In this implementation we will calculate in the test the sqrt of the input parameter and then, using assertEqual, we will verify that this value is equal to the output of the macro. The helper method macro_runs is used for executing the macro:: """Tests for a macro calculating the sqrt of an input number""" import numpy as np import unittest from sardana.macroserver.macros.test import RunMacroTestCase, testRun, testFail class sqrtmacTest(RunMacroTestCase, unittest.TestCase): """Test of sqrt macro. It verifies that macro sqrt can be executed. """ macro_name = "sqrtmac" def test_sqrtmac(self): macro_params = [str(x)] self.macro_runs(macro_params) data=self.macro_executor.getData() expected_output = 49 msg = 'Macro output does not equals the expected output' self.assertEqual(data['in'] ,float(macro_params[0]), msg) self.assertEqual(data['out'] ,expected_output, msg) Now, two new tests are added thanks to the decorator and the helper functions. In this case we will use the decorator @testRun. The same test case can be launched with different sets of parameters. One decorator is used for each set of parameters. One of the tests will run the sqrtmac macro for an input value of 9 and verify that the macro has been executed without problems. Another test added will run the sqrt for an input of 2.25 and will verify its input and output values against the expected values which we pass to the decorator. A wait_timeout of 5s will be given; this means, that if the test does not finish within 5 seconds, the current test will give an error and the following test will be executed:: """Tests for a macro calculating the sqrt of an input number""" import numpy as np import unittest from sardana.macroserver.macros.test import RunMacroTestCase, testRun, testFail @testRun(macro_params=['9']) @testRun(macro_params=['2.25'], data={'in':2.25,'out':1.5}, wait_timeout=5) class sqrtmacTest(RunMacroTestCase, unittest.TestCase): """Test of sqrt macro. It verifies that macro sqrt can be executed. """ macro_name = "sqrtmac" def test_sqrtmac(self): macro_params = [str(x)] self.macro_runs(macro_params) data=self.macro_executor.getData() expected_output = 49 msg = 'Macro output does not equals the expected output' self.assertEqual(data['in'] ,float(macro_params[0]), msg) self.assertEqual(data['out'] ,expected_output, msg) The following test implemented must check that the macro is raising an Exception if negative numbers are passed as input. The type of exception raised must be a ValueError. For developing this test we will use the decorator testFail which allows to test if a macro is raising an Exception before finishing its execution. The final implementation of our test file test_sqrt.py is as follows:: """Tests for a macro calculating the sqrt of an input number""" import numpy as np import unittest from sardana.macroserver.macros.test import RunMacroTestCase, testRun, testFail @testRun(macro_params=['9']) @testRun(macro_params=['2.25'], data={'in':2.25,'out':1.5}, wait_timeout=5) @testFail(macro_params=['-3.0'], exception=ValueError, wait_timeout=5) class sqrtmacTest(RunMacroTestCase, unittest.TestCase): """Test of sqrt macro. It verifies that macro sqrt can be executed. """ macro_name = "sqrtmac" def test_sqrtmac(self): macro_params = [str(x)] self.macro_runs(macro_params) data=self.macro_executor.getData() expected_output = 49 msg = 'Macro output does not equals the expected output' self.assertEqual(data['in'] ,float(macro_params[0]), msg) self.assertEqual(data['out'] ,expected_output, msg) Macro development ----------------- Thanks to the test that we have designed precedently we can now implement the macro and check if it is developed according to the specifications. We do a first implementation of the macro by calculating the square root of an input number. Then we will execute the test and analyze the results. The first implementation looks like this:: import numpy as np from sardana.macroserver.macro import Macro, Type class sqrtmac(Macro): """Macro sqrtmac""" param_def = [ [ "value", Type.Float, 9, "input value for which we want the square root"] ] result_def = [ [ "result", Type.Float, None, "square root of the input value"] ] def run (self, n): ret = np.sqrt(n) return ret An its ouput on the screen:: sardana/src/sardana/macroserver/macros/test> python -m unittest -v test_sqrtmac test_sqrtmac (test_sqrtmac.sqrtmacTest) ... ERROR test_sqrtmac_macro_fails (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_fails(macro_params=['-3.0'], exception=, wait_timeout=5) ... FAIL test_sqrtmac_macro_runs (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['2.25'], wait_timeout=5, data={'out': 1.5, 'in': 2.25}) ... ERROR test_sqrtmac_macro_runs_2 (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['9']) ... ok ====================================================================== ERROR: test_sqrtmac (test_sqrtmac.sqrtmacTest) ---------------------------------------------------------------------- Traceback (most recent call last): . . . desc = Exception: Macro 'sqrtmac' does not produce any data ====================================================================== ERROR: test_sqrtmac_macro_runs (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['2.25'], wait_timeout=5, data={'out': 1.5, 'in': 2.25}) ---------------------------------------------------------------------- Traceback (most recent call last): . . . desc = Exception: Macro 'sqrtmac' does not produce any data ====================================================================== FAIL: test_sqrtmac_macro_fails (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_fails(macro_params=['-3.0'], exception=, wait_timeout=5) ---------------------------------------------------------------------- Traceback (most recent call last): File "/siciliarep/tmp/mrosanes/workspace/GIT/projects/sardana/src/sardana/macroserver/macros/test/base.py", line 144, in newTest return helper(**helper_kwargs) File "/siciliarep/tmp/mrosanes/workspace/GIT/projects/sardana/src/sardana/macroserver/macros/test/base.py", line 271, in macro_fails self.assertEqual(state, 'exception', msg) AssertionError: Post-execution state should be "exception" (got "finish") ---------------------------------------------------------------------- Ran 4 tests in 0.977s FAILED (failures=1, errors=2) At this moment two tests are giving an error because 'sqrtmac' does not produce data, and one test is failing because the exception is not treat. The test that is giving 'Ok' is only testing that the macro can be executed. The second step will be to set the input and output data of the macro and execute the test again:: import numpy as np from sardana.macroserver.macro import Macro, Type class sqrtmac(Macro): """Macro sqrtmac""" param_def = [ [ "value", Type.Float, 9, "input value for which we want the square root"] ] result_def = [ [ "result", Type.Float, None, "square root of the input value"] ] def run (self, n): ret = np.sqrt(n) self.setData({'in':n,'out':ret}) return ret An its ouput on the screen:: sardana/macroserver/macros/test> python -m unittest -v test_sqrtmac test_sqrtmac (test_sqrtmac.sqrtmacTest) ... ok test_sqrtmac_macro_fails (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_fails(macro_params=['-3.0'], exception=, wait_timeout=5) ... FAIL test_sqrtmac_macro_runs (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['2.25'], wait_timeout=5, data={'out': 1.5, 'in': 2.25}) ... ok test_sqrtmac_macro_runs_2 (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['9']) ... ok ====================================================================== FAIL: test_sqrtmac_macro_fails (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_fails(macro_params=['-3.0'], exception=, wait_timeout=5) ---------------------------------------------------------------------- Traceback (most recent call last): File "/siciliarep/tmp/mrosanes/workspace/GIT/projects/sardana/src/sardana/macroserver/macros/test/base.py", line 142, in newTest return helper(**helper_kwargs) File "/siciliarep/tmp/mrosanes/workspace/GIT/projects/sardana/src/sardana/macroserver/macros/test/base.py", line 267, in macro_fails self.assertEqual(state, 'exception', msg) AssertionError: Post-execution state should be "exception" (got "finish") ---------------------------------------------------------------------- Ran 4 tests in 0.932s FAILED (failures=1) As we can see, the test_sqrtmac_macro_fails is Failing, because the case of negative numbers is still not suppported. The rest of tests that are testing the execution and the expected output values are OK. Finally we arrive to the complete implementation of the macro taking into account the Exception that should be raised if we enter a negative number as input parameter. For coding this macro test-driven development has been used:: import numpy as np from sardana.macroserver.macro import Macro, Type class sqrtmac(Macro): """Macro sqrtmac""" param_def = [ [ "value", Type.Float, 9, "input value for which we want the square root"] ] result_def = [ [ "result", Type.Float, None, "square root of the input value"] ] def run (self, n): if (n<0): raise ValueError("Negative numbers are not accepted.") ret = np.sqrt(n) self.setData({'in':n,'out':ret}) return ret An the output on the console after executing the test looks like this:: sardana/macroserver/macros/test> python -m unittest -v test_sqrtmac test_sqrtmac (test_sqrtmac.sqrtmacTest) ... ok test_sqrtmac_macro_fails (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_fails(macro_params=['-3.0'], exception=, wait_timeout=5) ... ok test_sqrtmac_macro_runs (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['2.25'], wait_timeout=5, data={'out': 1.5, 'in': 2.25}) ... ok test_sqrtmac_macro_runs_2 (test_sqrtmac.sqrtmacTest) Testing sqrtmac with macro_runs(macro_params=['9']) ... ok ---------------------------------------------------------------------- Ran 4 tests in 0.928s OK sardana-1.6.1/doc/source/devel/howto_test/test_general.rst0000644000234000017500000000716712555672635025556 0ustar zreszelaComputing00000000000000.. highlight:: python :linenothreshold: 5 .. currentmodule:: sardana.macroserver.macros.test .. _sardana-test-general-howto: =============== Sardana Testing =============== Sardana Test Framework ---------------------------- A testing framework allowing to test the Sardana features is included with the Sardana distribution. It is useful for test-driven development and it allows to find bugs in the code. The first implementation of the Framework is an outcome of the `Sardana Enhancement Proposal 5 (SEP5)`_. Ideally, whenever possible, bug reports should be accompanied by a test revealing the bug. The first tests implemented are focused on Unit Tests, but the same framework should be used for integration and system tests as well. The sardana.test module includes testsuite.py. This file provides an auto-discovering suite for all tests implemented in Sardana. The following are some key points to keep in mind when using this framework: - The Sardana Test Framework is based on :mod:`unittest` which should be imported from :mod:`taurus.external` in order to be compatible with all versions of python supported by Taurus. - all test-related code is contained in submodules named `test` which appear in any module of Sardana. - test-related code falls in one of these three categories: * Actual test code (classes that derive from unittest.TestCase) * Utility classes/functions (code to simplify development of test code) * Resources (accessory files required by some test). They are located in subdirectories named `res` situated inside the folders named `test`. For a more complete description of the conventions on how to write tests with the Sardana Testing Framework, please refer to the [SEP5](http://sourceforge.net/p/sardana/wiki/SEP5/). Sardana Test Framework for testing macros ----------------------------------------- Sardana Test Framework provides tools for testing macros. These tools come from sardana.macroserver.macros.test module Tests meant to be incorporated in the Sardana distribution must be portable. For this reason it is strongly encouraged to use only elements created by the sar_demo macro. Only in the case where this is not possible, one may create specific elements for a test; these elements must be removed at the end of the test execution (e.g. using the tearDown method). The module :mod:`sardana.macroserver.macros.test` provides utilities to simplify the tests for macro execution and macro stop. Macro test classes can inherit from :class:`.RunMacroTestCase`, :class:`.RunStopMacroTestCase` or :class:`.BaseMacroTestCase`. Another utility provided is the option to execute the same test with many different macro input parameters. This is done by decorating the test class with any of the decorators of the the macro tests family. This decorator is provided by :mod:`sardana.macroserver.macros.test`. **Specificities:** * Macros such as 'lsm' inherit from RunMacroTestCase as it is interesting to test if the macros can be executed. Helper methods ( such as :meth:`.RunMacroTestCase.macro_runs` ) can be overriden when programming new test cases. New helpers can be created as well. * Scan macros inherits from RunStopMacroTestCase as it is interesting to test both: if the macros can be executed and if they can be aborted. Links ----- For a more complete description of the conventions used when writing tests, see: http://sourceforge.net/p/sardana/wiki/SEP5/ For more information about unittest framework: http://docs.python.org/2/library/unittest.html .. _Sardana Enhancement Proposal 5 (SEP5): http://sourceforge.net/p/sardana/wiki/SEP5/ sardana-1.6.1/doc/source/devel/howto_test/test_run_commands.rst0000644000234000017500000000125512555672635026616 0ustar zreszelaComputing00000000000000 .. currentmodule:: sardana.test. .. _sardana-test-run-commands: =========================== Run tests from command line =========================== Run the whole Sardana test suite -------------------------------- Running the whole Sardana test suite from command line can be done by going to the Sardana directory: /sardana/test/. And executing: python testsuite.py Run a single test ----------------- Executing a single test from command line is done by doing: python -m unittest test_name Where test_name is the test module that has to be run. That can be done with more verbosity by indicating the option -v. python -m unittest -v test_name sardana-1.6.1/doc/source/devel/overview/0000755000234000017500000000000012555673000021767 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/devel/overview/index.rst0000644000234000017500000000102312555672635023641 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/devel/overview/overview.rst0000644000234000017500000001132612555672635024407 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/devel/overview/overview_0D.rst0000644000234000017500000000062012555672635024725 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_1D.rst0000644000234000017500000000061612555672635024733 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_2D.rst0000644000234000017500000000061612555672635024734 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_IOR.rst0000644000234000017500000000055712555672635025124 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_controller.rst0000644000234000017500000002151212555672635026650 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_countertimer.rst0000644000234000017500000000061112555672635027202 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_macroserver.rst0000644000234000017500000000654412555672635027025 0ustar zreszelaComputing00000000000000.. _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. Writing 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.6.1/doc/source/devel/overview/overview_motor.rst0000644000234000017500000000407612555672635025633 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/devel/overview/overview_pool.rst0000644000234000017500000000533112555672635025437 0ustar zreszelaComputing00000000000000 .. _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.6.1/doc/source/devel/overview/overview_pseudocounter.rst0000644000234000017500000000062112555672635027362 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/overview/overview_pseudomotor.rst0000644000234000017500000002353712555672635027056 0ustar zreszelaComputing00000000000000.. 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` Advanced topics --------------- Drift correction ~~~~~~~~~~~~~~~~ Pseudomotors which have siblings and are based on physical motors with an inaccurate or a finite precision positioning system could be affected by the drift effect. **Why does it happen?** Each move of a pseudomotor requires calculation of the physical motors positions in accordance with the current positions of its siblings. The consecutive movements of a pseudomotor can accumulate errors of the positioning system and cause drift of its siblings. **Who is affected?** * **Inaccurate positioning systems** which lead to a discrepancy between the write and the read position of the physical motors. In this case the physical motors must have a position sensor e.g. encoder but must not be configured in :term:`closed loop` (in some special cases, where the closed loop is not precise enough, the drift effect can be observed as well). This setup can lead to the situation where write and read values of the position attribute of the physical motors are different e.g. due to the loosing steps problems or the inaccurate *step_per_unit* calibration. * **Finite precision physical motors** e.g. :term:`stepper` is affected by the rounding error when moving to a position which does not translate into a discrete number of steps that must be commanded to the hardware. **How is it solved in Sardana?** Sardana implements the drift correction which use is optional but enabled by default for all pseudomotors. It is based on the use of the write value, instead of the read value, of the siblings' positions, together with the new desired position of the pseudomotor being moved, during the calculation of the physical positions. The write value of the pseudomotor's position gets updated at each move of the pseudomotor or any of the underneath motors. .. note:: Movements being stopped unexpectedly: abort by the user, over-travel limit or any other exceptional condition may cause considerable discrepancy in the motor's write and read positions. In the subsequent pseudomotor's move, Sardana will also correct this difference by using the write instead of read values. The drift correction is configurable with the *DriftCorrection* property either globally (on the Pool device level) or locally (on each PseudoMotor device level). **Example** Let's use the slit pseudomotor controller to visualize the drift effect. This controller comprises two pseudomotors: gap and offset, each of them based on the same two physical motors: right and left. In this example we will simulate the inaccurate positioning of the left motor (loosing of 0.002 unit every 1 unit move). *Drift correction disabled* #. Initial state: gap and offset are at positions 0 (gap totally closed and offset at the nominal position) .. sourcecode:: spock Door_lab_1 [1]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 0.000 0.000 0.000 0.000 Low Not specified Not specified Not specified Not specified #. Move gap to 1 .. sourcecode:: spock Door_lab_1 [2]: mv gap 1 The calculation of the physical motors' positions gives us 0.5 for both right and left (in accordance with the current offset of 0) .. sourcecode:: spock Door_lab_1 [3]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 0.500 0.498 0.998 0.001 Low Not specified Not specified Not specified Not specified We observe that the gap pseudomotor did not reach the desired position of 1 due to the left's positioning problem. Left's position write and read discrepancy of 0.002 causes that the gap reached only 0.998 and that the offset drifted to 0.001. #. Move gap to 2 .. sourcecode:: spock Door_lab_1 [4]: mv gap 2 The calculation of the physical motors' positions gives us 1.001 for right and 0.999 for left (in accordance with the current offset of 0.001). .. sourcecode:: spock Door_lab_1 [5]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 1.001 0.997 1.998 0.002 Low Not specified Not specified Not specified Not specified We observe that the gap pseudomotor did not reach the desired position of 2 due to the left's positioning problem. Left's position write and read discrepancy of 0.002 causes that the gap reached only 1.998 and that the offset drifted again by 0.001 and the total accumulated drift is 0.002. #. Move gap to 3 The calculation of the physical motors' positions gives us 1.502 for right and 1.498 for left (in accordance with the current offset of 0.002). .. sourcecode:: spock Door_lab_1 [6]: mv gap 3 Door_lab_1 [7]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 1.502 1.496 2.998 0.003 Low Not specified Not specified Not specified Not specified We observe that the gap pseudomotor did not reach the desired position of 3 due to the left's positioning problem. Left's position write and read discrepancy of 0.002 causes that the gap reached only 2.998 and that the offset drifted by 0.001 and the total accumulated drift is 0.003. .. figure:: /_static/drift_correction_disabled.png :align: center :width: 680 This sketch demonstrates the above example where offset drifted by 0.003. *Drift correction enabled* #. Initial state: gap and offset are at positions 0 (gap totally closed and offset at the nominal position) .. sourcecode:: spock Door_lab_1 [1]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 0.000 0.000 0.000 0.000 Low Not specified Not specified Not specified Not specified #. Move gap to 1 .. sourcecode:: spock Door_lab_1 [2]: mv gap 1 The calculation of the physical motors' positions gives us 0.5 for both right and left (in accordance with the **last set** offset of 0). .. sourcecode:: spock Door_lab_1 [3]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 0.500 0.498 0.998 0.001 Low Not specified Not specified Not specified Not specified We observe that the gap pseudomotor did not reach the desired position of 1 due to the left's positioning problem. Left's position write and read discrepancy of 0.002 causes that the gap reached only 0.998 and that the offset drifted to 0.001. #. Move gap to 2 .. sourcecode:: spock Door_lab_1 [4]: mv gap 2 The calculation of the physical motors' positions gives us 1 for right and 1 for left (in accordance to the **last set** offset 0). .. sourcecode:: spock Door_lab_1 [5]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 1.000 0.998 1.998 0.001 Low Not specified Not specified Not specified Not specified We observe that the gap pseudomotor did not reach the desired position of 2 due to the left's positioning problem. Left's position write and read discrepancy of 0.002 causes that the gap reached only 1.998 and that the offset drifted again by 0.001 but thanks to the drift correction is maintained at this value. #. Move gap to 3 .. sourcecode:: spock Door_lab_1 [6]: mv gap 3 The calculation of the physical motors' positions gives us 1.5 for right and 1.5 for left (in accordance to the **last set** offset of 0). .. sourcecode:: spock Door_lab_1 [7]: wm right left gap offset right left gap offset User High Not specified Not specified Not specified Not specified Current 1.500 1.498 2.998 0.001 Low Not specified Not specified Not specified Not specified We observe that the gap pseudomotor did not reach the desired position of 3 due to the left's positioning problem. Left's position write and read discrepancy of 0.002 causes that the gap reached only 2.998 and that the offset drifted again by 0.001 but thanks to the drift correction is maintained at this value. .. figure:: /_static/drift_correction_enabled.png :align: center :width: 680 This sketch demonstrates the above example where offset's drift was corrected. sardana-1.6.1/doc/source/devel/guide_coding.rst0000644000234000017500000001254612555672635023320 0ustar zreszelaComputing00000000000000.. _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 code 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 `_. Apart from directly contributing code, you can contribute to sardana in many ways, such as reporting bugs or proposing new features. In all cases you will probably need a sourceforge account and you are strongly encouragedto subscribe to the `sardana-devel and sardana-users mailing lists _`. The rest of this document will focus on how to contribute code. Cloning and forking sardana from Git ------------------------------------ You are welcome to clone the Sardana code from our main Git repository:: git clone git://git.code.sf.net/p/sardana/sardana.git sardana Code contributions (bug patches, new features) are welcome, but the review process/workflow for accepting new code is yet to be discussed. For the moment, use the sardana-devel mailing list for proposing patches. Note that you can also `fork the git repository in sourceforge `_ to get your own sourceforge-hosted clone of the sardana repository to which you will have full access. This will create a new git repository associated to your personal account in sourceforge, so that your changes can be easily shared and eventually merged into the official repository. The old SVN code repository --------------------------- After the release of Sardana 1.2 the Sardana code was migrated from its previous host in a SVN server to its current Git repository The old SVN repository is still `accessible for reference `_, but writing has been disabled and its contents are frozen as of 2013-07-31. For development, see the instructions above on cloning from Git 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 writing 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"s 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.6.1/doc/source/devel/guide_migration.rst0000644000234000017500000001732212555672635024043 0ustar zreszelaComputing00000000000000.. 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.6.1/doc/source/devel/index.rst0000644000234000017500000000056012555672635022000 0ustar zreszelaComputing00000000000000.. _sardana-developers-guide-index: ================= Developer's Guide ================= .. toctree:: :maxdepth: 2 Overview howto_macros/index howto_controllers/index howto_test/index API Migration guide Examples Development guidelines sardana-1.6.1/doc/source/sphinxext/0000755000234000017500000000000012555673000021054 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/sphinxext/ipython_console_highlighting.py0000644000234000017500000001215312555672636027407 0ustar zreszelaComputing00000000000000################################################################################ ## ## 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.6.1/doc/source/sphinxext/sardanaextension.py0000644000234000017500000001431312555672636025014 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/doc/source/sphinxext/spock_console_highlighting.py0000644000234000017500000001233612555672636027037 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/doc/source/users/0000755000234000017500000000000012555673000020163 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/users/getting_started/0000755000234000017500000000000012555673001023353 5ustar zreszelaComputing00000000000000sardana-1.6.1/doc/source/users/getting_started/index.rst0000644000234000017500000000056112555672636025233 0ustar zreszelaComputing00000000000000 .. _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.6.1/doc/source/users/getting_started/installing.rst0000644000234000017500000001072212555672636026270 0ustar zreszelaComputing00000000000000 .. _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 directly from Git ------------------------- Sometimes it is convenient to work directly from the git source without installing. To do so, you can clone sardana from our main git repository:: git clone git://git.code.sf.net/p/sardana/sardana.git sardana And then 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 .. tip:: If you plan to work normally from git without installing, you may want to add the `sardana/scripts` directory to your `PATH` variable and `sardana/src` to your `PYTHONPATH` variable. .. 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.6.1/doc/source/users/getting_started/running_cli.rst0000644000234000017500000001015512555672636026433 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/users/getting_started/running_server.rst0000644000234000017500000001150212555672636027167 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/users/faq.rst0000644000234000017500000002020312555672636021477 0ustar zreszelaComputing00000000000000 .. _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.6.1/doc/source/users/index.rst0000644000234000017500000000046312555672636022045 0ustar zreszelaComputing00000000000000.. _sardana-users-guide-index: ============ User's Guide ============ .. toctree:: :maxdepth: 2 Overview Getting started Spock Scans Standard macro catalog Screenshots FAQ sardana-1.6.1/doc/source/users/overview.rst0000644000234000017500000002621212555672636022604 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/users/scan.rst0000644000234000017500000001472312555672636021666 0ustar zreszelaComputing00000000000000 .. 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.6.1/doc/source/users/screenshots.rst0000644000234000017500000000633012555672636023275 0ustar zreszelaComputing00000000000000 .. 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.6.1/doc/source/users/spock.rst0000644000234000017500000004161712555672636022063 0ustar zreszelaComputing00000000000000 .. _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 the profile name as an option. If you use ipython version > 0.10 you can do it using **--profile** option:: spock --profile= Example:: marge@machine02:~$ spock --profile=D1 Otherwise (ipython version 0.10) you can do it using **-p** option:: 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.6.1/doc/source/users/standard_macro_catalog.rst0000644000234000017500000001163212555672636025411 0ustar zreszelaComputing00000000000000 .. _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.6.1/doc/source/conf.py0000644000234000017500000002617712555672635020353 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 # declare some useful absolute paths _this_dir = os.path.dirname(os.path.abspath(__file__)) _setup_dir = os.path.abspath(os.path.join(_this_dir, os.path.pardir, os.path.pardir)) _src_dir = os.path.join(_setup_dir, 'src') _mock_path = os.path.join(_setup_dir, 'doc', 'mock.zip') # append mock dir to the sys path (mocks will be used if needed) sys.path.append(_mock_path) # fix the mock so that the docs work with it mock_version = (999, 99, 9, 'mock', 0) import PyTango if not isinstance(PyTango.Release.version_info, tuple): PyTango.Release.version_info = mock_version # fix the mock so that the docs work with it import taurus if not isinstance(taurus.Release.version_info, tuple): taurus.Release.version_info = mock_version # fix the insertTest decorator so it always returns the decorated class, # otherwise the mocked version of the decorator returns mock objects, # this is causing problems with inheritance diagrams import taurus.test def insertTest(klass, *args, **kwargs): return klass taurus.test.insertTest = insertTest # Import code from src distribution sys.path.insert(0, _src_dir) import sardana # TODO: check if it is still necessary to fix_sardana_for_doc 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', ] try: import rst2pdf.pdfbuilder extensions.append('rst2pdf.pdfbuilder') except: pass # 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 = 'index' # 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 = os.path.join("_static", "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 = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # 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 = [ ('index', '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.esrf.fr/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/': None, 'http://www.taurus-scada.org' : None, 'http://pyqt.sourceforge.net/Docs/PyQt4/' : None, 'http://matplotlib.sourceforge.net/' : None, 'http://packages.python.org/guiqwt/' : None, } sardana-1.6.1/doc/source/docs.rst0000644000234000017500000000066012555672636020524 0ustar zreszelaComputing00000000000000 .. currentmodule:: sardana .. _docs: =============================== Sardana |version| Documentation =============================== Sardana is a software suite for Supervision, Control and Data Acquisition in scientific installations. .. toctree:: :maxdepth: 2 users/index devel/index Glossary To do History of changes * :ref:`genindex` * :ref:`modindex` * :ref:`search` sardana-1.6.1/doc/source/glossary.rst0000644000234000017500000005473212555672636021450 0ustar zreszelaComputing00000000000000 .. _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. closed loop A.k.a feedback loop, occurs when outputs of a system are routed back as inputs as part of a chain of cause-and-effect that forms a circuit or loop. In case of motion systems, closed loop positioning uses the position sensors e.g. encoders to measure the system's output. The measured signal is looped back to the control unit as input and is used to correct the moveable's position. 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`. stepper A stepper motor (or step motor) is a brushless DC electric motor that divides a full rotation into a number of equal steps. The motor's position can then be commanded to move and hold at one of these steps without any feedback sensor (an open-loop controller), as long as the motor is carefully sized to the application. 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.6.1/doc/source/index.rst0000644000234000017500000000333212555672636020702 0ustar zreszelaComputing00000000000000 Sardana Home Page ================= |image1| |image2| Sardana is a software suite for Supervision, Control and Data Acquisition in scientific installations. It aims to reduce cost and time of design, development and support of the control and data acquisition systems. Sardana development was started at the ALBA_ synchrotron and today is supported by a larger community which includes several other laboratories and individuals (ALBA_, DESY_, MaxIV_, Solaris_, ESRF_). You can download Sardana from PyPi_, check its Documentation_ or get support from its community and the latest code from the `project page `_. Projects related to Sardana --------------------------- - Sardana uses Taurus_ for control system access and user interfaces - Sardana is based on Tango_ - The command line interface for Sardana (Spock) is based on IPython_ .. |image1| image:: _static/gallery/gallery01.png :align: middle :height: 380 .. |image2| image:: _static/gallery/gallery02.png :align: middle :height: 380 .. toctree:: :hidden: Home Page Project Page Download from PyPI docs .. _ALBA: http://www.albasynchrotron.es .. _DESY: http://www.desy.de .. _MaxIV: http://www.maxiv.se/ .. _Solaris: http://www.synchrotron.uj.edu.pl/en_GB/ .. _ESRF: http://esrf.eu .. _LGPL: http://www.gnu.org/licenses/lgpl.html .. _PyPi: http://pypi.python.org/pypi/sardana .. _Documentation: http://sardana.readthedocs.org .. _Tango: http://www.tango-controls.org/ .. _Taurus: http://taurus-scada.org/ .. _IPython: http://ipython.org/ :Last Update: |today| :Release: |release| sardana-1.6.1/doc/source/revision.rst0000644000234000017500000000230512555672636021430 0ustar zreszelaComputing00000000000000.. _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.6.1/doc/source/todo.rst0000644000234000017500000000013612555672636020537 0ustar zreszelaComputing00000000000000 ========================== Documentation to be done ========================== .. todolist::sardana-1.6.1/doc/buildmock.py0000644000234000017500000003234512555672634020070 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################# ## ## This file is part of Taurus ## ## http://taurus-scada.org ## ## 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 . ## ########################################################################### # ---------------------------------------------------------------------------- # This class also borrows much code from the build_mock_qt.py script from # qarbon (http://qarbon.rtfd.org/) # # Copyright (c) 2013 European Synchrotron Radiation Facility, Grenoble, France # # ---------------------------------------------------------------------------- ''' Creates mocks of modules required by sardana. This is adapted from the buildmock module from taurus/doc .. todo:: Whenever taurus provides build mock utilities remove the copy&pasted code. See: https://sourceforge.net/p/tauruslib/tickets/169 ''' from __future__ import with_statement import os import sys import glob import re import inspect import shutil # Define templates _mock_module = """ class _MockMeta(type): def __getattr__(self, name): return _Mock() class _Mock(object): __metaclass__ = _MockMeta def __init__(self, *a, **kw): object.__init__(self) for k,v in kw.iteritems(): setattr(self, k, v) def __getattr__(*a, **kw): return _Mock() def __call__(*a, **kw): return _Mock() def __getitem__(*a, **kw): return _Mock() def __int__(*a, **kw): return 1 def __contains__(*a, **kw): return False def __len__(*a, **kw): return 1 def __iter__(*a, **kw): return iter([]) def __exit__(*a, **kw): return False def __complex__(*a, **kw): return 1j def __float__(*a, **kw): return 1.0 def __bool__(*a, **kw): return True def __nonzero__(*a, **kw): return True def __oct__(*a, **kw): return 1 def __hex__(*a, **kw): return 0x1 def __long__(*a, **kw): return long(1) def __index__(*a, **kw): return 1 """ module_init_template = """\ from __future__ import print_function from _mock import _Mock {imports} """ import_template = """{asname} = __import__('{fullname}', fromlist=['{name}'])""" mock_template = """{name} = _Mock()""" klass_template = """\ class {klass}({super_klass}): pass {members}""" function_template = """def {function}(*a,**k): return _Mock()""" member_template = """ {name} = {value!r}""" constant_template = """{name} = {value!r}""" specialfloats_template = """{name} = float('{value!r}')""" def abspath(*path): """A method to determine absolute path for a given relative path to the directory where this .py script is located""" this_dir = os.path.dirname(os.path.abspath(__file__)) return os.path.abspath(os.path.join(this_dir, *path)) def _import(name): __import__(name) return sys.modules[name] def _is_pseudo_enum(obj): if not isinstance(obj, int): return False try: int(repr(obj)) return False except: return True def _is_special_float(obj): if not isinstance(obj, float): return False return repr(obj) in ('inf', 'nan', '-inf') def _discard_element(name, exclude, include): if name in include: return False return name in exclude or name.startswith("__") def build_class(k_name, k, exclude=(), include=()): '''return the source text for a mock class based on a given class''' methods = [] members = [] for element_name in dir(k): if _discard_element(element_name, exclude, include): continue try: element = getattr(k, element_name) except AttributeError: continue if _is_special_float(element): members.append(specialfloats_template.format(name=element_name, value=element)) elif isinstance(element, (int, float, bool, str, unicode)): try: # make sure that the repr makes sense type(element)(repr(element)) except: # skip it (the _Mock.__getattr__ will deal with it) continue members.append(member_template.format(name=element_name, value=element)) members = "\n".join(members) klass_str = klass_template.format(klass=k_name, super_klass='_Mock', members=members) return klass_str def build_module(module_name, imports=(), out_prefix='mock', exclude=(), include=()): '''generate a mock package for a given module''' rel_dir = module_name.split(".") abs_dir = abspath(out_prefix, *rel_dir) if os.path.isdir(abs_dir): return os.makedirs(abs_dir) module = _import(module_name) fake_module_filename = os.path.join(abs_dir, "__init__.py") klasses = [] constants = [] mocks = [] imports = set([import_template.format(name=m, asname=m) for m in imports]) for element_name in sorted(dir(module)): if _discard_element(element_name, exclude, include): continue element = getattr(module, element_name) # internal imports (from the same package) if (inspect.ismodule(element) and element.__name__.split('.')[0] == module_name.split('.')[0]): # add the module to the imports set full_name = element.__name__ name = full_name.split('.')[-1] imports.add(import_template.format(fullname=full_name, name=name, asname=element_name)) # this comment refers to the above code: # when this code was copied from taurus/doc/buildmock the imports # were not done but pure mocks were used, it was warned that the # real imports may cause circular errors, but this was not the case # for mocks needed for sardana # in case of sardana, just mocking modules instead of importing them # was not enough e.g. # "from taurus.external import unittest" is creating a _Mock # unittest and than multiple inheritance using the unittest.TestCase # was not working due to the metaclass problems # TODO: when moving back this utils to taurus check if the circular # import errors are still present #mocks.append(mock_template.format(name=element_name)) # make sure that the module is built build_module(element.__name__, imports=(), out_prefix=out_prefix, exclude=exclude, include=include) # classes elif inspect.isclass(element): klasses.append(build_class(element_name, element, exclude=exclude, include=include)) # inf, and NaN constants elif _is_special_float(element): constants.append(specialfloats_template.format(name=element_name, value=element)) # enumerations-like objects elif (_is_pseudo_enum(element)): constants.append(mock_template.format(name=element_name)) # constants elif isinstance(element, (int, float, bool, str, unicode)): try: # make sure that the repr makes sense type(element)(repr(element)) except: # cannot write anything better than a mock constants.append(mock_template.format(name=element_name)) constants.append(constant_template.format(name=element_name, value=element)) # final catch-all: it covers modules, functions and other elements # that aren't caught by any of the above elif (element_name not in imports): mocks.append(mock_template.format(name=element_name)) imports = "\n".join(sorted(imports)) module_init = module_init_template.format(imports=imports) mocks = "\n\n".join(mocks) constants = "\n\n".join(constants) klasses = "\n\n".join(klasses) with open(fake_module_filename, "w") as f: f.write(module_init) f.write("\n\n") f.write(mocks) f.write("\n\n") f.write(constants) f.write("\n\n") f.write(klasses) f.write("\n\n") def guess_submodules_from_package(module_name, exclude=(), include=()): '''returns a list of submodule names found in a given package name. If module_name is not implemented as a package, it returns an empty list''' if module_name in exclude: return [] module = _import(module_name) try: modulefile = inspect.getfile(module) except TypeError: return [] if not (modulefile.endswith('__init__.py') or modulefile.endswith('__init__.pyc') ): return [] pkgdir, _ = os.path.split(modulefile) # explore pkgdir to find subdirs with __init__.py files g = glob.glob(os.path.join(pkgdir, '*', '__init__.py')) names = [re.findall(r".+\/(.*)\/__init__.py", s)[0] for s in g] # explore pkgdir to find .py files g = glob.glob(os.path.join(pkgdir, '*.py')) names += [re.findall(r".+\/(.*).py", s)[0] for s in g] # explore pkgdir to find .pyc files g = glob.glob(os.path.join(pkgdir, '*.pyc')) names += [re.findall(r".+\/(.*).pyc", s)[0] for s in g] # explore pkgdir to find .so files g = glob.glob(os.path.join(pkgdir, '*.so')) names += [re.findall(r".+\/(.*).so", s)[0] for s in g] # build list with full module names and filter out non-importable submodules full_module_names = [] for sm_name in names: name = '.'.join((module_name, sm_name)) # skip __main__ and __init__, etc and excluded (unless included) if ( name not in include and (name in exclude or sm_name.startswith('__')) ): continue # check if the module is indeed importable try: print name _import(name) full_module_names.append(name) except: print '!' pass return full_module_names def build_full_module(module_name, exclude=(), include=(), out_prefix='mock'): '''build a full mocked package (modules and submodules, recursively) for the given module''' rel_dir = module_name.split(".") abs_dir = abspath(out_prefix, *rel_dir) if os.path.isdir(abs_dir): shutil.rmtree(abs_dir) build_module(module_name, imports=(), exclude=exclude, include=include, out_prefix=out_prefix) #recursive call for submodules for name in guess_submodules_from_package(module_name, exclude=exclude): build_full_module(name, exclude=exclude, include=include, out_prefix=out_prefix) def _zipdir(basedir, archivename): '''function to zip directories. Adapted from: http://stackoverflow.com/questions/296499 ''' from zipfile import ZipFile, ZIP_DEFLATED from contextlib import closing assert os.path.isdir(basedir) with closing(ZipFile(archivename, "w", ZIP_DEFLATED)) as z: for root, dirs, files in os.walk(basedir): #NOTE: ignore empty directories for fn in files: absfn = os.path.join(root, fn) zfn = absfn[len(basedir)+len(os.sep):] #XXX: relative path z.write(absfn, zfn) def build_mocks_for_sardana(output='mock.zip'): '''builds mocks for the packages required by taurus. The mocks are written into the given output directory (or a zip file if output ends with ".zip") ''' import sys import tempfile if output.endswith('.zip'): zfile, outdir = output, tempfile.mkdtemp() else: zfile, outdir = None, output module_names = ['PyTango', 'PyMca', 'numpy', 'PyQt4', 'sip', 'lxml', 'guidata', 'guiqwt', 'spyderlib', 'IPython', 'ply', 'taurus'] exclude = ['exec', 'None', 'object', 'spyderlib.scientific_startup', 'spyderlib.spyder', 'spyderlib.widgets.externalshell.start_ipython_kernel'] include = ['__version__'] _mock_filename = os.path.join(outdir, '_mock.py') with open(_mock_filename, "w") as f: f.write(_mock_module) for module_name in module_names: build_full_module(module_name, exclude=exclude, include=include, out_prefix=outdir) if zfile: _zipdir(outdir, zfile) # compress the dir into the zip file shutil.rmtree(outdir) # delete the dir print '\nMocks written in %s' % output if __name__ == "__main__": build_mocks_for_sardana()sardana-1.6.1/doc/logo.bmp0000644000234000017500000035043612555672634017211 0ustar zreszelaComputing00000000000000BM6(  ɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾɾƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺƺʿƺƺƺƺƺƺȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼȼʿŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹʿŹŹŹŹŹǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻǻȼ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷Ǽ÷÷÷÷÷ǼŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹŹ÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷ĸŸµµµµµµµµµµµµµµµµµµµµµµµµµпппппппппппппппппппппппппϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽöϽϽϽƺппппппппппппппппппппппппμμμμμμμμμμμμμμμμμμμμμνμμŹϽϽϽϽɿϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺμμμμμμμμμμμμμμμμμμμμμμμ̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸̸Ѿ̸̸Ǽͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺ˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹ʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶ˷˷ͺ˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷˷ȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴȴʷɾʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶʶ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.6.1/doc/mock.zip0000644000234000017500001057457312555672634017241 0ustar zreszelaComputing00000000000000PK]SF _mock.pyn0 }STUpnv(6Jt<=h@\Og29&֤5xʷBÄ؅[!T eIJ^Eio]Hk GeҨ]-s"wNL#kϵ`Obaة̮;i%8LZϒTNF?qe`Crbzp?1#,AI> ._=Y+PKSFxaIPython/__init__.py}1o w 6'Rek U *5[U!S Q{& v{}e7Ιl;cuVj$U(.>՚n䁭`p(7W6\IrԾZȂ)j2`SR#}A5Be8rR(D00SMq o(I(R :h+vԾCs7:S|(˰D\Q3#`y`?M ZQ#{+Sa71@Kk4;r[M:`̷nRrsg,yt8cV%<%c]d-#]`# $ MC#BXE 5mgko42?PKSF;g`IPython/kernel/__init__.pyn0E *iWU=q qگsg4+ޓ'(7UHevjYRʰs`?(CP*ەFoj.Z=ovêO?7+F^Djӑc*mB)v WhBEl18KMMDZT4ĨH)RSQGQMBܬ[jH'Mw{|ˏ,kz|f,HERͅ>AG\LBf\0PATN㲾R)-ƹk}gfW+_AR 0^@ ! 卑"7yPKSF0l i"IPython/kernel/manager/__init__.pySN0 +r\'$chb$ۙ%NI܉dnM{/N[e#M@Qu y zl,gӅ{zV;< 6>hMn[HVzɦ5qŰbأ6K!ӽ,3bTSn:*SNPz^ ~lO[xoǢKh莛sGf*Ob1yf='K >^-T( B%aH4(h,_=f6!7 jfz!ӂq᫊J.jvtΞq;K[W&?t_L3٩UgV PKSFpI#IPython/kernel/launcher/__init__.pyU;0D{bˤ)7XcZC۳$Br{f1 Y# rmFU-EaV 3)Y*>ZS;eS(FsԾA:6mUxJOeӂ2>jm2R`,< PKSF$IPython/kernel/restarter/__init__.pyN1 <‚:WbT@NO9*o9N*a,*xJCF cͬr,|5HX ny4H;0Zfߙ"<Dg╮jdeB,ݖfZ_Z?^ ~wWҁ'Eo+%Y6J\MRʜcNt}PKSF|0Y/m!IPython/kernel/client/__init__.pyQMK1W"BhQhC6;;mj=K7o{v!:;Pց,~XB Oޚ;_D}~\ ^Ny7>{!en(qg ˌ0s2-oL}Jl֭CUS ehU+qh6A:`Jc 6X^)5't)Ga9Z1g:+ J AJt>m=dg4)|IMMt4g 0~ݢ1<2~ .lv_\]Ω>PKSFYo-IPython/kernel/multikernelmanager/__init__.pyRAN0 u Hp@ Q:lbA,'m("؊O1>KN`q%$)(9A&GVdw fW 5[OV 1(A0䉛ee3~Ǘe 7#=SZw*g#6ĩ, YsN/bhgpN 2 GHev]@gn\̽^,ϯq"LۜlV3uegɶgGB/a𶸘1C j6`9JMU5u5|Pct,Z3dy2yIHBAv 4ԄNV j~G_8859tX@U׶J}PKSF@T< #IPython/kernel/blocking/__init__.py 0 }ܶ]$"xfi]Y6;ydn/Ħ.$.11KJ]$e 6/(ǁ H N'$iۻѣjowFi LTh? ɹ^PKSFA,IPython/kernel/blocking/channels/__init__.pyN0 }  qeH& ZN:bq];r˗/MN 6J&DO٠ϬTkUsTM5]BpEpU-Y'kzw=pf E}2xLGz;BK㛫i鹼Ζ8y% "N'Z\J.RU0PKSFE.f*IPython/kernel/blocking/client/__init__.pyAKA +r^D"нq' f3lF[Peo^JV !c.ca5g I5,i%Ni*Iu}FM_(&DV6ߔLMǺB˘|LHB.ɥRBVʲ1.Ygew;qU0"^cftR-n#8)-FeG6 *##M;&# ^Qfb]?d"Y] v?CԶ!cҤ1+}y.$pvh}Șln_8PKSF@w,IPython/kernel/inprocess/manager/__init__.pyN@VƓ\Y7 ,evڸoؤ\y"0z Zq[ 58n[j{y"O4_%[Rˎ!oװ!|YBJiNqt۬+R~KF)? dv8aOnn~ M: 2QpR+EJPKSFRRx'+IPython/kernel/inprocess/client/__init__.pyMk0 TaͥaֻPe1s`Y+ )|1!0.K`0(fEl+5=j>cJ} Rm/jS3*@y1B|AQTXŸ=yz~ IXb@چVKl p:/fBi1 ou[G L_(n"h{b_pPKSFgDd6H*IPython/kernel/inprocess/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFD׾e=IPython/kernel/inprocess/tests/test_kernelmanager/__init__.py @ yM xQD /KmVfn&bƸ^DƠoYTZ|dp#L iM e`sMPssS5|dċ v C?pi6+-~SfIno}ېi.޹(_cb1["7xk; | PKSFεx+IPython/kernel/inprocess/socket/__init__.pyu1O1 w om7$JH -nЈKr$Ήq89/9"oڊa}.} IMNCNG*f S&xr ~u;~^Kqi1{#חA6UoϤzwMfR7:ii=>Z?Ln@IY )niEKPKSF֍-IPython/kernel/inprocess/ipkernel/__init__.py?O1 ڮ R N, k qNqr=@,Q^vK. mLٴqVmv Ѿ-dl(ˏ^$2XOǪM92=%󃸸iUqaxP3t M jhN>EK"+6ힼ3EM*w MkJĻM2?d힠$J=?a?xd2_M=n?wPKSF)j-IPython/kernel/inprocess/blocking/__init__.py 0EFWEDCSNJV޴ꪈHlZ1DZ5uZGR*U +V77L4b=,9$و oF T>WmbFl!;g+FJ?# GXc!_V7oIpꀷ;̌j8LPKSF{2ϟ;!IPython/kernel/ioloop/__init__.py 0 }ܶ=PQ2:-kf޺9E`n < lH,iRPDy]n:ahc E{ɕB=ՖQl$ͩXs$,^g\)AGjbF~ PKSFN`)IPython/kernel/ioloop/manager/__init__.py 0 }ܶQo^JdOo7 1u$8tL,itՏ9DvIP*%ܲcR31bdՆC9HLtYn1 C,PRZ/ b\b<ʾ'?PKSF*+IPython/kernel/ioloop/restarter/__init__.pyA 1 E=Ev3sJ-)ۤ/A8ib., E"iOkd2a2*c_2uOYB򒱏uS w&9gg!e_54:ZROwP?crŠq/vX%X7^ ^[_ҷ.Z Hnsq<+]Rznta2\ o8VK yPKSF"˞IPython/kernel/zmq/__init__.pyAn =`4&Ml8@7(cfQ9YNꀩ4 i5~_|W4ֆyX0iPc >\-VE3|*]u2OKpv=P׶e[[9e~J"xr:X.f)EHxp+:%lj, "/@ ۲r!~dq HƟ ~_nSqy%ZPKSFpÚ(IPython/kernel/zmq/heartbeat/__init__.py1@ ݀ň11 ٛJ]YV ^.x c D0vaƱa{-]p^l)Ed?[[VKYTZ$?w{[ $|(e< Zgc@ 9Dsp 0#Üh0"r uٱ,TPa9IO`ϵus~_1qW~,j3_Lᄜ;@bDG=*P-BG*]嬆?ݦݰ- õ9u>-s]g~aޅh$ɿ!h{5{+5StrOKJ)oPKSF S'IPython/kernel/zmq/iostream/__init__.pyeMK1TD,+VO"Cf`L&bNZ֮zJIr>c k|DvHce| &X؞Jo@">nwڤO:etSug1QHAN,3j|*"5{ej:gM}˛c{/Fیg@K^79 `'3Na tX\ҫ/v]ʡlPumPQ~PKSF(÷*IPython/kernel/zmq/displayhook/__init__.py=O0 l`ucϽFQV8@D(+2xnԱ0C>D$kvpDgOg5] Bϸr[9X qg PY4 Wgwg9=xqPKSFK4"IPython/kernel/zmq/log/__init__.pyuM0 {EoϋCM" fўo.E1U "`\ѐnJYҟ9nor'B r-w'Md/2R#>Ac(G[3|4E_sRV$hϾZGMAnE _~H2ȏ tUGƛ݈f,tѾPk(/MWieْ ; uU$yh1;?=yr!gΎt$* ΨLUR^E1|,Bɮ ߨf zZY©<92,aw5[ڥ]0ġBM.5BPF𣑱 %y$)- I\m.I,hlАYOKai'P&ǶSǡΡbQrJ2$r2oszߠ?|vŇNl{Б8E$ق,]ܹ-\k ԑ ;9QdOA ;*yb6cNvq7.A*Ψs*ieplS=;qetDwʁ;\ZLn_tD_TqQxGk7]HQ)C-8Ak I0m%J@MT1>hK̈ٹ Bwx9o9-o5^7mOkӞI.t,;(7/fOkѿK-5d.d2y1۰T_z,\(gԣuNPKSFgDd6H$IPython/kernel/zmq/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF̡1IPython/kernel/zmq/tests/test_session/__init__.pyQj0Wf)ɡKS=RSKY"z8Z~}WN ?ОyRi(0n1!m2\. kDbWRʲx>|>ѣܥ"$Fk(mߊ|_@Rrbpi9c Zx"|_Hir2@e>k0^9t,aNFc`Y6,t/6殪۹Ps})2UM*PKSF2G'IPython/kernel/zmq/ipkernel/__init__.pyMo0 9nzQ[ .AiG,j9[z 2뀭NH)L18bi2zjQ YW[H\1!'*/>wCNdl\GY{(XPNp4X-CFYVA%7Sz`-)~=ȃNSwujkjbL$h";4˙);S8 ɴ0ҰUt19ϊTN#4'SM4,v,V(޸n5/^gBxǸ%~\NMjӤǚwFu \_.XR")4%|}Z'>+;,HE*Zoz.v0o:^::{הMn9@|ߋŲ uJh?MH0A@APKSF:&IPython/kernel/zmq/datapub/__init__.pyn @wܡRMt*[mR Vӯّ#VUĻq1tΜ#h!,z(5.䈆%([hUꒂt6P!'" /cJ)ʔ6>){UTcv Lr(Z_`io˛ MX:-sO]7+ϔ fB_v4AA GzxǷLtRPKSFP<7(IPython/kernel/zmq/serialize/__init__.py}QJ1+)H -]t1X Eƛ'̔ys *Q u] Y+I;lh2`u^唝PWUONi߮QFG=U?1AAHMR C":0 hrek!{B+ 2 k^lAxoz0F-"b-Dp7[/]n=>)cE><;=11_z\3}_}PKSFv&IPython/kernel/zmq/session/__init__.pyT]o0}WV&tZ'H!dI}i0-62B*Þ{pc)2q\BRr!5%Pj&UC`YL+W G7'f:a~ 9eJ_}!qlYL]C4"G3> EDSјns>RٗQ4e e_ZPcsK)ڔ5Q딭ZPFf4kJK9 9kBHƓ&KѺMptMh"HRLRFT{u*NIN<07gZ+-xyΨj C/ 5S3t܉`mY|u. 18*[A!S曣RP<`/J$iAs#D%.kxKRE;bhdJNÍa9j(h{jŊ>l^T@Vv_z'.%aڕRtFRW?i%%KmYϰPKSFJG)IPython/kernel/zmq/eventloops/__init__.pym1 0ڂtr:8:"G m=_oZ u|{ b38Ԉ\ATKfY96oU/D̳er$vj-EYʷjvYO [怆 m0Æ߰?Fqv:cT,=#_JTPKSFgDd6H"IPython/kernel/zmq/gui/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFi+IPython/kernel/zmq/gui/gtkembed/__init__.pyM10 {%|  ff]Dn=["!qLGQxW`>bvUJ7lc)7LW]n1PKSFZ $IPython/kernel/zmq/embed/__init__.pyUM @ 9Evm p# )-@xy/ ZD(XUrm]JR7@7)NiadgW]kdŻ~'|t~XZ͜XͲASİAΆfKlr3PKSF?i2 IPython/core/__init__.py͎ }"ij`JWElb`.6o ·sdL|7^ᾹaUqWmr P{h0>Ra  {> _޾|۷zaZK12 $QjT-xns02)I+v:(6!P3LSRkfV-$7@zjU-7gT(}Ceaj'Vzʼn߶yizEX-ٓDJgİ`;7 zapza9Z ?Ph=F`8u:"Aq\Y O꥜ug´INYZU-0+sUZUrfSUZUh-!xJ =;B 7{Hs)XP_ n=ՠ0-#zskoRp~ej<= óa,>J3rUj1A((!uZ#h6'_oC&DJ?8vHwd 蝖K^IHS9߭U;'V>)!S[Tr Y㎕VI!vaREr<VN+ V'MGXizžlPmܾ?PKSF(IPython/core/magic_arguments/__init__.pyOK0 @؃^ă046LQiVy7o^S(#2.xɪ_r;PUCDN9h㻼7!h3W_)˚$zQwUɂ)loN4i@3k -xtsŔF wwY)fZʷҏ1&` .;wdm`"Cns_+ר5t}>1n-h%$L/KN-^`PKSFwIPython/core/page/__init__.py}N0{?$t =?TɭHD9̮v$SBM.$:&򒩷B~I`pR)C}qHex$KA;{I+~qޤt(h&DLXvm9ĵFĀ8Xm$[K09f5 eV[h&= ?\;u=EXy#ݚd=򃏆Y??]Í:f|=O:v)/PKSFbJ#IPython/core/splitinput/__init__.pyU 0DM,%lBvsߛVzy)`%;DC!Ŭ&eb-[0V\@64ʛ!py_V3˔'[w(б]"OP'ݶmӊHʟ)l#9فخ;1PKSFk(#IPython/core/formatters/__init__.pySMo0 W a5EH0Ldɐl=zjuRQki&DM8 E5`~ !Dd-DM=lq%7p6w8B@a^mqb K.N]: [oM(QSЉ)~-q7C8Bʆ#) ZGzE־WA!)#x4/*5=SMG+n#n|]Nձhp?сzDj5ݠ6`Qo0&O=Sb[?uMoG|ˣأ`SOcߍx(>t[|x$@26Og=x'Aq-e -ѓ,FDG~+2j|rPKSF =!IPython/core/excolors/__init__.pyuQO mo&8^]b&"M4fۿr9mnƌd 1Ɩ맵pQUڈ ?s9VF3$ &NBBWQH-ήMlxmcƷ/sGr3'ze]l1bE@=ctJ­-*6*\"bByJm G x'DJPQ@N11`QbCQlFQiJ0.BiO*0*8{V(]Pe PKSF\z} IPython/core/payload/__init__.pye0 D|/ 1R?LH*Ďѿ]R)}5zTAUbRF.T7B"h;p<9u_J~;$  /=Nct5 >fd\_PKSFu!IPython/core/autocall/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\ZYXZViťPREE% n9ũ0M )*k $*PKSFIPython/core/macro/__init__.pyM0>EB,.ƄAFzI[e< F 0Ln2=B+6\:J渒hXZByÔS@DJ&M-5r+ٷ!T'U@^YY}FڦXoZ\QfT X{ӟPKSF:9uV$IPython/core/application/__init__.pyT_K0[7}a THҴ=Brvl w yEU0R 8x $|G:M.gHT,K2kXrЉrnG*-4QYH{< ͵ӂ$7PQ9chǜTxnUC"]J.B0t4$3{Um(]{IJ"=pV(f 9ML]$<,>`bl4,D;tf&W%le.!(y-VR%vl6ʥmCsk.ec#@Ӱl?ESqfodth+cC*5&{5Ӌ1h]geV'ĿCPKSFW#IPython/core/profileapp/__init__.pyXk0_qtlf+e}GXT$';}8-}Mđ~ߝ.)!ֵgAcrr'^}n˄^+fyVJ),{?37.M*BS[ ٚE.[K!=HP{@2V7eP|MZL2/Y+Zb ނ^^nC@t( 7pkaRrLZ _=l1ڏe(iÒv̈́׾8ieE [pC5(iU뚩APy}0yoݽf\Ng$ϝ6MSTA\_LCW(Vs2c'4nw g hPd9v n k<ˑJu9d gbZKijC F;+KSe;BX:ݚ9TyJx1#) )f /K'f"OR0dv%?[Ezv=w`:lz?2E=kN>8Щnsn\r|Kg-(YtP q,גK^t%27ŋ_菤Gh"_Zbf ܶ☎.,7ƽc(ɒY FPkZ;I"_pl!ߢ*H/Xci-5wنɖ*(u 98};;TRx^)z2f͍h<vU dMebMJ@ sj24i?z_鹹9t&ѿu1rpk RBпPKSFjIPython/core/alias/__init__.pyj1 D ݒB Rz4 ]9FwRPfތoqD_K5FRDP$OOpFTCA B3vE[ƵZw(cNAJǚ5h=W2]k@9S[6nolwi!}DJgy\5 >(T-㥯?PKSFlJ˳1$IPython/core/displayhook/__init__.pyuA 0Es٥x+]Bp/bit0)DME|YslEz}$rFI9)Rz;IxB)@I)y?qb JCW0@\JtB[=d}aogInX)kN@$binxq!PKSF<)IPython/core/interactiveshell/__init__.pyWMo6WR8`{Hk k/@Q45 S񪿾C}Ք%)Л<[E6`LόgۊU8BlZ=#i3]tct\B+r7Rr؄숔@ 7-'PR8i();)֭id Q0J ?rR*)'^Sz5FnBOc+$FZJ3ߑzʟ>F)u0)=ԎZN*ӡoDJт$1MUMС dX iLєLMJM]b 8ftRrȁ)֢=h  ߁g9l9؈?X.mo24eJFЛMHN.$oH'>tڻ&%5ә4u64- QxH/;EJz(N+ $aAz)W@MZߖ ?O PܹNIc\U׿β,apM&1ʹKwmh\#dEU}Ro5W=نL w r܁V>P/.ˬG̃tFj+?Nx@y rEW-/4fd=+pnbh9UTP1"%.Z0XƅEPך2GnYY[jgxGKrƁ윷؇s-WoХiYuZc:w+.ӰOXWϷ9V| 6ޝgM &?fQ(T *AQ&N}]Zb=)Fa/X ,㭆_h~yG3WPw+(zh7.em4p?D b y+fk5=]K:ɇEw+UD?PKSF 'P  IPython/core/display/__init__.pyMo0+, D)~ڦ]e6 1ƲfwPϼ3 ԄҢDԺ1H UEŠtе{YjzZ@I{ eOP z h9gGTJ&Ms~l:h ={fCmTKЅΌ 6>OcAN"N [EZR?Q|b]m:g]Qd]~;?13ʺk)R_ ~DfլtuOuՉwc~F'qg$Ş_3f70#aPKSFW&#IPython/core/displaypub/__init__.pye 0=ŃлȒ.ِl}{E83|&MFDE r[ Q37U{Xv]lZϖ4"{UY-R̾W i6ծopuߣ|"t<Pʕb^sZf- IfTcЙҦ)Jsϸ@f#<:dz3k3Dڤ 1PPkQյ< '4υ+8NeVCVG0J72gmޣq,XhՋ8\+&QB_0>ŝKI !?͒Ԕ䞯aIrxXd ,sW HER瑺B 4r"X^A"w-ʹ /y#Ad߀5O­DpC"'lw&}Bihfl (dhoZCBhoZ}aUhQI$}\ho5[q\+| .s:ӝf9'%gX'%X5X3m]`4Z=VG[t1 M$܂x.UV ^5T @,0Qe+A)p]l-&n GJ8RuEC5{FwOQFU$ Kk&c1RŵBԼdOCGBLyA_SϧQdrSE]^HH=\ci$Lݲ# `g#X8F xU<^”&OI#4%bF {Up<0[thQ4ς$B¿FL~?6>ݝtSfSkÉkzI-0T+C{t/E]KcK>Qw*hlKm8ƫ.K)&r8 YWhY M'b$“3a?N['1cySaecD9)]o̴iX̪m*F̉.ራr}8ƍ!-pK DHi%-cX-!؞ןbL,G \x֧HU5qFJ8E|nSapך3XbtlقnZV݆' '[PHutƚ8x,CҦyvZry|qEȜfJ.mRZ,Ȳst'bCi{!1̄^-E4&Ԉ= Ļa>f(1g}-"Z͗I{I>]7LwPKSFaj#IPython/core/fakemodule/__init__.pyMK 0 D9Ez;ڦͼ7JBص@TR9)KXI Z;mI )S?y:0Xqo_J,K:Zv͎468k/S7x .4APKSFjc Ol%IPython/core/tests/refbug/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZYPY` *,FPKSFS(IPython/core/tests/simpleerr/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ X` khrqd +Ѹ%B PKSFgDd6H(IPython/core/tests/nonascii2/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF~N(IPython/core/tests/test_page/__init__.pyM10 Ew"[z! X8rܡ?$["j(gk4c7+Ix<PrS1O՞ Jc7W~#fZ43(c+PKSF{`-IPython/core/tests/daft_extension/__init__.pyA ">' DmI)F/jL9Faj`fYi51xW~y0+ R>tfk.vx70؜8PKSF*(},IPython/core/tests/test_autocall/__init__.pyE!D :\c}`abŏ̼uEbv ,*d%{SQ lnl̓>_7<% >G+=b` ք04~;PKSF^Z%IPython/core/tests/tclass/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ T"U\YJI,.Vp iZq)(PKSFjd'IPython/core/tests/nonascii/__init__.py5K; 0 =E7uR<7V LD`0]b.,%^rU"Xi*4=x;o3eחmW*;ǩjzPKSF9+IPython/core/tests/test_imports/__init__.py}Mn1F9,C=EkdbQ'8> =#q3JUcp_ɡ  Aaу\!*YX'Hꆫvt$PKSFIwAU)IPython/core/tests/print_argv/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ P\Y` khEPKSF&D+IPython/core/tests/test_ultratb/__init__.pyœj@z9H&b˸BSC)ev]AԧlӤg_vg=(e{}G>BFbabGjO8HIy M4!:D6_@:.Ļ5MđKCםGΣ]9ZrΤy%KM%_g%GVT5i'Y0V*N\^AE5ϺVE.J0L~/33_Ra[r}T7w~6eL @_j$_L {15[6jg&4Ԋ,pdB;s,<2.~އʹ˼2.8༩"_'3jI!t:6ٿPKSFE[,IPython/core/tests/test_shellapp/__init__.pyAK0+rkdt M D{ aLL@.Si1"%&,+e1kIA%pY?#+m^^ed iګA enL݉3#Di լ#Bc6.D魤vwO`̪>vQ9F\dwBZkIdGcY.W!J1z~p^|k RYWF˨ūx^f9xPPAg㇣s 5PҙgH&m[+-qnК`·+=91&гOrCT"ŋ WNJz)uS߳W]8R'gS(4۳Їaߺ}SdAPKSFib%IPython/core/builtin_trap/__init__.pyu10 @ݧ H,sRYN:ܞP BBxߗs_d2yH1+̢*N9 s `:f Jdd{˨V܏#hnZ7V8PxPKSFWJ]#IPython/core/getipython/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZYPY` pPKSFO`/6zIPython/core/error/__init__.py}1 0 ݧ\k鐡v[X2kɖj?PPI&!,j5ՖEaV7v~KG"JWUӊuÆȝXHh럺t4*PKSF?O X"IPython/core/completer/__init__.pyRKS0Wb2z5 i3$NT^'dɕd߻NՔq>2VԮ6e!2'"JUv#`C,Y#2K# YS`ԸVǵoDm.[t#B? oMp`µvLkYmt\+p.%c`=Ry^rtB 2o486yҞ2k W3^$W.U?|{spӇcx{GNBq̆痃5C:I.NJT!36Iy*Yao:{x ɕFr:F2֭2P4Qi2ܡB5} n;8+V pgoE1Ѯ(`ץ\ a&KZ]0K?/pξKTިPOOepN>숿PKSF^䦁%IPython/core/display_trap/__init__.pye10 E[+ 1 X-%"qAE]%E@M[q1 *V9}^0^V8I7 @h<P[G1txQhnڛsϏVo;9PPKSF3@IPython/core/magics/__init__.pyj!>@%% $]"q&uy\4w>f0'mqN3 *m4RA-Uj%/bc\"ŚJ-95k- iOWL Ŋʒ%(|us@S2% urF5 Lև`bv2\#ۦ,&׳s)oړkȺ":{26 !iQF6M1iL@@[]rN{.6jl$@P0m1NҟQQ(8j2wrJn٭'X %jbvo;f.)InKn Ipƌazُq̮²[Gڧa:PKSFD$%IPython/core/magics/basic/__init__.pyJ0yv"*xXԓidL²ooڲtA<|~|m3 З\ 8.FEO@x  fp %`̢5'sxkvfm~T22)T]ŌqJLz`2eĸ4\\w-OBM޻0_ XP 4z5Rs KG.AG64 97 ey&;nJ͓8{Fn'swNժơ~jdj ^Z*</ƃy]^3`Sjƻ_qk/PKSFl}*IPython/core/magics/deprecated/__init__.py; 0 @wBcrB-[wa9,߿Cc=f$ C0ܪ(6Eտ/6;;)~eO_p7am4 6>bWޭ++xԭPKSF3G[)IPython/core/magics/extension/__init__.py0 EwE f+ NDIS^{|l9Gh[mLǒ>N>'y\{mOQ;oy 0 Zg$:i(U/&ӽWnt mD;Z3Z/PKSF(#IPython/core/magics/osm/__init__.pyJ1y=*x( IdH$'oo6ҲRK)4PU$m)z4cmJ֏`xx:ʞBTgl"RD#2O6LKJ#^KTJv`)az`A#cJK̼ci^9_朚*^72ΫAsz2܉2![ӱ>L0XAFZvSgև,+_ݪq,Ci%<9y|{wė&PKSF``_%IPython/core/magics/pylab/__init__.pyj@}$C\ 0Hgr>Co EiR7%a"4.\U F@:85MJ焧ڵD}v:whK5)8MZu}Lުk|*fc$V_5i63տ F_bF}3π۪(<Yxů&~$.wnKoPKSF}ޯ'IPython/core/magics/display/__init__.py 0 }W6145JYkKZRSY8zG{CLtQlY'MjTB{-qeX7YCX"iVqu`4L^(Iv)(ܵmHb`?}VP7|a}1g4wqٴ PKSFuH)IPython/core/magics/execution/__init__.pyMo0 %ۀ;֝Pd"E-˿|`'/_>I=Q"#@kFO,g$N!5>Nاi:5mS:=t1/#N{}V6̸-bG-DPi޷>|noEQ|BҥK:aKc-mr .F ^HZcVxmDw2߄L|PKSFpB'@$IPython/core/magics/code/__init__.pyQMO1W H o&dLӴkC۩)޲R⩙5mK)̙@M$A AQo,fVRW ֥Q5jvQ&=ᗉ:eǓ/0a& eOPِ"h 846\RT%m^uVv*U566J!UR_rxUY}[4*nr#&]yc 0Ź "T_݂*YW-~ĖƜF 895e}B,MW* ֤~i_,*(ВMk)1 )ZSDe9Q`L) 0x8*HBYҔٔ?c3τlLv|~AW/^K{R.bGr]P,rnʇoA 5C͸H{i[;^Cow/mq ßj }B_PKSF"A+&IPython/core/magics/config/__init__.py0 EwEl`DyI4UQ`‹u+)(DUQqI±6MVHupi!$꼓i vlFAAu)#Nn{e'~OTnĥгwYnڗ(uѯPKSF#g$IPython/core/magics/auto/__init__.py;0 w"#\RvBܿ& ug!U+ dVW8$5`nzp!~B"6 Qe D>e7pbi 4Y͕O׸}PKSF_ &#'IPython/core/magics/logging/__init__.py 0 Dw ];5[waňReJC ٪Eܻ;iV`Vt3,+q2ϫu0 tNIi,;摊:wR' svspƴFJ +eݔ'Cg nr b-nu[r9.7h{6JCpاLexuc9>4Pzg= n 3 Jt[(30JNP [YF{!WEwYp[)EDDpN̍6<G$9]QSbŔVR IоYk1!&ހqqMw cLF_U*5cAc ]'J]GS5Ԑ;Nb0dg־m~/$ X@j ڋ%c5X+ح&\FTp'`›Nwc5cGNw6z+ 0o;]:-.Y6w礊 PKSF@ IPython/core/ultratb/__init__.pyo0W &4/Ӥ>H-TMe X$>Ͼhd΁6-bO(gߑa Q68"׵EGuSHNUY>`NmvE!kKk4tGS*e, V {Msbq+?sZ0ظ{QX[I=٩%e flI@?DP6\d >]-I RmDHKt~7sMQMq b]w[ǖp&)жX4gp*UkSb-(z{^UawOxEΎSw7=Ev-P}Iƴ{ᨵEOJk'=>}{^˔+`7ied:G|ɲdn 3}rh),=:ӫm%ۅ6%ᙧ|5$W _npPKSF^3H5 IPython/core/prompts/__init__.pyV[o0}WaSZijZZiSFR)ZMU7Y&pq¯sq9 ݞs|RChL<'B*/+m呢+HzH0!1OwUJ ~Uk2EYzTo^.h.^}ksK'>UY5k%I)٣ I*+bZכ\ @Wk5ͅlgM㣸̳I1N@{7ʽ:}.[QE +G:Θ #H-щ' \76;t8[h\9"&;Iaϑ M`hv7>9t<~Bpmz]O ;2O절{m? ĺ>([ f)vʗ)co/}#V6-7W~I X὆N-tBg8XbŠJ'3d"/1  uRsh.NJI ˍphJ<]C㸀7q.L` SAY8k-4E+@Xzr<34T #kMAz/)5^i`24phCz7yJO' BEڤ3SbR\ 黜@Y޹˃mK{nˀ@j$8ۍ*IKnha `kN]J+]VLGSBw-6 7ot@G`m6厹akKP5(z/Syz hm}Vmϗ}/Ǥ@aWgN#ȢQV4OTUsJ쓧/PKSF'cql"\IPython/core/usage/__init__.py\sƵbD#R%)KTQ~ݴczHX@,9(َ{{~-gwne&^v21pem2kzu;sr0yIܹSF5'CL&?oG+H diUܹy,s[N+@~~N?:J;o?6Qq6YW4?y8\V+eD[:&͍yTS-m^h]UTY\14L'ƭk?0&V4aZJW50Ԗ&v<]Hn$Ȭ-^ټh1U\E=0XWDʤsqkvB}ɡG4imLn1䍙S&1.![ Z6"DCDFY) -xtYFUJ`!A%d$١m%t#󔖪|Byn6b#F5a0re*:3#٘L1C^Y43uCϯMo-HZJX,[90 HVDQE3b4b,I;71ŐN358$OIHEM1ے9w:9м Ldv{"@K,,¡ߐ:!)Ҙ~^zIHPb;^wY6fڵQ>#چ5j CoY&s1 mfS:kPFi6P: gX$_哃@:am^~4OUDr٥5Ǐ],Has[CxtJf"aq=29iEYXOSBM ㎏= c!q%f CAZc7y3 R{A~edPFYmֆI@ 9Gm8l t'6LKc}s)KS Y3Ua'=%e (J$Cɑ BjbEӛ/x?k+Y0!K`u]x\8`qWmjg#hOu菣oLO+wiѽsͻg'iSXbSe3_J0AdillcuiEsF"_8?5(]f7HK[^ʸypD`w!n# ~$Z*7J;v*5ь63S_|`xOu]F-wT?ʮ ʔ~ R`r%$uqo( F " Bؘ6@oO.YQ {:6ngkW [3BM\b9=F\y%dw=a.23=__+ =!!‘:HMFK:_t x$ \Xd Z|rMJ*1jkFR@o]n (Dۂ4ENX"d v>OVgC`ܺ vLR c˦D<:݂+[*Nt-jtrO`n-B^~ZKYii]BU蟥SE6 121-㲤SWP-ݚSdil"@B5H)JpԜnf))Ufp`y`\ˆX WkUPYbf\FVbA^FǼᤊ۠UjE i& ([óׯ +'fh|뀌NBhT1)" BkDD|ֆg\FD,%8! 9aH;N_w{X5u uy#byؕ,hf (8 ( TEy=gfNUWl\B~"H ޽|lN0NS>J _֪uړ?>gpl@3OCpeek'&.ocŒ{C(a8J{+m3 N4T84X9Q \ fEe" @UeZU&JWiLyaVйp3G5m떞x=#,BZ WM$'uWrYx9x֔ZK^IX 앪h! 9di SVkH]Edab!УЌ_:AIO hi1xի'ȺCAFٖNȥ ,;[jY(T@tп+cJ+a[(70׵k`u,%g !X+qs%Y0OXO{t2`p~xK>]֜rWzJrU{Amq crGD)98 AHX5[@|^EFqUhz]"a9~Sp/E49G:9g{B`~ & Zm >e?ύnWx[a%J" =8OV< Е-v VS691BG~fh^[{l8tzl4O%ĕ!e5oAתW%VSV< ڲJصJ( cʃkyai?#e5t͹1%#Xm +qPSo @#3P+,@VucL@[.@rCK+0NAHam;V41&fA#YZi{%.h(2T$fXx7]bR}5y',0PR {VjU S98$]ka'!RaSt :.cٝZAT_&NCzEN\,ZS)*y0_""cE)?3 *  Ul [@(pGl+a)9HW)%mb:E~F,b($)½ e-\]HRܒ%n<|qH.@H׾Ve߳+r{9ۛc'wQiRˣ>+aqeF3IUc^T+]Sћ])fp9S%"#aّ&GXl׆D̑P$-fa''KJpK)Ny}RQEd- =&8dⵧGWm3rSe 97ہ^I4Zgro-sP-&U=)E,9)Tr"fgjq.$o/_qV6t5ML_6 t :3MDqFKFZF\8os=0|[h\Pp$NTkZtd:vd^C wN^yg/eHڐ?wUrjsU/H &#?@ZeCDM Ĕ(lso Z[ˆZuq%KI iSdJqKI +bM)-qЮy(\w7dg=NI=G V YJdjVG!?+q8z ϯI_D6sfJNZZگuiA; (@n}ׁaΑ6_eR a.x!#M e]HEwTЦK6jZQ%>W$:oq"l]0eB"qmU9a-9-@ ڏ/no^rupqZQrIcb f2a&l;g'˭g /n.Rw Z@v*k GZw-4 M<<5{|7ރs|ܸ 0o:7 I_}_^K!ٞ-1jV^3Ҁxwx6#ҀyGޝ;Vpoa ?ۈ<\7#VSELJj{OALlk W=iץ|S.; 7Vʈu&~${`,OcΡ7 sK]6AƷp9"A#xU5J^dȅBL$ twg+rG7 [:yFfMF\X*.әq+ٛ<9(Yj 3hEJ<MQCv$\`<{ 9;*^(rr T"}bv{Lޕni_iX%/YB:RNb{޿O{e=MEǝk<흨z#USǸKJ{L&Ussi b "Y]n휸@` R%xUIFIG 6z G8eo^=[0`:NXh-ߤ Zubb|՜(͜KИ:rG!9:ZSlyG$NUA 0P %!Eo4?_M1<y^nAka[IB7}lv;OcF#T@DF#wEtibc;+&HP,qʭg'ikDy 6 Hu8vՈYOOG>~fWɈ=WؒC PQq~.yp{_IG "%EYͬRx fiƉFރԀYnk &g0}~6459dgj5A6slqy_$cA버`AMao脮)JDA> %%d8 ^gj:2PZ6=o/x|.PrNHWgE*lܯW=4\l4=lX( օ8>"'Fqu>w¡:hw;‘dAHC+MRqS8@aͣ_ l@WGWvn{DѾ[k,FA1D'{_af{#QAJC}֟/E;/:A[Vpj {(כmm05C~够 L%I.YnвxMWri[&L@yOsV-3mR "s3Fs:خ@}N^g~&r^rn _7MX9 y 3KVT{׉w+}y2RЊ( b %ְ_VTJB%=Z֩\k:t˶t>#x#+n^$m62Tsp9[N^o5S%HK5 KoF6"6`0DUΗ0d!Q#]>Q5 烫A>nZɝX?yH pHmi4)!LW&H,dd(,J5h{}^0/I(T. )IK& qan7ncTp24GlV[u\Ryj3}DU}NSPS h*A_p2W]MDtoOSէרI*Ir閞XˆgpKdnw]؜So+*A5!2;2XqAw(ۑI .z-vJKS4!ph3 t$G<"$*j/ǯ"ND<+ Ea#Ҡu Rџ*8KG7#N|qq MV ]҂J7=+]jf,a8o1'@ʴk+7Wl^=}i>o38* $JKF9%oJ\FCV:w)ͅ5k2pe)/,^9៿&q@J-תVLw[GKޣvmn4YQTPȧOڎD |s Z`z =}5v%[| s}/xWXC QW%g }bI _~)zwp䙂sfׄ|l`ʹQ*\TC hXŌ5C!e.2i>ԫgL` w𔔥?+?Alp?=<|"=3vrP'Ud+[:qyG隇|P<\2uٗ-*{=$c U Ag 1 u3;Z>o[i{0!jXhǕo2L*Zd$X[$%&|,Ikրގohؤ{qʄfZr'w|ᇜ>֒1m)23<`gF6(\K@u /ۚviѰtmN>JJ:dEhye;,I&霥p*W*Ɵ}a0 ?oOsP5qOV?zza=08yZ ?[[TUDӊP.ƀM q?NO\i䩈 | '9~'g_es3k3lfǟ]/0C=/L%"xX?6)*dR1bhZ 7甆|:wn}y/$ԗ{4yĂI9&tmW[O M$M[9$Mz-.ξds5Q?>Z|>` H 71 9]sĮ 2MI]9'鉖Q16W hTf7K{\M0]@oOy2IK𖀠fό<=|o*~0jZ/KFXn\hT_fvmc4B^&z@"ҒwHm{c(t|׳$8EAODJ*]\OD~" 3զ} IJCȏzJK;3O|$}K_;|w>p{Zv h9'鷇 =.7~Eg؉Zi$?26G[㿓0#zOeoi1Jsa):Cu #ˆ*WY&P م?^PtI'DV޴5/۰]edB5׊w)8͑BVZ^q|#7Ȯk^Kw̰ߖcMog2V |;wPKSFۘ#IPython/core/extensions/__init__.pyu1 0'qp(:LBr)7V o#*劔dB?FN1ynF6MP}x8,>apS^v?3Jҏ`۵뎀ksR{zMzw,DOYFӂ6/PKSF`l]#IPython/core/historyapp/__init__.pyR;O0+nK+AĆB:V΅X8/{郾H{M(GR L|d8l+y#E|M8űI08N&jAʹd[[1Ȩkq[L 7UU94Y Ps֮A ezAp;_:D 5Zokh%Xn7I(&xy0;ʣ؎ @'a5Umm\YSe+/EX'X0E/$H:~9CoI'v4a`]oY5zl.$f1PKSF'X#IPython/core/compilerop/__init__.py]= ཿn~GMLtA"pA7A oAB>NE$Umʒ~P!{.UkuN+{@591e:9GI|*m;"ӤX˦6xJ+E:H!W~ ۶{F6(=KA֣ѡ^2!okJiW4ٳ@]Uo,^P *f`u pWZDCr@'1ޡތku;w4p =aprr0Ҹt!M7!>u> &y kv >MK2Sew1_UX>%ʮziyܨƹstEcY)bB9}Ui͆H/M:n073$QVvs?v!PJ[?PXf=,i~_8X#zf Lϭ=>4o%9JEnBP}{ >,|kC7W[8hl/]PKSF(D&)IPython/core/inputtransformer/__init__.py]k0+܋J(#6ӫ28"Ir!;r2 %WA{t;]jʸT.RW2مJC@$N@0KJ2Ζ+9vznS_Jp^w{$I^,H?=|1*dB[b \rǩ VSCh2"3\hg#ř2d-9BM !S+lH:.(FP BTx}%A/%>/Ъ!kVjr!:1SXHQ0UU>keT6TnG*%"XC`HSupk>xaRteVjC7To.peg>/gZ#˾gYX.<Auh=?xOϏ܃>IZR`7'@0̍G5Z`lW^#BǓi$D<ڵCBhDic;e*0㰻$M5B$7te{ o`,~ưl֕^Uk:px]^en-7\1GqNߤl>I)PKSF;mIPython/core/logger/__init__.pyUA0 ~DM6r*FCfؽ&š+̹W+#σwiǓ?Dfjn^451Q )m~svPKSF@s#IPython/core/pylabtools/__init__.pymnC! ڱRl>EAV 0Un7RX,skNw RE);̋])Y}5_t8.դ_+JY"]Fb :md.MFZ/{F8#Ywң lScY(k DHGyE!o+|zI_iѶfN`;vSPKSFO&IPython/core/inputsplitter/__init__.pyKk@!8B)6<9X^/vW1,{Nz.b~y3U9(ƅ:Q̓0X^Od9[<J"H $HџyVCg*WCjrӂ3R^d2`)P9Q iwpY=gqL7ٸ-vPS%Tݠ$4)Z?+#eJ2agC:+rN3YF{H)8*yʼ#v9=\Vdtz\iF4GrzD9K oRS泾+}'P[)B@wOp{_%zW'% E ~2pr2 O+#M8F~mBNu!Xf'Fh}q4?(V44M'7<(tZPKSFgDd6H!IPython/core/shadowns/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF9" %IPython/core/completerlib/__init__.pyu?o0w U+u! jCSpj=%O_C@ v{g$@)ŀ$#OzE&xѝ].Rjp)ZCu\42^ '.cl|ĞHm:1͆ݸ.ʒP3SԊM` fg5{&C0Y/5 lh^c'ung):iL=kFƱƴ^ntmQhIIؿ#_`qMzh|PKSFXaQIPython/core/magic/__init__.pyTQk0~8 1PXv]fOP/%#BnܸN:Xt)w!&4U2Q#&ۨʇ}XGXe|M2ttcJkf:cs:Zp+$IRBI~rQ5֙p%@Ɏ_ܵl$G܉>;ƌh 7{D2 $"sH]Cz|nJx 50wvݝP <}|ZYӯI A) %0mnSQ%Zۭo5t4>[5HG`h._#Q%bkF9l6z{t}a[*YvN+124[9yֆ!*trf{ƃWk= yP3&7ԞW&tN&4i/VVmO^Yqt*Z0v3jv޶Mƹ/bVʯݥy 92ςKПZG1b;o c -ѯp]pͱ. dh˥W+\h/PKSFQRg!IPython/core/debugger/__init__.pyKo0ޠ$#TQʳb*)BSrl1N:Bd*ؕQ DVAmtAq%AչEkE;SB~4`&Byvh]w\؝݇&uHQ߱|+kJQH\mEpΆ: vFcuvJH^p&T[!-=wvktxSˈ]TqP۱\r\RFBJw5=;ŝˢH+c9g-wnܱmEM7!>O.㚖0l-<tA˼3Bj)3qH0,k55pJsrPgb3N(qHKBYuUKHu{pv'O>^\~=~sasG7܎ %S vn=:%& khfXyfst!W\j00s7sPKSF$5S# %IPython/core/crashhandler/__init__.pyVMk$7ϯ(x|71$!$ !PwWw+VKB"bMcyPK޳ a͠ ceyRI(͔@ͱ_ iuR銧7E65[a5LAHe~Fs\X†~75Y`ބO*}K_~@벢\LkA Bf]ϲd6gktX/Y[rA,Z h|ɻ$<"]!Dj1[7cGQ6gy\O]Qr0c96b4Ҙ:UH%DYcݐP1ͪd_OǺl|[0X_߻m봝 2ɻ |,DzH]>"Ϸ$Z. C k5UKt%B)zqAYҌ~8.(v j_Bʤ4W`غ{ V Szwʯ⹻Zy&f`әߠPKSFu>,IPython/frontend/kernel/channels/__init__.pyRMO@W(c/&hbe)~S HKͼfg1`Qq %Wiɳ^3,6U.&rHOee#옻-wч6@P&JY2%K%o<(\LmUYOQG{zIBt$k4"l5]O*-86W?lN*qVZaE`Ш_UYf1Syϕ0K5ڕS: 0^@ ! 卑"7yPKSFoi+IPython/frontend/kernel/manager/__init__.pySN0 +rܑ8I sng8%q'דu4=8mSZ4VjDՁXFsVv,ͺ'e*xMY]г,,XQM=L:AE\z-?nl^s ,;nF<l晱[,.лz,ǂocS|'PT !S++⎣]w Hӛxh 6  ֒^\N rrƅ**m 9{3/m}^/~1d2fVQҟY%/PKSFpI,IPython/frontend/kernel/launcher/__init__.pyU;0D{bˤ)7XcZC۳$Br{f1 Y# rmFU-EaV 3)Y*>ZS;eS(FsԾA:6mUxJOeӂ2>jm2R`,< PKSF-IPython/frontend/kernel/restarter/__init__.pyN1 <‚:WbT@NO9*o9N*a,*xJCF cͬr,|5HX ny4H;0Zfߙ"<Dg╮jdeB,ݖfZ_Z?^ ~wWҁ'Eo+%Y6J\MRʜcNt}PKSF/m*IPython/frontend/kernel/client/__init__.pyQMK1W"A.>dɚכFCyLl'CI]o]# eȲLe*T魉Owǥ(w8R Jqm!v)ɍ2Gyx3'KYѪ6M`:T1RX%26nC4lxyŜ(XyBrésЪب@tA֓]zM§DJ'p'-ss)cPѐxfWZϵPKSFYo6IPython/frontend/kernel/multikernelmanager/__init__.pyRAN0 u Hp@ Q:lbA,'m("؊O1>KN`q%$)(9A&GVdw fW 5[OV 1(A0䉛ee3~Ǘe 7#=SZw*g#6ĩ, YsN/bhgpN 2 GHev]@gn\̽^,ϯq"LۜlV3uegɶgGB/a𶸘1C j Rj{eHPKSFS'4IPython/frontend/kernel/inprocess/client/__init__.pyMk0 Ka51VXBȗ-g(tXX)1XJi{d&bMę^ <=<c7 bwrIZ36|ZdKe.I~|6LYU~3ۺgyO PKSFĮт3IPython/frontend/kernel/inprocess/tests/__init__.pym1 0 Ew›S(Aн\5%#+Co_&C>|n6¢H"m[ LRrpiŪybǦ[_LH>QX=Elk:ܟdPKSFD׾eFIPython/frontend/kernel/inprocess/tests/test_kernelmanager/__init__.py @ yM xQD /KmVfn&bƸ^DƠoYTZ|dp#L iM e`sMPssS5|dċ v C?pi6+-~SfIno}ېi.޹(_cb1["7xk; | PKSF}Px4IPython/frontend/kernel/inprocess/socket/__init__.pyu1O1 w om7"1tCeC#.ɑ8'ʯǽDȾDi+B!(%$579 9/@;p|OMə/]y-\ǵxx6St>;@-:#\_ T9bH>ʗ5]'KsFn=\rj0"%yg cT.~PKSFtWN 6IPython/frontend/kernel/inprocess/ipkernel/__init__.pyN0 }ܶ=8?iLm'. nH*N*CJA.Q|/S @]rI`\hcʦMl\Wu4FհlLo9 cC\~\U"zB>V}lͱ$Q,EeLnÃ!C_h6fnJV3gG-p2w)ZYi u,mL5%` $-jRTh\Sb`>m-u. ' L 6h%?W;'aZ߮oOoqPKSF)j6IPython/frontend/kernel/inprocess/blocking/__init__.py 0EFWEDCSNJV޴ꪈHlZ1DZ5uZGR*U +V77L4b=,9$و oF T>WmbFl!;g+FJ?# GXc!_V7oIpꀷ;̌j8LPKSFM*IPython/frontend/kernel/ioloop/__init__.pyA 0E9EvmAr(Z"!TC0.7LO#Y e$S!~v6?ŒcѺ,*׀-` W=bTRwcJMlվjwtޤ$66YZH3=,oPKSFN`2IPython/frontend/kernel/ioloop/manager/__init__.py 0 }ܶQo^JdOo7 1u$8tL,itՏ9DvIP*%ܲcR31bdՆC9HLtYn1 C,PRZ/ b\b<ʾ'?PKSF*4IPython/frontend/kernel/ioloop/restarter/__init__.pyA 1 E=Ev3sJ-)ۤ/A8ib., E"iOkd2a2*c_2uOYB򒱏uS w&9gg!e_54:ZROwP?crŠq/vX%X7^ ^[_ҷ.Z Hnsq<+]Rznta2\ o8VK yPKSFoUY'IPython/frontend/kernel/zmq/__init__.pyMj0N](>@!PXXI.$HȻo}vBs=䬏ye"ɶ >NF ?Q&B_8X`D0]37tkOV!K{b N`HQN~:kD.PS&nX P@x ک-FW=ȉ.Z]ӄNA#A];5j{%][)@IYZVto3+ک-n!7Kb)dޯ0KQQ ̓4a!r;<838PKSFpÚ1IPython/frontend/kernel/zmq/heartbeat/__init__.py1@ ݀ň11 ٛJ]YV ^.x c D0vaƱa{-]p^l)Ed?[[VKYTZ$?w{[ $|(e< Zgc@ 9Dsp 0#Üh0"r uٱ,TPa9IO`ϵus~_1qW~,j3_Lᄜ;@bDG=*P-BG*]嬆?ݦݰ- õ9u>-s]g~aޅh$ɿ!h{5{+5StrOKJ)oPKSF S0IPython/frontend/kernel/zmq/iostream/__init__.pyeMK1TD,+VO"Cf`L&bNZ֮zJIr>c k|DvHce| &X؞Jo@">nwڤO:etSug1QHAN,3j|*"5{ej:gM}˛c{/Fیg@K^79 `'3Na tX\ҫ/v]ʡlPumPQ~PKSF(÷3IPython/frontend/kernel/zmq/displayhook/__init__.py=O0 l`ucϽFQV8@D(+2xnԱ0C>D$kvpDgOg5] Bϸr[9X qg PY4 Wgwg9=xqPKSFK4+IPython/frontend/kernel/zmq/log/__init__.pyuM0 {EoϋCM" fўo.E1U "`\ѐnJYҟ9nor'-hIZcbj>xxӌe.8j5\ |˃PaɆC9]]ҽaH :mIxXMg68[~fݕG' [ ,0XBCN3lK !Qh(2 :ct4qWhn]˘o:%8c?}'10nS}~/ҚL?pSq*9]˟VnPKSFm-1IPython/frontend/kernel/zmq/kernelapp/__init__.pyU]oJ}"+]J<"^5AC;fwb~=v8UUH33gfօ *8T  RbU@KsqJLm(Κ@ψ'SΆ|xe"$R@D!9H^ڒf:dR6B7&(5d eSjK̆J{:f_ҷQڕ-ns>ѾPk(/MWieْ ; uU$yh1;?=yr!gΎt$* ΨLUR^E1|,Bɮ ߨf zZY©<92,aw5[ڥ]0ġBM.5BPF𣑱 %y$)- I\m.I,hlАYOKai'P&ǶSǡΡbQrJ2$r2oszߠ?|vŇNl{Б8E$ق,]ܹ-\k ԑ ;9QdOA ;*yb6cNvq7.A*Ψs*ieplS=;qetDwʁ;\ZLn_tD_TqQxGk7]HQ)C-8Ak I0m%J@MT1>hK̈ٹ Bwx9o9-o5^7mOkӞI.t,;(7/fOkѿK-5d.d2y1۰T_z,\(gԣuNPKSF&bz-IPython/frontend/kernel/zmq/tests/__init__.pyU10 E[@BAĎQ-nR1/4BRgis+l~ފpUw/`JNA現1!/lď4Rcһ>Ӫi ֒u܏aPKSF̡:IPython/frontend/kernel/zmq/tests/test_session/__init__.pyQj0Wf)ɡKS=RSKY"z8Z~}WN ?ОyRi(0n1!m2\. kDbWRʲx>|>ѣܥ"$Fk(mߊ|_@Rrbpi9c Zx"|_Hir2@e>k0^9t,aNFc`Y6,t/6殪۹Ps})2UM*PKSF2G0IPython/frontend/kernel/zmq/ipkernel/__init__.pyMo0 9nzQ[ .AiG,j9[z 2뀭NH)L18bi2zjQ YW[H\1!'*/>wCNdl\GY{(XPNp4X-CFYVA%7Sz`-)~=ȃNSwujkjbL$h";4˙);S8 ɴ0ҰUt19ϊTN#4'SM4,v,V(޸n5/^gBxǸ%~\NMjӤǚwFu \_.XR")4%|}Z'>+;,HE*Zoz.v0o:^::{הMn9@|ߋŲ uJh?MH0A@APKSF:/IPython/frontend/kernel/zmq/datapub/__init__.pyn @wܡRMt*[mR Vӯّ#VUĻq1tΜ#h!,z(5.䈆%([hUꒂt6P!'" /cJ)ʔ6>){UTcv Lr(Z_`io˛ MX:-sO]7+ϔ fB_v4AA GzxǷLtRPKSFP<71IPython/frontend/kernel/zmq/serialize/__init__.py}QJ1+)H -]t1X Eƛ'̔ys *Q u] Y+I;lh2`u^唝PWUONi߮QFG=U?1AAHMR C":0 hrek!{B+ 2 k^lAxoz0F-"b-Dp7[/]n=>)cE><;=11_z\3}_}PKSFv/IPython/frontend/kernel/zmq/session/__init__.pyT]o0}WV&tZ'H!dI}i0-62B*Þ{pc)2q\BRr!5%Pj&UC`YL+W G7'f:a~ 9eJ_}!qlYL]C4"G3> EDSјns>RٗQ4e e_ZPcsK)ڔ5Q딭ZPFf4kJK9 9kBHƓ&KѺMptMh"HRLRFT{u*NIN<07gZ+-xyΨj C/ 5S3t܉`mY|u. 18*[A!S曣RP<`/J$iAs#D%.kxKRE;bhdJNÍa9j(h{jŊ>l^T@Vv_z'.%aڕRtFRW?i%%KmYϰPKSFJG2IPython/frontend/kernel/zmq/eventloops/__init__.pym1 0ڂtr:8:"G m=_oZ u|{ b38Ԉ\ATKfY96oU/D̳er$vj-EYʷjvYO [怆 m0Æ߰?Fqv:cT,=#_JTPKSF"mVv+IPython/frontend/kernel/zmq/gui/__init__.py==0 "[@BAĎ%ZD o{_,1V}U$hIu}f-hC*]87@L-5AuPKSFi4IPython/frontend/kernel/zmq/gui/gtkembed/__init__.pyM10 {%|  ff]Dn=["!qLGQxW`>bvUJ7lc)7LW]n1PKSFZ -IPython/frontend/kernel/zmq/embed/__init__.pyUM @ 9Evm p# )-@xy/ ZD(XUrm]JR7@7)NiadgW]kdŻ~'|t~XZ͜XͲASİAΆfKlr3PKSFɘ!IPython/frontend/core/__init__.py͎ }"R5o0E"6Q06o \:V0<6> Wj0PS5:g* ?¤`ž×/zIq5`[h޾]=%un{i-R4;`dRXĔ"w߄tB 0M" -ی =ªhplGTr עs(NG(nsگ"Tқ .mfj;t|Εwդ5Ѱ ۅFI2(.#|8ՖB+ l= ,F^QRfm6T7@'#1@ |t$*[,i67_l%MD%t{hurh[7;3A©Zf : u!]5q['.zIvwz'Q-B&C| HViTz1zGQ-fK*G{OVJ, αMPKSF1IPython/frontend/core/magic_arguments/__init__.pyOK0 @؃^ă046LQiVy7o^S(#2.xɪ_r;PUCDN9h㻼7!h3W_)˚$zQwUɂ)loN4i@3k -xtsŔF wwY)fZʷҏ1&` .;wdm`"Cns_+ר5t}>1n-h%$L/KN-^`PKSF-&IPython/frontend/core/page/__init__.py}N1 v%\&cEE >#FĺkωC^$N@<NoCe][9PtI!m`G6;˜Db :J*9)=N>? Qcv6PKSFbJ,IPython/frontend/core/splitinput/__init__.pyU 0DM,%lBvsߛVzy)`%;DC!Ŭ&eb-[0V\@64ʛ!py_V3˔'[w(б]"OP'ݶmӊHʟ)l#9فخ;1PKSF1{(,IPython/frontend/core/formatters/__init__.pySMo0 W]z)C?m . 2j%Cߏv>[oHGQbUKmDI6z7d'gh"u%5]t^DW_.L{ U5.mjtS8u4l5DMA'O+AJ> }d. GR-&e\.!筯&ES .Fj/vy;h^Uj,{7򛎪WvF(HyϹ]_Nձhp?сp}s;nynP0/7'n{q%>O]ӛ(hSv'\fp<:>.?f;>.< 6L eOY|Oy ͠w|Ж2 ҖV#YޣEg/yp |rPKSF =*IPython/frontend/core/excolors/__init__.pyuQO mo&8^]b&"M4fۿr9mnƌd 1Ɩ맵pQUڈ ?s9VF3$ &NBBWQH-ήMlxmcƷ/sGr3'ze]l1bE@=ctJ­-*6*\"bByJm G x'DJPQ@N11`QbCQlFQiJ0.BiO*0*8{V(]Pe PKSF\z})IPython/frontend/core/payload/__init__.pye0 D|/ 1R?LH*Ďѿ]R)}5zTAUbRF.T7B"h;p<9u_J~;$  /=Nct5 >fd\_PKSFu*IPython/frontend/core/autocall/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\ZYXZViťPREE% n9ũ0M )*k $*PKSF'IPython/frontend/core/macro/__init__.pyM0>EB,.ƄAFzI[e< F 0Ln2=B+6\:J渒hXZByÔS@DJ&M-5r+ٷ!T'U@^YY}FڦXoZ\QfT X{ӟPKSF:9uV-IPython/frontend/core/application/__init__.pyT_K0[7}a THҴ=Brvl w yEU0R 8x $|G:M.gHT,K2kXrЉrnG*-4QYH{< ͵ӂ$7PQ9chǜTxnUC"]J.B0t4$3{Um(]{IJ"=pV(f 9ML]$<,>`bl4,D;tf&W%le.!(y-VR%vl6ʥmCsk.ec#@Ӱl?ESqfodth+cC*5&{5Ӌ1h]geV'ĿCPKSFW,IPython/frontend/core/profileapp/__init__.pyXk0_qtlf+e}GXT$';}8-}Mđ~ߝ.)!ֵgAcrr'^}n˄^+fyVJ),{?37.M*BS[ ٚE.[K!=HP{@2V7eP|MZL2/Y+Zb ނ^^nC@t( 7pkaRrLZ _=l1ڏe(iÒv̈́׾8ieE [pC5(iU뚩APy}0yoݽf\Ng$ϝ6MSTA\_LCW(Vs2c'4nw g hPd9v n k<ˑJu9d gbZKijC F;+KSe;BX:ݚ9TyJx1#) )f /K'f"OR0dv%?[Ezv=w`:lz?2E=kN>8Щnsn\r|Kg-(YtP q,גK^t%27ŋ_菤Gh"_Zbf ܶ☎.,7ƽc(ɒY FPkZ;I"_pl!ߢ*H/Xci-5wنɖ*(u 98};;TRx^)z2f͍h<vU dMebMJ@ sj24i?z_鹹9t&ѿu1rpk RBпPKSFj'IPython/frontend/core/alias/__init__.pyj1 D ݒB Rz4 ]9FwRPfތoqD_K5FRDP$OOpFTCA B3vE[ƵZw(cNAJǚ5h=W2]k@9S[6nolwi!}DJgy\5 >(T-㥯?PKSFlJ˳1-IPython/frontend/core/displayhook/__init__.pyuA 0Es٥x+]Bp/bit0)DME|YslEz}$rFI9)Rz;IxB)@I)y?qb JCW0@\JtB[=d}aogInX)kN@$binxq!PKSFX:a2IPython/frontend/core/interactiveshell/__init__.pyWMo7W쥐 F"=F($B\+_~U\o[jk,0 R{Bl[ i0-_JG} zyb]^* ^*w-U:I,MH prR%[Ҙ bj݊F΀S-'Шb@rr5'Qc$`n-4BbT~:QU`aX*ctRM2J*AyfJ-HT:L܁MIJԕ), LI o&Mס-%-`-S`9axÖq{,f/CSdTy) ބRK&~::itY,SHG kJjQR".P^†gQj*ʲ^-9m(cj-pwQ^Grg̃1Gj엚ge yRӓz-0W شbZ1*F=b[$E ˸Z](=-k<5:~?kK<,hI8{wE*8<V{V58:m4.Uk`Ln1p%ev zf:ћ{',/兗 y~_8( pɴ/KY{9( xK~zcнt`8ԡm/outvEEM`f܅Vr(A !#o,{-gÛG=#se(yPKSF 'P )IPython/frontend/core/display/__init__.pyMo0+, D)~ڦ]e6 1ƲfwPϼ3 ԄҢDԺ1H UEŠtе{YjzZ@I{ eOP z h9gGTJ&Ms~l:h ={fCmTKЅΌ 6>OcAN"N [EZR?Q|b]m:g]Qd]~;?13ʺk)R_ ~DfլtuOuՉwc~F'qg$Ş_3f70#aPKSFW&,IPython/frontend/core/displaypub/__init__.pye 0=ŃлȒ.ِl}{E83|&MFDE r[ Q37U{Xv]lZϖ4"{UY-R̾W i6ծopuߣ|"t<Pʕb^sZf- IfTcЙҦ)Jsϸ@f#<:dz3k3Dڤ 1PPkQյ< '4υ+8NeVCVG0J72gmޣq,XhՋ8\+&QB_0>ŝKI !?͒Ԕ䞯aIrxXd ,sW HER瑺B 4r"X^A"w-ʹ /y#Ad߀5O­DpC"'lw&}Bihfl (dhoZCBhoZ}aUhQI$}\ho5[q\+| .s:ӝf9'%gX'%X5X3m]`4Z=VG[t1 M$܂x.UV ^5T @,0Qe+A)p]l-&n GJ8RuEC5{FwOQFU$ Kk&c1RŵBԼdOCGBLyA_SϧQdrSE]^HH=\ci$Lݲ# `g#X8F xU<^”&OI#4%bF {Up<0[thQ4ς$B¿FL~?6>ݝtSfSkÉkzI-0T+C{t/E]KcK>Qw*hlKm8ƫ.K)&r8 YWhY M'b$“3a?N['1cySaecD9)]o̴iX̪m*F̉.ራr}8ƍ!-pK DHi%-cX-!؞ןbL,G \x֧HU5qFJ8E|nSapך3XbtlقnZV݆' '[PHutƚ8x,CҦyvZry|qEȜfJ.mRZ,Ȳst'bCi{!1̄^-E4&Ԉ= Ļa>f(1g}-"Z͗I{I>]7LwPKSFaj,IPython/frontend/core/fakemodule/__init__.pyMK 0 D9Ez;ڦͼ7JBص@TR9)KXI Z;mI]}bj=Py}k-=_\ZZHMKT8<>+ڂ>=?.v~;w|a4Bv 6c.2 =1d]o)\z=J:LX~:{.9f3]ZVCbH(՗LōWpNOS-cv-i PKSFj9IPython/frontend/core/tests/test_completerlib/__init__.pyun! w1*P[-S#™;ZkSqU,~یA*e JIf)u ;.V@~ԩў lxC%*!y`+Cpg"ί&J`:D (H7 > )S?y:0Xqo_J,K:Zv͎468k/S7x .4APKSFjc Ol.IPython/frontend/core/tests/refbug/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZYPY` *,FPKSFS1IPython/frontend/core/tests/simpleerr/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ X` khrqd +Ѹ%B PKSFgDd6H1IPython/frontend/core/tests/nonascii2/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF~N1IPython/frontend/core/tests/test_page/__init__.pyM10 Ew"[z! X8rܡ?$["j(gk4c7+Ix<PrS1O՞ Jc7W~#fZ43(c+PKSF{`6IPython/frontend/core/tests/daft_extension/__init__.pyA ">' DmI)F/jL9Faj`fYi51xW~y0+ R>tfk.vx70؜8PKSF*(}5IPython/frontend/core/tests/test_autocall/__init__.pyE!D :\c}`abŏ̼uEbv ,*d%{SQ lnl̓>_7<% >G+=b` ք04~;PKSF^Z.IPython/frontend/core/tests/tclass/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ T"U\YJI,.Vp iZq)(PKSFjd0IPython/frontend/core/tests/nonascii/__init__.py5K; 0 =E7uR<7V LD`0]b.,%^rU"Xi*4=x;o3eחmW*;ǩjzPKSF94IPython/frontend/core/tests/test_imports/__init__.py}Mn1F9,C=EkdbQ'8> =#q3JUcp_ɡ  Aaу\!*YX'Hꆫvt$PKSFIwAU2IPython/frontend/core/tests/print_argv/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ P\Y` khEPKSF&D4IPython/frontend/core/tests/test_ultratb/__init__.pyœj@z9H&b˸BSC)ev]AԧlӤg_vg=(e{}G>BFbabGjO8HIy M4!:D6_@:.Ļ5MđKCםGΣ]9ZrΤy%KM%_g%GVT5i'Y0V*N\^AE5ϺVE.J0L~/33_Ra[r}T7w~6eL @_j$_L {15[6jg&4Ԋ,pdB;s,<2.~އʹ˼2.8༩"_'3jI!t:6ٿPKSFE[5IPython/frontend/core/tests/test_shellapp/__init__.pyAK0+rkdt M D{ aLL@.Si1"%&,+e1kIA%pY?#+m^^ed iګA enL݉3#Di լ#Bc6.D魤vwO`̪>vQ9F\dwBZkIdGcY.W!J1z~p^|k RYWF˨ūx^f9xPPAg㇣s 5PҙgH&m[+-qnК`·+=91&гOrCT"ŋ WNJz)uS߳W]8R'gS(4۳Їaߺ}SdAPKSFib.IPython/frontend/core/builtin_trap/__init__.pyu10 @ݧ H,sRYN:ܞP BBxߗs_d2yH1+̢*N9 s `:f Jdd{˨V܏#hnZ7V8PxPKSFWJ],IPython/frontend/core/getipython/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZYPY` pPKSFO`/6z'IPython/frontend/core/error/__init__.py}1 0 ݧ\k鐡v[X2kɖj?PPI&!,j5ՖEaV7v~KG"JWUӊuÆȝXHh럺t4*PKSF?O X+IPython/frontend/core/completer/__init__.pyRKS0Wb2z5 i3$NT^'dɕd߻NՔq>2VԮ6e!2'"JUv#`C,Y#2K# YS`ԸVǵoDm.[t#B? oMp`µvLkYmt\+p.%c`=Ry^rtB 2o486yҞ2k W3^$W.U?|{spӇcx{GNBq̆痃5C:I.NJT!36Iy*Yao:{x ɕFr:F2֭2P4Qi2ܡB5} n;8+V pgoE1Ѯ(`ץ\ a&KZ]0K?/pξKTިPOOepN>숿PKSF^䦁.IPython/frontend/core/display_trap/__init__.pye10 E[+ 1 X-%"qAE]%E@M[q1 *V9}^0^V8I7 @h<P[G1txQhnڛsϏVo;9PPKSFəb(IPython/frontend/core/magics/__init__.pyj0E @# $]"YvDmIH24ߑGU'+9ct-(:YAi![/CZ*Nt/bS\/*\[nY-[M|t~׊@Jȸ.sULIUƹ1 |0VpEqNTta8!3kRޅ+P(̡=41ϐi =KkPGrRV88ꖎPbkb0Bsi #@Jx-GHaoXFp@RtKegluK @cch4[&Sk1nQoK4k(}ZهClp"_PKSFD$.IPython/frontend/core/magics/basic/__init__.pyJ0yv"*xXԓidL²ooڲtA<|~|m3 З\ 8.FEO@x  fp %`̢5'sxkvfm~T22)T]ŌqJLz`2eĸ4\\w-OBM޻0_ XP 4z5Rs KG.AG64 97 ey&;nJ͓8{Fn'swNժơ~jdj ^Z*</ƃy]^3`Sjƻ_qk/PKSFl}3IPython/frontend/core/magics/deprecated/__init__.py; 0 @wBcrB-[wa9,߿Cc=f$ C0ܪ(6Eտ/6;;)~eO_p7am4 6>bWޭ++xԭPKSF3G[2IPython/frontend/core/magics/extension/__init__.py0 EwE f+ NDIS^{|l9Gh[mLǒ>N>'y\{mOQ;oy 0 Zg$:i(U/&ӽWnt mD;Z3Z/PKSF(,IPython/frontend/core/magics/osm/__init__.pyJ1y=*x( IdH$'oo6ҲRK)4PU$m)z4cmJ֏`xx:ʞBTgl"RD#2O6LKJ#^KTJv`)az`A#cJK̼ci^9_朚*^72ΫAsz2܉2![ӱ>L0XAFZvSgև,+_ݪq,Ci%<9y|{wė&PKSF``_.IPython/frontend/core/magics/pylab/__init__.pyj@}$C\ 0Hgr>Co EiR7%a"4.\U F@:85MJ焧ڵD}v:whK5)8MZu}Lުk|*fc$V_5i63տ F_bF}3π۪(<Yxů&~$.wnKoPKSF}ޯ0IPython/frontend/core/magics/display/__init__.py 0 }W6145JYkKZRSY8zG{CLtQlY'MjTB{-qeX7YCX"iVqu`4L^(Iv)(ܵmHb`?}VP7|a}1g4wqٴ PKSFuH2IPython/frontend/core/magics/execution/__init__.pyMo0 %ۀ;֝Pd"E-˿|`'/_>I=Q"#@kFO,g$N!5>Nاi:5mS:=t1/#N{}V6̸-bG-DPi޷>|noEQ|BҥK:aKc-mr .F ^HZcVxmDw2߄L|PKSFpB'@-IPython/frontend/core/magics/code/__init__.pyQMO1W H o&dLӴkC۩)޲R⩙5mK)̙@M$A AQo,fVRW ֥Q5jvQ&=ᗉ:eǓ/0a& eOPِ"h 846\RT%m^uVv*U566J!UR_rxUY}[4*nr#&]yc 0Ź "T_݂*YW-~ĖƜF 895e}B,MW* ֤~i_,*(ВMk)1 )ZSDe9Q`L) 0x8*HBYҔٔ?c3τlLv|~AW/^K{R.bGr]P,rnʇoA 5C͸H{i[;^Cow/mq ßj }B_PKSF"A+/IPython/frontend/core/magics/config/__init__.py0 EwEl`DyI4UQ`‹u+)(DUQqI±6MVHupi!$꼓i vlFAAu)#Nn{e'~OTnĥгwYnڗ(uѯPKSF#g-IPython/frontend/core/magics/auto/__init__.py;0 w"#\RvBܿ& ug!U+ dVW8$5`nzp!~B"6 Qe D>e7pbi 4Y͕O׸}PKSF_ &#0IPython/frontend/core/magics/logging/__init__.py 0 Dw ];5[waňReJC ٪Eܻ;iV`Vt3,+q2ϫu0 tNIi,;摊:wR' svspƴFJ +eݔ'Cg nr b-nu[r9.7h{6JCpاLexuc9>4Pzg= n 3 Jt[(30JNP [YF{!WEwYp[)EDDpN̍6<G$9]QSbŔVR IоYk1!&ހqqMw cLF_U*5cAc ]'J]GS5Ԑ;Nb0dg־m~/$ X@j ڋ%c5X+ح&\FTp'`›Nwc5cGNw6z+ 0o;]:-.Y6w礊 PKSF@)IPython/frontend/core/ultratb/__init__.pyo0W &4/Ӥ>H-TMe X$>Ͼhd΁6-bO(gߑa Q68"׵EGuSHNUY>`NmvE!kKk4tGS*e, V {Msbq+?sZ0ظ{QX[I=٩%e flI@?DP6\d >]-I RmDHKt~7sMQMq b]w[ǖp&)жX4gp*UkSb-(z{^UawOxEΎSw7=Ev-P}Iƴ{ᨵEOJk'=>}{^˔+`7ied:G|ɲdn 3}rh),=:ӫm%ۅ6%ᙧ|5$W _npPKSF^3H5 )IPython/frontend/core/prompts/__init__.pyV[o0}WaSZijZZiSFR)ZMU7Y&pq¯sq9 ݞs|RChL<'B*/+m呢+HzH0!1OwUJ ~Uk2EYzTo^.h.^}ksK'>UY5k%I)٣ I*+bZכ\ @Wk5ͅlgM㣸̳I1N@{7ʽ:}.[QE +G:Θ #H-щ' \76;t8[h\9"&;Iaϑ M`hv7>9t<~Bpmz]O ;2O절{m? ĺ>([ f)vʗ)co/}#V6-7W~I X὆N-tBg8XbŠJ'3d"/1  uRsh.NJI ˍphJ<]C㸀7q.L` SAY8k-4E+@Xzr<34T #kMAz/)5^i`24phCz7yJO' BEڤ3SbR\ 黜@Y޹˃mK{nˀ@j$8ۍ*IKnha `kN]J+]VLGSBw-6 7ot@G`m6厹akKP5(z/Syz hm}Vmϗ}/Ǥ@aWgN#ȢQV4OTUsJ쓧/PKSF'cql"\'IPython/frontend/core/usage/__init__.py\sƵbD#R%)KTQ~ݴczHX@,9(َ{{~-gwne&^v21pem2kzu;sr0yIܹSF5'CL&?oG+H diUܹy,s[N+@~~N?:J;o?6Qq6YW4?y8\V+eD[:&͍yTS-m^h]UTY\14L'ƭk?0&V4aZJW50Ԗ&v<]Hn$Ȭ-^ټh1U\E=0XWDʤsqkvB}ɡG4imLn1䍙S&1.![ Z6"DCDFY) -xtYFUJ`!A%d$١m%t#󔖪|Byn6b#F5a0re*:3#٘L1C^Y43uCϯMo-HZJX,[90 HVDQE3b4b,I;71ŐN358$OIHEM1ے9w:9м Ldv{"@K,,¡ߐ:!)Ҙ~^zIHPb;^wY6fڵQ>#چ5j CoY&s1 mfS:kPFi6P: gX$_哃@:am^~4OUDr٥5Ǐ],Has[CxtJf"aq=29iEYXOSBM ㎏= c!q%f CAZc7y3 R{A~edPFYmֆI@ 9Gm8l t'6LKc}s)KS Y3Ua'=%e (J$Cɑ BjbEӛ/x?k+Y0!K`u]x\8`qWmjg#hOu菣oLO+wiѽsͻg'iSXbSe3_J0AdillcuiEsF"_8?5(]f7HK[^ʸypD`w!n# ~$Z*7J;v*5ь63S_|`xOu]F-wT?ʮ ʔ~ R`r%$uqo( F " Bؘ6@oO.YQ {:6ngkW [3BM\b9=F\y%dw=a.23=__+ =!!‘:HMFK:_t x$ \Xd Z|rMJ*1jkFR@o]n (Dۂ4ENX"d v>OVgC`ܺ vLR c˦D<:݂+[*Nt-jtrO`n-B^~ZKYii]BU蟥SE6 121-㲤SWP-ݚSdil"@B5H)JpԜnf))Ufp`y`\ˆX WkUPYbf\FVbA^FǼᤊ۠UjE i& ([óׯ +'fh|뀌NBhT1)" BkDD|ֆg\FD,%8! 9aH;N_w{X5u uy#byؕ,hf (8 ( TEy=gfNUWl\B~"H ޽|lN0NS>J _֪uړ?>gpl@3OCpeek'&.ocŒ{C(a8J{+m3 N4T84X9Q \ fEe" @UeZU&JWiLyaVйp3G5m떞x=#,BZ WM$'uWrYx9x֔ZK^IX 앪h! 9di SVkH]Edab!УЌ_:AIO hi1xի'ȺCAFٖNȥ ,;[jY(T@tп+cJ+a[(70׵k`u,%g !X+qs%Y0OXO{t2`p~xK>]֜rWzJrU{Amq crGD)98 AHX5[@|^EFqUhz]"a9~Sp/E49G:9g{B`~ & Zm >e?ύnWx[a%J" =8OV< Е-v VS691BG~fh^[{l8tzl4O%ĕ!e5oAתW%VSV< ڲJصJ( cʃkyai?#e5t͹1%#Xm +qPSo @#3P+,@VucL@[.@rCK+0NAHam;V41&fA#YZi{%.h(2T$fXx7]bR}5y',0PR {VjU S98$]ka'!RaSt :.cٝZAT_&NCzEN\,ZS)*y0_""cE)?3 *  Ul [@(pGl+a)9HW)%mb:E~F,b($)½ e-\]HRܒ%n<|qH.@H׾Ve߳+r{9ۛc'wQiRˣ>+aqeF3IUc^T+]Sћ])fp9S%"#aّ&GXl׆D̑P$-fa''KJpK)Ny}RQEd- =&8dⵧGWm3rSe 97ہ^I4Zgro-sP-&U=)E,9)Tr"fgjq.$o/_qV6t5ML_6 t :3MDqFKFZF\8os=0|[h\Pp$NTkZtd:vd^C wN^yg/eHڐ?wUrjsU/H &#?@ZeCDM Ĕ(lso Z[ˆZuq%KI iSdJqKI +bM)-qЮy(\w7dg=NI=G V YJdjVG!?+q8z ϯI_D6sfJNZZگuiA; (@n}ׁaΑ6_eR a.x!#M e]HEwTЦK6jZQ%>W$:oq"l]0eB"qmU9a-9-@ ڏ/no^rupqZQrIcb f2a&l;g'˭g /n.Rw Z@v*k GZw-4 M<<5{|7ރs|ܸ 0o:7 I_}_^K!ٞ-1jV^3Ҁxwx6#ҀyGޝ;Vpoa ?ۈ<\7#VSELJj{OALlk W=iץ|S.; 7Vʈu&~${`,OcΡ7 sK]6AƷp9"A#xU5J^dȅBL$ twg+rG7 [:yFfMF\X*.әq+ٛ<9(Yj 3hEJ<MQCv$\`<{ 9;*^(rr T"}bv{Lޕni_iX%/YB:RNb{޿O{e=MEǝk<흨z#USǸKJ{L&Ussi b "Y]n휸@` R%xUIFIG 6z G8eo^=[0`:NXh-ߤ Zubb|՜(͜KИ:rG!9:ZSlyG$NUA 0P %!Eo4?_M1<y^nAka[IB7}lv;OcF#T@DF#wEtibc;+&HP,qʭg'ikDy 6 Hu8vՈYOOG>~fWɈ=WؒC PQq~.yp{_IG "%EYͬRx fiƉFރԀYnk &g0}~6459dgj5A6slqy_$cA버`AMao脮)JDA> %%d8 ^gj:2PZ6=o/x|.PrNHWgE*lܯW=4\l4=lX( օ8>"'Fqu>w¡:hw;‘dAHC+MRqS8@aͣ_ l@WGWvn{DѾ[k,FA1D'{_af{#QAJC}֟/E;/:A[Vpj {(כmm05C~够 L%I.YnвxMWri[&L@yOsV-3mR "s3Fs:خ@}N^g~&r^rn _7MX9 y 3KVT{׉w+}y2RЊ( b %ְ_VTJB%=Z֩\k:t˶t>#x#+n^$m62Tsp9[N^o5S%HK5 KoF6"6`0DUΗ0d!Q#]>Q5 烫A>nZɝX?yH pHmi4)!LW&H,dd(,J5h{}^0/I(T. )IK& qan7ncTp24GlV[u\Ryj3}DU}NSPS h*A_p2W]MDtoOSէרI*Ir閞XˆgpKdnw]؜So+*A5!2;2XqAw(ۑI .z-vJKS4!ph3 t$G<"$*j/ǯ"ND<+ Ea#Ҡu Rџ*8KG7#N|qq MV ]҂J7=+]jf,a8o1'@ʴk+7Wl^=}i>o38* $JKF9%oJ\FCV:w)ͅ5k2pe)/,^9៿&q@J-תVLw[GKޣvmn4YQTPȧOڎD |s Z`z =}5v%[| s}/xWXC QW%g }bI _~)zwp䙂sfׄ|l`ʹQ*\TC hXŌ5C!e.2i>ԫgL` w𔔥?+?Alp?=<|"=3vrP'Ud+[:qyG隇|P<\2uٗ-*{=$c U Ag 1 u3;Z>o[i{0!jXhǕo2L*Zd$X[$%&|,Ikրގohؤ{qʄfZr'w|ᇜ>֒1m)23<`gF6(\K@u /ۚviѰtmN>JJ:dEhye;,I&霥p*W*Ɵ}a0 ?oOsP5qOV?zza=08yZ ?[[TUDӊP.ƀM q?NO\i䩈 | '9~'g_es3k3lfǟ]/0C=/L%"xX?6)*dR1bhZ 7甆|:wn}y/$ԗ{4yĂI9&tmW[O M$M[9$Mz-.ξds5Q?>Z|>` H 71 9]sĮ 2MI]9'鉖Q16W hTf7K{\M0]@oOy2IK𖀠fό<=|o*~0jZ/KFXn\hT_fvmc4B^&z@"ҒwHm{c(t|׳$8EAODJ*]\OD~" 3զ} IJCȏzJK;3O|$}K_;|w>p{Zv h9'鷇 =.7~Eg؉Zi$?26G[㿓0#zOeoi1Jsa):Cu #ˆ*WY&P م?^PtI'DV޴5/۰]edB5׊w)8͑BVZ^q|#7Ȯk^Kw̰ߖcMog2V |;wPKSFۘ,IPython/frontend/core/extensions/__init__.pyu1 0'qp(:LBr)7V o#*劔dB?FN1ynF6MP}x8,>apS^v?3Jҏ`۵뎀ksR{zMzw,DOYFӂ6/PKSF`l],IPython/frontend/core/historyapp/__init__.pyR;O0+nK+AĆB:V΅X8/{郾H{M(GR L|d8l+y#E|M8űI08N&jAʹd[[1Ȩkq[L 7UU94Y Ps֮A ezAp;_:D 5Zokh%Xn7I(&xy0;ʣ؎ @'a5Umm\YSe+/EX'X0E/$H:~9CoI'v4a`]oY5zl.$f1PKSF'X,IPython/frontend/core/compilerop/__init__.py]= ཿn~GMLtA"pA7A oAB>NE$Umʒ~P!{.UkuN+{@591e:9GI|*m;"ӤX˦6xJ+E:H!W~ ۶{F6(=KA֣ѡ^2!okJiW4ٳ@]Uo,^P *f`u pWZDCr@'1ޡތku;w4p =aprr0Ҹt!M7!>u> &y kv >MK2Sew1_UX>%ʮziyܨƹstEcY)bB9}Ui͆H/M:n073$QVvs?v!PJ[?PXf=,i~_8X#zf Lϭ=>4o%9JEnBP}{ >,|kC7W[8hl/]PKSF:['2IPython/frontend/core/inputtransformer/__init__.py]k0+܋JliUBUNY$vj9=_:yQUJȮvBR^ie\ d+BTء xH oXg한֎ ;=Ee/%u9I$/ȟ_E^z -1q.T)X4 IILH p6hTiLߢZp* UGhՐ5h+59g)]t(u@*@ŵ2aT*͂#,AH0T$D5Tq}0Dm5Kd*78?ղ3=_e_,<̿- Č:=Ԃ痧Mm/-)ʃ yƣh-hz6+/\4Gf }D<ڵCBhDic;e*0㰻$M5B$wte{ `,~ư]WzVaVuX{M˧xsƨQ:}?$O?PKSF;m(IPython/frontend/core/logger/__init__.pyUA0 ~DM6r*FCfؽ&š+̹W+#σwiǓ?Dfjn^451Q )m~svPKSF@s,IPython/frontend/core/pylabtools/__init__.pymnC! ڱRl>EAV 0Un7RX,skNw RE);̋])Y}5_t8.դ_+JY"]Fb :md.MFZ/{F8#Ywң lScY(k DHGyE!o+|zI_iѶfN`;vSPKSFO/IPython/frontend/core/inputsplitter/__init__.pyKk@!8B)6<9X^/vW1,{Nz.b~y3U9(ƅ:Q̓0X^Od9[<J"H $HџyVCg*WCjrӂ3R^d2`)P9Q iwpY=gqL7ٸ-vPS%Tݠ$4)Z?+#eJ2agC:+rN3YF{H)8*yʼ#v9=\Vdtz\iF4GrzD9K oRS泾+}'P[)B@wOp{_%zW'% E ~2pr2 O+#M8F~mBNu!Xf'Fh}q4?(V44M'7<(tZPKSFgDd6H*IPython/frontend/core/shadowns/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF9" .IPython/frontend/core/completerlib/__init__.pyu?o0w U+u! jCSpj=%O_C@ v{g$@)ŀ$#OzE&xѝ].Rjp)ZCu\42^ '.cl|ĞHm:1͆ݸ.ʒP3SԊM` fg5{&C0Y/5 lh^c'ung):iL=kFƱƴ^ntmQhIIؿ#_`qMzh|PKSFXaQ'IPython/frontend/core/magic/__init__.pyTQk0~8 1PXv]fOP/%#BnܸN:Xt)w!&4U2Q#&ۨʇ}XGXe|M2ttcJkf:cs:Zp+$IRBI~rQ5֙p%@Ɏ_ܵl$G܉>;ƌh 7{D2 $"sH]Cz|nJx 50wvݝP <}|ZYӯI A) %0mnSQ%Zۭo5t4>[5HG`h._#Q%bkF9l6z{t}a[*YvN+124[9yֆ!*trf{ƃWk= yP3&7ԞW&tN&4i/VVmO^Yqt*Z0v3jv޶Mƹ/bVʯݥy 92ςKПZG1b;o c -ѯp]pͱ. dh˥W+\h/PKSFQRg*IPython/frontend/core/debugger/__init__.pyKo0ޠ$#TQʳb*)BSrl1N:Bd*ؕQ DVAmtAq%AչEkE;SB~4`&Byvh]w\؝݇&uHQ߱|+kJQH\mEpΆ: vFcuvJH^p&T[!-=wvktxSˈ]TqP۱\r\RFBJw5=;ŝˢH+c9g-wnܱmEM7!>O.㚖0l-<tA˼3Bj)3qH0,k55pJsrPgb3N(qHKBYuUKHu{pv'O>^\~=~sasG7܎ %S vn=:%& khfXyfst!W\j00s7sPKSF$5S# .IPython/frontend/core/crashhandler/__init__.pyVMk$7ϯ(x|71$!$ !PwWw+VKB"bMcyPK޳ a͠ ceyRI(͔@ͱ_ iuR銧7E65[a5LAHe~Fs\X†~75Y`ބO*}K_~@벢\LkA Bf]ϲd6gktX/Y[rA,Z h|ɻ$<"]!Dj1[7cGQ6gy\O]Qr0c9Nn]*Av_#/A= GUUF+PKSFgDd6H$IPython/frontend/scripts/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF7ox F%IPython/frontend/external/__init__.pyMn0=TAEʲO$z NTɰy!͍oZ+$VgIehuPPud^P>E_I3骵P\WyOߊ,alHGU~6DkA o:)]Xh[.zK.po![]Sr ré4%#C<-x? #LC&N:45{BuplR>]wG&OZlPKSFs@ҽ1IPython/frontend/external/jsonpointer/__init__.pyu 0 y6AŽ"a [SLOo6lߗ?U Vm<1>X'R,;: ^";*S0}0blO9tV;eԩ:dӂdiE9.60PN8aDW,4+hݭeEe]hzSpc_ʺ+ϵ/PKSF>>IPython/frontend/external/jsonpointer/_jsonpointer/__init__.pyu 0 y޶]D&E|0JA6m?I3mp%fꬲ8hG{ x Nb o8<9Ҝr j (aEAr$@=/̗צnv71cw:ѯ`(%?7PKSFty)IPython/frontend/external/ssh/__init__.py10 E"[@BA!j5"+Q{)i_!-Ģ(5Q*lG)O<:d[fB[1u/qC9`E1d_5YPKSF@1IPython/frontend/external/ssh/forward/__init__.pyeN1E I  - Z ?q.8ʾrVbڙ]*Kcu F뤩U[w;:N!=.G9Z)&yϮ$yD F#iґLًɽagpn1iI/)_.ԅ/`; JL> 黓( %'}uYí؛! PKSF'Yyo0IPython/frontend/external/ssh/tunnel/__init__.py}QAn0T=T^U++YZ D!dyf<;3`?`}&Q3[=Mc^j4U7xQ![}g5kc $Ǯ'bPˈ&.vCSD\s9'IƔKҗ JI^loEVrJ6G d s`f˽_Fa=`Fm;U5Ώ{Me HZ˸*J<5[L 'w'- `퉛C{rdPQG[%RP{/ɷܷښTf4Z/&jrw5 ·B,FM]bsuGo~M.EQ6e&K0ú .}AQ7H;Egw:{OSPKSF~0C-<IPython/frontend/external/jsonschema/_jsonschema/__init__.pyK0+rvPCa1'ɬe/7,Bޗ+a),*tH,iˁڌ5ڤhA4hbgA@Ť,*…TyHGX5FW vDkֿc\£ӫ7tiړp ӫpAx KQ\N(hhPs‹~bJWgn=nSYFE+E* 'ǦP/PKSF>-IPython/frontend/external/mathjax/__init__.py=n0 w›S9@݋Pf?PNG E #@G>E.14X԰|jd8cw&}/us7{9rRʎhϐ}ʫ+ Sbod658xC&@ېFP=: ZX9:=`8UKQOyBg\뀮 Y^ט GUPKSFt*IPython/frontend/external/path/__init__.py5K ! ";gxBH5f`z_+);(|̩0%>p xoB̚wZ䈋='R-DlɶՈ +oO9kLеBg˘Y~PKSFA?ܜF0IPython/frontend/external/path/_path/__init__.pye; 0D{b;M C.R(d jG1Hdyz `\ HxK23\){{2LJ&viɥD نgt-cOeLFV]@o\1_ S^H (:o炙1kvjQ}PKSF0IPython/frontend/external/decorators/__init__.py1n0 EwBtP S`Ho_9AQ;O)p-@tbq,%1 Wj~\1У4SsKmѯL]%E;Vdr6͋][R=}4`,('{cz,)k噂~_ DP{vӋl!;}egG^X[j@HPKSF*rEIPython/frontend/external/decorators/_numpy_testing_utils/__init__.pye10 {%|{V%(FߟQ ۝,"Q^lD&] 4|X%$FkV|`t՝o@?'9pJ=?PKSF<IPython/frontend/external/decorators/_decorators/__init__.py]10 Ew#\R1,#T)ޓCH!%c1QoTKVHW~0GryaX5HVRo*;U?pmIK@ܨV|n"mlPKSF/ذ/IPython/frontend/external/decorator/__init__.pye 0D{k z<,!M14Mv UqLiD~1'5Z)BdrPlb#)oHU])ꒌbMGПpå"Is_jXzբ fؚZq\fʆśPKSFȼfޘ:IPython/frontend/external/decorator/_decorator/__init__.pyu 0 Dw}$Knlm|1LJ_'mP*Mr\P)ʤ%EL5q1=RK4Pcpp)j:HPKSF@p3IPython/frontend/external/simplegeneric/__init__.py]NK 1 u ."Aj62ۛ*cvӢujnj,G͍!UW{8.t%&э ~wxq07+%CI\!~z]ɳG;m৭:gPKSFN1xBIPython/frontend/external/simplegeneric/_simplegeneric/__init__.pym;1 D{(U DSp{G[0y~l QэPJL4Rf_.X pceG]3^̴ ~Y=MyPKSFQFd'IPython/frontend/consoleapp/__init__.pyUj@}W̛CҗBh Ә$})e-mVb/v%,̞(&!E!@共 ȳ +7K fqr OsZYt:'̙mJ׶= ɠp;Ҙ)J6JEb>:C ZB}jNtVnZZވwVjmBզcu|#T!BP=t?l^}|qɿa4=l◢NYP6R|;s_gI> 4[Nti ,?vcJޘ'H%&p؇ i`9=*'ZssoS?PVʥEܩѻӧJ⛢(E.Re[J̣CUT5!ڱGStUE~klL*bV*RnH/9$E r]ͥS%ɸϸh_L^S57S_3Ir_ýTu: ;r/{uC+H68s 8"f2)?T p0PKSFSg%IPython/frontend/nbformat/__init__.py 0 {*`yA.#lhӑe޶sg)x `'H@,r1Ş]@asˇ! 6/V ‡ \$q#7Qy,r{k-Q溘4@ r@u~PKSFd8g(IPython/frontend/nbformat/v3/__init__.pyMn0]BtѪjd`(nChn/ +oD6M-!Gzx]b뵞W_%\C"=->I`et-BﲀoCL0ڋb R(GИeDkZt%ƔԩyhW-/DG(A*Wt T0Zsɯ)O9]?i8[;}g>}>6.Ӈ(kjq%PKSFNZ-r/IPython/frontend/nbformat/v3/nbbase/__init__.pyn0 Dw}x -@?!YҝP$,Mn6njN8gWQFs%[9ixTL2iSr Bb?3 Ne ROcJ[a@bze-/$x%T)$x4 $j /kO9LcY㓛&{~-26.S՝L*k"߫?B@QdJ|CSЏe|p4Jx:u8=㑐siڈCĮy+0l|H/=:|:w+!x}/V;=Nnvs_x˗؜sIr}PKSFG-IPython/frontend/nbformat/v3/nbpy/__init__.py}P=0 +2v## URؕܿ$P]+ds^%,@k/`}hYԶI#JN=*G`$ǥo(5mQ#X(3hsp a,[ܐB8b+sjXSb~rx9wS@y570sҵb E MPKSFA 6C8IPython/frontend/nbformat/v3/tests/test_nbpy/__init__.pyMo0 D{p24,EW4mvͅTlT$8]lza'|dZX1"cШXm.}ct""Ly؊$*=:KىMFgtR{U7;6gw q~5=Ni~1CN y*>ƐE.=ًj:/f!ScܻgǨQ%J9F!|z=WD7dS0ۻ<w`鹵|Y;F.0xrjW|ډ?[Ėi\&y>}zC⟀8epTEXݛ IRJ,'M/\+HV5B]md [<?Ё+'}KR?l EF~PKSF+=8IPython/frontend/nbformat/v3/tests/test_json/__init__.pyPOK0S vvR Sa}YIKu)jC! m$6Q;Ԩ]s- )z#`kH!;g+rl=iEX}{+Ƹ~)2ul}Dg>9~f~b(q%~5Gs=hZ'GkD{V"#3a{`q dHV+`L"VbEqDyLz7? /.~PKSFD6:IPython/frontend/nbformat/v3/tests/test_nbbase/__init__.pyŒ1o w d&CN9K,uD N,5 d*r(v bqfMPRYCQB䎼|AkjPhRU"C KF/9E"/)WǏ!&nEQA\}tB IKchLST %&9g< F+UuCG& pJ!זnҜ.Ms|mڦgRY PKSF(pr]9IPython/frontend/nbformat/v3/tests/formattest/__init__.pyR[k0~ϯ8:Սle0 !mOgHUZv|$'IjJ).yVŎkE%u tװ<gKiBtFZg]]Pj[DAE ȼ̧MXdIȷg;&\iI<{a|5Wsg>,Tj+{ UnU ~a]ȷ=<4XE}26R4Ff.UGL%ZvYVeC6 Bi=KU1E]ph= A0= B_'C/ܥ w_UXŧnwYT1:ji+Fg[P]8)+6UK3/_JaVQyiʦ.]P;frb|Kt&$' 休OKTݪjWim zQ^K,Q Q㣪ZTRA1a;e8}M®DC*4Nz^}LB9fn].K\Xd{i(AWCh `jGw];h$<ԺQmld21NJˊcã?&*98]P|zkq+Ƶ3l2 A?og*"wKВ!UuW߇9&SDHnAHYQ_<lf)sl/;@_PKSFo!(IPython/frontend/nbformat/v1/__init__.pyN0 EڑP%H,`Շ UNq_lr{$uԝtkZbHR)cWmiS2QguL4y~+S1*9<]{#1Npf32 od 73 FGtc`m~A.’N,&JJ~[ ,o[.%@}¸:Т{1lMұzz2ֶZr5:4PKSFn+/IPython/frontend/nbformat/v1/nbbase/__init__.pyN;0 s pJ=BYݢHIG5H.b"Ǫ0"(H$7n(4piK HYHμKy{#vB?}vlj{q4[؇ XQ*嗢J PKSF6./IPython/frontend/nbformat/v1/nbjson/__init__.py}10 Ec{$.D``4E4W\$P)o&@Y fb@KN 5WPMUu@OR"4KȽ<&co:n>BHLG48ISsNTW:r4笮PKSFfEp/IPython/frontend/nbformat/v1/rwbase/__init__.pym10 Ew#\RPMđcߐ {?$$ DS5,5;!t+N^NIE/^jʘ!z`JyiBr5D . +z$pk< 2*HpŚBK~zlzѵ\*R !gbXn [:VS|"b>. rGx&/eL~oPKSFr~9IPython/frontend/nbformat/v1/tests/nbexamples/__init__.pye=0 w#l+enAHIG5z?U2T*V7ztOwI^ɛq $2_}.˂ ib=cF }_PKSFiRj0IPython/frontend/nbformat/v1/convert/__init__.py5 0{C83mJ$h:w_>r@ "T_peӻx`N,PKSFDY(IPython/frontend/nbformat/v2/__init__.pyn0 <Ri>vmFe 1JLi~&DB/ĵ6{-Mۑ崳aLR$%IS ;>B&a4Unl8sV8>}sLLQ({S"~}1<=bozJkD"cnfct| MHdL'IT/lLKJ:.ȪRbn ƜzP;?d$:eBh4uŢ`ٶN+= 'i\HֵPD6DCgOq+syz|i'5yҚ~PKSF# 矮/IPython/frontend/nbformat/v2/nbbase/__init__.py10 E"c{$@حj$R[J%0ΐ)hAX2he)ȅFˎ6W ;Aj;MTHzB@6aSHw$k)>P#돳R֛ylj{RZ{Zʚe=u,?PKSFP$/IPython/frontend/nbformat/v2/nbjson/__init__.py} 0 {'^1l]u[S ۛUvcRihp @ޢ#a6Hh&zOg.SeX^0z9M)hǸ֒bhzr>O:mԌ{BS64-`T8Xdu0t4yyL=xlJobüUcwr ŊG ZzPKSF׹.IPython/frontend/nbformat/v2/nbxml/__init__.pyun <*ۺTi! Nؑ(ۏdT?oC4ZYgl'b'L1h"4ݦ)w΅Y>1 =טh`ΩW |.s#iDA4/m0BiU þ19Bsu+uB'@qc}}-@xƼm!5& ^ľ߶_9lX;nz礏UG6?PKSF$8 -IPython/frontend/nbformat/v2/nbpy/__init__.py}M@ sYL\7.N))%FI{kL(:b ['^uF,9U&S}tr랐2Ά0JR0f9r$l%G!HATuz}!ԈTZN_QR)՗?=(.{uO3@[KPKSFϭ/IPython/frontend/nbformat/v2/rwbase/__init__.pym wݍ㥥Ws8KۘR6K#; 0f4QtPoثq\|e+d#p%몛VKx><Ś&) ^[5-f0OJ{/E [ \Jۥ,3Oۋ:[UHrT}PKSF&C(.IPython/frontend/nbformat/v2/tests/__init__.py0>E741ywc.XwM{y{h"g#y `[n,CtYŚ6`!PGCc,`ݡ MdgRVI-6'4.qy,ZY&$uBPA ň{PKSF-Q8IPython/frontend/nbformat/v2/tests/test_nbpy/__init__.pyQKk@W,xP C)b 7EУĄ#nQ\v{|;ItAY& m+L*rVAҨ򋀯!8ף1XH#PAwxrJܦKvdo ŋM&e8gK&٫[CxR'O[-K d!жBثݎ*eQǺRf_̀i` }}7M=O-: HlݮzMQ<` BP&hΔxqкo}FEWK\8K]jЦZxb6ΈZWh-#p!׽ɛ?PKSFS,|8IPython/frontend/nbformat/v2/tests/test_json/__init__.py= 0VvBuhK&o9yjʘX1*>P 1HkȖ+.$W[OO/BFNIy bY!R-W)Rfϰ5c!yj߮PKSF$:IPython/frontend/nbformat/v2/tests/test_nbbase/__init__.pyR=k0+4&[M@lCGqϱ3 И̵C]kc91=E}l ,T=Nr:I?PKSFdJ9IPython/frontend/nbformat/v2/tests/nbexamples/__init__.pymR]K0}ﯸ6a:E& 2Y$77&YkY_s{[XTXYAK`NguF;IU _^=HmVsIa.*&?ǼʏzPl5d˄ÂsN|k$A,<:2,Nhj+D{I5"=ݼ<7kG1&3m`z>Əem` zSUZږ *So-<4\)NuvN+nk}du˭)0hrWc|5MN<\}v?Jߛf\&yUAڭ(8<0ƥN$PKSFw0IPython/frontend/nbformat/v2/convert/__init__.pymA0C=EzH:擊p\f%QHnl" 8y1%X;U ՄM P¾b] !.pWI:@ᘣqj?7',aU^PKSF.y&IPython/frontend/nbconvert/__init__.pyn0yީ,dKtYw ZN[jPS(YJ(%R+.U")l_SdgQ:_G{8bK1kX~:k}6؂m!Dz?PSvBUXfS2*Sǃ<)\ ѝWBv hdδc^T WM%M$׌pr)PD# N܌5Ch!XYN2( ]HUmV;o#6fB[q^Dhf|PU쎓7p~Dr7&"#z#=z=ef@[|E%I^fZU{Y<'ԨoX)%_vlm6a(iwd(~Pcl=NPKSF$Rs>0IPython/frontend/nbconvert/exporters/__init__.pyj0Sa,lPGY{7FW&w!wk%;X=8cz(6,!bN\5BXpb=\T+q, V~hX$tm BU/1H[ NBhWs%D wC"kQCZH4tT\]3rkbHuBY4 ;^(:S77ifuYc̽ŁERt3(NL(QQJ> lklj,ܳ/qPKSFM<9IPython/frontend/nbconvert/exporters/markdown/__init__.py10 [ H(uP$2wA8bڅ!ʢP%x\Lث~9bɵHN<_ @''̯򯻗y_ 0Sp=)>]WK`TZuaPKSF5-U7IPython/frontend/nbconvert/exporters/slides/__init__.pyAj1 E>vNJ] %PSS4rHo'CC[(N}#%SyD &l]hYإke8g&ё¦/1?|ڻQDjfץ%WtsjGᔏ[r|#wG;B{G.'z+=~#ð*8R>_ҚSτa{ifH??RaxW,mz[1)K&R a>nz$ j e\: 4E|'No4e8e#w ͇L!> 8v M<|ܣVBY K_x NA!'uhk3.ZћG"˟ܚlo}BMֵ21zaڡmXr銼FvPRyi)nDc?F~ l:;^濹+ݍc N梟Q$?IuR&cFY#-1 W?P ra_PKSFC76IPython/frontend/nbconvert/exporters/tests/__init__.pyM0;41paޘvJ?Pj ]}Y#z ,AWXLencA'I܁< ڥkoKxb ϡ$c'uz8.x]l!=<}0]1,=`)GQirjKʈYQ~FFa{PKSFDIPython/frontend/nbconvert/exporters/tests/test_exporter/__init__.py 0 E|v+PGLnL"'e,ڤsĽ*!BB꺨j,uUMZu:#6"2A:V,bOG$EsN^9ȑ8Zj=\1^+Վy$AU*CnhY[9CNC7PKSF0yY=IPython/frontend/nbconvert/exporters/tests/cheese/__init__.py}1 St+:7(-)p 4"ڌ!V![_ 58*i' /i^ %eusPKSFƵuBQ;IPython/frontend/nbconvert/exporters/tests/base/__init__.pyα =Ol6 ]J-S$g"UO<y@ߠ.NHER0&O Jpz@&*"3H#P"io-XyP,AfFm.=w\XDj ]NPKSF<쒦xDIPython/frontend/nbconvert/exporters/tests/test_markdown/__init__.py 0@~ō ['^$r)M qq2ˑ{@PK\ z |.&WͲEmTF2}wȑqis'?680f6h) Od2h$`ȍ-2?t+[:PZ^|/'rYPKSFDHBIPython/frontend/nbconvert/exporters/tests/test_export/__init__.py=k0w mB /% tH)4[)B϶>ݙ:]CҸkGϣ{Re-RҸ& M,$}<e@YfqȈJ/og_Nxyq'Qg)L sqrN:fH^fggbi<Ϡfc u%k KPoqIj"lרo&> )(܈tbzM)ՠN E|q-A S`{^= .tM{S&5 6PKSF tBIPython/frontend/nbconvert/exporters/tests/test_python/__init__.pyα 0Oqn"VB{iI.RooRYB*!BBQԪ,DU9p]r;gɸYX$%V88MƜ Zn 4uoR`ȍ-2?% dwؕWȕ&6}PKSF 6IPython/frontend/nbconvert/exporters/latex/__init__.pyJ1ye ($/ i`vfI&}n]|~ pI+R?pJ"Q$&TcĔ% ke\>iI[tE9{#**7;F.`+Gvi|v=SLn+0>ǷCrtO QdԶ*[s镒]Bt- Nq6koh.mWPKSFcB4IPython/frontend/nbconvert/exporters/rst/__init__.py;1 D] HTOmEdeQA{|¢@Bf *cV"P.RJ%N+ ZSf=4A8ҸYvgJ{_Prc2o 0ZR|Y)q0k'A{ahyPKSF fVD7IPython/frontend/nbconvert/exporters/export/__init__.pyMn F]+TꪉEUqb0hrr?=LIe[!x-*Cjаr4zDG#Z cN-!u>OHHH%v&?1zuMU[p?L. t$"_cL59A;|0mHLO`//nyvN; HIٴwAww8iB¨rjagXh۰mPKSF35IPython/frontend/nbconvert/exporters/html/__init__.pyJC1y٥]A.t%eiR\&Ҿ{E.ss' 6IPEaBjUZ\}S T3K҂&q柶g}gZ[d:&w%+U. +\ VRN~I7 [(5p ]Kjzyn}CGܼ4hڡ PKSFP!7IPython/frontend/nbconvert/exporters/python/__init__.py! @w &&. @@ gn}uhT1 KJzzNTM\BxlN[[`,|i ` If|, *M5rYu kܬ1/PKSF7 SQ3IPython/frontend/nbconvert/transformers/__init__.py?o0w oTe`ԖR TTPmD}8Cy̻wgΥQ-e3[ RmjNk%I\_qp(36lRp=A yJ`K[*ӂoQnjIP>gD(ހ`om&@IŐ e}r"?f&5immS?M3Iŵ T3F\^.97Gq {5:~ =X]29_5>Xc~=!{CN}[Kv~^J(˸#>}_)ܔFwr3Lg_PKSF٨J8IPython/frontend/nbconvert/transformers/base/__init__.pye10 E[ H,Eb=r#E$v8UU) x*B͚R*jjbsʋ%!VӅcd&|:eXzSĖ-l+9O%lD^oMX鷵K/EQ+_PKSF=8BIPython/frontend/nbconvert/transformers/convertfigures/__init__.py 1 >E+NΥң&G>̖@p!(,RHRf5N]7[>´v%R, ǓXLPTOLXF e/5#O?w PKSF >IPython/frontend/nbconvert/transformers/revealhelp/__init__.pyϱB! НѹixR/y98٭*㰡4QLk$U y.nw)8RQV?86An5YX8ȆOʃ_6O0>mrνPKSFl}m;IPython/frontend/nbconvert/transformers/svg2pdf/__init__.pyAK1m{1 AV(^CΖLLm-`n̼IKkk…Z:Q,n0HgPٸ wdMJT/U.D!_Õ\fud2uJ]n%egܸ #Cl!c!ylB4ᇩfxv3"@c: fq%y 4E~q BJT!hx܁T3$7PKSFKYCIPython/frontend/nbconvert/transformers/coalescestreams/__init__.pyMA c>o"HՄ$RvgryP G}ppH(2k<^SrdH`PKSF"e 9IPython/frontend/nbconvert/transformers/latex/__init__.py} 0 @ܶ}HJŶi&vsxL%)RnR@,8ORɈn"*Cb9cWoT]ORjSo(-KxTYs./ >S.8 }sƽ8NGl4[@ xPKSF]dAIPython/frontend/nbconvert/transformers/extractoutput/__init__.py?OC1 w oyPRGC;!d4$b}{ZQLwɺ8#Qڛ'˜+7b #ٽt?@/j7Mq7.1L \Rt] ܲoӑ\bܙ+>؞>l~<Ӎn,IaXk#OPKSF~$v =:IPython/frontend/nbconvert/transformers/sphinx/__init__.pyAK0  Â`A$mMgJ2YJ=yyu˔ZaHrU#7K@?E!arόuPCF39dhc'0-g3pˠ=LNOk &%I )G39K ɲ&{-K(#[~l v40-PhhX;-fsa612D1r[]4+9o)isoPKSF= AIPython/frontend/nbconvert/transformers/csshtmlheader/__init__.pyJ1s $  ]O"!&6dB2}{'[V^<?+Qk׸50KfTcQ@6| \kt }c@jmv੟A"տ `V|8׎/=$5[М6H"DUWhRq(wSҡ;2zqֻ{)WGE*mHE,ՓF#>WI$Iנ?ϸ8ՇyMf.ѩ-#ڟrЙGH<.G5Ad0)`S[%F5HW>mIMۖ0*^r©Aޜ+ݲFSQ"3u!"Fc0:Q_ Hj*򤌂 2pZ{cdĹ3T!=Y RSeW9(^x|i9<BvPKSF#̑q7IPython/frontend/nbconvert/filters/markdown/__init__.pym1 {2n y c}w86"vf hB"DL,jDғ4k^gjʶUq7ϟyحϭ-Ov~&9 ;sG]9PKSFF#3IPython/frontend/nbconvert/filters/ansi/__init__.pym 0 }޺}A.h]mJZc )l4D,:1FYi)*jo5(5'bF= 3CCyNW,WJmHU]~{R۔1^, ڋyPKSFrnf=IPython/frontend/nbconvert/filters/datatypefilter/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\XRYꖙSZViťPKr+K-*qJ,NTPKSFjy2!y4IPython/frontend/nbconvert/filters/tests/__init__.pyA E9PAERh"5cIin_kK;rvdjI:bHAŖJmSmiNRU$=@YZ<$voŇtĕ6$k4[A}`+hOͥ}t-"oU70~0aSӒ4䳈5dXQOO{_DzwdX ^PKSFmͭn?IPython/frontend/nbconvert/filters/tests/test_latex/__init__.py 0 }A"ɝBb&v" %$, )f)Yw6jh^?r:G>}A*Œ]2'4eJA,lV֩`5$K4=Se1e) 8?b'mK TVYPKSFosCIPython/frontend/nbconvert/filters/tests/test_highlight/__init__.py 0 }6ay/ES[?>Z,B}IT Z!xS? rasJh3kΚ#`="F+H]6\1\fIca7:i RN:ڦ w=C"PKSFjsfAIPython/frontend/nbconvert/filters/tests/test_strings/__init__.pyOK1u R^<&d7dBfwv={o&q6]Rc:XԲǤؾ}Q.Ju䯪1L+b8XB=O{YTR)eX©A6 >ՠ?ācX3\> GM[8#dCM!BΏ5}/6s%gSO J,H3{N|Iu޹P n6w[S"Cev|仿OPKSFJkHIPython/frontend/nbconvert/filters/tests/test_datatypefilter/__init__.py=@ _Q76&/ }Z$&GӴ:JYDJq1$< *Tb"3(ؽ#5 J :b-J$slX Z%ݔ`*s3_u^XPKSF;cxA>IPython/frontend/nbconvert/filters/tests/test_ansi/__init__.pyo +, Ժd\dYA"P}}{RpeykI P^ A%iZ4e[3dksH jpJKZe $1 *CkưɞmiyYa5 أ!xDl+=z%%䏞ײbQfهyM0TrkFnǨaV ݜv(`bb( CQXgi-pi-MثҀ(9f>z:UWAuAz l?(#ޮ/_>%vLio IT!X&i:DyXv A0YL_PKSFZ7Eq4IPython/frontend/nbconvert/filters/latex/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ` ЄI''$V "K2 sK2 Q@PKSF6IPython/frontend/nbconvert/filters/strings/__init__.pymQ=O0 +' F !+j]|qIZ9`i)Kf#[/մ\޾Pv.q}wz>Vu7ZMr|~RС3#Vڠ/G0~h)b 1d d&(Ƃ[Apq]అ W1$VsIF&]Z&XdR'_5c4#Q*vwJXFL&)aƙ3* PKSF78IPython/frontend/nbconvert/filters/highlight/__init__.pyMk0 Cрn˔_824~r:+?.Ǖ2JqbHc2)[4ZB{^ TM+nD<5?}c*NB ,m\=p>&嵃~@go+V#\Ao2Z=@ėFʻGy$AbCq 2\x2eXPi!xQMRL{_̀Cw _ѫn PKSFs,IPython/frontend/nbconvert/tests/__init__.py5 0Dܢ ~bfl޴ҹd٘ȗ:OVJBQqy.ХGc??&:J3ʘT6DpC&) -l~t{~PKSF:<1IPython/frontend/nbconvert/tests/base/__init__.pyAK1m JmB/Z   DB M27ٶ<-L! ژ&I"0F#EjaT@Wl$FgǘIuQ]ޱ,߿ŏR1SCɗla>"$S~y5uм"A,W@ F9k-jHK>Z;:)9/Xx/LԘ#R0_2G غ󝙛JYS]ߌ +ө+@o<]q/PKSF~x3IPython/frontend/nbconvert/writers/base/__init__.pym0 D|/ Vɢ#ǭUʂtwiļb\C5$gwhz=4p<ڻn,Yis8k񺪬d~~z; PKSF [5IPython/frontend/nbconvert/writers/stdout/__init__.pyeʱ Н訿Q()%\^V@1(dmMN ]EvbFmK]Ozy1}yPKSFi"4IPython/frontend/nbconvert/writers/files/__init__.pye0 Dwƈ&4ZUޝϲO2!/Z#BfIs⨕F,Ď[.Ug w<X*pIY_{.yl09㙃˷Rj}#Vzk#Λ&WKT {j%nclɓoPKSFGc4IPython/frontend/nbconvert/writers/debug/__init__.pye; {N%^Z[n!'rD_fPph2g҈`] z.+ *#bkaH{O }s#˚d(bQ_'/PKSF.,IPython/frontend/nbconvert/utils/__init__.pyM 0}N]7\EMLgB2z{h./=>ҠG#(!KEˎP@Mx2ud!E^ gXas{)!+Sŭ9ыkPKSFx[Xq7IPython/frontend/nbconvert/utils/exceptions/__init__.py5A 0 {_~x AB Eo,]fI[XWC?KCQ+wsn^:qPKSF%)_4IPython/frontend/nbconvert/utils/console/__init__.pym 0 L`fB -)؞Dww=@Vuռ(!KWwIY9i,臬__Xw.PKSF7+3IPython/frontend/nbconvert/utils/lexers/__init__.py0>E7`sp0&.nFM\H!a-wwp!TBpm qR& 5S@^ KsV++nN$5{Z50V{~Qa9=G\M/$JYz*56tԁ7[,_PKSF3IPython/frontend/nbconvert/utils/pandoc/__init__.pyeA 1 E=E3W\o:mBҊNE]^ B C-U<"$Xb.fW"e]?.m18g 7fc3 + 9CCkن^ey O]wUOUcK/PKSFm 3IPython/frontend/nbconvert/nbconvertapp/__init__.pySۊ0}W }e ۴!#gZYx7oY+Ii̙3G&VHi:"H) >qiB 3ZE1[fsR/{zw*#D9 WG.O$CRps$ST.K^s,ôO/`dsyR ȿyƪ&jEz+`#!FjpZVecN:77W4.VUDH9 Y7 f:rn>;>]f>ZV$Ufކ`5Հ[)2hAثQ3{쮯\מ3^-ţas]TuHNC8 \MZ@`4abT<`TgI1uW/~2z>hSJ?0oO{msi;ԾutcH/a?PKSF6IPython/frontend/nbconvert/post_processors/__init__.pyA 0E9EvmAzPp)4b i;M)څ]~{Rv!d{$}hq4})o+4`+&A7p93krWkp {@R>60d#'{"$&Lexm ZX{ȚUZ} V퐂 /Eԣ"rI⇬N:INP':GtY"ՈwR`rTPh\8Qx F ƧKOG˔umZsx=l!-4ۿB䅠(> a)n Xwbӏ;+Vo]KbːI1ٮf5UTV cVpǓtN@:nBC]Y2?8yYr@îșmQu=Sйiuٵ~NQ?dF>]N _3^u{t[:pŹ\hG̿r&8ʾ 4<,ETǤݦuL΁d-=pէ˸>jI>Do> }4aLG3Bpi@E#;SnmPKSFg/IPython/frontend/config/application/__init__.pyUk@ ~_! Ħ[}(]c(KSYhk?9M4)k^KO$2Di3B9*VIQ/'=$Z"SE%Y gc2Mo U%f["׆}cʍ-qA!#vG'úcdcQFtA#&tF-:qݶL SZҦ/*.$6w w mIa Buf`5XE"sgZ30`R',gy7ErvjN,hde>Dj<6vS;Ou{Z=x "%Py)"7l-HaCT2hԠyjBcR.$>k!Ͳ4tez3n F faBrZGޖpG[s^KAJ! J=?*kV󮓂TryБ+9 uջa{B/ګnQs̔~X%RAߕuÁ?"t4+0WrޢQ72`a&|DtvzAk60iPӣ{; /wW\t/b^"$>Mߴ~ߥv-OPKSF'T()IPython/frontend/config/tests/__init__.pyKB! E笂vĹ1A(w/H^obg=$\R,SFv%I'-"0̝S{6|[YH/׊,"J?jO{m͸PKSF;IPython/frontend/config/tests/test_configurable/__init__.pyTMk1ﯘꡋ=Tz NloTk`;{3o%La: -K2\ɈXJ2( i4(OES.lJ29MAe;wgW$t3O >FȨyF49a9菅RI|Xpi썶:Q)Pߩ"xcPTBhP&:VbACo`+i,LҘ+kc2 ;r9vNrޟ:ŒLU9;acVc* ؊36_k4k%J{Jf4fNH„3An?ʫZ>}. `gPKSFq'c:IPython/frontend/config/tests/test_application/__init__.pySn0{ ܐZ8TETNgkIƪ QT꡹yfvgIt9@JmZ `}Wɲ^pq& <+1S:[abړ @+Eabv@MK]&1-Ez*! V de+ښ1iֶJ8m\ےylߋOdhp C9Wnsm)_PRnK2Tm=X.wK!{\wa-~~`q;{[qm3(_^>MCLy_PKSF!0IPython/frontend/config/configurable/__init__.pyJC1  WCPpWz_.noo79pP6֫˗ec=TTeA%qbM%|΂ߍ;OpROKr %VbG[ [mi}PL8OE5EXbFu+|a _KJ,mw=L?PKSFgDd6H+IPython/frontend/config/profile/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFTN*IPython/frontend/config/loader/__init__.py?o0w oeRUb@TJ,7qR no_;4JH{Ąy``. p傪2ǵBEMIOyBJC2< &MQVC v %u䬾2- uNTWN_TIFz\8­yW^p % Ķ^2GIΡ:~5 4͉2 ^emݩ+[ut_b3y\nB/LPk m|y FalZL ծ|ՠn ixʍv*'01pX@n;PKSF/ҽo'IPython/frontend/extensions/__init__.pyA E]Z(AERDi:N}'N7gpq!稅hI=3#B}^JK.|E[pxt<3Nj`^D2JkmW#^+zqaɟdB/sEvDPKSFl>Xx5IPython/frontend/extensions/parallelmagic/__init__.pyU 0 L`f bG=DuO*S(QVF.=U|M*~B* o^~sPKSFgDd6H-IPython/frontend/extensions/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFvȌ(5IPython/frontend/extensions/sympyprinting/__init__.pyuK e{g(j5}IP$y!sJ@cLE$dRa"!-jk>rUj /ULTڕSB%o찤٬?t|r&TF{ލHPKSF%4L$2IPython/frontend/extensions/autoreload/__init__.pyRKK0W䶻 &aW}D$di74Mdߛ<|ɤښq^ 3U;*C55Yѩj+Qweցq [Lj|x7t6,nXb>VYӖ/c/#іsA~*'a$Ma ZJ&9W6SEg\jmL B[M'."no 6Up 2T 08Fj' BdJ9[Iimʻn{ˎ_=dBڥ0hIhypNyYqq#5!kI7PKSFm2IPython/frontend/extensions/storemagic/__init__.pyn0 Dw} tl6Omgi[, $6_APn|wG:tB>N|,rv8w4uq׉Y 7v8:b&aC[bgڱDBB5& g_v&"sEç|c,r0.߂e͜8H sâ_*Gtޫ j&{b2?R=PKSF)`3IPython/frontend/extensions/cythonmagic/__init__.pyS=o0+^(#=t3IM2d a$V=і#:HmS#g}畉5)+3?SPU NIf?^[Ja_`R*ǟlAtJr4RwR>In*D@4E*`R&LBS5A<`+3\ #o_zzK]Fڊ"JwXR-rˌ/cQPNCSp{d=cGG-s7:2@HAtU ӆ=fӣvfp: @-AyIEoPXXL*g9^hji^GSԼ n˦x_b^/5pls9C!墌֏kVM:~4b'dgkjPKSFA."IPython/frontend/utils/__init__.pyn0<$b{TEt$vhmtEIܳqkXqqH ښ9f+0|_7u|&Çӷ-\y&(3>AOa>:iaXAyGIاAHss<72&jMUFò}f"!EZT\vTœjc-M, a悥N'fs%o !hu,q"jAPh( c'ޞGU;M"$VS#  , m^xrmc6U#`^QNKݨmLO]4m[KNo*4JH5NmJ1Nw6%N  ޮ"\Gg`m`q(/!`̲b@iXII4N_c>"v 毭[W 0\&^ #}] \ &Wl1yҭ=Q{%fw0DxW?u8ݖu2g\w=x#5/ѥ&杯mʕ4yJU*_W]'=KElV'^#b_Z'd#ycZ75>R XrP(5OR^ +SM̤$zp]fm߰{]jPKSFLtVE-IPython/frontend/utils/pickleutil/__init__.py;O0w om% C[ BqnRS;/$X7'IeĄTo,4zl,W>yZJjv1]BYl7O*>AEb\1Л;w~2ii_rDDTؔFFcȗ' ¨J{Xقݩ%8;fZ_N Tfg3m2D4dz:`rUpd&ܤMO/!AX"3 Ӊ 7X w*²^ς1oJHdl,m4`n\_%- vX@w*tvu3-fI.f ߱]i[Tu;< !HpvmA/38{Z<TWu -j KH73Z֨EKf K|c:N8[UH 5L0cdžqx ށ[:GH.bMpԡb܆ 8E0\>ZGBjUeSKAaq`KB/4=b7ꇮV9Enόd,N9D1ơ%D|yܒ?ʆ~%:qT.(e.GD:̿=~{U¼;6o$-)%"TMk]C:W*,Rᩴvs<ˎ6;kYBy r90&qe&QAWeHl&̤Y2M6 ,hm:?H_<xi~G=_=>Ex pA"l*?7kaxgYJ5wB̹V3f$ )ֲy_>4Ceb́\&rIZ!؟/=h5N6! N —0rqn<((*FVàTY k@a3徂$462eec/#whM6@.;[Iʢ䡅yl!j(CPKSF(:{X1IPython/frontend/utils/nested_context/__init__.pyMA 0 yEBiRVEfvJvYSBt)QsE[, C|_YpAni`FXUG}PKSF\v+IPython/frontend/utils/ipstruct/__init__.py5A yE }BO=(HH{YvvpA8tH TbThB\Va]6ϮwUm]ͨy0GFPKSFzE7%IPython/frontend/utils/io/__init__.pyu=0 FcSԁV:(z{B*Ph69q@T)&&D;YۘvV2nxɅx8S@ Hi\XWֆ 77ZQcՖpisO7G2D5$C﵎mw8 7v$;wm{Oe4))zNzJ-^PKSFdZ0IPython/frontend/utils/doctestreload/__init__.pyMK K=G  BI)1^И0 P#v=--7W EJ2u3aW1/xBd卜!TYmfId.(|xΕG3`]dgsPKSF̱c%+IPython/frontend/utils/encoding/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ Z_\R` ˤ%%S2ґessRE+.n>!~.~@97] uPKSFc*IPython/frontend/utils/sysinfo/__init__.py}An E>wNʛs.*u_U#!F13}IpMچݼyɷ6su>P6D,5;^ZU4'ڃH{yy$3)=hrJ?AMCM)՚&Ϛ|PгjS4QMԒE!ك9b[mf߉\蜶aɶ) èxelRl)]%)HڤS~9PKSFOWH{'IPython/frontend/utils/path/__init__.py}AO0 }҆4MH0ۘ4MVH6jgN"`dq^;@z!L7. >񉩗ɠCC9Kt͒&9xT'{חt9Q "m;xUy\` ,Mӥjg$qk5(CkANZ0 Z`Ƶ`W-D > 77HJxCr2w[!g1n^(-mIQ~Lh{5S[lv?mIڭ5~ncGBؚsdlJ\G 8ik[q* \P(Kl¦$ sR܊ڐr(J%hچQߌ<+W/1pvvʫA{~tǿˊ ]!%>u}XPKSFb)IPython/frontend/utils/timing/__init__.pym= S0|WQ@R 5 eAM^BYw)6)Mo`ϗF[Bʔ` ]~yDNcڅ*ׄ8. Z;BYB)< ,u;FB'RD. Q4X!=.pF4H4J0t@aM 4)a @O9ajpT! Mv5{Ya˛ս'9o]%;$qfͮ ^_-ЛΟ{R6GO//PKSFّ\5IPython/frontend/utils/tests/test_tempdir/__init__.py}A @ E9Ew"Е2 $%"Ӗօbv?PIHFaL᠑|YPI\t-擌5V5lM-{Lgщڨޙe|hp}3s}3OP-x}ġuPKSF9|6IPython/frontend/utils/tests/test_wildcard/__init__.py]AK1+rޤ ؛HfiLNVV{f8 L9F!ZO,zԄe u}c/v\c)ȗיK%$D)r6]+pt6LXC᳆H5goL]n[$ p+pcNIy!5s~By}3^[gʇ{)^o8FFtn6[6OO %xYoPKSFL-5IPython/frontend/utils/tests/test_imports/__init__.pyuA! Es zWMACJiBJ NLt_jN`m֔\Q뫠qeX)+ˈQ5W>9fӮL2RMڌkdLkLyp 57PKSF d1IPython/frontend/utils/syspathcontext/__init__.py ;S+834!6^w_ 1T!&&Q`YۛF&*_K WwR2 7'|PKSF,<q+IPython/frontend/utils/generics/__init__.pym1AE9L~ PKSFt4V'IPython/frontend/utils/data/__init__.pyM ;SC834H 6B/hLoK*STQ֕KϫH8}Qإ4;7te~ϣPKSFiX ,IPython/frontend/utils/traitlets/__init__.pyVn0+x A 䐸vk q(ZZl)R%W]IYs8!kRycns&Xd JJM{iY!2i&ݒpTrׇy)%+0- g$"W8 wrh:Dfc.,HA$ulBP(% qB6LX\eXEHþe#U]H_WbPÏcA:1as .؋P9{ν1MX"NrcK"ЕX°-zouP]4Q*t-4qL羟*Dݩ\ߴ5ϭvи`ek VMIʕ 6R*g-#CwMɷfӺ> ݓHyǘl Qޙ?)4-C4W _d3.cfJ1IR^%rgm/•m2}T;tmcO|kXk({ߍEҿKOΡ}]{;줲̮z Z@a5yo JBJ3͌[o{8sz;ϥ;PKSFRE-JZ+IPython/frontend/utils/_sysinfo/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\Y`n`hlPKSFlG,IPython/frontend/utils/tokenize2/__init__.pymTM0W{|P'8pPE$(C;cy:Ϸ66ue'2jڡ'gS GA-S*/(H%KE.)>Lxz>:?m?OPǮOkϓv?S3 cv(twTɀ1!iJd! @U\I#",f 5[[*.Y9#\WNkA΄D8 1.Վf4}أ#)h5βь;c,tM(pϋCq%KC+laoG}P7r0Iʲ`WV"9f8:j& Im rnD:B 7ˉ]$v>`"G@;vXgyY!׹ !m[b[iPvu^?"6b>/.pPKSF,zQ^*IPython/frontend/utils/version/__init__.py51 St+x]]C  {B* m U"w;{9q\u6V؈;fQELPKSFYg="%IPython/frontend/utils/tz/__init__.pyuM 0 9nA$Ex k~Ц m'ʘ,yބ"%i".$RWb\Po.5@Ozv]"x7tvq|@3,t+= 쾴ބPKSFmOm-IPython/frontend/utils/decorators/__init__.pyM LѧАj ZRش"7o#B*U͡ZUȓJ*J7% 8)|iɦPKSFv8.IPython/frontend/utils/pickleshare/__init__.pymK 09Et! a ͣ$ӞX5SeNO1)4T|4"@ 6R&:Gk6o@b1۞Un=rXLl:։rʕCW KbTnݽ[Lt>} Px!0h,B)?(K wPKSF|k.IPython/frontend/utils/strdispatch/__init__.pye10 =W@bk'`Ei"b;rҷO_1e@,9T#JrR R}|,a<;5X9k"ɃZl)Ԯ~zu?PKSFf2IPython/frontend/utils/localinterfaces/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ `  utF-ҩ%"y%I9`3=CFz@hŕ_\ R^ldjrPKSF}.i'KfW+7[dG!jG:Eڻ\֫[TU8+o$0=nIuDet"-eO}R>g j-562#MNa)ڐ AZ>q5"mTDtc ]YӐT EkBZ-nek!wFcxX$l?&ؕu^"L4`fR8dOe5#}FZ lyv)Goaq>1:]K|CɣglͤMlvw~)v}PKSFt(/(IPython/frontend/utils/frame/__init__.pyuK @]kbpaޘ Tr{A/͛7s@D)(@P'Icݲ(Oea^P*@.De5[^SFG6IPmTO(0(EĈ%׹PKSFSk+IPython/frontend/utils/contexts/__init__.py5 лSخ:C V#I,t/Yb6b0t'+C^q!KOT'Rҧ~PKSF%7C+IPython/frontend/utils/terminal/__init__.pyuO;0 slC02vAV9EW+'mAjT'?/-uP&=~h 0@FE=˪; ^^ɖ8AhfRz4U"-:,N+]L98I,c($ޘPKSF1a1 -IPython/frontend/utils/PyColorize/__init__.pyUn0+t)H?EF$ A Mۂ)Ҡ$$חDﮤ9ݸ3,XI)$`ll ի"5:xVfV@HCr;MZN26/+<]q5táypl+IaR {y|6vCH5>#}V -q)p* zxpb؝7?Nf2Yˍ(Ueϋԋy{eusࠨK:/oq|e—?z>=F 49 VJgjcK{PI*e18A4; `ͳLFbakaa$s0g \"ex(ajXC4D h34'd!שZoȁ!NnCY,pN;]sF! )6 JAkNrޘ@QI}`piH0ܒaIWjҷbXw ÐRZmpF i4ӱB= X+^ ,p!AFy/+潰z|h??PKSFRk7,IPython/frontend/utils/rlineimpl/__init__.pyN0 y6$8 qGJ&5-sHahhJILAT P bw>ATu1"{ e,ݟ`$L[FUb'Ea^Ws\mNc.SNťi.\{( 1XڨW7oꝶ$~c!D7 F~I톰 = qiXc)涼Xv<-bx̘jVPH*yKT%rɵךhrͱXw~ 3$U.BED /½{hq2iI{RL[OU" 4(!i4 eY$f(2Jt(]$8U&e^+CeЯ]H%3h98\kKIW,Y/L0ׂYS;cfV%$6$c Yrw$^&8:бUjzRAF{9skc9[_*0)rؙsx 9 |6". 8X(q[d0- q B:0k?PKSF^GG',IPython/frontend/utils/py3compat/__init__.pymRN1 , $D[D u`\R,(q$.Sc?E4˜CDςzH^Ց9`'5oj>X/WJ AC!#7ǂB,t_=L7ub(v 5EN2gՆֱKköFڢ@!0ac=C[ ?G`%Xjg\'~yLXX*9gp~fVf~ݿHlq7 >>E2a=gD`:%=UuLPKSFmj=1IPython/frontend/utils/_process_posix/__init__.pyuMK1+r-RAĶZC{BvE2 ov[ytsh^p1 m0EyIw)[oł? ti0-c\k=QY]u@"7pJ{~O/՟bOnV6C5ӥw.@7"7?u/#z( .%ߙC* PKSFI)2IPython/frontend/testing/_paramtestpy2/__init__.pyMNA E{ŔIIDBB#kٌlwhX>\yFw1ǢFKk'0M 1jeWkc-s,QDl;_o"cg= kfA:#DWp$4eBwc[MSn7; R-ÉDp pPKSF6{5x+IPython/frontend/testing/plugin/__init__.py=0 "TqСR$`(ܾ  drgY;Js:$*ZS%oF̻=Sr6zXQJmWHi䒋 v=Y~EW8ޑ[zrKC}#e=>@4EvF,e̪7E8|6OPKSFS#=M6IPython/frontend/testing/plugin/simplevars/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\P``bPKSF{mk5IPython/frontend/testing/plugin/dtexample/__init__.pye DTQk> Qvɺ^(m^L`J )tLXtR)Z*t+ZT#+`b[4+s;6̾i>e(^rPKSF(g&h:IPython/frontend/testing/plugin/test_ipdoctest/__init__.py}1 {_AZp1x$#QcbAnwX' +Z Ģ& EkJ;w[ ]*fPY :ҹEfW-#W PKSFF؜f5IPython/frontend/testing/plugin/test_refs/__init__.pyuA 0 ᄁG}O 6)iQDhB"`L,j N)2uYr 0;2SZf<~''j VPKSFnIl2IPython/frontend/testing/plugin/simple/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ YP Rg` !PKSFK`Sk5IPython/frontend/testing/plugin/show_refs/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ` jh9 `!M+.PPKSF&+/IPython/frontend/testing/ipunittest/__init__.pyN0k!zRΡymWm4ڤ HM ㅭ7IRb(m9Mv K |l(Y[s'1HdX/GyHpL VJhR"+^!V72V׃cZeڣeʫ]Ǹ{E +GBt9T;W``sעn10h&z>30x CEh PKSF.ޒ;x*IPython/frontend/testing/tests/__init__.py]10 E"[@BA!%)ĎۓuooǢņV唵‚bF%];@>PA0Fk~O|{\ònZ!.vptwGq6{PKSF^(:IPython/frontend/testing/tests/test_ipunittest/__init__.pyN1 ;f'V6Y+o[|.Ŝu$ Odz|!?ӍW+ \#Uc 0u'PKSF &4U0IPython/frontend/testing/skipdoctest/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ PY\Z\` D/4F,FPKSF36=[/IPython/frontend/testing/mkdoctests/__init__.py}Qj0 +t)ia zePXz[q{5udc))Y cIzr9xVk}!e,(#*7؞g~@)Da+?n_X_ "oߪ|(aFQr-Ho<^1q2(/rTI}r>,(Uۿ^p?p2aA[oQ'}8gR8Z!:/% 9SL擅Cޜ-p]tWkNJeFtS$R\7a[C{oO3r㯟;XLzG{59}0;Z9E3:`Y|ra\LF?f/(R,KnAcCE"ٶwPKSF.?UP.0IPython/frontend/testing/globalipapp/__init__.py}Qj@SMKoCA[)ÚLtfgٙmw$7f,@[dKŦ(kM;:?xOv \l(VE|Yo W&#>ՔoDg\SzS݅`MRcS xF<i1K}a'j<8n¸S(?SP|NݺGi|)L@H3<tcГ)PKSF6VC*IPython/frontend/testing/tools/__init__.pySMk@؜dCmR919eJ+yQja;+9m{o޼ gehq1*5uR:i4):2Y.`K,EFﱿG%麅Sl t>ArR84k2mo3, Ob_0:JdaFC ߼'0 ,d\Y,Gp5/2(xS|;cg!ˈ飰!^4ua7KL,SV#2 TXQFS et%ZEyTXw4OhM_ mr0\|yYzB.y,&Bz䚐LjDLe):WH'==bd4=\w[=[}AK .wMʭN5Pt)[=[אM=ۮ q܅i?gVs:Q"Mbٟ5ݡ_bKB_"ּ2g)PKSF\2h%IPython/frontend/parallel/__init__.pyo0W䭝*񄴇61AT^粙:g;+$]4iOUǝ[U R+RmtJ渒I\b@V$Tk^" ks/45T oI=Lp.̂"atA=F(4}EG0.a2V0c*HH*(sԓY?u",3\c^'"ρ}-cV#!r\Lys b$2'[0ulK eȟ) `oO=⨀p(ԭ+Ң);(Xy$[G23z Vrg~YalG! gor9Ã֒}5Jyȹx(eB?-cxBNd1,=.~ˈ%eu9נIA@T b oKPUo{#s9k+ߎ=, nTsѺ_?PA%-NZ n5ݏa/PKSF3IPython/frontend/parallel/engine/engine/__init__.pyMo0 nljR)RZeDTEŌ=Tc($4ymS8[J 7vH,Y-EEUehPD7D`sAV坥5bpݺL>Łeo(L{Vi-W*Ų qfZ+kkifȴ=)cw: =;4ypuqwI<'1aKkͪk>:8 + V?iŠm[b(%KNz5(6:aTro#]=0@nFw1MjC݌FJEMk\!,jGQK\KM%snw3` Y3&Ȃ)tCsJ0t8_ngG>zEv`zXHbp7*2&OAtӉƞ8eqB'R/)9OB<;TJ&! rņZRnf Ji;1rqG#!vK %S 6Tf d=Ϟu aj` tɹz(3za$"77=^7j&WbcX݂t {q%JKyyRUحpSnj.@Cɥ!ϻ5L~ܷa&.vɨ54̨hBkZ8Qre͚iOROjpj j'p.7Mx 6܈f ;#HT"wNӎre1~ij b-ӂ4 6M JӾJ{TrXTR)藂?V8%(&s|G;xF; U)~ u.o2qENzQ"),v~PKSFh$..0IPython/frontend/parallel/client/map/__init__.py} 0 л1Yrql-aɅl_7%iϏ66m5Xk03U5\h@[]SyVM\_0(wvݒJ˼A7>O7$6&Ns>939v/` wD3δ`SBIoPKSFC3IPython/frontend/parallel/client/magics/__init__.pyuOMk1W̥DA<`T=b fefoV얞}Ԕ:0Β zQ U}Quo*@6KM0 üd]L,mKHg02T)eYiR0"{2e }o N|}3˧ּ/6lC" ! W [Zh-CLg#FȌJ+劁a5ÓKQ-)#ᡴ=xs-> 9͒7(kKy8׵DZOD5JPKSF821IPython/frontend/parallel/client/view/__init__.pyTn0 +ts FzXW 2 'өPY$؋ w2HnkMG]@)n $|ЖE3dN= rAQ[BܔǞb m]y` J|F$E#~.H?hM)''Bzߩ G I)Y @.HZEͩ>51}!,:@y|.#cvshsc'J"n1J:a&jSTФ@ȥqgr`v@ȐCj Q!D/9Ir:et@֎{ZQv$65S=}ߪ=/޾ZTPKSFYhk;IPython/frontend/parallel/client/remotefunction/__init__.pyuj0 z ߚ zإC:0ҙڲ,dl'OR_R4 C!DcNEL.E);񉡟T1"'A?ٽU qf[lZ<݋r؍sT2F}?ٕm5ZYd7KNʆ? !H67|0lm қ\f_]}3A)L)9xL*Gu^`tUݙPp;&,ݒ~Gۜg0)X߅?PKSF:+IPython/frontend/parallel/error/__init__.pyN0 };'$hh9JSw%v七=頬CŊϿ-' SPZ7 Z+"%gъ#,3@?KKރ bO'u-Eqm4VRw  F?ċXVLޤ6gMN`L:B'fyXnP+qֿL?vœ^l!. 0Sh &4 {U~i)=Eȳ6@PKSFF0IPython/frontend/parallel/controller/__init__.pyA E=jbz{cHja;mJ??E腔mFJaĀ^_yGQh3WPKSFg9IPython/frontend/parallel/controller/sqlitedb/__init__.py=O1 olH,U2 |@h.S'rK͏D=Hi dGJ 1ŎCUO8ȧ1|+6ÅoNqI+cZb 7ߜPoy8'<{I$dJv6Qt͜/ܵ`X&30n3N} $׵aNFcȌAo|;kp0/)]n E ?|]pPKSFs8IPython/frontend/parallel/controller/mongodb/__init__.py?O1 [ 'U @gB}Jq($1s*5k@DULM\`h+殄lh_7]$wǺ & v7`{޹Qq/fLK ц m;o jWaKrAl%lerOj0c莊8=iu?+?Ct5j O7o PKSF׀;IPython/frontend/parallel/controller/dependency/__init__.py}MK0 o<,'ҩ'L{UUOeޏ'o6f\3}H1NJ}$5Ω0{9JŐ,P>xzB%/k$ȵӦE!WcgJu oph ~=࿟]cÜ:_PKSF`>W:IPython/frontend/parallel/controller/scheduler/__init__.pyMo0 9=RV #ӎPYR%jGKj5|Ib\/lR {H-1U;FN=U! YK׿9{!1h.Ǡ*FG~*6sL>ήMNݬVInXPg-*uA+v9?%x;dJ \8h Oꍤ9&v ija m؆2֎Qb2{,WvJ^Qw;*{ۿBQn F{o_+!<!?{hdHruPI·)g[-mV bXqт6| &0=iEsC;C7ϳn_fV'ז\͵bwn==ᷠJg{:_yqK #YKPKSFJ{d7IPython/frontend/parallel/controller/dictdb/__init__.pyuR=k0+ns̅ ILЦK; UQYgSh}S: 4&q Za0Q7R.66 :!ΡLr2F8ʨ`=Q\h*@oHJtIszّ\쵑ɱ(VwܵS΋gm ^u<dJ֢'m .~ݧGE}%;K5DΟNzɚqX( PKSF\=IPython/frontend/parallel/controller/heartmonitor/__init__.py1O0w oi얛 sqbfKLA)Ȳ8P3Rfpy?F:d!B8 bMiY9=8*&u0 FS6S?O]'4RWF']m6b0ΜIXz'q*)هu`aֻpyWCZLb[ mf4Z_-󋖞mA -,EaPm~RJ\ PKSF_ H4IPython/frontend/parallel/controller/hub/__init__.pySn0 +ts Aˀ=lhm.+ A锝$z5Iqڬ{O$EU H)X-Gde*~<"YΑѡå ߓ)AO[RF$/n;>OE:d>*>&1#k=!b,7 @ F:(ȕ}_`E>&MTO ^/gﯯu獵;c:D>v'-<"M*JT,)}GmE7'@ ϱ  5㓈\neAc),2VVegnŒTrΏ+N!#rx/ O*<ǘ[G{ ox Ʒw:؉wf_aߓSiݎuXZ~,T!ZЩˊ(\bHo PKSFb0j*IPython/frontend/parallel/apps/__init__.pyn0E|wR"]}Y5X Կdeܹc+:꼖R֡')djj|L /YvSA+ĉc"G})նPJA<:]ix̌+mHddt0#wwi7S2 ?*n%K0,/[*~ i铋uhym˜齁cbflѸdX{ƌ?PKSFJaM4IPython/frontend/parallel/apps/winhpcjob/__init__.pyAo0 v*mڤJcAVgDKK5.<v ƻF*e"GJIlZYK%#aTPIa:~JtqaI:FZsvӻ{!ehY}k;̓dbfZ4e#l`.,CLNY6<ӯ;O}Bwւu5 KW]|eOjVz~!=w+KWPKSFl$ 3IPython/frontend/parallel/apps/launcher/__init__.py_s0>iofCX)8}D3$$T@RA/n6S%r0"4BW* hylNZQ{@pf 1 (-W׎xDadaz!wyr''z6X%H Fi,V"'(~eb !BV'F :3Iwt ܲJl.iA4$현$ vRU]lhN>W2n5i'y<=m73>7wS`:G%D o EE<_VC5:J &!R"N6rWRڽ绫j럎JP@lˎ 0߹o#%1.Og=571ʫgB薞l4 덙洨`U@aۓRݴ=꽐ʾd%[Зc!=,'l5bD6_]gc,T^| 'RD^u+iQgca)LNEP"ܡֳjlt$nHvZpˉ:r|6 NۋOʹ|N^PWו]4Jp NiV(d'GᲱ/`|KvK˂å X`}!O`Euѷ` E‰YYctm '}4I-v:tņ;_t>^A,6z2z.MPKSFp 6IPython/frontend/parallel/apps/ipengineapp/__init__.pyV[o6~8 ðCs57'0`(B/i_CJr,_q`;WƪE@4F[ UZM$i`wt;tpa'IN;WGhgyqE *fh۷p:pLҢ1gc3l#:ϒSj y ܾ#/ cыf[ +L ӥTv0Tk*JK ݘZg+RcI6(E ZFS1UdkQƈLK#|6H +nqsDJWķ;>]eѳxsrIYKś(EΩ*VPh7&h{| qm[R>"wm(2%d`j|t.h,`E4˧'Ĕ C@nt1,Aze PVy琓2fd\AJP{džU uj@ud\pulJY6߾24;x#Ò}gjfZ6Be7yÝUQwI|epq7$DJխb)x1ڿQzt\ '^tޢJ]1.tBMcH/ ?~U4"m3.kmggxzz PKSF@46IPython/frontend/parallel/apps/iploggerapp/__init__.pyT]A|ϯh% h~!(×3ۻ;8;·q&(ⳆTWWu#rt`\Bd[#(Dz9V E\sҭզQOo-\q1_P*:G|vH-b7֊%>' )xBAE`kUρѡ_^K5i9ϕJ!pÍĝ; 11 7lZЕ=Mj)B{|lC+;wr1V1VcL~lF$8nEU&N> z=2ZZƝ <=(:; +njaPԱQZ:Swp40D&?f?*2mDf9F nO~@qS/Lj/LRg`ae&^gVRsI}aeN!J5d: Y;5ehdƑ_Z(:?Iȋ>͋X~%Wgv*qg~xtFJBry>M1=PKSFp񾱇7IPython/frontend/parallel/apps/win32support/__init__.py 0 Ew} ]u.#SQn!_'&Z=:NG"WKU&B)jJ[$p}=Z}\ԟљLP2{?|ͫ\#]L8u 󵋆oZH1{'d>%nPKSF'BJ7IPython/frontend/parallel/apps/ipclusterapp/__init__.pyX[o6~ϯ8}@8k5#Q6WH*dɗ\P)^s!RrQD"/Th!-felGߕk!#LӰE5fl֝U*L|lz6qzt9^94kJig(-2ʩ< a!K7ZAR9rP\υqJrf;]U CAzsSF pL8vMe-s(z>|S@̕p'} xܧo>]M.zdt*Ї&\‚W''е 腰sz]EpRz*se,2[R'Z.׽]qNd3> ,,K&xv"[('NeR3z' Zn49m{TY;TwM N _n̖S|΄܉rb#Qo>.[D^ZxyV`M;97l$SyAY `k?5O)z4=pj%;CظReuEK-'xh1ҥ Z(Y!fsUqԆXQAsF0 zc"$GH[UN;9Z tJd+ua-fMKpmN-r:) _GZ%i1g~_%Umu\-nt޺]z^L-3Ԍ^Nn%d@|UR.y/nc*׬n w28K ʙ }]k\[z ʢ}$=H &`'jkzݼ.'FР}4hDiGDD5x Vn~̺@ ݑyc~r0J GmZeǚ xft!KNT`w< ..?E봘n5\fe+B̽@WlW05*Yka ^r }w<LŬņ-ɯtgҥ1J )݈E&E+8QjaLh@5bB(3jPU,SyKK7v3bWiw6M"-!SSL9~ \ a'PlcenR${"g#6~cny}YrMpDh NUB˺%ɉƯC)c!D Te'oE?3Xy/dN[ۏi)Ͷ vQcn jyC9?0V;P9z'=10swc}*>H ==a D2̮eIzj'q{C[* w"5F_dv=Qǟ=柱_wY°Gp ONPpҺwlܛZfz8&#qo/? Gj\[*C c Z,S<7o>p_ BYGJ}|MTK:4ٸ L.QPKSFnp*IPython/frontend/parallel/util/__init__.py}Sn0+tKr)m=8$BİɒT@G3.g`٧> @Iw!>MZb9:颮.-YQ q%l:)3k#NZ жdk[ L)^%&`G%}^Z2crŶ q^z7hvanV22)l;xנ7[ػjEz׃ &X#R_J.V} (OnbRR7g6L4&ceR<[oݿqX?\Nۇ#'_;9)Eu3gT|S5?z~oQ*3U|H=m}c{ŕ:19D"%PKSF/8F&IPython/frontend/sphinxext/__init__.py 0 }ު {=H[ۤt٘ool^d` $_ ' Ѝ2`1e.bsAR#dJR祉*JkHݱގ6ņi{~oƚ h+V2K!;oqxc;砐<:eyk(U<]\FRAOͧl !bݖ׫}}V<:~<JxtL@i- WmҀH4xz*rXeMDBZv&OJ='(N^zBXv-P7yg"R5O* {Os)dtFƝ&u/ugP o@|PKSF'Z IPython/frontend/lib/__init__.pyn0=_.Tem>JW.c%҄wF un|uis4ELW28&l܆E#=%SCN\\/ ZET]qsHTUF"MM9FuE#z6LE֜TI.)inr,rg) WpOOPKSF{'IPython/frontend/lib/kernel/__init__.pyQ@Di# l]Ȧ/VMIk7aȴfj 2Yl,gDV2xđVpNn)F<+,g-0;wo2,ުPKSF[Y.IPython/frontend/lib/inputhookglut/__init__.pyu; D{e%M&e W]K$>dB7o3 z!L=8O{9S;r4.1dѕ7ڂor8vd Dؘ" rm8(lDاUy nˢzz"L(mEXrƵ~/_U|rKTnPKSFN{cE(IPython/frontend/lib/irunner/__init__.pySMo0 W @nzar0۩)զ"$'%i!"G Dޣ@Yy2dMeng>Tã&k!f,V!)) ᵞow>5V;yMCfҒLI 8`]tSigv8PH_xq Å GoyWny :R(7kR. B{aLH.G`A$%rF۶WXu0$drQvTgAl׆51#ȁ$ԋOC6! Sg5W8ߓG -,.E@JcA[/_t; ⒓2L<2M>g>gOsJvibz'dR~32!a<{euzDx>`( uiŋ{etD*my;9i %_wkV{>TE׀÷6f=ma/PKSFat:,IPython/frontend/lib/editorhooks/__init__.pymA B1 D=Ez#}m&MAooUV d1o& d)sKV9YRPd2;9߀;ta^ rه: CyiBB !>?gnGzWy$'A >Jjգœ@ 8,)֟|G8]7oc3J~PKSF[,IPython/frontend/lib/inputhookwx/__init__.pyu10 E"c;#,ݪ6v8@oOZ d]`$)XsdJFIu_9i0ÇTRH>ɝ7b[*v"⍚aEE`v\1.˼>pQ/ȆjW7PKSFEʉ`-IPython/frontend/lib/inputhookgtk/__init__.py]A ">'F h%E :]8hW$ 1DNcBZ2)w`. LH=O^sID"PR(JEdž $MW.k@[[0cD-0Ve)4\C}|^3H|7PLX\"D$SI 8-'FP &{#Uʈj>/A2{W0io턻+'P9N4a$6uk;3@pFXa:jsOkf)IPython/frontend/lib/security/__init__.pye1 0 wc2ccǎ8cIS Ѧ@p*+$P̢4{ͰY /SS;>i49R*LOAo8kÎ %US{Ãf PKSFk9s+IPython/frontend/lib/deepreload/__init__.pyuMn! erJ=Bv[ hۇD;Sv}x-XKU>&bz.xa3('&r9+F.WcB%"DG`{"S ri|.=7'*PEt!zs彤穇~am{t椀ʽQms貲뇱65oPKSFmr+IPython/frontend/lib/guisupport/__init__.pymA@ Ebw<!3ikgI@*^,yP#Jsn z4khUKsKiDb(0i?4zk?}}PKSFBa'IPython/frontend/lib/pretty/__init__.pySr0 +|L~3q#(,OW&M!]I+Yv T9K5= nlFUg* Ѵ{ t+ҡepc9DX8o (aKCA=J\: &pT6"v==zӄoEғ-\ tNF2f)VYs0(uo2'R^L gaYzK#{(儸 J ᇱe"Lt\;>Xu\ \TN&\E|%]PKSF ی&/IPython/frontend/lib/backgroundjobs/__init__.pyS=o lvJ:VдP)K١c.r84:TsP)i:OqBfCN4YՑ>NK@AHEVƟ@ns|qB[QL[ 0c_YxRD•ɽ\k6POڧX3lӈ-؈ 4u"gxV: 4wcQ/k7Uh`F6)|F;7Z|ʆտmN>3-m#nlZzjBPKSF{yD*IPython/frontend/lib/clipboard/__init__.pyu0 EwE@7~ ! )DM(qDE<؝A vWB< Zɚ,tKk  xH*IkXfy?M [F&V%((v-5w83y!ΓT!ܧ7__{j[m14MRtT# (v Kq/PKSF|3%IPython/frontend/terminal/__init__.pyA =`g4tѤX#) F޾#օv;|3D40@|d!:6Ԑ[w7(yJޢnX'z詖gH}ֿ~u iMQmн/r{oH?V֟1hm1z|W _4G"1&NRn5i;_PKSF1O3e&6IPython/frontend/terminal/interactiveshell/__init__.pyZks_㑔>ҎӍǻytg֛v:$! 12hIvv"<6wVЛ^V1GKiʛ4!GGIlZsH cy>ί3Nݼ5?LgGGG(mEHT6v`|^jJt^Uyrc[%72x{OZ=9 {OM]+=O^8^Z6c׽b@mv{}Z*x{$EϿ8ͭx|.?:gϞ]T"0bPVl5/{HyB6r=.D5kx.h8jjpFh7))/Ⓚsst]5 ޏB-ꄟ1P0Kl`4Y v>irAR]neh.olAi̹$THNҸuݦC,2_!?/3Z$ݶwRQFsOI?Xo¥X!( H1*0ߏ$Qx=V8*9MZۑ@/YHI3Z>[Ts.`@p(R-쒷zW3@ںٺE{JP u H))-La+}PڣIg 1y;SƛE%Dv eҘYAzJ M^5(TB; u1Жk$ 4GKlWiK `C; RYDϑfrIIl6T4,sL#82C-3qH,S>Tb9lH*Eݔh(r1.YщWS 4q F98DJyѤD  Y9ji1bB4DIЬ鰇QqY/t3(G={x謥¬Eդ{+@+jw{F/{CB:o u-ucTHkS(_+i1M6(4P)+vE>^b,u6亮i+ik6A3Cm!n ѸѓzI?$3'\r\vc,eR471= 2b !Q;7O"іdEL{Bȧ,R*&[Y%S>i(o::Iʹ_A'1maρPᏙg0h,?L"YZT@١8~(+;d` TduQ>_m]SC \ڡl~0iUȪ7 RX2V ҿ´T0 Źs0`"M ~;R/B1,6=Eoʦk* T!vH!J v@OjXN}b@Ofbe0b)8l8tB 9{YTeo5CO@"R>Th4b>{,R0,WճY6ulɐ^{qz$L֌#<@L .5R ( 8>?op-.F-L2q$`H~!33jt8ջLꦀ7wUG*tGCIY: *gbƑzqa"ucQv0Y]Oϟ9C C 9;1$:" e"95q!P̗a%(N'Uvl@ޡQ -c*ʼnx.[8drރZq=;x*[XZr=m.6v3 :.1&KzC*%]δ*:'7F W\Oir`P(T.?H"r+}<0#dB'AtNs# ρB:Q@`h3.`wQ(6lp#CҦo߽G>:2(0b3ް=ZpTe3Ʒs&#C5u4dLzodb h+hBwSY֧:~+";+wЯOP `d'脓=szFAdZg涹QՈԇ0Jo R0Ut!?F5tKhW' q`$3l`PG;Mw.;j\RÉ9:(F 焄QUӖ]NT(+ԕ!$YLp°##k"\)<=!?QʓVeӏ:ht1+It n `t埌ǂ@g/n k- nURd|>oB:1ކ8>-&B@Z|鮞t,F4euLeOߡ#|Fw,lڝ+oPk@ʯ7t[o,D U.8rE7iyHx[.8@"ꯌY>EKVfIL)X'݊y8{2˦Og3rexy(m+uvy-WAy{ I)~ yFd!ⱜHiz sXPirQ "(35_3~ƔN8vAa1L Zܐ?#,K.tOOXmvK5 7фqq<b8\-&_ fii#RqsU*$\ŋix,Ft{Ub?>\<>4IB#١'#G~9DEڧPx`@(|勦u!sS[G/ؿx#ZrOLcd&lAL&qH?ʅQbg9V^RҚ@+6:<&F+sqӏ~&vAEѹ&:$wKmҹN{)ʒGF+tdqvp-d]7{la6̀w{B(j J325;q} wwD =CcSp^Qa'bs&r!\H(NwPJ< }"H0coKOusAZ{@nso3F=DMGG$UVcF2bJnAix/楫kR8'Np&9 *)}R֡I B%ETqݑ"ZEN7if.!`ˢ]L< g"& 3PqxXC|[JFZ2toO!O !7/]77zO-ñQ&^8PzprCw^B+.o& :Q7;z-pq#>~=[Ft Vx!n}Oy0"3LVmLx,C|iI_G,|,-gL↼.4dPR59>R@5A>Qv^B ZK^W^ցanf?P+:Z$>:I_R&#&5Gژ?WD 뺥ENBAmT5AGSdO<#1m&׹E[w46{-+A>K 4q{mzHq:K-*:2V'9DS$.oO|l<:! QUMMp*RrcrTн -A~ɵer\.vF&ҝ5#؟ ԛlS *,vA-HD[3KDə9F9l2({]X5P-EzHR"XN)ԎE;h̏3,bbE1]nE|JG>9QWqpJ784uR$|;>aĭR ѷqY_CIO6ίo~}/W1> ";i*2|+QPCCy1u)^gXgJ}!q/_k>6H%tG㒜?{OgӤYvIPython/frontend/terminal/console/interactiveshell/__init__.pyMk#1 M KP衻m`_K]x4-դ$4 4AzmMK)jc…cuGYTtvS{; I_ .3Ǟ >UO%5\")QTje3 0LU@h, df8giV)t~O.֝H&BT{jCj|rۦob{MwI,!Yާhm l6BOzv`wjl# q ÚY=Doh PKSFgDd6H?IPython/frontend/terminal/console/tests/writetofile/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF!Vk\=7IPython/frontend/terminal/console/completer/__init__.pyuA 0 ՁDWEBft迷STP-{y/.r .I|qЈrs~p5BCq8IgiR{K갫1S0Ǐ3p%ĵK,rjgQXkx`k/tuLe@Jq8kc܋Ore:Bw oׯPC%\ieK舙aL$yv/_fIt3-FQ4 `1S9,ڳ>) P5%U8M唱;`R8;5WA[X떭5%*@I?Gnjļ4orŸ\IZgz8(jHrdqClPйՇRٸ\G:oeo]`.*f:?/'"ccQ׊ހ>wRX*}-Wqz4. hE]nh_1VP#%K2j DUA*,*MYAW7nJ+@lBM*JV6 TGzP?nWtհ1O KeE$n=db7hF3]ia6k 5ϋ^(CF2@B2 N)d@gl/ջFRR1>rt?jH͛eP̳KY&ۈ`lvkGQY(<5)E<*a47@+/%8:+bW=g-eмdQcWosbŸE5<%k I`m_%ht9 yI<z#q :2u, qf"l9S*TyXn<&:>n}Tw۷:seh¤@b0 *'xjj'ӵo쌎n=EZetn^DXE*/7ߐ`K^> :)*foI­ViޅHMmL>3^<[ͣo}oJ{敏y S]mt"jvB>pcב|IٽGNyt\}Ē&qJ:4K6T5SR=2G=wğwz'̸6PޢDAN`vӳӁN,bH8W데~DZK*̊4C!򍬿_NIJaUBӉa;ʊ]ַaxlRQ4@y1'7'sevPKSFWQ+IPython/frontend/terminal/embed/__init__.pyMK@{K zQz(֓0Lҥa?N?O!<;y;P(Zj$u2r^XMQhZc)V-Ds,!m=_kR˚/刿΋lSNtjZ(E`y%gmkaczE smq-8L1M0ix)3i 1a"GI?{;P&a=L26põDDaB.ݿ<+V}"@ }*i\PjOO[}VQlQS<&akug6Ws,/SimPKSF>!IPython/frontend/html/__init__.pyAk {>7;"SakYBbY$O:N_< V/R$- c*RjHբt 1T0m֙ nO0jUwuGX:Eh8-wUϜ("bi z'fLt:a$ƹ2+9NQ@xsه2G)(z훷CG]ӵtvgzjנc%IcD`اpL"HPKSFWւ&IPython/frontend/html/base/__init__.py10 E[@BAĎUDH쒸(x=9eB8 L9Ԕ Lʭý T|Oc@W% qx&S9K񒢹ŚF,tM{J׼-PKSF 2IPython/frontend/html/base/zmqhandlers/__init__.py 0z˅" >Q;ʬH{& 80ğbɘB+;|CBc*whA^;Yr 2XRI]JTbRAN|r{җ'0'V^uRMFw0^tqY.!~$)t4Pnezͺ݈].MN[?j5csӎI|~xݟIyG70ѬPKSFgDd6H'IPython/frontend/html/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF>/к*IPython/frontend/html/notebook/__init__.pyA 0н7]/%4޾3)ݤ=SZ -hV̀f8YEt㶠/QBXc|O?Ty 4ʓq[h`,iVLV%5m?uv&[+]22XI5M濒& [ )jjkĜz˅" >Q;ʬH{& 80ğbɘB+;|CBc*whA^;Yr 2XRI]JTbRAN|r{җ'0'V^uRMFw0^tqY.!~$)t4Pnezͺ݈].MN[?j5csӎI|~xݟIyG70ѬPKSFgDd6H0IPython/frontend/html/notebook/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFy3IPython/frontend/html/notebook/notebook/__init__.pyE1 0 EwB(AС=&66(Cn_'ŭ&pİ&RYXIUQ g8aL|є'_ bo]#E-3 GENδPKSFTD^<IPython/frontend/html/notebook/notebook/handlers/__init__.pyj0E b(m(t`JAƵ{Fe\}bPӲX P J/0I_ 5 X#,O,~w%{m?t5o BDŽuo:;7Qi#P7=Cʹx~Npϸ~ueXPKSFd 6IPython/frontend/html/notebook/notebookapp/__init__.pyVmo6_A`t$KVia( E$e{7Kt8%sǻ{NQ2)%"Iq$5B9HUV(JtP)>t$e\XhxqbƙҎk PRXw x`uLgj6A I,ɇyZkəd<`.iU$6Mk5'_ !X&<@ޚ+P)PaK(ZΥ-o/ OZb-NngJǡdmLQc*hBjҘPrӶӛP*8^[_tҕP%dK7o옔zGl[} ņHZq(jI1j.B|vo+\MWw3zs7^ҏ-̚I|zb(l$$vN`~?o+qvz|3,PȒTDKdZx4JD$ƙi!-uzn\q J|/H@8\LP5{jƧ $L3ĥ\mA:ok6^7:/^]xzRLTzHDMh 7LZ^cau-ie2 !㏞ CFXq2p؅ĦF:nL:9DjOr5v X%%o.Bs"B_HX fQZm*JUyȧEc[3оcn0{x__ȫW]Qd-fZSzLV[L+Au H}M-#\Œ:MmaIc8| @?um O>94Z_!A%Ÿ .8r.~FL6;b  g b'`֜5"st}cüJƕ?ZOA3~Zp[f,AəYxka CGe\dUZ\@1ay{$7MS X*-&rg;.{1o*}KNFe}Fyj){8Wݙܸ#=<> Kgw2v^ʹ-zUu]ZdY\==H~ $K S4j ۲"mADA+jgS\*J:96|w@gPKSFK_0IPython/frontend/html/notebook/utils/__init__.py5 0 "O**$tJM(-T_J,_CzFi|fKPKSFkftj3IPython/frontend/html/notebook/services/__init__.py=0 F"[ABAĎ%FMq='E]͟΂6E$52\ؾJ']wxGabx37<&^|+>^!dF|6EKIc`젔}fbFP8P+ejRwD~vrJ^ub` PKSFwCIPython/frontend/html/notebook/services/notebooks/tests/__init__.py] 0 }ު }=HjdsLK : ؔ'$ҚRdKQ, 'mj|}i5)GO1,)`&ůdc*~4{PKSFzRIPython/frontend/html/notebook/services/notebooks/tests/test_nbmanager/__init__.pyn1 0 q{uuBK,NvaK*nKgT[هbMDApxm8]#TМ2r@: I !p]i3lRG!$Z!'80X]0h3m;a(sF 5 SBcI{UÑC n۠2gTd]H 䲟840h? p,{AƥM_s*Cŭ,*(kǂF2]-8@$ 5 =L?WiF6i(mrG:¦|z76!tCg4!_{Pob,4cx.ҝHI28X;HIIeө}m~JwTjב^~M PKSFZEIPython/frontend/html/notebook/services/clusters/handlers/__init__.pyM 0 DAݏPgծ-i xUA1y$ ]TC JkGm)",SU`^*{#1qf9c={ iI]y@/=y/nxtJ>b]~ VFg?Tc֝χsŖ^7:U.OOPKSFx(;IPython/frontend/html/notebook/services/kernels/__init__.pyM 09EvUܠp!tbC2 hе{? -@Xt1,jg%Ʉo+\0fhH(Ŷudґ?R#V'WPcq a*niNJh{k~hf{Imr{PKSFhIIPython/frontend/html/notebook/services/kernels/kernelmanager/__init__.py0 >W@bcQH"uq[.>EJFc@Ģ*;ȕ]Ct`Z=ixr7Ip#I3}TE|Fj/P^Cg6%1m-A'4z-fPRF(KFGPKSFAc-DIPython/frontend/html/notebook/services/kernels/handlers/__init__.pyQj0|+vJhE[K9QWMO7\ FE6ٝI -BiahFIDi.Т"C.SFfǑ@[8͡`Fr74\D+&t;キR0P-˒r Z@MYj(W}t;`k -2_NWNլm`yfosXE!DY3ad!}så2k}b%{>F( _K?م۸ğ<_njĸzy,s1|)ƹ#N2Co7PKSFCx/IPython/frontend/html/notebook/tree/__init__.py==0 "[@BAP! ZGؕܞJR=bmWBWl-ɲUiq.=y._!$ F3r-_PKSFnFil/IPython/frontend/html/notebook/auth/__init__.py10 E"[@BAĎEKB&vĆ7?BbCV=Me*vD)MLXWyEc2A G<# T"(%yGNszps{UڙfPKSFԇ5IPython/frontend/html/notebook/auth/login/__init__.pyu 1 yw_A[loowe=|q \o],TX 78[:,gS=6*hq ZswdV=qji|>R.|7PKSFJ1p6IPython/frontend/html/notebook/auth/logout/__init__.pyu1 SxL){+Ro`! *Ș/IlA8bh#B̅EH$_rL8Tf|a[|-)n|aܫKV>1N2} @R^_PKSFd -IPython/frontend/html/notebookapp/__init__.pyVmo6_A`t$KVia( E$e{7Kt8%sǻ{NQ2)%"Iq$5B9HUV(JtP)>t$e\XhxqbƙҎk PRXw x`uLgj6A I,ɇyZkəd<`.iU$6Mk5'_ !X&<@ޚ+P)PaK(ZΥ-o/ OZb-NngJǡdmLQc*hBjҘPrӶӛP*8^[_tҕP%dK7o옔zGl[} ņHZq(jI1j.B|vo+\MWw3zs7^ҏ-̚I|zb(l$$vN`~?o+qvz|3,PȒTDKdZx4JD$ƙi!-uzn\q J|/H@8\LP5{jƧ $L3ĥ\mA:ok6^7:/^]xzRLTzHDMh 7LZ^cau-ie2 !㏞ CFXq2p؅ĦF:nL:9DjOr5v X%%o.Bs"B_HX fQZm*JUyȧEc[3оcn0{x__ȫW]Qd-fZSzLV[L+Au H}M-#\Œ:MmaIc8| @?um O>94Z_!A%Ÿ .8r.~FL6;b  g b'`֜5"st}cüJƕ?ZOA3~Zp[f,AəYxka CGe\dUZ\@1ay{$7MS X*-&rg;.{1o*}KNFe}Fyj){8Wݙܸ#=<> Kgw2v^ʹ-zUu]ZdY\==H~ $K S4j ۲"mADA+jgS\*J:96|w@gPKSFK_'IPython/frontend/html/utils/__init__.py5 0 "O**$tJM(-T_J,_CzFi|fKPKSFO*IPython/frontend/html/services/__init__.py 0 }ަ }=H6i&֟Nv\n YgAĢvHZ)yL&|2=.4E) `O\HnМ\AyD5;w9Ţ[uoF´1kXIPython/frontend/html/services/notebooks/nbmanager/__init__.pyQAj0{%(PhBɩ!ے*bm~ߵSChȡ'13(2\,R88(b#YSs\n0بy\e_OA:^ֿ2{SGټم|_ch<&Ja)_qH5{0(OHNzxGabx37<&^|+>^!dF|6EKIc`젔}fbFP8P+ejRwD~vrJ^ub` PKSFU:IPython/frontend/html/services/notebooks/tests/__init__.py] 0 }ު }=wԕH39˗(-@\t),jgI5čkQ, 玺mjN}t`͓/(xbŞy,~r~Rv9 PKSFzIIPython/frontend/html/services/notebooks/tests/test_nbmanager/__init__.pyn1 nid.`lkv[u/\ ]8ߘMm>OPKSFiDϏYoBIPython/frontend/html/services/clusters/clustermanager/__init__.pyUMk@W A ƔJKL@WFլ;]iUɥczΠʲ,K]HrlIMY:]J dע+e?v.ˤVZK֕эThKIK˷ YV)a-<=+-m}zFxʳP9qٲURKo-&s)C"HhK>0 q{uuBK,NvaK*nKgT[هbMDApxm8]#TМ2r@: I !p]i3lRG!$Z!'80X]0h3m;a(sF 5 SBcI{UÑC n۠2gTd]H 䲟840h? p,{AƥM_s*Cŭ,*(kǂF2]-8@$ 5 =L?WiF6i(mrG:¦|z76!tCg4!_{Pob,4cx.ҝHI28X;HIIeө}m~JwTjב^~M PKSFZ<IPython/frontend/html/services/clusters/handlers/__init__.pyM 0 DAݏPgծ-i xUA1y$ ]TC JkGm)",SU`^*{#1qf9c={ iI]y@/=y/nxtJ>b]~ VFg?Tc֝χsŖ^7:U.OOPKSFf2IPython/frontend/html/services/kernels/__init__.pyK 09EvQܠp!J:ɤL7Z"d}s~@fr *9 RvK >J#M衎/3#A,)ڂ ] cmNCp3?~T{24>t=*PKSFh@IPython/frontend/html/services/kernels/kernelmanager/__init__.py0 >W@bcQH"uq[.>EJFc@Ģ*;ȕ]Ct`Z=ixr7Ip#I3}TE|Fj/P^Cg6%1m-A'4z-fPRF(KFGPKSFAc-;IPython/frontend/html/services/kernels/handlers/__init__.pyQj0|+vJhE[K9QWMO7\ FE6ٝI -BiahFIDi.Т"C.SFfǑ@[8͡`Fr74\D+&t;キR0P-˒r Z@MYj(W}t;`k -2_NWNլm`yfosXE!DY3ad!}så2k}b%{>F( _K?م۸ğ<_njĸzy,s1|)ƹ#N2Co7PKSFp}5r&IPython/frontend/html/tree/__init__.py== 0 wB(AС=QRP}Qb3r-_PKSFV}&IPython/frontend/html/auth/__init__.py10 E[@BAĎJC, Ą7?bi"P*̕X$j߻{" GR.|7PKSFJ1p-IPython/frontend/html/auth/logout/__init__.pyu1 SxL){+Ro`! *Ș/IlA8bh#B̅EH$_rL8Tf|a[|-)n|aܫKV>1N2} @R^_PKSFIPython/frontend/qt/__init__.py=0 F"[@BAĎEDX4vI\ n_}piDy"v*H)A&Tpkt1z%4@6n|ʕ7ů|}X;55hPKSF?Wo3IPython/frontend/qt/base_frontend_mixin/__init__.py51 SdlбC7*Db"e[ׄTAUb/G#a*Џpk ZTߞ>mpuPKSFR\O'IPython/frontend/qt/console/__init__.py10 E"[ABAĎ+'mP?QAYtʞd3)PkR,pf YUCwNd2O0o1p@[Nz~|]GUd XvhU`=ZT]|PKSF S-IPython/frontend/qt/console/tests/__init__.pym10 E"[@BA!Q#;8TnOVo(\,@\uTUio)hb2Gk(6f dPԍG&%HOVgc]xSPKSFPs?CIPython/frontend/qt/console/tests/test_completion_lexer/__init__.pyQj0+t &J)95Phnu1‘lQd@>vS}wgfG2wF]*"5.:#ޫ?΂j MOE8Ih-d%=.#B,𩂲*3w~zd,K*I*K}*޲w(]y<(DYvbgxl jPKSFj .IPython/frontend/qt/console/styles/__init__.pyAk0@]![BmaY2s3'"^Sg=t:$~™V4k@)U4Zs&*J.2TRzo^xT%Hm7EtI%~mGsAڜF pc?j^h!BMT{PՂaP*iwYQ~HbA0.SWd7>$fIk4JGfåba$׀ko֗Ď_Ìk.HU ڬ)x^DzKFjq'IpF3sId?xWv+mwݺtNni)5tG@k[Jh;pUL?iJIU2Dx^YE366oZC3ׅI? PKSF 9fv IPython/display/__init__.pyk0WbJ1KԵ[I@KaP}ȒMC^^:aO,I\nTI(+ PJxA L+W/XͰ Ń HEl,,ʠ0CUNn]*Av_#/A= GUUF+PKSFgDd6HIPython/scripts/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF!IPython/external/__init__.pyM 0ὧJo(t_JqPMMD(;>`*4G$fQi򫖤Ϊ|,X[XC~1 jў.?`QqϗqJLQK[ߚYAMJ MlK ֈ?1ٽB Pű%/';čW5?PKSF^Ex(IPython/external/jsonpointer/__init__.pyu 0 y޶=(EVNnc<) !*ZvFbj*l$1xl,G*bшdz˕MN]dl8' rڽБI8;=!O - yEP5p f[PF캊lI\}PKSF>5IPython/external/jsonpointer/_jsonpointer/__init__.pyu 0 y޶]D&E|0JA6m?I3mp%fꬲ8hG{ x Nb o8<9Ҝr j (aEAr$@=/̗צnv71cw:ѯ`(%?7PKSFn IPython/external/ssh/__init__.py5K 0 D>vn!9@K%Ԗ,Cs8 j1/, DҶҤɄ 黓( %'}uYí؛! PKSF'Yyo'IPython/external/ssh/tunnel/__init__.py}QAn0T=T^U++YZ D!dyf<;3`?`}&Q3[=Mc^j4U7xQ![}g5kc $Ǯ'bPˈ&.vCSD\y1'IPython/external/jsonschema/__init__.pyAK1-EhBLd[7ZTV9{_L2aɅ(*_Ui<ɽBÊHo c͡qJG! L{FӇdƭõr~i/=XZCunWj\ })ݩu"C8ʨW tNBoV+j;IFl>D6M㻫Ip>`l4lrk>]2m!eLMo Eqڐ13޶4lϤo PKSF~0C-3IPython/external/jsonschema/_jsonschema/__init__.pyK0+rvPCa1'ɬe/7,Bޗ+a),*tH,iˁڌ5ڤhA4hbgA@Ť,*…TyHGX5FW vDkֿc\£ӫ7tiړp ӫpAx KQ\N(hhPs‹~bJWgn=nSYFE+E* 'ǦP/PKSF>$IPython/external/mathjax/__init__.py=n0 w›S9@݋Pf?PNG E #@G>E.14X԰|jd8cw&}/us7{9rRʎhϐ}ʫ+ Sbod658xC&@ېFP=: ZX9:=`8UKQOyBg\뀮 Y^ט GUPKSF%7{!IPython/external/path/__init__.py5K 0 >vN Bclbq5G@t'"%WR}FapÊ|.mE[+L#'elkAuG Sޠ'^r*晠e׻6PKSFA?ܜF'IPython/external/path/_path/__init__.pye; 0D{b;M C.R(d jG1Hdyz `\ HxK23\){{2LJ&viɥD نgt-cOeLFV]@o\1_ S^H (:o炙1kvjQ}PKSFГ'IPython/external/decorators/__init__.py1n0 EwBtP S`Ho_9AQ;O)p-@tbq,%1 Wj~\1У4SsKmѯL~+2fyEO6<i, (F1]3caN_ Ƕ(\Lb&dݳ3X^d+gTyD-;;rR E*HPKSF*r<IPython/external/decorators/_numpy_testing_utils/__init__.pye10 {%|{V%(FߟQ ۝,"Q^lD&] 4|X%$FkV|`t՝o@?'9pJ=?PKSF3IPython/external/decorators/_decorators/__init__.py]10 Ew#\R1,#T)ޓCH!%c1QoTKVHW~0GryaX5HVRo*;U?pmIK@ܨV|n"mlPKSF&IPython/external/decorator/__init__.pye 0 yܶ]"˺d̷:/ HM:#B?$$>jNUo<Y,'$*7I4Spi~\| ~s咂 fz5rS7?PKSFȼfޘ1IPython/external/decorator/_decorator/__init__.pyu 0 Dw}$Knlm|1LJ_'mP*Mr\P)ʤ%EL5q1=RK4PcpNNwo0ؽA-\+bf5T+ =KYvSxzJPKSFL4/IPython/external/argparse/_argparse/__init__.pyn0 y n@^8k%6l]ac$Rڼ(jIQOhDwAAXlcW75zq4eHAݳhR`l{)H}Me7IGغW8xu/(G墨Ķr_lb ;2 *[VlT6{ޭo_eYu4}Wiʡ?yU|,=!.v|X=(Id-IJų@5W@ٍN:[#(TJxdM @ +Y*jahr=߃YvSgq2r1m?x{rۃwdqGubG?_5m DR̜F*q>p)j:HPKSF{*IPython/external/simplegeneric/__init__.py]A 1 E9EvAz9 HjML*cv%/j-H[0I,UJ /@hn95۫@4i*Wckoo%Ƴ]v#wm^PKSFN1x9IPython/external/simplegeneric/_simplegeneric/__init__.pym;1 D{(U DSp{G[0y~l QэPJL4Rf_.X pceG]3^̴ ~Y=MyPKSFQFdIPython/consoleapp/__init__.pyUj@}W̛CҗBh Ә$})e-mVb/v%,̞(&!E!@共 ȳ +7K fqr OsZYt:'̙mJ׶= ɠp;Ҙ)J6JEb>:C ZB}jNtVnZZވwVjmBզcu|#T!BP=t?l^}|qɿa4=l◢NYP6R|;s_gI> 4[Nti ,?vcJޘ'H%&p؇ i`9=*'ZssoS?PVʥEܩѻӧJ⛢(E.Re[J̣CUT5!ڱGStUE~klL*bV*RnH/9$E r]ͥS%ɸϸh_L^S57S_3Ir_ýTu: ;r/{uC+H68s 8"f2)?T p0PKSF6IPython/nbformat/__init__.py 0 {*`yA.Xҁoo;][ \D#ar"hGnMh5aш,G.Rq,M/?pQx݋o5,?{qՙ3gPKSFlaFIPython/nbformat/v3/__init__.pyn0 y nmۤ>vm@Jb̿ N(?l\{HsRyXR!򎲔]G^TFr<wow.]q wI++Mn ?ʥAԃsϐu@ncMuIRc$"\2d{a`.LU; ]iF 2./},hq1%9\ՋxUߐqQirS/¸YدhU0D-26.S՝L*k"߫?B@QdJ|CSЏe|p4Jx:u8=㑐siڈCĮy+0l|H/=:|:w+!x}/V;=Nnvs_x˗؜sIr}PKSFG$IPython/nbformat/v3/nbpy/__init__.py}P=0 +2v## URؕܿ$P]+ds^%,@k/`}hYԶI#JN=*G`$ǥo(5mQ#X(3hsp a,[ܐB8b+sjXSb~rx9wS@y570sҵb E M\9>Nè+n+>庢=g㟐yH@_ e'+No[vqwI^ LQыR=bIv&I)spK#;O7HZ"pkx#RW\: Zq[[tA8[,g$H+toWDwV^/TO4l EFPKSFk+/IPython/nbformat/v3/tests/test_json/__init__.pyAK1d) ,T&nl6 ɮb)o޼Ds!Bp{"AHmv]sĎ.)z#`kL!;g+[OHHqSׯE͘+B'oԷF1)%-ǗJb.|M-rHD~rܓN=o6FZC;gZ.+2 #dx/4yy~pN_Phuqm/PKSFD61IPython/nbformat/v3/tests/test_nbbase/__init__.pyŒ1o w d&CN9K,uD N,5 d*r(v bqfMPRYCQB䎼|AkjPhRU"C KF/9E"/)WǏ!&nEQA\}tB IKchLST %&9g< F+UuCG& pJ!זnҜ.Ms|mڦgRY PKSF(pr]0IPython/nbformat/v3/tests/formattest/__init__.pyR[k0~ϯ8:Սle0 !mOgHUZv|$'IjJ).yVŎkE%u tװ<gKiBtFZg]]Pj[DAE ȼ̧MXdIȷg;&\iI<{a|5Wsg>,Tj+{ UnU ~a]ȷ=<4XE}26R4Ff.UGL%ZvYVeC6 Bi=KU1E]ph= A0= B_'C/ܥ w_UX,o [ݪmWҴ3 <ǿD^K%"S ÿfGm9K. bGŝs 2뚮Y[ᑣ0 9` ƅݯ!PKSFvz)IPython/nbformat/v3/validator/__init__.pyn1 C*4Nz^}LB9fn].K\Xd{i(AWCh `jGw];h$<ԺQmld21NJˊcã?&*98]P|zkq+Ƶ3l2 A?og*"wKВ!UuW߇9&SDHnAHYQ_<lf)sl/;@_PKSF"^zIPython/nbformat/v1/__init__.pyj0 w?:Э= ri߾^!>$5Z GЮ( ,4XvT3Z(e)PGqx~ * pu{dGwE$!MDaf 5MvN35  Q=P,,z.bkś aP(7!:V$;z>-lRNÓҺ<`AַأR?PKSFn+&IPython/nbformat/v1/nbbase/__init__.pyN;0 s pJ=BYݢHIG5H.b"Ǫ0"(H$7n(4piK HYHμKy{#vB?}vlj{q4[؇ XQ*嗢J PKSF6.&IPython/nbformat/v1/nbjson/__init__.py}10 Ec{$.D``4E4W\$P)o&@Y fb@KN 5WPMUu@OR"4KȽ<&co:n>BHLG48ISsNTW:r4笮PKSFfEp&IPython/nbformat/v1/rwbase/__init__.pym10 Ew#\RPMđcߐ {?$$ DS5,5;!t+N^NIE/^jʘ!z`JyiBr5D . +z$pk< 2*HpŚBK~zlzѵ\*R !gbXn [:VS|"b>. rGx&/eL~oPKSFr~0IPython/nbformat/v1/tests/nbexamples/__init__.pye=0 w#l+enAHIG5z?U2T*V7ztOwI^ɛq $2_}.˂ ib=cF }_PKSFiRj'IPython/nbformat/v1/convert/__init__.py5 0{C83mJ$h:w_>r@ "T_peӻx`N,PKSF}H$IPython/nbformat/v2/__init__.pyn0w-D2tШC:r(4gGH޾ L3pԎs7%ǹuaLVVKu.dYEr{ǘ_LYkn{n<w3g, {&4&PL5}lGVo2H/U HIblhL<;=R2؃DRZBӠEVg*KkʩcۭeS}O/фU#ԍFZ\&Gp\e,:Lt\+2U$a\FK[?ZySO",ϭdr5rfPKSF# 矮&IPython/nbformat/v2/nbbase/__init__.py10 E"c{$@حj$R[J%0ΐ)hAX2he)ȅFˎ6W ;Aj;MTHzB@6aSHw$k)>P#돳R֛ylj{RZ{Zʚe=u,?PKSFP$&IPython/nbformat/v2/nbjson/__init__.py} 0 {'^1l]u[S ۛUvcRihp @ޢ#a6Hh&zOg.SeX^0z9M)hǸ֒bhzr>O:mԌ{BS64-`T8Xdu0t4yyL=xlJobüUcwr ŊG ZzPKSF׹%IPython/nbformat/v2/nbxml/__init__.pyun <*ۺTi! Nؑ(ۏdT?oC4ZYgl'b'L1h"4ݦ)w΅Y>1 =טh`ΩW |.s#iDA4/m0BiU þ19Bsu+uB'@qc}}-@xƼm!5& ^ľ߶_9lX;nz礏UG6?PKSF$8 $IPython/nbformat/v2/nbpy/__init__.py}M@ sYL\7.N))%FI{kL(:b ['^uF,9U&S}tr랐2Ά0JR0f9r$l%G!HATuz}!ԈTZN_QR)՗?=(.{uO3@[KPKSFϭ&IPython/nbformat/v2/rwbase/__init__.pym wݍ㥥Ws8KۘR6K#; 0f4QtPoثq\|e+d#p%몛VKx><Ś&) ^[5-f0OJ{/E [ \Jۥ,3Oۋ:[UHrT}PKSFgDd6H%IPython/nbformat/v2/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF-Q/IPython/nbformat/v2/tests/test_nbpy/__init__.pyQKk@W,xP C)b 7EУĄ#nQ\v{|;ItAY& m+L*rVAҨ򋀯!8ף1XH#PAwxrJܦKvdo ŋM&e8gK&٫[CxR'O[-K d!жBثݎ*eQǺRf_̀i` }}7M=O-: HlݮzMQ<` BP&hΔxqкo}FEWK\8K]jЦZxb6ΈZWh-#p!׽ɛ?PKSFS,|/IPython/nbformat/v2/tests/test_json/__init__.py= 0VvBuhK&o9yjʘX1*>P 1HkȖ+.$W[OO/BFNIy bY!R-W)Rfϰ5c!yj߮PKSF$1IPython/nbformat/v2/tests/test_nbbase/__init__.pyR=k0+4&[M@lCGqϱ3 И̵C]kc91=E}l ,T=Nr:I?PKSFJ0IPython/nbformat/v2/tests/nbexamples/__init__.pymRMK@衭RAJ+( ^ R/eLښY׻ ey7j 玜Ea'yVӊQ%uZ ,|V Gn4f U3țly#v gO,$2A+Mֺڑqg tѾֶIZwЯwL_RZnVjcrz 4~,3pORut?=W*ֶ$i8^HSb àNvQIӴu)lZ=*֊On49*1NǗ>"ri) vEog ?(KN}uPKSFw'IPython/nbformat/v2/convert/__init__.pymA0C=EzH:擊p\f%QHnl" 8y1%X;U ՄM P¾b] !.pWI:@ᘣqj?7',aU^PKSF#yYIPython/nbconvert/__init__.pyn0yީ,dKtYw XZNKj;_RjUJ(%Rk.SYW2+Uƛ,cg{4Y(N?/pPr.wL<{ҥ?Nj[ˌ\ ry.6=Ĉ״xr DC\Rj±0jP>GŢ6BIAs% gߊ`: ]+)'/J$'uI^?{(~P_ڷ,+Dn Y)fRc~`z m׫>nB;ǵ߹l۸?PKSFȸF.'IPython/nbconvert/exporters/__init__.pyj0D lCr Vp1$#ﻒ%rnn=3F) ӍTev)s >.2X '%P)5,BЌ_ض1F 'mcSԖ/ $Q,QQ\ ' 5i ,L + Ŵ͑0p$h&/W&Kqܽnc"6nO D/̛/"-+_RPڡ~!`z|os-a.}ϥw8 PKSFM<0IPython/nbconvert/exporters/markdown/__init__.py10 [ H(uP$2wA8bڅ!ʢP%x\Lث~9bɵHN<_ @''̯򯻗y_ 0Sp=)>]WK`TZuaPKSF5-U.IPython/nbconvert/exporters/slides/__init__.pyAj1 E>vNJ] %PSS4rHo'CC[(N}#%SyD &l]hYإke8g&ё¦/1?|ڻQDjfץ%WtsjGᔏ[r|#wG;B{G.'z+=~#ð*8R>_ҚSτa{ifH??RaxW,mz[1)K&R a>nz$ j e\: 4E|'No4e8e#w ͇L!> 8v M<|ܣVBY K_x NA!'uhk3.ZћG"˟ܚlo}BMֵ21zaڡmXr銼FvPRyi)nDc?F~ l:;^濹+ݍc N梟Q$?IuR&cFY#-1 W?P ra_PKSFgDd6H-IPython/nbconvert/exporters/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF;IPython/nbconvert/exporters/tests/test_exporter/__init__.py 0 E|v+PGLnL"'e,ڤsĽ*!BB꺨j,uUMZu:#6"2A:V,bOG$EsN^9ȑ8Zj=\1^+Վy$AU*CnhY[9CNC7PKSF0yY4IPython/nbconvert/exporters/tests/cheese/__init__.py}1 St+:7(-)p 4"ڌ!V![_ 58*i' /i^ %eusPKSFƵuBQ2IPython/nbconvert/exporters/tests/base/__init__.pyα =Ol6 ]J-S$g"UO<y@ߠ.NHER0&O Jpz@&*"3H#P"io-XyP,AfFm.=w\XDj ]NPKSF<쒦x;IPython/nbconvert/exporters/tests/test_markdown/__init__.py 0@~ō ['^$r)M qq2ˑ{@PK\ z |.&WͲEmTF2}wȑqis'?680f6h) Od2h$`ȍ-2?t+[:PZ^|/'rYPKSFDH9IPython/nbconvert/exporters/tests/test_export/__init__.py=k0w mB /% tH)4[)B϶>ݙ:]CҸkGϣ{Re-RҸ& M,$}<e@YfqȈJ/og_Nxyq'Qg)L sqrN:fH^fggbi<Ϡfc u%k KPoqIj"lרo&> )(܈tbzM)ՠN E|q-A S`{^= .tM{S&5 6PKSF t9IPython/nbconvert/exporters/tests/test_python/__init__.pyα 0Oqn"VB{iI.RooRYB*!BBQԪ,DU9p]r;gɸYX$%V88MƜ Zn 4uoR`ȍ-2?% dwؕWȕ&6}PKSF -IPython/nbconvert/exporters/latex/__init__.pyJ1ye ($/ i`vfI&}n]|~ pI+R?pJ"Q$&TcĔ% ke\>iI[tE9{#**7;F.`+Gvi|v=SLn+0>ǷCrtO QdԶ*[s镒]Bt- Nq6koh.mWPKSFcB+IPython/nbconvert/exporters/rst/__init__.py;1 D] HTOmEdeQA{|¢@Bf *cV"P.RJ%N+ ZSf=4A8ҸYvgJ{_Prc2o 0ZR|Y)q0k'A{ahyPKSF fVD.IPython/nbconvert/exporters/export/__init__.pyMn F]+TꪉEUqb0hrr?=LIe[!x-*Cjаr4zDG#Z cN-!u>OHHH%v&?1zuMU[p?L. t$"_cL59A;|0mHLO`//nyvN; HIٴwAww8iB¨rjagXh۰mPKSF3,IPython/nbconvert/exporters/html/__init__.pyJC1y٥]A.t%eiR\&Ҿ{E.ss' 6IPEaBjUZ\}S T3K҂&q柶g}gZ[d:&w%+U. +\ VRN~I7 [(5p ]Kjzyn}CGܼ4hڡ PKSFP!.IPython/nbconvert/exporters/python/__init__.py! @w &&. @@ gn}uhT1 KJzzNTM\BxlN[[`,|i ` If|, *M5rYu kܬ1/PKSF͞R#L*IPython/nbconvert/transformers/__init__.pyn0~ 4@ERU15-{?9T13Z4vuAM-ѩR`$)U6@eƦ7VJA(ys4\RzbS[\~L9#Bxkp0)듻wvW?;Jf ۦ~Yԏz TjhZ\M.yIQr8gcr);U-3O3)y2CUtPYlD4ZͺJ(G_îG~#|oa'y}\q0kPKSF٨J/IPython/nbconvert/transformers/base/__init__.pye10 E[ H,Eb=r#E$v8UU) x*B͚R*jjbsʋ%!VӅcd&|:eXzSĖ-l+9O%lD^oMX鷵K/EQ+_PKSF=89IPython/nbconvert/transformers/convertfigures/__init__.py 1 >E+NΥң&G>̖@p!(,RHRf5N]7[>´v%R, ǓXLPTOLXF e/5#O?w PKSF 5IPython/nbconvert/transformers/revealhelp/__init__.pyϱB! НѹixR/y98٭*㰡4QLk$U y.nw)8RQV?86An5YX8ȆOʃ_6O0>mrνPKSFl}m2IPython/nbconvert/transformers/svg2pdf/__init__.pyAK1m{1 AV(^CΖLLm-`n̼IKkk…Z:Q,n0HgPٸ wdMJT/U.D!_Õ\fud2uJ]n%egܸ #Cl!c!ylB4ᇩfxv3"@c: fq%y 4E~q BJT!hx܁T3$7PKSFKY:IPython/nbconvert/transformers/coalescestreams/__init__.pyMA c>o"HՄ$RvgryP G}ppH(2k<^SrdH`PKSF"e 0IPython/nbconvert/transformers/latex/__init__.py} 0 @ܶ}HJŶi&vsxL%)RnR@,8ORɈn"*Cb9cWoT]ORjSo(-KxTYs./ >S.8 }sƽ8NGl4[@ xPKSF]d8IPython/nbconvert/transformers/extractoutput/__init__.py?OC1 w oyPRGC;!d4$b}{ZQLwɺ8#Qڛ'˜+7b #ٽt?@/j7Mq7.1L \Rt] ܲoӑ\bܙ+>؞>l~<Ӎn,IaXk#OPKSF~$v =1IPython/nbconvert/transformers/sphinx/__init__.pyAK0  Â`A$mMgJ2YJ=yyu˔ZaHrU#7K@?E!arόuPCF39dhc'0-g3pˠ=LNOk &%I )G39K ɲ&{-K(#[~l v40-PhhX;-fsa612D1r[]4+9o)isoPKSF= 8IPython/nbconvert/transformers/csshtmlheader/__init__.pyJ1s $  ]O"!&6dB2}{'[V^<?+Qk׸50KfTcQ@6| \kt }c@jmv੟A"տ `V|8}A*Œ]2'4eJA,lV֩`5$K4=Se1e) 8?b'mK TVYPKSFos:IPython/nbconvert/filters/tests/test_highlight/__init__.py 0 }6ay/ES[?>Z,B}IT Z!xS? rasJh3kΚ#`="F+H]6\1\fIca7:i RN:ڦ w=C"PKSFjsf8IPython/nbconvert/filters/tests/test_strings/__init__.pyOK1u R^<&d7dBfwv={o&q6]Rc:XԲǤؾ}Q.Ju䯪1L+b8XB=O{YTR)eX©A6 >ՠ?ācX3\> GM[8#dCM!BΏ5}/6s%gSO J,H3{N|Iu޹P n6w[S"Cev|仿OPKSFJk?IPython/nbconvert/filters/tests/test_datatypefilter/__init__.py=@ _Q76&/ }Z$&GӴ:JYDJq1$< *Tb"3(ؽ#5 J :b-J$slX Z%ݔ`*s3_u^XPKSF;cxA5IPython/nbconvert/filters/tests/test_ansi/__init__.pyo +, Ժd\dYA"P}}{RpeykI P^ A%iZ4e[3dksH jpJKZe $1 *CkưɞmiyYa5 أ!xDl+=z%%䏞ײbQfهyM0TrkFnǨaV ݜv(`bb( CQXgi-pi-MثҀ(9f>z:UWAuAz l?(#ޮ/_>%vLio IT!X&i:DyXv A0YL_PKSFZ7Eq+IPython/nbconvert/filters/latex/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ` ЄI''$V "K2 sK2 Q@PKSF-IPython/nbconvert/filters/strings/__init__.pymQ=O0 +' F !+j]|qIZ9`i)Kf#[/մ\޾Pv.q}wz>Vu7ZMr|~RС3#Vڠ/G0~h)b 1d d&(Ƃ[Apq]అ W1$VsIF&]Z&XdR'_5c4#Q*vwJXFL&)aƙ3* PKSF/IPython/nbconvert/filters/highlight/__init__.pyMk0 FaǍPv^$f Ϳ5#f0Fz>ܥ%@)'֏1 ВAt*ϥjD9ut'xm'nwB85~p|iH gZqmZvXM :3M瘼!´Ȼrd(Նl?0fsqAUǙTY7s^w P12 PKSF+n#IPython/nbconvert/tests/__init__.py5A 0E9RAr `CA3S&7i%bL.jŊS(*.V:hcO/*AI¦3mwio~';PKSF:<(IPython/nbconvert/tests/base/__init__.pyAK1m JmB/Z   DB M27ٶ<-L! ژ&I"0F#EjaT@Wl$FgǘIuQ]ޱ,߿ŏR1SCɗla>"$S~y܇F Hy;_F_3i /PKSF~x*IPython/nbconvert/writers/base/__init__.pym0 D|/ Vɢ#ǭUʂtwiļb\C5$gwhz=4p<ڻn,Yis8k񺪬d~~z; PKSF [,IPython/nbconvert/writers/stdout/__init__.pyeʱ Н訿Q()%\^V@1(dmMN ]EvbFmK]Ozy1}yPKSFi"+IPython/nbconvert/writers/files/__init__.pye0 Dwƈ&4ZUޝϲO2!/Z#BfIs⨕F,Ď[.Ug w<X*pIY_{.yl09㙃˷Rj}#Vzk#Λ&WKT {j%nclɓoPKSFGc+IPython/nbconvert/writers/debug/__init__.pye; {N%^Z[n!'rD_fPph2g҈`] z.+ *#bkaH{O }s#˚d(bQ_'/PKSF kФ#IPython/nbconvert/utils/__init__.pyM 0}N]7\E6N1fB2z{hv.oG4@?@!Pd,7lɫ~2=\ڄ`'w##[9NzMܪet\9d0̿NAn:0ks&ThL!9mB PKSFV-(IPython/nbconvert/utils/base/__init__.pymA! =n &nt^0H#^2 .4}m.`m%X X*B$)yE&wU?'1Y>Mx2ud!E^ gXas{)!+Sŭ9ыkPKSFx[Xq.IPython/nbconvert/utils/exceptions/__init__.py5A 0 {_~x AB Eo,]fI[XWC?KCQ+wsn^:qPKSF%)_+IPython/nbconvert/utils/console/__init__.pym 0 L`fB -)؞Dww=@Vuռ(!KWwIY9i,臬__Xw.PKSF+*IPython/nbconvert/utils/lexers/__init__.py wvs4&.nF+Ė# &,z}ߧ.P ;4 LO״\g?/~fJ,CT"Km kz=?J]ԨNq!56KvirPi&GmgX-PKSF*IPython/nbconvert/utils/pandoc/__init__.pyeA 1 E=E3W\o:mBҊNE]^ B C-U<"$Xb.fW"e]?.m18g 7fc3 + 9CCkن^ey O]wUOUcK/PKSFm *IPython/nbconvert/nbconvertapp/__init__.pySۊ0}W }e ۴!#gZYx7oY+Ii̙3G&VHi:"H) >qiB 3ZE1[fsR/{zw*#D9 WG.O$CRps$ST.K^s,ôO/`dsyR ȿyƪ&jEz+`#!FjpZVecN:77W4.VUDH9 Y7 f:rn>;>]f>ZV$Ufކ`5Հ[)2hAثQ3{쮯\מ3^-ţas]TuHNC8 \MZ@`4abT<`TgI1uW/~2z>hSJ?0oO{msi;ԾutcH/a?PKSF-IPython/nbconvert/post_processors/__init__.py } AD]BX{ȚUZ} V퐂 /Eԣ"rI⇬N:INP':GtY"ՈwR`rTPh\8Qx F ƧKOG˔umZsx=l!-4ۿB䅠(> a)n Xwbӏ;+Vo]KbːI1V53/'&L3܈BWX`ۢ BUT6B!y"tDȵfKN%6q 7VRݕBOf3KЪKmZ2`Rg&I̺" džGx 1u^)?||HZ.϶ 9p!jrP uP Ti)꼷vϥo(oI%F%:&P^p3KE80Ex:S"lq`t%`VFBȫ ia2Kr.[))+ӳ=3~pʍg@Mh_ۇnTA({BoQad+1~v}TN3ڴ{]tOfُ\*-3Kӛ`m*'D= E)=&m7ׄ`R-8)*a'tTn}Fu#U#:F[*/iu 0̃(ug:HC$F䁦AUmPKSFg&IPython/config/application/__init__.pyUk@ ~_! Ħ[}(]c(KSYhk?9M4)k^KO$2Di3B9*VIQ/'=$Z"SE%Y gc2Mo U%f["׆}cʍ-qA!#vG'úcdcQFtA#&tF-:qݶL SZҦ/*.$6w w mIa Buf`5XE"sgZ30`R',gy7ErvjN,hde>Dj<6vS;Ou{Z=x "%Py)"7l-HaCT2hԠyjBcR.$>k!Ͳ4tez3n F faBrZGޖpG[s^KAJ! J=?*kV󮓂TryБ+9 uջa{B/ګnQs̔~X%RAߕuÁ?"t4+0WrޢQ72`a&|DtvzAk60iPӣ{; /wW\t/b^"$>Mߴ~ߥv-OPKSFgDd6H IPython/config/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF2IPython/config/tests/test_configurable/__init__.pyTMk1ﯘꡋ=Tz NloTk`;{3o%La: -K2\ɈXJ2( i4(OES.lJ29MAe;wgW$t3O >FȨyF49a9菅RI|Xpi썶:Q)Pߩ"xcPTBhP&:VbACo`+i,LҘ+kc2 ;r9vNrޟ:ŒLU9;acVc* ؊36_k4k%J{Jf4fNH„3An?ʫZ>}. `gPKSFq'c1IPython/config/tests/test_application/__init__.pySn0{ ܐZ8TETNgkIƪ QT꡹yfvgIt9@JmZ `}Wɲ^pq& <+1S:[abړ @+Eabv@MK]&1-Ez*! V de+ښ1iֶJ8m\ےylߋOdhp C9Wnsm)_PRnK2Tm=X.wK!{\wa-~~`q;{[qm3(_^>MCLy_PKSF!'IPython/config/configurable/__init__.pyJC1  WCPpWz_.noo79pP6֫˗ec=TTeA%qbM%|΂ߍ;OpROKr %VbG[ [mi}PL8OE5EXbFu+|a _KJ,mw=L?PKSFgDd6H"IPython/config/profile/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFTN!IPython/config/loader/__init__.py?o0w oeRUb@TJ,7qR no_;4JH{Ąy``. p傪2ǵBEMIOyBJC2< &MQVC v %u䬾2- uNTWN_TIFz\8­yW^p % Ķ^2GIΡ:~5 4͉2 ^emݩ+[ut_b3y\nB/LPk m|y FalZL ծ|ՠn ixʍv*'01pX@n;PKSFgDd6HIPython/extensions/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFl>Xx,IPython/extensions/parallelmagic/__init__.pyU 0 L`f bG=DuO*S(QVF.=U|M*~B* o^~sPKSFgDd6H$IPython/extensions/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFvȌ(,IPython/extensions/sympyprinting/__init__.pyuK e{g(j5}IP$y!sJ@cLE$dRa"!-jk>rUj /ULTڕSB%o찤٬?t|r&TF{ލHPKSF%4L$)IPython/extensions/autoreload/__init__.pyRKK0W䶻 &aW}D$di74Mdߛ<|ɤښq^ 3U;*C55Yѩj+Qweցq [Lj|x7t6,nXb>VYӖ/c/#іsA~*'a$Ma ZJ&9W6SEg\jmL B[M'."no 6Up 2T 08Fj' BdJ9[Iimʻn{ˎ_=dBڥ0hIhypNyYqq#5!kI7PKSFm)IPython/extensions/storemagic/__init__.pyn0 Dw} tl6Omgi[, $6_APn|wG:tB>N|,rv8w4uq׉Y 7v8:b&aC[bgڱDBB5& g_v&"sEç|c,r0.߂e͜8H sâ_*Gtޫ j&{b2?R=PKSF)`*IPython/extensions/cythonmagic/__init__.pyS=o0+^(#=t3IM2d a$V=і#:HmS#g}畉5)+3?SPU NIf?^[Ja_`R*ǟlAtJr4RwR>In*D@4E*`R&LBS5A<`+3\ #o_zzK]Fڊ"JwXR-rˌ/cQPNCSp{d=cGG-s7:2@HAtU ӆ=fӣvfp: @-AyIEoPXXL*g9^hji^GSԼ n˦x_b^/5pls9C!墌֏kVM:~4b'dgkjPKSFGl IPython/utils/__init__.py=o0ݿ›[̙:u((%R%&ʯ")y냒ks _3L<[S-=}bk2 tz\XxUdŮtw˗sFp}>u5R9I3MFbӥlX۳q1:V#okv=Li`)'ׯU7,*M JHB;8pRr%ՋwVj" /X"xL¨uwk _PhxA?D"3X1{/6(E8 SK()2ۤx"J V`F`M)2ч&(SRdF#ňQe VkmўLͅp]*YAJ+mʤ @cFAFrkjxpu&X]+8%F❠( ߃CVQ^^ ~ DzQUX!4㣗SR9@ R42GxQt* @Z0%Gu*/F*1JK)W~5jU9bup1u(C4P1 0R؞O)2F5JU9bPKSFlO3$IPython/utils/pickleutil/__init__.py}n w͉TeV)CRUխſn<lNje81B0F[GU1ϵBUKIͮ@^!Kh<xC:MY]nw~Uȴ4ԯT/$NT)(MUMqih UYB֖\QAUiβ Z;Y-ɐ0AclM6$ (">\&܎n:157iS523]E6kX.döə0;gĥMW|Ӛ'ֈt`- 1xp)#N\Lz~b"k'6PKSF[ZƊTsIPython/utils/dir2/__init__.pyMA BGz Q,h))ĹP*!B,j5&k6y\x*~.muAZKA&HPKSFk!IPython/utils/tempdir/__init__.py1 0 EwB[+Bv*t4QIdEr)N=נܰآF΢YcbS( b {dވO/!AX"3 Ӊ 7X w*²^ς1oJHdl,m4`n\_%- vX@w*tvu3-fI.f ߱]i[Tu;< !HpvmA/38{Z<TWu -j KH73Z֨EKf K|c:N8[UH 5L0cdžqx ށ[:GH.bMpԡb܆ 8E0\>ZGBjUeSKAaq`KB/4=b7ꇮV9Enόd,N9D1ơ%D|yܒ?ʆ~%:qT.(e.GD:̿=~{U¼;6o$-)%"TMk]C:W*,Rᩴvs<ˎ6;kYBy r90&qe&QAWeHl&̤Y2M6 ,hm:?H_<xi~G=_=>Ex pA"l*?7kaxgYJ5wB̹V3f$ )ֲy_>4Ceb́\&rIZ!؟/=h5N6! N —0rqn<((*FVàTY k@a3徂$462eec/#whM6@.;[Iʢ䡅yl!j(CPKSF(:{X(IPython/utils/nested_context/__init__.pyMA 0 yEBiRVEfvJvYSBt)QsE[, C|_YpAni`FXUG}PKSF\v"IPython/utils/ipstruct/__init__.py5A yE }BO=(HH{YvvpA8tH TbThB\Va]6ϮwUm]ͨy0GFPKSFzE7IPython/utils/io/__init__.pyu=0 FcSԁV:(z{B*Ph69q@T)&&D;YۘvV2nxɅx8S@ Hi\XWֆ 77ZQcՖpisO7G2D5$C﵎mw8 7v$;wm{Oe4))zNzJ-^PKSFdZ'IPython/utils/doctestreload/__init__.pyMK K=G  BI)1^И0 P#v=--7W EJ2u3aW1/xBd卜!TYmfId.(|xΕG3`]dgsPKSF̱c%"IPython/utils/encoding/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ Z_\R` ˤ%%S2ґessRE+.n>!~.~@97] uPKSFc!IPython/utils/sysinfo/__init__.py}An E>wNʛs.*u_U#!F13}IpMچݼyɷ6su>P6D,5;^ZU4'ڃH{yy$3)=hrJ?AMCM)՚&Ϛ|PгjS4QMԒE!ك9b[mf߉\蜶aɶ) èxelRl)]%)HڤS~9PKSFOWH{IPython/utils/path/__init__.py}AO0 }҆4MH0ۘ4MVH6jgN"`dq^;@z!L7. >񉩗ɠCC9Kt͒&9xT'{חt9Q "m;xUy\` ,Mӥjg$qk5(CkANZ0 Z`Ƶ`W-D > 77HJxCr2w[!g1n^(-mIQ~Lh{5S[lv?mIڭ5~ncGBؚsdlJ\G 8ik[q* \P(Kl¦$ sR܊ڐr(J%hچQߌ<+W/1pvvʫA{~tǿˊ ]!%>u}XPKSFb IPython/utils/timing/__init__.pym= S0o\5FeUm2i0U]0T}2V Dl|6zڢnLJa,HpG¶.T/xO|3BkA%$!/0׍N2nX9:|OX)09kJsб6΃{[y".*`IM 4't@ǩvAhD:q#9(A` d7 -{5T->^S'YVَ; h h8hv۠a}#BPKSFّ\,IPython/utils/tests/test_tempdir/__init__.py}A @ E9Ew"Е2 $%"Ӗօbv?PIHFaL᠑|YPI\t-擌5V5lM-{Lgщڨޙe|hp}3s}3OP-x}ġuPKSF9|-IPython/utils/tests/test_wildcard/__init__.py]AK1+rޤ ؛HfiLNVV{f8 L9F!ZO,zԄe u}c/v\c)ȗיK%$D)r6]+pt6LXC᳆H5goL]n[$ p+pcNIy!5s~By}3^[gʇ{)^o8FFtn6[6OO %xYoPKSFL-,IPython/utils/tests/test_imports/__init__.pyuA! Es zWMACJiBJ NLt_jN`m֔\Q뫠qeX)+ˈQ5W>9fӮL2RMڌkdLkLyp 57PKSF d(IPython/utils/syspathcontext/__init__.py ;S+834!6^w_ 1T!&&Q`YۛF&*_K WwR2 7'|PKSF,<q"IPython/utils/generics/__init__.pym1AE9L~ PKSFt4VIPython/utils/data/__init__.pyM ;SC834H 6B/hLoK*STQ֕KϫH8}Qإ4;7te~ϣPKSFiX #IPython/utils/traitlets/__init__.pyVn0+x A 䐸vk q(ZZl)R%W]IYs8!kRycns&Xd JJM{iY!2i&ݒpTrׇy)%+0- g$"W8 wrh:Dfc.,HA$ulBP(% qB6LX\eXEHþe#U]H_WbPÏcA:1as .؋P9{ν1MX"NrcK"ЕX°-zouP]4Q*t-4qL羟*Dݩ\ߴ5ϭvи`ek VMIʕ 6R*g-#CwMɷfӺ> ݓHyǘl Qޙ?)4-C4W _d3.cfJ1IR^%rgm/•m2}T;tmcO|kXk({ߍEҿKOΡ}]{;줲̮z Z@a5yo JBJ3͌[o{8sz;ϥ;PKSFRE-JZ"IPython/utils/_sysinfo/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\Y`n`hlPKSFlG#IPython/utils/tokenize2/__init__.pymTM0W{|P'8pPE$(C;cy:Ϸ66ue'2jڡ'gS GA-S*/(H%KE.)>Lxz>:?m?OPǮOkϓv?S3 cv(twTɀ1!iJd! @U\I#",f 5[[*.Y9#\WNkA΄D8 1.Վf4}أ#)h5βь;c,tM(pϋCq%KC+laoG}P7r0Iʲ`WV"9f8:j& Im rnD:B 7ˉ]$v>`"G@;vXgyY!׹ !m[b[iPvu^?"6b>/.pPKSF,zQ^!IPython/utils/version/__init__.py51 St+x]]C  {B* m U"w;{9q\u6V؈;fQELPKSFYg="IPython/utils/tz/__init__.pyuM 0 9nA$Ex k~Ц m'ʘ,yބ"%i".$RWb\Po.5@Ozv]"x7tvq|@3,t+= 쾴ބPKSFmOm$IPython/utils/decorators/__init__.pyM LѧАj ZRش"7o#B*U͡ZUȓJ*J7% 8)|iɦPKSFiXl3%IPython/utils/pickleshare/__init__.pym 0E,ۭ;7RAi6C(ɴo=>EYD)qBAG3 p-B=d >h*esf$Q]#UfYPj(W\9}P^Dn(Yi{PZO}ݻDӷIk@,rpPKSF|k%IPython/utils/strdispatch/__init__.pye10 =W@bk'`Ei"b;rҷO_1e@,9T#JrR R}|,a<;5X9k"ɃZl)Ԯ~zu?PKSFf)IPython/utils/localinterfaces/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ `  utF-ҩ%"y%I9`3=CFz@hŕ_\ R^ldjrPKSF}.i'KfW+7[dG!jG:Eڻ\֫[TU8+o$0=nIuDet"-eO}R>g j-562#MNa)ڐ AZ>q5"mTDtc ]YӐT EkBZ-nek!wFcxX$l?&ؕu^"L4`fR8dOe5#}FZ lyv)Goaq>1:]K|CɣglͤMlvw~)v}PKSFt(/IPython/utils/frame/__init__.pyuK @]kbpaޘ Tr{A/͛7s@D)(@P'Icݲ(Oea^P*@.De5[^SFG6IPmTO(0(EĈ%׹PKSFSk"IPython/utils/contexts/__init__.py5 лSخ:C V#I,t/Yb6b0t'+C^q!KOT'Rҧ~PKSF%7C"IPython/utils/terminal/__init__.pyuO;0 slC02vAV9EW+'mAjT'?/-uP&=~h 0@FE=˪; ^^ɖ8AhfRz4U"-:,N+]L98I,c($ޘPKSF1a1 $IPython/utils/PyColorize/__init__.pyUn0+t)H?EF$ A Mۂ)Ҡ$$חDﮤ9ݸ3,XI)$`ll ի"5:xVfV@HCr;MZN26/+<]q5táypl+IaR {y|6vCH5>#}V -q)p* zxpb؝7?Nf2Yˍ(Ueϋԋy{eusࠨK:/oq|e—?z>=F 49 VJgjcK{PI*e18A4; `ͳLFbakaa$s0g \"ex(ajXC4D h34'd!שZoȁ!NnCY,pN;]sF! )6 JAkNrޘ@QI}`piH0ܒaIWjҷbXw ÐRZmpF i4ӱB= X+^ ,p!AFy/+潰z|h??PKSF{dp#IPython/utils/rlineimpl/__init__.pyMn 9E!z"$րAƴۗLg}6z~fzh)('!֪U܍Uҭ3LY,[z4r&Tp"w?6QQz q% =̀Gt>V! OR -v'F8!( wHF0` v["h< 1q7^ C 湵ϒ~IOg31ގpW%NE/{ђlٹ6^:t3nAu OC }֮PKSFǤJ7G #IPython/utils/coloransi/__init__.pyk0We}e2Xc`WYL$_*]M;+j;M:4-Qe]Am<ӯv*ht/>b'Ea^Ws\mNc.SNťi.\{( 1XڨW7oꝶ$~c!D7 F~I톰 = qiXc)涼Xv<-bx̘jVPH*yKT%rɵךhrͱXw~ 3$U.BED /½{hq2iI{RL[OU" 4(!i4 eY$f(2Jt(]$8U&e^+CeЯ]H%3h98\kKIW,Y/L0ׂYS;cfV%$6$c Yrw$^&8:бUjzRAF{9skc9[_*0)rؙsx 9 |6". 8X(q[d0- q B:0k?PKSF^GG'#IPython/utils/py3compat/__init__.pymRN1 , $D[D u`\R,(q$.Sc?E4˜CDςzH^Ց9`'5oj>X/WJ AC!#7ǂB,t_=L7ub(v 5EN2gՆֱKköFڢ@!0ac=C[ ?G`%Xjg\'~yLXX*9gp~fVf~ݿHlq7 >>E2a=gD`:%=UuLPKSFmj=(IPython/utils/_process_posix/__init__.pyuMK1+r-RAĶZC{BvE2 ov[y\yFw1ǢFKk'0M 1jeWkc-s,QDl;_o"cg= kfA:#DWp$4eBwc[MSn7; R-ÉDp pPKSFgDd6H"IPython/testing/plugin/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFS#=M-IPython/testing/plugin/simplevars/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\P``bPKSF{mk,IPython/testing/plugin/dtexample/__init__.pye DTQk> Qvɺ^(m^L`J )tLXtR)Z*t+ZT#+`b[4+s;6̾i>e(^rPKSF(g&h1IPython/testing/plugin/test_ipdoctest/__init__.py}1 {_AZp1x$#QcbAnwX' +Z Ģ& EkJ;w[ ]*fPY :ҹEfW-#W PKSFF؜f,IPython/testing/plugin/test_refs/__init__.pyuA 0 ᄁG}O 6)iQDhB"`L,j N)2uYr 0;2SZf<~''j VPKSFnIl)IPython/testing/plugin/simple/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ YP Rg` !PKSFK`Sk,IPython/testing/plugin/show_refs/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ` jh9 `!M+.PPKSF&+&IPython/testing/ipunittest/__init__.pyN0k!zRΡymWm4ڤ HM ㅭ7IRb(m9Mv K |l(Y[s'1HdX/GyHpL VJhR"+^!V72V׃cZeڣeʫ]Ǹ{E +GBt9T;W``sעn10h&z>30x CEh PKSFgDd6H!IPython/testing/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF^(1IPython/testing/tests/test_ipunittest/__init__.pyN1 ;f'V6Y+o[|.Ŝu$ Odz|!?ӍW+ \#Uc 0u'PKSF &4U'IPython/testing/skipdoctest/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ PY\Z\` D/4F,FPKSF36=[&IPython/testing/mkdoctests/__init__.py}Qj0 +t)ia zePXz[q{5udc))Y cIzr9xVk}!e,(#*7؞g~@)Da+?n_X_ "oߪ|(aFQr-Ho<^1q2(/rTI}r>,(Uۿ^p?p2aA[oQ'}8gR8Z!:/% 9SL擅Cޜ-p]tWkNJeFtS$R\7a[C{oO3r㯟;XLzG{59}0;Z9E3:`Y|ra\LF?f/(R,KnAcCE"ٶwPKSF[(D('IPython/testing/globalipapp/__init__.py}Qj1)rS쥷 譔!Y M2!3iݷovM&m"%#v!QRhQT d?nxRگ rvrqG'ݛcY-RɜRƦ秾ݳzWBpM"RY\<5fq_)%Bd.>_Ȳgl,L׈1&_*ԡ8_;늏c. iWc?$\fRf&l3]@^֩RwspMo3z?k}/P3DSQ߻oyyG@H3<tcГ)PKSF1!IPython/testing/tools/__init__.pySn0+l6R!@@s (J-.% 9T}pU:(ceQq@9HI٩wĀB{Qf-l u5Eq'|j5ĶQdUN ߐ@GBo,G[6׼nM "o k !X `v\CJZ+FeA ϠS|'eKYG hŁeo(L{Vi-W*Ų qfZ+kkifȴ=)cw: =;4ypuqwI<'1aKkͪk>:8 + V?iŠm[b(%KNz5(6:aTro#]=0@nFw1MjC݌FJEMk\!,jGQK\KM%snw3` Y3&Ȃ)tCsJ0t8_ngG>zEv`zXHbp7*2&OAtӉƞ8eqB'R/)9OB<;TJ&! rņZRnf Ji;1rqG#!vK %S 6Tf d=Ϟu aj` tɹz(3za$"77=^7j&WbcX݂t {q%JKyyRUحpSnj.@Cɥ!ϻ5L~ܷa&.vɨ54̨hBkZ8Qre͚iOROjpj j'p.7Mx 6܈f ;#HT"wNӎre1~ij b-ӂ4 6M JӾJ{TrXTR)藂?V8%(&s|G;xF; U)~ u.o2qENzQ"),v~PKSFh$..'IPython/parallel/client/map/__init__.py} 0 л1Yrql-aɅl_7%iϏ66m5Xk03U5\h@[]SyVM\_0(wvݒJ˼A7>O7$6&Ns>939v/` wD3δ`SBIoPKSFC*IPython/parallel/client/magics/__init__.pyuOMk1W̥DA<`T=b fefoV얞}Ԕ:0Β zQ U}Quo*@6KM0 üd]L,mKHg02T)eYiR0"{2e }o N|}3˧ּ/6lC" ! W [Zh-CLg#FȌJ+劁a5ÓKQ-)#ᡴ=xs-> 9͒7(kKy8׵DZOD5JPKSF&(IPython/parallel/client/view/__init__.pyTj0+tʒs aBBR㭈Eͩ>51}!,:@y|.#cvshsc'J"n1J:a&jSTФ@ȥqgr`v@ȐCj Q!D/9Ir:et@֎{ZQv$65S=}ߪ=/޾ZTPKSF+yk2IPython/parallel/client/remotefunction/__init__.pyuj0 z ߒ z襰C:0ҙҷ&dIOHC^!#)fV)Ba S4I>'^/6'%s:,N͛"g ? vГYsTmkv%-S,*7?f*-n 0NU$LvA$UyHA)L)9xL*Gu^`tUݙPp;&,ݒ~Gۜg0)X߅?PKSF:"IPython/parallel/error/__init__.pyN0 };'$hh9JSw%v七=頬CŊϿ-' SPZ7 Z+"%gъ#,3@?KKރ bO'u-Eqm4VRw  F?ċXVLޤ6gMN`L:B'fyXnP+qֿL?vœ^l!. 0Sh &4 {U~i)=Eȳ6@PKSF='IPython/parallel/controller/__init__.py1 EwNVrCUR *1Cn_(m OgT8UJXFrYAt+~uˍF Ƃe1PSu#Ա{kI?T]nQmYټJs\mK#@=z7cK;E^#{OеPKSFg0IPython/parallel/controller/sqlitedb/__init__.py=O1 olH,U2 |@h.S'rK͏D=Hi dGJ 1ŎCUO8ȧ1|+6ÅoNqI+cZb 7ߜPoy8'<{I$dJv6Qt͜/ܵ`X&30n3N} $׵aNFcȌAo|;kp0/)]n E ?|]pPKSFs/IPython/parallel/controller/mongodb/__init__.py?O1 [ 'U @gB}Jq($1s*5k@DULM\`h+殄lh_7]$wǺ & v7`{޹Qq/fLK ц m;o jWaKrAl%lerOj0c莊8=iu?+?Ct5j O7o PKSF׀2IPython/parallel/controller/dependency/__init__.py}MK0 o<,'ҩ'L{UUOeޏ'o6f\3}H1NJ}$5Ω0{9JŐ,P>xzB%/k$ȵӦE!WcgJu oph ~=࿟]cÜ:_PKSF`>W1IPython/parallel/controller/scheduler/__init__.pyMo0 9=RV #ӎPYR%jGKj5|Ib\/lR {H-1U;FN=U! YK׿9{!1h.Ǡ*FG~*6sL>ήMNݬVInXPg-*uA+v9?%x;dJ \8h Oꍤ9&v ija m؆2֎Qb2{,WvJ^Qw;*{ۿBQn F{o_+!<!?{hdHruPI·)g[-mV bXqт6| &0=iEsC;C7ϳn_fV'ז\͵bwn==ᷠJg{:_yqK #YKPKSFJ{d.IPython/parallel/controller/dictdb/__init__.pyuR=k0+ns̅ ILЦK; UQYgSh}S: 4&q Za0Q7R.66 :!ΡLr2F8ʨ`=Q\h*@oHJtIszّ\쵑ɱ(VwܵS΋gm ^u<dJ֢'m .~ݧGE}%;K5DΟNzɚqX( PKSF\4IPython/parallel/controller/heartmonitor/__init__.py1O0w oi얛 sqbfKLA)Ȳ8P3Rfpy?F:d!B8 bMiY9=8*&u0 FS6S?O]'4RWF']m6b0ΜIXz'q*)هu`aֻpyWCZLb[ mf4Z_-󋖞mA -,EaPm~RJ\ PKSF_ H+IPython/parallel/controller/hub/__init__.pySn0 +ts Aˀ=lhm.+ A锝$z5Iqڬ{O$EU H)X-Gde*~<"YΑѡå ߓ)AO[RF$/n;>OE:d>*>&1#k=!b,7 @ F:(ȕ}_`E>&MTO ^/gﯯu獵;c:D>v'-<"M*JT,)}GmE7'@ ϱ  5㓈\neAc),2VVegnŒTrΏ+N!#rx/ O*<ǘ[G{ ox Ʒw:؉wf_aߓSiݎuXZ~,T!ZЩˊ(\bHo PKSFYsC!IPython/parallel/apps/__init__.py 1E|E(ZX"C 17F\lv%5C^d KW]|eOjVz~!=w+KWPKSFl$ *IPython/parallel/apps/launcher/__init__.py_s0>iofCX)8}D3$$T@RA/n6S%r0"4BW* hylNZQ{@pf 1 (-W׎xDadaz!wyr''z6X%H Fi,V"'(~eb !BV'F :3Iwt ܲJl.iA4$현$ vRU]lhN>W2n5i'y<=m73>7wS`:G%D o EE<_VC5:J &!R"N6rWRڽ绫j럎JP@lˎ 0߹o#%1.Og=571ʫgB薞l4 덙洨`U@aۓRݴ=꽐ʾd%[Зc!=,'l5bD6_]gc,T^| 'RD^u+iQgca)LNEP"ܡֳjlt$nHvZpˉ:r|6 NۋOʹ|N^PWו]4Jp NiV(d'GᲱ/`|KvK˂å X`}!O`Euѷ` E‰YYctm '}4I-v:tņ;_t>^A,6z2z.MPKSFp -IPython/parallel/apps/ipengineapp/__init__.pyV[o6~8 ðCs57'0`(B/i_CJr,_q`;WƪE@4F[ UZM$i`wt;tpa'IN;WGhgyqE *fh۷p:pLҢ1gc3l#:ϒSj y ܾ#/ cыf[ +L ӥTv0Tk*JK ݘZg+RcI6(E ZFS1UdkQƈLK#|6H +nqsDJWķ;>]eѳxsrIYKś(EΩ*VPh7&h{| qm[R>"wm(2%d`j|t.h,`E4˧'Ĕ C@nt1,Aze PVy琓2fd\AJP{džU uj@ud\pulJY6߾24;x#Ò}gjfZ6Be7yÝUQwI|epq7$DJխb)x1ڿQzt\ '^tޢJ]1.tBMcH/ ?~U4"m3.kmggxzz PKSF@4-IPython/parallel/apps/iploggerapp/__init__.pyT]A|ϯh% h~!(×3ۻ;8;·q&(ⳆTWWu#rt`\Bd[#(Dz9V E\sҭզQOo-\q1_P*:G|vH-b7֊%>' )xBAE`kUρѡ_^K5i9ϕJ!pÍĝ; 11 7lZЕ=Mj)B{|lC+;wr1V1VcL~lF$8nEU&N> z=2ZZƝ <=(:; +njaPԱQZ:Swp40D&?f?*2mDf9F nO~@qS/Lj/LRg`ae&^gVRsI}aeN!J5d: Y;5ehdƑ_Z(:?Iȋ>͋X~%Wgv*qg~xtFJBry>M1=PKSFp񾱇.IPython/parallel/apps/win32support/__init__.py 0 Ew} ]u.#SQn!_'&Z=:NG"WKU&B)jJ[$p}=Z}\ԟљLP2{?|ͫ\#]L8u 󵋆oZH1{'d>%nPKSF'BJ.IPython/parallel/apps/ipclusterapp/__init__.pyX[o6~ϯ8}@8k5#Q6WH*dɗ\P)^s!RrQD"/Th!-felGߕk!#LӰE5fl֝U*L|lz6qzt9^94kJig(-2ʩ< a!K7ZAR9rP\υqJrf;]U CAzsSF pL8vMe-s(z>|S@̕p'} xܧo>]M.zdt*Ї&\‚W''е 腰sz]EpRz*se,2[R'Z.׽]qNd3> ,,K&xv"[('NeR3z' Zn49m{TY;TwM N _n̖S|΄܉rb#Qo>.[D^ZxyV`M;97l$SyAY `k?5O)z4=pj%;CظReuEK-'xh1ҥ Z(Y!fsUqԆXQAsF0 zc"$GH[UN;9Z tJd+ua-fMKpmN-r:) _GZ%i1g~_%Umu\-nt޺]z^L-3Ԍ^Nn%d@|UR.y/nc*׬n w28K ʙ }]k\[z ʢ}$=H &`'jkzݼ.'FР}4hDiGDD5x Vn~̺@ ݑyc~r0J GmZeǚ xft!KNT`w< ..?E봘n5\fe+B̽@WlW05*Yka ^r }w<LŬņ-ɯtgҥ1J )݈E&E+8QjaLh@5bB(3jPU,SyKK7v3bWiw6M"-!SSL9~ \ a'PlcenR${"g#6~cny}YrMpDh NUB˺%ɉƯC)c!D Te'oE?3Xy/dN[ۏi)Ͷ vQcn jyC9?0V;P9z'=10swc}*>H ==a D2̮eIzj'q{C[* w"5F_dv=Qǟ=柱_wY°Gp ONPpҺwlܛZfz8&#qo/? Gj\[*C c Z,S<7o>p_ BYGJ}|MTK:4ٸ L.QPKSFnp!IPython/parallel/util/__init__.py}Sn0+tKr)m=8$BİɒT@G3.g`٧> @Iw!>MZb9:颮.-YQ q%l:)3k#NZ жdk[ L)^%&`G%}^Z2crŶ q^z7hvanV22)l;xנ7[ػjEz׃ &X#R_J.V} (OnbRR7g6L4&ceR<[oݿqX?\Nۇ#'_;9)Eu3gT|S5?z~oQ*3U|H=m}c{ŕ:19D"%PKSFgDd6HIPython/sphinxext/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF[V~n:IPython/sphinxext/ipython_console_highlighting/__init__.pyj1 w?$[)C)q\ݝY6KKzϟ;& )Bb-){Ȧ;S!0umc /sB%(Uۋa,[6 *N vG"oK8;~]?Ӑ12⪒BQH{lLq3EXnt}率n?y;Xh셟NPKSF}wj/IPython/sphinxext/ipython_directive/__init__.pyRNB1+cƄb‚Gi\nc_νi9өՔ:1*>R祉*JkHݱގ6ņi{~oƚ h+V2K!;oqxc;砐<:eyk(U<]\FRAOͧl !bݖ׫}}V<:~<JxtL@i- WmҀH4xz*rXeMDBZv&OJ='(N^zBXv-P7yg"R5O* {Os)dtFƝ&u/ugP o@|PKSF UYIPython/lib/__init__.py}An "S)*^EhYYvr9,'m̐9XGr5< q̧\jm7aQR`̮9}P^IoD$R{sʥY (T)FYؠFXr~e2-Õ}mO̼pIbkX22Oer*Mx/HPKSF{IPython/lib/kernel/__init__.pyQ@Di# l]Ȧ/VMIk7aȴfj 2Yl,gDV2xđVpNn)F<+,g-0;wo2,ުPKSF[Y%IPython/lib/inputhookglut/__init__.pyu; D{e%M&e W]K$>dB7o3 z!L=8O{9S;r4.1dѕ7ڂor8vd Dؘ" rm8(lDاUy nˢzz"L(mEXrƵ~/_U|rKTnPKSFN{cEIPython/lib/irunner/__init__.pySMo0 W @nzar0۩)զ"$'%i!"G Dޣ@Yy2dMeng>Tã&k!f,V!)) ᵞow>5V;yMCfҒLI 8`]tSigv8PH_xq Å GoyWny :R(7kR. B{aLH.G`A$%rF۶WXu0$drQvTgAl׆51#ȁ$ԋOC6! Sg5W8ߓG -,.E@JcA[/_t; ⒓2L<2M>g>gOsJvibz'dR~32!a<{euzDx>`( uiŋ{etD*my;9i %_wkV{>TE׀÷6f=ma/PKSFat:#IPython/lib/editorhooks/__init__.pymA B1 D=Ez#}m&MAooUV d1o& d)sKV9YRPd2;9߀;ta^ rه: CyiBB !>?gnGzWy$'A >Jjգœ@ 8,)֟|G8]7oc3J~PKSF[#IPython/lib/inputhookwx/__init__.pyu10 E"c;#,ݪ6v8@oOZ d]`$)XsdJFIu_9i0ÇTRH>ɝ7b[*v"⍚aEE`v\1.˼>pQ/ȆjW7PKSFEʉ`$IPython/lib/inputhookgtk/__init__.py]A ">'F h%E :]8hW$ 1DNcBZ2)w`. LH=O^sID"PR(JEdž $MW.k@[[0cD-0Ve)4\C}|^3H|7PLX\"D$SI 8-'FP &{#Uʈj>/A2{W0io턻+'P9N4a$6uk;3@pFXa:jsOkf IPython/lib/security/__init__.pye1 0 wc2ccǎ8cIS Ѧ@p*+$P̢4{ͰY /SS;>i49R*LOAo8kÎ %US{Ãf PKSFk9s"IPython/lib/deepreload/__init__.pyuMn! erJ=Bv[ hۇD;Sv}x-XKU>&bz.xa3('&r9+F.WcB%"DG`{"S ri|.=7'*PEt!zs彤穇~am{t椀ʽQms貲뇱65oPKSFmr"IPython/lib/guisupport/__init__.pymA@ Ebw<!3ikgI@*^,yP#Jsn z4khUKsKiDb(0i?4zk?}}PKSFBaIPython/lib/pretty/__init__.pySr0 +|L~3q#(,OW&M!]I+Yv T9K5= nlFUg* Ѵ{ t+ҡepc9DX8o (aKCA=J\: &pT6"v==zӄoEғ-\ tNF2f)VYs0(uo2'R^L gaYzK#{(儸 J ᇱe"Lt\;>Xu\ \TN&\E|%]PKSF ی&&IPython/lib/backgroundjobs/__init__.pyS=o lvJ:VдP)K١c.r84:TsP)i:OqBfCN4YՑ>NK@AHEVƟ@ns|qB[QL[ 0c_YxRD•ɽ\k6POڧX3lӈ-؈ 4u"gxV: 4wcQ/k7Uh`F6)|F;7Z|ʆտmN>3-m#nlZzjBPKSF{yD!IPython/lib/clipboard/__init__.pyu0 EwE@7~ ! )DM(qDE<؝A vWB< Zɚ,tKk  xH*IkXfy?M [F&V%((v-5w83y!ΓT!ܧ7__{j[m14MRtT# (v Kq/PKSF??+IPython/terminal/__init__.pyM 0F9EvQޠp!b`No$ }rn@X2. MkVk"0>{),`9u}k9Z ~ft?*AiZ[7w ŖҦՐPKSF3e&-IPython/terminal/interactiveshell/__init__.pyZo۸=/C`8Mކl n- C]hDۼȔz=KR6l"|އو<_v*υ޴x<5׍9ZMSަ [|8:jwOfJ/^@Jw~ݘyuI&HTq2<4;::Ea]^n+Fx\T+J-eW\Umkm;s*ɕ)#45ȕ{\^ɁX{mrmtZY}xA7&joVyՔ=j#u5~_ժVl'y($X\=JLx&5w\\<9ϟ_>L|իO a*q\6g`)jX pǵ.qX,iX%I/''T\Z!xm`3 0W"~M3lSuTSNh"^LX*INV-io"gתn{fk^m0)~P <,΋$ .PS竫ń]>{+EAH杓+ dzfa^ҟߛ%L[hÁ!ߕSF+ㅃuLVZִb!K 4v'6mԢkD[qE9 <B62JYYa#ѵ7kEiS\B;A3BAeW; HZ%!3HcWi7c[&ka@qw  ȬJږ;VYϺڋ]٘'I (e1m Rx2;d=s-j ̭+.TGʉQ/ķ\,ƿ%p͑*y~.E|DdaĠj^Clf{] ;j769]$w.p4" Fσ oSR^')#x0躢/jt9Z:;-y ?cZ`zٰi4u(;#7)`%M8Jvm, WiHh2B^RY6"9YKF vȠ~ThN71=HǰؠD/ )0\*R!(e$?oYc9E:[<)IœJL'+m E*2}g!R!sP ] u<HP ⇮"vKJPX^UF <F E)$٧h߰ 般& >lpęo"@1_bģ:UUّϲNxFFӃtb'le;qQdxj]Xna LkxpIdΘs@'8H/tmK (ƣv8'\p=A9P% G"~$@8 ;5Ꭴ/>B uDrݹD-ذijn I{ʐwϸvxêghbQٲI'壚KՈ{1u S@] @] #Ak8zhw@!=\xR&Ĥ#>a,x*V:\:Wr*VpF#Jw |mI*zӴ8 f܂zrɫuO8),j/W 7Ȏp2 5ɧ-axiJ>;Y~# 0 I L~_HN8c =IGLlDVuf(m[UH}hSP\]!6\ ^A'"X`*o ZCvu?=\#1 q5gv8izpTMN|tF1 ^8'$$"rr"X ~GYFg, !bZk]XaJ) 'U$ /ל~A_Iku T[(d$> >{ uCXL@e`]KmQNt묒B|( S{ ys*ԉϯ6tl194*ML!5-O{20= YޱXihwN,$QC W+mMWWq³(7*TE,lzgݤq!mI*:xD}|2Znnjd).][%1ҏ`EVLϳ,>˞g_ȑ=S/{煷 _UMo#&g()9~fr#f.GYꭞÓ{PcQ@][]Fm'**|5)Wf S;EDBFac@ e!FX1]J$솗gko ' 4x6p.[L~W&̚r HMn:Vup/b՞UpcSrqh(GgdzCQO!(i/>ŋGzt'GG^6M=;.ï:z-[ ~ג{/FcX|sCуm>(GaRR 'MKۇ8#|ʭܦ'̉u,{̴ !6yxC_8R+Oy$%XX||Cx\*cr_z(sV'.]K6.0~jEճ瓛78\?tYek[hwhyv1 #T m PKSFgDd6H"IPython/terminal/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF=u"IPython/terminal/ipapp/__init__.pyYmo7_A9HdH1qPQv)5ܐ\˺\=3䮵R\~:b<3բ(ml* (mĪ-vdɧjWu7prQ2(qi(NG7۸vvZ:h,!^|uAɀ 7#m&LW@zr"6LL|ȪSɪZ,  űu:mϸ\K*vת+T`tU[XVTz H$jShl;YZį`j` $2k>Lcd&lAL&qH?ʅQbg9V^RҚ@+6:<&F+sqӏ~&vAEѹ&:$wKmҹN{)ʒGF+tdqvp-d]7{la6̀w{B(j J325;q} wwD =CcSp^Qa'bs&r!\H(NwPJ< }"H0coKOusAZ{@nso3F=DMGG$UVcF2bJnAix/楫kR8'Np&9 *)}R֡I B%ETqݑ"ZEN7if.!`ˢ]L< g"& 3PqxXC|[JFZ2toO!O !7/]77zO-ñQ&^8PzprCw^B+.o& :Q7;z-pq#>~=[Ft Vx!n}Oy0"3LVmLx,C|iI_G,|,-gL↼.4dPR59>R@5A>Qv^B ZK^W^ցanf?P+:Z$>:I_R&#&5Gژ?WD 뺥ENBAmT5AGSdO<#1m&׹E[w46{-+A>K 4q{mzHq:K-*:2V'9DS$.oO|l<:! QUMMp*RrcrTн -A~ɵer\.vF&ҝ5#؟ ԛlS *,vA-HD[3KDə9F9l2({]X5P-EzHR"XN)ԎE;h̏3,bbE1]nE|JG>9QWqpJ784uR$|;>aĭR ѷqY_CIO6ίo~}/W1> ";i*2|+QPCCy1u)^gXgJ}!q/_k>6H%tG㒜?{OgӤYvUO%5\")QTje3 0LU@h, df8giV)t~O.֝H&BT{jCj|rۦob{MwI,!Yާhm l6BOzv`wjl# q ÚY=Doh giR{K갫1S0Ǐ3p%ĵK,rjgQXkx`k/tuLe@Jq8kc܋Ore:Bw oׯPC%\ieK舙aL$yv/_fIt3-FQ4 `1S9,ڳ>) P5%U8M唱;`R8;5WA[X떭5%*@I?Gnjļ4orŸ\IZgz8(jHrdqClPйՇRٸ\G:oeo]`.*f:?/'"ccQ׊ހ>wRX*}-Wqz4. hE]nh_1VP#%K2j DUA*,*MYAW7nJ+@lBM*JV6 TGzP?nWtհ1O KeE$n=db7hF3]ia6k 5ϋ^(CF2@B2 N)d@gl/ջFRR1>rt?jH͛eP̳KY&ۈ`lvkGQY(<5)E<*a47@+/%8:+bW=g-eмdQcWosbŸE5<%k I`m_%ht9 yI<z#q :2u, qf"l9S*TyXn<&:>n}Tw۷:seh¤@b0 *'xjj'ӵo쌎n=EZetn^DXE*/7ߐ`K^> :)*foI­ViޅHMmL>3^<[ͣo}oJ{敏y S]mt"jvB>pcב|IٽGNyt\}Ē&qJ:4K6T5SR=2G=wğwz'̸6PޢDAN`vӳӁN,bH8W데~DZK*̊4C!򍬿_NIJaUBӉa;ʊ]ַaxlRQ4@y1'7'sevPKSFWQ"IPython/terminal/embed/__init__.pyMK@{K zQz(֓0Lҥa?N?O!<;y;P(Zj$u2r^XMQhZc)V-Ds,!m=_kR˚/刿΋lSNtjZ(E`y%gmkaczE smq-8L1M0ix)3i 1a"GI?{;P&a=L26põDDaB.ݿ<+V}"@ }*i\PjOO[}VQlQS<&akug6Ws,/SimPKSF0ɄIPython/html/__init__.py5= 0ElK'-*G m>H^=kRp *I#2bHb+Wf\P_V_mQr).؉qά Mscْ>I-Kg`&BPKSF^knIPython/html/base/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\y)9E @C R%yz%9zIũz0: r2Klᢱ\0PKSF )IPython/html/base/zmqhandlers/__init__.py 0z˅" >Q;ʬH{& 80ğbɘB+;|CBc*whA^;Yr 2XRI]JTbRAN|r{җ'0'V^uRMFw0^tqY.!~$)t4Pnezͺ݈].MN[?j5csӎI|~xݟIyG70ѬPKSFgDd6HIPython/html/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H!IPython/html/notebook/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFTD^*IPython/html/notebook/handlers/__init__.pyj0E b(m(t`JAƵ{Fe\}bPӲX P J/0I_ 5 X#,O,~w%{m?t5o BDŽuo:;7Qi#P7=Cʹx~Npϸ~ueXPKSFd $IPython/html/notebookapp/__init__.pyVmo6_A`t$KVia( E$e{7Kt8%sǻ{NQ2)%"Iq$5B9HUV(JtP)>t$e\XhxqbƙҎk PRXw x`uLgj6A I,ɇyZkəd<`.iU$6Mk5'_ !X&<@ޚ+P)PaK(ZΥ-o/ OZb-NngJǡdmLQc*hBjҘPrӶӛP*8^[_tҕP%dK7o옔zGl[} ņHZq(jI1j.B|vo+\MWw3zs7^ҏ-̚I|zb(l$$vN`~?o+qvz|3,PȒTDKdZx4JD$ƙi!-uzn\q J|/H@8\LP5{jƧ $L3ĥ\mA:ok6^7:/^]xzRLTzHDMh 7LZ^cau-ie2 !㏞ CFXq2p؅ĦF:nL:9DjOr5v X%%o.Bs"B_HX fQZm*JUyȧEc[3оcn0{x__ȫW]Qd-fZSzLV[L+Au H}M-#\Œ:MmaIc8| @?um O>94Z_!A%Ÿ .8r.~FL6;b  g b'`֜5"st}cüJƕ?ZOA3~Zp[f,AəYxka CGe\dUZ\@1ay{$7MS X*-&rg;.{1o*}KNFe}Fyj){8Wݙܸ#=<> Kgw2v^ʹ-zUu]ZdY\==H~ $K S4j ۲"mADA+jgS\*J:96|w@gPKSFK_IPython/html/utils/__init__.py5 0 "O**$tJM(-T_J,_CzFi|fKPKSF̦ 4!IPython/html/services/__init__.pyM ὧp7(t_@e$τq,?dw~8\}E쳴5[Tl\G)kdž|O|]dl&I䧷XL~oúޏ* g_جLO[ PKSF k +IPython/html/services/notebooks/__init__.py0 D|E$vrĮOum; Y,E%kuyT6J2{.0&PDR*IO/7xAd.u'T6Ϳ? { PKSFm5IPython/html/services/notebooks/nbmanager/__init__.pyQAj0{%(PhBɩ!ے*bm~ߵSChȡ'13(2\,R88(b#YSs\n0بy\e_OA:^ֿ2{SGټم|_ch<&Ja)_qH5{0(OHNzxGabx37<&^|+>^!dF|6EKIc`젔}fbFP8P+ejRwD~vrJ^ub` PKSFgDd6H1IPython/html/services/notebooks/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFz@IPython/html/services/notebooks/tests/test_nbmanager/__init__.pyn1 0 q{uuBK,NvaK*nKgT[هbMDApxm8]#TМ2r@: I !p]i3lRG!$Z!'80X]0h3m;a(sF 5 SBcI{UÑC n۠2gTd]H 䲟840h? p,{AƥM_s*Cŭ,*(kǂF2]-8@$ 5 =L?WiF6i(mrG:¦|z76!tCg4!_{Pob,4cx.ҝHI28X;HIIeө}m~JwTjב^~M PKSFZ3IPython/html/services/clusters/handlers/__init__.pyM 0 DAݏPgծ-i xUA1y$ ]TC JkGm)",SU`^*{#1qf9c={ iI]y@/=y/nxtJ>b]~ VFg?Tc֝χsŖ^7:U.OOPKSFȶ^z)IPython/html/services/kernels/__init__.pyU1 0 Ew›[(AСнrBo_7j(%[&`)EԮBT=KXznm1fAaLyqBCtp:+ʋV4b/U=ϦPKSFh7IPython/html/services/kernels/kernelmanager/__init__.py0 >W@bcQH"uq[.>EJFc@Ģ*;ȕ]Ct`Z=ixr7Ip#I3}TE|Fj/P^Cg6%1m-A'4z-fPRF(KFGPKSFAc-2IPython/html/services/kernels/handlers/__init__.pyQj0|+vJhE[K9QWMO7\ FE6ٝI -BiahFIDi.Т"C.SFfǑ@[8͡`Fr74\D+&t;キR0P-˒r Z@MYj(W}t;`k -2_NWNլm`yfosXE!DY3ad!}så2k}b%{>F( _K?م۸ğ<_njĸzy,s1|)ƹ#N2Co7PKSFgDd6HIPython/html/tree/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF8}&IPython/html/tree/handlers/__init__.pyu;0D=Ŗ(@ ,`{ZchnL]:;0J,X9k1߬Lux:{tq `n /S6>3r-_PKSFgDd6HIPython/html/auth/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFԇ#IPython/html/auth/login/__init__.pyu 1 yw_A[loowe=|q \o],TX 78[:,gS=6*hq ZswdV=qji|>R.|7PKSFJ1p$IPython/html/auth/logout/__init__.pyu1 SxL){+Ro`! *Ș/IlA8bh#B̅EH$_rL8Tf|a[|-)n|aܫKV>1N2} @R^_PKSF{[qfIPython/qt/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\y9 @3 2%yz%zP: 3r2Kla\0PKSF?Wo*IPython/qt/base_frontend_mixin/__init__.py51 SdlбC7*Db"e[ׄTAUb/G#a*Џpk ZTߞ>mpuPKSFgDd6HIPython/qt/console/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H$IPython/qt/console/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFPs?:IPython/qt/console/tests/test_completion_lexer/__init__.pyQj0+t &J)95Phnu1‘lQd@>vS}wgfG2wF]*"5.:#ޫ?΂j MOE8Ih-d%=.#B,𩂲*3w~zd,K*I*K}*޲w(]y<(DYvbgxl jPKSFj %IPython/qt/console/styles/__init__.pyAk0@]![BmaY2s3'"^Sg=t:$~™V4k@)U4Zs&*J.2TRzo^xT%Hm7EtI%~mGsAڜF pc?j^h!BMT{PՂaP*iwYQ~HbA0.SWd7>$fIk4JGfåba$׀ko֗Ď_Ìk.HU ڬ)x^DzKFjq'IpF3sId?xWv+mwݺtNni)5tG@k[Jh;pUL?iJIU2Dx^YE366oZC3ׅI? PKSF8nJ]lxml/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZS` pPKSF lxml/builder/__init__.pye; 0{b;rK҅aX!Ƿd4)߼%egBja!KI(YJm_>Z0FOw&7Y M旾{RXE,eYFlwz(ڿS-K>PKSF=bglxml/isoschematron/__init__.pyRk0~_7YNVRCe{H2H(q%%q''c$&q=wߏӊ\BIVlYS/"!w 5MFs^Z?7^l*$;IOfv^Wp͵mikxKV syj ,~a+\lOszL Hhq -6![!tEܺU)>1."˖??.̇2ߒ)2}boE rgS8*v]{'U5gD kI!ǰ)D$~z->loTr,[1I&y%BΥT}XqK]$WF2ˣ6s5R;Ie:O𺪪4E(YPKSFq!lxml/objectify/__init__.pyMo0 *1 :iu!P i}iJ/8I% ,Z +W tT$Ȥer^R8g>yޢ[ЯR!$R:KZ1@4$VvbPrG1= hHBAQm" P5 t jI 9ԥzYG(fc@6Z>V.EpAhFi ~jL(DZ 3;.~/r7A)v0?''95ƟK_qXM=WNnv]\Rɳ}˻g<cR<`Bp?,\lxml/sax/__init__.py 1EtZ(v"!%2f)̹^& 'l'B)q] ϙz&xhF}{ rȄ(yɥ+;;j*5XPvVt|o7>2R8˫ZR"Q%7ͽ$ڪ2x kr.\T" _PKSFK{%qlxml/etree/__init__.py]Ks8ׯmg.܈9Pes"$r텡vݎv[@ԥL|D""^~^ o珷0\=|}y;_=>!7r" ;x_~<=i/i&;o+*[)H}yz=[e>WnW f/b3mW6ebnΙfݗ|~?}(u†w7Isşǧ"OlomxzyЏ;hL>=[j<ÏoǏz|{?Yb=ƚ<|yr`E 42ތ}_Rxòu8_?ζ!%L フz~R<|(z?S׼`;>e\]&*WkUVs, bM ^,y?-@st{|zq<_ܗϿ,\O^D3!luE/,[22O?.yC279 ߷oOʢǕџ\ܼ<>>+y ݤjx=xSx ##~eB#He_)+vMbl/Ou+} nj'/9C}vE+BU[\wP/o !!ys龵e/wea&.>o/F2Y3VSU?OO-UmJ uY˨L~=ʹn/u Dt}. _Ae-l0 Eh3!2_e[táߦ1uoZԢ"î:}E#hdL7m-T:mA Uc]y~ {I6Gh\z=bB(pfLpӬu^EU &1 ¡o9(@ V++vNg,ǽH^}Dp?Oy~0J63bdJ"y"5plڕd /d r+YAiBhL 7&k!Yd%+ӛϓ!Ī6f(en1 y. u#}40U@̼@ߊVyW7bt0d0Bwθ VQnS3K޾jjӨ{.Tֽ̅M@+#4@ٗJl4+JLڍ*ۢ+BL0+xXe0UZLՔ%I5֊qoUM5$*/sYvy[~ILA02 9$1~A5 ՝0`fN jLl" o|Bh:m$gˆI`"ƠL)#yoqK2óoBr7xRn6-nq`;'C[ 073^pXDi:LO+= t01 |;ls~,Q!@;ֆpJ(A`P uWz=ƍV[0lqE"Bz/:: P%oFz"|TPwE2qoH LʮX:|kh 8D\3ܼIM]C;t)q6 LJMÄL&wp'"iUL^!ܡYq'+06G38Pa9!;Jtڦ%)Mw۲aJX֨"Sm+ 8ހ F*?IsQtu2$j0 1>Iw"V `Үe$}GNꕱϤ 5ވPőhU^؝l@+(liH͎(|2T9 C*G"En,yfR%&.&]ṃ 5VU930Gxzd,nm_֔V H2G0B=kGor)WIaڳ%D[O]P#9cXXnPXup<јvG'x34K:naIk&,vjbad{|U^9fYW͐eжK9|S!I ƪi`-)BQvFpM9-R|5k)UweM)EwXeUO~Hw#mYqJGm[(V#zXk+,խ$a\@֬7\!ښWIF5 jقGt%Sw-JE~mB]aH_~y+NdA\m%q8MZ99J2I.8na-U! I:E:]8't~0D5@v* 'Bxf+Cly"%fV9cTmKQAT]䪁!#VpQ@X3,C "My&®&^ " wLY AN\=*RW99KћC5.u%.QWs]ҸF⁚I~㟾 oZ D-M"keMu+f1駪s#Oi?URЄ+xP (uC-.vVIkMϚ8RlJXIaW@LBш@Bm'ȡE UEfGߝág|_ KH f06>Li^"3ES,ܿV/0vYUKHOt ͈pKV*Pa:QpQ@7Zf)ɼq'mM'.q"Ucak=&Xd-V)-Cr ]"ȵeѮ8,ȵ3rA3r:H#!,v-R)TO0e/$hʔEJ1e)%#I8DХmI*m.FMy]afXuCR;UDyA'6.m8+u}c믩Jf~Sq3-mx_۵* zkCVU,7НwYX:E=rv& X=q>HjDqKEm 4&-?H9I-D_mm,ДF(|qA> V%S}Z4Y\erp;- I,䦸CS})-BC{q50FAqC S-4|U^_k!2OvDuIwJdVtQM+xީrDw\k)P먱 o X_]_> pw3to07j,rŔ/GMس0ۥ6ɺxʰ|^ՠ  T} O~Y`nRk+ShL2/ƞeΩw0cfUq"qPXuTsd/2b=$P'VvY_^JA=et:I$ٴO4SfϿ `PpS.DUG4;}sϬz"0-Rɧ}gN =ZP3q ZJD8‡)Y|“g et=f}='2i) Xn&eHu!(o5 cjjB)^=>=za*/x4'6/ǿiO/W wa_>_gcrQao|ṕW}}^rf7gEC;~ l79%S,:{|C }7/?ޥa/ t mZ )L1=]q8.p%oą_LC)T VX?暂!s^`nL25>O~LZmPI]닾\M&וn7iua s%:sӸIw?s=#y@EBמ1rؖOE{zys~?<^/3+2 tNo{?Yf>pV&>~|1;(|Q4E¥zu)sY >cѥDJl9{$yQ~NYꗳ.3}c߮ꗰ"iyJY 7>EX'XeҀ?4 yy iW.@/s鼗KLv%wǯ?/q({[.qZ?3_tvryjIYYvrb/Ԯ?=@,.ǂױni9.sKN-~Onǧ?pX4PKSFaCZ\vlxml/pyclasslookup/__init__.py51 St+7MAcDm ۋ&|Dߴ\kl5+3fU+[rX/"brݿPKSFgDd6Hlxml/includes/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF.լlxml/html/__init__.pyVn0 +|K ڮ@k1AX,y8?JNȱcD#CgaM2X*XL++5JE`Fv6C0XF1N&)YʘK}%^Onƹ4@ ЗqN QR\+(AOqBV;ǚcF)OK:jVڱLbȗ1owoHmUV;Ӽ c>2HLn1%W@WyYApZKaX6:4>)W}1\;r} ҄6܈:x秢m~x!u}E,_+ xu``4_(+95gΨ 4 +?_Jf1Yfͺ!lD7(Xaaזꬔ77 ͡Sijkvu{4g߮׏Wk M/z>[<3v9}~~> %&4Sa>fUf[k$;HҴ`%7"Ҕ'%G~@ç] *wZ]CJWAy43"D2=-a[1Fk8G3viJU#O88lWUvEsڇRݯC<ԶeF|㺟Any)6,L~CC)PKSF{lxml/html/builder/__init__.pyen0 E /<f!YtFJtѬ p0A$pEw犢Hʇҗm{x߆mc cyqRx9 h'?tw?m-HJEJ  1( rRy@4<51W[`l+3l4Ro2\E߄U##3 n+֚Jزb(,-,w@?~"[5[(XJ0 kS26!V0D#͜QdgQKU.#UMx1~<`9d"i`0 vn€xK2Ż*[!D_,$sa, >)g֜ ͐ F< wOu7ܺa.J>,N]ߝG{e?PKSF8lxml/html/clean/__init__.py}T0+r TJ{XTJUeg.'aY2ͼO }TJKTi}$eC6HD,pMPE5Q+5w˽G"gT,Y^ 0UÚ B#J/p!G;Jm ?Yd @`86*]|I0_3G͆l3bk*Nĝ ,gؘ i?eŃ,{bn,VZ7 tGUnݠ\Iw SɁ9a0i؜8%ކ].8hq`ޛ0(y%RHZu]>-vzKitfy/x(ʲpUvQv dJ.}Wj ꆤo%Ԥ=dF7ԷЃ[DRk?U`NCF|T #6v$kPZXapg3}y_MPKSFu lxml/html/formfill/__init__.pyuSMk0WvJO ДPXXDTF7ߑlv\lӛ7r9/k=p+S9yEBm٬L*㊷^weʐ_A s`1zyDzDa^e weRBG8"ҚΛ)jj0e n% ,hȭ03Rʕ7›Jq…\٪Y<;?"C `Йq[k'P" oE/lHS{$>ߴjAv"^x8lv 7h- H0D eȟnv?7[ڬViyZ:X]UX*:fР lvm,ξH.6YW$^7d@h! $#=>,?)E,M޿GG]hum}^rGK|rxj+i^>NPKSFUlxml/html/defs/__init__.pym10Ewc{=B`7VllaR)/iա"L[!M6|ΙD)Eɍ\jOZ#Yxչ;cٴv-}^é)4qZ J8 Xr3dZɒ)54}a怄vϤtSoPKSFVPflxml/html/_setmixin/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\ZYԴRP(PKSFJ*7lxml/html/diff/__init__.pyTɊ@+tB99d| )I%qo]OdZBr2~WU{s!ZBR;)w^bԔ$.J8geH1 =.v.Z}͇,goI#3UxϘMĭ3=R`'H4|C!W?yz7ݔeH=-&3hC VK՝ܭN .ty?e̐,vZxV[dek * 8/NǨoO>O3Hz [*6-jnqw1F#䓣iwH~ tDIOt\|.]>.Kϥs7?PKSF<[47BU?;dmO ENfY=A&9*=0ZӐ +AEb!/iAx4,Ht %N KP޴ UPb #6XpMWU_GFg*RKHifH Ɉ#`*;=sP^d.mI %A1L 6wv^b!p^] PKSFɱy"PyMca/PyMcaFileDialogs/__init__.py]M @+᩠ 1IJʐ:BFC.~L|`U@:C10dH#}RsYRU6A,)4}ߊW/ +IJ}5v+oFeuį~ڜjל䝘gcʯmh[4 } AXha\|1LCtӗ{Sx\":޸7r  )[w -<\vX& [/ki-UwS5:WZ[-1Da F1oH7GzGW 6z̑=/l3hSbTIxo%gI|O- QyA+B~PKSF#PpPyMca/PyMcaDirs/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\@*4'5( (>HQ QP雜&]2u@dF#c5`PKSF"PyMca/Plot1DMatplotlib/__init__.pyTMo0 Wxkl@muM6 ʊE4YnQrqsx(ke6fiC6 ›REon='+yA,q\BZDrڪ瀏y^t_3Wu;bRMG;PKSF踲«%PyMca/RGBCorrelatorSlider/__init__.pyՒMO0HiR8Ж$Rچ-V$ƪcc)E G.gVMumj IByQ*mh4Hejd n[$BAT/b35I (eC͟j}cl 1 uL?oY< e0쎺!`UE➽踸 Bi+7rҸAeKK{z_k5msi>¢'.36fvU-3}{%=Dn#U[ff(3 ggJeɟQ/TFA{E$(tA|W ^x ?@0nGRW`wÍsSI|aa%(f' kYZnxŕ9v˛Di xѮF?PKSF'pPyMca/Mca2Edf/__init__.pyN0KPE mwDJYvPd9n3jlۡ3q] qt9>,Q-k[keJiUE*%ҹb!KQ2˗?ft,ċ&etn{è)ثx &J>{BKS66\ a\X´Or[0%v[0m|((H_ZTT`7M -n0>^ 1!DM-+% kUР4ضi#M{E(=zVmX,L5L (se߸E/ slҪy>YIyJͺz)lu?LS7d6tbJ~C1d}/m0: 1#Oet~}|PKSFJ!PyMca/QSelectorWidget/__init__.pye]O0ϯ 1)(pG!Ƙf麭,HM9}鉭)q3U"+HV TFCܼ*Nx@lJVr6@ܢwdN;:Ywtxɋ`|٭ׄh0=αNR{%{MTkaV6VHHlb!KL o;,ݙ>&-=I؍9s5[W֫[IN0jZM_PKdSF, & PyMca/Object3D/__init__.pyO0$T8ҮV"eWp@(25x")>=NƩd:ЙNDӂ6Y2TUFZʭXlh[B274kŞe*/n+e.iR{~çfz` C} y!4^L0y߲<F\Kȯ3 bniԳ7}0$ٞO W~?:TzMAbS32F &&x6 1Y𳄰[8+C#{w>_Ȯ6^~ML@N%4d TРc'%-Y쳄q%i_<uJQA (⊸5?KAsŀ҂I!lKH6ЂȫX03Vyedeܝk ar 99iJw54SڒL iJf+R#|9'#LjgLߙ&֔Jƨ*+cVVi@(IwF"tɘPo)`L,hR(ۏ. !6]Rp#Hsw(V;GOy{S[[w x7L_^tlyjMc,XzJ2.Gq"@V!^X7ޑnz*`3q=ek͠uJb gjG3ׄPKdSFu $PyMca/Object3D/SceneTree/__init__.pyUn0+tK;MZ rqy( 2kTI*ˇ,%Ρ=ɚrȝݥRa,+]IH:,%Yj*xQHM@2G׏?!շ oŮb"&GūZє0/~5{~L)\A4#^f33ϸ$NcYN+)!n (T~AC<(xcTVo;يOg%{z_PKdSFl'$PyMca/Object3D/GLToolBar/__init__.pyKO1! 60HŨAcLS;Jwl;!B.ܻjsNϽml!Ņ/d,inW ĺ 7)(X0vP~E;sgzw[{BVKv !Bs@OV4G4U:FZ)f:P!ZĀ!wkPXFY s"4G=!4*I}3faUv]dS`2:%n᠖W*~ê㹾˹K>PKdSFh<)PyMca/Object3D/Object3DCTools/__init__.py0{"G{ބ=.zz tZ6))[iE&+TPUdΐNT>2Q}|/K ϛM!x{aF#J_747v/q?'g Uk0bM`_tkL:͢ɋ?,e62l;Le| -v&1To$Q[q>Kk,d5Áށ ns`Bf2L ]JβZ5贃 tNwc!WB]"9FiǪ}+g, S6dPKdSFZq-PyMca/Object3D/PrivateConfigTools/__init__.pyMO0V]>VP+54 !$Ncv3vGDOx<&NRrLHZR3B0 -.4-W>+WI !^,$ݚØMYl{ͭm®^eϝ2vz"ƅC&bF;-fZ ?7oPo;Np9t5{6jrtwF4ca,a\v^\JckByZ(\yXZs PyMca/Object3D/Scene/__init__.py1 0FڂMR*.$bH IC"^ 5TapR] )To@Ny; x6Uɼ 3irkYȗf")kܲO_MkCCo3h;.S Dծlcޓ3FӞm/PKdSFN6/(PyMca/Object3D/SceneGLWidget/__init__.pyS]O0} 1J|@O?bRvv]`Syi9{N]"P,iDwh0}ztZ>e@mbvu?͆YHHVAu6gXШ4<0 Gە|>>PKdSF4.Z.PyMca/Object3D/Object3DRedBookFont/__init__.pyN0E J"MQ( ,㸉Ib{UҲ`s59el]Bi%cT共@ 4`(ɺnF]< |RQ,Nm(K VL9GC;<z9Z/*OuUQy;#Lȸs3?hjLzc4xuixM(-ya,QYd5'mR:2)ilM#82.eB"] 鲡[5;_}Lf/8keuJ_Iq3=cB~PKdSFg(0PyMca/Object3D/Object3DPrivateConfig/__init__.pyN0E JMDY*(!8Nba2*_R_9gfcp"-7Ey "Y8ⶫp*6/3A <~ GIM1Zf& oO$ƌ\V_80?΢̗Tmq^RKM4yҫ[ϥp4]b@VSaTĔҼ]貣6I5;\"u֩0TFɼg &NLdv%5`%j$g  PKdSF{>q/PyMca/Object3D/Object3DPrintPreview/__init__.pymUS0~_7tơp3>(PzzsvђKڤmvownݹ&9Ż2f !Q L)v40 @ WWҼVx"t1{Htσhpsq;C|I,Q!=cx)ON'7wh;iXN3)^qq1%8 ,d,SOu3%?cyj#JY 0BQ%,2$E"$a_uCcгy#ahNv9?twn,%z(1ÿ(]q)&BSAP;ruq='$&KԎ'i ?kUϨ\PKdSF{(x'PyMca/Object3D/Object3DDirs/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\@*4'5( (>HQ QP雜矔\bgd( ,.VGPKdSFA)PyMca/Object3D/VerticalSpacer/__init__.pyeMO  nM^P1q5Ŷ4N?gwr!;Bpz=dB,+֩A}#_Q }VJFGOiL{t?l\! hlTÜ SnS&mi餶nw+U]lNJuSjg$MNJbBo^.gz#Niiе8GU` gɨ&bPKdSF2j)o%PyMca/Object3D/Object3DQt/__init__.pyYw8 _ysDjw}v]CK2E_HљY=3.9UeD@ @l|{xxzfUo[$YlQ%yvD6Y+<\CM?G7;Їipt 8:.oo೛׳&C t6|ntv7i^$ka"Ϊp!xl5^6i]XiZ&Fg[Lo%.Q?¿eJEeyA~hvGu,ȫ|m}ɿŗٶ.y]Vy6~t;mh?fy>$tQ>NON⹬7M`qIT"jcjB8/qqn.>n.afh_e0wQݨ&q]Uyօo(kTdIyTF}^')j?>Ѯ/Vruln\ITq r&iC9O:MVUR?zkm0 O"cy^g}x؀݄ukm]05nQ8 =pRD>STT"H|);|a̙а(?o$᧮%rUw q4Z5լ;́?at'w<;Lo0LLpx2fy^ئtG2INNa!_6|*:tlO2x 9jO@ڮE jd&'w*Hux➠Ǩd+ݍźEN&RY<3x *xb `Ҁ_D%kky\fhMnER#P+ecdЄ7Hک'a/oI3 '9XBֈbTށU[8~V Rij.DzzX``j^vc uTɫ|0ɷY< Xv`EQјPi[2?50LpȐ-Dgϫ+CivP7[/AřE7G4vQu 9;l!-[l,?& YdphtVSB!yΓa΢rio+2vjq+lW`jBBuB "Aޜ\4`T@xvhD X& }IrLjZ 0T%y] 8]OЏ8Xf&iXb=X凒:~R^Gf v{VhS̛l\;vvSi8AOm42"(#.HHix? eu RLot4m?[90,"|)nLTGgYYо!"߲.Fm]8[V@iIxFI"߸uJZFŻhM筐E ^̿>"ogUy?蒁5cnrtb6n:>X@on?DGqFB >ÅA<Ք^E4yg .y ?QҹB_1>'g#􅩍G "f%5Q-u5Lg$/>{S~&Q:8,ݢ"LAʾ!,cr 3hqrIvՓo:u4&lc66a:ڳwU>]Ftڠc%}z_w?G:8p23^eWY,%*Ĺhɏ\i@0(`6 `i#VhlpPUFxÜeRЁBXٰQ>ϯdC'cdhf頖m'@'鴨[+KRi\.D]y.Tlr400 CYM$2c c&HߚRFN^ܲ yGO÷.yzM$>r>4Ei\U6.ng0z$B4) |6KISGHRէ~9i;매#9χIq&X*HҎHޱ:%ojsEdZ.CWǂn0_f"t[WKKdN])K)N}(Gػ:" ޘ!|CƔvwV:xygƃh˦x(ib;Ga't)hiMʴ62$f& x9$_۞>. { 0LI1 ߠDeI 2G1_|^ s,evI}jҾUH(I0m` 慇}QÎo /q&C [9֣i8QyTV>"]\E'ً 2B`1U61:eة(BieЂϠ;_UcOo=t'AH%*"@ir~H&Y4I\)9+5$%.vfqOe)Gv,/׀{0Q! # r K~-`R+w lХÁrõw$ I=hw$وGRDMdhӉ(JgJ*G49f;eG< Z/Ďx sjKC2 ĿyM+EBӤ6hXj@ SY)Q5(Jdv;@r4Fb^~PÑ72 C*rO'>gΧ_o1`YqK '4]^e5.-nU RCi0< 6!GN` 21f,Y@rB#i9IXau,+N Ǝ#~e=8ދG < SuܞwY\H ė2=DO\*C:a4dK$/dGPSπ*_bN u~0ꧧ.+8Cڣs*E TY@O̽g9a7=B lxW?yqT`Q;g_՝,ʳiR&&ȋw&Մ@v~+wD;ڟf9S@$N+T* Tip߰$ʮEɡ ,#P]@ 6xOb*)}`}QUa OIl5> hq߇uAƍJ`B_}tǂzg 2^ B; Pa[H(䯐!jҀ=x2:sYΫFUċ#N ?M4џ&DOi?M4&4QdK>by[*V Uox[*x7VtXu^z|Q~t}DN4krk\ok[(..=wM泤,),)>K`Oy.QõI<)JuGkū8[q`ŏ|M5*32:zB&D y)آ,Y m%trۺƔ3"fr>;)yF[CuDdЄpV;LՃL8r3+11/m? (U-:*ĂX*C Uf3od8*'|Ŷ*z:y߃I\=,gnIMNg WkCI68fkaVLNS-In>3jsZ~|c?^s\(M5lH"@E\E v[ۘQ;0Gid5,u P?M # UtUݼg ~:p +N@m< L3wYQ nyv>ƫ?峸pǛ6onK=}lݎ8@LycV@I$ʕ@Y 1D0 & 1t(t0 aT"%;Q0MYnSl}~DO1r|3IAxqܡCNTY 2E4; 쁃0BKK0Mb'RmQd9금Z9Zç `Kk[5\%h㌾r$WOEf7;gW ݤ -5O*ު$a{HԀ5@Cn67=]vɽT)khq1 =CFUŏYa{q{cn!˹0Pb)l"nmMwO3r0pA0l3VEF,x8r_?'ۆ6p#COE4LDh}*I7Yj.|J2wan6 #Axs.(]r#V }:['OT}jkCF6({mNS!eӭ5 GgVHk8l (>y]e[5317h'Î* ~b܅|ՕnӺ3nQ#E>QE;'萘_;4'6ڋc 5T jwQ=񃊁/FJM(n,X-Y ak3)=Iy(f%? .%BV!F [అQFAWGO _̇?}p{m0J35tSٸsG# .~uT"+F&3lZh0"snF1 75::ۜ]=f8db9G(C`#o,N% ڣ`H1XaJ/H_-=7웊OGŒZrU=.-ot&Oxqfk@9-W7ux'hì7H ۉvr7-]pB;lspx8+H);߲@ q7ʄ0m!9ý-eJXjDnצ2rH-lZg/ٮT/d9+?um8j6LڢCDJ.Pvw:lں=Dm\/T4I$܃Kڗ9iTbDt׵R9XjG1fZ8ژĦT)m!>Uj!9QmdEeB^k77`Ɵyd}6^KA,2]ڛ8̍V:Hg8Peq.50N}d=e#uIҨ!݉=ރ=9@uHOQW+hk6ٮLdd?v3wcm&{)Q.x|9v>ە񮼉%92ǻA|IIsݲ0 SDߺ544hU:K gVaDZbh.L65}'yҞIwR>V_8 ܚVqXXfBDY37=r g讆Z#s%(,XOU`KmeK]QYѡ"7lԨFR춆;2I63\ ʮuҨ\xQB^3d%x`eOC3n1œ;h`Fp |݉?tdcE,{I^_PBv*p|xM{UpmIoē֬, It\wRyJT"L=h*i|Y+2m, ?=߻Mz($q,:c 頍4Cxpǃ65I>yZWIvcŹRkG]W/sJjjB\\/mн^c[sV8qg#H q-#L~QRl <-twTh; 0mN~`UtrNxt34ly*qT}wkװ9Fͪz'mMg ~ QBO15j`CtF3:V?6PMn^+4[EC 3l4&!G{< :Q8 Y"yzP-%'`oW3t1xQhp3m1!b6F[_Mj&xL18dj:'euF-Jsf.#027mE-`4F fcI0r~"'A~^7 = ?ou`jkk3? K[וm&¨2t72^҃2XeVO0i (?]𔠟T=wFA/}(eҙUA  e+WXU%hTl]jRu-g[ a_X?3Zah"gWۧ}l:ۧHfO@͛V^O ꓂咂{>)v*_`d`SˡHHqbNR;lJ)yY`o1. ؏ [Q"( f:Mhjn$RÔUؤURqoŧ!.ط}o 2T(PtZ* D°'2F*q4VABI46z[zՙɟƱE ўƗ'7{FE.uMVuQj@VG3C2Ĵmͬg&TVzpi*NEKTiR*NF;',}E^;hw  $jӧ&0DM~)?Q tXti7̓r,=p,2:-[DžDuCa9zdհHV9YoM3²( I<8ɏ\ `)vrh[ӎt6-n+3; C@9L(CIXA#?F_h/4|g/gP.0` uI Bsϑ͛(_Ut-?%(,S?\/:Jz2C D>jLsGrnz9C~Ey>.wH6ѳGN@JK|V^L|9wH2T>L(5ʄ̽x&HqN i`?@R"$J̢rB-7t!(.@Uni*`zqn?5Pnr Ӵg$ uZ^$eluo&9 /;yϏ^vnl}4,)R/e u͜GK qi]\s_S[\G=$ hx*v%jb|H2 cP B.y\}˭uE_* qIG$LѾ9 Ajʵ,j0G0zWT[fx.KA3l`lt؀k$7:GL<`kk]>?kn3g7W *݌U/gW% wrZveKtT|C>` !<GH  ^"8zx{=^?zx${5ޫ^jW{5ޫGϷ^*W Ux{ޫ^*Wߍ ߥy^:Nuzx^/:YT"o O&@dOd2F>3R^g ^f'IqB~L®$Ͳ8Tfns(K*H?81 L>Ց;rapMӛY2-aI~ﰇB6;CJ xX2XS ]ׁKcO ҏN @>k·Ldra@dLodB4RatH>y2y2^_ ]{,§3Npɢ=>wSleᐟK>d|gE +MH:BLn1B/ t:&T t SFf5gY'Rp7Ȍ۝$ଜYլw(M-ݣZC>,½}ksޒ34J5`Z{t&-M)ocY_p A,oNn:hƥhI+S ]ֈ5ݬ$'-X InuqRФ[u`EB8{U\%YJ` 0S,Mp;ڕSYHn`wqØY6OiJq)˨ SRlP}eT.I-vbS7t5hAA̓f*S-J{nϫL{<_GOܗy3{cW&6;%S@tm@o2BJSy<;S~}W/yɨ5Et)hyozozozoxozo{q0]f]%mkT-vSvUP򖈷D%-oxK["9𖈷D%n,E +ne$ e\4_b*dg CJMRIM(e.Flg)"1G&=Ƌ9YV74O6h";{8T[yUQ3k] qU.mHPmSj"/-E]BJ^AH|.I M~U LLDqo:]ŊWEx!LMgJdI>?\1?W hvg IJ 1vBi-Yz3NS[u`h䀓A7h?gS,0Kʪm$SH3#Jn 4UX(Zi\"y/Bzr&u;z"4^ ϻ)@wEDu:6第Kx̻I_VeیnV©!kū8[? TkRQ>lpK_ŒL&~D]G}S:2[TuW|rm+rO;rR7]ͿiP6:%lp[H|Rҥi;);H3)5dn@8K(Gu [P;y+w$KoQ"}s`Fy?˔}PlPyMXc-$/ʲhxf%G $UD7&ٲ}fiRx ]%sjMH-}0D:5gfhGٞسTtFzvm()@^KY 4g`؉2aq%+ *caFieoKv1)=myg!93uοSذ39*KI.IC^Vuǜ|ƩV+cwT@`go8 T̀x٪X0:zEa6J-([J#vBQ/``/<0?2|\XF 1_\[Zjač/m4J()mltyhNyq~:?Uq;";8O ,7V3byr  {: ! >Bg`H |<e/^nkTq) Esu&QutB-WghfgW0xl< ArvVs̸S)0VRl="V'b a1Cշ0ܳAWB׸3\[^.^=gQ-䐾\.n@s=GTL;ÒMUdD`?hvQޑ ޖ/%5ƺ]x߀w]7Tam x ;Y]/w"Gd,#|DY>"Gd%}W졮;:ɘ5 %9ő$Iƹek穻8d tanNO.;Mβ[s$7VqNx%5e.gۂf5 ?RȰmYNzs'w$͉SoqZgOO,ِKM3tg sq-IVM[y4IJхsGYKػd~ZC/o ӽ!1+=24PbD'us:U`>U^GŴ I~G[;2ЄV-TV;TR6Mx fMր/@? uơ7nONKłd-Szt9OG,Q[eIރ#J&, (6{UEj'_7v~5d\Ǡ.,gXQb'jD4&7Ti'̏-Dgϫb>3 psDcP/CٲfR}'LFl5=;z]/!^m6Q,*&woAoLڠ6^xaㅍ6^9aC@?%o(-:^xㅎ:^q Wq&y咗K^.yg:tz+ /p /p~$pd3C`boyţ^gϙ̙ٖ(ɽU{߫^y}{R.uy{]^?..uy^>y{}^ߧ>O+^ WBzBz{=*4^ WBz{+^ WߩB^>y{}^;yyk^F5zxk^=́WBz{+^ WBw'm#W6C?mGƟ{qm先"^x!ⅈ"NxSK/ERKBi/Iq-yPdhXS|'HۼsH^* ۾1BatBN-܃_%u&p>u<=]w$v~|([l"uz ԘmbR琎8H8YW2kn⎰yf^7 ؗ::eU! }F'0'|?`ulLl ( ة2Rt3u?DGHmѹyxkɎao)"2 =~1ڬ1f~~t4W ەe_TX~:߼γ\&؁\͎E^>EZMְPi0&aVMS+[PW=&Hn95"ʖi\tGI8-G]ӹA# Ny3ڧs@J 2LJ&@RFw÷Ԧ$R 9pNw'?IՏr9+t!gEA'c&qV"iTE LA}K&=EV!?S?0.T<~ xT9!^Agk b6ĺInW˶2e?ҧ"VG޻ר(,Rg0͞URRX1اqw[=_=_=_=_u=_=_e&䅽xޫ^jUEZ_?z?ku{[Y*:c7W7&^&6ݧ{dkZ@|[fFF-,7M {*kb#x ha?}djp$N#kuGFmƿ2U*fv;]IVƫ q`sBN[Sڢ-@ٝúGzs`o{Cۖ޶?2{c[?g O$5w ';\އxptHCtN4ZG0 n$> ;9Cs-QUA|%Zn׋x؈~p& 3)4%484Yo@b2@u`0Fc%iƸziL.#SDq"j ORdʯ^(a,FŲ,Q&dzbh3lcɓorĚ"d2W|?SO3jF If#uv‚ 2pgbI[uPm!էW ߀m[d6a=~#wZd61lHdpڔ! 3^>'F+׿>r=vRK#;E/Id|q&'JWU GnT8.Q$Eᄃ'@`lyR|:GXi2.f]ew2ߨHU#lI}\ѤL׭!?W7ԴDʏ) T"IL!#QHWkZNHyX;{7+g,GoZ 6һVH"VͰ/:帳yBcoi]x&ocwC-ت8+UªYcmکB.GoKM^l[/gr~'ҽ"öqdAc9_SO3d?{Z_DhV߅OAا qk˂pb>OB?吽3ҿ'ߌZdm 'θ?ЄbK?֍a0=/r/r@CR>wu{9zi\z菞92%՚Y<3W$Q\TIL U:"g6PkehGکl#EiwUj(IJEYE"vD'^Fq@w uL Ȍ\Dԥ)t4J%:E\:fo'n*_"Ƴ>4i!4G`Nbr}I)nq1C^.!]O|I Їep:<.,NNq(%#~\H)gfu8t h^@GOHw;g t4/kclqD0etyLK\,IT`2]3tℭ Yx 'mv:u^E>2]7 [IзgV(D /D6c<]vDj!kC ?+Eþ40dzPh@mXe8GP:<70R|A_bT͟m#n8)ydJ'9{潴-N=)0sX6ӤܦN_O~P\+>S ~9*bg4AcZ'G]>,Cy3`t $5q" =Cz$yx)tѾu2qj>y>HP q,012R sԵ2+.L1 .Owi[u<Ű*( ̘T yF_$PoHsBQ44"aS.eK'ǿ(9AP3@r)4%s]lP ݃& (ꈶuqPwqsC⇁)jPF=(C<%ʏ? ׉ԧLXxx%k⋨. 㾈^DvEK<\`;Ԣ!GH&u.HϣhE(>~"/̈xZaacXv }rEK J"- \_}h\'yD7@g`'TJ/ZbDo7-o|usg;դ|-/cZc Ư~1MWucɎ!nMB0Z%~$cXϓzG]!1d"GF*l<a gQiT@HVc+"Pj$?n4k3ZoWJc [/Q.w3"zL{*☨ eeeP8 ̽jNŠTQAlgu|1Mwu oW$b* x$|AHkX6^KA <W g ۫ZBDpԸ{i—@j~ƺ5f`/uAUCc#u rB)^ګ Tchaìrk@6q\UL+gl~HH/lJq2L \]A 6I7)@#u(J|Jj1X4KĢ@Xy#kPat9@Iͭvy^zj! ȑ-аUk dQX#20  \"nBm$ 5ְێ=QT@eyaߢ;䯓S:1uHlDװ!7L*ogAR cb(ȋQ[n;"5&}Q_KD!j4^9`/'X܈?kD&~̮X󭴛d1}$۩$M*7yƂff?"}M*Pg0ă.PYO%@LXbf 8&flĕn`s7UvHX(r|+<&>#a-E7=T!ph#>Og+TJo|.H;r>7^IEm˄yh>3Á)֔ZߗrHY /qAffX-}qAL:C2$lY6Lx 熦-lSJL#G #*nɾEۼTi yf{).N\.ѦEmFX+j*ɓ=GT\E! { 6RFXk'fX;‰Xl+2L[uX5+{̟Wj^/;\?k-R>Rg@,RNv~tqAHM5+e@[>;oaAr'x]P=&SّurH¨.T$;2sctͦ!9hiNs#í"B'o *%XbkzS"g y4_P&F<.s3:b/"9~\~[ΥoSRd=8Wlq9f=m91-9F"Eih0 e6=9lA–2úx_) U΍ ؖBI4lW?YH_E(^֘|%⟓UmxG) ;[I/6 ylF3#0%džCP:jAxitzKXEc1ߥ df-J2hDYUVx(;I|E?K)8]dvʗ$nȮ3yk83_@ˍhf9\Mjׂ.4ׯqA&bG!Y_Aѳyi_`<2ߣ~7R®, r92W9tOά :CMd(WT12m/Z%!*@oXu+_npS@i$S|*Z؟0ypas* X!nةG~Qy:uհ_+~eï &A|3HP$YL'_@K~g#Smf[S;daF58@Y ܈ $# B2oEa eNd86&-+ϙ;whSQ`G5Qp](>7A$") s`4: EQR+pAtQp8 VSƀ7 $*!.{Xe$)3FQh5f~C@rޖ?OO^QK8?i[ t]1q%4NCȕ::Os8\"d_qQ` xIuT|(4 .5jbS\[qsI|r!0E\OOga|3K{Ir~'n+|׽'QrLɉ5;zr)`&=u$aONr>Ow+O }%I-Q_<ݭrFrD)C-Я\ZB?iR@ C=I h$ ]ي8LR%LON?}.BgLSp&rXaғCtM̕biON0 U &cx̆$7ܥ1Y E9 U_r@5 =f%Pa~<[Ӆ#ߩROk>Ok>Aϧ}zw^?`Ҋx}^}}[qH/orM^יr|Y]Pr=j/m+ ph|4QL7U=M6[O:. hoTn:!:; Y85s:S3(%ĖUUy掝tӘ=wxԃRluP=r9V,bՃ(WUg1ZY>ՋQVn  ķkgh4j\tIۤ>X%Mm*J F]9exJKUx +6L&|2o=s7Ӽ,B X8▏:/SM*j%AWzm`ŖW/T/$>:N-Aeb&/ IP4F 9(a3{qQncski]pސ>ףdwW~f./"XШ=|šo‌\F/K=`L tMmfVy!eltK}f̉tH6]I^;yyx{vbtu(-gik `zku0;+˕YQ&qM͠kUw_R,N[`*}3jV$"$ڽ]u֥J#C1x/svH3k}0po|bK5s{ ncvtG4Ǡ?^#2?\䉗?߫$N.=Z'6͋piL F;fluBA2›*|'oehؠ*>>ѷpH{bSr*߈7~q;ЛA)Wǭ ަ1rPGCgx/̡"j&c\)JF اnM;=*6\KOQ(;ȎG#Xt4QVr4UFqtđ2-s!#S %&M:Zj؇[[LZ:+ 5^Բ@:Q4&C>uPDQRc˥_#|([jr3N%VDA4e&|H{z%Zs6`ftWfhLK_ĕqPD8se[FS#b4w>C ~Z1!yl5^t`N4(Y{M{20LɃ<-k?r 㿧_w{ϔ|zZ\Aެ 'RPqߠ,s&wP\޽h9 82ID2" ȰmYWW=' H!3ajl)2+zh ) ̥ڏi[qA|Shs I)@sc Ԋ1;N%VEuؗqHx#6d7N8x* @}}]o],+-®^T-H{h3\Wݯe++! +_7Z~y}/UY Mu;ѭiqLy<8!ȱg҂o:q Du{@Gp1i[ =𵃺,0a>ҥ~GDYFzJv#f[QZ91[GRvEyP.#g8ރS5W$>^vr?^ /?d'ld Ue_2 'Jm8FV`=|*[pot>OApj6!yAh'bNa55'u$<+ B /5pvQ QN= `)̐mb۟'mb۟'oĶ?aNl1xԮ'gu+Z"ifů,Á,w~>⸃:%#ֳQt*kIk -(aSq[.p^ +eN|󧂺}g3z_|20חαu %^an%/x&0M's\;%Y0Xꌀ$Seɱhz,:$72b=ų;sZ9jh hLᯏ1$Jx"K6Sàd/V9;4 8$)M-F,tsTpi07A/T ?=Ԗf~JIdd(WDLw7yVW?XVnG;`+R>cuYy!/pFpjrr_Xɐu1߱$ LƓ.PHil0!5 Ʋ!ݦ yQTas <$a~_?kb"XȻ/܉M v9t2%H' Yu7PIn:+YĭQ~&Q:Z2bNĝv%<(ttp(FwvQ<p? 'Ny35pCc3coD`jAȞa4̒rb`'T=+`ެjt$;ģ}HpnuX: .tHfVx8WEm?ɤҙ$&(I:h5MVxi@X9eZMs |qQ<ȳ+vF)ѧʕ^* E=ui=l a<%gH;t./q^@ȣyjMЙ}#㩇zW3Xu+52u1 v:4-=7.E )@|ȶ~9inELUy}2ads Myq[ڛx0r#n,G.  Γc&Ԝ$EUg|D5S%t}qA!upbèWNG{P=Re9UEX##+:SQ,b}&;)Q>`17v`4" )7ǯ_|YO ;hqXSOK6lШu R3wu ;hj-%. ̏G rwG:aqms 8{*'֤s0txʥ dJi+uumt2NoB t|VK({ʝt]᫣ǚڜfТ5-JqlGʼn}k7_xA2V3Nw"6g<pljmd5{Bvة[v0>?{RglwDMS- v!eg0>*̆;ܯU񀉳lM JFEW1偐MmX ^U:nwq["TRxZ[ddlsSI0_&_P-frD!=RchimEݯ~F~ͣ[FaQ[i`1,1S}Z臭b5 0anax(Eawg*%DpzoWʝ|SWOhxIZ$Mx݉iEbxSD$LL9bLqsl 9^BIZڄ{K a(} ,(.ǂ6fÔ~j`C$~]xqTpfHMG0p0Bld_gM&n4 $A!0iW 9}Gۀ t_}I3yL$==I-&FcӡE]x'tjOc"67䧑E]Mtdqscux73 S,y c}>9CG Ŀ(o`|J_1Jk r$iG<3 TPo!Xm5٦-I6sK)w }xօ+y)"͉_2"/rvWKcв9$bMČ 隝P9dÌ xh`<2 󞱭nμXqqd`[=ABQ7%a]Cu0cZdi.CVs~ĈiaA9#EA`AԀ@W{ 9$LClxF8 ;'fۧzozXT,1{ Jk:6/#ڒ8wy(Ct#Z6 dž% lѺ@1̌4&i 1CQ`YOY &H0Z/qZDfzF#B4fWhˋu t:4&SK `l&$.Vҟ33pqek$QJ('cyql+k #1DC7>nH۷{,pm&8.|-= DBk` ֛c7^by! ,"+F& BraXokkFf\nMw^ޅBMݪOY W/As=˻Z#B{62&Ԡ {Sz6WU1;g5~eEH݈KX 7M MDѭD T斀*<wb" /O @M}.WimhK蓪t3)5+[Cl4òێN5oBz=S%+TO= …\{r5.R}럅X}ĪSjO~bz"#7]ߘz)?RlSlO>MQ^iZ'_dzB ~fJI!nB0\ۃr)rzp)@{G5#\w1_G:l6P{Ԑ+Ʀ__^2S{ rP$,1sQZ#*->~#6[3|aد~gl+8%w"-/o86X=a2H?OC{~xzJ)|á EO=6oP=ǒ7x\p{Ziow=vkϛ==jϓ ۏkR۵E;.7zJoVX<ĺlPi/K_b++_a !7le/rlj\ߦʚf:BO/pkzB 5_v"aEe?<=o%|?NV̌b@Zإ\;),?AʏiO=7C={Z81 ЉcC47I%I s;6%xx/~I }3BΨ#y*InBֿ◭[Kge\@Bfł'M-b /7wU`OʹaQL[-9[Snf˽BL=[h磘Stn}*>竳(n0V0kkQ!! ZM!R#=)xO4NghRZfGusا2h/ ZVnGf[)MOctO=|~prKȁ_HvYGDC9]tlTٳI3dH:yٹ geU?.A?9 {H2 Vg%g}&u#GJ KgOGE}\)/e}޷ 3@=R|KVRwE$&-USqjٻʍa98gq'}h[˙ᶆed0lL&'P|Yi)(lBOo˧ұ9xi^ 6N?:Aιw4*08=!4H{i7uf2'Ri^čG:/4(%rQ639IQ+fЇ; RcCPa"ܗŶ0مEjn$J*mPnRo# ڡ ;d?QdʤiC*bLU֔=W *nQ0b[bsc8NwF.K|gT*4aHX9PJiJ=)<F{T?rڃEMhQ d@žh [푦`6EmFM 5PY$e' .xOږe9 /xTmb@(Ai@"m' FE3ͬҶ١Kl- $_3Kz!ϲ2_pUV80WLU2pcuB:]q".\/ xS&7 ^˗~E1sMҡ cD&o\Vs2h!ٖd^X[x`rv_=>~+OQM^kp_ھkc=\zh. 88\p8W8h 0nYnZ;E:X `M-\)偎E}_oGfG-z;>QWװ}J ]rU=~iˁ/l'2@U<p&@?1Wj\xz&p0l[ea4-Q3=hc)nmK8B=Zc!0c);XFuٺX\9P^/o&,ÇǬmn[pqFI(t^$Tq*Ot8GC Bѹ۵d/d=?AcMx/SM ʢ)]#ccc;̳]iXGn"$(IpQ |6DSq *La[!`msv64R$dJN"8?T[O;%Nxb)) v% ݂סĄdZ$ \8:>m%^l T;Ga{|*X?GQ/O A[jS*[.߁ .(xg&3; vBX`OGj1Lqbl P`U"_WB,#Gb%\5 M 8eamK<0㩔خA? 5ۺ1J Մ:oQ?] qB%|6| zd[zHc/rǠ-p盎'| N) -irl  Iv/ m8{.CttIuXX˱E&jW8 P C}SY4-ΰΡbwj8VhuDa)J@ʗk$Zryh,ݞ`LXQ2PJ* s0Z;8Y ޻bV`qh7兒hYDaN]P"9)%aAܛʩҰQ)1cL>S@+SJkǺf]1NZ:Fot}(E#'v+'S_8~aw{mP-ׯ)&>%y$u$H΍\y#q5JGYxT?CP 4 VlG%h΅t*Vb*bY5tQYjQ(RlQڀq2,z]ץ~] nB} H3ԯe{u U3O.NIɘ OeIZ- rms58hg uT-<tk\eѧ~^~DF4Q"`2W{(Hbq7[)@>׿`1=[00X],4+_|(0󱉁RobTو1H hԃIVLEYB a@-Nhas1xX;#e_'9M9t'T=̇jCvc3-Y/<@ctʥo \*x{ 7hoa<;򀃷woi8.c?)[~ {~o&- Ze6;8ukjb.' [v?&Yb@S`b <:M}JHkli/F:uA/j/k*r9E흓z^띓zO礳TM‘T|dA\-Ixq8؞lOn4H./jP!漆nM+}V( 0t޹ǟ ks;%e*H0K}[D.9|78rx/>s/>ϊχEKNLT@EV~z1wGz]Qߓt%vn6c v^6eo~.Ǒle G\S,\^9y`k>$qX>Q`m„b]"9a͠{!Prl^t۸w2@X/64B|y@8ƀHn+m ^ZBY@_֦H 9lbrX]c\Ʈ՜nNj"OD"]\WOIԭêU>scڴ=_Uba>%,cqխ)dpaVFx28!=HlWrK|o+j\^S^eUo:N1{V{aV{;{?*xd婛ܫp2(oZf-Wyݣbl 1A07 PrH.zv vKw,)<Ȉo`Eծ6$b 1ۏFwLp/9^G(W9i&)简6,xGEtBɚr̠?Xm=I3UIWq:D7FІۍ/1v'3b}uM:929A,Aw =:tc+ZSfg#2TVh@|5y#jSz[޽*6s¡2 #tty9T}>fyϼ?yH&j 4Qsf3O5K1 }O`gwH Gc~GX>EB 7=DW{يIg%QkƘ%޸XhG1}齾?^WLq\ { PgeyWƿlSo>;&p%Lޛs`c,|ƯxoڗEGw+0V"pS#!bѕ<_f7pLh>B'/?ori lvd/HR$A?ieٝ5GH5 [M s+!$> ?ߊm|ja z̬ҥ]0̒cka'•L s;IZ)e m$z8EU^Szk41-VrM!5'&䛌`xy09fIكzvٳ˞]g.;NmA8k~Nu~vx^5 8>`hY<`-Ŕ|1 p`ƿMjN"){&tW=W BdI#}kkxcGF2P|@ MƭhS}Ny],sf$#P5m%o~MXkLAmUD>deヤ} ZֻjZֻjozw]xa{{{{2|/2#ÿaFԆ\Ϩx9{䘇[-* n įkeEs''m%bkq W9B\HنOm]4Y .H{W){W){W){W)*eR*口R5Tl;fҀS/nT,s}^ᇙSbVr]J^t,qnh $56m&PĻżXX\}rmȚ\Ohr!:tH:,mT] Z]TLR_ q#88W/)[Hu@cI7P  Q||knR {$a &d#HR*>O)1H8o@쉃½2Iu֮|!X n gȏbIMr7~sJ.u3`zS~j6{;nSw_rr j4@(8*wB0s;إ^P(K,:uon n|qg3! ׉uڶ.)vebTjxUO_ZfR!#\@*o~Kטl|tU=zy5ŖKJRJb~ ',oC]:ZcUʐqzmn>ܡqs1Z l{R^>@z&}],lukCaot?gp;eȱ_}Gw:wJH#<{M2bQB6J.aԜ`2}TƐƫkcž2U.{2ό+p>'fո:Ȯ}a'e ls9lی)WӁ a!|~\)#Sf$VT)YJ"*Z IG 3@42CUnl( P08BHrx4RPZcF`1F!L'1zu2kRv@-3 _d΍߈ s6/ {X?&vL^n*ɴL6t-DcSvy$e.|0c yRv=$,==@.9o9ƅ6$y`AB?*Ǡ πTK-@32H\ʢ2W4tmv. 'B+ګtvO `rc6ߢ8]D0Bb &\v]3(@'!ܿ0VM+JRy;˰ȁF_@x:*;$Nc28A^&/騝sMF8avad L8] |y *L?GBIz,dC׮Qi<-Јkբ1Zjexxy9rzUx iJWG || & 8wFij&M1|+_T$%zd> (?GTȏT,% ,F{D`CfeԵ橥WzSv]?$_Uҋm6GĨ`{f^OLux#(l*ߥ y$n Ua 1Խd,CRK c<ܟ ϋ2,Q~y N9-ƁջVj=Y=,`=@`q|76=Ռ[-Xl>e&OBchj$ݙx(N(0Пw̟vhe$є=PNd'ћ.q֩1:&h_J7b8Pa[&{_#x댛gʣe|͡2k``F\ݗx`%A#,nL*D\h#1ix۝Wlb.)΍IISEpOtp#$Ϯ×ʏ;E"fC%tiEi$nD~v 5m c$EA288Jzwh&C bjmk 9QS>Q!) 'BlxSj wDI%+Rn 0څ}pܦcK3~CSQ逝a$?! :Rx6i8t>'"@ Rl8ژ ʭd*__qӼF$AIhD$sp pʪ}mUP u*")T0x`YQ>f(}]{8Yp (fv%p 78'gCᓦhk uu&ip9R$rpO7 y!ssp[jiU TC)= W˼AX' hԚt n,%K4^#?lL1II<& 1nj v|"PZmס t4A8B GyJGrdr x٨7YƱUAoyufqY]iEࣇ6IU>["Ux͂~)?I;UBTxV?:v(tkGP|]|V~!- ZH?&=g$q{LS"AFOW5 hMޛ]$NHXc):2P8ȩV"W?LET4ۻcѳ)Uĵ*HfAiN[X7GseEvffg8S^e O}uM&WN;P, auS>*DCN_2+0G8UDSF yPljo 'T{^N}_j/c˩2j/cKݸOb˙2=}/u7<-R1$$}$-$u|*$1*JrPfpS OHLt$XRƔ;)ʬr ,hBa3?*Ih=ZSӪi/WponxK*:-hʙN:{J#hssfOAm^8oQy*U"k+wgїM^[9 ^Ξ 81>}Yuٗe}Yref8ݫCi|~m|qL}bQM>~#w'D3_w:c+-gc>) ]?2E:T.ۖGe-^ Ј_ȢnPQR;y^6[y#clWiHcVI(,7wZw 쩘x^Ѿ"jΞ~wOG -je̼`m̭,ub!6E݋S4BLѱn?#ㆻGeMU wS]:n;["Aʰ]N&~UsK@!'ΑI5 UmQ]j1a43ON2CK"6F#`*^'TgeWtUj{ A[˯h13LqH*uaҺ*W5_,>K20x;QXGx201@tu |Ue~H=|܍OX* FKޢ߰8W&mn"3J< _ycfU:ȭkȽac5ͷ-\MԊTtoU'5F =^qtƎ :'^RB7װxƞM<{&ErSU1Hp߭V~MBJl֕Qu'4y|փQg2JUof*} 6S[aJoe^7NHD',~aX^ӵ y@Q(PZmX$C(5~p|xwpRfÇG~ȞL}C~vi"e>TVapK~^-~MT-S 9*y3 ;V ^QB3jyFlOUDt_{>l12G+XZ+jRV(@qIyw?pD _ŧa590,dNiq,vFy$ޮ˳:XEh<]M4NBN":N~`粅 恿TW#^#z_z2݇H,2P#]eO^ |#/l]u\7`NF$__ߝU^feWe*TI`\%-^\R<k 8@޴mwyVڻJq(Exܹ2V e< Ջ~ǁkn*m }7r9|'/F 3$&bD] />a63K3b!8 !0#oUxd&2)qEW>yq}*b_/`^>Iz#NG+t{$,b/*aY$!4nG ҃Rf peTσzx5]<`ӛ>kryN M c'u9䡿dn[5)]^"_WhRW /!% ^!ë) ph%*9.ffq [aKjzL~{M{X)W9p-kH'{:S={'̋OrWZ_țBM2㘄R,le1bM!dr$ c-C,Ix?ԳG|fvĹ} g'7b uh(ﬞ{5o.|c=DQ@3Y|M7Jk~Z)e}JY)CaߔZˍ>0܄wQ8Tbɗ6`/X`= 7I(349O,GbuŚ$Id˻٧{L2.6g'-#; bЮ+mG-0ͰpQZ<-/FU7gqX%P67n" by*N'6-w"c}pEA)˜V;h׶@C mG;MpGa`suv~d.z<ܵ4'<Te@rzĜMZoU<۳;V{=@L78IMb#!UP`V8L5ĔpޗƕH+ا& *$uІklC#QP 1 [;WPPH&e:t U1ƩD5{9q١(DE!R2 Ca7dQh)xvw)+rchwhr^d4Lݼ@WvtP"1A1AhiְFb7ec/D >`' ,Q.R-ȝA8HWAQ6XigD*Aə &rݘbp33'p4W&DD22s$@ZS? !")vM4}VKNm ‡5/—jS p h.G)yaJgDG \>7 hC& 酿sN4!jEO]*ڂ 3 M"ZAZFL(rZi`;[5~GwB?_Glx`%ȠqE$u \1%(À-?+0s  YxmRpIو(J< ؛L!r8.[g5 ^6*F"Ge,c4L_-$~hj8ޖ4RnZvKJnTź^m;Z(%Yrʰ^P!ymO 7xXE 7ǃˋEY(e)*>k^UFla=8-- b| j#g{I!S@&.nShB2{km= 9IcEaο]+ AbozUC//^25,-,?gۊ.s׭LtMTr0 fPk4#@fo׾Zh59@F#c/؇%>o`^[Li|^n^b84r_*Z(uP?PKdSFJ ;Rh%PyMca/Object3D/ObjectTree/__init__.py5A BG0^7ڔJJ {*c)WQ,I qTYa58Ne^^PxPKdSF>/~aG+PyMca/Object3D/SceneCoordinates/__init__.pyN@)H?B 44vvnNЫ|;s=lFG׉K >(ؠrDt[UH0 ,8>@pZG2&Ca-h?Z9c!5fLLx_+ MqATM̊,?`'&-+ .'HJ m",ƕuqt*) *_6ԎsعD @Z' Ay8W9Mz[[LT5m:al)Ij*HD6auEMUʿlGm~b@l +}ӊo{?(*aLE԰h-J$~Zۈ_vVc~xՊ盽 ׋bvƵQH_PKdSF{` w(PyMca/Object3D/Object3DScene/__init__.py_K0) d *-aHiFӤ$)cۦ+=ܜ%ͭ0y+(ŲR{p5hwSះJ@ !_$D(ĔNtO8T5nv|2:-AIW(yg;;%DpVƌFǵjsvh]a\CIJݺ*Bn`šFgXAk 4Q?\Ϡ.*;!A]Tku`+-Nr`oe-ɮPKdSFv@55PyMca/Object3D/ClippingPlaneConfiguration/__init__.py]O mKٜ+Z^T;21)mqh{O?6O9, *V( 6@9o !A=~xOfGrF*u@uAxX#$uR#TKxU* alm XEk]Pɬ.U 2-8'EȍA҈gPQ\dot}ݗEЬAqsQ_Հɸkԗtd?7g{Ծ~(}0yT9gfdPKdSF?NQ)PyMca/Object3D/Object3DConfig/__init__.pyRN0+|k+!D) THe'yCտwrfӳS8-miV"m@ZJjA \BykArds"Yd Yi?.6cˈǏOFhr\6A* z_ o&+ݵ|8tjZ_Hz !Tsa6 d3J8iL*"Rq8mE58tB]AۦfhPVvk*ΗP›  OjzI5̰QgmwI̿^PKdSFտƂP6-PyMca/Object3D/Object3DProperties/__init__.py]O0+z$ƀ_ r11]Ucџ9޴Q)&$\f8!XZ %QXtm Зc/!!r3zəzf:'8wIuNBdCor.΍ڛOnb l&V-{7c UXeڃ#ؚ:6?3{Ec !ZJ7OP/&I6NХ"QL j8PKdSF%kUC7PyMca/Object3D/Object3DPlugins/Object3DMesh/__init__.py_k0)Q}UW :]l0Fpm֘8se/j;{Ϲsle );ZJfu#[M(IU|3Hk eB\'DEӹ=37RL/y;ͽjq곜j&0 FPDɓdռwjw~:ЍS:%,=E5wӤQ==!$Z~p4Ю2( (%sr 4K(S]\̆d`lvqP;L/ƍUPKdSFOK=PyMca/Object3D/Object3DPlugins/Object3DMeshConfig/__init__.pyN0D JMDYxe'1q`;TyF*s3M"3LHTpBrm΍PbNhʕi@37#>3" $>B`3:;p!u^u6ݵ,CˇܺkGeX>0bp `Z)CAyۢehXˌ~*ܮ]mRR#7l^Q^U{;S3H6X<٭5d'+(6Lx_/-v=y|BUַJ'p@8NF9WƺPKdSFk?0A8PyMca/Object3D/Object3DPlugins/Object3DStack/__init__.pyAk0BY ]˂V*-mjLH=x|3y!BE"YVæeBUͤŐ%@EXQ3FuKDv ls{"gJޜcz\eճȏSa.˕xkaXEU+$+P˵oZgL3Fn4Zf0>G$=tŷ/.+3LQHfI?}T".zH1:[rdXyq\(?wRs2wZQm碩TQ܌ =F3 B~PKSFO1PyMca/SimpleFitUserEstimatedFunctions/__init__.pyUk0{ܴ0 s΃?1$ص=I^#$fV=!TN cUtKejmqBý{Ւwt \67CYٱњVTgg;E YkU\9¨n\館?]Ȓ#®P*\weGH㴸0q[. |^cku ҆grf~`V+9,B@]Ч$=ڿyNv.PKSFSZ&PyMca/IncoherentScattering/__init__.pyR]K0}ϯ['h: &nHi҅%%כ9p=p? (/ڮ 2OJ#uVFQ)/A6q4E,F.泘e=~3$ؗSgſFKbaƴݠNEfIq2]밺Ϟ+$)TiA)D3SlT;N ΙqX9k6)RB-㲱lRgHw;p<^3&TmTf'u<.f`p5z8w0 !;ʅQ;KP o LHDb)^qKap+aYIͅ}8KvW ?/>PKeSF#kPyMca/PyMcaIO/__init__.pyOk0[7;ރ J-0dla Io7j%5e-+'m)#ijwɿU!$-)1^0 X_ɲUrs}fyK$\_W۽Lec,%%E?]R-Cc69 {uy>Rm*ޘJK׮B0DC}PKeSFR3]&"PyMca/PyMcaIO/EDFStack/__init__.py}_k0țF} jY1˔ZnҗsqTQ6 (+*.$DVJLfOuTc{_? h0IPɳZn?ZY,֗3WFy#2_j7?uI .%g9󏧀MՃ?ԕP6\Y~{lmV% e;&c>֏,lCzO^=Bյ#6"b4"sۭ&BkyC!y%ft+PKeSF %'p PyMca/PyMcaIO/MarCCD/__init__.pye=0 ݧW@b g"HQ9훂zNR@"W%Br,>jSW! hi~kt=@Q}ǔis˼Y_PKeSFL#PyMca/PyMcaIO/AifiraMap/__init__.py}Ok0M c\!ӴMce dO_)]"G8G:@;M߁^_H[I!s9rʥx4G3{;X܌Uc1j0ݜЍ֠0mΔ<_N<R%/}4@6b68 /aω3SRV$,UsQݤ8RM^H9PKeSFJt<#PyMca/PyMcaIO/ArraySave/__init__.py}Ak  oiacv&"VWY jӤ\_Y̹nco d4): ']6׮bӟ츹2Κ qYqQ1 s5KU"5rպi˗0QTNVkyt Z;\`40Ux/ԗ"Qjq_;p>@D#o釁&!wES JPKeSFg+PyMca/PyMcaIO/BAXSCSVFileParser/__init__.pyuM 0 mgx CDJ-4av"̯K}$o纡&(Ι |0k%gAwT" +6]"ƍO<۷nwِ Mo2٩\O9k_;q6d! ySBձF|]<#40U+xEiߊO >BJAPKeSFo#PyMca/PyMcaIO/TiffStack/__init__.py}j SxF` I\cM j.3fc|;jg{$:!GBl@'S ?;!j֡yV'%-mp5e K~En%] S?΋aV71t>ls^VX'qd*GKsvv_#%XnH9exMEc<ԭ}%ϤPKeSF5"}/PyMca/PyMcaIO/SpecFileAbstractClass/__init__.pyu= 0@7`sH%.޴"ķ%E4W!Ts 2iH ~bw0&5>lMϗqka@1;'bIOKֿbn ,oPKeSFwi$PyMca/PyMcaIO/PilatusCBF/__init__.pye Ewvt@ QlҘbHп/1-{8\d g7OOLS:et k0k|BB҄ԩ;I g5mv7]tEz&cɾnA?E1KOBGXF8)oo{0N+ g֮B78\ PKeSFG*PyMca/PyMcaIO/APSMEDFileParser/__init__.py}M 0sT(=@ .K iIȌ oߘVt3ͤc7=^qt'6FHuV>&AI!p&PJ|پdƘV#dj2㻸#y!i Ŀu$lXT'i0, I id<U ʧv WKa~'PKeSF$Ͳ=f PyMca/PyMcaIO/TiffIO/__init__.pyun0w1АRǩ%6M3Y*jː ՛?WڕƩҭGfT)ƪmrvms7H.>@IqM}3x]RrT:K-I3m ay~*r{08fIX4EFR4Dgv2 }2=a!-xkkl^ȳYN@)dҘtËBݪM3d Сη+ 2k>INUa]! 3k1c3(}zdT#ݓ{Qf0sY;tm3,.(3,2 PM托;9"Øԛ_, ̟anPKeSF')QO'PyMca/PyMcaIO/SPXFileParser/__init__.pym 0 yT>v 0t%BYC~1P/3q) L1ZIY8`([1&oqE:)^oDq`sVg*h4h2& Z[v2> *$iJ7\^|Z/BP.PKeSF %"PyMca/PyMcaIO/OmnicMap/__init__.py}Mk  o0΃ĖCbc ΀k!~a[zI}x|g4dl!:Tuj N"(3ji#.@'o)ܧ̺d,C\ Fpʇ@;/%%0E} NNn'\\#^1'zr {@k8Q Jg{HDmv 61-s.rZ]S5K(WjW\{PKeSF =i !PyMca/PyMcaIO/spswrap/__init__.pym]k0+rԍ֋1FmmR_Vw}rdRh#)Ɛqm)O4dUW!VJ_S{{wrpHINgY]NpᮿS C)#5F4bLiSiچf:43~*1]6snjK-)I;5+h['pMTVx /ۥm90 CaոR֮m4@?Llnm'bn8 jr|h:*p#M7fs@;¤1Qޣ-ٌ$'JA*%B]PKeSF\qA!PyMca/PyMcaIO/MEDFile/__init__.pyu @ E,ۅnh kE? a;w(Z1pK Df5Z F^Jl`ƕ P W\f6@x)O1guòU/iSIRQR˞Yo9PKeSFH1k PyMca/PyMcaIO/MRCMap/__init__.py}j0Fy@)]fa534C)eQ#I\J[*||F`$VmýQNճjq ;ߤpxk!@@1LT(_d/;(ѻWi<qgn-mld̰Gƍӷу\FgA= ZO+ŝn-Wq! !EI%ya%T )c'GPKeSFa(3,PyMca/PyMcaIO/Fit2DChiFileParser/__init__.pym? 0ڂtp:HP,8R 6]~{ݽ7gJkP3m |Жk%igaΔq+9EHAHȺq^W6Jy/KFnA?uRPQǕ]JapJ s$Pg9c>|PKeSF:m'!PyMca/PyMcaIO/EdfFile/__init__.pyR]k0}ϯ[[+{!Iƍu40k4B^q^͚eE]5֍(bD*b`q *bďG!hsvy,ݐm*,AerT.M].w]Q}^|1?dH1{%$#qɎ;FԦE"qNJO+_˔,kx$j :Q:jh'5XfF/Z"E|!PKeSFLMc3=)PyMca/PyMcaIO/specfilewrapper/__init__.py]k %Q.hv",L6 cXe|0wM|砨)(Ωm Z0Ǵ޴ #U: !h*U p eiRq=o8Hfd3۳8hc2 GxƝ:+[j kTY%5&wS;R:g 6dx۰pf eZ:v'BŎLL;)?b7ḵPKeSF"PyMca/PyMcaIO/LuciaMap/__init__.py}j0E @0 [REKҘ⿯Png'Cg6nH#dp$/T1RKI8s+Ҥ]*)䁮#K6}G1Bu`M#qLaڦ+5~B@(ۦomY zT= yIfE%\z=J]/2Aڎ/^.c\~V7}g'{PKeSFEu'PyMca/PyMcaIO/SRSFileParser/__init__.py} 0ς 'c6 ooR*|\8-AqL] 惱]+8 'oS)IZ YqgebܿE6b6Hs`:V)KiB]6 I iWi /ZUPTX1|ͼV" J ?PKSFO PyMca/EnergyTable/__init__.pyUn0+ts;mZ omƎIQ#eRTl}eMr豀/q#gfJU a4R\!#EVV*M}!#Q$xߠóFP#raφ{ܛ>-gxEutlm94ޏ;UoD<π:3dSByfKyy7$7],~ѹjx^H}.3̘|?cH)%\ZXl{$$R<ƣ.$IADG 3@t][Z0{<M4EaLB$󨶡9M<+w( yF/Muui2厓+rEB`Kk1g4Ζ/H+xYY[ kZ:ojD?ps܉KSL 7rع1C*Q^yՠ#@rXXKb5$,{Vuj8hɡ2B}55жש ;NU/+$)2VN ,)l'zS@8ä/C>1fS-@WR^U<8HG=НLUcEj>ܗ{N[Gf&ZK6_veYqTK8qaxT%d^.s]_ܯiS6iS6iS)PKSFFI]PyMca/McaROIWidget/__init__.pyW[o"7~_Yn} iPB *==!93TO+BsaUZ.W-4,-JVr%TA0TrӐǶݔ=Mbv^?ȉ~|xcYh\ !p4+AxͣawX0cZu>/س3gᗠQ -dh!,(vyʥ%Ϙ2,GGna7` $dOz]ջ*!XnN*L\P#I5H;\3 Uq 7#BP.T]eлO畷5 \mLvMU!CII;H'O6 |c(|ȽL& Ş#-ff8JÄMEH Z21zj+ \}nTԽ1W!8ci5m /kgOy>NBftjTo$5`^#nmg"WwLxǟX:sQO?PKSF$z%#PyMca/CalculationThread/__init__.pyUMK1v RԪBOЕ fw&NKIR#H) !"zb0xh.ϵA6~IlyRajZ'Uw"OZL4<Ԝ )Y!+*JIգU>u7C&^O&QϬ'k {ñ5> yƏg7?PKSFÓ %PyMca/PyMcaMatplotlibSave/__init__.pyQj0+tsr zpq8Ƒl|} .v EhfvwT9Ԍ 3-&j Dՙ <"NӥͩB 0@h{;IiVaPr[< Dx\<,x&KfgcĘ'k> -$5ot0E"u :R]30-ol{%wW%uhg Qka8d]M:"zgso<(y%Ǽ9aĄJC=PKSFU18PyMca/Plot1DQwt/__init__.pymKo0HUUn\*8QUY1`al6B]Iniu );YNcc@B+TVf )2}*tBYM> ͮp(/uobaȁ_y*1Z*T F &sx7}4XW~\8I#@=޹j?=i_ٵ+-uF['S 7#^bX&>CBPKSF8;YPyMca/KShell/__init__.pyR=O0+ CLU  B5\Sɾ JV 1E˻ՙUCG!29/ EԔ$aUץmiX0j%́`.}6Bߴ~C~%!%>eaYIGe~ȡ{TN0$4d:b_< ӯG:-_?רC$ 8iѱx`1~"c70CV]6vmiB5Mz:-=u4;a xl +殥ښ@A ?RΘBc\Cc.ﭫE1:l*-Vg PKSF1-(PyMca/QPyMcaMatplotlibSave1D/__init__.pyVn8}W |ɭK 6NMX,ZK)RKRv_3e˵bOEɞpxfP -5DQBiK-Wp^C4A 7jXqX0ZE'm~v%򟧭C}G ZX1vJԧ948߳P:j&(˼4lӯtZB(+-@XS/vtI),o^fd|՗xSY(t$}_V ~*IY㌑P0.kp"hP[zf>menPB(mx2ƟZa.X<ND4cwuSaPX\4k"ڍ&q2- CP׵q>dwsVGߩcL9*=1?IHPKSFRPyMca/QwtPlotItems/__init__.py]K0+rD:u .s`ubZQSޓjgd$sΛxg(cMQe:v^Y@j(gI3f'S+QtoXUC)x֐*%R"Z790T B!uvcPaUn+8C([iPQ/?4x5} z4Uvu~ uKnӔU_ÄU%x Y^CSf!YI%d"Fne?l3ۋ :}MxfYtV Z\ӾSXQC!&ZVB9a&%&L_T'nڀxd4B1F&( m BCL;q],sU!h#^wTUɎW3CEKN "#+kNcH7V,(FN p_8NmGp޵GN`KeL଄YSRfv1DYd|;`b!J鈮s[pcƆ%4VN$Mx#g\xb8xA9Q8 1PEkD8r-;qSrzc $%hNC \n.YK(JȨth@ m~P]KS>lɷ5'ԫҔFA3.ɕ#`v+Ng㯿"pwˇ}4Ahxdt`BY9v~ z5san!G>Bn): z`sfL#, с+؅ P[p@z'JVNCiJ#j)i'i*L7#S J֋Rj}-`x;ɸHlecoRJ$Ȓ{E'vg`=pñw{L&á-.3fJa̦$޴db!wҧM1ҥʻװ&ojH YZG}-|[8@3;E資yY_ΞJ_nte^Pk7R7G<$Jߗa놴)d?=L)6X|3%]y"rS=03Ci?%.K\TK_ 'XY)l PԮ tDS{ƫ=#(8!u GUce.?ȳ W[ v(c8o+ՃiPC}b1qнs$m'Q)7nta~x(umxVo˻I彿0ۆ؛>T w'696W}o[yQ[,8~]dr#f(fyaw(9oFc|jkxQMVń %g\!y)~Eב5zR3.G^^/ZaolL@s=wxsPKSF<^PyMca/McaWindow/__init__.pyՕ_o0)F+MUڮH[hi"\ñ3Oǐ =wLR$n.2IC&M%Ui*0DD} b8 ift&aDJ!*}S:>d<G ]Tt`o z{@/(hJǢRQ!фVA p=7y4X(z"aCakЦQDLhF@oŷG=dFu/IjWUQA LWr][sa noo>eSq{MRUHj <1Z(!Wk%UWZiڿ?ݣp8l8=t|5G(v.ή.;QFrE:1ώh/[QK7J/b'z)Ech \HFIWse˔~uQ}\iP%l%`L&a 煌4VJPE~,zGKٍyFRw4!hy'du>d}5x.3ুesm݄HOuGB&?$w⠒гt̓gwbvDG  ?aA2m/+xIJա֞IB(`M۳(PKSFG\"C. PyMca/Elements/__init__.pyV]O0}ϯ[A-cx6EviGI.bԇso}+{YWR$zҽB*RDy?Y QtIŒ"DsjYvПmR,Mmc60QDFZHں27"ńb0Ѷk-G4*`Ŋ05m)fA`L<>0 th&H U41U<$gS{,)akNVQ3ajжy=Lf և.(_Z䲋1ĺX%˔UR9e?#X-+zڰd]܉Ub]{e E }#ƞ2Kq*`Le΍]Axe ͽk-MST~wL׻?"7AvwޢO_`3[$=uC6&Ee -LDꚌ%si}^*4ǙӲt˜VLS6DRJj}QstRZzv!mdz<gl"!EB H%x($ sEm@5;-jסEWnP-up֢v}Z.EOY 3RgWe}U yߨpo8%O(oB)a7k󴵓!?al*sk/.&>@?:3fxE~} FQ__IlΫ:~P7ioS@jϢ3ޥ2%z%mǨ[>~PKSF'X:.PyMca/PyMcaEPDL97/__init__.py?k0w} oNK萡]$hC)BCRΧ8.mNw3*a:TָX:DUFO)#ł}әqCQ_1sbo,߬_;F7":l㓩Pc@.OKuee a}cM n,"M=-Qv*Yڏ=oge/y-('L%Im%rq5x߄YC:َ^%:eʫ4/::!PKSF(\n[!PyMca/PyMcaBatch/__init__.pyn0Jlݤ^ %Re4EcEbgS /+}lO0$ ]f\H7Ip3gR)S p!g[(`b[qQ\n}rKHBsoQӄ<#V0AFZ!!/l?IZl$LY*i2M|w;TmP>l @G&ј8,9j TaKc3rAk"D+^LFD6TO# DBf֤ɷGBuhGp=`2J溗D)+mh~5K@{e cNFLu3gG]2]s#21MhHISko4x~T9˵X_F˕?ٺw-Y'<OK[=~q |]LwEr}p(!--'~Мϕcz`θHQ`a C/9Q<n \Z"~ ^d}=vdU2?* R[u=a"O_YA|j UʆӤ6QM_/PKSFԜ`m *PyMca/XASSelfAttenuationWindow/__init__.pyU]o0}W-4M}J}H!*i6_14/sνc Z Emk iJLZdefA᪄ʶ]A#Pɂ,9CVLd3r/O^Ƅ3c~L?O%ҚQN,Ԃf/sf5 hfVp̭z}\*{Z4tTXHӇpxAb+O2smKj4GiUJ!f)\DP ·Vѻ}GEqͮk*tZove{l|ҷ,w3.s*TIXX v0Eh$EY;xpS}>S/U+j)*[SZiA92@P\~FǑCj`% H, T "(hͭ_˓+:@s ^)~ד-kGbPKSFIPyMca/FitStatusGUI/__init__.pyeN@)bMPЋb1Ͷw4ln啯liXP"y%X@ȷ^cwZ'Kp~WR`)3ܰ{7-՝u7/owi2ƃQ@(s3K}UGzMM(582YVRbR)BEkmsA1Dr_ ^thHH3X;s8-WrKmQb@+giW6 `NPKSFnN +PyMca/CloseEventNotifyingWidget/__init__.pyuVMs8+8,U{H P&L ݽ-*FrׯeY6~jJooF7J+Ņ64bGޝ#R QVҺKY&OFqeͿ󂗹b˜+AF"ZaEwL Ώ Vˆq+VO#:/#%Vz`PN^q.KjEZgl (@ k3'aq{9oj-ˠdk%ק3+sVVY+VQY#Fna<ɴ ;GF-A>DϬ[Ȅ\kcks)#=F/bp6[Ӓi< y[ˬo'Y˒ׅSW;I8p ן&KQ5zM+|T6f_zDUKGHR,_0sAwƀxd4bV&(Km=lm ɟ8SwJ*I J6PdONB 2khF8H} )jqO&ϙp`'$-M6Ag&c CN\UO.$0ߋ8KO9&fk;\G|91T ٘lZ1(U-g$fT5QA/i.l'?k _ Dilm{+צn 8pIu$rL<``@^1p]8k!,iz퀉"8;^܍(DX9-!Se7@v,mt72.dgЅh9ys<)>(!8 V*ٙn7@܉Tn[ӸM )Q'2j:uAV!}Ma}WBf=7@#bO~@ḷƬ|Ph .؆LΨWӡ-4lr±ڧ^\[7Ӭ/~4t$tdd!RK=[$hQyO)MVܲǍvН}@v bP/p; d|vx͒Ơj CڗaX桄Z|N,< BUň}<q\{y+XXR_lQx`'~j?PKSF0ԋWPyMca/Specfit/__init__.pym 0DB/b B$BL!&1U!3o򲝷 YOym(Fy5X x@R{YEyFu:Vlf r+uJv`)KQ R +5M<274Ḉpz_.Xld/|^[`:PKSF,M>PyMca/FrameBrowser/__init__.pyN0k+V,؋]($n2Ɏ ;ݤ<7w3I"4]5!T5j㘚vU҄]t=LhdkF_NG[0B@&]. Oh{Xzlu[0Bd\F?IVpc;wr,fsY :'e4%7g2[يU$Hf01 \)gM2 1s bҕ[Ov ;}X@+KH͔qAPD3!71weyPh Ȫ !#!1g4N,+0 h*%W:h' KPKSFVti"PyMca/SpecFileMcaTable/__init__.pye]O0ϯ 1 SP4!Ƙv5tl=g 7m}nVPJdInh5hT2w4FdZR 懘Z>"eRI_I~\,[Z^8 E`z./3Ġ^s,sػb?J|qز(*BcQk2ZSG[mۡ袘'X>Em0HwgD,65g㿲Y2{V$g)g N2]`pPKSF{;PyMca/PyMca_Icons/__init__.pyuv 1c>+w6x@C%kvt,3- V˘/ꍉQ!ʎp*ݞGe 톭ګ4e պݔHU\la{OzLW2ش,PKSFQ.*"PyMca/Plot1DWindowBase/__init__.pym]O0ϯ 1)(p#pƘv5ll=g DoO^w%UwfEwosLc#uB7J2[2@Y r ^6W!jrEMuMZEJf[^kqjPKSF!+(PyMca/SimpleFitControlWidget/__init__.py[O0+6H E^$011Yn;kg{¿%'˶;M)iBp(Jc41,m o "$`[)D[84zTpW1Q:&-=Ir9r-7zV-8R]_^`x $ ϰ}6YwHLAC?PJ&OPKSFϬ*PyMca/Gefit/__init__.py}AK0=ۜSOjIa[톷-h,""" yC u&D08"S3Af7V߿ĚS?(eS]M[؜t G2 ݅A ¨ShMAGLj@p Z*>×M ڞS+ )rdn)/5"s(gOy0AWËxmpLq`ɩ1;rV+vvM@!GzB`ksǣ ЃY:^2^iݡg&*ֲ$u Dž2jVӴjPvKžzS߽zi}β}IĒK5آrcXI/v -~f;Lt ]w@΃s\{RO~ƍ)ָK 7U\TSľi$>G(+15 0^!߇OH`A[n}/SQ/@+ ME}x)hWl;mUDPKSFs&PyMca/TextField/__init__.pyeMO1-$ "(Ƙi mk IywƙB!Xָ:,HѦJ ۝H o=Z4?ƌ6s'O!>OSjdDʉZ2X'up_M@4Z,?Fo`nt!x)a,"XB[(5tt?HNhVj-57>e3PjAiƉ69O†B+?.-Em5a,e\R͓j?/h5KxL wPKSF jPyMca/QXTube/__init__.pyO0JUڭ,҆ LN '$"R=U=?&"}?!mfBI) nE+2.5MhJ9(CN{ J콳u@<~偃T$ΈR0jFU-M:vTKPz^[A\fY*xN6JdU%qh}wI3\fLM V+VO3eڵ]ל\2R-B铙 7f,,42z0L"0T IQzbG./j%G}(|WwxsiP%{ǀxG;?oPKSFPMPyMca/SpecfitGUI/__init__.py}[o0+C覛[|B@QH#OnKkKCSAԁh0..+/D KP/Ԍ T2l# k$uqTlN799?PKSF-$PyMca/SpecFileDataSource/__init__.pymQK0+dl""f]YHB Ѷ I{RN_|-1e[+9Ǫ6zlj8{4)?2 aV%pe(LxDHEvj~PKSF{J!PyMca/SimpleFitModule/__init__.pym 0yPJ/Փ HO !oU)-dTp8W S6EVv-e| X/Fha՘17:zѻa]/0&kź&`)Gs!QF,tgOB?-s0Ev-\'|PKSF6 "PyMca/PyMcaNexusWidget/__init__.pyn0JTRoHu0i"79 ({8$ z퓀S- EiiK QDyTi.,"\ Bƛ}A4CAH Eʳǖ^"h8Xf1{ăW˟댄̲zRXw!E]`/j!yl;<>ƹ}eY' >C$o>Y:3vAI8}.Ml#$\ծi+% T̮ۦa)Dꎷmm4m+|9!qΌZ)U}"*+lyh[\$r;!d߼FLH 3f6h\H;/A@V7le\Zw,=Z`t^fF-opgHeq,2YPv`t.urU5(~ F ܥT[V/!eenZޜ8/,aS;x~/|z?!PKSF=^(PyMca/FastXRFLinearFitWindow/__init__.py]O0+z$ƀߚp!)3Hb4]َtl{ցDxռO󞏥9eJ#B^hha@9;Њ,Wjk#LIZ:0on>m:PuÏg|AzXFȄko U>ݗA.4d-f3(Lm zw]s. ' [3 Y1J.=I6"bv4P^zGuՓ4sm2kMGӬloh`xI3`O6fKpѳD6PKSFz8)PyMca/PyMcaDataDir/__init__.py0>E7t89Xĸ85צHC۴eJ gE aB~"GD] RUIQCjW(7U _F(x||PG/?z;ᨤG颬aHcb 5W_`']QJ!Rob;z)ES K.$ Z1"L3亼,@}#tv#Sؤ̿vO f6[nпo45WxefiIBY Y7LH>r \WǙ/q>]~x<g눈y]j!ɕ<v/Kq5zg)}kʿ 'z!4G,@f+NÊtgvt̩ڹ qf xBJrkz龱~j12pV~q!n êT\#IyyW=[P!<⤻3НMWrfo(r\uﳵ.(N!ALmi A_ee@!ı I-C FvgӌxF\H(9 (AÏ&L>5OΫXզL-l%EJZmsWjQ`rRxL:a^.n]yYOwvk1plnY|EVe-k!dBcB 6׎sp̭mgrL;<(/\+x*?f6 B 4ĵ>O[۱jfmM\bB?PKSFsc PyMca/QtBlissGraph/__init__.pyX[o6~[NŁ[NbԎIzv0hHJQI_ᐔ([ݶاSKNOm% J@P2*]]j"?v n_VEH'y\+ VqѼU; \/nVYQ_1 y:at9pg'NK@Z$)wIғ=V~}zL^efG@_V9nU?BP2&y޾B/( 8戀<I=Y@.>cR Mz@遦%Rߏƫ+cܺTܤ¥dU̥w{.>A141؂7*h~]U`FC)aCSaDoہYnN $ ߬qR{;?[}jk7ɲӂ9T;ӮuqHׁÐ9۱ӄ`MunsƙxsJЌ?DrEځ^G +5MA}'z`,Y yQsB{ܨ}SY֙sr⅜0AÚdOWFCju[G ,XY3ɼD(Ah%YrER@í\дPPR?WΜ= T )P5`N FЮXpM{HsgCyJI@PcNՉJ4%FUü%^D# s@4+R% 2߸ \ PrlH  K[ 4gjޅGa> _Aڥ*κ%+4^׷Ug ϡ7CUtpw9ʁ`- *ã9ZU۱4\CJ %FlPo. SxFƠ|vH C6E;jֈQ27uG-ҧyJ} 7-.;z]-ZOGxh«0rUC^o*rc*Xb*סqm/oQ&f@N e(˺nP2FU)N3t8M(%̂UU&6X]^_"â4N.2Kjwj7|EǻUU1 #WgY-˃#:1 cE]^}I܅c [1 6&wg쑁5ϑ&^Hfw#d#ؚ9Nw*uZ?W DLT\4ª:vӂ9[pվ/KH{;쨟' ti43\a͝y\n S/i\xo/P/5F*XYNN-* kUW1wS{~,ɼ-pU? .-3GZ.H܌'zͲ<~hSYqB=lB ??xş6d2 O,h,d\ll^H=#Ɔ~Fj%I Ntv lIg,o}җ4=!׍!ёteJ [vY|ƑT.>vЅ5U`j5+?PKSFma)PyMca/StackSelector/__init__.py͔]k0+!0pvBbݲa;FJn'Oy*Ǖx"B)8,PPiNm(Y8I,0M\-W)JU +E=ůsdAܷψS[v rl+& YԧՔEdo7Rt,ZST 'E=6RryzB7YERTAU=+Y>5Ra-G62*kGZΎL_OfsFDz aBMa0^f)͋Xu.Q* i5Bpo:ڝPaED,iάY2GR@n34Pdž͕?c9^!{ ̭ /1Hff JWDPKSFD`:PyMca/RGBCorrelator/__init__.pyRn0+tE ZnS#V"G"FZ˄)%W ԯR_^$샻4 lYcm B^ie0ԆK$Vȕ Rz#bA0O8g1C- g/ɰep* oBg,ˇA$G 2Lz {yQ߽ W]ؐtrݞ(ls,".f> fm8OEh]试&a)7TL7YDQodלktrYgJYJ rϐv| &d@_˓SfCS^6nO׼϶śU6;xN {V\oQ\euiT- _fZJe fvIj݅P>nO B߁+e8wf7u)}G% ouFM63ڃyPKSF!~t PyMca/PCADialog/__init__.pym]O0+z$*~$\fđ4,MWJ?fׅ{TfӷFK$V% pe*jVh[%5$Bq0Yq-Ô$N\G3F^G?{OOc+ !Uɢv.ILY>Z.D( RdȉYwW! (kB)+,Ki r.Ra#N dFWjz)mXD Kq*CZ,ށn1Qtd62u)6. MlF˚ApmېNz圧yʥzɣzfؘ\6OK)`wn4BPKSFۨkPyMca/PyMca_help/__init__.pyMK0dK݋"^DJnI&õz'i+ B;I 46i@G>FZj[ E[Zc䴪ncp^hSd!P Ѭ-a 9/Vu@ ҁ Fֈ=BݮyIA7e/Niu<ȸ,M;0@9?iC;H#Ta{e;گF~$eri(Dssϛe{-cNk OGz!~_~GkbL+芍z6xNGӐ.GC|,؋%Wj9?! 7 ˺K1ef` j( E#8v!ep1Wo4<-UYD PPj 6LP7eJ#-ic ҀrHwIKj!NŊ@L5Do[[Qr63h\uAsDBf7!ɄM?^b 0[Ȱqk>F}wϗNvpfCB!T,C@/4MD0)pwv;BiY]P$F4N;.Mftj 2hօAȥ(]%٫wTV= rו0 {BXDW-gE|6&-蛙H[PA;^PKSFn0lPyMca/SPSLayer/__init__.py5 0EB BŠ2j$wfνs-MK^H3h\ft6ן@-)$O !Vj׮U'I~Kp ؄{O0UJMc,ry-?PKSFykx&PyMca/ConcentrationsWidget/__init__.pyWo"7~߿ ɥ.;x }^5kU/x o~y]JQe+ EUJ52AU/'~ D^hww(t?^}8oI^ #Jv=?EVZHsR Ly*}2)*qƅ Q+LbQtbIi+U-]rʓI*b4|\4(:~L'mÄ }Vz/ 0z.iܹ9-0fhp6S J̀}`bͅt)U¢\ӬxT: @TGh;l Ei{6EYٻeEbu+KC!W 1r7USՎ[Ixv-̘׷{Bs 6uw mۈCąE׮Ml8%),, ♺26Уs'[{b)uDpm .kp$I[)GZxn)}/͎# E =Z ߅ ﺅhкzύ,ضSu[lJ,eƭ ܪ5f<ȣX7H6rpU}mX g. 3AOp2ʶsؓk~D3ia6<;r8lbQq&k[̀sOTzbBqj[?f}.oaQ͔Hݼ ){PX;tw}nbG`;DSLWTr9, ~тc*GA(w:\ʶnh^Tt 7M3Z ;yƣJ*$nAtAmgbr9x @s~sZ@)@uEPKSF &y %PyMca/NumpyArrayTableView/__init__.pyuVn8}W- XYS'tba-H-IV3#RQ!ܕyKWE"/qQar :{uv Sխ1Z/tejŲZ$_)^c)]u:g7ц[| K&le۰I$6k#i嘜srsIWuEeF0kDѝp jPLHkL)Axcbr`PR<"PK(29at9%̘*#2!QmBA~HBurAE@}Lj/JH{xE'Q' ނJ6&qFml3Jڣۺ| 'p.yoq~,0( "C}ĤONSwt]"eMxƗGIcZ2E@ei>Bg_@sSb+ "};9PCe]'s8C@)kAOK&TX ps:l=8ThD=]r*]a#Z,se5a5O3m4lu`o;?a (+X='< ĚJJ<Ćm8gsˍPKdSF ƄPyMca/tests/__init__.pyj!F>I IU J`H{Mצu6w8G.>9*!C40uwL_ {0NpT UW@p H+ <+I~m(*ljTROWanPmP/AI?BҠ07*L!R1~S*vVv{˜OY_06ͷp6쥮PKdSFюDzI#PyMca/tests/EdfFileTest/__init__.py]; Fw~n&>7TwBKK%ƄBT*֧Il Y*/PwQ47[&Xօӻ[ |2!\'46,,L<񥖦*\CBFkc΀stu8.z&u;PKdSFC _PyMca/tests/TestAll/__init__.pyU D;Up",lԀ( 5X"#NgdAU^A;X`6)33KkMc\BnPKdSFMgX.%PyMca/tests/StackBaseTest/__init__.py] 0Eԝc!PJw>:iC"{Rݽ\FEoQ9G >2XW@ë́Olü.sv;ȔY Q~DX8VjC&QeOcFo*8SƻN)ɁV wPKdSFҬ$PyMca/tests/PCAToolsTest/__init__.py]= 0Z JMtA// zs'Ք11z`JG4Zvy6@lS-{B2G#!,l +%; 0Kkzs U 1nUmӜ5! ]Ww9PKdSFo6'"$PyMca/tests/ElementsTest/__init__.py]= 1 &9.ΥYM MOb>brR)SdPJZb& 4dcf|?A9:ХXn!D(>[MHm.?;ӈ Ga7k2qKA[w>Cs}dGtjÅa:ѽ~zkPKdSF)+Q@+PyMca/tests/specfilewrapperTest/__init__.py]0 E|EF!S٣(uڈ;ŋu=-)HlZ@)BNd..ѐKQ <~16/n:&:epI^!AyXgHK&Q`ڏg9CRwRfVxjjtu>)Vݑ xD=BuB|PKdSFc!PyMca/tests/GefitTest/__init__.py]? 0GMvܤNNuGr&%{BJ9GR >&&@o{P߂#r"sIXLZ?ֈi}ƻ)wUk9PKdSF9$PyMca/tests/SpecfileTest/__init__.py]0 E|EvCv@bClE)y)v${"{l[RJJR҅ \\$N!y|516v=\6K%| Ay͐\L5lG!e掗Zf/.#欽 =Vð). 6z34 PKdSFKd~;&PyMca/tests/ConfigDictTest/__init__.py] 1E|EJ`Y}qEfNVi¹1q`Xre]*&49Ɯ+3:}b)<4dgDdcߌx-!gJ`tϏ9yOx1˽ҺH+nrlAn^9bݮwR fzϓ,toR PKSF^1PyMca/Plot1D/__init__.pyM; 0=v!܄!,BXD?uG1I J H6Jr*pFNndߧ@sOr{M]qj$j\`x2=  QXoj;F@̍ PKSF,%-. "PyMca/McaAdvancedTable/__init__.pyU]O0}ϯ[7iBʾ$hӍʦi6ؙP_{ cy|oԪeٲ,VjͥEV+-Uu0f흣{Kf٫~7=@|O<}Qt;_L5Y?r˜%|1j/S :  1)k^ b2om(ȟOGz`9slTcR“!4ZeX5X|8JkVZT7RlBz9o+. ̼7sY͈RF>YpOyN*p" ɂCfiAPt_ 6R* 3fցdb)7V&8qMytXZkx +Cwk8)R!ƾ'>Wc!9wb.Tts}m$z 7j'#2M7A\3.vymA〃zwޙ;sxg^|gPKSFh!PyMca/FitActionsGUI/__init__.pyeN0E JBAZ] BȲרmlGmD;Ό(cYj2F8 HV JoUJ ,B [XĻH.]pDd M>BjTJ~l _P>$c._5HNXn"oŞEmh2Xu sOH h!CF^-k`FYwK47msCe#kh>yp!-%u3/vDĂ2ԒgZ 'il˶T l VPYjIbx$x@p~w@1GNfi܎N;sp6 FҘnN3u3dJa.IչYC!A$/ޒDGB<RR .$ **#0NR~aFbi}褌..Í(O=q +Ec¬Z,Mfz[?B` ?!.KV &7XK]p6A¦[E~:,*=ݫ鑸$wp`F;33BVN Ufxl+- *W&+IUɴ_xoXhϕ$}n jLV#!SoR|/0<[Y̹l-oGWBȔ0'9v- X"*j-mf}zq0!Od>,Dm;_SVF7*Qm1% I*#^jZ]Ot3Іp㚉PPWt?TRV0ZŷG[,iL0þoPKSFxqPyMca/NNMADialog/__init__.pym_O0)$*Ixf-S1hYl]oA l9{ݶJ^o+]) W(&4PA4m\]  `a"{o 6^T_˽ ϘpVWn/t06&LHY,O6["g0i P׌Zh~1(*[dcKD׽JT45(}@NZYP Ϊ%eic:fa/$cQ%#g0ZaIf +Į> >LQ_EIt݆4ڡ&*A&JdC͝<˽CƖT94,@?PKSF/!ɬPyMca/HDF5Info/__init__.pyXKo6W@Q~r=$v^hxcAKED$譗$o蛧*VҖZVJNen#+U~S^ wj|7CL_?Eh3[aojC26ioXL[)73 UY\tOgNTI"XL*YzcP1PnsŌl* r0B Ҩ~)tҍVl/J:h쌌xZx:Y kd9^ ϭr]Zaq8PC\\h~r˿G%7zo< r}RKo˔ xٰNJcUv* G0Fe*n*LemMnDZ5s- s56I k+7C(R`#b=vZRNo?'m|J}r[w|J-=ss kE.o dJ+lORY (CP1͋y.RL.v&#LJmc!s*6BkO êd`4Vx"'fɌdy]3Gh2TMX fH3S ;fLCA1啊J\UPڪB?Ɛ^Cڱ6+ ^_ZbgaX3U PR$22F>l8>W{<J[ʽ6%ҮsnCYV"Κڑl&vF }hD;, id (ݵ;zwhxk&ତ\jS i(f.I@\1bxU˜;=1L٦®[=b"e,*K8%Qi|{ 1a hϫdR!44&hfsO)ƶ0~a_ PKSFف@PyMca/StackBrowser/__init__.pymN0E J5A ,Ee71`;<ڦ![ܙkϬU B8PŜ *zW@"ї_BLce*$MF=FJ>3zc9Q%MR T8oBpL}w VhVS ]`Kە!QklNe;q\y*p]g-Z  : &J^"] 򪕹uWnECs!:ӦAѬ GIagPKSF\;2"PyMca/SpecfitFunctions/__init__.pyU]k0+rg c` Iƙ86"dc&^~o9ysHVC`ьC 5@]i $jCV5R^rɽ lk6 >ǔm[Jd/gfq ]+smϘqOH sP!~!%<}wI>&o]oFtؔzv $;M@̝5썄oN+lt %\0^mx %rn,PHGv[}uM:‡}!Ts^t¸ PKSF"bW PyMca/PyMcaPostBatch/__init__.pyuR]o0 |ׯS`-k֙Sa0Ȓ'+_?ZVҺ^ly\]yj5灨m0hPH*PhVfW'{E ȩ|ۤAE)謤x3Jo}8lޑƘ06n[||~D$dcQ\% TņDEݟ=,T_fجnUI҄Zi "DeCS tޣ[ =NWE[GZjIO֊Ko|qv&=,J t_v,3X&q\ nSnY.ywI_ w?TEnǑֈ[+  |A +J<9WlK^ۨihGÅW=ۈm{b.{: 2PKSFmm"PyMca/PyMcaImageWindow/__init__.py}]O0+v7H En!81fi2vv]gě-yڞM3E`FbFyEk&Boy F9šoVU0EJf"$RQ;0`BDoAd>@='a^(pI{lq[R+Tl~pz^L&Kq%Kدz29BPKSF$T)LPyMca/PyMcaMain/__init__.pyQs6i3!p36Iht:b/A|~l[ r{jgݕe"ir°ITHL% U)*xcG%"ڔF|IW>T#b gqD+w맦0j_ p R81dy5& $%lS%fظFr/ݤw0bHy,^Neޣ|##a d3@.Y> 9}w*DXS-*=%n4L h#>( 6م4VW&q*g>Rm$5;4'P$3 a$vՕl2řօa˸Dj]E5e.VVXVL%I8nPx_wy0_oZ=4|閬^z7u5 ἋЈ,k(d!PyMca/Median2DBrowser/__init__.pyJ02_VQ/*)"!i{X$e=i>7-|;9'FQƲV2FAUzZY&YRFl s]Ys%ueƣF'4}4|L)pkH}4S3{Q'?Cl# ~Uvr`F(s4n'/~qJ+,/|.L .z [S0u\+c$d AԽZMiCtޡh^?h0uxilOIJziݿ>PKSFUoPyMca/linalg/__init__.pym!E{-ݎo6K/Hݓs [PQY6kLh6-LxW,ktV'W 4>Vߛ=dVP+S|_FyPKSFZ'!PyMca/BindingEnergies/__init__.py1k0w oNK,%U>G΃k[{;kwRM} tG.BDQ%I4ys :B܆g8AXC9jm(_d1ܐHLvcfX ?j6? ڴ6Hz7Ԭ#i;#Bzղh+-0pz ^6wBSUܥ".EHUyt gJD_PKSF,%-. PyMca/McaTable/__init__.pyU]O0}ϯ[7iBʾ$hӍʦi6ؙP_{ cy|oԪeٲ,VjͥEV+-Uu0f흣{Kf٫~7=@|O<}Qt;_L5Y?r˜%|1j/S :  1)k^ b2om(ȟOGz`9slTcR“!4ZeX5X|8JkVZT7RlBz9o+. ̼7sY͈RF>YpOyN*p" ɂCfiAPt_ 6R* 3fցdb)7V&8qMytXZkx +Cwk8)R!ƾ'>Wc!9wb.Tts}m$z 7j'#2M7A\3.vymA〃zwޙ;sxg^|gPKSF_PyMca/CheckField/__init__.pyeMO1-$ Qc-dmmA<ϼNuKP8#uLDkDkȺNVKtd,v658HK)A0md U}+ܾ̫Ϊe2zÄyt)@i٩KB o'h͓VH"x[>cJyQ P,d1U.fg-:xC:?;Ҩ;,gee1jبE n/@+c?%PKdSFgDd6HPyMca/PyMcaPlugins/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKdSFt*PyMca/PyMcaPlugins/MathPlugins/__init__.pymj1yvEaPdR;Fl87L(L9i#-z}7@Dž[R%#,a^:E^E&Z|5r1=7=?QɃtNO58l:z(V!S)'en. ?PKdSF$z%0PyMca/PyMcaPlugins/CalculationThread/__init__.pyUMK1v RԪBOЕ fw&NKIR#H) !"zb0xh.ϵA6~IlyRajZ'Uw"OZL4<Ԝ )Y!+*JIգU>u7C&^O&QϬ'k {ñ5> yƏg7?PKdSFͧ6PyMca/PyMcaPlugins/MedianFilterStackPlugin/__init__.pymAk@+RJ`*9*Ju.&aw 1x~[$z!Bv>0v:iA5ZϏ2dd_ ֘ JݵmIx56' ^Q/y55gϻT4/Y3on 6< Y9=q+»ԓdLVM],x=~چvݨQJ  vPKdSFE0PyMca/PyMcaPlugins/RegularMeshPlugin/__init__.pymPM0W "uX. "!dnIj&9Rh^c޼I坡W1D8ڴzmV,q1xR0VVn0 -:?PKdSFKz57PyMca/PyMcaPlugins/XASSelfAttenuationPlugin/__init__.py0skU]=x(S LX|{Vz̟(@S716*)6lSU{@l*qum!lu)&PeW ިSB*M @X*=q|$2di#8<}5Nц;yl} Ҥz/dܠϯ@'yNbQy ,g&> A.S%b}Mr1PKdSFܶL8PyMca/PyMcaPlugins/ExternalImagesStackPlugin/__init__.py}QK0+d]`osoڪbE-eY/V@q#"kmދ_ q>ӟzkדOPF}mg,ۥ.KGzwk.Q֐4ASJI4 W|s|*{b4PKdSF .PyMca/PyMcaPlugins/StackAxesPlugin/__init__.py}j0 z ݒ;rXi6zHX 11N0ul;о{.+;~> u4*"ԃwcD?j92jgKOk#ŋ6jq}eBT ?.KBC>?sc- ynkAu-:}KN^ś|gCV&+v6֛+OM?ѱ~?|Q~~u(!`B3kZ33PKdSF.fÒ4PyMca/PyMcaPlugins/BackgroundStackPlugin/__init__.py}j0Et] ^854RPl#b}GI{sfD!k@=ZZ)pJ*hCMѨ jS!ky60i+o>4]i:WPI:6C5ҷMn зaW$5\80'4ajs]f)=bq6} N_`mn8vZ,osPKdSF2b.PyMca/PyMcaPlugins/MotorInfoWindow/__init__.pyUn8}W-).b; C|&hqtX4XSJR_^_%9 gs|70xU+m{"+S˕rgUt 1(f{н%Ãd=x#OA xEE䄧ΝB"Y1.x2}(J3+XUjV׫Nh!-Hk>}-ϸ6vV%Z;1j`x % ےB!N4[K.2 һue#. / 4,8&B4ǍvKL5~zdGZ6@n :쭪CAylmO˕jV&Y5䵇5m΁e8uW5R(mqH%Pe>=dyw? gBC wX'kBCiE.q岘Yf*ah0\ψPK Tj rXiyѨ@S! ?q/U=Q̓,&MZ{٦܊BȒӝB NAAc)~󦫚ɬcxHԠ n(_m?2DiPc>s#c'j)}QUյ<8+XY_+!ڛ O;Q7~q;{J8n lu?pKiVux7е#܂;K9%L.S$DMMԀ;2ء@\7)a!9ހ΋LT';p JLˑgǖQKVZ@31Qp+ppLzw4C*}uߑ-ՐuK -C]x,KY1~/u6PKdSFT-PyMca/PyMcaPlugins/FitStackPlugin/__init__.pyu@ {"VEHƶ IY7mjc|&o|Dy+mj֍c-[q![gR5R8(1 mG1q(ڄ5ziU) OoiCON8aۿX+ Mg:%ד" Glc/@5ճPKdSFyJ-PyMca/PyMcaPlugins/PCAStackPlugin/__init__.py]O0+v7H56\L1iUv]޳pWiO*u0^6 c4\I-WTf<"h.H'`q]@Iʽp >g+*i26YΛ%tH_pi&#iU.I,f10n\_?wPza b\'{7kFHoGv+ nV{0QX?ǰB4]4|bGqXhs8±6uwĞPKdSF# :PyMca/PyMcaPlugins/XASStackNormalizationPlugin/__init__.py]K0ϯ];Z؅"^tL@$aiRdzO3KWM!}ٖq 朩YAh"Z;2hCՇņMv`8ϳžʮX-;'D!w ̄G&Rѿ*_.)Ew˹u;nnJg-~Qi>cj97m'd< #&'Ą۟ 7e1_XWcsZx(qQ>:BiPKdSFEL-PyMca/PyMcaPlugins/ROIStackPlugin/__init__.pyuJ@sD< =X ClaY7ei2v'o$R~ICf!y" ]`$Dfjuu|R"g\f"3n.pԴ!źæW6_)<:SrT2[Tqnv|Gr .w-:V|b+ݣJqݏ61ɷ^nPKdSF>#3PyMca/PyMcaPlugins/NormalizationPlugins/__init__.pyuj0EɆR6E (0aQ#;ȥ]̌VK8H4zbP>{KKj,`.Bm>?.1=-72&DWNJk6/Q3/?=)CVyy \kaӸ.#F[&qc])sd>t"ȷ@8PKdSFһO2PyMca/PyMcaPlugins/AlignmentScanPlugin/__init__.pym 0D{K =(*xZA !%lC9ǝ7fJDKRl{fl^?>Ybkiߩ`0O KYhߢoPyHiEs<Dq{q8E8/>\mg[r'Н Ҋ&}/PKdSF.PyMca/PyMcaPlugins/StackPluginBase/__init__.py]1 0ݜb` nGI i\+BǙV$2KDhcLs^ fA@C Yr_}fWi;.iGgO M4Xc[e Zdm;bu PKdSFjJص&7PyMca/PyMcaPlugins/StackNormalizationPlugin/__init__.py] 0EB)]HtU(B̋$.7*r=QHi?uPָ byFCP2P-t|Yt !uR=ɾ|&i|ޚDDNR5'Z&+o{\j], 6r/PKdSF˳+1PyMca/PyMcaPlugins/StackBrowserPlugin/__init__.pyu 0 @6Aije8d JF֎C{ưx 퐨ꮷ.` 52hkf,BZq˝HVOδڇ-} d9 w̩c;d«#An*D HYeϋ5@.tίggVxS9{ l/PKdSF6n9PyMca/PyMcaPlugins/XASScanNormalizationPlugin/__init__.pyMK@+D*PB)TZ(,kR~ wXj33zkP6!Pg}D5EޒCXq ]Κdhpɢ QK4Pa/tSԮQ/¬is縪/??+ʍ~K>F>C&PmxɜqZo_~}ctx^SN3lS %w-S"NO/\`rذfHwh'T[3g턝R gP)1PKdSF>)PyMca/PyMcaPlugins/XMCDPlugin/__init__.pymMk0 9렇u Z7L9D~Gh2z<޷u=Fvdulޞ.d5S6\JDXD.5Q8O _)ľZO|tD3 x>M/-\$*Ln!N҈=2"a##@>/2-{7 Žm 3&ѓ>b'LPKdSF +PyMca/PyMcaPlugins/Plugin1DBase/__init__.pyUα @ =OM:ttPvGN5'HO"l'K"d i8K`NCd[jn eO\~VV=s\۝ZvtsID\"4O4#3Z;˓{H|.*w)UҜe6mZ7K&yvuim挙\X2R])hm=s{0aB1 TK$-GP^"2O]&3=Ij:A] Ɣ"$2m%naX {3Rr9{I\Y~ qRqfM̏d'@Y~ $AOn`nO{VQx<4|~GQJZ0=5 ր0ē^PKdSFA:PyMca/PyMcaPlugins/FastXRFLinearFitStackPlugin/__init__.py]K0+rdx-i'p Bհ6ɩi&pyy{0:J(My HUVT_[`Aȭ1τNr1j!؝*5*&6"w<ek$|K|bw[JIE>3H_-~4hl.[>}ds pq\fe*ՔZub 5 ]|}~"$M+ \ ?Qʼ md}}Mظ&d=mYb,]cΝb U"2n-m޸cأBiR|7PKdSFl7PyMca/PyMcaPlugins/MultipleScanToMeshPlugin/__init__.pyuKk0ɁRk!SrPIC Emҋ`fGEo]%*!LC.dޑnLY//S@ppH^}WnuKQ%<2^qFfφM{ y`I[L{L&~#LK\pGݶab07|4,ޝ^xo'_ JƋ:!5t`H)Ո޼Jp?PKSF\TqPyMca/ScanWindow/__init__.pyu_o0)&Tv&aʢ',t4MILHv@1$^sQ.eq$/n XFN, DK 0ENpƨW۝wdDȧ_ 2& lvDe5{;;[ /q)4ug(#zAwűtgԨ`XRCx |*0DqX%i8jTDY>]4714O_=g$XT PKSF>PyMca/EntryField/__init__.pyeN1[H E.r4&tvě|OSg XZ%Q(qZ:"$SC|:F2։VX^]V |D% 2\2 lᦾ^UguxXQo"tp9$JvxPjqIJDY6r͜)QGLoQ Pd1Ml/ZtywQC dyh9˖e118jبU j@c?'PKSF !PyMca/QEDFStackWidget/__init__.py]o0K+MU۵]7H>v4!8W̘f{ ؄IIs&KFA. ^0dAHAM#Nh-TB::PhN!eT^ .@bý\C9z:"52z)w)'-IW/d¼|4p<&z1e LbFت@qQ3m$ќ#X C*Q,E_HNdWJ@""'7QR o%g[63B=Cnຎރ*C%)NPRA*0Y~pZ0W㪈 9-7ڕ *Gql ŔIllhPp8el%BUM3O#X>LmF]4v $ш$Z(і4?yvHz5p?m;3 =-wX~N[b-B<㢻ie-w44Ûx3G'<p$EWk%$,uD\E TiΊTDRY̷J˵i=~pi⸑-GLGY2C)5۞ v?6e\1Ay ([Y |ңg/&CcMb;EViW)eXw ܀/pەէ}U=aZ]7M8{[$kJۜD(ށ?J|+,AaSiR݇LP=#!z8!c+0@M˟Y _kbUvG^hnM,#4_if\IeZJY@4\C]6mf5We`Ze N Æ~im?!͒faWP\yiVR͓L%nEW5+Q8w8(^Nਜ਼kM4ЉV e}˴op:lcaoۉd5;r G!~h&D#eҌ],a|JMuR굌p{Uth厽聛.C\Vqenm ]>!/PKSFuxz PyMca/PhysicalMemory/__init__.py}10 E"#7&wR!5 ϲpaER,jPFWd׊??V5cLw-<`ds£2{]o4WRjWUѵp PKSFgmq-PyMca/TabSheets/__init__.pye]O0+z7H E.b8>1M ;{>@owD:t <ͬ;怃JOR7 ;jՆGpGls켣qeef=Obt?Z|z$ulfښDJ5 scs78)n[h_B0 lA7?WCªºQQXi{xq/6]뮷ޏbF_PKSF:PyMca/XRayTubeEbel/__init__.py]10 E"[An #d˥Sۓ*ߠ=-+sRF ZLϊ\JpIl]|@\ ).ݚ_{?8p H ?h*o $%gO`t.opq%zoPKSF/U!PyMca/MultiParameters/__init__.pym_O0)6H E^a8`Ƙnekv!|{2PyY;{ӭ9miJEB1a@aRxw1 x!E-/898f5gDŀ;Los.͟J'BB`V 朧#-j=^zΰ39fZ0.c~1(* ܏IK,EV#<RQ}]f8H)-,:,]C@Ú(K37.EO$db]?julXb鞡ͯ6YU čes5TD9aS?APKSF =#PyMca/RenameCurveDialog/__init__.pyeN0E J5A,B7!dY$1#Ui$uص2Vap.I5Sڊn@x=JI/?M%}X'X !7+,B@Y)b.kTgJS]`Sc9ֵWHoH7A6m(~˞YeGuU\Mŷa@z+1QlDPKSF@(PyMca/QtMcaAdvancedFitReport/__init__.pymQ]K0}ϯ[62QA=`v_DB%&1_mt[8𶦜 4^qNu6!EtV~ |5.:Ƙ_KK)̮hRw?$z3j?Dc`R*epM i5@Ɇ.2^=.{tx9*_l=_$mr1BjP )VNn!PL*xY? F}J0"ޓM<`! o#7OىpmgoqHu dLZPKSF<&lZPyMca/SpsDataSource/__init__.pym 0RAE[ġDC Ѷ IVĊ.ڙ!}]tk : tP֨ۀ9 \+XB5/1#W2|ΆFgm~w~W!_3靪aZD~t`xOHaC` nXf(P ?Fcx, PKSFlFUPyMca/MatrixEditor/__init__.pyPO0m" &\I51fiڲ5l}yݗ"ze󽾍&7A@d6$Rd3)] mc<Q#K2A]C{BlY,33~uio][<яZ{͏2цĘ0H  z|?>7 ]44H5ڽS!)jjD2Z(̞Z*ʶ\q(CZx4"1@bɓHM𢆩|Ft٢D Fb,d1 aE-"ukO+z-yL ,s;ǟ_ÇV} a4o^Ck_(KPKSF=ׇPyMca/DoubleSlider/__init__.pyN0%f:tfc]0S1A(PZlKo\+x4Q$%R1a0)Pu2 m$ĶƏiwu$g,?Q~NBڸmc0Ts6{3h}~<;@k>]L] ZcOV_8a\B .O:c cάGwqΰ5~PKSFj^PyMca/HDF5Widget/__init__.pyWN#9}W FZr%<! 0ZZXq=n7IoU@}NW]Ӱ1h'ɦIEmF( JЪ!B`Z?l+;2INO,e{K=׿OϗV&.I=2Oc[TpPy*FQWġdvǨbTּWa j;V+!Lg\͗Zv /Z'o-/ ^7+#Ih% /-^U-8o /fBez]ntCIh{UsOFoT(*PIQYd8 r,  lns jeQLΠDZ+m7У.b;>'`}6,F.Xauᩅȷ'1Y-Ssuoґ ~Dqr"\: A4gK<+Ƽ=WДz1|E ~M:jm*2_cnEFF%*D pi:l }q>^Q1 7}t\vMT#7*Cu*341 ^ed-}KTǕKE[n[ PKSFotg' "PyMca/XiaCorrectWizard/__init__.pyo@ W *M 4I}X`)&Gr#. g'#l>Z%ms5OmɵZ!hѾa&PV bوL))d5Q'3ΜQGCWg7--񁚢/ir0aمq/`!W" .JseJOXJI$-U sU 9@nZu㓁ʨ߲A@, H- j76^%M3E^^jNنvx{zl a9#Mߦk. O~)V,|ǸJBdiQEP5Orm}N}ؼJ(tΨ_ޱ伧? 3.PKSFyWO>&PyMca/ScanWindowInfoWidget/__init__.pyN0{=cK̲dFҔ͠Ŷd$vym*bs+Tg VPå@a*t\;]Z.%[RRKѩ&N~PKSFR<#PyMca/PCAWindow/__init__.py]o0+CŨ-BeHD#s˲T脖%Ç?>=m JMu*,NF"@9LpͫbAvΎq@76UTx^tZ`dvSzmȝvZ9cpX7b|Q`w{MqІM۳y'*TV3Zzj/Vb\@&B$J%RY G"h}Wd kDM4Ғx? YKuKTd2dHcp!i~l] |R_z,uI;l J+mi~0,/%JfŬIO4eKWŵ<PKSFզsPyMca/SixCircle/__init__.pyUA 1 E9E3W\ԕCi%8IKڂ~P{}, ޺E"d)cmn54 i_I߀n+<ΗhdaY(R+ub k4xPKSFq./PyMca/Plot1DWindow/__init__.pyuN0EޥP@ 6d*!8/*A[@l3sgƉV4lcJ(J-)V( IU(@0W6;K8Q:p:l:' cA hc>W7 P*sLV33|ÑVkc޿]#:l4uxΌ![!#Rb fe&H0ժ\,T:i‹K!Xg= :E~͞0l]K+<~ک0,_w魈c#l|PKSFo(PyMca/XASNormalizationWindow/__init__.pySMo0 Wݺ|`X90 *˶:I$Gq;4;0,Mk'Ӕ)SCV9eP+Pe@iLAm[e3g$%t:IX "Zy>?Nf p~cҾAdQ  EѕR-kN P5f踐 $,X0@pӖp>b4}]`QZ ʧGr7eklĈU69g +ҙ/Pv ZpP۬~UXp2>l*K[֎4p?JTkܼإptuS9P B4ǎ2krIfVj=JP!F.(UQ]8!d|ߎl|ج~w~af?P!h19?c_O-I驶xhq M1PKSFo[/gPyMca/PyMcaSciPy/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\řy9 @# ɉz`2893RJ]GdNNfqm:T,V PKSFE y'#PyMca/PyMcaSciPy/signal/__init__.py 0 w?7'PG:"Q[O:T@w[w n>:ʪS1]S֫7S>1#Љ9MJuir -,. FО"MW?Πdd!Tw ]#PKSF c?*PyMca/PyMcaSciPy/signal/median/__init__.pym D~7(Oz,eRun}RH{X736v=F1p0R<S9:0Kr,9SsھN"kCg/IǨsͭe],:.9PKSF;mI\/PyMca/PyMcaSciPy/signal/mediantools/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ Sb` KpPKSF3#PyMca/PyMcaPrintPreview/__init__.py]O0+z7HMF44KWXekg۱{$MyOӭ&d[B1B0r KuU&+ B_O HBzNX4rue3l)ftҕIۥl6bSϧw ^cw DHkö^ s[JYnX 9WQ9Kx+&@jE,iD;% U/vB*Dzb"3%-Ho@%AlYd3Je1jTT(m_vo x'Xf6We_b7PKSF#PyMca/EdfFileDataSource/__init__.pym @E+fADMeBED=Tuw-*ūqw(^*h?z9 $.1c'LXwyKlA.BvR%]@7*L9(69) >cӣYn52:ХbDQrd!PKSF "PyMca/SpecFileDataInfo/__init__.pyWKS8Wpcjkv[5@-!! ڢ$*#˄d+9q/jK6g//TM9+PdkIRy1s[t7N`9Ó(׿=VUJmxiBat5N<||鞷Zia^sD?:;+^;5|Gb*fj5&X 3Bho|7ռ,y: éTyΊ2P%TTUyq ҚKsfre8R2axHHuD;H[^E͍YLm/XҪ1p %q{80 %͓(<,hxz enWRi>fZ| utf#yE:FmB;4MH^䔭~=.-]@L:h&Vk4UnDD^Q8K ^k5jqs'ROo*MS&ynf/ڽBl?GiIHΣW~Evw-4]J)xAYYddL ϙoB|6%GkxAF3&l{^Ӟt$ۈt fا.qʚ,]Gx^3S.֢̆3dRP_*oDM**y/C wJ[/zNtOk {<8p zgb-rr]wW^8<\;zC}hӍAI~cQr_UrJNJG"6? ğ{~{pd;2y 5eclyCޜӳPS2ZF=fh@ڍF '-@k\#Okx`ӽpQ[Ş8Z蝂YFk3x,mvWb2Xdwi1]ѱr&"h qdrH <9z}u9e׵=Å酆%Vߓ=C8` 5"&EY٨K˫Aךқ[4M0(ݚ "PBdBlJ,IPoy@Ch/~ k~4UC&\Na 73 dO1ۼ RJ7ɩ{D_#wKL ӷRjXh ۦm1Xƿȕ [n/eJ U a$j7WUb6chfD6;)EY9-o ܘmLfuU)~%$v"4XtpLŝbIp@ 2 2R4̙Y@ZВ9߉Hm.s/]m{+s"^φĈ!/-k^8)B=tHvSuoUT{xSxYԎO'Iwe%k ?8)=U"ضu5WGUce._3Xܫqhl1췥WaO,.]E[I8MdQʵk!أo} •eAka~ ם?Pe|Y!r`Mgb|'/6vM5bqP i_6Of̤m/V~*DgD7Z`eBNp*,Jx|,c|w,,~r PLn#m s&ߌf% ˱@5Ǚ3cf4;_p &bMS<d,?ʃb7W?hE6ŚW)@E {7zx`m8>c8PKSF#j9f Z PyMca/ClassMcaTheory/__init__.pymj0yt-S+Ž xF($6TI·Q;m.N:Li7IsJF-\ɬPukkPV9Jv3`0朵qpH/=q@I.EB;͂ڈ[B݂@#g@Lr'Anβ i49Қ,CgWi e\efOZn䥹qD(hDHR4IG~t>GUfic}k WzWa]a-7Z\n4UF*)gi9/$MT< J]G /R 437Pi?k 57%: gâP+e/^lGn t;҆Ӛ#_ˠF@-FU{'S?dQoEN0_" PKSF'cPyMca/Scofield1973/__init__.py;O0w o. *NZ !8v{U7ocW"12s|(d8Rf9fL\d) ?"wAbOGrW1<~cu+$`ݫZo7bMO̲bmAeʴ1)8Qtpͮ\]0&@w'>QzPh]y~.%. OǮU[ȑWPKSFmPPyMca/MatrixImage/__init__.pyeMO01~݃{i54 lKVS`5\<;V(X (XO; ڣՅI5v)S!d,!+x肆ןQ~%P!,VK-n%jRk7KRH͸ x,&OKxm-?lëYA̋%R,jmȸkQܠKofDH?9q {HcGn'7y†դPIpM/PKSF!PyMca/HDF5Stack1D/__init__.py}Mk0O zpv|A-&_BRI!B*, AM'HȦזL7j: &?%hg3בIy@cm}:35ʛ̭GLA5Qq9L.eq @ShkAo%\5Au=~=,xȓccRRl췹8JsvWx$i}|xY4U }r_;{PKSF_XoPyMca/PyMcaGLWindow/__init__.py}]K0+rdoVՂӴm>HSFo*WyIr%&$o]k9!XH *V(ZRP BeW0#B F08@-z &6?2տ}VO[ XMNLá7B-oJQg+v<*__SVV*(P6i&cn\ x6@]x(I5vʍm@z]#_ ZxK>PKSFt PyMca/QSource/__init__.pyuVmo8_v*$$'퇶nue@ҝN$88m_q癌jU-jRH+%/FTqQxڋ*&Z_Mnjv+>?ze++ P`Zj'͎g]76]h4}yЀy˟qCWӗx598}洪z Q˔]/z^a҆Bz7iʪyaĪTGS,/!)3.Gȁ,cZnGm[tA}N_ Y9OhT"eOcK(TR?:&Aj%K\f4gJ1+/2vM@TvtV3Z\ӁSMXQC!&wl#1$s6LJ !$ݎ  ;hDVc"LPPg<tәTwL Y$FF|+;^MDfys6-;\ދA4a*$(vR@JX;y=HlI7D& 4)w<)+qI*tJ%ƘDg;'QxbI4ˍ=Bp}3~g8_ v ?p7 ЏAkt'4-ƁzZH WWKn^8F)4p Faw񃾑=&lr[ĖQ\ gK|Yoig~Z;rg=-rxI k"x),iaJ'j0nN ^lh Q-a^20Z?]kO];~`Ay17m.ݣG"K2g S*%W"#^uh0TfPKSFz"|PyMca/EventHandler/__init__.pyu1 0 EwB[k KХ82ƲnJAsBڪL1EX-f[)OG;j8}A?mڄt/Vm,0biw'z<6PKSF# PyMca/FitPeakSelect/__init__.pyUn@HeM#PۤdlUU ae.`ΥR/Qs73ogޠe#EfT0i \R呢[:+ѶM=2Ȁ¾F&_y[ 0ZyfdR=g+Pz~.qiKbYCZAG>yujGf+CZ>Upw@.=Ta(| D_]Yc_3IvӔX②(nBm"Ec 9Kb ?fGs ѧ}Gt٠[I1آ̦ 7zP~Z4">aΰh\7Zës Ԋ/&|G-:&m"^̙gr0ßX7dP/!޹b:Pm[]Z67H GaR&P_%kcEģc/DBfu*q뻁:^Z{.6J ~wCF67PKSFÂH2j$PyMca/ConcentrationsTool/__init__.pyuA 0E9EvmAKj0$x"ƚ1ed|JkZ0{2ɝ:u rmu'K*B4O0#9okؙ7xc'A K.p4P(mnm?LG>e}PKSF!PyMca/StackPluginBase/__init__.py]1 0ݜb` nGI i\+BǙV$2KDhcLs^ fA@C Yr_}fWi;.iGgO M4Xc[e Zdm;bu PKSFZ^=#PyMca/ProfileScanWidget/__init__.pymMO0&,~k]z`F1MS 4@ ށ@gfޙ4JƨjZcVi@(I>v5FT *~S:3;_d, >XNR+`/{r/q׻ar8%D`zbIs4&W۳BB8.-6/|)UYqlR5UaM3,EXz*2Bq"͚XP"^Mتw} xz(aZs$9=w*-{?vX-gD3 PKSF ag"PyMca/XASNormalization/__init__.py}j0{^8nP[1(0x/syRZA 3o{ž,_Sü4l1M8 'Q͠wMAB4ij7C8I`ᶫ"3(\68Wr73~29r/uG'lh.9Mˣ)U9=CUc uPKSF*PyMca/FitConfigGUI/__init__.pyeN0E J("BAꆔ! ,˙qT -:{̨25)cjڀh$Zr"B-]`|Nsm%+h˯ !*݁  ʮsBL7sozqPqmP@TblTpQF20ʤoJSqR/Sm ċ5#]i>C yagEeTLj65 x5_7?'PKeSF W9+PyMca/XRFMC/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\EũE @c ɉzAnzE: r2KlՑc5j=Rs Pf4FBPKeSFWd"PyMca/XRFMC/XRFMCPyMca/__init__.py]o0+|NB.Uʊ&"7q#;ʯIdFxNuͲl\"FcA9܁VIj:d)$kUBܱKiY6iO M$Xwcҋ8ZW 8Z_gx\: kN`<1"+bOMF- ԍ%C_`Z0nPKeSF/~"PyMca/XRFMC/XMSOParser/__init__.pyU1 1E"v^FB Ge2)"''\(Z٘Djkd2S%_ 0#"~jmzΧ1‚AG ,VsO=PŦPKeSFGj#PyMca/XRFMC/XRFMCHelper/__init__.pySn0 +|sl =as ACa0EvZ@Q[ӯ edXOpChn<{uH[+f2Nu,+om9u}Q#]|̣HoׇlSV"EU^CRY[VeU~T嗨^U:PkJ;W1͆<[ 4ص";#/:ҽ˾A22F8;HR1R&ߞ, wS=C ,5=$-kcά Hsc0ɧ;m  8.;p{4Z4_t'E"73ғRiғw rsvog̍_bC1؄z$gژͲPKSF~}PyMca/Lanczos/__init__.pym=o0a\!C*Xq"Y3*\ܖ[s#Sc"1C"H(VAdNf.&SJtEHAY>'0' 0NN<6<48x:DORGb<_؃s^*˗ϧ &h69mn>_Ϛ-M凛vQq8…,[eꖟxunbosX=hYǯn1IXDev"*JxY^v]xN"E&_fۺ}tYYg~据l˻JJ nnd/zmI,H~?֫&^bw&!(fU{PseqڍlkUg]Ί"˿FEdGUkopCZ8n~2{jKh>.WeydI{߹,-o6NԮsdP^%%v sѪ-_=˭u܇ جM^I.&jE˓uTqԛG "^$e" "^IEğE?/q.+֤{5^e^<$2yDYj3n"Y2zʪrIeҘrטjz/^%_g,pҟ4=?I/É 92;ؖ rQ `js`T8%0"$ /5.$.IYGDOQVR HwpCkH`{cV0g Kf@T\`8bH:Ђ7;_DifЀ7g ؆0>2a YHWn OjmqB,Hy$9[&MJT-ߒ.R.]'q-.*Gjq,q4J,CIst)J} =Uc)MZTe vSi8AOm42"(#.HHix? eu RLot4m?[90;,"|)nLTGgYYо!"߲.Im]=V@iIxFI"߸u5JZFŻhM筐E ^̿>"ogUy?蒁5cnrtb6n:>X@n?DGqFB >3A<Ք^E4yg .y ?QҹB_1>'g#tG "f%5Q-u5Lg$g>{S &Q:8,ݢ"LAʾ!,c#hqrIvՓo:u4&lc66a:ڳ7U>]Jtڠc%}z_w?G:8p2=^egY,ܾp:8&pҘ`P~mFrh[ 8m9p ma0|_GɆ.4:2ЦA-$}O.'yNy~XVPO5gZ?Ng79wV6 U(@yk?ώ5##19(էfvy]'h']L ̼Wj("e:nSqt϶ނ)ercB& dœ-ޯYVQOziUsrRv?DPO1".I$Ou9m#Ǚ;3FlPl|iQfWӸ\>v5*\)i``$1%INe?40&+CLБ@5as e4ܟoa]4H|v}0iֻҸ;m].&`. { 0LI1 ߠDeI 2G1_|^ s,evI}jҾUH(I0m` 慇}^Îo /q&C [9֣i8QyTV>"]\E'ً 2B`1U61:eة(BieЂϠ;_UcOo=t'AH%*"@ir~H&Y4I\)9+5$%.vfqOe)Gv,/׀{0Q! #Pr K~-`R0w lХÁrõw$ I=hw$وGRDMdhӉ(JgJ*G49f;eG< Z/Ďx sjKC2 ĿyM+EBӤ6hXj@ SY)Q5(Jdv;@r4Fb^~PÑ72 C*rO'>gΧ_n1YqK 'gu.2^GxtRU*{QMN4 \sĐlMцvBh3s,ib}XޜxS:hcǁ2Xţav):|n;,.$KO|r'.!  0B_x Ll ( ةg@/1' ms\MSJ!M^9"S'yQg ^ăG0sN}6sмָAh*hb0֨Y;ۯq̗ԝ,ʳiR&&a0&4 X#5˙"q(_RY8O"H'Qv.N]8`:Jh|q{TI$<&(o(?Ï NJf aGk>ܯ *l0nTz}GaG{=7-p;]X3:Rv,2Y>ƞkYYѣp׶`]Pp# >݋\L69}v\ ,粕﫞 P?}K۞sP t&ݝ;WZ3.י"zeʌG/bJ"Ėy*$5r+[օΝ)'GM8MKK:0<Мq:%[<ǜ,HZ0hl4dq48C>SHЗZHQ؀j @BB! W$ː9t 5v^5:% 5'^CB`àRUon/B,ȉ: ^e6F<"8H_li0W=5y֝t2wu6oÎoF6fUid12h3=6Ǹ8+sKp龆-IĞHnqS?j(퀌n~=-ꇷi"ᵡ"Oԁ;4v]q҉؝*v!TfHc纁=pZhz &)ߒ^_D=Bq,pBQX+Gk`4liamWðif*!ܚvI[A0lɂf(_8Yq­Bƕqk"1*em-=f A=6p٨@11l/Tpa d9J#eMpmIv|F0Q&6@mʓȈG.+#dېn(i@m^@% ' YŚoXI.@эfo]?`ξţKBnDيABg䩲jO sbȆemɖq*v^t#l`֒wѰ7 dQ'vkۅT"OߨCƥ; 5YpvgR^6*45aF%)=vfo5VPu6!?ʖG) ~gq/G%mEBo KvP~i5Dlzo `TDg|:bf̾”Sqi ]w~6z3H3_;EiN6@[;Af!m GZNt8}ۿQv0n!zJ=a nW{7_F ̼EMᬮ'=m`P&$i m)#lUR&t6Cjaբ(vn}Avz!YkQa}"Ww騅sĸ>agy%j~Qr-IN"\?Ծ͹N*S$毥z:$T84KBl'6 h_Ji Q|įP ɡ}=:n#+(Zø6<#^2 %gI$7yā7fn$}E5=ą.&vy0دwHh%t/cICMF N8@a-GzjZAK \cWver\'#Pcpk5COXw{fyt%bc6Ӥ\FtM̞Ov[XrX9oFn`y6;4jcC=ZXE-4Iht,4iCbY =\1ré&OB!;DZb}OL-2Vz%mp*'|hL_0oݩԔ3j2P'>7{jn5/sd=ўVO*HP,xLGe/ChbSC3pjmH氿W :JUUЮAQ%lWkFS+F4 |: G,HpxYXz8tWMqخ}wM-qY>= Z?KOQH'֭AY'%^=;` ;Csa;ȓ$M}‘hnִC%JÊ2w'%/nkEyo6m4%us/2vߥsaϋWW}^ [k-7jV;im:=aSXXzQ ;6*ɵnrZ᠉ز/FOa{0ͤ17 9zޣ ƒ()NePlwyŋS qtwWJU&gjj!bdz``iU@疘3dqA-rsP>7&=KP`aԗ̡acEY0F5/K_+ wNc'0p"0k4i rhEKc]8c=8W (.A{݃Od,'iŵఁl4ESfb.]ԍ N]s˙i:򇁋Ñj\E-.-f>Xޖ|Bg`먿6U`É.@5>9t_ ؁^āo( ɉl=3*m0lW8 K+ ̞rѠtN6&.UL'gh)9<{dX2?,{Kq gymlݟ [8ge8/m"A뺲 I4ra7bFa ui6kTH"@pBvNU܃2S=uMTp6GMIiMLzzb:* 0suK`l-xvp8݈79mf?s7 Ð-˜ Xr">v5HËǪ Qi\=#FB-fhc4lt:caL&N.9~@sRV9PnҭDޭ=g<20,sSVtނ Fi ~m<8#'xa*zޣV>63н4}]f"z*Nw3P/%=H.UfoUK)ikۀO @Ce}gbч"Z&/[hџR|UZNE~k(59Qr&%5JO=#&zqX[P0c|>ۧ}l>ۧ}$s&y/ԼiEO *>).)h;~b 60^K6*\g( d!ձAI0 / p,/n!lӨĊ6&*M"5LY5MHJk^%,_|z.}{ H (OQa C}` [E@4Z* {(SiJc$T4JS-o讨NwQYi[i||{sϾk]RW~$j_GYmu;C99-4,:q60ob@e Td_$M&8is]䵓̝vP B6}i *LdAY{1駛%C.5Sg(*; ŔźFC6܈=E1^dS/#wл$6s%Oj5gq˲.yR^.|܁B|PVv븰n~H2,'[,Ɂ*' t5bTqۣI{FX0!I?`pb7˛x[AU,n>Z.m+_=`ڱ_Φm0{fg\}Z('X e(k5hg(M<" pa ʥ> C2 $UX•z9y3e㫊N倥{CEGqZO&tGm~i=HM/gȯ(ǥ”&z Ciqoѫr/grRʧ 9&Tpi3ɾ޴! '(TJPYVNE9^.}e*}"U1-YLZ/R6mW&0JMN@a5^ԕTKًdD}"e' ݎٍ>4ܸO9%E*吼b9}дhi0. `1_k` !0H  #K$^zx{=^zߓx{5ޫ^jWx{5֫^*W Ux{^*QỴ {^:Nu{E?Ju#AI^ɃLayz2Ӈx\la4$):N(ՏBYgП,sm2uI?52C' 4iY?5P:|Z.̣iz3K2^fBB=,OyZfgC)OKQk2!K:p`sla_Aѩg iY?5T̐[.LU(}&BS*Ú't9OC6t|[K]c=%qWt n;YLJ`N` mp,sbl(B$y~ɻ!»!»!»!!»!ލy|tu %Ɋ~He%MP%H\ڷE( Q(gfl]ƏN|jYTeƉ9)&S XҖ؍8cAAy*`j =2~Qj]IJYĤ;ƪ$ubJƝ|={?ѹDvbzIaz HgJ5)Eܼ1{H0RRI|d0Ov*$S;YmI\&֦eٻpLq0@ @{+Yd;L&#E3>~ffX3y%c qSSX-fXueN$*aR`9Lf04L=KD Y|ӟ3E{Tk(<§Cor-q.[rF\F,Sk܄;m̙` k.4 \iM͸-izA\XB$⤶e^ $ N<V t,Hgd9+_T Ltjivn~?W}*86n3>k=M).e!<{J /%INP0Q`ffT?; 26y̾R!qreRi~ytw6o&t}Jٺdfdف MFHɣ=u?s*o2qy/o%/45.Q2%-^^^^}/^TU8zqjNyx jT񖈷D%-oxK["񖈷Dލ%yvşm;̶4qWK\,xC [_ArHI]|<]*?rx<' &I:{FMDugU u;**wF{-1K5! EX  m*WMo1㓳+]h[+I%)aUCɏ*H"mY\XjC/6ē׷,[!+<ƃ'!XYa!186V @4.@ȶ[>% ]oij p2&۞~~I_YdrɓtttR -]"a&" ːE5K$@YBnn'^Pdƫy7n(NGUc)@y;_ 4l4^|ͪZ85u{xg+G|M5M2SqK:z"ڏH葶oJGcBm%tssTΐ ߡ6uG_=fTgV | )/YJX S|G8eif;FP ȣbg ਎` j'OvEd-ʢUT$2q (gʛ bS?,DcdEY-#׬D$[vUO^,_ wQkVyU#]iuEFy_g,lS1>{Vj3H/Σ "ȕ+v`i<˂Cl3;"Z&L"N7p¾$qAe 9lw#m0&e-;U~?$t҃~w*v`tƀ;Ge"S+)e&rF[ s09?`̟s09"_e.$cJ04hv`Жk[mĞzvDZqj8Kw}5/4ANnVoq5Hr#_aUnu|D' fECdm8ҫVWS ?7# b@yG$*?Ҿ7'Nn^.Ξ]dC.5Н35ɷX'鞯Z.oҰ'e㆑ӛ BwE*C t?i-@Qh7ތs1+ۿR07 )Nr`y{˦r.om#( rH쓺 9T8O@1-Ҁ_DN*44yTd+MA")mDS5 POBqh=-D ,Y˔K,m$Aw`|X``FG{ (6{UEj'_7J~5d\Ǡ.,7ౢNԨhLn42F ps= N[yWM! 4;5,A7~1 },f.n^2t-De͖8U!KCfe8uk4:`i׵!z*8l"Y4TnM69ނޘdwyNjqʳWخ9C]'u$%Xj›U/_v~3hG'@(BY$qoĀPlF Oj^xaㅍ6^xaDŽ dL^xㅎ:^xOZ7\ٯd咗K^.yKt҉ /p ٌ~c^g3gf[ƣ$WU{yNuzӿK^.uy{]^Q{}^>yx}^< {+^ WB WBӔ{+^ WBzx+^ 7{}^>y{}Tm5z{k^F5z{]j4^ WBz{+^ WߝBli\?h hQ~m6Gٷ"^x!ⅈ"^1!M/ERK/E)Sç$K1vXgBONb=O1d{ QDn2.!Ux4lƼ Y 9z.8ʪ$J/H{GC>| UPr!JO e;uuqdfWJsd&a@+Sg\Εp^DK { &w)Hp,ndA"NVk Ӽ(3n+}oM5YRgHSӈ()yGbgǸ8, (@͎ t)S}5ĝ@-1Ys-2VRY+6Z$'KN5<,8 0sKle R$؉5xΌô"0zi !𗺎 _@3l~܄=.)PUW)_5W U_5j {ޫ^*W U{ޫG/g2/طM^oxs79oxs=|ߣC"4&D8Z:XZ$&oő:[hiͲ t9-E?4[0]FnХ ; |$[Gܐ$lވF7box#1ވF7bލ=`̘*_E[H\xɬg!(M(KYRrOoc?8 ^՗f!W'h53+hRخ4ޯ4u.e/ [&Xu2jv,B`,Bւh LM 1@ *l:\ނ}z0)Gwt˩A~QL+?Jit> IEvoț>şV2]̖IeVm6eF(46%,,Hȡt30@>)I"~[̇Y o8+ =Q$C7yupVO*Rsd xw.^2)Raq!W`ˤ\  :[; =M4_uZ-C7]>5:ZݾFEWue:idl}>}̏W;آ////z7/˴&5&/ū^jWZ/ Gq|̈́Y["Ȫ/x$Uya`72>#[*F[u47؏4 hdA/ljOW\a4FGmPFx #'SS&uy]U82j3}IRaw6IJP2^7^m|&tښ]hm=՛3{GF޶-7&Io1##o <=g|܁3~r $zF)9ӥJ Uɷ;рNj}(xS"}lYלȆ|E S~qz$ oyx B"~"*[$* DUehV`^/zfyNc# S7̤DЀoXLSdiպ.lB)Ҷ=?7&{,~FFjpfo1L%ͨm- 'EF?֥zD 64l4j%mAĭT^6B~*?=lp0`߱jhƸ1n#u>B]iS,xm`BZ|_K L EMy ?NNBB}/&MFYrҹ_e{wenc #CŘ{/??|UnOu^Edm"f&S5 >G"d<)P\ XE${$N-Gcdt;^/iKSS0xGœHY<9A`9\YS*ͱQJ!~U#BJفH3Doq%D?~=\ZG]Pq(S1Y-分!2du}~NLR(6a ODBJj<.?ox\8i/(`tPiq\l x]3q3Ќ<)ha<)#V|#i'ZKXu -^/L!t:8NNUDgu |oi> Ch8R.(c\BTq4ty\Y"QJTG,NWlSR3<*q@BѼzuޏ@wH#)h,_N,""gahMXᓨd'lg [>`ETOt-|doA⿡oϬQ^lypB:׆-=(bAV}ia"/tڰtqD74txo`$J-PW%$4?ۆGLq@S /PȔOr"{i[90z*m1S?aHl,vIM$ eXTVm}< &MsTT Zӱi$ 9b/ TWO`*|Y0f锕>@ǕUIk4D&z7I Rv锣}(e⢟|hOy<0E ldv:?KgQMѸ>gGp3?]`ӈ' Hxa UP@901)֩":hRsXIP焂ih%(p#?D:\ʖ,v)N:Q sL-fC?RhJ8٠xVN9;i:#)=+Ă~ \}SoM+@Pmj9*Sՠp{PW xJAX?Ouj_)H"J4Q]}D,0ڋ8*x8w6EcAA?CfL|6P]GъP^}) E_ԙ `.L-2e/#f@:ە3EZJ$JFW $SyB л`k$ǂb3Y\%lg O 'CT G^I.\EĦ+i]JP}7иNoϿ |WD<%T=%#ԚI0ij?0g$>XS_2aD]of(DU1QDʠp8{՜ )L􏑔_8?N*e6(@&ǻmoRSx ߪ@Je&݌CeN~}F ꔿQ,6GbhEρ`Fנrs-[!\1B#}[0ax͕dAɢ2F"ke$;` E܄ۢI8ja;1z:^ ,3Ô;Ew_'ujc2&aCnUވς4Ī7QQ/fo֣܈7vDjM B(v%FPi rzG__N08RL][i7ɊcHSI' T!qA`> \ JK/Ťq>M.3MM +b?oYbP"Vx&IMR}(@v#GI[oẋ)sJU+q7]M븃c#9}mը|+WF#n$.16l& I{^Ar-QKE,9l$Wj4ljt{b* fI[֣ϐd_GO2A*F\{۫3L_G1 #HNH#.~NLtW4G)˸0n{/,?o1 I`"!3x`r o6;KVMIR9<_Aƅ # tN m2n](PTR<Vn^l: : [,9~M(TE:77c[6 ɓ@t'Q8a_gD  }mqzYcrG_vNVC??.,Nl%UD?$ iͨt Beq[-MbIdHϿ=|6ВI(ɠeuTYOb$v&%d,7t)_!Zrf|=/7+|@r4IX] "$|o^)_5d)!DϺR]祵x#%ߒrA.{@Uݓ3kN,_bJoL@x|8Dhak5uJP Dyh@."n6LvܻV%v_o_"y:|{5l5?1W?_+~eIGoa g;rI2e;.7샖`{Ʉ}.B e٪Ð=%=kTd&4Lٲ) dtd%]5`w]βX3u捘e V,X\+d>GPΈɵv@I&|<߭ [ۘJND8'~NJ9{xc.NSCK]2կ8(0P^:* >`C~ C5TUNg. -ϸzpSf "'⧳On= \$̃x9?`ړ 7{XO?GޓdŁ_|Hlgݚ=9g0O̰''9EЧ'>$–/NV 9uSO}.^DCb4)FAB|ؤwfDM4Qlih&tUQJ'>|Ƈ3_J90ɡIJ1''`hCP*YU˱gefCtΆ"לm*/yԏo0b?QTا}zm^ۧ}zm^k>;ImuHMiE}{}^~^ߍ-8AK\7y&Ly9.YE9ur [[ʗ|Ӷr?8Te4iۋ([i ޞ&x୧hdY7*k7VȁC,z9V)b˪*7H9 i^!rR qK&x+]lrbV+U\UMqOOr[A`21(# W0 ʂܙdtϸ(14r.YQLQ8[oZQ;+qq 3sUb,hTy> aW7Aq@F.#h0t\6Qi3ZC_ F륉>eD:w$y{{{zkv^;1:30Cq]NʈvӨ[ K٦f5*;߯v|έy{}W+yG{ޮqHR3tT@^!26hz4/]c9`0@ߥ` An:599.)KER\ߌ3wʉ4S(|,;M\% ug v2/lZs&;1GٲI0V^5·_د9 o;tCbr>8:Lu{E{պ۷kk6CD/Tax,7]GAX 4|ge87>9NxbJ I JW6@x<=b.'m{P;߅!^W NoJAfuw?_k--MfwtT3xOg~FF[ؽǼ4]2; 1OW }O4;y`/b4`@8xw4KϸVIMb"cȩ/u2pP [(46୰a-1^. sX'@@`=io `̙7I /yOJ΄(A2s>y}ϿMƻ*t:ғ@x2H:x4>MMQ*^0>T+89}eǡnAO㡲㑴n&9sԩXri#ʖ܌S$2zfMf}$,/^I-Ŝ Y$rW,7qe7\E$|֬ѾP<>ǰ_VLH^5aEMX4%45 JϔOY1w󌁒n,r^ET^ wE-^}a 8L:O-@lݚҾDKRg}-Me$kTZ5~$v z80UmE| D%եJW˼5uV:/)(ԟ,dc0T .l/ȳMG[u `gM~"~|ϥ9OAKo)j:/y"u3%fc<Wl"74;T;T?i7;+\ɝ*Ww@1ZLFxBk*2lGUb=Y5wȹ$;/A):'Z?v 9#?pO{Oy&ż]N@>GSi  Jy+c(ô,MJ U}Se/|ux v˅ZQra_01ߒ~ѣ c|;0Y/5uxU-uq`zz0w=]r73}Hn=K;kCmZg39Eiop>:x/e[3 ;U5M~pYctY[9m+|V?ʘN畦3-n+<7҈BL#{-f>ݐ_- =Kdv>dF\Qrdf71_r“O g|v{%lyYݵD~k+D\5[& -;Ea&/R¸R^j?G+sMA^n\ -O*KqIhO,ncVcicϩ3F֝ߦhxdUx{ޫ^*W Ux{ݨDHobsx~(|;H3s rqBIJI_^Njg.Jǜ ̩6ʖiy 7='k4y/ҎxL `*zrz0~BUI2^sv1tUU>\`y̲Hg=<Nm"-m'L=6N0aM>eRoG@EE qy{渑a_Q4ťw{f. 8f5$˶5۞ignd2$@"+;ֵβ" E݁d&?Å_Ǿn_neޜu Ep|ր&p[_Ntk;Sa'N#rY[~%wAn6F 5qd@B|i( rظOt)~q<0QyQr݈t9BTeNְqbattT@]20e`QT+bD,pY%w(܏: O,9>?c0&}/uJ\#6SAC#+0 a >RW7:z Xp 8US ]bU'uuv0xQϪ?;Ux|ӚƂ\8} ǨXiyρ#pp(j'Qh0vIMfv8Nlv8NlWÉpb;0'u2Qo8 -^_:;R/xgZ<<7ClyLR^\6q dɦ` @O96Wwy$Ǣ ?Hʄ!TϦiuBxX v)AИh1_cH,}LaXpt<3.>|6iL<K nH(nlqx졶tSJ $C( ebͳ~^RrM<+X!9# y!N3}c.B_"PsBPA.F)u8ݜI`i%qYGlp,}A좤K4Ѯduvq,ryȈU;S\z H_'%td g5>FjNc 1E 6eL c1 obYBM|^l>Ȑ9Aµ3Mmy= 32҈4S$i2-玃v_f/#Jv|f;_Â]-~L/.>74g>S~655[yA/)nϒy)L(mX_B-ylQ(x\lq=&Yƶz$nX0|̊sDC7y=.+;(X'r*fTgCZ}9SL/^Q88Kg&&A SO/ /ZP2$W)W~8x޶7a>B(29/\< G'AJ2*.ke Lzd`-n_vd 8JtwsvuYqzXT+XϪ|xO޷IGՍC0h$'E^̓P0Jztӑ:FgS/0oX\zfC;҉y: Lx_P: lalw>[C_ǰbL*iG<j-;[y½.ob- Fn!L($yINa)#Rd>)ʐZz*oޤs+VqW2>CDJl.P~u&!X՗oy%Hb~p-S%JL7Ҿ(myse]@T\bbT8SCjdc69th[F {+n]y](CRÑ],rҍ= U2O:6d6=b26G4qniofM~wH2,TW;ORs:ʗudO-']<} ^8@Nw{';8=@ApKQ渏 Vu˃cLF=k D!Nt?l΃͇hш,&\FBϋ~M=,L>1aN>U,۰A>5HIb<:#0ǻh0,ps|?&ߦxbOyeN'E{`wOqж"k)٬ihPv#ݓbS:(GL=bkJP7H/ο9lh+Jz}%a?phǍybeT\V~BTi/ ?ou6z/?),s]ơ) tWwVW~-󚝎{eΑlFR?~%*,|]qnҬּ"x{!ư)mn;r$IxӖ}* a\kxr性"nIAz7qJ&t2y[y<To9?VHU4R' C7K(K AڱR66#$/Ĕ`:3X^2f%-I:S,EfIE1VXMSNaks3l,’N;y N\1qPnr ߀HC8JboQWE<}O ݣNx,$|d[1]17{RS4QPCC[.޳jqyZ1cS>yɭ?Ӵ_~$tU0xs7zc vnyjf!gC XP Ʒ;7yg: `|? G!.+<8*8W$Nc[I\aO!6&f 7Mq߂ Zq+OQ}}q#m@y:쯾]󙿼}}gE pJAvS آ.e:=c"67䧑E]mtbq7n\A-o=f&:XFsZsN2=Qjƿ`ĕn7H&B*xa' Bgzߘ'BNk&M[ ]VR ?RGdG^n+cвH7ۍŘ5;sU nd8pLmpϾpĢL#{ BϷ(Bk}/ Kﲆ#FD0|âbSP85W9-x<-sp2N7EN`#plXB  $Nc1j 4Z` CYEi֪g81"DcvuLfXӱp;Mh63^0ȹ01 jbOo%.93=SxG, P I2Xx6_)J_,fļ0Y4vC?)Dȿ}fh<'ٲۓ@4,tZ@Pn `=u%(۬)Jad*-Z\/}j!6pf_jf_tW}/-ܭT2W8x X#0_w"y^ܣD1eӳ "N ػvt+>BZmF\@Jij@ Wo""n&`nȥ 4TٸFY~yfjwJoC_\DTݞpnI]M^Ab n;;G zFJLM@R}i+ O5&R}:럅X}Ī=P@ߏRb"+t߮oW](v ;P쟏b}krZ~BPB6֯ V= !C% 8MswP$]A[o.p eVȖfzߚ*1?XGjqrԞt? K\Tj`E*_I ofX5Ī"(ۊ1hCH 9+ΰʹ 2@Mƚ~iu]@~?WP :|HHu K_q]huK_q5[>0'W{{5'& ek\dW/n VX<ĺlP KlXb*+lXa !7l r DSeM3a ?`5} _ğ}nxbQ@!|kI}8;Wo|k]cX . d|U]*_ٸ:OIBd?,1D^߳7HzH>!0@Ac{+;TOԐ9W;jS_,ڍg2ɟtdԴ_Z5{KU3U|˪Ib;"ҾtV}1եJ=4śVa O/.w`֭h_zN=ك*1Y\V~i MmrFSNvo߰0n߰wd6l{ (B+̇VAUp,#67EtW`"yY2zzH.lӚJ&̏ǭ#="8c@);fr( rxabSmGU/k}3GKP.9Gf {ۢ-|lG)4)CgnyQO]6'N-Rs̏_m\̀P Xmݮ%{!q2gcOM6~h>gTJ7˼ى&~;4݇;՛],鬏ށb\mox/޷(ދ&E}4Uh&󽥤NwF׎ d{뼥hwO9mO%o뫬+Bh G҃tP#/< :g0r5F!{Q7DaF$^ⅾ>LbvVb[2ڽHv4̨=Xܙ}>L>df%\eeY *Dck!Ci#C{]"<6NUp҉#9娏TJ{P\Dr IoKN'Iu5'3ب--Lm<bCѬG/ݖ":B>Am+-k pIDpe>ٕ99}&(B2p-'A*jC4Hmo b1raiָ>k'|aC#E ML!B _"6Ndnjx& Py6" 4qD*csW=NgYtCս2+!ܲh x"B^,\WP&Pq3)qB0'6| DxP4 boz0zJCPpP=TӺ\ ߯|ynɪA! Ṟ?l%ӬwaI;HA1x2>bm=_vOSEɜ .quY)"6fKO)v+<[)/(=h ]S).w'+$+WPL <8w/sTn[-iQ!k菩K=\\{|D!ƐG<83a<:Nn cxY՗σw6&T`8NU5Hfu;l BִS!FX/s4!gJj@u`;O&0`ZAL0S7YQ:)n_zmQЖqFێ=)kz$r}PTTeI9_>M>W*RN[>{:ArUt'C{9is>o,*;鰹dKEEB`xIŎ]\{0n&9XcvL2s wV-秇I#عrN+n?HEwu;1c;9 3;4MN`=~]=EQ^D4 8%‰@s+jЖZ\kV+vwੀĂ YB-KtY_'̦`yv]!5x+;;:N-q>z\.V"NUQv ohSFx&Y.ܶ8K}Pqq["F)AP-b $N0ĀІDqsKV)xJc%|,S)"e¸E0MN`s󑕞_^Ad"a^ Id [aaa/#X]]4@ + NM[gQPk 8:NJqrtXc-/++_jhfv{ꋃ1a D^t@),hdf{V8YšQtJr g`U8uikGCe6I_. { *0DWNGMcvZHМ U]=6W&>3hOSjsely kFvX2!Q4rn~ㄻ a6#د; cO8JE5$ܧd0U=Onɹr} lHt\+Q>՝͢ۑ9h Z/+]5XéXVM5]Ԗ=%rT6@ cAt?BP z/^݂k̓n-i"gy2%ySֻvVaKB}\aE xB-#WY%%"M@40|̕ދEs Vy /XLϖ_f qa& 9W&-|lfԀ@6b Z0G6 #-2C){c~֫zP ڣeDb ֎6H IFN5+:tړSr?S][rlfx8=Grphm7"AKyx8q-gg_poaJ,` ?#>?,I.wK  hN]Zt;(rnBĖ.=OMMYqVX>,<<ح"{& %M5|tN?#  K*r9EoAqH礳 TM‘|dA\-Ixq8؞l0Lh05M^=vOՠBHYy٫ݚV0۬)P`s?׼λOy^U #|mwXA|A|f!@v)zM)oSN,^ ٿ'sK!2" KlL;l>_k \V#hi( XAr#\|HrM} `m„ղܮrvԿf(9ϪmV0]6. % {_n67N1 {J@4OOy#O, w/S$ yG1Bb9X.1shc@jN7YzE§[".A+p'EAԭúiU>scv},\|JX2:k:Sxҕrs ìLdt?qCN{ӑHٖrKv `i_Wj8NԸ8e6胃>8 )6l_ubm߃  ߃ wrTwES7WM$&|-ePv 8[yݣb@ba4nb\ƕŗX: !RW #"XqyָmIAbsU^r=Po rZoLS]W{mbYmO4H5 A`+zf.j;D! tz#o w_$bRO2fȹusd& rX {t6 V:Z'F dǭ3ЀkF5p{UmCeZv G0/9$S%r8̛C!y j_M;e!h;|1gkc~)&Mߤ(? Ey /PC$ԯ/)Ln{8/gW{يIgQƘ%޸XhG1}郾????ALf乜A?AɪV~v)~M8៯J(o2[sOOyְ@tRԇk_=ȃ[),E))GB:+yygٺh#4/4PX*f٦5T$qMm㹦#5,3%xYk\h`n \0 sPƧɩo iϛZ)r&.w6IPŏt&tZmYvgAoV'mpm3JSgȈwOlwb[8ߖ]8 CUѣKYrl- D_`A@qn1I\ 4_^M0]Dlܲ3t C`~; 75B;Ŀ$@]$| o9^1,){.v9ˁ]`wGpWégn.AJUԃ;աBfRzž".>I6>7ׄW$i@ɥh1gh9%d"CД#R?K~͈Aϒofa?U.SxQ[L7.wo9bD:~&"ႉMyujHij=`ssRf>ȫK/^Qg2?:_umWϺ哿 7=o'nssYWbJIcԲd< ,*\e־_v4P^=LQFʸkv.ANYݓޣ+XNM`' 5"_Ze'Ѝka'Mz_KXv`JH{m]:AE;-^::<.~\^ GKm*8K 9N+2{d]"΄+!DZm/# oD{9힠y38~3wgvEuP:'Y/E; 6k/˥},DŲU[?FV?&}=5.>յGѯ\_CoL=<{3  ¤vDp^)Q=IؓG8w|ct1g7pTAw#H%dCk6!śz1A[ 5dzJ?#sYXo|ڣF|JCU7$;0kc}DHߚX0Dcz㑑<ԧ'FSqg(0r[3ш9TS|WKz77T͛W[a?&,[LAmEDҗ b_})9,, j6 j6wzڏ⍆dAdAdAdA5 ?? ^  R:rm_ڧ?MLM_%J9J9J9JjP)rP)W7/gA6.(ĕFzILu{rUk ?̜Sit){V!XIj\5v@6ca cr-ɵ!k+r=[ߢa˅w@@aX6o_bX4/]VYS>Cpo!ˏ%8C3,$ؗ&R-K5> NyF69&FX}L6HGڕygOtM[ov}J^v;W8G~K lySr1st=4h͇v'6Mz%'f@'3]5"QwK!HvVoG~~p; "zX%0l}uM^N[e'|-4:xVK8ը.?~iIy웾rо /]c = UF, B楷 HHGL6N8[.MWǥ@< >O& VwYU %t,cڐUʐq и^ mu=)h!`rI~],lMgCaot?gp;eȱ_}G:wJH#<{M2bQ7\l\>8-=#]e !Wצ=[e:\dWU Rr;\(-aהp_02L_[;JC<|3qfJ G42N-|I 0S9DVUtR9xs ?4f3g,hd:2enl( P08BHrx2QPZcF`1V!L'1zu2kRv@-3 eƍ߈ s6/ ?&vL.n*ɴL6DcSvy$e.|0c yRv=$,==@.9o9ƅ6$y`UAB?*[ πX+-@32H\ɢ2W<]. 'W W]Ձ@y]fQk0eoQ"D!ISX7U. T_*fpp|>~ѝei@  d:t |p) /`Wt MF8avad L8] |u *L?GBIz*dC׮Qi<5Јkբ1Z4v<9=m= 4%R+d䉇A>xmq\Oum;I&4EF P~y &/kD`?=Nb2iqȄ|#G*yG*XaKzD`oL=l& 33@ZWzcq]?$/GESYYf2~`Kvj .n.%+lX A-(I0|}g=B I?.$ :Ȗ.ˢYn.kI l6KZϪrDŽ{!8xle!9 s^;O$Qdൣ6CoezqSN<A"h[@C*mp4 vY8:#[Q X[ Pkc5=K mvUԇ˒hU-c06XuUR%*0 <=MB䧢UGJL}څ#݄ʼn~ [6$@+D r+# Wܶn&IdP0m<7t3j_ۼkJR~"!nVEd#"*7X|`)rrJ_8~>2Yܖ p s}1i1>iOfPdiE(X|Ig27K%~h74g ڇ8R{ XkWy0NѨ5AXXl+i0}F~zcxLbRLE<cá ?ڄC'h*ptyK)ۮjɅG %|eBxbqVUnՅfM]OSa$UtnTA7 \K$'4T 7 QRYݙ,<[ڡЭN@ߋczSiX0ԺER}7=y= eڞ2y7% 2xRշ(m(DFk"q"@šJϏoOA<2gǁEN2!Xd*<=RZE\W?>GJ5Js"/ĺ9zw--*SK%6? gQ{p3?*Ih=[SӪهB^i½Q/-x7*+g:-1|tY}h~SY@I][~w}䍕eوߗ_g}Y&,ܗ+g~_aӽƛ;owMFG'SG=RpB?u3rF?VRoeu/#_ѭܟɈy n1=εom|RF^J#B~K#oG$biy$@=b 1 G=?c#ž{D{ a?N="yV~—a=R_48|7pԏS,R 뛥|Ƚ`8*N`O5w:64̢0v-QQ5+g`ԢojFMWEN,n.SyJ: }eok72П_:~e~6?프bʂ||U~♞Ξu+bYֱ}Jwx!EmJ8\ٜo[^VS_b>LyT*ͿStϡ-ǸሯrQAwSE/Tep̭x2lӪ ~(n (9;IZF: ^8>>48̝"Xfh~R]zdXիỸ ꉎJScOV\a8wk>t_G.rq%`Ăyc/#p]~7*S  H_I?Qz:E˶ss7ʞVT? Λbe~0!.Ux~_Y᧺T LvvFWD(3^ek(uLwfs7L]ʛ 脥7[ގ8>܋yV!A(4XQv.Jon8D8;R7~ eF߽{y샩/.[* R.{VReҏ霪eo!#g}AE!y!b kJhF\-53ϨMҜ)ҳ*`2FHVyK+~eYo e`蔶$.)GΜdo˪X쳦<=Кֵ)-Ҏ2h󔰞7OuyTBKugmI5N5)譥AU?4yf"ƊZ#s'=e%`Jp->܃[4 9"6۪Md뎥Xj)ȷR%׬E55L4cj-j#km5}f)ک'G;wN[3ݧ:pmR&Kƫ3F2)gDilq:z Ӥu⇜s;-qKI5{59ZA5 !?X/S\X_W#Ybs~䳸{?zmC}?}1-bDz .Gg'g7?f*Ԍ+2$0\/m)t:k 8ϖ@޴mwyVٻJq(E|ڹ2U U< Y@5I7uC9BD SDU5^ 1"ny\ Bɐ~Y銄bG*|v<2rPƸ"v+8F >r0H^@$=NwR֣r:1,zԐd\y}p7[t~ѣ })32wozx5]<`ӛ>kryN M }w'M=䡿dn[5)]^"_WhRW /!% U^!峿Q 84ВxR338ҭXgA=n!vнt{&O=є5ֿcyԞaG+-/ͼn{[P:9I!\0VC* Bvh\1*' 22Ē$C={gfG zvr; @,Z ESܲqpBE|l<( h2~BɣRl0.S2$ \HV7Znʰ&s ǡ._"gCsڀ&+Sdb0|dߜ&5 ЄK<Mk>$-N8fE2ͧb{~vb:\a?b?uۿLA:˕Ip#1 4gċ7ckP1Ľ׭%kPSlq:j)Jq#CabWNϭIbF48(jFvBiᮄ{ZSɴ"rv" w L'E(7,Xآ-6ZXXl=O)d&5S#{?q.>8<8@ :ssx-vhגWAMh֛}ڹ =&\0MpA=?Zs PA2s RQ9=↎MFoU<𽻳{=@L78IMb!UP`V8L5TpޗƕH+ا&+ *$uklC#SP 1 [;WPPH&e:t U0ƩD {9q١(DE!JL2 Cn7dQ(xvw)+rkhwh^d2Lݼ@W#vtP"1A1AhiְFb7ec/D >`g)yaJDGK\>73hC/f 酿s N4!jEO]*PnǦmn ]k-M9-a{!/Lz_<2dиn Weg.aʖUbS YtmRpIو(J<؛L!s8/ꎦ[g5 7*F"Ge,c4N_,$~hb8ܖ4Oܲ얔K%0~uvP'_KG/a  86)BRWaMs-@ o!1n/GGG8ɳPJT |ּ L,$ LJ{qZZ@)@x5+q  R뎆e냑=lᦀ6p -+v#g{I!S@&.nShB*{m= 9IcEaο]%[1r7g3!◗ϙVY5,?gۊ.s׭tMTr0fh4G# 3k_-R]S؇%>oa^[,W(9FG/y_*۵Pf$PKSFzPyMca/NNMAModule/__init__.pyM1 1E9E삈FVX K44I9DIQX|d%.4[O`>)P d$r rJ;Q/t FhxFNV/ڳ\=O˹PKSFfx?<PyMca/Plot1DBase/__init__.pyUj0Dفj{)r !S)B#"kV>8_K!>ΛafڄPRS1hTPx0C5JlUILEQ^ wT2U  Yo7>yU?2({+oz-+F{Y1_0U\Q,\0^c~7l9O>@PKeSFë֠MPyMca/EPDL97/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\\.>EũE @c ɉz.>zU: r2KlՑc5f&g2DP"Hd _ZT `*PKSFA]Li8PyMca/EPDL97/GenerateEADLShellRadiativeRates/__init__.pyS]O0}a&bLɜjl@{ gb"oqɅJy7FrUYWuVFU坪 ˫Z4lb!g}HRA*bKcU,#i ԦY6d[inƁFjorUc}Ey^fJGs]:Z6{lDQ/r#lI& H"ޅ;nS >$o]81.,QcJhgv I^pFSb06w?QudO(A~-ࣶ.ჰ2^a~ PKSF]f&PyMca/EPDL97/EADLSubshells/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ` JO- .M*HqjK)ME$a APKSFѩQC;PyMca/EPDL97/GenerateEADLShellNonradiativeRates/__init__.pyU_k0){Ŋ>Ўt0Bkح~[}sνJ֘ҲӝJ14nPk.*{U-Y@S Y-S-(41C҉=&9s7uʹ6^;sLZ5,?1(x/=bxr䑝.ymyPf'U0ΞUlR3J1_!t`U|U\C/1 PKSF|0=%PyMca/EPDL97/EPDL97Parser/__init__.pyS]o0}W-BMXD4M\Uc#H6Y*`Mׇ>{57!׺ЈzTIʵA9Tp'oU OGZ NGUcjtewڃ8MϮcU Q}V8s{f-}-WYjH_=A \.]cf34ecA|sz(բf!v` ;zG|\5J0leM>RS̒Bh ,P*Jr†.`6 {N@xìИ-DҌ.S_ӊ3I+mm[?a^UDTy]\5=Wnܮí~l}:/o׷KOka^!J%g`s y>zU gSTEރe^w;,߇kl8f( SbjyPKSFA-#PyMca/EPDL97/EADLParser/__init__.pyT]0}WZUk;N&3& Vصo䜓s%/ze #EɅꕂ0Q(™ժ'Og ²| j/@iMs l/햰g)[M}V#UϦbթ:\_qd\M7n PSE ?P&rUajru-a ]LJ/H暛b I.\;r>θT > HMSyRiXnlř)X`&xO^讹cGRu 6X(P1c s3M:^ЏV] y6y2nUEylUvxp6qylmhN>ڃha8{\鯾s8=ŎMyC);]'t9w.^zQ+dI/PKSF M~L4PyMca/EPDL97/GenerateEADLBindingEnergies/__init__.pyO0| UZI BiBTB" RwC TRN7~~3ɲyt9-EBڶŹt D͟_nnWliᐷ.t=k/|ZjyYޙ;HV|1ͩG.{)]QU^aM;(*7󲳯>ȇV6ٝcFg*K,J*/ PTa)BRASC4Ǖ$ոmwm+,{DzL5Hj0,Q!!`XbCBbbXLSA-H%"U!7bR-RrӘZlz80;e-k ٔ~BƜ;. Y)O%IDŽ.H"JÔ&5$x"^4D:D*Dr+Fg^~2΍IbaG }7~ ݤ`F~"DS)e: %g<|aߤe:6Y3_JɌs$\8k?VPKSF=3PyMca/EPDL97/GenerateEADLShellConstants/__init__.pyU͎0~ 2+Ap߇= v$i$,3qY%oO;%ʪa]fpɗ5zOuY3}]ǔQM<. Լ|BOaJSMowL6ռ5[~Ҧ8ǔ*}?xvK)K8MޫpE)ܙ":KR107X ]*I#?+~lq faVVċk2%Vi,pn|{T׷Z])̥og|iI[vۇ20F~TP%t G 2_aŬZ #$-JA@ i=zt;pJk%(g`BPKSF56G>n!PyMca/QSourceSelector/__init__.py}]O0+z7H &b|Ƙ kv!{Ϻ?nP-R(4E^r 9!8/sq|d-xh:z'wǤaą4#ADrfUUm^LF_J`;"G-e%s֚'EfjX~kύg.0)H:{ѺjXMEW|bh2 D"G6@II@KktPWGUK؊2m RS)htGܭ/yol[ceͺgyY&ehvQTu-hI60FTΉ >} T4aGI]X%x̢$~->8@kx|D0_ {<"l]{eԚʬJ=+Hڳ=Sg4#TIpd%a'!u@[>&$"q - 0/>WD =7ROsēIa6݅p;5$1uI?NFn閠Db?@wqOҩő@T @6xt0uK0,RtM5>KRs]m$48;Itg,HtgR}pqTBIZ@̃= R6΍Pya'{8M!PM{>.|:S%)\&h)i " %yst^vC /{gН_<>ojρ沅UW,x;IJ?xq_R&AtRKdN*l'@BMow@\ڦ;Yʷ2 k*Jk(24%wjc^Aqhlboae5'.=wN@I,v<= ~3PKSFoχ'PyMca/PyMcaBatchBuildOutput/__init__.pyM? 0GPsEjإS)AGri.w'ȘJ't^JpրȖ lHE~+:ηSp(y;|V`vآe"6sޯ B\n'6J5\2 ]RPKSFe$PyMca/FFTAlignmentWindow/__init__.py]O0+z$ƀߚp 44,MWF[_Wyzdhxܰ8\f8PE +t6!ƟETW^>z[[QRrdl2XpF[U.XЩmm {0R̊rl v[5.BTkd8#t6$Nð[AsgYER p3p_ls9 ET @R1b..Tm>LLmZy;rĸ^Qc6\4< jL<@@ }^W#=MbjDBIQ U 15wY5qXdc3I\H)pqJ^XD0lkj@[RݜM&n?? yujͫì)`7p ;eSFjf~ÿlʼ3?uNN)CuZdj Ԅ+_< 5/43 q뙩5PKSF{%"PyMca/FastXRFLinearFit/__init__.pyuj0E @)]IRg@i("ҡ֣xn@ݝ;G -tE-|D"8)Z֫[Ah`lʔJ=_j,QWo=izYBguǾVltV(7pفx&$kmVtl:w >5< ov)q }TNVesSĘyel롺zftPKSF#oc&PyMca/StackSimpleFitWindow/__init__.pyN0ۖ.tD34ƐZhV(ŅPoMSΉLqƅ) C\*s3nF m*t >"2<J] (}J9Pk3A Avb$%\a ۬ eĨBPAiHex@ )0}] ZA]eHR׬ P)SFwV0Xh Fnd5d/g9eii 15q̿PKSF+m* PyMca/XiaEdf/__init__.pyAK@+PHAD**AAdn&4ٍbJ"^{o<):RiZ Zo,1]Axb^VF(8K2M+]<ߞ bLm/ fBghaKQ1;~RCA7 ғ7CvM{עeV+{zF)Z@2q|z k*u5>0 e1ͽwoKOPjX>PKSF%fPyMca/SpecFileStack/__init__.py}]k0ϯȝFiUE-m7Fp!2W?BEM7y7KDH֨F0BP^Z(E^)M+򺂬o54xdT !!{cu"jjL bΨqeksBRLEeX)L̽C-SvԠj9tlta-nQ"b^ N^<=;q@TJ4;i uN+V>9ZѰnpgl': PKSFN%PyMca/SubprocessLogWidget/__init__.pye]O ܵKbd7nXS4%-ӏ-<}mhd*mj2A!0A" d,.|9o!:}Q>^B$Fu ?!"9V 0x Zmn]&w`Ť{.&ǣKN(PdH*ě @n'*L̜e^CJf*?c/ PKSF0:a PyMca/QSpsDataSource/__init__.py}A 0S6TAt΂2Fl}O ?j["D=TB89tJwP[eA$80#+G'"٘2ftEz!KW1xǏr?˜_^ hgV\㜟3BцbQܲx<eSZKwI0{c7PKSFf%3$PyMca/CoherentScattering/__init__.py?o0wlRKPU:0TS RUE16H{t`"N0)ӂèubPm ,}@ e(Jh0gQz\V<ۨhqgsSBB&T'SBj A''IhN T/q6MW(-%ĄHeRwLPKSFVψPyMca/HtmlIndex/__init__.pyU 0{K +X.H0Ɇd M+fH&%B3\|&#G1刴ZǪ .W_:ຌ?ݰ(>_0a!]CbnPKSF_GPyMca/ElementsInfo/__init__.pyUMo@WTB(NJ=ǐH4!dmM~ݵڻQ"$$Tp̼y㏵ϲuk'R$\sMM%d1ϋ(ffԿ6e^s %J|u/:L}.u2 UEbL}"')RwgZk+m"., -$62CK=^ۍ5/ @hB-# ҂MpKo-@+M1ٔsq|Kj *1MK^Q+5~ ELЁcN8>a,l25rsQ"e@;czmzfK̪DJfg-WaGS\ʪޑޚhrgxXY_ ?Rh"$C/vBw M^=/gϔ<1T#~~dC``iD57m?f C;L$ gH|3PKSF`?`$PyMca/RGBImageCalculator/__init__.pymIO0HjI=AM6!M:P=%)$z߼y32uhL(rXLXX&ZT K.u03E7w83v>NPOqB_XPۚxiF!s^*.-gKM[یVjߴΏ6Ch3𬽵,5;+pl܅@'Rx:Yvu`v.-5 w?zzC([j~gSE;p",F1'VNvrG~? 㱦*D,Fl-3C%?R^\ԣn@^VRWPWT%[9 fi3( #W7h>+1b~MPKSF͈ !PyMca/MaskImageWidget/__init__.pyuU]o8}ϯ]iBBiP(V ,;k;E̯Ā Ks}|?d#xJMJӴE *a X)™rOBc>q;Z޵ig4?Ghi+JoB 8"GEHF;7p.Pd\[ߪS %_7F-jLp.+K[dp!0E@Ů6̵m<)p!diZkg ϷBҲyi-+  =/ųԟQ<߁e$S6W9DH>l >PK@9XG<:PaG _TB@5hl>y<[fg?Ƌ )t B^lm[%t/lMG9U򷿽V~BеJ [e%[)2.6|P ,3 FϘlwlsׇ̫滣$Vo4Y%ӵ`pqN=gM>=m6լϘ3Œ]dXhh &7Э (l`xrO]\+POfk[:}RRH=DŽN"!k3sl(e4G Jeu hdfޯa״L.XѠT3W;OjQ'_z0ZTdQE M&ijTgۙwE3gz 'D:D z%p;]70 l{{'a煂Q %睒_Hg L}J嚗4A OuUHI$W44xJ^XF51\DpMг޿ɞԥԊPKSF~\{PyMca/FastEdf/__init__.py5A "B7j$Fmg& g@]"\Y?s3GR 0 ǧ6;]k@",v7u!_PKSF$+PyMca/McaSimpleFit/__init__.py}N0D J("BAꆖG)- BȲ'qT{**6gobt Ij[NEťU PҾ*4ˇ$PTrg9j2s}8 8G%_gB !]5f ) 7&BLҪ^;a60F0t;τ W=FXoo(SkJ*0/m򢗥xuyPz"l?lYs-ith*싯fፈ?dPKSFzK~MPyMca/FitParamForm/__init__.pyՒn@<;|mHY8n#C⴪*4=0Υ= `lyU7ύsXK$Ym$MH Tp6*t$ {L`tkK}pLΔ58̲JS>l#|*4h meKjt^V7NcqRNrLGD|27wk.2I*l 1~FFYǍIvF,BoQ~etRQM*LA[,4dqQ-{~c&mad9눩51\ Uւh?( 21Z5Y젂!\ts38\郔4/R"+ ?Ef`Tc!̌8m{QxXb{ ;Ys!fa|-ڐ2զMa_PKSFtePyMca/SGModule/__init__.pyu=0 =`T1CF+Qp*ӓo޳d[8j[.f.sqI&IO+2_.mQˠ d>}yWA2=3Tc@ ep:PKSF;ɼ PyMca/StackSimpleFit/__init__.pymM @+BDCeE)N˲i,쎁/,lfM8jm9See,*jhȺVid/Z$⓲(s߻5\}[U(g3EO# Ial^u|Ԭ3CbtsuY5cLbL$::g26α~W XE)PKSFĘ PyMca/McaAdvancedFit/__init__.pyMo6% Ax{%;NHQHc0ERMYJbky~Hk) ?M׵%ORH嗒r*[W!]kHx^HU-2lAȽ Q!Mϖ{\t-g?h>zvW~D6 N|P:.tUMp) Mvix AԌ%Ĵ.bstK' 6 s =1%]隂u-]INu>>K ^l/QDL(Fb p?lGw&n%)xpu3G00tz`GqTJAU捝1v1d@"VILquni^XAx^ ^.>GB*+WDwc)tL܍y]t[֊6U*ZtdDtK[$C2&a|>=g㋏[r VWVFy.^&85ϭNyц Rp/fx// f˼T}aIc!MttUǦMXnP@0aFZnz`tȸ`FNhZ`Ͷ>ZL%Xj|h%H&V{y;Mk3)~E^skn{-YoEq,q_+|yn PNR|_]s) [nAXz?s`@*|OW+3PV~šLپ9́u6HB!?>mnvR^bl%/.'~I jl%U/k3p$=oCG[h.^Qb8.vcMԇv.(/PKSF$ PyMca/spslut/__init__.pym= 0u!QJBPJ E3^Zoz޻4}6FDG l]ZZWo(+u؍n2TW|n 9d\0jČq5`dKs3s2J%i ȰpGcf>PKSFi|Nk PyMca/QPeriodicTable/__init__.pyIs#9 |ׯmfo]ԩ-Eefw]d!`ǒ`(3L eVU; c{uU7yQ6EUUg{Tk/%ԬMV]$e? ˂KvOwGW>ܝ__X\/Nov߁;5P >|9oN/>@'woڍ?\\4 w~!EH)2Y_4icVMLcj @ZO @^,&܁ɪѷ'SMbD,U\,=)i/lY$y/򴍽596uuϻʋs7"]C,/7yYudJ7Oq4ʇiѓY< כ”I,HylUR/y4M7;ț4N[\̟⥹hbn̤ݨ&a]Uyօm(k\dIi\F}Z')n??0U.\Ű3;i%iws^[^WmH6] l v sѪ-]=˭u܅LF ؼM^I_eˣhoM^ ,2iRau6;4ilѵ?>gŏ&)v>EqEܚrRݿFK͋$[/8WM~(SPƏ澬* 1iH.Z&)YO$U vcͦ[.XĮ\xiO?X틊v`2MPc:c6>5"+e">py(f@!4B;NMo'{{M]R<  f4W"x*dF:_e .7FHqJS[f\:3B`|y]xy 8fӶęw`W:gyg0M0E_;!JizL;NSCg:&W1ɤ ! 4:i}J04ޔ^#cYy]Mjb9 X 8z2yT,򭎋|CunPݗg+nʗ&N\cBf>o,Po /ne' LquZ%W}蒁E6"N,]gB\ A(I@Zc NAuH]Gj4;hl6Nzm{c o, |2O=^g|aK]0$h2TA E8s.לZYj왶ll3,fWUċJx^XEN@*d*Ey!p4uip[gy۝ =#'߀Q[ӮߩA.X!W抙ՓqpdRTVck40;ЃqJ Gqg8~9a'q Cd)>E/JA`2Nfy^flG2IN`!_6i91vr@ch½w3~Q@?ɇ"<% y؁;vS4Stx@vKꓸf aR=4:iwXb=X凒:tK'tz\:p ư'q:8,ݢ"LAʾ!,?: *3hqrIvՓo:u4&lc6aSoF.GSwAJtntx/&pZ23^eWy,G0u4qL-*?14(#Xrh[ 8m9p m `eFa]~&k~$B6Kl .:a+&bYQC=՜j"ήr>({ %Bm XATM)P0-@U~k&G(Ga?@>5Eۼ~ɓC&Wu}f^]}+uG2Ml68@`q `YA(yq {k?US^Z"\kݏ-1/L)M"y}iC9 PA-OIEݚ] F\BoM(u}DjT83)i``$"8#INe?0&+CLб@5~s eOoa]4MH|w}8mֻSSU5~gz$Bn4)@7Sbiyl4/ Ha/DZOїZ]9i;g#9fH8m"~uab!wN f:Y9ϡ'|,kS\wOIU7|H@Jy3 T+%2# }g}(ػ:" ބ!|CƔGvV#v:dyoƣx˦d(ib;GNRFTy3Yg-md3.BHgާ_2OA-oNYimKiQ]V9[ܶE5҇:`&qyn 6!V` 2f,Y@r)Bci9I:XW-ƑawDx/ ;'Na<ֹy' H?ғ6:_ƿr9ʒDwM^R`&Q5l0iTz?kϣY7mߜ;waHq{zvIF;FvÙk _ĖKyJ•7Pv/ys Gsɕr%{ _lIO[*]Ĝg$_{D7'ݟv?΅_v&l+Sft>z{%UB S$[_hBŴ.tL!=q< tdmkމՁ=<#|$[yɊPWx/)T@XTg4K,~*Ɠ%^, ?[q wpl޴(o((1Uyva:o8xk6iȇaGC?[+]i𔂍<AY'\T)#n 2>]Ay sRzZF_/&^уDet'q>8&G;3.8:wFZQ /q\wք\$Sr/Nl^kvfC5pt  uٮcN46ҩrx5z}t>S/u~ {GaC5j@"+dD6 QO5^ξŎ)Ss!FNib8M 41&pNib8M|/V8T>i5ْ*zG0|*VA U` X{*VA ލU'zGg߄+g4Qs`G6Z+W_~`6&J~K(|ϟz,)!K YRB%0' tiv #9js%?1rḤ)4G"d0ֳQJ!h,s!H? g}ۓ{ ӆRU*X<'~_o1-_nD 9U"흆7;gG>F;3йS&ob$CL jԾ;_;w˸A92|g"ħ8_\"_kw~3w>&N3鿩'KI6|JYaWLNS-In?3jsZ~x0!?4^ٝs\54Gܨ"ؓS,q3|ւm9icpQm0ү'}&M$&{ 4 UtUdgG~: +:vmy40Mj ̝ϊ"8v;L]3Kpv|Y\84nknKwzdZc2cHs/O{HB-dNrL2 \dEKԑ hKA }է"|C*Iؒq4nWl]~DO1rS~IAxgܣ}N>xYABei>x7CaOtN:f]H{`҅%w`BqxRToGqV_92" ?¯ɻI[hkPTUIJ,8l򅣧:{VyWhna{!plӁ8M6l N6w3Zs 8lTukXW*wFZrJ#eMpb[y b0 mviN"#<x%ܶp+24hKuT໽"Λ|dXmZF ;]P<$=Yթ>tʂGYQ EmȆHkf GcOl#2F~ T`܏>8k||"y*89R}Yy$"BT ZI-6D."{vUx,a ' b95$;Z8G}ñ`nܖ<6sozxA;:WXF>WhY$2S4@&$4o2wI ޟDrٶwi7()Y ّoFJML(n.D-] akAW)1/tf#A~68,Yd7j¸E-Ԯ2xzxЪ~{׮ D:.QC>KSm1*_"WYG-۽2oThj2 O~d*2;8j㙫xSuFf6 ~-R0[.8螟K=Z۸ F41}74&л3t9̚}SNQǥ61b9 6LB# \n ' 㝨 sސ6s\':.Fߨ[;n=J=ރ:'8o[BAy[]^6)zX'{y㺡LI ,GV%w,5i"@kSEy6hZam^&sV6~pFmEqĕ]:n61uDuŹ^ڸ_\k3/os2Dt׷R8‹jGvZ:ژ͆ gwT)m!.Uj!9mdEi20nnᬍ?Mm6BYdi7K_t2sM`Cnq<VtME/>vx[ԡ&uH'FPo v{wpy܁#=uG]f29\(3|޵u ۧDMla)IU/>X14&./}ڞ~yҭ|p$&,5kc㱢̄|ɋp({>"S /FJ QXYʟ5Z'e ˖~Z "G\3R7U)u ++g d1[Ve:i\>ɥ(WC&A`2g7n1œ;l`Fp"|ي?dcE,{I_PB*:|yxMG;Up$N N`yNҤ纓@dF+UGxHΪ_|(o;dxET}!d߻?S>&i\{HJ+:d羙a2lIQ#Cuen\~e\ c?hWv[ɨ]BM&Op=vrE?l ~=lăi!e:u~ނ}N~K5*>7w>\F1iJ 0)WeL'{9CM}ԕ |s˙iGݚ8r4qsX-ac+O qv Bo8quGǺ>{S x3 z+`F+1y 'mi9~MCa |k}߆ghFz'~qye`KϡcU̧6K3f@'yzQ˲vNln{k2iϟQ l裘L"m$HzYW.)T?*FWX+3o?.-㠍zA$}F8l!;*AࠅS=tFMTp6MIiMlzzb:* 0suK`INmYd p1or{̨o}AP13mƾWnHh0F^1F} i8rѵ&Ù t_`ǮE1F=&GKWe | =%>a~P~1A?;x~l|Pˤ3[jt-<@JqXKūB)` &gw[7$ēW)7:,tڋIyEy ^[oxPЋzM[حDukC;1~=jX$F, ԈQ3kG 9JaB8+?N&71c[l"ymKQ8 ܙCB9L(CI8A#?_hU4|/gP.0`(uI Bϑe㫊N倥CEGuZOh#97="<;v [H#|/ %|V^L|9wH2T>L(5ʔ̽x&HN i`?@R"$J좰rB-7t!(.@Un_{*`zq?5H~r Ӵ'fQW:S-gϒ8ݛHN7N>}==i8+GT!yps3D'*?{;i3va\}c `1_k<*3{ Fҙ"`[P&6ˇ,`࿀ +'sQuNsHKe|<`^ a[?,$i|b:ڗ8o!WMM\=)6̱ƁUuj+ ei r`F 4Iew"!Q3-A׾v?j(UJD7`tko*x}*|]{)չc0BP C!`()ޔ @!(DH +΃=>Az|ǿ'=I'Aj|P5~/AjQMP T>A*^P TwwiAA:}Nt>{A:}ߋN/[Gć ٓy jQR,tP+,I,;N?Yd'\9y~jlk N-@i;C۲~jOu\G"\fdV=ϤH j{Xr;!ސGR1@; e\.[Ή'G}Gg CeH2C~rH 2Q72W41>/|B'dxt @7Y_ ]{,§3pɢߘ;)dE‰pωrU\ y(yQnnnnnx7nEo:V50/+"7MsS($. ["MsT`kMd߿G(336z .L'v:G5$2Ĝ C iiRF! K0Ihs(5'>$%, 랱*)Iǒq+_ytO^0:7ҭ&̂$&@qȹ;O^*1[dϫKGZύ-5,%w0g=yBq3r`R5-|ߺ,{i43>@ٿnH`hUcPr%lg¼d&XRޚG`Ok{*璽&gDi˕k?xO[ھSƜ9FLX=ȧ6tЌO/V4uk!$YI Nj[u@ܠAoI(l⋄pP?>⫸JvrcfJ` S,Mwp;ڕS[Hnhowmq˘Y6OiJq)˨,cRQ}eT.IxI{bS7t5hAA̓f*0',ZI)wܞIAx>/kfBǞ LmwOZ : ZdӥãxTq\d)"G&=E^,+D'ugb4՝VEc2P_iUqk0. Sx)TTK 㓳 ]h[+I%)aUC*I"mY\KSx5^ktyDL,X |A}0Lf}֐~TxK Rag d-oBכAuC Dk' ]E978e1q_WV]#$⬜"y΁|*!EO$,W$WaRh=pWCdx5+GL)xt?M|Pa^]ȡt <=*gȡywmݱ:jEOc95x_w`̗.%]k ,j1 4R#(NA6YB!8C &؂ɣm#Yb|xɁr<˔}QlP¼-hXHgYU<||b%G $EL7&ٲ}fi Rx5]%sꉪVw]$[,a$unkΓ&-ю =g{bbϷ*RmbEۻxMHr-Xzae@sO x\/&8a_SaPC4H+w[3IYǿm{8!]sJŚ1NQY:ML,?$_4& m[}nZ= *) XA5L*UYD24vUE}:delZ&Ae_"_yo`~d ȱKv: uc.?`U3E[_{7i+qRS r#7FAH[ɭRg4#Dl3> tAgMz'jO#@Peja~o59X8 `,sp9X8{/`ZܚE`u]"I&`h,,W-\m[{',8rKk_if LkFª"U!N̊,s9&֫VWc ?11c ]G$*?Ҿ7'^nNô.N]dM.5Ѝ3uoF'閯 ]=̋e=^4 #7gTUY# g*g;3BƬfPg/G]ʬ;S$CYK M\#V>4Pb[T'uR`>SNG#Ŵ i~G[;MUh+h-*֕F Vn&ERڈzkg tơ+TBłd-SzKOG,Q 1߁%M`YY3tnPIem2M̊J~5d\oVGXQ&jD4&w42 ps=,N[yWM% 4;7,a7~1, },v&>dZf-&_!?5p4 Z~c7Q,Z*w&wAoL<}jqʓWخ9C]'u$%8j›U/_~3lG'@(BY$qoĀ>$5mAߟ & l 7)yCɘ B' t B nZ[5ɂ-ȥ \ r)ȥ?*'5N8A8!0[ǂx 1 xc&y]Ǜn9- _L] ? ' x o<ݮ,X4AK,]k\prI$AA$ H"A)H"P0؍'jA:^[S(S6[)Ç0&UFy YQYnvF 3$ 0C2̐ 3$0E5sc9R|.t]>A |..uyA|>}>{A|ߧ>O"(A }PBB=*4A }PB>({A }PߩB-A|>}>A;y>hA}F4>hA=APB>(A ^PBw'MjG!m 6ʏ£h=8 B$ D B$?&D)H"A)ȟ":%?|Kb^:S^|y*9`ɑ+IE&/*QWJvoPc_:͋J4Kx;÷@] %t_NW>22~MZ#&A0Ru37uߥDGHmѹ8yxkaoQhE/:/決oeA.GR5]CQ4`a%4i" v(Nɪ y0 WTfv^}& x[9;~fʗ&bcvf><ʺ0vN^71YcZqD@a4aDe7hQQTp8뛑MICaR:~] )^JƊśxM=D(ްn(e0SKL֜}L4TJ΄I?ɒSMj0aoقvk17vk0 ^gC0#Cn3,@27a'j*Lx?ixUp \5W U^jAj*|P T>A *|P ~Tʋ-}+l \}T @09́`s @0ޓ9p~=:4x LÈJ 5 &"|wF]Qg -YP?.碥6^v ˨=aWxAC|}-1 FL0b`#f/1 F̻1b'܎QˠC')^2+Y v<e 3K}E5ouÁh}@eYcԉZLJfx<ޭ4hWV:ҼLX~z߼̳\&؃\E^>MD:M֨P0&aVf3+[PoW=&Xn95,Ζ)$@裮ܠYQkGzS i%lY&j%iz g )Kqn΋B[j3q‚j8K;C $żߜ[V E1tW8+ gu8b?gK>zw̒IO"Ώx v,='d 4lB^lX8|jT֛ö Gt][h{w_ՕE ٓY{HJ+!?_`+x+x+x+x+xx|>Awj(A ZomOA6g ` T\]}tF]e}GU̍ķ5i&iA˂z԰OW\`4FGmPF c<):ٍ`-]?J6ykNdCJ a!Hk{)9w=o]oyx E"ETUHU9+h (+ %wO?^(w9*jA{\3IcQ2K} b1MTЛ *9XN`F1wܰd9\6mg^Ql^D-IJL %>̚>٨X%s49VO`DP __뇮D=/tl{)4Im4VϒΙyqX7ߕ)Lmc+x^Ʞ֛/|qHx$廏+5 ,X*"dog\e^ٹQUNG< o^!OK9c<^`}3Ҕy R3m.j<{;o\$*ȾuhRXE֒Mj[" Dzj+o[Y($ɫd5Ch <= 3#WI 6һVHxE~a_t*g߼ӺHU= ߉EL:Os`Ưc gi ƒ.5yM.5IҊ ۘ؁Bϕ|UN=}ސROތoF?BV[~-27g\hhg{ɻTFdYs qE]O&#fӗΗnMgG@.+K.A˻.˻ψ ,OoI1Vjp]E?x,8ΔVO\"mR$}GHdJ\2꼊>XCEukOqAN!h"d<Ռ.P\ XE,{$N -Cet;^*w@ s +r?Pf`4bYXwA6<9Q䊙9\YS*AAS:=GLѩrCpfn L'D?~?IBŔiXax)F 95geL˧Ħ?kXD\hfxfG'ѠCO篇X3StO\\J$B;LulYC/Oo/ M1Ϯ17Sdb <2-^GE#W̔0qRnx+̏~P+l7>Sm ~31ӂt} Z']>,3`t!( Me{EUo8  !COur}::Ng5zeu]ɢ6ME2TV[E8h\R |#b)'~EWj.[ . =)7*WrR"R)fdN$0BlO^r>s9g$UGd}`Jr8E`: :I8 4dN%G8MP)R2+.L1N,&OiSWu<Ų"=(D̘T iƴ_$Pq@sJٱar q%]67EUd Ռ\1S$/sO<ϙҊ4C9KYy&t%$]̽"(=zcph.X EPyW7$eۃB!?ԿbV);T -&~MS|ץegKӮ=3q3qH-:3!8f03@uAzOBy1tGά8PH6v02l[c Z|[:i)#Pʕ5[ rd['AdT̜gsTBFU.<0 R+tLx^&p^1S\wm&EB@:crQ?:s?Fz1s%ڷi~T<ے&oy TWܦ.#ٯO;#ӴLv qۏRIt|TrpIG2_>l~<[ 1 a$$o>6 h|Ŝ L h?")^=@LƤ9&q*$>ְ8䛺 ¶Xms@@PiO_5AqAY94M_~'aE!*ܨ 3p's;:obl1Sxags4 SBW9<b4(B[ }Ƿ]U&-τFEY"jq!& T^[j\<_4TJ~5?cݚTMW󺠄|޲F[2^h9djC2/Z*1K0\.ͥ1UŴ?|Ka:(PA,T59hd~sجCVuRb.3fq/sS4RPgć:8WD,z7"F iW'i* x+G7`tCN4ɂCEdXv,@+p9 E40Ԁ_m;vc PH^EؽE^tXq#iWf7T}-P4ARi rzG_5/GRYܘ?U"wfW,U(CT&h OIΫxgkA jiHs_ {>{9'T9S u4iňZLڬs_m30-A^4q+X\M?kվ^,J_ $)~NqҖogGʜcaJMW:n`HNě:E*4Ӽ/I919FDv7 $WoС٠ ZIFriپ+jfEo`=V I:5~ )êbmu}ή O@:9Ʉۧ@>2䄔<2Ĵn}MzHsYºI^ܾ0$1i Hםc a#5kqF TרH U;O,)a͋-_M%w623tϤDz\9;IH6nzQ>͇W~f|຃~kʇXK9\hl$֗͝W M37œQfK;jʾ8B^o!lnyLx 0ysCӖ7Q%WrDd_X_OM^8*Bi yf{).N\.ѦEJ8+j*ɓKT\E! { 6VFXk'fD{‰X|#2LuX5/{̟Wgi^/\?K-R>RgUE,Rv~sAIM5Ke@[>;oaA'x]P-&SٱurHª.T$;2sä1{@Os24T1J/2/tbXRqˌT -M\l\N܁B/ -&ѱuwg܎)f/";0D podw.xꅥ$| l߁P=#8)S;قx]$8msIFxʜMGA@–2úx6ܯHĕBQ4lWW 9u1=#J/;?'١N,Nn%Y"ٌfG`K ,Beq[u--MbIdHϿ=i$ [d~:'1qvT[E_bD?H.;Kb+a(gLA*njr+ڿY.& }ZWoA .4$ׯ&ez٠RuGf?女vR s= *ə5~Q,_b[JoL@xx8Dhak%u)K+P D)b\=̋i6LvܻV%n_oި"yzNk~Pcï 2WF?{_Ao<(M*040)mBo'vSA%oW̼~`ʾ\h'?usrƼ(!=ՀqS@H}w5]qih@%4J9pV_s*`& N4`W<.m~8Ix lx8G# B|fK&񿦜v+ Ʉ$6`M#JH˧&5VKϪQfgQ*m6p )ʊ@Ϲkx%#r8M7NxB ja4MqcONIXi13m6D $`M!oĮ|>a ]n䒶ew]zo-#,^;jȄF}S.Bc2ւǃр=Ifi'z'׸mNi2eSr ґ1tոU|v]o:S`Ay7b%lBZBrq)tAJ8#6&T>vS3~'b*95|#Kh:+ t8t5rM!d_pQd L}IuP|(4 S.5jLNg.)-N/pJcf '⧓On|= \$̃x9?ړ ?YO?G}ߓdŁ_ Mlgݙ=9g0O^''9nEЧ'>䒶•/NnW 9uSO8}.N^TCb4MGEB||#ؤwfDM4Q.L4(@ ӓSO >ÿЙ/SťVd]$s%`pܓs 0rk|Ȯ.ٳ2! wn|DgoCkεBD×>l#o0b7u TK~!wH~!wH C$v:O"A~}}?Ft [rzūܾpWu&_V,ԡCϺ=9-@Ki~9jv2_YY-ﴅ 禪7 xq\/eV́_'Dr$ ޝw4xNUG{wز :51j) z9H7OajxzPʙͰ'/JEz*hV.v|cCUכxD6ͼz_͞8B>`T<KÁEp]$,̞)Fb ŕC?=Jo7jGC6 {NjWO-T=NJJ cٗ} G bfosvX3|0po|bK5s>V,S+@pl}z^%Nx(GN=s Ҿ:"E&U>ĨWC{*@_#oyFc".!\Ѻ9ލR=MwPv]޿U۱7H[a&Ŏ=IFew3F&WC^֊>Gu&Փ\K$ן;E<@4 `4,rpX'@@\dp# ա?Qh]mj4ҋ YnܓCk֙UH- @3[E>=`vpؕD&W񭃸5%hJ7:AmTҼޠ dM_)ZO1 =qc%!'o֤j^{(oq\<%qj(A<>63q6Isc:!ғHx0 ed#Yt`}:*+9)8W@ig`:AM/bc0Rpt{ru8R|8'gʳU OHzA~&AewDCgn r,t6-@lO}H*!JoM71#,~-o|ă҃WnXWu;(ݱk]ߦQ9s/~bF eyW]ؙ/w/T7]n) j|3ڣ_{A-ܚw߬ҼٙXݿIlO_aUUU;Wau,otˊG"6&v T5ZJr_MCʛ`X{#J,J:p9KB`WWz)LҦMZ޷셯ãɬctpX3G?ju ˁƷ_` i'qG=/*6s.@Z['zr'zrp=9\Oדdr1!zw34<۴βW[c, px3_qW|dS   ߱X:ԬlF 2&ym}EmKQ8 J-.g҈BL(Ci^G(f yw ѓ{Kt|>7y|4.l=?OW#+MnVWxuI~!,_nq->/fwȯrmZeo(ҬbO+A/5)^GhŶ):Hi cA.>cTsx<0 ʶf(4?`$&3pb;'Épb;'Év8Nl[ 5㧍SFsά5pdls;?d㸇:%#VH冻Ne1HlB+춸-͕oJxa>cA] E$m=E~20חαu %L07bx:OIڋCBK r.@lR9/ CnsEzw@r, MLbOEl֜V'!D ffS'1c<2ǐ(,}LaXPv:ipbHRp>Z4&X`n>q:[(7P[:Zx)%])P=z21߉YS j)CZ&7X!ԤǤ֑g핼'.uQӣB ;L r1H+و( vPJDZA*_g"8\9=c@2dݢ=aLǷ#?S şt1RsLH (bg)C^f*7U n|k; ?nK7b]7@ VMd)T9&qbar%"5Jw h&C%(VD@*iFGvēh:хɢGGdÊ~;|'Ny37pCc coD`jC̰Hfhb`'s=`ެtq/RRN2bxAn20bhiѢS*/Q ~\-'6t,–$%ImIK؈v d8(pE^2O G3 % "JYvHPٓ:h6(?:iwrg_4{tbwID=$s$=k$}ͺZ& b҅ 2`n*d _oM ?A%Q Rsh=y`qXdvbAM@o_2 ξ}թ|(>lO]Ӻwpzd> <أ76h -Y7bNܙ$o8NT: Pd&޼Uk2҈4)PCz ZMSoUtZ/3햑Mv|f{_Â_-~L/.>7;fӜ8_{$@SdlQ N#W _XS%F;SilUsQZmœhqBmZA#e-I[bH^7ew'"L9{!xs'FQ,knc-&&ĢO e ;(X'r*Άpws Z%f^pLE,Y@MSO/ /ZtP:$+bI)N?zk[0j!|B .ӊbxEIKZ,&0XK~{裨"snv_}QCgW穇EZsB>-y%'uoaGrR<8 M&[7 KNGt:۾ÄSbq -ۻ;H'!ڧt<t^Lt^D]t1t7ǰcL*iG<wjv-{[tyBafEXyQ#{}&ü$0pw cip]eH-Qz:ooyy܊2DEReuG!"r%6N:(:cmiK{^ ڸ_)\T\-/sۣlU67R1i.3>u͆rrq{|qO{ōp"kQ:HJ`8_.r #,oGO r'&aq]s qz,GI=aL Ka6HQ-NU*vumt2N*7L! t|VK(=Er/]dFr_#ZqE#6vm8ѶltՌSId!G8,f}]=t1[OO{,T[-QA+]HdDC3>(,{ܯ#%PEnpoy D+YJ~.Em<"Do1-4~Οۋcq76:/?),s]P˔:;PP)D ?yNǝ2 }}H 6z g|o??87iqk}<½cXєGBT7x 9$FIdߢ o+ܺ9)r[R^Mk\ b]G[,RUԉ#3P͒y,ʒB2lXUv)qn܋PbJIVLgk[X_߼IgKn`F`Ke<=52h"ԊK>B:$J1}f^X97B(!,|vuWiLw\)[z7 r6=iy[TC|ē@3HS.; &b߻=ٕtLb~ *:xԂs^&]<*jhkrͯj8[Xů|ɭ?Ӵ[~&tU0xs7>̖CΆ<RbwFR߾,i$(4ڂ$3#_eZmDum0%\eL CO֔gKQ"uv:?b:k4ciҌ3y 7NˆcR8^ݲ#Nw:7l#a-+gh'M2< *5Zl`Ou,ӹE\>vސFu\[:Ṃ[zL0tL1~:O$}Gy[ TW@l#L =z(tj 腚~cvZ3ɴ1oI-po3qnj]Y.Ҝ%."wk\.!Hl7cn&fdPL!f}NGp:<֟}-kEwF$>D?l qv.fyf]wq>k8?bFt=g=;(0 QC4Ćgwh}zaESP߸msn;r[>-sp2N7EN`plXB  $NcҶ1j 4Z` C]`#_ӬUS74pcDȎ1Ǻ|؅d>4ԪF%ąQ05P{x+wϙ8J`i2_L$MM%jijڲ+~E΢ iLA7D{,pm&Ƴ8.|= DB` ֛S7^by! ˚"F&]V[˜C6D_?֌K͸Mw^ކB\ݪO)sؠ9cpmp-bޑep!=Jta3 j^=9=*─k M2"Unĥ D r&"Bya\@sK@7<wb" / @M}.WimhK蓪 $]L jX-!JͰđ5oW](_#&ؤb\@OiB 6@JSԓ2=T 2!C ݄` ?o=hr ZLۃ?U}c9ĵ:#dZܣ\56%3ՓNC'aZ xPe+I1[5êVj|ʶo#Pr yhN3l3m5PwӱD@b (ugcCPB6RRHWx\pZhWܻpMU9Zm_yr_a1~~m@j[E|` o`eCf6HdC2,a} qoVذ†+!7lr Tʚf{`<ۯpkBɉ?/;0ĪrCגp>:wӯ63X;uư@]H~U.ʯlQlNd R~V׿" Cpb2!h yoUpJI s;6%xx?,aI M^p-  !8͚2q_IC7A;Pl0VW?qOzW%/NYeea[mx,]3~$OeIQľvoXOS7E◝[BʸS-V̇n ZvQ0NQIʅC8uޢW>7OE JQ^zz;Er ѐw rݝѲ0 eR5N4}.K8Tk!0 irJ/t4_;mPJ‘39MQ+f; RcC;D#/m!`D n,J*mPnR ڣ ;d?QdʤiC*jL2kJ/?Fw([aUL-)#%emZSɄQqsGglČBAz#L=rjeyo&4( J2glA+V=q2LqQASB{~V8.R~R9ٍ'tZ?ٲ5xAbΏWNrm3B z*f'Lm;g,f0.4JbC3$=ZIfL bC :eU^p2+rf0WLU2pcuJ:]q" D)BkP&!"[.enkD&ZHvW)/k)%I4ˁ_r^|Zz&]{ol?+v좀cEw-AӼDUqr592plMP3Lm2Ο%脡3_Y4wͮ}`*;lJ8‡ot}ȣAm'k pIDpe>ٕ9=}&Bf<[=8 N2jUAՆhj0nTŢc3l'q'>ON†F"L)B'Dl&ɔ|L lT4t׻:i(CP+ ϲ)i{d6W!B|e= Ad- {ypi\!N]Ce#͎yN9譨wAlI}+o;i'M6U ؓA>`ʟܾhߜ Xx&+JeM[Yy+1J <9hж'eMT>2-*2M>W*RN^|t0خpR\ ]ls s.>s hr1 ]5],v,w#Q `]eZ jE>?Զ)mwNΕsh*ؽ=OT}'f ~/2'arfǁ ǯkbcgRޡh4< ۋPD8|y.`A R k-Wzͮ<pXPvA; Aqwer(x..vOwτZ҉.EERr5ិ?] uB5|6| zd-AX=S_ȏaB7b=(?e _n#)ZA:-[67Y N8{9˒Vy:l:~p"l:,آud k(\aa!)s, j gXX;\5NntL:eT t5]-bu4bV͌8@p2PJ* s0Z{8Y޹bVaqho:+%c9ц0*vikOCu6i_. 70Uo+Aţ\1|NAZHһ6nl2ƟA{S{W̭!׎[`H\#7?rԁ hSGT/kWv`0=`Ҷ l͋XpyTar<޺M$FrwG.< t W^+eQu A1,ZXkb [am;ή颶hd[ l{ NѰR^ nB} H3_|{u U3O/v>Γ)t ʶ޵v$kSVA;Oz[c*>AtnJ%LyQJ~ ^ "ιr+y /XMV_f qa& 9W&-|lfԀ@1]0G6 -2C){c~֫zP ٦eDzr1kGrc`ݯӌNS֬ ܆.`?e-oyLNOYo`tgH:C F>Z5p 5o;Sn0}y{W oWWc?)a 0Xx }ǟ~ߛrĠhpעD.F}Ov"vtw9 ~jj2,:aN̓jj}[.(_7O(i" 6hv:h-OUuPUUuPU_RU I+4(_ 4hG:'Uʾhf+#GȊA\-Ixq8XO6G @n7LC$zWۇjP!漁nM+] 0tυ5]r`pz>>ϪχEKNLT@EV~7!w'z]?ٿsG!2" j{٘vL-T1Xs|Ϳ֚G՗(R*FS,Z_9}`k>$qX>Q^B6aBjUֹhNXu;^b3g.+ yNkņ\ȽxZ[/6~_6 CވA Iv:GlXV+kk5M^|xQHr{ 8"z1unf wG*1m\UŇbe>%,c)k=+YZ~({ӑHٕ}%~+5 ۸8e l8e8NlÖS̠ v{pAY{pA  Yjy&)Ƅ ۭB3en@orhxX2 a}~(X$Auqel;Be,8 VjY#`ǚE;G>~Ѱ~Ul\5y.gAihռ|67e_Nk&ޛK`C5|Ư<ڗwEgrVD)a;(Kpi{Ñmѕ<<ճ.%K7 T!9mlӚJPvVqsTj}&\SVA.L ?^VZ#W,ط*%M[=F:F~@,t GtN.9T¿OF|cT|1 p`MjN#){ftW=W BlI#}kkxcGF2P|@ M[3xPEIo%ϐܚF|(N >2X3sf$#j.@ 97aߺf j۸G/NQ }^.Kao`eapWw]mpWw]6 ~o4::::AtAat<"LHжבke{]Ag܆x={W䘇[gFFWõ{"D:yؚp4wUN+~_Ddikv}DB=#{:˦)!aK9l)-尥ÖrR[WÖrR[gKRճ ojy6ĕFzIwH =ן+0sR_N;KI˷J>NZ[Zi~"Pb8:&ײ|\v{E|}[vr!=S<vX9֧ۨnaw$Gr1 pKq֔)-u@cI7Pz$\je5H:31و4ާɔH@:Ү4+؊Aw^$úhWG`syGcߜA; FnMOymݗw j>J\jExvNG/; }[,8#/?d=D2>@)vۗS.} _˺R+nkT̤<CFM_PUh1Y|pU8ԈT=ڐyikիRRJb~ 'V C]:Zu 1mHeHȸS?j67H;4~.WB)۞k途@boj4W0I`a/ |~~hʐcLE}G:wJ^d~'Ģ\l\>]R{V FX*04^]/Q"yf\%1Av3wemS}|1eܹ=139?ē阷Wnv~dJ#—Ѫ ?% SIdUŖ2õB*ongl: L'P͑A0 G SO& jCs 4;~fSID G^=5mv@-3 eƍ߈ s6/ ;X?&vL.~N7dZ& k:-DcSvy$e.|0c yRv=$,==@.9oW9ƅ6$i*P2@)Tl o(<6c]" r%P^5npa`=Ǽlj2Dɯ]Cu a&MALaTH]3(@'!ܿ0U^+JR}; i@  d:t |p) /`Wt Х&A#002D.m>܄kT#$\bp=XhPk׸i<5Јkբ1Z4v<9=m= 4%R+d䉇A>xmq\OuDN$MB-_Ă`b>o嫚4QOwg]2#ȑJ{X"R6S lah̻ >nĕ^Xún\A ,;)^zQ|kr)ϛ{D(I 8 h7el|bBAe tV9l+, 4 q#P.t {W% c}'*\b @8!tD|>/GMY$N紐N:eV[t2,`=@`.cwl{.!Z |L~4)dH2 %3PL=Q`?GzY~*ˌg,2t';]Əނpncx%0M5L@_s@l{'z$O:hP'``⻈ v>-ݗXv 7 -D\ Fb8Sn^NjY4gqn$ 쿘:(|mߗtŠS yvT~.jPn6TB!N{]CAQ=~CT p[ul?mQ 4R~m?xiH1Y :q\ZZ`e!'j S,xB(6WO8W{L<0 pGdI?gYِv#\>6?ߎG[ H-]M8t-M"~HG\T$a )?asx`q*Cc0|`>>afXYYr/ ,;da4<䨷觪g^|ԭS57)BP{flp4/Jh%B]!ΈV|9,X5DOB[$/mln 0M-bg]F L&|g|Ց'SvC7iq/(5Ȗ) lJ( J"h+nuj7$2( H`n<7dNY]kJR~"!nVEe#"*~,B_ZR9= KsG? |ì\JK9>4 4'3]Nk24ȉ"AO,x?iγÕeZh2 k!u^ ih5AXX*i0}u0$!&4Ĥ31)x ƆC v-~8 ;_N(TrK)ۮkɅG %|EP!n<8ck_7G')G1IU>"*nW~!- ZE$|] qYIpo(k/t0IU֣{#EDʁ5ߜ2y,eΎnu*rCTt{AE]>^n%P, aU(DqSNg}ə/{DNzL+pho#.^ε\{^ε r}/uvObK'Ef$*OK'壘ē׹u^^TUėSAxC O~(Tw<#1ӑབྷ2DWIQeזS3'=g@[* F| '_c"0-ghӖ3YwuISeČ=`qSQirNV_5y4,p]?e-^$|nfNMǝJ^iB٨]ʗUtZ܁+g:->|T l=EyE^zD,@I][G/}G7yc8@x@;{6p#eB,]9rYNoP5G|`F>O=H >1+/gJ}R .?|e03*:ǹ6MV>48̝"Xfh~R]zdXիỸ ꁎJScOV\a8%-&}I;<@_G>KՉvI_F&o' ިL-LL2P?Q~tuEss7ʞVt7p`T[]̢] ?U!"8SUVmvFWD(3^ek(e5+?-X}-)Oa-&}smtbI0<%v]Rijyծ$wHN' kxEmIΝ)9?wH~snAh.sD ۪Md뎥Xz)ȷR5x7'+k2)jhZFz^ݣC֠›N}p}'櫓~ N/e9`*ߞYg4O8#OsWdө@cG&?䄟hػl!e/ݓj!jskB>X/S\X}xĂ/+Ϭ19?Y\==¶>ԟξktcɄTˣϝ=ʫl#5 0L@j0 $5 ŋ4}[ ]~HA"γj)#:7mAU@ خLAljݾ/(|8uM|;wP 0s)L;@߻ j&Kra"F/ffi#WP2aG"!vđ| Ļ=&1G?QBŽ\l+'u2IӽbĩuRnO`EE-,$5$?@?5{Cp`{܍1t(=9Czp_:̝ep[桫sց `zGb2\1II/?|hIS?9䡿dN` ĩ#UBKxG %dFWp/aT $^%̌1dtk>l)Yopa;^:khU\  {FTGq"̼(wmoJ1 #X= (le1bM!dr" c-C,Ix?ԳG|fvĹ} g'7b uh(疍=隇y\(ȬKyR %5?(KO)Г:g(M nܔaro?=*,|L h*oX؞% 읇Ỡ4~P&5]HLuunX4 X:}ҋtb{~vjS}|G{ej}Zks&-{ b4gՉ9nnbzm#{m[K#!q-t psS`u1F0RDg=>&F h>pvB?=) Y҆M=h(iD uDV8BOND(7,XqlQ Ens-,pkr)‘8uizao ssx-hגWAMhԛ=Cw #\w0GsT8b RI<ʖ#tl5:7x,.穇=lat'ڵ?B68~s!؄?nHU|{qvxyt|{pxxF`0b+n&b*8A KJwh+ا&B@:ihژ pPn)(Rx׏+NP(]$^ K2R]:END {*ѸP"qEÐge%G&\}e(l)xvw)+rkhwhr^d2Lۼ@W#vtP"1A1AhiְFb7ec/D(PNk8蛬XY`京 nV}tnZbG^p?t}ޙx\qsn-_4 1RHr$ 1ZnP,b-0/"xdUPpˇ$5`vrUi; \⠣fx*c˚KEcmDNN ۏ+N{j"K@pu@%(9H.mp,l"ލ)7C>s'nOnBD$ )>I$n 2y*p|Z!DTM]es4MUR,Iۂ~yK/*eKA}Qb 8aG@;Bx銜HӝKhƳ/gnw'\n{y2WG5Hf G| Y#8^oP܃|_[K`t0H i"Z.HM !/f酿sN4!jEO&JuWJ- 0à  ҵ2aDjn L|auՇ gĖ F{VRT kp"(AF*X 8^~A<˜MjV{. p 1EI{)"d7scGEݳ}h 7F"Ge,cSG/X?Q4~ {_nK;O("ZKJntuvP'_KG/zq@mRBo kk!0 Pn(\X>]^?(T$B+5ĂM0tG@KlG|p| jX߸(7뮤{'FNl\5>D9S#:k_KS~v{[#pU~[&۬&votF|W &6C؇%>oa^[,W(9[ E ^7(&TklI͗&[4Sá1w,ϩ-12%(nQYp3W}6c]:P> LVJ fN=x ?1U R:@ϼ@gȸ׷s5Afqw@蝉ֵtPKSFKg!PyMca/NexusDataSource/__init__.pyeN0~ ߒJqHKiE!r-qH۳IUՁ|3;^oM}P\rEVv5S8y`MJNJ"_Q(mZKq;>t:ς]jvR5cuI 7Z0K 6wۥO5DZMcΩ|t1WMv@9 լ++vs _ۚ@V, d'bj:4xd{5QPKdSFʹVPyMca/py_nnma/__init__.pyQk0+|PTA㒥i I܊/psMn[Uea)2j%:*)r%KՊ/X:$R$g 0OKJ7nm #_$IEֶNg%; 4 Bn3`/ߟ[@iuvuɟ| _Nra3i,&3z,2}M=Ћ+*z 2b11jDm.UPVe/ ?F Q_/KA Q }X1Kಂr?Їn2بn \ )@C*#XfRVkwl6$MK$䜴㿬X?V}bpkPKdSFWqPyMca/py_nnma/nnma/__init__.py1O0t 6B C/U)U=|NmM=2vRYSITkq ΋˷etK/Aj<3N`pT )7.N˗9R'$#KTu\j]E28nJŊf"?(u.S>ŦWqƶ;ێ}]nr!c}ed9aY Vuml gJNЕa}Cu.A`4"dvXW̹,Whd0$,|b1&72EQVʿ"]TPKSF PyMca/Plugin1DBase/__init__.pyUα @ =OM:ttPvGN5'HO"l'K"d i8K`NCd[jn eO\~VV=s\۝ZvtsI!<X:ƌX[སP7ve8&8!_wWV!F?:(9$Sj8G z#D\ށTkBiI iCQkpl*d>ftsX4mx`oH{zG&͚=wؼ&*UkXE\}ɒ4{O^'PKSF"PyMca/XiaCorrect/__init__.pymOk19PZm E(MfdY8qL^j3h-wIv!elB ]f<f8YA<]$(p1?ʶB v?îif%Ǽg6R2p*+ڕ sބfJo_cDEpgBWjm7XxoQK5IV/'NPKSFdC7_%PyMca/Q4PyMcaPrintPreview/__init__.pymUMs0WF2`QL $i0`5J2 lɶ }ojnf[f,L9DHDSlKFaHq R+p9넇 B|s2\\8+ r&M~L\ ><*6:]?J8r5_Hӿ] :s<_` (?ͥS#PbL u/9"ƒwCOWq $Ad[wC8mG>I3L8e9w CT6hiznWE5M>Q hRm_\}3:Rރs[5OrjAuE-Qe C7гl?c ƻzhq6KzyT֋n h- 7Rʸ~$$&gO31~q2!KS~CFPKSF H[PyMca/PyMcaLogo/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ P雜蓟` sPKSF:"$PyMca/RGBCorrelatorTable/__init__.pyՔMs0%t 6L`hiH\G;GA\I+K4{wW//,[6ѐe1jm\k.-R[dtV 6@fQf)?uEQŸ$W s`2?\"EQ.1q|=Vk ձ3;q1l(4PS,fuU# |WץTf̬ E5ڮP~Q}ܫ[u\Y^f`M(At֢t3k[jρ沅_4`Q<$u'\};L8,D]t*é#;V֪Gp{Wh?g9.rknRu%#eSIOmyd6-V -S}:쵬Tn]DPnRM\uRP`_?PKSF[2APyMca/sps/__init__.pym;o0w ɖwJ4iӪT9âԪy^<ϱj dF(.U)v 5~hӜ~K ghM,x .Tr3jӜ*Q̏Øyc: T+ ׏wޓ v؀ =$9E(Hs$!tpMB>N, g2-`6!&~ɵ%h3W $KgSw9]Ȏp6#18=@A]'jBsu3~APKSF"l&g"PyMca/HDF5DatasetTable/__init__.py}]K0+r D:`*󢣂0E$4mCӤ&wi7:sFטu`Q789ʽ֬HP$\v"*V"+sHLK=B /~-ۺ鮍#}QϦq Gï$/YL_ auT xVBez}CYUݪ F! O@8!7<O@;ziEQfIˈƂ4르`TMAx˰=37'}PKSF=S;PyMca/PCAModule/__init__.pyuj0E9J"RǦ(2J!W";Nsq^T9c vAչ,ʟxl'56i io:L:]m}s&&i;|DpPePKSFEZ#PyMca/SimpleFitBatchGUI/__init__.pyN0$ 70] 4]v]oaLOU99=k2EEYŹ҂*JuY).|OɈ r"Tbp%QpJȹ@;gG\bI MĚV7 ^DhCȣJ6_]M]T'dv'8vGp./OЛN@t:^ D1`#ny5ʮ#8x\MÔX3 72VDB`4ـ!360@Gzhxj̑}'lRdC%TyA ҝᔈ*Lh_e5,o/$ d2miPKSFBˠ!PyMca/QSpecFileWidget/__init__.py[o0+x#V5[/ iJaC7[*$X16ER} 9g|7JfVmf ,R+WLtEldS2@ $XHfu:E#{Y12q?_|9![a.LH_9 B/֥zb#ŶabmCcowY;lMl#D겱|J]|jw1{C!qk1n9,~4t|asAW dXVRU*HXL2)yxAb944FNi ګICuќTZk&yxUr/fRo+h,̅ܤ(/մVi9j=쳹R[_2-4n/ssm0gPKSFj_ PyMca/SpecArithmetic/__init__.pymQ Og#tEEuYWۧE cqI5iltHTX4q5W`|FrKteUZLęVPKSF6)  "PyMca/QHDF5StackWizard/__init__.pyVKo0 Wy4C7HM0 j3Y$yM'ɏ8vK~$?(%+3EB,B\4bE8sV6*m83l cC^Н*#31x %R};_; -IupvT?Qn 4DZO4f++ls6( ";sb)Z ype?9:FSBLx$,8ެ/X]v=`@_$!=+3'_uX_5*)u2{"sʭ.;IbL+p%6L߫e 3}"9OL  K2:}/ԟ B'[X$DZ AP(X(RխR9f8o@f1f1&Ƴ>0֘gQ %-Y 91:6֫'QH3p?oVK Yb"b`&60ro3.3;g|fw3Uvݙ^ya4d}c9\ {߽/%oe7ՊF6&3|p &- V#&`x m;K!Q}a 4^^+a v#LqR ^~[?PKSFv&PyMca/NumpyArrayTableModel/__init__.py]Mo0 >qd[lŒ!i^ U\ar׏/`yER$%]]E, ;P+AoFQwo232Tgg{Udw[{ x2|FWe<[w=ϋ< iwRxYd-2t/bLQ,iDjQ+wK?1 IthIPv!?&i ɞUȡ#) }w; 9'+یKT]N$2 ) ؍Iͥxf|s!a(+ }90<ͫ"LH厊TM s¿ac;Z30.MA;FRѓ8%0P8cӌꕤyvoKcMykY0PGk! Ii)UGβ\Ӽ}GA%1S:CMsY'R"2pY@褏+5bu+Hc܉!,b68 _Wh䙄N%Y'phI <[x|yS3ArBL̿nN!zE7 m8v10'ܩ}P/+ KHA1 t 1pƛͺs%!Mx@]8; ZpW x8͞"H0|.ƀ EۅG:SF%M죜JldǺ'sUan&abNAvhٰ!oMÕR} skYMI\mIثk}voͯ򒜿$t\ 3"'PKSFSVKwPyMca/NNMAWindow/__init__.pyN0$ &r9ЈƘVv!=g)7moYkbBօ-4'4W\͘*C+Ulsh >**$cqEBZ^.C0v5WJd^8VG0$\? !Me-i7q2zΨ3b!Bi-f&Tq295aGi&BFg5r5a .yS\=P#[?sԾ tС0h@JDgz Y_Xoܰ?A{PKSF:$PyMca/RGBCorrelatorGraph/__init__.pyRM0Wp#($6]i%l,IVU\pcS4wl b{'y<ȝ8>$Bjk`y`UHN  Ua##$IٹZG=1*} FVKUkAׯ]m+ er3`LPIA@MT!?-#yow5@w6n\rj6u[8/DB7ܖ3҅QM@◉! $>/2RIxSaSqqr:JQQ?@80!Wq%G0ƞ)J44*zjCPR7^۱|&_))bA&x lUNϐx ]l$JDL~d=dU'Nez=.ȏ&<_Shsj6XT@'زPKSF.eUPyMca/LShell/__init__.pyTAo0WpC*l3<,i,۲˲%~{RĖN%EDHm%rmPh*8 X3_ B2 3ɌJkbc)+bTɏ]J )2`Uₚ_gȟ3sMWpr<^MX m4M,5 vkAt—$\Ѽ-4*T4vIZ4uI㿦[tp`p@O ߤ4lxWWCD :YZWPYF4Njء&QPaywãȚJN|xc.aN2uFtH L.#5 曆O5ƒgGyļg齞Ya@ y< "/TPKSFqʬzPyMca/PCATools/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ _X` JO-q/K,LKNM,)ʬ@+-pvD+D1$09PKSFVBPyMca/EdfFileLayer/__init__.py= @sS!s"HCD ’߾Ѵ9 |vA"=)"4MgΙsJol z+?+@)'S+Lk SYd4} 4G/lܳvx悃? q\8=_PK`SF])׾8&PyTango/__init__.pyZ]o}ϯЛ腷]\Ev5nlo h$>""7kΙCrOZe!Ҕ,WDҀUƆ+ysLonn2Ug Bj뼁gPB|kZ 9)  V0FRhDk54Z^9GKSVLY cLPg(Ch1qRyd߼Aa0z'B+8 S5>deʴ8Tp?ľTF=ړ憅I`Gi,o6LdNS?+()%. 3d$Z(${ XXeͷ-$!c$Re?o PDb \e{fV;{a= ËB'~z#Z:6P7ZK!blRo4a!o>pP |a:VS/; {4pVy/Ա;ܲ` c@͚e/❱1+-9̂5,j?+A @!?N|rx߱gwTYk`:Se^nMPEr4K] 2³D_򼵷 nh#kx~/x%Jg`Uqb˷,\C :ZspAx# 8J;gw򅀓3Ur֐?yo:wPn'eg:e>]K!ʥ3iÑW[R09 IDzl Rhƒ`"|au;ieWXSd(~UpSBU8xn}CUB)wDǿ}X}QDKsV.Eli/ g׿ }f"ּ-*2:r IȜYT"n^ ҄?_r>J} p0~}Y)tgE !Ma;YhDs%%twecr|hE̮Nw&234zѦQ 7H8Azu1`5v~AQau3:gPً(l|n6w\YSQ05uDtg' (-'aw:WFN*?;o[.R|$Ey_FPK`SF=(vPyTango/time_val/__init__.py]1 0 EwBcrBЭtkmY$LJFحk BU԰*xc)*=ƀ>΂qx?Aیu&:۾qaO5|ruPK`SF##PyTango/attribute_proxy/__init__.py?o w>cvԡRJ"u=a8pDͷV)?>Ǡ5#!:eO,U#~ ~]M>jz`8oY,dW gt`*_ 9  <欍㈳r_a5CF$q{E ~HRt_XH9g w(hٱYUjZwo4׫nguzZN>5l9Wҷ?PK`SFw&Rw$PyTango/group_reply_list/__init__.py10 =^b`K/` $gM ?}A9bVuEJj Jڛgvؿ\uHŐ2>b;^ \;w EFg"gRP Kߟok%DIJ .l}j{&KXU뱡8\ĴLF>V7|Po oXTglk\}^Q疨7p6ar3Ds:\tKqAd_b1FzPK`SF<)PyTango/ipython/ipython_10_00/__init__.pyPA  oIyBJYBR]}MĐCٙG(tq81ZmL8Af@#e2_[ln8PUWboss+r~iQ1%X;,ʈOQ}Y8^ǟ.l@WPK`SFD27PyTango/ipython/ipython_10_00/ipython_10_00/__init__.pyT]0|ϯ_P8H8B*IؖkqLY{wZ)FJj*̈́u(-"ٵZnxu$Y {>: 0]їș$IMsKs/5d}i`,$/H@e?,#ˢ˔V-v*jDjf~SZ?lY{@9|LMUD*95Rr]+c>z9`=Wj`2EvzG5Nta&rCND8Sg{"kge:I`ũ{Vx&@-|ݢ0,|Q`CP^d`>(9sWOci4% ̉ٲ'1砬6x/:4]~! E~8yPK`SFCi)PyTango/ipython/ipython_00_11/__init__.pyPA  oIyBJYBR]}MĐCٙG(tq81ZmL8Af@#e2_[)*a)PUPקl8ޠV 6[&.#bJvXC7qYX?+\،~, PK`SFx5PyTango/ipython/ipython_00_11/ipy_install/__init__.pymP_K0ϧ[;?o"GX ooڵҪKUhE!ZjFWGe6!6u: 0]їș$IMsKs/5d}i`,$/H@e?,#ˢ˔V-v*jDjf~SZ?lY{@9|LMUD*95Rr]+c>z9`=Wj`2EvzG5Nta&rCND8Sg{"kge:I`ũ{Vx&@-|ݢ0,|Q`CP^d`>(9sWOci4% ̉ٲ'1砬6x/:43S6 ęmjӀ y[?xPK`SFgPyTango/client/__init__.py1 0 @ѽȨWp'ji!h""b}HV@1(d횜'*{nKQUhKO0Y-r?d'PK`SF}TTwPyTango/callback/__init__.py}10 =^# Dؑr~BPJĴڪTQ־]H76Ìdpa)eޣ6<@mqJfs.yPK`SFadePyTango/db/__init__.py?0~:a"?4{o1JCk߻H+M6P':)ֿP,&`Oo0%fu@Y#kH?Ȅ,~{PK`SF=re PyTango/device_class/__init__.py}n0 iX$@&n][D 23[`#4HNJ&6x=|V^ZPc'RэIN}_f%SQ ʌLl$?+)dJ鈔 he Š8dIO?PV<0ˊr"K%$V,''@!IY]5BR2Quo6Z36lYfzp> إD.Rdq#u*܉َ#Vr/=l;RR@%(VSJSdSѡҢy < pm|Lb`p@[*+VGR"|"iNȖ;t_k9rzȀOr$ώ#8Fp%La|PVHEjMbcF2hS$( ]ڸ@5FJ2ӨydYqXMx'[UCo]:)KrAܲV0ڪ/Pޮ>d*>LƊn=Q$)v^MЙڲMQxiͯ >[`M/wwdcy]ĝ[e֕H~CˊfL3O!_$v%] 0~BTb;[1?yJ]JEe3 p~ߟ.is +R1SotE 4E'p:M5ɮD\8,G\j%\'D_E/!&H.\µ/[mGXB[fƳL[nn'bNttxh ]'\;\#aT,Ra뾏48/,!;!qvo g^`-{fY&.?\4WBń'٘.UH5_tZZg{nڶðiz o{ }˨ qBҤ^hخƴs.|ófO?`BXEyrgSXxUa2pe_,'d4::rT QH?Mo~{[by6dBT$.Z<. ߺQ|>ximW_@ 0}@]qTWKhG1U:w>wc=.m3ϓwkJN}NfCn8aHqD` 0R >EO4ᆩ-t; I0ܦP 1 vX}4⟊ o_40zҴki+LӮC&?F{ PK`SFJ>FPyTango/release/__init__.pymQK0+ oc8&0K޶ސ+&*s&'5cUapXUe:E!TŔpxȖUk=|F~{d6#г" w%;AQT_v]+ZrC )[E If 54sG,jp:!M*qܒbZHSb^gnp`4'h3 OimG\ 9o2EUl<9Oc- Q\ib.ju-P\*sD ȲPK`SF<~2PyTango/log4tango/__init__.py} 1 @~Eƻ_T8IŶ)i*:YG"hTZX Oh2))׫H -j7 >żS>2 X/؞(#_^PK`SFtGPyTango/base_types/__init__.pyn0 ;O8iv?R'Um FbԾnl!F)mHiQB-HnRXeWMN MRJc~_9wGpyAPF0T`jL0&WykN+$I^K҅OUǻg'ip Må$>VK 7\ocKSRqbRFUh:Gr{f'i22Z"槺Y\&q" ݋tau˃.WT_c򿄪".?`n5tPyl(Bz1c ',3]C5ޮިclA1OPK`SFNӛePyTango/connection/__init__.py}0 ;O##Mt9E݂I<1z[O/X}vPK`SF{PyTango/pyutil/__init__.py0wFx7$qpjK۴W"oonӓ(#GOg=pFKjD1?Pp\qY%jrL;(R}LlfMFeT>ꮦl-:.M4{S=>IujZh& PK`SFx&%PyTango/encoded_attribute/__init__.pyuAk0 %Pȡ v(ubfKNn>' F>&ʢS(EE+P ~(RŠK3xՏ߼ 7K(]A)NW㻴;c``.ۻ: XTUn(9*,=Qgq]soLG=4*~=ws"/PK`SFGPyTango/globals/__init__.py} Fc;DF VJL sD{0y`dFe}$ҠRay"kkR3i!^#g&R I8k1B{lFA:Cx/7 B¿ٸV^+PK`SFWPyTango/server/__init__.pyMo0 %vCЏ!@?.X1 L"Ė\N?Z+/IižV4LjϒlXUKUlpYf NB~.t/ѭSMJ]}e%[6yosq }jِقIJP-1w*/xM` ۷I*tU=L[򄌳״\+Ar/5Iz֟zh ]:+#Xj2iVa|9Rٍ%rqu 7iKK;,4e] =>beGT䒶f9z>S.L/% N[kq/R\TŌC@іT E?u 7zǁf_˾*;fPK`SF)PyTango/green/__init__.pyuPI  Vy<(Hb1{Yp^{;o̅Vamtq%јTB* }P|j2uxN=ZOmdd(t=k8,-ٽ0e9 leS`լKNҘjP]AZ|}?$;"u ~kxC-PK`SF3"PyTango/pytango_pprint/__init__.pyMo0 uMڡjR'Um+Jh$L@/ѯ 'ܰq7NN$k[$I,A!JQS HO})%XO(B$,m̴VsZ۴*EUSJE.uO=1yظܚЌr uރsaCmaZ Ra[@v"KC/8 tK=deqy˿LeS*vQ:c׺"&;Kn@dנ7[֥YU,TArW#%>]Zه-P.Mvm"BbB1Lb@%oCxԅ 9  d%z⃰6];6`)t/7@^5Wg墼@3zMȭV{Ί>l瞩(PK`SF0#7PyTango/attr_data/__init__.py 0E,/.* TM2N>޴"Jr;C N*UT\(%@,Da(sj#a9yQPT>xTWuQڸ[N |DS唙F BJL|idvO>iS: }a{X:}c7P农}ʡUɵ PK`SFEKGzPyTango/group_reply/__init__.py 0 {"Cē_ ڄ4wSsKX ( (%8xk3+AdY߱[˘3!w[@j=TxPK`SF^ PyTango/utils/__init__.pyn0<l=V!MJT5Q/Ue< o1-1;̌=MXag\66F*$U(ʪjt `eVBPclwmx?Wro~^]gYv,93!Kt\9O(+j%jCxB7кf8`#fUkI"婮#Km$^HM82P=tQVb/ V(1p-M4lNj3[ՙxyfPQ`&<7sy7J{W꺆q/\jHߪ\&j4g-eXJafgxu?/aԗ%5t e ~=lĴUɠy^+Q0"q"cZ 0) N`U .tM>uoR( #!q@jӳD{Kd\:3$N"Cv\ ^krx+<kp|NY~hZUw=kv#r)tx=PGڟL#n険"\.߁bS6\W6='RgNM؂~0QdeSPK`SF~=j' PyTango/device_proxy/__init__.pyj0~ kqKBJB׎Si:ouLAr4i;lfwΙzd+ʚPʯ?Rg [%=-f[UGlHuOh=S@a![\y 괅̙TP*#WVqs@d?zG.\H2 6:ODKp*($G'B.y%`/PK`SF`PyTango/device_data/__init__.py5K E9P`〈khQ>-;{'1- ZCmY1RxP|x-R&㋛ݶw0!jzWUPK`SF8@q PyTango/tango_gevent/__init__.pyuK De{gjߤ)Ydv3IeS& !ՐKqkBQM~es+M1T'Sֻp nyg []yPK`SFaaPyTango/_PyTango/__init__.pyQ8 y=\;p3h,7 ";N[}da!`9o }Ye." 0FʢTeVh57TN Ӫ\*zB+LJqU?~)*ûLJ`r̺L-3 WLY1\TxuT J%1t&8,_jPYk4:D[ Hezt,5Du%S}3#\vdN/tewfINޛ癛hMQ#gx&]P6A騁)RJ*Ƴ5K7Kd] 8g+,'Vxy%Ye: $(2*0k\Kxl D`pKZ!jD:r鷃%8.hrE]Ogk 7'r t65/.#]s)hd |xMA+0wP#1B(smmIC Kn 2ENd" PA2v'74z텅 a۷:,vɩEE" jGNn#V+qwƂT%a`[]t[lY-9iPc[Z+*"q-eؤ5;F6D飍w;T%vh_8} hB }MO,8rzAp`yO8, ML6gp oH`>)=(:+c~$}6XY(zh@5WCػ|1C~@e_aُ! ;AAkaSA;@x"7XboY8Eih)rn)E5~knrF L8-5}^>W*g"X 5t? A6ss\+DVu؍G'?jc)~ȂBK"Ю;_jzܧV%6.Z]򌬿{@z釟6~t?ԽD L]%{jg]^t`=m :auT{yMĦLG [L1?FOј ֦hl/yu½2?%"۲޲~UPK`SF<qPyTango/tango_numpy/__init__.pye Ewmb7c^RCi^ZV;rY&JApm }H$퐵:y `IRu@Y[OX!bt\|bj 2ShTQG4>Hg/s[qSK}];(o&R຾}alծ>PK`SF$}!PyTango/tango_futures/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZZ\Z_` *.H,C(M,Auv  []\,u-PK`SFfrPyTango/exception/__init__.pyu 0 {"G}n HI!hۯ̋,!A%bXmUBY +'+%Ъ(~.C\+ϓemhפ8\FvMړ~PK`SF@u:PyTango/group/__init__.pyu10 Ec2"13PՊ[E$Iܡ-zYLpVMzN͸YG5ZD‚pzӶ38"'B!ZjPHXPPKSFXnguiqwt/annotations/__init__.pyo0WVC&큒4E#W1ԫ1Ѳ~g)IiMK>wϴBf)5,W8Ҡ*JfW}@г^^9WiG(@QYPӶ rA bߡذ,/ *vywYR^*Q!ay8?QyJ L#aĻvp *2撰;'gC&h9pLm= 0mW*vة;02N0O?'G#Q1Uj/99Hn_Ю4yF׺1L2^v䛶85PsM34m|jgmmL}Eu[oG(ߐZ?9F7k` 5 ^[]B#ikcCxհV `f姁JZk*Rk&{9 ;h6EGESp3UQ(؃Yt9ց; oy@jݷ x4nRr:1fןj7 $$a/&^39crؾ/1Ms/WpVތ7mk HkVJsb牂aׁf0|DmT)im_4{ؾ1=.QCP_;5ׇbwl({us~<>)ϻ>&?PKSFG=guiqwt/geometry/__init__.pymN0 nF)P=yYZ;8xzBRS'" [ XTd)qT\Af<`c( `Mk`_Հ(rv)4,΍tr_`5J{5aD2P܌GJ &)z9SemJ~9Lo,?ل˪;<qi<]q_:bPKSF}k$nguiqwt/events/__init__.py]Is#;ׯЭg\M.T}qT^.v Rr7u0? zmМ jvЮeg.[o,M G';BN5f vUqѼZKE;Ҿbx Dbƺ;Ðy+5H=bH#S4 PMJ*\H PhlS|i,5b\E[UT֐jN-TRngneWK2=P?[}9{0gzl[_¬1ֻAT-MK 6erÈj]hاcGaeŹ5c[:<\H\l?զl/,Ƽe&\7Tn3iYtMoǜR :ߣ*ֶ4oـݮoq4G8{i벷EzXiղǺ4l& SPB874#p6 6ʱ"x^)ȎBCPخGV>Sѱ } @6ͭr;ӏfq{X᪂Ne"n,^,]KkޜҞٮl6[ GpG渣{FT^Jt g;L!HmNh&Ru`,] L:LNH"$dˢjE. G/lkS񠁘u}cmhLh}}800n8p^t;kX7eV C&_bUAtET8XM43ۃ >(\ 0O'bx NtOKD piyko8ac7d6?ⰻv0. _TbmA^Q3sۅfq[a.=[7NXؾn[ F 5.4HˬJ@]RGZ\Sd4JS4e )!į̺n2u!hY n67Ohh8FՠH%3+0(2*6bl1VlD17=6i[݇\6H-*ێ4Lq/ x}[sVؼC¨`}N++X0؂07*4Frj?RG_tFQp =6q@We!b㾖a$0?rd`g6ZXyi}X甕4/&ҦZ | n4և6 F`؜[碞|xzǏ =;a.Y"t[!K)M͎[ڒwP [E4MK)?kStL¯v6=4&(&o'u71G^ߔ5걷aڎʵu?I,~8D~`yVj!UFĵu*RBJIu3>ޜ /fi+0{u7hً9|Ƶ> ݴna{ŧ1w0& : '^-pmGTesmי}8SpsUNp@Cx@KDHt@- h- -@b2u-HLvـ q66L\ x/ٚ3.l]4~Z@<;X;'d%Ȍ5Bna848朹 <[𫋨'h4xgp9;w/&ukCVGFhΌF ԽLٮ3-CW6*hpRlRLE}qXnSj5 ފ> =5a0ɴœQHp$Q/?i93?jȇW8J=b[f+*ޭ:Efs10jm{^׭43I"R}V|'NeoFG$)"Vs۫-]AE f'ϢfHe㨳}4Wzrq ,ŋ\%m43Jf2G6k2Ƨq q$D專pO}{[zb/֥%4hExp*HGBZ:qK<gM"zj\,W:aj8TlGX)IHIT)#H#.ETh!U5PУ1 rTVKg/pZID-&Ύ iÑO;7egY7t.4f9jPE&]A/}2:ʂvD=]Až@{h@7ug/ qH\llEACfWvVoOQtsmx!٧[1ڪB|T$p턵JVp5QZy8a>5"+x}v\<#~LNY 1;8PmfJti]ٔF܀98G=x} 8 Ю)wZɖ:U ҂~3^@1K&SGR)h($P9'+80Qp,`DS JSTHsX[9Vʩ2ϧr*SieJ+cm8yI+cmķQ':O:r]#;N18Ǣ}u Lj<\"[;%qp,FfSmWD|#DJ1h#$JH0VB&JaI@8SBs%-P-TB+%-+!lW a;.+J;{%ʇނ] t/u./x*J`y7ј;^+y3K%=WIS;gM$\t^;7EIdY/>v4]8Nܰ^N}gL't~`uz~;<*5ƋZl'*k- w6OW=== Wvpo%~{SE79(i%l`E:Xf6w}ǧ~,`|x,}ZտX[kǀ@ۅxSE7x4;Ã4e-Ң~)?z: .X(R`SI & 3jKwN,t胼|+IkWX`o>fxeX1"[HYJ5ZIu[K7$ i@ H:L.䌸kȇic7op\exIѡx )LEVlΣRV]I ĥwxnR)lSq"LlxXn[:e+M 5K2\ɚ Pn#Vb3m(q^ ҚTܥTZWDҘjTvLYڐ}YtNlJ!/J,-.6IF,`so3T!u۽/g h"´^<љߛؾp-۸2ͮ2ORNY~+- T.p)~[:~dw|U %3V}*O7pf=Y4oelߟt:S.36~:Ln6^hm|υ1c@/N`ȍy2Vxۈ$ȂE`z7RBYɠt^a"ᐣrtg*Hѧ',ݧ/> \&x s>kҘx#U?toҧ2Orhv}nLEiH8YڨUK=F ib#pmdJ";DLB,#oKVlE+F\! fJXZEM$~ɋ3kb 0k,Moh'-:29HDva~vH;LFM 8~iL杊 k]$۠oY>sS[p򬒿Z\Q]ez= 5^pg+%qGH<qDc6E+Y'xe޶۬g_<;eZݡIC7_LQ8w7r>} E2>SʇeޡS,/'Sw [>P=!yi@V5CAguOW_#9ۙWq"}~FK1C1)br^ ΠGJS0dq|x#jt5ȅ.w˛Q="si?Mwܱx>*fGu #ԛlM]9=/[JXGQ WU>xF* Ν)Bi2h-W:B7W? 3d'kU#L.1f}^|.f "ѕt^# VDw5t]wwz$'|{mtlE nGC9K%G}e};|_robi$_N WhR%UB$B)A&v6רʃ^J[l'PZS7ky{Ԁcg&  s|"`W_2X{DM)W;n*Jw H)[:[ )2bFNt\(#Vw{_%[dRD-|5-3+g-\(rʏ'n1)>|IakܭJxo5P[#'ge)Z6# :!tSBoU1a?bX ܣB9e%2I{:tai䰢!3C1b_:W^avk]ckuOnXɸgbƻ<&RG;._{ϽZ wڠȤUwo?,\1m[xHu]l;`it8?|XU؎.΢Xo%tC$(Z670XU]Pb'LG>޺:T<P22𐌻CNæ:f{z2:%z`@֐= E)3'0h&B@/~Z^⛐@o"wk"ע}tyF[DQ3wͬYf'|s)T9 9| _FU ~%7ƉPq,g8/^Y_U-GL[n3 ޒԃaIYMg$_ӑРfS%8PYSbh(BƆ`=dQ9nuy(Ka+RKq,"|pvfIG{""1=C3I@i!^&Ow>C!~+7Gٔ_E.$@;4R2>> : \_H14ÊG$ZGQHM#x6PM{ #[]>OѫDe]&"B0z*x@7cvo:+݀۱H~tU{1~ِ&BMH\Ϋطr.0\+XsM 9hQO37gz-68Z xqn Wus z4|< 8l)~SaGvƽ4 'fh- h 8tLRӭḬu̞9ְ{;48%S{^2Yȳ}&DSmy%i ;۬,? , hzkb/-!ff vR."Ƕ),g3)5 _|_Kџm-G~ 9C03ן>'d|g?PKSF>XUZoguiqwt/panels/__init__.pyn0E|EvҗEH"DV±S);y@+E?X,-be%*ń*RäT)9 ;*~zFmb/Q0CKND g5ũZcMێ]b%>vw"o(BsxZxn~0ƙW9F| RN\$nXS3j?,.Íbճ@WS0)*M{a"9IȚ8X(Rр;~1 W\gK+SeŶ.jSK]/:ґ\* h֡uq,%/tE*L~ȶyik"(؟6PKSFP"?0guiqwt/builder/__init__.py[Ks*Wxvϙ3ԯk)bm4R@Av$'Q6 9p|$;KΒ:LfPIʸSPx%lq`5uS0^M?j`h+j+B2 L 5#oNĒQqq'rGX!8,D RgMtףHUFik>`0l]:Z QoQʤT#7?]SeWZd<4U;(YAٻ;"bjL՟Đ`(PK0^y-9^a!يD~ DY ! ӏ>\*-LBrwt-:&X@6YD3 %,4V`QsUnϏ#3JvT 4M~hPˈ *ATV?Ě:&JIsnm{=CRLJ5 AZ(P֚u3ͭI#ti̾b,+$J)$:Y+8B-eX_RDlItQ*זGL̪ oUϼuj-U(K:0. 4YV2u΍Xrf2 iBuFrѦHigk%"R䠆_eDftchUO]U|4q6=3'4^?韃ipyi-*m[ݎӜvSBé 힮IuU0[1*6~Kz,JR): =bHR>&JTPTHċKvukrgW5_n_Rh3)ɈyT%okJ%/?y}kуKhn`x}Q\=G92}Zh2zW9OCgp^o6v^-9Yil%PKSF}wguiqwt/scaler/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ __\` +@gV"x;:\O?W !\$3YPKSFYſ%guiqwt/pyplot/__init__.py}[o#9{ (SAmmU"%Zv*_`DbՀ 7^RzMP貾*4 oT?`޼rI6WeO?FUPK?}|A/Ryu`Q>ntf=Ya:lCSYmX1L?d_fIt6ud>vZveK p6={H^uZg*V{N_fA21-'f?yRcM΅tQm[m,uYm$K6I| ^sVZ%e?Cwer<*|6YfM8&eؓ4[&&u۽)'H0YPd"0KlIKVZ}@G : Zʃ&dzgLk?], 4 YoH^zR|J!52 gEU|ځ95SZlx!,yVAHTrWLJhdX@@L+hdmFF$ϟ Ĵ ?z9FT8ZB#.>ͶFb[-[>N6R781#Cr]Y1b2Z|Oo PO>vjH_3W6nת@ գd~7~nT/Iqs0UkJ7IFP jY)bc"/ehM=y|>"c]pK?FJF_oWd56]}/yB"~N2ip6Eֹ8꥖P὞AQ!q!2@fTIZ؆(D<}ghh|&wd'0s:sLMSYzYch4&J ]QR~&h~7//d3HƉ}Eu?~gGOa#M1 yQJc'H|͟:NC*,Ft$DS~YG|*ixо69’_Z$MV#Ը ,= i~2g:4;(]uP_kn.LG Ѷx j59C- HR3Urgaȅg~Wڐ*b%«ayeiF.?*1`?$^{^I&u؉>J!rpj=TRRhЗqhYkr@Y8) 1:cTlF,2] K~l2$ӥ.!Ѳ|g]ZXq|h}18:]jr}^677s)7,.i(/M)R-َ%%~bU/Yd PH]Ys^D^oaZ⢋bmdc@"p/`ìqbEysp1I݋*IoqZag4 Xs04:!{~XNSkj"fG-^bE߸eaM4R q%xby<۝ܛ(?iO֔ngAwX5`q_g3Uf{n5{MbE$wtˆUKAt,'o`ZP>e}?R,>i8_4[QU:kxª }o&$ϏۤܩIR$fy!h MIHTãdQwv 'nax٪ȅ+mL|@k[Y >Ik{;oa[\2)G3 xUmL\+i*.غjIIJ3V邳/i4bu6N.y@o?ѐ2+gʭ]gגzWcrh+M!;?̕_bDpڦD|Iwj%aNiDW4lߩRVT,u~k*sd[کY2Hҭ"_69v!p`qf'/]u:ˌã6sz,MKTޱ t S3c+0n6L5~ͅӠL|c8Bgƫ>)ABą}[o;Fo -Ԙ/5[qoh2n(|'py<ёog5a|K}S$;SJ3^ɑZ=1(;&TA~`UӮR"v&dcOWeśfڥ5Sz]U->=Ӹ5Gݘ-7eaf6Me<-[aicT5Ɲx0{ &W8T9`+E $6JM P[eQ>Z3 ;f0Fݠ4g-fi ,-]2gX@~7a6Bf\P߂@;)pUUMUg-+Y"\9:>N?$:wgu\C$ &Rb% ލ(E.xC w{yONLQ qFɆ!W1ڤ9d  v;K4bz~ӒriJr;F2V쐻3 <`fokRU~d+cj{qCAmcu3>9tN= #MN; ;>2V Pڈ4fSPlS=9n2WiUg0B=)񩏆a@6C/Ƞ {cݐHŻWta ^! :ʌ }H62hJv ֕tݎ<?(R$5tN^p!LGZvQe->*0z)0 a?t;>pss'0Zܔɵ\$٦1fH:1Gt͛ eOQW&N@Į*Am2E᪐t&IsWe'eA@Mڢ_*t# %Rs|aiKw#u)8׵ןOK6>+D#q3/ :TM~ '?Xy@բ"mA.~)gu2oTVB|tJIanWF.EʑL&J=-9XX=tuƠpsx̦Sߦ[)Tqg4r81%si2܁>'kNZ X㔃v $ov'Z`Ɏ\88KT(Q|pxN噁D)"\A컜]9P 8t ώkr ]/}>p^@z^(Yz9^Ʈ2R̵HYRz)zqv8k2LKgmKf.R3O1CV g}^"ڲfiZYliYhE[ ҆/v_͖~w1~n,u3G{Ʌ7.I37VGw0(z-6sT ڸɜ// V)I-аӰTW ci]RUGUĝF D=v>!i\-y.J[ d|T7|#>;/h$.i;֒>iKwJkg\[IC2zQUg\Lص2g\H{z2zb&39ؽRF?ѩ27U哊 60tijkt-qۂek7KEFڎ`2*oM]T"ЦN77:fB49Kk, c~-opQy[Q Zn&$MXwbIuZ>[?sma,*u8Y%J51v[>i%e~13H:\rծvq_`l}4pnoӵ~ƻ:3 C0GBmO*Ӊӝ= wOX: s|hjdoOa'SE@Vm)qFE= 4'xEβPBp*)7ڍX'}~H7N mC: `WKoNu]MuQg$\fJnIi7`Hji4)#xXwѲlW'5f r|\R$#Tg1hQ&/oKlV\_깏+U<8)662dQYvN]d.|##b`R{.hhYv[d~rOnk)S2>~ 0SV10ƾAyX[Sʇ&KlC/'m?礻|!)=nZApvق @W#0+xA_G)S⺋\#ʞ;ipƜ&iE?xjRx'89׍þË+jDvkM|6>F˟OFA哤v .((#>(7-x>*mL]7w4dv~̈́]%@"%fvG')3Rm9ʸCk:GeTBeA@nQt@7L'o V&rI.^|:ft+7?"1vLtIhy fE>yKw|hBƷa6+DuKO x5, :gbn$|]M!N t]%7q r o'FO ؋]Jë)lHN Α0/ Id|RVҫo'w #>EwQ+,FFg[`3f- <$ Z2_FM+ Ơۭf{/Hi2{+_l\ ̍)Vmf ޅ~g_-{h4bUݽ L-i{"|ٶuAhNk(h |7*/F٫(@1]E!o&J[>IP6Ylv`u2HD "}Lq<70Hq%{1lH}RW=x0h(d"#]*a>24ʍHPQ"־K\yd2\iy6{bn xH!nSXU]Ή2Ck-1 ?D ,=Zm!@==ӻj}bmnK@kOP*OD3*+<~Mw2NP-f OR8HBds3&G|Q_HP7FWfgi]o=N*j0ܺ)qB  xㆵ)L,vZҮ>Jx~GRi`Aj~xEKq,l"|rfiw2{"=< Oʹ"xø|Q4Ni;|4"MKiOvH̼((/j{21 Že8`F7oW }ANWt8 ѶAvn%Z_$Kxݐh 續.pP=+8D/k$[Uq}[Y1Ÿe*¬RJ&ؙr'|hg+z 5Iw4q(Qoʏ(W{ }ኜ-`1›xA=W2{ 8M 5BgiM;(K P׍-3|o6 سW{O3.dp:f~i:q-%x(9ܬZsrVMbY#R姼tYp0ӧ 4百iO$ܺq 7dj<^OmD(j i3ar ,T&s"HX #^7^`Ȱ-DwY$<ف Y{) G+dT@ {=ys/Py P;=ANcM[]O]hBg}'v$y lVCSA֎U{8z3z%Y:җfug9IyAQ@]i فyS4xl-uYiBZY'i=#m[JƬ~PV?ohsf7_DmQј1 6)_#G/l Lr{OУemJPR5mtn6#U\j{ *{>GL~? E%)XLOhg~Y(~w㳏l W|XS?ݧO7PKSF#Hoguiqwt/baseplot/__init__.py}ko#6{؝ILtz¨؊]rUM=:HJrҳX`cDQ*Iyf6me6XUsQVi46iz!c}->}JCu lӾMk5-~ u>}-Xk|=Xm(|_HzmKjc!C70"o|X {_ cS Wן7 m=̮&w@S@&mq=$rܟϿmןlXsT:_isՀvN/}̇ z5V 7sd烸Y77&&KM'R8&qNw03ɒ|7攙JytqQGT;Li4MVc}_/&7kQ+&:CʨmvH]erSi}WEKa$SzIsÿyQۤ~eyi;+0vå$7{;^9@q2 ~ȖL?4-rk"+*\~} ?td;:+R]dIՇ$ < #:f:$ %u,4?ҭH]+MK.JmYrǺ0_RQ_7ze|ݬus3_Yn?_4sF%j7zN8g!^ m:5 X4IsfIV2 <;y0[fɂ_s}*͏Ti$`m`?eRh;]պb&XֹyIڬ!J&ܦ,5y$P'6ODLk:&@us_y׋? OWu&=]RY1)7:"J2^vCт@w:x8G2 &=ϼLd Mr2_8Cg $=CNYP6HL4"28E#pFٴO"1Ř#L$6hnMU|1+ǨCVk]DX wCZKߠQPC5 xٖ΢pSU3. xW,`uY30Ͽ(QJfd|,\E<_!h^O N/d`ˢq{+ Q96s0? ڌ0MHT7,_DK"l~iMkv0)Fl BĪ\7^iK@!U( 4\o>ȷ<*cѰ3&70F7u^N90t" ;V7!Ʈ#Pͮ !߾t) cx3ݬdq1v)16Cm]cSiIF<[(O?UE];  Qքo]v~ lj 4Pp?\ـ{=2eH3eE듷C=awiw82B%hP$ ,vX;1pfshV6d#[SYQT@4Y޳2}yik3C6oaT`i.ijB H)j *bY5:@o9 VPHڝ@m8엛q;MFϞCr Rv[@t9q`F e]3A@l-%6b g&5(J|2)JwɉsɲKvRfI} ]ꃑkd](Z2aw؋Fpcc eBbw(^TNzc )&q>a]b7#%N@ZZW>ڨzG޷3 ꀞmBS#gܘ|O}IU!<'t ~ōy`nSj6Zqg<1|fm &3vekn%ߵg.7qEžhh q/,,-8R;Dҭ"(ZPC1̫N.pqJ{q!0wC\a4YZQ}G 5ڿy YE#1DoJu@L:\Wi{;ȿ+%1e'k2dX ޘ pzQ\S ۔b.vȅ ) CdXlj_2C_zd[$Y ^G٥oj ɾJl;LvVul#(|RO2T,B@>nPM$g&{ByXYotFAk ֯ASaZmDlI*v63\ G>9l>}F^ )MF<ȷ4wMGo^{:)Gzw"Bz rF>Lgq4PbzZۍ<j0;Ч{U;Z*((EBSU ٢CU ~5 ,c Br&Siaw%.Hqd:No 7v8›(u ^}Eb(G];x:/©WqeX3DWG*jgbmؙC1N4̣)kR#6 ӵK`vb 1={ 3"SQs¬ʼnCYh]:Gr(D.MLHVZ:\8*u>njo:VWufI^seAMڦ_.6x:ȖRI{ԾxU!ŁG&[_ C1V@V?% D.Ҷtꎅ̸#Vu>ԻQ4C)0&SUvYQPh@:zϋ]k #0Tie<8c#KLwDinVř)U5~9Gsʑ busٜs/g|롵bI#:+IN@ӁyXw)/"\ Aఫ@G9tu{8T`G 8 8r0RE;M HGQt>r(G:؍r(G:؍R"v(c7JEFp80suTQ_\t(%.ͱkӍRE׍R3#Pj.0,,:Qhp$8RHs \sLxWg\ERF06O9J}93 \翩O!f]5;!ɱp in/Dٕϸ $x(Yf&N*3iҍ|c9zM^[AΕ\BĕQ*J񼵗eJdnDh9i׀DKk)uiYB8rA;JSq@ \ F%Ղ23,|eʵ"fWՁ`B3ϟQ.3'sR'H"c3ڊt^~'T7H̗//FzęQ׉&q$m=/!B ~W5"s8@  CC !bȧ|d!‘"!‘vv!ǕCMUX!awU {btlk6s.ܛb`OK< cR^ ۤOΫh:A#A&r$<>>iCWoRn+XiѺh7ٹx݀&?ZTG)Q~Ct֘Ft~tAFkc=T]|Em*;.S{6 ؙMMt4L-G$ 6ÙOUsWsr*3Kwhfs [ two(3oԽ+ wCu *;K.CoKgxShӭÃ^OĶTO[H9Ko-PiYrGe)lʣJA.^cRO1I=SXIJAu|lj`> a꽩};gEnRǔn鋱S+eW JŤe0ˡ7 PW z\p7ԾO| /87"_ZSŠ\>-uF GO&+-z^f.U`@NW4? 7j(a:7,vq{T<iuV$jE1`9ëf EBX^:jZtl}ne;}@3S/jF+TZWƟT̘i2_`2Rfic*yv}?֍UܤMECU:1RCxIgK_ЮN)o+je6kP+wצ:yIRI=˯~e]\7!C \Ky[?u|]~S3.ڪRjdk>#<|Y8ۢ*dOnjj蜩txLe3U<:)~w!HCXڿi t~I͛6/=Eiq] ,Ηln&wN2OOOFtWrdg/.R$T P*MԾHo8~9՝_!e#ӜmBĻ] YGgz*5_z_P*a?Oj+8ZmQ*u"-JZ+)uwf&HΛhK5YSn NtMoGHZZ2|QT`m. sv=uG;Ǥ޶5u UsIRgϕISE4#sIF1*~o=>rFå?Pp9eR%{.|ëqiLΔaD9;t_ Mr*Fsas].;s xwB4BօW#tNW_#[?eJ"$⹰go Qe< χfc)sБa<] ΠGq mv|t1n߆.as;Y|6&%L+2*xWҶo!Z嗸hob&[ )z 5}A!sBwof{xwGeS]yv~d&`%Զr Ͽ&O,'HV $ǘ!A44ɥ;]]-?MZ{EBV ߮2DNCsTi|s[m|mEEQm͗ $JM^ r>HH|+dҴj)9H14κc@t.FcxEQyn1 n<:ꜜiazsCCO v^._^j,enF0yx ]'MمWhzf/J^$Hrwnۋ]J'Rh8>d>|ȩ}[1:,fR`ٽ+$6^JdY_HM%ks{vf 8U ]0 g+'];Wʾօw{!JR]#٫ ^w*XEJF%7?@3f#ުB`N&YZ6f]U萡:b(M XQ)݀a_QG<&ɡҝ eOTFX[X\% 싃Q]}T_HqC Me5v,zLZjm$Hމdm{/8@| L?!Z|.@?"k̂Z_Yrﮊlpv!%?:<d >Z*[Mk l&@#n?5#ܻB)Jgbi o FJyu`۬y=?w|\r )ݛ ď?@K Py}@о\K_5< ..F+".ΒXǎR(Y]:JSPflpԽiWi::ϝAo{mպ][Y-|w,epG`0yUp^RtU ޿5&qp`&ZCgiE]ҭJht7aeӳ@̰zC T//a#[g"Րzo&F`0I/AޗFS)IJ Jzc!r6L҄QL)*N`gizl |nqZkZi1-+92OEؓ\1~OGDI&/tEfLW'p{Kдh {LіC]ސb/ǚP=[|hEx{ cϜUyӳ?6d$=+7}G1zįcG#/p/tͥP4H"d)(5ZZ0t^<|4T,UPwjK|)+$*}ֺqi'75+ܦ\0=9&u%RT,I:WY`*|zyGN-0|zaA:K`+zX"s2'Y#ɽ'"c!.>?4 em< ~MjU6A黇\!*$iVa$eYJA{Q#ge%|oAAKQ&~w-ᣍ. 3lYq.x'C$lU^Y}႓-΃0-wJ^HF8M2#@³ns+(%܌x`8.ӭٳ]=GSl$ݾ'S"+@䭟(Ou~K[.BĤ-CiR,Nu: g8DCzyD ~Hpcb@ocNPLOt~q$"9%D.`N ,̘LuB ˠLF@JM$?>c #uwGehp! قs=R|ys/0 <6[_㝞R6\16ԉLpӯ)>! Ms@j5;Jiٳ Iv@Ӹ1 [ [;Q!9tH.|5G=<:Qb†vӁ23ջh]_ath<"d Xfosk>yT`AʢUy 7\t 5*E:V`_EkmULs{2}甔jvܧA`AxSk( 5z_XW\W!{m ,V_ȣzS۸A~p0rkbRJ[/ذrc-gt~$DTǭmr'l"'=OW͆PKSFgDd6Hguiqwt/widgets/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFi-c guiqwt/widgets/base/__init__.pyWKo@+|Ln!@ H$؃ٲޱv w^;&PC$0xߎ=ڥ̋ea Q,Ge\qi(;+x];D>) &RA'NVb@dSa ʶ1x)=RW(y2 h:]dQ B GPɕF W\$ l3=rשB&e|ϻfڐxN$gzM@"K8/\;6S~7㙲-},sW_ꓛ҄pJ9Dkp`Fd$(QlL$?'gr 29[g8ÝLv<ĪwPk8\}U%&0PTh?2L7[wa ͰP6{c 8\VUZLAoAWU+ӖTu˶^r {ݮLml"T]G APH ]Bt1JPmu~PKSF9 e'guiqwt/widgets/resizedialog/__init__.py}Is#9~nC1nc6SDLUE"!2J+T~;ô͔uY ;8 kcgϯ}7lӝ]i_^koo|_͗۳/@n6:Clͦ잿U q7B/m~O"˦xjiꡧbml_c{ nm]Ѿ_CPK(M\ڔ]监ݝVvgM Ac[WG)MMүm;uW{3f#*ib&G[ d`u-ި;)68и'4J?Ԅ`wFd3YƮ܁/kW]KRnBԮAy:A`Y|wsɉ2LQ>%2)? 8&+D6{W'Km=/ͼ4զwVS[wOM~zSۈEC@ *ǰy,6"|%ŋE4ְ e k]{,z$xSۨ%VՌc3rkDD|Swp0?3ŋ ك3-:_$A}6g嶞+e1X-|S.R?[csؖ{;o=OCQ[h-.\Eْ7".wHُ9;RX kY7/ġ[̨qү ?#۫Ί]oE%ն33waW~%{k^嵄 +7,ʺxHYq,:_ ɚ%f0M7 ܭRyl}=rgoб=IO*vQ4^{zUN͕^)w u\ eǏlŚ^f]S4MWxt߂!= G qx CsP4ucL}SnNωҢh0hwp$7u٭v0M˚|~: _Z[?ޣmAT<!mF +ClCZr81hw> ֞ҡ~+y[_\ 1aM.9 n-̄eJS!O4(QIee *&m36Vv~̩tCk:rmfqp&tsWvˣ(__֜W]!6oP0*4ԟ=T1c8luyYAZBpTM~L-jGGj Snw4"&(A~ "&渷?*F~'3/ˆ}D*L |XqH*$zbjz`t [DGᅬy&m`%CV\R(Ml9{aStbI@[Xf0y2!v "ֲ)!|鎾>eTzSs\Bm/,a{s8c@s(PBoHTE=}x-At' i g3̽[So)9:Jn,;"~ -y#.n;fE4MS\۲c ~OuY~O1'ɇ %hwvw܍~wkaUU{~ڽ8D~@x*)`96"FPC(2a}_|~ SAp7dً9kUx|}*d8X yBEwU6Bf0bt0f : ){Rm"+Gj!^G(žOoa!Rԛ/dXH|!'!0B c, }a/L0sZ5\"/:/>rY[;lwvN,8H=0`J܏mv}ݑEI2 m ˤKŃm!='ڋ7nk֑kuV Uْ4 QQto$ RCuop+Ke`)ΊjWQGiSAp_(%ϕBxDzg54pќHToλ9޿zJnGk e'N F:q|^WJYs)i\y2p cL )80Wp,P#X}`"TA֎vSy(SDF'sDF('2TG9Q:JqTG9Q:Jyo8I9t癎Rbheb+>hs"Ӣ^*3#Rb${Ho^gK!Q4"Ds!SBF4" E0V0"L0S%#¹_(!LeR ȯ|x_.VB*>>@I< $q? (L}- oJ`>0@4kWV @og,諔1kbj%eCyWn1I?Lr')"!o>$?: a_ ޴y;vN![,(?WlgOz\qwCAʪ+DߛR1~0A\.xGЮoea܁='´'mZ3XQw ijxŬVUl!KS4kCZ嚷ӧĝ0nWhvrr>3I9IרLSfPEtEH ?eҕ]"˲RT֘#@ H3շP.KE緅iuxD*67}%\nh-u'nn*ج:;[)bǽ``'E6&-[EZ=+9zN@e)tǏݝNpgw,~]p12ߎ>e$3|18i,b: /B|bxL9̗B{-KjkCG|;O.^8x; 1fS.aeh6eVYG~|i*d4ۮUCqWaB.`@ΖC΀:./H[M,/,@ jѣQTűxhl#Iq*5i6B?99*Ѳ躬c#tQ|"c677cQlUn%2):7tci谲%2M1-ƾM*/^$U~׀k;prLj_\$ މd}z/,˃Q@>BB.@"_;^P+<כk[mW16"cJ~puEy<<,4'@jxz1?Tpl ꎸԌxp1{nJɸgRo ֐ɽH77_ӧϽZQPЀW!޽B2G v=蟿H˶Cn f|p矓"_5"b,e;({$Aڬv" pVm*MuFL '>g%hύAoD{my9(~(+$]D@^qtE߶(̄\+S}6)VU,]o[47ʞ G׊#UxWrؘ(Ё_ TBʯ7lvu 8X#J_PҴҁqBc:plhIb\U0ph~P20|H!][Io.ǚng7z2H ?F ?Q0 .=|3! ?=5{= \ $$yԏNނ'sN;e|6әDo.*'A{Ґ8(5Z=wn%7$d,TnxOA)/^vQ!ܳn΍0TpN"? ,d$kV4%*E!Ҿvo4 BΩ5 _wu(]ԛ;_{ Ǣ.ރLggxpٔy|G?4EDJ 2yθ|ߓ%*A{ӈ{F OGr_%1/j2&!~՗d8pn.^14ϓ!h[ÈݙPo=,Q1c\48zl"  r~R{"e!g[^kv-k p-%4I/xݔhM; ?b6R87vVx&&M\SlWuoZT=a0X+R&agV_]%'z9;A/&qx\k`>tn){'[bu^{Te&q6( ѲWQ~@bs3Cqim[g5| gn#=2f}  2[?I2)?q4y_Pkٵ|dg &ov(ɟPӟ ~* OcCk<n ]@ }} ^f?B$5M)9Bd`O`*=@A; bx>)$?=w^~ym bV1XǠJ*xA aIvkї7}Ƴc`kq̲*q w;_O)Gg]>uOǪy*fD@oQ֎bT{*8x3j;I[o/&9fAyƎvӁ<3]Ĵ_tЎx߯kx t؟wOa yjbk=%݉0z);?<+J_oKpɉ9 X&h.܏`y#_ܖwa\o3pêe-3gm5mV3VvR.ʁi}WI4.@PKSFŪ#P!gmguiqwt/widgets/fit/__init__.py}[o#9{ pP^t[`l*{ʶ\=/F:Jf._FAʮ^`pg( &/`\xVO~hIot۟4mYOϘkxc?O'i ׫~YQ<>},{g[qy}RQi"##ES! |J^nA Ű:7ğ61___ǻ7S_|\&3ʺt*?49Ӻ;IښLye|}U87Q _֪t*}_iW726{[ʪh M젇.YԔj[ɺ+禸IN\)1)~5M]r]5nBW 4ЕyVP YذyI,?1qE^̒l2S:;w-Th2NhWi#Ng#a_,W>R4&9 [0Փ8`cv%YFV(FS(k͉UE_S*]W#Lߔ ej3lƑRo uj+ee:@UX$6j DO'3GڲBf.tmD:+kːwU?h&^Si] {yc ꠦyiy7FהsFZ=}D7nɉiFۮ|_2}ΞTmPuZ{oz MrW?&eO8He5j}Wdz<>b"(‘*Pz_89&DpEQ;e"iV>xM$d_bοH7m4#|em_Mt$l:|1s9r_ɒ[VҺU[= RﲭZ9-l.GjYJ>زbhgHSjM2De o:߭M g1-6dۿ sL8=}\d [ޘa,(ꀞpdxALf.*3S:ooWFCG~\@;Z:Ccͽ+`2ܬt5(9?;8slYx˚EV W W0L8&JƖJÊx=3{]&p^RU .2j"XP:'&/QtUfgzZt4כ09}t5Mw M mxax6;X!Tz uɽ Cc 3:{u-d x8r䩈!K9ۥn?L;\$"߇/@ [u>Su6Ϸ2#K6:7 ʎWCh]!?Abұڸ-3o̐pE%V=[&,6M} GHD ăo{ '^Uw΀mD@9!g$Û/Tt3e[ 5I0 8\dG)I&6\p*|/S52Z`{BLf:uUwJDnx]{bi9hlam 87(aW]t ` d aU1ȥ^Օ 1]'DeTއ<?3vu;GO:p0XSpi=/oJ9׽:"o7]7#\k3ZX"r E©XDT1ac`S¦j:VkK8Zhݚ:R/SUẌ́(JFSvMP4l+rR=Kc [vsDAnm #aw\@DLߔE>LJ/gyYR #,7nD=ZgaYC))oa'UKS ?pE2.]0ݲ-s967sԋC^)crntg0Jpԧ]VeT2tZX,޼ g*kqz(]eb=E.< a?RuZ6tHSs0ZԔŹd ..*[[ͅfL(i*tox<广0N]>'Ltg|4gRy]k"7&9g44>l]4;k1 U@iƒq4FMm*Ӏ&eALڢ&t<b9>dBR+].^'d 6H\m*EAGj_Q`vll"mA>\P):bGxJ[$bv@D2zioNHPmWքz~gyAh.+Q/|*Q/ȧG$e7`p;a˝k/N:+`2X4eĕF N%TrL0 8ep,hL>0bp. IR2^θrƽ|.q/c{K/gXzɆ{K/Xzɣl "v32^]\&K6DʜKK#ddWj). VaKĔ9b/VL ϸeY$^lx|nY'l>,o?}5[bB㜸wkXyˬ(im҄^=9qQH{BJߦ!GUG&a{|rȍu2$G uJ̧zc%{vr {d%7͢IuE.6f -Q?g}dpY̭HYpID[/bFW L:4W]\]&6^+,)gHP'>ȧBG 1YW,}2adt^.bñgl+m%DBV K%$BH0BB&a.i@8B3!=_Þ !ž/腰BqU Co.NFp@ΆJbyz`ʎ%ZaR!/JcnMu*N`O@431/m"m`GөOYxH84/DIxYLL[AtaYL2&~¨S'Rm"K+K{6O: 7W\ư;,pE4IM\E#+s6Ç :~ 2 eooH)5c6F?+nVP1}bkʾ*X n}mEp4j<-\`{gRlI' cGy8p')t䃴|˕u6f؛1;w/Έw;>9XqsI`+;8 >Y@ ?s)]N=ۮ}}lcC2tΟLcNz6%^U:k n:x̰ '~SωK0uL}鷧Oوөl `m& kQ{ hxYPCP*ksa v#V296SjNLZ^vss])ՈqnT"d1K:Teo&Dfro$}"zx˾qae=NsPg$FK$H ]WK6g\Hd v/p<\>nT/$SzFIe؉:[]n|'%e5C- ά;-C)~cJU}=2ǯ1e|IZr{߄ H,yRL0FAtq!{KiD0Pn/ϾJ2ԏ_yLyegfF*:Z䙅w@ChCDQ|*Ql%y[+q-n-BbLr%BmJE)*&x/Ĭ0$k`hbEpXvfgu;O( 1v)=>E#S{05{i-6~jU杊1'oU胱>s3;0;N!6Fvmjxi g17U9^g+ٳhwXwѠDeǥY''x9F]3/+N wFv\餑OvN6ٝvE2:SJ&KޡS,/'GS'r!'.͏pDxwقF`>#+x_NS+Ğ{F8?lLi1(\^ ΠGBSx?{;>싯\l`.6*;[fu~9]>ݛ;U/JF0L v 9騴2sX Gm!r@_m7yUw1 swwT&LqAu=xF*a Νdֻ# 31  C' `zΘ6Kr]DO75ΕϮԦ #!}  0r4ݮ´ё.7 Mx1ifDNɫ|kmzK[Su f5.Q.A,[M*˦3 r']"Ocwtbc*J.o-p!-^ã(LMC6 PVE(ScɌYuuI/08ФB +H\Y-ר{q:ȥ4]¦ěrSx;(-2uqܜ~;7y"XW#_C9F^g+-^T>r]W=n)qN)w-M1!d)">z!Hx?T#:WKq}7 .:3 Z _"z[@]Up#:ުد] ?2crZU,esuYF]̡`7*DBn9aߔ`X G|UYKdddail)M0|_e.ݦ߁3vWvd]o.4JPsPg#PVV3޽Nq2{+p>SAp[6qn;L7Kj(˟A>jGNLV^9MÏo^}@.]S]4;- ͘e wqٲ#(y$FQlvfITmWGLG4Oq8 > utgna+ݼ;MpG$:0 oG"TWyhl!ߡSŋQc}6j amMv*z|Ըff/kAbg;/)12+xC$؂a)_o0t7#g )5젆qBO !$:0$cb! G*+ 1‡Ì)OНI7d׍p(&$BȒ6;\EC'W5]{:ڇ 9ik:P[drqݐJ˓qx偒(zh!{w1^UNr2zO;}XzʡF3'0MV46u ®=3\D rIәO4YusO؝6Om<Kȱda*| h ~|4e*~@y(Uz+$}Қq53nI?8gcAG̈́d #em Eaш4P[=xQ׭eF)f.VN.DZ3K<(ɽ'"9V}L1,) j l:mޑ\ΒeSxX߻"1(c(2cb ˱} Mߐ9ҽqZ8 Z}w.`(ک IWo]dƘ{ 2r~R;"F!'nbwZEsv&-k`._$95Q+΍ ?@4dCP^\=8Df_ kUs}l[k `M+(\&;GV/L#j\n cTRT%[þp-`2L›zAݙP2' {dk2Ғ& +Qn@Bu3s]7\7Gkս484FT,xʘxAyh0Eq'F?nK [M79)hMbY?l;Pr?]J?"Czq)&~G3 ßW7kTϛgb\$Q!K00a*=(W l|jlvA~|{OU |ǫ;,ۈ, hc2^` ƭGP&Òd@ڃ7ye9Ǯ_Ý '-,b#2[]I>a Zֆ`?w>9MkVa"`b|^,z v,cƹ{(#dp_-R8:Igr:=2mWL{=niX^!MS3ӄ4uU-~,ܺdLW8TG?94g;rEc"r燌}9 '.mb[ZINVmLto,q_UUɚĶ[ꂪR,H Eַ]' \Qm?_PKSF i%guiqwt/widgets/fliprotate/__init__.pyU]O0}ϯ M-/Zƨ0"i"7M.u̾Qqڲ2M{UicUkCqmP*#*ZxUe'HQ4S6h4++ )^Aӯ{vEtlwnL 3 RZ"<1mRX_H'žWu~e9cxnjX 8~frlYݨN=*6d☉:gk}aEEIa5NUS 2uRL`vu[z/m;%xj7_gwSIIXK~;i]u,é>&@Nuh0m 9j+5nP+E6LTh,MK {tVV8U̐Q:K0R -̰1Ad]9 ]>K4 ƥ身3Xp퉟v Y7.cJ>1+ 5FQ&[5{vxr9FA #*b &9RJpTsj訞fJ2m{Z !:- PKSF'م%guiqwt/widgets/rotatecrop/__init__.pySN0+rkA-JTBq߳IR.̎ǻ#gjMq>|eX'VKFi*`E8N`Ns ۪ͨvPSa7c>_u⫀ΓH.%v ÌI%Jy,/<)'(Fq¢$}VĂ&@MP'fv.dZSZ=j]ܥrjc!.'bQMMR lA%>:\GBGstf>ܾqUE(cQs&p( -az+7$>6RzoQRbn>gomF ,2i;3)i%X7 }xdb|G3ou}PKSF{=t%guiqwt/curve/__init__.py}s#7 y&vgU7b(-%Q٭0J$DU됚73H3ÆiC#bZ=7uS"8i^x\b"Vf?,7r:Y-~iu?z?ݍOVAڳ:1eWEdY%ԃ*ʔ zhdmk?:_jU >^& \퓭YeɱhjB[j֧Ѝ8~*RjV{5@?bdm {AoICg%M|}=Y]/7׋%?#$9Y/Sʱ_>M'+Ƒy5+̽Z|k6?\_ͺz\?H^2l/[(6g %7m!+Ïɷ*@a ~;hAV3K{(/ؿ..]u]o(1AW&RǙNH02ylS\r2Ylˢڰ7yi:^ݤ[ 6^1ϵ Y d\f?1z'WH5 6uev- ]YQv-t;V:ɸD- ?jL%6Y""lCV;<`Cb7W̖Ӳa13hvzYTl;~ %"r\o=_W=~YLgKf/OWKn&4r6.%qLB$;nWs s\|GM],φg{YZF:`w +~.м4OCS:TtN 2=x؂0({-P6)_LTt˷<9 z>3F0jHjsE_UzQ֯G/߸+W!9K 6tSdy,}:վjΧw5TsӲ,ˤԝ O2!5@N/WBKr* XԶU>h+brqa? $Zx0jbEEOs0%Sfe s ~wdcim~mZY6ݤL[CMpv G's9eRw:%.MVq]s0KWdPUۦh$j϶ۮV5aNdc^%i^5VS&a/c]P<3m2Gߌ2H'h]FHg>unBe!ƴE֬LbIs/*R&Fǜ3jf &5JhiOCTL6?xW0£yy%5oN oRd<0 |b]W{?^6{u,_ʀYx)dٿ¬@*-_ߨA ZrsyY(fV >kYT\?H #m_v4ԃ/xDE?N'tAy;p?òfu=&WFGG\/7S 5?D*7 6 M#"%OBJ^Q߈t,jQ031U#pU^cOނϨU?V t^ӬSzWXb!{=COdr0$,Eܚ9#ɳCUV+Yi⨃MнBH?:HnCNgAF\6093ohkN4[d첢" `aNAŪ4f(]eC'P6ʹZ'%ٞ`k AB$N(&SSV1>,r=d4{~?&m;R A{$ᩪěrvq9=8 R{2DUk//_\  H̯B3q,~Ń'zt CȒY ȃKݸX$V;ȽG{b)y۱8!]QdߛCH3_93</?."LމCP7tdmmh#Sw~/ v;[PtBՅɍ^ذm[o vLQ]QC"j,{I-hND>iLGDaX@L;.b1h:G@+a@%KPTsͅSu- +1S*nmf%q]fMS',~59J*V^ n'%.CiL~Z.'rFlW :_O 5svP$n'mTZ|* 4 dJ]%DBBq~ݮBFǐFl1+M`J#Qnsi;*'H}z.])ٮ2ڑd6Bg\Oܥad57ʾ$cl Fk){O`9evxwE*別yD\i'8gp(C<=~Y-,qSVE)WkCKrclTEyaI('i \jkn4IlW&d8GkuN *ǼE4.zHArs%B4/3$ xO ~7;jBaYgXS7^hI.;Io=.7>T&]xpz2yer Yʉ(vG; mpm0vڔq2@6)LOlZ 0~ViA@zxYd.;^#E 5r,"o;\?*6I/vC!, ǚ+ox(2)jPUF_s+Դq]}Z@T?eSf X&ҖT]2㼎Xq=ܨvgv~z Ih5Q{Y-Iϧ+tS%c6 %m>UܒNOŧ["ӴjV]Ԕ*b͌#JZ9msb5SYcyk() C N\88oF5|^g:  55ʳH+W?et9.gm8`ׁ{6G}F (1sT~^@{sˁ2vh/cˁ2vT=]/RGw^59k^q]/.ڮjgmWЕzzeTWj!9f29^8iuPq8WNp쥊3n69/C 69 /JNz>ޘzzI^@@Y[=+s[fU_5UZ&$w=RC+OIYyx pRk(avg]GS~@F!Մү,|eʵf+r߱f&Ο.o#q_SH>O(3|^|'n0&ĻiiQX: AYA}xa)vWg @iA{g€V"OvXisEPܭ3;4>:+sY䳾]O?SbEm&Otc.BPy~[dEE ]NV4> bU~0xN\G ˡ]ߞ>U#"4O%eZ3Bբ0ҜUf/B0Iv ԰p!Y8|e9} sqZ{s&^vxIȌ98InT&sY#,-Q\CCA9gunP]2us|&l ˗tcs: hQw-%e>NJKm5l;di>Glft)#tp1yh Ә֥D  ?`xGϾ*ܠBҏ_tLueJ.jfGG*9YU uQ;Vu<)*UӈϽ>UTWL?fےU]JñTS(YӡՒlrFy_6kZ5v6"kmmT(36OkwsWh4R>.?QιZ}Hdg)THltžT㞣H-oɠDiiUKJ:}e&ѩdnO'|}3[®&m|(^oG8MdrT#z'!!xN tO^+}riwٗBXy͂jY2O*uy\3~gA1H(CKf )?6=FŽ+Է%.Š]'׳vdtoM>NR2eا=/GmݒiOp5^1qC sJY  f~6"ٖ;^m3k]i~!_.Y{{ ␁"LHy d3 Lƕ⤲{EN=RՑZJn_][$Z(zX;ë;c6bgJ>7n(-} !ct]V>0vSB+JcqսcgEnU)B\r K]2`_Fߢk젒EҦZ2`w FXD/[=K%5O֓@Ұu"n}e}[z0NPh ]<¿ _efʲ|sUd`30ڎ줋x8{KcI:_26qQTlqՌwSR0R!iI^l5#4ϾZ(i*׫0{;d#7}|(+mR.ͰsOZD({)0YbWAPBIY`I@ө4=_oL '>Wi8Zύט3cH@ԥ5L^{kYm!r"0#\wuWZ-Yȏ⥨f6{`v$)uXQoV1<>iIkzH={gxJ,F\?`t57HL5七ޗZA|ȥ>'"kEQ6ʐVMxc1}8Eia&'N`gi:L!|jpZi)K82;ZEؓ\t0~OGXx(_ӫ_V)sIz+L@+-OJ-wȹn)rw]Ή4CkeϜVYM >ԛ$صgpkO!J( ' |"H[eOܝG'O6<70ui彷.#:I96Aך6GoEBF磾R5+\:`#E).^*NBW<` ;PqN"?* ;n{0p$(LJ) E-m}f (~+CE!kbiz󋊑uJw3`k+:,XDn=|zfY2@L=JjfBLzsuZ(ڠ֟e>s`- R=OIFEm/0v,{=o߈13Wb7 Z}w)ϓA#n-[>oW }EN/*5 ~}{@j9;p-=Kj Uҋd J\Zv+! Y!4`~Y'XjS*\ Q[^k"`\k)]Mr9}o3qJ'z 5N,8RlWuJC|u尯?\p< 8rTu^foIzayhnA6b! 4"wǤ+j;=;=oFRy2|IևyQ㶔pi9)9Zr4>l;PjҮPÏpC>d">?n 4. h m>z q9^LwS##"9QZM(C'[Sj_GRjYr2 gEc2"',[\4%"x}Lt`/#R3ime&y \[VnzR/.xz[kb[g亰+[m`u".ՓGEZ$?c?$v߫ 2QIA7,~aGm1b^RGdz8PKSF(guiqwt/interfaces/__init__.pyMN0=p$6PYTT$bk j{$==nBh&X~Ou# H,* `RXgʓ_ʋe) X3rP*jJ8 8T{MB[K^;֞kKddHOWvXHaCzZ 7~ߛ[{3ijx|>{1/-?Jj،c&5tVr2%gfT8qMwO' PKSFm݆$ guiqwt/cross_section/__init__.py]Ys#7~_qFţE[ejuQ*BdYŪr8~3@JXn=#|3e?[)z}싼ϊ2j@N#ɰg]ѥW79 DGZץ F:+*Uk*XU(M6^W@|Gs0GESu&4j])jRrD'o`hȼ/%wL~tyI2:QyUթ\_u[{e&ulpIpS$2a.RQVG34C6} r/*z*գ Mw\`>Y/K@>َ˼?R/:[v8]7tt Y.Vїr.5:#?KoA+lw5E+i=柧z[Q:~9jÏ *j/Y^v:>5֛ԃxr=a:nJӯ! _/uMF?Lo2|R?+PEn.|z鏊c=W (K= s`_H :_,8M<=ljEhg%u63P+:@RmU&$#_cR_rsg2S)fbHTWH tB%]m f?ӼX*Ċ+_I 4|l3QnRXQH$|$o]./F44܁aB(蒼R1VMDAB}y²0 ⊙eZ0r:[d|]?]?_rh_Y~͕B9WyY Z(RePd=!,bLF$w>&c+"~xVy%n"XL_9N5ۿ~77Q;ӲH[oNٟ)6?hjt4e6~]jɿyVG[H F7Ρ#HKQXo+q9U(Jq-ԾwTٙ.FSix9EP.K>bT⛟Z῏5,څ޿umQ|g>&qޜvyoL7O1'+{Ɵ6gҕduSg7Zg6X'|+s#rc3XM{..C޼WIb8s,,rDeUOcԤe]m@%jK[CW )f`$e 1jR{"wW\&2U"I|x{ 4iAFb'āC(2' DUQі+@mYNXI|.tդd XAg` KҋRaO MBbŖxxH<# ^2,գ*us$MӬB m\ ${^&rO)e0;!vn=hu !Bڊ{ANe-ywttNJY~MmeFqT+W$A4}gn]GxjFK2'ۚ8-w<ͳ+5'f*ƺ XukӟZ:RfuLL{r~`1[S7^b\)rS˥ߤ\M#]M5㣆x^ZЛĈfJeh|X:9'rfk*^K̳^鯌$.=iw '5zO>ecUU~5QU\&VZyV6y5v5dƉ1s[fnUT-iL'P1Ac id.lv޸оo:8j`KVҁdER;iX?D϶4c;׆Lee9=QbDŽLtRt!D}V?kh !V?CVaj~YǍ] @K~+RA:'E(m!9?I s+@7xΓd3z>IMTc`iy^5rу0sh'ayeO?OA7?6QoPp+3_xRjI $m,w Hv\TS$n .Nxu~ qRRY&Et`S(Aeok bD%@Qxz8ކiS:#$ kj &B/eVQ^橣 ܁adM}+AqB@E{_-.ŻMjrOOBw@fѦBv"Z&y :1:6Rq^F !?pem'zL#%A˩`k[cźZLYottЪ4p >'{gi Tw4&R$MFiD ,Sڍ4 '4:PFOx8l,2'DWMvLB-J]CFUaU,jiD; }bDJ_%:Qn`Ebj,3z'rz[p֣d=QzGʳ5Sp1L6сs]=O8b(oNATQ`c&S+6J@%˴~'}NQ[ /_rovn8\EVWrF#`[jZ+ۛsM7^`sƮcqM/ߡ#r-]MI27_BKl;siōqx 00~&`U5>݃s{R4l A7,qT`Iu0Wߜ:f$0?8a c2UݰvvW:70_ Bʔk7d j*ư$E Ü^t]yʼN0[7 ܐ67VLӰ*4) >`'?}*,d23<ܾ%cۂZ9mpU&zV&?r X )a:Lr"Diq(NtɑDN1=N 1ĈVIL ۡib'eSE_ֆf3QiNK$³. M?F2^ g3x(x[E#4R+p5ٸ:tO3=9%Cad'ɘ+ @()4n5$TɍWKTn,Roa&%z^UȎ/IfD,^d8SDA!V)xqW%:$Xɖ0mUuhHځCO m)2n;6aYi<[$九9̪qق"aׁTهC[ "QM刴gte< Q7qxKsYJc)a/k N]|v<8L ]9jbxQ]VBQLjRCCɞ*00"?0R^YJF%:ԓI8&a^c7,_h253mmGR>m)ұC)?GSa'Z,; C&g0Y,m# m֣n6pr(biFjzэ"ZUU^zv]8*5hV4ktI]7kuGp1"o\5)'c=u^.DxT!y팧ev".oKOsOQMgX-&R5 ^G(8ŗd%a*@/!*,I:0nޱ"aCgF>]]3(ܜ[fΦLO̠Ƨ [FʧIլѪ)Uv*K4sG8N漞KCmO*f^[hihv)G *Yh{Bk-Ph/LQҸ)%`-ٷ9C vl['`ǂ}س9 8}X0phA#3Mqg@FQd->(2Ўr (2ЎR ,(C;JYhG)pf{$nmG)qֶ8kQImC[DL3Q\'pf!`fyaղB|ǙD_8(Yd !})RS95Mo?MgQI/e|uؤ(bN=9aڅ_S%GD{e;>ڏz}S =?m\ύ5M"˕QiҎ|R9uz=5R@ ڀF< 3۬Ϣ:hQfG$P?Due!g'JY(7VYQ^vvBz`(vٌk~d}l2vٰvCd{ld6o##߱@ 1crP6f"bXLlhqft^BH71oXDedN}[l&0"ж%k mгG[B# ,#KG~n ǖ'|j g 8.,UvBW8( -C#cCY;oR½̷vır vx[g哲t**NHP4A6thKЖ[Ӝ- 1m7\-~}&^6ϱuI+ ]_O}T-A:[ߠe5Vù7nUU*:6[>goԺoz2{&^{zVWJȦl:XR%)~$$j$t}xѕb^VJMVt(ֶPdKg ذ)k*·t5 8t:m 0^4(TvWZ#0tGX]i!}?:+L}eiپo@}8 va(*cWV @IN nv"W)cJbblJkݒ?ՋIaCg7(`p56vKq;T9:U,nʴ-eǀf5 ik奊2P¥$6CPbNe4;k:.| *ӓps*UXIרTj7@45,Q\CGAYcen/C,*ٖS~*/\'#j`7ebVh}.WxfhE;dvwoWw֘gL9w`a D:%;&`fZ>'edQjUca[!Mshjn_-#͌[a{=9uaLl" s7`0j_]Op q|9lI3cIm |.G?jέ5'JUGKDe$+@ZP)4PZ)Q[P$E )/9̚tE_6F PڢO(=ݡi.3Ea]GL^>&{4aj:(Zb Ts*%Ҟx rN.J>s Wh4>n!q_ehg)i*tBϢqX v̤DI%}v:vQI{ LMtjzcקZ.ؙ%pî&{t|Sbp6̙Rs9iYh:u/bXx^3ۜ,8laK@W#tAWF)Sŵ=g *qƣ|h64iZ&8?wBxgKSt_{9>7N;]6]*ծb2ͧ^ݨlf]4 jbX9*6/wݫ(8OS;R䒜M}uӿDSu,MsFVug 㪯HA/'X5|Ҡ##s9KIX~?ug{~]G\l+gy -=Mk*Q=r]\A,ܨ,:/ 8e|}h7~9)ހ0<wm.g5plGmkGG#S:YX e [ʢEҦZ%gK'VVRM̓$ 4lg[zid*碅Gs{;;̨e ls-3<ꤋx8g*i}׭Lg3ןwt,?iLJgBS hm(zmRiB?ӯ= rpU޽\ C/N> Qh_\횶pk; %NL]gg\%p7-$(i^TZJST}g/p#< !5Bds@\ԕ6LNW#ʼn,;--= ;?pwP pҹxG~.]/AWFVv#,giE]ЭJvht⩧h)E INL,(Fl?)`wb2]cz0rg(ݗx+4&MYAiD 1h-<5?jGk(j6b #tSh;ڃ0Ijjn@H(L@OZh6O/2s}˕{: 2P~*hqI:ey׷+L@+-J-Cɛwȹ\3SXU@epƇ(žyQP .=^m! ;=߮:s9@{7R}%UZ1yį`D܆C>­6_7|'lAךP;B_l%}R1n0LJO`f3^+w` ;PpN"? n{0$6l 9*,_Ecf@ '~+AM!mB5 ^ז8(]7s ֶr>E]Ogfx;x+C0wG.w =_:KLuP뮲ZO=]Lؒ S_pyI1pa]ȫ/h;se@Ѧ<&BzDB?6DEy1:h&]?r`A/Ѷ_fb/+,vHm[f,e}.sZBҡ"꣘v.ѐ}O0mUm5Op6? DZ!Z,r>b'-ᣵ^G1ٲNC&K_+^)Jb ͡_8`[ У.^2ߏdm_-(b=ݐ XD>-%fC1ɯZOD5? gi526Om74x*v4c=&̡mzUg.0i^gpLgi[?hfƾzeZ|yN~i^2Sb_{:OGǥ/|Yr24+gEcR1xlqՔp|d`OL4ĶfF'y W0L3tkW[jgg-53r[VRڋieI4g-E-<2۷_wP`W(bu1]?tx~7~u?ϯ>}{O{J,߀wKY?ulXGlc3D&뿡|w廦g-~X\1HBzz5+F RQ@6&}^jS. ے4&~Yq4% (%hn6Rϻ,, )fwܮv i >\l7ˠ1c իau .RH;/HA>U aP=++3n[l֞Riԡz,|=}ff5V5GYo}9i럠otKCQ˺%\[mRQ[=055YAsPKSFs63!guiqwt/tests/syncplot/__init__.pyWMs9+87>lj|C`lӔ<44+ilȯ0TR-bnZ;)fJ]JH& !ukDyEz IA?(X&^O8eD(Xh6 @h-9dc#~jxҿIɦ}ҫG2K m%[2 !LQU-\"8S,BBDs*Irђp`r{ {>,*zES^8|]Dn|( +-'ESߠ@ʹk=kF!mZ]\kYF;=A6OK660b]`e4EQjZWh6`NjӳI/=&$?&i$G\{m#V'ʫF05p?MQax?e zG_lԑ kʭ廟Z??W.:WWPN2 )_&gOJRú )/gl.^@w(BwEQA6Dl1Yj04C\(%K* ^B퀮ru@A"ze#B;VFS얞{>Pdv{791b^gdQ<@$mOT YMa2 ;MI,nHtpeO3MS[qN<;sKk_\ѤV;[5HGuXnKbe=QVvfi0HW+ 'F*8OJCiOQ9Ӱ]W+ρ=I"ؑ(IԂ= R( plzB@Y83O1|d 8//GT³q "/ ܁T*?o7PKSF2!guiqwt/tests/contrast/__init__.pye=o w~cm)uh!Fv>cb!{1Nj),yxh<^UUŵq#w^HʨѲf2(sCU1b7!kQY"3BAEj1όsG%^gaq`ILԶ㛐8sNYPБX&~B.Ch Zqs{{]R7h))ʞdK]d3oI|d?PKSF:(%^guiqwt/tests/pyplot/__init__.py}[o#9{ (SAmmU"%Zv*_`DbՀ 7^RzMP貾*4 oT?`޼rI6WeO?FUPK?}|A/Ryu`Q>ntf=Ya:lCSYmX1L?d_fIt6ud>vZvr<)?\MЙ.Ib: Elyu*K]>'A֗tgVMdO6I| ^sVZ%e?Cwer<*|6Yf>M8&eؓ4]n:ޔudz(U j%U&F&\OKVZ}@GT : Zʃ&dzg̍0%fMs0@5Hg!W } 8Ju*ySfR: SVWvU2jO;P5CP2i,g#YFϑR2߯Ȁ$oѣ".Wkwx NRUWUϟ Ĵ zѕ9FT4ZB]^dfRF =V NȐ\.`vu pV=%F|_6ԨS仿8OsjRU"Hżõ*Pn(YM/&55Kww9L`ZaMQ3*Z~JؘKbm|SfX׵>ܲ@Үz4YͿMGKHz< L\MQu.z%7TxgerPzHr\k YASB yH>1\[Nbbֲ>fjrMҁNt!B[3^!NjjqG^-c};?֏/7+jfVvQ+<#)p|QxLߓߓO:aku5F".iLÕC}(tBNoz>Ѡ/@ z .䀈qF5S" _t8ǨF y9Y45 ezS'LNq X7dMe/dI-ϧK]Be]ȻRR #s(Ou@@4"Km nn%,uSnXz]&P^R6v[Kl!KlnnӋ_>B':(H<(u"DKvǀE3o_.3YŬKx(;71,Q5ZQأJ-'Ӟ?D)IS_CwX5`q_g3Uf{n5{MbE$wtˆfVKAt,'o`ZP>e}?R,>i8_4[QU:kxª }o&$ϏۤܩIR$fy!h MIHTãdQwv 'nax٪ȅ+mL|@k[Y >Ik{;oaCY\2)R3 xUmL\+i*.غjIIJ3{V߇/i4bu6N.y@o?ѐ2+gʭ]gגzWcrh+M!;?̕_bDpڦ|Iwj%aNiDW4lߩRVT,u~k*sd[کY2H%-۝8QQf(|̴٨2W|Ddԙh* FDdWݮ@e00Ec1ӛzTIe ^4q]΍cACE;Q;fF@vwӎ$@Z;bߍՑ9 Y~]ڬ-i¾R"$fgkvdbPH0cҗ 1t) 別z o.k'8gpT6=H8hm)_|$66*![[."dӥE(rRfd#:NCRY\4Nakh  X'rE1v+`/FgI*.qf&/j6fG4T8ٸ)b8Vb:x)%8 $;=!8)L\xS]#hc<tS=h{Y=B5eQR9D2x0Yj󺬍`abT8\Jmoilcf)l99,ӃmL1+35V13`q%ptDg,;ȷ '*7񚂹1 s]jO=C?v Rumy;zE^e2UlCy}0@B)53(rfcu:L9XaNZJQ^!x-D$"t;KSQVyG5II"K4*1:&[h,rϩdUzJ\vi7dwߔC*m>ҭ"_69v!p`qf'/]u:ˌ6sz,MKTޱ t S3c+0n6L5~ͅӠL|c8Bgƫ>)ABą}[o;Fo -Ԙ/5[qoh2n(|'py<ёog4a|K}S$;SJ3^ɑZ=1(;&TA~`UӮR"v&dcOWeśfڥ5Sz]U->=Ӹ5Gݘ-7eaf6Me<-[aicT5Ɲx0{ &W8j9`+E $6JM P[eQ>Z3 ;f0Fݠ4g-fi ,-]2gX@~7a6Bf\P߂@;)pUUMUg-+Y"\9:>N?$:wgu\C$ &Rb% ލ(E.xC w{yONLQ qFɆ!W1ڤ9d  v;K4bz~ӒriJr;F2V쐻3 <`fokRU~d+cj{qCAmcu3>9t>= #MN; ;>2V Pڈ4fSPlS=9n2WiUg0B=)񩏆a@6C/Ƞ {ݐHŻWta ^! :ʌ }H62hJv ֕tݎ<?(R$5tN^pLGZvQe->*0z)0 a?t;>pss'0Zܔɵ\$٦1fH:1Gt͛ eOQW&N@Į*A$>9^SHǕI1Nz>ޘzzM^@9F,e.7yHLvIz$)럓:y HN:v, P:GS]ZW]G*}; aJeD/C];lݽ҅;djL?CO:QG5ul>Y!|#Yqeq.q<{~aϧ|aϿ8~%i*C/`f\7e7;bXy9v9ba,K贊HABH^N'=$ <4EiKXOYO~g%%mZR'QzvINZt`lkk8ycWF<1T,)Vl\pOOFO;&"Ph':U;\#|Rqx6wMn\>.}[#q,^{Y{f)7Cѱ(T#È[^;<[Z@BآPYT4YFAl[B?goy:}̯? . >` 6 D x$`>УipN, N9|+[cM:P}P%&@ƽ3fn+Rҧt;nZIsY-2=lL| RC$8xuô]f/ 5mtn@8ΌPz1̑~[ӣtEtg]tsE`)gu0ڥZ>ۓDTa[Jd)j ^k,Jʍcv#I ӇzPN=қSirFS]m= 7Ri@ڍj;@e.:RdiZZ06 yv >ݲydzlAb,ՉeYr6H5UY zT,ےiux<7zzJ4ODxM|ѽc$ӓݧ+#-|RKdhj3sOW^#Z?eQ\wk|d\3~g;m ӡ٘d18(_OM g#GS~zoxxDnwrh=|\2ڮee'妥=Gmݜi_C4.XoܿQBA|[=xF-;Gbv_0Jl=M?  3dU]D.ɅTW7ËO?U' 8neuu~'qW$x"_ݮ´ .7 -@AҬ7w~'o/Oҷu f%.w) afeSARMǔXL;tJ 1p x%;u <(אep[j䦡M$;4v ,8Rԇ >_Cu#T^ՉC#&$B. $wר){q8;KixU=Mɉ9#̚[j'(~Qہwira\H,| dpѾvRt>6#2_/UqUy@f8ˆw-/bFPܬt>?!o~&qd"B}7s|s0J-|EPO+ ^ p^+{{eoUد醳?2c22eC𺬠}Bg: &_h3K#r֍ݣB>,%2I{sU.ԵXZ߸%3a-ؾ*_HT~ ujmYD;9%5֒ҐvB|em{Z(' ^zM.@~'21juzeق(llҬ@>:?4\Áĸ>cP+UR?wC¨\0`tq wžI>mWfo ۂssa2=E?*MlOڻtX| r7_ 1m߽}@`\/v.͐qi -aFE({(fཋȖ=DD c' f7.,"N!"5SQ4)@@GkܪF4DH# D]Y%iZ8;EpGe\ ΏK{k/ʰTLʯzM&[`Vی5䰃ޗ퓴F|>lD.`\UbZ?O?hBy!PpbC>{ɟ9҃&/>K!bm<@1.Ѣ{O3 >Oj ŞL_|}K{:ڧWF}*jQQz +wC+-ut[LM;T܍[z}b޺ 9[Wth 3%b᧞59G˷-'{zWO Mҭ{ r-JEI;hf[eO؝N6 ?uྂq| ~*l2;mոIE [w/%AWhQ2߃#oܰߒ2nQKUgT ԯHWܹ@Uj17 ,[ڏ<S[]ѡy?M“V?R{OD[w顙v@D/wo\=֩Wـ:m\I`)<-IxEm/Q&FAرc h'#vwWt4fbeHRۥ|K`A/IXRQ=>=vu8-=XK4Ud rAm0ra\#xC%=pghBҀe dk5Ou+ k > VEZJDӷ;SnylB/:/&E<2*^MR`jo䰯?\y,^P9^foIzaF ,\@6I`gAp D>!7^v{f[Ð\=Ц{6jϳ\)cх VLO>C'Z=gUyNðI[,ӶcR6?CfƂ<: ށd[[Q,bZ\W׋)͓1@msv0s>L.ŔdYxi dċqaRf#kr 6~<֒g1;1p/v0ECqlBd;o<sxcp'z̲2Qq  Mh:CĎ8/cVam*pyj5(XڱTjOGpCW$B[oqԁӬ,'I_>9(Xc>#^ 2t!;"9BtWњ qž=5>MC?$v}ݲ0yKɘ  zK-*}9&&~"(Mz?cVn zM BjWf+Zm@uc}~(/t?7zL//}|Ky7coPKSF a\$guiqwt/tests/get_segment/__init__.pyKS0 vF[:Niju-Ć$q^TȆ|'rhYlj[k eںJ3aQeR8Ul3<}q @QC[PCX04^9w"BtIǭq]|M^'Ud:YDV$^pzQ֩mIҷ( [g)Ӕ^ں:L)IcOU2H4 ڒdٷVQ.?:2P>V}M?\{j5xٶв;wXaFKyc\xݣbH7{jh (m̞gy]yKmPEiXFy|Km:y2(,[%Q'Ozt83gPKSF1!guiqwt/tests/plot_log/__init__.pye=O0w $C ɲKb/5IKz e)`*]HeZ+rcqb86Iք$i۷fBiTk׭P걄דH|V V^iUtg..l/ujW(vT#'퉾&ڂ49q]fS:BDu=]z?fҍ2K b?PKSF%TO')guiqwt/tests/image_plot_tools/__init__.pyVMs0WpKri~3=Ǟ1$NNj$IL:bj=VIXrK bI&2R4LJDX&!N$P 䆥Sqc}-G:.ʚPMIG*ei*4O&#Ф}XV)g_.9;<푋4=s>1 8>!{M +%+4SI2 MJƅ6AI蓮۳Ͻ}!kJJk\Yr%1^defݥُi[43nEJWƬZº R5mMvncq5RlVm }<_XIj M 3aMYEm-R ap ~TSn2ƸW*neQw"p0wZ 1t"~dEdx~ ®7Μ񩄴RW&uJE,E.q*$ Z`FӤts*KDkTO%纚=Y8 0 wEWğע'ex¦FIw|S]y6-Ec}z+{$>U7V{%_wsgb씖,Y핕E.@cN :īzG>D[Pm1'߰lJ]ԮJp=Àb3齒g(^ĴPKSFmJdguiqwt/tests/resize/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ PZ\`  GsqPKSFhKT%guiqwt/tests/image_masked/__init__.pye=O0w om Ci@RR`,IL$$z{sg_Pd*c:Uhk*Iާ ` ᕤA@3%;FD'qyJP̔d7B!ot7 lbޗR%2u2j]WeQVd'Ѻ&l OF`o2OmCXQAʵKɡ+xbOO!%LAŊFV`1]Ƙ)EP۔p~Qj<+i*<6z]!"qAbڕW:Ft}wV2c͞@}^m0C?0zU4 |>ɲPKSF guiqwt/tests/imagexy/__init__.pye=o w~cnm<$ۨNal_m8XV}I=GÅ(y-Gԡ d;?^a@tŸL1ćj?PKSF(uW&[guiqwt/tests/sift/__init__.py}n+G໿B}p Vqo lIEn4 YV\t诟X2#2I_cVFD[.|s۴y|pct"nifdg\Q%(EKXKq@>jxl'0c6Yژ*ɂr$i|̧!$=>N_.Md'I>%s2K3h{,=U_$ 3'ҦD[V5'e >?6m[C/ss[>~<[\o;}:|{},.,:z4,3ecv#ڿ㋓͑=q'"]_OV!]ӟ:U6٦ٺ2(=x;KV/ ^[ꋫ4G9ߗLs/pS*ndnjf Ł-PJ(taͶO|}mMYQt0әx|-ԙ+R]dIwIRbW^aq{hYc-6!p-n Y;@M syޝ.ܼ[|rd0:ZC7Cu~{zwW?㫯۬JOi.xn$D:DEݕi6+ϩwE翸=!ӿoIX%F*rNX?8^Z@$E+*MM%`Ss?&w?] v~J_ɹ`趶YV$iU%_m_MMlx|wKye`x4 sNRܘ_$+# @|1DɲerSrSa <,+n30k4me7;{R04OwGhVT+VvP4?׀ྀ=ZZ"8ΕJg Wqmc[AaY 41Z4Ym:[1yHK%2%X2ٶ-˓dyUr)޴E қGcE L3&F-A_X2عL+^(lV-6췻Nبmt01`FHu[imuYGԼGcnp H쇳ʸܪȯ|&mb}rPl%_];-/tQ\eXk(L-hm[XE q\|kX)y;qm^L"Yn%天2+$vR83n|ԐZ/x[Raj"@c˼l]a-QpּVP (-t]iWi~_@5'J1+Vm}gZR9Y] ,E!$Aw.3.(dE H2g]8oZpfݎs|-:XUe$z!ݍ1y),03 `9&:_mJrE<ˁnAa@k8C*09:~լZh^Ϋ`qD2҇~6۠%EѳilnshTSoN0&y c^MMA޵FeIۃ omo:fOlu(l+‰U.; ^HMJNR  :z㢯hi>TIMWmU|PȻѰ3&OwxC ?p2MIW']x0oRNuTaDp@o]*`kܴf|g(#0w*׈&ٍUyxQO5A|yWy_`ӤZ| Bs⁡`~\e@i<7kjN cW̄*͔C)Lq.RN+`]&m 6t(1c ~i8(* q.Y1<+4}~nkm":o@QhOZYb "?rsϣ}/'. p"]WB#UÍvF#B;ҵ ":)TvOɪH] AZr~63arxyYQ=AOLCL`kd V̪ͫttڟswd O ewBg_ռU(M$@-.0:MJwoiLgٷ `+j*q{( ΍<3*ʺ,S0,.1v hzd5- pտcm }K=>&0ΰF\|CY1*!~Вsncm T ִ*Rma\J;pn>Ռ3|Ze-`f:f$0>yd)\ێrNKRp7h!naR;aזϓg} `I9渭U>Fo !mlRר\ =W{D'/k9J[^  a$@pK .vg(9+=r[cpFг};'6I c[O,tB$H =[bo x>?1pJ &+ߎ]ZPFyZ;]g+j;fp8uuPB)Ec׏MIr_ 3hgE QGQ(HoP+M{7T,\rK6n,P \LbBnGcadJ q{/+|_uNIg'l\r[:-&UfҹFpz]1;`XjZA@`J與Zu$b'C8ϼwCv8y:KDE7P1Zq]E-v#0aKkЦ{t,kMSdR:}3UEqׇ}bK>Bk-sdܺ.>0p]Lqqd:n8pz!f8CYpGq/;";`#m Xd&5˨gF;C O/UԪbX]2iGS$+v;mnCfK`l;Ċ醘bz!?Q/2a'Z҅V E98&L p05; XRN2>Pqtѯ:>̫Mȵ^Sbl$0\u0o(ӑ$hM'tB 7 Q)xY4x>:YNTm/ _(1Yj1\w?.dFXđ#|0WU2yFIIU ZQQ<'KDgE⮣CkF~@gPy;9;xTq T|@i>.鳪)U5fEGb]r@hj)NՑ)m蓑5F@ Djb("i\Y+@*e   p@s4H>R`$t̴bHF(G2X?:ʑ2Qdr$ubgr,u2XG)p=7sQquubg]YWk:Jg]DL3%Wjtbg Q3JB|Ǚrb((Yۤ^ 8<>,tƻb>*r~}5zPP9]gQI/*a:Ql@Ş=9N&[j?me!]K|tȍEiVi\t:K'A\ ϕڭ oxhJ6I#C0&MHRjSQFSe{$ qc P3c:/>sTtqϟƵ3#OrH8_%mڊ-eDqeDWa=En( "ba8UD83E#(ÑO\gGAB8 ENL*^򡗰aC@Dp'=q,񰘴;LK YuI]ժH8A#Jl=ARWxMZM$eܘ :u .n+{ꙇvSw87}uAW`EcOt\J1 Cw#)ӝɊDEO|kʂ.H|7Ţ(`𜸞:7V>S1"Ti[HHD1`ĩƷDC Ẽ0IRJX}KW.> %s1]-٪I뉗FѮzn.2cJ4ݍ*dҁf" tI @=ݢ}j&yeN,k^Q m$3֥gqhX緅hy1I%Y{sC/x<\wc\jIi'4ؕe1-`dQ;Q!~[d~dw|Y5,ڪBjdK>^G7xf=Y8otJhz5u`Lc*̹W}MU9 sA7-ӵQ7O*޵W:FQRwAe.,J]j 1磫^FfAuCד> 奭tx(Q Ծ=U ,̩d AҌwq$yF!( $? ZA/UQFE%{U=1luܵB F9}luTϺk*X:ϢqgH,OYs"lZjY'x%FmR3/3:`ٱcI_LVpǮ6ɹ|>PbeJ30wHd:/`z!<1eOFwkz.[8"8/3F 8Fg˩ʔzlsgA1ATCǕT_*P?Hx =1սKLŠ}v]ۃٽ5$)]" /PBہr甏Żܶ#SɊvXܗ~A /sBҳiGwTA||]?{4ax$ 8eu AtۗH;I`>foW;?޳V"~נNt.VWt?e!k*Q=r]=* !wp*KgU[owaOBpaG>(L%?ǀAf{E*3t99 arӐvߡkΟk̪bwX̪_h:i*:BS^%Dɞc!]NrFůklvBI71fg_#-Jt{Ð ;w Jc 2髻+_/MF2^&)3$]m dlb9Ad\0*/{B|o~G*[uWK bBo\\Ζ'}E aEOePޒ}m ^= 5|N~n(-DH躬@: # EB's;<&|tPd^"'s*1Q>BL`FߢkxRI~"i[/S=?i'Oe#t= CZkgzOxKK Mo.Z|.@~GLe˨eO+ +߀v!?:< B,T'@zlaS}kP3Ռp Mp -C{ *kƽ@_-(i*л7v~p럽H˶}fsg`"hӿA* b`⽋Ė-fAPBQ%mbEo60ѩ4\3%8YJ8u !kcë!.0yEeQg(lW#"Tj1UڒKWK޻lIEXE,x$dZQot{wu;*}qR잜wPﶷi0tޤ.,Y Q>?vr2?N&WF#|3&4t@4[17x1xDD 3h/G;50מNB1 #_w; /=Kӳ"̧'O%D7b $Wq2m-x(>>̾XpiX)ۮ %98R=4WZJ);䶺)|94b(c N5"W ݣW 9goWdN#'\`t͹g`kCP{7 m5#q>:~0Xino`C{o3 R(r$;DAך@zYϿK9Я0u`9>JqlUn+t8~͸ưV5 IhÁZ7=) wcR(X.,HҎ `ytŽwb}3tRomEʥ8uxO>+{{ODtǎzۇfBLsp|ڤ蜃Zyn91m.D#E] ˾-?BoY8-?+ Yߝ u%*vhA3i ݾ[IFt9HثIQȉkd-@5k[n͎IJe}%ZB"Yb׍]Mk\;!CŶC4!jdŎOfmuZa/Mkoe\NGؑqlѣoY/ lnL&KIX+^)JW)ث[J?`Kyqn!(@#ܾM2%@3C3ӄld%Ah D>"T7#;tPhx%zvo@Vwv`_?fI7t},{':':K[ngZ)Eg9 `ķTgNJiL5:p 4NM l|@7Y=Tt~sjwO:w!@{O?DBQu3(Դ٦ho%#ϲuy DmLG@LIL|d! qt@|=yn, <-x't eeb{.v_OHBh Ms@g7'vj IBŸ`%Xa,z8CmG=ɺ,8iAotDiL%l(OWeQ}C=b6_e4ge?: T{R=0rk3|?XR?د'kw뒜xتُWDz9H`yb[eahSp ЂXʺډYo*yMl9-lzb@ 610%Y߶4KcF"}n]Z/O~;O/xG ̇ ~L` w\PKSF+qguiqwt/tests/fit/__init__.pyU 0 Ew} YCB˜8d8mJIHو}Vr ZGh+NFz7Z{?3άo#͏@LPKSFcy+guiqwt/tests/loadsaveitems_hdf5/__init__.pyu @E4vi AC,b@˲b$ =g@ޢi!1qZxbY^A4)zVyF#֧ikR1$[#szli2죜nq,sG__oPKSFH\H<S"guiqwt/tests/image_rgb/__init__.pyO0+vjAIRխ]{xy}ۃQ‹CJB+:f]1|^\ ˔ lcМߕužh4dm2 ~gv]n1e za]pRtni{Jv, ``Hx&AM;2Q̤FS A@l@]8Pwř>[Z3f9sb e,Vm][Lƭ̤M%-b}PKSF)$guiqwt/tests/hist2d_func/__init__.pye=o w~cw m<4K +ʿ;)UzރBcQ qxTe."`%fŒ1@S.wvs|̱5!Uk ݟ.!=w]}Hg@WtH5%qۚ^vֳ: ?TQW:$ʖ8O+}=NMy̕7}[{ &oOHfځnڸ9sQ f=@zV;h%%=6.u5-%8_x/P7PKSF͆_{#guiqwt/tests/mandelbrot/__init__.pyMs0>&7G1C C`n=yT{*ֳä,O{('gw]kOhҢ7!(Tɧ5)+>d,]BHο"Ъ$1V'R[fe7ԥΥFM)4\$Mk$] s%4ʧ)iz[P{ivP"^DSGQ%ac앴H wd2s.w`yezӫ޶j J|l,ܘj$uևGxX݈L'-ީ* 3P%~Aٮ>V_j<ğ@BoEngpXk n;Rĥr% w¬ :u ut.z~A/fkv3 }u@t29,JaK,v1~)zGԁL/IǞܯ_>Fsq inQJ [D=PKSFz4!guiqwt/tests/polygons/__init__.pyuMo0>@ذ H ])!xqvZ_O؍d>GRE4SڒLsiJfαJ;7 Q). w[)ɨ>6="5RKmZb|X|b,7DŚv^VxrS{k.*?UiR{kA5߱]֧ti}tx]4<[4>=WÇůWO_79=PG%`%f}Zbk6[>O7nz1cs@em嬶Ճ"-Lj\ljwd~ئMݵZԦ\3w2/kځC󒻊''(6, lD^O YaWҬ18;ܥ'7߳Xe7 kYv+CꘈyϜ1ەܴf:qk dM29%HtWSYԟVIqei;ѴӶuY7tknA>f3LZ4xy:qOlcycl?UݙӚP;6WWZj44˷{Ӵfs qU0uZd Ǭ&xW0Y B8*F&U;5-'ζ[CN"p3-̃cδ8|2Em+$iftmixU-lە]4ayy0uY97ž`{ "?l]2zؿ/bبk s"5*fMCq{/c9̲T?Ն;CK NV4pЭyiW僓oeUI{YNL^/.u]2Lb51 0}Po[4qԻ.o3S1O8z {Tܗ~-qy&fbU04ɐlے "FGj]_c` QvMŰ$OEʷ&(f6@ªA_"C ٚsX*џcF;ݠލ32q'0RXMI~I22rY9HJGyk~4'=2yِ!MF+3[AF,!CBmk4YNkUx/Eic% tb^mBPMqgNl~i\H;Ok7 UNͩ Vr2a%Uw隺VmO͝myo9T5Ćj:Ls׌)n`9[21^+82@_{#4,BՑ.>7fiwش61%[YVPvqpɢ`~)VmXepyQ).7]$T nK s[K 5:}K)bb06PL*6blXڡ5,eksQ5dqV Y[o@kcq;m r 嗭 ݗ}*CWFqAHv ۋ v5*`I9y`nHOJ *sdLj:k6wMG2 `tӞ'sxꝹ LDDrsKI\b@K 1w&.1%&ĔV ' qŷnbu muMf3KlFԳRJ(HpnkgwE ,Gh0xۤHSŁUـYMcfp48 搾D٬삸+ o@3'mYl M[&+/܀]JFc?(7} +0 2ʤ: $eVXyq<\D "z<5:+sv8\qxTq}>Uc)ʚi^TM-(pϝ7'=R xśv$C͟ىc)m軑5F@ 9Djb 1ʳH?e%jΑ(8Hc JcXH,38XG9Q:ʱ2c-(cXF(2XG){('2XG);ub g#q3gR,Q]%:J1Dh:JgR"fWjΔ f Ve3H8b/QLYVۤ^lx|Y'b>*w5[c½X*&99sgQIϯb|Fuؤ(bGR{0sha^Hg/MGzQ 0CO}rȍeeY\I:H:OkIqrWxWug_4uV۴eӧM_,ҽ UBRK(VQ^vZg2A} $.n2OMhy(7jub˜&OG tptdJ-SGO{.A hDĢ+NyHLbyE1xVnb>۴+;QRK0 \KHWBJHP 0R 0 %T ϕByR ȯ|pU/VB84uBw8Jކ] M@v½-űăj vx[jըc,KVE  53&܅;'-N7- QV$/C_4s% |Ҋl7SJ{ zעSysc WF5)?f[X{ٳy:o+7==qGzp^_JȦlçWsPR'U9~dTu ?p}{ѕeKR=oEbPA?;n@q/--`ͱa.;k*)!Ne]Em|ح}s\>!ᾏ:3 C#[ӃTE_q{*+ߛbQ~0xN\_ ]'ø=}*FiNK۴2mKg,E1`ft4iVJXh?ĪQ|y;}"J̩vf&/^vbӓpsSIרDf/X)QBGՠcٸ[vm:/, ԉeY..>LuMYy02KdZ]hd͍l^x6c\zIi'4ؕUyYUUȢ ~:l㫲򝔾UեR%[< _ˣT M1妾S sa)6nꕸ9 c+vk1ZśAfm_]OHyy%:Ck$x+#yFUG0wW<_о3́87^@SenEǯ23H3rÍmC.G*TzJ4sK(*V%3,S<# DʺBf̚uw% Λɾe;&: {A!hk-"<3Pjb"=Mvwir{\45 UAcPϵIS=!#spviN>`wxў+ܠpnr*UZ[X2vnO'|?|3[̮x-lp!Pbpi$3|;iYt:/Bxb6=]+9=x-CN\Z:yw ĿA@Vt5%NS̞3{~W8 QK}߃cq\;Rt'8)Oa]D/8Z6] *;Xn~y3zx.?i5^PPF}r;rX<ms[q]2+\;MUB C4f|P(>4И9Cvh&Ap{ā`Č>B@﮽S$1ۇث'iSoi66 W$U zw2X5v}3,E=BC+"'2 ^FIe[8]LOA5lVSr傘f>ߗl(8s;y}h7w0ݥ{<h.o-0{1GǠ(LMCi~hYsKcY].U f{ _h:i*&BW^%Dɞc"]=O Fe¡A/ ?HNĝ2[ 츣Ծ5SQ7a?2:.]*V[5`ѽ+mDC_ޱetݬMJ .ird5nۮ2=*?Ή0!z]0 cˋπJ倡Uv/TzSGj)!n,tf: -S`Zt6-=4nsMޘ;{~g/McywM7Hat]VБCg:v(M 0V֒o谯F1j{DŽOQ<۸Kdd 7tci`%3U1*JIf5`ǎ z1]{ĐY'ٷoO|* }7}h]<.ĎeǨe Vbs]kXKM?:<^:AjcPt տn=qإ1FI|Sj1;S3޽NpcV ?d_Ao Plwï+.ϾZQӀWa{;d#7> Qh_/-ܚqΝ{9&.F٫(H.[vǞOj.wlU|u~;jp͔pRp #B>7=^gCmbaV:;UpG20#\wU5Z-[ȏ+%e5!ʔMZvE*WWqS}yro]gn{+H7'xq,h?`_o.WOӋ[a^oQ ޗSžI)5:5raV XCϠ>ln<kta$cKIob/ǚvWnetJ;F-6 9o"d퓯g\PolcMyqQBm}'5V9čNނGsO4=Zym3w\ EN$z`kMR[Y.ѿ!G#R1Z '_Vv^!+\֌{0DpN"? ,x$k E=WU1; ,_WHW B֨5 ^wFJ)f.V\cQ]330~/ɄP/{h& e> ^ +lmovK%AJע|pK瘝BBA}Qecqxa׃]>zi5?;:_YERQ=d >=+ٳDӀ!QcKG0:2p y' cV1p/ 0#v#H(daI6k7}eA9_㝞 'o,<#>un_7},B;4+`5\bؑUUe(>okPc3=d$,6?⨏YIN}e\ƖvӁ<3]iUVֽqt_4n/Ǒe?:O{/Ų0rr1_]Vosn;ӜuUM^Rؤ-D*>timy&8w09JYⒿR;s{Z^zn>k kk{ h6Yv48HcOo_oPKSFGyU"guiqwt/tests/transform/__init__.pyvF zn0`m]nMNRu0A"=]{_ Z{yFH¦IT ;f &IU&3Xe.=%j|?!xK*GU{}g]R}TU*}tj"h//ǸPƶcDYfv& L3{n{EQ2N"1.O!lL&3Ӭ/ywN<뾺|w T+}ɧ}>壯]7aͷG}C⧟/{Ϟ__|7 .G8d!f?UդZT::O JRҔ>x}>x}//////////////// oooooooooooooooomϟߔ)F?!/e"OrR0ğRf Ӟb~2MMMV4: 5,}1tL$)ˍhE;qΪ;7n8ʊˬ^oسYtIVn4@o^n.? Fz^,kΒ4Y?=>h)eUjYIK3|v,;ViZ'w'u6s.bmx;Q[Ձ^'n%ō+B.Zowz-Y8|rwz)4;:||֤Y({D=|<_PKSF7N4| 'guiqwt/tests/image/__init__.pyu=o0w~d Im6jeWϲP},y#wy8g-MSeu)A=mE,_mh_b;5ZT^c4tÔw5>Z>DY$AeYL8nK3MQd> YsJH\8d:fD Dg$h(øi[-BOߐxS_JPKSFU#guiqwt/tests/fliprotate/__init__.pyN0E /  h"PEʲl'lGIK|D3PZRY`"Z#XթK[ޝhEI yu `66נCk@42.?՜b!Wno#N-R*׏!y\( φM JxiP]N#xxۛS[c% k; ko'ttwH[ M1g.˿^o>ծ 8 u"=&aʿBߒ~lҾOV PKSFxo"guiqwt/tests/get_point/__init__.pymr0<;ujۙ.,uɄ)0!Z6w'! Ea"thT#)B&+*!YIV*PK(v'CkGaTJ@P,pN;|XQV_c vC&׵i5 suibf%XJfG+c}Wdi0iN:nwm4l 6Q TPˤ|V-!&ls FW$Zpv>).0`z3)'$Y`%#?`53^jҀ6LuNҲ1RCNDz^`=*.uU{tq:\jEaP?5[af2})h{qR ^䍅BD*p~/_ASb ѳRYTp9GN;Ȉbp3)J h:B[ ;BzTjb[0fŷo`=o]zdcF:̽tR.ĜuK) fxӋxn,g+[?EIr}ws ʬRH:CXy#,n/#2Z7s]vּgf4Y+3Y+Tꥵdb5pدaIz95Qq=Z4ƕ>pd4ݢey:xN,=>okOowy2JD4ۅA ܣup$^@8n w/έ7t~#Ypϩ8 u`O'lm`t0VlPKSFV$guiqwt/tests/filtertest1/__init__.pyTMo0+8iMl*lZئ{B`=؛dahz\mf<oF5H?IrkI Y6~2ȪP^zIH! xnon=7HA 9J>Ć7fՏknoFhM_=߯фFfy!LstLN 3{ VeZ jv@5%Xj&yh(6 ^5Z<"~!ܡ<_pRd6VΡ uQԈU+%FƟ8bIRh~⊉ $x:긚Tઉ̩Y߿YUN]$E{I? 1N}lh$[Ʈ l bi 8ynb\3PΈϙTc4οwFRy?#V9%R'z; cZ! )fy!ί)=ZPKSF.S#guiqwt/tests/rotatecrop/__init__.py]K0+r " M.*"!Y{\S4f {>, fEJ8gh+ \:Z^ȿPPKSF-L#guiqwt/tests/benchmarks/__init__.pyTMS0W7 EC=uBJ|t MjA^ݶKВ ,M CJ 2õ^%uni rkFnjsEl]v4\L6*ҧ']GFM5[yU7% 7cVTaICbE9ZqI[.rxELnGՁ} VA}!c=GZC$V‹K^DCƋ 8IVZhp55Ym+QX=9a-Oxa`\>E3; } 3PyX2a޿Xg^mY t:glh[|hϖ A`y,8S&HO~ƓPm,kT4sm{VxR#guiqwt/tests/qtdesigner/__init__.pyn0E,a}J,hPZhWLǶ(w844\_gr-0Msg4 YLXTL o]eoHc$cἓF H CF faȔc•UFc ,dxhgJW^:0QK'zQH 11% 7(ljqG>4h XX͙7lHr7vҶ `:blQx/'}Jq ju٬Hf@nϠ]}!'MώEނ ڿ<&#&!OV6͗݌'PKSFj  $guiqwt/tests/filtertest2/__init__.pyUMo0+rloݕ JN `ؑ,~ɄE{eJpf<3~쬵J0\H3i! 22BֺJUB㇩7q~UuH&4mihҴ+o'\-Ё]eJ'ƛ:U0&,zl<rP׊\m|ۊ$ h^վˣFfk ɩ@F* >wL`mNѶT 5O9Py!3[4%ZO l}ȴH{*Q:G讂c."Pg-+Ee3n,Z V\`xkYFNg-G6CӮ jȵ@\3bܕcC3wUoe؝16efsr`ȈU?"IC *QV G;SJp\ZCFJ [qILQ_H&D>|#u/Ukj_SgT=v?hJa͋̍Fā!)d.Np#]%/S45Yz19^Eq]9e(a__`۬Fi }/.F|0@ϕWOWMȷG#/y|MLTˣ?PKSFKguiqwt/tests/hist2d/__init__.pye=o w~cwm<$ۨNئ6`XQ}I ([.Dc-:w@d_X2p 靄V>α2!X/ 8E3#Hj P@p|ftEǫJSæ2BH':K;UJQgj$ʦԮ"5Dg!ziMY)Y콳x FHhOWHV΍If8!bPKSFc"guiqwt/tests/fontparam/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ PZ\`  G'$+$%j%4 @PKSF^!~ -guiqwt/tests/loadsaveitems_pickle/__init__.pyVr8fEȄdjZ5\hYJ2 ےe[$ͅVwVNr |J*3QA bsQ6 Oؿm z[4-В:s="} mʉ `8Ïiś8]|ƫM'GQQm{cg4ب^ƫwO . [.5Έ7k.ͬVG[s+&p"%:BG;,! ;#t}W QmIzР|)(A 4rP*NJO hZ["^PNHUX葉|%P(Ywƅ ^03f͊nh4X7Lg'IlU3ɥ^of(O l뚹LߍθHХ$[YКtire?p̤pDR3 )=}_R3$'-ym edN9_gPF衪:ESfNK-Ǘkߝ%Vr̵uH o&QlшDZ1ZixF@".P2~b`>7+EqWV9_s(dbT;ǟ[gZ΄c6~;ֲ5ve K(ZnݑìN Qr|=q* LL)މ3L2Hr*x"Pح-9n:TtP;RsӮ[τי#82@>bG_l%\}7VI_(IPͦΈ(f8Gᔸ`8$m%C8Nwp/ MtzZ$}}NI7va%hzsQϸ5z}D@o:4#OM .ꪣecˎNY~t/Xo4F)+3P"5AL)ĵ$"5(afmCq&RXoh!rG%!G 5ŸYVFag;WFbY!ܖ3q?Ӻ*m( opǃ# ֕yxU篋1 0|,?m[t-`^1[UvLBV/%je6{j}踕53aJZ-m*zT<.}[G]K+a{QU[d4]ꗴu%?,r7}q0"jt=,Ekg}<۝kYT;dLo?nn;S HԹ*v@X́Z]L 0,Gu\xi26vֱe9u#k}[W;g@ vEu4es#cKQC'^OFEҬEV֘j+'J зC{Hm[,[nMSjFuYC*LVh"$dˢs7V^\!Vh.}C޸U3 ('` 1Mx\ ̪wh_H 3m0Lz#T6 pu[0^KMNZ I!(6p|:.zK5"ю<̦9yh6#-T-^D؛}݃`c7bl84]ԝ^g0aM*N.0`6SK]o#0 *n#Y#K9K]ĈYBC(.̺=F$n-SQp?\CȄ'q!Z.\]c:)m.ɟc5̄eFngzJ##"E*XDT1ccŤbSƦ;5vh{O8~/ra4YZw OGB;k^oMLє5rUq"2HvBD)iHI2(-'1 u)YC0h2Gj &۾BrEsQK%ɵ8"h.LYUA=:i+m2 hY4ܤ:mQ@1`\b5 {O[{йk/8($:8M{,E!^ tmzqiǵ Ѩ#u>[1ڪB|T$°إdE5(&=/'̇քG~`Pyxή+q*8GWE7ś)UnW%csI49^漝kv"@zhi[vL2xJadMu z.)/#i\e4pS (80Up*XT}`$\A֎vSe(cLF3}\G9Q:ʙ2QdR2QeRfw(.Gf.8eLt9:u/dLKePj|* 1KjBbǥJb*pDVܲ0l(C6=w1, qz_p_{5[c½R+&hYJ5>bGR0whᓣP+1:!:x6 8~֜0LBP/ERIN:H:O{>\R Wͫx5myXvY#G˔Y,ҽBݭjղX-DQU^vzg1Ac */nN2OMy(7Yvсa W&:8O:qS#O'_k03؊|^~,\ȴVoo-̈뼅nb>glD|%DJ1h%$JH0QBJ&ai@8WB8 %#_Ñ_*!‘/څpJqUνAo.ND {bdlkC,z`* ;ݖ(}7K';WtFJM I{N}C6C"y)J" 9mQ o4u%}҆l7SKՠ7ЯZ<\uyDEbeay蝞̞wu+;8oaSE7˻9*i䓚_`nmlu~,=̇ת{ފš}w%^;:[ZaJĢЛYT<,"7~x,xZBZկe`AVUcV͏d؊"PO1I=E,AobAKG>۷o:%P}0mn* ao_+*eLENoUlp(.&)I_, _$ g]⡵oP>>ǹa>_o'ս|E No0:h@8>=[7ƶbs HYuE}S,Ə/K0uL}2۳DTM+Ӷ}F`+j#M 5 eZdmоUy;}.Jܩvf.-(w UsDҘF5M:F% R7t MYVlJ!БWu%xX6k_΋.!HubYc:#%y5%]G*/o zG3nn*`õyƴCB[ frIcv W7ËO4>g $Wleu W$X}+`ոUTr(|"~GqϾ;8[|+hlRr?゜xk6YDҴEw4d,Lw%ތ0<,rynYjuN`ZLnb{SCv(w֙~և‰~dV}݈S׿uTmx&U^%D^a!Vٜ^JQ/a |i C c(;(=:9AѹwD֚IN]!On#,3|+_2d! ~Ҕtk9&rRdČ|qVa*IP5Tv^-%č97Yp_n@Bqٍ"lȎ xwo̖ 5e7V%.~n-yYFe:t3 cu+|}3Q<&ɡ.D&eOjpJ7+k]21cg15vRI"mƍ#%5Ď,RW;9K5 6@28D2󽗍IEcP-> OwG jszeقy˭w XR@xJN(ڙ6H[751#n_5#{d>7fodgbo VV FJyu`y9l =?iB?ٯ{4bUȡwo? #i럻H˶cn f\p悶8pt1^EA LwqIJǝP=|dm6{XlvPc6#Qky_?$h)!$[,,ހ>h#=8:&"'cwG `x;?upP\ײ\C8NbWkeJX&Y+ӊv[. M=tr͞xhs(d#cWW+0`Qv]'=KcR<2B(R ~H!w] ^53[g1| bqoP0\zn&B /@~z*:7u͊{7Vd qIәOm9r'G'O6+ \]ZٷgRr$Z|QkoHT} 瑠a稐i}悷$`L;]U6DKK+6ԅY$LIP6 -k T,NFүqcvl]#]ql Ys0|zitRol}E8ud|vfg?cDD2gwI"tl  8;c'14?ÊHq@]ک[ Iny2} r~R;"e!g]^kv-kp-%4I_$9wQN;ύ?b6dSv6x&$͜lmWoZaUEc. 2vI!#ɹEg Wk& z+vNqNG&KIX+^)*r ̇-_8sɖ7U&q@]}Th wY@F}dV FgiI@ )(BK ḬNdkt^g#n3=2fA4J/y܉ѯbQqͮ3's1I~KuC)MRv'e8KzyLO=h&L1v17fNM?6?B$5m)9Bd`.%1E ˠLFAJM/۔|_$?>1[ݑϲE 5f1 20n'>rB`?, {=x_q,(lqf98T`zՅp Т}sϥs\5Y,@TCyz=Xc՞ }d$QY'2}cOӁ<3ջiS7})C;nʭi^)[\_:&䩭i?++t(د~xOs#W5"p~d`!2X^8ĕ!][t[ *{`Ge+ipKYZ tK][A^)@/QubRj'~ uKuqͯ `~dZrՃ#,[gCq@. >BrraLZye$a(,ۡF1ς{!.f6`\fegЛlz汬!,dCHAoW6}mo @Keo?~PKSFu@I\guiqwt/mandelbrot/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ T_` KpPKSFT\?,guiqwt/image/__init__.pyZr6}WL&#ɗɃ͉niGnEHBM R ]MSe"?sv Rp"2 cE94FcAYT( Tg B'Ӕ~z(;y[7R} 뽛&C f)ǡF8 b%c)~d,o"OO $Lp2'xL4-1ؚ!&}, em0S!w bNiϤ=OV)hx ɺA-$(xi=+;P2fpyʩ8rͭ/VzsvJE@ d2-XØ.HYY Rp&K OErXm<Ȇ8`-r1 ք4/+Nk ^;NUT! \JԹP>; :/\9^VdȜ@e/`RޜddƭlY @6̄n`q{8:._CzZzRS\M` 2%J U #HP(BP4)7R>3ϋ &xQ4]) Xg"sVD݇~W` bE=5`Rk #D5ЄYA{'#|rS| [)ٙF. tD6n"u~$i60#e6zU6%t:ٸK O̖ 1n H}jaK aU%L3џ)ɍX΀R;dXL TPZ7q4zVˋXG[xys/3QFyNy6=N?ssmM\dj!ˡfjWpyͤ\ X\͚^UL 0G96abR M:Q6iJb~n o-dwg[ 8;K6겔w%\g '!~1=wR:ypAFzecBٿYqxHڂI3 O_Oƺ a({eAx!_bu'< `^ۗ. E_;L7ig$0d^_7TOfqD-#P}xs}VLXpT}i{φOu-%l:UlMںy.h"EY@:Χa꥖ R: H gpMZ dCWՕsd{fVcG(o#9˶wPKwOM/ϱE4՗IJtb>f0/5؅cTsi*ڻ_ t<9lv?6EO8/G54;!bh7D=]oQDxN׫wР<dNU/>~bqK=~oKͿffAת&H!ޣ59ߣ\PKSFp%sguiqwt/label/__init__.pyVKO0WH{i=Z6vOLٓB;qb(ELf]Aó-7y%T )(+P,Qu%7Zµ6ys-a!`ue2CAS$O~JBzbuK}#x~) 1{pCs&ͮ {wRWoWPKSF@Q:%guiqwt/plot/__init__.py}rH{<0xo>P<,%Q)˞H@2++=1pG2udeUl)fJE^֭LZCN:%\/jj|_jr7n!*U]*XUQl]8HzSiRkjTQ6vE씮;aIճ֣ڹ'=f6r39_M5ɻ6Ixe;c>.Uqwr} TZm3?DDw>X-I'G>S*NTY$4gd_/V0]Un"o}UeS2yZ.ۋ||=ӽGi4jr{Zh@ Jټ+S&{i~Y\6f_G&nlOV rX_Ncia--zrY/7||{.a*,(UYTIS~UwV KNϺ@5->Iʈ}Kmtŏ2o-Q_$w˻,/eT=*m]2RT^T,Ϻ4LДU)_^R3r&y zx mlN `E]J;Й>\Иn eAfUSZVM?Vv[tvxm:?\ $@f3t;> zg"fQ]~O(.C )cr -9j>oΖYkB}\kb ~g#mTųnj8œRTz/U|4Y]FUC{ݢڠ'.&w ό5lMhkS洛'iRQfy/=bWtIWz)+yD~(pCVF߹gNC~T_ҙ94l&eӕRjTED:0t%!1XxI5|U OCԤ5XTjQ÷ܓiRityIǕ*2[mRCӨ^xؓRijȈu>̞!VHJQJW.A2!o@ӽC {>s?ݛ7Uկ!K *~T$~LC6R jM*mvwXr?+7]9w(c.?Ղ=4y55 F/e/.wf|3\r2^/P!W iB:h 3pG~(p;5uKL>1^sx(RC |9ݓ|b%)ISicHIDd&*DWJG%ThQ(a],uշ5ȯ&>5ګɴq~a>àe5F t:^ ADܘDYƧ6;I a{4z8ڊ MOTqT(i|uC8zv0hBρ{k°}7hV1s9@:},ih٘j2uM(| kvB= F?c RН hZ Lּ'Ղ =wC%_/CFdXmIA_vMZN8y/Z`EZy-'jJ~G.uqh0VcCU$j\iBu.A4 ›un:) 3Ɖ:5/5Ovl_2[>_ڭ: )>N*~4E>7šxWcaYy0%iYڸMjٺD R~ݛ}viZݡ^ {ljJn18.Ճ*Ms8+Mgs 0m1dW{?RM4 q́[A'Z*FSI8:~TGiF~o+ᵜx3 8G19m}PGO5Urj [Eh?>VT%i-T96p .Wf^*]4)uTљIh@؍e r&f%N2oÆHj5xo4Ou(]ťR"+2*niu5 XdIn+; ܙp}Mht1 מDØ_f&ɉ ڎ H;g #z o4l#]; 8P.pDZ6NЊY;{ F՞|>߫ ܁ Tc ΍i^_N@'q38/#t'cp9<ȳ4má"dZTha:XºYXO`F_`  zQïI VqT$1NgkiniTjuP4ni?k/TCg^I2sOl ̣nDV=Nc橶aQaKSN'*w XyYTt ǼLёstB̤eO/tjdomT&T)˴A7};,}mY&} =LpodLE0MZz0lz|KcSD;]:nS?zs)l [iֹxAsf@.8"*ad3$.sknly.aqC1GDUVd*% ' sSق8m*mIM0cVߜ:(zuxzo7491u܌~UkSM]qW9hEa(q G@1|`T]{/6+O&/ ̱+_2Ov4!zPP֊|5M ;> {U SY` eP۾2aGF‰V\ S֑5PYYz /gG7"qnQV FTAnT@!B% =t$ЇB ('z}*0W- ۑmb'eR)mmΣ [AlHi%`$8J}iR2 ܬk{QAo*2#hE^iWأ163cKN#fd'+0 twfJw&J{5Zi=SͰp$G Ɉ=dRubC8ϜwCv8:*՞304tEA,!#L+WYE; % q0C`vU{6s4(n%e+BgzVb𣪉|`K?Zi?j8u ̖d*(.=n$8Gv`'ک+# ]nBIGk= xQ]"^!IMjbC#&Ot4 .X,?0`T^^ |prAQ3/? h2 3^a &Lt1] \=Sf'Z܅F 9[&L+0Uv36gNX,mU*ĵ{.L[uU}VΧ#7J&N$`F'4U{&Tx.F䍋&Ru 7Q )kg<u.+ش#rx]C5Q(2l"M^^\׻d=30‡g.Xid0F3$DT+{%(hg9<+l>\*lAϬOϒ٬Ƀ)Un*A~59ys#qB637s5PˁD?[͎\ 8 0l{W,Ph< 6g?e80P(B p  80p$@+s&;PF9Q2!2χrȣ eCe((C%y((C%WI}VĄ=9!ܹe#: N*k8~R}hU$tN:yJ:s1zlvr Ε&τڮn:>kvQ&#bCk1Q=z$ܽ<D.RrkǢνtXgPB| b'vN·v( ˖ͰWJeв%:0ub仂5 >;?#1xI,}Ahl03l:/tHb7p,!w"jxϊö A<+KAtD!zx b  !Fx Dx|*3A# { 82JR+K{AN.0쁉᱁5p/#]v,;MKY>*qQUŪp8#FP Dm@u5xpmpNᴂA6}}b9mTE1Pv~qRt`|~ߠ-}Ѽp&uFUvߗfkPzy2|6챛xgok$ :MeـsGuTE)l`nm$y>G6M2lW/8+e]yU.RjeS!T[GZq-ZB%[SE5女)[4XAkٶdK)e~&5h .ݖ~8\<\` ,%ďGF"XRhݶ [nZg!uz*Ѡ$ǽ3ˀV*yLI;"V]p0f,&.ƤˇCy9D 륬spw~e=Lke?X}lTe; k5]fSQQ9<ݨ4Ztn`eO ex]je}FʖҴC:V77^R8D l܀#ת<$YpIveOsx1;Q!|~xw|e5Λ2wBjdk>N WpfYy8wojndrhz+6u{bLo=c̹i}mUY^89 OA;-7D= -0?»6]6b ;G[tӎb|%3zww':r.ztrd"-r7`p}je8rfFh{O?Ig#^d=gDuBi/>VTWѽ^"*V#gKuy+űdSh㡴hIVJE)MxM& t; [+k߻FQ-Z2x`v^Vbl"ٝCTMJKyMpxLPd}"TDue<\;}(EN~k9>pF#=-(gWVÓ;8ԶA`u s=B`f'%9JNr^Ug_6:zenN'];|3S-13]GO};@eL30s\9t^ b{}N8uؒˍrr/.[X;/򢤁W#N 8F3DZ{rh2g^/sp͆LCۖs. z 8wtþ@l iPNϸ.bl.ǫ'{yITؚw\a C-ǷΩ9oJ-)B6,b)3r`trw "eTwT .,Vw 0 ΝGnG -FiPv t7{.H&Bt@OVF|IοsuӿSu,MsɖWy𶯹"aѿHUX:2u!xWOW9?/PE_F HWt@\z4h*V=|]5*A|UnU) gTT FO:ө" Ó B̺\+ʻwWstMCSN `-Ijie~]O"fw_`:q*ֿB\%^B^2Fo"Q.=6 o fv(=:㸑V޹}|5?00/'@mDǫW+hRxi]'#QE8a$޹`. -䅌3Fk/Iz2#s!4||o:vnio[`IcEWvh{/2*i6Ot}iӔlD0.AtHP*Dm{Tȇ%Z'*3(p։DJFضَbMͽ$ i:!Ͼ\e|SR(Qc/p.Zxv.@~21j}zeq=ӭs`Kx>5pN(~jJ_tֽn=" Vo*m`|6 js̭yYp[0qn;LI8Zdql}=ӟ/yQ^ {+hϟ}@`^^ٶ 5CΝ} %LIE"ix,e-(yl(Yb3+TܜozL卦yϵq8P[Bh{Ykc@:/^»3ʻ}ex~,]/j_U\j&Z Vf$*yZAox,]hUņgΨun{ om_8>y B3J]۫d9mƓa^h:kv Ҹ5 I %1: m E٣Xon1@?a(N:̨B =HxY.!ka70IQ%{l1Q所=<&5ƜL_fH*t,k^24b|(e:P[d[ʕFÕ{%Mɘ;Tyns9V|+(Hgӱ+jeϜңaZ؋(ٚ3 ɵf:J(']ʨ#Bh;ymH?p$4ךoէ$ko3;IV`VkMz`S^>"c6㣀ǏVnoB33!줪#pK\`f!CAlm6?Eeeâ6(hP[#=v_ApRv <:(^6Kr>]k“F?oɝ'":#Kw顙İ/w-x[m\ ]eCkxGȒS[RH8`W_q1e8|mFoF;- !kх: %ʪv@ԁ3InVJ!U΀!'i]&$F!-k4k MYڲkv( #[k{ k":^7]}cع!2!hP;k8D㣆/D[cUs}j[m-`r a!0&BkG.q ;|hc  NOӢLFË_+\)Jc ZtuK(- ȼ=)wr[t?RI~70:N (ʃ\n4t8U^}e@ǂ6dz-^!W7[?A~NK SfnkZ^RZ- &o7JnM^L6:z"$zNfKZq{D~>7Y{`U٬5]^F$*jC`炝JY DGi tăAqMW9 p3;,[ ,@ք;8 ep(d aIk@d{;o } 'B4& wzcyjIѫ1XjOGXCiG<ɪȳ-}0i~w/O֘6OڙW'Qxf>B Tֱ˜"-R+3wwݡEAJE9]ɯG7ڂR-Hj/$>Gn,CG^-"O7B[mgjO~ ڋk[}' /D~뇕'FMI o x$p7u>|/~,4گӿXQuUm7~Q$vAC}?ϓM OosvoU,/wzCPKSFmBHguiqwt/transitional/__init__.pyWo"7NU$TCD{BήY\Mfc|ZU*]0?gvmt^֥- _"˵eUZnW߰??g,_kGDcɊݎu*ܼ1mKabY&|MMJz{p*(xa{*gf63ڞ'n>)_ _L6F'F܆pƎ _sUC(oXgZ#^K˽,Ŏ::sѡVgSrP "[cG!pz*CoSKqSA(&2JbKmqL |$s$$n@~W;.ҍٌPfP.khDNP4ujY$Ι!:x3 $,BWL.]=tfrÀwj,пAm{FPT[>]BYȗ?Kp_EUWqUڶP&v 3:*So8WV[`j뻕toyvb[W1|!xoŏXLaJiμzץY$FRs-wV/ m "k" )i<{M }*vɞ վAnL Vqk*8O>ֈw:"BV(y3[n(O]~RC `ckAs FKoK+'"ef<dG \T oх/ZM+x!Z7}E򣰒&Rw郞Ogp q]"rdp/ߵMZE)`a׼ݸ q!MZDx.Pq,Iș?>|~St!/ihq叡`*vǂe:7fW bKQt#wCݞ WuWP2. ]z~BGJ714tSClpZ_|W Fyu[\0g )svNf7Lɘ MI{0T05W&Zyn"y"ސ*oPKSFݶL"sguiqwt/debug/__init__.py|r8}=9!Z?\xSrAK1EI\3NDUtD_$fsw{y9)7ۦOmY֋l/oĵir /uMݽK׷'I?_KߺOHe|kcX:R.7ʽ5?!7ˢ*Kl d (tp]WU/\h-dC+WmL)b>&Vr\%;_LGi3:b{a@RmU.,HJs3+Ÿ?.?#Ϛ.exS]Qnu=|E=el>a(uY-E\*D'8ܾ6Ep@@ӑR7ouE* bQw8(]5/q2/ܛk[p0@GzKs<`ߑc,/'TnPT.6 {kqU]k喦%9d uwO벻m~Q#ge=5]w\J;\hS*S?):4$A%px_7'ym@\t],d4=dE@xtL%'!E,MMLZS(]J$f %Ed0U`~$?~ZFG㗺?uyh5%hn$Sˎ|@ ƒ4HIwRT48c.?ْ`h}ߺ~ݠ2Һ}ф0)7pV(({s[8(m`:D ǫgYPŏo70J\8EmS>RYoe`@Zg/^+QaLD i$姶X*huJ4/g ?%HRL D-:}>5Vu(MAUc(WM'e`+\ɡ>aS?5Q-Ⱦ&$:JQDhjLBԳrm4Y8t<(yHn>s^Z.ͅk ,n?JW\{ooy6Mմ+@}DOпd~.ԙ$(R_)W +BJ!R/R_)J Y~r^l1ńlesԉ ,A` \\?/_+0>[4Åm6|*Ǟjʩ9@ <܏:?. x+۬V,oz?T; Pf T5ĦxpQvbeQswީLݢuIr]F$LIO7$9 suW%Et`/vwrbc1R nN}]Y.0`D6O!{9C)|t Ѿ<_[mS xݟi|muA]!.0&6bE 'ڃ ]O l4ɐb-Mq]#2E[4m.ɟl[gm7MAFFc"%&T԰L̰`CF 6ƆMvhк~/iZ`qt1hg}Y(ʷ7OP!2>, UY!$FVQZմo:Mu|d&Zh)#3iŶ ]%@rYJ_Vʷrs5?*F/@UJ A_(0,L3Ȍ!H`^'w3lWE+0 irb9?{]>r^ ՚YYˆof(M& a_Xf0&$'v"-!|+Mkқz>s*z~DtF u[PG_l$TG= z dBO| SqWSEۈ#~n\+fZPDv Gp^(uۣ$cQ:>+ALn|sWq?MrG0=65}n=0_%"%Nŵ7jj(p$E!8MotQnȚ4 ׊S,TȎ$X yB[Bx5>hN{d@N(;Jn t ֶ~e'WSk:>+x"@g6q,(84Ήq +84p\d`n} L(1njp?Km2Q:~m2Q:F(S:Yj(S,Q7Y4̜e6JuF~q(%2sju(5ޟe6J͘fƨLj f& VƎ3D%LWܬ1l(C >=@{:'| 1~m SNvN{Yy+<z/w r("Fڸe] WtUŪmDh[v 0wkƴ,| чbLյnߺ6҈`1T e\~Y&:2k"fv?O~;SdT@9ZS'?4ڿK{~cJ3Fڊc ?VdތGZęQy)|c1=bW/j3ag!nch4"EabQDȍ0S#L"©⑟!<_!ȿ]qexEY\?Ź70ذK30ձ*u4@Xm;v-56b,0N]7H9 I;x@NBCLoO RL< rڲY40Gl.^78HzDۍԷh zg7 άq? \ "5۫ ҟͳ5K7== ogvpKhn×w7 $m+,5u†~ƂC;Tp1-Vts 7>+7c{T}Mգ.. C۽zZBo^Eʷ̏fz{W}T)}zIPL-Rm8Aپ|MakJa?+r:rA_Mbp(V/&-P<"E_%X5xh(ySwxp?og5x-uFG3էGW5yb[9lI)UG C ܰV&!Su"B lzܦi>#ǀfW-tyvaԴ5c\vT3 j\P9xO?=4s[4  pmf@U{QCG^͡cݸ^{<i2ENkTg`zI3붡5G)o+#:losw<n\)"S_Ssܔ ]T>p/Q)lf)C5OͮmZ=z˹ϬG_G-(2o϶R55fTvLe"gfS^ ai Lr,ӵG>L"(Կһ&.JOݙ74PR  RflHxj9K <7a x]?HUAe_2Ju—6yp ѿfcVmfL#~|SCߪ4"z%W*2 >ɪh%Vvߪ+,P[IҭIy_3kj}aXW;#$-`bGQ{Xvm.ϒ.El{lnqDԆ&LW ?AkT@ }#DuQQ ;<ρw4J>.큒S[-bg݉[ NVjdqXodRtcuZtwݺh~_V دAwxt W?4.2~#ëmqiLΔa9lep4@ xt]_>ܞ;W[bW2 Bہ[]9,^Jm;~ʼ/þB^]%DDc.X)|$侬sIg29ٸ@~h=~t:9FW?i'תbm3>$_݌/>\_K3\5eW$D >ޖjvFr_s_|Ov~J.Oȳ]?JZz<[*5=z]3. 1KpKg펒3.4}Os!O#`:Tz9ax xV+ f:2n<:\4vST)%³|{:go p뤩p v5 kTtqۥ4z<ďI/4T`L츣lMT{. k~q'HmDc_>e(HY_/]Eqۧ 8VaB:`@VP] G:ʑ@OMp{P%t?#XIt_n^@բw'h۩>}ǛdhwwwŊ*-i6tcmVjٔ1.Y挢ߔ`M|cpQ<&|tT/i99QeK#-T? b<zeoFX>d/+=K5^}$ dމd}z/?ʭ3@CB.@"HOseenOUS-"]Gԁf鄒\tQ&B\[}zX(n=e ӛ M@t v@R@2T*Wnksk#<;E[:y=?~o4j| 9M⧟|(+mGnpp7Lmq"b,e;({$E|(eKh@J!7"˽#mϲ/#9A## Gv~."py(4&1s٤huZnoV%X4]B8/4W n{Hi~Yt%ȃ_TCow/7QHL55/M+D+4&|`wmz.Nxm(e.S  ,R^zf2NΛVF D-{isH%\?~_Wh_:IS0 ~jbR2BkBiv[|H!U>;@ep‡ֈޮw({|/L O3NMQ.޳u__B:O:C"h[ΏtO)Z*]uY'Iclobz>E]ރLogfx9yDD6~UfHi!]& #_{C $> WY΃G!^~1Rx?r|_kQT_ LAc (h(SJED}_o?}KTMfۍ͝mgbA6Q`[R31~goyPln=wWФLZ:.=Z΅s# x: e/I9>{U\V=@=̨*0xkZknRF9k|^DvaPrŊs;A/&qx\ki_8d:Z 4haP9#ru\,نlJ5Jg=dJMCq5n͞%?&12}` ?e~dS>q4y_ZP>j ŵs `3TON;Oewrx8! 4|4ӷޝre7~7ft'(&O.O.. Y D2[֒QY#d`œx̹Ju#eNXh# GGN ~}m b6A$;RSUyCZ{^ayl0߿;=lcR'nҧ. )>1Ќ5:pQe*fYF@ߣ~TC=`/(dm%i2Ӭa~W/xJ_]lťz1=5[/0">#L\e%zֹP.VSlDnVU1m9IUyMlgI+4 ;e `d6yrmYl0f_z󠡼]rQBZͼR>&1}nn~aL׋b=L'wgW+M֨&CǶ?~n6ӯ*m*WWT_jv33m/fpr XP2BSQ_WqqȓFF.&EM,b: Ei(ߥ\7h/Mdk[7U49/.&77f0Lߢmm@b=fV]&ˮmbWJ&zYN'qn6),Z_z ffH/4GsјcJdd}3!ȦU7n\nwas]*[~4]3:~̶ؙKb]zU #H蕩SNqg Nnjy4jEjQ;ųtvilߤÉL,7ډ>L@ olG|ce6 IxcI*d~ts) K+jl :hsըv-,}!BV]Y=ݨ?p]jIΓVE~d̟t|76o2D58/yFxc~^/7kR&+ݑ:u?a$Hr5ș\1swP+"e]Qr2dvtQ8#B\퍔m[^b"U9jKzWm҃AuɵB:CY3_TH6zym^;lvyX|^n&?zZ4?*~] GSWBD{e<:^"f-&TUH(sgY@~7+@h!KG2ڷ g h%UV]i?gE*ُ2)n}RMB"%bKt!D%%H=B#H \b KLpPbV:4IRߎIUi{x~DSkvl׳1S?&*^옆3P<?d`N67Uiz1YڸmܘQ(fG lm{13Nl gvG;ېsm4W/ܫ`[RmaptAUDF<ķ#7>%*z傀v8y:73042IYhJˆ 6Ru#?QpK!;i^j[ĭh-]Y%->b=E5.8 a?Z)ePJ)uez%$O[ֹic>J'to??5N]>{N#614^7Z+f8MIslhs%@GLҵ赘k[@iq4FM<}8@7/h ZfJF¶J,nH RzB{9Tt38A".RO(рp\I+l7'8cK!ʵ8BZ.UJzE>mT&{M$RFUM x: Zs|$ik:wJ\\'& 6H\*E@Wꐽj՛?飚M?hť #fq>a-1J ʥ^ڵ&=+w)xXl} ssFwhfw3ߧ;4Tq|fϞEM"ѻ]Hjsq8hsv@:ZhnivHOIC? 0l{W,PL\K.l7~<082(93`W= 18 IGF $K7ٹ22QxIqG(GB8q\ !m2Wa[{!rAo.2쁉᱁]po;p^[nK X(qI]Ūp8#F ;.ߖ(]V$fo7YLZR'1Pv~>R )~ߠ#}-ZѼ~:~¨Vl"K/3{6OjS7==vou3=/vbSY6EIe06}G6m2l+8xf]y޼,TNRh+:fjsQܫlg CKh.ٚ/ )/e`M٢wz=bے--o!-SZiYK%ꇣeIlG[]8!ϖ|0{: mrF}xa̎꽪RW2Έ{YUcRb,b%q7b4|3:u.+wnc(gbVy˘n^m;d Ӄu"֢'xo:A.p||oYa9q=<7Lv]+ClS6"Dt*[ئi[>Z(^Vk<JTa:#!Ki;}̠ͩv5f/&^Xw+s\R$;FuPlf@VyBiޗ>VT='DT>O+q+.BbLR%VJE)&&l׬vgX+°%Y#~ZGk-c˽<3(D{:ms{\45u UsAbcPJ%ީz˹qI> ~k=>Ԟgc Wޭ.*YwM bSسYw9Ea4v{:S᳝it⥰]vé@};:?qΔaD魯R&[ЩSr!w]m> e "-_gBt5%LS+.Ğ {~m(;4Sy J+ǯ&36޻N ְMy/fޫbT3e%Ƿ=OGm۔iV\n`6I-nrQw1 sҤ;* ~Y3<#e Νdָ# #1 m CwD hJU*Kr5UDO54e[^]= !jH _Y5vLtIh:NjI"~"r~%َ.NWtB*U_3\zna6Xurf>iRY6uYq&cXLw&.!ǀy\ެ[^IGVm;G5O֓:<{$TG-> %񵻣>lrRlu~Z\2k)0xN(4 ^ >JPcPg#Pvf{/8PcV}!`a0bm X[E'.C>jGN,V^9MÏo^}@.]S[5㜻^gh|3&/F٫(@1]E+ӡy$FQ۬fETmWGoG "}nT~p #B|n"e ^7]aN~-R2lW#\w *kKȱ6`VkM =7]˴hT,@Jց8b*;8h͸C$+\>`B~FB2Qm_**K7f(キs{xS׭eF)f.V\ca] Ogp^{ODtǔ{AwC3݀a!^&n=:[lP믲>|s9KOq^UG#c \c h*CH1 w[DYbuLvplwGW CFN/UjG`i^Ekv$-k`-i_$K1uQ; ?B4dCvp&$lUmZ-a(/5f\s-}'r>`g-r5>GOV/ j\ cVR][þp-Eq@]M(2 {dVk2ҺM6d#'V>.'fnǕӍn0;#X?QY1 PLOu~ǝ8/D(o9dZsRg9 8ź~wܡ&KE8 4R百4&~;#o?>7$zyq9Zk$*-(4y }؅S*gٳ2pB,&ƏmB.ȏO`pdfwwY'G7vw!;3w_V=r/%ߒ<|=lV7ͧw{@zti5mf@]=.z_sX/G?"HݾN?O@ X PY|wPKSF @\guiqwt/qtdesigner/__init__.py]n1E{KB(Ph(C)-;^=#6huz|[c4Lu.XlrR/`>84_;,`̕;'(&cfz`ҔynC7E) V}ɜ٠+u)F~y.jt =hQҨ_>2/dkRwPKSF3Iguiqwt/config/__init__.pyM 0EԅDt墨Ņu=6mC2 "dva3D(kHuZ_s X βl( b 9X}*t^q{Rl%O6yYBW&4xGxWԾ7zP/-x]N_>PKSFzguiqwt/_scaler/__init__.pym1 ὿Q7uw``h/AH M{g08`%̺) ^ 1up̣)7)\Q:ju^H5I^bQZNXn 8ϸ[3m* CMyPKSFuLguiqwt/signals/__init__.pyr0E|Y~h1BeV]~DA\ߏd Ao({ڷzU=Ns[ʹբ1)PdӫjUnO=YFNf 5pxa%?sk |˛W^͒_!.yi(b$|i]Qw$/ D X#ݶR ۂQJ}/$Iqp]Wc4$X^N7椰u>6 K[N`oVr{7\\Dз7էVjWH>Y#va:ҀՀ }f+w6tSsfGчFlGMa8Kh̎wJe=L\w RxvoF|C)`Eeљ\0:/y=%)R/ &TvGxBO<$"P[ ؈FtokD17Unx3N*9؋NB s8gRXr%:LPKSFK guiqwt/colormap/__init__.pymSێ0}W V*(l+%ZuLb_߱1dSϜ9vvZ]iJM1ȕ6A40%e \p !,^VGz[Ya~,!.u<^mlU;}Σzx6(\.p8g-TC[|AMDqɛGDkrjےDIl]XjQsUxẓhغEŻbv8[jQj.L &X:Qef+ecjӠT3Ujl4[Vͳs&z~; G2GL棫ˉŘ&0!3_Z,s]FP-ϖphtº1w4Q6.q돖~x9_>2M (FТUZË9rgkrqb+.MQi3ԎjGXhf|ai~rfz2|4b"t.OUˀxl1\Of4_,)6jE|)NI(Tlr9 }bz/7!4. 33uIL_P|~vm7J=[)|_Fbzk@ՏfAǭS僬LLGB ,M!4lwyrDxa^ >bbf>*q7}#D7yqʩA\5bg0P<rU$86EVd=Rcrtvz:'( \^3=h)%Viflrx?&ީY̮ǝ"&ᅑh'ˑ lX"Gi"Io$ֶ@Es,Sko V7dBz8}_,iae-jxդ Ǣ{Mu~]`ctRRBol=d%uT+͙ZooRN6i־d%~Kќq22$yDfꞔYsjɥ͸|RUm/s\6"Ki,5ڴ(~ f֋*Np|If:hjtYjrr~q4sCKR Z0gхO`1|FxU"UVٴÎ]*A77&Uט49ۭmܿ3P \]^iČPxKU~Ͱv:пOC~^^v}<<2#M!Rt|r:]J+-Ɵ'.CU&aghqK8aCKdh c(5Ink uFv_<Ձ1䷖8qFv+563@)`U\ ʀU[bOEYbл 'c5[6*/9}-dLy4 cEA}ʪT2 Q|Yue@toٺ? p3c0M=8Ŀz8j}ϓa=Y|\Y&%gN_ſ櫃|Ha$z ߚM=jt<63r-boe!7$~#ydVh4@GtP! % C$,t"YoL:OJ 0Ӡ.\u ~(߫=UtV$imz4"d.&Fr-UAU$T%<* Ky7D dLUYNRv6N|i;iaReY1 L(m\C4Wġ6:/Rh3N-"ybޜq1jP@regF@~>mrge\i]uT 3 Re, TQӪL)'e'&Ѹ4XJ~Q t gE+Za0OW oNCMt52lRl'ाpNIW1ef.bOB𳤴##6p 0s,y-h\#m SpNSZ;BלOUEq-}T9̉2㬘X_eΐ5%tr]^FaQp2и:MǢp# E)b|nDHj?s;j?yLJZR'TkcQE)ލNjx{Gmezdہ}pҨ[bK-@c1ؐŸ͛ 9g!v;{mwCĬ DPv=\Ĭ>p# 8p;nXbnb|ntT397n O=jltE Ùc{(N9jD;scYٺjWnhA.԰6sPWWj;lT$h5A) >LJ03|_N95P˥[Dc#l[-T|"`YU:#&ACugzh]]Y\\'ڠ^{_=#Syu$/J;OxM#>#:n)+JXCvNI$#2p T04[QôhVԄmk4ܓGz~XvFNJGH-&xlnyў-Bq6FZ ]m<EYLȭjZQNToety\OM4{-ei9Hĸ ;x'/`:,sc8 i 晸,6q`OT&ߣMx@ˉԟG4.qn Hg|`G~MH.ja5B98ҫg "vŦM tG.[AF۠_?5r?ؐ0f.2OvT4e+c}F%17ad=F!s8R" H[Dlֈ:u@*V'ٮ*J6,%pKg66ZcFc%|{yK|sbezMKńք wGS)T`o2cUqBsi&;g&8a2wA]l6c޼@Х᜿7I~}tݍ1γsϢv;=7 Le>ފ0HL;6T¼W\Ҿ4āCxb|XrlF6 ,+۸' _,US6Wb|ab}LGSPϓrTHyMƓ1/B`gU܉ ?"`߇ QUƽe\vIrs٣pcNDɕZ(qW?y&Ϥ&GR  t`]yΕWލ KҼ=dYeoGB>8,^ۉ+ٽf^<|; * ^. ׺y=]`1 Dl[Ɖwڞ)84Q^zۄg{1 Ra*rϸmņwN8gXSpa]F/ f7A3Lc !.5'RC%DH j8NE ɰr6&mt˰MChV< xi888u8- O52'Un9D(h쏽%C:[@R3<kI BM5H[}BNAbP5sPUNL^.z3`l 1 { Ě ָY'856,:xi^ݛ pU`kx)5.])9ΓU'W݅ӤlO۲4tdJVc֤xfˍԻnCs.);SUͦ]6=gkgMMsxblk{IdK!?m111^nd[mT#$\!~ng%4 q+ATyAuR2w |5QQ$/˴H6M"7>M co+HK5h 7fo J1UǶC} #$E@މ\~<_ܠ6g+fqPkpA`\; N  2{eߋ#6J8Ѻp,kgJ8!nWQq> U;v>Z5ņvƸ+:> {$| jt?FhCxIm6!U/8~mgv[ug Nc$~ ֹݓy Ȕ;Qw{vW[#Eɬ4yzs j6rB%l;h=wz8F$"w@|x6A! #ͻIgK6Ņҭj( P򱷆az{$N@v*v#Cs"^}23W~)zFCiGiDDH+iǻJ{"zᯫ(δ.dfC0MaC`=v=K+Ujm%h"tff]F"Q?}W @2G A%:ww];0Np[N/Prtoݕ?4N]38;l n4:z/wťvz.IMSl/r6O+jJNER^\VN41jY5:yŀ*#2Ջ`ñ9L34bZ0ցDNUbT(CP:dBA:̄Q(xܛn'"'"*φ q;S~ra5 pN,6htI[u0s$ ^WňqDwl=mA.Dx!*wC.Nt鍧룮 1툜kODOƂdD?,@i= 0‡ܗd%aM8QRtp((l޳"QG p#s6 }>UTAاbIYE\T9$`ɛ9 8伝ݛ@6a5fG8ūg!Wb:5@syl@b i\1`)@Gut[`{8` c)8r(#7ʞ2r{eOFQdeOFQGn}eF);(]7(8nbM7J1㦫ttiŕ;:1c Qc ';' D15eō &e†HBg)F/rwv_޾&w.-:Oz~g*uʧs"6##g:bNw[퐍AV!&WVocrc7cǕA1OFޜzz+) Np)ą2䙣Utܫ<_4E8s#C˘g(N"JHԥnt tSD2 |8eIhy(gΑܥ@LF7':0-%qlopBx ?|XŌAD,΋E LNÃaft8ļc1=q-7bK-! )kMh9D  hCD!:1ppg|x!‘"!‘sz!DžC㸊UX !aO&@Y;R½kO[Xa1i:v8dc,b﬊8jDL MDF;VGĕK<4%8/DiJZHBw|->;/ hDh;֢>jKWJk\ ꮯY4oÃ?sut<w* =Ͽ-E"Ğs_<-pOOfO+ۧH|(uT*jPuKas?s`K6kpkͩH aƭFqϒ5-`Ma.;k*4t5fpT{j1ۦbi%4JDpCԏDK buo̗XI˜aXD2K US$`oFc5KDMltU)cJcJ nOboؘ 鑬Kp!WoP>>ay:MR:3 C^ JuE%EldE`)ĵ^a>Kt}Oň0өb M+6MN ۆs9lIk;KU֓ps*s&ݨ%@viRZ90~CxXw狰"q]fUD, u.igqhgV /o bz E6so+yso,8)$2262dQYvCdWVn\|'%j`\{!X9X=+8,< ewnJhSnÁ11~03ƻ=kHѻ;#wW_Kzx&~p}E|OexdN%3rQ3r ÍS$yz!( $`Z˃N5w`٫,f+ے]AJCZY>SȌY⡴Ւ\v EDpDUoϬNWðbYc~+Gk-J#wey&FQ8c4lbYS8aj6(Zb 2};QDYXO!rnM&g`=sFBù=#(gWVSسY︥h!_Hb"W뤐Z$GV&BɔS#;4v{:cዝ)ugvUᐚ~+mO~}cϔaD魯!+Щ xR9j.sMv:#fyi5;uW# 8Fжǁ"ٞSgW'(<<:+"k?C)l~ V|xʸ!Ml[jz>OF^ݨlf]i(P vޡrX<m39;l}`*^Z8M.$*v9>ttG#SUX3yv # =ߪ{Cˮ/onp;CL@OﵴrI1C '*coiKVZ?uP +,>^kqt^siVDO~kp?%kF HW4_AlYM%G˝21$$>_kVY, ܧ#ftWn0㨼Y:2 n]<](L Z*h|KԾAm(\0Bƻ`ƖC"ɸ`T4a"e~SM^-E(fܗņ!Vkm(vx_PrŵR+x =탏A[~tM7,dd"e}uYv :=M\: 1{T&+Wyۓ9 QKm K d"}t0, Ibχ[4u ZbMս$ :!Ϟ־>9)\jE`a #JwQ+d 07k)0ͨN('~f*<h?_ VX.#n{d>7fox p[03qn;L5`˴Z)~=ӟϏ}QӀo4*pwo?:f~Gy]l 5C=ylL^WQc&޻8l@Jh>Jm"f(Sq =_ݠ \3uO8xxz@!4Jѫ{!0HŚ[}zO2~;u 8 "PղTr~,]/__cppcLC/@I˴Jrpt>Lsk{Ի8B# 8>W{ ma'h1G C{a|3vlqD iǾI}9B. *13hu 7 )0j ℡l="N giZ,My_$m`0&$qA'Gb1h0d4#ma24KRN]GE1R.<4 =PҮ3FW;xH!g{9Vr(Ho#j=v'鶃;$VNT wR(r$g7Y5ᓜߟuoٗ껂b\)H b\|4JW {mbrޚ- a'? '.Ǖk Jns(x;V8O@8,Kv;3TƟxG $QkA܆f.h\ca3cO"01DD4 O4$xpI?7#GwcbȒ*S3T%O32z> k4=cLs&@\PAlHjt5vjl8nn\j ^Ԅdn ľtm9-=XK4Md1sA-9h3|k\BMUmZ0çG`MY+(RKd]NؑqkPwт 6{H$85yh4•d`qa' C-dbDv1I/f=٨v>ɩPU!~삁^3+ٳvAG<7ZSqȳlu! M2 *'vjY$U zV䘅Mqxv'Yt-8i(IyAaYlt ό{. ҋ#6|8OuOg8 9:U *ǒX-*7Mrl?)΀+3JY>?)H(g53R[U R21I^ܳg~~r/\ѿp !,x;G;O÷_õܵ_M?_f`7l7PJA{rgy 3/S ^C3&Fes&RkNxK}:iy}GR͸J~W!;*cA 7<`('!<"=?"8gS` _ңu5 %g{@u[݅HfK-]pCKiqzx85UmWc[ n{/%6W ~tf~o1ĹHV+do-~8O_ jҖUr`}p*dF V`=;!*='z؅ʰGSiC|$jALk|"mS()us#zk |(;A۴z5ك*>q~3(xu agO (wno{qo8bnt6d)g4#x5kSzu4yds07MxfVof⃟:r]=pXH)} +!V\Y'}*v:X&)@5 UI<Q'y-hmrckvWtU^0Pcryy3ߟ.7`o3R(Wɷ%?zxi=ÁfO5̾Fwf*ԅRpCn*#j.@}4ʺvp}ƩWtWhWW0kΦykk nȮE) ?Y{(!75p^be#F=?_Tmex/eu dO/"!CkWŸ:2ʕYsVn2/捾pYu Op\.STS7Y s7Fn 63mqOcz#%>%TX2ok7P Zf 6$:%"Z NڼvScȽhN}ԈʗF~J8H0en(OeA1o&KIh\d .EԿA@6?5)Fl"˪0+<@BPl \x[_=ͧ*me >co{JF[p $17Em Xy|sdca^*K\llZd2ffrRJ`׎ȴ !i nn焴ĈYnCC+.L[' 0SQp?7{$!C\BX6I-^eY"yp[bs[K idODРJ*b,R,f,V,a,QXO1؀bC ZZ[4㲬V S̀&p{Ii[|I JFړ;ݨc`u?`iʹo|U)MtWx$*hC%5c"zWE;}V;XU.[Bt+Hu%L34Fz?j@ 5?\X=CKL]O,l_Tsu!8z7(X+dEVoUB~*lI?AvYnX3IwH 7UKwA,Y7¤jxZ s?pP8r}@׳KPҼ0ސ zlhqP=k#̭ޥٶb rkuq#lY숨|\b781oRܐb9. ~ogu0j-GFѠۋ]z363^Rjvx2I]m7%%jߋh8C/+ $I ^L%up!V0UGĽ:^%q {T YsbVi!q;*G ,!\1Vj UVV Y1?J1pvы.-Vn}6E;3t]|b|躇4=(t}|Hza}0‡{8YW䅸A#|Uv¹jb IGYe/ *Q숻sn3H: 'Q@-hoǞX*<+k5wq#A%m㜙3?%#d̲1I{s D۰'~i$jWY9/s.w* }0ZiRjSA`[~`v&z!=+讨ŻWtÅ_x-EDM_t}Q7ՑOUYhI@SͲԠq&mA/}h t͝I{҃]}vCR])ޔןOK(ĵqUmVBVO]<-H[~PדkrQG$h3|p[1ڪB|T$°إ-dE%(&J=/̇V{~5`Pyux̮+p*p8:WY.fE͔*њr΍W9i8+^c .Z`NR*6Ȝ@' 2^@K׈StrS&ݎX@(g`OX{ +(mjۇ v)1fJp?CeJ/#}}k/H{9^Fˡ2^Dˑ2^N"xÉHI8'R\$2GZRIiJMOD!`PmUQH8QI D.ˌdEZhҲ05~fKJń?7m:-mg\CWN:|RnK%v MB$2 ܦ>9fJ%>h Sjχ>SUk+/HsmrMh$6^(7ϢTEeb*]H-S&} XyKPEo!_;kG;Sq@4ޠʃé_ 2wF2U!:>娉}|e*}K03؊c>/?c.37-//5Ȉ뼅.b>۴-1RK*aǢ+!#QBzJB_ I@(J\ a/|2{~WJ{>QBOj~\+!]:VKw8J( :$t5{[=L$CZaR}%VFci]Z{*NPOP4A6t>PGOzH[]x%4/EeY V볺xY&}OSu;cIQ4Vchv=WAյ)^jQH[ٽy9[7== {vw7RF9pjJ]0W*ud6wm-g~,=eKbj%eCyۍ>~ REB`$lna7]3 7W۱`ec.QĄK,(?,ǢO&/S{7m"I)G %7o7Z>Sq"Llx\a:#ۀW<-7yfjp琜Q|-y9}$Jܩrf.-(wiU^sDܘj4}0.fiGvyK!7Аgu}%xXfs5.6Hu"c:%Х4&rvͯ,Rܿ-L#:l+n깏sSm"$)d2//!.%0Ew\|;?HI ˶*Z<_{2e/O:S%5ΔrL_g*M$&,sa}|VF<_3dAѢeuPV2)-UoK8di'l&^#6z%'0.pϴH{Jy3Xvt pm/Fs3}ȱ{hF6A#pt؂ `4"֎ ]zz2U\=ug=~GA2nwf#~vCcSx?pZf?#"0qφ.w˛|`tL1Nw\2Ůae''هYY9-Jۺi^\j`.]Z ~o;(MUBCYnΨ΃WŪ~hT,;'avx2\Bm!Ω!}~i'X!9ٝ>$ >QLzS3\ٕlX="@]Ɲg).#̈7?|[mxwȓZM=ׁZ*1=r\y|_ɲOt>4y4;n7'=ۀ'yV.o-`Oۿgi{:G[<0ڦAtBx;}yM3؉ޞwu"<¬#4(!]ULz( GjrcW4:Tfk ;lFޥ}*k&88w'N#U/ZҀ=r]鐵Wn;r!s*LHx dH1rBQ14/Uޥjٙ#{]LgyY Vn8"'O[n'₮`ynA_G[ەh#'+B={ 2G]mw}< Qh].\q] ZE({)0YWAQBIo`I@T58fJ8 ]ҁH !\dad>vD@Zs똼G]pF,p8 "ѝKID>rP2k&D)t^+|w TzA܁KN⣮/_WzQ!foqv#m:f'4 Há0.mkZeXu] `xޫ+JNdQ:ֳJ)d.W$N/˱ Sڙ wbܻ""1軋fHi!&O^B }vlRϲ>5'AJ`4{tS/qE,cn13aDz$`/AA;xHw ;s)*v&-F=73|sAQjG,ݭtCiZsv-kp.%TI7n{݈hI+c6dSWz渉&$ lWoR޽0Qc. 鵔sI!#vܺ'hjڅ~Zdk8gn%#$,eˌr ̇-尷?dK" (N 4uӷ0 #&ł YZtAj[) ,dktu>wvc{e2:u2]?n)tI~tc #ײuDk.cfd`J|! {$;P˛pXP!x5 8y]f8D`ԅp Ь}v%#{ŎpkV!*PbF,6} v,C{APHޕʽ稛n~2EUZ^ؗr[^޽A {`Ge{ڙ[^Wr ts]]XVV )XAd^*ӫߛ[ Y9?2!lˏ{琗kYll[lϐ~|RfWNokgѩnO9=D?l23k sߝ߬i{08PKSFebHNyguiqwt/histogram2d/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ Y\^k` D,PKSFt^${guiqwt/styles/__init__.py}Ks#9o3se{eirYr\irJQ/)o#6@A<$Xc۴?ʷ;[5G*/&/D'Op_O|v19o?"Y.gw ByX58Vc*,+5~Œצ04!͋}=*rlk^U櫩js!rm-l5nBd;0kS*kl{ߘ`\va4o`\YD />_,ή g[7f[rmVlo`_~YY]m2MVeۿS_9v=M^3y}⏎-Q*qzH|`r^W=;>]_~jӬMXl\lomm&50ĬCe O԰aTmU~ZZoƖ?Ԅ,8u[}}W =Zj#U+O_ }ʛloB4?=gUJϪV'YMM6k*R?-Hq~01ʾ;|6g5ev㍇@XOZ 3͋Ƽ^jw0i \O{ g'Vo\7ك)ޓXa Z<SZN٘.f3ajwѬ3]P~r/NoO͔v񝁼#/EHQvRv*1GJR?_lb; ͵m! ZH{}uC ہ?__(fEbfDu-wҥ B>j 7OܓAœf ` ddI,qZ6Ja*7wnENB]lsn~峗]a9Ih,czhHG)M=%[C6Օz8=M+ ܹ)&_f,|&>8y!ʖ9cetm&d5U Tk7t8r]e2ۙnw 7% f #al2 OґO-T@1SshS5_vi[JU,iٵUBNe~lo=}6I6=znZBzPIH2i(@k[hb)"C4`+X>|KOX{ߙ*od5|*4ieTXOa \]O50+U<Ū2e˕}> 0s.meВ0KPoVSx 7^Oj{n WW^VvKf;FMǯ_HN >I"|kg]ToL }ws0"#Z\[ +ۣ-nx0AicEx^ G~-'q|{W=fg=c4Nuz9"X5t}0(L8N݁^l8S8+Kd[.$˖s4Uq\gwS`w;X־QG:y=PVu)/]\ٕacJ.$C0r%E7 tU{M=\^ dʼn;5] NM6kIȦ)¼4CȈm sTaLoMVH,E.=s^E xbl&zعVGV3M9.Ara\C&,v ȕ,/ԏ쳲JgxԱ]‚rJ{ SI3w(5&YDˍDx}T/ES, D2! E~ *1~,[i3{m!^)U+#dڣ2;]A@O Yq gWBf\&k`t_4^5slxaP;)¯p Ho .DKE|lM e8LA+gP8[\(x.-)9iwcVBaCo뽎j|Bni/{7T`4I%v8L:  :yC՟li KO4]tC hgegTbr;6CmOL'#0khG-nwc/m_eZ5CV LƆpiVo.]=Sc8p\pȐb+c~H<C\r}b!#] RKzSX > zPa#@7! ]MQƠ:(F?>9.vLlHtaTdiٞg#= 3 XkfeDgK GbQu @ CWЎ>ӈPvm"_!R*_b $vz-! -L֙fu#A}N!PM%6bR&5()nyE+0h_WٞsޱLr W e^lPLxKJ_9a,vdDDxeCBI<Jo0ʼnVa[٩Od|yF wƷ8|c@׳BoHE=7}x b#ꈞv8ÞUo-"\Sw|YYzbK\ܘwL6YhS<:o?68EI V"Fp6\'2n7 P)`> OWIњZPҋ:}WU%i7d&'1ӏGցJ{v'8[ɩx)Nb|\qcAp)S 7Qڟ@PWe>J{ C9b#|W_ZUTd .(FMaDW&ڵTZ+c@& hʚDxvE6T.hK0]&UL7tӋ1=LF"-DT0kQq !z4B8͕«©VܬHr,jhor>Qq'ai f֪7*[jQM.5DxBEItG̝}&1!/lge( q턜!@h+'?G4GZ\k?Օhԑ: \m AުSaMUUvig`%ZPM^$z:~gs Eg~ӎ(J;dz0J;~g>rM |?]%\c(L>Q4'is x^SS&ҹ)Ӥ#aWJ9TT}v8`OC8@s2Hy)0X^;ʦTG9Q:ʑ2#(SHF(G2TG){(2TG);Mu ʑӮR㴫8(%NXQJ?(%c*RSG8Ua1,T[U;NUC^byaFp9Yw}U~p\]0oE'g- #8' 3L@ 㚝lk b $p}SALpkYq?ߙeT >|b9 zʞZ Aι)4y~* tW:+uDh=׬ɞ"aϯ "jY*BoQU.hIt3UBc*/q]e?_CPŌ_*~=ⓄT@9jS QN*D=X03F؊tA~,ᬜ=>*gF\%$nH8/\nwŗ:Dqu">zH#D_1PD/B я#E "Xqx'G>Q#?UD<3E#*" 8* ν"bavE {bdlk'm,KT'%^m"'0q^4TjB gMB]honV7;\te[ m@oo볺xـ&?:T?D-(Q~cdʘFtVjlQ^V-o@=6&ڔ hP\lή}Md$L{vIhvsSE7+v~\L\;-<{;~:.VԳSq`"p5-aǾLĢ؛ҙET<,|ib-#ʒqOg;5,<@I< $q?0L}e@}+߀ 8X|8g`ҷ3/-&eLZ P-[LRz׺.MP!>?x}lM?owfs &`~K C#[]ѧ[SLEOBc[9"I)G Cйah{hw`Oʼnx\`S6L\D;85biMh!dȢr ~:L-t݅AJO¶ Rjd >#<}YGۢ''t+UROL}Wșp>TLUCHygdO|e4̓97*A/(?һvJ] 9\(G_ ݝ/ݻ)h'ޙ Ka$j="s*;S_!egwos3v$<[jzJ4g>1TJ"X"|^F'Y$B/%J[:+L*i":o"*|fMl/ +k^xL(WaOkmm噃Pgie`ʚ҄ɪٺNk3(CeTDGM"DMVP & [<΁\|rɼn.5u'j!5Zu wR"Ď[`s'E6&*kiEj=+9z]oN@Y ݝNꄘpggt,p>2p6R18i$l: /B|bؽy#9;x?岻0e G>h$At+tA!SN^_[o\ޙВ+c.Dius`:Dz<<-R7FGjut0ixГ yigi~ZLX]n&_:i**BS^%D͞a!pJFE!^/U?%]v/>1ֽtsJmqcẇ ,(TLz>Xyp ߸ e_]i4]:wmy X /7r~1<@V@!t\0}Z0CBt?T#cQt_n@Bq"x5oCSx}mWanUcx8잯B`NBl0.+!CtP*Dl%t}6 xL=*-_"rsFn,,ouɤYaTc_&/"8z7xb.>H$:^.&?;C-= k̂Z^Yvq:* pȁv!%?:<d ~ 6UlI;^375p1ꎸԌދ{7aߙ B9,!- 9eѮ=?vpܫ|zW!޽B ?Hm/ܚ ?Q* b`⃋$ Jf{M)|u36fJp2S0}Yҁp׉| xFh6Z 瘂"믃^.QdL+ݪFzzyX}ѵB v1}i2% Q~}b2;=?L.=Fb3 j|_V: Иv>6INa\UbiWҿ\ol=wF@i(`v*N`gizl |hqv mt#RY8g\{"n5bC[<w2}V#}n{q &q/>%fLhPrix^}!w;ސ.ǚfcWz2y Z#z#C3'xvA^g?s9{nr3*I{ V;s1N^s9$^z/ћKID>QP2k&zP1tVOޕ{m(X @kK|*ۮ7>*& vrS]:Q_p8PHޣ9XG*GiQGx 0cďt7)ZYuYIz3WX/DZEdO>8;3 [ODtǞwn.K=u1?ُ:labpmLrqgH`Aw(m#JH˯ҍv5k_~͎tc>KZB"YƞEGK&2{z1r)xWp? qy 3޵{ &owyJ]Yt g8D@<DM:#!r/ t> ћbvtrvt:>@&fU>Bd9%p0c =[δ6|TjئkI~zUȳl) zv 0'; C$rwrڣ/o c`i5( ?f8Sv5OLSh% ['vu~*&YE?1Oc6{vC=@PHr5&=<:^Q b†vӁ~fջhaw_aMUV=JdOM-^fy3nȘC %ڲ{UK}`K哳n?r'" 'a|EDݮ'+ދ> 3BvvEn0vv"ƿI6}PPC݋Dcvi[T!Sy_M ̃q/*@q޶0S#,D?`eUP  alp;L:'/\zG&~{;__·D:`&M<ӵeLi,/L{H7~ڄG.<+23|VYSdk+2hOC{5s)R 83:i G9p򓿬i}GT移 R6Ⱦs_CQ }_S?Aӿ'~w'=O/=/°ÿH 1PKSF[^PyQt4/__init__.pyu̽ ᝫ`Cc'.8s Q~wڅ˃ p1 . A[Ne*2nz,DF< yG_wݶ$ ? ۚ`uQY:{icXy7,)# I PKSFoU4PyQt4/phonon/__init__.pyeOK1)rԃP?&#F喸˒B]@vz0ꪵL \<>WcPa8=ʖ1d^u2˶kJ}vI P"嚓 VPKSFxWDgc EPyQt4/Qwt5/__init__.py[[s8~W.na[5IM 4З٭-Ja1G_:G=]p#\?]Y(Eʧ I$]s&ۖ7MQkPWsenw-LLDB4 ?_%L+ 5ʦ8Gf y$ Ԛ4qdhfqFlAeQQ<'8.7{ͧtIOQ:'"p73mEϮ?ۀW"WF=B~'Va?a: u@Ʀ@ EQ:v /snØB3q?$ ZS`ߡ['IIVDmyۈt=@kv5k{=`kM5gB"Ǜio'3QrIi%!`FsƇjMe$aDĥ"ٖgl+p >QvM @,G=ܻjءiub3zSc*%S%Z.lȫ"`QhU ˆ>08MU!}l/2)=R/.YE:qL-ݔ^m=ItVddp׸3F:rX1c5?dTQ[f2~dkk\O6/)W}YFW (MnVSWbAm\iΜj Lt*lee! 1\Ќ_?TlgQQyXx:CXmZAw$߸ecoX~t )$T6cY<Kٜw.ohd=N^qo*dO\JpSnj*% IgJG+h4hf-ˋc1: ZbU m\@%5/gn,\9VuuKWpƈ.]%٫ c4"_cgڭU[[nZ\P%D(C` j = ;?A?(%$UY:]-Tba#]-IF}B[h{ӅveSHv聬ܕR Ji,*y= Sb튬VLZfm+E ɄSjB_DE,Nh94pb$~$)T7.荰72U(x7o!\Tc *ۮ?'T^*76%4)vftJCf|iWt7v݆]Zڷl?Nʫf(.8J#yb ɀDVe&6ԗH1fs6psK3Z%K6biNRwT'@?HeWL#t ly"&Hy#p^?r?L #'2H!]r#*$rJ)x}- XC0):"'J>`ss#F";mP#A$4Ǔ6v8!Pbӿ"(]JGX& x٣+:Hfrvh_9#?%^b.p.rrω ޅFɥNxv!8/߲e|83g#p ؍C)xR)x$Ӳx=0fPKSFV'< EPyQt4/Qwt5/Qwt/__init__.py[Ks8W63)qj+v%;gHš hKh)%{GTbbul\y?U.}%Jƕ@1sh50}Rg4vnE}/VDVJ$]YQnz|<ivs~+q'ӱ~ѯ_;?5ALI f$Pg?f7kw&SmyBf`mM^dzԉYH<š^;Cd:y躻tHmT-4wdʾh귂CSǖ,Z(MAka"LȲni87v˲Xi{$j$gL@3ԥ&GV-KZYj*ڍI+%E?luNb6^p@J~/E./ :{u- #;s }f46CPBEG1jײ wп+yTqU/ϥ-,I<_q! ѯcɒ%ytLܔW^om=ItVd5Y|2p׸s:rcZӅhrܨ瘌x9QZ,FԓG-1YNWY[Q<O.EB]\iQ5B(1 qCYrBcX cGn/KX(caX=7'u0bAw$߹ecYt5(kMUY-Ot1 GQٗxyWX;k,9$8Qy̠R¡t7[o+7<^9EDkis" UүfSim czyr `ኅ_h΅xrk;rJfaSJW e6҈|~5^hxn}i{hp#M ,9# :??(%,WE:]% լAEn}.[ Ŭ^[. ]t1{&=!'nsgGGs,(}u=,QVLVھIW,'vm DN $6)ҔtB#3>/t(t_oFWWj߲ 1ाjZH,iV'GK H\5v`R6p}#"RȿŜ-ǒc*Bj6d2mttr\3.f |D7GS~:YHE*zALbF5_)v_ K>26l%˔o9M7$PfN>pfy Z3S]$v́G=+)nWOw`,22_Y1_6[F գfvdeoT(A"]atZeJ`M)xFd(~ZK/nf%y9,=nuKRaS8d Y@LR=eޝ'B)%W;8VGHr<{Q .x 6u(>1( `yxd#]Z(m.mԢQD+.$S6hHn[`8G㜫=ƛϗf_4a.~ZiMr(;SX@u\G\/9oru3˜Yxщ=ލQcBl;e}5ѷ1 u48=]=F=}%Ӵ)[Չ-Q4&kԕ|k(wEk Zc<}g8)SIx62!&j¥T7A]d@!pe%ol( "1$ί<!uk[feʫ|ݹ;zUgS$Yl^%yHI3_Bbo輪?=Cןn?UoӤ,yg?d|ho4;l?]_r{pw~}bww{p58;Arw:P|lv~uzO\|U rq}$0NrgU\E&6^y<EU^)}p t񷃇O/7yYudJ7ȇl6^0OV>0_o=**G^Ov?KRD/yumv7id?KE|DYZduUYfoQ%ߣӨj-R>Ѷc챑.\EE4ɒ*nw9/w-&Ns3 H/w{^'eK^~${݆);ఽK/I_Q-RKX}&O Y,cxM4JQorUYs?iafR_dhA?a|\XٴKMؕ/^0(>ʁz]p{8*ވsRPSzdD C9NA#`ruW `IAhaO~P*B㧊Nw1MBL϶c- Y& ]Lfu 0 m~Ǹ9ss `T1&ϽNg=s&o? s:i";l0xq $Βud 5ȧC_@߈GX"1)j~S/AlėQ$5,X/4YY,wӗ0`Gy%-^ݬ%yU$?H5"XW)kw=]ocvG ND|ϭ&A,o4yHҤ9-b+r>˸DK֏|HYB< N Aftw {^heTbAc.O1_Nȣnle $wX+ 瓉❢{4?۔Kbm[xi#DՠhiqڌU9 &yT[v)#}/$dʲX۸Alj F'gQj Ξ/7ydOhcX̻:() 1$1Mk4Aa ꍈBirguD2NP55ZЈ@p7!¹% ~;^IOeZKxR JmqWUrRNraS>cW|p[gbo9kF۲FY6GgԐjN/. SH.IdK P)+ftU+cKgDp*SE q%؅9UD1T%괺<8)b8?C' M\캂YQ^2v%#/OӈT0]<{Op47u'}~ej<L)v,Y,L u&$IRJFʑ#&|Oz#2_*CȸafhAhRlm-莮9 w3qO&>UNC{2/L=?JFdҎ{-M4].wTO!uz2~ Um>\YO:P(y̜<\ⰼ?<(Y4Rr.Ū:2XTѥJ2k\v|/GWP>W veaF4%F؟˄L @x 6"+C̀ǖ`.b38_<ߣjm}_OC/bE)њ!Kw8usx T QgىҼl(kgPg#nNET,M.޸z9B<.ƭ4y)BQY_Ƌ&P5l`.J tX qzkjk쐾V'^_řqrvs4Ƽ7͂NLfi3 j0=d[k ,Ah5ZTM( X8S-49JRti}I%34Fh)h*zOH5X|ßܱC#sWٜ;eabOd`z6K@{ ݴ{wj(,\~ zەcMd78yYu*V9>lI8}m!hZS]%@!H~,4 k;Vxvra?\8xP(,>Ťm~'">9E)iJ1زq&_6&΃2rB~ &{OVN/ϳo>1ρ ;]W@F\p ]s/ 襕fpƿxbYr]!Ͳ;Pmn4*xsr k$Bn+Ў脤xlr"×4lXQ)%#qrgV]Y3L6BczQ@ΠHqOq9ayGd5co*sEde.9;䶗z]M|[EUyJJu4"}4E`>DŠu]M>N'P`5"z] [-X:= B%K1C86R!Q{kcxo<ŲGy]0!Rs@'EGlchJNis ԷB @puyùHUDJ-,#v}d eQ2ڷ, QJ*ƕFॠ6;iG< ZW=bUC0$/ٲ) 0y1L !!Wfʥ%Zb{0UDz-O~C#.~w0PĿx)\+pzJbdRfK!rH~AG6'/كS5kRg*,e}1.nO:ѠuG xH]pyF': U-~^PyCMQy,m&64aCF:mYt"K2ZO&$[_pH3ńΩu,0/zKv fzlq.2͟hОBdEz/XU[JW%{:YqdG8x7D*/(!h11}mtprxFxͮ9ε]ݣ3 d^ɓaQ+1 cKiT0fKK#GmVIB&3^;`˨@Bu_68Ounx+n^1\&;sBN1G!©4C'bzMݚݗB3*Kqk4ųzhbM-46҉86}Qs!nG9ݞf؀r =HOBB Wːw _56^5:%o;jN<joڱކq?a8?Z_Վvtު'w X*VA U` X*0VXnu|V> W:Ϟ4Qs_e7ro?2]0B{h,\p=\.\Ln,~KpuFUwtrHf%V|/ϷZ`Y#3ЁG a>CLVQPЖwrۼƔ3"frYã-^ט=l{&0f1M8E!DT^\^`̺#u[#4_# R@GGIU9` -B.`-NF}*ncbwȜ]'OT} 0CTHV:MxzN֛jbC\jɭJCy(U[eT9PU^ij˳|GEr4CR`@/Q9uw,gnI>N'S+CI&0~6CYaO&d'PKnEjF;@-NqqȯUf,Aw(ِpç ]&~ vQ%i ]C=5׊7i"}ʄ8 fVA9KO@M<;s粢@, mrwVcw0^kH ~ЗjqP7/C&x`()C<Ϊ֐.ɜ䮱d\ғ:D֓I7MbP*tɰ70ERzєi9Ea%:yCwng+ $/zOCc%.(ݩ26 |7p0vP ߿RLx:hN.\As8 -C$ JYG;lHPG1j6y(?FJưY[Bsa|XҜt8k/;jԨ x8m(\PXl0m`Ld m‘ؓg6HJ-NnT`]E]е\|B]]GʿNTȽ086ߖsH%;ޮ%CЫa$ar, FqS08.|ufm#S ѵuX?gqXYmz_ 0_WHTҴ-}‘ R1 i"t]$ϔĸFK@5wdIW` #2tc)+anrXӣDb8?FKYe D璅$~]ek)~#WSjۄd"Oȡ]¥; 5pvVQf &3p `4.Ӛ*2';8F~kw5fPuhosv~sQld Ŗ80F4SsoJ4&;Sxw:-̹nSqi ]w7NL}럞 ҭgp3Ps½"k¬7H ۈvo#n7;i~nf-qxk-TH7p߲@8=藍m2! $c~#ݖTfP}TzB1wx- #dΫ5aRUb7+t@91u裚ݯDm\/TɗHږ9qTbD-uԃ!Q̠25N&f8.nC<9UJH=-~UHhqYэ2}^kj0mEo%dk""#-w&J)#{jVLإ`7޼/.hY :PuC#76;X˽;82ϛ=aI5_51]VOw2HP,˽Le<]hbCC3pjeHf ~2[AofcF aP!zVu E,IpxXz >73cimy='xsyVN M)rkFrr"!a,Р$MMxOȃ1W ͅF#O@'R ̷ Gb¤[Kle$T*%/=sY#P=l-j852VHKj%L(4.[脎~&o,*rB*>Hj$N̮kY9:IqlulTv͓FJ 89 $++kwa~9#]<4+#XV#K.bYKƱx$Sc9{>`c&Ý,4 _ RHu'ٝwV=5Zii i5>@c~nO|و!B\H3ڝY\9Myyg?`R Ϣ]G8MIR<ʘ |q}eh=vmƠ$5z'< rFIU w"N]#4xpX!NؤJᴑ*gjgj!bd``jU@璘'3dqsu#9(=gߞ c,-;eanXQ`>LQˋ"+:}yfItL&nVWfK&K3i&ϸ9o!Hqq V0֕#O1ͽs Bt,o޳ne_?>$>Cא}x fc9]ue,Sqpf&aEel@b5x~K()2}Ee:2U 8PmN\vѱN =j@@'ʸ~21x9f&BŴl qEk~3@7Ґ~4h"a ǡbgUĻ&ƹc5wBz^2vlO񸁳g?{J6gl࢘{+FsHzYW~/BT$]gX+3oB]Z~-*"S᠁l#Y܍~e":i$&{#(h}hagUOLKFfsiWrdז9<N"g a.8fFa-˜7 XD ?t=HÃǪu4m#DŽPMl~5,{`:wGtM&N.~@sr6t*іwm9- ,sRftނ F) y?鍜OׅU#ħG=}o<ڜ̠םCJyt;Uz2{+BOIJ=Lگ Ӂj J zS-֋/h֟me7Z8Y.zl5Cu-f a/qg̫Gz8^32 MD,jR4}>mpgw)yË@͛V^KAw4\ ۃ-ϳQT;%Z M.FBU#d!ձARQ0 xA^X`_c #*DIeúlif]Uq"L!%o vT'2Q3tyu6kmhs{Xs$o5R5kc'x)4V `GQӮ:Ϟ'WTRAZ]ih8܅-4xĉm1YClsmQxyn|tmw=^-۳9Ȣ]f4u7L @x%%)5K2 JMTSZxQo*0BAU'6YvG,"b{s$%ZmYNTx]FYsja5qTbg(3 –voA_@]0J<^LȮ4I*s!F2߳vnG$Fs%dpjAHզMz= SsDD tu0:@Ƚi,0vwcnmƛ//Ecsh1ԪJGZ$2GZ~ dCm{b.h!18AuJ-(a>v ͤz-r͆4r#]LkZ-֌--60| Z)(MB+'.aJ"8ձhx*mpysTKjOӗ84ؤ}CɞAN zqo-|xt<. ;x/0sswIe ƣ8t>+!D1-yb"Jg|(C$|Wڰ򞁙 a(If-2h_A? d (:}5F;G#χIQ>m^!(7Pyۄ  8z`Gc.󰊖;l -6[|L0@^l6 #|mݨ~t }&·EvL2.L/wT>I/a}׶Vh&2T%kh; |U?32kosV.:zzfuCyk.w `H6u%sTvJc[lLBH&\:^'ǿBwC6{ޣ:UuC|a*=R>{MXݐ!"~UA;*`pN== ]\hda!NE;OwF[43VeĬ<+7O <寮'$z-.o1+=\˳)+ei$q3p@٦o/8=݋-W!`A‘SqG C7H]qOe={0_Utn\>%(_qLizmL&}2"Z7 nyꚼvya!wK47ivt'۹*Rr[Z2Klȉ?T)];~W9N 24h$mb9j{A⡔mF3)͑+)S:|ݮ7Wկ%R!*8V^tOvWSJڽ.[KO^yjc=#gb +Hg, 0>Q+x;oī2gU~Ju\3<ڮRI&.:_5jH.9.JE+谧QVxowbu|)"ƾKxaK"* Ka@/C$a[?,a.UA7/W8 A8kʵ,0Ua05;;@)ٿln\l[2{py+ҋ"d'l}PUm C]WCX횤-・8g *O5MYK괈spw@4+Hckdw/N|_m .M46W(g]YkM5"[g  Iқw$\0 mbyq1ر0ڹiOfa q ϝsq+om6h4'2]U]d6gϩ 5 D K-e uߟ7&?qZ 򯝔}asȻ.mn޳?Α\־bѾ*{x3 ?(mm ; {^ ps9np78l9\f W3Af6Aj|P5>>A*|P T>A0*|t>A:}Nt'>(]mo怌 \Ns>W%3<C*Lϳk?!U?$saWbYv@{*BN^7r %jd}i: 30%kUTGze4#U~c&%4Q)ﰅUO 9]JtxXYs麔 v:U J S)Y*@FMF DʴFƪ/m"&|.U@U]{2^_]~ 6c{wDb`t;j'7O#|g݌ Og؝d@m9ַR,QsYad:1U!Qsœ*"& 1,畦cyCh+5N^O`nu%;uf%0d$:g_kRV%>aq{'GyJ?!i[3zI_LOtǫp2>%IRJԧH8N'־9|!vzK#EmgD X |\y,Zk` YwXXix}%A? Y$7#_wgƣ}j5WuPW9ٓg|OzTTVٺ7A;Tk(4T+µ}k8&Fiҕ{RVM94K0dbϥ&ݴЌK/тf4^ֱ^6X2> d; < ,Ig#^aPBw:M`(N!Xwp[DS™ȃ'A c$mdiIK cRQ}iTNI;/'9=u={kkN]P)IA)wxӹs<ńW++£Y.6 3۶M)yIm~_R i.b_WqB"bj1]xQ2%>??????(cTU8̸݊E|6FvԨ%,`K$X" HD%,`|Ku]oGՖ&s""9/>WlRj6|bh0OMRE)s1:g8+c#l[N$E:D'ueb4՝VE1+K|4ʪԄ*@a6T$^ƁjW0!9Љ&Y5 $"VW9e\,y6 ?Wx%Un}.N|m<)~qԓP*P5 hväZG%XIpҘ ;!,8~N: :f%ZdUn3ۖTG) +=Hl!$E( TBt@HXW$WaRhݲp=1UCĎ UoKڠf: e c!]@y+_ 4l|_|&(+Z89.,Y#q$~^oIB \[j?9XQ<`OAU@7-EUyŧ+Жwwf!1h;rB7U_t4F(A[P\%l h`Df*_c=4-mAq2g*u%b:b%<I+%3rFE"}`9@8~!T.ӊ=bE"CV`B(ˢEP(J`eW%X%=,rek:Jn\5劲Vw]$[0D:?gzhGVPmGLXEE`8#={)ǁ\idg VL8$h2+E$4kWTƐ}Fލ/[Øu}ezRGEH h+") ?^쉆w]*(֯ft (\,"<区d Y6Ccʷؖ ərb,Fo1PvO1_Ma6LyIԓy86@CtZ̜yϻ|@@Pwq"[G;B{-3ĺŵ `#[G3i&@c<0S'*O@ُڼ,._I?&F8Io!̗mZϷ|?#ͳ { ۸w Nƞ^͜qgͤ>hCeLs%k tinL]'ϱ-_ 1!{ z렝^#;svZ.UZKphx5|7P9>27F7잡{y}Q FvW"Fd(+|)XWxk7ȉ"Mꐻi][T; )aOu~ܸM-A ’LimGKx&wKDQlKY`=3:0t$ZeTɫ|_K +!0vatdٳ;P# n_ia<д }+ECnb~|x zc;˟3]`3t(0A WW5NbIQ|PEk7 GR(SXPM:fabxe6'0~P & l &'lH ] N:AN:]ulݬIA|.tH]p>}>A^>ϓ }PB>(>(A = yPB>(A ^PB?}>A|>}>AhA}F4>hR1 }PB>(A }PBdIcFcHGãQx1<mGg D B$ D}B$"A)H"ARDOM◖mlʋ/0N#źC|>ɖ@Ee\C*Yy r <`K]VyqUI&Q 5HyGC>| UPr!JÏ e9uuvdfUJd:G3Cg&\8qZDkK ; &71HpLnϲ u'Ue?奴 W54/JYmxY)% jLIR4b866JJ^ؘ!.l!A{"O3 ^Oo(lg6:QgOD !ʼY3vV˷},(gA9 YP΂r= 2n 2$Ȑ C 2$ȐeH"QcWcT*$˨Ƅ ^uPIv-%;y $hk9 X-B7Y;F}u,`ޚürX[wLEX~P9Ƹmr8ZPJp)IaizH;X˘8:W$[[ d[ 0N)946S,yG+Ռ.m?j^LK H:K9& lzy`RQFg*@lIVE,OhuKO3 (&,L*}Cvn94!YJ'?DzzxʑWC_Wk%}M&so~YE74_JK;O}|n):愺:I@T*yX2<0sK,Pp;Wc'G.śpFnxL_<26)@3lg k,]R"+;xD;枀O?-c{^x?WD`'p]Y`-@p9@N8 9rl{Z(Y(lR%+# .3?<-bm癙vGVERVRHw/xr:ɹJSzk'6 "k|O,釜@8*PHI;k2w';ŝ/Jgowg_ofo hȘ>"+2"+2"+2"+r/"+2"?+2)R5m23;M ڢ%PV:y :,h1ג0$ϤU;5gnʫSOœ=eK &a`&7 M0n: M0nqQڴFMHì (8}jLEƬe%1q SSc:lj"tbnZWzZ7_ PΞ4͵YiKioھ]f7޶G95 ;g)~-ýȁu󹡋8[F;U7E! k3R|rzB*UGU$ :e!i:X(k +ЛYϯ*t @̙oEbS8BBd#vK>4/Y0m${$,]ͩG_kuk(6 `x;w0 `xXwB\mE9JR$.<X ?ֱef-`| S/σ՗W?5ßL]?t4f73w3Mm::/k fe2bv(BPio,BւhB٦BT^Z QX6NU@kA]>t IG5Kw~}et`NUKGmL05M$uNy3ڧt8KH,hdϳ9( HR$PY8{$W?eV߈ގj7ROfF[R*͆\LzlCۦoa\x[ xTqy/^ki ~$JeeS5gwg"VG·[ר(D[{iPB|W|W|W|^|W|}ϗeA?^>V7h{A=ZmS!]Q>X"Ȫ%Uyfmϸ!Eb/slMl߲.ޅײ9w"H]sA1湾`E˿~^ClPFx-'S]d7=W?qdf}{dc~B{9{Z*:fNY|grI3m6PvknX f2 e-m17&cjqYg8YHL>Ss @1ݣ| ;71 Gܘ< ِ`^a/#~֐7;ĉ`ڹ /Q/Bt Ԁ ȮF\AKTUPF_(=<}Zy>FcǠ=I1(_ҮռCzYBe4}!Ҳ{;-:&;vKӌEqGDjpdp6O5E/ %L|5 fM~ҮJT,Kh ryޣZ< vNΗXS:H ٶU<ƏԩjFmhn8,2< Kll4q[CfáTH`2C G;-uv0ZVF&q'6e@O TH˕O_|}n(8:mAᇉҩ}82 &=MFYr8_;1ݑAQ{}"zhs7gXq!ح3^jsqH7ʻ/d*zT8ˬ9sɄ.8~oUYz.r*e>6 t?>gk$ QW\ӅT80:H^"K@|M Жdpڠ>'8 e?;e$Ky33Uu:JڀP4^]o#[,)$,#|DE 4 2S?k\,L&q!taY!Vto0N ̋|> ~UVX5$\7x  X⒗z" ASO͘ `Ѱ. 1 ޚitrV4CkI: e>{- 11OSd֓ K3-^ZGEC̔.=qRnh+WyYE0 Ny-@28LJ5昙&H:u>GI<|׏4^٠o3fK=x%/L(K!``"8 (_'+G IڥS>9$*QA<'4%Ɍ]n9q΢Y8?'`y9O4JT-RiT)4aB/U&}9SXt&ÉX 4 =EJ])nt kz1QVP SdBS$cʩlbW"d d<H^NM ǜW<a Ҋ4)1 t$'噘Й`-|O@ |ꍉ:m]@<`"nnH|gR. KTpO UbV<.V--BXϢ!>0%Jdi՞QqEH-: r< `[gqykyYD biSI}ڥ*A:NjAg`N(VL5\ퟣgM/|sg[դ|9/R~9z@6͟`~)Deb~}*LskR)|g[yTo)Ĵ>',^ *U $^A\$9HηESB4{\8c0 ϛ8Mٌ57Fa%ėLXQr:"ZLk"∹ eeeP8{ + QF ܭ#Xhcc]=I:5LE <A\%4C5م =40.W0m<}J3XLh_$hE*l/jU Hؒw"1҄]*ukf`/uAјzF-hNG xk&.$S'#DK%v fƟ]ºbZ}@t􏑤_8ߗVJe6(@&GCmoaSx uUw )2nnF;CneN ~mF (J|J\c(qEa`BkPat9"@Iͥpy{8\1B#]0`xdNɼ2FE$+`@8E\bI 8*ao`l}$Fע* o} ΎZ\˄ToY_‚\3 IiH$U_ڢ=r#tiWO " ȦUVC80eֺF\_H%2q+`vE,^%K$N))zPʋ<}24VW!S ܗEzIjd+]d?nz>OX(r|-<:>7#a-DO7<-9%ì}W:n`HND:I5*4h ◤9F#0(DC$Fxthl6G1&QR䠝\a׳|20&-*>C~H"ؔaUbmt}zg`Į?:L$nWQ -l$/&ӬӺu5[#QBv$:ݾbE00Ցkq TUGH eO+ta͓-5u@ )W-SI%eSA>|!$'fQHh+zgM`L?S>Qpp`hgpw%;.46fVCJz٦*VfK+jBe_ErT0GMq I691Kt,` %(.<㱡aK֛T +đ=sDl.h֟-1Ol/0ť É I#ZЭ>*kErV%yс;>c9 +R29i#a2F k[(55#e6!ĽQ%[[WO\%:3̪z.K_T78Hᗨ[pTW}cXv(G9bnїqAHM9àe@9J؝g\9<IͮUH )v$IF'eim?~eńq߂ܟՅd8WfnwxObӐxhiNw`7F[CEƅ _"TXƔ[fwbqmٯʇ"h|c˶)9GBbtn$sCK!)QP'$=9U P*xh9&"#T}B:Gd<.B@LϷv;Z(zS+}# _M=QJp4;Ii $krq֬PVPY%@aMr.TGA/[(P&T27%u>vrYbF___P LBro-C2`Q,t=1,7Dg?Z =wsC2$1zqO$s98j U=&bkǮK@Q~Kt|Giw3={7CQUVNMI!b2Sً]hPG7h8 "͇!xPI0ah6=$b?7wj"#Z[  g3( [7QI?l(ŔUM}8BYr=P> z8LHyo4Xp:B>-ڟ!{#Rߜf=mG#j}6ȻȔk޼l{{^S2 }GmЕE6hyReUIԷ41g+̪1!Q<IQ}Ph}z9IM4b"8 If _'-AP0߾ P<=9giT2t f%&Tt͔(&mO%)"e1#?q<: ]GpYT?QQz^t(4` z,1Ƨڸx͞oN;'B{=?&pSƾbq33޶:\?ȇcd_hYgݫ=>gL`'9ϑE>B?a["{+[Wr|D3ytw&H/" ,!S"y 3~Əp @XE"wGBf+P UIg| O8%3L '  `C`袘UenAED7ԂBӜ /K_?bvˬXe@0yLJme].z| _w?].w|Ag:y;y;y;yi "sy<-\Ӣ|Keʝz:ֻ'PekK+R~?B^wjE@ç${ +VuvzDM ]_vc q5 g2ZKWkc@ D,CpkHp`zH -'mP1Gn==e[SwK#Wx84G`?A}<- 8?Ia@isOxZԦRn>HV 6(BM?"yo |_4.6fiʵ1 I"KN+@idUpRAV&+ u(KBscgLTI|@g{Q+l)nxG .C;:Ѩlo$,9b̄ ZʡVA7pm5+d#,ǘ 1=>ņס;S>qO*pjNnH- JQjO66`b;7\Z26b؇&׆ g,a'=hk!Q.ֱ X&/!۪D ~3y B;A _ui['}.4ZswԽ?]Kz5}sI8k󭦁%xM['h4dϮ};P%w}OgI8fv;?,yqJ'%|h˨'uW=lCk"yUCcc<~Q$n4ٶҕ! Ƀtҟvfď}鑢|+DRr<]1.V)gH?,dTv PvB@GDأU9 aS= LNl#ݣZ$̼#e<+(eĜ&3t~& kgt~&Igt~&ILXj  `bkeo[Z՝۲%D6,GN$w_/v"N&!У7JxB㶡;|ZfۊY-a+V[i\r&)JV?GyFQnaCnmCXې Y2­{ ~N]7"XZE beG^Ă(@<<€E,iXd}HW|‚(9GR[\E.S>2FW1=\T՜Ҳm+Lj4}^Gsd(`Vr` {'5Yo÷ ~CpaS|;]ɧЉw _ {eEI鼏Nq#pk^Hzti6k{ "g[ii2;'9+ ¹J7(i}c[XqQng=\RMXUS}AB8Zf^mG~G,=obQ_N^-Q"uv^@琌ܣpA'1eVMaQO`.]ߥ#tuWI Xna"Wia_ zZ7nU-5 1t{ZåZq*ODKu+h  ݀GF%$sNJab 4[0lb8hV!ؤ0'L0;R }dȄ7eq;QWt[?{xQRm(}uBi`tcYo<qnWh)x pXGCZf&- Y"jѭ뜴d}zCfí0=ָ, f ݍf@EZQ d'@4eqWbH:qa" 9b:sG2J̿IIB|&OY tOkPMC>/cjׇo0ƌV?+ 8v8>ÚWQHoL,2i}Bw贋Bq-Gyݛg!| M󉰒T|&<>yD\{}a{0/`/e7R77Ʋ&³f !䝝. +#fQP]ɅÇs N*M9CKd[әRPŎ?Kej*M tHMX>&o-6@2}~ھ2*⥥ {;qHߚB߲)1 cqEեBAンBj),[x,q¬ۘăh^_W8rѭg?_bሀ 1w ~C|S|m~%v= G4߾@~|S׎찬\ t}Zi:[,:+.t葭~ǫ V UQYʟin"; vF6J]psnt7n7ݍMw㦻qݸXw㦻qݸ.nYëfwמ;\ !ns_I:mjh&T7:ma8ꉕ/! 2lH'52" &۬rI6!6}vqaQpɓQqʼn>i[vN(AkB/y`/jP`ܔ=ۘF:ۮ .1 0!ከj0ɺڏ")p7v$Ua3<:h>>A6Zܓ)kݽO ExH7ߵZ < T'oW{1oE&e8sᇊ qNsD2G}BTbΈ !7L4ߪ(P\auD~$!D9uƌEf ؽ5H;V&ò~JhpEG?5_pGA#Q)_3 nc^ጋy-LP`VknVpRvA/;[x"roLtH73{|X b vQ3o!<9 6-Ǚs(N&S\љp{K3Ka҈l4xsabI?1&OS[1rWeSRW~Ɠ$mCȲ%?zBw#}7Z̵zO}Β ]UJ4q"T^qX2tZu |~p\r5E-+ Jŧ*۵Ј@Ӝ#0O(flݛf䍇CHIbd) D1m6ݴ(P85- UG7#N4./>a8qN0HĻ<{xv3k p`38+Qw1;b٭(p 肵Gp:hXJf33L;3L;?tgݙ`w& w"|'w"|'w"|'w"|'DNDFG:~8/ƣM骂Mf~^g^P(J2偻"hJO<_QvտҘ_׼UJdzz,!/[Nh!_9VMA*8|$ Az$I x " nIEW<crc\7>'  cO\!.6O^Uw'~l>)7i=(ؤ<ڜnrn{E jW1sSD}Z\Zvb}?$y T+ع@S3Y!QP,ү}4~ͲEK~Z Ф폙}e%c װHܗm)Oj~.ֶ%((shb';BR!Cۭ.OP TLtLeIOv΅ߙs!(َȿ[T#zwhs2ԅBK4 HZ;{iJ oi%?:Օ#"נ'y=|}*̴/]q`թ_GV6cInZWI"|UdԧNjBWB(̖|@=]Ks_d+$YIaiXD G(GL&Mb~{y,eWy{ɾF3Ľ)`wN9{}r2jɆ4 { :EmE4Vަ>WH+UUz ['ok(U:w늡;BW,1JdoȠ劖Z2۵gYuCY#6q9%JƭNCEH/yN,(Rw[ ;q,Тᄹ iՂ}/}= SZW~{[)ƫ(B8kA^u)U"ӺNLP= |^]ơ.yܖF.ж?Db%u e4J7|I0j)1e&7wvw4(<5.LHZm7ݢ0P=TKe̪/p)-ȡg'j.~fnn0֖ XN:/B[31餼KD 4(N#=1͗VLDߦw S/̷}a瓪UdJĻs}?d{vg} *p{a>Vrl"U4IJQŃ7* Wv޶ΈG+;V!?Q/TDm> 7=J$NM<|[n n|3N&bV>Xna,*jlaj>n`mB=dfCLۦuZNb!RjcK8kKL^-kgNz_UߗhK3mg<5עtWf(CF`wp_ NDXEo'_b[1#,g՜i3%etԸ#Ak.j:7uxjD-gE \!p<_C} ܵp@hT>!B݈EY^6il&G.fV*hstZڬƏ3 P-!50|ƈJqh"eG *Y'V #@<aQC<_YG<-/ض҈dzFVIKIV:_f(.,ʔr !m 7%~$K;TPȁEEi)?EXhH[ :*Jﲡikk<ɏS(Ozo'V)I9vOh>5/m1tyKh~0 ^i4z۞oh /as;as;~978QH*A4wquK qwKుZUYFFk=wY NfKa2~}s2Qc/E޲ @9Lڹ0xns߿VCtt8 QzHH;۴}RS|Z Kt;#SrE.tOK}KO$nze DW hH4&|/!$.НLaXpcKdhb5F4tssi07Ac ?8p=Tf~LIed8 =fٸ _,noE,e_+7Z챂BU`CC% y!N3V=h ܬ8n0ܡh0ƅ;qb t+lĻ(I~)ѧʖ^9 ;f1AEXuj=kV^0` qps9p# n y`(od<а}wP}f'|@ʪꍄGJ[@H܏i\`dq5aP#߈var1kGGi\/;sR(mys^$ mnR7| 0j-!ޒ2sF&fkC]NFes"6F8E׵B $]/PIc^j0m⏲"6mdž26th]Dq[|AD%yy=m_(cV}G(rwRg{lm Q7%ǿXuVƹH7BqbY`͞^71k O;Yk5QǼ%$vt]HrMC3{;y i5KFE}c!0 Vy[ u EC_ƭ<^c*r**8ni1Û|u.M O 73\gq8K:hCBYn@)2 }ɒlF̭Isп}>s, !ur45m^Qh#!rDU}-JIF>Ӗ}*\kxrmj瀧M"vIAvM;qJ&t5y[y<To,R'q#Kf3%f ؉Rc^)d7+;+?5/oVْ;0B#B{|Y<=R{aDkI_E&n WiE~oxM;E.1=JISjEWLw\LDo@ʑDEpHYkQǯ4x AG=䢯1I\{5eG^17{RYpKpA$o"F}9-NVX[𿩿ڕgbD$0rĐg&:*F3x e8&=Oې;f w{b˂ݱ˱~0eFSQ>T! v*wN$h: c 7+ Guפ݌aI3@rdٔV]98_%Nw Ȕl53hgq}v0 NP)v!3~ L@,@1Y~ҠT'~QyjVʠ:ӃinȠ 249Oz8@㾂-y1e37pupO6lk"2 xs;Oi[L!H1S/kgY{ȟ2gsS᠁l9#EA`@9[[ 8$p"wNͶOm0|âbi)(/+|jK% ӍhXI32E031I[q*" 4h6&HvA0浗8"ʙzF#B4f[hˋu t/n8LTN/DF8U1 r| o%93=SxGC?X.@/B!p*QVA<c$WFb0Yvj.+c[֮m(RΨڑB8'M-b H*6קEߊk(-zVor/SO(~k;k~p[fUREQߟOk$ #3KZÚ{`2sg] ђ Y3DtK[5R,E`XloiVaw?`݆l+7=-xܤ?3}/Lϟ>q;,tF\ R8rų/X-3#t@MGy)AA|U cIG0/;./J}M7GK۲){+eNXQZV-{v1dQ wΜ8 9T̬bf@::I*Kk4"*}$~]'0BbbyOI*dׄV Ez'2Ĺ#|Bi,K[YJݻ,y['%UT(8xM @挡M7nXW'J U\/SZp-0v?-ᓝJD8 ,]вBط$# lgYS $*-Ǎ[Ar ѐwKYšaiA G:qYwwF7q>BHݷ?` 򗿣ݐ%n< Q:Ҡ ȩ%{d%EW1~2.06L$:F4L4h@MkJ}d!5P;t" L45~HE W#(W *Qe51-;#%2 eɦRw[KzDpʁRJw(P3ȒAYlGN#W,)Ẍ́/AI`@ T!-_*U6vT .j52h:#gG)?Y(fwYCv?k]OiR=y=g,f0.Ҟf]P̐ka'1], x& Y:9q;&Wldb !j<}!va{]U2a_5+ ]oOrɌs2h!d^X[x /De/;~6~ȧuШʔ.dVknF}hK/mE Bw-Acd*eIJh8k"9>wg,[#:d.-Ȕ[<}RWi-8ɸCIQ (t^$Tq*Ot8GE B'k^ȶ{ƒq:c؍_*N(ES2GbirN45 16@4ީ^G4bݏ'Mck+}xߢ58T.M[KI%~!/ /,ihRth m%/+Bh G҃F0^xu` C`L}_ )R)o„H }}șSY!/̿dW]"y]0`rgtE }<ICIʫJ%KS'I1$IsަD}k-!M #Cx@8s`Y9sڡ>&LH!\h :EX4+Mca'SXV; U6U㑃IO}+W4TQiἢ}2"[fUWr0+N Pߦ*VRNrK&rȒq{`і-USma`Ò$Pn-AR'vbwq_aF(ʩ>w=9ZQBYXlYȞ |7loXٕte }a{YgS-i/: VFj3/kbIws@~ l5G>#D_s&ןqcTw,4}55hѪa4}5xl#,M,}AeH;gϩv radmY&32mk)XvE5iY-ˠژ%zj>z)Ez}Q;08HSqjȠ}(UGkoS"  K $Na`faxjqCe%yIp2ﴨ $_I h(A ǂ^iLM ǓD0FÇ^Zo7L&.O%w" +Gnރ`)(}2-j&K+)mqG:͞=# j9O=N^_ʂ%)bJv.@7TikJ&/~\lCEt0%v4iնG "`R  U$3%Ip'!LBÔb[Χds`=w<RcNLL˔T333XAEhxQCOB^s8G#8/O TCdKP<pXPzA;3A8 Qf‚W-4C2|X!ft"IEv+pZU΁ @s-2Ȱa-)|6`QOv}M5SJGP&Zr$aDQ Oݴk 21Y c0-qK'\ϳs5kx r=Ҋ=j#<MB<=,ե}:E6|VrndWxpjTPtN#t)#f_+l ''][Db+ 1V)wv?jpGXny<>-]"Dk!,Dӏ\#V\3Ű-rmJ4Oa)ɒ˄6K("ȧdk 򕱂ɇb S(8o@MpWtoWoaJ,t?=?,]r|kZjS0"@5x_lbriBĖ: ˂ $X>4<<خʇטb2OEA]*%>밓tItߑNbU;QU;Q%Q9Hwt;N넿iᯓ:Nb$?9$0UI=L_,9JGzU2oؐۍ 3i!?}4]}[ !lʥlKR( 0tυ5{jLZž偫kIE.w t翆މϝ܉[y?-8? M (giEFo?HC;6ՎvtN6dZs!},_w@P`a*չG '.E'W:02ۮHNXuk^bs7}Jm0]V.MՆ\Ⱦbyʵ_n6c&Е8_M)O, wJUd 9LҢ!̗Kk]~gNWYg*G'#.A@p; cjW~QM w{*1CX6]OPuR֪=-*NzMfNK"feU J#xS:5;NAu`v)qJu*ۻSԠuvsNXsNGW屝26djf2@o}TP M,UB8C]6}펥E"e}^b 85Ii;%ɶ=06v?*c{A?BI9-q-U3qhNd |[&?-ރFP;9!:gwle[A}:e|(d@*N4ړ?fmx"js1w7/Kc b HM$+{9tʊ;V@|5y#OJSb޽ݛd ԇ~ڗ/ڢQJY.ezwGq8pGG;F =BMf*$R1XE,K6j+iw[Kg oRnK5eE(Xî2ӀL|-_MQ6ہ d@TY9Kj7i+UpV#j"2& Έ.1?B"MXj m@[i,  >m: ?G*]h%,9p/\tI 8Ø$u/Y]`09jYe{nJ5t^ wL trA!5+Mɻ`xEy0YfIك:vٱˎ]vcbஆUOz]XSnUI(C3o{_' dm1o HҀKAZ ! CK ,CUK,K4!y?K]rTŢ$VFPeVx(ڍ%Ma$ΐK'\+_-LtUl.CmoɦD q-r+81}L'*B˻#Qm7 ȼqy<;i1.+-PG+|$Zg)YI彿)'uGVl=A,v ̇0<B.r%;qWur+=ԀwueeFjzS=*wnh@8r,{b:R HI׿Dž=VM<~-@ ䷅t.e6.ba Xi,2枿Cpdpdά(<~@yrZ_V};>;#ZM[.ް1t~8YbjW@U /7Byn H9f;#NY"-bw¿^~3%Y7ݚa@OSޮ8d`E1x,q_vV`}}[/hVވF6 6 Z d殷LP I{{ DT&)>cnAS" 9zg)Y<ǴV$c?5 ̵#? za 5B"oz|^ o[$c-c_'YU@Ĩ4|ɍ,zmG x24cpD{_|}F[80:Yċc D/M΍~Kp&#t˿xPr}2cK'2P;h:CSq0Q$.9Ү>H<{2Xhn\%WD-B=>4/ #,ֽ[Uе{N%]|y&z~ k+Adiyk:vLT_ C!"Xb/⡐Q3l4 SHiӐYX5m: X d{P/Q,+؁H 9,E#6a8`W|EX=S'T|s J1_u Y4+ѡP#(;PSMjewf(\!-~)[(n4`f޻#.#I+ 8?iK_A U|)sᛤz9ކ-svOe z=c4R7bHy!/py] ճplmXD\A*^R T%<\Q>&.vlvU),V_ 졖V$6;\8`y!3]plwt,- zҽ'bThf81~zYN meԇEI 2ʝ a-زb0 kba:Ta:)kNOcyV$+AT4Vj=#Fj-=b-}6/YFcPۙ7iXn%f coC r]J u-œӓ0ķKFccBY|<;n{*/WGg6 ]eS"3(xD:)$Qe|[0*Lw0RS0ݻI1iH:n*^,8̅ӓ(>cD"ϡwcrOS,;(\!j(hÂɳm- zy/1\UrdY4`rS(z{4sͧh=In*dswEɶk6dy Gl9 }#[x7\~@-0=T(/7%7ؠ;vaQ̚H@wt1Mth[F! Hoh徳KJ( ^Bp .З`?0T/nx%9F HSZ=j2ރhbʘWVLEn|$+4 dۻ4?Joɣ c~>+S%k8m` +aJphe׹.A*6,%`iйޜ㉃ mn9ʤm&F>k,*$3 ! 30ZmqPXfa]5#(VYlY .j?$O"$'@kA "Jo0niuUURvO֠\@i%~k!r%bC)fWl gj E(+{D6Ach!ypNUvdwU77"M?Hq^S= du!LjaɕjR.ەڤq+|1ZZ c|ަ7Iy fߛyi-9enJfأ0 jLc?~T0ՈbQ_b^CP]o/oq].C Ѕ?t]. ;> y(/֟"~F5rX qԣXry~q#v'ʷ6 hKˋ&.*GȃSw6/"۰{ٖiU>" +!(H;S);S);S);S)?t*eRv*RjitnB1N3ĕzx-kryU.XvJdާAgrC;ӥ=w p5XŚ@6a$̡mCR[!~-q~r]'!lk>Fw xD$%qX=@_:2{>gomim!XRE=`!A4 gG܍IXv:gF}WCd/^ ov`t z9'G2Z[-Qe>w!K60k0`vùEMr޲EdݤC{e#I֐Y/&Bq}WN!|KInNqdmn3 ]E5B ՝Wyڠ,_xK7gƸe@Ńan'!QNU8W8Ҋ` [ƦX&<3e(-LEmǏd-/@x&(S<%h@tЊ[0òȫU^U\N$Ş9R#U.ό-ivmd=KVb3& ptT1YOna0$}d'̗* #M%QLJ{Su~q4`~c9>^fFˁuD08BHVw4r*<!qT!q!Ѕ\P!2"]L&0!zDɊ-z h$r_2_|sc/eqL~`' ;tE675x͉ΗEo@~T|<4G>1AKp<)cAX6E9WKҵ$0^ogx!JAqbB6HWAܝˢW44ur. /@ ?f/K¥Vp;6VPۢ*IIP0Bb &nKCxjő \A/&|X?GRza,fߠIFqr//>'Q:2Y!Df7x ̮/PH1pxRLa252 S`Ց $CK21&SafK/,,2 tNjͳf+$Ք ^!#x{}`Iu1j9 7AC[7 F)rPXIVQeA!G3Dɓ&ЁO|q`ID~b6ÆzH`#s{D`dԵЋEi ~qe5g}Hp Ho!]<'M="`$FۓV,yVx! B2x:}p>P;z|vW̑l(yX؆ ;Fm)]w ϲAtSᨱq`,Xȗ$ Ar_Kj7w`A'y҂'PGU:LE:qaRzIy t >tSl7iײL2 )g,sa pf(7# 7\dϪ1nLl8Ī:0L@_q`$Q9/`kz$Oɚ4ۜpTy<[ I'kF\/x`e{Xܠwx[MR.#i,pm۝Wlb.dgDE Tb\n7O|r9` *vxŝ ]m6TEXM{!P.}"_ 5&ѐ_*wo͆>YST d)W\TNMTaVa\SWb<0L ;dbZ`Fнg+O| VHddy ~ðǎهgcXEx8l!<@ ]C]{q͓%3|63k&_VGc0 YLlfҎ].w3ΜDu$z2F^CSL/>nʊ{FP3:368p!pm\372Mqtz3V*[zPCXȂ䥙kvˌ<\&S].ePc)1yF9:8(`6&=B4UG,\zTE6 0)xaYQ>}]ؘp ('rI^[<@H7=rsLĭ}+ԕ0ȑC(|S},đCmڋIAt4vz4jMn b `tHE 031nj|"2PIBp&l}nB2g _BH$k*HYz\^6*GuqP^iի3O"8OY >lTu%RQǻI/5ď{RAF!]Q<)j՟F}Jz(֎ȳ;+EAGf>V?ACH?}g7H1mOy7%7dʣ\C!M(Z].HXc1n4ea pхk܌,2ݜBPZmgSVWchbg"iε W[TnP-YD Ύ:,yɸ5xY@2rQ>#r @dė=p;'8=е98Է}ꁑprm1Y s%mXyp}+gpۓƎ3c08|b HSCU7Z}^FqXX'5^6O  D;Tc՜V=$[ruJ]7-{6e|vwNdyƧ$.RZ*_Yݍ_wH1VZNl&}H&In#RF+/2yh(qE˚zV^Ѹ "{9!L8%~_qW,y̗e(Ɨe)L >>?`K oM{C1|`W+3F7bXwBoeEXezAJk0cO~уRB4 q!te!cV! щ=Ct#ā!#ġ!"y<C#?5D<3C#gt!{CLUKX{C®fa쵣zp/ۂm,[[UR]C.Sr6  ljDAU 4GabPD8wEiZP]gcFdQ!Tǣ( KԗiZ%~>3٠n}WFy:GZ.|$5[jZ/3ͳtTL,]t'ZSuotmGͧ9Ɖz\-)= [끗۪S,~O]*ݿUtS! h)CʢGT9Z8(A-WN*~1f( "op`"r@CkuB&R$ wmX`T@l(t.}2aSՏbV MvzV*uL_m[iw[O07KiyLO0QDtHHKin1Oϧ&*͹N,^IT'ĵ^ݰr+29Դl3"JE pFxQԘBH)錝; >1,:@J٩A]y0V)w8V?'4MӴ2@:5e d>J6C$CJ1!?V`5,-Z+RsUgS7YtV˹ghum^RB7pfs|pk^xͤ9ʯ|8)$xK`ۇK{as_U[=XZ #tp2; ;6P k(XllizG_.Z{ r*Sa:1~gʧ"t!å*[ߨ$R1Ft<;S@b kdx!; g A "{8Sk]!5˅U7!)jq͑h?% Lh),1;8raa./9_ހHvCeCeu/?q2Qv8(Pcw f+_92Sij[ Rdqhh/}Æ<Ͻ@#)!dGO.C|vV HOאvI C`QK;Mޅ vUGaD،٥e Ǘ;e(W@\$d#20iN {WwXBx8_OWE`DBVvϊ(ѫUSC1TJz]n[p' qg|Uɢ /g僌]ly? 6a:fgdbܪDzW蚇ILEǘs,J2-昧?O[@{=v։Kc!̕v6&g $Q 99O攆 2x4ВJ> 1` 4qOb?ݻvkIX+4YFNUj /4#_/)2`8F8w㊱]fRooI-yo&GZ :??Er%@T cgڙ>%%+ dh_^=DQ@5;yvӍw (ta.}ECo+DK`Bu)5=3 ?*bىLݞUX,+ۑi 5 1xa9 \OLkZ 5m=%y^1w9:܋dS6O`ALE"Zv_xG />OEIPrsHٟȰۖD}ɋ"+1[`ue-6S0RTHBD%2b&L `~*o(bW:?h(ţAB Zmk'W;P8]'n'Q ,^P2O"%עK" AGloARZSDgo8$D`z`mޗ>8v{!9޶NBD g!}4ӊx-DgIBj͕.xд|K1'̪InpGUb~ӏ-W 0 h-;<)LF6(]";RsGH>Wۍ.7HM})RQؕx [#8WF=(gg _cnZФ]z ]z4`k ѕ`~vn&FxHIUIV8t:8 p gὉ"\>"хn ok/MZ(ex9݃EeytʁAr|"OW{L!M@;JRؚL18)[o"kUث3~4XUmHENXhKTo,$~2lqTݗPrl]%4wPj;492|B;''di*t[b<@1rڻBk*$_7iu/(D$#Hǹ\[se.a!fYѽGp@M\F܇ >lj|l3Uf   V'1pW@ÚƞdZ>(0Pfny\)[ - \M Ƨ.v_'."Whfy@ϖU*.2J? dҔc?FkNq)`Y r^c/FYFI|.f-6wQb/(a<\YRqa= B$]hߟe%Ϧ0_(pJA?(9sQ?UI|3n+Zd.ðrg5J:BM;ۂgV- R2!SK6fhgpo2* 6fcˆ&\$t*nVnKSkT $߾>{ub'6}IhvAWŠJ|$c%P9tUZƒ{+L%7\kʔK{>/ѤƧh5I4>h? (0 y*^]Ί*&&ѯqJ<ڂʔt+ V5 -CS•|(gBf{Jګgh8i٭߳hE`|>3-FmOhHהm[CXfi4eಋᙵ.+VďfZ7ٶϹy7}?%u)̺P ="?Pe~jUz5#J@K3Ut͗iT#9ЙΝЛH;Eb8ѤwzEzRϻ&ǨMN54DGˎ6CsT.%d(% D=HOua?v8?Pwk-n۹fTآ.lTy A2{/Ȥ@4{:!("1WZ[{Z-[e7M f9S.r8ɿ&[^KWKNE^v6{6Z S`3@>&.q3vqv Y1gR)zꓢ/H $vKW,j`|cwuYf_jjAx=Y$XNɠ0 7+F |z[@n Xף@QNoe\Ճ=`3I&coXE def^^hKOvz@_llJN7$A6{]2$XDaɢDY)` n<)Z)n:oZ|iJ4%{o-b"ݖ;BF Pb93]m&ЪłI.Dc1n,Hu[ K# &e]#_(#wtG2@d.0voN1q'׿k]LU޿!#\Zز)Q up+Q|nbz.Kǣڦ|R_RC+X-8_n{;!B_'o 7M`u9m;e(QEʹ_{; A_|hU.8KCi;n.T.{+  7n EqU0F3LzJYy2Њf〈u3 碘\&O=TjNn~d;Hw;J'̿ϱeф%~ hr66}O?&$n-H儿_ϧ[IDXma@'w2DjFV:rl, jH%B]/\=]?\L(*@?Ptu8Q$baxLзgc,0tg8<_VIb-3ϕyPKSFQcPyQt4/Qwt5/grace/__init__.pyU1 0 E"^ApvAB6%mooTyDզC̢T&Alev7z.7YsPKSF% /PyQt4/Qwt5/anynumpy/__init__.pyZ[o۸~[ڇ-b68nR'pDI\SJRN_Cn2CQ9vކs\XS1V#Y7JՙFON6 1 .ں[wG7o'+`/kHl)Oҽ25%zo[<_;Zx&sRRFY>C{JhL+Bf8A0g67a5´+RI4R,osqgK`J6ˌ@CTY q%U t;c%,9ivl2fؘ)~\ rV4sFI?X6*fȥ UBjI!,[,0P=fSsP$;:GW;Ϧ:DO1 ̱6܂0E>Zx%L`mBxA}UpN+׭;[qSN` P͸faAZHdYo7 !T6yn8PLg =HC鶌Fm (d) F͌((&T$=_’Pɬ!jtJ ݚ|0GP/e X1s?1D9<'8W`.6 =J_1sKJ3s^+Pf4, L_x5K G!$4:[UHMnS@0]0%7hQO !grY;S @R&(vhBL;n{G!q(lT ]$$Ŝ%OYO, )K6Lj16Xl) R5v’nBX DCovvx` J';hyC9U`kwL/VS:ǀ KHSУfL O !q=וkˊkM!鼁AWUaSUQS r8qD8*KcxbĈԅ'pW\[\&B<ۖNԘv!k0 F"@O ;oXtq.u8AITB2a`*F}h]g pC|#|Bm8h3Cʉ)Qx*"%ecτ}Bq жQHlT$ fytHE%+|0|0o)a69Ef#ms&nÜ'Y*iЧW1Em,H`"J+v%u% ! 2IH$tRDMHt .lbR٢a:?<-9 qO(@qVPr'%!T/AܝFhu訄7-#f-vԎo#,2FLwnJE"I&h'@.@:)وB[NAH=pThl1%\.Wqt[4n?v?Bw_WT3'Y7vNK|LF^o+=/-F_Ǔɏ!ƶg PrOn @g~} ߟ? \|WEnj!7㮻tބPzn~zv>pvzU;w%M7L`L`u /%qm*ƳjnS[7:"-ur} ӓÈt "vL2Ffx/#3Q%I8 "yrbrӮUrpVL-=i؞5ze Ad|sLg;K>"+iEn#~T{Ǹ13JH\#W]:Ō\QOO>Jɫ{ ckp/_]qUxrLR'4۟ fZL+SlTOnV & a|c"~j oHrE] BdPw/ # %Ih!F# \Gdi;< ;9Mq]=)K-Wj<WLy<|T'i 'cyr %7ݎv4a+XhCB{~ZZ;j[~,%oskdo`PKSFCEDPyQt4/QtCore/__init__.pyIs(_}oqoph"ewFQ"!Z*v _ s-޹rD& 3rB"\sS7{|lMQ֭M5@yoϔk]_45$~w~=ޜ_~z?]޴7nWGǛۻ=Oqz<N˛|vp=AWGv@gBn",JgE>o~b]Iܧ.tf".4O"Bfdqw˴W4vN;p^}ȰZ8O]...Yr|Y?tgoIAӷd_WWU{h)ΠTEkLPS [sQClSCS(E,GwG1q:LF!׺`6i qc| ͐P,Y:Z Su<]'PwsZ-)Tnu2Wo+OQE)ڐ&΃л&хTqqg0ߧiIʕy| ;r7Ț$kGAwIps,%@ϰ $ 0n0c$yJa !t4 Ri9iZ2$Md+5uN|}*fsJ$!nk3 -7P=γ' qzpxGDAq7VuzG ?zxݸH Kv<aWi"HRJ=Qjxoɨ3Rp[eihRlE8þ5X0ao`;.Cޭ(h4ҜE-}a6j2yа]4lܙQM |L{ b0(i0uGO Obz}Q]'t>n@1{02;ɨ>jbBMu1X%~@n22W=xmYMLc'`x,3EE?ޡM#<󬨘xSM2ghG":U$eI˘SEаM$8AY)3}S:T f} e l:p! q}d{ɒ[D: 3bo `[A'0%YM: tc0`LGڀk qW A:> 60fKHY2٬v& ?CdCf .si O}!8-/MAv &ebdNkFP!ybc8\Mae:96^RS?չdIk0nqy{!4rki*M*{(wdH"=~㿥xED +b1a8QIYy*X`EhM%%s Z[e  Q@5eU־ΘCSL@3^PNE?<>tLX\UmS _tc8p 3Fh&8)K3MҸrkCm"s#b~*zް> tNy 7 )5Gt; y נ9܀[fΤ',pm: ~X=]CmnRx<2.x"Ί";NKzBA:`}6ձ[@gbGa5cv&lƇmöۇmöab8K :E8B""皦fK@$zHM>72G+''$ה˼ SyN~}S(EA\Ҫ& G: YZUO_D-M ֚)w-RBGJ{OxWwF}IZ %)pAץ|d94Vo+H+@5@PU #KCXu-RDR\asB`]{C4|AM+uaݝ9q^xN&ΕB&[Ĝπ,^P?CP?CCP?15v(\LX[$(ϷBYpY\}SKK8-oD$ `638NG'Q{wӏk~?_Iƺ`+Nep- E> l;tW?2Vr٬v;_H1N`Frbt@ԽCMmҼsNi]^~LʽH0wqfWu}Ы"Y kחݑ:owj3tgtNgD.I.¶U4]_- ĘGp&xzYI/`2@4vY&6Btw: !WF S(}+B ~T_D!>J~(]g*;z^x ǜJ%IIx"8fG/O U7MI%lDh%oa&AH|DaBG ܗeɗEhI3Jr:)xOfIPE" (ߒMn@.2̎Q8axG`Ly %Mt|2S訪iGV vp-5#b{ $v|Jҿy$ʏg.V:ALR5~|a2؏,1_TEHJKj$Aն,)Rڜ\ .|JYJ:, WpW!ۉ˩c&OM=M:QjIZ]% >I,_h!LNj12$TI@}dDr/H6UM:O*$+g8No]V`5RF:5 6 6peAtМXܸ\eb ·7ua[!Rt6SFXP׋29ȊJ7ű̀7Z6C9qZvp*#NJ9>*J Ѱ/m1I1/+'#+NNG '>Wp(-4|@U\L!#=^'e}u0$Ycl,ʨb.ℍ.Qʓm ! T7_D0t8qH'i2/swLㅃ^E^`9tr ZqE^݊( -ӿS49#`:y\O:S&xqqLJyT5(5}j$yRsHU;˦Ih h>tROS @jx #BYdD^ņT?:{+r&D\Γ_ty `Ufk[h'ݳ$1:G9HEi&&t&WLsdPO.Ah¿KAdUDmO:ѠJp{^yJ?#l^VxjSS,Zp-[?N\$)}MC|4-Ieiׂ.T.@Ģ T7&u)I#C 'C'Mn,΀3F's'>$Q:]>n@ACM 5|j=,yO_ʄH*jD1Iւ6U IQz#kߓWMovYX5 _B Ï?'O 5(0W4f3(rj5&4ן\v Q Su|N~$/+RA-3@<}i"ZS@oBH|itPfw|1\ h.eSJ9 &y̟n`h]}6Rߒ*eDMؖ ӞJDڸ|_՞uCLAH%Dw 0[دOON$ݡ1uׯ-+srOx0ChUASҮ' @Pii'q*v9ly^h$_%lzՈ ] +sӼ*ތAYŢ)鬅-+iկ9QM'ܢVBH\ϼEJ%v fTmCes\]Z_~2䏁X9Hr%D3 TrEhjYy{b*3iq+ #n04P\GYsN)aѳhFJ.-j>+'ڕLjXG*6tC^bV/I6<"[$HjA@8'\D$nP nYdA(19 ye N gK5Jcj2"p;Zװ!׼Tވ͂4$ҧԋ]ׅh<5bMv6B,RBȚPdAAC\7ـrN%ٞpoD92Q ven%oAOyss22@=dk`K@FOa<B_VG#9ߜ$xYxmj-ț*dnl'|2S"Vh&quZ)T>2N]babw0#Cӈ>65Wd$0&B7(FA z9[ߴ0>wp46Ky9e0|Hؿ)mG=4L4'Еuq/tf$NH 2,i+6&; 7 |DoOÙ&8tZJX #OHN|ND>t*G$kŔbH c蒬;E?wG,9kJa섲SC†'[jvu@1W/Az)I֛pkm2oi,R: 穚< >MSWr.qNXoKLh$MȓfAffSbK;jBa_ E6(_a/cLmNir-]o2%S1AX%cڒ\&Ti y f}W\<#n-sDz4^ZԴ`Q E`3FT,\q(NJznآL4R;A`-`=`ND9ŽQ%k[W/\%s/Lf.+pp_l"+ytƲ)E)X@a痋XT,3v/WIq O+"t\UXgu$t.v--Ԯ+tk~Ns`nP.^)+ %:^-o:—Aki-C0\6"P컬RF5JRh&yԞyœ$?IkvjyW'PRPvԡ/ҹ3DMMÑ r^a|@$H0M݄Db@/;@;|a wISL蹥ZIQ i .?e͓3kF.i%: D4N85QV]WD?긆f/Z+WuHq7vH/7SE r=)rgD a8O0r 'o%tJ,ms#d˴,c m}Ԉ%?HjrC443r.AZ̩\z5Sxmy[+5s|v)^s'ډVK|NJ6;&LXFR$1 E_xL"WZg}-Jٗ; )_ƮOQ[". 3~gT脤|w|c ͩw-&CRht&CCz<7KMĊ> 4]5]|ɮt4:T(9-݉‹0*2$s7z^ FfoLQfF^ fYg=GX. g 6TmD1?g=%㛨9X2$׮\F@˂.ߌWuYa|gR6etBa Io N)Zݛ{ Q/YxɋGt_{2mgkZOU 8U \6H 6)]}T>?[ˑ5o?v c?館~xL4h[B_s;cM+N:3[-~4 jwZ:|,5w3L ȟ@a_e zའ1g)6tU2Mtat`<Gyѫi(mh:h+|š%GY {b#LH{ c4wOxmnjP4- xϺp4.vԏ'JviXKo~/\Ŏo3w=l!#*Υ)W$Ɍ6Y2N9r,&򚻐 =\E\]rX0,B@Ƿ0x=(gAk p]brq[(Ӯs {TO愘w|bc:5C$UAْAUI/s~пB f{%宫iC-AY~V)w4-޷L+Jr~Xwb]&/`R ؞7; ZmqEF@%GE0]F?'J|`@Nn5cyd٘EkfM[{ww]RI&.8h^b IHTMIOQWxVa"3k!!閄C$lǒp'a͊z ǡ<>E]Aݜtw w6,dԞ#m # "ْYP/i]p_F+6_B@<9;L-]$*I&;>2sxg5)!>B 1ݠk̴!$@F)S6g!\ 3Ia:d”Gd÷|&ɬzސV0o *ėfA94H^[ oqy Uv.5]Qdg!P=KImnA]} UV<L-a[?{~D#Gߏ|?"#G)|52OTrO)RQ^ρYPAͭ޼9C[.eGde)!A υ4k%؉KƮnvVdWZXv{zr&8[?9n(;U.7'Ӗ|$g_pJL -y!Rq;t:;~#lqpFilk; NCW5r@޷bj_jyꎿwzVVw"!dz2e ;a]+ze}zQ~E{SY);;ZDsl呥{- AdP,}g/e;@b/_]SOD'}zIpgOS9`V:`Hg4MUȨe5xcP9e`]gIb ؀&׸EMFش)‰ȩvTS+gU`{104 p-_$!Q,f\xԞ4 Gx<[aK}+7 `|=_ ĮP43h PTbaj352==d>}oa=vf vk. Ł U^,/6ۣ0` ʕ_A 1+&=; R 0 >R,I(@ tk`ITA"<V?Q%z#"$H~VPǏTWa])a}=lYC)lawrת|C|E(J5#ڝ>9 "}~`f{DD(Y( C#ˬPƈ(dJPf$Yi}[N|AgNj;p"P|/oC<ͩ tDi7@wCuX9n kCw\mA1*zK Znm|Y>L}אѧHn/xz7?~l/L Flb]<&Ӕs>zC׷BY=qWX:y=<5Ƅ{LoO3%Jc M$a; ,+Lf'ɼr}|O: OeDj! ]psUnu;w(:- F͵?[p  VfxggP`o|W ?0. C#rJn i/R;t ;JCE H[mV)m1rlz Qsb'TCCBo/ 4\.c/6>68H-cyK^_ NC#IVO&ހ}&^춏햄H;U?Zr ~K[01hIcL [Dfĸ%q11iIeL40&Έ ihf9b:ڎ{R\m,J}-/K9xhw؜AY%Ѹ3]W@gUQ󞕷)* \jz)љ~㇜ڮ d5OxR){Jo NGkVHI&<>w#LqU@(Q;o*mʈ_L~Wr^Uy5@D}E8DBQjf( h|s^N]Kqs"3{{{{̉/iL>R>1s?F Xds?# ѽ0l¹fY=Z =czZmD yJik?f9lXy t<Ep'  󃡱]_cF+o1wZ}W 8Fh8^&S?N8\{1҈V c[} 3>ֈ3c#bL{[ӯ&2ag+={D7B <!я#DG ##F#{D?qO="G=?<]qq?4st:Fڇ03Yp7m^` Mn.%afG/ ֈ뤪:A=JD`MBhhY&.PQzfV`ixi? xY 9 5#Eevj|˔tmּ@?2.*/諭m u}+S+3===:88%$VF᩶6m=6`.EClfK `߬7-񽦄{ 7_5Ew}-n=- lo[N &ԶmMN.}[fB-2ykxV\Y:lmQ0{'JLEצNb!PͷV9F:5p&޹r.^#Jޥ$EZ9eeUCzx3Y&q#Tm`uS.]@Z`.%W (WxgvOtԤҡq{ c&{}d^5s`Z1$:o#!oXvQ~Ԙjʹ6mS3B8OxȲBh.)~M-XO}<|՜>1`p e4\mYy7)8:H]39zќfmJiT\Y#,y<=y>n$*>%jgZ3>>D3LF 9! Sז8Dp^̳5euȨwmCe:+۔n<78ĸpo-L?:߾}4BG[׷~sO'd#͍>MQ9Tu4lIJ؜eOaDu$%܎g#@&UkO*# NPYIDO%^0zVHhH+e^lB$~pK EJܱtG' ]k:N]@b0<[XfŴݶgJmE<ͬ;뤚7Y*iW4ak֬3Ye^<. "چ+;A[%`O> F*Z,g`ʹլs[+sN&Yl@v\61k:)f(TRFVy^ѫj}f灕@/l Ž:5@{]oO//wf'FK&axƀU ULo)ZF7K2^evXyxW !pN@g !wGeh>շC< -H%p|)dqJcQHJGy,> CtI|%K+uwmG<" sv ],|f)9/Dv[ +-+4}W sLģo]!_J0P)XNJ}bL0xCzD{nMzX4|a8:pS) MRxDpޕ$ָU4 q Wb U7_͊@%IPO)-H DB/.gc 0բ(X({ s[OoO[@ʑ U.l4r7tr?*&GH?t ߋGN| 7 "Ԓ (RLH"9Hu{ ~+ʗ)7tdX؁ M2ⓎAI/*JBMWo~FSO $?aGE̢= &mS=XX][O;b @QZWYGayE_e(1fDg񂿬PɃ|G_"$tp|})GsJmi> L QR6ח")mnZ8GQy^ 0ˁot JQ BZ|-jv$ˠzcuw Λ{cIT ;f\{u{ے+VKR_U:&"=@[ԆX%"^/R hbXƋd\]ުPmQQ*Z30BJ$3:R7 |3Ӆag?KY8-hbĥ╢t!(Ghy{G!U>{x׋p ۑE+Jͷě1Kׁp\Mi*kZ g;Z~21:Gjͤ~:y~[JPr{9-YvPZ%[r{yDáLh^^СƖ ß0>:3đ=_ݶZ7gY0PPE*-),*Ül1 44|\t7(0 2*pά;m@b@ƒ ]X;i(%G'o>d1skTl̘#OG]h TOEUh9 JO8Ď/ZmVqE4Tz!7Ŵ1ݾD[ RI߂@$M/98P_ G+6ԙQLbc'G$!>!o()sMS'KWZ}OŽ[Iv)Yqخ~FYhJt61#")_#">PҟJ3qRL n|`${^e=IФhb@Pf/[]Z`:ҁ\n2c}]-qދ[lwMY_[PKSFd PyQt4/QtOpenGL/__init__.pyUr0 +tlo͝!e&x4' -6t}Ee5='B)*/6u4uI; ݒʒulUAik1((崞(ƌ'ްq镁0:}(N$@6يTuS&8ۘΩV}.<1f\? -3Cn5~`HG`>lR4aĦ t!InǢ7sTtm^b>!㷆Pmw媙j)Ɗlj7TTTɣSg׺RNB_i"ұ ߓ鎕͖,Q >[)pm9l9ٿt0 PKSFBdqjPyQt4/QtXmlPatterns/__init__.pyQO0}@B%. oK._Q\dzvNHe It$6NgLƬ,($Cå^LT4 dp{ybXvz ܚ0k穷&wŃ( Oy22b̅࿐@׹9- Pɼ_m>:+j3غpn}X#LsO"}mVB);, &O7_2ܕHU|OTA UШrQ]U;θ~v${zVt0v`(5XyxFfTPKSFYsnPyQt4/QtScript/__init__.pyTMs0 +rl;lnqDة+;6ѓeIOO^GŪb*Bʝ5߄'܈Z)ծ˽g"J~tdepk\8Ndo̤dK %'Sr,q~{G9Xw%6EhR[e+A {&g2 9SLц`ڸdmb;+'~(m:V+}^#C~l=[Y&L(8;P 7b>7?kQĴRLIXA3 tsx$RW{:)8;0l:-8ʷ}6vӭ(QͰuvl^wgu؈TUUkm+ߣZ9'}*Csw+(ep 3g!j7s(+ٶ{UFQLRqX?Lԑz|3Ul~{27*EdA?k-6$N /\f/b'%wPOK)R-Q)ÂeADZ rv9M0 9*/҈(ѩ_) >MzߢU8'{|\ly'+0hbm5W'"c kwq[g+ϊ]]wv J+i+>[}.@|0*ξ}OΊ'jdJ^AiF Yj'KIŠ5lnȠ{PeVB`₈_j#aZFȔ]zeP=娵^R-;To{h(%B7eV.7upf.4a@8?acWthF n70fl`: ?KX#p1͕`Z\ )6Fm*SvݦD5۽no khi f|&fwgY-T>f2 wGk#jq?a78-hy:䖝u3)}c8WU … u Kz8k8jCxF=A צtN'Cvɨ6m*y> :F0ԩ  g@YfZ䮍QG䪱< `V CJ*)U?(MۇFȴY8o- Φ93(PlY?,0e#D7aEc}!rF`0ܮn`)Mgͮ\jdY51Zz5+DOd7OE)BG|paiO= LX9mc&k 0h=ASпKؾ̺wR e?s'y"ݛՔd室;BSV58=TM8nq\YB-$:pƯ!و=];7J9x;b0jԽ46^H%"Do#"dN"IhV3P9sM0Y=A@=S_v&RguX@qHkđ0[N6p[}T#B`&y,rŶJVsz7֨ nNFOz5ܢY|IC5mm DY Bp=i8Qq/c i>ĞиAo, ?|]'Ud,nfŶwͺG w9ʳ!ܑ'Xt\q"$jW[V̏4nKl֮E^?8tZ$۹,Z['=<9+R.ʻR!Īmبm]fշ#"Mxs)MF0e̅(P;ߠCIeyP_<)@A9ni+2x R+@KP R"( Ηlep/j~?n34ЛI?:ΨYu!C;5_o5I']4mC0 ΅Jf)Gp:+ z0SËF '=5kӚ󐚆/^)S+r2m?>ެn."9t2^d24j s"y"gr ^*Sَ[r3lU& tꡣZ_+||KV;)}0>z} zj?ʿo\wsa |Q>><<+w^^˥6ps]F>M9re+I;(> pӾh]l|.H߿d' 4!;'^Qw O PKSF2JPyQt4/QtWebKit/__init__.pyXR#9g솉3ifB*E%J*%UI}KSR)o.ϟ ~>e;P*sB-q:{ 8~/`7B}@2ɬ=Ͱj'2 ?8~7&9>aَ`s,㕳sUnN^̯SM^@)*K^Xp26V~l mUnet X&~^;_{%Ôdm 1 xV+gQVopy튁nk?7)զd(cLgE1-uiAhYY@ˊ+su}!DuB#LeBPgNǵᝐ€M),+h7{\CŒhAxBc~>W=īsMP: oZ7_@؞FC:W; 2B>iMnQ#aB%AχzP`$]!AZgA "uëC0Ը7ߦ|`&W'`f 7 *l86U袐FK*qK;k Wv0? 0ءmfDE9+X4[aJ8Q@Do~o+אaoZڧI]P)ī2cGF USAaDyzfu]2>fH^YQZFjQX46l4UR~ˡEbfe{ k7 zJw z]h~v./脧4i4a ]*^Y&&ylm %p 6W6Wts{/V9oa=adZ OHJu%H H; UPRv1uHSHDnmgĄ4Y"FntCh ;[\Lj7(7jIvQdʮ[M_e&ہR3n|ʰ[;4p526uv3--4 S9䰗as6aA:NQtz9H/Zx CӁ"iu.7< PKSFbPyQt4/QtTest/__init__.pye 1 }Iؓ^ x/KI6M}~B`\fF GC JXXh2at|Zzw*P-EMpJJ,}PE< mcPKSFm^PyQt4/uic/__init__.py=o0w ƁaH4 24ꂠ|-E$Gɲ./{t_tL8/8am :ԁT-6Oo$79A+v> ʼ7.X(asWe|/"GYrW 6fO1f\ e  =7^%YD0i3 ƽ|PKSFY'PyQt4/uic/port_v3/as_string/__init__.pyU S:C"E#1BǯV /7mBSaQ(vN#g*~1P( mj d+VÊKPKSFi߹Of'PyQt4/uic/port_v3/string_io/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\\ԕԴRP(PKSF8]?c$PyQt4/uic/port_v3/invoke/__init__.py51 St+8:mJjƷ?fq@!($FW/9x7PKSFԡ֊PyQt4/uic/driver/__init__.py]= 0~mm''Atp/T7V-ީ-)OQ!cNdҲ^<Koygn5;4u,̘#dovu:w]{з嬺׼L,*7PKSFQʫPyQt4/uic/port_v2/__init__.pyM0=M #ژ V ӴS"ws͛'P.PXrCòH&*!]EҖ*eKwSP'9|ߋ!X?烘hZMnw %MiѮAL#?7kq 8~oPKSFc)PyQt4/uic/port_v2/load_plugin/__init__.py5ʱ Н舿`h"j(")q6.7w%֓2LnpqoȟEXl'hJ >PKSFT%Ke)PyQt4/uic/port_v2/ascii_upper/__init__.pyuWoA{:z<z d9sג%o 7Xx뽱wI4엝5MN泮];9jΦsk2ӯ/4|dm,s`_=ioLM/^F, ɶ6ac뾞Lwc^2 2 2 2 Cd CeW'N:}l=\[?wKGacsk{gӕvۿy?xϞxXן_jLd$2DF"#Hd$2DF"#ȈOOOOOOOO/x ^/x ^Wx+^Wx+^////////7 ox7 oxwx;wx;ãoPKSFY'PyQt4/uic/port_v2/as_string/__init__.pyU S:C"E#1BǯV /7mBSaQ(vN#g*~1P( mj d+VÊKPKSFk%zFZ'PyQt4/uic/port_v2/string_io/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ \T`  sPKSF{xh(PyQt4/uic/port_v2/proxy_base/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\P_QXմRP(JҜT[uuվ%`...PKSF8]?c$PyQt4/uic/port_v2/invoke/__init__.py51 St+8:mJjƷ?fq@!($FW/H/M˦h~Oa4w *f8ӷ1E7 a^/\0Wv%NʎR,%WML 3[ɞ_LQP+}"iwzm\8! {T}KPH__]|@4 pjNl1V d.2"U!V8 /p"pV +7"$̎e/ ILd$hdTgyJ,YJ#¤K^O+@8OM< U+ÜR [f)+qVㄴUYhjD*?5Yɽʞko3ryI6Օ xJ `|]3;|CUWz0<5Y=+9E=)Wʶ v\eS|iU)$UP`&uq0?rzr^Hq윰7՚CRLY2xy lFV$F= ~ a} xg@_lr4E֮HD+ر$DA_dv?l>x4!aQM_?x!ih9. E;-[)}fbg3vQ~wPKSF&':(PyQt4/uic/Compiler/qtproxies/__init__.py?O0w om7脐JOƹDqqd޻;9+[BileC@kբ*ǟp݂ϝKd/z: p%1cDy$4{4WQSHzxO3 %^)˙ݪ @iү|jĥJ!.}; gkAPӲUZؾy.9 ([^JZڔ~PKSFgDd6HPyQt4/uic/Loader/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF{n&2#PyQt4/uic/Loader/loader/__init__.pyu1 0ڂ89 *HA:S6r&:{:x"#%X7"1d=kEPky~%_?ܼ2|M//ak'4O.gVǚwmNy' =lNS,a(&$ZΈvAc}{io7vo lrdЖK;@r?iOРVuYVeC3QH˹0;>Im";&PuiNXds/.y+㽿=^-9]Oί,4 4kTMs yJ> /&<- K!*`.Iu{jdըQNk,dm$5y2}t:I_!>5,X9doF_Qm&r&,ۊ ӥTgٖs`+-{9eaƯg=G(AO6.A5*>5K)$:o*Ydnf@G!qA2@"#ĬE(68шRMˏ?Ӵ28[R y\Sc@ѱ@4|4b80Ujwo20ӐjNo .~46G 4aHPRY$ "Qfavvͱ$%xMy|CIkQi<#zgDIR=L^z|/MlOM0i_8OogfxҼ/TooG &;='^Le۽smue.;g8 6) ;J腙S{6my06<Lx*F^-\!婇];n;\N6kp`km+(+|i06rh=cg(W#e_(E<~AUtV!DEo(bXeFtP({0 H%:'a Z~7Q&A(5*}u_Q\폟(AwXNp6Rz9zj=.z.bJ"!|jD%qi&b@=l hFOѸKfh3G1)Mk^ؿǧ|F̿a (+mE>?yzoDǶ>^e |n.]:g8)S8n|S305#4}cD g,ϒKz}`F >ЬlLouUUuUr)Py򸬷|,#y |JUkGxGԕ_PS~iZɘ@s=ʹ9(ݷr@ge0lO5anw`@"`1E:wAY؇ہs#B5׹ٿBiy`77OoKY?ytr3^/ Ne{r-jjBSKH2c*.Oö9Iá(#I4MI5d-d͖Pn/g!]9pC6Ҷ;f&mU+ydm%`3ksxs.ۗVNK̠:'[#q:;^؈Svz^@u;ҁg;Hʱ!4t cg.> oxzx*Q.,G󽩞hކ+*p|,m\Ju^/η٘*t-$ ;~|>h@!:~qX|=[6iwFмuzEΘhٯ9i,٨;VsbJS5ۿq#^h!un+U R=L{& vMQ $"0Ž7ٶرqhI}J#+xpjfIHWKf}•4Sl9\]qp8 AjߡO_}EYr嚦motĩ{D)4[ˊXhФw-=`T\[ 8I.dad\ʴwQygN +Z0X=_}9鹞㢑Fհ#&kiQwq~ +ӌc4>+?ݲ^QSՎu[QJ_<9s4 ăIh 錞(U*}}N03NP5pԆcikktQ;wT`1A#J =^チ=فQUk;l~oQf= 9B~v!]ȿ.$wM5hAS ﯩ_ՠ}5諿zIC/[:;.~/m.ܯڰrX̀kUGR#jR,Uyz9' "jEGͷ`fpeg|=|=,lvm5yݜ?l5蝺~+^mے`ΆGO7hW<]Wox蛣Ԃ; ܝ~/RkM63UQUsVwk4ᩕ+[&#VGCg猙O<-&ɘR8t-Ew/`:l4e՜ MQ|_}>_v7y%h1ۀc-Ce!8἗gpq|܄gN1lp84C[&ZMd f;j+yȐ%#lh(P@a!QӸS!@)ճ騦_ vE='fwlEics:`·뇹>^VZV6|g򅉊Jnp^|]`&v|t'M#3nn7 o2p2LҵA}9Imן^Z/;/}:}+ckOOBUhSS{zV̠vƠvPیfmO'e.A5՟tIr?9!mI3 ^1ٿ |A2r /{nAg^wO 4zREOqw?X R 43ʁ&Z :&e kch$eZCc)`r(E:$rloœ.U΂a]o$Ed{jyb&ͳRk]}5*noLЭ6k)fpz~8=?pzNϕ}?lx3o|jxbLKhќh"_ωX`}bltc5'M", P4;NF7bĒXIx.Ր|)eohđߴ;59^ANލd[~ůڎ&0}lTZ@\oꤝL۬>T?`$ULh2Sn&y1xblwgjGĒK[Q1#"”x>űbKd~?Xje ~t w&t-p[5<V8?h]ILFEfwӌ" w,'{!: aKӍ$Ymص2AcsΧI%OWEq87YPw(ȅG<΋<},J$QU GX{If2"]<–DYG84D6DQr $5 Ury,]YKk+Ļ/noT/v׮ K1vzWqNj*Π/ngo~LZK5^WUrݧ`Guƕ j4YN*Ok'!?)c BZJ,3If*-!+p6C;(ʖhw< )e)Mt#(`V2VNYod(S<׍,ydt٬\uQ"G\ZF/6S Xh=t73VK{65,0<2R­A6f5H dΑ M Gu2#VLһli*og2d˾7%4͜% ^*'f;eVZxJH+ O) QHp&vQVPЁ# vzj|fB/-ˎoJ*tGe qWwSfcZ2a9;h8N`QrLqk~ M)J&9.yr[2Qd}/4/pGҕJI2mUq`>ă7̋J#hZ+vu) 95f,Ǚfc-;tu rЏ9S:l!fbn|T.CZicG4'PK(V^%4hA&6WśUVhT{˔I,Dq}h$`rOE|Ф3JWª'S2-cR7Y*G=P,e6Id!}#+L6UeSP>yƁrJz5@fc-B/J ѼLBf-qpUUJmXAպLi7Pd<~tj6cSj0"tensܐaғԢya9a\`dTI 1nSܪ$9;$M'M_M7M5aq805R>)$_L_I: 9҈aRUR|xOyzrF (H)[Y'zG 8@\?$Q (L.9Jm0YΦP-H9nL8/^YX N1wVor["U%Rat@c~6"6 GߏIYmz6LƄ3bRO97ѸH܏Z8}p`9Kj7F 2"E.sTgڢLj*eE͂I8ʶ!i-S٥ԜفU&.hc8{|a ! )\'y&& wɊzQ@V wkbIVE 9orJ fmR%8$uNAhLsaTm&|4b8:dܼ]ǵo@C6ABIkTTUs)ѩ#Cew:r}/ȧbt.;TDQGww)%5gn1UDp, LM+*F.5&'Enp:X1fP!I2YMU4glupH틄o!E˻l:WFꆑ X)Xu՘* cSCNf ̵10i),WZ|tb')2}V<.ɪfNЅ1kLD5tTr݁7j[GR;e&pH6)aj.U`ҤIqP֟KzRQ$e5 $0\87 ؼ'eM#ܡ@@2LxDŃg2a Lkjrf8vJ҇dMl9[~.iaS1 Ӥ`|^.ۊo5&022f&t`\!T.Q[P:fNƽǕQN+qoIj}<}Շ"{72eZS:{,u@drnŒ஍0$UKu21m酌gw[#J+ѓFmD6;O߀b$jƥ\C[֩_?lz0!w3V&qЭyxfzYUhŦCZfzTYBfG}x0{sE2Q_s?R[Ecr@0ǙĺtV@E!-}3sQGw11i(zxu״*WzdY}#93Ɇ ?|(s,V)@T=95{ukS]8%-*ɡZ e KȆqW\ΥP_R*'Bo1 Hr6PUQ"E0qX\D:j^K-JcjIVh 2[ng!V ǂHc4T1M--uF2ɷ̀ )u-GH)9@5 Tr- E_LyQB#֐8#,1FgNЄ晰pAv:h>elD{R9qF!:Z".b0fe>dϸ-cBVZSHTxo P,nGd2)ŒFi)jUT:C;cbȐl3Zg@uTHy*riMkz1Z75A]WN7ߧe2ɢ!Adf҄R*De/& P¥>q! l*txL&yh: 95i##:I_`V!E6b!6yǝ$ʺ >?fXyg\uIY-{Z"jrqOZ/G7ɕuu֧Ll\h$1h4@t]lڈM%9܀`X{l hH!급d|ڎ⟺LP[3#ހWOMߨUL=\WO8z쁟(} Fq/j,Rj,Hlz帊g:6 Ђ,e5R0ӨuB̳ct\A HD9>j?E^^1fa[AaT\C%R> jU;Bhـ#!Sz3W& 5#J֏L:WH׵H;DFu#u$Ub+TTF>Kg{ŒH)m+)uB==|W?CF/_AIuzJ@6Fv$Y \|dDxhG rovdfG" ȺOlTBҐ;^Œ:)/EAZuolj}!wDD P;} M$V`}Qx"kQx(\IaFtc;Nr{܉)zbNOc';1v6uB@Kw-KwȤ ~[8zE;QFu9!uJ7sd' Qghԙ,INaF)lE;P'LtA&A& {#ȱD#+A6PA5IFwR8WvH7 ){2㼤*yH^'܏`260U,G"ǠLܭȤS *P:Pܗz5P[ GWnYN_Z(-zMVChU`ZuLDCAO?K;NǏ(`v=!]Z5 %z%ђv1Z͈F&]h]J5kϮT\iU/`_u|)uڈ:z&㿱 t⿁wU܌|bw@}9#8L:pRGq׈⛔kE $fHx|0jfͿ94}]'Gt3B{q_"ը&H2b|m:ӻՁH)r| @E%b2I"<1ciՑ%"QKt"9Xݗf)f ,LN@OdܖL쾚+*lhcɏjЉV|#l@8QnEg#b@з9N؈1xōuJa ,X ] -ꄁ)==vƀ:]1ݡ5Ud-/RO dMo kitJVGbm V^hV%!]͈PZ}"SuFU4Q;c|C|9^|ƖV9{*S=&Ęe>?4*rpKlXh|v%UuaH[džIf]1tzS O/>Iulۃ.z砙;=O>"E8[. @ upV;'5%:+ NݎTBTP%0/[ɱ\Xu. ,fcW`-g-G# 0yvg؄ 6r R"9SA'$M7gX 5]ob/6I̴ vrѩ(Y݆ ؎`Kj⛩ipqK0"e2e%oQȄ 6"BK)JtAMu)8Ǫn¿[ aU&GΕˀG1(O(`LS"]PrU[Vka.VV~1uƤ$Mo}NLAYZÙDHNf6)rx9-7#m>M3eD$pn)&rua]MEtt?RDޫv!E"LKwNobyfgk/sAɅ[Z#|Dx,Rҩh&-^o i+8j4jRda (mʍ8idLA2EntS3B&m]L&DyV#zd*ɀD^0%  m_ ":"TmD@Y7F:ٌ-AO5p8DZq&k5tUUd1dGXO6L &  y]'6{P,_5.繝4q/b4 Q{ȏ)Cnٚҡʧ̂v\6E\#iFr>1ô(=)xs}i{ser*DʕZUOi덀 e *Zu/7ľoCa Ak@?omPjkۦA]y%I",M2$M(ꔀC&y.X)} AznO bw\ެS: vo'&ӶL져2yWvșTz^NxX"[рKF~w_w^4cr'^* 3q-*ޮ2 oW oW oW oW oW oWyޮ*ޮޮ2 oWQvvvvvvņLtxUUU ޮޮޮޮޮޮޮޮޮޮޮޮޮޮvvvvmxjxjxJ3RvUUdޮޮޮޮޮBxxJUU2]5]5]5]eӇ4mxjxjxjxjxjxjxJH* oW oW oW oW oW oW oW$UUUUޮޮޮޮvo}Hҿ&}O~ў͹XvϻC$ޟJvגr?|PKSFjf{ PyQt4/QtDesigner/__init__.pyVMs0W4viIhN#AbVRl,O`3>[VVT LBJ*##%WC1z|k;OV |k@j".P{Q{8b$%OO y;-R 800bl|eAOAwBj3:EeeLKcZZR!\ $ Kw{7Y 433{`WTPlEsU߉Nf|`_?)^2gQU C]gϪT?QNgQwwH'Ѽ+@9Q$i{دUuKLZuxpᄯp4.ϲJns^b~+3E.g얯EˎjAԿ|(V7W,.!:O)@Uy, mF3j{@םל>כ`?xT & -m`{ PKSFPyQt4/QtDeclarative/__init__.pyWKs6W&R+tƖKEir$D"&V~}wA$LbVbl+]I XQ d\c?Bįa3IOiI4{RJ||zLJ4~:9]Ή{87sOߍB| 0)Ӣs犒+皾Tb)oĤ,8*co#Q,Y'u{)R5ȼ+0Bc Y4}ߒOӴ_ !u Λ=j` t+Dbpp!XBBgԆcZjuJϩD3Kd,O&pu玘RIZD)u-~TR {-Q5 b!)|(I~-]:N^KF> .|KJy-cKKT]M[kkI Yl,cߩ+ѹY,h%471]͡XfvNd-&񫺦Im=4t-N}H:`? M(Niإ%&T䢘Ma$FAC<YtЕ@N?|-'/* R8_t9<ZQc"_}O_dy#w⿫' t`$j*3WO*3 FzCAW`FN3S쥓 pPGL#3p+4 :Css7Ma;SMNGDK֢le''lޛf]dE2 C ߄|!ԜprFb-q5 OW(~6|GrQ&03R0Ţ:6Ƣ^:[2F,$5'yIHT8g{U?33!\T%{ H~f;8.+q}*pmSݲFJꢐ.է083!f(ul[, 똁hD0a  JZxݛg)ބ63޴a3DZ߶3Ȥ:j6Eva&IO_ݬ7)S2dݭ>}N|nȢ-R2+S*\+K1Ah9a͡* OB4F$k2D~ҕoS?MiE`Dܘs#qQD5gMR1~PKSF+EIPyQt4/QtXml/__init__.py=o0w V5q7hWK1.Џ%#oxvKyO86Fg2ָ/מ_mM!y'`I;cܝڊ&zEV%(BA=1Onۣ+B߈99vb (dkCvͲi2V\J]9t[{ YM8x%C^)J:iՄB5Gp{N9]/vnԧ/dx: PKSFw" PyQt4/QtSvg/__init__.pyUr0+lw<"!/NhI [[#ɤ}%#e{KW[ul[rl"Z7epʤBY&)mgUci 6:\_V!_4%jW,$:?.Q`sʈ9J~F*ˠbV K9&ʯyIX 5<ҒmDgqUF{|j@c˴\ w߉/ÏcC !5ڸmboL!~w)$?V\9z92 L k (rKb&Z]#~ [5ѣ} ì:bG3X%aPu=N{TIclݦDr/A}%I),?D{ϬjAq;#ON4CAuQhpD!Q@2aVH |8P cGqM|ly;:"B=rqX5zh[fxbqZPD )ž;[Z+ѥ[o/To0PK4ֆYRIemoПTy[GD=ʖYz"J̪?LshQJEwNS3 ylՖ s,KcN7_Ҽ &гn||%-@y39@jZze]RNso PKSFNXEPyQt4/QtScriptTools/__init__.pyeN0y ֖(U*-Jl-Zۅvb'Df3s <8Xc B2LQY2; c4o#OՔZ"Jr!-@Wy}1ɽʣBD6w|@IKx NQ$6+" ykxJ9'0 d&6j88 czO^H)N¯T'Nph9^qw=XKDv``U69VqiI#%,-4 n]d_1q \1L& nqFinwu #yOV,PKSFYPyQt4/QtSql/__init__.pyTKS0+|l!L$N=f{ KF +&i.>w]DUVjaQjҠrġV*tft9h~F7>80;nː1)oZ%`xrB2mMk7`0/t;nk ZD!a> aQ9:yݹ(N0Qh>OK>/AƙG\85|Wm4]BpI(GF9Hp;A@aIk>`2r7x}Cv]z5t$%^XaK Ktñk)ȵLO"3r @<lҳ1it{ZU”E!{SH8;N!dW+3+;5N_NZ)A;͍pͨ}Am uԷF¢-B*E֓lRx(a_~{!+gveUvJ;ͨTkD^v] G_lې .Rtsxv*JxxmXWj$ovU\ G3=< /;B•-8j, U Yh6 f.~h?zQ;%(PKSF~w r_PyQt4/QtGui/__init__.py}YsF{ =>L<6b]3Ȓi-ɿ~+:c[rbfά<븯v/lyjhj|wTjYnw,c 7@[~SΞzym{ȫ"kj{cVgy/1WYa`qr׶U9v痃jjP/]Sg(}r=[U}vك]wVE4{y-m5ؠZ5mZ. c^k^̠OX~PWiCYkX֛Cm п?:Qc՘綰*Ѡ@W/M .xރBш56&r~bIoDmUiN[%_Jv^f:V_,V+s>V0N|xzYx Zm/r*"62+7:5q>p`vuSզhOP8Ramf}nb!>*Iy\d$\IEObq]EuP*=3xKl0M^[ D!Hq5bHW_Ȓh,RZ*1{ulJkEkeG0\؁J}7d>J=?W59 hAxy]a z*0#}DJEM\`cY4e;d-{UmT[/ţ̥`&i6M |k=~d f]߯އuUf;LdV?g?49zU eRh9CIi&sx*}̴bI5h(:ˉ{Q/W^Wvġ׽mВ #uxikV4 5i_:UB;eK9Ae6'("ϸQ%8`_h^|gE0 77bIMXM]ŜGZ_oү55PmCGonGg>VO@7qnko>;P=M+dQ9V!UCuj/|rDS%6z`q!jXX%goJ0TVl1xo96(KܲKrPi9BBiwi='ƒ G.* 5{oR = ;c#H2]7 燭%?g&{cԛmVFYRE;k&M!!kjrV}b,tDVLUM!*rOgZY D(XM̗݇2+ FS;!9Fh$?>=fms7`UG}z:B>-Y>]2֛9L{gv5"αx{_gwzGϵ.ћr#q)xFuE%8Sr7-Hy8 #ѥ_fhM[|!5h$exBr*GH,L!4q*C?b#st{ǖOL4cK@pٶ/piLХL-YMy CGJLőOγ=ȩ: erR QY]qmh@? GszP,zjl8pFr D.# āH0"lTu"xxG7ñS +nG+%eչObMVڛm- &B s+al ]>ݩ&mв;MvQK f C¨-=F,ɵμn%ilpw{HCQ&gxj{ʖ=3q4҈xi^'hh.nt Lfҥ'>^mHhjc2zDDr񘭧9uq_w3t x4Eocqࣩmmlb  ..NJ6*.ZIoɌ=\HS벟])*se[9[t\^^q/Ўgqp-|X70wY&ђnZiȒ#6la-L$Ec*Nxw%go ϝ#s\^M#K@:靨 ѐ.vZF >o$M:;񬃒w܁[x1o r ?Ù]VΙ/ t9zaL݃~faAsm9#ٴGhۮeZ:u ūm,(P6އ2^6¸,&Q*q4L|ct`KE""bZKCi0kl1^6RpϠ0A.f}b>סOC >Rb uoOvwm"v*uE}2y{8"ohؘ{S\mExBj텉]nN>ѡZUu&wu:)7 s*aHw`JyZp&pKmiyqWsh=se׼,u}抝|SMȊg6_K,Lu}Pj{|?6XZ~.V7ȄYtAS 8b?!1m7E1I8&A'9vJ=̛Zv8'7~ٓzTxIv*^pؚbp\eb8hy$3.M9Fo8D t|AĨ%|OPgrbU}'@Sr=vm7Ug*#M6B9l͞]=v1[ oճo#7c4*c_҅D( Z?ekQWQGwIc!JcX\įQHí.EybE|âO.1w\d_r\l7HfQ:$W, .Iqˡ>+ %[8kv2v+lՃg`y_WOSOqk[#E ;tMTp .$k\WO*#TxVZcŐ[P=<z%ɛFOn\ MG>YWőC@OHEEjL#:lv3gXg2/ {T Aޱ1مȚG>?ֲK(q(RkVL,va~9f'#Y,,㩍!b^KD}O_RЌUE!-{ _UWɸKF%{xh--ĹMd+t(P!Z!g$tgZGL{9lĩ2Tr=_7zUERc 8,Ƙ  t >&oVjσJucEa'3i2[S=zO$ᮮ8!cOf#EΉX~mS(m5v[CvIU q>--2^ē/U 7B&:TP8־E6;=b SIԡ#8t1HDʭ}Ym<"֦\e~{~̂gMI, L݈ˉ~}T՟Pd_%fj0+2'1cG\a':k~Mf m4 |s#ZZxW2WQ"wjjБowu9LzV]\G&spB֣f#ua7Yg.s'i[eE]FYrX+b4Ś06_pZB';(cj@WIGucS2cfمaJ$fP_k7W9#r[>r֖98OANGoS2رfe[Bÿ+ALcc^0\`|bs<ImC <=Fx̺tjDzOl6ُaqMN/3¹ i@Lpmy6L骸xGc;X椾%VٚoH4BQO'e~WHb>R ]X5F#=j{ހwٯ?le\c3I4-7tLyeKGxdB/JGt[}q:mZӋV:[_v@H[-9dJk&2c^I.BH0p VDZR4}>mpgɚy'?E7EKAjU6`GHcu4B+ZK-y`˗APj0죲0d_}`/:ڌB簼knu0- X ,[~{8v7x8U/KW;D{kδiO,!m6Etg*1M\l( ߫ ڝd l2w 2lLzwj vx#62u8P$RPnVwʥC[y'Ɂ,+p݁0~jh荨!!W=~m\T W6𲆀 <ռX L9Lה `b4fK,+Ć(]mJPT3x{n 1w?Nf <ƝXBB`@7<$|m#P*~lߗ1pt:цWjIs3"փfG2#&lB.p7CWDu꿷}MRpb)nf=fqdIWܴ3)d`sԿh $]G5 H68]0(kFWY(0G=(#*CÂG$Wx<ɘ{c.;[|1؋7f` ?oJR7/`IunJg#pش <ܰ Pݚ L/ض{QKl3xu퀝Yp (((bg1߅ xȀ [ɀu`;>v|.v[A`3>f|0`3>oƌ&|0 L`> L`¿ u_Xm𙪨? gjW~:79IGJF>7 gUE-_6ĒrYA*_ZE!= 7D9$/و1 IbJSU7yـ{hlؐ+xTf#MAh] ay~Zqex= >Ugn5ʈ/V !!!!x"!B"o%Bi淾a,sbAKPS1AyCp<!8<l|\|A_F6_gՓWb}iCyڼ_ۡ*1ÃlYAR ʵ*%;vun3)iQB279ήG:pBKr8+۬y1kRpG܃6T[k[Xڴ7P;G(]qoF?k%9ﻔ>^|rQ-6 /*sU?lȻ}Hb}T>Aͧ-gX#Ee]] #nd!|?o7VA|s ;8ap’&~+쇭좲:;?$7^BP3eeTu~ ]j>r.NP%+{%15]N5x|@W-tY 7# i(ʆc9Vfjw @/ ,Z+lZ8|ϳQ-Oy+o&$eLx?n-&֏(.jç$ ,m/rPoK "Kft,XnӒr5Fm8"RQeFyA+4Ɨ:羽Wy}ggomx7Ϗ;BW{0t/+PD/+lz#?8*\g5z^Z(%+7xi/.>Wb]><"Zuu"_`@o;o4fG]-* )b3[1dȍ*vl_gplN/<~O8̀A>|DtFFomY(Coyzu-"h}W 0/ւcxyOO.19C$p+CL @EM]- Bj٘I̒jmIkB ~`iZ\kSvhɠh/*&4tmt|@* zaGG{Y?HZݴZ9=EqUdyȼM1ӣ"cmy ' *lGDl:ez^[SZrT;Ascv    w!c2V!cV2VlZ\UP54tx&6dKcz6>"e_Y<2g?<K|AD73!?jzzRVuHPnA8cU-`DzU&ǔg^ Bn U`XME QOngQ/cWȆ =bWVD z28BW>ο(k: NeE _k#zT  pĉVTzmI*'86x8L0FzM6*=; }}/QFj3%A+|.Xu!ob 6IpH({ q$kvXltpn_H5AGrj'>ܯAEhs~ˈ.ܼ&'E!+['|-Eb+ĥsO1Ffld~K}gm?gzƿ+m߮/!T#G:C0=oAxy]u66L! H"Gh[)sXwA%[lnޫjoJzPx d, M?{ysJFpu_/ݘWUNPs&k\ ѳ^Z Uӎ72*OljG"97 @WPP܈1>|M^WwZAeMP6Ae˔ |y_WmP:ANP:ANȆ|>i^[KA/RKT/a; '(p /pZǂz 1Ǡze*da=-#̿_NԮVpVS> '(x (W~~ET/UoҦ|-l`[>l`[M򠄃=`{>|{><*`>}0A `>oѠ!}0A `> `_=`{>|=`ϿQ{QE,`>X`>XoҢ1}0A `> `f[(FHGãQx1<mG Z$hE ZWho1WOrzjq%cO4xx۪n:Fg&n]C-SegE5.v0b%xE~XgO;hY^UoHeY͐XË*嚀FJGeK?杣mޘȂ&(+ss fߌH;4ŋ ⟔LIqiy1B=Wy=HiS9@ o=$.H >+-w ~'9 hn) ixY2 H<9T'<,L ƵQ7xjgD J3Q8#M)?_<zjϴMg.wSB%jWׯt<)ah%v]a^%v]ah%v&|0 L`>L`͘Ux06| l`>K6<;d64r/.`lgC{Q![B-o!x -%o3^A| /Y^s椪>3CgF1(Ȣi_=.^zc<|~,<ح Ѧ/ٯ>Xӣ:L?}O4KӴOw&}9-Yg, KV@y^9[`4 !buD_Z c l6^ѭfݞ7 $+ׅnм̹=M' d39wx\γdlxO˕f)Zek5{wAgfR*9pNstO[ҟvw|w5|킈#GjgjaTN"af\VOFjv[8Yzԧ:oݦ+q?k[>s#'34,X+~y]apeۚh2/fHF"2G7PМKo#V3]_=ɺ'W|W|W|W|  7B;X-y/f}0Yoz6p.Xʿݽmu^n>x#(ۏj(هi&k`؍Z2L7ekJ5R ~ zQ؋SdW1y.!P6Fk}fr\ wS fV1E7yNOQޛ|bboLsOtʚ}x?,n]S:zmG38!e|[23w&RFA>Q,x|%I0j֣f1`X=jN0Ltywg*d4bǫn-g=N7/c/@Y bE ?Tq_BէٮF.]OTLPBi=i¾!XE>P[Ri G)iY:B;Wu@,G3 THʎz)?ai#ntu1h]Fạؔބvd'AClH^Mg@r5wEc||;x\'Uihsn[WսX5E2dk\`6@<6KS ,ZJ>E;l6{PydAґvl0R:FY:bјt21.-i Ĥh=Z2k WUmNCDm>;8m6§C~ͼ鏋L"KK3'`riS;<8\+S_CH~"gPqQh>-Bص3^hP8,Cէ|6+O5ǯZK]TGG9DsD>v~e m)~;fVu> GzR `sLIC^nkkWkD *L!$VeD1tS& 8],>A-?~v`u~.nξnDk%͊n Wo;G9l g݁҇+Z2i]^wdyAYd[Cޟ.[:hs=$bZD_FסF0#&Q B_UR~!GUWC}[';wON"&7kIYKZ߬eZ_e/OʅD~\HfnrwG{YwhOLGI*(Q]rU3)7I鱫)0xP稼*Iʛzasm8y] d6f?Lb6j0:'a<0iؾUsp^kYYjb<#\f2 !E}B2;'O]$iGK^e\8l8ҶXRvgsߗk ^3^U#~~|/v2jMF _Ht2MGs30#v/ؿm:eAHZ7m .$;X\ɶ.ݘ8o,lZ{7a*maGO J^0X4/8EO+bOuBVdI[c7=%:  Q Q Q{`! `! 5LxGO5;P Kc VYM`6"{uEKvdh}Ks׈uգV=HKq*v MN@cJkKQ ]<]#ΰf$i6=~S9RD8nB 㿘s]3VxM_,:FPTF_YFfZbvo/h(>'%h:O_S)u;ts*u[OoMUñ];w"D.g w1$&w P eWΉJĎ>;ZfF\G!ae7qc9A`@T n3o$s`Z„=-3Q,&2 pT@ ^fx 8҈h5zPz!Pډ5dg$]e-c:].3]?`zOKvE $LYlHP_N/rUn*w/oAUdw EDKȸئxx{lWuGou֠n}}D6Tur>Ձŕx{$b < e;ΜƗ{SXuzID8dum9{Zms>i09ؽꈀL7ŲOx|Z.n,/zV[1|H/Ikj$g#qO-&wAŀwoS O8ܩ] v2DB_ޛI/kAI= 3SF@Y}/`bF#ctQ)}0)g|UWZ~A kTNF0ӥk(-w['K헍Xa?rV;JcQR ,;x3V1򻌜1{A| e,a•,~Ҩlש[(Bt*ѿo*Ko{*enfa0"9,""-bsHi1QXE=J7_ڊ?Ap؏F" cY{c)?e?A??-pp=C!ARu'rht$oqHm+hҺ2>>Ϊa_t<&`>/yV2au%=Վ'u}?ȡqm}^۳OOK YVN~Phե̥HJGj1 =Zo'P6Y\rEQjs&spB7[4W1WUg ezj,MB\^T% 0M^E) B iW=6_q]̓ƛPWR%ސ[{meebKk)ӣ&]v&п Pv8:+-n z8zs}jmslYYPηg'lۇ}8lۇ}`ap>&s;s^{};NXހ~!&|0 .&1ymr> K(`JV'_.tW;͋9s5<3,x((6g%Y!QTtBA؁g"ϲ;e")zw #ΒuBdM嶚Ve.bɥΆjR$̭5\X6c{6iY`OL%3Eu9wvXDWBX ^D )K11#>2Gpg j`35 F @Hq*qGmG)ڱĩ ]냙JhZXj {|M$yN?]$C%D0ݲ#R=S 4?bq`|n@̍+"Xq;fB斮s2^#;W#bIG\/I.܊ٟr鈏2dF-O[u7P#1ItW"d0uݴ& !WaHq=ێS](Jq(RgGQPL`8`pF? F>s8n]>ʀ3\$ <131va\CԬ1G RSq:4VDگ3PwŐXW[iѼC/Qg\Kb'|*Jp)i5IAIAR$ 5" ]夤;"wQҝ'݉ˣtpoO-$tp8n5 J4펩гn/Yw' /_;cCudIDIص$kd8pi>@"U].ޑ+vn=mF,<:\j2wbA{M@#p:eAYt #|ۓ}77n菪n!$m;(< c Cpf9`p |϶KtJbqg^4Rߐ0+4Pv$ڞ%s^mHhjc2zDDr񘭧9uq_w3t x' neʼnsCx-(Op<}`l}Ѽ(i4D)i!h*>u[m0"~6B>ㅋ V a0<_$Hd˶ZIoɌ=\HS벟n2*se[9[tx9,IzQ/wo><\foor-_ˎ,);bfܾDR4q ]wwN|^Rz˙\^!dҫ^M#NԅhHCl#QbCG<$w&88b#޽oL[jB¼pfUD<3c6C qȦ&>Bv].3(bᷨS(lsM:/_Be}(¸,&Q*q4L|ct`KE""bZKCi0k'^*''J6u 2u1-^NmPڧ1Oi>6)AA{Ťln_Tɬ?.yjz'^b z{彩F.Z"ypavsN>ةx&Fb|adE3/Vv&VO:h澉_v=,[AidIb,:{1`\X趛$Nyq J;kJK] !zTE?\E] TI%=(a`!mF![D%z+pYxq'qJzi./|UsVju>ml1J8J:DZny}ԡOu`R+iwpNїH|]=љ+=iƭYChlGMx$U4SUæSx 7s]=[P+9)cX3D/M4zBuʵLh:ɺ-,*V-ʵ,Rc1ձf˝Y>0yQs .4pDTֲK(q(dORkVL,va~9f'#Y,,㩍!b^Kc/Q)hF'B G-̰p RF=j4H't /KK4/PZD}WyI4IrP $ ґ1~Y:_=B}ǻ$v'Qpcmű8gҡdC e/ q=#!Ưo;K:MM=O<<-q~#Nŗ{Cѣ* 4'?Si1dpO]F/^}bn=U&/Kxzh<"֦\e~{ĵgH{൲G$&nDP?b>XP (D2|e1#d0LO,Jy&i36Mq9AǛɻ2p)r9m9@Gk-3I zZ3vq== W[N\\ԅd9ϝ`Al #ueqZcud k|QTT!ӓak3X54_W8t x t@O t@/L7扁ӚI&]iN%.j3c-q.䣤t2~IE^(vrKxiOb7.98# t͝P$v$O'#T3) ɤg▿oYHL"vs >|%Af("a@/4w?-cE~j~+q&@pꓸ2;8 t5$|T'I8~0L 9iv]>Dbvses?.#gmɜ#t)-r; \I2EN`&1Y[1E0*h|w[:5y5&ԓچzx8{uҋel6ُaqMN/3z9>q5{SKgt/H<,s%V)i:;8Q$Nlm|'`2Fz(l'!S&_ӽfh4J[ܽk}^vW6`rPūg l~<+ W!_ְz~(?ֆeǚxC@ݗtO!gzՏ x[(yW `eg"Rށ8S.M1=e9'8QDqBαù@KkIi;1s ᦙ{0ӷX*j?Wø|5Ʈ80k`? Cj;pj?S-UqIaL~'i}'|86p±96 8DZǺs:A 50cf)x (-x`G6I .ʵ  N_UbḷvTcsK߰~u^co//W PsPZk.VdPc>JfM oUVj =1h:Chfjw䰝i 6V?ƚ``? N X#"C50c'X5˪߱セx5˫qB7GbF<j3W--!ȒZ_qwDmC-0럇Yl%,~ryu lo +,~t n[L}#0í  &'o"p/6ve |w:~,=ю_ $,?d צȁKrw:{ʓ,~ @'?fwC C)0 . 04^y߱L 2ziHze|1_̛ae']& ^4~m Kê 毷jY5X5uWy߿~=_2=A̾2N=4ņVaᅅ'[x.<|{բlsYcp#R *+z8xtWښFpX鱩aVӣM8F=,NW_ ^5Vi,]0r'q݄ ?P{9ѽiGY( DQmb9|erb/Uk`4=OKto^} nҽB|zOԫ~]v+iB*hWge>۵YD3 `Uї F[4 LDt*[-Rq`X6v6=[^oW4޿]ioLAp߹4f e\ xiKfʗp( mˎj_L;~iw {HB'nVnK=vI\&UgOk1PNxnCYՊ^kfm:~n0_d(g&s.[C.vT ; z|i`(yOт-lLn<Z'j,edAz]I5f-&`lȮ[Zl #ݬ|Yͭz@i؃JR͚(? @42i4!epgd 뀩yW}Q, )FܢA,'آ|zWEHa2(l8,f=b8Ǧ2*sH(լpXW[b'?lO.,=8 *bCހTBr5ǼMvG[:9cjK32Xqizq^}oNR䥧 )whYKŌ^eRƚ C)7vu*f'ʴM䕱M?њ՘qVͷAsJ;p;mٚ_#6Y-JP#l3ب-LO;U ĆbX>TKvajQ{ն\>j|:] p$o3͓Ұ mG-pGB&$8Q[̨Uq-zd+pǪy0oZئcFX9@&/'CܶFFq<L'u? Z-*ba(]z yov6>KvFك# C&t6;mQ֍<Вez5-^VS_4 W ,v I% MQpH)FlI[d$m Q ȯ1mAqY}z],пG?TȺ_ͦ ,62{fDSD#~}#'S)"I}_5Jq3hX[k$RS@-1Ó@P 80%0|79̚ês΢k&p0_wrK\Ҽ9tⷐ{-pp;.w=|8cMߟׯy[)ՎGNhn $w"?/1F:Jo3_KV281xVs>e5f0?]$8EE 'LT0CdLo& ۑ[c1C]vH)xz:cݫ= t@!1y op U7-]UU SO%+wt}~RB;9]{|eADtd4e%yjJyߋjޘҞsi #qfHw^bO_r@_Wx^{uPkOE@VE*5D׀jH!҇`6fp譹6k(z, wVWX&boZ6 U5 >dP^¼fS㊅%7 x:i9U<|b ]QL*:Ut})L U*TU QtOߛ㣈Qkr|>d(v4ۣ+sFQ Ҭ e%iW:tE ѯ7cY5lpl LsډqEB ԝ-|6KŨC! >ɡsz[oY>%ń>H$fGЊrbr[`t9G&_{7z>cűi"v-sRUl|_o_njSZS ;ͦ׀GgmQ11SsT;ܤɊ(6IWSc5]5<m=2Vq* _r} 0t=y\b(G&[`LJ)D~U?.ʰ4Pw~ 7}$ԣ&I&zգVZ {yNSWr{`UU+Xq{zbqPj SVq22RxXE=M"Jo_3 %Tҡ0+L.AͽlΐaӘ-Lv`A,V%T6ɳ!3cGrumT &^-}}0Q{E)|^9Ëg>U|Cy`e ! 0*` \^% %U@.2oLw!r'W7H%L3yzgӠ"^W&c"l`RE eٲ5ʑ\]䋰uFrB%Q V .#s Ӂ\Y*nRrʌƸda=Bo؊H;i$q8!0y<}1pNlZlk0mMtіq`EdOw<$7Axf4<\D y~/PXեKU.U].#l0_'x@Ʃ삌I 3n[C/LpP{&ɜ+ gCy<) [|VFn>A=ހEaI-1+5E ".K{䕚 ?f:Ǽ$3w]sr̓D*ش=61#FQ8 [7E.{=e{U=&sO5D? _o{":#ۥؒB o*\ǥk;d,%%>(@.G|)Z[ئJ|_1# ;$: 2#nWiە# . Aɦ,wGd ^ ahg.:gM|c˧D0 T6pPS\#IE`n5tv7klɱڦ0dw_Iv@Dȇ}g/0dFl9Ӭe=]r8y}͘@i:C%y PKSFtPyQt4/QtMultimedia/__init__.py}Ks0,` NgإNe( \M@bp_=A IꜫG*J/ϫ湇Pa)."xVIUC#`f>E {X>wP ɪ*H?I/3kY wz_9#|pzO/-,a^G b"fy }QF|rݸ3zZNC ‚mmP]/u4LD80"B$moEaV Fc}ɒ`Rg6Lѵ `-;;Bʛb*'v-ģ! 2c )ۉ ^PS\MB:՟i#V|K `:-b5:cX lJUq {jPмsV1lKmD%Η<4;h|Oa 5ZI<\YE(Odb1)8pDЁK9}M\ ^k15nH 8H jd* O(kZȞE]X20Sv Yճl!fߡSPu6llk3>#/g)NLa`aHZs/oʑVoG.4_?Ck}S* ޫ ῑlV.TPKSF*QPyQt4/QtHelp/__init__.pyUKs6W$?ڦ3=ȒZȮ"GvOjKŦՇd0(G"M"!0 B NiNb) 5B=bJ(̐\s]ica!&oZ`c՜6PK3Su&o`SQEo?">K)BZj>h)uu/ 0tty.;^6,cS*4(Hl\p'}`FPvڗ f7!J{' (:7$3H\ I"`/&n<hz@4_ MfŵM;`Ȭlk8jelX,=3il-pV<էk BCb1uQy M$k&95잗<^GųgWs27k25.g:}?[-|>ط+ܛ ,䟝ht̕xf\:No3~R:wA&& )́/H#ޑN} vϙQ>NWyoǏ\̖lʍ}gwy(+1K>V%1Kpxޘ9 PKSFGT PyQt4/QtDBus/__init__.pyVMs0WlcL NfGJa/Ɩ< w.A=i߮VK6Jfj)u`xK\qR\mH VS\\Oe?HE# ݧL>j^x:~\*&A3 bղjq7N&AYMV/|aͶdY[m9T4biZkEE-'}_4C2{e:{\__a/LT#AA81 W;k(7Nd؎^E'E8PKSFe=CPyQt4/Qt/__init__.pyYsH(_ qX[=/ H@EKk- ${ΌYZr=4uS&ww{f[޶LNGpw wGW?ϯ`~rwu}}|zy~:Pw}lv~uzO>_|d]{鬨}{I-'H:)]2Y$_fn!}I k(E-`vUN^dk $~C+]Ae:aeKoius^[]WmHg^v cʀ-]ݷӭϋ&_BC6k7s(m}Ty{sV.dRI.us/q&qvldVidyؤߏs?狮e9/5_r.BJעi Sƭ9v K Nj9͗&Oě2]=@HA'zvKؕ&^ԉ/'3V$pқP5?de\OxmA7"/6vo`J,_:Y%v\&u,tGXYX8Tլ x,MCQ'tLPHF1OKipʰ4hQo!XN(nleSDo|Η';Ec{  mJ֣Te<-a書bA:mɅE:s{ex̉:/.7 ('Poj> dij)S/ɂ٢e Z3tv$C/ \:a -ȫj?lV4u`Ɋ!]XA`d;T"ʠ昘iH˙$Y%:bZ:8$*) #xHv>`1p]Fo7OC'bǠ¯qk KiPI2G.gWhe;3 弶wB&Z.^5;o5iii>;83Nn֘Y]42,a&W"atT fA<$9epZ'8}V#UT 9x ]nid ?ZEU*ZS(i V;_lS9=42L%K{9i+(0xXz~]J14%\cE$¥ǻqhjh]-0V٦9L(qi^\%1[MjO-Y/ˮ kU㇒m7YSo5RMkqU![>;y|fgN9}%blwR'SLw~.S\wSJ!doq&ߔ&΃2vB~DЧhv_feG}5C=vJCB:%1 ~_7K'No ͡n40>( vC"ew(dƢ;00@IY'D϶7y췢'េj" OT$@fZTR q]8vָ%yP DHR?5J2)ogISdH=b'p|# "kg8K24.H|씼T'R9aV+AG}M}% 6';p.qFoa]pHf6}0YR׎50,>nn7HSi%W I,0E/it{aE X܍Lgl֞A-$g՟r,Z"(k1Tko҅9zol^*4u|Vh^5E4>i|A5}ҏ*qP52z=]> !%ޘ!@ސG ɽ1wwF?b٣<1hj| rR۠^'޶(ě&h*geڙK 7 ox9ĸ?鿖=i?g;N$aJiPjm6'*HZ<(x=0 W$ϱQP%#-܋u_"q ia"^fpC7PLHd :SA{hg}N7)EEp+ބdM%`x=M'edRL IAIW39&vPN9'mo 'G:3yO]0!Rs@?FlcaxXyB'Q T?\SSp8Ch}deմ:ѯnD#)H]tb JF6%!jCTIŸT"&r'!A0Y|߀x?OLjD9_%ؾ[]//bf^9$D*lVD@bRjPHshd I"+'$F#2[ C* *>NX/xΙqK8з ' /mLP\ ݣ vܘR4LH@ӳdcrjl]Z# (Z;vrL.,93H߹PB> k1zW, {Sm%z?,q-yMSLcufEi]cyn.inj~'Կ|WY,>E6q;yEO(ov}Q\K370e^msD(,bD.=/$CMjr%(<:ϪŀA3' _J#vrKM̶&y|#P6mxmLpQ˱ѽ7:NA'@%Ϫkwn(̮&#U?.EWՋ?L ,r}r\ ~T,e}gN]ܞGR{bCj˳/5|vs|4V`yA 5EIg\יƬӔ asedӡ NDSSX3 E!ΜSfH$p^Aa%.RM&&us_dw ojѐN]ǑSv{ws z{j)4kAB +dH_M}Bejm)4Őt0q{?\ĬC.`xC}x"ء:S tmƌ< (?2rJJ4 Yank[BИ p @j42ZB*'w Yh%MÑ"xLLc[f!x$+&<=Ͷ~{ڡD#:Zr"&<йG}bB} ?K 'ЂxsyI\(I3-U  u8~o^`< Nq:}ZJaɓ #~0 ;Z:t/T3jqOC~k 2+` :vQz鰅"'."fr4ڀ.J $a`%"x^ {(UtY>@.5f-y93wYQ_ 6S߱X=;WRcDR-Nf[Nw6.y}[@ D;n!] 59ɼd\җ:D֗K7ObP*tɰs}"T"%;Q<6 8]#';(D'O1r|R}E$Ωwhlߥ;U&#Bp<̇qc{ ãtQ_D=Bq,hBqX+G0hU^mWð]dv۫آVN^MZ`B\ڤL dAYA{/8Tyf=pe4@^7h x+*emMg A6p٨Xړ+svoMY-Hn%5-a abN(sbÑwpn=mFG2? h0ӢeT2"l.a%;E{@Hq} G0:uυCmj֡j3wqu(RS$_"n\j[\'wq`)4׵R9XjG1fZ8ژĦvpT)m!.Uj!9oOȚndxa/-~aPr2]ڛ8poFV+\&.Ԭv7K̓n&y_Q]%t/}IA>uHtFPol w{vpfyԁr#-[]%6/Wu2\υ]XۮKci`vK~SX)WQ~q`h%Zo GCu7hB{oaA܂=$ǸEcaO/ :koQ6򢑃ܝ䑶L\i5F8o0,ŒZ'tI#Mm;AeBku?Gk;'koL[(/:SW H"mh`@ڙOku?xsy^N MrkFrr"!a,Р$mVxOʃ1W ͅF#Oڃ@'2 ̷3Gb¤[Kle$T*(=sY#P=l-j852VHKjVL(4._ꄎz~6o9!K]F5\@f ̬az4$q6:6*j-F zl|㉃?\X_NHO( ݓ],̊U#K.bYKƱx$Sc9;>`c&Ý,4 (JRHu'ٝwV}5Z$08! 5ۘ;OT)w@p졕M>KP`aoS_f0] fTע|P sݗWhfoXDKO`fuE`ik4i rhKc]8c9GL ()A=N3IrzZ3tq-9;W(0j;v3sQW6r8u׏-gAl]mR%ָ\ $V*礲bxb)c/J<-+БBg`yԯ`|jpjKPu2]w:vg:qWDbӲ63'5=v>Ґ~4h#J`fKǡbgu̻6ƹc5wBz^2v{l$񸅳g?{Lgl࢘ FsHz~/BT]g(3oB]ZǨr}_Ʃ{pBvN,F`B=tn}Tkpc=‘ >M°M'#3W׹ Fֲkg Ӎx3f}0=^u3hEfZ˝ľgbxXpW3 xdj1Cͯ?e/xLHdjȹ:*jpMmyv8`6`0 N!hMƶ61?r>wƓ~Vmן:`jsc3~ox{_m31F=UHHWe0 |=#*0i.xHO2 zN/ŢeL;/lefE[H+*hdۺ`%'_Եm1Iĝ1V |Jx04 Lz.hnՇn }>mpS$џO7Hp)hOw)h;gIu[+l`6 lj9T6 )q)T[RFJ!GeQUlGK3Eic}I,tC۲M VqX3D1c镉|p/T/e}]s7/m?ċۻt{^&yJuب;yKzM=қ\yT<"$ R/6HÕG.@d#Nlbk[oŋs#^w&3V4tE4ls4u7!ɒ,"A5tL}Nؗ)ї}}0% aDMD'(1^I.{JtRj R/5^6LPsM#" Lށ7phtoR^qęݲ:BM2Ί܂2pv/3 xUkӋٓ&IQ`zBqmHh{ ZiӞ^c9C""{tu0:@Ƚi,0vwnG6U筿=dޚ]jU%NbwPv z{#j{Pm?JzAwή=ZeWE&ˤ0>v ͤzҼr4jb]Lg:-Ό/ے--60|Z)O(MB+/.aJ"8ձhx*mpE sTKjOW84ؤ}CɞAN Ѹ?v>UNCimO&`49lFHQ%#^(*m߯88$EL*L/wT>I/;??),mVQ zp#i[Gm39S!0fu=@feey/|Qb?Z{]%CF{oIdƊ|RV=7,ORB5Dr\9v!{Ad2p|)o"/Le52`Ĩw%xņ>ex7㐠w:3Ӣ<&*WP[P̂iBP@[Ok՛8Nkth[ Y 5*^5O9}+DF==@:~Kn=/ܻpfPndn9ʎ XIRrl+z򝍩?3T:@Y$wx|BT^x߻W'tu%Ţf9}U1x];WŌ9^7x)ޤvxd/xX5i$]򔔕AH@釯At[!de߁; U wӋ#6,n&,20}ޤ0WĹ.LʿvRgS;w].g^?rguw&VIu|Me|OFi˴oS(inp78 pue5jp5p5jf#΃=>Az|?=>Ax$5>Aj|PAj|P5>A*|P T*|P è]ZPNt>A:>?NBmȄȥ:=)zU2CZ=&_7DpC7n^ݡb&<];Țe% ,) ֭)9NK ~_# }yPOS+OKwt ^}! a5+|> /} h08˴Y BvY0yN,`:xT/B`& {, #~Tl_>?~CmmQ=8ӊpm_ήɽQt- }p_)L&Ȃye~ %Xrz[Nn:hƥxI34^ֱ^6X2AES. t~W?MJ $0]*}ǻIJ` 0C,O;AD)?'A\i`^/ܠ,Ө()q^'9=uGQ#֦fJI,Awx`5+y f;WWG]2Em '| kwiR:}I2pEL]%sQ UEtDʔȂ8888?q?FU#kό ̺JXܭk\/mSXi4ogA*X" HD%,`KCD%,A]bWDe$ e\,(r *bgX MJZÌOMRQM8c.F'|UbsM-XTyˉEQҞHdJQl\&:ƑBݼN㼎W_:\%",ކ6+8P힒&dw.tIl/ $yztJUq) LLT2)W<hB`ɔ[_g˓|%2$h/pFm%T ;D3%n!107V @4@ȶK>N҅7N,Y~lp2誰muvmKj\$Lq^͒2}΀\*!EK$,+0 PnY 8G^h)>KrbG*n79kQ3QAmM~ փM P6 OQ-inqƋ$_?kZQ>h..}#V0SDqvh|lQaQʁDtnrؼ#w/CZŞ3h 3+ ="̗L%ku&>|4WFP̙ʃr)`` j#^4 92}L `Fy<ʐ}l~Q)7}be,CV`B8eӚP(J`eWX%+=,57tjWjD׫5e#L_ZH<9#oܞm&[ "_C{bb^UdZ 3֣xCH}ʚ;[0ae!AcO x\/S&8`_ҤƠ24n=ƤtG['5qT!]sNrsؤYGOQ:MlY},Iiڥȵ\dx;,׃z; xY'de}Dfm:A U|Pj":CǤ]oa| (0svC]Kձ;dKIn%?¹lF1ʝ9/& "HRO&b í:$cHSaǥ̣\7klz9pyqVT*d駭*t=4фbivipUԧB>XDhrj,UC2ߗԄ>cf;flJMt̑q#rs.197R,JtRi-$ Z1nZi yl~g 0KxV#M}L˞s.U`.,-:S_k3m+t1v*Ծ=E֭s0~I5 s㪰sN8\t Ymh873EifGŜ \C{,vu+Kof7S+gWl8ime=ǎb]ڄ-Y>3i&Bc<0S'*OAOڼ,.w_IPYwd 9˵(\h5C>s}I'rXJ(Lu/6^3"[ԧ:cXǤ؀g*. x A. ttD&uSߑ{:7^Ǖz1bgpA!"/D䅈"BD^ yBD^ y?JDɢX将" IƬU`h(\’氰mn[Ƅ.8tJJ tav}ۼ}Gܹ4A%Ͱ[s$7fqNqSr2\ζ%;6 y/|n22lzev0Β?'[Nì)O:]?y! BF~ 8}JtnbH3̖8aQ. qv6{%i[kػd Vi-$QdTr|3"d9o?n=C=Jأ *9ERx:40QV`R<~8'7CoEb!7/h][T; +eO3Eu>%SK|YodV5fӽ#5r6}JGP5_;^ޘ7ENwrskl.&ȁI%0_Y|3p$2EЄjVI1 ǻ.-H>`6AaM6A1aC@%oZ t B' tB;efMy r)ȥ \ r%uNV~8AN8A|Kb =cA<7&vWlf r4%>#Q2Izvzh QY|~߻o a0e2pf _)y7>owO>pg̶GIT?A?܃!A:]>A|.t|.C(>}>A|?}>A1yA }PB~/(A }PD<(A }PBCPBT |>}>A|>󼌂F4>hA}?>hA!5z>(A }PBA }P8>lzxh|m 6G* D B$ D H"A)H"!_c;_3SȀDS|HۢsH^$+u۾1Bat@,m(:4)(vȇoJ.Diq?;BAl7ɲ~`.ܬJqev2<Ļiȳ˾'Nxcia҄f9ImW؜YΒtVae%@7*'@e wT>5<=MӊW$6涹O8_h,y"yhÝ ԘmrRǐ8H8W2kjw/,(gA9 YPξ\%AdH!A I%jpW~̒8yUեup؀AKi6 0%<2`'o@b̢ق!~%cd@[SvXukkN]<\$.`{^ B)_?㶝߭?IL7\MRdsX꫄8:W4_[ jk9aR`s>Yo+:=]5E# +V_US~:ԼW=u瘔zl3łJMGJ'yՔp?mL.=8$0Vg2]9(Ј{q&Q"K)G:+6n^Y $ZɛxMX%(0n iʏ }Pw9 wRR[Wu.$ uk'US9=a<-C¡N\\7I錨1L3o63 ydm\yNgGcX@%eR/&wz/񐉌 v='Ⱦ'['.xu^#2>Ɂ3$2Vrlr8 r8 r8 Q mO en? Mjvbm|$s㇧e<3 N4JHZ }ĕ)۵[m,47\>']NY( ⌤up l.|+/?+]NdbϮ?ϩofڟo hȘ>"+2"+2"+2"+CpEWdpE0ȴ:l% YV<[`UT5(Hu]_󛧱òx- cILZn^5YSyPV>u ,ic^< ra M0nq`f/7 M0n~㦮Q%s70z !J$8pߥS1ku9mI8c) {lj"tbnFW?rQn:?Y k-*Ӗ6~wK{-Ԁwte+[?XUDue ]$J6ܩ⶿) Y(XQQ0R8c( I$Ci'W_WU^Ytz~Wtto[@dΜL~-S2 e/x?>}h_L` a9IHJYX;ܘS6X0 `x;`x;?~#fu(Oq!qCBPUI(K4kQ+suM}w?vAT__C*f v3Lh)jgf=awVs?! 9{Z*͜ΰՊf&ln"Q9 Ͱel`[2lcÿޘ c2 Kd`CK 10Oa-Uth@GmI]?ƬYׂȆxEC~!ND? }byPs 9Cs-QUA|%^i 5^FcǠ=nI1(_ҞռCz[Be4i?hc%iƢƸ+>SMɳ%6wL?Kʧw9q`f:iK ocSpeBRrpSSԱ6kxSڨ:.iQR8 벌9vH4iFIYoc9 }$YVA9jKݶsC 3 tS&al-uMƒd-(tF@dUfHj{7`̸؁8I#K[oIyg k$ QԼZӅT׋$$/K% Y%h\2 8mPcKc*Έꈟ6*0d4+~*\#?M/%tC|a²B6قaBB{YbQ́ ~SVX5$\7x 3XW" ASO͘J`Ѱ. 1 ZYurV+64CI: U1{-) 11S֗KKs-^ZGeC̕.=f\98֋By_C u8k aTo L55Ɉ#p6%B]?x}WO`1 @X2s8(yImZEYҧdMa@&y\9ZH.r,xgL\Y!4'qj 9Y4)IfꕚC',Ξsj f;cD,o F[A9~pbO*iPrR"P_IdNuZlO>pc"b.qj OHX_a :MM"0ĮNailSӑv'b%TC МbX()ůS0R'c)WX:+Ұn(\$L iŴ^$P x|OsBq44$caSNKE$Qe S(g&sAr*2)s_hPGjP$4ӑgbBgB|..?݃i&" (ꈶw:8Hƫ!IjPŸ<(,c+åʏ? lשYԦJYZ^z5 YTqq*L,%O/<Μ@jYr_RHؐY:ԔQ,+W k5 o M2e=|EK VoIZH0 %~H\wܓX- JT̜cdDFU.<Q +Ocz^&p^1;6H+GnTd'и ~{JoSM1WuI+l`+jRRK) ?߃XD_5͟`)Db~}*LS[V)|,y|FBh76Lyqp9(H*g EFx-cPRr͒$?m,g3>50f4$>ӧS*eDMx-W1# BŴ/bom~>QVEñ܋HXQ8 7J `N`'5;\w$&$s lNqTTdX|RF^ôGUHwH8U^43\%El mU9\S6_^,.1+i/q>M'e\:-%,U\-bv 2Ii?|ya8C?F~f|_(PB,D59hd~sI1pssr+ Zn4RP\GYV9CT,z"W߀ J.ZԼCZeR2#dR9P kzID>.J+c$:[Ʋ}OyEH(6:v '+bTU%P}<0+S 1u4"KXAbW ) >jU\ųY[Xn;"5*iQOSD!ٔj4^9`Z#Z܈+x%U"wfW,UO픒")IΫ|(GcA z}L}}I*Pg0ă.PY@HD僯^s0 A^5݈Lc!Z)3I_oc z{~>6NMh|c˘Sr?Zw5MmbTBQv@ ~IMR`= R4DoW\Av~#(nz%K9+&މ}=Ь'hi[3$n4x,MVj@*6F目wF8{N2v'Ђb#JB 9!ir>891[Wӹ5^9%y,eGbOg[ C@D ac\YagOi]?X^%O|$ XPv>fN/6ٚMC=s泂 2`7Ɔ[CYƅ _S"TXƔ[fsP17pqY&ܮ$Hhlf"y(N=~A4bRm1_#Bvw骱vGȤɉNH'o*YbFV7[lef+7[ I#7HdžECX08,<1-on/r[㿵wzJd9HbEH(rFqV{C-]$nlGiw3w_X=am뛚Bdd0W>hPG7/h8 (Hza3ğva-gV<GMv(2䀪u p5Su[CS⍐_LY4x#<1쓠'pA5 &Cԉ[޳ܡlAi"݉F7dQl;/1FA^?"S><}yю'd@ڠ+i٠yQa o(i bL@0eVJH,'MVqST_4&TT6 ;2_jT:އ?Bx0 PA( 4r$J)1WQ$=`F4M}vSZ^=Ʒ>qz4&+x9td5FգCpYTO( {i=+KB;Ș~rᯗ:xߜwD$ g<~X^tKɓvĶ'f)m3r="V(BѲHU;z|(`=u8eor>]" O3M ^},8}zPO ['$ӯg|]5!O2%n(06 /Ux)*AI~OA>p&dUR 'Lo?}.wDpW9,0$SxAxsDX5z(>{j- f@Y@r6l-XO(?|)4}9)4vS`v`B"*邯w׻].z| _낯w׻?Hu+ÿ#:NNN^'w~'w#?-7זoyY2΋j%/m* (sSo@E-ȗ>I;yR+Gܜ;2 WbzDMڍ94waLh-=5@䯍A<%.a.)#[ )\w~B)K ,Ï{m(8H@fF xo.yD北<)< 0tv΋€lKOxެQjjr)7$Ul!٦.7|>必/sda Z1` I"K.hS]FJrL"YbsS(ԡ aͪ6bh1I sHB$Am'W99mR^<8#]ꐋ6vQѨhĆ,9b̄ ʡVA6E\Pjc\᜞TEuNiOǓe!Zrc6ab;\Z06bګ Y,x |Ij(]%nEFX[9ݲ(D]) c^22 hR ZKC^HkԲ4*% J0y q )n+@k?H=Lˤ4iڒWBgUk\+4BfTE~Pƍe<Œ) y7 DĢ@t,9;F}H)S?XŅBC"U[5ݎrȁCw#TGe"elhïGn.c1EXJRuے1G0wv[f现. G[==:Әex/#Yn DʨĵbqC0W=ݿ$X#fE8f֓|yHg{$|h˨'uW=bCDGccQ$n4ŦeBdܟVΜ 3E{N$;^N斒.邯q:twa"{Bv(HUR) aXv?:%ŬJy~C^0sM.ֲajmD6/mZ_`sB++'dgt~&Igt~&Igt~&3aEoPZ40m M9Z {=%6,Gv6^)1I^DL^)Cr[kBOQ*kzM"T8SXmCBdhЦ*A[{  [ЗEoQjmEk&=2!y)HmԎk?9+~_~w f61hBRZ%uzKpc>t?Xu :V,_/vыr䤵- m5:Ev^ѽ?vȮU P-"⺀+ bAJFX ^a,~[d}JW|‚(9Gҵ0٦|ebH\T՜Ҳm+LjL>92$K=cͬY~CpaSM.)tbCWhL ]N8vd$ɐzXNx(rV[IfV$g^D[4 9%J!o,}K#vvגKQjdyd`[{%_amX4WF 9~/zH묝1Pp$#(\Fs̱ ;]aS`.5ߥj QW $FftP,6pRa˴2aR=/@AՍGHnZåq(OD[u+h  ݀GF%$KNJa"=+1p4 kQDsƛ@J^pw { C dȄ7uqVt˭0^)֔˾: !:!]X IC\ZJlQU97,NJjpu,l bCd,k@nZt>_p쾡A^o9^rpk\Xf@.A d'@˲/1@ J")1]̒:/)镏ؤb)+tkC,A yw&>U_S|{a̙3:Z$t {B ~g x)J'ӈ}]CFe Zc{j\sOfqfl65 i6V2M'ψ}} 8w`/b/셲+{a{Co$zo,|o"˜QjJ#xRz\E{Q[j,TI-vn2=drY  r,KWIf ).t;/h.)Y9啔CZKY/ -_992Ndp^[{52Rwde\=>j ޅρ |[m``T:'H -@~ҵ-yoB%0H%`@[tUf?6|N7;N-W6"%z>xPyq^8EлousKs0uK;Xu-Hu[2j7s\tN7X$A!k8"mC9l⍘;*A5`!_E۵_ ]/*}Ȱ#ͷ/VuLRsWÈ$돐hU6_<$ХG\sP~~1)Ƞ/h d~ &FLc}쾁u*n=n(501U߂k{qӽ^t/n7݋ 7݋^5q홽~0E_rtM2Ι{ LOڦfn/ 1Oz3C.T| QP~FE=!Ѷ6T5!fmKt wW ?5.U^:~v$AT1:Չ{%Ҹ%Ko(7\Aj1j)A>xgwj%9(/BoyRVoClLp-M1 WDU1OVî lcERn"mInX}r=|h=%'S>:.)1]s'9鵑'=o@${|*lƤw.|r_aq ׼y!*d4 VHׅ)W ="[&G}BTbng`H#ӦDN*+SINSbk s Mh{ E/jvʍS ˆy;[#ye@~|k49WA.GRf k3orrr Zx]ܛ~1n!`2MƢ-/l 5vmp&{R zpo s9Gq28yFut"jP9pLR4" 0k3 /'d)`WbjPTAx<Q-lfOyнHxߋr$HWohp^xǷUA^fΖKn7oP뱭㧭)hP]XeU:_gQ7+9C o0K(*^?/͜7.o 9&$Roôvrt"ϢLB3`^Kq8BQ<h˫x!3# nhxHJ^S^khdQ:=Ȳ#en"ilw";ڤ6WH;թ.vk(U*}Ы-!+zCWv,1JdoȠኆ[2gY|uCYS‰ LFX>8j;ωEu?9]Z: 07+hc^G_~KE_nޒ6תt_)ʢ7+j=ȫü.SeYWq D>_hW9Q9Fw^.6e" ;4 XI~Bubd? Z ALU't4(<5Γ:EczЗvKΪ/p)[N[}xZ[2b2'e{|a ̸ >b̜n}d>BNt ה(~Sq]lS?F/9*ZqFgYZ$)3'cP530įI-φ>҉&I)]ShpNqgyqͺm]VHXA"LQDlQ"qnlqr]\gMGĜ^!f8?Ȅ^?&}Vdi3"YUMwNU` &Aʸl(˔/mxHɏ 7טprn/l^/E-Vk#]ͭL 0^:dj;%pғsp𲛺 ͳA(RlVT{Ց[l;xRh {(0x6iQ ynh0WWI8p*C)gglvƜS9c)ҜfJUetx#?`ɪX(>5xRO" 'd8+\h0Ξ`GfÈ$;8CkjB7v#%fs{d%9rd7l]VՠώxiۑA0QI]C8vTA'jp| *Eq0Iyķ 00gҠ g5YX!t<ۊ~<%b*?n= c4y33 Qx@I^h@#\.nQD(MKi_HIw 9#:8 fQlO K2t@g57&FjƧ\(`ef*7qa? fI7nK7bOw;^72! uPI=WCdF:a& Dt0f6S o3gG8 F ]]lwQЈ,`XѶ=\ᄖ;<(8ā;46u.wD`j Bș"iy96 v%>8 OΰoaRڰ:\^sIC:~YGF Wx 8WqnȤワnIMRQ5.>!Y`p- |aa?yy\ظ.7Ȇ,> ܞR`!== ^.ATp%n4v|ϲstm얒 RA&J; =WC}؎gyb} #3;H'"EH?{]좉`ZNnˌeDnx5,hq{m0i!d }oiE1rEVIF-t ^_x0zXGQnmb8D%:tқ\\xmY|xk yߢC^dnA#0Ҁ@>%Xo|*_5:[} l_0kn|#`>=[΄p? 8fnhNЄYkHCl'Z 6oĬᤁw؀qplZQ4yY]>Z]x5{k aB>1LHr ',Ka#5LQ>AoAR_*By}(Ǹj¸.l^""Wbs鰁31uࣚܽi\/TIo܋KCnuxs 8~Q_sw]-uvˏ-5 Mq[nP@tE^" 5'@M$yzboheElmѴcdž26hݥfn}-؅n2Eۅͦf;p[!:R1Cèȃ-N/-(?S{o]DFF:WshG=sytk5B6o|-onعvsDf#p1>4A3{_76h0DfUۣbi6Cj掂;daM=ŠqIBmÛ(rx"e=Hኛ285=)=p))ȨRڱ7 /a]d9Nzn8D%Ih"'Pd{ʍ}tUÉ:G!:Т5.JqnWő~HJ笌ӓHS x62Ϛ=&axhTsd-7.VO ;):4YU HCdAJ2V),Ks4 % "mLx"F[Vϳt[\=n +8"hfa:{|WΣII`@'mHi(j:̲t]T'gWCf]83$ "}XB8h֤!x[!aE# ;LU(;r$xȾA FCu\kxrc:jրM"fKAvMsRt5y[X<To9K٤*q#Cf3%f XEv)1'K=7'+Fc{渜qΖ-"b~a{jIE1%~xӗx(`\ Պ~k<*r!7vVҞQ(:q鎋_rK/[Z$Z.J܇K4O[*rP4" ;}ǔI*]<@{7m֓R^*FQ$o"ԉR--}.X[ʇWfv]ѠYIHa=G=6Rf#@_:EvNEy*z]C B0um4PyƑoٲg Q'a{0doR4# ?/)z`Xj1;1BB${q㇪":/Xt#5LYZ&"h#8517Q1,^.Rn.#C [s{3v^!n߾Ė]HPc0Z$_{b$q4M l9ki0qӤg 9M WF])xꃗ7+gӎJJ6anwyw I4zZ3pqs6zHǫTm3k;r1wQr0q c"։5uTU.C77'V פ`bsqJ:&dy"=|UB*aĕaCYLzES|Б=V؁7䅁ӞFM| CYIYc&$+䣨tnay-1Lm̀L34wAdƗ1=.Is f4j,ë?A|(.}ongF@e*ADŠZEYǰ9xpq/J=zll$ |Tpc;¡ܺ d4>D0lbi)(/+|kK% iؑf8U!eWB0$m!FsU(" `:KvA0f8"JM=CQρo!c8EǺl؅h2 cV zȈNur|_%.=3.( v4@-Bp0p*qFQ8֜c8:(hTئmT3](د?e)(CQ])@WI)[R-X_b|$J@%.8b Jwhj!x_Z7׺AG[ھ q:1~u(Aw>`"./n7h3{] S6H|U.ܸ;{JJP/Ǥ#`ql0P 'f:|,]`Ɛhw0MԐ W[j[Vkmm6_ SkZK]횿߮g ޱk;h"Ҿ~:ɟb@LRbMnu/nD3ZN^R}qPHJC*W>! SI?IţF [ب;m9hbvq軟Cھi25A\}"[8TJ!eǏ?`sr?iw^h<4Ҡ ȹ!9d$EA_J߀K i}DGp[BV6Uܛ  NpS;3T[~qORdeqr˲s:/&\=yo,f0ҸC3YU:6tI@1C/t% &I6sF񁝺HLC}]UH'N"䖣80"BeG;[Sc3@yDelKNx'I5FD/g SژO|ĎY>h=>BAm# ]kya4Q3 Yx0 ԫ54bܦNI Etϰ Ksͱ ;G/R&c1Nm!KM9).$@eoG@CwY<&΀He €b>sp`{]]=:Pu1A9DW,{$E!V b5<Tv r̈u܊rBpzj8T/Zb_69u~9*D!rޡfb=˗E NyR>%`mr ;$7d",'zIFtúejnذ$ Ά;CK~ cVf}b8ጯӢxܬ]#@Vսw=|QBeme{f3a{;b-E[ߚsL3E&ڹ V2fӱ:H:QrlvƜ(Zd$Eӌ' bdVuItLk*uV'|^QԤ fAߥ9*!מ87L?Fr#S('"ocÈjSde>([menc/pa5|~~(Ot͑0/̎"r&ןr>CTw \j:kЦu3OF u<ڲydls"0=C4ܓW<^%*q.lmPɃu8dj"87 'xv&$"gg[ c[4UD QoZ{Qd}K j{۰0q@I8`NzUdžȰ?{\Zd/C-[6G}"b@>ɜ)Giq:˓|)5p~?$Ԥ`?V<ޜ_s]]@?.7hjaTrg!2a}G@Ue6=21!ᘎd]}E-^7qw0 ˴^<,8_o.&d s"X2yr %.`B=(iӪFUE ?7U$3!Ip'!LAÄb'dS{^3cAUeBםZ2'8fW+ĿEaQ_D h= LqJC(]Az;jОЉr/ʀG PTzg8˛,Cwq9EbF PfS}ȇi > 58'q>zdvެD kW C;F7ML{<`a$7-[Sh1@y`)uY݂|ܥτ=ܜE Ԅ@#V6ޕFeكK>f !X>A~ &ɓ8t17[RނKRF4aO5"Pzę%r [xC;~ez [.f 8t: uwhpӕ, ja6_g_8:5F 4L:c܁@1$:syl,3:=p)fRRY8zЖ0ߍpppFK Pҗj8sXE`x-a Eշe655ag/Yu{gZYO E6ۖ5W&QѲV5t ? Oj`H\#w:܈PrH'י(qDo4a-½>7r ?."tVTS`OKs#SP  9T*>7Xf*809!ӕP] M WlG%hV:S:STCk:/\jQ(Rܞ"PtN#t)x#䑦_dN0O.7FLV ;58#zP,6<k_k!,Dkjav'y_ SX{tbz`2f ~G[3ieЅ987p@&*AW ,ȑ!JX)IĈ> 'Q ZkQ2L"-\n,=eA0R&H54(l_/ysr\2sxFW~Kx^$=$b',_jʁKy~ubps6AR w0W|0{/w׮ SBg,ANw[n?@ruрb6Ҧ0h > I^%bpឦff7U6J)& ='tbPo7d'vi'wSپ1?DNTDNT%"霓.n ?-u^IG:'^5iItW GR8#]% 6m26va& PT"}wiJ&xƀv _2\n0_]%<)\]LiH$]o^ioRuJu)>(N:NTNe{u3is;aV;as;;U!hylLĄ Tn,yHOW7įqJ}A5qi~]6}퍥A\ͽ\`Q'qi%6I'{alyUUcgAb^ؔN7 hN93V>`Le3sc}R.u/7ܢp^z #ٌ?vߛI$rw9?rI|?djaTcl; w+qkii[~>@7s oP]$EBm{ ˆd CcS{ވRc ~Utg0>NNNNu~w}2{69_I"wAi(㼂ݼ-_?;φ2ů  {<lzHgl%~ٗ/iE5;0Ͳ \pDpbzGͣ읿EIf*$R1E,וS JFJ7J]1|I)-ה za .L3񵀟\mY>w`oF%l6MȄN#2rhoyKu}ÝU >u5\Y݀O6IP? qr˲;k?!TO& o56v@[i$  g-m:?YUzѠKYrZӉp9% YƹO$q26`=|sԢ42)Szg41-T|rE!3#&]F0|y?a3̒uce..ۃ[ 6)UYSnTIf(C3o{M2[Ⱦ&|"IJ.i%Q8Fn1 &C@؆N9r.g/آ1150 YrX,Oj.KEm/ i1Z&"႑Mt"缲 Qx<.}^jz.p ò,DI.a qܚ2g G@ztΞ0;4CQO^;DBfR9w\&<n踀Sf힢5~ڡu(L hkLOX$)(Y%?^cVr` t'5DNeMgOqBS-$V3PLc&c#DzŜȻ¿^0%}R~c_"랥!"Y6+|iP *)K(A^K֎Cr/voD謡dZ!xTzV1J#^!#Bu2 ?{/u$/Շz|@P*h2AW,%*r$z짆!1z\ Aד9 Sr}}Z0"'kQE~8˶? W>ЯNnfco; W攡':{3z|wb7~Iq=v 21=M8oH?aҨޢ_/(*9#; c5koV !EY 62꣏"zroB X* =Xs//J><㲶&gEHE#CgH sC @$s(XMn5CZ>( Ig!1pC Lb]J u-]I90ķ&#豏1п2Y|<+b;A 9/Otg6 CuK"38pg6‰gsr$ el_0*L0RS¾btl&ݸt)eH뢴n*vS"*o--Xp[6LO6OtMYb<&ux'yp}飆~:O 4yeB[Yi^<?DLRҪpa{/,#la[$Xr2{C`?^<`ɉKI>ȑbh-ve7}% P P)yP5%76XHM-fG`8Mf0P[z8mvAK߈7 }l Z͖3=*h,d@~0RƕR~0= $#RuXDnV4gZ 2'ϩMY4OgDlsG-yt,_.|z.v#ˆx;BxF@4S9\bz w XZ%t.7uqbAgŒ?%%uyst oh*jp2Ao? |P;OZ n)R>4V#ng | iqf}1לo3mQ,~Lo7uۧޔG34{W{J%]zGIfOog﨑[֯'T%G@a")nٱ 4yx2ZjS%4EiI2ய5b>M-kAfNO㭼}^N, O4(N$#_.% j?ER' AmJAx-)Q}e~zqηXPbr0~pn^ѤLM^<]tѿ#ƲekȬ]Py%jNw|>Gfm9 sEK K<>s :)I0>%a 1נ)$Ii}`FjNh1f3k,q: a"!$L ;*oBFdEb0tN:jh/+H a bE:L&a~) B"H%[ h$V9>An2_lwCmKRBbYR3,%]k pesCQ dg" pnؠ[ꯐ%e 58!61M}(~H0TCx jqm3q8+^^/ĕ/$Ka #_Y fMJ6 m.Ę,! h `.0^Xh4#_YT 8] TydPaq1j= 7ACG7p0@F F t8QEAkeCPA7&8dB6Ł!$3 ,H` 6m,l,Id4ЇO"/4qe5W}@p H ],[?&1JB2xn*,>P;<zj>j;pP $|.J*VDlC;s tKpH~ITF9N`!_jvVK p^r<qy9_5!w O4* S^CB2&GP\Ld bKŃ+xL8c Nh2{Sp%NsfDG Vՙ+0]x%u 1ER:YqfvSoVN{  ~%>;XrrK~HJݧ`$Mpi؟aE HS$խӾ3E(d"iav\~B2D53i/S;dY/6DP Un`}.'oLQ)GSL-0,| Vp>!a8p7DNm% )\$́JVnz@LKm`O?'/7`DF?:wr^ccVهgcXE1qB[wAWw3q[qth/XJEZ.6,XSim\Og,ֳL0!rJ?f%Me832g`E~$z< c ^WN6uQQs^j>Ӭ3cv=]rLu"EgNF*zP&_TY"#>xK;p2T`HIlG<oin,9z8=C6; d xD msN"HW^QT:( d #L`>-vtg:ee. A$Rv!="OB á~o?,> |Z9ʦѣ֥=?l8[l2kK%M1PnI87B] |<*D9lbڟ:-,yH2lhųv4 .u a(~@`X&)œFhG֤{TCL[/j&D31: xxS,.ll@G#-!p,t&J-,𡇗 qԎnաW^<9N]~\mr,ekt;&joH޸kbrzR^玕xU!,3:Tюȋ{#od>F7ZHkK ڇN8ߜ*Ӷ+{(d~UEiG!M(Zu)FR$ACY/kv \LEn^N!(67β)U"eQ$ih_hmP)Zh/,gubY m9=|FΌkOPfrV|h*kǑmɱ-ZP88QX ZPǑ GDGQNt|b?(C;ʉ2(C;J=B;ʩ2= (4<=R1((s(#(uNmv*Ev1ق*JrzPfpdR Lu&XR;J8@#RY&Оx>|WHz0-whӞ27uO=Fʈ{hσ';ī"2)o>(,F_X.ڟ|lYD;:k1~*sJ<u)Ҳ[pt4|Liǹ9GvٓFP-=tz+`OzsYu8eOsYrbefbL?z ~p*:jgj=PpsAd ?S+3zr~'NE~qwgH2zt 2b^[ji#=K XC(Ïr Y"B1C,b!1yE="Y?};,E#?-_ql84ktkoc #a~=cZdV׍{Z;$8PܺX,51v,{:#F jDg. Z9*JfB+}G)YT5tQv$UIlз}7=[ȁ_:p;QU?JBeJyvp2NOWOij"mE\ulg<&/wQ .02vj6gSа2weZ{($ߜ"yav$i+}]s! ynrdP@BRė]sݡꮩkOW:60D !u/>(7UYtsS=:*G 8_e^@Xv 3UgNlNگ 1mWi6 77RmxyT+S:N(Eu]Iy"n**(XTǦr*rp73Yn->u(=?,jdTzj1Syǧ<Ô2u $XƶJX^}VP בzUTqkpGQz\v8 >_Nm!.K ڥE ,+0Hk4UE//j`Xj )'4‡eLj3+GP˨ZwFL|nP]JD =eUZJOGYUQV( wJ&TE2Do:s oֲd70G(TW9:tcmOhb)}Zwv~uڐ==S;`zjv2znyEtqؓ$}mZ .~?\ W`%Uյ.2 v^a8թcm7 kQ0d|lo۴A3 {ߝ__ᵊ\G gp)"N,3ħTyhRkt{ 2a@??GPpl!y/Wj*ćF`WлF0$˥2E+r}<}O 4ۗgq|;rgi׶/9?,L${0$av}w{wrufUZK( iPMd9$:Bŋ4-f5X)ACRyqq^. c?B= $'\ tšT؍ٕ8 /;hF+4VaR i85]ρF]*y_8f(`#´bjVٷ^]Rңro :8i%$>6GT'VyQ< Ψc:?nEVોGzS CW&4в@ `fkyv>;6iqK?V%OJ; ǫZ¨0a&. %>01,aE9)YըMw<Kw"2+[qWhk­J̯@%B'w[lk"q.DQ;qخ H+ $C<3# -E ]tx9 3Pi7jOlmyɶY&Y Υt݂ (tM 16 |SB!mwop Q:TE 2}v{@5̰4$X~lG/oGiH]|UFt㳖"GNf6{L2]$[` h,,ןbb? l#PKY3BWC<8պ&=ɹí' 1Qhqj{)=RPtʠT~E|#=͟o(kfB*ha7y^^81hו`ۡ8$B"00BQ> eق?l=v=Jh,FST_r랅";\Ru A7aP>4v@C m!J]EUgw 6k=GjMf7?/n#"f"!8^Oz@DZwE6ٓ1|Y L7pCк>A8Ɗ7tI!bJv_͋iiFJ PN!cJ4k@S倢>4Θ[{\b⣟Ϳ]走|Ö FƋI+u s1ZP+[+pяH7̋qn3Z< "d{ hGI{)"&7c~@8iuϭڳ= {uǗZٞ {z^ƲFo4,@Fۆ=ϥ [XyKi",׻sG Z%׆5l,=v4F`t5pe2|!'bxӹMo&AD2 l] ZSEXeEAPF >ljl3b% #uGӲuIj,,5*%A*DXR(|y 7K7?zggT)[[Q[g7lx})Z6ͱz=R,mREl埇?κ(Wm`@#~>U741К/*w5 7>oF7. -+s wA F$7gVTƫ'v* f,Y="7 r/^ !wn%%TFU4mThս)R %eQ/hSi7iO]_>^u6MP@s _Vs۪WۿbwYD׬>2[m+76/7۲]ּp_l>@4̡䐒7IwԵɷV?u;"~ZU L8awluVP3*~7ؘKb E_"hc7X@c̲} Cf C)ˮ|C^Qk:|H/^Z#"<6V4x0OulVH3J^C>eƲ5bчUVUn˭ymW#u*߫ I6>Xk"kP`.@fM)Uf&MbT{{4 M-~ ȑs wXf2ϋzcs(@ fA{BZ'fiŏD`PT[x"fO(\GtFz['b6HO)>7DLk[k8p"VZ`).k.oH37@j1^L-m9-D Jb=wͅ* @gLdD`yӺ`8*bl{װޱBUom`Ұ@ݖ%Yӣq^fBRc_X+Eg֍vvbJ񳪳jsj-sMmgT6(q}uKEk RMZ6U1et7LpeLu}81fmD[W]aټ8.sd a{J++jυAW=jJyUx*>6x=zŹϩՋ'b{L W~)Ш/I]{n>p]-P590 }6$"\ k;LN+E#`e/9 sc*WvV)_R-@?a#kvgDuk}Okx(֊˂e|:ܹ{*3y` l:_h"GYrZk]L^U uY%>SsSޙcCo K 1zǚ[*Sf[qil&%]oȖaȕi3G(:^B[s%GaE$^uZ&ט0ZhXa r-1\pP l?Z2cndrX!(S^~'_ (ٮ:Ӷ#+X hV{@Za~,'UiI ~4`w mWŽ]PNh/P6-eUU$&͉@kky+.%5}Ռ: "]A؃`J]WMkX6-k+{AȬHAHgy @l{o$-l?SQY3('`1kfgۧF\Y&N}\ 3unbCa ~ZեI)4;JOB\? A:s]s~G4_a->_7uzB ǣ?]=i(8ؕwb@K";~ؒ]QYKʺcיpi0t#L0l6،Ha%ȈG*#wǽ <]w:/iZWMĈeUdy|>l5;inCqy^I2)*R(eV_%+:2 A&>xʎ,<*.`G6RNŌŊ%% (&u 16Rm*@׵u6UUیM:EśkEqeJsMɛCiT0cu-X'YGe닋/.ނ j?R$T)wxkRn\H, "&q_I0*ŽK\Eֺ̚e <4/ sRpd6db[bJ:m}?0.K7ّs5ZO2ʵsq Ή8LL&kE1Gޮw/%4},zmY}iy2ʽȹ7&S]kLW]v{5X˂ L!ڒVui ëo4@7{Z8?]Oyqy#̭S ȭ) %_"l~ik"AK&7g kL W{ܞ}'hS뢃\.q3/^sj;6<}OxS(di<;}.P-fƒ|m'B*kxoЧP[eQJ}ϙF4黕CAknP]kb` Yvܑi@] <e#P2& : Z޴l]gs'`t^ew9>{G[ː{c G[ːH{ A!1n2$F=fĸG[ɐh=Z!nEvU\z_ bg[FQڗr6yfh A4\ <[Gh0xop*#/&Uc]NN8T6^[+[Nƶ,l.MY&uaugU;@䨩O} ZM0 2ɴǣAHpǙ"^y҅K~8=mpzĦtF J4H;c!W n˪jIy$ޟtģ* ;y^iʭK:RU:|ХUv٢8Qxo(9DK~nܻڹS-ntӬXw'#DiֹϔJAf4#S8 pv8"rXŤ?ZTbQӵ5EM${aq^6U 3ϵceK/cXzk/pcDzk/etR\[$n<^q'KD{)&qh-S{)<^J4׌J5¹2C\yҪq '(ŔȌ%MeHBg<fnJ1ɉ{rA yv*Q[ؤ(b^=9!ue?5WJN MC NJ?iCmN2 >!73Jr@\Ԟ}7^޲N>'.mn<8E:fH -S-"SUBRK('QVrZg`jRI]~ݜe.sWn.3]ܤB͜]@Q'Tiϕ}TV hDĢ+yH›ryF16$qp,FDZ4OĖ:BI@:BT q@(! C%aA@+a&J %=TBq@ p^ɺreuu4]Wf߯ix{;jO>K({b]|$LQej-Rsʊ'~S,ωKo0ڥZF>ӧbDTL+öuFE; 4UܵPCp&@ Fj'zPbN=7;5ix'U>'0栒& ݨDSbvn8)QچA*Dzp^ڼ-t\uYvAs/+QdYy42KdZ]/hdF6op<\>Lԓ{_ʪUpP(2;Q!~[:dw|U|'%5Bjd+>^ǂ8,< lߞtJhM)WĘrTM &w7ICXRg aoy2Wrr !dR:]0w|>rO=z=Hѧ'ݧ+/>)Kdрi63}J^ ΠGJS+_e,Ve'-f7绋/'{`ivw .((#>(wNݱx>*Lrlp2'v+7W k>+gwTB ~r<-?08w^ tdYS۫DpÄ}I@0."fx g̛̮ԥ7VfCo+0Ep9*zѝ~w/iΈEEob]/ ]L#Y6Dur٘f>W\.I')ܧqؙv<7.ȶu<ɏ'@@Q䦡Kkl]6jJ_2kV\`+l+4*!H!wV5*!⨗voÓ޳i{ 3l{.q܄Ч6\ͧGӀ@On#hJ}b6;ߕ)W;n gH;[ )2bFd\(*/l@/-UiRGj)"|f喙eZ.A=GvlhqwMޘ5U-2qwKȸnp:@ɠϔ;C29w]-1]5MZ X+BgN`MV{Gr,67nYXZW6J 'M>J['O؝Om<<̲5ui峷zt \ EN$A._kO?m {$T@́~KI$(7knciI6g=N*j<܅qB{V X]c]eھ#]q AQiAchYGuJ)ɥ86Zoy O>8=3 $glL=L8C3I@İ/;7xM -\Pϲ1u #ȒkSxZ>KH̼(%((/J ֘Xr@~p ]8bvD#I-.'cUd$ɲzR5:"[kֺxΎrEրs V-m"YF&D|DƏ x2M(/T ф19>YU\V.,@f`28a ʵ2 D;3n=0:G+A /&ap(_k@<ԣ[ýУ`K2 8.>JPu6ǽ8 No bc?-4]HD:N'fL]cVWnװ{+{48ğ,{/Edria}@gopɎh Y-zW_ uT`6%@fYSH0c =O6WPfϳ'׎~y/ cV1p/v0GC+! {X (BZ{/Py[l#UXh;A \N%^YzK ?8 T]!8[kPKSFtM)AUguidata/tests/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ PT` khEPKSF"V&guidata/tests/translations/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ` ihrqC))J+I #{#PKSF=Jf&guidata/tests/all_features/__init__.py=o0 o2RFHT2 nm\ :ND.ٹE(+,e"1VhtP# ALiHG+y;-LM! l*4LPȦ\\HԒxՌpGK'Pvj L$OBe:G_! ĸ{eP~ Oٺ@F[/xq$Xoz̐%/ًt8env^Jl버,ksd| ?-qp1 Ԇ}cm(ەph-GG7)VigDadݍ7R Z8$'>2ő(ap>M}PKSF)sU*" &guidata/tests/editgroupbox/__init__.pyVMo0+|lov+!MjvObldM6U^Vy<Vu("<˕Fk.Ѱ2FvLśFx gQQgG[XӱPG `6W kt:I*hQTQ!MkTHժ_+U)$#}b* !$:ӗsq~fKa&2 _b”WEP&ĝo8{{ŧD5>7#DtPKSFL,h2#guidata/tests/all_items/__init__.pyMo0 'Ӥhc%qK.ȯ׎ hMG]) 4( 1oU`ǃor c&.5va6M{u | 6TJs6I;pojvn?U؍ǮJ70h3Qw虚7:kS!onߩS/t@4'PKSF~V_x%guidata/tests/disthelpers/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\` JI,.Vp,.)L*ӴRP(PKSF'A,~%guidata/tests/inheritance/__init__.py= 1 ཿ")~ XJm6%MDQT,!y.dC"nfQ^':{}R=ޝgU07W%5}N@ImKzuG6a^K>{E*6O\xWPKSFD+guidata/tests/activable_dataset/__init__.py0 Cۗ|c,9y= qI"PPKSF`guidata/tests/hdf5/__init__.pyu; @B NDAQTY,rn|3˦@LkF6uR[¶TiK__P*9!!GnoM`/e[nK.w`\_3L@DLEUeD" > КmִEZ}QWסߙ ១*zk^ʢ7mVvg~m}zyuٲ? o.c/mk*b=ն][q_)Uuk5ʔƇ4Wl?4ҟPҵ)v^; aQu[a<+]O(6,\l3Wʬ@QDǬ >άHō9NGk CfKc-z'8oN rfƄ-ٱ36yˆ_U׷IHٮ @wُ0:Ϋ-<-x_-E͟e5hl9u ]d6Por* :9*xu\ٲ5-QdϜZC9@MSFƖ㣆܄..{-CEV֘jL^lj"y﵂Jӹ%DMU=t۱ngtkWCo SKm`u(6G^ @tf\{4YG"Ů#{b0)C 4knYɫ3ϡ닷# [h Oz%6uæaiwci웁ϵgql]^‚J{SٱIʦKP5x+8}݊T_Jl[8 Wo@&8Hΐ2 cG>?C-)[[#pU&w+42e Qb+ vF/.l0zN[5rk0ݔ! (X#EUҿ(A@6f0`)Fl"/궢a@&BPl*\u\=͗6kE=*y2MGsbx NlF[d:SuZ"7= U7n(T?;M5 Lt@ӿʣ L.R{Mo#0 *n#SK9K]ĈYBC(.̺ m&~1ĩ( mP$q!Z.zak2yf"%o ᶆ0uLOidqBDРH%3+0(2*6fl1QlTa{GEnu#s&tSGQ 9/}&6oP0*4ԟkfDl9YU^jBPꏊ™$.;v]sCj cFёE?hD(m~U[9D*mq_Ku5,O>̺ˆ{ۃ.KaY%ۄ+T:&5(JJ(7YBv.>bݤ,*NԡTIQL +xjY/ Y}c4ь5;Z˶? Q-qsa2UWn=rs?pP׀?֍]OM a!R*5 Pt 4&O!񣨴HëOp/' Rؕ9@cl\, VfBVu5t(<jJI*j=}0ϵD*η:O -RX\zK ϔJf:SY ڌY88"r|4gx֪^E.,F;SDW'#!՝ڵXjЁD& hʚDxP0T.:z)Tl'X)IHIT)cB^"*qN8 !z4a!\pi+$7Z$9T2\K:;*>”_uT}њޣsں&ӀeAMڪ_.Vz# %V8BRC)Խ7Or_ډAE@P|!jβiǵ Ѩ#u>[1ڪB|T$°إdE5(&=/'̇քG~`Pyxή+q*8GWE7ś)UnW%msI49^漝kv"@zhi[vL2xJadMu zH2%NYF#9UXS 8QPMig FdXj7%_:ʙ2Qd>>u3e(cLF(q/c\F(evRR{$a2Qs\&:JDG).qhsSG)2QJƴTF 'pcTY($v\$" {aJd- &2`sH`<W?žW5&/bIi;6Oz~UT3 pO!v+q'v>9 gӐI'~h $dxOnL^d*䤃O#ToN^g< Aε)5{ܼWVe.lU:"qLy{"+:)*V-%B!Uumwցq@4ޠJA2/߄~r~ŌoZ'L_m~E9jS'*߅=tBx #9cǢ}uLj<"Ό[HI&#q&]͆*ߋOėZBy@ZBT q@+! %aq@)aJs%#PB8<‘_)!R ȿ]qpwYQ\+Q6D$ .FƆv1½w Xy:i;v-5Qbn40Ne]wT"H3dkH 4lЍDoKRD, rڢ4H'>> h"XK % n/٧3$E46i_A-o_/?x L"6ۋ žIxWW㟱&P'>UtF>)f0n\-qǂߣK|x,}ZݿX*p-Qu,6ϮěJ, ,UMţ.rib[-UZ duZ5zjH6j=[7ƶbs HYuE}S,Ə/K0uL}2۳DTM+Ӷ}F`+j#M 5 eZdmоUy;}.Jܩvf.-(w UsDҘF5M:F% R7t MYVlJ!БWu%xX6k_΋.!HubYc:#%m5%]G*/o zG3nn*`õyƴN6MN6t[],o__OfT)vE /((#$>()x>*mfGucқ,2wPțʿ8hY?Q񹯪m\D0^b^lE ns󭠥YK%G r>H|dE;PrJ,M[t']!OcOtWc2)7x0ڑup[Q 䦡-<54HYm/yWoom}x,WMn׍0Ux ]'MنWhR%UBB) kTtE^.z)@8<^fwƘ.rSn(T{.Okyd1k'ۈ( Jė |Gn|4%]m7E%qN )w-/Y1#t\(c6w{!Jҳt?T#9WK qc7Yp_n@բO FS~dmCS7fKdk`J]75P[!-; :u2@gEW!V&fxL=*C][wLʞ!Fn,-V׺dbƾ)Fbk줒Eҡ}o F7#NRMë$ ;̾|ecG5# DO`GQvڜ^Y`s^mr8$R򃫓.@'/`v >iRspMk lƠW͈{^h:O;[) +ۂaRmX^[_OzڻЏ| Xzrݛ ďB?bھu­ܥ-N\]WQ]%q%t#$(Y]TتM)v)dޗ`I~x@J 7 Ot%+:H~6bΏ}4'8/>^eO7bqu 8X#JoPҴҁsBcj86NN. *o9EnX; Ndz1@N}""3$BL2n#wRQteZܠ='҈y =F GRW%1*2f>l  8;c'14?ÊHq@]ک[ Iny2} r~R;"e!g]^kv-kp-%4I_$9wQN;ύ?b6dSv6x&$͜lmWoZabGuVHM 9hO-r5>Ӈ^XͿZ0N[ssv<29^MZJQk`>tn)ÙK0BS<˜2$Z0$D& G2䶼 cn ;VeLh,q? n=]+_yn1k >hk{ 6Y?48Jc1fOv=n}2'?PKSF%(7guidata/tests/text/__init__.py 0 Ew}dkBR2qS },v=\yE1bfQVN7+}4\j}xxU]0lgZ=PKSFb#π%guidata/dataset/qtwidgets/__init__.py}n+G໿Bo=X`(JdRWIYeEcŲt3Rm<^Yп\~/U-uӥ*\V:YV?6{X7f k4oƧW'ɳ.livտ,u+S[uoNro֕7et%]6giÜ{4DwϦw4TKn|E&:lcmd/PgKYϷFm䟯,Ks>v\1e3ų*}l|U)@YoemDpԗBW:_ 1T1>'Sp :9 djRMőYfWg4GPh0cؙ+b]`E-;G8ogstȕt#D)uFɱruN+Z@Zߦ|6"~?bGٲxײʈv;/VƇ?|T_NqUg|nu@N\nӵyY|WYcmdeپ}egR˩hF[zNM$ϔ-U*isU@FW4wa„+u6Ӫ7IƏXבlw/d.EJ,^<[Qw맠? 'BuO0}Q0tc Dt^tc"$- 4%;u 3D= ebSf2`p ?=_ Up`G}P {GL5"4I5ojTTP"K#fUݰ!$65~M{q~̞޳r?ͲMziUͨ݀[H03.igim[Ou,6A$W p0KmB8zLx(G(1\.X"w(ƍ.eAr;43t#1e%1֝_mmw\uVʱ!!ҲnpM1z;gaѷwhۏJن\?7c̙Z:qISyL,N~[cl!clf%515-iX'Z"ȳ2U/Vլ|э0scPk0t4%Uãf{t#ƽDoG7o099:A[m}*-j({7k(l ?)㱴Z?ç~72]{LHK~һ4M HS ;\`, 'ntQeinU7f"va<ҒZ:oWYh>]. ݗHkIZFfVYUjg LͤRinR-?SnM :BЧ,UN,) mb/ز۴2 KmݳӝtxKIS WIiR,8`k#qB6X7>lրen .m!Jʨ V uP<ʟȚƌtUi_-SQ \Ҡ MdT/V jˉz ML0cm}?Pu9g䥈1ݻy 2مL?h?C[<te8'X7O$DGp*̖pB)̂B;6SY;`ZF 1sF&XnLcpE%J=@7泀'on (.]گ%o~JMڪqTL٬Zq0n.La-2:ܻnlR=mژnш6)\XzU5%qf(7yZ0inVj 3a[ `'*x#WsIQ >#6\pWy[d\,͗*-7ٲw:BwpKMڄ* |uB й@ζc>8(MX.Z.R3a0?+l,3l{bc`23c{{ 2b\e׈W:t?p]Ǝ8J׵Hx]A*yWyagiw_ b.&-Ԙk (2P˙Gu% AxޥRtW! u5p"Y piF"T`X`zDWvh %쇯RMV*k ڍ"{~nk5M:o(@QZ7*4؟.tRZ'?Ag1^Iͬ0LooiUTF<ȷ#7>)U~tQ!xBR%y(1d >պavD0atlNjOV5$(nEkȉЩUEqׇ="E!яƏ~ikO]w'0[+3!p\5n 8`D0 qokb*uap H:GaM 5.F&R|qt 7 Q )xo<u.}ViGlmTi/ :W.` X&4҅\8ߘ+V"̰IU襭jAqGun7"eCe,(cG(pOcG(yvTzn+d8(.N2J6Ӯ9:eO2JBȮTN VaSĀ9A+.iVx 'xXE/v_uƔw9~Yy #?D8sA# " 8.:rk{A^.2쁉᱁pK8,ƭ@R}AV/JcuZ;*NHR&f&nh |mJy!J ebL $}}b99mZTG-0Pv~qZt`|ߠ#}-ZѼz*u=Fյ*֞ߗfXzٳy288_׺xO*h7{6e>:> O]U*y>G6m-e }_0 8ԛG⾽"7.A59̸ua<[ǡ4쾝5e_tZS^:E3 8[*=HǶ[ZN!SZ'lv_hpVb#s)%$GF"XRhI-7~ O1uzUb@ƽ3ǀۍV*yL-p0fz{GI0@9D P9Գj~9any.tΞ^[\J1 Cw0S];TE"p.e=7m%IÀs7xnڥV>ڌӧlDөl M65Y˼2oP'5f^D%Idں|Wߩ_ExK6-.fw`p$Y{s/p<\wc\jIn'4?ە>W:."˷:û ]NJj`J{!5[XC+8,xx udR94cꚺ3n1e܋tþ/VR99 soA7-߲7L 0wF6/Jnv8FfAtC՗pd"08jOϾ긁e8~9̔0;$0Dd=[jEj3oUGd*hےe]AJĭ,u:,PjIJJE)rMMYe:]ɚ5}4AQ֢ 0=ͮiǔ( 1v -qvg6E#^S[0^5[1(SRTDMm=8}4G~m=>p F#=#(WVi;RSسYwR457):Αrcޤ>@2wѩ6#;4v{:c᳝itwjv·~mG~1IΔÈIsCR+Щ a{9\nt琻TW?pp!yË_@:#+xbA"_)SEӝcω=w6(<]<++"k) z$8puo}-b=\.w׽ٽU$-] .0ہ|wGmێhVA6о@s.-ʁ¿cf9g ϋU.yv =?t;eLBmA@!aډOaUʗ W7ËO8>դ 8xu%22𶯽"1̪UX6:2uMAsX4+"UΏ=kvz;詮[KYMŪ21$$>hl _ٔR MReoUٳo҂99Kو`x]N萠`7Um3:Vt˞D$z5db&0|_e'."ߗ3vWH۱].>YOȐu[/߲R~ \x]¿ebbʲbuw` +ڍ@pQzo,ZUGzD0Tl(q p N C*ۂs arOYەr`s}:= t`U@!wo?>v~p"mϵrMWe^Y kfBv w6#8"jYvA?.CkInlQ|LsmV<7Hhn ߌkIco3|s)9v컬HךV7]AGl+HGC1.^[ygfCIU G $T=@B~2FK ˅EWYҘ /#]qrI!kb5 LNO+GS\[[\ca3SO#01DDwh>=4 eE6WِmE*$iwgGCl? ꋺ1&@عoc hZU\VW Xf`0kkl{;0n=:1jB?ٚ2A /&ap([fk@M覶Hתc6O-cg~&R?oSn.ɉSޡ]IUZڏP@yB>Ml0Ͱ {`@;+e]* vB9uů=G7ڂR-H $&;nߨ~0]UsWx!<_ELG龸C?PKSF&D%guidata/dataset/dataitems/__init__.pyMk0 96;죅v2Q:1 \?'JR(8KJ[&W*F J:b);F/) (GP۴(^Ԫܭ9X/t(!D- `#^1(I*Hj0ď'NBTѣEvWInjSiC(l%CfPeg(zIG|,q6Eρ:d̀9Sb;^zAY <1|lC_r3e[S,[VsxM}5dPKSF˴f%guidata/dataset/datatypes/__init__.pyMo0| zeY$&sߒT|0J۴Ok$@7Z!!EJj fUdȤ3ULk,t $pv6U33ĠKp*UECdN(Z2e՞"`L\ЋwU&!Q+c}N Ǯ_D+Ya>zħYk ޠeyDK3i/4zk7C(S-GR|}\Xrk' fHXoTꂢFgSwp{_NۊJ;GDӛ, .v=#|5B{9PKSF ޥ"W{)guidata/dataset/qtitemwidgets/__init__.py}Is#G]927Z)&2\~{޳Rϡdyd,Ć=>>wmWǣ|hWe hlrmdx{oQb&/Vm 3,pTMYw6[C!9"W]{HkGEirkhGUCzO&:$Y?Aeٲ=}WʿQv w~|x{s 1|ҵmU~g|9UtL"~3H*k:>UI $iθ> g+NrV/*$#u枳hOA TT@on5w\8@[ r$ ySTQMh]|}wB|7.<Ӯկ]*|ʶrMp{$x59yͥxP^g$NhcrɵbˤV5[?4@O9q;$4fHD\b@\w۹?8jԋe.~Ɋj5Fjy$>[%pqQuuGs ZNCr 21h荛rɆkz0)W!r!ZC̞ R9)7U);B8Oȁ^E Z/DE% 忍Pl>ro>@_W{Oj̼,wD"YИi6pE#x&9{G?2byϒLۧ:_}+X7Q~/.?QAބ:Y=}~f=X5W"S\ { MW J's](+J:_n$j1֒%EIZ.f>2o=pr9qx/cvӼWŴy-KPZđ,X8^l~4sO[ُ*$^iȫ,_J;RH;>-,TY2p=@~v8Tf8d˖ԌlwFxP<{YJ*Xz*eug|Y;W^)EjlZP.s\y@OW dK ЃFR،=leX%drvU肰nUӘ 4r";˚ S#? y̏7~ k6gU TF_eUg"P֕> F]UwY#)!&~#KS`a} 6lh12l,ذ a wyi |NY@u8=ԋkP71B(ijOlϣB#lܖG" Nم#(6G Sָahϣ#n,H|spPؗH߲e{K AF3iV Ӑnⶍ(Y?AK\i]xEAab.]4D:_e{Y{\l=iV.:˼8YaSTL'EF5oЗA2!v,<ڲ}iG_`s\t[E\ 5;{_q5N;msWMQw#J~,%7/Oǝ8-/a#细/J s;vB> Nn;N7vuÆ)GkB z| Ot S,,f{Pƌӧ>7qAr \U0+`90T}|`r;J҅HAgWkj(۪pX%E!a(M=tCr9`nH4k}*eg x֘(Q߃opk.iْZuYI~ GOo\Y?xe &HQnzc"Ā$Cr$91ĀcL 91ĈSL9qLFdAْ۩Tqe}.- Nj}Em2=-ggPNTq3N;~9?O~x oAz֨ZUjmMհMbfjp2|Aϡm)T,} ~߀~9Mۊ|4fu:/ &wO ^31e ê]AV3 n2x_ҊNT,^ ')$hq_?D 6x4wR,M f&J4'Uh7$  `6=`ړsmUuIOZʆ/:Q-I!bŵ}İZ)GCV4GKrzfYhSse00 7I:?C%+GUL{tb+UxZTT@Wg&Jk^\(5)a|+;̴r)Lm(7 2 (581URQCY:(G#ar(lH{J99U4\OO#*!v?âӨ} >Ӭ泷T dyjTid&}QB H"zՁERI9>GPMbRm]J#.^VmПqHΖ!+Դv ՗DmTEVˏ*ք™ב8L*m %ޛQRfEU Җo0IZ~󶯽Hڗ|a t2iO,vj>,o?}5_b_Z2Ls9KcQi/؋)qs]6ifFjNvًȶo1Z}W 8}Br̍-̸?h SZ'!5ӠU/Ks hԃp2.'WYfl#5By1k(6/o 4JLRz& Zn1l\iD0@;{B ү,|eʥea^d)M,~Ą#~H:0D=U,f"bJL%-yF5WE{<D~ur#L#*J'10BFGalaDaFGc#=?1BSy3#=?7B2q??Ʊ7~,إ}0IWX,Z"8Pi-ذeg6:kY ''WGtiH7y@C]C_oO B.+xT5($x]&✷c=i(`qtڹVtd}5ߠgm-;ӼIxbe.QMuVE(V=Q>*ОU-=8(Kns`SU6E5Xe0ku[<:~2 doo*Ri,EjPA?+n}#<5-bZSEockS6j`KV-.!VOE[A۝+?צ~4k*Xۨ\P{)$14X: m AY@}Maꝫ~Wg @yE{g€V"OvMp(LƍɐIDr{YO?~\#}Ū֝=qAɒ0 CK}{WTY|[9lIߔ!ptnXr- :U-.uǀfW54yzi ԰oĚ1|/e9}` 4pqZ{16P/@gܜLҴ7eyfDer y2>2B`un= Z.. uRc:=#3&م|Vvoo&R<hp,Y{sc<nKepRͯveQUr(:;Q!}[6tw|QB'ej`Quujh}&Owxf=YFpoQx*>?LS1>~2LrD:&L/@/ʙsK^(Z?»nJ']wf yZG)){:1Fʈ><<>d/Aym{:ui6* $7^_@Sne/:2 dҌҺH%t:JdMeSwuz( Dlu?MWwY \49YARcPVO˂S=%sp6YA> `uxџܠ|B Fj.5uR!Zu R=[yG-oɠDyY$e4&◅D? )aδU M}xվ4-əR94,l: /B|bؿxȞ9s}N ]Bp'S<^| +t_SkNž#q}Gl*izv_O!E36^5.ӥC\ߞ].?+OL+bxFAE!@}}ҾntZj:[zˁ| *!@ s.7AszɋCێŁ0zRA _z*!1!_݌/>Q\S3\5l ~EB1~ 8^*Jt9$*9KIq;'_8ɾk XWAU}iql^Sr傘 g >T|>'9ݧ;`:{֖+u9kH ]ͣ)LMCGq մZ!<ˋƵ~^2owUK;Ad_BICV*!J-&b.הּkTt/_.v)ii9&8ޠgeL7AqE9n)Y(q;0:MV#]ǐ`n#"/3ܕѵtrBt]*myq,„MpL:RAɸR 3FBo~GJ:WK ЫQt_nC֢ h)^}ck77ilui(a|M7(TʦuYEnj"t(M 5߈/0{DŽݣ">TEKdd.Tcy{aS&a-*/^$E~3kֿ ZRIݓ$ tlg_ס>59S=EKGl(3W=;.WU ~z~:g']Á̸1'8cOҁ1Lo*xm}6mEo5 1HeV p?ÐJAx[8&)ހ-nZ ϿZ(i*׫0ݽ\x6k>HZו˶C fع8W0t1_EA |pqز!w /=K3`b SyJ H(xLH=OOqv[~Cn1-sJ[9MRYl;Pj_ɡJe&C8ML[D3[!zXޜfT(nUJDi-0sPDҀ!gQilz|;,[Ol jc1A`N WE֕B>0Q_kv΂q K / wbGs/Z֬,Ua<-y%*XTjǏHC@~mF=?Z7YUgjzF Ϸ v79?嗍nV}Q|-*XgFi<&tn)UAtJt?7eq oHoO Vt۾kt~}HǎwOVFنOJvSYA%Jza,PQ"NP8mDif%l(kKG0hLZ8qx]mv&0# Hبp0p'Ѹ ek8CfEl~mziǼoZMn{nTSlr峾h`UjCNIHE *n"g\>*Z4b7nLhrpa`=]ט= 8/:X7eV1K4ddkz/P1Be &~JQ/kvOB\>1A1cS}{q4ߚ?vh2Lm~]8L&(y֚UDzĀ< ՝ڼ:> ż 7jŀ6YUf&;l3 pV,OmljVfa]#f I"GUҳu}q|n[ B 1zDp|E\:bL8c]d8LS4P˅ u +M.џc7̄"C3>rE"XDT!aC`cƂv:6vh˂F͵nry L/FarؾUel&B K)$nV1:6[,+/?Q_8x{ .+pPmRmot`2/(܁/"WCm!I X& ^6UA5,|0Y'2~Ժ(j*IؼJZX;j p#i9n t,?ˈp>W*b\-z4lGjk01멳iMPXF=nGM5VFt'vcagܨjRMa?+Ӓ.rI↼cic#QFCU-~7Ot cbޕMfWLIO_3߮+cq;ݍ6rc\iZ5SB򉁂)_`.+ZȄZ ` [ȌVýr,nsT3w+U 0.YK]gnG  \!B )j+ 1tRWCa (\a +pPuhm\~;&fR'SjmxræTn޸W`GBM}߻t0 T2x?JX->x0qz(mi"ghua=G2+Y&W*nsmT;D 5$\:>'W [Z/":7J!['>j=Mu}0O@*G9ue~! $yVnzֹiS>J Û$yMPdO4)@p!!&Im5&Ӏ&eAMڪ_.Vtݛ# V9bBR#C)^'f_ڑܚUڋԾx&1r]?hϥ #fuq7lE3 Na7DU+c&+jFp7Gy8!>F4,Kx@sv\xT}I1U< -,y+^L"mH]4= fxIvƅCs[?ɲT'SOk;>^&bqSрq p3p`"T1C' >Gc'SI;Mr£ee,OsG('7uOI#6Ďz)`Ѯ/!^ 1:"*|{8~F1B|r(U6E&RI:2O[\R aVU*2|LWEmJFĎ(߳.{ X{Ekr qBТe1[g[%ν72C?ɧBg!b>E# 9cǬ}ąGUxEv7&%p, w&͎ }¾"!L5!mBPI@ ! c! D08 ̄\"pBG~)p !#&v!ǕqfE)s~t s/D۰=p1<6е\z*r` ŸH͛;qA 8Pj$ML[Hs?@ӱOzxH84/EIx[LN[^tgqĕ9֒>io8I{ תysc.j[Um$vBgdppx8LWvpx7\G;pM4Iu ?`E>3۾-62l+?Lyw.S }{EKwC59qK` oM9]ޔ2.6ҔĶdO[HKR$uZ֪zlp6>!Ylv˜ ^=Rg-Rݝ Ft& ^2a:Zd3nϞ!gS6-Oۊ [Q{ hbx٬.BPW*k6"@N b}N2 aGr2uOO,UT-tF%R6d uYtrYȝȋ8<w\.>Hub^c:!5XT־9](/o3jG2ܘ K4ƵjEyv _Y }Sx?d𢲁 u"˷ÿu))}.OWpf=eqI Pb{|ʩ8SjșgyI~rմ&HCXܾiQJ<^? !$AE TPV(-op8di'&fv'}zzA}޼Rz㾴s$'' W8QՏTIxY;)L2ZF?`vMIH ?ދUK=Z i/}l*^QՋd$˶E+aWHࡴmƤQy_⽠ lIZecꝻHB)giM_=N\TQw*bxzn]Vb g?z8hρOni|8g8wɶpA u {#Ď{EpM oL4j[\ rse >˒S7v{:iS᳟>tꭲ]vé߇;8qΔaD魯a;t_ Mv}ǿs©3{ [:yu|O- KF <]q|`ho3)E̞D6(;4SE *+ǀSS?Hp suLJ}췗kئN6t]^\//ogG{{yVSid\?Uwx:*m&GuCԛlcq7eVKF!+ cκS}ۧH%sqкFn3#Khm;Y;u@0vbBLBZ5d;n"bnp|˼Hyu W$H}-̪qlldFMA9^,~.ǁ.{/t]/p"F(plRrLN YwL-7=&gDҴEw4d,Lw%Aǀe.o-`/ۿWm;G#<0㛆e/x?Nz!N WhR!UB|3 wV5*|O^.r) isMpxycmvÞb;V޹#k&p:w'n#W KQe2]/UquQz@i8ˆw--^1!t)Cڻ=_%[*٫k1W׋Yp_n/Y"FS~dm oQ#4ުĿW߼j ~ddVeSuYF]ġ7*DBnoJ0lt "wȸ@5lTbEw%K&&`-ľN*/\$uQq5ʸF7jtF@zPf[{٘dQJ `}Gw #>(;A,[U.s}Kh1;<t;,V5Gz07Tlʎp N'aԘb$ca+-X<_H1lSp.}ݣ+]{ 2Ev럻ץ˶Cj f\p60"b3YvqEkޙfVxs6@ՑQky_ӧ?8h$o@{m>KumWtk߱;Vs5`x;?UpѠCeX^߶n|1|L+IݮV ptrS=^?L8oV\_(Ի- ߩ}»/\y8D؆H9|//.g a0b/LlFR*5/+:VpL5&A\%zm`|Í}xC5Og;4N|' f,}X,Mꈝ0_zޚVI {qsِOk;EC'ӗ]{:$ڧϯ *cR;R4p]G}#Rn=22\iy13?`w _ց4b͛U(*$}ѺqU52nI5'C@]Ld*ڦdMEiрUnP&#]qzB֩5 Ln=8PN)7s"uz?]t72'Y){OD$S^}L1-)6 j KlmD.Iw)<K]ȼ8˘(/J<Ls9tR.'fn DžӝnΞ)0;{x6f?\)c yh~DoDKwhu_P>* ɵ|$+#&o/;䗲;9+ ӗ42ğtfo7.Xo› bywobB$1!K20aXLu"&HFlvI~|C C7ϲ E5&1 40n'>rB`$&/8ym8 wzNpqYeNq:=;ŶOȫwZ {1;nʭi^)[\؟wO:OVV5{oacr|;V?Я>aiNs6W5"&@5o#4P;ȕMnK0= Ve`,ql=mïm@ѵMZ= tAO1~oPKSFdguidata/disthelpers/__init__.pymN0E{݂ L 4{&H6Yw+k4Thr"֙\dqeTH= iE/\u,ja4l`rK.&X/?}-1ZJ: 3B(#F[u+Ke;{{)u~ś;6槡Uã\͛Re]Y:2C-PKSF_H#guidata/gettext_helpers/__init__.pym 0 D3?!:Bgk2 u qB @9X]RuP]B ,5ljor%42G95\}3C_&JN3!>fm5[_)D1PKSFAe36guidata/config/__init__.pyMj1{=:E"p8qr^6YXH"o݅Ya%\3HS,S Y]>N>?NlwBO3j L-PWGoa&å?Œz9#孱%+gU[ 'U,CʊȸbrXʇkYHڥ-Mc(>zZJ<~PKSF*+guidata/utils/__init__.py}n0 ~ v/촶Cm=M'B%QӏrLF~5g=\f]HOElq*v,' tO]tNЇP,k@)h3vM*ޙ&{ZF-&);z<͜ 9jK{;5^ۛ_E&f/h2߶ k{yEW×+}^V]'%ݱ|PKSF0kguidata/hdf5io/__init__.pyJ1yۣȂ+v{[gZ@U[+՛|/n~?_og8ʮkܴвMH{Ңy.ҬCƴ/ul|W:ƊN0jkI'\/`-?-]忨Eޜ)s#Rk~F" UN&Nd,[!9DߵW>U78"/BԳeeӯw¯=/ 7/+2g /E4Z+Ѳ^ Dâ=@WؼĆ0{&Om6Uc4\մ3!u 󩆁' #`WpCL_Pt@HKX0hw\U78ƘT٘Pp^yזEE]ݴ*g-J#iS/$ +_aytoϫ }2$ 7Y: w99z^MY@a|L I~3M0XCm^M֟c/vy8ti^ly#qɗXvЬ+K͚ ~+Vvo5VזA[8&AmX4+7trJ -Wؔ C phܠx|DdzߝNCӚgYL_/{T̆444 v6Nx -PuB=Rbg"@?d(]ݴ|ϫ|טaWcA3|yN}qRQuo[J'4^ji&1WU9faڸ*QFnsK C'X!v92X-ey]Z[6#ex-`o -T%Iv/E,UM>#0eHeajy@x6!)z1; R Zy40m\_؟dO%¶-xۏGּKȺ ~V2Hi^T>3f*BdnP`QWk 1<8l{o'v+~vx܀X/.&q[*f˯^M+\iV-ejnTSP$XIz̳VF+r]?<=~\Զ|oBEl*Y2w3Ń+sxf?7boy>9*?ԞvЭE[AϜg݁.om @;6ߚ{ doo8T]'~o]:͎jnpy=nSe\5{H-_Q3>KT\yP4;=dਾT2a5C^X]n}޹f9[UԂ"ڰ<@?*zn0.I d4"-#ӳi2M.iVu-yd5#OIXϽ@2cfW]h򆸕yg:;~P]ۺڑ^d5mnsaDϕ8RM*_T;[Q\kvy  9 eP֖ G0J :*@Wy+.%́jNu0\5!eARܯU'e׵־"y6v%1_Ȅ>ennd`}Y䛇U~ҨG#\xbP9ݔY24\`' zE 3xa7 B$+ b^HI@g1 "9hZuBhP۟l8&+%a `US/ct`(ӭY-Z0^<"5Lp `-hN]WQ}{،_eX+ ^^2apMmӨy$h iw"]͖_M_q(g keAOK- 2_75&5]p%C@[[m k:RHPJ=*y,Sﱾb :<6RlLرt]kZWq֐ѰĠ:KWw.׮1~+!R΍4 hPHD~:9[-xE,5*4]80iҮ3p(| 2(ksgߍ=~PwW}si,&0+8ǽQHgj _p7iTai`f%0Zңp6d-1vM{Q2H9Uʿ fwPƌӗ ƛ˸&9憻oe+~:;ڽE-H=ƫAHvmݒs] C UJn@94GSI?Q0sC[1GOP_3W!;'oW_+>a"Aɘ)$j˺hZZ5yV>?'`r^⹆[wK:H01Dz A‰>I'Hrb>'Fpb!'&qfO\ :WN|竢^uv^wv-ѨߓrEn@  N|;7u؉ι[S0_G=';&LL\lDP |L NvuM&fUS~/+p }^OilͥGiV.* \t >z~H}CIV3 forh?JND,> _EL>DI? 6eN""d`&+a,jMsaA4AYx)Y@{ƵAhvY{Qv֭K:b_EFջlIa:7rI>DKA?|W";M^ji^:p8%DiJBhF2չi?½āѕ*&q:ͭUJE=NW`RK6ц(!駉lz-:x4A8&aCL-"DvDIŔL)W I8RX% e42d@Q pi 7k+X*٫\GO#7TD Bڅ)GXt}QIH浭~DSrԨid&]Q/C H"ȣ~֤_tGMbR]J#.6($嫐bډ8߀%QGû~@-bHW~TO?&FTE`ŸoEidQ0-Wv5JZZMV$|>Wt20n^N{~̮"+6^>U>;APtϋmjJdhlJD߁ޜHT_wc y( ЬصwZ5;qu;542'Kx3(\Yp 9G3Up `P# *(mNFc' zi3Ź˱2^~>ϵceK/SXzj/pRDzj/etgRL[$n,^qeKL{)&qi-S{),^J4ӌJ4™2CLyҪq '8ŔɌMeHbg<gWs%f_bi7u:6]g\WM"fڃ]_bo*19"}ۏ8~e.17{*rJv@ZԞCj0AN>'ڔЈqm {,.^L]A/麨;% (6Hb 5J*e[>.7ԡF7(PusdvwFg3պ!23};˔@>jC##W_=x@|ߋ%1c8"}>UW|d5Ȉ鼅-b>ۼV[QRGH03\GȔWBJ"P 0R "0%"¹_(!TyR qϯ|_U/VB܏(up( vi&C#}CYJeM }q,Ԃ ;^*~3K#9UpzBM1 I{+1VzCq/d4nL|#RdCNe]ջB>Ƴ4~{;̶NNC/{Fw(ѼsdI?yz4Zߗۊy4eOT s.2 @@%eZ3BѢ0TZ+}M^^)%,t}+>0؆s8\-٪I닗KvxI(٫Iy7*SٗEئDar yQ>TB`enѽE[금P'9AS][6Hu>8ChV,ےiy=D2ܛ ؼpqi]Q'"bWFL*NqR/>tRmR%[ <hgq½EPT M1U}?2#c*w{6uN"’@?,?Q7Oꏂn1=hQ2 zB*]+vש5rħ3nI{eѧ'O[P^_Zd^63O6 |n"Ae|?1? f?hgNV=;jQE%jy'J#z)bl< dEWH-+?b =cVt(m崤vm6RI|y_{5v^<7P΢N(<au]gB]_LNdug79YsAcPٗy98}ۼ$L;<΁nh|>B Fj> uܾB*`lx{w%bfg,LfS4R5zWb5>@ѩ-ݝNꅔbg]]V&pCxž4-30bpup4@ awV9ޞ3N_tm+8l M\W#( 8F0pķ)Egϙ;wB.(<M}=O@SH z<_p}7Z2] *;8n~y3z|;_|;ݻSM/|W2z'R;J}Gu|p2'˰ 7UxW 0rP(|$}UJ8 ϝ 5Ïfow\ܳ8B&ԣOЯT s$']݌/>QLS3\w5l urwE b|ǜ84*~Ý~O\s}m|uE 2KhݏI6DurALWY.uqs%1'4;nsJEc2h``!=]ͣ)LMC[NJXe(@cYmwߗSf|Y^Dv/44f_+AdӋ1w^5*.F 4tγ2ֽʴ{&w}ER 5mDcR2oVw__.Yˢ 8aB6`@Od9qT|t#Hҷt?T#Yp_蹃,/ȁ!NkP, k7ƬAָ[x o5XZ[))0Fe1:1h7Uc|C~Ũ>GE|eKdd=.TaE{S&[}T_H5bwP?wf^whp[A =4<8 /aD Kť~3_^=OW#ZwKoߗ{+ԧMMA 4KzFX3.[b#=6?!w /=Kgb K9J Hh^'ƙxm-.ŝLWȀ ^2_:@9M'|K󸻥dZ2^iyW(Ixv ==MxcE'p5@hQv㱒-K߰?@aQOڵs0-kƏtO(Zꛆβz3`g+,XDn=|pzfY2@L<M|jdBL|'?,s=C- R=#O>IDvE%Y 7{ ǤGpZQ ":}w)*vēA#-.gcUl$Ѳ_f"E!g@Z֬u9;VZ%\*EM|Qhٹ x2 u,/\Ĥ19>YU\V_ fc 28sZJlzK|szaQbÂs+A /&qIDp?qMMaQi/s8Ȉ$øXP<#oQ+Md'QBS sAq\{ۺ@Ya/l=ryO=>ɠI/ޯRcQyۛӜ>Go&o_V(_ҭP_2AimOY'dr/{t6k`MG0^r~vquv9/.P̺! 9$p1ȞC ff>k=#9NkVqu*<.9l,o8*znj{|CG=fo54ia| _gli=GF_2-^v`ELJz^s%.ѻ0ӄ~h|cji=ñ0ad ߟ9z"'{\4%xue`o#R2}im*K[0bIY? .6[ua;-[`m"Ƕ,PKSFj&.E2fguidata/qthelpers/__init__.py}[s8{ s&BkӾ-&r"ey:31eHٍVChjTMۏmYZyF]~խ{rwr3D|Yb7$w>oi}`y_+/ms?5??}Rr}LV}0y-ޟz3nۼ'w#~oV*kWw,?hwdSsp%B\b_rhЫeЖM[@&@l~P}ӼyQWڏb<\]å"Kc =ʉ#?4]_|h-uqv(UPEQ^/C[v \ 6hl4 ˦]\C73(xUPUeQEK P%,U_k7f6 Kj#޽;_U_2l:m~{og۲ڸࢀM4_D7뗺iۼ{ /HTf+UD$eGG!"߱fqw,CėF< ;Kj2oHH% S2~2\p~QB\7e^ j)pr~36R"3~ƦAxŦA?E&h_kS^ܟ'DI3>6[ , `iX3+fiP7T8rV0K#Dʟ!X,K/yj7E[!/¿_kgn-;Lh5 hOj>пURSiF7Bs^y<\?r$6߉sEe~*g;+T.ʊfr}!$Y]i?C)M F3_lw\GhM{"ӓ"ۢ>ip趧4F$`v:kvO)H4G7od&Y&%N)=*[(Ƕ:#ܸRG[OuHn9Z;}YSc",˾*蕌)MSJd]ٶX{IHA16aWC^/$3s\|u)z]F\:ډ@'>bO"?CLE!bmpd Nt~q@B<6͍~u/d6FHd3#/mhM637++6/ϣ_G Qt8# o>AC@{HQsMg#'쇧=Q%\+9nA*| $@eۡ}ݦd1$V簑i˿ }|x_=o19ve{: Ȇ=QL)Ŏ#A-^ 4O mYc3 a7솠xLnDG#v.3tXgk˜AȓfG k/qI?qdk "x ydR;5m]h`LqOdrmY%(EXѫ ዟk7JGfMzq] ~TaYSPzSj/:a)u Q}]i .wjy}#质|%9P6`IY{&I/ *+[8g.SD~*4}Ϟ{C-x&CYdkh87xLƟHHz+f[iNC֋~z ecRr:_e0rQ0PĚ[6} |jf,:K}p`bXcn\|ܻu0osWsdtHҞ1| 06I!v&iоLF_yi- ^f4&pd<3jX\f sv[;o'M 2p(S3h=vKџppN*͕,vMХ0 i'gyY^.ʋ;M;ZH}vyUӆם9vT{Cjxx>QU.+h*0a3eW(O/=ľбEx~J釃WW~ 2gO83=~vh;j _%HW6Εl0L` ~{dN0vYXc"G]~X׷͡+Ϊ|D?7'[lr`lqE$ޣC2H.ˢ=?ˠ dgW# tM4Egu l##d?> ѝUjT6 lk!މ4 {Zr%>lGHX; x6$ bw4-_B`<]6ޙ>##z dj l`ӫFF<`mI8n8ZB # Vd⽓(d|E P i\~6Q+q4@6;ci }Ņ_ ޸_߸_|.Vy_,n·* ׳Qbu8+ 2 ³ֳcA15N#X<D ,G`߾ĬeOCgR#NwM=z jYrad8TܹGab4'1ynڜJu6;ƹW +.T`d9=BM{'Gn g@~}}s<ĂY=rY8~슼#[k~ZGp(Dna~ W,b G‘bdCb6ŀى7 uK`ܧҼ + QW! s' `#c #,.V-Iq+/<3g[0sn-!/juZ+E ݧV_qؚb:Ү*rtlu<;bq).>m~%O4d% a; Bsgrhfg U#8]cVj숃[ K-ZLL-_ 6, 8J1 =%_oų,rƏvgG |l uO[Ik֥sj p; Nÿ[2 y4@CCmoXb1Vȵ$CbYn#[3N2@nWCf(⽻/V7Y4xl/@sݓPq7ZTCɀ颪}Wv7Zx"u83 nT}ؼLiŶy3'SE+9U '5$Ixܺϓ^a괨7h ˊ)+WQԢh)+u\!PőPqC/UBUq]avp={ 7#,+ؽ-zV Ow[XlPq>5yY8ˊCyb6ln^s$7 #0CG`O_ƞ} wNSnrWf3u>I֌irLztoNSE\MtV|V Nk;R*ZБWk+f4& pBafG`~:;;d|uT`_X ?| [\݁菢3d*mSlX^5~B'mV T 4uٹtO=GTģ^)uQ4sǸTL2by-I E0C J0үF^JdCpsx-+#ȲypD(^28 'O$}:{EQLYL&t/Z潖iIѾin= Ro $Y[a(c`Ks}7yy[sa2?#,F`<Ԉ@nF!4$LC4#Bh'a}i=aUY%u\\opm][rzHL&YFȞ7hhL^`&Ә-Dʖ^@zd!Mh苝SUi'xxY12ˢ`d6e84+URD8-,xT;Ȁc>3=SxG Kco`13+=O'ETIb>28>";Qا(P_$]I4~pySr S_pר#b*_nvۿs7?[>,CZ[׍|}wӞgHQ~RrV :B׵-cCv\E'^=+*;Kʠ G5V-ߟmʹ)?TRݱ*ud̡NNDfrbn -u}†frGu]b& vr`U4Ek59nmn=/0,) UpB.=ƿHr3^>xީ 4TD#iҜ+%*jY|~I=F#n83:{vD,/d!"[&jWbɌvc@%zmZ^$x,,G ?=K[Z˙N?zOn]`{ߐ*[HbfTg~y^ޚJ9ozi^3ca{Ii͛ _7Mr{9,= LRb%BK -5Z&hѦB2o 5 2΋8kagG aDiE֟'~Λ(JrM)[ayC$_Cg i20~n}g}(/#% T.$;aWxAeC-ܗv } zcdQ+z){A$~;j`а7 tO)^,W8zvӸY|į@5}C_"(q2D q5j1$EI" Ϣz37ŊrJ()#W!9bgES>S:(C+iES%/!g<[R[SZpFw:oc˭_x}xC2WxHG وra2Zxx[ e|6p2M|@+$:׼'Ne>잫k'ee:c-gSSB6K=N^ZJ(Lb$Q8^<,ʦJ޹qv6T.݋s~6Y3cA!qh[9eya%/W@ }s㽤pVFO\uؔvZgX{p0 dYQns7푅nn͟ly!-=n(>H,ևJ679!ij7YMu9ͅ>Ӏ.'Y<ሲJ4Vxv&(WU4>-tuqPә^fS:rh:WM*<82s&B80\\F&HbH"!΁Ys;'iV`eh8!C7t`Ө$:, Kxbg>Ӷ:#4ld|,0Tts$RQ7bATk"TzP+/(ZkRHL}6_PӎsP{QE+4nU%b D&>׭ 6z7V체z`C,M6,b2)Uoï# G[@'>40a,M쑒"mOښ1X8:n|zFM'$ #L~V}ȀyOt~#5 ̀$&05 0 –d܀-4 l a; qU6P_vql n(Deky7͋7Su,ᰘ~*6 KM l_ sy׽U]E[3hh!y@jh:!9Q<%Ja#>ŻP8mQH; V`7򨿞ZMP]W/?:b%$5bឞM>bUql 8wz- о M-0ѕßvf+}FF7E޽klJ$Au9%>8$\=ĆE݁;ұO~\+ٛ:E^gJ/z(2:4f.M1O}SipfnMMо8K><$( y+0Y餴+̗}ę)=w"W^5^3rF=7ȟQˏ#| ج:Tb|"`&x);-Ecd5zmO~ YT֍n;N|3[E\푞zW;A29S*eoC/'.7OspG-X祏/Jſ|n5)Fq"黈gDgpx,/Qx>43{ cy.O^ ΠG)lIBŽ bRۋ%$חۓů޽}(|/% 4LD ŧ)gma!H7o5ѹ8e3 ڿgmDs_ԛձΫw#Qz>2cLBwS\p@ nwb~w 5Q> . />a>f r$K3+2+(]NGr=4r݌Igi ! F*uE |ٴ[SRգ>_!,gΆOg䧱k1?iv݈L' i$Dx("]3H%h@aMo#$*@7 C'\EϝY:؄WhR*!{x׿ڮQ.=6 oWN?xyi1͞aMLL0z`ax]<1ZW#\qFYBnāLF*>& yqN[WVr~apE}fflYcqElTf|ـ)w~G|fuDWKmoחQp_n;D "[qp@(+"Ͷ(4y醣_r}rRU:LJ22Θ vSB$BkZ0[a4 ݣB94U <{cH{TY`)#Z_ٔh.uff9trt%mL#w,kq=%ɏr`2[/QV SXw- 7P%QfA-W?7WM~غ$fdM)B-u9ӸR0T m@>-"N[@`w V@>FRd( C,AzڭskaL9daSH ޅ~࣬|E׫,|>t`#͛W?um&߂ ;w -t3x1:޻8bܢyRQ,n$8 Tf4fj.ˁ#[|n4,ڎ JF?FdGD>?6"0Ώ<"FV-0uux)SªObtgke,h$o[AoV%;XغC]Yy%-\Wبmo#rvS6!/eK^cˈp"UFh0b-o&"5젆q;odٮɌ:0YCϠ"y~;;{S4q+NiiR{|:@'Hb$oSeQۼ[ `p!t2֟,¼\0ITjO鐢1WU. OtK`;<9dcA`G2-) .xiAo2ȝ"I=97QtSM^n(rnO3tsv䍳}x"}зxܜ,r3w̹9u.f ք oM%M[:`#xlUsxيW($nltGe'5+#ޤ" ^ ȣ'+[ޖ0dY4zf&|+N?4(DF-뜩9OlEOUq CG nMHƒ;h& @\eTڴߣ,qW8- ^ ʋg /3%A;2ztN_fHnj< In͘oQX<)$S|+F5Qz5۷4hlI>e%aIN?,U}~, ;hI*9C* 3cL+8&#q9*_I/LZ?/;F(ʒ"9g'zo-R8:IgG}tPcRJXֻiu309^sKɾ yN khXO~;0qˏ?$TQ AN8َh|{AM޾K ?DaCBuͪI4~ڈc/f{]1=|zgB@ |d}ۖz]?پXYPKSFDE\guidata/qt/__init__.py} 1E|E AqZd"hLމ+h9wM]Zw"Q[vu-{40vĝ -OQrŒ W:d'SfDjW<1s1DA]m?c6DjORqQJnqL.-c@B:B~O'PKSFF9uhguidata/qt/compat/__init__.py}RMs0WjҦ3=@'pFc/ֲ֑+#SCr1='m ձ۝"ƺ!Ơv!h۝)b e-֛t([TTTMfgtvHFu/ JB~u Wi/tj@Z^hV2[:agQ :8jXl`{VEGtwL$gA*im7ti_u(se&7'@xw"VɉDՃMx{oVmPW7b凅tkinHSF%tK:7Ugl_Dm cީL;0P|kVh20 >}y f}i^O8 ' ;2,J8<4afǤI>l-fRAyƼ&2z3O7V%1p>PKSFsEiguidata/qt/QtCore/__init__.py}r軿oga&/7>hfEQ"!Z*v-鯿 )L='BDaGnH$bzxxjtt)ʺ)Ӽh>"DY3<\AfwGˣ'Ї8B=}'GM >Ơˣ;nӋGfӏi%a+CäY~JEȚjr6LJQcV{SMVrT"2n Z"aMϙ-.έwoSQ<(O/ʟB'{豊ӋmQwESy'+7u ,֛Uq!'eZ$jߧYF̋oIy8Oꝏϛ?XWi']UŒWyN^!ur iI_vܹeZ^+XIЋ 8o />d؏`Za-.[|Kjs,NVI sIvݬ]y[yZ7nqܤYܠk+=dgP]5]U))֡ml6!k"nʬ;ڣ0(`ZrA84m!N0=tdᅧhPv;}lw,ͭ+w a&@D2W:$X^[aޠ?FZu#5Jg;ꍇ1vSX\ Lg@Rp0QVó|mOFVuU,XCȄ-K,@[b;. {ciwdpEFQ(j۸7۸pQ1L6Гh{]aAOfj'H抅~V?sZ' 5K38&VϪ_J/ޞ>*m~q<=j#o )g[m'$i RY _R+A:G0NE5/XJ] >)JJ $Íxc瓴gKA{8z1{kÏ:c@buD\}w?ϝH_[Ȩa؁Fw>^[E(Z=P^؝ ~?ֻ^/^u2mynu6%=pԢ߾;}x4RE@6 B'kX `nHLE*gB?TV+ֆߗ^;Â:BsHG>^aJj$#ݞ SJ?/ϊizOE>$sv* [,+P{XuRiq\?V$ DA|z%H2ũC}`֧PV' xfj)+` w_07ǿ@s,5J0sH*>p]1@׼1:tTfeicdD ,jg[4\6N`映"<'v4!Yه?ӢԾ`+kh\&Of eK# l^ի*P3a :fC͠r"{8r$ç! AmbA"|}5 2<r'~Qc㿂ʯ6[Ŝ4[Z}@#7}Lޞ:nBBil \Ft_-XCa!G *_ gP61t ЗA:7Lt>}-!O]~} 8FncM" 5@^&ۢYen IǏc4_HX!EV,& ' #:"4K7,͢ĴxA am,@^_! @ $)88.]BBPs\P6$,p mӹ|#,,G}nWɘ\YofB͏UmB;%Mu&MS~SUbPyA]"2y:2!hxh|DzΫ.`!Y(:Ɲ^w}lh&@ioP ޷{oMiXB<Ḁ E[w{B;X*_U5yMڴBYұ#A6x"ֆPҨp-T ի#[X:*CNA1/8_KH5ғ1CIېwv t]KR4$p<&f|@b:f`a!7u #!4 Dg}½xτBE2 WavԳ΀,\:z. NRLaS4PH<\Hط#$𭊲7,@@@*#y^ +g BH^DChΨn+7V3 f)K8{,Bִ;%}O P:#9 h3%D-#3HȎ^Pmys|uJЙ,Q*w X]r=#QLx 嫄CӠFkXpL&=usky;l5L @ $Fb =  Dv eZXR_u⫸?ɼLE q_?95xrDp!./_xŒ9'PKZ@ttZiϏuj "MԠ<<&5&HFR/5^mBf(%z 0JtDWd@JDD_KJ aQjR(5a:fSˁBo "!;:O@r%;y8@j"Ɋ܃;QHk4;K*Фd䭘4L]%|m|sS/JXi/+A}w8x{|ң΋e$4Lq*H&p)yȱ%p9f%8Cdv1qS5V.pu|m I_ѡ[!dA[Yr9 V,ZBi@.NQ}2u&try\ȹw*shUmﶍwƻmݶnxm6>6mﶍY~ t`O)94UM_"dChI9_i?!%GV4%+[̖2X;>Z#aHi.m6 p_6'_Yu&(9뤜?=&@{l,|K6} 5xTST3;Fc4.ԣ4\[P6Z}Z5$QkԺv`)4ruR:1I)DT+?Nx Z%R2Iq~I?1`?(AJCB95Ijۏ] )PmN.ӆW'u 4Aa'/$0BcHRɢr " 'W {RH9ZS\:nf<($w > R,}R f'WpW!ۉ˩ׄc&/OM=M:QjIZ]% >I,_h!LNj12$TI@}dDr/H6UM :O*$+g8No]V`5RF:5 6 6peAtМXܸ\eb ·7ua[!Rt6cFXP׋29ȊJ7ٱ̀WZ6C9qZvp*#NJ9>*J Ѱ/m1I1/+'#+NNG G>Wp(54|@U<\L!#^'e}u0$Ycl,ʨb.ℍ.Qʓm ! T7_D0t8qH'i2/swDㅃVE^`9tr ZqE^܊( -ӿR49#`:y\O:S&xqqLJyT5(5}j$yRsHU;˦Ih# h>tROc @jx #BYdD^ņT?:{-r&D\Γ_ty `Ufk[hGݳ$1:G9HYi&&t&WLsdPO.Ah¿KAdUDmO:ѠJp{^ yJ?#lWxjSS,Zp-[?N|JRSTF?%I*Ltr-/$}r{U:J1`[`5%ydHsAd$S3 ɰO&>dD[2PP~ 2S HTU Ҁ@^rf.Nk:WdYEHǒO.J.27/DQuLMUuR},jo 30GH+ƚbDED](/(?E%VMoE#H% LM/? cZ 4$C3DabJ9Tp| >O-57A]?@2}dž0E0}@ 6W>)Zj4mRv(FG5u91޸,3obWM`%פJQrƀBŴ/j";&6n?WAP`hldRF ѝVIwypcK/#cxUTj9Q4z4.ԅq}`xILA][)*g2˴^5bB`"\/,E4/W&t gsu2}hJ:kafJmdNC )(U+W3oR]Y&I@93v[b+kJfcC^m{nµRҘLhH%掖l5A"b . 1b ³Eua>O0 G$] ˠ;YmuD* d6\`I\.QL]0gotC)%EPS*ETdϦA zup.fD$X%SOA$sןHW'b1I8.41zl C!J0υ>}3̔H8I\ft 𣏄|OvԕK܃c8ے.+IS/9YY|ҎPC Dd?Rۢt#lDx"#t\aKכL+"t\UXgu$t;nHHЧm"y$I3X̃hDڶ Q  ~.?.v--Ԯ+tk~Ns`nP.^)+ %:^-o:—Aki-C0\6"P{컬RF5JRh&yԞyœ$?IkvjyW'PRPvԡ/ҹ3DMMÑ r^a|@$H0M݄Db@/;@;|x wISL詥﫢ZIQ i .?e͓3kF.i&:' D4N86QVMWD?긆f/Z+WuHq7vH/7SE r=)rkD a8O0r '4o%tJ,ms#d˴.,c m}Ԉ%HjrC443r.AZ̩\z5Sxmy[+뗋5s|v)^s'ډVK|NJ6;&LXFR$1 E_xL"WZg}-Jٗ; )_niǮOQ[". 3~gT脤|s|c ͩw-&CRht&CCz<7KMĊ> 4]5]|ɮt4:T(9-ܗdx)<¤%tE̙A%,>iYVن$&['61N_ e=EZy CʷI t/4>P9ؓ]c}agUdI急o~@uߘ $';͢f ϱ{]x'%l$(Gb~ zJ$#7QsdH\b]߿)? ^ΤmG@4AR7EѭB[2mgKZOU 8U \6A$~FK\T>o َȚVȷwTJ?<&-|Φ['-s?i5;-xlv`Pxr0]VИp^*{$Y0:K0dptZ464Pr咣=B&=A|]C'6{5 E~?']8_H;uyG_J|;4 N]7?g'b|{w7噻y+FdF^,GpPy]{jS\]rX0,B@Ƿ0x=(gAk p]brq[(Ӯs {TN愘7|bc:5C$UAْAUI/r~пB f{9宫iC-AY~V)sOo4-޷L+Jr~X7b]&/`B ؞7; ZmqEF@%GE0]F?'J|`@Nn5cyd٘Ekf -{􍽁sήw|p$4Gp/] dv$JN< kƙe5JtK! xkc dl`fwnI"qnN;p_hϑ6gtlI_,(4`//rA &Pxd_$G9!B `73-i/ -QJY8LAw;0e A1->/ r2+v7U9 'o %0Y (*}"@mOE:E;* 3}@8k\ADC<n}Ѕ S9r `Ա“=6}gHx?,p 7.AJ]єx<[I mxFi0ne | Nޔ&x{2B=$Uՙ&*%c=:#dNOQJP,ɇ*"G-P*J@qbGk5> dVݣ5;H[Af&𪩫-j+80*t>M+з|y&>' |u9ti. ng4"Ʈo&g ™ we@!ZH``*yuA8Ua}H _$!%>Bb5` h>ڑdD4PiP9LYZOYa'a77k}Eo_O<2ϼh`*+euq\٣ܝ|z @~T|1_Lqd ²O7 P 5i* PL2*uӠ|,|Z#favuo *ǽ췂|K@p<,ɟ D[taI_ˆ6P89Վj=xj% ,/7$4jE̖{7֝fwX@7r+ly'3صT&cMB,|9LmF'G "X6LnM 88zJ6 EЂf{l?]+H!AS:&xń`A74?Ya?aV !{'B RHn ,}$`5!QG8"B`uHuzWX x1F&!yw wż?W$N[3Y3@P/ҧ'mVѼGDŨP{84 er@Da eV=I-fkWt&Jv'|*癯N.g#Jr ""q]X(}M:at#JD﹠Fǝ#=gx }Jtwy]^I9M4ף랇dr.@GoU(˴GQ3 YwxaB `LuXdawDU^iu"\4EJzrgõT\iuaiM*-7WM|!j\q ~hvHTePa;˅vLGb<ey p+SI}uhp$J=ޞ}$«[ݒј x'p ^K$1o{ &-}aK3cbԒ̘$.3&&-q!mQ2vUrެ2GQL'ZbqzO 뷭E8 BEe)3:0?D=w#c(* w޳6EKWvVP9%:353`sX=izBӒs@*Ѓ5zOv)hbjiqg|o -~cLBARam\{<4EwlYY[<A{!BwJlmP:;#Ɔ`\UEQY7{N:3}é8k\]ʣ%t "{6Ԗaw̟O:1XO|)A:ZT╷6gQ# E9bwǾMtܜ́UBr8,s1,2J/.9dM뵽;&ӗK`1~{ ﬈q_*cN&4 P\GCӛϡK%Gt-l$',=ZI.^ڃw5,}\I;IJyG8UzI.:iN$QMQ'5o'FKh/:(D]%p(f utKZ=^-jc\~T׃&ϯg$u|4W!3x=(1UnrymQπ>z=#^]˱{9^v}/qw}/'ˮyҸo=Kc=K=Kc=_ė{iy4sDs #~,jCa^FzyK}c3笞L`-1-6zNTAѺ$u}‡i$2}Jd)_yX+i QU5} Ϟ;n7 n2u%|Yu×u/b]|YOJo5[K\%1%wqN}/D0axwB댑Flb?_\&yzyFc)wcؚ~4|egD#=[yD\G#b1~y B=b!&1G#➟1{~q<"G=B܏O*I3?WGWN^c}8 3C qy]6e `˫xRkzd`lJj빊ԓD41 f$Ե+G!E=ngfFN}ϞśӺ?Q3R޸]fGLIǡ񟯽lmOy;/cor2ږP׷2e<߹b*:ӳ31ߢCYBhe4jk֣!j"]$04檩(`ti( :~kJ ~{]UͿVSt* %n0njMMmD8ltBa1Nk&1Ɖoŕ+sF㺷-q$? 0~Ytm:$VZ|kc]k+e<])]K2\)Ӊ_V\%8w[7`28BEFHZ7 AO_ZrxL{+jwHw!LM:P(sO08fzsYxnMe[9wFٯO?R!oiWjhw@O(. Lk65;#d1*n ,)6yrB>\PN֛gi}r񉣃>'iƯ4kF^d}!Ƃ4մH mM;!CSH腭a]g_u6C3]Hvo^ݺ$h$" /Р ہ@ñ[Jsݚ5?Ek&sS@  "*! ! #Agr߹E'PXþ%wЁUh`ebč9/W7O?|oh҅>X_Ѕ(oUw9$ (툸ɋȠKԋmr@hE 4֓٘RrrNׅ,Ni, IhrR<%ݧaucp.)=~݀ϳds΀N4wMW9فGavӐt`L;%el`A4׿uTE|*!tx_+|q8Ki*CIW3B)X=coH|/ޭC+Ɩ0 5^'nj6"EIT/.}ѻzBtvf 9N0A*`@V7C_ [rYH$[#IH_BY+/7XL( 5Vb<[XX9@f`_5x?Q*6=c"ԫ= 0{n{h,]%2KkA4TyҀaio¾z};I,R#~Pteb%K/MJjY@ H#܉er/Iy@xd\"HA䎲 l27GS- l\r5cܝtQeF?JB1S@mZ'R)I̦@ofps V ajA*=7&p,IP XZ(RF0v&Mq5h$ u@Bӌws%NX](.Ұ %feP6l6TZl=M)ZAk'~Cmmkz gZ|.p1 YC/Hefp;7M# v~'NՀt{C*-<>6d걾/NJ@L]G SUp~,\D >ۀ '7gG''g kI FOP9G.Q٤S|]d fĊ7`0(oK| (;`i2 Ü֓3qr$z =\79*'C$ɑ'O<#}gnMwH-b37/9qRfEkC_y G#>0vBӁcPҋfRPqU"[Q픢:%pQhc´IEmkN૲Ytufbզ:sQ'jXd7f^їuǢ&JaL)љs/0>t DDoy$>8ї@3Ij!]&+%_GD 霱Rt;S.$ijMdH|1QT^df r #|@p]x~9)/}i`f2h&XH`ՠ72ȎY%WB}|]gJ7a/ԗ)hNHd`>7P!V'׋3C'5b'Y0Wezj)+AfT "`кR6I }1=2taORNK,A/&qx(kH$ZlyEma7޼QH8Bj9<"7vd@-&3DLnu >EmڳCَVudQ73iNf8jݖ5\ne-95G{V~K(v:o,VcɖtVp(ӛeu龦teBKk qd$Y E[Q"200̹C@ KXH#@EMm}] oͺcaږ$fDj,<ȠՁ%AG , @|=:yn$ y#0H_㝞(\$ee}y:Bkg},B 4U]!v,~j,.719*bHx|jwNh$Ym|!_9,N?Z9tΌze;<' A_M\~?DqOashBe;P*sB-q:{ 8ڞ׳??[i OB}@2ɬ=Ͱj'2 ?8~7&9>aَ`s,㕳sUnN^̯SM^@)*K^Xp26V~l mUnet X&~^;_{%Ôdm 1 xV+ .<4/ ]1ym0eڔ e 鬶1Ʊ.[ڊ).)&ˎs%Ϝgb9ߓ9UkDzW{wBU8m5JĹ#(!h1m:=;cW|Ў%ڤH`8Θ]brrbo!Z4B 4!RH%w7K Ҡwqs$ tlhx*Q7Zˍ:R *x!utpiD!J(J9ŕ,+4K#ǣ~CX=U4?0YGg =  چo=R 3?x%a6{jM1eP|Ϙ  Ot J wBDKXg +4=?aXRH98jih\יo TH[a6t,slY#/s6=p[#njse+6'ƿaѴx~-Uz:͗r O}ğ~7_„[.״ߋE'쾆 /5hԐV0#_$rR}a+N(ԄcМa ^['ʌw|P6FGݓ֖/ D|&o~eQV4-VLBFwB*<]h+S`- 1d(b}I72-:q@PTA^#޺,GH_{ A~#  _##.rC `{M<lF:gNꌹ[؂˖YV&:ֹ*:n;gbA@hɹ`3 \ۓ5]5ohRaOSn)Gޠ&P0Z=Ii~Qo?w 7tm#$H!^- ⳯mt}9MiMvZKeK)ЎyG5{%w/ݎyX0L54'?=+k({YqEqo8.Sh!3)#^](:IV9]#B)ҞrMfkH-XhOGx{޵ *?\V hH>\gBٗ a^R' 9*0zDt;L$P l;B#$H,;(C$nxu4۔oDuL8BFA|A8]m^C<8Cƴ]hI;n)sǠ"quGF;͌(Guf \#L #; ?me"MAKT0 *x5ck\[LԚk-uٿ{صZmU:/[ -Wm^{HVB؃fϢ>e>d~;ת_6ٶ.QY>ekusF s^ڶ*0NvzXmY7CvJ5=?w#| V{EwY箪r]=m2{TK*?ʛm??V }٪Q>ź +>VjWB":{,Z]dg kzs95_*|jvVEUK~zmUVp*F9_cc"'FD)_5UQ_:4ke֪lbҝoPS4'ǁ]j}GɠnԦ ,m#r[a So3 fW7Umꉦ4k,U)fȫm(2/$>ܯA'EؘOf_$]VU٪mp17k˖[ Y赵@0B~֜T]-f$Ea,&R.UKY[/v|_Կ^f́zkZs{Gx PIapUàFٜ7Uy_@nW 3rIdP_DE >%@SKr|PF5O R<\ liǩoͷsJFpn}xUZeVDf Qs&kc\\#0)o{:pקL!ă */uVO\yTQ߾e@V5:o/ Rqv cli,Q_TvBZ}Y77Ao^k%VF#KnQ $G͡Ew4vzvpPpZٶq IZNw1L+$+8vELIFMkUY'mkX&T5<ހT <.m3Glrȋ(vb]f yT=lyHש]z ~ro絶?e@33ݰo_6wH*_6v!0~]̗?&2e5*Y~_A|Y|?SŁo%rUe{jg L{xHIz-K0TύVfEPNu`[% Szʝs,4Zfs"'^ɴ Sc@E 4)qlJ I{B4FhhZ^Y7!(vF)o1CED<(kDHZ<(xQ|_ W` EaM/qVbiqO;S 󒀳塸9׿vcE:, #Q+ZM"_)i/I+ާ81¹۵a&cL6( Bncd:ءKӔ[m}vS9UwϜX|O\F$ h +wSB:z* LJj~935FEկfrMd#oF(T kQ84 T]0h!ifR2P_d'.ǒ Y-qZ [vӁz$n@Ph V € >] 67`àKyFk:3 a Rjm(]KaBrG AX+*85p( c9b[7jX;UCQJdFvz=z'܍}/~x2 CR խ͵Q(Fdy0c VMhkܦ75$Qk&  E(R"&Uˎ|#P7y^rUZ,~V곞{J} |Ϋ({6KOOٳTek%?)/+jg0.xfI">_'lBPÃo.8!B?!B?!B?!B?{!B?!^B?u x,hNEiY%+rqLT;xC%fuM&<Srݦ öma[wVj0$X{׀k"WI^7؎G\8h~'0-6PxЌBG"W$F6(VAMqn݅vhѭs8oJUR0di!< od6N1I4>)xFuE%8Sr7-Hy8 #ѥ_fhM[|!5h$exBr*wH,\!4؇q*C?b#s|wǖOL4cK@pٶpiLХL-YMy CGJLőO/=ȩ: erR UY]=r D.>iPK/;py4pN5%ݖ=Q䎻},(i;nԏqwr` [( AϹ#0=G"}$K-kIp7># āH0"lVu"xxGñS +n/+%eչObMVڛm &B s+al ]>ݩ&mв;MvQK f C¨-=F,ɵμm%ilpw{HCQ&gxj{ʖ=3q4҈xi^'hh.nt Lfҥ'>^mHhjc2zDDr񘭧9uq_w3t x4Eocqmmlb ..NJ6*.ZIoɌ=\HS벟])*se[9[t\]]q/Ўgqx-|X70wY&ђ^nZiȒ#6la-L$Ec*Nxw%go /#s\^M#K@:靨 ѐ.vZF >o$M:;񬃒w܁[x1o r ?Ù]VΙ/ t9zaL݃~faAsm9#ٴGhۮeZ:u ūm,(X6އ2^6¸,&Q*q4L|ct`KE""bZKCiے(kl1^6RpϠ0A.f}b>סOC >Rb uo_vwm*v*u'E}2y{8"oiؘ{S\mExBj텉]nN>ёZUu&wu:)7 s*aHw`FyZp&pKmiyqWsh=se׼,u}抝|SMȊg6_K,Lu}Pj{|?6XZ~.V7ȄYtAS 9b?!1]7E1I8&A'9vJ=ʛZv8'7AٓzRxIv*^rؚbp\ej8hŻy$3.M9Fo8D t|AĨ%|OQgrbU}'@Sr}v]7UOg*#M6B9l͞]=u1; oճo#7c4*c_҅D( Z?OekQWQGwIc!JcX\oQHí.CybE|âO.1w\f_r\l7HfQ:$W, Hqˡ>+ %[8kv2v+lՃg`yTϴSOqk[#E ;tM\p .$kBWO*#TxVZcŐ;P=<z%ɛFOn\ MG>YWőC@OHEEjL#:lv3gXg2/ {T Aޱ1مȚ'>?ֲK(q(RkVL,va~9f'#Y,,㩍!b^KD}O_RЌUE!{ UWɸKF%xh--ĹMd+t(P!Z!g$tgZGL{9lĩ2Vr=_7zUERc 8,Ƙ  wt >&oV7jσJuSEa'3i2;WS=zO%ᮮ8!cOf#EΉX~mS(m5v;CvIU s>-2^ēU 7B&:TP8ξE6;=b SIԡ#8t1wHDʝ}Ym<"֦\e~{~̂gMK, L݈ˉ~}?7J`8dNc0p0=tK #n }>m_}'k埬^AޘRP;\ .] Vـ!YUh-9-_A!j; p°O~=8Y(k3 ^j򮭖M.NEV€",c1PznfĢsQ\V,]휫Z]6v Z;Ӧ}ѝp{;l6-nppƯ|$hwQIː}>0e`?SRWKp7HR,b @xvKCb亍[m+m坞$vۢiwD~7 n_yy6pY-\D~22XWbcD0 J0Z2]SR4b0-ۊXNt-(AQX{/4ޝ8}7S[G4wcqN ALa(f$kHZs)BiȾ_iPVrČ[l…4F \&} \oWxk[КطSg+ j$Vt^^թy>J#I"IcϛКqrr&)B'_sӚK̤q%rQ-K&v՘/ t@  _gQf ΢ph %[\ !P'c= pn58`/ޙm' }v(kݨ%=׺)=oğO a[*p6@@wk+0`eպ.Ų׵vRg=Cb6$C<$C<$C<< 7<v|`;~/v{A`3>f|0`3>ƌ&|0 L`>{&|0ߋ \UWs:g}kk6LUE 35]+?PU#H%\ruNw3JǪxbIt `z u E-W~l_NuAnbɗloA1o% )rΫٻlK46lȕ{8m(B z;y_%Fyxm6+HὡUV%dGծC#`�-jUZH&ѢH֙[NuiQde5zW {fjkmz R*=s6hT[VKY'բls=0}yP#͆GOQ*#|"p5=Rt]%0 >Ovma7w Sz+Gɮ(,ibY~.+Khco[.+HaLlMr-5SV6KUХ#Ko2 4 *<9Zȸ΀WB3_#\d9QPtܒ!.cf: %cл}, Gq_ vwWI^kcM ysU>ޏC Sv˷$ĢZim)5k(m!*Kk-=}?\궀9#TR6H;|;<քﵤ`UQN0ToTgrAf&u^Њ$%+ǬιoTlfP+}v>P5 HIӗeD=PLAUxg.[ =Jd-xj+ :jïva0fW@7ۂ\W哮v]Ùn BwVG L3Oc6GYf@'IEf}U[j sG~E":~x,w顂߼l+Dbkw ]w_ =w谣,{LnJiBۢ._Ps~7CoSAB$w[aJ[LF8S~5NGJ;TSg+H8`#95@u ȓ"{l|րO9f?euAn^"Eؐɭݗ"}RY9Fڧ#362RIХMP{ݳ_3R=bR_ Y}noFDb*#!|\7 挼:o@ny{_$AAŌ{4qQe Д9; -\7TN n%=qj(X2yq醦=@{%hܺ]߯އWn*wcW95}E/W-i㄄iG |bȇ ăBIҁYq(nD}N&H>h;l &(lu K|6(t J'(t~\|wCdC>N4/C-襠^ z)_0ډRANP8A fS-cA=cPA=:xlqՖ/jWs+8)OP `E7J^h 7h.̦oֿ{^ 3\. a0e2LV<ͻ1?= wf;3Ý;3:4y0L`?p^Mlwi[>|-l`[><(`{>|=`{>ӞG `>}0A `=8}0A `>{}0ߩA%|=`{>;i>X}E,`>X=A0A `>^0A wgm@G#m 6Ghcxm Z$hE Z$hߠEdH\=d ʕv?qŕ >9T x7/z@n5 ^mvzd@L]kړ^my{t`/kJEotf t*ͮV,w_zcB8F Vg2xT}3 eVp_/R3_ƥKr_u(MD6b,#=4BxO<1srRZ/d7yrb,ZOxX $%q­kCoZΈصf^qFtwR y$MxiΈ]^crYKlkծ̯xS.ѰK4 D.K4 D.ѰK==L`>&|0 L`ݘUx06| l`>O6<;d64r/.alzx`CQ![B-o!x {[Bޓp\Soޠ`I>,/VsZUlzdѴ^^AoW_ V[|8HbNhӗWbDb&>'i'D>Ҝk3%+r u꼨ʊ؁/X_0PWMXZiO/-P1X6Dj3~_MywvuBCth^ܞwæ؀wpmf S;{x<\YYY_d;GKuAq]c#3tY'0*'s(k3Q.R@#5-,Skb=Avf:oݦ+q?k[>w#'34,D+~}[Qpeۚh2fHF"2GwPМKo#V3}uPɺ'W|W|W|W|W|׻|Y,`<`>f= Vovr[`pAJaŽvֹ MٚRp|pexTB$=:w^VUL%wz}xkZAzx;d2WCTY0Uff{QM,콇ST{@b{ӀoCL썉NY3\8М=ح`7G@hG3o|[Qp&xg2x!esł^;t ]>m=jv9h 1өlcMDW|:YyslF xխE"i&e,(k2A̻?'*T4۵%+ J(-WG?m{`V7ȇiqCB5A(%s$5;KGTh:h&IQ#=1a-N3.6^;\4ոX=YBқ.x|,sV׏4IId}iTp?zWWL`Jw{*k(o}\< 7. m^Eq ,je~Qat&BM z }x$ȼ?znIO *-2uCz`!_(W@21y.)iHm29r?jpA)۪̂1n+:$t;޳'o~ > hYQ-0]mG(3x_ ޟ;P~Rxe5XKƕP|_"ˠك,< ˃,o|Eu |]^Xq'PLCK:(ff<6~E諪W/x6$rjhءod|Q$ߤ"f-7kIYYki߸7bSկQ s^MZsJ[<)_E% KjF2!w57;=v69e4?&VئW3wC4bׂviOiS1lӹoY%Iljl}eL6.ĿMiOmVpُ8I"ͧ&7W Iyx[6l g3oVkaf'X*mO{#{4Ms:(tKRܡ7=A7ʗIqkT?d`&+{GI4e>"g |O+/o^}=m3k =zWJip;4iN om(̦3!7am8mS! x{~~"5f&11pCR%Ffvu%g\g8W荖6[) 0ba&p=2Pd,^+ ~bLjOVx[kQZƅ֎#m?%e76}{=}8UE?b1;bg!sT@k BD't4g ;3bGNۦSc˩*RI":_/lҍJ{vuG;|xD`tkCS4"A=ϿT'i~]meQMK5xhK( [N ٙ Q Q Q Q Q Q?}`=xwrCy<.)8DpTRe5&CX؈\F)-ʮ̍_#bU*[".˪5|7 8)Q.!n:_E%t"Ct:.v.N;Ê*CC۬~!$OKNP M74,bu AX7 ~MPAyX5+~mjiun؝Z;A̢\ >)|}ҫO9]7ZBOԫ tn>MU7U> vvZHj$i/q \%FCS$'R8'*;JbP@htq!LeʗQ2ǭQ-ϼ+V% Pk ̤k46G<77¹S5ݚmLH#՜AI]F@E"pk'HYtin=tdtP Y>+٩2eqH#B}9JooW !ܽETՒ+X]/"^bkiiU]m٦YcyٰFR W.'KmwH<~e.O&w04ܛN%ߒץ߈8k xW[>`#>Uϸ>3V|?_t[u1vj۾YmE 0&Ȯi 4<ĵ^?\0Jd%Im M96@>xskvj]}`:'m!)&Dv̤VL^dDs LE 4S&9w J|u]=j-%`nTS; LW&)m,_6bA:pY[D(]L QD1K|[n<2rYm,5 WpK^n۳ҩD.ƛ[Hg1".&ҦTDb&b1x+8k+nHA$ 08e$ E$\DTLd\az,P GJվ ?nѱBܻcCNJvx("8env&{"ڊbY$q\ו\wV; ʷ N"a ^Uć:{E_lF".ۛwy8qc]0zfufFMzԴo \V ):0XLXj=Fl/w'c.”ck׋LIʊ-F+ mGJSVipK;2-pyV97v_*" `kT_M*S9(o \B%\B%\B%\Be/\B%\K>&|0 L`~/&1mr> Kׁ(`JV'_.t_ٞy9~f@Y<,Ȑv[*:!zr3`fkٽ2Wesz=g:B2٦r[MG2Y1dgC5Au^~V.,zLwhZ1}s4,S0ާlݙRÜ~?,RoLAI9dUTrUsк_ݘY6b9%mRY6_!3tVTiZncx' ƲY5p桝\OwT= uΕϏ5+٢3_Ot/(a| "Lzg;xN}P \^6+|Z(8۲AI#!k8rQ N ء xYy5\ ,R|·Fu~rnhfYYpF<^qԅ/<"̬⧄7!?{&sy/@r$q%W4&pgӅe9bvҀp/1e0y>_ y9fO-ɐuI>Lw ȁT/Tj<O)y;s늢!V܎P+׈zkȃuWnKwjFo;cn _SVݭd)HL$ꕈ0Yĭ1Lq71|lf6DyO+aඣ;T{3j,ّ;}T"'=O<@ķcs2~Ofb2`= I,OL}Ag=+5j̑BTx{!M}2/ԝu1:VZ4PK{+)I&g!\JZMRPtЮ6zcCn- z9)΁ȅç>vt_Iw"`h&ۓn%iNg͂#McqlKV?f>e%Eq&Pp]6YѬdi%v-'u?s7%Dڅ9`{aU(ǩwJ~[Oo1O "8& s7 (3}2k갚̝Dl74ܯ/Xfd5Arzi06ȅ._t͍>[.I.|? 6~APp!Y:X;B!߳mXܙ$7$8L' M=m&簪l#88}F1x!0BbMkl]StiϴWZOV&&mߠxbB OW; R+٨D-VҹG[2cױú۱ʜpv٥~kE:b^<*1KdCE^p+*~m4[Dz4$Wd}ۛ\FKz-kײ#Kʎؠ/0mD\:aCcݝo3Ƨr&ײ{*dwwz'ua6ۈv8Ф:(x N؈wZ.70;e "rØ !3ìFrF!iж] aGu- \m{F>cxʼG0. +IDJ.M;(:X>k+.|%X~H-HnP:;Z ɉR 3udaL]vAS:iSo@{ewڼͼb uzоl1"U줥U2O*1dŃɲXÆ8rwyoKV;H9?2O]Y<0I':RWӁR\Ng}<=fa|B%  H {X+$nMu9u8oUw~<8n|g]%OzX\v*pI#zsyY8Ճ]|鼃ŀo]mKoP0wu ;hj>G :G}49<(&ķS^:$Z+GyRqW+&Hoӻ"/?'p*EH%gLM 7vj]gR9{1p%A"8QK y[ZLn*4Y i#\>)uvdsM'-퓪|zqFksΣGg8FE>nWOyldOOlGoHg?~z4 6]HР OekQWQGwI`Oc!JcX&oV mJuSEa'U2;W%aTJ=pn>a d"0%kl! gl1M^cH!b%af("a@/4w?-cEHW4#L:ȁ'qqevLsz0INpca#{@Fs610l}R Jk:6~]n'ڒ9GD)(CRZvegBLcc3\`TЬ899-huėk"4kL' 6p12ҩ˲l2v?T8NR_o$ĥs}@kpmyW6L^xGc;X.&Kx58S(=tӫ~lBȃy H\f0. =1ri5h/9v"r?vX:XKEHޙ݈X7/ؓ)SᜐsJ8Wy,;lD.k:oH~uRq7iMIYMxsS iu k -du?O 3}Y^cy; ]a~f0k<ĬfN8R40Ƥw2wWc!;cc| q;o2kQ1`VR^݂vdC `T/\ˠZaqU.V;Np?fhǯk@kSݥr{($ PɏY`as;!nk~Dc C04^y߱L 2ziHze|1_̛ae']& ^4~m Kê 毷jY5X5uWy߿}=_2=A̾2N=4ņVaᅅ'[x.<|{բlsYcp#R *+z8x`WښEpT鱩QVӣM8F=,N_ ^5Vi,]0r'q݄ ?P{9սiGY( DQmb9|mjbwUk`4=OKto^} nҽB|zOԫ~]u+iB:hWge>۵YD3 `Tї F[4 LDt*[-Rq`X7v6=[AoW4޿]YoLAp߹4f e\ xikf/ʗp( mˎj_L{~iw {HB'nVnK=vI\&Ugk1PNxncYՊ^kfm:~n0_d*g& .[C.wT ; ~zm`(yOт-lLn<Z'j,edAz]j̎[L`ؐ]520Y?F4Y+[3Ҡ65q9᭧Q~;d)h2eҜiC3 lSYS^ōhE(YNEwz .SxّdXQٶq IY;zpMezU֑P&Y񨮶"O~4\Y>{t`3T5Ŭ1Щύ"4'+!ޜKON3_X۪6]g*~?rc^ sP& C>5`dɠ姂{ݵ30mEF]eR&Jx]h=ezoyʶJ@`˥PchDl=j^ ƛMx@ z] aK˷4QA^yeCrxFYh ӾcoE{E fXLsfU[2FwuU?# r`IP:1r]yDOQcj\E,*A]kDhg"#!nJmM46TJ5HGUhDU Q0%2/B[JshπgAިQf E򣿦aF+m9ݙ|>ISpv-R?ERaVd\#^(%zt__#C]"T~U։S(6W6lGkVcY4ߺEd*fkBpڔFd17*A_bv0?Tj&a=`P-Ehu E VNsJv 0iDp4J ) \d'm.2VdSq6'*әv.lj%h $idNM Dqn,#b3oDTvL tWn0 r#=0cW jI\W9KA ә9L7l{,@O,)+Dkhl{Dhؙ(!6TzjoRf_cyT EVXCPĿr9Ll*ֿ9)phvyC;NVZdMqd`/0N;,h6gndW6Ś 5c '<3pX;Bʵ!~?Ze` 8 ˩`w^g/,O:EOMV Ն^$5զh $,j1aO'Z{!mTPk܉ *a.XuޮpFB )q-NÀ>:VT$k;#_6[T(B1Q},I140@YfFUpgV?6OkÛfdDG)f4S,2#^{@SP:>C$BkEa{5$~33L <R:3\g5oMĂr|3i (8)Z-vi81e1k$S,qR6$Hy_杣iAbaYĞDrL.w{0CB(+ j{QtI5e,fІb?2KVhBBy 4v1w9{m5 6% wm-i 'Pe(A]R8{h/lF.p/  8vfdꮮC :M(+Tzqe {F["Z6\FS |l8w,ڢy%ckF[h3@tYht J#1@K2^Rp NْFHڦJ9B3_=c 7rf⎲6:e]=7{X ~hu@gMAXzme%̈VF}#'S)"I}_5Jq3hX[k$RS@/1Ó@P 80%0|or5OGU0E LF`(h&4yw.͟sx)o!m9:-[p3@w]]5}F \ |m8V;n;v)܉zF[Q"PWR[#(q ;C-|C/Y^%[ي7]üv(h2q`RQœʦ; ^3mV0mGvlA.oF=O cg9g{^QO`pxS\iIꯪdϺdɵ;doVrCJh'kOq;B?ȾP 5ƱLU){Q-Sn5 dt$LNC1K,i6u@n kjHvêHU׀"WCZ i5Ր~}Cf5 ^5f ZyC d]lBS^CFF4ckVl*}\&O' 8jO40SEN: @BU UAU Yr|){Or|1*b|Mχ Nf{`}}n(y> A =X$J糙.(в?fL6B;MIaN;1HYaЁ/b~1Ճ1rUVu('9Pp@u<^o>+|V糤}LZQRNSLq.1( `F86; MĎ2xPCKNWYfB  4U#RIDM"_ck ]:FwI@%边ٝ2w,Ū7&y6/afHb˻BFR#SZ;j(8E?0֋7t &vt@(b$geFTwE/Ek ۴P K>r$AtOG5UfYrdcM3 aaĥ0!Ԟ $ E)blh[^j{P<)h խ0NRWF^|--9@+ [# fz؈-g,K7ﲯ{ϿPKSF (guidata/py3compat/__init__.pyuMo0 utvz聪ژB|,qԲ_@5}۱Fv ` ]I+}PQwva2m:s&tA.УBRɚ41b>͂5hg$b%~m,ʎTCK\e䒘,5FlDvy$ ҜEF!-B/Q66G=6׹;gw;PC)n$I,YC7~CR6,'Z>yű_PKSF}_gO_],ȐJI.C(@Wrq.XcXKMzLl piشT C-@gd֗뒈E={Q}H,8D#;XNe )EM>3Dk.rv笳uj=v!-6}sY0-/Xgr.s@68 d|7PKSFV7spyderlib/guiconfig/__init__.py}VMSHWfREa;*`0dAvAKmiьvfdP~v$[x\EoFl)$Ծ$,+c}XY=:`QI_$B#\^L Wݱ3M!5F{VȼP`跐r+_|\Pyb|JW!1زt :$5ĥpۈR(<\;\b;z,f ITx~߹/:'_Q_~29~ZE|ot,"y47(-(]#*\47m+GAV/ lWkgT!D*uDŽ*h^QI =W(ľQdyJ2e*vurK3nPV2P.۷J`>ǓSIcOO]T#흓e|rx+SRdwjf{P[2PG:47-_䌌6y&8Z+%#1F{69L+/nq@=MY!Sv%c3n p|axrï/Eխ:yusu2BZ}tG§<Ǿ;Rc7Wv2Fc] VnFcP%["aSJkPh7;#GVk%7C$Kp駦?-i]:P3+AFt#67‹5nVX$36JRk9ə6VvZnpT1Px醺tYwl۲~)Z[x? KD;zZLw([c-Iy?Q ǑP?Q#t)8 u|cSXyaS:RnYɍ_ȾSvRs@6O#"힆'"RTdU乻h0g5vv A}3"APKSFBc+"  !spyderlib/interpreter/__init__.pyej0w=6;ұ, J|NȒНCݧ٭.ǯӵ9vژ>1311Ơꢻ΂yP I1eAih {Ǣ񐀖ɹ"Ӣ`;X 5bfFZSZ2Ȱ.tYB {X? o'@)I<*je rU6k(.Fz*:&_PKSFhQ%0spyderlib/pyplot/__init__.py}[o#9{ (SAmmU"%Zv*_`DbՀ 7^RzMP貾*4 oT?`޼rI6WeO?FUPK?}|A/Ryu`Q>ntf=Ya:lCSYmX1L?d_fIt6ud>vZvr<)?\MЙ.Ib: Elyu*K]>'A֗tgVMdO6I| ^sVZ%e?Cwer<*|6Yf>M8&eؓ4]n:ޔudz(U j%U&F&\OKVZ}@GT : Zʃ&dzg!y .pH,7/Ci{B>P%oLR4rꭊSUipL:IlqH}#KUШ9R7U\a=0~:z4P$`-#IU]>TW,?󧫫`?1ms÷mm`iΫiz6PY׀e>٧ٶT9BOid+u02.ץK*M.&|qOɇv= 5/zn;sHoj#$1p D=JwKI lF}M7w{oX-0YztdT -6&X~[)ԃ#2uc>lvMVoG($ R$&WnnSb^j Y'|*dFZ]mh#4D _/wZ+C1S[lWtz )ߚ}=^V;bj@lE~YQ3 X-%aL#Bwgrg~Hv 3w^í1 (4e5&vIcB癚0%%gqrN6d%Y^8.P1yv!T6XŪ4n$s?biJKO?5[P8E$ϧqon.,Kd1Bk`Ðf.yȡCs C`![^5heVoNyHm|_s3Bj ة !5]%wv\}{Uϯ "V"J '^~Q6nTXSoӯNfCudiRYwC"wz֓L%%}7։ehp!`Ȏ3iP9F5Zȫ?6i4 ϢiX(ӛ*?au.ߠPĺ&k*ۯ}!MRnoy>]-wFޥʇgkC |J~0ڥ/7Yjcps/1gr2Ҕp/ے]b ]bw+Pu^ҘQOt>A5GME֨!(F;.R '~r &;/f]9s>iaܽR럄v !8$ŪLOF"ɹ<~YIhl6??viU:;z2jS'FKmQWhrc4d3zFӀ:G#c4[,bq%6Y۬]D.?Y",C)ϽaъMSj8!jMyOҭ+=;֨2P tnL}+"nu[[64-xoZ,ה 0T 6e9i|r044@,-+AUtj7`LÑR&ǥ2YVV|'6ɷ&)x~&NM"1ȳ AkhLMF%[K8smTn]<8KC^i qet`Z,; ,h\6M~Au^OJeS+ swH̘ |FP7aN8"6Fg\SX['&NʔqfηG9]-`3ޓbRpSz_ >`p%]KaE4V^ZieVzHJrES}͆ ‘i6W w'79G(،7?%uNq:[CfPN:y-wc\6~08KWp33 o~iTA7;M ñ2K)eY !> a}Oa ›_AاGޠڀ*GG.!ƓХϲWem M4}@Wj{cLs`3Oda1lSdXYw:a!+ȸE#:dq]G]8)uUĈ̅Y(ȝ> vT{څ EU=wjԏUiN)rk (*ïFdGxmw4BDNATX6cmu8XaRGa} v*mתWh]n!2$AYޱ=fH_^Jb8B (HlOZYrQ 6تUDf{N&sj Wr`8$|dL!;G-TILnS6win1Pip݈7;QxYftхdlZrUk.Xq geŐ7 Ǭm.e=:3^EW|PL &.ŴXf2~߉ 62}iY|y2{C qC9c8Yg牎| <["ٙVژJdy9 @/I0 c#̭<ȭwv-%ݔ45 ˥7}*+458.jgƭa?Ɣnټ)ؕ7 0oӤȿi2p@prmNy]2jҤ:hYq~JqQ$ֹ[?b( 1ΐ (nD(JtѐƻJ@l}\H@xۣDȻ}JppbZ4J6&-7%SxxfȵYCMeP1ڕbܝ gt؀_EDݾ3{^#/& ]Sأ *n{A!mPYmtᕱ lBͰF5O6⏆Ҭfq)J?ZIuԎO}4 Ӈ(zAU؛!D4wEG2-޽ c>Zܖ=mpUf,g`hEyGCdV# `_WpUv(IG"A=vl5g:Ԣ،*lQQq׃_UMهQs+Q;L]$61ȽEьq8J(hq/kb2a|w "vV1l n^ƨ,Êؼq߇+GBҕk*ӁSO hypf8:t9PbGitBJQGv ΄Ukq&4 PG=fbrTVv=z6΍/ENeZ:2\K:+*>m2EJt&IsWe'eA@Mڢ_*t# %Rs|aiKw#u)8׵ןOK6>+D#q3/ :TM~ '?Xy@բ"mA.~)gu2oTVB|tJIanWF.EʑL&J=-9XX=tuƠpsx̦Sߦ[)Tqg4r81%si2܁>'kNZ X㔃v $ov'Z`Ɏ\88KT(Q|pxN噁D)"\A컜]9P 8t ώkr ]/}>p^@z^(Yz9^Ʈ2R̵HYRz)zqv8k2LKgmKf.R3O1CV g}^"ڲfiZYliYhEK҆/v_͖~w1~n,B8OqJOkkbܨ94bA(=wyݤpUE2ݤeKr#QLYkEVƧpe[҉< ::z,Tq@p6tvTN/s'zxeef3.!sP3g\Gз}҉8گc{$p3Ȋ|,sE'(##N #q MM|A]j # \Kh;BXGuv@9B'  CG#=;BykG{>u3G{Ʌ7.I37VGw0(z-6sT ڸɜ// V)I-аӰTW ci]RUGUĝF D=v>!i\-y.J[ d|T7|#>;/h$.i;֒>iKwJkg\[IC2zQUg\Lص2g\H{z2zb&39ؽRF?ѩ27U哊 60Dijkt-qۂek7KEFڎ`2*oM]T"ЦN77:fB49Kk, c~-opQy[Q Zn&$MXwbIuZ>[_sma,*m5Y%J51v[>1vJnoacCg/"u>Ź宫]0~i஑n kuw:>!ufXՋa2U-:;{ \7+M?t<##x.ɦߞ<%4O&0 R&HQ{ hNX3De&/URn-N8n8>ۆuJ눕4thI̔*LnT*s,ב"KkwɵiȳS=G3?e eN,k^+8,v< l_JS\e}(SaW0_*+c$!,Sa}|KʙyVqAk )k!dQZ]a[!K%>A3wO{Hѧ''#OɫW^GZ'&xҾ8j_|K?dL%22JFn?`t $E<'::wJ4 oOUElʟiymɊ k%Z68 1ppJ#\/F)VVI; SسbYv<75 L ^R$FVW>)—{ {3wtR˧=Sgv5+9>WۑJcϔaD魯R$[Щ a{O91_smJC]`28/}~="g 8Fеב"칲gwA1C1bhqZQ^ ΠGu#)tZnq=ͧѽ{P$)d]4 OnMK{,Jۺ9=h`]8 v3!W wIٟQ zJT[08w2Ő;`QPzP!~4 'f8;\ "bnNp.O jHD /"'=']i##>]nZށYa;'o8O_l$+ڟo).=@J*=r]R.A,{"˦e6I')ܧؙtw$b,Kv.7xP!=^͛[>LMC,Iv*h5YqKY_Wb}F<Bm+4GpW MH\IQSpvtz /ûs$KF5>OP4 sJY |6}v.2|,OmGe~_ /Y{㶫4q4I7{*[^ dČqY}~B)P'1M^-E7o0疉aZ=9V@9Wj+O,ުĿ_=] g ~dde2ˆuYAt@(M fLG70=:G|YKd@\`kqK&f[}TpViARH۲wrLKj%2!<{$PN`h ]<¿OFebʲQֻiq،YKm}t~i*(q}fV ~<׭Q`|SJk1"vpދ}?0}J[1tsdz~U`*~=ßwW  Xzpwo?@f ?b^{H._r]! ZߍQ* P{g-{ǖOjo]XDlL!?+E7Qkxix?S܁ 8 Uh=F0HKHqwl;~a@0y2hPPֲX25ڿ&qFLȵ2GXm2XoUk =E3_#}xfڡmobg^|lx !.[ׂ_a_t=L0kHa5/'i\'}*6\)*0hCO~rRф74ZC  }?AsM^|Cx RcE+b\E (g .}"ij! .=H tO r#Rk"TԢno)W WZ(鶘wȩm{9V{u(s fxKO=j=̶ʊ#";)oӝm"HRxZ*3/r2>l? ʋ^Lc%?@ O<"=wGD+BiQۧ`zCwKʅUv_]&'2{0}z5;p[dku{ ji:^7&<`.GK<{6/T ф>jUk\V.4@@ 3|D1ny0k絔ҥ&ov"* >Z4ʅ^tB_M+ydT蛄0 70a_"goK {7󜜣,aX֧mT)/m$+~<)C=?yu/1yܬ}MGYeOSA'c"9 a-d t}\)ܳ20.Ȉä6G'02lp y% bv HcV^`"! ل<=^kv 7x-ƯNO.ee;VD;/9fa47YEuq^4Ǭ,ۀUc.8fkPc`՞2 2gIVηY{YN2|sP(}:GƽzdZBv`Er5 %r}{jֹ}IZ>HyeaD1+8G? 9O[T4&"xsL$MױE'DQK)5~;ӭhgY?Ԯ(fM?V?HuAW,H  Q*_.+~@;>&Ho-V7ǵqǙ__j%ʥߝc[!Tc)oӁ4v PKSFijspyderlib/start_app/__init__.py]M 09Ev AW;"Cl'u0$SۛX*YLx3$#qn`NosmSB\5}Y,I=b4tf&:|1FL7{Y2 %͏vB|,yeBb|dB; A𡬜jlZj}IFPqJc6vqQzo2YuyPKSFT63 spyderlib/userconfig/__init__.pyAK@+$X =6`R!Id$݉wIΫQx IƲ-i.D)S$^4Fn|iv Lf,cTG7Bq1cpZ*K߸s/ťraRgq FwK`]G@+;kj ІVHe8ux$\\Hb2pǬR_:MHx?RHI\յ`LTuEU*/`=u6̋J]Zg&| - >\\N;?KX{V-J|)F}F `9}:s%Ņ_u{@8 *Il(V;n-[Yϒe\:ʽdO3U[$INbE"X&/M.cVx0a; ^d99~Ͳ!:*&NpO3}~Y|zW\( Ely)תX.,M?hƒrі<+tYe!Z~yaZy][<ef]5Nl?pJN.Gnf̎dX`$n5CF_sS,c#Ϩ0I(&^z͊ƭg8]}IbY)%LMˢ%q48:Fӱ,vuޠ`^-2`*EԽ1vNU3^{U{K֍/d^793/>3ݨnIFbXʷCV*&f Z\YҗkE+] 3r^v(A6Wbً}3) gׂׄ\XKz>ts?zVL& ^{ˌ7"d\U.fy2g]Ǔ="&kPC(MJȪwAL>% ] W~'oN2|){-$ڻvdᢽ.oHPaIyD iN +L~ْ'u5zX0s~Ic˜$<7W>~B?Ӿ?1ԪK$~ˆ^ނ jCw(%37_wkCtx\%jOrSOޖ{orVR& ˎ>0eBaJzxA❡߾{hy3 45x8N=k):[vݓ7OTSѨM`P F 5l4s}GT߶FȹN k Ä7w`ОFW ?ەb}tl@zD|GSc1m. pR\1B MӫŶ@s.A-KD11U"dLe)-[['&鲮%_Q@+%iTywZkYg+ޖZWQB]60eWܪn*|V="5yX(4̋iW]lV]x{T@,=1׫Uޓ"P@PEƪn=E'UWx8h0N׮hdmr[Eޖjz?_AsbC~ 怍0Fad~Zt[ Į7}]xEx\̽+omq2Zu{ko$>y*Vjj)zr,y `8IHW0~F\0W/ >ҘCKqYk¢<8 J~ת_)6Sz6S~mLWLڏ$ޗy4xRܰ^ơQZ i  -D0lfx)ZvtQ5O- щr׼2rR! AeD,V qD2 Ve_ǿD6 ʧ`Ζ& K/MGn4Mvt@`Cp s2TB&i:\^#?c㞊D#bdI:o|Iﯜ!{"Ädhf{4ߑ}ӧrepr2!|ɓĢ> :Nb@wu/1 [Εٳ[vdψsgZFĞ IB+(8 ,De4D$\Jq1ݻ4֔IH NRfU3\2A$%~sw ȅ=}#ϼ8R8oUcAɩ#-0|G53MvdBƓѣ-t CA`L^5؈X&P;aaq}@F-$U/TQXIaـ/Pxh#`8uViGW #Sv0 ye`RQbAeuBǏqv`P`1 [Vj0bF yU@s05ES2DZuU?ccQ~>wFk6|R|! #;b^f$P@t6),>K꽰$a~fjZ'ޗ}H<=u"qO[bQ_a=fAl/+RѳD i-qX>$Z_ٷ؄l κ[8V~WdTVb0r8Mޞhg6~E(Pߓ*麕}rD8H- =L>ixƢt BQ%*RHP6@N?I{.oZ)87qx pPPYC$R!z߻xC]y΅zQ,"S aoT+LgJ.HM?0oqx9h4cϔ+.#Rd@_pD y$Fq?[Ã>qҟLqpj]n߀. +{j"iRc ƭ*~>Ӝa{;W g3Q;!7w2$%xS,;^'˳FC!4s[ χAvcJt]P~Hp2ˆ?s |Tק40U]mf:>y\)HS`a`a u  66 XRڗPчp^;zʋQ Լɬxzڷ=*&F%Q<*1:xr 9*@BOݼ v[SFa֦b?P>5n G Ӻץ9'$7?~QH #Łgvތ'Иf9HsF;ͣo|EF#ӥ7;>Xx,V3΋J΁f`v(IF>EۅdR:` Ur[RږZyd:t}@WЫjQ µ,$GB. Olx3|8QE13f8 M7hYI~:vLޣm @bʉ' t$=>+!Ab1$玆|\a >pF稅A'۩Tq*~Tnm"^WvĖxv~;iWEq1T*Sj^P0Vd|4fE}vXt(V[5z㣇D{ϰz{W (۹z<ķoAyڅS~8=np2mN5Md: Var=VeI@]dpk􀝲jO˽ꚷԑԵ _"SԏltLXQ0_-%1,V /.=ђ,p,/WBFApV)QмOX7\I:p18T"rXŴ?xwUm+Ux*,f/5 &ڇ4Q_"XK׮AH hyv 0x`_uH̴rLmG(YLɌ2) J 1uR^C2t@a ۅ吩0skTE=袨4FE65t*fQJ"5IEG* H":^ɣ~E{RQ.T@X҈ugU UHxKƒ I"Vʿ}5/zV&A+63xoJIAAF҆MZ$$XX#򢇧$-M .#xhS}ŦSa\<ҹlJgD"kN[d@.hѹ)ֺ~dGN .sN(U|޼.k(.=Jyhj̓LA9C3G  +84p@ms2Vpbm(85Pfܚ<^NrL}nh/SD{Z/'z{Z/z;O "53R<^^gKUʜZKR=eTSjnT΍* Ɖr}/LyQYU3sr&ЖxJsGcըLZ6Ls9 p#43po\WW4RAs#U'LԿڈѷ|ҏZ}׸ 8}Cr̍έܸ5PDQ'!5ӠU/^?P#Go(nn:ܲ.G'erhM^YT K/Qm^zԭje[)T vv 4" I ү#,|eʥea359_ė_.,$)^Do/y*+ c} oVOOGjQ ')yb{hӯ}zVA.%BbiDP%Bf҈04BFFDabQDaNqόqgF{~ns#=lr!Dž~\Eict coD0إr/k`Ku^՛` ԰3Z 48,52b0F\m{0&5&g&a,`2(df1yaTj[ăaHZ8s:|kAZM&]UYNZY<\v_ТS3},e E>ҩ:7Ë;v%l`unqz6^%n+|X@7=g dooj EP|#nK¡[XUmmMuFT5_ʅ` lUM!ڞfT lEhmT.ֽ)$v,ŦEÁ;,Jݥ[:LPGA{C>b"O wmZisE߭KZLɐIDrH \5uu¼]7aooog՝=iAIH]֡j{䙣!Lӽ+ܴ]iʜ{lsEh)UC` ܰZ!;DTa[hgQ)JǀfWKin!mĚ1|[$>U0؆Ruo=)7s;i@ލ 0:ˢ#Q.>DWہNcLΔaहϲG!m}맴C8=`BXD?x4j=}PkC"L1kN_=GtyX ?3{l1%fU<)AO;v|o_/!Lz t]/O_FUgNJF0L%0ܕcrTLo ֢!y _m *AKAպ^Efyyzyx7-6r~B' ﲑRѣ>}>H%8|SȢ<)&%1'4n9ܣ7+u {ֻ ? L!%IcAϋR>=7Y˽Z ~_/P8n_̾D%| &^.v) i9yЏ/R`QK7vMP49ĤNUGۈv>e[UJ ҕx:.2JoFX= Pb+ Wʡ@:=H8%[j,j)"| rEgI-|^EP>55;(gu- 2Ƴ~OwR:˦uYEnj#t(M Vc"#ƾ`[8&.U9UXVtdR߂hPq˾zcsOH]m.=hov"CgP{Mx+v6)2#8yEx_86Iww'.Oƒ7h6&*,S_.bF~⏼Rg>?\26ߚ$@Ҁl6-"N[@Mx7ERJ B[[L) /C>z@  | rݛO? B{߂}@`\W.~1 ~(~Ȗg~HR/6ZXDlMt:Uf8y ?@DGG\;"e g٧ ;CEw-"v~.G cvq?Fhkfim+ު ~-kwo`=1X=>UOxzaϜ)i}} ʋ5Ş mu}$$֒8b W^Mͫ8 L=\I(:_k_0 ~7X Bi(ūYB{ '; 熞* :f{214)`b[vɏNH'773^tABRiX_':NT~c ¤+}l*yv>?4EDt 2@p|'@`rjU6Nᯤ`.$@w`)|_pR/cQT^2 r@W$xL_@Q0"n ~b2p$ry6Q_5Ɗdx ^#ak=DjfFtD-}3o8KD%B\ iK<:/\Ĥ |MZc*(ÌLAR[{rhr>`[%~LJd!0JSHP@FŋI\*\)*VCTi^豳ee-QQo*u*hߨwy||޶<>MU':/[6Ϙj]_$}aa6\r6#"?>f[ȟ~N "o?_Ymۼh~dafڌjc7Y;_Kf6 Ҵ͏MƖm~lve}[Ua{ehA]½lnlr;`xzlӫ)lxPl&k S|"͛=q^}s^"+liUc0|m_>uV|H23ߧUOȋ=HE|\H5)|mYۺ 6c?7 ͼȖ~;MPpcՀWfe4ASZ[z5,׬ 1G tlr'||_]_܎n.,Ojm[mLG7񟠌-`aqM{NiNN 1? %~Dgv],SVlw^gogXD1f Iv_u-:/,d ոΐ|z ?e)8lP{O}}> Ҁ>r i*Kj(u~X{ +@gyc Tf,q! Cf C.mN__ j"zaKA:YU?(x4Aߌ]u<^ sTw7PXsr9:N~T*A OBc#U*Pxֽ@-KLiY>7uϪ:{HV;0mZw>@ί1)TܼLo$zrP0ߘU V +kNu(_MAG=d6+Q`ofy`5*^OXgO٥{TŖ]NHtPU@r̳uV/YyiCEpHXI|X͊ n5to-%VoFzT75 |A(EyfMb7> ,9-5uR)/*/ V,UM;ՖbuIboۤƔ)OΊB3~̲Q@fTUUUo ?66 9ԑ_m3m޾F87ٶh1%'ϊ(wԯ*~VvR02jfn0#Y^.EyYK_>%Z]td5Iu4"+vBvippMeU+cqHMXzVPwyJ̧mV,ap_qJ'hhMn7Mq'-hh&4Eՠz Q{Np-z *5b Ə^gj@0~t ~Pҧ+\# 9n)DYe]&0QyMpAevnIRM^Tulq>=[oX6ȕ4l ~8LWTigR5Ҩ RzⒻ$@Ѹ*c͙KQ1j }lT\iaz ]ߪam o"g,RXO&Wʒ F׭X\"Ǖ焇ko,Kέ=fML!nܠz}c-MV~р%kk87X%,/xWaڐړ7=4.:\2[;:۝+Y]0NJRaQGVYVysC{X54UWmsUf&[Y[ ~][a!( R'࠱feL;Os5Bw,PЯ =~;L vhBV8+=ztLK ף5g:pQ⽱*.S6/Q =z]+ a$?ف_6 Q]\6mvtE{ $@S!a u /v:Dګ.O^{[;AhdY;\I4&Ylg)gz8W'*i`TGHۍtoafN` )nD rڨujFxhK 7|eo|YfTx6$ÄifCwEh ayݴ8:I;Ǡ%"nH}?BD.!d}wVUi^Tj={g~v:5K:0T\tTШA י*l4޼Hy y"',425%cpR @:?9Ůp; a֡Zح9Αzm}}1y*9BY@τ`˄utžY>ʚK> [,o:gx5"%dgKo,t1ct,3+K-Tr svzȖ`:*+)hQah*l * sIPs)*|K7b:*i^27XQaP$EP,NEgs#'Jp=WTgոo &$/k'd`PdRSZԘq+y0hе5;fIضк-zfQͽ7VScD ر5rVb톸n?$ɱ1'firho,Nr{bv("eD)5kO̺>Fo('#KYVhFkUpP/;Ũ%N ?(lJST3{x6/|僎A%cMB"|-ڜNDN4>6 T;׊c;V-"rW)JxD;?ѹ&4y7PhǺ<5۝&SK-v~c=f!Y;S^l$t FaJ֚%[2fgAXE /l3h Q|Dp$9IoII`kJS J ɻcs aGap# S /즂\rV̪+U3 P[,q;1cAI=- vld L+ CcxviYZ+ΗtV w WNTF:^|(n;]c9J\\dFuMu5EN,t&gɸmhx< B-]>]=LW9 +~P[ޥ~-%O>sG֥x2;OR42ZQJ \ݐFQW*o^~ڄShd~8ݯpzĦp'NEAFaŇ5D(.9F$GLDI<ʗ]{Q{ZlM 7IK*}ЩUq(*q׃_ DBX].֏]WT zKrvϲb-8 ӆfQQнn_uLA8L*cGag@roʉWlnMjQ`ACMW)mam#%qK5jar ; ʩh5)bm!13ȱm;JRGICJ(]R[~O"*Uj8Cuyh 瓩K!pn bVɡ#%zP!i ڼz}YVW+2 hNzI:ho)(c,hjMLQ'TR 7 IkRpj}M6YuP]yQPLZY|dDRA_x<+<*m'JwFIANT->8V€zϊĉ'-]ys EE(6Sa#f8]NM"84Bn75r@хk>дҵ۞z}oّ^ւQ#@pFyi꧌9DAR*8`]9P)8tHUSqZ9VƮme^]+صr]+صR 8vj+cJqZpjn8qT8N\+.J59tyV?N\+u4v Օtjǎ ƎNZ+w;Npd|>t}|h"myݜ18L͏U$gFJQ =iqUζ|>Q[JA~K2RGBs4  CG#-?uga!l#-;BN/t7Y^ _wD}[0׶n 7ׁ{]-=LձbZ TlYqV&k*:P#i` $\L M>.ۺDD(.+Ʌ>fr'3i[Av} ' PnX/]1I:ƽvAյ:ySG<1iL<+U]-s:7An V9ǒ*Pخl;||1;GM|uln }nߞp$u|0o^yrR*տX [p>_ w'jMT$jwT6QKKH}Lg/$g(crA}RK>I8z'vIJBK;>xwmܓ=u\hdmjjׇyc$gagboo'U9xɒ0 C^ni*ST9Z']mdE'~S' *a9˥}mOՈөj `Vm6jQ: 4xUYb5TyjzBڈu|.Cm(5 ښ3izvxI9-8I nTεsp.*ɭȓ3=G.MO-߰uhLn#78¦r3Զ|VvkͯNxp~[.'`pfl^x+^83:/3ZNi~+꼒 HAE DOݻUƏÍ9IIU ̪m]ySjd3>^8,v(< d_HթgL/{T%0ʜ/`JO3`&L'>|ƹy:VS(\?w%u+D:k;D4 (GңNGw/Tk`p]Mp' DgSneiڧ2%NF(  " ${(pZ-+TM{3 F#zCĔO*oڙ paז rå޻@}۱ϸH&gJ0w&d Щ{\ns ?: \48/}xQj݀.t5._F)S\uNw0|Xcȳ?xjOp=r8-7a)þxbtUI\f4׻7w<63e]&wNX%<@M6珋Qț~ݭ@^]%@!gc܃;*=}?EhrSC;/vZˆ5 QƫnH9^ޮb$] />aLyC3\ѕ~H{+"`|^oWՑ._ I6{͗rH!zn8a2TzܱTvN xo+QY$:II|4h7ܣ p x\dKu(6n+o{1I4GŻh0Lb8/$-EYO~ϡ׿tbWEx&uw!wVkT֊s4Дx3y_w4')&l["?GTVZG_C9Gn#bL v2 *e#n\7M,/<"H>_y `H r JqRp,#Hx?ԩG|fuDWK`̂˫$/7,CHka,\(r0 /!HЏv`L7n.y/҂/AP)2e3:`7*D"Xò'U/`@Xr K] Xw5ԩ(Zn5ܱBrt1y ClgKzO2}7)κE`Gu ܌eU,{_eG^WwՀ&q'?Q Œ)v6>J[HSlqj Hat+r0Ē|NwlK{檜ۅo{!E-{4`Uݽ \Y?,UՏ"umWʂv8 5t͚EWQb;޻8lYʿR8Rn<2[2\iy Pn1 ɴeE[z}f ]5Z !'|h `p? zŨUD hN,_o"\jIӁO֐:b U.|h? r,6 _|Kȩ6Rd`&Q[Ug(v_,0LJ8/X[Um+ FoɌ{0L;%2PqNXr]ACB~wu9L:Zh0qL zn_8HW!X|-k?PNn"L"eca.w9""J@3I@i!^&O'7զE4GـM݇TlImSxROJe |^ /5&@P_vw -1:-9b7 ; u;U@y`Ort-'8AW0h#Vq,BL\YJA$[ku{0`2>^7*>ٹ=p 3C4!i"'[U%z߶J.`-a㎗L+(ךKe]NE>z1DzQ|ɂs+A /M\峡 0HANx2 8NJPu7Ȁsl^U<%-F,$QC pӭ8n[gkX5o6FRa[aB3@5^:;0kY ,VCnikW8# ]9Γl6U7G)f}pPUl (=fFw`9"=q)$]@K\n?qO8Єҵe4[.\? #[~IP}y"';5>D|""_N%T|?Y=7Y%3tORNxzYk43rYPe )P@́qmI,67`K[ZPO6~_=z~u7{gn7pe>sYٸo7vPKSF̌&t;spyderlib/widgets/sourcecode/syntaxhighlighters/__init__.py}Ms붒 -*3[%R[5 [Xcݸh S$ۺ~dO7F.jUYΊbfe噸EoYޯzEWO}x{ iq_񭬷>tH_㦪mM]4 _gؙqg,@xoϰoOE5ߧ)6vul獫MhTbCZl{{Z|e{Mۤ}oSM}~m3yNimEz@M"ɡ ^&kP"ك>=יjwe[^VYazPit^QE)JHC5lͦ5^=Am_lM]tP}˔ϽM[`мenukc=VZL?-@Y{]#5Yfuۥym?It͊y_rW]Kia8zi"]AOݮmi+w%\@@#[M#*'lYG>HFņ Ԅtݻ1Iglsg[{fiz{X #ݙP@$yy\,.o}U^1O# 7mUYU}>kYi\Wx3aE<ȇ|چuӜxW]CxkW,zk04 j?] "ma'%-rXBlo Z=/6nV+W l}gKK)Z/ʟ*LR #׺tM[f%Vt)qZ]6!k- _l[ܪyBg[[), =!2QPM|Wf UBr _#b6ĖVa=4ksH>)5+HT0sgy~SooUqU{̍{5fSBCf3NCubA}!vAÙSYo5y;S/L >g2Q?Nh=(ܕ_ dlG &9ٻX_H\RB&>+(YKzeD;A<MQX2^EXCԆRA ;Lv&Mz,"P4;$01μXa`QO;<oΤi? gG,IJI5ӧG)"5~;شp9-+hdz-=6gϭsYK:q̦`%2ŧӧɰ8|P71FaOa3;0  _}{0%RX`H/ɛ@0 2J0eD!n"ȕIA $_؈_ */q<,uV1(2煱&c[$~Bd=63HTO1'D|Q=i4,o<{0gw?#9bf0Zs8჎O41j_]ba 2T@>Pͭ-cg!+[e\-fm[0v2. xk%=J"IWE֠ܥ5N 6.]M'j۴^-w)5]["VIdcY 1m6ip>yaơzـ-M(! x8T&v)c^nޤ iK "8pA.)dJAesq!˞eEМ8Bs05h%8)$y~qZW,Yt%$ϴr`'0ZLYuxMa?tJrDk9jM}=LZ@8WgiΚ ~F,vKQ_/g\1,4("kAh"~`R,Gq4nIQ3 ('`>1&dFڸFŋ[I(tf4 MD!v ]pJKrd?qH +Y5G.zkVl@z?r ɸ?%=GɄktEc L^ň]y>\‡8 O`/] نeAs=8[\fҕ5s{`>eeu<mS>QB\vAwCpaƭ14dQ? Lv0X  ]_/~/ho[ٱ['S4e,;诌%<-4+v*, rF1/#$&>1Řs3^g$ Oxn]h 2/+OGg>2ny]:͏FYFqف2+GdL#z~/cn9>1Oim p+$-YF!!CJ$0Ƈ}=Ñ}>ѨKB"Y۩TqMwxi} n+z;Vxin|Uhh'r / ^Kï9@"_>}݉@glt<:mgJwAIT-K3֑TV^‡HZ~yO W/*K/%}'eMgM-w84Rs6 x)GGۑƦwՉ)Wѻ1A@lviPGZ)x;؁C)8pЁGT'āSu̝cʉ2vh+cĽZ9VƮmeZ9VƮkT[VjcJs'kR|Z!q>peN]:c;FMO)CYSsjν1 tͳ"-\h*Y4{+W"aIi_E_Ů˝8$F-ŃK C єIHI'Ra2ܗ'x\UfN+iҵ|S>zI_:}A+ fW -*{ _=UVp-@+ǟ6} XT9 P:+u(KrRrή~hcHeiI\4eQ3~ݫrX0Գ&:tG=sj>i{* 9c0#V_ϛ CXg#5bh=ybt8QoҮ42!ri@P?Pe:GaI@;0 La0g–ϜÖ_8BKG[>w__qa;i _Z`;-0myܛr`MPjANFXi.tZFM tiH54s 3͛ tYI0e'gu+9ICʥ cZjEw'*7rگQ-fTyֲQ =>r/ݪ{j6w StSXN"I{k*_ϚЮͽo+jyl nwKצ>dEiR<ϯqe]^xF):8q/QSdn_𔗤$eWޔZ#'Dq{փ/À[~C ۷7RujSI06~ * l:@l9~Plk\c̼9 hQ"wPW:(\4h:4_RCϞ[Hч#DW^>K)x( pK~}3Uo"MTW~izϲ<8xsT_z_Q*͈`~lydWl%Z6eu5b6)m^RݚT""o6{9(` VlM@F2@Q԰jϾ]gDCA!m61uQsI`Pt5WBp&CҷOsí|FfK}` +Vea;NR!q [E"`dM:E&:.EWMOk}\Z݃ضOq}+\/lj|;<>")͈Ns`ҭ?@ &I>}>V7A#ᰅV~iD֥$}E|L|9w*;u~xy[XmЗgcO=r܅-G;tyqe\`ȩbyq=\~:ŝ)fi%%SQPQ=WLw@yx*u @en]v oA^Y%D w(ѵ)ΨbσܗŶyZ41wi2l$n}Mh.Jy 6BVG$-}\,twGP>^zɯtgU`=^`};dt藬$Srq?xoKqY$5'&?ڝ!8Oư1>>nqyWiے\C/'x0ӓԜ:`Ex»|~nL;÷̪~YVy I]aQB%>ZB`6QѝJ|p8?Cit@ 0?XgL7}6yT~p/eL5Iw'箐ӈJ}P' #d9~!oթ@*,8k„dw D l\)*KE|w|sl-%Ķn{yU aEBCOO47ESt)oqWoB/7yV6UtlyN,qSB+V&̳w>{6P UnaiX^! ]} w*/$uVv$^c0t.=q&)щt$2tY'w BeΊUo;kKAcԻ,䮋sCOAyǭ N VS3޹haRJx "~ IF-Io{o-((i*V)~ Y2Hh͓Ϟ$ aۡԅK36wZc D(>x,e+`(ax$E۬0xz-4E}*uA#L '>Wt #62B|n zk@@R{H!UpFU\ OG "[y)(DќM2GXgnE]ѩJ`Q:cnL~-h*&Ͷ.r-K%ƞ'M&>awdSN:yvmg>НKiD19h2k&Q[Y0_J4pj|)J Ī%+jmx0N;ȩ/8Bb 3sdGJ)\9V$.˱HD+=|`?3`N]1 I!gE3HB:LΙǦD5.yR돲m4w4G\6 k1SxXۡ"yY,cRP^4 @Z e hyG ϒ 1%"=P Quc; I[o8Z'(fo5x#,g52vHkͮ.Al[6ZXUKn$KHV.8 Ux:mh/5n I/N|-GUNOc p 3(*+dZ&~؇G1/jJGKsKp>ԳGг-_`uV{:Gd NgyGs 5(BC ئ(o˖[gϒkl`?+g##-2}n'e~]}YjpKh)8@M:+;Pj%P1}Ws*Xo5O;d "'hz˛c۴~9G液 Ïv \43c ݳ ozvzWmb;/ѥOaªX7`m0Eַ}; Zw~r_z??|?PKSF !e1spyderlib/widgets/sourcecode/terminal/__init__.py5M ὧe^!hԢ6`@JGFfޏ1@tw"@bK}.pMp!QN/3Yd'2vQ\d/RE?PKSFxo -spyderlib/widgets/outlineexplorer/__init__.pyVMs0WplnHt&@ܘ$ɣ؋A<wW@!xOaU3Ug; y>MK,,W2Y9F`$~.{Y1`ƀ9yd)yX06I$Lٷd0h^YhwDXۥU2-y,Ufd?;r v$"AxNXm}h,CDA.+-:ՙ 8=dB' f#9SݫqbY5ӊ{ .x [qx3(1le6׬XWZur_ &Ȓ{'WOFIi5=sñm[&pH 2Vsl*4̙YBZВ9^Lm/k£[Ķ' Z U!ڗzjp7wԥyU[agO;ay"]V8z=C(/'e9lܰ5LӲAkk W-c<{EYt ~詴^0_~`)h/tŌ"2_ '쵲V)\ ]DP$MN8OžP`8/ }ZyZyZ_%*Z+s+q*_MGK - !HrH-wmxOp$PKSFCt`$spyderlib/widgets/mixins/__init__.py|Ys#{ {N(3N׮^ ->}rժ^俠Oz~OvMYNh?)S[A/Uc\YCu>]]/?ϯo.No/X/ .?ߝބsXظ5MyYc(/\')o U`nvy)ְחO6oں() »'Mݶ`{5*XU^d@YQpدΰJ^>E@>wT7;__['b"<"OuݲY[/"D|#/$+I?z7ko UHg%_u^;?+lI5?_DF Bٹiڪo+63?Xd:UsV D)o&_udɄy2.\S2_l[xhע[ie`PbAcmbfKF}_ty#Dfj3C>o:ܹ]q̺ERRʡts]ZקZ /kvh+bK}{~4|-VCS;gd0#/qY3$m5 "[z9qvAݚ+ uq]`(gTp2@ָf]^@ mT%6k/o2aTMt $xM:p|En9+ٵ~|(*|NF!9R墆F22dx< ]E\؇pSH\v&4rBL,(1Mee 6ld16l"İ)aw}'ïʝאI\=^EڷosyS#DҧQ!yv_Ύ#%[ƳW[X5NkSU:n3p(|dDЁGuт,7b킀Hb9jʺA, a~8yvFT+ni^B e5<Mlc*6/ C(֠> Rhᔈ:?u>xqiy^55h)-4nWe;AV0L0R|^~Eo. ioNn櫰=go*Pi0D;M8>`iYCwzj)Q d[H|)8"6V&"7t[!@Dr\2·8qݡS?kStB zrOlRf*"_Ϡ95 ]{ `+c~{Sì\AfQ:LSO1E{` ZwT9U^]mHUIE!Q8Mїl VopC\'\Bv4^}`d e YzoTqtJT@ok .8Zs@iK,GpmWk[n̔ /8qwG.dXH0$ˆI.0 #.h̅&\8Y#KB"iL8]߽ͪz=ϿjL&Áֳ.rNL84bgҝSa?z2MFw`mNۙ6Udx[H5[q3Eu&kf8}dx9TvMfvUt^BV7( 3Ta;16_f*V.êtryLCpZoÐ w%EMfG nrdߋʪN,ރ g,8=8Ķ>_, L6T ~kY eI@rO m2naL)]WԵ _"&t*)[f!fuİϬD*ȣNm`"9r~a \h3Are84 7i:?#%b*GMtjۛ+UxZLKg$a3L%խTk׮AX ѴjRջaz8;ʴziڎ(QeSF#FTUipUCEP(~ab ._?f]&gjFiD@E(~N5t󦮬aD3Ԩ(L_!WD#^8>KG]&1..$$PډxK.ܮZêļ"UkGMY֑9>ufJ|fRIh7Q{D4>̰&Kt cv%\@d st *_mV՛M(ͩD/esޏv@Ghmxv2|tN`u +^@hyyk2O N2sb#3  (82p@9(85٧& 똛ST{Z/>˩2^NrLrL:zpni9ϬR<^jHgV^j?ϬbRs@87e3.ZM;M1e:EieJs T84}Y$~3smro/¢Sɯjӗ|&uƤ:b^Z<k8aU ;FLX8~$C1cCrޭܴ M|ϧ!5@4ɹr-h4r^̢5U3]M+ZZ:uT[fD/0E\?dWph+zh4bVt(m彤|vpdEDtDuh̚tG0DߛdE XQ&(*z߮ӳGan!b.oW}wtNhtNki0g9$}ۼL z<ρO n1h|>\#\[ϛ|g݉[ +NVjfqǫD#_ɠD6EYk'xu޶ۼg{ ~YTn }!%ƙpQW_U^d>.r"ǫyiLΔa9up4@ PΉO3or峾4.[aFdYK:P$A|`+tNSk Tʜ1 영_OD36]Sޏ^.q.|r{q=||=]|4:R3守eԧoQi߶0ݿW8J-yȼȗ`UxW 5tX)|$侬SAg2yyvo[O~tZF""􃉴 \)zI1CBuy05#k]C_^P +b wo 5|#s9]ZRfD,䫝kb#zyݬܯM=@=.=.XAb]-.˗Κg\m"8Kj?J!IQ6-L6? ܱ5JCP )w]D4|xAD #!7"˽2.}` l;^}tG`" Ʒ\Dw5W[#py) ѿm5'1b5 Vf$otXoV%'XԻc{_O!}^^$64m uƁ#ƻB8 /aF@R~>|>=?Fr3I 0H 4ӁIB}Kn|]F 0hXk›:}-}wF4`0oJJ'{ҳ4C&v|qzZi)$o0L@O"f^u(]X1d "Yz)>/c5yDD6BC3YDe!]& 3_{S $~Qβ)w;HLiSoU}i,``5AE7bxLzo#"w'|_zj'<|4n1FNW "G'| 9=H-Smq5b\]Kh^$xLDD F;z< ul/Ĥ)'>GU\V#@fTU"`]k-#MJ9l-g1_'GذNP@KkVRT Zkz脯n[_WdBWKy-s<Ȉ$Zpћ?9<ӇwpJ@T %ǜ+< i%WXQӏmFyH­l-%  'RÒ@ ڣ_fAf kqʆ ?fٗSv_ʦO"KhF ;jٳY֑CEgc*ַv<c= chX&j_3Mxu<~d<ŌbedջiYX~a:W%e9zP7QIN3o^ -S |3+jz)iߗMN< j*$&:oG|1am+0[B*`У;R;=MmDĜ¦wV-J`]Mm' X*Z?>Kꤳ?`oPKSF*nBG"7l)spyderlib/widgets/findreplace/__init__.py|Is#=o}xffs(1Wz" O@T,d;|Hef2-X_{yyڮ6//PٺUu^-7mn/o`7%ׇпǗ//abS5/k׶ ;Ӿsigx޼Tɡ=/y+RU!6a5Ț퓩lc_zʑWu1Ŷ6Ѐg6v֑Gݕ6Y+S{SpRS1nR5n4䛬gg(T=o1I̍ǬmM]^ڟkڵ۲5e -/E^7jo?>q3ޙrmJߛkoﲣsnL{e޲hh7m%#-f2$Y~D pH`^^[G"x$p7jJ7n~L/k'3oNt@ _^ϵ~meBoU4Rٙ3ݮW( $$~;k "8/l-H4Z+S֐u]%~ ?^Y*ʼm M0a?8 ~͏v )ta K yc*P窬+SeuZс:?m"@U{ì-aWvHbqi06gP۠wq7".;9p3 19p=-NEr#=%rY;j(|Lʽ"ɲ@jY6n<+j-kP`s]Zp5H͛aҀ"Q>MEh]'6 VIA8ٳ2 kl. XHF;$bHl8P;F(4Cmቘ Gg.vF:3 ף:rc|Jd~,.<<×YHIY۬yCnAؒ1h;f"ߕsBSM{ l<5gHT{ 3G.`EJS?Eq@ $S7Fj9PSL C8CW0[?JNW#{qJ|gaKΨFEu9:4֙' F~wQ^tA?VY]َ @^h5AG^}uR[.AJT- (.E^Z!qEL$WDUCQɾ:_r=6V~jt;"LJ^U9q{؟AKʅd%]4ӡ %X 4d(A5r9x~^ Nµ 2НB/7crǪWg4q[}RZP"CRH0 F,0 hm?DFZơujeBLuBBѵEO=>NbCH_ À>E_33Ғ̙Ջ0{„yVݽSxAb 4 aH 劶K~Gq/x.45!e׃}f)stefcXW@k-(}2E )9U)fV2g;ZI [CfQN@1?Lw2΀˼=8m$ bEVgtfu@$K+)IHAc!(6|"\x_,WX7cm I`g;Frwk Ht(RR 26TlH1c؄b>v}d0&So7?@[ֹs_#|PKՒ泆a@PS91~-LO\Ik`ཞG=V_TK|K F[ypDdz)lly.=|䆸C S4s]2e< >8Ӵ?$],f[P O_n`awʍ3Ք,hߪ9£|N TaޯZIj*FpX%E f8Mѷyd6f37يy|ʵyC\Yv96KȌJ =( z ZΛ,V=+h&1\}L1ߣ_H$=ڿDڣmH za 1 $=ڲĤG{9hm@GKF+ 6θM^o[ap`Ƶ]lh;ϖd2K9<3N F2v\jQDy*vWQOh"Io@* .2h@>0 6E""V~ J2 H?| S!W nKDC4H{ - ;y^i뒞$X×]Qe-I!*bݴ0i)ΏŴvnF2 yVl,m4gJd&2Ω3Ƨ0A Ha4jUsgURQ3E${ai: a DHQJvkrpX9e ƨIgh]Iޡg`l;JĔR1eQ@"ӈn a':C&tZ (јp\i+m_.^]pəYzzP!? iaiTem~B"5_on^x}JЧJk>Kut/}jJdi DNޜHT5/1v܎h6{ -ud͎\*\dxbX*idNEjRAbT.~" 89'3Up$@C' 8VPڜLjۧ &dXh3Ź_˩2^N~>ϵSeJ/STzj/p/RLzj/etRB[$nbh/..K192/KQ\CPf2X(/TZ;.^2y nzB9Ҳ G|ULr޹t&+w]gι.%6i,jbNvُV aL~tI'~IqseUM)W' 'ӐiЪ콓Ɂje/57ϢeDn:eH -S^~="SUU)K%tK+p]vX:҈>tTj_'v6ܕ[fB6w3 7:0tbJWlO>jИ1EW c>uMp02b:\H1XDSi]֕(ROH0"0PB\P iD)aJFFaqD)a.R qWJ{~ %=z!Ǎ~gyctcD0XKa'{=iˮX^&"8I-аew4>kZ '' HA6DN|Gu0ӂe W<O&^XO5 Po.Y7 X7k[N5o]j peTӘrxcJ?[}%TRF?"pIU|:X"+Cmȸ$G}*^NŠ: **obM]T2b7&tCfR,,!-ky n|UH4zC' Vn ۊT)4ݒIҰ1a8H3YBEB>c3 oozk%ufxbW>>\ZU'㸬"IߔÀ!pↂxnR-S1"L tXXa[:"Z*^Qkh"2PBGC6j^MPܕTjW˜J%MHQjEz)QܺA+!Dzp^ۼ-t\uYuQ +ߣ6HuMYձy22KdZ,hd&6p<\>M},ԓ_^ٻ<ȐI؉: [[B'e(j`m!X5XS YvG-[d~ro:S%4ƔvbL"c*WM$!,?0a}|ϷFrLŃ2GYus9{J ץD2m0pn"o2܏Ș? fF+9YƄU qzjaު5\FnUGꦈ)_iylɊ o%Z6:b 1(Zb JZ,8BxO<9wN>+s؟} 7`4r:9!sFjuŏ`n n:?[)E|EcX?YAFJ5FOJ4g_2P~H /vv#+H~qϔaहReixS=}!(7Q 8lUt^UW#0<]qz`)S\Ջ\GfOϟ;Nth64y }NʀS?D p osKq}`װL:=y~yu~zXv2g+`pF@AA@y Ҿnδ(`5o6!r_mwy[wq!3qvGe,. PE;/R|Z:2e8z Y8 &\O 7\X%uDϴY05#[]j:?~"׃ݬUҟ~Kx1fDN~3E{~;F HW ~A^zc8q6Dur g >?XVY>uYw^SMǔxLy8:7h \<" _ebʲr{cmp K ~`vEy8H~&jcXt3/ua.Tl ꊸj<ɘ=mWo8gR.n .-qho6E5z.~_-{4dUCD.~ =i{"u낥rQ@k3x1q7YdVEm޻'+Sq?_oFLS}C׏(.z6=#3.u S$Hufw|;~_Ud\OpEtTyl|nG?7$;[Ԅ\+Sod + oU =¹nfc[`E bg8|mMx !mƱT\o|~}:8kH)a5/3ZVO& 4Y=opP\Ł7|KU wAB8`0nJt'@{4C".|`:Zq(.$ZqeGO/⢣˒0zOY|<琒>5Uh-2qK ȸp9@ɨU𐌿CNX7!˱ۭ^LΉ4ѡ5#s PKS L=!@;=g%C|מEey}4$:ik:" wMgt=B|6S.>Kȉ6`kM C[M9Я`8>KŸxlv{ 1f\ X5d&k)eD.gvf*>za1qrB- NV2^MRJQ1րxGW4Ge4iD]~ZkG*pzdd<d 7x[(_;=QN^p,#>`3},B?k?#9΋586b(`W.yl,ox*x{8֣dSrK_-Mpu<$+<E[\OwQd^!:z|GNU4ay/qd=u?MC[f;SK\y„䖒)PV?7~/riκOEc"7LY~?B9ǔv-$-3pU;uqHZ֬w& |F >hj *hY?48Je/PKSFb+{ $spyderlib/widgets/status/__init__.pyMS0vH-eΐ 3NjɈxh"k]}@__IМ[wwVhٲ Fֈ32E-EQk`лƎJ>UTSmԡ8:۾M #9lYH4"u%ZZg$/P5?b߬qc}Ym+:Gm)Q*+RX+6<$:ǵr_LgO"eAHz/s`qhDy*D$(@*e4O#ٳr}sU`CH2Aܦqˢa!f3Q@(-T Ż"zTo/uwULh5)XB #Nq.wœ(&غ ) !FtJSD&.En]A>;Z㛓\VB}w1}%g ]nMvv ۨ gL4}-%-!KgnG㜮 e \tA-,Zkyӿ25b\xm_ Q2  T;PKSF k)spyderlib/widgets/editortools/__init__.py\Ks8mw!Rk#`KVSr\4KS$Կ~3L@ؽFtteD"צ:=?]ߘPWMwV7yZf]^סޘ ?/w7g q#~!kLڙ甪ﺐ]x=m|ty2֙sϋmc"KU[ƄCn]csf64ϝFWm{6^ EUv}q]n,~?M9ǁjY Lk|>b4 7˼0UtiܿMVWE(70{tZu=9/mm|3 6=$iuWsof#xa 覭{}Q}wUC7nJF]뫾]J7|;[?I)̼ȳ7°EM?tUY (elacKα}qmzZИݾs2o!bw7N҂&=)8ĉK-|ۧ4k~{XۻasߝDteb|{$ ]# -,Uz5R7)~_uk62T5xhLy]}w[mlj"k]M8B=t4]4Lh2 ),`0m5VPQ47Wgj1fL}0i+QyJR' IQXAؕvU5Џ`OooD$ȓo!MT~i,Ia+v7ƾL{ǶUsʖl%?Qc܉Û2Wo$JEƼ@; -Ȅc gHUFr.> k]4gl}W ʇ:UT%y /nTI uʷ`gb\|[5ӀrvK0nT ȻX#Eoҿ(@@6f":T6 pUS0^KMNZ BPl\yu\=͗&y7*p< f$OtJ.[SbJhsao7J }1h չ[;Cw%.6R;F 7)Qyg WjMնAx]!.0!4C`ݻh,b8@F^h$dHEʁ^}eI}E G۴KW?.`2$єeCv,2*\p8/L4׫4܏ָ[7t=u6dHlann tgu ^\ȍ)w,%Ϛ󰆖pː=.n;E4M{0ɘvyǔ/~4&(v,߳odƮyu,Ia!=}|:H]7 \I~* ?1p@uDmxU+>a"΁8Tj7M>n4Qd(>G9>,",\!F +$Q0@XH\a+L0v&pN 䅸Ci7qM^ Cm͸vbL&@#S&8~F3ιc0_lD=F6=4UyzXW-5sfp4 rH|Dmsć7 }vtce%h&y5?fI&SGlXu/k:q`j'Zu$j'Cp^!9@cL,f VBVܶthy$R6WBWEћ쾤%I+U ]rC5Gf:>BgZ "%Q9weP<-{K) T)I o&x4?IIs#!b(GMxMygR {aqam%Z*M#F2Ƽ{|^1U/RK0 b0TBF8 0 c%$aQ@*afJs%#PB8<B /|p_.RB84/tnq(zvP$l % ] eT;O ,񰘴;ݖ+y3K'nӶ=WtFJM) I$w4׍ߖ(CV$=c> h"ϱ4IJݰ_O}kL'I:F??hl0оZC^hcpTۚrEcm=湥d$LʟяX|(u*QIT6ߦ0oL-qǂߡK|x,]ZݿX*pm0|Gg XB+l]7XtzSY:GgŶO+[H-괪MبlpUy[Q ^JI!:Jܩvf.-(ޡuOO"uaL&tF 0nf@"ؔ(B#/Jlܭ.  ]}IJ,KuJp\d,>?TyYx~[6Wt8l&ox<\1nLsԓ{_ʦZT7C,*/Q)~[~MUAJ"f`SM6}.O7xf=eqY(Pf{|ҕ*:Snęg*yT~,i!HCXҾioyVJE dQZmp(ᐥr<;$ӓS՗H˜d 6 Y0Jˬof&ΛH֝Yn-{C!ik=E'?{key`(%"{6ݫ0MM 贖8ziLꝊkm$CзO DǣTF·s{KW٭&YwmF)J,j.ă5٘h.o#kmO:}&g v{7v{:iSዟ>gq[i·svtq+&)ÈIs`ӭwԿ@ a{Q~Sgz!]_<y%-_ >:]qz`do)SՋ\Gϙ=~[<>ƣ }.bp,Q?x %A颵Tqzob0Ñ ]nWޛr\3Ůee'Ω=Gm̴(8"M3)z_}.J#`ƜvP}ܶO9 C)\Bk!ک! 3 }fj$X%.!fxg[򭬮Ė!D} y)"LaոUTr(Tދ"~O86;8[1 yY5GZ*1=r]G\AB]&˖.3Wbiڢ;y }}nI `+1e˛u  79Q 䦡-6854v2/wښnT܉~UV}݈S׿uTmx&Q^%D^a!]NKFeQ/=4N z8cL7AqG9}|,4_/MAqM^x@qSaBl]0 gˋ!a@V@'jl_%[٫ЛWYp_n@բJh)>c6@)%eo{_~n-I?yQFe8tSCƪFfxL=*CU[wLʞ!TFn,,wWdbƾ)Fbk줒EҾ=S5\؁Er'tF@zHf;{٘dF a!ػy;qw6W-X۫zw?-el`-tO(IpP[ӄVunMk lƠ۟t2VvR@2+ۂ%%#<:跆_OڻЏ|w\| 9M? s1m_}xsB|vm֌ L..F٫(H.ΒXǁOf.wlզT|uv)dޗ`I>9D=vaP|ydr╢<)|]RÙK.0DSw<9d$Z0$*5ئ% <61+֘]@! ق}X(AZ{˛pXP!x5 8y=f8D` w;/y'dڡy YKf\5Y,@T"[[;Q= sh$Uu_-<:N8rbۧyfջiS {)C;nʭi^)[\؟wOaۧ yjtg=9acv|;V?د>ayOs6W5"qvLe`6o#2X;ؕ!][t[ °J{`eCWڙ۳5 t ][A^)@QYb|6PKSF]#*spyderlib/widgets/importwizard/__init__.py}Ys#9{ C1"x>HR$*Ef_d DF)CJ֯_TNo̚MfY9 _jwҵ]mݾ۳}Eˬͫ U+gxOtqxXo}|w~ 7U.O?t~J&:=@V5'-OM[?11SVU} YX!?:OPyKiӜM5epi#iL:;4zPCo.Bw7=u3K! EI%Uε>-M+gi^򻯚p^Tm[*Txj`~PCٛˬϿ#3zn= sCh`rD:7 Eť].KlYhO]˹`5gL>?B&~|9>L&{',/SFLwWMA-jިץ353Ve6?mc}Aq&5Z19TV3͑IsoC} uԚְqtO; kdKB|ڒu"U)W?2gZκ)vDQ*Qc~vf[>`˿Nۏ̩s|fάsuN|ϥޤϧjܸ|SD |\o.~LUzW; bjfg}QB[9<#ܼ5eS:zg"8ER=T8)#:LC$I2NDYPtVnĿУiZf8Ѥ0"TTC{Q4_`d 1mtgf6ͼRd<_P#9u}@ynG!Tqe (FK&FÏfuwI+P9&8ƅ r0H8/{O\#<μU\x՞/q4_:;c4|yȉdcQԳ3}1ri h@L[x 2}s3)~o{L2/7ğ 7L}ryM8 PC.ţ2O\/YfOqy!]Ov0;4<;|`#M>i{\r{uzsaqTɉ%hjde+{_l;'`,K"hLʜ&(&K/P5[Rm^LQ%:śd*Y:/_Xɏ; }N&J]R - >\@ N˴akYZvԠ2!+/tEZvcMt?w~ܥKDBVv 9ZsEWxW7yO:5?cQig 5s#q4MpZ୵0rx8.ȒҚ V5ʷZ3+Ct]BE.Q6T.2:BpNpt2fymek28hzf،t?miSG/:k_AD2*8*+Yk7VӺªcrߵL-]zlh>؜Fui-aa/92V0o rEۥDXq'jYm%E[rs0fVh ۝F7EZ KKg:nEW$iU.:K)I,IC!(6L\x_4gkm󬹯 xԛ 8cEicƔ $taC }*v=FGSKhWֿCpN0]b=XvAxf䨭5Fp'.`!|J<2{ [wœ~ǫwu4:񚂹v OfK&PϦs}ǩ+gyy[PʬjyJxW&W]$ #Tv$MUnf΁P44SDʩXD>c} :)½uym>|33fK4c@dzEqY5oSyc%ҙQ;Hކg(uZE4kgQ/P/ٮ+pBHd3(s;xy bO!b6_'fi^\Hq65#ߨ̅a--yU?ۖRw t =št xc5ZOv%AWֹ`J\{OĒwym}[7JFhʲ e[娧e{qC9/L C;nعo!k}%*k!sVGhw=_Sx~i#ܑ̭ ȍ)7 %s5 w v[XwL)46u!d1\e v[rgۓO0d]c5sf@W'|>{>rz̬kiwh_{Cg vr;BؕM$M P[eS@Og3{WЪ$݀p-=L$ On@]0x!3^ ?_@ɘ(f8 WuVg-+Ř}So Ƙ;$"HL(üQ"DD>(J А}J 1CJL 19N\<۽c|o [FQ'X!'8vojwT"xhF:l΢HM1D*t959ad+k|p4RDխjz cUn* VhOD˰jw_֤ ٛT{<Ԣ#^y҅ ~8=npMa-g`h샰s-%x$0sহF$G}9GI<׽ ;y^i%Ij*ЅU6٢8Q_MK'QsHi]MinF2i4-J(R}y3ǃ5qp68"8kxfVV4цȇ+GBk^M 5 |@Wu蘩)ێ(R(RJxG3bЫBX% e42d@a RsTtg֕pr"R,r=謨4<E_tӦiMf~@әA@M| :H~Y{҃]|F!.'ݦ QH\lEAGfU֫ZT+?ۇk VG,yV?݈֙!UJ Щ*_Y$ 4M{Z$N8XXC A%w1 mmǝd*,̛i_TL\EZ[m6Q"wwg5'-R xy7ۡ|;wձE VȚ% ϚׅxU幅D)#\yp9G3Vp `P# *(mFc#' k3Ÿ˱2^~>ϵceK/cXzk/EqcDzk/etR\[$f<^r'KыD{)*qh-S{)<^4׌bJ5(¹2C\yUY!\91N%)7K0s&x"J3"3nJ1ɉ{Ƃ̓_9I>u褡b^>:!Ue/5UJ {8~e]Cn<-&SJr@Sj>SUk'_RIĂ26{y]pE2]uIK(ZH{l>ﹲB@}#Yqeqȴ(//k \ň8ߤ]mE'K!R$ Od:B0PBJaa@(aΕB aϧ3%=TBžVJ a?nӼб ?W|D8l̵P_^M`_ K8,&@ÎRC%֯F cim4*N`OnRg&,hNߎ(Izy`YUXG: Po.Sӊwje7_.{2iL,V;===1oGrpQ_JH܀sO栤OCkL-aۂ}ywRncQV>D Vp/ -`-bv!TlEMe,m*.<3y3i%΁ ӹ.}M]W>Lk0D5g<113:`^,s$|z0E+.<rY'~S,ψ a>K|'OE0͓ L+ö8"R ^k:J(!K֙2PBG]q8}" %3!\-٪J닕뮪| ]3zn. c:Ӥ(` fiGE:)QچLԓ{_ʪU|);Q.~[~dw|U}#/b`UuuԢV}&7pf=Y4oyپ>J*S2>~ 0*Lrm&sS0ƾAyXkfUԧdFaPw=!.,JGT&b9G.ɽ{9SF>>>`>^y}iyb\T$s WQŷTxY񛌩Dܺp%3GAqH8yکT{ *Ӏ/>TW%ѳ]"|V摷%+HjɪUȌPZ$6+Rqqy_[Й5w<טߛζ:-V:2:Hdbm4Y;t_ Bxb{}N8uxrBi}"LXO/J:Ŀ\z2(^80{m ML㴙?xjSx'8)NaUU)/D\A.";8v1__><ݞ/9{SN=+`pF@AA@sQiW7gZ3Gn4dn~턼.JXE9mP>\7\v;Gcu# cU { 3hzzl $^|6f|-˽g Hȃ `DnW ݮ´).{WDNɛGҷ|zɊyUgSlNRr>$|XdE5[MOcJiv" `:{E58 /h.opo.9G#<. 4 |4cxwҘv^W)~OZ'l[x T'YWhJЫ0׿RQg"xO ? po^_w_~tM7-?=e𺬠#B:&&_Hj7$Q 1{Tȇ$9UX8,otČ}S ׸A IfOUZkj9*7rLKꞝ%2#<{$|oT`L&Z|{ ?BWtG:yw ]KM:?:<.ԡT>IxSIg1q̏wS[)3 ۂsKaW&ˊnm ?u ܫtX| rݛď? 1m[{H._p]!_?[IP6]ln`UCPM>7zw #dNB| B鳄+ڟ}pG2P oG "ZT?Ǩ  3ʦ?AsM^|Oz RD+b]E (g .[{"qj! .Z;(Ȁ t $25E-2qwKdl ^}dcJ!wܖވ.ǚv[etJZ `5?zE ,=ZP vLѹKI= AEyi}'FH v'oGcO4ϽUuq壷#N91ϘY5JU9:Я t@D_Z]Uu-[Ls95vRQΝs+<t,x$[6 ~^N,vzҮL&زzi_鑮ABN4 NG)f.NWi^ca䃓3sO0(ɽ'" V}zh& e> jKlLvwa.$@ZT$f^e}}%^Lpc9 ߻@S'ɻ3Pg/]"jG\8To(h< F$#Agt腜^-ҺXkv[dk { jiR:^7&`'-'80KsF }TRg9-^8#gK2X 8.K}FG*pzd`- hhEq\O͘nǬZ7=awvh{6jO1 PLO~N~ܖ< nV-99GoMbY?l;F(Erɏ򐇃~POcA|kkww7L|67Y Y-..f,DR Ya-du>zţ\=X/# bx>LjlS<ޏ)|/y' bV1p/v0GCxzv-K%Y"䮵;o e9` qk =f(NKY؅&4/-}w{bGr10:`(kP`3 2ZZ;*_YIN2|sP({:GF_ 2ҋ7r}OaaٸsO]]vS3(ڮ֫qˮn!n.,ڹ ENa[WE@}mn*_柉/H˥un?LxMQ3Hz,U~/_Mպw_mϡ \Biߠ4KW7wkve b$=?+L ;,M'y錶Y=ރ1ӤW>ԥ vtە/l0T ܘҕ8dz[$(JiZ˼YxKUou~ҕWh4J!#i_W8Fτzbſ uen򥖑~[ ِ gzTاvN0d  XJP,;2o^I}ŋ57?g'Q/;okzYހv*#??czo%; Ȯhsoz`[z IJ*i;ћgR7hkU>ep8uګ5o{*>xΛ ?ӧiü [*r׈ቧ7:m*k98jD-7vjWZ1oigy{W[Ʃ;58LWv~v0Ecp]S"7]z}U3d2?H|]?Al"/J;W]Uܢe5M tʾ=^~x'_6.0DK?(bqad͖ƌYܷ.o>-u%@@cxإZn?ay)WΊ0kWA/]X~, 4MCwn}w Y`uR?6SXV(,!?Qb,tԍ2oqeƽDs9xBi=_+d 3ŝ`Miu#KG]r  ]TrEUyRJD .|XExV+zv^pO69?4kSƠvܛ+ZS@;趠$7ge^*D[AހiރN*6 puS4kKV@g1n?*Q`0U¥}{yѯhi4nS,q3@!φQoB.ccj]ԛ1,-_)eT"r)^2S"3+ 0U"v`[ JPF` UI@(Kf8Dz.'^a5m5 $ YocE?(v ~OnO.< ǛKoQr^w c0ȾTntMbbh9Ķ= nn;AtM+I|K`u E_lS*ar߂% g6f$԰sп$D%1~s]î\Fnk(pUP!|PR]C\ Xu($̑Қ̳$Fo !m.VL?$\B}*d*@UBi,x3|8*YUZ13K8׵Mw.YI}WvL>gcO c!„ )M .I0 G C,0€ c, 0ˆ kpAVHt/9HˢY/xto<[FQ܁*(8N׍O"A>AS0_G='[6|m]UY^*\݆lDQ $f':2]Ŕ |B߂>㫃D|I~4aWE==,K&w }曩 %YM0*mƣAL|/*k:Qx)|`ę'ؖ9#CK4$F+p۞u̲$ 'MOʷ6 ;eמ{յOD{R׶|lIa:WqIRb Re}2) eznӼ\hs7 7q:ޟS䂏~ākQ2:ߵ׵WqZD@W姟&J[k^\(.5)a|`_wiRێ(QSF#GTVq¨ءC[(GCaj(|DRVrrbidQFt1TD B? NtҦySWe?dyj42hI $ѼTkR/b=}.U|ؔ҈Wugne 5D[j%Dn[ßuWX&ҷuӟJg^G#|0OתM2`FI&+Kx52Q6QgX4za eKtiO"rҞ"ҞLB|'R~Qx15J^KgD?goNGd@B~ { n G 9?DW9S{>pKx@jgv~,)8#8P03p`  1'#6E:f6LugrLmcej?mcej,SXg,pRDg,uugRFn,Yqe6Kf&qYkf,Yj4Jͬ™1CxajPqf)'8RŔ鎛Me(bg^\1UW|*}R+Uw//VGzĕQӉ'|h8֡_jQE- ?Sq}#a`," Џ## "È01("!OύgFgB'|oLoO BL d< L&8ϱ4I x\q Yc?ߚoгV{ӼI~=6~ƨu:m"( 6&WSKtMgUBm7G6Ue>z!iWU-0fҩs‡y 5;~2T&2[IEjPA?ŚcZSEbk[.j`KN-cA'<1NuPRK\_a4 (&.}eo{PdS}zƫog€M꜊%}16¡[~3i?L|#RdC>ʺ S0}/8=;wLg!&)uazj 0GSӃ+ܬEp3eOM*? 'xG.2 0@ZS`VmyFZF)^Uk&O!ds7KcCi÷RPjN:zR'UƟҹIFeҒY6]YtmFT&w0g3C#XwsWt.}ꤺ?Lxx~[+-.Xd͍l_xu/s\f[TyI4ڕE}^E) ~:uiG/]U ,}S!ZZ`cY,"ZmQx *վ=NSۑ19~2Ljv/*0eY+gnUiFQR< zJ*ۘW)=fo0SwB>J8L1RVtp1 l"u0Hmگ/*ܠQ2tM53%H3#%y1CHݣ"j2EjK**V3lW=VQIVu{+wFM0fIҖ^KoWn75Λ*ފϬNwa%&^aeSvu{(Dl{fwyܗh{jK f:Ơ"zJZ'*m|08G|lpF Ǫ]k\}ڷ\$)ÈIsW~S'vO!g\ |l!yt^' FP=:]q|`)SEğ@}D?ƣcIٝ uxJt':Oa om/ϽX`. rsw~5xx9=Zݛ{WML+bxFAE!@iQi߷T{1o5Ky9_c»J!|2T  k_T3Rbxt\O ?~p`ZF?v,'z$>P\|Mu3Ds]l͈sJwWߗW 1Dw\ }"J(`*FO7:xzvDwmhp@ 8w8 /aĪ <Kեv{5;x:N/#F8kD j|_v::VhN;M+ſP&"kG/P8fOdx%b#tS*?!w /=KgbiU+%!]gJ.?ɻv%OUr}d{:Ǐ VKzR+e:<-6 Sx^{dJC297wYOz#fM Gb NU'FA3'xfJ +@v?yrz+{V\wD qHik:b_'щM'V;½|6 _|7bS'ɿE5(uZf^7soH5+L0'/_VFB` ;DqN"?( 'n{<64&Mz ϛK¢k93/+?ҕ?!hRT\_tnmE2|ȣ^?`YɃ'"ԡQ}~h&e-M Ԇl̓wQ-$Hw)<xI|Wi1a$ *1rЛ<&=PEUՎx36h%8py6V_5FO*5) 9ofK /[k {0k ]ҋd9Q\x;7ѐ'\,ML3㓯UmV{aƯi7WH&pѓWz),8' dx)6[+EŲXe5'l~UEaFԻ U=-s8Ȉ$øYP`?$o$IuQci0By~Vؤ-ӱSR)/}&:G8T 4Q+} ~{c/wz{CkGvE⟰ HBpJB *l gLAs*{(2 bx> ?=ё[{l=-ńh)'h( aI1kї7{ᆫ A5jJ…ܗ /%WѢY˿O;ZcӒ"VCg=v5ox*znj{cd/iӬCM־|sP\,:PV^*-~yNs4d )zP3F:z? garT o\9w\G?{IriΦMS!/&VyzD*S da|S*`Ѓ9Lpzkb-g侰5R.))A;KPKSFG@5ƽjrUWwr _?/w7'C?{:[g[ҫ.=9Zw^_/''5N7:Ε] - /E޴jW}@$qKWnI_unwJ;MqˋMJTg0mS{ޖUnesy@]L(]|H#ugUx>V}jတ3|X1P*OcQo&LX@i?4+owҫooy4ܡ i;wG ?A<b& P4rwkSk~j5Y1?5?cSi~*4nW?Uo?姺gRDY_!m_]qXA*6`\\cՏ*xy鸓龯꾎P| `m>Q; VE߹$ym.5k](Z!UVݡp,g*P9c@ Dx@7 g5]#drUu97?:h-c& u(EVvY{`[Ts[ܺ-J:pE\Oύ+qss//$V%ڱUe`>t뚭a:oN(q,6dY jHOIBZ3k13L߸7ׄ'Lg("A-NVJ]QkТ/ :T64쮲֝8;2a`np[#*+ەk7ftzj -+dePF<Zרk@krZY>޵vMjx*4ЀtC5_껯gpփ/۹/%˝'d="I{KX4^pbof܎5f P7 ^X ]W7<$ BM;}wYvE!bl'V&/ߙk|s0BVu c ~gY2ǖ'H+2*|??5g xp;!nj?=|Q5s;]ʌTzz v/'˷ mqNMY׏MEخ`hPCgU ;׷U=xjoAA<h9&~qYZ[d!!quyʾ0*βG=qԝy}p_ m\[wËClZ&6>kr~,uE崮H'cOQG ^My[Ycn+˺ϭ&JBCԯ$#75H2w0M+#-QLl*׮m]v z?T_QG Iv9PNcZƿu812gkƢZZ O|[ sb4sX>da*ؕZ VGV0Dh!@\օ |&Gƅ,nOԳ]\J{ SI39aYso9#r G7VȤb|t yc@$BX(Z3d #$`XMƲU#-컊2dּBJ @c 꽰7ZEmyM% YD95^Ԏ4U^ r]!Zg(Cas8L#V6aH8USjdJ[ZD M 4\ۃ>d҉vPgj6Id f3Qr哬:pb:q砦4] TP^Ac (ރ_/0rFaAj3.A8{:SNj: lA8>4H&dž|h~>V' ~q-:z܏wT`x4"C\TȈ.WךEx ᦂp7U:##!&4(1I 6ldXaİ`S|plo$1s< K:NjJboo͛!2>, uxVbdu?`fYvԚW}d& Fm8g>2&Bhl4"<7axʷf׸?*]_ZX9fe9o iJ )mB8q 7Y\kP3E+EokgI95|afti_3塡4n7ToN-)e0LQ2#v"ֲ% 1= ׸>s*ڲ]-y=[N|F 5N@ox zl -=V[{WS]yw =5ԧ==ΰp{Jn*qD~=ȅ;\ta5i1%0DjmN(~ӧ`>M)W.zmɌ_XRנ!7qEžtQ:y]!Z +C䠤ҩv~k"ܢM&!y c8yQH3I|(KBN < ?AZ䲍B ,<|ݢ,Qd! ^Ն+ҿ@\:|lcOjEVR%su!bJeq!œ oaa #(.) #.L0 .̱0))\N5st7~VoKo"΋e:&2qm2e8~;?Ou~t A{ی~jWAuBYմMrfb8PN*v$4~oP-{Sf;Q6_VɫúprtVSG!V \aUplqLKk:Q!x~1( *B %$XF)p۞U0 HePjÍ!8e՞IKU%Bg0%0DU qϓsk(K.l +VAx:No67QF#Px3㩮sLY:p 8V"r|0KgyT^5ԢZphNC]՟Q(jͮzq9b&:iGS֤«{d@_rtiR؎(Q1ehQLeP4bѫBE [:Gre5D.\y9}fS$窖FiDGE8N5tγ.G4SN#7雎|D@ѫB,ZMEo=bJ 7I )x]ux!6[PNT/?~ ?ԊZ]o?~n, [*$ܨ6P9%0Uկ.h vuIR# Aw:9t <^1U:A_JL&(o.33Jn gD}|ќrd@R6hݿzJn' k־e' .2:}s& 𺀌b^?;aU 3WFL{HZ?qG&qjX/ڭ̤2FFH#È01("L03#L"ӈpjxgFG~n2G~axFG0Bs&(|ox-{IzfmL>MPmmONU(5.s6WmKKix[?U M|;|yw# BR]|>D3۾'>XpwZpA2-d+:U 9q *;oM5]T2`kmV֌O?5f~4\r7<CI= $q?(Nm4Aپ|Ma*Wۙ~WA:|MZ)bp(_LZ&C9f)*!6Xu]C0}Ks#w=T+jpdK]ѡz-Ӄ+̼Vm΃)h~ޔ!FwtnXr/Ӑ :6U=n괭tǀfW+FZayfmԴk}PNu4;si#rW੾k]3I*MӔA5jh+l3RyfDrC!Ǻq_+l^4tYQ ,LmYա}pHVzZ>ñ1mn`í{ky~_y.@ӳTMM̙JWOGT9SΓ9LSqM A"&ȠLYk}EPw%>.JO5P _ RflH9{)E0axU?HUA^eԟ2 wّN6yf1.GYQ^R32O V+,W"'Y$˺B̚o7n &HΛhɿ-YS{ebv]9 sv#u{=MwwY~=MO 贖:zm\(k}$Cз TǣFå?P7p%ud[.|"ëqiLΔa9TMp4@ PΉO3ovݐO-K#XI:P$A@Wt5'Li.rD<''m T1  BDg#)l8>Xzt)؇.ˋףٽwyVK"iTTxWҾo(/p7_b)z _B^]%DDcܟLAڗ/Xsdu|d&[{#CjVB'תbM3>$_݌/>\K3\#.!+ wof8߮7*9KEX1v~e_\ll+? [-50T[*5=z]{ 'Uw,_:kzJθ$E>y̅>>Y7ӹ11`mY3FVm;GG#<2ӛO zbAxRwֺnTswq+m+4##UB%b)C.Yiר28\R=Zp(>1$*C)//ẇ,oD4L xRL+=VaFBo~G*9CW׋Ǔ*xEwi)>C˛! osm2잯Bjٜ1.EE)W!U֛031OHUoy ):PU4X]ْI0c_'5-y7,"U\o'"jw{-__((x՘p`&ZVgiE]ӭJ}tCN/ʦaC`譠'%|m\x #Vm/D!F0 [rk R j|_V::VhL& AZ% 6\olEi(`'N`giFL |qzoZi)-92ϻkwC@'ӗ\sc+C%?l u2$<-6 ;J+@x !OzS] gb NUAQ0 .=^C% ?}J:7ed=+\},$1y_'oщMVWW^6 _|7b |AɬךPGFUƿJ7U*}­ Wٌrj'AJaz7&,cdTg%|AA7xLzo##w'|zXjj|4opj0*r~WHY {@:l}ɚuc1KZB"Y"ڣu`XfC>%Op hbҌl㽪}q3~8BzY7) }>9[|^DvaQ˷|ˊs;A/&qx(_k`>tWᄓ-ïh1L҈(IidmI,of +(%x`8.ӭٳ@]ZD\NS^~XIIyi0C(%LTĤ-CiR,Nu:Qpib?Wzr~>7̴Mx 17c3NPL=.O.O.wU D2۔QY"dK!)ǜ+TR~KH h^wbGk|nZ*HT!t9{԰  :֏Em]i2ӬSM:}sP\]lťzUzj_a:E|hGUq{Ioqb=u&-k{oazTߟ\%/zW߽lrifMS!ׇL76Y~?"sO "o p *)C4tv{F_n1#]YH(M֏]' Y*;K?E"3)PKSF44<O_&spyderlib/widgets/pydocgui/__init__.py\Ks#9ׯmf|{e)ڒsqSTfv>ʥ @ʮ7;Hux<.s0u>t&HZ$V9~Y݃ie 'hX3v)*~db1_` kh O^{XuӖykwci ,'Yn簠ҞTL-e]%(SNDW9XX Ky '@ BPc gHUF\°>MSvnC_.ӖM2[<ϋ~TzQa3zv^d[0wjf쳗paP=)US,K+`qVf՛zAH ä/H1Be '~QD' &e'-$ i8W>t}}@O͚]wm`GJLfќX?\ch4YgT] @WؙmՃ`c7b԰H.&f+U%0`=ZjKw՛Lȫ](oҳpҎ> y1o`7\qmjA8@ಠP(I4%C=+!H_n3u}p Ẇ0u=LidqBDРH%3+0(2*6fl1QlT1/ͱCzGE eQ8:1hg=xYoyЙӲebfJ KC)nV1:ɟQCThMtWWN$ޢ ;>RGXёEiD(M~Q9D*Mq[Ke5,~̺ˆ{ńL|Xp $6b=1= | 2)! V`5 z_t 4&O!񽨴HݫOpϼ'!Rع=Q,=GlwY !J"R(BWY9$ԵN_*t!['>*j=}0ϵD*N7:O -\X\zK ϔJf:SY ڌY88"r|4gx]ת^E.,F;SDW'#!՝ڵXj7ЁD& hʚDx~P0T.:z)TlGX)IHIT)cB^"*qN8 !z4a!߭UdHn6Hr.jd6tvTD}ڙ)w85?O>muMM5RFU>] !FK&q|eik:w)VR{ou3e(cLF(q/c\F(evRR{$a2Qs\&:JDG).qhsSG)2QJƴTF 'pcTY($v\$" {aJd- &2`sH`<WfkL_kń~;=~,i"Q/Lĝ8e(+JMC=$G5G g>91yT>|S9z 9ԄF"Kr*,^L[e^/hmV2[got PwZ,| lkTեYzhLq@@{J*<#|eʕe3vefnQ'9Ti)Tc^j03؊|^~,\tWݽ*3#Rb${Iׯwb)a'(!l#UBJHD i@*afJT ϔ|2G~pJGTB8jq\*!MV:WG78J 8  p뭧x6TZoKMؾ 7YԫH:A#A& r$ҭN}}6C"y)J" 9mQ > h"ϱ4IkJݰ_O}cL/I:F?kl0ҾVZCipTיjEm=7湣d$L_g, :ݑOso栤OjJsSl2Hfs3tEcTvoQǥ`=V-Vt,s( 6މ7X.to* p?B&ztOkwhvֶ,PKE4g]>h$kjO&fo:%Π_Zy"FB;Gb0Q8=>SCQ(+8UvͶx֝A`u {R"bǽ"``'E6&Z-:E:=+9zNe)tǍݞNg:Y\CV.C`xſ\ʴIgJ0wXl:/Bxb:;C/swT!'|6Fe &҈kZGW#tNW_#[۩ʔvq"فsb}6(;4sE #.@P?H x {J?bt1dlCܛj5\3Ůee'OrX<m3{u-*!F|P}tO8*;/@vh;2cKl;8u ~0vbF ϭVk3$1ۇث'3oi+6R[ހΆP +>j**t9j>KEXa?'?8]~[8[|/hlRrqAN YϷ5,[:kJ\i+i,Y?J"ax xYf[fF; n<:4E}lhr ,J{}LlzDdV;Ը^BISa6T z5 赇kT tq<4z ~(>8cL9}P7~Pet]IP6,6ܱUJSPՑQky_%hFύAo@{m>KumWtk߱l;#Vs0y*kY!QKWKP]'1Lȵ2%&Y+ӊv[ qS=^=B8+{Q_8VԻ G'8//q-ՀH%|Zܝ_<.׌QH،5}iZ@9Z15D_>c /ѱ`wzmdzÍr!L驦ghz6b lS̟P8)/=K:bˀ4XJHxO3m.>n-\=~W̽â}i&E#u2޷$<-#;J @xĔzh!{UwY۟N(rwF/PF28qֈGxSgNp. :+6vY享. KhO|"h[g͑#8k}t"hn#Vcgo3 ORr$z u>U ~۷7$h*T@܁~[NHPʋ7UqTȴ.s[z0\pN"? ,l$k*E#WӸ1;@_7HW~BM!bF[:M/5 I3'/dUmp}[{სc. 2vI!#E'z Z[8'n'#$yAC'rN\U,IP+4uoY@FܽM2 #@³$lj%p׷uo[g5| w?g#n#-2f} _2[?Q4%;q4u_ZP+ٵ|dW &o_v(_P_ ~)P/OcC鱇?̈́ 7^A h X3Do:d߾|x982GȚ }إ3ݳdӀ)ڈWHQ6%.ɏ` d8^vwYYA=`AGTÒ@ ڃ_ǂ29cNO.1ˡ,ʼnO]ɛ>! -* :]:OǪy*d?1ݽ[;Q= sh$5uq_3R<:Ig8r=bۧyfջi]7 {)C;nʭi^)[\؟wOaۧ yjlkZ=ӟacv|8Vد>axOs#W5"q~d`og#2X^8ĕ!][t[ *{`e+apKYo[yMl%ƌ-lzblr`d}r ,yKdPKSFv!q*spyderlib/widgets/dependencies/__init__.py}Ys#9{ C1^k%)*JU,h#XqHwPʙnۗ*">Gp8ޝ<=]ߘbdUg*vunl z{z}onO?鞊|=~3m߲Ȫ~zz3Mk%?%/=97{SM=7d7חcw.[Ζtט[c ֗V?{ckn)gY5N-wE'z5ynYSKΛ}-uc*j@Eϲu}Ź6Uݘ}ܭwnk#J_mj,ljRl;F77ZmeP t=ET D?klL%9>c*{. rm?0~3p%)6}K]fY!Vo`m xfmUf+dhJҊ%N/oHwmVmTeV+b$ ʃ֚͆2RM1M!JUk-lWh ]g˘"}@Ey>Uՙ;fC;1e^}HF@.piczؓX @f@4Jc~M_vE_Q p$7H/b'ɥK@tU ?GWܕYQpڝ]W,Txf@>SWh(>+&2o촽3:2̱U-0!{|f:rl3;ߞHtఽa(..t)?Xbw(͚Gsvz€}%y2rvMwtΠuf?uj󳾵# ļdV1'emkKӼ̪&JJFUw_,a5`ilIwW0mICqپQMW[Vk??eĉOgZdI(T8x_8Eq'*11O0Mq"DYQh&eݢ-LG:MoK}hY,LFɿ<_+k_Cݳ4%x`Y%i$Wӂ;9ǙZքz.^DU|۸k;溮6P k0{nEDʩXDT!cCŤbcƊ9Vkkt[Y]76ؠG=uxYoKߚrDM(JFS2;x |ut:,*/v={hx$l0Ү3pJHd?=A(0\x7z渭}fK?,oYk׬j_`̳Lڰݹ唷0gSiS?0.K@Z7:;t?8I#QsU[*)2>Y'm~^tedFoo-º//X_F7u97dpc8ו.r{{Aa|M}ӳ`M{U[7b;pLt+j1w0w\jaQ g!v&$oarC1fulWt rm) eun?|rG^.q3^sj;٫wlKcj2=.xw0Taf{1P2`UR[b(КmN 9[1YkAŞgB!; OjA]T <Oe=#P2& : Z)Z^lݠgߌه0d5'SJ 7J$(DQb$%FH)1ĐpTa8cJZ!niS|;*NKip|ʵ cxYԕV4,G *ft7(pK&ӕ4R 7 Iv)xUw^>&}ViGbcT/ :4⭶Q.[j1~M(zƵ(m !ޫQfEU꥝Z%IC &J=+'<bu Πp;]W<6^>U,t1z_a_ݾ+1~wkXyˬ*q[ؤ(b^=9!e -JMC J?j]c2 .!7{r%9j Sj'>SUk/Oă46{y]pˋE3]M*Z<}˺5"+ [%*e[,ui.u֎8  !eՑ] 2wJ2v]̙A|@>IGF>U? e{$pϵU3芏Xs]CExy<\#kE{8#D~UE-uH Ӏ ?uD a0TBFJHX À0Q( L0J{~3ys%=PBžUR a?nԱ ?W|-ʼnpY_j,/x"c 'hHͫQXqAj$Ml KH'e.<$;$HzR#|jeKڎuOZauc: ҁ5N}UFLy+TiP,<\6O-艛xSW?Ӄϲ*PG6Ud>>i_Xg0o\-a߂K¼{YZKѱTD Vq/ -`-bv!T|EhMe,k*N"7{̶XZYBZe{@'mШhp`ipAM%񎐓vzXwbI[Ϊʺw u]0}lƆKoZN;sS%ufxb͋e,'"O3)C-UV$> bQ~0xN\*x.2ɶߞ>#4O%eZ3,E1`NӇ4Y+%,t}9/OĜz0,WKojRrIO|F[Oei^%MHQ,Ⱦ,:6% ;ېg5#%xXsWt.>ubc:%ЕjT}>CrL2GQus1{Kyd"0pn %گ/W܏dLeesfF+9Z䙄@wRRE%j'J#zSTϴ+/(WVYgM+9^pg+ų[qGX$wrxPda1Rd6k—%G v[+;ww:iSgvkLù݇@};@i\$3|;in쳵wԿ@ awO9^s ю- Kj泲+ ?ez9qg>ojp\Dc<͹^]636^ǔޏ)7+XNuY_ͯ.nNߎFTl% \PPF}r;PnZc|T͙9#z4dNKV * O/d]pGe$羨cgyyz, ƚՃŏ="aČ>ڀ^ drI.^|.fb-+u鵕;'."' ;kvtM޽}a;'oz~goņ/OɽlNSr1$|YeYcpF!:yL>>h7xLpoFsy;?z:gGx0&7 ]^$;V4xx^wҚnԻՌXg֬}{l)¬+4*!H!-kT8\R^/`@rpퟔ1>`VÖ[{;lޥ#9  d6">]Ol>crS]i~_/Y{㶫{9j_Z?D"z dH3AƅR9}~B|o~GL:rWKM˫$/,Cg p)߳CKkƬ ?w/MczJ{xxQKlJ^tL<@' cu#F}7a;8&.5]"'saJ+K21co5nPQ~"i߮ 8kw54FbI$@dgoz9d^*lE`Gh(VW?֗u~:\s)0I<f'^Áoىښ&(@[O ;]0 o*8m|6uEm5{d>nWnXθgb.n V6έpɽHWU^kïuϽZ@(i׫ ޽ \2{Ӷ>\˶C fȹ'm`D(w(vཋȖ-[A ' fM,VlU|uD\3Eܪ]7(6\\,DH^ H%D]9%W3Wqw-jv~.ECr"^zO}VMȵ2%,ݶIȰJrwǷhscfVٻVԻ v}ϳ/!D XKp{5[_<~4TYYSgZ>{.>Kȉm| tU ~%7h,T@́~Ki$(UuٲW4<3 a'5 I68'CAGB~O&JqiӁnXh -O(ZMβ#z3ag+RKq,l"|pzfI2ؘ{""rlѧfa!^&Owok]֟e;x= s%J߁𸼧RyQI1aQP^x18|w<"[%w'tvdpeHRa;|KD0z  r~BWQ 5:"[kֺxNrE֐s V-m"YFDG9\8;7dѐ c\BMH㓭UumR=aϊ/3v\K)CMt9}o-'oN/#jRlHpNh%#$,yC'tuKsN(R &( Tݝ q/s4 Ȁ$Xy4]HD:N'fB]㼾;7=aɷVVwip؋?q)c'ALO ~N ~ޖ"n6-srg9,$Ų~v\*KN"Szq+⏙:ǃd :{_1`|q{b]$Uu!C``Vs"{Q4@: Ը٦ۚGnduGeHm&ˀ,PJ|DB.d 7x[([;=AN^p,# []ɋ>a -*Kp]:uOHEUe? >v5(XqTjGpCG=v_WkqiQ: ep=#V^v`Ez^EsxBd ==MC[eHݿ(xWˆ䖒1(+p\G?94g31!EuּP@zFml˫0.IK nU{'e %3vBk֛F^xn >#UXh;tA BN˗PKSF #ϐ-spyderlib/widgets/dicteditorutils/__init__.pyuk0WK)`fNPƸX׉YR'yO{$t:q6uR&HY;:XƬT`14{~R3Ym/)(>wߋwczUɹ$Ha?<>82 j; eh<'ءG(pBo,:vq yL>Hgz7AlQV@n 2\>6%ͅn0ܡ>| X|4ܺVM*|$ϋf~Y>5b«'y4ͷf×p0'6B0KX!qT&ݵPg  Q#ӧKYD^?ևƤqwmuimğ&H>TaMPvE>5ﶏmؙ2`Hh7_r"˿::?U_|_E.uޭ|1 ֒\ZoӶf#xbc>"[eoo0kS)M$p/W޼hoj3iDfF}gZO̤!CMw0nfrg::0 a0e)q/䖰C)75ddS t b"t tEӽz7(vIq.jrdš4s}N;}5ﲭo &dMI Ͼlri?j{3 881*-oгnرo81kT=uVֻw؉W1/\18ʝt4yd\m﷗ T/[A@DkC[惐J#BgHljŵU~-1sxCi[-zo !iZLB- "37X ~BEwVlxU+>;+( sTdY~4`=KPܵG8&"L\"y3pK iFĈ IcbL\bK01qcZ58#- :N3θ,o~\qm"βe2 R:O <xحQL g~t֢LD6U"U{^JU f%7T6mч6qLfy~JA>X6@!߷0sNvUp2o&x4 F]2>#E`O򺽬tz"O3PEA${aq#?qn {yOxE2MIK(Z@kl>{@x"+c}3ݔ7ϚkđՉwlň8_}mE'K-!R, OdZB0RBJFaq@)aD aOaJ{~ %=r!ǹ~\yc~tcD ʼnpεP_^eP K<,&`Rc%6/F ciUڶ{*NPOh<ABDr'mGtxH4EI$`Iz`ّ>wUKKkI#"G %q+c:qґ5NmUF㉖1[WF)7?j;B2gs<''fUU~O@)Tx4Iu|j`,Uv[ҷ9. eo+kEǢPA>D 0nbFآ76shShplM+!- 7*~<-X(\{ )$M'fEE,A;N >[ćX`obޚ&{J+;cn+RgcJn_$iܘ0@ z;ŹmܩgՑO?0KD3':.?13:g9Od>ݙJU[ we<sE`)Gg 0uL|2ۓDTa[JǀWĚTJnҤM nĪQ|gN mC: ` WKo҆b HWm= 714iۍJ0#uwmJ&wА'Uc%xXw˻BELe:1K\!&}>Aܷw7R<-V7wpԳY{s<sWhKzzrO^YU _,*kNԡV_Uo E `3wHч݇+o(-|0Ov*9P+[ ,ET"S|/$#8:\AgD<{UT =Bio>TW%,S>V摷%+Y+ԒUUȌPZf$64༉/k޺3k" 0y17=VLPy2zke,*ItgY_㢑 u 贖(zjLꝊk%<odɄ>sS[T;$\JNtg)7WH3NaVeQsX$7gH`1R$F ^v6tL˂S-w{:iS^gvKi·swvKSϔaD9dӵwԿ@İ(xH/79ĥmlep^EIW#(:]qx`d/)SE=Ȟ{CDQތ6s~YO!E36ʕ^ҋ-Wg+ 5]nǫ{ukӴvE /((#>(wNx>*mL742;K0!/J">]}sGe,w}Vۇ" ϝ0dֹ# S cf[!aČ>C  ֤rI.+ohMxg[򵬮MaΆW$Y 0q"UnWQddʧ!Qy7Њi?ikmzwȋɼoYI%G˽ |>H;|]Ȳ'̥Wc ͽLw)}l 3Pu 움0LMC =^# {ܚnTթcMZ.c+¬+4C%UB7D׿RQ(pKitO;MI7'f7Lv(-=7lfw*νKNJ5r5?5'ۈAR2jf|W_𗦠K^*ޣ &$϶R y3Džr齗 OIxGD\_͂(/L!VjC(ztߺ;1kyk5V%?75p7~LJdFe8t.M 0V5o/F1{DŽܣ">TEv$9j Ti`id;%3E1m_c5/ov`1]*Đi'׍M|kM&Z|{ ?bWcʲr}^kXKMɄzx8{)X/iv տn=s\$`{ف[͈{^h8[)=n` ~nI;LU`YѯƂn+xϾZQрUmz&0wlGLV^}@P\/ێ. 8νGhÿAU{g-[D ' Jff[4=_5f/-@U4|x@ϵq?oc!QWV1yIeUU;upG2P#\wUUj-϶dGҕ%[1!ʔ&i#Êr[qCO\==d Fjfl4t tlPjM"MDaȣUSh!ob;x~9`4`d0l2'PzK Ah@7R%iLe 'i׮"P\a=fWˌB5D-1q{K2^iyW( R5>$c+7qLcMz2zK;F-[~ʡ \zn&B -@z>x26,n3>f[kő#\?qwtH?xyE3PuaW{o3 R8HRrf D/*nV|4*} @Ё,tUol2;Rgո銚$Zӑа"~OJ¸@/ibh kg0s銇$(dZMC ustRoluKq,jk=|rfM>DD2< I"t|ȸ|ڤ:*Nw($H;wn ]/c(22ar8|k;7<ߕ8 V uQ;qA# ݑ˷4>OW a#w 9r{fT!;5rõQK^$K7QF F.lpzVx&$MᓮVnRP=0しX+4dr>bo[J|yh8:M# Ȥx7 K+EyБ9䷃q_bDQw !7Sup̶aܦ{6jf_)c;(|7;q4~[P^K6Y96Ke}*KɡJg<]z~ ⷙ;T2a` ؀Vf ,bXo~,`"EKv(:#Uܳxi@ e388iMוso%#ϲ $Y 4fe$`\$>rB6adJ 7. <[\;=AN,%>0A0 K _mr ghYYxClݼ[;V!=APQKrk 4x8}I_>9((}:GF_ 2Zv`݋6ϖ.eEz*x)}*Auڼ؏H`. -Gal҅nAwv%.ڑYoyMlڌ.zb |` ns9i|kPKSF-~@ +spyderlib/widgets/internalshell/__init__.pyV]O9}Wԇhg@Z!iBV423N#{ IJ_ck(n- kW+&4LZ3(?zXh>t׻e]P*J4-q#݅%E)Ţ^.P*Do]3U nxE,b5U%%%؞3Oڊ{>W_>Cs8io$4Ur~lN.bL24#$8aؗSPlE̯Y~2w]|pzzz5n(Ѧ[}~BJYCsڸq noZ (10 ~)y[9lNj`=|]P5uMFTcP̖} X+f()(#X2̨Vx60s$*KU7m־ z{ U j˛}Ӱrș'X˃:sJ=(;ANghT1NX;*sX]bq>l繮"R0.Ϛe>")X.e$Ɍ>;J,W9Hbn!E6ɐ܂nh荻QΆŞ]v\2wz'^+P|s$|*G +w4_AAi XBPQTqǺQ<V 4I2i+HHgY"7(fi2rʺhp6F4 KyE4NyT6縐*/uO&&?BF8NGՃ֟׮^9"53%cOG[j)q$1,Ue~h;3DCTAB2x/ORCIG0vSv (N) VOt8CؠV4'yO:I<O<ľdG 26굂;X5/let\. ˪5L&4˿7Egkٓfz Ø;p eڀ 6?eAJ3ZOfCIֵױ(MXeO)?J'MDlLۼ*2]U0F-)o_,#&_e_ސJf3-&%9lyyymD~d5M[ ZJy \:(yx{ȪmF_KHlAMqj mڄbAjJ.m m8Mh*J-bV"pl[I+//{ɀ2@v.l!Mߟ,YM\ѐWQ-I>Z+V߄H |VBoq_wI^7G$.ZICVPǼ~Iѕ&;Z揣v TC͇F~Wן"ü#7*v԰N0yS9OdRx1"\'X>w!k*uM]30 Z8JAД=Tk^3k},DH u]W/z J r<ºo+lxd#E0O~(9s<fdi zoU;'>b'TjSG>x.b%&ͻͫ=/?ԧf~uav tJQ@<xfG|\臦~G#pEiQEG8eg$w[͇ortks+^HH=}KٶnK 6,l:.zc2$ͺE0t* 4&kEo2 |I_=!5&ԑthC(6k}S*г(lb=1 +SogI$AyzQI#N;ӠXP`_6Ҫ i'p3q*J-C$.)hp~AHΨSg[bcW_/!0fG(0=[$RI$gI|Fk. bԇ wE*8xO.7 SI0n}cRR6bC2ku8Kl`hۥ GMP>t))}JmSsڶpNTй+E#+zXn7 j^ uq BG7T\I^ԻUdQ?hHGh#@"ԃN,Ѭ].~trh'͸OLj#BǓg$%÷ފ٭4'>έ5t 5(UQ EMgɴ@_T(zem&>R'ԧ@ƽ:(/ 0؂6~󺑶OFJ֝Ll9~FC[1˛N1ΤnY&kq|22e\~zce}D)G*^]vM|cE?}B]]?\adվAZG)R8F.{&9I>~P/֣1^>fQBB5 3FPl GX#m >@푖=>2,Wٮ"]ck% abo?ثx,fp#1 Ѕ8ynf=,L"}PXjrmؠQ 0w {hn@"=/c4_,[ăƷW^<ǃ#w0sH>BO.p;%ZeʼȒXW,l!ᮦ1jIifjq+]!fd:00 sI,ģc,81T׍=jsS7݊V(v!l'LRnra>LEQWJhw_>;yʙr7+A~V#u9L`zLG\|oƐSyG+[Sl=r 7cc篯HNRil2 NP$sر Gyҩ3 ] ?|rTS=_a&m07z tdU$}G}ۘ`$n5>; <{+N<蝅~cL.[wLEI֘2?R- {4 DZd}:zy"OE==ck_K{8GvG涓 !v/kʩ?k =E}$¹>e߳p=¤`pqe'zp0 QM4Ć{y(h}i;j$B\oxm][v:pB f$/#,CgcqiczMj uqR0`/ɡ;ԁZ \C<{L]1[Hҟ`iTx܏̩o(] ,##j+,{P248=+33 ;1ָ ?' w(J_hOAQv@31N^72]z]٧3.O^n<,`t꽑.dl_fz>{r;HwH:Ye;- cAP1a%h?=;$tMJ*\y뭤`gsivB4HkJ+pGePP_?HPB#.b O8StP3GI+NՂaD ;_*(x[ƓEX싧'z^yGajt#bCaP"4Õy__ue@#s;8Nx̱It d$Y3h%-017t+81FP!ZmƘ72kC6s p0 Agk8BN^0F߮rx/?;ϘYDzb(dVk#h{y4-N§xIҏ6eOĠr_Žqv_ci!eM{Ih렛Pش) Nu80{29,x؀_ő#_yyk ,H^%2zΛ!pW19cL8RB| AT%*,uFfulQVSyհ-*A/E QJl:od7*4Ԟݕ~%$"g k"5QSi&?fL7 cI'/Ts ^:Vo "?6O!kD@zG -g8KXrQ~,KaOO)Ku-+uzA"%t `eSyA~7z v#YH Jia ӤtJh^t '$d8m>4/Dqo/ZD@Ňx dҁh [0->LMXf @6]Ⴌ6$[vUf>9ݗim'eڎ2Lҡ.PA+p@ΠO Y=4M m%[UE)+oWj6 l5358=d k{(Έ;9ax[iN5k.êw֪'pbM}#0>8"tR!G!\ёŻWut {}8opz/䘯垱|+k:ƈ!x nӺnIy(  &0_w6crwuqIFY-u/R:QU-jb<+gAi3W B=#ծ=(=;YVaraaȽL8uMipu92|-φx*ehll&oM̌]CxakƑJy* id3.9w}%!3ӕK+ȱ& 1ä!&uiI4K;d'\8vX P2~(TlWֵqrfbЪrx5T|O{uβFPisؠҳLrA}D2I_zrAL`ո.Gf+f y/ :_zaU?uGVʿ}kB;#6qGSN2 茒1NT-K[=(k(y qV$N=bqΠqB;]W<6^>UGns>x˗FUn~e44$18GLpl'9Ԁc6GN]ۧp*_ƮSez9^{rj]/rj]/p_Ʈ3ezi{^5t-272q4x^]L\/$^&̙+VL\KGg1ÔㅓV /'& Y{bJl]d/<Z:/CÅJL_j3J;6up83 \W346E, gfNw9 ɶCF=d^!{~h8$x*VIzSz>ޘzz^99' r ΢.7tU4 M^0˟.{ Hy~Iי[ŶB$QVPYg.o|? ^ =8e.kW]V6fj2[i@-tp3pl r*Эc:o}lҧT7|CU> 4Z#NLAG<cǩ5&W)l)#"SI.#H"#H!1qQ:8@b N"C=?s<{~a/"C=B؏+q%:0g4MpÉ%J{Sx"cŬlX?,5v5w56kۃ*Hh<56 u'tf[$V`|ɡ>wz^P#Էy"Y^:`Z<ϧQmW/?vv&Bk(w===so3=8WV~ӳ&xpjv%n`nf+}˟n0}ԢwI@GNJw͠~#nCIy' ĊBK>P÷Vy*_bȵ,5)6ui}*Vcʚ FI1!Da˺-.ܧv)/ɗA281XOt;aRWFwh1'(tpɵNVl}7Ŧh9q;:7v~{Ԍ8xMEPCh-̈́;{6bqmp̀6SpfLZj^b9֮l=7eYe7*qt,!lsHcr yr}=|ɇϸ s]`c:Įv+ԍԾ|6v~hߜ*K-ตߛ}XRq7ֲۢwL2fEV%u*HΛ.ފV?ߨZeM6¢T,[ƚg96mz(KDlm?͢;۬]KlsjKffˋ:eƠ41~tuWvJ>õ݇@}; $3z;i$l:/`x!<1Kr}L8lyp^$CDB+F|=OR]:=({|Oe< /fc}aϹPk)< zx [pqþ$ba:?Adsoto,i" /Р !@s*G4׭D9Fmb p7@^W]%!P9V;*c}ZN0A_*VԓdLu$};,ٱٷ䧵<ivL'ޔ`4[27 x]CmZ0iȏhs^#3A)sۯ3a.*u#Ux M' EФdC%U}/w)ii`t婥{0ÖRxvPatݚ yү^B/IL`t]֠^Щ@nUDauctc}1{Tć,'saF ++7eb}s0z}ߜ2E~p&([`bt$8!{NijzIΚb;@> \.@?brGY_YfZ_ڻp`R`@xBR7 >I'^t׭ghSl tqjFwSauZJpX t÷s+a9lV~k ޅ~r׫\nÏ߽}@P\W/ێ. ͈s'D(x,Esq JfƓ XSilpԥ1g-&o HanGhv@f (ːݑv;C΃u5ab&YcÊz{G*szso`n{;d;»B8$^8Rs)]ݟ_,O.nF#|3uSjx_f: :VO.{rFa]Y3hCh="(}lO'KSJfX_!w/I igJnAό3)o]l(CE>a.yޥ~ Tj鐢4T.1O|K4^iy%( Sw7!U[za _ͻM#i0CkDǢI Ӝԓ⃄taMV9l rWJhS^0sЁp|ūWUe^0dK=0.;༜ԏdqES¼zڰeMˢk>  ӿJ8aA!6j6 =XKȃ2P0ۊTOEM9X\0ɽLizG_$tŽ[$%~T"?^G=l\ $$,,Yl9uLq`4@#\rbsf^n9d#V;Ah D>"T7S:(xm@Vipؙ?i$wtXy4L?%\?Q4FN ?oK+whR)(z6ONJS^r$*}F#+":M1|x85" tSAzFr:bFvQZN/wBp E@t D!C`A\bx> 5m9]-FGFn?XtҲ p:XH|$[ 񃥞켹 7BⲂ+l~rpԀ$'賖Goj'$%@R^:;Fq\ƬBu*py:c~/A \;ғ$yz'j-o9R<:NG}mtPBQSȸwѢdtN/PKSFsM&(spyderlib/widgets/dicteditor/__init__.py}Ys#G~f͐5$" ~% b"ʃ,ok=ֲL21>ÏRWۓjtowUݞl-Z.ۼ*z\jnl'g~;"׳~jaMuemPVpOm>yˊ.ߟjbjS.S_Bǟ~{<+[6Ӳ*Tǹ76+mU*{.S}/îVviQ&_B0͛'die^`~v"_fUmeGlJS~fhk]cׇ1  OWdMsr Byw$dgI˥ٲ퇑Md++H zU~-_uՕj]VɚW [mmqPrbSCIͦF.uij$}sv '0;TP#*z~WؘKbͯfc^eY}zUkTiQcu^lepo yk1154c7gީ@Y.]GluWu pkv&+:Ug2rvHbfla@T U (ԿMnceﻬ\yS[S pyHbeV؁%< DR{m^X!ykHek.mA; j1%y螦FBi]6Vި8KNk8]/b'f%ɥK@tЩwU<&gUV< T2ʿr' |8_vޙc`wwd|Xo{mу/yr_7gf3X6dv=Tia;P\Ṟv_&dޕ8So4y;9c <_̵c} BS{ﶺP3Vd OyC8hǧl}ZOKi>-?hڴlcX<9>gff &G9VE1=Wf:Ŭ0?ʼdVn,'Ӭh |WWH|ܴulkOS]K9n~Z?[<2}r KM* RVg(mV0%,=PK[b:Ҹ٘olayʷWT9(Pn;TԤepuk2,h/ e"T PQ@J)UW{|4ynly`o6P$ `}SwE@Պ-r5ykv&]0W*y@!,P" 2:X| Z/N~8y9ç~JYQ??pON8ma`M<4Wr5ә$~enLrrӤazQ5Rè#;^-}SDfi((?=_J^g aTct:?Td髿@M_WZs:P 'sRIN 7f,{tQJ*ƍ1М0M,Ca!PƑRįy+ceȠ8%QRTsߥx x8<*w]*\{/7DC2ux>tKMc9n Jt:灉&>L&~fU[;Vj.LEr^T4\[%.acZu,ij.@koʒ u#VAMQU GEm%>M\A͵5fƥe簟ǦdKl{urePwEg ipӤ?AϺvЪƔ  nZ_߫fC`sEW50^/j4AskCeC?Lx5.8e- R1]soFiKnke* E\] (.:ݶ#+MJ˞е?#D7aޛtӴ$:}R7Scp'ju /m mt~ L0lVpp3;U\GF{aqwzx۟{iT񚂹`Y,܁^r5?֝WsF b;2waYՙo~}ו s]ۜh5?b"TXXXXXXbR@!cCܖt]k^[TUm3ePY:܋kidFJsMqXEPQ :[@R3+=-qO.@p"]gP*Ș> VwjomW3W0J8Wa2iFY6,j9-[NٶĔu5~@a]`ҲܴWxc5Aq:Uq8@E³&b۷r2a2LڷK‹7Жunݗ/;quf2U4뚖 N}f8 @`zv]XT֍Zȶu^/]mip%jK.8"צ\cdw|YWl۹ly. wDS7kLu_ls{nX@ˢk%u mzxeLQ٫mKcobוKk))[m.nr,ΎW!Gr;RBʀWIm;K@?A(h jsbjـr-\(; `^5Xgws$=;P2& : Z^ l]g_م0:F.LmjOZʂDtB萈Oh_ mC"==nHO$'g &2(1>8= @+ :͖ߎe^/Kap/`̵V cp8L{R*όUB)rnI-yQ dFHU垇n#q*aA!m) #eO;S^X-P-Ic[6ҬnW0亓]تrԧ[U;Reda?$C[w< ?Zȇ68J=bSdxFD;nC;cԺo0 9F$G GIg}!Ah0Vk+XdiMjQ`Ec^mh}"?i jTRz294A8&a^B3/J3\#e%VJR!%UJߣց?Q@ a':3J&tZ (рp>kspzU '"Jfq@gC^ߧ6_t}V7ӱOd5*ӀAL&tς~_z҃]~F!.'dKbڑ8[[U닂6lTo%-`HW~P?&Ye$ !{5J yʊDU㇍p$Wր{~gPyx.+q/|*q/ا{,y=7)Uz]%r.~u9ys"ub18@ap;kyΚ:RҊ`YZ<i$2z5Ps L*8Hh(H>R0p KT)4^r$~I/cHzk/GX{){k/X{);b "q3R4^]&K1DkKR"fWjN VeSP8A(Df4/mR/C.<'@Z:/0/n_͕pkTIN;kΓ_f+T :bz` hᗽl[)1: *6 w6p8(w903W'x2ϔ+AqR{>ޘzz^;@ l"ĥKͳ2h^/2uVj2kfAi^3*R)%.K+pUvt3A}$.s2Uh+WjFLn_f\W:0O:0~͕}=WV hDĢ+yH纆LryF1ph-bñG+QRG0\GH֑*!}%$a4 #% X ÀpgJ{>Q=?WB %=*! a?.& {%ʇނ]нDLu2q'8pXLj.K Xu7YժH8=F $::}]C"y!J" gv<&^8XG Po.Y1 Xo7i[N5o_ϴy2iLrL2GQus1{Kyd"0pn"//2܏ɘ_0Eȭ;Wws3 G@RRE%j{ 5W%ѳ"|V摷%+HjYV}-CiK%ەY[RUMYoyCgDaX1םm#JA"wezVQKDle?MVwYɊHLfxZKAY=&NE6Dέӷ D,[G9 ·s}V_Q.Zu07Wxbg}-'7rxPda6뼑Rd^Y2fxL˂Sۍ;)~δU3:ȉv+mO~qϔaD魯ͲVޡS,/'ݽGS'z!'G 8l㋒F`>++xA_OS̞w~Su?&is+M z8Sþbs]nfWӫ׃ѽ3$qid;X<vus{ylp2'v+WW kWA;*}?Ejs<#΋c!׵7$44/H 'fH_:Kr]Dϴ75+]K̆uW$f}p9YC \;(+a;Ѯv~b]/ ]Î=ALpϽǀ=卺fA;(LMC ~Z< ;{yiL;bB2kVn{&¬+4*!H !wV5*ﹶbvopwVaE9l{`qܘAY_[TEKdd,TRay{S&fb- */\$E?e琪\1],{vȐm[/Q[7}h]<¿ _ebʲw*VO+2v.4ċp8{r 3x^ԡGzLعsIxSi1+np 'ca2w+r=sAp[qn;L3`ˢ[~=?ӂ|GNLV^9MÏ޽}@._s]4C=h ÿ&/F(@]El` Jh{>IP6ln`b:r#5SQO%hBhϕW#VH@,!&/=1vGvǵs)`Qj\r~L]/AGj&Zn$eXAoV%9Xػ` 6^Wz+N? Ȣ3j17 <xRܽy(^ԛ;[\ca3SO}ɘ`+>=4D 2yʸ|ڤ_,Q;r, P<=M̳R`5n,;`I߰:-+; uUi22p$0Sd$j 9XV?D(vg֭5k]YU\V.,@f`28a ʵ'D;2n=uzaP˗|MsB+A /&ap(_k@?$, Yܬ}ogo uT`V%@fY{/d?ZU9F!Pfo+ !duGeIm&ˀQJ|DB.d 7x[([;=AN^p,# []ɋ>a KKұ{bGrkVaU*P$|aנ`ykQ=d=d $]U˿Q Y('i_>9(*{:GF_ 2-ҋ^3YXeg(mc[^qIZgvtw;)K(7Kj'f53R]PVV)PA^*7,/YÙ#~L[V?w >w >?]P ËS*sPKSFV (_"u)spyderlib/widgets/findinfiles/__init__.py}Is#9=nC13D)uJJd" ` *T~rfީDzʊ^j{8{zzڮ6OOgu{Vy:ܴ-?`ݼr[?ߝߜ/}&m^6YkZkmm_Cn!3|%/L{SGXn?Ŀo7?˝ٴ>yi0ېd8UڄmM5y-o+SF/]ocu5"/y̷Ky?U.߼f辴o]m8hT86#JV.5.5+-U#[-;lak`Cco CaMlL$~ȓeٲ4Pkc~7NҨw;#\n򺩲ޟ/x_xa FB/*5Ȫ&(dhvgn>+wGdn̊| n^ ˲8.IEk.Y+Mse;߽mr`y{aỲ|PC{ÇM v@g^4TK0<ط&luFVͷ'tJ+7] 9M(k( 9"3{xNs}/-P[ܯSxlrݴ}cJ9nsJA|Sph[G\oD u٘=q@z6&>{6-"귑Tb ڡy8I=Xo4Tb@_B/Ly**LMvڮz{mBkڒM:̙]', A3;)*f?@֑ VQMl*o7NRJ1b )1EJ'BO_Go+@!N<7[?v.?w|0n0߸MYms{ "ó`[x?P2%?eټ$fdGNNJ),lGHC,A5C#ScsFs7*GODdT0L:?!14hWk%R\T V<͋}u8*]a!HC[+"ߢnJ{8?VUNиuWt4Ei -xԟ d(dxmG Ӵ &zh|%ƾHꑸm}Ȋ󃙹4k@i7jc|!h`:ܣk7&5+SqoJ̅|}$_;M~_K̉p~4*XfDž˾I 3\Zgxw0TaޯcIj*FpX%E f(M=tMCAgnPC ("}*e`g '2R|"8(YTpʫ2Z,4g_ G/zdO3ZcD)%R%H(1@IJ 1CJL 1cJ%Z!nyvUoz^ 2S|]dAyAOqJ(Hp8ՙbܝsa~x 6QË6լh㦂J1368 琶|O&gP^;/P/Ic[6⏦ҬnqSgrܡoxfpJ-J0{/jRQT&1-/D-(Op/C@O bS8`mDdLVD>ՂF'[yJ?* ;y^i뒞$X×]Rȴ"0_MK٧I sH(@k`)f`.βbtiS9>S`toƓt8?sN]1>IBW&D+>Tc38ZXTFv Mdkn&ׁH hypf(_Еzfj&ʶJ~L+eSJ9'1VqE!M P3a\iɶOxukSK%4BZoTkXt}QӐ6jڰ*M%SJgEG&Dt<,E9>GMbR]J#.^68$fbڑ9UK!n]T~ZL/?ۇk ^G*#|gŸnDidA0/WN/pBWI<r}Πp;]FW6^>UN_OX/{ZUS"HknW%r.sEb/yqޏv$@![hkvD"ÓgR#s>^.U 2HrSIOq_@9֜C (8pDd,D>Q0p KB)"^Nr"L~H/SDzj/'T{){j/T{)Hb "q3}E_{)vq^I\̩^JĴЌJ-4…2CByҪq '(ԗKp'x_gEg>%bq :OZ~P3p\4ELK#1'DԿghl &߻V$(`YH&ϔ+:|R1 Zv89WЀF<+㲗gU S_4U^geӗ^,Ҽ |di`URK+* \nU=V4" !e]2wZ2YA&jL_ u~>jCI'F~D>S3FXs@e|y<\#E8#D~uf//%L#(H'1PBJGaaD(aJGs%=PB<\ q/|U/RB܏,/tna( vi_8 &@Y e] q,ᰘ ;])~5K#n9Up{BdiItGwt0IY }=-QIzȣje+ڎaHZcu[cZ ҁ5A}T&B}+ƔiP<ݚdM, 2MـsO樤^H LFvMn |\@V@%aނ,U)Rt*xŭW0P1k*22u5&p1{00ۖbie ii΃,Nʔ_kU? ZQ VޥĒwkI;ME*Á;[ީC:6O^f)ߖLlXkǵyz@]Y۹Ƀ TqY_*tRֶmR%[ <hgq½EW`(g3UBӯjL'Ɣ52œj0_˭$!,?0a}|˷FKd<0`p}E_BOeȘdQ3rÕÜ,Lb»U qaA @UQ|􉢒*13m2-Y$RVZL!3f6^K[s*ΛͿ Ynpa˲u.hq*[;4Ok^̝Pc7q4Y9dͦ+֣̩̚ >& NE6ODΝӷ DgG9 ·s}N_Q.Z]eu+NVgQ9@X"OrxPda6Rd7>—G {';w:Ril3Mcxž4.R>4wYl: /B|b{}N8uxrz7w-K(js+N =<(wNx>*L˷rm8 2l23 awwTFB arK'}(8w#  Q8 &\O 7^ՙ\/"n͂q. } yh+ݬUv:2.apF|XW=6^@֛ l^Srr1Ax$||08s'1%4{E`:{0<Q 0;y uNHazLn$?U4v "/81~Yeά}S׿tPm|fJD%z?φ^J{9lHN o2ƛNaE9n8nʿv`ax]`Ɩ'À)#d\(*Ol@H(-UiRGj)"|z>˭2\(z͝1[yd7e`^5XZt)e `7*D1[KaߌbX G|EP8@,Tcy{S&eb-*/\$u^Q?𙊶64JPS%&M Ơf{/8peV!傮`w\O1lSt[ï'~\|GNLV^9MOoA> Rp]/.X!玟?9Gq\Ea Jl{!IP6뽛l~`b: &jtTZ8g$hBϭwݘ #@]{$I~=R;UtG*2o'":TW٣SWK wک V6jVު$ {z|ɿl-jmo38|mMx !mƱT\ʯw׳|6a FlYCJ ;}iв}7I4FEa`z78?.y<%;p!FP0tQ7 =HxY[a>w0HW -k8#'Y۬ăO/K>2=fWKR[Rң E1o)7<;W(b wȩ+9ִ{ {b0 f9"){xM߾ χѹG_{奋jCI褍' 7M͙4 Lgt\EN$A>_k(ou r> ?s_q|q*2ͿxCIEMp5PhQrߓ\a\ڴ'A8,ILq.ʾHW: Bި4 \-8 PN7sb@r>M;“^,??t;(Ƀ'"S΃;L?"bX{7zM =I.}Pβ u=#ȒkSx\=PyYJ1 aQT^28c !q?7,xDzpN_JFDBU;zpwHVFUXe3JMDBhciZsv-=Kj2:^7&>oS?B4C8P=k8D&/d[oUs}j[Ek i/M+(Rʐd]qKG| Z;3Z hx16K+E&X39gl)~]FaF[﷞H%Nob@yZ?lBB%Ap $!!V7Ss{g[?=wNVipğMYwxʘyA}7i&~'Iz?C'z?oK [799GoMbY?m;PJ?_J?Cf)C8L_[ǽd7Kz{nMGgYzyvqy6_]dq.P̶!k00 a SƬY5To;{B^/;$}1/ Su➗n]^}@ @VNA6j1ҸΜ7M~8np8%x}a'N_X]ٚ{i?Xn[O4B@.M'RڮɋiQ0et(!Eu^mo{Մ#o]!;,/4ZSo6nAQ0w)ARҶ⹭󾣩qiJ5<A ?^vy)ʼ ]ޭwԯE;xFϏ^f^ -ucy <^v뜾$5M\:os с&w_r7*hnVvQZ0K~ DRfC; Bwq4TPP 똜P bpL  {g5so>V{!^MdY]F?ryT?!%WƼ& (x!h*Bc ==a+fܠarFJRT_# 'B8?5dw.1pnSsLEsL}t,^ڶsƥM.=QT.pƞzǚ;*3-ˢqs38P>C|yה.ADzߺFKr"</ǃˢ"1꾻hf ¬wWM=IrSjziyoW3dkke>BZ'~siuSP- o"SPBFBJb0S ZpIdrz^ۊǡa4f'#v-]ۦ˵#/_#./,@n{H]|~ &fN67*Fl$mSrK)IQ ?q}a,&t1J4 ۃ > ź}l쏃(y6N3|+I2NQp5QX"^@?ߙK:n( XSw.lk6׹pi0t*$70\6xSp3 7ONT\I@^ZzƖ-;n9KضU b$h r"hh3`y5/?Ʌȩs?\,C4PʥNQęzķ6y>a­u#anmuI.44BD#iPJK26TlH1c؄b~ZĿXcthIcdr/5eMJFESuhT1:џa5UQcib~L-h%5t():dw)8܁үJE&渷>|f^\qZ˷\Qo L'')jWSiiDh/]Ht]E_\eWkԚEQLQL ZoN,g׾zQt] &dLѿ];^}k.|&PeTz3PpC7&W[e,h>kvF5$0>+ie]OQϣ"^Zl~%@= 5/=0rON 5VVX7st5&724-9 h2fm1e<e_]p{j:MQJ,?e:O?@vנ̍7qz,F;ֺYvG0N=B=x` =ReD\;-up!j aX84K_S 0 t9{1OWEcgBvxc7-ؿ '2V|*8C@~ cp WMvI:7Y1?H1u<SpΫ[_epF";ֶufovsflp2:e9 %3d.9J0W.* ~i؎?K3iV).s/j2 O: ON`vX$q`jk'?8D-> ."hq&/zd2Ǐq"Wd:^ S!W n k[f%% (pm@l]%QGf_|.w?gD-.җUkh?gf΅܊V:%_PUhB$i-WLzx4c>5"+tcv\xT;}1U:`-*e+L"mi)isy?gXvMR(թeVȜ' υץx,元)/\E2p L )8pDS JSmTD mT{9^˩2קr*LSeJ/S8EI/S"^7\h$\dKqL{)~qi/%.2-sej/%_dKɘ(B.Tb * VĎ D$ALfܢ l(C>=@Z80/1~ '~;͓_5>wuOIc1DR0wBAL{JLFcKJ?jcc1Ó!9˲6"WdG uJ4c= r`Fqr,.^MSA/hm^i2K4h]NV V,| PxH.wCm0H#PRyP9<7_ܨ_f1]3I o=kMdNqd}RT1y+b x"z]^b & ?{Oni?sJrEmO#7WlxﭔȢv㞲D<؟DcE+Y;x%Go]3o2PAH /~3>DWہzE2Sʛ接7,/;Mvu9 "&!~ӫ7<@>+].,3~g{Ӧٔ)b! 7'<AOݡ>7 jZ2]Lv6|htM5k.cW02Ӂr[}Q]j(׾=NC  *Ax ^prFe,:r_U=R`T#>9GK=7Yt^n;xBS~䇖B)܊3T%.“atL7|ɍyY㲂N]DP|"c67&Q 6sT([:D&ρTB.,&Y~Q>0}h<~#<eȲjsmMp xͥȁfxP6&_ښ&@ [px>fcPWfs/8peT  傮` 0bغ7oO|;8|:GALV>^z& ӟ9OA< Rp]ێ.Xn8 >Q( PgQ,;XwAHj&XتM!~uB3E™>!@DG(DTB|nZe2uHɀ&4xǸ?d\wd8^d4`kHƟ!⮭7!ñٍLN48Mk=w _J3p L= MHyk"Cu岄y4$:mk9" _'oGcΔ.t;fZ~v7|;b }dmMCۼ/!A' -X: A1/^;_e펣B-w9o0!3}: gt$4(Y(TI0.m6[X ]uM}&liߺw+ Bީ4 Q$@8E!ex96Zd W>x;\N\͘[g颙,"bZɇ7M =I|Rβ)u#L\Iw)za589VoŖV2:^MRHQ.0׸wrgጒ-oh2ӈQ{t<~O#2t78.xyZtA6!%E 8)uK{o;?ܒ=sNWPKs()%1G\+ bxs >(5~lS$?=![GYݑkD 5f0` 40"KEk 729p'̲/KqCSvoO)4E;qZ4Y,HTC{tqcQr׎BT{,8d $Vzoi2ݬ􄓬 _p1v[" ,Ct֫hN_{湿ʷc?Qg߽[zLA ohk/{^ݜ̀Ƈ^^rY M<ω>g*%p\*`BГײ0vFkFnn 1#UXhߐtQBv2wtVCJ?UPKSFb(spyderlib/widgets/texteditor/__init__.py}Is#9~n3sh3홽D)uJJd" `K*Y;<ٴuW ;8 kcgϯ}7lӝ]i^koo|?˛/gA_.Va9,l k+׶δom~,n~;;; w^Cg6M>ەզ1Xoꡧbml_3Ͷ+7r6Knő/?4ҟPҵ)7#;levǶ\x u& Tˬ'r'{>$E2T8gag)C1+굩p4Xגּ-t i&`rjaO -u(&d2LKm8ھ=6x&#Fsyt>G)Mʍ?m;uW{3f#*ib&G[ d`u-ި;)68и'4~ 7gȳ]_ע ݄]7Lt+e>|@KdRqMrW-]'"Kǣ]mwXtez཭yEBo٧yl`}2~Tb=׷ewv{Ͻ}j/<5qPeM3JR-B2O]|H{ҏkYM iw/!)U3i&j)GŹ` +X?KZpk^}+t~l @"XYsymvzn(!gKyV0ָΗ{)H2qKf):s_p^/UYo[{Ϸڛ}Z_.O-Por+Jpt :.Xvyq2 lŚ^f]S4MWUU9 G =^ <M^|noCٍkshfB~IrSj#ݴoW'#?-rnC$iĀ)CZr81hw> "t( ]$X˥AP s6E*C@0ˢ%ATXXXXXؐbH1cc(u6 }'?ʵY#&tsWvˣ(__rî7QBd(]YO:V') *Zjਚ™$X[v]S@>?FсCiD(; 틫ܘ!Rlb f\f^,u5O|EAQهQ&$2m=1=w| ʃ Bh{ޔsuv_ܤ s*ڝKɔ=;~;lN,a^v] 8O&߮AW?Z6%/Jox SyYC77p"|ǀPl0ސ z,z7 d[BO|ϭdb7{a rk-CG)׍eGD/%;|ōylW4ic Ɛk[vL-.~n!uշI]2V?:0%hƀw܍~wkaUU{~ ڽ8D~@x*)`9Ivll68L&}_b+Қ=T0wC֜OиVgB'oZW5j/dAh (N=6jʶTȊQ_9 0^~zWs|-,$XBz3 /Q0@FX}a/L0)ƾpN W䅸CSn|]6~Z9rkͼΉe<gSPIqm܆M&mg /.OX=ho[Цd&MG^*l aG>n*m3SGC{*le9#yCxQ۠߷vl?JMigueߤWIF}<>"F9BG<֪Q>+z=pĶX4 JVD.ՊVeI@۟oŵCq򪽨zY6fIZV/aY-I5Lf:>MbZ "5Q盿6Pi g2T⬨=u>%TiJsPx3ñuM$#O KF$h֪zbgkpUE M240$?yɶjRnLLє5~P>:tz)LTl'T)YLɔǔ\)À@n+8'ZT҅^ E=.K`U4INE-&ӈΎhaH0}N/#4͊dT5jtIWu4% n{1h\b5 {OW{Թk/8$&5:4C]E!-^ ti Y=ɟ[$jq\P:RQG !GuJ" *UtԂ2n>"i|axWk EW<* *ctZ~UrW]%Zg(p}4'= xśn=%#ڵ?ٲT' WSO#k8>+x,9@4.q<8Tαr  +8pDd,D>Q0p k\)#uǀWmU4EVJZ>ĪQ|_y;}*`Jivf.-(w S*?Dʘjt0nf@U9)QAG^ԡcٸ[/]U:/,(Ie9B p:S}{,>H0p4Yox<\1L/"S_^ZBYT.p/Q)V~ %3}cZ< OϬG_-2eoOR%5ΔvLy"g*ޘ]h.Ah'k{iU,(Կһ~J 3 -#=ݞ߫ yFFt\zd^f/]$KɆ s}"Ix #U^q)s*;S|W,#_8;ȿ&$&|_ժzJ4K*V% ,S, $B̚nL*i77eS([fMl/ 5>B&ytOkwFWLd|#'́PlC^O ~O>>N<y^ >:]qz`o)SՋ\Gϙ;~g]D?ƣle1 l<߆OD36]ДOۻnӥ` ]7דٽ{08p"iX<vm3⽾a/;OewPț:8hE}2r_՛+sd uȄG.uC!I}_ . 9nh|+I]y:Ct]`E/$JX5vF| RVDOz~/Vd m6KZz~1Tbzg\AbeJMOə/Ǿݧq`/&1yUl+u<2wOWsqGar}Q,6eżtf^CnM~s/9׿uTM|&W^%D^`!/jFEꨗ| yo=(;(=:)*sb\HOr?|,'{/KA 8Ty&\ ly1 HBQ}~*Ij͑ZJ Կ΢r=l@EN^[9 x{oƿ2(w._Ûan-#-z :DRBH>7f-"&?L+ݪ7~-saekE `艦+9|^lLxGm/D*!|6eFf/}iZ@8Z186INV. *o8C ?58wΟqxmJF3٦BZ,Md/=NRL+mt#RE8g\{"iWtjG[<w2}Q̿â}yǜQ]'Ǹd2^iyW(b>$ꮭ7BqcM@|$Z#zz({|_ 튚@orME}YBc}|AZg{_|7b ɽ GzދS ~|2*@܁ ħW~㨐ii2N_d*K'ʟ a{2QTƵM/Ӣpcli_7HWBM!RF;:NS\Ƚ^cQ}A䃳3s8rl< ""t!_ 4dA&„_n:Ck'jqvquvdIM(fSs De5pXJt!eNXh#^!GmJ'd~ym bV1X;)֍BdJ}yn< <6[<ۿ;='o,' Lp3%o,B{~SĎp|bM$*魯L_gh=3EL+{/EO툧*q{@9zֹ{.S8Yg?ӳ~TwϛxllLg>emy8w0{iYR;{F^n1o kkw 6Yw48Jc)?KCPKSF9 h&u{#spyderlib/widgets/shell/__init__.py}o#9+̇[ʞ-%gHKT:r8IJ] ݷL`D0x赮v׮jwn{:/[6OkW$M|dUMm!Dz~O6u[Eoփi˧Owg7|xg?Um0'lL}n Uc꤀&f^”7sxKጠU~6ai+;" ̈́miA9m}qy}"kr*y֘|m[g~6y~ٿ.}͋um1CO7yzUW9M^BzSfwլ&1Tg{Ng)qHSԘRW&l[)ooNuiUT50i@䫬''(T A ;-FĴXަ]B|a oJ\+OU e& /ڬnʼn m֮Ys4w4 k-E~ϰW[ڡlx,>J0Za{ ntpAUYVطB&Q_TnGb&!LMԖTzm(sg2");:H1:H=[<ʋ1F|L6g쌰$jԹ杵1)'1%u,U j8[lBE-5(!3R kjj4 ,Ô fIrR _̺<ƿ_`Ecԃ3c5a셝@2T  =F!Iԩ+4 Pe?u-<tpB''#:H=[Gb6H)>7DGWp"KHYY,yÚUV 9hZ֔ݩ<o俐4vs1zzsUlq1ݴumŵh͊l8?=藶=2|uRdl= lPGQB 9XB:Iu /F^~Vo M7'IֈBM8@tW?"/I?"}\}l?ZavKAXقF ?Zp\49^gќOp.:C%%7 ۋƓHϔ;D <4xPGZ},CiB!|3! ";[rIH4SDY F<ӡsO6\70IYّ8$7١ڋvmf*q-6YB܄ՐQ%5/ɛ'#-WGrq3ҎS$C 7;yݓا(8Р+HSxRϊМ<> WCbVܢ-UtkVo>dWM.L-~Cq<`nWډ^5fPq쓕߉h$Ja!z2INAA3, +{9N9eˈ\* W&ܷZr~*7q֫XpaeU|Oԑ'4Ӿک X2h8Hn(`Np'8 Ȯn]L3ʡ~ pqg=\R,?]C9~`æ~|Î_٫CmaŸG+0l y}oV| E~T>bJG#^&"p bZ&>U6pϏqQˆF9 :sގB {=Z0BF;s"(J(g֓][ P"Kow{)IYVu A$91N*hnz5\8V"f]PȡeuM..mV،l?m\ߚ6'}YTV#iŰ786k[Ɣko 9[1U? ˖k]yڞe/\4VǶ=b+5e]<7sq%T.Q\ J0KP [cjdM%Qjԑ8?BSh'pRPl%׃09\z ^[VȲ576>aL.2~#=Cو=ZVȏ`5gvxJ4 ]刴ws& "MK_rl{KD(umͽSaiVoy HJ̢RDI(/v{#،oU 4y`Ӆ95~V)G`1L 68vgp 9d図3Y/P0Ba ~Zե:x%(? qP )I5/3K:Gd8'N%yi,IW@ѿ&h6rQ IbVLpk 8B.a2agQ[7׭ٝ!|pάOC UpBӺjDk "O ԍM4dPk~p۴'"^7^ˬ:M'豈pSّ07Uȼ-|Ja%(r8,,u@ôFF uykQG|eW. Kۏ%T񨧄Fzv9+LuEInTi=y/jX :[KoK bTA #QNYiw3p¨)ȘFm`>_Ϻ, "5Ү9*m:r)avd805u#߀EQZIYNy[Ev1b[bJu>b[qºt xفsǁhPh5aY^͖O9S,|ܯV5g۾Bɾ/%4},unZ ^Վ{ع&s wsn[z0>g[Ҳn< ێ ]C+ wL nV鹫m=u;pDnL (QhrakbK&7Yd ۰avB!&o"YSI Y3AA;NefB9X즲reM5}V!R?1q I8u.iْ ąc()z~v܁Dc6{|zI@"IH z|LĨG  CNLz|g=>KBҠlۉTqU{-0N[M׳h;bh4JZ:όUBx vԴMtQ8Ch-<8Ym2%ZUyj=Bu&kflp48͠rhk^|O*ϧP/W@ ml+F)hy5= cM.U;LIԧ>XU&gdǣAH|w<9G ?Z臀78J=bSd"񩙉Gj,J+i++ڠ$HS&JQw SfyљxCIZKUDʼn~3ĨW h#.͝hIS.pqࣵL8u3GISGAf4#Sՙ8 pq8P" 77XteMjQ`E^PQ.tU~8RR8k:r:WMʼjf8X+;$frq9QbGIBJ(iHIeQjI8WJ,gvh:W(Pp1_" &[?ͺRNNT,YT.. iO;7EEħM*]i@sEԠi`&I^uȂ~zRAT@T.'f+jڑ8X]]zlDRA_?5o4|V&1UN22NT+{lIZYah޳"q"J/W=< #io:NPp}iS}Tt թ)UfSG\yE8^Jp@v"]4;ru"U#Ϻׅ]:  Y2 ]Α;p`G 8Vp@ms4Rp>v`ā"3LugX{^|>wk/c˱2vk/cK5ܳr]/utgZÙkR,qT8K\/$Wĕz,qeTWj!9f29^8iuPq81RNKS3nYŤhBg }Ⓨ|h#D`}pk`E4>V\7i^__]FFM'/ X~uj>Q[J&A~K:RG0t4 aƎ0 G3G{~aϧa/!#=9BN/rY^ ?wD ʼnr^o/cd+Z^'MD0U.h-а7cmm4gUt9=Fخ4$MMG>>\!7Ѽ%Ja"L}v&^H\v,>i 7lƩoiuqowm-;y#rz;F5)7?tն*BkeNg\窵ynzpc=8(n{dSU6!*ojMTU E-`ޛzGG+ȖHSc'V\Q8M&MƤχt' O]0}lF&UxIH]ޡZZi.ST3-$oUsR[<7,vOy:U-iugYT1`9ūj54yazBڈu|%6SpfLZ^.]@g\읤iy7*q9[b#*[ېgЇc -6o 7.Xԉu[a_HFk>ա]^a)L˫Y{s#78>.M֓{_ʲRtR;QKdmUpQsRRU˪+oIl kXqgփA@Pf.M110ʜGg0xYѝ3us|&Wh |msk0QԿw}%.NJv&磔͔=ݜ9Fʈ>==9!}޼Rmyb\Mp Ѕگ*jdJ.fFG*9 CIH#xiCR5BiUGb)_xUxmɪ`o%ZVP)ƬPڊ|6RQ༉/[Z; k5mbɢN(<a%ݮ3TMN4˚U'7uNpthQ u"Jh#sm}08G:>vpF#RWkKnF SJ,wj,R ;;k2(&o5ћfxLBi3nptRߧW;ӾW.񡞞vū~1H&gJ0wfgkЩ ᣻|WZs 0 \"8/ Ȳ5.^tog)S⺋\aOoNã|h64{ }I΀63#)l>KŽ{KVe'r]n׳ˇ۳ŗѽ74KiTTor;_rt,^JSݒi^^@4)Vȗ~ۭ@^]%@!egN AܗyT;/Zk- `Ih4n.0 d@1z&Ƅ1CDfx g̛ήk+!TBEtEBAmng ߮wJ:NwJbΈN5|)ob_/`]<HSrk>H;|Wʢ< ©*>ỷ> a'ڍ``:{t^.7"wW~;(L!%AcEoQB__j2̚U}_`:q(:B:J=D%bcqp!6 4'^En'$=x(h)Yq7vvkkIMJ;j| ;mD|#2]lkV#\/M2''YW[[ :bANd\)N*-+0#Hx?ԩGL:p_ zei-|EP>t57wƬѵy@޼kGRQM벊Qr"rO =ou=*CUIH{2U.4 ,oܔ0|_C IfOZkiR=%u/I :!Ͼm|E>=-> _}mq'pVb$s)0I<N}7{s;QSZ?[OHitqjܻ =:nTFR,gX ۂ]疸$[<~ѫ|r r7@?ڶzq]l; 4Wh x&/FU؁."[ǾORrk'M,"NTt:⿙\3E̪] aPsm,NҋCu]VCw[Ղ]D:+V[#`x)jӨOpkkema[`a:C=^?Ywi{ڡmobg'xlmKq~6R>]Og`0b+o&RJA KLV^|ȥW 4ZCϠ |1Cty:{G  (3X>Aw />K2+̗@7Ph^˖DOMcpRd#.>2tm禣 E NwK+-/u B >N#hKoL˱Vkw2:%zӠLJ0)oʨU L= n7Yس䚗vPO}'O؝OmG"_H/ #joXpz hxqm WUk XA?x2 8KPu&pIaG$lB@qO͘nEuW4ܺz_ÒשּׁxW6jO\)c+@䭟(08-5PKqŴяrX6a1BUJ'?+Cz4Qħ[~Zǚ ßor7Yf؟eb~w $d]$B0R@->*\!vXbx |jlsd~PgbDB%ŀ"Dڃ7\<sxCk䔀 ?fTah},f4/->ktBOhӢ%ffYU[;Dqxd1t8OW嚿9R8:L'9YyAqt{.ȴ/0=>#|uK2 :ٟwO< ehlcjm=׳lsJ,Xn9C^ z$ 9>?^2 >B)Ӈk[PCnt`IY zst .z犅VӁ d}zࠕ,1 pӟׯkr=9t?qc,({OPKSFm9- +spyderlib/widgets/onecolumntree/__init__.pyR0y-Bgz8B{{h"KIW+Qؙp ik-jEl(iVsiJ^Q:*6~ `Py/&ťfN҃lw ƦΙ` $L>σuYl( qUqy]Nglóqx6{PKSFd*o%spyderlib/widgets/browser/__init__.pyXKo6W{(`ˏd `;IړAKc % C;bӢ˚7rbJPRni.g,\f# 游ٷ>}5h2kQdфCLc!\Y z62ZFQ,ZC.X ׋N'G Vup) ]:asdEHřT0g3VQz Np9r˜jxhMke2J!2*9+iV0e]Ha@Ծ HO Y؇9x3#!մU+,#61ʹ*{=.΋ _@v-g/g<.+i>m-3(ȸ!cz`ϋhtX{}6X*+rS_'TE_2/w4.ʝO{eo̗G7m>Y,P @fm2Яۼ!b77]ɥΪdgf'˥-| WۧER[_wS;>lK?3Gtaxh_f݁-:K+bQׂaRg"HS$+d-:C4eӔ ̠|ȧ ^$iva*u [d_ee=5jaLܖ/uY,[nXo,qka{#Ω搛&dO8ay` 'Zs fJ7Me~ST7uy *3F^˳ro-SSS?5ʺ)<м'ge/ӼOJmX,׾N XRo NCꕮ]DX/4]~9>?çGKl/? Oovfh|}gi fy6ԠV@RZ4VI, N$/7?%F_x"溨~7aSm:++p>*~q.U`7f"6|D"M[oq`:W74Α[xDt[ªvIUชU"ϋs}ͤp od"anKul i]#CN{rz߷KALBOGCYR4huy˚|d WH2Rꖼ#n!ӄ&r?,6P4BYVՍ1>'O6<09h4i F÷U# g.$\tZ@T! . ;=;e|O<Gߝfqъ5N<赵`g 1%>[aA܏X&VRw'Ƚ*aLG]aoܷ%Kۋ;2%5K [;Ɲ?K-|CNu@,A[wf%́bdSMs=tk- 6E+!cU 4uQ WN͹v^jcJzӃ3$n$QLX"o7 q`be|Ԑ 66gT IS_] O S"HFP{W<OQtYdj #]2'W#zPC^Ԕ 砐v~93 ) Ȝ2m[Ԛѡ C:aߙ~|5bP]U#Ży=Cx" 8gG@Xչ2hY7C' 4yf ĶJɁŬ2!?dÛP4*x-m6P0?\Xˋ~i^^k2iY%zo8qULLm|t#%4u?S9N'wm l$QPnn9Ԝe0):FF=>5Xm:onTi?Yϓ N"gf^xM H|Avݭ C# cÍZ yi+/1rgkD*_guHqSj,2#_Ȥّᠽn(j?A9ذD6|f)/0+)l[$k.]9U:9t~;byRlI:Tdj򋁟QM_dM}7GcogԖUK#[8M,<5U"ZΧnӆa'z 1'iUoP;Ov|/{}L`a#]tDLl`1YZb%Ķ=18&+jZ]J 6Y#I|O]Iy[% g,:f$0>xK H.Hv۫Ve 5!]OPbQ!|PT»-=JWC1W0Mr_$̑0s[0sC\bר\l/[B8 O(_֨ Y/>V8*AUV™5ZNR ȳzGc^COzf$B b.zX'€I.  .0 #.Ъ9Y!Ir|;&NҬJcnhGm"׳eh4wuPBEɦ R[&MgPV] ֣H;:UO*2Tܗ5-ٸB5l: ^=2N쌸W~_g6mDlI>huV܀MWOJ0coanda@`&q# BKV#>)G*?zz!U)?~RY%\Sn6qH/?goN{X$(-Ca f'8OПr }1&KS @jg6~,*pS9 9P})pcP8v};`t\7չnceF9Q܍r(:؍r(pb7ʉ2vٝnj gGfznjg=7JY9quQ?Qj4sJ™c*ㅓV g#^zfYn2as g3SW|{)%S_::O{~6wg.~Q4TEsgjNw~ IvCFGHSCڏz0$-wqܛ4KWzG<zs)yjurSl= . ZVE_5EV%p#RC+I<$ڽg(tRkPD]{A'g@{S~@ D!Ղ2#,|eʥfݫ\Ce/ز}Ă:2}%sl|sp^q8,ws~ts{a=41:66w.ܫr`_K<,`ǎRCsI]UpFBM1 $_ɲ|"i]⡧y!JO nl1zoqٙxM@r۱5Q+ ݰ_6 Y>9ߠZNF㩫c1MC<ԷW'RS*s>9)TMU9 gLlmk: (? »vJ]8RvSFwwur)3zwwtp.ykD J?`jO*ܠ22uN53%H3J#%y!UHݣitJ4N**ݫR)xUxmɪ`o%Vr cR:Z-)߮>i7Qe=g5YSnha-&޴GZ@Z2z`m<3PDt?M;NtMhtlP@CeTDWMm=Hm_[ u'ji*XtžTb㎣H-دɤhb2Z4GV6◹Dl ;':ˍrewØ.[b~}QBDB+ ,?eJY\w 3~ץc< ?uQ==sUOD3C)lz@{9>KWAeuO/g'ˏG{0YwE^QBBہzҶm!SIj/]Fgz sCkXLBm!=AhDډz=?0PX%.A44ek]]}[^̆ kHJ`DoWQtd"ˡPz[ъi?yv靀96^R=+2Tu &$RT-V-g\ :\X+PyӹܳO.1`| Qyn Xu}_´0ihzɱkϲ\h珏ifU:c U:׿tTux*!J !wRkT5.8ܥ4ᦁRMp|1anjrS՞⸉*s塃Uz5?0k('HmDzF+]7lcR=]i~!_.Y{㶫{b"L,z b @W@,W2'wol_$[#Y٫ЛU'/L!VkSA(vPsr czrkJ;{o5PZKc*euY: cݔ= 8c¯Q<[%2-{2=&\bi`aYsL,Fߢk줒EҶ^e[6OlBbtz lgzYdSE/QfF,[X_ڻi` +XKţIbM+T76>]Fn5#ܻB)Ҙ0R, -hI,۵(yW 9 XzR7?ܶ| Cy]l;05C &.F٫(.[A cG)j .3N|u36fJpR3P}勆a H!\~*~_ z]YVݱw +\wxh,UnɏPuԄ^+s6I*V{U5<*}гan{; .78%k=^G6X.姛˳J`0R/7g0ioƴ$r%gt3h5 ZB%8"6 {ZDC҄L)Oȝ@K@$VR1+8SrPmԫ-x({2}^Wk^2tRԘUuR޷<[ʵ;J8AW0e;|$1SXl˵@FzˠÇֈ^G 9˷d>ث$[ܳ05/!J '}$H[m'?4 eզE6W٘mo[Ĵ z w[^z}Fcl? z0v.} /oDeV @Z} u%vċA3ƥ{cBJHB:ha 46ڒ5;v +[k {0k Mҋd HQ{0!dסp;+1h0:نÙ MbVRuꖣ?t8r"X 8_ Tu i/s8Iay p.!X<-GfC1-oNFkduǛ4dzCGoW[?Q* 8~/F(/8bZ^S Ew5 `ƷTWNJm򫼴jt5p 4Qį>5ݱab|@koh{|YTռszޙo# HN" , >{4Wg!ePC,PfCߔG`o^hvGejpL| lD~c {=ys/0 <-Lcx' ?fi I$fhVO;JjY$U OX)XڱXjǏΡky,㨏Y+J־:}sPLP>(3^ V^w`EƓLJz5%~bZ})s4L-ɗL~,XnI忱_}JOsV] M~D*grb["p *nZs֛J_xn>#M\k{ h/LO1 <) @~{s0n|U6\kh.BOgXtuy *w%Q!~tEN H:YnjRYP3>BǓGu伷L:u՝Jr+v.S+ +(璹!KH&uMd }9HHe&=yIz*Ɛ("C8T ӯZ=c 43nv:PjVg ? ?n}ZK9I!'=JE{,$oYuw{]C{eD*®'tJ)Q}m?L-Wp6m/C梬1hm2]|x\} 7&V*)Xg,?1UU=6Y^g\@yV7(XJFW,5Kwu[m|tM٪0r(AMAewUr[laA\FQ.cXCqǢInU}0듺 3$lyurXuld9(oO?$Mo+4(iBs<)vmSc_Ɯ,+Juti$O|UP[N[Qg"e[5-!;4ijP>pEaUЀmTT?_L?4@|ٰo~l0;޴[_~,ϫ7+azwԛ oqk=@,7x?'Rk܀Kkl$w8/擫WYl'S v4ERi}X_M))i/Ԑ60Ҽ5Ժ-L,ZC63XjjE]tQ"qkbs~ПIҫfgxvm9ZY1EZ=oFI*>dcykr"OLg&6{#6? Åw]4t5Gu &xk +z'k"S$aC YGx֧Y̳$׻w̞tX1GugUmr9]Ez<پc0Q5k s૶ɍYsJ_n`=nҡ:'fSG&]äG9SS&}2Bj pMte &KvrFSФX3XL)/Np -e>?&P#M)Shb MOqfVUDeu;$G͝hcm$k лMTR4.b:qGcf~r@RܫZ-c" {IۤqT;5KdK" T4420Kr5 oIQJoPYjc"ύ$eAn UW w>)v\],ߗH1Fp> g̀;]7k DKOV6Y*L(\ ~l\g(dO*=!KO,Sss^5P#Aq_j=g[1]2B]3LG+kXj*hG켧 #6"ꗄ_تfܫ0}U55)}nG]rԙN֌ІI>,ϔL&^ꫬVB\D,LaJ?l~,Q'IFM*#eNnG]v|Zk[Ai2Po>@8{I}#9BK@о!j̚$~%bCnTSe[vA"l\jEu:M3/ B׆ϊխYR0N7Hp5Y.]{ l~6VPi8d1AywD(C|5 @vii֬вs+ nRTBet9޻~2Fy&B0``ٳC_33> xuY=_[^Ncݨ|(K`lиclTʰ6T]'GJ 5FlF+Kkl=kh pU#ZX 2Y2XߵC{X;`VLԐ &d.7v9g,0u&ij Y$C3D ׳\NG㳖-Q oXꙢlN? Gt,IF(ċ1 r[{"'HE5- \ >Y^cO+3Veb-ptg]Gqc,ƾMsLE!>`^7$ck=nDw;y{ @(`,,ⲣ3 ?p3 E)R|nħDn*T;l}% iijS. ,pMF3EqהX_0;WsbzBGu|`B>Z+):1\)TZ%a:*9Y[n`!1? IvE{Ӭ Pc(M~'@i{'Ӭ?p3 Q׭iR|n ND7EKa4ISooEÕW@j1ruNdb nؽgj#B}O@[9*X[Fկv^ h 33uɨ+kTwJN9EjVyT me:t1DJH\R]q rc{EZ.?xVY3[fƮxPy,Tx[;*̟<P)Մnac^%6[ [{ˈa7c#猵t޲R@lmuqcӿF ĐyST['dQ@^!t\$ `ۅlQAQiCB˜m4\eÏdž#9eOd[B/z lG3(>9iil\l+TN0aqe{(t|f{Z ̪߯.Xv!a B ӌ,ˡTgQΩ~O7hbtckČqn{*'A|)%*nSeA/54`<&1*^4u;hgP&z:|h o@,Ibno{i[JuGAgTm|wI|1#y/lp Øϥ)fgܤsYJnh0+R[gq/ax†ONSѽT b΃gS6/o7U}nE#i!,RF.>A'/w[cN<ΒnC{Pi=7y뢙m\gOb|F­ KַT="6@RXsCcu!6nv\jS<Χp+%[lkRΚ*yM$ PX~c-؍] {([W]NQcyaW92a\oNtˀM923TTg,%0ř,XqB5ný500еPOIԹ$E [/Jmv.35k'ChI~Ìɞ3b7X!¼@+]X tu Ms_rS a?GVSJ\Ut\UI-#fJAҒ<ϳfH،:K%m̳dwVq[uB9)\X?kmp,7<)^¥;f7xoUt':l$tUi $g`  =Af8G/#goGh#g{xsB(# /kP^m_0f®èD1T% 4Oav< X i'e -1H )3U\GF{aJ,;ď*]n15sQJ_`y?ôVCZ^^Jϳ 29;#\k8@gwţ-9Ubbu:Xa}:26t=s*mu PLd4(1QY<|m=?}"2ofT i=Y]ыR'p؂{5³` bo`8&|dkЎEI}x!ES#B%f128t)֗'wǒ1fDQ1-̜NOK]=uH@?ύI@,,M#]vsvPlR)]]`Je:Mkl-vh 2p-77j'0^ݎu&@P]B  S2ٙ6ژt ûJ4@W>':W0y`\bYRmYa;kS\7pjLDUռ삫k5Lcܞ}ΐmp:3ʰ)ɫC&%c6Рj0#1xe[xYWHr[ƤI0\x4)V0*-1sxh9\7pAiZLvkyƛxg*t2`6U oQl̸.>a$@uUI]uT.'u|{( w$.k\G]1H/$b9Cpۣ?óx\@L,P q&ɖ1W1fն=< cm+H;˖pH9i(#|Z4vLv ]l8Wh-(>['JUőY99cadͲr{χ7* 6=4ilÓͦ4M3=;nsW^UÑ;fl=zow9jM02R%~H|2-^ S>Zܕ=mpuAU" ڈ{ƞ ֵtۍ<G\:5tN^ӼU6.iIRn"BS3lEqGe}~Q eG!Ǯ@ cGivn F2 YoۜmhƸOs4o??3F]0>{Bh0⑫^֨<NJƒ=WqI{99i,r-=謨4<$EO+tfI We/eA@Mڢ}h :L~Y{҃]|F!r].^'$[ڑ\_͟di* tֳׇ0 =|Eh!{6প|EkG[&J=-w9XXbs Ơpswxw ߦ;T"BY>ٳS2W.WXjsEE9.88o@>0@^2pghcɎ\98OcPD&@T.vʒpv8}8P  8v ώkr$]/G}>r^Hz^(ez9^Ʈ2RҵHeRz)zqu2ǮLK]K.RKO1CV C^"Yf2`s e1kK>}5[b[Q;Lr޹\cdugƸ.~4ALԅQ'D ?' Q^H;NJ?i]N2 F=i )]G>SU/K+gqLUt=5tU.)\D2I^,Ҽ 9uͲX-@RMui_vv=8 8@:{TN/sN2U+WN/3^3I9O4&с%s_3H>g s<{>w G{t\qa?n,wc~tcaJD\e^7{bXa1v8ba,I贊ؓ<$$e;uߖ(] +XEOg%5mZR'mQzvIFFt`lkk:yOSW<1U,)VflNc{z2zb&[r^_JD܀s/HT氁filn>wb-qۂ=zRn-cQF>#vx9ەhSEW6 h4̓^ٶM+!vo W>WN7*<-X(\{gRI;$MXwbI:>[\ma,*6tAciy."OlⴈA[v1I6&}>F)!~ls![خ}>ayB]tOx,cRgFu({:GK:qڢp{wn7"a CT'~{T<*´2lk3,"E1`9+b^7 %7yj(n݈ul6SpfTZO\{*֓ps+U& ݨTY#pUƲɍiȓSGS51]mIJ,su:@wM2Rm]|v}_emɴ\݃qߛ XpW=qCV$'̓W6z6PdQYvN]d.}#'b`J{.h h#Yv[d~rnk)S2>~0Sm|}ګb*/@/Y'k.;20?ܻJݴNv4\+ɭc$Ã݇+'-|PO3KdYKdHK yuk/k_R9-> _Lڜ^Y`9)KO;fZ h7/@ f֪ ~Ŀ+_6wbTl jܻɘ>mWfoj'-X?&~*mަ_HϾZ@(hUݽ L2[kD um w ըe wqٲȿ(z$AQlfE@TmWG7Qkx_jx6P܁ 8 *z ,>#{/ g]nbKq]2q:P oG"TylvG;L/Avj#&Z#IRɰ.VU4*#8Ӈ'v v_MIKq KŤ|{5[lq cvPҸ akTmS:3l? ʋ^Lc'@as'#wt['Ni12p$SrH0zՠ;$~AW'>G3ԮAvn'Z_$Kxݘc{"gސuCLBlMHᓤVZTr)b q`UY+8>M49}k3Q#O\D'9ĹHGFŋIX*\)ʶc }ႜ-_buZ3"D\! d;o<sxcp'z̲sQ=q  MhVzcĎ8/cVa4`8$m^Kqxg1t8K.uҗfFg9IyAQ@]iKفyS4xqYfۧ yhd*i=[\?[F4o)BCh-94gա1c"A4^#}@iYu6I!pnL {`Hнe]J vA1]%NO?,r=[釻i:,Uf>')f4>MhooYge:eXboOYy饨CϦW˕햏;?[2;l}k0dVyVv2ȚdRfm9Hdg[j~tWc V9Vѳ{fZ,[nS ϻmI(1Y.ͮ5+jymbU2z?͖J}.d+5n=mlr@]M %M\MKHF gUQ0;b<>B|$ +s W6"'8sf9>) `kN.]zB/foWDӸ )wouVߨhˆ"5^!}D6_wvIZd9;j;&+׺0gV("Fû>HbKfMEkRM1ɇ!#Jec׼mWHn\|e( 9c`kʕY.M૲5u7v` {I͆vOj6/vvgAp3k$8L$UBqKTi4NEՠ>@Ζn )yj4hu:S.Mb0cPj"Q8x5}Yi=N,%:'La;JrEe,zC(k:Cճ{pULc9aԳ2DY.mUC͞$#;v#5L~#ٛX)+x h/K$ԥK@$p0u>W_ :d2ѧؚURK0Y|y[Y`Y.W;mV 2XZy;/c d@reI:ST_Zaf:e~: ?jQブ^T`E&c[T TUڿWO/`dtlfƥepr=9?ݫHmɖ،lw+f4(~WtVQN}GaE4k-< fŋ0ih('p u[Z`i64lΟ誴*`c{jx'p/&ύBezz:y:zLQמ%ȷl̘Vˮ7Y#ZC8RDoqK%eUvdKFgϝu^@-+)$`):M[IR?a@Ձ858 MډʆŹ,o妪y}+.%%=nդp@DT45!ʶl~.exRջ5{98iY2vmt.UT#y ?MP `3ު|%(D~g뻬ے |lfr̛)\+4oV1#pޜY*.}ܫ3 nMA YUrTṔqH$zp.k/z3殮]`'Ѱ7F-᎕9%uo<{:cp(cv=FůB KʚQ1~rLlVpPƛ6CGm10G޻{Um>ŭn?jAxM\tFy_NM `jՏStC)UkQ=Ϋ̝[Vu櫮OޡjẲ#ar}y < suT1r*f,V,a,Q,e,UX_1cؐb0ġt]k^[簸9f`gDᨧ/5"ygxE捔JgFۓ7"{ 4`הfͬ,j␓ zD5v]cBG* c}hϡ#86E1}VaJڇiVOgM.s.az8IXO>+? 2vS^~Z϶%Ԯ k+":_e{x ۈЩsU֊$l۷r2a2LK‹7un͗W֖Q@ :5* gEt&@Pg WP= ]-*k{޷ ՖBv+jmW[t}GɗuŊ۹ۚHwXwy ;Mp,P7 :o›CZS{,ߖEXMڿʘ⤶~6Y.q{Gd,v]UV`=v.xK`O"6 P2`UR[b&)cV&xo ZuҜD-E1e`c)3۫E 2N snS^pQ ȵ:hYq~cvӽąM_wB,HD't (DrBG HO$'t: FPb|B 19Y@- dKo\dnR smjsliOY噱BOEcnd]Bӊ gt؂E=E[;{ cTTUyx1kj6rСⶱό D0Yr{ k|p4RXխl,UL*j83x<5a@IA3x)CŻWtÅz-NC@)2<"(S;(Huva$jMsZUt3I",x ;y՞i%Ij*ЩU6٢8Qq߃_MKQsHi(wNkhqS5s,+]A}6VBISy33k8 p6"(ix<[ZZXXFC̟4T5*b)ZpȠ^0n t%YZ.z+% )RҐ*Qjk̈Q@ a(':N&tZ (̣3|6<MzU%˴T2\G:+*> ڼy}YVWV4YTzIWts_%Y/3kOWzиK/($ڥ8UzlBT;gkkj}QѹoOQrVtsmݲ,LBߪk:3xJI:U+:8(I G"0(Hp>% cv\qxTq;}6UY~7|Z Dů>'kNZ@,n $o:wo,ّ# \KEߌ Py]XW5P\ZH4NF=s9c& L Wp$@Ais4pm) 8VgT)4^r$~I/cHzk/GX{){k/X{); "13R4^^&KQDkKRޘzz^;@Lw"ĥKͫ2h/2uVjD2KfAi^gU*Y(].pjg~gj+P:@ɧJ5WG\Y!>c8285d5Ȉ.yb{Iӯ\nD'K!R8 Od:BT q@+! %a~@)aJž*!<ž_(!T a?\q7Y^X+Q>vq"snTciW// Z{S0I-аð@QXq5^HYABHC'esQ +8%'x @#qN۱I tް]1'Xo6i[N%o_Ny2iL,V;V===1o{rQ_J@܀sOfOOCk=u[ܷSy𷷕Rn-cQV>D Vp5-`"gMT,ЦΗ7Ҕ6M+!Y\u׼j? v|,m.ֽ)$azNc"Xhi9|+|צX`obޙzxeX(B:"HEJ%봒A[n1I6&}>_?\ȓ}?0qD5xb<13:=Z#e*Sm*rY'~S,ψKo0ڥZ>ۓDTaKf)M5w 2PBGmpX@oJԩgCZzQ| ]3zn cv:Ӥ(` fiGvE:)Q M=B(wm:.b̻Չe9@gM2R],|ܛt2KdZ\Ag6p<\>.Lԓ{_ʢ:"Ȣr DmUETsE-@xM nzh"ukʔz8PLJ@ sTarݏfs0ƾByX+fUdFaP>>`>f^yzlO~ |Yw`sN'|}3{̮=t"ù@~ۓ@i R>4Yv;t_ Bxb{}N8uxrBi}oL祏/J:Ŀ\:ObW/r=')>< 1MC\/q_WS?H p /Jq}b+3]nfWӫܙ,qhid;X<vus{y@Mt8 v;!J VSrGwTB ~r}b/Xu# #U o; 3hzzJ/X%."fx g[򕬮ԥWvΆuW$f}p9UCہ;(+\a;Ip;?{|HCV{ =$.Q.A,ۊEK]T68ۜO/!DXIp{u6;x]\3#fl!4tKhZ>64JyJ6Z!.*fț.tɓ{@8`h0l4'@zgiR"|`:'Z1 jD9cpْ\w2}V>F0k_ {)QQz"wwK+-J=Tqwȩm )ri7J/PFDoС5̀WZaϜңi^ ˱,_س䚕K 'MG>ζƉ#";ymuH?xy|,TGo3G|s)rb$Q1:_kR߫u r> ?u_A8>ExjuUխ7l2=ԸIEƂ;w5Q_hQ2ߣla\ڸ'Wcvb[ԓvvg5KJt 9s?5<S\Hi^ca䃓3SmQ{OD$c΃;L-) j lDvwa.$@ZR*3J2F>> ʋ/U&VAc %}Hh] ]8 CZ I7twon4|W aJMDBNhawi]Y5;R-=XKUdsA-g|ސsC\Y!4"~9'[9Cʥ(:a/=/Sv༖R47}[D%>GO<Ϳ80KsB }TR/s5:[ýpBΖWeq@ +{Q@&Z?$?_Ϭ n>zE-f''ۋ,DR Ya-du>=h%W!s!HX #^7۔|[QN;,[OŬ HcV^`"! {X(BZ{/Py P;=ANc]QOƭ.v_r'.4yi tؑEs*̲ X@;l,o8*X{8֣d}8J4 $+=E[bydջ Ӣ,Ct@U!C vS]iB2[ZZy-m #YBYЮ=~wӜuDD/VYz>B3(m}[¸$*!An%@HbZ^[{n6#UoXh;AM.' RYPKSFgDd6H+spyderlib/widgets/externalshell/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFga9spyderlib/widgets/externalshell/introspection/__init__.pyݑAO@+|.$ҢJ=Kir5)"Hz/|fvsMD-'e(P0Oq:}oFp%t[rt5dtd<_zsXeyɳVuQʋpwE=K` 8!jk^4aQ{TӮHYN| t>7Lwȴe@1]ڷLxR'u|QH !~PKSF q h5spyderlib/widgets/externalshell/baseshell/__init__.py]Ko#9ׯmw(3\`l=m[nK.wHKTRr e9 0E$`<(Zkvy~>+[gZ@u[+rooynzs?9,s4!oweѴϭ}}uBumZk˗mcִk[bb}¼o Ү@ qĥCXl}њ'02o\LYOdrvvEvELJSQmy~ֶ6@Jtlmn >9lT<Ai$ߡ4+Slw-5#[lik7܁wǦ9Rœk y`gg,_C _:=(W5|uMk} we;IuL_bVjKS75 6\+zVz /kn[3xi:?nڏ:] ayok47: iiZx*3i^0enO`V <8M=xg\'+B|hnC^yie0]AU ^J_Os'R0!cC%m oy2׭7eŔDYl\!I2 oʕQ&ꦨX?Lܝ9ZPM^R3g%,Gt]}ȋ gsy`Jp%lxeWxnȞrS|bɥug/;+ YOyNEǾ\_X8:3Ҽ5Uo}}mצi>1#](bYit1&_تa}w,^JZ ;~ vs]%V*py5{lʱ9"p@E nvq~$Q;|x.^6IۂibI*"x9]M Ƚ3Րkc*ohhnV\֐>oIr]j#4<ӛ3h1eZȴvo.L3LA G@ tf71uFqڌ<`q)NG` @TH@Gxm㔥#4A]A. y|>.& 4.@NExWp#, }4 ?NN~eֶC%L#1ܣAS!"RR2206PL*6blON Z֢NߋY[#IgNgnykטiybJ "K)dX4+Yh -, __8x{]WPH dJ{[(ʩm!Q]헐!blb;+2;H|^>qoyBQ5n!L|X9$E}b~J|nxE+0a=M~$wumY^{|!tmddN Mފ% ;,ߋv c(1+wg-—wR QM<@ q\\mfgMæa@Ps5~ps=| 5,{|xk Ƕх^)uȍ h9> WH\aBM +$TFQa$ЧTp?Tˆ S\5\D/ko't]nZuk­M7y>q2FԳ)rFLpnGogS0_}D='{&=L='3~_ғkuVsUْ4 QQto%I?ZRA55Jswgn+ e`)rAXG-&J3Jf4N#Y3qڏp8 尉IoCscUR15ԲĆ&^hB]џ~6jRnL(qʤ<&]7T.tE^Z/f턒*%)R1A@!?шqDJZT҅N uz4d!\,paIND-&ӈΎ iAH;7}Nk=tfym+mT<5jtI_u4% g~h\b5+{O_{Թ+/nILuHi$k|B\;[P$zQlEƿ}v4u>|#F[5CD~@UUQtԂ2n>"i|./g*ҼN{ ʔHqeRn^EWŋ;db:敎H-S-b n`URɷzo;@Sq@4^;%e_ 2Z2Wv]+p89j> I'N? {"/QF,#_1׍cZTẄ뼁ob>c1=7yWwb3񥞐(ag)!n4" EaAD+a&JE⑟+!LeB /|x_.RB<ۼ(un+Q> 6L$ \yWj./ nK`I+cRC%oFcm4G*NHR#i 9lm"G!>t!ӂ%mOFaH~p> h$.XO& ݸ_O}kL+I~ؠ}:Iru >UPMcmVT(^lnsIxkg, :݉OpQIt(b>P2ۮ):l0q);ފNš}w2%^[<[ZۅxSE7x4XڄAb[-})?;:#񏵚>+>CIus3 f[s![,(0 DLis}ƶbs HYuET& As|hZdw`Oʼn0- 6LRE?hjxŬіel!KkX>5oO ~wnZFS֗(w S*OO"eiA5M:HFe R7t hؔ(Bvc^ԡcٸ[v/mі:/,(IeyBۥO2S]s,JQ)7xLy3nnw*Hѧ',ݧ-/=|2/3ܗ&xa$j*K/8~9!e7s3 v$<{jVC%f>1T[DD/DLB?dVPH+k{8 Y0ko]鏋&8aj>)Z *R<8BH<=og>sc4 :큒S[nYwSY vS65٘Ͷh#kMk<}&/KNlw;4v:Rዟim:L·sv8ʸIgJ0bpX&8t^ p aQ~tr#CΨ|$|let^EIW#tOW^#x4oσcwͦ\eC 8~<^Π'Jpmӥ`]nˇٽ7,?p:]PPFP|r;Pc|TڷL4e^˰UxW!gnvpGe(r_V3R`yyvCkȘ.C t{@`>ABZ5\|aWnFu| g゜ ,,_:;LΨE:yL>>X7ө$#|\{>xjaֻu 䦡/'QEɼƴW3␃[ 9׉Sa6*+RyרEq<4] oanPv뤗 &w ϽKr5?k'ۈNU_٘{DC)uи?n*(!#FX ly12ADžZ9*P5X&s䯖"Bc7 竳2xFk|Ϗ m~B)w;oUkx8lڂLRlB^tDBB.@~t_eʲjseMp xR@t4G;H~ 1ulQ;3zzB +751#jvxp?C=7od3 )Wtn VV he1zn~_-{4׫޽B2GJ{k#D ef(&n"b(0YEkb+p;jSq ?_D{@s0}]ҁP !ܘx<p#>ˈ)(z~;=Ŗs02x!K!.dpLM-O2U0ph=458v[0_:7I7(-jse 'vy۬vŃ@'_Pe+C LjCJzu4(<-& ;ݕxA);d#F$9ִ; Gb 2i`3'n̈́^{TH7y{MEu YBm>iAotWx 47P P㱒2m[^N8-I3å}m葮 A6SKk.|{QxRo"}E2| H' g ODd^}zh&e>>j KKԆlLwޑC.$ҵ.RxZ>Sȼ$(/p& \H1'hHAD.kKTLgڍ-ngcUl$ɶ]&"f!g[i^kv-$=ܮ%4/tn]th; ?lȧēQnb}vVML|oWoZ(; "`^K-M 9ha[B5>GϬx0LNk%9sVwXk|茮n)ጒ-ůh1 ӈxT#ma\,lBJ5Ap $!!67c: {g[?ݒ=s;=hpgGNUO{ ?MS[[SK߿M3o^ -Sv|?oׯ?xӝ{T5x}e`o#4<#ʐ./80,mўĶA[rMZk 5F90n4~PKSF]Ts<8spyderlib/widgets/externalshell/osx_app_site/__init__.pym= 0U7Bõ HHCiU4mwp3Q48tg#NhHs3y>6ͅ'xM'9ݤ?kB+U#+D#)cGxE1eL{۹"]1[=>CŒ;PKSFq!.n7spyderlib/widgets/externalshell/pythonshell/__init__.py}[o#9{ afP^t`d*˶<=8h)۩켔KOD0Aʮ]`8{z01 ƅI^pw}cC]5Yeh酸1/rSvi ""&hYa/B_֋ }kErh[;a~V>cQ]qCUxx(A`:9*D iJM )o`!<Y!5Ki yQx0GCh5b=BmСo[M`'d2L'*iDȹț;wO4"#l5-xӢGVjH'#._P9#,eEz~F&󻓤q-NhVɈ h0KH~d+p._u˚d8lz+[l&<觓L-uq4MJĿ2k5=Q:x*f5PWN退veU:.h.8?fϻ[e~_T"QC.f=FpwW;ƛƘ;p zȜ(-E^+8-+?pEeޭ0mtvv>q *ά?(mAJM^EA29FdNCZr81n6*E[-IRuέ"+8[U1bW UB?­$r_ S_N݀2jmwX -vevS:uU'0jL8.7 Rhؘ` SSm@&Pΐ2 s&߃a7F ۼoZIf\͖u4C"$ty*d?LV[a3z~g }f@ꍟpaP=)~ȵ 8ϻX#'қ"+_^"l !&I uH8)%-Vx%5);i'!? A`_|jzoZ0Pɓd<5ek6GKӋ(ݛ+bHSAM_ir{AvxBcĺb\ 0-nBxj33sk#SFxS-^KMնAB\DqP 9H ҔO9[܏uW9mx),vS܀f~]!ڗ"? |w894"=FpP2a Mr_rq{Hk Ow1{T Ys, Ƶk7>}*$\@uDmp UDp4|"&VP36ncOAPdQ򟍩GϏjg] S.Ĩ7.$XFqaH$FXH0 g8 c.hո%y!סYvꚘmf^ C{kSl]d*jt l̀)~v 4 𓍨Ǔh8fmHSM/명Pޓ *i˙=C!}o8 MI:hS^CT`7(-{nwS6[r?Jm^͏€ݼJXu/k2(`0taH|K:x!x\^!R9@c(#JVD6ՊՐ%G@M)GR+Bӭ7]UMXKVJ/r*tB(N|T0z}j-GͶҮs-ו28)γbCX-ѦJ3@(i oƓx8?>wBOh:mno*UX|.(F;cDW'#!UڵXj&/2N#4̣)kUvCbv8K`b;JIBJ4JzQs¬E!]PԣrN.L}=CrDSQK%;kq@whO;7EWU7өOgMUji@SͲԠy&m/|h+zCIBRC)^W7O6(ĵqUۋ!VAVl-H[](F?݈V:%PU_]:@V*I:Z2n"q0_҉Xy;9 xxT TieO}fJth]Fn98K9o@x) Nx?,;Iupa< aw#N@db'@4.q"8NTαr L *8pDh,D>Q0pӎvSE(cDF'sDF('2XG9Q:Jq܋XG9Q:JEoIHtR"QK\$ZTQJHt1-QB#\0,T* *Hs/1LE^bؤQlz1, qzxKC~W5&*ń,ksg%UxSɩ-u'(?l'O2CAʪ+ߛb1~0xA\*xGݡ]neaܞ='hMO۴2m+g0YbUp]^٨%-b(~7n;}*Jܩvf.-(wC*?OO"UaL&Q,TbS/X?TyH0p4Yx<\wc\搗'Ii',uuQއ YT6p/Q)*tuUAJ*f`]M}.O7xf=8 hE'/(PQW_ԙ8S7/3|Qܚ[x.a_nZ[aկyS :AѦE TPV(-WoH8di]M7Ǜٝ 'ի/>9Ktxq]I~}#U' ̩L+nd]9䙄w@jRVC%fO |)cIVlG+c# fC6JnL*ik"8o"6EXl/ [kN޻I XQ(=Q[.3C.qisM_㢑MM 贖8znL杊km$Cз DǣDF]{/KVmu'n Uu {R"bgcx?8Xs""{dmYC{ p٩=ݞNg*z{L·~+qi̝)uRg[Щ7ٱ;Ή3o9zMw-aFd]u 5@Wt5%SΏNtF* ϝGi ;L`%r.׬NGH`E;'3>wfxg[򭬮Ԗ!TbCSD9]Ee;]J.GcVDOoz~;Ⱦ;wH~@^T|iB6ku ',ʙ,[:ozJθ>'ܧ;fa`:Dz</Z(7n믂zwt5:g'x`0-&7 m814HYn/._^Z-e=g/ *׍~S׿uTmx&U^%D^b!uJFE⨗Rz t6twÞRUMy*sb5xdU_Fwƀ=!K^:֨ X 7{9[R NDžZ9tкn3$y2#{ =%puXVZ-z46-;9 MΘi}C[OMk l@wXN;R@2UtKsKұlS[^}ϾZ((hW!޽ BC3ֆ?Hum-ܚ"?Q* R`⽋$=q%kb*[4=_L N}zt # )!$[XދA!6g S1yEuU;upG*p#\wU7{#pz ޿m%&Q|5 Vl52hkU7< y|l:xhs(dtG\DYҬQ殓 ~Kszd2^iyW(RҘ'1 ^5ݾ=[g|h'xSF3'x&B /@~%s~cMo޳ɵ,/!Kh 'M'>S'~G'O6*= \]w­|6_|7B >dGzS ~7$h,Tnħo^WUnBG~Y7vrU6DSC+2,d$65krT, _ucf[U/+?dS:u #-C:%Ƚ,?pP/}~h& e6 KlƒwvG\Iw)<x\%1/K2&>l%8pv.,{ ) hSÀh__=,Q1c^ In7Lw̷2}LW 'g|Fٽfm˭ىBV8p-%4I/e|n꺈hC; ~lȦӱnC}vx&$MX^6ɶ֫ԷZ=a*X+RːuBN?GsGzɩgkF |w8gRn֊WMNCg|uK9gl)~]a[Ry9dmQX탱³$lJ`5Ah D>!47:tKb ߁x6r;gSNF0+@L(O ~ܗ3εt8@LR]?;PJ?ɡF? ~(P/Os=ӗw{x0&tX L˳˳%>!P̶t)]Ї7zr{,v0B >*5}lSȸ[{ݑgR"f;1s201"-؇%%^k 7̂29x't.e_SSvt>!KK ؟tjU=e}PZu9fkPc՞ q 2ڎFm][elW{;ŶOWuUX~a:W%7N,SXiB7-I߿ξ3ׯV-c~cVosanOs6 xsd`5Gd}!x F4 m|*jUeFL_P?U9r{_?-jT'[t>[m{r ]/P_NNjT3;(!tQ7&lL'.`j/;;6ƴ-q:BՇ+0t}^EZ^!#B.U.Max70mZnl^T=ȡיI7MlI\rQ{h?xq͋ jlOyUgmT})J]M0d@leقl9tb̼C;Sf&9\%ޔUcnVK0ŸG隍KȥƼvO3;Lާ.mA4=1h标|\0M}~޻҂ Kqc'6 Dm}Z~.Lm]0Y翸ԯ#2ku쯨# o-<;Bh`5L G8ZRFCECuN欁151pȱu]%SUfsPɍ[} ˔sʼ )auY 4;ci"lvi#Pj>Ҹ٠nӦ[yn)ɼ ˉܢ9 Jޫ(.nf-@Uw-6nZ-n3nHkBCF#Z Bf2c^O|SrN\Ȉ@Y{HQdM-Įl@;҂36bsDoDA͍22ɪHRl]\Frd)@mF)W]Jlk8 ӨߦT`XM?m׆"Ӌ&3]lzW XmI/nqfj{g86/إ/ r̻)VQVY@I"-4B1 &̽dA7M!yՔQx)%iv? q`,& 3 ۽ޣڤ6_M}o{<O'|pik43%Fy#0ښY  p [ƙ 4n/&4Ѓ f޴XjH`W)̽ O>5r/`iu1챀_;EAXUpe-/sR.+W]_pSH\͘!Ѕ,^T1r*f,V,a,QlPc#Ťb&CoZ={6U@Fw:ŋjý__z̛*!֌ $ 'okhJ(u2:ܬYEmc<ؿ p"gC#1nQwU.<3BmeaJGiVUK(feGA(s:,euyR> t v& 0ygy{\ Aa+svk,D~ˏ[o}[f0I&hJ XxҲ|xlθq9LBխv[jkxN7PҪ3P;k;5px5#̭9O Sn3YJn*VDjrY. [\wo&iZ>8̵;p( Gj|_} :3.1I W? cpMr `*4+' tH`SC(2`tm!e5/zo !iZLN(\#J}f*$GX ~BEwYlxU+>a"΁1QpW+\5ygt:8?rgcpF^6lσ3q \"DCQ.1"C%Ƙ#-%f)N\kθuެka8Ҍk;Ͳyβe2 RNPNqilpƥ Kj-4MmSQ%RUd]`j[q3Amc3>9sgvC^U`} =4ilǓͦ4|. j23):jw_tAST{<ďԢ#^y҅3~8=lp4m324A<*!%y$XJ Zp۞U05AI$V\:c'ڳ7]Uٸ%I-U:Qe-iϵSeJ/cTzk/EqcLzk/etR\[$f<^r'KыD{)*qh3-S{)<^4׌bJ5(¹2C\yUY!\91N8KS"+nh6!;@Z(ۯv_͖pkVIN;?7e*-7}g`\N vKcQ'v~9Kwo!Z}ߘ 0CK}rȍemy\IHqJԧzc-}1rpXWWU7b<_$UޤeiYy9RuJgY,xQFo48I%zu}yC]VlݽF25s1u|TG>IJ~re{$p G,8\7iQ.^_5׈##OK q*MIrA.H ?k :JH I@+a&JaI@8UB3%=?W=PBK%=+!W a?6 [{%ʇ^.N0PHppo7bXa1v+WE] CvZE Nj"Mg&ܽ@'ݧ-sQ +X^tO~gU&mZ'QzvI֘Ntd~S`m-{|e=ÕQmkʍgNP<\dLgY|(e*s>>.p3˳Tcln6_k/}[p(;0^YͿPt, sqK{olsh Ѧb.Bm*KghSh̓ٶM+!ER鄇? .j>` 6 DCJ4wIGipNhÁrV*u6[Y=^Y%1v[)}״cJn_$iܘ0@ :\7Գȇڧvq0kD3/t~cRgFu(s$|z0jSq{#:W? b~0xFP ]W'C=y*JiLMaZ!HQ{ i*xE٫͡&/MڬڍX>5gzPN=қX'U>s[OeaL3MvL,H]e4EX >ݲqeN,k>T Xfi9 c6[5dO 3{7RB^ɢ^a"搥|ܻ;e$ӓS7>sK;x|sq~y-U]~*c*)YF[ 3 GQ 1QU;jCVA%b'J"z%bsS[T;$\JNtg)7WHdkNaVeQsX$wgH`1R$F ^v6tL˂S-w{:iS>gv[i·swvKSϔaD9d;t_ Bxb{}NҝbȚ.ѽ7yZsd"ib;X<usGy@{S6][ vץW P+iQ s_YD0׀ǀ! 卺l3ja䦡MKD`2yyM{\;/Ԫ}oB׿PuP,B3T^%ęD%z> G^J{9nHN o9aL7 L0a;0:.M+bp`On#"/RܕD!O@"J tګ]ދuv„w-/!bFPtV|C)IPv^-%,NrbaE"H ~B)˭*w4wtb_Y6s]tyNzB3v-wxL*]"71PJL7[}TxoW] "UcTRb- !NijMkڽ3}h]<¿ _;ʎQ+O*2XKMɄ߻x8{kq_(iv տn=s؅>II|SJk1qՌw\0\, >'l[}f  Xzл7Bf ?bڶ|vuahwBe ޻8Klb&J>IP6-,6تL!v4W};g MBp>3㞏3!QWV1yImUU:?Pl(W.**կdGҕ%r1!ʔ&i#Êr[ =sl~6kmo3rvp/qfYIxw}|>=?a Fjfl. KJB f${x 6W(C<>ۗ  JF3ɦ?!s,;0_zފV t#\E(g .>MvbO/J>2rtOǯ kz et޷<-#Sx ^}d4`JC1^5ݶetL;F5<~ʡ \zn&B -@z>Y~&3{\ƸéOZq3OܝG'6i{0峷N'zs)rb$(9^kB?m q>>u_aq| J~ tUol2;mո銚$_Zӑа"~OJ¸@oibh kg0k銇$(dZMC udtRoluKq,jk=|rfM?>DD2< I"t|ȸ|ڤ_:*Nw($H;n ]yQ1aQP^x@c9r#xFJD+N܅:Q;qA# ݑ˷4SܫDJ䅜FXkv[9Z¨%TI/x݌hM F.lY8_\=+؁n _o`Z}CO,bZ-N.O.w?}9zeQ-duF>=g2(Ҁ.ʈWpqRf*02lp |/ym bV1p/u0'"C $+P`M_qYa/5 rr=f(ՅNKY؅vh^=];hYYUHwh,x v,Cƹ{8֣d[Wek 4x8=餯 Q>#VU-;EG'刣x[^!pSb=un&-Ӎi_NeaKƬ~uYp]/}9ȉ9+xO%ۙD}r&][ViL`gYⒿ 6[ªwZ,H  6{L%2?؟cϿ1ccx(-%/ PKSFj: 7spyderlib/widgets/externalshell/systemshell/__init__.pyVKo8W! .ljYďfB`$& E:jKdϧoF*ybۘFѢءb*JämAޡQQʊ] DׯU=|l w;-Pi#Y[>b } P5HU51{<[Y,7|9L^;j VJŸ, ek=5g z%'Z/*A.58ϕ"=㕢?r|$NFT(G7;!@:\̜Yʏ=X֚Rhfoa,Tx˴Ẁ  A ߱vL?~ɫ6`jMvRgceQ`I$1u_IGr.Hec~D#y0KGyh;TWtKnM3kk(艺lLDax8ßn51\)m;X#,v(0ŔgyGaWWr H{xh[,ov~B> e@w6:/KDqa#m{6x j)8ʙ%%Pu`oIᥱq:p{uzķ۰rȁqH%U%'LxoX_/GfB.CO'4<bp /EC$|'lxACaj iF<Yqah޽tPKSF'̟3spyderlib/widgets/externalshell/monitor/__init__.py}n0 @ ^a;tk qDhDA&_?9MI("x2%@#@#K畍Z٢9FXVwY ˪5g?lZ|7Effau=_6CyZuͦP]LAQHB c:8čz zrٔ ۱h("HXE q04m|#(I=!@Y*HlE9Z P&JhmG#f]A;Qv6 +̛(g< T `mY"[%S#mQPQ/ԩ| ?̥_(|¿A¼0g~an_2ty-]dS-q`[^{e;PKSF۝#spyderlib/ipythonconfig/__init__.py=0E~Ejb3NH"Rc̋"h#} w4=3"5V*PjE9Bn/|/ sfնWޣl16AJщ󔄤X- $R1C+BFȡ"I ?6hK oPKSF0W"spyderlib/dependencies/__init__.pyU 0y҂l"VHMCMK6l fl)Vƻ&P퐔hS 5^[(Y,*$dtlRULGGz+u@b[/6[1NziT^G{p`hF_PKSFsfY spyderlib/baseconfig/__init__.pyOO@|Ѓ`H'-֦6Yah71⧗4Y5qnaf:%@gU0c̤b܌.o  ۣ*/(fvbM{#ٷNcu懐$gYQEhh%a"䑫=>k^RGy-uf` 4'aL'07;{ﮑAUk^[ގfZpnmuM-Cޙ\#:=@i]m0xhn jZNTp@$KϹ@{q򣶟N ęwԂص{Z ͤ̌y'B󓱦'cAA{)M.w0nl H8g^/HvxaPE[J*2bc)n}ªNʄU/PKSF]HDW spyderlib/rope_patch/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ XPS` qPKSF`*spyderlib/utils/__init__.pyAr ཧpg; ra)S'}T5LhV) Dfg1 5ʹf+sAӏ J6&KcjĠMV>\?#|mw=z@F;5Kn!)!R&i!4'3Lpho{Z))A?jmD 3Q,SNR_PKSFV.hb&&spyderlib/utils/sourcecode/__init__.pyuA 0E9Ez" E ءLI*RnQv,V6HP6c)09nwl4q.̫'*4PT. \Z_<9[Khr%^_rNsPKSF Cb(spyderlib/utils/codeanalysis/__init__.pyuj0/Vņ 82:D=`چ$eK w>NI&˜d$PRj*$+ID ّd`bBRXX$ ѩ-%)J65d=Fƙ҃jV84=cm%5"Bq4GfJvhN {!g:cE :VVE ET:p&Jǜcz -l-CԘa}}{s[ob<3?>ϟp-nggp/ 76;Βv8{#?xuE? {YNx J P*LhPKSF]y%spyderlib/utils/bsdsocket/__init__.pymn0 y I;bmtv.hoO4)>۲;^tOe"8` 9Pe!wjjxo^ꦅVzwҶ)8kKD! Jâ\ #xd'{a]s]*?NY30u#Zt7UHr PKSFb#spyderlib/utils/iofuncs/__init__.pymj0~ ݒBi!uB =-[GEuC޾A~3F:%&,`Bm+yZZe]pIf!=T4mwYVIy G.7(Cjo.yq>=6&y='h \xx zv)T";sbL.!uZ+'U*͔G$~PKSF)ޅ?spyderlib/utils/vcs/__init__.pymO1  7 A=^d 3;MIRoo;KW6{/dd-48Gb1hW`%5S{`1iv%?{6IkֶTy^_a9;JWi_e h;-5uvw|u0$L5G)UD[f-.?j$֒SXJk./NS PKSFDX$spyderlib/utils/encoding/__init__.py}?o0|lСbRpPvC:L-~^MUK7{w'iRRk UXJ/VibKRF'O5<`"b}4]O‡B )}T5OGMQ6eQPUk1h|I*>6ҡQm]=)p"7~m5{xd8:\M}~N&]FG.V~s9u?gLX&PKSFh4Z#spyderlib/utils/windows/__init__.py ;Sp!R_x/' 6AK-BYg؟3 Nw+G*mi6rPKSFdWw%spyderlib/utils/inspector/__init__.pyMA }EEBI)/hLWHUe" 1f ښI*;&ڳ֓HUǔqza(WkPKSF:`Z*spyderlib/utils/inspector/conf/__init__.pyuMO0 $}8p!QH5PL'i7~7+Wꜱ*PXr畡55Y5Ti+~lY^eL<ÿt>1 URER~(`giXr[PKSFpC/spyderlib/utils/inspector/sphinxify/__init__.pyAO0Hl-qAZZve4myZ5[q)L{.ߣ,t@CF`ƻ.Kg_%3#Yk>5oCL[bXm݁=cPKSF,i$spyderlib/utils/external/__init__.pyQ 0 {m;' K]kKd2}Z#r5͒41䥤J<7.Qʕjɡ3hѽB.ud?n㛳NGIkMo'*kZj!t ZJŘB ¶t=J[}[PKSF~@ԓD-spyderlib/utils/external/lockfile/__init__.pyeA 0 E=Ezٺ9C)B0METE3$IBh %Yl+1 G*8_ @ >O덁XZL-բJ'B}ydK܊IɊw*~(~ѻ/tA[MA릨DŽl3 jr!&7|pC.u#;=[/ǻ٬fU >$GqS>0Ʉ3m*s)Of#׽PKSFK'0spyderlib/utils/external/pickleshare/__init__.pyA 1 E=E72KA\Zҙ0mZ ^:"11~1'I%'H-[>s^s+#:ч J$HZ9̶t:{"JKX陡t%cwa XwJ\wr-x#tBZ~cOPKSFtqA }-spyderlib/utils/module_completion/__init__.pyun0~ ߀KSqC+E* u5bږJ|d4B.5%eJiS6w6q`WV51v‹ dž%HPhSn̐Ov1Dl' 'L%TP5IOۜj(% &.!k9I.=>_Q6.nPً iUńzZ,_+UɲQs?{ch;IW@zDPKSFzn!spyderlib/utils/debug/__init__.pyeQ0 C{~!86놐6??[[e K摻ƠJ!f`&m"Ǘ)Ν)^Rq`w$?0U5>c<Ӎ!ax4y)vy'LPKSFY4F%spyderlib/utils/qthelpers/__init__.pyYɲ>o*ЫGMΌ&SdMUZԢ~cbr3"+rZrm-|(whj+ڗWͰ/rSeߡF-p\j׶wlzX.?a/-糇0gw!d _\]/-Y 9}i,"zdd[hmM aU ^uU?ϱ/$cNNϋ:mY,Ugnkh<,UyV4!bxp|wal㖻GuNj0/U}?i Y4!/&M.k*ľK^bӁohҦ=\A[gMUԛS|urqƹVI Ǜ=jH} kSn6; RZlwgrs0_z -}:$.ʵ[]Ǧh(w4Z @.׬5S2}h]J8=w7FL?>)KX4GڭݧJvzg/e<HziJؖ|}ʩ h+<6mon^~m>uJJ,GA9I:SYqIXS徺 H@ks6qvn `2nX7Ǵ6z{;\B; c ̓<nB̺ !#i0 9[ݚ v͊@}v{-1,)Yh}=Oӟaˢ& 1.; +>2P@i|]E U.nDOTeL?* 1weMimqh e)3Ƚ+ZڗLۮwY/ls s74͑D>S"'9'XUsɔ\Yėmԋm^ܠqECrַjtpH?k+ԧaV9Փ{?Nx_<4irzrIf !U=8P<NDdy(޴/Pmyj{69i X/AXڅC;6RԆ?/A傔6L[!}i M%"1J$MQw0mo 0/Ί5<2p7eCČ}X$@ҿ(_\5R$Iғǯ_XX`}}}}}}}}_]|% )X;Fz |yk:/wkU+j ɠ;Ŭ 8%M%3d1̓ d0P5Aw}֬"(sbT?) LlK ]՛0& ӨhjR"kd`0 EAu&ª"~%iK0 ,yD}J4u/Fja}ʼWBAjP%` F똜`-NE v-.xyMl &Rlʫ.y>`NjS}RUUS,buC N'u !A k]}v_ARSՌ:첕yf*QZ@L/Fl6d(!pA%pAF*?-ptg'#9h=[6 .RA3 e ×ע|+2|t?rObw]+©NS`2gDy]X 7i A@o-4 tG!) ZMԇNi^/݁%y)S2ԍ o{ -o=9RKnl.Kʧr,6,)I&h+gVɚч*e^dUթ Hˬ$9&/MJRXb@sБJ"ܸ xYAh۞e"'TkSH`]lI΁f;,l0_>IqJk^i! . >'7y˜IYf=sd'$6@!1$j\@e'Su=G& usD!3$ ] J5:0~MBx:q9M1y5P18D 4iQx/Ӻʛk(qbqOh_|+\2-\~Pg;:ҎnT†^_Yt /@Q" ߓ%*LZke_vKCXH +L$)rَ>kٯv}$jՂ$y9Rsȥͳ7E\_hՈtW F$Rj1p A>WQؔ*Uj]!BU7sV#pvȪai):J+̽!0I$aj,Ku^܏.|p%ʙd2h^NBזAkG 5dNy9"t$WБ%OE?P@=(`k=AUG +HAq{U3م,>K,AO *?"l_xjS[lZp-G?o&dmm&{r`UkO,lL2nKEq! &uΛb1})ba+'d|(f/4[24͏uCGYY*Je~]UH#`wIʃۢ}m"-[bUme9H@m}msm]eDV9ziSILEWX' ҊX*Ѽ5iK8&Wc0cVc}E ί|SVmscVȌ!i}N0ُuS?GVy)$>怬D6 ^6|Ü)B h?*))`/k bxp_uhI]}4/,R߲:gDM8V-> Ӝ8l8ߠڸ]7^ñ%(!3H]|}yqb5&.Ԓ*;<dAܹj3@A[6v2rWgF#.G,Se{7VB *;KQO|3m›vf~5ԲO/mzhѿ=FS>[Oh8!֥jB +V* {0^e>{޹a^_Av!#Is>Q Jg6(@&/ ko^Wx u5w )2nnA! ?6B#uuT6Ix S\֙̀i"gtq')`0v nC*բ*j9>NgO=Zc2!Hm0!̃$*$fAZK7[tjƣ҈7qDfڃ;>Q_S!uhwE0*qT{dsn2$@UލCQJL*Ҝeܽ62@ڽkE@FI2hUdN_v\0,&kx@|w~8fC>| :WǏ"3I?CvpM'k){Mw,)yFI8c#= Lh #ʟQ\ d?2Nob'WH ҫO80b)oVY^栘z0*t03eIS ƣ)Eΐfxj?2veؚtaxm!s A ʽ>r()<4$CK٢rd9Jڭ]ea{o?g[CR@Jg8;vn6Py~pxiB:eN [lWx0 ObC-M%EK*׊lEwg$/VOy֮sZ 繆ya >ϔק+ΛD-جK Bh$ͽ֗SAffSaK3jEc_EmNMtY=):@aٝ+ -vBG&P) KrSEë%D:st8IA9cD4ûཨyɦ$e3}0ظ"#>:B(l0 NP9aD"k~f,ۚWz* |]x+`ܵ+XyCGbWrw>~ qXDH:\֣/u"c[!+Ԁ&l_q‚!O8XC3)v$I%5?0G+3](I~Nqepzm5$ٳk~WA̤5ބ.L&cMeGµ?tefUU7h>*۵$ػ[/}I(=r+ fk37䎩EaԳ N N p 2ZJqE PYga%5E]>4l-ToQ.*1g= $.sFb(Q嬣m6#|ZjcӏMM%;٣$sVYg\Ɋ9R;zى}2.9wR0 [g v^i @r,IiC"%м_^o-/)%Dn{ѿ$yaG%¦U rԽ`nJhY 9U84H12k7A#qh-*xvfí:/hߞpJx/[e'7o'']hc;],/QBiL`4ߋ%^S%=U!7{W宖vH`8 hi$ %gmOFz_-/n bȝܝ]/Y*:WF)s7fd0t*Q7x򎉫%o \0hcQ;.ܷcn97桄҅IҾ߀*$CQ/U|zꡟ}'5y? ,g8%g"jqR ;wߜ6*ml6"tlҪ8޾-Łfz[SvPyEfIqii帋i_SS(i0Nf_mxu*<^L>13途dݬT #߹tt1Z0 017fD ^sX\x xy 5vA*amfXy'舏 dʐx.Ox2ҩP,I$dJ"} ,S'MlB `,MD.bDa͎HGx4ekp:)FA#wNQXb ;™~RKEJR,?M=dR%=-4+ D.R IG!<=, N:s\$Mp'WA[43{*W)fwC_LC9y6iAAJ j*e .#[PGo ۶xU}f;8q.92-~-Cӎqa@ g`A=9ph٨Xx +Ea  T^b'H&iXbג{&"p.L|$G :;f@!7 Q1szi.ɿ9QqkuxM@h3OK,Ox<,z!̦6ܔUM0֣ #?j~V|3/ I!ȽLIɭ9{DP~j%RPwFȨQ-|ƃ(w8|ң8~G1%m F;1a|z3ȷњ A41(lxH2N҅hHs G-N`;9HXq#vPN;p 7Z.70C;ܤ!GO##(3*bfv|%^9#dR] Z:t kD|{Z1SQGFڤ HRI¥A cյz%Z~QJH.\j[~.Y:dkin襞KeTD wdb>5=ŝtht;FiWNQAM7ē>AV*!wI5v׻21嗷I,e 4Cޛr#i!R(GI.{&y08tVmsSJ֣)^>fQbB5 FP?Y@`ly*l/uuhVwqB0zE?ܳPvN]dw(Ɔ>>햊45bD$Ĝ+dE3^7u0zA BՎ~hXqF],4܃ytAs z1`B1Гj]8-|奣y:#mg˼^Tl+'Bx,W񤶎nG.^Hؚcxdu4N1plf4FI]&B! |WBk}}"M4+w'^vYA ʒvVTJbT7HCcauik%)/Jt"q͌}t!o)=Ӥ߅2Pr=0+ȉ|bCN.?ywɜ;yS`] 6^ bFo&]"zed~.x& ZqkoFL B ;zƙx#@=T*{Is+߂5B+,02rDlg)Wu@G8[Wc@E\Ƴ*3& 5c #+O#d[  d<ʣnAzue7(V4 a~']"<3'XܕQuK!bKc/I) L͠%_0xM'YpM,pc9?QVd:IANݹ"-ɼ iX>h%+i<{7ɫP%BnHG;$뿺~&,񜯶X2I8SiIiC"8'Cb/uk^\>_E?f]3Ǐxƿz*su/@8EI$b3R3wMQca1~yn+G:_dE9E2'ra3Ɣ8',ϊ|ׇσ6;y.̵|tgW;N Z{0"V>*F8F&AL7FtPxԿwBgL}1;MN^{\ "t8z(YZF}#45DLgV-d|.Y`0 @ne*Fׅ#Jszb8*&Rg~fPjv4lXQ?P1K"k X\)J#9?wD\H`~.5Y Li 7rg02{Q?r* бWR3I zz3 q=;Ex '*]mǎClCԃd9N0$D=yr8 qx~G*wW{D1LEuS@GV_*lB? j+0/.u0CgAƠ`T;`E5$֚!fwFpD]?t`E>8u @Oc7!&x%hP@t-Pޭ)midy:sHS0qe8,φ\ Dt'3涝 1mR/sIE∡^̽iC[ZǴUN:w'qp!0lTO@O.&1H8(F ZbvaY5NFnsig6ʪ-sxzikhcaDiyA 03J)[[AK:c*xԇl8"|Ôad5:} 7YmohGV 31SYɸt:d0L$((xA 72g=ufN68+jo].[3Es4B_6_vM. $)|  cS$IjDžIΡr4OΕ8ݗvE}anw;xtOQe6{>-/>S{ØLćn+S,Mt;6L=S-E`{©:dP .Ϗ}k̖oᢩvWE/+ k<%Z"oq NDj&z]r&mS<'+wpO$mae=~2`DC1D!\;I80R|A~5)u>d0!X`f-Q${yOQA}W.aLMʺ)" x}>2%+i1ԏc+p;˲=W̭cF@&=K+/iGBHpP)*,6TF y1&&t wbP[r%y!";C}ׯ࢞d#"AfT$i= XJME20&\X5f< r3偀*Bq3w 8HtZ "/IiCUAb^M%\wo#(3xfHFƔ CHC0T.5`W[hP80@syJi*I㷼YmC[?LɔСק*_=GxYyC&a.g3@_KP2=[=B"Wp:ʟGX[O*)c"{UDj! =hFvԢ|`rmF1ۓO}Ϡ ^ %C:8f q~ D9~xWCY( Rluai *-Rh q)| 7tAݐ4W-8.נ3'X zBF^<|jpzex sE5Msx&#oGw\{"'kH{dAOe11b,&F=Yĸ'빘dӞ,bb֓8&zr &H iβ3lWvuLk;[o(,dطry@vho*~'p~Z-4M /3rUEs CY[涩L NFLrk{*/:=bXԜiX{ĎS̚ծv)|#M9b֟S_w1ES+P2_ O 勛 0M U^Vzv9*6hGdm/=ي됉%0d`RĘ ccF/W!L9aMh}6Gc%PVtٚO%KңU2>8FEW[,]d0*scJ/"5EG U"D#eRr|PɥG1MbT廔FT-?uBRj' T__utz+J-"H.?&윷:RcG;39Ð^)18Yվם6xʕ!^eE k=Zܠ1hԼ'\C T]u&W הyvJ5g-@jJ<۱ꕘ*ىS*S|x8x^JDbr 8 881{9p>Ā3T4:Z/S˩2O羗Se{9^Se{i:Y/SKҴoKSKӋKS_̗{iT %Z*qPz夵s{A(7F It`>:Me?^2 ]};O8tJr 8icjAASz> z^[uuᓵ>΢|B$M^ey?u0K|5bk{{4!Je[`խnwxpUh۞jگێ^ve%3U>ac8}6@ɣ5ȘĻ8b{ZﲶXmML2"Y0?0e#:FG "#b1qy$ByDs{~i#_yDk{˅7>w~h϶GڇA b(]hy_&] Xph%nZaݰ#W ck}VGU̝ȅXx >6 $D{"\ ,(ipq٫x @5 Q r޸]IG6Ix U׮W rm\v˚lL/{YBheێN5}Ww~:ps3gstyh -:Г(ނ,CT*86~zc׷"' )alXyi4ʅpd{4Mk!e'/O{1o`kQSOQl Ċ@Co'AgS05CU+93񠼤3%V<"OV=[YsUm=.LtN#TB"Nyݜ :Z: 2]\A >g<0Xٸ:= aRWBuh}C';(p~#=7&a7vI~Ԕjô6ls3B q^Xﱄ&2ZJ3PN֛WiCrzSjғQss9(Qp;kliDƷh_B{D-p7o_y 2eFNjsC=>t6v~_y2-nQxfM XuYRq}^d%yݦo43'Ta ܓ|(7lLA%/#o(<&?qQKғˡ(qw #/#_נ{H2t47_1G_CKUAeۘZdwQ$uZ-JNg#N@fQqGjzi?+}&l,"xVQ$kbOfh-pL*aV)mRR] T""ob:2{Biercm-v9 솦"fѝ}Vڝ\lsjOffN?_K`WDM͖xb|F63ŭ|5*\k}_A)VVtNB*`,؎{`bmJYw^۬g_;U`ޑ~ ozy+#-^ y-k5v;@$=1iY:t Bcs##:Í:89ly_$C£xvWtz2(?u~Tx &Ǹ^6ͦi'eRt'ڃx;Zf_7jaΒ۫cgt\qd]i hPt9 Id4׭ߊK!lp2Y  y[g@AYmOΨ #AWź }$ 5dg*C\}?;LT__58xLvx:O?dԌ(x~D}2b|(ìUrH0#v'qo>(j>4q6T&z{B391wVcT^ 4:㢁夓;յtT\^0q;0nM{XeG!]c>FDZCDr zBt;:dT.7;NX r %^)bT!'ԋGJ8⣥q׋^t^nAXj]!-;|aW~pn:ga(arL7l3. t":(M= 1PXYY>;Mѡѓ-xA T҈aysLFߢxP^hR9P2| x/ۦK%{q f6kl}3}hi~Ć/䌲j=Y)w'=3V0":H'#p-x'qZ0ݩҀm68/5#<8BéOeT  s ZatXvo-sd4_|_7uMZ[>9Haۑօ1'V87Pt0 >88KdGcQ%idI@MY"SiD~ 6:f .is"^<"_?BNzA@O VLAR!\h/(S;z۠'[2zSD‡c]-u`deŢ^ =^sSOQ7ec cq^B !^u'Nށ靱Mg> T]"w7SO~;b3#t gmMtz}CO&L0t %%x l7[ w;ʅun5I}'TÎFOM= ӆ 9rd,u֮A,&^Y*twbjЂ].sNhYW /˱~5𯂷:O2O\1ijїfB:L>T8[]mV?䊝pM<|PMAKYP̏yE% (P<#_o FEHw=9PZ&j'2 I7vwGo||05j0䝇$y!=Ykd@5ob+z8M_h&ܟZ& 㗻AFtKEc;]>>\E(ܺPj!{g`m693cxi@ eWpiͣJq 5 dob@ƪƒ D+ zj=Yy7HQ-{_Ԁ\f+RYJȃї􉳨 -м[kn8+v,i#R )alpcN. 6oIևX˗&C:NOr E@]iQlVnaI@ڔ{x?ܔL%03΃+Ȓ 4ϩ=&>"o9TAJj>g_]o:[sV6F /䟉@ 颕|PKSFK?6wR #spyderlib/utils/environ/__init__.pyUn0!DQ -f2XYS@RN%)GH ċu}^J[%xfPtYKe^1a,+jäΫ~tج,෉?{trETVę60 NS[Gb(jN6aFg;qo-o^״7qKE;E!1 |:'Uru++kMg-*Ѣʣ+ڝ exzIv3t ɥrO5 gP M<L:.f5Ik?z2Ju!KFl?zGN՚\zCR((ZrrܽXJ?sgh r>#E,`5 K:Y\jAɬLsHP̀Ԓn]y6j h(ʪHށ ty Ligp瀠KN0QY@+{0eYL 7eU^o-۵JxGq 5!P_ȴ Vn$,igsΝCǠzBueiX3]noK<}}}j eM#"JWԯdM#* p<"/4NfQ6H]"G7C~,=O;ۿ47PKSFy"spyderlib/requirements/__init__.pyUA 0 ~ A{Uc&J pueQbV]9"BXsij-\:Zrn 9 ןӾut$}Dɴ湕Ѷ^^nDt8nuPKSFwPq!spyderlib/cli_options/__init__.pyM 0 {QpgR)&໽_\ ILzy1ZAhq` 5^_VAvxPKSFa!9ispyderlib/plugins/__init__.py}[o#{ `@ymyeSTXi%-e;KԿ~ )f`_0y $F=?CnP7Ev>b޾q;VW./Ra*\5euw/kE%bu `}~~#;e:+Le>~Pӻ]3]S̐ʬmRf} I? !H;i z*\_d۷]*7Ȑnvn]־ 5C~Tu7czD~7OStݾfUv wd-YIPh Zȱ3'̒_u]7X\m4sѷ}jX }EY(>U]54Ի:r|CV25l#Zrq}]nt f:r!DԵnM9 k|ʊNKAw#t,y2X-I#,Jf/b7JuDIʝNxfɦJu5$M7Q 5u\?{Um?8,@ PUPzEمas ?xNcSg;SF7rWP` 6E ٜ7=<&K-_nwُU#F!~֦%$aqC#i0EfG1SƣQB8g$TǶ[cIm0cW߽:(fMxⵟ:QܛnY[c(N5h_ږƒbe !UJص=i] P_eQJ/}mΙF4bA(h jsbr-GBrVVU q];|*8(C R0qp7MvdI]s&nг/JыՏ:rn}QҔ (R (~0PNJ#d@Uxu1=^RpV;4϶θhT?y̾lL&PɋL%)hQXT6輀C[BP=FۢX w@>1^MP¦Ӥ }fҭ>/-1cj2 x_,5aPդ㠀UF<w!b'Cp^yGGl = X/VPGAK ⶽF4CIQsģ|:6c'ڋW6/iIҊn" 3Eq"ȃTGgQsQD,.]"+}I6s4gd&Ʃk2Ƨq q$Dp尉pO]u{xŢ[cRIRćM+ƑtZ,\:rˤAQ0O y^#ǶJ(IHI% ):$̰I'}mI:0`6QFY8rayWkpW<*p!!}xR~Uz_:5%4yWX9sb1Ws e1 nɵZ:up?dMgDe)FyI,D@WrJ 8p,`#N;PMO 8s KuSeF9QnSe^(2؍r*(2؍R 2v(c7JeF)pz$n2qL(..7J19suQL(%bZJ-]91K QK ';.'& D1%En2`s g3 lg0)eg@YK|&nIcQDr`,hÐ1:!*8~F!!7׵JrASO}7^޲^^'v:(TxJ*.^TSe^/h]Veނ"ҽ513oJHԥns X| <89<7]8l4.ZB_|tL}N|hc0_Q.f "bXKBUz}ueE1&$IG#T~v/>[j #(D$GH!#GHҀ0qQ@:8 a‘/Ñ_:B8+GGtp䟝^q8tsts򢗰ᰑmgt,[D06I+бӴ7c]ֶGgU$P#ijbIm"ہ.Hmi^HZfr"}#|}v&^H\XK  n/S)Iqo0t}zy#r{;Fv?vv"Bea\=MOfO;]L>*@ߟT w4Iu 0"\`,]6~ǵ wﵓR=c1F?^;[ZAJКYT,YVA2Vbi%/egoA'aqGUlGX$|0y'L~%}ӷҸ}a,jZv#JS3C$V]V8wK.&y>i@ pܟɺrVuô_\Wf߯jv" Hp8ΌPwGRJ:s"ux]:VtΣ2\v"I)ĥwo7R+lS1"LtXHʴ%hۀ5CejZe1PB!i-gzĜz0e4{gRrR}]5$\JNҤ5*q*]2 .βɝȋ3cG$K"q]}IJ, u'O2S}[|v}l՟Nx[ mW`p\dMl`{kǸQ͡2Ni~+}o C,*ٽK~F׾^H-lTp{փ/[d~rOnJhSn11~ 03A7ytO{Hѧ'#OٛW_*=|R/ KdɊ o%V>6b 1[ܔZΨT"n"o"K^|/Zڳ&:]eMMbT(3tOkV,p.qi9dS|N pJ4*vE еD΍ӷJD g[>[0\Q_%[]c, bSؽYwf)Nbgw̮ޞp1Pbߎ3&xO)oFv"u{N^w fGwv3oyrB}&h[0adi rFVpw1%]u.̞wFӽǭi6g_O Gݱtսn;L@.6*;Ynuyz|݃Y5 PPF}r:pYP9ym ޫK"{4eVMF o* ׏3*cyUOJ}Q1ZG[@ ?*cZBwW?jD 3d`M&h3>D >TyK3\Jsnd6*h`A$;xWUCnoB4G"~={mttE2VңŬ#>*ebHI< ^ݗˁtq܌+/-];j;sWPӈx!F_>eG4d>~oY{_DbŐ2 + fLƅrF{ EN=3#{ X_,7n$Z DSgǖxhoQF*w4cKfNe)R6# :!tSBnQ Vl>;G|e!2ydU.4X]%3a.N*/$MQ8VQ4-lŚI :!Ͼ|e}{Q+G->o:LڜY`=k]O;le^΀&XxP6&_ڪ&(@[pxgcefs/8pcT ;2k8-X8/LfG[-\ķPZ@(iǫ;{d#?:arLnLGQb&;8lCJh>IP6Ylv`tTmWG1SQ/5ܪ#@@GB|f+"$3&鵄kG_gvu5Z-[я+%m+>Í6jB9~6V5$ G+z普>Z {N{;,W%b# ~VR~Y.-c0kՏƁ KJ7S;I tXCϠ ?h<&x?C ^8Q0tQ7 =HxZ0_zުVLtńD=1Θ\6${E& L_U||dD}:ڧ[pu[gCuT޻<)#cݐHˋqx%!St_E2 9Uw' 1U^etN6aXM 59G7ZӋ}V> 16+r{\D 'ik:" _'o's\_ϘL:w."'N [Y5̧u9M/9poA8>Ÿxflw{ g%CIUMgp Hh0Prө#ʸPoYS`qX4~5e\~蒮8 I!kbxp"ZIxҝEڊҿ H7<+Y&&Hf\{g颙$ bXSƭ&EW6Wٔm"KOiHK/*(c( cb q^wXhqЁ:NNh1:p&0Q F$AN:JMDBblٵkv +[k{ ki2^7.>zÎ?B4dCP^ l ISu|ZU\V,@C3A0z0kZjl{j|‹Y̿X0NxǸ4$$c tt˕? (rM,qPW4 Nwje%%d#+Q%PLiFq\{} C7zZو=/ryGp ӟ~h2h4Wpi9/%0li1C)M6~V",Szq+B_;éەOfNGcYY ._>ݸnW3{.0Sٳ20!WP6G'082p m(@l½8 e#B$bI6c7w %d k8 ]fٗT`NMNE8& {^#%ΫUX$X?rםKYlT,wX*x{̡kym{uNJ󮃢fՁ<3ֻFn!:z|GN*ZӐ^)).؟{O:WVN5{oͲ0"ǘ T8O z)wIN j|1$@5o%T MlYH)p̰*{`BУWRPzmb;-g郫zm7@]c}_N4İS>+v})=Ζ%GJޮ.W5z~q ~t}u|}syy7MLbd o[o_PKSF9$*spyderlib/plugins/configdialog/__init__.py}io#9ֳ`VSr,Jfa?F0"H.l,vk.#;zxx껾QGŮMwT7Eh ]}xB^?3Õ)|P7zdM%z,wE~?GPUYݿ~"ߨKf:WiU}miu9iÇz@dˋǗr ʥ_~}ɚ"*߇bCXE֝nx](U픏mXbkS֗Zyh[V:hfwa\>,ggWgWgYvzÇ2kۣ4tu 6(ڕ^ihb x?/Sҷ0]20{a ,UwjG4U5YQ1A͋/*_)܀/Ů0%`QWAx(`6k0_i;YDVoMQo<.H7M:e(*ׯ'yʩWJ7*ki7T,'SKgSҹ"~Uvpd-q̀nXg%U<}9v&X8iz_qcŨ d 1㣪TyʨG R\k)_KϤےzt޾Po/,r6Glչ{8 +0ԝ*8/yѴr_LA /U}m/7'jU?ou7.D6{TLI'i T'H]-W$dhA&+AE./dQģ8JS./4  5 h i ", U@4M;+u`:88޽Eѧ-u(&d2LiX靲1 #U8Med8~QW>Ur $g8LFX@lTŭq h0؝^8I4MF0+t} "- Yn+i z V%t0)IQ2ImZODGYGsce=X+]*oص/c[/7 ѸL%)ed$T\7{݁F^>h?^QIbS̺W a޴!ೣB`X9}El]ycs8YNͷTJ35h@bE/f+48XXwR<~eW^4CkoЛn?ˋwzjvY)ն=+0stlυz}םQƽjFa%IJ:H'iTkE$[ NT_8XfeV^CV]u.U0 mjb7{7+ʝdlNMqQA CU4J-%1`τ^#hGξY{)Sq*@uMŝqtΨw8&7q_f$*"ВىxR\2(xt(Bj{ #40A@ܿH39z>xЯ_ AhVHm\m_x.{&yeݘu1\7w_Yȭ~mTC͘YuK#ljb Ŷ.˿0|YZP1 \ L}$m$w%gM@6$ч\8bTMI2Ј Oxhw6.3;^`g fR}{#1ΫxgUȚ(ϛ=wo2N$яY^`vX{ܨ콜rGr,깢e]1? ^kФ=+?¦۞os۫T Y{gyZW0(Վ>ώ:oʢ3>E-.k{L N|UǯSd-ޙ3wy{!]}M_f Ukɜ}#Y ~{YV3T^d^="?SwuIeX ޵TNPhG{Ö;s@CpҚ:N*Vrzw UnfkJ+e4)o8kndh<>lրiтq5]ƟWꞓSG*2Z OQtQjkF<Ǘp͏m[]e3٧]7E0V.*8PGӾt01  l"\yݸ=XMVou{/{;d4.zIY*8#ZV 1@ cjF )p7| w~cL\b0# <[lg N@FVq#k7t?p]YIC ^ yP`Y%}$ƅ1nj̏5!SݙX^5foul=c̄qN9N ,aX`)R2l` ;nCh>wv~RLqypg=RoxS*<-:onTi?E[ۛ NfQy==2څ#7 nN j>r 2S제1`ۢ:+\yWENJ/&r=/&4nD{JH\68vy4=Qzj*5Dƥ V n̛"$xN=ZM|S$dJ*wuuI4[ߗqMоl t|22{S (.NTtfSw\ĆaǾ@]&Դƍ.D[4A;: sxH悺㍈0rG.8"r#dh1źlily.maqC1fDմ|mnզ~3Oݾ/|Y}k, fhثcBm&߄^eiHQvKmVژj9յč惠$kJI5ʄo" foy<ܠ6g+&G}ZPe'!`gi-?N=2EPNUS|5гbz'pFo'{9rE}#$B!” 1̀ "*(QT#IR*0 #*L01.gkohTvrky>^@Yt E*0r?7ݪ < 6֣OX;#m9D +?zȇ=pzȶ&…:hJv l*n[fDZLajwWI٫Nk(iEk7}ЉUv٢8"?ȧQf i\:ww]:,+׽q(Es9L: 7I<ڟ>!\h:x^j'^ژԲĆB^*8`q$(:K:WF2iGc$ӻtCLW/Fc&v$$a1DL.Ub jq.P3tt, *xSKfkqgC q8Q/ާS7]&$bFgU>M x< %Z)>;BT\Н7>+Ĵ#r1k/ TE;J,`H[w?w](:bGp)JI oQf$Uݓ'tn`6QFY8a:F<983xsv8\xT}>U<`)?+a-YE\7R9$럓7'=r@,vۑثw_X#W'\fx_dMgDexXQޜzzΞ{@>A"Ĺ2䕣Ut^<./t^4&܈2SethiY4Nb 7K/0쬳V2 R)88<]\8l`fr -3'(p.ЁO|ԁO±=̿GmXt[:/>cK ZT'G-̈鄻'6y b$zH/ZoE'bK-"riZDaCbI9D 1 CıC#?qp3p!‘"Gq;D8(\];|%D86ht,KD0I+бô!gcUֶ{gU$\faOL MDEU;tn%- QI+XJ葏gg%%mZG0Pv~IJNt`||k;yO'Qm\PzItZӓ7JW_ӃH|(u*ޡ>.a3/F\- a x}TkI)wSѱTÌ[Fq/ -`-av!T|EhMe,k*,b| Mm BZDz@'bx8#bpA)%.vz'LĒBK>ӷQ`c{0GF5k+Ā {g̀V*eLwXIwY`-]LRI$@_8D 뭬KpqЩg;ԡban}ޥQ"0ݩG<0N3; s$<ݪRgZn.x(`e'+M(? <'.x.2fܞ>#8O%4LRD= 8xE;./U֬%,N8Xs:}*@oJ̩CZFu&-/^Gg$\JNҤ8*]2 n`Y903yt}=ݲ슮t"˲BX֘Ex!A T>š][^f) lVX3wWUqR)CyZ>rnUxqI w!dQZUa"|ނ'[;G7`ZGG@& U$4ݜ}I&N{3NC5\ /"^ />TyK3\Jm972𶯽"!WY5t>WyJ{o/e/ņ/Wsݬ7dVSrQx5,[:ivJSt } {Y>`:{+8 r9*o-Fyz:g@aZ4Ex PyyQ2UݼѻՌX3cV!^ӉS M*!H !wVkTB8\ݥ4]PMpx16尧 )+s呃5r5?0k('@mD%8|fBUwJd5nۮ }4~0Bֻ`ƖCY1Cȸ`T?A|o~SX&ud"Ƃo_WG}efb"h|-%AV{bu7OtCi2M e:& b0˗mfȹ_Q* `{g-[A G jk]XdlN)|uD6fpTs!o PM+z3~~ +kRJog820Ώ<2h@VR-tE.6jB9ndL+oUzWzES\<uAFo]ϳ\yđ -~:xw}1[=fg C{a|3vSjx_WAtjM"WrF}CEkgo"Aa=?w L' fM1h^|&%dg"&݀1!ѢO3& >pͺv& ƞL_T|}dH{: Wk|*e:P[d-CcݠJˣqx%ct_C29Uwޘb/ǪnsHoѡ5$+eϜңi1ˬmYZTg&Jh'M'>H[k4N؝4OmX=3 LL=L{w顙$@bXS[7xM*)lP믲 N #TdIw)/oiT%/*2&>~%1&@عoc  nCwGtU;`vpwHtKD`A2AZR#klٵkv@V`-A4/etn]_~s=DC6$=` C4!jBO[jCʵ({a/VP!&7-OV/,ڼ4D$c ꖣ?QUFq]VnL({I8M2 5JgqIs وJAp D>"T7QZwv%zf_àh`_?qoIN1 *EЉh|!n6-o)b0aķXWJi򫼴lt5p 4Vo:ǃAbf3bX-NΎNg?q + >{J= 1Qf d|jlskMA~|~`сo$#ϲ yژMG,PP&>"B`d {=ys/ <-Dcp' =fٗTNKN$B ^^ҩ}bG(V9$X0-qxv'ֺ?Q YG %i_>9("0mqD+],Cx@U!S ?!N!xԬs4!OmmT#~tm, #[*l~&RociӜ̀BD$y>RyFMlY[8̰*{`L[+e VR;6[HmA;W-H $붐{iLި^{bCPKSFoZ-spyderlib/plugins/outlineexplorer/__init__.pyՒMk@+%5m/m?B ؞э]YW^}qvRTVQj@U ZWHy@p]Hw_ "gB*)#$-1VsK!12=/oa| 9 d1Pc&\z5{WDЕkNF3doPfu]k~\g]_,9t?ivnxe:lV坖5A]G:IVj-. Ih`~5~o~Y?:k{ Isc>fL6+NOPKSFnj"v-spyderlib/plugins/externalconsole/__init__.py=ko#7W[vD=@wl˱qЖhVӏ("){p} .@(Ňk}8[z}*]gU-@M3Q 7Pa*UnUUswȠ|Tǭ{;ʊi뇪ֻ:;|͋{& +(Ttq;jڇB֪yC6:#jתu>df7oɫcZ}U͞ uB yf}u/Y^~ fSU0C~P۬.|nRkZ?eȚ >mAz}?ߣ{Wj^&;50?hVj~9(9߬6ۮ:bwwb}urqkZ}%@wVeVLuBpvV\_/l >Qvtue*ݘrr~=[O\?^nחW3\՝B:{b[+؂r_aZwծԵɚ^L'imjQX?Ai(42KmU77nv.ts77Ya+bQπ-u&T ?-'#_UQش'W W0{UϕӜ./T&K~Y[Z7yɳOv+/0+B[<2#UAì檼Qeł7m@9M`rk+r@p4r@y Z08?:kzmY5mJ }!v&6 XnjJnVYC*ZA'|)ʼ]aۆr:ГF]4~f+9<8 g#}5pm3z5*k-ܹ3P7#K ٥ߠYz1#3A9c"~e+)E{73@U'El]\2B;J?D¼W\Vr'[@8g  lLpkn\-:ף y2 {ctuӬQ-5^.=t6/+CS.@4`¥8EibF*`[]fh-SB(#0*nCSGZ.dXZ7 x]!*P*.foS~ǩ8 ǘKox4r[KXFיo>HC\k uErH Y A"ǩa% K,eX`}L8ؐaC _*@35#/FM!mv9~hbRY SCTMAi2%f6kEV5o7{ߗ aȾ] g_P[9/sc)Ut ]?= j*̕*AM+ ny0^ϝF"V`&:_yy^l| &Ԛ 󰄖 =.n;ATuc C]2k}^"M5`IM0c3^sj|럼9$$Ƕfk rK p]2?@|w0U*aȞU-m!W0 }3̈2%1zP isbv >AZa vPjPJ^ וОP4ni]:oZkI]sY1=rRUk[n}Run`!b-$Xl!%>90Bj C,ma-0 . q&ƷcnbMwx.Ѝv;Ͼ3liO%S$8~LvI\5L:2`~4p>6iɈDc+!F0ᯫiεndIy(]4b]oUgAP9 d0I z^#ǶL0II& 1=L D.Ub0jq.tP3bt, *ۮ'Olpr,bЬr >lsUW8V_O>nպtMIN3i|DSARK&Q|dij:w) )x[orQdHFQdyF9Qn2؍RHyF)qQ]'nb牫stQJ4wJ¹c(ㅓV CᄍD1%yn2asHBg<W쫙G`BI{΢Γ_|IQ;s` ./{!A;dtT:6 w8~Z B{}|tȍR[jC(D$ H"}H!1t~9 @b &!‘OÑ_8D8C#;D8N/tp7Y^ ?wHKʼnpdM e+\,/ Z<LűSv v4-5pE9X:q5Y 'h$יG3HjPv}]ֹC"y!J"i6םҁgg%Mȥݎ5ZQI=XvbBK{>ӷouzU\3nom2|C;Np(,&)Ƥχt/ 뭬KpqW۳f}l>ĹayW t.L~8ΌBPzHJ?yWΜHྀNV$> bQ~0xN\* ]Gø=}*FqNKiZD98xERE!K@ F>~7N ۆs9IK]zWgvI,InTp,7[6&Б'gcI-6o 7/, ԉe.ILuMY屹W:em!Z].f ؼp8cM=SC`L9`ʭ'no;9*ZÎ(J_]OPEwy%n:g q #=^On#yF`>f/^}Q=M)/mM$sQS ~z=U2q,s*)mF{On$3 o@SjrJ4N(*٫ *f+ے]aHZX)dlPhIvvRI༉/K3k0lY֘߻A XcQo0=.3E]*& i9dͦ+qHԁ&LVtZKAjy"zhG"|08Gs| ܞ@ȟ(:Yw톮SYT;l4:k<).oɑ5Mj:}&e)=Ȏ91δ:34]ù@};Z?)IgJ0wHl:/`z!<1ln>':@@0>O=+ do`xt\Afh=2bИv Xn@0vb>B@o# \xM fxƧ[򭬮Ԕ !+,WDޮ2ȌOQ|"~O@%6{蹮7sNK $3JT\{ b>HH|լL+o'ؓǶܧ17̀$3O81`|\Qynwudֻ(L44E| T f"xLx~nT;a5_TU{_7`މ餩P M*!J !|VkT*8\ݥ4㦁Pz|*cŽ尧T(T{. 鑁!_C9Awn#"/3ܕzǖы"IPlՑZJ;y5_0h-zzEN|CsV)9Ru7oBLBllat]VC Б t-t >17ȷ=CP*XX^%3쳃ѷ*3$xkV6]Nl@tcTSd< C:kg_v2>5Soz5pw #v|e([FN,`5)zw?  a k)0I<itQz jPt ֿn=0;T0l tqՌp M'i1s+8caK-XB[?kc ئ越_:Hg^-(i׫ݽ \4{럽He>|Z_D(s10Yb3 (y(YaE@`TmWGL N}OJ8 ![eߠ^%W2+zt~V- v~]D:m5!biMZvE*E딝zzj=wV6=h;moS76lK,đ Kp{5]\5a^oaJA KJD b$r%gt>гh5 Z@e9"ț. 鍣ڼ~wQP"F4a0nr'P{XgiRl!|p:Z)э5{b) (D>k՞R<\9(HVfa>}ehRn2mIznn)7+-OJ=‡dr[ݥ6[zCs9V{u(HoCkD@/SO 9go"ds~C,ߚܳ0ɵ(g%'MG>1Ȣv;y Nm $)dZ]Cu,dA:K`c+R+XE{)>`/ޣ &HLC;$@RXHS7xN*)f&WLFT֒ kSx\ۥ*xQJ1棠(0sٷ3 <7H:U;A3i ݾ[*>OF$CUj(5@Zkvm9-k-p-a2{n]D}3ѐ C ŶC4!jdelkqOm+ׂ0<c"`\K-}+r>HY?0N ߾! /&ax(k`{.4W!g ePC,PfCj'`5q<֓1; jc6 0'c3H(d aI62ڃ7%A^Ҙ5 (9bBx*`l%'}B-4/a.'vm՜ IxAi]r/A֎W{8xv'T/G)f7VyAY–@]@ҕy,<>#oUvMcz>Y-}{ GiL^f^/4~wa8|K-PKSFm"q'spyderlib/plugins/shortcuts/__init__.py}Is#9=nޡ g6SDH" `DT,R~=˴MU[#8`KSO^oI;,Z*`}~ O769?˗kyPӟoYge{Uy;[iWsh&hcZ'U [gڀUvb]]c |YGWb+_~r{zsaEQwj\Y۞|5ibV/.ۚz󿾜6g4,[n/7XնsXfnng#Jo65taR&:F77ZmUEմov6_get!wٳ`d .p`PK=tUD̋mѸX'^uƶ0۬df^l ]co y|7o)(l3ԣeCXrcj%Bǣ8J* 1e>aOe!I4Mb( YoE$9xeh&zVT-|h͚ۼd}0mnof6]g wL&A-s 4ʪxho8HGcVf̫uޛ[uZےZ A@Q K%evd퟽u_@-眃)$3G&)E67ʾH4(58 ʖB~/9raP 劶Ky @[5xj=澆#l{I८L"iwUkТB#u #G@wsmoU nDl{uQQ/[pb`9t 8˻F"+_©VXAaaoT,T(l$Ϫn4;JOB\? Ag0E¹=hXMVu{T? h2L=,{,k ̼0 Avf.!+M'%@eKk 8'.a2lr;!<;jgM0!J<2z: [o~ǫp>j[ F`."}`Y#i$Wӂ;p [ǙZVؠy.^DU_ud"ja|fVUh.6QO^T[EҷEM(JFۓuUP::[Hjfej <6i8%~ 2LE} _/|c<| sV>Lٺ̹oYk׬lR\Xq;5Ul[bJz`ÅuHv&dy_\h= [ޖ(й*ڝ eM։&jW/n}8ۥeh&KNj6֗QM@ :3*\X.u%ǭAm !( @o`z ?Vuz8hB5ˏI{an;pDdm(a;K[\pj qliZ^e{ȵ;/ֹh@o%u xeQg~^Y.Qʵ5Ք_-]%1`>4®b] P[e'5DA(h jsbVׂr-gB!; OjA] <j'2̞E(S^p-/ ku6nгo>gY 6}3 -@NSJp`Q"EIJ Rb !%&Qb 1%Nqp7LAٚ)WqΛu) Ofsl@䙱J(Hp86n_!3pN:lΣOXཕ65D*<ֺۇ *ah1CCP=F^[[+[ߖv,l.MY&fua]J?UZnוO wZM0 2d0$X{IΠ?\D>Qzl-rGSdg&BpܶgUJ7$H(GyMɳMWUnۑX쨲ʼnC~5eF!Z );5sq޺u"m4gJIS{3ñuꚌI8;D N*D`O򺽮TbQ5EM%{aqYTV4,G *ft7(pK&ӕ4R 7 Iv)xUu^>&[ӎ:Z_tti[ez]b"]A?\P:bG[t-J[%Cjn@EUziO $ (Hp>F%8 xcv8\xT;}>U<`)i_TM"(;pɛqy7ۑ|;ՉEGF1|ֽ.lī(f.-$FyỊD@9֜CG *8p9 8ѶO*1fs?eH/c|k/'X{9^ˉ2^˩2^cXùHy8ObRL<2ZRyiŕk>1se(BUY!\91NP%)7Kp 'x"F+"Ws%&گbq :OZ~۾P3p\M"&ڃ]_B?}h4$V5((p_3riYu)W:|S1Z89ID?WV hDĢ+>c>u Ep02b:T[ļc1=NY_w)aD'"(!#UBJHH i@+a&JT aϔ|<{~J{>WB~\*!M:VG70J8[#}Y; e^W[OSq, ;^)y5K#n=Up{BdiItu4ׅDoGBDIOyaYM,@#qI۱4I+ ް]N}cL'A:F?߫o0жjCi#peTۚry#;6===qogzpY_JȦlçWsP'l`nM#ln6_k>,}_0[qIw/ {[roy):js(*eų̡T.Ě/LE`MŢ )m!Vs; .<4~$\|,m.ս)$rNSbpN,)t|+Yu6؛8wY=^%+;cܶ")}׸cb%eq/d4lL|H')!RXe]}> cΜ?9xIޡX{b#Kӽ)LEGP`eOX  a>K}Oň0өb `Vm)6hQw hxE&/M֬X>5/OĜz0,WKovjRrIO|F[OeaL& ݨDSbv.αM6Y H =e]"˲BX#x@ te$#շgqh,ےiuߛ ؾp2>/3ROi~+꼺ν TqY ?;jIIE Z, ά;À-2QgjL#c}|0A &w[=wh |c͓ w(\?»~J&j q#=^*#yDUG0wWTZhg.M&9X熻P{ y]TV*jFnݿN JEIH $ѿjZ-+UT_x;}dJ;>Qp 5%UVɶpssXf)J,j;)ĂI,L4fRzWbe >@ngeN' |}3{̮|-]|8(^o(d|#z'm:xN vdN>>PZ_1 e &,:ĿkCG|=O*^:;0{NA1?+ј&aisW+M z81þ6 bs]nW巣ѽ3,d]4 OnMKw,J9<@Mv8 oȫҿ5 anpGe$(7-ڀ( drI.^|.f|#+u鍕;'."'5-]i#3>]nwogDNɛ;[mttEjMC6Dur٘f>V\18T eLwi dUۮr固~0"z]0@c˓!e@f@Jg E1M]-E7/櫓2 qZ 1"x--~B);c2\_=] =<$R6% :&tBnU|#¾Ű=p P.Iړ9jX҅RLw[}T_Hڷ/]cM# !UcXR< !=Y'ַ^'YQ>X7}h]<¿ _ebʲrsYp;c ~`vEy8IiBTs}gcPWV3޽NƪpeV{!.`iw+gE1z.ܫt| rݛŏ?!1mW{Hu]l;`i;z nM^rWQb޻8lʿ<|mV;;$`Vu*AWG5SQϭ%hBhύgde ޫ@]9%7WUvbZ0y2hQj\z~L]/Aj&Zn$kdXAox,]oh-'ܘKzScxscy1%hZjlq~t:]\3#f!4tK[>DRX+qXkCI̐}xC1OELbCuS̟;ڃIAjŅnؐhр'-=˺v%\\w2}Q!F0k?2tZ9CBoy[ʭGwK+-JT} ɸ;Tew9tj(DoС5̀fSOZeϜԣiJ ˱,߸g`kQ^(1t4D+mSGDR?aw><~4TYYSgZ>{.>Kȉޙ| ߠT ~%7h,T@́~Ki$(Wk~ciy2g=N*j2܅mpOBLd ҦV8,HL.زz^鑮8 BΨ4 lNOF)f.V$XDj)<.ɓ2ؘ{""rlѧfa!^&Owo[]֟e;x= s%J߁𸼧RyQJ1aQP^x18|w<"[/%w'tvdpeHRa;|KD0z  r~BWQ 5:"[kֺxNrE֐s V-m"YFDGk!\H<{&ghB҄l㬪sm+a 3|V4xsZJl{}0n=szaQ]~÷GiHFËIX*\)9-^8`K2 8.KPuw6ǽ$ Nob@9ZtA6"!pE 8" u*pK̾%ZYӦ6j?f9ṢO2+@(48- D(%;lZ>rX6I|eB)Un%+,E8 4V3=t6~w _t7kYZ]/n/~,ER ٔa=d >=h5W!eJX#^lBmJ(ȏ`pdNVwY$#UXh;tA \N%f;Lo?.4[ΟN"? w7@X|Hr_5/ EgPKSFS(spyderlib/plugins/onlinehelp/__init__.pyՓOo@| n[/RhlO+l\v7k?}4iS{찒6ZM+1B&)$a P73cj(at2w0JܠYS\ci9͔2#F >B{i peA\dxv)@'Z&eI: <@mpʥ4ݡ*go|FX^Bx[|&Fay~?e|^%a! ¯d+/PKSFVM.spyderlib/plugins/workingdirectory/__init__.pyV]o0}WNڕvB)de4Yn$9];M{'ƩPZZZB*+@y԰ ZABg&D2p^+ʪPVu  5bI"( J%pJ+!]kBq WZr1.1~> zPKSFMˌ .spyderlib/plugins/variableexplorer/__init__.pyU]o0}ϯ4U}I}IZH$+r,;rNM$=r|q/m$AȦy! I' n-\$PXV!E&q^w P]tbU(+ڶ[K1ZҲ,wk-|&"?GCtH"# DC̲qN'd ź$jv%@:uiI=LĐ 2{+H u42JTUo_[|2!^ȹmoloEury,bQy=nwnL*3~&߈(,p|=J%l =ݐ4(W)P ū0},+[qAD3[;O`@7Ǔ!g;Q1(rc9n< Gˊ 'zR?3o xN]@'۟2}+΋D(vvw<{߷/PKSF|Me%spyderlib/plugins/console/__init__.pyMo8zhrd`-oeR( 0w(QRmn|9c̉uKq,G\qI(;** gdtg4&Οprӿo+q`ijԢ-' i;6cP U1lt(sk.@ ڮg2mV6dx-K -< .L*b gDšqzqdr}Ʊܐ]hơ7󀴷Dd"NaRxCߋ**WW^_Mc<LbіTaҷҊwC`\ӍD3VܑpN?6_rmf͜ wu|vփ=ٱI l!vQK v?T3A[+VZf5>Lf$ۀD{)xA˓$T14~ 8Knʓ5WR 5B / [Kl!+0= @/⁴ʘ8\nEC6i%/g93k7uohljt#Bqpa#\̄ÚB4HC/Iϭȥ+SrY bࣙL}u)6}FB.WצnPKSF(+K#~'spyderlib/plugins/runconfig/__init__.py}r#7軿/'01}#AĖƒ(=/ e t]ZM"yHxf8v=BfH𥲻K۴yz份ξAU+<ݺwt~7?nq&̗a)*lLTʖ/2豎H%Fr>:&{͗nr+jluKxvxi~y4~X,>9-;ԝzk:>K^Սoa:n+.vo'[>aE_ent}|t.UۘN^vVmUVk-q~SAkEΟeWzz{:y:_eYwŻ-8IWU(;拫WfEgq.wkhڹn~rN9KŬDmkw/k^UZXY]wγ<7Ev(_u:{Gl2{XtW6/N(%c^yzT-zSf~pm]qH}++}mCHVkwS[ GA ONA|I"sN<`JSe}1ailMkn~/ {lK[7KqF;SexSnp4<[|QTًӔS2HogsiG`Хrn^8z(.T?O^-A:L~_8`OF `@Gg= h7ADܘf0duiak@(J\ UEh^ f1^ݙ`ۆF|e h&CP}Yyt< ߿"_S?AO?mr $g0 zg%[ڳښpRzyIǔJjGI׭oAD2e甙 ȕ~#d1g/X}.yVY[}_ KGñYkܖ4M^ƲڝX9g%?Y^"aѲFՄbWhia{àFhYE["{q?~Pć*_?]iHwzȍġf`,X9m< gڡ<p@zzJa:'r|ڒy'hi}cܘ<C{iA}/XNǍ~iş7 ,1E)nT)eC'BMIoVR\p֊'RBV,XiPy caqVyk:ۘՍ>-ßFC? Oc?Vm^Q`;g5GMchSنf>5>`=op8xZ9'6F[cA-Ϫ2/7ğ+Ă3KS"wR8jt*b*/1\l|Q#uHYs6iel*BF K85k_[Trx?} &~J&=M=ȸu˘:~0e3L֘ W_lk0a?γX;칡Ʊ\HGpR6.Cr~;6[0޲ +d(_'q.#Z^ Ϟ sUMUeLy]֮ - QPF][&yp?%u7˭e&L2dvgSբp7;(7EV yEYG십(XJE(BߋZa(A$o k|6_rsG ||ADJHRa>FPPa !&PQ w . βŷlWvR{Nz}m2]igg)# lS6> }2a=8s[gIW偗{[;WsE7m3〓)CO!c(#UO;!xp!4lK\i"j׹Vq&w*CZCch5`tƣA|Km:x ړ)|`='Ys!pDdNVX>Ն:ѐE`ǽu@`v=/ZX%X˗Ue-I{!T0W$L?VR:?ʟCySX-B ӬXέq9>SLtoFt0?uN]1|#8;7$Iw}}cURQӕ3EM0:4`DPVJvmrpX9 e ƨIgw;ڒCLm#DvIӋ1=cL_1S9H"*1N(;d! r4d&\Jpaٳ nV89T4\O#<*u!-l:>$M> bQL _&7Dx:#%Z)>GMbTSJ#.^&(Dfb98UK..l]T/J,bH~w ^G*#|gŸnDidA0'TTK;D(u€D}`EӁ5_.n^z]^J<ЧJSD<y\)"mVq[X{EJ aN@Bcyٸ7v`_K8,&RCEVFcmV*NL@5v16uGpQZM<$ DIZ\LV0D?g5F>z D-1P~qI֘Ft`Vߩoձj$pm }WFյ)7?nTGy:96O5~ӓ7֖_ӃHB(m#*^AQ/:_gJdsJ-"jDWޙYRS1N?"^<[C\w.T|ylMe#k*m|eBgJ inYJՏD=  bu]I, $q? 0*,~%@NJN}MT{S7^%[v ϊԤ)_c+.+Ia2C"/"u*\WtOui㸘GXf_pCim30N3;`^s$yz0Z/x `eOM(? '/ ]eݼ}*FqNKiZYhQ pxE9-XC&V@ X> +NO|s8lդ]8KvjI(٫kTOdNd_g"ɍȳ"{,EM"ˢBTGNW{H_W!š] /o jG#emn$k<%'4ؕ7y!C6w\KqumG/>tRlR%[ <3їA -2?CT M?1>SȘ s>i,צW^9 c' /˧|m͓)7oAf&/+żMqZÞC[|ao#k^_Fh&xap}E^BOex?˚Jf/f V;9JcIHܣYSתDM||E%ߪ#zv[Ĕy|]AJ"P)d70W^Krݵ8R]DMYάN7aͲ޴n.hq*[ F'=^̝Pcie-^.욝 >W& NEtODΝӷ D>sc`4r:9!qFJzUκ#5w WxŸb|EcX_YEDe6y-H6|G lNvhtR7Ą;Ӽj·v ?ʘ$3|18iH:8t^ B|b{p갣rz'-K^j9Yz2,^:?0{: 8+Qx:4r<. mxԕOt=QƋa_|Nr iԩ.⇣ս74s .P A@sQi7 ;շiɼppN @!`9kVۓ;*C}\%q9.:2fq&A ˞!Izzd *Kr]'i`kFײux8۾ b|9]CtdƧ]9^,WsmttE+虭VS[&yM%G˽Gb>HL||j18R "_k+\d@{HTibiays[&e'a]}_T_H<|b]L#-lClcR= CZNȳϛzyd*7D@䢥Gq# |IwQ+?+WXw?=\r{)2tN(g~6jmXt6n=!M76>5#?5<0{<Jq0,][&~UѮ 'οZ@(i׫BD.~=q["|v}Aj;~,͙E9[,e '(y(YnfT\W'7ak:̩>&@GFB| L^ ]zg vbw8quv~]DUu[-OծGu->vjB)b?d,+=ު$ gZz|̹ng_4`'&gDHAxw=_\>M7 CG|3vS4th[97IF`\]a`кT"A^q <=G4 L fM)WAw />K'd"݀q!ѼO3&?͚z&ƟL|}d@{:W2 UhPpKИwh^}dem𐌿CN]YIoDLcMk@"mСCkHmWu9G۷'h۬s~#bM}Y䚗.J 'Cګ#BOhu><~DiߜkIfG|s)9qӔHךJ7[.A'#b1Z RI"PWVveqI6o0x"pNC;<L,x(6 SV Xue\=͙ƹ` Ҽ#]i$QKyhAx^M(^ԛOr>C;“^?=OD&L;L/BbX oV4S\6ec_{xGȒmSx\|b ?fbl WUC[ .0L#b;t?RIqN <4!x<n$DfLSw/Dk8}48şMS;OҖT2zOg_rgaBrKŔ D  z.pRXHI`U(O ?m9 ㋔gV/Cg)7& |F i0j :ho\N% Ʋex_ZZ\NGD~ PKSF(\)spyderlib/plugins/findinfiles/__init__.pySo0Wpk{[*@h*ɲ{]=eKv}{~­OHkQA* FVzw0g2}.:S7GNAՌ)T)B#' T$x=7(+Ȳ&H%V/ WEB8UU im $e\eEW0kR=oS~twF4)Ji'b9wH" `uGl[ #aFKVG.Rٕz9cmŇ@3 8S {Gc|o'/0p:Bٰ:RXc3C3j9b#Rtg!& .;jNaq!UO ޻75FUÔ.9Q Skn:9 'xv _PKSFϢ%-spyderlib/plugins/projectexplorer/__init__.pyՓO09oߚx`=5MZR/[XOr!}}.,Z׊axQJQ@\ cٺ IW[AN \;o!CA#aҦ )Ә}T `T;2Qk83* ?cc1#H\k`'eYsۍ̩`uE894CfI[4PKSFvL%spyderlib/plugins/history/__init__.pyWKo8WX FhֻX,Zl(@Ru~ȍ x7'{g>9܋miJq@eBqi({*szST{rS+B=O30Jc W]Y߂kHsiWU^o\̬%a1 HXƬ\wD3hN( ؔ+)8A*rVǓc{EW$i͸L,JמbT5h5%R$*3}O[Vi>H I?$\Kii٢6c޻Z'L4y 5iL#Votʨc[XIIS2A\O'n: q8GrAŮv 0dpLatG,fYrekv(8CiƘop'*1Rj!qf@ x)g\ip,\fQ *٬c{cm^xNԠpk@KE>̱B;c0! ˁ^4EP!#RH(PH]~6+t(Cm8y P@͘Gi#6QiN8'$L?iX0ÿBS/Aߣywoq?_K*V|qJܬLW3q3 k7~yAu}ۤl`HWXw놆I< zf%Lu)u'n7;RkRV#f4AqI5/h4gvi Pjw-ܱvAPCTt)/z]W_xxFEl_bM6n|:*bnMm!]@g)dV ` 7PKSF9( $spyderlib/plugins/editor/__init__.py}ks#73;6gKnIEv˞ FȲr=Ze& T̆7b712H$J}X)z} ]E5@MQ 7Pxn*ɓXBE^}U:ͪ|~UfiU~`ϟߩ i2YX@Ի291YX@J7Fa?AU0̃CuMs '̦Wzn1˫/?\MB:ɲcBV>A4M`7M5OguZ$L%߫8dhl>yKRINt6{uPi]$f>jn¦,V)-ʲɩtהio} c|u0 ^%_תӐO0ovt0y^nA[(@90j{'=JmXa8O8^?/oZ1!z^uKHo) ?<8y.O@K-ԫ4nFAK"ɷTB8P+Z;LZTK`k DFj.W}PES X̿ȷn<&KRmʴ }G9q8^L,`D/P]*v`n)G6E^-+"\kPu)%tcͪ,1iɰt7I$Ԭ,iPD6 `3a,}*%ey?q =IW~DB|[m:)wj&,mfJuv>UvIfx[rE WTx*nMc*dYzP.ʣ$9yv\٩$q w'ETwiDGʔpzI 7)uר@,k U*KLm|CeR!jT]I}s,B\z8<~}[_`WZMENUiKqeUٹ4i2m܁9mWyz*QQ&;ڹzkEz@WKAWdgFJmy|&Ccݒ&U1i<&-r\oΪe^\#r(+m8A/̗krxo +T-zRegN.U|z6pW&>ӧuم oK]i8N§zk(˥P8>B+2m'r` [(0\ m0܎NEs#>Er&72Sm\z R#P P4֠K-Le6s_H̳m: uVQ1T6(J6_ 2"zQFc`G_l1vCn?D.N' Zቘugx63 u"f)F NP"4}v1>>eoZd K c\]tOTnaQ;fؽgzQ7*o?~~|Bm ڿڷcL7֜X,!~{ʚ?׍Ѯo2j7Ŀ[g o0a4Zn`o:jJ-40gs}ƚS\:JKEm6 ʟ*OFxG+r:q7z$$"ȶj̵9C"g  ksq̘MSݫb]Νc3J@Y~5u)@!e#ж#AGtd"8g.xG$DUu $3|5fxvЎ`*+c %&}J-;hA¼W\TOr%[@8o lT{El 9(c .nwɒB-S]@kRmnp{'؜7C\k̿`hx[EHP83,v6aX :s>f6OCg2I%8Yxw<驩]7p@Q7*4ԟ*r N;^VjQCd.ޡ8P)ئ0v|Lx;9ҭ "TAle6Z9KO ܈zL l\ǣM޹ι.'*wC T`ko V`ܢ4üLJ.42I |bmsz8(MXbL7Zf2~߉d05:; p]: :7j(\°XPU"AM+ nw`~Nf]U@O0`#]tDc`MQ?KhP.ōqu ){LKkݶܞ}T`IM0cV_:L2&G6̷;0J?oT[n܉}* C!We%f(} `I1szqԱ}*ϙ׉vK)sCڜ=(r虣؇*Y0ǁB7Qx!3\>8*Cr(m4ni]+<`n-k<+GT`tgEo]Q׸E %F6[at ֍lsaOV`{a`pkb\,Xg AF'X0j0#+%&-7)S\rkv|Amg;-g& ꈆ܏Ѯ4s!gdy,QQ/HoP-MG^*W)0cfp='{h( j^W`}ttfa3%h(j7gUx capմ@*q#wC9*h!b'Cx|GYe !`ayA6g. b ju%l#e0\p!;yՎFZAI+ZX0Eqۇ]jK>B0]-2\ we2uImմÁs8L0q/kN]0|w8;$rİ5NbQ ,B mtHPrz-V|&SO& hypn8ɭwh0rl;1m鄘t=L D ΄UbIeB E91`Qd=BpcK'"*φpLUAR}>IR5 pN 6htISu0oMQI0.њD񁭧=ܥoJ78╮}MY!8(R/zw Yj1o~`O,LLZ A;$0I'=Z9tQ6QFYtax3z)nx,pqTq=c*nҪY/SS"n)~1G889o@h5goz@BK[ى:m% Y&%F@ De|&VG}\ p,sMq@FQd|>w(c7ʁ2v(c7J1؍r((evXù둸yۍRF)&qvu]nn1RsG'p!`xձB|ǹD_8ac/QLmYq4Gy0 g3W쫙PI/4S>uؤ(b9{sbqᗭCr h.i\-y!J[ ZtG3&nTG(Pv~IFZtd|k8yЏcWGσypǨR{ZD(vL<78UdM`-_JĦl::TGn`nm=lnnJa }ddѕ#ooR-c1Ì[!@q/-`-av!T|EhMe,k* pQ{0bi%ЏYkc,NxSԏDwPK>I=XvbB| oqTm [8wܘ=^Y%J\&&l+*eL)@ ZDP-YLRƍIA p5ɺr ڧ~187̾Uv[`VGaRgFw(߻pn#R3$^dηsNV$> bQ~0xN\G5Cq{T<*Ӵ2mK3hQs qNZβPCp*)7X}n8> %s1]-;/w M*٭'2Sp&QmPKfU%6&БGg{cI-:37/, ԉe~J$3Tgqh^ꄗY緅huG"7`]<ƕ*ixvRO]Yw[#8.u"ou֏쎯t;)Q+ݔ Œx]\`gE'd(}zp+UBOΘrSN)S`L9aӛ 8tKL>cyZ>[`7ytף[Hч#ɳW_Gz'&9j?=*s.8~9 f g:I BYH#|UirJԴApodJɚ:Єɪ9Nk15j;D]O<9od䃉>sh|8BF9}luo:57Hl7tœϢ`H,دYIDvi%Hr'x%F}R3/3NXAv餖/v~՘l.|8(^oG2%L)FNIlCL/'ͽGOF>ܶev.[0b>(i Y&"jF~/44j^8JB%H`vtvBI7] IBz|S:IAqܐa__[sR  Ja1 Q2k]>V n2: 3L㤲 ,I:HeRرЛWEp_nC֢WC(Qd/ɱ7<4nȰO ֥߼J }s22uY-t@vBKYg` ݣ">,KdRdA&\bk`i}L̰Fߢ̤߮Z`wF;-NRMͣ$@ iu"}$˗PNP->{ O?bWeʲ|{wڎꤋx82ocX*C/׭fӛ F.#n{d>7fnbo #8Ml@OڻЏt{\| )ݛŏ@1n_._r[]5h|AU{g-{JffU[Si 9_ٿ-6fJpRs9)@ÇG $|n5 ~+c$+]"re`\Ώ<2PVP5=tE ֿ'qpՠ&ZC,ͶIRʴ.VuhtSO\sv@ b;)8'[=^b!kT\OWw2f9 Y#L;}iZ逨[1D;z^UAks?jFhm9;(#P0rI7 =ҳ4!|lpZ)э%{b) (Dp1%cN/r>ҵt u<lIznn)W+-J-dr[.P2\U^o- {h$W 9)AVdoU[^'IE>(T>ig#A*,zhlj4CGoVz^|7B'l`VkM(/|7Q_,LJ@). 0f.w1d4ÂgQi݅Ppjv1:h&ma۵tK@N*EjBb^nxȖ{0k Mҋd=^7.>xe1׼} ŶC4!j`edkqOm+ׂ k0 <c"`\K-]+r>Ό[dk|,^E'X]ŷ{MbVRnR5.˽a@a^_bv񒣪P2{p6I/^\;ldH̓|Dnv8Vf%zf_з ip,ğs-2fA^juJoDQ4Q})1ByfrN(MR]_;e(ɯdrhlCD_e">'TCn_&?\/46k`MG0b߯tq;{$"992{.`g @se"{Qe0B> 5m9A~|FGnIvGekI1pB$2y) s=ys/XyH%[,_㝞.1&ĈwL[]OH!9 o:CĎPW9d?V/k3sPc՞2>2IVη˿QO:3J}e,aMYlt ό{. ZBv`<O*1S`R\nwOa yjdJ=k\?FVnm1f%Eẓxl٪ُ7Dۤ|H`yb=[_%rl6΀Vn-HYVR9])^<̦ld4Zט3]]-nj:U٨dQPKSFspyderlib/qt/__init__.py}1 0l E9(:9ZS8l\{/m}7$3*XXHZ%1-SBSi&}~ ĉVi`E{Cⶡ28r]GT8<:f|+:ʖ6h^:.w^\R7u z=QV-[u#Tӡ#z,+jqI|8R۪7s?83al_#",_Gﵫs?YPKSFsEispyderlib/qt/QtCore/__init__.py}r軿oga&/7>hfEQ"!Z*v-鯿 )L='BDaGnH$bzxxjtt)ʺ)Ӽh>"DY3<\AfwGˣ'Ї8B=}'GM >Ơˣ;nӋGfӏi%a+CäY~JEȚjr6LJQcV{SMVrT"2n Z"aMϙ-.έwoSQ<(O/ʟB'{豊ӋmQwESy'+7u ,֛Uq!'eZ$jߧYF̋oIy8Oꝏϛ?XWi']UŒWyN^!ur iI_vܹeZ^+XIЋ 8o />d؏`Za-.[|Kjs,NVI sIvݬ]y[yZ7nqܤYܠk+=dgP]5]U))֡ml6!k"nʬ;ڣ0(`ZrA84m!N0=tdᅧhPv;}lw,ͭ+w a&@D2W:$X^[aޠ?FZu#5Jg;ꍇ1vSX\ Lg@Rp0QVó|mOFVuU,XCȄ-K,@[b;. {ciwdpEFQ(j۸7۸pQ1L6Гh{]aAOfj'H抅~V?sZ' 5K38&VϪ_J/ޞ>*m~q<=j#o )g[m'$i RY _R+A:G0NE5/XJ] >)JJ $Íxc瓴gKA{8z1{kÏ:c@buD\}w?ϝH_[Ȩa؁Fw>^[E(Z=P^؝ ~?ֻ^/^u2mynu6%=pԢ߾;}x4RE@6 B'kX `nHLE*gB?TV+ֆߗ^;Â:BsHG>^aJj$#ݞ SJ?/ϊizOE>$sv* [,+P{XuRiq\?V$ DA|z%H2ũC}`֧PV' xfj)+` w_07ǿ@s,5J0sH*>p]1@׼1:tTfeicdD ,jg[4\6N`映"<'v4!Yه?ӢԾ`+kh\&Of eK# l^ի*P3a :fC͠r"{8r$ç! AmbA"|}5 2<r'~Qc㿂ʯ6[Ŝ4[Z}@#7}Lޞ:nBBil \Ft_-XCa!G *_ gP61t ЗA:7Lt>}-!O]~} 8FncM" 5@^&ۢYen IǏc4_HX!EV,& ' #:"4K7,͢ĴxA am,@^_! @ $)88.]BBPs\P6$,p mӹ|#,,G}nWɘ\YofB͏UmB;%Mu&MS~SUbPyA]"2y:2!hxh|DzΫ.`!Y(:Ɲ^w}lh&@ioP ޷{oMiXB<Ḁ E[w{B;X*_U5yMڴBYұ#A6x"ֆPҨp-T ի#[X:*CNA1/8_KH5ғ1CIېwv t]KR4$p<&f|@b:f`a!7u #!4 Dg}½xτBE2 WavԳ΀,\:z. NRLaS4PH<\Hط#$𭊲7,@@@*#y^ +g BH^DChΨn+7V3 f)K8{,Bִ;%}O P:#9 h3%D-#3HȎ^Pmys|uJЙ,Q*w X]r=#QLx 嫄CӠFkXpL&=usky;l5L @ $Fb =  Dv eZXR_u⫸?ɼLE q_?95xrDp!./_xŒ9'PKZ@ttZiϏuj "MԠ<<&5&HFR/5^mBf(%z 0JtDWd@JDD_KJ aQjR(5a:fSˁBo "!;:O@r%;y8@j"Ɋ܃;QHk4;K*Фd䭘4L]%|m|sS/JXi/+A}w8x{|ң΋e$4Lq*H&p)yȱ%p9f%8Cdv1qS5V.pu|m I_ѡ[!dA[Yr9 V,ZBi@.NQ}2u&try\ȹw*shUmﶍwƻmݶnxm6>6mﶍY~ t`O)94UM_"dChI9_i?!%GV4%+[̖2X;>Z#aHi.m6 p_6'_Yu&(9뤜?=&@{l,|K6} 5xTST3;Fc4.ԣ4\[P6Z}Z5$QkԺv`)4ruR:1I)DT+?Nx Z%R2Iq~I?1`?(AJCB95Ijۏ] )PmN.ӆW'u 4Aa'/$0BcHRɢr " 'W {RH9ZS\:nf<($w > R,}R f'WpW!ۉ˩ׄc&/OM=M:QjIZ]% >I,_h!LNj12$TI@}dDr/H6UM :O*$+g8No]V`5RF:5 6 6peAtМXܸ\eb ·7ua[!Rt6cFXP׋29ȊJ7ٱ̀WZ6C9qZvp*#NJ9>*J Ѱ/m1I1/+'#+NNG G>Wp(54|@U<\L!#^'e}u0$Ycl,ʨb.ℍ.Qʓm ! T7_D0t8qH'i2/swDㅃVE^`9tr ZqE^܊( -ӿR49#`:y\O:S&xqqLJyT5(5}j$yRsHU;˦Ih# h>tROc @jx #BYdD^ņT?:{-r&D\Γ_ty `Ufk[hGݳ$1:G9HYi&&t&WLsdPO.Ah¿KAdUDmO:ѠJp{^ yJ?#lWxjSS,Zp-[?N|JRSTF?%I*Ltr-/$}r{U:J1`[`5%ydHsAd$S3 ɰO&>dD[2PP~ 2S HTU Ҁ@^rf.Nk:WdYEHǒO.J.27/DQuLMUuR},jo 30GH+ƚbDED](/(?E%VMoE#H% LM/? cZ 4$C3DabJ9Tp| >O-57A]?@2}dž0E0}@ 6W>)Zj4mRv(FG5u91޸,3obWM`%פJQrƀBŴ/j";&6n?WAP`hldRF ѝVIwypcK/#cxUTj9Q4z4.ԅq}`xILA][)*g2˴^5bB`"\/,E4/W&t gsu2}hJ:kafJmdNC )(U+W3oR]Y&I@93v[b+kJfcC^m{nµRҘLhH%掖l5A"b . 1b ³Eua>O0 G$] ˠ;YmuD* d6\`I\.QL]0gotC)%EPS*ETdϦA zup.fD$X%SOA$sןHW'b1I8.41zl C!J0υ>}3̔H8I\ft 𣏄|OvԕK܃c8ے.+IS/9YY|ҎPC Dd?Rۢt#lDx"#t\aKכL+"t\UXgu$t;nHHЧm"y$I3X̃hDڶ Q  ~.?.v--Ԯ+tk~Ns`nP.^)+ %:^-o:—Aki-C0\6"P{컬RF5JRh&yԞyœ$?IkvjyW'PRPvԡ/ҹ3DMMÑ r^a|@$H0M݄Db@/;@;|x wISL詥﫢ZIQ i .?e͓3kF.i&:' D4N86QVMWD?긆f/Z+WuHq7vH/7SE r=)rkD a8O0r '4o%tJ,ms#d˴.,c m}Ԉ%HjrC443r.AZ̩\z5Sxmy[+뗋5s|v)^s'ډVK|NJ6;&LXFR$1 E_xL"WZg}-Jٗ; )_niǮOQ[". 3~gT脤|s|c ͩw-&CRht&CCz<7KMĊ> 4]5]|ɮt4:T(9-ܗdx)<¤%tE̙A%,>iYVن$&['61N_ e=EZy CʷI t/4>P9ؓ]c}agUdI急o~@uߘ $';͢f ϱ{]x'%l$(Gb~ zJ$#7QsdH\b]߿)? ^ΤmG@4AR7EѭB[2mgKZOU 8U \6A$~FK\T>o َȚVȷwTJ?<&-|Φ['-s?i5;-xlv`Pxr0]VИp^*{$Y0:K0dptZ464Pr咣=B&=A|]C'6{5 E~?']8_H;uyG_J|;4 N]7?g'b|{w7噻y+FdF^,GpPy]{jS\]rX0,B@Ƿ0x=(gAk p]brq[(Ӯs {TN愘7|bc:5C$UAْAUI/r~пB f{9宫iC-AY~V)sOo4-޷L+Jr~X7b]&/`B ؞7; ZmqEF@%GE0]F?'J|`@Nn5cyd٘Ekf -{􍽁sήw|p$4Gp/] dv$JN< kƙe5JtK! xkc dl`fwnI"qnN;p_hϑ6gtlI_,(4`//rA &Pxd_$G9!B `73-i/ -QJY8LAw;0e A1->/ r2+v7U9 'o %0Y (*}"@mOE:E;* 3}@8k\ADC<n}Ѕ S9r `Ա“=6}gHx?,p 7.AJ]єx<[I mxFi0ne | Nޔ&x{2B=$Uՙ&*%c=:#dNOQJP,ɇ*"G-P*J@qbGk5> dVݣ5;H[Af&𪩫-j+80*t>M+з|y&>' |u9ti. ng4"Ʈo&g ™ we@!ZH``*yuA8Ua}H _$!%>Bb5` h>ڑdD4PiP9LYZOYa'a77k}Eo_O<2ϼh`*+euq\٣ܝ|z @~T|1_Lqd ²O7 P 5i* PL2*uӠ|,|Z#favuo *ǽ췂|K@p<,ɟ D[taI_ˆ6P89Վj=xj% ,/7$4jE̖{7֝fwX@7r+ly'3صT&cMB,|9LmF'G "X6LnM 88zJ6 EЂf{l?]+H!AS:&xń`A74?Ya?aV !{'B RHn ,}$`5!QG8"B`uHuzWX x1F&!yw wż?W$N[3Y3@P/ҧ'mVѼGDŨP{84 er@Da eV=I-fkWt&Jv'|*癯N.g#Jr ""q]X(}M:at#JD﹠Fǝ#=gx }Jtwy]^I9M4ף랇dr.@GoU(˴GQ3 YwxaB `LuXdawDU^iu"\4EJzrgõT\iuaiM*-7WM|!j\q ~hvHTePa;˅vLGb<ey p+SI}uhp$J=ޞ}$«[ݒј x'p ^K$1o{ &-}aK3cbԒ̘$.3&&-q!mQ2vUrެ2GQL'ZbqzO 뷭E8 BEe)3:0?D=w#c(* w޳6EKWvVP9%:353`sX=izBӒs@*Ѓ5zOv)hbjiqg|o -~cLBARam\{<4EwlYY[<A{!BwJlmP:;#Ɔ`\UEQY7{N:3}é8k\]ʣ%t "{6Ԗaw̟O:1XO|)A:ZT╷6gQ# E9bwǾMtܜ́UBr8,s1,2J/.9dM뵽;&ӗK`1~{ ﬈q_*cN&4 P\GCӛϡK%Gt-l$',=ZI.^ڃw5,}\I;IJyG8UzI.:iN$QMQ'5o'FKh/:(D]%p(f utKZ=^-jc\~T׃&ϯg$u|4W!3x=(1UnrymQπ>z=#^]˱{9^v}/qw}/'ˮyҸo=Kc=K=Kc=_ė{iy4sDs #~,jCa^FzyK}c3笞L`-1-6zNTAѺ$u}‡i$2}Jd)_yX+i QU5} Ϟ;n7 n2u%|Yu×u/b]|YOJo5[K\%1%wqN}/D0axwB댑Flb?_\&yzyFc)wcؚ~4|egD#=[yD\G#b1~y B=b!&1G#➟1{~q<"G=B܏O*I3?WGWN^c}8 3C qy]6e `˫xRkzd`lJj빊ԓD41 f$Ե+G!E=ngfFN}ϞśӺ?Q3R޸]fGLIǡ񟯽lmOy;/cor2ږP׷2e<߹b*:ӳ31ߢCYBhe4jk֣!j"]$04檩(`ti( :~kJ ~{]UͿVSt* %n0njMMmD8ltBa1Nk&1Ɖoŕ+sF㺷-q$? 0~Ytm:$VZ|kc]k+e<])]K2\)Ӊ_V\%8w[7`28BEFHZ7 AO_ZrxL{+jwHw!LM:P(sO08fzsYxnMe[9wFٯO?R!oiWjhw@O(. Lk65;#d1*n ,)6yrB>\PN֛gi}r񉣃>'iƯ4kF^d}!Ƃ4մH mM;!CSH腭a]g_u6C3]Hvo^ݺ$h$" /Р ہ@ñ[Jsݚ5?Ek&sS@  "*! ! #Agr߹E'PXþ%wЁUh`ebč9/W7O?|oh҅>X_Ѕ(oUw9$ (툸ɋȠKԋmr@hE 4֓٘RrrNׅ,Ni, IhrR<%ݧaucp.)=~݀ϳds΀N4wMW9فGavӐt`L;%el`A4׿uTE|*!tx_+|q8Ki*CIW3B)X=coH|/ޭC+Ɩ0 5^'nj6"EIT/.}ѻzBtvf 9N0A*`@V7C_ [rYH$[#IH_BY+/7XL( 5Vb<[XX9@f`_5x?Q*6=c"ԫ= 0{n{h,]%2KkA4TyҀaio¾z};I,R#~Pteb%K/MJjY@ H#܉er/Iy@xd\"HA䎲 l27GS- l\r5cܝtQeF?JB1S@mZ'R)I̦@ofps V ajA*=7&p,IP XZ(RF0v&Mq5h$ u@Bӌws%NX](.Ұ %feP6l6TZl=M)ZAk'~Cmmkz gZ|.p1 YC/Hefp;7M# v~'NՀt{C*-<>6d걾/NJ@L]G SUp~,\D >ۀ '7gG''g kI FOP9G.Q٤S|]d fĊ7`0(oK| (;`i2 Ü֓3qr$z =\79*'C$ɑ'O<#}gnMwH-b37/9qRfEkC_y G#>0vBӁcPҋfRPqU"[Q픢:%pQhc´IEmkN૲Ytufbզ:sQ'jXd7f^їuǢ&JaL)љs/0>t DDoy$>8ї@3Ij!]&+%_GD 霱Rt;S.$ijMdH|1QT^df r #|@p]x~9)/}i`f2h&XH`ՠ72ȎY%WB}|]gJ7a/ԗ)hNHd`>7P!V'׋3C'5b'Y0Wezj)+AfT "`кR6I }1=2taORNK,A/&qx(kH$ZlyEma7޼QH8Bj9<"7vd@-&3DLnu >EmڳCَVudQ73iNf8jݖ5\ne-95G{V~K(v:o,VcɖtVp(ӛeu龦teBKk qd$Y E[Q"200̹C@ KXH#@EMm}] oͺcaږ$fDj,<ȠՁ%AG , @|=:yn$ y#0H_㝞(\$ee}y:Bkg},B 4U]!v,~j,.719*bHx|jwNh$Ym|!_9,N?Z9tΌze;<' A_M\~?DqOashBe;P*sB-q:{ 8ڞ׳??[i OB}@2ɬ=Ͱj'2 ?8~7&9>aَ`s,㕳sUnN^̯SM^@)*K^Xp26V~l mUnet X&~^;_{%Ôdm 1 xV+ .<4/ ]1ym0eڔ e 鬶1Ʊ.[ڊ).)&ˎs%Ϝgb9ߓ9UkDzW{wBU8m5JĹ#(!h1m:=;cW|Ў%ڤH`8Θ]brrbo!Z4B 4!RH%w7K Ҡwqs$ tlhx*Q7Zˍ:R *x!utpiD!J(J9ŕ,+4K#ǣ~CX=U4?0YGg =  چo=R 3?x%a6{jM1eP|Ϙ  Ot J wBDKXg +4=?aXRH98jih\יo TH[a6t,slY#/s6=p[#njse+6'ƿaѴx~-Uz:͗r O}ğ~7_„[.״ߋE'쾆 /5hԐV0#_$rR}a+N(ԄcМa ^['ʌw|P6FGݓ֖/ D|&o~eQV4-VLBFwB*<]h+S`- 1d(b}I72-:q@PTA^#޺,GH_{ A~#  _##.rC `{M<lF:gNꌹ[؂˖YV&:ֹ*:n;gbA@hɹ`3 \ۓ5]5ohRaOSn)Gޠ&P0Z=Ii~Qo?w 7tm#$H!^- ⳯mt}9MiMvZKeK)ЎyG5{%w/ݎyX0L54'?=+k({YqEqo8.Sh!3)#^](:IV9]#B)ҞrMfkH-XhOGx{޵ *?\V hH>\gBٗ a^R' 9*0zDt;L$P l;B#$H,;(C$nxu4۔oDuL8BFA|A8]m^C<8Cƴ]hI;n)sǠ"quGF;͌(Guf \#L #; ?me"MAKT0 *x5 4L;?R:zAL.9V$S.*P_KV$q +H&:0p$WqL0j1 D&M&KFä:bqgÖA$+( Fٺ/A}%I)!,m= fj^qC;#h~?:E錆g633JYuCa?@kJH ]س[g4qчvږ9;: |=RqX5zhjxj8bPKSF#%."r `spyderlib/qt/QtGui/__init__.pyYsF0_=L\n@m-fQݞD$L$[@>ck\[LԚk-uٿ{صZmU:/[ -Wm^{HVB؃fϢ>e>d~;ת_6ٶ.QY>ekusF s^ڶ*0NvzXmY7CvJ5=?w#| V{EwY箪r]=m2{TK*?ʛm??V }٪Q>ź +>VjWB":{,Z]dg kzs95_*|jvVEUK~zmUVp*F9_cc"'FD)_5UQ_:4ke֪lbҝoPS4'ǁ]j}GɠnԦ ,m#r[a So3 fW7Umꉦ4k,U)fȫm(2/$>ܯA'EؘOf_$]VU٪mp17k˖[ Y赵@0B~֜T]-f$Ea,&R.UKY[/v|_Կ^f́zkZs{Gx PIapUàFٜ7Uy_@nW 3rIdP_DE >%@SKr|PF5O R<\ liǩoͷsJFpn}xUZeVDf Qs&kc\\#0)o{:pקL!ă */uVO\yTQ߾e@V5:o/ Rqv cli,Q_TvBZ}Y77Ao^k%VF#KnQ $G͡Ew4vzvpPpZٶq IZNw1L+$+8vELIFMkUY'mkX&T5<ހT <.m3Glrȋ(vb]f yT=lyHש]z ~ro絶?e@33ݰo_6wH*_6v!0~]̗?&2e5*Y~_A|Y|?SŁo%rUe{jg L{xHIz-K0TύVfEPNu`[% Szʝs,4Zfs"'^ɴ Sc@E 4)qlJ I{B4FhhZ^Y7!(vF)o1CED<(kDHZ<(xQ|_ W` EaM/qVbiqO;S 󒀳塸9׿vcE:, #Q+ZM"_)i/I+ާ81¹۵a&cL6( Bncd:ءKӔ[m}vS9UwϜX|O\F$ h +wSB:z* LJj~935FEկfrMd#oF(T kQ84 T]0h!ifR2P_d'.ǒ Y-qZ [vӁz$n@Ph V € >] 67`àKyFk:3 a Rjm(]KaBrG AX+*85p( c9b[7jX;UCQJdFvz=z'܍}/~x2 CR խ͵Q(Fdy0c VMhkܦ75$Qk&  E(R"&Uˎ|#P7y^rUZ,~V곞{J} |Ϋ({6KOOٳTek%?)/+jg0.xfI">_'lBPÃo.8!B?!B?!B?!B?{!B?!^B?u x,hNEiY%+rqLT;xC%fuM&<Srݦ öma[wVj0$X{׀k"WI^7؎G\8h~'0-6PxЌBG"W$F6(VAMqn݅vhѭs8oJUR0di!< od6N1I4>)xFuE%8Sr7-Hy8 #ѥ_fhM[|!5h$exBr*wH,\!4؇q*C?b#s|wǖOL4cK@pٶpiLХL-YMy CGJLőO/=ȩ: erR UY]=r D.>iPK/;py4pN5%ݖ=Q䎻},(i;nԏqwr` [( AϹ#0=G"}$K-kIp7># āH0"lVu"xxGñS +n/+%eչObMVڛm &B s+al ]>ݩ&mв;MvQK f C¨-=F,ɵμm%ilpw{HCQ&gxj{ʖ=3q4҈xi^'hh.nt Lfҥ'>^mHhjc2zDDr񘭧9uq_w3t x4Eocqmmlb ..NJ6*.ZIoɌ=\HS벟])*se[9[t\]]q/Ўgqx-|X70wY&ђ^nZiȒ#6la-L$Ec*Nxw%go /#s\^M#K@:靨 ѐ.vZF >o$M:;񬃒w܁[x1o r ?Ù]VΙ/ t9zaL݃~faAsm9#ٴGhۮeZ:u ūm,(X6އ2^6¸,&Q*q4L|ct`KE""bZKCiے(kl1^6RpϠ0A.f}b>סOC >Rb uo_vwm*v*u'E}2y{8"oiؘ{S\mExBj텉]nN>ёZUu&wu:)7 s*aHw`FyZp&pKmiyqWsh=se׼,u}抝|SMȊg6_K,Lu}Pj{|?6XZ~.V7ȄYtAS 9b?!1]7E1I8&A'9vJ=ʛZv8'7AٓzRxIv*^rؚbp\ej8hŻy$3.M9Fo8D t|AĨ%|OQgrbU}'@Sr}v]7UOg*#M6B9l͞]=u1; oճo#7c4*c_҅D( Z?OekQWQGwIc!JcX\oQHí.CybE|âO.1w\f_r\l7HfQ:$W, Hqˡ>+ %[8kv2v+lՃg`yTϴSOqk[#E ;tM\p .$kBWO*#TxVZcŐ;P=<z%ɛFOn\ MG>YWőC@OHEEjL#:lv3gXg2/ {T Aޱ1مȚ'>?ֲK(q(RkVL,va~9f'#Y,,㩍!b^KD}O_RЌUE!{ UWɸKF%xh--ĹMd+t(P!Z!g$tgZGL{9lĩ2Vr=_7zUERc 8,Ƙ  wt >&oV7jσJuSEa'3i2;WS=zO%ᮮ8!cOf#EΉX~mS(m5v;CvIU s>-2^ēU 7B&:TP8ξE6;=b SIԡ#8t1wHDʝ}Ym<"֦\e~{~̂gMK, L݈ˉ~}?7J`8dNc0p0=tK #n }>m_}'k埬^AޘRP;\ .] Vـ!YUh-9-_A!j; p°O~=8Y(k3 ^j򮭖M.NEV€",c1PznfĢsQ\V,]휫Z]6v Z;Ӧ}ѝp{;l6-nppƯ|$hwQIː}>0e`?SRWKp7HR,b @xvKCb亍[m+m坞$vۢiwD~7 n_yy6pY-\D~22XWbcD0 J0Z2]SR4b0-ۊXNt-(AQX{/4ޝ8}7S[G4wcqN ALa(f$kHZs)BiȾ_iPVrČ[l…4F \&} \oWxk[КطSg+ j$Vt^^թy>J#I"IcϛКqrr&)B'_sӚK̤q%rQ-K&v՘/ t@  _gQf ΢ph %[\ !P'c= pn58`/ޙm' }v(kݨ%=׺)=oğO a[*p6@@wk+0`eպ.Ų׵vRg=Cb6$C<$C<$C<< 7<v|`;~/v{A`3>f|0`3>ƌ&|0 L`>{&|0ߋ \UWs:g}kk6LUE 35]+?PU#H%\ruNw3JǪxbIt `z u E-W~l_NuAnbɗloA1o% )rΫٻlK46lȕ{8m(B z;y_%Fyxm6+HὡUV%dGծC#`�-jUZH&ѢH֙[NuiQde5zW {fjkmz R*=s6hT[VKY'բls=0}yP#͆GOQ*#|"p5=Rt]%0 >Ovma7w Sz+Gɮ(,ibY~.+Khco[.+HaLlMr-5SV6KUХ#Ko2 4 *<9Zȸ΀WB3_#\d9QPtܒ!.cf: %cл}, Gq_ vwWI^kcM ysU>ޏC Sv˷$ĢZim)5k(m!*Kk-=}?\궀9#TR6H;|;<քﵤ`UQN0ToTgrAf&u^Њ$%+ǬιoTlfP+}v>P5 HIӗeD=PLAUxg.[ =Jd-xj+ :jïva0fW@7ۂ\W哮v]Ùn BwVG L3Oc6GYf@'IEf}U[j sG~E":~x,w顂߼l+Dbkw ]w_ =w谣,{LnJiBۢ._Ps~7CoSAB$w[aJ[LF8S~5NGJ;TSg+H8`#95@u ȓ"{l|րO9f?euAn^"Eؐɭݗ"}RY9Fڧ#362RIХMP{ݳ_3R=bR_ Y}noFDb*#!|\7 挼:o@ny{_$AAŌ{4qQe Д9; -\7TN n%=qj(X2yq醦=@{%hܺ]߯އWn*wcW95}E/W-i㄄iG |bȇ ăBIҁYq(nD}N&H>h;l &(lu K|6(t J'(t~\|wCdC>N4/C-襠^ z)_0ډRANP8A fS-cA=cPA=:xlqՖ/jWs+8)OP `E7J^h 7h.̦oֿ{^ 3\. a0e2LV<ͻ1?= wf;3Ý;3:4y0L`?p^Mlwi[>|-l`[><(`{>|=`{>ӞG `>}0A `=8}0A `>{}0ߩA%|=`{>;i>X}E,`>X=A0A `>^0A wgm@G#m 6Ghcxm Z$hE Z$hߠEdH\=d ʕv?qŕ >9T x7/z@n5 ^mvzd@L]kړ^my{t`/kJEotf t*ͮV,w_zcB8F Vg2xT}3 eVp_/R3_ƥKr_u(MD6b,#=4BxO<1srRZ/d7yrb,ZOxX $%q­kCoZΈصf^qFtwR y$MxiΈ]^crYKlkծ̯xS.ѰK4 D.K4 D.ѰK==L`>&|0 L`ݘUx06| l`>O6<;d64r/.alzx`CQ![B-o!x {[Bޓp\Soޠ`I>,/VsZUlzdѴ^^AoW_ V[|8HbNhӗWbDb&>'i'D>Ҝk3%+r u꼨ʊ؁/X_0PWMXZiO/-P1X6Dj3~_MywvuBCth^ܞwæ؀wpmf S;{x<\YYY_d;GKuAq]c#3tY'0*'s(k3Q.R@#5-,Skb=Avf:oݦ+q?k[>w#'34,D+~}[Qpeۚh2fHF"2GwPМKo#V3}uPɺ'W|W|W|W|W|׻|Y,`<`>f= Vovr[`pAJaŽvֹ MٚRp|pexTB$=:w^VUL%wz}xkZAzx;d2WCTY0Uff{QM,콇ST{@b{ӀoCL썉NY3\8М=ح`7G@hG3o|[Qp&xg2x!esł^;t ]>m=jv9h 1өlcMDW|:YyslF xխE"i&e,(k2A̻?'*T4۵%+ J(-WG?m{`V7ȇiqCB5A(%s$5;KGTh:h&IQ#=1a-N3.6^;\4ոX=YBқ.x|,sV׏4IId}iTp?zWWL`Jw{*k(o}\< 7. m^Eq ,je~Qat&BM z }x$ȼ?znIO *-2uCz`!_(W@21y.)iHm29r?jpA)۪̂1n+:$t;޳'o~ > hYQ-0]mG(3x_ ޟ;P~Rxe5XKƕP|_"ˠك,< ˃,o|Eu |]^Xq'PLCK:(ff<6~E諪W/x6$rjhءod|Q$ߤ"f-7kIYYki߸7bSկQ s^MZsJ[<)_E% KjF2!w57;=v69e4?&VئW3wC4bׂviOiS1lӹoY%Iljl}eL6.ĿMiOmVpُ8I"ͧ&7W Iyx[6l g3oVkaf'X*mO{#{4Ms:(tKRܡ7=A7ʗIqkT?d`&+{GI4e>"g |O+/o^}=m3k =zWJip;4iN om(̦3!7am8mS! x{~~"5f&11pCR%Ffvu%g\g8W荖6[) 0ba&p=2Pd,^+ ~bLjOVx[kQZƅ֎#m?%e76}{=}8UE?b1;bg!sT@k BD't4g ;3bGNۦSc˩*RI":_/lҍJ{vuG;|xD`tkCS4"A=ϿT'i~]meQMK5xhK( [N ٙ Q Q Q Q Q Q?}`=xwrCy<.)8DpTRe5&CX؈\F)-ʮ̍_#bU*[".˪5|7 8)Q.!n:_E%t"Ct:.v.N;Ê*CC۬~!$OKNP M74,bu AX7 ~MPAyX5+~mjiun؝Z;A̢\ >)|}ҫO9]7ZBOԫ tn>MU7U> vvZHj$i/q \%FCS$'R8'*;JbP@htq!LeʗQ2ǭQ-ϼ+V% Pk ̤k46G<77¹S5ݚmLH#՜AI]F@E"pk'HYtin=tdtP Y>+٩2eqH#B}9JooW !ܽETՒ+X]/"^bkiiU]m٦YcyٰFR W.'KmwH<~e.O&w04ܛN%ߒץ߈8k xW[>`#>Uϸ>3V|?_t[u1vj۾YmE 0&Ȯi 4<ĵ^?\0Jd%Im M96@>xskvj]}`:'m!)&Dv̤VL^dDs LE 4S&9w J|u]=j-%`nTS; LW&)m,_6bA:pY[D(]L QD1K|[n<2rYm,5 WpK^n۳ҩD.ƛ[Hg1".&ҦTDb&b1x+8k+nHA$ 08e$ E$\DTLd\az,P GJվ ?nѱBܻcCNJvx("8env&{"ڊbY$q\ו\wV; ʷ N"a ^Uć:{E_lF".ۛwy8qc]0zfufFMzԴo \V ):0XLXj=Fl/w'c.”ck׋LIʊ-F+ mGJSVipK;2-pyV97v_*" `kT_M*S9(o \B%\B%\B%\Be/\B%\K>&|0 L`~/&1mr> Kׁ(`JV'_.t_ٞy9~f@Y<,Ȑv[*:!zr3`fkٽ2Wesz=g:B2٦r[MG2Y1dgC5Au^~V.,zLwhZ1}s4,S0ާlݙRÜ~?,RoLAI9dUTrUsк_ݘY6b9%mRY6_!3tVTiZncx' ƲY5p桝\OwT= uΕϏ5+٢3_Ot/(a| "Lzg;xN}P \^6+|Z(8۲AI#!k8rQ N ء xYy5\ ,R|·Fu~rnhfYYpF<^qԅ/<"̬⧄7!?{&sy/@r$q%W4&pgӅe9bvҀp/1e0y>_ y9fO-ɐuI>Lw ȁT/Tj<O)y;s늢!V܎P+׈zkȃuWnKwjFo;cn _SVݭd)HL$ꕈ0Yĭ1Lq71|lf6DyO+aඣ;T{3j,ّ;}T"'=O<@ķcs2~Ofb2`= I,OL}Ag=+5j̑BTx{!M}2/ԝu1:VZ4PK{+)I&g!\JZMRPtЮ6zcCn- z9)΁ȅç>vt_Iw"`h&ۓn%iNg͂#McqlKV?f>e%Eq&Pp]6YѬdi%v-'u?s7%Dڅ9`{aU(ǩwJ~[Oo1O "8& s7 (3}2k갚̝Dl74ܯ/Xfd5Arzi06ȅ._t͍>[.I.|? 6~APp!Y:X;B!߳mXܙ$7$8L' M=m&簪l#88}F1x!0BbMkl]StiϴWZOV&&mߠxbB OW; R+٨D-VҹG[2cױú۱ʜpv٥~kE:b^<*1KdCE^p+*~m4[Dz4$Wd}ۛ\FKz-kײ#Kʎؠ/0mD\:aCcݝo3Ƨr&ײ{*dwwz'ua6ۈv8Ф:(x N؈wZ.70;e "rØ !3ìFrF!iж] aGu- \m{F>cxʼG0. +IDJ.M;(:X>k+.|%X~H-HnP:;Z ɉR 3udaL]vAS:iSo@{ewڼͼb uzоl1"U줥U2O*1dŃɲXÆ8rwyoKV;H9?2O]Y<0I':RWӁR\Ng}<=fa|B%  H {X+$nMu9u8oUw~<8n|g]%OzX\v*pI#zsyY8Ճ]|鼃ŀo]mKoP0wu ;hj>G :G}49<(&ķS^:$Z+GyRqW+&Hoӻ"/?'p*EH%gLM 7vj]gR9{1p%A"8QK y[ZLn*4Y i#\>)uvdsM'-퓪|zqFksΣGg8FE>nWOyldOOlGoHg?~z4 6]HР OekQWQGwI`Oc!JcX&oV mJuSEa'U2;W%aTJ=pn>a d"0%kl! gl1M^cH!b%af("a@/4w?-cEHW4#L:ȁ'qqevLsz0INpca#{@Fs610l}R Jk:6~]n'ڒ9GD)(CRZvegBLcc3\`TЬ899-huėk"4kL' 6p12ҩ˲l2v?T8NR_o$ĥs}@kpmyW6L^xGc;X.&Kx58S(=tӫ~lBȃy H\f0. =1ri5h/9v"r?vX:XKEHޙ݈X7/ؓ)SᜐsJ8Wy,;lD.k:oH~uRq7iMIYMxsS iu k -du?O 3}Y^cy; ]a~f0k<ĬfN8R40Ƥw2wWc!;cc| q;o2kQ1`VR^݂vdC `T/\ˠZaqU.V;Np?fhǯk@kSݥr{($ PɏY`as;!nk~Dc C04^y߱L 2ziHze|1_̛ae']& ^4~m Kê 毷jY5X5uWy߿}=_2=A̾2N=4ņVaᅅ'[x.<|{բlsYcp#R *+z8x`WښEpT鱩QVӣM8F=,N_ ^5Vi,]0r'q݄ ?P{9սiGY( DQmb9|mjbwUk`4=OKto^} nҽB|zOԫ~]u+iB:hWge>۵YD3 `Tї F[4 LDt*[-Rq`X7v6=[AoW4޿]YoLAp߹4f e\ xikf/ʗp( mˎj_L{~iw {HB'nVnK=vI\&Ugk1PNxncYՊ^kfm:~n0_d*g& .[C.wT ; ~zm`(yOт-lLn<Z'j,edAz]j̎[L`ؐ]520Y?F4Y+[3Ҡ65q9᭧Q~;d)h2eҜiC3 lSYS^ōhE(YNEwz .SxّdXQٶq IY;zpMezU֑P&Y񨮶"O~4\Y>{t`3T5Ŭ1Щύ"4'+!ޜKON3_X۪6]g*~?rc^ sP& C>5`dɠ姂{ݵ30mEF]eR&Jx]h=ezoyʶJ@`˥PchDl=j^ ƛMx@ z] aK˷4QA^yeCrxFYh ӾcoE{E fXLsfU[2FwuU?# r`IP:1r]yDOQcj\E,*A]kDhg"#!nJmM46TJ5HGUhDU Q0%2/B[JshπgAިQf E򣿦aF+m9ݙ|>ISpv-R?ERaVd\#^(%zt__#C]"T~U։S(6W6lGkVcY4ߺEd*fkBpڔFd17*A_bv0?Tj&a=`P-Ehu E VNsJv 0iDp4J ) \d'm.2VdSq6'*әv.lj%h $idNM Dqn,#b3oDTvL tWn0 r#=0cW jI\W9KA ә9L7l{,@O,)+Dkhl{Dhؙ(!6TzjoRf_cyT EVXCPĿr9Ll*ֿ9)phvyC;NVZdMqd`/0N;,h6gndW6Ś 5c '<3pX;Bʵ!~?Ze` 8 ˩`w^g/,O:EOMV Ն^$5զh $,j1aO'Z{!mTPk܉ *a.XuޮpFB )q-NÀ>:VT$k;#_6[T(B1Q},I140@YfFUpgV?6OkÛfdDG)f4S,2#^{@SP:>C$BkEa{5$~33L <R:3\g5oMĂr|3i (8)Z-vi81e1k$S,qR6$Hy_杣iAbaYĞDrL.w{0CB(+ j{QtI5e,fІb?2KVhBBy 4v1w9{m5 6% wm-i 'Pe(A]R8{h/lF.p/  8vfdꮮC :M(+Tzqe {F["Z6\FS |l8w,ڢy%ckF[h3@tYht J#1@K2^Rp NْFHڦJ9B3_=c 7rf⎲6:e]=7{X ~hu@gMAXzme%̈VF}#'S)"I}_5Jq3hX[k$RS@/1Ó@P 80%0|or5OGU0E LF`(h&4yw.͟sx)o!m9:-[p3@w]]5}F \ |m8V;n;v)܉zF[Q"PWR[#(q ;C-|C/Y^%[ي7]üv(h2q`RQœʦ; ^3mV0mGvlA.oF=O cg9g{^QO`pxS\iIꯪdϺdɵ;doVrCJh'kOq;B?ȾP 5ƱLU){Q-Sn5 dt$LNC1K,i6u@n kjHvêHU׀"WCZ i5Ր~}Cf5 ^5f ZyC d]lBS^CFF4ckVl*}\&O' 8jO40SEN: @BU UAU Yr|){Or|1*b|Mχ Nf{`}}n(y> A =X$J糙.(в?fL6B;MIaN;1HYaЁ/b~1Ճ1rUVu('9Pp@u<^o>+|V糤}LZQRNSLq.1( `F86; MĎ2xPCKNWYfB  4U#RIDM"_ck ]:FwI@%边ٝ2w,Ū7&y6/afHb˻BFR#SZ;j(8E?0֋7t &vt@(b$geFTwE/Ek ۴P K>r$AtOG5UfYrdcM3 aaĥ0!Ԟ $ E)blh[^j{P<)h խ0NRWF^|--9@+ [# fz؈-g,K7ﲯ{ϿPKSFgDd6Hply/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFwply/yacc/__init__.pySN@+f4 āCBpmcʮQm6=})(xP(@j ZJ^9| `+C`9Vl Gͷ$59}&3C ϊ\we6RBa>umU{Rpz>PKSF20ply/ctokens/__init__.pyuێ0lHJmMUcXz"UDUܴl1jyN\<\y_P|IXWxΡ)qZ>R$z3K 6 G&"%Bvk;n OU1YU7vo KD7j{2] c4Ѝ".ܹUi !TrdߦKsz7ܹZhYU! (6/_euYLЁ^^VKaĶLVBC({`9Aw{+c3XWoBp ]Al6f]f;3(c1:M/oL&=!K}qL_у)ƉLzbfZ Eb` lHD~*1\C}:4"&=k~Ƶ)7PKSFOH{ply/lex/__init__.py}1o! w~[K;UʘiZ5-ę E_J>vLQQFF@,z`ɊBE>Ksivpjbpɂ Un v. $yYعin,FPXRdQJH:o&뒚ۇM<5<~$ 9-mS>L]ݻz(ן]@+ki H}>;Lk/PKSF5 @ply/cpp/__init__.pymmO0+F$\2fL, hsbT[FX4眴6h'w(Eq*8H$ ΤY(ciޕp[Kgz</Q4*!@ ީih !~27)oue`y.l{쬏+a^Μ1^Bqڎŷ,kŮɒXqҧweqz? ?7w=B~AF~B.:bPN!o]7UT-LlUPbx/hcl70_!f$sd!pc?&i Zt7|2iಜ^7>DOȟ{^6@޶+1>Lc~h9{" Ԫ NDUKRPb|OJ&LHoF4/J?FJ/A{5ӼGlZ|,+ThBJnJ =*\&ƅmBB+l"r$9='|k8V݊62mw! r.މk +m+N ]8M%|yğ'Y51_H- M{@(FPm$|CQF}>Bi遯,_:w)C=9Hl3!=RTD+@uR1>Є/%=IO<][5#UTSb1'^KeF[QE6t:;Ut~eMa]3|d4%ĩ 'мL1|@q~"a,^UFAC$A <)gMWTp ]ܧ-oi|ME%}Aw݇}eQh~N>0DʽqYAC 6f+mtz𙤨DlHzBu\PKSF[#-taurus/core/__init__.pyZmS6_^{{-P;KI(9Q(l#l+68qǽk=+?+rJD'S J;BA!\4,&pJ[M/< "$E77 !Bi'hKUf*M{<)'k]J= dh{04}Q-yb̞ b(Qe/<Ki֛2&|,9H 2XB~h.%,vbiky3\kn#G\R*b 9(s`Yڀl8k"MN~=#*Ia`UepE0Epn]/`mz~"9bh.sh@<dE妭'B_`M*`*gm>NcG3ӹ^nqCEC'ŞfꚛyC݅ZaO5u-gM1NqJfW}m|҃Ónh|!ZAp(C2(w8ZzҧqDp貱N/ dmB'=!Fw@ȓ&!-B\BVyF/l^<}4tC Of%Q3*s5=7hv\ +5O~e;N[ Iq#s) {7ɷeBTmwG2[-$9xJ wern !֞ᦥo~^G8|T֨&#, VT*X',^G7↽&-3N\@[zjm"{1łݕtV=eܱjKW厅  i>LkZmqL|ڰܓ,R5secI|(l>nIA8(a 4Óz!\na~Ӥ1r{|#Y|Ua Ͱ-_ܖ{XI_b)*1ԇ}H17U9Nxtwgzv;`wI!PJkjFڗٛ#nOtMi[mΎV?g>Cg"D)URd7xKHDs'Uf=Um=Msȷ\% PKSF:.+taurus/core/taurusconfiguration/__init__.py͓Mk0$BB)P-,$e=u@N2f܇^TkpM>3{Q5VAjͅ|l(B3OՍ܀IpQ s{6 ="Ft^YQ$ {*U=8D>OD\TG2h㙌5}3%%"+>6ƿPKSF`V %taurus/core/taurusmanager/__init__.pyVMo@WHI*RU**H!zZ YukҤ6*/x޼792"P rHiVv6kV䯖 fl$񙁅B=s{be B FKTw$ON5>NҴbnP`8# ȉj)d%^zg}ZJ58^obOϊk_[٤g#:|h׭]AFM6v|]tEHhIe -0V{3W e un]#͍.Bs߻<}굪fr1;GԹVYo@F䝡]v'Bp#S@Сƽ9@u/CCI;HѾ2$Ԓ(ІU£X* 3"i?E#Ez&)r|fYWjqPt{/vKeZ˓./t?JUi~#C04wpv]e,hͧ_oķXZ {}YsfJQ[w9]_PKSF=ơ4$taurus/core/taurushelper/__init__.py}SMO1 W=T Rġ[(̦dPneg;=O8bz~5lDQLMpGK~!aY:V+|BphzhisᄾCo,l^'Ǐ9G$9Ȳ5ڕXm*F:C)U=7a/Ӫ* 4j ~t%tF\}(uL#O̹Vt}!5y^us\/\۷^~">UR!W1cQo+VUEKnGh15qz-_/#,\;[u(ZwpiܧZS^(T\]/1'J?PKSF[:a*taurus/core/tauruspollingtimer/__init__.pyPMK1ȥt X O ø]IfLNVCs|)k,ZH,fdE؉XSWknG:)-$uRO ͦ2fT@À_5fN\<[;ȃzѹ~cQ{rQ'#^!`sZ'}X0$ROth~W5i۟uߺڃ}Ğf-CE8X`_&<)r92F|Ʈ\s dPKSF$'taurus/core/taurusbasetypes/__init__.pyn0E _ETxDUBYZS3 SѯMhEBsdjo5=vx4s ۽]ΰ}FPt# ,?mx=6gP37A_CƘҏKL{oԚZaL+{1[/ڔ|^:v>JX-9f/YcmPKSF@_ taurus/core/epics/__init__.py]O0+"1f0jPJH!c|XIjđt߱CJv.6UrӜHH#˿HqtRvN5B|F;&nK\.C{t."@k 5XY.A_A"wT)zR\XIw~R@]|٦ d W{Vs'޵ b~>ޞ| cu:rR}܉U/(z>THK nym*#s+=^(H @-T($e3vQZ`vsUz0\- JSHB UR* $lPX*b#"_3?5c!A͖Z'jnc˛y= O9o׿6} -۲!bV~aޗј{I@)w N_RU3B.tP}K5PKSF%,=*taurus/core/epics/epicsfactory/__init__.pyX]o0}﯈ScLB[խ4iC큁:75ǎlϽIӥ_+4/oε֤cqs 2͌Afjэ`FVv]]+o)9{1> ::GNXD=;jQ3I󳐠JPHis.c3rC ͹@^%0>rLNhL@XBԜ2c ?JmbYPD WyAإkuI-)A 8e߱BE*)+Wܦ""I$H0t8umTԺQfr+7;sQ=77QR;$=Lʏdo,WڲږG Oχv>z\՟724 JʥQ ^I^# X0~}_~Qq{Eʹť5B{[ho .w]̶]K졿JںJmNaʠ3{[,le9 PKSF=|'taurus/core/taurusoperation/__init__.pyPN0 +r M IH\*-M\9ߏSTa=yyS0vY2ƇX>щXuSW 57أj>ńfW3*{`?Gl&Љ~PGL z֫Z>6U=8CRÊJ=iU]դna&}d;=  8Xi2XY3Ή9JhhNs|K:PKSFRg;"taurus/core/simulation/__init__.pyVMk0WR MhJ (d@Pe,xz͡$yz3~їBʼ”GG:Eƻ$oXW;$I)sPALrXCQ2:o$I1фZ蕶}cL󦀫v4DYA\NhzQ1 4*2 box~uf |f:(C -QCv jb:;ϳ8npƣկ=ILu }WAŷ?@g\8/׋ޓ4ΐc;G>m=EMzgȞ rS-b9SƬtS?:%,TKpE\zFg隁jɅ>jGO\A|ցL[IֵUBPhxZ!DŽƒduZJ`]"a?64L1nO&< {ߎ@2oI=酷(ɍܠ|ŗ|;n2jfЛuRst;o-pju[ ןeGhv|~؝/h ^7~.$B(&b(tJ?RQ$48ǖZDe_fC啀;rWf\Ai]A&s𔚝%$ŕcgs֙bp$Ea^fySjfT}h]O}}2m{Dxk4ʄ/CJیnh(/b,ev<}Yl.Uۍd?"v=,[\!JLf=5&}&c,zH3^.kyD"5g":HQK:Y-X9h|h@8>=SلoBM_`+Iu5Or+^ҙ߁~udĤM6Vqd Vkjࡽ.?dZ_-1rv| 8mr'/$nL&go: \ɠ2#e(dw? |IPKSF.8\ "taurus/core/evaluation/__init__.pyVmO0_$`+UT:&8cG~I_Ra^ȗ=|v+8ę%aI*qRńATIQ V"û9\V9B#iNi%s d*ӍP*ڰ Rr.g4n0kr.(dzE|8)Rua!pL;48/&q, 5iO ]Lq' ƪ̎ X()|zW)PІYu.b9a րϠ6krLx5_%!L0C#*f E\]I &)C+Pޮ!`^Moxsi>τ$hN@{)Sȝ1T8D~Rd(ߢcb 33D f_i΋l P6CIq*ȜtaJ2rG ںF雺:4gSm_|^ڟiڧ]ҡ1dXΩ[euV8h%Jry5hPKSFKgV2 .taurus/core/evaluation/dev_example/__init__.pyPAj0؇BP951^Ql+*Kf6]9}Cuj4*M=ʶ] VYmPM , KߨȲ ujc/Y FuBp5F˔D,~|P)4'0雙:c`%EZr$+XܕۨVKH<% Q摎;ڛU~$ $~UN ,=Op)ÁeeDB/OƚeTJVm?Gw\콹ɵI3%M%ηrM'Jƫ>/e| LFu^A5TqUzF/-kd5%)LڬeTdqu.wi(YSWT&#efJJd"Asjt_$p_=| aQ<9.-qJņ`rZ ~e(W[CSgP(F;`O:I}?9QLPFAdqO3%Z:_{P fJ`KAÞF̔$ o% Fp^%.l!b5#t%˩ kRYZd+CXaNpBaӀk!Cȗ#bU~uN&2y 7p=bgs6odzY @'o&kzd"\8b^كj:_oCZFmaU'fM"1[J\a7ݫC~/ŷy:f;2Cu޷i[LJƹÜQ^67PKSF+#Z:/taurus/core/evaluation/ipap_example/__init__.pyQj@|+$MR yM6c=읒} iB vffƜT %•Uȸ 0[FJ_M1Y&Dz^#D5_ŖEDƍvPqvXhxw性%pl2_G-=T/w7_`7c<@l4&< xM >K*{u锨M(S? Әcg,*ȊxH䩿Iҁ9uo&1g~2)W?!I"I"5М2R԰̺^Ol߁&m[վrS w oXN  'f}C&x,10yU*aK kK ܺ.ܴBS!bj 2%kOU$VJ%ఇsz1n.H\%}CMᣗ!ݫt7蟞/ߏ-DɅnD%(xrDKo-Mz'PKSFE&taurus/core/tauruslistener/__init__.pyPMK0Wl{\]A<.]OaNkɔDN*eK}dx=S0Y2ƇX>щX+{[ Z!%0 ׳*c&eg/hͥ|Ƀ zw-cѯSDWF8=AbMfU]ۂ!i`Ee)|jZu߶|u9z=-:E8X_i2XI3.t9é$W PKSFCn,#taurus/core/taurusmodel/__init__.pyQj0 +|)MukavY az j$dc?;!koOzOsԪUԙ2jn(rK-$KM =s@Wx!քb+ld˨R8!%M 8:Aj(1gzgEmE<u@uȵ5{BS],]sڎpS?AHиsFTEmKXۓV1jFn~;wo1#VPؾqR_ Ej2MOwm- 57PKSFP,taurus/core/tango/tangoattribute/__init__.pyMK0ۃ"xB0۝`DXI]lOw&wȴBʱ#R3Ģ#٫detRŪ֔r$#]p7AŹsfhg=1h7ZLWVOG&`0jQ~ZwψLWU?̷ ĮHx^Tcj1,V/p?ÌHt/Ds<:#E/#@ PKSFOFaF!taurus/core/tango/img/__init__.pyj@yHhF-b,:IڧlD+27ÏDgejΙ2;P@A9Mq$2Q6Z0|M'IP8 `=-0gH-gE1^"k* alG: TAIi1lxSI0wgiދ TJ;YxGga =d:FxD7PdVO}qT]3[ +bVx],iWq}y/:*pb2Z:9Z[4CKŒЇo/4O(6% >[0G0?PKSF Rc %taurus/core/tango/img/img/__init__.pyn0 y+B~ o PKSFO*taurus/core/tango/tangofactory/__init__.pyVn0 +t) k v((tGiG,5?Ɏ7HIO̚qy9g(%VZ)Z4:*VasC`$q̀W[b̤vB\#-4 g@Qa-=8:=pdb/n5Xq^*̊: BƆ|q)v_:3D0[:.erZ["!L!uKV5 OKRL~}4uBy͝\a0jpX8.A37\Bfa2lIcYTG,DiGSW\^UtPSX i8ҕ ܇jH5"aA-3t~~G Ë‘E_#)ش-I5i(t{ǡѿݿq%E/ˮ,Sd`^уQ*6 ,;?3+#\VR|y P|Y۰R(]0 (1##m`:-%_ T*3\^NmD"L~ց.x$G-I>ҽG?N/p7\o_oGPKSF $taurus/core/tango/search/__init__.pym! <75&;w]׉€]}PKSF9u/o+taurus/core/tango/tangodatabase/__init__.pyRj1W"BmJq+\uv &2]Z)Mr2"RroŞaϚ5QިJrA 2tOG.D!S6BE[_4Ye tNlmκ6N lEjt.Q͓c$עƋEBLI@[T估k ojB3K%pՋyGW(qp39ыuxg!`p>j½ݣVݟlhFͼ/_sۓ } d CIB_2q메*ݯt~*Ԭ:DL[K+k'ӱF4+Z(%y'*>PKSF!p5ztaurus/core/util/__init__.pyXMH+|iw&R)Lƻ|e0AIz2fLf~V\ ¯^=گnB%#T KhJ?PdY[*-Y3|?w[|#4?3BJѺtr1-ZF*O>j e3r&qD/΢O(vGnIPKSF&1'taurus/core/util/sourcecode/__init__.pyuA 0E9Ez" E|B:fSmH'H Ϲb+,6U\zYY#4f>bw^~3sG4$7؆/=$d,nG摚e\PKSFETnp,}'3l<aIWD6۬VPR/ElDqL'ByGrxɝ_Ҽ/!)0\4^/.PKSF(8.?'taurus/core/util/containers/__init__.pyN0D _@P("*Grı]g̼g+t#\8gz#m$ʨmLN?"\';v{6[r ι|2By͵":,$`tݧMD=/~TnQs#B`;D1%7si"D2~?? :P m ڜb术>V?+.vXoҿ^$X"]eH`~PKSF"Y(taurus/core/util/enumeration/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\WZZңViťPDQZ] PKSF;ad)taurus/core/util/propertyfile/__init__.pyUA 0 yE' Hi!hă*mv&d$Jsu[Hw%o@S&]Kvsi-f8ԨѺ fZqPKSFx[ taurus/core/util/log/__init__.pySMo0 WR$9l^( 6I EPY2(iG#ZӉG.,㵭,e eUZE*uȝL"I(șJ;^2 jY* C*fу>dXd9|"$CbGyܣU^f}sqI̹(y%$o $KNjM"Ŷ7sVȄ^G$dķ@Ceޏ(+F}]7 ELݸ /]E iD95>=܉pKyZ1ƒEZҒO_l,]j+E m*۫&fDpf7}oztyIi 9 ?~Qk %,` " (51LdX/%,k/BS)u/ /gO7eAPKSFL'taurus/core/util/threadpool/__init__.pyRJ1WR{ OjЊB54Y&Rz'YjW]s^e򒊰QZWwZ+۴HZ%[Yv5XZ@W yV׽Y{&Slo THal!@rCmC,;^rb) !Jݐe['sF$o#L tƣMd(w'*b8|DTMoU!40|k+<̰Tc3q(9K i6!:8Wҽ5ξ%߅q>> q's<PKSF"N-taurus/core/util/remotelogmonitor/__init__.pymP;O1 +2 V {]q8NOѨdp=I9ZJe>Ŏ(:9~q +>j%}0MܥRt'f k8&e"3 eEP(Rj.,ž #m|"w2e8=?\ۭEJGͻL ܩbN ;&t3ɕgTVw>pHKD;gL.7 ÐY?(j $okλ'1?PKSFW'Nd#taurus/core/util/object/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\0X\\ҴRP(ePKSF2J_y'taurus/core/util/excepthook/__init__.py5A EbzM C8#훊b KoRjKE-^*W/c3LB׻TZPKSFbG#taurus/core/util/codecs/__init__.pyN0yp@mHBmEeIp!0%D/,(IP:0|ru T9rpYldo$u\w(|(5ۤeՃŠP:P8̀G?޵^O]\LgRdl'G'z"|/)0yPKSF1;_!taurus/core/util/wrap/__init__.pymA нpYaDGFFP2y `K.l$Hed i);Z{ C@enZV!0 S 盫Q<~\PKSFgDd6H&taurus/core/util/decorator/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF(ɗ)X1taurus/core/util/decorator/deprecated/__init__.pyUK #x1ҒZM%lR*b.,j iLUfmNEw]=ƌ+q~儐PKSF.M Zy.taurus/core/util/decorator/memoize/__init__.py5A BGO AHR.^(Lv (TIE-^WE?c3"`u|. @|PKSFYW0taurus/core/util/decorator/typecheck/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZPR` KGMCQR\PKSFhpnV0taurus/core/util/decorator/decorator/__init__.pyMA 0 }E6)iۊvMSf85b,ޭJHJGW|/Yj5xPKSFƶVm%taurus/core/util/constant/__init__.py5ʱ 0 н_QU܃6 i:Bo+ n]"*WVBr|&K$0og?PKSFG$taurus/core/util/console/__init__.pyT]O0}ϯ Ƥ"$Њ&"7u!o9X=uob&-s XkSk,RiJAH֨mH5/I<>E](tf;8L!0܈4[B">XR $|#ҬS×қ`ݓ.̽xEpAa1&GYy?>ut4y4?Bs#p=%"3ETǩ: j<K7fDFӲֱ]݆jIs}[pޫ0yPKSFN!taurus/core/util/user/__init__.pyM1 0 E›Ct)ąQ Z6BiN_;PmdcP!Ģ2JiG+e`k@E0ڂl\DutJG֌z7`VRzQ[j+svƲPKSFp|#taurus/core/util/report/__init__.py510 E[Z H`AlY!8&ܟ/ַ+R/kb}:V|5jI\RLMբ/-pɓMLSNmMg|}Tl09õ9)gKC&>{VyP )A`Z/PKSF)Bs*taurus/core/util/report/report/__init__.py5;1 >pp$: A78u3s1X7aDU$>{Ņr:'RJ/]<a!GhgX.RŹ/PKSFҡGZ!taurus/core/util/prop/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ PP_ZTR`  sPKSFgDd6H!taurus/core/util/test/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFrhSV-taurus/core/util/test/test_codecs/__init__.pyeP]K0}h :@{,/| iRnndt9|J=95VHY R vIt-1kK&uj]9AXqY2KI ~ Gʌ[z#bўVo/'IRcbpƄ?kC{mAkWAY^͗k|Q. |5m]/ځa(U d(3qCsg⽧o9*)?":Y|Ptna(U6nŊq##ip~>͆[mշ" TS+l˼H"Inh 24\AVv*BOoA_U2zv?Pl7 nL`N0QhQ!@jL(bPJj3VE^mdž7D,rv\.V78@:<PKSF&{taurus/core/util/tb/__init__.pyu 0Ev8" ݾI$Pn' M[/h4^FĦLcѾX?^^H 7r,e5 ~q?:ϑ PKSF#t},taurus/core/util/property_parser/__init__.pyao0WXBS 4Mڇeh")E]5ǎΗ{leh;_m8/[j8gn,kPHR$e|‹$<~NIb]_5-Q'^* Cˑ ̅s2\܋̵-@\YA]֞sPɿpg?e߆`v[|CXίgI7?0= )iEqQZNȾ^䋎GeG=Dd1\H6zOjU6ΏȹK%i%5K1*.cSTо;/ᮭDQa ?zFMTpea~"afrH<i_«p؝SݕW68W] zڔv :2Ҷ/Zhŏe-l'rn&PKSFF1Pg&taurus/core/util/singleton/__init__.py5 {pRe !?eԌԺAWb󗓑p(jRcClDz ~PKSF]mWB#taurus/core/util/colors/__init__.pymA 0E9EzBQC,X;t5HE$ĸJ!-n`ZGnvQc;w7 ':؆fu|,]x.HSﲁG}lr|Hيٖc>jmtnG%M[6_t m55/u+CpÇ2yo ,G @}(/`ЂopPKSFn#'_z%taurus/core/util/safeeval/__init__.py5A EbzeV`Qԑq }Zw2 .="\*"' oɝ8j\oX?D.oM ~Y@rDPKSF%Y(taurus/core/util/init_bkcomp/__init__.pyXo0_V!!=dm ֔ RLݲ%ْ-wNd[cb+ Z&E{T!o7txvfB=C a=Oδ9ܫX lrJbr#EIfp!4N R3Qa22pxqxO,R^epa+f ^w " 0 *5ztRCay + jN\孒[PgYtYYm}I`|NV y)\$=̣w@_O9:W6A h n (va ĮZ&X+?DSfǟ ei̾|hC/f*S,]gvt c jbW4s<9|G} xdq侽ZƯbj{=ޗ 7x_>.>d}~΄uKx9^%!L0s( 7H+2;Q77X1rjbcx"@VLXW.{B4ŭuRe21\`^n1"gk߉߀qIpe:. ߓ;i6oN維[rkh4L7M[[j<6'dQVl:4+mRngݡu6ܶݬfP౏}KEƛi[λR#4, .MGY%}W}}X!R[]_N-{Ct L|8-V6dۈgQή=c5۟&e8vOە d|PKSFJкw!taurus/core/util/lock/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ XZTZkhrq䧧g# d& Ƈ9"%$+# KiZq)(PKSFROY5Li,taurus/core/util/whichexecutable/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ _` jhrqgd&ge" PKSF)taurus/core/util/eventfilters/__init__.pyuj0Eņ~A! ?*@)e\DmIR_[&%r=so@D 8OSOT^ ]~_HY-FqqfM},e-ΜT%H=͵% UkL4oT':*c&SGƇ/tcjOT+%GݏK;mC#rָ^M/4JG+93<ן\/PKSF!p5ztaurus/core/utils/__init__.pyXMH+|iw&R)Lƻ|e0AIz2fLf~V\ ¯^=گnB%#T KhJ?PdY[*-Y3|?w[|#4?3BJѺtr1-ZF*O>j e3r&qD/΢O(vGnIPKSF3'taurus/core/taurusvalidator/__init__.pyWߓ0~_QGꍾ89::b')dl0p@rm%8T%H(P~)(Sz%re֪׹A|_= tS2vrJ0k=m6ȁZ0XSi'"V?c3{YFGmFX:(J#z;bvXXVWա#5 {쳾}xj5Vx9x11Z>Hk_vm'쉔J}qf:dKȒDWo[ iJa);C5NuK#ǘ_pԶ3w+S?ܸ(ʹ#e#B PKSF*~pq&taurus/core/taurusdatabase/__init__.pyQN@)bHj PaNk|{w AT̷3RHY\J)TYYbQ2Y&*ZWi 'Dˠ 4h8{Pono'6?JY#վh+$`Kšاa&8@i:zFOӉEDFRsmһm=X13Law]B$X} SK-(xlcl0_g%- g]^ J8iۀyvw*7zU^QCz+q!#Ån|=2ʄWAv)~^2qᩌj<շXI$Wԅj(,є bUD*{oqe7CΙlqĬIBFCWJR!(/W$ ^k&쬂!յ" ?A]4p82J#r5+ 'mfY5x-j{ZaA 3pa#loэ<~׍WuZ+/Ey(B[xux}[/l1TPKSFW0"9'#taurus/core/init_bkcomp/__init__.pyZmS6_8(cC ᥽!z e:jYI4'[YN{w8$$+ΗDGg]INСJX'62 :u2T@Q}JD8#s-KM,smIJJLƙ[Zm\$ AKOjT,&dvL*X 5*w2>d b\nyoBQ, Cu0oc߄VFl*ٟ<S7s08{õW Xn'0n[,?0Ā/Z؈UYBw^h@_B!rF9! !%#'d%B~"dI]@(bܩԈDlba/InQQS+,JWY1(AsQ\VPԃ='k3 Q-tb7=PA[ze#&!?KkK_W>(Q 0z9*II*X',:B\<nGGMWޖh< ԞbfX8n1/,Q'UOmʰ_:_m~zjp'6YG/ HcTϯ`<-=DӔ5'VC̾[L6T{Hj|nD] = NJ|]fF)}:9,l4v3\ڻv5:eעC$+w+`&Uy)en%w&NW1/ޣ}# B. ZqkHF;RKըFkKe$m6aZ&;p8v}<@Z.">Oo)k' dN .;Rax2F e*;]"-~-vָ30!Έ/h ӯ"ET.)S̄L!` 8MȨn7#HdQNFM>XF_^ݾ3s_?i0<(;,eeDMؼUaK.Vh8&aZ)i(,Oi9Nh6[ۭ&=i4N8s.NOr5rf\ўx~=MS*B grxr $r}'*jnR3Hѯ;@0[21z&8 =S'ZcPKSFn8QTe'taurus/core/taurusexception/__init__.pym1 0>R`/1$Ɇ.x|n7)bPQS!(5;MU"?VwZa$_n4*kN7PKSFkj taurus/core/resource/__init__.pyVMk1K MHJ 'PКPkQfwuJh}͗Fl΅([ju8AmQH;U;3Ą,CTpL)p@(p$ע{&F{:>?FY%ə4!wn4VV,O L\!:Q^,tllq*}E E,d2U0,F5i%C'laVlE$>2y{M{a-{C#Z0?:Єs6-=?UI/cv%7`G[ e:7Ve\%L?^t`h-pZc~UU۟[=(ekjW8JmY=%r7"?h74L9d1tJn/@WsgK]SLݕ^@?_6넜yVq\K `@5@lC$ Se%~6 0$m;m/b}B݄Q87F.E˷*:(ЊU[!z@X簍kݧ)p„0a$m!$aPkGwMpVyoZ˃\*h{7i[|~PKSFgcn_} +taurus/core/resource/resfactory/__init__.pyVk0~_䡣Z=Aӕ-l"1Y2S;qMCat/}t?JuT9*yCƱN.+[VϞbd;p4βKi5BچX/pv~i Eb "pDdzU5%I Mߺ[|Z,,Bȯ|%YZ||y#ɰѐ2=={Xq%˺wwC/=2uf B(IߌlZZC!bq 3՝q8Dmu')ԥ4`gW>N23.e>MY_);̗gea,Q^iC813b4u۟-xk%$6ϣx JgnwηFW}M/٠o"{?LFO3h94Un.x e,es^<(WsԦ4X3M<"{R˴0}-]eBd:J>@z zR ZjU`]aS.¯M'"=A#0JcCMw(G;[ޗ&4.tq@)i$ (κQRaF0T2>*Fqr2A)-u9iF7;=ǞNXՃ6+69=o#,quk"0vfBz^~-A-/t9"uaC+7PKSF*k%taurus/external/pint/pint/__init__.pyAK0mEA]vG֦]XEݷ]g;K/ˬ.@[diEfTHJPjeUd(Jti8))p[ Ur՟\ ,HV:$_)[Bwt=W(q[,Z))பJe_C&$"oO+XW˗` >*l,Rh)eږivX<&ڵ M pDtp=S7jB;-8x%CXGN?e65L2/t"xa%DQDPKSFkR-taurus/external/pint/pint/context/__init__.pyQAn J=K`C-nٮr)Nh\* 2~IdQ;7dϿ:C#yvQtYIC^K%kɗM>Kfm[eɽ.ż nfO1m#>Z8 d rxsHQqѭsR r/&נwmy"(5_PKSFv<~1taurus/external/pint/pint/measurement/__init__.pyU 0EL1YRG u 6Ɲ4M%/8T Æ&"D r55KL_6_3%Kt-+/ޟDgm6r=QfZ9[ ݟ/r͕GPKSF:ifH).taurus/external/pint/pint/quantity/__init__.py}R=s0 +[u I'خ-sW B&'=9mh3HtGV!ǂ:ƻTן6RT/%?կUBפ]l53&"^PI.yt1%#kXrm+#YLILGEucq>RA$uﲳW p0f8P< 6IT[Pk5[Yizך>-UZz(WnsFDz@`9NǙ参y gk0F0{ctPKSFinFK*taurus/external/pint/pint/util/__init__.pyQk@ )+ %5yHArrНCm}һfE'%d5dBGY #eFeMUO0$LOpw?˿( 2a[o$5jkƸVyXk}': B@EmW}EU,g!X2:$lb5Zdt )Ӎ65:45'#+tM;3JA+^>e]́Ocvӫɐ,qQ8=,_>.'A(˪#'R o$u}"s:+O * .ôz$Lޛ>3Ai17 CxwaPKSF-I_*taurus/external/pint/pint/unit/__init__.pyS;o@ +4&c[C#~ ߫0R iQ-'}Gou Ф<tLd)ܟ0gv^f}QIO]bJ2 ~&a"!LҚ/Q #ZySzk:Ή!ˢkcN;VeU.ʶg%aV;ء[lsx6,~js5r'D&jytr`3 ɐ54\q2 ©we^n܉Պv776>^gz72*ұ8 :AS v "Bv?|5\R"9Ert%iV4 *4 nx_yo/ >AI$o;4վ`K ga/o[K?&Xo9 P+l@ ށ+p PKSFQ}C$taurus/external/unittest/__init__.pyT[k0~d,a!Ї%`F)FlݪKIr9qRv^lђ<': y(WR[4R)Y\/" F2g!! 6%I ;foد l9B2 .PmaQa,f3%2G 5 >#ip,q mjM' S\Pz9fVRBnk ,Wo<%Cxw2_~_d{zl n4u 1/Ddn !t2V!X}tgW 'D[T.Wh0TZVaGIܣP1L&+`h<)XV_lZ0Z_r6RQЂ 1{ _%Ǝ`X`[k xVkGYs_^>i'E7f$qLOhAO jzB'$8$FE9yFtvn&ESCHPKSFgDd6H taurus/external/test/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFˠ(taurus/external/test/test_qt/__init__.pymMk1+rs""x*VJ%3;Yݲ=yg$M^id Vw1 ,iMOX&Lj#ku5U֜%|Rg mh)r;rH< c -^@}׿|fG0nvH(WCXꤑCr:<`kaNitjȴ8½B~PKSFb_$taurus/external/argparse/__init__.pyAK0BP,`֋TM&)7i]vs{{fHP9J8:ԅN_Rv Wo9q5S\K~hϼ.~Za2"˲$s]lEͳ5M"y~Qy&wuEJ~]| L^c'Ѣ!n 1DvUߺ0B ]o:?J.}MqϰPKSF퍲_3taurus/external/argparse/argparse_local/__init__.pyAo0v%q%TI#m^,L"ƶv_ڪp{o>1c U1vr!05Vh#ޕm\:UOXEI `h*} Mhw 3XƻLvXSf qX5a»}CyFXN>Ko.A?y]$44coPOwٺz|) J28Iė^ Ϳx{(YlJ,ےU1'ju?82gxv4aagZpc]JQٵ N kA–[ 8 IhѸM# @6b4oPScfe%9XY)iy#@AaNcޢr6e-6gYVɩaB%pJ&";f@:pÅXܡfPKSF0S7otaurus/external/qt/__init__.pyeA0 yEPXuEzZ*$"6MK$7&Rb3Xm ZCTE7a ^IH}p?i8o`O5o* "IRս[?*jW;[a,X]7dL#3&,x0e"#6r]ilƢ^=d H5wr!i$ɻjɶ#cESf:eLf2] q&"!0-t7[&L+ ~5 ߳ t A ϙZ]&KMfkвԐͩ,j7g:%r.(*d{kYd leX:ć/++dl>:BO~پ3PBE{N"Ԯ2s \fXlL4|Ss:mHJ<'l+#cƢkc$;6*%kT+E,ö317Q'%Y@*;uke6dEĤ"g1p6Avf, z໖j[tb3}=1Uz\[9[O(jQ`EdD [YPdYjbD鄞 MX:KlΝNd܁`zm$ܐHJ&S5ܬı}ttRr\r >я|EUOZyH#&megl7(M'VSWbN_iNP5B@/pNqC9nYr@#m2>qxQ9xE6yr=3ܘ) 6lʲhy*  8bЕ}{  3^gK.jl#Wvk\ jHxf+>Rm*?RRS|N5#0]x1)Bh{Ӆve=R];Y&өGGsL(}kQmkxpLX 6&Y[Z1"j 3j' IOc*O}E89c94v崫A%KJb9 X_72yo)NBMw\Vk{)C$Q4&xdG}S`YI:e^y{N ocgU(KRaSR9씔D t%;;zȔ;O` .6v&,..bleD2?DNdk6ȇ6eYjyxd [%:" #@B'˿>I /,ftIn[:pL)1 OB5_,bz>5W?&pXCFUk|HRz/P D*b|G"!SX@G\-9oSu;˜Y0Ħoʮ=ލQK9вm= Egj[GeLqۣ'ww=HY+8n.D Q:󝮡@ۥ}nD%pBV?9A Rd**~PpvMpؒ->lyUM qCpVj?rMl{4!w ^|M}Q$*J&&7|_ckXBr dc(m::ǯЌXl `?xWQ:TL-G˘'<ǕqH|iĤrPDmL7hfrG~HX(˹Z OF$=Fɥ(36x! 3Z70PKSFV'< E'taurus/external/qt/Qwt5/Qwt/__init__.py[Ks8W63)qj+v%;gHš hKh)%{GTbbul\y?U.}%Jƕ@1sh50}Rg4vnE}/VDVJ$]YQnz|<ivs~+q'ӱ~ѯ_;?5ALI f$Pg?f7kw&SmyBf`mM^dzԉYH<š^;Cd:y躻tHmT-4wdʾh귂CSǖ,Z(MAka"LȲni87v˲Xi{$j$gL@3ԥ&GV-KZYj*ڍI+%E?luNb6^p@J~/E./ :{u- #;s }f46CPBEG1jײ wп+yTqU/ϥ-,I<_q! ѯcɒ%ytLܔW^om=ItVd5Y|2p׸s:rcZӅhrܨ瘌x9QZ,FԓG-1YNWY[Q<O.EB]\iQ5B(1 qCYrBcX cGn/KX(caX=7'u0bAw$߹ecYt5(kMUY-Ot1 GQٗxyWX;k,9$8Qy̠R¡t7[o+7<^9EDkis" UүfSim czyr `ኅ_h΅xrk;rJfaSJW e6҈|~5^hxn}i{hp#M ,9# :??(%,WE:]% լAEn}.[ Ŭ^[. ]t1{&=!'nsgGGs,(}u=,QVLVھIW,'vm DN $6)ҔtB#3>/t(t_oFWWj߲ 1ाjZH,iV'GK H\5v`R6p}#"RȿŜ-ǒc*Bj6d2mttr\3.f |D7GS~:YHE*zALbF5_)v_ K>26l%˔o9M7$PfN>pfy Z3S]$v́G=+)nWOw`,22_Y1_6[F գfvdeoT(A"]atZeJ`M)xFd(~ZK/nf%y9,=nuKRaS8d Y@LR=eޝ'B)%W;8VGHr<{Q .x 6u(>1( `yxd#]Z(m.mԢQD+.$S6hHn[`8G㜫=ƛϗf_4a.~ZiMr(;SX@u\G\/9oru3˜Yxщ=ލQcBl;e}5ѷ1 u48=]=F=}%Ӵ)[Չ-Q4&kԕ|k(wEk Zc<}g8)SIx62!&j¥T7A]d@!pe>Zts]gCZ )#% }BߠBL6M6BHJdze(z䵛Hihe|5\}jOC4AM3 PKSFra3(zl(taurus/external/qt/Qwt5/qplt/__init__.pyYs9(_ ns#ZkkQEQ"!Z*v-Zן\KgxnDaMP띻nJsw7EYl4?*_~-˭B>^ I7ͫO %&MCf'MCb kU(ʹi8[eИeeqe^dkPpftlyR{Hi]n΋jU81fQ3~PjB㧚N0MBCL^孽1ƊZz#`"K2a_k0n u~ϸ8sp `TQ¦;;}PaS> 6Y#0WӾY>q6rggy ,UQ|;yN}tyUr+R2>A;,x %sTRb}d6$V'ܤ)-NO_\€=YQVx tz̤-̻2%!@B*h<@\C0z@=vv|agERaVxmzhQ"/:?G:M,_E*Ӳ7 S'`apbch>t ȝÅ`A^79L *0bd* A;zR}(2l* }Lƫ u+aEڍͽhJ0d~CUl}x>͏o.mQ\2t' (@Z@|6cogu:ͅEަukzI08~_ %]7:YkĦpP!ntrd0:qGLہͼkg&I+bCl ILgdпeX6FA1Qkf:"XiZFiTVYLjD% 8ɉc雐Rἳj, z&QfW?W5kR.]HAϠ+\ؔOl|D :x0 h0EaRGXrN|W%NaiCdqGiihदd@dkS쪆YQs $cNT0=,(4LGh<?v$JYdw8L؍t0]Уtv,I)q2)GVcUTB0F`o-+@ @[b;nLw2? o2*~oЇҐ?0/Z6Nqkm&,`I`oz C½Աĩ;VH۟D~( *W$u?6OE 6 0' WѪXx@F̗r-=,T*n j.Fw𩂷WLSVEiӤbI-0UNރd E^m9'|'דakP$jɠO'>CA490sp@"Ҹ+wQHЋI`} SF&CgKkɬ^$`pYo~}`V neaFqw4%ُ8+L B 򦨓+K ̀G0=|1[h:[?%SKv|Q}4Z25w鍦~.!5,;}[mq at-mLدX5I+3] *ҽhg1qE& %{Z𰡊ۗ$ko<4)ŗ=/f,l{v4m{ x vəEn9r^<ڜVC'԰=,/:aYk{wCW/oCڤ@řrsƼ?΂mfi3 j1v&Y,ZTM( :8S-4g)I3ti=I'3VhUh*y4'PvOevn졑-|TpY'{tp?[GX =CIn[=`` 'j),\~ fەknMd7nKĬvV9~(v5pZC %дJ ^BqYhn}gZm2OqT̛5.PXj}iזVeK;{sS8Ҩ, زq&ߔ66΃"B~ 6{OUm>V밉ˎ8kʇd{<fC+v=|uKc)͑KNiag}Qv8 D.P@7fnwIctS}SXJ Ge"g3Ǎbhw(y}H&Ьx@砝)UTrx5~I}2HR?5J2)݇Co)A }0v\ƓB8)\3^8ÒzNE$.4tZ$D2+ 0uigy6 wݰFҘ*H+A݈}SdF#V@ {N䈜{@q&opFhYO9)BrV_8.'5,MBFDs8Q<2_d5%'{kg{RYnWiU\DHgjjQ)SRTϠGaerkWǿOACvɣ7aoFx9>9*11C)/Ґ@٧cA2_S܀A T7\SݦpW$ ʪiu_%]GRD!r`2] Q2s QJ*ƕ$ॠ6{iO<Wf= >1 !|ٖ`{dvK<;YED| Q2U _dẇ?*5<DT r(&wk@qoc?BA.D]t N:p5 Z ,rx!x%gH;vlo$;yH僤JnΒeIQ̰N: .|z ,j;^t;@mI-4Ĉ\]P&5-ї莈 |V- 9P[_j dv5AhM8eS&7ܜV^ {[{/X^k 8!~]۝sCav՘GC |yʲӢL;NaP904={d֧(v9[Tw( ޸ұaIyHJ>S3x khJ6{9}bm~]cPm}k`䠣L( B%LLYKw6^[ޟv;ʷ-t^8vsq#߅YQ'枽;svJF[Ea]w&`MbQZpdccR>Ջ?L Ù,r}|\ ~T[Y|Ǟ;9vĀ g_j;щՂ97'͟r_g/NR6iUܖEN.N)#)Ud$5rsN)pq9q5 "-+ޒh-ކ=|8s/q'3PYb_wLp VbO' $Vz_*wEIDB.r @*׆0L G/1,5rp {Ct#jz%OaFUVtƈ뒌ϕsP|-u/90#jljtJ_#?3쌕oq?q8q8(VT;Ńyb? F/Z*VA UhDC U*`[nVO•$K\ay\isI|} &z' P?:O.^{n&):4j^*c;z9$X3|Ɂ5W8HtzAl@Aro(!{A#t <)KaLv~Y\(?(ENKCu<5@@ Lyx@txʐE*k*q/B./0f]DWo Ac/X h #i0 簖2/>d7Ɗ1{{d.f!x$+6<}0Mb#}jɭIC?(U{9ER렪g˳|kxU9H_\h0{[Pȳpٗn^v`| vVӐI0ҡdP)ϡʮ>7l.Q EqG6$|yi 复im6@zIZBHkO3Z&K%v 4wCC?p`}Rp6.a%&/nGyޱY={WRc Z8jmnKwwI9޶Ǟ dʐp- pkkHB-dNrZL2 \K_="Kk,QNwbP*ɰ?0EކRi{Fa%:yCwg+ $/|O=Gc{'>(ݩ2. |70nR ߿RLx:tJjwVc#Fv;E;[ơB0wuí9{эi+y[K5Gw2A;Ѯ?ag9aUGrX4~36b4P2}4sUVtl.ϤGnƯZtx{1齕E|³k㜽8XgQ㞏Ѵ~TbpAs k"cݳᴅ) GcOmt#*u:9Pq|/7q@1 evՏwEPGgy*89R!dX`~|["{vex 0A~Gdas7{mY#S=&ûF6\q~Fbq$w8BY` -i[2Xm'xkYFH$7/-{OsqFq"knW1:CLG8eStP^?b b3EۃAe#s%vg@ۉh<-lq1~&KPݓ:̠r >'!3Hq>#^ P:ʸߕSƃV/;ծ ӉD:6C>K1wk12*_$hǕZBMfZx`} 5Udnܲ(SAPUNC6 /30$]?wLFC0Z$'M){`dbCO":tv0q SNQǥ61F;1 z3H ÁZhB"N sސ6#-\#:mߨ[?i!| -z-uNڵ87᭵P!mjfޢPvx+"~}d7ʄBb~ގ2Ln[j"@kSEy6Q-z pak^9u^Gm H\Iܥʭa}g~%j~Qr-HD߸?Զ͹`)U4׷R9XjG1vZ:ژ͆Ħ۸pT)m!6Uj!9oGȚn:8\TiO/:^/%~,ɍdiK[t2rgxCjr<ng›w%%Z|O4RnH`h p g7(=R Z pn#rep|'#\(3|޵uBwB?-ln*HY"1!0 q/6nZXr89k&a`jt?X^am,4ȺЃ[{ht,Aw-ЃƷW`!'y,{VxWSjP8;Q,Lh{}*nk q7)JŻy$;~z;c冗IM6B68_ikY$V\>.3uXOJ_<\Y;m!Vж3ze$枌ԉ,f2Z9.v[$(eb;*). 5g!8s$tqo Ad1#[TB0 z8x+:"w$}L ;=Cw ڙO浺LR9, /ro} 9 `y9N0jihteJ+<'kvkv+`Y#‘wۃ@'3 73Gb¤[KMd$T*(=sCY#P=l-jx52VH4KjVL(4._脎{a6o*rB ]V5\'@fW ̬a4[cr ʮyZ(C@`aeO>/b'w`Fp.Eff*ʓI%JXK ҩN=p1^,4 (JRHu'ٽwV}5Zlă>i!e;^SAz9O<-XtvRds[adBUa;yAklLRyѻnWVaV=]2|ӃѕzOu_] <qXd>s: KEC 3\ ̀~=Zn(u%W6]YwŃS t]&U\P8UU #=S>$01Cjܛ1w^7RӁ$@+[ە#a2C􂅻egG}Yn[v9Qo(Sa_B iw_^ifu-?mL`3.@c)o@Jֺp)پ)A=N3Irz:3q-9; NP(0j;3Q.r4W-gEls>Tj\El*U oS,d O tlqk;X%6_7T#Lzł(.6$^4ߋPipv+PqF~MJ/ԽG8l!;w,FࠅS;$쇨&(Ć{(h}hfUOLGF fsirdז9<N"g͌z{a{.9fƃр-7-XD 7r:ug ;ln Fټod.];!bizw֠ڌzTZ>'KĔA½>L }xCaip S''(1^I.{JuRj RAj)-l65 c{,GZ#DNa0phtܯS^I$:Bm"Ɋ܁2p뵻v/s l0+'M*{.ٿGɫw!F2ӢnG$FudjAH7M;zzA *?"Ør!A4t(4T5ϛp/Ec{hԪJlP z{#j#{P%;Pgث"YHLNPeR JאGfۋe=Ηiu9fCLJ釿$O [>KgƗMplh|rL' &ӗuf0bCH]Չhx*mpE sTKjOW84ؤ[}3@ɞE*OU)-F;T[ +9OʋҎ S5:#<&ͷ2_`05(ʄ{G'q(VB\9b[ ĞeW6P(HIra} $PZER|_:ۿb7 d (:}q5FZ;G·IQ>MQ!(6PۄÞ- 8G.;j!’6_TM{&y m.RgenTho 텈W:>lkë2N}7Iwrskse*<]mOn OBxPEt<0&\Nٟ_D6_|+T=8䀑gn{HXԍmᶙ_}:&y>{AY$(qρd~W~ v:d':x9>xSTP Wp^= 2}z 8y_W7^+t&e:`Īw%xņ>exG7㐠z3&*WH[P̂mBP@[Okכ8Vjth] ]É5*Y^3O=}+DF==u@:~37EQھ-pˠf:)s=/ X)9=Eԟ* Ԭd^':9޾@1Ǯ1TN!C!C4yUA;*`;r= ]\ht )X"v\FhVOg:[S2bVxW3ܩ;7wR-t|̰Tct8lEwŪX@$z u֗͋ă:<(s 1Kņ! =W? 8sORon{D\"gu1։v-,6oW% }kljlϚ{o) ɶ~8 e%Dljv e@B) P"~%N/'{bǀUz GPptܑCЭc,GD; .:7.LizmԹQh4wS䵓O W[MeyIة"%1໥ 捜*~x $Yv9 ګ>IX9y]0?x(eN ons/JAJ+NlwUTcm8KU9FV3otCmgD54],`>tf΢?I  e;}y oxbQ3\Ɯ с,NbƜGSkEoR6%^ ^<6VMwegLY(Zyd ~4{GU0B[]uz<_Jp7qn &jC2wX?I6 :pXU 3"CΚrm% bU'LA!PJ/6[W{㶌\%J"`y#Av rޯ.ͥV&ihv_{NYoyEJӱbf%uR&K{8y \Y~d!݋XW(Cz`U X+ ʳʦ /rQIl$́?q.sYdiN61ÿ<8X\H4j0 o8NԸݕ64W] xY ̮Ϻ)s Ն" ӄ|%Rƿ2ӛt8WINmپ89]KYO;wYݭ#}AŢ{Uxf~F1~ߓQڲʅkm xs9ops]uMs9^!^'يG=>Qz|Qz|$=I'Qj|TG5CTG/6Q*|T UG> U0*|uG>Q:}N!Q:`t=uA[T|0EJx(ZTsi9~BO®0%Ų8Ԅfl (g9KZlm{ w-@WЖU S蕹{"\ӶfƏTDS.^CW>1uy$I)IJgmRFxiRv\2XV9)H+ZTk^Edj!?]Z9$(E`TW-{to* WEVt~N&ڔm 7ޛ||N,.ա.  S    "!qC`7ϋbP~zR_ U{gb1eR qZhiL±;P~'h10:z 5퓛' >uKvFy͌'3Ts.P Tyh[iU%0 )`jސ}0M29a^zTi_y'{Hzn/#|]ͺW&܂Q' :~I'vIALxDb%}^@'d:}ǫp2>%KRJԧH8JGֽ9|!vzK#EfD X |\y,Yka YX1Wlu4ͽڛD,:sf^/{ J|QA5jrU7uAiAFؼ'}~**l=ۢ-{Iھ,4]{Z @O=RVٶM4 ZO0bߧ6tЌO/ɂflG}=hkcl! eAM9@vx\=4i+eY Xtd&uZ*)RG<6!oov*ۧ7 +nsY'KmZzeIrLpJ'$7g; wKHPyG;^[u*'}nNx<~lJ4Hkft0]C^Lp󾲽/<ڕ)j`(<[]KkĬwԡK<;)QuiAV"h)EqGqGqGq? Gs]פsۦh΂UD%-hDK$Z"ȇhDK$Z"?%I vŶwiH@ĺJYv^(dI\N.q9L,ɼD{f^')ȬS)4MDTwR_dP?/$jKKPL].mHPm390!;svMb+}!S*g.Na`Z]8O\l \ LU8Η"sHF`q_L@Ap3L4Szl` $AJc>l#utd: wdAscZSd,0&/`"qdJjfA::>LH4d@ѺeM+ {9b竧,Ď Uos֢fz e3j~ /M P. OQ-iqs/ kZP>h..}#V0SDfh|PAQʡt <*gȁ Ѹc/#ZŎ3h 3kc zDx)/J:X? M|l8eiJ83)`` j#_4 92}40XP`ܘG/ ʛ1>6y\QO,42tI`d%y,VDUx't-:r/`^ /^|MQɭvXFt\Q6%33Ydb1!T#&XEE`8={)ρ\Ydg V L8$h2+E$5Kjj *c^H#FZaL:AOJeyRGEH<'d*MuDyydcI2H.GU%2/34 y `3POadZa gPԶC]$/(fNE` @ xl^^V:" Xvqtb+L-Vm Nw-sV:@-]$h :KR{&I+:[%0*wp> dcDL\/MH;.~AW3z[uc.Ijҁ4OJ Uݹo֊s iQi"L;UZ{h* 0#ನO|@,TC2Ԇ>cssg~WI3k7%nƋ:a:Hʵ99Tk_%:4tq~@-|ǼxvQvn?wʳ%F<+ݑ> B?e;4:8iƟKb" \p ]쨭 o}NuvĞL{d߃rG=qYy'.Y:tx< "4sbOx4KY'[ @=OҮH#wx;`9YEP0Xb'@;%=r\ˮ; W|qX S{28>0$mM,k3'z}>@zc+qD6_ Оc xqeH|–,~Qo cn1)5f  Oav%Wg*8A;e-gwi&6w=CW;g8f\d2)v-"V#-Pb$3+oaeÎZԮIG5CF-m+9ײP+Drܑ-jT.B9 P=&waA^*<2u2;*?zΈt/K or P rnM{S:1[oiU\%; Y.hr:r٬;nLݔw螎qe`"Ay\Pȋy1"/Fň#bDއ#bDޏ'ōPU{:Ʉ5 %١KXˍc֘Ez`LKS: ^7+>u rȷ,i@$Q,1޼$Yb)ٱInV,/|ysa8N`-u~>ޘxٺwp2dMy5Y:4B׶'tc 4ml²:hoWNVK6~Y<^M" ,,*TOF |7#Q61z=;=4/̨ԬiGY{X70e2xf 3^/sG'Spxgxgf3ygf[ƣ$TUG?ރuG.uG]>Q|?D]>Q!uyQ|>G}>>< G>*Q }TBG>*?BOCG>*Q }TB!*Q ?E}>Q|>G}>QAy^FQ}F5G>jF5=ATBG>*Q G>*?B7AmD|1>(G㣍{qB$ (DB$ ?&D)H"QD)!EtH40pWI-l0T_/G W"1I*S?ԩI} i5@.YQV™tzR}Rg].1}/ISóԛ$xEbcn{S$BFee ӝ 6IPI:)n<,t iC~y/fn{D,*gQ9YT΢r- tFeH!QDe2$m13yHUեupؐAKn 0<`/]M}EC.K|l_S젨-SxvrnFJ99m]Q݄C`)p5݃RKI ϲEZR_\|n:+j&+TdYBtS828f}UMPgr^JPWy*cRqϖ V*5aN`t*US~B;/\zqD@a0aDeR3tQɓL89 "K)ǒ:-~^Y I^Zdz ωJPae#HPҔ|+-`Ay2[$KH\W0'ԭTMe[/03[E 5vzR67v k0tY0R!7s|:e]>KXcIJKSW6wz/񐉌 v=/Ⱦ'[#'.yu^#2>΁3w+g9~x9@x9@wx9@(w}&5w;]z>9Óh̜w8jӪBz'g'zrs=9IeKvFA$s O%}hf7]A~.c{~?jO?*tqz?;zv{zFo (P+2"+2"+2"+2"?DWdtEFWL(_SIf#9Lβ{AD:T*~]?MmE'kILKg vɲbZ\gx]eiOc9WgM4nqhD&7;ѸM4nq7u錚(+ Q"q.OMXiKr9 LMOMaScsc^yQ<62grd)hզ+ç-m2I-Oe#[>lYUDue |)]Tq, |((i V}ԉH``P UUAVw4=7]U ƛ8P(=3/4_riey?ܖ>}h_l` a9IHJY8;\SW6X4 hxG;hxG;?~#e2P4CSdm( 4kQ+sgkuM}w7h(9Fg+OUlgꅙx;Ӡii8K/ؑa^y!Ag"/'"dk` m: IhXUaT $DF]&"v:lQ;LMӱA# o]Q'zS\:Zt%_IZI_^'2gH R9ORLI& r, -пjk۲MoDoGul 'w3 yG)\UfC@&=Ef!lSwV1.T<~ڮַY5{Nȼh 0QdŲղ[w嵖"VGn]g|o=(uz_/zE =_=_=_=_+z|955ya/Qj}TZzQp!jD˿i_wƮh|^wU-hܒJkYgܐ`f-[[*>ķ0h hir9eEK#sum6\nvn%x@W宲lǿ+ [.i] ՛#k;Ќ[FѶe-Q4&?h1-h ~tS#B%LؼtV۵ ܘ<Zِ`v^`/~֐7;ĉ`ڻ | QB ԀȮF\AKTUPF_I(<}Zy>ۂFcG=I(_^ռz8Ae4 !Ҳ[-:v0ZL^Ơ6^lj(6Ϣ L|5 fM~ҮNL,+h ry@1xI/uOMZAmQx1ԩjFmdn9,ܧ Kull<qWGfQTH` 2#[-o u0ZVƣ6I1 6cO TH˗Oߊb}f(>?732Al2M73SFU#4A+YGlP[eo52z 7 u}_d1b+\d-HSHͬ]]me|25 vD<$I E*2E\@_]o2[Q(ۢ +U|>&2E!I_ 7i@k )ؓ@D$_,+='\zr*e>6Ňt?>>lGTٿa3\w#/<^"ͩӧצn-g|zS΃d]2ÿTEl&^Ѻu*7v` k(ΓrikcJP m<0Khji88Fp4rdd1\4nuwkWuh^t{ caLdZWrGJ~Ke=XLMtm?cʘ+V4{6 8~W&$U) N\$%"FWIIA^eɗE@I3Jr:)x># p" !PK]Q䞚4 ~eCmy_ Nl%UM #5_uAcIuR:3}S6 V~<8JIRD.%R>eB6/ *ͫJcj\䯍 rm3)ye0qRLᣨNXi!IS h`0f#R`E7f -v UEQyq djw!ʿmSl&  znƄ Vuiaּ,ϊe#Z^CO*i@v/smIi9xt2pT^^+ DnҲ8, `d v<&K^j9Cg(5p^7>S <&Mf8ff o)((N8g]Q5׎lwe`΁%<gj*ʒ>q"_R LD4qh!ItʱM1qg t|'5.x$WjEsg${R4b)x>_Avs'X FWu\EA̕׫0j}v $##X x?Ix*&t:E`w O vuKcԷ4u+!VB5ı)B@ORWʬ8#|~wbaE kz |b< < #&&yBsd W*#+ ܥP0 9 .8DXǔS.EUFB9.+S1EX=& upNǒzT 9  t§؈h#چ% F*6Aԏ/*?y\vS*eՂkySi4ħISY}<'L0S ܟyy ԢSs_RH؈Y:ԔQ,+ k6 oF}o%V Uvޠ%^+$-eH0 %~H\wܑX-2*fNk 2"`#*J@ ^įJǘI.UeŽ )Ƒ6$٧= 4Â_vt.7Ҋ+ѺKibP^0~ND5)_)ʅJAk,QahzO`0HlN\JrY1m?ҾNI&)-y\ڏd|2+ @<}l^)Ĵ>,*M ${^A\(9H*^hx vf&g0 OelƧƌ't{jsR, 7;tDDysDTAD`E$(F%vp2^hc]?I:\ MMPMv!ߋE'! maLOAMK tDyZq!A3 U[ VѶsP%?n55l1Ţ)]>ӼFK"tB, mծUR]Y& ҐHS^&eY<۵E{,0F, #R.͆O {" &*<z2j5χx1W7D&~ ̮LXt$)%EPS*EPdւfraǾA (}3OAC,s@HNg#jtG 9ُ /%Lc!Z)W3I_c z~>6Nuh}˘Sr?Z>t5uiTBkQv@ ~I)0rpA)"i+H^CcA?i=OҒ%J ==,w0Ӥ%z Q7gH2\7/=iXO 2ԀTl7]oM'pPgd*1Ђb-JB 9!ir>991_ӹ^9%yb#3=-! YBK`@ a\Y3R,.i# C('O7n͒fV>[~|4伃&~ CXI\hl$֓͜(d M33QfK+jBe_ErTGMq I69Kt.`-(MаM&ɕi8zR6p ~n)JOE Иi2I$-Z uf<@-z&O +*n4/V+tkr: Jv bԋ-n&#zkVF➎cԔ& ~/*Ej =W'hگJ ={ ۻ6ϬO1Ǩ93)׉R?A@FJ7_)T ?Hɠa'Kovv/+BW%~bLnnГkE4ahm:U~W~_~zՋ~cL@O;9vJ ,1|ͯ ͯ ͯ _ &y!7HǖYECX0x,t=1,7DgZ =wsC2$1zqO$s98j I=&bkǮK@Q~KPI.#;?{7CQUVNMI!b2SًBt4q(N£fh4RqÐgS,M(`=L&<6a8NrOnc㐽\Lk`huILvŶ#rc>%2}Лw\k}Jh= f {)@/%YjPD}KICzaʬraHØ,'zGIST_4LI &nȈd֨[u?BaŃlQN QhHRbSQ 9`D4Mm6SZn]w>q4mVp(+j< V.Შ$oHQz^t(4` z,1ƧhqqwjGϙ?,ؾ3IsdQx<}ģqOȞ u J>uSϒ(y&vvՄEd%dJ$n)06~U*x& 82X)ǧJ:_̗xJ=-yO8T/z|b΀0D6.jϞZtAD#P\zHނBӜ //cvˬXe@0yLJme].z| _w?].w|Ag:y;y;y;yi "sy<-4KiQ_ls>%mgznݓȲG?B^wjE@ç${ +Vuֈm= ] 0&XhU.]5 @䯍A%.nV!-S )\~B)3czz˶. /Os+<;F*xq>i  $~xZq~ʓ€񺵼YԦRn>HV 6(BM?"yo |_4.6fi 1r I"KN+,ͣ. z[9&uM(WP0fU[1Θ$ya$!}'W9mS8#]j6vUѨlo$,9b̄ ZʡVA6EZRjc\ᘞTbÉǝӊ)L8'pjNnH- JQjO6r^0 o1.-PRc mvCdkC3E7[B._R.f E}5%ڴ#w{+_eՖh 3u`LPY+m,3'À&dTkPv!,% J~/xp<߁}?pHlsSZfaJӕ|? mjVH.kPe%iF gu-R̀2"MRt+4}98$Q"7" 60apyUpnU'aQ7')8yPAݰq|GE69\p> D1Qwuuk5y$.@܆oYxvu]7[SbŨ:!t,2? a,/J)[SOE|uSLhA1 =Ac_Lyʌ%=Mfr_ WݽȊұ|V |Z8>ӝB?'B3.dWNUeҘXƓn-},0\?ݑqpHD, DoՇKy%hU\(4VH(r^.!xw7C4f/[:*5)kME>%O=r۝4Wq-2Wێ9/2@<@(fp9کֵ(.ֱ{ X&/!۪D n3y B;A _ IӶ7*}.4ZswԽ?]Kz5t}SI}VX˦-4eu- !)³ogJ:x"u%oV2.S 䶄mV`hڀG^U_~$tte9C``:CL]4">\T՜Ҳm+Lj4>92XtF(?Áߐ2\$sTo+:1!ao4Y.BNJ}vs'[;vB ԁK3ݬeyO'O9+JKY>Y-*bߠE}oRc +cҊG9mRl2 94/2m;̕>R;bqrrJo!'%^wR> >dg;gX, I)%\*EhZGewhfո#<ܳ`>ҦDX|*b><"^.܀0H^f˲X Kq{cY{a{SY{3G\ptQN 3QP]ɅÇs *B5PD (Td5.m8MVldcGƤYnyuO?uTd:"~,GyRJ'6Gpq0bÍ$ԣ,XZo$,(e&ZO?r~:,7kz6JCJ,]Z ԧ \S AќS7rssp+)\% *PxWsreZ!(+Z6 jdl+ˤ?|J@ޅׁ. Km``U:'0}^ڹUO755i6:F+XPyiUle{ɿo&Ri--|5]^Q[}Y\䇿f{}Y4N}K>M9CKd[әRPŎ?Kej*M tHMX>&o-6@2}~ھ2*⥥ {;qHߚ¿e#Rbpz2N zbNVMi7fƒf}  1*/M,HP[n8" Y%M`;oQ >?x *ڎJzv{[ G4߾@~|kGvXVF$)F_b^ ?YgY'xŅ=xcRa_*|_A** [3M&֫u>F&`Wi nݍMw㦻qݸnt7n7nt7n7ō8kxՌ0ǵg<CuM9ʌ/$az654pCxha|*ЛI0uiEzbK [}T$ݓBjwHPlI]mNCMRvqaQpɓ' 9W'H㔤S.=r=Ǩe<A6?b m] vAyʜ}MY#i#[cHc ]~I\') Aɝ wN\xPt?!M|iH\-cNq]51cѽ-Y5vE N ac7|fk%O hёO'(HT̂A!tk q1y8(>7Yl+8)cŝ-1 L,s,(_m6Dm~a;`ܨuvk7Yې уte9'\?ǭ3T;gʁcghXguabI?1&OS[1rWϦ 'Iۆ=;lesKFn$?k%AzFh"< X2tZu |~p\Z 9~ ;UNSe)Jv-4"4gHŬ}{+yP{c$2Y56NnnZ^^IvFG~>^Ö掆G7Gi]_v}p`7wy ͬ%2<83n"3s{6سYU{' F+݊2_ ׀8]<4A G_ayB7^h.Н vgݙ`w&؝ vgݙ`w&;3LȾ;;;;C'w"|'7"<'y\0mvO+duvjkY$S,қNTz)@"`W+ͼ| ?Z|<0eˉ=k9#ʾ)|+6Io8f8k=H*z@RQqπV}Lnf~zp">ĥN{[MX%Yѻ=cO{SjwXSG&tks;+mWkŘLiqi٥ƞ~H@x;V@S3Y!QP,_hnk eEK~Z Ф|_ycfWY aXs(1YNs+W-GFEG LÁckVKBJrR}XM˖)֥l?A,4y!𨙮] Ti_jq`թ[GV6cInگD&Ɋ/ \ H0[u_Wv.}CNd $Ɠ]`VKqo8BQ<f2i˫d)#=ӥKK j4Cܛ2w=A''7v\{Y`@HMƞKjJ*{=-5yeyvbŎ!+0ˢ|E 2+cvYmoPAzՆ1N#pqB?0Ӹ=ii;ωEuо>Pr -J N𴱠!Zp異GRw`J_okն;xeYȝa^)}P%2$ۣ%2OgtZ(Nr[CJZx-(qV[%Ĕ]>_AӠ,0#Fktvb@$NS/kƗ2D¥ xsC0sp7d0zmw"1~qAH']%% 0n@}L"5-Qݶ|T/ m}_X,s&j-\ ٞY2H4 0>mC$~5?H/$`QŃ3z4b1:ŝ \yr;#:pޑrME|)ءD$ηpΚ7cښqH h,f2Y¬ªf/NU`&Alh)7u2?\c"ZX}C}XNneCf`!WYWq%f75&G "Qجc'OsE@0pǧ0 eQ`pR ,EVqNc}= 7晕X] k7O%U_&ذ͍3:;팧Zze2n]+T$Qvr%F%cN >"p&[lU5Hs)`dT"*Q.<ͺ LgUi{.4Br@FYRNLvs0vT3pm$;xC/~F+Jb7Hc39r1^ٍ6G9U5hm05~LѴ ZjRm$K&AE58^7j| *Eq0IyO/8d`E1x`lL"ٍm)>5Jr?^Jҙ?Ov6Cqad!Vhi 5nW)#Yb\S*0 a{m!S/~,)=А22TuTeۧQ$?N3>xS0{A,Cxu~9w~9;aqoDZ8ήZDT ]|O=QwP=w uZli s_0n].p2k_ +eiC>:Me(聅_ers7,uan_)µG vhҋEB9ަ=?%ȧU dI3~@O9.Wx$^~V/>C|'u<8. BxKAtŀf Ac yd!q9f Ӱ*{[:$3 IA(FHc]\M'r@BCGJ8ꗎf~LIed8 fQ/MR"2􋫕챂BXKB gܭ7a{ш7@8n0ܡhI{uXݜx%ɏ Lpye9nb7Ҁ.JDJP7`w 9+:z< Y(~O5K2ȃOTkD`jAȞ#iyIq=J-tmwAr*Jq@q+ţ6^8a6:|^piC:~YlEF _x8WE"nI%}!I6 o2V`7ُ~p GseAe@"5q8f- 1{SFDEۏǰ9\3B& 1AIt$klJ]f7_Ĩ c ."~QȂ#e m~(b›tqEِ58DS l?$dGE`{h - Y6bNܙ$o8T: Pdve= 3OOaH#Ö"EH;U죉`ZNʌeDndkXûōI"%ß)ѧʖ^) |Q<6VZ$q/vGGqs0 w\C7n<0C]l n[vh 8Jt褷89>8O=,|*p(>kE;P8F"aB0JynxWZv:gtv0UbNQťa61xG:1 }zA3@ -u~Jq"㝨 s֐&F] Y;7n>i%WgyG I  ֢S4=^m\3 0m ) ečBXj"lפ2EyEJ۵wxy\2D\Uk #KG [X!)+.J"HZ^tg?_̹ڀU67R7| 0j-!ޒN]ltӡn vQu-PIW@{ D蘇)LH~0kads ]28rioq[#yBp5Φf;h羏Yؠ:R1Cè;Xǽ;8=@pKQ~&272Ҿ"3E{ϻfX׮yJbi`v`?07v`4"R.#ot!_s-ѬE' 4S8ԪK6lШ R3 j`A7Ԃ[ h0,8nQ⑇ܝ䑴4VAZ--Wܖ 7^I0p8tʥ d JiǺ+^7u"9gDZB7cV݅_M qE\nQl du<*h[{Sr\geD~#Dڜh' }z#gٽpzSIў]u̫XBbG@Jk!k}$3Yzs$Y,AP$n_ƔB6a`%x=KWy[ uphƍ&z-8)Yjs, !ur4qk|<㱢1U(;r$d?O[5Z0ZcŐkP;<|_nK k W2~X~fdhĥ,AϜoLdefc٥ Ǽ,SnoV%4Jh;O<,iÚJ:[rFhVhO3S+oO",y-I(xMJVtܯ ;p%&vJ^Yͣ(Qt*=?/S(^ p I\ڹ4NiU~iI{C.E]C^v1 ?:OJ:xԂs^x&ySٶ6K8tbR>nMծ7aIHa>G=6<o./ y0bkFR߾,L5up~imAG4沐dWdp-G1)ӵg C1D$0x!35MuU/)gpM{ݽ!3v!Ė]XP}2(*I_ {b;'q4M \:kn0qӤg 9l +haxҮx7 n q_NLC>xK蓪k ]4ϤBfa %BEv;w5Э?f G u?N&V V;Zsi…\;r5&Rw_X6b(?RظH;"ӈtN"m=UG)۾#:(G6粓:ZZG6w+MQK6CKz4Ȅ$1t)2d'L|hG9ˍw1$~wۭ?b-G kljI'!@ļZ xPj')9j5ݪVj\ʶn#Pr yhܢz7mQ&cTX2jtQjG.2vXޡR;RH%wx\p;ZhϥwܻM C9Z`vcڋm"]닛my;,®흕#ֿ M vKĺ%ˋ+Ž[a VطVܰQ'rOu]tkv"waEe7<wzw>H63{][ SH|U.:=䟒4H1Ⱦ#?X\1D^o$ =‰YN$K#?1/L*iz$5jB<~'_A~kj|Le]&05k弴[5ݪ;VpGUD_O'cb'[]CSiu-nՅ)nQ:Tn5rRHzDB [޶ĵ5{AdSӖIIIpv-Sj9$WHWʜaz(V۠4rqbI\&n"i&-O1̺DܣyˢSVsY;ֆ ΢ؖK9jGTIlk7iچ4um lm/>o (BTkSK玐6ɿ)" <\~+2?hâroY[rZQn{zrG1[Y2B.<}Z[W&yIQ\bt`0;+pFH|/ʐ<'Xڪdy/b{NCx F{mʶrS3ۂM 7=4i='nnȗ+^Bt~\A GxUcfyy]He^JPqP&_1HvwprqtmBye'9g}^F5t,=G3 wWf<-R馉|mﹶ|ǴEZP]f ;-2NL6!m ;0<^dw`yRX t1u8S@/uX#D3%pgoE=ۮ/|jS)w -eNXQZV-{v1dQ Q;ɝ9Q 9T̬tp1 3M eE $kf>Y!1\<$ckBH+߀["\P%{iu;K {꫟EqRbQ[EŊrAפin$q:W"eJD2FnmetW"YP-g?òԠeJR~P#~:.~Yc~O6F@d%3ch֐D 6'*5u-!|i'e/;~ˎ_v@>F]UD~[ھ c/NO ^Zڲ-L 2Z&DUr)2pl|Erx&(yLm20kp :bc7VLe&#|AQ;nՆ<0jvՆ>*dC~LTWn;O!"v"c< Ꞁ3")qYVVL`ғ|2.ӘJ8y[c-[!qM;XJ3~cyNd}qB-WpE}y>d!ˤRnv; !3D' LbvVlsWזL7v/5 3,PLhG#>iȷ7IyY did?`2$ic/QZKsp_#Cx @bCѬG/nK nKԶs喎&㼣x1|WVd9ȍPeS %Ԫ lmuPMna[!`m)][ )W@to2L' bBpr$&SvSsM3IJ7gO@Cw]ޣ&He €b>8S ,QRv A&SyD/W,$E!N b5<"Tv,q? <6d|+HhjAɽ>4TQiJCP?pޣdb3WE ^)_qR6Uir[2DԍRǷ,ݰn٦樚6,I?=HĮ]lθ#NcQFj3/kŒxïs@~ l5G>#D_s&ןqcTw,|j:kТ3OCW Ğù^!̏=( "jHI`kS" D <hmj-jŗ,x,p=A='p2Zd-ni81e6˫/s"_WBͨ"IEv+pZU΁ @dt0Mm0@y`S)u]߀|gn'BjaTEekBk+[wJr#2mx zӮ]z4dy3ȏ-y:>z}MX[{(uktH+T# G9  B<=,t8t0kNuXX˱֑Pu WXXa/zM(Ǣ֠vquUcʲJD+# K X_V .F:WF2S_, W "o(%-ބq_ W_`hY %}9ֆ0UD'PT}[fzIkP[S+بxtŨܓH=z\,*ٶ2+ת]LUPxܳpWtoWoaJ,t?=?,]r|kZFy .0"@5x_lb9E4`!bKQ ďeAIqWF,><خʅ1)d6"~ %쇝N:tjWډډ/A:礿9'u_'O 9'uc'1I'9WMa‘qUm7~elFLZxOM~WVr!e5riۮi|I;N;[нf_wZKس'! @CRZ~cՔls#zQQam)xҐk؇j;:kn'w{eXM; Py00ʣwp[3ʼn5EwɕLa,4@̶+#V]M|dL׼=F&jCc.d_~- +R?`d_Җ') Yme(FH,#=6v ѯt/9>Q_/\`Qd[IAbsU^rzc;e66= TVw($J4{Tb͑pwCĝ*#OV]e!djAcoc,}4goYe78gɳd`67vV^֙"JL("#.(tFtK/(fC\nE"`)K0GȨ*ϚdFqXxp60}V#6g/190:ϓNemI B3-$V3TLc$pc+Oar+A8'ޮGʐBGjzS=*wnh@8 }K6ŞN}T$׽Dž=VM<~-@ ䷅t.e1l4ba Xi,2掿xJw)ɜYAQd'xӁ.)]r  Rpw\=y)V#ަ-EeoXp:?["L1+*INphjr@BSIҋ,_L~;K߉L/KqԬ߸Ⱥf)D~S򔮷k|eQ )+K*A"&X__ ڽ7ƲQ*uB ٷ,FFF2Bu2 ?{ϵPݼODeCN]=>?Fo!;% ֣8K9$aHfu܀N)9p>y-HmHE~EHdJ,W>ic'7v豷+iKyp=`t7Y9NA^еԍ~K M'(q0\p)^fӃf34u0W@_F:<_@L,횉zD|G͕Dp."eoQy Lazmܣu*HWhc,(54뷃][x &KM[xSfp8;/%" :5F;8 3s9>mv2 KغB'#1˂wzPx%e+(1N0aR4b5/ Ps_c 7.փmL|_q : ,YP)ZٝY= Wb_  &< ؿ/.dҟJ!?%D*}mBw{$g18W܀a&^af-1j9@0lkoL1ܼ֐<ЮHl8 6ZP o/)%<\Q>&.vlvlSX4C-7yI^mwwp<\Bo558?UB ~,FxDQT1|*4UL_lT̆(^EN meԇEIʅlYTZ590_L*0VN!SzkɊ{w"= hp#5̖?b-}6/YFcP[͛j|P,3ރC r]J u-]Ip[ǘP_iV,bcoc_Ev3\&kbw,pеTdF< Q |J.zR6 LkFFjw0\[W Sm4rwȑb,vg7% P vP);$ΔX`Fj`6׳ۅ`Dʗ ʾak[/4ѡn8l)d 1Ͽڢ.[+٣6.3{ ñB4Е`?0T+nx%9F!õN?{e 1>JEn|$+4 dۻ4?Joɣ c~>+S%k8m` +aJ90?ʶmXK*sBc mn) pJeR6A pE 2IB4H V%5yx^N(,X 0߮SW,6,k5|cƧ~D 5oO%{[PÏte7Nߴ:*YE'kP8oxZɮZ\IP[*^k" =;2 lBr(noIA}^!ؑ5kY<$CԯJU! dW SLWryoGޮ&ō[wՒ׊V6-nqxcdNh:d@,YY{3/M%MAl{tӘ9= /jDaEƨ 1^CP]o/oq].C Ѕ?t]. ;> y(/֟"~F5rX qԣXry~q#v'ʷ6IύzE&M[q#9mؽl˴Bi/p}1WAJ٩J٩J٩J٩:S);Q)CRu~` q)3N{T.1ZN|Й\(tnCX(Ƈżcɶ!s-EÖ8I?ACva7$Gpä̞[uZ[$/7ype8XH_32Q(wc=!`AYAxD중j:|,˥5\ S;wxAAPJuvTW8GK l'.9xsoۖCSTQ>T۔ndHhPAqT]iEaz9/QQ@c2n@J?+x gsq/Y6ټf[}m)4K׈\Yf*;JZj5{|$\~Gtٲ~]-eR'=Rć sIAk|͎mP;:R"-)sz9'E2<Ѡ:~4+~# J-!O 9ve@x--^me2cw!K60k0`vùEMr޲Eduҿ=Ʋ$ekȬ^yJ\SH;g+R`RD;Sqd6Wa}Bܢ!x2a|JhLcASlI]oaM&h?X`wW}3ˁuD08BHVw4RPvŌ8*5`ilt^.V"!ŽŎ2 tLR@sY"%+@4I_e/ڲ8fgv?J:"  5m cIndpq4䗮FOU#Y. kiDNpnʊ{R#fv ~H%`Y-tG>s R;jc5=K3mvˌ U2G, R~jHn(F.qlL|8pdl$-fg bCx4ѵo24p9R$rYO7‘Wqi,ʹxf\Cx-^G ڋIAt4I=&%K(tkGٝP N ۟ Bł->uYI?*v )`UCiC!M(Z.HXc1:2q_0B}܌,2ݜBPZmcSJ14CJ3F4-r@yseEvjɢ$fpvթg SCOFlY:ہbeYQW9\8(Е8p8Q ;9(p>uH38rT(vj/c˩2vO뮗Sez9^ƮSezQz9^Ʈ:GGE*f \/us<^x4p-hꜹ:]/U?^t (uFxC Gn(Tvqך-u 5qeozz*&^.:Vē@cP᩺7c6TݣSxg]\˂mՎ_)?'WD~{Y._* Rkx[psÆtP㔿TeAM "n-lzݖi(UҠf( "op`"r@CkuB&R$ wضhrKd0{F6tr>D簩t1b+}e&;B=+r:l/ƶBpޭt&<{*:CjcsP;g%]RXQw0QDtHHKin1Oϧ&*͹J,^IT'ĵ^ݰr+29ԴlC3"JE pFxQԘBH)錝; >1,:@ <Kk; j+u՟ӓpsiA~j 22f%M!u!%Ν1!?VpuW[V NS!Un#>Js?*˫7ۼ2`ڿ+pּ2剛Im's_uq\Hy"^Wdm1 )m%jQ+rk>=`,v"[9aRzWcMo"fsc SiAHD#,m߱0Am1% fP& jϕJ]T"G1O&RVhmkkoӻ#K3-AJ^>{IUfZeꚪfWfHwq@#H+J^xiK*}RnFw*sdVVF|PV(wJo$TEDdo8q_Ʋd'GHT7Fa= ڮ3À6:Y"fڝY87dC LO͌.h /i"($7t! .~[#ف }6}`9Us]A`\5J2)cDgi̓3:^-+Fg ߊrH(p03]#\+h]Qu#[,So^@fC]S./)gm+lfx5隁d:$\ NN\ ?TVc%seW3l0xbR#x1)?m HF'=lȳ*$0QНIV|Ta_$/o3j) Χkm'hh%|yl2NNI%N:NmЏhWuHI͘]Yv݌p|i\6X ~JEB6"԰w~uy(Ďw|5qP9:A F$iEkXOZ59#JG嶕 wqϗ,:\r_>el^a`|:M&Vʭ:>:awyhT$zZ*`97O/tQnx$U dGc/`8vi\ agcx0PKtmNi "G-@c A,xq?/޵]-LJ?,]qɪ7"UR[xB~N)5N涐 FH6zpl0ŹCWʎ4z ~Ko?#~39"RXСu-B,Z;E)Y/Y9!C32M!M%ܹͳn[GaMSe}BzA{ )- -eا` ̄7pi6f'2v{@sPTbC|oG)O߂Ң0. >|(pE>Q3]iui)׉^$ yjb,њs?bxQQ扺,p~ӱ$ ńX̚}`jp@}ctS}b@Ԁd6F^p9VT; WJ Д 2E9x0ވD@'9C9ZЀ1ٽ JM$75Ϋ'?D uٶ#mj;8,)t"Ww8-%fuR(3zV[WغnGN1: 0\>)׶@E u.u1;y_70b{7p"kia#.8#A3r{mIYҳIe=GJptڻ9ry[D66 ƌ#\p4.x CX0*R\ O FEDXCL/4(EZ1E6iؗ1= ,[chu` Ok7Ts{ T(BKk ㍛Ҵ)ᮎ C1; W=eΨ\( cHr1`2}H+P$, NW8]'n'Q ,^P2_WdƒkQ]%ei #j T)DL)] "׉7T"0A06K Ƚs͐Μ?No[p'w!"Z})ÙAGʹ"$^ љ-p|ЫZ!DsK?e=4-tRI*AR^ksXx-F$0ZG -(JנNm$2Rχvn SSz }T5vf$BjH0ΕQc ʙإ,24)9p@F,V"| !pnhbTdL\*oZLWÌ7pVp_k-ޛ(rzi`̭5b/?]6*>Ʃ&ȡ$\Qw ΚG%(C/[?ˣmFS[f}Bګ&pg oQbdMqqYz{Y#/^zlC,r|V2G[ Xz{g!hwa,-e*IXξR9F  PM󰦞sȁCko Qdϯ]j'ɿH roͩeEA-5 pq.З_02"p+jw4,[]?l@]ɫ k{i%@3G˛E"0q l2\R.r5*o+@)J\A?[} %6U\dM$<)6x*X;'HՉ=R@P%_6Xv۽L}u\8(Zl (+cQB\_`9"Q:xWT?%{9&͓Ic?|K8cMa|rQЯ)WkEƏxNT 0N#$}.haU`AWZk *' &6qdFn Yk2HJ֧L- ژ//Xqʃ@|Qw-6#\vWkyrN%Tumbý~j*C $۷Sç{_ئ/ɢ.(᪻9_ջÚ5~DtS*SJ+]xpw/bzkMr |χ%O-*ɖs#{x~1 G!etgNEع{=YGh)*p}=d rf#D`0a/pvgvJ5};qQkMdt$@&ǟǍX^bWq$:pj\:wuj.#<0X٠/yqE^.D''i,[b6rt۲h 24444\B넇OBf{Jګgh8i٭߳hE`|>3-FmOhHהm[CXfi4eಋᙵ.+VďfZ7ٶϹy7}?%u.̺P ="?Pe~jUjuw.9+-W'i6_QPJBg:w>Co"G*y.m7IG? 6:ph-;Z~͍S ܓVx08. 8 =} vxxC??RU]UnQb@)NR}7 T+k ԿDWLk\9km=#jɷly45+tL] sko$ly)rW\,_A.:y :oWhohLi<vŭ/ 5$fǜI詏RT"6 &n؟*-]ض_lfiAYb>cWe}  a1dHcE8%0ܬU*to% 2 d [Hc]CG:sQWKyxt$|_b5T~{yy/AMH}AHu?ѯb8"xg| ~m's~71ԅLHVHA`hFi8*)P`U%ֆ}|c.m,Vu, ~ej4&P4pl߸ae_-~0B(e:p;(Fc@+3fԕEf(VCbrJ? _R%:B4I#mo*2>ǖ]>[12ɵr??OO ~ >DK?n% WcQP^.gkHJ#u [nX u,^ZdV? Xܶ*#L u?wtiv\9>3s2M@хD1@߸Ξ)Sfu/]r'OO訵z Bш0 gaq4ۋ"BX7f.7V]`(Dd1}` -n7q& JMy<Ļ߳ [g+r-W+T=VPKSFQc)taurus/external/qt/Qwt5/grace/__init__.pyU1 0 E"^ApvAB6%mooTyDզC̢T&Alev7z.7YsPKSF% /,taurus/external/qt/Qwt5/anynumpy/__init__.pyZ[o۸~[ڇ-b68nR'pDI\SJRN_Cn2CQ9vކs\XS1V#Y7JՙFON6 1 .ں[wG7o'+`/kHl)Oҽ25%zo[<_;Zx&sRRFY>C{JhL+Bf8A0g67a5´+RI4R,osqgK`J6ˌ@CTY q%U t;c%,9ivl2fؘ)~\ rV4sFI?X6*fȥ UBjI!,[,0P=fSsP$;:GW;Ϧ:DO1 ̱6܂0E>Zx%L`mBxA}UpN+׭;[qSN` P͸faAZHdYo7 !T6yn8PLg =HC鶌Fm (d) F͌((&T$=_’Pɬ!jtJ ݚ|0GP/e X1s?1D9<'8W`.6 =J_1sKJ3s^+Pf4, L_x5K G!$4:[UHMnS@0]0%7hQO !grY;S @R&(vhBL;n{G!q(lT ]$$Ŝ%OYO, )K6Lj16Xl) R5v’nBX DCovvx` J';hyC9U`kwL/VS:ǀ KHSУfL O !q=וkˊkM!鼁AWUaSUQS r8qD8*KcxbĈԅ'pW\[\&B<ۖNԘv!k0 F"@O ;oXtq.u8AITB2a`*F}h]g pC|#|Bm8h3Cʉ)Qx*"%ecτ}Bq жQHlT$ fytHE%+|0|0o)a69Ef#ms&nÜ'Y*iЧW1Em,H`"J+v%u% ! 2IH$tRDMHt .lbR٢a:?<-9 qO(@qVPr'%!T/AܝFhu訄7-#f-vԎo#,2FLwnJE"I&h'@.@:)وB[NAH=pThl1%\.Wqt[4n?v?Bw_WT3'Y7vNK|LF^o+=/-F_Ǔɏ!ƶg PrOn @g~} ߟ? \|WEnj!7㮻tބPzn~zv>pvzU;w%M7L`L`u /%qm*ƳjnS[7:"-ur} ӓÈt "vL2Ffx/#3Q%I8 "yrbrӮUrpVL-=i؞5ze Ad|sLg;K>"+iEn#~T{Ǹ13JH\#W]:Ō\QOO>Jɫ{ ckp/_]qUxrLR'4۟ fZL+SlTOnV & a|c"~j oHrE] BdPw/ # %Ih!F# \Gdi;< ;9Mq]=)K-Wj<WLy<|T'i 'cyr %7ݎv4a+XhCB{~ZZ;j[~,%oskdo`PKSF[ F%taurus/external/qt/QtCore/__init__.pyIs(_}oqo8x ښ,vwo%"Ub _H>7!GAd0#'$OU<< )3h0c WH!7a# .irf|| ɐJBluu:@*7ENtNkZ-NqV6%́/Jru!ɹMwi[m!+0n_`Ie&m+W3Y΋%l@2ow ݥJρ%ճ=Z?H01lA7Mze+9G!,r$H]D 6PU7n3 0Р{$ tS$Xƃ~*^&p0 FZG ?d-“`2cWY,JRJ }Qjxo{ݣq2Īp[eihRlPE85X0ɨ?Qx0I' +7{4geH&de:D`ÿSh. 6I 4l~7v%0V/?DzV.\˜W*&mh^Y0:;D'}V4/NW6}ddqUoi{ P oJEvBPߙ(UR/#UG6ɶqh A UiT7> (p#$^}Z4$mPaAdŞIX}+hށ2}s/\2*ae:qQ}x]ז'ø[{ ky7GzG˲Ic= 5`ΦdZwg@jH7dH> ODT}~#Oelm}含s,(ZYfz)dD>;|~^QyMQyl ;kmIGD;I 6>ԔKH3ʈ\f!#sأWjF 4v&N#eM/h@qS6H!o?3@!SV6a:n8·L{6y:wk Ha8T }{*"L@׼1c:\s`*{IIa1[2G}ZVf3iC[0sLPveQN;y,Kχ?%7Z7`/$dHH+'{Ga}5 WȀGĄ! )QR~Qc㿂ʯ6[Ŝ,_Z}@#7{ٞ9nBBil ]Nt_X'#a!ǠKuU,7(:K PM.:d&qC3.XHC WlVæq4G-+<,G&Ru4Q]g5 #Dgǒu \fTRbZ>5q.-\` ~o]DP[eeK&$<8Ag=w@ E &+6,H:J\g#*s[l-_:/P[U2! Wt5m6lըѼmCb,1oB6!nFv`4G8\-G +ޅ,On㟐e˓@l^Op'ã &dC'OF}lx&@ioP ޷woMJv4T,Z?ӠLB{"XՓި m{ײ'{wuq{mvSBPh=+[:bx$=X^4^ڐ`Ine IŰ]*q1Ҿũ21h2T.=900-<Ž:X%ߵ$EI0mBrw1 7cZ},IvMzBǀ,,1b",i`Ds]pC"dh"p/^$}sD\"p#Wav6O g@.Azh=M'eh`)[WmmrM$r|$! |j-apRe$kapLA9!ɋh-<vP*5$G},c so+$aCXl -1$3dl]FG>_B22d:+$ /Ֆ=W'nI ɑ xe.;2a$җW)@|phh-{"NϲnAr-O~Vì۹3 @b$Г HdPK,Y'/cP5y\ ! @"CΒ. !ē&WMS.c}t@ ^ e)NWi Mx=m*XU3VYf)9i0A22,_|n@ ^7D"^b W(ȀH *âH3Qj)tV{ޥu#{DZ/ܻ_}~/NLJ]_2 CmV,m$,*Ew/oK6?_.+CwL 3eUZFʀο܈H7ꏙ*qrvx QpV{h;cs8#rtItj9!<3KכJ&D#aW.)Ԛeb_IloH!D*}):hk;(p0a"ŁJnq ON. > XJSϫ;~R%ǰq̩ʞӔ+rc|[uӔTl1_–OʜVbfx!-LQkv.t }UڜbYQ,,$ljWd-J]-f/!SNiP~TKTP+X$B[PZ}Z$QuԺvb+4ruZ:1)FL+?Ix {ZV*I~I?1a?(QR"S*]WϙI%V~jIrr8)LY ҧO;Y}!COix8qjyݓBʩ̺"g@֩u3A!\Q(R (R0?[B8N\NS0xq%TL|l'ii*Nbe\o.-fhH dU@ dpRO 'N6_AjgEZ8 Y<{-$udBD6)1PdQIJvݥ}u¬x(Hu> I{iscA]/r"+>*жgǶ.^iٌi!T.Gs|4f+9]U@a_br^AW8NF^. D GWp(5d4|@U>\LU!3ʫGKWi Li/mӪBOɁOOw1YneT1uyFneDv(i*퇛t{Q"k:8KPPW}{+çrLXs:]9YMk"/nE0dh<|'p)_漸8&HC}5oLS<_n94Q4NLy4LjH?-:giEtS 5<tuRMTSyO|P"sެrxd\".iK/X:ʼHDa/3/@(NɊG>9)(ES/pXq Fxd2ž}),)FQd ?s)W* tė>MRk)Hp!D?B:&*v|Թ=J)3BiJ%9c~+ :;{ސ:cXh8'CI=+Ą΄ |. `i7v2eq=wQs[G@4ShhUf;\˖Oӌ!kӮ]Zlq=?+A 6Ec^΃G G@mEr TR8: 8ct29w2GG>dD[2PP~ 2S HTU Ҁ@~rf.:W dYeHǒO.+.*7/TQuLKUuZ},j 30OcJoM1U}{i". &ZHa &ܟ[}[N&qSZȎ!j uF0OyS?&2ϳvKM!)d*'FWe6y!,gi-@r[ P {|zI1$\"@R ""|')0vNpˊ]l%c@׌ya-{qpvT.4&? R)e} rkH,KC"{̼ȁlou]S# i7n~ 2(E+EV[$0| (7X!WK#ubW&[vJI8MY=i,#Y,ܣ˽A&( D dƓhP?*g`u4#)ՉXLҬN5g f?ۂiP Ls)vr3%of]g B#!$-ߥf&v3Bq>T0cS:`xK7m j"4{Cgt ] Ms8CCfvcwY3O9lƑ w0Wo!tUS KdG)Aʪ [=MQp-4'R-(BHm$o&,Ѻ%{ʑ( Z1e|eyĿE1$1Mi H֝I#wkq 5 Ѓō{ag%0bvB)!pStAa˓-5MS .£AӢ~H;t9+xe̳nӴ]dtS5Ey}^?=D-XJ Lh$MȓfAffSbK;jBa_ E6(_a/c-lNiʕr-[or%S1aJ u%L7eY! :x8GܘX6-h൨iɢ$"Pf,XP2ܰE`Civ[(54{dM7r Ë{KֶZJ}.0mڹX~E狼ꚯ!˦q_-c=SLSSdBh#3~ Pp>`Fj6BG#x_3IFguu?k~`BѸoMt$9ŕ P+V @KR4HUޘԫ .gd)eLXg bpR얚Vg=3_ɢf.oбv7sui=R9E5O`+۹T^?"g2N<;#XSO%8(0;YUq.e萴0 E+lV>Kf7KVYeözvܮ$eU̍5ODiEg6lHmS;/AKlpgiv= ۸.ulDwAJYe(pmu6 ZKZ2U+ _~<}WJHRwFI ״h3xYC=D>IJN91C3yii82_A+CzImP^ hqcezbhXvi߀ =uTcU^6#=*O6lTӥg,yrfM#ZBa#3&_ V2j޼*CHO0yP2=CwZ 8.7Wsl@.'E蓴7 Xr`9lqi3fBCDēYwQp0дwNe:m`ds6$VQ,J9Y3'Gմھx1?.v1.NۜpQK;c+$t C S  9x('R^2&?a=~ /U/(y΋_yQ:(1j6WSմ>IK$j7k sqU3! 3TŸyPUz"11FEh7 aDR[Nl^[W ~GQJ'h |(!. QY^j%]jӍ-B8{84 $C!]{ @x);ןZXQ~2}={|#G={S"jdx_=H :-P{ճfvBU&5~ rl–MD1?kL:o `c'.9i8YS\kcot|Pp^4哺ߜN;bӂ}%VD-z3+v ׯ.hK9Lhioަ鮯i[{4t; ]C{ߊi{~[j7;1[s[P Tc=5NuNM ]S#15K R#}'u%u#u!5GsG 8*ni{4xLk?v76Mwvƿ1lss5]lw|=?7[D2:8o}"P#y7jQ{wphʘp)L9!XeiBb5` h>ڑD4;PiP9LYZOYi'a77g}Eo_O1_L+pd ²O7)P 5Y& PL2e*uӠ||Z#favMo *ǽ|K@p<<- D[taZI_ˆ6P89Վj=xj% ,?F$4jE̖{?G;qҝLF@7r+쨏y'3uT&cMʚB,|9LmF "X6̀5nM 88zJ7 WeЂf{l?]+H!ASbBp|h3 EПC0+p8!RJd)k$@Du~ $`5!Qǻ8"B`%~z yX_a}(laC =yXac;V?7|+eYAIQ ^7h#"BbTDi=Yf2FTG9 {V2$VJ5@+_ :t V߁GM~*癯N.#Jr ""qSZ(Mֺat#J9T﹠Fǝ#=>`x }*9tuwE]^I9ňM2ЋУ뾇dr.@Go5U(t ԏ;' *HPclL;Sq(=֚{> ٤Kr# *R]/aqKi^kkQ+lݮ#ϐ1hTFD\O&"P 77^VC{NjrӒ`\ 5{g0^`ewe &[~}u cr0;"*oD\l"#CPZ{*:T0&Lao?ΦW>5W.8yB]? ;$*2@ ˚B;&r#1L 2=W)᤾:48dm CO7i'}v$l4&E ߑIL :ނaGbcbԑ̘w$23&&ˌD[qGc✸68~{UϳjޮrGQL"})>37Z9,u@2sJޏ;lΠWx x5P[Uom쬚sJtfjp2`sX}dYϳF#'Tk XcpSё5]dv9j< 3x#`!r IFQqx#_زx ʳ.t4x4&C68ZlmP;#&`\'eY[7$@ٙ`}é$o]Sʣӗ:YU= j˰7 xOُ|))@:^╷6gQ.*|Dp94$rTQwқ75~xҡss:/W#s qև^b(Yd^.\Vp"N#4ԣ-n=k{wFm!!/41Ax0T ﬈I_*cN& P\G#۩ϡK̥Gt-m$lYz\"2*u!kXt/*r/G!4!brblTi&g!KOgi/rO.=jG/$FUKh/&8D]p(v /::u~]/ H.?}W >\+Ð)`/UJΫjȚhC(JX## 6:ϓ@ne*v6"T?Mnɓ)[k2w8[XygXZRnG" ]);ă4軳=L9htяEbrt 8=#0MQY.%":4<1Qke9!Jzo!NbRVsgUЋ^^v/k.wNe̗+/0^~$&>u8^&?3?쉁w'DIiF+>unۧ'Gkę1։Rوyn1=NWi[WFKxQ0߷ˈGu <!я#DG ##F##➟xDS?q<"G=<]#~\Y*uaf(!Z;isƽ*`y/\J@vR#i]o=W1uzr=Lx8DE@EYQfe륁(Dgf&)& CԌ7n٩.Sqhk/t}[S$~:e]U׮XWVf;W.CMgz6{&&^[tpx(KHvSmmózT7Dmr<\dF\5̖nx; eYo:{M dooJJ7jC[[v MMmۈG ]( :lḯt[>8a=t.h`\#N$_=:6@5Z"l>왠z窹x=({F V i}tb엕5W ݖ?di< a0PMwiieS4\%^Ɲ=ҝASJ ]^[ <|{hνQk輩gď@!auڕZ!Sc" hq4ڴMY0<52c M4b=u6Wsc(cjʳIAjѓ4wnW5PNroY63G w}V.6Ruz:]ؔ^jM8&N/^R߶Lpf3 =W}aت" Fo|eVz 0Xp][~܄Bl2P͐Mܡzt8p٢ᗎDŧ7SM5♩VejDg/m`&,La_;ry1׌ǖԁ"Yu xlS2ܰoqu3%o@~osPZ=]ZX2T474E폧PR# (asj?!eՑp;FIسxWY=UKOL#683BegU&=VxQ[u#Y"$V˼l+c:0s I@v@Rii/%c=Nt-.2GayV͊imό`XyYwi=oL^Ӯil׬Y)gˢ|\xEt ,'A[9`O>F&Z,'`ʅլs[+sN&Yl@v\6G53LTnO*H)f#uJ+>Z| lVv 1a4ejֵk5&JF2)UglEt^ ׅ"8(uؑh/i e EL#iJZ Fp߂+v |z_:~! & ‚ˊlO"1t5$LO!E"# [rqξt |fE۳ˋ駝ٽsiђIvE^1ABgcxu5kq!M-ׁ~eUBCHQFϋE-Cs4O' FKi.ɉsl_n(ߚe ]N/r*"" Qk*( 42UrHAQq;?NAӗlzЊh `5'12c g oJ%YXxK"Oð=1]R6z9_ fwit[摫s&!'BC~ _dwJ.rev*CIN_BISG9&Q |/Q  ,']%ρ>1` |R]!=H{nMyX4|0xHۈ&SL"oEJ k*gwY8Y1[ )doƯʡfep{X ᒤo~'r$a|"} //fc 0բ(Nj'}\|ׂ@b57;ho[A> aȮmZfDp"b_EA L|pqeX(1{(`&bi*MD "]3%8 }mk[0H>G"s$NVodE_lsz4bo'pEH1ײ@$G\K\^(&xBT#|lUiq'S}|R\?tmoΔ߅q&SK HJa3}- f*4{ }>mT6I|38j.l.pÀuB18?kM1i =^6 `E{ ̓/R] 2ʇByϘ3?r!Hd\ {z}d(I<{]l?ʐDYN$4N o)+- %îbvs/84Ha{dl8Q@cz} .@|Re@lgYIV39O'xHߙޑσ&5YC:r\ Iă8)5Q`eP8K>@#IY wD:G)pĴ J ߦR$e-L˘`(*/q0hFE#E G[آFjDz I7Vwo?1D5 cVUjAjЉp}_ى0ҍpKh*e ZGDGs\0*|G׋3C'5b']0Wezj)+EfT "`кR6I }1DJFtb0JvSKP&KI\*^);tQ<6èao_(hg5bdY4|G tYEto``1y6jݐс > Pwf&$7QT*p+kϩ9r[G1Il;Y(7ǒ-9T[yDáLohV/ C%M,?\a$|7tX f#{8%1휜wno`Z#pBU J[duS!XT9chdi@ i(ͣoJQ{;`dT6Yw,,[H4:'i(%G'o>d1skTlܘ#OG]h TOEUhf Zq˱_ڬ,hCnic } X;݁=&I֛XȗsvqN6}A8(ӏVl3EfN`%"IC:"x}B)`QSPHS81<[I)Yqخǜ~VYuhJ$|`V'L ~$8)&p\C 0=$thRzYY4e (3J]X,0dd}]W.V汹8Ao-Dn𻎿ΦY,ϯKK-PKSF[< /(taurus/external/qt/QtNetwork/__init__.pyZKsWR%KǓd+J4$t7 HQV$ǏUmk#8Ty=,*,P*]H*ɣqd9*/҈(ѩ_) >MzߢU8'{|\ly'+0hbm5W'"c kwq[g+ϊ]]wv J+i+>[}.@|0*ξ}OΊ'jdJ^AiF Yj'KIŠ5lnȠ{PeVB`₈_j#aZFȔ]zeP=娵^R-;To{h(%B7eV.7upf.4a@8?acWthF n70fl`: ?KX#p1͕`Z\ )6Fm*SvݦD5۽no khi f|&fwgY-T>f2 wGk#jq?a78-hy:䖝u3)}c8WU … u Kz8k8jCxF=A צtN'Cvɨ6m*y> :F0ԩ  g@YfZ䮍QG䪱< `V CJ*)U?(MۇFȴY8o- Φ93(PlY?,0e#D7aEc}!rF`0ܮn`)Mgͮ\jdY51Zz5+DOd7OE)BG|paiO= LX9mc&k 0h=ASпKؾ̺wR e?s'y"ݛՔd室;BSV58=TM8nq\YB-$:pƯ!و=];7J9x;b0jԽ46^H%"Do#"dN"IhV3P9sM0Y=A@=S_v&RguX@qHkđ0[N6p[}T#B`&y,rŶJVsz7֨ nNFOz5ܢY|IC5mm DY Bp=i8Qq/c i>ĞиAo, ?|]'Ud,nfŶwͺG w9ʳ!ܑ'Xt\q"$jW[V̏4nKl֮E^?8tZ$۹,Z['=<9+R.ʻR!Īmبm]fշ#"Mxs)MF0e̅(P;ߠCIeyP_<)@A9ni+2x R+@KP R"( Ηlep/j~?n34ЛI?:ΨYu!C;5_o5I']4mC0 ΅Jf)Gp:+ z0SËF '=5kӚ󐚆/^)S+r2m?>ެn."9t2^d24j s"y"gr ^*Sَ[r3lU& tꡣZ_+||KV;)}0>z} zj?ʿo\wsa |Q>><<+w^^˥6ps]F>M9re+I;(> pӾh]l|.H߿d' 4!;'^Qw O PKSF2J'taurus/external/qt/QtWebKit/__init__.pyXR#9g솉3ifB*E%J*%UI}KSR)o.ϟ ~>e;P*sB-q:{ 8~/`7B}@2ɬ=Ͱj'2 ?8~7&9>aَ`s,㕳sUnN^̯SM^@)*K^Xp26V~l mUnet X&~^;_{%Ôdm 1 xV+gQVopy튁nk?7)զd(cLgE1-uiAhYY@ˊ+su}!DuB#LeBPgNǵᝐ€M),+h7{\CŒhAxBc~>W=īsMP: oZ7_@؞FC:W; 2B>iMnQ#aB%AχzP`$]!AZgA "uëC0Ը7ߦ|`&W'`f 7 *l86U袐FK*qK;k Wv0? 0ءmfDE9+X4[aJ8Q@Do~o+אaoZڧI]P)ī2cGF USAaDyzfu]2>fH^YQZFjQX46l4UR~ˡEbfe{ k7 zJw z]h~v./脧4i4a ]*^Y&&ylm %p 6W6Wts{/V9oa=adZ OHJu%H H; UPRv1uHSHDnmgĄ4Y"FntCh ;[\Lj7(7jIvQdʮ[M_e&ہR3n|ʰ[;4p526uv3--4 S9䰗as6aA:NQtz9H/Zx CӁ"iu.7< PKSFJ֥-"taurus/external/qt/uic/__init__.pyeͱ 0=O-HߠN"!i=LrrA|{E4}ߟIĉR\@b[VVT LBJ*##%WC1z|k;OV |k@j".P{Q{8b$%OO y;-R 800bl|eAOAwBj3:EeeLKcZZR!\ $ Kw{7Y 433{`WTPlEsU߉Nf|`_?)^2gQU C]gϪT?QNgQwwH'Ѽ+@9Q$i{دUuKLZuxpᄯp4.ϲJns^b~+3E.g얯EˎjAԿ|(V7W,.!:O)@Uy, mF3j{@םל>כ`?xT & -m`{ PKSFw" $taurus/external/qt/QtSvg/__init__.pyUr0+lw<"!/NhI [[#ɤ}%#e{KW[ul[rl"Z7epʤBY&)mgUci 6:\_V!_4%jW,$:?.Q`sʈ9J~F*ˠbV K9&ʯyIX 5<ҒmDgqUF{|j@c˴\ w߉/ÏcC !5ڸmboL!~w)$?V\9z92 L k (rKb&Z]#~ [5ѣ} ì:bG3X%aPu=N{TIclݦDr/A}%I),?D{ϬjAq;#ON4CAuQhpD!Q@2aVH |8P cGqM|ly;:"B=rqX5zh[fxbqZPD )ž;[Z+ѥ[o/To0PK4ֆYRIemoПTy[GD=ʖYz"J̪?LshQJEwNS3 ylՖ s,KcN7_Ҽ &гn||%-@y39@jZze]RNso PKSF~w r_$taurus/external/qt/QtGui/__init__.py}YsF{ =>L<6b]3Ȓi-ɿ~+:c[rbfά<븯v/lyjhj|wTjYnw,c 7@[~SΞzym{ȫ"kj{cVgy/1WYa`qr׶U9v痃jjP/]Sg(}r=[U}vك]wVE4{y-m5ؠZ5mZ. c^k^̠OX~PWiCYkX֛Cm п?:Qc՘綰*Ѡ@W/M .xރBш56&r~bIoDmUiN[%_Jv^f:V_,V+s>V0N|xzYx Zm/r*"62+7:5q>p`vuSզhOP8Ramf}nb!>*Iy\d$\IEObq]EuP*=3xKl0M^[ D!Hq5bHW_Ȓh,RZ*1{ulJkEkeG0\؁J}7d>J=?W59 hAxy]a z*0#}DJEM\`cY4e;d-{UmT[/ţ̥`&i6M |k=~d f]߯އuUf;LdV?g?49zU eRh9CIi&sx*}̴bI5h(:ˉ{Q/W^Wvġ׽mВ #uxikV4 5i_:UB;eK9Ae6'("ϸQ%8`_h^|gE0 77bIMXM]ŜGZ_oү55PmCGonGg>VO@7qnko>;P=M+dQ9V!UCuj/|rDS%6z`q!jXX%goJ0TVl1xo96(KܲKrPi9BBiwi='ƒ G.* 5{oR = ;c#H2]7 燭%?g&{cԛmVFYRE;k&M!!kjrV}b,tDVLUM!*rOgZY D(XM̗݇2+ FS;!9Fh$?>=fms7`UG}z:B>-Y>]2֛9L{gv5"αx{_gwzGϵ.ћr#q)xFuE%8Sr7-Hy8 #ѥ_fhM[|!5h$exBr*GH,L!4q*C?b#st{ǖOL4cK@pٶ/piLХL-YMy CGJLőOγ=ȩ: erR QY]qmh@? GszP,zjl8pFr D.# āH0"lTu"xxG7ñS +nG+%eչObMVڛm- &B s+al ]>ݩ&mв;MvQK f C¨-=F,ɵμn%ilpw{HCQ&gxj{ʖ=3q4҈xi^'hh.nt Lfҥ'>^mHhjc2zDDr񘭧9uq_w3t x4Eocqࣩmmlb  ..NJ6*.ZIoɌ=\HS벟])*se[9[t\^^q/Ўgqp-|X70wY&ђnZiȒ#6la-L$Ec*Nxw%go ϝ#s\^M#K@:靨 ѐ.vZF >o$M:;񬃒w܁[x1o r ?Ù]VΙ/ t9zaL݃~faAsm9#ٴGhۮeZ:u ūm,(P6އ2^6¸,&Q*q4L|ct`KE""bZKCi0kl1^6RpϠ0A.f}b>סOC >Rb uoOvwm"v*uE}2y{8"ohؘ{S\mExBj텉]nN>ѡZUu&wu:)7 s*aHw`JyZp&pKmiyqWsh=se׼,u}抝|SMȊg6_K,Lu}Pj{|?6XZ~.V7ȄYtAS 8b?!1m7E1I8&A'9vJ=̛Zv8'7~ٓzTxIv*^pؚbp\eb8hy$3.M9Fo8D t|AĨ%|OPgrbU}'@Sr=vm7Ug*#M6B9l͞]=v1[ oճo#7c4*c_҅D( Z?ekQWQGwIc!JcX\įQHí.EybE|âO.1w\d_r\l7HfQ:$W, .Iqˡ>+ %[8kv2v+lՃg`y_WOSOqk[#E ;tMTp .$k\WO*#TxVZcŐ[P=<z%ɛFOn\ MG>YWőC@OHEEjL#:lv3gXg2/ {T Aޱ1مȚG>?ֲK(q(RkVL,va~9f'#Y,,㩍!b^KD}O_RЌUE!-{ _UWɸKF%{xh--ĹMd+t(P!Z!g$tgZGL{9lĩ2Tr=_7zUERc 8,Ƙ  t >&oVjσJucEa'3i2[S=zO$ᮮ8!cOf#EΉX~mS(m5v[CvIU q>--2^ē/U 7B&:TP8־E6;=b SIԡ#8t1HDʭ}Ym<"֦\e~{~̂gMI, L݈ˉ~}T՟Pd_%fj0+2'1cG\a':k~Mf m4 |s#ZZxW2WQ"wjjБowu9LzV]\G&spB֣f#ua7Yg.s'i[eE]FYrX+b4Ś06_pZB';(cj@WIGucS2cfمaJ$fP_k7W9#r[>r֖98OANGoS2رfe[Bÿ+ALcc^0\`|bs<ImC <=Fx̺tjDzOl6ُaqMN/3¹ i@Lpmy6L骸xGc;X椾%VٚoH4BQO'e~WHb>R ]X5F#=j{ހwٯ?le\c3I4-7tLyeKGxdB/JGt[}q:mZӋV:[_v@H[-9dJk&2c^I.BH0p VDZR4}>mpgɚy'?E7EKAjU6`GHcu4B+ZK-y`˗APj0죲0d_}`/:ڌB簼knu0- X ,[~{8v7x8U/KW;D{kδiO,!m6Etg*1M\l( ߫ ڝd l2w 2lLzwj vx#62u8P$RPnVwʥC[y'Ɂ,+p݁0~jh荨!!W=~m\T W6𲆀 <ռX L9Lה `b4fK,+Ć(]mJPT3x{n 1w?Nf <ƝXBB`@7<$|m#P*~lߗ1pt:цWjIs3"փfG2#&lB.p7CWDu꿷}MRpb)nf=fqdIWܴ3)d`sԿh $]G5 H68]0(kFWY(0G=(#*CÂG$Wx<ɘ{c.;[|1؋7f` ?oJR7/`IunJg#pش <ܰ Pݚ L/ض{QKl3xu퀝Yp (((bg1߅ xȀ [ɀu`;>v|.v[A`3>f|0`3>oƌ&|0 L`> L`¿ u_Xm𙪨? gjW~:79IGJF>7 gUE-_6ĒrYA*_ZE!= 7D9$/و1 IbJSU7yـ{hlؐ+xTf#MAh] ay~Zqex= >Ugn5ʈ/V !!!!x"!B"o%Bi淾a,sbAKPS1AyCp<!8<l|\|A_F6_gՓWb}iCyڼ_ۡ*1ÃlYAR ʵ*%;vun3)iQB279ήG:pBKr8+۬y1kRpG܃6T[k[Xڴ7P;G(]qoF?k%9ﻔ>^|rQ-6 /*sU?lȻ}Hb}T>Aͧ-gX#Ee]] #nd!|?o7VA|s ;8ap’&~+쇭좲:;?$7^BP3eeTu~ ]j>r.NP%+{%15]N5x|@W-tY 7# i(ʆc9Vfjw @/ ,Z+lZ8|ϳQ-Oy+o&$eLx?n-&֏(.jç$ ,m/rPoK "Kft,XnӒr5Fm8"RQeFyA+4Ɨ:羽Wy}ggomx7Ϗ;BW{0t/+PD/+lz#?8*\g5z^Z(%+7xi/.>Wb]><"Zuu"_`@o;o4fG]-* )b3[1dȍ*vl_gplN/<~O8̀A>|DtFFomY(Coyzu-"h}W 0/ւcxyOO.19C$p+CL @EM]- Bj٘I̒jmIkB ~`iZ\kSvhɠh/*&4tmt|@* zaGG{Y?HZݴZ9=EqUdyȼM1ӣ"cmy ' *lGDl:ez^[SZrT;Ascv    w!c2V!cV2VlZ\UP54tx&6dKcz6>"e_Y<2g?<K|AD73!?jzzRVuHPnA8cU-`DzU&ǔg^ Bn U`XME QOngQ/cWȆ =bWVD z28BW>ο(k: NeE _k#zT  pĉVTzmI*'86x8L0FzM6*=; }}/QFj3%A+|.Xu!ob 6IpH({ q$kvXltpn_H5AGrj'>ܯAEhs~ˈ.ܼ&'E!+['|-Eb+ĥsO1Ffld~K}gm?gzƿ+m߮/!T#G:C0=oAxy]u66L! H"Gh[)sXwA%[lnޫjoJzPx d, M?{ysJFpu_/ݘWUNPs&k\ ѳ^Z Uӎ72*OljG"97 @WPP܈1>|M^WwZAeMP6Ae˔ |y_WmP:ANP:ANȆ|>i^[KA/RKT/a; '(p /pZǂz 1Ǡze*da=-#̿_NԮVpVS> '(x (W~~ET/UoҦ|-l`[>l`[M򠄃=`{>|{><*`>}0A `>oѠ!}0A `> `_=`{>|=`ϿQ{QE,`>X`>XoҢ1}0A `> `f[(FHGãQx1<mG Z$hE ZWho1WOrzjq%cO4xx۪n:Fg&n]C-SegE5.v0b%xE~XgO;hY^UoHeY͐XË*嚀FJGeK?杣mޘȂ&(+ss fߌH;4ŋ ⟔LIqiy1B=Wy=HiS9@ o=$.H >+-w ~'9 hn) ixY2 H<9T'<,L ƵQ7xjgD J3Q8#M)?_<zjϴMg.wSB%jWׯt<)ah%v]a^%v]ah%v&|0 L`>L`͘Ux06| l`>K6<;d64r/.`lgC{Q![B-o!x -%o3^A| /Y^s椪>3CgF1(Ȣi_=.^zc<|~,<ح Ѧ/ٯ>Xӣ:L?}O4KӴOw&}9-Yg, KV@y^9[`4 !buD_Z c l6^ѭfݞ7 $+ׅnм̹=M' d39wx\γdlxO˕f)Zek5{wAgfR*9pNstO[ҟvw|w5|킈#GjgjaTN"af\VOFjv[8Yzԧ:oݦ+q?k[>s#'34,X+~y]apeۚh2/fHF"2G7PМKo#V3]_=ɺ'W|W|W|W|  7B;X-y/f}0Yoz6p.Xʿݽmu^n>x#(ۏj(هi&k`؍Z2L7ekJ5R ~ zQ؋SdW1y.!P6Fk}fr\ wS fV1E7yNOQޛ|bboLsOtʚ}x?,n]S:zmG38!e|[23w&RFA>Q,x|%I0j֣f1`X=jN0Ltywg*d4bǫn-g=N7/c/@Y bE ?Tq_BէٮF.]OTLPBi=i¾!XE>P[Ri G)iY:B;Wu@,G3 THʎz)?ai#ntu1h]Fạؔބvd'AClH^Mg@r5wEc||;x\'Uihsn[WսX5E2dk\`6@<6KS ,ZJ>E;l6{PydAґvl0R:FY:bјt21.-i Ĥh=Z2k WUmNCDm>;8m6§C~ͼ鏋L"KK3'`riS;<8\+S_CH~"gPqQh>-Bص3^hP8,Cէ|6+O5ǯZK]TGG9DsD>v~e m)~;fVu> GzR `sLIC^nkkWkD *L!$VeD1tS& 8],>A-?~v`u~.nξnDk%͊n Wo;G9l g݁҇+Z2i]^wdyAYd[Cޟ.[:hs=$bZD_FסF0#&Q B_UR~!GUWC}[';wON"&7kIYKZ߬eZ_e/OʅD~\HfnrwG{YwhOLGI*(Q]rU3)7I鱫)0xP稼*Iʛzasm8y] d6f?Lb6j0:'a<0iؾUsp^kYYjb<#\f2 !E}B2;'O]$iGK^e\8l8ҶXRvgsߗk ^3^U#~~|/v2jMF _Ht2MGs30#v/ؿm:eAHZ7m .$;X\ɶ.ݘ8o,lZ{7a*maGO J^0X4/8EO+bOuBVdI[c7=%:  Q Q Q{`! `! 5LxGO5;P Kc VYM`6"{uEKvdh}Ks׈uգV=HKq*v MN@cJkKQ ]<]#ΰf$i6=~S9RD8nB 㿘s]3VxM_,:FPTF_YFfZbvo/h(>'%h:O_S)u;ts*u[OoMUñ];w"D.g w1$&w P eWΉJĎ>;ZfF\G!ae7qc9A`@T n3o$s`Z„=-3Q,&2 pT@ ^fx 8҈h5zPz!Pډ5dg$]e-c:].3]?`zOKvE $LYlHP_N/rUn*w/oAUdw EDKȸئxx{lWuGou֠n}}D6Tur>Ձŕx{$b < e;ΜƗ{SXuzID8dum9{Zms>i09ؽꈀL7ŲOx|Z.n,/zV[1|H/Ikj$g#qO-&wAŀwoS O8ܩ] v2DB_ޛI/kAI= 3SF@Y}/`bF#ctQ)}0)g|UWZ~A kTNF0ӥk(-w['K헍Xa?rV;JcQR ,;x3V1򻌜1{A| e,a•,~Ҩlש[(Bt*ѿo*Ko{*enfa0"9,""-bsHi1QXE=J7_ڊ?Ap؏F" cY{c)?e?A??-pp=C!ARu'rht$oqHm+hҺ2>>Ϊa_t<&`>/yV2au%=Վ'u}?ȡqm}^۳OOK YVN~Phե̥HJGj1 =Zo'P6Y\rEQjs&spB7[4W1WUg ezj,MB\^T% 0M^E) B iW=6_q]̓ƛPWR%ސ[{meebKk)ӣ&]v&п Pv8:+-n z8zs}jmslYYPηg'lۇ}8lۇ}`ap>&s;s^{};NXހ~!&|0 .&1ymr> K(`JV'_.tW;͋9s5<3,x((6g%Y!QTtBA؁g"ϲ;e")zw #ΒuBdM嶚Ve.bɥΆjR$̭5\X6c{6iY`OL%3Eu9wvXDWBX ^D )K11#>2Gpg j`35 F @Hq*qGmG)ڱĩ ]냙JhZXj {|M$yN?]$C%D0ݲ#R=S 4?bq`|n@̍+"Xq;fB斮s2^#;W#bIG\/I.܊ٟr鈏2dF-O[u7P#1ItW"d0uݴ& !WaHq=ێS](Jq(RgGQPL`8`pF? F>s8n]>ʀ3\$ <131va\CԬ1G RSq:4VDگ3PwŐXW[iѼC/Qg\Kb'|*Jp)i5IAIAR$ 5" ]夤;"wQҝ'݉ˣtpoO-$tp8n5 J4펩гn/Yw' /_;cCudIDIص$kd8pi>@"U].ޑ+vn=mF,<:\j2wbA{M@#p:eAYt #|ۓ}77n菪n!$m;(< c Cpf9`p |϶KtJbqg^4Rߐ0+4Pv$ڞ%s^mHhjc2zDDr񘭧9uq_w3t x' neʼnsCx-(Op<}`l}Ѽ(i4D)i!h*>u[m0"~6B>ㅋ V a0<_$Hd˶ZIoɌ=\HS벟n2*se[9[tx9,IzQ/wo><\foor-_ˎ,);bfܾDR4q ]wwN|^Rz˙\^!dҫ^M#NԅhHCl#QbCG<$w&88b#޽oL[jB¼pfUD<3c6C qȦ&>Bv].3(bᷨS(lsM:/_Be}(¸,&Q*q4L|ct`KE""bZKCi0k'^*''J6u 2u1-^NmPڧ1Oi>6)AA{Ťln_Tɬ?.yjz'^b z{彩F.Z"ypavsN>ةx&Fb|adE3/Vv&VO:h澉_v=,[AidIb,:{1`\X趛$Nyq J;kJK] !zTE?\E] TI%=(a`!mF![D%z+pYxq'qJzi./|UsVju>ml1J8J:DZny}ԡOu`R+iwpNїH|]=љ+=iƭYChlGMx$U4SUæSx 7s]=[P+9)cX3D/M4zBuʵLh:ɺ-,*V-ʵ,Rc1ձf˝Y>0yQs .4pDTֲK(q(dORkVL,va~9f'#Y,,㩍!b^Kc/Q)hF'B G-̰p RF=j4H't /KK4/PZD}WyI4IrP $ ґ1~Y:_=B}ǻ$v'Qpcmű8gҡdC e/ q=#!Ưo;K:MM=O<<-q~#Nŗ{Cѣ* 4'?Si1dpO]F/^}bn=U&/Kxzh<"֦\e~{ĵgH{൲G$&nDP?b>XP (D2|e1#d0LO,Jy&i36Mq9AǛɻ2p)r9m9@Gk-3I zZ3vq== W[N\\ԅd9ϝ`Al #ueqZcud k|QTT!ӓak3X54_W8t x t@O t@/L7扁ӚI&]iN%.j3c-q.䣤t2~IE^(vrKxiOb7.98# t͝P$v$O'#T3) ɤg▿oYHL"vs >|%Af("a@/4w?-cE~j~+q&@pꓸ2;8 t5$|T'I8~0L 9iv]>Dbvses?.#gmɜ#t)-r; \I2EN`&1Y[1E0*h|w[:5y5&ԓچzx8{uҋel6ُaqMN/3z9>q5{SKgt/H<,s%V)i:;8Q$Nlm|'`2Fz(l'!S&_ӽfh4J[ܽk}^vW6`rPūg l~<+ W!_ְz~(?ֆeǚxC@ݗtO!gzՏ x[(yW `eg"Rށ8S.M1=e9'8QDqBαù@KkIi;1s ᦙ{0ӷX*j?Wø|5Ʈ80k`? Cj;pj?S-UqIaL~'i}'|86p±96 8DZǺs:A 50cf)x (-x`G6I .ʵ  N_UbḷvTcsK߰~u^co//W PsPZk.VdPc>JfM oUVj =1h:Chfjw䰝i 6V?ƚ``? N X#"C50c'X5˪߱セx5˫qB7GbF<j3W--!ȒZ_qwDmC-0럇Yl%,~ryu lo +,~t n[L}#0í  &'o"p/6ve |w:~,=ю_ $,?d צȁKrw:{ʓ,~ @'?fwC C)0 . 04^y߱L 2ziHze|1_̛ae']& ^4~m Kê 毷jY5X5uWy߿~=_2=A̾2N=4ņVaᅅ'[x.<|{բlsYcp#R *+z8xtWښFpX鱩aVӣM8F=,NW_ ^5Vi,]0r'q݄ ?P{9ѽiGY( DQmb9|erb/Uk`4=OKto^} nҽB|zOԫ~]v+iB*hWge>۵YD3 `Uї F[4 LDt*[-Rq`X6v6=[^oW4޿]ioLAp߹4f e\ xiKfʗp( mˎj_L;~iw {HB'nVnK=vI\&UgOk1PNxnCYՊ^kfm:~n0_d(g&s.[C.vT ; z|i`(yOт-lLn<Z'j,edAz]I5f-&`lȮ[Zl #ݬ|Yͭz@i؃JR͚(? @42i4!epgd 뀩yW}Q, )FܢA,'آ|zWEHa2(l8,f=b8Ǧ2*sH(լpXW[b'?lO.,=8 *bCހTBr5ǼMvG[:9cjK32Xqizq^}oNR䥧 )whYKŌ^eRƚ C)7vu*f'ʴM䕱M?њ՘qVͷAsJ;p;mٚ_#6Y-JP#l3ب-LO;U ĆbX>TKvajQ{ն\>j|:] p$o3͓Ұ mG-pGB&$8Q[̨Uq-zd+pǪy0oZئcFX9@&/'CܶFFq<L'u? Z-*ba(]z yov6>KvFك# C&t6;mQ֍<Вez5-^VS_4 W ,v I% MQpH)FlI[d$m Q ȯ1mAqY}z],пG?TȺ_ͦ ,62{fDSD#~}#'S)"I}_5Jq3hX[k$RS@-1Ó@P 80%0|79̚ês΢k&p0_wrK\Ҽ9tⷐ{-pp;.w=|8cMߟׯy[)ՎGNhn $w"?/1F:Jo3_KV281xVs>e5f0?]$8EE 'LT0CdLo& ۑ[c1C]vH)xz:cݫ= t@!1y op U7-]UU SO%+wt}~RB;9]{|eADtd4e%yjJyߋjޘҞsi #qfHw^bO_r@_Wx^{uPkOE@VE*5D׀jH!҇`6fp譹6k(z, wVWX&boZ6 U5 >dP^¼fS㊅%7 x:i9U<|b ]QL*:Ut})L U*TU QtOߛ㣈Qkr|>d(v4ۣ+sFQ Ҭ e%iW:tE ѯ7cY5lpl LsډqEB ԝ-|6KŨC! >ɡsz[oY>%ń>H$fGЊrbr[`t9G&_{7z>cűi"v-sRUl|_o_njSZS ;ͦ׀GgmQ11SsT;ܤɊ(6IWSc5]5<m=2Vq* _r} 0t=y\b(G&[`LJ)D~U?.ʰ4Pw~ 7}$ԣ&I&zգVZ {yNSWr{`UU+Xq{zbqPj SVq22RxXE=M"Jo_3 %Tҡ0+L.AͽlΐaӘ-Lv`A,V%T6ɳ!3cGrumT &^-}}0Q{E)|^9Ëg>U|Cy`e ! 0*` \^% %U@.2oLw!r'W7H%L3yzgӠ"^W&c"l`RE eٲ5ʑ\]䋰uFrB%Q V .#s Ӂ\Y*nRrʌƸda=Bo؊H;i$q8!0y<}1pNlZlk0mMtіq`EdOw<$7Axf4<\D y~/PXեKU.U].#l0_'x@Ʃ삌I 3n[C/LpP{&ɜ+ gCy<) [|VFn>A=ހEaI-1+5E ".K{䕚 ?f:Ǽ$3w]sr̓D*ش=61#FQ8 [7E.{=e{U=&sO5D? _o{":#ۥؒB o*\ǥk;d,%%>(@.G|)Z[ئJ|_1# ;$: 2#nWiە# . Aɦ,wGd ^ ahg.:gM|c˧D0 T6pPS\#IE`n5tv7klɱڦ0dw_Iv@Dȇ}g/0dFl9Ӭe=]r8y}͘@i:C%y PKSF*Q%taurus/external/qt/QtHelp/__init__.pyUKs6W$?ڦ3=ȒZȮ"GvOjKŦՇd0(G"M"!0 B NiNb) 5B=bJ(̐\s]ica!&oZ`c՜6PK3Su&o`SQEo?">K)BZj>h)uu/ 0tty.;^6,cS*4(Hl\p'}`FPvڗ f7!J{' (:7$3H\ I"`/&n<hz@4_ MfŵM;`Ȭlk8jelX,=3il-pV<էk BCb1uQy M$k&95잗<^GųgWs27k25.g:}?[-|>ط+ܛ ,䟝ht̕xf\:No3~R:wA&& )́/H#ޑN} vϙQ>NWyoǏ\̖lʍ}gwy(+1K>V%1Kpxޘ9 PKSFcLO]!taurus/external/qt/Qt/__init__.pyYw8(_{95Noi)3ŇheTsI[X3{f]sʈ@,<TWu?<6/޶H ٢JjmųVxsOۛ旷7b̮g7w{@>ϧ &h69mn>_Ϛ-M凛v(yQr8…,[eꖟxunbosX=h{HfuNXDev"*JxkY^v]xN"E&_fۺ}tYYgE?z,./,n:jBF8?9YNj4f[e'ER%1Ə )X]򺉶{Ȼ4J e|EYv:duUYfQ%YsDQyo;~PD ߿̞ZOE[~Y'YR-w.˽v˛ @>7yWI =a\*>y Wry-!a6kwy˯ɲZ1wdm}7Iu6;4{ilѵ?>gŏ&K\}⊨5)zx (/I_6Q${HV\$ L!?h4f;e@v3yg/O͇ˇ`fp<'M4 3ϠCAaJ!l[reb\`y8?gH"=NrFKAA$Vo?hQe&BE];/QzqWuͪHy!PfEui~p_gB!܊1_25f(DU! w@_G%!f9R&Ĕ).b [8Ӽ@1n+q=(~ 3XSތ}=kUu\pyϓ4>Vpgi]7&Y]TcƯ Q(A jl gAEu>-Khlٲ相*diJ é[[ME Z~y:Ov؇MDsT:mLs\{?,stE Sfǁӗg] Ϊ] |b ?ߣC -xKo xsVpрmSS)MȰtE$J^'2dWKeRįTK"-R!}k}~ĩ27I*?<ʺ^9Ym 6p!^;bUm=°?OL3HJƭ{~PH2,E+mm>o, d/RAb Lq`$y8E :aM &bYQC=՜j"8|:P%KXhSJW`筭?L?;* LPH!7c?Tz*u㟠Mt2٪3(0(^=lbM= z b^ˍ +OxfZE=UQ &JvZC?@󋸔&>Չjl!g" PA-OIEݚ] F\BoOrQ$ըpb{HhÔj&9S\ 3AG䯇*4rv]8r]vs4n"yIY.JrX촉gwp ?#iLrIfN1Y&NҼ4:* Dd>UF_kug50IY?%ɹ|>N3WWqDv5D)S,$ =vrB>uU|h]vˇg2@ۺXC\ 8+JXJw>C= y  7<+Ͱ9{;3GX6Ǔ6F9-Mv߉= ;KAMSxhR޸}'q8hoVa(hotqW0W0fJiPx'*LZ<( `Hc)[OS zD@N„Dl{nTG;eh7/<}v ~Nuxw-~3LɵMyۥy*:~^<<wHg!+ܰ)kN@L#-x{rxl q= B (Q)ExMuF2 G IࢌLY!)(q3C}.KN9{=dyQ-tث@v7 iHQ8爕cXh뗂fa v.W5s- QHqE]$F<$m"C5N DV$D=è UR@8r/1);yHz>Wu84 v4`HU[a8$Uk25 ^)&AK :UbJAQ"?8$9 12N݆ VR'{l?9{t>MrAҎ[J<m8i^g >vy >:rMW)܋jJuL ,.ؘ#e;m6B{ĘydM5 ='Xo_bMԱg8%@;"a\nDx/ 3'Na<֙s{gq!I'_zF<=>q IdX/>`88`eK@ xdN]>(~9v7N>o3Pm¨|WLnJ >hΩ0)Pg=q'ϋ:[0"=笇#v 5ﳙ]BSAF* ~gWwڞ*V#K"/ TuPhL8yP,T`PݧExkc(  './H@u%4W>8=IE|o7GUA'?%mM5~QB6Z7*Q }w`ڍk}s.);{WѬ~dcO,,pQsv8}xc kpI0O%Y\X?ozbCd&>QTsU_ݟľmO9(p{EUNϝ߫N^Q{C-Q{lLimyf{2eF裗MNYR%Tb<kzBÕ^N \LBNǣHG&?hӌ8B~gβExGтBdEuxɃODxqXߋqGFzxKS7OPP 6g _;07G<ɿi7l~\W _X9+y2 oڨRFd}.lr;D+ZwMFz=Det'q.4"G;3.8:FZ7a /q\wք\$7S Ll^A5vfC5pt -umcNM-46҉8ta !u 2^ B; Pa[H(䯐!jҀ=x2:sYΫFUċ#?O ?M4џ&DOi?M4&4QdK>by[*V Uox[*x7VtXu^z|Q~t}DN4krk\ok[(i/.=wM泤,)峤,)>K`Oy.QõI<)JuGkū8[q`ŏ|M5*#2:zB&D y)آ,Y m%trۺƔ3"fr>;)yF[Cu 4Zt-|fzR@zevr)t4װ"ؓ q1|ڂm9ncG`Qְm0ԯ'ŲB6M$6G&WY)kWu#}&j8i10t0Mj eE@, m2`+۱ w~k[ ¡ovۼŻ/!Ew;[2eHs/O=[c2'6L+WCdu ô&(С|% 40EΛRGx4emp)FNwQ]<ȥ;'WAIۙ:pK8n]:QSe1. |\7p0vP -9@/_`46[닝HG]H>’NZ"kh &-=:lp3ʑ\}?m^%[w64.נ>z8!#YPrl^ 'k0U^|^ܸ2t Nsw =C$&R $5U(?f=ŕ =a,8CyLn-5= 1jXy;|eplreR? h0ۢ $dD7X +܅( 4xtIȍh:[1S]l|XҜ8k/w,P3QEp?+1JSٍ5`˜\wc‘ؓg6HK-Nn T`. ]е.FwAY]Ce<P<7it-ڤ" X=[v* 00 Hf- A07nFso8xpjN-B+Y\,D]Z`u̔oA%MddQfN!}wHnN=N;-E9Э`ΣoQ=#h/h`nrď4nY+;41nacf5#1ϤtКU`6,8,Yd5j/Jloaj_G]U=e*|1ntl*觇oСOeR,WUQif̰kiQ_w”nQhj+:lsvypQeˣ 8y#j6n"f%;(u"M6˷To*3>Ng 3f_ha)JW܆.[AL`?=ƙ ï\ ' L׭㝠 ސ6#-l':>Fߨ[;v=i 7q+֯P#mjfޢpVWD~]60ހ~n(jôs *cq] !j[j֏gRMlP׵ 0i>b+tB9hb\밉j3qu(R$'p.j_\gQc)U]J=z`m k!Sdjc[4گÃS (>WUоFe ezaTix /m$ӧFB+mk_h Y>/7 ֋TjRIvBC YÛ=aYX9]hO{$(ebq ^! f!8K6$s߫*ۈ*h AШ5#L aP#xUC}#$], C?g&8lW>ƻ&`ˬr%|'Eu˂(XNM}РU,Wʓ/ɞ[u0NJ0tpI{&QJX>HLX47pk![%aEc ;eK7@5|E6gNh̕@`=mV-I:-uAGf6o GܐnRIs VVN$8p5:6*Ir-F zl|㉃? ]X{\θHOQړS,Lv'ґI%%}{9hIB=q?=5UOI8'mOZgķ@8P~6顐}X딏I7X6҈Y*yh^xR'Xi]'ٍ־NKav{\α+1_ sr!)Czinm<[ĭGx0^:"-ĵ2A3+FzK7`R Ϣ<7q:9LUa;9аū>Qu/߭5_FX5ꝴ6i 0[)Gi =pwרq\pZx@w7ypwlY Q'ΰ=fFFgAqh2(L6܉;u<)c8H鿻+|zP%pڪu3 5~ P12=t0 sKLSPḍyh 9](hek%~{~(]V^Yvz ݰ˱~C,c % DVیNZ;V'1xY]}d\5Y L4y| 9FB{P yDfca=A'2fgZrvp@6p fcp.Y.4mlEel@bx3Q S,eCo td>3u_* οab/| t@/ t@o7Dbr6+UVrx؆_fOhF:'~QyMCΪOmc̀N34wA=2vl񸅳g?{Nφ-󳁋b26 Mu]^RHH\bXa5*$} }F8h!;'*A`Bx: &uH8lbg&r$P4&& vYU=1uϥ_0mS[V^<;e8ně63Zy_q̌aaӆj ,9}}xacՎC4h#GN 31jS[6`:1܏0 &Uc|?9)d7nVm֞3sYNo+:oA p4xdl6KS_NyG`< 0JmQ`ykS[^I^bl3F=qe$ **%~Im@邧tZ!3 zC-ė H)[Yªb-qF eG?V5k9bO_׊ Cрx=Zi-Yf1> g>}Og>E9Lj޴"'}RPOuIV{%ZM.GBus2aUHi@{qi~tLp8ؗˆJDIe6[iTEhbEWst&&]$5G T {/>U=wpG@{{TЧ0B>G-Ra -=Q4RK *MзtW 'LƀлL4-rg4l}N>齹g5.r|V?nʯR ܶ:ҝ!Ԝ@ȖQglcmfT871҃NSq*/]JRqB49|Hu}.D^Fk|!IV>4ha&j2ĠͬMS)abbb]@nxyn/2[hőhu zvZOT೸@eAV{q<)/>!ȁ zQo(su\XHTq?$حG[ h:18Ѥ=#,|R$J 81M -ؠ* `7-ίN [0دHJgRЁB=y.>d- ,˄2Č43o@smw8B0y  ¡[*t,AJ=ټo2UEM'SrR=}!8'IH:B6Y?ʹ?w$禗3Wg~Ԏhai={T񁡴ĸyηaUD9Η3 9~T)CSL΄]HL\܋gd_oڐkx*%B, +'Ԣ|CI/XqI>2@T>*vᎬ&)+S &'0M p/JPzE\Vf> nfxOOnܧNʒ"rH^1\ щ^hy`~^`I0ϯ5h1Ņ}Cҙ֏w"`WP&&ˇ,`>f +H%ǨZ9^2>@otD 4>A1 KP\[. s sqg{U=HJnG4t]0N FR9xSsij FF={psվ(Xrv]` y~l?^_+רeWftNGhOun  !0||$@%Ȉs{=^z{=IGjWx{5ޫ^?jW~|Ux{ޫ^*W Ux{ݨ]ZNuz{^:NuӟE%֑ $/aDA&jdE?{]2Wy\($. ["MsT`kMd߿(336z .L'v>C5,2Ĝ  iiRF1 K05IhrD(5.$%,bcUR: 1O%]Nd螽b"KF1=դ0d$3k%@yU"{n^]=IR}n|$MmYe)٤Xx2h; m\)IQZԬ$OY~k]S̸adU s=VY@ɕ,ҝ]sW"ܙ`Iz?^j󼒱ل8 ک),y3,@cON0UIoo&_P3q%|"wIOʙUj}ۢ=5{!78-9#JS\#GnB6́ 05`.馃f\zb=̠Qe[!JqR2^'wz+MEQg _$ _UxAʯnCq:54 xx;h]>gv\~G7o䞦ʐ|=%YFEᒤb'io((v0u3KHP3_IYKTTv|l]`2m]2Eo@Y&#ю9cN~ q.DۤRbt(ϖqr.sj29cȋHeyHQnL&תoCuGY;%\W",ކ6&_ٕ.4$W0Ϫ!GYD$G,u\x5^tyDL,X |A}0Lf}֐~ThK Rsa d-ߒ74U~zO8tۊsvmO?QclFH2EY9I:::r.L_\eHȚv%Bk ĬW_!iZyw(J t7|N[L@Pls~ʪ~ Ǽu P6 fU-VGu&&p Ǹ%XQ=dOAuH7#EUyw!ж:й9*gqP#w/u|Ce3 3Z+|_w`̗,%]k ,h) 4R#(NQB pT@L'"IyGe**ۇ8 lLهMŎuT?L_"؁1 I2,kVBI~|O|\Etc-*ѧmav/a׻(еQr<ݮT"g #L䌼3{[slov|Dl 퉉=HLgmцbJ;[`e@svH x\-&8a_ 26i仑Vdg{ۖ*qVCA?S; ;0:c񝣲tP|ј49iU(p̧̩h*`2vG v{Sʺ@% ' (یWf3"0Ɏ%<2`.+M)0 &h #WU^ZlywZu6JBۦK\1Fʃ9. "GROn:{$eQ!@\zqԮwWuDmw2_L #צּ9?`̟s09?`LTx2C]Hwt1kn%4Kb;G0h˵s6bOX8d ~u '|Y+ȷ8Ӛ$v:Uo>Aj2\ζEU{Y|) Ƒ1c <#O`Ie `iߛZoeqZgOO.Gk! BfΌ[tB@abiX2qͅGU!B(4|BtoFȹWVߘ O pbpD)e|Yś`'9t0PV`<=eS9k눷 9Q$I]_* § h?i/hky\f cjJqeQ& o~A6c'84t㞖JXeJo{zI%j6~Y s|;d ,00#=~bDRY"y/xEG%x.coFGXQb'jD4&7Ti'Ȉ-Dgϫb>3 psDcP/CٲfCo⪐!?54 Z~g6Q,*&woAoLOad>Oass8ry293|L3ϙ3-Q{߫^W<^:ߥNuy{]^.uy{]](>y{}^>yϿO}WBz{+^y+^ {TiʽBz{+^ WBzпS>y{}^>w6F5z{k^?F.5z{+^ WB{+NO64Fm4?(?6G?h"^x)⥈"^RD䇯~I◎lfgBMЀ''|& G6/*c«Ta](̂N)ԣuYQV%QD%|AC<rn tV>Cы#*$f;uuqdfWJJd03 ..A.^ rs ~-"7cPպ? 754G [x4|nSMԙ)R4bv>JJޑؙ1.l)AE)uz鬄 ԘmbhsHީ:{&R EUZq[`lf^7ͼnuuD,N㧨N+`YeUȱRQ+  t&z#([J#v $h8-(lBw)Q{;R[t..`Z㼪r[s:E*~ ?HsD(9,m9Ewۜ8# +JQ-j[}ӺG>B]5rvzm9q/`xа@)ހ|OV5X(̃_̀b130tx39$b ,ϱ(߱ПX7 ~T5q3YVE,Ohu5L6@T&qsq,J씏Ų ))HJƭ+!MZXx"+_6;t Lװwd͙߷HDs[HeLH j,9T` 4--HAsWc'G]\83j`w@F ӊM _:2>)?ΰ)sX@-VE\-֦%D}Q=%D}Q)JW Ux{ޫ^*W U—U^3]_Vj ۦrv79oxs79́[ѡgFtWPh-`B,~-77|E-xfcxA-.BHK҂ m}zYãznHJ6ox#1ވF7b㍘ox#1ƈer{fLG/a-JR$.dV^&r %,9p7yNױ?B /k٫?Jh_)lWW:2~Sa-J|:r`r5;y!@h0!kA4Y&B٦˜T^Z ̆QX6NU@oA_=b#; ۋ([qѕ%FuM$̊"_;7[heM+.f$2Q+I6Hf2[I^Rt#p^ RHR$PY:{$W?-ӅзR`(:YQ8DާQ)xH9_2 T[;/Z)OøPi+eR{{Pȋ|&Q]-xsؖ_HڛK{X-{n_H4{2>kWIIc``>lQ|yϗ|yϗ|yϗ|yׁ|yϗ|ϗe^?_z{ޫVk^#Z}i>fCo^wU-od<및Y\Hxtis:o byGAft65}txii׏?A#6(Ec<):ُ$W;qw%{@Z6Hǁ sD:mMiVҶ`kew Moh##o[zۖƤ7@T Ik@Nvy?tS#R%*d۝h@'>`)>I6y,kNdCJ a"Hk{)8w=o]<@ D}bU-}@vvr Z2 JBO+0=y3 w<\M)hfR"i Jfiph7,)߀jazYBe6iFa=~KEqg#l#87Ҙ\FEɔ_PrìXᓍeX2GXM3h g4Ʒ'z5?IE:ɶe>~Nf6" GAR="d65Ēi۴CfaOLP!Ql8h{Fal4lc:!.)Bf|N60R!-W>ͥyKl&\*zr7'lGw_l-<.BJM2,wd732@ݨp*?]D'ۣHh}OO7n󘧥1t- Ҿ12Qd\)Hʹ)dQDG""7Ia"[C~ni(SD n fBF$״5v$nV"X,glw |a:E~a_t*qg߼ӺHM=DŇ"Z&9UqZAwSW|UųڴS\PxcIVtٶR__BO{iEmȂBϕs*>g|)'ڵѬ߅OAا qk˂pb>OB?吽3ҿߌZdm 'θ?ЄbK?֍a0=/r/r@CR>wu[9zi\z菞92%՚Y<3W$Q\TIL U:"g6PkehGکl#EiwUj(IJEYE"vD'^Fq@w uL Ȍ\Dԥ)t4J%:E\:fo'n*_"Ƴ>4i!4G`Nbr}I)nq1C^.!]O|I Їep:<.,NNq(%#~\H)gfu8t h^@GOHw;g t4/kclqD0etyLK\,IT`2]3tℭ Yx 'mv:u^E>2M7 [IзgV(D /D6c<]vDj!kC ?+Eþ40dzPh@mXe8GP:<70R|A_bT͟m#n8)ydJ'9{潴-N=)0sX6ӤܦN_O~P\+>S ~9*bg4AcZ'G]>,Cy3`t $5q"_ =Cz$yx)tѾu2qj>y>HP q,012R sԵ2+.L1 .Owi[u<Ű*( ̘T yF_$PoHsBQ44"aS.eK'ǿ(9AP3@r)4%s]lP ݃& (ꈶuqPwqsC⇁)jPF=(C+<%ʏ? ׉ԧLXxx%k⋨. 㾈^DvEK<\`;Ԣ!GH&u.HϣhE(>~"/̈xZaacXv }rEK J"-_ \_}h\'yD7_@g`'TJ/ZbD/7-˯|usg;դ|%/cZc Ư~1UWucɎ!nMB0oZ%~$cXϓzG]!1d"GFo*l<a gQiT@HVc+"Pj$?n4k3ZoWJc [/Q.73"zL{*☨ eeeP8 ̽jNŠTQAlgu|1Mwu oW$b* x$|AHkX6^KA <W g ۫ZBDpԸ{i—@j~ƺ5f`/uAUCc#u rB)^ګ Tchaìrk@6q\UL+gl~HH/lJq2L \]A 6I7)@#u(J|Jj1X4KĢ@Xy#kPat9@Iͭvy^zj! ȑ-аUk dQX#20  \"nBm$ 5ְێ=QT@eyaߢ;䯓S: 1uHlDװ!7L*ogAR cb(ȋQ[n;"5&}Q_KD!j4^9`/'X܈?KD&~̮X󭴛d1}$۩$M*7yƂff?"}M*Pg0ă.PYO%@LXbf 8&flĕn`s7UvHX(r|+<&>#a-E7=T!ph#>Og+TJo|.H;r>7^IEm˄yh>3Á)֔ZߗrHY /qAffX-}qAL:C2$o٢d 3l,AAv M[٦r#\F  GTݒ}a}=yaY#S\ 2 \5M=یV,gU'3{X"%;B(l0qN ̲VwVddkkV?I.יfU_Tw~Hר[|TW}NjYv(G)b/ゞ"kWBAT&(}dw_pÂ"O:'5V[#L/#)0:)Kk;X+&;Q]Hvqe6-MC=sӜ 2`7F[CEN_"T~-K*nA ײFElEhF+iMy\fu6G_ :DTs0D ZK%+ަza){p szscC:j'[sEB6g7.ka(*)l?F+{f7/s6-eus&R"Vñ- (iٰ~^ 8Q1?#J/;?'ڡNCSn'w*^"mٌfG`K J2\u^-~&s$2$sQJcKh$ [d~:'1QvT;E_~2Rp/I\ݐ]- C93g Uq[spfr> $y]ծ] h_/BJMŚCg]ZM|Z[voR s= o*ə5~QH/Q %7F&MJj%0N;ʡdj&Q%$Sro$efU( bfgQl: rF )ʊ@ϙbh%#pJ6Mk7LxB ja8MqcOVIRVi?1r3m6 et"s&7?bW>^0r$IAA0NdBO>PPA A2ւlՏaHZ5*2~ ollٔ\w2@:2⒮WNϮZgYE|: F HRh,.N2#[ gZ; $QnjV]׭mL%'acod ?P'r%Ӝ1)ġ.Wm(/qR !?ȄE͡c*T3g\\w=8ߩ\3L}Yw'L?aҞ|A0I|='D# uIT/S>$3zrn͎3b x'IfؓOwĢ]HGsrIaKn'Ow܄|Qp:)'} P >Vgtf"E!O#Рnab!>qvelR;3&I(@Wq44(%{@ ӓSO >ÿЙ/S\DV]$syAxړs 0!k|Ȭ32! wir |DggCkζBD×Ok>O}}zm^׶:O$ئ"^}{}}{}Ft ˥rzśܼpWu&_V,ԢCϺ?9-@Kin9h vB24E-ﴅ gqUoO SNˬڛ鵛?ON+!Hf?hxet J eUtGc((ݮ4e5;*3aTO\8XJUghVs|ObCUhD6-~uY*=q}#6x6Ap[$,< FRl0;6gFcjNyboR=`J,/(p,ӿ"(̛ypOǜ4/Hnz9)T ZIvЕ^.{6XvDE+Õ*.&a ' SKPɋBt?+bgJp`eAL^~2g\ۘZ9t,((­7dr(߸8˪q4w<+8 #4sRS:.nuS-¡U^H/#_`2s";MW{{zkvkvkv=^y] |˙@Z~@Zá.LF reDViT`܅lSz3hGW Star,z\Q qئ;=PaW>$vBӤTϫd܈7RP ^K9ҡZ>2R'<1U%yG$%+ Dh1A6_c$dO-HthνtƻDu7a/31Uٶ 0P[;a>KH>PޭR=fl+Buӽo.RI`IY7qch`x7y9%;ǻ,չ ڮh|G=fs s 3҇O߯Miߖ&Gs|]fa3 ?O#}c.'+`D>'˝(#?*:>T)p2:SzS"Z%dSwaI3G SoOWgʇ8rR_\гen5$vd*!1б@GkR p}|IטWQgEa#ƋZC'DȧXbh79Tjpzt4K~eKMnƩĊU|H=~3&>vO yO$XKbb̬ЁnJ ri]+2g"Lkh_|jWs(ucX^/rQ+&$񚍰܋,}Q%gr 'Ny@Ihrl/"*gq`"s|[|`&'] 6nMi_%~3F>&2^OuhH* -n;}uz=@ 몶"R%+e^ϋ:[I+gjmsdI2 *@ [R٦#ҭB3&??|>yR`󜧠7ymg]at, F̗:NؖѺSӸ[ w=]w=]@zz>O%5!63ߜ٢Ӵh8spnrN &?Zdt,1X:Ԭ-؜>eL Jӎ ؖ Z J |FiDI&Б~ὖP h~`S}AOڿn /YASTTG%{|j 2x#(923VSXI^'ܳ@>|Ua,?"ɵ".˚-rjx{)a\ zwgIY ۹Ǧ xc7yu.T'r$qez\4#oST@@@@<@D*W Ux{ޫ^?*W nTxkطCO?/kcp.}|Euٗ u%R"Ρh ot>OApv!yAh'bNEkkḃ:'#ֳt&kI[ -(a3q[.^ +e|󧂺}g3z_|30חαu %^fn%/x&0,ݓٮ|Y.,uF_)2Od[4g^1٭NBlKܮ09 H4&Z~G%<)LaPN<3N,I gS# \M' p@CqCg돣/CR ԃh<&ϚGQKʍ6hl`P[`y^ q2?rqB ;c4ŀ#;g3wQl=$x2 P帋K]4{.ڥ,TGr@2pW! c:cM>Hj'].`Bj@̍eEC?xa3dȔ Z0pgkH@c',&+W"![Dq7&Q:Z2bQ;H%ȎxGSںp8Y#;(L`Xo8O<@)onhlfpl-L2`;I,))'!vb>AeJгj ͺp@hɇZ>pޮuX& .l^KfVy8WEm?dҞH[VT$&@b'^2VpNV_8|brԤ;2O G3Jm 9?tҝ>;g;wCin/Y|qBwmBalܑ&MwMb[cW]#keb F]TuS! NGoȾxSp1/ "&,JUuoTyXb^ىM6~u~<8N>EN=cqsZ7o%DE&CvAPp%|"`pK yu#ȝy]KrH9 ;Qq JGþ?$@w|ܣ@9? ^-#H=Ev(S:AآpIˌedkXûŏ"%bdy{qPUOQE)8vOB\,(d~~ayv{L;OeUMGiEm"*:Mm P`CBbst17? Ώxʕ^*f6ґR)z戳"{x$a<%3I$$yKFAܸ+ yOzt&1xxa#!],D#Mgm[g;k &my #z5ʔt|b?Cr3bN͍ Y<7bc[]^=7M,|ʊsD#C7y=.+;(X'r,fTgCZ9]LϸެwQ88Kg&l):]e+bQ)^?zg[0k!wtJ .| _%ӵ2BM& p `4 /Q]b4D5:<7?p;OOXTKXgU>ӷIGC0X$'E^̓P0jz]TiwdN#aj&mKmh1yG:1 ?=`τe ݸFg{'¼7u{.ƤMo9 |Ju 8l,bCyDSG\&܈ꥃEȅxbyrwĖdQF{jd=#n6(Tܐv`r;hʶ[귺7]\Ȱ^d$"3E.ַkX;ln6sI"YLH<,B~f,:LvL}Rgjt*mؠQn$`AwԂ{ :K]48u(ƉƷ/$M=*څ& qz,'s=!fة{v0>߭{R$SmwDm[/ v!͊ug0yT wJ_e񀉳M J "pW1!g*WB|s $ n!z'SpYQ 1q0s^dɷͥiyΓ8% ULI* %Bh>S9C_?8u'g|<~%*,|]?87iִ"JaEc ;'nt%t$5r>O"=T~bȝk/7 %܄UK0,mqPsAE:qd*Y2 EYRH Ue2) JL 9=w}ڟ7Mb)F&]ļZ9OoPpN9IR@w9g&NX97B(!,피uGݠUj 喨^ Mm/Kf{7LQ")}3{E$X:?b#:$i09I3@:7#[ 伹vF#JSr8}Pް՗l;W$'Ojq9dT 5[lOuYS|83ν#?,:oso\#;Ṃ[zD0M1^ 'dz>̣@*ʼn+n 6ȑLẀO:6SN B]1O `L2"DL[v =,@-@1Y~V}奤4;~ɨ-ơesH7ߍŘ5;sՎ yd2=c[?y-(.in= BϷuQ6v.fY 3uѿ.cE~Ώ8#L:={;(=15`/M(Du6 BN MozXT<1{ Jg:6SnG޵%uSӍhh3tdgBcf1i[JGzdh0AF.vEi֪gcDM|y1.v!NC2CqdbjU`s qab Ğ%J]}fz.8R?X4y-d4JSS%d6/K_&ȼ0I4tC?)Tȿ}fh8'b'hX贀bm''&؍x^H+ﳦ*) Ȫjks}?ֆuǚ}q]w!gSS\6(bqܹyAy\sFXDzOpJ*"38&`LFi=qis+ᦩ\P2u胹!*Pc^NLd!*m ~q}Ru{B9Iݓ» Ou cR3,;qdk_-N*1}XzZi7(zrk]>'? UԞR~bz"t7b{!_#&=ǣdڹV:B jO? JS'!dz$=dB1t)"9.i.p e,-rgk.;ƘC\k~ۯcAj=j^cӯ//=9(q UTIɱ[3|aد~gl+8%w"- ͑_T߰mױz*a:HC{~xzJ)XaE'ԞP@wO=XRŞV{Z .\So3zyǝ[m_yr_a1~m@j[zv~E|⠧g~Gط!ֽn6HdJ{ͥ_b^xk֯]a{䆭UZmifo#! 'ԞP#9C> 7<쇧'tn7-ގޯ/~_*.olQlNd R~L{wV׿" j,@' BުpL*٧HjȜ |)/3~L 2aj/=WުIgդ߰juWYz:>en|R]i[xw/1FR Q<;8VvښV^RGYCIpv_.q@PL€|%& ^SrkǼɫ}CHi${ fsx_IC7ك>wXc֭h_zN=ڃ*1Y\VцymGSNvo߰0n߰2S׋_n}l^: (B|S,_yB\gn1Suֺx7~{1q> d Ŕ{E/ݒӽ%];f+-ԓv>:.Lw Yꪮ7W|MV F f\=)'Dr uDt掶6@Jaxa_!{.OfOC(AYUcR"L>z5vFYLS^M(D#4LlHko_6n,'/>rNǩw"+ 9 ж4/grm_&V o& #GH]qPzS(B J˯!_E䝈 _Bk"^.v"eŰ|Q&B8)v^~OPнU!?S٩j9T,_b^@9;_0pLh>B;5?4S:t+Cg$e'+|X2'ሟN-Zs̏$/xD*61 Ԡ`v4 Ѷ~_vdU$8N:itI ֤0ౣK< ؈$a!*~L捦ա> rӳK/EN룼Ew=AӼDUqr5)2pl]P3L}2WntO/t,f>2%l· Gyf__.Oj#vK&a&i'_T WuY %fYeeM{3ymg7gzQ6QН$R[uЃ66?N.N2ZD1 %XJhXKŕqB򗞂PjǢ<|x6cт'%dN 8@5 qD[H3|4D1 d;%}8S L 3!t&w_*N(ESr~|Wy8;h-`<2xz3x%v?t1;pB {ڤơ uhT2QBΨ ڑ6_:oi+#4cN)M}5tAݴHznj[`^^ Nn;VpokAa"E+e LKׇI t?ۜ y%݋awMÌڍ[Zшw}ܮGY0+a2R4°hHj#:qt_ZȐu^Ci$73vb*j@v9#"/T7}5C1]fTߺE$*gm濄ҔIc܀\}%Hb0_y EW,Eu¼ZV=[֚ἣx-<ە9=OHPc<[<: v2jUA5,aܶ)HE4;dVȅ9XN}.VN†F"L)ӉBg'Dl&˔)&$@٨讷G<# 2#d=0+g h)U.#d Cr˪{@Zmypi\!N]Ce#Bc< ZgV;!PS6PUCׂgɿ'+ս4Tד&U*Z_>`Օ]5/uY5QJxMiVZ0iyar5/7T>`rQ86Y)"6aYR:*mjW yT?K_P{q#M9M-ȇPW,]bNWH4T@+,@9#̩ꂦ]mEi([LI!FV-ܮi,SBΪԀwh -Ma5p(͉`n굅 otZicѦ-͓」m{RHG ؃b,cN2pݘ 79H ٺ勧A-Wf7puvtJ J`?r`J߁vBQ@(ydbGsG\{0 d`,m7L2SR wV-Oi'>9%NyuS24^qK'@*uf:1a)) #gvh |g`{Sl T;Ga{|*X?GQ/O A[jS*[.'']PLgv@mY",pϧ#\Z81e6k( X!q l#rw wlRvv8eamK<0㩔خA? 5]jB.:È>@>M0D 2ˇ1z |$9{i>gm IѲ ia"&JOo} 4H{QnH<졵s%.CtEuXX˱E&jW8 P C}SY4-ΰΡbwj:VhuDa)J@k$шY53Ҟ`LX2PJ* }0Z;8Y ޻bVaqh7啒lhYEa\QP#9-%A֠SMsLiT[{7Nb V0G6 -2C{C~֫zP ceDb n6Ș iFxΚ:t9U.shycrYmfE=Gs8. nDj[ "^ށqþ[ξw9υkW5X>Q^B6aBjQnhNXu;^b3g6+0]6G;J s!Km]!nƀHN(m^FB]@_6H 9larX]c\Ǯ՝nrƊ*OD*]\WOIԭúi Q̍i93EZU|,S27WY1E/\.70 O'bt$R%KKRvJo)=(~;NMd3h?^Yw;{_*xd婛ܫp2(o7 8[yݣbl 1A0:7 PrH.zv ~Kw,)<Ȉo`E5rwqGc%Gً*1D r [mNρ2[sOyְBtRԇʵ/GAyrVD)a;(K8"p#*+yyԽ]4Jx"4/4PtT+uk*AiZQ=37)皲" uYgJ*_f7pLh>BZ/?ji 䕳7@_tUWuե,$A?ie8k̏j &ou61 ̭4  9η GUѡKYrl- ijp%=,ܦg|2z6 taO8EUޘS hXaB59 PW4&/vΣ7טc=g=e.{vMr#3^*kP!3)a}uh:.gl& 5cd\^#GE+'x#\bL r = M9:\ @s_D3bj8A?gɷKNְXA9k~N||~4cڶrm")R<`q-lT|1 OF4]jD/Mo%AɈ9];$BGdƌ!d>0:[3иQEeIo%O,ܚ)N >2X3wsƀ9Բ{+<_evԶq^N_)^CV/\KfKW돫jqZ\??W믧YNa{{{{:|:F^  2n~\>}@g2516~桨V!=q=p}B٭Zx"D:58hx!.Wن)ڍYݩ׏l"BMޤMޤMޤMޤ|ӛIٛ77KՓmyS̻`TWp%2#*O& VwYV5C]:Ze 1mHeHȹS?i67H;4~.WB|o5t@J 75ël}$`O`-cs٘PY>Nrשhacl=PH{B,j^UȖ[0샳ڳ |0U:xumLس_E&̸sbVJVxrXf7Ec酃7uixx~9rz6uz iJWG || &$Q"#Z(@| 5i漃`?=vb2itqȄ|#G*yG*XaKzH`#o=l"32@ZWzSq]?$/Ec*m|,.3$4rʜIt?z3r%:3F]K `F<V`P F5L@_r@7i='l1θyK :WbqéU!) 'BlxSj ,I`5+Rn 0څ}pܦcKl3~M]QI~Cx| l1J!iA`v&8XbX p&_;X.OOhX&I:zE;&D3iC^fҝrg`EDd& ^9m3t&EuT!?6368PyH%f.GgV|`%hfPn%{Tdm]$ JB#&1۵L7)m7uM^|BWO_$$ͪltHJȀ E!X|-cץGaV.%ryLz OƣC5qEA`H'fi<_SY‰ԲʹxĂh!' ˼AX' ht n,k4^#?lL1II<& 1nj q |"Pp6a : ]} !<[a`e#9Sha* GqlmqP&d^Yaԕd8/ ::WŧYlR`UDR}7OzAwi{PJ:o~UQPD"q"@KϏoNA<2gǁEnu*:`ѩv{7,>z6MP)8֌?ipq[4n hKpmΎ:2}sk >^(Q*O")'PDė=p L=pN8@ms4QԷ}ꁑg(q⛩I{9^ƾSe_}/r}/RI{9^ƾ:'J"U3OK'œREI:}/U?I|/b:U:TPfpS OHLt$RƔ;)rbs e2i![iOiI;G4xPLSL+#f챗c'; VGFd^!;jNqX^e^$|jfNMJ^iB٨]ʗUtZ1*c+g:-!|T l=EyEl /n=TP=@wξ/뼱z@ =p8b|rYu֑2g\y, {ww( ߀0ЁO,#SG=RpwB?uo3r>VReu/#_Q ǟɉy bzjej>QYJ#fB~K#oG$bix(@L=b f1 G=?c#ž{D{ a?N="yV~—a=R_48|7pSU,h~uK=yʽb8K5''@Ԉ:A]ttbQfΘ(m0zlװE:9~#ACKyQ#ƿзzo}c2p?PmWFnbʂ===U5>8WIJ@cؑJp)EK\jٜo[^Vꂩz/|1 gSD޽=J/@u9%7=}^8*;>4U]2t.i-b[ Me.UҪ 鲾/_rٝ\@PFW> sxu:p'Z:@)5zn0VE*o|xAzVVpHۊ\X'+m0|IIacҎC: PbKj\\5| :`^.)ˀ#\Da&?K] CG78OμH=|]zVyuFӊ'~S ĥ a9_X*DgxJp(cWe 94yg빏g 4P*N jͣijhwxIGs^S6wKYFӢ3Ryr#ͪ23p~+7Q-9A؉ݺGwoURRe7IiT9YvG-0o?|+UM[/LSa*} έj7S~߈0p#|(WtB^5?2P? ̻*+];zi:D8;Rw~ eF?|yԗj ?f)#^jTe4jo: dҺ8>'4DxT={M ͈zi_>eTW}yUl*`m%ү,KPf%eՂ Λ,>-YSRhMabILv0<%Ǘ#v]R4v-hkjfEFRaPMSCElZ#s=f%`Jp>9 4 >.sD ۪udpKSJ,Nw\55uL4Cj-#k ^1k›X<:餡<\k2|%`*^XgtəR9hN"li ^O wIrA4\<8/'(B,hOWtt`O_z2݇H,2?a5þktcɈTˣϝ=ʫl-5 0L@j0 $5 m)t\7Dg BSFt oڶ;<]%8A |Y%$T<6^"y}R7 8)FJY^W>HX|eѓ'ܧ!w#=O:zCzp_:̝yp[Q&e4\b޻B_~曓^_3'VMJWp׿@tT M*!P%<_+tq|0AZCbfP5hw޵ck4*q 鄃uo#X^g+Gq"̼$wNcFHx4 PbHĚB+SH@AZXw~gsONn}9 Q){5o/|c=DQ@7Y|M7J[~PJe3uYR'tPr"Xh1^1{T8uY,>Uޱ4"X9K&{wAiR#̡M(jˑAbM{$ecJ/I: U}|G{ejyZKs&- b4'hċp8nnbzm#{m[K#!q= psS`u1F0RDg=[l#F48(jFvJiᮄ{Zcl~]l;ok;ىEWQ&\ayϿ#P<-JmnbETNvm[\3E8 .M# 3>9wrm@~-y4&Mޑ;upGa@:`x;?2ypA=?J- z9G( U91mi[`a9O=|쎲=^k5=;Sf78~-s!؈?nHU8;<:;8<<~'0TN7e 1젆q;FZt?y @s44mHq641;P INk JҤpWN#8}O3:B8\t:~YW&tܭ%ZOJ^ҙ4=$FkL!wnMx-IrݕR Hr >0(g<4HDt6Q>v[5~GwB?_Glx`'ȠQm WEgςaƖUbV p/s< 6MXuNG$ylD@%i|L!r8/ MZϢk8oU䳻E.𔱌ў> 0}e4`o`^[Li|^î_~`84r_*Z(uP?PKSFfo(j taurus/external/enum/__init__.pym10 Ew#\cJD vH:ދU2ESS.RKM$ |MV@N7iOZ'[:>ts/{PKSFјg%taurus/external/enum/enum/__init__.py}? 0|""EMS81Q7{qFq&Pp5EW BY(eD 衖^8d?|,%ArVJ!hʪ~W͎t_tPY=FBR4.Ag_&< a\㣢>PKSF3:rtaurus/console/__init__.py5A 0 zoN9}A)ZRNvP@,n1TE-ZdUa%sN=lpr%Jh'z)l.PKSF5xtaurus/console/list/__init__.pyMα @ =OAtN Ѧzػi}|Rh'3b48AKEn_K5vwCxHIײLemJGQ˟V{@f;+eua=t477_?|PKSFK_| taurus/console/enums/__init__.py5A BG}CcF[H-0mg'43 jU#"EIQ FY\pS8Q?uy`Q~8)/PKSFo_v taurus/console/table/__init__.py5 0 Ep@kb} k- K8PKSFgDd6Htaurus/console/util/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Htaurus/web/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF'E9$taurus/web/taurustornado/__init__.pyXs4=)lt@Bޥ<Wt-;IrΓ'N,cO{Iz({$)#y! ŅA 8T.k9F>0|zp@<O_y8ÁwPAƨ'%͸Z6QiXx$ERQ8HSlQ@q&n| ppq/BHE #Dzј!t;},9`\2؞7e{{er\;WAve yW֨PHfP,oPi[qA}B5c~]Rfw-KS*NRfKSs[u+Sb s1;bOyM=.nPn+ .\D=D,{e*5`In:m?[o^Oi_}ןzQр!howcὂAq B3lTu e:df_MgLkͩ}7chl`g'ۦoزάWTS:W"{hC-lשHdC 6=dJinJJCƭPlQSCr'ea&dБ&^ASۧXO, gq{Pyd&b(I v3u66u*#ŋ!^Rc.2zEJ\U52y4E UP0:lVC A6OS7%mMMՐJM;Yoޏ_۪_V, `fݱ[a^S-;*c/PKSFvOB ttaurus/test/__init__.py}AN0E>wM% u"T(B$]!dfV۲CR,o^<r!)\>hZYtTyā>;|KXb277^{,+@fWmyffןewMnEl9zDvToPKSF߀;O~!taurus/test/testsuite/__init__.pym 0 D5B"B4,AǯBwOw'ED5aʻᮉR^- C<\Yg7Э [\\+8pbm|qd MeAy٦nZ X:6oPKSF۽]'V~ taurus/test/resource/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZZ_ZX` /FWpAPKSFgDd6Htaurus/qt/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFI Ftaurus/qt/Qwt5/__init__.py[[s9~WL͌Uok vęڢD#V۰~#FݴI% קsӥR̫4UQc!U5+@1+SF]MT*/y:ߴh4zFT](*9OjDF,QMJ(I@wyQrW͙a-k*°eT*H1zO꜆ƝH DDdW ^A$>~8|\4l߷rh0'oG7J$uƉZSD-j5+KTVOI0t2LKC<2P.ϴr6cDRZx2R|⚻Kd~Nc5dۑ1_3MXꊲp\38f-_CM:SH L@Hԥ&{V5KYhYjT3x]|Bp ׵,22O,yNOHQ6]SEyg'Na?lEMWDklnk(=J'jBx9w |. n6I>qS)9n6$%YE6xs1\\mcѿVֵG`kM5GB"aϙο(Ē,KBN5 g2P2È"VbR}l3 8z 3DZeMG=]K5\-t:G{ԘGzT*=-圭Cy5QLy(0qU1υ-,I,KztBOԋ&~% 6ON'2@0S^xv_э [MnRk%)wJHGBnVx X>d:)N9Ul9G>`֢'r-ڼx\EJ36V&w+1ί4uChrB!viO'S,96vI@8~؍bTBƃZnLtAmJh[\KecoX~p )Tv6eY< ٌE1n>|sVl&{R93pH$m7VJ&^s 83TWw`9 Ԇtd%\M5FyLs{WXk5QN$b TY?l.̃tg bI׽Bg2]t Ϯ,ͣ9Rj>Ե65N |D"*ao*ӧ h۟K`Z#1IVRluS>fx%Bm[N!o!úD>@ΔV'}Tٳ2v@yGg+/ӥE5Em`Q=jfT&g7~ F'b!лm.pQB+!mauA@(Y Pn)Rw(W"]1A#qtIx 2x <)t t(`=vr9[ڔ1RlT,Un#zeB,tb7eƂԥnoh6ۄRGۢ3`2Z ӞW`n7FW"iNMVר NPҋ>7"8Vby )CIx2rNK?DsuVn8D&8lɀBn>JCCTH%p5, !fo}DN21|p6tWZhFEv ,vA ]wONpB{KEdHG@bڣleēajn~Q4blz}N(64m 3_9#?$^B, X\Dg#]#Rp]p4VhKv4?%a]nęP\7!GAd0#'$OU<< )3h0c WH!7a# .irf|| ɐJBluu:@*7ENtNkZ-NqV6%́/Jru!ɹMwi[m!+0n_`Ie&m+W3Y΋%l@2ow ݥJρ%ճ=Z?H01lA7Mze+9G!,r$H]D 6PU7n3 0Р{$ tS$Xƃ~*^&p0 FZG ?d-“`2cWY,JRJ }Qjxo{ݣq2Īp[eihRlPE85X0ɨ?Qx0I' +7{4geH&de:D`ÿSh. 6I 4l~7v%0V/?DzV.\˜W*&mh^Y0:;D'}V4/NW6}ddqUoi{ P oJEvBPߙ(UR/#UG6ɶqh A UiT7> (p#$^}Z4$mPaAdŞIX}+hށ2}s/\2*ae:qQ}x]ז'ø[{ ky7GzG˲Ic= 5`ΦdZwg@jH7dH> ODT}~#Oelm}含s,(ZYfz)dD>;|~^QyMQyl ;kmIGD;I 6>ԔKH3ʈ\f!#sأWjF 4v&N#eM/h@qS6H!o?3@!SV6a:n8·L{6y:wk Ha8T }{*"L@׼1c:\s`*{IIa1[2G}ZVf3iC[0sLPveQN;y,Kχ?%7Z7`/$dHH+'{Ga}5 WȀGĄ! )QR~Qc㿂ʯ6[Ŝ,_Z}@#7{ٞ9nBBil ]Nt_X'#a!ǠKuU,7(:K PM.:d&qC3.XHC WlVæq4G-+<,G&Ru4Q]g5 #Dgǒu \fTRbZ>5q.-\` ~o]DP[eeK&$<8Ag=w@ E &+6,H:J\g#*s[l-_:/P[U2! Wt5m6lըѼmCb,1oB6!nFv`4G8\-G +ޅ,On㟐e˓@l^Op'ã &dC'OF}lx&@ioP ޷woMJv4T,Z?ӠLB{"XՓި m{ײ'{wuq{mvSBPh=+[:bx$=X^4^ڐ`Ine IŰ]*q1Ҿũ21h2T.=900-<Ž:X%ߵ$EI0mBrw1 7cZ},IvMzBǀ,,1b",i`Ds]pC"dh"p/^$}sD\"p#Wav6O g@.Azh=M'eh`)[WmmrM$r|$! |j-apRe$kapLA9!ɋh-<vP*5$G},c so+$aCXl -1$3dl]FG>_B22d:+$ /Ֆ=W'nI ɑ xe.;2a$җW)@|phh-{"NϲnAr-O~Vì۹3 @b$Г HdPK,Y'/cP5y\ ! @"CΒ. !ē&WMS.c}t@ ^ e)NWi Mx=m*XU3VYf)9i0A22,_|n@ ^7D"^b W(ȀH *âH3Qj)tV{ޥu#{DZ/ܻ_}~/NLJ]_2 CmV,m$,*Ew/oK6?_.+CwL 3eUZFʀο܈H7ꏙ*qrvx QpV{h;cs8#rtItj9!<3KכJ&D#aW.)Ԛeb_IloH!D*}):hk;(p0a"ŁJnq ON. > XJSϫ;~R%ǰq̩ʞӔ+rc|[uӔTl1_–OʜVbfx!-LQkv.t }UڜbYQ,,$ljWd-J]-f/!SNiP~TKTP+X$B[PZ}Z$QuԺvb+4ruZ:1)FL+?Ix {ZV*I~I?1a?(QR"S*]WϙI%V~jIrr8)LY ҧO;Y}!COix8qjyݓBʩ̺"g@֩u3A!\Q(R (R0?[B8N\NS0xq%TL|l'ii*Nbe\o.-fhH dU@ dpRO 'N6_AjgEZ8 Y<{-$udBD6)1PdQIJvݥ}u¬x(Hu> I{iscA]/r"+>*жgǶ.^iٌi!T.Gs|4f+9]U@a_br^AW8NF^. D GWp(5d4|@U>\LU!3ʫGKWi Li/mӪBOɁOOw1YneT1uyFneDv(i*퇛t{Q"k:8KPPW}{+çrLXs:]9YMk"/nE0dh<|'p)_漸8&HC}5oLS<_n94Q4NLy4LjH?-:giEtS 5<tuRMTSyO|P"sެrxd\".iK/X:ʼHDa/3/@(NɊG>9)(ES/pXq Fxd2ž}),)FQd ?s)W* tė>MRk)Hp!D?B:&*v|Թ=J)3BiJ%9c~+ :;{ސ:cXh8'CI=+Ą΄ |. `i7v2eq=wQs[G@4ShhUf;\˖Oӌ!kӮ]Zlq=?+A 6Ec^΃G G@mEr TR8: 8ct29w2GG>dD[2PP~ 2S HTU Ҁ@~rf.:W dYeHǒO.+.*7/TQuLKUuZ},j 30OcJoM1U}{i". &ZHa &ܟ[}[N&qSZȎ!j uF0OyS?&2ϳvKM!)d*'FWe6y!,gi-@r[ P {|zI1$\"@R ""|')0vNpˊ]l%c@׌ya-{qpvT.4&? R)e} rkH,KC"{̼ȁlou]S# i7n~ 2(E+EV[$0| (7X!WK#ubW&[vJI8MY=i,#Y,ܣ˽A&( D dƓhP?*g`u4#)ՉXLҬN5g f?ۂiP Ls)vr3%of]g B#!$-ߥf&v3Bq>T0cS:`xK7m j"4{Cgt ] Ms8CCfvcwY3O9lƑ w0Wo!tUS KdG)Aʪ [=MQp-4'R-(BHm$o&,Ѻ%{ʑ( Z1e|eyĿE1$1Mi H֝I#wkq 5 Ѓō{ag%0bvB)!pStAa˓-5MS .£AӢ~H;t9+xe̳nӴ]dtS5Ey}^?=D-XJ Lh$MȓfAffSbK;jBa_ E6(_a/c-lNiʕr-[or%S1aJ u%L7eY! :x8GܘX6-h൨iɢ$"Pf,XP2ܰE`Civ[(54{dM7r Ë{KֶZJ}.0mڹX~E狼ꚯ!˦q_-c=SLSSdBh#3~ Pp>`Fj6BG#x_3IFguu?k~`BѸoMt$9ŕ P+V @KR4HUޘԫ .gd)eLXg bpR얚Vg=3_ɢf.oбv7sui=R9E5O`+۹T^?"g2N<;#XSO%8(0;YUq.e萴0 E+lV>Kf7KVYeözvܮ$eU̍5ODiEg6lHmS;/AKlpgiv= ۸.ulDwAJYe(pmu6 ZKZ2U+ _~<}WJHRwFI ״h3xYC=D>IJN91C3yii82_A+CzImP^ hqcezbhXvi߀ =uTcU^6#=*O6lTӥg,yrfM#ZBa#3&_ V2j޼*CHO0yP2=CwZ 8.7Wsl@.'E蓴7 Xr`9lqi3fBCDēYwQp0дwNe:m`ds6$VQ,J9Y3'Gմھx1?.v1.NۜpQK;c+$t C S  9x('R^2&?a=~ /U/(y΋_yQ:(1j6WSմ>IK$j7k sqU3! 3TŸyPUz"11FEh7 aDR[Nl^[W ~GQJ'h |(!. QY^j%]jӍ-B8{84 $C!]{ @x);ןZXQ~2}={|#G={S"jdx_=H :-P{ճfvBU&5~ rl–MD1?kL:o `c'.9i8YS\kcot|Pp^4哺ߜN;bӂ}%VD-z3+v ׯ.hK9Lhioަ鮯i[{4t; ]C{ߊi{~[j7;1[s[P Tc=5NuNM ]S#15K R#}'u%u#u!5GsG 8*ni{4xLk?v76Mwvƿ1lss5]lw|=?7[D2:8o}"P#y7jQ{wphʘp)L9!XeiBb5` h>ڑD4;PiP9LYZOYi'a77g}Eo_O1_L+pd ²O7)P 5Y& PL2e*uӠ||Z#favMo *ǽ|K@p<<- D[taZI_ˆ6P89Վj=xj% ,?F$4jE̖{?G;qҝLF@7r+쨏y'3uT&cMʚB,|9LmF "X6̀5nM 88zJ7 WeЂf{l?]+H!ASbBp|h3 EПC0+p8!RJd)k$@Du~ $`5!Qǻ8"B`%~z yX_a}(laC =yXac;V?7|+eYAIQ ^7h#"BbTDi=Yf2FTG9 {V2$VJ5@+_ :t V߁GM~*癯N.#Jr ""qSZ(Mֺat#J9T﹠Fǝ#=>`x }*9tuwE]^I9ňM2ЋУ뾇dr.@Go5U(t ԏ;' *HPclL;Sq(=֚{> ٤Kr# *R]/aqKi^kkQ+lݮ#ϐ1hTFD\O&"P 77^VC{NjrӒ`\ 5{g0^`ewe &[~}u cr0;"*oD\l"#CPZ{*:T0&Lao?ΦW>5W.8yB]? ;$*2@ ˚B;&r#1L 2=W)᤾:48dm CO7i'}v$l4&E ߑIL :ނaGbcbԑ̘w$23&&ˌD[qGc✸68~{UϳjޮrGQL"})>37Z9,u@2sJޏ;lΠWx x5P[Uom쬚sJtfjp2`sX}dYϳF#'Tk XcpSё5]dv9j< 3x#`!r IFQqx#_زx ʳ.t4x4&C68ZlmP;#&`\'eY[7$@ٙ`}é$o]Sʣӗ:YU= j˰7 xOُ|))@:^╷6gQ.*|Dp94$rTQwқ75~xҡss:/W#s qև^b(Yd^.\Vp"N#4ԣ-n=k{wFm!!/41Ax0T ﬈I_*cN& P\G#۩ϡK̥Gt-m$lYz\"2*u!kXt/*r/G!4!brblTi&g!KOgi/rO.=jG/$FUKh/&8D]p(v /::u~]/ H.?}W >\+Ð)`/UJΫjȚhC(JX## 6:ϓ@ne*v6"T?Mnɓ)[k2w8[XygXZRnG" ]);ă4軳=L9htяEbrt 8=#0MQY.%":4<1Qke9!Jzo!NbRVsgUЋ^^v/k.wNe̗+/0^~$&>u8^&?3?쉁w'DIiF+>unۧ'Gkę1։Rوyn1=NWi[WFKxQ0߷ˈGu <!я#DG ##F##➟xDS?q<"G=<]#~\Y*uaf(!Z;isƽ*`y/\J@vR#i]o=W1uzr=Lx8DE@EYQfe륁(Dgf&)& CԌ7n٩.Sqhk/t}[S$~:e]U׮XWVf;W.CMgz6{&&^[tpx(KHvSmmózT7Dmr<\dF\5̖nx; eYo:{M dooJJ7jC[[v MMmۈG ]( :lḯt[>8a=t.h`\#N$_=:6@5Z"l>왠z窹x=({F V i}tb엕5W ݖ?di< a0PMwiieS4\%^Ɲ=ҝASJ ]^[ <|{hνQk輩gď@!auڕZ!Sc" hq4ڴMY0<52c M4b=u6Wsc(cjʳIAjѓ4wnW5PNroY63G w}V.6Ruz:]ؔ^jM8&N/^R߶Lpf3 =W}aت" Fo|eVz 0Xp][~܄Bl2P͐Mܡzt8p٢ᗎDŧ7SM5♩VejDg/m`&,La_;ry1׌ǖԁ"Yu xlS2ܰoqu3%o@~osPZ=]ZX2T474E폧PR# (asj?!eՑp;FIسxWY=UKOL#683BegU&=VxQ[u#Y"$V˼l+c:0s I@v@Rii/%c=Nt-.2GayV͊imό`XyYwi=oL^Ӯil׬Y)gˢ|\xEt ,'A[9`O>F&Z,'`ʅլs[+sN&Yl@v\6G53LTnO*H)f#uJ+>Z| lVv 1a4ejֵk5&JF2)UglEt^ ׅ"8(uؑh/i e EL#iJZ Fp߂+v |z_:~! & ‚ˊlO"1t5$LO!E"# [rqξt |fE۳ˋ駝ٽsiђIvE^1ABgcxu5kq!M-ׁ~eUBCHQFϋE-Cs4O' FKi.ɉsl_n(ߚe ]N/r*"" Qk*( 42UrHAQq;?NAӗlzЊh `5'12c g oJ%YXxK"Oð=1]R6z9_ fwit[摫s&!'BC~ _dwJ.rev*CIN_BISG9&Q |/Q  ,']%ρ>1` |R]!=H{nMyX4|0xHۈ&SL"oEJ k*gwY8Y1[ )doƯʡfep{X ᒤo~'r$a|"} //fc 0բ(Nj'}\|ׂ@b57;ho[A> aȮmZfDp"b_EA L|pqeX(1{(`&bi*MD "]3%8 }mk[0H>G"s$NVodE_lsz4bo'pEH1ײ@$G\K\^(&xBT#|lUiq'S}|R\?tmoΔ߅q&SK HJa3}- f*4{ }>mT6I|38j.l.pÀuB18?kM1i =^6 `E{ ̓/R] 2ʇByϘ3?r!Hd\ {z}d(I<{]l?ʐDYN$4N o)+- %îbvs/84Ha{dl8Q@cz} .@|Re@lgYIV39O'xHߙޑσ&5YC:r\ Iă8)5Q`eP8K>@#IY wD:G)pĴ J ߦR$e-L˘`(*/q0hFE#E G[آFjDz I7Vwo?1D5 cVUjAjЉp}_ى0ҍpKh*e ZGDGs\0*|G׋3C'5b']0Wezj)+EfT "`кR6I }1DJFtb0JvSKP&KI\*^);tQ<6èao_(hg5bdY4|G tYEto``1y6jݐс > Pwf&$7QT*p+kϩ9r[G1Il;Y(7ǒ-9T[yDáLohV/ C%M,?\a$|7tX f#{8%1휜wno`Z#pBU J[duS!XT9chdi@ i(ͣoJQ{;`dT6Yw,,[H4:'i(%G'o>d1skTlܘ#OG]h TOEUhf Zq˱_ڬ,hCnic } X;݁=&I֛XȗsvqN6}A8(ӏVl3EfN`%"IC:"x}B)`QSPHS81<[I)Yqخǜ~VYuhJ$|`V'L ~$8)&p\C 0=$thRzYY4e (3J]X,0dd}]W.V汹8Ao-Dn𻎿ΦY,ϯKK-PKSF[< /taurus/qt/QtNetwork/__init__.pyZKsWR%KǓd+J4$t7 HQV$ǏUmk#8Ty=,*,P*]H*ɣqd9*/҈(ѩ_) >MzߢU8'{|\ly'+0hbm5W'"c kwq[g+ϊ]]wv J+i+>[}.@|0*ξ}OΊ'jdJ^AiF Yj'KIŠ5lnȠ{PeVB`₈_j#aZFȔ]zeP=娵^R-;To{h(%B7eV.7upf.4a@8?acWthF n70fl`: ?KX#p1͕`Z\ )6Fm*SvݦD5۽no khi f|&fwgY-T>f2 wGk#jq?a78-hy:䖝u3)}c8WU … u Kz8k8jCxF=A צtN'Cvɨ6m*y> :F0ԩ  g@YfZ䮍QG䪱< `V CJ*)U?(MۇFȴY8o- Φ93(PlY?,0e#D7aEc}!rF`0ܮn`)Mgͮ\jdY51Zz5+DOd7OE)BG|paiO= LX9mc&k 0h=ASпKؾ̺wR e?s'y"ݛՔd室;BSV58=TM8nq\YB-$:pƯ!و=];7J9x;b0jԽ46^H%"Do#"dN"IhV3P9sM0Y=A@=S_v&RguX@qHkđ0[N6p[}T#B`&y,rŶJVsz7֨ nNFOz5ܢY|IC5mm DY Bp=i8Qq/c i>ĞиAo, ?|]'Ud,nfŶwͺG w9ʳ!ܑ'Xt\q"$jW[V̏4nKl֮E^?8tZ$۹,Z['=<9+R.ʻR!Īmبm]fշ#"Mxs)MF0e̅(P;ߠCIeyP_<)@A9ni+2x R+@KP R"( Ηlep/j~?n34ЛI?:ΨYu!C;5_o5I']4mC0 ΅Jf)Gp:+ z0SËF '=5kӚ󐚆/^)S+r2m?>ެn."9t2^d24j s"y"gr ^*Sَ[r3lU& tꡣZ_+||KV;)}0>z} zj?ʿo\wsa |Q>><<+w^^˥6ps]F>M9re+I;(> pӾh]l|.H߿d' 4!;'^Qw O PKSF2Jtaurus/qt/QtWebKit/__init__.pyXR#9g솉3ifB*E%J*%UI}KSR)o.ϟ ~>e;P*sB-q:{ 8~/`7B}@2ɬ=Ͱj'2 ?8~7&9>aَ`s,㕳sUnN^̯SM^@)*K^Xp26V~l mUnet X&~^;_{%Ôdm 1 xV+gQVopy튁nk?7)զd(cLgE1-uiAhYY@ˊ+su}!DuB#LeBPgNǵᝐ€M),+h7{\CŒhAxBc~>W=īsMP: oZ7_@؞FC:W; 2B>iMnQ#aB%AχzP`$]!AZgA "uëC0Ը7ߦ|`&W'`f 7 *l86U袐FK*qK;k Wv0? 0ءmfDE9+X4[aJ8Q@Do~o+אaoZڧI]P)ī2cGF USAaDyzfu]2>fH^YQZFjQX46l4UR~ˡEbfe{ k7 zJw z]h~v./脧4i4a ]*^Y&&ylm %p 6W6Wts{/V9oa=adZ OHJu%H H; UPRv1uHSHDnmgĄ4Y"FntCh ;[\Lj7(7jIvQdʮ[M_e&ہR3n|ʰ[;4p526uv3--4 S9䰗as6aA:NQtz9H/Zx CӁ"iu.7< PKSF6taurus/qt/uic/__init__.pym90E{]RLp`7c1ߞ4[ 'N$e t]1z'W.: !6,<Mb(FYSpj)z`UO]SVKO6 M/O}Bs`:_ G֋O<ݚ /N9U&d˙{PKSFOYt(taurus/qt/uic/tau2taurus_map/__init__.pyu @ >7zAPsFYtfZ)!fL6hxF؉X(k14F'eȂ) .n^e||Y3#hzA;F9:?HKzIk&\B 44^JͦPԱEoPKSFjf{ taurus/qt/QtDesigner/__init__.pyVMs0W4viIhN#AbVRl,O`3>[VVT LBJ*##%WC1z|k;OV |k@j".P{Q{8b$%OO y;-R 800bl|eAOAwBj3:EeeLKcZZR!\ $ Kw{7Y 433{`WTPlEsU߉Nf|`_?)^2gQU C]gϪT?QNgQwwH'Ѽ+@9Q$i{دUuKLZuxpᄯp4.ϲJns^b~+3E.g얯EˎjAԿ|(V7W,.!:O)@Uy, mF3j{@םל>כ`?xT & -m`{ PKSFw" taurus/qt/QtSvg/__init__.pyUr0+lw<"!/NhI [[#ɤ}%#e{KW[ul[rl"Z7epʤBY&)mgUci 6:\_V!_4%jW,$:?.Q`sʈ9J~F*ˠbV K9&ʯyIX 5<ҒmDgqUF{|j@c˴\ w߉/ÏcC !5ڸmboL!~w)$?V\9z92 L k (rKb&Z]#~ [5ѣ} ì:bG3X%aPu=N{TIclݦDr/A}%I),?D{ϬjAq;#ON4CAuQhpD!Q@2aVH |8P cGqM|ly;:"B=rqX5zh[fxbqZPD )ž;[Z+ѥ[o/To0PK4ֆYRIemoПTy[GD=ʖYz"J̪?LshQJEwNS3 ylՖ s,KcN7_Ҽ &гn||%-@y39@jZze]RNso PKSF~w r_taurus/qt/QtGui/__init__.py}YsF{ =>L<6b]3Ȓi-ɿ~+:c[rbfά<븯v/lyjhj|wTjYnw,c 7@[~SΞzym{ȫ"kj{cVgy/1WYa`qr׶U9v痃jjP/]Sg(}r=[U}vك]wVE4{y-m5ؠZ5mZ. c^k^̠OX~PWiCYkX֛Cm п?:Qc՘綰*Ѡ@W/M .xރBш56&r~bIoDmUiN[%_Jv^f:V_,V+s>V0N|xzYx Zm/r*"62+7:5q>p`vuSզhOP8Ramf}nb!>*Iy\d$\IEObq]EuP*=3xKl0M^[ D!Hq5bHW_Ȓh,RZ*1{ulJkEkeG0\؁J}7d>J=?W59 hAxy]a z*0#}DJEM\`cY4e;d-{UmT[/ţ̥`&i6M |k=~d f]߯އuUf;LdV?g?49zU eRh9CIi&sx*}̴bI5h(:ˉ{Q/W^Wvġ׽mВ #uxikV4 5i_:UB;eK9Ae6'("ϸQ%8`_h^|gE0 77bIMXM]ŜGZ_oү55PmCGonGg>VO@7qnko>;P=M+dQ9V!UCuj/|rDS%6z`q!jXX%goJ0TVl1xo96(KܲKrPi9BBiwi='ƒ G.* 5{oR = ;c#H2]7 燭%?g&{cԛmVFYRE;k&M!!kjrV}b,tDVLUM!*rOgZY D(XM̗݇2+ FS;!9Fh$?>=fms7`UG}z:B>-Y>]2֛9L{gv5"αx{_gwzGϵ.ћr#q)xFuE%8Sr7-Hy8 #ѥ_fhM[|!5h$exBr*GH,L!4q*C?b#st{ǖOL4cK@pٶ/piLХL-YMy CGJLőOγ=ȩ: erR QY]qmh@? GszP,zjl8pFr D.# āH0"lTu"xxG7ñS +nG+%eչObMVڛm- &B s+al ]>ݩ&mв;MvQK f C¨-=F,ɵμn%ilpw{HCQ&gxj{ʖ=3q4҈xi^'hh.nt Lfҥ'>^mHhjc2zDDr񘭧9uq_w3t x4Eocqࣩmmlb  ..NJ6*.ZIoɌ=\HS벟])*se[9[t\^^q/Ўgqp-|X70wY&ђnZiȒ#6la-L$Ec*Nxw%go ϝ#s\^M#K@:靨 ѐ.vZF >o$M:;񬃒w܁[x1o r ?Ù]VΙ/ t9zaL݃~faAsm9#ٴGhۮeZ:u ūm,(P6އ2^6¸,&Q*q4L|ct`KE""bZKCi0kl1^6RpϠ0A.f}b>סOC >Rb uoOvwm"v*uE}2y{8"ohؘ{S\mExBj텉]nN>ѡZUu&wu:)7 s*aHw`JyZp&pKmiyqWsh=se׼,u}抝|SMȊg6_K,Lu}Pj{|?6XZ~.V7ȄYtAS 8b?!1m7E1I8&A'9vJ=̛Zv8'7~ٓzTxIv*^pؚbp\eb8hy$3.M9Fo8D t|AĨ%|OPgrbU}'@Sr=vm7Ug*#M6B9l͞]=v1[ oճo#7c4*c_҅D( Z?ekQWQGwIc!JcX\įQHí.EybE|âO.1w\d_r\l7HfQ:$W, .Iqˡ>+ %[8kv2v+lՃg`y_WOSOqk[#E ;tMTp .$k\WO*#TxVZcŐ[P=<z%ɛFOn\ MG>YWőC@OHEEjL#:lv3gXg2/ {T Aޱ1مȚG>?ֲK(q(RkVL,va~9f'#Y,,㩍!b^KD}O_RЌUE!-{ _UWɸKF%{xh--ĹMd+t(P!Z!g$tgZGL{9lĩ2Tr=_7zUERc 8,Ƙ  t >&oVjσJucEa'3i2[S=zO$ᮮ8!cOf#EΉX~mS(m5v[CvIU q>--2^ē/U 7B&:TP8־E6;=b SIԡ#8t1HDʭ}Ym<"֦\e~{~̂gMI, L݈ˉ~}T՟Pd_%fj0+2'1cG\a':k~Mf m4 |s#ZZxW2WQ"wjjБowu9LzV]\G&spB֣f#ua7Yg.s'i[eE]FYrX+b4Ś06_pZB';(cj@WIGucS2cfمaJ$fP_k7W9#r[>r֖98OANGoS2رfe[Bÿ+ALcc^0\`|bs<ImC <=Fx̺tjDzOl6ُaqMN/3¹ i@Lpmy6L骸xGc;X椾%VٚoH4BQO'e~WHb>R ]X5F#=j{ހwٯ?le\c3I4-7tLyeKGxdB/JGt[}q:mZӋV:[_v@H[-9dJk&2c^I.BH0p VDZR4}>mpgɚy'?E7EKAjU6`GHcu4B+ZK-y`˗APj0죲0d_}`/:ڌB簼knu0- X ,[~{8v7x8U/KW;D{kδiO,!m6Etg*1M\l( ߫ ڝd l2w 2lLzwj vx#62u8P$RPnVwʥC[y'Ɂ,+p݁0~jh荨!!W=~m\T W6𲆀 <ռX L9Lה `b4fK,+Ć(]mJPT3x{n 1w?Nf <ƝXBB`@7<$|m#P*~lߗ1pt:цWjIs3"փfG2#&lB.p7CWDu꿷}MRpb)nf=fqdIWܴ3)d`sԿh $]G5 H68]0(kFWY(0G=(#*CÂG$Wx<ɘ{c.;[|1؋7f` ?oJR7/`IunJg#pش <ܰ Pݚ L/ض{QKl3xu퀝Yp (((bg1߅ xȀ [ɀu`;>v|.v[A`3>f|0`3>oƌ&|0 L`> L`¿ u_Xm𙪨? gjW~:79IGJF>7 gUE-_6ĒrYA*_ZE!= 7D9$/و1 IbJSU7yـ{hlؐ+xTf#MAh] ay~Zqex= >Ugn5ʈ/V !!!!x"!B"o%Bi淾a,sbAKPS1AyCp<!8<l|\|A_F6_gՓWb}iCyڼ_ۡ*1ÃlYAR ʵ*%;vun3)iQB279ήG:pBKr8+۬y1kRpG܃6T[k[Xڴ7P;G(]qoF?k%9ﻔ>^|rQ-6 /*sU?lȻ}Hb}T>Aͧ-gX#Ee]] #nd!|?o7VA|s ;8ap’&~+쇭좲:;?$7^BP3eeTu~ ]j>r.NP%+{%15]N5x|@W-tY 7# i(ʆc9Vfjw @/ ,Z+lZ8|ϳQ-Oy+o&$eLx?n-&֏(.jç$ ,m/rPoK "Kft,XnӒr5Fm8"RQeFyA+4Ɨ:羽Wy}ggomx7Ϗ;BW{0t/+PD/+lz#?8*\g5z^Z(%+7xi/.>Wb]><"Zuu"_`@o;o4fG]-* )b3[1dȍ*vl_gplN/<~O8̀A>|DtFFomY(Coyzu-"h}W 0/ւcxyOO.19C$p+CL @EM]- Bj٘I̒jmIkB ~`iZ\kSvhɠh/*&4tmt|@* zaGG{Y?HZݴZ9=EqUdyȼM1ӣ"cmy ' *lGDl:ez^[SZrT;Ascv    w!c2V!cV2VlZ\UP54tx&6dKcz6>"e_Y<2g?<K|AD73!?jzzRVuHPnA8cU-`DzU&ǔg^ Bn U`XME QOngQ/cWȆ =bWVD z28BW>ο(k: NeE _k#zT  pĉVTzmI*'86x8L0FzM6*=; }}/QFj3%A+|.Xu!ob 6IpH({ q$kvXltpn_H5AGrj'>ܯAEhs~ˈ.ܼ&'E!+['|-Eb+ĥsO1Ffld~K}gm?gzƿ+m߮/!T#G:C0=oAxy]u66L! H"Gh[)sXwA%[lnޫjoJzPx d, M?{ysJFpu_/ݘWUNPs&k\ ѳ^Z Uӎ72*OljG"97 @WPP܈1>|M^WwZAeMP6Ae˔ |y_WmP:ANP:ANȆ|>i^[KA/RKT/a; '(p /pZǂz 1Ǡze*da=-#̿_NԮVpVS> '(x (W~~ET/UoҦ|-l`[>l`[M򠄃=`{>|{><*`>}0A `>oѠ!}0A `> `_=`{>|=`ϿQ{QE,`>X`>XoҢ1}0A `> `f[(FHGãQx1<mG Z$hE ZWho1WOrzjq%cO4xx۪n:Fg&n]C-SegE5.v0b%xE~XgO;hY^UoHeY͐XË*嚀FJGeK?杣mޘȂ&(+ss fߌH;4ŋ ⟔LIqiy1B=Wy=HiS9@ o=$.H >+-w ~'9 hn) ixY2 H<9T'<,L ƵQ7xjgD J3Q8#M)?_<zjϴMg.wSB%jWׯt<)ah%v]a^%v]ah%v&|0 L`>L`͘Ux06| l`>K6<;d64r/.`lgC{Q![B-o!x -%o3^A| /Y^s椪>3CgF1(Ȣi_=.^zc<|~,<ح Ѧ/ٯ>Xӣ:L?}O4KӴOw&}9-Yg, KV@y^9[`4 !buD_Z c l6^ѭfݞ7 $+ׅnм̹=M' d39wx\γdlxO˕f)Zek5{wAgfR*9pNstO[ҟvw|w5|킈#GjgjaTN"af\VOFjv[8Yzԧ:oݦ+q?k[>s#'34,X+~y]apeۚh2/fHF"2G7PМKo#V3]_=ɺ'W|W|W|W|  7B;X-y/f}0Yoz6p.Xʿݽmu^n>x#(ۏj(هi&k`؍Z2L7ekJ5R ~ zQ؋SdW1y.!P6Fk}fr\ wS fV1E7yNOQޛ|bboLsOtʚ}x?,n]S:zmG38!e|[23w&RFA>Q,x|%I0j֣f1`X=jN0Ltywg*d4bǫn-g=N7/c/@Y bE ?Tq_BէٮF.]OTLPBi=i¾!XE>P[Ri G)iY:B;Wu@,G3 THʎz)?ai#ntu1h]Fạؔބvd'AClH^Mg@r5wEc||;x\'Uihsn[WսX5E2dk\`6@<6KS ,ZJ>E;l6{PydAґvl0R:FY:bјt21.-i Ĥh=Z2k WUmNCDm>;8m6§C~ͼ鏋L"KK3'`riS;<8\+S_CH~"gPqQh>-Bص3^hP8,Cէ|6+O5ǯZK]TGG9DsD>v~e m)~;fVu> GzR `sLIC^nkkWkD *L!$VeD1tS& 8],>A-?~v`u~.nξnDk%͊n Wo;G9l g݁҇+Z2i]^wdyAYd[Cޟ.[:hs=$bZD_FסF0#&Q B_UR~!GUWC}[';wON"&7kIYKZ߬eZ_e/OʅD~\HfnrwG{YwhOLGI*(Q]rU3)7I鱫)0xP稼*Iʛzasm8y] d6f?Lb6j0:'a<0iؾUsp^kYYjb<#\f2 !E}B2;'O]$iGK^e\8l8ҶXRvgsߗk ^3^U#~~|/v2jMF _Ht2MGs30#v/ؿm:eAHZ7m .$;X\ɶ.ݘ8o,lZ{7a*maGO J^0X4/8EO+bOuBVdI[c7=%:  Q Q Q{`! `! 5LxGO5;P Kc VYM`6"{uEKvdh}Ks׈uգV=HKq*v MN@cJkKQ ]<]#ΰf$i6=~S9RD8nB 㿘s]3VxM_,:FPTF_YFfZbvo/h(>'%h:O_S)u;ts*u[OoMUñ];w"D.g w1$&w P eWΉJĎ>;ZfF\G!ae7qc9A`@T n3o$s`Z„=-3Q,&2 pT@ ^fx 8҈h5zPz!Pډ5dg$]e-c:].3]?`zOKvE $LYlHP_N/rUn*w/oAUdw EDKȸئxx{lWuGou֠n}}D6Tur>Ձŕx{$b < e;ΜƗ{SXuzID8dum9{Zms>i09ؽꈀL7ŲOx|Z.n,/zV[1|H/Ikj$g#qO-&wAŀwoS O8ܩ] v2DB_ޛI/kAI= 3SF@Y}/`bF#ctQ)}0)g|UWZ~A kTNF0ӥk(-w['K헍Xa?rV;JcQR ,;x3V1򻌜1{A| e,a•,~Ҩlש[(Bt*ѿo*Ko{*enfa0"9,""-bsHi1QXE=J7_ڊ?Ap؏F" cY{c)?e?A??-pp=C!ARu'rht$oqHm+hҺ2>>Ϊa_t<&`>/yV2au%=Վ'u}?ȡqm}^۳OOK YVN~Phե̥HJGj1 =Zo'P6Y\rEQjs&spB7[4W1WUg ezj,MB\^T% 0M^E) B iW=6_q]̓ƛPWR%ސ[{meebKk)ӣ&]v&п Pv8:+-n z8zs}jmslYYPηg'lۇ}8lۇ}`ap>&s;s^{};NXހ~!&|0 .&1ymr> K(`JV'_.tW;͋9s5<3,x((6g%Y!QTtBA؁g"ϲ;e")zw #ΒuBdM嶚Ve.bɥΆjR$̭5\X6c{6iY`OL%3Eu9wvXDWBX ^D )K11#>2Gpg j`35 F @Hq*qGmG)ڱĩ ]냙JhZXj {|M$yN?]$C%D0ݲ#R=S 4?bq`|n@̍+"Xq;fB斮s2^#;W#bIG\/I.܊ٟr鈏2dF-O[u7P#1ItW"d0uݴ& !WaHq=ێS](Jq(RgGQPL`8`pF? F>s8n]>ʀ3\$ <131va\CԬ1G RSq:4VDگ3PwŐXW[iѼC/Qg\Kb'|*Jp)i5IAIAR$ 5" ]夤;"wQҝ'݉ˣtpoO-$tp8n5 J4펩гn/Yw' /_;cCudIDIص$kd8pi>@"U].ޑ+vn=mF,<:\j2wbA{M@#p:eAYt #|ۓ}77n菪n!$m;(< c Cpf9`p |϶KtJbqg^4Rߐ0+4Pv$ڞ%s^mHhjc2zDDr񘭧9uq_w3t x' neʼnsCx-(Op<}`l}Ѽ(i4D)i!h*>u[m0"~6B>ㅋ V a0<_$Hd˶ZIoɌ=\HS벟n2*se[9[tx9,IzQ/wo><\foor-_ˎ,);bfܾDR4q ]wwN|^Rz˙\^!dҫ^M#NԅhHCl#QbCG<$w&88b#޽oL[jB¼pfUD<3c6C qȦ&>Bv].3(bᷨS(lsM:/_Be}(¸,&Q*q4L|ct`KE""bZKCi0k'^*''J6u 2u1-^NmPڧ1Oi>6)AA{Ťln_Tɬ?.yjz'^b z{彩F.Z"ypavsN>ةx&Fb|adE3/Vv&VO:h澉_v=,[AidIb,:{1`\X趛$Nyq J;kJK] !zTE?\E] TI%=(a`!mF![D%z+pYxq'qJzi./|UsVju>ml1J8J:DZny}ԡOu`R+iwpNїH|]=љ+=iƭYChlGMx$U4SUæSx 7s]=[P+9)cX3D/M4zBuʵLh:ɺ-,*V-ʵ,Rc1ձf˝Y>0yQs .4pDTֲK(q(dORkVL,va~9f'#Y,,㩍!b^Kc/Q)hF'B G-̰p RF=j4H't /KK4/PZD}WyI4IrP $ ґ1~Y:_=B}ǻ$v'Qpcmű8gҡdC e/ q=#!Ưo;K:MM=O<<-q~#Nŗ{Cѣ* 4'?Si1dpO]F/^}bn=U&/Kxzh<"֦\e~{ĵgH{൲G$&nDP?b>XP (D2|e1#d0LO,Jy&i36Mq9AǛɻ2p)r9m9@Gk-3I zZ3vq== W[N\\ԅd9ϝ`Al #ueqZcud k|QTT!ӓak3X54_W8t x t@O t@/L7扁ӚI&]iN%.j3c-q.䣤t2~IE^(vrKxiOb7.98# t͝P$v$O'#T3) ɤg▿oYHL"vs >|%Af("a@/4w?-cE~j~+q&@pꓸ2;8 t5$|T'I8~0L 9iv]>Dbvses?.#gmɜ#t)-r; \I2EN`&1Y[1E0*h|w[:5y5&ԓچzx8{uҋel6ُaqMN/3z9>q5{SKgt/H<,s%V)i:;8Q$Nlm|'`2Fz(l'!S&_ӽfh4J[ܽk}^vW6`rPūg l~<+ W!_ְz~(?ֆeǚxC@ݗtO!gzՏ x[(yW `eg"Rށ8S.M1=e9'8QDqBαù@KkIi;1s ᦙ{0ӷX*j?Wø|5Ʈ80k`? Cj;pj?S-UqIaL~'i}'|86p±96 8DZǺs:A 50cf)x (-x`G6I .ʵ  N_UbḷvTcsK߰~u^co//W PsPZk.VdPc>JfM oUVj =1h:Chfjw䰝i 6V?ƚ``? N X#"C50c'X5˪߱セx5˫qB7GbF<j3W--!ȒZ_qwDmC-0럇Yl%,~ryu lo +,~t n[L}#0í  &'o"p/6ve |w:~,=ю_ $,?d צȁKrw:{ʓ,~ @'?fwC C)0 . 04^y߱L 2ziHze|1_̛ae']& ^4~m Kê 毷jY5X5uWy߿~=_2=A̾2N=4ņVaᅅ'[x.<|{բlsYcp#R *+z8xtWښFpX鱩aVӣM8F=,NW_ ^5Vi,]0r'q݄ ?P{9ѽiGY( DQmb9|erb/Uk`4=OKto^} nҽB|zOԫ~]v+iB*hWge>۵YD3 `Uї F[4 LDt*[-Rq`X6v6=[^oW4޿]ioLAp߹4f e\ xiKfʗp( mˎj_L;~iw {HB'nVnK=vI\&UgOk1PNxnCYՊ^kfm:~n0_d(g&s.[C.vT ; z|i`(yOт-lLn<Z'j,edAz]I5f-&`lȮ[Zl #ݬ|Yͭz@i؃JR͚(? @42i4!epgd 뀩yW}Q, )FܢA,'آ|zWEHa2(l8,f=b8Ǧ2*sH(լpXW[b'?lO.,=8 *bCހTBr5ǼMvG[:9cjK32Xqizq^}oNR䥧 )whYKŌ^eRƚ C)7vu*f'ʴM䕱M?њ՘qVͷAsJ;p;mٚ_#6Y-JP#l3ب-LO;U ĆbX>TKvajQ{ն\>j|:] p$o3͓Ұ mG-pGB&$8Q[̨Uq-zd+pǪy0oZئcFX9@&/'CܶFFq<L'u? Z-*ba(]z yov6>KvFك# C&t6;mQ֍<Вez5-^VS_4 W ,v I% MQpH)FlI[d$m Q ȯ1mAqY}z],пG?TȺ_ͦ ,62{fDSD#~}#'S)"I}_5Jq3hX[k$RS@-1Ó@P 80%0|79̚ês΢k&p0_wrK\Ҽ9tⷐ{-pp;.w=|8cMߟׯy[)ՎGNhn $w"?/1F:Jo3_KV281xVs>e5f0?]$8EE 'LT0CdLo& ۑ[c1C]vH)xz:cݫ= t@!1y op U7-]UU SO%+wt}~RB;9]{|eADtd4e%yjJyߋjޘҞsi #qfHw^bO_r@_Wx^{uPkOE@VE*5D׀jH!҇`6fp譹6k(z, wVWX&boZ6 U5 >dP^¼fS㊅%7 x:i9U<|b ]QL*:Ut})L U*TU QtOߛ㣈Qkr|>d(v4ۣ+sFQ Ҭ e%iW:tE ѯ7cY5lpl LsډqEB ԝ-|6KŨC! >ɡsz[oY>%ń>H$fGЊrbr[`t9G&_{7z>cűi"v-sRUl|_o_njSZS ;ͦ׀GgmQ11SsT;ܤɊ(6IWSc5]5<m=2Vq* _r} 0t=y\b(G&[`LJ)D~U?.ʰ4Pw~ 7}$ԣ&I&zգVZ {yNSWr{`UU+Xq{zbqPj SVq22RxXE=M"Jo_3 %Tҡ0+L.AͽlΐaӘ-Lv`A,V%T6ɳ!3cGrumT &^-}}0Q{E)|^9Ëg>U|Cy`e ! 0*` \^% %U@.2oLw!r'W7H%L3yzgӠ"^W&c"l`RE eٲ5ʑ\]䋰uFrB%Q V .#s Ӂ\Y*nRrʌƸda=Bo؊H;i$q8!0y<}1pNlZlk0mMtіq`EdOw<$7Axf4<\D y~/PXեKU.U].#l0_'x@Ʃ삌I 3n[C/LpP{&ɜ+ gCy<) [|VFn>A=ހEaI-1+5E ".K{䕚 ?f:Ǽ$3w]sr̓D*ش=61#FQ8 [7E.{=e{U=&sO5D? _o{":#ۥؒB o*\ǥk;d,%%>(@.G|)Z[ئJ|_1# ;$: 2#nWiە# . Aɦ,wGd ^ ahg.:gM|c˧D0 T6pPS\#IE`n5tv7klɱڦ0dw_Iv@Dȇ}g/0dFl9Ӭe=]r8y}͘@i:C%y PKSFgDd6H taurus/qt/qtdesigner/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFnKn2taurus/qt/qtdesigner/extraguiqwtplugin/__init__.py}A! =r &ܠ!XZ,"]wU* aC rmM3\9Xvq*x}A='&VF mREXd[`86'PKSFd/taurus/qt/qtdesigner/taurusdesigner/__init__.pymn0 y 8OeZQ'8Խ= e[R57 ~äuc6cM;uF} pJ1g4@]8[>=ks9?T"nNc0@'J@#2vrN)e渧WuXF)+񺻬J@ :t: (*˪X!%6(սR{PKSF1w0taurus/qt/qtdesigner/containerplugin/__init__.pyS]o@|W%iC)D RTU>Nܽu󡒇>fvw<;DAĖU@J*;EUloP3΂;ߑJkn KDHw?;~`sm P=oH Fm`Բ_G?W19 q#XG:Ic'AWM5}="=,Qg >4z\0ʵ~0R[%ְOdC]lnsIеqh%5 bx}^<F2X#ȷ.ˣ,cH6Hjwum%8YX0(3ogS0@y>S~1(Jm*'US$ڲ(0&^Ul*M_8?ZCYarjȅDMv֢^hHC li9Rhf-em XX.^ <7FhQЃ{#gVD❗ h-= -'&W3T/t+𯜠>v+5ibހװ3V{Qh`-6<=E̋@7KmKHIw pL@T>@.gjұ ,46gɰqY.W䨇X jc~fGKogք'vBf90i {HZ(NҎ _ JW//izLh0C^rt໌34'4lNh1HߡY\X@̌/PKSFXШPx-taurus/qt/qtdesigner/taurusplugin/__init__.pymQj0 +|)I` (PhG 20^dfOvڌ$==K s WMk)Ě5U-!Ois#;LnxP-!SaZ5%xUpu CuXÐ`:͂Yg mzRƷP5X|gSyK,=N*;sj*5|C_ x/kXZ0.@/v<|g"t&B!RԜ29~4 /V2CHN>_p֢PF!D]FUրxaPKSFu}8:taurus/qt/qtdesigner/taurusplugin/taurusplugin/__init__.py]QK0)2ڂd'` CDBl5&r?lcS.}'j=8b*2މ&Uu8- !$~J0otڎ?iJFk_2֯^U>EtnyLĔm7e\衢H&3!eϔG4d*mކ$o_t +et;(' G}.uqaQw*BKD_4W4]ZƟg(QW4:w1;Q4ozzO8CP3*qF9S@;;ߎ?PKSFgDd6Htaurus/qt/qtopengl/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFLo}taurus/qt/qtcore/__init__.pyA 1 E=EwUMM732JW* cickkF=EoˊLdQ>=4W̗0Nף+XZ_pjPKSF&z9"taurus/qt/qtcore/model/__init__.pyMk@{ 5MB F1`R 䚍ٌTu)R `zJy(GX&Ѳ#1 b]̺np) AlS;]<]r&āst_?CQ8OFE~45hq(;o{P/8[U[V\'wmJ-Bo=rjsaN82~/M{^v`Ǯ-N>[#y1!E =/r8no"Ch,؉Iqnnbzibx0 3|[>@/VKlR<].jp֫yLB-UX)15pLF! 7[z6>8;PKSFF=0_q6taurus/qt/qtcore/model/taurusdatabasemodel/__init__.pyMk@КMrH`AyGޯyٸr3>d>7 `4$8WJH32=ɴb:xz-|VP%$ 5Bj^p|C2+ QOC?[\hCCKJ KC~/۞ƖjwPKSFҦc[.taurus/qt/qtcore/model/taurusmodel/__init__.py\[o~ϯbfE[bOl˱xf -R[=}[UdUrj^ź~iKyz:ut'u˫ q+3<@Çq >=SM|LSfſO"oOP_>|"֋M٭ڟa]dm{r]m_5y|n-"*tܵj+tc6ۚy3OskL_= |$`!@ ~mU?AMS5P_MͳNuUT܇UqC5e^b$TUyg6ްD>w8=}e5NM_`w7yZIdU`ͺy7[-:-wպ*۫Ɣ=Rc> e8^UŃ2,rSPyޘuK:lMxYtB+m^uzZ*B[x9m\XcʫjS3UNkurXߣ fiEZԲ^gxs[}g?^͹iM^cU(VBey81á@-tf c^d-IRے;Տ<V=Lm ihd1c e@?u1[vˁ5H.H/]A`UX,/l%}Ӑűvq *)L%RVUU1KMtUo(JEƼ@PȄ')XRUC~ӭ{l۬oZp~6%N٢UEu4kB!y .7`g<϶wYY~6U_n7nLe zV%ۃ5bAޜY*- d7ä'H1Be '~V5% 3ԤŸ>0bc< 㢧i>6Y]S};'x0%V8L&$Y֚5e%rӋPg;~]v> %7Ht PfsKq488TblrXڌ-rwٟރe*<[,m_Sj#^W Ld y<>,r}QyRZ1o+0"sv{&ekx~ڡs4z<ԛKW/nc8ф%+Z&; QM-quf2UXr3ѷ%ԏ֠8qc@Sg[iUAoHTF=wzW d[|O| s/7ٷ|16۹Jn*vDZrE. ;\ܘwv 9&8162Wwƃ8Ǝۺ[6+WgqIz:nG`UU;aƓV=Ե+ ҈vbiC ʄ9oE (RC^xi4M1@ , AZ5 ;HPj] j'1D۷0& Z wyRm"+G2`=;\|r'sx`&aa BR(WR #,0&X cW8UÅ Bܡl)7qΛu)7¹f}Ekg2ӁԳ3F(Lp86bn*m3S{C޸{*ly>#yO}xQݠ[ N*XlJM^ثj<heFOUc 6x< oyUGo^}23W~8=pzĶ`mDS+Y !W+n۳ TC:D 5$V\;>'ڳ7]Us$it"V3d5j:>BZ "%QSi g2;W,+=u.%TigJISPx3ñuM$NG C9jb:mn+UXl .(F;cDW'#!UڵXj6&ЁH& hʚDx~PЗ.:z)TlGX)IHIT)C@^"*qN8 !z4b!/pn3$7J$9T2\K:;* >՛_uT}֘ޣS6˚&ӀeAMڪ.V# %V8>BRC)^U7O־(ĵqUۋ.>ZAV?1S@"mA_v0uĢ6t-F[5CDv@UUZ%IG+PM{^$N#buH;]W<>^1U9eJTiH^5a2W'xZfg*䨃O#ToN^f< AΥ)4{ܼ.ge]Hr uJTbɷ˶FU]zAu4~dWRP:/?ckdZqfu^CJb71Xdu֗D|%DJ1h%$JH0RBJFaq@8UB83%#Ñ+!‘ϕڅpJqU νAo.ND {bdlkg},j`* ;ޖ)y5K'n=WtFJM I[}]C"y)J" 9m^ #|o4u% }Ҋl7SI e7OgZ<\նzHDbenઍyj非̞7U#;8o~wSE7ӫ9(i_`nM#ln6_>,X0[q)7TKC%Jý̷t%مxSE7x4XAie iQ=߽Y)5? .j>`+>AI< $a?(Lu- oJw`>{0@4kWV @yEXw;ZU)cXJn/b2NREB`uI. unS3 soZ~Vu5@L8a΂PyȖ~"to*So*^ۊ͹7 eOM?J .s|h׵20nϞagS6LRE=45bրXEh!K5kEZӧzĝz0nWhvRr੾k]1I,UӤmT)t3KRygŦDryV>Ren?wyWHT'5f ^3PN>LmY塽7H0.p4Yx<\1L̓{_ʪ:sE,*Y ]?v|U~XU}Sy)xz Y,neeG]>3)!p"u,# DʺB̚g7f &ΛHɿ;&6 {C!ik=E';;key`(٥">MvwY {\45 UIgPVύɼS!t#svYA1(`xў(ܢpnr*ud[ pW_|8^o2mR>4:xN U{NNA#yiDVAB+ -?eJz9go*x"cWS( z<Vv|WdX6] &;fq~59]~:ݛ;Sβk1L#vtF* ϝ0dֹ#  ֶCۋoSB 3 jP&Kr}H^|.f |#+ lؐ"@Mݮ2ȌOCsT>UϏ#m56wيyլ͗@f-.=. !wbeKgMOə+4mѝY7 ]I7! ϋl\ެ[hGm[GG#<0 e < ]7a5s_Uw_7"/t4f^IW QX@6רpqKi؅_'6sW}prʎ;aOΪi &5ʮdBgIx[ʭGw 㕖gx%S;䮺ʾ;˱U@'zZ#D,.M ?sK-DOvYINY{&ע,1>i:m5G wOց4+8*dr-I=NWd*M'ʟ ua{2QTƵMɚӢݘ` [V/ݫHW~ B֩5 _uy(]ԛ[_:?E]t' '>Lzw݇fHi!]&O~DžD=.lR믲;ȵ;r)}-UI̋RۇcgI~ ϰ9=-(q;qS;vA3 ݡ[>O&$cAOUjG,Ľk kֶxNb%ܵ&d;^7.=Z΅sC ٔx:M/ I'/dUmp}[E{AUQ<Bz- nRGsn>|jڅQtD-_SRn֊WuNC'rد?dK2X 8.J4uwӻ$ #M2 #@³$lj%LpWUg[g5| w/ ij7Nà_?doD<}i0Cy+9f9q$~wڡ&(KCN2b@< {w{x0&xzY3Dt'&|q{_|IM(fSr De5K ,fL!g2hS,/R6%V.ɏ` d8Nvwl)xhم{ 4 ۉ"-K%^k޼n <6[ݿ;='oYE!N<^un$o,B;4/`ks~bG8W{V!&PbN7,x *oX*FǂsaCmG#ɶʍ{8J4(tWch~:gFz0Z/8:E|hGW5K<vKSSXӄD&3G2䶼 cn Vito,q? n=m#_zn1k kk{ 6Yv48Hc1~,kɰff>]][PKSFt?&taurus/qt/qtcore/mimetypes/__init__.pyn0 }'jH L&dJ֚&bojvcč4 QvvYsW~PK42NzN2GYKs[iɟ4K!Va+!vPoǶ6\:עag.<i(u$OqJ_Q0[QVPm/JFq>_>fbY<PKSF٥nK0taurus/qt/qtcore/mimetypes/mimetypes/__init__.py 0 Oћ' vp؃lhjfmO76. d0!Pqs'Z"S4Rƪ'DY[ dBPq=sv`tnD%)ÜH"] ]~U$ye_;N9/,KI?( g1c PKSF[b1ȫ'*taurus/qt/qtcore/configuration/__init__.py] 0 }ܶ WAZ[-vmMӃoo1pB{*hק ] M.aG5AujcӴH,}?Ѵ x xTյSirf?7oôi qv7VOy6`f$zͬ?d>6!PKSFQ8taurus/qt/qtcore/configuration/configuration/__init__.py] B1 E~EF\\J& f$e64mBLxTLXL5{Ō 8S Οuۃ^{1K^7 Yp~"(یyPKSFҰ2 ,taurus/qt/qtcore/taurusqlistener/__init__.pyR]K1|ϯK;j)EkA*"!|͞\9Z_SvfaHI:q$wh<1k2B5\PKBHx}O*g;b -\Qv!5foB<$e BޫTHc4djmy6]`܃VI>PKQt r@gO6KXG(=vAn#Pihd8 S$Hʒ)8^kɎRbr`MqL_ N 4G\_> ~oս<灄q**BZ'T;H (j%kädzb)MG_%FnHֲdqoT/-JN$PX2RK/zD;d`RwkMn-Jk>{fltHHM!]!ICV&2@ M{ʘi-Q?ApF39-v iQǪ=t}?nfھD؏>3m_"OA>!],'CMF~+JE|kfZD/iqXT5&%3PBds ҕ)r-Ni˜`yPKSFgnv !taurus/qt/qtgui/model/__init__.pyVQO0~ k+ 2` R Ti"78]6~g7i;0qRHg;qfy^ziѳ%*5WtʔUM3;.If^={dPG)h}ϢV_96Z=K5Ɩ1ըRZ PI FPh@i,B'DD=5pA?PM β4#-:NԬzuL[7~~Lc -~lL,\((Jk rMbKǦNMX,Okƾ8+r% 54ޒ֒y:.uP5cX[xI-s\:ڷ|Ŕ?8vqIyvtWK׈KԄm_7mF7ă&euWX<{t]?ϑf\$'\;@. _h4=PP65J󇯤\eWwk_cG֔JC2na_me9Hӂ\SSIPKSFl ,taurus/qt/qtgui/model/qbasemodel/__init__.pyV]O0}ϯ k+ c R 14M$]$-&s㯛D5I"THb&%eM^MI $Ny#$k? Hy+VNuEQT]x/jVBQj8 eJWDB,8ȟ!*R<;#~9]7T +R +YAoNWq&Kǩ0@nUR=asDw5a2D-R"Șa 1`fH|nrX*!xWV.2/K}rt>w&&Y5 P_}X;FǏ7kZm5fjR_F3[dO`?h8oc8nh~)S6A[r]^g!虜7O(O7\Ŧǯk!7\9j r{dX Ki nTaBNrQHLo}{|v05(vKȹeԚy>t8 +bM|:ȕv9VjK2!2eihMkHkt۽YmYz PKSF'^'taurus/qt/qtgui/extra_xterm/__init__.pye]K0+r Xvv &"!i$ ޳ΉP=ysZ3\*`%צwm-P;˪8e\ AB1b |CzSG"Χǒ3~G'):=ݾQ,.0`grX6+AYZbRmK7<ʢ[RQ\[*%qEb]![#ݍtt͑%xRףZ7_^72 KƾPKSFGR4taurus/qt/qtgui/extra_xterm/qxtermwidget/__init__.pyMK0 R { ꡲaWDBh64Mj2a來OyfImMO=x+:X.AM걫7erB K$cq[ jH NhHP-B~_dft0:L bcuG{K̸ֶUq~ΜkUao oMkI4`i7eQދ[W߼W6y /3!Z&ՀQ!Ip)kYq-C>=|vX3L30Rжg.ybqOy˅PKSFtWۀp taurus/qt/qtgui/base/__init__.pyWmo6_ek%l 0xK2 +tq5r@K'E*$7w'ǶvC틭{{xyrk I$ee*+'N47^I >S&IzQuGЇ#(eHUܙ9xZv٥#VKL(#/cVᷬ,7{+ǵD˘UYZV F׃7WOgn$ta*mi91DꍽkU&<1=^:k;LQ\[۪N'U¹`ZF(IPF_AE^k^{bv.v @ `;zLѣ]:AܘŻ.'snl)}vbv_7׷~r3`ml)T+Qe7QIEGD>Mo5!݄V9=s~J| aj+u ]-:|ty>W~Gݹ񐨫WMӨ1~DUa{tEL3w[e*-e8 6!Ǧ8[dK :' <̷t$"oltHqn߲,]$sv}z*gPc"5<_r#uҹ0"坿EjoؔPN&O%O\38uV{x2]Te4i빷昁V'.k籟?'PKSFcwc+taurus/qt/qtgui/base/taurusbase/__init__.pyWmo0_/Vb"!$>tkڭ2BKjvsg/m H6{l?%eX^c(+m\TZUVܣJ~nlNguckS>\90ןQD۟zXrs@vB\B aH3]&\hV]% K;K6>n$Ďe[-0FjҶnngBmr^Kw㲦}bqp~z~Ir&o'#|Jz\sF\qѻa,Dڊ GQ@bP*O6ˮYU'*tߡ%zC}XcTOצ X 8ҦDj;%AWR-zf ʐgc>2F:n=*S>FўK)J8ДbCrQԆ_H8$eXsc½&](A#=k5o.ǃ:LMx.O K s}9npbYx@v& QqٲvSfg@Qx͔qbFH~Y荺0uꐇ,Mű:p'IX,?@S R_G4c"[A1a9'US% Ҽ`o.ށ8s7"QQ1HԲ4a+ɗƪj@U+%7M]`5+C n;:-u\edmJ[{mulnkZSo/?G]|NMH=!-B^x;_qvPKSFG 1taurus/qt/qtgui/base/taurusqattribute/__init__.pyVmo0_#^Z ^*M:+\Zk]lg݄v-$|ssrtABQqHR' ʫ́nQDX9^ڡQ\־ZEkGº^A=;i[gd=r5Ћ*$QaNE1K*Rɭ oNx\St\% GEN~TwNYM:S ;'G1@`,hDx86":I^Ovjc*@-YI;yoIUnW"}@?<*JzehdөlD#"↨l~oPEso|JXW[84 P (^hjТ*/geogt}9P6̩[m]nqVeg)T _HhTB_Uh-`Ϥ- ̯daX8U)^{[xHJmt*&P90FݼSur=kx?M:F +~Mr*[9S4BVBg"/q#m.-z ƸS$8tM演nO\ 0-ksGnHN rz䔝0cB W}P͘_m;tbqwPKSF:dE~1taurus/qt/qtgui/base/tauruscontroller/__init__.pyAK@+ǔ6bBcVADm2iC78-ME;a342dyQ$^a^S˄rS ly"#?RvRt8XU]1KT. րw+^[3+;Yeʢj~gDigtPKSF'S#6#taurus/qt/qtgui/display/__init__.pyZmO8_/{i[ölB9I-/~3N&M"(DBό{<_Bdx^DQsX<8ń ZX7FX: {^5$Q޸2%l#`z;ř6qV*$_4/ĈiPLPbAdT=k;"ęۘLnXQSgB|M4_3_R~q!%>ejK Wo8EtGY?쯶B`Jׄ'tU`i z b`PmOu!sm0-DuUN J8AOr kgee#. }EqX&TZ 'Z;G4e3Mk4g/zB}sBCv*ܣ,[w$QǩtH9 S៚ѽSTxO6"71ぢLtD oXd"lFA0 ]:xM3m Oik\ f`IlՙS 4 π'ڛ8w]hZiP1tyu+`hH^Lҁ h˙d"*0h7gHQ*ܒn_\SelhZRH\wʏ~bQy4o>iѧΉjN:*FDѣ# _8DbH`N U=4ʼY׈Og0\6N0m.hL`Uf*\ٌG^#(vyųl97ı.SK(aCl,1 ]KOI< 3рj d ax4c8v49V DA b)TK+GR4`SŐR}_2wDDxpゴ O>[˭EjTjQD \M5_Gd Jz] Q}Aɳ)'ޱ+7^^0tbt4YײU*Wd߽mך7ꚿ5}߫5՟ ի0PKSFw)l(taurus/qt/qtgui/display/qled/__init__.pyTnAW%" ;% 2qX,;QZ3ТI/6򿧫gN.EzUzYh%$Y84$ID ͤL-S,BPj= djs_^I҈-uڙ-hIymMm>BΌ={IlҨjf,섭-ꤠLֱrjLY:bl(*|h2M_Ƣh 긽0vcᬝ}ϙ\17rm\ 6-d>|IZK8d 鞜y<(<`s[jҷJPZGi8X2i݊g2S}r̪Q.15+O<1 ч]˗j^ƉnpRRưJ+t%}ϲ0LqԿ?g) wܬ6t Y]ܬorIv썺T@u&Tx ^:̝̄/w%v%W4s.Qe**1M޾n_ԻP3wkyۿPKSFgDd6H(taurus/qt/qtgui/display/demo/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF}2u:taurus/qt/qtgui/display/demo/qpixmapwidgetdemo/__init__.pyMA 1 E9EvAz9Y2c&o{6Aҭk&B\m][iI[]_I4K]˲ִŧƇ|;=K4GPKSF}2u8taurus/qt/qtgui/display/demo/tauruslabeldemo/__init__.pyMA 1 E9EvAz9Y2c&o{6Aҭk&B\m][iI[]_I4K]˲ִŧƇ|;=K4GPKSF}2u6taurus/qt/qtgui/display/demo/tauruslcddemo/__init__.pyMA 1 E9EvAz9Y2c&o{6Aҭk&B\m][iI[]_I4K]˲ִŧƇ|;=K4GPKSF}2u6taurus/qt/qtgui/display/demo/taurusleddemo/__init__.pyMA 1 E9EvAz9Y2c&o{6Aҭk&B\m][iI[]_I4K]˲ִŧƇ|;=K4GPKSF0Y1taurus/qt/qtgui/display/qsevensegment/__init__.pyn0E~ H"]⡀V"%t,+q /QNܙ;ΔBR*KEqT$Jd+@, v[eu|fO[Vj3z8ꮜ:]605;5^K꯷ɧ4]437$yndyQeH:|"T_iLĒpMnđgeي׻f›IAYHuATr3:WҊY>R);odIߚ5Z9u>XG:nB9[M=ޅ d?l}.-PKSFd²1taurus/qt/qtgui/display/taurusboolled/__init__.pyQO@ +HQ6RԠvi"\S/weٗML$glgZ~g4cK\Z2\I/sZJByS럠y Xte؝eZj6x=%jşZo7 MsI|KYfр 5P}& hߝKueeC BŪ^Yx&'eMTU?d)(QQoFr4xЍ(GY)^ &ZhYݱ6$sp.M0dBt/8^q?cQt`pv7J)8е4!'tƴǰ\^;VzJV=fmeִ8 6_3$?tWy(P8QIFȣ} ;e#wgKV WLN:Tq/[QCⓎL0.俺Eu]+D@C^צR[UH(4aURGxes9lKh|kSSA&(K ű734lp 'J7MY# sl[@)M#kJ%_CޠㇸSZme=mAk)SFQH*W=ʟL?PKSF -taurus/qt/qtgui/display/taurusled/__init__.pyUQO0~ϯV2` [PĦiLrq:vf;tm  m6-KUg6@ϓTi맚K -WҋDeycbzRY4-h~ͱƞ~y^Pɔ#pduxBG+d#4\VmV*6:W! 5RK{J's_=>BL3a?B{Au*JÐQ҅N<*͔Fqa}ΦpI|Ka̪jYIQ1 8KmF\O(JQ:S脿 tզʾѬ0~~xuDg58G^0nw] 79k(Hʢ+W>xtέ"{#gR! Wd9Au  C[ʟQ#NT>AcKF섶s|h7N(tdfpPOem*2Z?Mۘd*1,pJp~wVPvh(i?_XfɶLKE%G3 n Sɮ{-AegJƥ`6u)b ⥮Jء/ .Py,7pϢ1ܺM;>x^g۽{5p`ڊ{~8?PKSFtR0L -taurus/qt/qtgui/display/tauruslcd/__init__.pyUn@}WHPZ hܓRB;wݽ3vT*o;gfS0Rg( y^(mBsiJU| h܆'^QlX3pkAK&6^ 'hoAUj%h &kv)6+&3UVU}WԝNVh_D㏳=W~1U4}Nd0u[U{pE,/3LA fLX :QA@9O2°1xӛWhehڑFp ` `tHgM ˡ}dgMAyd3B6T-@־+GtՀ]]Cm ~5J%Ϥj5+il8_Zv>oJLK򜄇1L <,Kv! @R4=9=SN rzYc +M eNXeʳN{P5lcPY$hl%(O7̡Đj'ScRu{?k{H'uKE<^NPz߸*wk&5I7nv||MPKSFqv /taurus/qt/qtgui/display/tauruslabel/__init__.pyUMo7WF$;+6 ɒv7(]~+ie;@ay3|<S%sǩ5VARR(& beGru 'h4sCq{ q30*3sJgڜwh @hSptMDgL֡S9WJD&4Z\E</̣x6j_MGuWA9en5R1u-j`L{tu)iERh4VjMFIA5}T gboXyGH_1VIޣ=h{#5c&5`$UNwMV@)͡u>]}gΦU[{XwqT- P)_SwԈ}^W"|ok $!˄ \I _Z wmNVN%]{GbռV6ݛ|y!o/7Vs-!E=oPKSFȲU>-21taurus/qt/qtgui/display/qpixmapwidget/__init__.pymMK1)o=aHnhL&Tݵ]Sxyg&IU RQe @}PjSƕ۟+Yc{'T~ L0:yVo# v[ҸܒQVp?+;dBJc.QmyrC(Xc)+4F/Kx fs6V.\zE2>FYvw%+Cm][g(V,G^.tѽTu=ac2 ]{ީUUu? fǝ?j/3`;oPKSFgDd6H(taurus/qt/qtgui/display/test/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF$ L 9taurus/qt/qtgui/display/test/test_tauruslabel/__init__.pyTKO@WBH( q J ${^MAwfm'.^ f~Ȍ.8μ8R-PQ8U+ ^NjxJp0HiN1o݃F1W?FJ ξnɬ½H9ZGuBi+wt[(_bc&--Y \K2Ajŧ`-p/@~:gP`Dw.#rs)B0E_cxQD$_d+yν # 0Z҃?=½7̤ef ^-[9>kzgn*ﯡ6 흎> lӑ 1✢Fr)JEkCBV\Ԁ%^T,yF{Vl^6fnD(bc)O52]?gS)[BIչ;6}RzlKAfLt9Ma.7>ԎK ֧ӪRD}1RKO+Yji'[C=Qbz 5? @2A<[&lX0!qE[?PjG+l~2)n@O\@U]Q&&:0c8njo0~3s' ]U_?|ŘޔMG-H-i ~ 7/k^=V 4taurus/qt/qtgui/display/taurusvaluelabel/__init__.pyTn0+timMP?ںr1`~(N 6%HKKӤ^"'qrgWyXRpqUZh[9Zms<~ kq@~wKW֝#֬_<4^~p̖W4alcM7o1[} }!$qI6uZ)w <34‰$)tpo?Rsn-|MT rH+ڡiI⡁(9:Ȯ,_-H n%i|r"IYp#4mzLB${4LJlHH 6  JDQa,\A'- :ebvL(|R^k~%lZvŭD1Cri02F*wхa3=m҆n+RO ChK_}z@7ztzy)2E>RloɲR3iWdZGwMR] }3lm_bvZqʺP[]˘nJO^YwYNN4?PKSFңy2taurus/qt/qtgui/display/tauruslcdvalue/__init__.pyTMo@WRH"MRKITY[{l Aڦ <}ε$ɝu$Vin5YZdJ6!ʆgX^IX3GdAK&أIApc>uX'q|=dus|1)]L8R cՈY3zAnq?c-OoOv|Z?~"00SbtAזXv*&< 8! "=mN1jTkQoH[͘}k.s ĸdl :M46\-Tz$ka|Ǵp@ɍ% md1aLb*كlƓI;ryz +Z:9vLW nwHAΜc%s^\Ci֖tD4x[R6[ߔxr˄n (RO$ I0q\r-cCqK7VNfM{{6GXpI0T"f6_K5xfYQ@j)Ϊv5p?"z#:ϥ5\jҦΐ};H7߃^Fi)OZfP3뒡YIsR}fmwP{~RY;O~zkx8xPKSF}Yk)taurus/qt/qtgui/display/qlogo/__init__.pye]k0+rns/2T#6ݿI:aW=sѓr\e!RKÕǵB:KhB[P@BG+S>8foߺ[7!2b~ޮ TRn5BJg[3¸35g AU4ldzvL_| <"5L \Z+zzՂ'_2WHe  /W UXoixY %zcRLX1 F4+Bd4~:A@sENMSl)f=ұ g9/ ٛΖXtcPE" \,Z)pɭ3儞݈- X9<+^#qT5"9Sf}Pra~nBZf?K [!mG]/hGed ZgUWD-i GESd.*PBiN;Rro(V iY83tc"DMMɰI۶k1r;(lSe7vOL^o1//PKSF}]uV'taurus/qt/qtgui/extra_nexus/__init__.pyeSak0_/Xòu[W藤 !]32Q,"K4~'i1뽻{~wgڬ,@,3nREmY[vvPUCBY0 H K;-Pvj]NY.>K|B(ʔ?>gEF{U}J x ~nje[ 5Jx$ߨ [;φ -'>;Xgq<+Fhŧ<m$o쩵(tC|uCYPHZ(3kU ,oa嬧x*{7ޖ-5[+zbt١UC}(z?,B;sơ;j}\F/}:l鵖&OLPT GbiR !ـ@ߡr(]0iX:fh 8&xhasjƯ[kEwH{wŃ!T A:nbm.T^,jl5Z5[@ bZRC{ #C gf?݅v]nE|Rq: u2KtLpK\;BSȘd),6Iݣ@ zQNwOz*kU1|xhlZ,| qvKGg31 !8뇖*Om|&qFN7I̔lSE޳%R%!4PCm7:#;s׼CAUe?Bf쓚7[sӓ6zQ,H7ԲAf}qߊg3oPKSFtW"taurus/qt/qtgui/dialog/__init__.pyMK1) =Vh+E*"!fݸɚZ zryyfɬ*0!+g`QJ[\j!-Y$ZyP,k@Rt64W zK9UF.=w/:Є_]vP-UD.V3;1[4B,a5¸wa3v̫AoX5ǰT$y븶Bj=,KrTGd`)KAײ.Z2IjVGv؝+&*WڀuEay=jϭ`/EH?{_|ϗ?X{OPKSF^|"<taurus/qt/qtgui/dialog/taurusconfigurationdialog/__init__.py]K0+r ~+B l"L !MҤ0x7oNNeMKV2F=Z-<M>X@9^$c`K姗Vs~t#8?Mߦc$ "w>82N Bv^X!., |<5loKXYpAqbY kGbO/HI?>){mn٠͗X|u`lk(a_xR _%R.l|PKSF\53taurus/qt/qtgui/dialog/taurusmessagebox/__init__.pyIO0PՅ]ꡛ(nRAY㦦Ilq%)yƙRM8!XTGJԐ!CL]d뽁8M @{&RXyb _2\` m:B/aNl}˫M՚+i83ךz'|s@E(k9m O؉b<>fZjhy'Q%6FNO=0a<2#)մ^GGP=+3=I͕31>̦q(鯄*noI rӣl){J \0vĭw  6qaqЗTZW4^m`Rf#Maa?a7PKSFK4taurus/qt/qtgui/dialog/taurusinputdialog/__init__.pyeMK1m RZz`+MwcM&TOyx6x˅&LA > 8$wlۦWC@OiB 2)8ߨffgi0q cn$J\TZ SF_=&>i|9h#{yMz5' Ltxޫ5ڕ'wH/Jeܑ$,*k趣' e#_s3o|:~"(iY0wz E{ /Sc~PKSF(j[!taurus/qt/qtgui/panel/__init__.py\S9˞BBll(`!rEIc[Ҍ_}a慲ZnMՠtSjt*|(m+"UF+u*ztXں?;eN. H_Wʀ^M4όJԡY{Ѿ@CAgi@YߧŬ͵GJvybn:JlN(K5#;qk,2/W<*WÐG"\SW*"َ 2I0-RP [LEE'T b}*+O+[9@,U*O2]E}ɅU; sߵ bqDQVFqY,te%3*nmES1Gnڝ[Juy:tY*=kY ޓ5Aanjv{}2ANxcDWMs#F=:ܧ|u(99h[08(gc43ijr_-[}5jczJ]{z0tCNjxo9HHmK6w{˶ >TfXߎl>x;)WskDeF,zi8XDkc3s]pI=44yiLb2h9A!~%{P?/թ/$bu> ńK奯X:3(`'/7HL5%&hxR?6 9 QHF4N'"a{ i[}&}t&FZizӲcq$7vm"= cB0-ɚf2[[M CmN0NYDR' ̤=Fn*ÂS՘w95?2ލ&b5o J4;!N';"8Vvvҧvܲև|pv`xn̯|(gI"xfs}dPS})W:S2=U,Ҫz:8ClL)p]?qu F /kC 7Dө9\6<pQ{*]f,-g(7*9ʶu?:K>Bnv"Ó농fo> -օ+kƈȇ~}z5xZd̸<3 /dM(vhC12H3Uڱ~V%T;#ү.soPa&(ݪtMpNok@DxFEy yM P0$D桻~ˏ]A:VJv؄6iP$G8Oh?xѵ8&l904rXY h4Cȯ_0,,Q"/}W; ea ׍#:Go6PW62Oi{+{V]tg de(ݛީh+%8fvL*̖־Qjw>αK&7~!{ww3 5 s8; `e#q޹Zp7,w9 Ԓ(.Kd)~͋Q|<(ʰa 湅f^^ $[Y+AwKښ#8eqAq$¸ c}E(~PBD8*\?j _Q =8Z^]$gX '3^FR4QK2y:x"M_N hAːS=Րu~7!bY?40cm9 &4!> F2Ȥ≳A(A&$0~0 $`4RֿOڻэآH*#̀9.UQJQҕ ZzUlk2 pd*s 9iv&3I"ޏ`D8M_dWię ܨbxd+bqItG(,:hQ{`TVISۗx}gcrT΀6kʖw%ǑMp}hG:ڿtҕR ׊| ۮLL??y&?y\/:+VK]w~]nU:뜑i~_?PKSFh} 3taurus/qt/qtgui/panel/taurusdevicepanel/__init__.pyXQO8~ VRn9}(mY*B w:En2M-;k;ߌҴ!-yx2o2LԦ|Di[M4QXdeb,! ʙ~eNM,hDmگU _O)>zz]=H|W u?qW'`nyc&A  =1H;O`{+4Yf׎]l*;*5 h ]<ŭ`EH5ڷ,nX2{1ޓO{h}ޭTǽ=Gj5-i =iohNx.WZ{;Z㪣#vQ4h 3;PnVa(N5pbh|hN]9CG6G3S S#-:s.B 2+.C8ưEZ2}iN [$Ia3P :s&#= 3Q h=PgQ9R'odu89bDta&B!Sp{(;J(M>ȠPrÿo!|CL :[9Ց7gr?۞ 1b ,y{dK>]qB{~WLK&> c~6-`CC:'L <,Ija:8@Asy'{\-R&GxSBCT؎3CjzD"_pAJYKu!ghI^nIݒov3K"#Nkx6-4ҧyWV1~vh:* ]GzkUwAƿ,Rr=1@ yx#<cQFFܢC3R=bcx ؄1f"J) pt;}Xn6ف4 I s [㉸vo{gDu9TBiPΨXW+zy$41x}>Y~'?}7]PKSFI-taurus/qt/qtgui/panel/qdoublelist/__init__.pye[K0@+냃UVAml\{^6>s$)i1!e Bl;c=f^a5%!qi% J|R%_E3jm(JnnjS9\d&av0`;D)`fnYKŭsJ&Ɗ9 o3Հv@@#=Y~y{ (cQm'US/HJ><&=¡I| 6~}/PKSFQ[<4taurus/qt/qtgui/panel/taurusmessagepanel/__init__.pyU[O0~ϯ@(شNqNod3ZU;΅%-M4M荀.OG4'hzյ%Ԃ岷>SMFHB|bϨJkx .ɋ-]\uqa6_ۖTAQ-{dž^ n(Vv;H=#C(gNc!1l`s*aM',z[]\}3U?SULrQ<>:UR >Uוi?3S< ZG UvR赋VHjq>7h5I8 &>RqХK7) (3 ; LEASx(pi3&/k7n)L]pD3Tt[a¡7 uUoߣRR p0Cj`?#z}4h irAG켔ZzYSa,8~:I̠+#$Xw(`T! vM"ܗiuۨ&|=Q%߮4zmCP͹a򭱕:*9OJjFm@]4C'/*zrqG(Uk or ]*.P9Ho?%uvKѻGt`> qY0s[A^Q!c 7a4 _3qAZ*\ B*@>q&ͯhphO̴FE/1 @»OPG C#Tg(5~)Ov_OPKSF.1taurus/qt/qtgui/panel/qrawdatachooser/__init__.pyeJ1k Rg,ZHwaɚL}{gEd2g+.D08)WUm)dM]M] ["N 1 X~tK&A+ӷ1<‡MF7$mBUoc 6 UK 㼦*ͬP:u^I2w6J*sc$H,*5=rODWK؏s=jfuy֫t|6&ǝo`[ 2y:ZwPKSF|r}<4taurus/qt/qtgui/panel/taurusconfigeditor/__init__.pyQO0)Jll АjG')2ű<ƷM!=uOww]+BsHCm-I;)uzP,lI☏o`QG$J4z-ўXdYV p^:]OCrm`H|H!!hZ?ʲHLz;[kPG:NiL%*e0 e@ύ8vݝn햛J6sԤK;xnb1M .'#{a+cG;cjdu)[Ny36M0jyVڍď;ʻyM;ߣkm+w7Z q!IzŹ!~m ̼VAuMF퀎yx˔x5-vWV ÍZ5Ay_Νq`ͽ?>70U*f:-zk6^#hBr)I! :q!)Z\jɇ;kgCqw {+ /++q0sTh)in6s<7 xy PKSFbZ-taurus/qt/qtgui/panel/taurusvalue/__init__.pykO:;"[.tEcEDKi *2ijؙPi;IVB; yIH{?Hu*='Bj/k@SW*yAprdπZ$ڀK Moʟ;VpJFx-U,++qH.3*`qeȹq~jTH0j6:ZҳTCeWo JQ*Umx^C€Lg]RPd=i7 q54H RT2 9޿qΰthBE vcS5$VPu? f8*J. jSLH$k BD .fXJczC{`+Mt~l$<*gߗiI`0錑uoT/ W!ce YL@-P 5޷%e ư : [**J5 ز\弄H*63s08J˚4PECm}+G@hFQKzvoH~n-kb%P66==foR~nǟrI'qBs6-+OLXֆc6xh﷬azE]졧i^q2P8FrWW_.q:m2(.򘌒Rq#ZȽTk]끷TK:0АuƄ{>8(uB+㎀X\?SUd7QmzPV.~5OsW6]wthUjគ<2*)6 smOʱ基rѵuwv]CvaORiDQ\_A}X|޶ d!Ex#c?f2kgvŮ O-x+>ҽ<<(_ܩ- }%PKSFLl=,taurus/qt/qtgui/panel/taurusform/__init__.pyXYO#9~ϯiaGFMC aXZLඳȿ*!(OPu|^(YxI(MhxXIeb*Räh,V!ӻZ!Ah4.+0IZMCJUhk.Lw=p רߵ~00i49D+XAؔ+c  5m,I|%(4jYJZ_1ݖ6G?>4=K7l$/M k>G2RNDBFÖMu[Vp?RIa0ز;8fJR>3'Tf :G:,OSM Awhxp]3ɇ!Ir%KOs! B@h`i ||$@8_Q 10U5%@rUG`!]@Ϻ89ՙ+4+tekuRI_I''9]6a!T]t֘s| |5l0h5a.%D ;|6F4HSRrZS>*X0t( jȩ`#"R1G0 wĥ};0ԙZ(E?/s! :!kY ^]K'٢FN># gǛ̞b>ɾe Vz&l. ~l8^}ys.Ot-)moTCNWj? Rraл=5 WĊj*e>KPJr7w*nDzUvF٧ݴ-o˼.xa&2{;3SIN%_Zf(}#}iqL4L H7\/ˑRRrpLsB)ĸFKX4\Xf`h]`m;W$qM4M+MaÖ5DŽkxH~$-& ]fX.TMb2sl?2`?\Oia=_$\fX]>EylJJ66(G(ȪjGzxؽ}ޱzckՎ;vog{o=> /??{JDU6 S^}߫. ӖJslI+[`K ؊֐fJqg{glדw[n95/|zF?PKSFjh1taurus/qt/qtgui/panel/taurusmodellist/__init__.pyTMo8WI)Cb;Q+Q-%bi"Hj E:`b=Λ>E:ֶ"goP|狇~\'ң;Ud)=7`ªYs_\WS.u NQ{SG {GjVxBҏw8݋0 WOz7";;8ܷ5.r}_vT|jO|KN;/]3g=2t '퍲Ve~@;:sFSH?ݳn%8:m-q cjmdP> dYdӎk Pgb['p.#CJHքpxV@>;r垏 hIv.R'T_ 񞻟PKSFgDd6H(taurus/qt/qtgui/panel/report/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFU_4taurus/qt/qtgui/panel/report/basicreport/__init__.pyj0E @ IhEqTRQg[,LʜûWsEIJQDE^hharhUV$roQ@!EϱҔbz3]ѪA _w>hZBQuPLS&$ZKQ53|Z#өτ3akXQAo_K[8ܔVKKHrkj|T:py-rm,D]q IA sHOe}[\`VBugTX} +Ї;tAhAA;(j!.Fiiq1s| {1 2GԊZsa5An=0FɑPOT.tE:(C`d`FvfR %qF̦ZL n"j`,D?7S:/9[뀯R!j-K+PKSFS[E:taurus/qt/qtgui/panel/taurusconfigurationpanel/__init__.pyTMo@WRHR M*wmX1!ǦF‘|sUyC 4MU{FY.[gz4aE+/9|OxD`O}^Ǣ`M/#_'Q==(xZ4Dotic?]*0n. !!d 8EuԻsL^(k ,+a|q rbhU{I:vZPK'1NZo4CSI蹊y ̩.} WNKpVpmب̻@x+Dr[YV \DpɭzT]=;'mg[1ZT2||f7zdtG)J5{$]E,jGى=,wA x>e׮Mx[}Iv- o4->%AA WCUW]~)ڱ&B鷫klZ[,,2(sh,7 |JֺzOqۯ5wXU}vDPKSFgDd6H&taurus/qt/qtgui/panel/test/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFᎷe-#7taurus/qt/qtgui/panel/test/test_taurusvalue/__init__.py}SQO0~ k+ 4e M"n MSt$±=MJ5wߝ]jrmVu (2vB֑Y[N֕FЇ윋lBE1>$ `gRhhNW Ú Ftle+uFe A` |aur ?R9z Z{Bu -N}71gq*<#9'ڟݔT'xZ4TVn;m+4Q$rc1WeaQB -Bh*n)mYm Tа3:ݠ/U8{?\v#/7Ԫy270yLXG$q!B.xtmeإ*ui`K`mǺFZ!i'TQZv|n"^^S gka4f*Lwr.d*6n{tbOWl^Q#$[xPKSF)]3N6taurus/qt/qtgui/panel/test/test_taurusform/__init__.pySN@+|NJ!"q(0 MUc{z7m;qB =SO~oξٙеIWB']8d lwkA1D)9$PSR߃{eDR{a z0#X@]uYX0RI/I,ڈgD8v>U%5Bv8|nC`?.]} ?Ao W5HJ%ť;}jTyZdo䜍ı` TJvTQM`Ǝk[*jtCP=V!SNBʭK\ f([C9յvrӮ}W6)sXP.7F6 }]7հYa*#gz1&̓ft?co֝aosVͿz(~`ʼce<_/5PnEKg'~r;][VbZWCZR dMWbruݝ:iψRK+XB { BH2.˅̠/f0!hǯ¶$iLY #]@6_RCqą+v8 CHu2pZ|U\nm4K zCg>a-8o03n,2 [ 2~ZX7Ql,.tsW0rA)LȄ_116Sp*ŀ=n=& +w }䦆K)5fDqP1"6 ӈ]Mvgz14PdHn$.c[kWpF2=D9F 02'Y<IZ; ?Fb:ʠFϤç촗LD+j`"T۠%.+zļEN T̊cRAጠJ5BĤԖђgdl@PtGFՆAZ0<`Bu5i Gmi {1k9H^/WD';F9jbs";h.>eٟj48x:M{۶2)4A1("_ u{/AyvV^'t9;^xmwW0&55x"q%}!8VwT濯3xDX *4d hbT ˉ(`w wSEkS7'd}vC?pH'.c$;%Ҥ_{(g@o kR{=`.klL^941ma7v*X?s_@ SwX1CW"ö$Ъ)J*ÜO-^&\sxPY7- >6;%c3R9yWe/< n.a?PKSFj4taurus/qt/qtgui/container/taurusgroupbox/__init__.pyRn@+RH4"@K*ABc{73q $N'{ߔheeGB մI 1krRDeP56Y $|}OfYsCx$@# A+Go1( h&1\K*XN5"$-K3EE* ޼bzHmzZKSAq*Tqs&58Jxřw̾8XHC\j/PVWFk(iФ+K| U*/nԊvLl4qB>CޡřAK5NG,ѶtALE`Kv>iPnxbO)v"MŃ?ϻQJ忳,9𶇭ctGAU53<4akV[t2w·;$Z gfPKSFEG47taurus/qt/qtgui/container/taurusgroupwidget/__init__.pyT]o@|KI"Ѩ)J}IBJh >z {{. =sYW4ϫ["A=Tx۪5_:uk*CAṣWvv\By v>隐g#q0xi,o\;~F((\uVnYCJ4Z+Ou [89\X_zA|JP7@6D]A1q b | $PgH&-_fyVI:Rt8?|ML{`4?]Y_iiaƩ,fBqXTaOk ~/C|qPKSF:v6taurus/qt/qtgui/container/taurusscrollarea/__init__.pyTQO0~ϯ K+ R1$B$ZڭCXu w&L{ );>wNh|e}Fe<&ʚYW]BOi̲^E;{h>f>yVΟ~KGQ$zDB]Eŋ 9Ɩ1`|/$O8^S }ƨʅ&omSPK[^OsZM5G.igqX8j !^ڝЪJ]BIP'Sخ8@@ W^,=So?<${ԕ6Ia .-!M /JiI-uJm_sZq"­:†VυϲµFotChEg?^4m;%梩V[t56-k?=ao:V243܁AĄyK\آ7@K, +zbfiԓ) # $W<$Нzi$6,||\S!ac1 W­\:#d&ߥ .4i!Zl/huu <^"faF.D/!ᖅW,qϏP:[G&dD| C}'?IbѮC'^ u!r="wAMw Kۧ|Cj(^>7| ݖ3x 5{Ʌbk ]VlJt1bWwX4-ַ)BHn K. ATI ()$XFjSrcnK IBC-逶At oIWf ܰ~<-&hS{Wyd\U zSvK=PrbtV4\ڗ"u?I}eANGL;;~WsG l:@dR#Up6v5i?LsD9fk8=}8Ih_j.L^Ѣ . ueJ)!t./GHDW,!85^u =VڛL$R:'g;qI= G+( <,pFeof\Ez3_bLYޤVb3QfPd2yNyj`"srۮ&^GXk;ޘI"6cl]\xlcww&>ݯjnE֍ԒZ[$T?fS2Zަ*5h^h},]Ꮇ":$$ï/Rbg4?|DzaBthخO1Z1դ^Lڿd(Ic2:1G~gPKSFg) !taurus/qt/qtgui/input/__init__.pyYmO9ί/HzJ@^"%i Pt:]ﮋ96 \0c33dQgZi8"eŅ*A%pY'7A!$8y8nB˃O sM:[?G$%R(0[s<ܜ͜)-?r?ea^qJ#S6-P Ȋ9gl2jۇsE:+Hw$m h޶f/*Ѐ_'I+SDā@~Ah*0kR&\}3. bEZNzI^(L-Kc]9B􋃦ŭ4>yÿCC_n"ZG\8q~2cu͈n ݻGބ Tb.b65F"b蘭^ "-Gf3+{| cv3Sceٍظhtxbx~mae`p4U HNT8CgL ᆐ̱8)pb9ZxxGAM=5.zI7Wdφ4}fJޅ߳S"|]cHit#rKKt*D&ڭmU $α^,HB U:SJ MX"^ݜΘBd D XIJvVc YT+.K+WƳHgI1O1 Krf=h+hB%UtKXJ;ߥ(+ f35x =ciSD%6x*P>dtb )hS߻buZ:׈eb{)ASwxCd$@KyL}%XG* s̀5v8c|<{r_zb= N>i ^ap5 LG'ŒxU-U+;r=SѲ×ӞwJy\/#z߭=}k*PKSF^P -taurus/qt/qtgui/input/tauruswheel/__init__.pyTn@}W8hJ$iJM4ޱz6ό/I΃(J(y #CTNhIʨ\& ,\p+0cx{b;Xy@C^ |nx/`[;A7w $K7x"R+*pPn\ݍ3!D#שh^R(f̮kJO '`S)3uzC0uUlCL+|^,;^=X:siW+{6Gk Eͳ1uߠAW Zfx@^3azD,3ӎYV@ HMeպ\ېZ|[/bqMQC\#faec8P,0GH5F?G%n}9IܥN/s-4kY SmrFc.3?`+*cWK؞)R,mM(2en[ׅJtSLs Dʨ0oX+L4xVưah((cœp3KI s3Em;Snм~ %\$GiڗlI6O(+ )6_R,Pzc^CEj>qP4]$k;!yBS?'{g_SaG_wbGnPKSF<{|+taurus/qt/qtgui/input/choicedlg/__init__.pyՒKk@+SQUi-4jK)a\i&3ρPKSF> 0taurus/qt/qtgui/input/tauruslineedit/__init__.pyVMo@WRH"@KTTMBBBc{]7_zݦp@ KfΗL2㬶8yY)mJsiJ*Uj 2j]nAK&ك<IApcOt=!A0,E]J66 ̘pT%Os]; °B;E[0ѯ^ u#;ٱpdyGMÙ%Zt)+?2^WPt1afFg:>Zi;Θ׹T{JADϥ[l7Qp<|#f >_2-rbivb#du)ӎԬj~j{4,e[5D -mnjfn@5*+RXSj`]NG&f2mEi'b?Osi@X@eyaS 'e"Ƹf.nGwŊ7nq[~PKSFP+J~ (taurus/qt/qtgui/input/qwheel/__init__.pyUMo@Wf*iH@!UUYwWwnCA!'ٙyfdh \Ri7ULhˊP3)epU9# gk^A41d-hP/ݚj8MqFcFXfu8!'YN1L7r[qZύߞ$1ݗF`i(3YcƩQy[j"eiy=`={FB*lUcImD&YDD@gZYuAYphz;g|_UwtBy /Joߡ]X}hG|2KSxWPx2/=g4/Ư< ^ Rbf1^vzK|fh~23bO|,v~cZRvFk))7N&!鸘w [S/bg73 ѝV jj{BO9D0`|9P+<'^_= d! Z>DvX R 6eiKKK_VSkU6yOPKSFk d< /taurus/qt/qtgui/input/taurusspinbox/__init__.pyU[o9~_1/$hSrY&MRMK{fz&s\OBXi`4 <,KepiR;duIj_A,\z7du;yv_\9n:AIuKn hJDIh˖:zl7w>^?k\@#AsBˆg-u4d%dYa:8>yVbZ$mLs ӵb}3M>0._ V\z0ˠmq.uyNY%+XI E[?c˜)bK wjSApKM'jFu]E?xlӽ8gE-!M` :an[+]B+KSa('ҡ%? ʇW 4YG1;b@h7D0eX94@~δ0 C,BGטl)鮑>O,k%67C'Zr. ]/{x)E*E2SqQaw`ˤ.TN'7Lyq*pf\IqEtbVRs}+xM]E6 ^jf&ye3\E5qޱkMc'.Fȿq"zv^Vi,QHͫkK댉žmwp~ݢ](v\" rwffb]A|&ozJ3s[<+oR{N4f:v`ϛ ?a훛\O43PKSF*0taurus/qt/qtgui/input/tauruscheckbox/__init__.pySQo@ ~h+c^miZ6(B8S/w[nEH<yHlc_M͊"m爳eamAZWE.`0Xpv*(FC@#Y0?`×YT0鷡) xݤ)x\f3ԕB,Au'u Fy% 0IK.3Q ވBg{#l"#/ D99#;.hk!wYVauM^vz,]e/QĨ'%0*=΁r#yc+unvi45IhL:Ru>&ƭGo(Dm&[b Ϝe /Kt7?TaAّs\h9U_5X_ߋ3ѦŌ=Զr)+E.[#ռjxN :ޠU}O8z G_Uͣn'#Td&w@OPKSF9:(:}!taurus/qt/qtgui/image/__init__.pyM 0 Ew}_Ȗ%CBRlc4k'I:XQ!Za!|,XM+YG;X IUSS8p|} ^Y/Q;3Z޺{3tE}PKSFP+)taurus/qt/qtgui/extra_sardana/__init__.pyVMoA +H%I[T 4հ]Fάڧ )( ޓ=EF.Lzw4kE #pjAAsbw]%R+ۦj&gG/:6랈V̑f:"Op. ]ABdfVC[3G\4%,\ ӃuKVwkLzY(B0ğCo|#c_LfQDP& 𻅩 281tH 4EzENaCDr|oC9.J s,!r}^ATͬH=FICUoq|r}Ŝ'AgJ,=˖\,;r%>$`s;p$`ꡪ#xNMTEu ׂh5 -t\KXb+$ړF/J@3B\[6LǕ13[ <,i;CuېL9ˬ+?SM3y| D+:D 4(oCPKSFk"^(taurus/qt/qtgui/style/nebula/__init__.pyWo6~_7;N Р8CQ̃ [M&U^wH2)Y%mG/}o. |֒>HH"IU>ST<ٵo3Z7 f;m:"]nTFc6sj?G}1:ZD=#U:Ʒ_?ƿF l `&L0!1[RETȐHjY) F`4,KR]r1uŰgg'=JD#s ء_t̷2JUYOզJUB533I z/᪳w]toyGbޓX!$Rn&'Ox&pL)fWr<.2pDZSGyfz׵ZZeDpv Nw:Ԟ;ҍBCغ{^TE$nȚTQ4Vf"& Z>D~" \E|aB> AʇwӃq=˒FMWFj. ER,Y[תмpClP48mvV q7$;J!ъT[ZSZ%\'3]YHT=Wa7\$Uѹ%0U?-}?&ˇ̡P9ZUPY̮#?|dIL"2Z?PqRq>˫$_cL p zxY[Qc {fak79k0U=tl3f`7C>wYD; c/ ]ҕRK&$ ÀCivNHYy4|ȇ.}H|]M42aU^\go[Ǿ*!?UyJƢhԑyT #rT$CJ6'1}EL%y k~jtQzgOhaLn u[AH~EFNpvҰJ~X јdX,#0t;{lU W*9t`i<`[hȎLIw)Qi ʒAOk,X乲 ulɱpa^bߍ>ʤү {$ޔԙeSg;uc͸a+⾧m evIh1*sq'> gzDP>u_%: zR3@Ic)ܤhVzw*pU%XY!Y.zev1 ˑs92M=EYvCub܅Ӳ-G34D3qcyv9_8kvX3c~LA, l$)mO6!9Q  c5}輘:XiFF$Ӏ;Z+)M巖`T=]w9u?2۾r~j ]Q>%[OJ*; ?6<}{S :.tB[Ge`eӂ230N{ObYY~0c~lҥLPy*`Si4؃tN =VY5=ōaAK-ȴ14 RT`]n~@Mr-i7;(Oam ƻw9a|MlƋe{K$V"pj*ܟk3UqSVmRv <ӗǓ\WgR?PKSF30.taurus/qt/qtgui/plot/curveStatsDlg/__init__.pyeN1C@S……$S[k;}{g :O;K ˈCr]#/HJβe]U8 cw4vPDC;*[QGUw%4qBw6Igc{Ƥ!I_T n]ѻ`tOǥP"(NXOrm*U m[_ ʼvS=ˬ󐈰"qLb)'-tK/Dg ]rll9Inc1q@jԨy >gAZՏ`D>@6_l/PKSFgDd6H(taurus/qt/qtgui/plot/qwtplot/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFϣ!*taurus/qt/qtgui/plot/qwtdialog/__init__.pyeN0E Jj򒺀fA%Z*!8Nbx=Qh?̘2.ZYda]1+JsP'1%.rc^mK`{#Uy.xP8%Jʈr³+Ltnr9r| 5*FI_͂L?!?>aPKSF^n:~1;taurus/qt/qtgui/plot/curvesAppearanceChooserDlg/__init__.py}_o0)64u>tPiHA)r p|~7!eXdν[Y&2m:,٢Wv|JX_(f aSSG𛁼q_88ͭjtwНW{-"%ab YC똔udҺN'o7/d4l 5yMve~#|јE5&D߅3M]ӴKeQWuy!ܸ.Ù_{[ͿPPKSFp7 +taurus/qt/qtgui/plot/curveprops/__init__.py}U[O8~ϯٝ桴]mӆ&e@UdCjYǡ9ӺܞUckZ yVڄ +W+_1~2ͧ)RA,I/ XA6\.ԥY\5+ǘ~Rl{ sVzތ\y/e6WlTj]0y"I*AAp-ox&ĽL% ͫ t2Q)5O=!ccEj#]'6KUNѸp]6V~e\a+Oǭ0OΔSKˎK vȷWNBsŔ0 yOj Y%ܡ{WDR;q"3kݿdm g֞ӎ ̙}讦]D5 04WoG3[h`)+kJbKFj]1˶q7cjGiTtpr7WCOQS\~ϭE&}7&i+:_Pn^ppp6>a*@|t^,xt: }^14e]GUrA=[z^=K7PKSF@>,taurus/qt/qtgui/plot/taurustrend/__init__.pyWKo8WmDҤ(FID(RKRw9bSM̓fvUFQZJC(ar%Y*  At߁QnYVʜƂLcO[H7-tއC oLf6b;kY| 8_!Yk'&*0MqٔeU&)yYyZ0@Ł>b ZJSm°Dd 0fc6S٬b&ݕ Psc&0(Ɠt]G9V M,:NU6@^C3Le0Q`T֋5y=3ዶ ?逷$3S:`]Z+ T95=bZrI*3~5NQl/ )& nQ1-ZWJ+]5Ҫ,!Sl8HY%PɔgKGiULv:Hkl%ԩxnBC$13?|QL\'8(kU1 ǒ iv7̹HpT 2QwfZU݇t!\WgRi1s[^CL% 9>x&]V@46\pQcm.D3)Ȝ];)jx(hIgwɳO*m<"~\O\2݆JcեT}̒ٗB"_׎pP[٭]Uq~F^rH~4>1'uLp [LDl,iX&㆛mJ A(N`MԲ>wKp9g{ghp91q띾98_ya櫐0f e&ڴ%3EKAp7xDH 9*"f "ݭ(l;6B ^dk r) לUZrxfSTZݧj&!ZERVAT|J} GN9)4W$ I x7t>Xiy7TaxVgB_cXMy2{hCp:aOmhN2?^1hPׅ}m`RԾl\h&Dub^ b{`zz)3:-b53ƔS8^HЧLH*A =/HJi(4ALT 9irAܔ'Ajc &8Wet4 }xb#H@h W;s=l2Ry+ qtӏq fA0L&"A1\y۴]W 5Li6A[UгWU}}:0&Tv>vLNVizp#z70EyK5 )W tVW0dVqm"碫˷܀S9JTK:0큝CҞRnrrFon1dxk/|URE4&7ز9NHX˖P?#JW}B=ȯಲsts}~5j-"_ܴ7~ss#tkv tg=N M#VU },zO/m>{{3f' ry]n"%+11Ҍ;*O[2mXԕzqg3:"" iCf+cW;Ueq4tיHW{eWQn6]Xvkˡ:G%mq, vm|חU-Dz>2aT2{_u$wTBywe*HC+ٛnuZmK-P02ΓG[NuuoɸQT/Pza>Y*с,{nm [تoiV;$`*/IDoZ|Q+H5vu8)j[5SR.̙=4%nkMBR T @AMnk3#~l!lqԂ()>KMNMldǚ\0R͌7NsNӵ||Iy^ y.ttHb lRY+ y If$X!󼗒 ~f3J_`)dWcI,Q"Fz/>!ya O!j\kS"XuBҭFS-94Х!c&e3% wp13:٠ϠUM]e;ЌqB6 ]vvd5Ex;۠E&]9uG;*壟 ==dy-8虨-qD{KS~k6V} #:]m[\ f\Kʶc{xxO 1GY@ghcS#y!ȗ(չ}o(TPl}xb1fOڭfAM3cl VZ}"vTn}kE(VS{rs e_PKSF:]f*taurus/qt/qtgui/plot/arrayedit/__init__.pyOK1)rk) VPiIֶxSx}$cB%A Sx(<: d*PE `{ ݊2t`֮ e'a<U*+ I AN3c'y"A˲OrN~Fi_J5n=}3qH0aA>MY7қGV'V`&lуW]Yhee0J&6xd0-?`po_F$WD]r6RtZK\!Ғ>=HNAF聢𽛵IwPKSFiʣR'taurus/qt/qtgui/plot/scales/__init__.pySKk@WM"նP +lAͭeL%H7U}g|Lvr <lvXU^B|ձS^N!AxXZրS)Q8el0HE]@HɼBë-nc$UdL;:dI͝4$s&6װG'I/+qKG䮩'J(mHk ͫ{Чn?q1qFH.7@}9bTȾU*=rAlR}+w!U#n#͞JH4kHӒQ"ܓ{sdcC15+= dJ;n4Wy)~CN6Te0D7-7ir(X#DɂKmtt p@mLPR6ٻ=&lK^VW[m <" 6"g~ߏݏPKSFP˶K>&taurus/qt/qtgui/extra_pool/__init__.pyo:+ PQNh"0s5Ҋ Q| YI;}]\/&h2cɛZ`)3 #*Κh s&Ue`,kc= UTwgIqKC+_(nKߠtV.pmy:ur\HӵJi rSD [gzbsϸ:GDbZK"Gȅ-!ĵ3,ԆƎ]tq)PnL f 3a|kƭ34mƈJh\КZ?`bH- Ii>܀I4%a|TRMg)8BB!YD݄10v>$3 4R~6y<{vP3 ȟHV>lOyQX8뗟n{aSߑ=Jy= `3_r?uV6Z|R-9J}`PKSF4~S=%!taurus/qt/qtgui/table/__init__.pyYmS7ί001/ L>` S@;G;IwW;ƙ4iqE7Hɴ6F 5fRZ0p)"˕dvں `jZzpnXr{g'av=5Rpm>YٺKdl%^YqutU pt}sjf)2ӕ-=^ju [Xpľ̆+[_=KrXY'̆A´]60maV:w$rrqIJG3`S6k+6iy*N.B9i6V2>*yGB*2},´ #֑wE x<6zEw3eyڒTdzK_dv3 Ƽ$AG(.Kx <ߜN 鱜\,nÁ !bybZRD< WSk:Sĥ= Ѭ2;أ6II2\]#yR1eB17[ ^.bL{ 3״SH1nʇdL{J-* s>$`& \]Wsqs1&Ha vgKVȨD993B< \b|=p>)PF= jS*}t "'>by (;5xY*b|o d]"0@|Y>Y@ڦdҎ,>:LgG{Efvˊ nVM!cc%3 9n0KCckʢ1ܺQDE|7\z 1M4stkˋ6-7G}ln>#jW/=VBҴD.+-+U5pMHU>+Meu%  l]Ft ޓV%Y&_ey}=r݈%\JY(xTKO6@|Q=jkdZuH 2ŦkmSo\6 fTl3Y^F;&j''Ρ nTqYo[*!VګޢK•=zCx7y2VWGk֬7V/;[v1s ;E3byX?kAthgmXxG lt򾨩p7^OSH鷠w e3iBe80#ej΁]f9IxZN4N(-޸SHg=*l V3+3G = la̱o3qȕP}rq7\@N5jI+u3{'I1_PKSFK3JLo,taurus/qt/qtgui/table/taurusgrid/__init__.pyYmS6_/ׄқ%iAo:bol Jlo\&_h˳+,#!/- ɼ0Gc/,VnFALHt|WҖn?y~w؂οK/[sh,ݬwBJA+[jǥ=CKl)zJQ *w"$K+=>8 =EՆMY,J"gB=!wNx#5P [`+p.:D)x셕(*_D)cN;54Q9!Ґ pCJGK*06iv݃!ZƠH >2eWoLw RUg\)W=tYG|'S^r]P]SG: pzfwxIT5 O A&#IBQe+coֳר]+_F+eSL2A^l[.W[?/xp8@9d<4\P0EAX&ϓA.$ܒM2<+AI<\@hL1.{Hu1zfEzOdi[9[C| $& [PUm+~K,[ȠBVä U!J4$l-tlOEC a&UBЕԉY,N)u?$Xf 򎘚#KԵIpp S]J@~% mɤi2||SAqj߭L+8o>Sh@r9Hbg@)u!ń@}fooBvM˺&Locc hx9]y2x߀LֺO􀙍N#`W) UR I}n:5d}v6@}Ӈę~{[;fnnfnosTlٞUK=#6y0}sVmΪY;bO}3Kng&j܀-MFEVQs?|_֠(l~:|J_PKSF;bz$+taurus/qt/qtgui/table/qlogtable/__init__.pyWo6_=N51ql/Y7 #e"TEٲuxM[΂ca0ym"߸gZp6^]:p9 YA3mfd` KBkFĂ\vYl^90q:[3.<tvҊ7[hTQxuT3F_7MH:K)4v‘?ʱi֊3k aǞDbHxR6[H*b\`1L$٪"Aj]TKD,~L*dRi1b$Bn(bEFe)]OoGquPs#4Y "{8g5?N]\00Ęh2.i&Za"wKd {S# 06"BZ^d9EK58^ {I/)6T v~(~j+vKY˰l "䶍}yNxϼEE1$S`\[դb~Űk: @s9VnY6VJ@a_߅@ ,dR/vOYs%43,`K&m0{D][={H`p<-wm{;Y2B*[&HZ:o>Rozs,a_y߉4B.=XۄIO;n8ŵ_Ğsl5sZ $ufJEda`=DîZI6=w /];E$OCp@n+3/;}:tXբzꀽ,.߸TO'I7e)qX/ҧ (&p"eZUUGtdxgpk, ulŸ;@G=dKVV+Zel+(-[ˡ E@=΢] Hh'B>r>q.+Eø cz7_oqa'%|Wa˄9G/e߾3;PKSFN/taurus/qt/qtgui/table/taurusdbtable/__init__.pyXmO0_/[[iTxCm@Cn MS$±wvI&-=~|yHQ~)Xȥ!TƆ+饎nFdxޕ} aaXnÓLM46hM 3,brX"ܛX!ee[ory`:T@ 'cXP U;SaJ_dx9N3!T9 ?uI;#ǴLz Uh=DEFFP<8?|Q!۳[QAyTr"B|Pri3޵KBe(uJKn !h,J3@4Y"'BKдY@K&<1z,,9ur{#.YnLcwB&eGRC[L3}W*R-God5Ϥ+hΊ6յAo[6A06#"'ܺ-'3ldW~!ESB.hmYVqt*ʓL;Jʨ-xƄ'ȲSi;3TpiE.Sn Īǫ n& dʳ/+1z'o.(ozaWorx =ՊPѶ֚ts9~֚it XkBZ X^|)`z.OgGdjV EPNGYOm牡E`omea˹l yUlƟ~3ڋcC~嫱PKSFd,3taurus/qt/qtgui/table/taurusvaluestable/__init__.pyWmO9__z ZZ  !INSd^BxCJp/QxDyVBiJA KçLxǟPڠWWƻvkV..g Hl]sO00}uQ z]7 x)!Mќa'>m b2(:E3KeW{rk`}K7w\@sz{V-ZH}2@+{a.%N)*ac},3J˓\fܻݷ_;T?IGx(߃8IG׏s) $?߉,)q 9` ؕKn({1 c 3au8҉JC3@bC//5m \O*辶#Aly(.U#>$Kߗpa> = ()GU㠹]D<8kAV~DDK=2O, V C0 ^O?6.n`m'$G`_pi}?)߄3|k}mOz|=ǃUZ 6ײAd?C_PKSFO;2(taurus/qt/qtgui/table/qtable/__init__.pyKO0PEymP BrMbձQ߳Iܗsk>$:[0 +3U!+2H$ff7cQ@6r\O/sj<;?zQ{-g[ zdm{c%#)=yJ^U*ԉ$WZ:0aF+eݎEɜ ӏ%pj|K93A,&$e1s KJf.'PY!}`6Ձ-^%B_k>fp$KKpX5 O'PKSF3  -taurus/qt/qtgui/table/taurustable/__init__.pyTQo0~߯h01$hIKղB)rcձCϝA$@|}w;@W%YVԡFȲDW[!٢XY*oZ,%pr#O#a)VZ*4=K-1n7@NweKSH_1mu%:C&(vR`hVJ|V6S9(|C!~djPnV! }mb }diz{sa','<ԿX̰+">sŮ\_kCHƨc<&U|RHP@w%3Qbx8H[R#;D9N5X׽-\[C<иV|F^a>$@_ȡJe 5O悶(ɩ0(ԝ-]Nfè. 9vl:T.4 _ݢF=KPڄV!kgnL38t.dB'C7Z_{_}!~2SL>8mPKSF +ڕN-taurus/qt/qtgui/table/qdictionary/__init__.pyVQO0~ϯ k+ kmA-014M/^@ h/}jwϮsU!McQm\PXYUJg]@hzCigCgTLn٭|1ggM"#.OOǣ0h aE(b?;*GM(NJUTP3\1 (̘x6f9j쇰~5ϧ,'! +2& #|g8 '8GTư5Vo\ooKOYᎉ7Sʍ٧WG6Br-ej܏5Oه*J#$aO\w%$LE´^3gm |nS^ΕF="נ Ҷ5$i!U-5f6Դ\ߌV їdK0oq75]Ȃ: Um?~50%)O3iYqص *45Uٱs)tȅ/H'RgIa/yCΜrQAАu=uI]_P)-u_[mWj_[~mdszcw_EeB3e?8 LѴFOlz_7PKSFʽ"/ ;taurus/qt/qtgui/table/taurusdevicepropertytable/__init__.pyVMo6WkqfC&hUloҢ(Fl(R%8!)[vrh{)S87tU%I^ZCDQr%;;U9t:w6L^ײZ^,hvȃ~>ZbM=8x7M:xdPdE?ּMt:`DP0 =Egq{^[(rX3W ҷ Aۙ@Y "KO#M8xEBe! YL4[W\ddȀ.3ЪBb-gUP#£5QnQyd ḻ#$KJآ&=v?M|N1^!'-fp*)kUpvh-t&sƽ4dH5n(\߭m}K+=޲. Q=GM<3Wkgn]7+bN0N␫TNvϝGwGSI>]qz~->i| oߟPKSF #taurus/qt/qtgui/graphic/__init__.py]{"};/hڎCډo8ʶ'i#/#kьf$͌槑A0Ieqly¸L84э5g;!BccTn>D)OSo&Ne!Amc׈ 󛜦dkQ2#[U A\`JݖqI f֩tP0SEZ kX8v-CD4s :F )+Nygι Nۃ:=-;w{kCu]R2a,$E\$xq2%#* `aWtI+",Ģ",9 T&.\鵱RrrJ|%IVO667!֟goO|???_|}?}?}c( <āңJgJeƓ}Ƅ|VW xo5~('gy? =_3j|QS(.wum,dqpc}&u|-4$yv=л#)e1 .mkw4a?KOz4!'ߗzi'I;\qs}Ry*Ϙ>n[iv$ ܃a|qpp "k]XLg#N'rt)"&=`W%#)c6 313]Xj_4[@1AԈ#p1Q ӔX3)fgBPʃ̍zLo?N l'r=4L Kkj^JHj$ݘHK4䂲PBŵr1J54wwXQMWm$ LdgBǹ.EvPH sTQa qJblfz 1JށO鋬v ZV͓aoA IEM%L-4I~wFE8 X3<,?YfL{@xlIP1;E1^zҧ3Xv:Tߍ2JU_]K/CC𙍒ko^|fp9.TXJ ^˃v8.S=,faצboW@5ӎ~Mm*~᫂oH(:P6f#[_!*o;zVο:꨿&Z:.>=X6K)?aGĽtd9!Shp.O(.-؆۽$iɓ*@S/_>7"0g:wT*J.-6;=%4r|:sɓ8#h8s[zj:{D˝RKy}0rD($(I*}q hϕQ^ .1Gm 35fFǦ-^!1C8S6A)]³;{ 7?zCq[!m+koעk'chk/jAm df+(u; Yw͆3eEJiNuS+^`*)2UbDž5t?eO'\Oeeik,jA;},?D& BCRUp'f]:׎g~~k%b2-cZFN𐓹77`D_ &֧$f5}bӉk@M9=jQԯC 9,8g$1yVY4xkAqc%h';zoFǽnh:dCYJ<[N/HJU tzD kJL@Ga(O PKSFgϤ6taurus/qt/qtgui/graphic/jdraw/jdraw_lextab/__init__.pym10 "[ʂx*ؕ"߄ ATVE"jnV);zWY.]H* QUmwKʼnEX1ɡMfKSmH{#EJajR?Zr=PKSFy4taurus/qt/qtgui/graphic/jdraw/jdraw_view/__init__.pyXmS6_%RZB@(GG,$t߻+;ih7ާx>ZVRFZe61;*]uJrZ.ju_ F;E*!|N%!W|Og|A !UB {&3jokuv+cw@?!dſzMH{5-T!$7Ϲ龮V T:QU~وqT`،" 5O:<'Jݓx&܏3^AJ|t8o1X_ZsZÅ3FsޯݝA ;abijS*`7_b4=Ra86:}lW^TX3b{V*N:`ej ~;lWQy#Z=oڧvסB6P,H:J\@ƖOzpɨC>ޓϩ8]^GF`Xj&m Oa\؂h=@ȐJ .tmIVG*!8 m8\Ii0hTDdy>h)i·@'-wE|)x҅<( ўa4\ 9,q?b!8pp4C(- ,ԟӎUV%+ ̈́}0:]*wO\L }=.@̤ƣfr/4n*w.@ZˉY@/0YΙzAtq[RGWO)7n3pt0@+! X¦PT/n5G'T^:C:8XPKSFЋ6taurus/qt/qtgui/graphic/jdraw/jdraw_parser/__init__.pyuao0WD$CBNB4+*EQپv&d4|4R5KѸ6B;puRU ۇ,#euλOD]_jjn,>EW5+PWr.^\3@AȤǎ1xs])$ 1vM BleL7*3PBЕ/a̝DֶQ;x;rۓ 9|)=̱/lol٣'u:K tZrN=܃(\U]mG,gŦe[Go`N|y-^}j4hQi 1JH! 82&iZanE7/IHQ:[2WpFq2ӱeﮨY&/mz:>Nkno')TjbG}꒻C]t5lM{hTR%b7 ҕhB;lLIPKSF9'y/taurus/qt/qtgui/graphic/jdraw/jdraw/__init__.pyWKo8WR$AG9Qa;.#ebeRKRnw(褻螂7|3y|*W0t&B9L!ErZReֽr>'"@0oR>qgVk03oh)r't NK¦x7 pdϲ\@^\]hMxxhtD 6Li& ,54^67s E6 <# H;$/-6ۧc 8II"+dߐ-*v9ǵpʢ{f;[۞U3򴍎1 r=n_x\v "U 3\'dJmp!)뚺WFNTM-UJ=mף¸:)`]+biUMaAeu\4ٖFǭ ,u-ez}=l5by |Jj>m3pyЬL. [A8m4Q5)I533#xrڥGt*tG# |Q~{$iX|;+웥xQPlbkf}U0RbbB~&b|'[xxxxPKSFa>P+7taurus/qt/qtgui/graphic/jdraw/jdraw_yacctab/__init__.py]1  S]&R]IPI 46=@J k"DLn$`CյFg"_daczhkg5i^\{vy*TܽLxu_8Vߕ G=j9lJ!7vFØW]m[_oj2Pe_ŰgLB$d{?jѰޥcGH@~,٘@66:T^sNOD^s.#-:S7Jf1vCeu8nkH>tleq3Y<ȸ=/뜞'ciznXhz2#>$빱c6-/Kg@9auņbalaEDL\6v<W-L:6P`\L{BфʃW:1I>Iol}јO!RA`X rFu` edbf>bQsha.Oz*jTFh"K5c M`ddRSMe+l.Ec|̥" TF<2oV(&~k >'Г s9{-i<27`vxR(&~HC OMYBl ow w>rRzف솦cP53Us#F]w~ݯ-RVZM dOX~܋ ,y2|FvacX; tΤ+& P'R$ȲⲯbO2փ"yUq˖1c靷;]A[vf4G# =Yx-`+#1KTÍB~@/²˂奄GRZxS>؇=sYRb,L$ÇxK^R_>bQ>CFFFFFP=|bhhhhhhh}Ojjjjjjj{ m=ˡ{BCCCa=8>@@@@ޗ~- ނ\}1@?677777_h@PKSFS-k5taurus/qt/qtgui/graphic/taurusgraphicview/__init__.pyTn8+t:qib 'NBH#TdPR⮷=-p3,I4MTXICxfM5"mv/H KpzKh!Pp oMDA+O9LsuL[GQ}~$ oNʫ 47gxJ a |@PKtJ\XA 8~=HKı`p|fFiVj솬Me>5,mz^)1ߨUze8\nTeKvRyg&rkT1kM7DH|*vx$T؈YoBܼSހ~qB' +owԶ5lcΟX}yQO.;Xš]UC=LR?GZv 1$}: չ?2Xj`HV Hh3Rc. \27^=;Ч_Yj[%E1<<1Z9'wI9WjhUrwDW8siġݰoQB6rotܾoPKSFTm(;taurus/qt/qtgui/console/taurusconsoleextensions/__init__.pyMN0>wn% uCIxxR8I#{߼)mmIhvMK,e%>G^PŏR[X>.@]X {Wڊ}B킬_M-R \}}R7%A<ؖt QXy[8>Wa|!˹[՘ƥ|X ViF&>u,7a'hq(3%ƴUÄ́lU)3]vI3BW`Fg~0 ]78 PKSFڔ.@ /taurus/qt/qtgui/extra_macroexecutor/__init__.pyXMs6WH:ĕlq=Ӄ%YcϘbq{@D ,>, iіftD2X`wvLʃ*qiXJ۠\ZDedUt_OX(t/Ryds NV6ф=(1J7RL&Hn`" : {(f9X{NaO2R0c Z6K{~ H=!>M4ی3.b t 2VS􎌫W7\>u* )4+*a$J<'P +࿡YRfvðJ(My_BJO;(m0a ?!@0N~Qo@f1tѪr !faĵe)(ŭS`'Ͱ z Ɖ6א2׆Ɛum$7*2[(cX SsFLg 8#,(ѳ9>奪~1.{r֊]D&X8c2xSuڋ46XmpY%#t9C8V5K/%[ Og(% 9hbE&S n^jGh 2V2-`OR;"T߼Z)VK56YZ~>~/xfO8C-L" j|vM4}} 'ys!D&GN7j[gJʶ%:3c\.kDS*V$_/gą̑=@2=ҩN|1;vu"D <X04FpM/ ܧYvUEULCKgdCh <=JuȖldRTE4H qװuL/:DX<%4" {q iόỎjL$v{W[ fq 웘( F򒪩W?>bƽeXvIc(VXif]_ \~YPKSF5-taurus/qt/qtgui/button/qbuttonbox/__init__.pyeRn0+ts(Q!hi( h5E$.I8]fPcRWLˊ0)dsQ5ܖ{o& jSjOLŠ6Fk8:.cX{!Fi"hڛ'ɩeG@d@=9stBJe񒈆r 0,%i2+QE+R2ՂPVUEr+E^G[EŘfg&Z G!;\`{{eYLh >TP,ԚӘ#΄6TNۿ}Ԛ4W 񍴇"ϳ0֍ J>MqPRIC]DneWt {ݢvaSv8xf薒K-{xѬ!<cwΜY̠Ӈ?ߴr`(QbG*;ݓSdwWQ_?,<"?J`>\w)Y= sEdiYTQPKSFWbJ !taurus/qt/qtgui/gauge/__init__.pyU[O0~ϯ mUe$hVch"^;u MS}883H:,%Qh*x9B$!`-M4$';7zChU?v !:7C: 8% [$t] E L #X][NE_R-d &_ BgZU3F xl;0,Ɂ`B$pP,樵sNx$huxU#3~`\>Qm4OU \Hn!ͩ2vznCEpB,{F)8Z)mp%k#5zsڎFnlKh4[(慏7;%|KSLot{>E?ϙm~{P_$)Jkܾx` 4BOK&sJl'{.D R"mkz[3$Iͧ _Knz.En]}7-r%V\{}ҷ-tՓtRJ ` q@jM̦b4zU(FPKSFgDd6H&taurus/qt/qtgui/gauge/demo/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF}2u1taurus/qt/qtgui/gauge/demo/qmeterdemo/__init__.pyMA 1 E9EvAz9Y2c&o{6Aҭk&B\m][iI[]_I4K]˲ִŧƇ|;=K4GPKSF ^i(taurus/qt/qtgui/gauge/qmeter/__init__.pyUO0~_7@ڪLRm (mMSt$īcguBm}5Δ,8jS+㐕T&X&ER&eB[ǻ;jU>Txܚ7uLӯ;APvuݳX: a]G}°"%|F^^hNѡ(ڧR<g).Q~OQoi9Ԋm %Rlo1BfM̠LWP#۹,g&4>:ݕ+npAYML$?mҲ&,c5Q t&Ui-6Ox/kpd /)x$\Z2Raz`нb_oН0~G.-a1,O6;=e+A3Oy9?ݐuVG%.:c4!yjl'ʒnT/'s*ȞJHqcgc#HO~piR L^1HߕmeZ}poӥm 3!W ywO0Œ&qU+zB9`sPKSF9u+ taurus/qt/qtgui/util/__init__.pyXmo8ί@+hk]ou]ݢJ^u:E&UNm-Ǝ Vj?'2ox{&3)RJ:!u=k@Sk3.w(jc]?L; MR}x 9az J@}(IDxJ0M@"zPjD$Gѿ _!Gkt`BIyeר}1cF \gMqx. 4Y3|])Cq. ˾0f*{KNY]FrUӬf ¼~;R~g=2%^;U0V^ӵ=o]=1􇭁kU8~x;?WX岼lo(^r=WԖaDGVPKSFdat2taurus/qt/qtgui/util/qdraganddropdebug/__init__.pye]k0+rns/e8XЍ1B64M|{O M=%K(ƈTU T$IR&EcA6h qcUVP%tsLWw/hN‰(R2s9@7^8Ĝ pbhز rW vY <H !zQTӱ̵a$_$Nٯ =) F8_xY ~EOPKSFyKFK1taurus/qt/qtgui/util/tauruswidgettree/__init__.pyTMO@WHmC"iUU=vY1i}gSo޼7~u*UQZDeY&jUaJ  `D9/I!: +׃h=PoDћOn_ {(ʏ;ݯ#1NŃ#_uB:!mHr}R亞s;=^jGX!Fl sl DK+SuН= °ғdt!fRvޖ'b pEtǞ6k>s1D0M&ʤvq!y2iSorcÓO{3|F aêڢ7|fJnaAݒekW@=^u*'``Sл_;V)ilnm~ -5d% .E!t( }S?״;b9"~ha#{w`~ߦk ]P6 @9!c,Nv~r"m3FćL-) wD+UzQv kNq!KH+fVC5 bZ5_X|ƒOWy]|_A7f8@FpP+S>hL,Rቆʆ7DB2-ȌAװMTy.UUR{q6|za=IE<s8"s4wagpk!%cX#ʩq * yno S_mPKSFӧbOW1taurus/qt/qtgui/util/taurusscreenshot/__init__.pyQJ1|Whڂ}ҶR)A$׽3KfOį7/t;3dBHZivI8+x'tZD Ē8wRyF6W/);`McS!PllGN@s_׀lz6ۨ>#zF[i QZE `JHt\!SjFgeAg~~a1];@q:-D\2֡xωWqj:"d}蹈!_5tu*ϰB]+Gq^kt],Y_+7='e!Fj-dr-FuJF[چoʥ~PKSF8FX*taurus/qt/qtgui/util/widgetgen/__init__.pyUMN1 =w9*݀* ҙ$Xd۪z{U*}//1^E3pTr$M 祉9Uk'<ؔ|1=#W|'_-]hSJbqT6DDkpR #Kкnkm:&du[d0u~گPKSF&&#taurus/qt/qtgui/util/ui/__init__.pyA 0E9Ev A 袋DSL25@Ю)QS0Sb=',4ZFjZ@"Au//h6%ܹ]w/n.x_ɷ*hWEw+RLaՕL+x}-"%`f>PKSFVCd,taurus/qt/qtgui/util/tauruscolor/__init__.py}Qk0[+HC<yƐK((K.sc|M jF%mׇȢࡹQ]?ڥY,$36cžFo\Ʌl.&k^e)f _ܖJrM|EBV WӎBʆY>А)e5<IJb !ϏB,=:RzAл;]Cv:9JmԹXQ;:̹UYHx G7W-5}ݺrEL`V3.:-+e~'3;rlaHeȻ ysؗ b~PKSFgDd6H%taurus/qt/qtgui/util/test/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF,O-taurus/qt/qtgui/util/test/test_ui/__init__.pyő[O0+TE BEj* ZU2$ֱ=ֲ\"ZU<9.me@:S59*kX٥ƀH0v{Sep' &8#A+'XY@}/XT:A}9C&}7{G(?[C%c߭,䳆9%kcKx R.sqRb U:Oſb.w+44JjVX8gTTx/+؋7uI 1wr< tr.ĝ?֣2]_|U9LR2A&2nf -q [V"uޫo1[e;؏,.nW7H{Ɏ?bPKSFQLj55taurus/qt/qtgui/util/test/test_ui/test_ui/__init__.pyőKK1ٵ}nl)iRE$ę;3df/)w97IftI˼q2B9TUV$]N;Y8:X7vˁQ\v>\gZ4$Ha赅vF΁3bb!O{S.!(\cI$r +7FjמBi b(e\HHoʥ0KE- 2 AoU<#{ɿ&x YwZ=1s\wJ+Ry˓unW7,W@> @зJ<#]骡;y5{C؃/Zj^|HbcE6D Q2[?PKSFWFu7taurus/qt/qtgui/util/test/test_ui/mywidget3/__init__.pye]K0+rX7B6 I4 sUx=I]K9/#D8ym-@;KauE3![ >JD1d dm!9}o ~rB/5)NJ<=eՋI .ZQѺ+&BF+Ax=aH7'zEQ骆i͉-{QmcЅ0S?/GN7PKSF]HDW0taurus/qt/qtgui/util/taurusropepatch/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ XPS` qPKSF)%taurus/qt/qtgui/taurusgui/__init__.pyXmO9ίȗ^@R@HUUrvߌ=rp*T $֏33cs%Æc+ FRF0 0)V*u&:0"Q1Lzɾ7ނDu*֭/~1~ml@3iSssΖ'P"&$QAսUVUWBD>՞b_^ 0빷jAklh4%?'Z7h%V9<*91+Na c]H@;%cmH\NPt!ܠvΡˌ Cfr Vi X f l!dƩ_ | ڌIP`hf+&|,F8SBS&^cޑAf wjpG7tlBW)$Tw <*be魩 Gkʋ*dO>@#@HE$$M7B" 03<|8$'.sO(nN QVvz{dՐI K!m)qS%;[;N&@p T:2@ ҁTN_1:) ~$%zI(jEsz TB SJY*fQZYdPnCTKmP$;;=xq>kFma}_ajG7Q{K[`璘tWqMw+-JRRŠL'1Y0`AD@ ] K64qCoL\w`F"M_%p0Kݿ4q4kHp" PL{>*&4 WS\ gfTňI;ԋC׸.URwVQ}+2\`LdwPܻ r S'>3(Q+rs~ mm=,_Xw?YIўҫͶ{d o3ͦ2,ڣ4.txa >jS4? @=A+2@1: *$,]A}L *#h)g7uVG<$ᦊ`QIa}>anwXfV,DPCy$A\}wkK> ӯ+E.Anhv#S+͕f tՕk1zOEgعʥaM^YaD-N1[V*㇑," s!=弤R@`K;Uk*R(F8\¢xF.tĔv;!7JrX,#?L+x~)ɚq т 'h?2jXq(IaờRrbDHZNҰavR7tX:6?v^Vp&Tܬ]PKSF-&>taurus/qt/qtgui/taurusgui/PermanentCustomPanelsDlg/__init__.py5 1 }ܺ Wa,Ji?||.)3| T3 <"*14%-c-*T&Fa#D4AaO&f>!]KwX=e[|\*wpPKSF$*taurus/qt/qtgui/taurusgui/conf/__init__.pyA 1 E=EwU#xPJ;MͤMB]OϋYƍN" ˶xNXT|20YR<{,庄IOl Fmw[Sϴ9NZ|]ʛp#> lPKSF%NJZ7taurus/qt/qtgui/taurusgui/conf/gui_selfconf/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\`[^PKSFn;taurus/qt/qtgui/taurusgui/conf/tgconf_example01/__init__.py_k0)V>dIR#s#d5a͟oD'ćA!={iomԽ #rP.\IP\BUɜR sAdio.iz6 @nhC[Ǵ臽 ."Ŝk [5T,cw>: 6PKSFgDd6H5taurus/qt/qtgui/taurusgui/conf/gui_noconf/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF :taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/__init__.pyu]K0+rdǕYX l{OU!ۗxMV;L\e<7وg|PKSF29? /taurus/qt/qtgui/taurusgui/taurusgui/__init__.pyWo6~_zqv]>G Rv E!IB*IKQ-'nn vy};>VIiK aPz"*#˕l%+W! hf{e.M%ݏ;= /߷pЪFZob1[ @BHWM)y ZduKS@dP2M\+`&_LyAe8u4FEˈ3뎞׏"(,#VÌXMιjTRT* 3#0|^_6hWֿAMvVC%c`DSk5i=#XzqNT:K-1,9ڶtlg,c=xA63HO*ՁiS4B9P#;#hL׽u]xc*g؍e T b1B0Tׅ;+[b#,[䦡.e};u~V:AtܙZ]`&K;zUN, tE؟_}Faؾ+7u\4ykȵ Kp]{vx'd%_(ؾoPءX(%88ßRO~r-d:լ"?8qVeAoh=aޣ<**>*ѿUG}yԗG}՗"qz5v0}3PKSF56+taurus/qt/qtgui/taurusgui/utils/__init__.pyTMo@ WRHKKWUR>j)GPtq4t߯Bj "LA(QX:mQFduU鯶 y _9hrn9Si H>N2St0,p#pVnBI+ V%z"M<TITg:mW'z'ßdTǖޮ;H+R4滀>$+3ld%xLbW(sӿex^fs8)E[D tlbTN{0Ec󼾐hB*CCΗlJz^|ECiD`S22)䯎 xr$KЛ#}n%V Graǧ@s(7Ȩga!v*m|Uj+%e0OLCD[Me(v̕OaAɂ΍{@",FmM!n<#-  bU?Vza~ >4'*%t?n?F4?PKSF'%_3taurus/qt/qtgui/taurusgui/macrolistener/__init__.pyTn0 +t)lkl-0%HfȰPMBeɣmQN`)v.QOeCWZGB@533U~:$Yeu+E0g^Oi6~mFtEIS ȗb DŽ[")%o蕮/ hԁ`w uhq~3{?{|#w->N(4ϙ&:3~p) em8NC/q -|`]d&j(R]A҇D<-)#xjkeWYғTIM> ovP}÷<ƴkKd"F{vI9}t}u$083PR!IJ=$#H !J*\aHCT=.`Msk98 AWA/YN&<Ňes˷J])wl'[(Fy>2{! _FpE@;]K(">e57/i76:c\[ɘyĐ=ʱJM*֚v$ͪlI Lie^lf\V]&؞Z .Ӏ7gﳍ:O=]_b$aK\*]c{Ŀy;E&Nv|#깧Ys.b8?MLn_PKSFCDml taurus/qt/qtgui/test/__init__.py10 E[Z H]``bCb@ !,$qS?= 5;D̰d,4ZoVH,A)F)0b\f٩zzkLǛnޫmlJ+='9:Jڟ~1~E?PKSF'%taurus/qt/qtgui/test/base/__init__.pyRMO0WJʗ8[DBI'Y ǎcqЮ8p%-^fhI1r1ؼNaٌ9kSP˚w&yrpD˥cCIFJW7ln? UɉjMI ݮyiɨ*z`Ňk'K]cZ/u9Btj((NYKd^،bwo &Ԇ mZgF{<^(ĥ`2銧~o5O3vXUkKwh D}6qʸ}zKL?16 2nkz}9h1 H;j̠_PKSF!Txs taurus/qt/qtgui/help/__init__.pyn0z "@I@6ڇ) EQ4XQ$C߽KRzI;ߎ֙%ɶA0YZY'5qF!Y[dSI2 ׮"xDp[ _1d!oLd?1eJ+z۫޵d^VOaraq7-ZJ O?`r;6 dE >ۓPZHqfb8Y|n=O]uU1glu8k9o#1f cwy.5n5~k?8΂PXNbcLQrW^F#hl]9=l O*Nö PKSFM*taurus/qt/qtgui/help/helppanel/__init__.pyՒ[k0)&V|8P schiwN^\?hlu,WچJT]u@҆=H/!!N;d˴mK[ >kN1keKƄxnA%"x0F)fheZ9@(V*ft,lr2Nc&oSۜlv.6wP -ң1QkDߩ h@aڎ/$F^N{_\IXuTxQQ3a%XӬg֚^[?_v@o9Q_)7 }0J E8UVNtoQ< ^;RPKSF/t*taurus/qt/qtgui/help/assistant/__init__.pyeOO0 uHhGBp Pw:qY38gJC+x w} .zBf4i :T"yJoaUMJ q BN?ya|V~?0\(bPzԭxn 'qpi,֝uSNҩ2 F{tQ %,+E۪[]ɡS7dv.Y՝-ExfK:q,З%fe՘3@?P u๬UO[@OF={SJ!w53,^$q=cv:־ҤnZ<0b\|i;%y噠; ͌PKSFc \>,taurus/qt/qtgui/help/aboutdialog/__init__.pye]k0+70꾩֡cÍ1Jmfdikv) Alq)e]uC'ie {,R.JD7lu3jGe' 'ӫeJS&h 0:sUr N5k75b1Iu75f% & SAd-.+݆*F㝚|wy R9${N$d|bLL$!+%H!tH9#59x1EIq&٦;aug ٤ng腮B0f$evA)}DD[؄ #F $[lm8AW ψ>>[D[tȌ+j̹(:boK&ڃ67ThJ|fc{͆4kdj5tge^3xިt1q?碇&UcY,vkvKDpNހ벪djwREqGҍ/q Z/M)>-5NL"JXܶS JΪ@oe&JԔxSh'“y>j x"8_ԉBI=d H\~řٿAg%/k>PKSFS ۚ(taurus/qt/qtgui/extra_guiqwt/__init__.pyUMO@WBH%*Zġ$"a EUemzz7i}gv^|CYۙ72J;o I"Q.qUZUqHb4z2 G$cx;ztp/FҍۈX{ {7OЅ0*!@vA\/ (khSV-v]ȿMdn%v"l5|U3 m+^Mrɪ_*,s q/=4F82;'0ւK/)HjZl6%Fw0+VpwF;Iq*Gd3[YQ m [ <+ڱhό49sU\p >2*M 1Iz\0!\~Ro {* ^u>\r6$ +Kͨ?7ANd! 3G~BZugPsnjБ Ŗs&-ʝ<3#t^33>B/=­ rk ~xX#ޥP6ZD(QUZʿ f_[ tЋM,|q&ykË *PoPKSF[70taurus/qt/qtgui/extra_guiqwt/builder/__init__.pyXMo6W䰀Iz;1`'MX#0E$(YN.E\y|%6:m3.7X[6jVXզZ&h臵-V+O1Ṷ صQs:h*O}hV[q SY1sng㯞vNcH@QQun?آgSK?ա)ßk!#ZЃP~&1:/Q΁Q\%\"x3 x(m`c])xkHwW5Z?ϥu"YkiO&>/"yRO%4]XqADT4" :Jqa6xĄz=_suHᤁ޺r\ Njg׽fNy <:}N&NUmyM|?-?ҿCqs PKSF%4taurus/qt/qtgui/extra_guiqwt/curvesmodel/__init__.pyS]o0}TZ뾤>0`Z$gP[M&p̹w dsϹ>Φ\E!J3gN$ĨaRx}cdH! +l [l㾃V9hy*S# c`&Ѥdwu<V&YCm%`[sFE+HOU%A $;̈j36vt4 Ft>(0"zZCfVq_UG}s8Q?`*yy[2H5cOPZ9l!K'f9yFvt-݉o kD=$+B/K%emH :__C& IԮRo8I %]D2(C&xr+mR;^7U+l,&:tGP5CLX{t}Uᡫ9%mUiJ2u>K^5yZS^rA#,8A̍VV {?84Mjд=!JB(G+pE[pFB&8"L8ʹtt=xlaY~l mCϕ ZuS0CC5ԮcT`(ͼ&.3sHq`t\7wu9gX8t( NdzqtAn.ʤ1I-K1 ͪ ƞXp3^`g4?6:#窚lܩo^P}^UϨPKSFО .taurus/qt/qtgui/extra_guiqwt/image/__init__.pyYmO0_/4"$> VEP7MSdKH|at~gNhLc7|=v0ҒJ( e1H"FULR u^ѐ'ApL/QT(4pIJhj/BC. }k#9ru9K@djuFf~!2 P ǽQ4Z#64 NƌmA c4AN,\\>Aq! [%X[n| [ȥ0p()®ܩ(Wrt`˪fNSݮ'z} $'.y榍BqCC0*I j 琌t ?hO95gѲ3vmsq;@*I$x6.;4.ڷa5fW[әPXopuo\xf6<*f[5Lw!jΎ /hW_zE s? TRٌ]9مr(u2f"9j͙~\r#tYRQ* ];u긂I%h[dTH<';*Og֎HQR7WWxx1rclu ++(!2Bi$\xJ*S?^zs?PKSF! -taurus/qt/qtgui/extra_guiqwt/plot/__init__.pyWmo6_/m`I4k5`e, B`̙"U~GYa)&M^ȻSUAc!\fJi.P"W҉ TZ!Hp3tߑy A,׹هZ2ϰk=nݧɟ{Nxm # U&6x-\_P$r{u۫ݳor6"2Cft5:p4 )Q/raI=w 0fJ`B9NqH΄JqBQ>CnK.":AtenNXJe=I1"YݒW$nKޔ0ygy:PBi[_Kh\ʢQ~K,$`BXUY]I'@M`;m$#eWyR8Un LU+2{γ..5蔥YWX;Yo ?$6o+-]LVˆ3k"cUSOdI[h7TҠ{ޕgPeiiW(ucpn`ƈ$ 0`Hd$ٕ(t2'yLkoՈ꟬ɧn9˙h=_ f1OSnVEYRpbn!Ӫor}QOf!9e fJ*u =^Ph*|ce.|"Ao| 4}3L}UEѠc.hkLdX"](^GL(o)~ H%[j 1*H.x_ujufD]{^ܬlBfH b&DmY}~av>׺)론y!!'%QޓL\Ov=ٴCre(PTa `nMWGwl/PKSFDc 6taurus/qt/qtgui/extra_guiqwt/taurustrend2d/__init__.pyՖO0Wek+ c K"@76MSdKtΉ&rMAQ|b JMLuLFZz&9D!);Qj(pKZzJ7/M・{[~A'kPHj#VڠW9(52Fv#&Z{"d]0!H8|X3ZB*CSQ B( $p1ޜOllmU!lL>MmJr܉\\, c59 Z¾\7_h C{aW-l9[X$[v*T69AW/j_\G:53& Ar.3]z5ڊCn#1_nK"F, BPOPd{Z\5i-p(MUMZ"Sw7ٱ9-4e<RQ( -Lu+,HmAc(ZV.鷯1|&i8OߛGu6*~&oR_>GB˒~*!Zg ģ.M9Pk%C~M"\%}k *ۻH?YbᄅdKN5>ancYsjq:`ejH4 J] a>{"J+PKSFM.taurus/qt/qtgui/extra_guiqwt/tools/__init__.pyWo6~_6q]>8=; 0҉L.yJ=R-K y}<wdz3( q| Fk#Z52dU9c2Fi{ q0={fk}$mi]K lxlRPRWJhX0x:%|-RLf‚50P\(8PjBH%H 22%PUC݂AH'hM%49+W @ yt̨Xf]s1˽Sly;N^%'z冗R؇W gx%܂[?Acqj3. trhEK}oltv+/CmEhChݩC&eʭ?Ke%†5 M2zB+zEt &;QS pZύ8pLs X`Y쮡_΃wP;pM{]_{*#m8iN XUXu۪vkfTWm…?f61]Y`N\"Fƅ&|ȤFSym!'䦎٥tMK7Q+H cIh;ҥ'5e౧cDIhOUHd>W5!K1OŹok5Eb4{J}qRH;sI$NG(m5`rb<$N*c3#?0`A+h wSL Dh/Qȱ+ 1ͧhh p lF1U?ܱ&nЊvL/JxM#k*%gPxt|'zV[\E(tbny{^-jPKSF ^D<4taurus/qt/qtgui/compact/abstractswitcher/__init__.pyTQO0~ϯ k+ /-M"MSdcBǿߝBI&1wwϩ7iWuyHi ]RŬR4zlt8Rsh{ҭ}.UH֑jVR0`D/G*z냫̗`rK]4.P:$N_D UB'tOf Qzdz4} Z(ms/>A+Z]p6*x>&X5h/5HMZXtjU>S:mS/R4+Ml]ޛ9W9ta{<.ҴI Mk#&laL4N{) Ԣ|r3'K-'DCA%MġPXBS:|AVWȪݎhӁVy-JuJA8TniFh&q+=l,BJ/[n8Vw>L cZ1vF:[/υղ7[1 J9t:ֹ%0jId^ƒ"sl+X;t]n볨k {%$Xge,!Jz -Vid'qYu2е=eN ʪr3haFͻ 6e%ЅOYdzyV +2[nB6]0sqXԦ(N4so*i!]8naw5ySv*Xn}% Ͽc(ntPKSF_56-taurus/qt/qtgui/tree/taurusdbtree/__init__.pyXo0~_h+AEalb:VB\Rk]lg=wNڅu-4i䩹ߝƩVia a|gK-WK+Wł@ nDzB,hD3"n0"f W Ca6VԿn= =o9H;π& 8` u;[cJn=f9`Lȸ3befA4g1-_ѐPY(|R6[HVkk~>\RBތYnU=!1*!C+[E-j8" teY|iUȤ}}1?#f.*En8e2gE5frj5m=Jyo*sƿviWӣx6ҖhTqPTtnFU+`Vq jƎ Uerj_pS30@xYv Y$\7,a,E]TsNfN &/:HY!Pɔg!.Sh!][t]#=6h{\qT> jO,.y CZE(Zh[a[M7j\α5ujFV4oS}'8k֔jEZ#u[Z03@%IHB{>),.*l;n(\̷؆;<V6G6\zq4M7/r_}~PKSF5)c +taurus/qt/qtgui/tree/taurustree/__init__.pyTn1+|)IH)T@FTF N+g=ⵣMg6J }ofތg.,B3Uo-zEe<ʚ2yնشyF;#`+%$~ܞ1%3f< {.[z#}ijq7AWJ DGj/6m0Z,G辰w&\u 7OkK(Y&β,c-ƄԼ;Up=acMK ;0"31tԕK08 a*b lOJ`|hsr 3|Ati:Ps@e1PT'MkD/1DV@ɃckJ%?Bk"\[fi,hϕQ>Ng/ߵ5 F`g47G'/,O(-q,e_;-L~]BB#E3Jek>CT>jj#6%nd;P=%5 s-`tӔ O:XtM 3^?a1Ve؃T;|p)uk ÓBX1SWГi#=_(tϱӬb"d03#H ,/v\OY{Ǻb'%=a$3Q-ܥWV. }L{#N۲ PDXfRKjط'2NƆ{:v]GKy5O) VxșkZfqid턊[屏#.*G43Yyi(1`t>J)Oj5o>w=ݎU=k'};JPO/8H75"w`=Gڱ띃&.폜l;"5N{*k!s`,2XJu+q!L,Kv.4f̐UHaVԜ蚞4FVgªR]%O/S 5UnJE&;HrXL6 ^ l:g̡KW6ˡ)Fx u[fB\y8֊crX08ahstIhzDWS% OIZczc)Wf(.cG |io6U]Iyf Č' *d}FJJr˹Hq%~Xm ù/CJcFnTz{?Vb_t?'}Ɂ?IĺXvbNۉX,'.Z/}k(6}aRS է>q")C"fln¯ l :﫾ͯ#]N<<88$Sx_-~_9Sq PKSFg^ &taurus/qt/qtgui/tree/qtree/__init__.pyVn0}W uR RAtEinKbٵ$e2U>'6K2e*8( 9QԎY8it A];q˷d[*lIpkz'֝~k1މ(CwXEGQZqL q6PDB\I'Pc|2dWQS2*:hy;⠭:` #?=Qb# K4A; -w|KdK-L-&!X\@ FT)O_SwRi*#Si/2m`W;cr5,WF=]rW?O;YU2d뮙_\-yo"`NL4%h_[>< yDLُL)4C˛m%[ v7}%;סK+Z[p"s_!/-;fOA^\Iu{̄d^Ư-׹  7s=\ nnFaUn* oÿ||PKSFJщL$taurus/qt/qtgui/resource/__init__.pyOK1m ߠ7=T] ev0ɤެ :!y/#`"RiR4r`[ƈ+\20Tx@(B>MxV͙i_Cs,FGvkcc(wCs\k{pxe?}Jv=^bkt^[ Y~'PKSFi,:taurus/qt/qtgui/resource/taurus_resource_utils/__init__.pyS]K@}_IR>H)+; "e7١܈ڧ93'IeJ5=Jeu)xbd0Bk3*BRvWR"'cB^Mo)k"]<NW<mi"R\lilsrL xwiRUʬ.msSC;?0/Nw[`ٵtfDF,[5Jj$[G8&[$|:lɹȲY~|GC֖=__c28@C3$ Fu@e Z#Uã6@%#z9k$^"伓յ^7 u)4zSoIU ) )=lN$ݣ/PKSFcLO]taurus/qt/Qt/__init__.pyYw8(_{95Noi)3ŇheTsI[X3{f]sʈ@,<TWu?<6/޶H ٢JjmųVxsOۛ旷7b̮g7w{@>ϧ &h69mn>_Ϛ-M凛v(yQr8…,[eꖟxunbosX=h{HfuNXDev"*JxkY^v]xN"E&_fۺ}tYYgE?z,./,n:jBF8?9YNj4f[e'ER%1Ə )X]򺉶{Ȼ4J e|EYv:duUYfQ%YsDQyo;~PD ߿̞ZOE[~Y'YR-w.˽v˛ @>7yWI =a\*>y Wry-!a6kwy˯ɲZ1wdm}7Iu6;4{ilѵ?>gŏ&K\}⊨5)zx (/I_6Q${HV\$ L!?h4f;e@v3yg/O͇ˇ`fp<'M4 3ϠCAaJ!l[reb\`y8?gH"=NrFKAA$Vo?hQe&BE];/QzqWuͪHy!PfEui~p_gB!܊1_25f(DU! w@_G%!f9R&Ĕ).b [8Ӽ@1n+q=(~ 3XSތ}=kUu\pyϓ4>Vpgi]7&Y]TcƯ Q(A jl gAEu>-Khlٲ相*diJ é[[ME Z~y:Ov؇MDsT:mLs\{?,stE Sfǁӗg] Ϊ] |b ?ߣC -xKo xsVpрmSS)MȰtE$J^'2dWKeRįTK"-R!}k}~ĩ27I*?<ʺ^9Ym 6p!^;bUm=°?OL3HJƭ{~PH2,E+mm>o, d/RAb Lq`$y8E :aM &bYQC=՜j"8|:P%KXhSJW`筭?L?;* LPH!7c?Tz*u㟠Mt2٪3(0(^=lbM= z b^ˍ +OxfZE=UQ &JvZC?@󋸔&>Չjl!g" PA-OIEݚ] F\BoOrQ$ըpb{HhÔj&9S\ 3AG䯇*4rv]8r]vs4n"yIY.JrX촉gwp ?#iLrIfN1Y&NҼ4:* Dd>UF_kug50IY?%ɹ|>N3WWqDv5D)S,$ =vrB>uU|h]vˇg2@ۺXC\ 8+JXJw>C= y  7<+Ͱ9{;3GX6Ǔ6F9-Mv߉= ;KAMSxhR޸}'q8hoVa(hotqW0W0fJiPx'*LZ<( `Hc)[OS zD@N„Dl{nTG;eh7/<}v ~Nuxw-~3LɵMyۥy*:~^<<wHg!+ܰ)kN@L#-x{rxl q= B (Q)ExMuF2 G IࢌLY!)(q3C}.KN9{=dyQ-tث@v7 iHQ8爕cXh뗂fa v.W5s- QHqE]$F<$m"C5N DV$D=è UR@8r/1);yHz>Wu84 v4`HU[a8$Uk25 ^)&AK :UbJAQ"?8$9 12N݆ VR'{l?9{t>MrAҎ[J<m8i^g >vy >:rMW)܋jJuL ,.ؘ#e;m6B{ĘydM5 ='Xo_bMԱg8%@;"a\nDx/ 3'Na<֙s{gq!I'_zF<=>q IdX/>`88`eK@ xdN]>(~9v7N>o3Pm¨|WLnJ >hΩ0)Pg=q'ϋ:[0"=笇#v 5ﳙ]BSAF* ~gWwڞ*V#K"/ TuPhL8yP,T`PݧExkc(  './H@u%4W>8=IE|o7GUA'?%mM5~QB6Z7*Q }w`ڍk}s.);{WѬ~dcO,,pQsv8}xc kpI0O%Y\X?ozbCd&>QTsU_ݟľmO9(p{EUNϝ߫N^Q{C-Q{lLimyf{2eF裗MNYR%Tb<kzBÕ^N \LBNǣHG&?hӌ8B~gβExGтBdEuxɃODxqXߋqGFzxKS7OPP 6g _;07G<ɿi7l~\W _X9+y2 oڨRFd}.lr;D+ZwMFz=Det'q.4"G;3.8:FZ7a /q\wք\$7S Ll^A5vfC5pt -umcNM-46҉8ta !u 2^ B; Pa[H(䯐!jҀ=x2:sYΫFUċ#?O ?M4џ&DOi?M4&4QdK>by[*V Uox[*x7VtXu^z|Q~t}DN4krk\ok[(i/.=wM泤,)峤,)>K`Oy.QõI<)JuGkū8[q`ŏ|M5*#2:zB&D y)آ,Y m%trۺƔ3"fr>;)yF[Cu 4Zt-|fzR@zevr)t4װ"ؓ q1|ڂm9ncG`Qְm0ԯ'ŲB6M$6G&WY)kWu#}&j8i10t0Mj eE@, m2`+۱ w~k[ ¡ovۼŻ/!Ew;[2eHs/O=[c2'6L+WCdu ô&(С|% 40EΛRGx4emp)FNwQ]<ȥ;'WAIۙ:pK8n]:QSe1. |\7p0vP -9@/_`46[닝HG]H>’NZ"kh &-=:lp3ʑ\}?m^%[w64.נ>z8!#YPrl^ 'k0U^|^ܸ2t Nsw =C$&R $5U(?f=ŕ =a,8CyLn-5= 1jXy;|eplreR? h0ۢ $dD7X +܅( 4xtIȍh:[1S]l|XҜ8k/w,P3QEp?+1JSٍ5`˜\wc‘ؓg6HK-Nn T`. ]е.FwAY]Ce<P<7it-ڤ" X=[v* 00 Hf- A07nFso8xpjN-B+Y\,D]Z`u̔oA%MddQfN!}wHnN=N;-E9Э`ΣoQ=#h/h`nrď4nY+;41nacf5#1ϤtКU`6,8,Yd5j/Jloaj_G]U=e*|1ntl*觇oСOeR,WUQif̰kiQ_w”nQhj+:lsvypQeˣ 8y#j6n"f%;(u"M6˷To*3>Ng 3f_ha)JW܆.[AL`?=ƙ ï\ ' L׭㝠 ސ6#-l':>Fߨ[;v=i 7q+֯P#mjfޢpVWD~]60ހ~n(jôs *cq] !j[j֏gRMlP׵ 0i>b+tB9hb\밉j3qu(R$'p.j_\gQc)U]J=z`m k!Sdjc[4گÃS (>WUоFe ezaTix /m$ӧFB+mk_h Y>/7 ֋TjRIvBC YÛ=aYX9]hO{$(ebq ^! f!8K6$s߫*ۈ*h AШ5#L aP#xUC}#$], C?g&8lW>ƻ&`ˬr%|'Eu˂(XNM}РU,Wʓ/ɞ[u0NJ0tpI{&QJX>HLX47pk![%aEc ;eK7@5|E6gNh̕@`=mV-I:-uAGf6o GܐnRIs VVN$8p5:6*Ir-F zl|㉃? ]X{\θHOQړS,Lv'ґI%%}{9hIB=q?=5UOI8'mOZgķ@8P~6顐}X딏I7X6҈Y*yh^xR'Xi]'ٍ־NKav{\α+1_ sr!)Czinm<[ĭGx0^:"-ĵ2A3+FzK7`R Ϣ<7q:9LUa;9аū>Qu/߭5_FX5ꝴ6i 0[)Gi =pwרq\pZx@w7ypwlY Q'ΰ=fFFgAqh2(L6܉;u<)c8H鿻+|zP%pڪu3 5~ P12=t0 sKLSPḍyh 9](hek%~{~(]V^Yvz ݰ˱~C,c % DVیNZ;V'1xY]}d\5Y L4y| 9FB{P yDfca=A'2fgZrvp@6p fcp.Y.4mlEel@bx3Q S,eCo td>3u_* οab/| t@/ t@o7Dbr6+UVrx؆_fOhF:'~QyMCΪOmc̀N34wA=2vl񸅳g?{Nφ-󳁋b26 Mu]^RHH\bXa5*$} }F8h!;'*A`Bx: &uH8lbg&r$P4&& vYU=1uϥ_0mS[V^<;e8ně63Zy_q̌aaӆj ,9}}xacՎC4h#GN 31jS[6`:1܏0 &Uc|?9)d7nVm֞3sYNo+:oA p4xdl6KS_NyG`< 0JmQ`ykS[^I^bl3F=qe$ **%~Im@邧tZ!3 zC-ė H)[Yªb-qF eG?V5k9bO_׊ Cрx=Zi-Yf1> g>}Og>E9Lj޴"'}RPOuIV{%ZM.GBus2aUHi@{qi~tLp8ؗˆJDIe6[iTEhbEWst&&]$5G T {/>U=wpG@{{TЧ0B>G-Ra -=Q4RK *MзtW 'LƀлL4-rg4l}N>齹g5.r|V?nʯR ܶ:ҝ!Ԝ@ȖQglcmfT871҃NSq*/]JRqB49|Hu}.D^Fk|!IV>4ha&j2ĠͬMS)abbb]@nxyn/2[hőhu zvZOT೸@eAV{q<)/>!ȁ zQo(su\XHTq?$حG[ h:18Ѥ=#,|R$J 81M -ؠ* `7-ίN [0دHJgRЁB=y.>d- ,˄2Č43o@smw8B0y  ¡[*t,AJ=ټo2UEM'SrR=}!8'IH:B6Y?ʹ?w$禗3Wg~Ԏhai={T񁡴ĸyηaUD9Η3 9~T)CSL΄]HL\܋gd_oڐkx*%B, +'Ԣ|CI/XqI>2@T>*vᎬ&)+S &'0M p/JPzE\Vf> nfxOOnܧNʒ"rH^1\ щ^hy`~^`I0ϯ5h1Ņ}Cҙ֏w"`WP&&ˇ,`>f +H%ǨZ9^2>@otD 4>A1 KP\[. s sqg{U=HJnG4t]0N FR9xSsij FF={psվ(Xrv]` y~l?^_+רeWftNGhOun  !0||$@%Ȉs{=^z{=IGjWx{5ޫ^?jW~|Ux{ޫ^*W Ux{ݨ]ZNuz{^:NuӟE%֑ $/aDA&jdE?{]2Wy\($. ["MsT`kMd߿(336z .L'v>C5,2Ĝ  iiRF1 K05IhrD(5.$%,bcUR: 1O%]Nd螽b"KF1=դ0d$3k%@yU"{n^]=IR}n|$MmYe)٤Xx2h; m\)IQZԬ$OY~k]S̸adU s=VY@ɕ,ҝ]sW"ܙ`Iz?^j󼒱ل8 ک),y3,@cON0UIoo&_P3q%|"wIOʙUj}ۢ=5{!78-9#JS\#GnB6́ 05`.馃f\zb=̠Qe[!JqR2^'wz+MEQg _$ _UxAʯnCq:54 xx;h]>gv\~G7o䞦ʐ|=%YFEᒤb'io((v0u3KHP3_IYKTTv|l]`2m]2Eo@Y&#ю9cN~ q.DۤRbt(ϖqr.sj29cȋHeyHQnL&תoCuGY;%\W",ކ6&_ٕ.4$W0Ϫ!GYD$G,u\x5^tyDL,X |A}0Lf}֐~ThK Rsa d-ߒ74U~zO8tۊsvmO?QclFH2EY9I:::r.L_\eHȚv%Bk ĬW_!iZyw(J t7|N[L@Pls~ʪ~ Ǽu P6 fU-VGu&&p Ǹ%XQ=dOAuH7#EUyw!ж:й9*gqP#w/u|Ce3 3Z+|_w`̗,%]k ,h) 4R#(NQB pT@L'"IyGe**ۇ8 lLهMŎuT?L_"؁1 I2,kVBI~|O|\Etc-*ѧmav/a׻(еQr<ݮT"g #L䌼3{[slov|Dl 퉉=HLgmцbJ;[`e@svH x\-&8a_ 26i仑Vdg{ۖ*qVCA?S; ;0:c񝣲tP|ј49iU(p̧̩h*`2vG v{Sʺ@% ' (یWf3"0Ɏ%<2`.+M)0 &h #WU^ZlywZu6JBۦK\1Fʃ9. "GROn:{$eQ!@\zqԮwWuDmw2_L #צּ9?`̟s09?`LTx2C]Hwt1kn%4Kb;G0h˵s6bOX8d ~u '|Y+ȷ8Ӛ$v:Uo>Aj2\ζEU{Y|) Ƒ1c <#O`Ie `iߛZoeqZgOO.Gk! BfΌ[tB@abiX2qͅGU!B(4|BtoFȹWVߘ O pbpD)e|Yś`'9t0PV`<=eS9k눷 9Q$I]_* § h?i/hky\f cjJqeQ& o~A6c'84t㞖JXeJo{zI%j6~Y s|;d ,00#=~bDRY"y/xEG%x.coFGXQb'jD4&7Ti'Ȉ-Dgϫb>3 psDcP/CٲfCo⪐!?54 Z~g6Q,*&woAoLOad>Oass8ry293|L3ϙ3-Q{߫^W<^:ߥNuy{]^.uy{]](>y{}^>yϿO}WBz{+^y+^ {TiʽBz{+^ WBzпS>y{}^>w6F5z{k^?F.5z{+^ WB{+NO64Fm4?(?6G?h"^x)⥈"^RD䇯~I◎lfgBMЀ''|& G6/*c«Ta](̂N)ԣuYQV%QD%|AC<rn tV>Cы#*$f;uuqdfWJJd03 ..A.^ rs ~-"7cPպ? 754G [x4|nSMԙ)R4bv>JJޑؙ1.l)AE)uz鬄 ԘmbhsHީ:{&R EUZq[`lf^7ͼnuuD,N㧨N+`YeUȱRQ+  t&z#([J#v $h8-(lBw)Q{;R[t..`Z㼪r[s:E*~ ?HsD(9,m9Ewۜ8# +JQ-j[}ӺG>B]5rvzm9q/`xа@)ހ|OV5X(̃_̀b130tx39$b ,ϱ(߱ПX7 ~T5q3YVE,Ohu5L6@T&qsq,J씏Ų ))HJƭ+!MZXx"+_6;t Lװwd͙߷HDs[HeLH j,9T` 4--HAsWc'G]\83j`w@F ӊM _:2>)?ΰ)sX@-VE\-֦%D}Q=%D}Q)JW Ux{ޫ^*W U—U^3]_Vj ۦrv79oxs79́[ѡgFtWPh-`B,~-77|E-xfcxA-.BHK҂ m}zYãznHJ6ox#1ވF7b㍘ox#1ƈer{fLG/a-JR$.dV^&r %,9p7yNױ?B /k٫?Jh_)lWW:2~Sa-J|:r`r5;y!@h0!kA4Y&B٦˜T^Z ̆QX6NU@oA_=b#; ۋ([qѕ%FuM$̊"_;7[heM+.f$2Q+I6Hf2[I^Rt#p^ RHR$PY:{$W?-ӅзR`(:YQ8DާQ)xH9_2 T[;/Z)OøPi+eR{{Pȋ|&Q]-xsؖ_HڛK{X-{n_H4{2>kWIIc``>lQ|yϗ|yϗ|yϗ|yׁ|yϗ|ϗe^?_z{ޫVk^#Z}i>fCo^wU-od<및Y\Hxtis:o byGAft65}txii׏?A#6(Ec<):ُ$W;qw%{@Z6Hǁ sD:mMiVҶ`kew Moh##o[zۖƤ7@T Ik@Nvy?tS#R%*d۝h@'>`)>I6y,kNdCJ a"Hk{)8w=o]<@ D}bU-}@vvr Z2 JBO+0=y3 w<\M)hfR"i Jfiph7,)߀jazYBe6iFa=~KEqg#l#87Ҙ\FEɔ_PrìXᓍeX2GXM3h g4Ʒ'z5?IE:ɶe>~Nf6" GAR="d65Ēi۴CfaOLP!Ql8h{Fal4lc:!.)Bf|N60R!-W>ͥyKl&\*zr7'lGw_l-<.BJM2,wd732@ݨp*?]D'ۣHh}OO7n󘧥1t- Ҿ12Qd\)Hʹ)dQDG""7Ia"[C~ni(SD n fBF$״5v$nV"X,glw |a:E~a_t*qg߼ӺHM=DŇ"Z&9UqZAwSW|UųڴS\PxcIVtٶR__BO{iEmȂBϕs*>g|)'ڵѬ߅OAا qk˂pb>OB?吽3ҿߌZdm 'θ?ЄbK?֍a0=/r/r@CR>wu[9zi\z菞92%՚Y<3W$Q\TIL U:"g6PkehGکl#EiwUj(IJEYE"vD'^Fq@w uL Ȍ\Dԥ)t4J%:E\:fo'n*_"Ƴ>4i!4G`Nbr}I)nq1C^.!]O|I Їep:<.,NNq(%#~\H)gfu8t h^@GOHw;g t4/kclqD0etyLK\,IT`2]3tℭ Yx 'mv:u^E>2M7 [IзgV(D /D6c<]vDj!kC ?+Eþ40dzPh@mXe8GP:<70R|A_bT͟m#n8)ydJ'9{潴-N=)0sX6ӤܦN_O~P\+>S ~9*bg4AcZ'G]>,Cy3`t $5q"_ =Cz$yx)tѾu2qj>y>HP q,012R sԵ2+.L1 .Owi[u<Ű*( ̘T yF_$PoHsBQ44"aS.eK'ǿ(9AP3@r)4%s]lP ݃& (ꈶuqPwqsC⇁)jPF=(C+<%ʏ? ׉ԧLXxx%k⋨. 㾈^DvEK<\`;Ԣ!GH&u.HϣhE(>~"/̈xZaacXv }rEK J"-_ \_}h\'yD7_@g`'TJ/ZbD/7-˯|usg;դ|%/cZc Ư~1UWucɎ!nMB0oZ%~$cXϓzG]!1d"GFo*l<a gQiT@HVc+"Pj$?n4k3ZoWJc [/Q.73"zL{*☨ eeeP8 ̽jNŠTQAlgu|1Mwu oW$b* x$|AHkX6^KA <W g ۫ZBDpԸ{i—@j~ƺ5f`/uAUCc#u rB)^ګ Tchaìrk@6q\UL+gl~HH/lJq2L \]A 6I7)@#u(J|Jj1X4KĢ@Xy#kPat9@Iͭvy^zj! ȑ-аUk dQX#20  \"nBm$ 5ְێ=QT@eyaߢ;䯓S: 1uHlDװ!7L*ogAR cb(ȋQ[n;"5&}Q_KD!j4^9`/'X܈?KD&~̮X󭴛d1}$۩$M*7yƂff?"}M*Pg0ă.PYO%@LXbf 8&flĕn`s7UvHX(r|+<&>#a-E7=T!ph#>Og+TJo|.H;r>7^IEm˄yh>3Á)֔ZߗrHY /qAffX-}qAL:C2$o٢d 3l,AAv M[٦r#\F  GTݒ}a}=yaY#S\ 2 \5M=یV,gU'3{X"%;B(l0qN ̲VwVddkkV?I.יfU_Tw~Hר[|TW}NjYv(G)b/ゞ"kWBAT&(}dw_pÂ"O:'5V[#L/#)0:)Kk;X+&;Q]Hvqe6-MC=sӜ 2`7F[CEN_"T~-K*nA ײFElEhF+iMy\fu6G_ :DTs0D ZK%+ަza){p szscC:j'[sEB6g7.ka(*)l?F+{f7/s6-eus&R"Vñ- (iٰ~^ 8Q1?#J/;?'ڡNCSn'w*^"mٌfG`K J2\u^-~&s$2$sQJcKh$ [d~:'1QvT;E_~2Rp/I\ݐ]- C93g Uq[spfr> $y]ծ] h_/BJMŚCg]ZM|Z[voR s= o*ə5~QH/Q %7F&MJj%0N;ʡdj&Q%$Sro$efU( bfgQl: rF )ʊ@ϙbh%#pJ6Mk7LxB ja8MqcOVIRVi?1r3m6 et"s&7?bW>^0r$IAA0NdBO>PPA A2ւlՏaHZ5*2~ ollٔ\w2@:2⒮WNϮZgYE|: F HRh,.N2#[ gZ; $QnjV]׭mL%'acod ?P'r%Ӝ1)ġ.Wm(/qR !?ȄE͡c*T3g\\w=8ߩ\3L}Yw'L?aҞ|A0I|='D# uIT/S>$3zrn͎3b x'IfؓOwĢ]HGsrIaKn'Ow܄|Qp:)'} P >Vgtf"E!O#Рnab!>qvelR;3&I(@Wq44(%{@ ӓSO >ÿЙ/S\DV]$syAxړs 0!k|Ȭ32! wir |DggCkζBD×Ok>O}}zm^׶:O$ئ"^}{}}{}Ft ˥rzśܼpWu&_V,ԢCϺ?9-@Kin9h vB24E-ﴅ gqUoO SNˬڛ鵛?ON+!Hf?hxet J eUtGc((ݮ4e5;*3aTO\8XJUghVs|ObCUhD6-~uY*=q}#6x6Ap[$,< FRl0;6gFcjNyboR=`J,/(p,ӿ"(̛ypOǜ4/Hnz9)T ZIvЕ^.{6XvDE+Õ*.&a ' SKPɋBt?+bgJp`eAL^~2g\ۘZ9t,((­7dr(߸8˪q4w<+8 #4sRS:.nuS-¡U^H/#_`2s";MW{{zkvkvkv=^y] |˙@Z~@Zá.LF reDViT`܅lSz3hGW Star,z\Q qئ;=PaW>$vBӤTϫd܈7RP ^K9ҡZ>2R'<1U%yG$%+ Dh1A6_c$dO-HthνtƻDu7a/31Uٶ 0P[;a>KH>PޭR=fl+Buӽo.RI`IY7qch`x7y9%;ǻ,չ ڮh|G=fs s 3҇O߯Miߖ&Gs|]fa3 ?O#}c.'+`D>'˝(#?*:>T)p2:SzS"Z%dSwaI3G SoOWgʇ8rR_\гen5$vd*!1б@GkR p}|IטWQgEa#ƋZC'DȧXbh79Tjpzt4K~eKMnƩĊU|H=~3&>vO yO$XKbb̬ЁnJ ri]+2g"Lkh_|jWs(ucX^/rQ+&$񚍰܋,}Q%gr 'Ny@Ihrl/"*gq`"s|[|`&'] 6nMi_%~3F>&2^OuhH* -n;}uz=@ 몶"R%+e^ϋ:[I+gjmsdI2 *@ [R٦#ҭB3&??|>yR`󜧠7ymg]at, F̗:NؖѺSӸ[ w=]w=]@zz>O%5!63ߜ٢Ӵh8spnrN &?Zdt,1X:Ԭ-؜>eL Jӎ ؖ Z J |FiDI&Б~ὖP h~`S}AOڿn /YASTTG%{|j 2x#(923VSXI^'ܳ@>|Ua,?"ɵ".˚-rjx{)a\ zwgIY ۹Ǧ xc7yu.T'r$qez\4#oST@@@@<@D*W Ux{ޫ^?*W nTxkطCO?/kcp.}|Euٗ u%R"Ρh ot>OApv!yAh'bNEkkḃ:'#ֳt&kI[ -(a3q[.^ +e|󧂺}g3z_|30חαu %^fn%/x&0,ݓٮ|Y.,uF_)2Od[4g^1٭NBlKܮ09 H4&Z~G%<)LaPN<3N,I gS# \M' p@CqCg돣/CR ԃh<&ϚGQKʍ6hl`P[`y^ q2?rqB ;c4ŀ#;g3wQl=$x2 P帋K]4{.ڥ,TGr@2pW! c:cM>Hj'].`Bj@̍eEC?xa3dȔ Z0pgkH@c',&+W"![Dq7&Q:Z2bQ;H%ȎxGSںp8Y#;(L`Xo8O<@)onhlfpl-L2`;I,))'!vb>AeJгj ͺp@hɇZ>pޮuX& .l^KfVy8WEm?dҞH[VT$&@b'^2VpNV_8|brԤ;2O G3Jm 9?tҝ>;g;wCin/Y|qBwmBalܑ&MwMb[cW]#keb F]TuS! NGoȾxSp1/ "&,JUuoTyXb^ىM6~u~<8N>EN=cqsZ7o%DE&CvAPp%|"`pK yu#ȝy]KrH9 ;Qq JGþ?$@w|ܣ@9? ^-#H=Ev(S:AآpIˌedkXûŏ"%bdy{qPUOQE)8vOB\,(d~~ayv{L;OeUMGiEm"*:Mm P`CBbst17? Ώxʕ^*f6ґR)z戳"{x$a<%3I$$yKFAܸ+ yOzt&1xxa#!],D#Mgm[g;k &my #z5ʔt|b?Cr3bN͍ Y<7bc[]^=7M,|ʊsD#C7y=.+;(X'r,fTgCZ9]LϸެwQ88Kg&l):]e+bQ)^?zg[0k!wtJ .| _%ӵ2BM& p `4 /Q]b4D5:<7?p;OOXTKXgU>ӷIGC0X$'E^̓P0jz]TiwdN#aj&mKmh1yG:1 ?=`τe ݸFg{'¼7u{.ƤMo9 |Ju 8l,bCyDSG\&܈ꥃEȅxbyrwĖdQF{jd=#n6(Tܐv`r;hʶ[귺7]\Ȱ^d$"3E.ַkX;ln6sI"YLH<,B~f,:LvL}Rgjt*mؠQn$`AwԂ{ :K]48u(ƉƷ/$M=*څ& qz,'s=!fة{v0>߭{R$SmwDm[/ v!͊ug0yT wJ_e񀉳M J "pW1!g*WB|s $ n!z'SpYQ 1q0s^dɷͥiyΓ8% ULI* %Bh>S9C_?8u'g|<~%*,|]?87iִ"JaEc ;'nt%t$5r>O"=T~bȝk/7 %܄UK0,mqPsAE:qd*Y2 EYRH Ue2) JL 9=w}ڟ7Mb)F&]ļZ9OoPpN9IR@w9g&NX97B(!,피uGݠUj 喨^ Mm/Kf{7LQ")}3{E$X:?b#:$i09I3@:7#[ 伹vF#JSr8}Pް՗l;W$'Ojq9dT 5[lOuYS|83ν#?,:oso\#;Ṃ[zD0M1^ 'dz>̣@*ʼn+n 6ȑLẀO:6SN B]1O `L2"DL[v =,@-@1Y~V}奤4;~ɨ-ơesH7ߍŘ5;sՎ yd2=c[?y-(.in= BϷuQ6v.fY 3uѿ.cE~Ώ8#L:={;(=15`/M(Du6 BN MozXT<1{ Jg:6SnG޵%uSӍhh3tdgBcf1i[JGzdh0AF.vEi֪gcDM|y1.v!NC2CqdbjU`s qab Ğ%J]}fz.8R?X4y-d4JSS%d6/K_&ȼ0I4tC?)Tȿ}fh8'b'hX贀bm''&؍x^H+ﳦ*) Ȫjks}?ֆuǚ}q]w!gSS\6(bqܹyAy\sFXDzOpJ*"38&`LFi=qis+ᦩ\P2u胹!*Pc^NLd!*m ~q}Ru{B9Iݓ» Ou cR3,;qdk_-N*1}XzZi7(zrk]>'? UԞR~bz"t7b{!_#&=ǣdڹV:B jO? JS'!dz$=dB1t)"9.i.p e,-rgk.;ƘC\k~ۯcAj=j^cӯ//=9(q UTIɱ[3|aد~gl+8%w"- ͑_T߰mױz*a:HC{~xzJ)XaE'ԞP@wO=XRŞV{Z .\So3zyǝ[m_yr_a1~m@j[zv~E|⠧g~Gط!ֽn6HdJ{ͥ_b^xk֯]a{䆭UZmifo#! 'ԞP#9C> 7<쇧'tn7-ގޯ/~_*.olQlNd R~L{wV׿" j,@' BުpL*٧HjȜ |)/3~L 2aj/=WުIgդ߰juWYz:>en|R]i[xw/1FR Q<;8VvښV^RGYCIpv_.q@PL€|%& ^SrkǼɫ}CHi${ fsx_IC7ك>wXc֭h_zN=ڃ*1Y\VцymGSNvo߰0n߰2S׋_n}l^: (B|S,_yB\gn1Suֺx7~{1q> d Ŕ{E/ݒӽ%];f+-ԓv>:.Lw Yꪮ7W|MV F f\=)'Dr uDt掶6@Jaxa_!{.OfOC(AYUcR"L>z5vFYLS^M(D#4LlHko_6n,'/>rNǩw"+ 9 ж4/grm_&V o& #GH]qPzS(B J˯!_E䝈 _Bk"^.v"eŰ|Q&B8)v^~OPнU!?S٩j9T,_b^@9;_0pLh>B;5?4S:t+Cg$e'+|X2'ሟN-Zs̏$/xD*61 Ԡ`v4 Ѷ~_vdU$8N:itI ֤0ౣK< ؈$a!*~L捦ա> rӳK/EN룼Ew=AӼDUqr5)2pl]P3L}2WntO/t,f>2%l· Gyf__.Oj#vK&a&i'_T WuY %fYeeM{3ymg7gzQ6QН$R[uЃ66?N.N2ZD1 %XJhXKŕqB򗞂PjǢ<|x6cт'%dN 8@5 qD[H3|4D1 d;%}8S L 3!t&w_*N(ESr~|Wy8;h-`<2xz3x%v?t1;pB {ڤơ uhT2QBΨ ڑ6_:oi+#4cN)M}5tAݴHznj[`^^ Nn;VpokAa"E+e LKׇI t?ۜ y%݋awMÌڍ[Zшw}ܮGY0+a2R4°hHj#:qt_ZȐu^Ci$73vb*j@v9#"/T7}5C1]fTߺE$*gm濄ҔIc܀\}%Hb0_y EW,Eu¼ZV=[֚ἣx-<ە9=OHPc<[<: v2jUA5,aܶ)HE4;dVȅ9XN}.VN†F"L)ӉBg'Dl&˔)&$@٨讷G<# 2#d=0+g h)U.#d Cr˪{@Zmypi\!N]Ce#Bc< ZgV;!PS6PUCׂgɿ'+ս4Tד&U*Z_>`Օ]5/uY5QJxMiVZ0iyar5/7T>`rQ86Y)"6aYR:*mjW yT?K_P{q#M9M-ȇPW,]bNWH4T@+,@9#̩ꂦ]mEi([LI!FV-ܮi,SBΪԀwh -Ma5p(͉`n굅 otZicѦ-͓」m{RHG ؃b,cN2pݘ 79H ٺ勧A-Wf7puvtJ J`?r`J߁vBQ@(ydbGsG\{0 d`,m7L2SR wV-Oi'>9%NyuS24^qK'@*uf:1a)) #gvh |g`{Sl T;Ga{|*X?GQ/O A[jS*[.'']PLgv@mY",pϧ#\Z81e6k( X!q l#rw wlRvv8eamK<0㩔خA? 5]jB.:È>@>M0D 2ˇ1z |$9{i>gm IѲ ia"&JOo} 4H{QnH<졵s%.CtEuXX˱E&jW8 P C}SY4-ΰΡbwj:VhuDa)J@k$шY53Ҟ`LX2PJ* }0Z;8Y ޻bVaqh7啒lhYEa\QP#9-%A֠SMsLiT[{7Nb V0G6 -2C{C~֫zP ceDb n6Ș iFxΚ:t9U.shycrYmfE=Gs8. nDj[ "^ށqþ[ξw9υkW5X>Q^B6aBjQnhNXu;^b3g6+0]6G;J s!Km]!nƀHN(m^FB]@_6H 9larX]c\Ǯ՝nrƊ*OD*]\WOIԭúi Q̍i93EZU|,S27WY1E/\.70 O'bt$R%KKRvJo)=(~;NMd3h?^Yw;{_*xd婛ܫp2(o7 8[yݣbl 1A0:7 PrH.zv ~Kw,)<Ȉo`E5rwqGc%Gً*1D r [mNρ2[sOyְBtRԇʵ/GAyrVD)a;(K8"p#*+yyԽ]4Jx"4/4PtT+uk*AiZQ=37)皲" uYgJ*_f7pLh>BZ/?ji 䕳7@_tUWuե,$A?ie8k̏j &ou61 ̭4  9η GUѡKYrl- ijp%=,ܦg|2z6 taO8EUޘS hXaB59 PW4&/vΣ7טc=g=e.{vMr#3^*kP!3)a}uh:.gl& 5cd\^#GE+'x#\bL r = M9:\ @s_D3bj8A?gɷKNְXA9k~N||~4cڶrm")R<`q-lT|1 OF4]jD/Mo%AɈ9];$BGdƌ!d>0:[3иQEeIo%O,ܚ)N >2X3wsƀ9Բ{+<_evԶq^N_)^CV/\KfKW돫jqZ\??W믧YNa{{{{:|:F^  2n~\>}@g2516~桨V!=q=p}B٭Zx"D:58hx!.Wن)ڍYݩ׏l"BMޤMޤMޤMޤ|ӛIٛ77KՓmyS̻`TWp%2#*O& VwYV5C]:Ze 1mHeHȹS?i67H;4~.WB|o5t@J 75ël}$`O`-cs٘PY>Nrשhacl=PH{B,j^UȖ[0샳ڳ |0U:xumLس_E&̸sbVJVxrXf7Ec酃7uixx~9rz6uz iJWG || &$Q"#Z(@| 5i漃`?=vb2itqȄ|#G*yG*XaKzH`#o=l"32@ZWzSq]?$/Ec*m|,.3$4rʜIt?z3r%:3F]K `F<V`P F5L@_r@7i='l1θyK :WbqéU!) 'BlxSj ,I`5+Rn 0څ}pܦcKl3~M]QI~Cx| l1J!iA`v&8XbX p&_;X.OOhX&I:zE;&D3iC^fҝrg`EDd& ^9m3t&EuT!?6368PyH%f.GgV|`%hfPn%{Tdm]$ JB#&1۵L7)m7uM^|BWO_$$ͪltHJȀ E!X|-cץGaV.%ryLz OƣC5qEA`H'fi<_SY‰ԲʹxĂh!' ˼AX' ht n,k4^#?lL1II<& 1nj q |"Pp6a : ]} !<[a`e#9Sha* GqlmqP&d^Yaԕd8/ ::WŧYlR`UDR}7OzAwi{PJ:o~UQPD"q"@KϏoNA<2gǁEnu*:`ѩv{7,>z6MP)8֌?ipq[4n hKpmΎ:2}sk >^(Q*O")'PDė=p L=pN8@ms4QԷ}ꁑg(q⛩I{9^ƾSe_}/r}/RI{9^ƾ:'J"U3OK'œREI:}/U?I|/b:U:TPfpS OHLt$RƔ;)rbs e2i![iOiI;G4xPLSL+#f챗c'; VGFd^!;jNqX^e^$|jfNMJ^iB٨]ʗUtZ1*c+g:-!|T l=EyEl /n=TP=@wξ/뼱z@ =p8b|rYu֑2g\y, {ww( ߀0ЁO,#SG=RpwB?uo3r>VReu/#_Q ǟɉy bzjej>QYJ#fB~K#oG$bix(@L=b f1 G=?c#ž{D{ a?N="yV~—a=R_48|7pSU,h~uK=yʽb8K5''@Ԉ:A]ttbQfΘ(m0zlװE:9~#ACKyQ#ƿзzo}c2p?PmWFnbʂ===U5>8WIJ@cؑJp)EK\jٜo[^Vꂩz/|1 gSD޽=J/@u9%7=}^8*;>4U]2t.i-b[ Me.UҪ 鲾/_rٝ\@PFW> sxu:p'Z:@)5zn0VE*o|xAzVVpHۊ\X'+m0|IIacҎC: PbKj\\5| :`^.)ˀ#\Da&?K] CG78OμH=|]zVyuFӊ'~S ĥ a9_X*DgxJp(cWe 94yg빏g 4P*N jͣijhwxIGs^S6wKYFӢ3Ryr#ͪ23p~+7Q-9A؉ݺGwoURRe7IiT9YvG-0o?|+UM[/LSa*} έj7S~߈0p#|(WtB^5?2P? ̻*+];zi:D8;Rw~ eF?|yԗj ?f)#^jTe4jo: dҺ8>'4DxT={M ͈zi_>eTW}yUl*`m%ү,KPf%eՂ Λ,>-YSRhMabILv0<%Ǘ#v]R4v-hkjfEFRaPMSCElZ#s=f%`Jp>9 4 >.sD ۪udpKSJ,Nw\55uL4Cj-#k ^1k›X<:餡<\k2|%`*^XgtəR9hN"li ^O wIrA4\<8/'(B,hOWtt`O_z2݇H,2?a5þktcɈTˣϝ=ʫl-5 0L@j0 $5 m)t\7Dg BSFt oڶ;<]%8A |Y%$T<6^"y}R7 8)FJY^W>HX|eѓ'ܧ!w#=O:zCzp_:̝yp[Q&e4\b޻B_~曓^_3'VMJWp׿@tT M*!P%<_+tq|0AZCbfP5hw޵ck4*q 鄃uo#X^g+Gq"̼$wNcFHx4 PbHĚB+SH@AZXw~gsONn}9 Q){5o/|c=DQ@7Y|M7J[~PJe3uYR'tPr"Xh1^1{T8uY,>Uޱ4"X9K&{wAiR#̡M(jˑAbM{$ecJ/I: U}|G{ejyZKs&- b4'hċp8nnbzm#{m[K#!q= psS`u1F0RDg=[l#F48(jFvJiᮄ{Zcl~]l;ok;ىEWQ&\ayϿ#P<-JmnbETNvm[\3E8 .M# 3>9wrm@~-y4&Mޑ;upGa@:`x;?2ypA=?J- z9G( U91mi[`a9O=|쎲=^k5=;Sf78~-s!؈?nHU8;<:;8<<~'0TN7e 1젆q;FZt?y @s44mHq641;P INk JҤpWN#8}O3:B8\t:~YW&tܭ%ZOJ^ҙ4=$FkL!wnMx-IrݕR Hr >0(g<4HDt6Q>v[5~GwB?_Glx`'ȠQm WEgςaƖUbV p/s< 6MXuNG$ylD@%i|L!r8/ MZϢk8oU䳻E.𔱌ў> 0}e4`o`^[Li|^î_~`84r_*Z(uP?PKSF# 2numpy/__init__.pyZ_o8[m;M&HI=Zd^$R%)'ߡd'!)H7D g3 #ƊֵF0v$Fw*sRQI:{ @F'ӺG-n6'HGT%ǘ_F.jp#_*`PyΔxu_[glM@8E1| &:= oNш ^maq(`A/WQm8|A(/ 8ȧVqJ*^ ϢZ5O ^xNw *aad56p0jt-y5Fp0b!gczVb^QE?0I@Pv:aka,Ԛuw F׼ye_t}X/-!u: U}!*0]2sr!/IAd0^iU2"mӰ#U',6DVdBBLB=Ǖtz^ C^FOI$\<ďWQXC؈Ƅm*"ò8\MA,[=RI 6ɲmLaG/]"U[y D3BdrKn@9A .^ Yb­8X{`JG/xT_nWhgQ-[=(lP5͸b#(ೕ&5.dh(ɵxWx]k]+k;f)K0q'wĐ/2ZjMfCi+KE11bLEA1Q$ǵS.STR25:@mjzaNꖅ !ʉ9gH. SF`3ٳt+F\L\fa{8,*e \KO\iLe%p}ȃ:)!qRu6*M!PX.kKz8p@ zrAJgȗ$ )*8r(>yFrZT9F6 -HQq- a( .)GzlhsQ#JB0 TWJ{qCrZ,C$=nKZ ԃ!P9@2Ҍ^%>A|q-6{+^ė+`: C*v6 .8Q9ąCָJkxa$#EWBcZaB T܆ 0MX955Ԙq!-# #@ONWDa-w-3IPTB2Z`U+ [q: X*YQ !L {O`'K[@D]aw=3va3JӖV$ &y;JE:`2`|ЗC?Xà)|fw)FRָB, O+?Ԣ%q-p&FQĮJ#9OVr(S H"D: Qn4hrׅ+AË-_ P,!]$mGB $NW lP<ӫ)3BA rHG?H25*: OX A[Fȷtc0.5.|*ij*H̔&ɲ=E3$qಌ`#8QJC 庡q2) /T]#U!0$ƝiY1Z;S [K-EY^&Hp[ˡfxg@+d×gEΧ!a7ʟFY`?_L7R#(͹6:^` &@/"itU!Q+AO/qM$A4y_] vf{d4 JX5 Be:vf>~jr 䄂W'D49G(GĀ$dEX;wXJKvt+"WՇ:ZKAkdU8XԪ V5׽5uj?somК+]{A8X\M/1~uħd4|3t4Z,g꬧.7o-ɸf_淋7/wtvE'=}>_-(ǻÖww.gfW ͿMof]zL}+uݱT/Q6_og`m>I%Vo]寧'9VniyÇqmcaow{6~ 9G]mN|q<>x2OO2'~HWA@]a6Hߏ/&?]|8G#{i:Ksttww'WJ+VSAbR\$B IK!ާ!&K2w{ev`N\*۝ϵـ^&S, /$E[Hw13eu M1SC2HO2+xH(7c_On^> }=657شsJ,bxUxrhS/it50ӞfLnr4KzG*~v3;Pt׵e )V+'&en}=P 2ͅy]dxWMk P6 xzP6bjETΒ ޱ Dg-c¶weBlҡrM2Wq$=8&;9C|'ZnePKSFW0%)numpy/distutils/from_template/__init__.pym͍! S""ammd"@=$ T+"({KxR-XZГ.?/t^_o@ řPԜX"uCPb&I}mbyh_hoR~AQů%xLo # ϳʷ[}(/>e~Wp{OPKSFos%numpy/distutils/extension/__init__.py}A 1 E9E3W\ a II3PooAA=~ش"oY&Rc"$/*U5]#e<4pH)6֥w ߴ-GF'PKSFo /#numpy/distutils/command/__init__.pyKn 9̩TyYBVPU`y*?a #Arղt>؉wƂ*A+2-o*‚#8]F^zY8qHWrY)lm]LAt+9ykPKSFܗ+V},numpy/distutils/command/autodist/__init__.pyM1 EwOQwW:4 В_АޏcfT5j,ޭWQJgˀ@ IK /,%PKSFGǮT1numpy/distutils/command/build_scripts/__init__.py[ 0E~$. 5md0/{]_!93&D C*B Z.Q#QI_]\rl!/ ,.71 NmTh; JvƬŒU3/{Z_q`S#O`/<[PKSFZ8JK,numpy/distutils/command/egg_info/__init__.pyŎ1@ J$Z:`/:;G8ܬnVweD(uuX4iCSUsp- Kr>BHjMmBfa9i1FZ֭1ܑ3$w5׭&2w<&sPKSF++6-numpy/distutils/command/build_src/__init__.pyMk0C.ޅCAB!2h-jKꌔÂuқy_ϗmN '|*ԛWs6(5<:I9An`(WSR 86^NjlB?ƩEzK{u4wVb -4ͅ>mVHFV`k%4!N˸-KfKЌv[l8TҎ[c*GNPo&ohShzz]{qq,ԣl@{J{*~X7-$ _4 ɴ  ZWY?)XK#?_a5X.ևYZif'H\<>=|o?-4_sSrE<իuY'PHsPKSF}-numpy/distutils/command/bdist_rpm/__init__.py1 0 EwB[+z@ [F޾vJ"_Q%!Ql4!"jXkƒ!$uhHW @}HZq۹iI Cekpe|>V1 :]erPKSFfE7H0numpy/distutils/command/install_clib/__init__.py]A0 ~o*Ĺo $~JꋵӈDZWD(1U&6&XTT~z4<}%3ɿ5f ޮ\Upp14117%B 2gg_$o_ۅUϻs)x3PKSF_pA)numpy/distutils/command/build/__init__.pyA0 yomxHqA=iQ%㋵jpİ*1W*hwń'.>3)d5d~d o~aGTlAǹDKl?lkp_caOPٗ$ֽ] I ȓeMi89ycPKSF0numpy/distutils/command/install_data/__init__.pyK0 D9wm8#,8$nOZ5X3<] a'DҤNզ[THxަpK?jL^yfzdNm:O/ ; 8rG PKSFF()numpy/distutils/command/scons/__init__.pyUMk16i%!q64%%RZ[V#$mix֋}͛if]X( E++(%4`=1Vj^N*D\b|R:IuUi.T b&IBS8AJ{_ h8hfPЄ:o󟢘=x]E':gs%T芗H%{Quy۹Sw]3ɬ(d_7#j.L>Qk5PU"+/AGīJ?_;? ")#A'Ng4Y-W3z8mN׷C4: - {a~d窍/Tj֝GjŜ#٦I ! ~d秫 0=~zn%"j]4߮d/Xdf;fȬA)w|zQzt8=v.yGbY݅SEmw ǭܾҨ$-ydsgJ@%.6 v= Ck9","'h[Q|{_PKSF7x3numpy/distutils/command/config_compiler/__init__.py1 }:{< x'X$ mv~Se<?_$.KD79O!I2ǪiSAw[?x9A)bgm3rse_6JhǶ2Ɣ\i["~ʥ隻k!?0ıV{4~I3T(sjGؖ4~e&p5("un]_PKSF3wD*numpy/distutils/command/config/__init__.pyN1 {lmw&$. lQs՜9>Ѿ=V. m ƒ6: Xkp,j ipM Os>עegoכO1O/6Ԗ%記4p/yq Pj!O7-E,YU0K 4'VoItj71N=[btsg [cz(^pw08bWs?'PKSFWj-numpy/distutils/command/build_ext/__init__.pyQN0 +,.m8q∐ե&IqMjBq_:v= v)&&DнwQPvFVRq[X6~X: aw`e(7&BVɒU~Nt$27‹\bE3-E$mZlXt$wʠc<_^)ʤjeZ"PKSFw).numpy/distutils/command/build_clib/__init__.pyAK1mKxz&E64ędEyᑎ 2!C t$듨$FjfY\ZUYr:^ QmV}WV;3k瀓<;pd1͏^1`qEh-.4yW3ZXke` NeruO!ǩvyW**`eWʸY?J|" 4:.4p)?&[ׂ~ZȆl,CFToVbղA5Y))39c eSHPKSFF;)numpy/distutils/command/sdist/__init__.py 0 E·RH V:"m"9$E=0X[/J1VB[bPwk=ţ< xoycD /' ɫBN+jて( ҝsBŧ4Û t d2 ϒPKSF}sÐ+,numpy/distutils/command/build_py/__init__.py 0EdJR7@q@}HP.f s ( (t Fv~>t{Qb.㰼Jw%L@{%peoqXT` , O7)k+=QPKSFJ_!numpy/distutils/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF`KHY'numpy/distutils/environment/__init__.py]=n0 wb{pv LD$RO޾Zm##hxPʖ\"* !窲$<ضVmꃜc=hǑFFwi@ΞWʧ+S*laPKSF~,On"numpy/distutils/compat/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZZZR` *,FPKSFF numpy/distutils/core/__init__.pyݖn0E @!hdKYH ELadI*Caёk[/ ΝÇ#o(ҔbX!2H* &xuB]k70M´J(u IBV :"(bD?,4s_dyr*zXNj9l3aESV"5QL= О8"\I߲D`mi֡0%˩첆 ¸6qHo>1OvEێ#6e"=xFㄪS kx6hx'֒X+p X|$ '`QñUAC=;8bFL =Z+Śj oa['MċR)E=M"0b̞*Ô2%xAB`VCٵ3 Q `J[Y)@iSmOxŤ[ZhE7Y k3m  l70l3ѓ[[hŗl8O߯l#6N57Hj- tp3bFzϒ-MERv 5(+Ia؏0eU9¬\a7>.t(2)5[p^@sML7=u߮.PKSF.numpy/distutils/numpy_distribution/__init__.pyO1j1{C_p d^NXZ iE-/xefgf5"%R>$ɲT\>[7s%Cq:g|,^3oibaUWMּ4mkH!a晁LRGZ[kQ=hn#JLZ6m{_,g5:1w)>PKSF+%o0numpy/distutils/log/__init__.pymMO0 9nG.Hؤ J['H⤰{Ф~,}^vl `1hߴYc)*{j<#vI?R TbhL{) 䆸M<5kgL<d#ψ>Z :Nq#v|O(ӁB= KJ>]p+E/D*Y"zmX;Q7r`R[rSҺΑ,_PKSF26*numpy/distutils/intelccompiler/__init__.pyݑ1k0 -!ɐN!CВ:NBQV% ɿ:6؋N 㼨sMW{^<ŏi,n$CJ.{ VߙZڜq ܝ3FK1tQ-aEVE8YfN{[Pxq@9 M[s֎&i9L5/ÑŴiG9C[sxtdeӓd#h:if ~|s?XaۈLvD |v{ӻ0뗝B(L?WGU%E"rOM'/l޶FVV$JTu~.XPKSF<`*numpy/distutils/npy_pkg_config/__init__.py}j0D _(LB muY++GҊ\nmfF)ӥN@YX b}ʮɲ/@9/YA*_Z,s\}L4EBy 4{ckXHW7-pG Hî'ŪiԐmɣq$m؎疾&e_:% ôaY P*膼JP.]۳o- w4P9l:^_vt|PKSFW7V|B%numpy/distutils/misc_util/__init__.pyUn!+h"'H9%9XrN@ Y04ߧ?xU 45cA1s$,G>huwWxu| *?9OS:|{fo@$F'bM$>ܤfb3d\N]yiHLKj9ݡIXNB *PYN _PN!b ՊktdsP(eʍfB6'թęt՞o9V*R ' 0)}T#0ݻN(JГM_5LE)M9dcQ͆q樍Pn!-Y]9:) e"{/Co 7MYN]5 P1*±Z쨼4N٬"u,=sސT4L@3rZw6E~fDНV-ԸGJe ¬dV@^\f,\6ڄD>N(RKzT;!SG`ʡ}1Î7pJ12^_v[,."_4Ƴuˢ 0:%!ϼOqչ?:\58y^&PKSFGa numpy/distutils/info/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\P_\Rjh$PKSFKĐB'numpy/distutils/interactive/__init__.py} 0 E"GV;r@'Bjo}?;$g<,j>+5ʃ$]k nA{554"t}Q4ۣuAR t r%xlI}2yPKSFDI#numpy/distutils/lib2def/__init__.pym_K0)V}p̽A|ȚL 3n(.[jqMB &a_7V4@]HNXGEm;)eq @LEpQnn`Ϣ_[O437X5Xhx; o0ͧ 'e 3,[OJRGC7.23ń2x0{EWѾKZ/QN(ю$MB3.']ٓ},*ڸݟEj؃:PKSF23,numpy/distutils/mingw32ccompiler/__init__.py͓]k0+|S6"I]Pp>CȲhч6;r4B/v9ZLJ۰LZP%L )ȾA6GQ$KQT[ZCpnEN}]>JZ,7d'h9u\%#r5IVL籧%YTc]!,ϯc/7y"z&;Jfm9--4`%sX$֩՞mCCs&3qӊZ[*]Hn L*4-"Ԙ R|PX>7mzɎYJZajω6nQ'COvqNAKiCCT7kKWoʴiV13% iңڽaމk('`r㬉0~gDE-MͿOIf5mӓ3a#9:4 חHr^VUs?zT6SƵN +se vn H1_&k-#q(jF渿Mc\oڃQa.kY_~yPKSF Nm&numpy/distutils/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` /FPKSFQ{r;i(numpy/distutils/line_endings/__init__.pym CwQWv?oA QЭM넽p)& *H4Gd02&riu(7ic %?bW [AA6jMWm*>"Y]{ǙZ8Sl hۈ0e~.E09y#㱄Pu S[ho%FJUX: )^5D 2 :=tI?}oPKSFC,%numpy/distutils/ccompiler/__init__.pyTMo1ۂTV=TʁڊMTUdul}m ?ܠyr.5kÕ D >,L" ;`P(/u{Uq^E&Dn~=̲lg&f BHjLM 6|RN%HhrţZp;Gd$tҰ,kZlҷF7D)vRm]L"p?L>NGӟ!2Ĵ{_Þ8 n;ep:=VU hYye?=yTKxPKSF&(numpy/distutils/exec_command/__init__.py}Qn sJ;@LňZCZm :ϏŔ9!@O>}LZTJ=6G)΅? 8x;$JWWP}uW`R-w'1]7=nxL(R`MX LCr}y¬ͨXu  ^2mdo>cI7K]&kQNJt֏Bn_ `%5XB l>]PKSFb?)numpy/distutils/conv_template/__init__.pyV0 wBL0Q1Ա }{Btm\8hb[vS&$jdPlagy p>5 G8ꗞI Rl.5WfNNh=a\kёIVhIhf+:šܼCɣ['Աtc5nǒt׸\͡~Gwx>\D##O0l֕_֠c;a=` ܒ!jn#B>nۗ}Q{д)q5dCةV9:I|Hwm5_n*SEPKSF1w%numpy/distutils/fcompiler/__init__.pyTMo0WR`\*zh)"kxR{n}ٯ؛#(y̛P 6V2imAB@&);U~+`$կQƎ3Tu;)vRdRo ;yI$%o42U[ycYyzZjpW`rEf,X-5VJVrjO-똥ETQZ P\k:\i>r9eHϪ/.j=:G߻3`\+&.cAH@X}}l! jΠ]T+m1^̘qKneu#W(\T>xց1b|hqfP5}B d(O# φӺ 7IzfZ!{heht!mm$>7)-N7qG|HҴ&|&lq?Kvs}1;~S,mOs>I`W vȭ&"x)t۫.n_t)ohqNmscͣ`*ip T1}n6'b%OWsc'/f;J 7trFۍ FeXk4m7*SgFR 0:V[L;G exӋKד6PKSF*V )numpy/distutils/fcompiler/nag/__init__.pySKO0 W!xh bemS%.lgkpGñc7&!JB c sb4WM$sUf{-S&+tmBV9v*qsN >s7 *ISl0w{Sn"-"c+lEsݾ:" SxɎ8%pJ;n2 x"3qIt2^K4_lT0W=۲ 3tbl&s[nI^.-<³?9z p._=SVTusFFZ|QH"S0ChV㧗=oxOPKSFp[+numpy/distutils/fcompiler/lahey/__init__.pySKO@W̅&ɃGK`4fNbmv RCz^^;ә&d DRRiQYa,AauN抴ɃReF upD[ 0['9jm'@ǰ0t!8GUdb8Fn*-"+bCs۽{ PWu IMd_y8'waɛbL\rUZ[aOuai>v\Љ$5\U$IaV>-Dt:u?+xh!Ȇ: /jq5;`9@'w. PKSFFwtF)numpy/distutils/fcompiler/g95/__init__.pyݓMO@@h1#1 bflvݩBwГ'c/>;3iUJ( (4WHeH3Retn 5p2ڐΚ:nf ꔒ{Z#$G_CO{q 6KD$QқG[)i=ǻci@k qqH.:dTTBчNA/Oi }كgQeIVt 47tgyE; l7;/9͎Ios6s(VB $MK64ON0T{=\V~ZįV|bOtq/9bVvS /^PwV+_g fݛWh|l5tY܄YbArw ~ؔfOْ˗oɀsAܘJ3y<(zPKSF\+numpy/distutils/fcompiler/intel/__init__.pyMO0"-C%m7E R,י/ql8IEZR\;dS$4qD; wK*tW脇+EƒҺFK)n4,)ULcE%s.[L}gZ2`!hXp9u?}<1F p,.j7I^!Hh&fEzp55P,cwyc. /PS0cHJ<9|ldLHUfHQ0"5jAH 6 GA,{}0Z2X I?; Q,+D_5V:56tIݫҮ!P(Dʡk> +3X.+%r/hV& mIKCօaپ6bˉ܊^5i/Yb578!0`Ia6zzs*(.L>mN۹'RybP)">{[}hZƩmOo?:'PKSF%*numpy/distutils/fcompiler/vast/__init__.pyT_O0ϧA[N4-U\ĎN !R4"E|If DRPYnCNxFښ(TUAe\H6v'RlbkXy'-BUx9INoOq|xw! E'$zFyf$vT.WAU38 c9:E:[cœ4v JVGjm [&+B 7ϹK[p "Z=s샕Gb:E9=-f~޶6ο>\3I$ѡ$j[?n>,.Bs& O!+[D:42Cxr/m04LKS>͈l.ȴþ폣uo?PKSF&2#)numpy/distutils/fcompiler/ibm/__init__.pyN0s @DWE.TE,vKlGR8MiRV"7wc'5 )j_[AHU롲R{T5h\ʰ׍\" 3~8".A]kOSm5]ӕ$0/;bVv0h:3+iЉpJ!`&CIrRe\_ 0aBNEW|~].]PKSFqb\yF(numpy/distutils/fcompiler/pg/__init__.pySO0Űa 18Ӕ6m0Г'c/}&Zf$f#)-R K%*}#wxnQ)2my穔D FEi7 --Mw^Ѱ7NoD|^4۰?IQe.EgaL(29"qIi$:M֖ m[Ǟ=ڽ(;0 -%{ Q12W+v13TseZ0)1* A5hSЯs]J`Xta"Ts?tzuR>hYexz= M/PKSF[K,numpy/distutils/fcompiler/compaq/__init__.pyT]O0}ϯ jD^MHNEE]A ,qÉ3u> )hж>ܛ{nJ 2#(%2N /U7s?T*a,9,nPqEnqfYKؒ\xH#8 'h`yG [+A˧2l.o!Urm4`I+j$k'95PؤOeC5nؠF2f[nW;mXU p2> ^L.QzC]2TD"-b}ib':tն}>GϪJ!6Ju:̣7LL6H//L NXe0B9¦O , 0|zxlGPKSFeeH)numpy/distutils/fcompiler/sun/__init__.pyՒ1O0 /U6:%E"dE5$vtDMK}9h*yG6XJ;Rth\/iGV%e:E%[ dJ8sZ6aFwc5/yL)c؁NlJ,$KV Ty&tݳHm~C{ :a@ރĶrlX=QZ>?)6;-vmZ^x5g0H5:ᔼg!cIwɸ$zV]{Rjd3мQhv{ú#z>#_PKSFJ_numpy/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF$6numpy/compat/__init__.py}j1eD >BOKb$$}&[+Ufr э2fBT>EY*e+>29=]V$uȯB4!MkC2dJ9/}4Mh=0e? d*B6m͌m<]xbFL>ŖH(}[J퇖%#7K\$O+; `S:ͩJU#y>PKSFJ_numpy/compat/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF*ܴs!numpy/compat/_inspect/__init__.pymб0訣Ł1DFKCŪj[L|{ wM0n$1.@j$$Ѻ jv)cN{(H\VJmln5!nU&3zT%ڱroPvV+Ii9^A%/;I0odMt&VC .YPKSF Nm#numpy/compat/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` /FPKSF韞gnumpy/compat/py3k/__init__.py}10 E[ۑ#0q+MI=I)7@ 1$Lsj 1/vbBn3MQ8P,7ܱu=!^5?VISFթR's+z%6}PKSF4Snumpy/ma/__init__.py;o$7 ۭ \"]vD꬗pfgp)Q%( k C*ۘ/HPL=rax /(l6CH \w;_]<80vmL$]tpf#iwl-@RD **ُN9&Kk_i<* SiBnɁ1>H>Sؼ{ 77) $2zGT,\ģѧ.R݃AL!o8=S](5u[ 02 OL6aOt4o=aNBw(?z!xi::hSnGiᝫD53ϬL+Bhx|f0lQE}$6ĥOH֙uA+ڻ:|1\l,\њZ]Dć`y*߀^? :٫ɋʕ :4{ц2&r7G H$t' "~ ̓AOf (9mv5m ,c|ƿnD9^߲ V/tuwp瓌+[$-20|35ӜUQ:J*6otɩfFbJ×X_L)y6"޼1?3!ۭX.S뷤_fMUXSgQ2_PKSFk_numpy/ma/setup/__init__.pyMQ 0 C{?kRIYn(d'2CZ-.,judf q[HivM^'qPاF?k.vZn9N=S;lNñcwDOUpĬD{ZM {}ڡ4!cdO_'49;vXoi@{qޔ" 'f{APavtsc) ^HFI+,ba,j\]Xy*Fc0l.k#ji r;&1[tzg{nNշ!Ӻn: A4g8M-#}À;Fk% Ѩ\`Zki{A+8E3HRʙ=]bMQ3 ]=;Ut1晏;jy,]ɛP#Qmp'ُP#|SL@HV:ɬcf$7 oF؄)-~IG4 )CV{kdT],]s&߷-woLō GI#(hLɆD?~Hԟ]T>Rq\h(3&OU;z9'‹rP?q*Pe`OiMO?7#PQXWν|XcH28TOa8r92{Q`=u &6&"@*Q)GFү(鈺=X.0gx^KF,oP'N Ϣ;V7ϛa@J?j{?xyFQKmQl)X :O߻[{Lpne'~PKSFtܼhnumpy/ma/mrecords/__init__.pyRn  8R!CeZU f΋s/[.DƖPm)򆴋 u2jX=@Ӂ1 |#(Drm &C~k\$.#űo0,KOIHZYčIICѓBu93% YсiqN:c+|ĴFY)S{'C耮#]KSX06=J c9HAh SL1zDA  LtUA74[.G,' H= *@Nc1& 7"O@_Mo0.ךJ8 khM<]w0KXF<*OEs󲟴:hЏPKSFADnumpy/ma/testutils/__init__.pyUMo0W[ A{@PCOM&YS{&Yg-yoޛ3Q @Cte uBBuѬQʴc< c- .B;8y$)|߮0cRh67L Q ST<.tRez./P!/1G,"5cG% PMԷƥ2k9ΐbT>Wd\ev,tv=_rFY'eDWIŏPoka]\Z>XŝTjq&̰Kf(d(?L@Pf~3 _HBJȀ!l ..^;xnqKhO!q~0ôYVe,9ʊ_13s\ϊqQGpu { r|ؼ7TVRAtlѦ6\}`Mcfc#qKi |=;Kh\`d"n!hnc8}I慄ѭKezV*Qwi̥ZwU!cPKSFk_numpy/ma/setupscons/__init__.pyMQ 0 C{?gPKSF8Znumpy/random/__init__.py}n0 ~ ߒ`CŒ # aơeaOG'K`NIџѻZQڸcC4R=g9&GPnpJ-T\8#ѻu/>}5)?\ɯUrKǸ\̾ NRU2ؐw`iΤ%hi:y-xBʣ3a91F0s7 J8Sw@ѹ; , rd5{6J|tr^ bgjڊP'O Yz+6@qw^{hv]agh MMBӌ#ɢbѧU (}J]iQ]9 UN;[~'~Sw$eEXwRȴp^<9⾂=8jۘҲ͡X1]}]תKe~Yowwf~m;{ɗJHsy[ `rM (%:XTs/Ap`+R-JaHfz%y}/wq uAb/UZ/GH&xS-?K xұZqEY-:[89?TD'v߿vwwvpoAPKSFF/FYnumpy/random/info/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZR` rPKSF@sg#numpy/random/setupscons/__init__.pyUA0 yE>oI"SbGI`o3Q%{Xj𔋨^F#a* ~ \ GJU?F*ӝJv?,l2؉Q!PKSFvg$numpy/core/__init__.pyY[o~[v v}psHq6=(ZlJJRN_o3b3 Gp.tftqXVNdQjNJ#T%NjjB'o1aO~- O*Y8ۉɥu?t :Z6DײzpД,HE%X „CYPam l[6Vt;#  T.e!]w"X5Re:suv\k7_]Nq^h騋Zs͟n]SJj8ψSz`؄-:2X5-y)^h㠩Nn{̯9@/6g`Ctf*,*eT;%+44Ed.sB&`aAN5K?0-VjDY5BB B[CB?a}) 96O `NjLQ64! h6l U3B6tЊ^ ߵ,s䦹ogK.a=v ֭:>\와O] Hb c98Yjr\EɡUxKFX;8N "Z|ErmBQi#@صmIOa2ə @$;jIaON#oDž?8b@FTVҦr%Sd5Td(:X.Gz >JB] \9T n-I0fRp7GVnq]k|jFHH ̐;Lf2B).]\{i(]zՖ5 CIHnP=GB#l,0"&8 FทJo1RҲ&b0hA蓎bM tPTi)FCjR4OI"s.e0SC⃶9'OczA9J  m"=G&Ev ,E?88; @ B{ Y A:VDaVOseX;HPs%JX'RS^+ /g$ fTO!tPtEYwR*l7fY9Bܢdz5@ كZ d$l*-8$B|솘LGc!ы4p:nv<y:&n}tw/Oh}8giSP|#}򯸧kw4t^b<?6ƛ]p~6p,lի,aF-p6BVbv>o&DÝ_x7rzzocЗ[*siY| ξ%Dlb\: &IlRӞ/W7/WW7_o.^1h߸Q>՚>wrRzrhbܙﬢܹuErG?<x6$<.NCǸ-)0)*k8/ҽA՗#_. vo^}FXcB%)e+\cga:\Nvh5;c>˴IBn3^bZ~x]ljnDJۮ=ٳ;}kuX9rcZP-d 7A!q4 yr .>\2.>Bdqx#fzh G:͒9Oi14IF)Pj>~={nyLEwgݓ@n1<~.n> .Vhi+VDF9]W8<*A3⵨;j?v[}7ϛOoPKSF~Hm- numpy/core/numeric/__init__.pyXmO_7f+.JL +M֗Nq=q:s-+ؑjmQmrIժtW`@HZB502;X>ZoO2mɁ񿎼TJ~jJ'1|]ouNMݶ6ס 1_SqoxIrK+_m a{L+'Wn %$'YJP U:F ֽ{ز zp]RD˸%D֚IVJT2]FP5SwBq*TrCzkJQi#`;r2mIafF;A 0:\Mu@uNB䖅YE0+|ΰ\nd@JQT+ 'HfV1%r5EH.cٺkpX叐&!ZH"Ҫ!qhQj]-BSrnlBnb҅צhR+X;om GɈ:T/QrCrrv .\.3R)?rOb0Xb]Tհ,H15˜eN¬cv- Q\o1x'"5R" Go[ѦIS8(iݲµo.R:'e`_\(@D>cEZnqz1%JX'rK^+^(N0=Te^l`0 rZkx9&!߬+HU p(fB%一BޓU b8A+% _I(O0]yM!Rq<%}P V\{jHָ{S:@/.R?- y/vlb+V#gK~vwkKX\5Y_vC q o|yKyFf7Q[YB;$ŵо◄:/} #!L=x0^=mCʍG%ۗ_A?$aU$w9I2Y,5鬓n&㧻wz|:luvt'ә_މ<^̺Sݏl~ |~xq ~L~ξ7.p}OxivCLA {>Tv oo߼`xטMgOu):=xnwUzmzH-pmpp%Infl ~bcl6r|'b<<#.=yt^ ?X=v.s`8)Z'U3^B0>w9󿓣dŚ_Tc:K!EIm%о.23eMT ƽ!FYYgɠOEJV| (x^|@ q;u|{Ёh?H?ǰ\q:pVo>A:nz#]^q^5qڝpqs7qSbZ8uˎ!x}u4|"fe\dq/wtv sq]tWJ &z'Fjx6Cݩ/( ⢇nS̽f0kRJn;>'bXkuet\PKSFs"!numpy/core/shape_base/__init__.pym 0 {Mz#"!k:tnoo &[Nǟ]@;?=#JF\ }S>kt PW07&mrkٙ~jA)8Z#ҼU-FcOϻzgϯ'4nB>PKSF6[numpy/core/setup/__init__.pyUmo8_a!h=BU!.oUL٦$iBZIO3<3ϋV2"wfR£X*CbŅA ZgH'bYܐRzQ(N+P7Q@!>?SK˲77?F7H#a/.ˠ8s+ǎ SE'j* I5U4?%/UJ_XnQUY7[)tKn ަkU$yuRJ5ZPD(%3%ؔh4kxާݐ ^϶;2+"=r'ȥ w6|8r#!9N>]/cż̺/>^RApi218F3bk"$j7"K0{A!LHPk\<E/! C !~ckd72T*f{ 8vQ׎+HeMQ<0 B>"Sڦ_.Rdu _.0f[܁9~#WOz:$k)…,?_^CIl5;x;v+ڝnvg!ɯ-}>4ίusugb;V7ܦLscu˚=z_qV: z?> Cu}iM, "|Ep|r xRRsu >JPKSFTk#numpy/core/defchararray/__init__.py}0~ 6;CϝGt:"cG)T7}b7Q $`,iY :ׇ9"}.!%؍ל˜*^6_(]9OAx[e݄k!,ɱh~K-14n5-0c- 9P4`1$q6%#NcK9{2#C1DSTo50~Z ,Қ\i QT<- - T%gvN!s}n&&KZ)?9GɴOl*&iotaL cK[._3ُ)M}(D4ʢ4jP\ {`S"i~\ D&mG4ȼ(auImWA>l^ߺJfٳ? ?Dnϸ am=8it:nzݻg/PKSFpg{$numpy/core/function_base/__init__.pye 0 л)l:A)ƒQdhCNgs Q[WFT:x-V>G45)Eu͖?qQ0ڦ.+VCL?&?PKSFfnumpy/core/_methods/__init__.pyuQ =oma=N0FkQI~ڲQ OQLB@{LX' } jڦ0wBCm`Z{(3{Cdˆ/<ܚwJAÏ:S numpy/core/umath/__init__.pymr0 } nte @{HKfLvڋ'$xة+(gٖeIq&E"$t%)!-VBV)@y7ɀ<1?G~Ooi"9M+Y")DKbF:8[3%1Oa! e9҂uq$Qp̔%)82N-$)ERRb ݕt,] D:8@.wΊx5Ȭ8\3YM6j*X(C "K/*1Q 08:@N3MԖeSl}e.6umPZ4 ڦ,sNp0΂rUF8@HUYS(*E18n)d!stU&"IZČւlr6vk0Flq'q1(|Zk'vղWJ0.Z/ȣ;jMl I̡ӫ#l3?ZZF0N-_( MgswO$XEvm%8'@ ,'8 '峨Kϼ"oǒaf%W*} 0V>h5CĶl\8NyS> t+|$9jL pdGsPrY2L;}n -6Q(=i"ke2N AJA ;m[wvu@$FPȒ2^:cKgώnFGXŏl4s ޏ@PKSF7ix"numpy/core/fromnumeric/__init__.pyu_j0 s z` #1eOSZ:"}D?lKSU!g$JKHnbA׹2[5[|yb.S(ZMku`/:v_咱9ɨK]jTUڹ&kh!Y"l<5pE"m]LV4(U,2PtgE~L;)dK<~k78 OPr 8"R]?;^&@1#X 26(\-[f ޢ9?֪$}#R~*b#9A3. 0P+/PKSF1o!numpy/core/arrayprint/__init__.pySMo@WT$*R*cg~;[ϬoJ}y[] E(vS4ĨiHZStJI (Q!3;\6%eCaLI t0˘'ą23#U7k B15OU!ZK!VnH}R?/Z6(ȃTgN1X)KZW-( GSBYwI k.,k^i0`ƀQg4琱$w5ml2/0xtyc8Lxg+2yX.E^}պ?_4/a#jb3i/Ae]bZc3g Ҏz0' I7:ow\lgUQBjp yPKSF a!numpy/core/scalarmath/__init__.py}A BG}O MC R^x1ƽdpDߴC Bjle%#ڋ]`94pNN1rji'yPKSFgDd6Hnumpy/core/_dummy/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF#e#numpy/core/setup_common/__init__.pySo0_qBh%GU[!A@Vd7bgYAU9 w._(xKcQ̅XPtrV 7SK)9%vA=;-zt\Ǐ$1z#ڇQǽ<ֳݶ=Eq]< *Hczxn ^ݿkuQA=Pt{g`on;FMl<̗\0'w$B.8)_N  " Sx̏9%a>9#*K1*Loox *r"ׅj F٬s/h8MFӲ,llAJn߽I_?tܱܶ-)c G/l9gj}E*+[[vzBnP| ~kݑn~k [_CfZ*,y-[U>uAu7M &mG^m/Q7-t+=dtuCj]7|.htV[cІpE:V.fm쾳р+[c`luHqzOG-M4?"lcWkvݼoyoiAFdAFdc &0Hb 7zw._y>h8ɧ7? IȾ8΋hΝ<={|w:I$dL1I$dL1I$dL1I$dL1|' |' |' |' ^ x/^ x/|g|g|g|g^Kx /%^Kx /%W ^+xW ^+x^kx 5^kx 57xo 7xo4<}nyW_w߻?9|㳟~uß7 E+"_:BZx%{kU7.JNp7ļ)$ld/ޔ;od:\`ӹЮsm7 <^.ܮuvwtJ?5 IeUHےݿPKSF2QYnumpy/dual/__init__.pyuKn S)se=-TJ֨`$CG;a)702_qJ:ڰ_27ݾ,?VSzi\BE# oCf:-{hzLo*ohڰ+>+jOm%b(-94'ޢϟc=;'mp6PKSFNUnumpy/f2py/__init__.pyn E|8RUUٵR>jD0NQC<;81K9s`ET*k\I0H}\vS$2ڍT++ɇr-f15R!U)9 OXԊ[BB$IU2&reT .jh Z522uS}#ZLPKSFb-numpy/f2py/cfuncs/__init__.pymAjC!L]9BOP`tL%ȨwjBFf[KeX\HeIbi4( {SVZm#8XCZ?=I/}w6yB0&yC .y:ҷ@EuJAiABy@LX]Ծe-:u(˚Рepň tkF۱yIPKSFQ?9 numpy/f2py/cb_rules/__init__.py}M0eJ!RcV赔"dIH#'ZgfI#u!] BR;yi"EiMMVڲـ!"|p}87J$> Cd/Kayw :Fb >&8J { RM5@0k"&05іӒpѦQ'Wuyd! _{-Ba)s!Z/L2hPHJ5vF 0ii`xj tRQ*(plݨE,碫!r*5|Z 4H:Q6l@QxCUtidP1:++nl] P?\v e4fRHM)*j;*"#ܟv!R_YpVyx?%WT;X<|;$[Qm0uUםMc| Bjt:FvSR%S}v˃o5 2w8"||K"/)yfrxxj-0kk]O u,"ѕn~OdЏc'x1*_xo9f6-bD&PKSFI Mnumpy/f2py/setup/__init__.pyUj0{ȁJBS!>A(q jKB?IY-8fvvwvB!Yym"SGm Kj>Y-RB4Sc(9!v FfEdޚAߒܒ+ vz(6UP10Dww;-2SywǺ' 5U[H5&̢XrQ`clje b8``9^Oo 1;!Ob%-[iOEZLWvPKSF),numpy/f2py/f2py2e/__init__.pyMN0>Ev)h7E  V %xlb7ߌ` )hOsІLjP ̔Q]F/=ED_`׆Ӱ7GzTY:v' YTb3`qcNpƢ)ԍ(PpQV!yy:U<ot q.u-ؑs^gU]-kD{F1e@  ZҲ>Ē4ZAv%>Q+lH%;Xl?w>Vka?!PKSF`VG #numpy/f2py/common_rules/__init__.py}M0eJ!R豽z-%bU}$ߑZUh3=B7Bť*s9+9*X4`^B[ո  f@-Ӎ*lS╄ or 6=֓)bEʲ%q{*Cz9J ob1/pPr0>著/^IQl(JPw:"TeF /[KMӥhފ\sz(ԱGW^9RQ?M~Ũ?8{럦_!hfl{kmPKSF- numpy/f2py/func2subr/__init__.py}M0% e!Rc{+ZJ$bU}$ȉKA5,Jkn-{4, B;_#|n| }i:Fld{ifMf#r0S7^( yYrqJ=N.Dsb`*";Ecvɳ e,ыHei4HJcT)mΎ.Sc7RI#N*E ݨE,碫!r*5|xrth@Vϗ"@(*T42J76S ?TјI#",-WTDV99lBrmZ'GoS*|T|^u Ӂ,CY|H/[tEu b(u{U:|P0H#͊ 7B 7`u5{, OXRLJ'hO'a3Vd|ֲ~.tBZ~ܩZRsR S|Eɔ|V;CË;k+=CGH<Ю}dn?9˃Dܒoܻ6&/"lXT~`"Ԙ>+^,R RÝ\i8B->vz !~B*]{x:ep-#T%?~d[Ӷ@3"!PKSF)TL[numpy/f2py/diagnose/__init__.py]A 0 }E&)izm٤B U'NPKSF!5 #numpy/f2py/f90mod_rules/__init__.pyWK4NP+ڴ,Hs{ 8 @;cf_O9'Z+r7JyC*ʸB&sLC?I =Gx9:X \9ʣB_ ?wz8:tҞO\1XoͶHsW5wHG p'R)0SB(c"j!di*6%2@X!*j#Ij.f8v!%6P阋C,66@0(gx밣}1XJ,Rq&iCƤFEP[j:ER3,[l-B5MVKmUuH5sL2Omq)^*.4@2 6 I0 !$1Tu%ӍK`%4oY0c̽jD$DU q1;w#F{؞D0uLAm2L4C9$%{W{<߲xGq7 A* ʲH09lҧ^y5%X Wr@\.gίZG3=gJ NSeh*f?J4g<4U;7ʜ35Mm;uW]w6[lwbe ֶHomULGO!b0Ȥ >aRJ/;عm=[{-Ba؟Zq T g DpE {sN;kK6'-8鼍o>Daϡpi$IEg{rIMZvq"DXf#\y!@~02fζU xsS_nF&7%?B-A|" \A:=o!<[x'A wfwIvYt6UqtI)7:YvD{dH×M¾W":ŀ3A_C ??ȿh2xKԙI r3%Qvwـa7xK1Ж1eDdkY3C̏ ^U_ F vpTq`~8U^`3/~%EP㹩rtD\ߌ8Qwfn>#;&a`1 m$.->!$[ 4:g"byW{"sz/&y "\՞Oxh C E c;jz$P[I7Ů/ʷ©?IPQp=ԲXB~We.LQc-acF@%`/2&n~<&_H<'Gk/|kk:v\"ɲcCNcmt]BDubexu*hKe ŗ1}}|D =,j7wZ|<,zpu|$X|&+fy5^0SLxi-x`yZ9b1%]PӮ0?>K$>65iGp>TTv쑍%G؋_N+R۵%H/JaA`|+[cIQZC9nlnl6کޔYa#UiRQ@ńk45K;]踵d)x%k)J׈Brx(7kyxI]W rjoaH@Oquʝg{2sS5W[_p׃x:v]92yow_! )PKSFI M!numpy/f2py/setupscons/__init__.pyUj0{ȁJBS!>A(q jKB?IY-8fvvwvB!Yym"SGm Kj>Y-RB4Sc(9!v FfEdޚAߒܒ+ vz(6UP10Dww;-2SywǺك!~sMP p)30gD*M`Vkk0E[k<*\ti`.\,%Sa#k ^ј|d0QrAD*KwNcT)m & =DpFCu!TJѩ|Υ&-h9}x"pJY^#i!@ <ԉJ,*_V5PE Ux*k9+M*Xi!]U2@јJNu+6ROWao(DV)}Ʌʂ۴''oS*4JTv+%YG$:b3!8`?~S?_p1ᔲQl(JuuH 䆅 :l`8 )pgp 6g_Wյrx}(k` ?j, :! LTyQy/I/xEsS s}Fݔll#L^u݅mGR{H#WE*5ّXFŭ='szW"XT%E$9g&7ϚċUk^p.S9N|va?9 B X.e=Œ`Jh~OM:^MPKSFqGxq> #numpy/f2py/crackfortran/__init__.pyYM6  "MQ4ɩȵƖgؖ+ɻb~|eI${EQ$E)mQԃ,[ڸިJtwS{Vf/|Ń4"z&(nh?.6/oIWesI|ݔ4]3񱊀a4)ESeW*";` YZ|M=hdwtP+LFʢ~NXQUNQ')*irjPO-uAz4],aP1K7CC5Av-7,h-p "QHDă04} WF%:ьt;;jdRQd`XSTlr2=}ߌfhd *Zpɣ߾]c޿A5j\6 6Qbl8|7>(&n#T |?f1> -X.̹1.`qc/m/U"J8UjZPDEG%1_P$2YJC?5@A/F[ =YԙÍAG%)bF .It l,S"VDQèn34´AYTFN8 b0X14ؔH%Y#n2=I/=tajܡhi=`xN2m Բ,@-'?!n:iFFe·Uj s=i$kM=\J\@#.+\ :е cwڥC8!`J9O&GkPIĿ;c|sƎV,GO영uAVt=9.Nzv$? 23f.4WQ$.uTCێNjL ow;c vǬz(tQNVwoxrxbGEy+L~sN&B{!NQ ^F2$Dk4.FdTLc%||4;l{ NxؼhLbިs)B.~I/ƳKH2-tRC kF%z/y1sSb+vz]{hM~trJ FABI\'scakR4cD͌Wѣ~ U+}~F\',R?PKSF)*Bnumpy/polynomial/__init__.pyMK0EMd aV"PpN$dkIkcFh\,^n匢Umh0FjS]a4J+ :7=e1VtlwFv(aw7I}7{ҀS"*bkQ g UlI^ܦ+qkՔ&Af"waJ)fx5m<(+sDk919.^$;-tTrCY1R(c^KXяs,E._>y &PKSF|g/%numpy/polynomial/laguerre/__init__.pymN0 {"mBbH"Ӧ"46AھڮtH1C%Yc4H)0de%S`^A)ӯh~[ܸ5ᔟ^w?vP!n%l~!n-ݴ\EgxZ?c }/#!ٽMRpBP&p(OG(Sc D>E!| V/ j"l?w!94쀥p7+7%N&9MosdjW'HøڌR>gM7Gud狇3oxAoPKSFJ_"numpy/polynomial/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSFq 5Mt'numpy/polynomial/polynomial/__init__.pymj0 л·@) K1n6Dmx+'bYe9S@+raTJ\"u}tbZ,?>0Z(}C_o 8mÍ,b:(o%7`;x4WY_s1R;׮;,j`$Fl@L^ LjIlt ysMͦc~)Xֶh !¢]n6m(Ϋi|Yn]٭k'!zX}) = PKSFjS1$numpy/polynomial/hermite/__init__.pymN0 {"uBbHv 6,46A}J9娕hI.>wb\?+€ #vעLi5Ntm6]j<3sMNQShk[]wKț]5sVYtbScIAI` m&wM) m%ݭg!e  ÓPKSF0 &numpy/polynomial/polyutils/__init__.py} @ Eق_ t#č ah%0*{BGeNMnM)>h < 2POqe!֋"g(ej-D ]sP,YjS, ˒5:T(LQ'Lrd tdoKPd6I8n*ٴ7 6;0J픈+/0J9,^'清iơ?Z\qWw~PKSF{8`)numpy/polynomial/polytemplate/__init__.pyU L:#8Cc "PRˁDsL]|}֦M<%Wx2*6氊3iVM=mf@;PKSFMz3&numpy/polynomial/hermite_e/__init__.pymJ0{"V QM#M]Ih~L!z+rQ+% ]"u]BİfY}$€iX[Fk6H;_ :tnDŽ x&SFB@N uλ!PKSF:xnumpy/ctypeslib/__init__.py}R1n0 mNPCK&Bԭ, <$#;Ļ#y$ݣ@? 1K:FV^\:9Xr57EɊAHs05ΰ7rf@5LlX3K vP"M@dbNf{=kGB+t!/TęV۾1 8N3_"4BD:,͜bnnvl:r h#>?ߖѼۋiQ.4PKSF 7numpy/matrixlib/__init__.pyeM 0sٵ;  흶Z]}gRpHd кcLֳPf\P@' 7m\>#+_\|K5ڡ]h3wjMA{uqOdw@}xS=Q.PKSF Nm!numpy/matrixlib/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` /FPKSF9pM%numpy/matrixlib/defmatrix/__init__.pyRP{?RmD=tR􊈲O-9 vڳ7&s|Ҳg(E7JЯO(zeLs[gE'=<=n؎YymQ6}L4ҝwݩF"?сzK8#L .8(C)KNNٙr)i{ĘgSJsrv9Y=qt<7W{=^q'p5&~3ݗr4l K+JgfFd0?Ob@Y&+dNr Iɫ'!#cd12FƊh"[>ѥW^4[S7gfsݼ~{3wf ~~v vsuZkDQ)O?PKSF Nm&numpy/matrixlib/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` /FPKSFnumpy/linalg/__init__.py}N0w? u`` !ˤNb|瞝@'6Q'O:wLN*MqbGbLh EoA Ŏ9 6Ts ,jO }!+8 ^=AV+=`ѭ$KB|lE\$&^|11U*oiLPKSFxOnnumpy/linalg/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` *,FPKSFxY $numpy/linalg/lapack_lite/__init__.pye=0 F#\Rn(?qpR}zR8~ h%!H4RieĨ™ZN~B}#]9;AV d'3Y)Ұ҅$e0K?nƏ7~rw[7(eg3瀗V)D%S݆$AO0i7'MBBPK\%PGOb̍4\?*_HKr%d`xFL"U3r_F~@\62yfCjoVĠxd=s *_O&֬YXz+~c-tAjV1(d3DrgvՉwKCX_>66Z}ɞkN xg$zrn$rhX7j~aZU.[D&k]v'kd=Go+*9rk,m z]V\o7vVa(\yx5-C,fIPT?PKSFF/FYnumpy/linalg/info/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZR` rPKSFJ_#numpy/linalg/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF"')numpy/version/__init__.pym10 Ew"D2=FLXTlx V6!D%K1h:%<.xGIVETMB{r|۸9[K6XQSJ:E'U&8PKSF4FMnumpy/doc/__init__.py}[r ]o3 K : Z8`Sw߃ _>/hF74uZ آS=- >xPWIFQyabqӹu^ΐ|VV\d$9c<"%ia8:S`I1!{ j0Y cSv@$q"@UF12D yL;-3vuF8VvM)d=uHz ۃwqqոkw/?D~1e?ƐcL0^ڠU:21$4EGZHD9϶WI/($`.?Ŏ 墀ꏰPKSFgDd6Hnumpy/doc/internals/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/glossary/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/io/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFsJKhnumpy/doc/constants/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ P` jhrqV% PKSFgDd6Hnumpy/doc/basics/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/creation/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/indexing/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H'numpy/doc/structured_arrays/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/jargon/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H*numpy/doc/methods_vs_functions/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H"numpy/doc/broadcasting/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H"numpy/doc/byteswapping/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/misc/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H!numpy/doc/performance/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6H!numpy/doc/subclassing/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/ufuncs/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSFgDd6Hnumpy/doc/howtofind/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\PKSF(\fnumpy/fft/__init__.py EwMM&~BnMCR 8DM{gx™2&0;uR=0x5Bv@ڣcm+=Obn}uBLA$д6\YNEk*6cœN2F3B^\rY.?,vY2%i w99(Px M1)dAȨ9wu͕PjbPKSFcNRnumpy/fft/helper/__init__.pymM @ sT(zR0dL\xFKAK{/9~Zd((MNBNﮘ5؛$A?ڶIK,k2S-qp9TIytdL#mY[n+2zD.'BI)9AYS~3 ](V PKSFJ_numpy/fft/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSFad"numpy/fft/fftpack_lite/__init__.py] 0 {QWE۔oߨYN;2SUaThIK'5n_'_=Q_A+@TxPKSFKnZnumpy/fft/fftpack/__init__.pymM "t{9, qvN?)&a, Kan 17Lf wJY3=玗ph2){c3V8/FW@Si,+فz0ފUR~ &$Y=Yvk=Ty=mhg6#4`F! "P?PKSFF/FYnumpy/fft/info/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ZR` rPKSFJ_ numpy/fft/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF!݌WI\numpy/add_newdocs/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ Z` KpPKSFf+ u 4numpy/oldnumeric/__init__.pyZo8_ѷEG{>dNNZcvAD[[Hr_7!%0G("FWGk`HV66R9@UVt o@F<ϙϹo2n:jJio2ˈ÷U&]02;FD-bl2mq. /ЎŠqZR.z.VA[GGͤ=ExKxJLYx8nJ'[m!8h2\c1- a~sS^`>V<Ê^Q4]Yo <y"!t\{59L@A!sqH'"!v&B6 +tIȬV~0k`ZԪJ28kr[KVBK`x dLYȒr 2 !2nEne}Z;Qmi]T &sڄLe6u)]vlxT"ܐMA,[?RI?6MldmS\)uli=(83Xra 5R 9nV(ݳ{U+&Sf DysGallz,]r뢰3N'C8 1Fh!QdkMbVѐ+^[xUi69w%\#,TƝPEoJ7Ph -aVr(4Fɴ((&`dG8 ~ C&@'3,>e˪!!FP6!NV2Y p9W. F2ٳtkFJ\Td8k[ ,J _, L?r1fya~rɃ)v-qRCUJ\&АhY.+Kj#-}؜n2[UȲd3g4UϻC$> ȅHcDk,tTJ Gmaɽ/``҅-= 9SP0 a+{q]r.l,CKԍI[~B3u% 0TFZAғ81 K5*b5WBj{q:H.m3D28q 'cp/8q$YKUhL+l`ۄ! O}Ċ5oʺ4| A Y$%mX˾ J( i"c4,: yT8N/qf/H-WKQ8fײpŕÈl NX -Ըɐ^rrBSB}- W?;VV~[JT`EUEze$g6|zXR!E~9 T @ 9ÿ) ĥ X(C*QZt*8& S:31BL_ e)/)!4¬j2Fdin:Vrݐ5@j|ZJg1&UgR S a R-E&V4%B5vFObx-9"mݠ[i<|q qaF1Ii& B &T2~~Zp2G# 2|M!A6m#WH9a Odvp'hs2K.rQ=MNC?oz9GQ _H2dkD)®}_Ԙ-e:G\km4|wAci5BYERǵk8LB@^H>zi_] fW Uh6 Be:l2~E*kq|%f  A =&_‡/,)eP:P݈;!c#}l)x%(q +]u(еԸ!N `+ի@PVήow{`LFϏW.8OG/[ N/e'q65{\==H)>'*z˻; iG]\^^/n.27{vG~#!ofۛ]_\~˻=:_1_xuw{7G, f|#Z =Jv{z3+Owc/-_FM&_wD7nݐ~ȵtf.v VX5@װ/௻-vrqhnnX;v{7ƃ:z'y<<8=^=.]kNO|o~!C;fww_wTw j'E~i(܃z=Eg~7" 4e/MǓO9hzir6=8?y)#> El݌ϺGP!O''Χ?~8;t~?xskJ@kQ Q/I߹/) }[$l=3)-$x["-v}=|ۓp fRto?$<^=d-U7 аԺ<b$FR}or\\72989AoEK"$>!iCvvJoCzʇ>ҞRbIf 86/Vf:~|dֲG֙T0Ʀʷ)E'.xK/mP)Հ1Hwȅbw4Wl:v$Oqv=ŵkmUop.ou&'iݫ_\#߫'`!^r`RiJ3V %f(=4oEnI'ϩQ57g47Z&"PKSF oQ+@&numpy/oldnumeric/functions/__init__.pyun0 <7:ia>ž`(ؑcO >ca` 1C`LC$6G)xfx"0iBn/9uCώ!O-v|Wo ;m_`#N5& S?f!c?[Q2iVv"CJ]zx?T)%Dʢ4&IkXMoy#k{@;P{!/0L%I`F>DWAMSqVPKSF(&numpy/oldnumeric/rng_stats/__init__.pyUM 09Ev ޠ;zaOl&ez{g/1hS)Q^8U&Qd快7[ JspBFOq49%.z8fXhKcgM:V8 n ٢ث+,(l,>PKSFJ_"numpy/oldnumeric/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSFc_i#numpy/oldnumeric/matrix/__init__.pySPq-( A{UTT\Wƻ4)Ioalu_}:sfi5J4:ݲjn 5YYTt' nZSb+0ijl W-.-+=7{yOh3I~*uZeJ%MRm)T| ~12F#cd(M ;S8DgΞ;bҞtyfvʯo\u{<|g_|zw?l'K睢Tu;?:LHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHxxxxxxxx7x7x7x7x7x7x7x7xxxxxxxxxwxwxwxwxwxwxwxwxxxxxxxxx/x ^/x ^^zɥ}؆=X>lh.7umO`z+t['OjV?PKSFtY5#numpy/oldnumeric/compat/__init__.pyMK1m RUaՊBH٬iJzyg>H P"Hƨ2A ZM.6=dGGH9T6Ϝn!Aٗ:{V]XT딘8JD} 8!G%E3!⃄u\#4Aux3GSݱF|T` `n*/ Ob>ƅjnu+rv]_ W*-Qiu4k{9IcdciJe}{^"|> ߐ/]!F PKSFnumpy/oldnumeric/ma/__init__.pyn: gq E]42m%GK);zǏh(u[!!띏kZzPuN=fpԁj^!nvH+<f?|]:nZ r u27<"etfC8 #tXxJ?HÄ /mΤHɊđ(0OIƢOT%#R.e(@pQ\mظ ]r䒥y^t/jQKDMGr]笨1X&qg!ʬLjl(C" Dk2Yղqe*G~\2Y d[jh ?=I=6uqx Hh=M.FI@m+h? hpl3T|:@]$uuq˵0k[Ӳ);|byC[4\Ϗ-x;z3Oh`Q ln7d,`o(=UF'pd" Q5X$n-,4pIɧ,@硓ا^Dj x: zߤRYHŭp Hs)=>~q:WdsٞozE M9Q ӒoG K_9115Q 00|ŢMP'͏A8 1,G֦ No(T5̛lph^-~l7,57ycVIKd+B)AJ6HB~PKSFޑ%numpy/oldnumeric/arrayfns/__init__.pyUAj1 нO]&]w'(EǓĒ4%W3mAY˞{[d$sjȔ=չ^CJ40hqx[j?d_3p`XvBW<e8u>֧~_ىΛD0eOy+ǶMy*}yv8B*Cz֚hbo/~d܎(/PKSFM%numpy/oldnumeric/typeconv/__init__.pyuA 0EsٵW] ='Jj I*NB(5Abgl'@'pA/H65,ť<W;-TeUc?,uQ _tkSBڪ# zPKSF<  !numpy/oldnumeric/misc/__init__.pymMN0 =E?f, EiƑI!"y>=;+R q]ÊZ,0 : zs-?xH#D^‡Ǣ* ÑR&C{Mw\xO48%v122\6Xo H(@6+991`30iê2NOka:jXÿިٲ62HZf5HKTSڠfIzn4:+}J/413b{䳭-lrקsu/)ڮj4țSV]_?wMw}.PKSF.gMw*numpy/oldnumeric/array_printer/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ XTXiT\Ԓ` %PKSFJ_'numpy/oldnumeric/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF S-numpy/oldnumeric/fix_default_axis/__init__.pymr D dY9d_}SF#LĢ|} Ndn󦫧ȴ1BYiK LJ۸LZG%L(U E"4ExL9kM0 ޼"ZGd%fgY me[ -\m_P\VդY -Suj{{'q !J{# UAhortu}s{w'$Ng΅Tŗ6U?Xolnm8?4'%CPKSFnr"!numpy/oldnumeric/mlab/__init__.pyn8s ,99 "m4@).M$6cw(Yg^q4z4jgw?m}uԖizJ`~^GL3@k'O68w'H^noqM M 3?[3Cؑ <ю6Z,rQ wpyr.AY2J5^ c85t&(:JȀIe<8F6< dJRCNǩjV%SK6t~L{촪Evj=%[&UMkMG2XW qfyg) bXC=?&I-}1w(id-1rl6  wP &xW+%F6x 5fTU\u LzUiR2]QMm s`61]>zFli T&`c {s$^<F.9$`З X8] 4Si czqْsf𨎽܋Aow~[Pxo:Ovzѻ^^*ʃ 5{\.fo|ޫ[zثQ!?v:#<=#k~cKY7G_c,WrקF~6_/.gx]wRc:tt`dڝOه?o5HwM*QOw_foC@wQPKSFؘ$#numpy/oldnumeric/ufuncs/__init__.pymKr }NekzcaD8K%Nod# &Pj@)!& i0)\+˓w .ϥLlX"(cE&-|ľ1a:cJgq6~yO+NЋ2[l71m,vī}tBayD*GBbBsq{G??N΁׶3ˮlWCGq f*黋tcN5I ː"): 3n )uy?PKSF+numpy/oldnumeric/linear_algebra/__init__.pyuAj0 E>wIY̢E{RITbg${`z*@OK%/x$OB1L)~Ԟ|9xu8]oVa&͇}5ι7%pAӱI6FtdeJnkÌ2ZGkyhT, A36)šk = -g6IYBTpP<$yqOf PKSF46(numpy/oldnumeric/alter_code1/__init__.pymn0E v<*UcU)ʢ#ra+~$!R?Z)c`_]O$Bg:#(38d@e)P[rv*ӿ@|b7}%d,d[yeOm68d;Xg/$ޠҰ= c'l*V m`T%v>fUi}_ Hx'p3g5HN? #7CrI!=}QfUV~UyCvxSg8;3h?CC2+L$鴻PKSFdJ numpy/oldnumeric/rng/__init__.pyJ1 {EI$ԙt-6mIS}{]WQ[K:Il]*h<$j');+Ns+Xͮ_+VloYa1}>Aqn/kX΁~nYmʌ$V,S)R̝Uz 6`Ln_?p)RTo$/ѻP_PKSFٵN&numpy/oldnumeric/precision/__init__.pymMk E ]֭^vĘըu~꫉ 1P[-{q;AS)̈́uVˤ(p/a"mUs^7N+M 3.lf[\ˠre.7p6GݹT;"+'d86ۅx|X"Q{.+Im"h;i B2kXC 58RXPrG1=5>"A BՃ0Kʂ̺u 7^N%k-:|3͍3 g=!6N ƺ8m& ښII6 o@L&2υQ0Oݾi{8M}y? NYrUtN>i O^ OI^`A2G4" A+mdU&C``-ՒM3$L%{49X{hEm1 i]Μ`\V^ ]@7Fo]K۪ D܋]-[ѻ0*Z«tȬ^1,)m X-)J$扐MLΐIʚRGc(,EY`ӒY3ȳw 2!6/WzMzX+c['L0pąj֛vq1J8PY6wS6Ϭ lm;4@tNSCx*BbAzJ: b4W&]y30=Ã)$l젴uC#+W>B;+ Oߩت94rۢ2+tn2OFe&)hgkRZVАk Gx][#7sSa&AD濜nXhc Ú'N{]K2 *Z힦Φ\rlA2gFu6,0Էk$-]{gg.G*gN r^Tf2ւ]%6bpѕYT4\K/]JotN%h~ȣG!pe6XnSJߓ壛H=61u\O)ٟ:z"+PuQڇ//s0 ]Ubp]"& zѠYb\T99Eu b(XQ4 TjB9 Tm;, ox-Sz`+2(Eאxp<* a1 ~I/VSz*XݣvEnV%P\ۭe]3]1R Hg((wܱ~jhч᠚&hMNO= IWRP BS'c+\!^emçljJS^ 3\`^P| (2e }Ӱq o Obw9@:mu-vULeU𥀀%PMb]z4{D(gF>P!Thnm"QTӸ<.[}Rbr:jwb #@?.@؄M,YSh +5w 3F)kkſi1еx:z[`Ө?p0D)@׮W"VnKA}~2pt(͊@`JxZ` ÇNLݎLݪ'+ 8 ]A#k2k hieBCeQk.Zß6?66So,}{X2SD%l~zd3 >OOfɗ#:ӳ { `xXYz5L_3Xtݾ6gm7̶/_$AAbyRȸn+M88/:8Ap^drw~"νOܫ`Í'BlPXZO>LAqviy>~A*N )dɧ#'_??wL9k;I o[)%MfKq e.+RIk(S$I1߂2Gx>,JzQ5 i=uM /Fow,i?!Vd6:*32}>ƕսP½_ޓ 5bGv)fD=?i}4eֱ{fuЌF:> v,)ZVEzK/P` ̴2"~%Ճeʴrݤx7&27oRZ&O}$GBڵ# 7.ֽ#ȅWi.П'}g'mou<_hf MK [gV㹸Z>׈궏)6^LGb;vw'M2A3cѤҎfv4cyKXzhߊ\09M'ԚQw@Y%:PKSF%:Opnumpy/setupscons/__init__.pyU @TSk " p!\i|8W$-v"5IJ[+)nO^/76J\gPKSFկKnumpy/numarray/__init__.pyYO#9+#F$+-Djj9J9[N*7a@uV,6qe]Uօn H ʚtUY9*dC:T |;.βW_pNkэ+jȿ_:M/DWB\ӹ4DPih.h4\'9WBiM̧xDpbpĞzqDr<ƒp-&?@eL ;%0TbIejO?$8!#AKfҊÀʆط\m6`B/c _DGKfG&mN pQ(bW7(u: u:7lnzwrzqtrKU QJ_{'Ӌŷc4,C[~x?\N[#&O!~J0T޾ ӫ~tY8բ8o?0(tK~XꮩAgzgG*>0T[,|W?aÇ cQcʭnPKSF3Ȭ$numpy/numarray/functions/__init__.py}O0W MtT ֪EB4Eƹ&Nsna9e|;9K4˖-dY**O#U Ϊ|a=He+ܾYvQueΗ4i$نY%T®)2\jH nEŶ1*".dGUNeM B-ߚɣX؂m|s`⥎J˥0DXp2řŦ5Pou^sQWW$Њ*kzP9"8 Ɛve/s)${<>\i~Q2G j“bHZj#5Ծ+qW̗b[ #cBV`Im6ؑ^ԢGc"Y1:D8^i'.`"JI<eP=9]A|6̰-klE\`cguQHxnQT3R?ó0: FE3[8ukvRij<]&ĹQ,8toH,`o[l'&FzL199u;&RJ4dXo*#>><ex 4L[ʵsF)Ȃ xwOcVmXXbmSb/Qx8۬S&M9Xvqo -v{?ݝ RÜ/4LlJAa:@RNιHLt *'}PKSFK'numpy/numarray/random_array/__init__.pyuAn! EerJ]tz˝PcT`2eƋMT/Y1[6+!~.:$šSĵg5Bn(S)u'Li1B%{n(TuڪlJY3{SHRSsuDl{P7,b@cRE0J-N443JZ2ДE(Q4ѭ V~eO1;w+ܪ2q¶؎qkd1wܘ"wTJe #Voh39 ޴YB/ek';9QT>ҳ7!k3k3h v'{{L,/jCjVꟂ-ZP L 7jMC۫nn|X;wUK\n\+ 8A3+-{`S]P~q}2++PKSFz~ck numpy/numarray/_capi/__init__.py51 0D=vjU+`@d&z~Wfp@"wC,X &(x+>ZM4.3/%tZɺӿUf_sF+R?fbRPKSFѓs"numpy/numarray/session/__init__.py}Mn0>wURh]Y 74$P{g<#zXCt1z .P NTlmw[Ey-Wtw,ώjݬ&jf9!ZDk| gimhdTՍua8eR#fRtVσAAFvb=Yv23mVNɹ3[~FZk/ar[8'vr:LD[ꖴӺA):i2]‹8A`E?f101kou<'RkƂk)2Q2")ʤ,Sr‡+},7lkhRx;]IkA3B>iF}Vkႆ@VEy׀i2|:HPʲڑZ5Dۺq=eFFD-SzX\R朴PP )HgϢ+FgzE$KƾZG֘@w&k៏ckauZ6m_R)פRVqՁL0«PͥdNמu ur vϮ*>^D#Jx dqD`-6(&5--\ a׀9B6}7q7+L[HC{1=[xo:<_ՋޛEke5tyPߪ_vC~{tWH{ ! 7 Ǟ=#86 JǑ ohh1/zYί*/O/Al8_\\///.VWg--}r#l!numpy/numarray/ufuncs/__init__.pymMr 9>G8/q30H'RFN bFS&Hd*`:* wї2&1I2H ȢeQ'_#b}w(Ndpzʱqf -wm]*Hcm@̂\fX%4+E񞀳Ac֎;igQ[djlB,;ܘ}рwny&ͰE :/0'd/\K%mc'VPKSFfad)numpy/numarray/linear_algebra/__init__.py}AN0 E9Evm%4@ $p4BkܤuI,@Wr4QBV5L1nI џ1!=j PW  S@'7q՝1||~yc8.3n~t9ƀI֥|}Ե'-f y-p8l4 ZF28ْ&9Q k? 16!v)g ?D7֎jiPKSFɱ&numpy/numarray/alter_code1/__init__.pymQn "!v`*ؑq#m*op}3ǼJ$JV#䟩ZLy毗||N8wNh//ME! 1M؁ܘOiJoEL!\/{+mSЂ 1 mT W5&9f]/Bȡ@%iԲ/lCH}F~PKSF<3'numpy/numarray/numerictypes/__init__.pyTMo0 WءN,Cv]&+(: Ȏ[2Q~QKr)R$2ZRHqQR&’a"K) R*hrl`@YUx"<Ӊ&Bc.n4ߋ T[Z9: PWr~'  ep`4w;" 窴z$5}ᆒx?esPKSFJ_numpy/testing/setup/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSFh$numpy/testing/nosetester/__init__.pyU 0 y'z&JFٚEfs=ɘc@b.碔maܭאVˉNgܖ/ex %cg39bܶuuQ\Y?yőT_SF}̞ňMܝ=/4QPKSFB$numpy/testing/decorators/__init__.pye10 Ew#\R1,Fo ɱC^JX@ܫ% HRF#>Mr<%jv3,z2]@H^_j[E-WPKSFe/numpy/testing/print_coercion_tables/__init__.pye10 Ew[ ufB!+R)8Q=I ,磻D˪kqDcNE1/RaI`٭81o {#= lmUR;}k4?\pʼn+oӱ;6g@ 6 PKSF hQh$numpy/testing/nulltester/__init__.py5A " C{(H#1Apo3ELr5ZےUi%};!%zǀg<,yƋPKSFG-ZY#numpy/testing/numpytest/__init__.pyU 0 Ew}d\RJk WI8I#ƌU*18X0Eit2j>``Td/zͲ޷0C:ˑ+*l^om NR14πOPKSFJ_$numpy/testing/setupscons/__init__.pyK+UO+-)-JW-/*Q((+%dqU'g9\ ^ZR` qPKSF,BJnumpy/testing/utils/__init__.pySR0 +rlozQ9lviu 7VX0ؒBcTǹlM| PL4 @)ǗEWEQOdBD]*H@}QM_pqSi$Dn7\)PUm nQoW2V+O-6Wzn1utԯ0o+e%Y=Qc܃iXcteYTn$d^ĝ$1-O!fFiUe5hF!9e-e%nFw6Ƞt qS%7am5Ig D1)p ڜDV헏1Cr!m\(pA42Ew?158 ]OsdoTFބh[B)c?C =:֙vܢ=)St@7b=錼 U^6|@4rZ Um]7OŰ3R2A3BBl⡭dV*Jr.؊/}oGVt2- \ jANXR+Y`]bC*`E JTZf"NgsVt6Z$eG[wermA*V}{PKSF1_numpy/lib/scimath/__init__.pyN y ]j/|c&HJ ?Iix@8Ja c@bzNk=5~$,/i*?a5ѐռ3|y (on@;C> a_r^"\}woQT5 o+ZTdc.&6pހ /t>4]۞ۇܝ PKSFo] numpy/lib/polynomial/__init__.pyuN0~ ߚJRH}8p !k8aU&<=Nʳr ژn1;c4!eCȅF˘THt "z|чr i6q egSvrtN=^77UJ! y`SɀuvyHBw@l횶IvOŜwb(Vql w>`n[khpQ\e5 QvRUnJ,6H̗I'U3䈱)"|+bD:]Ϝ7PKSF௽H"numpy/lib/index_tricks/__init__.py}Sn0 )raB;m"rҩ}ElNNR jG@cȉ΄2mU;Bdz^P b7?EB6[#==Xϕ:w7~-T2KRL%щ@]5~ +u"WA *nRs 5hAmm/ё ^ȔYh%h?]$d0wI!-'M)DzMњꢩb1Ǿ}&W WsC9:W0niv/ƒK5?PKSFIJ"numpy/lib/recfunctions/__init__.pyRN1H@JAC`&&#"|=,Aqv9!'Zj"i\ Ș/zULb\Pǫv|¡ܲ}+_] 7CUƝYe1g|$2r$LqkLڱ^fͯ*o^i^PKSFGHnumpy/lib/npyio/__init__.pyN0~v*h+UpX Y8u' ٧dh8q~k l!Q+2 }pwÅ:$\qYr5Y^}kdzZ cma if& CR f'5=RKRwBNc&,"([cW>\_a~J/ImжX4B<Sp E*X²RSwz{ӺbR\JFe7QjPXcK(BP#b-Fe!_|M~7\1e9񼑯gJ!}el.9nM_b;pִ@Qwq?Ғ9ΗlrA smRe%J8ǿPKSFG= numpy/lib/type_check/__init__.pymMk0 e0>`;rTRHz)'L^^SJmI>ok+\}:ɗP[rKtbܭ c4rؖPKSF=i"numpy/lib/arrayterator/__init__.pyMA 0 z =}0n e$9WMdo3E"Q>t!B]Ա+7egiPJ^ol<v_4t=\4?PKSF}uiNo numpy/lib/setupscons/__init__.pyU @TSk " p!\i|8W$-v"5IJVR܀J\_@k76J\gNnPKSF7~g-numpy/lib/format/__init__.pyuMK0{~Enŋ {Ye.Ea6j|jiwy2yjqvG41QZiK[/@̠]u:%%C?eE1aG:c-zȮK*E ֑MZ+m o9-t L?tX? ng[\/T_秫}OVǰNB=%..s~oPKSF֕%:numpy/lib/utils/__init__.pyuMn > k]# c4@#>ةL{e` `2(qQ],FSn\̼]uxzӹ)d7FgK#g=<fciĈ <Q\k!jwQ~i{ъ,&Fӊ:pqeK^mqA3Hwq qϹ ۲$|<ޣвI-/rrYTH"®5 pD]5[)N^9݆JyPKSFvc!numpy/lib/twodim_base/__init__.pyu=n0 c:9ڔCD]lN&p{R65 PӍQ!]˯!6qb8IF4Q7({uQ(ZDbӞ̂(O֙,P_B$j[777=\,Q/E |B]zFqBaxoPKSF01!numpy/lib/_datasource/__init__.pyu=0 Fc{$6ĆV)đ =I+Pˏ E|H, I|JUϱs>^kΏ(d/I?Ԡ5&b|*o%Ц&g85W.ba %^Y=?PKSFF1%4numpy/lib/_iotools/__init__.py=o0@w obXF CUYƹ β/H%}ؗ4ZmLqHuLYfZr`^E)z)釠1 6=dyy } G ɻ1(Jͦg& d/i|:L͇b>'`sojoe[{*" X0E)lR 0ը̟Q"CzI]k%mr%Eٌ6Qڗ"Kx"xg&7+_K uW.PKSFmknumpy/_import_tools/__init__.pym1 E9Ŕz;K7D0Da5߽HdK.bȒ1 Ag]yЧ\M /лJ '7bub4 PKSF&sip/__init__.pyN0:S@ Ku!h`ݴ c7mws-(QΥ3ڶ"Ymq>AS I j ]= l8ᬒD?9JCBrj['9ٔF{> RGtZ~n]p,?7lfU\IZ- Px̄p,ShgM袾O_< PK]SF _mock.pyPKSFxa0IPython/__init__.pyPKSF;g`IPython/kernel/__init__.pyPKSF:?#xIPython/kernel/channels/__init__.pyPKSFDTy$IPython/kernel/clientabc/__init__.pyPKSF0l i"IPython/kernel/manager/__init__.pyPKSFpI#\IPython/kernel/launcher/__init__.pyPKSF$0 IPython/kernel/restarter/__init__.pyPKSF|0Y/m!; IPython/kernel/client/__init__.pyPKSFYo- IPython/kernel/multikernelmanager/__init__.pyPKSF`% IPython/kernel/managerabc/__init__.pyPKSFgDd6H IPython/kernel/tests/__init__.pyPKSF`&[IPython/kernel/channelsabc/__init__.pyPKSF@T< #>IPython/kernel/blocking/__init__.pyPKSFA,IPython/kernel/blocking/channels/__init__.pyPKSFE.f*2IPython/kernel/blocking/client/__init__.pyPKSFPn9$NIPython/kernel/inprocess/__init__.pyPKSF#-IPython/kernel/inprocess/channels/__init__.pyPKSF@w,IPython/kernel/inprocess/manager/__init__.pyPKSFRRx'+IPython/kernel/inprocess/client/__init__.pyPKSFgDd6H*IPython/kernel/inprocess/tests/__init__.pyPKSFD׾e=uIPython/kernel/inprocess/tests/test_kernelmanager/__init__.pyPKSFεx+IPython/kernel/inprocess/socket/__init__.pyPKSF֍-IPython/kernel/inprocess/ipkernel/__init__.pyPKSF)j-IPython/kernel/inprocess/blocking/__init__.pyPKSF{2ϟ;!IPython/kernel/ioloop/__init__.pyPKSFN`)IPython/kernel/ioloop/manager/__init__.pyPKSF*+IPython/kernel/ioloop/restarter/__init__.pyPKSFi"IPython/kernel/connect/__init__.pyPKSF"˞ IPython/kernel/zmq/__init__.pyPKSFpÚ(!IPython/kernel/zmq/heartbeat/__init__.pyPKSF".}+"IPython/kernel/zmq/parentpoller/__init__.pyPKSFYTy$#IPython/kernel/zmq/pylab/__init__.pyPKSF7_3x$IPython/kernel/zmq/pylab/backend_inline/__init__.pyPKSF S'&IPython/kernel/zmq/iostream/__init__.pyPKSF(÷*@'IPython/kernel/zmq/displayhook/__init__.pyPKSFK4"b(IPython/kernel/zmq/log/__init__.pyPKSF1D'8)IPython/kernel/zmq/zmqshell/__init__.pyPKSFm-(+IPython/kernel/zmq/kernelapp/__init__.pyPKSFgDd6H$4/IPython/kernel/zmq/tests/__init__.pyPKSF̡1/IPython/kernel/zmq/tests/test_session/__init__.pyPKSF2G'0IPython/kernel/zmq/ipkernel/__init__.pyPKSF:&3IPython/kernel/zmq/datapub/__init__.pyPKSFP<7(N4IPython/kernel/zmq/serialize/__init__.pyPKSFv&5IPython/kernel/zmq/session/__init__.pyPKSFJG)8IPython/kernel/zmq/eventloops/__init__.pyPKSFgDd6H"v9IPython/kernel/zmq/gui/__init__.pyPKSFi+9IPython/kernel/zmq/gui/gtkembed/__init__.pyPKSFZ $:IPython/kernel/zmq/embed/__init__.pyPKSF?i2 v;IPython/core/__init__.pyPKSF(>IPython/core/magic_arguments/__init__.pyPKSFwl?IPython/core/page/__init__.pyPKSFbJ#@IPython/core/splitinput/__init__.pyPKSFk(#AIPython/core/formatters/__init__.pyPKSF =!CIPython/core/excolors/__init__.pyPKSF\z} EIPython/core/payload/__init__.pyPKSFu!EIPython/core/autocall/__init__.pyPKSFrFIPython/core/macro/__init__.pyPKSF:9uV$[GIPython/core/application/__init__.pyPKSFW#IIPython/core/profileapp/__init__.pyPKSFj3MIPython/core/alias/__init__.pyPKSFlJ˳1$,hIPython/frontend/kernel/channels/__init__.pyPKSF?Sy-IPython/frontend/kernel/clientabc/__init__.pyPKSFoi+IPython/frontend/kernel/manager/__init__.pyPKSFpI,fIPython/frontend/kernel/launcher/__init__.pyPKSF-CIPython/frontend/kernel/restarter/__init__.pyPKSF/m*WIPython/frontend/kernel/client/__init__.pyPKSFYo6IPython/frontend/kernel/multikernelmanager/__init__.pyPKSF 耝.0IPython/frontend/kernel/managerabc/__init__.pyPKSFgDd6H)IPython/frontend/kernel/tests/__init__.pyPKSFƂ K/IPython/frontend/kernel/channelsabc/__init__.pyPKSFڂ,~IPython/frontend/kernel/blocking/__init__.pyPKSFA5eIPython/frontend/kernel/blocking/channels/__init__.pyPKSFE.f3IPython/frontend/kernel/blocking/client/__init__.pyPKSF*-IPython/frontend/kernel/inprocess/__init__.pyPKSFV.*6#IPython/frontend/kernel/inprocess/channels/__init__.pyPKSFq@w5QIPython/frontend/kernel/inprocess/manager/__init__.pyPKSFS'4fIPython/frontend/kernel/inprocess/client/__init__.pyPKSFĮт3IPython/frontend/kernel/inprocess/tests/__init__.pyPKSFD׾eFhIPython/frontend/kernel/inprocess/tests/test_kernelmanager/__init__.pyPKSF}Px4IPython/frontend/kernel/inprocess/socket/__init__.pyPKSFtWN 6IPython/frontend/kernel/inprocess/ipkernel/__init__.pyPKSF)j6IPython/frontend/kernel/inprocess/blocking/__init__.pyPKSFM*IPython/frontend/kernel/ioloop/__init__.pyPKSFN`2IPython/frontend/kernel/ioloop/manager/__init__.pyPKSF*4IPython/frontend/kernel/ioloop/restarter/__init__.pyPKSFi+IPython/frontend/kernel/connect/__init__.pyPKSFoUY'IPython/frontend/kernel/zmq/__init__.pyPKSFpÚ1|IPython/frontend/kernel/zmq/heartbeat/__init__.pyPKSF".}4eIPython/frontend/kernel/zmq/parentpoller/__init__.pyPKSFY.~-]IPython/frontend/kernel/zmq/pylab/__init__.pyPKSF7_<&IPython/frontend/kernel/zmq/pylab/backend_inline/__init__.pyPKSF S0IPython/frontend/kernel/zmq/iostream/__init__.pyPKSF(÷3IPython/frontend/kernel/zmq/displayhook/__init__.pyPKSFK4++IPython/frontend/kernel/zmq/log/__init__.pyPKSFVD0 IPython/frontend/kernel/zmq/zmqshell/__init__.pyPKSFm-1IPython/frontend/kernel/zmq/kernelapp/__init__.pyPKSF&bz-IPython/frontend/kernel/zmq/tests/__init__.pyPKSF̡:IPython/frontend/kernel/zmq/tests/test_session/__init__.pyPKSF2G0$IPython/frontend/kernel/zmq/ipkernel/__init__.pyPKSF:/QIPython/frontend/kernel/zmq/datapub/__init__.pyPKSFP<71IPython/frontend/kernel/zmq/serialize/__init__.pyPKSFv/IPython/frontend/kernel/zmq/session/__init__.pyPKSFJG2IPython/frontend/kernel/zmq/eventloops/__init__.pyPKSF"mVv+IPython/frontend/kernel/zmq/gui/__init__.pyPKSFi4IPython/frontend/kernel/zmq/gui/gtkembed/__init__.pyPKSFZ -WIPython/frontend/kernel/zmq/embed/__init__.pyPKSFɘ!8IPython/frontend/core/__init__.pyPKSF1IPython/frontend/core/magic_arguments/__init__.pyPKSF-&oIPython/frontend/core/page/__init__.pyPKSFbJ, IPython/frontend/core/splitinput/__init__.pyPKSF1{(, IPython/frontend/core/formatters/__init__.pyPKSF =* IPython/frontend/core/excolors/__init__.pyPKSF\z})%IPython/frontend/core/payload/__init__.pyPKSFu*IPython/frontend/core/autocall/__init__.pyPKSF'IPython/frontend/core/macro/__init__.pyPKSF:9uV-IPython/frontend/core/application/__init__.pyPKSFW,XIPython/frontend/core/profileapp/__init__.pyPKSFj'IPython/frontend/core/alias/__init__.pyPKSFlJ˳1-IPython/frontend/core/displayhook/__init__.pyPKSFX:a2IPython/frontend/core/interactiveshell/__init__.pyPKSF 'P )IPython/frontend/core/display/__init__.pyPKSFW&,IPython/frontend/core/displaypub/__init__.pyPKSF`m *IPython/frontend/core/oinspect/__init__.pyPKSFYk" )9#IPython/frontend/core/release/__init__.pyPKSFaj,)IPython/frontend/core/fakemodule/__init__.pyPKSF*+')IPython/frontend/core/tests/__init__.pyPKSFj9$+IPython/frontend/core/tests/test_completerlib/__init__.pyPKSFjc Ol.^,IPython/frontend/core/tests/refbug/__init__.pyPKSFS1,IPython/frontend/core/tests/simpleerr/__init__.pyPKSFgDd6H1-IPython/frontend/core/tests/nonascii2/__init__.pyPKSF~N1 .IPython/frontend/core/tests/test_page/__init__.pyPKSF{`6.IPython/frontend/core/tests/daft_extension/__init__.pyPKSF*(}5/IPython/frontend/core/tests/test_autocall/__init__.pyPKSF^Z.r0IPython/frontend/core/tests/tclass/__init__.pyPKSFjd01IPython/frontend/core/tests/nonascii/__init__.pyPKSF941IPython/frontend/core/tests/test_imports/__init__.pyPKSFIwAU22IPython/frontend/core/tests/print_argv/__init__.pyPKSF&D4q3IPython/frontend/core/tests/test_ultratb/__init__.pyPKSFE[5N5IPython/frontend/core/tests/test_shellapp/__init__.pyPKSFȻ,u6IPython/frontend/core/profiledir/__init__.pyPKSFib.7IPython/frontend/core/builtin_trap/__init__.pyPKSFWJ],r8IPython/frontend/core/getipython/__init__.pyPKSFO`/6z'9IPython/frontend/core/error/__init__.pyPKSF?O X+9IPython/frontend/core/completer/__init__.pyPKSFt4';IPython/frontend/core/hooks/__init__.pyPKSF^䦁.<IPython/frontend/core/display_trap/__init__.pyPKSFəb(=IPython/frontend/core/magics/__init__.pyPKSFD$.?IPython/frontend/core/magics/basic/__init__.pyPKSFl}3 AIPython/frontend/core/magics/deprecated/__init__.pyPKSF3G[2AIPython/frontend/core/magics/extension/__init__.pyPKSF(,BIPython/frontend/core/magics/osm/__init__.pyPKSF``_.%DIPython/frontend/core/magics/pylab/__init__.pyPKSF}ޯ0FEIPython/frontend/core/magics/display/__init__.pyPKSFuH2CFIPython/frontend/core/magics/execution/__init__.pyPKSFs82SHIPython/frontend/core/magics/namespace/__init__.pyPKSFpB'@-IIPython/frontend/core/magics/code/__init__.pyPKSFC2/.KIPython/frontend/core/magics/script/__init__.pyPKSF"A+/LIPython/frontend/core/magics/config/__init__.pyPKSF#g-MIPython/frontend/core/magics/auto/__init__.pyPKSF_ &#0iNIPython/frontend/core/magics/logging/__init__.pyPKSFZ,0JOIPython/frontend/core/magics/history/__init__.pyPKSFGTn+PIPython/frontend/core/prefilter/__init__.pyPKSF@)RIPython/frontend/core/ultratb/__init__.pyPKSF^3H5 )UIPython/frontend/core/prompts/__init__.pyPKSF'cql"\'XIPython/frontend/core/usage/__init__.pyPKSFۘ,{IPython/frontend/core/extensions/__init__.pyPKSF`l],s|IPython/frontend/core/historyapp/__init__.pyPKSF'X,~IPython/frontend/core/compilerop/__init__.pyPKSFnͼi- IPython/frontend/core/payloadpage/__init__.pyPKSFtVa*IPython/frontend/core/shellapp/__init__.pyPKSFLS)IPython/frontend/core/history/__init__.pyPKSF:['2IPython/frontend/core/inputtransformer/__init__.pyPKSF;m(IPython/frontend/core/logger/__init__.pyPKSF@s,IPython/frontend/core/pylabtools/__init__.pyPKSFO/ƇIPython/frontend/core/inputsplitter/__init__.pyPKSFgDd6H*IPython/frontend/core/shadowns/__init__.pyPKSF9" .hIPython/frontend/core/completerlib/__init__.pyPKSFXaQ'IPython/frontend/core/magic/__init__.pyPKSFQRg*IPython/frontend/core/debugger/__init__.pyPKSF$5S# .IPython/frontend/core/crashhandler/__init__.pyPKSF^ohk%IPython/frontend/frontend/__init__.pyPKSF 9fv $.IPython/frontend/display/__init__.pyPKSFgDd6H$֗IPython/frontend/scripts/__init__.pyPKSF7ox F%NIPython/frontend/external/__init__.pyPKSFs@ҽ1IPython/frontend/external/jsonpointer/__init__.pyPKSF>>IPython/frontend/external/jsonpointer/_jsonpointer/__init__.pyPKSFty)IPython/frontend/external/ssh/__init__.pyPKSF@1oIPython/frontend/external/ssh/forward/__init__.pyPKSF'Yyo0IPython/frontend/external/ssh/tunnel/__init__.pyPKSF770IPython/frontend/external/jsonschema/__init__.pyPKSF~0C-<lIPython/frontend/external/jsonschema/_jsonschema/__init__.pyPKSF0 IPython/frontend/external/qt_loaders/__init__.pyPKSF>-4IPython/frontend/external/mathjax/__init__.pyPKSFt*sIPython/frontend/external/path/__init__.pyPKSFA?ܜF0<IPython/frontend/external/path/_path/__init__.pyPKSF00IPython/frontend/external/decorators/__init__.pyPKSF*rE^IPython/frontend/external/decorators/_numpy_testing_utils/__init__.pyPKSF<3IPython/frontend/external/decorators/_decorators/__init__.pyPKSF/ذ/IPython/frontend/external/decorator/__init__.pyPKSFȼfޘ:IPython/frontend/external/decorator/_decorator/__init__.pyPKSFe)3IPython/frontend/external/qt_for_kernel/__init__.pyPKSF-IPython/frontend/external/pexpect/__init__.pyPKSF% F6IPython/frontend/external/pexpect/_pexpect/__init__.pyPKSFq:,.IPython/frontend/external/argparse/__init__.pyPKSFL48$IPython/frontend/external/argparse/_argparse/__init__.pyPKSF@p3IPython/frontend/external/simplegeneric/__init__.pyPKSFN1xBIPython/frontend/external/simplegeneric/_simplegeneric/__init__.pyPKSFQFd'ųIPython/frontend/consoleapp/__init__.pyPKSFSg%IPython/frontend/nbformat/__init__.pyPKSFd8g(IPython/frontend/nbformat/v3/__init__.pyPKSFNZ-r/IPython/frontend/nbformat/v3/nbbase/__init__.pyPKSF$m/IPython/frontend/nbformat/v3/nbjson/__init__.pyPKSFG-IPython/frontend/nbformat/v3/nbpy/__init__.pyPKSF/IPython/frontend/nbformat/v3/rwbase/__init__.pyPKSF ,..:IPython/frontend/nbformat/v3/tests/__init__.pyPKSFA 6C86IPython/frontend/nbformat/v3/tests/test_nbpy/__init__.pyPKSF+=81IPython/frontend/nbformat/v3/tests/test_json/__init__.pyPKSFD6:IPython/frontend/nbformat/v3/tests/test_nbbase/__init__.pyPKSF(pr]9IPython/frontend/nbformat/v3/tests/formattest/__init__.pyPKSFO?9IPython/frontend/nbformat/v3/tests/nbexamples/__init__.pyPKSFvz2IPython/frontend/nbformat/v3/validator/__init__.pyPKSF"\:0IPython/frontend/nbformat/v3/convert/__init__.pyPKSFgDd6H+IPython/frontend/nbformat/tests/__init__.pyPKSF]fL-!IPython/frontend/nbformat/current/__init__.pyPKSFo!(IPython/frontend/nbformat/v1/__init__.pyPKSFn+/IPython/frontend/nbformat/v1/nbbase/__init__.pyPKSF6./IPython/frontend/nbformat/v1/nbjson/__init__.pyPKSFfEp/IPython/frontend/nbformat/v1/rwbase/__init__.pyPKSF3m.IPython/frontend/nbformat/v1/tests/__init__.pyPKSF'G j8rIPython/frontend/nbformat/v1/tests/test_json/__init__.pyPKSFV26:rIPython/frontend/nbformat/v1/tests/test_nbbase/__init__.pyPKSFr~9IPython/frontend/nbformat/v1/tests/nbexamples/__init__.pyPKSFiRj0eIPython/frontend/nbformat/v1/convert/__init__.pyPKSFDY(IPython/frontend/nbformat/v2/__init__.pyPKSF# 矮/IPython/frontend/nbformat/v2/nbbase/__init__.pyPKSFP$/IPython/frontend/nbformat/v2/nbjson/__init__.pyPKSF׹.IPython/frontend/nbformat/v2/nbxml/__init__.pyPKSF$8 -IPython/frontend/nbformat/v2/nbpy/__init__.pyPKSFϭ/IPython/frontend/nbformat/v2/rwbase/__init__.pyPKSF&C(.IPython/frontend/nbformat/v2/tests/__init__.pyPKSF-Q8IPython/frontend/nbformat/v2/tests/test_nbpy/__init__.pyPKSFS,|8{IPython/frontend/nbformat/v2/tests/test_json/__init__.pyPKSF$:IPython/frontend/nbformat/v2/tests/test_nbbase/__init__.pyPKSFdJ9IPython/frontend/nbformat/v2/tests/nbexamples/__init__.pyPKSFw0gIPython/frontend/nbformat/v2/convert/__init__.pyPKSF.y&,IPython/frontend/nbconvert/__init__.pyPKSF$Rs>0 IPython/frontend/nbconvert/exporters/__init__.pyPKSFM<9IPython/frontend/nbconvert/exporters/markdown/__init__.pyPKSF5-U7qIPython/frontend/nbconvert/exporters/slides/__init__.pyPKSF#hNy9IPython/frontend/nbconvert/exporters/exporter/__init__.pyPKSFC76IPython/frontend/nbconvert/exporters/tests/__init__.pyPKSFDIPython/frontend/nbconvert/exporters/tests/test_exporter/__init__.pyPKSF0yY=IPython/frontend/nbconvert/exporters/tests/cheese/__init__.pyPKSFƵuBQ;IPython/frontend/nbconvert/exporters/tests/base/__init__.pyPKSF<쒦xDIPython/frontend/nbconvert/exporters/tests/test_markdown/__init__.pyPKSFDHBIPython/frontend/nbconvert/exporters/tests/test_export/__init__.pyPKSF tBIPython/frontend/nbconvert/exporters/tests/test_python/__init__.pyPKSF 6%IPython/frontend/nbconvert/exporters/latex/__init__.pyPKSFcB4UIPython/frontend/nbconvert/exporters/rst/__init__.pyPKSF fVD73IPython/frontend/nbconvert/exporters/export/__init__.pyPKSF35IPython/frontend/nbconvert/exporters/html/__init__.pyPKSFP!7IPython/frontend/nbconvert/exporters/python/__init__.pyPKSF7 SQ3IPython/frontend/nbconvert/transformers/__init__.pyPKSF٨J8)IPython/frontend/nbconvert/transformers/base/__init__.pyPKSF=8BIPython/frontend/nbconvert/transformers/convertfigures/__init__.pyPKSF >IPython/frontend/nbconvert/transformers/revealhelp/__init__.pyPKSFl}m;IPython/frontend/nbconvert/transformers/svg2pdf/__init__.pyPKSFKYC.IPython/frontend/nbconvert/transformers/coalescestreams/__init__.pyPKSF"e 9IPython/frontend/nbconvert/transformers/latex/__init__.pyPKSF]dAIPython/frontend/nbconvert/transformers/extractoutput/__init__.pyPKSF~$v =:IPython/frontend/nbconvert/transformers/sphinx/__init__.pyPKSF= AlIPython/frontend/nbconvert/transformers/csshtmlheader/__init__.pyPKSF;l.IPython/frontend/nbconvert/filters/__init__.pyPKSF#̑q7bIPython/frontend/nbconvert/filters/markdown/__init__.pyPKSFF#3(IPython/frontend/nbconvert/filters/ansi/__init__.pyPKSFrnf= IPython/frontend/nbconvert/filters/datatypefilter/__init__.pyPKSFjy2!y4IPython/frontend/nbconvert/filters/tests/__init__.pyPKSFmͭn?IPython/frontend/nbconvert/filters/tests/test_latex/__init__.pyPKSFosCIPython/frontend/nbconvert/filters/tests/test_highlight/__init__.pyPKSFjsfAIPython/frontend/nbconvert/filters/tests/test_strings/__init__.pyPKSFJkH_ IPython/frontend/nbconvert/filters/tests/test_datatypefilter/__init__.pyPKSF;cxA>c IPython/frontend/nbconvert/filters/tests/test_ansi/__init__.pyPKSFZ7Eq47 IPython/frontend/nbconvert/filters/latex/__init__.pyPKSF6 IPython/frontend/nbconvert/filters/strings/__init__.pyPKSF78TIPython/frontend/nbconvert/filters/highlight/__init__.pyPKSFs,IPython/frontend/nbconvert/tests/__init__.pyPKSF:<1WIPython/frontend/nbconvert/tests/base/__init__.pyPKSF?7_.IPython/frontend/nbconvert/writers/__init__.pyPKSF~x3IPython/frontend/nbconvert/writers/base/__init__.pyPKSF [5IPython/frontend/nbconvert/writers/stdout/__init__.pyPKSFi"4;IPython/frontend/nbconvert/writers/files/__init__.pyPKSFGc40IPython/frontend/nbconvert/writers/debug/__init__.pyPKSF.,IPython/frontend/nbconvert/utils/__init__.pyPKSFV-1IPython/frontend/nbconvert/utils/base/__init__.pyPKSFx[Xq7IPython/frontend/nbconvert/utils/exceptions/__init__.pyPKSF%)_4TIPython/frontend/nbconvert/utils/console/__init__.pyPKSF7+3IPython/frontend/nbconvert/utils/lexers/__init__.pyPKSF3IPython/frontend/nbconvert/utils/pandoc/__init__.pyPKSFm 3IPython/frontend/nbconvert/nbconvertapp/__init__.pyPKSF6IPython/frontend/nbconvert/post_processors/__init__.pyPKSF|`;IPython/frontend/nbconvert/post_processors/base/__init__.pyPKSFB\k}<IPython/frontend/nbconvert/post_processors/serve/__init__.pyPKSFunU׵:!IPython/frontend/nbconvert/post_processors/pdf/__init__.pyPKSFA}$ #"IPython/frontend/config/__init__.pyPKSFg/X&IPython/frontend/config/application/__init__.pyPKSF'T()I)IPython/frontend/config/tests/__init__.pyPKSF;*IPython/frontend/config/tests/test_configurable/__init__.pyPKSFq'c:+IPython/frontend/config/tests/test_application/__init__.pyPKSF!0x-IPython/frontend/config/configurable/__init__.pyPKSFgDd6H+.IPython/frontend/config/profile/__init__.pyPKSFTN*/IPython/frontend/config/loader/__init__.pyPKSF/ҽo'0IPython/frontend/extensions/__init__.pyPKSFl>Xx51IPython/frontend/extensions/parallelmagic/__init__.pyPKSFgDd6H-K2IPython/frontend/extensions/tests/__init__.pyPKSFvȌ(52IPython/frontend/extensions/sympyprinting/__init__.pyPKSF%4L$23IPython/frontend/extensions/autoreload/__init__.pyPKSFm2G5IPython/frontend/extensions/storemagic/__init__.pyPKSF)`3r6IPython/frontend/extensions/cythonmagic/__init__.pyPKSFA."8IPython/frontend/utils/__init__.pyPKSFLtVE-;IPython/frontend/utils/pickleutil/__init__.pyPKSF[ZƊTs';=IPython/frontend/utils/dir2/__init__.pyPKSFk*=IPython/frontend/utils/tempdir/__init__.pyPKSF7+>IPython/frontend/utils/wildcard/__init__.pyPKSFQz,|?IPython/frontend/utils/daemonize/__init__.pyPKSFxݰ*@IPython/frontend/utils/process/__init__.pyPKSFNO0AIPython/frontend/utils/_tokenize_py2/__init__.pyPKSFww2)?FIPython/frontend/utils/openpy/__init__.pyPKSF(:{X1GIPython/frontend/utils/nested_context/__init__.pyPKSF\v+&HIPython/frontend/utils/ipstruct/__init__.pyPKSFzE7%HIPython/frontend/utils/io/__init__.pyPKSFdZ0IIPython/frontend/utils/doctestreload/__init__.pyPKSFَ,~JIPython/frontend/utils/submodule/__init__.pyPKSF̱c%+JKIPython/frontend/utils/encoding/__init__.pyPKSFc*LIPython/frontend/utils/sysinfo/__init__.pyPKSFOWH{'GMIPython/frontend/utils/path/__init__.pyPKSFb)/OIPython/frontend/utils/timing/__init__.pyPKSFp8b2OIPython/frontend/utils/_process_common/__init__.pyPKSFo(PIPython/frontend/utils/tests/__init__.pyPKSFvjH:QIPython/frontend/utils/tests/test_module_paths/__init__.pyPKSFّ\5gSIPython/frontend/utils/tests/test_tempdir/__init__.pyPKSF9|6KTIPython/frontend/utils/tests/test_wildcard/__init__.pyPKSFL-5UIPython/frontend/utils/tests/test_imports/__init__.pyPKSF d1YVIPython/frontend/utils/syspathcontext/__init__.pyPKSF,<q+ WIPython/frontend/utils/generics/__init__.pyPKSFDpR]-WIPython/frontend/utils/zmqrelated/__init__.pyPKSFt4V'nXIPython/frontend/utils/data/__init__.pyPKSFiX , YIPython/frontend/utils/traitlets/__init__.pyPKSFRE-JZ+[IPython/frontend/utils/_sysinfo/__init__.pyPKSFlG,n\IPython/frontend/utils/tokenize2/__init__.pyPKSF,zQ^*^IPython/frontend/utils/version/__init__.pyPKSFYg="%V_IPython/frontend/utils/tz/__init__.pyPKSFmOm-&`IPython/frontend/utils/decorators/__init__.pyPKSFv8.`IPython/frontend/utils/pickleshare/__init__.pyPKSF|k.aIPython/frontend/utils/strdispatch/__init__.pyPKSFf2zbIPython/frontend/utils/localinterfaces/__init__.pyPKSFW:IPython/frontend/parallel/controller/scheduler/__init__.pyPKSFJ{d7IPython/frontend/parallel/controller/dictdb/__init__.pyPKSF\=IPython/frontend/parallel/controller/heartmonitor/__init__.pyPKSF_ H4XIPython/frontend/parallel/controller/hub/__init__.pyPKSFb0j*mIPython/frontend/parallel/apps/__init__.pyPKSFJaM4IPython/frontend/parallel/apps/winhpcjob/__init__.pyPKSFl$ 3IPython/frontend/parallel/apps/launcher/__init__.pyPKSFp 6IPython/frontend/parallel/apps/ipengineapp/__init__.pyPKSF@46IPython/frontend/parallel/apps/iploggerapp/__init__.pyPKSFp񾱇7#IPython/frontend/parallel/apps/win32support/__init__.pyPKSF'BJ7IPython/frontend/parallel/apps/ipclusterapp/__init__.pyPKSF Ue 2IPython/frontend/parallel/apps/baseapp/__init__.pyPKSFjbbg5IPython/frontend/parallel/apps/logwatcher/__init__.pyPKSF{F :IPython/frontend/parallel/apps/ipcontrollerapp/__init__.pyPKSFnp*IPython/frontend/parallel/util/__init__.pyPKSF/8F&IPython/frontend/sphinxext/__init__.pyPKSF[V~nCIPython/frontend/sphinxext/ipython_console_highlighting/__init__.pyPKSF}wj8IPython/frontend/sphinxext/ipython_directive/__init__.pyPKSF'Z IPython/frontend/lib/__init__.pyPKSF{'&IPython/frontend/lib/kernel/__init__.pyPKSF[Y.IPython/frontend/lib/inputhookglut/__init__.pyPKSFN{cE(IPython/frontend/lib/irunner/__init__.pyPKSFA^3+IPython/frontend/lib/latextools/__init__.pyPKSFtx-1IPython/frontend/lib/inputhookqt4/__init__.pyPKSFҐ^%DIPython/frontend/lib/demo/__init__.pyPKSFat:,`IPython/frontend/lib/editorhooks/__init__.pyPKSF[,XIPython/frontend/lib/inputhookwx/__init__.pyPKSFEʉ`-8IPython/frontend/lib/inputhookgtk/__init__.pyPKSFL1J(IPython/frontend/lib/display/__init__.pyPKSFOf*ZIPython/frontend/lib/inputhook/__init__.pyPKSF5їmv&IPython/frontend/lib/tests/__init__.pyPKSF3IPython/frontend/lib/tests/test_irunner/__init__.pyPKSF>Okf)IPython/frontend/lib/security/__init__.pyPKSFk9s+IPython/frontend/lib/deepreload/__init__.pyPKSFmr+IPython/frontend/lib/guisupport/__init__.pyPKSFBa'IPython/frontend/lib/pretty/__init__.pyPKSF ی&/4IPython/frontend/lib/backgroundjobs/__init__.pyPKSF{yD*IPython/frontend/lib/clipboard/__init__.pyPKSF|3%IPython/frontend/terminal/__init__.pyPKSF1O3e&6IPython/frontend/terminal/interactiveshell/__init__.pyPKSFgDd6H+IPython/frontend/terminal/tests/__init__.pyPKSF=u+IPython/frontend/terminal/ipapp/__init__.pyPKSFNU-IPython/frontend/terminal/console/__init__.pyPKSFDž8>IPython/frontend/terminal/console/interactiveshell/__init__.pyPKSFUby3IPython/frontend/terminal/console/tests/__init__.pyPKSFgDd6H?cIPython/frontend/terminal/console/tests/writetofile/__init__.pyPKSF!Vk\=7IPython/frontend/terminal/console/completer/__init__.pyPKSFw /1IPython/frontend/terminal/console/app/__init__.pyPKSFWQ+( IPython/frontend/terminal/embed/__init__.pyPKSF>!IPython/frontend/html/__init__.pyPKSFWւ&IPython/frontend/html/base/__init__.pyPKSF 2IPython/frontend/html/base/zmqhandlers/__init__.pyPKSFG! /IPython/frontend/html/base/handlers/__init__.pyPKSFgDd6H'!IPython/frontend/html/tests/__init__.pyPKSF>/к*IPython/frontend/html/notebook/__init__.pyPKSF& /IPython/frontend/html/notebook/base/__init__.pyPKSF ;IPython/frontend/html/notebook/base/zmqhandlers/__init__.pyPKSFG! 8IPython/frontend/html/notebook/base/handlers/__init__.pyPKSFgDd6H0IPython/frontend/html/notebook/tests/__init__.pyPKSFy3IPython/frontend/html/notebook/notebook/__init__.pyPKSFTD^<IIPython/frontend/html/notebook/notebook/handlers/__init__.pyPKSFd 6~IPython/frontend/html/notebook/notebookapp/__init__.pyPKSFK_0IPython/frontend/html/notebook/utils/__init__.pyPKSFkftj3F IPython/frontend/html/notebook/services/__init__.pyPKSF =,!IPython/frontend/html/notebook/services/notebooks/__init__.pyPKSFmG/"IPython/frontend/html/notebook/services/notebooks/nbmanager/__init__.pyPKSF-eK#IPython/frontend/html/notebook/services/notebooks/filenbmanager/__init__.pyPKSFwC%IPython/frontend/html/notebook/services/notebooks/tests/__init__.pyPKSFzR%IPython/frontend/html/notebook/services/notebooks/tests/test_nbmanager/__init__.pyPKSFֹF('IPython/frontend/html/notebook/services/notebooks/handlers/__init__.pyPKSF')7-<[(IPython/frontend/html/notebook/services/clusters/__init__.pyPKSFiDϏYoKK)IPython/frontend/html/notebook/services/clusters/clustermanager/__init__.pyPKSFZE ,IPython/frontend/html/notebook/services/clusters/handlers/__init__.pyPKSFx(;.-IPython/frontend/html/notebook/services/kernels/__init__.pyPKSFhI.IPython/frontend/html/notebook/services/kernels/kernelmanager/__init__.pyPKSFAc-D)/IPython/frontend/html/notebook/services/kernels/handlers/__init__.pyPKSFCx/0IPython/frontend/html/notebook/tree/__init__.pyPKSF8}8}1IPython/frontend/html/notebook/tree/handlers/__init__.pyPKSFnFil/P2IPython/frontend/html/notebook/auth/__init__.pyPKSFԇ5 3IPython/frontend/html/notebook/auth/login/__init__.pyPKSFJ1p63IPython/frontend/html/notebook/auth/logout/__init__.pyPKSFd -4IPython/frontend/html/notebookapp/__init__.pyPKSFK_'9IPython/frontend/html/utils/__init__.pyPKSFO*t:IPython/frontend/html/services/__init__.pyPKSF4M;IPython/frontend/html/services/notebooks/__init__.pyPKSFm>B<IPython/frontend/html/services/notebooks/nbmanager/__init__.pyPKSF-eB=IPython/frontend/html/services/notebooks/filenbmanager/__init__.pyPKSFU:?IPython/frontend/html/services/notebooks/tests/__init__.pyPKSFzI?IPython/frontend/html/services/notebooks/tests/test_nbmanager/__init__.pyPKSFֹ=AIPython/frontend/html/services/notebooks/handlers/__init__.pyPKSFt3?BIPython/frontend/html/services/clusters/__init__.pyPKSFiDϏYoBCIPython/frontend/html/services/clusters/clustermanager/__init__.pyPKSFZ<EIPython/frontend/html/services/clusters/handlers/__init__.pyPKSFf2FIPython/frontend/html/services/kernels/__init__.pyPKSFh@GIPython/frontend/html/services/kernels/kernelmanager/__init__.pyPKSFAc-;HIPython/frontend/html/services/kernels/handlers/__init__.pyPKSFp}5r&XJIPython/frontend/html/tree/__init__.pyPKSF8}/KIPython/frontend/html/tree/handlers/__init__.pyPKSFV}&KIPython/frontend/html/auth/__init__.pyPKSFԇ,LIPython/frontend/html/auth/login/__init__.pyPKSFJ1p-jMIPython/frontend/html/auth/logout/__init__.pyPKSF%NIPython/frontend/qt/__init__.pyPKSF?Wo3NIPython/frontend/qt/base_frontend_mixin/__init__.pyPKSFR\O'OIPython/frontend/qt/console/__init__.pyPKSF S-fPIPython/frontend/qt/console/tests/__init__.pyPKSFPs?C0QIPython/frontend/qt/console/tests/test_completion_lexer/__init__.pyPKSFo8RIPython/frontend/qt/console/completion_lexer/__init__.pyPKSFj .kSIPython/frontend/qt/console/styles/__init__.pyPKSF 9fv UIPython/display/__init__.pyPKSFgDd6H+XIPython/scripts/__init__.pyPKSF!XIPython/external/__init__.pyPKSF^Ex(YIPython/external/jsonpointer/__init__.pyPKSF>5ZIPython/external/jsonpointer/_jsonpointer/__init__.pyPKSFn [IPython/external/ssh/__init__.pyPKSF@(8\IPython/external/ssh/forward/__init__.pyPKSF'Yyo'J]IPython/external/ssh/tunnel/__init__.pyPKSF >y1'^IPython/external/jsonschema/__init__.pyPKSF~0C-3`IPython/external/jsonschema/_jsonschema/__init__.pyPKSF'aIPython/external/qt_loaders/__init__.pyPKSF>$bIPython/external/mathjax/__init__.pyPKSF%7{!dIPython/external/path/__init__.pyPKSFA?ܜF'dIPython/external/path/_path/__init__.pyPKSFГ'eIPython/external/decorators/__init__.pyPKSF*r<fIPython/external/decorators/_numpy_testing_utils/__init__.pyPKSF3gIPython/external/decorators/_decorators/__init__.pyPKSF&dhIPython/external/decorator/__init__.pyPKSFȼfޘ1=iIPython/external/decorator/_decorator/__init__.pyPKSFe)*$jIPython/external/qt_for_kernel/__init__.pyPKSF_;۟'$+kIPython/external/pexpect/__init__.pyPKSF% F- lIPython/external/pexpect/_pexpect/__init__.pyPKSFQg&q%mIPython/external/argparse/__init__.pyPKSFL4/nIPython/external/argparse/_argparse/__init__.pyPKSF{*pIPython/external/simplegeneric/__init__.pyPKSFN1x9qIPython/external/simplegeneric/_simplegeneric/__init__.pyPKSFQFd^rIPython/consoleapp/__init__.pyPKSF6uIPython/nbformat/__init__.pyPKSFlaFVvIPython/nbformat/v3/__init__.pyPKSFNZ-r&wIPython/nbformat/v3/nbbase/__init__.pyPKSF$m&xIPython/nbformat/v3/nbjson/__init__.pyPKSFG$+zIPython/nbformat/v3/nbpy/__init__.pyPKSF&@{IPython/nbformat/v3/rwbase/__init__.pyPKSFgDd6H%b|IPython/nbformat/v3/tests/__init__.pyPKSF1/|IPython/nbformat/v3/tests/test_nbpy/__init__.pyPKSFk+/~IPython/nbformat/v3/tests/test_json/__init__.pyPKSFD61IPython/nbformat/v3/tests/test_nbbase/__init__.pyPKSF(pr]0\IPython/nbformat/v3/tests/formattest/__init__.pyPKSFR0IPython/nbformat/v3/tests/nbexamples/__init__.pyPKSFvz)IPython/nbformat/v3/validator/__init__.pyPKSF"\:' IPython/nbformat/v3/convert/__init__.pyPKSFgDd6H"IPython/nbformat/tests/__init__.pyPKSF]fL$qIPython/nbformat/current/__init__.pyPKSF"^zIPython/nbformat/v1/__init__.pyPKSFn+&/IPython/nbformat/v1/nbbase/__init__.pyPKSF6.&IPython/nbformat/v1/nbjson/__init__.pyPKSFfEp&IPython/nbformat/v1/rwbase/__init__.pyPKSFgDd6H%IPython/nbformat/v1/tests/__init__.pyPKSF'G j/IPython/nbformat/v1/tests/test_json/__init__.pyPKSFV261IPython/nbformat/v1/tests/test_nbbase/__init__.pyPKSFr~0#IPython/nbformat/v1/tests/nbexamples/__init__.pyPKSFiRj'IPython/nbformat/v1/convert/__init__.pyPKSF}H$IPython/nbformat/v2/__init__.pyPKSF# 矮& IPython/nbformat/v2/nbbase/__init__.pyPKSFP$&IPython/nbformat/v2/nbjson/__init__.pyPKSF׹%IPython/nbformat/v2/nbxml/__init__.pyPKSF$8 $5IPython/nbformat/v2/nbpy/__init__.pyPKSFϭ&0IPython/nbformat/v2/rwbase/__init__.pyPKSFgDd6H%IPython/nbformat/v2/tests/__init__.pyPKSF-Q/IPython/nbformat/v2/tests/test_nbpy/__init__.pyPKSFS,|/5IPython/nbformat/v2/tests/test_json/__init__.pyPKSF$10IPython/nbformat/v2/tests/test_nbbase/__init__.pyPKSFJ0nIPython/nbformat/v2/tests/nbexamples/__init__.pyPKSFw'IPython/nbformat/v2/convert/__init__.pyPKSF#yYIPython/nbconvert/__init__.pyPKSFȸF.'vIPython/nbconvert/exporters/__init__.pyPKSFM<0IPython/nbconvert/exporters/markdown/__init__.pyPKSF5-U.IPython/nbconvert/exporters/slides/__init__.pyPKSF#hNy0ɢIPython/nbconvert/exporters/exporter/__init__.pyPKSFgDd6H-IPython/nbconvert/exporters/tests/__init__.pyPKSF;IPython/nbconvert/exporters/tests/test_exporter/__init__.pyPKSF0yY4IPython/nbconvert/exporters/tests/cheese/__init__.pyPKSFƵuBQ2<IPython/nbconvert/exporters/tests/base/__init__.pyPKSF<쒦x;*IPython/nbconvert/exporters/tests/test_markdown/__init__.pyPKSFDH9)IPython/nbconvert/exporters/tests/test_export/__init__.pyPKSF t9IPython/nbconvert/exporters/tests/test_python/__init__.pyPKSF -IPython/nbconvert/exporters/latex/__init__.pyPKSFcB+IPython/nbconvert/exporters/rst/__init__.pyPKSF fVD.IPython/nbconvert/exporters/export/__init__.pyPKSF3,IPython/nbconvert/exporters/html/__init__.pyPKSFP!.IPython/nbconvert/exporters/python/__init__.pyPKSF͞R#L*̰IPython/nbconvert/transformers/__init__.pyPKSF٨J/`IPython/nbconvert/transformers/base/__init__.pyPKSF=895IPython/nbconvert/transformers/convertfigures/__init__.pyPKSF 5IPython/nbconvert/transformers/revealhelp/__init__.pyPKSFl}m2IPython/nbconvert/transformers/svg2pdf/__init__.pyPKSFKY:AIPython/nbconvert/transformers/coalescestreams/__init__.pyPKSF"e 0IPython/nbconvert/transformers/latex/__init__.pyPKSF]d8ܷIPython/nbconvert/transformers/extractoutput/__init__.pyPKSF~$v =1IPython/nbconvert/transformers/sphinx/__init__.pyPKSF= 8[IPython/nbconvert/transformers/csshtmlheader/__init__.pyPKSFnOZ?%IPython/nbconvert/filters/__init__.pyPKSF#̑q.-IPython/nbconvert/filters/markdown/__init__.pyPKSFF#*IPython/nbconvert/filters/ansi/__init__.pyPKSFrnf4þIPython/nbconvert/filters/datatypefilter/__init__.pyPKSFgDd6H+{IPython/nbconvert/filters/tests/__init__.pyPKSFmͭn6IPython/nbconvert/filters/tests/test_latex/__init__.pyPKSFos:IPython/nbconvert/filters/tests/test_highlight/__init__.pyPKSFjsf8IPython/nbconvert/filters/tests/test_strings/__init__.pyPKSFJk?eIPython/nbconvert/filters/tests/test_datatypefilter/__init__.pyPKSF;cxA5`IPython/nbconvert/filters/tests/test_ansi/__init__.pyPKSFZ7Eq++IPython/nbconvert/filters/latex/__init__.pyPKSF-IPython/nbconvert/filters/strings/__init__.pyPKSF/6IPython/nbconvert/filters/highlight/__init__.pyPKSF+n#lIPython/nbconvert/tests/__init__.pyPKSF:<(IPython/nbconvert/tests/base/__init__.pyPKSFۯ%rIPython/nbconvert/writers/__init__.pyPKSF~x*dIPython/nbconvert/writers/base/__init__.pyPKSF [,$IPython/nbconvert/writers/stdout/__init__.pyPKSFi"+IPython/nbconvert/writers/files/__init__.pyPKSFGc+IPython/nbconvert/writers/debug/__init__.pyPKSF kФ#aIPython/nbconvert/utils/__init__.pyPKSFV-(FIPython/nbconvert/utils/base/__init__.pyPKSFx[Xq. IPython/nbconvert/utils/exceptions/__init__.pyPKSF%)_+IPython/nbconvert/utils/console/__init__.pyPKSF+*WIPython/nbconvert/utils/lexers/__init__.pyPKSF*GIPython/nbconvert/utils/pandoc/__init__.pyPKSFm *IPython/nbconvert/nbconvertapp/__init__.pyPKSF-=IPython/nbconvert/post_processors/__init__.pyPKSF|`2=IPython/nbconvert/post_processors/base/__init__.pyPKSFB\k}3IPython/nbconvert/post_processors/serve/__init__.pyPKSFunU׵1IPython/nbconvert/post_processors/pdf/__init__.pyPKSFS`IPython/config/__init__.pyPKSFg&5IPython/config/application/__init__.pyPKSFgDd6H IPython/config/tests/__init__.pyPKSF2IPython/config/tests/test_configurable/__init__.pyPKSFq'c1eIPython/config/tests/test_application/__init__.pyPKSF!'IPython/config/configurable/__init__.pyPKSFgDd6H"IPython/config/profile/__init__.pyPKSFTN!YIPython/config/loader/__init__.pyPKSFgDd6HIPython/extensions/__init__.pyPKSFl>Xx,XIPython/extensions/parallelmagic/__init__.pyPKSFgDd6H$IPython/extensions/tests/__init__.pyPKSFvȌ(,rIPython/extensions/sympyprinting/__init__.pyPKSF%4L$)HIPython/extensions/autoreload/__init__.pyPKSFm)IPython/extensions/storemagic/__init__.pyPKSF)`*IPython/extensions/cythonmagic/__init__.pyPKSFGl IPython/utils/__init__.pyPKSFlO3$IPython/utils/pickleutil/__init__.pyPKSF[ZƊTsFIPython/utils/dir2/__init__.pyPKSFk!IPython/utils/tempdir/__init__.pyPKSF7"IPython/utils/wildcard/__init__.pyPKSFQz#lIPython/utils/daemonize/__init__.pyPKSFxݰ!IPython/utils/process/__init__.pyPKSFNO'IPython/utils/_tokenize_py2/__init__.pyPKSFww2 IPython/utils/openpy/__init__.pyPKSF(:{X(KIPython/utils/nested_context/__init__.pyPKSF\v"IPython/utils/ipstruct/__init__.pyPKSFzE7IPython/utils/io/__init__.pyPKSFdZ'IPython/utils/doctestreload/__init__.pyPKSFَ#&IPython/utils/submodule/__init__.pyPKSF̱c%"IPython/utils/encoding/__init__.pyPKSFc!IPython/utils/sysinfo/__init__.pyPKSFOWH{IPython/utils/path/__init__.pyPKSFb IPython/utils/timing/__init__.pyPKSFp8b)SIPython/utils/_process_common/__init__.pyPKSFgDd6HNIPython/utils/tests/__init__.pyPKSFf?ԨI1IPython/utils/tests/test_module_paths/__init__.pyPKSFّ\,YIPython/utils/tests/test_tempdir/__init__.pyPKSF9|-4 IPython/utils/tests/test_wildcard/__init__.pyPKSFL-,e IPython/utils/tests/test_imports/__init__.pyPKSF d(0 IPython/utils/syspathcontext/__init__.pyPKSF,<q" IPython/utils/generics/__init__.pyPKSFDpR]$ IPython/utils/zmqrelated/__init__.pyPKSFt4V* IPython/utils/data/__init__.pyPKSFiX # IPython/utils/traitlets/__init__.pyPKSFRE-JZ"IPython/utils/_sysinfo/__init__.pyPKSFlG#IPython/utils/tokenize2/__init__.pyPKSF,zQ^!HIPython/utils/version/__init__.pyPKSFYg="IPython/utils/tz/__init__.pyPKSFmOm$IPython/utils/decorators/__init__.pyPKSFiXl3%=IPython/utils/pickleshare/__init__.pyPKSF|k%6IPython/utils/strdispatch/__init__.pyPKSFf)IPython/utils/localinterfaces/__init__.pyPKSFIPython/parallel/engine/__init__.pyPKSF*>IPython/parallel/engine/engine/__init__.pyPKSFfz#@IPython/parallel/client/__init__.pyPKSF0X *AIPython/parallel/client/client/__init__.pyPKSFh$..'+EIPython/parallel/client/map/__init__.pyPKSFC*FIPython/parallel/client/magics/__init__.pyPKSF&(cGIPython/parallel/client/view/__init__.pyPKSF'Ev/sIIPython/parallel/client/asyncresult/__init__.pyPKSF+yk2JIPython/parallel/client/remotefunction/__init__.pyPKSFPd$KIPython/parallel/factory/__init__.pyPKSFgDd6H$MIPython/parallel/scripts/__init__.pyPKSFʖ "NIPython/parallel/tests/__init__.pyPKSF:"AOIPython/parallel/error/__init__.pyPKSF='zPIPython/parallel/controller/__init__.pyPKSFg0lQIPython/parallel/controller/sqlitedb/__init__.pyPKSFs/RIPython/parallel/controller/mongodb/__init__.pyPKSF׀2SIPython/parallel/controller/dependency/__init__.pyPKSF`>W11UIPython/parallel/controller/scheduler/__init__.pyPKSFJ{d.=WIPython/parallel/controller/dictdb/__init__.pyPKSF\4vXIPython/parallel/controller/heartmonitor/__init__.pyPKSF_ H+YIPython/parallel/controller/hub/__init__.pyPKSFYsC![IPython/parallel/apps/__init__.pyPKSFJaM+\IPython/parallel/apps/winhpcjob/__init__.pyPKSFl$ *^IPython/parallel/apps/launcher/__init__.pyPKSFp -aIPython/parallel/apps/ipengineapp/__init__.pyPKSF@4-eIPython/parallel/apps/iploggerapp/__init__.pyPKSFp񾱇.hIPython/parallel/apps/win32support/__init__.pyPKSF'BJ.hIPython/parallel/apps/ipclusterapp/__init__.pyPKSF Ue )nIPython/parallel/apps/baseapp/__init__.pyPKSFjbbg,rIPython/parallel/apps/logwatcher/__init__.pyPKSF{F 1sIPython/parallel/apps/ipcontrollerapp/__init__.pyPKSFnp!wIPython/parallel/util/__init__.pyPKSFgDd6HtyIPython/sphinxext/__init__.pyPKSF[V~n:yIPython/sphinxext/ipython_console_highlighting/__init__.pyPKSF}wj/{IPython/sphinxext/ipython_directive/__init__.pyPKSF UY|IPython/lib/__init__.pyPKSF{}IPython/lib/kernel/__init__.pyPKSF[Y%~IPython/lib/inputhookglut/__init__.pyPKSFN{cEIPython/lib/irunner/__init__.pyPKSFA^3"-IPython/lib/latextools/__init__.pyPKSFtx$˃IPython/lib/inputhookqt4/__init__.pyPKSFҐ^ՄIPython/lib/demo/__init__.pyPKSFat:#IPython/lib/editorhooks/__init__.pyPKSF[#׆IPython/lib/inputhookwx/__init__.pyPKSFEʉ`$IPython/lib/inputhookgtk/__init__.pyPKSFL1JPIPython/lib/display/__init__.pyPKSFOf!IPython/lib/inputhook/__init__.pyPKSFgDd6HcIPython/lib/tests/__init__.pyPKSF*ԋIPython/lib/tests/test_irunner/__init__.pyPKSF>Okf IPython/lib/security/__init__.pyPKSFk9s"ݍIPython/lib/deepreload/__init__.pyPKSFmr"IPython/lib/guisupport/__init__.pyPKSFBaIPython/lib/pretty/__init__.pyPKSF ی&&IPython/lib/backgroundjobs/__init__.pyPKSF{yD!IPython/lib/clipboard/__init__.pyPKSF??+lIPython/terminal/__init__.pyPKSF3e&-2IPython/terminal/interactiveshell/__init__.pyPKSFgDd6H"IPython/terminal/tests/__init__.pyPKSF=u"&IPython/terminal/ipapp/__init__.pyPKSFgDd6H$XIPython/terminal/console/__init__.pyPKSFDž85ЭIPython/terminal/console/interactiveshell/__init__.pyPKSFgDd6H*IPython/terminal/console/tests/__init__.pyPKSFgDd6H6&IPython/terminal/console/tests/writetofile/__init__.pyPKSF!Vk\=.IPython/terminal/console/completer/__init__.pyPKSFw /(IPython/terminal/console/app/__init__.pyPKSFWQ"йIPython/terminal/embed/__init__.pyPKSF0ɄaIPython/html/__init__.pyPKSF^knIPython/html/base/__init__.pyPKSF )ļIPython/html/base/zmqhandlers/__init__.pyPKSFG! &ĽIPython/html/base/handlers/__init__.pyPKSFgDd6HIPython/html/tests/__init__.pyPKSFgDd6H!IPython/html/notebook/__init__.pyPKSFTD^*IPython/html/notebook/handlers/__init__.pyPKSFd $IPython/html/notebookapp/__init__.pyPKSFK_9IPython/html/utils/__init__.pyPKSF̦ 4!IPython/html/services/__init__.pyPKSF k +IPython/html/services/notebooks/__init__.pyPKSFm5YIPython/html/services/notebooks/nbmanager/__init__.pyPKSF-e9IPython/html/services/notebooks/filenbmanager/__init__.pyPKSFgDd6H1IPython/html/services/notebooks/tests/__init__.pyPKSFz@IPython/html/services/notebooks/tests/test_nbmanager/__init__.pyPKSFֹ4IPython/html/services/notebooks/handlers/__init__.pyPKSFl={*IPython/html/services/clusters/__init__.pyPKSFiDϏYo9IPython/html/services/clusters/clustermanager/__init__.pyPKSFZ3LIPython/html/services/clusters/handlers/__init__.pyPKSFȶ^z)[IPython/html/services/kernels/__init__.pyPKSFh7IPython/html/services/kernels/kernelmanager/__init__.pyPKSFAc-2IPython/html/services/kernels/handlers/__init__.pyPKSFgDd6HIPython/html/tree/__init__.pyPKSF8}&IPython/html/tree/handlers/__init__.pyPKSFgDd6HIPython/html/auth/__init__.pyPKSFԇ#9IPython/html/auth/login/__init__.pyPKSFJ1p$IPython/html/auth/logout/__init__.pyPKSF{[qfIPython/qt/__init__.pyPKSF?Wo*MIPython/qt/base_frontend_mixin/__init__.pyPKSFgDd6HIPython/qt/console/__init__.pyPKSFgDd6H$^IPython/qt/console/tests/__init__.pyPKSFPs?:IPython/qt/console/tests/test_completion_lexer/__init__.pyPKSFo/CIPython/qt/console/completion_lexer/__init__.pyPKSFj %IPython/qt/console/styles/__init__.pyPKSF8nJ]lxml/__init__.pyPKSF lxml/builder/__init__.pyPKSF=bgHlxml/isoschematron/__init__.pyPKSFq!3lxml/objectify/__init__.pyPKSF =lxml/_elementpath/__init__.pyPKSF>\lxml/sax/__init__.pyPKSFK{%qlxml/etree/__init__.pyPKSFaCZ\v lxml/pyclasslookup/__init__.pyPKSFgDd6Hlxml/includes/__init__.pyPKSF.լlxml/html/__init__.pyPKSF{lxml/html/builder/__init__.pyPKSF8lxml/html/clean/__init__.pyPKSFu  lxml/html/formfill/__init__.pyPKSFU lxml/html/defs/__init__.pyPKSFVPf lxml/html/_setmixin/__init__.pyPKSFJ*7 lxml/html/diff/__init__.pyPKSFa:"lxml/html/_diffcommand/__init__.pyPKSFc'lxml/doctestcompare/__init__.pyPKSFm /J lxml/ElementInclude/__init__.pyPK`SF@T?PyMca/__init__.pyPKSFʌ,"PyMca/AttenuatorsTable/__init__.pyPKSF @9PyMca/Object3D/Scene/__init__.pyPKdSFN6/(*:PyMca/Object3D/SceneGLWidget/__init__.pyPKdSF4.Z.<PyMca/Object3D/Object3DRedBookFont/__init__.pyPKdSFg(0=PyMca/Object3D/Object3DPrivateConfig/__init__.pyPKdSF{>q/?PyMca/Object3D/Object3DPrintPreview/__init__.pyPKdSF{(x'BPyMca/Object3D/Object3DDirs/__init__.pyPKdSFA)HCPyMca/Object3D/VerticalSpacer/__init__.pyPKdSF2j)o%DPyMca/Object3D/Object3DQt/__init__.pyPKdSFJ ;Rh%PyMca/Object3D/ObjectTree/__init__.pyPKdSF>/~aG+PyMca/Object3D/SceneCoordinates/__init__.pyPKdSF1u=c (2PyMca/Object3D/SceneGLWindow/__init__.pyPKdSF#?.PyMca/Object3D/Object3DFileDialogs/__init__.pyPKdSFq.PyMca/Object3D/Object3DCoordinates/__init__.pyPKdSF{` w(TPyMca/Object3D/Object3DScene/__init__.pyPKdSFv@55PyMca/Object3D/ClippingPlaneConfiguration/__init__.pyPKdSF?NQ)MPyMca/Object3D/Object3DConfig/__init__.pyPKdSFտƂP6- PyMca/Object3D/Object3DProperties/__init__.pyPKdSFx.} PyMca/Object3D/GLWidgetCachePixmap/__init__.pyPKdSFSo*h PyMca/Object3D/Object3DPlugins/__init__.pyPKdSFMU7D PyMca/Object3D/Object3DPlugins/ChimeraStack/__init__.pyPKdSF%kUC7kPyMca/Object3D/Object3DPlugins/Object3DMesh/__init__.pyPKdSFOK=PyMca/Object3D/Object3DPlugins/Object3DMeshConfig/__init__.pyPKdSFL-9PyMca/Object3D/Object3DPlugins/Object3DPixmap/__init__.pyPKdSFk?0A8-PyMca/Object3D/Object3DPlugins/Object3DStack/__init__.pyPKdSF2i(PyMca/Object3D/Object3DQhull/__init__.pyPKdSFε$j+bPyMca/Object3D/HorizontalSpacer/__init__.pyPKSFO1PyMca/SimpleFitUserEstimatedFunctions/__init__.pyPKSFSZ&PyMca/IncoherentScattering/__init__.pyPKeSF#kPyMca/PyMcaIO/__init__.pyPKeSFR3]&"PyMca/PyMcaIO/EDFStack/__init__.pyPKeSF %'p PyMca/PyMcaIO/MarCCD/__init__.pyPKeSFL#PyMca/PyMcaIO/AifiraMap/__init__.pyPKeSFJt<#PyMca/PyMcaIO/ArraySave/__init__.pyPKeSFg+PyMca/PyMcaIO/BAXSCSVFileParser/__init__.pyPKeSFMff$!PyMca/PyMcaIO/OpusDPTMap/__init__.pyPKeSFo#."PyMca/PyMcaIO/TiffStack/__init__.pyPKeSF5"}/Y#PyMca/PyMcaIO/SpecFileAbstractClass/__init__.pyPKeSFwi$#$PyMca/PyMcaIO/PilatusCBF/__init__.pyPKeSFG**%PyMca/PyMcaIO/APSMEDFileParser/__init__.pyPKeSF$Ͳ=f (&PyMca/PyMcaIO/TiffIO/__init__.pyPKeSF')QO''PyMca/PyMcaIO/SPXFileParser/__init__.pyPKeSF %"(PyMca/PyMcaIO/OmnicMap/__init__.pyPKeSF =i !)PyMca/PyMcaIO/spswrap/__init__.pyPKeSF\qA!+PyMca/PyMcaIO/MEDFile/__init__.pyPKeSF)z&i,PyMca/PyMcaIO/SupaVisioMap/__init__.pyPKeSFD?p(-PyMca/PyMcaIO/TextImageStack/__init__.pyPKeSFH1k .PyMca/PyMcaIO/MRCMap/__init__.pyPKeSFa(3,/PyMca/PyMcaIO/Fit2DChiFileParser/__init__.pyPKeSF:m'!0PyMca/PyMcaIO/EdfFile/__init__.pyPKeSFLMc3=)2PyMca/PyMcaIO/specfilewrapper/__init__.pyPKeSF"3PyMca/PyMcaIO/LuciaMap/__init__.pyPKeSFEu'5PyMca/PyMcaIO/SRSFileParser/__init__.pyPKSFO 6PyMca/EnergyTable/__init__.pyPKSFFI]n9PyMca/McaROIWidget/__init__.pyPKSF$z%#=PyMca/CalculationThread/__init__.pyPKSFÓ %>PyMca/PyMcaMatplotlibSave/__init__.pyPKSFU18 @PyMca/Plot1DQwt/__init__.pyPKSF8;Y\APyMca/KShell/__init__.pyPKSF1-(BPyMca/QPyMcaMatplotlibSave1D/__init__.pyPKSFRGPyMca/QwtPlotItems/__init__.pyPKSFRUHPyMca/SpecFileLayer/__init__.pyPKSFv mIPyMca/McaCustomEvent/__init__.pyPKSFg2kkNPyMca/SNIPModule/__init__.pyPKSFIUN`OPyMca/SNIPWindow/__init__.pyPKSFZiQPyMca/Parameters/__init__.pyPKSF<^,UPyMca/McaWindow/__init__.pyPKSFG\"C.  XPyMca/Elements/__init__.pyPKSF'X:.[PyMca/PyMcaEPDL97/__init__.pyPKSF(\n[!\PyMca/PyMcaBatch/__init__.pyPKSFԜ`m *_PyMca/XASSelfAttenuationWindow/__init__.pyPKSFIaPyMca/FitStatusGUI/__init__.pyPKSFnN +8cPyMca/CloseEventNotifyingWidget/__init__.pyPKSF0ԋWhPyMca/Specfit/__init__.pyPKSF,M>liPyMca/FrameBrowser/__init__.pyPKSFmo 8kPyMca/MaterialEditor/__init__.pyPKSFVti"mPyMca/SpecFileMcaTable/__init__.pyPKSF{;nPyMca/PyMca_Icons/__init__.pyPKSFE7VpPyMca/SGWindow/__init__.pyPKSF = #/rPyMca/ImageRegistration/__init__.pyPKSFQ.*"jsPyMca/Plot1DWindowBase/__init__.pyPKSF!+(tPyMca/SimpleFitControlWidget/__init__.pyPKSFϬ*IvPyMca/Gefit/__init__.pyPKSF:XfjwPyMca/StackBase/__init__.pyPKSFs"xPyMca/PyMcaMdi/__init__.pyPKSFs&zPyMca/TextField/__init__.pyPKSF j{PyMca/QXTube/__init__.pyPKSFPM@~PyMca/SpecfitGUI/__init__.pyPKSF-$PyMca/SpecFileDataSource/__init__.pyPKSF{J!DPyMca/SimpleFitModule/__init__.pyPKSF6 "1PyMca/PyMcaNexusWidget/__init__.pyPKSF=^(PyMca/FastXRFLinearFitWindow/__init__.pyPKSFz8)PyMca/PyMcaDataDir/__init__.pyPKSFEPyMca/DataObject/__init__.pyPKSFa~cD PyMca/QEdfFileWidget/__init__.pyPKSF1 n{*PyMca/QStackWidget/__init__.pyPKSFsc ԌPyMca/QtBlissGraph/__init__.pyPKSF}ѪPyMca/XMCDWindow/__init__.pyPKSFma)_PyMca/StackSelector/__init__.pyPKSFD`:%PyMca/RGBCorrelator/__init__.pyPKSF!~t PyMca/PCADialog/__init__.pyPKSFۨkʠPyMca/PyMca_help/__init__.pyPKSF X'PyMca/StripBackgroundWidget/__init__.pyPKSFRz" @PyMca/QDataSource/__init__.pyPKSF\p/K%PyMca/EdfFileSimpleViewer/__init__.pyPKSFC4+PyMca/MShell/__init__.pyPKSFUU^w9&PyMca/Fit2Spec/__init__.pyPKSFN6"ժPyMca/SpecFileCntTable/__init__.pyPKSFX PyMca/StackROIWindow/__init__.pyPKSFn0lPyMca/SPSLayer/__init__.pyPKSFykx&\PyMca/ConcentrationsWidget/__init__.pyPKSF &y %PyMca/NumpyArrayTableView/__init__.pyPKdSF ƄPyMca/tests/__init__.pyPKdSFюDzI#PyMca/tests/EdfFileTest/__init__.pyPKdSFC _PyMca/tests/TestAll/__init__.pyPKdSFMgX.%CPyMca/tests/StackBaseTest/__init__.pyPKdSFҬ$ PyMca/tests/PCAToolsTest/__init__.pyPKdSFo6'"$PyMca/tests/ElementsTest/__init__.pyPKdSF)+Q@+PyMca/tests/specfilewrapperTest/__init__.pyPKdSFc!PyMca/tests/GefitTest/__init__.pyPKdSF9$PyMca/tests/SpecfileTest/__init__.pyPKdSFKd~;&PyMca/tests/ConfigDictTest/__init__.pyPKSF^1PyMca/Plot1D/__init__.pyPKSF,%-. "xPyMca/McaAdvancedTable/__init__.pyPKSFh!PyMca/FitActionsGUI/__init__.pyPKSFt7PyMca/McaCalWidget/__init__.pyPKSF! & %{PyMca/RGBCorrelatorWidget/__init__.pyPKSFԮ-%PyMca/PyMcaHKLImageWindow/__init__.pyPKSFxq+PyMca/NNMADialog/__init__.pyPKSF/!ɬPyMca/HDF5Info/__init__.pyPKSF,+PyMca/SimpleFitConfigurationGUI/__init__.pyPKSFف@PyMca/StackBrowser/__init__.pyPKSF\;2"PyMca/SpecfitFunctions/__init__.pyPKSF"bW PyMca/PyMcaPostBatch/__init__.pyPKSFmm"vPyMca/PyMcaImageWindow/__init__.pyPKSF$T)L#PyMca/PyMcaMain/__init__.pyPKSF~}>d!PyMca/Median2DBrowser/__init__.pyPKSFUoPyMca/linalg/__init__.pyPKSFZ'!PyMca/BindingEnergies/__init__.pyPKSF,%-. PyMca/McaTable/__init__.pyPKSF_<PyMca/CheckField/__init__.pyPKdSFgDd6HPyMca/PyMcaPlugins/__init__.pyPKdSFt*PyMca/PyMcaPlugins/MathPlugins/__init__.pyPKdSF$z%0 PyMca/PyMcaPlugins/CalculationThread/__init__.pyPKdSFͧ6LPyMca/PyMcaPlugins/MedianFilterStackPlugin/__init__.pyPKdSFE0PyMca/PyMcaPlugins/RegularMeshPlugin/__init__.pyPKdSFKz57PyMca/PyMcaPlugins/XASSelfAttenuationPlugin/__init__.pyPKdSFxukl5PyMca/PyMcaPlugins/MedianFilterScanPlugin/__init__.pyPKdSF_*1PyMca/PyMcaPlugins/ReverseStackPlugin/__init__.pyPKdSFܶL8PyMca/PyMcaPlugins/ExternalImagesStackPlugin/__init__.pyPKdSF1<t=vPyMca/PyMcaPlugins/MedianFilterScanDeglitchPlugin/__init__.pyPKdSF .PyMca/PyMcaPlugins/StackAxesPlugin/__init__.pyPKdSF.fÒ4PyMca/PyMcaPlugins/BackgroundStackPlugin/__init__.pyPKdSFQ3PyMca/PyMcaPlugins/BackgroundScanPlugin/__init__.pyPKdSF2b.HPyMca/PyMcaPlugins/MotorInfoWindow/__init__.pyPKdSFT-#PyMca/PyMcaPlugins/FitStackPlugin/__init__.pyPKdSFyJ-?PyMca/PyMcaPlugins/PCAStackPlugin/__init__.pyPKdSFjTR. PyMca/PyMcaPlugins/MotorInfoPlugin/__init__.pyPKdSF# :PyMca/PyMcaPlugins/XASStackNormalizationPlugin/__init__.pyPKdSFEL-}PyMca/PyMcaPlugins/ROIStackPlugin/__init__.pyPKdSF>#3PyMca/PyMcaPlugins/NormalizationPlugins/__init__.pyPKdSFһO2PyMca/PyMcaPlugins/AlignmentScanPlugin/__init__.pyPKdSF.PyMca/PyMcaPlugins/StackPluginBase/__init__.pyPKdSFjJص&7 PyMca/PyMcaPlugins/StackNormalizationPlugin/__init__.pyPKdSF˳+1 PyMca/PyMcaPlugins/StackBrowserPlugin/__init__.pyPKdSF6n9 PyMca/PyMcaPlugins/XASScanNormalizationPlugin/__init__.pyPKdSF\F: PyMca/PyMcaPlugins/AdvancedAlignmentScanPlugin/__init__.pyPKdSF>)_PyMca/PyMcaPlugins/XMCDPlugin/__init__.pyPKdSF +PyMca/PyMcaPlugins/Plugin1DBase/__init__.pyPKdSFp:=rG8\PyMca/PyMcaPlugins/ImageAlignmentStackPlugin/__init__.pyPKdSFw-.$PyMca/PyMcaPlugins/NNMAStackPlugin/__init__.pyPKdSF'Um4PyMca/PyMcaPlugins/StackScanWindowPlugin/__init__.pyPKdSFA:PyMca/PyMcaPlugins/FastXRFLinearFitStackPlugin/__init__.pyPKdSFl7PyMca/PyMcaPlugins/MultipleScanToMeshPlugin/__init__.pyPKSF\TqPyMca/ScanWindow/__init__.pyPKSFiswxjPyMca/ElementHtml/__init__.pyPKSF>PyMca/EntryField/__init__.pyPKSF !qPyMca/QEDFStackWidget/__init__.pyPKSF/ =!PyMca/ColormapDialog/__init__.pyPKSFuxz #PyMca/PhysicalMemory/__init__.pyPKSFgmq-H$PyMca/TabSheets/__init__.pyPKSF U%PyMca/QNexusWidget/__init__.pyPKSF:'PyMca/XRayTubeEbel/__init__.pyPKSF/U!(PyMca/MultiParameters/__init__.pyPKSF =#:*PyMca/RenameCurveDialog/__init__.pyPKSF@(|+PyMca/QtMcaAdvancedFitReport/__init__.pyPKSF<&lZ-PyMca/SpsDataSource/__init__.pyPKSFlFU.PyMca/MatrixEditor/__init__.pyPKSF=ׇ/PyMca/DoubleSlider/__init__.pyPKSFj^0PyMca/HDF5Widget/__init__.pyPKSFotg' "5PyMca/XiaCorrectWizard/__init__.pyPKSFC*]8PyMca/StackPluginResultsWindow/__init__.pyPKSFyWO>&f:PyMca/ScanWindowInfoWidget/__init__.pyPKSFR<#;PyMca/PCAWindow/__init__.pyPKSFզs=PyMca/SixCircle/__init__.pyPKSFq./c>PyMca/Plot1DWindow/__init__.pyPKSFo(?PyMca/XASNormalizationWindow/__init__.pyPKSFo[/gAPyMca/PyMcaSciPy/__init__.pyPKSFE y'#BPyMca/PyMcaSciPy/signal/__init__.pyPKSF c?*pCPyMca/PyMcaSciPy/signal/median/__init__.pyPKSF;mI\/DDPyMca/PyMcaSciPy/signal/mediantools/__init__.pyPKSF3#DPyMca/PyMcaPrintPreview/__init__.pyPKSF#NFPyMca/EdfFileDataSource/__init__.pyPKSFޣR)'VGPyMca/NumpyArrayTableWidget/__init__.pyPKSF "HPyMca/SpecFileDataInfo/__init__.pyPKSF&!!OPyMca/PeakTableWidget/__init__.pyPKSF#j9f Z TPyMca/ClassMcaTheory/__init__.pyPKSF{A1&PUPyMca/ExternalImagesWindow/__init__.pyPKSFW.]WPyMca/HDF5Selection/__init__.pyPKSF'cXPyMca/Scofield1973/__init__.pyPKSFmPYPyMca/MatrixImage/__init__.pyPKSF!ZPyMca/HDF5Stack1D/__init__.pyPKSF_Xo4\PyMca/PyMcaGLWindow/__init__.pyPKSFt ]PyMca/QSource/__init__.pyPKSFz"|bPyMca/EventHandler/__init__.pyPKSF# QcPyMca/FitPeakSelect/__init__.pyPKSFÂH2j$ePyMca/ConcentrationsTool/__init__.pyPKSF"Y'_fPyMca/specfile/__init__.pyPKSF%)gPyMca/QHDF5Stack1D/__init__.pyPKSFgdAhPyMca/ChangeLog/__init__.pyPKSF!iPyMca/StackPluginBase/__init__.pyPKSFZ^=#SjPyMca/ProfileScanWidget/__init__.pyPKSF ag"kPyMca/XASNormalization/__init__.pyPKSFɥL &lPyMca/QPyMcaMatplotlibSave/__init__.pyPKSF*oPyMca/FitConfigGUI/__init__.pyPKeSF W9+AqPyMca/XRFMC/__init__.pyPKeSFWd"qPyMca/XRFMC/XRFMCPyMca/__init__.pyPKeSF/~"tPyMca/XRFMC/XMSOParser/__init__.pyPKeSFGj#tPyMca/XRFMC/XRFMCHelper/__init__.pyPKSF~}vPyMca/Lanczos/__init__.pyPKSF|uwPyMca/QScriptOption/__init__.pyPKSFC`e3gyPyMca/PyMcaQt/__init__.pyPKSFz1PyMca/NNMAModule/__init__.pyPKSFfx?<p2PyMca/Plot1DBase/__init__.pyPKeSFë֠M|3PyMca/EPDL97/__init__.pyPKSFA]Li8R4PyMca/EPDL97/GenerateEADLShellRadiativeRates/__init__.pyPKSF]f&6PyMca/EPDL97/EADLSubshells/__init__.pyPKSFѩQC;6PyMca/EPDL97/GenerateEADLShellNonradiativeRates/__init__.pyPKSF|0=%e8PyMca/EPDL97/EPDL97Parser/__init__.pyPKSFA-#:PyMca/EPDL97/EADLParser/__init__.pyPKSF M~L4<PyMca/EPDL97/GenerateEADLBindingEnergies/__init__.pyPKSF=3r?PyMca/EPDL97/GenerateEADLShellConstants/__init__.pyPKSF56G>n!HAPyMca/QSourceSelector/__init__.pyPKSF55%BPyMca/McaAdvancedFitBatch/__init__.pyPKSF flg =DPyMca/FitParam/__init__.pyPKSFd <.JGPyMca/XASSelfAttenuationCorrection/__init__.pyPKSFA"JHPyMca/HDF5CounterTable/__init__.pyPKSFoχ'UKPyMca/PyMcaBatchBuildOutput/__init__.pyPKSFe$5LPyMca/FFTAlignmentWindow/__init__.pyPKSF=MPyMca/McaControlGUI/__init__.pyPKSF{%"VPPyMca/FastXRFLinearFit/__init__.pyPKSF#oc&QPyMca/StackSimpleFitWindow/__init__.pyPKSFaZ2SPyMca/MySPSSelector/__init__.pyPKSF+m* TPyMca/XiaEdf/__init__.pyPKSF%fUPyMca/SpecFileStack/__init__.pyPKSFN%UWPyMca/SubprocessLogWidget/__init__.pyPKSF0:a XPyMca/QSpsDataSource/__init__.pyPKSFf%3$YPyMca/CoherentScattering/__init__.pyPKSFVψ[PyMca/HtmlIndex/__init__.pyPKSF_G[PyMca/ElementsInfo/__init__.pyPKSF`?`$]PyMca/RGBImageCalculator/__init__.pyPKSF͈ !_PyMca/MaskImageWidget/__init__.pyPKSF~\{cPyMca/FastEdf/__init__.pyPKSF$+-dPyMca/McaSimpleFit/__init__.pyPKSFzK~MePyMca/FitParamForm/__init__.pyPKSFtegPyMca/SGModule/__init__.pyPKSF;ɼ XhPyMca/StackSimpleFit/__init__.pyPKSFĘ `iPyMca/McaAdvancedFit/__init__.pyPKSF$ SmPyMca/spslut/__init__.pyPKSFi|Nk ,nPyMca/QPeriodicTable/__init__.pyPKSFKg!( PyMca/NexusDataSource/__init__.pyPKdSFʹV * PyMca/py_nnma/__init__.pyPKdSFWq+ PyMca/py_nnma/nnma/__init__.pyPKSF \- PyMca/Plugin1DBase/__init__.pyPKSF| Xu+. PyMca/PyMcaIOHelper/__init__.pyPKSFE')E. PyMca/ScanFit/__init__.pyPKSFpYm| 0 PyMca/PeakIdentifier/__init__.pyPKSF"1 PyMca/XiaCorrect/__init__.pyPKSFdC7_%2 PyMca/Q4PyMcaPrintPreview/__init__.pyPKSF H[`6 PyMca/PyMcaLogo/__init__.pyPKSF:"$6 PyMca/RGBCorrelatorTable/__init__.pyPKSF[2A9 PyMca/sps/__init__.pyPKSF"l&g"[; PyMca/HDF5DatasetTable/__init__.pyPKSF=S;< PyMca/PCAModule/__init__.pyPKSFEZ#= PyMca/SimpleFitBatchGUI/__init__.pyPKSFBˠ!~? PyMca/QSpecFileWidget/__init__.pyPKSFj_ ]A PyMca/SpecArithmetic/__init__.pyPKSF6)  "A PyMca/QHDF5StackWizard/__init__.pyPKSFv&D PyMca/NumpyArrayTableModel/__init__.pyPKSF1G PyMca/SimpleMath/__init__.pyPKSFnϩZG PyMca/QSpsWidget/__init__.pyPKSFSVKwK PyMca/NNMAWindow/__init__.pyPKSF:$6M PyMca/RGBCorrelatorGraph/__init__.pyPKSF=nfGO PyMca/SpecfitFuns/__init__.pyPKSF.eUKP PyMca/LShell/__init__.pyPKSFqʬz*R PyMca/PCATools/__init__.pyPKSFVBR PyMca/EdfFileLayer/__init__.pyPK`SF])׾8&S PyTango/__init__.pyPK`SF=(v[ PyTango/time_val/__init__.pyPK`SF##O\ PyTango/attribute_proxy/__init__.pyPK`SFw&Rw$w] PyTango/group_reply_list/__init__.pyPK`SFj50^ PyTango/ipython/__init__.pyPK`SF<):_ PyTango/ipython/ipython_10_00/__init__.pyPK`SFD27.` PyTango/ipython/ipython_10_00/ipython_10_00/__init__.pyPK`SFx5b PyTango/ipython/ipython_10_00/ipy_install/__init__.pyPK`SF v"d PyTango/ipython/common/__init__.pyPK`SFCi)d PyTango/ipython/ipython_00_11/__init__.pyPK`SFx5e PyTango/ipython/ipython_00_11/ipy_install/__init__.pyPK`SFD27f PyTango/ipython/ipython_00_11/ipython_00_11/__init__.pyPK`SFi'i PyTango/ipython/eventlogger/__init__.pyPK`SFaw$.j PyTango/device_attribute/__init__.pyPK`SFgj PyTango/client/__init__.pyPK`SF}TTwk PyTango/callback/__init__.pyPK`SFade7l PyTango/db/__init__.pyPK`SF=re ?m PyTango/device_class/__init__.pyPK`SF(n PyTango/constants/__init__.pyPK`SFJ>Fv PyTango/release/__init__.pyPK`SF<~2x PyTango/log4tango/__init__.pyPK`SFtGx PyTango/base_types/__init__.pyPK`SFNӛez PyTango/connection/__init__.pyPK`SF0  _{ PyTango/pytango_init/__init__.pyPK`SFU~| PyTango/api_util/__init__.pyPK`SF{S} PyTango/pyutil/__init__.pyPK`SFx&%@~ PyTango/encoded_attribute/__init__.pyPK`SF:bS!S PyTango/device_server/__init__.pyPK`SFG PyTango/globals/__init__.pyPK`SFWn PyTango/server/__init__.pyPK`SF)] PyTango/green/__init__.pyPK`SF3"O PyTango/pytango_pprint/__init__.pyPK`SF0#7% PyTango/attr_data/__init__.pyPK`SFEKGz% PyTango/group_reply/__init__.pyPK`SF^ ܇ PyTango/utils/__init__.pyPK`SF~=j' q PyTango/device_proxy/__init__.pyPK`SF`֋ PyTango/device_data/__init__.pyPK`SF8@q s PyTango/tango_gevent/__init__.pyPK`SFaa" PyTango/_PyTango/__init__.pyPK`SF<q PyTango/tango_numpy/__init__.pyPK`SF$}! PyTango/tango_futures/__init__.pyPK`SFfrt PyTango/exception/__init__.pyPK`SF@u:! PyTango/group/__init__.pyPK`SFFG PyTango/gevent/__init__.pyPKSFa} guiqwt/__init__.pyPKSFXn? guiqwt/annotations/__init__.pyPKSFG=H guiqwt/geometry/__init__.pyPKSF}k$n` guiqwt/events/__init__.pyPKSF>XUZo guiqwt/panels/__init__.pyPKSFP"?0: guiqwt/builder/__init__.pyPKSF}w guiqwt/scaler/__init__.pyPKSFYſ%_ guiqwt/pyplot/__init__.pyPKSF#HoU guiqwt/baseplot/__init__.pyPKSFbAJu guiqwt/io/__init__.pyPKSFgDd6H guiqwt/widgets/__init__.pyPKSFi-c ` guiqwt/widgets/base/__init__.pyPKSF9 e' guiqwt/widgets/resizedialog/__init__.pyPKSFŪ#P!gm6 guiqwt/widgets/fit/__init__.pyPKSF i%W guiqwt/widgets/fliprotate/__init__.pyPKSF'م%;Z guiqwt/widgets/rotatecrop/__init__.pyPKSF{=t%\ guiqwt/curve/__init__.pyPKSF(с guiqwt/interfaces/__init__.pyPKSFm݆$  guiqwt/cross_section/__init__.pyPKSFtM)AU guiqwt/tests/__init__.pyPKSFvY$Y guiqwt/tests/imagesuperp/__init__.pyPKSFs63!\ guiqwt/tests/syncplot/__init__.pyPKSFpPj(X guiqwt/tests/highprecisionxy/__init__.pyPKSF|-7 guiqwt/tests/manager/__init__.pyPKSF2! guiqwt/tests/contrast/__init__.pyPKSF:(%^) guiqwt/tests/pyplot/__init__.pyPKSF a\$ guiqwt/tests/get_segment/__init__.pyPKSF1! guiqwt/tests/plot_log/__init__.pyPKSF%TO') guiqwt/tests/image_plot_tools/__init__.pyPKSF.% guiqwt/tests/computations/__init__.pyPKSFmJd; guiqwt/tests/resize/__init__.pyPKSFhKT% guiqwt/tests/image_masked/__init__.pyPKSFT guiqwt/tests/pcolor/__init__.pyPKSF t guiqwt/tests/imagexy/__init__.pyPKSF(uW&[ guiqwt/tests/sift/__init__.pyPKSF+q guiqwt/tests/fit/__init__.pyPKSFcy+ guiqwt/tests/loadsaveitems_hdf5/__init__.pyPKSFH\H<S" guiqwt/tests/image_rgb/__init__.pyPKSF)$ guiqwt/tests/hist2d_func/__init__.pyPKSF-E guiqwt/tests/customize_shape_tool/__init__.pyPKSFi;& guiqwt/tests/cross_section/__init__.pyPKSF͆_{# guiqwt/tests/mandelbrot/__init__.pyPKSFz4! guiqwt/tests/polygons/__init__.pyPKSF]y";q& guiqwt/tests/simple_window/__init__.pyPKSFGyU"9 guiqwt/tests/transform/__init__.pyPKSF7N4| 'x= guiqwt/tests/image/__init__.pyPKSFU#> guiqwt/tests/fliprotate/__init__.pyPKSFxo"@ guiqwt/tests/get_point/__init__.pyPKSFn9<A guiqwt/tests/plot/__init__.pyPKSFV$D guiqwt/tests/filtertest1/__init__.pyPKSF.S#F guiqwt/tests/rotatecrop/__init__.pyPKSF-L#H guiqwt/tests/benchmarks/__init__.pyPKSF1"]J guiqwt/tests/histogram/__init__.pyPKSFa,˾$K guiqwt/tests/imagefilter/__init__.pyPKSF8>xR#L guiqwt/tests/qtdesigner/__init__.pyPKSFj  $[N guiqwt/tests/filtertest2/__init__.pyPKSFK8Q guiqwt/tests/hist2d/__init__.pyPKSFc"{R guiqwt/tests/fontparam/__init__.pyPKSF^!~ -S guiqwt/tests/loadsaveitems_pickle/__init__.pyPKSF.W guiqwt/tests/cross_section_oblique/__init__.pyPKSF|r&yY guiqwt/tests/simple_dialog/__init__.pyPKSF~T N[ guiqwt/tests/cursors/__init__.pyPKSF֤%"|\ guiqwt/tests/test_line/__init__.pyPKSF1&C] guiqwt/tests/plot_yreverse/__init__.pyPKSFf\s^ guiqwt/tests/styles/__init__.pyPKSFu@I\} guiqwt/mandelbrot/__init__.pyPKSFT\?,} guiqwt/image/__init__.pyPKSFp%ss guiqwt/label/__init__.pyPKSF@Q:% guiqwt/plot/__init__.pyPKSFmBH* guiqwt/transitional/__init__.pyPKSFݶL"s guiqwt/debug/__init__.pyPKSF'\"~t1 guiqwt/histogram/__init__.pyPKSF @\ guiqwt/qtdesigner/__init__.pyPKSF3I guiqwt/config/__init__.pyPKSFz guiqwt/_scaler/__init__.pyPKSFuLm guiqwt/signals/__init__.pyPKSFK  guiqwt/colormap/__init__.pyPKSF}AO guiqwt/_cm/__init__.pyPKSFΟ-h guiqwt/tools/__init__.pyPKSFַ@Їm- guiqwt/qthelpers/__init__.pyPKSFp4B"|yI0 guiqwt/shapes/__init__.pyPKSFebHNyR guiqwt/histogram2d/__init__.pyPKSFt^${LS guiqwt/styles/__init__.pyPKSF[^Ox PyQt4/__init__.pyPKSFoU4y PyQt4/phonon/__init__.pyPKSFxWDgc E{z PyQt4/Qwt5/__init__.pyPKSFV'< E PyQt4/Qwt5/Qwt/__init__.pyPKSFgDd6H PyQt4/Qwt5/_iqt/__init__.pyPKSFP^ PyQt4/Qwt5/iqt/__init__.pyPKSFߛWl PyQt4/Qwt5/qplt/__init__.pyPKSFQc| PyQt4/Qwt5/grace/__init__.pyPKSF% /5} PyQt4/Qwt5/anynumpy/__init__.pyPKSFCEDv PyQt4/QtCore/__init__.pyPKSFd  PyQt4/QtOpenGL/__init__.pyPKSFBdqj) PyQt4/QtXmlPatterns/__init__.pyPKSFYsn PyQt4/QtScript/__init__.pyPKSF[< /v PyQt4/QtNetwork/__init__.pyPKSF2J PyQt4/QtWebKit/__init__.pyPKSFbW PyQt4/QtTest/__init__.pyPKSFm^ PyQt4/uic/__init__.pyPKSFgDd6H PyQt4/uic/port_v3/__init__.pyPKSFc) PyQt4/uic/port_v3/load_plugin/__init__.pyPKSFY' PyQt4/uic/port_v3/as_string/__init__.pyPKSFi߹Of'X PyQt4/uic/port_v3/string_io/__init__.pyPKSF8]?c$ PyQt4/uic/port_v3/invoke/__init__.pyPKSF PyQt4/uic/uiparser/__init__.pyPKSFSt PyQt4/uic/exceptions/__init__.pyPKSFXMJ ? PyQt4/uic/objcreator/__init__.pyPKSFԡ֊. PyQt4/uic/driver/__init__.pyPKSFQʫ PyQt4/uic/port_v2/__init__.pyPKSFc) PyQt4/uic/port_v2/load_plugin/__init__.pyPKSFT%Ke) PyQt4/uic/port_v2/ascii_upper/__init__.pyPKSFY' PyQt4/uic/port_v2/as_string/__init__.pyPKSFk%zFZ'. PyQt4/uic/port_v2/string_io/__init__.pyPKSF{xh( PyQt4/uic/port_v2/proxy_base/__init__.pyPKSF8]?c$g PyQt4/uic/port_v2/invoke/__init__.pyPKSF % PyQt4/uic/pykdeuic4/__init__.pyPKSF ] PyQt4/uic/properties/__init__.pyPKSFQLp ` PyQt4/uic/icon_cache/__init__.pyPKSF- PyQt4/uic/Compiler/__init__.pyPKSFw'PyQt4/uic/Compiler/compiler/__init__.pyPKSF&':( PyQt4/uic/Compiler/qtproxies/__init__.pyPKSFJl.cPyQt4/uic/Compiler/proxy_metaclass/__init__.pyPKSFZdn#PyQt4/uic/Compiler/misc/__init__.pyPKSFݲc'PyQt4/uic/Compiler/indenter/__init__.pyPKSF-PyQt4/uic/Compiler/qobjectcreator/__init__.pyPKSFgDd6HPyQt4/uic/Loader/__init__.pyPKSF{n&2#PyQt4/uic/Loader/loader/__init__.pyPKSFt)+PyQt4/uic/Loader/qobjectcreator/__init__.pyPKSF_!15PyQt4/Qsci/__init__.pyPKSFjf{ 9PyQt4/QtDesigner/__init__.pyPKSF,<PyQt4/QtDeclarative/__init__.pyPKSF+EIhAPyQt4/QtXml/__init__.pyPKSFw" CPyQt4/QtSvg/__init__.pyPKSFNXEFPyQt4/QtScriptTools/__init__.pyPKSFYJHPyQt4/QtSql/__init__.pyPKSF~w r_KPyQt4/QtGui/__init__.pyPKSFt\PyQt4/QtMultimedia/__init__.pyPKSF*QLPyQt4/QtHelp/__init__.pyPKSFGT PyQt4/QtDBus/__init__.pyPKSFe=CPyQt4/Qt/__init__.pyPKSFHCOPyQt4/pyqtconfig/__init__.pyPKSFwvguidata/__init__.pyPKSFT&e guidata/userconfigio/__init__.pyPKSF'Vɪguidata/userconfig/__init__.pyPKSF{#vܫguidata/guitest/__init__.pyPKSFtM)AUguidata/tests/__init__.pyPKSF"V&guidata/tests/translations/__init__.pyPKSF=Jf&%guidata/tests/all_features/__init__.pyPKSF)sU*" &guidata/tests/editgroupbox/__init__.pyPKSFL,h2#=guidata/tests/all_items/__init__.pyPKSF֝#guidata/tests/callbacks/__init__.pyPKSFKfy&guidata/tests/datasetgroup/__init__.pyPKSFB@Kguidata/tests/data/__init__.pyPKSF~V_x%Zguidata/tests/disthelpers/__init__.pyPKSF'A,~%guidata/tests/inheritance/__init__.pyPKSFD+guidata/tests/activable_dataset/__init__.pyPKSFvO guidata/tests/config/__init__.pyPKSF`guidata/tests/hdf5/__init__.pyPKSFJ0@)guidata/tests/activable_items/__init__.pyPKSFRH6 _&guidata/tests/rotatedlabel/__init__.pyPKSF%(7vguidata/tests/text/__init__.pyPKSF2P#'8guidata/tests/bool_selector/__init__.pyPKSFZ#guidata/dataset/__init__.pyPKSFb#π%guidata/dataset/qtwidgets/__init__.pyPKSF&D%)$guidata/dataset/dataitems/__init__.pyPKSF˴f%%guidata/dataset/datatypes/__init__.pyPKSF ޥ"W{)Y'guidata/dataset/qtitemwidgets/__init__.pyPKSFwtk$EJguidata/dataset/textedit/__init__.pyPKSF0F1 fJguidata/qtwidgets/__init__.pyPKSFd^kguidata/disthelpers/__init__.pyPKSF_H#lguidata/gettext_helpers/__init__.pyPKSFAe36Rmguidata/config/__init__.pyPKSF*+Wnguidata/utils/__init__.pyPKSF0kpguidata/hdf5io/__init__.pyPKSF|k"^f4qguidata/configtools/__init__.pyPKSFj&.E2fguidata/qthelpers/__init__.pyPKSFDE\guidata/qt/__init__.pyPKSFF9uhguidata/qt/compat/__init__.pyPKSFsEiguidata/qt/QtCore/__init__.pyPKSF'&guidata/qt/QtWebKit/__init__.pyPKSF#%."r `guidata/qt/QtGui/__init__.pyPKSF (guidata/py3compat/__init__.pyPKSF}gspyderlib/utils/codeanalysis/__init__.pyPKSF]y%hspyderlib/utils/bsdsocket/__init__.pyPKSFb#ispyderlib/utils/iofuncs/__init__.pyPKSFb" kspyderlib/utils/system/__init__.pyPKSFk&kspyderlib/utils/dochelpers/__init__.pyPKSF)ޅ?mspyderlib/utils/vcs/__init__.pyPKSFDX$ nspyderlib/utils/encoding/__init__.pyPKSFh4Z#Bospyderlib/utils/windows/__init__.pyPKSFdWw%ospyderlib/utils/inspector/__init__.pyPKSF:`Z*wpspyderlib/utils/inspector/conf/__init__.pyPKSFpC/rspyderlib/utils/inspector/sphinxify/__init__.pyPKSF,i$sspyderlib/utils/external/__init__.pyPKSF~@ԓD-tspyderlib/utils/external/lockfile/__init__.pyPKSFAo )uspyderlib/utils/external/path/__init__.pyPKSFK'0vspyderlib/utils/external/pickleshare/__init__.pyPKSFtqA }-wspyderlib/utils/module_completion/__init__.pyPKSFzn!%yspyderlib/utils/debug/__init__.pyPKSF yspyderlib/utils/misc/__init__.pyPKSF`8$zspyderlib/utils/programs/__init__.pyPKSFY4F%[|spyderlib/utils/qthelpers/__init__.pyPKSF'spyderlib/utils/classparser/__init__.pyPKSFK?6wR #spyderlib/utils/environ/__init__.pyPKSFy"tspyderlib/requirements/__init__.pyPKSFwPq!-spyderlib/cli_options/__init__.pyPKSFa!9ispyderlib/plugins/__init__.pyPKSF9$*Xspyderlib/plugins/configdialog/__init__.pyPKSFoZ-]spyderlib/plugins/outlineexplorer/__init__.pyPKSFnj"v-spyderlib/plugins/externalconsole/__init__.pyPKSFm"q'3spyderlib/plugins/shortcuts/__init__.pyPKSFS(Uspyderlib/plugins/onlinehelp/__init__.pyPKSFVM.Wspyderlib/plugins/workingdirectory/__init__.pyPKSF&2[spyderlib/plugins/explorer/__init__.pyPKSFMˌ .]spyderlib/plugins/variableexplorer/__init__.pyPKSF|Me%_spyderlib/plugins/console/__init__.pyPKSF(+K#~'cspyderlib/plugins/runconfig/__init__.pyPKSF(\)ۆspyderlib/plugins/findinfiles/__init__.pyPKSFϢ%-ӈspyderlib/plugins/projectexplorer/__init__.pyPKSFvL%spyderlib/plugins/history/__init__.pyPKSF9( $spyderlib/plugins/editor/__init__.pyPKSF{spyderlib/qt/__init__.pyPKSF1<spyderlib/qt/compat/__init__.pyPKSFsEispyderlib/qt/QtCore/__init__.pyPKSF'&!spyderlib/qt/QtWebKit/__init__.pyPKSFXT spyderlib/qt/QtSvg/__init__.pyPKSF#%."r ` spyderlib/qt/QtGui/__init__.pyPKSFgDd6H~ply/__init__.pyPKSFwRply/yacc/__init__.pyPKSF208ply/ctokens/__init__.pyPKSFOH{jply/lex/__init__.pyPKSF5 @ply/cpp/__init__.pyPKSF//taurus/__init__.pyPKSF[#-taurus/core/__init__.pyPKSF:.+6taurus/core/taurusconfiguration/__init__.pyPKSF`V %5taurus/core/taurusmanager/__init__.pyPKSF=ơ4$Γtaurus/core/taurushelper/__init__.pyPKSF[:a*taurus/core/tauruspollingtimer/__init__.pyPKSF$'taurus/core/taurusbasetypes/__init__.pyPKSF@_ \taurus/core/epics/__init__.pyPKSF%,=*/taurus/core/epics/epicsfactory/__init__.pyPKSF=|'taurus/core/taurusoperation/__init__.pyPKSFRg;"taurus/core/simulation/__init__.pyPKSF#?-taurus/core/simulation/simfactory/__init__.pyPKSF.8\ ""taurus/core/evaluation/__init__.pyPKSFKgV2 .4taurus/core/evaluation/dev_example/__init__.pyPKSFL@.taurus/core/evaluation/evalfactory/__init__.pyPKSF+#Z:/dtaurus/core/evaluation/ipap_example/__init__.pyPKSFf{ taurus/core/release/__init__.pyPKSF'P#'ðtaurus/core/taurusattribute/__init__.pyPKSF3%%+taurus/core/taurusfactory/__init__.pyPKSFE&Mtaurus/core/tauruslistener/__init__.pyPKSFCn,#taurus/core/taurusmodel/__init__.pyPKSFfO=$taurus/core/taurusdevice/__init__.pyPKSFC  taurus/core/tango/__init__.pyPKSFP,jtaurus/core/tango/tangoattribute/__init__.pyPKSFOFaF!?taurus/core/tango/img/__init__.pyPKSF Rc %߾taurus/core/tango/img/img/__init__.pyPKSF0#ttaurus/core/tango/enums/__init__.pyPKSF %gtaurus/core/tango/starter/__init__.pyPKSFcIf)taurus/core/tango/tangodevice/__init__.pyPKSFO*ctaurus/core/tango/tangofactory/__init__.pyPKSFTz0*taurus/core/tango/tangoconfiguration/__init__.pyPKSF $[taurus/core/tango/search/__init__.pyPKSF9u/o+itaurus/core/tango/tangodatabase/__init__.pyPKSF!p5z!taurus/core/util/__init__.pyPKSF&1'taurus/core/util/sourcecode/__init__.pyPKSFEtaurus/external/qt/Qwt5/qplt/__init__.pyPKSFQc))taurus/external/qt/Qwt5/grace/__init__.pyPKSF% /,*taurus/external/qt/Qwt5/anynumpy/__init__.pyPKSF[ F%5taurus/external/qt/QtCore/__init__.pyPKSF[< /(7|taurus/external/qt/QtNetwork/__init__.pyPKSF2J'htaurus/external/qt/QtWebKit/__init__.pyPKSFJ֥-"2taurus/external/qt/uic/__init__.pyPKSFjf{ )taurus/external/qt/QtDesigner/__init__.pyPKSFw" $ataurus/external/qt/QtSvg/__init__.pyPKSF~w r_$taurus/external/qt/QtGui/__init__.pyPKSF*Q%taurus/external/qt/QtHelp/__init__.pyPKSFcLO]!c taurus/external/qt/Qt/__init__.pyPKSFfo(j Utaurus/external/enum/__init__.pyPKSFјg%taurus/external/enum/enum/__init__.pyPKSF3:rtaurus/console/__init__.pyPKSF5xtaurus/console/list/__init__.pyPKSFK_| ytaurus/console/enums/__init__.pyPKSFo_v taurus/console/table/__init__.pyPKSFgDd6Htaurus/console/util/__init__.pyPKSFgDd6H&taurus/web/__init__.pyPKSF'E9$taurus/web/taurustornado/__init__.pyPKSFvOB ttaurus/test/__init__.pyPKSFbѻ#taurus/test/test_import/__init__.pyPKSFZzPqtaurus/test/base/__init__.pyPKSFWt9wtaurus/test/skip/__init__.pyPKSFښc!Xtaurus/test/fuzzytest/__init__.pyPKSFt&taurus/test/moduleexplorer/__init__.pyPKSF߀;O~!taurus/test/testsuite/__init__.pyPKSF۽]'V~ otaurus/test/resource/__init__.pyPKSFgDd6Htaurus/qt/__init__.pyPKSFI Fltaurus/qt/Qwt5/__init__.pyPKSF[ F;taurus/qt/QtCore/__init__.pyPKSF[< /%taurus/qt/QtNetwork/__init__.pyPKSF2J0taurus/qt/QtWebKit/__init__.pyPKSF6h9taurus/qt/uic/__init__.pyPKSFOYt(d:taurus/qt/uic/tau2taurus_map/__init__.pyPKSFjf{ L;taurus/qt/QtDesigner/__init__.pyPKSFw" =taurus/qt/QtSvg/__init__.pyPKSF~w r_@taurus/qt/QtGui/__init__.pyPKSFgDd6H taurus/qt/qtdesigner/__init__.pyPKSFnKn2]taurus/qt/qtdesigner/extraguiqwtplugin/__init__.pyPKSFd/taurus/qt/qtdesigner/taurusdesigner/__init__.pyPKSF1w08taurus/qt/qtdesigner/containerplugin/__init__.pyPKSFZ ! 3gtaurus/qt/qtdesigner/tauruspluginplugin/__init__.pyPKSFXШPx-ٹtaurus/qt/qtdesigner/taurusplugin/__init__.pyPKSFu}8:ttaurus/qt/qtdesigner/taurusplugin/taurusplugin/__init__.pyPKSFgDd6Htaurus/qt/qtopengl/__init__.pyPKSFLo}vtaurus/qt/qtcore/__init__.pyPKSF&z9"-taurus/qt/qtcore/model/__init__.pyPKSFF=0_q63taurus/qt/qtcore/model/taurusdatabasemodel/__init__.pyPKSFҦc[.taurus/qt/qtcore/model/taurusmodel/__init__.pyPKSFt?&Itaurus/qt/qtcore/mimetypes/__init__.pyPKSF٥nK0^taurus/qt/qtcore/mimetypes/mimetypes/__init__.pyPKSF[b1ȫ'*Ntaurus/qt/qtcore/configuration/__init__.pyPKSFQ8Ataurus/qt/qtcore/configuration/configuration/__init__.pyPKSFҰ2 ,taurus/qt/qtcore/taurusqlistener/__init__.pyPKSF֌M*taurus/qt/qtcore/communication/__init__.pyPKSF 8taurus/qt/qtcore/communication/communication/__init__.pyPKSFgDd6H"taurus/qt/qtcore/tango/__init__.pyPKSFqF=!taurus/qt/qtcore/util/__init__.pyPKSFT2+taurus/qt/qtcore/util/tauruslog/__init__.pyPKSF;.,9taurus/qt/qtcore/util/properties/__init__.pyPKSF,vWpp)taurus/qt/qtcore/util/emitter/__init__.pyPKSFP taurus/qt/qtgui/__init__.pyPKSFgnv !taurus/qt/qtgui/model/__init__.pyPKSFl ,7taurus/qt/qtgui/model/qbasemodel/__init__.pyPKSF'^'taurus/qt/qtgui/extra_xterm/__init__.pyPKSFGR4`taurus/qt/qtgui/extra_xterm/qxtermwidget/__init__.pyPKSF@1Xf'taurus/qt/qtgui/application/__init__.pyPKSF'29ataurus/qt/qtgui/application/taurusapplication/__init__.pyPKSFtWۀp ztaurus/qt/qtgui/base/__init__.pyPKSFcwc+8taurus/qt/qtgui/base/taurusbase/__init__.pyPKSFG 1taurus/qt/qtgui/base/taurusqattribute/__init__.pyPKSF:dE~1taurus/qt/qtgui/base/tauruscontroller/__init__.pyPKSF'S#6#|taurus/qt/qtgui/display/__init__.pyPKSFw)l(taurus/qt/qtgui/display/qled/__init__.pyPKSFgDd6H(taurus/qt/qtgui/display/demo/__init__.pyPKSF}2u:taurus/qt/qtgui/display/demo/qpixmapwidgetdemo/__init__.pyPKSF}2u8taurus/qt/qtgui/display/demo/tauruslabeldemo/__init__.pyPKSF}2u6taurus/qt/qtgui/display/demo/tauruslcddemo/__init__.pyPKSF}2u6\taurus/qt/qtgui/display/demo/taurusleddemo/__init__.pyPKSF0Y1%taurus/qt/qtgui/display/qsevensegment/__init__.pyPKSFd²1taurus/qt/qtgui/display/taurusboolled/__init__.pyPKSF-21Q)taurus/qt/qtgui/display/qpixmapwidget/__init__.pyPKSFgDd6H(*taurus/qt/qtgui/display/test/__init__.pyPKSF$ L 9I+taurus/qt/qtgui/display/test/test_tauruslabel/__init__.pyPKSF">V 4.taurus/qt/qtgui/display/taurusvaluelabel/__init__.pyPKSFңy21taurus/qt/qtgui/display/tauruslcdvalue/__init__.pyPKSF}Yk)4taurus/qt/qtgui/display/qlogo/__init__.pyPKSFR}B5L6taurus/qt/qtgui/display/taurusconfiglabel/__init__.pyPKSF}]uV'79taurus/qt/qtgui/extra_nexus/__init__.pyPKSFu7N 9u;taurus/qt/qtgui/extra_nexus/taurusnexuswidget/__init__.pyPKSFtW">taurus/qt/qtgui/dialog/__init__.pyPKSF^|"<{@taurus/qt/qtgui/dialog/taurusconfigurationdialog/__init__.pyPKSF\53Ataurus/qt/qtgui/dialog/taurusmessagebox/__init__.pyPKSFK4Ctaurus/qt/qtgui/dialog/taurusinputdialog/__init__.pyPKSF(j[!6Etaurus/qt/qtgui/panel/__init__.pyPKSFh} 3SNtaurus/qt/qtgui/panel/taurusdevicepanel/__init__.pyPKSFݛs4 Staurus/qt/qtgui/panel/taurusmodelchooser/__init__.pyPKSFI-Wtaurus/qt/qtgui/panel/qdoublelist/__init__.pyPKSFQ[<42Ytaurus/qt/qtgui/panel/taurusmessagepanel/__init__.pyPKSFj3&&8\taurus/qt/qtgui/panel/taurusattributechooser/__init__.pyPKSF.1^taurus/qt/qtgui/panel/qrawdatachooser/__init__.pyPKSF|r}<4_taurus/qt/qtgui/panel/taurusconfigeditor/__init__.pyPKSFbZ-btaurus/qt/qtgui/panel/taurusvalue/__init__.pyPKSFLl=,itaurus/qt/qtgui/panel/taurusform/__init__.pyPKSFjh1ntaurus/qt/qtgui/panel/taurusmodellist/__init__.pyPKSFgDd6H(}rtaurus/qt/qtgui/panel/report/__init__.pyPKSFU_4rtaurus/qt/qtgui/panel/report/basicreport/__init__.pyPKSFQZBn3ttaurus/qt/qtgui/panel/report/albareport/__init__.pyPKSF[|!2 3=vtaurus/qt/qtgui/panel/taurusfilterpanel/__init__.pyPKSFS[E:ytaurus/qt/qtgui/panel/taurusconfigurationpanel/__init__.pyPKSFgDd6H&{taurus/qt/qtgui/panel/test/__init__.pyPKSFᎷe-#7F|taurus/qt/qtgui/panel/test/test_taurusvalue/__init__.pyPKSF)]3N6~taurus/qt/qtgui/panel/test/test_taurusform/__init__.pyPKSFG2jtaurus/qt/qtgui/panel/taurusinputpanel/__init__.pyPKSFmfEYc3Ђtaurus/qt/qtgui/panel/qdataexportdialog/__init__.pyPKSFޜHS*%ztaurus/qt/qtgui/container/__init__.pyPKSF. 0taurus/qt/qtgui/container/qcontainer/__init__.pyPKSFj4ɋtaurus/qt/qtgui/container/taurusgroupbox/__init__.pyPKSFEG47*taurus/qt/qtgui/container/taurusgroupwidget/__init__.pyPKSF:v6Ɛtaurus/qt/qtgui/container/taurusscrollarea/__init__.pyPKSFQJ2taurus/qt/qtgui/container/tauruswidget/__init__.pyPKSFF!ap1ߕtaurus/qt/qtgui/container/taurusframe/__init__.pyPKSFgik6taurus/qt/qtgui/container/taurusmainwindow/__init__.pyPKSF YI9]taurus/qt/qtgui/container/taurusbasecontainer/__init__.pyPKSFg) !Xtaurus/qt/qtgui/input/__init__.pyPKSF^P -!taurus/qt/qtgui/input/tauruswheel/__init__.pyPKSF<{|+4taurus/qt/qtgui/input/choicedlg/__init__.pyPKSF$ 0taurus/qt/qtgui/input/tauruscombobox/__init__.pyPKSF> 05taurus/qt/qtgui/input/tauruslineedit/__init__.pyPKSFP+J~ (\taurus/qt/qtgui/input/qwheel/__init__.pyPKSFk d< /taurus/qt/qtgui/input/taurusspinbox/__init__.pyPKSF*0utaurus/qt/qtgui/input/tauruscheckbox/__init__.pyPKSF9:(:}!޸taurus/qt/qtgui/image/__init__.pyPKSFP+)taurus/qt/qtgui/extra_sardana/__init__.pyPKSF {!ütaurus/qt/qtgui/style/__init__.pyPKSFk"^(}taurus/qt/qtgui/style/nebula/__init__.pyPKSFZ- taurus/qt/qtgui/plot/__init__.pyPKSF30.}taurus/qt/qtgui/plot/curveStatsDlg/__init__.pyPKSFgDd6H(taurus/qt/qtgui/plot/qwtplot/__init__.pyPKSFϣ!*utaurus/qt/qtgui/plot/qwtdialog/__init__.pyPKSF^n:~1;taurus/qt/qtgui/plot/curvesAppearanceChooserDlg/__init__.pyPKSFp7 +taurus/qt/qtgui/plot/curveprops/__init__.pyPKSF@>,taurus/qt/qtgui/plot/taurustrend/__init__.pyPKSF<;+taurus/qt/qtgui/plot/taurusplot/__init__.pyPKSFC`0>taurus/qt/qtgui/plot/taurusarrayedit/__init__.pyPKSF:]f*taurus/qt/qtgui/plot/arrayedit/__init__.pyPKSFiʣR'Otaurus/qt/qtgui/plot/scales/__init__.pyPKSF֕2 (taurus/qt/qtgui/plot/monitor/__init__.pyPKSFP˶K>&taurus/qt/qtgui/extra_pool/__init__.pyPKSF4~S=%!ntaurus/qt/qtgui/table/__init__.pyPKSF=o 6taurus/qt/qtgui/table/taurusvaluestable_ro/__init__.pyPKSFK3JLo,+taurus/qt/qtgui/table/taurusgrid/__init__.pyPKSF;bz$+taurus/qt/qtgui/table/qlogtable/__init__.pyPKSFN/.taurus/qt/qtgui/table/taurusdbtable/__init__.pyPKSFd,3taurus/qt/qtgui/table/taurusvaluestable/__init__.pyPKSFO;2(6taurus/qt/qtgui/table/qtable/__init__.pyPKSF3  -taurus/qt/qtgui/table/taurustable/__init__.pyPKSF +ڕN- taurus/qt/qtgui/table/qdictionary/__init__.pyPKSFʽ"/ ; taurus/qt/qtgui/table/taurusdevicepropertytable/__init__.pyPKSF #taurus/qt/qtgui/graphic/__init__.pyPKSF/k3%)taurus/qt/qtgui/graphic/jdraw/__init__.pyPKSFgϤ6H taurus/qt/qtgui/graphic/jdraw/jdraw_lextab/__init__.pyPKSFy4!taurus/qt/qtgui/graphic/jdraw/jdraw_view/__init__.pyPKSFЋ6B&taurus/qt/qtgui/graphic/jdraw/jdraw_parser/__init__.pyPKSF9'y/s(taurus/qt/qtgui/graphic/jdraw/jdraw/__init__.pyPKSFa>P+79-taurus/qt/qtgui/graphic/jdraw/jdraw_yacctab/__init__.pyPKSFA!&r.E.taurus/qt/qtgui/graphic/jdraw/test/__init__.pyPKSFgDd6H2/taurus/qt/qtgui/graphic/jdraw/test/res/__init__.pyPKSF#x1/taurus/qt/qtgui/graphic/taurusgraphic/__init__.pyPKSFS-k57taurus/qt/qtgui/graphic/taurusgraphicview/__init__.pyPKSF{ #=;taurus/qt/qtgui/console/__init__.pyPKSFTm(;X=taurus/qt/qtgui/console/taurusconsoleextensions/__init__.pyPKSFڔ.@ />taurus/qt/qtgui/extra_macroexecutor/__init__.pyPKSF׫)lN ")Ctaurus/qt/qtgui/button/__init__.pyPKSFmw;l'Ftaurus/qt/qtgui/button/test/__init__.pyPKSFa2bA9Gtaurus/qt/qtgui/button/test/test_taurusbutton/__init__.pyPKSFgDd6H+?Jtaurus/qt/qtgui/button/test/res/__init__.pyPKSF6˳+/Jtaurus/qt/qtgui/button/taurusbutton/__init__.pyPKSF5-Ntaurus/qt/qtgui/button/qbuttonbox/__init__.pyPKSFWbJ !XPtaurus/qt/qtgui/gauge/__init__.pyPKSFgDd6H&7Staurus/qt/qtgui/gauge/demo/__init__.pyPKSF}2u1Staurus/qt/qtgui/gauge/demo/qmeterdemo/__init__.pyPKSF ^i(uTtaurus/qt/qtgui/gauge/qmeter/__init__.pyPKSF9u+ $Wtaurus/qt/qtgui/util/__init__.pyPKSFdat2\taurus/qt/qtgui/util/qdraganddropdebug/__init__.pyPKSF9aC;4]taurus/qt/qtgui/util/taurusactionfactory/__init__.pyPKSFyKFK1d_taurus/qt/qtgui/util/tauruswidgettree/__init__.pyPKSFܦ-ataurus/qt/qtgui/util/taurusaction/__init__.pyPKSFӧbOW1dtaurus/qt/qtgui/util/taurusscreenshot/__init__.pyPKSF8FX*ftaurus/qt/qtgui/util/widgetgen/__init__.pyPKSF&&#gtaurus/qt/qtgui/util/ui/__init__.pyPKSFVCd,}htaurus/qt/qtgui/util/tauruscolor/__init__.pyPKSF޾2HX4itaurus/qt/qtgui/util/tauruswidgetfactory/__init__.pyPKSFgDd6H%'ktaurus/qt/qtgui/util/test/__init__.pyPKSF,O-ktaurus/qt/qtgui/util/test/test_ui/__init__.pyPKSFQLj55mtaurus/qt/qtgui/util/test/test_ui/test_ui/__init__.pyPKSFWFu7Aotaurus/qt/qtgui/util/test/test_ui/mywidget3/__init__.pyPKSF]HDW0ptaurus/qt/qtgui/util/taurusropepatch/__init__.pyPKSF)%*qtaurus/qt/qtgui/taurusgui/__init__.pyPKSF4u7vtaurus/qt/qtgui/taurusgui/appsettingswizard/__init__.pyPKSF-&>ztaurus/qt/qtgui/taurusgui/PermanentCustomPanelsDlg/__init__.pyPKSF$*{taurus/qt/qtgui/taurusgui/conf/__init__.pyPKSF%NJZ7t|taurus/qt/qtgui/taurusgui/conf/gui_selfconf/__init__.pyPKSFn;}taurus/qt/qtgui/taurusgui/conf/tgconf_example01/__init__.pyPKSFj!33aB~taurus/qt/qtgui/taurusgui/conf/tgconf_example01/config/__init__.pyPKSFZu6t7mtaurus/qt/qtgui/taurusgui/conf/gui_pureconf/__init__.pyPKSFgDd6H56taurus/qt/qtgui/taurusgui/conf/gui_noconf/__init__.pyPKSF :taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/__init__.pyPKSF:A7taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/config/__init__.pyPKSF29? /taurus/qt/qtgui/taurusgui/taurusgui/__init__.pyPKSF56+وtaurus/qt/qtgui/taurusgui/utils/__init__.pyPKSF'%_3Xtaurus/qt/qtgui/taurusgui/macrolistener/__init__.pyPKSFxq%B<_taurus/qt/qtgui/taurusgui/paneldescriptionwizard/__init__.pyPKSFCDml taurus/qt/qtgui/test/__init__.pyPKSF'%Ǔtaurus/qt/qtgui/test/base/__init__.pyPKSF!Txs taurus/qt/qtgui/help/__init__.pyPKSFM*taurus/qt/qtgui/help/helppanel/__init__.pyPKSF/t*taurus/qt/qtgui/help/assistant/__init__.pyPKSFc \>,Gtaurus/qt/qtgui/help/aboutdialog/__init__.pyPKSFUl~N`"taurus/qt/qtgui/editor/__init__.pyPKSFbL /{taurus/qt/qtgui/editor/tauruseditor/__init__.pyPKSFS ۚ(Ρtaurus/qt/qtgui/extra_guiqwt/__init__.pyPKSF[70taurus/qt/qtgui/extra_guiqwt/builder/__init__.pyPKSF%4taurus/qt/qtgui/extra_guiqwt/curvesmodel/__init__.pyPKSF+l .4taurus/qt/qtgui/extra_guiqwt/curve/__init__.pyPKSFО .taurus/qt/qtgui/extra_guiqwt/image/__init__.pyPKSF! - taurus/qt/qtgui/extra_guiqwt/plot/__init__.pyPKSFDc 6taurus/qt/qtgui/extra_guiqwt/taurustrend2d/__init__.pyPKSFM.otaurus/qt/qtgui/extra_guiqwt/tools/__init__.pyPKSF8 Ml/taurus/qt/qtgui/extra_guiqwt/styles/__init__.pyPKSFr G!#taurus/qt/qtgui/compact/__init__.pyPKSF ^D<4taurus/qt/qtgui/compact/abstractswitcher/__init__.pyPKSF6_P1taurus/qt/qtgui/compact/basicswitcher/__init__.pyPKSF'o 'taurus/qt/qtgui/tree/__init__.pyPKSF_56-taurus/qt/qtgui/tree/taurusdbtree/__init__.pyPKSF5)c +taurus/qt/qtgui/tree/taurustree/__init__.pyPKSFb"1 taurus/qt/qtgui/tree/taurusdevicetree/__init__.pyPKSFg^ &ttaurus/qt/qtgui/tree/qtree/__init__.pyPKSFJщL$taurus/qt/qtgui/resource/__init__.pyPKSFi,:,taurus/qt/qtgui/resource/taurus_resource_utils/__init__.pyPKSFcLO]taurus/qt/Qt/__init__.pyPKSF# 2numpy/__init__.pyPKSF Kànumpy/distutils/__init__.pyPKSFW0%)Gnumpy/distutils/from_template/__init__.pyPKSFos%[numpy/distutils/extension/__init__.pyPKSFo /#numpy/distutils/command/__init__.pyPKSF&lўQ+numpy/distutils/command/install/__init__.pyPKSF4~3hnumpy/distutils/command/install_headers/__init__.pyPKSFܗ+V},7numpy/distutils/command/autodist/__init__.pyPKSFGǮT1קnumpy/distutils/command/build_scripts/__init__.pyPKSFZ8JK,Ԩnumpy/distutils/command/egg_info/__init__.pyPKSF++6-numpy/distutils/command/build_src/__init__.pyPKSF}-numpy/distutils/command/bdist_rpm/__init__.pyPKSFfE7H0Ynumpy/distutils/command/install_clib/__init__.pyPKSF_pA);numpy/distutils/command/build/__init__.pyPKSF0numpy/distutils/command/install_data/__init__.pyPKSFF()numpy/distutils/command/scons/__init__.pyPKSF7x3ȱnumpy/distutils/command/config_compiler/__init__.pyPKSF3wD*numpy/distutils/command/config/__init__.pyPKSFWj-numpy/distutils/command/build_ext/__init__.pyPKSFU@+еnumpy/distutils/command/develop/__init__.pyPKSFw).numpy/distutils/command/build_clib/__init__.pyPKSFF;)numpy/distutils/command/sdist/__init__.pyPKSF}sÐ+,numpy/distutils/command/build_py/__init__.pyPKSFJ_!ֹnumpy/distutils/setup/__init__.pyPKSF`KHY'_numpy/distutils/environment/__init__.pyPKSF~,On"rnumpy/distutils/compat/__init__.pyPKSFF numpy/distutils/core/__init__.pyPKSF͍#1numpy/distutils/cpuinfo/__init__.pyPKSF.numpy/distutils/numpy_distribution/__init__.pyPKSF+%o0numpy/distutils/log/__init__.pyPKSF26*numpy/distutils/intelccompiler/__init__.pyPKSF$W%'Anumpy/distutils/system_info/__init__.pyPKSF<`* numpy/distutils/npy_pkg_config/__init__.pyPKSFW7V|B%Anumpy/distutils/misc_util/__init__.pyPKSF=Q)numpy/distutils/unixccompiler/__init__.pyPKSFGa numpy/distutils/info/__init__.pyPKSFKĐB'Snumpy/distutils/interactive/__init__.pyPKSFDI#"numpy/distutils/lib2def/__init__.pyPKSF23,_numpy/distutils/mingw32ccompiler/__init__.pyPKSF Nm&numpy/distutils/setupscons/__init__.pyPKSFQ{r;i(mnumpy/distutils/line_endings/__init__.pyPKSF|\)numpy/distutils/pathccompiler/__init__.pyPKSFC,%enumpy/distutils/ccompiler/__init__.pyPKSF&(numpy/distutils/exec_command/__init__.pyPKSFb?)+numpy/distutils/conv_template/__init__.pyPKSF1w%numpy/distutils/fcompiler/__init__.pyPKSF[zugA-knumpy/distutils/fcompiler/pathf95/__init__.pyPKSF*V )numpy/distutils/fcompiler/nag/__init__.pyPKSFp[+numpy/distutils/fcompiler/lahey/__init__.pyPKSF۲$%*^numpy/distutils/fcompiler/none/__init__.pyPKSFFwtF)numpy/distutils/fcompiler/g95/__init__.pyPKSFYZJ)numpy/distutils/fcompiler/gnu/__init__.pyPKSF\+numpy/distutils/fcompiler/intel/__init__.pyPKSFEdk,numpy/distutils/fcompiler/absoft/__init__.pyPKSF%*numpy/distutils/fcompiler/vast/__init__.pyPKSF&2#)numpy/distutils/fcompiler/ibm/__init__.pyPKSFR*{V*numpy/distutils/fcompiler/mips/__init__.pyPKSFqb\yF(_numpy/distutils/fcompiler/pg/__init__.pyPKSF[K,numpy/distutils/fcompiler/compaq/__init__.pyPKSFO*Unumpy/distutils/fcompiler/hpux/__init__.pyPKSFeeH)numpy/distutils/fcompiler/sun/__init__.pyPKSFJ_{numpy/setup/__init__.pyPKSF$6numpy/compat/__init__.pyPKSFJ_ numpy/compat/setup/__init__.pyPKSF*ܴs!numpy/compat/_inspect/__init__.pyPKSF Nm#numpy/compat/setupscons/__init__.pyPKSF韞gnumpy/compat/py3k/__init__.pyPKSF4Snumpy/ma/__init__.pyPKSFk_unumpy/ma/setup/__init__.pyPKSFCt numpy/ma/core/__init__.pyPKSFbE,! numpy/ma/extras/__init__.pyPKSFtܼh numpy/ma/mrecords/__init__.pyPKSFAD) numpy/ma/testutils/__init__.pyPKSFk_numpy/ma/setupscons/__init__.pyPKSF:Enumpy/ma/bench/__init__.pyPKSF8Z%numpy/random/__init__.pyPKSFP(Fnumpy/random/setup/__init__.pyPKSF\~numpy/random/mtrand/__init__.pyPKSFF/FYnumpy/random/info/__init__.pyPKSF@sg#ynumpy/random/setupscons/__init__.pyPKSFvg$!numpy/core/__init__.pyPKSFr!numpy/core/multiarray/__init__.pyPKSF~Hm- "numpy/core/numeric/__init__.pyPKSFs"!*numpy/core/shape_base/__init__.pyPKSF6[[+numpy/core/setup/__init__.pyPKSFTk#.numpy/core/defchararray/__init__.pyPKSFpg{$1numpy/core/function_base/__init__.pyPKSFf1numpy/core/_methods/__init__.pyPKSF`2numpy/core/machar/__init__.pyPKSFi%v"C3numpy/core/umath_tests/__init__.pyPKSF>3numpy/core/umath/__init__.pyPKSFC&7numpy/core/memmap/__init__.pyPKSFVĬd 7numpy/core/getlimits/__init__.pyPKSFΙUs8numpy/core/info/__init__.pyPKSFoi9numpy/core/records/__init__.pyPKSF+y<% :numpy/core/_internal/__init__.pyPKSF7ix"<numpy/core/fromnumeric/__init__.pyPKSF1o!=numpy/core/arrayprint/__init__.pyPKSF0Pw'?numpy/core/multiarray_tests/__init__.pyPKSF a!@numpy/core/scalarmath/__init__.pyPKSFgDd6H6Anumpy/core/_dummy/__init__.pyPKSF#e#Anumpy/core/setup_common/__init__.pyPKSFu %#Dnumpy/core/numerictypes/__init__.pyPKSF2QYInumpy/dual/__init__.pyPKSFNUJnumpy/f2py/__init__.pyPKSFb-ALnumpy/f2py/cfuncs/__init__.pyPKSFQ?9 XMnumpy/f2py/cb_rules/__init__.pyPKSFI MPnumpy/f2py/setup/__init__.pyPKSF϶w_#Qnumpy/f2py/f2py_testing/__init__.pyPKSF),8Rnumpy/f2py/f2py2e/__init__.pyPKSF`VG #Snumpy/f2py/common_rules/__init__.pyPKSFg7{ Vnumpy/f2py/auxfuncs/__init__.pyPKSF- Ynumpy/f2py/func2subr/__init__.pyPKSF)TL[1]numpy/f2py/diagnose/__init__.pyPKSF!5 #]numpy/f2py/f90mod_rules/__init__.pyPKSFGabnumpy/f2py/info/__init__.pyPKSF\M`"bnumpy/f2py/__version__/__init__.pyPKSFp#cnumpy/f2py/rules/__init__.pyPKSFRZ Dgnumpy/f2py/capi_maps/__init__.pyPKSFI M!jnumpy/f2py/setupscons/__init__.pyPKSF۸ knumpy/f2py/use_rules/__init__.pyPKSFqGxq> #onumpy/f2py/crackfortran/__init__.pyPKSF)*Bvnumpy/polynomial/__init__.pyPKSF|g/%wnumpy/polynomial/laguerre/__init__.pyPKSFJ_"]ynumpy/polynomial/setup/__init__.pyPKSFq 5Mt'ynumpy/polynomial/polynomial/__init__.pyPKSFjS1$H{numpy/polynomial/hermite/__init__.pyPKSF0 &|numpy/polynomial/polyutils/__init__.pyPKSFB/%}numpy/polynomial/legendre/__init__.pyPKSFwh[&/numpy/polynomial/chebyshev/__init__.pyPKSF{8`)΀numpy/polynomial/polytemplate/__init__.pyPKSFMz3&unumpy/polynomial/hermite_e/__init__.pyPKSF:xnumpy/ctypeslib/__init__.pyPKSF 7;numpy/matrixlib/__init__.pyPKSF Nm! numpy/matrixlib/setup/__init__.pyPKSF9pM%numpy/matrixlib/defmatrix/__init__.pyPKSF Nm&jnumpy/matrixlib/setupscons/__init__.pyPKSFnumpy/linalg/__init__.pyPKSFxOn4numpy/linalg/setup/__init__.pyPKSFxY $numpy/linalg/lapack_lite/__init__.pyPKSF~numpy/linalg/linalg/__init__.pyPKSFF/FYnumpy/linalg/info/__init__.pyPKSFJ_#tnumpy/linalg/setupscons/__init__.pyPKSF"')numpy/version/__init__.pyPKSF4FMnumpy/doc/__init__.pyPKSFgDd6HBnumpy/doc/internals/__init__.pyPKSFgDd6Hnumpy/doc/glossary/__init__.pyPKSFgDd6H'numpy/doc/io/__init__.pyPKSFsJKhnumpy/doc/constants/__init__.pyPKSFgDd6Hnumpy/doc/basics/__init__.pyPKSFgDd6Hnumpy/doc/creation/__init__.pyPKSFgDd6Hnumpy/doc/indexing/__init__.pyPKSFgDd6H'onumpy/doc/structured_arrays/__init__.pyPKSFgDd6Hnumpy/doc/jargon/__init__.pyPKSFgDd6H*Znumpy/doc/methods_vs_functions/__init__.pyPKSFgDd6H"ؕnumpy/doc/broadcasting/__init__.pyPKSFgDd6H"Nnumpy/doc/byteswapping/__init__.pyPKSFgDd6HĖnumpy/doc/misc/__init__.pyPKSFgDd6H!2numpy/doc/performance/__init__.pyPKSFgDd6H!numpy/doc/subclassing/__init__.pyPKSFgDd6Hnumpy/doc/ufuncs/__init__.pyPKSFgDd6Hnumpy/doc/howtofind/__init__.pyPKSF(\fnumpy/fft/__init__.pyPKSFcNRnumpy/fft/helper/__init__.pyPKSFJ_numpy/fft/setup/__init__.pyPKSFad"rnumpy/fft/fftpack_lite/__init__.pyPKSFKnZnumpy/fft/fftpack/__init__.pyPKSFF/FY#numpy/fft/info/__init__.pyPKSFJ_ numpy/fft/setupscons/__init__.pyPKSF!݌WI\)numpy/add_newdocs/__init__.pyPKSFf+ u 4numpy/oldnumeric/__init__.pyPKSF oQ+@&\numpy/oldnumeric/functions/__init__.pyPKSF(&numpy/oldnumeric/rng_stats/__init__.pyPKSFJ_"numpy/oldnumeric/setup/__init__.pyPKSFc_i# numpy/oldnumeric/matrix/__init__.pyPKSFtY5#numpy/oldnumeric/compat/__init__.pyPKSFmnumpy/oldnumeric/ma/__init__.pyPKSFu#l!Onumpy/numarray/ufuncs/__init__.pyPKSFfad)numpy/numarray/linear_algebra/__init__.pyPKSFɱ&numpy/numarray/alter_code1/__init__.pyPKSF<3' numpy/numarray/numerictypes/__init__.pyPKSFQ)numpy/testing/__init__.pyPKSFJ_]numpy/testing/setup/__init__.pyPKSFh$numpy/testing/nosetester/__init__.pyPKSFB$numpy/testing/decorators/__init__.pyPKSFe/numpy/testing/print_coercion_tables/__init__.pyPKSF hQh$lnumpy/testing/nulltester/__init__.pyPKSFG-ZY#numpy/testing/numpytest/__init__.pyPKSFJ_$ numpy/testing/setupscons/__init__.pyPKSF,BJW numpy/testing/utils/__init__.pyPKSFRŐ numpy/lib/__init__.pyPKSF\"C$ numpy/lib/_compiled_base/__init__.pyPKSFn  numpy/lib/shape_base/__init__.pyPKSF}uiNo numpy/lib/setup/__init__.pyPKSFъ# numpy/lib/stride_tricks/__init__.pyPKSFf>\ numpy/lib/arraypad/__init__.pyPKSFu#[ numpy/lib/function_base/__init__.pyPKSF! numpy/lib/arraysetops/__init__.pyPKSF1_ numpy/lib/scimath/__init__.pyPKSFo]  numpy/lib/polynomial/__init__.pyPKSF௽H"Z numpy/lib/index_tricks/__init__.pyPKSFIJ" numpy/lib/recfunctions/__init__.pyPKSFGHl numpy/lib/npyio/__init__.pyPKSFG= K numpy/lib/type_check/__init__.pyPKSFJN0w numpy/lib/ufunclike/__init__.pyPKSFH8\uq O numpy/lib/user_array/__init__.pyPKSFΙUsb numpy/lib/info/__init__.pyPKSFQӗa numpy/lib/financial/__init__.pyPKSF=i" numpy/lib/arrayterator/__init__.pyPKSF}uiNo l numpy/lib/setupscons/__init__.pyPKSF7~g- numpy/lib/format/__init__.pyPKSF֕%:, numpy/lib/utils/__init__.pyPKSFvc! numpy/lib/twodim_base/__init__.pyPKSF01! numpy/lib/_datasource/__init__.pyPKSFF1%4_! numpy/lib/_iotools/__init__.pyPKSFmk" numpy/_import_tools/__init__.pyPKSF&w# sip/__init__.pyPKtt$ sardana-1.6.1/scripts/0000755000234000017500000000000012555673001016445 5ustar zreszelaComputing00000000000000sardana-1.6.1/scripts/MacroServer0000755000234000017500000000311212555672636020635 0ustar zreszelaComputing00000000000000#!/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.6.1/scripts/Pool0000755000234000017500000000307612555672636017327 0ustar zreszelaComputing00000000000000#!/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.6.1/scripts/Sardana0000755000234000017500000000306112555672636017761 0ustar zreszelaComputing00000000000000#!/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.6.1/scripts/h5toascii0000755000234000017500000000763212555672636020310 0ustar zreszelaComputing00000000000000#!/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.6.1/scripts/h5tospec0000755000234000017500000001715412555672636020152 0ustar zreszelaComputing00000000000000#!/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.6.1/scripts/macroexecutor0000755000234000017500000000211412555672636021266 0ustar zreszelaComputing00000000000000#!/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 sardana.taurus.qt.qtgui.extra_macroexecutor.macroexecutor import main main() sardana-1.6.1/scripts/sequencer0000755000234000017500000000211512555672636020401 0ustar zreszelaComputing00000000000000#!/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 sardana.taurus.qt.qtgui.extra_macroexecutor.sequenceeditor import main main() sardana-1.6.1/scripts/spectoascii0000755000234000017500000000571512555672636020726 0ustar zreszelaComputing00000000000000#!/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.6.1/scripts/spock0000755000234000017500000000321412555672636017527 0ustar zreszelaComputing00000000000000#!/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.6.1/src/0000755000234000017500000000000012555672777015570 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/0000755000234000017500000000000012555673001017156 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/0000755000234000017500000000000012555673001021506 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/macros/0000755000234000017500000000000012555673001022772 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/macros/examples/0000755000234000017500000000000012555673001024610 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/macros/examples/__init__.py0000644000234000017500000000206612555672636026742 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/examples/debug.py0000644000234000017500000000236212555672636026270 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################# ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 ...""" #__all__ = [] __docformat__ = 'restructuredtext' from sardana.macroserver.macro import Type, macro @macro() def raise_exception(self): '''A macro that raises an exception (useful for debugging)''' raise Exception('here is your exception!') sardana-1.6.1/src/sardana/macroserver/macros/examples/funcs.py0000644000234000017500000000453512555672636026324 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/examples/hooks.py0000644000234000017500000001374612555672636026335 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/examples/parameters.py0000644000234000017500000001303612555672636027345 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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): """A macro that returns a float that is twice its input. It also sets its data to be a dictionary with 'in','out' as keys and value,result as values, respectively""" # 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): ret = 2*n self.setData({'in':n, 'out':ret}) return retsardana-1.6.1/src/sardana/macroserver/macros/examples/plotting.py0000644000234000017500000000311312555672636027035 0ustar zreszelaComputing00000000000000import 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.6.1/src/sardana/macroserver/macros/examples/scans.py0000644000234000017500000006056412555672636026321 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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, Hookable): """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-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } 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["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('_NOHINT_') step["post-step-hooks"] = self.getHooks('post-step') 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.6.1/src/sardana/macroserver/macros/examples/specific_experiments.py0000644000234000017500000001140512555672636031410 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/examples/submacros.py0000644000234000017500000001354412555672636027204 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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, prep = self.createMacro("ascan %s 0 10 4 0.2" % motor.getName()) macro.hooks = [ self.hook ] self.runMacro(macro) 8 - macro, prep = 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, prep = 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, prep = self.createMacro("ascan %s 0 10 4 0.2" % \ motor.getName()) macro.hooks = [ self.hook ] self.runMacro(macro) elif call_type == 8: macro, prep = 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, prep = self.createMacro(params) macro.hooks = [ self.hook ] self.runMacro(macro) sardana-1.6.1/src/sardana/macroserver/macros/examples/user_input.py0000644000234000017500000000630112555672636027374 0ustar zreszelaComputing00000000000000 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.6.1/src/sardana/macroserver/macros/test/0000755000234000017500000000000012555673001023751 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/macros/test/__init__.py0000644000234000017500000000227612555672636026106 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 macroexecutor import BaseMacroExecutor, MacroExecutorFactory from base import (macroTest, BaseMacroTestCase, RunMacroTestCase, RunStopMacroTestCase, testRun, testFail, testStop) from sardemoenv import SarDemoEnv sardana-1.6.1/src/sardana/macroserver/macros/test/base.py0000644000234000017500000003250512555672636025257 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """System tests for Macros""" __all__ = ['macroTest', 'BaseMacroTestCase', 'RunMacroTestCase', 'RunStopMacroTestCase', 'testRun', 'testFail', 'testStop'] import time import functools from sardana import sardanacustomsettings from sardana.macroserver.macros.test import MacroExecutorFactory from taurus.test import insertTest #Define a "_NOT_PASSED" object to mark a keyword arg which is not passed # Note that we do not want to use None because one may want to pass None class __NotPassedType(int): pass _NOT_PASSED = __NotPassedType() def macroTest(klass=None, helper_name=None, test_method_name=None, test_method_doc=None, **helper_kwargs): """This decorator is an specialization of :function::`taurus.test.insertTest` for macro testing. It inserts test methods from a helper method that may accept arguments. macroTest provides a very economic API for creating new tests for a given macro based on a helper method. macroTest accepts the following arguments: - helper_name (str): the name of the helper method. macroTest will insert a test method which calls the helper with any the helper_kwargs (see below). - test_method_name (str): Optional. Name of the test method to be used. If None given, one will be generated from the macro and helper names. - test_method_doc (str): The docstring for the inserted test method (this shows in the unit test output). If None given, a default one is generated which includes the input parameters and the helper name. - \*\*helper_kwargs: All remaining keyword arguments are passed to the helper. `macroTest` assumes that the decorated class has a `macro_name` class member. This decorator can be considered a "base" decorator. It is often used to create other decorators in which the helper method is pre-set. Some of them are already provided in this module: - :meth:`testRun` is equivalent to macroTest with helper_name='macro_runs' - :meth:`testStop` is equivalent to macroTest with helper_name='macro_stops' - :meth:`testFail` is equivalent to macroTest with helper_name='macro_fails' The advantage of using the decorators compared to writing the test methods directly is that the helper method can get keyword arguments and therefore avoid duplication of code for very similar tests (think, e.g. on writing similar tests for various sets of macro input parameters): Consider the following code written using the :meth:`RunMacroTestCase.macro_runs` helper:: class FooTest(RunMacroTestCase, unittest.TestCase) macro_name = twice def test_foo_runs_with_input_2(self): '''test that twice(2) runs''' self.macro_runs(macro_params=['2']) def test_foo_runs_with_input_minus_1(self): '''test that twice(2) runs''' self.macro_runs(macro_params=['-1']) The equivalent code could be written as:: @macroTest(helper_name='macro_runs', macro_params=['2']) @macroTest(helper_name='macro_runs', macro_params=['-1']) class FooTest(RunMacroTestCase, unittest.TestCase): macro_name = 'twice' Or, even better, using the specialized testRun decorator:: @testRun(macro_params=['2']) @testRun(macro_params=['-1']) class FooTest(RunMacroTestCase, unittest.TestCase): macro_name = 'twice' .. seealso:: :function::`taurus.test.insertTest` """ #recipe to allow decorating with and without arguments if klass is None: return functools.partial(macroTest, helper_name=helper_name, test_method_name=test_method_name, test_method_doc=test_method_doc, **helper_kwargs) return insertTest(klass=klass, helper_name=helper_name, test_method_name=test_method_name, test_method_doc=test_method_doc, tested_name = klass.macro_name, **helper_kwargs) #Definition of specializations of the macroTest decorator: testRun = functools.partial(macroTest, helper_name='macro_runs') testStop = functools.partial(macroTest, helper_name='macro_stops') testFail = functools.partial(macroTest, helper_name='macro_fails') class BaseMacroTestCase(object): """An abstract class for macro testing. BaseMacroTestCase will provide a `macro_executor` member which is an instance of BaseMacroExecutor and which can be used to run a macro. To use it, simply inherit from BaseMacroTestCase *and* unittest.TestCase and provide the following class members: - macro_name (string) name of the macro to be tested (mandatory) - door_name (string) name of the door where the macro will be executed. This is optional. If not set, `sardanacustomsettings.UNITTEST_DOOR_NAME` is used Then you may define test methods. """ macro_name = None door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME') def setUp(self): """ A macro_executor instance must be created """ if self.macro_name is None: msg = '%s does not define macro_name' % self.__class__.__name__ raise NotImplementedError(msg) mefact = MacroExecutorFactory() self.macro_executor = mefact.getMacroExecutor(self.door_name) def tearDown(self): """The macro_executor instance must be removed """ self.macro_executor.unregisterAll() self.macro_executor = None class RunMacroTestCase(BaseMacroTestCase): """A base class for testing execution of arbitrary Sardana macros. See :class:`BaseMacroTestCase` for requirements. It provides the following helper methods: - :meth:`macro_runs` - :meth:`macro_fails` """ def assertFinished(self, msg): """Asserts that macro has finished. """ finishStates = [u'finish'] state = self.macro_executor.getState() #TODO buffer is just for debugging, attach only the last state state_buffer = self.macro_executor.getStateBuffer() msg = msg + '; State history=%s' % state_buffer self.assertIn(state, finishStates, msg) def setUp(self): """Preconditions: - Those from :class:`BaseMacroTestCase` - the macro executor registers to all the log levels """ BaseMacroTestCase.setUp(self) self.macro_executor.registerAll() def macro_runs(self, macro_params=None, wait_timeout=float("inf"), data=_NOT_PASSED): """A helper method to create tests that check if the macro can be successfully executed for the given input parameters. It may also optionally perform checks on the outputs from the execution. :param macro_params: (seq): parameters for running the macro. If passed, they must be given as a sequence of their string representations. :param wait_timeout: (float) maximum allowed time (in s) for the macro to finish. By default infinite timeout is used. :param data: (obj) Optional. If passed, the macro data after the execution is tested to be equal to this. """ self.macro_executor.run(macro_name=self.macro_name, macro_params=macro_params, sync=True, timeout=wait_timeout) self.assertFinished('Macro %s did not finish' % self.macro_name) #check if the data of the macro is the expected one if data is not _NOT_PASSED: actual_data = self.macro_executor.getData() msg = 'Macro data does not match expected data:\n' + \ 'obtained=%s\nexpected=%s' % (actual_data, data) self.assertEqual(actual_data, data, msg) #TODO: implement generic asserts for macro result and macro output, etc # in a similar way to what is done for macro data def macro_fails(self, macro_params=None, wait_timeout=float("inf"), exception=None): """Check that the macro fails to run for the given input parameters :param macro_params: (seq) input parameters for the macro :param wait_timeout: maximum allowed time for the macro to fail. By default infinite timeout is used. :param exception: (str or Exception) if given, an additional check of the type of the exception is done. (IMPORTANT: this is just a comparison of str representations of exception objects) """ self.macro_executor.run(macro_name=self.macro_name, macro_params=macro_params, sync=True, timeout=wait_timeout) state = self.macro_executor.getState() actual_exc_str = self.macro_executor.getExceptionStr() msg = 'Post-execution state should be "exception" (got "%s")' % state self.assertEqual(state, 'exception', msg) if exception is not None: msg = 'Raised exception does not match expected exception:\n' + \ 'raised=%s\nexpected=%s' % (actual_exc_str, exception) self.assertEqual(actual_exc_str, str(exception), msg) class RunStopMacroTestCase(RunMacroTestCase): """This is an extension of :class:`RunMacroTestCase` to include helpers for testing the abort process of a macro. Useful for Runnable and Stopable macros. It provides the :meth:`macro_stops` helper """ def assertStopped(self, msg): """Asserts that macro was stopped """ stoppedStates = [u'stop'] state = self.macro_executor.getState() #TODO buffer is just for debugging, attach only the last state state_buffer = self.macro_executor.getStateBuffer() msg = msg + '; State buffer was %s' % state_buffer self.assertIn(state, stoppedStates, msg) def macro_stops(self, macro_params=None, stop_delay=0.1, wait_timeout=float("inf")): """A helper method to create tests that check if the macro can be successfully stoped (a.k.a. aborted) after it has been launched. :param macro_params: (seq): parameters for running the macro. If passed, they must be given as a sequence of their string representations. :param stop_delay: (float) Time (in s) to wait between launching the macro and sending the stop command. default=0.1 :param wait_timeout: (float) maximum allowed time (in s) for the macro to finish. By default infinite timeout is used. """ self.macro_executor.run(macro_name=self.macro_name, macro_params=macro_params, sync=False) if stop_delay is not None: time.sleep(stop_delay) self.macro_executor.stop() self.macro_executor.wait(timeout=wait_timeout) self.assertStopped('Macro %s did not stop' % self.macro_name) if __name__ == '__main__': from taurus.external import unittest from sardana.macroserver.macros.test import SarDemoEnv _m1 = SarDemoEnv().getMotors()[0] #@testRun(macro_params=[_m1, '0', '100', '4', '.1']) @testRun(macro_params=[_m1, '1', '0', '2', '.1']) @testRun(macro_params=[_m1, '0', '1', '4', '.1']) class dummyAscanTest(RunStopMacroTestCase, unittest.TestCase): macro_name = 'ascan' @testRun(macro_params=['1'], data={'in': 1, 'out': 2}) @testRun(macro_params=['5']) @testRun class dummyTwiceTest(RunStopMacroTestCase, unittest.TestCase): macro_name = 'twice' @testFail @testFail(exception=Exception) class dummyRaiseException(RunStopMacroTestCase, unittest.TestCase): macro_name = 'raise_exception' suite = unittest.defaultTestLoader.loadTestsFromTestCase( dummyRaiseException) unittest.TextTestRunner(descriptions=True, verbosity=2).run(suite) sardana-1.6.1/src/sardana/macroserver/macros/test/macroexecutor.py0000644000234000017500000002517012555672636027225 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.core.util.singleton import Singleton class BaseMacroExecutor(object): """Abstract MacroExecutor class. Inherit from it if you want to create your own macro executor. """ log_levels = ['debug', 'output', 'info', 'warning', 'critical', 'error'] def __init__(self): # macro result self._result = None #macro exception status self._exception = None # buffer for state history self._state_buffer = [] # log buffers, one for each level for level in self.log_levels: setattr(self, '_%s' % level, None) # common buffer, any registered log level will be appended here self._common = None def _clean(self): """In case of reuse of the macro executor object this method executes the necessary cleanups. Extend if you need to clean your particular setups. """ for level in self.log_levels: log_buffer = getattr(self, '_%s' % level) if not log_buffer is None: log_buffer.__init__() if self._common: self._common.__init__() def run(self, macro_name, macro_params=None, sync=True, timeout=float("inf")): """Execute macro. :param macro_name: (string) name of macro to be executed :param macro_params: (list) macro parameters (default is macro_params=None for macros without parameters or with the default values) :param sync: (bool) whether synchronous or asynchronous call (default is sync=True) :param timeout: (float) timeout (in s) that will be passed to the wait method, in case of synchronous execution In asyncrhonous execution method :meth:`~wait` has to be explicitly called. """ if macro_params == None: macro_params = [] self._clean() self._run(macro_name, macro_params) if sync: self.wait(timeout) def _run(self, macro_name, macro_params): """Method responsible for triggering the macro execution. Must be implemented in your macro executor. :param macro_name: (string) name of macro to be executed :param macro_params: (list) macro parameters (default is macro_params=None for macros without parameters or with the default values) """ raise NotImplementedError('Method _run not implemented in class %s' % self.__class__.__name__) def wait(self, timeout=float("inf")): """ Wait until macro is done. Use it in asynchronous executions. :param timeout: (float) waiting timeout (in s) """ if timeout <= 0: timeout = float("inf") self._wait(timeout) def _wait(self, timeout): """Method responsible for waiting until macro is done. Must be implemented in your macro executor. :param timeout: (float) waiting timeout (in s) """ raise NotImplementedError('Method _wait not implemented in class %s' % self.__class__.__name__) def stop(self, started_event_timeout=3.0): """Stop macro execution. Execute macro in synchronous way before using this method. :param started_event_timeout: (float) waiting timeout for started event """ self._stop(started_event_timeout) def _stop(self, started_event_timeout=3.0): """ Method responsible for stopping the macro execution. Must be implemented in your macro executor. :param started_event_timeout: (float) waiting timeout for started event """ raise NotImplementedError('Method _stop not implemented in class %s' % self.__class__.__name__) def registerLog(self, log_level): """Start registering log messages. :param log_level: (str) string indicating the log level """ log_buffer_name = '_%s' % log_level setattr(self, log_buffer_name, []) self._registerLog(log_level) def _registerLog(self, log_level): """ Method responsible for starting log registration. Must be implemented in your macro executor. :param log_level: (str) string indicating the log level """ raise NotImplementedError('Method _registerLog not implemented in ' 'class %s' % self.__class__.__name__) def unregisterLog(self, log_level): """Stop registering log messages. :param log_level: (str) string indicating the log level """ self._unregisterLog(log_level) def _unregisterLog(self, log_level): """Method responsible for stopping log registration. Must be implemented in your macro executor. :param log_level: (str) string indicating the log level """ raise NotImplementedError('Method _unregisterLog not implemented in ' 'class %s' % self.__class__.__name__) def getLog(self, log_level): """Get log messages. :param log_level: (str) string indicating the log level :return: (seq) list of strings with log messages """ log_buffer_name = '_%s' % log_level log = getattr(self, log_buffer_name) return log def registerAll(self): """Register for macro result, all log levels and common buffer. """ for log_level in self.log_levels: self.registerLog(log_level) self.registerResult() self.createCommonBuffer() def unregisterAll(self): """Unregister macro result, all log levels and common buffer. """ for log_level in self.log_levels: self.unregisterLog(log_level) self.unregisterResult() def registerResult(self): """Register for macro result """ self._registerResult() def _registerResult(self): """Method responsible for registering for macro result. Must be implemented in your macro executor. """ raise NotImplementedError('Method _registerResult not implemented in ' 'class %s' % self.__class__.__name__) def unregisterResult(self): """Unregister macro result. """ self._unregisterResult() def _unregisterResult(self): """Method responsible for unregistering for macro result. Must be implemented in your macro executor. """ raise NotImplementedError('Method _unregisterResult not implemented in' ' class %s' % self.__class__.__name__) def getResult(self): """Get macro result. :return: (seq) list of strings with Result messages """ return self._result def createCommonBuffer(self): """Create a common buffer, where all the registered logs will be stored. """ self._common = [] def getCommonBuffer(self): """Get common buffer. Method getCommonBuffer can only be used if at least one buffer exists. :return: (seq) list of strings with messages from all log levels .. seealso:: :meth:`~createCommonBuffer` """ return self._common def getState(self): """Get macro execution state. :return: (str) """ state = None if len(self._state_buffer) > 0: state = self._state_buffer[-1] return state def getStateBuffer(self): """Get buffer (history) of macro execution states. :return: (seq) """ return self._state_buffer def getExceptionStr(self): """Get macro exception type representation (None if the macro state is not exception). :return: (str) """ return self._exception class MacroExecutorFactory(Singleton): """A scheme-agnostic factory for MacroExecutor instances Example:: f = MacroExecutorFactory() f.getMacroExecutor('tango://my/door/name') #returns a TangoMacroExecutor Note: For the moment, only TangoMacroExecutor is supported """ def getMacroExecutor(self, door_name=None): """ Returns a macro executor instance (a subclass of :class:`BaseMacroExecutor`) depending on the door being used. """ if door_name == None: from sardana import sardanacustomsettings door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME') #======================================================================= # TODO: Once SEP3 is done, it will define a better way to get the scheme # from a model name (including customized default schemes) # For the moment I implement it by calling an internal member of # TaurusManager from taurus.core import TaurusManager scheme = TaurusManager()._get_scheme(door_name) #====================================================================== if scheme == 'tango': return self._getTangoMacroExecutor(door_name) else: raise ValueError('No MacroExecutor supported for scheme %s' % scheme) def _getTangoMacroExecutor(self, door_name): from sardana.tango.macroserver.test import TangoMacroExecutor return TangoMacroExecutor(door_name=door_name) if __name__ == '__main__': from sardana import sardanacustomsettings door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME') print MacroExecutorFactory().getMacroExecutor(door_name) sardana-1.6.1/src/sardana/macroserver/macros/test/sardemoenv.py0000644000234000017500000001217512555672636026511 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################# ## ## This file is part of Sardana, a Tango User Interface Library ## ## http://www.sardana-controls.org/ ## ## 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 taurus import Device from sardana.taurus.core.tango.sardana import registerExtensions from taurus.core.util.singleton import Singleton from sardana import sardanacustomsettings class SarDemoEnv(Singleton): """Class to get _SAR_DEMO environment variable with cross checking with the MacroServer (given by :attr:`UNITTEST_DOOR_NAME`) """ def __init__(self, door_name=None): if door_name is None: door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME') registerExtensions() try: self.door = Device(door_name) self.ms = self.door.macro_server except ValueError: raise ValueError('The door %s does not exist' % (door_name)) self.controllers = None self.cts = None self.motors = None self.pseudos = None self.zerods = None self.oneds = None self.twods = None try: self.env = self.ms.getEnvironment()['_SAR_DEMO']['elements'] + \ list(self.ms.getEnvironment()['_SAR_DEMO']['controllers']) except KeyError: err = 'sar_demo has not been executed (or door %s not ready)' % \ door_name raise RuntimeError(err) def getElements(self, elem_type='all'): """Return the name of sardemo element(s) of given elem type :param elem_type: (str) type of elemnts to return (all by default) :return: (list) """ if elem_type.lower() == 'all': return self.env if elem_type.lower() == 'moveable': return self.getElements('motor') + self.getElements('pseudomotor') ms_elems = self.ms.getElementNamesOfType(elem_type) elems = [e for e in ms_elems if e is not None and e in self.env] return elems def getMoveables(self): """Return the name of moveable(s) defined by SarDemo :return: (list) """ return self.getMotors() + self.getPseudoMotors() def getControllers(self): """Return the name of controllers(s) defined by SarDemo :return: (list) """ if not self.controllers: self.controllers = self.getElements('controller') return self.controllers def getCTs(self): """Return the name of counter timer exp channel(s) defined by SarDemo :return: (list) """ if not self.cts: self.cts = self.getElements('ctexpchannel') return self.cts def getMotors(self): """Return the name of motor(s) defined by SarDemo :return: (list) """ if not self.motors: self.motors = self.getElements('motor') return self.motors def getPseudoMotors(self): """Return the name of pseudomotor(s) defined by SarDemo :return: (list) """ if not self.pseudos: self.pseudos = self.getElements('pseudomotor') return self.pseudos def getZerods(self): """Return the name of zerod exp channel(s) defined by SarDemo :return: (list) """ if not self.zerods: self.zerods = self.getElements('zerodexpchannel') return self.zerods def getOneds(self): """Return the name of one exp channel(s) defined by SarDemo :return: (list) """ if not self.oneds: self.oneds = self.getElements('onedexpchannel') return self.oneds def getTwods(self): """Return the name of two exp channel(s) defined by SarDemo :return: (list) """ if not self.twods: self.twods = self.getElements('twodexpchannel') return self.twods def changeDoor(self, door_name): """Change the door name and reset all lists """ self.__init__(door_name) if __name__ == '__main__': s = SarDemoEnv() print s.env print s.getControllers() print s.getCTs() print s.getMotors() print s.getPseudoMotors() print s.getZerods() print s.getOneds() print s.getTwods() print s.getElements('Moveable') print s.getMoveables() print s.getElements() sardana-1.6.1/src/sardana/macroserver/macros/test/test_ct.py0000644000234000017500000000334212555672636026007 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Tests for ct macros""" from taurus.external import unittest from sardana.macroserver.macros.test import RunStopMacroTestCase from sardana.macroserver.macros.test import testRun from sardana.macroserver.macros.test import testStop @testRun(macro_params=['.1'], wait_timeout=2) @testRun(macro_params=['.3'], wait_timeout=2) @testStop(macro_params=['1'], stop_delay=.1, wait_timeout=3) class CtTest(RunStopMacroTestCase, unittest.TestCase): """Test of ct macro. It verifies that macro ct can be executed. It inherits from RunStopMacroTestCase and from unittest.TestCase. It tests two executions of the ct macro with two different input parameters. Then it does another execution and it tests if the execution can be aborted. """ macro_name = "ct" sardana-1.6.1/src/sardana/macroserver/macros/test/test_list.py0000644000234000017500000001231512555672636026354 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Tests for list macros""" import time from taurus.external import unittest from sardana.macroserver.macros.test import (RunMacroTestCase, testRun, SarDemoEnv) class LsTest(RunMacroTestCase): """Base class for testing macros used to list elements. See :class:`.RunMacroTestCase` for requirements. LsTest use the lists of elem_type generated by :class:`.SarDemoEnv` as reference for compare with the output of the tested ls macro. LsTest provide the class member: - elem_type (str): Type of the element to validate (mandatory). Must be a valid type for :class:`.SarDemoEnv` class. It provides the helper method: - :meth:`check_elements` """ elem_type = None def check_elements(self, list1, list2): """ A helper method to evaluate if all elements of list1 are in list2. :params list1: (seq) List of elements to evaluate. :params list2: (seq) List of elements for validate. """ for elem in list1: msg = "{0} does not contain {1}".format(self.macro_name, elem) self.assertTrue(elem in list2, msg) def macro_runs(self, **kwargs): """ Reimplementation of macro_runs method for ls macros. It verifies that elements (elem_type) gotten by parsing the macro executor log output are in the correspondent list (elem_type) of SardanaEnv. """ RunMacroTestCase.macro_runs(self, **kwargs) self.log_output = self.macro_executor.getLog("output") msg = "generic ls macro does not contain elements" self.assertTrue(len(self.log_output) > 0, msg) if (self.elem_type is not None): list_sardemo = SarDemoEnv().getElements(self.elem_type) else: raise Exception("element_type cannot be None") #parsing log output to get all elements header_rows = 2 names_column_index = 0 macro_output = [] for row, in self.log_output[header_rows:]: macro_output.append(row.split()[names_column_index]) # Evaluate if element of A are in B if len(macro_output) >= len(list_sardemo): self.check_elements(list_sardemo, macro_output) else: self.check_elements(macro_output, list_sardemo) @testRun(macro_params=['l.*']) @testRun class LsmTest(LsTest, unittest.TestCase): """Class used for testing the 'lsm' macro. It verifies that all motors created by sar_demo are listed after execution of the macro 'lsm'. """ macro_name = "lsm" elem_type = "moveable" @testRun class LspmTest(LsTest, unittest.TestCase): """Class used for testing the 'lspm' macro. It verifies that all pseudomotors created by sar_demo are listed after execution of the macro 'lspm'. """ macro_name = "lspm" elem_type = "pseudomotor" @testRun class LsctrlTest(LsTest, unittest.TestCase): """Class used for testing the 'lsctrl' macro. It verifies that all controllers created by sar_demo are listed after execution of the macro 'lsctrl'. """ macro_name = "lsctrl" elem_type = "controller" @testRun class LsctTest(LsTest, unittest.TestCase): """Class used for testing the 'lsct' macro. It verifies that all ct created by sar_demo are listed after execution of the macro 'lsct'. """ macro_name = "lsct" elem_type = "ctexpchannel" @testRun class Ls0dTest(LsTest, unittest.TestCase): """Class used for testing the 'ls0d' macro. It verifies that all 0d created by sar_demo are listed after execution of the macro 'ls0d'. """ macro_name = "ls0d" elem_type = "zerodexpchannel" @testRun class Ls1dTest(LsTest, unittest.TestCase): """Class used for testing the 'ls1d' macro. It verifies that all 1d created by sar_demo are listed after execution of the macro 'ls1d'. """ macro_name = "ls1d" elem_type = "onedexpchannel" @testRun class Ls2dTest(LsTest, unittest.TestCase): """Class used for testing the 'ls2d' macro. It verifies that all 2d created by sar_demo are listed after execution of the macro 'ls2d'. """ macro_name = "ls2d" elem_type = "twodexpchannel" sardana-1.6.1/src/sardana/macroserver/macros/test/test_scan.py0000644000234000017500000001572112555672636026331 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Tests for scan macros""" from taurus.external import unittest from sardana.macroserver.macros.test import (RunStopMacroTestCase, testRun, testStop, SarDemoEnv) #get handy motor names from sardemo try: _MOTORS = SarDemoEnv().getMotors() _m1, _m2 = _MOTORS[:2] except RuntimeError: import taurus from sardana import sardanacustomsettings door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME', 'UNDEFINED') taurus.warning("The door %s is not running. " % (door_name) + "Ignore this message if you are building the documentation") _m1 = _m2 = 'motor_not_defined' except Exception, e: import taurus taurus.debug(e) taurus.warning("It was not possible to retrieve the motor names. " + "Ignore this message if you are building the documentation.") _m1 = _m2 = 'motor_not_defined' def parsing_log_output(log_output): """A helper method to parse log output of an executed scan macro. :params log_output: (seq) Result of macro_executor.getLog('output') (see description in :class:`.BaseMacroExecutor`). :return: (seq) The numeric data of a scan. """ first_data_line = 1 scan_index = 0 data = [] for line, in log_output[first_data_line:]: # Get a list of elements without white spaces between them l = line.split() # Cast all elements of the scan line (l) to float l = [float(scan_elem) for scan_elem in l] # Cast index of scan to int (the first element of the list) l[scan_index] = int(l[scan_index]) data.append(l) return data class ANscanTest(RunStopMacroTestCase): """Not yet implemented. Once implemented it will test anscan. See :class:`.RunStopMacroTestCase` for requirements. """ pass class DNscanTest(ANscanTest): """Not yet implemented. Once implemented it will test the macro dnscanc. See :class:`ANscanTest` for requirements. """ pass class DNscancTest(DNscanTest): """Not yet implemented. Once implemented it will test the macro dnscanc. See :class:`DNscanTest` for requirements. """ pass @testRun(macro_params=[_m1, '0', '5', '4', '.1'], wait_timeout=30.0) @testStop(macro_params=[_m1, '0', '5', '3', '.1']) class AscanTest(ANscanTest, unittest.TestCase): """Test of ascan macro. See :class:`ANscanTest` for requirements. It verifies that macro ascan can be executed and stoped and tests the output of the ascan using data from log system and macro data. """ macro_name = 'ascan' def macro_runs(self, macro_params=None, wait_timeout=30.0): """Reimplementation of macro_runs method for ascan macro. It verifies using double checking, with log output and data from the macro: - The motor initial and final positions of the scan are the ones given as input. - Intervals in terms of motor position between one point and the next one are equidistant. """ #call the parent class implementation ANscanTest.macro_runs(self, macro_params=macro_params, wait_timeout=wait_timeout) mot_name = macro_params[0] expected_init_pos = float(macro_params[1]) expected_final_pos = float(macro_params[2]) self.steps = int(macro_params[-2]) interval = abs(expected_final_pos - expected_init_pos) / self.steps # Test data from macro (macro_executor.getData()) data = self.macro_executor.getData() mot_init_pos = data[min(data.keys())].data[mot_name] mot_final_pos = data[max(data.keys())].data[mot_name] pre = mot_init_pos for step in range(1, max(data.keys()) + 1): self.assertAlmostEqual(abs(pre - data[step].data[mot_name]), interval, 7, "Step interval differs for more than expected (using getData)") pre = data[step].data[mot_name] self.assertAlmostEqual(mot_init_pos, expected_init_pos, 7, "Initial possition differs from set value (using getData)") self.assertAlmostEqual(mot_final_pos, expected_final_pos, 7, "Final possition differs from set value (using getData)") # Test data from log_output (macro_executor.getLog('output')) log_output = self.macro_executor.getLog('output') data = parsing_log_output(log_output) init_pos = 0 last_pos = -1 value = 1 pre = data[init_pos] for step in data[1:]: self.assertAlmostEqual(abs(pre[value] - step[value]), interval, 7, "Step interval differs for more than expected (using getData)") pre = step self.assertAlmostEqual(data[init_pos][value], expected_init_pos, 7, "Initial possition differs from set value (using getLog)") self.assertAlmostEqual(data[last_pos][value], expected_final_pos, 7, "Final possition differs from set value (using getLog)") @testRun(macro_params=[_m1, '-1', '1', '2', '.1'], wait_timeout=30) @testStop(macro_params=[_m1, '1', '-1', '3', '.1']) class DscanTest(DNscanTest, unittest.TestCase): """Test of dscan macro. It verifies that macro dscan can be executed and stoped. See :class:`DNscanTest` for requirements. """ macro_name = 'dscan' @testRun(macro_params=[_m1, '-1', '1', '3', _m2, '-1', '0', '2', '.1'], wait_timeout=30) @testRun(macro_params=[_m1, '-2', '2', '3', _m2, '-2', '-1', '2', '.1'], wait_timeout=30) @testStop(macro_params=[_m1, '-3', '0', '3', _m2, '-3', '0', '2', '.1'], wait_timeout=30) class MeshTest(RunStopMacroTestCase, unittest.TestCase): """Test of mesh macro. It verifies that macro mesh can be executed and stoped. See :class:`.RunStopMacroTestCase` for requirements. """ macro_name = 'mesh' sardana-1.6.1/src/sardana/macroserver/macros/test/test_wm.py0000644000234000017500000000515412555672636026027 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Tests for wm macros""" from taurus.external import unittest from sardana.macroserver.macros.test import (RunMacroTestCase, testRun, SarDemoEnv) try: _MOTORS = SarDemoEnv().getMotors() _m1, _m2 = _MOTORS[:2] except RuntimeError: import taurus from sardana import sardanacustomsettings door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME', 'UNDEFINED') taurus.warning("The door %s is not running. " % (door_name) + "Ignore this message if you are building the documentation.") _m1 = _m2 = 'motor_not_defined' except Exception, e: import taurus taurus.debug(e) taurus.warning("It was not possible to retrieve the motor names. " + "Ignore this message if you are building the documentation.") _m1 = _m2 = 'motor_not_defined' class WBase(RunMacroTestCase): """Base class for testing macros used to read position. """ def macro_runs(self, **kw): """Testing the execution of the 'wm' macro and verify that the log 'output' exists. """ RunMacroTestCase.macro_runs(self, **kw) self.logOutput = self.macro_executor.getLog("output") msg = "wm macro did not return any data." self.assertTrue(len(self.logOutput) > 0, msg) @testRun(macro_params=[_m1], wait_timeout=5.0) class WmTest(WBase, unittest.TestCase): """Test of wm macro. It verifies that the macro 'wm' can be executed. It inherits from WmBase and from unittest.TestCase. It tests the execution of the 'wm' macro and verifies that the log 'output' exists. """ macro_name = "wm" sardana-1.6.1/src/sardana/macroserver/macros/__init__.py0000644000234000017500000000207012555672636025117 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/communication.py0000644000234000017500000000400112555672636026221 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/demo.py0000644000234000017500000001364512555672636024316 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/env.py0000644000234000017500000002702712555672636024161 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 in alphabetical order""" 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() names_list = list(env.keys()) names_list.sort(key=str.lower) for k in names_list: str_val = self.reprValue(env[k]) type_name = type(env[k]).__name__ out.appendRow([k, str_val, type_name]) # list the environment for the current door for the given macros else: out = List(['Macro', 'Name', 'Value', 'Type']) for macro in macro_list: env = self.getEnv(key=None, macro_name=macro.name) names_list = list(env.keys()) names_list.sort(key=str.lower) for k in names_list: str_val = self.reprValue(env[k]) type_name = type(env[k]).__name__ out.appendRow([macro.name, k, str_val, 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.6.1/src/sardana/macroserver/macros/expert.py0000644000234000017500000003753112555672636024701 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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", "addmaclib", "send2ctrl", "udefctrl", "udefelem", "udefmeas", "sar_info"] import sys import traceback import array from sardana.macroserver.msexception import UnknownMacroLibrary from sardana.macroserver.msparameter import WrongParam 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(s)""" param_def = [ ['elements', ParamRepeat(['element', Type.Element, None, 'element name'], min=1), None, 'List of element(s) name'], ] def run(self, *elements): for element in elements: 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 .. warning:: Prior to the Sardana version 1.6.0 this macro was successfully reloading python libraries located in the MacroPath. The MacroPath is not a correct place to locate your python libraries. They may be successfully loaded on the MacroServer startup, but this can not be guaranteed. In order to use python libraries within your macro code, locate them in either of valid system PYTHONPATH or MacroServer PythonPath property (of the host where MacroServer runs). In order to achieve the previous behavior, just configure the the same directory in both system PYTHONPATH (or MacroServer's PythonPath) and MacroPath. .. 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 addmaclib(Macro): """Loads a new macro library. .. warning:: Keep in mind that macros from the new library can override macros already present in the system. """ param_def = [ ['macro_library_name', Type.String, None, 'The module name to be loaded (without extension)'] ] def prepare(self, macro_library_name): try: _ = self.getMacroLib(macro_library_name) except UnknownMacroLibrary: pass else: raise WrongParam('%s macro library is already loaded' % macro_library_name) def run(self, macro_library_name): old_macros = self.getMacroNames() new_macro_library = self.reloadMacroLibrary(macro_library_name) if new_macro_library.has_errors(): exc_info = new_macro_library.get_error() msg = "".join(traceback.format_exception_only(*exc_info[:2])) self.error(msg) else: new_metamacros = new_macro_library.get_macros() # retrieving the macro names from the metamacros new_macros = [metamacro.name for metamacro in new_metamacros] self.output("%s successfully loaded (found %d macros)", macro_library_name, len(new_macros)) # intersection between old and new indicates the overridden macros overridden_macros = list(set(old_macros) & set(new_macros)) if len(overridden_macros) > 0: msg = ('%s macro library has overridden the following ' + 'macros: %s' ) % (macro_library_name, overridden_macros) self.warning(msg) 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.6.1/src/sardana/macroserver/macros/ioregister.py0000644000234000017500000000411112555672636025532 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.debug(o) data = ioreg.writeIORegister(data) class read_ioreg(Macro): """Reads an output register""" param_def = [ ['input/output register', Type.IORegister, None, 'input/output register'] ] result_def = [ ['input/output register value', Type.Integer, None, 'value read from ' + 'the input/output register'] ] def run(self, ioreg): name = ioreg.getName() data = ioreg.readIORegister(force=True) o = "Reading " + name + " register " self.debug(o) return data sardana-1.6.1/src/sardana/macroserver/macros/lists.py0000644000234000017500000001604112555672636024521 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/mca.py0000644000234000017500000000312612555672636024123 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macros/scan.py0000644000234000017500000021160012555672636024305 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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(force=True)) 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 dmesh(mesh): '''2d relative grid scan. The relative mesh scan traces out a grid using motor1 and motor2. If first motor is at the position X before the scan begins, it will be scanned from X+m1_start_pos to X+m1_final_pos using the specified m1_nr_interv number of intervals. If the second motor is at the position Y before the scan begins, it will be scanned from Y+m2_start_pos to Y+m2_final_pos using the specified m2_nr_interv number of intervals. Each point is counted for the 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. Upon scan completion, it returns the motors to their original positions. ''' hints = copy.deepcopy(mesh.hints) hints['scan'] = 'dmesh' env = copy.deepcopy(mesh.env) 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._motion=self.getMotion( [m1,m2] ) self.originalPositions = numpy.array(self._motion.readPosition(force=True)) start1 = self.originalPositions[0] + m1_start_pos start2 = self.originalPositions[1] + m2_start_pos final1 = self.originalPositions[0] + m1_final_pos final2 = self.originalPositions[1] + m2_final_pos mesh.prepare(self, m1, start1, final1, m1_nr_interv, m2, start2, final2, m2_nr_interv, integ_time, bidirectional, **opts) def do_restore(self): self.info("Returning to start positions...") self._motion.move(self.originalPositions) 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 = [] 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' self._gScan = CSScan(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 dmeshc(meshc): '''2d relative continuous grid scan. The relative mesh scan traces out a grid using motor1 and motor2. If first motor is at the position X before the scan begins, it will be continuously scanned from X+m1_start_pos to X+m1_final_pos. If the second motor is at the position Y before the scan begins, it will be discrete scanned from Y+m2_start_pos to Y+m2_final_pos using the specified m2_nr_interv number of intervals. The scan considers the accel. and decel. times of the motor1, so the counts (for the integ_time seconds or monitor counts, if integ_time is negative) are executed while motor1 is moving with the constant velocity. Upon scan completion, it returns the motors to their original positions. ''' hints = copy.deepcopy(meshc.hints) hints['scan'] = 'dmeshc' env = copy.deepcopy(meshc.env) 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._motion=self.getMotion( [m1,m2] ) self.originalPositions = numpy.array(self._motion.readPosition(force=True)) start1 = self.originalPositions[0] + m1_start_pos start2 = self.originalPositions[1] + m2_start_pos final1 = self.originalPositions[0] + m1_final_pos final2 = self.originalPositions[1] + m2_final_pos meshc.prepare(self, m1, start1, final1, slow_down, m2, start2, final2, m2_nr_interv, integ_time, bidirectional, **opts) def do_restore(self): self.info("Returning to start positions...") self._motion.move(self.originalPositions) 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.6.1/src/sardana/macroserver/macros/sequence.py0000644000234000017500000000656512555672636025205 0ustar zreszelaComputing00000000000000import 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.6.1/src/sardana/macroserver/macros/standard.py0000644000234000017500000005555112555672636025174 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 import PyTango 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 run(self, *motor_list): show_dial = self.getViewOption(ViewOption.ShowDial) show_ctrlaxis = self.getViewOption(ViewOption.ShowCtrlAxis) pos_format = self.getViewOption(ViewOption.PosFormat) motor_width = 9 motors = {} # dict(motor name: motor obj) requests = {} # dict(motor name: request id) data = {} # dict(motor name: list of motor data) # sending asynchronous requests: neither Taurus nor Sardana extensions # allow asynchronous requests - use PyTango asynchronous request model for motor in motor_list: name = motor.getName() motors[name] = motor args = ('position',) if show_dial: args += ('dialposition',) _id = motor.read_attributes_asynch(args) requests[name] = _id motor_width = max(motor_width, len(name)) data[name] = [] # get additional motor information (ctrl name & axis) if show_ctrlaxis: for name, motor in motors.iteritems(): ctrl_name = self.getController(motor.controller).name axis_nb = str(getattr(motor, "axis")) data[name].extend((ctrl_name, axis_nb)) motor_width = max(motor_width, len(ctrl_name), len(axis_nb)) # collect asynchronous replies while len(requests) > 0: req2delete = [] for name, _id in requests.iteritems(): motor = motors[name] try: attrs = motor.read_attributes_reply(_id) for attr in attrs: value = attr.value if value == None: value = float('NaN') data[name].append(value) req2delete.append(name) except PyTango.AsynReplyNotArrived, e: continue except PyTango.DevFailed: data[name].append('NaN') if show_dial: data[name].append('NaN') req2delete.append(name) self.debug('Error when reading %s position(s)' % name) self.debug('Details:', exc_info=1) continue # removing motors which alredy replied for name in req2delete: requests.pop(name) # define format for numerical values fmt = '%c*.%df' % ('%', motor_width - 5) if pos_format > -1: fmt = '%c*.%df' % ('%', int(pos_format)) # prepare row headers and formats row_headers = [] t_format = [] if show_ctrlaxis: row_headers += ['Ctrl', 'Axis'] t_format += ['%*s', '%*s'] row_headers.append('User') t_format.append(fmt) if show_dial: row_headers.append('Dial') t_format.append(fmt) # sort the data dict by keys col_headers = [] values = [] for mot_name, mot_values in sorted(data.items()): col_headers.append([mot_name]) # convert name to list values.append(mot_values) # create and print table table = Table(values, elem_fmt=t_format, col_head_str=col_headers, col_head_width=motor_width, row_head_str=row_headers) 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""" param_def = [ ['filter', ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=0, max=1), '.*', 'a regular expression filter'], ] def prepare(self, *filter, **opts): self.all_motors = self.findObjs(filter, type_class=Type.Moveable) self.table_opts = {} def run(self, *filter): 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""" param_def = [ ['filter', ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=0, max=1), '.*', 'a regular expression filter'], ] def run(self, *filter): self.execMacro('wa', *filter, **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) show_ctrlaxis = self.getViewOption(ViewOption.ShowCtrlAxis) pos_format = self.getViewOption(ViewOption.PosFormat) for motor in motor_list: max_len = 0 if show_ctrlaxis: axis_nb = getattr(motor, "axis") ctrl_name = self.getController(motor.controller).name max_len = max(max_len, len(ctrl_name), len(str(axis_nb))) name = motor.getName() max_len = max(max_len, len(name)) max_len = max_len + 5 if max_len < 14: max_len = 14 # Length of 'Not specified' str_fmt = "%c%ds" % ('%', int(max_len)) name = str_fmt % name motor_names.append([name]) posObj = motor.getPositionObj() if pos_format > -1: fmt = '%c.%df' % ('%', int(pos_format)) try: val1 = fmt % motor.getPosition(force=True) val1 = str_fmt % val1 except: val1 = str_fmt % motor.getPosition(force=True) val2 = str_fmt % posObj.getMaxValue() val3 = str_fmt % posObj.getMinValue() if show_ctrlaxis: valctrl = str_fmt % (ctrl_name) valaxis = str_fmt % str(axis_nb) upos = map(str, [valctrl, valaxis, ' ', val2, val1, val3]) else: upos = map(str, ['', val2, val1, val3]) pos_data = upos if show_dial: try: val1 = fmt % motor.getDialPosition(force=True) val1 = str_fmt % val1 except: val1 = str_fmt % motor.getDialPosition(force=True) dPosObj = motor.getDialPositionObj() val2 = str_fmt % dPosObj.getMaxValue() val3 = str_fmt % dPosObj.getMinValue() dpos = map(str, [val2, val1, val3]) pos_data += [''] + dpos motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 5) * 2 row_head_str = [] if show_ctrlaxis: row_head_str += ['Ctrl', 'Axis'] 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): 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.6.1/src/sardana/macroserver/scan/0000755000234000017500000000000012555673001022432 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/scan/recorder/0000755000234000017500000000000012555673001024237 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/macroserver/scan/recorder/__init__.py0000644000234000017500000000222312555672636026364 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/scan/recorder/datarecorder.py0000644000234000017500000001347012555672636027272 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import Logger from taurus.core.util.enumeration import Enumeration 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): try: self._addCustomData(value, name, **kwargs) except Exception, e: raise RuntimeError('%s can not process custom data: %s' % (self.__class__.__name__, e)) 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.6.1/src/sardana/macroserver/scan/recorder/output.py0000644000234000017500000002475312555672636026201 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.codecs import CodecFactory from taurus.core.util.containers import CaselessList from sardana.macroserver.scan.recorder.datarecorder import DataRecorder from sardana.macroserver.scan.recorder.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' ''' #try to convert to list to avoid serialization problems try: value = value.tolist() except: pass macro_id = self._stream.getID() 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()) endts = recordlist.getEnvironValue('endts') startts = recordlist.getEnvironValue('startts') totaltimets = endts - startts deadtime_perc = deadtime * 100.0 / totaltimets motiontime_perc = motiontime * 100.0 / totaltimets info_string = 'Scan #%s ended at %s, taking %s.' + \ 'Dead time %.1f%% (motion dead time %.1f%%)' self._stream.info(info_string % (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.6.1/src/sardana/macroserver/scan/recorder/sharedmemory.py0000644000234000017500000002301312555672636027324 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 time import numpy import operator from sardana.macroserver.scan.recorder.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.6.1/src/sardana/macroserver/scan/recorder/storage.py0000644000234000017500000015121312555672636026275 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 import PyTango from sardana.taurus.core.tango.sardana import PlotType from sardana.macroserver.macro import Type from sardana.macroserver.scan.recorder.datarecorder import DataRecorder, \ DataFormats, SaveModes from taurus.core.util.containers import chunks 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() if filename: self.setFileName(self.base_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.currentlist = None # # construct the filename, e.g. : /dir/subdir/etcdir/prefix_00123.fio # tpl = filename.rpartition('.') try: # For avoiding error when calling at __init__ 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) except: self.filename = "%s_%s.%s" % (tpl[0], "[ScanId]", tpl[2]) 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: if c == "timestamp" or c == "point_nb": continue 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' } supported_dtypes = ('float32','float64','int8', 'int16','int32','int64','uint8', 'uint16','uint32','uint64') 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): '''Prepares and writes the scan header.''' 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 # prepare pre-scan snapshot snapshot_labels, snapshot_values = self._preparePreScanSnapshot(env) # format scan header data = { 'serialno': serialno, 'title': env['title'], 'user': env['user'], 'epoch': epoch, 'starttime': start_time.ctime(), 'nocols': len(names), 'labels': ' '.join(labels) } #Compatibility with PyMca if os.path.exists(self.filename): header = '\n' else: header = '' header += '#S %(serialno)s %(title)s\n' header += '#U %(user)s\n' header += '#D %(epoch)s\n' header += '#C Acquisition started at %(starttime)s\n' # add a pre-scan snapshot (sep is two spaces for labels!!) header += self._prepareMultiLines('O', ' ', snapshot_labels) header += self._prepareMultiLines('P', ' ', snapshot_values) header += '#N %(nocols)s\n' header += '#L %(labels)s\n' self.fd = open(self.filename,'a') self.fd.write(header % data ) self.fd.flush() def _prepareMultiLines(self, character, sep, items_list): '''Translate list of lists of items into multiple line string :param character (string): each line will start # :sep: separator (string): separator to use between items :param items_list (list):list of lists of items :return multi_lines (string): string with all the items''' multi_lines = '' for nr, items in enumerate(items_list): start = '#%s%d ' % (character, nr) items_str = sep.join(map(str, items)) end = '\n' line = start + items_str + end multi_lines += line return multi_lines def _preparePreScanSnapshot(self, env): '''Extract pre-scan snapshot, filters elements of shape different than scalar and split labels and values into chunks of 8 items. :param: env (dict) scan environment :return: labels, values (tuple) labels - list of chunks with 8 elements containing labels values - list of chunks with 8 elements containing values ''' # preScanSnapShot is a list o ColumnDesc objects pre_scan_snapshot = env.get('preScanSnapShot',[]) labels = []; values = [] for column_desc in pre_scan_snapshot: shape = column_desc.shape # shape is a tuple of dimensions label = column_desc.label dtype = column_desc.dtype pre_scan_value = column_desc.pre_scan_value # skip items with shape different than scalar if len(shape) > 0: self.info('Pre-scan snapshot of "%s" will not be stored.' + \ ' Reason: value is non-scalar', label) continue if dtype not in self.supported_dtypes: self.info('Pre-scan snapshot of "%s" will not be stored.' + \ ' Reason: type %s not supported', label, dtype) continue labels.append(label) values.append(pre_scan_value) # split labels in chunks o 8 items labels_chunks = list(chunks(labels, 8)) values_chunks = list(chunks(values, 8)) return labels_chunks, values_chunks 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.6.1/src/sardana/macroserver/scan/__init__.py0000644000234000017500000000212012555672636024553 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/scan/gscan.py0000644000234000017500000026054312555672636024126 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import Logger from taurus.core.util.user import USER_NAME from taurus.core.tango import FROM_TANGO_TO_STR_TYPE 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 sardana.macroserver.scan.scandata import ColumnDesc, MoveableDesc, \ ScanFactory, ScanDataEnvironment from sardana.macroserver.scan.recorder import OutputRecorder, JsonRecorder, \ SharedMemoryRecorder, FileRecorder from sardana.taurus.core.tango.sardana.pool import Ready 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: raise 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 ScanFile ") 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 # The physical motion object contains only physical motors - no pseudo # motors (in case the pseudomotors are involved in the scan, # it comprarises the underneath physical motors) # This is due to the fact that the CTScan coordinates the # pseudomotors' underneeth physical motors on on their constant # velocity in contrary to the the CScan which do not coordinate them 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._setFastMotions() self.macro.info("Correcting overshoot...") self.motion.move(restore_positions) self.do_restore() 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 _setFastMotions(self, motors=None): '''make given motors go at their max speed and accel''' if motors is None: motors = [b.get('moveable') for b in self._backup if b is not None] for motor in motors: try: motor.setVelocity(self.get_max_top_velocity(motor)) motor.setAcceleration(self.get_min_acc_time(motor)) motor.setDeceleration(self.get_min_dec_time(motor)) self.debug("%s put into fast motion", motor) except: self.macro.warning("Failed to put %s into fast motion", 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(): self.on_waypoints_end() return # prepare motor(s) with the velocity required for synchronization 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(): self.on_waypoints_end() return 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(): self.on_waypoints_end() return # 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(): self.on_waypoints_end() return 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(): self.on_waypoints_end() return #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() for point_nr, position in enumerate(np.linspace(start, \ final, nr_of_points)): 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): """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) .. todo:: Unify this method for all the continuous scans. Hint: use the motion property and return the _physical_motion member instead of _motion or in both cases: CSScan and CTScan coordinate the physical motors' velocit. """ self.macro.debug("on_waypoints_end() entering...") self.set_all_waypoints_finished(True) if restore_positions is not None: self._setFastMotions() self.macro.info("Correcting overshoot...") self._physical_motion.move(restore_positions) self.do_restore() self.motion_end_event.set() self.motion_event.set() 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.6.1/src/sardana/macroserver/scan/scandata.py0000644000234000017500000002160112555672636024577 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.singleton import Singleton from sardana.macroserver.scan.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.6.1/src/sardana/macroserver/__init__.py0000644000234000017500000000204712555672636023637 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/basetypes.py0000644000234000017500000000721312555672636024077 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/macroserver/macro.py0000644000234000017500000024612512555672636023210 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sys import time import copy import types import ctypes import weakref import operator import StringIO import threading import traceback from taurus.core.util.log import Logger from taurus.core.util.prop import propertx from taurus.console.table import Table from taurus.console.list import List from sardana.sardanadefs import State from sardana.util.wrap import wraps from sardana.macroserver.msparameter import Type, ParamType, ParamRepeat from sardana.macroserver.msexception import StopException, AbortException, \ MacroWrongParameterType, UnknownEnv, UnknownMacro, LibraryError from sardana.macroserver.msoptions import ViewOption from sardana.taurus.core.tango.sardana.pool import PoolElement 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 elements: the macro object and the result of preparing the macro :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: macro result""" # 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._getViewOption(name) @mAPI def getViewOptions(self): vo = self._getViewOptions() # ensure that all view options known by sardana are present, in case # there were missing ones, update _ViewOptions dictionary after # initializing missing options with the default values ivo = copy.deepcopy(vo) ViewOption.init_options(ivo) if vo != ivo: self.setEnv('_ViewOptions', vo) return ivo @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): '''Gets _ViewOption dictionary. If it is not defined in the environment, sets it with the default values dictionary and returns it. ''' try: vo = self.getEnv('_ViewOptions') except UnknownEnv: vo = ViewOption.init_options(dict()) self.setEnv('_ViewOptions', vo) return vo def _getViewOption(self, name): '''Gets _ViewOption of a given name. If it is not defined in the environment, sets it to a default value and returns it. ''' view_options = self._getViewOptions() if not view_options.has_key(name): ViewOption.reset_option(view_options, name) self.setEnv('_ViewOptions', view_options) return view_options[name] 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.6.1/src/sardana/macroserver/macro_template.txt0000644000234000017500000000015312555672636025257 0ustar zreszelaComputing00000000000000@macro() def @macro_name@(self): """Macro @macro_name@""" self.output("Running @macro_name@...") sardana-1.6.1/src/sardana/macroserver/macroserver.py0000644000234000017500000007764312555672636024446 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 from taurus.core import TaurusEventType from taurus.core.util.log import Logger from taurus.core.util.containers import CaselessDict 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 sardana.taurus.core.tango.sardana.motion import Motion, MotionGroup from sardana.taurus.core.tango.sardana.pool import registerExtensions from sardana.macroserver.msbase import MSObject from sardana.macroserver.mscontainer import MSContainer from sardana.macroserver.msdoor import MSDoor from sardana.macroserver.msmacromanager import MacroManager from sardana.macroserver.mstypemanager import TypeManager from sardana.macroserver.msenvmanager import EnvironmentManager from sardana.macroserver.msparameter import ParamType from sardana.macroserver.msexception import UnknownMacroLibrary 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.6.1/src/sardana/macroserver/msbase.py0000644000234000017500000000514712555672636023356 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 = MSBaseObject.serialize(self, *args, **kwargs) kwargs = SardanaObjectID.serialize(self, *args, **kwargs) return kwargs sardana-1.6.1/src/sardana/macroserver/mscontainer.py0000644000234000017500000000236712555672636024427 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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): pass sardana-1.6.1/src/sardana/macroserver/msdoor.py0000644000234000017500000003030112555672636023375 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 weakref import collections from taurus.core.util.log import Logger from sardana import ElementType from sardana.sardanaevent import EventType from sardana.macroserver.msbase import MSObject from sardana.macroserver.msparameter import Type from sardana.macroserver.msexception import MacroServerException 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 MacroServerException("No macro has run so far " + \ "or the macro data was not preserved.") 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.6.1/src/sardana/macroserver/msenvmanager.py0000644000234000017500000004060212555672636024562 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers import CaselessDict from sardana.macroserver.msmanager import MacroServerManager from sardana.macroserver.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.6.1/src/sardana/macroserver/msexception.py0000644000234000017500000000402712555672636024436 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.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.6.1/src/sardana/macroserver/msmacromanager.py0000644000234000017500000013566112555672636025105 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 re import os import sys import copy import inspect import functools import traceback from lxml import etree from PyTango import DevFailed from taurus.core.util.log import Logger from taurus.core.util.codecs import 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 sardana.macroserver.msmanager import MacroServerManager from sardana.macroserver.msmetamacro import MACRO_TEMPLATE, MacroLibrary, \ MacroClass, MacroFunction from sardana.macroserver.msparameter import ParamDecoder from sardana.macroserver.macro import Macro, MacroFunc from sardana.macroserver.msexception import UnknownMacroLibrary, \ LibraryError, UnknownMacro, MissingEnv, AbortException, StopException, \ MacroServerException, UnknownEnv _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: # use normcase to treat case insensitivity of paths on # certain platforms e.g. Windows if os.path.normcase(inspect.getabsfile(macro)) !=\ os.path.normcase(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: # use normcase to treat case insensitivity of paths on # certain platforms e.g. Windows if os.path.normcase(inspect.getabsfile(macro)) !=\ os.path.normcase(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, file_name in macro_file_names.iteritems(): dir_name = os.path.dirname(file_name) path = [dir_name] try: self.reloadMacroLib(mod_name, path) 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: 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. 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() return mod_manager.reloadModule(module_name, path=None) 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) if macro_lib.has_macros(): 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,)) result = macro_obj.getResult() # sending result only if we are the top most macro if macro_obj.hasResult() and macro_obj.getParentMacro() is None: result_repr = self.__preprocessResult(result) door.debug("sending result %s", result_repr) self.sendResult(result_repr) 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() # decide whether to preserve the macro data env_var_name = 'PreserveMacroData' try: preserve_macro_data = macro_obj.getEnv(env_var_name) except UnknownEnv: preserve_macro_data = True if not preserve_macro_data: self.debug('Macro data will not be preserved. ' + \ 'Set "%s" environment variable ' % env_var_name + \ 'to True in order to change it.') self._macro_pointer = None return result def _popMacro(self): self._macro_stack.pop() length = len(self._macro_stack) if length > 0: self._macro_pointer = self._macro_stack[-1] 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.6.1/src/sardana/macroserver/msmanager.py0000644000234000017500000000351212555672636024050 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log 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.CLEANED sardana-1.6.1/src/sardana/macroserver/msmetamacro.py0000644000234000017500000002416612555672636024416 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.macroserver.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 has_macros = SardanaLibrary.has_metas 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): '''Builds a list of parameters, each of them represented by a dictionary containing information: name, type, default_value, description, min and max values. In case of simple parameters, type is the parameter type. In case of ParamRepeat, type is a list containing definition of the param repeat. ''' 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.6.1/src/sardana/macroserver/msoptions.py0000644000234000017500000000366112555672636024136 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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, 'ShowCtrlAxis' : False, 'PosFormat': -1, } @classmethod def init_options(cls, d): '''Init missing options with the default values. ''' diff = set(cls._DEFAULT_VIEW_OPTIONS).difference(d) if len(diff) > 0: for key in diff: d[key] = cls._DEFAULT_VIEW_OPTIONS[key] 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.6.1/src/sardana/macroserver/msparameter.py0000644000234000017500000003243112555672636024420 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers import CaselessDict from sardana import ElementType, INTERFACES_EXPANDED from sardana.macroserver.msbase import MSBaseObject from sardana.macroserver.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 # neither pool nor macroserver contains any element with this name raise UnknownParamObj('%s with name %s does not exist' % \ (self._name, name)) 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 # neither pool nor macroserver contains any element with this name raise UnknownParamObj('%s with name %s does not exist' % \ (self._name, name)) 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() 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) obj_list = [] str_idx = 0 for i, par_def in enumerate(def_list): name = par_def['name'] type_class = par_def['type'] def_val = par_def['default_value'] if str_idx == str_len: if def_val is None: if not isinstance(type_class, list): raise MissingParam, "'%s' not specified" % name elif isinstance(type_class, list): min_rep = par_def['min'] if min_rep > 0: msg = "'%s' demands at least %d values" %\ (name, min_rep) raise WrongParam, msg new_obj_list = [] if not def_val is None: new_obj_list.append(def_val) else: if isinstance(type_class, list): 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 except UnknownParamObj, e: raise WrongParam, 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 = par_def['name'] param_def = par_def['type'] min_rep = par_def['min'] max_rep = par_def['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:], 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.6.1/src/sardana/macroserver/mstypemanager.py0000644000234000017500000001171512555672636024756 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.macroserver.msparameter import Type, ParamType, AbstractParamTypes from sardana.macroserver.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 module_name in self._modules: 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 _, 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 _, 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.6.1/src/sardana/pool/0000755000234000017500000000000012555673001020127 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/pool/poolcontrollers/0000755000234000017500000000000012555673001023367 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/pool/poolcontrollers/DiscretePseudoMotorController.py0000644000234000017500000001471212555672636031772 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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'] = float 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.6.1/src/sardana/pool/poolcontrollers/DummyCounterTimerController.py0000644000234000017500000001352512555672636031464 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontrollers/DummyIORController.py0000644000234000017500000000356412555672636027477 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontrollers/DummyMotorController.py0000644000234000017500000006500212555672636030141 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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: m = BaseMotion() m.curr_pos = 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) 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.6.1/src/sardana/pool/poolcontrollers/DummyOneDController.py0000644000234000017500000001700212555672636027663 0ustar zreszelaComputing00000000000000############################################################################## ## ## 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.6.1/src/sardana/pool/poolcontrollers/DummyTwoDController.py0000644000234000017500000001705212555672636027720 0ustar zreszelaComputing00000000000000############################################################################## ## ## 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.6.1/src/sardana/pool/poolcontrollers/DummyZeroDController.py0000644000234000017500000000447512555672636030073 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontrollers/IoverI0.py0000644000234000017500000000315112555672636025233 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontrollers/Slit.py0000644000234000017500000000737412555672636024704 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontrollers/TangoController.py0000644000234000017500000001510512555672636027074 0ustar zreszelaComputing00000000000000############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers 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.6.1/src/sardana/pool/poolcontrollers/__init__.py0000644000234000017500000000173512555672636025523 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/test/0000755000234000017500000000000012555673001021106 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/pool/test/__init__.py0000644000234000017500000000207312555672636023236 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 pool test module""" from .fake import * from .helper import * from .dummyconfs import * sardana-1.6.1/src/sardana/pool/test/dummyconfs.py0000644000234000017500000000435012555672636023663 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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__ = ['dummyCounterTimerConf01', 'dummyMeasurementGroupConf01', 'dummyPoolCTCtrlConf01'] # Pool Elements '''Minimum configuration to create a Pool CounterTimer''' dummyCounterTimerConf01 = { 'axis': 1, 'ctrl': None, 'full_name': '', 'id': 2, 'name': '', 'pool': None } '''Minimum configuration to create a Pool MeasurementGroup''' dummyMeasurementGroupConf01 = { 'full_name': '', 'id': 3, 'name': '', 'pool': None, 'user_elements': [2] } # Pool Ctrls '''Minimum configuration to create a Pool CounterTimer controller''' dummyPoolCTCtrlConf01 = { 'class_info': None, 'full_name': '', 'id': 1, 'klass': 'DummyCounterTimerController', 'lib_info': None, 'library': 'DummyCounterTimerController.py', 'name': '', 'pool': None, 'properties': {}, 'role_ids': '', 'type': 'CTExpChannel' } sardana-1.6.1/src/sardana/pool/test/fake.py0000644000234000017500000000302412555672636022402 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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__ = ['FakePool'] from sardana.pool.poolcontrollermanager import ControllerManager class FakePool(object): ''' Fake class to simulate the behaviour of the Pool class ''' acq_loop_sleep_time = 0.1 acq_loop_states_per_value = 10 elements = {} def __init__(self): self.ctrl_manager = ControllerManager() self.ctrl_manager.set_pool(self) self.ctrl_manager.setControllerPath([]) def add_element(self, element): self.elements[element.id] = element def get_element(self, id): return self.elements[id] sardana-1.6.1/src/sardana/pool/test/helper.py0000644000234000017500000000433112555672636022755 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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__ = ['createPoolController', 'createPoolCounterTimer', 'createPoolMeasurementGroup'] from sardana.pool.poolcontroller import PoolController from sardana.pool.poolcountertimer import PoolCounterTimer from sardana.pool.poolmeasurementgroup import PoolMeasurementGroup def createPoolController(pool, conf): '''Method to create a PoolController using a configuration dictionary ''' kwargs = conf ctrl_manager = pool.ctrl_manager ctrl_class_info = None ctrl_lib_info = ctrl_manager.getControllerLib(kwargs['library']) if ctrl_lib_info is not None: ctrl_class_info = ctrl_lib_info.get_controller(kwargs['klass']) kwargs['pool'] = pool kwargs['lib_info'] = ctrl_lib_info kwargs['class_info'] = ctrl_class_info return PoolController(**kwargs) def createPoolCounterTimer(pool, poolcontroller, conf): '''Method to create a PoolCounterTimer using a configuration dictionary ''' kwargs = conf kwargs['pool'] = pool kwargs['ctrl'] = poolcontroller return PoolCounterTimer(**kwargs) def createPoolMeasurementGroup(pool, conf): '''Method to create a PoolMeasurementGroup using a configuration dictionary ''' kwargs = conf kwargs['pool'] = pool return PoolMeasurementGroup(**kwargs) sardana-1.6.1/src/sardana/pool/test/test_ctacquisition.py0000644000234000017500000000625712555672636025425 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.external import unittest from sardana.pool.poolmeasurementgroup import PoolMeasurementGroup from sardana.pool.test import (FakePool, createPoolController, createPoolMeasurementGroup, createPoolCounterTimer, dummyCounterTimerConf01, dummyPoolCTCtrlConf01, dummyMeasurementGroupConf01) class PoolMeasurementGroupTestCase(unittest.TestCase): """Class used for an acquisition done by a Measurement Group with a dummyCounterTimer channel. The Measurement Group runs with a freshly created fake Pool which does not depends on the Sardana Pool. """ def setUp(self): """Setup: - Use resources for Controller, CounterTimer and MeasurementGroup features. - Create Controller, CounterTimer and MeasurementGroup. """ pool = FakePool() pc = createPoolController(pool, dummyPoolCTCtrlConf01) pct = createPoolCounterTimer(pool, pc, dummyCounterTimerConf01) pc.add_element(pct) pool.add_element(pc) pool.add_element(pct) self.pmg = createPoolMeasurementGroup(pool, dummyMeasurementGroupConf01) self._pct = pct # keep a reference to use it in test_acquisition def test_init(self): """check that the PoolMeasurementGroup is correctly instantiated""" msg = 'PoolMeasurementGroup constructor does not create ' +\ 'PoolMeasurementGroup instance' self.assertIsInstance(self.pmg, PoolMeasurementGroup, msg) def test_acquisition(self): """Test acquisition using the created measurement group without using a Sardana pool.""" msg = 'Pool Measurement Group does not acquire' integ_time = 1 self.pmg.set_integration_time(integ_time) self.pmg.start_acquisition() acq = self.pmg.get_acquisition()._ct_acq # 'acquiring..' while acq.is_running(): time.sleep(0.05) values = acq.raw_read_value_loop() self.assertEqual(values[self._pct].value, integ_time, msg) def tearDown(self): unittest.TestCase.tearDown(self) self.pmg = None self._pct = None sardana-1.6.1/src/sardana/pool/test/test_poolcontroller.py0000644000234000017500000000344312555672636025615 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.external import unittest from sardana.pool.test import (FakePool, createPoolController, dummyPoolCTCtrlConf01) from sardana.pool.poolcontroller import PoolController class PoolControllerTestCase(unittest.TestCase): """Unittest of PoolController Class""" def setUp(self): """Instantiate a fake Pool and create a Controller""" pool = FakePool() self.pc = createPoolController(pool, dummyPoolCTCtrlConf01) def test_init(self): """Verify that the created Controller is an instance of PoolController""" msg = 'PoolController constructor does not create ' +\ 'PoolController instance' self.assertIsInstance(self.pc, PoolController, msg) def tearDown(self): unittest.TestCase.tearDown(self) self.pc = None sardana-1.6.1/src/sardana/pool/test/test_poolcontrollermanager.py0000644000234000017500000000320012555672636027137 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.external import unittest from sardana.pool.poolcontrollermanager import ControllerManager class ControllerManagerTestCase(unittest.TestCase): """Unittest of ControllerManager Class""" def setUp(self): """Create a ControllerManager""" self.cm = ControllerManager() def test_init(self): """Verify that the created ControllerManager is a ControllerManager instance.""" msg = 'ControllerManager constructor does not create ' +\ 'ControllerManager instance' self.assertIsInstance(self.cm, ControllerManager, msg) def tearDown(self): unittest.TestCase.tearDown(self) self.cm = Nonesardana-1.6.1/src/sardana/pool/test/test_poolcountertimer.py0000644000234000017500000000371312555672636026152 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.external import unittest from sardana.pool.poolcountertimer import PoolCounterTimer from sardana.pool.test import (FakePool, createPoolController, createPoolCounterTimer, dummyCounterTimerConf01, dummyPoolCTCtrlConf01) class PoolCounterTimerTestCase(unittest.TestCase): """Unittest of PoolCounterTimer Class""" def setUp(self): """Create a Controller and a CounterTimer element""" pool = FakePool() pc = createPoolController(pool, dummyPoolCTCtrlConf01) self.pct = createPoolCounterTimer(pool, pc, dummyCounterTimerConf01) def test_init(self): """Verify that the created CounterTimer is a PoolCounterTimer instance.""" msg = 'PoolCounterTimer constructor does not create ' +\ 'PoolCounterTimer instance' self.assertIsInstance(self.pct, PoolCounterTimer, msg) def tearDown(self): unittest.TestCase.tearDown(self) self.pct = Nonesardana-1.6.1/src/sardana/pool/__init__.py0000644000234000017500000000230712555672636022257 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/controller.py0000644000234000017500000015220012555672636022701 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 from taurus.core.taurushelper import getLogLevel from taurus.core.util.log import Logger from sardana import DataAccess from sardana.sardanavalue import SardanaValue from sardana.pool.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(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 :return: any relevant information e.g. response of the controller :rtype: str""" 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`""" dict_ids = self._getPoolController().get_element_ids() dict_axis = self._getPoolController().get_element_axis() pseudo_motor_ids = [] for akey, aname in dict_axis.items(): pseudo_motor_ids.append(dict_ids.keys()[dict_ids.values().index(aname)]) return self._getElem(index_or_role, self.pseudo_motor_roles, self.__pseudo_motor_role_elements, pseudo_motor_ids) # 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.6.1/src/sardana/pool/pool.py0000644000234000017500000006404112555672636021474 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolobject import PoolObject from sardana.pool.poolcontainer import PoolContainer from sardana.pool.poolcontroller import PoolController from sardana.pool.poolmonitor import PoolMonitor from sardana.pool.poolmetacontroller import TYPE_MAP_OBJ from sardana.pool.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.6.1/src/sardana/pool/poolacquisition.py0000644000234000017500000004766412555672636023761 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import DebugIt from taurus.core.util.enumeration import Enumeration from sardana import State, ElementType, TYPE_TIMERABLE_ELEMENTS from sardana.sardanathreadpool import get_thread_pool from sardana.pool.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.6.1/src/sardana/pool/poolaction.py0000644000234000017500000005530212555672636022672 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import Logger from sardana import State from sardana.sardanathreadpool import get_thread_pool from sardana.pool.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.6.1/src/sardana/pool/poolbasechannel.py0000644000234000017500000001324012555672636023653 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolelement import PoolElement from sardana.pool.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.6.1/src/sardana/pool/poolbaseelement.py0000644000234000017500000003161712555672636023704 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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)sardana-1.6.1/src/sardana/pool/poolbasegroup.py0000644000234000017500000003577612555672636023421 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolexternal import PoolExternalObject from sardana.pool.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.6.1/src/sardana/pool/poolbaseobject.py0000644000234000017500000000370012555672636023511 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontainer.py0000644000234000017500000000335212555672636023375 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolcontroller.py0000644000234000017500000010003512555672636023572 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers import CaselessDict from sardana import State, ElementType, TYPE_TIMERABLE_ELEMENTS from sardana.sardanaevent import EventType from sardana.sardanavalue import SardanaValue from sardana.pool.poolextension import translate_ctrl_value from sardana.pool.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 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 = None self._set_state_info(state_info, propagate=propagate) return self._status _STD_STATUS = '{name} is {state}' 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*. :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_info state_str = State[state] new_status = self._STD_STATUS.format(name=self.name, state=state_str) return status_info[0], new_status 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] = SardanaValue(exc_info=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.6.1/src/sardana/pool/poolcontrollermanager.py0000644000234000017500000005112512555672636025132 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 os import re import sys import copy import types import inspect from taurus.core import ManagerState from taurus.core.util.log import Logger from taurus.core.util.singleton import Singleton from sardana.sardanamodulemanager import ModuleManager from sardana.pool import controller from sardana.pool.poolexception import UnknownController from sardana.pool.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 # use normcase to treat case insensitivity of paths on # certain platforms e.g. Windows if os.path.normcase(inspect.getabsfile(klass)) !=\ os.path.normcase(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) from sardana.macroserver.msparameter import ParamDecoder out_par_list = 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.6.1/src/sardana/pool/poolcountertimer.py0000644000234000017500000000407412555672636024135 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/pooldefs.py0000644000234000017500000000241012555672636022326 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.taurus.core.tango.sardana import AcqTriggerType, AcqMode #: A constant defining the controller API version currently supported ControllerAPI = 1.1 sardana-1.6.1/src/sardana/pool/poolelement.py0000644000234000017500000001215212555672636023042 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/poolexception.py0000644000234000017500000000264212555672636023412 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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): pass sardana-1.6.1/src/sardana/pool/poolextension.py0000644000234000017500000000557012555672636023433 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolexternal.py0000644000234000017500000001002612555672636023231 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/poolgroupelement.py0000644000234000017500000000756312555672636024131 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolbaseelement import PoolBaseElement from sardana.pool.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.6.1/src/sardana/pool/poolinstrument.py0000644000234000017500000000664212555672636023630 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/poolioregister.py0000644000234000017500000001175212555672636023572 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.sardanaattribute import SardanaAttribute from sardana.pool.poolelement import PoolElement from sardana.pool.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.6.1/src/sardana/pool/poolmeasurementgroup.py0000644000234000017500000005453412555672636025025 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana import State, ElementType, \ TYPE_EXP_CHANNEL_ELEMENTS, TYPE_TIMERABLE_ELEMENTS from sardana.sardanaevent import EventType from sardana.pool.pooldefs import AcqMode, AcqTriggerType from sardana.pool.poolgroupelement import PoolGroupElement from sardana.pool.poolacquisition import PoolAcquisition from sardana.pool.poolexternal import PoolExternalObject from sardana.taurus.core.tango.sardana import PlotType, Normalization #---------------------------------------------- # 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.6.1/src/sardana/pool/poolmetacontroller.py0000644000234000017500000003353512555672636024453 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 types import inspect from taurus.core.util.containers import CaselessDict from sardana import DataType, DataFormat, DataAccess, \ to_dtype_dformat, to_daccess, \ ElementType, TYPE_ELEMENTS, InvalidId from sardana.sardanameta import SardanaLibrary, SardanaClass from sardana.pool.poolmotor import PoolMotor from sardana.pool.poolpseudomotor import PoolPseudoMotor from sardana.pool.poolmotorgroup import PoolMotorGroup from sardana.pool.poolmeasurementgroup import PoolMeasurementGroup from sardana.pool.poolcountertimer import PoolCounterTimer from sardana.pool.poolzerodexpchannel import Pool0DExpChannel from sardana.pool.poolonedexpchannel import Pool1DExpChannel from sardana.pool.pooltwodexpchannel import Pool2DExpChannel from sardana.pool.poolpseudocounter import PoolPseudoCounter from sardana.pool.poolinstrument import PoolInstrument from sardana.pool.poolioregister import PoolIORegister from sardana.pool.poolcontroller import PoolController, \ PoolPseudoMotorController, PoolPseudoCounterController from sardana.pool.controller import Controller, MotorController, \ CounterTimerController, ZeroDController, OneDController, TwoDController, \ PseudoMotorController, PseudoCounterController, IORegisterController from sardana.pool.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.6.1/src/sardana/pool/poolmonitor.py0000644000234000017500000001253412555672636023104 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 time import threading from taurus.core.util.log import Logger from sardana import ElementType, TYPE_PSEUDO_ELEMENTS from sardana.pool.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.6.1/src/sardana/pool/poolmotion.py0000644000234000017500000004651112555672636022724 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import DebugIt from taurus.core.util.enumeration import Enumeration from sardana import State from sardana.pool.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 sardana.pool.poolelement import PoolElement from sardana.pool.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.6.1/src/sardana/pool/poolmotorgroup.py0000644000234000017500000002363412555672636023635 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolgroupelement import PoolGroupElement from sardana.pool.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.6.1/src/sardana/pool/poolmoveable.py0000644000234000017500000000307012555672636023202 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/pool/poolobject.py0000644000234000017500000000333012555672636022655 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/poolonedexpchannel.py0000644000234000017500000000460612555672636024411 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/poolpseudocounter.py0000644000234000017500000003321212555672636024310 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolexception import PoolException from sardana.pool.poolbasechannel import PoolBaseChannel from sardana.pool.poolbasegroup import PoolBaseGroup from sardana.pool.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.6.1/src/sardana/pool/poolpseudomotor.py0000644000234000017500000005702712555672636024003 0ustar zreszelaComputing00000000000000#!/usr/bin/env python from sardana.sardanavalue import SardanaValue ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolbaseelement import PoolBaseElement from sardana.pool.poolelement import PoolElement from sardana.pool.poolbasegroup import PoolBaseGroup from sardana.pool.poolmotion import PoolMotion from sardana.pool.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.6.1/src/sardana/pool/pooltwodexpchannel.py0000644000234000017500000000452512555672636024441 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.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.6.1/src/sardana/pool/poolutil.py0000644000234000017500000000375412555672636022376 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers 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.6.1/src/sardana/pool/poolzerodexpchannel.py0000644000234000017500000002363612555672636024613 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.pool.poolbasechannel import PoolBaseChannel from sardana.pool.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.6.1/src/sardana/spock/0000755000234000017500000000000012555673001020275 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/spock/ipython_00_10/0000755000234000017500000000000012555673001022566 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/spock/ipython_00_10/__init__.py0000644000234000017500000000207012555672636024713 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/ipython_00_10/genutils.py0000644000234000017500000010264112555672636025013 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 from taurus.core.taurushelper import Factory from taurus.core.util.codecs import CodecFactory 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: import taurus 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 = 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. CodecFactory() factory = 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 from taurus.core.taurushelper import setLogLevel, Warning CodecFactory() setLogLevel(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.6.1/src/sardana/spock/ipython_00_11/0000755000234000017500000000000012555673001022567 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/spock/ipython_00_11/__init__.py0000644000234000017500000000207212555672636024716 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/ipython_00_11/genutils.py0000644000234000017500000011376112555672636025021 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 from taurus.core.taurushelper import Factory, Manager, Warning from taurus.core.util.codecs import CodecFactory from taurus.core.taurushelper import setLogLevel # make sure Qt is properly initialized from taurus.external.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(): Manager().cleanUp() def get_taurus_core_version(): try: import taurus return taurus.core.release.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 = 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 = 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.spsplot) 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, 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) 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() setLogLevel(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: # in ipython the last option in the list takes precedence # so reversing order for searching of the profile reversed_argv = reversed(argv[1:]) for _, arg in enumerate(reversed_argv): 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() # removing all options refering to profile for _, arg in enumerate(argv[1:]): if arg.startswith('--profile='): argv.remove(arg) return if append_profile: argv.append("--profile=" + profile) def run(): try: 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 IPythonQtConsoleApp.version.default_value = release.version except ImportError: pass 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.6.1/src/sardana/spock/ipython_01_00/0000755000234000017500000000000012555673001022566 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/spock/ipython_01_00/__init__.py0000644000234000017500000000207212555672636024715 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/ipython_01_00/genutils.py0000644000234000017500000011455712555672636025024 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.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.terminal.ipapp import TerminalIPythonApp, launch_new_instance import taurus #from taurus.core import Release as TCRelease from taurus.core.taurushelper import Factory from taurus.core.util.codecs import CodecFactory # make sure Qt is properly initialized from taurus.external.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(prompt) 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: import taurus return taurus.core.release.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 = 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) ########################################################################### # NOTE: BaseIPythonApplication.config_file_name.default_value should return # the config file name, but it returns an empty string instead (at least # in some cases). For now, we give a hardcoded name if it is empty # TODO: Check why this is the case config_file_name = BaseIPythonApplication.config_file_name.default_value config_file_name = config_file_name or 'ipython_config.py' ########################################################################### 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 = 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.spsplot) 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, 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) 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: # in ipython the last option in the list takes precedence # so reversing order for searching of the profile reversed_argv = reversed(argv[1:]) for _, arg in enumerate(reversed_argv): 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() # removing all options refering to profile for _, arg in enumerate(argv[1:]): if arg.startswith('--profile='): argv.remove(arg) return if append_profile: argv.append("--profile=" + profile) def run(): try: from IPython.utils.traitlets import Unicode from IPython.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.qt.console.qtconsoleapp IPythonQtConsoleApp = IPython.qt.console.qtconsoleapp.IPythonQtConsoleApp IPythonQtConsoleApp.widget_factory = SpockConsole IPythonQtConsoleApp.version.default_value = release.version except ImportError: pass 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.6.1/src/sardana/spock/test/0000755000234000017500000000000012555673001021254 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/spock/test/__init__.py0000644000234000017500000000172212555672636023404 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/test/test_parameter.py0000644000234000017500000000564312555672636024672 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """test_parameter module documentation""" from taurus.external import unittest from sardana.spock import parameter class ParamTestCase(unittest.TestCase): """ Instantiate in different ways a Param object and verify that they are correct instances from the class Param. """ def testInstanceCreation(self): """ Instantiate in different ways a Param object. """ spock_param = parameter.Param() self.assertIsInstance(spock_param, parameter.Param, 'Instantiation of an object Param without arguments ' + 'does not work \n') spock_param = parameter.Param(name='sardanaName') self.assertIsInstance(spock_param, parameter.Param, 'Instantiation of an object Param with argument name ' + 'does not work') spock_param = parameter.Param(name='sardanaName', desc='description_is_present') self.assertIsInstance(spock_param, parameter.Param, 'Instantiation of an object Param with arguments name ' + 'and description does not work') spock_param = parameter.Param(name='sardanaName', desc='description_is_present', type_name='integer') self.assertIsInstance(spock_param, parameter.Param, 'Instantiation of an object Param with arguments name, ' + 'description and type_name does not work') spock_param = parameter.Param(name='sardanaName', desc='description_is_present', type_name='integer', defvalue=7) self.assertIsInstance(spock_param, parameter.Param, 'Instantiation of an object Param with arguments name, ' + 'description, type_name and defvalue does not work') sardana-1.6.1/src/sardana/spock/__init__.py0000644000234000017500000000215312555672636022424 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/colors.py0000644000234000017500000000776212555672636022201 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/config.py0000644000234000017500000000264412555672636022137 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/exception.py0000644000234000017500000000261612555672636022667 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/genutils.py0000644000234000017500000000412112555672636022514 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 * elif ipv >= [0, 11] and ipv < [1, 0]: from ipython_00_11.genutils import * else: from ipython_01_00.genutils import * sardana-1.6.1/src/sardana/spock/inputhandler.py0000644000234000017500000001247312555672636023370 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Spock submodule. It contains an input handler""" __all__ = ['SpockInputHandler', 'InputHandler'] __docformat__ = 'restructuredtext' import sys from multiprocessing import Process, Pipe from taurus.core import TaurusManager from taurus.core.util.singleton import Singleton from taurus.external.qt import Qt from taurus.qt.qtgui.dialog import TaurusMessageBox, TaurusInputDialog from sardana.taurus.core.tango.sardana.macroserver import BaseInputHandler from sardana.spock import genutils 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') if 'data_type' in input_data: if input_data['data_type'] != 'String': print("Accepted input: %s" % input_data['data_type']) 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.6.1/src/sardana/spock/magic.py0000644000234000017500000002153612555672636021753 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.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': msg = 'To see the scans online, launch "expconf" and ' + \ 'enable the plots from the "plots" button ' + \ '(top-right in the first tab)' print msg return # show the scan plot, ignoring the plot configuration elif params[0].lower() == 'online_raw': 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") from taurus.core.util.codecs import CodecFactory factory = 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 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: PyTango.Except.print_exception(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.6.1/src/sardana/spock/parameter.py0000644000234000017500000001315512555672636022651 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/spock/release.py0000644000234000017500000000440612555672636022310 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1' 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'), 'Reszela' : ('Zbigniew Reszela','zreszela@cells.es') , '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.6.1/src/sardana/spock/spockms.py0000755000234000017500000005143112555672636022352 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 ctypes import PyTango from taurus.core import TaurusEventType, TaurusSWDevState from sardana.sardanautils import is_pure_str, is_non_str_seq from sardana.spock import genutils from sardana.spock.inputhandler import SpockInputHandler, InputHandler from sardana import sardanacustomsettings CHANGE_EVTS = TaurusEventType.Change, TaurusEventType.Periodic if genutils.get_gui_mode() == 'qt': from sardana.taurus.qt.qtcore.tango.sardana.macroserver import QDoor, QMacroServer BaseDoor = QDoor BaseMacroServer = QMacroServer BaseGUIViewer = object else: from sardana.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 _processInput(self, input_data): pyos_inputhook_ptr = ctypes.c_void_p.in_dll(ctypes.pythonapi, "PyOS_InputHook") old_pyos_inputhook_ptr = pyos_inputhook_ptr.value pyos_inputhook_ptr.value = ctypes.c_void_p(None).value ret = BaseDoor._processInput(self, input_data) pyos_inputhook_ptr.value = old_pyos_inputhook_ptr return ret 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.external.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): inputhandler = getattr(sardanacustomsettings, 'SPOCK_INPUT_HANDLER', "CLI") if inputhandler == "Qt": return InputHandler() else: return SpockInputHandler() 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.6.1/src/sardana/tango/0000755000234000017500000000000012555673001020266 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tango/core/0000755000234000017500000000000012555673001021216 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tango/core/SardanaDevice.py0000644000234000017500000004721112555672636024303 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.threadpool import ThreadPool from taurus.core.util.log import Logger from sardana.tango.core.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): # The following try/except workarounds bug-238: "Not possible # to read motor's position when it's out of limits" # (http://sourceforge.net/p/sardana/tickets/238) # In the condition of position attribute out of range, its # w_value will not be updated during readouts or when pushing # events. # The workaround does not affect the drift correction feature # of the pseudomotors, but affects pending operation of the # Taurus write widgets of the position attribute or any other # feature (not known at the moment of applying this workaround) # or anyone trusting the w_value. # # TODO: Remove the try/except protection whenever Sardana # feature-286 has been implemented and bug-54 has been fixed. # The lack of the feature and the bug can lead to the situation # when motor's position write value is out of range. # # feature-286: "Solve inconsistencies between user position # limits and dial position limits" # (http://sourceforge.net/p/sardana/tickets/286) # # bug-54: "Software limits problems between motors and # pseudomotors" # (http://sourceforge.net/p/sardana/tickets/54) ############################################################### try: attr.set_write_value(w_value) except DevFailed as df: error = df[0] reason = error.reason if reason == PyTango.constants.API_WAttrOutsideLimit and\ attr_name == 'position': msg = ('Unable to update "w_value" because it is' + ' out of range') self.warning(msg) self.debug('Details:', exc_info = 1) else: raise df ############################################################### 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.6.1/src/sardana/tango/core/__init__.py0000644000234000017500000000575712555672636023362 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/tango/core/attributehandler.py0000644000234000017500000000511412555672636025147 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers 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 = AttributeLogHandler sardana-1.6.1/src/sardana/tango/core/util.py0000644000234000017500000011160112555672636022562 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 time import string import logging import os.path import traceback 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.type, exc.msg, tb) elif hasattr(exc, 'exc_info'): Except.throw_python_exception(*exc.exc_info) else: raise exc 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]) server_name, _ = os.path.splitext(bin_name) 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" % server_name sys.exit(1) if len(tango_args) < 2: valid = False while not valid: inst_name = raw_input("Please indicate %s instance name: " % server_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, server_name, inst_name): if ask_yes_no('%s does not exist. Do you wish create a new one' % inst_name, default='y'): if server_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, server_name, inst_name, pool_names) else: log_messages += register_sardana(db, server_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_server(db, prefix, start_from=1): prefix = prefix + "_" server_members = db.get_server_list(prefix + "*") server = server_members.value_string while prefix + str(start_from) in server: start_from += 1 return prefix + str(start_from) 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): '''Iterates until failure, trying to retrieve from the database device of the given alias. This way, first which fails is available in the database. :param db: database where to look for the free alias :type db: PyTango.Database :param start_from: alias suffix in form of consecutive number :type start_from: int ''' while True: name = prefix + "_" + str(start_from) try: db.get_device_from_alias(name) # PyTango >= 8.1.0 except PyTango.DevFailed: return name except AttributeError: try: db.get_device_alias(name) # deprecated since PyTango 8.1.0 except PyTango.DevFailed: return name start_from += 1 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) from sardana import sardanacustomsettings maxBytes = getattr(sardanacustomsettings, 'LOG_FILES_SIZE', 1E7) backupCount = getattr(sardanacustomsettings, 'LOG_BCK_COUNT', 5) fmt = Logger.getLogFormat() f_h = logging.handlers.RotatingFileHandler(log_file_name, maxBytes=maxBytes, backupCount=backupCount) 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.6.1/src/sardana/tango/macroserver/0000755000234000017500000000000012555673001022616 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tango/macroserver/test/0000755000234000017500000000000012555673001023575 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tango/macroserver/test/__init__.py0000644000234000017500000000200012555672636025713 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 macroexecutor import TangoMacroExecutor sardana-1.6.1/src/sardana/tango/macroserver/test/macroexecutor.py0000644000234000017500000001677012555672636027057 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 copy import threading import PyTango from sardana.macroserver.macros.test import BaseMacroExecutor from taurus.core.util.codecs import CodecFactory from sardana import sardanacustomsettings class TangoAttrCb(object): '''An abstract callback class for Tango events''' def __init__(self, tango_macro_executor): self._tango_macro_executor = tango_macro_executor class TangoResultCb(TangoAttrCb): '''Callback class for Tango events of the Result attribute''' def push_event(self, *args, **kwargs): '''callback method receiving the event''' event_data = args[0] if event_data.err: result = event_data.errors else: result = event_data.attr_value.value self._tango_macro_executor._result = result class TangoLogCb(TangoAttrCb): '''Callback class for Tango events of the log attributes e.g. Output, Error, Critical ''' def __init__(self, tango_macro_executor, log_name): self._tango_macro_executor = tango_macro_executor self._log_name = log_name def push_event(self, *args, **kwargs): '''callback method receiving the event''' event_data = args[0] if event_data.attr_value: log = event_data.attr_value.value log_buffer_name = '_%s' % self._log_name log_buffer = getattr(self._tango_macro_executor, log_buffer_name) log_buffer.append(log) common_buffer = self._tango_macro_executor._common if common_buffer != None: common_buffer.append(log) class TangoStatusCb(TangoAttrCb): '''Callback class for Tango events of the MacroStatus attribute''' START_STATES = ['start'] DONE_STATES = ['finish', 'stop', 'exception'] def push_event(self, *args, **kwargs): '''callback method receiving the event''' event_data = args[0] if event_data.err: self._state_buffer = event_data.errors self._tango_macro_executor._done_event.set() # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) attr_value = event_data.attr_value v = map(str, attr_value.value) if not len(v[1]): return fmt = v[0] codec = CodecFactory().getCodec(fmt) # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) v[1] = str(v[1]) fmt, data = codec.decode(v) for macro_status in data: state = macro_status['state'] self._tango_macro_executor._exception = macro_status.get( 'exc_type') if state in self.START_STATES: #print 'TangoStatusCb.push_event: setting _started_event' self._tango_macro_executor._started_event.set() elif state in self.DONE_STATES: # print 'TangoStatusCb.push_event: setting _done_event %s' # %(state) self._tango_macro_executor._done_event.set() #else: # print 'State %s' %(state) self._tango_macro_executor._state_buffer.append(state) class TangoMacroExecutor(BaseMacroExecutor): ''' Macro executor implemented using Tango communication with the Door device ''' def __init__(self, door_name=None): super(TangoMacroExecutor, self).__init__() if door_name == None: door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME') self._door = PyTango.DeviceProxy(door_name) self._done_event = None self._started_event = None def _clean(self): '''Recreates threading Events in case the macro executor is reused.''' super(TangoMacroExecutor, self)._clean() self._started_event = threading.Event() self._done_event = threading.Event() def _run(self, macro_name, macro_params): '''reimplemented from :class:`BaseMacroExecutor`''' # preaparing RunMacro command input arguments argin = copy.copy(macro_params) argin.insert(0, macro_name) # registering for MacroStatus events status_cb = TangoStatusCb(self) self._status_id = self._door.subscribe_event('macrostatus', PyTango.EventType.CHANGE_EVENT, status_cb) # executing RunMacro command self._door.RunMacro(argin) def _wait(self, timeout): '''reimplemented from :class:`BaseMacroExecutor`''' #TODO: In case of timeout = inf if the macro excecutor run a macro # with wrong parameters it'll never awake of the done_event wait # Pending to remove this comment when Sardana resolves the bug. if self._done_event: self._done_event.wait(timeout) self._door.unsubscribe_event(self._status_id) def _stop(self, started_event_timeout=3.0): '''reimplemented from :class:`BaseMacroExecutor`''' self._started_event.wait(started_event_timeout) try: self._door.StopMacro() except PyTango.DevFailed as e: raise Exception("Unable to Stop macro: %s" % e) def _registerLog(self, log_level): '''reimplemented from :class:`BaseMacroExecutor`''' log_cb = TangoLogCb(self, log_level) id_log_name = '_%s_id' % log_level id_log = self._door.subscribe_event(log_level, PyTango.EventType.CHANGE_EVENT, log_cb) setattr(self, id_log_name, id_log) def _unregisterLog(self, log_level): '''reimplemented from :class:`BaseMacroExecutor`''' id_log_name = '_%s_id' % log_level id_log = getattr(self, id_log_name) self._door.unsubscribe_event(id_log) def _registerResult(self): '''reimplemented from :class:`BaseMacroExecutor`''' result_cb = TangoResultCb(self) self._result_id = self._door.subscribe_event('result', PyTango.EventType.CHANGE_EVENT, result_cb) def _unregisterResult(self): '''reimplemented from :class:`BaseMacroExecutor`''' self._door.unsubscribe_event(self._result_id) def getData(self): '''Returns the data object for the last executed macro :return: (obj) ''' data = self._door.RecordData return CodecFactory().decode(data) sardana-1.6.1/src/sardana/tango/macroserver/Door.py0000644000234000017500000004302412555672636024113 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 json import time import threading from lxml import etree from PyTango import Util, DevFailed, Except, DevVoid, DevLong, \ DevLong64, DevString, DevState, DevEncoded, \ DevVarStringArray, ArgType, \ READ, READ_WRITE, SCALAR, SPECTRUM from taurus.core.util.log import DebugIt, LogFilter from taurus.core.util.codecs import CodecFactory 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.macroserver.msexception import MacroServerException from sardana.tango.core.util import throw_sardana_exception from sardana.tango.core.attributehandler import AttributeLogHandler from sardana.tango.core.SardanaDevice import SardanaDevice, SardanaDeviceClass from sardana.macroserver.msexception import 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 = 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.door.get_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 MacroServerException, mse: throw_sardana_exception(mse) 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.6.1/src/sardana/tango/macroserver/MacroServer.py0000644000234000017500000004007112555672636025437 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.codecs import CodecFactory from sardana import State, SardanaServer 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.6.1/src/sardana/tango/macroserver/__init__.py0000644000234000017500000000345212555672636024750 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/tango/pool/0000755000234000017500000000000012555673001021237 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tango/pool/test/0000755000234000017500000000000012555673001022216 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tango/pool/test/__init__.py0000644000234000017500000000212712555672636024346 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 base import (BasePoolTestCase, ControllerLoadsTestCase, ControllerCreationTestCase, ElementCreationTestCase) sardana-1.6.1/src/sardana/tango/pool/test/base.py0000644000234000017500000001612312555672636023522 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Base classes for the controller tests""" __all__ = ['BasePoolTestCase', 'ControllerLoadsTestCase', 'ControllerCreationTestCase', 'ElementCreationTestCase'] import os import PyTango from taurus import Device from taurus.external import unittest from taurus.core.tango.starter import ProcessStarter from sardana import sardanacustomsettings from sardana.taurus.core.tango.sardana import (registerExtensions, unregisterExtensions) from sardana.tango.core.util import (get_free_server, get_free_device, get_free_alias) from taurus.core.util import whichexecutable class BasePoolTestCase(object): """Abstract class for pool DS testing. """ pool_ds_name = getattr(sardanacustomsettings, 'UNITTEST_POOL_DS_NAME') pool_name = getattr(sardanacustomsettings, 'UNITTEST_POOL_NAME') def setUp(self): """Start Pool DS and register extensions. """ # Discover the Pool launcher script poolExec = whichexecutable.whichfile("Pool") # register Pool server pool_ds_name = "Pool/" + self.pool_ds_name pool_free_ds_name = get_free_server(PyTango.Database(), pool_ds_name) self._starter = ProcessStarter(poolExec, pool_free_ds_name) # register Pool device dev_name_parts = self.pool_name.split('/') prefix = '/'.join(dev_name_parts[0:2]) start_from = int(dev_name_parts[2]) self.pool_name = get_free_device(PyTango.Database(), prefix, start_from) self._starter.addNewDevice(self.pool_name, klass='Pool') # start Pool server self._starter.startDs() # register extensions so the test methods can use them registerExtensions() self.pool = Device(self.pool_name) def tearDown(self): """Remove the Pool instance. """ unregisterExtensions() self._starter.cleanDb(force=True) # TODO: Currently test inputs are implemented as class members, it would be # more aesthetic to implement them as decorators. class ControllerLoadsTestCase(BasePoolTestCase): """Class for loading an arbitrary Sardana controller library and class. """ controller_classes = [] def test_controller_loads(self): """Test that the controller library and class can be loaded. """ libraries = self.pool.getElementsOfType('ControllerLibrary').values() libraries_names = [lib.getName() for lib in libraries] classes = self.pool.getElementsOfType('ControllerClass').values() classes_names = [cls.getName() for cls in classes] for test_lib, test_classes in self.controller_classes.items(): msg = 'ControllerLibrary %s was not correctly loaded.' % test_lib self.assertIn(test_lib, libraries_names, msg) msg = 'ControllerClass %s was not correctly loaded.' for test_class in test_classes: self.assertIn(test_class, classes_names, msg % test_class) # TODO: Currently test inputs are implemented as class members, it would be # more aesthetic to implement them as decorators. class ControllerCreationTestCase(BasePoolTestCase): """Class for creating a controller and testing the correct creation. """ controller_infos = [] def test_controller_creation(self): """Test that the controller has been created with the correct name. """ for cls, name, props in self.controller_infos: ctrl = self.pool.createController(cls, name, *props) msg = 'Controller %s was not correctly created.' % name self.assertEqual(ctrl.getName(), name, msg) ctrl = self.pool.deleteElement(ctrl.getName()) # TODO: Currently test inputs are implemented as class members, it would be # more aesthetic to implement them as decorators. class ElementCreationTestCase(BasePoolTestCase): """Class used for creating a Sardana controller and Sardana elements. """ controller_infos = [] NAME = 0 AXIS = 1 def test_element_creation(self): """Test that controller and elements have been correctly created. """ for cls, name, props, elements in self.controller_infos: ctrl = self.pool.createController(cls, name, *props) msg = 'Controller %s was not correctly created.' % name self.assertEqual(ctrl.getName(), name, msg) for element_info in elements: test_name = element_info[self.NAME] test_axis = element_info[self.AXIS] elem = self.pool.createElement(test_name, ctrl, test_axis) msg = 'Element %s was not correctly created.' % test_name self.assertIsNotNone(elem, msg) name = elem.getName() msg = 'Element name: %s does not correspond to: %s.' % \ (name, test_name) self.assertEqual(name, test_name, msg) elem = self.pool.deleteElement(test_name) msg = 'Element %s was not correctly deleted.' % test_name self.assertIsNotNone(elem, msg) ctrl = self.pool.deleteElement(ctrl.getName()) if __name__ == '__main__': class BuiltinControllerLoadsTest(ControllerLoadsTestCase, unittest.TestCase): controller_classes = { 'DummyMotorController':('DummyMotorController',) } class BuiltinControllerCreationTest(ControllerCreationTestCase, unittest.TestCase): controller_infos = [('DummyMotorController', 'unittest', ()) ] class BuiltinElementCreationTest(ElementCreationTestCase, unittest.TestCase): alias = get_free_alias(PyTango.Database(), "mot_test") controller_infos = [('DummyMotorController', 'unittest', (), [(alias, 1)]) ] suite = unittest.defaultTestLoader.loadTestsFromTestCase( BuiltinElementCreationTest) unittest.TextTestRunner(descriptions=True, verbosity=2).run(suite) sardana-1.6.1/src/sardana/tango/pool/test/test_Motor.py0000644000234000017500000000612212555672636024745 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Tests Read Position from Sardana using PyTango""" import PyTango from taurus.external import unittest from sardana.tango.pool.test import BasePoolTestCase from sardana.tango.core.util import get_free_alias import numbers class ReadMotorPositionOutsideLim(BasePoolTestCase, unittest.TestCase): """TestCase class for testing that read position is possible when motor is out of SW limits. Verify that position has a numeric type. """ def setUp(self): """Create dummy motor controller and dummy motor element """ super(ReadMotorPositionOutsideLim, self).setUp() cls = 'DummyMotorController' self.ctrl_name = get_free_alias(PyTango.Database(), "readposctrl") props = () ctrl = self.pool.createController(cls, self.ctrl_name, *props) #Add extra timeout of 3 seconds. if ctrl is None: elements_info = self.pool.getElementsInfo() ctrl = self.pool._wait_for_element_in_container(elements_info, self.ctrl_name, timeout = 3) self.elem_name = get_free_alias(PyTango.Database(), "mot_test") elem_axis = 1 self.elem = self.pool.createElement(self.elem_name, ctrl, elem_axis) self.elem.DefinePosition(0) def test_read_position_outside_sw_lim(self): """Test bug #238: reading position when motor is out of SW lims. Verify that position has a numeric type.""" pc = self.elem.get_attribute_config("position") pc.min_value = "1" pc.max_value = "2" self.elem.set_attribute_config(pc) try: posread = self.elem.read_attribute('position').value except Exception as e_read: msg = ("Position cannot be read. Exception: %s" % e_read) self.fail(msg) msg = ("Position is not a number") self.assertIsInstance(posread, numbers.Number, msg) def tearDown(self): """Remove motor element and motor controller """ self.pool.DeleteElement(self.elem_name) self.pool.DeleteElement(self.ctrl_name) super(ReadMotorPositionOutsideLim, self).tearDown() sardana-1.6.1/src/sardana/tango/pool/CTExpChannel.py0000644000234000017500000001701112555672636024102 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/Controller.py0000644000234000017500000002335312555672636023757 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import DebugIt from taurus.core.util.containers import CaselessDict 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=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.6.1/src/sardana/tango/pool/IORegister.py0000644000234000017500000002055412555672636023650 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log import DebugIt from sardana import State, SardanaServer from sardana.sardanaattribute import SardanaAttribute from sardana.pool.poolexception import PoolException from sardana.sardanautils import str_to_value from sardana.tango.core.util import exception_str, throw_sardana_exception from sardana.tango.pool.PoolDevice import PoolElementDevice, \ PoolElementDeviceClass 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.6.1/src/sardana/tango/pool/MeasurementGroup.py0000644000234000017500000002177212555672636025141 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.codecs 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/Motor.py0000644000234000017500000007145312555672636022740 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.log 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/MotorGroup.py0000644000234000017500000001750412555672636023752 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/OneDExpChannel.py0000644000234000017500000001740712555672636024432 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/Pool.py0000644000234000017500000015166712555672636022557 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers import CaselessDict from taurus.core.util.codecs import 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.6.1/src/sardana/tango/pool/PoolDevice.py0000644000234000017500000007630612555672636023673 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.containers 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("writing 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.6.1/src/sardana/tango/pool/PseudoCounter.py0000644000234000017500000002137212555672636024432 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/PseudoMotor.py0000644000234000017500000002604012555672636024110 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/TwoDExpChannel.py0000644000234000017500000001751212555672636024457 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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() if data_source is None: data_source = "tango://{0}/value".format(self.get_full_name()) 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.6.1/src/sardana/tango/pool/ZeroDExpChannel.py0000644000234000017500000002143712555672636024626 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.tango.pool.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.6.1/src/sardana/tango/pool/__init__.py0000644000234000017500000000751412555672636023374 0ustar zreszelaComputing00000000000000#!/usr/bin/env python from sardana.pool.poolextension import ControllerStateTranslator ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/tango/__init__.py0000644000234000017500000000253512555672636022421 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/0000755000234000017500000000000012555673001020501 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/core/0000755000234000017500000000000012555673001021431 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/core/tango/0000755000234000017500000000000012555673001022541 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/core/tango/sardana/0000755000234000017500000000000012555673001024152 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/core/tango/sardana/__init__.py0000644000234000017500000000257612555672636026312 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 package. It contains specific part of sardana""" __docformat__ = 'restructuredtext' from .sardana import * def registerExtensions(): from . import pool from . import macroserver pool.registerExtensions() macroserver.registerExtensions() def unregisterExtensions(): from . import pool from . import macroserver pool.unregisterExtensions() macroserver.unregisterExtensions() sardana-1.6.1/src/sardana/taurus/core/tango/sardana/macro.py0000644000234000017500000010070212555672636025642 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 macro submodule.""" __all__ = ["MacroInfo", "Macro", "MacroNode", "ParamFactory", "MacroRunException"] __docformat__ = 'restructuredtext' import os import copy import types import tempfile from lxml import etree import PyTango from taurus.core.util.user import USER_NAME from taurus.core.util.codecs import CodecFactory class MacroRunException(Exception): pass class MacroInfo(object): """Contains all information about a macro: name, documentation, parameters, result, etc""" def __init__(self, from_json_str=None, from_json=None): json_obj = from_json if from_json_str is not None: json_obj = self._fromJSON(from_json_str) if json_obj: self.__dict__.update(json_obj) self._buildDoc() def _fromJSON(self, json_str): json_codec = CodecFactory().getCodec('json') format, data = json_codec.decode(('json', json_str)) return data def _buildDoc(self): if self.hasParams(): self._parameter_line = self._buildParameterLine(self.parameters) self._parameter_description = self._buildParameterDescription(self.parameters) if self.hasResult(): self._result_line = self._buildResultLine(self.result) self._result_description = self._buildResultDescription(self.result) doc = 'Syntax:\n\t%s %s' % (self.name, self.getParamStr()) if self.hasResult(): doc += ' -> ' + self.getResultStr() doc += '\n\n' doc += self.description if self.hasParams(): doc += '\n\nParameters:\n\t' doc += '\n\t'.join(self.getParamDescr()) if self.hasResult(): doc += '\n\nResult:\n\t' doc += '\n\t'.join(self.getResultDescr()) self.doc = doc def _hasParamComplex(self, parameters=None): if parameters is None: parameters = self.parameters for p in parameters: if self._isParamComplex(p): return True return False def _isParamComplex(self, p): return not self._isParamAtomic(p) def _isParamAtomic(self, p): return type(p['type']) in types.StringTypes def _buildParameterLine(self, parameters): l = [] for p in parameters: t = p['type'] if type(t) in types.StringTypes: #Simple parameter l.append('<%s>' % p['name']) else: l.append('[ %s ]' % self._buildParameterLine(t)) return ' '.join(l) _buildResultLine = _buildParameterLine def _buildParameterDescription(self, parameters): l = [] for p in parameters: t = p['type'] if type(t) in types.StringTypes: #Simple parameter l.append('{name} : ({type}) {description}'.format(**p)) else: l.extend(self._buildParameterDescription(t)) return l _buildResultDescription = _buildParameterDescription def hasParams(self): """Determines if the macro has parameters :return: (bool) True if the macro has parameters or False otherwise """ return hasattr(self , 'parameters') def getParamList(self): """Returs the list of parameters :return: (sequence) a list of parameters """ if not self.hasParams(): return [] return self.parameters def getParam(self, idx=0): """Gets the parameter for the given index :param idx: (int) the index (default is 0) :return: (object) the parameter or None if the macro does not have the desired parameter """ if not self.hasParams(): return return self.parameters[idx] def getPossibleParams(self, idx, parameters=None): """Gets the possible parameters for the given index :param idx: (int) parameter index :param parameters: (sequence) sequence of parameter information (default is None which means use the macro parameters :return: (sequence) list of possible parameters """ if parameters is None: parameters = self.parameters res = [] n = len(parameters) if idx >= n: if self._hasParamComplex(parameters): p = copy.copy(parameters) p.reverse() res.extend(self.getPossibleParams(0, p)) return res res = [] for i, p in enumerate(parameters): atomic = self._isParamAtomic(p) if i < idx: if atomic: continue else: res.extend(self.getPossibleParams(idx - i, p['type'])) elif i == idx: if atomic: res.append(p) else: res.extend(self.getPossibleParams(0, p['type'])) else: break return res def getParamStr(self): """Returns the string line representing the macro parameters. For example, if a macro has a motor parameter followed by a list of numbers it will return: ' [ ]' :return: (str) a string representing the macro parameter line """ if not self.hasParams(): return '' return self._parameter_line def getParamDescr(self): """Returns the list of strings, each one documenting each macro parameter :return: (sequence) list of parameter lines """ if not self.hasParams(): return [] return self._parameter_description def hasResult(self): """Determines if the macro has a result :return: (bool) True if the macro has a result or False otherwise """ return hasattr(self , 'result') def getResultList(self): """Returns the list of results :return: (sequence) a list of results """ if not self.hasResult(): return [] return self.result def getResult(self, idx=0): """Gets the result for the given index :param idx: (int) the index (default is 0) :return: (object) the result or None if the macro does not have the desired result """ return self.result[idx] def getResultStr(self): """Returns the string line representing the macro results. For example, if a macro returns a number, this method it will return: '' :return: (str) a string representing the macro result line """ if not self.hasResult(): return '' return self._result_line def getResultDescr(self): """Returns the list of strings, each one documenting each macro result :return: (sequence) list of result lines """ if not self.hasResult(): return [] return self._result_description def formatResult(self, res): if not self.hasResult(): if res is None: return None raise Exception('Macro %s does not return any result' % self.name) result_info = self.getResult() rtype = result_info['type'] if rtype == 'File': fd, filename = tempfile.mkstemp(prefix='spock_', text=True) os.write(fd, res[1]) os.close(fd) # put the local filename in the result res.insert(0, filename) return res if len(res) > 0: if rtype == 'Float': return float(res[0]) elif rtype == 'Integer': return int(res[0]) elif rtype == 'Boolean': return res[0].lower() == 'true' elif rtype in ('String', 'User', 'Filename'): return res[0] else: raise Exception('Unknown return type for macro %s' % self.name) else: return None def __str__(self): return self.name class Macro(object): Ready = PyTango.DevState.ON Init = PyTango.DevState.INIT Running = PyTango.DevState.RUNNING Pause = PyTango.DevState.STANDBY Fault = PyTango.DevState.FAULT Finished = PyTango.DevState.ON Abort = PyTango.DevState.ALARM def __init__(self, door, name, id, xml_obj): self.door = door self.name = name self.xml_node = xml_obj self.id = id self.range = None self.step = None self.result = None def getID(self): return self.id def getRange(self): return self.range def getStep(self): return self.step def getInfo(self): return self.door.macro_server.getMacroInfoObj(self.name) def setResult(self, res): self.result = self.getInfo().formatResult(res) def getResult(self): return self.result class BaseNode(object): """Base class defining basic interface for all type of nodes used to represent, relationship between sequence, macros and parameters.""" def __init__(self, parent=None): # if parent: # parent = weakref.ref(parent) self._parent = parent def parent(self): return self._parent def setParent(self, parent): # if parent: # parent = weakref.ref(parent) self._parent = parent def value(self): return "" def isAllowedMoveUp(self): return False def isAllowedMoveDown(self): return False def isAllowedDelete(self): return False class BranchNode(BaseNode): """Class used to represent all types of elements which contain a list of other elements (children)""" def __init__(self, parent=None): BaseNode.__init__(self, parent) self._children = [] def __len__(self): return len(self.children()) def children(self): return self._children def child(self, idx): try: children = self.children() return children[idx] except: return None def rowOfChild(self, child): try: return self.children().index(child) except ValueError: return -1 def insertChild(self, child, row=-1): child.setParent(self) if row == -1: row = len(self) self.children().insert(row, child) return row def removeChild(self, child): self.children().remove(child) def upChild(self, child): i = self.children().index(child) if i == 0: return self.removeChild(child) self.children().insert(child, i - 1) def downChild(self, child): i = self.children().index(child) if i == len(self) - 1: return self.removeChild(child) self.children().insert(i + 1, child) def toRun(self): values = [] alert = "" for child in self.children(): val, ale = child.toRun() values += val alert += ale return values, alert class ParamNode(BaseNode): """Base class for param elements: single parameters and param repeats. It groups a common interface of them.""" def __init__(self, parent=None, param=None): BaseNode.__init__(self, parent) if param is None: self.setName(None) self.setDescription(None) self.setMin(None) self.setMax(None) else: self.setName(str(param.get('name'))) self.setDescription(str(param.get('description'))) self.setMin(str(param.get('min'))) self.setMax(str(param.get('max'))) def name(self): return self._name def setName(self, name): self._name = name def description(self): return self._description def setDescription(self, description): self._description = description def min(self): return self._min def setMin(self, min): if min == 'None': min = None elif min: min = float(min) self._min = min def max(self): return self._max def setMax(self, max): if max == 'None': max = None elif max: max = float(max) self._max = max class SingleParamNode(ParamNode): """Single parameter class.""" def __init__(self, parent=None, param=None): ParamNode.__init__(self, parent, param) if param is None: return self.setType(str(param.get('type'))) self.setDefValue(str(param.get('default_value', ''))) if self.type() == "User": self.setDefValue(str(USER_NAME)) self.setValue(self.defValue()) def __len__(self): return 0 def value(self): return self._value def setValue(self, value): self._value = value def defValue(self): return self._defValue def setDefValue(self, defValue): self._defValue = defValue def type(self): return self._type def setType(self, type): self._type = type def toXml(self): paramElement = etree.Element("param", name=self.name(), value=self.value()) return paramElement def fromXml(self, xmlElement): self.setName(xmlElement.get("name")) self.setValue(xmlElement.get("value")) def isMotorParam(self): return self.type() == globals.PARAM_MOTOR def allMotors(self): if self.isMotorParam() and self.value() != 'None': return [self.value()] else: return[] def toRun(self): val = self.value() if val is None or val == "None" or val == "": alert = "Parameter " + self.name() + " is missing.
    " return ([val], alert) return ([val], "") class RepeatParamNode(ParamNode, BranchNode): """Repeat parameter class.""" def __init__(self, parent=None, param=None): ParamNode.__init__(self, parent, param) BranchNode.__init__(self, parent) if param is None: return self.setParamsInfo(copy.deepcopy(param.get('type'))) def arrangeIndexes(self): for i, child in enumerate(self.children()): child.setIndex(i + 1) def paramsInfo(self): return self._paramsInfo def setParamsInfo(self, paramsInfo): self._paramsInfo = paramsInfo def newRepeat(self): repeatNode = RepeatNode(self) for repeatParam in self.paramsInfo(): repeatNode.addParam(repeatParam) return repeatNode def addRepeat(self): repeat = RepeatNode(self) self.insertChild(repeat) for repeatParam in self.paramsInfo(): repeat.addParam(repeatParam) def isReachedMin(self): if self.min() is None: return False return len(self) <= self.min() def isBelowMin(self): if self.min() is None: return False return len(self) < self.min() def isReachedMax(self): if self.max() is None: return False return len(self) == self.max() def isAboveMax(self): if self.max() is None: return False return len(self) > self.max() def insertChild(self, child, row=-1): #this line was removed on purpose #in case of importing sequences from plain text, it is possible that user introduced more repetitions than allowed #in this case later validation will inform him about exceeding a limit #if self.isReachedMax(): return return BranchNode.insertChild(self, child, row) def removeChild(self, child): if self.isReachedMin(): return child.setParent(None) begin = self.children().index(child) + 1 for i in range(begin, len(self)): self.child(i).setIndex(self.child(i).index() - 1) BranchNode.removeChild(self, child) def upChild(self, child): i = self.children().index(child) if i == 0: return child.setIndex(child.index() - 1) self.child(i - 1).setIndex(self.child(i - 1).index() + 1) BranchNode.removeChild(self, child) self.insertChild(child, i - 1) def downChild(self, child): i = self.children().index(child) if i == len(self) - 1: return child.setIndex(child.index() + 1) self.child(i + 1).setIndex(self.child(i + 1).index() - 1) BranchNode.removeChild(self, child) self.insertChild(child, i + 1) def toRun(self): values = [] alert = "" if self.isBelowMin(): alert += "Parameter " + self.name() + " has not enough repeats
    " for child in self.children(): val, ale = child.toRun() values += val alert += ale return (values, alert) def toXml(self): paramElement = etree.Element("paramrepeat", name=self.name()) for child in self.children(): paramElement.append(child.toXml()) return paramElement def fromXml(self, xmlElement): self.setName(xmlElement.get("name")) for repeatElement in xmlElement.getiterator("repeat"): repeat = RepeatNode(self) repeat.fromXml(repeatElement) self.insertChild(repeat) def allMotors(self): motors = [] for child in self.children(): motors += child.allMotors() return motors # def isAllowedMoveUp(self): # return self is not self.parent().child(0) # # def isAllowedMoveDown(self): # return self is not self.parent().child(len(self.parent()) - 1) class RepeatNode(BranchNode): """Class for repetition elements (group of params which were repeated in macro)""" def __init__(self, parent=None): BranchNode.__init__(self, parent) if parent is None: return self.setIndex(len(self.parent()) + 1) def index(self): return self._index def setIndex(self, index): self._index = index def name(self): return "#%d" % self.index() def addParam(self, param): type = param.get('type', None) if isinstance(type, list): paramRepeat = RepeatParamNode(self, param) self.insertChild(paramRepeat) paramRepeat.addRepeat() else: self.insertChild(SingleParamNode(self, param)) def toXml(self): repeatElement = etree.Element("repeat", nr=str(self.index())) for child in self.children(): repeatElement.append(child.toXml()) return repeatElement def fromXml(self, xmlElement): self.setIndex(int(xmlElement.get("nr"))) for paramElement in xmlElement: if paramElement.tag == "param": param = SingleParamNode(self) elif paramElement.tag == "paramrepeat": param = RepeatParamNode(self) param.fromXml(paramElement) self.insertChild(param) def allMotors(self): motors = [] for child in self.children(): motors += child.allMotors() return motors def isAllowedDel(self): pass def isAllowedMoveUp(self): return self is not self.parent().child(0) def isAllowedMoveDown(self): return self is not self.parent().child(len(self.parent()) - 1) class MacroNode(BranchNode): """Class to represent macro element.""" count = 0 def __init__(self, parent=None, name=None): BranchNode.__init__(self, parent) self.setId(None) self.setName(name) self.setPause(False) self.setProgress(0) self.setRange((0, 100)) self.setParams([]) self.setHooks([]) self.setHookPlaces([]) self.setAllowedHookPlaces([]) def id(self): """ Getter of macro's id property :return: (int) .. seealso: :meth:`MacroNode.setId`, assignId """ return self._id def setId(self, id): """ Setter of macro's id property :param id: (int) new macro's id See Also: id, assignId """ self._id = id def assignId(self): """ If macro didn't have an assigned id it assigns it and return macro's id. :return: (int) See Also: id, setId """ id = self.id() if id is not None: return id MacroNode.count += 1 self.setId(MacroNode.count) return MacroNode.count def name(self): return self._name def setName(self, name): self._name = name def isPause(self): return self._pause def setPause(self, pause): self._pause = pause def range(self): return self._range def setRange(self, range): self._range = range def progress(self): return self._progress def setProgress(self, progress): self._progress = progress def isAllowedHooks(self): return bool(self._allowedHookPlaces) def allowedHookPlaces(self): return self._allowedHookPlaces def setAllowedHookPlaces(self, allowedHookPlaces): self._allowedHookPlaces = allowedHookPlaces def hookPlaces(self): return self._hookPlaces def setHookPlaces(self, hookPlaces): self._hookPlaces = hookPlaces def addHookPlace(self, hookPlace): self._hookPlaces.append(hookPlace) def removeHookPlace(self, hookPlace): self._hookPlaces.remove(hookPlace) def hasParams(self): return self._hasParams def setHasParams(self, hasParams): self._hasParams = hasParams ################################# def params(self): return self._params def setParams(self, params): self._params = params def addParam(self, param): param.setParent(self) self._params.append(param) def popParam(self, index=None): if index == None: return self._params.pop() else: return self._params.pop(index) def hooks(self): return self._hooks def setHooks(self, hooks): self._hooks = hooks def addHook(self, hook): hook.setParent(self) self._hooks.append(hook) def removeHook(self, hook): self._hooks.remove(hook) def rowOfHook(self, hook): try: return self.hooks().index(hook) except ValueError: return -1 ################################## def children(self): return self.params() + self.hooks() def insertChild(self, child, row=-1): child.setParent(self) if isinstance(child, MacroNode): if row == -1: row = len(self._hooks) else: row = row - len(self._params) self._hooks.insert(row, child) elif isinstance(child, ParamNode): if row == -1: row = len(self._params) self._params.insert(row, child) return self.rowOfChild(child) def removeChild(self, child): if isinstance(child, MacroNode): self._hooks.remove(child) elif isinstance(child, ParamNode): self._params.insert(child) def toRun(self): values = [] alert = "" for child in self.children(): if isinstance(child, ParamNode): val, ale = child.toRun() values += val alert += ale return values, alert def toSpockCommand(self): values, alerts = self.toRun() return "%s %s" % (self.name(), str.join(' ', values)) def value(self): values, alerts = self.toRun() if len(values) == 0: return '' elif len(values) == 1: return '[%s]' % values[0] else: valueString = '' for value in values: valueString += (value + ', ') return '[%s]' % valueString[:-2] # def allMotors(self): # motors = [] # for macro in self.allMacros(): # motors += macro.ownMotors() # return motors # # def ownMotors(self): # motors = [] # for macro in self.hooks(): # motors += macro.allMotors() # return motors def allMacros(self): macros = self.allDescendants() macros.append(self) return macros def allDescendants(self): descendantsMacros = [] ownMacros = [] for child in self.children(): if isinstance(child, MacroNode): ownMacros.append(child) descendantsMacros += child.allDescendants() return descendantsMacros + ownMacros # def descendantFromId(self, id): # descendant = None # for child in self.children(): # if isinstance(child, MacroNode) and child.id() == id: # descendant = child # break # else: # for child in self.children(): # descendant = child.descendantById(id) # return descendant def isAllowedMoveLeft(self): """This method checks if is is allowed to move macro to grandparent's hook list. It is enough to check that grandparent exist, cause all parents must allow hooks""" return self.parent().parent() is not None def moveLeft(self): """This method moves macro to grandparent's hook list and place it right after its ex-parent, it also returns newRow""" oldParent = self.parent() newParent = oldParent.parent() newRow = newParent.hooks().index(oldParent) + 1 oldParent.removeHook(self) self.setParent(newParent) newParent.insertHook(newRow, self) return newRow def isAllowedMoveRight(self): """This method is used to check if it is allowed to move macro to it's first following sibling's hook list.""" parent = self.parent() try: return parent.child(parent.rowOfChild(self) + 1).isAllowedHooks() except: return False def moveRight(self): """This method is used to move selected macro (pased via index) to it's first following sibling's hook list. In tree representation it basically move macro to the right""" parent = self.parent() for idx, hook in enumerate(parent.hooks()): if hook is self: newParent = parent.hook(idx + 1) parent.removeHook(self) self.setParent(newParent) newParent.insertHook(0, self) return 0 def isAllowedMoveUp(self): parent = self.parent() if isinstance(parent, SequenceNode): return self is not self.parent().child(0) elif isinstance(parent, MacroNode): return self is not self.parent()._hooks[0] else: return False def moveUp(self): """This method moves hook up and returns newRow""" parent = self.parent() myOldRow = parent.rowOfHook(self) parent.removeHook(self) parent.insertHook(myOldRow - 1, self) return myOldRow - 1 def isAllowedMoveDown(self): parent = self.parent() return parent.rowOfChild(self) < len(parent) - 1 def moveDown(self): """This method moves hook up and returns newRow""" parent = self.parent() myOldRow = parent.rowOfHook(self) parent.removeHook(self) parent.insertHook(myOldRow + 1, self) return myOldRow + 1 def toXml(self, withId=True): """ Converts MacroNode obj to etree.Element obj. :param withId: (bool) if we want to export also macro id (default: True) See Also: fromXml """ macroElement = etree.Element("macro", name=self.name()) if withId: macroElement.set("id", str(self.id())) for hookPlace in self.hookPlaces(): hookElement = etree.SubElement(macroElement, "hookPlace") hookElement.text = hookPlace for child in self.children(): if isinstance(child, MacroNode): xmlElement = child.toXml(withId) else: xmlElement = child.toXml() macroElement.append(xmlElement) return macroElement def fromXml(self, xmlElement): """ Fills properties of MacroNode obj from etree.Element obj passed as a parameter :param xmlElement: (etree.Element) See Also: toXml """ self.setName(xmlElement.get("name")) hookPlaces = [] for element in xmlElement: if element.tag == "param": param = SingleParamNode(self) param.fromXml(element) self.addParam(param) elif element.tag == "paramrepeat": param = RepeatParamNode(self) param.fromXml(element) self.addParam(param) elif element.tag == "macro": macro = MacroNode(self) macro.fromXml(element) self.addHook(macro) elif element.tag == "hookPlace": hookPlaces.append(element.text) self.setHookPlaces(hookPlaces) def fromPlainText(self, plainText): words = plainText.split() length = len(words) if length == 0: return self.setName(words[0]) for index in range(1, length): param = SingleParamNode(self) param.setValue(words[index]) self.addParam(param) class SequenceNode(BranchNode): """Class to represent sequence element.""" comment_characters = ('#',) def __init__(self, parent=None): BranchNode.__init__(self, parent) def allMacros(self): macros = [] for macro in self.children(): macros += macro.allDescendants() macros += self.children() return macros def upMacro(self, macro): BranchNode.upChild(self, macro) def downMacro(self, macro): BranchNode.downChild(self, macro) def toXml(self, withId=True): sequenceElement = etree.Element("sequence") for child in self.children(): sequenceElement.append(child.toXml(withId)) return sequenceElement def fromXml(self, sequenceElement): for childElement in sequenceElement.iterchildren("macro"): macro = MacroNode(self) macro.fromXml(childElement) self.insertChild(macro) def fromPlainText(self, plainText): plainMacros = plainText.split('\n') for plainMacro in plainMacros: # stripping the whitespace characters plainMacro = plainMacro.strip() # ignoring the empty lines if len(plainMacro) == 0: continue # ignoring the commented lines if plainMacro[0] in self.comment_characters: continue macro = MacroNode(self) macro.fromPlainText(plainMacro) self.insertChild(macro) # def descendantFromId(self, id): # descendant = None # for child in self.children(): # if isinstance(child, MacroNode) and child.id() == id: # descendant = child # break # else: # for child in self.children(): # descendant = child.descendantById(id) # return descendant def ParamFactory(paramInfo): """Factory method returning param element, depends of the paramInfo argument.""" if isinstance(paramInfo.get('type'), list): param = RepeatParamNode(param=paramInfo) if param.min() > 0: param.addRepeat() else: param = SingleParamNode(param=paramInfo) return param sardana-1.6.1/src/sardana/taurus/core/tango/sardana/macroserver.py0000644000234000017500000012414312555672636027076 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 submodule. It contains specific part of macroserver""" __all__ = ['BaseInputHandler', 'BaseDoor', 'BaseMacroServer', 'registerExtensions'] __docformat__ = 'restructuredtext' import sys import time import uuid import weakref import threading import os.path as osp from lxml import etree import PyTango from taurus import Device, Factory from taurus.core.taurusmanager import TaurusManager from taurus.core.taurusbasetypes import TaurusEventType, TaurusSWDevState, \ TaurusSerializationMode from taurus.core.util.log import Logger from taurus.core.util.containers import CaselessDict from taurus.core.util.codecs import CodecFactory from taurus.core.util.event import EventGenerator, AttributeEventWait from taurus.core.tango import TangoDevice from .macro import MacroInfo, Macro, \ MacroNode, ParamFactory, RepeatNode, RepeatParamNode, SingleParamNode, \ ParamNode from .sardana import BaseSardanaElementContainer, BaseSardanaElement from .pool import getChannelConfigs CHANGE_EVT_TYPES = TaurusEventType.Change, TaurusEventType.Periodic class Attr(Logger, EventGenerator): def __init__(self, dev, name, obj_class, attr): self._dev = weakref.ref(dev) self._obj_class = obj_class self._attr = attr self.call__init__(Logger, name) event_name = '%s %s' % (dev.getNormalName(), name) self.call__init__(EventGenerator, event_name) self._attr.addListener(self) def eventReceived(self, src, type, evt_value): if type == TaurusEventType.Error: self.fireEvent(None) elif type != TaurusEventType.Config: if evt_value: self.fireEvent(evt_value.value) else: self.fireEvent(None) def getTaurusAttribute(self): return self._attr def __getattr__(self, name): return getattr(self._attr, name) class LogAttr(Attr): def __init__(self, dev, name, obj_class, attr, max_buff_size=4096): self._log_buffer = [] self._max_buff_size = max_buff_size self.call__init__(Attr, dev, name, obj_class, attr) def getLogBuffer(self): return self._log_buffer def clearLogBuffer(self): self._log_buffer = [] def eventReceived(self, src, type, evt_value): if type == TaurusEventType.Change: if evt_value is None or evt_value.value is None: self.fireEvent(None) else: self._log_buffer.extend(evt_value.value) while len(self._log_buffer) > self._max_buff_size: self._log_buffer.pop(0) if evt_value: self.fireEvent(evt_value.value) 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') 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 "input timeout" class MacroServerDevice(TangoDevice): """A class encapsulating a generic macro server device (usually a MacroServer or a Door""" def _getEventWait(self): if not hasattr(self, '_evt_wait'): # create an object that waits for attribute events. # each time we use it we have to connect and disconnect to an attribute self._evt_wait = AttributeEventWait() return self._evt_wait class ExperimentConfiguration(object): def __init__(self, door): self._door = door def get(self, cache=False): door = self._door macro_server = door.macro_server env = door.getEnvironment() ret = dict(ScanDir=env.get('ScanDir'), DataCompressionRank=env.get('DataCompressionRank', 0), PreScanSnapshot=env.get('PreScanSnapshot', [])) scan_file = env.get('ScanFile') if scan_file is None: scan_file = [] elif isinstance(scan_file, (str, unicode)): scan_file = [scan_file] ret['ScanFile'] = scan_file mnt_grps = macro_server.getElementNamesOfType("MeasurementGroup") active_mnt_grp = env.get('ActiveMntGrp') if active_mnt_grp is None and len(mnt_grps): active_mnt_grp = mnt_grps[0] door.putEnvironment('ActiveMntGrp', active_mnt_grp) ret['ActiveMntGrp'] = active_mnt_grp ret['MntGrpConfigs'] = mnt_grp_configs = CaselessDict() if len(mnt_grps) == 0: return ret mnt_grp_grps = PyTango.Group("grp") mnt_grp_grps.add(mnt_grps) codec = CodecFactory().getCodec('json') replies = mnt_grp_grps.read_attribute("configuration") for mnt_grp, reply in zip(mnt_grps, replies): try: mnt_grp_configs[mnt_grp] = \ codec.decode(('json', reply.get_data().value), ensure_ascii=True)[1] except Exception, e: from taurus.core.util.log import warning warning('Cannot load Measurement group "%s": %s', repr(mnt_grp), repr(e)) return ret def set(self, conf, mnt_grps=None): """Sets the ExperimentConfiguration dictionary.""" env = dict(ScanDir=conf.get('ScanDir'), ScanFile=conf.get('ScanFile'), DataCompressionRank=conf.get('DataCompressionRank', -1), ActiveMntGrp=conf.get('ActiveMntGrp'), PreScanSnapshot=conf.get('PreScanSnapshot')) if mnt_grps is None: mnt_grps = conf['MntGrpConfigs'].keys() self._door.putEnvironments(env) codec = CodecFactory().getCodec('json') for mnt_grp in mnt_grps: try: mnt_grp_cfg = conf['MntGrpConfigs'][mnt_grp] if mnt_grp_cfg is None: #a mntGrp to be deleted pool = self._getPoolOfElement(mnt_grp) pool.DeleteElement(mnt_grp) else: try: mnt_grp_dev = Device(mnt_grp) except: #if the mnt_grp did not already exist, create it now chconfigs = getChannelConfigs(mnt_grp_cfg) chnames, chinfos = zip(*chconfigs) #unzipping pool = self._getPoolOfElement(chnames[0]) #We assume that all the channels belong to the same pool! pool.createMeasurementGroup([mnt_grp] + list(chnames)) mnt_grp_dev = Device(mnt_grp) # TODO when we start using measurement group extension change the # code below with the following: # mnt_grp.setConfiguration(mnt_grp_cfg) data = codec.encode(('', mnt_grp_cfg))[1] mnt_grp_dev.write_attribute('configuration', data) except Exception, e: from taurus.core.util.log import error error('Could not create/delete/modify Measurement group "%s": %s', mnt_grp, repr(e)) def _getPoolOfElement(self, elementname): ms = self._door.macro_server einfo = ms.getElementInfo(elementname) poolname = einfo.pool return ms.getElementInfo(poolname) # @property # def _pool(self): # pooldict = self._door.macro_server.getElementsOfType('Pool') # if len(pooldict)==0: # raise ValueError('Cannot access the Pool') # elif len(pooldict)>1: # raise ValueError('Multiple pools are not supported') # poolinfo = pooldict.values()[0] # return poolinfo class BaseDoor(MacroServerDevice): """ Class encapsulating Door device functionality.""" On = PyTango.DevState.ON Running = PyTango.DevState.RUNNING Paused = PyTango.DevState.STANDBY Critical = 'Critical' Error = 'Error' Warning = 'Warning' Info = 'Info' Output = 'Output' Debug = 'Debug' Result = 'Result' RecordData = 'RecordData' BlockStart = '' BlockFinish = '' log_streams = (Error, Warning, Info, Output, Debug, Result) # maximum execution time without user interruption InteractiveTimeout = 0.1 def __init__(self, name, **kw): self._log_attr = CaselessDict() self._block_lines = 0 self._macro_server = None self._running_macros = None self._running_macro = None self._last_running_macro = None self._user_xml = None self._ignore_logs = kw.get("ignore_logs", False) self._silent = kw.get("silent", True) self._debug = kw.get("debug", False) self._output_stream = kw.get("output", sys.stdout) self._writeLock = threading.Lock() self._input_handler = self.create_input_handler() self.call__init__(MacroServerDevice, name, **kw) self._old_door_state = PyTango.DevState.UNKNOWN self._old_sw_door_state = TaurusSWDevState.Uninitialized self.getStateObj().addListener(self.stateChanged) for log_name in self.log_streams: tg_attr = self.getAttribute(log_name) attr = LogAttr(self, log_name, None, tg_attr) if log_name == 'Result': attr.subscribeEvent(self.resultReceived, log_name) else: attr.subscribeEvent(self.logReceived, log_name) self._log_attr[log_name] = attr input_attr = self.getAttribute("Input") input_attr.addListener(self.inputReceived) record_data_attr = self.getAttribute('RecordData') record_data_attr.addListener(self.recordDataReceived) macro_status_attr = self.getAttribute('MacroStatus') macro_status_attr.addListener(self.macroStatusReceived) self._experiment_configuration = ExperimentConfiguration(self) def create_input_handler(self): return BaseInputHandler() def get_input_handler(self): return self._input_handler def get_color_mode(self): return "NoColor" #def macrosChanged(self, s, v, t): # pass @property def log_start(self): if not hasattr(self, "_log_start"): import taurus.core.util.console if self.get_color_mode() == "NoColor": kls = taurus.core.util.console.NoColors else: kls = taurus.core.util.console.TermColors self._log_start = { BaseDoor.Critical : kls.LightRed, BaseDoor.Error : kls.Red, BaseDoor.Info : kls.LightBlue, BaseDoor.Warning : kls.Brown, BaseDoor.Output : kls.Normal, BaseDoor.Debug : kls.DarkGray, BaseDoor.Result : kls.LightGreen } return self._log_start @property def log_stop(self): if not hasattr(self, "_log_stop"): import taurus.core.util.console if self.get_color_mode() == "NoColor": kls = taurus.core.util.console.NoColors else: kls = taurus.core.util.console.TermColors self._log_stop = { BaseDoor.Critical : kls.Normal, BaseDoor.Error : kls.Normal, BaseDoor.Info : kls.Normal, BaseDoor.Warning : kls.Normal, BaseDoor.Output : kls.Normal, BaseDoor.Debug : kls.Normal, BaseDoor.Result : kls.Normal } return self._log_stop def getStateAttr(self): return self._state_attr @property def macro_server(self): if self._macro_server is None: self._macro_server = self._get_macroserver_for_door() return self._macro_server def _get_macroserver_for_door(self): """Returns the MacroServer device object in the same DeviceServer as this door""" db = self.factory().getDatabase() door_name = self.dev_name() 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 self.factory().getDevice(devs[i]) else: return None def setDebugMode(self, state): self._debug = state def getDebugMode(self): return self._debug def setSilent(self, yesno): self._silent = yesno def isSilent(self): return self._silent def getLogObj(self, log_name='Debug'): return self._log_attr.get(log_name, None) def getRunningXML(self): return self._user_xml def getRunningMacro(self): return self._running_macro def getLastRunningMacro(self): return self._last_running_macro def abort(self, synch=True): if not synch: self.command_inout("AbortMacro") return evt_wait = AttributeEventWait(self.getAttribute("state")) evt_wait.lock() try: time_stamp = time.time() self.command_inout("AbortMacro") evt_wait.waitEvent(self.Running, equal=False, after=time_stamp, timeout=self.InteractiveTimeout) finally: evt_wait.unlock() evt_wait.disconnect() def stop(self, synch=True): if not synch: self.command_inout("StopMacro") return evt_wait = AttributeEventWait(self.getAttribute("state")) evt_wait.lock() try: time_stamp = time.time() self.command_inout("StopMacro") evt_wait.waitEvent(self.Running, equal=False, after=time_stamp, timeout=self.InteractiveTimeout) finally: evt_wait.unlock() evt_wait.disconnect() def _clearRunMacro(self): # Clear the log buffer map(LogAttr.clearLogBuffer, self._log_attr.values()) self._running_macros = None self._running_macro = None self._user_xml = None self._block_lines = 0 def preRunMacro(self, obj, parameters): self._clearRunMacro() xml_root = None if isinstance(obj , (str, unicode)): if obj.startswith('<') and not parameters: xml_root = etree.fromstring(obj) else: macros = [] if len(parameters) == 0: macros_strs = obj.split('\n') for m in macros_strs: pars = m.split() macros.append((pars[0], pars[1:])) else: parameters = map(str, parameters) macros.append((obj, parameters)) xml_root = xml_seq = etree.Element('sequence') for m in macros: xml_macro = etree.SubElement(xml_seq, 'macro') xml_macro.set('name', m[0]) xml_macro.set('id', str(uuid.uuid1())) for p in m[1]: etree.SubElement(xml_macro, 'param', value=p) elif etree.iselement(obj): xml_root = obj else: raise TypeError('obj must be a string or a etree.Element') self._running_macros = {} for macro_xml in xml_root.xpath('//macro'): id, name = macro_xml.get('id'), macro_xml.get('name') self._running_macros[id] = Macro(self, name, id, macro_xml) return xml_root def postRunMacro(self, result, synch): pass def runMacro(self, obj, parameters=[], synch=False): self._user_xml = self.preRunMacro(obj, parameters) result = self._runMacro(self._user_xml, synch=synch) return self.postRunMacro(result, synch) def _runMacro(self, xml, synch=False): if not synch: return self.command_inout("RunMacro", [etree.tostring(xml)]) timeout = self.InteractiveTimeout evt_wait = self._getEventWait() evt_wait.connect(self.getAttribute("state")) evt_wait.lock() try: evt_wait.waitEvent(self.Running, equal=False, timeout=timeout) ts = time.time() result = self.command_inout("RunMacro", [etree.tostring(xml)]) evt_wait.waitEvent(self.Running, after=ts, timeout=timeout) if synch: evt_wait.waitEvent(self.Running, equal=False, after=ts, timeout=timeout) finally: self._clearRunMacro() evt_wait.unlock() evt_wait.disconnect() return result def stateChanged(self, s, t, v): self._old_door_state = self.getState() self._old_sw_door_state = self.getSWState() def resultReceived(self, log_name, result): """Method invoked by the arrival of a change event on the Result attribute""" if self._ignore_logs or self._running_macro is None: return self._running_macro.setResult(result) return result def putEnvironment(self, name, value): self.macro_server.putEnvironment(name, value) def putEnvironments(self, obj): self.macro_server.putEnvironments(obj) setEnvironment = putEnvironment setEnvironments = putEnvironments def getEnvironment(self, name=None): return self.macro_server.getEnvironment(name=name) def inputReceived(self, s, t, v): if t not in CHANGE_EVT_TYPES: return if v is None or self._running_macros is None: return input_data = CodecFactory().decode(('json', v.value)) self.processInput(input_data) def processInput(self, input_data): TaurusManager().addJob(self._processInput, None, input_data) def _processInput(self, input_data): input_type = input_data['type'] if input_type == 'input': result = self._input_handler.input(input_data) if result['input'] is '' and 'default_value' in input_data: result['input'] = input_data['default_value'] result = CodecFactory().encode('json', ('', result))[1] self.write_attribute('Input', result) elif input_type == 'timeout': self._input_handler.input_timeout(input_data) def recordDataReceived(self, s, t, v): if t not in CHANGE_EVT_TYPES: return return self._processRecordData(v) def _processRecordData(self, data): if data is None or data.value is None: return # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) data = map(str, data.value) size = len(data[1]) if size == 0: return format = data[0] codec = CodecFactory().getCodec(format) data = codec.decode(data) return data def processRecordData(self, data): pass def macroStatusReceived(self, s, t, v): if v is None or self._running_macros is None: return if t not in CHANGE_EVT_TYPES: return # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) v = map(str, v.value) if not len(v[1]): return format = v[0] codec = CodecFactory().getCodec(format) # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) v[1] = str(v[1]) fmt, data = codec.decode(v) for macro_status in data: id = macro_status.get('id') macro = self._running_macros.get(id) self._last_running_macro = self._running_macro = macro # if we don't have the ID it's because the macro is running a submacro # or another client is connected to the same door (shame on him!) and # executing a macro we discard this event if macro is not None: macro.__dict__.update(macro_status) return data def logReceived(self, log_name, output): if not output or self._silent or self._ignore_logs: return if log_name == self.Debug and not self._debug: return o = self.log_start[log_name] for line in output: if not self._debug: if line == self.BlockStart: for i in xrange(self._block_lines): o += '\x1b[2K\x1b[1A\x1b[2K' #erase current line, up one line, erase current line self._block_lines = 0 continue elif line == self.BlockFinish: continue o += "%s\n" % line self._block_lines += 1 o += self.log_stop[log_name] self.write(o) def write(self, msg, stream=None): if self.isSilent(): return msg = msg.encode('utf-8') self._output_stream = sys.stdout out = self._output_stream if not stream is None: start, stop = self.log_start.get(stream), self.log_stop.get(stream) if start is not None and stop is not None: out.write(start) out.write(msg) out.write(stop) out.flush() return out.write(msg) out.flush() def writeln(self, msg='', stream=None): self.write("%s\n" % msg, stream=stream) def getExperimentConfigurationObj(self): return self._experiment_configuration def getExperimentConfiguration(self): return self._experiment_configuration.get() def setExperimentConfiguration(self, config, mnt_grps=None): self._experiment_configuration.set(config, mnt_grps=mnt_grps) class UnknownMacroServerElementFormat(Exception): pass class MacroPath(object): def __init__(self, ms): self._ms = weakref.ref(ms) self.refresh() def refresh(self): self.macro_path = mp = self._ms().get_property("MacroPath")["MacroPath"] self.base_macro_path = osp.commonprefix(self.macro_path) self.rel_macro_path = [ osp.relpath for p in mp, self.base_macro_path ] class Environment(dict): def __init__(self, macro_server): dict.__setattr__(self, "_macro_server_", weakref.ref(macro_server)) def __setattr__(self, key, value): ms = self._macro_server_() if ms is not None: ms.putEnvironment(key, value) def __getattr__(self, key): return self[key] def __delattr__(self, key): ms = self._macro_server_() if ms is not None: ms.removeEnvironment(key) def __dir__(self): return [ key for key in self.keys() if not key.startswith("_") ] class BaseMacroServer(MacroServerDevice): """Class encapsulating Macro Server device functionality.""" def __init__(self, name, **kw): self._env = Environment(self) self._elements = BaseSardanaElementContainer() self.call__init__(MacroServerDevice, name, **kw) attr = self.getAttribute("Elements") attr.setSerializationMode(TaurusSerializationMode.Serial) attr.addListener(self.on_elements_changed) attr.setSerializationMode(TaurusSerializationMode.Concurrent) attr = self.getAttribute('Environment') attr.setSerializationMode(TaurusSerializationMode.Serial) attr.addListener(self.on_environment_changed) attr.setSerializationMode(TaurusSerializationMode.Concurrent) NO_CLASS_TYPES = 'ControllerClass', 'ControllerLibrary', \ 'MacroLibrary', 'Instrument', 'Meta', 'ParameterType' def on_environment_changed(self, evt_src, evt_type, evt_value): try: return self._on_environment_changed(evt_src, evt_type, evt_value) except Exception: self.error("Exception occurred processing environment") self.error("Details:", exc_info=1) return set(), set(), set() def _on_environment_changed(self, evt_src, evt_type, evt_value): ret = added, removed, changed = set(), set(), set() if evt_type not in CHANGE_EVT_TYPES: return ret env = CodecFactory().decode(evt_value.value) for key, value in env.get('new', {}).items(): self._addEnvironment(key, value) added.add(key) for key in env.get('del', []): self._removeEnvironment(key) removed.add(key) for key, value in env.get('change', {}).items(): self._removeEnvironment(key) self._addEnvironment(key, value) changed.add(key) return ret def _addEnvironment(self, key, value): self._env[key] = value def _removeEnvironment(self, key): try: self._env.pop(key) except KeyError: pass def putEnvironment(self, name, value): self.putEnvironments({ name : value }) def putEnvironments(self, obj): obj = dict(new=obj) codec = CodecFactory().getCodec('pickle') self.write_attribute('Environment', codec.encode(('', obj))) setEnvironment = putEnvironment setEnvironments = putEnvironments def getEnvironment(self, name=None): if name is None: return self._env else: return self._env[name] def removeEnvironment(self, key): keys = key, return self.removeEnvironments(keys) def removeEnvironments(self, keys): obj = { 'del' : keys } codec = CodecFactory().getCodec('pickle') self.write_attribute('Environment', codec.encode(('', obj))) def getObject(self, element_info): elem_type = element_info.getType() data = element_info._data if elem_type in self.NO_CLASS_TYPES: obj = object() elif "MacroCode" in element_info.interfaces: obj = self._createMacroClassObject(element_info) else: obj = self._createDeviceObject(element_info) return obj def _createMacroClassObject(self, element_info): return MacroInfo(from_json=element_info._data) def _createDeviceObject(self, element_info): return Factory().getDevice(element_info.full_name) def on_elements_changed(self, evt_src, evt_type, evt_value): try: return self._on_elements_changed(evt_src, evt_type, evt_value) except Exception: self.error("Exception occurred processing elements") self.error("Details:", exc_info=1) return set(), set(), set() def _on_elements_changed(self, evt_src, evt_type, evt_value): ret = added, removed, changed = set(), set(), set() if evt_type not in CHANGE_EVT_TYPES: return ret try: elems = CodecFactory().decode(evt_value.value, ensure_ascii=True) except: self.error("Could not decode element info format=%s len=%s", evt_value.value[0], len(evt_value.value[1])) return ret for element_data in elems.get('new', ()): element_data['manager'] = self element = self._addElement(element_data) added.add(element) for element_data in elems.get('del', ()): element = self._removeElement(element_data) removed.add(element) for element_data in elems.get('change', ()): element = self._removeElement(element_data) element_data['manager'] = self element = self._addElement(element_data) changed.add(element) return ret def _addElement(self, element_data): element = BaseSardanaElement(**element_data) self.getElementsInfo().addElement(element) return element def _removeElement(self, element_data): name = element_data['name'] element = self.getElementInfo(name) self.getElementsInfo().removeElement(element) return element def getElementsInfo(self): return self._elements def getElements(self): return self.getElementsInfo().getElements() def getElementInfo(self, name): return self.getElementsInfo().getElement(name) def getElementNamesOfType(self, elem_type): return self.getElementsInfo().getElementNamesOfType(elem_type) def getElementNamesWithInterface(self, interface): return self.getElementsInfo().getElementNamesWithInterface(interface) def getElementsWithInterface(self, interface): return self.getElementsInfo().getElementsWithInterface(interface) def getElementsWithInterfaces(self, interfaces): return self.getElementsInfo().getElementsWithInterfaces(interfaces) def getElementsOfType(self, elem_type): return self.getElementsInfo().getElementsOfType(elem_type) def getElementsOfTypes(self, elem_types): elems = CaselessDict() for elem_type in elem_types: elems.update(self.getElementsOfType(elem_type)) return elems def getInterfaces(self): return self.getElementsInfo().getInterfaces() def getExpChannelElements(self): channel_types = "CTExpChannel", "ZeroDExpChannel", "OneDExpChannel", \ "TwoDExpChannel", "PseudoCounter" return self.getElementsOfTypes(channel_types) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Macro API #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def getMacros(self): return dict(self.getElementsInfo().getElementsWithInterface('MacroCode')) def getMacroInfoObj(self, macro_name): return self.getElementsInfo().getElementWithInterface(macro_name, 'MacroCode') def getMacroStrList(self): return self.getElementNamesWithInterface('MacroCode') def getMacroNodeObj(self, macro_name): """ This method retrieves information about macro from MacroServer and creates MacroNode object, filled with all information about parameters. :param macro_name: (str) macro name :return: (MacroNode) See Also: fillMacroNodeAddidtionalInfos """ macroNode = MacroNode(name=macro_name) macroInfoObj = self.getMacroInfoObj(macro_name) if macroInfoObj is None: return allowedHookPlaces = [] hints = macroInfoObj.hints if hints is not None: for hook in hints.get('allowsHooks', []): allowedHookPlaces.append(str(hook)) macroNode.setAllowedHookPlaces(allowedHookPlaces) hasParams = bool(len(macroInfoObj.parameters)) macroNode.setHasParams(hasParams) paramsInfo = macroInfoObj.parameters for paramInfo in paramsInfo: param = ParamFactory(paramInfo) macroNode.addParam(param) return macroNode def validateMacroName(self, macroName): macroInfo = self.getElementInfo(macroName) if macroInfo is None: raise Exception("%s macro does not exist in this sardana system." % macroName) elif macroInfo.type != 'MacroClass': raise Exception("%s element is not a macro." % macroName) return True def validateMacroNode(self, macroNode): paramNodes = macroNode.children() for paramNode in paramNodes: self.validateParamNode(paramNode) return True def validateParamNode(self, paramNode): assert isinstance(paramNode, ParamNode) if isinstance(paramNode, SingleParamNode): self.validateSingleParam(paramNode) else: self.validateRepeatParam(paramNode) return True def validateSingleParam(self, singleParamNode): name = singleParamNode.name() type = singleParamNode.type() value = singleParamNode.value() if type == "Boolean": pass elif type == "Env": pass elif type == "File": pass elif type == "Filename": pass elif type == "MotorParam": pass elif type == "String": pass elif type == "User": pass elif type == "MotorParam": pass elif type == "Integer": int(value) min = singleParamNode.min() max = singleParamNode.max() if min != None and value < min: raise Exception("%s parameter value: %s is below minimum allowed value." % (name, value)) if max != None and value > max: raise Exception("%s parameter value: %s is above maximum allowed value." % (name, value)) elif type == "Float": float(value) min = singleParamNode.min() max = singleParamNode.max() if min != None and value < min: raise Exception("%s parameter value: %s is below minimum allowed value." % (name, value)) if max != None and value > max: raise Exception("%s parameter value: %s is above maximum allowed value." % (name, value)) else: allowedInterfaces = self.getInterfaces().keys() if not type in allowedInterfaces: raise Exception("No element with %s interface exist in this sardana system." % type) allowedValues = self.getElementNamesWithInterface(type) if not value in allowedValues: raise Exception("%s element with %s interface does not exist in this sardana system." % (value, type)) return True def validateRepeatParam(self, repeatParamNode): paramName = repeatParamNode.name() if repeatParamNode.isBelowMin(): raise Exception("%s param repeats has not enough repeats." % (paramName)) if repeatParamNode.isAboveMax(): raise Exception("%s param repeat has too many repeats." % (paramName)) repetitions = repeatParamNode.children() for repeat in repetitions: params = repeat.children() for param in params: if isinstance(param, SingleParamNode): self.validateSingleParam(param) else: self.validateRepeatParam(param) return True def fillMacroNodeAdditionalInfos(self, macroNode): """ This method fills macroNode information which couldn't be stored in XML file. :param macroNode: (MacroNode) macro node obj populated from XML information See Also: getMacroNodeObj """ macroName = macroNode.name() macroInfoObj = self.getMacroInfoObj(macroName) if macroInfoObj is None: raise Exception("It was not possible to get information about %s macro.\nCheck if MacroServer is alive and if this macro exist." % macroName) allowedHookPlaces = [] hints = macroInfoObj.hints or {} for hook in hints.get("allowsHooks", []): allowedHookPlaces.append(str(hook)) macroNode.setAllowedHookPlaces(allowedHookPlaces) hasParams = macroInfoObj.hasParams() macroNode.setHasParams(hasParams) if hasParams: paramList = macroInfoObj.getParamList() for paramNode, paramInfo in zip(macroNode.params(), paramList): self.__fillParamNodeAdditionalInfos(paramNode, paramInfo) def __fillParamNodeAdditionalInfos(self, paramNode, paramInfo): """ This is a protected method foreseen to use only internally by fillMacroNodeAdditionaInfos, to be called for every param node obj.""" type = paramInfo.get('type') paramNode.setDescription(str(paramInfo.get("description"))) min = paramInfo.get("min") paramNode.setMin(min) max = paramInfo.get("max") paramNode.setMax(max) if isinstance(type, list): paramNode.setParamsInfo(type) for repeatNode in paramNode.children(): for internalParamNode, internalParamInfo in zip(repeatNode.children(), type): self.__fillParamNodeAdditionalInfos(internalParamNode, internalParamInfo) else: paramNode.setType(str(type)) paramNode.setDefValue(str(paramInfo.get("default_value"))) def recreateMacroNodeAndFillAdditionalInfos(self, macroNode): """ This method filles macroNode information which couldn't be stored in plain text file. :param macroNode: (MacroNode) macro node obj populated from plain text information See Also: getMacroNodeObj """ macroName = macroNode.name() self.validateMacroName(macroName) macroInfoObj = self.getMacroInfoObj(macroName) if macroInfoObj is None: raise Exception("It was not possible to get information about %s macro.\nCheck if MacroServer is alive and if this macro exist." % macroName) allowedHookPlaces = [] hints = macroInfoObj.hints or {} for hook in hints.get("allowsHooks", []): allowedHookPlaces.append(str(hook)) macroNode.setAllowedHookPlaces(allowedHookPlaces) hasParams = macroInfoObj.hasParams() macroNode.setHasParams(hasParams) if not hasParams: return paramInfosList = macroInfoObj.getParamList() paramNodes = macroNode.params() paramIndex = 0 for paramNode, paramInfo in zip(paramNodes, paramInfosList): paramType = paramInfo.get('type') if isinstance(paramType, list): paramNode = self.__recreateParamRepeatNodes(macroNode, paramIndex, paramInfo) else: paramNode.setName(paramInfo.get("name")) self.__recreateParamNodeAdditionalInfos(paramNode, paramInfo) paramIndex += 1 self.validateMacroNode(macroNode) def __recreateParamRepeatNodes(self, macroNode, indexToStart, repeatParamInfo): #extracting rest of the single params which have to be adopted to param repeats paramNodes = [] while len(macroNode.params()) > indexToStart: lastParam = macroNode.popParam() paramNodes.append(lastParam) paramNodes.reverse() nrOfSingleParams = len(paramNodes) paramName = repeatParamInfo.get("name") min = repeatParamInfo.get("min") max = repeatParamInfo.get("max") repeatParamChildrenInfos = repeatParamInfo.get("type") if nrOfSingleParams % len(repeatParamChildrenInfos): raise Exception("Param repeat %s doesn't have correct number of repetitions" % paramName) nrOfRepeats = nrOfSingleParams / len(repeatParamChildrenInfos) repeatParamNode = RepeatParamNode(macroNode, repeatParamInfo) for repeatIdx in range(nrOfRepeats): repeatNode = RepeatNode(repeatParamNode) for singleParamInfo in repeatParamChildrenInfos: singleParamName = singleParamInfo.get('name') singleParamNode = paramNodes.pop(0) singleParamNode.setName(singleParamName) repeatNode.insertChild(singleParamNode) repeatParamNode.insertChild(repeatNode) macroNode.addParam(repeatParamNode) return repeatParamNode def __recreateParamNodeAdditionalInfos(self, paramNode, paramInfo): """ This is a protected method foreseen to use only internally by fillMacroNodeAdditionaInfos, to be called for every param node obj.""" paramType = paramInfo.get('type') min = paramInfo.get("min") max = paramInfo.get("max") paramNode.setMin(min) paramNode.setMax(max) paramNode.setDescription(str(paramInfo.get("description"))) if type(paramType) == list: paramNode.setParamsInfo(paramType) for repeatNode in paramNode.children(): for internalParamNode, internalParamInfo in zip(repeatNode.children(), paramType): self.__recreateParamNodeAdditionalInfos(internalParamNode, internalParamInfo) else: paramNode.setType(paramType) paramNode.setDefValue(str(paramInfo.get("default_value"))) def getMacroPathObj(self, cache=False): if not hasattr(self, "_macro_path"): self._macro_path = MacroPath(self) elif not cache: self._macro_path.refresh() return self._macro_path def registerExtensions(): """Registers the macroserver extensions in the :class:`taurus.core.tango.TangoFactory`""" factory = Factory('tango') factory.registerDeviceClass('MacroServer', BaseMacroServer) factory.registerDeviceClass('Door', BaseDoor) def unregisterExtensions(): """Registers the macroserver extensions in the :class:`taurus.core.tango.TangoFactory`""" factory = Factory('tango') factory.unregisterDeviceClass('MacroServer') factory.unregisterDeviceClass('Door') sardana-1.6.1/src/sardana/taurus/core/tango/sardana/motion.py0000644000234000017500000004753012555672636026057 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 motion submodule. It contains specific part of sardana motion""" __all__ = ["Moveable", "MoveableSource", "Motion", "MotionGroup"] __docformat__ = 'restructuredtext' import time from taurus.core.util.containers import CaselessDict class Moveable: """ An item that can 'move'. In order to move it you need to provide a list of values (normally interpreted as motor positions). Therefore this Moveable can represent a single motor, a group of motors""" def __init__(self): pass def startMove(self, new_pos, timeout=None): """ startMove(sequence new_pos, double timeout=None) -> sequence Calling this method will trigger a movement off all components of the movement.""" pass def waitMove(self, timeout=None, id=None): """ waitMove(float timeout=None, sequence id=None) -> None Waits for the movement to end. If no movement is active the method returns immediately.""" pass def move(self, new_pos, timeout=None): """ move(list new_pos, timeout=None) -> None Triggers a movement and waits for it to end. """ self.waitMove(id=self.startMove(new_pos, timeout=timeout)) def iterMove(self, new_pos, timeout=None): """ generator for motor positions""" pass def getLastMotionTime(self): raise NotImplementedError def getTotalLastMotionTime(): raise NotImplementedError def abort(self, wait_ready=True, timeout=None): pass def readPosition(self, force=False): pass def getMoveableSource(self): return None def getSize(self): return 0 def getIndex(self, name): pass class MoveableSource: """ A container of Moveable items. """ def __init__(self): pass def getMoveable(self, names): """ getMoveable(list names) -> Moveable Returns a Moveable object that handles all the moveable items given in names. """ pass class BaseMotion(Moveable): def __init__(self, elements, moveable_srcs, allow_repeat=False, allow_unknown=False, read_only=False): self.read_only = read_only if len(elements) == 0: raise Exception("Motion with no elements") first_elem = elements[0] if isinstance(first_elem, (str, unicode)): self.init_by_names(elements, moveable_srcs, allow_repeat, allow_unknown) else: self.init_by_movables(elements, moveable_srcs, allow_repeat, allow_unknown) def getMoveable(self, sources, name): for source in sources: moveable = source.getMoveable(name) if moveable is not None: return moveable class MotionGroup(BaseMotion): """ A virtual motion group object """ def __init__(self, elements, moveable_srcs, allow_repeat=False, allow_unknown=False, read_only=False): BaseMotion.__init__(self, elements, moveable_srcs, allow_repeat=allow_repeat, allow_unknown=allow_unknown, read_only=read_only) self.__total_motion_time = 0 def init_by_movables(self, elements, moveable_srcs, allow_repeat, allow_unknown): self.moveable_list = elements def init_by_names(self, names, moveable_srcs, allow_repeat, allow_unknown): moveables = [ self.getMoveable(moveable_srcs, name) for name in names ] self.init_by_movables(moveables, moveable_srcs, allow_repeat, allow_unknown) def getLastMotionTime(self): times = [ moveable.getLastMotionTime() for moveable in self.moveable_list ] return max(times) def getTotalLastMotionTime(): return self.__total_motion_time def startMove(self, pos_list, timeout=None): if self.read_only: raise Exception("Trying to move read only motion") if len(pos_list) != len(self.moveable_list): raise Exception("Invalid number of position values") ids = [] for i, moveable in enumerate(self.moveable_list): ids.append(moveable.startMove(pos_list[i], timeout=timeout)) return ids def waitMove(self, timeout=None, id=None): if id is None: id = len(self.moveable_list) * [None] for i, moveable in enumerate(self.moveable_list): moveable.waitMove(timeout=timeout, id=id[i]) def move(self, new_pos, timeout=None): start_time = time.time() states, positions = [], [] for moveable, pos in zip(self.moveable_list, new_pos): res = moveable.move(pos, timeout=timeout) states.append(res[0]) positions.extend(res[1]) import PyTango state = PyTango.DevState.ON if PyTango.DevState.FAULT in states: state = PyTango.DevState.FAULT elif PyTango.DevState.ALARM in states: state = PyTango.DevState.ALARM elif PyTango.DevState.UNKNOWN in states: state = PyTango.DevState.UNKNOWN elif PyTango.DevState.MOVING in states: state = PyTango.DevState.MOVING self.__total_motion_time = time.time() - start_time return state, positions def iterMove(self, new_pos, timeout=None): """ generator for motor positions""" raise NotImplementedError def getStatus(self): # res = [] # for moveable in self.moveable_list: # status = moveable.status.split('\n') # res.append(moveable.getName() + ":") # for st in status: # res.append(" " + st) # return "\n".join(res) return "\n".join([ m.status() for m in self.moveable_list ]) def readState(self, force=False): if len(self.moveable_list) == 1: return self.moveable_list[0].getState() return [ m.getState() for m in self.moveable_list ] def readPosition(self, force=False): return [ m.readPosition(force=force) for m in self.moveable_list ] def abort(self, wait_ready=True, timeout=None): for moveable in self.moveable_list: try: moveable.abort(wait_ready=wait_ready, timeout=timeout) except: pass def stop(self, wait_ready=True, timeout=None): for moveable in self.moveable_list: try: moveable.stop(wait_ready=wait_ready, timeout=timeout) except: pass def read(self): pass class Motion(BaseMotion): """ A motion object """ def __init__(self, elements, moveable_srcs, allow_repeat=False, allow_unknown=False, read_only=False): BaseMotion.__init__(self, elements, moveable_srcs, allow_repeat=allow_repeat, allow_unknown=allow_unknown, read_only=read_only) self.__total_motion_time = 0 def init_by_movables(self, elements, moveable_srcs, allow_repeat, allow_unknown): # TODO: Optimize this. Dont call init_by_names. It its possible to do it # manually with some performance gain names = [ elem.getName() for elem in elements] self.init_by_names(names, moveable_srcs, allow_repeat, allow_unknown) def init_by_names(self, names, moveable_srcs, allow_repeat, allow_unknown): ms_elem_names = self.getElemNamesByMoveableSource(names, moveable_srcs, allow_repeat=allow_repeat, allow_unknown=allow_unknown) # map ms_moveables = {} for moveable_source, ms_names in ms_elem_names.items(): moveable = moveable_source.getMoveable(ms_names) ms_moveables[moveable_source] = moveable # list moveable_list = ms_moveables.values() # list pos_to_moveable = len(names) * [None, ] for i, name in enumerate(names): moveable_index, position_index = -1, -1 for j, moveable in enumerate(moveable_list): position_index = moveable.getIndex(name) if position_index >= 0: pos_to_moveable[i] = (j, position_index) break # list moveable item names self.names = names # list self.moveable_list = moveable_list # list # the list index itself is the position index for this motion # the tuple for a given index gives the corresponding moveable index and # the position index inside the moveable object self.pos_to_moveable = pos_to_moveable # map self.ms_moveables = ms_moveables # a buffer for positions for performance reasons #list> index of outer list is the moveable index. The #contents of the list are the ordered positions for that moveable pos_buff = [] total_count = 0 for m in moveable_list: count = m.getSize() total_count += count pos_buff.append(m.getSize() * [0.0, ]) self.pos_buff = pos_buff assert(len(self.pos_to_moveable) == len(self.names)) assert(total_count == len(self.names)) def getElemNamesByMoveableSource(self, names, moveable_sources, allow_repeat, allow_unknown): """ getElemNamesByMoveableSource(listnames, list moveable_sources, bool allow_repeat, bool allow_unknown) Organizes the elements by moveable source. The result is a dictionary with key being the MoveableSource and data a list of the names that belong to the that motion source. """ ms_elems = {} for name in names: moveable = None for moveable_source in moveable_sources: moveable = moveable_source.getMoveable([name]) if not moveable is None: if not ms_elems.has_key(moveable_source): ms_elems[moveable_source] = [] moveable_source_moveables = ms_elems.get(moveable_source) present = name in moveable_source_moveables if not present or (present and allow_repeat): moveable_source_moveables.append(name) break elif present and not allow_repeat: raise Exception("Moveable item %s appears more " "than once" % name) if moveable is None and not allow_unknown: raise Exception("Moveable item %s not found" % name) return ms_elems def getLastMotionTime(self): times = [ moveable.getLastMotionTime() for moveable in self.moveable_list ] return max(times) def getTotalLastMotionTime(): return self.__total_motion_time def startMove(self, pos_list, timeout=None): if self.read_only: raise Exception("Trying to move read only motion") if len(pos_list) != len(self.names): raise Exception("Invalid number of position values") buff = self.pos_buff for i, pair in enumerate(self.pos_to_moveable): pos = pos_list[i] buff[pair[0]][pair[1]] = pos ids = [] for i, moveable in enumerate(self.moveable_list): ids.append(moveable.startMove(buff[i], timeout=timeout)) return ids def waitMove(self, timeout=None, id=None): if id is None: id = len(self.moveable_list) * [None] for i, moveable in enumerate(self.moveable_list): moveable.waitMove(timeout=timeout, id=id[i]) def move(self, new_pos, timeout=None): start_time = time.time() if len(self.moveable_list) == 1: moveable = self.moveable_list[0] ret = moveable.move(new_pos, timeout=timeout) else: start, ids = 0, [] for moveable in self.moveable_list: end = start + moveable.getSize() pos = new_pos[start:end] id = moveable.startMove(pos, timeout=timeout) ids.append(id) start = end for moveable, id in zip(self.moveable_list, ids): moveable.waitMove(id=id, timeout=timeout) states, positions = self.readState(), self.readPosition() import PyTango state = PyTango.DevState.ON if PyTango.DevState.FAULT in states: state = PyTango.DevState.FAULT elif PyTango.DevState.ALARM in states: state = PyTango.DevState.ALARM elif PyTango.DevState.UNKNOWN in states: state = PyTango.DevState.UNKNOWN elif PyTango.DevState.MOVING in states: state = PyTango.DevState.MOVING ret = state, positions self.__total_motion_time = time.time() return ret def iterMove(self, new_pos, timeout=None): """ generator for motor positions""" assert len(self.moveable_list) == 1, "for now we support only 'simple' motions!!!!" moveable = self.moveable_list[0] for p in moveable.iterMove(new_pos, timeout=timeout): yield p def getStatus(self): return "\n".join([ m.status() for m in self.moveable_list ]) def readState(self, force=False): if len(self.moveable_list) == 1: return self.moveable_list[0].getState() return [ m.getState() for m in self.moveable_list ] def readPosition(self, force=False): moveable_pos_list = [ m.readPosition(force=force) for m in self.moveable_list ] pos = [ moveable_pos_list[pair[0]][pair[1]] for pair in self.pos_to_moveable ] return pos def abort(self, wait_ready=True, timeout=None): for moveable in self.moveable_list: moveable.abort(wait_ready=wait_ready, timeout=timeout) def stop(self, wait_ready=True, timeout=None): for moveable in self.moveable_list: moveable.stop(wait_ready=wait_ready, timeout=timeout) def read(self): pass #------------------------------------------------------------------------------- # Small test framework #------------------------------------------------------------------------------- class PoolMoveableTest(Moveable): def __init__(self, name, elems, moveable_src, mov_items=None): self.name = name self.elem_names = elems self.moveable_src = moveable_src self.pos = len(elems) * [0.0, ] def startMove(self, new_pos, timeout=None): self.pos = new_pos # return the id as time_stamp return len(self.elem_names) * [time.time()] def waitMove(self, timeout=None, id=None): pass def abort(self, wait_ready=True, timeout=None): pass def readPosition(self, force=False): return self.pos def getMoveableSource(self): return self.moveable_src def getSize(self): return len(self.elem_names) def getIndex(self, name): try: return self.elem_names.index(name) except: return -1 class PoolMSTest(MoveableSource): def __init__(self, initial_elems): MoveableSource.__init__(self) self.elem_names = initial_elems self.moveable_inc = 0 self.motors = CaselessDict() for elem_name in initial_elems: self.motors[elem_name] = PoolMoveableTest(elem_name, [elem_name], self) self.motor_group = None def getMoveable(self, names): if len(names) == 1: return self.motors.get(names[0]) l = [name for name in self.elem_names if name in names] self.motor_group = PoolMoveableTest("moveable %d" % self.moveable_inc, l, self) self.moveable_inc += 1 return self.motor_group def test(): ms1 = PoolMSTest(["m1", "m2", "m3", "m4"]) ms2 = PoolMSTest(["m5", "m6", "m7", "m8"]) ms3 = PoolMSTest(["m9", "m10", "m11", "m12"]) motion1 = Motion(["m1"], [ms1, ms2, ms3]) # some tests for p in [[5.0], [20.0], [0.0], [-14.5], [0.0]]: motion1.move(p) assert(ms1.motors["m1"].pos[0] == p[0]) assert(motion1.readPosition() == p) motion2 = Motion(["m1", "m2", "m3"], [ms1, ms2, ms3]) for p in [[5.0, 20.0, 0.0], [-14.5, 3.32, 232], [0.0, 0.0, 0.0]]: motion2.move(p) assert(ms1.motor_group.pos == p) assert(motion2.readPosition() == p) motion3 = Motion(["m3", "m1", "m2"], [ms1, ms2, ms3]) for p in [[5.0, 20.0, 0.0], [-14.5, 3.32, 232], [0.0, 0.0, 0.0]]: motion3.move(p) assert(ms1.motor_group.pos[0] == p[1]) assert(ms1.motor_group.pos[1] == p[2]) assert(ms1.motor_group.pos[2] == p[0]) assert(motion3.readPosition() == p) motion4 = Motion(["m2", "m6"], [ms1, ms2, ms3]) for p in [[5.0, 20.0], [-14.5, 3.32], [0.0, 0.0]]: motion4.move(p) assert(ms1.motors["m2"].pos[0] == p[0]) assert(ms2.motors["m6"].pos[0] == p[1]) assert(motion4.readPosition() == p) motion5 = Motion(["m3", "m1", "m7"], [ms1, ms2, ms3]) for p in [[5.0, 20.0, 0.0], [-14.5, 3.32, 232], [0.0, 0.0, 0.0]]: motion5.move(p) assert(ms1.motor_group.pos[1] == p[0]) assert(ms1.motor_group.pos[0] == p[1]) assert(ms2.motors["m7"].pos[0] == p[2]) assert(motion5.readPosition() == p) motion6 = Motion(["m4", "m9", "m10", "m2"], [ms1, ms2, ms3]) for p in [[5.0, 20.0, 0.0, 21.0], [-14.5, 3.32, 232, 45.4], [0.0, 0.0, 0.0, 0.0]]: motion6.move(p) assert(ms1.motor_group.pos[1] == p[0]) assert(ms1.motor_group.pos[0] == p[3]) assert(ms3.motor_group.pos[0] == p[1]) assert(ms3.motor_group.pos[1] == p[2]) assert(motion6.readPosition() == p) motion7 = Motion(["m4", "m9", "m7", "m2"], [ms1, ms2, ms3]) for p in [[5.0, 20.0, 0.0, 21.0], [-14.5, 3.32, 232, 45.4], [0.0, 0.0, 0.0, 0.0]]: motion7.move(p) assert(ms1.motor_group.pos[1] == p[0]) assert(ms1.motor_group.pos[0] == p[3]) assert(ms3.motors["m9"].pos[0] == p[1]) assert(ms2.motors["m7"].pos[0] == p[2]) assert(motion7.readPosition() == p) try: m = Motion(["m1", "m2"], [ms1, ms2, ms3], read_only=True) m.startMove([0.5, 20.4]) except Exception, e: assert(e.message == "Trying to move read only motion") try: m = Motion(["m1", "m1"], [ms1, ms2, ms3]) except Exception, e: assert(e.message == "Moveable item m1 appears more than once") try: m = Motion(["m1", "m999"], [ms1, ms2, ms3]) except Exception, e: assert(e.message == "Moveable item m999 not found") if __name__ == "__main__": test() sardana-1.6.1/src/sardana/taurus/core/tango/sardana/pool.py0000644000234000017500000016416212555672636025524 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 device pool submodule. It contains specific part of sardana device pool""" __all__ = ["InterruptException", "StopException", "AbortException", "BaseElement", "ControllerClass", "ControllerLibrary", "PoolElement", "Controller", "ComChannel", "ExpChannel", "CTExpChannel", "ZeroDExpChannel", "OneDExpChannel", "TwoDExpChannel", "PseudoCounter", "Motor", "PseudoMotor", "MotorGroup", "MeasurementGroup", "IORegister", "Instrument", "Pool", "registerExtensions", "getChannelConfigs"] __docformat__ = 'restructuredtext' import os import sys import time import weakref import operator import traceback from PyTango import DevState, AttrDataFormat, AttrQuality, DevFailed, \ DeviceProxy from taurus import Factory, Device from taurus.core.taurusbasetypes import TaurusEventType, TaurusSWDevState, \ TaurusSerializationMode from taurus.core.taurusvalidator import AttributeNameValidator from taurus.core.util.log import Logger from taurus.core.util.singleton import Singleton from taurus.core.util.codecs import CodecFactory from taurus.core.util.containers import CaselessDict from taurus.core.util.event import EventGenerator, AttributeEventWait, \ AttributeEventIterator from taurus.core.tango import TangoDevice, FROM_TANGO_TO_STR_TYPE from .sardana import BaseSardanaElementContainer, BaseSardanaElement from .motion import Moveable, MoveableSource Ready = Standby = DevState.ON Counting = Acquiring = Moving = DevState.MOVING Alarm = DevState.ALARM Fault = DevState.FAULT CHANGE_EVT_TYPES = TaurusEventType.Change, TaurusEventType.Periodic MOVEABLE_TYPES = 'Motor', 'PseudoMotor', 'MotorGroup' QUALITY = { AttrQuality.ATTR_VALID : 'VALID', AttrQuality.ATTR_INVALID : 'INVALID', AttrQuality.ATTR_CHANGING : 'CHANGING', AttrQuality.ATTR_WARNING : 'WARNING', AttrQuality.ATTR_ALARM : 'ALARM', None : 'UNKNOWN' } class InterruptException(Exception): pass class StopException(InterruptException): pass class AbortException(InterruptException): pass class BaseElement(object): """ The base class for elements in the Pool (Pool itself, Motor, ControllerClass, ExpChannel all should inherit from this class directly or indirectly) """ def __repr__(self): pd = self.getPoolData() return "{0}({1})".format(pd['type'], pd['full_name']) def __str__(self): return self.getName() def serialize(self): return self.getPoolData() def str(self, n=0): """Returns a sequence of strings representing the object in 'consistent' way. Default is to return , , :param n: the number of elements in the tuple.""" if n == 0: return CodecFactory.encode(('json'), self.serialize()) return self._str_tuple[:n] def __cmp__(self, o): return cmp(self.getPoolData()['full_name'], o.getPoolData()['full_name']) def getName(self): return self.getPoolData()['name'] def getPoolObj(self): return self._pool_obj def getPoolData(self): try: return self._pool_data except AttributeError: self._pool_data = self._find_pool_data() return self._pool_data class ControllerClass(BaseElement): def __init__(self, **kw): self.__dict__.update(kw) self.path, self.f_name = os.path.split(self.file_name) self.lib_name, self.ext = os.path.splitext(self.f_name) def __repr__(self): pd = self.getPoolData() return "ControllerClass({0})".format(pd['full_name']) def getSimpleFileName(self): return self.f_name def getFileName(self): return self.file_name def getClassName(self): return self.getName() def getType(self): return self.getTypes()[0] def getTypes(self): return self.types def getLib(self): return self.f_name def getGender(self): return self.gender def getModel(self): return self.model def getOrganization(self): return self.organization def __cmp__(self, o): t = cmp(self.getType(), o.getType()) if t != 0: return t t = cmp(self.getGender(), o.getGender()) if t != 0: return t return cmp(self.getClassName(), o.getClassName()) class ControllerLibrary(BaseElement): def __init__(self, **kw): self.__dict__.update(kw) def getType(self): return self.getTypes()[0] def getTypes(self): return self.type class TangoAttributeEG(Logger, EventGenerator): """An event generator for a 'State' attribute""" def __init__(self, attr): self._attr = attr self.call__init__(Logger, 'EG', attr) event_name = '%s EG' % (attr.getParentObj().getNormalName()) self.call__init__(EventGenerator, event_name) self._attr.addListener(self) def getAttribute(self): return self._attr def eventReceived(self, evt_src, evt_type, evt_value): """Event handler from Taurus""" if evt_type not in CHANGE_EVT_TYPES: return if evt_value is None: v = None else: v = evt_value.value EventGenerator.fireEvent(self, v) def read(self, force=False): try: self.last_val = self._attr.read(cache=not force).value except: self.error("Read error") self.debug("Details:", exc_info=1) self.last_val = None return EventGenerator.read(self) def readValue(self, force=False): r = self.read(force=force) if r is None: # do a retry r = self.read(force=force) return r def write(self, value): self._attr.write(value, with_read=False) def __getattr__(self, name): return getattr(self._attr, name) def reservedOperation(fn): def new_fn(*args, **kwargs): self = args[0] wr = self.getReservedWR() if wr is not None: if wr().isStopped(): raise StopException("stopped before calling %s" % fn.__name__) elif wr().isAborted(): raise AbortException("aborted before calling %s" % fn.__name__) try: return fn(*args, **kwargs) except: print "Exception occured in reserved operation: clearing events..." self._clearEventWait() raise return new_fn def get_pool_for_device(db, device): server_devs = db.get_device_class_list(device.info().server_id) for dev_name, klass_name in zip(server_devs[0::2], server_devs[1::2]): if klass_name == "Pool": return Device(dev_name) class PoolElement(BaseElement, TangoDevice): """Base class for a Pool element device.""" def __init__(self, name, **kwargs): """PoolElement initialization.""" self._reserved = None self._evt_wait = None self.__go_start_time = 0 self.__go_end_time = 0 self.__go_time = 0 self._total_go_time = 0 self.call__init__(TangoDevice, name, **kwargs) # dict # key : the attribute name # value : the corresponding TangoAttributeEG self._attrEG = CaselessDict() # force the creation of a state attribute self.getStateEG() def _find_pool_data(self): pool = get_pool_for_device(self.getParentObj(), self.getHWObj()) return pool.getElementInfo(self.getFullName())._data def cleanUp(self): TangoDevice.cleanUp(self) self._reserved = None f = self.factory() attr_map = self._attrEG for attr_name in attr_map.keys(): attrEG = attr_map.pop(attr_name) attr = attrEG.getAttribute() attrEG = None f.removeExistingAttribute(attr) def reserve(self, obj): if obj is None: self._reserved = None return self._reserved = weakref.ref(obj, self._unreserveCB) def _unreserveCB(self, obj): self.unreserve() def unreserve(self): self._reserved = None def isReserved(self, obj=None): if obj is None: return self._reserved is not None else: o = self._reserved() return o == obj def getReservedWR(self): return self._reserved def getReserved(self): if self._reserved is None: return None return self._reserved() def dump_attributes(self): attr_names = self.get_attribute_list() req_id = self.read_attributes_asynch(attr_names) return self.read_attributes_reply(req_id, 2000) def _getAttrValue(self, name, force=False): attrEG = self._getAttrEG(name) if attrEG is None: return None return attrEG.readValue(force=force) def _getAttrEG(self, name): attrEG = self.getAttrEG(name) if attrEG is None: attrEG = self._createAttribute(name) return attrEG def _createAttribute(self, name): attrObj = self.getAttribute(name) if attrObj is None: self.warning("Unable to create attribute %s" % name) return None, None attrEG = TangoAttributeEG(attrObj) self._attrEG[name] = attrEG return attrEG def _getEventWait(self): if self._evt_wait is None: # create an object that waits for attribute events. # each time we use it we have to connect and disconnect to an attribute self._evt_wait = AttributeEventWait() return self._evt_wait def _clearEventWait(self): self._evt_wait = None def getStateEG(self): return self._getAttrEG('state') def getControllerName(self): return self.getControllerObj().name def getControllerObj(self): full_ctrl_name = self.getPoolData()['controller'] return self.getPoolObj().getObj(full_ctrl_name, "Controller") def getAxis(self): return self.getPoolData()['axis'] def getType(self): return self.getPoolData()['type'] def getPoolObj(self): return self._pool_obj def waitReady(self, timeout=None): return self.getStateEG().waitEvent(Moving, equal=False, timeout=timeout) def getAttrEG(self, name): """Returns the TangoAttributeEG object""" return self._attrEG.get(name) def getAttrObj(self, name): """Returns the taurus.core.tangoattribute.TangoAttribute object""" attrEG = self._attrEG.get(name) if attrEG is None: return None return attrEG.getAttribute() def getInstrumentObj(self): return self._getAttrEG('instrument') def getInstrumentName(self, force=False): instr_name = self._getAttrValue('instrument', force=force) if not instr_name: return '' #instr_name = instr_name[:instr_name.index('(')] return instr_name def getInstrument(self): instr_name = self.getInstrumentName() if not instr_name: return None return self.getPoolObj().getObj("Instrument", instr_name) @reservedOperation def start(self, *args, **kwargs): evt_wait = self._getEventWait() evt_wait.connect(self.getAttribute("state")) evt_wait.lock() try: evt_wait.waitEvent(DevState.MOVING, equal=False) self.__go_time = 0 self.__go_start_time = ts1 = time.time() self._start(*args, **kwargs) ts2 = time.time() evt_wait.waitEvent(DevState.MOVING, after=ts1) except: evt_wait.disconnect() raise finally: evt_wait.unlock() ts2 = evt_wait.getRecordedEvents().get(DevState.MOVING, ts2) return (ts2,) @reservedOperation def waitFinish(self, timeout=None, id=None): if id is not None: id = id[0] evt_wait = self._getEventWait() evt_wait.lock() try: evt_wait.waitEvent(DevState.MOVING, after=id, equal=False, timeout=timeout) finally: self.__go_end_time = time.time() self.__go_time = self.__go_end_time - self.__go_start_time evt_wait.unlock() evt_wait.disconnect() @reservedOperation def go(self, *args, **kwargs): self._total_go_time = 0 start_time = time.time() eid = self.start(*args, **kwargs) self.waitFinish(id=eid) self._total_go_time = time.time() - start_time def getLastGoTime(self): """Returns the time it took for last go operation""" return self.__go_time def getTotalLastGoTime(self): """Returns the time it took for last go operation, including dead time to prepare, wait for events, etc""" return self._total_go_time def abort(self, wait_ready=True, timeout=None): state = self.getStateEG() state.lock() try: self.command_inout("Abort") if wait_ready: self.waitReady(timeout=timeout) finally: state.unlock() def stop(self, wait_ready=True, timeout=None): state = self.getStateEG() state.lock() try: self.command_inout("Stop") if wait_ready: self.waitReady(timeout=timeout) finally: state.unlock() def information(self, tab=' '): msg = self._information(tab=tab) return "\n".join(msg) def _information(self, tab=' '): indent = "\n" + tab + 10 * ' ' msg = [ self.getName() + ":" ] try: state = str(self.state()).capitalize() except DevFailed, df: if len(df.args): state = df.args[0].desc else: e_info = sys.exc_info()[:2] state = traceback.format_exception_only(*e_info) except: e_info = sys.exc_info()[:2] state = traceback.format_exception_only(*e_info) msg.append(tab + " State: " + state) try: e_info = sys.exc_info()[:2] status = self.status() status = status.replace('\n', indent) except DevFailed, df: if len(df.args): status = df.args[0].desc else: e_info = sys.exc_info()[:2] status = traceback.format_exception_only(*e_info) except: e_info = sys.exc_info()[:2] status = traceback.format_exception_only(*e_info) msg.append(tab + " Status: " + status) return msg class Controller(PoolElement): """ Class encapsulating Controller functionality.""" def __init__(self, name, **kw): """PoolElement initialization.""" self.call__init__(PoolElement, name, **kw) def getModuleName(self): return self.getPoolData()['module'] def getClassName(self): return self.getPoolData()['klass'] def getTypes(self): return self.getPoolData()['types'] def getMainType(self): return self.getPoolData()['main_type'] def addElement(self, elem): axis = elem.getAxis() self._elems[axis] = elem self._last_axis = max(self._last_axis, axis) def removeElement(self, elem): axis = elem.getAxis() del self._elems[elem.getAxis()] if axis == self._last_axis: self._last_axis = max(self._elems) def getElementByAxis(self, axis): pool = self.getPoolObj() for _, elem in pool.getElementsOfType(self.getMainType()).items(): if elem.controller != self.getName() or elem.getAxis() != axis: continue return elem def getElementByName(self, name): pool = self.getPoolObj() for name, elem in pool.getElementsOfType(self.getMainType()).items(): if elem.controller != self.getName() or elem.getName() != name: continue return elem def getUsedAxis(self): pool = self.getPoolObj() axis = [] for _, elem in pool.getElementsOfType(self.getMainType()).items(): if elem.controller != self.getName(): continue axis.append(elem.getAxis()) return sorted(axis) def getLastUsedAxis(self): return max([1] + self.getUsedAxis()) def __cmp__(self, o): return cmp(self.getName(), o.getName()) class ComChannel(PoolElement): """ Class encapsulating CommunicationChannel functionality.""" pass class ExpChannel(PoolElement): """ Class encapsulating ExpChannel functionality.""" pass class CTExpChannel(ExpChannel): """ Class encapsulating CTExpChannel functionality.""" pass class ZeroDExpChannel(ExpChannel): """ Class encapsulating ZeroDExpChannel functionality.""" pass class OneDExpChannel(ExpChannel): """ Class encapsulating OneDExpChannel functionality.""" pass class TwoDExpChannel(ExpChannel): """ Class encapsulating TwoDExpChannel functionality.""" pass class PseudoCounter(ExpChannel): """ Class encapsulating PseudoCounter functionality.""" pass class Motor(PoolElement, Moveable): """ Class encapsulating Motor functionality.""" def __init__(self, name, **kw): """PoolElement initialization.""" self.call__init__(PoolElement, name, **kw) self.call__init__(Moveable) def getPosition(self, force=False): return self._getAttrValue('position', force=force) def getDialPosition(self, force=False): return self._getAttrValue('dialposition', force=force) def getVelocity(self, force=False): return self._getAttrValue('velocity', force=force) def getAcceleration(self, force=False): return self._getAttrValue('acceleration', force=force) def getDeceleration(self, force=False): return self._getAttrValue('deceleration', force=force) def getBaseRate(self, force=False): return self._getAttrValue('base_rate', force=force) def getBacklash(self, force=False): return self._getAttrValue('backlash', force=force) def getLimitSwitches(self, force=False): return self._getAttrValue('limit_switches', force=force) def getOffset(self, force=False): return self._getAttrValue('offset', force=force) def getStepPerUnit(self, force=False): return self._getAttrValue('step_per_unit', force=force) def getSign(self, force=False): return self._getAttrValue('Sign', force=force) def getSimulationMode(self, force=False): return self._getAttrValue('SimulationMode', force=force) def getPositionObj(self): return self._getAttrEG('position') def getDialPositionObj(self): return self._getAttrEG('dialposition') def getVelocityObj(self): return self._getAttrEG('velocity') def getAccelerationObj(self): return self._getAttrEG('acceleration') def getDecelerationObj(self): return self._getAttrEG('deceleration') def getBaseRateObj(self): return self._getAttrEG('base_rate') def getBacklashObj(self): return self._getAttrEG('backlash') def getLimitSwitchesObj(self): return self._getAttrEG('limit_switches') def getOffsetObj(self): return self._getAttrEG('offset') def getStepPerUnitObj(self): return self._getAttrEG('step_per_unit') def getSimulationModeObj(self): return self._getAttrEG('step_per_unit') def setVelocity(self, value): return self.getVelocityObj().write(value) def setAcceleration(self, value): return self.getAccelerationObj().write(value) def setDeceleration(self, value): return self.getDecelerationObj().write(value) def setBaseRate(self, value): return self.getBaseRateObj().write(value) def setBacklash(self, value): return self.getBacklashObj().write(value) def setOffset(self, value): return self.getOffsetObj().write(value) def setStepPerUnit(self, value): return self.getStepPerUnitObj().write(value) def setSign(self, value): return self.getSignObj().write(value) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Moveable interface # def _start(self, *args, **kwargs): new_pos = args[0] if operator.isSequenceType(new_pos): new_pos = new_pos[0] try: self.write_attribute('position', new_pos) except DevFailed, df: for err in df: if err.reason == 'API_AttrNotAllowed': raise RuntimeError('%s is already moving' % self) else: raise self.final_pos = new_pos def go(self, *args, **kwargs): start_time = time.time() PoolElement.go(self, *args, **kwargs) ret = self.getStateEG().readValue(), self.readPosition() self._total_go_time = time.time() - start_time return ret startMove = PoolElement.start waitMove = PoolElement.waitFinish move = go getLastMotionTime = PoolElement.getLastGoTime getTotalLastMotionTime = PoolElement.getTotalLastGoTime @reservedOperation def iterMove(self, new_pos, timeout=None): if operator.isSequenceType(new_pos): new_pos = new_pos[0] state, pos = self.getAttribute("state"), self.getAttribute("position") evt_wait = self._getEventWait() evt_wait.connect(state) evt_wait.lock() try: #evt_wait.waitEvent(DevState.MOVING, equal=False) time_stamp = time.time() try: self.getPositionObj().write(new_pos) except DevFailed, err_traceback: for err in err_traceback: if err.reason == 'API_AttrNotAllowed': raise RuntimeError, '%s is already moving' % self else: raise self.final_pos = new_pos # putting timeout=0.1 and retries=1 is a patch for the case the when the initial # moving event doesn't arrive do to an unknow tango/pytango error at the time evt_wait.waitEvent(DevState.MOVING, time_stamp, timeout=0.1, retries=1) finally: evt_wait.unlock() evt_wait.disconnect() evt_iter_wait = AttributeEventIterator(state, pos) evt_iter_wait.lock() try: for evt_data in evt_iter_wait.events(): src, value = evt_data if src == state and value != DevState.MOVING: raise StopIteration yield value finally: evt_iter_wait.unlock() evt_iter_wait.disconnect() def readPosition(self, force=False): return [ self.getPosition(force=force) ] def getMoveableSource(self): return self.getPoolObj() def getSize(self): return 1 def getIndex(self, name): if name.lower() == self.getName().lower(): return 0 return -1 # # End of Moveable interface #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def _information(self, tab=' '): msg = PoolElement._information(self, tab=tab) try: position = self.read_attribute("position") pos = str(position.value) if position.quality != AttrQuality.ATTR_VALID: pos += " [" + QUALITY[position.quality] + "]" except DevFailed, df: if len(df.args): pos = df.args[0].desc else: e_info = sys.exc_info()[:2] pos = traceback.format_exception_only(*e_info) except: e_info = sys.exc_info()[:2] pos = traceback.format_exception_only(*e_info) msg.append(tab + "Position: " + str(pos)) return msg class PseudoMotor(PoolElement, Moveable): """ Class encapsulating PseudoMotor functionality.""" def __init__(self, name, **kw): """PoolElement initialization.""" self.call__init__(PoolElement, name, **kw) self.call__init__(Moveable) def getPosition(self, force=False): return self._getAttrValue('position', force=force) def getDialPosition(self, force=False): return self.getPosition(force=force) def getPositionObj(self): return self._getAttrEG('position') def getDialPositionObj(self): return self.getPositionObj() #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Moveable interface # def _start(self, *args, **kwargs): new_pos = args[0] if operator.isSequenceType(new_pos): new_pos = new_pos[0] try: self.write_attribute('position', new_pos) except DevFailed, df: for err in df: if err.reason == 'API_AttrNotAllowed': raise RuntimeError('%s is already moving' % self) else: raise self.final_pos = new_pos def go(self, *args, **kwargs): start_time = time.time() PoolElement.go(self, *args, **kwargs) ret = self.getStateEG().readValue(), self.readPosition() self._total_go_time = time.time() - start_time return ret startMove = PoolElement.start waitMove = PoolElement.waitFinish move = go getLastMotionTime = PoolElement.getLastGoTime getTotalLastMotionTime = PoolElement.getTotalLastGoTime def readPosition(self, force=False): return [ self.getPosition(force=force) ] def getMoveableSource(self): return self.getPoolObj() def getSize(self): return 1 def getIndex(self, name): if name.lower() == self.getName().lower(): return 0 return -1 # # End of Moveable interface #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def _information(self, tab=' '): msg = PoolElement._information(self, tab=tab) try: position = self.read_attribute("position") pos = str(position.value) if position.quality != AttrQuality.ATTR_VALID: pos += " [" + QUALITY[position.quality] + "]" except DevFailed, df: if len(df.args): pos = df.args[0].desc else: e_info = sys.exc_info()[:2] pos = traceback.format_exception_only(*e_info) except: e_info = sys.exc_info()[:2] pos = traceback.format_exception_only(*e_info) msg.append(tab + "Position: " + str(pos)) return msg class MotorGroup(PoolElement, Moveable): """ Class encapsulating MotorGroup functionality.""" def __init__(self, name, **kw): """PoolElement initialization.""" self.call__init__(PoolElement, name, **kw) self.call__init__(Moveable) def _create_str_tuple(self): return 3 * ["TODO"] def getMotorNames(self): return self.getPoolData()['elements'] def hasMotor(self, name): motor_names = map(str.lower, self.getMotorNames()) return name.lower() in motor_names def getPosition(self, force=False): return self._getAttrValue('position', force=force) def getPositionObj(self): return self._getAttrEG('position') #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Moveable interface # def _start(self, *args, **kwargs): new_pos = args[0] try: self.write_attribute('position', new_pos) except DevFailed, df: for err in df: if err.reason == 'API_AttrNotAllowed': raise RuntimeError('%s is already moving' % self) else: raise self.final_pos = new_pos def go(self, *args, **kwargs): start_time = time.time() PoolElement.go(self, *args, **kwargs) ret = self.getStateEG().readValue(), self.readPosition() self._total_go_time = time.time() - start_time return ret startMove = PoolElement.start waitMove = PoolElement.waitFinish move = go getLastMotionTime = PoolElement.getLastGoTime getTotalLastMotionTime = PoolElement.getTotalLastGoTime def readPosition(self, force=False): return self.getPosition(force=force) def getMoveableSource(self): return self.getPoolObj() def getSize(self): return len(self.getMotorNames()) def getIndex(self, name): try: motor_names = map(str.lower, self.getMotorNames()) return motor_names.index(name.lower()) except: return -1 # # End of Moveable interface #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def _information(self, tab=' '): msg = PoolElement._information(self, tab=tab) try: position = self.read_attribute("position") pos = str(position.value) if position.quality != AttrQuality.ATTR_VALID: pos += " [" + QUALITY[position.quality] + "]" except DevFailed, df: if len(df.args): pos = df.args[0].desc else: e_info = sys.exc_info()[:2] pos = traceback.format_exception_only(*e_info) except: e_info = sys.exc_info()[:2] pos = traceback.format_exception_only(*e_info) msg.append(tab + "Position: " + str(pos)) return msg class BaseChannelInfo(object): def __init__(self, data): # dict # channel data self.raw_data = data self.__dict__.update(data) class TangoChannelInfo(BaseChannelInfo): def __init__(self, data, info): BaseChannelInfo.__init__(self, data) # PyTango.AttributeInfoEx self.set_info(info) def has_info(self): return self.raw_info is not None def set_info(self, info): self.raw_info = info if info is None: return data = self.raw_data if 'data_type' not in data: self.data_type = FROM_TANGO_TO_STR_TYPE[info.data_type] if 'shape' not in data: shape = () if info.data_format == AttrDataFormat.SPECTRUM: shape = (info.max_dim_x,) elif info.data_format == AttrDataFormat.IMAGE: shape = (info.max_dim_x, info.max_dim_y) self.shape = shape else: shape = self.shape self.shape = list(shape) def __getattr__(self, name): if self.has_info(): return getattr(self.raw_info, name) cls_name = self.__class__.__name__ raise AttributeError("'%s' has no attribute '%s'" % (cls_name, name)) def getChannelConfigs(mgconfig, ctrls=None, units=None, sort=True): ''' gets a list of channel configurations by flattening the controllers and units levels of the given measurement group configuration. It optionally filters to those channels matching given lists of controller and unit names. :param ctrls: (seq or None) a sequence of strings to filter the controllers. If None given, all controllers will be used :param units: (seq) a sequence of strings to filter the units. If None given, all controllers will be used :param sort: (bool) If True (default) the returned list will be sorted according to channel index (if given in channeldata) and then by channelname. :return: (list) A list of channelname,channeldata pairs. ''' chconfigs = [] if not mgconfig: return [] for ctrl_name, ctrl_data in mgconfig['controllers'].items(): if ctrls is None or ctrl_name in ctrls: for unit_id, unit_data in ctrl_data['units'].items(): if units is None or unit_id in units: for ch_name, ch_data in unit_data['channels'].items(): ch_data.update({'_controller_name':ctrl_name, '_unit_id':unit_id}) #add controller and unit ids chconfigs.append((ch_name, ch_data)) if sort: #sort the channel configs by index (primary sort) and then by channel name. chconfigs = sorted(chconfigs, key=lambda c:c[0]) #sort by channel_name chconfigs = sorted(chconfigs, key=lambda c:c[1].get('index', 1e16)) #sort by index (give a very large index for those which don't have it) return chconfigs class MGConfiguration(object): def __init__(self, mg, data): self._mg = weakref.ref(mg) if isinstance(data, (str, unicode)): data = CodecFactory().decode(('json', data), ensure_ascii=True) self.raw_data = data self.__dict__.update(data) # dict # where key is the channel name and value is the channel data in form # of a dict as receveid by the MG configuration attribute self.channels = channels = CaselessDict() for _, ctrl_data in self.controllers.items(): for _, unit_data in ctrl_data['units'].items(): for channel_name, channel_data in unit_data['channels'].items(): channels[channel_name] = channel_data ##################### #@todo: the for-loops above could be replaced by something like: #self.channels = channels = CaselessDict(getChannelConfigs(data,sort=False)) ##################### # seq each element is the channel data in form of a dict as # receveid by the MG configuration attribute. This seq is just a cache # ordered by channel index in the MG. self.channel_list = len(channels) * [None] for channel in channels.values(): self.channel_list[channel['index']] = channel # dict]> # where key is a device name and value is a list with two elements: # - A device proxy or None if there was an error building it # - A dict where keys are attribute names and value is a reference to # a dict representing channel data as received in raw data self.tango_dev_channels = None # Number of elements in tango_dev_channels in error (could not build # DeviceProxy, probably) self.tango_dev_channels_in_error = 0 # dict> # where key is a channel name and value is a tuple of three elements: # - device name # - attribute name # - attribute information or None if there was an error trying to get # the information self.tango_channels_info = None # Number of elements in tango_channels_info_in_error in error # (could not build attribute info, probably) self.tango_channels_info_in_error = 0 # dict # where key is a channel name and data is a reference to a dict # representing channel data as received in raw data self.non_tango_channels = None self.initialized = False def _build(self): # internal channel structure that groups channels by tango device so # they can be read as a group minimizing this way the network requests self.tango_dev_channels = tg_dev_chs = CaselessDict() self.tango_dev_channels_in_error = 0 self.tango_channels_info = tg_chs_info = CaselessDict() self.tango_channels_info_in_error = 0 self.non_tango_channels = n_tg_chs = CaselessDict() self.cache = cache = {} tg_attr_validator = AttributeNameValidator() for channel_name, channel_data in self.channels.items(): cache[channel_name] = None data_source = channel_data['source'] #external = ctrl_name.startswith("__") params = tg_attr_validator.getParams(data_source) if params is None: # Handle NON tango channel n_tg_chs[channel_name] = channel_data else: # Handle tango channel dev_name = params['devicename'].lower() attr_name = params['attributename'].lower() host, port = params.get('host'), params.get('port') if host is not None and port is not None: dev_name = "{0}:{1}/{2}".format(host, port, dev_name) dev_data = tg_dev_chs.get(dev_name) if dev_data is None: # Build tango device dev = None try: dev = DeviceProxy(dev_name) except: self.tango_dev_channels_in_error += 1 tg_dev_chs[dev_name] = dev_data = [ dev, CaselessDict() ] dev, attr_data = dev_data attr_data[attr_name] = channel_data # get attribute configuration attr_info = None if dev is None: self.tango_channels_info_in_error += 1 else: try: tg_attr_info = dev.get_attribute_config_ex(attr_name)[0] except: tg_attr_info = \ self._build_empty_tango_attr_info(channel_data) self.tango_channels_info_in_error += 1 attr_info = TangoChannelInfo(channel_data, tg_attr_info) tg_chs_info[channel_name] = dev_name, attr_name, attr_info def _build_empty_tango_attr_info(self, channel_data): import PyTango ret = PyTango.AttributeInfoEx() ret.name = channel_data['name'] ret.label = channel_data['label'] return ret def prepare(self): # first time? build everything if self.tango_dev_channels is None: return self._build() # prepare missing tango devices if self.tango_dev_channels_in_error > 0: for dev_name, dev_data in self.tango_dev_channels.items(): if dev_data[0] is None: try: dev_data[0] = DeviceProxy(dev_name) self.tango_dev_channels_in_error -= 1 except: pass # prepare missing tango attribute configuration if self.tango_channels_info_in_error > 0: for _, attr_data in self.tango_channels_info.items(): dev_name, attr_name, attr_info = attr_data if attr_info.has_info(): continue dev = self.tango_dev_channels[dev_name] if dev is None: continue try: tg_attr_info = dev.get_attribute_config_ex(attr_name)[0] attr_info.set_info(tg_attr_info) self.tango_channels_info_in_error -= 1 except: pass def getChannelInfo(self, channel_name): try: return self.tango_channels_info[channel_name] except: channel_name = channel_name.lower() for d_name, a_name, ch_info in self.tango_channels_info.values(): if ch_info.name.lower() == channel_name: return d_name, a_name, ch_info def getChannelsInfo(self): self.prepare() ret = CaselessDict(self.tango_channels_info) ret.update(self.non_tango_channels) return ret def getChannelsInfoList(self): channels_info = self.getChannelsInfo() ret = len(channels_info) * [None] for _, (_, _, ch_info) in channels_info.items(): ret[ch_info.index] = ch_info return ret def getCountersInfoList(self): channels_info = self.getChannelsInfoList() timer_name, idx = self.timer, -1 for i, ch in enumerate(channels_info): if ch['full_name'] == timer_name: idx = i break if idx >= 0: channels_info.pop(idx) return channels_info def read(self, parallel=True): if parallel: return self._read_parallel() return self._read() def _read_parallel(self): self.prepare() ret = CaselessDict(self.cache) dev_replies = {} # deposit read requests for _, dev_data in self.tango_dev_channels.items(): dev, attrs = dev_data if dev is None: continue try: dev_replies[dev] = dev.read_attributes_asynch(attrs.keys()), attrs except: dev_replies[dev] = None, attrs # gather all replies for dev, reply_data in dev_replies.items(): reply, attrs = reply_data try: data = dev.read_attributes_reply(reply, 0) for data_item in data: channel_data = attrs[data_item.name] if data_item.has_failed: value = None else: value = data_item.value ret[channel_data['full_name']] = value except: for _, channel_data in attrs.items(): ret[channel_data['full_name']] = None return ret def _read(self): self.prepare() ret = CaselessDict(self.cache) for _, dev_data in self.tango_dev_channels.items(): dev, attrs = dev_data try: data = dev.read_attributes(attrs.keys()) for data_item in data: channel_data = attrs[data_item.name] if data_item.has_failed: value = None else: value = data_item.value ret[channel_data['full_name']] = value except: for _, channel_data in attrs.items(): ret[channel_data['full_name']] = None return ret class MeasurementGroup(PoolElement): """ Class encapsulating MeasurementGroup functionality.""" def __init__(self, name, **kw): """PoolElement initialization.""" self._configuration = None self._channels = None self._last_integ_time = None self.call__init__(PoolElement, name, **kw) cfg_attr = self.getAttribute('configuration') cfg_attr.addListener(self.on_configuration_changed) def _create_str_tuple(self): return self.getName(), self.getTimerName(), ", ".join(self.getChannelNames()) def getConfigurationAttrEG(self): return self._getAttrEG('Configuration') def setConfiguration(self, configuration): codec = CodecFactory().getCodec('json') f, data = codec.encode(('', configuration)) self.write_attribute('configuration', data) def _setConfiguration(self, data): self._configuration = MGConfiguration(self, data) def getConfiguration(self, force=False): if force or self._configuration is None: data = self.getConfigurationAttrEG().readValue(force=True) self._setConfiguration(data) return self._configuration def on_configuration_changed(self, evt_src, evt_type, evt_value): if evt_type not in CHANGE_EVT_TYPES: return self.info("Configuration changed") self._setConfiguration(evt_value.value) def getTimerName(self): return self.getTimer()['name'] def getTimer(self): cfg = self.getConfiguration() return cfg.channels[cfg.timer] def getTimerValue(self): return self.getTimerName() def getMonitorName(self): return self.getMonitor()['name'] def getMonitor(self): cfg = self.getConfiguration() return cfg.channels[cfg.monitor] def setTimer(self, timer_name): try: self.getChannel(timer_name) except KeyError: raise Exception("%s does not contain a channel named '%s'" % (str(self), timer_name)) cfg = self.getConfiguration().raw_data cfg['timer'] = timer_name import json self.write_attribute("configuration", json.dumps(cfg)) def getChannels(self): return self.getConfiguration().channel_list def getCounters(self): cfg = self.getConfiguration() return [ ch for ch in self.getChannels() if ch['full_name'] != cfg.timer ] def getChannelNames(self): return [ ch['name'] for ch in self.getChannels() ] def getCounterNames(self): return [ ch['name'] for ch in self.getCounters() ] def getChannelLabels(self): return [ ch['label'] for ch in self.getChannels() ] def getCounterLabels(self): return [ ch['label'] for ch in self.getCounters() ] def getChannel(self, name): return self.getConfiguration().channels[name] def getChannelInfo(self, name): return self.getConfiguration().getChannelInfo(name) def getChannelsInfo(self): return self.getConfiguration().getChannelsInfoList() def getCountersInfo(self): return self.getConfiguration().getCountersInfoList() def getValues(self, parallel=True): return self.getConfiguration().read(parallel=parallel) def getIntegrationTime(self): return self._getAttrValue('IntegrationTime') def getIntegrationTimeObj(self): return self._getAttrEG('IntegrationTime') def setIntegrationTime(self, ctime): self.getIntegrationTimeObj().write(ctime) def putIntegrationTime(self, ctime): if self._last_integ_time == ctime: return self._last_integ_time = ctime self.getIntegrationTimeObj().write(ctime) def _start(self, *args, **kwargs): self.Start() def go(self, *args, **kwargs): start_time = time.time() cfg = self.getConfiguration() cfg.prepare() duration = args[0] if duration is None or duration == 0: return self.getStateEG().readValue(), self.getValues() self.putIntegrationTime(duration) PoolElement.go(self, *args, **kwargs) ret = self.getStateEG().readValue(), self.getValues() self._total_go_time = time.time() - start_time return ret startCount = PoolElement.start waitCount = PoolElement.waitFinish count = go stopCount = PoolElement.abort class IORegister(PoolElement): """ Class encapsulating IORegister functionality.""" def __init__(self, name, **kw): """IORegister initialization.""" self.call__init__(PoolElement, name, **kw) def getValueObj(self): return self._getAttrEG('value') def readValue(self, force=False): return self._getAttrValue('value', force=force) def startWriteValue(self, new_value, timeout=None): try: self.getValueObj().write(new_value) self.final_val = new_value except DevFailed, err_traceback: for err in err_traceback: if err.reason == 'API_AttrNotAllowed': raise RuntimeError, '%s is already chaging' % self else: raise def waitWriteValue(self, timeout=None): pass def writeValue(self, new_value, timeout=None): self.startWriteValue(new_value, timeout=timeout) self.waitWriteValue(timeout=timeout) return self.getStateEG().readValue(), self.readValue() writeIORegister = writeIOR = writeValue readIORegister = readIOR = getValue = readValue class Instrument(BaseElement): def __init__(self, **kw): self.__dict__.update(kw) def getFullName(self): return self.full_name def getParentInstrument(self): return self.getPoolObj().getObj(self.parent_instrument) def getParentInstrumentName(self): return self.parent_instrument def getChildrenInstruments(self): raise NotImplementedError return self._children def getElements(self): raise NotImplementedError return self._elements def getType(self): return self.klass def getPoolObj(self): return self._pool_obj class Pool(TangoDevice, MoveableSource): """ Class encapsulating device Pool functionality.""" def __init__(self, name, **kw): self.call__init__(TangoDevice, name, **kw) self.call__init__(MoveableSource) self._elements = BaseSardanaElementContainer() self.getAttribute("Elements").addListener(self.on_elements_changed) def getObject(self, element_info): elem_type = element_info.getType() data = element_info._data if elem_type in ('ControllerClass', 'ControllerLibrary', 'Instrument'): klass = globals()[elem_type] kwargs = dict(data) kwargs['_pool_data'] = data kwargs['_pool_obj'] = self return klass(**kwargs) obj = Factory().getDevice(element_info.full_name, _pool_obj=self, _pool_data=data) return obj def on_elements_changed(self, evt_src, evt_type, evt_value): if evt_type == TaurusEventType.Error: msg = evt_value if isinstance(msg, DevFailed): d = msg[0] # skip configuration errors if d.reason == "API_BadConfigurationProperty": return if d.reason in ("API_DeviceNotExported", "API_CantConnectToDevice"): msg = "Pool was shutdown or is inacessible" else: msg = "{0}: {1}".format(d.reason, d.desc) self.warning("Received elements error event %s", msg) self.debug(evt_value) return elif evt_type not in CHANGE_EVT_TYPES: return try: elems = CodecFactory().decode(evt_value.value, ensure_ascii=True) except: self.error("Could not decode element info") self.info("value: '%s'", evt_value.value) self.debug("Details:", exc_info=1) return elements = self.getElementsInfo() for element_data in elems.get('new', ()): element_data['manager'] = self element = BaseSardanaElement(**element_data) elements.addElement(element) for element_data in elems.get('del', ()): element = self.getElementInfo(element_data['name']) try: elements.removeElement(element) except: self.warning("Failed to remove %s", element_data) return elems def getElementsInfo(self): return self._elements def getElements(self): return self.getElementsInfo().getElements() def getElementInfo(self, name): return self.getElementsInfo().getElement(name) def getElementNamesOfType(self, elem_type): return self.getElementsInfo().getElementNamesOfType(elem_type) def getElementsOfType(self, elem_type): return self.getElementsInfo().getElementsOfType(elem_type) def getElementsWithInterface(self, interface): return self.getElementsInfo().getElementsWithInterface(interface) def getElementWithInterface(self, elem_name, interface): return self.getElementsInfo().getElementWithInterface(elem_name, interface) def getObj(self, name, elem_type=None): if elem_type is None: return self.getElementInfo(name) elif isinstance(elem_type, (str, unicode)): elem_types = elem_type, else: elem_types = elem_type name = name.lower() for e_type in elem_types: elems = self.getElementsOfType(e_type) for elem in elems.values(): if elem.name.lower() == name: return elem elem = elems.get(name) if elem is not None: return elem def __repr__(self): return self.getNormalName() def __str__(self): return repr(self) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # MoveableSource interface # def getMoveable(self, names): """getMoveable(seq names) -> Moveable Returns a moveable object that handles all the moveable items given in names.""" # if simple motor just return it (if the pool has it) if isinstance(names, (str, unicode)): names = names, if len(names) == 1: name = names[0] return self.getObj(name, elem_type=MOVEABLE_TYPES) # find a motor group that contains elements moveable = self.__findMotorGroupWithElems(names) # if none exists create one if moveable is None: mgs = self.getElementsOfType('MotorGroup') i = 1 pid = os.getpid() while True: name = "_mg_ms_{0}_{1}".format(pid, i) exists = False for mg in mgs.values(): if mg.name == name: exists = True break if not exists: break i += 1 moveable = self.createMotorGroup(name, names) return moveable def __findMotorGroupWithElems(self, names): names_lower = map(str.lower, names) len_names = len(names) mgs = self.getElementsOfType('MotorGroup') for mg in mgs.values(): mg_elems = mg.elements if len(mg_elems) != len_names: continue for mg_elem, name in zip(mg_elems, names_lower): if mg_elem.lower() != name: break else: return mg # # End of MoveableSource interface #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- def _wait_for_element_in_container(self, container, elem_name, timeout=0.5, contains=True): start = time.time() cond = True nap = 0.01 if timeout: nap = timeout / 10. while cond: elem = container.getElement(elem_name) if contains: if elem is not None: return elem else: if elem is None: return True if timeout: dt = time.time() - start if dt > timeout: self.info("Timed out waiting for '%s' in container", elem_name) return time.sleep(nap) def createMotorGroup(self, mg_name, elements): params = [mg_name, ] + map(str, elements) self.debug('trying to create motor group for elements: %s', params) self.command_inout('CreateMotorGroup', params) elements_info = self.getElementsInfo() return self._wait_for_element_in_container(elements_info, mg_name) def createMeasurementGroup(self, mg_name, elements): params = [mg_name, ] + map(str, elements) self.debug('trying to create measurement group: %s', params) self.command_inout('CreateMeasurementGroup', params) elements_info = self.getElementsInfo() return self._wait_for_element_in_container(elements_info, mg_name) def deleteMeasurementGroup(self, name): return self.deleteElement(name) def createElement(self, name, ctrl, axis=None): ctrl_type = ctrl.types[0] if axis is None: axis = str(ctrl.getLastUsedAxis() + 1) else: axis = str(axis) cmd = "CreateElement" pars = ctrl_type, ctrl.name, axis, name self.command_inout(cmd, pars) elements_info = self.getElementsInfo() return self._wait_for_element_in_container(elements_info, name) def deleteElement(self, name): self.debug('trying to delete element: %s', name) self.command_inout('DeleteElement', name) elements_info = self.getElementsInfo() return self._wait_for_element_in_container(elements_info, name, contains=False) def createController(self, class_name, name, *props): ctrl_class = self.getObj(class_name, elem_type='ControllerClass') if ctrl_class is None: raise Exception("Controller class %s not found" % class_name) cmd = "CreateController" pars = [ctrl_class.types[0], ctrl_class.file_name, class_name, name] pars.extend(map(str, props)) self.command_inout(cmd, pars) elements_info = self.getElementsInfo() return self._wait_for_element_in_container(elements_info, name) def deleteController(self, name): return self.deleteElement(name) def registerExtensions(): factory = Factory() factory.registerDeviceClass("Pool", Pool) hw_type_names = [ 'Controller', 'ComChannel', 'Motor', 'PseudoMotor', 'CTExpChannel', 'ZeroDExpChannel', 'OneDExpChannel', 'TwoDExpChannel', 'PseudoCounter', 'IORegister', 'MotorGroup', 'MeasurementGroup'] hw_type_map = [ (name, globals()[name]) for name in hw_type_names ] for klass_name, klass in hw_type_map: factory.registerDeviceClass(klass_name, klass) def unregisterExtensions(): factory = Factory() factory.unregisterDeviceClass("Pool") hw_type_names = [ 'Controller', 'ComChannel', 'Motor', 'PseudoMotor', 'CTExpChannel', 'ZeroDExpChannel', 'OneDExpChannel', 'TwoDExpChannel', 'PseudoCounter', 'IORegister', 'MotorGroup', 'MeasurementGroup'] for klass_name in hw_type_names: factory.unregisterDeviceClass(klass_name) sardana-1.6.1/src/sardana/taurus/core/tango/sardana/sardana.py0000644000234000017500000005776412555672636026175 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 submodule. It contains specific part of sardana""" __all__ = ["BaseSardanaElement", "BaseSardanaElementContainer", "Pool", "MacroServer", "Door", "Sardana", "SardanaManager", "PoolElementType", "ControllerClassInfo", "ControllerInfo", "ChannelView", "PlotType", "Normalization", "AcqTriggerType", "AcqMode"] #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- __docformat__ = 'restructuredtext' import PyTango from taurus.core.util.enumeration import Enumeration from taurus.core.util.log import Logger from taurus.core.util.singleton import Singleton from taurus.core.util.containers import CaselessDict from taurus.core.util.codecs import CodecFactory PoolElementType = Enumeration("PoolElementType", ("0D", "1D", "2D", "Communication", "CounterTimer", "IORegister", "Motor", "PseudoCounter", "PseudoMotor")) ChannelView = Enumeration("ChannelView", ("Channel", "Enabled", "Output", "PlotType", "PlotAxes", "Timer", "Monitor", "Trigger", "Conditioning", "Normalization", "NXPath", "Shape", "DataType", "Unknown")) PlotType = Enumeration("PlotType", ("No", "Spectrum", "Image")) Normalization = Enumeration("Normalization", ("No", "Avg", "Integ")) #: an enumeration describing all possible acquisition trigger types AcqTriggerType = Enumeration("AcqTriggerType", (\ "Software", # channel triggered by software - start and stop by software "Gate", # channel triggered by HW - start and stop by external "Unknown")) #: an enumeration describing all possible acquisition mode types AcqMode = Enumeration("AcqMode", (\ "Timer", "Monitor", "Unknown")) class BaseSardanaElement(object): """Generic sardana element""" def __init__(self, *args, **kwargs): self._manager = kwargs.pop('manager') self.__dict__.update(kwargs) self._data = kwargs self._object = None def __repr__(self): return "{0}({1})".format(self.type, self.full_name) def __str__(self): return self.name def __getattr__(self, name): return getattr(self.getObj(), name) def __cmp__(self, elem): return cmp(self.name, elem.name) def getData(self): return self._data def getName(self): return self.name def getId(self): return self.full_name def getType(self): return self.getTypes()[0] def getTypes(self): elem_types = self.type if isinstance(elem_types, (str, unicode)): return [elem_types] return elem_types def serialize(self, *args, **kwargs): kwargs.update(self._data) return kwargs def str(self, *args, **kwargs): #TODO change and check which is the active protocol to serialize #acordingly return CodecFactory().encode(('json', self.serialize(*args, **kwargs))) def getObj(self): obj = self._object if obj is None: self._object = obj = self._manager.getObject(self) return obj class BaseSardanaElementContainer: def __init__(self): # dict where key is the type and value is: # dict where key is the element full name # and value is the Element object self._type_elems_dict = CaselessDict() # dict where key is the interface and value is the set # of elements which implement that interface self._interfaces_dict = {} def addElement(self, elem): elem_type = elem.getType() elem_full_name = elem.full_name #update type_elems type_elems = self._type_elems_dict.get(elem_type) if type_elems is None: self._type_elems_dict[elem_type] = type_elems = CaselessDict() type_elems[elem_full_name] = elem # update interfaces for interface in elem.interfaces: interface_elems = self._interfaces_dict.get(interface) if interface_elems is None: self._interfaces_dict[interface] = interface_elems = CaselessDict() interface_elems[elem_full_name] = elem def removeElement(self, e): elem_type = e.getType() # update type_elems type_elems = self._type_elems_dict.get(elem_type) if type_elems: del type_elems[e.full_name] # update interfaces for interface in e.interfaces: interface_elems = self._interfaces_dict.get(interface) del interface_elems[e.full_name] def removeElementsOfType(self, t): for elem in self.getElementsOfType(t): self.removeElement(elem) def getElementsOfType(self, t): elems = self._type_elems_dict.get(t, {}) return elems def getElementNamesOfType(self, t): return [e.name for e in self.getElementsOfType(t).values()] def getElementsWithInterface(self, interface): elems = self._interfaces_dict.get(interface, {}) return elems def getElementsWithInterfaces(self, interfaces): ret = CaselessDict() for interface in interfaces: ret.update(self.getElementsWithInterface(interface)) return ret def getElementNamesWithInterface(self, interface): return [e.name for e in self.getElementsWithInterface(interface).values()] def hasElementName(self, elem_name): return self.getElement(elem_name) != None def getElement(self, elem_name): elem_name = elem_name.lower() for elems in self._type_elems_dict.values(): elem = elems.get(elem_name) # full_name? if elem is not None: return elem for elem in elems.values(): if elem.name.lower() == elem_name: return elem def getElementWithInterface(self, elem_name, interface): elem_name = elem_name.lower() elems = self._interfaces_dict.get(interface, {}) if elem_name in elems: return elems[elem_name] for elem in elems.values(): if elem.name.lower() == elem_name: return elem def getElements(self): ret = set() for elems in self._type_elems_dict.values(): ret.update(elems.values()) return ret def getInterfaces(self): return self._interfaces_dict def getTypes(self): return self._type_elems_dict #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class PropertyInfo(): def __init__(self, name, type, format, default_value=None): self._name = name self._type = type self._format = format self._default_value = default_value def get_name(self): return self._name def get_type(self): return self._type def get_format(self): return self._format def get_default_value(self): return self._default_value #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class ControllerClassInfo(object): def __init__(self, name, type, library): self._name = name self._type = type self._library = library def get_max_elements(self): return 20 def get_name(self): return self._name def get_model(self): # fake data ############### return "Model of " + self._name def get_icon(self): # fake data ############### import taurus.qt.qtgui.resource return taurus.qt.qtgui.resource.getIcon(":/designer/extra_motor.png") def get_organization(self): # fake data ############### return "Organization of " + self._name def get_description(self): #fake data############ descr = "This is description of " for i in range(20): descr = descr + " and " + self._name #################### return descr def get_family(self): # fake data ############### return "Family of " + self._name def get_properties(self): properties = [] # fake data ###################### properties.append(PropertyInfo("my parameter", "string", "0D", "deviceName")) properties.append(PropertyInfo("asdsadasd", "integer", "0D", 5)) properties.append(PropertyInfo("boollll0", "boolean", "0D", False)) properties.append(PropertyInfo("boollll0", "boolean", "0D", True)) properties.append(PropertyInfo("boollll0", "boolean", "0D", False)) properties.append(PropertyInfo("number1", "float", "0D", 3.5)) properties.append(PropertyInfo("string2", "string", "0D", "hehe")) properties.append(PropertyInfo("tableIntegerD1", "integer", "1D", [1, 2, 3])) properties.append(PropertyInfo("tablestringD1", "string", "1D", ["aaaa", "bbb", "ccc"])) properties.append(PropertyInfo("tablefloatD1", "float", "1D", [1.0, 2.5, 3.6])) properties.append(PropertyInfo("tablebooleanD1", "boolean", "1D", [True, False, True, False])) properties.append(PropertyInfo("tablebleintegerD1", "integer", "1D", [1, 2, 3])) properties.append(PropertyInfo("tablebooleanD2", "boolean", "2D", [ [True, False, True], [True, True, True], [False, False, False] ])) properties.append(PropertyInfo("tableinteger2", "integer", "2D", [ [1, 2, 3], [11, 22, 33], [-10, -20, -30] ])) properties.append(PropertyInfo("tablefloatD2", "float", "2D", [ [0.5, 0.6, 0.8], [0.4, 0.0, 0.333333], [-0.1111, 1, 123123.6] ])) properties.append(PropertyInfo("tablestringD2", "string", "2D", [ ["aaaa", "bbb", "ccc"], ["aaaa2", "bbb2", "ccc2"], ["aaaa3", "bbb3", "ccc3"] ])) return properties def get_controller_type(self): return self._type #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class ControllerInfo(object): def __init__(self, name, ctrl_class_info): self._name = name self._ctrl_class_info = ctrl_class_info def get_controller_class_info(self): return self._ctrl_class_info def get_controller_type(self): return self._ctrl_class_info.get_controller_type() def get_name(self): return self._name def get_max_elements(self): return self._ctrl_class_info.get_max_elements() def is_axis_free(self, axis): #fake data if axis == 3: return False else: return True def is_name_free(self, name): #fake data if name == "asd": return False else: return True def get_icon(self): return self._ctrl_class_info.get_icon() #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class Pool(object): def __init__(self, sardana, name, poolpath, version, alias=None, device_name=None): self._sardana = sardana self._name = name self._poolpath = poolpath self._version = version self._alias = alias self._device_name = device_name def starter_run(self, host, level=1): return True def get_name(self): return self._name def local_run(self): return True def get_element_types(self): return sorted(PoolElementType.keys()) def get_controller_class_infos(self): #fake data ######################## data = [] for i in range(5): data.append(ControllerClassInfo("motorController" + str(i), PoolElementType.Motor, None)) for i in range(5): data.append(ControllerClassInfo("counterTimerController" + str(i), PoolElementType.CounterTimer, None)) return data def get_controller_infos(self): ctrl_classes = self.get_controller_class_infos() data = [] for i in range(2): data.append(ControllerInfo("My_motor_ctrl_" + str(i), ctrl_classes[i])) for i in range(2): data.append(ControllerInfo("My_ct_ctrl_" + str(i), ctrl_classes[i + 5])) return data def create_controller(self, controller_class_info, name, properties): pass def create_element(self, controller_name, name, axis): pass #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class MacroServer(object): def __init__(self, sardana, name, macropath, pool_names, version, alias=None, device_name=None): self._sardana = sardana self._name = name self._macropath = macropath self._pool_names = pool_names self._version = version self._alias = alias self._device_name = device_name self._doors = [] def create_door(self, alias, device_name): try: return self._create_door(alias, device_name) except: db = self.get_database() db.delete_device(device_name) raise def _create_door(self, alias, device_name): db = self.get_database() info = PyTango.DbDevInfo() info.name = device_name info._class = "Door" info.server = "MacroServer/" + self._name db.add_device(info) if alias: db.put_device_alias(device_name, alias) door = Door(alias=alias, device_name=device_name) self._doors.append(door) return door def remove_door(self, device_name): pass def starter_run(self, host, level=1): return True def local_run(self): return True def get_database(self): return self._sardana.get_database() #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class Door(object): def __init__(self, alias=None, device_name=None): self._name = alias self._device_name = device_name #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class Sardana(object): def __init__(self, sardana_db , name, device_name=None): self._sardana_db = sardana_db self._name = name self._device_name = device_name self._pools = [] self._macroservers = [] self._init() def _init(self): if not self._device_name: return self._pools = [] self._macroservers = [] dev_name = self._device_name db = self.get_database() cache = db.cache() dev_info = cache.devices()[dev_name] dev_class_name = dev_info.klass().name() if dev_class_name == "Pool": pass elif dev_class_name == "MacroServer": ms_dev_name = dev_name ms_prop_list = map(str.lower, db.get_device_property_list(ms_dev_name, "*")) ms_props = db.get_device_property(ms_dev_name, ms_prop_list) ms_name = dev_info.server().serverInstance() ms_alias = dev_info.alias() ms = MacroServer(self, ms_name, ms_props.get("macropath"), ms_props.get("poolnames"), ms_props.get("version"), ms_alias, ms_dev_name) self._macroservers.append(ms) for pool_dev_name in ms_props.get("poolnames", ()): pool_prop_list = map(str.lower, db.get_device_property_list(pool_dev_name, "*")) pool_props = db.get_device_property(pool_dev_name, pool_prop_list) pool_dev_info = cache.devices()[pool_dev_name] pool_name = pool_dev_info.server().serverInstance() pool_alias = pool_dev_info.alias() pool = Pool(self, pool_name, pool_props.get("poolpath"), pool_props.get("version"), pool_alias, pool_dev_name) self._pools.append(pool) def get_name(self): return self._name def set_device_name(self, device_name): self._device_name = device_name self._init() def get_device_name(self): return self._device_name def get_pools(self): return self._pools def get_macro_servers(self): return self._macro_servers def create_pool(self, name, poolpath, version, alias=None, device_name=None): try: return self._create_pool(name, poolpath, version, alias=alias, device_name=device_name) except: db = self.get_database() db.delete_device(device_name) raise def _create_pool(self, name, poolpath, version, alias=None, device_name=None): db = self.get_database() info = PyTango.DbDevInfo() info.name = device_name info._class = "Pool" info.server = "Pool/" + name db.add_device(info) if alias: db.put_device_alias(device_name, alias) db.put_device_property(device_name, {"PoolPath" : poolpath, "Version": version}) pool = Pool(self, name, poolpath, version, alias=alias, device_name=device_name) self._pools.append(pool) db.cache().refresh() return pool def create_macroserver(self, name, macropath, pool_names, version, alias=None, device_name=None): try: return self._create_macroserver(name, macropath, pool_names, version, alias=alias, device_name=device_name) except: db = self.get_database() db.delete_device(device_name) raise def _create_macroserver(self, name, macropath, pool_names, version, alias=None, device_name=None): db = self.get_database() info = PyTango.DbDevInfo() info.name = device_name info._class = "MacroServer" info.server = "MacroServer/" + name db.add_device(info) if alias: db.put_device_alias(device_name, alias) db.put_device_property(device_name, {"MacroPath" : macropath, "Version": version, "PoolNames":pool_names}) ms = MacroServer(self, name, macropath, pool_names, version, alias=alias, device_name=device_name) self._macroservers.append(ms) db.cache().refresh() return ms def remove_pool(self): pass def remove_macroserver(self): pass def get_database(self): return self._sardana_db.get_database() #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class DatabaseSardana(object): """A class containning all sardanas for a single database""" def __init__(self, db): assert(db is not None) self._db = db self.refresh() def refresh(self): self._sardanas = sardanas = {} services = self._db.get_service_list("Sardana/.*") for service, dev in services.items(): service_type, service_instance = service.split("/", 1) try: sardanas[service_instance] = Sardana(self, service_instance, dev) except: pass def create_sardana(self, name, device_name): if self._sardanas.has_key(name): raise Exception("Sardana '%s' already exists" % name) self._db.register_service("Sardana", name, device_name) sardana = Sardana(self, name) self._sardanas[name] = sardana return sardana def remove_sardana(self, name): try: self._sardanas.pop(name) except KeyError: raise Exception("Sardana '%s' does NOT exist" % name) self._db.unregister_service("Sardana", name) def get_sardanas(self): return self._sardanas def get_sardana(self, name): return self._sardanas[name] def get_database(self): return self._db #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # T E M P O R A R Y I M P L E M E N T A T I O N # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class SardanaManager(Singleton, Logger): def __init__(self): """ Initialization. Nothing to be done here for now.""" pass def init(self, *args, **kwargs): """Singleton instance initialization. **For internal usage only**""" name = self.__class__.__name__ self.call__init__(Logger, name) self._db_sardanas = {} def _get_db_sardana(self, db=None): if db is None: import taurus db = taurus.Database() db_sardana = self._db_sardanas.get(db) if db_sardana is None: db_sardana = DatabaseSardana(db) return db_sardana def create_sardana(self, name, device_name, db=None): return self._get_db_sardana(db).create_sardana(name, device_name) def remove_sardana(self, name, db=None): self._get_db_sardana(db).remove_sardana(name) def get_sardanas(self, db=None): return self._get_db_sardana(db).get_sardanas() def get_sardana(self, name, db=None): return self._get_db_sardana(db).get_sardana(name) def get_hosts(self): return ["localhost"] + ["controls%02d" % i for i in range(5)] def get_level_range(self): return 1, 200 def has_localhost_starter(self): import socket return socket.gethostname() in self.get_hosts() @classmethod def get_default_pool_path(cls): pathList = [] pathList.append("/homelocal/sicilia/lib/poolcontrollers") pathList.append("/homelocal/sicilia/lib/python/site-packages/poolcontrollers") return pathList @classmethod def get_default_ms_path(cls): pathList = [] pathList.append("/homelocal/sicilia/lib/python/site-packages/macroserver/macros") return pathList sardana-1.6.1/src/sardana/taurus/core/tango/__init__.py0000644000234000017500000000173312555672636024673 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/core/__init__.py0000644000234000017500000000173312555672636023563 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/qt/0000755000234000017500000000000012555673001021125 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtcore/0000755000234000017500000000000012555673001022422 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/0000755000234000017500000000000012555673001023532 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/sardana/0000755000234000017500000000000012555673001025143 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/sardana/__init__.py0000644000234000017500000000226412555672636027275 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 extension for taurus Qt """ __docformat__ = 'restructuredtext' def registerExtensions(): from . import pool from . import macroserver pool.registerExtensions() macroserver.registerExtensions() sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/sardana/macroserver.py0000644000234000017500000001444112555672636030066 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """MacroServer extension for taurus Qt""" __all__ = ["QDoor", "QMacroServer", "MacroServerMessageErrorHandler", "registerExtensions"] from taurus.core.taurusbasetypes import TaurusEventType from taurus.external.qt import Qt from sardana.taurus.core.tango.sardana.macroserver import BaseMacroServer, BaseDoor CHANGE_EVTS = TaurusEventType.Change, TaurusEventType.Periodic class QDoor(BaseDoor, Qt.QObject): __pyqtSignals__ = ["resultUpdated", "recordDataUpdated", "macroStatusUpdated"] __pyqtSignals__ += [ "%sUpdated" % l.lower() for l in BaseDoor.log_streams ] def __init__(self, name, qt_parent=None, **kw): self.call__init__wo_kw(Qt.QObject, qt_parent) self.call__init__(BaseDoor, name, **kw) def resultReceived(self, log_name, result): res = BaseDoor.resultReceived(self, log_name, result) self.emit(Qt.SIGNAL("resultUpdated"), res) return res def recordDataReceived(self, s, t, v): if t not in CHANGE_EVTS: return res = BaseDoor.recordDataReceived(self, s, t, v) self.emit(Qt.SIGNAL("recordDataUpdated"), res) return res def macroStatusReceived(self, s, t, v): res = BaseDoor.macroStatusReceived(self, s, t, v) if t == TaurusEventType.Error: macro = None else: macro = self.getRunningMacro() if macro is None: return self.emit(Qt.SIGNAL("macroStatusUpdated"), (macro, res)) return res def logReceived(self, log_name, output): res = BaseDoor.logReceived(self, log_name, output) self.emit(Qt.SIGNAL("%sUpdated" % log_name.lower()), output) return res class QMacroServer(BaseMacroServer, Qt.QObject): def __init__(self, name, qt_parent=None, **kw): self.call__init__wo_kw(Qt.QObject, qt_parent) self.call__init__(BaseMacroServer, name, **kw) def typesChanged(self, s, t, v): res = BaseMacroServer.typesChanged(self, s, t, v) self.emit(Qt.SIGNAL("typesUpdated")) return res def elementsChanged(self, s, t, v): res = BaseMacroServer.elementsChanged(self, s, t, v) self.emit(Qt.SIGNAL("elementsUpdated")) return res def macrosChanged(self, s, t, v): res = BaseMacroServer.macrosChanged(self, s, t, v) self.emit(Qt.SIGNAL("macrosUpdated")) return res def on_elements_changed(self, s, t, v): ret = added, removed, changed = \ BaseMacroServer.on_elements_changed(self, s, t, v) macros, elements = 0, 0 for element in set.union(added, removed, changed): if "MacroCode" in element.interfaces: macros += 1 elements += 1 if elements and macros: break if elements: self.emit(Qt.SIGNAL("elementsChanged")) if macros: self.emit(Qt.SIGNAL("macrosUpdated")) return ret def on_environment_changed(self, s, t, v): ret = added, removed, changed = \ BaseMacroServer.on_environment_changed(self, s, t, v) if added or removed or changed: self.emit(Qt.SIGNAL("environmentChanged"), ret) return ret # ugly access to qtgui level: in future find a better way to register error # handlers, maybe in TangoFactory & TaurusManager from taurus.qt.qtgui.panel import TaurusMessageErrorHandler class MacroServerMessageErrorHandler(TaurusMessageErrorHandler): def setError(self, err_type=None, err_value=None, err_traceback=None): """Translates the given error object into an HTML string and places it in the message panel :param error: an error object (typically an exception object) :type error: object""" msgbox = self._msgbox msgbox.setText(err_value) msg = "
    %s
    " % err_value msgbox.setDetailedHtml(msg) html_orig = """""" exc_info = "".join(err_traceback) style = "" try: import pygments.formatters import pygments.lexers except: pygments = None if pygments is not None: formatter = pygments.formatters.HtmlFormatter() style = formatter.get_style_defs() html = html_orig.format(style=style) if pygments is None: html += "
    %s
    " % exc_info else: formatter = pygments.formatters.HtmlFormatter() html += pygments.highlight(exc_info, pygments.lexers.PythonTracebackLexer(), formatter) html += "" msgbox.setOriginHtml(html) def registerExtensions(): """Registers the macroserver extensions in the :class:`taurus.core.tango.TangoFactory`""" import taurus factory = taurus.Factory() factory.registerDeviceClass('MacroServer', QMacroServer) factory.registerDeviceClass('Door', QDoor) # ugly access to qtgui level: in future find a better way to register error # handlers, maybe in TangoFactory & TaurusManager import sardana.taurus.core.tango.sardana.macro import taurus.qt.qtgui.panel MacroRunException = sardana.taurus.core.tango.sardana.macro.MacroRunException TaurusMessagePanel = taurus.qt.qtgui.panel.TaurusMessagePanel TaurusMessagePanel.registerErrorHandler(MacroRunException, MacroServerMessageErrorHandler) sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/sardana/model.py0000644000234000017500000003671512555672636026646 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus text editor widget.""" __all__ = ["SardanaBaseElementModel", "SardanaElementTypeModel", "SardanaElementPlainModel", "SardanaBaseProxyModel", "SardanaTypeProxyModel", "SardanaBaseTreeItem", "SardanaRootTreeItem", "SardanaElementTreeItem", "SardanaTypeTreeItem", "SardanaEnvironmentModel"] __docformat__ = 'restructuredtext' try: import pygments from pygments import highlight from pygments.formatters import HtmlFormatter from pygments.lexers import PythonLexer, PythonTracebackLexer except: pygments = None from taurus.core.taurusdevice import TaurusDevice from taurus.external.qt import Qt from taurus.core.util.enumeration import Enumeration from taurus.qt.qtcore.model import TaurusBaseTreeItem, TaurusBaseModel, \ TaurusBaseProxyModel from taurus.qt.qtcore.mimetypes import TAURUS_MODEL_LIST_MIME_TYPE, \ TAURUS_MODEL_MIME_TYPE _MOD, _CLS, _FNC, _TNG = ":/python-module.png", ":/class.png", ":/function.png", ":/tango.png" TYPE_MAP = { "ControllerLibrary" : ("Controller libraries", _MOD, "Controller library",), "ControllerClass" : ("Controller classes", _CLS, "Controller class",), "Controller" : ("Controllers", _TNG, "Controller",), "Motor" : ("Motors", _TNG, "Motor",), "PseudoMotor" : ("Pseudo motors", _TNG, "Pseudo Motor",), "CTExpChannel" : ("Counter/Timers", _TNG, "Counter/Timer experiment channel",), "CounterTimer" : ("Counter/Timers", _TNG, "Counter/Timer experiment channel",), "ZeroDExpChannel" : ("0D channels", _TNG, "0D experiment channel",), "OneDExpChannel" : ("1D channels", _TNG, "1D experiment channel",), "TwoDExpChannel" : ("2D channels", _TNG, "2D experiment channel",), "MotorGroup" : ("Motor groups", _TNG, "Motor group",), "MeasurementGroup" : ("Measurement groups", _TNG, "Measurement group",), "CommunicationChannel" : ("Communication channels", _TNG, "Communication channel",), "MacroLibrary" : ("Macro libraries", _MOD, "Macro library",), "MacroClass" : ("Macro classes", _CLS, "Macro class",), "Instrument" : ("Instruments", _TNG, "Instrument",), "MacroFunction" : ("Macro functions", _FNC, "Macro function",), } def getElementTypeLabel(t): return TYPE_MAP.get(t, (t,))[0] def getElementTypeIcon(t): import taurus.qt.qtgui.resource try: return taurus.qt.qtgui.resource.getIcon(TYPE_MAP.get(t, (None, _TNG))[1]) except: return None def getElementTypeSize(t): return Qt.QSize(200, 24) def getElementTypeToolTip(t): return TYPE_MAP.get(t, (None, None, 'no information'))[2] class SardanaBaseTreeItem(TaurusBaseTreeItem): """A generic node""" def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ if index.column() > 0: return None return getElementTypeLabel(self._itemData) def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown This method should be able to return any kind of python object as long as the model that is used is compatible. :return: the role in form of element type""" return 'type' class SardanaRootTreeItem(SardanaBaseTreeItem): pass class SardanaTypeTreeItem(SardanaBaseTreeItem): pass class SardanaElementTreeItem(SardanaBaseTreeItem): def role(self): return self.itemData().type def data(self, index): column, model = index.column(), index.model() role = model.role(column, self.depth()) obj = self.itemData() if role == "parent": if hasattr(obj, "klass"): return obj.klass if hasattr(obj, "module"): return obj.module if hasattr(obj, "controller"): return obj.controller if hasattr(obj, "parent"): return obj.parent return None return getattr(obj, role) def toolTip(self, index): if index.column() > 0: return self.data(index) obj = self.itemData() if hasattr(obj, "exc_info") and obj.exc_info is not None: html_orig = '' formatter, style = None, "" if pygments is not None: formatter = HtmlFormatter() style = formatter.get_style_defs() txt = html_orig.format(style=style) if formatter is None: txt += "
    %s
    " % obj.exc_info else: txt += highlight(obj.exc_info, PythonTracebackLexer(), formatter) txt += "" else: txt = "{0} {1}".format(getElementTypeToolTip(obj.type), obj.name) return txt def icon(self, index): if index.column() > 0: return None return getElementTypeIcon(self.itemData().type) class SardanaBaseElementModel(TaurusBaseModel): ColumnNames = ["Elements", "Controller/Module/Parent"] ColumnRoles = ('Root', 'type', 'name', 'name'), "parent" def __init__(self, parent=None, data=None): TaurusBaseModel.__init__(self, parent=parent, data=data) self.setSelectables(self.ColumnRoles[0]) def setDataSource(self, data_source): old_ds = self.dataSource() if old_ds is not None: Qt.QObject.disconnect(old_ds, Qt.SIGNAL('elementsChanged'), self.on_elements_changed) if data_source is not None: Qt.QObject.connect(data_source, Qt.SIGNAL('elementsChanged'), self.on_elements_changed) TaurusBaseModel.setDataSource(self, data_source) def on_elements_changed(self): self.refresh() def createNewRootItem(self): return SardanaRootTreeItem(self, self.ColumnNames) def roleIcon(self, role): return getElementTypeIcon(role) def columnIcon(self, column): return self.roleIcon(self.role(column)) def roleToolTip(self, role): return getElementTypeToolTip(role) def columnToolTip(self, column): return self.roleToolTip(self.role(column)) def roleSize(self, role): return getElementTypeSize(role) def columnSize(self, column): role = self.role(column) s = self.roleSize(role) return s def mimeTypes(self): return "text/plain", TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_MODEL_MIME_TYPE def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: if not index.isValid(): continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: continue data.append(mime_data_item) ret.setData(TAURUS_MODEL_LIST_MIME_TYPE, "\r\n".join(data)) ret.setText(", ".join(data)) if len(data) == 1: ret.setData(TAURUS_MODEL_MIME_TYPE, str(data[0])) return ret def accept(self, element): return True def setupModelData(self, data): dev = self.dataSource() if dev is None: return self.ColumnNames[0] = dev.getSimpleName() info = dev.getElementsInfo() elements = info.getElements() root = self._rootItem type_nodes = {} parent_elements = {} child_elements = set() parent_types = "ControllerLibrary", "MacroLibrary", "Controller" child_types = "ControllerClass", "MacroClass", "MacroFunction", \ "Motor", "CounterTimer", "PseudoMotor", "PseudoCounter", \ "ZeroDExpChannel", "OneDExpChannel", "TwoDExpChannel" for element in elements: if not self.accept(element): continue element_type = element.type type_item = type_nodes.get(element_type) if type_item is None: type_item = SardanaTypeTreeItem(self, element_type, root) type_nodes[element_type] = type_item root.appendChild(type_item) element_item = SardanaElementTreeItem(self, element, type_item) type_item.appendChild(element_item) if element_type in parent_types: parent_elements[element.name] = element_item elif element_type in child_types: child_elements.add(element) for element in child_elements: try: parent_item = parent_elements[element.parent] except KeyError: self.warning("Error adding %s to parent %s (parent unknown)", element.name, element.parent) element_item = SardanaElementTreeItem(self, element, parent_item) parent_item.appendChild(element_item) class SardanaElementTypeModel(SardanaBaseElementModel): pass class SardanaElementPlainModel(SardanaBaseElementModel): ColumnNames = "Elements", ColumnRoles = ('Root', 'name',), def setupModelData(self, data): dev = self.dataSource() if dev is None: return info = dev.getElementsInfo() elements = info.getElements() root = self._rootItem skip_types = "ControllerLibrary", "MacroLibrary" for element in elements: element_type = element.type if element_type in skip_types: continue element_item = SardanaElementTreeItem(self, element, root) root.appendChild(element_item) class SardanaBaseProxyModel(TaurusBaseProxyModel): def filterAcceptsRow(self, sourceRow, sourceParent): sourceModel = self.sourceModel() idx = sourceModel.index(sourceRow, 0, sourceParent) treeItem = idx.internalPointer() if isinstance(treeItem, SardanaElementTreeItem): expr = self.filterRegExp() element = treeItem.itemData() return self.elementMatches(element, expr) return True def elementMatches(self, element, expr): name = element.name if Qt.QString(name).contains(expr): return True name = element.full_name if name is None: return False return Qt.QString(name).contains(expr) class SardanaTypeProxyModel(TaurusBaseProxyModel): """Sardana filter by element type""" def __init__(self, types=None, parent=None): TaurusBaseProxyModel.__init__(self, parent=parent) if types is None: types = () self._types = types def filterAcceptsRow(self, sourceRow, sourceParent): sourceModel = self.sourceModel() idx = sourceModel.index(sourceRow, 0, sourceParent) treeItem = idx.internalPointer() if isinstance(treeItem, SardanaElementTreeItem): return treeItem.itemData().type in self._types return False class EnvironmentTreeItem(TaurusBaseTreeItem): """An environment node""" def role(self): return self.itemData().type def data(self, index): column, model = index.column(), index.model() role = model.role(column, self.depth()) obj = self.itemData() if role == "key": return obj[0] elif role == "value": return obj[1] elif role == "datatype": return type(obj[1]).__name__ def toolTip(self, index): return "environment '%s'" % self.itemData()[0] def icon(self, index): if index.column() > 0: return None return ":/class.png" class SardanaEnvironmentModel(TaurusBaseModel): ColumnNames = ["Environment", "Value", "Data Type"] ColumnRoles = ('Root', 'key'), 'value', 'datatype' def __init__(self, parent=None, data=None): TaurusBaseModel.__init__(self, parent=parent, data=data) self.setSelectables(self.ColumnRoles[0]) def setDataSource(self, data_source): old_ds = self.dataSource() if old_ds is not None: Qt.QObject.disconnect(old_ds, Qt.SIGNAL('environmentChanged'), self.on_environment_changed) if data_source is not None: Qt.QObject.connect(data_source, Qt.SIGNAL('environmentChanged'), self.on_environment_changed) TaurusBaseModel.setDataSource(self, data_source) def on_environment_changed(self): self.refresh() def createNewRootItem(self): return SardanaRootTreeItem(self, self.ColumnNames) def roleIcon(self, role): return ":/tango.png" # return getElementTypeIcon(role) #def columnIcon(self, column): # return self.roleIcon(self.role(column)) def roleToolTip(self, role): cr = self.ColumnRoles if role == cr[0][1]: return "Environment name" elif role == cr[1]: return "Environment value" elif role == cr[2]: return "Environment value data type" #def columnToolTip(self, column): # return self.roleToolTip(self.role(column)) def roleSize(self, role): return Qt.QSize(200, 24) def columnSize(self, column): role = self.role(column) s = self.roleSize(role) return s def mimeTypes(self): return "text/plain", TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_MODEL_MIME_TYPE def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: if not index.isValid(): continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: continue data.append(mime_data_item) ret.setData(TAURUS_MODEL_LIST_MIME_TYPE, "\r\n".join(data)) ret.setText(", ".join(data)) if len(data) == 1: ret.setData(TAURUS_MODEL_MIME_TYPE, str(data[0])) return ret def accept(self, environment): return True def setupModelData(self, data): dev = self.dataSource() if dev is None: return env = dev.getEnvironment() root = self._rootItem for key, value in env.items(): if not self.accept(key): continue env_item = EnvironmentTreeItem(self, (key, value), root) root.appendChild(env_item) sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/sardana/pool.py0000644000234000017500000000611012555672636026501 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Device pool extension for taurus Qt""" __all__ = ["QPool", "QMeasurementGroup", "registerExtensions"] import json from taurus.external.qt import Qt from taurus.core.taurusbasetypes import TaurusEventType from taurus.core.tango import TangoDevice CHANGE_EVTS = TaurusEventType.Change, TaurusEventType.Periodic class QPool(Qt.QObject, TangoDevice): def __init__(self, name, qt_parent=None, **kw): self.call__init__wo_kw(Qt.QObject, qt_parent) self.call__init__(TangoDevice, name, **kw) class QMeasurementGroup(Qt.QObject, TangoDevice): def __init__(self, name, qt_parent=None, **kw): self.call__init__wo_kw(Qt.QObject, qt_parent) self.call__init__(TangoDevice, name, **kw) self._config = None configuration = self.getAttribute("Configuration") configuration.addListener(self._configurationChanged) def __getattr__(self, name): try: return Qt.QObject.__getattr__(self, name) except AttributeError: return TangoDevice.__getattr__(self, name) def _configurationChanged(self, s, t, v): if t == TaurusEventType.Config: return if TaurusEventType.Error: self._config = None else: self._config = json.loads(v.value) self.emit(Qt.SIGNAL("configurationChanged")) def getConfiguration(self, cache=True): if self._config is None or not cache: try: v = self.read_attribute("configuration") self._config = json.loads(v.value) except: self._config = None return self._config def setConfiguration(self, config): self.write_attribute("configuration", json.dumps(config)) def registerExtensions(): """Registers the pool extensions in the :class:`taurus.core.tango.TangoFactory`""" import taurus #import sardana.taurus.core.tango.sardana.pool #sardana.taurus.core.tango.sardana.pool.registerExtensions() factory = taurus.Factory() #factory.registerDeviceClass('Pool', QPool) factory.registerDeviceClass('MeasurementGroup', QMeasurementGroup) sardana-1.6.1/src/sardana/taurus/qt/qtcore/tango/__init__.py0000644000234000017500000000173312555672636025664 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/qt/qtcore/__init__.py0000644000234000017500000000173312555672636024554 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/qt/qtgui/0000755000234000017500000000000012555673001022256 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/0000755000234000017500000000000012555673001026341 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/0000755000234000017500000000000012555673001031737 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/__init__.py0000644000234000017500000000206512555672636034070 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 favouriteseditor import FavouritesMacrosEditor from historyviewer import HistoryMacrosViewer sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/favouriteseditor.py0000644000234000017500000001761012555672636035731 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ favouriteseditor.py: """ import copy from taurus.external.qt import Qt from taurus.qt.qtgui.container import TaurusWidget from taurus.qt.qtcore.configuration import BaseConfigurableClass from model import MacrosListModel class FavouritesMacrosEditor(TaurusWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setObjectName(self.__class__.__name__) self.registerConfigProperty("toXmlString", "fromXmlString", "favourites") self.initComponents() def initComponents(self): self.setLayout(Qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.list = FavouritesMacrosList(self) self._model = MacrosListModel() self.list.setModel(self._model) # self.registerConfigDelegate(self.list) self.layout().addWidget(self.list) actionBar = self.createActionBar() self.layout().addLayout(actionBar) def createActionBar(self): layout = Qt.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) deleteButton = Qt.QToolButton() deleteButton.setDefaultAction(self.list.removeAction) layout.addWidget(deleteButton) deleteAllButton = Qt.QToolButton() deleteAllButton.setDefaultAction(self.list.removeAllAction) layout.addWidget(deleteAllButton) moveUpButton = Qt.QToolButton() moveUpButton.setDefaultAction(self.list.moveUpAction) layout.addWidget(moveUpButton) moveDownButton = Qt.QToolButton() moveDownButton.setDefaultAction(self.list.moveDownAction) layout.addWidget(moveDownButton) spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) layout.addItem(spacerItem) return layout def addMacro(self, macroNode): self.list.insertMacro(macroNode) def toXmlString(self): return self.list.toXmlString() def fromXmlString(self, xmlString): self.list.fromXmlString(xmlString) favouritesList = self.list.model().list macroServerObj = self.getModelObj() if macroServerObj is None: self.debug("MS IS NONE") return for macroNode in favouritesList: macroServerObj.fillMacroNodeAdditionalInfos(macroNode) @classmethod def getQtDesignerPluginInfo(cls): return None class FavouritesMacrosList(Qt.QListView, BaseConfigurableClass): def __init__(self, parent): Qt.QListView.__init__(self, parent) self.setSelectionMode(Qt.QListView.ExtendedSelection) self.removeAction = Qt.QAction(Qt.QIcon(":/actions/list-remove.svg"), "Remove from favourites", self) self.connect(self.removeAction, Qt.SIGNAL("triggered()"), self.removeMacros) self.removeAction.setToolTip("Clicking this button will remov selected macros from favourites.") self.removeAllAction = Qt.QAction(Qt.QIcon(":/places/user-trash.svg"), "Remove all from favourites", self) self.connect(self.removeAllAction, Qt.SIGNAL("triggered()"), self.removeAllMacros) self.removeAllAction.setToolTip("Clicking this button will remove all macros from favourites.") self.moveUpAction = Qt.QAction(Qt.QIcon(":/actions/go-up.svg"), "Move up", self) self.connect(self.moveUpAction, Qt.SIGNAL("triggered()"), self.upMacro) self.moveUpAction.setToolTip("Clicking this button will move the macro up in the favourites hierarchy.") self.moveDownAction = Qt.QAction(Qt.QIcon(":/actions/go-down.svg"), "Move up", self) self.connect(self.moveDownAction, Qt.SIGNAL("triggered()"), self.downMacro) self.moveDownAction.setToolTip("Clicking this button will move the macro down in the favourites hierarchy.") self.disableActions() def currentChanged(self, current, previous): macro = copy.deepcopy(self.currentIndex().internalPointer()) self.emit(Qt.SIGNAL("favouriteSelected"), macro) Qt.QListView.currentChanged(self, current, previous) def selectionChanged(self, old, new): macro = None if self.currentIndex().isValid(): self.removeAllAction.setEnabled(True) self.isIndexSelected() else: self.disableActions() Qt.QListView.selectionChanged(self, old, new) if len(self.selectedIndexes()) > 1: self.moveUpAction.setEnabled(False) self.moveDownAction.setEnabled(False) def isIndexSelected(self): if len(self.selectedIndexes()) > 0: self.removeAction.setEnabled(True) self.moveUpAction.setEnabled(self.model().isUpRowAllowed(self.currentIndex())) self.moveDownAction.setEnabled(self.model().isDownRowAllowed(self.currentIndex())) else: self.removeAction.setEnabled(False) self.moveUpAction.setEnabled(False) self.moveDownAction.setEnabled(False) def mousePressEvent(self, e): clickedIndex = self.indexAt(e.pos()) if clickedIndex.isValid(): macro = copy.deepcopy(self.currentIndex().internalPointer()) self.emit(Qt.SIGNAL("favouriteSelected"), macro) Qt.QListView.mousePressEvent(self, e) def disableActions(self): self.removeAction.setEnabled(False) self.removeAllAction.setEnabled(False) self.moveUpAction.setEnabled(False) self.moveDownAction.setEnabled(False) def insertMacro(self, macroNode): idx = self.model().insertRow(macroNode) self.setCurrentIndex(idx) def removeMacros(self): slist = sorted(self.selectedIndexes(), key=lambda index: index.row(), reverse=True) for index in slist: row = index.row() idx = self.model().removeRow(row) self.setCurrentIndex(idx) def removeAllMacros(self): self.selectAll() slist = sorted(self.selectedIndexes(), key=lambda index: index.row(), reverse=True) for index in slist: self.model().removeRow(index.row()) def upMacro(self): row = self.currentIndex().row() idx = self.model().upRow(row) self.setCurrentIndex(idx) def downMacro(self): row = self.currentIndex().row() idx = self.model().downRow(row) self.setCurrentIndex(idx) def toXmlString(self): return self.model().toXmlString() def fromXmlString(self, xmlString): self.model().fromXmlString(xmlString) def test(): import sys, taurus, time from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv) favouritesEditor = FavouritesMacrosEditor() args = app.get_command_line_args() favouritesEditor.setModel(args[0]) time.sleep(1) macroNode = favouritesEditor.getModelObj().getMacroNodeObj(str(args[1])) favouritesEditor.addMacro(macroNode) favouritesEditor.show() sys.exit(app.exec_()) if __name__ == "__main__": test() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/historyviewer.py0000644000234000017500000001403212555672636035251 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ historyviewer.py: """ import copy from taurus.external.qt import Qt from taurus.qt.qtgui.container import TaurusWidget from taurus.qt.qtcore.configuration import BaseConfigurableClass from model import MacrosListModel class HistoryMacrosViewer(TaurusWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setObjectName(self.__class__.__name__) self.registerConfigProperty("toXmlString", "fromXmlString", "history") self.initComponents() def initComponents(self): self.setLayout(Qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.list = HistoryMacrosList(self) self._model = MacrosListModel() self.list.setModel(self._model) ##### self.registerConfigDelegate(self.list) self.layout().addWidget(self.list) actionBar = self.createActionBar() self.layout().addLayout(actionBar) def createActionBar(self): layout = Qt.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) deleteAllButton = Qt.QToolButton() deleteAllButton.setDefaultAction(self.list.removeAllAction) layout.addWidget(deleteAllButton) spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) layout.addItem(spacerItem) return layout def listElementUp(self): indexPos = self.list.currentIndex() if indexPos.isValid() and indexPos.row() >= 1: self.list.setCurrentIndex(indexPos.sibling(indexPos.row() - 1, indexPos.column())) else: self.selectFirstElement() def listElementDown(self): indexPos = self.list.currentIndex() if indexPos.isValid() and indexPos.row() < self._model.rowCount() - 1: self.list.setCurrentIndex(indexPos.sibling(indexPos.row() + 1, indexPos.column())) elif indexPos.row() == self._model.rowCount() - 1: return else: self.selectFirstElement() def addMacro(self, macroNode): self.list.insertMacro(macroNode) def toXmlString(self): return self.list.toXmlString() def fromXmlString(self, xmlString): self.list.fromXmlString(xmlString) historyList = self.list.model().list macroServerObj = self.getModelObj() if macroServerObj is None: return for macroNode in historyList: macroServerObj.fillMacroNodeAdditionalInfos(macroNode) def selectFirstElement(self): self.list.removeAllAction.setEnabled(True) self.list.setCurrentIndex(self._model.index(0)) @classmethod def getQtDesignerPluginInfo(cls): return None class HistoryMacrosList(Qt.QListView, BaseConfigurableClass): def __init__(self, parent): Qt.QListView.__init__(self, parent) self.setSelectionMode(Qt.QListView.SingleSelection) self.removeAllAction = Qt.QAction(Qt.QIcon(":/places/user-trash.svg"), "Remove all from history", self) self.connect(self.removeAllAction, Qt.SIGNAL("triggered()"), self.removeAllMacros) self.removeAllAction.setToolTip("Clicking this button will remove all macros from history.") self.removeAllAction.setEnabled(False) def currentChanged(self, current, previous): macro = copy.deepcopy(self.currentIndex().internalPointer()) self.emit(Qt.SIGNAL("historySelected"), macro) Qt.QListView.currentChanged(self, current, previous) def mousePressEvent(self, e): clickedIndex = self.indexAt(e.pos()) if clickedIndex.isValid(): macro = copy.deepcopy(self.currentIndex().internalPointer()) self.emit(Qt.SIGNAL("historySelected"), macro) self.removeAllAction.setEnabled(True) Qt.QListView.mousePressEvent(self, e) def focusInEvent(self, e): if self.model().rowCount() > 0: self.removeAllAction.setEnabled(True) else: self.removeAllAction.setEnabled(False) def insertMacro(self, macroNode): idx = self.model().insertRow(macroNode) self.setCurrentIndex(idx) self.removeAllAction.setEnabled(True) def removeAllMacros(self): self.selectAll() slist = sorted(self.selectedIndexes(), key=lambda index: index.row(), reverse=True) for index in slist: self.model().removeRow(index.row()) self.removeAllAction.setEnabled(False) def toXmlString(self): return self.model().toXmlString() def fromXmlString(self, xmlString): self.model().fromXmlString(xmlString) def test(): import sys, taurus, time from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv) historyViewer = HistoryMacrosViewer() args = app.get_command_line_args() historyViewer.setModel(args[0]) time.sleep(1) macroNode = historyViewer.getModelObj().getMacroNodeObj(str(args[1])) historyViewer.addMacro(macroNode) historyViewer.show() sys.exit(app.exec_()) if __name__ == "__main__": test() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/model.py0000644000234000017500000000662612555672636033440 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ model.py: """ from taurus.external.qt import Qt from lxml import etree from sardana.taurus.core.tango.sardana import macro class MacrosListModel(Qt.QAbstractListModel): def __init__(self, parent=None): Qt.QAbstractListModel.__init__(self, parent) self.list = [] def rowCount(self, parent=Qt.QModelIndex()): return len(self.list) def data(self, index, role): if index.isValid() and role == Qt.Qt.DisplayRole: macroNode = self.list[index.row()] return Qt.QVariant(self.list[index.row()].toSpockCommand()) else: return Qt.QVariant() def index(self, row, column=0, parent=Qt.QModelIndex()): if self.rowCount(): return self.createIndex(row, column, self.list[row]) else: return Qt.QModelIndex() def insertRow(self, macroNode, row=0): self.beginInsertRows(Qt.QModelIndex(), row, row) self.list.insert(row, macroNode) self.endInsertRows() return self.index(row) def removeRow(self, row): self.beginRemoveRows(Qt.QModelIndex(), row, row) self.list.pop(row) self.endRemoveRows() if row == self.rowCount(): row = row - 1 return self.index(row) def isUpRowAllowed(self, index): return index.row() > 0 def upRow(self, row): """This method move macro up and returns index with its new position""" macroNode = self.list[row] self.removeRow(row) return self.insertRow(macroNode, row - 1) def isDownRowAllowed(self, index): return index.row() < self.rowCount() - 1 def downRow(self, row): """This method move macro down and returns index with its new position""" macroNode = self.list[row] self.removeRow(row) return self.insertRow(macroNode, row + 1) def toXmlString(self, pretty=False): listElement = etree.Element("list") for macroNode in self.list: listElement.append(macroNode.toXml(withId=False)) xmlTree = etree.ElementTree(listElement) xmlString = etree.tostring(xmlTree, pretty_print=pretty) return xmlString def fromXmlString(self, xmlString): listElement = etree.fromstring(xmlString) for childElement in listElement.iterchildren("macro"): macroNode = macro.MacroNode() macroNode.fromXml(childElement) self.list.append(macroNode) self.reset() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/0000755000234000017500000000000012555673001032735 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/0000755000234000017500000000000012555673001035641 5ustar zreszelaComputing00000000000000././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/__init__.pysardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/__0000644000234000017500000000175712555672637036171 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 senv import SenvEditor ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/senv.pysardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/se0000644000234000017500000003406712555672637036223 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.external.qt import Qt from taurus import Database from taurus.core.taurusbasetypes import TaurusElementType from taurus.core.taurusdatabase import TaurusAttrInfo from taurus.qt.qtgui.input import TaurusAttrListComboBox from taurus.qt.qtgui.tree import TaurusDbTreeWidget from taurus.qt.qtgui.resource import getThemeIcon from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.macroparameterseditor import MacroParametersEditor from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.parameditors import LineEditParam, ParamBase, ComboBoxParam, CheckBoxParam, DirPathParam, MSAttrListComboBoxParam from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.model import ParamEditorModel from sardana.taurus.qt.qtgui.extra_macroexecutor.common import MSAttrListComboBox class SenvEditor(Qt.QWidget, MacroParametersEditor): def __init__(self, parent=None): Qt.QWidget.__init__(self, parent) MacroParametersEditor.__init__(self) self.valueWidget = None def initComponents(self): self.setLayout(Qt.QFormLayout()) self.layout().addRow(Qt.QLabel("Setting environment variable:", self)) self.nameComboBox = ComboBoxParam(self) self.nameComboBox.addItems(["ActiveMntGrp", "ExtraColumns", "JsonRecorder", "ScanFile", "ScanDir"]) self.nameComboBox.setEditable(True) self.connect(self.nameComboBox, Qt.SIGNAL("currentIndexChanged(int)"), self.onNameComboBoxChanged) self.layout().addRow("name:", self.nameComboBox) nameIndex = self.model().index(0, 1, self.rootIndex()) self.nameComboBox.setIndex(nameIndex) def setRootIndex(self, rootIndex): self._rootIndex = rootIndex self.initComponents() def rootIndex(self): return self._rootIndex def model(self): return self._model def setModel(self, model): self._model = model if isinstance(model, ParamEditorModel): self.setRootIndex(Qt.QModelIndex()) def onNameComboBoxChanged(self, index): text = str(self.nameComboBox.currentText()) if self.valueWidget is not None: label = self.layout().labelForField(self.valueWidget) if label is not None: self.layout().removeWidget(label) label.setParent(None) label = None self.layout().removeWidget(self.valueWidget) self.valueWidget.resetValue() self.valueWidget.setParent(None) self.valueWidget = None self.valueWidget, label = getSenvValueEditor(text, self) paramRepeatIndex = self.model().index(1, 0, self.rootIndex()) repeatIndex = paramRepeatIndex.child(0, 0) valueIndex = repeatIndex.child(0, 1) self.valueWidget.setIndex(valueIndex) if label: self.layout().addRow(label, self.valueWidget) else: self.layout().addRow(self.valueWidget) def getSenvValueEditor(envName, parent): """Factory method, requires: string, and QWidget as a parent for returned editor. Factory returns a tuple of widget and a label for it. :return: (Qt.QWidget, str) """ label = "value:" if envName == "ActiveMntGrp": editor = MSAttrListComboBoxParam(parent) editor.setUseParentModel(True) editor.setModel("/MeasurementGroupList") elif envName == "ExtraColumns": editor = ExtraColumnsEditor(parent) label = None elif envName == "JsonRecorder": editor = CheckBoxParam(parent) elif envName == "ScanDir": editor = DirPathParam(parent) elif envName == "ScanFile": editor = LineEditParam(parent) else: editor = LineEditParam(parent) return editor, label class ExtraColumnsEditor(ParamBase, Qt.QWidget): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QWidget.__init__(self, parent) self.setLayout(Qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) addNewColumnButton = Qt.QPushButton(getThemeIcon("list-add") , "Add new column...", self) removeSelectedColumnsButton = Qt.QPushButton(getThemeIcon("list-remove") , "Remove selected...", self) buttonsLayout = Qt.QHBoxLayout() buttonsLayout.addWidget(addNewColumnButton) buttonsLayout.addWidget(removeSelectedColumnsButton) self.layout().addLayout(buttonsLayout) self.extraColumnsTable = ExtraColumnsTable(self) self.extraColumnsModel = ExtraColumnsModel() self.extraColumnsTable.setModel(self.extraColumnsModel) self.extraColumnsTable.setItemDelegate(ExtraColumnsDelegate(self.extraColumnsTable)) self.layout().addWidget(self.extraColumnsTable) self.connect(addNewColumnButton, Qt.SIGNAL("clicked()"), self.onAddNewColumn) self.connect(removeSelectedColumnsButton, Qt.SIGNAL("clicked()"), self.onRemoveSelectedColumns) self.connect(self.extraColumnsModel, Qt.SIGNAL("dataChanged (const QModelIndex&,const QModelIndex&)"), self.onExtraColumnsChanged) self.connect(self.extraColumnsModel, Qt.SIGNAL("modelReset()"), self.onExtraColumnsChanged) def getValue(self): return repr(self.extraColumnsTable.model().columns()) def setValue(self, value): try: columns = eval(value) except: columns = [] self.extraColumnsTable.setColumns(columns) def onAddNewColumn(self): self.extraColumnsTable.insertRows() self.emit(Qt.SIGNAL("modelChanged()")) def onRemoveSelectedColumns(self): self.extraColumnsTable.removeRows() self.emit(Qt.SIGNAL("modelChanged()")) def onExtraColumnsChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) class ExtraColumnsTable(Qt.QTableView): def __init__(self, parent): Qt.QTableView.__init__(self, parent) self.setSelectionBehavior(Qt.QAbstractItemView.SelectRows) self.setSelectionMode(Qt.QAbstractItemView.ExtendedSelection) def setColumns(self, columns): if columns == None: columns = [] self.model().setColumns(columns) self.resizeColumnsToContents() def insertRows(self): self.model().insertRows(self.model().rowCount()) def removeRows(self): rows = [index.row() for index in self.selectedIndexes()] rows = list(set(rows)) rows.sort(reverse=True) for row in rows: self.model().removeRows(row) class ExtraColumnsDelegate(Qt.QItemDelegate): def __init__(self, parent=None): Qt.QItemDelegate.__init__(self, parent) db = Database() self.host = db.getNormalName() def createEditor(self, parent, option, index): if index.column() == 1: self.combo_attr_tree_widget = TaurusDbTreeWidget(perspective=TaurusElementType.Device) self.combo_attr_tree_widget.setModel(self.host) treeView = self.combo_attr_tree_widget.treeView() qmodel = self.combo_attr_tree_widget.getQModel() editor = Qt.QComboBox(parent) editor.setModel(qmodel) editor.setMaxVisibleItems(20) editor.setView(treeView) elif index.column() == 2: editor = MSAttrListComboBox(parent) editor.setUseParentModel(True) editor.setModel("/InstrumentList") else: editor = Qt.QItemDelegate.createEditor(self, parent, option, index) return editor def setEditorData(self, editor, index): if index.column() == 2: text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) editor.setCurrentText(text) else: Qt.QItemDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index): column = index.column() if column == 1: selectedItems = self.combo_attr_tree_widget.selectedItems() if not len(selectedItems) == 1: return taurusTreeAttributeItem = selectedItems[0] itemData = taurusTreeAttributeItem.itemData() if isinstance(itemData, TaurusAttrInfo): model.setData(index, Qt.QVariant(itemData.fullName())) elif column == 2: model.setData(index, Qt.QVariant(editor.currentText())) else: Qt.QItemDelegate.setModelData(self, editor, model, index) def sizeHint(self, option, index): if index.column() == 0: fm = option.fontMetrics text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) document = Qt.QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) size = Qt.QSize(document.idealWidth() + 5, fm.height()) elif index.column() == 1: editor = self.createEditor(self.parent(), option, index) if editor is None: size = Qt.QItemDelegate.sizeHint(self, option, index) else: size = editor.sizeHint() editor.hide() editor.setParent(None) # editor.destroy() else: size = Qt.QItemDelegate.sizeHint(self, option, index) return size class ExtraColumnsModel(Qt.QAbstractTableModel): def __init__(self, columns=None): if columns is None: columns = [] Qt.QAbstractItemModel.__init__(self) self.__columns = columns def setColumns(self, columns): self.__columns = columns self.reset() def columns(self): return self.__columns def rowCount(self, index=Qt.QModelIndex()): return len(self.__columns) def columnCount(self, index=Qt.QModelIndex()): return 3 def data(self, index, role=Qt.Qt.DisplayRole): if not index.isValid() or not (0 <= index.row() < self.rowCount()): return Qt.QVariant() row = index.row() column = index.column() #Display Role if role == Qt.Qt.DisplayRole: if column == 0: return Qt.QVariant(Qt.QString(self.__columns[row]['label'])) elif column == 1: return Qt.QVariant(Qt.QString(self.__columns[row]['model'])) elif column == 2: return Qt.QVariant(Qt.QString(self.__columns[row]['instrument'])) return Qt.QVariant() def headerData(self, section, orientation, role=Qt.Qt.DisplayRole): if role == Qt.Qt.TextAlignmentRole: if orientation == Qt.Qt.Horizontal: return Qt.QVariant(int(Qt.Qt.AlignLeft | Qt.Qt.AlignVCenter)) return Qt.QVariant(int(Qt.Qt.AlignRight | Qt.Qt.AlignVCenter)) if role != Qt.Qt.DisplayRole: return Qt.QVariant() #So this is DisplayRole... if orientation == Qt.Qt.Horizontal: if section == 0: return Qt.QVariant("Label") elif section == 1: return Qt.QVariant("Attribute") elif section == 2: return Qt.QVariant("Instrument") return Qt.QVariant() else: return Qt.QVariant(Qt.QString.number(section + 1)) def flags(self, index): flags = Qt.Qt.ItemIsEnabled | Qt.Qt.ItemIsSelectable if index.isValid(): column = index.column() if column in (0, 1, 2): flags |= Qt.Qt.ItemIsEditable return flags def setData(self, index, value=None, role=Qt.Qt.EditRole): if index.isValid() and (0 <= index.row() < self.rowCount()): row = index.row() column = index.column() value = Qt.from_qvariant(value, str) if column == 0: self.__columns[row]['label'] = value elif column == 1: self.__columns[row]['model'] = value elif column == 2: self.__columns[row]['instrument'] = value self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) return True return False def insertRows(self, row, rows=1, parentindex=None): if parentindex is None: parentindex = Qt.QModelIndex() first = row last = row + rows - 1 self.beginInsertRows(parentindex, first, last) for row in range(first, last + 1): self.insertRow(row) self.endInsertRows() return True def insertRow(self, row, parentIndex=None): self.__columns.insert(row, {'label':'', 'model':'', 'instrument':''}) def removeRows(self, row, rows=1, parentindex=None): if parentindex is None: parentindex = Qt.QModelIndex() first = row last = row + rows - 1 self.beginRemoveRows(parentindex, first, last) for row in range(first, last + 1): self.removeRow(row) self.endRemoveRows() return True def removeRow(self, row, parentIndex=None): self.__columns.pop(row) CUSTOM_EDITOR = SenvEditor if __name__ == "__main__": import sys import taurus from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv) args = app.get_command_line_args() editor = SenvEditor() macroServer = taurus.Device(args[0]) macroInfoObj = macroServer.getMacroInfoObj("senv") macroNode = MacroNode() editor.setMacroNode(macroNode) editor.show() sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/__init__.py0000644000234000017500000000214012555672636035060 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ __init__.py: """ from macroparameterseditor import ParamEditorManager, StandardMacroParametersEditor from model import ParamEditorModel sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/delegate.py0000644000234000017500000001247112555672637035104 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ delegate.py: """ from taurus.external.qt import Qt from sardana.taurus.qt.qtgui.extra_macroexecutor import globals from sardana.taurus.core.tango.sardana import macro from .parameditors import MSAttrListComboBoxParam, SpinBoxParam, \ DoubleSpinBoxParam, LineEditParam, FileDialogParam, ComboBoxParam, ComboBoxBoolean class ParamEditorDelegate(Qt.QStyledItemDelegate): def __init__(self, parent=None): Qt.QStyledItemDelegate.__init__(self, parent) def createEditor(self, parent, option, index): if index.column() == 1: node = index.model().nodeFromIndex(index) if isinstance(node, macro.SingleParamNode): paramType = node.type() if paramType in globals.EDITOR_COMBOBOX_PARAMS: comboBox = MSAttrListComboBoxParam(parent, node) comboBox.setElementType(paramType) ################## # The setUseParentModel mechanism is not working # we do it manually here as a hack #comboBox.setUseParentModel(True) #comboBox.setModel('/elements') w = parent while w is not None: if hasattr(w, 'getModelName'): model = w.getModelName() + '/elements' break w = w.parent() comboBox.setModel(model) ################### return comboBox elif paramType in globals.EDITOR_SPINBOX_PARAMS: return SpinBoxParam(parent, node) elif paramType in globals.EDITOR_DOUBLESPINBOX_PARAMS: return DoubleSpinBoxParam(parent, node) elif paramType in globals.EDITOR_LINEEDIT_PARAMS: return LineEditParam(parent, node) elif paramType in globals.EDITOR_FILEDIALOG_PARAMS: return FileDialogParam(parent, node) elif paramType in globals.EDITOR_BOOLEAN_PARAMS: return ComboBoxBoolean(parent, node) return Qt.QStyledItemDelegate.createEditor(self, parent, option, index) def setEditorData(self, editor, index): if index.column() == 1: text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) if text == "None" or text == "": Qt.QStyledItemDelegate.setEditorData(self, editor, index) else: editor.setValue(text) # node = index.model().nodeFromIndex(index) # paramType = node.type() # if paramType in globals.EDITOR_COMBOBOX_PARAMS : # editor.setValue(text) # elif paramType in globals.EDITOR_SPINBOX_PARAMS: # editor.setValue(int(text)) # elif paramType in globals.EDITOR_DOUBLESPINBOX_PARAMS: # editor.setValue(float(text)) # elif paramType in globals.EDITOR_LINEEDIT_PARAMS: # editor.setText(text) # elif paramType in globals.EDITOR_FILEDIALOG_PARAMS: # editor.filePath.setText(text) else: Qt.QStyledItemDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index): if index.column() == 1: model.setData(index, Qt.QVariant(editor.getValue())) else: Qt.QStyledItemDelegate.setModelData(self, editor, model, index) def sizeHint(self, option, index): if index.column() == 0: fm = option.fontMetrics text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) document = Qt.QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) size = Qt.QSize(document.idealWidth() + 5, fm.height()) elif index.column() == 1: editor = self.createEditor(self.parent(), option, index) if editor is None: size = Qt.QStyledItemDelegate.sizeHint(self, option, index) else: size = editor.sizeHint() editor.hide() editor.setParent(None) # editor.destroy() else: size = Qt.QStyledItemDelegate.sizeHint(self, option, index) return size ././@LongLink0000000000000000000000000000015500000000000011216 Lustar 00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/macroparameterseditor.pysardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/macroparameterse0000644000234000017500000003565612555672637036247 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ macroparameterseditor.py: """ import sys, inspect, glob from taurus.external.qt import Qt from taurus.core.util.singleton import Singleton from taurus.qt.qtgui.resource import getThemeIcon from sardana.taurus.core.tango.sardana import macro from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.delegate import ParamEditorDelegate class MacroParametersEditor(object): def __init__(self): pass # self._macroModel = None # def setMacroModel(self, model): # self._macroModel = model # self.connect(self._macroModel, Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.onDataChanged) # self.connect(self._macroModel, Qt.SIGNAL("modelReset()"), self.onModelReset) # # def onDataChanged(self): # pass # # def onModelReset(self): # self.onDataChanged() class StandardMacroParametersEditor(Qt.QWidget, MacroParametersEditor): def __init__(self, parent=None, macroNode=None): Qt.QWidget.__init__(self, parent) self.initComponents() def initComponents(self): self.setLayout(Qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.tree = MacroParametersTree(self) self.delegate = ParamEditorDelegate(self.tree) self.tree.setItemDelegate(self.delegate) self.tree.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Expanding) self.layout().addWidget(self.tree) actionLayout = Qt.QVBoxLayout() actionLayout.setContentsMargins(0, 0, 0, 0) addButton = Qt.QToolButton() addButton.setDefaultAction(self.tree.addAction) actionLayout.addWidget(addButton) deleteButton = Qt.QToolButton() deleteButton.setDefaultAction(self.tree.deleteAction) actionLayout.addWidget(deleteButton) moveUpButton = Qt.QToolButton() moveUpButton.setDefaultAction(self.tree.moveUpAction) actionLayout.addWidget(moveUpButton) moveDownButton = Qt.QToolButton() moveDownButton.setDefaultAction(self.tree.moveDownAction) actionLayout.addWidget(moveDownButton) spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) actionLayout.addItem(spacerItem) self.layout().addLayout(actionLayout) def setModel(self, model): self.tree.setModel(model) self.tree.expandAll() def macroNode(self): return self.tree.macroNode() def setMacroNode(self, macroNode): self.tree.setMacroNode(macroNode) class MacroParametersTree(Qt.QTreeView): def __init__(self, parent=None, designMode=False): Qt.QTreeView.__init__(self, parent) self.setSelectionBehavior(Qt.QTreeView.SelectItems) self.setRootIsDecorated(False) # self.setTabKeyNavigation(True) self.setEditTriggers(Qt.QAbstractItemView.AllEditTriggers) self.addAction = Qt.QAction(getThemeIcon("list-add"), "Add new repetition", self) self.connect(self.addAction, Qt.SIGNAL("triggered()"), self.onAddRepeat) self.addAction.setToolTip("Clicking this button will add new repetition to current parameter.") self.deleteAction = Qt.QAction(getThemeIcon("list-remove"), "Remove repetition", self) self.connect(self.deleteAction, Qt.SIGNAL("triggered()"), self.onDelRepeat) self.deleteAction.setToolTip("Clicking this button will remove current repetition.") self.moveUpAction = Qt.QAction(getThemeIcon("go-up"), "Move up", self) self.connect(self.moveUpAction, Qt.SIGNAL("triggered()"), self.onUpRepeat) self.moveUpAction.setToolTip("Clicking this button will move current repetition up.") self.moveDownAction = Qt.QAction(getThemeIcon("go-down"), "Move down", self) self.connect(self.moveDownAction, Qt.SIGNAL("triggered()"), self.onDownRepeat) self.moveDownAction.setToolTip("Clicking this button will move current repetition down.") self.disableActions() def disableActions(self): self.addAction.setEnabled(False) self.deleteAction.setEnabled(False) self.moveUpAction.setEnabled(False) self.moveDownAction.setEnabled(False) def manageActions(self, currentIndex): self.disableActions() if currentIndex is None: return node = self.model().nodeFromIndex(currentIndex) if isinstance(node, macro.RepeatNode): self.deleteAction.setEnabled(not node.parent().isReachedMin()) self.addAction.setEnabled(False) self.moveUpAction.setEnabled(node.isAllowedMoveUp()) self.moveDownAction.setEnabled(node.isAllowedMoveDown()) elif isinstance(node, macro.RepeatParamNode): self.addAction.setEnabled(not node.isReachedMax()) self.deleteAction.setEnabled(False) def currentChanged(self, current, previous): self.manageActions(current) Qt.QTreeView.currentChanged(self, current, previous) #def focusInEvent(self, event): # reason = event.reason() # if (reason == Qt.Qt.TabFocusReason) | (reason == Qt.Qt.BacktabFocusReason): # if reason == Qt.Qt.TabFocusReason: # idx = self.forwardIdx(0, 1, Qt.QModelIndex()) # elif reason == Qt.Qt.BacktabFocusReason: # idx = self.backwardIdx(len(self.root()) - 1, 1, Qt.QModelIndex()) # self.setCurrentIndex(idx) # self.edit(idx) # else: # Qt.QTreeView.focusInEvent(self, event) # #def forwardIdx(self, row, col, parentIdx): # try: # proposalIdx = self.model().index(row, col, parentIdx) # except AssertionError: # if parentIdx.row() == -1: # return Qt.QModelIndex() # grandParentIdx = parentIdx.parent() # return self.forwardIdx(parentIdx.row() + 1, col, grandParentIdx) # # proposalNode = self.model().nodeFromIndex(proposalIdx) # # if isinstance(proposalNode, macro.SingleParamNode): # return proposalIdx # elif isinstance(proposalNode, macro.RepeatNode): # return self.forwardIdx(0, 1, proposalIdx) # elif isinstance(proposalNode, macro.RepeatParamNode): # if len(proposalNode) > 0: # return self.forwardIdx(0, 1, proposalIdx) # else: # return self.forwardIdx(row + 1, col, proposalIdx) # elif not proposalIdx.isValid(): # proposalIdx = parentIdx.sibling(parentIdx.row()+1, 0) # if proposalIdx.isValid(): # proposalIdx = proposalIdx.child(0,1) # else: # while not proposalIdx.isValid(): # parentIdx = parentIdx.parent() # if not parentIdx.isValid(): # return Qt.QModelIndex() # proposalIdx = parentIdx.sibling(parentIdx.row()+1, 1) # # return proposalIdx # # elif isinstance(proposalNode, macro.MacroNode): # ##self.model().setRoot(proposalNode) # return self.forwardIdx(0,1,proposalIdx) # #def backwardIdx(self, row, col, parentIdx): # try: # proposalIdx = self.model().index(row, col, parentIdx) # except AssertionError: # if parentIdx.row() == -1: # return Qt.QModelIndex() # grandParentIdx = parentIdx.parent() # return self.backwardIdx(parentIdx.row() - 1, col, grandParentIdx) # proposalNode = self.model().nodeFromIndex(proposalIdx) # if isinstance(proposalNode, macro.SingleParamNode): # return proposalIdx # elif isinstance(proposalNode, macro.RepeatNode): # return self.backwardIdx(self.model().rowCount(proposalIdx) - 1, 1, proposalIdx) # elif isinstance(proposalNode, macro.RepeatParamNode): # return self.backwardIdx(self.model().rowCount(proposalIdx) - 1, 1, proposalIdx) # # elif not proposalIdx.isValid(): # proposalIdx = parentIdx.sibling(parentIdx.row()-1, 0) # if proposalIdx.isValid(): # tempRow = 0 # proposalIdx = proposalIdx.child(tempRow,1) # while proposalIdx.sibling(tempRow+1, 1).isValid(): # proposalIdx = proposalIdx.sibling(tempRow+1, 1) # tempRow +=1 # else: # while not proposalIdx.isValid(): # parentIdx = parentIdx.parent() # if not parentIdx.isValid(): # return Qt.QModelIndex() # proposalIdx = parentIdx.sibling(parentIdx.row()-1, 1) # # return proposalIdx # #def moveCursor (self, cursorAction, modifiers): # ix=self.currentIndex() # self.manageActions(ix) # (col, row, parentIdx)=(ix.column(), ix.row(), ix.parent()) # #to start from second column # if col == -1 and row == -1: # if cursorAction == Qt.QAbstractItemView.MoveNext: # return self.forwardIdx(0, 1, parentIdx) # elif cursorAction == Qt.QAbstractItemView.MovePrevious: # return self.backwardIdx(self.model().rowCount(parentIdx) - 1, 1, parentIdx) # if (cursorAction == Qt.QAbstractItemView.MoveNext and # modifiers == Qt.Qt.NoModifier): # #This condition in case we start tabbing with cursor on first column # if col == 0: # currentNode = self.model().nodeFromIndex(ix) # if isinstance(currentNode, macro.SingleParamNode): # nextIdx = self.forwardIdx(row, 1, parentIdx) # else: # nextIdx = self.forwardIdx(0, 1, ix) # else: # nextIdx = self.forwardIdx(row + 1, 1, parentIdx) # #this condition in case there is no next index and we want to pass focus # #to next widget in parent obj # # if nextIdx == "term": # self.focusNextPrevChild(True) # return Qt.QModelIndex() # # if not nextIdx.isValid(): # self.parent().focusNextChild() # #this condition in case the next index is valid and we want to # #refresh state of buttons # else: # self.manageActions(nextIdx) # return nextIdx # # elif (cursorAction == Qt.QAbstractItemView.MovePrevious and # modifiers == Qt.Qt.NoModifier): # backwardIdx = self.backwardIdx(row - 1, 1, parentIdx) # #this contion in case there is no previous index and we want to pass focus # #to previous widget in parent obj # if backwardIdx == "term": # self.focusNextPrevChild(False) # return Qt.QModelIndex() # # if not backwardIdx.isValid(): # self.parent().focusPreviousChild() # else: # self.manageActions(backwardIdx) # return backwardIdx # #def expanded(self): # for column in range(self.model().columnCount(Qt.QModelIndex())): # self.resizeColumnToContents(column) def onAddRepeat(self): index = self.currentIndex() if isinstance(self.model(), Qt.QSortFilterProxyModel): sourceIndex = self.model().mapToSource(index) newSourceIndex = self.model()._insertRow(sourceIndex) newIndex = self.model().mapFromSource(newSourceIndex) else: newIndex = self.model()._insertRow(index) self.setCurrentIndex(newIndex) self.expandAll() def onDelRepeat(self): index = self.currentIndex() if isinstance(self.model(), Qt.QSortFilterProxyModel): index = self.model().mapToSource(index) self.model()._removeRow(index) self.expandAll() def onUpRepeat(self): index = self.currentIndex() if isinstance(self.model(), Qt.QSortFilterProxyModel): sourceIndex = self.model().mapToSource(index) newSourceIndex = self.model()._upRow(sourceIndex) newIndex = self.model().mapFromSource(newSourceIndex) else: newIndex = self.model()._upRow(index) self.setCurrentIndex(newIndex) self.expandAll() def onDownRepeat(self): index = self.currentIndex() if isinstance(self.model(), Qt.QSortFilterProxyModel): sourceIndex = self.model().mapToSource(index) newSourceIndex = self.model()._downRow(sourceIndex) newIndex = self.model().mapFromSource(newSourceIndex) else: newIndex = self.model()._downRow(index) self.setCurrentIndex(newIndex) self.expandAll() class ParamEditorManager(Singleton): def init(self): self._paths = [] self._macroEditorsDict = {} def paths(self): return self._paths def setPaths(self, paths): self._paths = paths def appendPath(self, path): self._paths.append() def parsePaths(self, pathsString): self.setPaths(pathsString.split(":")) def browsePaths(self): for path in self.paths(): modulePaths = glob.glob("%s/*.py" % path) if not modulePaths: continue sys.path.insert(0, path) for modulePath in modulePaths: if modulePath.endswith("__init__.py"): continue modulePathAsArray = modulePath.split("/") moduleFileName = modulePathAsArray[-1] moduleName = moduleFileName[:-3] try: module = __import__(moduleName) except ImportError: continue klass = getattr(module, "CUSTOM_EDITOR", None) # for name, klass in inspect.getmembers(module, inspect.isclass): # if issubclass(klass, MacroParametersEditor): self._macroEditorsDict[moduleName] = klass def getMacroEditor(self, macroName=None, parent=None): editorClass = self._macroEditorsDict.get(macroName, None) try: return editorClass(parent=parent) except: return None sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/model.py0000644000234000017500000001606012555672637034430 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ model.py: """ from lxml import etree from taurus.external.qt import Qt from sardana.taurus.core.tango.sardana import macro from sardana.taurus.qt.qtgui.extra_macroexecutor import globals class ParamEditorModel(Qt.QAbstractItemModel): def __init__(self, parent=None): Qt.QAbstractItemModel.__init__(self, parent) self.columns = 2 self.setRoot() self.headers = ["Parameter", "Value"] def root(self): return self._root def setRoot(self, node=None): if node == None: node = macro.MacroNode() self._root = node self.reset() def flags(self, index): if index.column() == 0: return Qt.Qt.ItemIsEnabled | Qt.Qt.ItemIsSelectable node = self.nodeFromIndex(index) if (index.column() == 1 and isinstance(node, macro.SingleParamNode) and not node.type() in globals.EDITOR_NONEDITABLE_PARAMS): return Qt.Qt.ItemIsEnabled | Qt.Qt.ItemIsEditable return Qt.Qt.ItemIsEnabled def _insertRow(self, parentIndex, node=None, row=-1): parentNode = self.nodeFromIndex(parentIndex) if row == -1: row = len(parentNode) if node == None: node = parentNode.newRepeat() self.beginInsertRows(parentIndex, row, row) row = parentNode.insertChild(node, row) self.endInsertRows() return self.index(row, 0, parentIndex) def _removeRow(self, index): """This method is used remove macro (pased via index)""" node = self.nodeFromIndex(index) parentIndex = index.parent() parentNode = self.nodeFromIndex(parentIndex) row = parentNode.rowOfChild(node) self.beginRemoveRows(parentIndex, row, row) parentNode.removeChild(node) self.endRemoveRows() def _upRow(self, index): node = self.nodeFromIndex(index) parentIndex = index.parent() parentNode = self.nodeFromIndex(parentIndex) row = parentNode.rowOfChild(node) self._removeRow(index) newIndex = self._insertRow(parentIndex, node, row - 1) parentNode.arrangeIndexes() return newIndex def _downRow(self, index): node = self.nodeFromIndex(index) parentIndex = index.parent() parentNode = self.nodeFromIndex(parentIndex) row = parentNode.rowOfChild(node) self._removeRow(index) newIndex = self._insertRow(parentIndex, node, row + 1) parentNode.arrangeIndexes() return newIndex def addRepeat(self, index, callReset=True): paramRepeatNode = self.nodeFromIndex(index) paramRepeatNode.addRepeat() if callReset: self.reset() def delRepeat(self, index, callReset=True): branchIndex = self.parent(index) branch = self.nodeFromIndex(branchIndex) child = self.nodeFromIndex(index) branch.removeChild(child) if callReset: self.reset() def upRepeat(self, index, callReset=True): branchIndex = self.parent(index) branch = self.nodeFromIndex(branchIndex) child = self.nodeFromIndex(index) branch.upChild(child) if callReset: self.reset() def downRepeat(self, index, callReset=True): branchIndex = self.parent(index) branch = self.nodeFromIndex(branchIndex) child = self.nodeFromIndex(index) branch.downChild(child) if callReset: self.reset() def rowCount(self, index): node = self.nodeFromIndex(index) if node is None or isinstance(node, macro.SingleParamNode): return 0 return len(node) def columnCount(self, parent): return self.columns def data(self, index, role): if not index.isValid() or not (0 <= index.row() < self.rowCount(index.parent())): return Qt.QVariant() if role == Qt.Qt.DisplayRole: node = self.nodeFromIndex(index) if index.column() == 0: return Qt.QVariant(node.name()) elif index.column() == 1: return Qt.QVariant(node.value()) return Qt.QVariant() def setData (self, index, value, role=Qt.Qt.EditRole): node = self.nodeFromIndex(index) # if index.isValid() and 0 <= index.row() < len(node.parent()): if index.column() == 1: node.setValue(Qt.from_qvariant(value, str)) self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) return True return False def headerData(self, section, orientation, role): if orientation == Qt.Qt.Horizontal and role == Qt.Qt.DisplayRole: return Qt.QVariant(self.headers[section]) return Qt.QVariant() def index(self, row, column, parent): if not parent.isValid(): parentNode = self.root(); else: parentNode = parent.internalPointer() childNode = parentNode.child(row) if childNode is None: return Qt.QModelIndex(); else: return self.createIndex(row, column, childNode); def parent(self, child): node = self.nodeFromIndex(child) if node is None: return Qt.QModelIndex() parent = node.parent() if parent is None or isinstance(parent, macro.SequenceNode): return Qt.QModelIndex() grandparent = parent.parent() if grandparent is None: return Qt.QModelIndex() row = grandparent.rowOfChild(parent) return self.createIndex(row, 0, parent) def nodeFromIndex(self, index): if index.isValid(): return index.internalPointer() else: return self.root() def toSpockCommand(self): """ Converts root obj (MacroNode) to string representing spock command and returns it. :return: (etree.Element) """ return self.root().toSpockCommand() def toXmlString(self): """ Converts root obj (MacroNode) to xml string and returns it. :return: (etree.Element) """ xmlElement = self.root().toXml() return etree.tostring(xmlElement) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/parameditors.py0000644000234000017500000002431512555672637036024 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ parameditors.py: """ import os from taurus.external.qt import Qt from taurus.qt.qtgui.input import TaurusAttrListComboBox from sardana.taurus.qt.qtgui.extra_macroexecutor import globals from sardana.taurus.qt.qtgui.extra_macroexecutor.common import MSAttrListComboBox #@todo: replace by method from common module def str2bool(text): return text in ("True", "1") class ParamBase: def __init__(self, paramModel=None): self.setParamModel(paramModel) def paramModel(self): return self._paramModel def setParamModel(self, paramModel): self._paramModel = paramModel def resetValue(self): if self.paramModel() is not None: defValue = self.paramModel().defValue() self.setValue(defValue) def index(self): return self._index def setIndex(self, index): self._index = index paramModel = index.model().nodeFromIndex(index) self.setParamModel(paramModel) self.connect(self, Qt.SIGNAL("modelChanged()"), self.onModelChanged) self.setValue(paramModel.value()) def onModelChanged(self): model = self.index().model() model.setData(self.index(), Qt.QVariant(self.getValue())) class ComboBoxBoolean(ParamBase, Qt.QComboBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QComboBox.__init__(self, parent) self.addItems(['True', 'False']) self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), self.onCurrentIndexChanged) def getValue(self): return str(self.currentText()) def setValue(self, value): currentIdx = self.currentIndex() idx = self.findText(value) if currentIdx == idx: self.emit(Qt.SIGNAL("currentIndexChanged(int)"), self.currentIndex()) else: self.setCurrentIndex(idx) def onCurrentIndexChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) class ComboBoxParam(ParamBase, Qt.QComboBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QComboBox.__init__(self, parent) self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), self.onCurrentIndexChanged) def getValue(self): return str(self.currentText()) def setValue(self, value): currentIdx = self.currentIndex() idx = self.findText(value) if currentIdx == idx: self.emit(Qt.SIGNAL("currentIndexChanged(int)"), self.currentIndex()) else: self.setCurrentIndex(idx) def onCurrentIndexChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) class MSAttrListComboBoxParam(ParamBase, MSAttrListComboBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) MSAttrListComboBox.__init__(self, parent) # self.setUseParentModel(True) # self.setModel("/" + self.paramModel().type() + "List") self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), self.onCurrentIndexChanged) def getValue(self): return str(self.currentText()) def setValue(self, value): self.setCurrentText(value) def onCurrentIndexChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) class AttrListComboBoxParam(ParamBase, TaurusAttrListComboBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) TaurusAttrListComboBox.__init__(self, parent) self.setModel("/" + self.paramModel().type() + "List") # self.setToolTip(self.paramModel().description()) def handleEvent(self, src, type, value): self.clear() if src and value: lines = list(value.value) items = [] if self.paramModel().type() == globals.PARAM_CONTROLLER_CLASS: for line in lines: items.append(line.split()[4]) else: for line in lines: items.append(line.split()[0]) items.sort() self.addItems(items) # self.updateStyle() def getValue(self): return str(self.currentText()) # def resetValue(self): # self.setCurrentIndex(0) class LineEditParam(ParamBase, Qt.QLineEdit): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QLineEdit.__init__(self, parent) self.connect(self, Qt.SIGNAL("textChanged(const QString&)"), self.onTextChanged) # self.setToolTip(self.paramModel().description()) def onTextChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) # def setDefaultValue(self): # defVal = self.paramModel().defValue() # if not (defVal == "None" or defVal == ""): # self.setText(defVal) def setValue(self, value): self.setText(value) def getValue(self): return str(self.text()) # def resetValue(self): # self.setText("") # self.setDefaultValue() class CheckBoxParam(ParamBase, Qt.QCheckBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QCheckBox.__init__(self, parent) self.connect(self, Qt.SIGNAL("stateChanged(int)"), self.onStateChanged) def getValue(self): return str(self.isChecked()) def setValue(self, value): self.setChecked(str2bool(value)) def onStateChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) class SpinBoxParam(ParamBase, Qt.QSpinBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QSpinBox.__init__(self, parent) self.setRange(-999999999, 999999999) self.setAccelerated(True) # self.setToolTip(self.paramModel().description()) def getValue(self): return str(self.value()) def setValue(self, value): Qt.QSpinBox.setValue(self, int(value)) # def resetValue(self): # self.setValue(0) # self.setDefaultValue() class DoubleSpinBoxParam(ParamBase, Qt.QDoubleSpinBox): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QDoubleSpinBox.__init__(self, parent) self.setRange(-999999999.999999, 999999999.999999) self.setAccelerated(True) self.setDecimals(6) self.setSingleStep(0.000001) # self.setToolTip(self.paramModel().description()) def getValue(self): return str(self.value()) def setValue(self, value): Qt.QDoubleSpinBox.setValue(self, float(value)) # def setDefaultValue(self): # defVal = self.paramModel().defValue() # if not (defVal == "None" or defVal == ""): # defVal = defVal.lower() # try: # val = float(defVal) # self.setValue(val) # except Error, e: # pass # # def resetValue(self): # self.setValue(0.0) # self.setDefaultValue() class FileDialogParam(ParamBase, Qt.QWidget): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QWidget.__init__(self, parent) self.setToolTip(self.paramModel().description()) self.layout = Qt.QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.filePath = Qt.QLineEdit(self) self.layout.addWidget(self.filePath) self.button = Qt.QPushButton(self) self.button.setText("...") self.layout.addWidget(self.button) self.text = "" Qt.QObject.connect(self.button, Qt.SIGNAL("clicked()"), self._chooseAFile) def _chooseAFile(self): path = Qt.QFileDialog().getOpenFileName() self.filePath.setText(path) def _readFileContent(self, path): content = "" if not os.access(path, os.R_OK): return (False, content) file = open(path, "r") line = "nonempty" while(line != ""): line = file.readline() content = content + line file.close() return (True, content) def getValue(self): state, self.text = self._readFileContent(self.filePath.text()) if state is False: self.filePath.setText("Error: couldn't read a file") return str(self.text) def setValue(self, value): self.filePath.setText(value) class DirPathParam(ParamBase, Qt.QWidget): def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) Qt.QWidget.__init__(self, parent) self.layout = Qt.QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.dirPath = Qt.QLineEdit(self) self.layout.addWidget(self.dirPath) self.button = Qt.QPushButton(self) self.button.setText("...") self.layout.addWidget(self.button) self.connect(self.button, Qt.SIGNAL("clicked()"), self.__chooseDirPath) self.connect(self.dirPath, Qt.SIGNAL("textChanged(const QString&)"), self.onDirPathChanged) def onDirPathChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) def __chooseDirPath(self): path = Qt.QFileDialog().getExistingDirectory() self.setValue(path) def getValue(self): return str(self.dirPath.text()) def setValue(self, value): self.dirPath.setText(value) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/0000755000234000017500000000000012555673001031360 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/__init__.py0000644000234000017500000000206212555672637033507 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ __init__.py: """ from sequenceeditor import TaurusSequencer, TaurusSequencerWidget, main sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/delegate.py0000644000234000017500000001424412555672637033527 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ delegate.py: """ from taurus.external.qt import Qt from sardana.taurus.core.tango.sardana import macro from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.parameditors import \ AttrListComboBoxParam, SpinBoxParam, \ DoubleSpinBoxParam, LineEditParam, FileDialogParam from sardana.taurus.qt.qtgui.extra_macroexecutor import globals class SequenceEditorDelegate(Qt.QItemDelegate): def __init__(self, parent=None): Qt.QItemDelegate.__init__(self, parent) def paint(self, painter, option, index): if index.column() == 2: macroNode = index.model().nodeFromIndex(index) opts = Qt.QStyleOptionProgressBarV2() opts.rect = option.rect range = macroNode.range() opts.minimum = range[0] opts.maximum = range[1] opts.textVisible = True percent = macroNode.progress() opts.progress = percent # opts.text = Qt.QString('Unavailable' if percent == 0 else '%d%%'%percent) opts.text = Qt.QString('%d%%' % percent) # opts.text = Qt.QString(percent) Qt.QApplication.style().drawControl(Qt.QStyle.CE_ProgressBar, opts, painter) else: Qt.QItemDelegate.paint(self, painter, option, index) def createEditor(self, parent, option, index): if index.column() == 3: return Qt.QCheckBox(parent) else: return Qt.QItemDelegate.createEditor(self, parent, option, index) def setEditorData(self, editor, index): node = index.model().mapToSource(index).internalPointer() if index.column() == 3: #and isinstance(node, MacroNode): editor.setChecked(node.isPause()) else: Qt.QItemDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index): if index.column() == 3: model.setData(index, Qt.QVariant(editor.isChecked())) class MacroParametersProxyDelegate(Qt.QItemDelegate): def __init__(self, parent=None): Qt.QItemDelegate.__init__(self, parent) def createEditor(self, parent, option, index): if index.column() == 1: node = index.model().nodeFromIndex(index) if isinstance(node, macro.SingleParamNode): paramType = node.type() if paramType in globals.EDITOR_COMBOBOX_PARAMS: comboBox = AttrListComboBoxParam(parent, node) comboBox.setUseParentModel(True) return comboBox elif paramType in globals.EDITOR_SPINBOX_PARAMS: return SpinBoxParam(parent, node) elif paramType in globals.EDITOR_DOUBLESPINBOX_PARAMS: return DoubleSpinBoxParam(parent, node) elif paramType in globals.EDITOR_LINEEDIT_PARAMS: return LineEditParam(parent, node) elif paramType in globals.EDITOR_FILEDIALOG_PARAMS: return FileDialogParam(parent, node) return Qt.QItemDelegate.createEditor(self, parent, option, index) def setEditorData(self, editor, index): if index.column() == 1: text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) if text == "None" or text == "": pass else: node = index.model().mapToSource(index).internalPointer() paramType = node.type() if paramType in globals.EDITOR_COMBOBOX_PARAMS : i = editor.findText(text) if i == -1: i = 0 else: editor.previous = text editor.setCurrentIndex(i) elif paramType in globals.EDITOR_SPINBOX_PARAMS: editor.setValue(int(text)) elif paramType in globals.EDITOR_DOUBLESPINBOX_PARAMS: editor.setValue(float(text)) elif paramType in globals.EDITOR_LINEEDIT_PARAMS: editor.setText(text) elif paramType in globals.EDITOR_FILEDIALOG_PARAMS: editor.filePath.setText(text) else: Qt.QItemDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index): if index.column() == 1: model.setData(index, Qt.QVariant(editor.getValue())) def sizeHint(self, option, index): if index.column() == 0: fm = option.fontMetrics text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) document = Qt.QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) size = Qt.QSize(document.idealWidth() + 5, fm.height()) elif index.column() == 1: editor = self.createEditor(self.parent(), option, index) if editor is None: size = Qt.QItemDelegate.sizeHint(self, option, index) else: size = editor.sizeHint() editor.hide() editor.setParent(None) # editor.destroy() else: size = Qt.QItemDelegate.sizeHint(self, option, index) return size sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/model.py0000644000234000017500000003370012555672637033053 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ model.py: """ from lxml import etree from taurus.external.qt import Qt from sardana.taurus.core.tango.sardana import macro class MacroSequenceTreeModel(Qt.QAbstractItemModel): def __init__(self, parent=None): Qt.QAbstractItemModel.__init__(self, parent) self.columns = 4 self.setRoot(macro.SequenceNode()) self.headers = ["Macro", "Parameters", "Progress", "Pause"] def root(self): return self._root def setRoot(self, root): self._root = root self.reset() def clearSequence(self): self.setRoot(macro.SequenceNode()) def isEmpty(self): return len(self.root()) == 0 def flags(self, index): column = index.column() node = self.nodeFromIndex(index) flags = Qt.Qt.ItemIsEnabled if column == 0: flags |= Qt.Qt.ItemIsSelectable elif column == 1: if isinstance(node, macro.SingleParamNode) and \ not node.type() == "User": flags |= Qt.Qt.ItemIsEditable else: flags |= Qt.Qt.ItemIsSelectable elif column == 2: flags |= Qt.Qt.ItemIsSelectable elif index.column() == 3: flags |= (Qt.Qt.ItemIsSelectable | Qt.Qt.ItemIsEditable) if isinstance(node, macro.MacroNode): flags |= Qt.Qt.ItemIsDragEnabled if node.isAllowedHooks(): flags |= Qt.Qt.ItemIsDropEnabled return flags def _insertRow(self, parentIndex, node=None, row=-1): parentNode = self.nodeFromIndex(parentIndex) if row == -1: row = len(parentNode) if isinstance(parentNode, macro.RepeatParamNode): if node == None: node = parentNode.newRepeat() self.beginInsertRows(parentIndex, row, row) row = parentNode.insertChild(node, row) self.endInsertRows() return self.index(row, 0, parentIndex) def _removeRow(self, index): """This method is used remove macro (pased via index)""" node = self.nodeFromIndex(index) parentIndex = index.parent() parentNode = self.nodeFromIndex(parentIndex) row = parentNode.rowOfChild(node) self.beginRemoveRows(parentIndex, row, row) parentNode.removeChild(node) self.endRemoveRows() def _upRow(self, index): node = self.nodeFromIndex(index) parentIndex = index.parent() parentNode = self.nodeFromIndex(parentIndex) row = parentNode.rowOfChild(node) self._removeRow(index) newIndex = self._insertRow(parentIndex, node, row - 1) if isinstance(parentNode, macro.RepeatParamNode): parentNode.arrangeIndexes() return newIndex def _downRow(self, index): node = self.nodeFromIndex(index) parentIndex = index.parent() parentNode = self.nodeFromIndex(parentIndex) row = parentNode.rowOfChild(node) self._removeRow(index) newIndex = self._insertRow(parentIndex, node, row + 1) if isinstance(parentNode, macro.RepeatParamNode): parentNode.arrangeIndexes() return newIndex def _leftRow(self, index): """This method is used to move selected macro (pased via index) to it's grandparent's hook list. In tree representation it basically move macro to the left""" node = self.nodeFromIndex(index) parentIndex = index.parent() grandParentIndex = parentIndex.parent() self._removeRow(index) return self._insertRow(grandParentIndex, node) def _rightRow(self, index): """This method is used to move selected macro (pased via index) to it's grandparent's hook list. In tree representation it basically move macro to the left""" node = self.nodeFromIndex(index) parentIndex = index.parent() row = index.row() self._removeRow(index) newParentIndex = self.index(row, 0, parentIndex) return self._insertRow(newParentIndex, node) def rowCount(self, parent): branchNode = self.nodeFromIndex(parent) return len(branchNode) def columnCount(self, parent): return self.columns def data(self, index, role): if role == Qt.Qt.DisplayRole: node = self.nodeFromIndex(index) if index.column() == 0: return Qt.QVariant(node.name()) elif index.column() == 1: return Qt.QVariant(node.value()) elif index.column() == 2: if isinstance(node, macro.MacroNode): return Qt.QVariant(node.progress()) elif role == Qt.Qt.DecorationRole: node = self.nodeFromIndex(index) if index.column() == 3: if isinstance(node, macro.MacroNode): if node.isPause(): return Qt.QVariant(Qt.QIcon(":/actions/media-playback-pause.svg")) return Qt.QVariant() def setData (self, index, value, role=Qt.Qt.EditRole): node = self.nodeFromIndex(index) if index.column() == 1: if isinstance(node, macro.SingleParamNode): node.setValue(Qt.from_qvariant(value, str)) self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) while True: index = index.parent() node = self.nodeFromIndex(index) if isinstance(node, macro.MacroNode): self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index.sibling(index.row(), self.columnCount(index))) break elif index.column() == 2: progress = Qt.from_qvariant(value, float) node.setProgress(progress) self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) elif index.column() == 3: node.setPause(Qt.from_qvariant(value, bool)) self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) return True def headerData(self, section, orientation, role): if orientation == Qt.Qt.Horizontal and role == Qt.Qt.DisplayRole: return Qt.QVariant(self.headers[section]) return Qt.QVariant() def index(self, row, column, parent): assert self.root() is not None branchNode = self.nodeFromIndex(parent) assert branchNode is not None return self.createIndex(row, column, branchNode.child(row)) def parent(self, child): node = self.nodeFromIndex(child) if node is None: return Qt.QModelIndex() parent = node.parent() if parent is None: return Qt.QModelIndex() grandparent = parent.parent() if grandparent is None: return Qt.QModelIndex() row = grandparent.rowOfChild(parent) assert row != -1 return self.createIndex(row, 0, parent) def nodeFromIndex(self, index): if index.isValid(): return index.internalPointer() else: return self.root() def toXmlString(self, pretty=False, withId=True): xmlSequence = self.root().toXml(withId=withId) xmlTree = etree.ElementTree(xmlSequence) xmlString = etree.tostring(xmlTree, pretty_print=pretty) return xmlString def fromXmlString(self, xmlString): xmlElement = etree.fromstring(xmlString) newRoot = macro.SequenceNode(None) newRoot.fromXml(xmlElement) self.setRoot(newRoot) self.reset() return newRoot def fromPlainText(self, text): newRoot = macro.SequenceNode(None) newRoot.fromPlainText(text) self.setRoot(newRoot) self.reset() return newRoot def assignIds(self): """ Assigns ids for all macros present in the sequence. If certain macro already had an id, it stays without change. A list of all ids is returned :return: (list) """ parentNode = self.root() return self.__assignIds(parentNode) def __assignIds(self, parentNode): ids = [] for childNode in parentNode.children(): if isinstance(childNode, macro.MacroNode): id = childNode.assignId() ids.append(id) ids.extend(self.__assignIds(childNode)) return ids def firstMacroId(self): return self.root().child(0).id() def lastMacroId(self): root = self.root() return root.child(len(root.children()) - 1).id() def createIdIndexDictionary(self): parentIndex = Qt.QModelIndex() parentNode = self.root() return self.__createIdIndexDictionary(parentIndex, parentNode) def __createIdIndexDictionary(self, parentIndex, parentNode): d = {} for row, child in enumerate(parentNode.children()): if isinstance(child, macro.MacroNode): index = self.index(row, 0, parentIndex) d[child.id()] = index d.update(self.__createIdIndexDictionary(index, child)) return d # def supportedDropActions(self): # return Qt.Qt.CopyAction | Qt.Qt.MoveAction # def mimeTypes(self): # types = Qt.QStringList() # types.append("text/xml") # return types # def mimeData(self, indexes): # mimeData = Qt.QMimeData() # encodedData = Qt.QByteArray() # stream = Qt.QDataStream(encodedData, Qt.QIODevice.WriteOnly) # doc = xml.dom.minidom.Document() # for i,index in enumerate(indexes): # if i % 2: # continue # text = self.nodeFromIndex(index).toXml(doc).toxml() # stream.writeString(text) # # mimeData.setData("text/xml", encodedData) # return mimeData # # def dropMimeData(self, data, action, row, column, parent): # if action == Qt.Qt.IgnoreAction: # return True # if not data.hasFormat("text/xml"): # return False # # encodedData = data.data("text/xml") # stream = Qt.QDataStream(encodedData, Qt.QIODevice.ReadOnly) # newItems = Qt.QStringList() # rows = 0 # # while(not stream.atEnd()): # text = stream.readString() # newItems.append(text) # rows += 1 # # sequence = self.nodeFromIndex(parent) # # for text in newItems: # macroNode = macro.MacroNode() # macroNode.fromDoc(xml.dom.minidom.parseString(text)) # self.insertMacro(sequence, macroNode, row, False) # macros = [macro.name() for macro in macroNode.allMacros()] # if action == Qt.Qt.CopyAction: # self.emit(Qt.SIGNAL("macrosAdded"), macros, macroNode.allMotors()) # self.emit(Qt.SIGNAL("dataChanged")) # return True class MacroSequenceProxyModel(Qt.QSortFilterProxyModel): def __init__(self, parent=None): Qt.QSortFilterProxyModel.__init__(self, parent) self.setDynamicSortFilter(True) self.headers = ["Macro", "Parameters", "Progress", "Pause"] self.columns = 4 def __getattr__(self, name): return getattr(self.sourceModel(), name) def nodeFromIndex(self, index): sourceIndex = self.mapToSource(index) node = self.sourceModel().nodeFromIndex(sourceIndex) return node def createIdIndexDictionary(self): d = self.sourceModel().createIdIndexDictionary() for id, sourceIndex in d.iteritems(): proxyIndex = self.mapFromSource(sourceIndex) d[id] = Qt.QPersistentModelIndex(proxyIndex) return d def filterAcceptsRow(self, row, parentIndex): child = self.sourceModel().index(row, 0, parentIndex) node = self.sourceModel().nodeFromIndex(child) return isinstance(node, macro.MacroNode) class MacroParametersProxyModel(Qt.QSortFilterProxyModel): def __init__(self, parent=None): Qt.QSortFilterProxyModel.__init__(self, parent) self.columns = 2 self.headers = ["Parameter", "Value", "", "", "", ""] self._macroIndex = None def __getattr__(self, name): return getattr(self.sourceModel(), name) def headerData(self, section, orientation, role): if orientation == Qt.Qt.Horizontal and role == Qt.Qt.DisplayRole: return Qt.QVariant(self.headers[section]) return Qt.QVariant() def nodeFromIndex(self, index): sourceIndex = self.mapToSource(index) node = self.sourceModel().nodeFromIndex(sourceIndex) return node def setMacroIndex(self, macroIndex): self._macroIndex = macroIndex def macroIndex(self): return self._macroIndex def columnCount(self, parent): return self.columns def filterAcceptsRow(self, row, parentIndex): if self.macroIndex() == None: return False if self.macroIndex() == parentIndex: child = self.sourceModel().index(row, 0, parentIndex) node = self.sourceModel().nodeFromIndex(child) if not isinstance(node, macro.ParamNode): return False return True sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/sequenceeditor.py0000644000234000017500000011225312555672637034773 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ sequenceeditor.py: """ import os import sys from lxml import etree import PyTango from taurus import Device from taurus.external.qt import Qt from taurus.qt.qtgui.container import TaurusMainWindow, TaurusWidget from taurus.qt.qtcore.configuration import BaseConfigurableClass from taurus.qt.qtgui.display import TaurusLed from taurus.qt.qtgui.dialog import TaurusMessageBox from taurus.qt.qtgui.resource import getIcon, getThemeIcon from sardana.taurus.qt.qtgui.extra_macroexecutor.common import MacroExecutionWindow, MacroComboBox, standardPlotablesFilter from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor import ParamEditorManager, StandardMacroParametersEditor from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.delegate import ParamEditorDelegate from sardana.taurus.core.tango.sardana.macro import MacroRunException, MacroNode from sardana.taurus.qt.qtgui.extra_macroexecutor import globals from .model import MacroSequenceTreeModel, MacroSequenceProxyModel, MacroParametersProxyModel from .delegate import SequenceEditorDelegate class HookAction(Qt.QAction): def __init__(self, text, parent, macroNode): Qt.QAction.__init__(self, text, parent) self.setCheckable(True) self.setMacroNode(macroNode) if text in self.macroNode().hookPlaces(): self.setChecked(True) self.setToolTip("This macro will be executed as a %s" % text) self.connect(self, Qt.SIGNAL('toggled(bool)'), self.onToggle) def macroNode(self): return self._macroNode def setMacroNode(self, macroNode): self._macroNode = macroNode def onToggle(self, trueFalse): if trueFalse: self.macroNode().addHookPlace(str(self.text())) else: self.macroNode().removeHookPlace(str(self.text())) class MacroSequenceTree(Qt.QTreeView, BaseConfigurableClass): def __init__(self, parent=None): Qt.QTreeView.__init__(self, parent) BaseConfigurableClass.__init__(self) self._idIndexDict = {} self.setSelectionBehavior(Qt.QTreeView.SelectRows) self.setSelectionMode(Qt.QTreeView.SingleSelection) self.setRootIsDecorated(False) # self.setItemsExpandable(False) self.setDragEnabled(True) self.setAcceptDrops(True) self.setTabKeyNavigation(True) self.setEditTriggers(Qt.QAbstractItemView.EditKeyPressed | Qt.QAbstractItemView.CurrentChanged) self.setDropIndicatorShown(True) self.deleteAction = Qt.QAction(getThemeIcon("list-remove"), "Remove macro", self) self.connect(self.deleteAction, Qt.SIGNAL("triggered()"), self.deleteMacro) self.deleteAction.setToolTip("Clicking this button will remove current macro.") self.moveUpAction = Qt.QAction(getThemeIcon("go-up"), "Move up", self) self.connect(self.moveUpAction, Qt.SIGNAL("triggered()"), self.upMacro) self.moveUpAction.setToolTip("Clicking this button will move current macro up.") self.moveDownAction = Qt.QAction(getThemeIcon("go-down"), "Move down", self) self.connect(self.moveDownAction, Qt.SIGNAL("triggered()"), self.downMacro) self.moveDownAction.setToolTip("Clicking this button will move current macro down.") self.moveLeftAction = Qt.QAction(getThemeIcon("go-previous"), "Move left", self) self.connect(self.moveLeftAction, Qt.SIGNAL("triggered()"), self.leftMacro) self.moveLeftAction.setToolTip("Clicking this button will move current macro to the left.") self.moveRightAction = Qt.QAction(getThemeIcon("go-next"), "Move right", self) self.connect(self.moveRightAction, Qt.SIGNAL("triggered()"), self.rightMacro) self.moveRightAction.setToolTip("Clicking this button will move current macro to the right.") def disableActions(self): self.deleteAction.setEnabled(False) self.moveUpAction.setEnabled(False) self.moveDownAction.setEnabled(False) self.moveLeftAction.setEnabled(False) self.moveRightAction.setEnabled(False) def contextMenuEvent(self, event): contextMenu = Qt.QMenu() proxyIndex = self.indexAt(event.pos()) node = self.model().nodeFromIndex(proxyIndex) #this is in case if we right click on an empty field of tree if not isinstance(node, MacroNode): return parentNode = node.parent() #this is in case if we right click on a top level macro if not isinstance(parentNode, MacroNode): return allowedHooks = parentNode.allowedHookPlaces() if allowedHooks: hookPlacesSubmenu = contextMenu.addMenu("Hook places") for allowedHook in allowedHooks: action = HookAction(allowedHook, self, node) hookPlacesSubmenu.addAction(action) contextMenu.exec_(event.globalPos()) # def setHint(self, add): # action = self.sender() # hookText = action.text() # macroNode = action.macroNode() # if add: # macroNode.addHook(hookText) # else: # macroNode.removeHook(hookText) # pass def selectionChanged(self, selected, deselected): self.disableActions() macroName = None node, proxyIndex = self.selectedNodeAndIndex() if node is not None: macroName = node.name() self.deleteAction.setEnabled(True) self.moveUpAction.setEnabled(node.isAllowedMoveUp()) self.moveDownAction.setEnabled(node.isAllowedMoveDown()) self.moveLeftAction.setEnabled(node.isAllowedMoveLeft()) self.moveRightAction.setEnabled(node.isAllowedMoveRight()) sourceIndex = self.model().mapToSource(proxyIndex) self.emit(Qt.SIGNAL("macroChanged"), sourceIndex) self.emit(Qt.SIGNAL("macroNameChanged"), macroName) def expanded(self): for column in range(self.model().columnCount(Qt.QModelIndex())): self.resizeColumnToContents(column) def clearTree(self): self.model().clearSequence() def toXmlString(self, pretty=False, withId=True): return self.model().toXmlString(pretty=pretty, withId=withId) def fromXmlString(self, xmlString): newRoot = self.model().fromXmlString(xmlString) self.expandAll() self.expanded() return newRoot def fromPlainText(self, plainText): newRoot = self.model().fromPlainText(plainText) self.expandAll() self.expanded() return newRoot def root(self): return self.model().root() def setRoot(self, root): self.model().setRoot(root) self.model().reset() def addMacro(self, macroNode): node, proxyIndex = self.selectedNodeAndIndex() if node == None or not node.isAllowedHooks(): proxyIndex = self.rootIndex() sourceIndex = self.model().mapToSource(proxyIndex) newSourceIndex = self.model()._insertRow(sourceIndex, macroNode) newProxyIndex = self.model().mapFromSource(newSourceIndex) # persistentProxyIndex = Qt.QPersistentModelIndex(newProxyIndex) # self._idIndexDict[macroNode.id()] = persistentProxyIndex self.setCurrentIndex(newProxyIndex) self.expandAll() self.expanded() def deleteMacro(self): node, proxyIndex = self.selectedNodeAndIndex() sourceIndex = self.model().mapToSource(proxyIndex) self.model()._removeRow(sourceIndex) # self._idIndexDict.pop(node.id()) self.expandAll() self.expanded() def upMacro(self): node, proxyIndex = self.selectedNodeAndIndex() sourceIndex = self.model().mapToSource(proxyIndex) newSourceIndex = self.model()._upRow(sourceIndex) newProxyIndex = self.model().mapFromSource(newSourceIndex) # persistentProxyIndex = Qt.QPersistentModelIndex(newProxyIndex) # self._idIndexDict[node.id()] = persistentProxyIndex self.setCurrentIndex(newProxyIndex) self.expandAll() # self.expanded() def downMacro(self): node, proxyIndex = self.selectedNodeAndIndex() sourceIndex = self.model().mapToSource(proxyIndex) newSourceIndex = self.model()._downRow(sourceIndex) newProxyIndex = self.model().mapFromSource(newSourceIndex) # persistentProxyIndex = Qt.QPersistentModelIndex(newProxyIndex) # self._idIndexDict[node.id()] = persistentProxyIndex self.setCurrentIndex(newProxyIndex) self.expandAll() # self.expanded() def leftMacro(self): node, proxyIndex = self.selectedNodeAndIndex() sourceIndex = self.model().mapToSource(proxyIndex) newSourceIndex = self.model()._leftRow(sourceIndex) newProxyIndex = self.model().mapFromSource(newSourceIndex) # persistentProxyIndex = Qt.QPersistentModelIndex(newProxyIndex) # self._idIndexDict[node.id()] = persistentProxyIndex self.setCurrentIndex(newProxyIndex) self.expandAll() self.expanded() def rightMacro(self): node, proxyIndex = self.selectedNodeAndIndex() sourceIndex = self.model().mapToSource(proxyIndex) newSourceIndex = self.model()._rightRow(sourceIndex) newProxyIndex = self.model().mapFromSource(newSourceIndex) # persistentProxyIndex = Qt.QPersistentModelIndex(newProxyIndex) # self._idIndexDict[node.id()] = persistentProxyIndex self.setCurrentIndex(newProxyIndex) self.expandAll() self.expanded() def prepareMacroIds(self): model = self.model() ids = model.assignIds() firstId = model.firstMacroId() lastId = model.lastMacroId() return firstId, lastId, ids def prepareMacroProgresses(self): self._idIndexDict = self.model().createIdIndexDictionary() for macroId in self._idIndexDict.iterkeys(): self.setProgressForMacro(macroId, 0) def setProgressForMacro(self, macroId, progress): persistentIndex = self._idIndexDict.get(macroId, None) if persistentIndex == None: return progressIndex = persistentIndex.sibling(persistentIndex.row(), 2) index = Qt.QModelIndex(progressIndex) self.model().setData(index, Qt.QVariant(progress)) def setRangeForMacro(self, macroId, range): persistentIndex = self._idIndexDict.get(macroId, None) if persistentIndex == None: return index = Qt.QModelIndex(persistentIndex) node = self.model().nodeFromIndex(index) node.setRange(range) def selectedNodeAndIndex(self): """Returns a tuple with selected internal model node object and QModelIndex from current model.""" for idx in self.selectedIndexes(): if idx.column() == 0: node = self.model().nodeFromIndex(idx) break else: node, idx = None, None return node, idx def dropEvent(self, event): Qt.QTreeView.dropEvent(self, event) self.expandAll() class TaurusSequencerWidget(TaurusWidget): def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self._macroIds = [] #list representing all macros ids (all from sequence) currently executed self._sequencesPath = str(Qt.QDir.homePath()) self._sequenceModel = MacroSequenceTreeModel() self.registerConfigProperty("sequencesPath", "setSequencesPath", "sequencesPath") self.setLayout(Qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) splitter = Qt.QSplitter() self.layout().addWidget(splitter) splitter.setOrientation(Qt.Qt.Vertical) sequenceEditor = TaurusWidget() splitter.addWidget(sequenceEditor) sequenceEditor.setUseParentModel(True) sequenceEditor.setLayout(Qt.QVBoxLayout()) sequenceEditor.layout().setContentsMargins(0, 0, 0, 0) self.tree = MacroSequenceTree(sequenceEditor) self.sequenceProxyModel = MacroSequenceProxyModel() self.sequenceProxyModel.setSourceModel(self._sequenceModel) self.tree.setModel(self.sequenceProxyModel) self.tree.setItemDelegate(SequenceEditorDelegate(self.tree)) actionsLayout = Qt.QHBoxLayout() actionsLayout.setContentsMargins(0, 0, 0, 0) self.newSequenceAction = Qt.QAction(getThemeIcon("document-new"), "New", self) self.connect(self.newSequenceAction, Qt.SIGNAL("triggered()"), self.onNewSequence) self.newSequenceAction.setToolTip("New sequence") self.newSequenceAction.setEnabled(False) newSequenceButton = Qt.QToolButton() newSequenceButton.setDefaultAction(self.newSequenceAction) actionsLayout.addWidget(newSequenceButton) self.openSequenceAction = Qt.QAction(getThemeIcon("document-open"), "Open...", self) self.connect(self.openSequenceAction, Qt.SIGNAL("triggered()"), self.onOpenSequence) self.openSequenceAction.setToolTip("Open sequence...") openSequenceButton = Qt.QToolButton() openSequenceButton.setDefaultAction(self.openSequenceAction) actionsLayout.addWidget(openSequenceButton) self.saveSequenceAction = Qt.QAction(getThemeIcon("document-save"), "Save...", self) self.connect(self.saveSequenceAction, Qt.SIGNAL("triggered()"), self.onSaveSequence) self.saveSequenceAction.setToolTip("Save sequence...") self.saveSequenceAction.setEnabled(False) saveSequenceButton = Qt.QToolButton() saveSequenceButton.setDefaultAction(self.saveSequenceAction) actionsLayout.addWidget(saveSequenceButton) self.stopSequenceAction = Qt.QAction(getIcon(":/actions/media_playback_stop.svg"), "Stop", self) self.connect(self.stopSequenceAction, Qt.SIGNAL("triggered()"), self.onStopSequence) self.stopSequenceAction.setToolTip("Stop sequence") stopSequenceButton = Qt.QToolButton() stopSequenceButton.setDefaultAction(self.stopSequenceAction) actionsLayout.addWidget(stopSequenceButton) self.pauseSequenceAction = Qt.QAction(getIcon(":/actions/media_playback_pause.svg"), "Pause", self) self.connect(self.pauseSequenceAction, Qt.SIGNAL("triggered()"), self.onPauseSequence) self.pauseSequenceAction.setToolTip("Pause sequence") pauseSequenceButton = Qt.QToolButton() pauseSequenceButton.setDefaultAction(self.pauseSequenceAction) actionsLayout.addWidget(pauseSequenceButton) self.playSequenceAction = Qt.QAction(getIcon(":/actions/media_playback_start.svg"), "Play", self) self.connect(self.playSequenceAction, Qt.SIGNAL("triggered()"), self.onPlaySequence) self.playSequenceAction.setToolTip("Play sequence") playSequenceButton = Qt.QToolButton() playSequenceButton.setDefaultAction(self.playSequenceAction) actionsLayout.addWidget(playSequenceButton) self.doorStateLed = TaurusLed(self) actionsLayout.addWidget(self.doorStateLed) #@todo this feature will be replaced by checkboxes in the sequence tree view #indicating clearing of the plot after execution self.fullSequencePlotCheckBox = Qt.QCheckBox("Full sequence plot", self) self.connect(self.fullSequencePlotCheckBox, Qt.SIGNAL("toggled(bool)"), self.setFullSequencePlot) self.fullSequencePlotCheckBox.setChecked(True) actionsLayout.addWidget(self.fullSequencePlotCheckBox) spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed) actionsLayout.addItem(spacerItem) sequenceEditor.layout().addLayout(actionsLayout) macroLayout = Qt.QHBoxLayout() macroLayout.setContentsMargins(0, 0, 0, 0) macroLabel = Qt.QLabel("Macro:") macroLayout.addWidget(macroLabel) self.macroComboBox = MacroComboBox(self) self.macroComboBox.setUseParentModel(True) self.macroComboBox.setModelColumn(0) self.macroComboBox.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) macroLayout.addWidget(self.macroComboBox) self.addMacroAction = Qt.QAction(getThemeIcon("list-add"), "Add macro...", self) self.connect(self.addMacroAction, Qt.SIGNAL("triggered()"), self.onAdd) self.addMacroAction.setToolTip("Clicking this button will add selected macro") self.addMacroAction.setEnabled(False) addButton = Qt.QToolButton() addButton.setDefaultAction(self.addMacroAction) macroLayout.addWidget(addButton) sequenceEditor.layout().addLayout(macroLayout) sequenceLayout = Qt.QHBoxLayout() sequenceLayout.addWidget(self.tree) layout = Qt.QVBoxLayout() delButton = Qt.QToolButton() delButton.setDefaultAction(self.tree.deleteAction) delButton.setEnabled(False) layout.addWidget(delButton) upButton = Qt.QToolButton() upButton.setDefaultAction(self.tree.moveUpAction) upButton.setEnabled(False) layout.addWidget(upButton) downButton = Qt.QToolButton() downButton.setDefaultAction(self.tree.moveDownAction) downButton.setEnabled(False) layout.addWidget(downButton) leftButton = Qt.QToolButton() leftButton.setDefaultAction(self.tree.moveLeftAction) leftButton.setEnabled(False) layout.addWidget(leftButton) rightButton = Qt.QToolButton() rightButton.setDefaultAction(self.tree.moveRightAction) rightButton.setEnabled(False) layout.addWidget(rightButton) spacerItem = Qt.QSpacerItem(0, 40, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) layout.addItem(spacerItem) sequenceLayout.addLayout(layout) sequenceEditor.layout().addLayout(sequenceLayout) self.parametersProxyModel = MacroParametersProxyModel() self.parametersProxyModel.setSourceModel(self._sequenceModel) self.stackedWidget = Qt.QStackedWidget() splitter.addWidget(self.stackedWidget) self.standardMacroParametersEditor = StandardMacroParametersEditor(self.stackedWidget) self.standardMacroParametersEditor.setModel(self.parametersProxyModel) self.standardMacroParametersEditor.tree.setItemDelegate(ParamEditorDelegate(self.standardMacroParametersEditor.tree)) self.stackedWidget.addWidget(self.standardMacroParametersEditor) self.customMacroParametersEditor = None self.connect(self.macroComboBox, Qt.SIGNAL("currentIndexChanged(QString)"), self.onMacroComboBoxChanged) self.connect(self.tree, Qt.SIGNAL("macroChanged"), self.setMacroParametersRootIndex) def contextMenuEvent(self, event): menu = Qt.QMenu() action = menu.addAction(getThemeIcon("view-refresh"), "Check door state", self.checkDoorState) menu.exec_(event.globalPos()) def checkDoorState(self): '''Method used by "Check door state" action (available in the context menu). It is a workaround for situations when the event notification about the macro status does not reach the sequencer widget.''' door = Device(self.doorName()) doorState = door.state() if doorState == PyTango.DevState.RUNNING: self.playSequenceAction.setEnabled(False) self.pauseSequenceAction.setEnabled(True) self.stopSequenceAction.setEnabled(True) elif doorState in (PyTango.DevState.ON, PyTango.DevState.ALARM): self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(False) elif doorState == PyTango.DevState.STANDBY: self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(True) def doorName(self): return self._doorName def setDoorName(self, doorName): self._doorName = doorName def firstMacroId(self): return self._firstMacroId def setFirstMacroId(self, firstMacroId): self._firstMacroId = firstMacroId def lastMacroId(self): return self._lastMacroId def setLastMacroId(self, lastMacroId): self._lastMacroId = lastMacroId def macroIds(self): return self._macroIds def setMacroIds(self, macroIds): self._macroIds = macroIds def emitExecutionStarted(self): return self._emitExecutionStarted def setEmitExecutionStarted(self, yesNo): self._emitExecutionStarted = yesNo def sequencesPath(self): return self._sequencesPath def setSequencesPath(self, sequencesPath): self._sequencesPath = sequencesPath def isFullSequencePlot(self): return self._fullSequencePlot def setFullSequencePlot(self, fullSequencePlot): self._fullSequencePlot = fullSequencePlot def onNewSequence(self): if Qt.QMessageBox.question(self, "New sequence", "Do you want to save existing sequence?", Qt.QMessageBox.Yes, Qt.QMessageBox.No) == Qt.QMessageBox.Yes: self.onSaveSequence() self.tree.clearTree() self.newSequenceAction.setEnabled(False) self.saveSequenceAction.setEnabled(False) self.emit(Qt.SIGNAL("currentMacroChanged"), None) def onOpenSequence(self): if not self._sequenceModel.isEmpty(): if Qt.QMessageBox.question(self, "Open sequence", "Do you want to save existing sequence?", Qt.QMessageBox.Yes, Qt.QMessageBox.No) == Qt.QMessageBox.Yes: self.onSaveSequence() self.tree.clearTree() sequencesPath = self.sequencesPath() fileName = str(Qt.QFileDialog.getOpenFileName(self, "Choose a sequence to open...", sequencesPath, "*")) if fileName == "": return #@todo: reset macroComboBox to index 0 try: file = open(fileName, 'r') string = file.read() if fileName.endswith('.xml'): root = self.fromXmlString(string) else: root = self.fromPlainText(string) self._sequenceModel.setRoot(root) self.sequenceProxyModel.invalidateFilter() self.tree.expandAll() self.tree.expanded() self.parametersProxyModel.setMacroIndex(None) self.parametersProxyModel.invalidateFilter() if not self._sequenceModel.isEmpty(): self.newSequenceAction.setEnabled(True) self.saveSequenceAction.setEnabled(True) self.playSequenceAction.setEnabled(True) except IOError: Qt.QMessageBox.warning(self, "Error while loading macros sequence", "There was a problem while reading from file: %s" % fileName) self.tree.clearTree() self.newSequenceAction.setEnabled(False) self.saveSequenceAction.setEnabled(False) except: self.tree.clearTree() self.playSequenceAction.setEnabled(False) self.newSequenceAction.setEnabled(False) self.saveSequenceAction.setEnabled(False) raise finally: if not file is None: file.close() self.setSequencesPath(str.join("/", fileName.rsplit("/")[:-1])) self.emit(Qt.SIGNAL("currentMacroChanged"), None) def onSaveSequence(self): sequencesPath = self.sequencesPath() if sequencesPath == "": sequencesPath = str(Qt.QDir.homePath()) sequencesPath = os.path.join(sequencesPath, "Untitled.xml") fileName = str(Qt.QFileDialog.getSaveFileName(self, "Choose a sequence file name...", sequencesPath, "*.xml")) if fileName == "": return try: file = open(fileName, "w") file.write(self.tree.toXmlString(pretty=True, withId=False)) self.setSequencesPath(str.join("/", fileName.rsplit("/")[:-1])) except Exception, e: Qt.QMessageBox.warning(self, "Error while saving macros sequence", "There was a problem while writing to the file: %s" % fileName) print e finally: if not file is None: file.close() def onPlaySequence(self): door = Device(self.doorName()) doorState = door.state() if doorState == PyTango.DevState.ON or doorState == PyTango.DevState.ALARM: first, last, ids = self.tree.prepareMacroIds() self.setFirstMacroId(first) self.setLastMacroId(last) self.setMacroIds(ids) self.tree.prepareMacroProgresses() self.setEmitExecutionStarted(True) door.runMacro(self.tree.toXmlString()) elif doorState == PyTango.DevState.STANDBY: door.command_inout("ResumeMacro") else: Qt.QMessageBox.warning(self, "Error while starting/resuming sequence", "It was not possible to start/resume sequence, because state of the door was different than ON/STANDBY") def onStopSequence(self): door = Device(self.doorName()) doorState = door.state() if doorState in (PyTango.DevState.RUNNING, PyTango.DevState.STANDBY): door.command_inout("StopMacro") else: Qt.QMessageBox.warning(self, "Error while stopping sequence", "It was not possible to stop sequence, because state of the door was different than RUNNING or STANDBY") def onPauseSequence(self): door = Device(self.doorName()) doorState = door.state() if doorState == PyTango.DevState.RUNNING: door.command_inout("PauseMacro") else: Qt.QMessageBox.warning(self, "Error while pausing sequence", "It was not possible to pause sequence, because state of the door was different than RUNNING") def onMacroStatusUpdated(self, data): macro = data[0] if macro is None: return data = data[1][0] state, range, step, id = str(data["state"]), data["range"], data["step"], data["id"] if id is None: return id = int(id) if not id in self.macroIds(): return macroName = macro.name shortMessage = "" if state == "start": #@todo: Check this signal because it doesn't work, emitExecutionStarted is not set!!! if self.emitExecutionStarted(): self.emit(Qt.SIGNAL("macroStarted"), "DoorOutput") self.tree.setRangeForMacro(id, range) self.playSequenceAction.setEnabled(False) self.pauseSequenceAction.setEnabled(True) self.stopSequenceAction.setEnabled(True) if id == self.firstMacroId(): self.emit(Qt.SIGNAL("plotablesFilterChanged"), None) self.emit(Qt.SIGNAL("plotablesFilterChanged"), standardPlotablesFilter) shortMessage = "Sequence started." elif not self.isFullSequencePlot(): self.emit(Qt.SIGNAL("plotablesFilterChanged"), None) shortMessage += " Macro %s started." % macroName elif state == "pause": self.playSequenceAction.setText("Resume sequence") self.playSequenceAction.setToolTip("Resume sequence") self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) shortMessage = "Macro %s paused." % macroName elif state == "resume": self.playSequenceAction.setText("Start sequence") self.playSequenceAction.setToolTip("Start sequence") self.playSequenceAction.setEnabled(False) self.pauseSequenceAction.setEnabled(True) shortMessage = "Macro %s resumed." % macroName elif state == "stop" or state == "finish": shortMessage = "Macro %s finished." % macroName if id == self.lastMacroId(): self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(False) shortMessage += " Sequence finished." elif state == 'exception': self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(False) shortMessage = "Macro %s error." % macroName exc_value, exc_stack = data['exc_value'], data['exc_stack'] exceptionDialog = TaurusMessageBox(MacroRunException, exc_value, exc_stack) exceptionDialog.exec_() elif state == 'abort': self.playSequenceAction.setText("Start sequence") self.playSequenceAction.setToolTip("Start sequence") self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(False) shortMessage = "Macro %s stopped." % macroName elif state == "step": shortMessage = "Macro %s at %d %% of progress." % (macroName, step) self.emit(Qt.SIGNAL("shortMessageEmitted"), shortMessage) self.tree.setProgressForMacro(id, step) def onDoorChanged(self, doorName): self.setDoorName(doorName) if self.doorName() == "": self.doorStateLed.setModel(None) return self.doorStateLed.setModel(self.doorName() + "/State") doorState = Device(doorName).state() if doorState == PyTango.DevState.ON: self.playSequenceAction.setText("Start sequence") self.playSequenceAction.setToolTip("Start sequence") self.playSequenceAction.setEnabled(False) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(False) elif doorState == PyTango.DevState.STANDBY: self.playSequenceAction.setText("Resume sequence") self.playSequenceAction.setToolTip("Resume sequence") self.playSequenceAction.setEnabled(True) self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(True) def setMacroParametersRootIndex(self, sourceIndex): parametersModel = self.standardMacroParametersEditor.tree.model() parametersModel.setMacroIndex(sourceIndex) parametersModel.invalidateFilter() proxyIndex = parametersModel.mapFromSource(sourceIndex) macroNode = sourceIndex.internalPointer() macroName = macroNode.name() if self.stackedWidget.count() == 2: self.stackedWidget.removeWidget(self.customMacroParametersEditor) self.customMacroParametersEditor.setParent(None) self.customMacroParametersEditor = ParamEditorManager().getMacroEditor(macroName) if self.customMacroParametersEditor: self.customMacroParametersEditor.setModel(parametersModel) self.customMacroParametersEditor.setRootIndex(proxyIndex) self.stackedWidget.addWidget(self.customMacroParametersEditor) self.stackedWidget.setCurrentWidget(self.customMacroParametersEditor) else: self.standardMacroParametersEditor.tree.setRootIndex(proxyIndex) self.standardMacroParametersEditor.tree.expandAll() def onMacroComboBoxChanged(self): macroName = str(self.macroComboBox.currentText()) if macroName == "": self.addMacroAction.setEnabled(False) else: self.addMacroAction.setEnabled(True) self.emit(Qt.SIGNAL("macroNameChanged"), macroName) def onAdd(self): macroName = str(self.macroComboBox.currentText()) macroNode = self.getModelObj().getMacroNodeObj(macroName) self.tree.addMacro(macroNode) self.saveSequenceAction.setEnabled(True) self.playSequenceAction.setEnabled(True) def isEmptySequence(self): return len(self.tree.root()) == 0 def isMacroSelected(self): return len(self.tree.selectedIndexes()) == 2 def emptySequence(self): self.tree.clearTree() self.disableButtons() self.emit(Qt.SIGNAL("currentMacroChanged"), None) self.emit(Qt.SIGNAL("sequenceEmpty")) def fromXmlString(self, xmlString): newRoot = self.tree.fromXmlString(xmlString) macroServerObj = self.getModelObj() for macroNode in newRoot.allMacros(): macroServerObj.fillMacroNodeAdditionalInfos(macroNode) return newRoot def fromPlainText(self, plainText): newRoot = self.tree.fromPlainText(plainText) macroServerObj = self.getModelObj() for macroNode in newRoot.allMacros(): macroServerObj.recreateMacroNodeAndFillAdditionalInfos(macroNode) return newRoot def setModel(self, model): oldModelObj = self.getModelObj() if oldModelObj is not None: self.disconnect(oldModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) TaurusWidget.setModel(self, model) newModelObj = self.getModelObj() self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) @classmethod def getQtDesignerPluginInfo(cls): return {'container': False, 'group': 'Taurus Sardana', 'module': 'taurus.qt.qtgui.extra_macroexecutor', 'icon': ':/designer/frame.png'} class TaurusSequencer(MacroExecutionWindow): def __init__(self, parent=None, designMode=False): MacroExecutionWindow.__init__(self) def initComponents(self): #@todo: take care about storing model self.setModelInConfig(True) self.taurusSequencerWidget = TaurusSequencerWidget(self) self.taurusSequencerWidget.setUseParentModel(True) self.registerConfigDelegate(self.taurusSequencerWidget) self.setCentralWidget(self.taurusSequencerWidget) self.connect(self.taurusSequencerWidget, Qt.SIGNAL('shortMessageEmitted'), self.onShortMessage) self.statusBar().showMessage("Sequencer ready") def setCustomMacroEditorPaths(self, customMacroEditorPaths): MacroExecutionWindow.setCustomMacroEditorPaths(self, customMacroEditorPaths) ParamEditorManager().parsePaths(customMacroEditorPaths) ParamEditorManager().browsePaths() def loadSettings(self): TaurusMainWindow.loadSettings(self) self.emit(Qt.SIGNAL("doorChanged"), self.doorName()) def onDoorChanged(self, doorName): MacroExecutionWindow.onDoorChanged(self, doorName) if self._qDoor: Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusSequencerWidget.onMacroStatusUpdated) if doorName == "": return self._qDoor = Device(doorName) Qt.QObject.connect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusSequencerWidget.onMacroStatusUpdated) self.taurusSequencerWidget.onDoorChanged(doorName) @classmethod def getQtDesignerPluginInfo(cls): return None def createSequencerWidget(args): sequencer = TaurusSequencerWidget() sequencer.setModelInConfig(True) Qt.QObject.connect(sequencer, Qt.SIGNAL("doorChanged"), sequencer.onDoorChanged) if len(args) == 2: sequencer.setModel(args[0]) sequencer.emit(Qt.SIGNAL('doorChanged'), args[1]) return sequencer def createSequencer(args): sequencer = TaurusSequencer() sequencer.setModelInConfig(True) Qt.QObject.connect(sequencer, Qt.SIGNAL("doorChanged"), sequencer.onDoorChanged) if len(args) == 2: sequencer.setModel(args[0]) sequencer.emit(Qt.SIGNAL('doorChanged'), args[1]) sequencer.loadSettings() return sequencer def main(): from taurus.qt.qtgui.application import TaurusApplication import taurus # from rfoo.utils import rconsole # rconsole.spawn_server() app = TaurusApplication(sys.argv, app_version=taurus.Release.version) args = app.get_command_line_args() app.setOrganizationName(globals.ORGANIZATION_NAME) app.setApplicationName(globals.SEQUENCER_APPLICATION_NAME) sequencer = createSequencer(args) sequencer.show() sys.exit(app.exec_()) if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/ui/0000755000234000017500000000000012555673001026756 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/ui/MacroButton.ui0000644000234000017500000000515412555672637031575 0ustar zreszelaComputing00000000000000 MacroButton 0 0 106 79 Form 0 0 QFrame::Box QFrame::Plain 3 3 0 0 0 0 PushButton true false 0 0 16777215 10 6 24 TaurusWidget QWidget
    taurus.qt.qtgui.container
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/__init__.py0000644000234000017500000000253712555672636030476 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ __init__.py: """ from .macroexecutor import TaurusMacroExecutorWidget, TaurusMacroExecutor from .sequenceeditor import TaurusSequencerWidget, TaurusSequencer from .common import TaurusMacroConfigurationDialog from .macrodescriptionviewer import TaurusMacroDescriptionViewer from .dooroutput import DoorOutput, DoorDebug, DoorResult from .macrobutton import MacroButton, MacroButtonAbortDoor sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/common.py0000644000234000017500000003320712555672636030225 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 PyTango import taurus from taurus.external.qt import Qt from taurus.core.taurusbasetypes import TaurusEventType from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.input import TaurusAttrListComboBox from taurus.qt.qtgui.container import TaurusMainWindow from taurus.qt.qtgui.resource import getThemeIcon def str2bool(text): return text in ("True", "1") def standardPlotablesFilter(column_desc_dict): """This is a standard plotables filter emitted with "plotablesFilter" signal. Its purpose is to filterout point_nr columnf from scanline""" if column_desc_dict.get("label", None) == "point_nb": return False return True class MSAttrListComboBox(TaurusAttrListComboBox): _elementType = '' def handleEvent(self, evt_src, evt_type, evt_value): if evt_type in (TaurusEventType.Config, TaurusEventType.Error): return text = str(self.currentText()) self.clear() parentModelObj = self.getParentModelObj() if parentModelObj == None: return items = parentModelObj.getElementNamesWithInterface(self._elementType) items.sort() self.addItems(items) if text in items: self.setCurrentText(text) def setCurrentText(self, text): idx = self.findText(text) self.setCurrentIndex(idx) def setElementType(self, elementType): self._elementType = elementType def getElementType(self): return self._elementType def resetElementType(self): self._elementType = MSAttrListComboBox._elementType elementType = Qt.pyqtProperty("QString", getElementType, setElementType, resetElementType) class MacroComboBox(Qt.QComboBox, TaurusBaseWidget): """ComboBox representing list of macros""" def __init__(self, parent=None): name = self.__class__.__name__ self.call__init__wo_kw(Qt.QComboBox, parent) self.call__init__(TaurusBaseWidget, name) self.setSizeAdjustPolicy(Qt.QComboBox.AdjustToContentsOnFirstShow) self.setToolTip("Choose a macro name...") def setModel(self, model): if isinstance(model, Qt.QAbstractItemModel): Qt.QAbstractItemView.setModel(self, model) else: TaurusBaseWidget.setModel(self, model) self.__loadMacroNames() def parentModelChanged(self, parentmodel_name): TaurusBaseWidget.parentModelChanged(self, parentmodel_name) self.__loadMacroNames() def onMacrosUpdated(self): self.__loadMacroNames() def __loadMacroNames(self): self.clear() ms = self.getModelObj() if ms == None: return macros = ms.getElementsWithInterface('MacroCode') macroNames = [macro.name for macro in macros.values()] macroNames.sort() macroNames.insert(0, '') #adding blank item self.addItems(macroNames) self.updateStyle() def selectMacro(self, macroName): currentIdx = self.currentIndex() index = self.findText(macroName) self.setCurrentIndex(index) if currentIdx == index: self.emit(Qt.SIGNAL("currentIndexChanged(QString)"), macroName) class TaurusMacroConfigurationDialog(Qt.QDialog): def __init__(self, parent=None, initMacroServer=None, initDoor=None): Qt.QDialog.__init__(self, parent) self.initMacroServer = initMacroServer self.initDoor = initDoor configureAction = Qt.QAction(getThemeIcon("folder-open"), "Change custom macro editors paths", self) self.connect(configureAction, Qt.SIGNAL("triggered()"), self.onReloadMacroServers) configureAction.setToolTip("Change custom macro editors paths") configureAction.setShortcut("F11") self.refreshMacroServersAction = Qt.QAction(getThemeIcon("view-refresh"), "Reload macroservers", self) self.connect(self.refreshMacroServersAction, Qt.SIGNAL("triggered()"), self.onReloadMacroServers) self.refreshMacroServersAction.setToolTip("This will reload list of all macroservers from Tango DB") self.refreshMacroServersAction.setShortcut("F5") self.initComponents() def initComponents(self): self.setModal(True) macroServerLabel = Qt.QLabel("MacroServer:", self) self.macroServerComboBox = Qt.QComboBox() ms_stateIcons = self.__retriveMacroServersFromDB() self.__fillMacroServerComboBox(ms_stateIcons, self.macroServerComboBox) refreshMacroServersButton = Qt.QToolButton() refreshMacroServersButton.setDefaultAction(self.refreshMacroServersAction) doorLabel = Qt.QLabel("Door:", self) self.doorComboBox = TaurusAttrListComboBox(self) self.doorComboBox.setModel(self.macroServerComboBox.currentText() + "/doorList") self.buttonBox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel) gridLayout = Qt.QGridLayout() gridLayout.addWidget(macroServerLabel, 0, 0) gridLayout.addWidget(self.macroServerComboBox, 0, 1) gridLayout.addWidget(refreshMacroServersButton, 0, 2) gridLayout.addWidget(doorLabel, 1, 0) gridLayout.addWidget(self.doorComboBox, 1, 1) self.setLayout(Qt.QVBoxLayout()) self.layout().addLayout(gridLayout) self.layout().addWidget(self.buttonBox) self.adjustSize() self.connect(self.buttonBox, Qt.SIGNAL("accepted()"), self, Qt.SLOT("accept()")) self.connect(self.buttonBox, Qt.SIGNAL("rejected()"), self, Qt.SLOT("reject()")) self.connect(self.macroServerComboBox, Qt.SIGNAL("currentIndexChanged(const QString&)"), self.onMacroServerComboBoxChanged) self.selectMacroServer(self.initMacroServer) self.selectDoor(self.initDoor) def accept(self): self.emit(Qt.SIGNAL("macroserverNameChanged"), str(self.macroServerComboBox.currentText())) self.emit(Qt.SIGNAL("doorNameChanged"), str(self.doorComboBox.currentText())) Qt.QDialog.accept(self) def __retriveMacroServersFromDB(self): ms_stateIcons = [] db = taurus.Database() macroServerList = db.getValueObj().get_device_name('*', 'MacroServer') for macroServer in macroServerList: #state = Device(macroServer).getState() state = None try: state = PyTango.DeviceProxy(macroServer).state() except: pass icon = None if state == PyTango.DevState.ON: icon = Qt.QIcon(":/leds/images24/ledgreen.png") elif state == PyTango.DevState.FAULT: icon = Qt.QIcon(":/leds/images24/ledred.png") elif state == None: icon = Qt.QIcon(":/leds/images24/ledredoff.png") ms_stateIcons.append((macroServer, icon)) return ms_stateIcons def onReloadMacroServers(self): ms_stateIcons = self.__retriveMacroServersFromDB() self.__fillMacroServerComboBox(ms_stateIcons, self.macroServerComboBox) def onMacroServerComboBoxChanged(self, macroServerName): self.doorComboBox.setModel(macroServerName + "/doorList") self.doorComboBox.fireEvent(self.doorComboBox, taurus.core.taurusbasetypes.TaurusEventType.Change, self.doorComboBox.getModelValueObj()) #fake event def onMacroServerNameChanged(self, macroServerName): self.__selectMacroServer(macroServerName) def onDoorNameChanged(self, doorName): self.__selectDoor(doorName) def __fillMacroServerComboBox(self, ms_stateIcons, comboBox): comboBox.clear() for ms_stateIcon in ms_stateIcons: macroServer = ms_stateIcon[0] icon = ms_stateIcon[1] comboBox.addItem(icon, macroServer) def selectDoor(self, doorName): if doorName is None: return #@todo: Change that it will be able to handle also full device names "/".join(doorName.split("/")[-3:]) index = self.doorComboBox.findText(doorName) if index != -1: self.doorComboBox.setCurrentIndex(index) def selectMacroServer(self, macroServerName): if macroServerName is None: return #@todo: Change that it will be able to handle also full device names "/".join(macroServerName.split("/")[-3:]) index = self.macroServerComboBox.findText(macroServerName) if index != -1: self.macroServerComboBox.setCurrentIndex(index) class MacroExecutionWindow(TaurusMainWindow): def __init__(self, parent=None, designMode=False): TaurusMainWindow.__init__(self, parent, designMode) self.statusBar().showMessage("") self.setModelInConfig(True) self._doorName = "" self.registerConfigProperty("doorName", "setDoorName", "doorName") self._customMacroEditorPaths = "" self.registerConfigProperty("customMacroEditorPaths", "setCustomMacroEditorPaths", "customMacroEditorPaths") self._qDoor = None self.setWindowIcon(Qt.QIcon(":/apps/preferences-system-session.svg")) toolBar = self.basicTaurusToolbar() toolBar.setIconSize(Qt.QSize(24, 24)) self.configureAction = self.createConfigureAction() toolBar.addAction(self.configureAction) self.taurusMenu.addAction(self.configureAction) self.customMacroEditorsPathsAction = self.createCustomMacroEditorPathsAction() self.taurusMenu.addAction(self.customMacroEditorsPathsAction) self.addToolBar(toolBar) self.initComponents() self.splashScreen().finish(self) self.connect(self, Qt.SIGNAL("doorChanged"), self.onDoorChanged) def doorName(self): return self._doorName def setDoorName(self, doorName): self._doorName = doorName def onDoorChanged(self, doorName): self.setDoorName(doorName) def customMacroEditorPaths(self): return self._customMacroEditorPaths def setCustomMacroEditorPaths(self, customMacroEditorPaths): self._customMacroEditorPaths = customMacroEditorPaths # ParamEditorManager().parsePaths(customMacroEditorPaths) # ParamEditorManager().browsePaths() def onCustomMacroEditorPaths(self): paths = str(Qt.QInputDialog.getText(self, "Edition of custom macro editors paths", "Paths:", Qt.QLineEdit.Normal, str(self.customMacroEditorPaths()))[0]) self.setCustomMacroEditorPaths(paths) def initComponents(self): pass def setModel(self, model): """Sets new model for application, and change window title witn new macroserver name.""" TaurusMainWindow.setModel(self, model) self.setWindowTitle(Qt.QApplication.applicationName() + ": " + model) def createConfigureAction(self): configureAction = Qt.QAction(getThemeIcon("preferences-system-session"), "Change configuration", self) self.connect(configureAction, Qt.SIGNAL("triggered()"), self.changeConfiguration) configureAction.setToolTip("Configuring MacroServer and Door") configureAction.setShortcut("F10") return configureAction def createCustomMacroEditorPathsAction(self): configureAction = Qt.QAction(getThemeIcon("folder-open"), "Change custom macro editors paths", self) self.connect(configureAction, Qt.SIGNAL("triggered()"), self.onCustomMacroEditorPaths) configureAction.setToolTip("Change custom macro editors paths") configureAction.setShortcut("F11") return configureAction def changeConfiguration(self): """This method is used to change macroserver as a model of application. It shows dialog with list of all macroservers on tango host, if the user Cancel dialog it doesn't do anything.""" dialog = TaurusMacroConfigurationDialog(self, self.modelName, self.doorName()) if dialog.exec_(): self.setModel(str(dialog.macroServerComboBox.currentText())) self.emit(Qt.SIGNAL("doorChanged"), str(dialog.doorComboBox.currentText())) else: return def onShortMessage(self, msg): ''' Slot to be called when there is a new short message. Currently, the only action taken when there is a new message is to display it in the main window status bar. :param msg: (str) the short descriptive message to be handled ''' self.statusBar().showMessage(msg) def test_macrocombobox(ms_name): mcb = MacroComboBox() mcb.setModel(ms_name) mcb.show() if __name__ == "__main__": import sys from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication() args = app.get_command_line_args() ms_name = args[0] test_macrocombobox(ms_name) sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/dooroutput.py0000644000234000017500000001613412555672636031161 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ dooroutput.py: """ import taurus.core from taurus.external.qt import Qt class DoorOutput(Qt.QPlainTextEdit): """Widget used for displaying changes of door's attributes: Output, Info, Warning and Error.""" def __init__(self, parent=None): Qt.QTextEdit.__init__(self, parent) self.setReadOnly(True) self.setFont(Qt.QFont("Courier", 9)) self.stopAction = Qt.QAction("Stop scrolling", self) self.stopAction.setCheckable(True) self.stopAction.setChecked(False) self._isStopped = False def onDoorOutputChanged(self, output): """call on output attribute changed""" txt = "" if output is None: return for line in output: txt += line.replace(' ', ' ') + "\n" txt += "" self.appendHtmlText(txt) def onDoorInfoChanged(self, info): """call on info attribute changed""" txt = "" if info is None: return for line in info: txt += line.replace(' ', ' ') + "\n" txt += "" self.appendHtmlText(txt) def onDoorWarningChanged(self, warning): """call on warning attribute changed""" txt = "" if warning is None: return for line in warning: txt += line.replace(' ', ' ') + "\n" txt += "" self.appendHtmlText(txt) def onDoorErrorChanged(self, error): """call on error attribute changed""" txt = "" if error is None: return for line in error: txt += line.replace(' ', ' ') + "\n" txt += "" self.appendHtmlText(txt) def appendHtmlText(self, text): self.appendHtml(text) if not self._isStopped: self.moveCursor(Qt.QTextCursor.End) def contextMenuEvent(self, event): menu = self.createStandardContextMenu() clearAction = Qt.QAction("Clear", menu) menu.addAction(clearAction) menu.addAction(self.stopAction) if not len(self.toPlainText()): clearAction.setEnabled(False) Qt.QObject.connect(clearAction, Qt.SIGNAL("triggered()"), self.clear) Qt.QObject.connect(self.stopAction, Qt.SIGNAL("toggled(bool)"), self.stopScrolling) menu.exec_(event.globalPos()) def stopScrolling(self, stop): self._isStopped = stop class DoorDebug(Qt.QPlainTextEdit): """Widget used for displaying changes of door's Debug attribute.""" def __init__(self, parent=None): Qt.QTextEdit.__init__(self, parent) self.setReadOnly(True) self.setFont(Qt.QFont("Courier", 9)) self.stopAction = Qt.QAction("Stop scrolling", self) self.stopAction.setCheckable(True) self.stopAction.setChecked(False) self._isStopped = False def onDoorDebugChanged(self, debug): """call on debug attribute changed""" if debug is None: return for line in debug: self.appendPlainText(line) if not self._isStopped: self.moveCursor(Qt.QTextCursor.End) def contextMenuEvent(self, event): menu = self.createStandardContextMenu() clearAction = Qt.QAction("Clear", menu) menu.addAction(clearAction) menu.addAction(self.stopAction) if not len(self.toPlainText()): clearAction.setEnabled(False) Qt.QObject.connect(clearAction, Qt.SIGNAL("triggered()"), self.clear) Qt.QObject.connect(self.stopAction, Qt.SIGNAL("toggled(bool)"), self.stopScrolling) menu.exec_(event.globalPos()) def stopScrolling(self, stop): self._isStopped = stop class DoorResult(Qt.QPlainTextEdit): """Widget used for displaying changes of door's Result attribute.""" def __init__(self, parent=None): Qt.QTextEdit.__init__(self, parent) self.setReadOnly(True) self.setFont(Qt.QFont("Courier", 9)) def onDoorResultChanged(self, result): """call on result attribute changed""" if result is None: return for line in result: self.appendPlainText(line) self.moveCursor(Qt.QTextCursor.End) def contextMenuEvent(self, event): menu = self.createStandardContextMenu() clearAction = Qt.QAction("Clear", menu) menu.addAction(clearAction) if not len(self.toPlainText()): clearAction.setEnabled(False) Qt.QObject.connect(clearAction, Qt.SIGNAL("triggered()"), self.clear) menu.exec_(event.globalPos()) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Door attributes listeners #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class DoorAttrListener(Qt.QObject): def __init__(self, attrName): Qt.QObject.__init__(self) self.attrName = attrName self.attrObj = None def setDoorName(self, doorName): if not self.attrObj is None: self.attrObj.removeListener(self) self.attrObj = taurus.Attribute(doorName, self.attrName) self.attrObj.addListener(self) def eventReceived(self, src, type, value): if (type == taurus.core.taurusbasetypes.TaurusEventType.Error or type == taurus.core.taurusbasetypes.TaurusEventType.Config): return self.emit(Qt.SIGNAL('door%sChanged' % self.attrName), value.value) if __name__ == "__main__": import sys import taurus from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv) args = app.get_command_line_args() doorOutput = DoorOutput() if len(args) == 1: door = taurus.Device(args[0]) Qt.QObject.connect(door, Qt.SIGNAL("outputUpdated"), doorOutput.onDoorOutputChanged) Qt.QObject.connect(door, Qt.SIGNAL("infoUpdated"), doorOutput.onDoorInfoChanged) Qt.QObject.connect(door, Qt.SIGNAL("warningUpdated"), doorOutput.onDoorWarningChanged) Qt.QObject.connect(door, Qt.SIGNAL("errorUpdated"), doorOutput.onDoorErrorChanged) doorOutput.show() sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/globals.py0000644000234000017500000001220312555672636030351 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ globals.py: """ ORGANIZATION_NAME = "Taurus" MACROEXECUTOR_APPLICATION_NAME = "macroexecutor" SEQUENCER_APPLICATION_NAME = "sequencer" SEQUENCES_DIRNAME = "Sequences" SEQUENCE_DEFAULT_FILENAME = "Untitled.xml" FAVOURITES_FILENAME = "favourite_macros.xml" MACROS_HISTORY_FILENAME = ".macros_history" MACROS_HISTORY_LENGHT = 5 TITLE_MACROSERVER_DIALOG = "Choose MacroServer" TITLE_OUTPUT_DOCK_WIDGET = "Output" TITLE_SPOCK_DOCK_WIDGET = "Spock" TITLE_DEBUG_DOCK_WIDGET = "Debug" TITLE_RESULT_DOCK_WIDGET = "Result" TITLE_DESCRIPTION_DOCK_WIDGET = "Macro description" TITLE_SEQUENCE_EDITOR_DOCK_WIDGET = "Sequence editor" TITLE_MACRO_EXECUTOR_DOCK_WIDGET = "Macro executor" MENU_FILE = "File" MENU_FILE_CONFIGURATION = "Configuration" MENU_FILE_NEW = "New" MENU_FILE_OPEN = "Open..." MENU_FILE_SAVE = "Save" MENU_FILE_SAVEAS = "Save as..." MENU_FILE_QUIT = "Quit" MENU_CONTROL = "Control" MENU_CONTROL_PLAY_SEQUENCE = "Play sequence" MENU_CONTROL_PLAY_MACRO = "Play macro" MENU_CONTROL_PAUSE = "Pause" MENU_CONTROL_STOP = "Stop" MENU_FAVOURITES = "Add to favourites" MENU_VIEW = "View" MENU_SETTINGS = "Settings" MENU_SETTINGS_ONLYSCANS = "Only scan macros" TIP_MENU_FILE_CONFIGURATION = "Configuration" TIP_MENU_FILE_QUIT = "Quit application" TIP_MENU_FILE_NEW = "New sequence" TIP_MENU_FILE_OPEN = "Open sequence..." TIP_MENU_FILE_SAVE = "Save sequence" TIP_MENU_FILE_SAVEAS = "Save sequence as..." TIP_MENU_CONTROL_PLAY_SEQUENCE = "Play sequence" TIP_MENU_CONTROL_PLAY_MACRO = "Play macro" TIP_MENU_CONTROL_PAUSE = "Pause" TIP_MENU_CONTROL_STOP = "Stop" TIP_MENU_FAVOURITES = "Add to favourites" SHORTCUT_MENU_FILE_CONFIGURATION = "F2" SHORTCUT_MENU_FILE_NEW = "Ctrl+N" SHORTCUT_MENU_FILE_OPEN = "Ctrl+O" SHORTCUT_MENU_FILE_SAVE = "Ctrl+S" SHORTCUT_MENU_FILE_SAVEAS = "Ctrl+Shift+S" SHORTCUT_MENU_FILE_QUIT = "Ctrl+Q" SCAN_MACROS_FILTER = "scan" ALLOWS_HOOKS_FILTER = 'allowsHooks' PARAM_REPEAT = "ParamRepeat" PARAM_OBJECT = "Object" PARAM_MOTOR = "Motor" PARAM_PSEUDOMOTOR = "PseudoMotor" PARAM_MOVEABLE = "Moveable" PARAM_CONTROLLER_CLASS = "ControllerClass" PARAM_CONTROLLER = "Controller" PARAM_MOTOR_PARAM = "MotorParam" PARAM_MEASUREMENT_GROUP = "MeasurementGroup" PARAM_IO_REGISTER = "IORegister" PARAM_COMMUNICATION_CHANNEL = "ComChannel" PARAM_EXPERIMENTAL_CHANNEL = "ExpChannel" PARAM_MACRO_CODE = "MacroCode" PARAM_MACRO_CLASS = "MacroClass" PARAM_MACRO_FUNCTION = "MacroFunction" PARAM_MACRO_LIBRARY = "MacroLibrary" PARAM_STRING = "String" PARAM_FILENAME = "FileName" PARAM_FILENAME_2 = "Filename" PARAM_INTEGER = "Integer" PARAM_FLOAT = "Float" PARAM_FILEDIALOG = "File" PARAM_USERNAME = "User" PARAM_BOOLEAN = "Boolean" MAX_REPEATS = "max" MIN_REPEATS = "min" EDITOR_COMBOBOX_PARAMS = [PARAM_OBJECT, PARAM_MOTOR, PARAM_PSEUDOMOTOR, PARAM_MOVEABLE, PARAM_CONTROLLER_CLASS, PARAM_CONTROLLER, PARAM_MOTOR_PARAM, PARAM_MEASUREMENT_GROUP, PARAM_IO_REGISTER, PARAM_COMMUNICATION_CHANNEL, PARAM_EXPERIMENTAL_CHANNEL, PARAM_MACRO_CODE, PARAM_MACRO_CLASS, PARAM_MACRO_FUNCTION, PARAM_MACRO_LIBRARY] EDITOR_LINEEDIT_PARAMS = [PARAM_STRING, PARAM_FILENAME, PARAM_FILENAME_2, "Env"] EDITOR_SPINBOX_PARAMS = [PARAM_INTEGER] EDITOR_DOUBLESPINBOX_PARAMS = [PARAM_FLOAT] EDITOR_FILEDIALOG_PARAMS = [PARAM_FILEDIALOG] EDITOR_BOOLEAN_PARAMS = [PARAM_BOOLEAN] EDITOR_NONEDITABLE_PARAMS = [PARAM_USERNAME] TAG_MACRO = 'macro' TAG_PARAM = 'param' TAG_PARAMREPEAT = 'paramrepeat' TAG_REPEAT = 'repeat' TAG_PARAMS = 'params' TAG_SEQUENCE = 'sequence' TAG_ALLOWED_HOOK = 'allowedHook' TAG_HOOK = 'hookPlaces' 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' ATTRIBUTE_MAX = 'max' sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrobutton.py0000644000234000017500000003631312555672636031273 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 a button for executing macros """ __all__ = ['MacroButton'] import functools import uuid import PyTango import taurus from taurus.core import TaurusEventType, TaurusDevice from taurus.external.qt import Qt from taurus.qt.qtgui.container import TaurusWidget from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.button import TaurusCommandButton from taurus.qt.qtgui.dialog import ProtectTaurusMessageBox from taurus.core.util.colors import DEVICE_STATE_PALETTE from taurus.qt.qtgui.util.ui import UILoadable class DoorStateListener(Qt.QObject): '''A listener of Change and periodic events from a Door State attribute. It converts the received Tango events and emits a Qt signal ''' __pyqtSignals__ = ["doorStateChanged"] def eventReceived(self, evt_src, evt_type, evt_value): if evt_type not in (TaurusEventType.Change, TaurusEventType.Periodic): return door_state = evt_value.value self.emit(Qt.SIGNAL('doorStateChanged'), door_state) @UILoadable(with_ui='ui') class MacroButton(TaurusWidget): ''' A button to execute/pause/stop macros. The model must be a valid door. .. todo:: Not implemented but will be needed: set an icon .. todo:: It may be useful to have all the streams from qdoor available somehow (right-click?) ''' __pyqtSignals__ = ['statusUpdated', 'resultUpdated'] def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.loadUi() self.door = None self.door_state_listener = None self.macro_name = '' self.macro_args = [] self.macro_id = None self.running_macro = None self.ui.progress.setValue(0) self.ui.button.setCheckable(True) self.connect(self.ui.button, Qt.SIGNAL('clicked()'), self._onButtonClicked) def toggleProgress(self, visible): '''deprecated''' self.warning('toggleProgress is deprecated. Use showProgress') self.showProgress(visible) def showProgress(self, visible): '''Set whether the progress bar is shown :param visible: (bool) If True, the progress bar is shown. Otherwise it is hidden''' self.ui.progress.setVisible(visible) def setModel(self, model): ''' reimplemented from :class:`TaurusWidget`. A door device name is expected as the model ''' TaurusWidget.setModel(self, model) if self.door is not None: self.disconnect(self.door, Qt.SIGNAL('macroStatusUpdated'), self._statusUpdated) self.disconnect(self.door, Qt.SIGNAL('resultUpdated'), self._resultUpdated) # disable management of Door Tango States self.door.getAttribute('State').removeListener(self.door_state_listener) self.disconnect(self.door_state_listener, Qt.SIGNAL('doorStateChanged'), self._doorStateChanged) self.door_state_listener = None try: self.door = taurus.Device(model) except: return self.connect(self.door, Qt.SIGNAL('macroStatusUpdated'), self._statusUpdated) self.connect(self.door, Qt.SIGNAL('resultUpdated'), self._resultUpdated) # Manage Door Tango States self.door_state_listener = DoorStateListener() self.connect(self.door_state_listener, Qt.SIGNAL('doorStateChanged'), self._doorStateChanged) self.door.getAttribute('State').addListener(self.door_state_listener) def _doorStateChanged(self, state): '''slot called on door state changes''' color = '#' + DEVICE_STATE_PALETTE.hex(state) stylesheet = 'QFrame{border: 4px solid %s;}' % color self.ui.frame.setStyleSheet(stylesheet) # In case state is not ON, and macro not triggered by the button, disable it door_available = True if state not in [PyTango.DevState.ON, PyTango.DevState.ALARM] and not self.ui.button.isChecked(): door_available = False self.ui.button.setEnabled(door_available) self.ui.progress.setEnabled(door_available) def _statusUpdated(self, *args): '''slot called on status changes''' # SHOULD SEE THE DOCUMENTATION ABOUT THE ARGS AND ALSO THE STATUS STATE MACHINE # ARGS FORMAT IS (GUESSING WITH PRINT STATEMENTS) # e.g. ((, [{u'step': 100.0, u'state': u'stop', u'range': [0.0, 100.0], u'id': u'b226f5e8-c807-11e0-8abe-001d0969db5b'}]),) # ( (MacroObj, [status_dict, .?.]), .?.) # QUESTIONS: THIS MACRO OBJECT HAS ALOS STEP, RANGE, ... # AND ALSO THE STATUS DICT... WHICH SHOULD I USE? first_tuple = args[0] self.running_macro = first_tuple[0] status_dict = first_tuple[1][0] # KEYS RECEIVED FROM A 'SCAN' MACRO AND A 'TWICE' MACRO: IS IT GENERAL ?!?!?! macro_id = status_dict['id'] # if macro id is unknown ignoring this signal if macro_id is None: return # check if we have launch this macro, otherwise ignore the signal if macro_id != str(self.macro_id): return state = status_dict['state'] step = status_dict['step'] step_range = status_dict['range'] # Update progress bar self.ui.progress.setMinimum(step_range[0]) self.ui.progress.setMaximum(step_range[1]) self.ui.progress.setValue(step) if state in ['stop', 'abort', 'finish', 'alarm']: self.ui.button.setChecked(False) self.emit(Qt.SIGNAL('statusUpdated'), status_dict) def _resultUpdated(self, *args): '''slot called on result changes''' # ARGS APPEAR TO BE EMPTY... SHOULD THEY CONTAIN THE RESULT ?!?!?! # I have to rely on the 'macro object' received in the last status update if self.running_macro is None: return result = self.running_macro.getResult() self.emit(Qt.SIGNAL('resultUpdated'), result) def setText(self, text): '''set the button text :param text: (str) text for the button ''' self.setButtonText(text) def setButtonText(self, text): '''same as :meth:`setText` ''' # SHOULD ALSO BE POSSIBLE TO SET AN ICON self.ui.button.setText(text) def setMacroName(self, name): '''set the name of the macro to be executed :param name: (str) text for the button ''' self.macro_name = str(name) def updateMacroArgument(self, index, value): '''change a given argument :param index: (int) positional index for this argument :param value: (str) value for this argument ''' #make sure that the macro_args is at least as long as index while len(self.macro_args) < index + 1: self.macro_args.append('') #update the given argument self.macro_args[index] = str(value) def updateMacroArgumentFromSignal(self, index, obj, signal): '''deprecated''' msg = 'updateMacroArgumentFromSignal is deprecated. connectArgEditors' self.warning(msg) self.connect(obj, signal, functools.partial(self.updateMacroArgument, index)) def connectArgEditors(self, signals): '''Associate signals to argument changes. :param signals: (seq) An ordered sequence of (`obj`, `sig`) tuples , where `obj` is a parameter editor object and `sig` is a signature for a signal emitted by `obj` which provides the value of a parameter as its argument. Each (`obj`, `sig`) tuple is associated to parameter corresponding to its position in the `signals` sequence. ''' for i,(obj,sig) in enumerate(signals): self.connect(obj, Qt.SIGNAL(sig), functools.partial(self.updateMacroArgument, i)) def _onButtonClicked(self): if self.ui.button.isChecked(): self.runMacro() else: self.abort() @ProtectTaurusMessageBox(msg='Error while executing the macro.') def runMacro(self): '''execute the macro with the current arguments''' if self.door is None: return # Thanks to gjover for the hint... :-D #macro_cmd = self.macro_name + ' ' + ' '.join(self.macro_args) self.macro_id = uuid.uuid1() macro_cmd_xml = '\n' % \ (self.macro_name, self.macro_id) for arg in self.macro_args: macro_cmd_xml += '\n' % arg macro_cmd_xml += '' try: #self.door.runMacro(macro_cmd) self.door.runMacro(macro_cmd_xml) except Exception, e: self.ui.button.setChecked(False) raise e def abort(self): '''abort the macro.''' if self.door is None: return self.door.PauseMacro() # Since this could be done by error (impatient users clicking more than once) # we provide a warning message that does not make the process too slow # It may also be useful and 'ABORT' at TaurusApplication level (macros+motions+acquisitions) title = 'Aborting macro' message = 'The following macro is still running:\n\n' message += '%s %s\n\n' % (self.macro_name, ' '.join(self.macro_args)) message += 'Are you sure you want to abort?\n' buttons = Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel ans = Qt.QMessageBox.warning(self, title, message, buttons, Qt.QMessageBox.Ok) if ans == Qt.QMessageBox.Ok: self.door.abort(synch=True) else: self.ui.button.setChecked(True) self.door.ResumeMacro() @classmethod def getQtDesignerPluginInfo(cls): '''reimplemented from :class:`TaurusWidget`''' return {'container': False, 'group': 'Taurus Sardana', 'module': 'taurus.qt.qtgui.extra_macroexecutor', 'icon': ':/designer/pushbutton.png'} class MacroButtonAbortDoor(Qt.QPushButton, TaurusBaseWidget): '''Deprecated class. Instead use TaurusCommandButton. A button for aborting macros on a door ''' #todo: why not inheriting from (TaurusBaseComponent, Qt.QPushButton)? def __init__(self, parent=None, designMode=False): name = self.__class__.__name__ self.call__init__wo_kw(Qt.QPushButton, parent) self.call__init__(TaurusBaseWidget, name, designMode=designMode) self.warning('Deprecation warning: use TaurusCommandButton class ' +\ 'instead of MacroButtonAbortDoor') self.setText('Abort') self.setToolTip('Abort Macro') self.connect(self, Qt.SIGNAL('clicked()'), self.abort) def getModelClass(self): '''reimplemented from :class:`TaurusBaseWidget`''' return TaurusDevice @ProtectTaurusMessageBox(msg='An error occurred trying to abort the macro.') def abort(self): '''stops macros''' door = self.getModelObj() if door is not None: door.stopMacro() if __name__ == '__main__': import sys from taurus.qt.qtgui.application import TaurusApplication from taurus.core.util.argparse import get_taurus_parser from sardana.macroserver.macros.test import SarDemoEnv parser = get_taurus_parser() parser.set_usage("python macrobutton.py [door_name]") parser.set_description("Macro button for macro execution") app = TaurusApplication(app_name="macrobutton", app_version=taurus.Release.version) args = app.get_command_line_args() if len(args) < 1: parser.print_help(sys.stderr) sys.exit(1) door_name = args[0] w = Qt.QWidget() w.setLayout(Qt.QGridLayout()) col = 0 w.layout().addWidget(Qt.QLabel('macro name'), 0, col) macro_name = Qt.QLineEdit() w.layout().addWidget(macro_name, 1, col) _argEditors = [] for a in range(5): col += 1 w.layout().addWidget(Qt.QLabel('arg%d' % a), 0, col) argEdit = Qt.QLineEdit() w.layout().addWidget(argEdit, 1, col) _argEditors.append(argEdit) from sardana.taurus.qt.qtcore.tango.sardana.macroserver import registerExtensions registerExtensions() mb = MacroButton() mb.setModel(door_name) w.layout().addWidget(mb, 2, 0, 2, 7) w.layout().addWidget(Qt.QLabel('Result:'), 4, 0) result_label = Qt.QLabel() w.layout().addWidget(result_label, 4, 1, 1, 5) show_progress = Qt.QCheckBox('Progress') show_progress.setChecked(True) w.layout().addWidget(show_progress, 5, 0) mb_abort = TaurusCommandButton(command = 'StopMacro', icon=':/actions/media_playback_stop.svg') mb_abort.setModel(door_name) w.layout().addWidget(mb_abort, 5, 1) # Change macro name Qt.QObject.connect(macro_name, Qt.SIGNAL('textChanged(QString)'), mb.setMacroName) Qt.QObject.connect(macro_name, Qt.SIGNAL('textChanged(QString)'), mb.setButtonText) # connect the argument editors signals = [(e, 'textChanged(QString)') for e in _argEditors] mb.connectArgEditors(signals) def update_result(result): result_label.setText(str(result)) def toggle_progress(showProgress): visible = show_progress.isChecked() mb.toggleProgress(visible) # Toggle progressbar Qt.QObject.connect(show_progress, Qt.SIGNAL('stateChanged(int)'), toggle_progress) # Update possible macro result Qt.QObject.connect(mb, Qt.SIGNAL('resultUpdated'), update_result) # Obtain a demo motor try: demo_motor_name = SarDemoEnv(door_name).getMotors()[0] except Exception, e: from taurus.core.util.log import warning, debug warning('It was unable to obtain a demo motor') debug('Details: %s' % e.message) demo_motor_name = '' # Since everything is now connected, the parameters will be updated macro_name.setText('ascan') macro_params = [demo_motor_name, '0', '1', '5', '.1'] for e,v in zip(_argEditors, macro_params): e.setText(v) w.show() sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrodescriptionviewer.py0000644000234000017500000000667512555672636033535 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ macrodescriptionviewer.py: """ import taurus.core from taurus.external.qt import Qt from taurus.qt.qtgui.base import TaurusBaseWidget class TaurusMacroDescriptionViewer(Qt.QTextEdit, TaurusBaseWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): name = "TaurusMacroDescriptionView" self.call__init__wo_kw(Qt.QTextEdit, parent) self.call__init__(TaurusBaseWidget, name) self.setReadOnly(True) self.setFont(Qt.QFont("Courier", 9)) def defineStyle(self): """ Defines the initial style for the widget """ self.updateStyle() def getModelClass(self): return taurus.core.taurusdevice.TaurusDevice def updateStyle(self): self.update() def onMacroNameChanged(self, macroName): """Can be connected to an event emitted after macro name was changed. As an argument receives macroName and ask BaseMacroServer object about already prepared and stored in MacroInfoObj object macro description""" macroServer = self.getModelObj() if macroServer is None or macroName is None or macroName == "": self.setText("") return self.setText(str(macroServer.getMacroInfoObj(macroName).doc)) def getFormatedToolTip(self, cache=True): """This method was overridden to get rid of the default tooltip of TaurusWidget""" return "" model = Qt.pyqtProperty("QString", TaurusBaseWidget.getModel, TaurusBaseWidget.setModel, TaurusBaseWidget.resetModel) useParentModel = Qt.pyqtProperty("bool", TaurusBaseWidget.getUseParentModel, TaurusBaseWidget.setUseParentModel, TaurusBaseWidget.resetUseParentModel) def test(): import sys from sardana.taurus.core.tango.sardana.macroserver import registerExtensions registerExtensions() app = Qt.QApplication(sys.argv) taurusMacroDescriptionView = TaurusMacroDescriptionViewer(designMode=1) if len(sys.argv) != 2: taurusMacroDescriptionView.setModel("macroserver/zreszela/1") else: taurusMacroDescriptionView.setModel(sys.argv[1]) taurusMacroDescriptionView.onMacroChanged("mv") taurusMacroDescriptionView.show() sys.exit(app.exec_()) if __name__ == "__main__": test() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroeditor.py0000644000234000017500000002140212555672636031237 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus.external.qt import Qt from PyQt4 import Qsci from taurus.qt.qtgui.resource import getThemeIcon class MacroEditor(Qsci.QsciScintilla): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): Qsci.QsciScintilla.__init__(self, parent) self.textEdit = Qsci.QsciScintilla() self.textEdit.setAutoCompletionThreshold(1) self.textEdit.setAutoCompletionSource(Qsci.QsciScintilla.AcsAll) self.textEdit.setAutoIndent(True) self.textEdit.setCallTipsStyle(Qsci.QsciScintilla.CallTipsContext) self.textEdit.setCallTipsVisible(0) self.pythonLexer = Qsci.QsciLexerPython(self.textEdit) self.api = Qsci.QsciAPIs(self.pythonLexer) self.api.add(Qt.QString("dupa(a,b)this is function dupa")) self.api.prepare() self.pythonLexer.setAPIs(self.api) self.textEdit.setLexer(self.pythonLexer) self.newAction = Qt.QAction(getThemeIcon("document-new"), "New", self) self.connect(self.newAction, Qt.SIGNAL("triggered()"), self.newFile) self.newAction.setToolTip("Create new file") self.newAction.setShortcut("Ctrl+N") self.openAction = Qt.QAction(getThemeIcon("document-open"), "Open", self) self.connect(self.openAction, Qt.SIGNAL("triggered()"), self.openFile) self.openAction.setToolTip("Open existing file") self.openAction.setShortcut("Ctrl+O") self.saveAction = Qt.QAction(getThemeIcon("document-save"), "Save", self) self.connect(self.saveAction, Qt.SIGNAL("triggered()"), self.saveFile) self.saveAction.setToolTip("Save document to disk") self.saveAction.setShortcut("Ctrl+S") self.saveAsAction = Qt.QAction(getThemeIcon("document-save-as"), "Save as...", self) self.connect(self.saveAsAction, Qt.SIGNAL("triggered()"), self.saveFile) self.saveAsAction.setToolTip("Save document under a new name") self.cutAction = Qt.QAction(getThemeIcon("edit-cut"), "Cut", self) self.connect(self.cutAction, Qt.SIGNAL("triggered()"), self.cut) self.cutAction.setToolTip("Cut current selection's contents to the clipboard") self.cutAction.setShortcut("Ctrl+X") self.cutAction.setEnabled(False) self.copyAction = Qt.QAction(getThemeIcon("edit-copy"), "Copy", self) self.connect(self.copyAction, Qt.SIGNAL("triggered()"), self.copy) self.copyAction.setToolTip("Copy current selection's contents to the clipboard") self.copyAction.setShortcut("Ctrl+C") self.copyAction.setEnabled(False) self.pasteAction = Qt.QAction(getThemeIcon("edit-paste"), "Paste", self) self.connect(self.pasteAction, Qt.SIGNAL("triggered()"), self.paste) self.pasteAction.setToolTip("Paste the clipboard's contents into the current selection") self.pasteAction.setShortcut("Ctrl+V") self.aboutAction = Qt.QAction("About", self) self.connect(self.aboutAction, Qt.SIGNAL("triggered()"), self.about) self.aboutAction.setToolTip("Show the application's About box") self.connect(self.textEdit, Qt.SIGNAL("copyAvailable(bool)"), self.cutAction.setEnabled) self.connect(self.textEdit, Qt.SIGNAL("copyAvailable(bool)"), self.copyAction.setEnabled) self.setCurrentFile("") def closeEvent(self, event): if self.maybeSave(): # self.writeSettings() event.accept() else: event.ignore() def newFile(self): if self.maybeSave(): self.textEdit.clear() self.setCurrentFile("") def openFile(self): if self.maybeSave(): fileName = Qt.QFileDialog.getOpenFileName(self) if not fileName is None and file != "": self.loadFile(fileName) def saveFile(self): if self.curFile == "": return self.__saveAs() else: return self.__saveFile(self.curFile) def __saveAs(self): self.fileName = Qt.QFileDialog.getSaveFileName(self) if self.fileName == "": return False return self.__saveFile(self.fileName) def about(self): Qt.QMessageBox.about(self, "About MacroEditor", "The MacroEditor by Zbigniew Reszela") def documentWasModified(self): self.setWindowModified(self.textEdit.isModified()) def createMenus(self): fileMenu = self.menuBar().addMenu("File") fileMenu.addAction(self.newAction) fileMenu.addAction(self.openAction) fileMenu.addAction(self.saveAction) fileMenu.addAction(self.saveAsAction) editMenu = self.menuBar().addMenu("Edit") editMenu.addAction(self.cutAction) editMenu.addAction(self.copyAction) editMenu.addAction(self.pasteAction) self.menuBar().addSeparator() helpMenu = self.menuBar().addMenu("&Help") helpMenu.addAction(self.aboutAction) # def createToolBars(self): # fileToolBar = self.addToolBar("File") # fileToolBar.setIconSize(Qt.QSize(36,36)) # fileToolBar.addAction(self.newAction) # fileToolBar.addAction(self.openAction) # fileToolBar.addAction(self.saveAction) # fileToolBar.addAction(self.saveAsAction) # # editToolBar = self.addToolBar("Edit") # editToolBar.setIconSize(Qt.QSize(36,36)) # editToolBar.addAction(self.cutAction) # editToolBar.addAction(self.copyAction) # editToolBar.addAction(self.pasteAction) def createStatusBar(self): self.statusBar().showMessage("Ready") def maybeSave(self): if self.textEdit.isModified(): ret = Qt.QMessageBox.warning(self, "MacroEditor", "The document has been modified\nDo you want to save your changes?", Qt.QMessageBox.Yes | Qt.QMessageBox.Default, Qt.QMessageBox.No, Qt.QMessageBox.Cancel | Qt.QMessageBox.Escape) if ret == Qt.QMessageBox.Yes: return self.save() elif ret == Qt.QMessageBox.Cancel: return False return True def loadFile(self, fileName): try: fileHandle = open(fileName, 'r') except IOError, e: Qt.QMessageBox.warning(self, "MacroEditor", "Cannot read file %s:\n%s." % (fileName, e)) return False fileContents = fileHandle.read() Qt.QApplication.setOverrideCursor(Qt.Qt.WaitCursor) self.textEdit.setText(fileContents) Qt.QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File loaded", 2000) def __saveFile(self, fileName): try: file = open(fileName, 'w') except IOError, e: Qt.QMessageBox.warning(self, "MacroEditor", "Cannot write file %s:\n%s." % (fileName, e)) return False Qt.QApplication.setOverrideCursor(Qt.Qt.WaitCursor) file.write(self.textEdit.text()) Qt.QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage(("File saved"), 2000) return True def setCurrentFile(self, fileName): self.curFile = fileName self.textEdit.setModified(False) self.setWindowModified(False) if self.curFile == "": shownName = "untitled.txt" else: shownName = self.strippedName(self.curFile) self.setWindowTitle("%s[*] - %s" % (shownName, "MacroExecutor")) def strippedName(self, fullFileName): return Qt.QFileInfo(fullFileName).fileName() def cut(self): pass def copy(self): pass def paste(self): pass def test(): import sys app = Qt.QApplication(sys.argv) macroEditor = MacroEditor() macroEditor.show() sys.exit(app.exec_()) if __name__ == "__main__": test() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py0000644000234000017500000012332712555672636031620 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ sequenceeditor.py: """ import sys from copy import deepcopy import PyTango from taurus.external.qt import Qt from taurus import Device from taurus.qt.qtgui.container import TaurusWidget, TaurusMainWindow, TaurusBaseContainer from taurus.qt.qtgui.display import TaurusLed from taurus.qt.qtgui.dialog import TaurusMessageBox from taurus.qt.qtgui.resource import getIcon, getThemeIcon from sardana.taurus.core.tango.sardana import macro from sardana.taurus.core.tango.sardana.macro import MacroRunException from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor import ParamEditorManager, ParamEditorModel, StandardMacroParametersEditor from .favouriteseditor import FavouritesMacrosEditor, HistoryMacrosViewer from .common import MacroComboBox, MacroExecutionWindow, standardPlotablesFilter class MacroProgressBar(Qt.QProgressBar): def __init__(self, parent=None): Qt.QProgressBar.__init__(self, parent) class SpockCommandWidget(Qt.QLineEdit, TaurusBaseContainer): def __init__(self, name, parent=None, designMode=False): #self.newValue - is used as a flag to indicate whether a controlUp controlDown actions are used to iterate existing element or put new one #self.disableEditMode - flag, used to disable edition, when user enters name of the macro which is not valid (not allowed to edit in the yellow line) # switches off validation #disableSpockCommandUpdate - flag, it disables updates of the model when macro is edited by macroEditor Qt.QLineEdit.__init__(self, parent) TaurusBaseContainer.__init__(self, name, parent, designMode) self._model = None self.setFont(Qt.QFont("Courier", 9)) palette = Qt.QPalette() palette.setColor(Qt.QPalette.Base, Qt.QColor('yellow')) self.setPalette(palette) self.currentIndex = Qt.QModelIndex() self.newValue = False self.disableSpockCommandUpdate = False self.disableEditMode = True self.setEnabled(False) self.setActions() self.connect(self, Qt.SIGNAL("textChanged(const QString &)"), self.textChanged) self.connect(self, Qt.SIGNAL("returnPressed()"), self.returnPressed) def setActions(self): self._downAction = Qt.QAction("downAction", self) self._upAction = Qt.QAction("upAction", self) self._ctrlDownAction = Qt.QAction("controlDownAction", self) self._ctrlUpAction = Qt.QAction("controlUpAction", self) self._ctrlDownAction.setShortcut(Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Down)) self._ctrlUpAction.setShortcut(Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Up)) self._downAction.setShortcuts([Qt.Qt.Key_Down]) self._upAction.setShortcuts([Qt.Qt.Key_Up]) self._ctrlDownAction.setShortcutContext (Qt.Qt.WidgetShortcut) self._ctrlUpAction.setShortcutContext (Qt.Qt.WidgetShortcut) self._downAction.setShortcutContext (Qt.Qt.WidgetShortcut) self._upAction.setShortcutContext (Qt.Qt.WidgetShortcut) self.addAction(self._ctrlDownAction) self.addAction(self._ctrlUpAction) self.addAction(self._downAction) self.addAction(self._upAction) self.connect(self._downAction, Qt.SIGNAL("triggered()"), self.downAction) self.connect(self._upAction, Qt.SIGNAL("triggered()"), self.upAction) self.connect(self._ctrlDownAction, Qt.SIGNAL("triggered()"), self.controlDownAction) self.connect(self._ctrlUpAction, Qt.SIGNAL("triggered()"), self.controlUpAction) def setCommand(self): command = self._model.toSpockCommand() command = command.replace("None", "").strip() if not self.disableSpockCommandUpdate: self.setText(command) def setModel(self, model): enable = bool(model) self.disableEditMode = not enable self.setEnabled(enable) self._model = model self.connect(self._model, Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.setCommand) self.connect(self._model, Qt.SIGNAL("modelReset()"), self.setCommand) def model(self): return self._model def getIndex(self, elementNumber=-1): #Returns QModelIndex of the required element (number of single parameter). If the elementNumber == -1 next single parameter index is returned. if elementNumber == -1: ix = self.currentIndex elementNumber = 1 elif elementNumber == 0: return Qt.QModelIndex() else: ix = Qt.QModelIndex() (col, row, parentIdx) = (ix.column(), ix.row(), ix.parent()) #to start from second column if col == -1 and row == -1: ix = self.forwardIdx(0, 1, ix) for i in range (0, elementNumber): #This condition in case we start tabbing with cursor on first column if col == 0: currentNode = self.model().nodeFromIndex(ix) if isinstance(currentNode, macro.SingleParamNode): nextIdx = self.forwardIdx(row, 1, parentIdx) else: nextIdx = self.forwardIdx(0, 1, ix) else: nextIdx = self.forwardIdx(row + 1, 1, parentIdx) #this condition in case there is no next index and we want to pass focus #to next widget in parent obj if nextIdx == "term": return Qt.QModelIndex() ix = nextIdx (col, row, parentIdx) = (ix.column(), ix.row(), ix.parent()) return ix def forwardIdx(self, row, col, parentIdx): #This method is moving down the tree to get next SingleParamNode index. try: proposalIdx = self.model().index(row, col, parentIdx) except AssertionError: if parentIdx.row() == -1: return Qt.QModelIndex() grandParentIdx = parentIdx.parent() return self.forwardIdx(parentIdx.row() + 1, col, grandParentIdx) proposalNode = self.model().nodeFromIndex(proposalIdx) if isinstance(proposalNode, macro.SingleParamNode): return proposalIdx elif isinstance(proposalNode, macro.RepeatNode): return self.forwardIdx(0, 1, proposalIdx) elif isinstance(proposalNode, macro.RepeatParamNode): if len(proposalNode) > 0: return self.forwardIdx(0, 1, proposalIdx) else: return self.forwardIdx(row + 1, col, proposalIdx) elif not proposalIdx.isValid(): proposalIdx = parentIdx.sibling(parentIdx.row() + 1, 0) if proposalIdx.isValid(): proposalIdx = proposalIdx.child(0, 1) else: while not proposalIdx.isValid(): parentIdx = parentIdx.parent() if not parentIdx.isValid(): return Qt.QModelIndex() proposalIdx = parentIdx.sibling(parentIdx.row() + 1, 1) return proposalIdx def validateAllExpresion(self, secValidation=False): #This method is responsible for full validation of the macro. It is executed whenever the text is changed (when user edits values). #Validation starts with checking if the macro (name) is valid. #Next steps: #1. Validates every SingleParamNode and counts how many there are in the macro. #2. If there are more SingleParamNodes than entered values it will check if there is RepeatParamNode. # If there is RepeatParamNode it will check if its RepeatNodes can be deleted. #3. If there are more values entered than SingleParamNodes in macro it will check if there is RepeatParamNode. # If there is it will try to add new RepeatNode. if self.model() is None: raise RuntimeError('Door must be set in order to use the macroexecutor.') self.currentIndex = Qt.QModelIndex() mlist = str(self.text()).split() problems = [] try: if str(mlist[0]) != str(self.model().root().name()): try: self.getModelObj().validateMacroName(str(mlist[0])) self.validateMacro(mlist[0]) self.updateMacroEditor(mlist[0]) if not secValidation: self.validateAllExpresion(True) except Exception as e: if self.disableEditMode: self.updateMacroEditor(mlist[0]) raise Exception(e) message = e[0] #raise Exception(e) problems.append(message) except IndexError: problems.append("Macro<\b> is missing!") self.setStyleSheet("") self.setToolTip('
    '.join(problems)) return self.currentIndex = Qt.QModelIndex() ix = self.getIndex() self.currentIndex = ix counter = 1 while not ix == Qt.QModelIndex(): try: propValue = mlist[counter] try: self.validateOneValue(propValue) self.model().setData(self.currentIndex, Qt.QVariant(propValue)) except Exception as e: self.model().setData(self.currentIndex, Qt.QVariant('None')) txt = str(Qt.from_qvariant(ix.sibling(ix.row(), 0).data(), str)) message = "" + txt + " " + e[0] problems.append(message) except IndexError: txt = str(Qt.from_qvariant(ix.sibling(ix.row(), 0).data(), str)) problems.append("" + txt + " is missing!") data = str(Qt.from_qvariant(ix.data(), str)) if data != 'None': self.model().setData(self.currentIndex, Qt.QVariant('None')) counter += 1 ix = self.getIndex() self.currentIndex = ix if len(mlist) > counter: #if there are more values than parameters repeatNode = None for i in self.model().root().params(): repeatNode = i if isinstance(repeatNode, macro.RepeatParamNode): index = self.findParamRepeat(i) self.currentIndex = self.model()._insertRow(index) nn = self.model().nodeFromIndex(self.currentIndex) self.emit(Qt.SIGNAL("expandTree")) ix = self.getIndex() if not secValidation: self.validateAllExpresion(True) return repeatNode = None if repeatNode == None: problems.append("Too many values.") elif counter - len(mlist) >= 1: repeatNode = None node = None for i in self.model().root().params(): repeatNode = i if isinstance(repeatNode, macro.RepeatParamNode): index = self.findParamRepeat(i) node = self.model().nodeFromIndex(index) sub = len(node.child(0)) break repeatNode = None if repeatNode is not None: while counter - len(mlist) > sub - 1: if len(node.children()) == 1 and node.isReachedMin(): break self.model()._removeRow(index.child(len(node.children()) - 1, 0)) counter -= sub if not secValidation: self.validateAllExpresion(True) return if len(problems) == 0: self.setStyleSheet('SpockCommandWidget {background-color: %s; color: %s; border: %s; border-radius: %s}' % ('yellow', 'black', '3px solid green', '5px')) self.setToolTip("") else: self.setStyleSheet("") self.setToolTip('
    '.join(problems)) return def findParamRepeat(self, repeatNode): #Method which finds index of given ParamRepeatNode in the macro. children = self.model().root().children() occ = children.count(repeatNode) idx = 0 for i in range(0, occ): idx = children.index(repeatNode, idx) index = self.model().index(idx , 0, Qt.QModelIndex()) return index def validateOneValue(self, value): #Validates value of a SingleParamNode of a currentIndex paramNode = deepcopy(self.model().nodeFromIndex(self.currentIndex)) paramNode.setValue(value) return self.getModelObj().validateSingleParam(paramNode) def returnPressed(self): #SLOT called when return is pressed if self.toolTip() == "": self.emit(Qt.SIGNAL("pressedReturn")) else: raise Exception("Cannot start macro. Please correct following mistakes:
    " + self.toolTip()) def textChanged(self, strs): #SLOT called when QLineEdit text is changed if strs == "": self.updateMacroEditor("") if not self.disableEditMode and self.disableSpockCommandUpdate: self.validateAllExpresion() else: txt_parts = str(self.text()).split() if len(txt_parts) == 0: return try: if self.validateMacro(txt_parts[0]): self.validateAllExpresion() except: self.setToolTip("Read Mode") def validateMacro(self, value): #Method which ivestigates if the macro can be edited using yellow line. #It cannot be executed when: 1. there are more than 1 ParamRepeatNodes, #2. There is a ParamRepeatNode inside ParamRepeatNodem #3. After ParamRepeatNode there are other nodes macroNode = self.getModelObj().getMacroNodeObj(str(value)) if macroNode is None: return False t = [child for child in macroNode.children() if isinstance(child, macro.RepeatParamNode)] if len(t) > 1: self.disableEditMode = True raise Exception('Macro %s cannot be edited using yellow line.
    It contains more than 1 paramRepeat node.
    Please use Macro Editor Widget to edit and execute this macro.' % str(value)) elif len(t) == 1: if len([child for child in t[0].children() if isinstance(child, macro.RepeatParamNode)]) > 0: self.disableEditMode = True raise Exception('Macro %s cannot be edited using yellow line.
    It contains paramRepeat node inside paramRepeat node.
    Please use Macro Editor Widget to edit and execute this macro.' % str(value)) else: if macroNode.children().index(t[0]) != len(macroNode.children()) - 1 : self.disableEditMode = True raise Exception('Macro %s cannot be edited using yellow line.
    It contains paramRepeat node but not as a last parameter.
    Please use Macro Editor Widget to edit and execute this macro.' % str(value)) self.disableEditMode = False return True def downAction(self): #Goes down in the history list of executed macros. #self.disableSpockCommandUpdate flag is used to allow updating yellow line when model is changed. (when new row in history is chosen) self.disableSpockCommandUpdate = False self.emit(Qt.SIGNAL("elementDown")) text = str(self.text()).split() if len(text) > 0: self.validateMacro(text[0]) self.disableSpockCommandUpdate = True def upAction(self): self.disableSpockCommandUpdate = False self.emit(Qt.SIGNAL("elementUp")) text = str(self.text()).split() if len(text) > 0: self.validateMacro(text[0]) self.disableSpockCommandUpdate = True def controlDownAction(self): c = self.cursorPosition() newValue = False try: if self.text()[c] == " " and self.text()[c - 1] == " ": newValue = True except IndexError: if c == 0: newValue = True elif len(self.text()) == self.cursorPosition() and self.text()[c - 1] == " ": newValue = True try: txt = str(self.text()) txt = txt[:txt.find(" ", c)] except IndexError: txt = str(self.text())[:c] elementsNum = txt.split() if newValue: self.insert("0") self.currentIndex = self.getIndex(len(elementsNum)) if not self.currentIndex.isValid(): if len(elementsNum) > 0: self.backspace() return value = self.prevValue("") self.backspace() self.insert(value) self.model().setData(self.currentIndex, Qt.QVariant(value)) else: self.currentIndex = self.getIndex(len(elementsNum) - 1) if not self.currentIndex.isValid(): if len(elementsNum) > 1: return value = self.prevValue(elementsNum[len(elementsNum) - 1]) sel = self.measureSelection(self.cursorPosition()) self.setSelection(sel[0], sel[1]) c = c - (sel[1] - len(str(value))) self.insert(value) self.setCursorPosition(c) self.model().setData(self.currentIndex, Qt.QVariant(value)) def controlUpAction(self): c = self.cursorPosition() newValue = False try: if self.text()[c] == " " and self.text()[c - 1] == " ": newValue = True except IndexError: if c == 0: newValue = True elif len(self.text()) == self.cursorPosition() and self.text()[c - 1] == " ": newValue = True try: txt = str(self.text()) txt = txt[:txt.find(" ", c)] except IndexError: txt = str(self.text())[:c] elementsNum = txt.split() if newValue: self.insert("0") self.currentIndex = self.getIndex(len(elementsNum)) if not self.currentIndex.isValid(): if len(elementsNum) > 0: self.backspace() return value = self.nextValue("") self.backspace() self.insert(value) self.model().setData(self.currentIndex, Qt.QVariant(value)) else: self.currentIndex = self.getIndex(len(elementsNum) - 1) if not self.currentIndex.isValid(): if len(elementsNum) > 1: return value = self.nextValue(elementsNum[len(elementsNum) - 1]) sel = self.measureSelection(self.cursorPosition()) self.setSelection(sel[0], sel[1]) c = c - (sel[1] - len(str(value))) self.insert(value) self.setCursorPosition(c) self.model().setData(self.currentIndex, Qt.QVariant(value)) def getParamItems(self, index): #Returns list of items that can be chosen for the node corresponding to the given index. Used by {next,prev}Value methods node = self.model().nodeFromIndex(index) if isinstance(node, macro.MacroNode): return None type = node.type() ms = self.getParentModelObj() items = ms.getElementsWithInterface(type).keys() return items, type def nextValue(self, current): current = str(current) if self.currentIndex.isValid(): items, type = self.getParamItems(self.currentIndex) items = sorted(items) else: items = self.getParentModelObj().getMacroStrList() items = sorted(items) type = "Macro" if type == "Float": value = float(current) + 0.1 elif type == "Integer": value = int(current) + 1 elif type == "Boolean": value = True else: try: textindex = items.index(current) value = items[textindex - 1] except: tmpitems = [s for s in items if s.startswith(current)] if len(tmpitems) > 0: value = tmpitems[0] else: value = items[0] return str(value) def prevValue(self, current): current = str(current) if self.currentIndex.isValid(): items, type = self.getParamItems(self.currentIndex) items = sorted(items) else: items = self.getParentModelObj().getMacroStrList() items = sorted(items) type = "Macro" if type == "Float": value = float(current) - 0.1 elif type == "Integer": value = int(current) - 1 elif type == "Boolean": value = True else: try: textindex = items.index(current) value = items[textindex + 1] except: tmpitems = [s for s in items if s.startswith(current)] if len(tmpitems) > 0: value = tmpitems[0] else: value = items[0] return str(value) def updateMacroEditor(self, macroName): #I had to make the macroname lowered as macros in comboBox (with macros), has names with all letter low. #Because of that sometimes it was not loading macros in MacroEditor #TO FIX self.emit(Qt.SIGNAL("spockComboBox"), str(macroName).lower()) def measureSelection(self, position): s = str(self.text()) + " " try: if s[position] == " ": position -= 1 except IndexError: position -= 1 end = s.find(' ', position) beg = s.rfind(' ', 0, position + 1) if end == -1: end = s.length() - 1 return beg + 1, end - beg - 1 #returns the start and length of the value def focusInEvent(self, event): self.disableSpockCommandUpdate = True Qt.QLineEdit.focusInEvent(self, event) def focusOutEvent(self, event): self.disableSpockCommandUpdate = False Qt.QLineEdit.focusOutEvent(self, event) class TaurusMacroExecutorWidget(TaurusWidget): def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setObjectName(self.__class__.__name__) self._doorName = "" self._macroId = None self.setLayout(Qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.addToFavouritesAction = Qt.QAction(getThemeIcon("software-update-available"), "Add to favourites", self) self.connect(self.addToFavouritesAction, Qt.SIGNAL("triggered()"), self.onAddToFavourites) self.addToFavouritesAction.setToolTip("Add to favourites") self.stopMacroAction = Qt.QAction(getIcon(":/actions/media_playback_stop.svg"), "Stop macro", self) self.connect(self.stopMacroAction, Qt.SIGNAL("triggered()"), self.onStopMacro) self.stopMacroAction.setToolTip("Stop macro") self.pauseMacroAction = Qt.QAction(getIcon(":/actions/media_playback_pause.svg"), "Pause macro", self) self.connect(self.pauseMacroAction, Qt.SIGNAL("triggered()"), self.onPauseMacro) self.pauseMacroAction.setToolTip("Pause macro") self.playMacroAction = Qt.QAction(getIcon(":/actions/media_playback_start.svg"), "Start macro", self) self.connect(self.playMacroAction, Qt.SIGNAL("triggered()"), self.onPlayMacro) self.playMacroAction.setToolTip("Start macro") actionsLayout = Qt.QHBoxLayout() actionsLayout.setContentsMargins(0, 0, 0, 0) addToFavouritsButton = Qt.QToolButton() addToFavouritsButton.setDefaultAction(self.addToFavouritesAction) self.addToFavouritesAction.setEnabled(False) actionsLayout.addWidget(addToFavouritsButton) self.macroComboBox = MacroComboBox(self) self.macroComboBox.setUseParentModel(True) self.macroComboBox.setModelColumn(0) actionsLayout.addWidget(self.macroComboBox) stopMacroButton = Qt.QToolButton() stopMacroButton.setDefaultAction(self.stopMacroAction) actionsLayout.addWidget(stopMacroButton) pauseMacroButton = Qt.QToolButton() pauseMacroButton.setDefaultAction(self.pauseMacroAction) actionsLayout.addWidget(pauseMacroButton) self.playMacroButton = Qt.QToolButton() self.playMacroButton.setDefaultAction(self.playMacroAction) actionsLayout.addWidget(self.playMacroButton) self.disableControlActions() self.doorStateLed = TaurusLed(self) actionsLayout.addWidget(self.doorStateLed) self.layout().addLayout(actionsLayout) splitter = Qt.QSplitter(self) self.layout().addWidget(splitter) splitter.setOrientation(Qt.Qt.Vertical) self._paramEditorModel = ParamEditorModel() self.stackedWidget = Qt.QStackedWidget() self.standardMacroParametersEditor = StandardMacroParametersEditor(self.stackedWidget) self.stackedWidget.addWidget(self.standardMacroParametersEditor) self.customMacroParametersEditor = None splitter.addWidget(self.stackedWidget) self._favouritesBuffer = None self.favouritesMacrosEditor = FavouritesMacrosEditor(self) self.registerConfigDelegate(self.favouritesMacrosEditor) self.favouritesMacrosEditor.setUseParentModel(True) self.favouritesMacrosEditor.setFocusPolicy(Qt.Qt.NoFocus) self._historyBuffer = None self.historyMacrosViewer = HistoryMacrosViewer(self) self.registerConfigDelegate(self.historyMacrosViewer) self.historyMacrosViewer.setUseParentModel(True) self.historyMacrosViewer.setFocusPolicy(Qt.Qt.NoFocus) self.tabMacroListsWidget = Qt.QTabWidget(self) self.tabMacroListsWidget.addTab(self.favouritesMacrosEditor, "Favourite list") self.tabMacroListsWidget.addTab(self.historyMacrosViewer, "History Viewer") splitter.addWidget(self.tabMacroListsWidget) self._isHistoryMacro = False self.macroProgressBar = MacroProgressBar(self) self.layout().addWidget(self.macroProgressBar) #spockCommandLabel = Qt.QLabel("Spock command:", self) #spockCommandLabel.setFont(Qt.QFont("Courier",9)) self.spockCommand = SpockCommandWidget("Spock", self) self.spockCommand.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) self.spockCommand.setUseParentModel(True) spockCommandLayout = Qt.QHBoxLayout() spockCommandLayout.setContentsMargins(0, 0, 0, 0) #spockCommandLayout.addWidget(spockCommandLabel) spockCommandLayout.addWidget(self.spockCommand) self.layout().addLayout(spockCommandLayout) self.connect(self.macroComboBox, Qt.SIGNAL("currentIndexChanged(QString)"), self.onMacroComboBoxChanged) self.connect(self.favouritesMacrosEditor.list, Qt.SIGNAL("favouriteSelected"), self.onFavouriteSelected) self.connect(self.historyMacrosViewer.list, Qt.SIGNAL("historySelected"), self.onHistorySelected) self.connect(self.spockCommand, Qt.SIGNAL("pressedReturn"), self.onPlayMacro) self.connect(self.spockCommand, Qt.SIGNAL("spockComboBox"), self.setComboBoxItem) self.connect(self.spockCommand, Qt.SIGNAL("elementUp"), self.setHistoryUp) self.connect(self.spockCommand, Qt.SIGNAL("elementDown"), self.setHistoryDown) self.connect(self.spockCommand, Qt.SIGNAL("setHistoryFocus"), self.setHistoryFocus) self.connect(self.spockCommand, Qt.SIGNAL("expandTree"), self.standardMacroParametersEditor.tree.expandAll) def macroId(self): return self._macroId def contextMenuEvent(self, event): menu = Qt.QMenu() action = menu.addAction(getThemeIcon("view-refresh"), "Check door state", self.checkDoorState) menu.exec_(event.globalPos()) def checkDoorState(self): door = Device(self.doorName()) doorState = door.state() if doorState == PyTango.DevState.RUNNING: self.playMacroAction.setEnabled(False) self.pauseMacroAction.setEnabled(True) self.stopMacroAction.setEnabled(True) elif doorState == PyTango.DevState.ON or doorState == PyTango.DevState.ALARM: self.playMacroAction.setEnabled(True) self.pauseMacroAction.setEnabled(False) self.stopMacroAction.setEnabled(False) elif doorState == PyTango.DevState.STANDBY: self.playMacroAction.setEnabled(True) self.pauseMacroAction.setEnabled(False) self.stopMacroAction.setEnabled(True) def setMacroId(self, macroId): self._macroId = macroId def doorName(self): return self._doorName def setDoorName(self, doorName): self._doorName = doorName def setFavouritesBuffer(self, favouritesMacro): self._favouritesBuffer = favouritesMacro #History Widget def setHistoryUp(self): self.setHistoryFocus() self.historyMacrosViewer.listElementUp() def setHistoryDown(self): self.setHistoryFocus() self.historyMacrosViewer.listElementDown() def setHistoryFocus(self): self.tabMacroListsWidget.setCurrentWidget(self.historyMacrosViewer) #self.historyMacrosViewer.setFocus() def historyBuffer(self): return self._historyBuffer def setHistoryBuffer(self, favouritesMacro): self._historyBuffer = favouritesMacro def favouritesBuffer(self): return self._favouritesBuffer def paramEditorModel(self): return self._paramEditorModel def setParamEditorModel(self, paramEditorModel): self._paramEditorModel = paramEditorModel def setComboBoxItem(self, macroName): self.macroComboBox.selectMacro(macroName) def onMacroComboBoxChanged(self, macroName): macroName = str(macroName) if macroName == "": macroName, macroNode = None, None # macroNode = macro.MacroNode(name="") self.playMacroAction.setEnabled(False) self.addToFavouritesAction.setEnabled(False) else: if self._isHistoryMacro: macroNode = self.historyBuffer() self.setHistoryBuffer(None) self.favouritesMacrosEditor.list.clearSelection() else: macroNode = self.favouritesBuffer() self.setFavouritesBuffer(None) self.historyMacrosViewer.list.clearSelection() self._isHistoryMacro = False if macroNode is None: macroNode = self.getModelObj().getMacroNodeObj(macroName) self.playMacroAction.setEnabled(True) self.addToFavouritesAction.setEnabled(True) self.paramEditorModel().setRoot(macroNode) self.spockCommand.setModel(self.paramEditorModel()) if self.stackedWidget.count() == 2: self.stackedWidget.removeWidget(self.customMacroParametersEditor) self.customMacroParametersEditor.setParent(None) self.customMacroParametersEditor = ParamEditorManager().getMacroEditor(macroName, self.stackedWidget) if self.customMacroParametersEditor: self.customMacroParametersEditor.setModel(self.paramEditorModel()) self.stackedWidget.addWidget(self.customMacroParametersEditor) self.stackedWidget.setCurrentWidget(self.customMacroParametersEditor) else: self.standardMacroParametersEditor.setModel(self.paramEditorModel()) self.emit(Qt.SIGNAL("macroNameChanged"), macroName) def onFavouriteSelected(self, macroNode): self.setFavouritesBuffer(macroNode) name = "" if not macroNode is None: name = macroNode.name() self._isHistoryMacro = False self.macroComboBox.selectMacro(name) def onHistorySelected(self, macroNode): self.setHistoryBuffer(macroNode) name = "" if not macroNode is None: name = macroNode.name() self._isHistoryMacro = True self.macroComboBox.selectMacro(name) def onAddToFavourites(self): self.favouritesMacrosEditor.addMacro(deepcopy(self.paramEditorModel().root())) def addToHistory(self): self.historyMacrosViewer.addMacro(deepcopy(self.paramEditorModel().root())) def onDoorChanged(self, doorName): self.setDoorName(doorName) if self.doorName() == "": self.doorStateLed.setModel(None) return self.doorStateLed.setModel(self.doorName() + "/State") doorState = Device(doorName).state() if doorState == PyTango.DevState.ON: self.playMacroAction.setText("Start macro") self.playMacroAction.setToolTip("Start macro") elif doorState == PyTango.DevState.STANDBY: self.playMacroAction.setText("Resume macro") self.playMacroAction.setToolTip("Resume macro") def onPlayMacro(self): door = Device(self.doorName()) doorState = door.state() if doorState == PyTango.DevState.ON or doorState == PyTango.DevState.ALARM: paramEditorModel = self.paramEditorModel() macroNode = paramEditorModel.root() id = macroNode.assignId() self.setMacroId(id) params, alerts = macroNode.toRun() xmlString = paramEditorModel.toXmlString() if len(alerts) > 0: Qt.QMessageBox.warning(self, "Macro parameters warning", alerts) return door.runMacro(xmlString) self.addToHistory() # door.runMacro(str(macroNode.name()), params) elif doorState == PyTango.DevState.STANDBY: door.command_inout("ResumeMacro") else: Qt.QMessageBox.warning(self, "Error while starting/resuming macro", "It was not possible to start/resume macro, because state of the door was different than ON/STANDBY") def onStopMacro(self): door = Device(self.doorName()) doorState = door.state() if doorState in (PyTango.DevState.RUNNING, PyTango.DevState.STANDBY): door.command_inout("StopMacro") else: Qt.QMessageBox.warning(self, "Error while stopping macro", "It was not possible to stop macro, because state of the door was different than RUNNING or STANDBY") def onPauseMacro(self): door = Device(self.doorName()) doorState = door.state() if doorState == PyTango.DevState.RUNNING: door.command_inout("PauseMacro") else: Qt.QMessageBox.warning(self, "Error while pausing macro", "It was not possible to pause macro, because state of the door was different than RUNNING") def onMacroStatusUpdated(self, data): macro = data[0] if macro is None: return data = data[1][0] state, range, step, id = data["state"], data["range"], data["step"], data["id"] if id is None: return id = int(id) if id != self.macroId(): return macroName = macro.name shortMessage = "" if state == "start": self.emit(Qt.SIGNAL("macroStarted"), "DoorOutput") self.macroProgressBar.setRange(range[0], range[1]) self.playMacroAction.setEnabled(False) self.pauseMacroAction.setEnabled(True) self.stopMacroAction.setEnabled(True) self.emit(Qt.SIGNAL("plotablesFilterChanged"), None) self.emit(Qt.SIGNAL("plotablesFilterChanged"), standardPlotablesFilter) shortMessage = "Macro %s started." % macroName elif state == "pause": self.playMacroAction.setText("Resume macro") self.playMacroAction.setToolTip("Resume macro") self.playMacroAction.setEnabled(True) self.pauseMacroAction.setEnabled(False) shortMessage = "Macro %s paused." % macroName elif state == "resume": self.playMacroAction.setText("Start macro") self.playMacroAction.setToolTip("Start macro") self.playMacroAction.setEnabled(False) self.pauseMacroAction.setEnabled(True) shortMessage = "Macro %s resumed." % macroName elif state == "stop" or state == "finish": self.playMacroAction.setEnabled(True) self.pauseMacroAction.setEnabled(False) self.stopMacroAction.setEnabled(False) shortMessage = "Macro %s finished." % macroName elif state == "exception": self.playMacroAction.setEnabled(True) self.pauseMacroAction.setEnabled(False) self.stopMacroAction.setEnabled(False) shortMessage = "Macro %s error." % macroName exc_value, exc_stack = data['exc_value'], data['exc_stack'] exceptionDialog = TaurusMessageBox(MacroRunException, exc_value, exc_stack) exceptionDialog.exec_() elif state == "abort": self.playMacroAction.setText("Start macro") self.playMacroAction.setToolTip("Start macro") self.playMacroAction.setEnabled(True) self.pauseMacroAction.setEnabled(False) self.stopMacroAction.setEnabled(False) shortMessage = "Macro %s stopped." % macroName elif state == "step": shortMessage = "Macro %s at %d %% of progress." % (macroName, step) self.emit(Qt.SIGNAL("shortMessageEmitted"), shortMessage) self.macroProgressBar.setValue(step) def disableControlActions(self): self.pauseMacroAction.setEnabled(False) self.stopMacroAction.setEnabled(False) self.playMacroAction.setEnabled(False) def setModel(self, model): oldModelObj = self.getModelObj() if oldModelObj is not None: self.disconnect(oldModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) TaurusWidget.setModel(self, model) newModelObj = self.getModelObj() self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) @classmethod def getQtDesignerPluginInfo(cls): return {'container': False, 'group': 'Taurus Sardana', 'module': 'taurus.qt.qtgui.extra_macroexecutor', 'icon': ':/designer/frame.png'} class TaurusMacroExecutor(MacroExecutionWindow): def __init__(self, parent=None, designMode=False): MacroExecutionWindow.__init__(self, parent, designMode) def initComponents(self): self.taurusMacroExecutorWidget = TaurusMacroExecutorWidget(self) self.registerConfigDelegate(self.taurusMacroExecutorWidget) self.taurusMacroExecutorWidget.setUseParentModel(True) self.setCentralWidget(self.taurusMacroExecutorWidget) self.connect(self.taurusMacroExecutorWidget, Qt.SIGNAL('shortMessageEmitted'), self.onShortMessage) self.statusBar().showMessage("MacroExecutor ready") def setCustomMacroEditorPaths(self, customMacroEditorPaths): MacroExecutionWindow.setCustomMacroEditorPaths(self, customMacroEditorPaths) ParamEditorManager().parsePaths(customMacroEditorPaths) ParamEditorManager().browsePaths() def loadSettings(self): TaurusMainWindow.loadSettings(self) self.emit(Qt.SIGNAL("doorChanged"), self.doorName()) def onDoorChanged(self, doorName): MacroExecutionWindow.onDoorChanged(self, doorName) if self._qDoor: Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated) if doorName == "": return self._qDoor = Device(doorName) Qt.QObject.connect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated) self.taurusMacroExecutorWidget.onDoorChanged(doorName) @classmethod def getQtDesignerPluginInfo(cls): return None def createMacroExecutorWidget(args): macroExecutor = TaurusMacroExecutorWidget() macroExecutor.setModelInConfig(True) Qt.QObject.connect(macroExecutor, Qt.SIGNAL("doorChanged"), macroExecutor.onDoorChanged) if len(args) == 2: macroExecutor.setModel(args[0]) macroExecutor.emit(Qt.SIGNAL('doorChanged'), args[1]) return macroExecutor def createMacroExecutor(args): macroExecutor = TaurusMacroExecutor() macroExecutor.setModelInConfig(True) Qt.QObject.connect(macroExecutor, Qt.SIGNAL("doorChanged"), macroExecutor.onDoorChanged) if len(args) == 2: macroExecutor.setModel(args[0]) macroExecutor.emit(Qt.SIGNAL('doorChanged'), args[1]) macroExecutor.loadSettings() return macroExecutor def main(): from taurus.qt.qtgui.application import TaurusApplication import taurus app = TaurusApplication(sys.argv, app_version=taurus.Release.version) args = app.get_command_line_args() app.setOrganizationName("Taurus") app.setApplicationName("macroexecutor") macroExecutor = createMacroExecutor(args) macroExecutor.show() sys.exit(app.exec_()) if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_macroexecutor/scanplotter.py0000644000234000017500000001315512555672637031274 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ scanplotter.py: module containing the widget: scanplotter, to be used in the Taurus app "scanner.py" """ import taurus.core from taurus.external.qt import QtGui, Qwt5 #from taurus.qt.Qt import * from taurus.core.util import dictFromSequence from taurus.core.util.containers import CaselessDict from taurus.core.util import eventfilters from taurus.qt.qtgui.plot import TaurusTrend class ScanPlotter(TaurusTrend): def __init__(self, parent=None, designMode=False): TaurusTrend.__init__(self, parent, designMode) self.setUseParentModel(False) self._plotables = CaselessDict() self._movingMotors = [] self._macroNames = [] self._doorName = None self.setMinimumSize(300, 200) self.setXIsTime(True) self.setAxisScale(Qwt5.QwtPlot.xBottom, 0, 60) self.setXDynScale(True) def onSequenceCleared(self): self._movingMotors = [] self._macroNames = [] self.populatePlotables() def onMacrosAdded(self, macroNames, motors): for macro in macroNames: self._macroNames.append(macro) self._movingMotors += motors self.populatePlotables() def onMacroEdited(self, oldMotors, newMotors): for motor in oldMotors: self._movingMotors.remove(motor) self._movingMotors += newMotors self.populatePlotables() def onMacrosDeleted(self, macroNames, motors): for macro in macroNames: self._macroNames.remove(macro) for motor in motors: self._movingMotors.remove(motor) self.populatePlotables() def onMacroStarted(self, macroName, motors): self._macroNames = [macroName] self._movingMotors = motors self.populatePlotables() def onMotorChanged(self, oldMotor, newMotor): if oldMotor in self._movingMotors: self._movingMotors.remove(oldMotor) self._movingMotors.append(newMotor) self.populatePlotables() def onMacroChanged(self, macroNode): if macroNode is None: self._macroNames = [] self._movingMotors = [] # return else: self._macroNames = [macroNode.name()] self._movingMotors = macroNode.allMotors() self.populatePlotables() def onDoorChanged(self, doorName): self._doorName = doorName self._movingMotors = [] self.populatePlotables() def getPlotables(self, macronames=None, doorname=None, movingmotors=None): """returns a list of plotables for this scan given macro (channels and moving motors)""" plotables = [] if macronames is None: macronames = list(set(self._macroNames)) if doorname is None: doorname = self._doorName if movingmotors is None: movingmotors = list(set(self._movingMotors)) if doorname is None or not len(macronames): return plotables door = taurus.Device(doorname) for macroname in macronames: env = dictFromSequence(door.getMacroEnv([macroname])) mntgrp_name = env.get("ActiveMntGrp") if mntgrp_name is None: continue mntgrp = taurus.Device(mntgrp_name) channels = mntgrp.getAttribute('Channels').read() channelsList = channels.value timer_name = mntgrp.getAttribute('Timer').read().value.lower() plotables += [('%s/%s_value' % (mntgrp_name, ch)).lower() for ch in channelsList if ch.lower() != timer_name] for m in movingmotors: if not (m is None or m == "" or m == "None"): plotables += ["%s/position" % m] return plotables def populatePlotables(self, plotables=None): ##@TODO: The name in the legend should be more descriptive: i.e. "dev/attr" instead of "attr" (this probably has to be changed for taurusplot in general ) if plotables is None: plotables = self.getPlotables() self.setModel(plotables) self.curves_lock.acquire() try: for name in self.getTrendSetNames(): ts = self.getTrendSet(name) ts.fireEvent(None, taurus.core.taurusbasetypes.TaurusEventType.Change, None) finally: self.curves_lock.release() self.setEventFilters([eventfilters.ONLY_VALID], plotables) if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) form = ScanPlotter() if len(sys.argv) < 4: raise ValueError('Syntax: ' + sys.argv[0] + ' macroname doorname plotable [anotherplotable...]') form._macroName = sys.argv[1] form._doorName = sys.argv[2] form.populatePlotables(sys.argv[3:]) form.show() sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/0000755000234000017500000000000012555673001024432 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/0000755000234000017500000000000012555673001025047 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/AppleiiPLCTemperature.ui0000644000234000017500000001301012555672637031557 0ustar zreszelaComputing00000000000000 AppleiiPLCTemperature 0 0 238 30 Form 0 0 0 0 0 0 false 0 0 0 0 0 0 true RED Qt::Horizontal 20 20 50 22 50 16777215 true 0 0 50 22 Qt::AlignCenter true 35 22 35 16777215 true Qt::Horizontal 20 20 Cfg TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusBoolLed QLabel
    taurus.qt.qtgui.display
    TaurusConfigLabel QLabel
    taurus.qt.qtgui.display
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/AppleiiPLCTemperatureAlarms.ui0000644000234000017500000001611212555672637032725 0ustar zreszelaComputing00000000000000 AppleiiPLCTemperatureAlarms 0 0 275 191 Form 0 0 0 0 0 0 false Alarm Up Qt::AlignCenter true 100 0 100 16777215 Qt::Horizontal Warning Up Qt::AlignCenter true false 100 0 100 16777215 Qt::Horizontal 0 20 16777215 20 true true Warning Down Qt::AlignCenter true 100 0 100 16777215 Qt::Horizontal Alarm Down Qt::AlignCenter true 100 0 100 16777215 Qt::Horizontal Apply TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusValueLineEdit QLineEdit
    taurus.qt.qtgui.input
    TaurusConfigLabel QLabel
    taurus.qt.qtgui.display
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/PoolIORegisterButtons.ui0000644000234000017500000000261412555672637031654 0ustar zreszelaComputing00000000000000 PoolIORegisterButtons 0 0 172 52 0 0 Form 0 0 0 QLayout::SetMinimumSize 0 TaurusWidget QWidget
    taurus.qt.qtgui.container
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/PoolMotorSlim.ui0000644000234000017500000002657112555672637030216 0ustar zreszelaComputing00000000000000 PoolMotorSlim 0 0 487 61 Dialog 0 0 0 0 false 0 0 0 0 0 0 0 20 16777215 Negative limit - true false 0 0 20 16777215 Moves the motor towards negative limit |< false false 0 0 20 16777215 Moves the motor towards negative limit while pressed « 0 0 20 16777215 Decrements motor position <inc> units < 80 16777215 10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104.000000000000000 1.000000000000000 0 0 20 16777215 Increments motor position <inc> units > 0 0 20 16777215 Moves the motor towards positive limit while pressed » 0 0 20 16777215 Moves the motor towards positive limit >| 0 0 20 16777215 Positive limit + false 30 16777215 Stops the motor S 30 16777215 Goes Home H 30 16777215 Configures the motor Cfg 0 0 7 TauValueLabel { border-style: outset; border-width: 2px; border-color: rgba(255,255,255,128); background-color: transparent; color:black; } QFrame::StyledPanel 0 /Status true false TaurusWidget QWidget
    taurus.qt.qtgui.container
    TaurusLauncherButton QPushButton
    taurus.qt.qtgui.button
    TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/TaurusMotorH.ui0000644000234000017500000001417612555672637030051 0ustar zreszelaComputing00000000000000 TaurusMotorH 0 0 392 48 Form 0 0 0 0 0 0 false 50 22 QFrame::NoFrame QFrame::Plain false true /State true /State 50 22 true /Position 0 0 50 22 true /Position 35 22 35 16777215 true /Position?configuration=unit cfg true /Limit_switches 2 - lim + Qt::AlignCenter true /Limit_switches 1 TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusStateLed QLabel
    taurus.qt.qtgui.display
    TaurusBoolLed QLabel
    taurus.qt.qtgui.display
    TaurusValueLineEdit QLineEdit
    taurus.qt.qtgui.input
    TaurusConfigLabel QLabel
    taurus.qt.qtgui.display
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/TaurusMotorH2.ui0000644000234000017500000001511712555672637030127 0ustar zreszelaComputing00000000000000 TaurusMotorH2 0 0 212 82 Form 0 0 0 0 0 0 false 50 22 QFrame::NoFrame QFrame::Plain false true /State true /State Qt::Horizontal 40 20 true /Limit_switches 2 - lim + Qt::AlignCenter true /Limit_switches 1 true /Position 0 0 true /Position 35 24 35 24 true /Position?configuration=unit cfg TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusStateLed QLabel
    taurus.qt.qtgui.display
    TaurusBoolLed QLabel
    taurus.qt.qtgui.display
    TaurusValueLineEdit QLineEdit
    taurus.qt.qtgui.input
    TaurusConfigLabel QLabel
    taurus.qt.qtgui.display
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/TaurusMotorV.ui0000644000234000017500000001425112555672637030061 0ustar zreszelaComputing00000000000000 TaurusMotorV 0 0 120 144 Form 0 0 0 0 0 0 false 50 22 QFrame::NoFrame QFrame::Plain false true /State true /State true /Position cfg true /Position 35 24 35 24 true /Position?configuration=unit true /Limit_switches 2 - lim + Qt::AlignCenter true /Limit_switches 1 TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusStateLed QLabel
    taurus.qt.qtgui.display
    TaurusBoolLed QLabel
    taurus.qt.qtgui.display
    TaurusValueLineEdit QLineEdit
    taurus.qt.qtgui.input
    TaurusConfigLabel QLabel
    taurus.qt.qtgui.display
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/ui/TaurusMotorV2.ui0000644000234000017500000006307412555672637030152 0ustar zreszelaComputing00000000000000 TaurusMotorV2 0 0 297 272 0 0 Dialog 0 0 0 0 0 0 false 24 true /State 50 22 QFrame::NoFrame QFrame::Plain false true /State Qt::Horizontal 40 20 true ORANGE /Limit_switches 2 - lim + Qt::AlignCenter true ORANGE /Limit_switches 1 true : /Position?configuration=label 0 0 70 22 true /Position 0 0 50 22 true /Position 0 0 35 22 35 16777215 true /Position?configuration=unit true : /Velocity?configuration=label 0 0 70 22 true /Velocity 0 0 50 22 true /Velocity 0 0 35 22 35 16777215 true /Velocity?configuration=unit true : /Acceleration?configuration=label 0 0 70 22 true /Acceleration 0 0 50 22 true /Acceleration 0 0 35 22 35 16777215 true /Acceleration?configuration=unit true : /Deceleration?configuration=label 0 0 70 22 true /Deceleration 0 0 50 22 true /Deceleration 0 0 35 22 35 16777215 true /Deceleration?configuration=unit true : /Offset?configuration=label 0 0 70 22 true /Offset 0 0 50 22 true /Offset 0 0 35 22 35 16777215 true /Offset?configuration=unit true : /Base_rate?configuration=label 0 0 70 22 true /Base_rate 0 0 50 22 true /Base_rate 0 0 35 22 35 16777215 true /Base_rate?configuration=unit true : /Step_per_unit?configuration=label 0 0 70 22 true /Step_per_unit 0 0 50 22 true /Step_per_unit 0 0 35 22 35 16777215 true /Step_per_unit?configuration=unit true : /Backlash?configuration=label 0 0 70 22 true /Backlash 0 0 50 22 true /Backlash 0 0 35 22 35 16777215 true /Backlash?configuration=unit TaurusGroupBox QGroupBox
    taurus.qt.qtgui.container
    1
    TaurusStateLed QLabel
    taurus.qt.qtgui.display
    TaurusBoolLed QLabel
    taurus.qt.qtgui.display
    TaurusValueLineEdit QLineEdit
    taurus.qt.qtgui.input
    TaurusConfigLabel QLabel
    taurus.qt.qtgui.display
    TaurusValueLabel QLabel
    taurus.qt.qtgui.display
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/__init__.py0000644000234000017500000000273112555672637026564 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ __init__.py: """ from motor import TaurusMotorH, TaurusMotorH2, TaurusMotorV, TaurusMotorV2 from poolmotor import PoolMotorSlim, LabelWidgetDragsDeviceAndAttribute from poolmotor import PoolMotorTV, PoolMotorTVLabelWidget, PoolMotorTVReadWidget, PoolMotorTVWriteWidget, PoolMotorTVUnitsWidget from poolmotor import PoolMotor from poolchannel import PoolChannel, PoolChannelTV from poolioregister import PoolIORegisterTV, PoolIORegisterReadWidget, PoolIORegisterWriteWidget, PoolIORegister, PoolIORegisterButtons sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/motor.py0000644000234000017500000015057512555672637026177 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ motor.py: """ from taurus.external.qt import Qt from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.util.ui import UILoadable def showDialogConfigureMotor(parent): Dialog = Qt.QDialog(parent) Dialog.resize((Qt.QSize(Qt.QRect(0, 0, 310, 309).size()).expandedTo(Dialog.minimumSizeHint()))) motorV2 = TaurusMotorV2(Dialog) motorV2.setModel(parent.model) motorV2.setGeometry(Qt.QRect(10, 10, 291, 291)) Dialog.show() @UILoadable(with_ui='ui') class TaurusMotorH(Qt.QWidget, TaurusBaseWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) self.loadUi() Qt.QObject.connect(self.ui.config, Qt.SIGNAL("clicked()"), self.configureMotor) def sizeHint(self): return Qt.QSize(330, 50) def configureMotor(self): showDialogConfigureMotor(self.ui.TaurusGroupBox) @classmethod def getQtDesignerPluginInfo(cls): return None # ret = TaurusBaseWidget.getQtDesignerPluginInfo() # ret['module'] = 'taurus.qt.qtgui.extra_pool' # ret['group'] = 'Taurus Sardana' # ret['icon'] = ':/designer/extra_pool.png' # return ret #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # QT properties #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @Qt.pyqtSignature("getModel()") def getModel(self): return self.ui.TaurusGroupBox.getModel() @Qt.pyqtSignature("setModel(QString)") def setModel(self, model): self.ui.TaurusGroupBox.setModel(model) @Qt.pyqtSignature("resetModel()") def resetModel(self): self.ui.TaurusGroupBox.resetModel() @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @Qt.pyqtSignature("setShowText(bool)") def setShowText(self, showText): self.ui.TaurusGroupBox.setShowText(showText) @Qt.pyqtSignature("resetShowText()") def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) @UILoadable(with_ui='ui') class TaurusMotorH2(Qt.QWidget, TaurusBaseWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) self.loadUi() Qt.QObject.connect(self.ui.config, Qt.SIGNAL("clicked()"), self.configureMotor) def sizeHint(self): return Qt.QSize(215, 85) def configureMotor(self): showDialogConfigureMotor(self.ui.TaurusGroupBox) @classmethod def getQtDesignerPluginInfo(cls): return None # ret = TaurusBaseWidget.getQtDesignerPluginInfo() # ret['module'] = 'taurus.qt.qtgui.extra_pool' # ret['group'] = 'Taurus Sardana' # ret['icon'] = ':/designer/extra_pool.png' # return ret #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # QT properties #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @Qt.pyqtSignature("getModel()") def getModel(self): return self.ui.TaurusGroupBox.getModel() @Qt.pyqtSignature("setModel(QString)") def setModel(self, model): self.ui.TaurusGroupBox.setModel(model) @Qt.pyqtSignature("resetModel()") def resetModel(self): self.ui.TaurusGroupBox.resetModel() @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @Qt.pyqtSignature("setShowText(bool)") def setShowText(self, showText): self.ui.TaurusGroupBox.setShowText(showText) @Qt.pyqtSignature("resetShowText()") def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) @UILoadable(with_ui='ui') class TaurusMotorV(Qt.QWidget, TaurusBaseWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) self.loadUi() Qt.QObject.connect(self.ui.config, Qt.SIGNAL("clicked()"), self.configureMotor) def sizeHint(self): return Qt.QSize(120, 145) def configureMotor(self): showDialogConfigureMotor(self.ui.TaurusGroupBox) @classmethod def getQtDesignerPluginInfo(cls): return None # ret = TaurusBaseWidget.getQtDesignerPluginInfo() # ret['module'] = 'taurus.qt.qtgui.extra_pool' # ret['group'] = 'Taurus Sardana' # ret['icon'] = ':/designer/extra_pool.png' # return ret #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # QT properties #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @Qt.pyqtSignature("getModel()") def getModel(self): return self.ui.TaurusGroupBox.getModel() @Qt.pyqtSignature("setModel(QString)") def setModel(self, model): self.ui.TaurusGroupBox.setModel(model) @Qt.pyqtSignature("resetModel()") def resetModel(self): self.ui.TaurusGroupBox.resetModel() @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @Qt.pyqtSignature("setShowText(bool)") def setShowText(self, showText): self.ui.TaurusGroupBox.setShowText(showText) @Qt.pyqtSignature("resetShowText()") def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) @UILoadable(with_ui='ui') class TaurusMotorV2(Qt.QWidget, TaurusBaseWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) self.loadUi() def sizeHint(self): return Qt.QSize(300, 275) @classmethod def getQtDesignerPluginInfo(cls): return None # ret = TaurusBaseWidget.getQtDesignerPluginInfo() # ret['module'] = 'taurus.qt.qtgui.extra_pool' # ret['group'] = 'Taurus Sardana' # ret['icon'] = ':/designer/extra_pool.png' # return ret #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # QT properties #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @Qt.pyqtSignature("getModel()") def getModel(self): return self.ui.TaurusGroupBox.getModel() @Qt.pyqtSignature("setModel(QString)") def setModel(self, model): self.ui.TaurusGroupBox.setModel(model) @Qt.pyqtSignature("resetModel()") def resetModel(self): self.ui.TaurusGroupBox.resetModel() @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @Qt.pyqtSignature("setShowText(bool)") def setShowText(self, showText): self.ui.TaurusGroupBox.setShowText(showText) @Qt.pyqtSignature("resetShowText()") def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) ###class TaurusMotorH2(Qt.QGroupBox, TaurusBaseWidget): ### ### def __init__(self, parent = None, designMode = False): ### name = "TaurusMotorH2" ### self._prefix = '' ### self._suffix = '' ### ### self.call__init__wo_kw(Qt.QGroupBox, parent) ### self.call__init__(TaurusBaseWidget, name, designMode = designMode) ### ### self.setObjectName(name) ### self.defineStyle() ### ### ### ## I CAN NOT INHERIT FROM TAUGROUPBOX ! ### ## SO ALL THE STUFFABOVE IS NECESSARY ### ## ### ## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ### ############################################################################## ### ## ### #class TaurusMotorH2(TaurusGroupBox): ### #def __init__(self, parent = None): ### #self.call__init__wo_kw(TaurusGroupBox,parent) ### #self.call__init__(TaurusGroupBox,str(self.objectName())) ### self.setupUi() ### self.retranslateUi() ### self.connect(self.config,Qt.SIGNAL('clicked()'),self.configureMotor) ### ### ### def configureMotor(self): ### Dialog = Qt.QDialog(self) ### Dialog.resize((Qt.QSize(Qt.QRect(0,0,310,309).size()).expandedTo(Dialog.minimumSizeHint()))) ### motorV2 = TaurusMotorV2(Dialog) ### motorV2.setModel(self.model) ### motorV2.setGeometry(Qt.QRect(10,10,291,291)) ### Dialog.show() ### ### ### ### def minimumSizeHint(self): ### return Qt.QSize(211,80) ### ### def sizeHint(self): ### return Qt.QSize(211,80) ### ### ### def setupUi(self): ### ### self.gridlayout = Qt.QGridLayout(self) ### self.gridlayout.setObjectName("gridlayout") ### ### self.vboxlayout = Qt.QVBoxLayout() ### self.vboxlayout.setObjectName("vboxlayout") ### ### self.hboxlayout = Qt.QHBoxLayout() ### self.hboxlayout.setObjectName("hboxlayout") ### ### self.taurusValueLabel_2 = TaurusValueLabel(self) ### self.taurusValueLabel_2.setFrameShape(Qt.QFrame.NoFrame) ### self.taurusValueLabel_2.setFrameShadow(Qt.QFrame.Plain) ### self.taurusValueLabel_2.setShowQuality(False) ### self.taurusValueLabel_2.setUseParentModel(True) ### self.taurusValueLabel_2.setObjectName("taurusValueLabel_2") ### self.hboxlayout.addWidget(self.taurusValueLabel_2) ### ### self.TaurusStateLed_17 = TaurusStateLed(self) ### self.TaurusStateLed_17.setUseParentModel(True) ### self.TaurusStateLed_17.setObjectName("TaurusStateLed_17") ### self.hboxlayout.addWidget(self.TaurusStateLed_17) ### ### spacerItem = Qt.QSpacerItem(40,20,Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Minimum) ### self.hboxlayout.addItem(spacerItem) ### ### self.TaurusLimitSwitch = TaurusLimitSwitch(self) ### self.TaurusLimitSwitch.setUseParentModel(True) ### self.TaurusLimitSwitch.setBoolIndex(2) ### self.TaurusLimitSwitch.setObjectName("TaurusLimitSwitch") ### self.hboxlayout.addWidget(self.TaurusLimitSwitch) ### ### self.label_3 = Qt.QLabel(self) ### self.label_3.setAlignment(Qt.Qt.AlignCenter) ### self.label_3.setObjectName("label_3") ### self.hboxlayout.addWidget(self.label_3) ### ### self.TaurusLimitSwitch_2 = TaurusLimitSwitch(self) ### self.TaurusLimitSwitch_2.setUseParentModel(True) ### self.TaurusLimitSwitch_2.setBoolIndex(1) ### self.TaurusLimitSwitch_2.setObjectName("TaurusLimitSwitch_2") ### self.hboxlayout.addWidget(self.TaurusLimitSwitch_2) ### self.vboxlayout.addLayout(self.hboxlayout) ### ### self.hboxlayout1 = Qt.QHBoxLayout() ### self.hboxlayout1.setObjectName("hboxlayout1") ### ### self.TaurusValueLineEdit_21 = TaurusValueLineEdit(self) ### self.TaurusValueLineEdit_21.setUseParentModel(True) ### self.TaurusValueLineEdit_21.setObjectName("TaurusValueLineEdit_21") ### self.hboxlayout1.addWidget(self.TaurusValueLineEdit_21) ### ### self.taurusValueLabel_21 = TaurusValueLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.taurusValueLabel_21.sizePolicy().hasHeightForWidth()) ### self.taurusValueLabel_21.setSizePolicy(sizePolicy) ### self.taurusValueLabel_21.setUseParentModel(True) ### self.taurusValueLabel_21.setObjectName("taurusValueLabel_21") ### self.hboxlayout1.addWidget(self.taurusValueLabel_21) ### ### self.taurusConfigLabel_18 = TaurusConfigLabel(self) ### self.taurusConfigLabel_18.setMaximumSize(Qt.QSize(27,22)) ### self.taurusConfigLabel_18.setUseParentModel(True) ### self.taurusConfigLabel_18.setObjectName("taurusConfigLabel_18") ### self.hboxlayout1.addWidget(self.taurusConfigLabel_18) ### ### self.config = Qt.QToolButton(self) ### self.config.setObjectName("config") ### self.hboxlayout1.addWidget(self.config) ### self.vboxlayout.addLayout(self.hboxlayout1) ### self.gridlayout.addLayout(self.vboxlayout,0,0,1,1) ### ### ### def retranslateUi(self): ### self.taurusValueLabel_2.setModel(Qt.QApplication.translate("Form", "/State", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusStateLed_17.setModel(Qt.QApplication.translate("Form", "/State", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch.setModel(Qt.QApplication.translate("Form", "/Limit_switches", None, Qt.QApplication.UnicodeUTF8)) ### self.label_3.setText(Qt.QApplication.translate("Form", "- lim +", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch_2.setModel(Qt.QApplication.translate("Form", "/Limit_switches", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusValueLineEdit_21.setModel(Qt.QApplication.translate("Form", "/Position", None, Qt.QApplication.UnicodeUTF8)) ### self.taurusValueLabel_21.setModel(Qt.QApplication.translate("Form", "/Position", None, Qt.QApplication.UnicodeUTF8)) ### self.taurusConfigLabel_18.setModel(Qt.QApplication.translate("Form", "/Position?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.config.setText(Qt.QApplication.translate("Form", "cfg", None, Qt.QApplication.UnicodeUTF8)) ### ### ### ############################################################################## ### ## VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ### ## ### ## I CAN NOT INHERIT FROM TAUGROUPBOX ! ### ## SO ALL THE STUFF BELOW IS NECESSARY ### ### ### ### def defineStyle(self): ### palette = Qt.QPalette() ### self.setPalette(palette) ### self.updateStyle() ### ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### # TaurusBaseWidget over writing ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### ### def getDisplayValue(self): ### return (self._prefix or '') + TaurusBaseWidget.getDisplayValue(self) + (self._suffix or '') ### ### def isReadOnly(self): ### return True ### ### def updateStyle(self): ### if self.getShowQuality(): ### self.setAutoFillBackground(True) ### #TODO: get quality/state from model and update accordingly ### else: ### self.setAutoFillBackground(False) ### #TODO: restore colors ### self.update() ### ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### # QT properties ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### ### def getPrefixText(self): ### return self._prefix ### ### @Qt.pyqtSignature("setPrefixText(QString)") ### def setPrefixText(self,prefix): ### self._prefix = prefix ### self.fireValueChanged() ### ### def getSuffixText(self): ### return self._suffix ### ### @Qt.pyqtSignature("setSuffixText(QString)") ### def setSuffixText(self,suffix): ### self._suffix = suffix ### self.fireValueChanged() ### ### model = Qt.pyqtProperty("QString", TaurusBaseWidget.getModel, ### TaurusBaseWidget.setModel, TaurusBaseWidget.resetModel) ### useParentModel = Qt.pyqtProperty("bool", TaurusBaseWidget.getUseParentModel, ### TaurusBaseWidget.setUseParentModel, ### TaurusBaseWidget.resetUseParentModel) ### showQuality = Qt.pyqtProperty("bool", TaurusBaseWidget.getShowQuality, ### TaurusBaseWidget.setShowQuality, ### TaurusBaseWidget.resetShowQuality) ### showText = Qt.pyqtProperty("bool", TaurusBaseWidget.getShowText, ### TaurusBaseWidget.setShowText, ### TaurusBaseWidget.resetShowText) ### prefixText = Qt.pyqtProperty("QString", getPrefixText, setPrefixText, ### doc="prefix text (optional)") ### suffixText = Qt.pyqtProperty("QString", getSuffixText, setSuffixText, ### doc="suffix text (optional)") ### ### ### ### ###class TaurusMotorV(Qt.QGroupBox, TaurusBaseWidget): ### ### def __init__(self, parent = None): ### name = "TaurusMotorV" ### self._prefix = '' ### self._suffix = '' ### ### self.call__init__wo_kw(Qt.QGroupBox, parent) ### self.call__init__(TaurusBaseWidget, name) ### ### self.setObjectName(name) ### self.defineStyle() ### ### ### ## I CAN NOT INHERIT FROM TAUGROUPBOX ! ### ## SO ALL THE STUFFABOVE IS NECESSARY ### ## ### ## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ### ############################################################################## ### ## ### #class TaurusMotorV(TaurusGroupBox): ### #def __init__(self, parent = None): ### #self.call__init__wo_kw(TaurusGroupBox,parent) ### #self.call__init__(TaurusGroupBox,str(self.objectName())) ### self.setupUi() ### self.retranslateUi() ### self.connect(self.config,Qt.SIGNAL('clicked()'),self.configureMotor) ### ### ### def configureMotor(self): ### Dialog = Qt.QDialog(self) ### Dialog.resize((Qt.QSize(Qt.QRect(0,0,310,309).size()).expandedTo(Dialog.minimumSizeHint()))) ### motorV2 = TaurusMotorV2(Dialog) ### motorV2.setModel(self.model) ### motorV2.setGeometry(Qt.QRect(10,10,291,291)) ### Dialog.show() ### ### ### ### ### def minimumSizeHint(self): ### return Qt.QSize(150,128) ### ### def sizeHint(self): ### return Qt.QSize(150,128) ### ### def setupUi(self): ### ### self.gridlayout = Qt.QGridLayout(self) ### self.gridlayout.setObjectName("gridlayout") ### ### self.vboxlayout = Qt.QVBoxLayout() ### self.vboxlayout.setObjectName("vboxlayout") ### ### self.hboxlayout = Qt.QHBoxLayout() ### self.hboxlayout.setObjectName("hboxlayout") ### ### self.taurusValueLabel_2 = TaurusValueLabel(self) ### self.taurusValueLabel_2.setFrameShape(Qt.QFrame.NoFrame) ### self.taurusValueLabel_2.setFrameShadow(Qt.QFrame.Plain) ### self.taurusValueLabel_2.setShowQuality(False) ### self.taurusValueLabel_2.setUseParentModel(True) ### self.taurusValueLabel_2.setObjectName("taurusValueLabel_2") ### self.hboxlayout.addWidget(self.taurusValueLabel_2) ### ### self.TaurusStateLed_17 = TaurusStateLed(self) ### self.TaurusStateLed_17.setUseParentModel(True) ### self.TaurusStateLed_17.setObjectName("TaurusStateLed_17") ### self.hboxlayout.addWidget(self.TaurusStateLed_17) ### self.vboxlayout.addLayout(self.hboxlayout) ### ### self.hboxlayout1 = Qt.QHBoxLayout() ### self.hboxlayout1.setObjectName("hboxlayout1") ### ### self.TaurusValueLineEdit_21 = TaurusValueLineEdit(self) ### self.TaurusValueLineEdit_21.setUseParentModel(True) ### self.TaurusValueLineEdit_21.setObjectName("TaurusValueLineEdit_21") ### self.hboxlayout1.addWidget(self.TaurusValueLineEdit_21) ### ### self.config = Qt.QToolButton(self) ### self.config.setObjectName("config") ### self.hboxlayout1.addWidget(self.config) ### self.vboxlayout.addLayout(self.hboxlayout1) ### ### self.hboxlayout2 = Qt.QHBoxLayout() ### self.hboxlayout2.setObjectName("hboxlayout2") ### ### self.taurusValueLabel_21 = TaurusValueLabel(self) ### self.taurusValueLabel_21.setUseParentModel(True) ### self.taurusValueLabel_21.setObjectName("taurusValueLabel_21") ### self.hboxlayout2.addWidget(self.taurusValueLabel_21) ### ### self.taurusConfigLabel_18 = TaurusConfigLabel(self) ### self.taurusConfigLabel_18.setMaximumSize(Qt.QSize(27,22)) ### self.taurusConfigLabel_18.setUseParentModel(True) ### self.taurusConfigLabel_18.setObjectName("taurusConfigLabel_18") ### self.hboxlayout2.addWidget(self.taurusConfigLabel_18) ### self.vboxlayout.addLayout(self.hboxlayout2) ### ### self.hboxlayout3 = Qt.QHBoxLayout() ### self.hboxlayout3.setObjectName("hboxlayout3") ### ### self.TaurusLimitSwitch = TaurusLimitSwitch(self) ### self.TaurusLimitSwitch.setUseParentModel(True) ### self.TaurusLimitSwitch.setBoolIndex(2) ### self.TaurusLimitSwitch.setObjectName("TaurusLimitSwitch") ### self.hboxlayout3.addWidget(self.TaurusLimitSwitch) ### ### self.label_3 = Qt.QLabel(self) ### self.label_3.setAlignment(Qt.Qt.AlignCenter) ### self.label_3.setObjectName("label_3") ### self.hboxlayout3.addWidget(self.label_3) ### ### self.TaurusLimitSwitch_2 = TaurusLimitSwitch(self) ### self.TaurusLimitSwitch_2.setUseParentModel(True) ### self.TaurusLimitSwitch_2.setBoolIndex(1) ### self.TaurusLimitSwitch_2.setObjectName("TaurusLimitSwitch_2") ### self.hboxlayout3.addWidget(self.TaurusLimitSwitch_2) ### self.vboxlayout.addLayout(self.hboxlayout3) ### self.gridlayout.addLayout(self.vboxlayout,0,0,1,1) ### ### ### def retranslateUi(self): ### self.taurusValueLabel_2.setModel(Qt.QApplication.translate("Form", "/State", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusStateLed_17.setModel(Qt.QApplication.translate("Form", "/State", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusValueLineEdit_21.setModel(Qt.QApplication.translate("Form", "/Position", None, Qt.QApplication.UnicodeUTF8)) ### self.config.setText(Qt.QApplication.translate("Form", "cfg", None, Qt.QApplication.UnicodeUTF8)) ### self.taurusValueLabel_21.setModel(Qt.QApplication.translate("Form", "/Position", None, Qt.QApplication.UnicodeUTF8)) ### self.taurusConfigLabel_18.setModel(Qt.QApplication.translate("Form", "/Position?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch.setModel(Qt.QApplication.translate("Form", "/Limit_switches", None, Qt.QApplication.UnicodeUTF8)) ### self.label_3.setText(Qt.QApplication.translate("Form", "- lim +", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch_2.setModel(Qt.QApplication.translate("Form", "/Limit_switches", None, Qt.QApplication.UnicodeUTF8)) ### ### ############################################################################## ### ## VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ### ## ### ## I CAN NOT INHERIT FROM TAUGROUPBOX ! ### ## SO ALL THE STUFF BELOW IS NECESSARY ### ### ### ### def defineStyle(self): ### palette = Qt.QPalette() ### self.setPalette(palette) ### self.updateStyle() ### ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### # TaurusBaseWidget over writing ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### ### def getDisplayValue(self): ### return (self._prefix or '') + TaurusBaseWidget.getDisplayValue(self) + (self._suffix or '') ### ### def isReadOnly(self): ### return True ### ### def updateStyle(self): ### if self.getShowQuality(): ### self.setAutoFillBackground(True) ### #TODO: get quality/state from model and update accordingly ### else: ### self.setAutoFillBackground(False) ### #TODO: restore colors ### self.update() ### ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### # QT properties ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### ### def getPrefixText(self): ### return self._prefix ### ### @Qt.pyqtSignature("setPrefixText(QString)") ### def setPrefixText(self,prefix): ### self._prefix = prefix ### self.fireValueChanged() ### ### def getSuffixText(self): ### return self._suffix ### ### @Qt.pyqtSignature("setSuffixText(QString)") ### def setSuffixText(self,suffix): ### self._suffix = suffix ### self.fireValueChanged() ### ### model = Qt.pyqtProperty("QString", TaurusBaseWidget.getModel, ### TaurusBaseWidget.setModel, TaurusBaseWidget.resetModel) ### useParentModel = Qt.pyqtProperty("bool", TaurusBaseWidget.getUseParentModel, ### TaurusBaseWidget.setUseParentModel, ### TaurusBaseWidget.resetUseParentModel) ### showQuality = Qt.pyqtProperty("bool", TaurusBaseWidget.getShowQuality, ### TaurusBaseWidget.setShowQuality, ### TaurusBaseWidget.resetShowQuality) ### showText = Qt.pyqtProperty("bool", TaurusBaseWidget.getShowText, ### TaurusBaseWidget.setShowText, ### TaurusBaseWidget.resetShowText) ### prefixText = Qt.pyqtProperty("QString", getPrefixText, setPrefixText, ### doc="prefix text (optional)") ### suffixText = Qt.pyqtProperty("QString", getSuffixText, setSuffixText, ### doc="suffix text (optional)") ### ### ### ###class TaurusMotorV2(Qt.QGroupBox, TaurusBaseWidget): ### ### def __init__(self, parent = None): ### name = "TaurusMotorV2" ### self._prefix = '' ### self._suffix = '' ### ### self.call__init__wo_kw(Qt.QGroupBox, parent) ### self.call__init__(TaurusBaseWidget, name) ### ### self.setObjectName(name) ### self.defineStyle() ### ### ### ## I CAN NOT INHERIT FROM TAUGROUPBOX ! ### ## SO ALL THE STUFFABOVE IS NECESSARY ### ## ### ## ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ### ############################################################################## ### ## ### #class TaurusMotorV2(TaurusGroupBox): ### #def __init__(self, parent = None): ### #self.call__init__wo_kw(TaurusGroupBox,parent) ### #self.call__init__(TaurusGroupBox,str(self.objectName())) ### self.setupUi() ### self.retranslateUi() ### ### ### def minimumSizeHint(self): ### return Qt.QSize(260,270) ### ### def sizeHint(self): ### return Qt.QSize(260,270) ### ### ### def setupUi(self): ### ### self.gridlayout = Qt.QGridLayout(self) ### self.gridlayout.setObjectName("gridlayout") ### ### self.m1StateLed_2 = TaurusStateLed(self) ### self.m1StateLed_2.setLedSize(24) ### self.m1StateLed_2.setUseParentModel(True) ### self.m1StateLed_2.setObjectName("m1StateLed_2") ### self.gridlayout.addWidget(self.m1StateLed_2,0,0,1,1) ### ### self.taurusValueLabel = TaurusValueLabel(self) ### self.taurusValueLabel.setFrameShape(Qt.QFrame.NoFrame) ### self.taurusValueLabel.setFrameShadow(Qt.QFrame.Plain) ### self.taurusValueLabel.setShowQuality(False) ### self.taurusValueLabel.setUseParentModel(True) ### self.taurusValueLabel.setObjectName("taurusValueLabel") ### self.gridlayout.addWidget(self.taurusValueLabel,0,1,1,1) ### ### self.TaurusLimitSwitch = TaurusLimitSwitch(self) ### self.TaurusLimitSwitch.setUseParentModel(True) ### self.TaurusLimitSwitch.setBoolIndex(2) ### self.TaurusLimitSwitch.setObjectName("TaurusLimitSwitch") ### self.gridlayout.addWidget(self.TaurusLimitSwitch,0,3,1,1) ### ### self.TaurusLimitSwitch_2 = TaurusLimitSwitch(self) ### self.TaurusLimitSwitch_2.setUseParentModel(True) ### self.TaurusLimitSwitch_2.setBoolIndex(1) ### self.TaurusLimitSwitch_2.setObjectName("TaurusLimitSwitch_2") ### self.gridlayout.addWidget(self.TaurusLimitSwitch_2,0,4,1,1) ### ### self.m1PositionLabel_2 = TaurusConfigLabel(self) ### self.m1PositionLabel_2.setUseParentModel(True) ### self.m1PositionLabel_2.setObjectName("m1PositionLabel_2") ### self.gridlayout.addWidget(self.m1PositionLabel_2,1,0,1,2) ### ### self.m1PositionEdit_2 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionEdit_2.sizePolicy().hasHeightForWidth()) ### self.m1PositionEdit_2.setSizePolicy(sizePolicy) ### self.m1PositionEdit_2.setUseParentModel(True) ### self.m1PositionEdit_2.setObjectName("m1PositionEdit_2") ### self.gridlayout.addWidget(self.m1PositionEdit_2,1,2,1,1) ### ### self.m1Position_2 = TaurusValueLabel(self) ### self.m1Position_2.setUseParentModel(True) ### self.m1Position_2.setObjectName("m1Position_2") ### self.gridlayout.addWidget(self.m1Position_2,1,3,1,2) ### ### self.m1PositionUnitLabel_2 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionUnitLabel_2.sizePolicy().hasHeightForWidth()) ### self.m1PositionUnitLabel_2.setSizePolicy(sizePolicy) ### self.m1PositionUnitLabel_2.setUseParentModel(True) ### self.m1PositionUnitLabel_2.setObjectName("m1PositionUnitLabel_2") ### self.gridlayout.addWidget(self.m1PositionUnitLabel_2,1,5,1,1) ### ### self.m1VelocityLabel_2 = TaurusConfigLabel(self) ### self.m1VelocityLabel_2.setUseParentModel(True) ### self.m1VelocityLabel_2.setObjectName("m1VelocityLabel_2") ### self.gridlayout.addWidget(self.m1VelocityLabel_2,2,0,1,2) ### ### self.m1VelocityEdit_2 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1VelocityEdit_2.sizePolicy().hasHeightForWidth()) ### self.m1VelocityEdit_2.setSizePolicy(sizePolicy) ### self.m1VelocityEdit_2.setUseParentModel(True) ### self.m1VelocityEdit_2.setObjectName("m1VelocityEdit_2") ### self.gridlayout.addWidget(self.m1VelocityEdit_2,2,2,1,1) ### ### self.m1Velocity_2 = TaurusValueLabel(self) ### self.m1Velocity_2.setUseParentModel(True) ### self.m1Velocity_2.setObjectName("m1Velocity_2") ### self.gridlayout.addWidget(self.m1Velocity_2,2,3,1,2) ### ### self.m1VelocityUnitLabel_2 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1VelocityUnitLabel_2.sizePolicy().hasHeightForWidth()) ### self.m1VelocityUnitLabel_2.setSizePolicy(sizePolicy) ### self.m1VelocityUnitLabel_2.setUseParentModel(True) ### self.m1VelocityUnitLabel_2.setObjectName("m1VelocityUnitLabel_2") ### self.gridlayout.addWidget(self.m1VelocityUnitLabel_2,2,5,1,1) ### ### self.m1PositionLabel_4 = TaurusConfigLabel(self) ### self.m1PositionLabel_4.setUseParentModel(True) ### self.m1PositionLabel_4.setObjectName("m1PositionLabel_4") ### self.gridlayout.addWidget(self.m1PositionLabel_4,3,0,1,2) ### ### self.m1PositionEdit_4 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionEdit_4.sizePolicy().hasHeightForWidth()) ### self.m1PositionEdit_4.setSizePolicy(sizePolicy) ### self.m1PositionEdit_4.setUseParentModel(True) ### self.m1PositionEdit_4.setObjectName("m1PositionEdit_4") ### self.gridlayout.addWidget(self.m1PositionEdit_4,3,2,1,1) ### ### self.m1Position_4 = TaurusValueLabel(self) ### self.m1Position_4.setUseParentModel(True) ### self.m1Position_4.setObjectName("m1Position_4") ### self.gridlayout.addWidget(self.m1Position_4,3,3,1,2) ### ### self.m1PositionUnitLabel_4 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionUnitLabel_4.sizePolicy().hasHeightForWidth()) ### self.m1PositionUnitLabel_4.setSizePolicy(sizePolicy) ### self.m1PositionUnitLabel_4.setUseParentModel(True) ### self.m1PositionUnitLabel_4.setObjectName("m1PositionUnitLabel_4") ### self.gridlayout.addWidget(self.m1PositionUnitLabel_4,3,5,1,1) ### ### self.m1AccelerationLabel_2 = TaurusConfigLabel(self) ### self.m1AccelerationLabel_2.setUseParentModel(True) ### self.m1AccelerationLabel_2.setObjectName("m1AccelerationLabel_2") ### self.gridlayout.addWidget(self.m1AccelerationLabel_2,4,0,1,2) ### ### self.m1AccelerationEdit_2 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1AccelerationEdit_2.sizePolicy().hasHeightForWidth()) ### self.m1AccelerationEdit_2.setSizePolicy(sizePolicy) ### self.m1AccelerationEdit_2.setUseParentModel(True) ### self.m1AccelerationEdit_2.setObjectName("m1AccelerationEdit_2") ### self.gridlayout.addWidget(self.m1AccelerationEdit_2,4,2,1,1) ### ### self.m1Acceleration_2 = TaurusValueLabel(self) ### self.m1Acceleration_2.setUseParentModel(True) ### self.m1Acceleration_2.setObjectName("m1Acceleration_2") ### self.gridlayout.addWidget(self.m1Acceleration_2,4,3,1,2) ### ### self.m1AccelerationUnitLabel_2 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1AccelerationUnitLabel_2.sizePolicy().hasHeightForWidth()) ### self.m1AccelerationUnitLabel_2.setSizePolicy(sizePolicy) ### self.m1AccelerationUnitLabel_2.setUseParentModel(True) ### self.m1AccelerationUnitLabel_2.setObjectName("m1AccelerationUnitLabel_2") ### self.gridlayout.addWidget(self.m1AccelerationUnitLabel_2,4,5,1,1) ### ### self.m1PositionLabel_5 = TaurusConfigLabel(self) ### self.m1PositionLabel_5.setUseParentModel(True) ### self.m1PositionLabel_5.setObjectName("m1PositionLabel_5") ### self.gridlayout.addWidget(self.m1PositionLabel_5,5,0,1,2) ### ### self.m1PositionEdit_5 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionEdit_5.sizePolicy().hasHeightForWidth()) ### self.m1PositionEdit_5.setSizePolicy(sizePolicy) ### self.m1PositionEdit_5.setUseParentModel(True) ### self.m1PositionEdit_5.setObjectName("m1PositionEdit_5") ### self.gridlayout.addWidget(self.m1PositionEdit_5,5,2,1,1) ### ### self.m1Position_5 = TaurusValueLabel(self) ### self.m1Position_5.setUseParentModel(True) ### self.m1Position_5.setObjectName("m1Position_5") ### self.gridlayout.addWidget(self.m1Position_5,5,3,1,2) ### ### self.m1PositionUnitLabel_5 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionUnitLabel_5.sizePolicy().hasHeightForWidth()) ### self.m1PositionUnitLabel_5.setSizePolicy(sizePolicy) ### self.m1PositionUnitLabel_5.setUseParentModel(True) ### self.m1PositionUnitLabel_5.setObjectName("m1PositionUnitLabel_5") ### self.gridlayout.addWidget(self.m1PositionUnitLabel_5,5,5,1,1) ### ### self.m1DecelerationLabel_2 = TaurusConfigLabel(self) ### self.m1DecelerationLabel_2.setUseParentModel(True) ### self.m1DecelerationLabel_2.setObjectName("m1DecelerationLabel_2") ### self.gridlayout.addWidget(self.m1DecelerationLabel_2,6,0,1,2) ### ### self.m1DecelerationEdit_2 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1DecelerationEdit_2.sizePolicy().hasHeightForWidth()) ### self.m1DecelerationEdit_2.setSizePolicy(sizePolicy) ### self.m1DecelerationEdit_2.setUseParentModel(True) ### self.m1DecelerationEdit_2.setObjectName("m1DecelerationEdit_2") ### self.gridlayout.addWidget(self.m1DecelerationEdit_2,6,2,1,1) ### ### self.m1Deceleration_2 = TaurusValueLabel(self) ### self.m1Deceleration_2.setUseParentModel(True) ### self.m1Deceleration_2.setObjectName("m1Deceleration_2") ### self.gridlayout.addWidget(self.m1Deceleration_2,6,3,1,2) ### ### self.m1DecelerationUnitLabel_2 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1DecelerationUnitLabel_2.sizePolicy().hasHeightForWidth()) ### self.m1DecelerationUnitLabel_2.setSizePolicy(sizePolicy) ### self.m1DecelerationUnitLabel_2.setUseParentModel(True) ### self.m1DecelerationUnitLabel_2.setObjectName("m1DecelerationUnitLabel_2") ### self.gridlayout.addWidget(self.m1DecelerationUnitLabel_2,6,5,1,1) ### ### self.m1PositionLabel_6 = TaurusConfigLabel(self) ### self.m1PositionLabel_6.setUseParentModel(True) ### self.m1PositionLabel_6.setObjectName("m1PositionLabel_6") ### self.gridlayout.addWidget(self.m1PositionLabel_6,7,0,1,2) ### ### self.m1PositionEdit_6 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionEdit_6.sizePolicy().hasHeightForWidth()) ### self.m1PositionEdit_6.setSizePolicy(sizePolicy) ### self.m1PositionEdit_6.setUseParentModel(True) ### self.m1PositionEdit_6.setObjectName("m1PositionEdit_6") ### self.gridlayout.addWidget(self.m1PositionEdit_6,7,2,1,1) ### ### self.m1Position_6 = TaurusValueLabel(self) ### self.m1Position_6.setUseParentModel(True) ### self.m1Position_6.setObjectName("m1Position_6") ### self.gridlayout.addWidget(self.m1Position_6,7,3,1,2) ### ### self.m1PositionUnitLabel_6 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1PositionUnitLabel_6.sizePolicy().hasHeightForWidth()) ### self.m1PositionUnitLabel_6.setSizePolicy(sizePolicy) ### self.m1PositionUnitLabel_6.setUseParentModel(True) ### self.m1PositionUnitLabel_6.setObjectName("m1PositionUnitLabel_6") ### self.gridlayout.addWidget(self.m1PositionUnitLabel_6,7,5,1,1) ### ### self.m1StepPerUnitLabel_2 = TaurusConfigLabel(self) ### self.m1StepPerUnitLabel_2.setUseParentModel(True) ### self.m1StepPerUnitLabel_2.setObjectName("m1StepPerUnitLabel_2") ### self.gridlayout.addWidget(self.m1StepPerUnitLabel_2,8,0,1,2) ### ### self.m1StepPerUnitEdit_2 = TaurusValueLineEdit(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed,Qt.QSizePolicy.Fixed) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1StepPerUnitEdit_2.sizePolicy().hasHeightForWidth()) ### self.m1StepPerUnitEdit_2.setSizePolicy(sizePolicy) ### self.m1StepPerUnitEdit_2.setUseParentModel(True) ### self.m1StepPerUnitEdit_2.setObjectName("m1StepPerUnitEdit_2") ### self.gridlayout.addWidget(self.m1StepPerUnitEdit_2,8,2,1,1) ### ### self.m1StepPerUnit_2 = TaurusValueLabel(self) ### self.m1StepPerUnit_2.setUseParentModel(True) ### self.m1StepPerUnit_2.setObjectName("m1StepPerUnit_2") ### self.gridlayout.addWidget(self.m1StepPerUnit_2,8,3,1,2) ### ### self.m1StepPerUnitUnitLabel_2 = TaurusConfigLabel(self) ### ### sizePolicy = Qt.QSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Preferred) ### sizePolicy.setHorizontalStretch(0) ### sizePolicy.setVerticalStretch(0) ### sizePolicy.setHeightForWidth(self.m1StepPerUnitUnitLabel_2.sizePolicy().hasHeightForWidth()) ### self.m1StepPerUnitUnitLabel_2.setSizePolicy(sizePolicy) ### self.m1StepPerUnitUnitLabel_2.setUseParentModel(True) ### self.m1StepPerUnitUnitLabel_2.setObjectName("m1StepPerUnitUnitLabel_2") ### self.gridlayout.addWidget(self.m1StepPerUnitUnitLabel_2,8,5,1,1) ### ### ### def retranslateUi(self): ### self.m1StateLed_2.setModel(Qt.QApplication.translate("Dialog", "/State", None, Qt.QApplication.UnicodeUTF8)) ### self.taurusValueLabel.setModel(Qt.QApplication.translate("Dialog", "/State", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch.setLedColor(Qt.QApplication.translate("Dialog", "ORANGE", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch.setModel(Qt.QApplication.translate("Dialog", "/Limit_switches", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch_2.setLedColor(Qt.QApplication.translate("Dialog", "ORANGE", None, Qt.QApplication.UnicodeUTF8)) ### self.TaurusLimitSwitch_2.setModel(Qt.QApplication.translate("Dialog", "/Limit_switches", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_2.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Position?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionEdit_2.setModel(Qt.QApplication.translate("Dialog", "/Position", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Position_2.setModel(Qt.QApplication.translate("Dialog", "/Position", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionUnitLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Position?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1VelocityLabel_2.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1VelocityLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Velocity?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1VelocityEdit_2.setModel(Qt.QApplication.translate("Dialog", "/Velocity", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Velocity_2.setModel(Qt.QApplication.translate("Dialog", "/Velocity", None, Qt.QApplication.UnicodeUTF8)) ### self.m1VelocityUnitLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Velocity?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_4.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_4.setModel(Qt.QApplication.translate("Dialog", "/Acceleration?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionEdit_4.setModel(Qt.QApplication.translate("Dialog", "/Acceleration", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Position_4.setModel(Qt.QApplication.translate("Dialog", "/Acceleration", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionUnitLabel_4.setModel(Qt.QApplication.translate("Dialog", "/Acceleration?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1AccelerationLabel_2.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1AccelerationLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Deceleration?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1AccelerationEdit_2.setModel(Qt.QApplication.translate("Dialog", "/Deceleration", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Acceleration_2.setModel(Qt.QApplication.translate("Dialog", "/Deceleration", None, Qt.QApplication.UnicodeUTF8)) ### self.m1AccelerationUnitLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Deceleration?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_5.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_5.setModel(Qt.QApplication.translate("Dialog", "/Offset?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionEdit_5.setModel(Qt.QApplication.translate("Dialog", "/Offset", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Position_5.setModel(Qt.QApplication.translate("Dialog", "/Offset", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionUnitLabel_5.setModel(Qt.QApplication.translate("Dialog", "/Offset?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1DecelerationLabel_2.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1DecelerationLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Base_rate?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1DecelerationEdit_2.setModel(Qt.QApplication.translate("Dialog", "/Base_rate", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Deceleration_2.setModel(Qt.QApplication.translate("Dialog", "/Base_rate", None, Qt.QApplication.UnicodeUTF8)) ### self.m1DecelerationUnitLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Base_rate?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_6.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionLabel_6.setModel(Qt.QApplication.translate("Dialog", "/Step_per_unit?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionEdit_6.setModel(Qt.QApplication.translate("Dialog", "/Step_per_unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1Position_6.setModel(Qt.QApplication.translate("Dialog", "/Step_per_unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1PositionUnitLabel_6.setModel(Qt.QApplication.translate("Dialog", "/Step_per_unit?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### self.m1StepPerUnitLabel_2.setSuffixText(Qt.QApplication.translate("Dialog", ":", None, Qt.QApplication.UnicodeUTF8)) ### self.m1StepPerUnitLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Backlash?configuration=label", None, Qt.QApplication.UnicodeUTF8)) ### self.m1StepPerUnitEdit_2.setModel(Qt.QApplication.translate("Dialog", "/Backlash", None, Qt.QApplication.UnicodeUTF8)) ### self.m1StepPerUnit_2.setModel(Qt.QApplication.translate("Dialog", "/Backlash", None, Qt.QApplication.UnicodeUTF8)) ### self.m1StepPerUnitUnitLabel_2.setModel(Qt.QApplication.translate("Dialog", "/Backlash?configuration=unit", None, Qt.QApplication.UnicodeUTF8)) ### ### ############################################################################## ### ## VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ### ## ### ## I CAN NOT INHERIT FROM TAUGROUPBOX ! ### ## SO ALL THE STUFF BELOW IS NECESSARY ### ### ### ### def defineStyle(self): ### palette = Qt.QPalette() ### self.setPalette(palette) ### self.updateStyle() ### ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### # TaurusBaseWidget over writing ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### ### def getDisplayValue(self): ### return (self._prefix or '') + TaurusBaseWidget.getDisplayValue(self) + (self._suffix or '') ### ### def isReadOnly(self): ### return True ### ### def updateStyle(self): ### if self.getShowQuality(): ### self.setAutoFillBackground(True) ### #TODO: get quality/state from model and update accordingly ### else: ### self.setAutoFillBackground(False) ### #TODO: restore colors ### self.update() ### ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### # QT properties ### #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ### ### def getPrefixText(self): ### return self._prefix ### ### @Qt.pyqtSignature("setPrefixText(QString)") ### def setPrefixText(self,prefix): ### self._prefix = prefix ### self.fireValueChanged() ### ### def getSuffixText(self): ### return self._suffix ### ### @Qt.pyqtSignature("setSuffixText(QString)") ### def setSuffixText(self,suffix): ### self._suffix = suffix ### self.fireValueChanged() ### ### model = Qt.pyqtProperty("QString", TaurusBaseWidget.getModel, ### TaurusBaseWidget.setModel, TaurusBaseWidget.resetModel) ### useParentModel = Qt.pyqtProperty("bool", TaurusBaseWidget.getUseParentModel, ### TaurusBaseWidget.setUseParentModel, ### TaurusBaseWidget.resetUseParentModel) ### showQuality = Qt.pyqtProperty("bool", TaurusBaseWidget.getShowQuality, ### TaurusBaseWidget.setShowQuality, ### TaurusBaseWidget.resetShowQuality) ### showText = Qt.pyqtProperty("bool", TaurusBaseWidget.getShowText, ### TaurusBaseWidget.setShowText, ### TaurusBaseWidget.resetShowText) ### prefixText = Qt.pyqtProperty("QString", getPrefixText, setPrefixText, ### doc="prefix text (optional)") ### suffixText = Qt.pyqtProperty("QString", getSuffixText, setSuffixText, ### doc="suffix text (optional)") ### ### ### if __name__ == "__main__": import sys app = Qt.QApplication(sys.argv) form = TaurusMotorH() form.setModel(sys.argv[1]) form.show() sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/poolchannel.py0000644000234000017500000001053512555672637027330 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ channelWidgets.py: """ __all__ = ["PoolChannel", "PoolChannelTV"] import taurus from taurus.external.qt import Qt from taurus.qt.qtgui.panel import TaurusValue, TaurusDevButton from taurus.qt.qtgui.container import TaurusWidget from poolmotor import LabelWidgetDragsDeviceAndAttribute class _ParentDevButton(TaurusDevButton): '''A TaurusDevButton that receives an attribute name but sets the corresponding device as model. **For internal use only** ''' def __init__(self, **kwargs): TaurusDevButton.__init__(self, **kwargs) self.setText('') self.setSizePolicy(Qt.QSizePolicy.Preferred, Qt.QSizePolicy.Maximum) def setModel(self, model): try: attr = taurus.Attribute(model) except: return dev = attr.getParentObj() devname = dev.getFullName() TaurusDevButton.setModel(self, devname) class PoolChannelTV(TaurusValue): ''' A widget that displays and controls a pool channel device. It differs from :class:`PoolChannel` in that it behaves as a TaurusValue (i.e., it allows its subwidgets to be aligned in columns in a TaurusForm)` ''' def __init__(self, parent=None, designMode=False): TaurusValue.__init__(self, parent=parent, designMode=designMode) self.setLabelWidgetClass("LabelWidgetDragsDeviceAndAttribute") self.setLabelConfig('dev_alias') def getDefaultExtraWidgetClass(self): return _ParentDevButton def setModel(self, model): if model is not None: model = "%s/value" % model #@todo: change this (it assumes tango naming!) TaurusValue.setModel(self, model) def showEvent(self, event): TaurusValue.showEvent(self, event) try: self.getModelObj().getParentObj().getAttribute('Value').enablePolling(force=True) except: pass def hideEvent(self, event): TaurusValue.hideEvent(self, event) try: self.getModelObj().getParentObj().getAttribute('Value').disablePolling() except: pass class PoolChannel(TaurusWidget): ''' A widget that displays and controls a pool channel device .. seealso:: :class:`PoolChannelTV` ''' def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent) self.setLayout(Qt.QHBoxLayout()) #put a widget with a TaurusValue w = Qt.QWidget() w.setLayout(Qt.QGridLayout()) self._TaurusValue = TaurusValue(parent=w, designMode=designMode) self._TaurusValue.setLabelWidgetClass(LabelWidgetDragsDeviceAndAttribute) self._TaurusValue.setLabelConfig('dev_alias') self.layout().addWidget(w) #...and a dev button next to the widget self._devButton = TaurusDevButton(parent=self, designMode=designMode) self._devButton.setText('') self.layout().addWidget(self._devButton) self.connect(self, Qt.SIGNAL('modelChanged(const QString &)'), self._updateTaurusValue) def _updateTaurusValue(self): m = self.getModelName() self._TaurusValue.setModel("%s/value" % m) self._devButton.setModel(m) #if __name__ == '__main__': # import sys # app = Qt.QApplication(sys.argv) # # form = PoolChannel() # # #model = 'tango://controls02:10000/expchan/bl97_simucotictrl_1/1' # model = 'ct_cp1_1' # if len(sys.argv)>1: # model = sys.argv[1] # form.setModel(model) # # # form.show() # sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/poolioregister.py0000644000234000017500000002532712555672637030101 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """ poolioregister.py: """ __all__ = ["PoolIORegisterTV", "PoolIORegister", 'PoolIORegisterButtons'] from taurus.external.qt import Qt from taurus.qt.qtgui.display import TaurusLabel from taurus.core.util.eventfilters import EventValueMap from taurus.qt.qtgui.input import TaurusValueComboBox from taurus.qt.qtgui.panel import TaurusValue from taurus.qt.qtgui.container import TaurusWidget from taurus.qt.qtgui.util.ui import UILoadable from poolmotor import LabelWidgetDragsDeviceAndAttribute import taurus class PoolIORegisterReadWidget(TaurusLabel): ''' This class is intended to be used as a read widget of a TaurusValue with IORegister devices. After setting the model, it gets the Labels and creates a filter to show them instead of the values. ''' def __init__(self, parent=None, designMode=False): TaurusLabel.__init__(self, parent, designMode) def setModel(self, model): TaurusLabel.setModel(self, '%s/value' % model) #@todo: change this (it assumes tango naming!) try: ior_dev = taurus.Device(model) except: return labels = ior_dev.getAttribute('Labels').read().value labels_list = labels.split(' ') # Update the mapping self.readEventValueMap = EventValueMap() for label_and_value in labels_list: label, value = label_and_value.split(':') self.readEventValueMap[int(value)] = label # @TODO: Some day filters will work again... # until then, it is better to NOT have the filter # so at least we see a value and not '------' #self.setEventFilters([self.readEventValueMap]) ########################################################## # FILTERS ARE NOT WORKING AS OF SVN:17541 # SO I RE-IMPLEMENT getFormatedToolTip for this purpose ########################################################## def getFormatedToolTip(self, cache=True): taurus_label_tooltip = TaurusLabel.getFormatedToolTip(self, cache) try: display_value = int(self.getDisplayValue()) extended_tooltip = '' value_keys = self.readEventValueMap.keys() value_keys.sort() for value in value_keys: label = self.readEventValueMap[value] value_label_info = '%d: %s' % (value, label) if value == display_value: value_label_info = '* ' + value_label_info + ' *' extended_tooltip += value_label_info + '
    ' return taurus_label_tooltip + '
    ' + extended_tooltip except: pass return taurus_label_tooltip ########################################################## @classmethod def getQtDesignerPluginInfo(cls): return None class PoolIORegisterWriteWidget(TaurusValueComboBox): ''' This class is intended to be used as a write widget of a TaurusValue with IORegister devices. After setting the model, it gets the Labels and populates the combobox. It has AutoApply set to True. ''' def __init__(self, parent=None, designMode=False): TaurusValueComboBox.__init__(self, parent, designMode) TaurusValueComboBox.setForcedApply(self, True) def setModel(self, model): TaurusValueComboBox.setModel(self, '%s/value' % model) #@todo: change this (it assumes tango naming!) try: ior_dev = taurus.Device(model) except: return labels = ior_dev.getAttribute('Labels').read().value labels_list = labels.split(' ') # Update the mapping self.writeValueNames = [] for label_and_value in labels_list: label, value = label_and_value.split(':') self.writeValueNames.append((label, value)) self.setValueNames(self.writeValueNames) @classmethod def getQtDesignerPluginInfo(cls): return None class PoolIORegisterTV(TaurusValue): ''' A widget that displays and controls a pool IORegister device. It behaves as a TaurusValue. ''' def __init__(self, parent=None, designMode=False): TaurusValue.__init__(self, parent=parent, designMode=designMode) self.setLabelWidgetClass("LabelWidgetDragsDeviceAndAttribute") self.setLabelConfig('dev_alias') self.setReadWidgetClass('PoolIORegisterReadWidget') self.setWriteWidgetClass('PoolIORegisterWriteWidget') self.ioreg_dev = None def setModel(self, model): TaurusValue.setModel(self, model) try: self.ioreg_dev = taurus.Device(model) except: return def showEvent(self, event): TaurusValue.showEvent(self, event) if self.ioreg_dev is not None: self.ioreg_dev.getAttribute('Value').enablePolling(force=True) def hideEvent(self, event): TaurusValue.hideEvent(self, event) if self.ioreg_dev is not None: self.ioreg_dev.getAttribute('Value').disablePolling() class PoolIORegister(TaurusWidget): ''' A widget that displays and controls a pool IORegister device. It reads the value and provides a combobox to write it. NOTE: It would be nice to provide 'ABORT' button if the device allows it. NOTE: It would be nice to set icons for each possible value label. ''' def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.ioreg_dev = None self.setLayout(Qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self.alias_label = TaurusLabel() self.alias_label.setBgRole('state') self.layout().addWidget(self.alias_label) self.read_widget = PoolIORegisterReadWidget() self.layout().addWidget(self.read_widget) self.write_widget = PoolIORegisterWriteWidget() self.layout().addWidget(self.write_widget) def setModel(self, model): try: self.ioreg_dev = taurus.Device(model) except: return self.alias_label.setModel('%s/State?configuration=dev_alias' % model) self.read_widget.setModel(model) self.write_widget.setModel(model) def showEvent(self, event): TaurusWidget.showEvent(self, event) if self.ioreg_dev is not None: self.ioreg_dev.getAttribute('Value').enablePolling(force=True) def hideEvent(self, event): TaurusWidget.hideEvent(self, event) if self.ioreg_dev is not None: self.ioreg_dev.getAttribute('Value').disablePolling() @UILoadable(with_ui='ui') class PoolIORegisterButtons(TaurusWidget): ''' A widget that displays and controls a pool IORegister device. It reads the value and provides buttons to switch between values. NOTE: It would be nice to provide 'ABORT' button if the device allows it. NOTE: It would be nice to set icons for each possible value label. ''' def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.loadUi() self.ioreg_dev = None self.alias_label = TaurusLabel() self.alias_label.setBgRole('state') self.value_label = PoolIORegisterReadWidget() self.button_value_dict = {} policy = self.value_label.sizePolicy() policy.setHorizontalPolicy(Qt.QSizePolicy.Expanding) self.value_label.setSizePolicy(policy) self.ui.lo_state_read.addWidget(self.alias_label) self.ui.lo_state_read.addWidget(self.value_label) def setModel(self, model): try: self.ioreg_dev = taurus.Device(model) except: return self.alias_label.setModel('%s/State?configuration=dev_alias' % model) self.value_label.setModel(model) # Empty previous buttons #self.ui.lo_buttons_write. for button in self.button_value_dict.keys(): self.disconnect(button, Qt.SIGNAL('clicked'), self.writeValue) button.deleteLater() self.button_value_dict = {} labels = self.ioreg_dev.getAttribute('Labels').read().value labels_list = labels.split(' ') # Update the mapping for label_and_value in labels_list: label, value = label_and_value.split(':') button = Qt.QPushButton(label) self.button_value_dict[button] = value self.ui.lo_buttons_write.addWidget(button) self.connect(button, Qt.SIGNAL('clicked()'), self.writeValue) def writeValue(self): if self.ioreg_dev is None: return button = self.sender() value = self.button_value_dict[button] self.ioreg_dev.getAttribute('Value').write(value) def showEvent(self, event): TaurusWidget.showEvent(self, event) if self.ioreg_dev is not None: self.ioreg_dev.getAttribute('Value').enablePolling(force=True) def hideEvent(self, event): TaurusWidget.hideEvent(self, event) if self.ioreg_dev is not None: self.ioreg_dev.getAttribute('Value').disablePolling() def test_form(): from taurus.qt.qtgui.panel import TaurusForm tgclass_map = {'IORegister':PoolIORegisterTV} form = TaurusForm() form.setCustomWidgetMap(tgclass_map) model = 'tango://controls02:10000/ioregister/gc_tgiorctrl/1' if len(sys.argv) > 1: model = sys.argv[1] form.setModel([model]) form.show() def test_widget(): w = PoolIORegister() model = 'tango://controls02:10000/ioregister/gc_tgiorctrl/1' if len(sys.argv) > 1: model = sys.argv[1] w.setModel(model) w.show() def test_buttons(): w = PoolIORegisterButtons() model = 'tango://controls02:10000/ioregister/gc_tgiorctrl/1' if len(sys.argv) > 1: model = sys.argv[1] w.setModel(model) w.show() if __name__ == '__main__': import sys app = Qt.QApplication(sys.argv) #test_form() #test_widget() test_buttons() sys.exit(app.exec_()) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_pool/poolmotor.py0000644000234000017500000021031412555672637027055 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 copy import PyTango import numpy from taurus.external.qt import Qt import taurus from taurus.core.util.colors import DEVICE_STATE_PALETTE from taurus.core.taurusbasetypes import TaurusEventType from taurus.core.taurusvalidator import DeviceNameValidator import taurus.qt.qtcore.mimetypes from taurus.qt.qtgui.base import TaurusBaseWritableWidget from taurus.qt.qtgui.compact import TaurusReadWriteSwitcher from taurus.qt.qtgui.dialog import ProtectTaurusMessageBox from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.container import TaurusWidget from taurus.qt.qtgui.container import TaurusFrame from taurus.qt.qtgui.display import TaurusLabel from taurus.qt.qtgui.input import TaurusValueLineEdit from taurus.qt.qtgui.input import TaurusValueSpinBox from taurus.qt.qtgui.panel import DefaultLabelWidget from taurus.qt.qtgui.panel import DefaultUnitsWidget from taurus.qt.qtgui.panel import TaurusValue, TaurusAttrForm from taurus.qt.qtcore.mimetypes import TAURUS_DEV_MIME_TYPE, TAURUS_ATTR_MIME_TYPE from taurus.qt.qtgui.resource import getIcon from taurus.qt.qtgui.util.ui import UILoadable class LimitsListener(Qt.QObject): """ A class that listens to changes on motor limits. If that is the case it emits a signal so the application can do whatever with it. """ def __init__(self): Qt.QObject.__init__(self) def eventReceived(self, evt_src, evt_type, evt_value): if evt_type not in [TaurusEventType.Change, TaurusEventType.Periodic]: return limits = evt_value.value self.emit(Qt.SIGNAL('updateLimits(PyQt_PyObject)'), limits.tolist()) class PoolMotorClient(): maxint_in_32_bits = 2147483647 def __init__(self): self.motor_dev = None self.has_limits = False self.has_encoder = False def setMotor(self, pool_motor_dev_name): # AT SOME POINT THIS WILL BE USING THE 'POOL' TAURUS EXTENSION # TO OPERATE THE MOTOR INSTEAD OF A 'TANGO' TAURUSDEVICE try: self.motor_dev = taurus.Device(pool_motor_dev_name) # IT IS IMPORTANT TO KNOW IF IT IS AN ICEPAP MOTOR, SO EXTRA FEATURES CAN BE PROVIDED # PENDING. self.has_limits = hasattr(self.motor_dev, 'Limit_Switches') self.has_encoder = hasattr(self.motor_dev, 'Encoder') except Exception, e: taurus.warning('Exception Creating Motor Device %s', str(e)) def moveMotor(self, pos): #self.motor_dev['position'] = pos # Make use of Taurus operations (being logged) self.motor_dev.getAttribute('Position').write(pos) def moveInc(self, inc): self.moveMotor(self.motor_dev['position'].value + inc) def jogNeg(self): neg_limit = -((self.maxint_in_32_bits / 2) - 1) # THERE IS A BUG IN THE ICEPAP THAT DOES NOT ALLOW MOVE ABSOLUTE FURTHER THAN 32 BIT # SO IF THERE ARE STEPS PER UNIT, max_int HAS TO BE REDUCED if hasattr(self.motor_dev, 'step_per_unit'): neg_limit = neg_limit / self.motor_dev['step_per_unit'].value try: min_value = self.motor_dev.getAttribute('Position').getConfig().getValueObj().min_value neg_limit = float(min_value) except Exception: pass self.moveMotor(neg_limit) def jogPos(self): pos_limit = (self.maxint_in_32_bits / 2) - 1 # THERE IS A BUG IN THE ICEPAP THAT DOES NOT ALLOW MOVE ABSOLUTE FURTHER THAN 32 BIT # SO IF THERE ARE STEPS PER UNIT, max_int HAS TO BE REDUCED if hasattr(self.motor_dev, 'step_per_unit'): pos_limit = pos_limit / self.motor_dev['step_per_unit'].value try: max_value = self.motor_dev.getAttribute('Position').getConfig().getValueObj().max_value pos_limit = float(max_value) except Exception: pass self.moveMotor(pos_limit) def goHome(self): pass def abort(self): self.motor_dev.abort() class LabelWidgetDragsDeviceAndAttribute(DefaultLabelWidget): """ Offer richer mime data with taurus-device, taurus-attribute, and plain-text. """ def mouseMoveEvent(self, event): model = self.taurusValueBuddy().getModelName() mimeData = Qt.QMimeData() mimeData.setText(self.text()) attr_name = model dev_name = model.rpartition('/')[0] mimeData.setData(TAURUS_DEV_MIME_TYPE, dev_name) mimeData.setData(TAURUS_ATTR_MIME_TYPE, attr_name) drag = Qt.QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(event.pos() - self.rect().topLeft()) drag.start(Qt.Qt.CopyAction) class PoolMotorConfigurationForm(TaurusAttrForm): def __init__(self, parent=None, designMode=False): TaurusAttrForm.__init__(self, parent, designMode) self._form.setWithButtons(False) def getMotorControllerType(self): modelObj = self.getModelObj() modelNormalName = modelObj.getNormalName() poolDsId = modelObj.getHWObj().info().server_id db = taurus.Database() pool_devices = tuple(db.get_device_class_list(poolDsId).value_string) pool_dev_name = pool_devices[pool_devices.index('Pool') - 1] pool = taurus.Device(pool_dev_name) poolMotorInfos = pool["MotorList"].value for motorInfo in poolMotorInfos: # BE CAREFUL, THIS ONLY WORKS IF NOBODY CHANGES THE DEVICE NAME OF A MOTOR!!! # ALSO THERE COULD BE A CASE PROBLEM, BETTER DO COMPARISONS WITH .lower() #to better understand following actions #this is an example of one motor info record #'dummymotor10 (motor/dummymotorctrl/10) (dummymotorctrl/10) Motor', motorInfos = motorInfo.split() if modelNormalName.lower() == motorInfos[1][1:-1].lower(): controllerName = motorInfos[2][1:-1].split("/")[0] poolControllerInfos = pool["ControllerList"].value for controllerInfo in poolControllerInfos: #to better understand following actions #this is an example of one controller info record #'dummymotorctrl (DummyMotorController.DummyMotorController/dummymotorctrl) - Motor Python ctrl (DummyMotorController.py)' controllerInfos = controllerInfo.split() if controllerName.lower() == controllerInfos[0].lower(): controllerType = controllerInfos[1][1:-1].split("/")[0] return controllerType def getDisplayAttributes(self, controllerType): attributes = ['position', 'state', 'status', 'velocity', 'acceleration', 'base_rate', 'step_per_unit', 'dialposition', 'sign', 'offset', 'backlash'] if controllerType == "IcePAPCtrl.IcepapController": attributes.insert(1, "encoder") attributes.extend(['frequency', 'poweron', 'closedloop', 'useencodersource', 'encodersource', 'encodersourceformula', 'statusstopcode', 'statusdisable', 'statusready', 'statuslim-', 'statuslim+', 'statushome']) elif controllerType == "PmacCtrl.PmacController": attributes.extend(["motoractivated", "negativeendlimitset", "positiveendlimitset", "handwheelenabled", "phasedmotor", "openloopmode", "runningdefine-timemove", "integrationmode", "dwellinprogress", "datablockerror", "desiredvelocityzero", "abortdeceleration", "blockrequest", "homesearchinprogress", "assignedtocoordinatesystem", "coordinatesystem", "amplifierenabled", "stoppedonpositionlimit", "homecomplete", "phasingsearcherror", "triggermove", "integratedfatalfollowingerror", "i2t_amplifierfaulterror", "backlashdirectionflag", "amplifierfaulterror", "fatalfollowingerror", "warningfollowingerror", "inposition", "motionprogramrunning"]) elif controllerType == "TurboPmacCtrl.TurboPmacController": attributes.extend(["motoractivated", "negativeendlimitset", "positiveendlimitset", "extendedservoalgorithmenabled" "amplifierenabled", "openloopmode", "movetimeractive", "integrationmode", "dwellinprogress", "datablockerror", "desiredvelocityzero", "abortdeceleration", "blockrequest", "homesearchinprogress", "user-writtenphaseenable", "user-writtenservoenable", "alternatesource/destination", "phasedmotor", "followingoffsetmode", "followingenabled", "errortriger", "softwarepositioncapture", "integratorinvelocityloop", "alternatecommand-outputmode", "coordinatesystem", "coordinatedefinition", "assignedtocoordinatesystem", "foregroundinposition", "stoppedondesiredpositionlimit", "stoppedonpositionlimit", "homecomplete", "phasing_search/read_active", "triggermove", "integratedfatalfollowingerror", "i2t_amplifierfaulterror", "backlashdirectionflag", "amplifierfaulterror", "fatalfollowingerror", "warningfollowingerror", "inposition"]) return attributes def setModel(self, modelName): TaurusAttrForm.setModel(self, modelName) controllerType = self.getMotorControllerType() attributes = self.getDisplayAttributes(controllerType) #self.setViewFilters([lambda a: a.name.lower() in attributes]) self.setSortKey(lambda att: attributes.index(att.name.lower()) if att.name.lower() in attributes else 1) @UILoadable(with_ui='ui') class PoolMotorSlim(TaurusWidget, PoolMotorClient): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent) #self.call__init__wo_kw(Qt.QWidget, parent) #self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) PoolMotorClient.__init__(self) self.loadUi() self.show_context_menu = True self.setAcceptDrops(True) if designMode: self.__setTaurusIcons() return # CREATE THE TaurusValue that can not be configured in the Designer self.taurus_value = TaurusValue(self.ui.taurusValueContainer) # Use a DragDevAndAttributeLabelWidget to provide a richer QMimeData content self.taurus_value.setLabelWidgetClass(LabelWidgetDragsDeviceAndAttribute) # Make the label to be the device alias self.taurus_value.setLabelConfig('dev_alias') self.taurus_value_enc = TaurusValue(self.ui.taurusValueContainer) # THIS WILL BE DONE IN THE DESIGNER # Config Button will launch a PoolMotorConfigurationForm # 19.08.2011 after discussion between cpascual, gcui and zreszela, Configuration Panel was rolled back to # standard TaurusAttrForm - list of all attributes alphabetically ordered # taurus_attr_form = PoolMotorConfigurationForm() taurus_attr_form = TaurusAttrForm() taurus_attr_form.setMinimumSize(Qt.QSize(470, 800)) self.ui.btnCfg.setWidget(taurus_attr_form) self.ui.btnCfg.setUseParentModel(True) # ADD AN EVENT FILTER FOR THE STATUS LABEL IN ORDER TO PROVIDE JUST THE STRING FROM THE CONTROLLER (LAST LINE) def just_ctrl_status_line(evt_src, evt_type, evt_value): if evt_type not in [TaurusEventType.Change, TaurusEventType.Periodic]: return evt_src, evt_type, evt_value try: status = evt_value.value last_line = status.split('\n')[-1] new_evt_value = PyTango.DeviceAttribute(evt_value) new_evt_value.value = last_line return evt_src, evt_type, new_evt_value except: return evt_src, evt_type, evt_value self.ui.lblStatus.insertEventFilter(just_ctrl_status_line) # These buttons are just for showing if the limit is active or not self.ui.btnMin.setEnabled(False) self.ui.btnMax.setEnabled(False) # HOMING NOT IMPLMENTED YET self.ui.btnHome.setEnabled(False) # DEFAULT VISIBLE COMPONENTS self.toggleHideAll() self.toggleMoveAbsolute(True) self.toggleStopMove(True) # SET TAURUS ICONS self.__setTaurusIcons() self.ui.motorGroupBox.setContextMenuPolicy(Qt.Qt.CustomContextMenu) self.connect(self.ui.motorGroupBox, Qt.SIGNAL('customContextMenuRequested(QPoint)'), self.buildContextMenu) self.connect(self.ui.btnGoToNeg, Qt.SIGNAL('clicked()'), self.jogNeg) self.connect(self.ui.btnGoToNegPress, Qt.SIGNAL('pressed()'), self.jogNeg) self.connect(self.ui.btnGoToNegPress, Qt.SIGNAL('released()'), self.abort) self.connect(self.ui.btnGoToNegInc, Qt.SIGNAL('clicked()'), self.goToNegInc) self.connect(self.ui.btnGoToPos, Qt.SIGNAL('clicked()'), self.jogPos) self.connect(self.ui.btnGoToPosPress, Qt.SIGNAL('pressed()'), self.jogPos) self.connect(self.ui.btnGoToPosPress, Qt.SIGNAL('released()'), self.abort) self.connect(self.ui.btnGoToPosInc, Qt.SIGNAL('clicked()'), self.goToPosInc) self.connect(self.ui.btnHome, Qt.SIGNAL('clicked()'), self.goHome) self.connect(self.ui.btnStop, Qt.SIGNAL('clicked()'), self.abort) # ALSO UPDATE THE WIDGETS EVERYTIME THE FORM HAS TO BE SHOWN self.connect(self.ui.btnCfg, Qt.SIGNAL('clicked()'), taurus_attr_form._updateAttrWidgets) self.connect(self.ui.btnCfg, Qt.SIGNAL('clicked()'), self.buildBetterCfgDialogTitle) ################################################################################################################# ######################################## # LET TAURUS CONFIGURATION MECANISM SHINE! ######################################## self.registerConfigProperty(self.ui.inc.isVisible, self.toggleMoveRelative, 'MoveRelative') self.registerConfigProperty(self.ui.btnGoToNegPress.isVisible, self.toggleMoveContinuous, 'MoveContinuous') self.registerConfigProperty(self.ui.btnGoToNeg.isVisible, self.toggleMoveToLimits, 'MoveToLimits') self.registerConfigProperty(self.ui.btnStop.isVisible, self.toggleStopMove, 'StopMove') self.registerConfigProperty(self.ui.btnHome.isVisible, self.toggleHoming, 'Homing') self.registerConfigProperty(self.ui.btnCfg.isVisible, self.toggleConfig, 'Config') self.registerConfigProperty(self.ui.lblStatus.isVisible, self.toggleStatus, 'Status') ################################################################################################################# def __setTaurusIcons(self): self.ui.btnMin.setText('') self.ui.btnMin.setIcon(getIcon(':/actions/list-remove.svg')) self.ui.btnMax.setText('') self.ui.btnMax.setIcon(getIcon(':/actions/list-add.svg')) self.ui.btnGoToNeg.setText('') self.ui.btnGoToNeg.setIcon(getIcon(':/actions/media_skip_backward.svg')) self.ui.btnGoToNegPress.setText('') self.ui.btnGoToNegPress.setIcon(getIcon(':/actions/media_seek_backward.svg')) self.ui.btnGoToNegInc.setText('') self.ui.btnGoToNegInc.setIcon(getIcon(':/actions/media_playback_backward.svg')) self.ui.btnGoToPos.setText('') self.ui.btnGoToPos.setIcon(getIcon(':/actions/media_skip_forward.svg')) self.ui.btnGoToPosPress.setText('') self.ui.btnGoToPosPress.setIcon(getIcon(':/actions/media_seek_forward.svg')) self.ui.btnGoToPosInc.setText('') self.ui.btnGoToPosInc.setIcon(getIcon(':/actions/media_playback_start.svg')) self.ui.btnStop.setText('') self.ui.btnStop.setIcon(getIcon(':/actions/media_playback_stop.svg')) self.ui.btnHome.setText('') self.ui.btnHome.setIcon(getIcon(':/actions/go-home.svg')) self.ui.btnCfg.setText('') self.ui.btnCfg.setIcon(getIcon(':/categories/preferences-system.svg')) ################################################################################################################# #@Qt.pyqtSlot(list) def updateLimits(self, limits): if isinstance(limits, dict): limits = limits["limits"] pos_lim = limits[1] pos_btnstylesheet = '' enabled = True if pos_lim: pos_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) enabled = False self.ui.btnMax.setStyleSheet(pos_btnstylesheet) self.ui.btnGoToPos.setEnabled(enabled) self.ui.btnGoToPosPress.setEnabled(enabled) self.ui.btnGoToPosInc.setEnabled(enabled) neg_lim = limits[2] neg_btnstylesheet = '' enabled = True if neg_lim: neg_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) enabled = False self.ui.btnMin.setStyleSheet(neg_btnstylesheet) self.ui.btnGoToNeg.setEnabled(enabled) self.ui.btnGoToNegPress.setEnabled(enabled) self.ui.btnGoToNegInc.setEnabled(enabled) #def sizeHint(self): # return Qt.QSize(300,30) def goToNegInc(self): self.moveInc(-1 * self.ui.inc.value()) def goToPosInc(self): self.moveInc(self.ui.inc.value()) def buildContextMenu(self, point): if not self.show_context_menu: return menu = Qt.QMenu(self) action_hide_all = Qt.QAction(self) action_hide_all.setText('Hide All') menu.addAction(action_hide_all) action_show_all = Qt.QAction(self) action_show_all.setText('Show All') menu.addAction(action_show_all) action_move_absolute = Qt.QAction(self) action_move_absolute.setText('Move Absolute') action_move_absolute.setCheckable(True) action_move_absolute.setChecked(self.taurus_value.writeWidget().isVisible()) menu.addAction(action_move_absolute) action_move_relative = Qt.QAction(self) action_move_relative.setText('Move Relative') action_move_relative.setCheckable(True) action_move_relative.setChecked(self.ui.inc.isVisible()) menu.addAction(action_move_relative) action_move_continuous = Qt.QAction(self) action_move_continuous.setText('Move Continuous') action_move_continuous.setCheckable(True) action_move_continuous.setChecked(self.ui.btnGoToNegPress.isVisible()) menu.addAction(action_move_continuous) action_move_to_limits = Qt.QAction(self) action_move_to_limits.setText('Move to Limits') action_move_to_limits.setCheckable(True) action_move_to_limits.setChecked(self.ui.btnGoToNeg.isVisible()) menu.addAction(action_move_to_limits) action_encoder = Qt.QAction(self) action_encoder.setText('Encoder Read') action_encoder.setCheckable(True) action_encoder.setChecked(self.taurus_value_enc.isVisible()) if self.has_encoder: menu.addAction(action_encoder) action_stop_move = Qt.QAction(self) action_stop_move.setText('Stop Movement') action_stop_move.setCheckable(True) action_stop_move.setChecked(self.ui.btnStop.isVisible()) menu.addAction(action_stop_move) action_homing = Qt.QAction(self) action_homing.setText('Homing') action_homing.setCheckable(True) action_homing.setChecked(self.ui.btnHome.isVisible()) menu.addAction(action_homing) action_config = Qt.QAction(self) action_config.setText('Config') action_config.setCheckable(True) action_config.setChecked(self.ui.btnCfg.isVisible()) menu.addAction(action_config) action_status = Qt.QAction(self) action_status.setText('Status') action_status.setCheckable(True) action_status.setChecked(self.ui.lblStatus.isVisible()) menu.addAction(action_status) self.connect(action_hide_all, Qt.SIGNAL('triggered()'), self.toggleHideAll) self.connect(action_show_all, Qt.SIGNAL('triggered()'), self.toggleShowAll) self.connect(action_move_absolute, Qt.SIGNAL('toggled(bool)'), self.toggleMoveAbsolute) self.connect(action_move_relative, Qt.SIGNAL('toggled(bool)'), self.toggleMoveRelative) self.connect(action_move_continuous, Qt.SIGNAL('toggled(bool)'), self.toggleMoveContinuous) self.connect(action_move_to_limits, Qt.SIGNAL('toggled(bool)'), self.toggleMoveToLimits) self.connect(action_encoder, Qt.SIGNAL('toggled(bool)'), self.toggleEncoder) self.connect(action_stop_move, Qt.SIGNAL('toggled(bool)'), self.toggleStopMove) self.connect(action_homing, Qt.SIGNAL('toggled(bool)'), self.toggleHoming) self.connect(action_config, Qt.SIGNAL('toggled(bool)'), self.toggleConfig) self.connect(action_status, Qt.SIGNAL('toggled(bool)'), self.toggleStatus) menu.popup(self.cursor().pos()) def toggleHideAll(self): self.toggleAll(False) def toggleShowAll(self): self.toggleAll(True) def toggleAll(self, visible): self.toggleMoveAbsolute(visible) self.toggleMoveRelative(visible) self.toggleMoveContinuous(visible) self.toggleMoveToLimits(visible) self.toggleEncoder(visible) self.toggleStopMove(visible) self.toggleHoming(visible) self.toggleConfig(visible) self.toggleStatus(visible) def toggleMoveAbsolute(self, visible): if self.taurus_value.writeWidget() is not None: self.taurus_value.writeWidget().setVisible(visible) def toggleMoveRelative(self, visible): self.ui.btnGoToNegInc.setVisible(visible) self.ui.inc.setVisible(visible) self.ui.btnGoToPosInc.setVisible(visible) def toggleMoveContinuous(self, visible): self.ui.btnGoToNegPress.setVisible(visible) self.ui.btnGoToPosPress.setVisible(visible) def toggleMoveToLimits(self, visible): self.ui.btnGoToNeg.setVisible(visible) self.ui.btnGoToPos.setVisible(visible) def toggleEncoder(self, visible): self.taurus_value_enc.setVisible(visible) def toggleStopMove(self, visible): self.ui.btnStop.setVisible(visible) def toggleHoming(self, visible): self.ui.btnHome.setVisible(visible) def toggleConfig(self, visible): self.ui.btnCfg.setVisible(visible) def toggleStatus(self, visible): self.ui.lblStatus.setVisible(visible) def dragEnterEvent(self, event): event.accept() def dropEvent(self, event): mimeData = event.mimeData() if mimeData.hasFormat(TAURUS_DEV_MIME_TYPE): model = str(mimeData.data(TAURUS_DEV_MIME_TYPE)) elif mimeData.hasFormat(TAURUS_ATTR_MIME_TYPE): model = str(mimeData.data(TAURUS_ATTR_MIME_TYPE)) else: model = str(mimeData.text()) self.setModel(model) def keyPressEvent(self, key_event): if key_event.key() == Qt.Qt.Key_Escape: self.abort() key_event.accept() TaurusWidget.keyPressEvent(self, key_event) def buildBetterCfgDialogTitle(self): while self.ui.btnCfg._dialog is None: pass model = self.getModel() self.ui.btnCfg._dialog.setWindowTitle('%s config' % taurus.Factory().getDevice(model).getSimpleName()) @classmethod def getQtDesignerPluginInfo(cls): ret = TaurusWidget.getQtDesignerPluginInfo() ret['module'] = 'taurus.qt.qtgui.extra_pool' ret['group'] = 'Taurus Sardana' ret['icon'] = ':/designer/extra_motor.png' ret['container'] = False return ret def showEvent(self, event): TaurusWidget.showEvent(self, event) try: self.motor_dev.getAttribute('Position').enablePolling(force=True) except AttributeError, e: self.debug('Error in showEvent: %s', repr(e)) def hideEvent(self, event): TaurusWidget.hideEvent(self, event) try: self.motor_dev.getAttribute('Position').disablePolling() except AttributeError, e: self.debug('Error in hideEvent: %s', repr(e)) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # QT properties #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @Qt.pyqtSignature("getModel()") def getModel(self): return self.ui.motorGroupBox.getModel() @Qt.pyqtSignature("setModel(QString)") def setModel(self, model): # DUE TO A BUG IN TAUGROUPBOX, WE NEED THE FULL MODEL NAME try: # In case the model is an attribute of a motor, get the device name if not DeviceNameValidator().isValid(model): model = model.rpartition('/')[0] model = taurus.Factory().getDevice(model).getFullName() self.setMotor(model) self.ui.motorGroupBox.setModel(model) self.ui.motorGroupBox.setEnabled(True) self.taurus_value.setModel(model + '/Position') # DUE TO A BUG IN TAURUSVALUE, THAT DO NOT USE PARENT MODEL WE NEED TO ALWAYS SET THE MODEL self.taurus_value.setUseParentModel(False) # THE FORCED APPLY HAS TO BE DONE AFTER THE MODEL IS SET, SO THE WRITEWIDGET IS AVAILABLE if self.taurus_value.writeWidget() is not None: self.taurus_value.writeWidget().setForcedApply(True) show_enc = self.taurus_value_enc.isVisible() if self.has_encoder: self.taurus_value_enc.setModel(model + '/Encoder') self.taurus_value_enc.setUseParentModel(False) self.taurus_value_enc.readWidget().setBgRole('none') else: self.taurus_value_enc.setModel(None) show_enc = False if not show_enc: self.toggleEncoder(False) try: self.unregisterConfigurableItem('MoveAbsolute') self.unregisterConfigurableItem('Encoder') except: pass self.registerConfigProperty(self.taurus_value.writeWidget().isVisible, self.toggleMoveAbsolute, 'MoveAbsolute') self.registerConfigProperty(self.taurus_value_enc.isVisible, self.toggleEncoder, 'Encoder') # SINCE TAURUSLAUNCHERBUTTON HAS NOT THIS PROPERTY IN THE # DESIGNER, WE MUST SET IT HERE self.ui.btnCfg.setUseParentModel(True) # CONFIGURE A LISTENER IN ORDER TO UPDATE LIMIT SWITCHES STATES self.limits_listener = LimitsListener() self.connect(self.limits_listener, Qt.SIGNAL('updateLimits(PyQt_PyObject)'), self.updateLimits) limits_visible = False if self.has_limits: limits_attribute = self.motor_dev.getAttribute('Limit_switches') limits_attribute.addListener(self.limits_listener) #self.updateLimits(limits_attribute.read().value) limits_visible = True self.ui.btnMin.setVisible(limits_visible) self.ui.btnMax.setVisible(limits_visible) except Exception, e: self.ui.motorGroupBox.setEnabled(False) self.info('Error setting model "%s". Reason: %s' % (model, repr(e))) self.traceback() @Qt.pyqtSignature("resetModel()") def resetModel(self): self.ui.motorGroupBox.resetModel() @Qt.pyqtSignature("getShowContextMenu()") def getShowContextMenu(self): return self.show_context_menu @Qt.pyqtSignature("setShowContextMenu(bool)") def setShowContextMenu(self, showContextMenu): self.show_context_menu = showContextMenu @Qt.pyqtSignature("resetShowContextMenu()") def resetShowContextMenu(self): self.show_context_menu = True @Qt.pyqtSignature("getStepSize()") def getStepSize(self): return self.ui.inc.value() @Qt.pyqtSignature("setStepSize(double)") def setStepSize(self, stepSize): self.ui.inc.setValue(stepSize) @Qt.pyqtSignature("resetStepSize()") def resetStepSize(self): self.setStepSize(1) @Qt.pyqtSignature("getStepSizeIncrement()") def getStepSizeIncrement(self): return self.ui.inc.singleStep() @Qt.pyqtSignature("setStepSizeIncrement(double)") def setStepSizeIncrement(self, stepSizeIncrement): self.ui.inc.setSingleStep(stepSizeIncrement) @Qt.pyqtSignature("resetStepSizeIncrement()") def resetStepSizeIncrement(self): self.setStepSizeIncrement(1) model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) stepSize = Qt.pyqtProperty("double", getStepSize, setStepSize, resetStepSize) stepSizeIncrement = Qt.pyqtProperty("double", getStepSizeIncrement, setStepSizeIncrement, resetStepSizeIncrement) ################################################################################################ # NEW APPROACH TO OPERATE POOL MOTORS FROM A TAURUS FORM INHERITTING DIRECTLY FROM TaurusVALUE # # AND USING PARTICULAR CLASSES THAT KNOW THEY ARE PART OF A TAURUSVALUE AND CAN INTERACT # ################################################################################################ class TaurusAttributeListener(Qt.QObject): """ A class that recieves events on tango attribute changes. If that is the case it emits a signal with the event's value. """ def __init__(self): Qt.QObject.__init__(self) def eventReceived(self, evt_src, evt_type, evt_value): if evt_type not in [TaurusEventType.Change, TaurusEventType.Periodic]: return value = evt_value.value self.emit(Qt.SIGNAL('eventReceived'), value) ################################################## # LABEL WIDGET # ################################################## class PoolMotorTVLabelWidget(TaurusWidget): ''' @TODO tooltip should be extended with status info @TODO context menu should be the lbl_alias extended @TODO default tooltip extended with the complete (multiline) status @TODO rightclick popup menu with actions: (1) switch user/expert view, (2) Config -all attributes-, (3) change motor For the (3), a drop event should accept if it is a device, and add it to the 'change-motor' list and select @TODO on the 'expert' row, it could be an ENABLE section with a button to set PowerOn to True/False ''' layoutAlignment = Qt.Qt.AlignTop def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setLayout(Qt.QGridLayout()) self.layout().setMargin(0) self.layout().setSpacing(0) self.lbl_alias = DefaultLabelWidget(parent, designMode) self.lbl_alias.setBgRole('none') self.layout().addWidget(self.lbl_alias) self.btn_poweron = Qt.QPushButton() self.btn_poweron.setText('Set ON') self.layout().addWidget(self.btn_poweron) # Align everything on top self.layout().addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding)) # I don't like this approach, there should be something like # self.lbl_alias.addAction(...) self.lbl_alias.contextMenuEvent = lambda(event): self.contextMenuEvent(event) # I' don't like this approach, there should be something like # self.lbl_alias.addToolTipCallback(self.calculate_extra_tooltip) self.lbl_alias.getFormatedToolTip = self.calculateExtendedTooltip # I' don't like this approach, there should be something like # self.lbl_alias.disableDrag() or self.lbl_alias.setDragEnabled(False) # or better, define if Attribute or Device or Both have to be included in the mimeData self.lbl_alias.mouseMoveEvent = self.mouseMoveEvent def setExpertView(self, expertView): btn_poweron_visible = expertView and self.taurusValueBuddy().hasPowerOn() self.btn_poweron.setVisible(btn_poweron_visible) @ProtectTaurusMessageBox(msg='An error occurred trying to write PowerOn Attribute.') def setPowerOn(self): motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: poweron = (self.btn_poweron.text() == 'Set ON') motor_dev.getAttribute('PowerOn').write(poweron) def setModel(self, model): # Handle User/Expert view self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) self.disconnect(self.btn_poweron, Qt.SIGNAL('clicked()'), self.setPowerOn) if model in (None, ''): self.lbl_alias.setModel(model) TaurusWidget.setModel(self, model) return self.lbl_alias.taurusValueBuddy = self.taurusValueBuddy self.lbl_alias.setModel(model) TaurusWidget.setModel(self, model + '/Status') self.connect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) # Handle Power ON/OFF self.connect(self.btn_poweron, Qt.SIGNAL('clicked()'), self.setPowerOn) self.setExpertView(self.taurusValueBuddy()._expertView) def calculateExtendedTooltip(self, cache=False): default_label_widget_tooltip = DefaultLabelWidget.getFormatedToolTip(self.lbl_alias, cache) status_info = '' motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: status = motor_dev.getAttribute('Status').read().value # MAKE IT LOOK LIKE THE STANDARD TABLE FOR TAURUS TOOLTIPS status_lines = status.split('\n') status_info = '' for status_extra_line in status_lines[1:]: status_info += '' status_info += '
    Status:' + status_lines[0] + '
    ' + status_extra_line + '
    ' return default_label_widget_tooltip + status_info def contextMenuEvent(self, event): # Overwrite the default taurus label behaviour menu = Qt.QMenu(self) action_expert_view = Qt.QAction(self) action_expert_view.setText('Expert View') action_expert_view.setCheckable(True) action_expert_view.setChecked(self.taurusValueBuddy()._expertView) menu.addAction(action_expert_view) self.connect(action_expert_view, Qt.SIGNAL('toggled(bool)'), self.taurusValueBuddy().setExpertView) action_tango_attributes = Qt.QAction(self) action_tango_attributes.setIcon(getIcon(':/categories/preferences-system.svg')) action_tango_attributes.setText('Tango Attributes') menu.addAction(action_tango_attributes) self.connect(action_tango_attributes, Qt.SIGNAL('triggered()'), self.taurusValueBuddy().showTangoAttributes) cm_action = menu.addAction("Compact") cm_action.setCheckable(True) cm_action.setChecked(self.taurusValueBuddy().isCompact()) self.connect(cm_action, Qt.SIGNAL("toggled(bool)"), self.taurusValueBuddy().setCompact) menu.exec_(event.globalPos()) event.accept() def mouseMoveEvent(self, event): model = self.lbl_alias.getModelName() mimeData = Qt.QMimeData() mimeData.setText(self.lbl_alias.text()) dev_name = model.rpartition('/')[0] attr_name = dev_name + '/Position' mimeData.setData(TAURUS_DEV_MIME_TYPE, dev_name) mimeData.setData(TAURUS_ATTR_MIME_TYPE, attr_name) drag = Qt.QDrag(self) drag.setMimeData(mimeData) drag.setHotSpot(event.pos() - self.rect().topLeft()) drag.start(Qt.Qt.CopyAction) ################################################## # READ WIDGET # ################################################## class PoolMotorTVReadWidget(TaurusWidget): ''' @TODO on the 'expert' row, there should be an Indexer/Encoder radiobuttongroup to show units from raw dial/indx/enc @TODO TaurusLCD may be used but, now it does not display the sign, and color is WHITE... ''' layoutAlignment = Qt.Qt.AlignTop def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setLayout(Qt.QGridLayout()) self.layout().setMargin(0) self.layout().setSpacing(0) limits_layout = Qt.QHBoxLayout() limits_layout.setMargin(0) limits_layout.setSpacing(0) self.btn_lim_neg = Qt.QPushButton() self.btn_lim_neg.setToolTip('Negative Limit') #self.btn_lim_neg.setEnabled(False) self.prepare_button(self.btn_lim_neg) self.btn_lim_neg.setIcon(getIcon(':/actions/list-remove.svg')) limits_layout.addWidget(self.btn_lim_neg) self.btn_lim_pos = Qt.QPushButton() self.btn_lim_pos.setToolTip('Positive Limit') #self.btn_lim_pos.setEnabled(False) self.prepare_button(self.btn_lim_pos) self.btn_lim_pos.setIcon(getIcon(':/actions/list-add.svg')) limits_layout.addWidget(self.btn_lim_pos) self.layout().addLayout(limits_layout, 0, 0) self.lbl_read = TaurusLabel() self.lbl_read.setBgRole('quality') self.lbl_read.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) self.layout().addWidget(self.lbl_read, 0, 1) # WITH A COMPACT VIEW, BETTER TO BE ABLE TO STOP! self.btn_stop = Qt.QPushButton() self.btn_stop.setToolTip('Stops the motor') self.prepare_button(self.btn_stop) self.btn_stop.setIcon(getIcon(':/actions/media_playback_stop.svg')) self.layout().addWidget(self.btn_stop, 0, 2) self.connect(self.btn_stop, Qt.SIGNAL('clicked()'), self.abort) # WITH COMPACT VIEW, WE NEED TO FORWARD DOUBLE CLICK EVENT self.lbl_read.installEventFilter(self) ## @TODO right now, no options here... #self.cb_expertRead = Qt.QComboBox() #self.cb_expertRead.addItems(['Enc']) #self.layout().addWidget(self.cb_expertRead, 1, 0) self.lbl_enc = Qt.QLabel('Encoder') self.layout().addWidget(self.lbl_enc, 1, 0) self.lbl_enc_read = TaurusLabel() self.lbl_enc_read.setBgRole('none') self.lbl_enc_read.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) self.layout().addWidget(self.lbl_enc_read, 1, 1) # Align everything on top self.layout().addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding), 2, 0, 1, 2) # IN ORDER TO BEHAVE AS EXPECTED REGARDING THE 'COMPACT VIEW' FEATURE # WE NEED TO SET THE 'EXPERTVIEW' WITHOUT ACCESSING THE taurusValueBuddy WHICH IS STILL NOT LINKED # SO WE ASSUME 'expertview is FALSE' AND WE HAVE TO AVOID self.setExpertView :-( # WOULD BE NICE THAT THE taurusValueBuddy COULD EMIT THE PROPER SIGNAL... self.lbl_enc.setVisible(False) self.lbl_enc_read.setVisible(False) def eventFilter(self, obj, event): if event.type() == Qt.QEvent.MouseButtonDblClick: if isinstance(self.parent(), TaurusReadWriteSwitcher): self.parent().enterEdit() return True try: if obj is self.lbl_read: return self.lbl_read.eventFilter(obj, event) except AttributeError: # self.lbl_read may not exist now pass return True @ProtectTaurusMessageBox(msg='An error occurred trying to abort the motion.') def abort(self): motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: motor_dev.abort() def setExpertView(self, expertView): self.lbl_enc.setVisible(False) self.lbl_enc_read.setVisible(False) if self.taurusValueBuddy().motor_dev is not None: hw_limits = self.taurusValueBuddy().hasHwLimits() self.btn_lim_neg.setEnabled(hw_limits) self.btn_lim_pos.setEnabled(hw_limits) if expertView and self.taurusValueBuddy().motor_dev is not None: encoder = self.taurusValueBuddy().hasEncoder() self.lbl_enc.setVisible(encoder) self.lbl_enc_read.setVisible(encoder) def prepare_button(self, btn): btn_policy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Fixed) btn_policy.setHorizontalStretch(0) btn_policy.setVerticalStretch(0) btn.setSizePolicy(btn_policy) btn.setMinimumSize(25, 25) btn.setMaximumSize(25, 25) btn.setText('') def setModel(self, model): if hasattr(self, 'taurusValueBuddy'): self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) if model in (None, ''): TaurusWidget.setModel(self, model) self.lbl_read.setModel(model) self.lbl_enc_read.setModel(model) return TaurusWidget.setModel(self, model + '/Position') self.lbl_read.setModel(model + '/Position') self.lbl_enc_read.setModel(model + '/Encoder') # Handle User/Expert view self.setExpertView(self.taurusValueBuddy()._expertView) self.connect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) ################################################## # WRITE WIDGET # ################################################## class PoolMotorTVWriteWidget(TaurusWidget): layoutAlignment = Qt.Qt.AlignTop def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setLayout(Qt.QGridLayout()) self.layout().setMargin(0) self.layout().setSpacing(0) self.le_write_absolute = TaurusValueLineEdit() self.layout().addWidget(self.le_write_absolute, 0, 0) self.qw_write_relative = Qt.QWidget() self.qw_write_relative.setLayout(Qt.QHBoxLayout()) self.qw_write_relative.layout().setMargin(0) self.qw_write_relative.layout().setSpacing(0) self.cb_step = Qt.QComboBox() self.cb_step.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) self.cb_step.setEditable(True) self.cb_step.lineEdit().setValidator(Qt.QDoubleValidator(self)) self.cb_step.lineEdit().setAlignment(Qt.Qt.AlignRight) self.cb_step.addItem('1') self.qw_write_relative.layout().addWidget(self.cb_step) self.btn_step_down = Qt.QPushButton() self.btn_step_down.setToolTip('Decrements motor position') self.prepare_button(self.btn_step_down) self.btn_step_down.setIcon(getIcon(':/actions/media_playback_backward.svg')) self.qw_write_relative.layout().addWidget(self.btn_step_down) self.btn_step_up = Qt.QPushButton() self.btn_step_up.setToolTip('Increments motor position') self.prepare_button(self.btn_step_up) self.btn_step_up.setIcon(getIcon(':/actions/media_playback_start.svg')) self.qw_write_relative.layout().addWidget(self.btn_step_up) self.layout().addWidget(self.qw_write_relative, 0, 0) self.cbAbsoluteRelative = Qt.QComboBox() self.connect(self.cbAbsoluteRelative, Qt.SIGNAL('currentIndexChanged(QString)'), self.cbAbsoluteRelativeChanged) self.cbAbsoluteRelative.addItems(['Abs', 'Rel']) self.layout().addWidget(self.cbAbsoluteRelative, 0, 1) # WITH THE COMPACCT VIEW FEATURE, BETTER TO HAVE IT IN THE READ WIDGET # WOULD BE BETTER AS AN 'EXTRA WIDGET' (SOME DAY...) #self.btn_stop = Qt.QPushButton() #self.btn_stop.setToolTip('Stops the motor') #self.prepare_button(self.btn_stop) #self.btn_stop.setIcon(getIcon(':/actions/media_playback_stop.svg')) #self.layout().addWidget(self.btn_stop, 0, 2) btns_layout = Qt.QHBoxLayout() btns_layout.setMargin(0) btns_layout.setSpacing(0) btns_layout.addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)) self.btn_to_neg = Qt.QPushButton() self.btn_to_neg.setToolTip('Moves the motor towards the Negative Software Limit') self.prepare_button(self.btn_to_neg) self.btn_to_neg.setIcon(getIcon(':/actions/media_skip_backward.svg')) btns_layout.addWidget(self.btn_to_neg) self.btn_to_neg_press = Qt.QPushButton() self.btn_to_neg_press.setToolTip('Moves the motor (while pressed) towards the Negative Software Limit') self.prepare_button(self.btn_to_neg_press) self.btn_to_neg_press.setIcon(getIcon(':/actions/media_seek_backward.svg')) btns_layout.addWidget(self.btn_to_neg_press) self.btn_to_pos_press = Qt.QPushButton() self.prepare_button(self.btn_to_pos_press) self.btn_to_pos_press.setToolTip('Moves the motor (while pressed) towards the Positive Software Limit') self.btn_to_pos_press.setIcon(getIcon(':/actions/media_seek_forward.svg')) btns_layout.addWidget(self.btn_to_pos_press) self.btn_to_pos = Qt.QPushButton() self.btn_to_pos.setToolTip('Moves the motor towards the Positive Software Limit') self.prepare_button(self.btn_to_pos) self.btn_to_pos.setIcon(getIcon(':/actions/media_skip_forward.svg')) btns_layout.addWidget(self.btn_to_pos) btns_layout.addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)) self.layout().addLayout(btns_layout, 1, 0, 1, 3) self.connect(self.btn_step_down, Qt.SIGNAL('clicked()'), self.stepDown) self.connect(self.btn_step_up, Qt.SIGNAL('clicked()'), self.stepUp) ###self.connect(self.btn_stop, Qt.SIGNAL('clicked()'), self.abort) self.connect(self.btn_to_neg, Qt.SIGNAL('clicked()'), self.goNegative) self.connect(self.btn_to_neg_press, Qt.SIGNAL('pressed()'), self.goNegative) self.connect(self.btn_to_neg_press, Qt.SIGNAL('released()'), self.abort) self.connect(self.btn_to_pos, Qt.SIGNAL('clicked()'), self.goPositive) self.connect(self.btn_to_pos_press, Qt.SIGNAL('pressed()'), self.goPositive) self.connect(self.btn_to_pos_press, Qt.SIGNAL('released()'), self.abort) # Align everything on top self.layout().addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding), 2, 0, 1, 3) # IN ORDER TO BEHAVE AS EXPECTED REGARDING THE 'COMPACT VIEW' FEATURE # WE NEED TO SET THE 'EXPERTVIEW' WITHOUT ACCESSING THE taurusValueBuddy WHICH IS STILL NOT LINKED # SO WE ASSUME 'expertview is FALSE' AND WE HAVE TO AVOID self.setExpertView :-( # WOULD BE NICE THAT THE taurusValueBuddy COULD EMIT THE PROPER SIGNAL... self.btn_to_neg.setVisible(False) self.btn_to_neg_press.setVisible(False) self.btn_to_pos.setVisible(False) self.btn_to_pos_press.setVisible(False) # IN EXPERT VIEW, WE HAVE TO FORWARD THE ''editingFinished()' SIGNAL FROM TaurusValueLineEdit TO Switcher self.connect(self.le_write_absolute, Qt.SIGNAL(TaurusBaseWritableWidget.appliedSignalSignature), self.emitEditingFinished) self.connect(self.btn_step_down, Qt.SIGNAL("clicked()"), self.emitEditingFinished) self.connect(self.btn_step_up, Qt.SIGNAL("clicked()"), self.emitEditingFinished) self.connect(self.btn_to_neg, Qt.SIGNAL("clicked()"), self.emitEditingFinished) self.connect(self.btn_to_pos, Qt.SIGNAL("clicked()"), self.emitEditingFinished) # list of widgets used for edition editingWidgets = (self.le_write_absolute, self.cbAbsoluteRelative, self.cb_step, self.btn_step_down, self.btn_step_up, self.btn_to_neg, self.btn_to_pos, self.btn_to_neg_press, self.btn_to_pos_press) for w in editingWidgets: w.installEventFilter(self) def eventFilter(self, obj, event): '''reimplemented to intercept events from the subwidgets''' try: if obj in (self.btn_to_neg_press, self.btn_to_pos_press): if event.type() == Qt.QEvent.MouseButtonRelease: self.emitEditingFinished() except AttributeError: # self.btn_to_neg_press, self.btn_to_pos_press may not exist now pass # emit editingFinished when focus out to a non-editing widget if event.type() == Qt.QEvent.FocusOut: focused = Qt.qApp.focusWidget() focusInChild = focused in self.findChildren(focused.__class__) if not focusInChild: self.emitEditingFinished() return False def cbAbsoluteRelativeChanged(self, abs_rel_option): abs_visible = abs_rel_option == 'Abs' rel_visible = abs_rel_option == 'Rel' self.le_write_absolute.setVisible(abs_visible) self.qw_write_relative.setVisible(rel_visible) def stepDown(self): self.goRelative(-1) def stepUp(self): self.goRelative(+1) @ProtectTaurusMessageBox(msg='An error occurred trying to move the motor.') def goRelative(self, direction): motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: increment = direction * float(self.cb_step.currentText()) position = float(motor_dev.getAttribute('Position').read().value) target_position = position + increment motor_dev.getAttribute('Position').write(target_position) @ProtectTaurusMessageBox(msg='An error occurred trying to move the motor.') def goNegative(self): motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: min_value = float(motor_dev.getAttribute('Position').min_value) motor_dev.getAttribute('Position').write(min_value) @ProtectTaurusMessageBox(msg='An error occurred trying to move the motor.') def goPositive(self): motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: max_value = float(motor_dev.getAttribute('Position').max_value) motor_dev.getAttribute('Position').write(max_value) @ProtectTaurusMessageBox(msg='An error occurred trying to abort the motion.') def abort(self): motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: motor_dev.abort() def prepare_button(self, btn): btn_policy = Qt.QSizePolicy(Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Fixed) btn_policy.setHorizontalStretch(0) btn_policy.setVerticalStretch(0) btn.setSizePolicy(btn_policy) btn.setMinimumSize(25, 25) btn.setMaximumSize(25, 25) btn.setText('') def setExpertView(self, expertView): self.btn_to_neg.setVisible(expertView) self.btn_to_neg_press.setVisible(expertView) self.btn_to_pos.setVisible(expertView) self.btn_to_pos_press.setVisible(expertView) if expertView and self.taurusValueBuddy().motor_dev is not None: neg_sw_limit_enabled = self.taurusValueBuddy().motor_dev.getAttribute('Position').min_value.lower() != 'not specified' self.btn_to_neg.setEnabled(neg_sw_limit_enabled) self.btn_to_neg_press.setEnabled(neg_sw_limit_enabled) pos_sw_limit_enabled = self.taurusValueBuddy().motor_dev.getAttribute('Position').max_value.lower() != 'not specified' self.btn_to_pos.setEnabled(pos_sw_limit_enabled) self.btn_to_pos_press.setEnabled(pos_sw_limit_enabled) def setModel(self, model): if hasattr(self, 'taurusValueBuddy'): self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) if model in (None, ''): TaurusWidget.setModel(self, model) self.le_write_absolute.setModel(model) return TaurusWidget.setModel(self, model + '/Position') self.le_write_absolute.setModel(model + '/Position') # Handle User/Expert View self.setExpertView(self.taurusValueBuddy()._expertView) self.connect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) def keyPressEvent(self, key_event): if key_event.key() == Qt.Qt.Key_Escape: self.abort() key_event.accept() TaurusWidget.keyPressEvent(self, key_event) def emitEditingFinished(self): self.emit(Qt.SIGNAL(TaurusBaseWritableWidget.appliedSignalSignature)) ################################################## # UNITS WIDGET # ################################################## class PoolMotorTVUnitsWidget(DefaultUnitsWidget): layoutAlignment = Qt.Qt.AlignTop def __init__(self, parent=None, designMode=False): DefaultUnitsWidget.__init__(self, parent, designMode) def setModel(self, model): if model in (None,''): DefaultUnitsWidget.setModel(self, model) return DefaultUnitsWidget.setModel(self, model + '/Position') ################################################## # TV MOTOR WIDGET # ################################################## class PoolMotorTV(TaurusValue): ''' A widget that displays and controls a pool Motor device. It behaves as a TaurusValue. @TODO the view mode should be stored in the configuration @TODO the motor list should be stored in the configuration @TODO the selected radiobuttons (dial/indx/enc) and (abs/rel) should be stored in configuration @TODO it would be nice if the neg/pos limits could react also when software limits are 'active' @TODO expert view for read widget should include signals (indexer/encoder/inpos)... ''' def __init__(self, parent=None, designMode=False): TaurusValue.__init__(self, parent=parent, designMode=designMode) self.setLabelWidgetClass('PoolMotorTVLabelWidget') self.setReadWidgetClass('PoolMotorTVReadWidget') self.setWriteWidgetClass('PoolMotorTVWriteWidget') self.setUnitsWidgetClass('PoolMotorTVUnitsWidget') self.setLabelConfig('dev_alias') self.motor_dev = None self._expertView = False self.limits_listener = None self.poweron_listener = None self.status_listener = None self.position_listener = None self.setExpertView(False) def setExpertView(self, expertView): self._expertView = expertView self.emit(Qt.SIGNAL('expertViewChanged(bool)'), expertView) def minimumHeight(self): return None #@todo: UGLY HACK to avoid subwidgets being forced to minimumheight=20 def setModel(self, model): TaurusValue.setModel(self, model) try: # disconnect signals if self.limits_listener is not None: self.disconnect(self.limits_listener, Qt.SIGNAL('eventReceived'), self.updateLimits) if self.poweron_listener is not None: self.disconnect(self.poweron_listener, Qt.SIGNAL('eventReceived'), self.updatePowerOn) if self.status_listener is not None: self.disconnect(self.status_listener, Qt.SIGNAL('eventReceived'), self.updateStatus) if self.position_listener is not None: self.disconnect(self.position_listener, Qt.SIGNAL('eventReceived'), self.updatePosition) #remove listeners if self.motor_dev is not None: if self.hasHwLimits(): self.motor_dev.getAttribute('Limit_Switches').removeListener(self.limits_listener) if self.hasPowerOn(): self.motor_dev.getAttribute('PowerOn').removeListener(self.poweron_listener) self.motor_dev.getAttribute('Status').removeListener(self.status_listener) self.motor_dev.getAttribute('Position').removeListener(self.position_listener) if model == '' or model is None: self.motor_dev = None return self.motor_dev = taurus.Device(model) # CONFIGURE A LISTENER IN ORDER TO UPDATE LIMIT SWITCHES STATES self.limits_listener = TaurusAttributeListener() if self.hasHwLimits(): self.connect(self.limits_listener, Qt.SIGNAL('eventReceived'), self.updateLimits) self.motor_dev.getAttribute('Limit_Switches').addListener(self.limits_listener) # CONFIGURE AN EVENT RECEIVER IN ORDER TO PROVIDE POWERON <- True/False EXPERT OPERATION self.poweron_listener = TaurusAttributeListener() if self.hasPowerOn(): self.connect(self.poweron_listener, Qt.SIGNAL('eventReceived'), self.updatePowerOn) self.motor_dev.getAttribute('PowerOn').addListener(self.poweron_listener) # CONFIGURE AN EVENT RECEIVER IN ORDER TO UPDATED STATUS TOOLTIP self.status_listener = TaurusAttributeListener() self.connect(self.status_listener, Qt.SIGNAL('eventReceived'), self.updateStatus) self.motor_dev.getAttribute('Status').addListener(self.status_listener) # CONFIGURE AN EVENT RECEIVER IN ORDER TO ACTIVATE LIMIT BUTTONS ON SOFTWARE LIMITS self.position_listener = TaurusAttributeListener() self.connect(self.position_listener, Qt.SIGNAL('eventReceived'), self.updatePosition) self.motor_dev.getAttribute('Position').addListener(self.position_listener) self.motor_dev.getAttribute('Position').enablePolling(force=True) self.setExpertView(self._expertView) except Exception, e: self.warning("Exception caught while setting model: %s", repr(e)) self.motor_dev = None return def hasPowerOn(self): try: return hasattr(self.motor_dev, 'PowerOn') except: return False def hasHwLimits(self): try: return hasattr(self.motor_dev, 'Limit_Switches') except: return False def updateLimits(self, limits, position=None): if isinstance(limits, dict): limits = limits["limits"] limits = list(limits) HOME = 0 POS = 1 NEG = 2 # Check also if the software limit is 'active' if self.motor_dev is not None: position_attribute = self.motor_dev.getAttribute('Position') if position is None: position = position_attribute.read().value max_value_str = position_attribute.max_value min_value_str = position_attribute.min_value try: max_value = float(max_value_str) limits[POS] = limits[POS] or (position >= max_value) except: pass try: min_value = float(min_value_str) limits[NEG] = limits[NEG] or (position <= min_value) except: pass pos_lim = limits[POS] pos_btnstylesheet = '' enabled = True if pos_lim: pos_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) enabled = False self.readWidget(followCompact=True).btn_lim_pos.setStyleSheet(pos_btnstylesheet) self.writeWidget(followCompact=True).btn_step_up.setEnabled(enabled) self.writeWidget(followCompact=True).btn_step_up.setStyleSheet(pos_btnstylesheet) enabled = enabled and self.motor_dev.getAttribute('Position').max_value.lower() != 'not specified' self.writeWidget(followCompact=True).btn_to_pos.setEnabled(enabled) self.writeWidget(followCompact=True).btn_to_pos_press.setEnabled(enabled) neg_lim = limits[NEG] neg_btnstylesheet = '' enabled = True if neg_lim: neg_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) enabled = False self.readWidget(followCompact=True).btn_lim_neg.setStyleSheet(neg_btnstylesheet) self.writeWidget(followCompact=True).btn_step_down.setEnabled(enabled) self.writeWidget(followCompact=True).btn_step_down.setStyleSheet(neg_btnstylesheet) enabled = enabled and self.motor_dev.getAttribute('Position').min_value.lower() != 'not specified' self.writeWidget(followCompact=True).btn_to_neg.setEnabled(enabled) self.writeWidget(followCompact=True).btn_to_neg_press.setEnabled(enabled) def updatePowerOn(self, poweron='__no_argument__'): if poweron == '__no_argument__': msg = 'updatePowerOn called without args (bug in old PyQt). Ignored' self.debug(msg) return btn_text = 'Set ON' if poweron: btn_text = 'Set OFF' self.labelWidget().btn_poweron.setText(btn_text) def updateStatus(self, status): # SHOULD THERE BE A BETTER METHOD FOR THIS UPDATE? # IF THIS IS NOT DONE, THE TOOLTIP IS NOT CALCULATED EVERY TIME # TaurusLabel.updateStyle DIDN'T WORK, SO I HAD TO GO DEEPER TO THE CONTROLLER... #self.labelWidget().lbl_alias.updateStyle() self.labelWidget().lbl_alias.controllerUpdate() def updatePosition(self, position='__no_argument__'): if position == '__no_argument__': msg = 'updatePowerOn called without args (bug in old PyQt). Ignored' self.debug(msg) return # we do not need the position for nothing... # we just want to check if any software limit is 'active' # and updateLimits takes care of it if self.motor_dev is not None: limit_switches = [False, False, False] if self.hasHwLimits(): limit_switches = self.motor_dev.getAttribute('Limit_switches').read().value #print "update limits", limit_switches self.updateLimits(limit_switches, position=position) def hasEncoder(self): try: return hasattr(self.motor_dev, 'Encoder') except: return False def showTangoAttributes(self): model = self.getModel() taurus_attr_form = TaurusAttrForm() taurus_attr_form.setMinimumSize(Qt.QSize(555, 800)) taurus_attr_form.setModel(model) taurus_attr_form.setWindowTitle('%s Tango Attributes' % taurus.Factory().getDevice(model).getSimpleName()) taurus_attr_form.show() ### def showEvent(self, event): ### TaurusValue.showEvent(self, event) ### if self.motor_dev is not None: ### self.motor_dev.getAttribute('Position').enablePolling(force=True) ### ### def hideEvent(self, event): ### TaurusValue.hideEvent(self, event) ### if self.motor_dev is not None: ### self.motor_dev.getAttribute('Position').disablePolling() ################################################### # A SIMPLER WIDGET THAT MAY BE USED OUTSIDE FORMS # ################################################### class PoolMotor(TaurusFrame): ''' A widget that displays and controls a pool Motor device. ''' def __init__(self, parent=None, designMode=False): TaurusFrame.__init__(self, parent, designMode) self.setLayout(Qt.QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self.setFrameShape(Qt.QFrame.Box) self.pool_motor_tv = PoolMotorTV(self) def setModel(self, model): self.pool_motor_tv.setModel(model) try: self.motor_dev = taurus.Device(model) except: return def main(): import sys import taurus.qt.qtgui.application import taurus.core.util.argparse from taurus.qt.qtgui.panel import TaurusForm parser = taurus.core.util.argparse.get_taurus_parser() parser.usage = "%prog [options] [ [] ...]" app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser) args = app.get_command_line_args() #models = ['tango://controls02:10000/motor/gcipap10ctrl/8'] models = ['motor/motctrl13/3'] if len(args) > 0: models = args w = Qt.QWidget() w.setLayout(Qt.QVBoxLayout()) tests = [] #tests.append(1) tests.append(2) #tests.append(3) #tests.append(4) # 1) Test PoolMotorSlim motor widget form_pms = TaurusForm() pms_widget_class = 'taurus.qt.qtgui.extra_pool.PoolMotorSlim' pms_tgclass_map = {'SimuMotor':(pms_widget_class, (), {}), 'Motor':(pms_widget_class, (), {}), 'PseudoMotor':(pms_widget_class, (), {})} form_pms.setCustomWidgetMap(pms_tgclass_map) if 1 in tests: form_pms.setModel(models) w.layout().addWidget(form_pms) # 2) Test PoolMotorTV motor widget form_tv = TaurusForm() form_tv.setModifiableByUser(True) tv_widget_class = 'taurus.qt.qtgui.extra_pool.PoolMotorTV' tv_tgclass_map = {'SimuMotor':(tv_widget_class, (), {}), 'Motor':(tv_widget_class, (), {}), 'PseudoMotor':(tv_widget_class, (), {})} form_tv.setCustomWidgetMap(tv_tgclass_map) if 2 in tests: form_tv.setModel(models) w.layout().addWidget(form_tv) form_tv.setCompact(True) # 3) Test Stand-Alone PoolMotor widget # New approach would be to let PoolMotorTV live outside a TaurusForm.... but inside a GridLayout # Carlos already said this is not a good approach but... if 3 in tests: for motor in models: motor_widget = PoolMotor() motor_widget.setModel(motor) w.layout().addWidget(motor_widget) # 4) Test Stand-Alone PoolMotorSlim widget if 4 in tests: for motor in models: motor_widget = PoolMotorSlim() motor_widget.setModel(motor) w.layout().addWidget(motor_widget) w.show() sys.exit(app.exec_()) if __name__ == '__main__': main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/0000755000234000017500000000000012555673001025072 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/ui/0000755000234000017500000000000012555673001025507 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/ui/ExpDescriptionEditor.ui0000644000234000017500000002321512555672637032176 0ustar zreszelaComputing00000000000000 ExpDescriptionEditor 0 0 733 411 Experiment Configuration 0 Measurement Group Active Measurement Group Selects the active Measurement Group Create a new Measurement Group + Delete the current Measurement Group - Qt::Horizontal 40 20 If checked, the configured plots are shown plots true Snapshot Group Qt::Vertical 0 Sardana Elements External (Tango) (Drag elements from the above selectors and drop them at the bottom list) Storage QFormLayout::ExpandingFieldsGrow <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">comma separated list of file names in which to store the results of the scans. Use .h5 extension for NeXus files (preferred) and .dat for spec format (note: SPEC format is <span style=" font-weight:600;">not </span>supported)</p></body></html> File Name(s) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">comma separated list of file names in which to store the results of the scans. Use .h5 extension for NeXus files (preferred) and .dat for spec format (note: SPEC format is <span style=" font-weight:600;">not </span>supported)</p></body></html> Path 0 ... Data compression nowhere for all datasets for datasets of rank 1 or more for datasets of rank 2 or more for datasets of rank 3 or more QDialogButtonBox::NoButton TaurusModelList QListView
    taurus.qt.qtgui.panel
    TaurusModelSelectorTree TaurusWidget
    taurus.qt.qtgui.panel
    SardanaElementTreeWidget QMainWindow
    sardana.taurus.qt.qtgui.extra_sardana
    1
    MntGrpChannelEditor QMainWindow
    sardana.taurus.qt.qtgui.extra_sardana
    1
    sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/ui/__init__.py0000644000234000017500000000172212555672637027640 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/__init__.py0000644000234000017500000000252512555672637027225 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 a collection of taurus widgets designed to connect to sardana""" __docformat__ = 'restructuredtext' from .measurementgroup import * from .expdescription import * from .elementtree import * try: from .sardanaeditor import * except: from taurus.qt.qtgui.display import create_taurus_fallback as __create SardanaEditor = __create("SardanaEditor") sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/cmdline.py0000644000234000017500000000625512555672637027105 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 a collection of taurus widgets designed to connect to sardana""" __docformat__ = 'restructuredtext' from taurus.external.qt import Qt from taurus.qt.qtgui.resource import getIcon, getThemeIcon class CommandLineHistory(list): pass class CommandLine(Qt.QComboBox): def __init__(self, qt_parent=None, designMode=False): Qt.QComboBox.__init__(self, qt_parent) self.setEditable(True) self.setFrame(False) class TaurusCommandLineWidget(Qt.QWidget): def __init__(self, qt_parent=None, designMode=False): Qt.QWidget.__init__(self, qt_parent) self._history = CommandLineHistory() l = Qt.QHBoxLayout() self.setLayout(l) l.setContentsMargins(0, 0, 0, 0) l.setSpacing(0) self._detailsButton = Qt.QToolButton() self._detailsButton.setText("...") self._cmdLine = Qt.QComboBox() self._cmdLine.setEditable(True) self._applyButton = Qt.QToolButton() self._applyButton.setIcon(getIcon(":/actions/media_playback_start.svg")) self._stopButton = Qt.QToolButton() self._stopButton.setIcon(getIcon(":/actions/media_playback_stop.svg")) self._clearButton = Qt.QToolButton() self._clearButton.setIcon(getThemeIcon("edit-clear")) l.addWidget(self._detailsButton, 0) l.addWidget(self._cmdLine, 1) l.addWidget(self._applyButton, 0) l.addWidget(self._stopButton, 0) l.addWidget(self._clearButton, 0) def run(self): pass def demo(): pass def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: import taurus.core.util.argparse parser = taurus.core.util.argparse.get_taurus_parser() app = Application(sys.argv, cmd_line_parser=parser, app_name="Taurus command line demo", app_version="1.0", org_domain="Taurus", org_name="Tango community") w = TaurusCommandLineWidget() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == '__main__': main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/controllertree.py0000644000234000017500000002652212555672637030534 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus text editor widget.""" __all__ = ["ControllerClassTreeWidget", "ControllerClassSelectionDialog"] __docformat__ = 'restructuredtext' import sys import os import taurus.core from taurus.core.util.enumeration import Enumeration from taurus.external.qt import Qt from taurus.qt.qtcore.mimetypes import TAURUS_MODEL_MIME_TYPE, TAURUS_MODEL_LIST_MIME_TYPE from taurus.qt.qtcore.model import TaurusBaseTreeItem, TaurusBaseModel, TaurusBaseProxyModel from taurus.qt.qtgui.tree import TaurusBaseTreeWidget from taurus.qt.qtgui.resource import getThemeIcon, getIcon PoolControllerView = Enumeration("PoolControllerView", ("ControllerModule", "ControllerClass", "Unknown")) def getElementTypeIcon(t): if t == PoolControllerView.ControllerModule: return getIcon(":/python-file.png") elif t == PoolControllerView.ControllerClass: return getIcon(":/python.png") return getIcon(":/tango.png") def getElementTypeSize(t): return Qt.QSize(200, 24) def getElementTypeToolTip(t): """Wrapper to prevent loading qtgui when this module is imported""" if t == PoolControllerView.ControllerModule: return "Controller module" elif t == PoolControllerView.ControllerClass: return "Controller class" class ControllerBaseTreeItem(TaurusBaseTreeItem): """A generic node""" def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ return self._itemData def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown This method should be able to return any kind of python object as long as the model that is used is compatible. :return: (PoolControllerView) the role in form of element type""" return PoolControllerView.Unknown class ControllerModuleTreeItem(ControllerBaseTreeItem): def role(self): return PoolControllerView.ControllerModule def toolTip(self): return "The controller module '%s'" % self.display() def icon(self): return getIcon(":/python-file.png") class ControllerTreeItem(ControllerBaseTreeItem): def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ return self._itemData.name def role(self): return PoolControllerView.ControllerClass def toolTip(self): return self._itemData.doc def icon(self): return getIcon(":/python.png") class ControllerBaseModel(TaurusBaseModel): ColumnNames = "Controllers", ColumnRoles = (PoolControllerView.ControllerModule, PoolControllerView.ControllerModule, PoolControllerView.ControllerClass), def setDataSource(self, pool): if self._data_src is not None: Qt.QObject.disconnect(self._data_src, Qt.SIGNAL('controllerClassesUpdated'), self.controllerClassesUpdated) if pool is not None: Qt.QObject.connect(pool, Qt.SIGNAL('controllerClassesUpdated'), self.controllerClassesUpdated) TaurusBaseModel.setDataSource(self, pool) def controllerClassesUpdated(self): self.refresh() def createNewRootItem(self): return ControllerBaseTreeItem(self, self.ColumnNames) def roleIcon(self, role): return getElementTypeIcon(role) def columnIcon(self, column): return self.roleIcon(self.role(column)) def roleToolTip(self, role): return getElementTypeToolTip(role) def columnToolTip(self, column): return self.roleToolTip(self.role(column)) def roleSize(self, role): return getElementTypeSize(role) def columnSize(self, column): role = self.role(column) s = self.roleSize(role) return s def mimeTypes(self): return ["text/plain", TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_MODEL_MIME_TYPE] def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: if not index.isValid(): continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: continue data.append(mime_data_item) ret.setData(TAURUS_MODEL_LIST_MIME_TYPE, "\r\n".join(data)) ret.setText(", ".join(data)) if len(data) == 1: ret.setData(TAURUS_MODEL_MIME_TYPE, str(data[0])) return ret def pyData(self, index, role): if not index.isValid(): return None item = index.internalPointer() row, column, depth = index.row(), index.column(), item.depth() item_role = self.role(column, depth) ret = None if role == Qt.Qt.DisplayRole: ret = Qt.QString(item.data(index)) elif role == Qt.Qt.DecorationRole: ret = item.icon() elif role == Qt.Qt.ToolTipRole: ret = item.toolTip() #elif role == Qt.Qt.SizeHintRole: # ret = self.columnSize(column) elif role == Qt.Qt.FontRole: ret = self.DftFont return ret def setupModelData(self, data): pool = self.dataSource() if pool is None: return root = self._rootItem ctrl_modules = {} # TODO #ctrl_class_dict = pool.getControllerClasses() #for ctrl_class_name, ctrl_class in ctrl_class_dict.items(): # module_name = ctrl_class.module_name # moduleNode = ctrl_modules.get(module_name) # if moduleNode is None: # moduleNode = ControllerModuleTreeItem(self, module_name, root) # root.appendChild(moduleNode) # ctrl_modules[module_name] = moduleNode # ctrlNode = ControllerTreeItem(self, ctrl_class, moduleNode) # moduleNode.appendChild(ctrlNode) class ControllerModuleModel(ControllerBaseModel): pass class PlainControllerModel(ControllerBaseModel): ColumnNames = "Controller classes", ColumnRoles = (PoolControllerView.ControllerClass, PoolControllerView.ControllerClass), def setupModelData(self, data): pool = self.dataSource() if pool is None: return root = self._rootItem # TODO #ctrl_class_dict = pool.getControllerClasses() #ctrl_classes = ctrl_class_dict.keys() #ctrl_classes.sort() #self.debug("Found %d controller classes", len(ctrl_classes)) #for ctrl_class_name in ctrl_classes: # ctrl_class = ctrl_class_dict[ctrl_class_name] # ctrlNode = ControllerTreeItem(self, ctrl_class, root) # root.appendChild(ctrlNode) class ControllerBaseModelProxy(TaurusBaseProxyModel): pass class ControllerModuleModelProxy(ControllerBaseModelProxy): pass class PlainControllerModelProxy(ControllerBaseModelProxy): pass class ControllerClassTreeWidget(TaurusBaseTreeWidget): KnownPerspectives = { PoolControllerView.ControllerModule : { "label" : "By module", "icon" : ":/python-file.png", "tooltip" : "View by controller module", "model" : [ControllerModuleModelProxy, ControllerModuleModel], }, PoolControllerView.ControllerClass : { "label" : "By controller", "icon" : ":/python.png", "tooltip" : "View by controller class", "model" : [PlainControllerModelProxy, PlainControllerModel], } } DftPerspective = PoolControllerView.ControllerModule def getModelClass(self): return taurus.core.taurusdevice.TaurusDevice class ControllerClassSelectionDialog(Qt.QDialog): def __init__(self, parent=None, designMode=False, model_name=None, perspective=None): Qt.QDialog.__init__(self, parent) self.setWindowTitle("Controller Class Selection Dialog") layout = Qt.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self._panel = ControllerClassTreeWidget(parent=self, perspective=perspective, designMode=designMode, with_navigation_bar=False) self._panel.setModel(model_name) self.setWindowIcon(getElementTypeIcon(self._panel.perspective())) self._buttonBox = Qt.QDialogButtonBox(self) bts = Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel self._buttonBox.setStandardButtons(bts) layout.addWidget(self._panel) layout.addWidget(self._buttonBox) self.connect(self._buttonBox, Qt.SIGNAL("accepted()"), self.accept) self.connect(self._buttonBox, Qt.SIGNAL("rejected()"), self.reject) def selectedItems(self): return self._panel.selectedItems() def getSelectedMacros(self): return [ i.itemData() for i in self.selectedItems() ] def main_ControllerClassSelecionDialog(pool, perspective=PoolControllerView.ControllerClass): w = ControllerClassSelectionDialog(model_name=pool, perspective=perspective) if w.result() == Qt.QDialog.Accepted: print w.getSelectedMacros() return w def main_ControllerClassTreeWidget(pool, perspective=PoolControllerView.ControllerClass): w = ControllerClassTreeWidget(perspective=perspective, with_navigation_bar=False) w.setModel(pool) w.show() return w def demo(poolname="Pool_BL98"): """ControllerClassTreeWidget""" w = main_ControllerClassSelecionDialog(poolname, PoolControllerView.ControllerClass) return w def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Application(app_name="Pool controller class tree demo", app_version="1.0", org_domain="Taurus", org_name="Tango community") args = app.get_command_line_args() if len(args) == 1: w = demo(poolname=args[0]) else: w = demo() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/elementtree.py0000644000234000017500000000567512555672637030010 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus text editor widget.""" __all__ = ["SardanaElementTreeWidget"] __docformat__ = 'restructuredtext' from taurus.core.taurusdevice import TaurusDevice from taurus.qt.qtgui.tree import TaurusBaseTreeWidget from sardana.taurus.qt.qtcore.tango.sardana.model import \ SardanaBaseProxyModel, SardanaElementTypeModel class SardanaElementTreeWidget(TaurusBaseTreeWidget): KnownPerspectives = { "Type" : { "label" : "By type", "icon" : ":/python-file.png", "tooltip" : "View elements by type", "model" : [SardanaBaseProxyModel, SardanaElementTypeModel], }, } DftPerspective = "Type" def getModelClass(self): return TaurusDevice @classmethod def getQtDesignerPluginInfo(cls): ret = TaurusBaseTreeWidget.getQtDesignerPluginInfo() ret['module'] = 'taurus.qt.qtgui.extra_sardana' ret['group'] = 'Taurus Sardana' ret['icon'] = ":/designer/listview.png" return ret def main_SardanaTreeWidget(device): w = SardanaElementTreeWidget(with_navigation_bar=True) w.setWindowTitle("Sardana browser - " + device) w.setModel(device) w.setMinimumSize(400, 800) w.show() return w def demo(device="V3"): """""" w = main_SardanaTreeWidget(device) return w def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Application(app_name="Pool element tree demo", app_version="1.0", org_domain="Taurus", org_name="Tango community") args = app.get_command_line_args() if len(args) == 1: w = demo(device=args[0]) else: w = demo() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/environment.py0000644000234000017500000000567712555672637030045 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus environment widgets.""" __all__ = ["SardanaEnvironmentTreeWidget"] __docformat__ = 'restructuredtext' from taurus.core.taurusdevice import TaurusDevice from taurus.external.qt import Qt from taurus.qt.qtgui.tree import TaurusBaseTreeWidget from sardana.taurus.qt.qtcore.tango.sardana.model import SardanaEnvironmentModel class SardanaEnvironmentTreeWidget(TaurusBaseTreeWidget): KnownPerspectives = { "Type" : { "label" : "By key", "icon" : ":/python-file.png", "tooltip" : "View elements by key", "model" : [SardanaEnvironmentModel], }, } DftPerspective = "Type" def getModelClass(self): return TaurusDevice @classmethod def getQtDesignerPluginInfo(cls): ret = TaurusBaseTreeWidget.getQtDesignerPluginInfo() ret['module'] = 'taurus.qt.qtgui.extra_sardana' ret['group'] = 'Taurus Sardana' ret['icon'] = ":/designer/listview.png" return ret def main_SardanaTreeWidget(device): w = SardanaEnvironmentTreeWidget(with_navigation_bar=True) w.setWindowTitle("Sardana browser - " + device) w.setModel(device) w.setMinimumSize(400, 800) w.show() return w def demo(device="V3"): """""" w = main_SardanaTreeWidget(device) return w def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Application(app_name="Sardana environment tree demo", app_version="1.0", org_domain="Taurus", org_name="Tango community") args = app.get_command_line_args() if len(args) == 1: w = demo(device=args[0]) else: w = demo() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/expdescription.py0000644000234000017500000004470512555672637030534 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 widget for configuring the data acquisition and display of an experiment""" __all__ = ["ExpDescriptionEditor"] from taurus.external.qt import Qt import copy import taurus import taurus.core from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui import resource from sardana.taurus.qt.qtcore.tango.sardana.model import SardanaBaseProxyModel, SardanaTypeTreeItem from taurus.qt.qtgui.util.ui import UILoadable ## Using a plain model and filtering and checking 'Acquirable' in item.itemData().interfaces is more elegant, but things don't get properly sorted... #from taurus.qt.qtcore.tango.sardana.model import SardanaElementPlainModel class SardanaAcquirableProxyModel(SardanaBaseProxyModel): # ALLOWED_TYPES = 'Acquirable' # # def filterAcceptsRow(self, sourceRow, sourceParent): # sourceModel = self.sourceModel() # idx = sourceModel.index(sourceRow, 0, sourceParent) # item = idx.internalPointer() # return 'Acquirable' in item.itemData().interfaces # ALLOWED_TYPES = ['Motor', 'CTExpChannel', 'ZeroDExpChannel', 'OneDExpChannel', # 'TwoDExpChannel', 'ComChannel', 'IORegister', 'PseudoMotor', # 'PseudoCounter'] from sardana.sardanadefs import ElementType, TYPE_ACQUIRABLE_ELEMENTS ALLOWED_TYPES = [ElementType[t] for t in TYPE_ACQUIRABLE_ELEMENTS] def filterAcceptsRow(self, sourceRow, sourceParent): sourceModel = self.sourceModel() idx = sourceModel.index(sourceRow, 0, sourceParent) treeItem = idx.internalPointer() if isinstance(treeItem, SardanaTypeTreeItem): return treeItem.itemData() in self.ALLOWED_TYPES return True @UILoadable(with_ui='ui') class ExpDescriptionEditor(Qt.QWidget, TaurusBaseWidget): ''' A widget for editing the configuration of a experiment (measurement groups, plot and storage parameters, etc). It receives a Sardana Door name as its model and gets/sets the configuration using the `ExperimentConfiguration` environmental variable for that Door. ''' def __init__(self, parent=None, door=None, plotsButton=True): Qt.QWidget.__init__(self, parent) TaurusBaseWidget.__init__(self, 'ExpDescriptionEditor') self.loadUi() self.ui.buttonBox.setStandardButtons(Qt.QDialogButtonBox.Reset | Qt.QDialogButtonBox.Apply) newperspectivesDict = copy.deepcopy(self.ui.sardanaElementTree.KnownPerspectives) #newperspectivesDict[self.ui.sardanaElementTree.DftPerspective]['model'] = [SardanaAcquirableProxyModel, SardanaElementPlainModel] newperspectivesDict[self.ui.sardanaElementTree.DftPerspective]['model'][0] = SardanaAcquirableProxyModel self.ui.sardanaElementTree.KnownPerspectives = newperspectivesDict #assign a copy because if just a key of this class memberwas modified, all instances of this class would be affected self.ui.sardanaElementTree._setPerspective(self.ui.sardanaElementTree.DftPerspective) self._localConfig = None self._originalConfiguration = None self._dirty = False self._dirtyMntGrps = set() self.connect(self.ui.activeMntGrpCB, Qt.SIGNAL('activated (QString)'), self.changeActiveMntGrp) self.connect(self.ui.createMntGrpBT, Qt.SIGNAL('clicked ()'), self.createMntGrp) self.connect(self.ui.deleteMntGrpBT, Qt.SIGNAL('clicked ()'), self.deleteMntGrp) self.connect(self.ui.compressionCB, Qt.SIGNAL('currentIndexChanged (int)'), self.onCompressionCBChanged) self.connect(self.ui.pathLE, Qt.SIGNAL('textEdited (QString)'), self.onPathLEEdited) self.connect(self.ui.filenameLE, Qt.SIGNAL('textEdited (QString)'), self.onFilenameLEEdited) self.connect(self.ui.channelEditor.getQModel(), Qt.SIGNAL('dataChanged (QModelIndex, QModelIndex)'), self._updateButtonBox) self.connect(self.ui.channelEditor.getQModel(), Qt.SIGNAL('modelReset ()'), self._updateButtonBox) self.connect(self.ui.preScanList, Qt.SIGNAL('dataChanged'), self.onPreScanSnapshotChanged) self.connect(self.ui.choosePathBT, Qt.SIGNAL('clicked ()'), self.onChooseScanDirButtonClicked) self.__plotManager = None icon = resource.getIcon(":/actions/view.svg") self.togglePlotsAction = Qt.QAction(icon, "Show/Hide plots", self) self.togglePlotsAction.setCheckable(True) self.togglePlotsAction.setChecked(False) self.togglePlotsAction.setEnabled(plotsButton) self.addAction(self.togglePlotsAction) self.connect(self.togglePlotsAction, Qt.SIGNAL("toggled(bool)"), self.onPlotsButtonToggled) self.ui.plotsButton.setDefaultAction(self.togglePlotsAction) if door is not None: self.setModel(door) self.connect(self.ui.buttonBox, Qt.SIGNAL("clicked(QAbstractButton *)"), self.onDialogButtonClicked) #Taurus Configuration properties and delegates self.registerConfigDelegate(self.ui.channelEditor) def getModelClass(self): '''reimplemented from :class:`TaurusBaseWidget`''' return taurus.core.taurusdevice.TaurusDevice def onChooseScanDirButtonClicked(self): ret = Qt.QFileDialog.getExistingDirectory (self, 'Choose directory for saving files', self.ui.pathLE.text()) if ret: self.ui.pathLE.setText(ret) self.ui.pathLE.emit(Qt.SIGNAL('textEdited (QString)'), ret) def onDialogButtonClicked(self, button): role = self.ui.buttonBox.buttonRole(button) if role == Qt.QDialogButtonBox.ApplyRole: self.writeExperimentConfiguration(ask=False) elif role == Qt.QDialogButtonBox.ResetRole: self._reloadConf() def closeEvent(self, event): '''This event handler receives widget close events''' if self.isDataChanged(): self.writeExperimentConfiguration(ask=True) Qt.QWidget.closeEvent(self, event) def setModel(self, model): '''reimplemented from :class:`TaurusBaseWidget`''' TaurusBaseWidget.setModel(self, model) self._reloadConf(force=True) #set the model of some child widgets door = self.getModelObj() if door is None: return tghost = taurus.Database().getNormalName() #@todo: get the tghost from the door model instead msname = door.macro_server.getFullName() self.ui.taurusModelTree.setModel(tghost) self.ui.sardanaElementTree.setModel(msname) def _reloadConf(self, force=False): if not force and self.isDataChanged(): op = Qt.QMessageBox.question(self, "Reload info from door", "If you reload, all current experiment configuration changes will be lost. Reload?", Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return door = self.getModelObj() if door is None: return conf = door.getExperimentConfiguration() self._originalConfiguration = copy.deepcopy(conf) self.setLocalConfig(conf) self._setDirty(False) self._dirtyMntGrps = set() #set a list of available channels avail_channels = {} for ch_info in door.macro_server.getExpChannelElements().values(): avail_channels[ch_info.full_name] = ch_info.getData() self.ui.channelEditor.getQModel().setAvailableChannels(avail_channels) def _setDirty(self, dirty): self._dirty = dirty self._updateButtonBox() def isDataChanged(self): """Tells if the local data has been modified since it was last refreshed :return: (bool) True if he local data has been modified since it was last refreshed """ return bool(self._dirty or self.ui.channelEditor.getQModel().isDataChanged() or self._dirtyMntGrps) def _updateButtonBox(self, *args, **kwargs): self.ui.buttonBox.setEnabled(self.isDataChanged()) def getLocalConfig(self): return self._localConfig def setLocalConfig(self, conf): '''gets a ExpDescription dictionary and sets up the widget''' self._localConfig = conf #set the Channel Editor activeMntGrpName = self._localConfig['ActiveMntGrp'] or '' if activeMntGrpName in self._localConfig['MntGrpConfigs']: mgconfig = self._localConfig['MntGrpConfigs'][activeMntGrpName] self.ui.channelEditor.getQModel().setDataSource(mgconfig) #set the measurement group ComboBox self.ui.activeMntGrpCB.clear() self.ui.activeMntGrpCB.addItems(sorted(self._localConfig['MntGrpConfigs'].keys())) idx = self.ui.activeMntGrpCB.findText(activeMntGrpName) self.ui.activeMntGrpCB.setCurrentIndex(idx) #set the system snapshot list psl = self._localConfig.get('PreScanSnapshot') #I get it before clearing because clear() changes the _localConfig self.ui.preScanList.clear() self.ui.preScanList.addModels(psl) #other settings self.ui.filenameLE.setText(", ".join(self._localConfig['ScanFile'])) self.ui.pathLE.setText(self._localConfig['ScanDir'] or '') self.ui.compressionCB.setCurrentIndex(self._localConfig['DataCompressionRank'] + 1) def writeExperimentConfiguration(self, ask=True): '''sends the current local configuration to the door :param ask: (bool) If True (default) prompts the user before saving. ''' if ask: op = Qt.QMessageBox.question(self, "Save configuration?", 'Do you want to save the current configuration?\n(if not, any changes will be lost)', Qt.QMessageBox.Yes | Qt.QMessageBox.No) if op != Qt.QMessageBox.Yes: return False conf = self.getLocalConfig() #make sure that no empty measurement groups are written for mgname, mgconfig in conf.get('MntGrpConfigs', {}).items(): if mgconfig is not None and not mgconfig.get('controllers'): Qt.QMessageBox.information(self, "Empty Measurement group", "The measurement group '%s' is empty. Fill it (or delete it) before applying" % mgname, Qt.QMessageBox.Ok) self.changeActiveMntGrp(mgname) return False #check if the currently displayed mntgrp is changed if self.ui.channelEditor.getQModel().isDataChanged(): self._dirtyMntGrps.add(self._localConfig['ActiveMntGrp']) door = self.getModelObj() door.setExperimentConfiguration(conf, mnt_grps=self._dirtyMntGrps) self._originalConfiguration = copy.deepcopy(conf) self._dirtyMntGrps = set() self.ui.channelEditor.getQModel().setDataChanged(False) self._setDirty(False) self.emit(Qt.SIGNAL('experimentConfigurationChanged'), copy.deepcopy(conf)) return True def changeActiveMntGrp(self, activeMntGrpName): activeMntGrpName = str(activeMntGrpName) if self._localConfig is None: return if activeMntGrpName == self._localConfig['ActiveMntGrp']: return #nothing changed if activeMntGrpName not in self._localConfig['MntGrpConfigs']: raise KeyError('Unknown measurement group "%s"' % activeMntGrpName) #add the previous measurement group to the list of "dirty" groups if something was changed if self.ui.channelEditor.getQModel().isDataChanged(): self._dirtyMntGrps.add(self._localConfig['ActiveMntGrp']) self._localConfig['ActiveMntGrp'] = activeMntGrpName i = self.ui.activeMntGrpCB.findText(activeMntGrpName, Qt.Qt.MatchExactly) self.ui.activeMntGrpCB.setCurrentIndex(i) mgconfig = self._localConfig['MntGrpConfigs'][activeMntGrpName] self.ui.channelEditor.getQModel().setDataSource(mgconfig) self._setDirty(True) def createMntGrp(self): '''creates a new Measurement Group''' if self._localConfig is None: return mntGrpName, ok = Qt.QInputDialog.getText(self, "New Measurement Group", "Enter a name for the new measurement Group") if not ok: return mntGrpName = str(mntGrpName) #check that the given name is not an existing pool element ms = self.getModelObj().macro_server poolElementNames = [v.name for v in ms.getElementsWithInterface("PoolElement").values()] while mntGrpName in poolElementNames: Qt.QMessageBox.warning(self, "Cannot create Measurement group", "The name '%s' already is used for another pool element. Please Choose a different one." % mntGrpName, Qt.QMessageBox.Ok) mntGrpName, ok = Qt.QInputDialog.getText(self, "New Measurement Group", "Enter a name for the new measurement Group", Qt.QLineEdit.Normal, mntGrpName) if not ok: return mntGrpName = str(mntGrpName) #check that the measurement group is not already in the localConfig if mntGrpName in self._localConfig['MntGrpConfigs']: Qt.QMessageBox.warning(self, "%s already exists" % mntGrpName, 'A measurement group named "%s" already exists. A new one will not be created' % mntGrpName) return #add an empty configuration dictionary to the local config mgconfig = {'label': mntGrpName, 'controllers':{} } self._localConfig['MntGrpConfigs'][mntGrpName] = mgconfig #add the new measurement group to the list of "dirty" groups self._dirtyMntGrps.add(mntGrpName) #add the name to the combobox self.ui.activeMntGrpCB.addItem(mntGrpName) #make it the Active MntGrp self.changeActiveMntGrp(mntGrpName) def deleteMntGrp(self): '''creates a new Measurement Group''' activeMntGrpName = str(self.ui.activeMntGrpCB.currentText()) op = Qt.QMessageBox.question(self, "Delete Measurement Group", "Remove the measurement group '%s'?" % activeMntGrpName, Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return currentIndex = self.ui.activeMntGrpCB.currentIndex() if self._localConfig is None: return if activeMntGrpName not in self._localConfig['MntGrpConfigs']: raise KeyError('Unknown measurement group "%s"' % activeMntGrpName) #add the current measurement group to the list of "dirty" groups self._dirtyMntGrps.add(activeMntGrpName) self._localConfig['MntGrpConfigs'][activeMntGrpName] = None self.ui.activeMntGrpCB.setCurrentIndex(-1) self.ui.activeMntGrpCB.removeItem(currentIndex) self.ui.channelEditor.getQModel().setDataSource({}) self._setDirty(True) def onCompressionCBChanged(self, idx): if self._localConfig is None: return self._localConfig['DataCompressionRank'] = idx - 1 self._setDirty(True) def onPathLEEdited(self, text): self._localConfig['ScanDir'] = str(text) self._setDirty(True) def onFilenameLEEdited(self, text): self._localConfig['ScanFile'] = [v.strip() for v in str(text).split(',')] self._setDirty(True) def onPreScanSnapshotChanged(self, items): door = self.getModelObj() ms = door.macro_server preScanList = [] for e in items: nfo = ms.getElementInfo(e.src) if nfo is None: preScanList.append((e.src, e.display)) else: preScanList.append((nfo.full_name, nfo.name)) self._localConfig['PreScanSnapshot'] = preScanList self._setDirty(True) def onPlotsButtonToggled(self, checked): if checked: from taurus.qt.qtgui.taurusgui.macrolistener import \ DynamicPlotManager self.__plotManager = DynamicPlotManager(self) self.__plotManager.setModel(self.getModelName()) self.connect(self, Qt.SIGNAL('experimentConfigurationChanged'), self.__plotManager.onExpConfChanged) else: self.disconnect(self, Qt.SIGNAL('experimentConfigurationChanged'), self.__plotManager.onExpConfChanged) self.__plotManager.removePanels() self.__plotManager.setModel(None) self.__plotManager = None def demo(model=None): """Experiment configuration""" #w = main_ChannelEditor() w = ExpDescriptionEditor() if model is None: from sardana.taurus.qt.qtgui.extra_macroexecutor import \ TaurusMacroConfigurationDialog dialog = TaurusMacroConfigurationDialog(w) accept = dialog.exec_() if accept: model = str(dialog.doorComboBox.currentText()) if model is not None: w.setModel(model) return w def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Application(app_name="Exp. Description demo", app_version="1.0", org_domain="Sardana", org_name="Tango community") args = app.get_command_line_args() if len(args) == 1: w = demo(model=args[0]) else: w = demo() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/macrotree.py0000644000234000017500000002336712555672637027456 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus text editor widget.""" __all__ = ["MacroTreeWidget", "MacroSelectionDialog"] __docformat__ = 'restructuredtext' from taurus.core.taurusdevice import TaurusDevice from taurus.core.util.enumeration import Enumeration from taurus.external.qt import Qt from taurus.qt.qtcore.mimetypes import TAURUS_MODEL_MIME_TYPE, \ TAURUS_MODEL_LIST_MIME_TYPE from taurus.qt.qtcore.model import TaurusBaseTreeItem, TaurusBaseModel, \ TaurusBaseProxyModel from taurus.qt.qtgui.tree import TaurusBaseTreeWidget from taurus.qt.qtgui.resource import getIcon from sardana.taurus.core.tango.sardana.macro import MacroInfo MacroView = Enumeration("MacroView", ("MacroModule", "Macro", "Unknown")) def getElementTypeIcon(t): if t == MacroView.MacroModule: return getIcon(":/python-file.png") elif t == MacroView.Macro: return getIcon(":/python.png") return getIcon(":/tango.png") def getElementTypeSize(t): return Qt.QSize(200, 24) def getElementTypeToolTip(t): """Wrapper to prevent loading qtgui when this module is imported""" if t == MacroView.MacroModule: return "Macro module" elif t == MacroView.Macro: return "Macro item" return "Unknown" class MacroTreeBaseItem(TaurusBaseTreeItem): """A generic node""" def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ return self._itemData def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown This method should be able to return any kind of python object as long as the model that is used is compatible. :return: (MacroView) the role in form of element type""" return MacroView.Unknown class MacroModuleTreeItem(MacroTreeBaseItem): def role(self): return MacroView.MacroModule def toolTip(self, index): return "The macro module '%s'" % self.display() def icon(self, index): return getIcon(":/python-file.png") class MacroTreeItem(MacroTreeBaseItem): def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ return self._itemData.name def role(self): return MacroView.Macro def toolTip(self, index): return self._itemData.doc def icon(self, index): return getIcon(":/python.png") class MacroBaseModel(TaurusBaseModel): ColumnNames = "Macros", ColumnRoles = (MacroView.MacroModule, MacroView.MacroModule, MacroView.Macro), def setDataSource(self, ms): if self._data_src is not None: Qt.QObject.disconnect(self._data_src, Qt.SIGNAL('macrosUpdated'), self.macrosUpdated) if ms is not None: Qt.QObject.connect(ms, Qt.SIGNAL('macrosUpdated'), self.macrosUpdated) TaurusBaseModel.setDataSource(self, ms) def macrosUpdated(self): self.refresh() def createNewRootItem(self): return MacroTreeBaseItem(self, self.ColumnNames) def roleIcon(self, role): return getElementTypeIcon(role) def columnIcon(self, column): return self.roleIcon(self.role(column)) def roleToolTip(self, role): return getElementTypeToolTip(role) def columnToolTip(self, column): return self.roleToolTip(self.role(column)) def roleSize(self, role): return getElementTypeSize(role) def columnSize(self, column): role = self.role(column) s = self.roleSize(role) return s def mimeTypes(self): return ["text/plain", TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_MODEL_MIME_TYPE] def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: if not index.isValid(): continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: continue data.append(mime_data_item) ret.setData(TAURUS_MODEL_LIST_MIME_TYPE, "\r\n".join(data)) ret.setText(", ".join(data)) if len(data) == 1: ret.setData(TAURUS_MODEL_MIME_TYPE, str(data[0])) return ret def setupModelData(self, data): ms = self.dataSource() if ms is None: return root = self._rootItem macro_modules = {} macro_dict = ms.getMacros() for macro_name, macro in macro_dict.items(): module_name = macro.module moduleNode = macro_modules.get(module_name) if moduleNode is None: moduleNode = MacroModuleTreeItem(self, module_name, root) root.appendChild(moduleNode) macro_modules[module_name] = moduleNode macroNode = MacroTreeItem(self, macro, moduleNode) moduleNode.appendChild(macroNode) class MacroModuleModel(MacroBaseModel): pass class MacroPlainMacroModel(MacroBaseModel): ColumnNames = "Macros", ColumnRoles = (MacroView.Macro, MacroView.Macro), def setupModelData(self, data): ms = self.dataSource() if ms is None: return root = self._rootItem macro_dict = ms.getMacros() macros = macro_dict.keys() macros.sort() self.debug("Found %d macros", len(macros)) for macro_name in macros: macro = macro_dict[macro_name] macroNode = MacroTreeItem(self, macro, root) root.appendChild(macroNode) class MacroBaseModelProxy(TaurusBaseProxyModel): pass class MacroModuleModelProxy(MacroBaseModelProxy): pass class MacroPlainMacroModelProxy(MacroBaseModelProxy): pass class MacroTreeWidget(TaurusBaseTreeWidget): KnownPerspectives = { MacroView.MacroModule : { "label" : "By module", "icon" : ":/python-file.png", "tooltip" : "View by macro module", "model" : [MacroModuleModelProxy, MacroModuleModel], }, MacroView.Macro : { "label" : "By macro", "icon" : ":/python.png", "tooltip" : "View by macro", "model" : [MacroPlainMacroModelProxy, MacroPlainMacroModel], } } DftPerspective = MacroView.MacroModule def getModelClass(self): return TaurusDevice class MacroSelectionDialog(Qt.QDialog): def __init__(self, parent=None, designMode=False, model_name=None, perspective=None): Qt.QDialog.__init__(self, parent) self.setWindowTitle("Macro Selection Dialog") layout = Qt.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self._panel = MacroTreeWidget(parent=self, perspective=perspective, designMode=designMode, with_navigation_bar=False) self._panel.setModel(model_name) self.setWindowIcon(getElementTypeIcon(self._panel.perspective())) self._buttonBox = Qt.QDialogButtonBox(self) bts = Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel self._buttonBox.setStandardButtons(bts) layout.addWidget(self._panel) layout.addWidget(self._buttonBox) self.connect(self._buttonBox, Qt.SIGNAL("accepted()"), self.accept) self.connect(self._buttonBox, Qt.SIGNAL("rejected()"), self.reject) def selectedItems(self): return self._panel.selectedItems() def getSelectedMacros(self): return [ i.itemData() for i in self.selectedItems() ] def main_MacroSelecionDialog(ms, perspective=MacroView.MacroModule): w = MacroSelectionDialog(model_name=ms, perspective=perspective) if w.result() == Qt.QDialog.Accepted: print w.getSelectedMacros() return w def main_MacroTreeWidget(ms, perspective=MacroView.MacroModule): w = MacroTreeWidget(perspective=perspective, with_navigation_bar=False) w.setModel(ms) w.show() return w def demo(): """MacroTreeWidget""" w = main_MacroSelecionDialog("MS_BL98", MacroView.Macro) return w def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Application(app_name="MacroServer macro tree demo", app_version="1.0", org_domain="Taurus", org_name="Tango community") w = demo() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/measurementgroup.py0000644000234000017500000012477312555672637031102 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 a base widget that can be used to display a taurus model in a table widget""" __all__ = ["MntGrpChannelEditor"] __docformat__ = 'restructuredtext' from taurus.core.taurusdevice import TaurusDevice from taurus.external.qt import Qt from taurus.qt.qtcore.model import TaurusBaseTreeItem, TaurusBaseModel from taurus.qt.qtgui.model import EditorToolBar from taurus.qt.qtgui.resource import getIcon, getThemeIcon from taurus.qt.qtgui.table import TaurusBaseTableWidget from taurus.qt.qtgui.panel import TaurusModelChooser from taurus.core.taurusbasetypes import TaurusElementType from sardana.taurus.core.tango.sardana import ChannelView, PlotType, \ Normalization, AcqTriggerType from sardana.taurus.core.tango.sardana.pool import getChannelConfigs #=============================================================================== # some dummydict for developing the "Experimental Configuration widget" # This block is to be removed and the dictionaries will be defined and # initialized in Sardana's Door code # 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' : a value from AcqTriggerType enum # - 'channels' where value is a dict with (at least) keys: # - 'index' : int indicating the position of the channel in the measurement group # - 'id' : the channel name ( channel id ) # optional keys: # - 'enabled' : True/False (default is True) # any hints: # - 'output' : True/False (default is True) # - 'plot_type' : a value from PlotType enum # - '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 #=============================================================================== DEFAULT_STRING_LENGTH = 80 #just an arbitrary value to use as default string length... def createChannelDict(channel, index=None, **kwargs): from taurus.core.tango import FROM_TANGO_TO_STR_TYPE import PyTango import numpy if isinstance(channel, (str, unicode)): #@fixme: to make things uglier, I lazily assume Tango attribute namin dev_name, attr_name = channel.rsplit('/', 1) name = attr_name try: dev = PyTango.DeviceProxy(dev_name) db = dev.get_device_db() try: alias = db.get_alias(dev.name()) except: # no alias... alias = dev.name() label = alias + "/" + attr_name except: label = channel full_name = channel source = channel else: name = channel['name'] label = name full_name = channel['full_name'] source = channel['source'] ret = { 'name' : name, 'label': label, 'full_name': full_name, 'enabled': True, # bool. Whether this channel is enabled (if not enabled, it won't be used for output or plot) 'output': True, # bool. Whether to show output in the stdout 'data_type':'float64', 'data_units': 'No unit', # 'timer': '', #should contain a channel name # 'monitor': '', #should contain a channel name # 'trigger': '', #should contain a channel name 'conditioning': '', #this is a python expresion to be evaluated for conditioning the data. The data for this channel can be referred as 'x' and data from other channels can be referred by channel name 'normalization': Normalization.No, # one of the Normalization enumeration members 'nexus_path': '', #string indicating the location of the data of this channel within the nexus tree } #If the channel is a Tango one, try to guess data_type, shape and data_units attrproxy = attrconf = value = None dtype = shape = None try: attrproxy = PyTango.AttributeProxy(source) attrconf = attrproxy.get_config() # avoid trying to read for scalars. We know that their shape must be () if attrconf.data_format != PyTango.AttrDataFormat.SCALAR: value = attrproxy.read().value except Exception, e: print str(e) if value is not None: shape = list(numpy.shape(value)) dtype = getattr(value, 'dtype', numpy.dtype(type(value))).name ret['data_units'] = attrconf.unit elif attrconf is not None: if attrconf.data_format == PyTango.AttrDataFormat.SCALAR: shape = [] else: shape = [n for n in (attrconf.max_dim_x, attrconf.max_dim_y) if n > 0] dtype = FROM_TANGO_TO_STR_TYPE[attrconf.data_type] ret['data_units'] = attrconf.unit if dtype is not None: # if dtype.startswith('str'): # dtype='char' # shape = list(shape)+[DEFAULT_STRING_LENGTH] # elif dtype == 'bool': # dtype='int8' ret['data_type'] = dtype if shape is not None: ret['shape'] = shape #now overwrite using the arguments ret.update(kwargs) #Calculate the index if index is not None: ret['index'] = index #an integer used for ordering the channel in this measurement group #Choose a default plot_type for the channel if 'plot_type' not in ret: default_plot_type = {0:PlotType.Spectrum, 2:PlotType.Image, None:PlotType.No} try: rank = len(ret['shape']) except KeyError: rank = None #if shape is not known, use the default plot_type ret['plot_type'] = default_plot_type.get(rank, PlotType.No) #And a default value for plot_axes if 'plot_axes' not in ret: default_axes = {PlotType.No:[], PlotType.Spectrum:[''], PlotType.Image:['', '']} ret['plot_axes'] = default_axes[ret['plot_type']] # a string defining a colon-separated list of axis names. An axis can be a channel name or "". This shares the syntax of the NeXus @axes attribute return ret def getElementTypeIcon(t): if t == ChannelView.Channel: return getIcon(":/actions/system-shutdown.svg") elif t == ChannelView.Enabled: return getIcon(":/status/true.svg") elif t == ChannelView.Output: return getThemeIcon("utilities-terminal") elif t == ChannelView.PlotType: return getIcon(":/apps/utilities-system-monitor.svg") elif t == ChannelView.PlotAxes: return getIcon(":/apps/utilities-system-monitor.svg") elif t == ChannelView.Timer: return getIcon(":/status/flag-green-clock.svg") elif t == ChannelView.Monitor: return getIcon(":/status/flag-green.svg") elif t == ChannelView.Trigger: return getIcon(":/actions/system-shutdown.svg") elif t == ChannelView.NXPath: return getThemeIcon("document-save-as") return getIcon(":/tango.png") def getElementTypeSize(t): if t == ChannelView.Channel: return Qt.QSize(200, 24) elif t == ChannelView.Enabled: return Qt.QSize(50, 24) elif t == ChannelView.Output: return Qt.QSize(50, 24) elif t == ChannelView.PlotType: return Qt.QSize(50, 24) return Qt.QSize(50, 24) def getElementTypeToolTip(t): """Wrapper to prevent loading qtgui when this module is imported""" if t == ChannelView.Channel: return "Channel" elif t == ChannelView.Enabled: return "Channel active or not" elif t == ChannelView.Output: return "Channel output active or not" elif t == ChannelView.Shape: return "Shape of the data (using numpy convention). For example, a scalar will have shape=(), a spectrum of 10 elements will have shape=(10,) and an image of 20x30 will be shape=(20,30)" elif t == ChannelView.DataType: return "Type of data for storing (valid types are: char, float32, float64, [u]int{8|16|32|64})", elif t == ChannelView.PlotType: return "Plot type for this channel " elif t == ChannelView.PlotAxes: return "Independent variables to be used in the plot of this channel" elif t == ChannelView.Timer: return "The channel to be used as the timer" elif t == ChannelView.Monitor: return "The channel to be used as a monitor for stopping the acquisition" elif t == ChannelView.Trigger: return "The channel to be used for triggering the acquisition" elif t == ChannelView.Conditioning: return "An expression to evaluate on the data when displaying it" elif t == ChannelView.Normalization: return "Normalization mode for the data" elif t == ChannelView.NXPath: return "Location of the data of this channel within the NeXus tree" return "Unknown" class BaseMntGrpChannelItem(TaurusBaseTreeItem): """ """ def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ return self._itemData def role(self): """Returns the prefered role for the item. This implementation returns ChannelView.Unknown This method should be able to return any kind of python object as long as the model that is used is compatible. :return: (MacroView) the role in form of element type""" return ChannelView.Unknown class MntGrpChannelItem(BaseMntGrpChannelItem): itemdata_keys_map = {ChannelView.Channel:'label', ChannelView.Enabled:'enabled', ChannelView.Output:'output', ChannelView.Shape:'shape', ChannelView.DataType:'data_type', ChannelView.PlotType:'plot_type', ChannelView.PlotAxes:'plot_axes', # ChannelView.Timer:'timer', # ChannelView.Monitor:'monitor', # ChannelView.Trigger:'trigger', ChannelView.Conditioning:'conditioning', ChannelView.Normalization:'normalization', ChannelView.NXPath:'nexus_path' } def data(self, index): """Returns the data of this node for the given index :return: (object) the data for the given index """ taurus_role = index.model().role(index.column()) ch_name, ch_data = self.itemData() key = self.itemdata_keys_map[taurus_role] ret = ch_data[key] if taurus_role == ChannelView.PlotType: ret = PlotType[ret] elif taurus_role == ChannelView.Normalization: ret = Normalization[ret] elif taurus_role == ChannelView.PlotAxes: ret = ":".join(ret) elif taurus_role == ChannelView.Shape: ret = str(ret) return ret def setData(self, index, qvalue): taurus_role = index.model().role(index.column()) str_value = Qt.from_qvariant(qvalue, str) if taurus_role in (ChannelView.Channel, ChannelView.Conditioning, ChannelView.NXPath, ChannelView.DataType) : data = str_value elif taurus_role in (ChannelView.Enabled, ChannelView.Output) : data = Qt.from_qvariant(qvalue, bool) elif taurus_role == ChannelView.PlotType: data = PlotType[str_value] elif taurus_role == ChannelView.Normalization: data = Normalization[str_value] elif taurus_role == ChannelView.PlotAxes: data = [a for a in str_value.split(':')] elif taurus_role == ChannelView.Shape: s = str_value try: data = eval(s, {}, {}) if not isinstance(data, (tuple, list)): raise ValueError except: from taurus.core.util.log import Logger Logger(self.__class__.__name__).error('Invalid shape %s', s) data = () else: raise NotImplementedError('Unknown role') ch_name, ch_data = self.itemData() key = self.itemdata_keys_map[taurus_role] ch_data[key] = data def role(self): return ChannelView.Channel def toolTip(self, index): return "Channel " + self._itemData[0] def icon(self, index): taurus_role = index.model().role(index.column()) if taurus_role == ChannelView.Channel: return getIcon(":/actions/system-shutdown.svg") class MntGrpUnitItem(TaurusBaseTreeItem): pass class BaseMntGrpChannelModel(TaurusBaseModel): ColumnNames = ("Channel", "enabled", "output", "Shape", "Data Type", "Plot Type", "Plot Axes", "Timer", "Monitor", "Trigger", "Conditioning", "Normalization", "NeXus Path") ColumnRoles = ((ChannelView.Channel, ChannelView.Channel), ChannelView.Enabled, ChannelView.Output, ChannelView.Shape, ChannelView.DataType, ChannelView.PlotType, ChannelView.PlotAxes, ChannelView.Timer, ChannelView.Monitor, ChannelView.Trigger, ChannelView.Conditioning, ChannelView.Normalization, ChannelView.NXPath) DftFont = Qt.QFont() _availableChannels = {} data_keys_map = {ChannelView.Timer:'timer', ChannelView.Monitor:'monitor', ChannelView.Trigger:'trigger_type', } def __init__(self, parent=None, data=None): TaurusBaseModel.__init__(self, parent=parent, data=data) self._mgconfig = None self._dirty = False def setAvailableChannels(self, cdict): self._availableChannels = cdict def getAvailableChannels(self): return self._availableChannels def createNewRootItem(self): return BaseMntGrpChannelItem(self, self.ColumnNames) def roleIcon(self, taurus_role): return getElementTypeIcon(taurus_role) def roleSize(self, taurus_role): return getElementTypeSize(taurus_role) def roleToolTip(self, taurus_role): return getElementTypeToolTip(taurus_role) def getPyData(self, ctrlname=None, unitid=None, chname=None, key=None): ''' If controller name, unitid and channel name are given, it returns the dictionary with the channel info. If only controller name and unit id are given, it returns the dictionary with the unit info. If only controller name is given, it returns the dictionary with the controller info. Note that it will raise a KeyError exception if any of the keys are not found or if chname is given without providing the unit id ''' if ctrlname is None: raise ValueError('controller name must be passed') if unitid is None: return self._mgconfig['controllers'][ctrlname] elif chname is None: return self._mgconfig['controllers'][ctrlname]['units'][unitid] else: return self._mgconfig['controllers'][ctrlname]['units'][unitid]['channels'][chname] def setupModelData(self, mgconfig): if mgconfig is None: return root = self._rootItem #@The root could eventually be changed for each unit or controller channelNodes = [MntGrpChannelItem(self, chcfg, root) for chcfg in getChannelConfigs(mgconfig)] for ch in channelNodes: root.appendChild(ch) self.updateMntGrpChannelIndex(root=root) #store the whole config object for accessing the info that is not at the channel level self._mgconfig = mgconfig def setDataSource(self, data_src): self._dirty = False TaurusBaseModel.setDataSource(self, data_src) def updateMntGrpChannelIndex(self, root=None): ''' assigns the MeasurementGroup index (the internal order in the MG) according to the order in the QModel ''' if root is None: root = self._rootItem for row in range(root.childCount()): chname, chdata = root.child(row).itemData() chdata['index'] = row def flags(self, index): flags = TaurusBaseModel.flags(self, index) taurus_role = self.role(index.column()) if taurus_role == ChannelView.Channel: #channel column is not editable return flags elif taurus_role == ChannelView.Trigger: ch_name, ch_data = index.internalPointer().itemData() if not ch_data['_controller_name'].startswith("__"): ch_info = self.getAvailableChannels()[ch_name] #only timer/monitor columns of counter timers are editable if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): flags |= Qt.Qt.ItemIsEditable elif taurus_role in (ChannelView.Timer, ChannelView.Monitor): ch_name, ch_data = index.internalPointer().itemData() if not ch_data['_controller_name'].startswith("__"): #ch_info = self.getAvailableChannels()[ch_name] #if 'CTExpChannel' == ch_info['type']: #only timer/monitor columns of counter timers are editable # flags |= Qt.Qt.ItemIsEditable flags |= Qt.Qt.ItemIsEditable else: flags |= Qt.Qt.ItemIsEditable return flags def data(self, index, role=Qt.Qt.DisplayRole): """Reimplemented from :meth:`TaurusBaseModel.data` :return: (object) the data for the given index """ #Try with the normal TaurusBaseModel item-oriented approach try: return TaurusBaseModel.data(self, index, role=role) except: pass #For those things which are inter-item, we handle them here taurus_role = self.role(index.column()) if taurus_role == ChannelView.Trigger: ch_name, ch_data = index.internalPointer().itemData() unitdict = self.getPyData(ctrlname=ch_data['_controller_name'], unitid=ch_data['_unit_id']) key = self.data_keys_map[taurus_role] return Qt.QVariant(AcqTriggerType[unitdict.get(key, None)]) elif taurus_role in (ChannelView.Timer, ChannelView.Monitor): ch_name, ch_data = index.internalPointer().itemData() ctrlname = ch_data['_controller_name'] if ctrlname.startswith("__"): return Qt.QVariant() ch_info = self.getAvailableChannels()[ch_name] if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): unitdict = self.getPyData(ctrlname=ctrlname, unitid=ch_data['_unit_id']) key = self.data_keys_map[taurus_role] master_full_name = unitdict.get(key, None) else: key = taurus_role == ChannelView.Timer and 'timer' or 'monitor' master_full_name = self._mgconfig.get(key, None) if master_full_name is None: return Qt.QVariant() else: master_info = self.getAvailableChannels()[master_full_name] return Qt.QVariant(master_info['name']) return Qt.QVariant() def setData(self, index, qvalue, role=Qt.Qt.EditRole): #For those things which are at the unit level, we handle them here taurus_role = self.role(index.column()) if taurus_role in (ChannelView.Timer, ChannelView.Monitor, ChannelView.Trigger): ch_name, ch_data = index.internalPointer().itemData() ch_info = self.getAvailableChannels()[ch_name] unit_data = self.getPyData(ctrlname=ch_data['_controller_name'], unitid=ch_data['_unit_id']) key = self.data_keys_map[taurus_role] data = Qt.from_qvariant(qvalue, str) self._dirty = True self.beginResetModel() is_settable = ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel') if taurus_role == ChannelView.Trigger: data = AcqTriggerType[data] if is_settable: unit_data[key] = data else: if is_settable: if unit_data[key] == self._mgconfig[key]: self._mgconfig[key] = data unit_data[key] = data else: self._mgconfig[key] = data self.endResetModel() return True #for the rest, we use the regular TaurusBaseModel item-oriented approach #ret = self._setData(index, qvalue, role) #@todo we do not use _setData because it is not Qt4.4-compatible item = index.internalPointer() item.setData(index, qvalue) self._dirty = True self.emit(Qt.SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), index, index) return True def addChannel(self, chname=None, chinfo=None, ctrlname=None, unitname=None, external=False): #@todo: Very inefficient implementation. We should use {begin|end}InsertRows if chname is None: chname = chinfo['full_name'] chname = str(chname) if ctrlname is None: desc = self.getAvailableChannels()[chname] ctrlname = desc['controller'] if unitname is None: desc = self.getAvailableChannels()[chname] unitname = desc.get('unit', '0') #@fixme: at the moment of writing, the unit info cannot be obtained from desc #update the internal data self.beginResetModel() #we are altering the internal data here, so we need to protect it ctrlsdict = self.dataSource()['controllers'] if not ctrlsdict.has_key(ctrlname): ctrlsdict[ctrlname] = {'units':{}} unitsdict = ctrlsdict[ctrlname]['units'] if not unitsdict.has_key(unitname): unitsdict[unitname] = unit = {'channels':{}} if not external and chinfo['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): unit['timer'] = chname unit['monitor'] = chname unit['trigger_type'] = AcqTriggerType.Software channelsdict = unitsdict[unitname]['channels'] if channelsdict.has_key(chname): self.error('Channel "%s" is already in the measurement group. It will not be added again' % chname) return self._dirty = True if external: channelsdict[chname] = createChannelDict(chname) else: channelsdict[chname] = createChannelDict(chinfo) self.endResetModel() #we are altering the internal data here, so we need to protect it self.refresh() #note that another reset will be done here... #import pprint #pprint.pprint(self.dataSource()) def removeChannels(self, chnames): #@todo: Very inefficient implementation. We should use {begin|end}InsertRows #update the internal data self._dirty = True self.beginResetModel() #we are altering the internal data here, so we need to protect it for chname in chnames: avail_channels = self.getAvailableChannels() if chname in avail_channels: desc = self.getAvailableChannels()[chname] ctrlname = desc['controller'] unitname = desc.get('unit', '0') #@fixme: at the moment of writing, the unit info cannot be obtained from desc else: #@todo: This assumes that if it is not in the list of avail_channels, it must be an external tango channel ctrlname = '__tango__' unitname = '0' try: self.dataSource()['controllers'][ctrlname]['units'][unitname]['channels'].pop(chname) try: if not self.dataSource()['controllers'][ctrlname]['units'][unitname]['channels']: self.dataSource()['controllers'][ctrlname]['units'].pop(unitname) if not self.dataSource()['controllers'][ctrlname]['units']: self.dataSource()['controllers'].pop(ctrlname) except: self.error('error cleaning the data source dictionary') except: self.error('cannot find "%s" for removing' % chname) self.endResetModel() #we are altering the internal data here, so we need to protect it self.refresh() #note that another reset will be done here... def swapChannels(self, root, row1, row2): #@todo: Very inefficient implementation. We should use {begin|end}MoveRows self._dirty = True n1, d1 = root.child(row1).itemData() n2, d2 = root.child(row2).itemData() d1['index'], d2['index'] = d2['index'], d1['index'] self.debug("swapping %s with %s" % (n1, n2)) self.refresh() def isDataChanged(self): return self._dirty def setDataChanged(self, datachanged): self._dirty = datachanged class MntGrpChannelModel(BaseMntGrpChannelModel): '''A BaseMntGrpChannelModel that communicates with a MntGrp device for setting and reading the configuration ''' def setDataSource(self, mg): if self._data_src is not None: Qt.QObject.disconnect(self._data_src, Qt.SIGNAL('configurationChanged'), self.configurationChanged) if mg is not None: Qt.QObject.connect(mg, Qt.SIGNAL('configurationChanged'), self.configurationChanged) BaseMntGrpChannelModel.setDataSource(self, mg) def configurationChanged(self): self.refresh() def setupModelData(self, mg): if mg is None: return BaseMntGrpChannelModel.setupModelData(self, self.getSourceData()) def writeSourceData(self): mg = self.dataSource() if mg is not None and self._mgconfig is not None: mg.setConfiguration(self._mgconfig) def getSourceData(self): """Gets data from the dataSource""" mg = self.dataSource() if mg is not None: return mg.getConfiguration() def getLocalData(self): """Gets the local data (may be different from the one in the data source since it may have been modified by the user)""" return self._mgconfig class AxesSelector(Qt.QWidget): def __init__(self, parent, n=0, choices=None): '''Shows n comboboxes populated with choices. If n is 0, it just shows a LineEdit instead''' Qt.QWidget.__init__(self, parent) self._n = n self._CBs = [] self._LE = None l = Qt.QHBoxLayout(self) if self._n == 0: self._LE = Qt.QLineEdit() l.addWidget(self._LE) else: for i in range(n): cb = Qt.QComboBox() l.addWidget(cb) self._CBs.append(cb) if choices is not None: self.setChoices(choices) def setChoices(self, choices): for cb in self._CBs: cb.addItems(choices) def text(self): return ":".join(self.getCurrentChoices()) def getCurrentChoices(self): if self._LE is None: return [str(cb.currentText()) for cb in self._CBs] else: return [str(self._LE.text())] def setCurrentChoices(self, choice): if self._LE is None: texts = str(choice).split(':') for t, cb in zip(texts[:len(self._CBs)], self._CBs): cb.setCurrentIndex(max(0, cb.findText(t))) else: self._LE.setText(str(choice)) class ChannelDelegate(Qt.QStyledItemDelegate): def createEditor(self, parent, option, index): model = index.model() taurus_role = model.role(index.column()) if taurus_role in (ChannelView.Channel, ChannelView.PlotType, ChannelView.Normalization, ChannelView.Timer, ChannelView.Monitor, ChannelView.Trigger): ret = Qt.QComboBox(parent) elif taurus_role == ChannelView.PlotAxes: item = index.internalPointer() ptype = item.itemData()[1]['plot_type'] if ptype == PlotType.Spectrum: n = 1 elif ptype == PlotType.Image: n = 2 else: return None ret = AxesSelector(parent, n=n) else: ret = Qt.QStyledItemDelegate.createEditor(self, parent, option, index) ret.setAutoFillBackground(True) return ret def setEditorData(self, editor, index): model = index.model() dataSource = model.dataSource() taurus_role = model.role(index.column()) if taurus_role == ChannelView.PlotType: editor.addItems(PlotType.keys()) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentIndex(editor.findText(current)) elif taurus_role == ChannelView.Normalization: editor.addItems(Normalization.keys()) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentIndex(editor.findText(current)) elif taurus_role in (ChannelView.Timer, ChannelView.Monitor): key = taurus_role == ChannelView.Timer and 'timer' or 'monitor' ch_name, ch_data = index.internalPointer().itemData() ctrl_filterlist = [ch_data['_controller_name']] ctrl_dict = getChannelConfigs(dataSource, ctrls=ctrl_filterlist) all_channels = model.getAvailableChannels() # if it is a timer capable type of element if all_channels[ch_name]['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): for full_name, channel_data in ctrl_dict: editor.addItem(channel_data['name'], Qt.QVariant(full_name)) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentIndex(editor.findText(current)) else: for ctrl_data in dataSource['controllers'].values(): for unit_data in ctrl_data['units'].values(): if key in unit_data: channel = all_channels[unit_data[key]] editor.addItem(channel['name'], Qt.QVariant(channel['full_name'])) current = dataSource.get(key) # current global timer/monitor editor.setCurrentIndex(editor.findData(Qt.QVariant(current))) elif taurus_role == ChannelView.Trigger: editor.addItems(AcqTriggerType.keys()) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentIndex(editor.findText(current)) elif taurus_role == ChannelView.PlotAxes: selectables = ['', ''] + [n for n, d in getChannelConfigs(dataSource)] editor.setChoices(selectables) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentChoices(current) else: Qt.QStyledItemDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index): taurus_role = model.role(index.column()) dataSource = model.dataSource() if taurus_role in (ChannelView.Channel, ChannelView.PlotType, ChannelView.Normalization): data = Qt.QVariant(editor.currentText()) model.setData(index, data) elif taurus_role == ChannelView.Trigger: old_value = Qt.from_qvariant(model.data(index), str) new_value = str(editor.currentText()) if new_value == old_value: return ch_name, ch_data = index.internalPointer().itemData() channels = getChannelConfigs(dataSource, ctrls=[ch_data['_controller_name']], units=[ch_data['_unit_id']]) affected = [d['name'] for n, d in channels] if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return data = Qt.QVariant(new_value) model.setData(index, data) elif taurus_role in (ChannelView.Timer, ChannelView.Monitor): key = taurus_role == ChannelView.Timer and 'timer' or 'monitor' old_value = Qt.from_qvariant(model.data(index), str) new_value = str(editor.currentText()) if new_value == old_value: return ch_name, ch_data = index.internalPointer().itemData() all_channels = model.getAvailableChannels() # if it is a timer capable type of element ch_info = all_channels[ch_name] selected_master = editor.itemData(editor.currentIndex()) if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): affected = [] unit_data = model.getPyData(ctrlname=ch_data['_controller_name'], unitid=ch_data['_unit_id']) channels = getChannelConfigs(dataSource, ctrls=[ch_data['_controller_name']], units=[ch_data['_unit_id']]) for n, d in channels: affected.append(d['name']) # if old timer/monitor was also the global, then non # timerable/monitorable channels must be changed if unit_data[key] == dataSource.get(key): for n, d in getChannelConfigs(dataSource): if d['_controller_name'].startswith("__"): continue ch_info = all_channels[n] if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): continue affected.append(d['name']) if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return else: affected = [] channels = getChannelConfigs(dataSource) for n, d in channels: if d['_controller_name'].startswith("__"): continue ch_info = all_channels[n] if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): continue affected.append(d['name']) if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return model.setData(index, selected_master) elif taurus_role == ChannelView.PlotAxes: data = Qt.QVariant(editor.text()) model.setData(index, data) else: Qt.QStyledItemDelegate.setModelData(self, editor, model, index) class MntGrpChannelEditor(TaurusBaseTableWidget): """ """ KnownPerspectives = { "Channel" : { "label" : "Channels", "icon" : ":/actions/system-shutdown.svg", "tooltip" : "View by channel", "model" : [BaseMntGrpChannelModel, ], }, } DftPerspective = "Channel" _simpleViewColumns = (ChannelView.Channel, ChannelView.Output, ChannelView.Shape, ChannelView.PlotType, ChannelView.PlotAxes) _simpleView = False def __init__(self, parent=None, designMode=False, with_filter_widget=True, perspective=None): TaurusBaseTableWidget.__init__(self, parent=parent, designMode=designMode, with_filter_widget=with_filter_widget, perspective=perspective, proxy=None) self.setContextMenuPolicy(Qt.Qt.ActionsContextMenu) self._simpleViewAction = Qt.QAction("Simple View", self) self._simpleViewAction.setCheckable(True) self.connect(self._simpleViewAction, Qt.SIGNAL("toggled(bool)"), self.setSimpleView) self.addAction(self._simpleViewAction) self.registerConfigProperty(self.isSimpleView, self.setSimpleView, "simpleView") def isSimpleView(self): return self._simpleView def setSimpleView(self, simpleview): if simpleview == self.isSimpleView(): return columnRoles = list(self.getQModel().ColumnRoles) columnRoles[0] = columnRoles[0][-1] #account for the fact that the first element is a tuple instead of a role columnIndexes = [columnRoles.index(r) for r in self._simpleViewColumns] for i in range(self.getQModel().columnCount()): hide = simpleview and (i not in columnIndexes) self.tableView().setColumnHidden(i, hide) self._simpleView = simpleview self._simpleViewAction.setChecked(simpleview) def resetSimpleView(self): self.setSimpleView(False) def createViewWidget(self): tableView = TaurusBaseTableWidget.createViewWidget(self) self._delegate = ChannelDelegate(self) #self._delegate.setItemEditorFactory(Qt.QItemEditorFactory()) #This causes a segfault when calling ChannelDelegate.createEditor tableView.setItemDelegate(self._delegate) tableView.setSortingEnabled(False) self.connect(self._editorBar, Qt.SIGNAL("addTriggered"), self.addChannel) self.connect(self._editorBar, Qt.SIGNAL("removeTriggered"), self.removeChannels) self.connect(self._editorBar, Qt.SIGNAL("moveUpTriggered"), self.moveUpChannel) self.connect(self._editorBar, Qt.SIGNAL("moveDownTriggered"), self.moveDownChannel) return tableView def createToolArea(self): ta = TaurusBaseTableWidget.createToolArea(self) e_bar = self._editorBar = EditorToolBar(self, self) ta.append(e_bar) return ta def getModelClass(self): return TaurusDevice def addChannel(self, channel=None): qmodel = self.getQModel() dataSource = qmodel.dataSource() if channel is None: shown = [n for n, d in getChannelConfigs(dataSource)] avail_channels = qmodel.getAvailableChannels() clist = [ ch_info['name'] for ch_name, ch_info in avail_channels.items() if ch_name not in shown ] clist = sorted(clist) + ['(Other...)'] chname, ok = Qt.QInputDialog.getItem(self, "New Channel", "Choose channel:", clist, 0, False) if not ok: return chname = str(chname) if chname == '(Other...)': models, ok = TaurusModelChooser.modelChooserDlg(parent=self, singleModel=False, windowTitle='Choose source of data', selectables=[TaurusElementType.Attribute]) if not ok: return for m in models: qmodel.addChannel(chname=m, ctrlname='__tango__', unitname='0', external=True) else: for ch_info in avail_channels.values(): if ch_info['name'] == chname: qmodel.addChannel(chinfo=ch_info) def removeChannels(self, channels=None): if channels is None: channels = self.selectedItems() chnames = [ch.itemData()[0] for ch in channels] self.getQModel().removeChannels(chnames) def moveUpChannel(self, channel=None): if channel is None: channels = self.selectedItems() if len(channels) != 1: return channel = channels[0] parent = channel.parent() row = channel.row() if row < 1: return model = self.getQModel() model.swapChannels(parent, row, row - 1) idx = model.index(row - 1, 0) self.viewWidget().setCurrentIndex(idx) def moveDownChannel(self, channel=None): if channel is None: channels = self.selectedItems() if len(channels) != 1: return channel = channels[0] parent = channel.parent() row = channel.row() if row >= parent.childCount() - 1: return model = self.getQModel() self.getQModel().swapChannels(parent, row, row + 1) idx = model.index(row + 1, 0) self.viewWidget().setCurrentIndex(idx) def getLocalConfig(self): return self.getQModel().getLocalData() @classmethod def getQtDesignerPluginInfo(cls): ret = TaurusBaseTableWidget.getQtDesignerPluginInfo() ret['module'] = 'taurus.qt.qtgui.extra_sardana' ret['group'] = 'Taurus Sardana' ret['icon'] = ":/designer/table.png" return ret simpleView = Qt.pyqtProperty("bool", isSimpleView, setSimpleView, resetSimpleView) sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/sardanabasewizard.py0000644000234000017500000000445612555672637031160 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana base wizard classes.""" __all__ = ["SardanaBaseWizard"] __docformat__ = 'restructuredtext' from taurus.external.qt import Qt class SardanaBasePage(Qt.QWizardPage): def __init__(self, parent=None): Qt.QWizardPage.__init__(self, parent) self._item_funcs = {} def __setitem__(self, name, value): self._item_funcs[name] = value def __getitem__(self, name): return self._item_funcs[name] def getPanelWidget(self): return self._panel class SardanaBaseWizard(Qt.QWizard): def __init__(self, parent=None): Qt.QWizard.__init__(self, parent) self._item_funcs = {} self._pages = {} def __setitem__(self, name, value): self._item_funcs[name] = value def __getitem__(self, name): for id in self.getPages(): p = self.page(id) if isinstance(p, SardanaBasePage): try: return p[name]() except Exception, e: pass return self._item_funcs[name]() return None def addPage(self, page): id = Qt.QWizard.addPage(self, page) self._pages[id] = page def setPage(self, id, page): Qt.QWizard.setPage(self, id, page) self._pages[id] = page def getPages(self): return self._pages sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/sardanaeditor.py0000644000234000017500000005122712555672637030311 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 taurus text editor widget.""" __all__ = ["SardanaEditor"] __docformat__ = 'restructuredtext' import os import os.path as osp import tempfile import shutil import functools from taurus.external.qt import Qt from taurus.qt.qtgui.base import TaurusBaseWidget from taurus.qt.qtgui.editor import TaurusBaseEditor from taurus.qt.qtgui.util import ActionFactory from taurus.qt.qtgui.dialog import ProtectTaurusMessageBox from macrotree import MacroSelectionDialog from elementtree import SardanaElementTreeWidget from sardana.taurus.qt.qtcore.tango.sardana.model import SardanaBaseProxyModel, \ SardanaElementTypeModel, SardanaTypeTreeItem, SardanaRootTreeItem from sardanabasewizard import SardanaBaseWizard, SardanaBasePage _MACRO_LIB_TEMPLATE = """#!/usr/bin/env python {copyright} # don't forget to place every new macro here! __all__ = [] __docformat__ = 'restructuredtext' {non_sardana_imports} from sardana.macroserver.macro import macro, Macro, Type {sardana_imports} # Place your code here! """ _MACRO_CLASS_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_FUNCTION_TEMPLATE = """ @macro() def {macro_name}(self): self.output("Running {macro_name}...") """ class NewElementWizard(SardanaBaseWizard): pass class ChooseElementTypePage(SardanaBasePage): def __init__(self, parent=None): SardanaBasePage.__init__(self, parent) self.setTitle('Please select type of element you wish to create') layout = Qt.QVBoxLayout() self.setLayout(layout) class SardanaLibProxyModel(SardanaBaseProxyModel): ALLOWED_TYPES = 'MacroLibrary', #'ControllerLibrary', def filterAcceptsRow(self, sourceRow, sourceParent): sourceModel = self.sourceModel() idx = sourceModel.index(sourceRow, 0, sourceParent) treeItem = idx.internalPointer() if isinstance(treeItem, SardanaRootTreeItem): return True if isinstance(treeItem, SardanaTypeTreeItem): return treeItem.itemData() in self.ALLOWED_TYPES return True class SardanaLibTreeWidget(SardanaElementTreeWidget): KnownPerspectives = { "Type" : { "label" : "By lib", "icon" : ":/python-package.png", "tooltip" : "View elements by library", "model" : [SardanaLibProxyModel, SardanaElementTypeModel], }, } DftPerspective = "Type" class SardanaEditor(TaurusBaseEditor, TaurusBaseWidget): def __init__(self, parent=None, designMode=None): name = self.__class__.__name__ self._base_tmp_dir = None self._tmp_dir = None self._is_filesystem_prepared = False self.call__init__wo_kw(TaurusBaseEditor, parent) self.call__init__(TaurusBaseWidget, name, designMode=designMode) self._elementTree = elementTree = \ SardanaLibTreeWidget(self, with_navigation_bar=False, with_filter_widget=False,) elementTree.treeView().setColumnHidden(1, True) self.connect(self._elementTree, Qt.SIGNAL("itemDoubleClicked"), self.on_element_clicked) self.insertWidget(0, self._elementTree) self.setAutoTooltip(False) def setTemporaryDirectory(self, tmp_dir): self._base_tmp_dir = tmp_dir self._is_filesystem_prepared = False def getTemporaryDirectory(self): return self._base_tmp_dir def createMenuActions(self): af = ActionFactory() on_save = functools.partial(self.on_save, apply=False) on_save_apply = functools.partial(self.on_save, apply=True) self.new_action = af.createAction(self, "New...", icon='document-new', tip="Create a new macro or controller class", triggered=self.on_new, shortcut=Qt.QKeySequence.New) self.open_action = af.createAction(self, "Open...", icon='document-open', tip="Open macro(s) or controller(s)", triggered=self.on_open, shortcut=Qt.QKeySequence.Open) self.save_action = af.createAction(self, "Save", icon='document-save', tip="Save the current selected item", triggered=on_save) self.save_and_apply_action = af.createAction(self, "Save && apply", triggered=on_save_apply, icon='document-save', tip="Save the current selected item and apply the new code", shortcut=Qt.QKeySequence.Save) self.revert_action = af.createAction(self, "Revert", icon='edit-undo', tip="Revert the current selected item code", triggered=self.on_revert) io_actions = [self.new_action, self.open_action, self.save_action, self.revert_action] actions = [self.new_action, self.open_action, self.save_action, self.save_and_apply_action, self.revert_action] return actions, io_actions def register_editorstack(self, editorstack): TaurusBaseEditor.register_editorstack(self, editorstack) self.connect(editorstack, Qt.SIGNAL('refresh_save_all_action()'), self.refresh_save_and_apply_action) def refresh_save_and_apply_action(self): self.save_and_apply_action.setEnabled(self.save_action.isEnabled()) def on_element_clicked(self, item, item_column): item_data = item.itemData() interfaces = item_data.interfaces if 'MacroCode' in interfaces: self.open_macros([item_data]) elif 'MacroLibrary' in interfaces: self.open_macro_libraries([item_data]) @ProtectTaurusMessageBox(title="A error occured trying to create a class") def on_new(self): elem_types = "Macro function", "Macro class", "Macro library", \ "Motor controller class", "Counter/Timer controller class", \ "Pseudo motor controller class" msg = "Please select type of element you wish to create" elem_type, ok = Qt.QInputDialog.getItem(self, "New", msg, elem_types, current=0, editable=False) if not ok: return idx = elem_types.index(elem_type) if idx == 0: return self.new_macro_function() elif idx == 1: return self.new_macro_class() elif idx == 2: return self.new_macro_library() raise NotImplementedError("Sorry! Not implemented yet.") def new_macro(self, template): macro_server = self.getModelObj() msg = "Please select the library where you want to place the new macro" macro_libraries = macro_server.getElementsOfType("MacroLibrary") macro_lib_names = macro_libraries.keys() macro_lib_names.sort() macro_lib_name, ok = Qt.QInputDialog.getItem(self, "Macro library", msg, macro_lib_names, current=0, editable=False) if not ok: return macro_lib_name = str(macro_lib_name) macro_lib = macro_libraries[macro_lib_name] fname, path = macro_lib.file_path, macro_lib.path fname = fname[fname.index(osp.sep) + 1:] # transform into relative path local_filename = osp.join(self._tmp_dir, fname) msg = "Please give new macro name" macros = macro_lib.elements valid = False while not valid: macro_name, ok = Qt.QInputDialog.getText(self, "Macro name", msg) if not ok: return if macro_name in macros: res = Qt.QMessageBox.information(self, "Macro already exists", "A macro named '%s' already exists in '%s'.\n" "Please give a different macro name" % (macro_name, macro_lib_name), Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel, Qt.QMessageBox.Ok) if res == Qt.QMessageBox.Cancel: return continue valid = True pars = dict(macro_name=macro_name) code = template.format(**pars) editorstack = self.editorStack() idx = editorstack.has_filename(local_filename) if idx is None: if not self._prepare_path(path): raise Exception("Error trying to prepare path for %s", path) self.debug("Creating local file %s...", local_filename) fname, lib_code, line = macro_server.GetMacroCode((macro_lib_name,)) fd = file(local_filename, "w") fd.write(lib_code) fd.close() self.debug("Loading local file %s...", local_filename) self.load(local_filename, goto=None) else: pass editorstack.set_current_filename(local_filename) editor = editorstack.get_current_editor() editor.set_cursor_position(editor.get_position("eof")) editor.append(code) return macro_lib, macro_name def new_macro_class(self): macro_info = self.new_macro(_MACRO_CLASS_TEMPLATE) if macro_info is None: return macro_lib, macro_name = macro_info def new_macro_function(self): macro_info = self.new_macro(_MACRO_FUNCTION_TEMPLATE) if macro_info is None: return macro_lib, macro_name = macro_info def new_macro_library(self): ms = self.getModelObj() ms_path = ms.getMacroPathObj() directory, ok = Qt.QInputDialog.getItem(self, "New macro module", "Select the directory where you want the new macro module to " \ "be placed", ms_path.macro_path, current=0, editable=False) if not ok: return directory = str(directory) ok = 0 while not ok: mod, ok = Qt.QInputDialog.getText(self, "New macro module", "Module name:", Qt.QLineEdit.Normal, "") if not ok: return mod = str(mod) m, ext = osp.splitext(mod) if len(ext): if ext != ".py" : Qt.QMessageBox.critical(self, "Wrong extension", "When given, file extension MUST be .py.") ok = 0 continue else: mod = mod + ".py" self._prepare_path(directory) filename = osp.join(directory, mod) rel_filename = filename[filename.index(osp.sep) + 1:] # transform into relative path local_filename = osp.join(self._tmp_dir, rel_filename) f = file(local_filename, "w") #TODO: ask for additional imports #TODO: check if door environment has copyright variable pars = dict(copyright="", non_sardana_imports="", sardana_imports="") code = _MACRO_LIB_TEMPLATE.format(**pars) f.write(code) f.close() self.editorStack().load(local_filename) @ProtectTaurusMessageBox(title="An error occured trying to open a macro class") def on_open(self): ms = self.getModelObj() ms_tree = MacroSelectionDialog(self, model_name=ms.getNormalName()) ms_tree.exec_() if ms_tree.result() != Qt.QDialog.Accepted: return self.open_macros(ms_tree.getSelectedMacros()) @ProtectTaurusMessageBox(title="An error occured trying to open macro(s)") def open_macros(self, macros): editorstack = self.editorStack() all_any = Qt.QMessageBox.YesToAll, Qt.QMessageBox.NoToAll yes_any = Qt.QMessageBox.Yes, Qt.QMessageBox.YesToAll no_any = Qt.QMessageBox.No, Qt.QMessageBox.NoToAll last_answer = Qt.QMessageBox.No for macro_info in macros: name, fname = macro_info.name, macro_info.file_path module = macro_info.module fname = fname[fname.index(osp.sep) + 1:] # transform into relative path local_filename = osp.join(self._tmp_dir, fname) idx = editorstack.has_filename(local_filename) if idx is not None and last_answer not in all_any: last_answer = Qt.QMessageBox.question(self, "Macro file '{0}' already opened".format(module), "All changes to {0} will be lost." "
    Do you want to revert file from the server ignoring " "any possible changes you (may) have made?".format(module), Qt.QMessageBox.Yes | Qt.QMessageBox.YesToAll | \ Qt.QMessageBox.No | Qt.QMessageBox.NoToAll, Qt.QMessageBox.No) if idx is None or last_answer in yes_any: if not self._prepare_path(macro_info.path): Qt.QMessageBox.warning(self, "Error trying to prepare '{0}'".format(module), "An error occured trying to prepare '{0}'".format(module), Qt.QMessageBox.Ok, Qt.QMessageBox.Ok) continue _, code, line = self.get_macro_code(module, name) line = int(line) self.debug("Creating local file %s...", local_filename) fd = file(local_filename, "w") fd.write(code) fd.close() if idx is None: self.debug("Loading local file %s...", local_filename) self.load(local_filename, goto=line) else: self.debug("Reloading local file %s...", local_filename) self.reload(idx, filename=local_filename, goto=line) elif last_answer in no_any: self.set_current_filename(local_filename) @ProtectTaurusMessageBox(title="An error occured trying to open macro(s)") def open_macro_libraries(self, macro_libraries): editorstack = self.editorStack() all_any = Qt.QMessageBox.YesToAll, Qt.QMessageBox.NoToAll yes_any = Qt.QMessageBox.Yes, Qt.QMessageBox.YesToAll no_any = Qt.QMessageBox.No, Qt.QMessageBox.NoToAll last_answer = Qt.QMessageBox.No for macro_library in macro_libraries: name, fname = macro_library.name, macro_library.file_path module = macro_library.module fname = fname[fname.index(osp.sep) + 1:] # transform into relative path local_filename = osp.join(self._tmp_dir, fname) idx = editorstack.has_filename(local_filename) if idx is not None and last_answer not in all_any: last_answer = Qt.QMessageBox.question(self, "Macro file '{0}' already opened".format(module), "All changes to {0} will be lost." "
    Do you want to revert file from the server ignoring " "any possible changes you (may) have made?".format(module), Qt.QMessageBox.Yes | Qt.QMessageBox.YesToAll | \ Qt.QMessageBox.No | Qt.QMessageBox.NoToAll, Qt.QMessageBox.No) if idx is None or last_answer in yes_any: if not self._prepare_path(macro_library.path): Qt.QMessageBox.warning(self, "Error trying to prepare '{0}'".format(module), "An error occured trying to prepare '{0}'".format(module), Qt.QMessageBox.Ok, Qt.QMessageBox.Ok) continue _, code, line = self.get_macro_code(module) line = int(line) self.debug("Creating local file %s...", local_filename) fd = file(local_filename, "w") fd.write(code) fd.close() if idx is None: self.debug("Loading local file %s...", local_filename) self.load(local_filename, goto=line) else: self.debug("Reloading local file %s...", local_filename) self.reload(idx, filename=local_filename, goto=line) elif last_answer in no_any: self.set_current_filename(local_filename) @ProtectTaurusMessageBox(msg="A error occured trying to save") def on_save(self, apply=True): editorstack = self.editorStack() # Save the currently edited file if not editorstack.get_stack_count(): return index = editorstack.get_stack_index() res = editorstack.save(index=index) file_info = editorstack.data[index] if not res: return local_filename = file_info.filename fd = file(local_filename, "r") code = fd.read() fd.close() remote_filename = local_filename[len(self._tmp_dir):] self.set_macro_code(remote_filename, code, apply) def on_revert(self): self.editorStack().revert() def reload_macro_lib(self, module_name): pass def set_macro_code(self, filename, code, apply=True): ms = self.getModelObj() if apply: apply = "true" else: apply = "false" return ms.SetMacroCode((filename, code, apply)) def get_macro_code(self, module_name, macro_name=None): ms = self.getModelObj() pars = [ module_name ] if macro_name is not None: pars.append(macro_name) return ms.GetMacroCode(pars) def setModel(self, model_name): TaurusBaseWidget.setModel(self, model_name) self._elementTree.setModel(model_name) self._is_filesystem_prepared = False self.prepare_filesystem() def _prepare_path(self, p): if not self.prepare_filesystem(): return False p = p[p.index(osp.sep) + 1:] # transform into relative path p = osp.join(self._tmp_dir, p) if not osp.exists(p): os.makedirs(p) return True def prepare_filesystem(self): """Prepares a temporary directory to store the macro files locally""" if self._is_filesystem_prepared: return True ms = self.getModelObj() if ms is None: self.warning("Could not prepare local filesystem to store macros") return False ms_name = ms.getSimpleName().replace('/', '_') self._tmp_dir = tempfile.mkdtemp(prefix=ms_name, dir=self._base_tmp_dir) self._is_filesystem_prepared = True return True def closeEvent(self, event): if self._is_filesystem_prepared: shutil.rmtree(self._tmp_dir) TaurusBaseEditor.closeEvent(self, event) def demo(model_name="MS_BL98"): test = SardanaEditor() test.resize(1000, 800) #test.load(__file__) test.setModel(model_name) test.show() return test def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: import taurus.core.util.argparse parser = taurus.core.util.argparse.get_taurus_parser() parser.usage = "%prog [options] " app = Application(sys.argv, cmd_line_parser=parser, app_name="Macro editor demo", app_version="1.0", org_domain="Sardana", org_name="Tango community") args = app.get_command_line_args() if len(args) == 0: parser.error("must give a macroserver device name") else: w = demo(args[0]) if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main() sardana-1.6.1/src/sardana/taurus/qt/qtgui/extra_sardana/startup.py0000644000234000017500000001406612555672637027173 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 is executed by the python interpreter running as subprocess of SpockShell""" __docformat__ = 'restructuredtext' import sys def __run_pythonstartup_script(): import os filename = os.environ.get('PYTHONSTARTUP') if filename and os.path.isfile(filename): execfile(filename) def __run_init_commands(): import os return os.environ.get('PYTHONINITCOMMANDS') def __remove_from_syspath__(): """Remove this module's path from sys.path""" import os.path as osp try: sys.path.remove(osp.dirname(__file__)) except ValueError: pass class UserModuleDeleter(object): """ User Module Deleter (UMD) aims at deleting user modules to force Python to deeply reload them during import pathlist [list]: blacklist in terms of module path namelist [list]: blacklist in terms of module name """ def __init__(self, namelist=None, pathlist=None): if namelist is None: namelist = [] self.namelist = namelist + ['sitecustomize', 'spyderlib', 'spyderplugins'] if pathlist is None: pathlist = [] self.pathlist = pathlist self.previous_modules = sys.modules.keys() def is_module_blacklisted(self, modname, modpath): for path in [sys.prefix] + self.pathlist: if modpath.startswith(path): return True else: return set(modname.split('.')) & set(self.namelist) def run(self, verbose=False): """ Del user modules to force Python to deeply reload them Do not del modules which are considered as system modules, i.e. modules installed in subdirectories of Python interpreter's binary Do not del C modules """ log = [] for modname, module in sys.modules.items(): if modname not in self.previous_modules: modpath = getattr(module, '__file__', None) if modpath is None: # *module* is a C module that is statically linked into the # interpreter. There is no way to know its path, so we # choose to ignore it. continue if not self.is_module_blacklisted(modname, modpath): log.append(modname) del sys.modules[modname] if verbose and log: print "\x1b[4;33m%s\x1b[24m%s\x1b[0m" % ("UMD has deleted", ": " + ", ".join(log)) __umd__ = None def runfile(filename, args=None, wdir=None): """ Run filename args: command line arguments (string) wdir: working directory """ global __umd__ import os if os.environ.get("UMD_ENABLED", "").lower() == "true": if __umd__ is None: namelist = os.environ.get("UMD_NAMELIST", None) if namelist is not None: namelist = namelist.split(',') __umd__ = UserModuleDeleter(namelist=namelist) else: verbose = os.environ.get("UMD_VERBOSE", "").lower() == "true" __umd__.run(verbose=verbose) if args is not None and not isinstance(args, basestring): raise TypeError("expected a character buffer object") glbs = globals() if '__ipythonshell__' in glbs: glbs = glbs['__ipythonshell__'].IP.user_ns glbs['__file__'] = filename sys.argv = [filename] if args is not None: for arg in args.split(): sys.argv.append(arg) if wdir is not None: os.chdir(wdir) execfile(filename, glbs) sys.argv = [''] glbs.pop('__file__') def debugfile(filename, args=None, wdir=None): """ Debug filename args: command line arguments (string) wdir: working directory """ import pdb debugger = pdb.Pdb() filename = debugger.canonic(filename) debugger._wait_for_mainpyfile = 1 debugger.mainpyfile = filename debugger._user_requested_quit = 0 debugger.run("runfile(%r, args=%r, wdir=%r)" % (filename, args, wdir)) if __name__ == "__main__": __remove_from_syspath__() __commands__ = __run_init_commands() if __commands__: for command in __commands__.split(';'): exec command else: __run_pythonstartup_script() for _name in ['__run_pythonstartup_script', '__run_init_commands', '__create_banner', '__commands__', 'command', '__file__', '__remove_sys_argv__'] + ['_name']: if _name in locals(): locals().pop(_name) __doc__ = '' __name__ = '__main__' import os if os.name == 'nt': # Windows platforms: monkey-patching *pyreadline* module # to make IPython work in a remote process import pyreadline pyreadline.unicode_helper.pyreadline_codepage = "ascii" pyreadline.GetOutputFile = lambda: None from sardana.spock.genutils import start, mainloop __ipythonshell__ = start(user_ns={'runfile': runfile, 'debugfile': debugfile}) __ipythonshell__.IP.stdin_encoding = os.environ['SPYDER_ENCODING'] mainloop(shell=__ipythonshell__) sardana-1.6.1/src/sardana/taurus/qt/qtgui/__init__.py0000644000234000017500000000173312555672636024410 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/qt/__init__.py0000644000234000017500000000173312555672636023257 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/taurus/__init__.py0000644000234000017500000000173412555672636022634 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/test/0000755000234000017500000000000012555673001020135 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/test/__init__.py0000644000234000017500000001006412555672637022265 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 includes a framework allowing to test its features. This framework is aimed to be used with the objective of finding bugs and promote test driven development. \n This Framework is the outcome of the Sardana Enhancement Proposal 5 (SEP5). Its documentation is located here: http://sourceforge.net/p/sardana/wiki/SEP5/ \n Ideally, each bug found should be accompanied by a test revealing the bug. That eases the process of correcting bugs. \n The objective of the Sardana Test Framework is not to provide a test for every piece of code, but rather to ease collaborations and allow people from other institutions to provide their own test classes. \n At the moment the Sardana testing is focused on Unit Tests, but in the future the objective is to extend it to integration and system tests as well. \n In order to run all the tests provided by Sardana test framework, at a given moment, just go to 'sardana/src/sardana/test' and execute: \n python testsuite.py Sardana Test Framework is based on 'unittest'. This means that each of the Sardana python test classes inherits from unittest.TestCase. \n Each of the Sardana Tests has to be acompanied by a documentation that is written in the module, class and method docstrings; as well as in the assert methods. \n All tests have to be written in folders named 'test/'. \n Sardana Test Framework provides tools for testing macros. These tools comes from: \n * sardana/src/sardana/macroserver/macros/test/base.py * sardana/src/sardana/macroserver/macros/test/macroexecutor.py * sardana/src/sardana/macroserver/macros/test/sardemoenv.py * sardana/src/sardana/tango/macroserver/test/macroexecutor.py Tests of macros are done using the motors and experimental channels created by Sardana demo. \n base.py provides the mean of executing macros and test the function Run and Stop for each macro. Macro test classes can inherit from RunMacroTestCase, RunStopMacroTestCase or BaseMacroTestCase. \n Macros as 'lsm' inherits from RunMacroTestCase as it is interesting to test if the macros can be executed. The test methods can override the function macro_runs() that is defined in the class RunMacroTestCase. \n However, scan macros inherits from RunStopMacroTestCase as it is interesting to test both: if the macros can be executed and if they can be aborted. \n Another capacity provided by the Framework is the option to execute the same test method with many different macro input parameters. These is done by the help of a decorator inserted at the beginning of the test function. One decorator has to be used for each set of macro input parameters. Examples of the decorator usage can be seen in: test_scan.py \n If new tests of scan macros or list macros have to be added, that can be done in test_scan.py or in test_list.py where a useful base class is provided. \n Examples of Sardana tests using tools of Sardana Test Framework are: \n * sardana/src/sardana/test/test_sardanavalue.py * sardana/src/sardana/test/test_parameter.py * sardana/src/sardana/macroserver/macros/test_ct.py * sardana/src/sardana/macroserver/macros/test_list.py * sardana/src/sardana/macroserver/macros/test_wm.py """ sardana-1.6.1/src/sardana/test/test_sardanavalue.py0000644000234000017500000000731412555672637024237 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################## """Unit tests for sardanavalue module""" from taurus.external import unittest from sardana.sardanavalue import SardanaValue class SardanaValueTestCase(unittest.TestCase): """Instantiating in different ways a Sardana Value and perform some verifications. """ def testInstanceCreation(self): """ Instantiate in different ways a SardanaValue object. """ sar_val = SardanaValue() self.assertIsInstance(sar_val, SardanaValue, 'Instantiation of an ' + 'object SardanaValue without arguments does not work') sar_val1 = SardanaValue(value=9) self.assertIsInstance(sar_val1, SardanaValue, 'Instantiation of an ' + 'object SardanaValue with the value argument does not work') sar_val2 = SardanaValue(value=8, exc_info=None, timestamp='09:30', dtype='int', dformat='int') self.assertIsInstance(sar_val2, SardanaValue, 'Instantiation of an ' + 'object SardanaValue with arguments and exc_info equal None, ' + 'does not work.') sar_val3 = SardanaValue(value=7, exc_info='exception_info', timestamp='09:30', dtype='int', dformat='int') self.assertIsInstance(sar_val3, SardanaValue, 'Instantiation of an ' + 'object SardanaValue with arguments and exc_info ' + 'different of None, does not work.') def testSardanaValueWithExceptionInfo(self): """Verify the creation of SardanaValue when exc_info != None. Verify that 'Error' is contained in the returned string. """ val = 4 sar_val = SardanaValue(value=val, exc_info='exception_info') representation = repr(sar_val) self.assertEqual(sar_val.error, True, 'The error attribute should be True.') self.assertRegexpMatches(representation, ".*.*", 'The SardanaValue representation does not contain .') def testSardanaValueWithNoExceptionInfo(self): """Verify the creation of SardanaValue when exc_info is not specified and we give a value as argument of the SardanaValue constructor. SardanaValue representation shall contain its value. """ value = 5 sar_val = SardanaValue(value=value) returned_string = sar_val.__repr__() self.assertRegexpMatches(returned_string, repr(value), 'The SardanaValue representation does not contain its value') self.assertEqual(sar_val.error, False, 'The error attribute should be False') sardana-1.6.1/src/sardana/test/testsuite.py0000644000234000017500000000352512555672637022563 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 defines the test suite for the whole Sardana package Usage:: from sardana.test import testsuite testsuite.run() """ __docformat__ = 'restructuredtext' import sys, os from taurus.external import unittest import sardana def run(): '''Runs all tests for the taurus package :returns: the test runner result :rtype: unittest.result.TestResult ''' # discover all tests within the sardana/src directory loader = unittest.defaultTestLoader suite = loader.discover(os.path.dirname(sardana.__file__)) # use the basic text test runner that outputs to sys.stderr runner = unittest.TextTestRunner(descriptions=True, verbosity=2) # run the test suite result = runner.run(suite) return result if __name__ == '__main__': result = run() exit_code = 0 if not result.wasSuccessful(): exit_code = 1 sys.exit(exit_code)sardana-1.6.1/src/sardana/tools/0000755000234000017500000000000012555672777020341 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tools/config/0000755000234000017500000000000012555673001021563 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/tools/config/FODS_TO_SAR.xslt0000644000234000017500000012017212555672637024362 0ustar zreszelaComputing00000000000000 PoolPath : Item Version 0.3.0 MacroPath : Item PoolNames ; Item IORegisters Motors Channels Channels Channels Channels CommunicationChannels Channels ; : ; Motor ; Channel Automatic ; : ; True sardana-1.6.1/src/sardana/tools/config/SAR_TO_FODS.xslt0000644000234000017500000013754412555672637024375 0ustar zreszelaComputing00000000000000 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.6.1/src/sardana/tools/config/XLS_TO_SAR.xslt0000644000234000017500000012553312555672637024303 0ustar zreszelaComputing00000000000000 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.6.1/src/sardana/tools/config/fods_to_sar.py0000644000234000017500000000154712555672637024464 0ustar zreszelaComputing00000000000000#!/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.6.1/src/sardana/tools/config/get_pool_config.py0000644000234000017500000001557612555672637025326 0ustar zreszelaComputing00000000000000import 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.6.1/src/sardana/tools/config/pexpect23.py0000644000234000017500000022424112555672637023775 0ustar zreszelaComputing00000000000000"""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.6.1/src/sardana/tools/config/sar_to_fods.py0000644000234000017500000000061612555672637024460 0ustar zreszelaComputing00000000000000#!/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.6.1/src/sardana/tools/config/sardana.py0000644000234000017500000021354212555672637023573 0ustar zreszelaComputing00000000000000#!/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.codecs 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.6.1/src/sardana/tools/config/sardana.xsd0000644000234000017500000002100712555672637023732 0ustar zreszelaComputing00000000000000 sardana-1.6.1/src/sardana/tools/config/tango.xsd0000644000234000017500000001672612555672637023445 0ustar zreszelaComputing00000000000000 sardana-1.6.1/src/sardana/tools/config/to_sar.py0000644000234000017500000000134712555672637023447 0ustar zreszelaComputing00000000000000#!/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.6.1/src/sardana/tools/config/xls_to_sar.py0000644000234000017500000000151512555672637024332 0ustar zreszelaComputing00000000000000#!/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.6.1/src/sardana/util/0000755000234000017500000000000012555673001020133 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/util/motion/0000755000234000017500000000000012555673001021440 5ustar zreszelaComputing00000000000000sardana-1.6.1/src/sardana/util/motion/__init__.py0000644000234000017500000000223012555672637023564 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/util/motion/motion.py0000644000234000017500000005572112555672637023347 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 sardana.taurus.core.tango.sardana.pool if isinstance(motor, sardana.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.6.1/src/sardana/util/__init__.py0000644000234000017500000000204112555672637022257 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/util/deepreload.py0000644000234000017500000002570412555672637022637 0ustar zreszelaComputing00000000000000# -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/util/tree.py0000644000234000017500000000133712555672637021466 0ustar zreszelaComputing00000000000000class 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.6.1/src/sardana/util/wrap.py0000644000234000017500000000415212555672637021476 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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__ = ["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.6.1/src/sardana/__init__.py0000644000234000017500000000246312555672636021311 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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.6.1/src/sardana/release.py0000644000234000017500000000570512555672636021174 0ustar zreszelaComputing00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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, 6, 1, 'rc', 0) version = '.'.join(map(str, version_info[:3])) revision = str(version_info[4]) description = "instrument control and data acquisition system" long_description = \ '''Sardana is a Supervision, Control And Data Acquisition (SCADA) system for scientific installations. It is written in Python and based on the TANGO library. The hardware control and data acquisition routines can be accessed via an IPython console and a generic graphical user interface (both of which are easily extensible by the user).''' license = 'LGPL' authors = {'Tiago' : ('Tiago Coutinho','tiago.coutinho@esrf.fr'), 'Pascual-Izarra' : ('Carlos Pascual-Izarra','cpascual@cells.es'), 'Reszela' : ('Zbigniew Reszela','zreszela@cells.es') } url = 'http://www.sardana-controls.org' 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.6.1/src/sardana/requirements.py0000644000234000017500000000611012555672636022266 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 absolute_import __docformat__ = 'restructuredtext' __all__ = ["check_requirements"] import sys __requires__ = { # module minimum "Python" : (2, 6, 0), "PyTango" : (7, 2, 3), "taurus.core" : (3, 6, 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.6.1/src/sardana/sardanaattribute.py0000644000234000017500000003217712555672636023114 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __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.6.1/src/sardana/sardanabase.py0000644000234000017500000001523412555672636022016 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __all__ = ["SardanaBaseObject", "SardanaObjectID"] __docformat__ = 'restructuredtext' import weakref from taurus.core.util.log import Logger from sardana.sardanadefs import ElementType, Interface, InterfacesExpanded, InvalidId from sardana.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.6.1/src/sardana/sardanacontainer.py0000644000234000017500000002015212555672636023061 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __all__ = ["SardanaContainer"] __docformat__ = 'restructuredtext' from taurus.core.util.containers import CaselessDict from sardana.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.6.1/src/sardana/sardanacustomsettings.py0000644000234000017500000000351612555672636024177 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################# ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 . ## ############################################################################# """This module contains some Sardana-wide default configurations. The idea is that the final user may edit the values here to customize certain aspects of Sardana. """ #:UnitTest door name: the door to be used by unit tests. #:UNITTEST_DOOR_NAME Must be defined for running sardana unittests. UNITTEST_DOOR_NAME = "door/demo1/1" #:UnitTests Pool DS name: Pool DS to use in unit tests. UNITTEST_POOL_DS_NAME = "unittest1" #:UnitTests Pool Device name: Pool Device to use in unit tests. UNITTEST_POOL_NAME = "pool/demo1/1" #:Size and number of rotating backups of the log files. #:The Pool and MacroServer Device servers will use these values for their logs. LOG_FILES_SIZE = 1e7 LOG_BCK_COUNT = 5 #:Input handler for spock interactive macros. Accepted values are: #: - "CLI": Input via spock command line. This is the default. #: - "Qt": Input via Qt dialogs SPOCK_INPUT_HANDLER = "CLI" sardana-1.6.1/src/sardana/sardanadefs.py0000644000234000017500000004561512555672636022033 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __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.enumeration 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.6.1/src/sardana/sardanaevent.py0000644000234000017500000001427012555672636022224 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __all__ = ["EventGenerator", "EventReceiver", "EventType"] __docformat__ = 'restructuredtext' import weakref import collections from sardana.sardanautils import is_callable from taurus.core.util.event 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.6.1/src/sardana/sardanaexception.py0000644000234000017500000000617112555672636023102 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __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.6.1/src/sardana/sardanalock.py0000644000234000017500000000613112555672636022030 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __all__ = ["SardanaLock"] __docformat__ = 'restructuredtext' import logging import threading _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.6.1/src/sardana/sardanamanager.py0000644000234000017500000000615312555672636022516 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __all__ = ["SardanaElementManager", "SardanaIDManager"] __docformat__ = 'restructuredtext' from taurus.core.util.codecs 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.6.1/src/sardana/sardanameta.py0000644000234000017500000004414112555672636022031 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __all__ = ["SardanaLibrary", "SardanaClass", "SardanaFunction"] __docformat__ = 'restructuredtext' import os import inspect import string import weakref import linecache import traceback from sardana.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 has_metas(self): """Returns True if any meta object exists in the library or False otherwise. :return: True if any meta object (class or function) exists in the library or False otherwise :rtype: bool """ has_metas_bool = False if (len(self.get_meta_classes()) > 0 or len(self.get_meta_functions()) > 0): has_metas_bool = True return has_metas_bool 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.6.1/src/sardana/sardanamodulemanager.py0000644000234000017500000002074612555672636023730 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 from __future__ import absolute_import __all__ = ["ModuleManager"] __docformat__ = 'restructuredtext' import imp import sys import threading from taurus.core import ManagerState from taurus.core.util.log import Logger from taurus.core.util.singleton import Singleton 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.6.1/src/sardana/sardanathreadpool.py0000644000234000017500000000326112555672636023242 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 from __future__ import absolute_import __all__ = ["get_thread_pool"] __docformat__ = 'restructuredtext' import threading from taurus.core.util.threadpool 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_pool sardana-1.6.1/src/sardana/sardanautils.py0000644000234000017500000001177612555672636022253 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __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 numpy import numbers import collections from sardana.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.6.1/src/sardana/sardanavalue.py0000644000234000017500000000352312555672636022216 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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""" from __future__ import absolute_import __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.6.1/setup.py0000644000234000017500000003313112555672636016506 0ustar zreszelaComputing00000000000000#!/usr/bin/env python ############################################################################## ## ## This file is part of Sardana ## ## http://www.sardana-controls.org/ ## ## 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 imp from distutils.core import setup, Command from distutils.command.build import build as dftbuild from distutils.command.install import install as dftinstall from distutils.command.install_scripts import install_scripts as dftinstall_scripts from distutils.version import StrictVersion as V try: import sphinx import sphinx.util.console sphinx.util.console.color_terminal = lambda: False if V(sphinx.__version__) < V("1.0.0") \ or V(sphinx.__version__) == V("1.2.0"): print("Sphinx documentation can not be compiled" " with sphinx < 1.0.0 or the 1.2.0 version") sphinx = None except ImportError: 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 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_scripts(dftinstall_scripts): '''Customization to create .bat wrappers for the scripts when installing on windows. Adapted from a recipe by Matthew Brett (who licensed it under CC0): https://github.com/matthew-brett/myscripter/blob/master/setup.py See rationale in: http://matthew-brett.github.io/pydagogue/installing_scripts.html ''' user_options = list(dftinstall_scripts.user_options) user_options.extend( [ ('wrappers', None, 'Install .bat wrappers for windows (enabled by default on windows)'), ('ignore-shebang', None, 'Use "python" as the interpreter in .bat wrappers (instead of using the interpreter found in the shebang line of the scripts). Note: this only affects to windows .bat wrappers!'), ]) BAT_TEMPLATE_SHEBANG = \ r"""@echo off REM wrapper to use shebang first line of {FNAME} set mypath=%~dp0 set pyscript="%mypath%{FNAME}" set /p line1=<%pyscript% if "%line1:~0,2%" == "#!" (goto :goodstart) echo First line of %pyscript% does not start with "#!" exit /b 1 :goodstart set py_exe=%line1:~2% call %py_exe% %pyscript% %* """ BAT_TEMPLATE_PATH = \ r"""@echo off REM wrapper to launch {FNAME} set mypath=%~dp0 set pyscript="%mypath%{FNAME}" set py_exe="python" call %py_exe% %pyscript% %* """ def initialize_options(self): self.ignore_shebang = None self.wrappers = (os.name == "nt") dftinstall_scripts.initialize_options(self) def run(self): dftinstall_scripts.run(self) if self.wrappers: for filepath in self.get_outputs(): # If we can find an executable name in the #! top line of the script # file, make .bat wrapper for script. with open(filepath, 'rt') as fobj: first_line = fobj.readline() if not (first_line.startswith('#!') and 'python' in first_line.lower()): print("No #!python executable found, skipping .bat wrapper") continue pth, fname = os.path.split(filepath) froot, ext = os.path.splitext(fname) bat_file = os.path.join(pth, froot + '.bat') if self.ignore_shebang: template = self.BAT_TEMPLATE_PATH else: template = self.BAT_TEMPLATE_SHEBANG bat_contents = template.replace('{FNAME}', fname) print("Making %s wrapper for %s" % (bat_file, filepath)) if self.dry_run: continue with open(bat_file, 'wt') as fobj: fobj.write(bat_contents) class install(dftinstall): user_options = list(dftinstall.user_options) user_options.extend([ ('install-man=', None, 'install directory for Unix man pages'), ('install-html=', None, "install 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 elif 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, 'install_scripts' : install_scripts} if sphinx: from sphinx.setup_command import BuildDoc class build_doc(BuildDoc): def has_doc_api(self): return True 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['Reszela'] package_dir = {'sardana': abspath('src', 'sardana')} packages = [ 'sardana', 'sardana.test', 'sardana.util', 'sardana.util.motion', 'sardana.pool', 'sardana.pool.test', 'sardana.pool.poolcontrollers', 'sardana.macroserver', 'sardana.macroserver.macros', 'sardana.macroserver.macros.test', 'sardana.macroserver.macros.examples', 'sardana.macroserver.scan', 'sardana.macroserver.scan.recorder', 'sardana.tango', 'sardana.tango.core', 'sardana.tango.pool', 'sardana.tango.pool.test', 'sardana.tango.macroserver', 'sardana.tango.macroserver.test', 'sardana.spock', 'sardana.spock.test', 'sardana.spock.ipython_00_10', 'sardana.spock.ipython_00_11', 'sardana.spock.ipython_01_00', 'sardana.taurus', 'sardana.taurus.core', 'sardana.taurus.core.tango', 'sardana.taurus.core.tango.sardana', 'sardana.taurus.qt', 'sardana.taurus.qt.qtcore', 'sardana.taurus.qt.qtcore.tango', 'sardana.taurus.qt.qtcore.tango.sardana', 'sardana.taurus.qt.qtgui', 'sardana.taurus.qt.qtgui.extra_macroexecutor', 'sardana.taurus.qt.qtgui.extra_macroexecutor.favouriteseditor', 'sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor', 'sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.customeditors', 'sardana.taurus.qt.qtgui.extra_macroexecutor.sequenceeditor', 'sardana.taurus.qt.qtgui.extra_sardana', 'sardana.taurus.qt.qtgui.extra_sardana.ui', 'sardana.taurus.qt.qtgui.extra_pool', ] package_data = {'sardana.taurus.qt.qtgui.extra_macroexecutor': ['ui/*.ui'], 'sardana.taurus.qt.qtgui.extra_pool': ['ui/*.ui'], 'sardana.taurus.qt.qtgui.extra_sardana': ['ui/*.ui'] } provides = [ 'sardana', 'sardana.pool', 'sardana.macroserver', 'sardana.spock', 'sardana.tango', ] requires = [ 'PyTango (>=7.2.3)', 'taurus (>= 3.6.0)', 'lxml (>=2.1)', 'ipython (>=0.10, !=0.11)' ] scripts = [ "scripts/h5toascii", "scripts/h5tospec", "scripts/MacroServer", "scripts/Pool", "scripts/Sardana", "scripts/spectoascii", "scripts/spock", "scripts/macroexecutor", "scripts/sequencer" ] 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, package_data=package_data, classifiers=classifiers, scripts=scripts, provides=provides, keywords=Release.keywords, requires=requires, cmdclass=cmdclass) if __name__ == "__main__": main() sardana-1.6.1/PKG-INFO0000644000234000017500000000332112555673001016052 0ustar zreszelaComputing00000000000000Metadata-Version: 1.1 Name: sardana Version: 1.6.1 Summary: instrument control and data acquisition system Home-page: http://www.sardana-controls.org Author: Zbigniew Reszela Author-email: zreszela@cells.es License: LGPL Download-URL: http://pypi.python.org/packages/source/s/sardana Description: Sardana is a Supervision, Control And Data Acquisition (SCADA) system for scientific installations. It is written in Python and based on the TANGO library. The hardware control and data acquisition routines can be accessed via an IPython console and a generic graphical user interface (both of which are easily extensible by the user). 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.6.0) Requires: lxml (>=2.1) Requires: ipython (>=0.10, !=0.11) Provides: sardana Provides: sardana.pool Provides: sardana.macroserver Provides: sardana.spock Provides: sardana.tango

    >>.ŗ~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.6.1/doc/source/_static/snapshot02.png0000644000234000017500000026636012555672634023210 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/snapshot03.png0000644000234000017500000017041512555672634023204 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/snapshot04.png0000644000234000017500000025256412555672634023213 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/snapshot05.png0000644000234000017500000036413512555672634023212 0ustar zreszelaComputing00000000000000PNG  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ّ

    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.6.1/doc/source/_static/gui_snapshot05.png0000644000234000017500000011145112555672634024045 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gui_snapshot06.png0000644000234000017500000031023012555672634024042 0ustar zreszelaComputing00000000000000PNG  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.6.1/doc/source/_static/gui_snapshot07.png0000644000234000017500000037561412555672634024064 0ustar zreszelaComputing00000000000000PNG  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